Bug 786801 - js_InferFlags should not stop at compartment boundaries (r=bhackett)

--HG--
extra : rebase_source : 19804a0ae5802a3b8a5b540c4b840aa75f3f3223
This commit is contained in:
Luke Wagner 2012-09-04 14:31:04 -07:00
parent ebdf717cae
commit 499b6ddc0c
2 changed files with 25 additions and 16 deletions

View File

@ -22,6 +22,8 @@ Tests for document.all
<a id="id3">E</a>
<a id="id3">F</a>
</div>
<iframe id="subframe" src="data:text/html,<span id='x'></span>"
style="display: none"></iframe>
<pre id="test">
<script class="testbody" type="text/javascript">
@ -138,6 +140,14 @@ elementNames.forEach(function (name) {
});
is(hasName.length, 0, "found all names");
SimpleTest.waitForExplicitFinish();
addLoadEvent(function() {
var subdoc = $("subframe").contentDocument;
is(subdoc.all.x, subdoc.body.firstChild,
"document.all should work in a subdocument");
SimpleTest.finish();
});
// Utility functions
function rC(node) {
node.parentNode.removeChild(node);

View File

@ -2403,16 +2403,13 @@ js_CreateThisForFunction(JSContext *cx, HandleObject callee, bool newType)
* checking whether document.all is defined.
*/
static bool
Detecting(JSContext *cx, jsbytecode *pc)
Detecting(JSContext *cx, JSScript *script, jsbytecode *pc)
{
/* General case: a branch or equality op follows the access. */
JSOp op = JSOp(*pc);
if (js_CodeSpec[op].format & JOF_DETECTING)
return true;
JSAtom *atom;
JSScript *script = cx->stack.currentScript();
jsbytecode *endpc = script->code + script->length;
JS_ASSERT(script->code <= pc && pc < endpc);
@ -2434,7 +2431,7 @@ Detecting(JSContext *cx, jsbytecode *pc)
* about a local variable named |undefined| shadowing the immutable
* global binding...because, really?
*/
atom = script->getAtom(GET_UINT32_INDEX(pc));
JSAtom *atom = script->getAtom(GET_UINT32_INDEX(pc));
if (atom == cx->names().undefined &&
(pc += js_CodeSpec[op].length) < endpc) {
op = JSOp(*pc);
@ -2452,24 +2449,26 @@ Detecting(JSContext *cx, jsbytecode *pc)
unsigned
js_InferFlags(JSContext *cx, unsigned defaultFlags)
{
const JSCodeSpec *cs;
uint32_t format;
unsigned flags = 0;
jsbytecode *pc;
JSScript *script = cx->stack.currentScript(&pc);
if (!script || !pc)
/*
* Use ScriptFrameIter since we intentionally want to look across
* compartment boundaries in the case of cross-compartment property access.
*/
ScriptFrameIter i(cx);
if (i.done())
return defaultFlags;
cs = &js_CodeSpec[*pc];
format = cs->format;
jsbytecode *pc = i.pc();
JSScript *script = i.script();
const JSCodeSpec *cs = &js_CodeSpec[*pc];
uint32_t format = cs->format;
unsigned flags = 0;
if (JOF_MODE(format) != JOF_NAME)
flags |= JSRESOLVE_QUALIFIED;
if (format & JOF_SET) {
flags |= JSRESOLVE_ASSIGNING;
} else if (cs->length >= 0) {
pc += cs->length;
if (pc < script->code + script->length && Detecting(cx, pc))
if (pc < script->code + script->length && Detecting(cx, script, pc))
flags |= JSRESOLVE_DETECTING;
}
return flags;
@ -4330,7 +4329,7 @@ js_GetPropertyHelperInline(JSContext *cx, HandleObject obj, HandleObject receive
/* Do not warn about tests like (obj[prop] == undefined). */
if (cx->resolveFlags == RESOLVE_INFER) {
pc += js_CodeSpec[op].length;
if (Detecting(cx, pc))
if (Detecting(cx, script, pc))
return JS_TRUE;
} else if (cx->resolveFlags & JSRESOLVE_DETECTING) {
return JS_TRUE;