Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(373)

Side by Side Diff: src/hydrogen.cc

Issue 10388047: Implement correct checking for inherited readonliness on assignment. (Closed) Base URL: https://v8.googlecode.com/svn/branches/bleeding_edge
Patch Set: Addressed Michael's comments. Created 8 years, 6 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « src/arm/stub-cache-arm.cc ('k') | src/ia32/stub-cache-ia32.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright 2012 the V8 project authors. All rights reserved. 1 // Copyright 2012 the V8 project authors. All rights reserved.
2 // Redistribution and use in source and binary forms, with or without 2 // Redistribution and use in source and binary forms, with or without
3 // modification, are permitted provided that the following conditions are 3 // modification, are permitted provided that the following conditions are
4 // met: 4 // met:
5 // 5 //
6 // * Redistributions of source code must retain the above copyright 6 // * Redistributions of source code must retain the above copyright
7 // notice, this list of conditions and the following disclaimer. 7 // notice, this list of conditions and the following disclaimer.
8 // * Redistributions in binary form must reproduce the above 8 // * Redistributions in binary form must reproduce the above
9 // copyright notice, this list of conditions and the following 9 // copyright notice, this list of conditions and the following
10 // disclaimer in the documentation and/or other materials provided 10 // disclaimer in the documentation and/or other materials provided
(...skipping 4256 matching lines...) Expand 10 before | Expand all | Expand 10 after
4267 switch (property->kind()) { 4267 switch (property->kind()) {
4268 case ObjectLiteral::Property::MATERIALIZED_LITERAL: 4268 case ObjectLiteral::Property::MATERIALIZED_LITERAL:
4269 ASSERT(!CompileTimeValue::IsCompileTimeValue(value)); 4269 ASSERT(!CompileTimeValue::IsCompileTimeValue(value));
4270 // Fall through. 4270 // Fall through.
4271 case ObjectLiteral::Property::COMPUTED: 4271 case ObjectLiteral::Property::COMPUTED:
4272 if (key->handle()->IsSymbol()) { 4272 if (key->handle()->IsSymbol()) {
4273 if (property->emit_store()) { 4273 if (property->emit_store()) {
4274 property->RecordTypeFeedback(oracle()); 4274 property->RecordTypeFeedback(oracle());
4275 CHECK_ALIVE(VisitForValue(value)); 4275 CHECK_ALIVE(VisitForValue(value));
4276 HValue* value = Pop(); 4276 HValue* value = Pop();
4277 HInstruction* store = BuildStoreNamed(literal, value, property); 4277 HInstruction* store;
4278 CHECK_ALIVE(store = BuildStoreNamed(literal, value, property));
4278 AddInstruction(store); 4279 AddInstruction(store);
4279 if (store->HasObservableSideEffects()) AddSimulate(key->id()); 4280 if (store->HasObservableSideEffects()) AddSimulate(key->id());
4280 } else { 4281 } else {
4281 CHECK_ALIVE(VisitForEffect(value)); 4282 CHECK_ALIVE(VisitForEffect(value));
4282 } 4283 }
4283 break; 4284 break;
4284 } 4285 }
4285 // Fall through. 4286 // Fall through.
4286 case ObjectLiteral::Property::PROTOTYPE: 4287 case ObjectLiteral::Property::PROTOTYPE:
4287 case ObjectLiteral::Property::SETTER: 4288 case ObjectLiteral::Property::SETTER:
(...skipping 143 matching lines...) Expand 10 before | Expand all | Expand 10 after
4431 } 4432 }
4432 } 4433 }
4433 4434
4434 4435
4435 HInstruction* HGraphBuilder::BuildStoreNamedField(HValue* object, 4436 HInstruction* HGraphBuilder::BuildStoreNamedField(HValue* object,
4436 Handle<String> name, 4437 Handle<String> name,
4437 HValue* value, 4438 HValue* value,
4438 Handle<Map> type, 4439 Handle<Map> type,
4439 LookupResult* lookup, 4440 LookupResult* lookup,
4440 bool smi_and_map_check) { 4441 bool smi_and_map_check) {
4442 ASSERT(lookup->IsFound());
4441 if (smi_and_map_check) { 4443 if (smi_and_map_check) {
4442 AddInstruction(new(zone()) HCheckNonSmi(object)); 4444 AddInstruction(new(zone()) HCheckNonSmi(object));
4443 AddInstruction(HCheckMaps::NewWithTransitions(object, type)); 4445 AddInstruction(HCheckMaps::NewWithTransitions(object, type));
4444 } 4446 }
4445 4447
4448 // If the property does not exist yet, we have to check that it wasn't made
4449 // readonly by some meanwhile modifications on the prototype chain.
4450 if (!lookup->IsProperty()) {
4451 Object* proto = type->prototype();
4452 // First check that the prototype chain isn't affected already.
4453 LookupResult proto_result(isolate());
4454 proto->Lookup(*name, &proto_result);
4455 if (proto_result.IsProperty()) {
4456 // If the inherited property could induce readonly-ness, bail out.
4457 if (proto_result.IsReadOnly() || !proto_result.IsCacheable()) {
4458 Bailout("improper object on prototype chain for store");
4459 return NULL;
4460 }
4461 // We only need to check up to where the preexisting property.
4462 proto = proto_result.holder();
4463 } else {
4464 // Otherwise, find the top prototype.
4465 while (proto->GetPrototype()->IsJSObject()) proto = proto->GetPrototype();
4466 }
4467 ASSERT(proto->IsJSObject());
4468 AddInstruction(new(zone()) HCheckPrototypeMaps(
4469 Handle<JSObject>(JSObject::cast(type->prototype())),
4470 Handle<JSObject>(JSObject::cast(proto))));
4471 }
4472
4446 int index = ComputeLoadStoreFieldIndex(type, name, lookup); 4473 int index = ComputeLoadStoreFieldIndex(type, name, lookup);
4447 bool is_in_object = index < 0; 4474 bool is_in_object = index < 0;
4448 int offset = index * kPointerSize; 4475 int offset = index * kPointerSize;
4449 if (index < 0) { 4476 if (index < 0) {
4450 // Negative property indices are in-object properties, indexed 4477 // Negative property indices are in-object properties, indexed
4451 // from the end of the fixed part of the object. 4478 // from the end of the fixed part of the object.
4452 offset += type->instance_size(); 4479 offset += type->instance_size();
4453 } else { 4480 } else {
4454 offset += FixedArray::kHeaderSize; 4481 offset += FixedArray::kHeaderSize;
4455 } 4482 }
(...skipping 136 matching lines...) Expand 10 before | Expand all | Expand 10 after
4592 join = graph()->CreateBasicBlock(); 4619 join = graph()->CreateBasicBlock();
4593 } 4620 }
4594 ++count; 4621 ++count;
4595 HBasicBlock* if_true = graph()->CreateBasicBlock(); 4622 HBasicBlock* if_true = graph()->CreateBasicBlock();
4596 HBasicBlock* if_false = graph()->CreateBasicBlock(); 4623 HBasicBlock* if_false = graph()->CreateBasicBlock();
4597 HCompareMap* compare = 4624 HCompareMap* compare =
4598 new(zone()) HCompareMap(object, map, if_true, if_false); 4625 new(zone()) HCompareMap(object, map, if_true, if_false);
4599 current_block()->Finish(compare); 4626 current_block()->Finish(compare);
4600 4627
4601 set_current_block(if_true); 4628 set_current_block(if_true);
4602 HInstruction* instr = 4629 HInstruction* instr;
4603 BuildStoreNamedField(object, name, value, map, &lookup, false); 4630 CHECK_ALIVE(instr =
4631 BuildStoreNamedField(object, name, value, map, &lookup, false));
4604 instr->set_position(expr->position()); 4632 instr->set_position(expr->position());
4605 // Goto will add the HSimulate for the store. 4633 // Goto will add the HSimulate for the store.
4606 AddInstruction(instr); 4634 AddInstruction(instr);
4607 if (!ast_context()->IsEffect()) Push(value); 4635 if (!ast_context()->IsEffect()) Push(value);
4608 current_block()->Goto(join); 4636 current_block()->Goto(join);
4609 4637
4610 set_current_block(if_false); 4638 set_current_block(if_false);
4611 } 4639 }
4612 } 4640 }
4613 4641
(...skipping 47 matching lines...) Expand 10 before | Expand all | Expand 10 after
4661 // Named store. 4689 // Named store.
4662 CHECK_ALIVE(VisitForValue(expr->value())); 4690 CHECK_ALIVE(VisitForValue(expr->value()));
4663 value = Pop(); 4691 value = Pop();
4664 HValue* object = Pop(); 4692 HValue* object = Pop();
4665 4693
4666 Literal* key = prop->key()->AsLiteral(); 4694 Literal* key = prop->key()->AsLiteral();
4667 Handle<String> name = Handle<String>::cast(key->handle()); 4695 Handle<String> name = Handle<String>::cast(key->handle());
4668 ASSERT(!name.is_null()); 4696 ASSERT(!name.is_null());
4669 4697
4670 SmallMapList* types = expr->GetReceiverTypes(); 4698 SmallMapList* types = expr->GetReceiverTypes();
4671 LookupResult lookup(isolate());
4672
4673 if (expr->IsMonomorphic()) { 4699 if (expr->IsMonomorphic()) {
4674 instr = BuildStoreNamed(object, value, expr); 4700 CHECK_ALIVE(instr = BuildStoreNamed(object, value, expr));
4675 4701
4676 } else if (types != NULL && types->length() > 1) { 4702 } else if (types != NULL && types->length() > 1) {
4677 HandlePolymorphicStoreNamedField(expr, object, value, types, name); 4703 HandlePolymorphicStoreNamedField(expr, object, value, types, name);
4678 return; 4704 return;
4679 4705
4680 } else { 4706 } else {
4681 instr = BuildStoreNamedGeneric(object, name, value); 4707 instr = BuildStoreNamedGeneric(object, name, value);
4682 } 4708 }
4683 4709
4684 } else { 4710 } else {
(...skipping 158 matching lines...) Expand 10 before | Expand all | Expand 10 after
4843 if (load->HasObservableSideEffects()) AddSimulate(expr->CompoundLoadId()); 4869 if (load->HasObservableSideEffects()) AddSimulate(expr->CompoundLoadId());
4844 4870
4845 CHECK_ALIVE(VisitForValue(expr->value())); 4871 CHECK_ALIVE(VisitForValue(expr->value()));
4846 HValue* right = Pop(); 4872 HValue* right = Pop();
4847 HValue* left = Pop(); 4873 HValue* left = Pop();
4848 4874
4849 HInstruction* instr = BuildBinaryOperation(operation, left, right); 4875 HInstruction* instr = BuildBinaryOperation(operation, left, right);
4850 PushAndAdd(instr); 4876 PushAndAdd(instr);
4851 if (instr->HasObservableSideEffects()) AddSimulate(operation->id()); 4877 if (instr->HasObservableSideEffects()) AddSimulate(operation->id());
4852 4878
4853 HInstruction* store = BuildStoreNamed(obj, instr, prop); 4879 HInstruction* store;
4880 CHECK_ALIVE(store = BuildStoreNamed(obj, instr, prop));
4854 AddInstruction(store); 4881 AddInstruction(store);
4855 // Drop the simulated receiver and value. Return the value. 4882 // Drop the simulated receiver and value. Return the value.
4856 Drop(2); 4883 Drop(2);
4857 Push(instr); 4884 Push(instr);
4858 if (store->HasObservableSideEffects()) AddSimulate(expr->AssignmentId()); 4885 if (store->HasObservableSideEffects()) AddSimulate(expr->AssignmentId());
4859 return ast_context()->ReturnValue(Pop()); 4886 return ast_context()->ReturnValue(Pop());
4860 4887
4861 } else { 4888 } else {
4862 // Keyed property. 4889 // Keyed property.
4863 CHECK_ALIVE(VisitForValue(prop->obj())); 4890 CHECK_ALIVE(VisitForValue(prop->obj()));
(...skipping 2229 matching lines...) Expand 10 before | Expand all | Expand 10 after
7093 load = BuildLoadNamed(obj, prop, map, name); 7120 load = BuildLoadNamed(obj, prop, map, name);
7094 } else { 7121 } else {
7095 load = BuildLoadNamedGeneric(obj, prop); 7122 load = BuildLoadNamedGeneric(obj, prop);
7096 } 7123 }
7097 PushAndAdd(load); 7124 PushAndAdd(load);
7098 if (load->HasObservableSideEffects()) AddSimulate(expr->CountId()); 7125 if (load->HasObservableSideEffects()) AddSimulate(expr->CountId());
7099 7126
7100 after = BuildIncrement(returns_original_input, expr); 7127 after = BuildIncrement(returns_original_input, expr);
7101 input = Pop(); 7128 input = Pop();
7102 7129
7103 HInstruction* store = BuildStoreNamed(obj, after, prop); 7130 HInstruction* store;
7131 CHECK_ALIVE(store = BuildStoreNamed(obj, after, prop));
7104 AddInstruction(store); 7132 AddInstruction(store);
7105 7133
7106 // Overwrite the receiver in the bailout environment with the result 7134 // Overwrite the receiver in the bailout environment with the result
7107 // of the operation, and the placeholder with the original value if 7135 // of the operation, and the placeholder with the original value if
7108 // necessary. 7136 // necessary.
7109 environment()->SetExpressionStackAt(0, after); 7137 environment()->SetExpressionStackAt(0, after);
7110 if (returns_original_input) environment()->SetExpressionStackAt(1, input); 7138 if (returns_original_input) environment()->SetExpressionStackAt(1, input);
7111 if (store->HasObservableSideEffects()) AddSimulate(expr->AssignmentId()); 7139 if (store->HasObservableSideEffects()) AddSimulate(expr->AssignmentId());
7112 7140
7113 } else { 7141 } else {
(...skipping 1746 matching lines...) Expand 10 before | Expand all | Expand 10 after
8860 } 8888 }
8861 } 8889 }
8862 8890
8863 #ifdef DEBUG 8891 #ifdef DEBUG
8864 if (graph_ != NULL) graph_->Verify(false); // No full verify. 8892 if (graph_ != NULL) graph_->Verify(false); // No full verify.
8865 if (allocator_ != NULL) allocator_->Verify(); 8893 if (allocator_ != NULL) allocator_->Verify();
8866 #endif 8894 #endif
8867 } 8895 }
8868 8896
8869 } } // namespace v8::internal 8897 } } // namespace v8::internal
OLDNEW
« no previous file with comments | « src/arm/stub-cache-arm.cc ('k') | src/ia32/stub-cache-ia32.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698