diff --git a/js/src/js.c b/js/src/js.c index 559af6059bb6..dadd75d7dd74 100644 --- a/js/src/js.c +++ b/js/src/js.c @@ -942,12 +942,6 @@ GetSwitchTableBounds(JSScript *script, uintN offset, } -/* - * SrcNotes assumes that SRC_METHODBASE should be distinguished from SRC_LABEL - * using the bytecode the source note points to. - */ -JS_STATIC_ASSERT(SRC_LABEL == SRC_METHODBASE); - static void SrcNotes(JSContext *cx, JSScript *script) { @@ -955,7 +949,6 @@ SrcNotes(JSContext *cx, JSScript *script) jssrcnote *notes, *sn; JSSrcNoteType type; const char *name; - JSOp op; jsatomid atomIndex; JSAtom *atom; @@ -969,18 +962,11 @@ SrcNotes(JSContext *cx, JSScript *script) type = (JSSrcNoteType) SN_TYPE(sn); name = js_SrcNoteSpec[type].name; if (type == SRC_LABEL) { - /* Heavily overloaded case. */ + /* Check if the source note is for a switch case. */ if (switchTableStart <= offset && offset < switchTableEnd) { name = "case"; } else { - op = script->code[offset]; - if (op == JSOP_GETMETHOD || op == JSOP_SETMETHOD) { - /* This is SRC_METHODBASE which we print as SRC_PCBASE. */ - type = SRC_PCBASE; - name = "methodbase"; - } else { - JS_ASSERT(op == JSOP_NOP); - } + JS_ASSERT(script->code[offset] == JSOP_NOP); } } fprintf(gOutFile, "%3u: %5u [%4u] %-8s", diff --git a/js/src/jsemit.c b/js/src/jsemit.c index cad8777699e0..0b96c74f268a 100644 --- a/js/src/jsemit.c +++ b/js/src/jsemit.c @@ -2276,25 +2276,6 @@ CheckSideEffects(JSContext *cx, JSTreeContext *tc, JSParseNode *pn, return ok; } -/* - * Secret handshake with js_EmitTree's TOK_LP/TOK_NEW case logic, to flag all - * uses of JSOP_GETMETHOD that implicitly qualify the method property's name - * with a function:: prefix. All other JSOP_GETMETHOD and JSOP_SETMETHOD uses - * must be explicit, so we need a distinct source note (SRC_METHODBASE rather - * than SRC_PCBASE) for round-tripping through the beloved decompiler. - */ -#define JSPROP_IMPLICIT_FUNCTION_NAMESPACE 0x100 - -static jssrcnote -SrcNoteForPropOp(JSParseNode *pn, JSOp op) -{ - return ((op == JSOP_GETMETHOD && - !(pn->pn_attrs & JSPROP_IMPLICIT_FUNCTION_NAMESPACE)) || - op == JSOP_SETMETHOD) - ? SRC_METHODBASE - : SRC_PCBASE; -} - static JSBool EmitPropOp(JSContext *cx, JSParseNode *pn, JSOp op, JSCodeGenerator *cg) { @@ -2374,7 +2355,7 @@ EmitPropOp(JSContext *cx, JSParseNode *pn, JSOp op, JSCodeGenerator *cg) do { /* Walk back up the list, emitting annotated name ops. */ - if (js_NewSrcNote2(cx, cg, SrcNoteForPropOp(pndot, pndot->pn_op), + if (js_NewSrcNote2(cx, cg, SRC_PCBASE, CG_OFFSET(cg) - pndown->pn_offset) < 0) { return JS_FALSE; } @@ -2391,7 +2372,7 @@ EmitPropOp(JSContext *cx, JSParseNode *pn, JSOp op, JSCodeGenerator *cg) return JS_FALSE; } - if (js_NewSrcNote2(cx, cg, SrcNoteForPropOp(pn, op), + if (js_NewSrcNote2(cx, cg, SRC_PCBASE, CG_OFFSET(cg) - pn2->pn_offset) < 0) { return JS_FALSE; } @@ -5396,8 +5377,7 @@ js_EmitTree(JSContext *cx, JSCodeGenerator *cg, JSParseNode *pn) pn2->pn_type != TOK_RB && pn2->pn_type != TOK_RC && #endif - js_NewSrcNote2(cx, cg, SrcNoteForPropOp(pn2, pn2->pn_op), - CG_OFFSET(cg) - top) < 0) { + js_NewSrcNote2(cx, cg, SRC_PCBASE, CG_OFFSET(cg) - top) < 0) { return JS_FALSE; } @@ -5832,16 +5812,15 @@ js_EmitTree(JSContext *cx, JSCodeGenerator *cg, JSParseNode *pn) * constructable object expression. * * For E4X, if this expression is a dotted member reference, select - * JSOP_GETMETHOD instead of JSOP_GETPROP. ECMA-357 separates XML + * JSOP_CALLPROP instead of JSOP_GETPROP. ECMA-357 separates XML * method lookup from the normal property id lookup done for native * objects. */ pn2 = pn->pn_head; #if JS_HAS_XML_SUPPORT - if (pn2->pn_type == TOK_DOT && pn2->pn_op != JSOP_GETMETHOD) { + if (pn2->pn_type == TOK_DOT) { JS_ASSERT(pn2->pn_op == JSOP_GETPROP); - pn2->pn_op = JSOP_GETMETHOD; - pn2->pn_attrs |= JSPROP_IMPLICIT_FUNCTION_NAMESPACE; + pn2->pn_op = JSOP_CALLPROP; } #endif if (!js_EmitTree(cx, cg, pn2)) diff --git a/js/src/jsemit.h b/js/src/jsemit.h index 90709c22ae95..7d36715d4b38 100644 --- a/js/src/jsemit.h +++ b/js/src/jsemit.h @@ -549,9 +549,6 @@ typedef enum JSSrcNoteType { SRC_PCBASE = 12, /* distance back from annotated getprop or setprop op to left-most obj.prop.subprop bytecode -- always a backward delta */ - SRC_METHODBASE = 13, /* SRC_PCBASE variant for obj.function::foo - gets and sets; disjoint from SRC_LABEL by - bytecode to which it applies */ SRC_LABEL = 13, /* JSOP_NOP for label: with atomid immediate */ SRC_LABELBRACE = 14, /* JSOP_NOP for label: {...} begin brace */ SRC_ENDBRACE = 15, /* JSOP_NOP for label: {...} end brace */ diff --git a/js/src/jsinterp.c b/js/src/jsinterp.c index bc2fddd9de99..bd499ab7470c 100644 --- a/js/src/jsinterp.c +++ b/js/src/jsinterp.c @@ -639,7 +639,7 @@ NoSuchMethod(JSContext *cx, JSStackFrame *fp, jsval *vp, uint32 flags, case JSOP_NAME: case JSOP_GETPROP: #if JS_HAS_XML_SUPPORT - case JSOP_GETMETHOD: + case JSOP_CALLPROP: #endif atom = js_GetAtomFromBytecode(fp->script, pc, 0); argc = *argcp; @@ -1965,11 +1965,19 @@ InternNonIntElementId(JSContext *cx, jsval idval, jsid *idp) } #if JS_HAS_XML_SUPPORT +static JSBool +InternNonXmlObjectId(JSContext *cx, JSObject *obj, jsid *idp) +{ + if (!js_IsFunctionQName(cx, obj, idp)) + return JS_FALSE; + return *idp != 0 || InternStringElementId(cx, OBJECT_TO_JSVAL(obj), idp); +} + #define CHECK_ELEMENT_ID(obj, id) \ JS_BEGIN_MACRO \ if (JSID_IS_OBJECT(id) && !OBJECT_IS_XML(cx, obj)) { \ SAVE_SP_AND_PC(fp); \ - ok = InternStringElementId(cx, OBJECT_JSID_TO_JSVAL(id), &id); \ + ok = InternNonXmlObjectId(cx, JSID_TO_OBJECT(id), &id); \ if (!ok) \ goto out; \ } \ @@ -5760,7 +5768,7 @@ interrupt: STORE_OPND(-1, OBJECT_TO_JSVAL(obj)); END_CASE(JSOP_XMLPI) - BEGIN_CASE(JSOP_GETMETHOD) + BEGIN_CASE(JSOP_CALLPROP) /* Get an immediate atom naming the property. */ LOAD_ATOM(0); id = ATOM_TO_JSID(atom); @@ -5806,31 +5814,7 @@ interrupt: if (!ok) goto out; STORE_OPND(-1, rval); - END_CASE(JSOP_GETMETHOD) - - BEGIN_CASE(JSOP_SETMETHOD) - /* Get an immediate atom naming the property. */ - LOAD_ATOM(0); - id = ATOM_TO_JSID(atom); - rval = FETCH_OPND(-1); - FETCH_OBJECT(cx, -2, lval, obj); - SAVE_SP_AND_PC(fp); - - /* Special-case XML object method lookup, per ECMA-357. */ - if (OBJECT_IS_XML(cx, obj)) { - JSXMLObjectOps *ops; - - ops = (JSXMLObjectOps *) obj->map->ops; - ok = ops->setMethod(cx, obj, id, &rval); - } else { - ok = OBJ_SET_PROPERTY(cx, obj, id, &rval); - } - if (!ok) - goto out; - --sp; - STORE_OPND(-1, rval); - obj = NULL; - END_CASE(JSOP_SETMETHOD) + END_CASE(JSOP_CALLPROP) BEGIN_CASE(JSOP_GETFUNNS) SAVE_SP_AND_PC(fp); @@ -6063,6 +6047,7 @@ interrupt: #if JS_THREADED_INTERP L_JSOP_BACKPATCH: L_JSOP_BACKPATCH_POP: + L_JSOP_UNUSED194: L_JSOP_UNUSED197: #else default: diff --git a/js/src/jsopcode.c b/js/src/jsopcode.c index 41b1eeb3fc52..0558e25ff011 100644 --- a/js/src/jsopcode.c +++ b/js/src/jsopcode.c @@ -3273,14 +3273,15 @@ Decompile(SprintStack *ss, jsbytecode *pc, intN nb) (void) PopOff(ss, lastop); /* FALL THROUGH */ +#if JS_HAS_XML_SUPPORT + case JSOP_CALLPROP: +#endif case JSOP_GETPROP: case JSOP_GETXPROP: LOAD_ATOM(0); do_getprop: GET_QUOTE_AND_FMT(index_format, dot_format, rval); - - do_getprop_lval: lval = POP_STR(); todo = Sprint(&ss->sprinter, fmt, lval, rval); break; @@ -3311,31 +3312,9 @@ Decompile(SprintStack *ss, jsbytecode *pc, intN nb) return NULL; goto do_getprop; -#if JS_HAS_XML_SUPPORT - BEGIN_LITOPX_CASE(JSOP_GETMETHOD, 0) - sn = js_GetSrcNote(jp->script, pc); - if (sn && SN_TYPE(sn) == SRC_PCBASE) - goto do_getprop; - GET_QUOTE_AND_FMT("%s.function::[%s]", "%s.function::%s", rval); - goto do_getprop_lval; - - BEGIN_LITOPX_CASE(JSOP_SETMETHOD, 0) - sn = js_GetSrcNote(jp->script, pc); - if (sn && SN_TYPE(sn) == SRC_PCBASE) - goto do_setprop; - GET_QUOTE_AND_FMT("%s.function::[%s] %s= %s", - "%s.function::%s %s= %s", - xval); - goto do_setprop_rval; -#endif - case JSOP_SETPROP: LOAD_ATOM(0); - - do_setprop: GET_QUOTE_AND_FMT("%s[%s] %s= %s", "%s.%s %s= %s", xval); - - do_setprop_rval: rval = POP_STR(); /* diff --git a/js/src/jsopcode.tbl b/js/src/jsopcode.tbl index 3dc3e4316858..849d12fcd67a 100644 --- a/js/src/jsopcode.tbl +++ b/js/src/jsopcode.tbl @@ -401,7 +401,7 @@ OPDEF(JSOP_XMLOBJECT, 180,"xmlobject", NULL, 3, 0, 1, 19, JOF_CONST) OPDEF(JSOP_XMLCDATA, 181,"xmlcdata", NULL, 3, 0, 1, 19, JOF_CONST) OPDEF(JSOP_XMLCOMMENT, 182,"xmlcomment", NULL, 3, 0, 1, 19, JOF_CONST) OPDEF(JSOP_XMLPI, 183,"xmlpi", NULL, 3, 1, 1, 19, JOF_CONST) -OPDEF(JSOP_GETMETHOD, 184,"getmethod", NULL, 3, 1, 1, 18, JOF_CONST|JOF_PROP) +OPDEF(JSOP_CALLPROP, 184,"callprop", NULL, 3, 1, 1, 18, JOF_CONST|JOF_PROP) OPDEF(JSOP_GETFUNNS, 185,"getfunns", NULL, 1, 0, 1, 19, JOF_BYTE) OPDEF(JSOP_FOREACH, 186,"foreach", NULL, 1, 1, 1, 0, JOF_BYTE) OPDEF(JSOP_DELDESC, 187,"deldesc", NULL, 1, 2, 1, 17, JOF_BYTE |JOF_ELEM|JOF_DEL) @@ -426,7 +426,7 @@ OPDEF(JSOP_RESETBASE0, 191,"resetbase0", NULL, 1, 0, 0, 0, JOF_BYTE) */ OPDEF(JSOP_STARTXML, 192,"startxml", NULL, 1, 0, 0, 0, JOF_BYTE) OPDEF(JSOP_STARTXMLEXPR, 193,"startxmlexpr",NULL, 1, 0, 0, 0, JOF_BYTE) -OPDEF(JSOP_SETMETHOD, 194,"setmethod", NULL, 3, 2, 1, 3, JOF_CONST|JOF_PROP|JOF_SET|JOF_ASSIGNING|JOF_DETECTING) +OPDEF(JSOP_UNUSED194, 194,"", NULL, 1, 0, 0, 0, 0) /* * Stop interpretation, emitted at end of script to save the threaded bytecode diff --git a/js/src/jsparse.c b/js/src/jsparse.c index 3934144fa168..aa451751d770 100644 --- a/js/src/jsparse.c +++ b/js/src/jsparse.c @@ -3810,9 +3810,7 @@ AssignExpr(JSContext *cx, JSTokenStream *ts, JSTreeContext *tc) tc->flags |= TCF_FUN_HEAVYWEIGHT; break; case TOK_DOT: - pn2->pn_op = (pn2->pn_op == JSOP_GETMETHOD) - ? JSOP_SETMETHOD - : JSOP_SETPROP; + pn2->pn_op = JSOP_SETPROP; break; case TOK_LB: pn2->pn_op = JSOP_SETELEM; @@ -4315,11 +4313,8 @@ MemberExpr(JSContext *cx, JSTokenStream *ts, JSTreeContext *tc, if (!pn3) return NULL; tt = pn3->pn_type; - if (tt == TOK_NAME || - (tt == TOK_DBLCOLON && - pn3->pn_arity == PN_NAME && - pn3->pn_expr->pn_type == TOK_FUNCTION)) { - pn2->pn_op = (tt == TOK_NAME) ? JSOP_GETPROP : JSOP_GETMETHOD; + if (tt == TOK_NAME) { + pn2->pn_op = JSOP_GETPROP; pn2->pn_expr = pn; pn2->pn_atom = pn3->pn_atom; RecycleTree(pn3, tc); diff --git a/js/src/jsxml.c b/js/src/jsxml.c index 0ec3e84542be..5f22d6a866ba 100644 --- a/js/src/jsxml.c +++ b/js/src/jsxml.c @@ -3110,6 +3110,34 @@ ReportBadXMLName(JSContext *cx, jsval id) js_ReportValueError(cx, JSMSG_BAD_XML_NAME, JSDVG_IGNORE_STACK, id, NULL); } +static JSBool +IsFunctionQName(JSContext *cx, JSXMLQName *qn, jsid *funidp) +{ + JSAtom *atom; + + atom = cx->runtime->atomState.lazy.functionNamespaceURIAtom; + if (qn->uri && atom && + (qn->uri == ATOM_TO_STRING(atom) || + js_EqualStrings(qn->uri, ATOM_TO_STRING(atom)))) { + return JS_ValueToId(cx, STRING_TO_JSVAL(qn->localName), funidp); + } + *funidp = 0; + return JS_TRUE; +} + +JSBool +js_IsFunctionQName(JSContext *cx, JSObject *obj, jsid *funidp) +{ + JSXMLQName *qn; + + if (OBJ_GET_CLASS(cx, obj) == &js_QNameClass.base) { + qn = (JSXMLQName *) JS_GetPrivate(cx, obj); + return IsFunctionQName(cx, qn, funidp); + } + *funidp = 0; + return JS_TRUE; +} + static JSXMLQName * ToXMLName(JSContext *cx, jsval v, jsid *funidp) { @@ -3118,7 +3146,6 @@ ToXMLName(JSContext *cx, jsval v, jsid *funidp) JSClass *clasp; uint32 index; JSXMLQName *qn; - JSAtom *atom; if (JSVAL_IS_STRING(v)) { name = JSVAL_TO_STRING(v); @@ -3173,15 +3200,8 @@ construct: out: qn = (JSXMLQName *) JS_GetPrivate(cx, obj); - atom = cx->runtime->atomState.lazy.functionNamespaceURIAtom; - if (qn->uri && atom && - (qn->uri == ATOM_TO_STRING(atom) || - js_EqualStrings(qn->uri, ATOM_TO_STRING(atom)))) { - if (!JS_ValueToId(cx, STRING_TO_JSVAL(qn->localName), funidp)) - return NULL; - } else { - *funidp = 0; - } + if (!IsFunctionQName(cx, qn, funidp)) + return NULL; return qn; bad: diff --git a/js/src/jsxml.h b/js/src/jsxml.h index 71e591acc57a..7df247e4a54b 100644 --- a/js/src/jsxml.h +++ b/js/src/jsxml.h @@ -253,6 +253,13 @@ js_InitXMLClasses(JSContext *cx, JSObject *obj); extern JSBool js_GetFunctionNamespace(JSContext *cx, jsval *vp); +/* + * If obj is QName corresponding to function::name, set *funidp to name's id, + * otherwise set *funidp to 0. + */ +JSBool +js_IsFunctionQName(JSContext *cx, JSObject *obj, jsid *funidp); + extern JSBool js_GetDefaultXMLNamespace(JSContext *cx, jsval *vp);