static void Ap_forEach(js_State *J) { int hasthis = js_gettop(J) >= 3; int k, len; if (!js_iscallable(J, 1)) js_typeerror(J, "callback is not a function"); len = js_getlength(J, 0); for (k = 0; k < len; ++k) { if (js_hasindex(J, 0, k)) { js_copy(J, 1); if (hasthis) js_copy(J, 2); else js_pushundefined(J); js_copy(J, -3); js_pushnumber(J, k); js_copy(J, 0); js_call(J, 3); js_pop(J, 2); } } js_pushundefined(J); }
static void O_getOwnPropertyDescriptor(js_State *J) { js_Object *obj; js_Property *ref; if (!js_isobject(J, 1)) js_typeerror(J, "not an object"); obj = js_toobject(J, 1); ref = jsV_getproperty(J, obj, js_tostring(J, 2)); if (!ref) js_pushundefined(J); else { js_newobject(J); if (!ref->getter && !ref->setter) { js_pushvalue(J, ref->value); js_setproperty(J, -2, "value"); js_pushboolean(J, !(ref->atts & JS_READONLY)); js_setproperty(J, -2, "writable"); } else { if (ref->getter) js_pushobject(J, ref->getter); else js_pushundefined(J); js_setproperty(J, -2, "get"); if (ref->setter) js_pushobject(J, ref->setter); else js_pushundefined(J); js_setproperty(J, -2, "set"); } js_pushboolean(J, !(ref->atts & JS_DONTENUM)); js_setproperty(J, -2, "enumerable"); js_pushboolean(J, !(ref->atts & JS_DONTCONF)); js_setproperty(J, -2, "configurable"); } }
static void jsB_load(js_State *J) { int i, n = js_gettop(J); for (i = 1; i < n; ++i) { js_loadfile(J, js_tostring(J, i)); js_pushundefined(J); js_call(J, 0); js_pop(J, 1); } js_pushundefined(J); }
static void ToPropertyDescriptor(js_State *J, js_Object *obj, const char *name, js_Object *desc) { int haswritable = 0; int hasvalue = 0; int enumerable = 0; int configurable = 0; int writable = 0; int atts = 0; js_pushobject(J, obj); js_pushobject(J, desc); if (js_hasproperty(J, -1, "writable")) { haswritable = 1; writable = js_toboolean(J, -1); js_pop(J, 1); } if (js_hasproperty(J, -1, "enumerable")) { enumerable = js_toboolean(J, -1); js_pop(J, 1); } if (js_hasproperty(J, -1, "configurable")) { configurable = js_toboolean(J, -1); js_pop(J, 1); } if (js_hasproperty(J, -1, "value")) { hasvalue = 1; js_setproperty(J, -3, name); } if (!writable) atts |= JS_READONLY; if (!enumerable) atts |= JS_DONTENUM; if (!configurable) atts |= JS_DONTCONF; if (js_hasproperty(J, -1, "get")) { if (haswritable || hasvalue) js_typeerror(J, "value/writable and get/set attributes are exclusive"); } else { js_pushundefined(J); } if (js_hasproperty(J, -2, "set")) { if (haswritable || hasvalue) js_typeerror(J, "value/writable and get/set attributes are exclusive"); } else { js_pushundefined(J); } js_defaccessor(J, -4, name, atts); js_pop(J, 2); }
static void wrapsetter(js_State *J) { pdf_jsimp_setter *set; const char *type; void *jsctx; void *obj; js_getregistry(J, "jsctx"); jsctx = js_touserdata(J, "jsctx", -1); js_pop(J, 1); js_currentfunction(J); { js_getproperty(J, -1, "__set"); set = js_touserdata(J, "setter", -1); js_pop(J, 1); js_getproperty(J, -1, "__type"); type = js_tostring(J, -1); js_pop(J, 1); } js_pop(J, 1); if (js_isuserdata(J, type, 0)) obj = js_touserdata(J, type, 0); else obj = NULL; set(jsctx, obj, OBJ(1)); js_pushundefined(J); }
static void Ap_filter(js_State *J) { int hasthis = js_gettop(J) >= 3; int k, to, len; if (!js_iscallable(J, 1)) js_typeerror(J, "callback is not a function"); js_newarray(J); to = 0; len = js_getlength(J, 0); for (k = 0; k < len; ++k) { if (js_hasindex(J, 0, k)) { js_copy(J, 1); if (hasthis) js_copy(J, 2); else js_pushundefined(J); js_copy(J, -3); js_pushnumber(J, k); js_copy(J, 0); js_call(J, 3); if (js_toboolean(J, -1)) { js_pop(J, 1); js_setindex(J, -2, to++); } else { js_pop(J, 2); } } } }
void js_pushundefinedthis(js_State *J) { if (J->strict) js_pushundefined(J); else js_pushobject(J, J->G); }
static void wrapgetter(js_State *J) { pdf_jsimp_obj *ret; pdf_jsimp_getter *get; const char *type; void *jsctx; void *obj; js_getregistry(J, "jsctx"); jsctx = js_touserdata(J, "jsctx", -1); js_pop(J, 1); js_currentfunction(J); { js_getproperty(J, -1, "__get"); get = js_touserdata(J, "getter", -1); js_pop(J, 1); js_getproperty(J, -1, "__type"); type = js_tostring(J, -1); js_pop(J, 1); } js_pop(J, 1); if (js_isuserdata(J, type, 0)) obj = js_touserdata(J, type, 0); else obj = NULL; ret = get(jsctx, obj); if (ret) js_copy(J, IDX(ret)); else js_pushundefined(J); }
static int sortcmp(const void *avoid, const void *bvoid) { const struct sortslot *aslot = avoid, *bslot = bvoid; const js_Value *a = &aslot->v, *b = &bslot->v; js_State *J = aslot->J; const char *sx, *sy; int c; int unx = (a->type == JS_TUNDEFINED); int uny = (b->type == JS_TUNDEFINED); if (unx) return !uny; if (uny) return -1; if (js_iscallable(J, 1)) { js_copy(J, 1); /* copy function */ js_pushundefined(J); js_pushvalue(J, *a); js_pushvalue(J, *b); js_call(J, 2); c = js_tonumber(J, -1); js_pop(J, 1); } else { js_pushvalue(J, *a); js_pushvalue(J, *b); sx = js_tostring(J, -2); sy = js_tostring(J, -1); c = strcmp(sx, sy); js_pop(J, 2); } return c; }
static void js_pushrune(js_State *J, Rune rune) { char buf[UTFmax + 1]; if (rune > 0) { buf[runetochar(buf, &rune)] = 0; js_pushstring(J, buf); } else { js_pushundefined(J); } }
static void jsB_write(js_State *J) { int i, top = js_gettop(J); for (i = 1; i < top; ++i) { const char *s = js_tostring(J, i); if (i > 1) putchar(' '); fputs(s, stdout); } js_pushundefined(J); }
void jsB_init(js_State *J) { /* Create the prototype objects here, before the constructors */ J->Object_prototype = jsV_newobject(J, JS_COBJECT, NULL); J->Array_prototype = jsV_newobject(J, JS_CARRAY, J->Object_prototype); J->Function_prototype = jsV_newobject(J, JS_CCFUNCTION, J->Object_prototype); J->Boolean_prototype = jsV_newobject(J, JS_CBOOLEAN, J->Object_prototype); J->Number_prototype = jsV_newobject(J, JS_CNUMBER, J->Object_prototype); J->String_prototype = jsV_newobject(J, JS_CSTRING, J->Object_prototype); J->RegExp_prototype = jsV_newobject(J, JS_COBJECT, J->Object_prototype); J->Date_prototype = jsV_newobject(J, JS_CDATE, J->Object_prototype); /* All the native error types */ J->Error_prototype = jsV_newobject(J, JS_CERROR, J->Object_prototype); J->EvalError_prototype = jsV_newobject(J, JS_CERROR, J->Error_prototype); J->RangeError_prototype = jsV_newobject(J, JS_CERROR, J->Error_prototype); J->ReferenceError_prototype = jsV_newobject(J, JS_CERROR, J->Error_prototype); J->SyntaxError_prototype = jsV_newobject(J, JS_CERROR, J->Error_prototype); J->TypeError_prototype = jsV_newobject(J, JS_CERROR, J->Error_prototype); J->URIError_prototype = jsV_newobject(J, JS_CERROR, J->Error_prototype); /* Create the constructors and fill out the prototype objects */ jsB_initobject(J); jsB_initarray(J); jsB_initfunction(J); jsB_initboolean(J); jsB_initnumber(J); jsB_initstring(J); jsB_initregexp(J); jsB_initdate(J); jsB_initerror(J); jsB_initmath(J); jsB_initjson(J); /* Initialize the global object */ js_pushnumber(J, NAN); js_defglobal(J, "NaN", JS_READONLY | JS_DONTENUM | JS_DONTCONF); js_pushnumber(J, INFINITY); js_defglobal(J, "Infinity", JS_READONLY | JS_DONTENUM | JS_DONTCONF); js_pushundefined(J); js_defglobal(J, "undefined", JS_READONLY | JS_DONTENUM | JS_DONTCONF); jsB_globalf(J, "eval", jsB_eval, 1); jsB_globalf(J, "parseInt", jsB_parseInt, 1); jsB_globalf(J, "parseFloat", jsB_parseFloat, 1); jsB_globalf(J, "isNaN", jsB_isNaN, 1); jsB_globalf(J, "isFinite", jsB_isFinite, 1); jsB_globalf(J, "decodeURI", jsB_decodeURI, 1); jsB_globalf(J, "decodeURIComponent", jsB_decodeURIComponent, 1); jsB_globalf(J, "encodeURI", jsB_encodeURI, 1); jsB_globalf(J, "encodeURIComponent", jsB_encodeURIComponent, 1); }
void js_util_pushjsonnode(js_State *state, JsonNode *node) { GType type; if (!JSON_NODE_HOLDS_VALUE(node)) { js_pushundefined(state); return; } type = json_node_get_value_type(node); if (type == G_TYPE_STRING) js_pushstring(state, json_node_get_string(node)); else if (type == G_TYPE_INT) js_pushnumber(state, json_node_get_int(node)); else if (type == G_TYPE_BOOLEAN) js_pushboolean(state, json_node_get_boolean(node)); else js_pushundefined(state); }
static void jsR_callcfunction(js_State *J, unsigned int n, unsigned int min, js_CFunction F) { unsigned int i; js_Value v; for (i = n; i < min; ++i) js_pushundefined(J); F(J); v = *stackidx(J, -1); TOP = --BOT; /* clear stack */ js_pushvalue(J, v); }
static void Ap_pop(js_State *J) { unsigned int n; n = js_getlength(J, 0); if (n > 0) { js_getindex(J, 0, n - 1); js_delindex(J, 0, n - 1); js_setlength(J, 0, n - 1); } else { js_setlength(J, 0, 0); js_pushundefined(J); } }
static void wrapmethod(js_State *J) { pdf_jsimp_obj *args[MAXARGS]; pdf_jsimp_obj *ret; pdf_jsimp_method *meth; const char *type; void *jsctx; void *obj; int i; int argc = js_gettop(J) - 1; js_getregistry(J, "jsctx"); jsctx = js_touserdata(J, "jsctx", -1); js_pop(J, 1); js_currentfunction(J); { js_getproperty(J, -1, "__call"); meth = js_touserdata(J, "method", -1); js_pop(J, 1); js_getproperty(J, -1, "__type"); type = js_tostring(J, -1); js_pop(J, 1); } js_pop(J, 1); if (js_isuserdata(J, type, 0)) obj = js_touserdata(J, type, 0); else obj = NULL; if (argc > MAXARGS) js_rangeerror(J, "too many arguments"); for (i = 0; i < argc; ++i) args[i] = OBJ(i+1); ret = meth(jsctx, obj, argc, args); if (ret) js_copy(J, IDX(ret)); else js_pushundefined(J); }
static int eval_print(js_State *J, const char *source) { if (js_ploadstring(J, "[stdin]", source)) { fprintf(stderr, "%s\n", js_trystring(J, -1, "Error")); js_pop(J, 1); return 1; } js_pushundefined(J); if (js_pcall(J, 0)) { fprintf(stderr, "%s\n", js_trystring(J, -1, "Error")); js_pop(J, 1); return 1; } if (js_isdefined(J, -1)) { printf("%s\n", js_tryrepr(J, -1, "can't convert to string")); } js_pop(J, 1); return 0; }
static void jsR_callfunction(js_State *J, unsigned int n, js_Function *F, js_Environment *scope) { js_Value v; unsigned int i; scope = jsR_newenvironment(J, jsV_newobject(J, JS_COBJECT, NULL), scope); jsR_savescope(J, scope); if (F->arguments) { js_newobject(J); if (!J->strict) { js_currentfunction(J); js_defproperty(J, -2, "callee", JS_DONTENUM); } js_pushnumber(J, n); js_defproperty(J, -2, "length", JS_DONTENUM); for (i = 0; i < n; ++i) { js_copy(J, i + 1); js_setindex(J, -2, i); } js_initvar(J, "arguments", -1); js_pop(J, 1); } for (i = 0; i < F->numparams; ++i) { if (i < n) js_initvar(J, F->vartab[i], i + 1); else { js_pushundefined(J); js_initvar(J, F->vartab[i], -1); js_pop(J, 1); } } js_pop(J, n); jsR_run(J, F); v = *stackidx(J, -1); TOP = --BOT; /* clear stack */ js_pushvalue(J, v); jsR_restorescope(J); }
static void jsR_calllwfunction(js_State *J, unsigned int n, js_Function *F, js_Environment *scope) { js_Value v; unsigned int i; jsR_savescope(J, scope); if (n > F->numparams) { js_pop(J, F->numparams - n); n = F->numparams; } for (i = n; i < F->varlen; ++i) js_pushundefined(J); jsR_run(J, F); v = *stackidx(J, -1); TOP = --BOT; /* clear stack */ js_pushvalue(J, v); jsR_restorescope(J); }
static void Ap_reduceRight(js_State *J) { int hasinitial = js_gettop(J) >= 3; int k, len; if (!js_iscallable(J, 1)) js_typeerror(J, "callback is not a function"); len = js_getlength(J, 0); k = len - 1; if (len == 0 && !hasinitial) js_typeerror(J, "no initial value"); /* initial value of accumulator */ if (hasinitial) js_copy(J, 2); else { while (k >= 0) if (js_hasindex(J, 0, k--)) break; if (k < 0) js_typeerror(J, "no initial value"); } while (k >= 0) { if (js_hasindex(J, 0, k)) { js_copy(J, 1); js_pushundefined(J); js_rot(J, 4); /* accumulator on top */ js_rot(J, 4); /* property on top */ js_pushnumber(J, k); js_copy(J, 0); js_call(J, 4); /* calculate new accumulator */ } --k; } /* return accumulator */ }
static void Ap_shift(js_State *J) { unsigned int k, len; len = js_getlength(J, 0); if (len == 0) { js_setlength(J, 0, 0); js_pushundefined(J); return; } js_getindex(J, 0, 0); for (k = 1; k < len; ++k) { if (js_hasindex(J, 0, k)) js_setindex(J, 0, k - 1); else js_delindex(J, 0, k - 1); } js_delindex(J, 0, len - 1); js_setlength(J, 0, len - 1); }
static void jsB_Function_prototype(js_State *J) { js_pushundefined(J); }
static void jsR_getproperty(js_State *J, js_Object *obj, const char *name) { if (!jsR_hasproperty(J, obj, name)) js_pushundefined(J); }
static void jsB_gc(js_State *J) { int report = js_toboolean(J, 1); js_gc(J, report); js_pushundefined(J); }
static void jsR_run(js_State *J, js_Function *F) { js_Function **FT = F->funtab; double *NT = F->numtab; const char **ST = F->strtab; js_Instruction *pcstart = F->code; js_Instruction *pc = F->code; enum js_OpCode opcode; int offset; const char *str; js_Object *obj; double x, y; unsigned int ux, uy; int ix, iy, okay; int b; while (1) { if (J->gccounter > JS_GCLIMIT) { J->gccounter = 0; js_gc(J, 0); } opcode = *pc++; switch (opcode) { case OP_POP: js_pop(J, 1); break; case OP_DUP: js_dup(J); break; case OP_DUP2: js_dup2(J); break; case OP_ROT2: js_rot2(J); break; case OP_ROT3: js_rot3(J); break; case OP_ROT4: js_rot4(J); break; case OP_NUMBER_0: js_pushnumber(J, 0); break; case OP_NUMBER_1: js_pushnumber(J, 1); break; case OP_NUMBER_POS: js_pushnumber(J, *pc++); break; case OP_NUMBER_NEG: js_pushnumber(J, -(*pc++)); break; case OP_NUMBER: js_pushnumber(J, NT[*pc++]); break; case OP_STRING: js_pushliteral(J, ST[*pc++]); break; case OP_CLOSURE: js_newfunction(J, FT[*pc++], J->E); break; case OP_NEWOBJECT: js_newobject(J); break; case OP_NEWARRAY: js_newarray(J); break; case OP_NEWREGEXP: js_newregexp(J, ST[pc[0]], pc[1]); pc += 2; break; case OP_UNDEF: js_pushundefined(J); break; case OP_NULL: js_pushnull(J); break; case OP_TRUE: js_pushboolean(J, 1); break; case OP_FALSE: js_pushboolean(J, 0); break; case OP_THIS: js_copy(J, 0); break; case OP_GLOBAL: js_pushobject(J, J->G); break; case OP_CURRENT: js_currentfunction(J); break; case OP_INITLOCAL: STACK[BOT + *pc++] = STACK[--TOP]; break; case OP_GETLOCAL: CHECKSTACK(1); STACK[TOP++] = STACK[BOT + *pc++]; break; case OP_SETLOCAL: STACK[BOT + *pc++] = STACK[TOP-1]; break; case OP_DELLOCAL: ++pc; js_pushboolean(J, 0); break; case OP_INITVAR: js_initvar(J, ST[*pc++], -1); js_pop(J, 1); break; case OP_DEFVAR: js_defvar(J, ST[*pc++]); break; case OP_GETVAR: str = ST[*pc++]; if (!js_hasvar(J, str)) js_referenceerror(J, "'%s' is not defined", str); break; case OP_HASVAR: if (!js_hasvar(J, ST[*pc++])) js_pushundefined(J); break; case OP_SETVAR: js_setvar(J, ST[*pc++]); break; case OP_DELVAR: b = js_delvar(J, ST[*pc++]); js_pushboolean(J, b); break; case OP_IN: str = js_tostring(J, -2); if (!js_isobject(J, -1)) js_typeerror(J, "operand to 'in' is not an object"); b = js_hasproperty(J, -1, str); js_pop(J, 2 + b); js_pushboolean(J, b); break; case OP_INITPROP: obj = js_toobject(J, -3); str = js_tostring(J, -2); jsR_setproperty(J, obj, str, stackidx(J, -1)); js_pop(J, 2); break; case OP_INITGETTER: obj = js_toobject(J, -3); str = js_tostring(J, -2); jsR_defproperty(J, obj, str, 0, NULL, jsR_tofunction(J, -1), NULL); js_pop(J, 2); break; case OP_INITSETTER: obj = js_toobject(J, -3); str = js_tostring(J, -2); jsR_defproperty(J, obj, str, 0, NULL, NULL, jsR_tofunction(J, -1)); js_pop(J, 2); break; case OP_GETPROP: str = js_tostring(J, -1); obj = js_toobject(J, -2); jsR_getproperty(J, obj, str); js_rot3pop2(J); break; case OP_GETPROP_S: str = ST[*pc++]; obj = js_toobject(J, -1); jsR_getproperty(J, obj, str); js_rot2pop1(J); break; case OP_SETPROP: str = js_tostring(J, -2); obj = js_toobject(J, -3); jsR_setproperty(J, obj, str, stackidx(J, -1)); js_rot3pop2(J); break; case OP_SETPROP_S: str = ST[*pc++]; obj = js_toobject(J, -2); jsR_setproperty(J, obj, str, stackidx(J, -1)); js_rot2pop1(J); break; case OP_DELPROP: str = js_tostring(J, -1); obj = js_toobject(J, -2); b = jsR_delproperty(J, obj, str); js_pop(J, 2); js_pushboolean(J, b); break; case OP_DELPROP_S: str = ST[*pc++]; obj = js_toobject(J, -1); b = jsR_delproperty(J, obj, str); js_pop(J, 1); js_pushboolean(J, b); break; case OP_ITERATOR: if (!js_isundefined(J, -1) && !js_isnull(J, -1)) { obj = jsV_newiterator(J, js_toobject(J, -1), 0); js_pop(J, 1); js_pushobject(J, obj); } break; case OP_NEXTITER: obj = js_toobject(J, -1); str = jsV_nextiterator(J, obj); if (str) { js_pushliteral(J, str); js_pushboolean(J, 1); } else { js_pop(J, 1); js_pushboolean(J, 0); } break; /* Function calls */ case OP_EVAL: js_eval(J); break; case OP_CALL: js_call(J, *pc++); break; case OP_NEW: js_construct(J, *pc++); break; /* Unary operators */ case OP_TYPEOF: str = js_typeof(J, -1); js_pop(J, 1); js_pushliteral(J, str); break; case OP_POS: x = js_tonumber(J, -1); js_pop(J, 1); js_pushnumber(J, x); break; case OP_NEG: x = js_tonumber(J, -1); js_pop(J, 1); js_pushnumber(J, -x); break; case OP_BITNOT: ix = js_toint32(J, -1); js_pop(J, 1); js_pushnumber(J, ~ix); break; case OP_LOGNOT: b = js_toboolean(J, -1); js_pop(J, 1); js_pushboolean(J, !b); break; case OP_INC: x = js_tonumber(J, -1); js_pop(J, 1); js_pushnumber(J, x + 1); break; case OP_DEC: x = js_tonumber(J, -1); js_pop(J, 1); js_pushnumber(J, x - 1); break; case OP_POSTINC: x = js_tonumber(J, -1); js_pop(J, 1); js_pushnumber(J, x + 1); js_pushnumber(J, x); break; case OP_POSTDEC: x = js_tonumber(J, -1); js_pop(J, 1); js_pushnumber(J, x - 1); js_pushnumber(J, x); break; /* Multiplicative operators */ case OP_MUL: x = js_tonumber(J, -2); y = js_tonumber(J, -1); js_pop(J, 2); js_pushnumber(J, x * y); break; case OP_DIV: x = js_tonumber(J, -2); y = js_tonumber(J, -1); js_pop(J, 2); js_pushnumber(J, x / y); break; case OP_MOD: x = js_tonumber(J, -2); y = js_tonumber(J, -1); js_pop(J, 2); js_pushnumber(J, fmod(x, y)); break; /* Additive operators */ case OP_ADD: js_concat(J); break; case OP_SUB: x = js_tonumber(J, -2); y = js_tonumber(J, -1); js_pop(J, 2); js_pushnumber(J, x - y); break; /* Shift operators */ case OP_SHL: ix = js_toint32(J, -2); uy = js_touint32(J, -1); js_pop(J, 2); js_pushnumber(J, ix << (uy & 0x1F)); break; case OP_SHR: ix = js_toint32(J, -2); uy = js_touint32(J, -1); js_pop(J, 2); js_pushnumber(J, ix >> (uy & 0x1F)); break; case OP_USHR: ux = js_touint32(J, -2); uy = js_touint32(J, -1); js_pop(J, 2); js_pushnumber(J, ux >> (uy & 0x1F)); break; /* Relational operators */ case OP_LT: b = js_compare(J, &okay); js_pop(J, 2); js_pushboolean(J, okay && b < 0); break; case OP_GT: b = js_compare(J, &okay); js_pop(J, 2); js_pushboolean(J, okay && b > 0); break; case OP_LE: b = js_compare(J, &okay); js_pop(J, 2); js_pushboolean(J, okay && b <= 0); break; case OP_GE: b = js_compare(J, &okay); js_pop(J, 2); js_pushboolean(J, okay && b >= 0); break; case OP_INSTANCEOF: b = js_instanceof(J); js_pop(J, 2); js_pushboolean(J, b); break; /* Equality */ case OP_EQ: b = js_equal(J); js_pop(J, 2); js_pushboolean(J, b); break; case OP_NE: b = js_equal(J); js_pop(J, 2); js_pushboolean(J, !b); break; case OP_STRICTEQ: b = js_strictequal(J); js_pop(J, 2); js_pushboolean(J, b); break; case OP_STRICTNE: b = js_strictequal(J); js_pop(J, 2); js_pushboolean(J, !b); break; case OP_JCASE: offset = *pc++; b = js_strictequal(J); if (b) { js_pop(J, 2); pc = pcstart + offset; } else { js_pop(J, 1); } break; /* Binary bitwise operators */ case OP_BITAND: ix = js_toint32(J, -2); iy = js_toint32(J, -1); js_pop(J, 2); js_pushnumber(J, ix & iy); break; case OP_BITXOR: ix = js_toint32(J, -2); iy = js_toint32(J, -1); js_pop(J, 2); js_pushnumber(J, ix ^ iy); break; case OP_BITOR: ix = js_toint32(J, -2); iy = js_toint32(J, -1); js_pop(J, 2); js_pushnumber(J, ix | iy); break; /* Try and Catch */ case OP_THROW: js_throw(J); case OP_TRY: offset = *pc++; if (js_trypc(J, pc)) { pc = J->trybuf[J->trytop].pc; } else { pc = pcstart + offset; } break; case OP_ENDTRY: js_endtry(J); break; case OP_CATCH: str = ST[*pc++]; obj = jsV_newobject(J, JS_COBJECT, NULL); js_pushobject(J, obj); js_rot2(J); js_setproperty(J, -2, str); J->E = jsR_newenvironment(J, obj, J->E); js_pop(J, 1); break; case OP_ENDCATCH: J->E = J->E->outer; break; /* With */ case OP_WITH: obj = js_toobject(J, -1); J->E = jsR_newenvironment(J, obj, J->E); js_pop(J, 1); break; case OP_ENDWITH: J->E = J->E->outer; break; /* Branching */ case OP_DEBUGGER: js_trap(J, (int)(pc - pcstart) - 1); break; case OP_JUMP: pc = pcstart + *pc; break; case OP_JTRUE: offset = *pc++; b = js_toboolean(J, -1); js_pop(J, 1); if (b) pc = pcstart + offset; break; case OP_JFALSE: offset = *pc++; b = js_toboolean(J, -1); js_pop(J, 1); if (!b) pc = pcstart + offset; break; case OP_RETURN: return; case OP_LINE: J->trace[J->tracetop].line = *pc++; break; } } }