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 |