Bug 1089761 - Fix initializing lexicals to throw on touch on CallObject. (r=jandem,Waldo)

This commit is contained in:
Shu-yu Guo 2014-10-29 19:41:42 -07:00
parent 6440005c47
commit 3911713b43
7 changed files with 53 additions and 21 deletions

View File

@ -0,0 +1,14 @@
var hits = 0;
for (var j = 0; j < 9; ++j) {
try {
(function() {
(function() {
eval("x")
let x
})()
})()
} catch (e) {
hits++;
}
}
assertEq(hits, 9);

View File

@ -4480,7 +4480,7 @@ CodeGenerator::visitNewDeclEnvObject(LNewDeclEnvObject *lir)
return true;
}
typedef JSObject *(*NewCallObjectFn)(JSContext *, HandleShape, HandleTypeObject);
typedef JSObject *(*NewCallObjectFn)(JSContext *, HandleShape, HandleTypeObject, uint32_t);
static const VMFunction NewCallObjectInfo =
FunctionInfo<NewCallObjectFn>(NewCallObject);
@ -4492,9 +4492,12 @@ CodeGenerator::visitNewCallObject(LNewCallObject *lir)
NativeObject *templateObj = lir->mir()->templateObject();
JSScript *script = lir->mir()->block()->info().script();
uint32_t lexicalBegin = script->bindings.aliasedBodyLevelLexicalBegin();
OutOfLineCode *ool = oolCallVM(NewCallObjectInfo, lir,
(ArgList(), ImmGCPtr(templateObj->lastProperty()),
ImmGCPtr(templateObj->type())),
ImmGCPtr(templateObj->type()),
Imm32(lexicalBegin)),
StoreRegisterTo(objReg));
if (!ool)
return false;
@ -4508,7 +4511,7 @@ CodeGenerator::visitNewCallObject(LNewCallObject *lir)
return true;
}
typedef JSObject *(*NewSingletonCallObjectFn)(JSContext *, HandleShape);
typedef JSObject *(*NewSingletonCallObjectFn)(JSContext *, HandleShape, uint32_t);
static const VMFunction NewSingletonCallObjectInfo =
FunctionInfo<NewSingletonCallObjectFn>(NewSingletonCallObject);
@ -4519,9 +4522,12 @@ CodeGenerator::visitNewSingletonCallObject(LNewSingletonCallObject *lir)
JSObject *templateObj = lir->mir()->templateObject();
JSScript *script = lir->mir()->block()->info().script();
uint32_t lexicalBegin = script->bindings.aliasedBodyLevelLexicalBegin();
OutOfLineCode *ool;
ool = oolCallVM(NewSingletonCallObjectInfo, lir,
(ArgList(), ImmGCPtr(templateObj->lastProperty())),
(ArgList(), ImmGCPtr(templateObj->lastProperty()),
Imm32(lexicalBegin)),
StoreRegisterTo(objReg));
if (!ool)
return false;

View File

