зеркало из https://github.com/mozilla/gecko-dev.git
Improve JSRESOLVE_DETECTING to handle typeof, ==, !=, etc.; don't give undefined property strict warning for detecting cases (253150, r=shaver).
This commit is contained in:
Родитель
d585c6199a
Коммит
652a45f1d5
|
@ -2380,6 +2380,59 @@ bad:
|
|||
return JS_FALSE;
|
||||
}
|
||||
|
||||
/*
|
||||
* Given pc pointing after a property accessing bytecode, return true if the
|
||||
* access is a "object-detecting" in the sense used by web pages, e.g., when
|
||||
* checking whether document.all is defined.
|
||||
*/
|
||||
static JSBool
|
||||
Detecting(JSContext *cx, jsbytecode *pc)
|
||||
{
|
||||
JSScript *script;
|
||||
jsbytecode *endpc;
|
||||
JSOp op;
|
||||
JSAtom *atom;
|
||||
|
||||
script = cx->fp->script;
|
||||
for (endpc = script->code + script->length; pc < endpc; pc++) {
|
||||
/* General case: a branch or equality op follows the access. */
|
||||
op = (JSOp) *pc;
|
||||
if (js_CodeSpec[op].format & JOF_DETECTING)
|
||||
return JS_TRUE;
|
||||
|
||||
/*
|
||||
* Special case #1: handle (document.all == null). Don't sweat about
|
||||
* JS1.2's revision of the equality operators here.
|
||||
*/
|
||||
if (op == JSOP_NULL) {
|
||||
if (++pc < endpc)
|
||||
return *pc == JSOP_EQ || *pc == JSOP_NE;
|
||||
break;
|
||||
}
|
||||
|
||||
/*
|
||||
* Special case #2: handle (document.all == undefined). Don't worry
|
||||
* about someone redefining undefined, which was added by Edition 3,
|
||||
* so was read/write for backward compatibility.
|
||||
*/
|
||||
if (op == JSOP_NAME) {
|
||||
atom = GET_ATOM(cx, script, pc);
|
||||
if (atom == cx->runtime->atomState.typeAtoms[JSTYPE_VOID] &&
|
||||
(pc += js_CodeSpec[op].length) < endpc) {
|
||||
op = (JSOp) *pc;
|
||||
return op == JSOP_EQ || op == JSOP_NE ||
|
||||
op == JSOP_NEW_EQ || op == JSOP_NEW_NE;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
/* At this point, anything but grouping means we're not detecting. */
|
||||
if (op != JSOP_GROUP)
|
||||
break;
|
||||
}
|
||||
return JS_FALSE;
|
||||
}
|
||||
|
||||
#if defined JS_THREADSAFE && defined DEBUG
|
||||
JS_FRIEND_API(JSBool)
|
||||
_js_LookupProperty(JSContext *cx, JSObject *obj, jsid id, JSObject **objp,
|
||||
|
@ -2466,9 +2519,7 @@ js_LookupProperty(JSContext *cx, JSObject *obj, jsid id, JSObject **objp,
|
|||
flags |= JSRESOLVE_ASSIGNING;
|
||||
} else {
|
||||
pc += cs->length;
|
||||
while (*pc == JSOP_GROUP)
|
||||
pc++;
|
||||
if (js_CodeSpec[*pc].format & JOF_DETECTING)
|
||||
if (Detecting(cx, pc))
|
||||
flags |= JSRESOLVE_DETECTING;
|
||||
}
|
||||
}
|
||||
|
@ -2695,21 +2746,15 @@ js_GetProperty(JSContext *cx, JSObject *obj, jsid id, jsval *vp)
|
|||
cx->fp && cx->fp->pc &&
|
||||
(*cx->fp->pc == JSOP_GETPROP || *cx->fp->pc == JSOP_GETELEM))
|
||||
{
|
||||
jsbytecode *pc, *endpc;
|
||||
jsbytecode *pc;
|
||||
JSString *str;
|
||||
|
||||
/* Kludge to allow (typeof foo == "undefined") tests. */
|
||||
JS_ASSERT(cx->fp->script);
|
||||
pc = cx->fp->pc;
|
||||
pc += js_CodeSpec[*pc].length;
|
||||
endpc = cx->fp->script->code + cx->fp->script->length;
|
||||
while (pc < endpc) {
|
||||
if (*pc == JSOP_TYPEOF)
|
||||
return JS_TRUE;
|
||||
if (*pc != JSOP_GROUP)
|
||||
break;
|
||||
pc++;
|
||||
}
|
||||
if (Detecting(cx, pc))
|
||||
return JS_TRUE;
|
||||
|
||||
/* Ok, bad undefined property reference: whine about it. */
|
||||
str = js_DecompileValueGenerator(cx, JSDVG_IGNORE_STACK,
|
||||
|
|
|
@ -93,8 +93,8 @@ OPDEF(JSOP_SETCONST, 14, "setconst", NULL, 3, 1, 1, 1, JOF_CONST|
|
|||
OPDEF(JSOP_BITOR, 15, "bitor", "|", 1, 2, 1, 2, JOF_BYTE|JOF_LEFTASSOC)
|
||||
OPDEF(JSOP_BITXOR, 16, "bitxor", "^", 1, 2, 1, 3, JOF_BYTE|JOF_LEFTASSOC)
|
||||
OPDEF(JSOP_BITAND, 17, "bitand", "&", 1, 2, 1, 4, JOF_BYTE|JOF_LEFTASSOC)
|
||||
OPDEF(JSOP_EQ, 18, "eq", "==", 1, 2, 1, 5, JOF_BYTE|JOF_LEFTASSOC)
|
||||
OPDEF(JSOP_NE, 19, "ne", "!=", 1, 2, 1, 5, JOF_BYTE|JOF_LEFTASSOC)
|
||||
OPDEF(JSOP_EQ, 18, "eq", "==", 1, 2, 1, 5, JOF_BYTE|JOF_LEFTASSOC|JOF_DETECTING)
|
||||
OPDEF(JSOP_NE, 19, "ne", "!=", 1, 2, 1, 5, JOF_BYTE|JOF_LEFTASSOC|JOF_DETECTING)
|
||||
OPDEF(JSOP_LT, 20, "lt", "<", 1, 2, 1, 6, JOF_BYTE|JOF_LEFTASSOC)
|
||||
OPDEF(JSOP_LE, 21, "le", "<=", 1, 2, 1, 6, JOF_BYTE|JOF_LEFTASSOC)
|
||||
OPDEF(JSOP_GT, 22, "gt", ">", 1, 2, 1, 6, JOF_BYTE|JOF_LEFTASSOC)
|
||||
|
@ -114,7 +114,7 @@ OPDEF(JSOP_NEW, 35, js_new_str, NULL, 3, -1, 1, 10, JOF_UINT16
|
|||
OPDEF(JSOP_DELNAME, 36, "delname", NULL, 3, 0, 1, 10, JOF_CONST|JOF_NAME|JOF_DEL)
|
||||
OPDEF(JSOP_DELPROP, 37, "delprop", NULL, 3, 1, 1, 10, JOF_CONST|JOF_PROP|JOF_DEL)
|
||||
OPDEF(JSOP_DELELEM, 38, "delelem", NULL, 1, 2, 1, 10, JOF_BYTE |JOF_ELEM|JOF_DEL)
|
||||
OPDEF(JSOP_TYPEOF, 39, js_typeof_str,NULL, 1, 1, 1, 10, JOF_BYTE)
|
||||
OPDEF(JSOP_TYPEOF, 39, js_typeof_str,NULL, 1, 1, 1, 10, JOF_BYTE|JOF_DETECTING)
|
||||
OPDEF(JSOP_VOID, 40, js_void_str, NULL, 1, 1, 1, 10, JOF_BYTE)
|
||||
OPDEF(JSOP_INCNAME, 41, "incname", NULL, 3, 0, 1, 10, JOF_CONST|JOF_NAME|JOF_INC)
|
||||
OPDEF(JSOP_INCPROP, 42, "incprop", NULL, 3, 1, 1, 10, JOF_CONST|JOF_PROP|JOF_INC)
|
||||
|
@ -151,8 +151,8 @@ OPDEF(JSOP_TABLESWITCH, 70, "tableswitch", NULL, -1, 1, 0, 0, JOF_TABLES
|
|||
OPDEF(JSOP_LOOKUPSWITCH, 71, "lookupswitch", NULL, -1, 1, 0, 0, JOF_LOOKUPSWITCH)
|
||||
|
||||
/* New, infallible/transitive identity ops. */
|
||||
OPDEF(JSOP_NEW_EQ, 72, "eq", NULL, 1, 2, 1, 5, JOF_BYTE)
|
||||
OPDEF(JSOP_NEW_NE, 73, "ne", NULL, 1, 2, 1, 5, JOF_BYTE)
|
||||
OPDEF(JSOP_NEW_EQ, 72, "eq", NULL, 1, 2, 1, 5, JOF_BYTE|JOF_DETECTING)
|
||||
OPDEF(JSOP_NEW_NE, 73, "ne", NULL, 1, 2, 1, 5, JOF_BYTE|JOF_DETECTING)
|
||||
|
||||
/* Lexical closure constructor. */
|
||||
OPDEF(JSOP_CLOSURE, 74, "closure", NULL, 3, 0, 0, 0, JOF_CONST)
|
||||
|
|
Загрузка…
Ссылка в новой задаче