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

Side by Side Diff: src/interpreter/bytecode-generator.cc

Issue 2142333002: Refactor class declaration logic to the parser and runtime Base URL: https://chromium.googlesource.com/v8/v8.git@master
Patch Set: minor cleanup per Adam Created 4 years, 5 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
OLDNEW
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/code-stubs.h" 8 #include "src/code-stubs.h"
9 #include "src/compiler.h" 9 #include "src/compiler.h"
10 #include "src/interpreter/bytecode-register-allocator.h" 10 #include "src/interpreter/bytecode-register-allocator.h"
(...skipping 1286 matching lines...) Expand 10 before | Expand all | Expand 10 after
1297 Compiler::GetSharedFunctionInfo(expr, info()->script(), info()); 1297 Compiler::GetSharedFunctionInfo(expr, info()->script(), info());
1298 if (shared_info.is_null()) { 1298 if (shared_info.is_null()) {
1299 return SetStackOverflow(); 1299 return SetStackOverflow();
1300 } 1300 }
1301 uint8_t flags = CreateClosureFlags::Encode(expr->pretenure(), 1301 uint8_t flags = CreateClosureFlags::Encode(expr->pretenure(),
1302 scope()->is_function_scope()); 1302 scope()->is_function_scope());
1303 builder()->CreateClosure(shared_info, flags); 1303 builder()->CreateClosure(shared_info, flags);
1304 execution_result()->SetResultInAccumulator(); 1304 execution_result()->SetResultInAccumulator();
1305 } 1305 }
1306 1306
1307 void BytecodeGenerator::VisitClassLiteral(ClassLiteral* expr) {
1308 if (expr->scope()->ContextLocalCount() > 0) {
1309 VisitNewLocalBlockContext(expr->scope());
1310 ContextScope scope(this, expr->scope());
1311 VisitDeclarations(expr->scope()->declarations());
1312 VisitClassLiteralContents(expr);
1313 } else {
1314 VisitDeclarations(expr->scope()->declarations());
1315 VisitClassLiteralContents(expr);
1316 }
1317 }
1318
1319 void BytecodeGenerator::VisitClassLiteralContents(ClassLiteral* expr) {
1320 VisitClassLiteralForRuntimeDefinition(expr);
1321
1322 // Load the "prototype" from the constructor.
1323 register_allocator()->PrepareForConsecutiveAllocations(2);
1324 Register literal = register_allocator()->NextConsecutiveRegister();
1325 Register prototype = register_allocator()->NextConsecutiveRegister();
1326 Handle<String> name = isolate()->factory()->prototype_string();
1327 FeedbackVectorSlot slot = expr->PrototypeSlot();
1328 builder()
1329 ->StoreAccumulatorInRegister(literal)
1330 .LoadNamedProperty(literal, name, feedback_index(slot))
1331 .StoreAccumulatorInRegister(prototype);
1332
1333 VisitClassLiteralProperties(expr, literal, prototype);
1334 builder()->CallRuntime(Runtime::kToFastProperties, literal, 1);
1335 // Assign to class variable.
1336 if (expr->class_variable_proxy() != nullptr) {
1337 Variable* var = expr->class_variable_proxy()->var();
1338 FeedbackVectorSlot slot = expr->NeedsProxySlot()
1339 ? expr->ProxySlot()
1340 : FeedbackVectorSlot::Invalid();
1341 VisitVariableAssignment(var, Token::INIT, slot);
1342 }
1343 execution_result()->SetResultInAccumulator();
1344 }
1345
1346 void BytecodeGenerator::VisitClassLiteralForRuntimeDefinition(
1347 ClassLiteral* expr) {
1348 AccumulatorResultScope result_scope(this);
1349 register_allocator()->PrepareForConsecutiveAllocations(4);
1350 Register extends = register_allocator()->NextConsecutiveRegister();
1351 Register constructor = register_allocator()->NextConsecutiveRegister();
1352 Register start_position = register_allocator()->NextConsecutiveRegister();
1353 Register end_position = register_allocator()->NextConsecutiveRegister();
1354
1355 VisitForAccumulatorValueOrTheHole(expr->extends());
1356 builder()->StoreAccumulatorInRegister(extends);
1357
1358 VisitForAccumulatorValue(expr->constructor());
1359 builder()
1360 ->StoreAccumulatorInRegister(constructor)
1361 .LoadLiteral(Smi::FromInt(expr->start_position()))
1362 .StoreAccumulatorInRegister(start_position)
1363 .LoadLiteral(Smi::FromInt(expr->end_position()))
1364 .StoreAccumulatorInRegister(end_position)
1365 .CallRuntime(Runtime::kDefineClass, extends, 4);
1366 result_scope.SetResultInAccumulator();
1367 }
1368
1369 void BytecodeGenerator::VisitClassLiteralProperties(ClassLiteral* expr,
1370 Register literal,
1371 Register prototype) {
1372 RegisterAllocationScope register_scope(this);
1373 register_allocator()->PrepareForConsecutiveAllocations(5);
1374 Register receiver = register_allocator()->NextConsecutiveRegister();
1375 Register key = register_allocator()->NextConsecutiveRegister();
1376 Register value = register_allocator()->NextConsecutiveRegister();
1377 Register attr = register_allocator()->NextConsecutiveRegister();
1378 Register set_function_name = register_allocator()->NextConsecutiveRegister();
1379
1380 bool attr_assigned = false;
1381 Register old_receiver = Register::invalid_value();
1382
1383 // Create nodes to store method values into the literal.
1384 for (int i = 0; i < expr->properties()->length(); i++) {
1385 ObjectLiteral::Property* property = expr->properties()->at(i);
1386
1387 // Set-up receiver.
1388 Register new_receiver = property->is_static() ? literal : prototype;
1389 if (new_receiver != old_receiver) {
1390 builder()->MoveRegister(new_receiver, receiver);
1391 old_receiver = new_receiver;
1392 }
1393
1394 VisitForAccumulatorValue(property->key());
1395 builder()->CastAccumulatorToName().StoreAccumulatorInRegister(key);
1396 // The static prototype property is read only. We handle the non computed
1397 // property name case in the parser. Since this is the only case where we
1398 // need to check for an own read only property we special case this so we do
1399 // not need to do this for every property.
1400 if (property->is_static() && property->is_computed_name()) {
1401 VisitClassLiteralStaticPrototypeWithComputedName(key);
1402 }
1403 VisitForAccumulatorValue(property->value());
1404 builder()->StoreAccumulatorInRegister(value);
1405
1406 VisitSetHomeObject(value, receiver, property);
1407
1408 if (!attr_assigned) {
1409 builder()
1410 ->LoadLiteral(Smi::FromInt(DONT_ENUM))
1411 .StoreAccumulatorInRegister(attr);
1412 attr_assigned = true;
1413 }
1414
1415 switch (property->kind()) {
1416 case ObjectLiteral::Property::CONSTANT:
1417 case ObjectLiteral::Property::MATERIALIZED_LITERAL:
1418 case ObjectLiteral::Property::PROTOTYPE:
1419 // Invalid properties for ES6 classes.
1420 UNREACHABLE();
1421 break;
1422 case ObjectLiteral::Property::COMPUTED: {
1423 builder()
1424 ->LoadLiteral(Smi::FromInt(property->NeedsSetFunctionName()))
1425 .StoreAccumulatorInRegister(set_function_name);
1426 builder()->CallRuntime(Runtime::kDefineDataPropertyInLiteral, receiver,
1427 5);
1428 break;
1429 }
1430 case ObjectLiteral::Property::GETTER: {
1431 builder()->CallRuntime(Runtime::kDefineGetterPropertyUnchecked,
1432 receiver, 4);
1433 break;
1434 }
1435 case ObjectLiteral::Property::SETTER: {
1436 builder()->CallRuntime(Runtime::kDefineSetterPropertyUnchecked,
1437 receiver, 4);
1438 break;
1439 }
1440 }
1441 }
1442 }
1443
1444 void BytecodeGenerator::VisitClassLiteralStaticPrototypeWithComputedName(
1445 Register key) {
1446 BytecodeLabel done;
1447 builder()
1448 ->LoadLiteral(isolate()->factory()->prototype_string())
1449 .CompareOperation(Token::Value::EQ_STRICT, key)
1450 .JumpIfFalse(&done)
1451 .CallRuntime(Runtime::kThrowStaticPrototypeError, Register(0), 0)
1452 .Bind(&done);
1453 }
1454
1455 void BytecodeGenerator::VisitNativeFunctionLiteral( 1307 void BytecodeGenerator::VisitNativeFunctionLiteral(
1456 NativeFunctionLiteral* expr) { 1308 NativeFunctionLiteral* expr) {
1457 // Find or build a shared function info for the native function template. 1309 // Find or build a shared function info for the native function template.
1458 Handle<SharedFunctionInfo> shared_info = 1310 Handle<SharedFunctionInfo> shared_info =
1459 Compiler::GetSharedFunctionInfoForNative(expr->extension(), expr->name()); 1311 Compiler::GetSharedFunctionInfoForNative(expr->extension(), expr->name());
1460 builder()->CreateClosure(shared_info, NOT_TENURED); 1312 builder()->CreateClosure(shared_info, NOT_TENURED);
1461 execution_result()->SetResultInAccumulator(); 1313 execution_result()->SetResultInAccumulator();
1462 } 1314 }
1463 1315
1464 void BytecodeGenerator::VisitDoExpression(DoExpression* expr) { 1316 void BytecodeGenerator::VisitDoExpression(DoExpression* expr) {
(...skipping 1716 matching lines...) Expand 10 before | Expand all | Expand 10 after
3181 return execution_context()->scope()->language_mode(); 3033 return execution_context()->scope()->language_mode();
3182 } 3034 }
3183 3035
3184 int BytecodeGenerator::feedback_index(FeedbackVectorSlot slot) const { 3036 int BytecodeGenerator::feedback_index(FeedbackVectorSlot slot) const {
3185 return TypeFeedbackVector::GetIndex(slot); 3037 return TypeFeedbackVector::GetIndex(slot);
3186 } 3038 }
3187 3039
3188 } // namespace interpreter 3040 } // namespace interpreter
3189 } // namespace internal 3041 } // namespace internal
3190 } // namespace v8 3042 } // namespace v8
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698