Index: src/hydrogen-instructions.h |
diff --git a/src/hydrogen-instructions.h b/src/hydrogen-instructions.h |
index c9a4bf062d3a7c3c6b4c79d36d4abe4959c6d8e2..213e0c69524476b9475994f549f18d94efc660af 100644 |
--- a/src/hydrogen-instructions.h |
+++ b/src/hydrogen-instructions.h |
@@ -3447,8 +3447,21 @@ class HStoreGlobalGeneric: public HTemplateInstruction<3> { |
class HLoadContextSlot: public HUnaryOperation { |
public: |
- HLoadContextSlot(HValue* context , int slot_index) |
- : HUnaryOperation(context), slot_index_(slot_index) { |
+ enum Mode { |
+ // Perform a normal load of the context slot without checking its value. |
+ kLoad, |
+ // Load and check the value of the context slot. Deoptimize if it's the |
+ // hole value. This is used for checking for loading of uninitialized |
+ // harmony bindings where we deoptimize into full-codegen generated code |
+ // which will subsequently throw a reference error. |
+ kLoadCheck |
+ }; |
+ |
+ HLoadContextSlot(HValue* context, Variable* var) |
+ : HUnaryOperation(context), slot_index_(var->index()) { |
+ ASSERT(var->IsContextSlot()); |
+ mode_ = (var->mode() == LET || var->mode() == CONST_HARMONY) |
+ ? kLoadCheck : kLoad; |
set_representation(Representation::Tagged()); |
SetFlag(kUseGVN); |
SetFlag(kDependsOnContextSlots); |
@@ -3456,6 +3469,10 @@ class HLoadContextSlot: public HUnaryOperation { |
int slot_index() const { return slot_index_; } |
+ bool RequiresHoleCheck() { |
+ return mode_ == kLoadCheck; |
+ } |
+ |
virtual Representation RequiredInputRepresentation(int index) { |
return Representation::Tagged(); |
} |
@@ -3472,13 +3489,35 @@ class HLoadContextSlot: public HUnaryOperation { |
private: |
int slot_index_; |
+ Mode mode_; |
}; |
class HStoreContextSlot: public HTemplateInstruction<2> { |
public: |
- HStoreContextSlot(HValue* context, int slot_index, HValue* value) |
- : slot_index_(slot_index) { |
+ enum Mode { |
+ // Perform a normal store to the context slot without checking its previous |
+ // value. |
+ kAssign, |
+ // Check the previous value of the context slot and deoptimize if it's the |
+ // hole value. This is used for checking for assignments to uninitialized |
+ // harmony bindings where we deoptimize into full-codegen generated code |
+ // which will subsequently throw a reference error. |
+ kAssignCheck |
+ }; |
+ |
+ HStoreContextSlot(HValue* context, Variable* var, HValue* value) |
+ : slot_index_(var->index()) { |
fschneider
2011/12/09 08:37:40
I'm not convinced that two constructors are better
Steven
2011/12/09 09:44:56
Agreed.
|
+ ASSERT(var->IsContextSlot()); |
+ mode_ = (var->mode() == LET || var->mode() == CONST_HARMONY) |
+ ? kAssignCheck : kAssign; |
+ SetOperandAt(0, context); |
+ SetOperandAt(1, value); |
+ SetFlag(kChangesContextSlots); |
+ } |
+ |
+ HStoreContextSlot(HValue* context, int slot_index, Mode mode, HValue* value) |
+ : slot_index_(slot_index), mode_(mode) { |
SetOperandAt(0, context); |
SetOperandAt(1, value); |
SetFlag(kChangesContextSlots); |
@@ -3487,11 +3526,16 @@ class HStoreContextSlot: public HTemplateInstruction<2> { |
HValue* context() { return OperandAt(0); } |
HValue* value() { return OperandAt(1); } |
int slot_index() const { return slot_index_; } |
+ Mode mode() const { return mode_; } |
bool NeedsWriteBarrier() { |
return StoringValueNeedsWriteBarrier(value()); |
} |
+ bool RequiresHoleCheck() { |
+ return mode_ == kAssignCheck; |
+ } |
+ |
virtual Representation RequiredInputRepresentation(int index) { |
return Representation::Tagged(); |
} |
@@ -3502,6 +3546,7 @@ class HStoreContextSlot: public HTemplateInstruction<2> { |
private: |
int slot_index_; |
+ Mode mode_; |
}; |