зеркало из https://github.com/mozilla/gecko-dev.git
Track ES4 proposal by restricting let declaration to be direct child of block (408957, r=mrbkap).
This commit is contained in:
Родитель
810fc6c19f
Коммит
9744f8528f
|
@ -302,3 +302,4 @@ MSG_DEF(JSMSG_NON_LIST_XML_METHOD, 219, 2, JSEXN_TYPEERR, "cannot call {0} me
|
|||
MSG_DEF(JSMSG_BAD_DELETE_OPERAND, 220, 0, JSEXN_SYNTAXERR, "invalid delete operand")
|
||||
MSG_DEF(JSMSG_BAD_INCOP_OPERAND, 221, 0, JSEXN_SYNTAXERR, "invalid increment/decrement operand")
|
||||
MSG_DEF(JSMSG_NULL_OR_UNDEFINED, 222, 2, JSEXN_TYPEERR, "{0} is {1}")
|
||||
MSG_DEF(JSMSG_LET_DECL_NOT_IN_BLOCK, 223, 0, JSEXN_SYNTAXERR, "let declaration not directly within block")
|
||||
|
|
|
@ -56,7 +56,7 @@ JS_BEGIN_EXTERN_C
|
|||
|
||||
/*
|
||||
* NB: If you add enumerators for scope statements, add them between STMT_WITH
|
||||
* and STMT_CATCH, or you will break the STMT_TYPE_IS_SCOPE macro. If you add
|
||||
* and STMT_CATCH, or you will break the STMT_TYPE_IS_SCOPE macro. If you add
|
||||
* non-looping statement enumerators, add them before STMT_DO_LOOP or you will
|
||||
* break the STMT_TYPE_IS_LOOP macro.
|
||||
*
|
||||
|
@ -66,10 +66,10 @@ typedef enum JSStmtType {
|
|||
STMT_LABEL, /* labeled statement: L: s */
|
||||
STMT_IF, /* if (then) statement */
|
||||
STMT_ELSE, /* else clause of if statement */
|
||||
STMT_SWITCH, /* switch statement */
|
||||
STMT_BODY, /* synthetic body of function with
|
||||
destructuring formal parameters */
|
||||
STMT_BLOCK, /* compound statement: { s1[;... sN] } */
|
||||
STMT_SWITCH, /* switch statement */
|
||||
STMT_WITH, /* with statement */
|
||||
STMT_CATCH, /* catch block */
|
||||
STMT_TRY, /* try block */
|
||||
|
@ -87,19 +87,17 @@ typedef enum JSStmtType {
|
|||
* A comment on the encoding of the JSStmtType enum and type-testing macros:
|
||||
*
|
||||
* STMT_TYPE_MAYBE_SCOPE tells whether a statement type is always, or may
|
||||
* become, a lexical scope. It therefore includes block and switch (the two
|
||||
* low-numbered "maybe" scope types) and excludes with (with has dynamic scope
|
||||
* pending the "reformed with" in ES4/JS2). It includes all try-catch-finally
|
||||
* types, which are high-numbered maybe-scope types.
|
||||
* become, a lexical scope. Per the proposed JS2/ES4 spec, it includes only
|
||||
* syntactic blocks: block statements and try/catch/finally statements.
|
||||
*
|
||||
* STMT_TYPE_LINKS_SCOPE tells whether a JSStmtInfo of the given type eagerly
|
||||
* links to other scoping statement info records. It excludes the two early
|
||||
* "maybe" types, block and switch, as well as the try and both finally types,
|
||||
* since try and the other trailing maybe-scope types don't need block scope
|
||||
* unless they contain let declarations.
|
||||
* links to other scoping statement info records. It excludes the the "maybe"
|
||||
* type, block, as well as the try and both finally types, since try and the
|
||||
* other trailing maybe-scope types don't need block scope unless they contain
|
||||
* let declarations.
|
||||
*
|
||||
* We treat with as a static scope because it prevents lexical binding from
|
||||
* continuing further up the static scope chain. With the "reformed with"
|
||||
* We treat WITH as a static scope because it prevents lexical binding from
|
||||
* continuing further up the static scope chain. With the "reformed with"
|
||||
* proposal for JS2, we'll be able to model it statically, too.
|
||||
*/
|
||||
#define STMT_TYPE_MAYBE_SCOPE(type) \
|
||||
|
@ -141,8 +139,8 @@ struct JSStmtInfo {
|
|||
|
||||
/*
|
||||
* To reuse space in JSStmtInfo, rename breaks and continues for use during
|
||||
* try/catch/finally code generation and backpatching. To match most common
|
||||
* use cases, the macro argument is a struct, not a struct pointer. Only a
|
||||
* try/catch/finally code generation and backpatching. To match most common
|
||||
* use cases, the macro argument is a struct, not a struct pointer. Only a
|
||||
* loop, switch, or label statement info record can have breaks and continues,
|
||||
* and only a for loop has an update backpatch chain, so it's safe to overlay
|
||||
* these for the "trying" JSStmtTypes.
|
||||
|
@ -373,7 +371,7 @@ js_InitCodeGenerator(JSContext *cx, JSCodeGenerator *cg, JSParseContext *pc,
|
|||
|
||||
/*
|
||||
* Release cg->codePool, cg->notePool, and cx->tempPool to marks set by
|
||||
* js_InitCodeGenerator. Note that cgs are magic: they own the arena pool
|
||||
* js_InitCodeGenerator. Note that cgs are magic: they own the arena pool
|
||||
* "tops-of-stack" space above their codeMark, noteMark, and tempMark points.
|
||||
* This means you cannot alloc from tempPool and save the pointer beyond the
|
||||
* next JS_FinishCodeGenerator.
|
||||
|
@ -445,7 +443,7 @@ js_PushStatement(JSTreeContext *tc, JSStmtInfo *stmt, JSStmtType type,
|
|||
ptrdiff_t top);
|
||||
|
||||
/*
|
||||
* Push a block scope statement and link blockObj into tc->blockChain. To pop
|
||||
* Push a block scope statement and link blockObj into tc->blockChain. To pop
|
||||
* this statement info record, use js_PopStatement as usual, or if appropriate
|
||||
* (if generating code), js_PopStatementCG.
|
||||
*/
|
||||
|
@ -454,7 +452,7 @@ js_PushBlockScope(JSTreeContext *tc, JSStmtInfo *stmt, JSObject *blockObj,
|
|||
ptrdiff_t top);
|
||||
|
||||
/*
|
||||
* Pop tc->topStmt. If the top JSStmtInfo struct is not stack-allocated, it
|
||||
* Pop tc->topStmt. If the top JSStmtInfo struct is not stack-allocated, it
|
||||
* is up to the caller to free it.
|
||||
*/
|
||||
extern void
|
||||
|
@ -472,10 +470,10 @@ js_PopStatementCG(JSContext *cx, JSCodeGenerator *cg);
|
|||
* Define and lookup a primitive jsval associated with the const named by atom.
|
||||
* js_DefineCompileTimeConstant analyzes the constant-folded initializer at pn
|
||||
* and saves the const's value in cg->constList, if it can be used at compile
|
||||
* time. It returns true unless an error occurred.
|
||||
* time. It returns true unless an error occurred.
|
||||
*
|
||||
* If the initializer's value could not be saved, js_DefineCompileTimeConstant
|
||||
* calls will return the undefined value. js_DefineCompileTimeConstant tries
|
||||
* calls will return the undefined value. js_DefineCompileTimeConstant tries
|
||||
* to find a const value memorized for atom, returning true with *vp set to a
|
||||
* value other than undefined if the constant was found, true with *vp set to
|
||||
* JSVAL_VOID if not found, and false on error.
|
||||
|
@ -489,14 +487,14 @@ js_DefineCompileTimeConstant(JSContext *cx, JSCodeGenerator *cg, JSAtom *atom,
|
|||
* comprehension) named by atom, looking in tc's compile-time scopes.
|
||||
*
|
||||
* If a WITH statement is reached along the scope stack, return its statement
|
||||
* info record, so callers can tell that atom is ambiguous. If slotp is not
|
||||
* info record, so callers can tell that atom is ambiguous. If slotp is not
|
||||
* null, then if atom is found, set *slotp to its stack slot, otherwise to -1.
|
||||
* This means that if slotp is not null, all the block objects on the lexical
|
||||
* scope chain must have had their depth slots computed by the code generator,
|
||||
* so the caller must be under js_EmitTree.
|
||||
*
|
||||
* In any event, directly return the statement info record in which atom was
|
||||
* found. Otherwise return null.
|
||||
* found. Otherwise return null.
|
||||
*/
|
||||
extern JSStmtInfo *
|
||||
js_LexicalLookup(JSTreeContext *tc, JSAtom *atom, jsint *slotp,
|
||||
|
@ -517,9 +515,9 @@ js_EmitFunctionScript(JSContext *cx, JSCodeGenerator *cg, JSParseNode *body);
|
|||
/*
|
||||
* Source notes generated along with bytecode for decompiling and debugging.
|
||||
* A source note is a uint8 with 5 bits of type and 3 of offset from the pc of
|
||||
* the previous note. If 3 bits of offset aren't enough, extended delta notes
|
||||
* the previous note. If 3 bits of offset aren't enough, extended delta notes
|
||||
* (SRC_XDELTA) consisting of 2 set high order bits followed by 6 offset bits
|
||||
* are emitted before the next note. Some notes have operand offsets encoded
|
||||
* are emitted before the next note. Some notes have operand offsets encoded
|
||||
* immediately after them, in note bytes or byte-triples.
|
||||
*
|
||||
* Source Note Extended Delta
|
||||
|
@ -536,8 +534,8 @@ js_EmitFunctionScript(JSContext *cx, JSCodeGenerator *cg, JSParseNode *body);
|
|||
* Note on adding new source notes: every pair of bytecodes (A, B) where A and
|
||||
* B have disjoint sets of source notes that could apply to each bytecode may
|
||||
* reuse the same note type value for two notes (snA, snB) that have the same
|
||||
* arity, offsetBias, and isSpanDep initializers in js_SrcNoteSpec. This is
|
||||
* why SRC_IF and SRC_INITPROP have the same value below. For bad historical
|
||||
* arity, offsetBias, and isSpanDep initializers in js_SrcNoteSpec. This is
|
||||
* why SRC_IF and SRC_INITPROP have the same value below. For bad historical
|
||||
* reasons, some bytecodes below that could be overlayed have not been, but
|
||||
* before using SRC_EXTENDED, consider compressing the existing note types.
|
||||
*
|
||||
|
@ -588,7 +586,7 @@ typedef enum JSSrcNoteType {
|
|||
} JSSrcNoteType;
|
||||
|
||||
/*
|
||||
* Constants for the SRC_DECL source note. Note that span-dependent bytecode
|
||||
* Constants for the SRC_DECL source note. Note that span-dependent bytecode
|
||||
* selection means that any SRC_DECL offset greater than SRC_DECL_LET may need
|
||||
* to be adjusted, but these "offsets" are too small to span a span-dependent
|
||||
* instruction, so can be used to denote distinct declaration syntaxes to the
|
||||
|
@ -662,8 +660,8 @@ extern JS_FRIEND_API(uintN) js_SrcNoteLength(jssrcnote *sn);
|
|||
|
||||
/*
|
||||
* Append a new source note of the given type (and therefore size) to cg's
|
||||
* notes dynamic array, updating cg->noteCount. Return the new note's index
|
||||
* within the array pointed at by cg->current->notes. Return -1 if out of
|
||||
* notes dynamic array, updating cg->noteCount. Return the new note's index
|
||||
* within the array pointed at by cg->current->notes. Return -1 if out of
|
||||
* memory.
|
||||
*/
|
||||
extern intN
|
||||
|
@ -696,11 +694,11 @@ js_SetSrcNoteOffset(JSContext *cx, JSCodeGenerator *cg, uintN index,
|
|||
|
||||
/*
|
||||
* Finish taking source notes in cx's notePool, copying final notes to the new
|
||||
* stable store allocated by the caller and passed in via notes. Return false
|
||||
* stable store allocated by the caller and passed in via notes. Return false
|
||||
* on malloc failure, which means this function reported an error.
|
||||
*
|
||||
* To compute the number of jssrcnotes to allocate and pass in via notes, use
|
||||
* the CG_COUNT_FINAL_SRCNOTES macro. This macro knows a lot about details of
|
||||
* the CG_COUNT_FINAL_SRCNOTES macro. This macro knows a lot about details of
|
||||
* js_FinishTakingSrcNotes, SO DON'T CHANGE jsemit.c's js_FinishTakingSrcNotes
|
||||
* FUNCTION WITHOUT CHECKING WHETHER THIS MACRO NEEDS CORRESPONDING CHANGES!
|
||||
*/
|
||||
|
|
|
@ -607,14 +607,6 @@ js_QuoteString(JSContext *cx, JSString *str, jschar quote)
|
|||
|
||||
/************************************************************************/
|
||||
|
||||
#if JS_HAS_BLOCK_SCOPE
|
||||
typedef enum JSBraceState {
|
||||
ALWAYS_BRACE,
|
||||
MAYBE_BRACE,
|
||||
DONT_BRACE
|
||||
} JSBraceState;
|
||||
#endif
|
||||
|
||||
struct JSPrinter {
|
||||
Sprinter sprinter; /* base class state */
|
||||
JSArenaPool pool; /* string allocation pool */
|
||||
|
@ -625,10 +617,6 @@ struct JSPrinter {
|
|||
jsbytecode *dvgfence; /* js_DecompileValueGenerator fencepost */
|
||||
JSFunction *fun; /* interpreted function */
|
||||
JSAtom **localNames; /* argument and variable names */
|
||||
#if JS_HAS_BLOCK_SCOPE
|
||||
JSBraceState braceState; /* remove braces around let declaration */
|
||||
ptrdiff_t spaceOffset; /* -1 or offset of space before maybe-{ */
|
||||
#endif
|
||||
};
|
||||
|
||||
/*
|
||||
|
@ -655,10 +643,6 @@ JS_NEW_PRINTER(JSContext *cx, const char *name, JSFunction *fun,
|
|||
jp->grouped = (indent & JS_IN_GROUP_CONTEXT) != 0;
|
||||
jp->script = NULL;
|
||||
jp->dvgfence = NULL;
|
||||
#if JS_HAS_BLOCK_SCOPE
|
||||
jp->braceState = ALWAYS_BRACE;
|
||||
jp->spaceOffset = -1;
|
||||
#endif
|
||||
jp->fun = fun;
|
||||
if (!fun || !FUN_INTERPRETED(fun) || fun->nargs + fun->u.i.nvars == 0) {
|
||||
jp->localNames = NULL;
|
||||
|
@ -712,55 +696,6 @@ VarPrefix(jssrcnote *sn)
|
|||
return "";
|
||||
}
|
||||
|
||||
#if !JS_HAS_BLOCK_SCOPE
|
||||
# define SET_MAYBE_BRACE(jp) jp
|
||||
# define CLEAR_MAYBE_BRACE(jp) jp
|
||||
# define MAYBE_SET_DONT_BRACE(jp,pc,endpc,rval) /* nothing */
|
||||
#else
|
||||
# define SET_MAYBE_BRACE(jp) ((jp)->braceState = MAYBE_BRACE, (jp))
|
||||
# define CLEAR_MAYBE_BRACE(jp) ((jp)->braceState = ALWAYS_BRACE, (jp))
|
||||
# define MAYBE_SET_DONT_BRACE MaybeSetDontBrace
|
||||
|
||||
static void
|
||||
SetDontBrace(JSPrinter *jp)
|
||||
{
|
||||
ptrdiff_t offset;
|
||||
const char *bp;
|
||||
|
||||
/* When not pretty-printing, newline after brace is chopped. */
|
||||
JS_ASSERT(jp->spaceOffset < 0);
|
||||
offset = jp->sprinter.offset - (jp->pretty ? 3 : 2);
|
||||
|
||||
/* The shortest case is "if (x) {". */
|
||||
JS_ASSERT(offset >= 6);
|
||||
bp = jp->sprinter.base;
|
||||
if (bp[offset+0] == ' ' && bp[offset+1] == '{') {
|
||||
JS_ASSERT(!jp->pretty || bp[offset+2] == '\n');
|
||||
jp->spaceOffset = offset;
|
||||
jp->braceState = DONT_BRACE;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* If a let declaration is the only child of a control structure that does not
|
||||
* require braces, it must not be braced. If it were braced explicitly, then it
|
||||
* would be bracketed by JSOP_ENTERBLOCK/JSOP_LEAVEBLOCK.
|
||||
*/
|
||||
static void
|
||||
MaybeSetDontBrace(JSPrinter *jp, jsbytecode *pc, jsbytecode *endpc,
|
||||
const char *rval)
|
||||
{
|
||||
JS_ASSERT(*pc == JSOP_POP || *pc == JSOP_POPV || *pc == JSOP_POPN);
|
||||
|
||||
if (jp->braceState == MAYBE_BRACE &&
|
||||
pc + js_CodeSpec[*pc].length == endpc &&
|
||||
!strncmp(rval, var_prefix[SRC_DECL_LET], 4) &&
|
||||
rval[4] != '(') {
|
||||
SetDontBrace(jp);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
int
|
||||
js_printf(JSPrinter *jp, const char *format, ...)
|
||||
{
|
||||
|
@ -776,46 +711,6 @@ js_printf(JSPrinter *jp, const char *format, ...)
|
|||
/* If pretty-printing, expand magic tab into a run of jp->indent spaces. */
|
||||
if (*format == '\t') {
|
||||
format++;
|
||||
|
||||
#if JS_HAS_BLOCK_SCOPE
|
||||
if (*format == '}' && jp->braceState != ALWAYS_BRACE) {
|
||||
JSBraceState braceState;
|
||||
|
||||
braceState = jp->braceState;
|
||||
jp->braceState = ALWAYS_BRACE;
|
||||
if (braceState == DONT_BRACE) {
|
||||
ptrdiff_t offset, delta, from;
|
||||
|
||||
JS_ASSERT(format[1] == '\n' || format[1] == ' ');
|
||||
offset = jp->spaceOffset;
|
||||
JS_ASSERT(offset >= 6);
|
||||
|
||||
/* Replace " {\n" at the end of jp->sprinter with "\n". */
|
||||
bp = jp->sprinter.base;
|
||||
if (bp[offset+0] == ' ' && bp[offset+1] == '{') {
|
||||
delta = 2;
|
||||
if (jp->pretty) {
|
||||
/* If pretty, we don't have to worry about 'else'. */
|
||||
JS_ASSERT(bp[offset+2] == '\n');
|
||||
} else if (bp[offset-1] != ')') {
|
||||
/* Must keep ' ' to avoid 'dolet' or 'elselet'. */
|
||||
++offset;
|
||||
delta = 1;
|
||||
}
|
||||
|
||||
from = offset + delta;
|
||||
memmove(bp + offset, bp + from, jp->sprinter.offset - from);
|
||||
jp->sprinter.offset -= delta;
|
||||
jp->spaceOffset = -1;
|
||||
|
||||
format += 2;
|
||||
if (*format == '\0')
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
if (jp->pretty && Sprint(&jp->sprinter, "%*s", jp->indent, "") < 0)
|
||||
return -1;
|
||||
}
|
||||
|
@ -1081,7 +976,7 @@ DecompileSwitch(SprintStack *ss, TableEntry *table, uintN tableLength,
|
|||
off = isCondSwitch ? GetOff(ss, ss->top-1) : PopOff(ss, JSOP_NOP);
|
||||
lval = OFF2STR(&ss->sprinter, off);
|
||||
|
||||
js_printf(CLEAR_MAYBE_BRACE(jp), "\tswitch (%s) {\n", lval);
|
||||
js_printf(jp, "\tswitch (%s) {\n", lval);
|
||||
|
||||
if (tableLength) {
|
||||
diff = table[0].offset - defaultOffset;
|
||||
|
@ -1970,7 +1865,7 @@ Decompile(SprintStack *ss, jsbytecode *pc, intN nb, JSOp nextop)
|
|||
tail = js_GetSrcNoteOffset(sn, 0) - 1;
|
||||
LOCAL_ASSERT(pc[tail] == JSOP_IFNE ||
|
||||
pc[tail] == JSOP_IFNEX);
|
||||
js_printf(SET_MAYBE_BRACE(jp), "\tdo {\n");
|
||||
js_printf(jp, "\tdo {\n");
|
||||
jp->indent += 4;
|
||||
DECOMPILE_CODE(pc, tail);
|
||||
jp->indent -= 4;
|
||||
|
@ -2012,7 +1907,7 @@ Decompile(SprintStack *ss, jsbytecode *pc, intN nb, JSOp nextop)
|
|||
}
|
||||
|
||||
/* Do the loop body. */
|
||||
js_printf(SET_MAYBE_BRACE(jp), ") {\n");
|
||||
js_printf(jp, ") {\n");
|
||||
jp->indent += 4;
|
||||
oplen = (cond) ? js_CodeSpec[pc[cond]].length : 0;
|
||||
DECOMPILE_CODE(pc + cond + oplen, next - cond - oplen);
|
||||
|
@ -2030,7 +1925,7 @@ Decompile(SprintStack *ss, jsbytecode *pc, intN nb, JSOp nextop)
|
|||
if (!rval)
|
||||
return NULL;
|
||||
RETRACT(&ss->sprinter, rval);
|
||||
js_printf(CLEAR_MAYBE_BRACE(jp), "\t%s:\n", rval);
|
||||
js_printf(jp, "\t%s:\n", rval);
|
||||
jp->indent += 4;
|
||||
break;
|
||||
|
||||
|
@ -2040,7 +1935,7 @@ Decompile(SprintStack *ss, jsbytecode *pc, intN nb, JSOp nextop)
|
|||
if (!rval)
|
||||
return NULL;
|
||||
RETRACT(&ss->sprinter, rval);
|
||||
js_printf(CLEAR_MAYBE_BRACE(jp), "\t%s: {\n", rval);
|
||||
js_printf(jp, "\t%s: {\n", rval);
|
||||
jp->indent += 4;
|
||||
break;
|
||||
|
||||
|
@ -2069,7 +1964,7 @@ Decompile(SprintStack *ss, jsbytecode *pc, intN nb, JSOp nextop)
|
|||
break;
|
||||
|
||||
case SRC_BRACE:
|
||||
js_printf(CLEAR_MAYBE_BRACE(jp), "\t{\n");
|
||||
js_printf(jp, "\t{\n");
|
||||
jp->indent += 4;
|
||||
len = js_GetSrcNoteOffset(sn, 0);
|
||||
DECOMPILE_CODE(pc + oplen, len - oplen);
|
||||
|
@ -2138,14 +2033,14 @@ Decompile(SprintStack *ss, jsbytecode *pc, intN nb, JSOp nextop)
|
|||
break;
|
||||
|
||||
case JSOP_TRY:
|
||||
js_printf(CLEAR_MAYBE_BRACE(jp), "\ttry {\n");
|
||||
js_printf(jp, "\ttry {\n");
|
||||
jp->indent += 4;
|
||||
todo = -2;
|
||||
break;
|
||||
|
||||
case JSOP_FINALLY:
|
||||
jp->indent -= 4;
|
||||
js_printf(CLEAR_MAYBE_BRACE(jp), "\t} finally {\n");
|
||||
js_printf(jp, "\t} finally {\n");
|
||||
jp->indent += 4;
|
||||
|
||||
/*
|
||||
|
@ -2296,10 +2191,8 @@ Decompile(SprintStack *ss, jsbytecode *pc, intN nb, JSOp nextop)
|
|||
* If control flow reaches this point with todo still -2,
|
||||
* just print rval as an expression statement.
|
||||
*/
|
||||
if (todo == -2) {
|
||||
MAYBE_SET_DONT_BRACE(jp, pc, endpc, rval);
|
||||
if (todo == -2)
|
||||
js_printf(jp, "\t%s;\n", rval);
|
||||
}
|
||||
end_popn:
|
||||
break;
|
||||
}
|
||||
|
@ -2378,8 +2271,7 @@ Decompile(SprintStack *ss, jsbytecode *pc, intN nb, JSOp nextop)
|
|||
#endif
|
||||
len = js_GetSrcNoteOffset(sn, 0);
|
||||
if (pc[len] == JSOP_LEAVEBLOCK) {
|
||||
js_printf(CLEAR_MAYBE_BRACE(jp), "\tlet (%s) {\n",
|
||||
POP_STR());
|
||||
js_printf(jp, "\tlet (%s) {\n", POP_STR());
|
||||
jp->indent += 4;
|
||||
DECOMPILE_CODE(pc, len);
|
||||
jp->indent -= 4;
|
||||
|
@ -2422,7 +2314,6 @@ Decompile(SprintStack *ss, jsbytecode *pc, intN nb, JSOp nextop)
|
|||
* not appear in the decompiler's output.
|
||||
*/
|
||||
if (*rval != '\0' && (rval[0] != '/' || rval[1] != '*')) {
|
||||
MAYBE_SET_DONT_BRACE(jp, pc, endpc, rval);
|
||||
js_printf(jp,
|
||||
(*rval == '{' ||
|
||||
(strncmp(rval, js_function_str, 8) == 0 &&
|
||||
|
@ -2451,7 +2342,7 @@ Decompile(SprintStack *ss, jsbytecode *pc, intN nb, JSOp nextop)
|
|||
case JSOP_ENTERWITH:
|
||||
LOCAL_ASSERT(!js_GetSrcNote(jp->script, pc));
|
||||
rval = POP_STR();
|
||||
js_printf(SET_MAYBE_BRACE(jp), "\twith (%s) {\n", rval);
|
||||
js_printf(jp, "\twith (%s) {\n", rval);
|
||||
jp->indent += 4;
|
||||
todo = Sprint(&ss->sprinter, with_cookie);
|
||||
break;
|
||||
|
@ -2505,7 +2396,7 @@ Decompile(SprintStack *ss, jsbytecode *pc, intN nb, JSOp nextop)
|
|||
switch (sn ? SN_TYPE(sn) : SRC_NULL) {
|
||||
#if JS_HAS_BLOCK_SCOPE
|
||||
case SRC_BRACE:
|
||||
js_printf(CLEAR_MAYBE_BRACE(jp), "\t{\n");
|
||||
js_printf(jp, "\t{\n");
|
||||
jp->indent += 4;
|
||||
len = js_GetSrcNoteOffset(sn, 0);
|
||||
ok = Decompile(ss, pc + oplen, len - oplen, JSOP_NOP)
|
||||
|
@ -2519,7 +2410,7 @@ Decompile(SprintStack *ss, jsbytecode *pc, intN nb, JSOp nextop)
|
|||
|
||||
case SRC_CATCH:
|
||||
jp->indent -= 4;
|
||||
js_printf(CLEAR_MAYBE_BRACE(jp), "\t} catch (");
|
||||
js_printf(jp, "\t} catch (");
|
||||
|
||||
pc2 = pc;
|
||||
pc += oplen;
|
||||
|
@ -2862,7 +2753,7 @@ Decompile(SprintStack *ss, jsbytecode *pc, intN nb, JSOp nextop)
|
|||
tail = js_GetSrcNoteOffset(sn, 0);
|
||||
DECOMPILE_CODE(pc + cond, tail - cond);
|
||||
rval = POP_STR();
|
||||
js_printf(SET_MAYBE_BRACE(jp), "\twhile (%s) {\n", rval);
|
||||
js_printf(jp, "\twhile (%s) {\n", rval);
|
||||
jp->indent += 4;
|
||||
DECOMPILE_CODE(pc + oplen, cond - oplen);
|
||||
jp->indent -= 4;
|
||||
|
@ -2926,7 +2817,7 @@ Decompile(SprintStack *ss, jsbytecode *pc, intN nb, JSOp nextop)
|
|||
return NULL;
|
||||
AddParenSlop(ss);
|
||||
} else {
|
||||
js_printf(SET_MAYBE_BRACE(jp),
|
||||
js_printf(jp,
|
||||
elseif ? " if (%s) {\n" : "\tif (%s) {\n",
|
||||
rval);
|
||||
jp->indent += 4;
|
||||
|
@ -2961,7 +2852,7 @@ Decompile(SprintStack *ss, jsbytecode *pc, intN nb, JSOp nextop)
|
|||
goto if_again;
|
||||
}
|
||||
|
||||
js_printf(SET_MAYBE_BRACE(jp), " {\n");
|
||||
js_printf(jp, " {\n");
|
||||
jp->indent += 4;
|
||||
DECOMPILE_CODE(pc + oplen, len - oplen);
|
||||
}
|
||||
|
@ -3155,8 +3046,7 @@ Decompile(SprintStack *ss, jsbytecode *pc, intN nb, JSOp nextop)
|
|||
AddParenSlop(ss);
|
||||
DECOMPILE_CODE(pc + oplen, tail - oplen);
|
||||
} else {
|
||||
js_printf(SET_MAYBE_BRACE(jp), "\t%s in %s) {\n",
|
||||
lval, rval);
|
||||
js_printf(jp, "\t%s in %s) {\n", lval, rval);
|
||||
jp->indent += 4;
|
||||
DECOMPILE_CODE(pc + oplen, tail - oplen);
|
||||
jp->indent -= 4;
|
||||
|
|
|
@ -2254,7 +2254,7 @@ PushLexicalScope(JSContext *cx, JSTokenStream *ts, JSTreeContext *tc,
|
|||
{
|
||||
JSParseNode *pn;
|
||||
JSObject *obj;
|
||||
JSParsedObjectBox *blockPob;
|
||||
JSParsedObjectBox *blockpob;
|
||||
|
||||
pn = NewParseNode(cx, ts, PN_NAME, tc);
|
||||
if (!pn)
|
||||
|
@ -2264,14 +2264,14 @@ PushLexicalScope(JSContext *cx, JSTokenStream *ts, JSTreeContext *tc,
|
|||
if (!obj)
|
||||
return NULL;
|
||||
|
||||
blockPob = js_NewParsedObjectBox(cx, tc->parseContext, obj);
|
||||
if (!blockPob)
|
||||
blockpob = js_NewParsedObjectBox(cx, tc->parseContext, obj);
|
||||
if (!blockpob)
|
||||
return NULL;
|
||||
|
||||
js_PushBlockScope(tc, stmtInfo, obj, -1);
|
||||
pn->pn_type = TOK_LEXICALSCOPE;
|
||||
pn->pn_op = JSOP_LEAVEBLOCK;
|
||||
pn->pn_pob = blockPob;
|
||||
pn->pn_pob = blockpob;
|
||||
pn->pn_slot = -1;
|
||||
return pn;
|
||||
}
|
||||
|
@ -3174,9 +3174,8 @@ Statement(JSContext *cx, JSTokenStream *ts, JSTreeContext *tc)
|
|||
#if JS_HAS_BLOCK_SCOPE
|
||||
case TOK_LET:
|
||||
{
|
||||
JSStmtInfo **sip;
|
||||
JSObject *obj;
|
||||
JSParsedObjectBox *blockPob;
|
||||
JSParsedObjectBox *blockpob;
|
||||
|
||||
/* Check for a let statement or let expression. */
|
||||
if (js_PeekToken(cx, ts) == TOK_LP) {
|
||||
|
@ -3199,12 +3198,11 @@ Statement(JSContext *cx, JSTokenStream *ts, JSTreeContext *tc)
|
|||
* scope statement) then we also need to set tc->blockNode to be our
|
||||
* TOK_LEXICALSCOPE.
|
||||
*/
|
||||
sip = &tc->topScopeStmt;
|
||||
for (stmt = tc->topStmt; stmt; stmt = stmt->down) {
|
||||
if (STMT_MAYBE_SCOPE(stmt))
|
||||
break;
|
||||
if (stmt == *sip)
|
||||
sip = &stmt->downScope;
|
||||
stmt = tc->topStmt;
|
||||
if (stmt && !STMT_MAYBE_SCOPE(stmt)) {
|
||||
js_ReportCompileErrorNumber(cx, ts, NULL, JSREPORT_ERROR,
|
||||
JSMSG_LET_DECL_NOT_IN_BLOCK);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (stmt && (stmt->flags & SIF_SCOPE)) {
|
||||
|
@ -3236,8 +3234,8 @@ Statement(JSContext *cx, JSTokenStream *ts, JSTreeContext *tc)
|
|||
obj = js_NewBlockObject(cx);
|
||||
if (!obj)
|
||||
return NULL;
|
||||
blockPob = js_NewParsedObjectBox(cx, tc->parseContext, obj);
|
||||
if (!blockPob)
|
||||
blockpob = js_NewParsedObjectBox(cx, tc->parseContext, obj);
|
||||
if (!blockpob)
|
||||
return NULL;
|
||||
|
||||
/*
|
||||
|
@ -3248,14 +3246,13 @@ Statement(JSContext *cx, JSTokenStream *ts, JSTreeContext *tc)
|
|||
*/
|
||||
JS_ASSERT(!(stmt->flags & SIF_SCOPE));
|
||||
stmt->flags |= SIF_SCOPE;
|
||||
if (stmt != *sip) {
|
||||
if (stmt != tc->topScopeStmt) {
|
||||
JS_ASSERT(!stmt->downScope);
|
||||
JS_ASSERT(stmt->type == STMT_BLOCK ||
|
||||
stmt->type == STMT_SWITCH ||
|
||||
stmt->type == STMT_TRY ||
|
||||
stmt->type == STMT_FINALLY);
|
||||
stmt->downScope = *sip;
|
||||
*sip = stmt;
|
||||
stmt->downScope = tc->topScopeStmt;
|
||||
tc->topScopeStmt = stmt;
|
||||
} else {
|
||||
JS_ASSERT(stmt->type == STMT_CATCH);
|
||||
JS_ASSERT(stmt->downScope);
|
||||
|
@ -3278,7 +3275,7 @@ Statement(JSContext *cx, JSTokenStream *ts, JSTreeContext *tc)
|
|||
pn1->pn_type = TOK_LEXICALSCOPE;
|
||||
pn1->pn_op = JSOP_LEAVEBLOCK;
|
||||
pn1->pn_pos = tc->blockNode->pn_pos;
|
||||
pn1->pn_pob = blockPob;
|
||||
pn1->pn_pob = blockpob;
|
||||
pn1->pn_expr = tc->blockNode;
|
||||
pn1->pn_slot = -1;
|
||||
tc->blockNode = pn1;
|
||||
|
|
|
@ -560,7 +560,8 @@ js_ReportCompileErrorNumber(JSContext *cx, JSTokenStream *ts, JSParseNode *pn,
|
|||
goto report;
|
||||
tp = &pn->pn_pos;
|
||||
} else {
|
||||
tp = &ts->tokens[(ts->cursor+ts->lookahead) & NTOKENS_MASK].pos;
|
||||
/* Point to the current token, not the next one to get. */
|
||||
tp = &ts->tokens[ts->cursor].pos;
|
||||
}
|
||||
report.lineno = ts->lineno;
|
||||
linelength = PTRDIFF(ts->linebuf.limit, ts->linebuf.base, jschar);
|
||||
|
|
Загрузка…
Ссылка в новой задаче