Index: src/hydrogen.cc |
diff --git a/src/hydrogen.cc b/src/hydrogen.cc |
index 3be001e42b79b996f82523d7927b8fd0c412f8a6..58a5ef6628b218db523f1f50414a3411cb3e806e 100644 |
--- a/src/hydrogen.cc |
+++ b/src/hydrogen.cc |
@@ -4275,6 +4275,7 @@ void HGraphBuilder::VisitObjectLiteral(ObjectLiteral* expr) { |
CHECK_ALIVE(VisitForValue(value)); |
HValue* value = Pop(); |
HInstruction* store = BuildStoreNamed(literal, value, property); |
+ CHECK_ALIVE({}); |
Michael Starzinger
2012/05/30 13:08:55
Can we rewrite that to use the following syntax. I
rossberg
2012/05/31 13:31:28
Done.
|
AddInstruction(store); |
if (store->HasObservableSideEffects()) AddSimulate(key->id()); |
} else { |
@@ -4438,11 +4439,37 @@ HInstruction* HGraphBuilder::BuildStoreNamedField(HValue* object, |
Handle<Map> type, |
LookupResult* lookup, |
bool smi_and_map_check) { |
+ ASSERT(lookup->IsFound()); |
if (smi_and_map_check) { |
AddInstruction(new(zone()) HCheckNonSmi(object)); |
AddInstruction(HCheckMaps::NewWithTransitions(object, type)); |
} |
+ // If the property does not exist yet, we have to check that it wasn't made |
+ // readonly by some meanwhile modifications on the prototype chain. |
+ if (!lookup->IsProperty()) { |
+ Object* proto = type->prototype(); |
+ // First check that the prototype chain isn't affected already. |
+ LookupResult proto_result(isolate()); |
+ proto->Lookup(*name, &proto_result); |
+ if (proto_result.IsProperty()) { |
+ // If the inherited property could induce readonly-ness, bail out. |
+ if (proto_result.IsReadOnly() || !proto_result.IsCacheable()) { |
+ Bailout("improper object on prototype chain for store"); |
+ return NULL; |
+ } |
+ // We only need to check up to where the preexisting property. |
+ proto = proto_result.holder(); |
+ } else { |
+ // Otherwise, find the top prototype. |
+ while (proto->GetPrototype()->IsJSObject()) proto = proto->GetPrototype(); |
+ } |
+ ASSERT(proto->IsJSObject()); |
+ AddInstruction(new(zone()) HCheckPrototypeMaps( |
+ Handle<JSObject>(JSObject::cast(type->prototype())), |
+ Handle<JSObject>(JSObject::cast(proto)))); |
+ } |
+ |
int index = ComputeLoadStoreFieldIndex(type, name, lookup); |
bool is_in_object = index < 0; |
int offset = index * kPointerSize; |
@@ -4601,6 +4628,7 @@ void HGraphBuilder::HandlePolymorphicStoreNamedField(Assignment* expr, |
set_current_block(if_true); |
HInstruction* instr = |
BuildStoreNamedField(object, name, value, map, &lookup, false); |
+ CHECK_ALIVE({}); |
Michael Starzinger
2012/05/30 13:08:55
Likewise. Also for the rest of the file.
rossberg
2012/05/31 13:31:28
Done.
|
instr->set_position(expr->position()); |
// Goto will add the HSimulate for the store. |
AddInstruction(instr); |
@@ -4668,10 +4696,9 @@ void HGraphBuilder::HandlePropertyAssignment(Assignment* expr) { |
ASSERT(!name.is_null()); |
SmallMapList* types = expr->GetReceiverTypes(); |
- LookupResult lookup(isolate()); |
- |
if (expr->IsMonomorphic()) { |
instr = BuildStoreNamed(object, value, expr); |
+ CHECK_ALIVE({}); |
} else if (types != NULL && types->length() > 1) { |
HandlePolymorphicStoreNamedField(expr, object, value, types, name); |
@@ -4851,6 +4878,7 @@ void HGraphBuilder::HandleCompoundAssignment(Assignment* expr) { |
if (instr->HasObservableSideEffects()) AddSimulate(operation->id()); |
HInstruction* store = BuildStoreNamed(obj, instr, prop); |
+ CHECK_ALIVE({}); |
AddInstruction(store); |
// Drop the simulated receiver and value. Return the value. |
Drop(2); |
@@ -7101,6 +7129,7 @@ void HGraphBuilder::VisitCountOperation(CountOperation* expr) { |
input = Pop(); |
HInstruction* store = BuildStoreNamed(obj, after, prop); |
+ CHECK_ALIVE({}); |
AddInstruction(store); |
// Overwrite the receiver in the bailout environment with the result |