зеркало из 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_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_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_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")
|
||||||
|
|
|
@ -66,10 +66,10 @@ typedef enum JSStmtType {
|
||||||
STMT_LABEL, /* labeled statement: L: s */
|
STMT_LABEL, /* labeled statement: L: s */
|
||||||
STMT_IF, /* if (then) statement */
|
STMT_IF, /* if (then) statement */
|
||||||
STMT_ELSE, /* else clause of if statement */
|
STMT_ELSE, /* else clause of if statement */
|
||||||
|
STMT_SWITCH, /* switch statement */
|
||||||
STMT_BODY, /* synthetic body of function with
|
STMT_BODY, /* synthetic body of function with
|
||||||
destructuring formal parameters */
|
destructuring formal parameters */
|
||||||
STMT_BLOCK, /* compound statement: { s1[;... sN] } */
|
STMT_BLOCK, /* compound statement: { s1[;... sN] } */
|
||||||
STMT_SWITCH, /* switch statement */
|
|
||||||
STMT_WITH, /* with statement */
|
STMT_WITH, /* with statement */
|
||||||
STMT_CATCH, /* catch block */
|
STMT_CATCH, /* catch block */
|
||||||
STMT_TRY, /* try block */
|
STMT_TRY, /* try block */
|
||||||
|
@ -87,18 +87,16 @@ typedef enum JSStmtType {
|
||||||
* A comment on the encoding of the JSStmtType enum and type-testing macros:
|
* 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
|
* 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
|
* become, a lexical scope. Per the proposed JS2/ES4 spec, it includes only
|
||||||
* low-numbered "maybe" scope types) and excludes with (with has dynamic scope
|
* syntactic blocks: block statements and try/catch/finally statements.
|
||||||
* pending the "reformed with" in ES4/JS2). It includes all try-catch-finally
|
|
||||||
* types, which are high-numbered maybe-scope types.
|
|
||||||
*
|
*
|
||||||
* STMT_TYPE_LINKS_SCOPE tells whether a JSStmtInfo of the given type eagerly
|
* 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
|
* links to other scoping statement info records. It excludes the the "maybe"
|
||||||
* "maybe" types, block and switch, as well as the try and both finally types,
|
* type, block, as well as the try and both finally types, since try and the
|
||||||
* since try and the other trailing maybe-scope types don't need block scope
|
* other trailing maybe-scope types don't need block scope unless they contain
|
||||||
* unless they contain let declarations.
|
* let declarations.
|
||||||
*
|
*
|
||||||
* We treat with as a static scope because it prevents lexical binding from
|
* We treat WITH as a static scope because it prevents lexical binding from
|
||||||
* continuing further up the static scope chain. With the "reformed with"
|
* continuing further up the static scope chain. With the "reformed with"
|
||||||
* proposal for JS2, we'll be able to model it statically, too.
|
* proposal for JS2, we'll be able to model it statically, too.
|
||||||
*/
|
*/
|
||||||
|
|
|
@ -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 {
|
struct JSPrinter {
|
||||||
Sprinter sprinter; /* base class state */
|
Sprinter sprinter; /* base class state */
|
||||||
JSArenaPool pool; /* string allocation pool */
|
JSArenaPool pool; /* string allocation pool */
|
||||||
|
@ -625,10 +617,6 @@ struct JSPrinter {
|
||||||
jsbytecode *dvgfence; /* js_DecompileValueGenerator fencepost */
|
jsbytecode *dvgfence; /* js_DecompileValueGenerator fencepost */
|
||||||
JSFunction *fun; /* interpreted function */
|
JSFunction *fun; /* interpreted function */
|
||||||
JSAtom **localNames; /* argument and variable names */
|
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->grouped = (indent & JS_IN_GROUP_CONTEXT) != 0;
|
||||||
jp->script = NULL;
|
jp->script = NULL;
|
||||||
jp->dvgfence = NULL;
|
jp->dvgfence = NULL;
|
||||||
#if JS_HAS_BLOCK_SCOPE
|
|
||||||
jp->braceState = ALWAYS_BRACE;
|
|
||||||
jp->spaceOffset = -1;
|
|
||||||
#endif
|
|
||||||
jp->fun = fun;
|
jp->fun = fun;
|
||||||
if (!fun || !FUN_INTERPRETED(fun) || fun->nargs + fun->u.i.nvars == 0) {
|
if (!fun || !FUN_INTERPRETED(fun) || fun->nargs + fun->u.i.nvars == 0) {
|
||||||
jp->localNames = NULL;
|
jp->localNames = NULL;
|
||||||
|
@ -712,55 +696,6 @@ VarPrefix(jssrcnote *sn)
|
||||||
return "";
|
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
|
int
|
||||||
js_printf(JSPrinter *jp, const char *format, ...)
|
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 pretty-printing, expand magic tab into a run of jp->indent spaces. */
|
||||||
if (*format == '\t') {
|
if (*format == '\t') {
|
||||||
format++;
|
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)
|
if (jp->pretty && Sprint(&jp->sprinter, "%*s", jp->indent, "") < 0)
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
@ -1081,7 +976,7 @@ DecompileSwitch(SprintStack *ss, TableEntry *table, uintN tableLength,
|
||||||
off = isCondSwitch ? GetOff(ss, ss->top-1) : PopOff(ss, JSOP_NOP);
|
off = isCondSwitch ? GetOff(ss, ss->top-1) : PopOff(ss, JSOP_NOP);
|
||||||
lval = OFF2STR(&ss->sprinter, off);
|
lval = OFF2STR(&ss->sprinter, off);
|
||||||
|
|
||||||
js_printf(CLEAR_MAYBE_BRACE(jp), "\tswitch (%s) {\n", lval);
|
js_printf(jp, "\tswitch (%s) {\n", lval);
|
||||||
|
|
||||||
if (tableLength) {
|
if (tableLength) {
|
||||||
diff = table[0].offset - defaultOffset;
|
diff = table[0].offset - defaultOffset;
|
||||||
|
@ -1970,7 +1865,7 @@ Decompile(SprintStack *ss, jsbytecode *pc, intN nb, JSOp nextop)
|
||||||
tail = js_GetSrcNoteOffset(sn, 0) - 1;
|
tail = js_GetSrcNoteOffset(sn, 0) - 1;
|
||||||
LOCAL_ASSERT(pc[tail] == JSOP_IFNE ||
|
LOCAL_ASSERT(pc[tail] == JSOP_IFNE ||
|
||||||
pc[tail] == JSOP_IFNEX);
|
pc[tail] == JSOP_IFNEX);
|
||||||
js_printf(SET_MAYBE_BRACE(jp), "\tdo {\n");
|
js_printf(jp, "\tdo {\n");
|
||||||
jp->indent += 4;
|
jp->indent += 4;
|
||||||
DECOMPILE_CODE(pc, tail);
|
DECOMPILE_CODE(pc, tail);
|
||||||
jp->indent -= 4;
|
jp->indent -= 4;
|
||||||
|
@ -2012,7 +1907,7 @@ Decompile(SprintStack *ss, jsbytecode *pc, intN nb, JSOp nextop)
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Do the loop body. */
|
/* Do the loop body. */
|
||||||
js_printf(SET_MAYBE_BRACE(jp), ") {\n");
|
js_printf(jp, ") {\n");
|
||||||
jp->indent += 4;
|
jp->indent += 4;
|
||||||
oplen = (cond) ? js_CodeSpec[pc[cond]].length : 0;
|
oplen = (cond) ? js_CodeSpec[pc[cond]].length : 0;
|
||||||
DECOMPILE_CODE(pc + cond + oplen, next - cond - oplen);
|
DECOMPILE_CODE(pc + cond + oplen, next - cond - oplen);
|
||||||
|
@ -2030,7 +1925,7 @@ Decompile(SprintStack *ss, jsbytecode *pc, intN nb, JSOp nextop)
|
||||||
if (!rval)
|
if (!rval)
|
||||||
return NULL;
|
return NULL;
|
||||||
RETRACT(&ss->sprinter, rval);
|
RETRACT(&ss->sprinter, rval);
|
||||||
js_printf(CLEAR_MAYBE_BRACE(jp), "\t%s:\n", rval);
|
js_printf(jp, "\t%s:\n", rval);
|
||||||
jp->indent += 4;
|
jp->indent += 4;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
@ -2040,7 +1935,7 @@ Decompile(SprintStack *ss, jsbytecode *pc, intN nb, JSOp nextop)
|
||||||
if (!rval)
|
if (!rval)
|
||||||
return NULL;
|
return NULL;
|
||||||
RETRACT(&ss->sprinter, rval);
|
RETRACT(&ss->sprinter, rval);
|
||||||
js_printf(CLEAR_MAYBE_BRACE(jp), "\t%s: {\n", rval);
|
js_printf(jp, "\t%s: {\n", rval);
|
||||||
jp->indent += 4;
|
jp->indent += 4;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
@ -2069,7 +1964,7 @@ Decompile(SprintStack *ss, jsbytecode *pc, intN nb, JSOp nextop)
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case SRC_BRACE:
|
case SRC_BRACE:
|
||||||
js_printf(CLEAR_MAYBE_BRACE(jp), "\t{\n");
|
js_printf(jp, "\t{\n");
|
||||||
jp->indent += 4;
|
jp->indent += 4;
|
||||||
len = js_GetSrcNoteOffset(sn, 0);
|
len = js_GetSrcNoteOffset(sn, 0);
|
||||||
DECOMPILE_CODE(pc + oplen, len - oplen);
|
DECOMPILE_CODE(pc + oplen, len - oplen);
|
||||||
|
@ -2138,14 +2033,14 @@ Decompile(SprintStack *ss, jsbytecode *pc, intN nb, JSOp nextop)
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case JSOP_TRY:
|
case JSOP_TRY:
|
||||||
js_printf(CLEAR_MAYBE_BRACE(jp), "\ttry {\n");
|
js_printf(jp, "\ttry {\n");
|
||||||
jp->indent += 4;
|
jp->indent += 4;
|
||||||
todo = -2;
|
todo = -2;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case JSOP_FINALLY:
|
case JSOP_FINALLY:
|
||||||
jp->indent -= 4;
|
jp->indent -= 4;
|
||||||
js_printf(CLEAR_MAYBE_BRACE(jp), "\t} finally {\n");
|
js_printf(jp, "\t} finally {\n");
|
||||||
jp->indent += 4;
|
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,
|
* If control flow reaches this point with todo still -2,
|
||||||
* just print rval as an expression statement.
|
* just print rval as an expression statement.
|
||||||
*/
|
*/
|
||||||
if (todo == -2) {
|
if (todo == -2)
|
||||||
MAYBE_SET_DONT_BRACE(jp, pc, endpc, rval);
|
|
||||||
js_printf(jp, "\t%s;\n", rval);
|
js_printf(jp, "\t%s;\n", rval);
|
||||||
}
|
|
||||||
end_popn:
|
end_popn:
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -2378,8 +2271,7 @@ Decompile(SprintStack *ss, jsbytecode *pc, intN nb, JSOp nextop)
|
||||||
#endif
|
#endif
|
||||||
len = js_GetSrcNoteOffset(sn, 0);
|
len = js_GetSrcNoteOffset(sn, 0);
|
||||||
if (pc[len] == JSOP_LEAVEBLOCK) {
|
if (pc[len] == JSOP_LEAVEBLOCK) {
|
||||||
js_printf(CLEAR_MAYBE_BRACE(jp), "\tlet (%s) {\n",
|
js_printf(jp, "\tlet (%s) {\n", POP_STR());
|
||||||
POP_STR());
|
|
||||||
jp->indent += 4;
|
jp->indent += 4;
|
||||||
DECOMPILE_CODE(pc, len);
|
DECOMPILE_CODE(pc, len);
|
||||||
jp->indent -= 4;
|
jp->indent -= 4;
|
||||||
|
@ -2422,7 +2314,6 @@ Decompile(SprintStack *ss, jsbytecode *pc, intN nb, JSOp nextop)
|
||||||
* not appear in the decompiler's output.
|
* not appear in the decompiler's output.
|
||||||
*/
|
*/
|
||||||
if (*rval != '\0' && (rval[0] != '/' || rval[1] != '*')) {
|
if (*rval != '\0' && (rval[0] != '/' || rval[1] != '*')) {
|
||||||
MAYBE_SET_DONT_BRACE(jp, pc, endpc, rval);
|
|
||||||
js_printf(jp,
|
js_printf(jp,
|
||||||
(*rval == '{' ||
|
(*rval == '{' ||
|
||||||
(strncmp(rval, js_function_str, 8) == 0 &&
|
(strncmp(rval, js_function_str, 8) == 0 &&
|
||||||
|
@ -2451,7 +2342,7 @@ Decompile(SprintStack *ss, jsbytecode *pc, intN nb, JSOp nextop)
|
||||||
case JSOP_ENTERWITH:
|
case JSOP_ENTERWITH:
|
||||||
LOCAL_ASSERT(!js_GetSrcNote(jp->script, pc));
|
LOCAL_ASSERT(!js_GetSrcNote(jp->script, pc));
|
||||||
rval = POP_STR();
|
rval = POP_STR();
|
||||||
js_printf(SET_MAYBE_BRACE(jp), "\twith (%s) {\n", rval);
|
js_printf(jp, "\twith (%s) {\n", rval);
|
||||||
jp->indent += 4;
|
jp->indent += 4;
|
||||||
todo = Sprint(&ss->sprinter, with_cookie);
|
todo = Sprint(&ss->sprinter, with_cookie);
|
||||||
break;
|
break;
|
||||||
|
@ -2505,7 +2396,7 @@ Decompile(SprintStack *ss, jsbytecode *pc, intN nb, JSOp nextop)
|
||||||
switch (sn ? SN_TYPE(sn) : SRC_NULL) {
|
switch (sn ? SN_TYPE(sn) : SRC_NULL) {
|
||||||
#if JS_HAS_BLOCK_SCOPE
|
#if JS_HAS_BLOCK_SCOPE
|
||||||
case SRC_BRACE:
|
case SRC_BRACE:
|
||||||
js_printf(CLEAR_MAYBE_BRACE(jp), "\t{\n");
|
js_printf(jp, "\t{\n");
|
||||||
jp->indent += 4;
|
jp->indent += 4;
|
||||||
len = js_GetSrcNoteOffset(sn, 0);
|
len = js_GetSrcNoteOffset(sn, 0);
|
||||||
ok = Decompile(ss, pc + oplen, len - oplen, JSOP_NOP)
|
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:
|
case SRC_CATCH:
|
||||||
jp->indent -= 4;
|
jp->indent -= 4;
|
||||||
js_printf(CLEAR_MAYBE_BRACE(jp), "\t} catch (");
|
js_printf(jp, "\t} catch (");
|
||||||
|
|
||||||
pc2 = pc;
|
pc2 = pc;
|
||||||
pc += oplen;
|
pc += oplen;
|
||||||
|
@ -2862,7 +2753,7 @@ Decompile(SprintStack *ss, jsbytecode *pc, intN nb, JSOp nextop)
|
||||||
tail = js_GetSrcNoteOffset(sn, 0);
|
tail = js_GetSrcNoteOffset(sn, 0);
|
||||||
DECOMPILE_CODE(pc + cond, tail - cond);
|
DECOMPILE_CODE(pc + cond, tail - cond);
|
||||||
rval = POP_STR();
|
rval = POP_STR();
|
||||||
js_printf(SET_MAYBE_BRACE(jp), "\twhile (%s) {\n", rval);
|
js_printf(jp, "\twhile (%s) {\n", rval);
|
||||||
jp->indent += 4;
|
jp->indent += 4;
|
||||||
DECOMPILE_CODE(pc + oplen, cond - oplen);
|
DECOMPILE_CODE(pc + oplen, cond - oplen);
|
||||||
jp->indent -= 4;
|
jp->indent -= 4;
|
||||||
|
@ -2926,7 +2817,7 @@ Decompile(SprintStack *ss, jsbytecode *pc, intN nb, JSOp nextop)
|
||||||
return NULL;
|
return NULL;
|
||||||
AddParenSlop(ss);
|
AddParenSlop(ss);
|
||||||
} else {
|
} else {
|
||||||
js_printf(SET_MAYBE_BRACE(jp),
|
js_printf(jp,
|
||||||
elseif ? " if (%s) {\n" : "\tif (%s) {\n",
|
elseif ? " if (%s) {\n" : "\tif (%s) {\n",
|
||||||
rval);
|
rval);
|
||||||
jp->indent += 4;
|
jp->indent += 4;
|
||||||
|
@ -2961,7 +2852,7 @@ Decompile(SprintStack *ss, jsbytecode *pc, intN nb, JSOp nextop)
|
||||||
goto if_again;
|
goto if_again;
|
||||||
}
|
}
|
||||||
|
|
||||||
js_printf(SET_MAYBE_BRACE(jp), " {\n");
|
js_printf(jp, " {\n");
|
||||||
jp->indent += 4;
|
jp->indent += 4;
|
||||||
DECOMPILE_CODE(pc + oplen, len - oplen);
|
DECOMPILE_CODE(pc + oplen, len - oplen);
|
||||||
}
|
}
|
||||||
|
@ -3155,8 +3046,7 @@ Decompile(SprintStack *ss, jsbytecode *pc, intN nb, JSOp nextop)
|
||||||
AddParenSlop(ss);
|
AddParenSlop(ss);
|
||||||
DECOMPILE_CODE(pc + oplen, tail - oplen);
|
DECOMPILE_CODE(pc + oplen, tail - oplen);
|
||||||
} else {
|
} else {
|
||||||
js_printf(SET_MAYBE_BRACE(jp), "\t%s in %s) {\n",
|
js_printf(jp, "\t%s in %s) {\n", lval, rval);
|
||||||
lval, rval);
|
|
||||||
jp->indent += 4;
|
jp->indent += 4;
|
||||||
DECOMPILE_CODE(pc + oplen, tail - oplen);
|
DECOMPILE_CODE(pc + oplen, tail - oplen);
|
||||||
jp->indent -= 4;
|
jp->indent -= 4;
|
||||||
|
|
|
@ -2254,7 +2254,7 @@ PushLexicalScope(JSContext *cx, JSTokenStream *ts, JSTreeContext *tc,
|
||||||
{
|
{
|
||||||
JSParseNode *pn;
|
JSParseNode *pn;
|
||||||
JSObject *obj;
|
JSObject *obj;
|
||||||
JSParsedObjectBox *blockPob;
|
JSParsedObjectBox *blockpob;
|
||||||
|
|
||||||
pn = NewParseNode(cx, ts, PN_NAME, tc);
|
pn = NewParseNode(cx, ts, PN_NAME, tc);
|
||||||
if (!pn)
|
if (!pn)
|
||||||
|
@ -2264,14 +2264,14 @@ PushLexicalScope(JSContext *cx, JSTokenStream *ts, JSTreeContext *tc,
|
||||||
if (!obj)
|
if (!obj)
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|
||||||
blockPob = js_NewParsedObjectBox(cx, tc->parseContext, obj);
|
blockpob = js_NewParsedObjectBox(cx, tc->parseContext, obj);
|
||||||
if (!blockPob)
|
if (!blockpob)
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|
||||||
js_PushBlockScope(tc, stmtInfo, obj, -1);
|
js_PushBlockScope(tc, stmtInfo, obj, -1);
|
||||||
pn->pn_type = TOK_LEXICALSCOPE;
|
pn->pn_type = TOK_LEXICALSCOPE;
|
||||||
pn->pn_op = JSOP_LEAVEBLOCK;
|
pn->pn_op = JSOP_LEAVEBLOCK;
|
||||||
pn->pn_pob = blockPob;
|
pn->pn_pob = blockpob;
|
||||||
pn->pn_slot = -1;
|
pn->pn_slot = -1;
|
||||||
return pn;
|
return pn;
|
||||||
}
|
}
|
||||||
|
@ -3174,9 +3174,8 @@ Statement(JSContext *cx, JSTokenStream *ts, JSTreeContext *tc)
|
||||||
#if JS_HAS_BLOCK_SCOPE
|
#if JS_HAS_BLOCK_SCOPE
|
||||||
case TOK_LET:
|
case TOK_LET:
|
||||||
{
|
{
|
||||||
JSStmtInfo **sip;
|
|
||||||
JSObject *obj;
|
JSObject *obj;
|
||||||
JSParsedObjectBox *blockPob;
|
JSParsedObjectBox *blockpob;
|
||||||
|
|
||||||
/* Check for a let statement or let expression. */
|
/* Check for a let statement or let expression. */
|
||||||
if (js_PeekToken(cx, ts) == TOK_LP) {
|
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
|
* scope statement) then we also need to set tc->blockNode to be our
|
||||||
* TOK_LEXICALSCOPE.
|
* TOK_LEXICALSCOPE.
|
||||||
*/
|
*/
|
||||||
sip = &tc->topScopeStmt;
|
stmt = tc->topStmt;
|
||||||
for (stmt = tc->topStmt; stmt; stmt = stmt->down) {
|
if (stmt && !STMT_MAYBE_SCOPE(stmt)) {
|
||||||
if (STMT_MAYBE_SCOPE(stmt))
|
js_ReportCompileErrorNumber(cx, ts, NULL, JSREPORT_ERROR,
|
||||||
break;
|
JSMSG_LET_DECL_NOT_IN_BLOCK);
|
||||||
if (stmt == *sip)
|
return NULL;
|
||||||
sip = &stmt->downScope;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (stmt && (stmt->flags & SIF_SCOPE)) {
|
if (stmt && (stmt->flags & SIF_SCOPE)) {
|
||||||
|
@ -3236,8 +3234,8 @@ Statement(JSContext *cx, JSTokenStream *ts, JSTreeContext *tc)
|
||||||
obj = js_NewBlockObject(cx);
|
obj = js_NewBlockObject(cx);
|
||||||
if (!obj)
|
if (!obj)
|
||||||
return NULL;
|
return NULL;
|
||||||
blockPob = js_NewParsedObjectBox(cx, tc->parseContext, obj);
|
blockpob = js_NewParsedObjectBox(cx, tc->parseContext, obj);
|
||||||
if (!blockPob)
|
if (!blockpob)
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -3248,14 +3246,13 @@ Statement(JSContext *cx, JSTokenStream *ts, JSTreeContext *tc)
|
||||||
*/
|
*/
|
||||||
JS_ASSERT(!(stmt->flags & SIF_SCOPE));
|
JS_ASSERT(!(stmt->flags & SIF_SCOPE));
|
||||||
stmt->flags |= SIF_SCOPE;
|
stmt->flags |= SIF_SCOPE;
|
||||||
if (stmt != *sip) {
|
if (stmt != tc->topScopeStmt) {
|
||||||
JS_ASSERT(!stmt->downScope);
|
JS_ASSERT(!stmt->downScope);
|
||||||
JS_ASSERT(stmt->type == STMT_BLOCK ||
|
JS_ASSERT(stmt->type == STMT_BLOCK ||
|
||||||
stmt->type == STMT_SWITCH ||
|
|
||||||
stmt->type == STMT_TRY ||
|
stmt->type == STMT_TRY ||
|
||||||
stmt->type == STMT_FINALLY);
|
stmt->type == STMT_FINALLY);
|
||||||
stmt->downScope = *sip;
|
stmt->downScope = tc->topScopeStmt;
|
||||||
*sip = stmt;
|
tc->topScopeStmt = stmt;
|
||||||
} else {
|
} else {
|
||||||
JS_ASSERT(stmt->type == STMT_CATCH);
|
JS_ASSERT(stmt->type == STMT_CATCH);
|
||||||
JS_ASSERT(stmt->downScope);
|
JS_ASSERT(stmt->downScope);
|
||||||
|
@ -3278,7 +3275,7 @@ Statement(JSContext *cx, JSTokenStream *ts, JSTreeContext *tc)
|
||||||
pn1->pn_type = TOK_LEXICALSCOPE;
|
pn1->pn_type = TOK_LEXICALSCOPE;
|
||||||
pn1->pn_op = JSOP_LEAVEBLOCK;
|
pn1->pn_op = JSOP_LEAVEBLOCK;
|
||||||
pn1->pn_pos = tc->blockNode->pn_pos;
|
pn1->pn_pos = tc->blockNode->pn_pos;
|
||||||
pn1->pn_pob = blockPob;
|
pn1->pn_pob = blockpob;
|
||||||
pn1->pn_expr = tc->blockNode;
|
pn1->pn_expr = tc->blockNode;
|
||||||
pn1->pn_slot = -1;
|
pn1->pn_slot = -1;
|
||||||
tc->blockNode = pn1;
|
tc->blockNode = pn1;
|
||||||
|
|
|
@ -560,7 +560,8 @@ js_ReportCompileErrorNumber(JSContext *cx, JSTokenStream *ts, JSParseNode *pn,
|
||||||
goto report;
|
goto report;
|
||||||
tp = &pn->pn_pos;
|
tp = &pn->pn_pos;
|
||||||
} else {
|
} 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;
|
report.lineno = ts->lineno;
|
||||||
linelength = PTRDIFF(ts->linebuf.limit, ts->linebuf.base, jschar);
|
linelength = PTRDIFF(ts->linebuf.limit, ts->linebuf.base, jschar);
|
||||||
|
|
Загрузка…
Ссылка в новой задаче