| OLD | NEW | 
|---|
| 1 // Copyright 2015 the V8 project authors. All rights reserved. | 1 // Copyright 2015 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/interpreter/bytecode-generator.h" | 5 #include "src/interpreter/bytecode-generator.h" | 
| 6 | 6 | 
| 7 #include "src/ast/scopes.h" | 7 #include "src/ast/scopes.h" | 
| 8 #include "src/compiler.h" | 8 #include "src/compiler.h" | 
| 9 #include "src/interpreter/bytecode-register-allocator.h" | 9 #include "src/interpreter/bytecode-register-allocator.h" | 
| 10 #include "src/interpreter/control-flow-builders.h" | 10 #include "src/interpreter/control-flow-builders.h" | 
| (...skipping 1210 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
| 1221   Handle<SharedFunctionInfo> shared_info = | 1221   Handle<SharedFunctionInfo> shared_info = | 
| 1222       Compiler::GetSharedFunctionInfo(expr, info()->script(), info()); | 1222       Compiler::GetSharedFunctionInfo(expr, info()->script(), info()); | 
| 1223   CHECK(!shared_info.is_null());  // TODO(rmcilroy): Set stack overflow? | 1223   CHECK(!shared_info.is_null());  // TODO(rmcilroy): Set stack overflow? | 
| 1224   builder()->CreateClosure(shared_info, | 1224   builder()->CreateClosure(shared_info, | 
| 1225                            expr->pretenure() ? TENURED : NOT_TENURED); | 1225                            expr->pretenure() ? TENURED : NOT_TENURED); | 
| 1226   execution_result()->SetResultInAccumulator(); | 1226   execution_result()->SetResultInAccumulator(); | 
| 1227 } | 1227 } | 
| 1228 | 1228 | 
| 1229 | 1229 | 
| 1230 void BytecodeGenerator::VisitClassLiteral(ClassLiteral* expr) { | 1230 void BytecodeGenerator::VisitClassLiteral(ClassLiteral* expr) { | 
| 1231   UNIMPLEMENTED(); | 1231   if (expr->scope()->ContextLocalCount() > 0) { | 
|  | 1232     VisitNewLocalBlockContext(expr->scope()); | 
|  | 1233     ContextScope scope(this, expr->scope()); | 
|  | 1234     VisitDeclarations(expr->scope()->declarations()); | 
|  | 1235     VisitClassLiteralContents(expr); | 
|  | 1236   } else { | 
|  | 1237     VisitDeclarations(expr->scope()->declarations()); | 
|  | 1238     VisitClassLiteralContents(expr); | 
|  | 1239   } | 
| 1232 } | 1240 } | 
| 1233 | 1241 | 
|  | 1242 void BytecodeGenerator::VisitClassLiteralContents(ClassLiteral* expr) { | 
|  | 1243   VisitClassLiteralForRuntimeDefinition(expr); | 
|  | 1244   // The prototype is ensured to exist by Runtime_DefineClass in | 
|  | 1245   // VisitClassForRuntimeDefinition. No access check is needed here | 
|  | 1246   // since the constructor is created by the class literal. | 
|  | 1247   register_allocator()->PrepareForConsecutiveAllocations(2); | 
|  | 1248   Register literal = register_allocator()->NextConsecutiveRegister(); | 
|  | 1249   Register prototype = register_allocator()->NextConsecutiveRegister(); | 
|  | 1250   builder() | 
|  | 1251       ->StoreAccumulatorInRegister(literal) | 
|  | 1252       .LoadPrototypeOrInitialMap() | 
|  | 1253       .StoreAccumulatorInRegister(prototype); | 
|  | 1254 | 
|  | 1255   VisitClassLiteralProperties(expr, literal, prototype); | 
|  | 1256   builder()->CallRuntime(Runtime::kFinalizeClassDefinition, literal, 2); | 
|  | 1257   // Assign to class variable. | 
|  | 1258   if (expr->class_variable_proxy() != nullptr) { | 
|  | 1259     Variable* var = expr->class_variable_proxy()->var(); | 
|  | 1260     FeedbackVectorSlot slot = expr->NeedsProxySlot() | 
|  | 1261                                   ? expr->ProxySlot() | 
|  | 1262                                   : FeedbackVectorSlot::Invalid(); | 
|  | 1263     VisitVariableAssignment(var, slot); | 
|  | 1264   } | 
|  | 1265   execution_result()->SetResultInAccumulator(); | 
|  | 1266 } | 
|  | 1267 | 
|  | 1268 void BytecodeGenerator::VisitClassLiteralForRuntimeDefinition( | 
|  | 1269     ClassLiteral* expr) { | 
|  | 1270   AccumulatorResultScope result_scope(this); | 
|  | 1271   register_allocator()->PrepareForConsecutiveAllocations(4); | 
|  | 1272   Register extends = register_allocator()->NextConsecutiveRegister(); | 
|  | 1273   Register constructor = register_allocator()->NextConsecutiveRegister(); | 
|  | 1274   Register start_position = register_allocator()->NextConsecutiveRegister(); | 
|  | 1275   Register end_position = register_allocator()->NextConsecutiveRegister(); | 
|  | 1276 | 
|  | 1277   VisitForAccumulatorValueOrTheHole(expr->extends()); | 
|  | 1278   builder()->StoreAccumulatorInRegister(extends); | 
|  | 1279 | 
|  | 1280   VisitForAccumulatorValue(expr->constructor()); | 
|  | 1281   builder() | 
|  | 1282       ->StoreAccumulatorInRegister(constructor) | 
|  | 1283       .LoadLiteral(Smi::FromInt(expr->start_position())) | 
|  | 1284       .StoreAccumulatorInRegister(start_position) | 
|  | 1285       .LoadLiteral(Smi::FromInt(expr->end_position())) | 
|  | 1286       .StoreAccumulatorInRegister(end_position) | 
|  | 1287       .CallRuntime(Runtime::kDefineClass, extends, 4); | 
|  | 1288   result_scope.SetResultInAccumulator(); | 
|  | 1289 } | 
|  | 1290 | 
|  | 1291 void BytecodeGenerator::VisitClassLiteralProperties(ClassLiteral* expr, | 
|  | 1292                                                     Register literal, | 
|  | 1293                                                     Register prototype) { | 
|  | 1294   RegisterAllocationScope register_scope(this); | 
|  | 1295   register_allocator()->PrepareForConsecutiveAllocations(4); | 
|  | 1296   Register receiver = register_allocator()->NextConsecutiveRegister(); | 
|  | 1297   Register key = register_allocator()->NextConsecutiveRegister(); | 
|  | 1298   Register value = register_allocator()->NextConsecutiveRegister(); | 
|  | 1299   Register attr = register_allocator()->NextConsecutiveRegister(); | 
|  | 1300 | 
|  | 1301   bool attr_assigned = false; | 
|  | 1302   Register old_receiver = Register::invalid_value(); | 
|  | 1303 | 
|  | 1304   // Create nodes to store method values into the literal. | 
|  | 1305   for (int i = 0; i < expr->properties()->length(); i++) { | 
|  | 1306     ObjectLiteral::Property* property = expr->properties()->at(i); | 
|  | 1307 | 
|  | 1308     // Set-up receiver. | 
|  | 1309     Register new_receiver = property->is_static() ? literal : prototype; | 
|  | 1310     if (new_receiver != old_receiver) { | 
|  | 1311       builder()->MoveRegister(new_receiver, receiver); | 
|  | 1312       old_receiver = new_receiver; | 
|  | 1313     } | 
|  | 1314 | 
|  | 1315     VisitForAccumulatorValue(property->key()); | 
|  | 1316     builder()->CastAccumulatorToName().StoreAccumulatorInRegister(key); | 
|  | 1317     // The static prototype property is read only. We handle the non computed | 
|  | 1318     // property name case in the parser. Since this is the only case where we | 
|  | 1319     // need to check for an own read only property we special case this so we do | 
|  | 1320     // not need to do this for every property. | 
|  | 1321     if (property->is_static() && property->is_computed_name()) { | 
|  | 1322       VisitClassLiteralStaticPrototypeWithComputedName(key); | 
|  | 1323     } | 
|  | 1324     VisitForAccumulatorValue(property->value()); | 
|  | 1325     builder()->StoreAccumulatorInRegister(value); | 
|  | 1326 | 
|  | 1327     VisitSetHomeObject(value, receiver, property); | 
|  | 1328 | 
|  | 1329     if ((property->kind() == ObjectLiteral::Property::GETTER || | 
|  | 1330          property->kind() == ObjectLiteral::Property::SETTER) && | 
|  | 1331         !attr_assigned) { | 
|  | 1332       builder() | 
|  | 1333           ->LoadLiteral(Smi::FromInt(DONT_ENUM)) | 
|  | 1334           .StoreAccumulatorInRegister(attr); | 
|  | 1335       attr_assigned = true; | 
|  | 1336     } | 
|  | 1337 | 
|  | 1338     switch (property->kind()) { | 
|  | 1339       case ObjectLiteral::Property::CONSTANT: | 
|  | 1340       case ObjectLiteral::Property::MATERIALIZED_LITERAL: | 
|  | 1341       case ObjectLiteral::Property::PROTOTYPE: | 
|  | 1342         // Invalid properties for ES6 classes. | 
|  | 1343         UNREACHABLE(); | 
|  | 1344         break; | 
|  | 1345       case ObjectLiteral::Property::COMPUTED: { | 
|  | 1346         builder()->CallRuntime(Runtime::kDefineClassMethod, receiver, 3); | 
|  | 1347         break; | 
|  | 1348       } | 
|  | 1349       case ObjectLiteral::Property::GETTER: { | 
|  | 1350         builder()->CallRuntime(Runtime::kDefineGetterPropertyUnchecked, | 
|  | 1351                                receiver, 4); | 
|  | 1352         break; | 
|  | 1353       } | 
|  | 1354       case ObjectLiteral::Property::SETTER: { | 
|  | 1355         builder()->CallRuntime(Runtime::kDefineSetterPropertyUnchecked, | 
|  | 1356                                receiver, 4); | 
|  | 1357         break; | 
|  | 1358       } | 
|  | 1359     } | 
|  | 1360   } | 
|  | 1361 } | 
|  | 1362 | 
|  | 1363 void BytecodeGenerator::VisitClassLiteralStaticPrototypeWithComputedName( | 
|  | 1364     Register key) { | 
|  | 1365   BytecodeLabel done; | 
|  | 1366   builder() | 
|  | 1367       ->LoadLiteral(isolate()->factory()->prototype_string()) | 
|  | 1368       .CompareOperation(Token::Value::EQ_STRICT, key, Strength::WEAK) | 
|  | 1369       .JumpIfFalse(&done) | 
|  | 1370       .CallRuntime(Runtime::kThrowStaticPrototypeError, Register(0), 0) | 
|  | 1371       .Bind(&done); | 
|  | 1372 } | 
| 1234 | 1373 | 
| 1235 void BytecodeGenerator::VisitNativeFunctionLiteral( | 1374 void BytecodeGenerator::VisitNativeFunctionLiteral( | 
| 1236     NativeFunctionLiteral* expr) { | 1375     NativeFunctionLiteral* expr) { | 
| 1237   // Find or build a shared function info for the native function template. | 1376   // Find or build a shared function info for the native function template. | 
| 1238   Handle<SharedFunctionInfo> shared_info = | 1377   Handle<SharedFunctionInfo> shared_info = | 
| 1239       Compiler::GetSharedFunctionInfoForNative(expr->extension(), expr->name()); | 1378       Compiler::GetSharedFunctionInfoForNative(expr->extension(), expr->name()); | 
| 1240   builder()->CreateClosure(shared_info, NOT_TENURED); | 1379   builder()->CreateClosure(shared_info, NOT_TENURED); | 
| 1241   execution_result()->SetResultInAccumulator(); | 1380   execution_result()->SetResultInAccumulator(); | 
| 1242 } | 1381 } | 
| 1243 | 1382 | 
| (...skipping 1269 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
| 2513   execution_result()->SetResultInAccumulator(); | 2652   execution_result()->SetResultInAccumulator(); | 
| 2514 } | 2653 } | 
| 2515 | 2654 | 
| 2516 | 2655 | 
| 2517 // Visits the expression |expr| and places the result in the accumulator. | 2656 // Visits the expression |expr| and places the result in the accumulator. | 
| 2518 void BytecodeGenerator::VisitForAccumulatorValue(Expression* expr) { | 2657 void BytecodeGenerator::VisitForAccumulatorValue(Expression* expr) { | 
| 2519   AccumulatorResultScope accumulator_scope(this); | 2658   AccumulatorResultScope accumulator_scope(this); | 
| 2520   Visit(expr); | 2659   Visit(expr); | 
| 2521 } | 2660 } | 
| 2522 | 2661 | 
|  | 2662 void BytecodeGenerator::VisitForAccumulatorValueOrTheHole(Expression* expr) { | 
|  | 2663   if (expr == nullptr) { | 
|  | 2664     builder()->LoadTheHole(); | 
|  | 2665   } else { | 
|  | 2666     VisitForAccumulatorValue(expr); | 
|  | 2667   } | 
|  | 2668 } | 
| 2523 | 2669 | 
| 2524 // Visits the expression |expr| and discards the result. | 2670 // Visits the expression |expr| and discards the result. | 
| 2525 void BytecodeGenerator::VisitForEffect(Expression* expr) { | 2671 void BytecodeGenerator::VisitForEffect(Expression* expr) { | 
| 2526   EffectResultScope effect_scope(this); | 2672   EffectResultScope effect_scope(this); | 
| 2527   Visit(expr); | 2673   Visit(expr); | 
| 2528 } | 2674 } | 
| 2529 | 2675 | 
| 2530 | 2676 | 
| 2531 // Visits the expression |expr| and returns the register containing | 2677 // Visits the expression |expr| and returns the register containing | 
| 2532 // the expression result. | 2678 // the expression result. | 
| (...skipping 21 matching lines...) Expand all  Loading... | 
| 2554 } | 2700 } | 
| 2555 | 2701 | 
| 2556 | 2702 | 
| 2557 int BytecodeGenerator::feedback_index(FeedbackVectorSlot slot) const { | 2703 int BytecodeGenerator::feedback_index(FeedbackVectorSlot slot) const { | 
| 2558   return TypeFeedbackVector::GetIndex(slot); | 2704   return TypeFeedbackVector::GetIndex(slot); | 
| 2559 } | 2705 } | 
| 2560 | 2706 | 
| 2561 }  // namespace interpreter | 2707 }  // namespace interpreter | 
| 2562 }  // namespace internal | 2708 }  // namespace internal | 
| 2563 }  // namespace v8 | 2709 }  // namespace v8 | 
| OLD | NEW | 
|---|