wmls.c
来自「WAP browser is based on the Wireless App」· C语言 代码 · 共 1,474 行 · 第 1/3 页
C
1,474 行
/*
* Copyright (c) 2004, TapTarget. All rights reserved.
* Copyright (c) 2002-2004, Yuri Plaksyuk (york@noir.crocodile.org).
*
* http://www.taptarget.com/
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* - Redistributions of source code must retain the above
* copyright notice, this list of conditions and the following
* disclaimer.
*
* - Redistributions in binary form must reproduce the above
* copyright notice, this list of conditions and the following
* disclaimer in the documentation and/or other materials
* provided with the distribution.
*
* - All advertising materials mentioning features or use of this
* software must display the following acknowledgement: This
* product includes software developed by TapTarget.
*
* - The name of TapTarget may not be used to endorse or
* promote products derived from this software without specific
* prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY TAPTARGET "AS IS" AND ANY EXPRESS
* OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL TAPTARGET BE LIABLE FOR ANY DIRECT,
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
* GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
* IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
* OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
* $Id: wmls.c,v 1.4 2004/05/13 10:19:24 york Exp $
*/
#include "wmls.h"
#include "wmlscode.h"
#include "MathLib.h"
static ScriptModule *ScriptLoadModule(ScriptLibGlobals *gP, const Char *uri, UInt16 len, Err *errP);
static Int16 ScriptFindFunc(ScriptModule *m, Char *str, UInt16 strlen);
static Err ScriptFuncCall(ScriptLibGlobals *gP, ScriptModule *m, UInt8 findex);
static Err ScriptLibFuncCall(ScriptLibGlobals *gP, UInt16 lindex, UInt8 findex);
static Err ScriptUrlFuncCall(ScriptLibGlobals *gP, UInt16 uindex, UInt8 findex);
static Int32 ReadIntMB(UInt8 *buf, UInt16 *offsetP);
Err ScriptExecute(ScriptLibGlobals *gP, const Char *uri, ScriptSlot *rs)
{
Int16 findex;
UInt8 argc = 0;
Char *str, *ptr;
Err err = errNone;
ScriptModule *m;
ScriptSlot *stack;
ScriptFunction *fp;
str = StrChr(uri, '#');
if(str == NULL) return scriptErrInvalidURI;
m = ScriptLoadModule(gP, uri, str - uri, &err);
if(m == NULL) return err;
ptr = StrChr(++str, '(');
if(ptr == NULL) return scriptErrInvalidURI;
findex = ScriptFindFunc(m, str, ptr - str);
if(findex < 0) return scriptErrFunctionNotFound;
stack = MemPtrNew(sizeof(ScriptSlot) * gP->stackSize);
if(stack == NULL) return scriptErrMemory;
gP->sp = stack + gP->stackSize; // initialize stack pointer
while(1)
{
// push function parameters into the stack
ptr++;
while(*ptr == ' ') ptr++; // skip spaces
if(*ptr == ')') break;
ptr = SlotParseConst(--gP->sp, ptr), argc++;
if(ptr == NULL) { err = scriptErrSyntax; goto __cleanup; }
while(*ptr == ' ') ptr++; // skip spaces
if(*ptr == ')') break;
if(*ptr != ',') { err = scriptErrSyntax; goto __cleanup; }
}
// check number of parameters
fp = m->func_table + findex;
if(argc != fp->arg_count)
{
err = scriptErrVerificationFailed;
goto __cleanup;
}
// execute function
err = ScriptFuncCall(gP, m, findex);
if(err) goto __cleanup;
// save result into result slot
rs->type = gP->sp->type;
rs->value.a = gP->sp->value.a;
SLOT_FREE(gP->sp);
__cleanup:
while(gP->sp < stack + gP->stackSize) { SLOT_POP(gP->sp); }
MemPtrFree(stack);
return err;
}
Err ScriptUnloadModules(ScriptLibGlobals *gP)
{
ScriptModule *m = gP->modules, *p;
UInt16 i;
while(m)
{
if(m->uri)
MemPtrFree(m->uri);
if(m->const_pool)
{
for(i = 0; i < m->const_count; i++)
SlotFree(m->const_pool + i);
MemPtrFree(m->const_pool);
}
if(m->func_table)
MemPtrFree(m->func_table);
p = m, m = m->next;
gP->hostP->UnloadModule(p->moduleP);
MemPtrFree(p);
}
gP->modules = NULL;
return 0;
}
/////////////////////////////////////////////////////////////////////////////////////////
static ScriptModule *ScriptLoadModule(ScriptLibGlobals *gP, const Char *uri, UInt16 len, Err *errP)
{
ScriptModule *m;
UInt16 offset, i;
UInt8 *moduleP;
*errP = 0;
// find it among already loaded modules
for(m = gP->modules; m; m = m->next)
{
if(StrNCompare(m->uri, uri, len) == 0 && m->uri[len] == 0)
return m;
}
// load module from the host
*errP = gP->hostP->LoadModule(uri, len, (void**)&moduleP, &offset);
if(*errP) return NULL;
// parse module
m = MemPtrNew(sizeof(ScriptModule));
if(m == NULL) { *errP = scriptErrMemory; return NULL; }
offset++; // skip version info
MemSet(m, sizeof(ScriptModule), 0);
m->uri = ScriptStrCopyEx(uri, len);
m->moduleP = moduleP;
m->code_size = ReadIntMB(moduleP, &offset);
m->const_count = ReadIntMB(moduleP, &offset);
m->const_charset = ReadIntMB(moduleP, &offset);
if(m->const_count)
{
m->const_pool = MemPtrNew(sizeof(ScriptSlot) * m->const_count);
if(m->const_pool == NULL) { *errP = scriptErrMemory; return NULL; }
for(i = 0; i < m->const_count; i++)
SlotLoadConst(m->const_pool + i, moduleP, &offset);
}
// pragma pool
m->pragma_count = ReadIntMB(moduleP, &offset);
for(i = 0; i < m->pragma_count; i++)
switch(moduleP[offset++])
{
case 0: // Access Domain
case 1: // Access Path
ReadIntMB(moduleP, &offset);
break;
case 2: // User Agent Property
ReadIntMB(moduleP, &offset);
ReadIntMB(moduleP, &offset);
break;
case 3: // User Agent Property and Scheme
ReadIntMB(moduleP, &offset);
ReadIntMB(moduleP, &offset);
ReadIntMB(moduleP, &offset);
break;
}
// function pool
m->func_count = moduleP[offset++];
m->export_count = moduleP[offset++];
m->export_table = moduleP + offset;
// skip exported function names
for(i = 0; i < m->export_count; i++)
offset += moduleP[offset + 1] + 2;
m->func_table = MemPtrNew(sizeof(ScriptFunction) * m->func_count);
if(m->func_table == NULL) { *errP = scriptErrMemory; return NULL; }
for(i = 0; i < m->func_count; i++)
{
ScriptFunction *fp = m->func_table + i;
fp->arg_count = moduleP[offset++];
fp->var_count = moduleP[offset++];
fp->code_size = ReadIntMB(moduleP, &offset);
fp->code = moduleP + offset;
offset += fp->code_size;
}
return m->next = gP->modules, gP->modules = m;
}
static Int16 ScriptFindFunc(ScriptModule *m, Char *str, UInt16 strlen)
{
UInt16 i;
UInt8 *ptr = m->export_table;
UInt8 findex, length;
for(i = 0; i < m->export_count; i++)
{
findex = *ptr++; // exported function index
length = *ptr++; // exported function name length
if(length == strlen && StrNCompare(ptr, str, strlen) == 0)
return findex;
ptr += length; // go to next name entry
}
return -1;
}
static Err ScriptFuncCall(ScriptLibGlobals *gP, ScriptModule *m, UInt8 findex)
{
ScriptFunction *fp;
ScriptSlot *bp, *xp, *tp;
UInt8 *ip, *code_end;
UInt16 i;
Err err;
FlpCompDouble flpArg1;
FlpCompDouble flpArg2;
FlpCompDouble theCompFloat;
if(findex >= m->func_count)
goto __verification_failed;
fp = m->func_table + findex;
bp = gP->sp + fp->arg_count - 1; // TODO: check for stack underflow!!!
ip = fp->code;
for(i = 0; i < fp->var_count; i++)
{
SLOT_PUSH_STRING(gP->sp, NULL);
}
code_end = ip + fp->code_size;
while(ip < code_end)
{
switch(*ip)
{
case RESERVED_00:
goto __illegal_instruction;
case JUMP_FW:
ip += *(++ip);
break;
case JUMP_FW_W:
ip += *(UInt16*)(++ip) + 1;
break;
case JUMP_BW:
ip -= *(ip + 1);
continue;
case JUMP_BW_W:
ip -= *(UInt16*)(ip + 1);
continue;
case TJUMP_FW:
if(SLOT_IS_FALSE(gP->sp)) ip += *(++ip);
SLOT_POP(gP->sp);
break;
case TJUMP_FW_W:
if(SLOT_IS_FALSE(gP->sp)) ip += *(UInt16*)(++ip) + 1;
SLOT_POP(gP->sp);
break;
case TJUMP_BW:
if(SLOT_IS_FALSE(gP->sp)) ip -= *(ip + 1);
SLOT_POP(gP->sp);
continue;
case TJUMP_BW_W:
if(SLOT_IS_FALSE(gP->sp)) ip -= *(UInt16*)(ip + 1);
SLOT_POP(gP->sp);
break;
case CALL:
err = ScriptFuncCall(gP, m, *(++ip));
if(err) return err;
break;
case CALL_LIB:
err = ScriptLibFuncCall(gP, *(++ip), *(++ip));
if(err) return err;
break;
case CALL_LIB_W:
err = ScriptLibFuncCall(gP, *(UInt16*)(++ip), *(++ip));
if(err) return err;
++ip;
break;
case CALL_URL:
err = ScriptUrlFuncCall(gP, *(++ip), *(++ip));
if(err) return err;
break;
case CALL_URL_W:
err = ScriptUrlFuncCall(gP, *(UInt16*)(++ip), *(++ip));
if(err) return err;
++ip;
break;
case LOAD_VAR:
SLOT_PUSH_VAR(gP->sp, bp - *(++ip));
break;
case STORE_VAR:
SLOT_SAVE_VAR(gP->sp, bp - *(++ip));
break;
case INCR_VAR:
tp = bp - *(++ip);
if (tp->type == scriptTypeInteger) {
SLOT_TO_INTEGER(tp);
xp->value.n++;
}
else {
SLOT_TO_FLOAT(tp);
//xp->value.f++;
flpArg1.d = xp->value.f;
flpArg2.d = 1.0;
FlpBufferCorrectedAdd(&theCompFloat.fd, flpArg1.fd, flpArg2.fd, kDefAccuracy);
xp->value.f = theCompFloat.d;
}
break;
case DECR_VAR:
tp = bp - *(++ip);
if (tp->type == scriptTypeInteger) {
SLOT_TO_INTEGER(tp);
xp->value.n--;
}
else {
SLOT_TO_FLOAT(tp);
//xp->value.f--;
flpArg1.d = xp->value.f;
flpArg2.d = 1.0;
FlpBufferCorrectedSub(&theCompFloat.fd, flpArg1.fd, flpArg2.fd, kDefAccuracy);
xp->value.f = theCompFloat.d;
}
break;
case LOAD_CONST:
SLOT_PUSH_VAR(gP->sp, m->const_pool + *(++ip));
break;
case LOAD_CONST_W:
SLOT_PUSH_VAR(gP->sp, m->const_pool + *(UInt16*)(++ip));
++ip;
break;
case CONST_0:
SLOT_PUSH_INTEGER(gP->sp, 0);
break;
case CONST_1:
SLOT_PUSH_INTEGER(gP->sp, 1);
break;
case CONST_M1:
SLOT_PUSH_INTEGER(gP->sp, -1);
break;
case CONST_ES:
SLOT_PUSH_STRING(gP->sp, NULL);
break;
case CONST_INVALID:
SLOT_PUSH_INVALID(gP->sp);
break;
case CONST_TRUE:
SLOT_PUSH_TRUE(gP->sp);
break;
case CONST_FALSE:
SLOT_PUSH_FALSE(gP->sp);
break;
case INCR:
if (gP->sp->type == scriptTypeInteger) {
SLOT_TO_INTEGER(gP->sp);
xp->value.n++;
}
else {
SLOT_TO_FLOAT(gP->sp);
//xp->value.f++;
flpArg1.d = xp->value.f;
flpArg2.d = 1.0;
FlpBufferCorrectedAdd(&theCompFloat.fd, flpArg1.fd, flpArg2.fd, kDefAccuracy);
xp->value.f = theCompFloat.d;
}
break;
case DECR:
if (gP->sp->type == scriptTypeInteger) {
SLOT_TO_INTEGER(gP->sp);
xp->value.n--;
}
else {
SLOT_TO_FLOAT(gP->sp);
//xp->value.f--;
flpArg1.d = xp->value.f;
flpArg2.d = 1.0;
FlpBufferCorrectedSub(&theCompFloat.fd, flpArg1.fd, flpArg2.fd, kDefAccuracy);
xp->value.f = theCompFloat.d;
}
break;
case ADD_ASG:
switch(SlotMixedOp(xp = bp - *(++ip), gP->sp))
{
case scriptTypeString:
SlotStrAppend(xp, gP->sp->value.s, StrLen(gP->sp->value.s));
break;
case scriptTypeInteger:
xp->value.n += gP->sp->value.n;
break;
case scriptTypeFloat:
//xp->value.f += gP->sp->value.f;
flpArg1.d = xp->value.f;
flpArg2.d = gP->sp->value.f;
FlpBufferCorrectedAdd(&theCompFloat.fd, flpArg1.fd, flpArg2.fd, kDefAccuracy);
xp->value.f = theCompFloat.d;
break;
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?