namespace internal {
-enum TypeofState { INSIDE_TYPEOF, NOT_INSIDE_TYPEOF };
-
-
class StringCharLoadGenerator : public AllStatic {
public:
// Generates the code for handling different string types and loading the
void FullCodeGenerator::EmitLoadGlobalCheckExtensions(VariableProxy* proxy,
- TypeofState typeof_state,
+ TypeofMode typeof_mode,
Label* slow) {
Register current = cp;
Register next = r1;
// All extension objects were empty and it is safe to use a normal global
// load machinery.
- EmitGlobalVariableLoad(proxy, typeof_state);
+ EmitGlobalVariableLoad(proxy, typeof_mode);
}
void FullCodeGenerator::EmitDynamicLookupFastCase(VariableProxy* proxy,
- TypeofState typeof_state,
- Label* slow,
- Label* done) {
+ TypeofMode typeof_mode,
+ Label* slow, Label* done) {
// Generate fast-case code for variables that might be shadowed by
// eval-introduced variables. Eval is used a lot without
// introducing variables. In those cases, we do not want to
// containing the eval.
Variable* var = proxy->var();
if (var->mode() == DYNAMIC_GLOBAL) {
- EmitLoadGlobalCheckExtensions(proxy, typeof_state, slow);
+ EmitLoadGlobalCheckExtensions(proxy, typeof_mode, slow);
__ jmp(done);
} else if (var->mode() == DYNAMIC_LOCAL) {
Variable* local = var->local_if_not_shadowed();
void FullCodeGenerator::EmitGlobalVariableLoad(VariableProxy* proxy,
- TypeofState typeof_state) {
+ TypeofMode typeof_mode) {
Variable* var = proxy->var();
DCHECK(var->IsUnallocatedOrGlobalSlot() ||
(var->IsLookupSlot() && var->mode() == DYNAMIC_GLOBAL));
__ mov(LoadDescriptor::NameRegister(), Operand(var->name()));
__ mov(LoadDescriptor::SlotRegister(),
Operand(SmiFromSlot(proxy->VariableFeedbackSlot())));
- // Inside typeof use a regular load, not a contextual load, to avoid
- // a reference error.
- CallLoadIC(typeof_state == NOT_INSIDE_TYPEOF ? CONTEXTUAL : NOT_CONTEXTUAL);
+ CallLoadIC(typeof_mode);
}
}
void FullCodeGenerator::EmitVariableLoad(VariableProxy* proxy,
- TypeofState typeof_state) {
+ TypeofMode typeof_mode) {
// Record position before possible IC call.
SetExpressionPosition(proxy);
PrepareForBailoutForId(proxy->BeforeId(), NO_REGISTERS);
case VariableLocation::GLOBAL:
case VariableLocation::UNALLOCATED: {
Comment cmnt(masm_, "[ Global variable");
- EmitGlobalVariableLoad(proxy, typeof_state);
+ EmitGlobalVariableLoad(proxy, typeof_mode);
context()->Plug(r0);
break;
}
case VariableLocation::PARAMETER:
case VariableLocation::LOCAL:
case VariableLocation::CONTEXT: {
- DCHECK_EQ(NOT_INSIDE_TYPEOF, typeof_state);
+ DCHECK_EQ(NOT_INSIDE_TYPEOF, typeof_mode);
Comment cmnt(masm_, var->IsContextSlot() ? "[ Context variable"
: "[ Stack variable");
if (var->binding_needs_init()) {
Label done, slow;
// Generate code for loading from variables potentially shadowed
// by eval-introduced variables.
- EmitDynamicLookupFastCase(proxy, typeof_state, &slow, &done);
+ EmitDynamicLookupFastCase(proxy, typeof_mode, &slow, &done);
__ bind(&slow);
__ mov(r1, Operand(var->name()));
__ Push(cp, r1); // Context and name.
Runtime::FunctionId function_id =
- typeof_state == NOT_INSIDE_TYPEOF
+ typeof_mode == NOT_INSIDE_TYPEOF
? Runtime::kLoadLookupSlot
: Runtime::kLoadLookupSlotNoReferenceError;
__ CallRuntime(function_id, 2);
__ LoadRoot(load_name, Heap::kdone_stringRootIndex); // "done"
__ mov(LoadDescriptor::SlotRegister(),
Operand(SmiFromSlot(expr->DoneFeedbackSlot())));
- CallLoadIC(NOT_CONTEXTUAL); // r0=result.done
+ CallLoadIC(NOT_INSIDE_TYPEOF); // r0=result.done
Handle<Code> bool_ic = ToBooleanStub::GetUninitialized(isolate());
CallIC(bool_ic);
__ cmp(r0, Operand(0));
__ LoadRoot(load_name, Heap::kvalue_stringRootIndex); // "value"
__ mov(LoadDescriptor::SlotRegister(),
Operand(SmiFromSlot(expr->ValueFeedbackSlot())));
- CallLoadIC(NOT_CONTEXTUAL); // r0=result.value
+ CallLoadIC(NOT_INSIDE_TYPEOF); // r0=result.value
context()->DropAndPlug(2, r0); // drop iter and g
break;
}
__ mov(LoadDescriptor::NameRegister(), Operand(key->value()));
__ mov(LoadDescriptor::SlotRegister(),
Operand(SmiFromSlot(prop->PropertyFeedbackSlot())));
- CallLoadIC(NOT_CONTEXTUAL, language_mode());
+ CallLoadIC(NOT_INSIDE_TYPEOF, language_mode());
}
__ mov(LoadDescriptor::NameRegister(), Operand(expr->name()));
__ mov(LoadDescriptor::SlotRegister(),
Operand(SmiFromSlot(expr->CallRuntimeFeedbackSlot())));
- CallLoadIC(NOT_CONTEXTUAL);
+ CallLoadIC(NOT_INSIDE_TYPEOF);
}
DECLARE_HYDROGEN_ACCESSOR(LoadGlobalGeneric)
Handle<Object> name() const { return hydrogen()->name(); }
- bool for_typeof() const { return hydrogen()->for_typeof(); }
+ TypeofMode typeof_mode() const { return hydrogen()->typeof_mode(); }
};
__ mov(LoadDescriptor::NameRegister(), Operand(instr->name()));
EmitVectorLoadICRegisters<LLoadGlobalGeneric>(instr);
- ContextualMode mode = instr->for_typeof() ? NOT_CONTEXTUAL : CONTEXTUAL;
- Handle<Code> ic = CodeFactory::LoadICInOptimizedCode(isolate(), mode, SLOPPY,
- PREMONOMORPHIC).code();
+ Handle<Code> ic =
+ CodeFactory::LoadICInOptimizedCode(isolate(), instr->typeof_mode(),
+ SLOPPY, PREMONOMORPHIC).code();
CallCode(ic, RelocInfo::CODE_TARGET, instr);
}
EmitVectorLoadICRegisters<LLoadNamedGeneric>(instr);
Handle<Code> ic =
CodeFactory::LoadICInOptimizedCode(
- isolate(), NOT_CONTEXTUAL, instr->hydrogen()->language_mode(),
+ isolate(), NOT_INSIDE_TYPEOF, instr->hydrogen()->language_mode(),
instr->hydrogen()->initialization_state()).code();
CallCode(ic, RelocInfo::CODE_TARGET, instr, NEVER_INLINE_TARGET_ADDRESS);
}
void FullCodeGenerator::EmitLoadGlobalCheckExtensions(VariableProxy* proxy,
- TypeofState typeof_state,
+ TypeofMode typeof_mode,
Label* slow) {
Register current = cp;
Register next = x10;
// All extension objects were empty and it is safe to use a normal global
// load machinery.
- EmitGlobalVariableLoad(proxy, typeof_state);
+ EmitGlobalVariableLoad(proxy, typeof_mode);
}
void FullCodeGenerator::EmitDynamicLookupFastCase(VariableProxy* proxy,
- TypeofState typeof_state,
- Label* slow,
- Label* done) {
+ TypeofMode typeof_mode,
+ Label* slow, Label* done) {
// Generate fast-case code for variables that might be shadowed by
// eval-introduced variables. Eval is used a lot without
// introducing variables. In those cases, we do not want to
// containing the eval.
Variable* var = proxy->var();
if (var->mode() == DYNAMIC_GLOBAL) {
- EmitLoadGlobalCheckExtensions(proxy, typeof_state, slow);
+ EmitLoadGlobalCheckExtensions(proxy, typeof_mode, slow);
__ B(done);
} else if (var->mode() == DYNAMIC_LOCAL) {
Variable* local = var->local_if_not_shadowed();
void FullCodeGenerator::EmitGlobalVariableLoad(VariableProxy* proxy,
- TypeofState typeof_state) {
+ TypeofMode typeof_mode) {
Variable* var = proxy->var();
DCHECK(var->IsUnallocatedOrGlobalSlot() ||
(var->IsLookupSlot() && var->mode() == DYNAMIC_GLOBAL));
__ Mov(LoadDescriptor::NameRegister(), Operand(var->name()));
__ Mov(LoadDescriptor::SlotRegister(),
SmiFromSlot(proxy->VariableFeedbackSlot()));
- // Inside typeof use a regular load, not a contextual load, to avoid
- // a reference error.
- CallLoadIC(typeof_state == NOT_INSIDE_TYPEOF ? CONTEXTUAL : NOT_CONTEXTUAL);
+ CallLoadIC(typeof_mode);
}
}
void FullCodeGenerator::EmitVariableLoad(VariableProxy* proxy,
- TypeofState typeof_state) {
+ TypeofMode typeof_mode) {
// Record position before possible IC call.
SetExpressionPosition(proxy);
PrepareForBailoutForId(proxy->BeforeId(), NO_REGISTERS);
case VariableLocation::GLOBAL:
case VariableLocation::UNALLOCATED: {
Comment cmnt(masm_, "Global variable");
- EmitGlobalVariableLoad(proxy, typeof_state);
+ EmitGlobalVariableLoad(proxy, typeof_mode);
context()->Plug(x0);
break;
}
case VariableLocation::PARAMETER:
case VariableLocation::LOCAL:
case VariableLocation::CONTEXT: {
- DCHECK_EQ(NOT_INSIDE_TYPEOF, typeof_state);
+ DCHECK_EQ(NOT_INSIDE_TYPEOF, typeof_mode);
Comment cmnt(masm_, var->IsContextSlot()
? "Context variable"
: "Stack variable");
Label done, slow;
// Generate code for loading from variables potentially shadowed by
// eval-introduced variables.
- EmitDynamicLookupFastCase(proxy, typeof_state, &slow, &done);
+ EmitDynamicLookupFastCase(proxy, typeof_mode, &slow, &done);
__ Bind(&slow);
Comment cmnt(masm_, "Lookup variable");
__ Mov(x1, Operand(var->name()));
__ Push(cp, x1); // Context and name.
Runtime::FunctionId function_id =
- typeof_state == NOT_INSIDE_TYPEOF
+ typeof_mode == NOT_INSIDE_TYPEOF
? Runtime::kLoadLookupSlot
: Runtime::kLoadLookupSlotNoReferenceError;
__ CallRuntime(function_id, 2);
__ Mov(LoadDescriptor::NameRegister(), Operand(key->value()));
__ Mov(LoadDescriptor::SlotRegister(),
SmiFromSlot(prop->PropertyFeedbackSlot()));
- CallLoadIC(NOT_CONTEXTUAL, language_mode());
+ CallLoadIC(NOT_INSIDE_TYPEOF, language_mode());
}
__ Mov(LoadDescriptor::NameRegister(), Operand(name));
__ Mov(LoadDescriptor::SlotRegister(),
SmiFromSlot(expr->CallRuntimeFeedbackSlot()));
- CallLoadIC(NOT_CONTEXTUAL);
+ CallLoadIC(NOT_INSIDE_TYPEOF);
}
__ LoadRoot(load_name, Heap::kdone_stringRootIndex); // "done"
__ Mov(LoadDescriptor::SlotRegister(),
SmiFromSlot(expr->DoneFeedbackSlot()));
- CallLoadIC(NOT_CONTEXTUAL); // x0=result.done
+ CallLoadIC(NOT_INSIDE_TYPEOF); // x0=result.done
// The ToBooleanStub argument (result.done) is in x0.
Handle<Code> bool_ic = ToBooleanStub::GetUninitialized(isolate());
CallIC(bool_ic);
__ LoadRoot(load_name, Heap::kvalue_stringRootIndex); // "value"
__ Mov(LoadDescriptor::SlotRegister(),
SmiFromSlot(expr->ValueFeedbackSlot()));
- CallLoadIC(NOT_CONTEXTUAL); // x0=result.value
+ CallLoadIC(NOT_INSIDE_TYPEOF); // x0=result.value
context()->DropAndPlug(2, x0); // drop iter and g
break;
}
DECLARE_HYDROGEN_ACCESSOR(LoadGlobalGeneric)
Handle<Object> name() const { return hydrogen()->name(); }
- bool for_typeof() const { return hydrogen()->for_typeof(); }
+ TypeofMode typeof_mode() const { return hydrogen()->typeof_mode(); }
};
DCHECK(ToRegister(instr->result()).Is(x0));
__ Mov(LoadDescriptor::NameRegister(), Operand(instr->name()));
EmitVectorLoadICRegisters<LLoadGlobalGeneric>(instr);
- ContextualMode mode = instr->for_typeof() ? NOT_CONTEXTUAL : CONTEXTUAL;
- Handle<Code> ic = CodeFactory::LoadICInOptimizedCode(isolate(), mode, SLOPPY,
- PREMONOMORPHIC).code();
+ Handle<Code> ic =
+ CodeFactory::LoadICInOptimizedCode(isolate(), instr->typeof_mode(),
+ SLOPPY, PREMONOMORPHIC).code();
CallCode(ic, RelocInfo::CODE_TARGET, instr);
}
EmitVectorLoadICRegisters<LLoadNamedGeneric>(instr);
Handle<Code> ic =
CodeFactory::LoadICInOptimizedCode(
- isolate(), NOT_CONTEXTUAL, instr->hydrogen()->language_mode(),
+ isolate(), NOT_INSIDE_TYPEOF, instr->hydrogen()->language_mode(),
instr->hydrogen()->initialization_state()).code();
CallCode(ic, RelocInfo::CODE_TARGET, instr);
// static
-Callable CodeFactory::LoadIC(Isolate* isolate, ContextualMode mode,
+Callable CodeFactory::LoadIC(Isolate* isolate, TypeofMode typeof_mode,
LanguageMode language_mode) {
return Callable(
LoadIC::initialize_stub(
- isolate, LoadICState(mode, language_mode).GetExtraICState()),
+ isolate, LoadICState(typeof_mode, language_mode).GetExtraICState()),
LoadDescriptor(isolate));
}
// static
Callable CodeFactory::LoadICInOptimizedCode(
- Isolate* isolate, ContextualMode mode, LanguageMode language_mode,
+ Isolate* isolate, TypeofMode typeof_mode, LanguageMode language_mode,
InlineCacheState initialization_state) {
auto code = LoadIC::initialize_stub_in_optimized_code(
- isolate, LoadICState(mode, language_mode).GetExtraICState(),
+ isolate, LoadICState(typeof_mode, language_mode).GetExtraICState(),
initialization_state);
return Callable(code, LoadWithVectorDescriptor(isolate));
}
class CodeFactory final {
public:
// Initial states for ICs.
- static Callable LoadIC(Isolate* isolate, ContextualMode mode,
+ static Callable LoadIC(Isolate* isolate, TypeofMode typeof_mode,
LanguageMode language_mode);
- static Callable LoadICInOptimizedCode(Isolate* isolate, ContextualMode mode,
+ static Callable LoadICInOptimizedCode(Isolate* isolate,
+ TypeofMode typeof_mode,
LanguageMode language_mode,
InlineCacheState initialization_state);
static Callable KeyedLoadIC(Isolate* isolate, LanguageMode language_mode);
// CodeForDoWhileConditionPosition
// CodeForSourcePosition
-enum TypeofState { INSIDE_TYPEOF, NOT_INSIDE_TYPEOF };
-
#if V8_TARGET_ARCH_IA32
#include "src/ia32/codegen-ia32.h" // NOLINT
#elif V8_TARGET_ARCH_X64
FrameStateBeforeAndAfter states(this, BeforeId(proxy));
operand =
BuildVariableLoad(proxy->var(), expr->expression()->id(), states, pair,
- OutputFrameStateCombine::Push(), NOT_CONTEXTUAL);
+ OutputFrameStateCombine::Push(), INSIDE_TYPEOF);
} else {
VisitForValue(expr->expression());
operand = environment()->Pop();
FrameStateBeforeAndAfter& states,
const VectorSlotPair& feedback,
OutputFrameStateCombine combine,
- ContextualMode contextual_mode) {
+ TypeofMode typeof_mode) {
Node* the_hole = jsgraph()->TheHoleConstant();
VariableMode mode = variable->mode();
switch (variable->location()) {
Node* global = BuildLoadGlobalObject();
Handle<Name> name = variable->name();
Node* value = BuildGlobalLoad(script_context, global, name, feedback,
- contextual_mode, slot_index);
+ typeof_mode, slot_index);
states.AddToNode(value, bailout_id, combine);
return value;
}
if (mode == DYNAMIC_GLOBAL) {
uint32_t check_bitset = ComputeBitsetForDynamicGlobal(variable);
const Operator* op = javascript()->LoadDynamicGlobal(
- name, check_bitset, feedback, contextual_mode);
+ name, check_bitset, feedback, typeof_mode);
value = NewNode(op, BuildLoadFeedbackVector(), current_context());
states.AddToNode(value, bailout_id, combine);
} else if (mode == DYNAMIC_LOCAL) {
} else if (mode == DYNAMIC) {
uint32_t check_bitset = DynamicGlobalAccess::kFullCheckRequired;
const Operator* op = javascript()->LoadDynamicGlobal(
- name, check_bitset, feedback, contextual_mode);
+ name, check_bitset, feedback, typeof_mode);
value = NewNode(op, BuildLoadFeedbackVector(), current_context());
states.AddToNode(value, bailout_id, combine);
}
Node* AstGraphBuilder::BuildGlobalLoad(Node* script_context, Node* global,
Handle<Name> name,
const VectorSlotPair& feedback,
- ContextualMode mode, int slot_index) {
- const Operator* op =
- javascript()->LoadGlobal(MakeUnique(name), feedback, mode, slot_index);
+ TypeofMode typeof_mode, int slot_index) {
+ const Operator* op = javascript()->LoadGlobal(MakeUnique(name), feedback,
+ typeof_mode, slot_index);
Node* node = NewNode(op, script_context, global, BuildLoadFeedbackVector());
return Record(js_type_feedback_, node, feedback.slot());
}
FrameStateBeforeAndAfter& states,
const VectorSlotPair& feedback,
OutputFrameStateCombine framestate_combine,
- ContextualMode mode = CONTEXTUAL);
+ TypeofMode typeof_mode = NOT_INSIDE_TYPEOF);
// Builders for property loads and stores.
Node* BuildKeyedLoad(Node* receiver, Node* key,
// Builders for global variable loads and stores.
Node* BuildGlobalLoad(Node* script_context, Node* global, Handle<Name> name,
- const VectorSlotPair& feedback, ContextualMode mode,
+ const VectorSlotPair& feedback, TypeofMode typeof_mode,
int slot_index);
Node* BuildGlobalStore(Node* script_context, Node* global, Handle<Name> name,
Node* value, const VectorSlotPair& feedback,
CallDescriptor::Flags flags = AdjustFrameStatesForCall(node);
const LoadNamedParameters& p = LoadNamedParametersOf(node->op());
Callable callable = CodeFactory::LoadICInOptimizedCode(
- isolate(), p.contextual_mode(), p.language_mode(), UNINITIALIZED);
+ isolate(), NOT_INSIDE_TYPEOF, p.language_mode(), UNINITIALIZED);
node->InsertInput(zone(), 1, jsgraph()->HeapConstant(p.name()));
node->InsertInput(zone(), 2, jsgraph()->SmiConstant(p.feedback().index()));
ReplaceWithStubCall(node, callable, flags);
} else {
Callable callable = CodeFactory::LoadICInOptimizedCode(
- isolate(), p.contextual_mode(), SLOPPY, UNINITIALIZED);
+ isolate(), p.typeof_mode(), SLOPPY, UNINITIALIZED);
node->RemoveInput(0); // script context
node->InsertInput(zone(), 1, jsgraph()->HeapConstant(p.name()));
node->InsertInput(zone(), 2, jsgraph()->SmiConstant(p.feedback().index()));
void JSGenericLowering::LowerJSLoadDynamicGlobal(Node* node) {
const DynamicGlobalAccess& access = DynamicGlobalAccessOf(node->op());
Runtime::FunctionId function_id =
- (access.mode() == CONTEXTUAL) ? Runtime::kLoadLookupSlot
- : Runtime::kLoadLookupSlotNoReferenceError;
+ (access.typeof_mode() == NOT_INSIDE_TYPEOF)
+ ? Runtime::kLoadLookupSlot
+ : Runtime::kLoadLookupSlotNoReferenceError;
Node* projection = graph()->NewNode(common()->Projection(0), node);
NodeProperties::ReplaceUses(node, projection, node, node, node);
node->RemoveInput(NodeProperties::FirstFrameStateIndex(node) + 1);
DynamicGlobalAccess::DynamicGlobalAccess(const Handle<String>& name,
uint32_t check_bitset,
const VectorSlotPair& feedback,
- ContextualMode mode)
+ TypeofMode typeof_mode)
: name_(name),
check_bitset_(check_bitset),
feedback_(feedback),
- mode_(mode) {
+ typeof_mode_(typeof_mode) {
DCHECK(check_bitset == kFullCheckRequired || check_bitset < 0x80000000U);
}
std::ostream& operator<<(std::ostream& os, DynamicGlobalAccess const& access) {
return os << Brief(*access.name()) << ", " << access.check_bitset() << ", "
- << access.mode();
+ << access.typeof_mode();
}
LoadNamedParameters const& rhs) {
return lhs.name() == rhs.name() &&
lhs.language_mode() == rhs.language_mode() &&
- lhs.contextual_mode() == rhs.contextual_mode() &&
lhs.feedback() == rhs.feedback();
}
size_t hash_value(LoadNamedParameters const& p) {
- return base::hash_combine(p.name(), p.language_mode(), p.contextual_mode(),
- p.feedback());
+ return base::hash_combine(p.name(), p.language_mode(), p.feedback());
}
std::ostream& operator<<(std::ostream& os, LoadNamedParameters const& p) {
- return os << Brief(*p.name().handle()) << ", " << p.language_mode() << ", "
- << p.contextual_mode();
+ return os << Brief(*p.name().handle()) << ", " << p.language_mode();
}
bool operator==(LoadGlobalParameters const& lhs,
LoadGlobalParameters const& rhs) {
return lhs.name() == rhs.name() && lhs.feedback() == rhs.feedback() &&
- lhs.contextual_mode() == rhs.contextual_mode() &&
+ lhs.typeof_mode() == rhs.typeof_mode() &&
lhs.slot_index() == rhs.slot_index();
}
size_t hash_value(LoadGlobalParameters const& p) {
- return base::hash_combine(p.name(), p.contextual_mode(), p.slot_index());
+ return base::hash_combine(p.name(), p.typeof_mode(), p.slot_index());
}
std::ostream& operator<<(std::ostream& os, LoadGlobalParameters const& p) {
- return os << Brief(*p.name().handle()) << ", " << p.contextual_mode()
+ return os << Brief(*p.name().handle()) << ", " << p.typeof_mode()
<< ", slot: " << p.slot_index();
}
const Operator* JSOperatorBuilder::LoadNamed(const Unique<Name>& name,
const VectorSlotPair& feedback,
LanguageMode language_mode) {
- LoadNamedParameters parameters(name, feedback, language_mode, NOT_CONTEXTUAL);
+ LoadNamedParameters parameters(name, feedback, language_mode);
return new (zone()) Operator1<LoadNamedParameters>( // --
IrOpcode::kJSLoadNamed, Operator::kNoProperties, // opcode
"JSLoadNamed", // name
const Operator* JSOperatorBuilder::LoadGlobal(const Unique<Name>& name,
const VectorSlotPair& feedback,
- ContextualMode contextual_mode,
+ TypeofMode typeof_mode,
int slot_index) {
- LoadGlobalParameters parameters(name, feedback, contextual_mode, slot_index);
+ LoadGlobalParameters parameters(name, feedback, typeof_mode, slot_index);
return new (zone()) Operator1<LoadGlobalParameters>( // --
IrOpcode::kJSLoadGlobal, Operator::kNoProperties, // opcode
"JSLoadGlobal", // name
const Operator* JSOperatorBuilder::LoadDynamicGlobal(
const Handle<String>& name, uint32_t check_bitset,
- const VectorSlotPair& feedback, ContextualMode mode) {
- DynamicGlobalAccess access(name, check_bitset, feedback, mode);
+ const VectorSlotPair& feedback, TypeofMode typeof_mode) {
+ DynamicGlobalAccess access(name, check_bitset, feedback, typeof_mode);
return new (zone()) Operator1<DynamicGlobalAccess>( // --
IrOpcode::kJSLoadDynamicGlobal, Operator::kNoProperties, // opcode
"JSLoadDynamicGlobal", // name
class DynamicGlobalAccess final {
public:
DynamicGlobalAccess(const Handle<String>& name, uint32_t check_bitset,
- const VectorSlotPair& feedback, ContextualMode mode);
+ const VectorSlotPair& feedback, TypeofMode typeof_mode);
const Handle<String>& name() const { return name_; }
uint32_t check_bitset() const { return check_bitset_; }
const VectorSlotPair& feedback() const { return feedback_; }
- ContextualMode mode() const { return mode_; }
+ TypeofMode typeof_mode() const { return typeof_mode_; }
// Indicates that an inline check is disabled.
bool RequiresFullCheck() const {
const Handle<String> name_;
const uint32_t check_bitset_;
const VectorSlotPair feedback_;
- const ContextualMode mode_;
+ const TypeofMode typeof_mode_;
};
size_t hash_value(DynamicGlobalAccess const&);
class LoadNamedParameters final {
public:
LoadNamedParameters(const Unique<Name>& name, const VectorSlotPair& feedback,
- LanguageMode language_mode,
- ContextualMode contextual_mode)
- : name_(name),
- feedback_(feedback),
- language_mode_(language_mode),
- contextual_mode_(contextual_mode) {}
+ LanguageMode language_mode)
+ : name_(name), feedback_(feedback), language_mode_(language_mode) {}
const Unique<Name>& name() const { return name_; }
LanguageMode language_mode() const { return language_mode_; }
- ContextualMode contextual_mode() const { return contextual_mode_; }
const VectorSlotPair& feedback() const { return feedback_; }
const Unique<Name> name_;
const VectorSlotPair feedback_;
const LanguageMode language_mode_;
- const ContextualMode contextual_mode_;
};
bool operator==(LoadNamedParameters const&, LoadNamedParameters const&);
class LoadGlobalParameters final {
public:
LoadGlobalParameters(const Unique<Name>& name, const VectorSlotPair& feedback,
- ContextualMode contextual_mode, int slot_index)
+ TypeofMode typeof_mode, int slot_index)
: name_(name),
feedback_(feedback),
- contextual_mode_(contextual_mode),
+ typeof_mode_(typeof_mode),
slot_index_(slot_index) {}
const Unique<Name>& name() const { return name_; }
- ContextualMode contextual_mode() const { return contextual_mode_; }
+ TypeofMode typeof_mode() const { return typeof_mode_; }
const VectorSlotPair& feedback() const { return feedback_; }
private:
const Unique<Name> name_;
const VectorSlotPair feedback_;
- const ContextualMode contextual_mode_;
+ const TypeofMode typeof_mode_;
const int slot_index_;
};
const Operator* LoadGlobal(const Unique<Name>& name,
const VectorSlotPair& feedback,
- ContextualMode contextual_mode = NOT_CONTEXTUAL,
+ TypeofMode typeof_mode = NOT_INSIDE_TYPEOF,
int slot_index = -1);
const Operator* StoreGlobal(LanguageMode language_mode,
const Unique<Name>& name,
const Operator* LoadDynamicGlobal(const Handle<String>& name,
uint32_t check_bitset,
const VectorSlotPair& feedback,
- ContextualMode mode);
+ TypeofMode typeof_mode);
const Operator* LoadDynamicContext(const Handle<String>& name,
uint32_t check_bitset, size_t depth,
size_t index);
javascript()->LoadContext(0, Context::GLOBAL_OBJECT_INDEX, true), context,
context, effect);
Node* fast = graph()->NewNode(
- javascript()->LoadGlobal(name, access.feedback(), access.mode()), context,
- global, vector, context, state1, state2, global, check_true);
+ javascript()->LoadGlobal(name, access.feedback(), access.typeof_mode()),
+ context, global, vector, context, state1, state2, global, check_true);
// Slow case, because variable potentially shadowed. Perform dynamic lookup.
uint32_t check_bitset = DynamicGlobalAccess::kFullCheckRequired;
Node* slow = graph()->NewNode(
javascript()->LoadDynamicGlobal(access.name(), check_bitset,
- access.feedback(), access.mode()),
+ access.feedback(), access.typeof_mode()),
vector, context, context, state1, state2, effect, check_false);
// Replace value, effect and control uses accordingly.
Code::Kind kind = code->kind();
if (code->is_inline_cache_stub()) {
if (kind == Code::LOAD_IC &&
- LoadICState::GetContextualMode(code->extra_ic_state()) ==
- CONTEXTUAL) {
+ LoadICState::GetTypeofMode(code->extra_ic_state()) ==
+ NOT_INSIDE_TYPEOF) {
out.AddFormatted(" contextual,");
}
InlineCacheState ic_state = code->ic_state();
}
-void FullCodeGenerator::CallLoadIC(ContextualMode contextual_mode,
+void FullCodeGenerator::CallLoadIC(TypeofMode typeof_mode,
LanguageMode language_mode,
TypeFeedbackId id) {
Handle<Code> ic =
- CodeFactory::LoadIC(isolate(), contextual_mode, language_mode).code();
+ CodeFactory::LoadIC(isolate(), typeof_mode, language_mode).code();
CallIC(ic, id);
}
// Platform-specific code for loading variables.
void EmitLoadGlobalCheckExtensions(VariableProxy* proxy,
- TypeofState typeof_state,
- Label* slow);
+ TypeofMode typeof_mode, Label* slow);
MemOperand ContextSlotOperandCheckExtensions(Variable* var, Label* slow);
- void EmitDynamicLookupFastCase(VariableProxy* proxy,
- TypeofState typeof_state,
- Label* slow,
- Label* done);
- void EmitGlobalVariableLoad(VariableProxy* proxy, TypeofState typeof_state);
+ void EmitDynamicLookupFastCase(VariableProxy* proxy, TypeofMode typeof_mode,
+ Label* slow, Label* done);
+ void EmitGlobalVariableLoad(VariableProxy* proxy, TypeofMode typeof_mode);
void EmitVariableLoad(VariableProxy* proxy,
- TypeofState typeof_state = NOT_INSIDE_TYPEOF);
+ TypeofMode typeof_mode = NOT_INSIDE_TYPEOF);
void EmitAccessor(Expression* expression);
void CallIC(Handle<Code> code,
TypeFeedbackId id = TypeFeedbackId::None());
- void CallLoadIC(ContextualMode mode, LanguageMode language_mode = SLOPPY,
+ // Inside typeof reference errors are never thrown.
+ void CallLoadIC(TypeofMode typeof_mode, LanguageMode language_mode = SLOPPY,
TypeFeedbackId id = TypeFeedbackId::None());
void CallStoreIC(TypeFeedbackId id = TypeFeedbackId::None());
class HLoadGlobalGeneric final : public HTemplateInstruction<2> {
public:
DECLARE_INSTRUCTION_WITH_CONTEXT_FACTORY_P3(HLoadGlobalGeneric, HValue*,
- Handle<String>, bool);
+ Handle<String>, TypeofMode);
HValue* context() { return OperandAt(0); }
HValue* global_object() { return OperandAt(1); }
Handle<String> name() const { return name_; }
- bool for_typeof() const { return for_typeof_; }
+ TypeofMode typeof_mode() const { return typeof_mode_; }
FeedbackVectorICSlot slot() const { return slot_; }
Handle<TypeFeedbackVector> feedback_vector() const {
return feedback_vector_;
private:
HLoadGlobalGeneric(HValue* context, HValue* global_object,
- Handle<String> name, bool for_typeof)
+ Handle<String> name, TypeofMode typeof_mode)
: name_(name),
- for_typeof_(for_typeof),
+ typeof_mode_(typeof_mode),
slot_(FeedbackVectorICSlot::Invalid()) {
SetOperandAt(0, context);
SetOperandAt(1, global_object);
}
Handle<String> name_;
- bool for_typeof_;
+ TypeofMode typeof_mode_;
Handle<TypeFeedbackVector> feedback_vector_;
FeedbackVectorICSlot slot_;
};
: owner_(owner),
kind_(kind),
outer_(owner->ast_context()),
- for_typeof_(false) {
+ typeof_mode_(NOT_INSIDE_TYPEOF) {
owner->set_ast_context(this); // Push.
#ifdef DEBUG
DCHECK(owner->environment()->frame_type() == JS_FUNCTION);
void HOptimizedGraphBuilder::VisitForTypeOf(Expression* expr) {
ValueContext for_value(this, ARGUMENTS_NOT_ALLOWED);
- for_value.set_for_typeof(true);
+ for_value.set_typeof_mode(INSIDE_TYPEOF);
Visit(expr);
}
HValue* global_object = Add<HLoadNamedField>(
context(), nullptr,
HObjectAccess::ForContextSlot(Context::GLOBAL_OBJECT_INDEX));
- HLoadGlobalGeneric* instr =
- New<HLoadGlobalGeneric>(global_object,
- variable->name(),
- ast_context()->is_for_typeof());
+ HLoadGlobalGeneric* instr = New<HLoadGlobalGeneric>(
+ global_object, variable->name(), ast_context()->typeof_mode());
instr->SetVectorAndSlot(handle(current_feedback_vector(), isolate()),
expr->VariableFeedbackSlot());
return ast_context()->ReturnInstruction(instr, expr->id());
virtual void ReturnContinuation(HIfContinuation* continuation,
BailoutId ast_id) = 0;
- void set_for_typeof(bool for_typeof) { for_typeof_ = for_typeof; }
- bool is_for_typeof() { return for_typeof_; }
+ void set_typeof_mode(TypeofMode typeof_mode) { typeof_mode_ = typeof_mode; }
+ TypeofMode typeof_mode() { return typeof_mode_; }
protected:
AstContext(HOptimizedGraphBuilder* owner, Expression::Context kind);
HOptimizedGraphBuilder* owner_;
Expression::Context kind_;
AstContext* outer_;
- bool for_typeof_;
+ TypeofMode typeof_mode_;
};
void FullCodeGenerator::EmitLoadGlobalCheckExtensions(VariableProxy* proxy,
- TypeofState typeof_state,
+ TypeofMode typeof_mode,
Label* slow) {
Register context = esi;
Register temp = edx;
// All extension objects were empty and it is safe to use a normal global
// load machinery.
- EmitGlobalVariableLoad(proxy, typeof_state);
+ EmitGlobalVariableLoad(proxy, typeof_mode);
}
void FullCodeGenerator::EmitDynamicLookupFastCase(VariableProxy* proxy,
- TypeofState typeof_state,
- Label* slow,
- Label* done) {
+ TypeofMode typeof_mode,
+ Label* slow, Label* done) {
// Generate fast-case code for variables that might be shadowed by
// eval-introduced variables. Eval is used a lot without
// introducing variables. In those cases, we do not want to
// containing the eval.
Variable* var = proxy->var();
if (var->mode() == DYNAMIC_GLOBAL) {
- EmitLoadGlobalCheckExtensions(proxy, typeof_state, slow);
+ EmitLoadGlobalCheckExtensions(proxy, typeof_mode, slow);
__ jmp(done);
} else if (var->mode() == DYNAMIC_LOCAL) {
Variable* local = var->local_if_not_shadowed();
void FullCodeGenerator::EmitGlobalVariableLoad(VariableProxy* proxy,
- TypeofState typeof_state) {
+ TypeofMode typeof_mode) {
Variable* var = proxy->var();
DCHECK(var->IsUnallocatedOrGlobalSlot() ||
(var->IsLookupSlot() && var->mode() == DYNAMIC_GLOBAL));
__ mov(LoadDescriptor::NameRegister(), var->name());
__ mov(LoadDescriptor::SlotRegister(),
Immediate(SmiFromSlot(proxy->VariableFeedbackSlot())));
- // Inside typeof use a regular load, not a contextual load, to avoid
- // a reference error.
- CallLoadIC(typeof_state == NOT_INSIDE_TYPEOF ? CONTEXTUAL : NOT_CONTEXTUAL);
+ CallLoadIC(typeof_mode);
}
}
void FullCodeGenerator::EmitVariableLoad(VariableProxy* proxy,
- TypeofState typeof_state) {
+ TypeofMode typeof_mode) {
SetExpressionPosition(proxy);
PrepareForBailoutForId(proxy->BeforeId(), NO_REGISTERS);
Variable* var = proxy->var();
case VariableLocation::GLOBAL:
case VariableLocation::UNALLOCATED: {
Comment cmnt(masm_, "[ Global variable");
- EmitGlobalVariableLoad(proxy, typeof_state);
+ EmitGlobalVariableLoad(proxy, typeof_mode);
context()->Plug(eax);
break;
}
case VariableLocation::PARAMETER:
case VariableLocation::LOCAL:
case VariableLocation::CONTEXT: {
- DCHECK_EQ(NOT_INSIDE_TYPEOF, typeof_state);
+ DCHECK_EQ(NOT_INSIDE_TYPEOF, typeof_mode);
Comment cmnt(masm_, var->IsContextSlot() ? "[ Context variable"
: "[ Stack variable");
if (var->binding_needs_init()) {
Label done, slow;
// Generate code for loading from variables potentially shadowed
// by eval-introduced variables.
- EmitDynamicLookupFastCase(proxy, typeof_state, &slow, &done);
+ EmitDynamicLookupFastCase(proxy, typeof_mode, &slow, &done);
__ bind(&slow);
__ push(esi); // Context.
__ push(Immediate(var->name()));
Runtime::FunctionId function_id =
- typeof_state == NOT_INSIDE_TYPEOF
+ typeof_mode == NOT_INSIDE_TYPEOF
? Runtime::kLoadLookupSlot
: Runtime::kLoadLookupSlotNoReferenceError;
__ CallRuntime(function_id, 2);
isolate()->factory()->done_string()); // "done"
__ mov(LoadDescriptor::SlotRegister(),
Immediate(SmiFromSlot(expr->DoneFeedbackSlot())));
- CallLoadIC(NOT_CONTEXTUAL); // result.done in eax
+ CallLoadIC(NOT_INSIDE_TYPEOF); // result.done in eax
Handle<Code> bool_ic = ToBooleanStub::GetUninitialized(isolate());
CallIC(bool_ic);
__ test(eax, eax);
isolate()->factory()->value_string()); // "value"
__ mov(LoadDescriptor::SlotRegister(),
Immediate(SmiFromSlot(expr->ValueFeedbackSlot())));
- CallLoadIC(NOT_CONTEXTUAL); // result.value in eax
+ CallLoadIC(NOT_INSIDE_TYPEOF); // result.value in eax
context()->DropAndPlug(2, eax); // drop iter and g
break;
}
__ mov(LoadDescriptor::NameRegister(), Immediate(key->value()));
__ mov(LoadDescriptor::SlotRegister(),
Immediate(SmiFromSlot(prop->PropertyFeedbackSlot())));
- CallLoadIC(NOT_CONTEXTUAL, language_mode());
+ CallLoadIC(NOT_INSIDE_TYPEOF, language_mode());
}
__ mov(LoadDescriptor::NameRegister(), Immediate(expr->name()));
__ mov(LoadDescriptor::SlotRegister(),
Immediate(SmiFromSlot(expr->CallRuntimeFeedbackSlot())));
- CallLoadIC(NOT_CONTEXTUAL);
+ CallLoadIC(NOT_INSIDE_TYPEOF);
}
__ mov(LoadDescriptor::NameRegister(), instr->name());
EmitVectorLoadICRegisters<LLoadGlobalGeneric>(instr);
- ContextualMode mode = instr->for_typeof() ? NOT_CONTEXTUAL : CONTEXTUAL;
- Handle<Code> ic = CodeFactory::LoadICInOptimizedCode(isolate(), mode, SLOPPY,
- PREMONOMORPHIC).code();
+ Handle<Code> ic =
+ CodeFactory::LoadICInOptimizedCode(isolate(), instr->typeof_mode(),
+ SLOPPY, PREMONOMORPHIC).code();
CallCode(ic, RelocInfo::CODE_TARGET, instr);
}
EmitVectorLoadICRegisters<LLoadNamedGeneric>(instr);
Handle<Code> ic =
CodeFactory::LoadICInOptimizedCode(
- isolate(), NOT_CONTEXTUAL, instr->hydrogen()->language_mode(),
+ isolate(), NOT_INSIDE_TYPEOF, instr->hydrogen()->language_mode(),
instr->hydrogen()->initialization_state()).code();
CallCode(ic, RelocInfo::CODE_TARGET, instr);
}
DECLARE_HYDROGEN_ACCESSOR(LoadGlobalGeneric)
Handle<Object> name() const { return hydrogen()->name(); }
- bool for_typeof() const { return hydrogen()->for_typeof(); }
+ TypeofMode typeof_mode() const { return hydrogen()->typeof_mode(); }
};
void LoadIC::set_target(Code* code) {
// The contextual mode must be preserved across IC patching.
- DCHECK(LoadICState::GetContextualMode(code->extra_ic_state()) ==
- LoadICState::GetContextualMode(target()->extra_ic_state()));
+ DCHECK(LoadICState::GetTypeofMode(code->extra_ic_state()) ==
+ LoadICState::GetTypeofMode(target()->extra_ic_state()));
// Strongness must be preserved across IC patching.
DCHECK(LoadICState::GetLanguageMode(code->extra_ic_state()) ==
LoadICState::GetLanguageMode(target()->extra_ic_state()));
class LoadICState final BASE_EMBEDDED {
private:
- class ContextualModeBits : public BitField<ContextualMode, 0, 1> {};
+ class TypeofModeBits : public BitField<TypeofMode, 0, 1> {};
class LanguageModeBits
- : public BitField<LanguageMode, ContextualModeBits::kNext, 2> {};
- STATIC_ASSERT(static_cast<int>(NOT_CONTEXTUAL) == 0);
+ : public BitField<LanguageMode, TypeofModeBits::kNext, 2> {};
+ STATIC_ASSERT(static_cast<int>(INSIDE_TYPEOF) == 0);
const ExtraICState state_;
public:
explicit LoadICState(ExtraICState extra_ic_state) : state_(extra_ic_state) {}
- explicit LoadICState(ContextualMode mode, LanguageMode language_mode)
- : state_(ContextualModeBits::encode(mode) |
+ explicit LoadICState(TypeofMode typeof_mode, LanguageMode language_mode)
+ : state_(TypeofModeBits::encode(typeof_mode) |
LanguageModeBits::encode(language_mode)) {}
ExtraICState GetExtraICState() const { return state_; }
- ContextualMode contextual_mode() const {
- return ContextualModeBits::decode(state_);
- }
+ TypeofMode typeof_mode() const { return TypeofModeBits::decode(state_); }
LanguageMode language_mode() const {
return LanguageModeBits::decode(state_);
}
- static ContextualMode GetContextualMode(ExtraICState state) {
- return LoadICState(state).contextual_mode();
+ static TypeofMode GetTypeofMode(ExtraICState state) {
+ return LoadICState(state).typeof_mode();
}
static LanguageMode GetLanguageMode(ExtraICState state) {
LookupIterator it(object, name);
LookupForRead(&it);
- if (it.IsFound() || !IsUndeclaredGlobal(object)) {
+ if (it.IsFound() || !ShouldThrowReferenceError(object)) {
// Update inline cache and stub cache.
if (use_ic) UpdateCaches(&it);
isolate(), result, Object::GetProperty(&it, language_mode()), Object);
if (it.IsFound()) {
return result;
- } else if (!IsUndeclaredGlobal(object)) {
+ } else if (!ShouldThrowReferenceError(object)) {
LOG(isolate(), SuspectReadEvent(*name, *object));
return result;
}
}
-static Object* ThrowReferenceError(Isolate* isolate, Name* name) {
- // If the load is non-contextual, just return the undefined result.
- // Note that both keyed and non-keyed loads may end up here.
- HandleScope scope(isolate);
- LoadIC ic(IC::NO_EXTRA_FRAME, isolate, true);
- if (ic.contextual_mode() != CONTEXTUAL) {
- return isolate->heap()->undefined_value();
- }
-
- // Throw a reference error.
- Handle<Name> name_handle(name);
- THROW_NEW_ERROR_RETURN_FAILURE(
- isolate, NewReferenceError(MessageTemplate::kNotDefined, name_handle));
-}
-
-
/**
* Loads a property with an interceptor performing post interceptor
* lookup if interceptor failed.
if (it.IsFound()) return *result;
- return ThrowReferenceError(isolate, Name::cast(args[0]));
+ // Return the undefined result if the reference error should not be thrown.
+ // Note that both keyed and non-keyed loads may end up here.
+ LoadIC ic(IC::NO_EXTRA_FRAME, isolate, true);
+ if (!ic.ShouldThrowReferenceError(it.GetReceiver())) {
+ return isolate->heap()->undefined_value();
+ }
+
+ // Throw a reference error.
+ THROW_NEW_ERROR_RETURN_FAILURE(
+ isolate, NewReferenceError(MessageTemplate::kNotDefined, it.name()));
}
class LoadIC : public IC {
public:
- static ExtraICState ComputeExtraICState(ContextualMode contextual_mode,
+ static ExtraICState ComputeExtraICState(TypeofMode typeof_mode,
LanguageMode language_mode) {
- return LoadICState(contextual_mode, language_mode).GetExtraICState();
+ return LoadICState(typeof_mode, language_mode).GetExtraICState();
}
- ContextualMode contextual_mode() const {
- return LoadICState::GetContextualMode(extra_ic_state());
+ TypeofMode typeof_mode() const {
+ return LoadICState::GetTypeofMode(extra_ic_state());
}
LanguageMode language_mode() const {
DCHECK(IsLoadStub());
}
- // Returns if this IC is for contextual (no explicit receiver)
- // access to properties.
- bool IsUndeclaredGlobal(Handle<Object> receiver) {
- if (receiver->IsGlobalObject()) {
- return contextual_mode() == CONTEXTUAL;
- } else {
- DCHECK(contextual_mode() != CONTEXTUAL);
- return false;
- }
+ bool ShouldThrowReferenceError(Handle<Object> receiver) {
+ return receiver->IsGlobalObject() && typeof_mode() == NOT_INSIDE_TYPEOF;
}
// Code generator routines.
class IcCheckTypeField
: public BitField<IcCheckType, LoadICState::kNextBitFieldOffset, 1> {};
- static ExtraICState ComputeExtraICState(ContextualMode contextual_mode,
+ static ExtraICState ComputeExtraICState(TypeofMode typeof_mode,
LanguageMode language_mode,
IcCheckType key_type) {
- return LoadICState(contextual_mode, language_mode).GetExtraICState() |
+ return LoadICState(typeof_mode, language_mode).GetExtraICState() |
IcCheckTypeField::encode(key_type);
}
namespace internal {
-enum TypeofState { INSIDE_TYPEOF, NOT_INSIDE_TYPEOF };
-
-
class StringCharLoadGenerator : public AllStatic {
public:
// Generates the code for handling different string types and loading the
void FullCodeGenerator::EmitLoadGlobalCheckExtensions(VariableProxy* proxy,
- TypeofState typeof_state,
+ TypeofMode typeof_mode,
Label* slow) {
Register current = cp;
Register next = a1;
// All extension objects were empty and it is safe to use a normal global
// load machinery.
- EmitGlobalVariableLoad(proxy, typeof_state);
+ EmitGlobalVariableLoad(proxy, typeof_mode);
}
void FullCodeGenerator::EmitDynamicLookupFastCase(VariableProxy* proxy,
- TypeofState typeof_state,
- Label* slow,
- Label* done) {
+ TypeofMode typeof_mode,
+ Label* slow, Label* done) {
// Generate fast-case code for variables that might be shadowed by
// eval-introduced variables. Eval is used a lot without
// introducing variables. In those cases, we do not want to
// containing the eval.
Variable* var = proxy->var();
if (var->mode() == DYNAMIC_GLOBAL) {
- EmitLoadGlobalCheckExtensions(proxy, typeof_state, slow);
+ EmitLoadGlobalCheckExtensions(proxy, typeof_mode, slow);
__ Branch(done);
} else if (var->mode() == DYNAMIC_LOCAL) {
Variable* local = var->local_if_not_shadowed();
void FullCodeGenerator::EmitGlobalVariableLoad(VariableProxy* proxy,
- TypeofState typeof_state) {
+ TypeofMode typeof_mode) {
Variable* var = proxy->var();
DCHECK(var->IsUnallocatedOrGlobalSlot() ||
(var->IsLookupSlot() && var->mode() == DYNAMIC_GLOBAL));
__ li(LoadDescriptor::NameRegister(), Operand(var->name()));
__ li(LoadDescriptor::SlotRegister(),
Operand(SmiFromSlot(proxy->VariableFeedbackSlot())));
- // Inside typeof use a regular load, not a contextual load, to avoid
- // a reference error.
- CallLoadIC(typeof_state == NOT_INSIDE_TYPEOF ? CONTEXTUAL : NOT_CONTEXTUAL);
+ CallLoadIC(typeof_mode);
}
}
void FullCodeGenerator::EmitVariableLoad(VariableProxy* proxy,
- TypeofState typeof_state) {
+ TypeofMode typeof_mode) {
// Record position before possible IC call.
SetExpressionPosition(proxy);
PrepareForBailoutForId(proxy->BeforeId(), NO_REGISTERS);
case VariableLocation::GLOBAL:
case VariableLocation::UNALLOCATED: {
Comment cmnt(masm_, "[ Global variable");
- EmitGlobalVariableLoad(proxy, typeof_state);
+ EmitGlobalVariableLoad(proxy, typeof_mode);
context()->Plug(v0);
break;
}
case VariableLocation::PARAMETER:
case VariableLocation::LOCAL:
case VariableLocation::CONTEXT: {
- DCHECK_EQ(NOT_INSIDE_TYPEOF, typeof_state);
+ DCHECK_EQ(NOT_INSIDE_TYPEOF, typeof_mode);
Comment cmnt(masm_, var->IsContextSlot() ? "[ Context variable"
: "[ Stack variable");
if (var->binding_needs_init()) {
Label done, slow;
// Generate code for loading from variables potentially shadowed
// by eval-introduced variables.
- EmitDynamicLookupFastCase(proxy, typeof_state, &slow, &done);
+ EmitDynamicLookupFastCase(proxy, typeof_mode, &slow, &done);
__ bind(&slow);
__ li(a1, Operand(var->name()));
__ Push(cp, a1); // Context and name.
Runtime::FunctionId function_id =
- typeof_state == NOT_INSIDE_TYPEOF
+ typeof_mode == NOT_INSIDE_TYPEOF
? Runtime::kLoadLookupSlot
: Runtime::kLoadLookupSlotNoReferenceError;
__ CallRuntime(function_id, 2);
__ LoadRoot(load_name, Heap::kdone_stringRootIndex); // "done"
__ li(LoadDescriptor::SlotRegister(),
Operand(SmiFromSlot(expr->DoneFeedbackSlot())));
- CallLoadIC(NOT_CONTEXTUAL); // v0=result.done
+ CallLoadIC(NOT_INSIDE_TYPEOF); // v0=result.done
__ mov(a0, v0);
Handle<Code> bool_ic = ToBooleanStub::GetUninitialized(isolate());
CallIC(bool_ic);
__ LoadRoot(load_name, Heap::kvalue_stringRootIndex); // "value"
__ li(LoadDescriptor::SlotRegister(),
Operand(SmiFromSlot(expr->ValueFeedbackSlot())));
- CallLoadIC(NOT_CONTEXTUAL); // v0=result.value
+ CallLoadIC(NOT_INSIDE_TYPEOF); // v0=result.value
context()->DropAndPlug(2, v0); // drop iter and g
break;
}
__ li(LoadDescriptor::NameRegister(), Operand(key->value()));
__ li(LoadDescriptor::SlotRegister(),
Operand(SmiFromSlot(prop->PropertyFeedbackSlot())));
- CallLoadIC(NOT_CONTEXTUAL, language_mode());
+ CallLoadIC(NOT_INSIDE_TYPEOF, language_mode());
}
__ li(LoadDescriptor::NameRegister(), Operand(expr->name()));
__ li(LoadDescriptor::SlotRegister(),
Operand(SmiFromSlot(expr->CallRuntimeFeedbackSlot())));
- CallLoadIC(NOT_CONTEXTUAL);
+ CallLoadIC(NOT_INSIDE_TYPEOF);
}
__ li(LoadDescriptor::NameRegister(), Operand(instr->name()));
EmitVectorLoadICRegisters<LLoadGlobalGeneric>(instr);
- ContextualMode mode = instr->for_typeof() ? NOT_CONTEXTUAL : CONTEXTUAL;
- Handle<Code> ic = CodeFactory::LoadICInOptimizedCode(isolate(), mode, SLOPPY,
- PREMONOMORPHIC).code();
+ Handle<Code> ic =
+ CodeFactory::LoadICInOptimizedCode(isolate(), instr->typeof_mode(),
+ SLOPPY, PREMONOMORPHIC).code();
CallCode(ic, RelocInfo::CODE_TARGET, instr);
}
EmitVectorLoadICRegisters<LLoadNamedGeneric>(instr);
Handle<Code> ic =
CodeFactory::LoadICInOptimizedCode(
- isolate(), NOT_CONTEXTUAL, instr->hydrogen()->language_mode(),
+ isolate(), NOT_INSIDE_TYPEOF, instr->hydrogen()->language_mode(),
instr->hydrogen()->initialization_state()).code();
CallCode(ic, RelocInfo::CODE_TARGET, instr);
}
DECLARE_HYDROGEN_ACCESSOR(LoadGlobalGeneric)
Handle<Object> name() const { return hydrogen()->name(); }
- bool for_typeof() const { return hydrogen()->for_typeof(); }
+ TypeofMode typeof_mode() const { return hydrogen()->typeof_mode(); }
};
namespace internal {
-enum TypeofState { INSIDE_TYPEOF, NOT_INSIDE_TYPEOF };
-
-
class StringCharLoadGenerator : public AllStatic {
public:
// Generates the code for handling different string types and loading the
void FullCodeGenerator::EmitLoadGlobalCheckExtensions(VariableProxy* proxy,
- TypeofState typeof_state,
+ TypeofMode typeof_mode,
Label* slow) {
Register current = cp;
Register next = a1;
// All extension objects were empty and it is safe to use a normal global
// load machinery.
- EmitGlobalVariableLoad(proxy, typeof_state);
+ EmitGlobalVariableLoad(proxy, typeof_mode);
}
void FullCodeGenerator::EmitDynamicLookupFastCase(VariableProxy* proxy,
- TypeofState typeof_state,
- Label* slow,
- Label* done) {
+ TypeofMode typeof_mode,
+ Label* slow, Label* done) {
// Generate fast-case code for variables that might be shadowed by
// eval-introduced variables. Eval is used a lot without
// introducing variables. In those cases, we do not want to
// containing the eval.
Variable* var = proxy->var();
if (var->mode() == DYNAMIC_GLOBAL) {
- EmitLoadGlobalCheckExtensions(proxy, typeof_state, slow);
+ EmitLoadGlobalCheckExtensions(proxy, typeof_mode, slow);
__ Branch(done);
} else if (var->mode() == DYNAMIC_LOCAL) {
Variable* local = var->local_if_not_shadowed();
void FullCodeGenerator::EmitGlobalVariableLoad(VariableProxy* proxy,
- TypeofState typeof_state) {
+ TypeofMode typeof_mode) {
Variable* var = proxy->var();
DCHECK(var->IsUnallocatedOrGlobalSlot() ||
(var->IsLookupSlot() && var->mode() == DYNAMIC_GLOBAL));
__ li(LoadDescriptor::NameRegister(), Operand(var->name()));
__ li(LoadDescriptor::SlotRegister(),
Operand(SmiFromSlot(proxy->VariableFeedbackSlot())));
- // Inside typeof use a regular load, not a contextual load, to avoid
- // a reference error.
- CallLoadIC(typeof_state == NOT_INSIDE_TYPEOF ? CONTEXTUAL : NOT_CONTEXTUAL);
+ CallLoadIC(typeof_mode);
}
}
void FullCodeGenerator::EmitVariableLoad(VariableProxy* proxy,
- TypeofState typeof_state) {
+ TypeofMode typeof_mode) {
// Record position before possible IC call.
SetExpressionPosition(proxy);
PrepareForBailoutForId(proxy->BeforeId(), NO_REGISTERS);
case VariableLocation::GLOBAL:
case VariableLocation::UNALLOCATED: {
Comment cmnt(masm_, "[ Global variable");
- EmitGlobalVariableLoad(proxy, typeof_state);
+ EmitGlobalVariableLoad(proxy, typeof_mode);
context()->Plug(v0);
break;
}
case VariableLocation::PARAMETER:
case VariableLocation::LOCAL:
case VariableLocation::CONTEXT: {
- DCHECK_EQ(NOT_INSIDE_TYPEOF, typeof_state);
+ DCHECK_EQ(NOT_INSIDE_TYPEOF, typeof_mode);
Comment cmnt(masm_, var->IsContextSlot() ? "[ Context variable"
: "[ Stack variable");
if (var->binding_needs_init()) {
Label done, slow;
// Generate code for loading from variables potentially shadowed
// by eval-introduced variables.
- EmitDynamicLookupFastCase(proxy, typeof_state, &slow, &done);
+ EmitDynamicLookupFastCase(proxy, typeof_mode, &slow, &done);
__ bind(&slow);
__ li(a1, Operand(var->name()));
__ Push(cp, a1); // Context and name.
Runtime::FunctionId function_id =
- typeof_state == NOT_INSIDE_TYPEOF
+ typeof_mode == NOT_INSIDE_TYPEOF
? Runtime::kLoadLookupSlot
: Runtime::kLoadLookupSlotNoReferenceError;
__ CallRuntime(function_id, 2);
__ LoadRoot(load_name, Heap::kdone_stringRootIndex); // "done"
__ li(LoadDescriptor::SlotRegister(),
Operand(SmiFromSlot(expr->DoneFeedbackSlot())));
- CallLoadIC(NOT_CONTEXTUAL); // v0=result.done
+ CallLoadIC(NOT_INSIDE_TYPEOF); // v0=result.done
__ mov(a0, v0);
Handle<Code> bool_ic = ToBooleanStub::GetUninitialized(isolate());
CallIC(bool_ic);
__ LoadRoot(load_name, Heap::kvalue_stringRootIndex); // "value"
__ li(LoadDescriptor::SlotRegister(),
Operand(SmiFromSlot(expr->ValueFeedbackSlot())));
- CallLoadIC(NOT_CONTEXTUAL); // v0=result.value
+ CallLoadIC(NOT_INSIDE_TYPEOF); // v0=result.value
context()->DropAndPlug(2, v0); // drop iter and g
break;
}
__ li(LoadDescriptor::NameRegister(), Operand(key->value()));
__ li(LoadDescriptor::SlotRegister(),
Operand(SmiFromSlot(prop->PropertyFeedbackSlot())));
- CallLoadIC(NOT_CONTEXTUAL, language_mode());
+ CallLoadIC(NOT_INSIDE_TYPEOF, language_mode());
}
__ li(LoadDescriptor::NameRegister(), Operand(expr->name()));
__ li(LoadDescriptor::SlotRegister(),
Operand(SmiFromSlot(expr->CallRuntimeFeedbackSlot())));
- CallLoadIC(NOT_CONTEXTUAL);
+ CallLoadIC(NOT_INSIDE_TYPEOF);
}
__ li(LoadDescriptor::NameRegister(), Operand(instr->name()));
EmitVectorLoadICRegisters<LLoadGlobalGeneric>(instr);
- ContextualMode mode = instr->for_typeof() ? NOT_CONTEXTUAL : CONTEXTUAL;
- Handle<Code> ic = CodeFactory::LoadICInOptimizedCode(isolate(), mode, SLOPPY,
- PREMONOMORPHIC).code();
+ Handle<Code> ic =
+ CodeFactory::LoadICInOptimizedCode(isolate(), instr->typeof_mode(),
+ SLOPPY, PREMONOMORPHIC).code();
CallCode(ic, RelocInfo::CODE_TARGET, instr);
}
EmitVectorLoadICRegisters<LLoadNamedGeneric>(instr);
Handle<Code> ic =
CodeFactory::LoadICInOptimizedCode(
- isolate(), NOT_CONTEXTUAL, instr->hydrogen()->language_mode(),
+ isolate(), NOT_INSIDE_TYPEOF, instr->hydrogen()->language_mode(),
instr->hydrogen()->initialization_state()).code();
CallCode(ic, RelocInfo::CODE_TARGET, instr);
}
DECLARE_HYDROGEN_ACCESSOR(LoadGlobalGeneric)
Handle<Object> name() const { return hydrogen()->name(); }
- bool for_typeof() const { return hydrogen()->for_typeof(); }
+ TypeofMode typeof_mode() const { return hydrogen()->typeof_mode(); }
};
};
-enum ContextualMode {
- NOT_CONTEXTUAL,
- CONTEXTUAL
-};
+enum TypeofMode { INSIDE_TYPEOF, NOT_INSIDE_TYPEOF };
enum MutableMode {
namespace internal {
-enum TypeofState { INSIDE_TYPEOF, NOT_INSIDE_TYPEOF };
-
-
class StringCharLoadGenerator : public AllStatic {
public:
// Generates the code for handling different string types and loading the
void FullCodeGenerator::EmitLoadGlobalCheckExtensions(VariableProxy* proxy,
- TypeofState typeof_state,
+ TypeofMode typeof_mode,
Label* slow) {
Register current = cp;
Register next = r4;
// All extension objects were empty and it is safe to use a normal global
// load machinery.
- EmitGlobalVariableLoad(proxy, typeof_state);
+ EmitGlobalVariableLoad(proxy, typeof_mode);
}
void FullCodeGenerator::EmitDynamicLookupFastCase(VariableProxy* proxy,
- TypeofState typeof_state,
+ TypeofMode typeof_mode,
Label* slow, Label* done) {
// Generate fast-case code for variables that might be shadowed by
// eval-introduced variables. Eval is used a lot without
// containing the eval.
Variable* var = proxy->var();
if (var->mode() == DYNAMIC_GLOBAL) {
- EmitLoadGlobalCheckExtensions(proxy, typeof_state, slow);
+ EmitLoadGlobalCheckExtensions(proxy, typeof_mode, slow);
__ b(done);
} else if (var->mode() == DYNAMIC_LOCAL) {
Variable* local = var->local_if_not_shadowed();
void FullCodeGenerator::EmitGlobalVariableLoad(VariableProxy* proxy,
- TypeofState typeof_state) {
+ TypeofMode typeof_mode) {
Variable* var = proxy->var();
DCHECK(var->IsUnallocatedOrGlobalSlot() ||
(var->IsLookupSlot() && var->mode() == DYNAMIC_GLOBAL));
__ mov(LoadDescriptor::NameRegister(), Operand(var->name()));
__ mov(LoadDescriptor::SlotRegister(),
Operand(SmiFromSlot(proxy->VariableFeedbackSlot())));
- // Inside typeof use a regular load, not a contextual load, to avoid
- // a reference error.
- CallLoadIC(typeof_state == NOT_INSIDE_TYPEOF ? CONTEXTUAL : NOT_CONTEXTUAL);
+ CallLoadIC(typeof_mode);
}
}
void FullCodeGenerator::EmitVariableLoad(VariableProxy* proxy,
- TypeofState typeof_state) {
+ TypeofMode typeof_mode) {
// Record position before possible IC call.
SetExpressionPosition(proxy);
PrepareForBailoutForId(proxy->BeforeId(), NO_REGISTERS);
case VariableLocation::GLOBAL:
case VariableLocation::UNALLOCATED: {
Comment cmnt(masm_, "[ Global variable");
- EmitGlobalVariableLoad(proxy, typeof_state);
+ EmitGlobalVariableLoad(proxy, typeof_mode);
context()->Plug(r3);
break;
}
case VariableLocation::PARAMETER:
case VariableLocation::LOCAL:
case VariableLocation::CONTEXT: {
- DCHECK_EQ(NOT_INSIDE_TYPEOF, typeof_state);
+ DCHECK_EQ(NOT_INSIDE_TYPEOF, typeof_mode);
Comment cmnt(masm_, var->IsContextSlot() ? "[ Context variable"
: "[ Stack variable");
if (var->binding_needs_init()) {
Label done, slow;
// Generate code for loading from variables potentially shadowed
// by eval-introduced variables.
- EmitDynamicLookupFastCase(proxy, typeof_state, &slow, &done);
+ EmitDynamicLookupFastCase(proxy, typeof_mode, &slow, &done);
__ bind(&slow);
__ mov(r4, Operand(var->name()));
__ Push(cp, r4); // Context and name.
Runtime::FunctionId function_id =
- typeof_state == NOT_INSIDE_TYPEOF
+ typeof_mode == NOT_INSIDE_TYPEOF
? Runtime::kLoadLookupSlot
: Runtime::kLoadLookupSlotNoReferenceError;
__ CallRuntime(function_id, 2);
__ LoadRoot(load_name, Heap::kdone_stringRootIndex); // "done"
__ mov(LoadDescriptor::SlotRegister(),
Operand(SmiFromSlot(expr->DoneFeedbackSlot())));
- CallLoadIC(NOT_CONTEXTUAL); // r0=result.done
+ CallLoadIC(NOT_INSIDE_TYPEOF); // r0=result.done
Handle<Code> bool_ic = ToBooleanStub::GetUninitialized(isolate());
CallIC(bool_ic);
__ cmpi(r3, Operand::Zero());
__ LoadRoot(load_name, Heap::kvalue_stringRootIndex); // "value"
__ mov(LoadDescriptor::SlotRegister(),
Operand(SmiFromSlot(expr->ValueFeedbackSlot())));
- CallLoadIC(NOT_CONTEXTUAL); // r3=result.value
+ CallLoadIC(NOT_INSIDE_TYPEOF); // r3=result.value
context()->DropAndPlug(2, r3); // drop iter and g
break;
}
__ mov(LoadDescriptor::NameRegister(), Operand(key->value()));
__ mov(LoadDescriptor::SlotRegister(),
Operand(SmiFromSlot(prop->PropertyFeedbackSlot())));
- CallLoadIC(NOT_CONTEXTUAL, language_mode());
+ CallLoadIC(NOT_INSIDE_TYPEOF, language_mode());
}
__ mov(LoadDescriptor::NameRegister(), Operand(expr->name()));
__ mov(LoadDescriptor::SlotRegister(),
Operand(SmiFromSlot(expr->CallRuntimeFeedbackSlot())));
- CallLoadIC(NOT_CONTEXTUAL);
+ CallLoadIC(NOT_INSIDE_TYPEOF);
}
__ mov(LoadDescriptor::NameRegister(), Operand(instr->name()));
EmitVectorLoadICRegisters<LLoadGlobalGeneric>(instr);
- ContextualMode mode = instr->for_typeof() ? NOT_CONTEXTUAL : CONTEXTUAL;
- Handle<Code> ic = CodeFactory::LoadICInOptimizedCode(isolate(), mode, SLOPPY,
- PREMONOMORPHIC).code();
+ Handle<Code> ic =
+ CodeFactory::LoadICInOptimizedCode(isolate(), instr->typeof_mode(),
+ SLOPPY, PREMONOMORPHIC).code();
CallCode(ic, RelocInfo::CODE_TARGET, instr);
}
EmitVectorLoadICRegisters<LLoadNamedGeneric>(instr);
Handle<Code> ic =
CodeFactory::LoadICInOptimizedCode(
- isolate(), NOT_CONTEXTUAL, instr->hydrogen()->language_mode(),
+ isolate(), NOT_INSIDE_TYPEOF, instr->hydrogen()->language_mode(),
instr->hydrogen()->initialization_state()).code();
CallCode(ic, RelocInfo::CODE_TARGET, instr);
}
DECLARE_HYDROGEN_ACCESSOR(LoadGlobalGeneric)
Handle<Object> name() const { return hydrogen()->name(); }
- bool for_typeof() const { return hydrogen()->for_typeof(); }
+ TypeofMode typeof_mode() const { return hydrogen()->typeof_mode(); }
};
namespace internal {
-enum TypeofState { INSIDE_TYPEOF, NOT_INSIDE_TYPEOF };
-
-
class StringCharLoadGenerator : public AllStatic {
public:
// Generates the code for handling different string types and loading the
void FullCodeGenerator::EmitLoadGlobalCheckExtensions(VariableProxy* proxy,
- TypeofState typeof_state,
+ TypeofMode typeof_mode,
Label* slow) {
Register context = rsi;
Register temp = rdx;
// All extension objects were empty and it is safe to use a normal global
// load machinery.
- EmitGlobalVariableLoad(proxy, typeof_state);
+ EmitGlobalVariableLoad(proxy, typeof_mode);
}
void FullCodeGenerator::EmitDynamicLookupFastCase(VariableProxy* proxy,
- TypeofState typeof_state,
- Label* slow,
- Label* done) {
+ TypeofMode typeof_mode,
+ Label* slow, Label* done) {
// Generate fast-case code for variables that might be shadowed by
// eval-introduced variables. Eval is used a lot without
// introducing variables. In those cases, we do not want to
// containing the eval.
Variable* var = proxy->var();
if (var->mode() == DYNAMIC_GLOBAL) {
- EmitLoadGlobalCheckExtensions(proxy, typeof_state, slow);
+ EmitLoadGlobalCheckExtensions(proxy, typeof_mode, slow);
__ jmp(done);
} else if (var->mode() == DYNAMIC_LOCAL) {
Variable* local = var->local_if_not_shadowed();
void FullCodeGenerator::EmitGlobalVariableLoad(VariableProxy* proxy,
- TypeofState typeof_state) {
+ TypeofMode typeof_mode) {
Variable* var = proxy->var();
DCHECK(var->IsUnallocatedOrGlobalSlot() ||
(var->IsLookupSlot() && var->mode() == DYNAMIC_GLOBAL));
__ movp(LoadDescriptor::ReceiverRegister(), GlobalObjectOperand());
__ Move(LoadDescriptor::SlotRegister(),
SmiFromSlot(proxy->VariableFeedbackSlot()));
- // Inside typeof use a regular load, not a contextual load, to avoid
- // a reference error.
- CallLoadIC(typeof_state == NOT_INSIDE_TYPEOF ? CONTEXTUAL : NOT_CONTEXTUAL);
+ CallLoadIC(typeof_mode);
}
}
void FullCodeGenerator::EmitVariableLoad(VariableProxy* proxy,
- TypeofState typeof_state) {
+ TypeofMode typeof_mode) {
// Record position before possible IC call.
SetExpressionPosition(proxy);
PrepareForBailoutForId(proxy->BeforeId(), NO_REGISTERS);
case VariableLocation::GLOBAL:
case VariableLocation::UNALLOCATED: {
Comment cmnt(masm_, "[ Global variable");
- EmitGlobalVariableLoad(proxy, typeof_state);
+ EmitGlobalVariableLoad(proxy, typeof_mode);
context()->Plug(rax);
break;
}
case VariableLocation::PARAMETER:
case VariableLocation::LOCAL:
case VariableLocation::CONTEXT: {
- DCHECK_EQ(NOT_INSIDE_TYPEOF, typeof_state);
+ DCHECK_EQ(NOT_INSIDE_TYPEOF, typeof_mode);
Comment cmnt(masm_, var->IsContextSlot() ? "[ Context slot"
: "[ Stack slot");
if (var->binding_needs_init()) {
Label done, slow;
// Generate code for loading from variables potentially shadowed
// by eval-introduced variables.
- EmitDynamicLookupFastCase(proxy, typeof_state, &slow, &done);
+ EmitDynamicLookupFastCase(proxy, typeof_mode, &slow, &done);
__ bind(&slow);
__ Push(rsi); // Context.
__ Push(var->name());
Runtime::FunctionId function_id =
- typeof_state == NOT_INSIDE_TYPEOF
+ typeof_mode == NOT_INSIDE_TYPEOF
? Runtime::kLoadLookupSlot
: Runtime::kLoadLookupSlotNoReferenceError;
__ CallRuntime(function_id, 2);
__ LoadRoot(load_name, Heap::kdone_stringRootIndex); // "done"
__ Move(LoadDescriptor::SlotRegister(),
SmiFromSlot(expr->DoneFeedbackSlot()));
- CallLoadIC(NOT_CONTEXTUAL); // rax=result.done
+ CallLoadIC(NOT_INSIDE_TYPEOF); // rax=result.done
Handle<Code> bool_ic = ToBooleanStub::GetUninitialized(isolate());
CallIC(bool_ic);
__ testp(result_register(), result_register());
__ LoadRoot(load_name, Heap::kvalue_stringRootIndex); // "value"
__ Move(LoadDescriptor::SlotRegister(),
SmiFromSlot(expr->ValueFeedbackSlot()));
- CallLoadIC(NOT_CONTEXTUAL); // result.value in rax
+ CallLoadIC(NOT_INSIDE_TYPEOF); // result.value in rax
context()->DropAndPlug(2, rax); // drop iter and g
break;
}
__ Move(LoadDescriptor::NameRegister(), key->value());
__ Move(LoadDescriptor::SlotRegister(),
SmiFromSlot(prop->PropertyFeedbackSlot()));
- CallLoadIC(NOT_CONTEXTUAL, language_mode());
+ CallLoadIC(NOT_INSIDE_TYPEOF, language_mode());
}
__ Move(LoadDescriptor::NameRegister(), expr->name());
__ Move(LoadDescriptor::SlotRegister(),
SmiFromSlot(expr->CallRuntimeFeedbackSlot()));
- CallLoadIC(NOT_CONTEXTUAL);
+ CallLoadIC(NOT_INSIDE_TYPEOF);
}
__ Move(LoadDescriptor::NameRegister(), instr->name());
EmitVectorLoadICRegisters<LLoadGlobalGeneric>(instr);
- ContextualMode mode = instr->for_typeof() ? NOT_CONTEXTUAL : CONTEXTUAL;
- Handle<Code> ic = CodeFactory::LoadICInOptimizedCode(isolate(), mode, SLOPPY,
- PREMONOMORPHIC).code();
+ Handle<Code> ic =
+ CodeFactory::LoadICInOptimizedCode(isolate(), instr->typeof_mode(),
+ SLOPPY, PREMONOMORPHIC).code();
CallCode(ic, RelocInfo::CODE_TARGET, instr);
}
EmitVectorLoadICRegisters<LLoadNamedGeneric>(instr);
Handle<Code> ic =
CodeFactory::LoadICInOptimizedCode(
- isolate(), NOT_CONTEXTUAL, instr->hydrogen()->language_mode(),
+ isolate(), NOT_INSIDE_TYPEOF, instr->hydrogen()->language_mode(),
instr->hydrogen()->initialization_state()).code();
CallCode(ic, RelocInfo::CODE_TARGET, instr);
}
LOperand* temp_vector() { return temps_[0]; }
Handle<Object> name() const { return hydrogen()->name(); }
- bool for_typeof() const { return hydrogen()->for_typeof(); }
+ TypeofMode typeof_mode() const { return hydrogen()->typeof_mode(); }
};
void FullCodeGenerator::EmitLoadGlobalCheckExtensions(VariableProxy* proxy,
- TypeofState typeof_state,
+ TypeofMode typeof_mode,
Label* slow) {
Register context = esi;
Register temp = edx;
// All extension objects were empty and it is safe to use a normal global
// load machinery.
- EmitGlobalVariableLoad(proxy, typeof_state);
+ EmitGlobalVariableLoad(proxy, typeof_mode);
}
void FullCodeGenerator::EmitDynamicLookupFastCase(VariableProxy* proxy,
- TypeofState typeof_state,
- Label* slow,
- Label* done) {
+ TypeofMode typeof_mode,
+ Label* slow, Label* done) {
// Generate fast-case code for variables that might be shadowed by
// eval-introduced variables. Eval is used a lot without
// introducing variables. In those cases, we do not want to
// containing the eval.
Variable* var = proxy->var();
if (var->mode() == DYNAMIC_GLOBAL) {
- EmitLoadGlobalCheckExtensions(proxy, typeof_state, slow);
+ EmitLoadGlobalCheckExtensions(proxy, typeof_mode, slow);
__ jmp(done);
} else if (var->mode() == DYNAMIC_LOCAL) {
Variable* local = var->local_if_not_shadowed();
void FullCodeGenerator::EmitGlobalVariableLoad(VariableProxy* proxy,
- TypeofState typeof_state) {
+ TypeofMode typeof_mode) {
Variable* var = proxy->var();
DCHECK(var->IsUnallocatedOrGlobalSlot() ||
(var->IsLookupSlot() && var->mode() == DYNAMIC_GLOBAL));
__ mov(LoadDescriptor::NameRegister(), var->name());
__ mov(LoadDescriptor::SlotRegister(),
Immediate(SmiFromSlot(proxy->VariableFeedbackSlot())));
- // Inside typeof use a regular load, not a contextual load, to avoid
- // a reference error.
- CallLoadIC(typeof_state == NOT_INSIDE_TYPEOF ? CONTEXTUAL : NOT_CONTEXTUAL);
+ CallLoadIC(typeof_mode);
}
}
void FullCodeGenerator::EmitVariableLoad(VariableProxy* proxy,
- TypeofState typeof_state) {
+ TypeofMode typeof_mode) {
SetExpressionPosition(proxy);
PrepareForBailoutForId(proxy->BeforeId(), NO_REGISTERS);
Variable* var = proxy->var();
case VariableLocation::GLOBAL:
case VariableLocation::UNALLOCATED: {
Comment cmnt(masm_, "[ Global variable");
- EmitGlobalVariableLoad(proxy, typeof_state);
+ EmitGlobalVariableLoad(proxy, typeof_mode);
context()->Plug(eax);
break;
}
case VariableLocation::PARAMETER:
case VariableLocation::LOCAL:
case VariableLocation::CONTEXT: {
- DCHECK_EQ(NOT_INSIDE_TYPEOF, typeof_state);
+ DCHECK_EQ(NOT_INSIDE_TYPEOF, typeof_mode);
Comment cmnt(masm_, var->IsContextSlot() ? "[ Context variable"
: "[ Stack variable");
if (var->binding_needs_init()) {
Label done, slow;
// Generate code for loading from variables potentially shadowed
// by eval-introduced variables.
- EmitDynamicLookupFastCase(proxy, typeof_state, &slow, &done);
+ EmitDynamicLookupFastCase(proxy, typeof_mode, &slow, &done);
__ bind(&slow);
__ push(esi); // Context.
__ push(Immediate(var->name()));
Runtime::FunctionId function_id =
- typeof_state == NOT_INSIDE_TYPEOF
+ typeof_mode == NOT_INSIDE_TYPEOF
? Runtime::kLoadLookupSlot
: Runtime::kLoadLookupSlotNoReferenceError;
__ CallRuntime(function_id, 2);
isolate()->factory()->done_string()); // "done"
__ mov(LoadDescriptor::SlotRegister(),
Immediate(SmiFromSlot(expr->DoneFeedbackSlot())));
- CallLoadIC(NOT_CONTEXTUAL); // result.done in eax
+ CallLoadIC(NOT_INSIDE_TYPEOF); // result.done in eax
Handle<Code> bool_ic = ToBooleanStub::GetUninitialized(isolate());
CallIC(bool_ic);
__ test(eax, eax);
isolate()->factory()->value_string()); // "value"
__ mov(LoadDescriptor::SlotRegister(),
Immediate(SmiFromSlot(expr->ValueFeedbackSlot())));
- CallLoadIC(NOT_CONTEXTUAL); // result.value in eax
+ CallLoadIC(NOT_INSIDE_TYPEOF); // result.value in eax
context()->DropAndPlug(2, eax); // drop iter and g
break;
}
__ mov(LoadDescriptor::NameRegister(), Immediate(key->value()));
__ mov(LoadDescriptor::SlotRegister(),
Immediate(SmiFromSlot(prop->PropertyFeedbackSlot())));
- CallLoadIC(NOT_CONTEXTUAL, language_mode());
+ CallLoadIC(NOT_INSIDE_TYPEOF, language_mode());
}
__ mov(LoadDescriptor::NameRegister(), Immediate(expr->name()));
__ mov(LoadDescriptor::SlotRegister(),
Immediate(SmiFromSlot(expr->CallRuntimeFeedbackSlot())));
- CallLoadIC(NOT_CONTEXTUAL);
+ CallLoadIC(NOT_INSIDE_TYPEOF);
}
__ mov(LoadDescriptor::NameRegister(), instr->name());
EmitVectorLoadICRegisters<LLoadGlobalGeneric>(instr);
- ContextualMode mode = instr->for_typeof() ? NOT_CONTEXTUAL : CONTEXTUAL;
- Handle<Code> ic = CodeFactory::LoadICInOptimizedCode(isolate(), mode, SLOPPY,
- PREMONOMORPHIC).code();
+ Handle<Code> ic =
+ CodeFactory::LoadICInOptimizedCode(isolate(), instr->typeof_mode(),
+ SLOPPY, PREMONOMORPHIC).code();
CallCode(ic, RelocInfo::CODE_TARGET, instr);
}
EmitVectorLoadICRegisters<LLoadNamedGeneric>(instr);
Handle<Code> ic =
CodeFactory::LoadICInOptimizedCode(
- isolate(), NOT_CONTEXTUAL, instr->hydrogen()->language_mode(),
+ isolate(), NOT_INSIDE_TYPEOF, instr->hydrogen()->language_mode(),
instr->hydrogen()->initialization_state()).code();
CallCode(ic, RelocInfo::CODE_TARGET, instr);
}
DECLARE_HYDROGEN_ACCESSOR(LoadGlobalGeneric)
Handle<Object> name() const { return hydrogen()->name(); }
- bool for_typeof() const { return hydrogen()->for_typeof(); }
+ TypeofMode typeof_mode() const { return hydrogen()->typeof_mode(); }
};
__ bind(&L2);
__ call(Operand(ebx, ecx, times_4, 10000));
__ nop();
- Handle<Code> ic(LoadIC::initialize_stub(isolate, NOT_CONTEXTUAL));
+ Handle<Code> ic(LoadIC::initialize_stub(isolate, NOT_INSIDE_TYPEOF));
__ call(ic, RelocInfo::CODE_TARGET);
__ nop();
__ call(FUNCTION_ADDR(DummyStaticFunction), RelocInfo::RUNTIME_ENTRY);
// TODO(mstarzinger): The following is protected.
// __ call(Operand(rbx, rcx, times_4, 10000));
__ nop();
- Handle<Code> ic(LoadIC::initialize_stub(isolate, NOT_CONTEXTUAL));
+ Handle<Code> ic(LoadIC::initialize_stub(isolate, NOT_INSIDE_TYPEOF));
__ call(ic, RelocInfo::CODE_TARGET);
__ nop();
__ nop();
__ bind(&L2);
__ call(Operand(ebx, ecx, times_4, 10000));
__ nop();
- Handle<Code> ic(LoadIC::initialize_stub(isolate, NOT_CONTEXTUAL));
+ Handle<Code> ic(LoadIC::initialize_stub(isolate, NOT_INSIDE_TYPEOF));
__ call(ic, RelocInfo::CODE_TARGET);
__ nop();
__ call(FUNCTION_ADDR(DummyStaticFunction), RelocInfo::RUNTIME_ENTRY);
for (int i = 0; i < DynamicGlobalAccess::kMaxCheckDepth; ++i) {
uint32_t bitset = 1 << i; // Only single check.
Reduction r = Reduce(graph()->NewNode(
- javascript()->LoadDynamicGlobal(name, bitset, feedback, NOT_CONTEXTUAL),
+ javascript()->LoadDynamicGlobal(name, bitset, feedback,
+ NOT_INSIDE_TYPEOF),
vector, context, context, frame_state, frame_state, effect, control));
ASSERT_TRUE(r.Changed());
EXPECT_THAT(