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