From c01c46739f98fe13ebb666486d6d2baa6bcc9b05 Mon Sep 17 00:00:00 2001 From: "brendan%mozilla.org" Date: Thu, 8 Jun 2000 06:46:18 +0000 Subject: [PATCH] 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). --- js/src/jsemit.c | 15 +++------------ js/src/jsemit.h | 2 +- js/src/jsinterp.c | 13 ++++++++----- js/src/jsopcode.c | 32 ++++++++++++++++---------------- js/src/jsopcode.tbl | 1 + 5 files changed, 29 insertions(+), 34 deletions(-) diff --git a/js/src/jsemit.c b/js/src/jsemit.c index 7fe387cafb4..3509788b228 100644 --- a/js/src/jsemit.c +++ b/js/src/jsemit.c @@ -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 */ diff --git a/js/src/jsemit.h b/js/src/jsemit.h index 14357c4feb2..802b071c23b 100644 --- a/js/src/jsemit.h +++ b/js/src/jsemit.h @@ -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 */ diff --git a/js/src/jsinterp.c b/js/src/jsinterp.c index 99701b0092c..58fd557dd45 100644 --- a/js/src/jsinterp.c +++ b/js/src/jsinterp.c @@ -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)); diff --git a/js/src/jsopcode.c b/js/src/jsopcode.c index acd917ee631..e26996fc178 100644 --- a/js/src/jsopcode.c +++ b/js/src/jsopcode.c @@ -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: diff --git a/js/src/jsopcode.tbl b/js/src/jsopcode.tbl index 0652f39e2d9..1d9799269f6 100644 --- a/js/src/jsopcode.tbl +++ b/js/src/jsopcode.tbl @@ -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)