@ -555,9 +555,9 @@ MallocWrapper(JSRuntime *rt, size_t nbytes)
}
JSObject *
NewCallObject(JSContext *cx, HandleShape shape, HandleTypeObject type)
NewCallObject(JSContext *cx, HandleShape shape, HandleTypeObject type, uint32_t lexicalBegin)
{
JSObject *obj = CallObject::create(cx, shape, type);
JSObject *obj = CallObject::create(cx, shape, type, lexicalBegin);
if (!obj)
return nullptr;
@ -573,9 +573,9 @@ NewCallObject(JSContext *cx, HandleShape shape, HandleTypeObject type)
}
JSObject *
NewSingletonCallObject(JSContext *cx, HandleShape shape)
NewSingletonCallObject(JSContext *cx, HandleShape shape, uint32_t lexicalBegin)
{
JSObject *obj = CallObject::createSingleton(cx, shape);
JSObject *obj = CallObject::createSingleton(cx, shape, lexicalBegin);
if (!obj)
return nullptr;

View File

@ -667,8 +667,9 @@ bool SetProperty(JSContext *cx, HandleObject obj, HandlePropertyName name, Handl
bool InterruptCheck(JSContext *cx);
void *MallocWrapper(JSRuntime *rt, size_t nbytes);
JSObject *NewCallObject(JSContext *cx, HandleShape shape, HandleTypeObject type);
JSObject *NewSingletonCallObject(JSContext *cx, HandleShape shape);
JSObject *NewCallObject(JSContext *cx, HandleShape shape, HandleTypeObject type,
uint32_t lexicalBegin);
JSObject *NewSingletonCallObject(JSContext *cx, HandleShape shape, uint32_t lexicalBegin);
JSObject *NewStringObject(JSContext *cx, HandleString str);
bool SPSEnter(JSContext *cx, HandleScript script);

View File

@ -54,12 +54,17 @@ CallObject::setAliasedVarFromArguments(JSContext *cx, const Value &argsValue, js
}
inline void
CallObject::setAliasedLexicalsToThrowOnTouch(JSScript *script)
CallObject::initRemainingSlotsToUninitializedLexicals(uint32_t begin)
{
uint32_t aliasedLexicalBegin = script->bindings.aliasedBodyLevelLexicalBegin();
uint32_t aliasedLexicalEnd = numFixedSlots();
for (uint32_t slot = aliasedLexicalBegin; slot < aliasedLexicalEnd; slot++)
initFixedSlot(slot, MagicValue(JS_UNINITIALIZED_LEXICAL));
uint32_t end = slotSpan();
for (uint32_t slot = begin; slot < end; slot++)
initSlot(slot, MagicValue(JS_UNINITIALIZED_LEXICAL));
}
inline void
CallObject::initAliasedLexicalsToThrowOnTouch(JSScript *script)
{
initRemainingSlotsToUninitializedLexicals(script->bindings.aliasedBodyLevelLexicalBegin());
}
template <AllowGC allowGC>

View File

@ -139,7 +139,7 @@ ScopeObject::setEnclosingScope(HandleObject obj)
}
CallObject *
CallObject::create(JSContext *cx, HandleShape shape, HandleTypeObject type)
CallObject::create(JSContext *cx, HandleShape shape, HandleTypeObject type, uint32_t lexicalBegin)
{
MOZ_ASSERT(!type->singleton(),
"passed a singleton type to create() (use createSingleton() "
@ -152,11 +152,12 @@ CallObject::create(JSContext *cx, HandleShape shape, HandleTypeObject type)
if (!obj)
return nullptr;
obj->as<CallObject>().initRemainingSlotsToUninitializedLexicals(lexicalBegin);
return &obj->as<CallObject>();
}
CallObject *
CallObject::createSingleton(JSContext *cx, HandleShape shape)
CallObject::createSingleton(JSContext *cx, HandleShape shape, uint32_t lexicalBegin)
{
gc::AllocKind kind = gc::GetGCObjectKind(shape->numFixedSlots());
MOZ_ASSERT(CanBeFinalizedInBackground(kind, &CallObject::class_));
@ -172,6 +173,7 @@ CallObject::createSingleton(JSContext *cx, HandleShape shape)
MOZ_ASSERT(obj->hasSingletonType(),
"type created inline above must be a singleton");
obj->as<CallObject>().initRemainingSlotsToUninitializedLexicals(lexicalBegin);
return &obj->as<CallObject>();
}
@ -198,6 +200,10 @@ CallObject::createTemplateObject(JSContext *cx, HandleScript script, gc::Initial
if (!obj)
return nullptr;
// Set uninitialized lexicals even on template objects, as Ion will use
// copy over the template object's slot values in the fast path.
obj->as<CallObject>().initAliasedLexicalsToThrowOnTouch(script);
return &obj->as<CallObject>();
}
@ -217,7 +223,6 @@ CallObject::create(JSContext *cx, HandleScript script, HandleObject enclosing, H
callobj->as<ScopeObject>().setEnclosingScope(enclosing);
callobj->initFixedSlot(CALLEE_SLOT, ObjectOrNullValue(callee));
callobj->setAliasedLexicalsToThrowOnTouch(script);
if (script->treatAsRunOnce()) {
Rooted<CallObject*> ncallobj(cx, callobj);

View File

@ -237,7 +237,8 @@ class CallObject : public ScopeObject
static CallObject *
create(JSContext *cx, HandleScript script, HandleObject enclosing, HandleFunction callee);
inline void setAliasedLexicalsToThrowOnTouch(JSScript *script);
inline void initRemainingSlotsToUninitializedLexicals(uint32_t begin);
inline void initAliasedLexicalsToThrowOnTouch(JSScript *script);
public:
static const Class class_;
@ -249,14 +250,14 @@ class CallObject : public ScopeObject
* type. The call object must be further initialized to be usable.
*/
static CallObject *
create(JSContext *cx, HandleShape shape, HandleTypeObject type);
create(JSContext *cx, HandleShape shape, HandleTypeObject type, uint32_t lexicalBegin);
/*
* Construct a bare-bones call object given a shape and make it have
* singleton type. The call object must be initialized to be usable.
*/
static CallObject *
createSingleton(JSContext *cx, HandleShape shape);
createSingleton(JSContext *cx, HandleShape shape, uint32_t lexicalBegin);
static CallObject *
createTemplateObject(JSContext *cx, HandleScript script, gc::InitialHeap heap);