📄 eswt0.h
字号:
else
{
JS_SP2->type = JS_FLOAT;
if (r->type == JS_INTEGER)
JS_SP2->u.vfloat = l->u.vfloat * (double) r->u.vinteger;
else
JS_SP2->u.vfloat = l->u.vfloat * r->u.vfloat;
}
}
}
JS_POP ();
break;
/* operand div (41) */
case 41:
{
int nan = 0;
double l, r;
int l_inf = 0;
int r_inf = 0;
JSNode *n;
JSNode cvt;
/* Convert divident to float. */
if (JS_IS_NUMBER (JS_SP2))
n = JS_SP2;
else
{
js_vm_to_number (vm, JS_SP2, &cvt);
n = &cvt;
}
switch (n->type)
{
case JS_INTEGER:
l = (double) n->u.vinteger;
break;
case JS_FLOAT:
l = n->u.vfloat;
if (JS_IS_POSITIVE_INFINITY (n) || JS_IS_NEGATIVE_INFINITY (n))
l_inf = 1;
break;
case JS_NAN:
default:
nan = 1;
l = 0.0;
break;
}
/* Convert divisor to float. */
if (JS_IS_NUMBER (JS_SP1))
n = JS_SP1;
else
{
js_vm_to_number (vm, JS_SP2, &cvt);
n = &cvt;
}
switch (n->type)
{
case JS_INTEGER:
r = (double) n->u.vinteger;
break;
case JS_FLOAT:
r = n->u.vfloat;
if (JS_IS_POSITIVE_INFINITY (n) || JS_IS_NEGATIVE_INFINITY (n))
r_inf = 1;
break;
case JS_NAN:
default:
nan = 1;
r = 0.0;
break;
}
/* Do the division. */
JS_POP ();
if (nan || (l_inf && r_inf))
JS_SP1->type = JS_NAN;
else
{
if (l_inf && r == 0.0)
{
/* <l> is already an infinity. */
JS_SP1->type = JS_FLOAT;
JS_SP1->u.vfloat = l;
}
else if (l == 0.0 && r == 0.0)
JS_SP1->type = JS_NAN;
else
{
JS_SP1->type = JS_FLOAT;
JS_SP1->u.vfloat = l / r;
}
}
}
break;
/* operand mod (42) */
case 42:
if (JS_SP2->type == JS_INTEGER && JS_SP1->type == JS_INTEGER)
{
if (JS_SP1->u.vinteger == 0)
JS_SP2->type = JS_NAN;
else
JS_SP2->u.vinteger %= JS_SP1->u.vinteger;
}
else
{
JSNode l_cvt, r_cvt;
JSNode *l, *r;
if (JS_IS_NUMBER (JS_SP2))
l = JS_SP2;
else
{
js_vm_to_number (vm, JS_SP2, &l_cvt);
l = &l_cvt;
}
if (JS_IS_NUMBER (JS_SP1))
r = JS_SP1;
else
{
js_vm_to_number (vm, JS_SP1, &r_cvt);
r = &r_cvt;
}
if (l->type == JS_NAN || r->type == JS_NAN)
JS_SP2->type = JS_NAN;
else if (JS_IS_POSITIVE_INFINITY (l)
|| JS_IS_NEGATIVE_INFINITY (l)
|| ((r->type == JS_INTEGER && r->u.vinteger == 0)
|| (r->type == JS_FLOAT && r->u.vfloat == 0.0)))
JS_SP2->type = JS_NAN;
else if (JS_IS_POSITIVE_INFINITY (r)
|| JS_IS_NEGATIVE_INFINITY (r))
JS_COPY (JS_SP2, l);
else if ((l->type == JS_INTEGER && l->u.vinteger == 0)
|| (l->type == JS_FLOAT && l->u.vfloat == 0.0))
JS_COPY (JS_SP2, l);
else
{
if (l->type == JS_INTEGER && r->type == JS_INTEGER)
{
JS_SP2->type = JS_INTEGER;
JS_SP2->u.vinteger = l->u.vinteger % r->u.vinteger;
}
else
{
double ld, rd;
int full;
if (l->type == JS_INTEGER)
ld = (double) l->u.vinteger;
else
ld = l->u.vfloat;
if (r->type == JS_INTEGER)
rd = (double) r->u.vinteger;
else
rd = r->u.vfloat;
full = ld / rd;
JS_SP2->type = JS_FLOAT;
JS_SP2->u.vfloat = ld - (full * rd);
}
}
}
JS_POP ();
break;
/* operand neg (43) */
case 43:
if (JS_SP1->type == JS_INTEGER)
JS_SP1->u.vinteger = -JS_SP1->u.vinteger;
else if (JS_SP1->type == JS_FLOAT)
JS_SP1->u.vfloat = -JS_SP1->u.vfloat;
else if (JS_SP1->type == JS_NAN)
;
else
{
JSNode cvt;
js_vm_to_number (vm, JS_SP1, &cvt);
JS_SP1->type = cvt.type;
switch (cvt.type)
{
case JS_INTEGER:
JS_SP1->u.vinteger = -cvt.u.vinteger;
break;
case JS_FLOAT:
JS_SP1->u.vfloat = -cvt.u.vfloat;
break;
case JS_NAN:
default:
/* Nothing here. */
break;
}
}
break;
/* operand and (44) */
case 44:
JS_OPERAND_BINARY (&);
break;
/* operand not (45) */
case 45:
JS_SP1->u.vboolean = JS_IS_FALSE (JS_SP1);
JS_SP1->type = JS_BOOLEAN;
break;
/* operand or (46) */
case 46:
JS_OPERAND_BINARY (|);
break;
/* operand xor (47) */
case 47:
JS_OPERAND_BINARY (^);
break;
/* operand shift_left (48) */
case 48:
if (JS_SP2->type == JS_INTEGER && JS_SP1->type == JS_INTEGER)
{
JS_SP2->u.vinteger = ((JSInt32) JS_SP2->u.vinteger
<< (JSUInt32) JS_SP1->u.vinteger);
JS_POP ();
}
else
{
JSInt32 l;
JSUInt32 r;
l = js_vm_to_int32 (vm, JS_SP2);
r = (JSUInt32) js_vm_to_int32 (vm, JS_SP1);
JS_SP2->u.vinteger = l << r;
JS_SP2->type = JS_INTEGER;
JS_POP ();
}
break;
/* operand shift_right (49) */
case 49:
if (JS_SP2->type == JS_INTEGER && JS_SP1->type == JS_INTEGER)
{
JS_SP2->u.vinteger = ((JSInt32) JS_SP2->u.vinteger
>> (JSUInt32) JS_SP1->u.vinteger);
JS_POP ();
}
else
{
JSInt32 l;
JSUInt32 r;
l = js_vm_to_int32 (vm, JS_SP2);
r = (JSUInt32) js_vm_to_int32 (vm, JS_SP1);
JS_SP2->u.vinteger = l >> r;
JS_SP2->type = JS_INTEGER;
JS_POP ();
}
break;
/* operand shift_rright (50) */
case 50:
{
JSInt32 l;
JSUInt32 r;
l = js_vm_to_int32 (vm, JS_SP2);
r = (JSUInt32) js_vm_to_int32 (vm, JS_SP1);
if (r > 0)
JS_SP2->u.vinteger = (l & 0x7fffffff) >> r;
else
JS_SP2->u.vinteger = l;
JS_SP2->type = JS_INTEGER;
JS_POP ();
}
break;
/* operand iffalse (51) */
case 51:
READ_INT32 (i);
if (JS_IS_FALSE (JS_SP1))
SETPC_RELATIVE (i);
JS_POP ();
break;
/* operand iftrue (52) */
case 52:
READ_INT32 (i);
if (JS_IS_TRUE (JS_SP1))
SETPC_RELATIVE (i);
JS_POP ();
break;
/* operand call_method (53) */
case 53:
/* Fetch the method symbol. */
READ_INT32 (j);
if (JS_SP1->type == JS_BUILTIN)
{
JS_SAVE_REGS ();
if (JS_SP1->u.vbuiltin->info->method_proc)
{
if ((*JS_SP1->u.vbuiltin->info->method_proc) (
vm,
JS_SP1->u.vbuiltin->info,
JS_SP1->u.vbuiltin->instance_context, j,
&builtin_result, JS_SP2)
== JS_PROPERTY_UNKNOWN)
ERROR ("call_method: unknown method");
}
else
ERROR ("illegal builtin object for call_method");
JS_COPY (JS_SP0, &builtin_result);
JS_PUSH ();
JS_MAYBE_GC ();
}
else if (JS_SP1->type == JS_OBJECT)
{
JSNode method;
if (js_vm_object_load_property (vm, JS_SP1->u.vobject, j, &method)
== JS_PROPERTY_FOUND)
{
/* The property has been defined in the object. */
if (method.type != JS_FUNC)
ERROR ("call_method: unknown method");
/* And once again. We must do a subroutine call here. */
JS_SUBROUTINE_CALL (method.u.vfunction->implementation);
}
else
/* Let our prototype handle this. */
goto _op_call_method_try_proto;
}
else if (vm->prim[JS_SP1->type])
{
/* The primitive language types. */
_op_call_method_try_proto:
JS_SAVE_REGS ();
if ((*vm->prim[JS_SP1->type]->method_proc) (vm, vm->prim[JS_SP1->type],
JS_SP1, j, &builtin_result,
JS_SP2)
== JS_PROPERTY_UNKNOWN)
{
JSNode method;
int result = JS_PROPERTY_UNKNOWN;
/* Let's see if we can find it from the prototype. */
if (JS_SP1->type == JS_STRING && JS_SP1->u.vstring->prototype)
result = js_vm_object_load_property (vm,
JS_SP1->u.vstring->prototype,
j, &method);
else if (JS_SP1->type == JS_ARRAY && JS_SP1->u.varray->prototype)
result = js_vm_object_load_property (vm,
JS_SP1->u.varray->prototype,
j, &method);
else if (JS_SP1->type == JS_FUNC && JS_SP1->u.vfunction->prototype)
result
= js_vm_object_load_property (vm, JS_SP1->u.vfunction->prototype,
j, &method);
if (result == JS_PROPERTY_UNKNOWN || method.type != JS_FUNC)
ERROR ("call_method: unknown method");
/* Do the subroutine call. */
JS_SUBROUTINE_CALL (method.u.vfunction->implementation);
}
else
{
JS_COPY (JS_SP0, &builtin_result);
JS_PUSH ();
JS_MAYBE_GC ();
}
}
else
ERROR ("illegal object for call_method");
break;
/* operand jmp (54) */
case 54:
READ_INT32 (i);
SETPC_RELATIVE (i);
break;
/* operand jsr (55) */
case 55:
/* Call the global method. */
{
JSNode f;
/* Fetch the function to our local variable. */
JS_COPY (&f, JS_SP1);
function = &f;
/* Reset the `this' to null. */
JS_SP1->type = JS_NULL;
if (function->type == JS_BUILTIN
&& function->u.vbuiltin->info->global_method_proc)
{
JS_SAVE_REGS ();
(*function->u.vbuiltin->info->global_method_proc) (
vm,
function->u.vbuiltin->info,
function->u.vbuiltin->instance_context,
&builtin_result,
JS_SP2);
JS_COPY (JS_SP0, &builtin_result);
JS_PUSH ();
}
else if (function->type == JS_FUNC)
{
JS_SUBROUTINE_CALL (function->u.vfunction->implementation);
}
else
{
sprintf (buf, "illegal function object in jsr");
ERROR (buf);
}
}
break;
/* operand return (56) */
case 56:
if (fp->u.iptr == NULL)
/* Return from the global scope. */
DONE ();
/* STACKFRAME */
/* Check if the stack has been modified by min_args. */
if (JS_ARGS_FIXP->u.args_fix.delta)
{
unsigned int delta = JS_ARGS_FIXP->u.args_fix.delta;
/*
* Yes it was. Truncate it back to the state where it was
* before the call.
*/
memmove (JS_SP1 + delta, JS_SP1,
(fp - JS_SP0 + JS_ARGS_FIXP->u.args_fix.argc)
* sizeof (JSNode));
sp += delta;
fp += delta;
}
/* Set pc to the saved return address. */
#if 0
if (fp[-3].type != JS_IPTR)
ERROR ("can't find saved return address");
#endif
pc = fp[-3].u.iptr;
{
void *old_fp;
/* Save old frame pointer. */
#if 0
if (fp->type != JS_IPTR)
ERROR ("can't find saved frame pointer");
#endif
old_fp = fp->u.iptr;
/* Put return value to its correct location. */
JS_COPY (fp, JS_SP1);
/* Restore sp. */
sp = &fp[-1];
/* Restore frame pointer. */
fp = old_fp;
}
break;
/* operand typeof (57) */
case 57:
{
char *typeof_name = ""; /* Initialized to make compiler quiet. */
switch (JS_SP1->type)
{
case JS_UNDEFINED:
typeof_name = "undefined";
break;
case JS_NULL:
typeof_name = "object";
break;
case JS_BOOLEAN:
typeof_name = "boolean";
break;
case JS_INTEGER:
case JS_FLOAT:
case JS_NAN:
typeof_name = "number";
break;
case JS_STRING:
typeof_name = "string";
break;
case JS_ARRAY:
typeof_name = "#array";
break;
case JS_OBJECT:
typeof_name = "object";
break;
case JS_SYMBOL:
typeof_name = "#symbol";
break;
case JS_BUILTIN:
typeof_name = "#builtin";
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -