зеркало из https://github.com/mozilla/gecko-dev.git
Bug 762473 - Don't apply non-reentrant-closure optimization when the scope is extensible (r=dvander)
--HG-- extra : rebase_source : e20cc5157607b72d8ecdd1fc4560373e0ad7060a
This commit is contained in:
Родитель
20cc12b099
Коммит
2271b34bbd
|
@ -34,6 +34,13 @@ MarkInnerAndOuterFunctions(JSContext *cx, JSScript* script_)
|
|||
JSScript *outer = worklist.back();
|
||||
worklist.popBack();
|
||||
|
||||
/*
|
||||
* If outer has an extensible scope, its slots may be resized which
|
||||
* will invalidate nesting->varArray/argArray.
|
||||
*/
|
||||
if (outer->funHasExtensibleScope)
|
||||
continue;
|
||||
|
||||
if (outer->hasObjects()) {
|
||||
ObjectArray *arr = outer->objects();
|
||||
|
||||
|
|
|
@ -0,0 +1,49 @@
|
|||
function f(i) {
|
||||
var a1,a2,a3,a4,a5,a6,a7,a8,a9,a10,a11,a12,a16,a17;
|
||||
var b = true;
|
||||
if (b)
|
||||
function f1() {}
|
||||
if (b)
|
||||
function f2() {}
|
||||
if (b)
|
||||
function f3() {}
|
||||
if (b)
|
||||
function f4() {}
|
||||
if (b)
|
||||
function f5() {}
|
||||
if (b)
|
||||
function f6() {}
|
||||
if (b)
|
||||
function f7() {}
|
||||
if (b)
|
||||
function f8() {}
|
||||
if (b)
|
||||
function f9() {}
|
||||
if (b)
|
||||
function f10() {}
|
||||
if (b)
|
||||
function f11() {}
|
||||
if (b)
|
||||
function f12() {}
|
||||
if (b)
|
||||
function f13() {}
|
||||
if (b)
|
||||
function f14() {}
|
||||
if (b)
|
||||
function f15() {}
|
||||
if (b)
|
||||
function f16() {}
|
||||
if (b)
|
||||
function f17() {}
|
||||
|
||||
a1 = i;
|
||||
|
||||
function f() {
|
||||
return a1;
|
||||
}
|
||||
|
||||
return f();
|
||||
}
|
||||
|
||||
for (var i = 0; i < 100; ++i)
|
||||
assertEq(f(i), i);
|
|
@ -5259,6 +5259,8 @@ NestingPrologue(JSContext *cx, StackFrame *fp)
|
|||
MarkTypeObjectFlags(cx, fp->fun(), OBJECT_FLAG_REENTRANT_FUNCTION);
|
||||
}
|
||||
|
||||
/* Extensibility guards in the frontend guarantee the slots won't move. */
|
||||
JS_ASSERT(!script->funHasExtensibleScope);
|
||||
nesting->activeCall = &fp->callObj();
|
||||
nesting->argArray = Valueify(nesting->activeCall->argArray());
|
||||
nesting->varArray = Valueify(nesting->activeCall->varArray());
|
||||
|
|
|
@ -374,6 +374,7 @@ js::XDRScript(XDRState<mode> *xdr, JSScript **scriptp, JSScript *parentScript)
|
|||
SavedCallerFun,
|
||||
StrictModeCode,
|
||||
ContainsDynamicNameAccess,
|
||||
FunHasExtensibleScope,
|
||||
ArgumentsHasLocalBinding,
|
||||
NeedsArgsObj,
|
||||
OwnFilename,
|
||||
|
@ -529,6 +530,8 @@ js::XDRScript(XDRState<mode> *xdr, JSScript **scriptp, JSScript *parentScript)
|
|||
scriptBits |= (1 << StrictModeCode);
|
||||
if (script->bindingsAccessedDynamically)
|
||||
scriptBits |= (1 << ContainsDynamicNameAccess);
|
||||
if (script->funHasExtensibleScope)
|
||||
scriptBits |= (1 << FunHasExtensibleScope);
|
||||
if (script->argumentsHasLocalBinding())
|
||||
scriptBits |= (1 << ArgumentsHasLocalBinding);
|
||||
if (script->analyzedArgsUsage() && script->needsArgsObj())
|
||||
|
@ -602,6 +605,8 @@ js::XDRScript(XDRState<mode> *xdr, JSScript **scriptp, JSScript *parentScript)
|
|||
script->strictModeCode = true;
|
||||
if (scriptBits & (1 << ContainsDynamicNameAccess))
|
||||
script->bindingsAccessedDynamically = true;
|
||||
if (scriptBits & (1 << FunHasExtensibleScope))
|
||||
script->funHasExtensibleScope = true;
|
||||
if (scriptBits & (1 << ArgumentsHasLocalBinding)) {
|
||||
PropertyName *arguments = cx->runtime->atomState.argumentsAtom;
|
||||
unsigned local;
|
||||
|
@ -1313,6 +1318,7 @@ JSScript::NewScriptFromEmitter(JSContext *cx, BytecodeEmitter *bce)
|
|||
script->savedCallerFun = true;
|
||||
}
|
||||
script->bindingsAccessedDynamically = bce->sc->bindingsAccessedDynamically();
|
||||
script->funHasExtensibleScope = bce->sc->funHasExtensibleScope();
|
||||
script->hasSingletons = bce->hasSingletons;
|
||||
#ifdef JS_METHODJIT
|
||||
if (cx->compartment->debugMode())
|
||||
|
@ -1820,6 +1826,7 @@ js::CloneScript(JSContext *cx, HandleScript src)
|
|||
dst->strictModeCode = src->strictModeCode;
|
||||
dst->compileAndGo = src->compileAndGo;
|
||||
dst->bindingsAccessedDynamically = src->bindingsAccessedDynamically;
|
||||
dst->funHasExtensibleScope = src->funHasExtensibleScope;
|
||||
dst->hasSingletons = src->hasSingletons;
|
||||
dst->isGenerator = src->isGenerator;
|
||||
|
||||
|
|
|
@ -526,6 +526,7 @@ struct JSScript : public js::gc::Cell
|
|||
bool strictModeCode:1; /* code is in strict mode */
|
||||
bool compileAndGo:1; /* see Parser::compileAndGo */
|
||||
bool bindingsAccessedDynamically:1; /* see ContextFlags' field of the same name */
|
||||
bool funHasExtensibleScope:1; /* see ContextFlags' field of the same name */
|
||||
bool warnedAboutTwoArgumentEval:1; /* have warned about use of
|
||||
obsolete eval(s, o) in
|
||||
this script */
|
||||
|
|
|
@ -25,7 +25,7 @@ namespace js {
|
|||
* and saved versions. If deserialization fails, the data should be
|
||||
* invalidated if possible.
|
||||
*/
|
||||
static const uint32_t XDR_BYTECODE_VERSION = uint32_t(0xb973c0de - 117);
|
||||
static const uint32_t XDR_BYTECODE_VERSION = uint32_t(0xb973c0de - 118);
|
||||
|
||||
class XDRBuffer {
|
||||
public:
|
||||
|
|
Загрузка…
Ссылка в новой задаче