зеркало из https://github.com/mozilla/gecko-dev.git
Bug 589199 - Support global lexicals in Baseline. (r=jandem)
This commit is contained in:
Родитель
78aa3b8277
Коммит
934bb0bb13
|
@ -2115,6 +2115,7 @@ BaselineCompiler::emit_JSOP_GETGNAME()
|
|||
|
||||
RootedPropertyName name(cx, script->getName(pc));
|
||||
|
||||
// These names are non-configurable on the global and cannot be shadowed.
|
||||
if (name == cx->names().undefined) {
|
||||
frame.push(UndefinedValue());
|
||||
return true;
|
||||
|
@ -2130,7 +2131,7 @@ BaselineCompiler::emit_JSOP_GETGNAME()
|
|||
|
||||
frame.syncStack(0);
|
||||
|
||||
masm.movePtr(ImmGCPtr(&script->global()), R0.scratchReg());
|
||||
masm.movePtr(ImmGCPtr(&script->global().lexicalScope()), R0.scratchReg());
|
||||
|
||||
// Call IC.
|
||||
ICGetName_Fallback::Compiler stubCompiler(cx);
|
||||
|
@ -2146,8 +2147,27 @@ bool
|
|||
BaselineCompiler::emit_JSOP_BINDGNAME()
|
||||
{
|
||||
if (!script->hasNonSyntacticScope()) {
|
||||
frame.push(ObjectValue(script->global()));
|
||||
return true;
|
||||
// We can bind name to the global lexical scope if the binding already
|
||||
// exists and is initialized at compile time.
|
||||
RootedPropertyName name(cx, script->getName(pc));
|
||||
Rooted<ClonedBlockObject*> globalLexical(cx, &script->global().lexicalScope());
|
||||
if (Shape* shape = globalLexical->lookup(cx, name)) {
|
||||
if (!globalLexical->getSlot(shape->slot()).isMagic(JS_UNINITIALIZED_LEXICAL)) {
|
||||
frame.push(ObjectValue(*globalLexical));
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
// We can bind name to the global object if the property exists on the
|
||||
// global and is non-configurable, as then it cannot be shadowed.
|
||||
if (Shape* shape = script->global().lookup(cx, name)) {
|
||||
if (!shape->configurable()) {
|
||||
frame.push(ObjectValue(script->global()));
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
// Otherwise we have to use the dynamic scope chain.
|
||||
}
|
||||
|
||||
return emit_JSOP_BINDNAME();
|
||||
|
@ -2437,8 +2457,8 @@ BaselineCompiler::emit_JSOP_GETINTRINSIC()
|
|||
return true;
|
||||
}
|
||||
|
||||
typedef bool (*DefVarOrConstFn)(JSContext*, HandlePropertyName, unsigned, HandleObject);
|
||||
static const VMFunction DefVarOrConstInfo = FunctionInfo<DefVarOrConstFn>(DefVarOrConst);
|
||||
typedef bool (*DefVarFn)(JSContext*, HandlePropertyName, unsigned, HandleObject);
|
||||
static const VMFunction DefVarInfo = FunctionInfo<DefVarFn>(DefVar);
|
||||
|
||||
bool
|
||||
BaselineCompiler::emit_JSOP_DEFVAR()
|
||||
|
@ -2446,9 +2466,7 @@ BaselineCompiler::emit_JSOP_DEFVAR()
|
|||
frame.syncStack(0);
|
||||
|
||||
unsigned attrs = JSPROP_ENUMERATE;
|
||||
if (JSOp(*pc) == JSOP_DEFCONST)
|
||||
attrs |= JSPROP_READONLY;
|
||||
else if (!script->isForEval())
|
||||
if (!script->isForEval())
|
||||
attrs |= JSPROP_PERMANENT;
|
||||
MOZ_ASSERT(attrs <= UINT32_MAX);
|
||||
|
||||
|
@ -2460,34 +2478,34 @@ BaselineCompiler::emit_JSOP_DEFVAR()
|
|||
pushArg(Imm32(attrs));
|
||||
pushArg(ImmGCPtr(script->getName(pc)));
|
||||
|
||||
return callVM(DefVarOrConstInfo);
|
||||
return callVM(DefVarInfo);
|
||||
}
|
||||
|
||||
typedef bool (*DefLexicalFn)(JSContext*, HandlePropertyName, unsigned);
|
||||
static const VMFunction DefLexicalInfo = FunctionInfo<DefLexicalFn>(DefLexicalOperation);
|
||||
|
||||
bool
|
||||
BaselineCompiler::emit_JSOP_DEFCONST()
|
||||
{
|
||||
return emit_JSOP_DEFVAR();
|
||||
return emit_JSOP_DEFLET();
|
||||
}
|
||||
|
||||
typedef bool (*SetConstFn)(JSContext*, HandlePropertyName, HandleObject, HandleValue);
|
||||
static const VMFunction SetConstInfo = FunctionInfo<SetConstFn>(SetConst);
|
||||
|
||||
bool
|
||||
BaselineCompiler::emit_JSOP_SETCONST()
|
||||
BaselineCompiler::emit_JSOP_DEFLET()
|
||||
{
|
||||
frame.popRegsAndSync(1);
|
||||
frame.push(R0);
|
||||
frame.syncStack(0);
|
||||
|
||||
masm.loadPtr(frame.addressOfScopeChain(), R1.scratchReg());
|
||||
unsigned attrs = JSPROP_ENUMERATE | JSPROP_PERMANENT;
|
||||
if (*pc == JSOP_DEFCONST)
|
||||
attrs |= JSPROP_READONLY;
|
||||
MOZ_ASSERT(attrs <= UINT32_MAX);
|
||||
|
||||
prepareVMCall();
|
||||
|
||||
pushArg(R0);
|
||||
pushArg(R1.scratchReg());
|
||||
pushArg(Imm32(attrs));
|
||||
pushArg(ImmGCPtr(script->getName(pc)));
|
||||
|
||||
return callVM(SetConstInfo);
|
||||
return callVM(DefLexicalInfo);
|
||||
}
|
||||
|
||||
typedef bool (*DefFunOperationFn)(JSContext*, HandleScript, HandleObject, HandleFunction);
|
||||
|
@ -2818,6 +2836,15 @@ BaselineCompiler::emit_JSOP_INITLEXICAL()
|
|||
return emit_JSOP_SETLOCAL();
|
||||
}
|
||||
|
||||
bool
|
||||
BaselineCompiler::emit_JSOP_INITGLEXICAL()
|
||||
{
|
||||
frame.popRegsAndSync(1);
|
||||
frame.push(ObjectValue(script->global().lexicalScope()));
|
||||
frame.push(R0);
|
||||
return emit_JSOP_SETPROP();
|
||||
}
|
||||
|
||||
bool
|
||||
BaselineCompiler::emit_JSOP_CHECKALIASEDLEXICAL()
|
||||
{
|
||||
|
|
|
@ -141,7 +141,7 @@ namespace jit {
|
|||
_(JSOP_GETINTRINSIC) \
|
||||
_(JSOP_DEFVAR) \
|
||||
_(JSOP_DEFCONST) \
|
||||
_(JSOP_SETCONST) \
|
||||
_(JSOP_DEFLET) \
|
||||
_(JSOP_DEFFUN) \
|
||||
_(JSOP_GETLOCAL) \
|
||||
_(JSOP_SETLOCAL) \
|
||||
|
@ -149,6 +149,7 @@ namespace jit {
|
|||
_(JSOP_SETARG) \
|
||||
_(JSOP_CHECKLEXICAL) \
|
||||
_(JSOP_INITLEXICAL) \
|
||||
_(JSOP_INITGLEXICAL) \
|
||||
_(JSOP_CHECKALIASEDLEXICAL) \
|
||||
_(JSOP_INITALIASEDLEXICAL) \
|
||||
_(JSOP_UNINITIALIZED) \
|
||||
|
|
|
@ -696,6 +696,7 @@ RecompileBaselineScriptForDebugMode(JSContext* cx, JSScript* script,
|
|||
_(GetElem_NativePrototypeCallScriptedSymbol) \
|
||||
_(GetProp_CallScripted) \
|
||||
_(GetProp_CallNative) \
|
||||
_(GetProp_CallNativeGlobal) \
|
||||
_(GetProp_CallDOMProxyNative) \
|
||||
_(GetProp_CallDOMProxyWithGenerationNative) \
|
||||
_(GetProp_DOMProxyShadowed) \
|
||||
|
@ -708,7 +709,8 @@ RecompileBaselineScriptForDebugMode(JSContext* cx, JSScript* script,
|
|||
_(GetElem_Dense) \
|
||||
_(GetElem_Arguments) \
|
||||
_(GetProp_NativePrototype) \
|
||||
_(GetProp_Native)
|
||||
_(GetProp_Native) \
|
||||
_(GetName_Global)
|
||||
#endif
|
||||
|
||||
static bool
|
||||
|
|
|
@ -16,8 +16,11 @@ using namespace js::jit;
|
|||
bool
|
||||
FrameInfo::init(TempAllocator& alloc)
|
||||
{
|
||||
// One slot is always needed for this/arguments type checks.
|
||||
size_t nstack = Max(script->nslots() - script->nfixed(), size_t(1));
|
||||
// The minimum stack size is two. One slot is always needed for
|
||||
// this/arguments type checks. Two slots are needed because INITGLEXICAL
|
||||
// (stack depth 1) is compiled as a SETPROP (stack depth 2) on the global
|
||||
// lexical scope.
|
||||
size_t nstack = Max(script->nslots() - script->nfixed(), size_t(2));
|
||||
if (!stack.init(alloc, nstack))
|
||||
return false;
|
||||
|
||||
|
|
|
@ -4893,25 +4893,29 @@ UpdateExistingSetPropCallStubs(ICSetProp_Fallback* fallbackStub,
|
|||
// Attach an optimized stub for a GETGNAME/CALLGNAME slot-read op.
|
||||
static bool
|
||||
TryAttachGlobalNameValueStub(JSContext* cx, HandleScript script, jsbytecode* pc,
|
||||
ICGetName_Fallback* stub, Handle<GlobalObject*> global,
|
||||
ICGetName_Fallback* stub, Handle<ClonedBlockObject*> globalLexical,
|
||||
HandlePropertyName name, bool* attached)
|
||||
{
|
||||
MOZ_ASSERT(global->is<GlobalObject>());
|
||||
MOZ_ASSERT(globalLexical->isGlobal());
|
||||
MOZ_ASSERT(!*attached);
|
||||
|
||||
RootedId id(cx, NameToId(name));
|
||||
|
||||
// The property must be found, and it must be found as a normal data property.
|
||||
RootedShape shape(cx);
|
||||
RootedNativeObject current(cx, global);
|
||||
RootedShape shape(cx, globalLexical->lookup(cx, id));
|
||||
RootedNativeObject current(cx, globalLexical);
|
||||
while (true) {
|
||||
shape = current->lookup(cx, id);
|
||||
if (shape)
|
||||
break;
|
||||
JSObject* proto = current->getProto();
|
||||
if (!proto || !proto->is<NativeObject>())
|
||||
return true;
|
||||
current = &proto->as<NativeObject>();
|
||||
if (current == globalLexical) {
|
||||
current = &globalLexical->global();
|
||||
} else {
|
||||
JSObject* proto = current->getProto();
|
||||
if (!proto || !proto->is<NativeObject>())
|
||||
return true;
|
||||
current = &proto->as<NativeObject>();
|
||||
}
|
||||
}
|
||||
|
||||
// Instantiate this global property, for use during Ion compilation.
|
||||
|
@ -4924,23 +4928,28 @@ TryAttachGlobalNameValueStub(JSContext* cx, HandleScript script, jsbytecode* pc,
|
|||
|
||||
ICStub* monitorStub = stub->fallbackMonitorStub()->firstMonitorStub();
|
||||
ICStub* newStub;
|
||||
if (current == global) {
|
||||
if (current == globalLexical) {
|
||||
MOZ_ASSERT(shape->slot() >= current->numFixedSlots());
|
||||
uint32_t slot = shape->slot() - current->numFixedSlots();
|
||||
|
||||
JitSpew(JitSpew_BaselineIC, " Generating GetName(GlobalName) stub");
|
||||
ICGetName_Global::Compiler compiler(cx, monitorStub, current->lastProperty(), slot);
|
||||
JitSpew(JitSpew_BaselineIC, " Generating GetName(GlobalName lexical) stub");
|
||||
ICGetName_GlobalLexical::Compiler compiler(cx, monitorStub, slot);
|
||||
newStub = compiler.getStub(compiler.getStubSpace(script));
|
||||
} else {
|
||||
bool isFixedSlot;
|
||||
uint32_t offset;
|
||||
GetFixedOrDynamicSlotOffset(shape, &isFixedSlot, &offset);
|
||||
if (!IsCacheableGetPropReadSlot(global, current, shape))
|
||||
|
||||
// Check the prototype chain from the global to the current
|
||||
// prototype. Ignore the global lexical scope as it doesn' figure
|
||||
// into the prototype chain. We guard on the global lexical
|
||||
// scope's shape independently.
|
||||
if (!IsCacheableGetPropReadSlot(&globalLexical->global(), current, shape))
|
||||
return true;
|
||||
|
||||
JitSpew(JitSpew_BaselineIC, " Generating GetName(GlobalName prototype) stub");
|
||||
ICGetPropNativeCompiler compiler(cx, ICStub::GetProp_NativePrototype, false, monitorStub,
|
||||
global, current, name, isFixedSlot, offset,
|
||||
JitSpew(JitSpew_BaselineIC, " Generating GetName(GlobalName non-lexical) stub");
|
||||
ICGetPropNativeCompiler compiler(cx, ICStub::GetName_Global, false, monitorStub,
|
||||
globalLexical, current, name, isFixedSlot, offset,
|
||||
/* inputDefinitelyObject = */ true);
|
||||
newStub = compiler.getStub(compiler.getStubSpace(script));
|
||||
}
|
||||
|
@ -4956,14 +4965,19 @@ TryAttachGlobalNameValueStub(JSContext* cx, HandleScript script, jsbytecode* pc,
|
|||
// Attach an optimized stub for a GETGNAME/CALLGNAME getter op.
|
||||
static bool
|
||||
TryAttachGlobalNameAccessorStub(JSContext* cx, HandleScript script, jsbytecode* pc,
|
||||
ICGetName_Fallback* stub, Handle<GlobalObject*> global,
|
||||
ICGetName_Fallback* stub, Handle<ClonedBlockObject*> globalLexical,
|
||||
HandlePropertyName name, bool* attached,
|
||||
bool* isTemporarilyUnoptimizable)
|
||||
{
|
||||
MOZ_ASSERT(global->is<GlobalObject>());
|
||||
|
||||
MOZ_ASSERT(globalLexical->isGlobal());
|
||||
RootedId id(cx, NameToId(name));
|
||||
|
||||
// There must not be a shadowing binding on the global lexical scope.
|
||||
if (globalLexical->lookup(cx, id))
|
||||
return true;
|
||||
|
||||
RootedGlobalObject global(cx, &globalLexical->global());
|
||||
|
||||
// The property must be found, and it must be found as a normal data property.
|
||||
RootedShape shape(cx);
|
||||
RootedNativeObject current(cx, global);
|
||||
|
@ -4998,10 +5012,11 @@ TryAttachGlobalNameAccessorStub(JSContext* cx, HandleScript script, jsbytecode*
|
|||
*attached = true;
|
||||
return true;
|
||||
}
|
||||
ICGetProp_CallNative::Compiler compiler(cx, monitorStub, global, current,
|
||||
getter, script->pcToOffset(pc),
|
||||
/* outerClass = */ nullptr,
|
||||
/* inputDefinitelyObject = */ true);
|
||||
ICGetPropCallNativeCompiler compiler(cx, ICStub::GetProp_CallNativeGlobal,
|
||||
monitorStub, globalLexical, current,
|
||||
getter, script->pcToOffset(pc),
|
||||
/* outerClass = */ nullptr,
|
||||
/* inputDefinitelyObject = */ true);
|
||||
|
||||
ICStub* newStub = compiler.getStub(compiler.getStubSpace(script));
|
||||
if (!newStub)
|
||||
|
@ -5142,8 +5157,9 @@ DoGetNameFallback(JSContext* cx, BaselineFrame* frame, ICGetName_Fallback* stub_
|
|||
}
|
||||
|
||||
if (!attached && IsGlobalOp(JSOp(*pc)) && !script->hasNonSyntacticScope()) {
|
||||
if (!TryAttachGlobalNameAccessorStub(cx, script, pc, stub, scopeChain.as<GlobalObject>(),
|
||||
name, &attached, &isTemporarilyUnoptimizable))
|
||||
if (!TryAttachGlobalNameAccessorStub(cx, script, pc, stub,
|
||||
scopeChain.as<ClonedBlockObject>(),
|
||||
name, &attached, &isTemporarilyUnoptimizable))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
@ -5172,8 +5188,8 @@ DoGetNameFallback(JSContext* cx, BaselineFrame* frame, ICGetName_Fallback* stub_
|
|||
return true;
|
||||
|
||||
if (IsGlobalOp(JSOp(*pc)) && !script->hasNonSyntacticScope()) {
|
||||
Handle<GlobalObject*> global = scopeChain.as<GlobalObject>();
|
||||
if (!TryAttachGlobalNameValueStub(cx, script, pc, stub, global, name, &attached))
|
||||
Handle<ClonedBlockObject*> globalLexical = scopeChain.as<ClonedBlockObject>();
|
||||
if (!TryAttachGlobalNameValueStub(cx, script, pc, stub, globalLexical, name, &attached))
|
||||
return false;
|
||||
} else {
|
||||
if (!TryAttachScopeNameStub(cx, script, stub, scopeChain, name, &attached))
|
||||
|
@ -5205,7 +5221,7 @@ ICGetName_Fallback::Compiler::generateStubCode(MacroAssembler& masm)
|
|||
}
|
||||
|
||||
bool
|
||||
ICGetName_Global::Compiler::generateStubCode(MacroAssembler& masm)
|
||||
ICGetName_GlobalLexical::Compiler::generateStubCode(MacroAssembler& masm)
|
||||
{
|
||||
MOZ_ASSERT(engine_ == Engine::Baseline);
|
||||
|
||||
|
@ -5213,13 +5229,12 @@ ICGetName_Global::Compiler::generateStubCode(MacroAssembler& masm)
|
|||
Register obj = R0.scratchReg();
|
||||
Register scratch = R1.scratchReg();
|
||||
|
||||
// Shape guard.
|
||||
masm.loadPtr(Address(ICStubReg, ICGetName_Global::offsetOfShape()), scratch);
|
||||
masm.branchTestObjShape(Assembler::NotEqual, obj, scratch, &failure);
|
||||
// There's no need to guard on the shape. Lexical bindings are
|
||||
// non-configurable, and this stub cannot be shared across globals.
|
||||
|
||||
// Load dynamic slot.
|
||||
masm.loadPtr(Address(obj, NativeObject::offsetOfSlots()), obj);
|
||||
masm.load32(Address(ICStubReg, ICGetName_Global::offsetOfSlot()), scratch);
|
||||
masm.load32(Address(ICStubReg, ICGetName_GlobalLexical::offsetOfSlot()), scratch);
|
||||
masm.loadValue(BaseIndex(obj, scratch, TimesEight), R0);
|
||||
|
||||
// Enter type monitor IC to type-check result.
|
||||
|
@ -5789,8 +5804,9 @@ TryAttachNativeGetAccessorPropStub(JSContext* cx, HandleScript script, jsbytecod
|
|||
return true;
|
||||
}
|
||||
|
||||
ICGetProp_CallNative::Compiler compiler(cx, monitorStub, obj, holder, callee,
|
||||
script->pcToOffset(pc), outerClass);
|
||||
ICGetPropCallNativeCompiler compiler(cx, ICStub::GetProp_CallNative,
|
||||
monitorStub, obj, holder, callee,
|
||||
script->pcToOffset(pc), outerClass);
|
||||
newStub = compiler.getStub(compiler.getStubSpace(script));
|
||||
}
|
||||
if (!newStub)
|
||||
|
@ -6361,11 +6377,31 @@ ICGetPropNativeCompiler::getStub(ICStubSpace* space)
|
|||
offset_, holder_, holderShape);
|
||||
}
|
||||
|
||||
case ICStub::GetName_Global: {
|
||||
MOZ_ASSERT(obj_ != holder_);
|
||||
Shape* holderShape = holder_->as<NativeObject>().lastProperty();
|
||||
Shape* globalShape = obj_->as<ClonedBlockObject>().global().lastProperty();
|
||||
return newStub<ICGetName_Global>(space, getStubCode(), firstMonitorStub_, guard,
|
||||
offset_, holder_, holderShape, globalShape);
|
||||
}
|
||||
|
||||
default:
|
||||
MOZ_CRASH("Bad stub kind");
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
GuardGlobalObject(MacroAssembler& masm, HandleObject holder, Register globalLexicalReg,
|
||||
Register holderReg, Register scratch, size_t globalShapeOffset, Label* failure)
|
||||
{
|
||||
if (holder->is<GlobalObject>())
|
||||
return;
|
||||
masm.extractObject(Address(globalLexicalReg, ScopeObject::offsetOfEnclosingScope()),
|
||||
holderReg);
|
||||
masm.loadPtr(Address(ICStubReg, globalShapeOffset), scratch);
|
||||
masm.branchTestObjShape(Assembler::NotEqual, holderReg, scratch, failure);
|
||||
}
|
||||
|
||||
bool
|
||||
ICGetPropNativeCompiler::generateStubCode(MacroAssembler& masm)
|
||||
{
|
||||
|
@ -6393,6 +6429,7 @@ ICGetPropNativeCompiler::generateStubCode(MacroAssembler& masm)
|
|||
|
||||
Register holderReg;
|
||||
if (obj_ == holder_) {
|
||||
MOZ_ASSERT(kind != ICStub::GetName_Global);
|
||||
if (obj_->is<UnboxedPlainObject>()) {
|
||||
// We are loading off the expando object, so use that for the holder.
|
||||
holderReg = regs.takeAny();
|
||||
|
@ -6401,8 +6438,17 @@ ICGetPropNativeCompiler::generateStubCode(MacroAssembler& masm)
|
|||
holderReg = objReg;
|
||||
}
|
||||
} else {
|
||||
// Shape guard holder.
|
||||
holderReg = regs.takeAny();
|
||||
|
||||
// If we are generating a non-lexical GETGNAME stub, we must also
|
||||
// guard on the shape of the GlobalObject.
|
||||
if (kind == ICStub::GetName_Global) {
|
||||
MOZ_ASSERT(obj_->is<ClonedBlockObject>() && obj_->as<ClonedBlockObject>().isGlobal());
|
||||
GuardGlobalObject(masm, holder_, objReg, holderReg, scratch,
|
||||
ICGetName_Global::offsetOfGlobalShape(), &failure);
|
||||
}
|
||||
|
||||
// Shape guard holder.
|
||||
masm.loadPtr(Address(ICStubReg, ICGetProp_NativePrototype::offsetOfHolder()),
|
||||
holderReg);
|
||||
masm.loadPtr(Address(ICStubReg, ICGetProp_NativePrototype::offsetOfHolderShape()),
|
||||
|
@ -6657,7 +6703,7 @@ ICGetProp_CallScripted::Compiler::generateStubCode(MacroAssembler& masm)
|
|||
}
|
||||
|
||||
bool
|
||||
ICGetProp_CallNative::Compiler::generateStubCode(MacroAssembler& masm)
|
||||
ICGetPropCallNativeCompiler::generateStubCode(MacroAssembler& masm)
|
||||
{
|
||||
MOZ_ASSERT(engine_ == Engine::Baseline);
|
||||
|
||||
|
@ -6689,12 +6735,22 @@ ICGetProp_CallNative::Compiler::generateStubCode(MacroAssembler& masm)
|
|||
|
||||
// Shape guard.
|
||||
GuardReceiverObject(masm, ReceiverGuard(receiver_), objReg, scratch,
|
||||
ICGetProp_CallNative::offsetOfReceiverGuard(), &failure);
|
||||
ICGetPropCallGetter::offsetOfReceiverGuard(), &failure);
|
||||
|
||||
if (receiver_ != holder_ ) {
|
||||
if (receiver_ != holder_) {
|
||||
Register holderReg = regs.takeAny();
|
||||
masm.loadPtr(Address(ICStubReg, ICGetProp_CallNative::offsetOfHolder()), holderReg);
|
||||
masm.loadPtr(Address(ICStubReg, ICGetProp_CallNative::offsetOfHolderShape()), scratch);
|
||||
|
||||
// If we are generating a non-lexical GETGNAME stub, we must also
|
||||
// guard on the shape of the GlobalObject.
|
||||
if (kind == ICStub::GetProp_CallNativeGlobal) {
|
||||
MOZ_ASSERT(receiver_->is<ClonedBlockObject>() &&
|
||||
receiver_->as<ClonedBlockObject>().isGlobal());
|
||||
GuardGlobalObject(masm, holder_, objReg, holderReg, scratch,
|
||||
ICGetProp_CallNativeGlobal::offsetOfGlobalShape(), &failure);
|
||||
}
|
||||
|
||||
masm.loadPtr(Address(ICStubReg, ICGetPropCallGetter::offsetOfHolder()), holderReg);
|
||||
masm.loadPtr(Address(ICStubReg, ICGetPropCallGetter::offsetOfHolderShape()), scratch);
|
||||
masm.branchTestObjShape(Assembler::NotEqual, holderReg, scratch, &failure);
|
||||
regs.add(holderReg);
|
||||
}
|
||||
|
@ -6711,7 +6767,12 @@ ICGetProp_CallNative::Compiler::generateStubCode(MacroAssembler& masm)
|
|||
|
||||
// Load callee function.
|
||||
Register callee = regs.takeAny();
|
||||
masm.loadPtr(Address(ICStubReg, ICGetProp_CallNative::offsetOfGetter()), callee);
|
||||
masm.loadPtr(Address(ICStubReg, ICGetPropCallGetter::offsetOfGetter()), callee);
|
||||
|
||||
// If we're calling a getter on the global, inline the logic for the
|
||||
// 'this' hook on the global lexical scope and manually push the global.
|
||||
if (kind == ICStub::GetProp_CallNativeGlobal)
|
||||
masm.extractObject(Address(objReg, ScopeObject::offsetOfEnclosingScope()), objReg);
|
||||
|
||||
// Push args for vm call.
|
||||
masm.push(objReg);
|
||||
|
@ -6734,6 +6795,30 @@ ICGetProp_CallNative::Compiler::generateStubCode(MacroAssembler& masm)
|
|||
return true;
|
||||
}
|
||||
|
||||
ICStub*
|
||||
ICGetPropCallNativeCompiler::getStub(ICStubSpace* space)
|
||||
{
|
||||
ReceiverGuard guard(receiver_);
|
||||
Shape* holderShape = holder_->as<NativeObject>().lastProperty();
|
||||
|
||||
switch (kind) {
|
||||
case ICStub::GetProp_CallNative:
|
||||
return newStub<ICGetProp_CallNative>(space, getStubCode(), firstMonitorStub_,
|
||||
guard, holder_, holderShape,
|
||||
getter_, pcOffset_);
|
||||
|
||||
case ICStub::GetProp_CallNativeGlobal: {
|
||||
Shape* globalShape = receiver_->as<ClonedBlockObject>().global().lastProperty();
|
||||
return newStub<ICGetProp_CallNativeGlobal>(space, getStubCode(), firstMonitorStub_,
|
||||
guard, holder_, holderShape, globalShape,
|
||||
getter_, pcOffset_);
|
||||
}
|
||||
|
||||
default:
|
||||
MOZ_CRASH("Bad stub kind");
|
||||
}
|
||||
}
|
||||
|
||||
bool
|
||||
ICGetPropCallDOMProxyNativeCompiler::generateStubCode(MacroAssembler& masm,
|
||||
Address* expandoAndGenerationAddr,
|
||||
|
@ -7476,7 +7561,8 @@ DoSetPropFallback(JSContext* cx, BaselineFrame* frame, ICSetProp_Fallback* stub_
|
|||
op == JSOP_INITLOCKEDPROP ||
|
||||
op == JSOP_INITHIDDENPROP ||
|
||||
op == JSOP_SETALIASEDVAR ||
|
||||
op == JSOP_INITALIASEDLEXICAL);
|
||||
op == JSOP_INITALIASEDLEXICAL ||
|
||||
op == JSOP_INITGLEXICAL);
|
||||
|
||||
RootedPropertyName name(cx);
|
||||
if (op == JSOP_SETALIASEDVAR || op == JSOP_INITALIASEDLEXICAL)
|
||||
|
@ -7529,6 +7615,9 @@ DoSetPropFallback(JSContext* cx, BaselineFrame* frame, ICSetProp_Fallback* stub_
|
|||
return false;
|
||||
} else if (op == JSOP_SETALIASEDVAR || op == JSOP_INITALIASEDLEXICAL) {
|
||||
obj->as<ScopeObject>().setAliasedVar(cx, ScopeCoordinate(pc), name, rhs);
|
||||
} else if (op == JSOP_INITGLEXICAL) {
|
||||
RootedValue v(cx, rhs);
|
||||
InitGlobalLexicalOperation(cx, script, pc, v);
|
||||
} else {
|
||||
MOZ_ASSERT(op == JSOP_SETPROP || op == JSOP_STRICTSETPROP);
|
||||
|
||||
|
@ -11268,10 +11357,9 @@ ICIn_Dense::ICIn_Dense(JitCode* stubCode, HandleShape shape)
|
|||
shape_(shape)
|
||||
{ }
|
||||
|
||||
ICGetName_Global::ICGetName_Global(JitCode* stubCode, ICStub* firstMonitorStub, Shape* shape,
|
||||
uint32_t slot)
|
||||
: ICMonitoredStub(GetName_Global, stubCode, firstMonitorStub),
|
||||
shape_(shape),
|
||||
ICGetName_GlobalLexical::ICGetName_GlobalLexical(JitCode* stubCode, ICStub* firstMonitorStub,
|
||||
uint32_t slot)
|
||||
: ICMonitoredStub(GetName_GlobalLexical, stubCode, firstMonitorStub),
|
||||
slot_(slot)
|
||||
{ }
|
||||
|
||||
|
@ -11322,10 +11410,11 @@ ICGetProp_Native::Clone(JSContext* cx, ICStubSpace* space, ICStub* firstMonitorS
|
|||
other.receiverGuard(), other.offset());
|
||||
}
|
||||
|
||||
ICGetProp_NativePrototype::ICGetProp_NativePrototype(JitCode* stubCode, ICStub* firstMonitorStub,
|
||||
ReceiverGuard guard, uint32_t offset,
|
||||
JSObject* holder, Shape* holderShape)
|
||||
: ICGetPropNativeStub(GetProp_NativePrototype, stubCode, firstMonitorStub, guard, offset),
|
||||
ICGetPropNativePrototypeStub::ICGetPropNativePrototypeStub(ICStub::Kind kind, JitCode* stubCode,
|
||||
ICStub* firstMonitorStub,
|
||||
ReceiverGuard guard, uint32_t offset,
|
||||
JSObject* holder, Shape* holderShape)
|
||||
: ICGetPropNativeStub(kind, stubCode, firstMonitorStub, guard, offset),
|
||||
holder_(holder),
|
||||
holderShape_(holderShape)
|
||||
{ }
|
||||
|
@ -11336,7 +11425,24 @@ ICGetProp_NativePrototype::Clone(JSContext* cx, ICStubSpace* space, ICStub* firs
|
|||
{
|
||||
return New<ICGetProp_NativePrototype>(cx, space, other.jitCode(), firstMonitorStub,
|
||||
other.receiverGuard(), other.offset(),
|
||||
other.holder_, other.holderShape_);
|
||||
other.holder(), other.holderShape());
|
||||
}
|
||||
|
||||
ICGetName_Global::ICGetName_Global(JitCode* stubCode, ICStub* firstMonitorStub,
|
||||
ReceiverGuard guard, uint32_t offset,
|
||||
JSObject* holder, Shape* holderShape, Shape* globalShape)
|
||||
: ICGetPropNativePrototypeStub(GetName_Global, stubCode, firstMonitorStub, guard, offset,
|
||||
holder, holderShape),
|
||||
globalShape_(globalShape)
|
||||
{ }
|
||||
|
||||
/* static */ ICGetName_Global*
|
||||
ICGetName_Global::Clone(JSContext* cx, ICStubSpace* space, ICStub* firstMonitorStub,
|
||||
ICGetName_Global& other)
|
||||
{
|
||||
return New<ICGetName_Global>(cx, space, other.jitCode(), firstMonitorStub,
|
||||
other.receiverGuard(), other.offset(),
|
||||
other.holder(), other.holderShape(), other.globalShape());
|
||||
}
|
||||
|
||||
ICGetProp_NativeDoesNotExist::ICGetProp_NativeDoesNotExist(
|
||||
|
@ -11394,6 +11500,7 @@ ICGetPropCallGetter::ICGetPropCallGetter(Kind kind, JitCode* stubCode, ICStub* f
|
|||
{
|
||||
MOZ_ASSERT(kind == ICStub::GetProp_CallScripted ||
|
||||
kind == ICStub::GetProp_CallNative ||
|
||||
kind == ICStub::GetProp_CallNativeGlobal ||
|
||||
kind == ICStub::GetProp_CallDOMProxyNative ||
|
||||
kind == ICStub::GetProp_CallDOMProxyWithGenerationNative);
|
||||
}
|
||||
|
@ -11425,6 +11532,16 @@ ICGetProp_CallNative::Clone(JSContext* cx, ICStubSpace* space, ICStub* firstMoni
|
|||
other.holderShape_, other.getter_, other.pcOffset_);
|
||||
}
|
||||
|
||||
/* static */ ICGetProp_CallNativeGlobal*
|
||||
ICGetProp_CallNativeGlobal::Clone(JSContext* cx, ICStubSpace* space, ICStub* firstMonitorStub,
|
||||
ICGetProp_CallNativeGlobal& other)
|
||||
{
|
||||
return New<ICGetProp_CallNativeGlobal>(cx, space, other.jitCode(), firstMonitorStub,
|
||||
other.receiverGuard(), other.holder_,
|
||||
other.holderShape_, other.globalShape_,
|
||||
other.getter_, other.pcOffset_);
|
||||
}
|
||||
|
||||
ICSetProp_Native::ICSetProp_Native(JitCode* stubCode, ObjectGroup* group, Shape* shape,
|
||||
uint32_t offset)
|
||||
: ICUpdatedStub(SetProp_Native, stubCode),
|
||||
|
|
|
@ -2100,47 +2100,37 @@ class ICGetName_Fallback : public ICMonitoredFallbackStub
|
|||
};
|
||||
};
|
||||
|
||||
// Optimized GETGNAME/CALLGNAME stub.
|
||||
class ICGetName_Global : public ICMonitoredStub
|
||||
// Optimized lexical GETGNAME stub.
|
||||
class ICGetName_GlobalLexical : public ICMonitoredStub
|
||||
{
|
||||
friend class ICStubSpace;
|
||||
|
||||
protected: // Protected to silence Clang warning.
|
||||
HeapPtrShape shape_;
|
||||
uint32_t slot_;
|
||||
|
||||
ICGetName_Global(JitCode* stubCode, ICStub* firstMonitorStub, Shape* shape, uint32_t slot);
|
||||
ICGetName_GlobalLexical(JitCode* stubCode, ICStub* firstMonitorStub, uint32_t slot);
|
||||
|
||||
public:
|
||||
HeapPtrShape& shape() {
|
||||
return shape_;
|
||||
}
|
||||
static size_t offsetOfShape() {
|
||||
return offsetof(ICGetName_Global, shape_);
|
||||
}
|
||||
static size_t offsetOfSlot() {
|
||||
return offsetof(ICGetName_Global, slot_);
|
||||
return offsetof(ICGetName_GlobalLexical, slot_);
|
||||
}
|
||||
|
||||
class Compiler : public ICStubCompiler {
|
||||
ICStub* firstMonitorStub_;
|
||||
RootedShape shape_;
|
||||
uint32_t slot_;
|
||||
|
||||
protected:
|
||||
bool generateStubCode(MacroAssembler& masm);
|
||||
|
||||
public:
|
||||
Compiler(JSContext* cx, ICStub* firstMonitorStub, Shape* shape, uint32_t slot)
|
||||
: ICStubCompiler(cx, ICStub::GetName_Global, Engine::Baseline),
|
||||
Compiler(JSContext* cx, ICStub* firstMonitorStub, uint32_t slot)
|
||||
: ICStubCompiler(cx, ICStub::GetName_GlobalLexical, Engine::Baseline),
|
||||
firstMonitorStub_(firstMonitorStub),
|
||||
shape_(cx, shape),
|
||||
slot_(slot)
|
||||
{}
|
||||
|
||||
ICStub* getStub(ICStubSpace* space) {
|
||||
return newStub<ICGetName_Global>(space, getStubCode(), firstMonitorStub_, shape_,
|
||||
slot_);
|
||||
return newStub<ICGetName_GlobalLexical>(space, getStubCode(), firstMonitorStub_, slot_);
|
||||
}
|
||||
};
|
||||
};
|
||||
|
@ -2577,27 +2567,16 @@ class ICGetProp_Native : public ICGetPropNativeStub
|
|||
ICGetProp_Native& other);
|
||||
};
|
||||
|
||||
// Stub for accessing a property on the native prototype of a native or unboxed
|
||||
// object. Note that due to the shape teleporting optimization, we only have to
|
||||
// guard on the object's shape/group and the holder's shape.
|
||||
class ICGetProp_NativePrototype : public ICGetPropNativeStub
|
||||
class ICGetPropNativePrototypeStub : public ICGetPropNativeStub
|
||||
{
|
||||
friend class ICStubSpace;
|
||||
|
||||
protected:
|
||||
// Holder and its shape.
|
||||
HeapPtrObject holder_;
|
||||
HeapPtrShape holderShape_;
|
||||
|
||||
ICGetProp_NativePrototype(JitCode* stubCode, ICStub* firstMonitorStub,
|
||||
ReceiverGuard guard,
|
||||
uint32_t offset, JSObject* holder, Shape* holderShape);
|
||||
|
||||
public:
|
||||
static ICGetProp_NativePrototype* Clone(JSContext* cx,
|
||||
ICStubSpace* space,
|
||||
ICStub* firstMonitorStub,
|
||||
ICGetProp_NativePrototype& other);
|
||||
protected:
|
||||
ICGetPropNativePrototypeStub(ICStub::Kind kind, JitCode* stubCode, ICStub* firstMonitorStub,
|
||||
ReceiverGuard guard, uint32_t offset, JSObject* holder,
|
||||
Shape* holderShape);
|
||||
|
||||
public:
|
||||
HeapPtrObject& holder() {
|
||||
|
@ -2607,10 +2586,59 @@ class ICGetProp_NativePrototype : public ICGetPropNativeStub
|
|||
return holderShape_;
|
||||
}
|
||||
static size_t offsetOfHolder() {
|
||||
return offsetof(ICGetProp_NativePrototype, holder_);
|
||||
return offsetof(ICGetPropNativePrototypeStub, holder_);
|
||||
}
|
||||
static size_t offsetOfHolderShape() {
|
||||
return offsetof(ICGetProp_NativePrototype, holderShape_);
|
||||
return offsetof(ICGetPropNativePrototypeStub, holderShape_);
|
||||
}
|
||||
};
|
||||
|
||||
// Stub for accessing a property on the native prototype of a native or unboxed
|
||||
// object. Note that due to the shape teleporting optimization, we only have to
|
||||
// guard on the object's shape/group and the holder's shape.
|
||||
class ICGetProp_NativePrototype : public ICGetPropNativePrototypeStub
|
||||
{
|
||||
friend class ICStubSpace;
|
||||
|
||||
protected:
|
||||
ICGetProp_NativePrototype(JitCode* stubCode, ICStub* firstMonitorStub, ReceiverGuard guard,
|
||||
uint32_t offset, JSObject* holder, Shape* holderShape)
|
||||
: ICGetPropNativePrototypeStub(GetProp_NativePrototype, stubCode, firstMonitorStub, guard,
|
||||
offset, holder, holderShape)
|
||||
{ }
|
||||
|
||||
public:
|
||||
static ICGetProp_NativePrototype* Clone(JSContext* cx,
|
||||
ICStubSpace* space,
|
||||
ICStub* firstMonitorStub,
|
||||
ICGetProp_NativePrototype& other);
|
||||
};
|
||||
|
||||
// Stub for accessing a non-lexical global name. Semantically, it is really a
|
||||
// getprop: the name is either on the GlobalObject or its prototype chain. We
|
||||
// teleport to the object that has the name, but we also need to guard on the
|
||||
// shape of the global object.
|
||||
//
|
||||
// The receiver object is the global lexical scope.
|
||||
class ICGetName_Global : public ICGetPropNativePrototypeStub
|
||||
{
|
||||
friend class ICStubSpace;
|
||||
|
||||
protected:
|
||||
HeapPtrShape globalShape_;
|
||||
|
||||
ICGetName_Global(JitCode* stubCode, ICStub* firstMonitorStub, ReceiverGuard guard,
|
||||
uint32_t slot, JSObject* holder, Shape* holderShape, Shape* globalShape);
|
||||
|
||||
public:
|
||||
static ICGetName_Global* Clone(JSContext* cx, ICStubSpace* space, ICStub* firstMonitorStub,
|
||||
ICGetName_Global& other);
|
||||
|
||||
HeapPtrShape& globalShape() {
|
||||
return globalShape_;
|
||||
}
|
||||
static size_t offsetOfGlobalShape() {
|
||||
return offsetof(ICGetName_Global, globalShape_);
|
||||
}
|
||||
};
|
||||
|
||||
|
@ -2955,7 +2983,7 @@ class ICGetPropCallGetter : public ICMonitoredStub
|
|||
const Class* outerClass_;
|
||||
|
||||
virtual int32_t getKey() const {
|
||||
// ICGetProp_CallNative::Compiler::getKey adds more bits to our
|
||||
// ICGetPropCallNativeCompiler::getKey adds more bits to our
|
||||
// return value, so be careful when making changes here.
|
||||
return static_cast<int32_t>(engine_) |
|
||||
(static_cast<int32_t>(kind) << 1) |
|
||||
|
@ -2977,7 +3005,8 @@ class ICGetPropCallGetter : public ICMonitoredStub
|
|||
outerClass_(outerClass)
|
||||
{
|
||||
MOZ_ASSERT(kind == ICStub::GetProp_CallScripted ||
|
||||
kind == ICStub::GetProp_CallNative);
|
||||
kind == ICStub::GetProp_CallNative ||
|
||||
kind == ICStub::GetProp_CallNativeGlobal);
|
||||
}
|
||||
};
|
||||
};
|
||||
|
@ -3042,36 +3071,61 @@ class ICGetProp_CallNative : public ICGetPropCallGetter
|
|||
static ICGetProp_CallNative* Clone(JSContext* cx, ICStubSpace* space, ICStub* firstMonitorStub,
|
||||
ICGetProp_CallNative& other);
|
||||
|
||||
class Compiler : public ICGetPropCallGetter::Compiler
|
||||
{
|
||||
bool inputDefinitelyObject_;
|
||||
protected:
|
||||
bool generateStubCode(MacroAssembler& masm);
|
||||
};
|
||||
|
||||
virtual int32_t getKey() const {
|
||||
int32_t baseKey = ICGetPropCallGetter::Compiler::getKey();
|
||||
MOZ_ASSERT((baseKey >> 21) == 0);
|
||||
return baseKey | (static_cast<int32_t>(inputDefinitelyObject_) << 21);
|
||||
}
|
||||
// Stub for calling a native getter on the GlobalObject.
|
||||
class ICGetProp_CallNativeGlobal : public ICGetPropCallGetter
|
||||
{
|
||||
friend class ICStubSpace;
|
||||
|
||||
public:
|
||||
Compiler(JSContext* cx, ICStub* firstMonitorStub, HandleObject receiver,
|
||||
HandleObject holder, HandleFunction getter, uint32_t pcOffset,
|
||||
const Class* outerClass, bool inputDefinitelyObject = false)
|
||||
: ICGetPropCallGetter::Compiler(cx, ICStub::GetProp_CallNative,
|
||||
firstMonitorStub, receiver, holder,
|
||||
getter, pcOffset, outerClass),
|
||||
inputDefinitelyObject_(inputDefinitelyObject)
|
||||
{}
|
||||
protected:
|
||||
HeapPtrShape globalShape_;
|
||||
|
||||
ICStub* getStub(ICStubSpace* space) {
|
||||
ReceiverGuard guard(receiver_);
|
||||
Shape* holderShape = holder_->as<NativeObject>().lastProperty();
|
||||
return newStub<ICGetProp_CallNative>(space, getStubCode(), firstMonitorStub_,
|
||||
guard, holder_, holderShape,
|
||||
getter_, pcOffset_);
|
||||
}
|
||||
};
|
||||
ICGetProp_CallNativeGlobal(JitCode* stubCode, ICStub* firstMonitorStub,
|
||||
ReceiverGuard receiverGuard,
|
||||
JSObject* holder, Shape* holderShape, Shape* globalShape,
|
||||
JSFunction* getter, uint32_t pcOffset)
|
||||
: ICGetPropCallGetter(GetProp_CallNativeGlobal, stubCode, firstMonitorStub,
|
||||
receiverGuard, holder, holderShape, getter, pcOffset),
|
||||
globalShape_(globalShape)
|
||||
{ }
|
||||
|
||||
public:
|
||||
static ICGetProp_CallNativeGlobal* Clone(JSContext* cx, ICStubSpace* space,
|
||||
ICStub* firstMonitorStub,
|
||||
ICGetProp_CallNativeGlobal& other);
|
||||
|
||||
HeapPtrShape& globalShape() {
|
||||
return globalShape_;
|
||||
}
|
||||
static size_t offsetOfGlobalShape() {
|
||||
return offsetof(ICGetProp_CallNativeGlobal, globalShape_);
|
||||
}
|
||||
};
|
||||
|
||||
class ICGetPropCallNativeCompiler : public ICGetPropCallGetter::Compiler
|
||||
{
|
||||
bool inputDefinitelyObject_;
|
||||
protected:
|
||||
bool generateStubCode(MacroAssembler& masm);
|
||||
|
||||
virtual int32_t getKey() const {
|
||||
int32_t baseKey = ICGetPropCallGetter::Compiler::getKey();
|
||||
MOZ_ASSERT((baseKey >> 21) == 0);
|
||||
return baseKey | (static_cast<int32_t>(inputDefinitelyObject_) << 21);
|
||||
}
|
||||
|
||||
public:
|
||||
ICGetPropCallNativeCompiler(JSContext* cx, ICStub::Kind kind, ICStub* firstMonitorStub,
|
||||
HandleObject receiver, HandleObject holder, HandleFunction getter,
|
||||
uint32_t pcOffset, const Class* outerClass,
|
||||
bool inputDefinitelyObject = false)
|
||||
: ICGetPropCallGetter::Compiler(cx, kind, firstMonitorStub, receiver, holder,
|
||||
getter, pcOffset, outerClass),
|
||||
inputDefinitelyObject_(inputDefinitelyObject)
|
||||
{}
|
||||
|
||||
ICStub* getStub(ICStubSpace* space);
|
||||
};
|
||||
|
||||
class ICGetPropCallDOMProxyNativeStub : public ICGetPropCallGetter
|
||||
|
|
|
@ -78,6 +78,7 @@ namespace jit {
|
|||
_(In_Dense) \
|
||||
\
|
||||
_(GetName_Fallback) \
|
||||
_(GetName_GlobalLexical) \
|
||||
_(GetName_Global) \
|
||||
_(GetName_Scope0) \
|
||||
_(GetName_Scope1) \
|
||||
|
@ -104,6 +105,7 @@ namespace jit {
|
|||
_(GetProp_TypedObject) \
|
||||
_(GetProp_CallScripted) \
|
||||
_(GetProp_CallNative) \
|
||||
_(GetProp_CallNativeGlobal) \
|
||||
_(GetProp_CallDOMProxyNative) \
|
||||
_(GetProp_CallDOMProxyWithGenerationNative) \
|
||||
_(GetProp_DOMProxyShadowed) \
|
||||
|
|
|
@ -2552,7 +2552,7 @@ InlineFrameIterator::computeScopeChain(Value scopeChainValue, MaybeReadFallback&
|
|||
// the global on their scope chain.
|
||||
MOZ_ASSERT(!script()->isForEval());
|
||||
MOZ_ASSERT(!script()->hasNonSyntacticScope());
|
||||
return &script()->global();
|
||||
return &script()->global().lexicalScope();
|
||||
}
|
||||
|
||||
bool
|
||||
|
|
|
@ -366,7 +366,10 @@ ICStub::trace(JSTracer* trc)
|
|||
}
|
||||
case ICStub::GetName_Global: {
|
||||
ICGetName_Global* globalStub = toGetName_Global();
|
||||
TraceEdge(trc, &globalStub->shape(), "baseline-global-stub-shape");
|
||||
globalStub->receiverGuard().trace(trc);
|
||||
TraceEdge(trc, &globalStub->holder(), "baseline-global-stub-holder");
|
||||
TraceEdge(trc, &globalStub->holderShape(), "baseline-global-stub-holdershape");
|
||||
TraceEdge(trc, &globalStub->globalShape(), "baseline-global-stub-globalshape");
|
||||
break;
|
||||
}
|
||||
case ICStub::GetName_Scope0:
|
||||
|
@ -479,6 +482,15 @@ ICStub::trace(JSTracer* trc)
|
|||
TraceEdge(trc, &callStub->getter(), "baseline-getpropcallnative-stub-getter");
|
||||
break;
|
||||
}
|
||||
case ICStub::GetProp_CallNativeGlobal: {
|
||||
ICGetProp_CallNativeGlobal* callStub = toGetProp_CallNativeGlobal();
|
||||
callStub->receiverGuard().trace(trc);
|
||||
TraceEdge(trc, &callStub->holder(), "baseline-getpropcallnativeglobal-stub-holder");
|
||||
TraceEdge(trc, &callStub->holderShape(), "baseline-getpropcallnativeglobal-stub-holdershape");
|
||||
TraceEdge(trc, &callStub->globalShape(), "baseline-getpropcallnativeglobal-stub-globalshape");
|
||||
TraceEdge(trc, &callStub->getter(), "baseline-getpropcallnativeglobal-stub-getter");
|
||||
break;
|
||||
}
|
||||
case ICStub::SetProp_Native: {
|
||||
ICSetProp_Native* propStub = toSetProp_Native();
|
||||
TraceEdge(trc, &propStub->shape(), "baseline-setpropnative-stub-shape");
|
||||
|
|
|
@ -720,6 +720,7 @@ class ICStub
|
|||
case GetElem_UnboxedPropertyName:
|
||||
case GetProp_CallScripted:
|
||||
case GetProp_CallNative:
|
||||
case GetProp_CallNativeGlobal:
|
||||
case GetProp_CallDOMProxyNative:
|
||||
case GetProp_CallDOMProxyWithGenerationNative:
|
||||
case GetProp_DOMProxyShadowed:
|
||||
|
@ -737,6 +738,7 @@ class ICStub
|
|||
case GetElem_Arguments:
|
||||
case GetProp_NativePrototype:
|
||||
case GetProp_Native:
|
||||
case GetName_Global:
|
||||
#endif
|
||||
return true;
|
||||
default:
|
||||
|
|
|
@ -167,25 +167,14 @@ CheckOverRecursedWithExtra(JSContext* cx, BaselineFrame* frame,
|
|||
}
|
||||
|
||||
bool
|
||||
DefVarOrConst(JSContext* cx, HandlePropertyName dn, unsigned attrs, HandleObject scopeChain)
|
||||
DefVar(JSContext* cx, HandlePropertyName dn, unsigned attrs, HandleObject scopeChain)
|
||||
{
|
||||
// Given the ScopeChain, extract the VarObj.
|
||||
RootedObject obj(cx, scopeChain);
|
||||
while (!obj->isQualifiedVarObj())
|
||||
obj = obj->enclosingScope();
|
||||
|
||||
return DefVarOrConstOperation(cx, obj, dn, attrs);
|
||||
}
|
||||
|
||||
bool
|
||||
SetConst(JSContext* cx, HandlePropertyName name, HandleObject scopeChain, HandleValue rval)
|
||||
{
|
||||
// Given the ScopeChain, extract the VarObj.
|
||||
RootedObject obj(cx, scopeChain);
|
||||
while (!obj->isQualifiedVarObj())
|
||||
obj = obj->enclosingScope();
|
||||
|
||||
return SetConstOperation(cx, obj, name, rval);
|
||||
return DefVarOperation(cx, obj, dn, attrs);
|
||||
}
|
||||
|
||||
bool
|
||||
|
|
|
@ -588,8 +588,7 @@ bool CheckOverRecursed(JSContext* cx);
|
|||
bool CheckOverRecursedWithExtra(JSContext* cx, BaselineFrame* frame,
|
||||
uint32_t extra, uint32_t earlyCheck);
|
||||
|
||||
bool DefVarOrConst(JSContext* cx, HandlePropertyName dn, unsigned attrs, HandleObject scopeChain);
|
||||
bool SetConst(JSContext* cx, HandlePropertyName name, HandleObject scopeChain, HandleValue rval);
|
||||
bool DefVar(JSContext* cx, HandlePropertyName dn, unsigned attrs, HandleObject scopeChain);
|
||||
bool MutatePrototype(JSContext* cx, HandlePlainObject obj, HandleValue value);
|
||||
bool InitProp(JSContext* cx, HandleObject obj, HandlePropertyName name, HandleValue value,
|
||||
jsbytecode* pc);
|
||||
|
|
Загрузка…
Ссылка в новой задаче