if (!js_SetSrcNoteOffset(cx, cg, noteIndex, 0, off))
if (!js_SetSrcNoteOffset(cx, cg, (uintN)noteIndex, 0, off))
js_EmitTree(JSContext *cx, JSCodeGenerator *cg, JSParseNode *pn){    JSBool ok;    JSCodeGenerator cg2;    JSStmtInfo *stmt, stmtInfo;    ptrdiff_t top, off, tmp, beq, jmp;    JSParseNode *pn2, *pn3, *pn4;    JSAtom *atom;    JSAtomListElement *ale;    jsatomid atomIndex;    intN noteIndex;    JSOp op;    uint32 argc;    pn->pn_offset = top = CG_OFFSET(cg);    /* Emit notes to tell the current bytecode's source line number. */    UPDATE_LINENO_NOTES(cx, cg, pn);    switch (pn->pn_type) {      case TOK_FUNCTION:      {	JSFunction *fun;	/* Fold constants and generate code for the function's body. */	pn2 = pn->pn_body;	if (!js_FoldConstants(cx, pn2))	    return JS_FALSE;	if (!js_InitCodeGenerator(cx, &cg2, cg->filename,				  pn->pn_pos.begin.lineno,				  cg->principals)) {	    return JS_FALSE;	}	cg2.treeContext.tryCount = pn->pn_tryCount;	fun = pn->pn_fun;	if (!js_EmitFunctionBody(cx, &cg2, pn2, fun))	    return JS_FALSE;	js_FinishCodeGenerator(cx, &cg2);	/* Make the function object a literal in the outer script's pool. */	atom = js_AtomizeObject(cx, fun->object, 0);	if (!atom)	    return JS_FALSE;	ale = js_IndexAtom(cx, atom, &cg->atomList);	if (!ale)	    return JS_FALSE;	/* Emit a bytecode or srcnote naming the literal in its immediate. */#if JS_HAS_LEXICAL_CLOSURE	if (pn->pn_op != JSOP_NOP) {	    EMIT_ATOM_INDEX_OP(pn->pn_op, ale->index);	    break;	}#endif	noteIndex = js_NewSrcNote2(cx, cg, SRC_FUNCDEF, (ptrdiff_t)ale->index);	if (noteIndex < 0 ||	    js_Emit1(cx, cg, JSOP_NOP) < 0) {	    return JS_FALSE;	}	break;      }#if JS_HAS_EXPORT_IMPORT      case TOK_EXPORT:	pn2 = pn->pn_head;	if (pn2->pn_type == TOK_STAR) {	    /*	     * 'export *' must have no other elements in the list (what would	     * be the point?).	     */	    if (js_Emit1(cx, cg, JSOP_EXPORTALL) < 0)		return JS_FALSE;	} else {	    /*	     * If not 'export *', the list consists of NAME nodes identifying	     * properties of the variable object to flag as exported.	     */	    do {		ale = js_IndexAtom(cx, pn2->pn_atom, &cg->atomList);		if (!ale)		    return JS_FALSE;		EMIT_ATOM_INDEX_OP(JSOP_EXPORTNAME, ale->index);	    } while ((pn2 = pn2->pn_next) != NULL);	}	break;      case TOK_IMPORT:	for (pn2 = pn->pn_head; pn2; pn2 = pn2->pn_next) {	    /*	     * Each subtree on an import list is rooted by a DOT or LB node.	     * A DOT may have a null pn_atom member, in which case pn_op must	     * be JSOP_IMPORTALL -- see EmitPropOp above.	     */	    if (!js_EmitTree(cx, cg, pn2))		return JS_FALSE;	}	break;#endif /* JS_HAS_EXPORT_IMPORT */      case TOK_IF:	/* Emit code for the condition before pushing stmtInfo. */	if (!js_EmitTree(cx, cg, pn->pn_kid1))	    return JS_FALSE;	js_PushStatement(&cg->treeContext, &stmtInfo, STMT_IF, CG_OFFSET(cg));	/* Emit an annotated branch-if-false around the then part. */	noteIndex = js_NewSrcNote(cx, cg, SRC_IF);	if (noteIndex < 0)	    return JS_FALSE;	beq = js_Emit3(cx, cg, JSOP_IFEQ, 0, 0);	if (beq < 0)	    return JS_FALSE;	/* Emit code for the then and optional else parts. */	if (!js_EmitTree(cx, cg, pn->pn_kid2))	    return JS_FALSE;	pn3 = pn->pn_kid3;	if (pn3) {	    /* Modify stmtInfo and the branch-if-false source note. */	    stmtInfo.type = STMT_ELSE;	    SN_SET_TYPE(&cg->notes[noteIndex], SRC_IF_ELSE);	    /* Jump at end of then part around the else part. */	    jmp = js_Emit3(cx, cg, JSOP_GOTO, 0, 0);	    if (jmp < 0)		return JS_FALSE;	    /* Ensure the branch-if-false comes here, then emit the else. */	    CHECK_AND_SET_JUMP_OFFSET_AT(cx, cg, beq);	    if (!js_EmitTree(cx, cg, pn3))		return JS_FALSE;	    /* Fixup the jump around the else part. */	    CHECK_AND_SET_JUMP_OFFSET_AT(cx, cg, jmp);	} else {	    /* No else part, fixup the branch-if-false to come here. */	    CHECK_AND_SET_JUMP_OFFSET_AT(cx, cg, beq);	}	return js_PopStatementCG(cx, cg);#if JS_HAS_SWITCH_STATEMENT      case TOK_SWITCH:      {	JSOp switchop;	uint32 ncases, tablen = 0;	JSScript *script;	jsint i, low, high;	jsdouble d;	size_t switchsize, tablesize;	void *mark;	JSParseNode **table;	jsbytecode *pc;	JSBool hasDefault = JS_FALSE;	JSBool isEcmaSwitch = cx->version == JSVERSION_DEFAULT ||			      cx->version >= JSVERSION_1_4;	ptrdiff_t defaultOffset = -1;	/* Try for most optimal, fall back if not dense ints, and per ECMAv2. */	switchop = JSOP_TABLESWITCH;	/* Emit code for the discriminant first. */	if (!js_EmitTree(cx, cg, pn->pn_kid1))	    return JS_FALSE;	/* Switch bytecodes run from here till end of final case. */	top = CG_OFFSET(cg);	js_PushStatement(&cg->treeContext, &stmtInfo, STMT_SWITCH, top);	pn2 = pn->pn_kid2;	ncases = pn2->pn_count;	if (pn2->pn_count == 0) {	    low = high = 0;	    tablen = 0;	    ok = JS_TRUE;	} else {	    low  = JSVAL_INT_MAX;	    high = JSVAL_INT_MIN;	    cg2.base = NULL;	    for (pn3 = pn2->pn_head; pn3; pn3 = pn3->pn_next) {		if (pn3->pn_type == TOK_DEFAULT) {		    hasDefault = JS_TRUE;		    ncases--;   /* one of the "cases" was the default */		    continue;		}		JS_ASSERT(pn3->pn_type == TOK_CASE);		pn4 = pn3->pn_left;		if (isEcmaSwitch) {		    if (switchop == JSOP_CONDSWITCH)			continue;		    switch (pn4->pn_type) {		      case TOK_NUMBER:			d = pn4->pn_dval;			if (JSDOUBLE_IS_INT(d, i) && INT_FITS_IN_JSVAL(i)) {			    pn3->pn_val = INT_TO_JSVAL(i);			} else {			    atom = js_AtomizeDouble(cx, d, 0);			    if (!atom)				return JS_FALSE;			    pn3->pn_val = ATOM_KEY(atom);			}			break;		      case TOK_STRING:			pn3->pn_val = ATOM_KEY(pn4->pn_atom);			break;		      case TOK_PRIMARY:			if (pn4->pn_op == JSOP_TRUE) {			    pn3->pn_val = JSVAL_TRUE;			    break;			}			if (pn4->pn_op == JSOP_FALSE) {			    pn3->pn_val = JSVAL_FALSE;			    break;			}			/* FALL THROUGH */		      default:			switchop = JSOP_CONDSWITCH;			continue;		    }		} else {		    /* Pre-ECMAv2 switch evals case exprs at compile time. */		    if (!js_InitCodeGenerator(cx, &cg2, cg->filename,					      pn3->pn_pos.begin.lineno,					      cg->principals)) {			return JS_FALSE;		    }		    cg2.currentLine = pn4->pn_pos.begin.lineno;		    if (!js_EmitTree(cx, &cg2, pn4))			return JS_FALSE;		    if (js_Emit1(cx, &cg2, JSOP_POPV) < 0)			return JS_FALSE;		    script = js_NewScriptFromCG(cx, &cg2, NULL);		    if (!script)			return JS_FALSE;		    ok = js_Execute(cx, cx->fp->scopeChain, script, NULL,				    cx->fp, JS_FALSE, &pn3->pn_val);		    js_DestroyScript(cx, script);		    if (!ok)			return JS_FALSE;		}		if (!JSVAL_IS_NUMBER(pn3->pn_val) &&		    !JSVAL_IS_STRING(pn3->pn_val) &&		    !JSVAL_IS_BOOLEAN(pn3->pn_val)) {		    char numBuf[12];		    JS_snprintf(numBuf, sizeof numBuf, "%u",		    		pn4->pn_pos.begin.lineno);		    JS_ReportErrorNumber(cx, js_GetErrorMessage, NULL,					 JSMSG_BAD_CASE,					 cg2.filename ? cg2.filename : "stdin",					 numBuf);		    return JS_FALSE;		}		if (switchop != JSOP_TABLESWITCH)		    continue;		if (!JSVAL_IS_INT(pn3->pn_val)) {		    switchop = JSOP_LOOKUPSWITCH;		    continue;		}		i = JSVAL_TO_INT(pn3->pn_val);		if ((jsuint)(i + (jsint)JS_BIT(15)) >= (jsuint)JS_BIT(16)) {		    switchop = JSOP_LOOKUPSWITCH;		    continue;		}		if (i < low)		    low = i;		if (high < i)		    high = i;	    }	    if (switchop == JSOP_CONDSWITCH) {		JS_ASSERT(!cg2.base);	    } else {		if (cg2.base)		    js_FinishCodeGenerator(cx, &cg2);		if (switchop == JSOP_TABLESWITCH) {		    tablen = (uint32)(high - low + 1);		    if (tablen >= JS_BIT(16) || tablen > 2 * ncases)			switchop = JSOP_LOOKUPSWITCH;		}	    }	}	/*	 * Emit a note with two offsets: first tells total switch code length,	 * second tells offset to first JSOP_CASE if condswitch.	 */	noteIndex = js_NewSrcNote3(cx, cg, SRC_SWITCH, 0, 0);	if (noteIndex < 0)	    return JS_FALSE;	if (switchop == JSOP_CONDSWITCH) {	    /*	     * 0 bytes of immediate for unoptimized ECMAv2 switch.	     */	    switchsize = 0;	} else if (switchop == JSOP_TABLESWITCH) {	    /*	     * 3 offsets (len, low, high) before the table, 1 per entry.	     */	    switchsize = (size_t)(6 + 2 * tablen);	} else {	    /*	     * JSOP_LOOKUPSWITCH:	     * 1 offset (len) and 1 atom index (npairs) before the table,	     * 1 atom index and 1 jump offset per entry.	     */	    switchsize = (size_t)(4 + 4 * ncases);	}	/* Emit switchop and switchsize bytes of jump or lookup table. */	if (js_EmitN(cx, cg, switchop, switchsize) < 0)	    return JS_FALSE;        off = -1;	if (switchop == JSOP_CONDSWITCH) {	    intN caseNoteIndex = -1;	    /* Emit code for evaluating cases and jumping to case statements. */	    for (pn3 = pn2->pn_head; pn3; pn3 = pn3->pn_next) {		pn4 = pn3->pn_left;		if (pn4 && !js_EmitTree(cx, cg, pn4))		    return JS_FALSE;		if (caseNoteIndex >= 0) {		    /* off is the previous JSOP_CASE's bytecode offset. */		    if (!js_SetSrcNoteOffset(cx, cg, caseNoteIndex, 0,					     CG_OFFSET(cg) - off)) {			return JS_FALSE;		    }		}		if (pn3->pn_type == TOK_DEFAULT)		    continue;		caseNoteIndex = js_NewSrcNote2(cx, cg, SRC_PCDELTA, 0);		if (caseNoteIndex < 0)		    return JS_FALSE;		off = js_Emit3(cx, cg, JSOP_CASE, 0, 0);		if (off < 0)		    return JS_FALSE;		pn3->pn_offset = off;		if (pn3 == pn2->pn_head) {		    /* Switch note's second offset is to first JSOP_CASE. */		    if (!js_SetSrcNoteOffset(cx, cg, noteIndex, 1, off - top))			return JS_FALSE;		}	    }	    /* Emit default even if no explicit default statement. */	    defaultOffset = js_Emit3(cx, cg, JSOP_DEFAULT, 0, 0);	    if (defaultOffset < 0)		return JS_FALSE;	}	/* Emit code for each case's statements, copying pn_offset up to pn3. */	for (pn3 = pn2->pn_head; pn3; pn3 = pn3->pn_next) {	    if (switchop == JSOP_CONDSWITCH && pn3->pn_type != TOK_DEFAULT) {		pn3->pn_val = INT_TO_JSVAL(pn3->pn_offset - top);		CHECK_AND_SET_JUMP_OFFSET_AT(cx, cg, pn3->pn_offset);	    }	    pn4 = pn3->pn_right;	    if (!js_EmitTree(cx, cg, pn4))		return JS_FALSE;	    pn3->pn_offset = pn4->pn_offset;	    if (pn3->pn_type == TOK_DEFAULT)		off = pn3->pn_offset - top;	}	if (!hasDefault) {	    /* If no default case, offset for default is to end of switch. */	    off = CG_OFFSET(cg) - top;	}        /* We better have set "off" by now. */        JS_ASSERT(off != -1);	/* Set the default offset (to end of switch if no default). */        pc = NULL;	if (switchop == JSOP_CONDSWITCH) {	    JS_ASSERT(defaultOffset != -1);	    if (!js_SetJumpOffset(cx, cg, CG_CODE(cg, defaultOffset),				  off - (defaultOffset - top))) {		return JS_FALSE;	    }	} else {	    pc = CG_CODE(cg, top);	    if (!js_SetJumpOffset(cx, cg, pc, off))		return JS_FALSE;	    pc += 2;	}	/* Set the SRC_SWITCH note's offset operand to tell end of switch. */	off = CG_OFFSET(cg) - top;	if (!js_SetSrcNoteOffset(cx, cg, noteIndex, 0, off))	    return JS_FALSE;	if (switchop == JSOP_TABLESWITCH) {	    /* Fill in jump table. */	    if (!js_SetJumpOffset(cx, cg, pc, low))		return JS_FALSE;	    pc += 2;	    if (!js_SetJumpOffset(cx, cg, pc, high))		return JS_FALSE;	    pc += 2;	    if (tablen) {		/* Avoid bloat for a compilation unit with many switches. */		mark = JS_ARENA_MARK(&cx->tempPool);		tablesize = (size_t)tablen * sizeof *table;		JS_ARENA_ALLOCATE(table, &cx->tempPool, tablesize);		if (!table) {		    JS_ReportOutOfMemory(cx);		    return JS_FALSE;		}		memset(table, 0, tablesize);		for (pn3 = pn2->pn_head; pn3; pn3 = pn3->pn_next) {		    if (pn3->pn_type == TOK_DEFAULT)			continue;		    i = JSVAL_TO_INT(pn3->pn_val);		    i -= low;		    JS_ASSERT((uint32)i < tablen);		    table[i] = pn3;		}		for (i = 0; i < (jsint)tablen; i++) {		    pn3 = table[i];		    off = pn3 ? pn3->pn_offset - top : 0;		    if (!js_SetJumpOffset(cx, cg, pc, off))			return JS_FALSE;		    pc += 2;		}		JS_ARENA_RELEASE(&cx->tempPool, mark);	    }	} else if (switchop == JSOP_LOOKUPSWITCH) {	    /* Fill in lookup table. */	    SET_ATOM_INDEX(pc, ncases);	    pc += 2;	    for (pn3 = pn2->pn_head; pn3; pn3 = pn3->pn_next) {		if (pn3->pn_type == TOK_DEFAULT)		    continue;		atom = js_AtomizeValue(cx, pn3->pn_val, 0);		if (!atom)		    return JS_FALSE;		ale = js_IndexAtom(cx, atom, &cg->atomList);		if (!ale)		    return JS_FALSE;		SET_ATOM_INDEX(pc, ale->index);		pc += 2;		off = pn3->pn_offset - top;		if (!js_SetJumpOffset(cx, cg, pc, off))		    return JS_FALSE;		pc += 2;	    }	}	return js_PopStatementCG(cx, cg);      }#endif /* JS_HAS_SWITCH_STATEMENT */      case TOK_WHILE:	js_PushStatement(&cg->treeContext, &stmtInfo, STMT_WHILE_LOOP, top);	if (!js_EmitTree(cx, cg, pn->pn_left))	    return JS_FALSE;	noteIndex = js_NewSrcNote(cx, cg, SRC_WHILE);	if (noteIndex < 0)	    return JS_FALSE;	beq = js_Emit3(cx, cg, JSOP_IFEQ, 0, 0);	if (beq < 0)	    return JS_FALSE;	if (!js_EmitTree(cx, cg, pn->pn_right))	    return JS_FALSE;	jmp = js_Emit3(cx, cg, JSOP_GOTO, 0, 0);	if (jmp < 0)	    return JS_FALSE;	CHECK_AND_SET_JUMP_OFFSET(cx, cg, CG_CODE(cg,jmp), top - jmp);	CHECK_AND_SET_JUMP_OFFSET_AT(cx, cg, beq);	return js_PopStatementCG(cx, cg);#if JS_HAS_DO_WHILE_LOOP      case TOK_DO:	/* Emit an annotated nop so we know to decompile a 'do' keyword. */	if (js_NewSrcNote(cx, cg, SRC_WHILE) < 0 ||	    js_Emit1(cx, cg, JSOP_NOP) < 0) {	    return JS_FALSE;	}	/* Compile the loop body. */	top = CG_OFFSET(cg);	js_PushStatement(&cg->treeContext, &stmtInfo, STMT_DO_LOOP, top);	if (!js_EmitTree(cx, cg, pn->pn_left))	    return JS_FALSE;	/* Set loop and enclosing label update offsets, for continue. */	stmt = &stmtInfo;	do {	    stmt->update = CG_OFFSET(cg);	} while ((stmt = stmt->down) != NULL && stmt->type == STMT_LABEL);	/* Compile the loop condition, now that continues know where to go. */	if (!js_EmitTree(cx, cg, pn->pn_right))	    return JS_FALSE;	/* Re-use the SRC_WHILE note, this time for the JSOP_IFNE opcode. */	if (js_NewSrcNote(cx, cg, SRC_WHILE) < 0)	    return JS_FALSE;	jmp = top - CG_OFFSET(cg);	if (js_Emit3(cx, cg, JSOP_IFNE,		     JUMP_OFFSET_HI(jmp), JUMP_OFFSET_LO(jmp)) < 0) {	    return JS_FALSE;	}	return js_PopStatementCG(cx, cg);#endif /* JS_HAS_DO_WHILE_LOOP */      case TOK_FOR:	pn2 = pn->pn_left;	js_PushStatement(&cg->treeContext, &stmtInfo, STMT_FOR_LOOP, top);	if (pn2->pn_type == TOK_IN) {	    /* If the left part is var x = i, bind x, evaluate i, and pop. */	    pn3 = pn2->pn_left;	    if (pn3->pn_type == TOK_VAR && pn3->pn_head->pn_expr) {		if (!js_EmitTree(cx, cg, pn3))		    return JS_FALSE;		/* Set pn3 to the variable name, to avoid another var note. */		pn3 = pn3->pn_head;		JS_ASSERT(pn3->pn_type == TOK_NAME);	    }	    /* Fix stmtInfo and emit a push to allocate the iterator. */	    stmtInfo.type = STMT_FOR_IN_LOOP;	    noteIndex = -1;	    if (js_Emit1(cx, cg, JSOP_PUSH) < 0)		return JS_FALSE;	    /* Compile the object expression to the right of 'in'. */	    if (!js_EmitTree(cx, cg, pn2->pn_right))		return JS_FALSE;	    if (js_Emit1(cx, cg, JSOP_TOOBJECT) < 0)		return JS_FALSE;	    top = CG_OFFSET(cg);	    SET_STATEMENT_TOP(&stmtInfo, top);	    /* Compile a JSOP_FOR*2 bytecode based on the left hand side. */	    switch (pn3->pn_type) {	      case TOK_VAR:		pn3 = pn3->pn_head;		if (js_NewSrcNote(cx, cg, SRC_VAR) < 0)		    return JS_FALSE;		/* FALL THROUGH */	      case TOK_NAME:		if (!EmitAtomOp(cx, pn3, JSOP_FORNAME2, cg))		    return JS_FALSE;		break;	      case TOK_DOT:		if (!EmitPropOp(cx, pn3, JSOP_FORPROP2, cg))		    return JS_FALSE;		break;	      case TOK_LB:                /*                 * We separate the first/next bytecode from the enumerator		 * variable binding to avoid any side-effects in the index                 * expression (e.g., for (x[i++] in {}) should not bind x[i]		 * or increment i at all).                 */                if (!js_Emit1(cx, cg, JSOP_FORELEM2))                    return JS_FALSE;	        beq = js_Emit3(cx, cg, JSOP_IFEQ, 0, 0);	        if (beq < 0)		    return JS_FALSE;		if (!EmitElemOp(cx, pn3, JSOP_ENUMELEM, cg))		    return JS_FALSE;		break;	      default:		JS_ASSERT(0);	    }            if (pn3->pn_type != TOK_LB) {	        /* Pop and test the loop condition generated by JSOP_FOR*2. */	        beq = js_Emit3(cx, cg, JSOP_IFEQ, 0, 0);	        if (beq < 0)		    return JS_FALSE;            }	} else {	    if (!pn2->pn_kid1) {		/* No initializer: emit an annotated nop for the decompiler. */		noteIndex = js_NewSrcNote(cx, cg, SRC_FOR);		if (noteIndex < 0 ||		    js_Emit1(cx, cg, JSOP_NOP) < 0) {		    return JS_FALSE;		}	    } else {		if (!js_EmitTree(cx, cg, pn2->pn_kid1))		    return JS_FALSE;		noteIndex = js_NewSrcNote(cx, cg, SRC_FOR);		if (noteIndex < 0 ||		    js_Emit1(cx, cg, JSOP_POP) < 0) {		    return JS_FALSE;		}	    }	    top = CG_OFFSET(cg);	    SET_STATEMENT_TOP(&stmtInfo, top);	    if (!pn2->pn_kid2) {		/* No loop condition: flag this fact in the source notes. */		if (!js_SetSrcNoteOffset(cx, cg, noteIndex, 0, 0))		    return JS_FALSE;		beq = 0;	    } else {		if (!js_EmitTree(cx, cg, pn2->pn_kid2))		    return JS_FALSE;		if (!js_SetSrcNoteOffset(cx, cg, noteIndex, 0,					 (ptrdiff_t)(CG_OFFSET(cg) - top))) {		    return JS_FALSE;		}		beq = js_Emit3(cx, cg, JSOP_IFEQ, 0, 0);		if (beq < 0)		    return JS_FALSE;	    }	}	/* Emit code for the loop body. */	if (!js_EmitTree(cx, cg, pn->pn_right))	    return JS_FALSE;	if (pn2->pn_type != TOK_IN) {	    /* Set the second note offset so we can find the update part. */	    JS_ASSERT(noteIndex != -1);	    if (!js_SetSrcNoteOffset(cx, cg, noteIndex, 1,				     (ptrdiff_t)(CG_OFFSET(cg) - top))) {		return JS_FALSE;	    }	    pn3 = pn2->pn_kid3;	    if (pn3) {		/* Set loop and enclosing "update" offsets, for continue. */		stmt = &stmtInfo;		do {		    stmt->update = CG_OFFSET(cg);		} while ((stmt = stmt->down) != NULL &&			 stmt->type == STMT_LABEL);		if (!js_EmitTree(cx, cg, pn3))		    return JS_FALSE;		if (js_Emit1(cx, cg, JSOP_POP) < 0)		    return JS_FALSE;		/* Restore the absolute line number for source note readers. */		off = (ptrdiff_t) pn->pn_pos.end.lineno;		if (cg->currentLine != (uintN) off) {		    if (js_NewSrcNote2(cx, cg, SRC_SETLINE, off) < 0)			return JS_FALSE;		    cg->currentLine = (uintN) off;		}	    }	    /* The third note offset helps us find the loop-closing jump. */	    if (!js_SetSrcNoteOffset(cx, cg, noteIndex, 2,				     (ptrdiff_t)(CG_OFFSET(cg) - top))) {		return JS_FALSE;	    }	}	/* Emit the loop-closing jump and fixup all jump offsets. */	jmp = js_Emit3(cx, cg, JSOP_GOTO, 0, 0);	if (jmp < 0)	    return JS_FALSE;	CHECK_AND_SET_JUMP_OFFSET(cx, cg, CG_CODE(cg,jmp), top - jmp);	if (beq > 0)	    CHECK_AND_SET_JUMP_OFFSET_AT(cx, cg, beq);	/* Now fixup all breaks and continues (before for/in's final POP2). */	if (!js_PopStatementCG(cx, cg))	    return JS_FALSE;	if (pn2->pn_type == TOK_IN) {	    /*	     * Generate the object and iterator pop opcodes after popping the	     * stmtInfo stack, so breaks will go to this pop bytecode.	     */            if (pn3->pn_type != TOK_LB) {	        if (js_Emit1(cx, cg, JSOP_POP2) < 0)		    return JS_FALSE;            }            else {                /*                    for 'for(x[i]...)' there's only the object on the stack,                    so we need to hide the pop.                */	        if (js_NewSrcNote(cx, cg, SRC_HIDDEN) < 0)		    return JS_FALSE;                if (js_Emit1(cx, cg, JSOP_POP) < 0)		    return JS_FALSE;            }	}	break;      case TOK_BREAK:	stmt = cg->treeContext.topStmt;	atom = pn->pn_atom;	if (atom) {	    ale = js_IndexAtom(cx, atom, &cg->atomList);	    if (!ale)		return JS_FALSE;	    while (stmt->type != STMT_LABEL || stmt->label != atom)		stmt = stmt->down;	} else {	    ale = NULL;	    while (!STMT_IS_LOOP(stmt) && stmt->type != STMT_SWITCH)		stmt = stmt->down;	}	if (js_EmitBreak(cx, cg, stmt, ale) < 0)	    return JS_FALSE;	break;      case TOK_CONTINUE:	stmt = cg->treeContext.topStmt;	atom = pn->pn_atom;	if (atom) {            /* Find the loop statement enclosed by the matching label. */            JSStmtInfo *loop = NULL;	    ale = js_IndexAtom(cx, atom, &cg->atomList);	    if (!ale)		return JS_FALSE;            while (stmt->type != STMT_LABEL || stmt->label != atom) {                if (STMT_IS_LOOP(stmt))                    loop = stmt;		stmt = stmt->down;            }            stmt = loop;	} else {	    ale = NULL;	    while (!STMT_IS_LOOP(stmt))		stmt = stmt->down;	    if (js_NewSrcNote(cx, cg, SRC_CONTINUE) < 0)		return JS_FALSE;	}	if (js_EmitContinue(cx, cg, stmt, ale) < 0)	    return JS_FALSE;	break;      case TOK_WITH:	if (!js_EmitTree(cx, cg, pn->pn_left))	    return JS_FALSE;	js_PushStatement(&cg->treeContext, &stmtInfo, STMT_WITH, CG_OFFSET(cg));	if (js_Emit1(cx, cg, JSOP_ENTERWITH) < 0)	    return JS_FALSE;	if (!js_EmitTree(cx, cg, pn->pn_right))	    return JS_FALSE;	if (js_Emit1(cx, cg, JSOP_LEAVEWITH) < 0)	    return JS_FALSE;	return js_PopStatementCG(cx, cg);#if JS_HAS_EXCEPTIONS      case TOK_TRY: {	ptrdiff_t start, end;        ptrdiff_t catchStart = -1, finallyCatch = -1, catchjmp = -1;	JSParseNode *iter = pn;	uint16 depth;	/* XXX use -(CG_OFFSET + 1) */#define EMIT_FINALLY_GOSUB(cx, cg)                                            \    JS_BEGIN_MACRO                                                            \	if (!js_Emit3(cx, cg, JSOP_GOSUB, 0, 0))                              \	    return JS_FALSE;                                                  \    JS_END_MACRO	/*	 * When a finally block is `active' (STMT_FINALLY on the treeContext),	 * non-local jumps result in a GOSUB being written into the bytecode	 * stream for later fixup.  The GOSUB is written with offset 0 for the	 * innermost finally, -1 for the next, etc.  As the finally fixup code	 * runs for each finished try/finally, it will fix the GOSUBs with	 * offset 0 to match the appropriate finally code for its block	 * and decrement all others by one.	 *	 * NOTE: This will cause problems if we use GOSUBs for something other	 * than finally handling in the future.  Caveat hacker!	 */	if (pn->pn_kid3) {	    js_PushStatement(&cg->treeContext, &stmtInfo, STMT_FINALLY,			     CG_OFFSET(cg));	}	/*	 * About SETSP:	 * An exception can be thrown while the stack is in an unbalanced	 * state, and this causes problems with things like function invocation	 * later on.	 *	 * To fix this, we compute the `balanced' stack depth upon try entry,	 * and then restore the stack to this depth when we hit the first catch	 * or finally block.  We can't just zero the stack, because things like	 * for/in and with that are active upon entry to the block keep things	 * on the stack.	 */	depth = cg->stackDepth;	/* mark try location for decompilation, then emit try block */	if (js_NewSrcNote2(cx, cg, SRC_TRYFIN, 0) < 0 ||	    js_Emit1(cx, cg, JSOP_NOP) < 0)	    return JS_FALSE;	start = CG_OFFSET(cg);	if(!js_EmitTree(cx, cg, pn->pn_kid1))	    return JS_FALSE;	/* emit (hidden) jump over catch and/or finally */	if (pn->pn_kid3) {	    if (js_NewSrcNote(cx, cg, SRC_HIDDEN) < 0)		return JS_FALSE;	    EMIT_FINALLY_GOSUB(cx, cg);	}	if (js_NewSrcNote(cx, cg, SRC_HIDDEN) < 0)	    return JS_FALSE;	jmp = js_Emit3(cx, cg, JSOP_GOTO, 0, 0);	if (jmp < 0)	    return JS_FALSE;	end = CG_OFFSET(cg);	/* if this try has a catch block, emit it */	if (pn->pn_kid2) {	    catchStart = end;	    /*	     * The emitted code for a catch block looks like:	     *	     * [ popscope ]                       only if 2nd+ catch block	     * name Object	     * pushobj	     * newinit	     * exception	     * initprop <atom>                    marked SRC_CATCH	     * enterwith	     * [< catchguard code >]              if there's a catchguard	     * ifeq <offset to next catch block>	     * < catch block contents >	     * leavewith	     * goto <end of catch blocks>         non-local; finally applies	     *	     * If there's no catch block without a catchguard, the last	     * <offset to next catch block> points to rethrow code.  This	     * code will GOSUB to the finally code if appropriate, and is	     * also used for the catch-all trynote for capturing exceptions	     * thrown from catch{} blocks.	     */	    do {		JSStmtInfo stmtInfo2;		JSParseNode *disc;		ptrdiff_t guardnote;		iter = iter->pn_kid2;		disc = iter->pn_kid1;                if (!UpdateLinenoNotes(cx, cg, iter))                    return JS_FALSE;		if (catchjmp != -1) {		    /* fix up and clean up previous catch block */		    CHECK_AND_SET_JUMP_OFFSET_AT(cx, cg, catchjmp);		    if ((uintN)++cg->stackDepth > cg->maxStackDepth)			cg->maxStackDepth = cg->stackDepth;		    if (js_NewSrcNote(cx, cg, SRC_HIDDEN) < 0 ||			js_Emit1(cx, cg, JSOP_LEAVEWITH) < 0)			return JS_FALSE;		} else {		    /* set stack to original depth (see SETSP comment above) */		    EMIT_ATOM_INDEX_OP(JSOP_SETSP, (jsatomid)depth);		}		/* non-zero guardnote is length of catchguard */		guardnote = js_NewSrcNote2(cx, cg, SRC_CATCH, 0);		if (guardnote < 0 ||		    js_Emit1(cx, cg, JSOP_NOP) < 0)		    return JS_FALSE;		/* construct the scope holder and push it on */		ale = js_IndexAtom(cx, cx->runtime->atomState.ObjectAtom,				   &cg->atomList);		if (!ale)		    return JS_FALSE;		EMIT_ATOM_INDEX_OP(JSOP_NAME, ale->index);		if (js_Emit1(cx, cg, JSOP_PUSHOBJ) < 0 ||		    js_Emit1(cx, cg, JSOP_NEWINIT) < 0 ||		    js_Emit1(cx, cg, JSOP_EXCEPTION) < 0)		    return JS_FALSE;		/* setprop <atomIndex> */		ale = js_IndexAtom(cx, disc->pn_atom, &cg->atomList);		if (!ale)		    return JS_FALSE;		EMIT_ATOM_INDEX_OP(JSOP_INITPROP, ale->index);		if (js_NewSrcNote(cx, cg, SRC_HIDDEN) < 0 ||		    js_Emit1(cx, cg, JSOP_ENTERWITH) < 0)		    return JS_FALSE;		/* boolean_expr */		if (disc->pn_expr) {		    ptrdiff_t guardstart = CG_OFFSET(cg);		    if (!js_EmitTree(cx, cg, disc->pn_expr))			return JS_FALSE;		    /* ifeq <next block> */		    catchjmp = js_Emit3(cx, cg, JSOP_IFEQ, 0, 0);		    if (catchjmp < 0)			return JS_FALSE;		    if (!js_SetSrcNoteOffset(cx, cg, guardnote, 0,					     (ptrdiff_t)CG_OFFSET(cg) -					     guardstart))			return JS_FALSE;		}		/* emit catch block */		js_PushStatement(&cg->treeContext, &stmtInfo2, STMT_WITH,				 CG_OFFSET(cg));		if (!js_EmitTree(cx, cg, iter->pn_kid3))		    return JS_FALSE;		js_PopStatementCG(cx, cg);		/*		 * jump over the remaining catch blocks		 * this counts as a non-local jump, so do the finally thing		 */		/* popscope */		if (js_NewSrcNote(cx, cg, SRC_HIDDEN) < 0 ||		    js_Emit1(cx, cg, JSOP_LEAVEWITH) < 0)		    return JS_FALSE;		/* gosub <finally>, if required */		if (pn->pn_kid3)		    EMIT_FINALLY_GOSUB(cx, cg);		/* this will get fixed up to jump to after catch/finally */		if (js_NewSrcNote(cx, cg, SRC_HIDDEN) < 0 ||		    js_Emit3(cx, cg, JSOP_GOTO, 0, 0) < 0)		    return JS_FALSE;		if (!iter->pn_kid2)		    break;	    } while (iter);	}	/*	 * we use a [leavewith],[gosub],rethrow block for rethrowing	 * when there's no unguarded catch, and also for	 * running finally code while letting an uncaught exception	 * pass through	 */	if (pn->pn_kid3 ||	    (catchjmp != -1 && iter->pn_kid1->pn_expr)) {	    /*	     * Emit another stack fix, because the catch could itself	     * throw an exception in an unbalanced state, and the finally	     * may need to call functions etc.	     */	    EMIT_ATOM_INDEX_OP(JSOP_SETSP, (jsatomid)depth);	    if (catchjmp != -1 && iter->pn_kid1->pn_expr) {		CHECK_AND_SET_JUMP_OFFSET_AT(cx, cg, catchjmp);	    }	    /* last discriminant jumps to rethrow if none match */	    if ((uintN)++cg->stackDepth > cg->maxStackDepth)		cg->maxStackDepth = cg->stackDepth;	    if (pn->pn_kid2 &&		(js_NewSrcNote(cx, cg, SRC_HIDDEN) < 0 ||		 js_Emit1(cx, cg, JSOP_LEAVEWITH) < 0))		return JS_FALSE;	    if (pn->pn_kid3) {		finallyCatch = CG_OFFSET(cg);		EMIT_FINALLY_GOSUB(cx, cg);	    }	    if (js_NewSrcNote(cx, cg, SRC_HIDDEN) < 0 ||		js_Emit1(cx, cg, JSOP_EXCEPTION) < 0 ||		js_NewSrcNote(cx, cg, SRC_HIDDEN) < 0 ||		js_Emit1(cx, cg, JSOP_THROW) < 0)		return JS_FALSE;	}	/*	 * If we've got a finally, it goes here, and we have to fix up	 * the gosubs that might have been emitted before non-local jumps.	 */	if (pn->pn_kid3) {	    ptrdiff_t finallyIndex;	    finallyIndex = CG_OFFSET(cg);	    if (!FixupFinallyJumps(cx, cg, start, finallyIndex))		return JS_FALSE;	    js_PopStatementCG(cx, cg);            if (!UpdateLinenoNotes(cx, cg, pn->pn_kid3))                return JS_FALSE;	    if (js_NewSrcNote2(cx, cg, SRC_TRYFIN, 1) < 0 ||		js_Emit1(cx, cg, JSOP_NOP) < 0 ||		!js_EmitTree(cx, cg, pn->pn_kid3) ||		js_Emit1(cx, cg, JSOP_RETSUB) < 0)		return JS_FALSE;	}	if (js_NewSrcNote(cx, cg, SRC_ENDBRACE) < 0 ||	    js_Emit1(cx, cg, JSOP_NOP) < 0)	    return JS_FALSE;	/* fix up the end-of-try/catch jumps to come here */	if (!FixupCatchJumps(cx, cg, start, CG_OFFSET(cg)))	    return JS_FALSE;	CHECK_AND_SET_JUMP_OFFSET_AT(cx, cg, jmp);	/*	 * Add the try note last, to let post-order give us the right ordering	 * (first to last, inner to outer).	 */	if (pn->pn_kid2 &&	    !js_NewTryNote(cx, cg, start, end, catchStart))	    return JS_FALSE;	/*	 * If we've got a finally, mark try+catch region with additional	 * trynote to catch exceptions (re)thrown from a catch block or	 * for the try{}finally{} case.	 */	if (pn->pn_kid3 &&	    !js_NewTryNote(cx, cg, start, finallyCatch-1, finallyCatch))	    return JS_FALSE;	break;      }#endif /* JS_HAS_EXCEPTIONS */      case TOK_VAR:	off = noteIndex = -1;	for (pn2 = pn->pn_head; ; pn2 = pn2->pn_next) {	    JS_ASSERT(pn2->pn_type == TOK_NAME);	    op = pn2->pn_op;	    if (pn2->pn_slot >= 0) {		atomIndex = (jsatomid) pn2->pn_slot;	    } else {		ale = js_IndexAtom(cx, pn2->pn_atom, &cg->atomList);		if (!ale)		    return JS_FALSE;		atomIndex = ale->index;	    }	    if (pn2->pn_expr) {		if (op == JSOP_SETNAME2)		    EMIT_ATOM_INDEX_OP(JSOP_BINDNAME, atomIndex);		if (!js_EmitTree(cx, cg, pn2->pn_expr))		    return JS_FALSE;	    }	    if (pn2 == pn->pn_head && js_NewSrcNote(cx, cg, SRC_VAR) < 0)		return JS_FALSE;	    EMIT_ATOM_INDEX_OP(op, atomIndex);	    tmp = CG_OFFSET(cg);	    if (noteIndex >= 0) {		if (!js_SetSrcNoteOffset(cx, cg, noteIndex, 0, tmp - off))		    return JS_FALSE;	    }	    if (!pn2->pn_next)		break;	    off = tmp;	    noteIndex = js_NewSrcNote2(cx, cg, SRC_PCDELTA, 0);	    if (noteIndex < 0 ||		js_Emit1(cx, cg, JSOP_POP) < 0) {		return JS_FALSE;	    }	}