| Index: src/hydrogen.cc
|
| diff --git a/src/hydrogen.cc b/src/hydrogen.cc
|
| index 3be001e42b79b996f82523d7927b8fd0c412f8a6..53b8a2b45b364fd603733edcf6c1a3091aaed660 100644
|
| --- a/src/hydrogen.cc
|
| +++ b/src/hydrogen.cc
|
| @@ -4274,7 +4274,8 @@ void HGraphBuilder::VisitObjectLiteral(ObjectLiteral* expr) {
|
| property->RecordTypeFeedback(oracle());
|
| CHECK_ALIVE(VisitForValue(value));
|
| HValue* value = Pop();
|
| - HInstruction* store = BuildStoreNamed(literal, value, property);
|
| + HInstruction* store;
|
| + CHECK_ALIVE(store = BuildStoreNamed(literal, value, property));
|
| 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;
|
| @@ -4599,8 +4626,9 @@ void HGraphBuilder::HandlePolymorphicStoreNamedField(Assignment* expr,
|
| current_block()->Finish(compare);
|
|
|
| set_current_block(if_true);
|
| - HInstruction* instr =
|
| - BuildStoreNamedField(object, name, value, map, &lookup, false);
|
| + HInstruction* instr;
|
| + CHECK_ALIVE(instr =
|
| + BuildStoreNamedField(object, name, value, map, &lookup, false));
|
| instr->set_position(expr->position());
|
| // Goto will add the HSimulate for the store.
|
| AddInstruction(instr);
|
| @@ -4668,10 +4696,8 @@ 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(instr = BuildStoreNamed(object, value, expr));
|
|
|
| } else if (types != NULL && types->length() > 1) {
|
| HandlePolymorphicStoreNamedField(expr, object, value, types, name);
|
| @@ -4850,7 +4876,8 @@ void HGraphBuilder::HandleCompoundAssignment(Assignment* expr) {
|
| PushAndAdd(instr);
|
| if (instr->HasObservableSideEffects()) AddSimulate(operation->id());
|
|
|
| - HInstruction* store = BuildStoreNamed(obj, instr, prop);
|
| + HInstruction* store;
|
| + CHECK_ALIVE(store = BuildStoreNamed(obj, instr, prop));
|
| AddInstruction(store);
|
| // Drop the simulated receiver and value. Return the value.
|
| Drop(2);
|
| @@ -7100,7 +7127,8 @@ void HGraphBuilder::VisitCountOperation(CountOperation* expr) {
|
| after = BuildIncrement(returns_original_input, expr);
|
| input = Pop();
|
|
|
| - HInstruction* store = BuildStoreNamed(obj, after, prop);
|
| + HInstruction* store;
|
| + CHECK_ALIVE(store = BuildStoreNamed(obj, after, prop));
|
| AddInstruction(store);
|
|
|
| // Overwrite the receiver in the bailout environment with the result
|
|
|