Chromium Code Reviews| OLD | NEW | 
|---|---|
| 1 // Copyright 2014 the V8 project authors. All rights reserved. | 1 // Copyright 2014 the V8 project authors. All rights reserved. | 
| 2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be | 
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. | 
| 4 | 4 | 
| 5 #include "src/compiler/ast-graph-builder.h" | 5 #include "src/compiler/ast-graph-builder.h" | 
| 6 | 6 | 
| 7 #include "src/compiler.h" | 7 #include "src/compiler.h" | 
| 8 #include "src/compiler/ast-loop-assignment-analyzer.h" | 8 #include "src/compiler/ast-loop-assignment-analyzer.h" | 
| 9 #include "src/compiler/control-builders.h" | 9 #include "src/compiler/control-builders.h" | 
| 10 #include "src/compiler/machine-operator.h" | 10 #include "src/compiler/machine-operator.h" | 
| (...skipping 1009 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1020 // The object is expected on the operand stack during computation of the | 1020 // The object is expected on the operand stack during computation of the | 
| 1021 // property values and is the value of the entire expression. | 1021 // property values and is the value of the entire expression. | 
| 1022 environment()->Push(literal); | 1022 environment()->Push(literal); | 
| 1023 | 1023 | 
| 1024 // Mark all computed expressions that are bound to a key that is shadowed by | 1024 // Mark all computed expressions that are bound to a key that is shadowed by | 
| 1025 // a later occurrence of the same key. For the marked expressions, no store | 1025 // a later occurrence of the same key. For the marked expressions, no store | 
| 1026 // code is emitted. | 1026 // code is emitted. | 
| 1027 expr->CalculateEmitStore(zone()); | 1027 expr->CalculateEmitStore(zone()); | 
| 1028 | 1028 | 
| 1029 // Create nodes to store computed values into the literal. | 1029 // Create nodes to store computed values into the literal. | 
| 1030 int property_index = 0; | |
| 1030 AccessorTable accessor_table(zone()); | 1031 AccessorTable accessor_table(zone()); | 
| 1031 for (int i = 0; i < expr->properties()->length(); i++) { | 1032 for (; property_index < expr->properties()->length(); property_index++) { | 
| 1032 ObjectLiteral::Property* property = expr->properties()->at(i); | 1033 ObjectLiteral::Property* property = expr->properties()->at(property_index); | 
| 1034 if (property->is_computed_name()) break; | |
| 1033 if (property->IsCompileTimeValue()) continue; | 1035 if (property->IsCompileTimeValue()) continue; | 
| 1034 | 1036 | 
| 1035 Literal* key = property->key()->AsLiteral(); | 1037 Literal* key = property->key()->AsLiteral(); | 
| 1036 switch (property->kind()) { | 1038 switch (property->kind()) { | 
| 1037 case ObjectLiteral::Property::CONSTANT: | 1039 case ObjectLiteral::Property::CONSTANT: | 
| 1038 UNREACHABLE(); | 1040 UNREACHABLE(); | 
| 1039 case ObjectLiteral::Property::MATERIALIZED_LITERAL: | 1041 case ObjectLiteral::Property::MATERIALIZED_LITERAL: | 
| 1040 DCHECK(!CompileTimeValue::IsCompileTimeValue(property->value())); | 1042 DCHECK(!CompileTimeValue::IsCompileTimeValue(property->value())); | 
| 1041 // Fall through. | 1043 // Fall through. | 
| 1042 case ObjectLiteral::Property::COMPUTED: { | 1044 case ObjectLiteral::Property::COMPUTED: { | 
| (...skipping 61 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1104 Node* getter = environment()->Pop(); | 1106 Node* getter = environment()->Pop(); | 
| 1105 Node* name = environment()->Pop(); | 1107 Node* name = environment()->Pop(); | 
| 1106 Node* attr = jsgraph()->Constant(NONE); | 1108 Node* attr = jsgraph()->Constant(NONE); | 
| 1107 const Operator* op = | 1109 const Operator* op = | 
| 1108 javascript()->CallRuntime(Runtime::kDefineAccessorPropertyUnchecked, 5); | 1110 javascript()->CallRuntime(Runtime::kDefineAccessorPropertyUnchecked, 5); | 
| 1109 Node* call = NewNode(op, literal, name, getter, setter, attr); | 1111 Node* call = NewNode(op, literal, name, getter, setter, attr); | 
| 1110 // This should not lazy deopt on a new literal. | 1112 // This should not lazy deopt on a new literal. | 
| 1111 PrepareFrameState(call, BailoutId::None()); | 1113 PrepareFrameState(call, BailoutId::None()); | 
| 1112 } | 1114 } | 
| 1113 | 1115 | 
| 1116 // Object literals have two parts. The "static" part on the left contains no | |
| 1117 // computed property names, and so we can compute its map ahead of time; see | |
| 1118 // Runtime_CreateObjectLiteralBoilerplate. The second "dynamic" part starts | |
| 1119 // with the first computed property name and continues with all properties to | |
| 1120 // its right. All the code from above initializes the static component of the | |
| 1121 // object literal, and arranges for the map of the result to reflect the | |
| 1122 // static order in which the keys appear. For the dynamic properties, we | |
| 1123 // compile them into a series of "SetOwnProperty" runtime calls. This will | |
| 1124 // preserve insertion order. | |
| 1125 for (; property_index < expr->properties()->length(); property_index++) { | |
| 1126 ObjectLiteral::Property* property = expr->properties()->at(property_index); | |
| 1127 | |
| 1128 environment()->Push(literal); // Duplicate receiver. | |
| 1129 VisitForValue(property->key()); | |
| 1130 environment()->Push(BuildToName(environment()->Pop())); | |
| 1131 // TODO(mstarzinger): For ObjectLiteral::Property::PROTOTYPE the key should | |
| 
 
arv (Not doing code reviews)
2015/02/13 15:15:57
In the case of the property being `__proto__: expr
 
Michael Starzinger
2015/02/16 10:39:15
The TODO is not about evaluating the "key" being o
 
 | |
| 1132 // not be on the operand stack while the value is being evaluated. Come up | |
| 1133 // with a repro for this and fix it. Also find a nice way to do so. :) | |
| 1134 VisitForValue(property->value()); | |
| 1135 Node* value = environment()->Pop(); | |
| 1136 Node* key = environment()->Pop(); | |
| 1137 Node* receiver = environment()->Pop(); | |
| 1138 | |
| 1139 switch (property->kind()) { | |
| 1140 case ObjectLiteral::Property::CONSTANT: | |
| 1141 case ObjectLiteral::Property::COMPUTED: | |
| 1142 case ObjectLiteral::Property::MATERIALIZED_LITERAL: { | |
| 1143 Node* attr = jsgraph()->Constant(NONE); | |
| 1144 const Operator* op = | |
| 1145 javascript()->CallRuntime(Runtime::kDefineDataPropertyUnchecked, 4); | |
| 1146 Node* call = NewNode(op, receiver, key, value, attr); | |
| 1147 PrepareFrameState(call, BailoutId::None()); | |
| 1148 break; | |
| 1149 } | |
| 1150 case ObjectLiteral::Property::PROTOTYPE: { | |
| 1151 const Operator* op = | |
| 1152 javascript()->CallRuntime(Runtime::kInternalSetPrototype, 2); | |
| 1153 Node* call = NewNode(op, receiver, value); | |
| 1154 PrepareFrameState(call, BailoutId::None()); | |
| 1155 break; | |
| 1156 } | |
| 1157 case ObjectLiteral::Property::GETTER: { | |
| 1158 const Operator* op = javascript()->CallRuntime( | |
| 1159 Runtime::kDefineGetterPropertyUnchecked, 3); | |
| 1160 Node* call = NewNode(op, receiver, key, value); | |
| 1161 PrepareFrameState(call, BailoutId::None()); | |
| 1162 break; | |
| 1163 } | |
| 1164 case ObjectLiteral::Property::SETTER: { | |
| 1165 const Operator* op = javascript()->CallRuntime( | |
| 1166 Runtime::kDefineSetterPropertyUnchecked, 3); | |
| 1167 Node* call = NewNode(op, receiver, key, value); | |
| 1168 PrepareFrameState(call, BailoutId::None()); | |
| 1169 break; | |
| 1170 } | |
| 1171 } | |
| 1172 } | |
| 1173 | |
| 1114 // Transform literals that contain functions to fast properties. | 1174 // Transform literals that contain functions to fast properties. | 
| 1115 if (expr->has_function()) { | 1175 if (expr->has_function()) { | 
| 1116 const Operator* op = | 1176 const Operator* op = | 
| 1117 javascript()->CallRuntime(Runtime::kToFastProperties, 1); | 1177 javascript()->CallRuntime(Runtime::kToFastProperties, 1); | 
| 1118 NewNode(op, literal); | 1178 NewNode(op, literal); | 
| 1119 } | 1179 } | 
| 1120 | 1180 | 
| 1121 ast_context()->ProduceValue(environment()->Pop()); | 1181 ast_context()->ProduceValue(environment()->Pop()); | 
| 1122 } | 1182 } | 
| 1123 | 1183 | 
| (...skipping 1243 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 2367 | 2427 | 
| 2368 BitVector* AstGraphBuilder::GetVariablesAssignedInLoop( | 2428 BitVector* AstGraphBuilder::GetVariablesAssignedInLoop( | 
| 2369 IterationStatement* stmt) { | 2429 IterationStatement* stmt) { | 
| 2370 if (loop_assignment_analysis_ == NULL) return NULL; | 2430 if (loop_assignment_analysis_ == NULL) return NULL; | 
| 2371 return loop_assignment_analysis_->GetVariablesAssignedInLoop(stmt); | 2431 return loop_assignment_analysis_->GetVariablesAssignedInLoop(stmt); | 
| 2372 } | 2432 } | 
| 2373 | 2433 | 
| 2374 } // namespace compiler | 2434 } // namespace compiler | 
| 2375 } // namespace internal | 2435 } // namespace internal | 
| 2376 } // namespace v8 | 2436 } // namespace v8 | 
| OLD | NEW |