Version 3.1.4
Fixed incorrect compare of prototypes of the global object (issue 1082).
Fixed a bug in optimizing calls to global functions (issue 1106).
Made optimized Function.prototype.apply safe for non-JSObject first arguments (issue 1128).
Fixed an error related to element accessors on Object.prototype and parser errors (issue 1130).
Fixed a bug in sorting an array with large array indices (issue 1131).
Properly treat exceptions thrown while compiling (issue 1132).
Fixed bug in register requirements for function.apply (issue 1133).
Fixed a representation change bug in the Hydrogen graph construction (issue 1134).
Fixed the semantics of delete on parameters (issue 1136).
Fixed a optimizer bug related to moving instructions with side effects (issue 1138).
Added support for the global object in Object.keys (issue 1150).
Fixed incorrect value for Math.LOG10E (issue http://code.google.com/p/chromium/issues/detail?id=72555)
Performance improvements on the IA32 platform.
Implement assignment to undefined reference in ES5 Strict Mode.
git-svn-id: http://v8.googlecode.com/svn/trunk@6768 ce2b1a6d-e550-0410-aec6-3dcde31c8c00
diff --git a/src/hydrogen-instructions.h b/src/hydrogen-instructions.h
index 05ff68c..a0d932f 100644
--- a/src/hydrogen-instructions.h
+++ b/src/hydrogen-instructions.h
@@ -48,6 +48,7 @@
#define HYDROGEN_ALL_INSTRUCTION_LIST(V) \
V(ArithmeticBinaryOperation) \
+ V(BinaryCall) \
V(BinaryOperation) \
V(BitwiseBinaryOperation) \
V(Call) \
@@ -58,6 +59,7 @@
V(Phi) \
V(StoreKeyed) \
V(StoreNamed) \
+ V(UnaryCall) \
V(UnaryControlInstruction) \
V(UnaryOperation) \
HYDROGEN_CONCRETE_INSTRUCTION_LIST(V)
@@ -127,12 +129,15 @@
V(LoadKeyedGeneric) \
V(LoadNamedField) \
V(LoadNamedGeneric) \
+ V(LoadPixelArrayElement) \
+ V(LoadPixelArrayExternalPointer) \
V(Mod) \
V(Mul) \
V(ObjectLiteral) \
V(OsrEntry) \
V(OuterContext) \
V(Parameter) \
+ V(PixelArrayLength) \
V(Power) \
V(PushArgument) \
V(RegExpLiteral) \
@@ -164,6 +169,7 @@
V(InobjectFields) \
V(BackingStoreFields) \
V(ArrayElements) \
+ V(PixelArrayElements) \
V(GlobalVars) \
V(Maps) \
V(ArrayLengths) \
@@ -289,6 +295,7 @@
kTagged,
kDouble,
kInteger32,
+ kExternal,
kNumRepresentations
};
@@ -298,6 +305,7 @@
static Representation Tagged() { return Representation(kTagged); }
static Representation Integer32() { return Representation(kInteger32); }
static Representation Double() { return Representation(kDouble); }
+ static Representation External() { return Representation(kExternal); }
bool Equals(const Representation& other) const {
return kind_ == other.kind_;
@@ -308,6 +316,7 @@
bool IsTagged() const { return kind_ == kTagged; }
bool IsInteger32() const { return kind_ == kInteger32; }
bool IsDouble() const { return kind_ == kDouble; }
+ bool IsExternal() const { return kind_ == kExternal; }
bool IsSpecialization() const {
return kind_ == kInteger32 || kind_ == kDouble;
}
@@ -602,9 +611,6 @@
virtual HType CalculateInferredType() const;
- // Helper for type conversions used by normal and phi instructions.
- void InsertInputConversion(HInstruction* previous, int index, HType type);
-
#ifdef DEBUG
virtual void Verify() = 0;
#endif
@@ -1041,27 +1047,15 @@
class HPushArgument: public HUnaryOperation {
public:
- explicit HPushArgument(HValue* value)
- : HUnaryOperation(value), argument_index_(-1) {
- set_representation(Representation::Tagged());
- }
+ explicit HPushArgument(HValue* value) : HUnaryOperation(value) { }
virtual Representation RequiredInputRepresentation(int index) const {
return Representation::Tagged();
}
- virtual void PrintDataTo(StringStream* stream) const;
HValue* argument() const { return OperandAt(0); }
- int argument_index() const { return argument_index_; }
- void set_argument_index(int index) {
- ASSERT(argument_index_ == -1 || index == argument_index_);
- argument_index_ = index;
- }
DECLARE_CONCRETE_INSTRUCTION(PushArgument, "push_argument")
-
- private:
- int argument_index_;
};
@@ -1124,36 +1118,80 @@
class HCall: public HInstruction {
public:
- // Construct a call with uninitialized arguments. The argument count
- // includes the receiver.
- explicit HCall(int count);
+ // The argument count includes the receiver.
+ explicit HCall(int argument_count) : argument_count_(argument_count) {
+ set_representation(Representation::Tagged());
+ SetAllSideEffects();
+ }
virtual HType CalculateInferredType() const { return HType::Tagged(); }
- // TODO(3190496): This needs a cleanup. We don't want the arguments
- // be operands of the call instruction. This results in bad code quality.
- virtual int argument_count() const { return arguments_.length(); }
- virtual int OperandCount() const { return argument_count(); }
- virtual HValue* OperandAt(int index) const { return arguments_[index]; }
- virtual HPushArgument* PushArgumentAt(int index) const {
- return HPushArgument::cast(OperandAt(index));
- }
- virtual HValue* ArgumentAt(int index) const {
- return PushArgumentAt(index)->argument();
- }
- virtual void SetArgumentAt(int index, HPushArgument* push_argument);
+ virtual int argument_count() const { return argument_count_; }
virtual void PrintDataTo(StringStream* stream) const;
DECLARE_INSTRUCTION(Call)
- protected:
- virtual void InternalSetOperandAt(int index, HValue* value) {
- arguments_[index] = value;
+ private:
+ int argument_count_;
+};
+
+
+class HUnaryCall: public HCall {
+ public:
+ HUnaryCall(HValue* value, int argument_count)
+ : HCall(argument_count), value_(NULL) {
+ SetOperandAt(0, value);
}
- int argument_count_;
- Vector<HValue*> arguments_;
+ virtual void PrintDataTo(StringStream* stream) const;
+
+ HValue* value() const { return value_; }
+
+ virtual int OperandCount() const { return 1; }
+ virtual HValue* OperandAt(int index) const {
+ ASSERT(index == 0);
+ return value_;
+ }
+
+ DECLARE_INSTRUCTION(UnaryCall)
+
+ protected:
+ virtual void InternalSetOperandAt(int index, HValue* value) {
+ ASSERT(index == 0);
+ value_ = value;
+ }
+
+ private:
+ HValue* value_;
+};
+
+
+class HBinaryCall: public HCall {
+ public:
+ HBinaryCall(HValue* first, HValue* second, int argument_count)
+ : HCall(argument_count) {
+ SetOperandAt(0, first);
+ SetOperandAt(1, second);
+ }
+
+ virtual void PrintDataTo(StringStream* stream) const;
+
+ HValue* first() const { return operands_[0]; }
+ HValue* second() const { return operands_[1]; }
+
+ virtual int OperandCount() const { return 2; }
+ virtual HValue* OperandAt(int index) const { return operands_[index]; }
+
+ DECLARE_INSTRUCTION(BinaryCall)
+
+ protected:
+ virtual void InternalSetOperandAt(int index, HValue* value) {
+ operands_[index] = value;
+ }
+
+ private:
+ HOperandVector<2> operands_;
};
@@ -1163,6 +1201,7 @@
: HCall(argument_count), function_(function) { }
Handle<JSFunction> function() const { return function_; }
+
bool IsApplyFunction() const {
return function_->code() == Builtins::builtin(Builtins::FunctionApply);
}
@@ -1176,42 +1215,32 @@
};
-class HCallKeyed: public HCall {
+class HCallKeyed: public HBinaryCall {
public:
- HCallKeyed(HValue* key, int argument_count)
- : HCall(argument_count + 1) {
- SetOperandAt(0, key);
+ HCallKeyed(HValue* context, HValue* key, int argument_count)
+ : HBinaryCall(context, key, argument_count) {
}
virtual Representation RequiredInputRepresentation(int index) const {
return Representation::Tagged();
}
- // TODO(3190496): This is a hack to get an additional operand that
- // is not an argument to work with the current setup. This _needs_ a cleanup.
- // (see HCall)
- virtual void PrintDataTo(StringStream* stream) const;
- HValue* key() const { return OperandAt(0); }
- virtual int argument_count() const { return arguments_.length() - 1; }
- virtual int OperandCount() const { return arguments_.length(); }
- virtual HValue* OperandAt(int index) const { return arguments_[index]; }
- virtual HPushArgument* PushArgumentAt(int index) const {
- return HPushArgument::cast(OperandAt(index + 1));
- }
- virtual void SetArgumentAt(int index, HPushArgument* push_argument) {
- HCall::SetArgumentAt(index + 1, push_argument);
- }
+ HValue* context() const { return first(); }
+ HValue* key() const { return second(); }
DECLARE_CONCRETE_INSTRUCTION(CallKeyed, "call_keyed")
};
-class HCallNamed: public HCall {
+class HCallNamed: public HUnaryCall {
public:
- HCallNamed(Handle<String> name, int argument_count)
- : HCall(argument_count), name_(name) { }
+ HCallNamed(HValue* context, Handle<String> name, int argument_count)
+ : HUnaryCall(context, argument_count), name_(name) {
+ }
+
virtual void PrintDataTo(StringStream* stream) const;
+ HValue* context() const { return value(); }
Handle<String> name() const { return name_; }
DECLARE_CONCRETE_INSTRUCTION(CallNamed, "call_named")
@@ -1221,21 +1250,27 @@
};
-class HCallFunction: public HCall {
+class HCallFunction: public HUnaryCall {
public:
- explicit HCallFunction(int argument_count) : HCall(argument_count) { }
+ HCallFunction(HValue* context, int argument_count)
+ : HUnaryCall(context, argument_count) {
+ }
+
+ HValue* context() const { return value(); }
DECLARE_CONCRETE_INSTRUCTION(CallFunction, "call_function")
};
-class HCallGlobal: public HCall {
+class HCallGlobal: public HUnaryCall {
public:
- HCallGlobal(Handle<String> name, int argument_count)
- : HCall(argument_count), name_(name) { }
+ HCallGlobal(HValue* context, Handle<String> name, int argument_count)
+ : HUnaryCall(context, argument_count), name_(name) {
+ }
virtual void PrintDataTo(StringStream* stream) const;
+ HValue* context() const { return value(); }
Handle<String> name() const { return name_; }
DECLARE_CONCRETE_INSTRUCTION(CallGlobal, "call_global")
@@ -1247,10 +1282,11 @@
class HCallKnownGlobal: public HCall {
public:
- HCallKnownGlobal(Handle<JSFunction> target,
- int argument_count)
+ HCallKnownGlobal(Handle<JSFunction> target, int argument_count)
: HCall(argument_count), target_(target) { }
+ virtual void PrintDataTo(StringStream* stream) const;
+
Handle<JSFunction> target() const { return target_; }
DECLARE_CONCRETE_INSTRUCTION(CallKnownGlobal, "call_known_global")
@@ -1260,15 +1296,18 @@
};
-class HCallNew: public HCall {
+class HCallNew: public HBinaryCall {
public:
- explicit HCallNew(int argument_count) : HCall(argument_count) { }
+ HCallNew(HValue* context, HValue* constructor, int argument_count)
+ : HBinaryCall(context, constructor, argument_count) {
+ }
virtual Representation RequiredInputRepresentation(int index) const {
return Representation::Tagged();
}
- HValue* constructor() const { return ArgumentAt(0); }
+ HValue* context() const { return first(); }
+ HValue* constructor() const { return second(); }
DECLARE_CONCRETE_INSTRUCTION(CallNew, "call_new")
};
@@ -1334,6 +1373,27 @@
};
+class HPixelArrayLength: public HUnaryOperation {
+ public:
+ explicit HPixelArrayLength(HValue* value) : HUnaryOperation(value) {
+ set_representation(Representation::Integer32());
+ // The result of this instruction is idempotent as long as its inputs don't
+ // change. The length of a pixel array cannot change once set, so it's not
+ // necessary to introduce a kDependsOnArrayLengths or any other dependency.
+ SetFlag(kUseGVN);
+ }
+
+ virtual Representation RequiredInputRepresentation(int index) const {
+ return Representation::Tagged();
+ }
+
+ DECLARE_CONCRETE_INSTRUCTION(PixelArrayLength, "pixel_array_length")
+
+ protected:
+ virtual bool DataEquals(HValue* other) const { return true; }
+};
+
+
class HBitNot: public HUnaryOperation {
public:
explicit HBitNot(HValue* value) : HUnaryOperation(value) {
@@ -1452,6 +1512,30 @@
};
+class HLoadPixelArrayExternalPointer: public HUnaryOperation {
+ public:
+ explicit HLoadPixelArrayExternalPointer(HValue* value)
+ : HUnaryOperation(value) {
+ set_representation(Representation::External());
+ // The result of this instruction is idempotent as long as its inputs don't
+ // change. The external array of a pixel array elements object cannot
+ // change once set, so it's no necessary to introduce any additional
+ // dependencies on top of the inputs.
+ SetFlag(kUseGVN);
+ }
+
+ virtual Representation RequiredInputRepresentation(int index) const {
+ return Representation::Tagged();
+ }
+
+ DECLARE_CONCRETE_INSTRUCTION(LoadPixelArrayExternalPointer,
+ "load-pixel-array-external-pointer")
+
+ protected:
+ virtual bool DataEquals(HValue* other) const { return true; }
+};
+
+
class HCheckMap: public HUnaryOperation {
public:
HCheckMap(HValue* value, Handle<Map> map)
@@ -1861,7 +1945,6 @@
operands_[index] = value;
}
- private:
HOperandVector<2> operands_;
};
@@ -2073,7 +2156,11 @@
}
void SetInputRepresentation(Representation r);
- virtual bool EmitAtUses() const { return uses()->length() <= 1; }
+
+ virtual bool EmitAtUses() const {
+ return !HasSideEffects() && (uses()->length() <= 1);
+ }
+
virtual Representation RequiredInputRepresentation(int index) const {
return input_representation_;
}
@@ -2111,7 +2198,10 @@
SetFlag(kUseGVN);
}
- virtual bool EmitAtUses() const { return uses()->length() <= 1; }
+ virtual bool EmitAtUses() const {
+ return !HasSideEffects() && (uses()->length() <= 1);
+ }
+
virtual Representation RequiredInputRepresentation(int index) const {
return Representation::Tagged();
}
@@ -2130,7 +2220,11 @@
set_representation(Representation::Tagged());
SetFlag(kUseGVN);
}
- virtual bool EmitAtUses() const { return uses()->length() <= 1; }
+
+ virtual bool EmitAtUses() const {
+ return !HasSideEffects() && (uses()->length() <= 1);
+ }
+
virtual Representation RequiredInputRepresentation(int index) const {
return Representation::Tagged();
}
@@ -2187,7 +2281,9 @@
SetFlag(kUseGVN);
}
- virtual bool EmitAtUses() const { return uses()->length() <= 1; }
+ virtual bool EmitAtUses() const {
+ return !HasSideEffects() && (uses()->length() <= 1);
+ }
DECLARE_CONCRETE_INSTRUCTION(IsConstructCall, "is_construct_call")
@@ -2278,20 +2374,42 @@
};
-class HInstanceOf: public HBinaryOperation {
+class HInstanceOf: public HInstruction {
public:
- HInstanceOf(HValue* left, HValue* right) : HBinaryOperation(left, right) {
+ HInstanceOf(HValue* context, HValue* left, HValue* right) {
+ SetOperandAt(0, context);
+ SetOperandAt(1, left);
+ SetOperandAt(2, right);
set_representation(Representation::Tagged());
SetAllSideEffects();
}
- virtual bool EmitAtUses() const { return uses()->length() <= 1; }
+ HValue* context() const { return operands_[0]; }
+ HValue* left() const { return operands_[1]; }
+ HValue* right() const { return operands_[2]; }
+
+ virtual bool EmitAtUses() const {
+ return !HasSideEffects() && (uses()->length() <= 1);
+ }
virtual Representation RequiredInputRepresentation(int index) const {
return Representation::Tagged();
}
+ virtual void PrintDataTo(StringStream* stream) const;
+
+ virtual int OperandCount() const { return 3; }
+ virtual HValue* OperandAt(int index) const { return operands_[index]; }
+
DECLARE_CONCRETE_INSTRUCTION(InstanceOf, "instance_of")
+
+ protected:
+ virtual void InternalSetOperandAt(int index, HValue* value) {
+ operands_[index] = value;
+ }
+
+ private:
+ HOperandVector<3> operands_;
};
@@ -2560,18 +2678,17 @@
};
-class HCallStub: public HInstruction {
+class HCallStub: public HUnaryCall {
public:
- HCallStub(CodeStub::Major major_key, int argument_count)
- : major_key_(major_key),
- argument_count_(argument_count),
+ HCallStub(HValue* context, CodeStub::Major major_key, int argument_count)
+ : HUnaryCall(context, argument_count),
+ major_key_(major_key),
transcendental_type_(TranscendentalCache::kNumberOfCaches) {
- set_representation(Representation::Tagged());
- SetAllSideEffects();
}
CodeStub::Major major_key() { return major_key_; }
- int argument_count() { return argument_count_; }
+
+ HValue* context() const { return value(); }
void set_transcendental_type(TranscendentalCache::Type transcendental_type) {
transcendental_type_ = transcendental_type;
@@ -2579,13 +2696,13 @@
TranscendentalCache::Type transcendental_type() {
return transcendental_type_;
}
+
virtual void PrintDataTo(StringStream* stream) const;
DECLARE_CONCRETE_INSTRUCTION(CallStub, "call_stub")
private:
CodeStub::Major major_key_;
- int argument_count_;
TranscendentalCache::Type transcendental_type_;
};
@@ -2763,15 +2880,16 @@
};
-class HLoadNamedGeneric: public HUnaryOperation {
+class HLoadNamedGeneric: public HBinaryOperation {
public:
- HLoadNamedGeneric(HValue* object, Handle<Object> name)
- : HUnaryOperation(object), name_(name) {
+ HLoadNamedGeneric(HValue* context, HValue* object, Handle<Object> name)
+ : HBinaryOperation(context, object), name_(name) {
set_representation(Representation::Tagged());
SetAllSideEffects();
}
- HValue* object() const { return OperandAt(0); }
+ HValue* context() const { return OperandAt(0); }
+ HValue* object() const { return OperandAt(1); }
Handle<Object> name() const { return name_; }
virtual Representation RequiredInputRepresentation(int index) const {
@@ -2846,19 +2964,67 @@
};
+class HLoadPixelArrayElement: public HBinaryOperation {
+ public:
+ HLoadPixelArrayElement(HValue* external_elements, HValue* key)
+ : HBinaryOperation(external_elements, key) {
+ set_representation(Representation::Integer32());
+ SetFlag(kDependsOnPixelArrayElements);
+ // Native code could change the pixel array.
+ SetFlag(kDependsOnCalls);
+ SetFlag(kUseGVN);
+ }
+
+ virtual void PrintDataTo(StringStream* stream) const;
+
+ virtual Representation RequiredInputRepresentation(int index) const {
+ // The key is supposed to be Integer32, but the base pointer
+ // for the element load is a naked pointer.
+ return (index == 1) ? Representation::Integer32()
+ : Representation::External();
+ }
+
+ HValue* external_pointer() const { return OperandAt(0); }
+ HValue* key() const { return OperandAt(1); }
+
+ DECLARE_CONCRETE_INSTRUCTION(LoadPixelArrayElement,
+ "load_pixel_array_element")
+
+ protected:
+ virtual bool DataEquals(HValue* other) const { return true; }
+};
+
+
class HLoadKeyedGeneric: public HLoadKeyed {
public:
- HLoadKeyedGeneric(HValue* obj, HValue* key) : HLoadKeyed(obj, key) {
+ HLoadKeyedGeneric(HContext* context, HValue* obj, HValue* key)
+ : HLoadKeyed(obj, key), context_(NULL) {
+ SetOperandAt(2, context);
SetAllSideEffects();
}
+ HValue* context() const { return context_; }
+ HValue* object() const { return operands_[0]; }
+ HValue* key() const { return operands_[1]; }
+
+ virtual int OperandCount() const { return 3; }
+ virtual HValue* OperandAt(int index) const {
+ return (index < 2) ? operands_[index] : context_;
+ }
+
DECLARE_CONCRETE_INSTRUCTION(LoadKeyedGeneric, "load_keyed_generic")
+
+ protected:
+ virtual void InternalSetOperandAt(int index, HValue* value);
+
+ private:
+ HValue* context_;
};
class HStoreNamed: public HBinaryOperation {
public:
- HStoreNamed(HValue* obj, Handle<Object> name, HValue* val)
+ HStoreNamed(HValue* obj, Handle<String> name, HValue* val)
: HBinaryOperation(obj, val), name_(name) {
}
@@ -2869,21 +3035,21 @@
virtual void PrintDataTo(StringStream* stream) const;
HValue* object() const { return OperandAt(0); }
- Handle<Object> name() const { return name_; }
+ Handle<String> name() const { return name_; }
HValue* value() const { return OperandAt(1); }
void set_value(HValue* value) { SetOperandAt(1, value); }
DECLARE_INSTRUCTION(StoreNamed)
private:
- Handle<Object> name_;
+ Handle<String> name_;
};
class HStoreNamedField: public HStoreNamed {
public:
HStoreNamedField(HValue* obj,
- Handle<Object> name,
+ Handle<String> name,
HValue* val,
bool in_object,
int offset)
@@ -2922,12 +3088,32 @@
class HStoreNamedGeneric: public HStoreNamed {
public:
- HStoreNamedGeneric(HValue* obj, Handle<Object> name, HValue* val)
- : HStoreNamed(obj, name, val) {
+ HStoreNamedGeneric(HValue* context,
+ HValue* object,
+ Handle<String> name,
+ HValue* value)
+ : HStoreNamed(object, name, value), context_(NULL) {
+ SetOperandAt(2, context);
SetAllSideEffects();
}
+ HValue* context() const { return context_; }
+ HValue* object() const { return operands_[0]; }
+ HValue* value() const { return operands_[1]; }
+
+ virtual int OperandCount() const { return 3; }
+
+ virtual HValue* OperandAt(int index) const {
+ return (index < 2) ? operands_[index] : context_;
+ }
+
DECLARE_CONCRETE_INSTRUCTION(StoreNamedGeneric, "store_named_generic")
+
+ protected:
+ virtual void InternalSetOperandAt(int index, HValue* value);
+
+ private:
+ HValue* context_;
};
@@ -2962,7 +3148,6 @@
operands_[index] = value;
}
- private:
HOperandVector<3> operands_;
};
@@ -2987,12 +3172,33 @@
class HStoreKeyedGeneric: public HStoreKeyed {
public:
- HStoreKeyedGeneric(HValue* obj, HValue* key, HValue* val)
- : HStoreKeyed(obj, key, val) {
+ HStoreKeyedGeneric(HValue* context,
+ HValue* object,
+ HValue* key,
+ HValue* value)
+ : HStoreKeyed(object, key, value), context_(NULL) {
+ SetOperandAt(3, context);
SetAllSideEffects();
}
+ HValue* context() const { return context_; }
+ HValue* object() const { return operands_[0]; }
+ HValue* key() const { return operands_[1]; }
+ HValue* value() const { return operands_[2]; }
+
+ virtual int OperandCount() const { return 4; }
+
+ virtual HValue* OperandAt(int index) const {
+ return (index < 3) ? operands_[index] : context_;
+ }
+
DECLARE_CONCRETE_INSTRUCTION(StoreKeyedGeneric, "store_keyed_generic")
+
+ protected:
+ virtual void InternalSetOperandAt(int index, HValue* value);
+
+ private:
+ HValue* context_;
};
@@ -3094,22 +3300,36 @@
class HObjectLiteral: public HMaterializedLiteral {
public:
- HObjectLiteral(Handle<FixedArray> constant_properties,
+ HObjectLiteral(HValue* context,
+ Handle<FixedArray> constant_properties,
bool fast_elements,
int literal_index,
int depth)
: HMaterializedLiteral(literal_index, depth),
+ context_(NULL),
constant_properties_(constant_properties),
- fast_elements_(fast_elements) {}
+ fast_elements_(fast_elements) {
+ SetOperandAt(0, context);
+ }
+ HValue* context() const { return context_; }
Handle<FixedArray> constant_properties() const {
return constant_properties_;
}
bool fast_elements() const { return fast_elements_; }
+ virtual int OperandCount() const { return 1; }
+ virtual HValue* OperandAt(int index) const { return context_; }
+
DECLARE_CONCRETE_INSTRUCTION(ObjectLiteral, "object_literal")
+ protected:
+ virtual void InternalSetOperandAt(int index, HValue* value) {
+ context_ = value;
+ }
+
private:
+ HValue* context_;
Handle<FixedArray> constant_properties_;
bool fast_elements_;
};