}
js_Interpret(JSContext *cx, jsval *result){    JSRuntime *rt;    JSStackFrame *fp;    JSScript *script;    uintN inlineCallCount;    JSObject *obj, *obj2, *proto, *parent;    JSVersion currentVersion, originalVersion;    JSBranchCallback onbranch;    JSBool ok, cond;    jsint depth, len;    jsval *sp, *newsp;    void *mark;    jsbytecode *pc, *pc2, *endpc;    JSOp op, op2;    JSCodeSpec *cs;    JSAtom *atom;    uintN argc, slot, attrs;    jsval *vp, lval, rval, ltmp, rtmp;    jsid id;    JSObject *withobj, *origobj, *propobj;    JSIdArray *ida;    jsval iter_state;    JSProperty *prop;    JSScopeProperty *sprop;    JSString *str, *str2;    jsint i, j;    jsdouble d, d2;    JSClass *clasp, *funclasp;    JSFunction *fun;    JSType type;#ifdef DEBUG    FILE *tracefp;#endif#if JS_HAS_SWITCH_STATEMENT    jsint low, high, off, npairs;    JSBool match;#endif#if JS_HAS_GETTER_SETTER    JSPropertyOp getter, setter;#endif    *result = JSVAL_VOID;    rt = cx->runtime;    /* Set registerized frame pointer and derived script pointer. */    fp = cx->fp;    script = fp->script;    /* Count of JS function calls that nest in this C js_Interpret frame. */    inlineCallCount = 0;    /*     * Optimized Get and SetVersion for proper script language versioning.     *     * If any native method or JSClass/JSObjectOps hook calls JS_SetVersion     * and changes cx->version, the effect will "stick" and we will stop     * maintaining currentVersion.  This is relied upon by testsuites, for     * the most part -- web browsers select version before compiling and not     * at run-time.     */    currentVersion = script->version;    originalVersion = cx->version;    if (currentVersion != originalVersion)        JS_SetVersion(cx, currentVersion);    /*     * Prepare to call a user-supplied branch handler, and abort the script     * if it returns false.     */    onbranch = cx->branchCallback;    ok = JS_TRUE;#define CHECK_BRANCH(len)                                                     \    JS_BEGIN_MACRO                                                            \        if (len <= 0 && onbranch) {                                           \            SAVE_SP(fp);                                                      \            if (!(ok = (*onbranch)(cx, script)))                              \                goto out;                                                     \        }                                                                     \    JS_END_MACRO    pc = script->code;    endpc = pc + script->length;    len = -1;    /*     * Allocate operand and pc stack slots for the script's worst-case depth.     */    depth = (jsint) script->depth;    newsp = js_AllocRawStack(cx, (uintN)(2 * depth), &mark);    if (!newsp) {        ok = JS_FALSE;        goto out;    }    sp = newsp + depth;    fp->spbase = sp;    SAVE_SP(fp);    if (++cx->interpLevel == MAX_INTERP_LEVEL) {        JS_ReportErrorNumber(cx, js_GetErrorMessage, NULL, JSMSG_OVER_RECURSED);        ok = JS_FALSE;        goto out;    }    while (pc < endpc) {        fp->pc = pc;        op = (JSOp) *pc;      do_op:        cs = &js_CodeSpec[op];        len = cs->length;#ifdef DEBUG        tracefp = (FILE *) cx->tracefp;        if (tracefp) {            intN nuses, n;            fprintf(tracefp, "%4u: ", js_PCToLineNumber(script, pc));            js_Disassemble1(cx, script, pc,                            PTRDIFF(pc, script->code, jsbytecode), JS_FALSE,                            tracefp);            nuses = cs->nuses;            if (nuses) {                SAVE_SP(fp);                for (n = -nuses; n < 0; n++) {                    str = js_DecompileValueGenerator(cx, n, sp[n], NULL);                    if (str != NULL) {                        fprintf(tracefp, "%s %s",                                (n == -nuses) ? "  inputs:" : ",",                                JS_GetStringBytes(str));                    }                }                fprintf(tracefp, " @ %d\n", sp - fp->spbase);            }        }#endif        {            JSTrapHandler handler = rt->interruptHandler;            if (handler) {                SAVE_SP(fp);                switch (handler(cx, script, pc, &rval,                                rt->interruptHandlerData)) {                  case JSTRAP_ERROR:                    ok = JS_FALSE;                    goto out;                  case JSTRAP_CONTINUE:                    break;                  case JSTRAP_RETURN:                    fp->rval = rval;                    goto out;#if JS_HAS_EXCEPTIONS                  case JSTRAP_THROW:                    cx->throwing = JS_TRUE;                    cx->exception = rval;                    ok = JS_FALSE;                    goto out;#endif /* JS_HAS_EXCEPTIONS */                  default:;                }            }        }        switch (op) {          case JSOP_NOP:            break;          case JSOP_GROUP:            obj = NULL;            break;          case JSOP_PUSH:            PUSH_OPND(JSVAL_VOID);            break;          case JSOP_POP:            sp--;            break;          case JSOP_POP2:            sp -= 2;            break;          case JSOP_SWAP:            /*             * N.B. JSOP_SWAP doesn't swap the corresponding pc stack             * generating pcs, as they're not needed for the current use of             * preserving the top-of-stack return value when popping scopes             * while returning from catch blocks.             */            ltmp = sp[-1];            sp[-1] = sp[-2];            sp[-2] = ltmp;            break;          case JSOP_POPV:            *result = POP_OPND();            break;          case JSOP_ENTERWITH:            rval = FETCH_OPND(-1);            VALUE_TO_OBJECT(cx, rval, obj);            withobj = js_NewObject(cx, &js_WithClass, obj, fp->scopeChain);            if (!withobj)                goto out;            fp->scopeChain = withobj;            STORE_OPND(-1, OBJECT_TO_JSVAL(withobj));            break;          case JSOP_LEAVEWITH:            rval = POP_OPND();            JS_ASSERT(JSVAL_IS_OBJECT(rval));            withobj = JSVAL_TO_OBJECT(rval);            JS_ASSERT(OBJ_GET_CLASS(cx, withobj) == &js_WithClass);            rval = OBJ_GET_SLOT(cx, withobj, JSSLOT_PARENT);            JS_ASSERT(JSVAL_IS_OBJECT(rval));            fp->scopeChain = JSVAL_TO_OBJECT(rval);            break;          case JSOP_SETRVAL:            fp->rval = POP_OPND();            break;          case JSOP_RETURN:            CHECK_BRANCH(-1);            fp->rval = POP_OPND();            /* FALL THROUGH */          case JSOP_RETRVAL:    /* fp->rval already set */            if (inlineCallCount)          inline_return:            {                JSInlineFrame *ifp = (JSInlineFrame *) fp;                void *hookData = ifp->hookData;                if (hookData) {                    JSInterpreterHook hook = cx->runtime->callHook;                    if (hook)                        hook(cx, fp, JS_FALSE, &ok, hookData);                }#if JS_HAS_ARGS_OBJECT                if (fp->argsobj)                    ok &= js_PutArgsObject(cx, fp);#endif                /* Restore context version only if callee hasn't set version. */                if (cx->version == currentVersion) {                    currentVersion = ifp->callerVersion;                    if (currentVersion != cx->version)                        JS_SetVersion(cx, currentVersion);                }                /* Store the return value in the caller's operand frame. */                vp = fp->argv - 2;                *vp = fp->rval;                /* Restore cx->fp and release the inline frame's space. */                cx->fp = fp = fp->down;                JS_ARENA_RELEASE(&cx->stackPool, ifp->mark);                /* Restore sp to point just above the return value. */                fp->sp = vp + 1;                RESTORE_SP(fp);                /* Restore the calling script's interpreter registers. */                script = fp->script;                depth = (jsint) script->depth;                pc = fp->pc;                endpc = script->code + script->length;                /* Store the generating pc for the return value. */                vp[-depth] = (jsval)pc;                /* Set remaining variables for 'goto advance_pc'. */                op = (JSOp) *pc;                cs = &js_CodeSpec[op];                len = cs->length;                /* Resume execution in the calling frame. */                inlineCallCount--;                if (ok)                    goto advance_pc;            }            goto out;#if JS_HAS_SWITCH_STATEMENT          case JSOP_DEFAULT:            (void) POP();            /* FALL THROUGH */#endif          case JSOP_GOTO:            len = GET_JUMP_OFFSET(pc);            CHECK_BRANCH(len);            break;          case JSOP_IFEQ:            POP_BOOLEAN(cx, rval, cond);            if (cond == JS_FALSE) {                len = GET_JUMP_OFFSET(pc);                CHECK_BRANCH(len);            }            break;          case JSOP_IFNE:            POP_BOOLEAN(cx, rval, cond);            if (cond != JS_FALSE) {                len = GET_JUMP_OFFSET(pc);                CHECK_BRANCH(len);            }            break;          case JSOP_OR:            POP_BOOLEAN(cx, rval, cond);            if (cond == JS_TRUE) {                len = GET_JUMP_OFFSET(pc);                PUSH_OPND(rval);            }            break;          case JSOP_AND:            POP_BOOLEAN(cx, rval, cond);            if (cond == JS_FALSE) {                len = GET_JUMP_OFFSET(pc);                PUSH_OPND(rval);            }            break;#if JS_HAS_SWITCH_STATEMENT          case JSOP_DEFAULTX:            (void) POP();            /* FALL THROUGH */#endif          case JSOP_GOTOX:            len = GET_JUMPX_OFFSET(pc);            CHECK_BRANCH(len);            break;          case JSOP_IFEQX:            POP_BOOLEAN(cx, rval, cond);            if (cond == JS_FALSE) {                len = GET_JUMPX_OFFSET(pc);                CHECK_BRANCH(len);            }            break;          case JSOP_IFNEX:            POP_BOOLEAN(cx, rval, cond);            if (cond != JS_FALSE) {                len = GET_JUMPX_OFFSET(pc);                CHECK_BRANCH(len);            }            break;          case JSOP_ORX:            POP_BOOLEAN(cx, rval, cond);            if (cond == JS_TRUE) {                len = GET_JUMPX_OFFSET(pc);                PUSH_OPND(rval);            }            break;          case JSOP_ANDX:            POP_BOOLEAN(cx, rval, cond);            if (cond == JS_FALSE) {                len = GET_JUMPX_OFFSET(pc);                PUSH_OPND(rval);            }            break;          case JSOP_TOOBJECT:            SAVE_SP(fp);            obj = js_ValueToNonNullObject(cx, FETCH_OPND(-1));            if (!obj) {                ok = JS_FALSE;                goto out;            }            STORE_OPND(-1, OBJECT_TO_JSVAL(obj));            break;#define FETCH_ELEMENT_ID(n, id)                                               \    JS_BEGIN_MACRO                                                            \        /* If the index is not a jsint, atomize it. */                        \        id = (jsid) FETCH_OPND(n);                                            \        if (JSVAL_IS_INT(id)) {                                               \            atom = NULL;                                                      \        } else {                                                              \            SAVE_SP(fp);                                                      \            atom = js_ValueToStringAtom(cx, (jsval)id);                       \            if (!atom) {                                                      \                ok = JS_FALSE;                                                \                goto out;                                                     \            }                                                                 \            id = (jsid)atom;                                                  \        }                                                                     \    JS_END_MACRO#define POP_ELEMENT_ID(id)                                                    \    JS_BEGIN_MACRO                                                            \        FETCH_ELEMENT_ID(-1, id);                                             \        sp--;                                                                 \    JS_END_MACRO#if JS_HAS_IN_OPERATOR          case JSOP_IN:            rval = FETCH_OPND(-1);            if (JSVAL_IS_PRIMITIVE(rval)) {                str = js_DecompileValueGenerator(cx, -1, rval, NULL);                if (str) {                    JS_ReportErrorNumber(cx, js_GetErrorMessage, NULL,                                         JSMSG_IN_NOT_OBJECT,                                         JS_GetStringBytes(str));                }                ok = JS_FALSE;                goto out;            }            sp--;            obj = JSVAL_TO_OBJECT(rval);            FETCH_ELEMENT_ID(-1, id);            ok = OBJ_LOOKUP_PROPERTY(cx, obj, id, &obj2, &prop);            if (!ok)                goto out;            STORE_OPND(-1, BOOLEAN_TO_JSVAL(prop != NULL));            if (prop)                OBJ_DROP_PROPERTY(cx, obj2, prop);            break;#endif /* JS_HAS_IN_OPERATOR */          case JSOP_FORPROP:            /*             * Handle JSOP_FORPROP first, so the cost of the goto do_forinloop             * is not paid for the more common cases.             */            lval = FETCH_OPND(-1);            atom = GET_ATOM(cx, script, pc);            id   = (jsid)atom;            i = -2;            goto do_forinloop;          case JSOP_FORNAME:            atom = GET_ATOM(cx, script, pc);            id   = (jsid)atom;            /*             * ECMA 12.6.3 says to eval the LHS after looking for properties             * to enumerate, and bail without LHS eval if there are no props.             * We do Find here to share the most code at label do_forinloop.             * If looking for enumerable properties could have side effects,             * then we'd have to move this into the common code and condition             * it on op == JSOP_FORNAME.             */            SAVE_SP(fp);            ok = js_FindProperty(cx, id, &obj, &obj2, &prop);            if (!ok)                goto out;            if (prop)                OBJ_DROP_PROPERTY(cx, obj2, prop);            lval = OBJECT_TO_JSVAL(obj);            /* FALL THROUGH */          case JSOP_FORARG:          case JSOP_FORVAR:            /*             * JSOP_FORARG and JSOP_FORVAR don't require any lval computation             * here, because they address slots on the stack (in fp->args and             * fp->vars, respectively).             */            /* FALL THROUGH */          case JSOP_FORELEM:            /*             * JSOP_FORELEM simply initializes or updates the iteration state             * and leaves the index expression evaluation and assignment to the             * enumerator until after the next property has been acquired, via             * a JSOP_ENUMELEM bytecode.             */            i = -1;          do_forinloop:            /*             * ECMA-compatible for/in evals the object just once, before loop.             * Bad old bytecodes (since removed) did it on every iteration.             */            obj = JSVAL_TO_OBJECT(sp[i]);            /* If the thing to the right of 'in' has no properties, break. */            if (!obj) {                rval = JSVAL_FALSE;                goto end_forinloop;            }            /*             * Save the thing to the right of 'in' as origobj.  Later on, we             * use this variable to suppress enumeration of shadowed prototype             * properties.             */            origobj = obj;            /*             * Reach under the top of stack to find our property iterator, a             * JSObject that contains the iteration state.  (An object is used             * rather than a native struct so that the iteration state is             * cleaned up via GC if the for-in loop terminates abruptly.)             */            vp = &sp[i - 1];            rval = *vp;            /* Is this the first iteration ? */            if (JSVAL_IS_VOID(rval)) {                /* Yes, create a new JSObject to hold the iterator state */                propobj = js_NewObject(cx, &prop_iterator_class, NULL, obj);                if (!propobj) {                    ok = JS_FALSE;                    goto out;                }                /*                 * Root the parent slot so we can get it even in our finalizer                 * (otherwise, it would live as long as we do, but it might be                 * finalized first).                 */                ok = js_AddRoot(cx, &propobj->slots[JSSLOT_PARENT], NULL);                if (!ok)                    goto out;                /*                 * Rewrite the iterator so we know to do the next case.                 * Do this before calling the enumerator, which could                 * displace cx->newborn and cause GC.                 */                *vp = OBJECT_TO_JSVAL(propobj);                ok = OBJ_ENUMERATE(cx, obj, JSENUMERATE_INIT, &iter_state, 0);                /*                 * Stash private iteration state into property iterator object.                 * We do this before checking 'ok' to ensure that propobj is                 * in a valid state even if OBJ_ENUMERATE returned JS_FALSE.                 * NB: This code knows that the first slots are pre-allocated.                 */#if JS_INITIAL_NSLOTS < 5#error JS_INITIAL_NSLOTS must be greater than or equal to 5.#endif                propobj->slots[JSSLOT_ITER_STATE] = iter_state;                if (!ok)                    goto out;            } else {                /* This is not the first iteration. Recover iterator state. */                propobj = JSVAL_TO_OBJECT(rval);                obj = JSVAL_TO_OBJECT(propobj->slots[JSSLOT_PARENT]);                iter_state = propobj->slots[JSSLOT_ITER_STATE];            }          enum_next_property:            /* Get the next jsid to be enumerated and store it in rval. */            OBJ_ENUMERATE(cx, obj, JSENUMERATE_NEXT, &iter_state, &rval);            propobj->slots[JSSLOT_ITER_STATE] = iter_state;            /* No more jsids to iterate in obj? */            if (iter_state == JSVAL_NULL) {                /* Enumerate the properties on obj's prototype chain. */                obj = OBJ_GET_PROTO(cx, obj);                if (!obj) {                    /* End of property list -- terminate loop. */                    rval = JSVAL_FALSE;                    goto end_forinloop;                }                ok = OBJ_ENUMERATE(cx, obj, JSENUMERATE_INIT, &iter_state, 0);                /*                 * Stash private iteration state into property iterator object.                 * We do this before checking 'ok' to ensure that propobj is                 * in a valid state even if OBJ_ENUMERATE returned JS_FALSE.                 * NB: This code knows that the first slots are pre-allocated.                 */                propobj->slots[JSSLOT_ITER_STATE] = iter_state;                if (!ok)                    goto out;                /*                 * Update the iterator JSObject's parent link to refer to the                 * current object. This is used in the iterator JSObject's                 * finalizer.                 */                propobj->slots[JSSLOT_PARENT] = OBJECT_TO_JSVAL(obj);                goto enum_next_property;            }            /* Skip properties not owned by obj, and leave next id in rval. */            ok = OBJ_LOOKUP_PROPERTY(cx, origobj, rval, &obj2, &prop);            if (!ok)                goto out;            if (prop) {                OBJ_DROP_PROPERTY(cx, obj2, prop);                /* Yes, don't enumerate again.  Go to the next property. */                if (obj2 != obj)                    goto enum_next_property;            }            /* Make sure rval is a string for uniformity and compatibility. */            if (!JSVAL_IS_INT(rval)) {                rval = ATOM_KEY((JSAtom *)rval);            } else if (cx->version != JSVERSION_1_2) {                str = js_NumberToString(cx, (jsdouble) JSVAL_TO_INT(rval));                if (!str) {                    ok = JS_FALSE;                    goto out;                }                rval = STRING_TO_JSVAL(str);            }            switch (op) {              case JSOP_FORARG:                slot = GET_ARGNO(pc);                JS_ASSERT(slot < fp->fun->nargs);                fp->argv[slot] = rval;                break;              case JSOP_FORVAR:                slot = GET_VARNO(pc);                JS_ASSERT(slot < fp->fun->nvars);                fp->vars[slot] = rval;                break;              case JSOP_FORELEM:                /* FORELEM is not a SET operation, it's more like BINDNAME. */                PUSH_OPND(rval);                break;              default:                /* Convert lval to a non-null object containing id. */                VALUE_TO_OBJECT(cx, lval, obj);                /* Set the variable obj[id] to refer to rval. */                fp->flags |= JSFRAME_ASSIGNING;                ok = OBJ_SET_PROPERTY(cx, obj, id, &rval);                fp->flags &= ~JSFRAME_ASSIGNING;                if (!ok)                    goto out;                break;            }            /* Push true to keep looping through properties. */            rval = JSVAL_TRUE;          end_forinloop:            sp += i + 1;            PUSH_OPND(rval);            break;          case JSOP_DUP:            JS_ASSERT(sp > fp->spbase);            rval = sp[-1];            PUSH_OPND(rval);            break;          case JSOP_DUP2:            JS_ASSERT(sp - 1 > fp->spbase);            lval = FETCH_OPND(-2);            rval = FETCH_OPND(-1);            PUSH_OPND(lval);            PUSH_OPND(rval);            break;#define PROPERTY_OP(n, call)                                                  \    JS_BEGIN_MACRO                                                            \        /* Pop the left part and resolve it to a non-null object. */          \        lval = FETCH_OPND(n);                                                 \        VALUE_TO_OBJECT(cx, lval, obj);                                       \                                                                              \        /* Get or set the property, set ok false if error, true if success. */\        SAVE_SP(fp);                                                          \        call;                                                                 \        if (!ok)                                                              \            goto out;                                                         \    JS_END_MACRO#define ELEMENT_OP(n, call)                                                   \    JS_BEGIN_MACRO                                                            \        FETCH_ELEMENT_ID(n, id);                                              \        PROPERTY_OP(n-1, call);                                               \    JS_END_MACRO/* * Direct callers, i.e. those who do not wrap CACHED_GET and CACHED_SET calls * in PROPERTY_OP or ELEMENT_OP macro calls must SAVE_SP(fp); beforehand, just * in case a getter or setter function is invoked. */#define CACHED_GET(call)                                                      \    JS_BEGIN_MACRO                                                            \        if (!OBJ_IS_NATIVE(obj)) {                                            \            ok = call;                                                        \        } else {                                                              \            JS_LOCK_OBJ(cx, obj);                                             \            PROPERTY_CACHE_TEST(&rt->propertyCache, obj, id, sprop);          \            if (sprop) {                                                      \                JSScope *scope_ = OBJ_SCOPE(obj);                             \                slot = (uintN)sprop->slot;                                    \                rval = (slot != SPROP_INVALID_SLOT)                           \                       ? LOCKED_OBJ_GET_SLOT(obj, slot)                       \                       : JSVAL_VOID;                                          \                JS_UNLOCK_SCOPE(cx, scope_);                                  \                ok = SPROP_GET(cx, sprop, obj, obj, &rval);                   \                JS_LOCK_SCOPE(cx, scope_);                                    \                if (ok && SPROP_HAS_VALID_SLOT(sprop, scope_))                \                    LOCKED_OBJ_SET_SLOT(obj, slot, rval);                     \                JS_UNLOCK_SCOPE(cx, scope_);                                  \            } else {                                                          \                JS_UNLOCK_OBJ(cx, obj);                                       \                ok = call;                                                    \                /* No fill here: js_GetProperty fills the cache. */           \            }                                                                 \        }                                                                     \    JS_END_MACRO#define CACHED_SET(call)                                                      \    JS_BEGIN_MACRO                                                            \        if (!OBJ_IS_NATIVE(obj)) {                                            \            ok = call;                                                        \        } else {                                                              \            JS_LOCK_OBJ(cx, obj);                                             \            PROPERTY_CACHE_TEST(&rt->propertyCache, obj, id, sprop);          \            if (sprop && !(sprop->attrs & JSPROP_READONLY)) {                 \                JSScope *scope_ = OBJ_SCOPE(obj);                             \                JS_UNLOCK_SCOPE(cx, scope_);                                  \                ok = SPROP_SET(cx, sprop, obj, obj, &rval);                   \                JS_LOCK_SCOPE(cx, scope_);                                    \                if (ok && SPROP_HAS_VALID_SLOT(sprop, scope_)) {              \                    LOCKED_OBJ_SET_SLOT(obj, sprop->slot, rval);              \                    GC_POKE(cx, JSVAL_NULL);  /* XXX second arg ignored */    \                }                                                             \                JS_UNLOCK_SCOPE(cx, scope_);                                  \            } else {                                                          \                JS_UNLOCK_OBJ(cx, obj);                                       \                ok = call;                                                    \                /* No fill here: js_SetProperty writes through the cache. */  \            }                                                                 \        }                                                                     \    JS_END_MACRO          case JSOP_SETCONST:            obj = fp->varobj;            atom = GET_ATOM(cx, script, pc);            rval = FETCH_OPND(-1);            ok = OBJ_DEFINE_PROPERTY(cx, obj, (jsid)atom, rval, NULL, NULL,                                     JSPROP_ENUMERATE | JSPROP_PERMANENT |                                     JSPROP_READONLY,                                     NULL);            if (!ok)                goto out;            STORE_OPND(-1, rval);            break;          case JSOP_BINDNAME:            atom = GET_ATOM(cx, script, pc);            SAVE_SP(fp);            ok = js_FindVariable(cx, (jsid)atom, &obj, &obj2, &prop);            if (!ok)                goto out;            OBJ_DROP_PROPERTY(cx, obj2, prop);            PUSH_OPND(OBJECT_TO_JSVAL(obj));            break;          case JSOP_SETNAME:            atom = GET_ATOM(cx, script, pc);            id   = (jsid)atom;            rval = FETCH_OPND(-1);            lval = FETCH_OPND(-2);            JS_ASSERT(!JSVAL_IS_PRIMITIVE(lval));            obj  = JSVAL_TO_OBJECT(lval);            SAVE_SP(fp);            CACHED_SET(OBJ_SET_PROPERTY(cx, obj, id, &rval));            if (!ok)                goto out;            sp--;            STORE_OPND(-1, rval);            break;#define INTEGER_OP(OP, EXTRA_CODE)                                            \    JS_BEGIN_MACRO                                                            \        FETCH_INT(cx, -1, j);                                                 \        FETCH_INT(cx, -2, i);                                                 \        if (!ok)                                                              \            goto out;                                                         \        EXTRA_CODE                                                            \        d = i OP j;                                                           \        sp--;                                                                 \        STORE_NUMBER(cx, -1, d);                                              \    JS_END_MACRO#define BITWISE_OP(OP)          INTEGER_OP(OP, (void) 0;)#define SIGNED_SHIFT_OP(OP)     INTEGER_OP(OP, j &= 31;)          case JSOP_BITOR:            BITWISE_OP(|);            break;          case JSOP_BITXOR:            BITWISE_OP(^);            break;          case JSOP_BITAND:            BITWISE_OP(&);            break;#ifdef XP_PC#define COMPARE_DOUBLES(LVAL, OP, RVAL, IFNAN)                                \    ((JSDOUBLE_IS_NaN(LVAL) || JSDOUBLE_IS_NaN(RVAL))                         \     ? (IFNAN)                                                                \     : (LVAL) OP (RVAL))#else#define COMPARE_DOUBLES(LVAL, OP, RVAL, IFNAN) ((LVAL) OP (RVAL))#endif#define RELATIONAL_OP(OP)                                                     \    JS_BEGIN_MACRO                                                            \        rval = FETCH_OPND(-1);                                                \        lval = FETCH_OPND(-2);                                                \        /* Optimize for two int-tagged operands (typical loop control). */    \        if ((lval & rval) & JSVAL_INT) {                                      \            ltmp = lval ^ JSVAL_VOID;                                         \            rtmp = rval ^ JSVAL_VOID;                                         \            if (ltmp && rtmp) {                                               \                cond = JSVAL_TO_INT(lval) OP JSVAL_TO_INT(rval);              \            } else {                                                          \                d  = ltmp ? JSVAL_TO_INT(lval) : *rt->jsNaN;                  \                d2 = rtmp ? JSVAL_TO_INT(rval) : *rt->jsNaN;                  \                cond = COMPARE_DOUBLES(d, OP, d2, JS_FALSE);                  \            }                                                                 \        } else {                                                              \            VALUE_TO_PRIMITIVE(cx, lval, JSTYPE_NUMBER, &lval);               \            VALUE_TO_PRIMITIVE(cx, rval, JSTYPE_NUMBER, &rval);               \            if (JSVAL_IS_STRING(lval) && JSVAL_IS_STRING(rval)) {             \                str  = JSVAL_TO_STRING(lval);                                 \                str2 = JSVAL_TO_STRING(rval);                                 \                cond = js_CompareStrings(str, str2) OP 0;                     \            } else {                                                          \                VALUE_TO_NUMBER(cx, lval, d);                                 \                VALUE_TO_NUMBER(cx, rval, d2);                                \                cond = COMPARE_DOUBLES(d, OP, d2, JS_FALSE);                  \            }                                                                 \        }                                                                     \        sp--;                                                                 \        STORE_OPND(-1, BOOLEAN_TO_JSVAL(cond));                               \    JS_END_MACRO#define EQUALITY_OP(OP, IFNAN)                                                \    JS_BEGIN_MACRO                                                            \        rval = FETCH_OPND(-1);                                                \        lval = FETCH_OPND(-2);                                                \        ltmp = JSVAL_TAG(lval);                                               \        rtmp = JSVAL_TAG(rval);                                               \        if (ltmp == rtmp) {                                                   \            if (ltmp == JSVAL_STRING) {                                       \                str  = JSVAL_TO_STRING(lval);                                 \                str2 = JSVAL_TO_STRING(rval);                                 \                cond = js_CompareStrings(str, str2) OP 0;                     \            } else if (ltmp == JSVAL_DOUBLE) {                                \                d  = *JSVAL_TO_DOUBLE(lval);                                  \                d2 = *JSVAL_TO_DOUBLE(rval);                                  \                cond = COMPARE_DOUBLES(d, OP, d2, IFNAN);                     \            } else {                                                          \                /* Handle all undefined (=>NaN) and int combinations. */      \                cond = lval OP rval;                                          \            }                                                                 \        } else {                                                              \            if (JSVAL_IS_NULL(lval) || JSVAL_IS_VOID(lval)) {                 \                cond = (JSVAL_IS_NULL(rval) || JSVAL_IS_VOID(rval)) OP 1;     \            } else if (JSVAL_IS_NULL(rval) || JSVAL_IS_VOID(rval)) {          \                cond = 1 OP 0;                                                \            } else {                                                          \                if (ltmp == JSVAL_OBJECT) {                                   \                    VALUE_TO_PRIMITIVE(cx, lval, JSTYPE_VOID, &lval);         \                    ltmp = JSVAL_TAG(lval);                                   \                } else if (rtmp == JSVAL_OBJECT) {                            \                    VALUE_TO_PRIMITIVE(cx, rval, JSTYPE_VOID, &rval);         \                    rtmp = JSVAL_TAG(rval);                                   \                }                                                             \                if (ltmp == JSVAL_STRING && rtmp == JSVAL_STRING) {           \                    str  = JSVAL_TO_STRING(lval);                             \                    str2 = JSVAL_TO_STRING(rval);                             \                    cond = js_CompareStrings(str, str2) OP 0;                 \                } else {                                                      \                    VALUE_TO_NUMBER(cx, lval, d);                             \                    VALUE_TO_NUMBER(cx, rval, d2);                            \                    cond = COMPARE_DOUBLES(d, OP, d2, IFNAN);                 \                }                                                             \            }                                                                 \        }                                                                     \        sp--;                                                                 \        STORE_OPND(-1, BOOLEAN_TO_JSVAL(cond));                               \    JS_END_MACRO          case JSOP_EQ:            EQUALITY_OP(==, JS_FALSE);            break;          case JSOP_NE:            EQUALITY_OP(!=, JS_TRUE);            break;#if !JS_BUG_FALLIBLE_EQOPS#define NEW_EQUALITY_OP(OP, IFNAN)                                            \    JS_BEGIN_MACRO                                                            \        rval = FETCH_OPND(-1);                                                \        lval = FETCH_OPND(-2);                                                \        ltmp = JSVAL_TAG(lval);                                               \        rtmp = JSVAL_TAG(rval);                                               \        if (ltmp == rtmp) {                                                   \            if (ltmp == JSVAL_STRING) {                                       \                str  = JSVAL_TO_STRING(lval);                                 \                str2 = JSVAL_TO_STRING(rval);                                 \                cond = js_CompareStrings(str, str2) OP 0;                     \            } else if (ltmp == JSVAL_DOUBLE) {                                \                d  = *JSVAL_TO_DOUBLE(lval);                                  \                d2 = *JSVAL_TO_DOUBLE(rval);                                  \                cond = COMPARE_DOUBLES(d, OP, d2, IFNAN);                     \            } else {                                                          \                cond = lval OP rval;                                          \            }                                                                 \        } else {                                                              \            if (ltmp == JSVAL_DOUBLE && JSVAL_IS_INT(rval)) {                 \                d  = *JSVAL_TO_DOUBLE(lval);                                  \                d2 = JSVAL_TO_INT(rval);                                      \                cond = COMPARE_DOUBLES(d, OP, d2, IFNAN);                     \            } else if (JSVAL_IS_INT(lval) && rtmp == JSVAL_DOUBLE) {          \                d  = JSVAL_TO_INT(lval);                                      \                d2 = *JSVAL_TO_DOUBLE(rval);                                  \                cond = COMPARE_DOUBLES(d, OP, d2, IFNAN);                     \            } else {                                                          \                cond = lval OP rval;                                          \            }                                                                 \        }                                                                     \        sp--;                                                                 \        STORE_OPND(-1, BOOLEAN_TO_JSVAL(cond));                               \    JS_END_MACRO          case JSOP_NEW_EQ:            NEW_EQUALITY_OP(==, JS_FALSE);            break;          case JSOP_NEW_NE:            NEW_EQUALITY_OP(!=, JS_TRUE);            break;#if JS_HAS_SWITCH_STATEMENT          case JSOP_CASE:            NEW_EQUALITY_OP(==, JS_FALSE);            (void) POP();            if (cond) {                len = GET_JUMP_OFFSET(pc);                CHECK_BRANCH(len);            } else {                PUSH(lval);            }            break;          case JSOP_CASEX:            NEW_EQUALITY_OP(==, JS_FALSE);            (void) POP();            if (cond) {                len = GET_JUMPX_OFFSET(pc);                CHECK_BRANCH(len);            } else {                PUSH(lval);            }            break;#endif#endif /* !JS_BUG_FALLIBLE_EQOPS */          case JSOP_LT:            RELATIONAL_OP(<);            break;          case JSOP_LE:            RELATIONAL_OP(<=);            break;          case JSOP_GT:            RELATIONAL_OP(>);            break;          case JSOP_GE:            RELATIONAL_OP(>=);            break;#undef EQUALITY_OP#undef RELATIONAL_OP          case JSOP_LSH:            SIGNED_SHIFT_OP(<<);            break;          case JSOP_RSH:            SIGNED_SHIFT_OP(>>);            break;          case JSOP_URSH:          {            uint32 u;            FETCH_INT(cx, -1, j);            FETCH_UINT(cx, -2, u);            j &= 31;            d = u >> j;            sp--;            STORE_NUMBER(cx, -1, d);            break;          }#undef INTEGER_OP#undef BITWISE_OP#undef SIGNED_SHIFT_OP          case JSOP_ADD:            rval = FETCH_OPND(-1);            lval = FETCH_OPND(-2);            VALUE_TO_PRIMITIVE(cx, lval, JSTYPE_VOID, &ltmp);            VALUE_TO_PRIMITIVE(cx, rval, JSTYPE_VOID, &rtmp);            if ((cond = JSVAL_IS_STRING(ltmp)) || JSVAL_IS_STRING(rtmp)) {                if (cond) {                    str = JSVAL_TO_STRING(ltmp);                    SAVE_SP(fp);                    ok = (str2 = js_ValueToString(cx, rtmp)) != NULL;                } else {                    str2 = JSVAL_TO_STRING(rtmp);                    SAVE_SP(fp);                    ok = (str = js_ValueToString(cx, ltmp)) != NULL;                }                if (!ok)                    goto out;                str = js_ConcatStrings(cx, str, str2);                if (!str) {                    ok = JS_FALSE;                    goto out;                }                sp--;                STORE_OPND(-1, STRING_TO_JSVAL(str));            } else {                VALUE_TO_NUMBER(cx, lval, d);                VALUE_TO_NUMBER(cx, rval, d2);                d += d2;                sp--;                STORE_NUMBER(cx, -1, d);            }            break;#define BINARY_OP(OP)                                                         \    JS_BEGIN_MACRO                                                            \        FETCH_NUMBER(cx, -1, d2);                                             \        FETCH_NUMBER(cx, -2, d);                                              \        d = d OP d2;                                                          \        sp--;                                                                 \        STORE_NUMBER(cx, -1, d);                                              \    JS_END_MACRO          case JSOP_SUB:            BINARY_OP(-);            break;          case JSOP_MUL:            BINARY_OP(*);            break;          case JSOP_DIV:            FETCH_NUMBER(cx, -1, d2);            FETCH_NUMBER(cx, -2, d);            sp--;            if (d2 == 0) {#ifdef XP_PC                /* XXX MSVC miscompiles such that (NaN == 0) */                if (JSDOUBLE_IS_NaN(d2))                    rval = DOUBLE_TO_JSVAL(rt->jsNaN);                else#endif                if (d == 0 || JSDOUBLE_IS_NaN(d))                    rval = DOUBLE_TO_JSVAL(rt->jsNaN);                else if ((JSDOUBLE_HI32(d) ^ JSDOUBLE_HI32(d2)) >> 31)                    rval = DOUBLE_TO_JSVAL(rt->jsNegativeInfinity);                else                    rval = DOUBLE_TO_JSVAL(rt->jsPositiveInfinity);                STORE_OPND(-1, rval);            } else {                d /= d2;                STORE_NUMBER(cx, -1, d);            }            break;          case JSOP_MOD:            FETCH_NUMBER(cx, -1, d2);            FETCH_NUMBER(cx, -2, d);            sp--;            if (d2 == 0) {                STORE_OPND(-1, DOUBLE_TO_JSVAL(rt->jsNaN));            } else {#ifdef XP_PC              /* Workaround MS fmod bug where 42 % (1/0) => NaN, not 42. */              if (!(JSDOUBLE_IS_FINITE(d) && JSDOUBLE_IS_INFINITE(d2)))#endif                d = fmod(d, d2);                STORE_NUMBER(cx, -1, d);            }            break;          case JSOP_NOT:            POP_BOOLEAN(cx, rval, cond);            PUSH_OPND(BOOLEAN_TO_JSVAL(!cond));            break;          case JSOP_BITNOT:            FETCH_INT(cx, -1, i);            d = (jsdouble) ~i;            STORE_NUMBER(cx, -1, d);            break;          case JSOP_NEG:            FETCH_NUMBER(cx, -1, d);#ifdef HPUX            /*             * Negation of a zero doesn't produce a negative             * zero on HPUX. Perform the operation by bit             * twiddling.             */            JSDOUBLE_HI32(d) ^= JSDOUBLE_HI32_SIGNBIT;#else            d = -d;#endif            STORE_NUMBER(cx, -1, d);            break;          case JSOP_POS:            FETCH_NUMBER(cx, -1, d);            STORE_NUMBER(cx, -1, d);            break;          case JSOP_NEW:            /* Get immediate argc and find the constructor function. */            argc = GET_ARGC(pc);#if JS_HAS_INITIALIZERS          do_new:#endif            vp = sp - (2 + argc);            JS_ASSERT(vp >= fp->spbase);            fun = NULL;            obj2 = NULL;            lval = *vp;            if (!JSVAL_IS_OBJECT(lval) ||                (obj2 = JSVAL_TO_OBJECT(lval)) == NULL ||                /* XXX clean up to avoid special cases above ObjectOps layer */                OBJ_GET_CLASS(cx, obj2) == &js_FunctionClass ||                !obj2->map->ops->construct)            {                SAVE_SP(fp);                fun = js_ValueToFunction(cx, vp, JS_TRUE);                if (!fun) {                    ok = JS_FALSE;                    goto out;                }            }            clasp = &js_ObjectClass;            if (!obj2) {                proto = parent = NULL;                fun = NULL;            } else {                /* Get the constructor prototype object for this function. */                ok = OBJ_GET_PROPERTY(cx, obj2,                                      (jsid)rt->atomState.classPrototypeAtom,                                      &rval);                if (!ok)                    goto out;                proto = JSVAL_IS_OBJECT(rval) ? JSVAL_TO_OBJECT(rval) : NULL;                parent = OBJ_GET_PARENT(cx, obj2);                if (OBJ_GET_CLASS(cx, obj2) == &js_FunctionClass) {                    funclasp = ((JSFunction *)JS_GetPrivate(cx, obj2))->clasp;                    if (funclasp)                        clasp = funclasp;                }            }            obj = js_NewObject(cx, clasp, proto, parent);            if (!obj) {                ok = JS_FALSE;                goto out;            }            /* Now we have an object with a constructor method; call it. */            vp[1] = OBJECT_TO_JSVAL(obj);            SAVE_SP(fp);            ok = js_Invoke(cx, argc, JSINVOKE_CONSTRUCT);            RESTORE_SP(fp);            if (!ok) {                cx->newborn[GCX_OBJECT] = NULL;                goto out;            }            /* Check the return value and update obj from it. */            rval = *vp;            if (JSVAL_IS_PRIMITIVE(rval)) {                if (fun || !JSVERSION_IS_ECMA(cx->version)) {                    *vp = OBJECT_TO_JSVAL(obj);                    break;                }                /* native [[Construct]] returning primitive is error */                str = js_ValueToString(cx, rval);                if (str) {                    JS_ReportErrorNumber(cx, js_GetErrorMessage, NULL,                                         JSMSG_BAD_NEW_RESULT,                                         JS_GetStringBytes(str));                }                ok = JS_FALSE;                goto out;            }            obj = JSVAL_TO_OBJECT(rval);            JS_RUNTIME_METER(rt, constructs);            break;          case JSOP_DELNAME:            atom = GET_ATOM(cx, script, pc);            id   = (jsid)atom;            SAVE_SP(fp);            ok = js_FindProperty(cx, id, &obj, &obj2, &prop);            if (!ok)                goto out;            /* ECMA says to return true if name is undefined or inherited. */            rval = JSVAL_TRUE;            if (prop) {                OBJ_DROP_PROPERTY(cx, obj2, prop);                ok = OBJ_DELETE_PROPERTY(cx, obj, id, &rval);                if (!ok)                    goto out;            }            PUSH_OPND(rval);            break;          case JSOP_DELPROP:            atom = GET_ATOM(cx, script, pc);            id   = (jsid)atom;            PROPERTY_OP(-1, ok = OBJ_DELETE_PROPERTY(cx, obj, id, &rval));            STORE_OPND(-1, rval);            break;          case JSOP_DELELEM:            ELEMENT_OP(-1, ok = OBJ_DELETE_PROPERTY(cx, obj, id, &rval));            sp--;            STORE_OPND(-1, rval);            break;          case JSOP_TYPEOF:            rval = POP_OPND();            type = JS_TypeOfValue(cx, rval);            atom = rt->atomState.typeAtoms[type];            str  = ATOM_TO_STRING(atom);            PUSH_OPND(STRING_TO_JSVAL(str));            break;          case JSOP_VOID:            (void) POP_OPND();            PUSH_OPND(JSVAL_VOID);            break;          case JSOP_INCNAME:          case JSOP_DECNAME:          case JSOP_NAMEINC:          case JSOP_NAMEDEC:            atom = GET_ATOM(cx, script, pc);            id   = (jsid)atom;            SAVE_SP(fp);            ok = js_FindProperty(cx, id, &obj, &obj2, &prop);            if (!ok)                goto out;            if (!prop) {                js_ReportIsNotDefined(cx, ATOM_BYTES(atom));                ok = JS_FALSE;                goto out;            }            OBJ_DROP_PROPERTY(cx, obj2, prop);            lval = OBJECT_TO_JSVAL(obj);            goto do_incop;          case JSOP_INCPROP:          case JSOP_DECPROP:          case JSOP_PROPINC:          case JSOP_PROPDEC:            atom = GET_ATOM(cx, script, pc);            id   = (jsid)atom;            lval = POP_OPND();            goto do_incop;          case JSOP_INCELEM:          case JSOP_DECELEM:          case JSOP_ELEMINC:          case JSOP_ELEMDEC:            POP_ELEMENT_ID(id);            lval = POP_OPND();          do_incop:            VALUE_TO_OBJECT(cx, lval, obj);            /* The operand must contain a number. */            SAVE_SP(fp);            CACHED_GET(OBJ_GET_PROPERTY(cx, obj, id, &rval));            if (!ok)                goto out;            /* The expression result goes in rtmp, the updated value in rval. */            if (JSVAL_IS_INT(rval) &&                rval != INT_TO_JSVAL(JSVAL_INT_MIN) &&                rval != INT_TO_JSVAL(JSVAL_INT_MAX)) {                if (cs->format & JOF_POST) {                    rtmp = rval;                    (cs->format & JOF_INC) ? (rval += 2) : (rval -= 2);                } else {                    (cs->format & JOF_INC) ? (rval += 2) : (rval -= 2);                    rtmp = rval;                }            } else {/* * Initially, rval contains the value to increment or decrement, which is not * yet converted.  As above, the expression result goes in rtmp, the updated * value goes in rval. */#define NONINT_INCREMENT_OP()                                                 \    JS_BEGIN_MACRO                                                            \        VALUE_TO_NUMBER(cx, rval, d);                                         \        if (cs->format & JOF_POST) {                                          \            rtmp = rval;                                                      \            if (!JSVAL_IS_NUMBER(rtmp)) {                                     \                ok = js_NewNumberValue(cx, d, &rtmp);                         \                if (!ok)                                                      \                    goto out;                                                 \            }                                                                 \            (cs->format & JOF_INC) ? d++ : d--;                               \            ok = js_NewNumberValue(cx, d, &rval);                             \        } else {                                                              \            (cs->format & JOF_INC) ? ++d : --d;                               \            ok = js_NewNumberValue(cx, d, &rval);                             \            rtmp = rval;                                                      \        }                                                                     \        if (!ok)                                                              \            goto out;                                                         \    JS_END_MACRO                NONINT_INCREMENT_OP();            }            CACHED_SET(OBJ_SET_PROPERTY(cx, obj, id, &rval));            if (!ok)                goto out;            PUSH_OPND(rtmp);            break;/* * NB: This macro can't use JS_BEGIN_MACRO/JS_END_MACRO around its body because * it must break from the switch case that calls it, not from the do...while(0) * loop created by the JS_BEGIN/END_MACRO brackets. */#define FAST_INCREMENT_OP(SLOT,COUNT,BASE,PRE,OP,MINMAX)                      \    slot = (uintN)SLOT;                                                       \    JS_ASSERT(slot < fp->fun->COUNT);                                         \    vp = fp->BASE + slot;                                                     \    rval = *vp;                                                               \    if (JSVAL_IS_INT(rval) &&                                                 \        rval != INT_TO_JSVAL(JSVAL_INT_##MINMAX)) {                           \        PRE = rval;                                                           \        rval OP 2;                                                            \        *vp = rval;                                                           \        PUSH_OPND(PRE);                                                       \        break;                                                                \    }                                                                         \    goto do_nonint_fast_incop;          case JSOP_INCARG:            FAST_INCREMENT_OP(GET_ARGNO(pc), nargs, argv, rval, +=, MAX);          case JSOP_DECARG:            FAST_INCREMENT_OP(GET_ARGNO(pc), nargs, argv, rval, -=, MIN);          case JSOP_ARGINC:            FAST_INCREMENT_OP(GET_ARGNO(pc), nargs, argv, rtmp, +=, MAX);          case JSOP_ARGDEC:            FAST_INCREMENT_OP(GET_ARGNO(pc), nargs, argv, rtmp, -=, MIN);          case JSOP_INCVAR:            FAST_INCREMENT_OP(GET_VARNO(pc), nvars, vars, rval, +=, MAX);          case JSOP_DECVAR:            FAST_INCREMENT_OP(GET_VARNO(pc), nvars, vars, rval, -=, MIN);          case JSOP_VARINC:            FAST_INCREMENT_OP(GET_VARNO(pc), nvars, vars, rtmp, +=, MAX);          case JSOP_VARDEC:            FAST_INCREMENT_OP(GET_VARNO(pc), nvars, vars, rtmp, -=, MIN);#undef FAST_INCREMENT_OP          do_nonint_fast_incop:            NONINT_INCREMENT_OP();            *vp = rval;            PUSH_OPND(rtmp);            break;          case JSOP_GETPROP:            /* Get an immediate atom naming the property. */            atom = GET_ATOM(cx, script, pc);            id   = (jsid)atom;            PROPERTY_OP(-1, CACHED_GET(OBJ_GET_PROPERTY(cx, obj, id, &rval)));            STORE_OPND(-1, rval);            break;          case JSOP_SETPROP:            /* Pop the right-hand side into rval for OBJ_SET_PROPERTY. */            rval = FETCH_OPND(-1);            /* Get an immediate atom naming the property. */            atom = GET_ATOM(cx, script, pc);            id   = (jsid)atom;            PROPERTY_OP(-2, CACHED_SET(OBJ_SET_PROPERTY(cx, obj, id, &rval)));            sp--;            STORE_OPND(-1, rval);            break;          case JSOP_GETELEM:            ELEMENT_OP(-1, CACHED_GET(OBJ_GET_PROPERTY(cx, obj, id, &rval)));            sp--;            STORE_OPND(-1, rval);            break;          case JSOP_SETELEM:            rval = FETCH_OPND(-1);            ELEMENT_OP(-2, CACHED_SET(OBJ_SET_PROPERTY(cx, obj, id, &rval)));            sp -= 2;            STORE_OPND(-1, rval);            break;          case JSOP_ENUMELEM:            /* Funky: the value to set is under the [obj, id] pair. */            FETCH_ELEMENT_ID(-1, id);            lval = FETCH_OPND(-2);            VALUE_TO_OBJECT(cx, lval, obj);            rval = FETCH_OPND(-3);            SAVE_SP(fp);            CACHED_SET(OBJ_SET_PROPERTY(cx, obj, id, &rval));            if (!ok)                goto out;            sp -= 3;            break;/* * LAZY_ARGS_THISP allows the JSOP_ARGSUB bytecode to defer creation of the * arguments object until it is truly needed.  JSOP_ARGSUB optimizes away * arguments objects when the only uses of the 'arguments' parameter are to * fetch individual actual parameters.  But if such a use were then invoked, * e.g., arguments[i](), the 'this' parameter would and must bind to the * caller's arguments object.  So JSOP_ARGSUB sets obj to LAZY_ARGS_THISP. */#define LAZY_ARGS_THISP ((JSObject *) 1)          case JSOP_PUSHOBJ:            if (obj == LAZY_ARGS_THISP && !(obj = js_GetArgsObject(cx, fp))) {                ok = JS_FALSE;                goto out;            }            PUSH_OPND(OBJECT_TO_JSVAL(obj));            break;          case JSOP_CALL:          case JSOP_EVAL:            argc = GET_ARGC(pc);            vp = sp - (argc + 2);            lval = *vp;            SAVE_SP(fp);            if (JSVAL_IS_FUNCTION(cx, lval) &&                (obj = JSVAL_TO_OBJECT(lval),                 fun = (JSFunction *) JS_GetPrivate(cx, obj),                 !fun->native &&                 !(fun->flags & (JSFUN_HEAVYWEIGHT | JSFUN_BOUND_METHOD)) &&                 argc >= (uintN)(fun->nargs + fun->extra)))          /* inline_call: */            {                uintN nframeslots, nvars;                void *newmark;                JSInlineFrame *newifp;                JSInterpreterHook hook;                /* Restrict recursion of lightweight functions. */                if (inlineCallCount == MAX_INLINE_CALL_COUNT) {                    JS_ReportErrorNumber(cx, js_GetErrorMessage, NULL,                                         JSMSG_OVER_RECURSED);                    ok = JS_FALSE;                    goto out;                }#if JS_HAS_JIT                /* ZZZbe should do this only if interpreted often enough. */                ok = jsjit_Compile(cx, fun);                if (!ok)                    goto out;#endif                /* Compute the number of stack slots needed for fun. */                nframeslots = (sizeof(JSInlineFrame) + sizeof(jsval) - 1)                              / sizeof(jsval);                nvars = fun->nvars;                script = fun->script;                depth = (jsint) script->depth;                /* Allocate the frame and space for vars and operands. */                newsp = js_AllocRawStack(cx, nframeslots + nvars + 2 * depth,                                         &newmark);                if (!newsp) {                    ok = JS_FALSE;                    goto bad_inline_call;                }                newifp = (JSInlineFrame *) newsp;                newsp += nframeslots;                /* Initialize the stack frame. */                memset(newifp, 0, sizeof(JSInlineFrame));                newifp->frame.script = script;                newifp->frame.fun = fun;                newifp->frame.argc = argc;                newifp->frame.argv = vp + 2;                newifp->frame.rval = JSVAL_VOID;                newifp->frame.nvars = nvars;                newifp->frame.vars = newsp;                newifp->frame.down = fp;                newifp->frame.scopeChain = OBJ_GET_PARENT(cx, obj);                newifp->mark = newmark;                /* Compute the 'this' parameter now that argv is set. */                ok = ComputeThis(cx, JSVAL_TO_OBJECT(vp[1]), &newifp->frame);                if (!ok) {                    js_FreeRawStack(cx, newmark);                    goto bad_inline_call;                }                /* Push void to initialize local variables. */                sp = newsp;                while (nvars--)                    PUSH(JSVAL_VOID);                sp += depth;                newifp->frame.spbase = sp;                SAVE_SP(&newifp->frame);                /* Call the debugger hook if present. */                hook = cx->runtime->callHook;                if (hook) {                    newifp->hookData = hook(cx, &newifp->frame, JS_TRUE, 0,                                            cx->runtime->callHookData);                }                /* Switch to new version if currentVersion wasn't overridden. */                newifp->callerVersion = cx->version;                if (cx->version == currentVersion) {                    currentVersion = script->version;                    if (currentVersion != cx->version)                        JS_SetVersion(cx, currentVersion);                }                /* Push the frame and set interpreter registers. */                cx->fp = fp = &newifp->frame;                pc = script->code;                endpc = pc + script->length;                inlineCallCount++;                JS_RUNTIME_METER(rt, inlineCalls);                continue;              bad_inline_call:                script = fp->script;                depth = (jsint) script->depth;                goto out;            }            ok = js_Invoke(cx, argc, 0);            RESTORE_SP(fp);            if (!ok)                goto out;            JS_RUNTIME_METER(rt, nonInlineCalls);#if JS_HAS_LVALUE_RETURN            if (cx->rval2set) {                /*                 * Sneaky: use the stack depth we didn't claim in our budget,                 * but that we know is there on account of [fun, this] already                 * having been pushed, at a minimum (if no args).  Those two                 * slots have been popped and [rval] has been pushed, which                 * leaves one more slot for rval2 before we might overflow.                 *                 * NB: rval2 must be the property identifier, and rval the                 * object from which to get the property.  The pair form an                 * ECMA "reference type", which can be used on the right- or                 * left-hand side of assignment op.  Only native methods can                 * return reference types.  See JSOP_SETCALL just below for                 * the left-hand-side case.                 */                PUSH_OPND(cx->rval2);                cx->rval2set = JS_FALSE;                ELEMENT_OP(-1,                           CACHED_GET(OBJ_GET_PROPERTY(cx, obj, id, &rval)));                sp--;                STORE_OPND(-1, rval);            }#endif            obj = NULL;            break;#if JS_HAS_LVALUE_RETURN          case JSOP_SETCALL:            argc = GET_ARGC(pc);            SAVE_SP(fp);            ok = js_Invoke(cx, argc, 0);            RESTORE_SP(fp);            if (!ok)                goto out;            if (!cx->rval2set) {                JS_ReportErrorNumber(cx, js_GetErrorMessage, NULL,                                     JSMSG_BAD_LEFTSIDE_OF_ASS);                ok = JS_FALSE;                goto out;            }            PUSH_OPND(cx->rval2);            cx->rval2set = JS_FALSE;            obj = NULL;            break;#endif          case JSOP_NAME:            atom = GET_ATOM(cx, script, pc);            id   = (jsid)atom;            SAVE_SP(fp);            ok = js_FindProperty(cx, id, &obj, &obj2, &prop);            if (!ok)                goto out;            if (!prop) {                /* Kludge to allow (typeof foo == "undefined") tests. */                for (pc2 = pc + len; pc2 < endpc; pc2++) {                    op2 = (JSOp)*pc2;                    if (op2 == JSOP_TYPEOF) {                        PUSH_OPND(JSVAL_VOID);                        goto advance_pc;                    }                    if (op2 != JSOP_GROUP)                        break;                }                js_ReportIsNotDefined(cx, ATOM_BYTES(atom));                ok = JS_FALSE;                goto out;            }            /* Take the slow path if prop was not found in a native object. */            if (!OBJ_IS_NATIVE(obj) || !OBJ_IS_NATIVE(obj2)) {                OBJ_DROP_PROPERTY(cx, obj2, prop);                ok = OBJ_GET_PROPERTY(cx, obj, id, &rval);                if (!ok)                    goto out;                PUSH_OPND(rval);                break;            }            /* Get and push the obj[id] property's value. */            sprop = (JSScopeProperty *)prop;            slot = (uintN)sprop->slot;            rval = (slot != SPROP_INVALID_SLOT)                   ? LOCKED_OBJ_GET_SLOT(obj2, slot)                   : JSVAL_VOID;            JS_UNLOCK_OBJ(cx, obj2);            ok = SPROP_GET(cx, sprop, obj, obj2, &rval);            JS_LOCK_OBJ(cx, obj2);            if (!ok) {                OBJ_DROP_PROPERTY(cx, obj2, prop);                goto out;            }            if (SPROP_HAS_VALID_SLOT(sprop, OBJ_SCOPE(obj2)))                LOCKED_OBJ_SET_SLOT(obj2, slot, rval);            OBJ_DROP_PROPERTY(cx, obj2, prop);            PUSH_OPND(rval);            break;          case JSOP_UINT16:            i = (jsint) GET_ATOM_INDEX(pc);            rval = INT_TO_JSVAL(i);            PUSH_OPND(rval);            break;          case JSOP_NUMBER:          case JSOP_STRING:            atom = GET_ATOM(cx, script, pc);            PUSH_OPND(ATOM_KEY(atom));            break;          case JSOP_OBJECT:            atom = GET_ATOM(cx, script, pc);            rval = ATOM_KEY(atom);            JS_ASSERT(JSVAL_IS_OBJECT(rval));            PUSH_OPND(rval);            obj = NULL;            break;          case JSOP_ZERO:            PUSH_OPND(JSVAL_ZERO);            break;          case JSOP_ONE:            PUSH_OPND(JSVAL_ONE);            break;          case JSOP_NULL:            PUSH_OPND(JSVAL_NULL);            break;          case JSOP_THIS:            PUSH_OPND(OBJECT_TO_JSVAL(fp->thisp));            obj = NULL;            break;          case JSOP_FALSE:            PUSH_OPND(JSVAL_FALSE);            break;          case JSOP_TRUE:            PUSH_OPND(JSVAL_TRUE);            break;#if JS_HAS_SWITCH_STATEMENT          case JSOP_TABLESWITCH:            pc2 = pc;            len = GET_JUMP_OFFSET(pc2);            /*             * ECMAv2 forbids conversion of discriminant, so we will skip to             * the default case if the discriminant isn't already an int jsval.             * (This opcode is emitted only for dense jsint-domain switches.)             */            if (cx->version == JSVERSION_DEFAULT ||                cx->version >= JSVERSION_1_4) {                rval = POP_OPND();                if (!JSVAL_IS_INT(rval))                    break;                i = JSVAL_TO_INT(rval);            } else {                FETCH_INT(cx, -1, i);                sp--;            }            pc2 += JUMP_OFFSET_LEN;            low = GET_JUMP_OFFSET(pc2);            pc2 += JUMP_OFFSET_LEN;            high = GET_JUMP_OFFSET(pc2);            i -= low;            if ((jsuint)i < (jsuint)(high - low + 1)) {                pc2 += JUMP_OFFSET_LEN + JUMP_OFFSET_LEN * i;                off = (jsint) GET_JUMP_OFFSET(pc2);                if (off)                    len = off;            }            break;          case JSOP_LOOKUPSWITCH:            lval = POP_OPND();            pc2 = pc;            len = GET_JUMP_OFFSET(pc2);            if (!JSVAL_IS_NUMBER(lval) &&                !JSVAL_IS_STRING(lval) &&                !JSVAL_IS_BOOLEAN(lval)) {                goto advance_pc;            }            pc2 += JUMP_OFFSET_LEN;            npairs = (jsint) GET_ATOM_INDEX(pc2);            pc2 += ATOM_INDEX_LEN;#define SEARCH_PAIRS(MATCH_CODE)                                              \    while (npairs) {                                                          \        atom = GET_ATOM(cx, script, pc2);                                     \        rval = ATOM_KEY(atom);                                                \        MATCH_CODE                                                            \        if (match) {                                                          \            pc2 += ATOM_INDEX_LEN;                                            \            len = GET_JUMP_OFFSET(pc2);                                       \            goto advance_pc;                                                  \        }                                                                     \        pc2 += ATOM_INDEX_LEN + JUMP_OFFSET_LEN;                              \        npairs--;                                                             \    }            if (JSVAL_IS_STRING(lval)) {                str  = JSVAL_TO_STRING(lval);                SEARCH_PAIRS(                    match = (JSVAL_IS_STRING(rval) &&                             ((str2 = JSVAL_TO_STRING(rval)) == str ||                              !js_CompareStrings(str2, str)));                )            } else if (JSVAL_IS_DOUBLE(lval)) {                d = *JSVAL_TO_DOUBLE(lval);                SEARCH_PAIRS(                    match = (JSVAL_IS_DOUBLE(rval) &&                             *JSVAL_TO_DOUBLE(rval) == d);                )            } else {                SEARCH_PAIRS(                    match = (lval == rval);                )            }#undef SEARCH_PAIRS            break;          case JSOP_TABLESWITCHX:            pc2 = pc;            len = GET_JUMPX_OFFSET(pc2);            /*             * ECMAv2 forbids conversion of discriminant, so we will skip to             * the default case if the discriminant isn't already an int jsval.             * (This opcode is emitted only for dense jsint-domain switches.)             */            if (cx->version == JSVERSION_DEFAULT ||                cx->version >= JSVERSION_1_4) {                rval = POP_OPND();                if (!JSVAL_IS_INT(rval))                    break;                i = JSVAL_TO_INT(rval);            } else {                FETCH_INT(cx, -1, i);                sp--;            }            pc2 += JUMPX_OFFSET_LEN;            low = GET_JUMP_OFFSET(pc2);            pc2 += JUMP_OFFSET_LEN;            high = GET_JUMP_OFFSET(pc2);            i -= low;            if ((jsuint)i < (jsuint)(high - low + 1)) {                pc2 += JUMP_OFFSET_LEN + JUMPX_OFFSET_LEN * i;                off = (jsint) GET_JUMPX_OFFSET(pc2);                if (off)                    len = off;            }            break;          case JSOP_LOOKUPSWITCHX:            lval = POP_OPND();            pc2 = pc;            len = GET_JUMPX_OFFSET(pc2);            if (!JSVAL_IS_NUMBER(lval) &&                !JSVAL_IS_STRING(lval) &&                !JSVAL_IS_BOOLEAN(lval)) {                goto advance_pc;            }            pc2 += JUMPX_OFFSET_LEN;            npairs = (jsint) GET_ATOM_INDEX(pc2);            pc2 += ATOM_INDEX_LEN;#define SEARCH_EXTENDED_PAIRS(MATCH_CODE)                                     \    while (npairs) {                                                          \        atom = GET_ATOM(cx, script, pc2);                                     \        rval = ATOM_KEY(atom);                                                \        MATCH_CODE                                                            \        if (match) {                                                          \            pc2 += ATOM_INDEX_LEN;                                            \            len = GET_JUMPX_OFFSET(pc2);                                      \            goto advance_pc;                                                  \        }                                                                     \        pc2 += ATOM_INDEX_LEN + JUMPX_OFFSET_LEN;                             \        npairs--;                                                             \    }            if (JSVAL_IS_STRING(lval)) {                str  = JSVAL_TO_STRING(lval);                SEARCH_EXTENDED_PAIRS(                    match = (JSVAL_IS_STRING(rval) &&                             ((str2 = JSVAL_TO_STRING(rval)) == str ||                              !js_CompareStrings(str2, str)));                )            } else if (JSVAL_IS_DOUBLE(lval)) {                d = *JSVAL_TO_DOUBLE(lval);                SEARCH_EXTENDED_PAIRS(                    match = (JSVAL_IS_DOUBLE(rval) &&                             *JSVAL_TO_DOUBLE(rval) == d);                )            } else {                SEARCH_EXTENDED_PAIRS(                    match = (lval == rval);                )            }#undef SEARCH_EXTENDED_PAIRS            break;          case JSOP_CONDSWITCH:            break;#endif /* JS_HAS_SWITCH_STATEMENT */#if JS_HAS_EXPORT_IMPORT          case JSOP_EXPORTALL:            obj = fp->varobj;            ida = JS_Enumerate(cx, obj);            if (!ida) {                ok = JS_FALSE;            } else {                for (i = 0, j = ida->length; i < j; i++) {                    id = ida->vector[i];                    ok = OBJ_LOOKUP_PROPERTY(cx, obj, id, &obj2, &prop);                    if (!ok)                        break;                    if (!prop)                        continue;                    ok = OBJ_GET_ATTRIBUTES(cx, obj, id, prop, &attrs);                    if (ok) {                        attrs |= JSPROP_EXPORTED;                        ok = OBJ_SET_ATTRIBUTES(cx, obj, id, prop, &attrs);                    }                    OBJ_DROP_PROPERTY(cx, obj2, prop);                    if (!ok)                        break;                }                JS_DestroyIdArray(cx, ida);            }            break;          case JSOP_EXPORTNAME:            atom = GET_ATOM(cx, script, pc);            id   = (jsid)atom;            obj  = fp->varobj;            ok = OBJ_LOOKUP_PROPERTY(cx, obj, id, &obj2, &prop);            if (!ok)                goto out;            if (!prop) {                ok = OBJ_DEFINE_PROPERTY(cx, obj, id, JSVAL_VOID, NULL, NULL,                                         JSPROP_EXPORTED, NULL);            } else {                ok = OBJ_GET_ATTRIBUTES(cx, obj, id, prop, &attrs);                if (ok) {                    attrs |= JSPROP_EXPORTED;                    ok = OBJ_SET_ATTRIBUTES(cx, obj, id, prop, &attrs);                }                OBJ_DROP_PROPERTY(cx, obj2, prop);            }            if (!ok)                goto out;            break;          case JSOP_IMPORTALL:            id = (jsid)JSVAL_VOID;            PROPERTY_OP(-1, ok = ImportProperty(cx, obj, id));            sp--;            break;          case JSOP_IMPORTPROP:            /* Get an immediate atom naming the property. */            atom = GET_ATOM(cx, script, pc);            id   = (jsid)atom;            PROPERTY_OP(-1, ok = ImportProperty(cx, obj, id));            sp--;            break;          case JSOP_IMPORTELEM:            ELEMENT_OP(-1, ok = ImportProperty(cx, obj, id));            sp -= 2;            break;#endif /* JS_HAS_EXPORT_IMPORT */          case JSOP_TRAP:            switch (JS_HandleTrap(cx, script, pc, &rval)) {              case JSTRAP_ERROR:                ok = JS_FALSE;                goto out;              case JSTRAP_CONTINUE:                JS_ASSERT(JSVAL_IS_INT(rval));                op = (JSOp) JSVAL_TO_INT(rval);                JS_ASSERT((uintN)op < (uintN)JSOP_LIMIT);                goto do_op;              case JSTRAP_RETURN:                fp->rval = rval;                goto out;#if JS_HAS_EXCEPTIONS              case JSTRAP_THROW:                cx->throwing = JS_TRUE;                cx->exception = rval;                ok = JS_FALSE;                goto out;#endif /* JS_HAS_EXCEPTIONS */              default:;            }            break;          case JSOP_ARGUMENTS:            SAVE_SP(fp);            ok = js_GetArgsValue(cx, fp, &rval);            if (!ok)                goto out;            PUSH_OPND(rval);            break;          case JSOP_ARGSUB:            id = (jsid) INT_TO_JSVAL(GET_ARGNO(pc));            SAVE_SP(fp);            ok = js_GetArgsProperty(cx, fp, id, &obj, &rval);            if (!ok)                goto out;            if (!obj) {                /*                 * If arguments was not overridden by eval('arguments = ...'),                 * set obj to the magic cookie respected by ComputeThis, just                 * in case this bytecode is part of an 'arguments[i](j, k)' or                 * similar such invocation sequence, where the function that                 * is invoked expects its 'this' parameter to be the caller's                 * arguments object.                 */                obj = LAZY_ARGS_THISP;            }            PUSH_OPND(rval);            break;#undef LAZY_ARGS_THISP          case JSOP_ARGCNT:            id = (jsid) rt->atomState.lengthAtom;            SAVE_SP(fp);            ok = js_GetArgsProperty(cx, fp, id, &obj, &rval);            if (!ok)                goto out;            PUSH_OPND(rval);            break;          case JSOP_GETARG:            slot = GET_ARGNO(pc);            JS_ASSERT(slot < fp->fun->nargs);            PUSH_OPND(fp->argv[slot]);            obj = NULL;            break;          case JSOP_SETARG:            slot = GET_ARGNO(pc);            JS_ASSERT(slot < fp->fun->nargs);            vp = &fp->argv[slot];            GC_POKE(cx, *vp);            *vp = FETCH_OPND(-1);            obj = NULL;            break;          case JSOP_GETVAR:            slot = GET_VARNO(pc);            JS_ASSERT(slot < fp->fun->nvars);            PUSH_OPND(fp->vars[slot]);            obj = NULL;            break;          case JSOP_SETVAR:            slot = GET_VARNO(pc);            JS_ASSERT(slot < fp->fun->nvars);            vp = &fp->vars[slot];            GC_POKE(cx, *vp);            *vp = FETCH_OPND(-1);            obj = NULL;            break;          case JSOP_DEFCONST:          case JSOP_DEFVAR:          {            JSBool defined;            atom = GET_ATOM(cx, script, pc);            obj = fp->varobj;            attrs = JSPROP_ENUMERATE;            if (!(fp->flags & JSFRAME_EVAL))                attrs |= JSPROP_PERMANENT;            if (op == JSOP_DEFCONST)                attrs |= JSPROP_READONLY;            /* Lookup id in order to check for redeclaration problems. */            id = (jsid)atom;            ok = js_CheckRedeclaration(cx, obj, id, attrs, &defined);            if (!ok)                goto out;            /* Bind a variable only if it's not yet defined. */            if (!defined) {                ok = OBJ_DEFINE_PROPERTY(cx, obj, id, JSVAL_VOID, NULL, NULL,                                         attrs, NULL);                if (!ok)                    goto out;            }            break;          }          case JSOP_DEFFUN:            atom = GET_ATOM(cx, script, pc);            obj = ATOM_TO_OBJECT(atom);            fun = (JSFunction *) JS_GetPrivate(cx, obj);            id = (jsid) fun->atom;            /*             * We must be at top-level (default "box", either function body or             * global) scope, not inside a with or other compound statement in             * the same compilation unit (ECMA Program).             *             * However, we could be in a Program being eval'd from inside a             * with statement, so we need to distinguish variables object from             * scope chain head.  Hence the two assignments to parent below.             * First we make sure the function object we're defining has the             * right scope chain.  Then we define its name in fp->varobj.             *             * If static link is not current scope, clone fun's object to link             * to the current scope via parent.  This clause exists to enable             * sharing of compiled functions among multiple equivalent scopes,             * splitting the cost of compilation evenly among the scopes and             * amortizing it over a number of executions.  Examples include XUL             * scripts and event handlers shared among Mozilla chrome windows,             * and server-side JS user-defined functions shared among requests.             *             * NB: The Script object exposes compile and exec in the language,             * such that this clause introduces an incompatible change from old             * JS versions that supported Script.  Such a JS version supported             * executing a script that defined and called functions scoped by             * the compile-time static link, not by the exec-time scope chain.             *             * We sacrifice compatibility, breaking such scripts, in order to             * promote compile-cost sharing and amortizing, and because Script             * is not and will not be standardized.             */            parent = fp->scopeChain;            if (OBJ_GET_PARENT(cx, obj) != parent) {                obj = js_CloneFunctionObject(cx, obj, parent);                if (!obj) {                    ok = JS_FALSE;                    goto out;                }            }            /*             * Load function flags that are also property attributes.  Getters             * and setters do not need a slot, their value is stored elsewhere             * in the property itself, not in obj->slots.             */            attrs = fun->flags & (JSFUN_GETTER | JSFUN_SETTER);            if (attrs)                attrs |= JSPROP_SHARED;            /*             * Check for a const property of the same name -- or any kind             * of property if executing with the strict option.  We check             * here at runtime as well as at compile-time, to handle eval             * as well as multiple HTML script tags.             */            parent = fp->varobj;            ok = js_CheckRedeclaration(cx, parent, id, attrs, &cond);            if (!ok)                goto out;            ok = OBJ_DEFINE_PROPERTY(cx, parent, id,                                     attrs ? JSVAL_VOID : OBJECT_TO_JSVAL(obj),                                     (attrs & JSFUN_GETTER)                                     ? (JSPropertyOp) obj                                     : NULL,                                     (attrs & JSFUN_SETTER)                                     ? (JSPropertyOp) obj                                     : NULL,                                     attrs | JSPROP_ENUMERATE,                                     NULL);            if (!ok)                goto out;            break;#if JS_HAS_LEXICAL_CLOSURE          case JSOP_DEFLOCALFUN:            /*             * Define a local function (i.e., one nested at the top level of             * another function), parented by the current scope chain, and             * stored in a local variable slot that the compiler allocated.             * This is an optimization over JSOP_DEFFUN that avoids requiring             * a call object for the outer function's activation.             */            pc2 = pc;            slot = GET_VARNO(pc2);            pc2 += VARNO_LEN;            atom = GET_ATOM(cx, script, pc2);            obj = ATOM_TO_OBJECT(atom);            fun = (JSFunction *) JS_GetPrivate(cx, obj);            parent = fp->scopeChain;            if (OBJ_GET_PARENT(cx, obj) != parent) {                obj = js_CloneFunctionObject(cx, obj, parent);                if (!obj) {                    ok = JS_FALSE;                    goto out;                }            }            fp->vars[slot] = OBJECT_TO_JSVAL(obj);            break;          case JSOP_ANONFUNOBJ:            /* Push the specified function object literal. */            atom = GET_ATOM(cx, script, pc);            obj = ATOM_TO_OBJECT(atom);            /* If re-parenting, push a clone of the function object. */            parent = fp->scopeChain;            if (OBJ_GET_PARENT(cx, obj) != parent) {                obj = js_CloneFunctionObject(cx, obj, parent);                if (!obj) {                    ok = JS_FALSE;                    goto out;                }            }            PUSH_OPND(OBJECT_TO_JSVAL(obj));            break;          case JSOP_NAMEDFUNOBJ:            /* ECMA ed. 3 FunctionExpression: function Identifier [etc.]. */            atom = GET_ATOM(cx, script, pc);            rval = ATOM_KEY(atom);            JS_ASSERT(JSVAL_IS_FUNCTION(cx, rval));            /*             * 1. Create a new object as if by the expression new Object().             * 2. Add Result(1) to the front of the scope chain.             *             * Step 2 is achieved by making the new object's parent be the             * current scope chain, and then making the new object the parent             * of the Function object clone.             */            SAVE_SP(fp);            parent = js_ConstructObject(cx, &js_ObjectClass, NULL,                                        fp->scopeChain, 0, NULL);            if (!parent) {                ok = JS_FALSE;                goto out;            }            /*             * 3. Create a new Function object as specified in section 13.2             * with [parameters and body specified by the function expression             * that was parsed by the compiler into a Function object, and             * saved in the script's atom map].             */            obj = js_CloneFunctionObject(cx, JSVAL_TO_OBJECT(rval), parent);            if (!obj) {                ok = JS_FALSE;                goto out;            }            /*             * 4. Create a property in the object Result(1).  The property's             * name is [fun->atom, the identifier parsed by the compiler],             * value is Result(3), and attributes are { DontDelete, ReadOnly }.             */            fun = (JSFunction *) JS_GetPrivate(cx, obj);            attrs = fun->flags & (JSFUN_GETTER | JSFUN_SETTER);            if (attrs)                attrs |= JSPROP_SHARED;            ok = OBJ_DEFINE_PROPERTY(cx, parent, (jsid)fun->atom,                                     attrs ? JSVAL_VOID : OBJECT_TO_JSVAL(obj),                                     (attrs & JSFUN_GETTER)                                     ? (JSPropertyOp) obj                                     : NULL,                                     (attrs & JSFUN_SETTER)                                     ? (JSPropertyOp) obj                                     : NULL,                                     attrs |                                     JSPROP_ENUMERATE | JSPROP_PERMANENT |                                     JSPROP_READONLY,                                     NULL);            if (!ok) {                cx->newborn[GCX_OBJECT] = NULL;                goto out;            }            /*             * 5. Remove Result(1) from the front of the scope chain [no-op].             * 6. Return Result(3).             */            PUSH_OPND(OBJECT_TO_JSVAL(obj));            break;          case JSOP_CLOSURE:            /*             * ECMA ed. 3 extension: a named function expression in a compound             * statement (not at the top statement level of global code, or at             * the top level of a function body).             *             * Get immediate operand atom, which is a function object literal.             * From it, get the function to close.             */            atom = GET_ATOM(cx, script, pc);            JS_ASSERT(JSVAL_IS_FUNCTION(cx, ATOM_KEY(atom)));            obj = ATOM_TO_OBJECT(atom);            /*             * Clone the function object with the current scope chain as the             * clone's parent.  The original function object is the prototype             * of the clone.  Do this only if re-parenting; the compiler may             * have seen the right parent already and created a sufficiently             * well-scoped function object.             */            parent = fp->scopeChain;            if (OBJ_GET_PARENT(cx, obj) != parent) {                obj = js_CloneFunctionObject(cx, obj, parent);                if (!obj) {                    ok = JS_FALSE;                    goto out;                }            }            /*             * Make a property in fp->varobj with id fun->atom and value obj,             * unless fun is a getter or setter (in which case, obj is cast to             * a JSPropertyOp and passed accordingly).             */            fun = (JSFunction *) JS_GetPrivate(cx, obj);            attrs = fun->flags & (JSFUN_GETTER | JSFUN_SETTER);            if (attrs)                attrs |= JSPROP_SHARED;            ok = OBJ_DEFINE_PROPERTY(cx, fp->varobj, (jsid)fun->atom,                                     attrs ? JSVAL_VOID : OBJECT_TO_JSVAL(obj),                                     (attrs & JSFUN_GETTER)                                     ? (JSPropertyOp) obj                                     : NULL,                                     (attrs & JSFUN_SETTER)                                     ? (JSPropertyOp) obj                                     : NULL,                                     attrs | JSPROP_ENUMERATE,                                     NULL);            if (!ok) {                cx->newborn[GCX_OBJECT] = NULL;                goto out;            }            break;#endif /* JS_HAS_LEXICAL_CLOSURE */#if JS_HAS_GETTER_SETTER          case JSOP_GETTER:          case JSOP_SETTER:            JS_ASSERT(len == 1);            op2 = (JSOp) *++pc;            cs = &js_CodeSpec[op2];            len = cs->length;            switch (op2) {              case JSOP_SETNAME:              case JSOP_SETPROP:                atom = GET_ATOM(cx, script, pc);                id   = (jsid)atom;                i = -1;                rval = FETCH_OPND(i);                goto gs_pop_lval;              case JSOP_SETELEM:                rval = FETCH_OPND(-1);                i = -2;                FETCH_ELEMENT_ID(i, id);              gs_pop_lval:                lval = FETCH_OPND(i-1);                VALUE_TO_OBJECT(cx, lval, obj);                break;#if JS_HAS_INITIALIZERS              case JSOP_INITPROP:                JS_ASSERT(sp - fp->spbase >= 2);                i = -1;                rval = FETCH_OPND(i);                atom = GET_ATOM(cx, script, pc);                id   = (jsid)atom;                goto gs_get_lval;              case JSOP_INITELEM:                JS_ASSERT(sp - fp->spbase >= 3);                rval = FETCH_OPND(-1);                i = -2;                FETCH_ELEMENT_ID(i, id);              gs_get_lval:                lval = FETCH_OPND(i-1);                JS_ASSERT(JSVAL_IS_OBJECT(lval));                obj = JSVAL_TO_OBJECT(lval);                break;#endif /* JS_HAS_INITIALIZERS */              default:                JS_ASSERT(0);            }            if (JS_TypeOfValue(cx, rval) != JSTYPE_FUNCTION) {                JS_ReportErrorNumber(cx, js_GetErrorMessage, NULL,                                     JSMSG_BAD_GETTER_OR_SETTER,                                     (op == JSOP_GETTER)                                     ? js_getter_str                                     : js_setter_str);                ok = JS_FALSE;                goto out;            }            /*             * Getters and setters are just like watchpoints from an access             * control point of view.             */            ok = OBJ_CHECK_ACCESS(cx, obj, id, JSACC_WATCH, &rtmp, &attrs);            if (!ok)                goto out;            if (op == JSOP_GETTER) {                getter = (JSPropertyOp) JSVAL_TO_OBJECT(rval);                setter = NULL;                attrs = JSPROP_GETTER;            } else {                getter = NULL;                setter = (JSPropertyOp) JSVAL_TO_OBJECT(rval);                attrs = JSPROP_SETTER;            }            attrs |= JSPROP_ENUMERATE | JSPROP_SHARED;            /* Check for a readonly or permanent property of the same name. */            ok = js_CheckRedeclaration(cx, obj, id, attrs, &cond);            if (!ok)                goto out;            ok = OBJ_DEFINE_PROPERTY(cx, obj, id, JSVAL_VOID, getter, setter,                                     attrs, NULL);            if (!ok)                goto out;            sp += i;            if (cs->ndefs)                STORE_OPND(-1, rval);            break;#endif /* JS_HAS_GETTER_SETTER */#if JS_HAS_INITIALIZERS          case JSOP_NEWINIT:            argc = 0;            fp->sharpDepth++;            goto do_new;          case JSOP_ENDINIT:            if (--fp->sharpDepth == 0)                fp->sharpArray = NULL;            /* Re-set the newborn root to the top of this object tree. */            JS_ASSERT(sp - fp->spbase >= 1);            lval = FETCH_OPND(-1);            JS_ASSERT(JSVAL_IS_OBJECT(lval));            cx->newborn[GCX_OBJECT] = JSVAL_TO_GCTHING(lval);            break;          case JSOP_INITPROP:            /* Pop the property's value into rval. */            JS_ASSERT(sp - fp->spbase >= 2);            rval = FETCH_OPND(-1);            /* Get the immediate property name into id. */            atom = GET_ATOM(cx, script, pc);            id   = (jsid)atom;            i = -1;            goto do_init;          case JSOP_INITELEM:            /* Pop the element's value into rval. */            JS_ASSERT(sp - fp->spbase >= 3);            rval = FETCH_OPND(-1);            /* Pop and conditionally atomize the element id. */            FETCH_ELEMENT_ID(-2, id);            i = -2;          do_init:            /* Find the object being initialized at top of stack. */            lval = FETCH_OPND(i-1);            JS_ASSERT(JSVAL_IS_OBJECT(lval));            obj = JSVAL_TO_OBJECT(lval);            /* Set the property named by obj[id] to rval. */            ok = OBJ_SET_PROPERTY(cx, obj, id, &rval);            if (!ok)                goto out;            sp += i;            break;#if JS_HAS_SHARP_VARS          case JSOP_DEFSHARP:            obj = fp->sharpArray;            if (!obj) {                obj = js_NewArrayObject(cx, 0, NULL);                if (!obj) {                    ok = JS_FALSE;                    goto out;                }                fp->sharpArray = obj;            }            i = (jsint) GET_ATOM_INDEX(pc);            id = (jsid) INT_TO_JSVAL(i);            rval = FETCH_OPND(-1);            if (JSVAL_IS_PRIMITIVE(rval)) {                char numBuf[12];                JS_snprintf(numBuf, sizeof numBuf, "%u", (unsigned) i);                JS_ReportErrorNumber(cx, js_GetErrorMessage, NULL,                                     JSMSG_BAD_SHARP_DEF, numBuf);                ok = JS_FALSE;                goto out;            }            ok = OBJ_SET_PROPERTY(cx, obj, id, &rval);            if (!ok)                goto out;            break;          case JSOP_USESHARP:            i = (jsint) GET_ATOM_INDEX(pc);            id = (jsid) INT_TO_JSVAL(i);            obj = fp->sharpArray;            if (!obj) {                rval = JSVAL_VOID;            } else {                ok = OBJ_GET_PROPERTY(cx, obj, id, &rval);                if (!ok)                    goto out;            }            if (!JSVAL_IS_OBJECT(rval)) {                char numBuf[12];                JS_snprintf(numBuf, sizeof numBuf, "%u", (unsigned) i);                JS_ReportErrorNumber(cx, js_GetErrorMessage, NULL,                                     JSMSG_BAD_SHARP_USE, numBuf);                ok = JS_FALSE;                goto out;            }            PUSH_OPND(rval);            break;#endif /* JS_HAS_SHARP_VARS */#endif /* JS_HAS_INITIALIZERS */#if JS_HAS_EXCEPTIONS          /* No-ops for ease of decompilation and jit'ing. */          case JSOP_TRY:          case JSOP_FINALLY:            break;          /* Reset the stack to the given depth. */          case JSOP_SETSP:            i = (jsint) GET_ATOM_INDEX(pc);            JS_ASSERT(i >= 0);            sp = fp->spbase + i;            break;          case JSOP_GOSUB:            i = PTRDIFF(pc, script->main, jsbytecode) + len;            len = GET_JUMP_OFFSET(pc);            PUSH(INT_TO_JSVAL(i));            break;          case JSOP_GOSUBX:            i = PTRDIFF(pc, script->main, jsbytecode) + len;            len = GET_JUMPX_OFFSET(pc);            PUSH(INT_TO_JSVAL(i));            break;          case JSOP_RETSUB:            rval = POP();            JS_ASSERT(JSVAL_IS_INT(rval));            i = JSVAL_TO_INT(rval);            pc = script->main + i;            len = 0;            break;          case JSOP_EXCEPTION:            PUSH(cx->exception);            break;          case JSOP_THROW:            cx->throwing = JS_TRUE;            cx->exception = POP_OPND();            ok = JS_FALSE;            /* let the code at out try to catch the exception. */            goto out;          case JSOP_INITCATCHVAR:            /* Pop the property's value into rval. */            JS_ASSERT(sp - fp->spbase >= 2);            rval = POP_OPND();            /* Get the immediate catch variable name into id. */            atom = GET_ATOM(cx, script, pc);            id   = (jsid)atom;            /* Find the object being initialized at top of stack. */            lval = FETCH_OPND(-1);            JS_ASSERT(JSVAL_IS_OBJECT(lval));            obj = JSVAL_TO_OBJECT(lval);            /* Define obj[id] to contain rval and to be permanent. */            ok = OBJ_DEFINE_PROPERTY(cx, obj, id, rval, NULL, NULL,                                     JSPROP_PERMANENT, NULL);            if (!ok)                goto out;            break;#endif /* JS_HAS_EXCEPTIONS */#if JS_HAS_INSTANCEOF          case JSOP_INSTANCEOF:            rval = FETCH_OPND(-1);            if (JSVAL_IS_PRIMITIVE(rval)) {                SAVE_SP(fp);                str = js_DecompileValueGenerator(cx, -1, rval, NULL);                if (str) {                    JS_ReportErrorNumber(cx, js_GetErrorMessage, NULL,                                         JSMSG_BAD_INSTANCEOF_RHS,                                         JS_GetStringBytes(str));                }                ok = JS_FALSE;                goto out;            }            obj = JSVAL_TO_OBJECT(rval);            lval = FETCH_OPND(-2);            cond = JS_FALSE;            if (obj->map->ops->hasInstance) {                SAVE_SP(fp);                ok = obj->map->ops->hasInstance(cx, obj, lval, &cond);                if (!ok)                    goto out;            }            sp--;            STORE_OPND(-1, BOOLEAN_TO_JSVAL(cond));            break;#endif /* JS_HAS_INSTANCEOF */#if JS_HAS_DEBUGGER_KEYWORD          case JSOP_DEBUGGER:          {            JSTrapHandler handler = rt->debuggerHandler;            if (handler) {                SAVE_SP(fp);                switch (handler(cx, script, pc, &rval,                                rt->debuggerHandlerData)) {                  case JSTRAP_ERROR:                    ok = JS_FALSE;                    goto out;                  case JSTRAP_CONTINUE:                    break;                  case JSTRAP_RETURN:                    fp->rval = rval;                    goto out;#if JS_HAS_EXCEPTIONS                  case JSTRAP_THROW:                    cx->throwing = JS_TRUE;                    cx->exception = rval;                    ok = JS_FALSE;                    goto out;#endif /* JS_HAS_EXCEPTIONS */                  default:;                }            }            break;          }#endif /* JS_HAS_DEBUGGER_KEYWORD */          default: {            char numBuf[12];            JS_snprintf(numBuf, sizeof numBuf, "%d", op);            JS_ReportErrorNumber(cx, js_GetErrorMessage, NULL,                                 JSMSG_BAD_BYTECODE, numBuf);            ok = JS_FALSE;            goto out;          }        }    advance_pc:        pc += len;#ifdef DEBUG        if (tracefp) {            intN ndefs, n;            jsval *siter;            ndefs = cs->ndefs;            if (ndefs) {                SAVE_SP(fp);                for (n = -ndefs; n < 0; n++) {                    str = js_DecompileValueGenerator(cx, n, sp[n], NULL);                    if (str) {                        fprintf(tracefp, "%s %s",                                (n == -ndefs) ? "  output:" : ",",                                JS_GetStringBytes(str));                    }                }                fprintf(tracefp, " @ %d\n", sp - fp->spbase);            }            fprintf(tracefp, "  stack: ");            for (siter = fp->spbase; siter < sp; siter++) {                str = js_ValueToSource(cx, *siter);                fprintf(tracefp, "%s ",                        str ? JS_GetStringBytes(str) : "<null>");            }            fputc('\n', tracefp);        }#endif    }out:#if JS_HAS_EXCEPTIONS    /*     * Has an exception been raised?     */    if (!ok && cx->throwing) {        /*         * Call debugger throw hook if set (XXX thread safety?).         */        JSTrapHandler handler = rt->throwHook;        if (handler) {            SAVE_SP(fp);            switch (handler(cx, script, pc, &rval, rt->throwHookData)) {              case JSTRAP_ERROR:                cx->throwing = JS_FALSE;                goto no_catch;              case JSTRAP_RETURN:                ok = JS_TRUE;                cx->throwing = JS_FALSE;                fp->rval = rval;                goto no_catch;              case JSTRAP_THROW:                cx->exception = rval;              case JSTRAP_CONTINUE:              default:;            }        }        /*         * Look for a try block within this frame that can catch the exception.         */        JSSCRIPT_FIND_CATCH_START(script, pc, pc);        if (pc) {            len = 0;            cx->throwing = JS_FALSE;    /* caught */            ok = JS_TRUE;            goto advance_pc;        }    }no_catch:#endif    /*     * Check whether control fell off the end of a lightweight function, or an     * exception thrown under such a function was not caught by it.  If so, go     * to the inline code under JSOP_RETURN.     */    if (inlineCallCount)        goto inline_return;    /*     * Reset sp before freeing stack slots, because our caller may GC soon.     * Clear spbase to indicate that we've popped the 2 * depth operand slots.     * Restore the previous frame's execution state.     */    fp->sp = fp->spbase;    fp->spbase = NULL;    js_FreeRawStack(cx, mark);    if (cx->version == currentVersion && currentVersion != originalVersion)        JS_SetVersion(cx, originalVersion);    cx->interpLevel--;    return ok;}