зеркало из https://github.com/mozilla/pjs.git
Comply with weird ECMA nit: call (o.f)() (note parens around the function expression) must bind 'this' to the global object, not to o\! (41864, r=shaver).
This commit is contained in:
Родитель
3d1f6ab8b8
Коммит
c01c46739f
|
@ -2392,20 +2392,11 @@ js_EmitTree(JSContext *cx, JSCodeGenerator *cg, JSParseNode *pn)
|
|||
* The node for (e) has e as its kid, enabling users who want to nest
|
||||
* assignment expressions in conditions to avoid the error correction
|
||||
* done by Condition (from x = y to x == y) by double-parenthesizing.
|
||||
*
|
||||
* We also emit an annotated NOP so we can decompile user parentheses,
|
||||
* but that's just a nicety (the decompiler does not preserve comments
|
||||
* or white space, and it parenthesizes for correct precedence anyway,
|
||||
* so this nop nicety should be considered with a cold eye, especially
|
||||
* if another srcnote type is needed).
|
||||
*/
|
||||
if (!js_EmitTree(cx, cg, pn->pn_kid))
|
||||
return JS_FALSE;
|
||||
|
||||
if (js_NewSrcNote(cx, cg, SRC_PAREN) < 0 ||
|
||||
js_Emit1(cx, cg, JSOP_NOP) < 0) {
|
||||
if (js_Emit1(cx, cg, JSOP_GROUP) < 0)
|
||||
return JS_FALSE;
|
||||
}
|
||||
break;
|
||||
|
||||
case TOK_NAME:
|
||||
|
@ -2467,7 +2458,7 @@ JS_FRIEND_DATA(const char *) js_SrcNoteName[] = {
|
|||
"pcdelta",
|
||||
"assignop",
|
||||
"cond",
|
||||
"paren",
|
||||
"reserved0",
|
||||
"hidden",
|
||||
"pcbase",
|
||||
"label",
|
||||
|
@ -2499,7 +2490,7 @@ uint8 js_SrcNoteArity[] = {
|
|||
1, /* SRC_PCDELTA */
|
||||
0, /* SRC_ASSIGNOP */
|
||||
0, /* SRC_COND */
|
||||
0, /* SRC_PAREN */
|
||||
0, /* SRC_RESERVED0 */
|
||||
0, /* SRC_HIDDEN */
|
||||
1, /* SRC_PCBASE */
|
||||
1, /* SRC_LABEL */
|
||||
|
|
|
@ -300,7 +300,7 @@ typedef enum JSSrcNoteType {
|
|||
or from CONDSWITCH to first CASE opcode */
|
||||
SRC_ASSIGNOP = 8, /* += or another assign-op follows */
|
||||
SRC_COND = 9, /* JSOP_IFEQ is from conditional ?: operator */
|
||||
SRC_PAREN = 10, /* JSOP_NOP generated to mark user parens */
|
||||
SRC_RESERVED0 = 10, /* reserved for future use */
|
||||
SRC_HIDDEN = 11, /* opcode shouldn't be decompiled */
|
||||
SRC_PCBASE = 12, /* offset of first obj.prop.subprop bytecode */
|
||||
SRC_LABEL = 13, /* JSOP_NOP for label: with atomid immediate */
|
||||
|
|
|
@ -1207,6 +1207,10 @@ js_Interpret(JSContext *cx, jsval *result)
|
|||
case JSOP_NOP:
|
||||
break;
|
||||
|
||||
case JSOP_GROUP:
|
||||
obj = NULL;
|
||||
break;
|
||||
|
||||
case JSOP_PUSH:
|
||||
PUSH_OPND(JSVAL_VOID);
|
||||
break;
|
||||
|
@ -1347,12 +1351,11 @@ js_Interpret(JSContext *cx, jsval *result)
|
|||
#endif
|
||||
|
||||
case JSOP_TOOBJECT:
|
||||
rval = POP();
|
||||
SAVE_SP(fp);
|
||||
ok = js_ValueToObject(cx, rval, &obj);
|
||||
ok = js_ValueToObject(cx, sp[-1], &obj);
|
||||
if (!ok)
|
||||
goto out;
|
||||
PUSH(OBJECT_TO_JSVAL(obj));
|
||||
sp[-1] = OBJECT_TO_JSVAL(obj);
|
||||
break;
|
||||
|
||||
#define POP_ELEMENT_ID(id) { \
|
||||
|
@ -1373,7 +1376,7 @@ js_Interpret(JSContext *cx, jsval *result)
|
|||
#if JS_HAS_IN_OPERATOR
|
||||
case JSOP_IN:
|
||||
rval = POP();
|
||||
if (!JSVAL_IS_OBJECT(rval) || rval == JSVAL_NULL) {
|
||||
if (JSVAL_IS_PRIMITIVE(rval)) {
|
||||
JS_ReportErrorNumber(cx, js_GetErrorMessage, NULL,
|
||||
JSMSG_IN_NOT_OBJECT);
|
||||
ok = JS_FALSE;
|
||||
|
@ -2507,7 +2510,7 @@ js_Interpret(JSContext *cx, jsval *result)
|
|||
PUSH_OPND(JSVAL_VOID);
|
||||
goto advance_pc;
|
||||
}
|
||||
if (op2 != JSOP_NOP)
|
||||
if (op2 != JSOP_GROUP)
|
||||
break;
|
||||
}
|
||||
js_ReportIsNotDefined(cx, ATOM_BYTES(atom));
|
||||
|
|
|
@ -888,26 +888,13 @@ Decompile(SprintStack *ss, jsbytecode *pc, intN nb)
|
|||
switch (op) {
|
||||
case JSOP_NOP:
|
||||
/*
|
||||
* Check for extra user parenthesization, a do-while loop,
|
||||
* a for-loop with an empty initializer part, a labeled
|
||||
* statement, a function definition, or try/finally.
|
||||
* 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) {
|
||||
case SRC_PAREN:
|
||||
/* 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;
|
||||
|
||||
#if JS_HAS_DO_WHILE_LOOP
|
||||
case SRC_WHILE:
|
||||
js_printf(jp, "\tdo {\n"); /* balance} */
|
||||
|
@ -1033,6 +1020,19 @@ Decompile(SprintStack *ss, jsbytecode *pc, intN nb)
|
|||
}
|
||||
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:
|
||||
|
|
|
@ -268,3 +268,4 @@ OPDEF(JSOP_NAMEDFUNOBJ, 129, "namedfunobj", NULL, 3, 0, 1, 12, JOF_CONST)
|
|||
|
||||
/* Like JSOP_INITPROP, but specialized to make a DontDelete property for ECMA ed. 3 catch variables. */
|
||||
OPDEF(JSOP_INITCATCHVAR,130, "initcatchvar",NULL, 3, 1, 0, 0, JOF_CONST|JOF_PROP)
|
||||
OPDEF(JSOP_GROUP, 131, "group", NULL, 1, 0, 0, 0, JOF_BYTE)
|
||||
|
|
Загрузка…
Ссылка в новой задаче