lval = ATOM_BYTES(atom);
lval = QuoteString(&ss->sprinter, ATOM_TO_STRING(atom), 0); if (!lval) return JS_FALSE;
Decompile(SprintStack *ss, jsbytecode *pc, intN nb){    JSContext *cx;    JSPrinter *jp, *jp2;    jsbytecode *endpc, *done, *forelem_done;    ptrdiff_t len, todo, oplen, cond, next, tail;    JSOp op, lastop, saveop;    JSCodeSpec *cs, *topcs;    jssrcnote *sn;    const char *lval, *rval, *xval;    jsint i, argc;    char **argv;    JSAtom *atom;    JSObject *obj;    JSFunction *fun;    JSString *str;    JSBool ok;    jsval key;/* * Local macros*/#define DECOMPILE_CODE(pc,nb)	if (!Decompile(ss, pc, nb)) return JS_FALSE#define POP_STR()		OFF2STR(&ss->sprinter, PopOff(ss, op))#define LOCAL_ASSERT(expr)	JS_ASSERT(expr); if (!(expr)) return JS_FALSE    cx = ss->sprinter.context;    jp = ss->printer;    endpc = pc + nb;    forelem_done = NULL;    todo = -2;			/* NB: different from Sprint() error return. */    tail = -1;    op = JSOP_NOP;    sn = NULL;    rval = NULL;    while (pc < endpc) {	lastop = op;	op = saveop = (JSOp) *pc;	if (op >= JSOP_LIMIT) {	    switch (op) {	      case JSOP_GETPROP2:		saveop = JSOP_GETPROP;		break;	      case JSOP_GETELEM2:		saveop = JSOP_GETELEM;		break;	      default:;	    }	}	cs = &js_CodeSpec[saveop];	len = oplen = cs->length;	if (cs->token) {	    switch (cs->nuses) {	      case 2:		rval = POP_STR();		lval = POP_STR();		if ((sn = js_GetSrcNote(jp->script, pc)) != NULL &&		    SN_TYPE(sn) == SRC_ASSIGNOP) {		    /* Print only the right operand of the assignment-op. */		    todo = SprintPut(&ss->sprinter, rval, strlen(rval));		} else {		    todo = Sprint(&ss->sprinter, "%s %s %s",				  lval, cs->token, rval);		}		break;	      case 1:		rval = POP_STR();		todo = Sprint(&ss->sprinter, "%s%s", cs->token, rval);		break;	      case 0:#if JS_HAS_GETTER_SETTER                if (op == JSOP_GETTER || op == JSOP_SETTER) {                    todo = -2;                    break;                }#endif		todo = SprintPut(&ss->sprinter, cs->token, strlen(cs->token));		break;	      default:		todo = -2;		break;	    }	} else {	    switch (op) {	      case JSOP_NOP:		/*                 * Check for a do-while loop, a for-loop with an empty                 * initializer part, a labeled statement, a function                 * definition, or try/finally.		 */		sn = js_GetSrcNote(jp->script, pc);		todo = -2;		switch (sn ? SN_TYPE(sn) : SRC_NULL) {#if JS_HAS_DO_WHILE_LOOP		  case SRC_WHILE:		    js_printf(jp, "\tdo {\n");		    jp->indent += 4;		    break;#endif /* JS_HAS_DO_WHILE_LOOP */		  case SRC_FOR:		    rval = "";		  do_forloop:		    /* Skip the JSOP_NOP or JSOP_POP bytecode. */		    pc++;		    /* Get the cond, next, and loop-closing tail offsets. */		    cond = js_GetSrcNoteOffset(sn, 0);		    next = js_GetSrcNoteOffset(sn, 1);		    tail = js_GetSrcNoteOffset(sn, 2);		    LOCAL_ASSERT(tail + GetJumpOffset(pc+tail, pc+tail) == 0);		    /* Print the keyword and the possibly empty init-part. */		    js_printf(jp, "\tfor (%s;", rval);		    if (pc[cond] == JSOP_IFEQ || pc[cond] == JSOP_IFEQX) {			/* Decompile the loop condition. */			DECOMPILE_CODE(pc, cond);			js_printf(jp, " %s", POP_STR());		    }		    /* Need a semicolon whether or not there was a cond. */		    js_puts(jp, ";");		    if (pc[next] != JSOP_GOTO && pc[next] != JSOP_GOTOX) {			/* Decompile the loop updater. */			DECOMPILE_CODE(pc + next, tail - next - 1);			js_printf(jp, " %s", POP_STR());		    }		    /* Do the loop body. */		    js_puts(jp, ") {\n");		    jp->indent += 4;		    oplen = (cond) ? js_CodeSpec[pc[cond]].length : 0;		    DECOMPILE_CODE(pc + cond + oplen, next - cond - oplen);		    jp->indent -= 4;		    js_printf(jp, "\t}\n");		    /* Set len so pc skips over the entire loop. */		    len = tail + js_CodeSpec[pc[tail]].length;		    break;		  case SRC_LABEL:		    atom = js_GetAtom(cx, &jp->script->atomMap,				      (jsatomid) js_GetSrcNoteOffset(sn, 0));		    jp->indent -= 4;		    js_printf(jp, "\t%s:\n", ATOM_BYTES(atom));		    jp->indent += 4;		    break;		  case SRC_LABELBRACE:		    atom = js_GetAtom(cx, &jp->script->atomMap,				      (jsatomid) js_GetSrcNoteOffset(sn, 0));		    js_printf(jp, "\t%s: {\n", ATOM_BYTES(atom));		    jp->indent += 4;		    break;		  case SRC_ENDBRACE:		    jp->indent -= 4;		    js_printf(jp, "\t}\n");		    break;		  case SRC_CATCH:		    jp->indent -= 4;		    sn = js_GetSrcNote(jp->script, pc);		    pc += oplen;		    js_printf(jp, "\t} catch (");                    LOCAL_ASSERT(*pc == JSOP_NAME);                    pc += js_CodeSpec[JSOP_NAME].length;                    LOCAL_ASSERT(*pc == JSOP_PUSHOBJ);                    pc += js_CodeSpec[JSOP_PUSHOBJ].length;                    LOCAL_ASSERT(*pc == JSOP_NEWINIT);                    pc += js_CodeSpec[JSOP_NEWINIT].length;                    LOCAL_ASSERT(*pc == JSOP_EXCEPTION);                    pc += js_CodeSpec[JSOP_EXCEPTION].length;                    LOCAL_ASSERT(*pc == JSOP_INITCATCHVAR);		    js_printf(jp, "%s",			      ATOM_BYTES(GET_ATOM(cx, jp->script, pc)));                    pc += js_CodeSpec[JSOP_INITCATCHVAR].length;                    LOCAL_ASSERT(*pc == JSOP_ENTERWITH);                    pc += js_CodeSpec[JSOP_ENTERWITH].length;		    len = js_GetSrcNoteOffset(sn, 0);		    if (len) {			js_printf(jp, " if ");			DECOMPILE_CODE(pc, len);			js_printf(jp, "%s", POP_STR());			pc += len;                        LOCAL_ASSERT(*pc == JSOP_IFEQ || *pc == JSOP_IFEQX);                        pc += js_CodeSpec[*pc].length;		    }		    js_printf(jp, ") {\n");		    jp->indent += 4;		    len = 0;		    break;		  case SRC_FUNCDEF:		    atom = js_GetAtom(cx, &jp->script->atomMap,				      (jsatomid) js_GetSrcNoteOffset(sn, 0));		    JS_ASSERT(ATOM_IS_OBJECT(atom));                  do_function:		    obj = ATOM_TO_OBJECT(atom);		    fun = (JSFunction *) JS_GetPrivate(cx, obj);		    jp2 = js_NewPrinter(cx, JS_GetFunctionName(fun),					jp->indent, jp->pretty);		    if (!jp2)			return JS_FALSE;		    jp2->scope = jp->scope;		    if (js_DecompileFunction(jp2, fun)) {			str = js_GetPrinterOutput(jp2);			if (str)			    js_printf(jp, "%s\n", JS_GetStringBytes(str));		    }		    js_DestroyPrinter(jp2);		    break;		  default:;		}              case JSOP_RETRVAL:		break;              case JSOP_GROUP:                /* Use last real op so PopOff adds parens if needed. */                todo = PopOff(ss, lastop);                /* Now add user-supplied parens only if PopOff did not. */                cs    = &js_CodeSpec[lastop];                topcs = &js_CodeSpec[ss->opcodes[ss->top]];                if (topcs->prec >= cs->prec) {                    todo = Sprint(&ss->sprinter, "(%s)",                                  OFF2STR(&ss->sprinter, todo));                }                break;	      case JSOP_PUSH:	      case JSOP_PUSHOBJ:	      case JSOP_BINDNAME:		todo = Sprint(&ss->sprinter, "");		break;#if JS_HAS_EXCEPTIONS              case JSOP_TRY:                js_printf(jp, "\ttry {\n");                jp->indent += 4;		todo = -2;                break;            {              static const char finally_cookie[] = "finally-cookie";              case JSOP_FINALLY:                jp->indent -= 4;                js_printf(jp, "\t} finally {\n");                jp->indent += 4;                /*                 * We must push an empty string placeholder for gosub's return                 * address, popped by JSOP_RETSUB and counted by script->depth                 * but not by ss->top (see JSOP_SETSP, below).                 */                todo = Sprint(&ss->sprinter, finally_cookie);                break;              case JSOP_RETSUB:                rval = POP_STR();                LOCAL_ASSERT(strcmp(rval, finally_cookie) == 0);                todo = -2;                break;            }              case JSOP_SWAP:                /*                 * We don't generate this opcode currently, and previously we                 * did not need to decompile it.  If old, serialized bytecode                 * uses it still, we should fall through and set todo = -2.                 */                /* FALL THROUGH */	      case JSOP_GOSUB:	      case JSOP_GOSUBX:                /*                 * JSOP_GOSUB and GOSUBX have no effect on the decompiler's                 * string stack because the next op in bytecode order finds                 * the stack balanced by a JSOP_RETSUB executed elsewhere.                 */		todo = -2;		break;	      case JSOP_SETSP:                /*                 * The compiler models operand stack depth and fixes the stack                 * pointer on entry to a catch clause based on its depth model.                 * The decompiler must match the code generator's model, which                 * is why JSOP_FINALLY pushes a cookie that JSOP_RETSUB pops.                 */                ss->top = (uintN) GET_ATOM_INDEX(pc);		break;	      case JSOP_EXCEPTION:                /*                 * The only other JSOP_EXCEPTION case occurs as part of a code                 * sequence that follows a SRC_CATCH-annotated JSOP_NOP.                 */                sn = js_GetSrcNote(jp->script, pc);                LOCAL_ASSERT(sn && SN_TYPE(sn) == SRC_HIDDEN);                todo = -2;		break;#endif /* JS_HAS_EXCEPTIONS */	      case JSOP_POP:	      case JSOP_POPV:		sn = js_GetSrcNote(jp->script, pc);		switch (sn ? SN_TYPE(sn) : SRC_NULL) {		  case SRC_FOR:		    rval = POP_STR();		    todo = -2;		    goto do_forloop;		  case SRC_PCDELTA:		    /* Pop and save to avoid blowing stack depth budget. */		    lval = JS_strdup(cx, POP_STR());		    if (!lval)			return JS_FALSE;		    /*                     * The offset tells distance to the end of the right-hand                     * operand of the comma operator.                     */		    done = pc + len;		    pc += js_GetSrcNoteOffset(sn, 0);		    len = 0;		    if (!Decompile(ss, done, pc - done)) {			JS_free(cx, (char *)lval);			return JS_FALSE;		    }		    /* Pop Decompile result and print comma expression. */		    rval = POP_STR();		    todo = Sprint(&ss->sprinter, "%s, %s", lval, rval);		    JS_free(cx, (char *)lval);		    break;		  case SRC_HIDDEN:		    /* Hide this pop, it's from a goto in a with or for/in. */		    todo = -2;		    break;		  default:		    rval = POP_STR();		    if (*rval != '\0')			js_printf(jp, "\t%s;\n", rval);		    todo = -2;		    break;		}		break;	      case JSOP_POP2:		(void) PopOff(ss, op);		(void) PopOff(ss, op);		todo = -2;		break;            {              static const char with_cookie[] = "with-cookie";	      case JSOP_ENTERWITH:		sn = js_GetSrcNote(jp->script, pc);		if (sn && SN_TYPE(sn) == SRC_HIDDEN) {                    todo = -2;                    break;                }                rval = POP_STR();                js_printf(jp, "\twith (%s) {\n", rval);                jp->indent += 4;                todo = Sprint(&ss->sprinter, with_cookie);		break;	      case JSOP_LEAVEWITH:		sn = js_GetSrcNote(jp->script, pc);                todo = -2;		if (sn && SN_TYPE(sn) == SRC_HIDDEN)                    break;                rval = POP_STR();                LOCAL_ASSERT(strcmp(rval, with_cookie) == 0);                jp->indent -= 4;                js_printf(jp, "\t}\n");		break;            }              case JSOP_SETRVAL:	      case JSOP_RETURN:		rval = POP_STR();		if (*rval != '\0')		    js_printf(jp, "\t%s %s;\n", cs->name, rval);		else		    js_printf(jp, "\t%s;\n", cs->name);                todo = -2;		break;#if JS_HAS_EXCEPTIONS	      case JSOP_THROW:		sn = js_GetSrcNote(jp->script, pc);		todo = -2;		if (sn && SN_TYPE(sn) == SRC_HIDDEN)		    break;		rval = POP_STR();		js_printf(jp, "\t%s %s;\n", cs->name, rval);		break;#endif /* JS_HAS_EXCEPTIONS */	      case JSOP_GOTO:	      case JSOP_GOTOX:		sn = js_GetSrcNote(jp->script, pc);		switch (sn ? SN_TYPE(sn) : SRC_NULL) {		  case SRC_CONT2LABEL:		    atom = js_GetAtom(cx, &jp->script->atomMap,				      (jsatomid) js_GetSrcNoteOffset(sn, 0));		    js_printf(jp, "\tcontinue %s;\n", ATOM_BYTES(atom));		    break;		  case SRC_CONTINUE:		    js_printf(jp, "\tcontinue;\n");		    break;		  case SRC_BREAK2LABEL:		    atom = js_GetAtom(cx, &jp->script->atomMap,				      (jsatomid) js_GetSrcNoteOffset(sn, 0));		    js_printf(jp, "\tbreak %s;\n", ATOM_BYTES(atom));		    break;		  case SRC_HIDDEN:		    break;		  default:		    js_printf(jp, "\tbreak;\n");		    break;		}		todo = -2;		break;	      case JSOP_IFEQ:	      case JSOP_IFEQX:		len = GetJumpOffset(pc, pc);		sn = js_GetSrcNote(jp->script, pc);		switch (sn ? SN_TYPE(sn) : SRC_NULL) {		  case SRC_IF:		  case SRC_IF_ELSE:		    rval = POP_STR();		    js_printf(jp, "\tif (%s) {\n", rval);		    jp->indent += 4;		    if (SN_TYPE(sn) == SRC_IF) {			DECOMPILE_CODE(pc + oplen, len - oplen);		    } else {                        len = js_GetSrcNoteOffset(sn, 0);			DECOMPILE_CODE(pc + oplen, len - oplen);			jp->indent -= 4;			pc += len;			LOCAL_ASSERT(*pc == JSOP_GOTO || *pc == JSOP_GOTOX);			oplen = js_CodeSpec[*pc].length;			len = GetJumpOffset(pc, pc);			js_printf(jp, "\t} else {\n");			jp->indent += 4;			DECOMPILE_CODE(pc + oplen, len - oplen);		    }		    jp->indent -= 4;		    js_printf(jp, "\t}\n");		    todo = -2;		    break;		  case SRC_WHILE:		    rval = POP_STR();		    js_printf(jp, "\twhile (%s) {\n", rval);		    jp->indent += 4;                    tail = js_GetSrcNoteOffset(sn, 0);		    DECOMPILE_CODE(pc + oplen, tail - oplen);		    jp->indent -= 4;		    js_printf(jp, "\t}\n");		    todo = -2;		    break;		  case SRC_COND:		    xval = JS_strdup(cx, POP_STR());		    if (!xval)			return JS_FALSE;                    len = js_GetSrcNoteOffset(sn, 0);		    DECOMPILE_CODE(pc + oplen, len - oplen);		    lval = JS_strdup(cx, POP_STR());		    if (!lval) {			JS_free(cx, (void *)xval);			return JS_FALSE;		    }		    pc += len;		    LOCAL_ASSERT(*pc == JSOP_GOTO || *pc == JSOP_GOTOX);		    oplen = js_CodeSpec[*pc].length;		    len = GetJumpOffset(pc, pc);		    DECOMPILE_CODE(pc + oplen, len - oplen);		    rval = POP_STR();		    todo = Sprint(&ss->sprinter, "%s ? %s : %s",				  xval, lval, rval);		    JS_free(cx, (void *)xval);		    JS_free(cx, (void *)lval);		    break;		  default:		    break;		}		break;	      case JSOP_IFNE:	      case JSOP_IFNEX:#if JS_HAS_DO_WHILE_LOOP		/* Currently, this must be a do-while loop's upward branch. */                jp->indent -= 4;                js_printf(jp, "\t} while (%s);\n", POP_STR());                todo = -2;#else                JS_ASSERT(0);#endif /* JS_HAS_DO_WHILE_LOOP */		break;	      case JSOP_OR:	      case JSOP_ORX:                xval = "||";              do_logical_connective:		/* Top of stack is the first clause in a disjunction (||). */		lval = JS_strdup(cx, POP_STR());		if (!lval)		    return JS_FALSE;		done = pc + GetJumpOffset(pc, pc);		pc += len;		len = PTRDIFF(done, pc, jsbytecode);		DECOMPILE_CODE(pc, len);		rval = POP_STR();                if (jp->pretty &&                    jp->indent + 4 + strlen(lval) + 4 + strlen(rval) > 75) {                    rval = JS_strdup(cx, rval);                    if (!rval) {                        tail = -1;                    } else {                        todo = Sprint(&ss->sprinter, "%s %s\n", lval, xval);                        tail = Sprint(&ss->sprinter, "%*s%s",                                      jp->indent + 4, "", rval);                        JS_free(cx, (char *)rval);                    }                    if (tail < 0)                        todo = -1;                } else {                    todo = Sprint(&ss->sprinter, "%s %s %s", lval, xval, rval);                }		JS_free(cx, (char *)lval);		break;	      case JSOP_AND:	      case JSOP_ANDX:                xval = "&&";                goto do_logical_connective;	      case JSOP_FORARG:		atom = GetSlotAtom(jp, js_GetArgument, GET_ARGNO(pc));		LOCAL_ASSERT(atom);		lval = ATOM_BYTES(atom);		goto do_fornameinloop;	      case JSOP_FORVAR:		atom = GetSlotAtom(jp, js_GetLocalVariable, GET_VARNO(pc));		LOCAL_ASSERT(atom);		lval = ATOM_BYTES(atom);		goto do_fornameinloop;	      case JSOP_FORNAME:                atom = GET_ATOM(cx, jp->script, pc);		lval = ATOM_BYTES(atom);              do_fornameinloop:		sn = js_GetSrcNote(jp->script, pc);		xval = NULL;		atom = NULL;		goto do_forinloop;	      case JSOP_FORPROP:		xval = NULL;		atom = GET_ATOM(cx, jp->script, pc);		lval = POP_STR();		sn = NULL;	      do_forinloop:		pc += oplen;		LOCAL_ASSERT(*pc == JSOP_IFEQ || *pc == JSOP_IFEQX);		oplen = js_CodeSpec[*pc].length;		len = GetJumpOffset(pc, pc);		sn = js_GetSrcNote(jp->script, pc);                tail = js_GetSrcNoteOffset(sn, 0);              do_forinbody:		js_printf(jp, "\tfor (%s%s", VarPrefix(sn), lval);		if (atom)		    js_printf(jp, ".%s", ATOM_BYTES(atom));		else if (xval)		    js_printf(jp, "[%s]", xval);                rval = OFF2STR(&ss->sprinter, ss->offsets[ss->top-1]);		js_printf(jp, " in %s) {\n", rval);		jp->indent += 4;		DECOMPILE_CODE(pc + oplen, tail - oplen);		jp->indent -= 4;		js_printf(jp, "\t}\n");		todo = -2;		break;              case JSOP_FORELEM:		pc++;		LOCAL_ASSERT(*pc == JSOP_IFEQ || *pc == JSOP_IFEQX);		len = js_CodeSpec[*pc].length;                /*                 * Set tail for use by do_forinbody: code that uses it to find                 * the loop-closing jump (whatever its format, short or long),                 * in order to bound the recursively decompiled loop body.                 */		sn = js_GetSrcNote(jp->script, pc);                tail = js_GetSrcNoteOffset(sn, 0) - oplen;                /*                 * This gets a little wacky.  Only the length of the for loop                 * body PLUS the element-indexing expression is known here, so                 * we pass the after-loop pc to the JSOP_ENUMELEM case, which                 * is immediately below, to decompile that helper bytecode via                 * the 'forelem_done' local.                 */                JS_ASSERT(!forelem_done);		forelem_done = pc + GetJumpOffset(pc, pc);                break;	      case JSOP_ENUMELEM:		/*		 * The stack has the object under the (top) index expression.		 * The "rval" property id is underneath those two on the stack.		 * The for loop body length can now be adjusted to account for		 * the length of the indexing expression.		 */		atom = NULL;		xval = POP_STR();		lval = POP_STR();		rval = OFF2STR(&ss->sprinter, ss->offsets[ss->top-1]);                JS_ASSERT(forelem_done > pc);		len = forelem_done - pc;                forelem_done = NULL;		goto do_forinbody;	      case JSOP_DUP2:		rval = OFF2STR(&ss->sprinter, ss->offsets[ss->top-2]);		todo = SprintPut(&ss->sprinter, rval, strlen(rval));		if (todo < 0 || !PushOff(ss, todo, ss->opcodes[ss->top-2]))		    return JS_FALSE;		/* FALL THROUGH */	      case JSOP_DUP:		rval = OFF2STR(&ss->sprinter, ss->offsets[ss->top-1]);                op = ss->opcodes[ss->top-1];		todo = SprintPut(&ss->sprinter, rval, strlen(rval));		break;	      case JSOP_SETARG:		atom = GetSlotAtom(jp, js_GetArgument, GET_ARGNO(pc));		LOCAL_ASSERT(atom);		goto do_setname;	      case JSOP_SETVAR:		atom = GetSlotAtom(jp, js_GetLocalVariable, GET_VARNO(pc));		LOCAL_ASSERT(atom);		goto do_setname;	      case JSOP_SETCONST:	      case JSOP_SETNAME:		atom = GET_ATOM(cx, jp->script, pc);	      do_setname:		lval = ATOM_BYTES(atom);		rval = POP_STR();		if (op == JSOP_SETNAME)		    (void) PopOff(ss, op);              do_setlval:		if ((sn = js_GetSrcNote(jp->script, pc - 1)) != NULL &&		    SN_TYPE(sn) == SRC_ASSIGNOP) {		    todo = Sprint(&ss->sprinter, "%s %s= %s",				  lval, js_CodeSpec[lastop].token, rval);		} else {		    sn = js_GetSrcNote(jp->script, pc);		    todo = Sprint(&ss->sprinter, "%s%s = %s",				  VarPrefix(sn), lval, rval);		}		break;	      case JSOP_NEW:	      case JSOP_CALL:	      case JSOP_EVAL:#if JS_HAS_LVALUE_RETURN	      case JSOP_SETCALL:#endif		saveop = op;		op = JSOP_NOP;           /* turn off parens */		argc = GET_ARGC(pc);		argv = (char **)                    JS_malloc(cx, (size_t)(argc + 1) * sizeof *argv);		if (!argv)		    return JS_FALSE;		ok = JS_TRUE;		for (i = argc; i > 0; i--) {		    argv[i] = JS_strdup(cx, POP_STR());		    if (!argv[i]) {			ok = JS_FALSE;			break;		    }		}		/* Skip the JSOP_PUSHOBJ-created empty string. */		LOCAL_ASSERT(ss->top >= 2);		(void) PopOff(ss, op);		/* Get the callee's decompiled image in argv[0]. */		argv[0] = JS_strdup(cx, POP_STR());		if (!argv[i])		    ok = JS_FALSE;		lval = "(", rval = ")";		if (saveop == JSOP_NEW) {		    todo = Sprint(&ss->sprinter, "%s %s%s",				  js_new_str, argv[0], lval);		} else {		    todo = Sprint(&ss->sprinter, "%s%s",				  argv[0], lval);		}		if (todo < 0)		    ok = JS_FALSE;		for (i = 1; i <= argc; i++) {		    if (!argv[i] ||			Sprint(&ss->sprinter, "%s%s",			       argv[i], (i < argc) ? ", " : "") < 0) {			ok = JS_FALSE;			break;		    }		}		if (Sprint(&ss->sprinter, rval) < 0)		    ok = JS_FALSE;		for (i = 0; i <= argc; i++) {		    if (argv[i])			JS_free(cx, argv[i]);		}		JS_free(cx, argv);		if (!ok)		    return JS_FALSE;		op = saveop;#if JS_HAS_LVALUE_RETURN                if (op == JSOP_SETCALL) {                    if (!PushOff(ss, todo, op))                        return JS_FALSE;                    todo = Sprint(&ss->sprinter, "");                }#endif		break;	      case JSOP_DELNAME:		atom = GET_ATOM(cx, jp->script, pc);		lval = ATOM_BYTES(atom);		todo = Sprint(&ss->sprinter, "%s %s", js_delete_str, lval);		break;	      case JSOP_DELPROP:		atom = GET_ATOM(cx, jp->script, pc);		lval = POP_STR();		todo = Sprint(&ss->sprinter, "%s %s.%s",			      js_delete_str, lval, ATOM_BYTES(atom));		break;	      case JSOP_DELELEM:		xval = POP_STR();		lval = POP_STR();		todo = Sprint(&ss->sprinter, "%s %s[%s]",			      js_delete_str, lval, xval);		break;	      case JSOP_TYPEOF:	      case JSOP_VOID:		rval = POP_STR();		todo = Sprint(&ss->sprinter, "%s %s", cs->name, rval);		break;	      case JSOP_INCARG:	      case JSOP_DECARG:		atom = GetSlotAtom(jp, js_GetArgument, GET_ARGNO(pc));		LOCAL_ASSERT(atom);		goto do_incatom;	      case JSOP_INCVAR:	      case JSOP_DECVAR:		atom = GetSlotAtom(jp, js_GetLocalVariable, GET_VARNO(pc));		LOCAL_ASSERT(atom);		goto do_incatom;	      case JSOP_INCNAME:	      case JSOP_DECNAME:		atom = GET_ATOM(cx, jp->script, pc);	      do_incatom:		lval = ATOM_BYTES(atom);		todo = Sprint(&ss->sprinter, "%s%s",			      js_incop_str[!(cs->format & JOF_INC)], lval);		break;	      case JSOP_INCPROP:	      case JSOP_DECPROP:		atom = GET_ATOM(cx, jp->script, pc);		lval = POP_STR();		todo = Sprint(&ss->sprinter, "%s%s.%s",			      js_incop_str[!(cs->format & JOF_INC)],			      lval, ATOM_BYTES(atom));		break;	      case JSOP_INCELEM:	      case JSOP_DECELEM:		xval = POP_STR();		lval = POP_STR();		todo = Sprint(&ss->sprinter, "%s%s[%s]",			      js_incop_str[!(cs->format & JOF_INC)],			      lval, xval);		break;	      case JSOP_ARGINC:	      case JSOP_ARGDEC:		atom = GetSlotAtom(jp, js_GetArgument, GET_ARGNO(pc));		LOCAL_ASSERT(atom);		goto do_atominc;	      case JSOP_VARINC:	      case JSOP_VARDEC:		atom = GetSlotAtom(jp, js_GetLocalVariable, GET_VARNO(pc));		LOCAL_ASSERT(atom);		goto do_atominc;	      case JSOP_NAMEINC:	      case JSOP_NAMEDEC:		atom = GET_ATOM(cx, jp->script, pc);	      do_atominc:		lval = ATOM_BYTES(atom);		todo = Sprint(&ss->sprinter, "%s%s",			      lval, js_incop_str[!(cs->format & JOF_INC)]);		break;	      case JSOP_PROPINC:	      case JSOP_PROPDEC:		atom = GET_ATOM(cx, jp->script, pc);		lval = POP_STR();		todo = Sprint(&ss->sprinter, "%s.%s%s",			      lval, ATOM_BYTES(atom),			      js_incop_str[!(cs->format & JOF_INC)]);		break;	      case JSOP_ELEMINC:	      case JSOP_ELEMDEC:		xval = POP_STR();		lval = POP_STR();		todo = Sprint(&ss->sprinter, "%s[%s]%s",			      lval, xval,			      js_incop_str[!(cs->format & JOF_INC)]);		break;	      case JSOP_GETPROP2:		op = JSOP_GETPROP;		(void) PopOff(ss, lastop);		/* FALL THROUGH */	      case JSOP_GETPROP:		atom = GET_ATOM(cx, jp->script, pc);		lval = POP_STR();                str = ATOM_TO_STRING(atom);                if (IsASCIIIdentifier(str)) {                    todo = Sprint(&ss->sprinter, "%s.%s",                                  lval, JS_GetStringBytes(str));                } else {                    lval = JS_strdup(cx, lval);                    if (!lval)                        return JS_FALSE;                    xval = QuoteString(&ss->sprinter, str, (jschar)'\'');                    todo = Sprint(&ss->sprinter, "%s[%s]", lval, xval);                    JS_free(cx, (char *)lval);                }		break;	      case JSOP_SETPROP:		rval = POP_STR();		atom = GET_ATOM(cx, jp->script, pc);		lval = POP_STR();                sn = js_GetSrcNote(jp->script, pc - 1);                str = ATOM_TO_STRING(atom);                if (IsASCIIIdentifier(str)) {                    xval = JS_GetStringBytes(str);                    if (sn && SN_TYPE(sn) == SRC_ASSIGNOP) {                        todo = Sprint(&ss->sprinter, "%s.%s %s= %s",                                      lval, xval,                                      js_CodeSpec[lastop].token, rval);                    } else {                        todo = Sprint(&ss->sprinter, "%s.%s = %s",                                      lval, xval, rval);                    }                } else {                    rval = JS_strdup(cx, rval);                    lval = JS_strdup(cx, lval);                    if (!rval || !lval) {                        JS_free(cx, (char *)rval);                        return JS_FALSE;                    }                    xval = QuoteString(&ss->sprinter, str, (jschar)'\'');                    if (sn && SN_TYPE(sn) == SRC_ASSIGNOP) {                        todo = Sprint(&ss->sprinter, "%s[%s] %s= %s",                                      lval, xval,                                      js_CodeSpec[lastop].token, rval);                    } else {                        todo = Sprint(&ss->sprinter, "%s[%s] = %s",                                      lval, xval, rval);                    }                    JS_free(cx, (char *)rval);                    JS_free(cx, (char *)lval);                }		break;	      case JSOP_GETELEM2:		op = JSOP_GETELEM;		(void) PopOff(ss, lastop);		/* FALL THROUGH */	      case JSOP_GETELEM:		op = JSOP_NOP;           /* turn off parens */		xval = POP_STR();		op = JSOP_GETELEM;		lval = POP_STR();                if (*xval == '\0')                    todo = Sprint(&ss->sprinter, "%s", lval);                else                    todo = Sprint(&ss->sprinter, "%s[%s]", lval, xval);		break;	      case JSOP_SETELEM:		op = JSOP_NOP;           /* turn off parens */		rval = POP_STR();		xval = POP_STR();		op = JSOP_SETELEM;		lval = POP_STR();                if (*xval == '\0')                    goto do_setlval;                if ((sn = js_GetSrcNote(jp->script, pc - 1)) != NULL &&                    SN_TYPE(sn) == SRC_ASSIGNOP) {                    todo = Sprint(&ss->sprinter, "%s[%s] %s= %s",                                  lval, xval,                                  js_CodeSpec[lastop].token, rval);                } else {                    todo = Sprint(&ss->sprinter, "%s[%s] = %s",                                  lval, xval, rval);                }		break;              case JSOP_ARGSUB:                i = (jsint) GET_ATOM_INDEX(pc);                todo = Sprint(&ss->sprinter, "%s[%d]",                              js_arguments_str, (int) i);                break;              case JSOP_ARGCNT:                todo = Sprint(&ss->sprinter, "%s.%s",                              js_arguments_str, js_length_str);                break;	      case JSOP_GETARG:		atom = GetSlotAtom(jp, js_GetArgument, GET_ARGNO(pc));		LOCAL_ASSERT(atom);		goto do_name;	      case JSOP_GETVAR:		atom = GetSlotAtom(jp, js_GetLocalVariable, GET_VARNO(pc));		LOCAL_ASSERT(atom);		goto do_name;	      case JSOP_NAME:		atom = GET_ATOM(cx, jp->script, pc);	      do_name:		sn = js_GetSrcNote(jp->script, pc);		todo = Sprint(&ss->sprinter, "%s%s",			      VarPrefix(sn), ATOM_BYTES(atom));		break;	      case JSOP_UINT16:		i = (jsint) GET_ATOM_INDEX(pc);		todo = Sprint(&ss->sprinter, "%u", (unsigned) i);		break;              case JSOP_NUMBER:                atom = GET_ATOM(cx, jp->script, pc);                key = ATOM_KEY(atom);                if (JSVAL_IS_INT(key)) {                    long ival = (long)JSVAL_TO_INT(key);                    todo = Sprint(&ss->sprinter, "%ld", ival);                } else {                    char buf[DTOSTR_STANDARD_BUFFER_SIZE];                    char *numStr = JS_dtostr(buf, sizeof buf, DTOSTR_STANDARD,                                             0, *JSVAL_TO_DOUBLE(key));                    if (!numStr) {                        JS_ReportOutOfMemory(cx);                        return JS_FALSE;                    }                    todo = Sprint(&ss->sprinter, numStr);                }                break;              case JSOP_STRING:                atom = GET_ATOM(cx, jp->script, pc);                rval = QuoteString(&ss->sprinter, ATOM_TO_STRING(atom),                                   (jschar)'"');                if (!rval)                    return JS_FALSE;                todo = Sprint(&ss->sprinter, "%s", rval);                break;              case JSOP_OBJECT:              case JSOP_ANONFUNOBJ:              case JSOP_NAMEDFUNOBJ:                atom = GET_ATOM(cx, jp->script, pc);                str = js_ValueToSource(cx, ATOM_KEY(atom));                if (!str)                    return JS_FALSE;                todo = SprintPut(&ss->sprinter, JS_GetStringBytes(str),                                 JSSTRING_LENGTH(str));                break;#if JS_HAS_SWITCH_STATEMENT	      case JSOP_TABLESWITCH:	      case JSOP_TABLESWITCHX:	      {		jsbytecode *pc2;		ptrdiff_t off, off2;		jsint j, n, low, high;		TableEntry *table;		sn = js_GetSrcNote(jp->script, pc);		JS_ASSERT(sn && SN_TYPE(sn) == SRC_SWITCH);		len = js_GetSrcNoteOffset(sn, 0);		pc2 = pc;		off = GetJumpOffset(pc, pc2);		pc2 += JUMP_OFFSET_LEN;		low = GetJumpOffset(pc, pc2);		pc2 += JUMP_OFFSET_LEN;		high = GetJumpOffset(pc, pc2);		n = high - low + 1;                if (n == 0) {                    table = NULL;		    j = 0;                } else {                    table = (TableEntry *)                            JS_malloc(cx, (size_t)n * sizeof *table);                    if (!table)                        return JS_FALSE;		    for (i = j = 0; i < n; i++) {			pc2 += JUMP_OFFSET_LEN;			off2 = GetJumpOffset(pc, pc2);			if (off2) {			    table[j].key = INT_TO_JSVAL(low + i);			    table[j++].offset = off2;			}		    }                    js_HeapSort(table, (size_t) j, sizeof *table,                                CompareOffsets, NULL);		}		ok = DecompileSwitch(ss, table, (uintN)j, pc, len, off,				     JS_FALSE);		JS_free(cx, table);		if (!ok)		    return ok;		todo = -2;		break;	      }	      case JSOP_LOOKUPSWITCH:	      case JSOP_LOOKUPSWITCHX:	      {		jsbytecode *pc2;		ptrdiff_t off, off2;		jsint npairs;		TableEntry *table;		sn = js_GetSrcNote(jp->script, pc);		JS_ASSERT(sn && SN_TYPE(sn) == SRC_SWITCH);		len = js_GetSrcNoteOffset(sn, 0);		pc2 = pc;		off = GetJumpOffset(pc, pc2);		pc2 += JUMP_OFFSET_LEN;		npairs = (jsint) GET_ATOM_INDEX(pc2);		pc2 += ATOM_INDEX_LEN;		table = (TableEntry *)                    JS_malloc(cx, (size_t)npairs * sizeof *table);		if (!table)		    return JS_FALSE;		for (i = 0; i < npairs; i++) {		    atom = GET_ATOM(cx, jp->script, pc2);		    pc2 += ATOM_INDEX_LEN;		    off2 = GetJumpOffset(pc, pc2);		    pc2 += JUMP_OFFSET_LEN;		    table[i].key = ATOM_KEY(atom);		    table[i].offset = off2;		}		ok = DecompileSwitch(ss, table, (uintN)npairs, pc, len, off,				     JS_FALSE);		JS_free(cx, table);		if (!ok)		    return ok;		todo = -2;		break;	      }	      case JSOP_CONDSWITCH:	      {		jsbytecode *pc2;		ptrdiff_t off, off2, caseOff;		jsint ncases;		TableEntry *table;		sn = js_GetSrcNote(jp->script, pc);		JS_ASSERT(sn && SN_TYPE(sn) == SRC_SWITCH);		len = js_GetSrcNoteOffset(sn, 0);		off = js_GetSrcNoteOffset(sn, 1);		/*		 * Count the cases using offsets from switch to first case,		 * and case to case, stored in srcnote immediates.		 */		pc2 = pc;		off2 = off;		for (ncases = 0; off2 != 0; ncases++) {		    pc2 += off2;		    JS_ASSERT(*pc2 == JSOP_CASE || *pc2 == JSOP_DEFAULT ||                              *pc2 == JSOP_CASEX || *pc2 == JSOP_DEFAULTX);		    if (*pc2 == JSOP_DEFAULT || *pc2 == JSOP_DEFAULTX) {			/* End of cases, but count default as a case. */			off2 = 0;		    } else {			sn = js_GetSrcNote(jp->script, pc2);			JS_ASSERT(sn && SN_TYPE(sn) == SRC_PCDELTA);			off2 = js_GetSrcNoteOffset(sn, 0);		    }		}		/*		 * Allocate table and rescan the cases using their srcnotes,		 * stashing each case's delta from switch top in table[i].key,		 * and the distance to its statements in table[i].offset.		 */		table = (TableEntry *)                    JS_malloc(cx, (size_t)ncases * sizeof *table);		if (!table)		    return JS_FALSE;		pc2 = pc;		off2 = off;		for (i = 0; i < ncases; i++) {		    pc2 += off2;		    JS_ASSERT(*pc2 == JSOP_CASE || *pc2 == JSOP_DEFAULT ||                              *pc2 == JSOP_CASEX || *pc2 == JSOP_DEFAULTX);		    caseOff = pc2 - pc;		    table[i].key = INT_TO_JSVAL((jsint) caseOff);		    table[i].offset = caseOff + GetJumpOffset(pc2, pc2);		    if (*pc2 == JSOP_CASE || *pc2 == JSOP_CASEX) {			sn = js_GetSrcNote(jp->script, pc2);			JS_ASSERT(sn && SN_TYPE(sn) == SRC_PCDELTA);			off2 = js_GetSrcNoteOffset(sn, 0);		    }		}		/*		 * Find offset of default code by fetching the default offset		 * from the end of table.  JSOP_CONDSWITCH always has a default		 * case at the end.		 */		off = JSVAL_TO_INT(table[ncases-1].key);		pc2 = pc + off;		off += GetJumpOffset(pc2, pc2);		ok = DecompileSwitch(ss, table, (uintN)ncases, pc, len, off,				     JS_TRUE);		JS_free(cx, table);		if (!ok)		    return ok;		todo = -2;		break;	      }	      case JSOP_CASE:	      case JSOP_CASEX:	      {		lval = POP_STR();		if (!lval)		    return JS_FALSE;		js_printf(jp, "\tcase %s:\n", lval);		todo = -2;		break;	      }#endif /* JS_HAS_SWITCH_STATEMENT */#if !JS_BUG_FALLIBLE_EQOPS	      case JSOP_NEW_EQ:	      case JSOP_NEW_NE:		rval = POP_STR();		lval = POP_STR();		todo = Sprint(&ss->sprinter, "%s %c%s %s",			      lval,			      (op == JSOP_NEW_EQ) ? '=' : '!',#if JS_HAS_TRIPLE_EQOPS			      JSVERSION_IS_ECMA(cx->version) ? "==" :#endif			      "=",			      rval);		break;#endif /* !JS_BUG_FALLIBLE_EQOPS */#if JS_HAS_LEXICAL_CLOSURE	      case JSOP_CLOSURE:		atom = GET_ATOM(cx, jp->script, pc);		JS_ASSERT(ATOM_IS_OBJECT(atom));                goto do_function;#endif /* JS_HAS_LEXICAL_CLOSURE */#if JS_HAS_EXPORT_IMPORT	      case JSOP_EXPORTALL:		js_printf(jp, "\texport *\n");		todo = -2;		break;	      case JSOP_EXPORTNAME:		atom = GET_ATOM(cx, jp->script, pc);		js_printf(jp, "\texport %s\n", ATOM_BYTES(atom));		todo = -2;		break;	      case JSOP_IMPORTALL:		lval = POP_STR();		js_printf(jp, "\timport %s.*\n", lval);		todo = -2;		break;	      case JSOP_IMPORTPROP:		atom = GET_ATOM(cx, jp->script, pc);		lval = POP_STR();		js_printf(jp, "\timport %s.%s\n", lval, ATOM_BYTES(atom));		todo = -2;		break;	      case JSOP_IMPORTELEM:		xval = POP_STR();		op = JSOP_GETELEM;		lval = POP_STR();		js_printf(jp, "\timport %s[%s]\n", lval, xval);		todo = -2;		break;#endif /* JS_HAS_EXPORT_IMPORT */	      case JSOP_TRAP:		op = JS_GetTrapOpcode(cx, jp->script, pc);		if (op == JSOP_LIMIT)		    return JS_FALSE;		*pc = op;		cs = &js_CodeSpec[op];		len = cs->length;		DECOMPILE_CODE(pc, len);		*pc = JSOP_TRAP;		todo = -2;		break;#if JS_HAS_INITIALIZERS	      case JSOP_NEWINIT:		LOCAL_ASSERT(ss->top >= 2);		(void) PopOff(ss, op);		lval = POP_STR();#if JS_HAS_SHARP_VARS		op = (JSOp)pc[len];		if (op == JSOP_DEFSHARP) {		    pc += len;		    cs = &js_CodeSpec[op];		    len = cs->length;		    i = (jsint) GET_ATOM_INDEX(pc);		    todo = Sprint(&ss->sprinter, "#%u=%c",				  (unsigned) i,				  (*lval == 'O') ? '{' : '[');		} else#endif /* JS_HAS_SHARP_VARS */		{		    todo = Sprint(&ss->sprinter, (*lval == 'O') ? "{" : "[");		}		break;	      case JSOP_ENDINIT:		rval = POP_STR();		sn = js_GetSrcNote(jp->script, pc);		todo = Sprint(&ss->sprinter, "%s%s%c",			      rval,			      (sn && SN_TYPE(sn) == SRC_CONTINUE) ? ", " : "",			      (*rval == '{') ? '}' : ']');		break;	      case JSOP_INITPROP:              case JSOP_INITCATCHVAR:		rval = POP_STR();		atom = GET_ATOM(cx, jp->script, pc);		xval = ATOM_BYTES(atom);		lval = POP_STR();	      do_initprop:#ifdef OLD_GETTER_SETTER                todo = Sprint(&ss->sprinter, "%s%s%s%s%s:%s",                              lval,                              (lval[1] != '\0') ? ", " : "",                              xval,                              (lastop == JSOP_GETTER || lastop == JSOP_SETTER)                              ? " " : "",                              (lastop == JSOP_GETTER) ? js_getter_str :                              (lastop == JSOP_SETTER) ? js_setter_str :                              "",                              rval);#else                if (lastop == JSOP_GETTER || lastop == JSOP_SETTER) {                    todo = Sprint(&ss->sprinter, "%s%s%s %s%s",                              lval,                              (lval[1] != '\0') ? ", " : "",                              (lastop == JSOP_GETTER)                              ? js_get_str : js_set_str,                              xval,                              rval + strlen(js_function_str) + 1);                } else {                    todo = Sprint(&ss->sprinter, "%s%s%s:%s",                              lval,                              (lval[1] != '\0') ? ", " : "",                              xval,                              rval);                }#endif		break;	      case JSOP_INITELEM:		rval = POP_STR();		xval = POP_STR();		lval = POP_STR();		sn = js_GetSrcNote(jp->script, pc);		if (sn && SN_TYPE(sn) == SRC_LABEL)		    goto do_initprop;		todo = Sprint(&ss->sprinter, "%s%s%s",			      lval,			      (lval[1] != '\0' || *xval != '0') ? ", " : "",			      rval);		break;#if JS_HAS_SHARP_VARS	      case JSOP_DEFSHARP:		i = (jsint) GET_ATOM_INDEX(pc);		rval = POP_STR();		todo = Sprint(&ss->sprinter, "#%u=%s", (unsigned) i, rval);		break;	      case JSOP_USESHARP:		i = (jsint) GET_ATOM_INDEX(pc);		todo = Sprint(&ss->sprinter, "#%u#", (unsigned) i);		break;#endif /* JS_HAS_SHARP_VARS */#endif /* JS_HAS_INITIALIZERS */#if JS_HAS_DEBUGGER_KEYWORD	      case JSOP_DEBUGGER:		js_printf(jp, "\tdebugger;\n");		todo = -2;		break;#endif /* JS_HAS_DEBUGGER_KEYWORD */	      default:		todo = -2;		break;	    }	}	if (todo < 0) {	    /* -2 means "don't push", -1 means reported error. */	    if (todo == -1)		return JS_FALSE;	} else {	    if (!PushOff(ss, todo, op))		return JS_FALSE;	}	pc += len;    }/* * Undefine local macros. */#undef DECOMPILE_CODE#undef POP_STR#undef LOCAL_ASSERT    return JS_TRUE;}