default: JS_ReportError(cx, "unimplemented JavaScript bytecode %d", op); ok = JS_FALSE; goto out; }
default: { char numBuf[12]; sprintf(numBuf, "%d", op); JS_ReportErrorNumber(cx, NULL, JSMSG_BAD_BYTECODE, numBuf); ok = JS_FALSE; goto out; } }
js_Interpret(JSContext *cx, jsval *result){    JSRuntime *rt;    JSStackFrame *fp;    JSScript *script;    JSObject *obj, *obj2, *proto, *parent;    JSBranchCallback onbranch;    JSBool ok, cond;    ptrdiff_t depth, len;    jsval *sp, *newsp;    void *mark;    jsbytecode *pc, *pc2, *endpc;    JSOp op, op2;    JSCodeSpec *cs;    JSAtom *atom;    uintN argc, slot;    jsval *vp, lval, rval, ltmp, rtmp;    jsid id;    JSObject *withobj, *origobj, *propobj;    JSIdArray *ida;    jsval iter_state;    JSProperty *prop;    JSScopeProperty *sprop;    JSString *str, *str2, *str3;    size_t length, length2, length3;    jschar *chars;    jsint i, j;    jsdouble d, d2;    JSFunction *fun;    JSType type;#ifdef DEBUG    FILE *tracefp;#endif#if JS_HAS_SWITCH_STATEMENT    jsint low, high;    uintN off, npairs;    JSBool match;#endif#if JS_HAS_LEXICAL_CLOSURE    JSFunction *fun2;    JSObject *closure;#endif#if JS_HAS_EXPORT_IMPORT    uintN attrs;#endif#if JS_HAS_EXCEPTIONS    JSTryNote *tn;    ptrdiff_t offset;#endif    if (cx->interpLevel == MAX_INTERP_LEVEL) {	JS_ReportError(cx, "too much recursion");	return JS_FALSE;    }    cx->interpLevel++;    *result = JSVAL_VOID;    rt = cx->runtime;    /*     * Set registerized frame pointer and derived pointers.     */    fp = cx->fp;    script = fp->script;    obj = fp->scopeChain;    /*     * 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) {                                                   \    if (len < 0 && onbranch) {                                                \	SAVE_SP(fp);                                                          \	if (!(ok = (*onbranch)(cx, script)))                                  \	    goto out;                                                         \    }                                                                         \}    /*     * Allocate operand and pc stack slots for the script's worst-case depth.     */    depth = (ptrdiff_t)script->depth;    newsp = js_AllocStack(cx, (uintN)(2 * depth), &mark);    if (!newsp) {	ok = JS_FALSE;	goto out;    }    newsp += depth;    fp->sp = sp = newsp;    pc = script->code;    endpc = pc + script->length;    while (pc < endpc) {	fp->pc = pc;	op = (JSOp)*pc;      do_op:	cs = &js_CodeSpec[op];	len = cs->length;#ifdef DEBUG	tracefp = cx->tracefp;	if (tracefp) {	    intN nuses, n;	    fprintf(tracefp, "%4u: ", js_PCToLineNumber(script, pc));	    js_Disassemble1(cx, script, pc, pc - script->code, JS_FALSE,			    tracefp);	    nuses = cs->nuses;	    if (nuses) {		fp->sp = sp - nuses;		for (n = 0; n < nuses; n++) {		    str = js_DecompileValueGenerator(cx, *fp->sp, NULL);		    if (str != NULL) {			fprintf(tracefp, "%s %s",				(n == 0) ? "  inputs:" : ",",				JS_GetStringBytes(str));		    }		    fp->sp++;		}		putc('\n', tracefp);	    }	}#endif	if (rt->interruptHandler) {	    JSTrapHandler handler = (JSTrapHandler) rt->interruptHandler;            /* check copy of pointer for safety in multithreaded situation */            if (handler) {	        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;	          default:;	        }            }	}	switch (op) {	  case JSOP_NOP:	    break;	  case JSOP_PUSH:	    PUSH_OPND(JSVAL_VOID);	    break;	  case JSOP_POP:	    sp--;	    break;	  case JSOP_POP2:	    sp -= 2;	    break;	  case JSOP_POPV:	    *result = POP();	    break;	  case JSOP_ENTERWITH:	    rval = POP();	    VALUE_TO_OBJECT(cx, rval, obj);	    withobj = js_NewObject(cx, &js_WithClass, obj, fp->scopeChain);	    if (!withobj)		goto out;	    fp->scopeChain = withobj;	    PUSH_OPND(OBJECT_TO_JSVAL(withobj));	    break;	  case JSOP_LEAVEWITH:	    rval = POP();	    PR_ASSERT(JSVAL_IS_OBJECT(rval));	    withobj = JSVAL_TO_OBJECT(rval);	    PR_ASSERT(OBJ_GET_CLASS(cx, withobj) == &js_WithClass);	    rval = OBJ_GET_SLOT(cx, withobj, JSSLOT_PARENT);	    PR_ASSERT(JSVAL_IS_OBJECT(rval));	    fp->scopeChain = JSVAL_TO_OBJECT(rval);	    break;	  case JSOP_RETURN:	    CHECK_BRANCH(-1);	    fp->rval = POP();	    goto out;	  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;#if !JS_BUG_SHORT_CIRCUIT	  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;#endif	  case JSOP_TOOBJECT:	    rval = POP();	    SAVE_SP(fp);	    ok = js_ValueToObject(cx, rval, &obj);	    if (!ok)		goto out;	    PUSH(OBJECT_TO_JSVAL(obj));	    break;#define POP_ELEMENT_ID(id) {                                                  \    /* If the index is not a jsint, atomize it. */                            \    id = (jsid) POP();                                                        \    if (JSVAL_IS_INT(id)) {                                                   \    	atom = NULL;                                                          \    } else {                                                                  \	atom = js_ValueToStringAtom(cx, (jsval)id);                           \	if (!atom) {                                                          \	    ok = JS_FALSE;                                                    \	    goto out;                                                         \	}                                                                     \	id = (jsid)atom;                                                      \    }                                                                         \}#if JS_HAS_IN_OPERATOR	  case JSOP_IN:	    rval = POP();            if (!JSVAL_IS_OBJECT(rval) || rval == JSVAL_NULL) {                JS_ReportError(cx, "target of 'in' operator must be an object");                ok = JS_FALSE;                goto out;            }            obj = JSVAL_TO_OBJECT(rval);	    POP_ELEMENT_ID(id);	    ok = OBJ_LOOKUP_PROPERTY(cx, obj, id, &obj2, &prop);	    if (!ok)		goto out;	    PUSH_OPND(BOOLEAN_TO_JSVAL(prop != NULL));	    break;#endif /* JS_HAS_IN_OPERATOR */	  case JSOP_FORNAME:	    rval = POP();	    /* FALL THROUGH */	  case JSOP_FORNAME2:	    atom = GET_ATOM(cx, script, pc);	    id   = (jsid)atom;	    SAVE_SP(fp);	    ok = js_FindVariable(cx, id, &obj, &obj2, &prop);	    if (!ok)		goto out;	    PR_ASSERT(prop);	    OBJ_DROP_PROPERTY(cx, obj2, prop);	    lval = OBJECT_TO_JSVAL(obj);	    goto do_forinloop;	  case JSOP_FORPROP:	    rval = POP();	    /* FALL THROUGH */	  case JSOP_FORPROP2:	    lval = POP();	    atom = GET_ATOM(cx, script, pc);	    id   = (jsid)atom;	    goto do_forinloop;	  case JSOP_FORELEM:	    rval = POP();	    /* FALL THROUGH */	  case JSOP_FORELEM2:	    POP_ELEMENT_ID(id);	    lval = POP();	  do_forinloop:	    /*             * ECMA-compatible for/in evals the object just once, before loop.             */	    if (cs->format & JOF_FOR2) {		obj = JSVAL_TO_OBJECT(sp[-1]);		vp = sp - 2;	    } else {                /* Old-style (pre-ECMA) JSOPs */		SAVE_SP(fp);		ok = js_ValueToObject(cx, rval, &obj);		if (!ok)		    goto out;		vp = sp - 1;	    }	    /* 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.)             */	    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, NULL);		if (!propobj) {		    ok = JS_FALSE;		    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);		propobj->slots[JSSLOT_ITR_STATE] = iter_state;		if (!ok)                    goto out;		/*                 * Stash private iteration state into property iterator object.                 * NB: This code knows that the first slots are pre-allocated.                 */		PR_ASSERT(JS_INITIAL_NSLOTS >= 5);		propobj->slots[JSSLOT_PARENT] = OBJECT_TO_JSVAL(obj);	    } 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_ITR_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_ITR_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);		propobj->slots[JSSLOT_ITR_STATE] = iter_state;		if (!ok)                    goto out;		/* Stash private iteration state into iterator JSObject. */		propobj->slots[JSSLOT_PARENT] = OBJECT_TO_JSVAL(obj);                goto enum_next_property;            }	    /* Skip deleted and shadowed properties, leave next id in rval. */            if (obj != origobj) {                /* Have we already enumerated a clone of this property? */		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;                }	    }	    /* Convert lval to a non-null object containing id. */	    VALUE_TO_OBJECT(cx, lval, obj);	    /* 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_1) &&                       (cx->version >= JSVERSION_1_0)) {		str = js_NumberToString(cx, (jsdouble) JSVAL_TO_INT(rval));		if (!str) {		    ok = JS_FALSE;		    goto out;		}		/* Hold via sp[0] in case the GC runs under OBJ_SET_PROPERTY. */		rval = sp[0] = STRING_TO_JSVAL(str);	    }	    /* Set the variable obj[id] to refer to rval. */	    ok = OBJ_SET_PROPERTY(cx, obj, id, &rval);	    if (!ok)		goto out;	    /* Push true to keep looping through properties. */	    rval = JSVAL_TRUE;	  end_forinloop:	    PUSH_OPND(rval);	    break;	  case JSOP_DUP:	    PR_ASSERT(sp > newsp);	    rval = sp[-1];	    PUSH_OPND(rval);	    break;	  case JSOP_DUP2:	    PR_ASSERT(sp - 1 > newsp);	    lval = sp[-2];	    rval = sp[-1];	    PUSH_OPND(lval);	    PUSH_OPND(rval);	    break;#define PROPERTY_OP(call) {                                                   \    /* Pop the left part and resolve it to a non-null object. */              \    lval = POP();                                                             \    VALUE_TO_OBJECT(cx, lval, obj);                                           \									      \    /* Get or set the property, set ok false if error, true if success. */    \    call;                                                                     \    if (!ok)                                                                  \	goto out;                                                             \}#define ELEMENT_OP(call) {                                                    \    POP_ELEMENT_ID(id);                                                       \    PROPERTY_OP(call);                                                        \}#define CACHED_GET(call) {                                                    \    PROPERTY_CACHE_TEST(&rt->propertyCache, obj, id, prop);                   \    if (PROP_FOUND(prop)) {                                                   \	sprop = (JSScopeProperty *)prop;                                      \	slot = (uintN)sprop->slot;                                            \	rval = OBJ_GET_SLOT(cx, obj, slot);                                   \	ok = SPROP_GET(cx, sprop, obj, obj, &rval);                           \	if (ok)                                                               \	    OBJ_SET_SLOT(cx, obj, slot, rval);                                \    } else {                                                                  \	SAVE_SP(fp);                                                          \	ok = call;                                                            \	/* No fill here: js_GetProperty fills the cache. */                   \    }                                                                         \}#if JS_BUG_SET_ENUMERATE#define SET_ENUMERATE_ATTR(sprop) ((sprop)->attrs |= JSPROP_ENUMERATE)#else#define SET_ENUMERATE_ATTR(sprop) ((void)0)#endif#define CACHED_SET(call) {                                                    \    PROPERTY_CACHE_TEST(&rt->propertyCache, obj, id, prop);                   \    if (PROP_FOUND(prop) &&                                                   \	!(sprop = (JSScopeProperty *)prop,                                    \	  sprop->attrs & (JSPROP_READONLY | JSPROP_ASSIGNHACK))) {            \	ok = SPROP_SET(cx, sprop, obj, obj, &rval);                           \	if (ok) {                                                             \	    SET_ENUMERATE_ATTR(sprop);                                        \	    OBJ_SET_SLOT(cx, obj, sprop->slot, rval);                         \	}                                                                     \    } else {                                                                  \	SAVE_SP(fp);                                                          \	ok = call;                                                            \	/* No fill here: js_SetProperty writes through the cache. */          \    }                                                                         \}	  case JSOP_SETNAME:	    /* Get an immediate atom naming the variable to set. */	    atom = GET_ATOM(cx, script, pc);	    id   = (jsid)atom;	    SAVE_SP(fp);	    ok = js_FindVariable(cx, id, &obj, &obj2, &prop);	    if (!ok)		goto out;	    PR_ASSERT(prop);	    OBJ_DROP_PROPERTY(cx, obj2, prop);	    /* Pop the right-hand side and set obj[id] to it. */	    rval = POP();	    /* Try to hit the property cache, FindVariable primes it. */	    CACHED_SET(OBJ_SET_PROPERTY(cx, obj, id, &rval));	    if (!ok)		goto out;	    /* Push the right-hand side as our result. */	    PUSH_OPND(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_SETNAME2:	    atom = GET_ATOM(cx, script, pc);	    id   = (jsid)atom;	    rval = POP();	    lval = POP();	    PR_ASSERT(!JSVAL_IS_PRIMITIVE(lval));	    obj  = JSVAL_TO_OBJECT(lval);	    CACHED_SET(OBJ_SET_PROPERTY(cx, obj, id, &rval));	    if (!ok)		goto out;	    PUSH_OPND(rval);	    break;#define INTEGER_OP(OP, EXTRA_CODE) {                                          \    SAVE_SP(fp);                                                              \    ok = PopInt(cx, &j) && PopInt(cx, &i);                                    \    RESTORE_SP(fp);                                                           \    if (!ok)                                                                  \	goto out;                                                             \    EXTRA_CODE                                                                \    i = i OP j;                                                               \    PUSH_NUMBER(cx, i);                                                       \}#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) {                                                   \    rval = POP();                                                             \    lval = POP();                                                             \    /* 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);                   \	/* Need lval for strcmp or ToNumber later, so root it via sp[0]. */   \	sp[0] = 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 {                                                              \	    /* Need rval after ToNumber(lval), so root it via sp[1]. */       \	    sp[1] = rval;                                                     \	    VALUE_TO_NUMBER(cx, lval, d);                                     \	    VALUE_TO_NUMBER(cx, rval, d2);                                    \	    cond = COMPARE_DOUBLES(d, OP, d2, JS_FALSE);                      \	}                                                                     \    }                                                                         \    PUSH_OPND(BOOLEAN_TO_JSVAL(cond));                                        \}#define EQUALITY_OP(OP, IFNAN) {                                              \    rval = POP();                                                             \    lval = POP();                                                             \    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 {                                                          \		/* Need rval after ToNumber(lval), so root it via sp[1]. */   \		sp[1] = rval;                                                 \		VALUE_TO_NUMBER(cx, lval, d);                                 \		VALUE_TO_NUMBER(cx, rval, d2);                                \		cond = COMPARE_DOUBLES(d, OP, d2, IFNAN);                     \	    }                                                                 \	}                                                                     \    }                                                                         \    PUSH_OPND(BOOLEAN_TO_JSVAL(cond));                                        \}	  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) {                                          \    rval = POP();                                                             \    lval = POP();                                                             \    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;                                              \	}                                                                     \    }                                                                         \    PUSH_OPND(BOOLEAN_TO_JSVAL(cond));                                        \}	  case JSOP_NEW_EQ:	    NEW_EQUALITY_OP(==, JS_FALSE);	    break;	  case JSOP_NEW_NE:	    NEW_EQUALITY_OP(!=, JS_TRUE);	    break;#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;	    SAVE_SP(fp);	    ok = PopInt(cx, &j) && PopUint(cx, &u);	    RESTORE_SP(fp);	    if (!ok)		goto out;	    j &= 31;	    d = u >> j;	    PUSH_NUMBER(cx, d);	    break;	  }#undef INTEGER_OP#undef BITWISE_OP#undef SIGNED_SHIFT_OP	  case JSOP_ADD:	    rval = rtmp = POP();	    lval = ltmp = POP();	    VALUE_TO_PRIMITIVE(cx, lval, JSTYPE_VOID, &lval);	    if ((cond = JSVAL_IS_STRING(lval)) != 0) {		/*		 * Keep lval on the stack so it isn't GC'd during either the		 * next VALUE_TO_PRIMITIVE or the js_ValueToString(cx, rval).		 */		sp[0] = lval;	    }	    VALUE_TO_PRIMITIVE(cx, rval, JSTYPE_VOID, &rval);	    if (cond || JSVAL_IS_STRING(rval)) {		if (cond) {		    str = JSVAL_TO_STRING(lval);		    SAVE_SP(fp);		    ok = (str2 = js_ValueToString(cx, rval)) != NULL;		} else {		    /*		     * Keep rval on the stack so it isn't GC'd during the next		     * js_ValueToString.		     */		    sp[1] = rval;		    str2 = JSVAL_TO_STRING(rval);		    SAVE_SP(fp);		    ok = (str = js_ValueToString(cx, lval)) != NULL;		}		if (!ok)		    goto out;		if ((length = str->length) == 0) {		    str3 = str2;		} else if ((length2 = str2->length) == 0) {		    str3 = str;		} else {		    length3 = length + length2;		    chars = JS_malloc(cx, (length3 + 1) * sizeof(jschar));		    if (!chars) {			ok = JS_FALSE;			goto out;		    }		    js_strncpy(chars, str->chars, length);		    js_strncpy(chars + length, str2->chars, length2);		    chars[length3] = 0;		    str3 = js_NewString(cx, chars, length3, 0);		    if (!str3) {			JS_free(cx, chars);			ok = JS_FALSE;			goto out;		    }		}		PUSH_OPND(STRING_TO_JSVAL(str3));	    } else {		VALUE_TO_NUMBER(cx, ltmp, d);		VALUE_TO_NUMBER(cx, rtmp, d2);		d += d2;		PUSH_NUMBER(cx, d);	    }	    break;#define BINARY_OP(OP) {                                                       \    POP_NUMBER(cx, d2);                                                       \    POP_NUMBER(cx, d);                                                        \    d = d OP d2;                                                              \    PUSH_NUMBER(cx, d);                                                       \}	  case JSOP_SUB:	    BINARY_OP(-);	    break;	  case JSOP_MUL:	    BINARY_OP(*);	    break;	  case JSOP_DIV:	    POP_NUMBER(cx, d2);	    POP_NUMBER(cx, d);	    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);		PUSH_OPND(rval);	    } else {		d /= d2;		PUSH_NUMBER(cx, d);	    }	    break;	  case JSOP_MOD:	    POP_NUMBER(cx, d2);	    POP_NUMBER(cx, d);	    if (d2 == 0) {		PUSH_OPND(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);		PUSH_NUMBER(cx, d);	    }	    break;	  case JSOP_NOT:	    POP_BOOLEAN(cx, rval, cond);	    PUSH_OPND(BOOLEAN_TO_JSVAL(!cond));	    break;	  case JSOP_BITNOT:	    SAVE_SP(fp);	    ok = PopInt(cx, &i);	    RESTORE_SP(fp);	    if (!ok)		goto out;            i = ~i;            PUSH_NUMBER(cx, i);	    break;	  case JSOP_NEG:	    POP_NUMBER(cx, d);	    d = -d;	    PUSH_NUMBER(cx, d);	    break;	  case JSOP_POS:	    POP_NUMBER(cx, d);	    PUSH_NUMBER(cx, d);	    break;	  case JSOP_NEW:	    /* Get immediate argc and find the constructor function. */	    argc = GET_ARGC(pc);	  do_new:	    vp = sp - (2 + argc);	    PR_ASSERT(vp >= newsp);	    lval = *vp;	    if (!JSVAL_IS_OBJECT(lval) ||		(obj2 = JSVAL_TO_OBJECT(lval)) == NULL ||		!obj2->map->ops->construct) {		fun = js_ValueToFunction(cx, vp, JS_TRUE);		if (!fun) {		    ok = JS_FALSE;		    goto out;		}		obj2 = fun->object;	    }	    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 there is no class prototype, use js_ObjectClass. */	    if (!proto)		obj = js_NewObject(cx, &js_ObjectClass, NULL, parent);	    else		obj = js_NewObject(cx, OBJ_GET_CLASS(cx, proto), 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, JS_TRUE);	    RESTORE_SP(fp);	    if (!ok) {		cx->newborn[GCX_OBJECT] = NULL;#if JS_HAS_EXCEPTIONS		if (fp->throwing) {		    sp[-1] = fp->exception;		    goto do_throw;		}#endif		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)) {		    /* Pre-ECMA code would coerce result to obj. */		    *vp = OBJECT_TO_JSVAL(obj);		    break;		}		str = js_ValueToString(cx, rval);		if (str) {		    JS_ReportError(cx, "invalid new expression result %s",				   JS_GetStringBytes(str));		}		ok = JS_FALSE;		goto out;	    }	    obj = JSVAL_TO_OBJECT(rval);	    break;	  case JSOP_DELNAME:	    atom = GET_ATOM(cx, script, pc);	    id   = (jsid)atom;	    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;	    SAVE_SP(fp);	    PROPERTY_OP(ok = OBJ_DELETE_PROPERTY(cx, obj, id, &rval));	    PUSH_OPND(rval);	    break;	  case JSOP_DELELEM:	    SAVE_SP(fp);	    ELEMENT_OP(ok = OBJ_DELETE_PROPERTY(cx, obj, id, &rval));	    PUSH_OPND(rval);	    break;	  case JSOP_TYPEOF:	    rval = POP();	    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();	    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();	    goto do_incop;	  case JSOP_INCELEM:	  case JSOP_DECELEM:	  case JSOP_ELEMINC:	  case JSOP_ELEMDEC:	    POP_ELEMENT_ID(id);	    lval = POP();	  do_incop:	    VALUE_TO_OBJECT(cx, lval, obj);	    /* The operand must contain a number. */	    CACHED_GET(OBJ_GET_PROPERTY(cx, obj, id, &rval));	    if (!ok)		goto out;	    VALUE_TO_NUMBER(cx, rval, d);	    /* Compute the post- or pre-incremented value. */	    if (cs->format & JOF_INC)		d2 = (cs->format & JOF_POST) ? d++ : ++d;	    else		d2 = (cs->format & JOF_POST) ? d-- : --d;	    /* Set obj[id] to the resulting number. */	    ok = js_NewNumberValue(cx, d, &rval);	    if (!ok)		goto out;	    CACHED_SET(OBJ_SET_PROPERTY(cx, obj, id, &rval));	    if (!ok)		goto out;	    PUSH_NUMBER(cx, d2);	    break;	  case JSOP_INCARG:	  case JSOP_DECARG:	  case JSOP_ARGINC:	  case JSOP_ARGDEC:	    slot = (uintN)GET_ARGNO(pc);	    PR_ASSERT(slot < fp->fun->nargs);	    rval = fp->argv[slot];	    VALUE_TO_NUMBER(cx, rval, d);	    /* Compute the post- or pre-incremented value. */	    if (cs->format & JOF_INC)		d2 = (cs->format & JOF_POST) ? d++ : ++d;	    else		d2 = (cs->format & JOF_POST) ? d-- : --d;	    ok = js_NewNumberValue(cx, d, &rval);	    if (!ok)		goto out;	    fp->argv[slot] = rval;	    PUSH_NUMBER(cx, d2);	    break;	  case JSOP_INCVAR:	  case JSOP_DECVAR:	  case JSOP_VARINC:	  case JSOP_VARDEC:	    slot = (uintN)GET_VARNO(pc);	    PR_ASSERT(slot < fp->fun->nvars);	    rval = fp->vars[slot];	    VALUE_TO_NUMBER(cx, rval, d);	    /* Compute the post- or pre-incremented value. */	    if (cs->format & JOF_INC)		d2 = (cs->format & JOF_POST) ? d++ : ++d;	    else		d2 = (cs->format & JOF_POST) ? d-- : --d;	    ok = js_NewNumberValue(cx, d, &rval);	    if (!ok)		goto out;	    fp->vars[slot] = rval;	    PUSH_NUMBER(cx, d2);	    break;	  case JSOP_GETPROP:	    /* Get an immediate atom naming the property. */	    atom = GET_ATOM(cx, script, pc);	    id   = (jsid)atom;	    PROPERTY_OP(CACHED_GET(OBJ_GET_PROPERTY(cx, obj, id, &rval)));	    PUSH_OPND(rval);	    break;	  case JSOP_SETPROP:	    /* Pop the right-hand side into rval for OBJ_SET_PROPERTY. */	    rval = POP();	    /* Get an immediate atom naming the property. */	    atom = GET_ATOM(cx, script, pc);	    id   = (jsid)atom;	    PROPERTY_OP(CACHED_SET(OBJ_SET_PROPERTY(cx, obj, id, &rval)));	    PUSH_OPND(rval);	    break;	  case JSOP_GETELEM:	    ELEMENT_OP(CACHED_GET(OBJ_GET_PROPERTY(cx, obj, id, &rval)));	    PUSH_OPND(rval);	    break;	  case JSOP_SETELEM:	    rval = POP();	    ELEMENT_OP(CACHED_SET(OBJ_SET_PROPERTY(cx, obj, id, &rval)));	    PUSH_OPND(rval);	    break;	  case JSOP_PUSHOBJ:	    PUSH_OPND(OBJECT_TO_JSVAL(obj));	    break;	  case JSOP_CALL:	    argc = GET_ARGC(pc);	    SAVE_SP(fp);	    ok = js_Invoke(cx, argc, JS_FALSE);	    RESTORE_SP(fp);	    if (!ok) {#if JS_HAS_EXCEPTIONS		if (fp->throwing) {		    /* do_throw expects to have the exception on the stack */		    sp[-1] = fp->exception;		    goto do_throw;		}#endif		goto out;	    }	    obj = NULL;	    break;	  case JSOP_NAME:	    atom = GET_ATOM(cx, script, pc);	    id   = (jsid)atom;	    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_NOP)			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 = LOCKED_OBJ_GET_SLOT(obj2, slot);	    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;	    }	    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);	    PR_ASSERT(JSVAL_IS_OBJECT(rval));	    PUSH_OPND(rval);	    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));	    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:	    SAVE_SP(fp);	    ok = PopInt(cx, &i);	    RESTORE_SP(fp);	    if (!ok)		goto out;	    pc2 = pc;	    len = GET_JUMP_OFFSET(pc2);	    pc2 += 2;	    low = GET_JUMP_OFFSET(pc2);	    pc2 += 2;	    high = GET_JUMP_OFFSET(pc2);	    i -= low;	    if ((jsuint)i <= (jsuint)(high - low)) {		pc2 += 2 + 2 * i;		off = GET_JUMP_OFFSET(pc2);		if (off)		    len = off;	    }	    break;	  case JSOP_LOOKUPSWITCH:	    lval = POP();	    pc2 = pc;	    len = GET_JUMP_OFFSET(pc2);	    if (!JSVAL_IS_NUMBER(lval) &&		!JSVAL_IS_STRING(lval) &&		!JSVAL_IS_BOOLEAN(lval)) {		goto advance_pc;	    }	    pc2 += 2;	    npairs = GET_ATOM_INDEX(pc2);	    pc2 += 2;#define SEARCH_PAIRS(MATCH_CODE)                                              \    while (npairs) {                                                          \	atom = GET_ATOM(cx, script, pc2);                                     \	rval = ATOM_KEY(atom);                                                \	MATCH_CODE                                                            \	if (match) {                                                          \	    pc2 += 2;                                                         \	    len = GET_JUMP_OFFSET(pc2);                                       \	    goto advance_pc;                                                  \	}                                                                     \	pc2 += 4;                                                             \	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;#endif /* JS_HAS_SWITCH_STATEMENT */#if JS_HAS_LEXICAL_CLOSURE	  case JSOP_CLOSURE:	    /*	     * If the nearest variable scope is a function, not a call object,	     * replace it in the scope chain with its call object.	     */	    obj = js_FindVariableScope(cx, &fun);	    if (!obj) {		ok = JS_FALSE;		goto out;	    }	    /*	     * If in a with statement, set obj to the With object's prototype,	     * i.e., the object specified in the with statement head.	     */	    if (fp->scopeChain != obj) {		obj = fp->scopeChain;		PR_ASSERT(OBJ_GET_CLASS(cx, obj) == &js_WithClass);#if JS_BUG_WITH_CLOSURE		while (OBJ_GET_CLASS(cx, obj) == &js_WithClass) {		    proto = OBJ_GET_PROTO(cx, obj);		    if (!proto)			break;		    obj = proto;		}#endif	    }	    /*	     * Get immediate operand atom, which is a function object literal.	     * From it, get the function to close.	     */	    atom = GET_ATOM(cx, script, pc);	    PR_ASSERT(ATOM_IS_OBJECT(atom));	    obj2 = ATOM_TO_OBJECT(atom);	    fun2 = JS_GetPrivate(cx, obj2);	    /*	     * Let closure = new Closure(obj2).	     * NB: js_ConstructObject does not use the "constructor" property	     * of the new object it creates, because in this case and others	     * such as js_WithClass, that property refers to the prototype's	     * constructor function.	     */	    closure = js_ConstructObject(cx, &js_ClosureClass, obj2,					 fp->scopeChain);	    if (!closure) {		ok = JS_FALSE;		goto out;	    }	    /*	     * Define a property in obj with id fun2->atom and value closure,	     * but only if fun2 is not anonymous.	     */	    if (fun2->atom) {		ok = OBJ_DEFINE_PROPERTY(cx, obj, (jsid)fun2->atom,					 OBJECT_TO_JSVAL(closure),					 NULL, NULL, JSPROP_ENUMERATE,					 NULL);		if (!ok) {		    cx->newborn[GCX_OBJECT] = NULL;		    goto out;		}	    }	    PUSH_OPND(OBJECT_TO_JSVAL(closure));	    break;#endif /* JS_HAS_LEXICAL_CLOSURE */#if JS_HAS_EXPORT_IMPORT	  case JSOP_EXPORTALL:	    obj = js_FindVariableScope(cx, &fun);	    if (!obj) {		ok = JS_FALSE;	    } else {		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  = js_FindVariableScope(cx, &fun);	    if (!obj) {		ok = JS_FALSE;		goto out;	    }	    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(ok = ImportProperty(cx, obj, id));	    break;	  case JSOP_IMPORTPROP:	    /* Get an immediate atom naming the property. */	    atom = GET_ATOM(cx, script, pc);	    id   = (jsid)atom;	    PROPERTY_OP(ok = ImportProperty(cx, obj, id));	    break;	  case JSOP_IMPORTELEM:	    ELEMENT_OP(ok = ImportProperty(cx, obj, id));	    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:		PR_ASSERT(JSVAL_IS_INT(rval));		op = (JSOp) JSVAL_TO_INT(rval);		PR_ASSERT((uintN)op < (uintN)JSOP_LIMIT);		goto do_op;	      case JSTRAP_RETURN:		fp->rval = rval;		goto out;	      default:;	    }	    break;	  case JSOP_GETARG:	    obj = NULL;	    slot = (uintN)GET_ARGNO(pc);	    PR_ASSERT(slot < fp->fun->nargs);	    PUSH_OPND(fp->argv[slot]);	    break;	  case JSOP_SETARG:	    obj = NULL;	    slot = (uintN)GET_ARGNO(pc);	    PR_ASSERT(slot < fp->fun->nargs);	    vp = &fp->argv[slot];	    GC_POKE(cx, *vp);	    *vp = sp[-1];	    break;	  case JSOP_GETVAR:	    obj = NULL;	    slot = (uintN)GET_VARNO(pc);	    PR_ASSERT(slot < fp->fun->nvars);	    PUSH_OPND(fp->vars[slot]);	    break;	  case JSOP_SETVAR:	    obj = NULL;	    slot = (uintN)GET_VARNO(pc);	    PR_ASSERT(slot < fp->fun->nvars);	    vp = &fp->vars[slot];	    GC_POKE(cx, *vp);	    *vp = sp[-1];	    break;#if JS_HAS_INITIALIZERS	  case JSOP_NEWINIT:	    argc = 0;	    fp->sharpDepth++;	    goto do_new;	  case JSOP_ENDINIT:	    if (--fp->sharpDepth == 0)		fp->sharpArray = NULL;	    break;	  case JSOP_INITPROP:	    /* Pop the property's value into rval. */	    PR_ASSERT(sp - newsp >= 2);	    rval = POP();	    /* Get the immediate property name into id. */	    atom = GET_ATOM(cx, script, pc);	    id   = (jsid)atom;	    goto do_init;	  case JSOP_INITELEM:	    /* Pop the element's value into rval. */	    PR_ASSERT(sp - newsp >= 3);	    rval = POP();	    /* Pop and conditionally atomize the element id. */	    POP_ELEMENT_ID(id);	  do_init:	    /* Find the object being initialized at top of stack. */	    lval = sp[-1];	    PR_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;	    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 = sp[-1];	    if (JSVAL_IS_PRIMITIVE(rval)) {		JS_ReportError(cx, "invalid sharp variable definition #%u=",			       (unsigned) i);	    	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)) {		JS_ReportError(cx, "invalid sharp variable use #%u#",			       (unsigned) i);		ok = JS_FALSE;		goto out;	    }	    PUSH_OPND(rval);	    break;#endif /* JS_HAS_SHARP_VARS */#endif /* JS_HAS_INITIALIZERS */#if JS_HAS_EXCEPTIONS	  case JSOP_JSR:	    len = GET_JUMP_OFFSET(pc);	    PUSH(INT_TO_JSVAL(pc - script->code));	    CHECK_BRANCH(len);	    break;	  case JSOP_RETSUB:	    rval = POP();	    PR_ASSERT(JSVAL_IS_INT(rval));	    pc = script->code + JSVAL_TO_INT(rval) + 3 /* JSR */;	    len = 0;	    CHECK_BRANCH(-1);	    break;	  case JSOP_EXCEPTION:	    PUSH(fp->exception);	    break;	  case JSOP_THROW:	  do_throw:	    fp->exception = POP();	    tn = script->trynotes;	    offset = PTRDIFF(pc, script->code, jsbytecode);	    if (tn) {		while (PR_UPTRDIFF(offset, tn->start) >= (pruword)tn->length)		    tn++;		if (tn->catchStart) {		    pc = script->code + tn->catchStart;		    len = 0;		    goto advance_pc;		}	    }	    /* Not in a catch block, so propagate the exception. */	    fp->throwing = JS_TRUE;	    ok = JS_FALSE;	    goto out;#endif /* JS_HAS_EXCEPTIONS */#if JS_HAS_INSTANCEOF	  case JSOP_INSTANCEOF:	    rval = POP();	    if (JSVAL_IS_PRIMITIVE(rval)) {		str = js_DecompileValueGenerator(cx, rval, NULL);		if (str) {		    JS_ReportError(cx, "invalid %s operand %s",				   js_instanceof_str, JS_GetStringBytes(str));		}	    	ok = JS_FALSE;	    	goto out;	    }	    obj = JSVAL_TO_OBJECT(rval);	    lval = POP();	    cond = JS_FALSE;	    if (obj->map->ops->hasInstance) {		SAVE_SP(fp);		ok = obj->map->ops->hasInstance(cx, obj, lval, &cond);		if (!ok)		    goto out;	    }	    PUSH_OPND(BOOLEAN_TO_JSVAL(cond));	    break;#endif /* JS_HAS_INSTANCEOF */#if JS_HAS_DEBUGGER_KEYWORD          case JSOP_DEBUGGER:	    if (rt->debuggerHandler) {	        JSTrapHandler handler = (JSTrapHandler) rt->debuggerHandler;                /* check copy of pointer for safety in multithread situation */                if (handler) {	            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;	              default:;	            }                }	    }	    break;#endif /* JS_HAS_DEBUGGER_KEYWORD */	  default:	    JS_ReportError(cx, "unimplemented JavaScript bytecode %d", op);	    ok = JS_FALSE;	    goto out;	}    advance_pc:	pc += len;#ifdef DEBUG	if (tracefp) {	    intN ndefs, n;	    ndefs = cs->ndefs;	    if (ndefs) {		fp->sp = sp - ndefs;		for (n = 0; n < ndefs; n++) {		    str = js_DecompileValueGenerator(cx, *fp->sp, NULL);		    if (str) {			fprintf(tracefp, "%s %s",				(n == 0) ? "  output:" : ",",				JS_GetStringBytes(str));		    }		    fp->sp++;		}		putc('\n', tracefp);	    }	}#endif    }out:    /*     * Restore the previous frame's execution state.     */    js_FreeStack(cx, mark);    cx->interpLevel--;    return ok;}