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

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

Issue 2369873002: [Interpreter] Replace BytecodeRegisterAllocator with a simple bump pointer. (Closed)
Patch Set: Rebase Created 4 years, 2 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
« no previous file with comments | « src/interpreter/bytecode-generator.h ('k') | src/interpreter/bytecode-register-allocator.h » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
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/compile-time-value.h" 7 #include "src/ast/compile-time-value.h"
8 #include "src/ast/scopes.h" 8 #include "src/ast/scopes.h"
9 #include "src/code-stubs.h" 9 #include "src/code-stubs.h"
10 #include "src/compilation-info.h" 10 #include "src/compilation-info.h"
(...skipping 356 matching lines...) Expand 10 before | Expand all | Expand 10 after
367 generator()->builder()->PopContext(current->context()->reg()); 367 generator()->builder()->PopContext(current->context()->reg());
368 } 368 }
369 } while (current != nullptr); 369 } while (current != nullptr);
370 UNREACHABLE(); 370 UNREACHABLE();
371 } 371 }
372 372
373 class BytecodeGenerator::RegisterAllocationScope { 373 class BytecodeGenerator::RegisterAllocationScope {
374 public: 374 public:
375 explicit RegisterAllocationScope(BytecodeGenerator* generator) 375 explicit RegisterAllocationScope(BytecodeGenerator* generator)
376 : generator_(generator), 376 : generator_(generator),
377 outer_(generator->register_allocator()), 377 outer_next_register_index_(
378 allocator_(builder()->zone(), 378 generator->register_allocator()->next_register_index()) {}
379 builder()->temporary_register_allocator()) { 379
380 generator_->set_register_allocator(this); 380 virtual ~RegisterAllocationScope() {
381 generator_->register_allocator()->ReleaseRegisters(
382 outer_next_register_index_);
381 } 383 }
382 384
383 virtual ~RegisterAllocationScope() {
384 generator_->set_register_allocator(outer_);
385 }
386
387 Register NewRegister() {
388 RegisterAllocationScope* current_scope = generator()->register_allocator();
389 if ((current_scope == this) ||
390 (current_scope->outer() == this &&
391 !current_scope->allocator_.HasConsecutiveAllocations())) {
392 // Regular case - Allocating registers in current or outer context.
393 // VisitForRegisterValue allocates register in outer context.
394 return allocator_.NewRegister();
395 } else {
396 // If it is required to allocate a register other than current or outer
397 // scopes, allocate a new temporary register. It might be expensive to
398 // walk the full context chain and compute the list of consecutive
399 // reservations in the innerscopes.
400 UNIMPLEMENTED();
401 return Register::invalid_value();
402 }
403 }
404
405 void PrepareForConsecutiveAllocations(int count) {
406 allocator_.PrepareForConsecutiveAllocations(count);
407 }
408
409 Register NextConsecutiveRegister() {
410 return allocator_.NextConsecutiveRegister();
411 }
412
413 bool RegisterIsAllocatedInThisScope(Register reg) const {
414 return allocator_.RegisterIsAllocatedInThisScope(reg);
415 }
416
417 RegisterAllocationScope* outer() const { return outer_; }
418
419 private: 385 private:
420 BytecodeGenerator* generator() const { return generator_; }
421 BytecodeArrayBuilder* builder() const { return generator_->builder(); }
422
423 BytecodeGenerator* generator_; 386 BytecodeGenerator* generator_;
424 RegisterAllocationScope* outer_; 387 int outer_next_register_index_;
425 BytecodeRegisterAllocator allocator_;
426 388
427 DISALLOW_COPY_AND_ASSIGN(RegisterAllocationScope); 389 DISALLOW_COPY_AND_ASSIGN(RegisterAllocationScope);
428 }; 390 };
429 391
430 // Scoped base class for determining where the result of an expression 392 // Scoped base class for determining how the result of an expression will be
431 // is stored. 393 // used.
432 class BytecodeGenerator::ExpressionResultScope { 394 class BytecodeGenerator::ExpressionResultScope {
433 public: 395 public:
434 ExpressionResultScope(BytecodeGenerator* generator, Expression::Context kind) 396 ExpressionResultScope(BytecodeGenerator* generator, Expression::Context kind)
435 : generator_(generator), 397 : generator_(generator),
436 kind_(kind), 398 kind_(kind),
437 outer_(generator->execution_result()), 399 outer_(generator->execution_result()),
438 allocator_(generator), 400 allocator_(generator) {
439 result_identified_(false) {
440 generator_->set_execution_result(this); 401 generator_->set_execution_result(this);
441 } 402 }
442 403
443 virtual ~ExpressionResultScope() { 404 virtual ~ExpressionResultScope() {
444 generator_->set_execution_result(outer_); 405 generator_->set_execution_result(outer_);
445 DCHECK(result_identified() || generator_->HasStackOverflow());
446 } 406 }
447 407
448 bool IsEffect() const { return kind_ == Expression::kEffect; } 408 bool IsEffect() const { return kind_ == Expression::kEffect; }
449 bool IsValue() const { return kind_ == Expression::kValue; } 409 bool IsValue() const { return kind_ == Expression::kValue; }
450 bool IsTest() const { return kind_ == Expression::kTest; } 410 bool IsTest() const { return kind_ == Expression::kTest; }
451 411
452 TestResultScope* AsTest() { 412 TestResultScope* AsTest() {
453 DCHECK(IsTest()); 413 DCHECK(IsTest());
454 return reinterpret_cast<TestResultScope*>(this); 414 return reinterpret_cast<TestResultScope*>(this);
455 } 415 }
456 416
457 virtual void SetResultInAccumulator() = 0;
458 virtual void SetResultInRegister(Register reg) = 0;
459
460 protected:
461 ExpressionResultScope* outer() const { return outer_; }
462 BytecodeArrayBuilder* builder() const { return generator_->builder(); }
463 BytecodeGenerator* generator() const { return generator_; }
464 const RegisterAllocationScope* allocator() const { return &allocator_; }
465
466 void set_result_identified() {
467 DCHECK(!result_identified());
468 result_identified_ = true;
469 }
470
471 bool result_identified() const { return result_identified_; }
472
473 private: 417 private:
474 BytecodeGenerator* generator_; 418 BytecodeGenerator* generator_;
475 Expression::Context kind_; 419 Expression::Context kind_;
476 ExpressionResultScope* outer_; 420 ExpressionResultScope* outer_;
477 RegisterAllocationScope allocator_; 421 RegisterAllocationScope allocator_;
478 bool result_identified_;
479 422
480 DISALLOW_COPY_AND_ASSIGN(ExpressionResultScope); 423 DISALLOW_COPY_AND_ASSIGN(ExpressionResultScope);
481 }; 424 };
482 425
483 // Scoped class used when the result of the current expression is not 426 // Scoped class used when the result of the current expression is not
484 // expected to produce a result. 427 // expected to produce a result.
485 class BytecodeGenerator::EffectResultScope final 428 class BytecodeGenerator::EffectResultScope final
486 : public ExpressionResultScope { 429 : public ExpressionResultScope {
487 public: 430 public:
488 explicit EffectResultScope(BytecodeGenerator* generator) 431 explicit EffectResultScope(BytecodeGenerator* generator)
489 : ExpressionResultScope(generator, Expression::kEffect) { 432 : ExpressionResultScope(generator, Expression::kEffect) {}
490 set_result_identified();
491 }
492
493 virtual void SetResultInAccumulator() {}
494 virtual void SetResultInRegister(Register reg) {}
495 }; 433 };
496 434
497 // Scoped class used when the result of the current expression to be 435 // Scoped class used when the result of the current expression to be
498 // evaluated should go into the interpreter's accumulator register. 436 // evaluated should go into the interpreter's accumulator.
499 class BytecodeGenerator::AccumulatorResultScope final 437 class BytecodeGenerator::ValueResultScope final : public ExpressionResultScope {
500 : public ExpressionResultScope {
501 public: 438 public:
502 explicit AccumulatorResultScope(BytecodeGenerator* generator) 439 explicit ValueResultScope(BytecodeGenerator* generator)
503 : ExpressionResultScope(generator, Expression::kValue) {} 440 : ExpressionResultScope(generator, Expression::kValue) {}
504
505 virtual void SetResultInAccumulator() { set_result_identified(); }
506
507 virtual void SetResultInRegister(Register reg) {
508 builder()->LoadAccumulatorWithRegister(reg);
509 set_result_identified();
510 }
511 }; 441 };
512 442
513 // Scoped class used when the result of the current expression to be 443 // Scoped class used when the result of the current expression to be
514 // evaluated should go into an interpreter register.
515 class BytecodeGenerator::RegisterResultScope final
516 : public ExpressionResultScope {
517 public:
518 explicit RegisterResultScope(BytecodeGenerator* generator)
519 : ExpressionResultScope(generator, Expression::kValue) {}
520
521 virtual void SetResultInAccumulator() {
522 result_register_ = allocator()->outer()->NewRegister();
523 builder()->StoreAccumulatorInRegister(result_register_);
524 set_result_identified();
525 }
526
527 virtual void SetResultInRegister(Register reg) {
528 DCHECK(builder()->RegisterIsParameterOrLocal(reg) ||
529 (builder()->TemporaryRegisterIsLive(reg) &&
530 !allocator()->RegisterIsAllocatedInThisScope(reg)));
531 result_register_ = reg;
532 set_result_identified();
533 }
534
535 Register ResultRegister() {
536 if (generator()->HasStackOverflow() && !result_identified()) {
537 SetResultInAccumulator();
538 }
539 return result_register_;
540 }
541
542 private:
543 Register result_register_;
544 };
545
546 // Scoped class used when the result of the current expression to be
547 // evaluated is only tested with jumps to two branches. 444 // evaluated is only tested with jumps to two branches.
548 class BytecodeGenerator::TestResultScope final : public ExpressionResultScope { 445 class BytecodeGenerator::TestResultScope final : public ExpressionResultScope {
549 public: 446 public:
550 TestResultScope(BytecodeGenerator* generator, BytecodeLabels* then_labels, 447 TestResultScope(BytecodeGenerator* generator, BytecodeLabels* then_labels,
551 BytecodeLabels* else_labels, TestFallthrough fallthrough) 448 BytecodeLabels* else_labels, TestFallthrough fallthrough)
552 : ExpressionResultScope(generator, Expression::kTest), 449 : ExpressionResultScope(generator, Expression::kTest),
553 then_labels_(then_labels), 450 then_labels_(then_labels),
554 else_labels_(else_labels), 451 else_labels_(else_labels),
555 fallthrough_(fallthrough), 452 fallthrough_(fallthrough),
556 result_consumed_by_test_(false) {} 453 result_consumed_by_test_(false) {}
557 454
558 virtual void SetResultInAccumulator() { set_result_identified(); }
559
560 virtual void SetResultInRegister(Register reg) {
561 builder()->LoadAccumulatorWithRegister(reg);
562 set_result_identified();
563 }
564
565 // Used when code special cases for TestResultScope and consumes any 455 // Used when code special cases for TestResultScope and consumes any
566 // possible value by testing and jumping to a then/else label. 456 // possible value by testing and jumping to a then/else label.
567 void SetResultConsumedByTest() { 457 void SetResultConsumedByTest() {
568 result_consumed_by_test_ = true; 458 result_consumed_by_test_ = true;
569 set_result_identified();
570 } 459 }
571 460
572 bool ResultConsumedByTest() { return result_consumed_by_test_; } 461 bool ResultConsumedByTest() { return result_consumed_by_test_; }
573 462
574 BytecodeLabel* NewThenLabel() { return then_labels_->New(); } 463 BytecodeLabel* NewThenLabel() { return then_labels_->New(); }
575 BytecodeLabel* NewElseLabel() { return else_labels_->New(); } 464 BytecodeLabel* NewElseLabel() { return else_labels_->New(); }
576 465
577 BytecodeLabels* then_labels() const { return then_labels_; } 466 BytecodeLabels* then_labels() const { return then_labels_; }
578 BytecodeLabels* else_labels() const { return else_labels_; } 467 BytecodeLabels* else_labels() const { return else_labels_; }
579 468
(...skipping 91 matching lines...) Expand 10 before | Expand all | Expand 10 after
671 info->SourcePositionRecordingMode())), 560 info->SourcePositionRecordingMode())),
672 info_(info), 561 info_(info),
673 scope_(info->scope()), 562 scope_(info->scope()),
674 globals_builder_(new (zone()) GlobalDeclarationsBuilder(info->zone())), 563 globals_builder_(new (zone()) GlobalDeclarationsBuilder(info->zone())),
675 global_declarations_(0, info->zone()), 564 global_declarations_(0, info->zone()),
676 function_literals_(0, info->zone()), 565 function_literals_(0, info->zone()),
677 native_function_literals_(0, info->zone()), 566 native_function_literals_(0, info->zone()),
678 execution_control_(nullptr), 567 execution_control_(nullptr),
679 execution_context_(nullptr), 568 execution_context_(nullptr),
680 execution_result_(nullptr), 569 execution_result_(nullptr),
681 register_allocator_(nullptr),
682 generator_resume_points_(info->literal()->yield_count(), info->zone()), 570 generator_resume_points_(info->literal()->yield_count(), info->zone()),
683 generator_state_(), 571 generator_state_(),
684 loop_depth_(0), 572 loop_depth_(0),
685 home_object_symbol_(info->isolate()->factory()->home_object_symbol()), 573 home_object_symbol_(info->isolate()->factory()->home_object_symbol()),
686 prototype_string_(info->isolate()->factory()->prototype_string()) { 574 prototype_string_(info->isolate()->factory()->prototype_string()) {
687 } 575 }
688 576
689 Handle<BytecodeArray> BytecodeGenerator::FinalizeBytecode(Isolate* isolate) { 577 Handle<BytecodeArray> BytecodeGenerator::FinalizeBytecode(Isolate* isolate) {
690 AllocateDeferredConstants(); 578 AllocateDeferredConstants();
691 if (HasStackOverflow()) return Handle<BytecodeArray>(); 579 if (HasStackOverflow()) return Handle<BytecodeArray>();
(...skipping 229 matching lines...) Expand 10 before | Expand all | Expand 10 after
921 break; 809 break;
922 case VariableLocation::LOOKUP: { 810 case VariableLocation::LOOKUP: {
923 DCHECK_EQ(VAR, variable->mode()); 811 DCHECK_EQ(VAR, variable->mode());
924 DCHECK(!variable->binding_needs_init()); 812 DCHECK(!variable->binding_needs_init());
925 813
926 Register name = register_allocator()->NewRegister(); 814 Register name = register_allocator()->NewRegister();
927 815
928 builder() 816 builder()
929 ->LoadLiteral(variable->name()) 817 ->LoadLiteral(variable->name())
930 .StoreAccumulatorInRegister(name) 818 .StoreAccumulatorInRegister(name)
931 .CallRuntime(Runtime::kDeclareEvalVar, name, 1); 819 .CallRuntime(Runtime::kDeclareEvalVar, name);
932 break; 820 break;
933 } 821 }
934 case VariableLocation::MODULE: 822 case VariableLocation::MODULE:
935 if (variable->IsExport() && variable->binding_needs_init()) { 823 if (variable->IsExport() && variable->binding_needs_init()) {
936 builder()->LoadTheHole(); 824 builder()->LoadTheHole();
937 VisitVariableAssignment(variable, Token::INIT, 825 VisitVariableAssignment(variable, Token::INIT,
938 FeedbackVectorSlot::Invalid()); 826 FeedbackVectorSlot::Invalid());
939 } 827 }
940 // Nothing to do for imports. 828 // Nothing to do for imports.
941 break; 829 break;
(...skipping 17 matching lines...) Expand all
959 break; 847 break;
960 } 848 }
961 case VariableLocation::CONTEXT: { 849 case VariableLocation::CONTEXT: {
962 DCHECK_EQ(0, execution_context()->ContextChainDepth(variable->scope())); 850 DCHECK_EQ(0, execution_context()->ContextChainDepth(variable->scope()));
963 VisitForAccumulatorValue(decl->fun()); 851 VisitForAccumulatorValue(decl->fun());
964 builder()->StoreContextSlot(execution_context()->reg(), variable->index(), 852 builder()->StoreContextSlot(execution_context()->reg(), variable->index(),
965 0); 853 0);
966 break; 854 break;
967 } 855 }
968 case VariableLocation::LOOKUP: { 856 case VariableLocation::LOOKUP: {
969 register_allocator()->PrepareForConsecutiveAllocations(2); 857 RegisterList args = register_allocator()->NewRegisterList(2);
970 Register name = register_allocator()->NextConsecutiveRegister(); 858 builder()
971 Register literal = register_allocator()->NextConsecutiveRegister(); 859 ->LoadLiteral(variable->name())
972 builder()->LoadLiteral(variable->name()).StoreAccumulatorInRegister(name); 860 .StoreAccumulatorInRegister(args[0]);
973
974 VisitForAccumulatorValue(decl->fun()); 861 VisitForAccumulatorValue(decl->fun());
975 builder()->StoreAccumulatorInRegister(literal).CallRuntime( 862 builder()->StoreAccumulatorInRegister(args[1]).CallRuntime(
976 Runtime::kDeclareEvalFunction, name, 2); 863 Runtime::kDeclareEvalFunction, args);
977 break; 864 break;
978 } 865 }
979 case VariableLocation::MODULE: 866 case VariableLocation::MODULE:
980 DCHECK_EQ(variable->mode(), LET); 867 DCHECK_EQ(variable->mode(), LET);
981 DCHECK(variable->IsExport()); 868 DCHECK(variable->IsExport());
982 VisitForAccumulatorValue(decl->fun()); 869 VisitForAccumulatorValue(decl->fun());
983 VisitVariableAssignment(variable, Token::INIT, 870 VisitVariableAssignment(variable, Token::INIT,
984 FeedbackVectorSlot::Invalid()); 871 FeedbackVectorSlot::Invalid());
985 break; 872 break;
986 } 873 }
987 } 874 }
988 875
989 void BytecodeGenerator::VisitDeclarations( 876 void BytecodeGenerator::VisitDeclarations(
990 ZoneList<Declaration*>* declarations) { 877 ZoneList<Declaration*>* declarations) {
991 RegisterAllocationScope register_scope(this); 878 RegisterAllocationScope register_scope(this);
992 DCHECK(globals_builder()->empty()); 879 DCHECK(globals_builder()->empty());
993 for (int i = 0; i < declarations->length(); i++) { 880 for (int i = 0; i < declarations->length(); i++) {
994 RegisterAllocationScope register_scope(this); 881 RegisterAllocationScope register_scope(this);
995 Visit(declarations->at(i)); 882 Visit(declarations->at(i));
996 } 883 }
997 if (globals_builder()->empty()) return; 884 if (globals_builder()->empty()) return;
998 885
999 globals_builder()->set_constant_pool_entry( 886 globals_builder()->set_constant_pool_entry(
1000 builder()->AllocateConstantPoolEntry()); 887 builder()->AllocateConstantPoolEntry());
1001 int encoded_flags = info()->GetDeclareGlobalsFlags(); 888 int encoded_flags = info()->GetDeclareGlobalsFlags();
1002 889
1003 register_allocator()->PrepareForConsecutiveAllocations(3);
1004
1005 Register pairs = register_allocator()->NextConsecutiveRegister();
1006 Register flags = register_allocator()->NextConsecutiveRegister();
1007 Register function = register_allocator()->NextConsecutiveRegister();
1008
1009 // Emit code to declare globals. 890 // Emit code to declare globals.
891 RegisterList args = register_allocator()->NewRegisterList(3);
1010 builder() 892 builder()
1011 ->LoadConstantPoolEntry(globals_builder()->constant_pool_entry()) 893 ->LoadConstantPoolEntry(globals_builder()->constant_pool_entry())
1012 .StoreAccumulatorInRegister(pairs) 894 .StoreAccumulatorInRegister(args[0])
1013 .LoadLiteral(Smi::FromInt(encoded_flags)) 895 .LoadLiteral(Smi::FromInt(encoded_flags))
1014 .StoreAccumulatorInRegister(flags) 896 .StoreAccumulatorInRegister(args[1])
1015 .MoveRegister(Register::function_closure(), function) 897 .MoveRegister(Register::function_closure(), args[2])
1016 .CallRuntime(Runtime::kDeclareGlobalsForInterpreter, pairs, 3); 898 .CallRuntime(Runtime::kDeclareGlobalsForInterpreter, args);
1017 899
1018 // Push and reset globals builder. 900 // Push and reset globals builder.
1019 global_declarations_.push_back(globals_builder()); 901 global_declarations_.push_back(globals_builder());
1020 globals_builder_ = new (zone()) GlobalDeclarationsBuilder(zone()); 902 globals_builder_ = new (zone()) GlobalDeclarationsBuilder(zone());
1021 } 903 }
1022 904
1023 void BytecodeGenerator::VisitStatements(ZoneList<Statement*>* statements) { 905 void BytecodeGenerator::VisitStatements(ZoneList<Statement*>* statements) {
1024 for (int i = 0; i < statements->length(); i++) { 906 for (int i = 0; i < statements->length(); i++) {
1025 // Allocate an outer register allocations scope for the statement. 907 // Allocate an outer register allocations scope for the statement.
1026 RegisterAllocationScope allocation_scope(this); 908 RegisterAllocationScope allocation_scope(this);
(...skipping 234 matching lines...) Expand 10 before | Expand all | Expand 10 after
1261 builder()->StoreAccumulatorInRegister(value); 1143 builder()->StoreAccumulatorInRegister(value);
1262 Register object = VisitForRegisterValue(property->obj()); 1144 Register object = VisitForRegisterValue(property->obj());
1263 Register key = VisitForRegisterValue(property->key()); 1145 Register key = VisitForRegisterValue(property->key());
1264 builder()->LoadAccumulatorWithRegister(value); 1146 builder()->LoadAccumulatorWithRegister(value);
1265 builder()->StoreKeyedProperty(object, key, feedback_index(slot), 1147 builder()->StoreKeyedProperty(object, key, feedback_index(slot),
1266 language_mode()); 1148 language_mode());
1267 break; 1149 break;
1268 } 1150 }
1269 case NAMED_SUPER_PROPERTY: { 1151 case NAMED_SUPER_PROPERTY: {
1270 RegisterAllocationScope register_scope(this); 1152 RegisterAllocationScope register_scope(this);
1271 register_allocator()->PrepareForConsecutiveAllocations(4); 1153 RegisterList args = register_allocator()->NewRegisterList(4);
1272 Register receiver = register_allocator()->NextConsecutiveRegister(); 1154 builder()->StoreAccumulatorInRegister(args[3]);
1273 Register home_object = register_allocator()->NextConsecutiveRegister();
1274 Register name = register_allocator()->NextConsecutiveRegister();
1275 Register value = register_allocator()->NextConsecutiveRegister();
1276 builder()->StoreAccumulatorInRegister(value);
1277 SuperPropertyReference* super_property = 1155 SuperPropertyReference* super_property =
1278 property->obj()->AsSuperPropertyReference(); 1156 property->obj()->AsSuperPropertyReference();
1279 VisitForRegisterValue(super_property->this_var(), receiver); 1157 VisitForRegisterValue(super_property->this_var(), args[0]);
1280 VisitForRegisterValue(super_property->home_object(), home_object); 1158 VisitForRegisterValue(super_property->home_object(), args[1]);
1281 builder() 1159 builder()
1282 ->LoadLiteral(property->key()->AsLiteral()->AsPropertyName()) 1160 ->LoadLiteral(property->key()->AsLiteral()->AsPropertyName())
1283 .StoreAccumulatorInRegister(name); 1161 .StoreAccumulatorInRegister(args[2])
1284 BuildNamedSuperPropertyStore(receiver, home_object, name, value); 1162 .CallRuntime(StoreToSuperRuntimeId(), args);
1285 break; 1163 break;
1286 } 1164 }
1287 case KEYED_SUPER_PROPERTY: { 1165 case KEYED_SUPER_PROPERTY: {
1288 RegisterAllocationScope register_scope(this); 1166 RegisterAllocationScope register_scope(this);
1289 register_allocator()->PrepareForConsecutiveAllocations(4); 1167 RegisterList args = register_allocator()->NewRegisterList(4);
1290 Register receiver = register_allocator()->NextConsecutiveRegister(); 1168 builder()->StoreAccumulatorInRegister(args[3]);
1291 Register home_object = register_allocator()->NextConsecutiveRegister();
1292 Register key = register_allocator()->NextConsecutiveRegister();
1293 Register value = register_allocator()->NextConsecutiveRegister();
1294 builder()->StoreAccumulatorInRegister(value);
1295 SuperPropertyReference* super_property = 1169 SuperPropertyReference* super_property =
1296 property->obj()->AsSuperPropertyReference(); 1170 property->obj()->AsSuperPropertyReference();
1297 VisitForRegisterValue(super_property->this_var(), receiver); 1171 VisitForRegisterValue(super_property->this_var(), args[0]);
1298 VisitForRegisterValue(super_property->home_object(), home_object); 1172 VisitForRegisterValue(super_property->home_object(), args[1]);
1299 VisitForRegisterValue(property->key(), key); 1173 VisitForRegisterValue(property->key(), args[2]);
1300 BuildKeyedSuperPropertyStore(receiver, home_object, key, value); 1174 builder()->CallRuntime(StoreKeyedToSuperRuntimeId(), args);
1301 break; 1175 break;
1302 } 1176 }
1303 } 1177 }
1304 } 1178 }
1305 1179
1306 void BytecodeGenerator::VisitForInStatement(ForInStatement* stmt) { 1180 void BytecodeGenerator::VisitForInStatement(ForInStatement* stmt) {
1307 if (stmt->subject()->IsNullLiteral() || 1181 if (stmt->subject()->IsNullLiteral() ||
1308 stmt->subject()->IsUndefinedLiteral()) { 1182 stmt->subject()->IsUndefinedLiteral()) {
1309 // ForIn generates lots of code, skip if it wouldn't produce any effects. 1183 // ForIn generates lots of code, skip if it wouldn't produce any effects.
1310 return; 1184 return;
1311 } 1185 }
1312 1186
1313 LoopBuilder loop_builder(builder()); 1187 LoopBuilder loop_builder(builder());
1314 BytecodeLabel subject_null_label, subject_undefined_label; 1188 BytecodeLabel subject_null_label, subject_undefined_label;
1315 1189
1316 // Prepare the state for executing ForIn. 1190 // Prepare the state for executing ForIn.
1317 builder()->SetExpressionAsStatementPosition(stmt->subject()); 1191 builder()->SetExpressionAsStatementPosition(stmt->subject());
1318 VisitForAccumulatorValue(stmt->subject()); 1192 VisitForAccumulatorValue(stmt->subject());
1319 builder()->JumpIfUndefined(&subject_undefined_label); 1193 builder()->JumpIfUndefined(&subject_undefined_label);
1320 builder()->JumpIfNull(&subject_null_label); 1194 builder()->JumpIfNull(&subject_null_label);
1321 Register receiver = register_allocator()->NewRegister(); 1195 Register receiver = register_allocator()->NewRegister();
1322 builder()->ConvertAccumulatorToObject(receiver); 1196 builder()->ConvertAccumulatorToObject(receiver);
1323 1197
1324 register_allocator()->PrepareForConsecutiveAllocations(3);
1325 Register cache_type = register_allocator()->NextConsecutiveRegister();
1326 Register cache_array = register_allocator()->NextConsecutiveRegister();
1327 Register cache_length = register_allocator()->NextConsecutiveRegister();
1328 // Used as kRegTriple and kRegPair in ForInPrepare and ForInNext. 1198 // Used as kRegTriple and kRegPair in ForInPrepare and ForInNext.
1329 USE(cache_array); 1199 RegisterList triple = register_allocator()->NewRegisterList(3);
1330 builder()->ForInPrepare(receiver, cache_type); 1200 Register cache_length = triple[2];
1201 builder()->ForInPrepare(receiver, triple.first_register());
1331 1202
1332 // Set up loop counter 1203 // Set up loop counter
1333 Register index = register_allocator()->NewRegister(); 1204 Register index = register_allocator()->NewRegister();
1334 builder()->LoadLiteral(Smi::FromInt(0)); 1205 builder()->LoadLiteral(Smi::FromInt(0));
1335 builder()->StoreAccumulatorInRegister(index); 1206 builder()->StoreAccumulatorInRegister(index);
1336 1207
1337 // The loop 1208 // The loop
1338 VisitIterationHeader(stmt, &loop_builder); 1209 VisitIterationHeader(stmt, &loop_builder);
1339 builder()->SetExpressionAsStatementPosition(stmt->each()); 1210 builder()->SetExpressionAsStatementPosition(stmt->each());
1340 builder()->ForInContinue(index, cache_length); 1211 builder()->ForInContinue(index, cache_length);
1341 loop_builder.BreakIfFalse(); 1212 loop_builder.BreakIfFalse();
1342 DCHECK(Register::AreContiguous(cache_type, cache_array));
1343 FeedbackVectorSlot slot = stmt->ForInFeedbackSlot(); 1213 FeedbackVectorSlot slot = stmt->ForInFeedbackSlot();
1344 builder()->ForInNext(receiver, index, cache_type, feedback_index(slot)); 1214 builder()->ForInNext(receiver, index, triple.first_register(),
1215 feedback_index(slot));
1345 loop_builder.ContinueIfUndefined(); 1216 loop_builder.ContinueIfUndefined();
1346 VisitForInAssignment(stmt->each(), stmt->EachFeedbackSlot()); 1217 VisitForInAssignment(stmt->each(), stmt->EachFeedbackSlot());
1347 VisitIterationBody(stmt, &loop_builder); 1218 VisitIterationBody(stmt, &loop_builder);
1348 builder()->ForInStep(index); 1219 builder()->ForInStep(index);
1349 builder()->StoreAccumulatorInRegister(index); 1220 builder()->StoreAccumulatorInRegister(index);
1350 loop_builder.JumpToHeader(loop_depth_); 1221 loop_builder.JumpToHeader(loop_depth_);
1351 loop_builder.EndLoop(); 1222 loop_builder.EndLoop();
1352 builder()->Bind(&subject_null_label); 1223 builder()->Bind(&subject_null_label);
1353 builder()->Bind(&subject_undefined_label); 1224 builder()->Bind(&subject_undefined_label);
1354 } 1225 }
(...skipping 11 matching lines...) Expand all
1366 loop_builder.BreakIfTrue(); 1237 loop_builder.BreakIfTrue();
1367 1238
1368 VisitForEffect(stmt->assign_each()); 1239 VisitForEffect(stmt->assign_each());
1369 VisitIterationBody(stmt, &loop_builder); 1240 VisitIterationBody(stmt, &loop_builder);
1370 loop_builder.JumpToHeader(loop_depth_); 1241 loop_builder.JumpToHeader(loop_depth_);
1371 loop_builder.EndLoop(); 1242 loop_builder.EndLoop();
1372 } 1243 }
1373 1244
1374 void BytecodeGenerator::VisitTryCatchStatement(TryCatchStatement* stmt) { 1245 void BytecodeGenerator::VisitTryCatchStatement(TryCatchStatement* stmt) {
1375 TryCatchBuilder try_control_builder(builder(), stmt->catch_prediction()); 1246 TryCatchBuilder try_control_builder(builder(), stmt->catch_prediction());
1376 Register no_reg;
1377 1247
1378 // Preserve the context in a dedicated register, so that it can be restored 1248 // Preserve the context in a dedicated register, so that it can be restored
1379 // when the handler is entered by the stack-unwinding machinery. 1249 // when the handler is entered by the stack-unwinding machinery.
1380 // TODO(mstarzinger): Be smarter about register allocation. 1250 // TODO(mstarzinger): Be smarter about register allocation.
1381 Register context = register_allocator()->NewRegister(); 1251 Register context = register_allocator()->NewRegister();
1382 builder()->MoveRegister(Register::current_context(), context); 1252 builder()->MoveRegister(Register::current_context(), context);
1383 1253
1384 // Evaluate the try-block inside a control scope. This simulates a handler 1254 // Evaluate the try-block inside a control scope. This simulates a handler
1385 // that is intercepting 'throw' control commands. 1255 // that is intercepting 'throw' control commands.
1386 try_control_builder.BeginTry(context); 1256 try_control_builder.BeginTry(context);
1387 { 1257 {
1388 ControlScopeForTryCatch scope(this, &try_control_builder); 1258 ControlScopeForTryCatch scope(this, &try_control_builder);
1389 Visit(stmt->try_block()); 1259 Visit(stmt->try_block());
1390 } 1260 }
1391 try_control_builder.EndTry(); 1261 try_control_builder.EndTry();
1392 1262
1393 // Create a catch scope that binds the exception. 1263 // Create a catch scope that binds the exception.
1394 BuildNewLocalCatchContext(stmt->variable(), stmt->scope()); 1264 BuildNewLocalCatchContext(stmt->variable(), stmt->scope());
1395 builder()->StoreAccumulatorInRegister(context); 1265 builder()->StoreAccumulatorInRegister(context);
1396 1266
1397 // If requested, clear message object as we enter the catch block. 1267 // If requested, clear message object as we enter the catch block.
1398 if (stmt->clear_pending_message()) { 1268 if (stmt->clear_pending_message()) {
1399 builder()->CallRuntime(Runtime::kInterpreterClearPendingMessage, no_reg, 0); 1269 builder()->CallRuntime(Runtime::kInterpreterClearPendingMessage);
1400 } 1270 }
1401 1271
1402 // Load the catch context into the accumulator. 1272 // Load the catch context into the accumulator.
1403 builder()->LoadAccumulatorWithRegister(context); 1273 builder()->LoadAccumulatorWithRegister(context);
1404 1274
1405 // Evaluate the catch-block. 1275 // Evaluate the catch-block.
1406 VisitInScope(stmt->catch_block(), stmt->scope()); 1276 VisitInScope(stmt->catch_block(), stmt->scope());
1407 try_control_builder.EndCatch(); 1277 try_control_builder.EndCatch();
1408 } 1278 }
1409 1279
1410 void BytecodeGenerator::VisitTryFinallyStatement(TryFinallyStatement* stmt) { 1280 void BytecodeGenerator::VisitTryFinallyStatement(TryFinallyStatement* stmt) {
1411 TryFinallyBuilder try_control_builder(builder(), stmt->catch_prediction()); 1281 TryFinallyBuilder try_control_builder(builder(), stmt->catch_prediction());
1412 Register no_reg;
1413 1282
1414 // We keep a record of all paths that enter the finally-block to be able to 1283 // We keep a record of all paths that enter the finally-block to be able to
1415 // dispatch to the correct continuation point after the statements in the 1284 // dispatch to the correct continuation point after the statements in the
1416 // finally-block have been evaluated. 1285 // finally-block have been evaluated.
1417 // 1286 //
1418 // The try-finally construct can enter the finally-block in three ways: 1287 // The try-finally construct can enter the finally-block in three ways:
1419 // 1. By exiting the try-block normally, falling through at the end. 1288 // 1. By exiting the try-block normally, falling through at the end.
1420 // 2. By exiting the try-block with a function-local control flow transfer 1289 // 2. By exiting the try-block with a function-local control flow transfer
1421 // (i.e. through break/continue/return statements). 1290 // (i.e. through break/continue/return statements).
1422 // 3. By exiting the try-block with a thrown exception. 1291 // 3. By exiting the try-block with a thrown exception.
(...skipping 27 matching lines...) Expand all
1450 try_control_builder.LeaveTry(); 1319 try_control_builder.LeaveTry();
1451 try_control_builder.BeginHandler(); 1320 try_control_builder.BeginHandler();
1452 commands.RecordHandlerReThrowPath(); 1321 commands.RecordHandlerReThrowPath();
1453 1322
1454 // Pending message object is saved on entry. 1323 // Pending message object is saved on entry.
1455 try_control_builder.BeginFinally(); 1324 try_control_builder.BeginFinally();
1456 Register message = context; // Reuse register. 1325 Register message = context; // Reuse register.
1457 1326
1458 // Clear message object as we enter the finally block. 1327 // Clear message object as we enter the finally block.
1459 builder() 1328 builder()
1460 ->CallRuntime(Runtime::kInterpreterClearPendingMessage, no_reg, 0) 1329 ->CallRuntime(Runtime::kInterpreterClearPendingMessage)
1461 .StoreAccumulatorInRegister(message); 1330 .StoreAccumulatorInRegister(message);
1462 1331
1463 // Evaluate the finally-block. 1332 // Evaluate the finally-block.
1464 Visit(stmt->finally_block()); 1333 Visit(stmt->finally_block());
1465 try_control_builder.EndFinally(); 1334 try_control_builder.EndFinally();
1466 1335
1467 // Pending message object is restored on exit. 1336 // Pending message object is restored on exit.
1468 builder()->CallRuntime(Runtime::kInterpreterSetPendingMessage, message, 1); 1337 builder()->CallRuntime(Runtime::kInterpreterSetPendingMessage, message);
1469 1338
1470 // Dynamic dispatch after the finally-block. 1339 // Dynamic dispatch after the finally-block.
1471 commands.ApplyDeferredCommands(); 1340 commands.ApplyDeferredCommands();
1472 } 1341 }
1473 1342
1474 void BytecodeGenerator::VisitDebuggerStatement(DebuggerStatement* stmt) { 1343 void BytecodeGenerator::VisitDebuggerStatement(DebuggerStatement* stmt) {
1475 builder()->SetStatementPosition(stmt); 1344 builder()->SetStatementPosition(stmt);
1476 builder()->Debugger(); 1345 builder()->Debugger();
1477 } 1346 }
1478 1347
1479 void BytecodeGenerator::VisitFunctionLiteral(FunctionLiteral* expr) { 1348 void BytecodeGenerator::VisitFunctionLiteral(FunctionLiteral* expr) {
1480 uint8_t flags = CreateClosureFlags::Encode(expr->pretenure(), 1349 uint8_t flags = CreateClosureFlags::Encode(expr->pretenure(),
1481 scope()->is_function_scope()); 1350 scope()->is_function_scope());
1482 size_t entry = builder()->AllocateConstantPoolEntry(); 1351 size_t entry = builder()->AllocateConstantPoolEntry();
1483 builder()->CreateClosure(entry, flags); 1352 builder()->CreateClosure(entry, flags);
1484 function_literals_.push_back(std::make_pair(expr, entry)); 1353 function_literals_.push_back(std::make_pair(expr, entry));
1485 execution_result()->SetResultInAccumulator();
1486 } 1354 }
1487 1355
1488 void BytecodeGenerator::VisitClassLiteral(ClassLiteral* expr) { 1356 void BytecodeGenerator::VisitClassLiteral(ClassLiteral* expr) {
1489 VisitClassLiteralForRuntimeDefinition(expr); 1357 VisitClassLiteralForRuntimeDefinition(expr);
1490 1358
1491 // Load the "prototype" from the constructor. 1359 // Load the "prototype" from the constructor.
1492 register_allocator()->PrepareForConsecutiveAllocations(2); 1360 RegisterList args = register_allocator()->NewRegisterList(2);
1493 Register literal = register_allocator()->NextConsecutiveRegister(); 1361 Register literal = args[0];
1494 Register prototype = register_allocator()->NextConsecutiveRegister(); 1362 Register prototype = args[1];
1495 FeedbackVectorSlot slot = expr->PrototypeSlot(); 1363 FeedbackVectorSlot slot = expr->PrototypeSlot();
1496 builder() 1364 builder()
1497 ->StoreAccumulatorInRegister(literal) 1365 ->StoreAccumulatorInRegister(literal)
1498 .LoadNamedProperty(literal, prototype_string(), feedback_index(slot)) 1366 .LoadNamedProperty(literal, prototype_string(), feedback_index(slot))
1499 .StoreAccumulatorInRegister(prototype); 1367 .StoreAccumulatorInRegister(prototype);
1500 1368
1501 VisitClassLiteralProperties(expr, literal, prototype); 1369 VisitClassLiteralProperties(expr, literal, prototype);
1502 builder()->CallRuntime(Runtime::kToFastProperties, literal, 1); 1370 builder()->CallRuntime(Runtime::kToFastProperties, literal);
1503 // Assign to class variable. 1371 // Assign to class variable.
1504 if (expr->class_variable_proxy() != nullptr) { 1372 if (expr->class_variable_proxy() != nullptr) {
1505 Variable* var = expr->class_variable_proxy()->var(); 1373 Variable* var = expr->class_variable_proxy()->var();
1506 FeedbackVectorSlot slot = expr->NeedsProxySlot() 1374 FeedbackVectorSlot slot = expr->NeedsProxySlot()
1507 ? expr->ProxySlot() 1375 ? expr->ProxySlot()
1508 : FeedbackVectorSlot::Invalid(); 1376 : FeedbackVectorSlot::Invalid();
1509 VisitVariableAssignment(var, Token::INIT, slot); 1377 VisitVariableAssignment(var, Token::INIT, slot);
1510 } 1378 }
1511 execution_result()->SetResultInAccumulator();
1512 } 1379 }
1513 1380
1514 void BytecodeGenerator::VisitClassLiteralForRuntimeDefinition( 1381 void BytecodeGenerator::VisitClassLiteralForRuntimeDefinition(
1515 ClassLiteral* expr) { 1382 ClassLiteral* expr) {
1516 AccumulatorResultScope result_scope(this); 1383 RegisterAllocationScope register_scope(this);
1517 register_allocator()->PrepareForConsecutiveAllocations(4); 1384 RegisterList args = register_allocator()->NewRegisterList(4);
1518 Register extends = register_allocator()->NextConsecutiveRegister();
1519 Register constructor = register_allocator()->NextConsecutiveRegister();
1520 Register start_position = register_allocator()->NextConsecutiveRegister();
1521 Register end_position = register_allocator()->NextConsecutiveRegister();
1522
1523 VisitForAccumulatorValueOrTheHole(expr->extends()); 1385 VisitForAccumulatorValueOrTheHole(expr->extends());
1524 builder()->StoreAccumulatorInRegister(extends); 1386 builder()->StoreAccumulatorInRegister(args[0]);
1525 1387 VisitForRegisterValue(expr->constructor(), args[1]);
1526 VisitForAccumulatorValue(expr->constructor());
1527 builder() 1388 builder()
1528 ->StoreAccumulatorInRegister(constructor) 1389 ->LoadLiteral(Smi::FromInt(expr->start_position()))
1529 .LoadLiteral(Smi::FromInt(expr->start_position())) 1390 .StoreAccumulatorInRegister(args[2])
1530 .StoreAccumulatorInRegister(start_position)
1531 .LoadLiteral(Smi::FromInt(expr->end_position())) 1391 .LoadLiteral(Smi::FromInt(expr->end_position()))
1532 .StoreAccumulatorInRegister(end_position) 1392 .StoreAccumulatorInRegister(args[3])
1533 .CallRuntime(Runtime::kDefineClass, extends, 4); 1393 .CallRuntime(Runtime::kDefineClass, args);
1534 result_scope.SetResultInAccumulator();
1535 } 1394 }
1536 1395
1537 void BytecodeGenerator::VisitClassLiteralProperties(ClassLiteral* expr, 1396 void BytecodeGenerator::VisitClassLiteralProperties(ClassLiteral* expr,
1538 Register literal, 1397 Register literal,
1539 Register prototype) { 1398 Register prototype) {
1540 RegisterAllocationScope register_scope(this); 1399 RegisterAllocationScope register_scope(this);
1541 register_allocator()->PrepareForConsecutiveAllocations(5); 1400 RegisterList args = register_allocator()->NewRegisterList(5);
1542 Register receiver = register_allocator()->NextConsecutiveRegister(); 1401 Register receiver = args[0], key = args[1], value = args[2], attr = args[3],
1543 Register key = register_allocator()->NextConsecutiveRegister(); 1402 set_function_name = args[4];
1544 Register value = register_allocator()->NextConsecutiveRegister();
1545 Register attr = register_allocator()->NextConsecutiveRegister();
1546 Register set_function_name = register_allocator()->NextConsecutiveRegister();
1547 1403
1548 bool attr_assigned = false; 1404 bool attr_assigned = false;
1549 Register old_receiver = Register::invalid_value(); 1405 Register old_receiver = Register::invalid_value();
1550 1406
1551 // Create nodes to store method values into the literal. 1407 // Create nodes to store method values into the literal.
1552 for (int i = 0; i < expr->properties()->length(); i++) { 1408 for (int i = 0; i < expr->properties()->length(); i++) {
1553 ClassLiteral::Property* property = expr->properties()->at(i); 1409 ClassLiteral::Property* property = expr->properties()->at(i);
1554 1410
1555 // Set-up receiver. 1411 // Set-up receiver.
1556 Register new_receiver = property->is_static() ? literal : prototype; 1412 Register new_receiver = property->is_static() ? literal : prototype;
1557 if (new_receiver != old_receiver) { 1413 if (new_receiver != old_receiver) {
1558 builder()->MoveRegister(new_receiver, receiver); 1414 builder()->MoveRegister(new_receiver, receiver);
1559 old_receiver = new_receiver; 1415 old_receiver = new_receiver;
1560 } 1416 }
1561 1417
1562 VisitForAccumulatorValue(property->key()); 1418 VisitForAccumulatorValue(property->key());
1563 builder()->ConvertAccumulatorToName(key); 1419 builder()->ConvertAccumulatorToName(key);
1564 // The static prototype property is read only. We handle the non computed 1420
1565 // property name case in the parser. Since this is the only case where we
1566 // need to check for an own read only property we special case this so we do
1567 // not need to do this for every property.
1568 if (property->is_static() && property->is_computed_name()) { 1421 if (property->is_static() && property->is_computed_name()) {
1569 VisitClassLiteralStaticPrototypeWithComputedName(key); 1422 // The static prototype property is read only. We handle the non computed
1423 // property name case in the parser. Since this is the only case where we
1424 // need to check for an own read only property we special case this so we
1425 // do not need to do this for every property.
1426 BytecodeLabel done;
1427 builder()
1428 ->LoadLiteral(prototype_string())
1429 .CompareOperation(Token::Value::EQ_STRICT, key)
1430 .JumpIfFalse(&done)
1431 .CallRuntime(Runtime::kThrowStaticPrototypeError)
1432 .Bind(&done);
1570 } 1433 }
1571 VisitForAccumulatorValue(property->value());
1572 builder()->StoreAccumulatorInRegister(value);
1573 1434
1435 VisitForRegisterValue(property->value(), value);
1574 VisitSetHomeObject(value, receiver, property); 1436 VisitSetHomeObject(value, receiver, property);
1575 1437
1576 if (!attr_assigned) { 1438 if (!attr_assigned) {
1577 builder() 1439 builder()
1578 ->LoadLiteral(Smi::FromInt(DONT_ENUM)) 1440 ->LoadLiteral(Smi::FromInt(DONT_ENUM))
1579 .StoreAccumulatorInRegister(attr); 1441 .StoreAccumulatorInRegister(attr);
1580 attr_assigned = true; 1442 attr_assigned = true;
1581 } 1443 }
1582 1444
1583 switch (property->kind()) { 1445 switch (property->kind()) {
1584 case ClassLiteral::Property::METHOD: { 1446 case ClassLiteral::Property::METHOD: {
1585 builder() 1447 builder()
1586 ->LoadLiteral(Smi::FromInt(property->NeedsSetFunctionName())) 1448 ->LoadLiteral(Smi::FromInt(property->NeedsSetFunctionName()))
1587 .StoreAccumulatorInRegister(set_function_name); 1449 .StoreAccumulatorInRegister(set_function_name)
1588 builder()->CallRuntime(Runtime::kDefineDataPropertyInLiteral, receiver, 1450 .CallRuntime(Runtime::kDefineDataPropertyInLiteral, args);
1589 5);
1590 break; 1451 break;
1591 } 1452 }
1592 case ClassLiteral::Property::GETTER: { 1453 case ClassLiteral::Property::GETTER: {
1593 builder()->CallRuntime(Runtime::kDefineGetterPropertyUnchecked, 1454 builder()->CallRuntime(Runtime::kDefineGetterPropertyUnchecked,
1594 receiver, 4); 1455 args.Truncate(4));
1595 break; 1456 break;
1596 } 1457 }
1597 case ClassLiteral::Property::SETTER: { 1458 case ClassLiteral::Property::SETTER: {
1598 builder()->CallRuntime(Runtime::kDefineSetterPropertyUnchecked, 1459 builder()->CallRuntime(Runtime::kDefineSetterPropertyUnchecked,
1599 receiver, 4); 1460 args.Truncate(4));
1600 break; 1461 break;
1601 } 1462 }
1602 case ClassLiteral::Property::FIELD: { 1463 case ClassLiteral::Property::FIELD: {
1603 UNREACHABLE(); 1464 UNREACHABLE();
1604 break; 1465 break;
1605 } 1466 }
1606 } 1467 }
1607 } 1468 }
1608 } 1469 }
1609 1470
1610 void BytecodeGenerator::VisitClassLiteralStaticPrototypeWithComputedName(
1611 Register key) {
1612 BytecodeLabel done;
1613 builder()
1614 ->LoadLiteral(prototype_string())
1615 .CompareOperation(Token::Value::EQ_STRICT, key)
1616 .JumpIfFalse(&done)
1617 .CallRuntime(Runtime::kThrowStaticPrototypeError, Register(0), 0)
1618 .Bind(&done);
1619 }
1620
1621 void BytecodeGenerator::VisitNativeFunctionLiteral( 1471 void BytecodeGenerator::VisitNativeFunctionLiteral(
1622 NativeFunctionLiteral* expr) { 1472 NativeFunctionLiteral* expr) {
1623 size_t entry = builder()->AllocateConstantPoolEntry(); 1473 size_t entry = builder()->AllocateConstantPoolEntry();
1624 builder()->CreateClosure(entry, NOT_TENURED); 1474 builder()->CreateClosure(entry, NOT_TENURED);
1625 native_function_literals_.push_back(std::make_pair(expr, entry)); 1475 native_function_literals_.push_back(std::make_pair(expr, entry));
1626 execution_result()->SetResultInAccumulator();
1627 } 1476 }
1628 1477
1629 void BytecodeGenerator::VisitDoExpression(DoExpression* expr) { 1478 void BytecodeGenerator::VisitDoExpression(DoExpression* expr) {
1630 VisitBlock(expr->block()); 1479 VisitBlock(expr->block());
1631 VisitVariableProxy(expr->result()); 1480 VisitVariableProxy(expr->result());
1632 } 1481 }
1633 1482
1634 void BytecodeGenerator::VisitConditional(Conditional* expr) { 1483 void BytecodeGenerator::VisitConditional(Conditional* expr) {
1635 if (expr->condition()->ToBooleanIsTrue()) { 1484 if (expr->condition()->ToBooleanIsTrue()) {
1636 // Generate then block unconditionally as always true. 1485 // Generate then block unconditionally as always true.
1637 VisitForAccumulatorValue(expr->then_expression()); 1486 VisitForAccumulatorValue(expr->then_expression());
1638 } else if (expr->condition()->ToBooleanIsFalse()) { 1487 } else if (expr->condition()->ToBooleanIsFalse()) {
1639 // Generate else block unconditionally if it exists. 1488 // Generate else block unconditionally if it exists.
1640 VisitForAccumulatorValue(expr->else_expression()); 1489 VisitForAccumulatorValue(expr->else_expression());
1641 } else { 1490 } else {
1642 BytecodeLabel end_label; 1491 BytecodeLabel end_label;
1643 BytecodeLabels then_labels(zone()), else_labels(zone()); 1492 BytecodeLabels then_labels(zone()), else_labels(zone());
1644 1493
1645 VisitForTest(expr->condition(), &then_labels, &else_labels, 1494 VisitForTest(expr->condition(), &then_labels, &else_labels,
1646 TestFallthrough::kThen); 1495 TestFallthrough::kThen);
1647 1496
1648 then_labels.Bind(builder()); 1497 then_labels.Bind(builder());
1649 VisitForAccumulatorValue(expr->then_expression()); 1498 VisitForAccumulatorValue(expr->then_expression());
1650 builder()->Jump(&end_label); 1499 builder()->Jump(&end_label);
1651 1500
1652 else_labels.Bind(builder()); 1501 else_labels.Bind(builder());
1653 VisitForAccumulatorValue(expr->else_expression()); 1502 VisitForAccumulatorValue(expr->else_expression());
1654 builder()->Bind(&end_label); 1503 builder()->Bind(&end_label);
1655 } 1504 }
1656
1657 execution_result()->SetResultInAccumulator();
1658 } 1505 }
1659 1506
1660 void BytecodeGenerator::VisitLiteral(Literal* expr) { 1507 void BytecodeGenerator::VisitLiteral(Literal* expr) {
1661 if (!execution_result()->IsEffect()) { 1508 if (!execution_result()->IsEffect()) {
1662 const AstValue* raw_value = expr->raw_value(); 1509 const AstValue* raw_value = expr->raw_value();
1663 if (raw_value->IsSmi()) { 1510 if (raw_value->IsSmi()) {
1664 builder()->LoadLiteral(raw_value->AsSmi()); 1511 builder()->LoadLiteral(raw_value->AsSmi());
1665 } else if (raw_value->IsUndefined()) { 1512 } else if (raw_value->IsUndefined()) {
1666 builder()->LoadUndefined(); 1513 builder()->LoadUndefined();
1667 } else if (raw_value->IsTrue()) { 1514 } else if (raw_value->IsTrue()) {
1668 builder()->LoadTrue(); 1515 builder()->LoadTrue();
1669 } else if (raw_value->IsFalse()) { 1516 } else if (raw_value->IsFalse()) {
1670 builder()->LoadFalse(); 1517 builder()->LoadFalse();
1671 } else if (raw_value->IsNull()) { 1518 } else if (raw_value->IsNull()) {
1672 builder()->LoadNull(); 1519 builder()->LoadNull();
1673 } else if (raw_value->IsTheHole()) { 1520 } else if (raw_value->IsTheHole()) {
1674 builder()->LoadTheHole(); 1521 builder()->LoadTheHole();
1675 } else { 1522 } else {
1676 builder()->LoadLiteral(raw_value->value()); 1523 builder()->LoadLiteral(raw_value->value());
1677 } 1524 }
1678 execution_result()->SetResultInAccumulator();
1679 } 1525 }
1680 } 1526 }
1681 1527
1682 void BytecodeGenerator::VisitRegExpLiteral(RegExpLiteral* expr) { 1528 void BytecodeGenerator::VisitRegExpLiteral(RegExpLiteral* expr) {
1683 // Materialize a regular expression literal. 1529 // Materialize a regular expression literal.
1684 builder()->CreateRegExpLiteral(expr->pattern(), expr->literal_index(), 1530 builder()->CreateRegExpLiteral(expr->pattern(), expr->literal_index(),
1685 expr->flags()); 1531 expr->flags());
1686 execution_result()->SetResultInAccumulator();
1687 } 1532 }
1688 1533
1689 void BytecodeGenerator::VisitObjectLiteral(ObjectLiteral* expr) { 1534 void BytecodeGenerator::VisitObjectLiteral(ObjectLiteral* expr) {
1690 // Copy the literal boilerplate. 1535 // Copy the literal boilerplate.
1691 uint8_t flags = CreateObjectLiteralFlags::Encode( 1536 uint8_t flags = CreateObjectLiteralFlags::Encode(
1692 FastCloneShallowObjectStub::IsSupported(expr), 1537 FastCloneShallowObjectStub::IsSupported(expr),
1693 FastCloneShallowObjectStub::PropertiesCount(expr->properties_count()), 1538 FastCloneShallowObjectStub::PropertiesCount(expr->properties_count()),
1694 expr->ComputeFlags()); 1539 expr->ComputeFlags());
1695 // Allocate in the outer scope since this register is used to return the 1540 // Allocate in the outer scope since this register is used to return the
1696 // expression's results to the caller. 1541 // expression's results to the caller.
1697 Register literal = register_allocator()->outer()->NewRegister(); 1542 Register literal = register_allocator()->NewRegister();
1698 builder()->CreateObjectLiteral(expr->constant_properties(), 1543 builder()->CreateObjectLiteral(expr->constant_properties(),
1699 expr->literal_index(), flags, literal); 1544 expr->literal_index(), flags, literal);
1700 1545
1701 // Store computed values into the literal. 1546 // Store computed values into the literal.
1702 int property_index = 0; 1547 int property_index = 0;
1703 AccessorTable accessor_table(zone()); 1548 AccessorTable accessor_table(zone());
1704 for (; property_index < expr->properties()->length(); property_index++) { 1549 for (; property_index < expr->properties()->length(); property_index++) {
1705 ObjectLiteral::Property* property = expr->properties()->at(property_index); 1550 ObjectLiteral::Property* property = expr->properties()->at(property_index);
1706 if (property->is_computed_name()) break; 1551 if (property->is_computed_name()) break;
1707 if (property->IsCompileTimeValue()) continue; 1552 if (property->IsCompileTimeValue()) continue;
(...skipping 23 matching lines...) Expand all
1731 VisitSetHomeObject(value, literal, property, 1); 1576 VisitSetHomeObject(value, literal, property, 1);
1732 } else { 1577 } else {
1733 builder()->StoreNamedProperty( 1578 builder()->StoreNamedProperty(
1734 literal, key->AsPropertyName(), 1579 literal, key->AsPropertyName(),
1735 feedback_index(property->GetSlot(0)), language_mode()); 1580 feedback_index(property->GetSlot(0)), language_mode());
1736 } 1581 }
1737 } else { 1582 } else {
1738 VisitForEffect(property->value()); 1583 VisitForEffect(property->value());
1739 } 1584 }
1740 } else { 1585 } else {
1741 register_allocator()->PrepareForConsecutiveAllocations(4); 1586 RegisterList args = register_allocator()->NewRegisterList(4);
1742 Register literal_argument =
1743 register_allocator()->NextConsecutiveRegister();
1744 Register key = register_allocator()->NextConsecutiveRegister();
1745 Register value = register_allocator()->NextConsecutiveRegister();
1746 Register language = register_allocator()->NextConsecutiveRegister();
1747 1587
1748 builder()->MoveRegister(literal, literal_argument); 1588 builder()->MoveRegister(literal, args[0]);
1749 VisitForAccumulatorValue(property->key()); 1589 VisitForRegisterValue(property->key(), args[1]);
1750 builder()->StoreAccumulatorInRegister(key); 1590 VisitForRegisterValue(property->value(), args[2]);
1751 VisitForAccumulatorValue(property->value());
1752 builder()->StoreAccumulatorInRegister(value);
1753 if (property->emit_store()) { 1591 if (property->emit_store()) {
1754 builder() 1592 builder()
1755 ->LoadLiteral(Smi::FromInt(SLOPPY)) 1593 ->LoadLiteral(Smi::FromInt(SLOPPY))
1756 .StoreAccumulatorInRegister(language) 1594 .StoreAccumulatorInRegister(args[3])
1757 .CallRuntime(Runtime::kSetProperty, literal_argument, 4); 1595 .CallRuntime(Runtime::kSetProperty, args);
1596 Register value = args[2];
1758 VisitSetHomeObject(value, literal, property); 1597 VisitSetHomeObject(value, literal, property);
1759 } 1598 }
1760 } 1599 }
1761 break; 1600 break;
1762 } 1601 }
1763 case ObjectLiteral::Property::PROTOTYPE: { 1602 case ObjectLiteral::Property::PROTOTYPE: {
1764 DCHECK(property->emit_store()); 1603 DCHECK(property->emit_store());
1765 register_allocator()->PrepareForConsecutiveAllocations(2); 1604 RegisterList args = register_allocator()->NewRegisterList(2);
1766 Register literal_argument = 1605 builder()->MoveRegister(literal, args[0]);
1767 register_allocator()->NextConsecutiveRegister(); 1606 VisitForRegisterValue(property->value(), args[1]);
1768 Register value = register_allocator()->NextConsecutiveRegister(); 1607 builder()->CallRuntime(Runtime::kInternalSetPrototype, args);
1769
1770 builder()->MoveRegister(literal, literal_argument);
1771 VisitForAccumulatorValue(property->value());
1772 builder()->StoreAccumulatorInRegister(value).CallRuntime(
1773 Runtime::kInternalSetPrototype, literal_argument, 2);
1774 break; 1608 break;
1775 } 1609 }
1776 case ObjectLiteral::Property::GETTER: 1610 case ObjectLiteral::Property::GETTER:
1777 if (property->emit_store()) { 1611 if (property->emit_store()) {
1778 accessor_table.lookup(key)->second->getter = property; 1612 accessor_table.lookup(key)->second->getter = property;
1779 } 1613 }
1780 break; 1614 break;
1781 case ObjectLiteral::Property::SETTER: 1615 case ObjectLiteral::Property::SETTER:
1782 if (property->emit_store()) { 1616 if (property->emit_store()) {
1783 accessor_table.lookup(key)->second->setter = property; 1617 accessor_table.lookup(key)->second->setter = property;
1784 } 1618 }
1785 break; 1619 break;
1786 } 1620 }
1787 } 1621 }
1788 1622
1789 // Define accessors, using only a single call to the runtime for each pair of 1623 // Define accessors, using only a single call to the runtime for each pair of
1790 // corresponding getters and setters. 1624 // corresponding getters and setters.
1791 for (AccessorTable::Iterator it = accessor_table.begin(); 1625 for (AccessorTable::Iterator it = accessor_table.begin();
1792 it != accessor_table.end(); ++it) { 1626 it != accessor_table.end(); ++it) {
1793 RegisterAllocationScope inner_register_scope(this); 1627 RegisterAllocationScope inner_register_scope(this);
1794 register_allocator()->PrepareForConsecutiveAllocations(5); 1628 RegisterList args = register_allocator()->NewRegisterList(5);
1795 Register literal_argument = register_allocator()->NextConsecutiveRegister(); 1629 builder()->MoveRegister(literal, args[0]);
1796 Register name = register_allocator()->NextConsecutiveRegister(); 1630 VisitForRegisterValue(it->first, args[1]);
1797 Register getter = register_allocator()->NextConsecutiveRegister(); 1631 VisitObjectLiteralAccessor(literal, it->second->getter, args[2]);
1798 Register setter = register_allocator()->NextConsecutiveRegister(); 1632 VisitObjectLiteralAccessor(literal, it->second->setter, args[3]);
1799 Register attr = register_allocator()->NextConsecutiveRegister();
1800
1801 builder()->MoveRegister(literal, literal_argument);
1802 VisitForAccumulatorValue(it->first);
1803 builder()->StoreAccumulatorInRegister(name);
1804 VisitObjectLiteralAccessor(literal, it->second->getter, getter);
1805 VisitObjectLiteralAccessor(literal, it->second->setter, setter);
1806 builder() 1633 builder()
1807 ->LoadLiteral(Smi::FromInt(NONE)) 1634 ->LoadLiteral(Smi::FromInt(NONE))
1808 .StoreAccumulatorInRegister(attr) 1635 .StoreAccumulatorInRegister(args[4])
1809 .CallRuntime(Runtime::kDefineAccessorPropertyUnchecked, 1636 .CallRuntime(Runtime::kDefineAccessorPropertyUnchecked, args);
1810 literal_argument, 5);
1811 } 1637 }
1812 1638
1813 // Object literals have two parts. The "static" part on the left contains no 1639 // Object literals have two parts. The "static" part on the left contains no
1814 // computed property names, and so we can compute its map ahead of time; see 1640 // computed property names, and so we can compute its map ahead of time; see
1815 // Runtime_CreateObjectLiteralBoilerplate. The second "dynamic" part starts 1641 // Runtime_CreateObjectLiteralBoilerplate. The second "dynamic" part starts
1816 // with the first computed property name and continues with all properties to 1642 // with the first computed property name and continues with all properties to
1817 // its right. All the code from above initializes the static component of the 1643 // its right. All the code from above initializes the static component of the
1818 // object literal, and arranges for the map of the result to reflect the 1644 // object literal, and arranges for the map of the result to reflect the
1819 // static order in which the keys appear. For the dynamic properties, we 1645 // static order in which the keys appear. For the dynamic properties, we
1820 // compile them into a series of "SetOwnProperty" runtime calls. This will 1646 // compile them into a series of "SetOwnProperty" runtime calls. This will
1821 // preserve insertion order. 1647 // preserve insertion order.
1822 for (; property_index < expr->properties()->length(); property_index++) { 1648 for (; property_index < expr->properties()->length(); property_index++) {
1823 ObjectLiteral::Property* property = expr->properties()->at(property_index); 1649 ObjectLiteral::Property* property = expr->properties()->at(property_index);
1824 RegisterAllocationScope inner_register_scope(this); 1650 RegisterAllocationScope inner_register_scope(this);
1825 1651
1826 if (property->kind() == ObjectLiteral::Property::PROTOTYPE) { 1652 if (property->kind() == ObjectLiteral::Property::PROTOTYPE) {
1827 DCHECK(property->emit_store()); 1653 DCHECK(property->emit_store());
1828 register_allocator()->PrepareForConsecutiveAllocations(2); 1654 RegisterList args = register_allocator()->NewRegisterList(2);
1829 Register literal_argument = 1655 builder()->MoveRegister(literal, args[0]);
1830 register_allocator()->NextConsecutiveRegister(); 1656 VisitForRegisterValue(property->value(), args[1]);
1831 Register value = register_allocator()->NextConsecutiveRegister(); 1657 builder()->CallRuntime(Runtime::kInternalSetPrototype, args);
1832
1833 builder()->MoveRegister(literal, literal_argument);
1834 VisitForAccumulatorValue(property->value());
1835 builder()->StoreAccumulatorInRegister(value).CallRuntime(
1836 Runtime::kInternalSetPrototype, literal_argument, 2);
1837 continue; 1658 continue;
1838 } 1659 }
1839 1660
1840 register_allocator()->PrepareForConsecutiveAllocations(5);
1841 Register literal_argument = register_allocator()->NextConsecutiveRegister();
1842 Register key = register_allocator()->NextConsecutiveRegister();
1843 Register value = register_allocator()->NextConsecutiveRegister();
1844 Register attr = register_allocator()->NextConsecutiveRegister();
1845 DCHECK(Register::AreContiguous(literal_argument, key, value, attr));
1846 Register set_function_name =
1847 register_allocator()->NextConsecutiveRegister();
1848
1849 builder()->MoveRegister(literal, literal_argument);
1850 VisitForAccumulatorValue(property->key());
1851 builder()->ConvertAccumulatorToName(key);
1852 VisitForAccumulatorValue(property->value());
1853 builder()->StoreAccumulatorInRegister(value);
1854 VisitSetHomeObject(value, literal, property);
1855 builder()->LoadLiteral(Smi::FromInt(NONE)).StoreAccumulatorInRegister(attr);
1856 switch (property->kind()) { 1661 switch (property->kind()) {
1857 case ObjectLiteral::Property::CONSTANT: 1662 case ObjectLiteral::Property::CONSTANT:
1858 case ObjectLiteral::Property::COMPUTED: 1663 case ObjectLiteral::Property::COMPUTED:
1859 case ObjectLiteral::Property::MATERIALIZED_LITERAL: 1664 case ObjectLiteral::Property::MATERIALIZED_LITERAL: {
1665 RegisterList args = register_allocator()->NewRegisterList(5);
1666 builder()->MoveRegister(literal, args[0]);
1667 VisitForAccumulatorValue(property->key());
1668 builder()->ConvertAccumulatorToName(args[1]);
1669 VisitForRegisterValue(property->value(), args[2]);
1670 VisitSetHomeObject(args[2], literal, property);
1860 builder() 1671 builder()
1861 ->LoadLiteral(Smi::FromInt(property->NeedsSetFunctionName())) 1672 ->LoadLiteral(Smi::FromInt(NONE))
1862 .StoreAccumulatorInRegister(set_function_name); 1673 .StoreAccumulatorInRegister(args[3])
1863 builder()->CallRuntime(Runtime::kDefineDataPropertyInLiteral, 1674 .LoadLiteral(Smi::FromInt(property->NeedsSetFunctionName()))
1864 literal_argument, 5); 1675 .StoreAccumulatorInRegister(args[4]);
1676 builder()->CallRuntime(Runtime::kDefineDataPropertyInLiteral, args);
1865 break; 1677 break;
1678 }
1679 case ObjectLiteral::Property::GETTER:
1680 case ObjectLiteral::Property::SETTER: {
1681 RegisterList args = register_allocator()->NewRegisterList(4);
1682 builder()->MoveRegister(literal, args[0]);
1683 VisitForAccumulatorValue(property->key());
1684 builder()->ConvertAccumulatorToName(args[1]);
1685 VisitForRegisterValue(property->value(), args[2]);
1686 VisitSetHomeObject(args[2], literal, property);
1687 builder()
1688 ->LoadLiteral(Smi::FromInt(NONE))
1689 .StoreAccumulatorInRegister(args[3]);
1690 Runtime::FunctionId function_id =
1691 property->kind() == ObjectLiteral::Property::GETTER
1692 ? Runtime::kDefineGetterPropertyUnchecked
1693 : Runtime::kDefineSetterPropertyUnchecked;
1694 builder()->CallRuntime(function_id, args);
1695 break;
1696 }
1866 case ObjectLiteral::Property::PROTOTYPE: 1697 case ObjectLiteral::Property::PROTOTYPE:
1867 UNREACHABLE(); // Handled specially above. 1698 UNREACHABLE(); // Handled specially above.
1868 break; 1699 break;
1869 case ObjectLiteral::Property::GETTER:
1870 builder()->CallRuntime(Runtime::kDefineGetterPropertyUnchecked,
1871 literal_argument, 4);
1872 break;
1873 case ObjectLiteral::Property::SETTER:
1874 builder()->CallRuntime(Runtime::kDefineSetterPropertyUnchecked,
1875 literal_argument, 4);
1876 break;
1877 } 1700 }
1878 } 1701 }
1879 1702
1880 execution_result()->SetResultInRegister(literal); 1703 builder()->LoadAccumulatorWithRegister(literal);
1881 } 1704 }
1882 1705
1883 void BytecodeGenerator::VisitArrayLiteral(ArrayLiteral* expr) { 1706 void BytecodeGenerator::VisitArrayLiteral(ArrayLiteral* expr) {
1884 // Deep-copy the literal boilerplate. 1707 // Deep-copy the literal boilerplate.
1885 int runtime_flags = expr->ComputeFlags(); 1708 int runtime_flags = expr->ComputeFlags();
1886 bool use_fast_shallow_clone = 1709 bool use_fast_shallow_clone =
1887 (runtime_flags & ArrayLiteral::kShallowElements) != 0 && 1710 (runtime_flags & ArrayLiteral::kShallowElements) != 0 &&
1888 expr->values()->length() <= JSArray::kInitialMaxFastElementArray; 1711 expr->values()->length() <= JSArray::kInitialMaxFastElementArray;
1889 uint8_t flags = 1712 uint8_t flags =
1890 CreateArrayLiteralFlags::Encode(use_fast_shallow_clone, runtime_flags); 1713 CreateArrayLiteralFlags::Encode(use_fast_shallow_clone, runtime_flags);
(...skipping 23 matching lines...) Expand all
1914 .StoreAccumulatorInRegister(index); 1737 .StoreAccumulatorInRegister(index);
1915 VisitForAccumulatorValue(subexpr); 1738 VisitForAccumulatorValue(subexpr);
1916 builder()->StoreKeyedProperty(literal, index, feedback_index(slot), 1739 builder()->StoreKeyedProperty(literal, index, feedback_index(slot),
1917 language_mode()); 1740 language_mode());
1918 } 1741 }
1919 1742
1920 if (!literal_in_accumulator) { 1743 if (!literal_in_accumulator) {
1921 // Restore literal array into accumulator. 1744 // Restore literal array into accumulator.
1922 builder()->LoadAccumulatorWithRegister(literal); 1745 builder()->LoadAccumulatorWithRegister(literal);
1923 } 1746 }
1924 execution_result()->SetResultInAccumulator();
1925 } 1747 }
1926 1748
1927 void BytecodeGenerator::VisitVariableProxy(VariableProxy* proxy) { 1749 void BytecodeGenerator::VisitVariableProxy(VariableProxy* proxy) {
1928 builder()->SetExpressionPosition(proxy); 1750 builder()->SetExpressionPosition(proxy);
1929 VisitVariableLoad(proxy->var(), proxy->VariableFeedbackSlot()); 1751 VisitVariableLoad(proxy->var(), proxy->VariableFeedbackSlot());
1930 } 1752 }
1931 1753
1932 void BytecodeGenerator::BuildHoleCheckForVariableLoad(Variable* variable) { 1754 void BytecodeGenerator::BuildHoleCheckForVariableLoad(Variable* variable) {
1933 if (variable->binding_needs_init()) { 1755 if (variable->binding_needs_init()) {
1934 BuildThrowIfHole(variable->name()); 1756 BuildThrowIfHole(variable->name());
(...skipping 67 matching lines...) Expand 10 before | Expand all | Expand 10 after
2002 } 1824 }
2003 case VariableLocation::MODULE: { 1825 case VariableLocation::MODULE: {
2004 ModuleDescriptor* descriptor = scope()->GetModuleScope()->module(); 1826 ModuleDescriptor* descriptor = scope()->GetModuleScope()->module();
2005 if (variable->IsExport()) { 1827 if (variable->IsExport()) {
2006 auto it = descriptor->regular_exports().find(variable->raw_name()); 1828 auto it = descriptor->regular_exports().find(variable->raw_name());
2007 DCHECK(it != descriptor->regular_exports().end()); 1829 DCHECK(it != descriptor->regular_exports().end());
2008 Register export_name = register_allocator()->NewRegister(); 1830 Register export_name = register_allocator()->NewRegister();
2009 builder() 1831 builder()
2010 ->LoadLiteral(it->second->export_name->string()) 1832 ->LoadLiteral(it->second->export_name->string())
2011 .StoreAccumulatorInRegister(export_name) 1833 .StoreAccumulatorInRegister(export_name)
2012 .CallRuntime(Runtime::kLoadModuleExport, export_name, 1); 1834 .CallRuntime(Runtime::kLoadModuleExport, export_name);
2013 } else { 1835 } else {
2014 auto it = descriptor->regular_imports().find(variable->raw_name()); 1836 auto it = descriptor->regular_imports().find(variable->raw_name());
2015 DCHECK(it != descriptor->regular_imports().end()); 1837 DCHECK(it != descriptor->regular_imports().end());
2016 register_allocator()->PrepareForConsecutiveAllocations(2); 1838 RegisterList args = register_allocator()->NewRegisterList(2);
2017 Register import_name = register_allocator()->NextConsecutiveRegister();
2018 Register module_request =
2019 register_allocator()->NextConsecutiveRegister();
2020 builder() 1839 builder()
2021 ->LoadLiteral(it->second->import_name->string()) 1840 ->LoadLiteral(it->second->import_name->string())
2022 .StoreAccumulatorInRegister(import_name) 1841 .StoreAccumulatorInRegister(args[0])
2023 .LoadLiteral(Smi::FromInt(it->second->module_request)) 1842 .LoadLiteral(Smi::FromInt(it->second->module_request))
2024 .StoreAccumulatorInRegister(module_request) 1843 .StoreAccumulatorInRegister(args[1])
2025 .CallRuntime(Runtime::kLoadModuleImport, import_name, 2); 1844 .CallRuntime(Runtime::kLoadModuleImport, args);
2026 } 1845 }
2027 BuildHoleCheckForVariableLoad(variable); 1846 BuildHoleCheckForVariableLoad(variable);
2028 break; 1847 break;
2029 } 1848 }
2030 } 1849 }
2031 execution_result()->SetResultInAccumulator();
2032 } 1850 }
2033 1851
2034 void BytecodeGenerator::VisitVariableLoadForAccumulatorValue( 1852 void BytecodeGenerator::VisitVariableLoadForAccumulatorValue(
2035 Variable* variable, FeedbackVectorSlot slot, TypeofMode typeof_mode) { 1853 Variable* variable, FeedbackVectorSlot slot, TypeofMode typeof_mode) {
2036 AccumulatorResultScope accumulator_result(this); 1854 ValueResultScope accumulator_result(this);
2037 VisitVariableLoad(variable, slot, typeof_mode); 1855 VisitVariableLoad(variable, slot, typeof_mode);
2038 } 1856 }
2039 1857
2040 Register BytecodeGenerator::VisitVariableLoadForRegisterValue(
2041 Variable* variable, FeedbackVectorSlot slot, TypeofMode typeof_mode) {
2042 RegisterResultScope register_scope(this);
2043 VisitVariableLoad(variable, slot, typeof_mode);
2044 return register_scope.ResultRegister();
2045 }
2046
2047 void BytecodeGenerator::BuildNamedSuperPropertyLoad(Register receiver,
2048 Register home_object,
2049 Register name) {
2050 DCHECK(Register::AreContiguous(receiver, home_object, name));
2051 builder()->CallRuntime(Runtime::kLoadFromSuper, receiver, 3);
2052 }
2053
2054 void BytecodeGenerator::BuildKeyedSuperPropertyLoad(Register receiver,
2055 Register home_object,
2056 Register key) {
2057 DCHECK(Register::AreContiguous(receiver, home_object, key));
2058 builder()->CallRuntime(Runtime::kLoadKeyedFromSuper, receiver, 3);
2059 }
2060
2061 void BytecodeGenerator::BuildNamedSuperPropertyStore(Register receiver,
2062 Register home_object,
2063 Register name,
2064 Register value) {
2065 DCHECK(Register::AreContiguous(receiver, home_object, name, value));
2066 Runtime::FunctionId function_id = is_strict(language_mode())
2067 ? Runtime::kStoreToSuper_Strict
2068 : Runtime::kStoreToSuper_Sloppy;
2069 builder()->CallRuntime(function_id, receiver, 4);
2070 }
2071
2072 void BytecodeGenerator::BuildKeyedSuperPropertyStore(Register receiver,
2073 Register home_object,
2074 Register key,
2075 Register value) {
2076 DCHECK(Register::AreContiguous(receiver, home_object, key, value));
2077 Runtime::FunctionId function_id = is_strict(language_mode())
2078 ? Runtime::kStoreKeyedToSuper_Strict
2079 : Runtime::kStoreKeyedToSuper_Sloppy;
2080 builder()->CallRuntime(function_id, receiver, 4);
2081 }
2082
2083 void BytecodeGenerator::BuildAbort(BailoutReason bailout_reason) { 1858 void BytecodeGenerator::BuildAbort(BailoutReason bailout_reason) {
2084 RegisterAllocationScope register_scope(this); 1859 RegisterAllocationScope register_scope(this);
2085 Register reason = register_allocator()->NewRegister(); 1860 Register reason = register_allocator()->NewRegister();
2086 builder() 1861 builder()
2087 ->LoadLiteral(Smi::FromInt(static_cast<int>(bailout_reason))) 1862 ->LoadLiteral(Smi::FromInt(static_cast<int>(bailout_reason)))
2088 .StoreAccumulatorInRegister(reason) 1863 .StoreAccumulatorInRegister(reason)
2089 .CallRuntime(Runtime::kAbort, reason, 1); 1864 .CallRuntime(Runtime::kAbort, reason);
2090 } 1865 }
2091 1866
2092 void BytecodeGenerator::BuildThrowReferenceError(Handle<String> name) { 1867 void BytecodeGenerator::BuildThrowReferenceError(Handle<String> name) {
2093 RegisterAllocationScope register_scope(this); 1868 RegisterAllocationScope register_scope(this);
2094 Register name_reg = register_allocator()->NewRegister(); 1869 Register name_reg = register_allocator()->NewRegister();
2095 builder()->LoadLiteral(name).StoreAccumulatorInRegister(name_reg).CallRuntime( 1870 builder()->LoadLiteral(name).StoreAccumulatorInRegister(name_reg).CallRuntime(
2096 Runtime::kThrowReferenceError, name_reg, 1); 1871 Runtime::kThrowReferenceError, name_reg);
2097 } 1872 }
2098 1873
2099 void BytecodeGenerator::BuildThrowIfHole(Handle<String> name) { 1874 void BytecodeGenerator::BuildThrowIfHole(Handle<String> name) {
2100 // TODO(interpreter): Can the parser reduce the number of checks 1875 // TODO(interpreter): Can the parser reduce the number of checks
2101 // performed? Or should there be a ThrowIfHole bytecode. 1876 // performed? Or should there be a ThrowIfHole bytecode.
2102 BytecodeLabel no_reference_error; 1877 BytecodeLabel no_reference_error;
2103 builder()->JumpIfNotHole(&no_reference_error); 1878 builder()->JumpIfNotHole(&no_reference_error);
2104 BuildThrowReferenceError(name); 1879 BuildThrowReferenceError(name);
2105 builder()->Bind(&no_reference_error); 1880 builder()->Bind(&no_reference_error);
2106 } 1881 }
(...skipping 52 matching lines...) Expand 10 before | Expand all | Expand 10 after
2159 ->StoreAccumulatorInRegister(value_temp) 1934 ->StoreAccumulatorInRegister(value_temp)
2160 .LoadAccumulatorWithRegister(destination); 1935 .LoadAccumulatorWithRegister(destination);
2161 1936
2162 BuildHoleCheckForVariableAssignment(variable, op); 1937 BuildHoleCheckForVariableAssignment(variable, op);
2163 builder()->LoadAccumulatorWithRegister(value_temp); 1938 builder()->LoadAccumulatorWithRegister(value_temp);
2164 } 1939 }
2165 1940
2166 if (mode != CONST || op == Token::INIT) { 1941 if (mode != CONST || op == Token::INIT) {
2167 builder()->StoreAccumulatorInRegister(destination); 1942 builder()->StoreAccumulatorInRegister(destination);
2168 } else if (variable->throw_on_const_assignment(language_mode())) { 1943 } else if (variable->throw_on_const_assignment(language_mode())) {
2169 builder()->CallRuntime(Runtime::kThrowConstAssignError, Register(), 0); 1944 builder()->CallRuntime(Runtime::kThrowConstAssignError);
2170 } 1945 }
2171 break; 1946 break;
2172 } 1947 }
2173 case VariableLocation::UNALLOCATED: { 1948 case VariableLocation::UNALLOCATED: {
2174 builder()->StoreGlobal(variable->name(), feedback_index(slot), 1949 builder()->StoreGlobal(variable->name(), feedback_index(slot),
2175 language_mode()); 1950 language_mode());
2176 break; 1951 break;
2177 } 1952 }
2178 case VariableLocation::CONTEXT: { 1953 case VariableLocation::CONTEXT: {
2179 int depth = execution_context()->ContextChainDepth(variable->scope()); 1954 int depth = execution_context()->ContextChainDepth(variable->scope());
(...skipping 14 matching lines...) Expand all
2194 ->StoreAccumulatorInRegister(value_temp) 1969 ->StoreAccumulatorInRegister(value_temp)
2195 .LoadContextSlot(context_reg, variable->index(), depth); 1970 .LoadContextSlot(context_reg, variable->index(), depth);
2196 1971
2197 BuildHoleCheckForVariableAssignment(variable, op); 1972 BuildHoleCheckForVariableAssignment(variable, op);
2198 builder()->LoadAccumulatorWithRegister(value_temp); 1973 builder()->LoadAccumulatorWithRegister(value_temp);
2199 } 1974 }
2200 1975
2201 if (mode != CONST || op == Token::INIT) { 1976 if (mode != CONST || op == Token::INIT) {
2202 builder()->StoreContextSlot(context_reg, variable->index(), depth); 1977 builder()->StoreContextSlot(context_reg, variable->index(), depth);
2203 } else if (variable->throw_on_const_assignment(language_mode())) { 1978 } else if (variable->throw_on_const_assignment(language_mode())) {
2204 builder()->CallRuntime(Runtime::kThrowConstAssignError, Register(), 0); 1979 builder()->CallRuntime(Runtime::kThrowConstAssignError);
2205 } 1980 }
2206 break; 1981 break;
2207 } 1982 }
2208 case VariableLocation::LOOKUP: { 1983 case VariableLocation::LOOKUP: {
2209 builder()->StoreLookupSlot(variable->name(), language_mode()); 1984 builder()->StoreLookupSlot(variable->name(), language_mode());
2210 break; 1985 break;
2211 } 1986 }
2212 case VariableLocation::MODULE: { 1987 case VariableLocation::MODULE: {
2213 DCHECK(IsDeclaredVariableMode(mode)); 1988 DCHECK(IsDeclaredVariableMode(mode));
2214 1989
2215 if (mode == CONST && op != Token::INIT) { 1990 if (mode == CONST && op != Token::INIT) {
2216 builder()->CallRuntime(Runtime::kThrowConstAssignError, Register(), 0); 1991 builder()->CallRuntime(Runtime::kThrowConstAssignError);
2217 break; 1992 break;
2218 } 1993 }
2219 1994
2220 // If we don't throw above, we know that we're dealing with an 1995 // If we don't throw above, we know that we're dealing with an
2221 // export because imports are const and we do not generate initializing 1996 // export because imports are const and we do not generate initializing
2222 // assignments for them. 1997 // assignments for them.
2223 DCHECK(variable->IsExport()); 1998 DCHECK(variable->IsExport());
2224 1999
2225 ModuleDescriptor* mod = scope()->GetModuleScope()->module(); 2000 ModuleDescriptor* mod = scope()->GetModuleScope()->module();
2226 // There may be several export names for this local name, but it doesn't 2001 // There may be several export names for this local name, but it doesn't
2227 // matter which one we pick, as they all map to the same cell. 2002 // matter which one we pick, as they all map to the same cell.
2228 auto it = mod->regular_exports().find(variable->raw_name()); 2003 auto it = mod->regular_exports().find(variable->raw_name());
2229 DCHECK(it != mod->regular_exports().end()); 2004 DCHECK(it != mod->regular_exports().end());
2230 2005
2231 register_allocator()->PrepareForConsecutiveAllocations(2); 2006 RegisterList args = register_allocator()->NewRegisterList(2);
2232 Register export_name = register_allocator()->NextConsecutiveRegister();
2233 Register value = register_allocator()->NextConsecutiveRegister();
2234 builder() 2007 builder()
2235 ->StoreAccumulatorInRegister(value) 2008 ->StoreAccumulatorInRegister(args[1])
2236 .LoadLiteral(it->second->export_name->string()) 2009 .LoadLiteral(it->second->export_name->string())
2237 .StoreAccumulatorInRegister(export_name) 2010 .StoreAccumulatorInRegister(args[0])
2238 .CallRuntime(Runtime::kStoreModuleExport, export_name, 2); 2011 .CallRuntime(Runtime::kStoreModuleExport, args);
2239 break; 2012 break;
2240 } 2013 }
2241 } 2014 }
2242 } 2015 }
2243 2016
2244 void BytecodeGenerator::VisitAssignment(Assignment* expr) { 2017 void BytecodeGenerator::VisitAssignment(Assignment* expr) {
2245 DCHECK(expr->target()->IsValidReferenceExpressionOrThis()); 2018 DCHECK(expr->target()->IsValidReferenceExpressionOrThis());
2246 Register object, key, home_object, value; 2019 Register object, key;
2020 RegisterList super_property_args;
2247 Handle<String> name; 2021 Handle<String> name;
2248 2022
2249 // Left-hand side can only be a property, a global or a variable slot. 2023 // Left-hand side can only be a property, a global or a variable slot.
2250 Property* property = expr->target()->AsProperty(); 2024 Property* property = expr->target()->AsProperty();
2251 LhsKind assign_type = Property::GetAssignType(property); 2025 LhsKind assign_type = Property::GetAssignType(property);
2252 2026
2253 // Evaluate LHS expression. 2027 // Evaluate LHS expression.
2254 switch (assign_type) { 2028 switch (assign_type) {
2255 case VARIABLE: 2029 case VARIABLE:
2256 // Nothing to do to evaluate variable assignment LHS. 2030 // Nothing to do to evaluate variable assignment LHS.
2257 break; 2031 break;
2258 case NAMED_PROPERTY: { 2032 case NAMED_PROPERTY: {
2259 object = VisitForRegisterValue(property->obj()); 2033 object = VisitForRegisterValue(property->obj());
2260 name = property->key()->AsLiteral()->AsPropertyName(); 2034 name = property->key()->AsLiteral()->AsPropertyName();
2261 break; 2035 break;
2262 } 2036 }
2263 case KEYED_PROPERTY: { 2037 case KEYED_PROPERTY: {
2264 object = VisitForRegisterValue(property->obj()); 2038 object = VisitForRegisterValue(property->obj());
2265 if (expr->is_compound()) { 2039 key = VisitForRegisterValue(property->key());
2266 // Use VisitForAccumulator and store to register so that the key is
2267 // still in the accumulator for loading the old value below.
2268 key = register_allocator()->NewRegister();
2269 VisitForAccumulatorValue(property->key());
2270 builder()->StoreAccumulatorInRegister(key);
2271 } else {
2272 key = VisitForRegisterValue(property->key());
2273 }
2274 break; 2040 break;
2275 } 2041 }
2276 case NAMED_SUPER_PROPERTY: { 2042 case NAMED_SUPER_PROPERTY: {
2277 register_allocator()->PrepareForConsecutiveAllocations(4); 2043 super_property_args = register_allocator()->NewRegisterList(4);
2278 object = register_allocator()->NextConsecutiveRegister();
2279 home_object = register_allocator()->NextConsecutiveRegister();
2280 key = register_allocator()->NextConsecutiveRegister();
2281 value = register_allocator()->NextConsecutiveRegister();
2282 SuperPropertyReference* super_property = 2044 SuperPropertyReference* super_property =
2283 property->obj()->AsSuperPropertyReference(); 2045 property->obj()->AsSuperPropertyReference();
2284 VisitForRegisterValue(super_property->this_var(), object); 2046 VisitForRegisterValue(super_property->this_var(), super_property_args[0]);
2285 VisitForRegisterValue(super_property->home_object(), home_object); 2047 VisitForRegisterValue(super_property->home_object(),
2048 super_property_args[1]);
2286 builder() 2049 builder()
2287 ->LoadLiteral(property->key()->AsLiteral()->AsPropertyName()) 2050 ->LoadLiteral(property->key()->AsLiteral()->AsPropertyName())
2288 .StoreAccumulatorInRegister(key); 2051 .StoreAccumulatorInRegister(super_property_args[2]);
2289 break; 2052 break;
2290 } 2053 }
2291 case KEYED_SUPER_PROPERTY: { 2054 case KEYED_SUPER_PROPERTY: {
2292 register_allocator()->PrepareForConsecutiveAllocations(4); 2055 super_property_args = register_allocator()->NewRegisterList(4);
2293 object = register_allocator()->NextConsecutiveRegister();
2294 home_object = register_allocator()->NextConsecutiveRegister();
2295 key = register_allocator()->NextConsecutiveRegister();
2296 value = register_allocator()->NextConsecutiveRegister();
2297 builder()->StoreAccumulatorInRegister(value);
2298 SuperPropertyReference* super_property = 2056 SuperPropertyReference* super_property =
2299 property->obj()->AsSuperPropertyReference(); 2057 property->obj()->AsSuperPropertyReference();
2300 VisitForRegisterValue(super_property->this_var(), object); 2058 VisitForRegisterValue(super_property->this_var(), super_property_args[0]);
2301 VisitForRegisterValue(super_property->home_object(), home_object); 2059 VisitForRegisterValue(super_property->home_object(),
2302 VisitForRegisterValue(property->key(), key); 2060 super_property_args[1]);
2061 VisitForRegisterValue(property->key(), super_property_args[2]);
2303 break; 2062 break;
2304 } 2063 }
2305 } 2064 }
2306 2065
2307 // Evaluate the value and potentially handle compound assignments by loading 2066 // Evaluate the value and potentially handle compound assignments by loading
2308 // the left-hand side value and performing a binary operation. 2067 // the left-hand side value and performing a binary operation.
2309 if (expr->is_compound()) { 2068 if (expr->is_compound()) {
2310 Register old_value; 2069 Register old_value = register_allocator()->NewRegister();
2311 switch (assign_type) { 2070 switch (assign_type) {
2312 case VARIABLE: { 2071 case VARIABLE: {
2313 VariableProxy* proxy = expr->target()->AsVariableProxy(); 2072 VariableProxy* proxy = expr->target()->AsVariableProxy();
2314 old_value = VisitVariableLoadForRegisterValue( 2073 VisitVariableLoad(proxy->var(), proxy->VariableFeedbackSlot());
2315 proxy->var(), proxy->VariableFeedbackSlot()); 2074 builder()->StoreAccumulatorInRegister(old_value);
2316 break; 2075 break;
2317 } 2076 }
2318 case NAMED_PROPERTY: { 2077 case NAMED_PROPERTY: {
2319 FeedbackVectorSlot slot = property->PropertyFeedbackSlot(); 2078 FeedbackVectorSlot slot = property->PropertyFeedbackSlot();
2320 old_value = register_allocator()->NewRegister();
2321 builder() 2079 builder()
2322 ->LoadNamedProperty(object, name, feedback_index(slot)) 2080 ->LoadNamedProperty(object, name, feedback_index(slot))
2323 .StoreAccumulatorInRegister(old_value); 2081 .StoreAccumulatorInRegister(old_value);
2324 break; 2082 break;
2325 } 2083 }
2326 case KEYED_PROPERTY: { 2084 case KEYED_PROPERTY: {
2327 // Key is already in accumulator at this point due to evaluating the 2085 // Key is already in accumulator at this point due to evaluating the
2328 // LHS above. 2086 // LHS above.
2329 FeedbackVectorSlot slot = property->PropertyFeedbackSlot(); 2087 FeedbackVectorSlot slot = property->PropertyFeedbackSlot();
2330 old_value = register_allocator()->NewRegister();
2331 builder() 2088 builder()
2332 ->LoadKeyedProperty(object, feedback_index(slot)) 2089 ->LoadKeyedProperty(object, feedback_index(slot))
2333 .StoreAccumulatorInRegister(old_value); 2090 .StoreAccumulatorInRegister(old_value);
2334 break; 2091 break;
2335 } 2092 }
2336 case NAMED_SUPER_PROPERTY: { 2093 case NAMED_SUPER_PROPERTY: {
2337 old_value = register_allocator()->NewRegister(); 2094 builder()
2338 BuildNamedSuperPropertyLoad(object, home_object, key); 2095 ->CallRuntime(Runtime::kLoadFromSuper,
2339 builder()->StoreAccumulatorInRegister(old_value); 2096 super_property_args.Truncate(3))
2097 .StoreAccumulatorInRegister(old_value);
2340 break; 2098 break;
2341 } 2099 }
2342 case KEYED_SUPER_PROPERTY: { 2100 case KEYED_SUPER_PROPERTY: {
2343 old_value = register_allocator()->NewRegister(); 2101 builder()
2344 BuildKeyedSuperPropertyLoad(object, home_object, key); 2102 ->CallRuntime(Runtime::kLoadKeyedFromSuper,
2345 builder()->StoreAccumulatorInRegister(old_value); 2103 super_property_args.Truncate(3))
2104 .StoreAccumulatorInRegister(old_value);
2346 break; 2105 break;
2347 } 2106 }
2348 } 2107 }
2349 VisitForAccumulatorValue(expr->value()); 2108 VisitForAccumulatorValue(expr->value());
2350 FeedbackVectorSlot slot = 2109 FeedbackVectorSlot slot =
2351 expr->binary_operation()->BinaryOperationFeedbackSlot(); 2110 expr->binary_operation()->BinaryOperationFeedbackSlot();
2352 builder()->BinaryOperation(expr->binary_op(), old_value, 2111 builder()->BinaryOperation(expr->binary_op(), old_value,
2353 feedback_index(slot)); 2112 feedback_index(slot));
2354 } else { 2113 } else {
2355 VisitForAccumulatorValue(expr->value()); 2114 VisitForAccumulatorValue(expr->value());
(...skipping 12 matching lines...) Expand all
2368 } 2127 }
2369 case NAMED_PROPERTY: 2128 case NAMED_PROPERTY:
2370 builder()->StoreNamedProperty(object, name, feedback_index(slot), 2129 builder()->StoreNamedProperty(object, name, feedback_index(slot),
2371 language_mode()); 2130 language_mode());
2372 break; 2131 break;
2373 case KEYED_PROPERTY: 2132 case KEYED_PROPERTY:
2374 builder()->StoreKeyedProperty(object, key, feedback_index(slot), 2133 builder()->StoreKeyedProperty(object, key, feedback_index(slot),
2375 language_mode()); 2134 language_mode());
2376 break; 2135 break;
2377 case NAMED_SUPER_PROPERTY: { 2136 case NAMED_SUPER_PROPERTY: {
2378 builder()->StoreAccumulatorInRegister(value); 2137 builder()
2379 BuildNamedSuperPropertyStore(object, home_object, key, value); 2138 ->StoreAccumulatorInRegister(super_property_args[3])
2139 .CallRuntime(StoreToSuperRuntimeId(), super_property_args);
2380 break; 2140 break;
2381 } 2141 }
2382 case KEYED_SUPER_PROPERTY: { 2142 case KEYED_SUPER_PROPERTY: {
2383 builder()->StoreAccumulatorInRegister(value); 2143 builder()
2384 BuildKeyedSuperPropertyStore(object, home_object, key, value); 2144 ->StoreAccumulatorInRegister(super_property_args[3])
2145 .CallRuntime(StoreKeyedToSuperRuntimeId(), super_property_args);
2385 break; 2146 break;
2386 } 2147 }
2387 } 2148 }
2388 execution_result()->SetResultInAccumulator();
2389 } 2149 }
2390 2150
2391 void BytecodeGenerator::VisitYield(Yield* expr) { 2151 void BytecodeGenerator::VisitYield(Yield* expr) {
2392 builder()->SetExpressionPosition(expr); 2152 builder()->SetExpressionPosition(expr);
2393 Register value = VisitForRegisterValue(expr->expression()); 2153 Register value = VisitForRegisterValue(expr->expression());
2394 2154
2395 Register generator = VisitForRegisterValue(expr->generator_object()); 2155 Register generator = VisitForRegisterValue(expr->generator_object());
2396 2156
2397 // Save context, registers, and state. Then return. 2157 // Save context, registers, and state. Then return.
2398 builder() 2158 builder()
2399 ->LoadLiteral(Smi::FromInt(expr->yield_id())) 2159 ->LoadLiteral(Smi::FromInt(expr->yield_id()))
2400 .SuspendGenerator(generator) 2160 .SuspendGenerator(generator)
2401 .LoadAccumulatorWithRegister(value) 2161 .LoadAccumulatorWithRegister(value)
2402 .Return(); // Hard return (ignore any finally blocks). 2162 .Return(); // Hard return (ignore any finally blocks).
2403 2163
2404 builder()->Bind(&(generator_resume_points_[expr->yield_id()])); 2164 builder()->Bind(&(generator_resume_points_[expr->yield_id()]));
2405 // Upon resume, we continue here. 2165 // Upon resume, we continue here.
2406 2166
2407 { 2167 {
2408 RegisterAllocationScope register_scope(this); 2168 RegisterAllocationScope register_scope(this);
2409 2169
2410 // Update state to indicate that we have finished resuming. Loop headers 2170 // Update state to indicate that we have finished resuming. Loop headers
2411 // rely on this. 2171 // rely on this.
2412 builder() 2172 builder()
2413 ->LoadLiteral(Smi::FromInt(JSGeneratorObject::kGeneratorExecuting)) 2173 ->LoadLiteral(Smi::FromInt(JSGeneratorObject::kGeneratorExecuting))
2414 .StoreAccumulatorInRegister(generator_state_); 2174 .StoreAccumulatorInRegister(generator_state_);
2415 2175
2416 Register input = register_allocator()->NewRegister(); 2176 Register input = register_allocator()->NewRegister();
2417 builder() 2177 builder()
2418 ->CallRuntime(Runtime::kInlineGeneratorGetInputOrDebugPos, generator, 1) 2178 ->CallRuntime(Runtime::kInlineGeneratorGetInputOrDebugPos, generator)
2419 .StoreAccumulatorInRegister(input); 2179 .StoreAccumulatorInRegister(input);
2420 2180
2421 Register resume_mode = register_allocator()->NewRegister(); 2181 Register resume_mode = register_allocator()->NewRegister();
2422 builder() 2182 builder()
2423 ->CallRuntime(Runtime::kInlineGeneratorGetResumeMode, generator, 1) 2183 ->CallRuntime(Runtime::kInlineGeneratorGetResumeMode, generator)
2424 .StoreAccumulatorInRegister(resume_mode); 2184 .StoreAccumulatorInRegister(resume_mode);
2425 2185
2426 // Now dispatch on resume mode. 2186 // Now dispatch on resume mode.
2427 2187
2428 BytecodeLabel resume_with_next; 2188 BytecodeLabel resume_with_next;
2429 BytecodeLabel resume_with_return; 2189 BytecodeLabel resume_with_return;
2430 BytecodeLabel resume_with_throw; 2190 BytecodeLabel resume_with_throw;
2431 2191
2432 builder() 2192 builder()
2433 ->LoadLiteral(Smi::FromInt(JSGeneratorObject::kNext)) 2193 ->LoadLiteral(Smi::FromInt(JSGeneratorObject::kNext))
2434 .CompareOperation(Token::EQ_STRICT, resume_mode) 2194 .CompareOperation(Token::EQ_STRICT, resume_mode)
2435 .JumpIfTrue(&resume_with_next) 2195 .JumpIfTrue(&resume_with_next)
2436 .LoadLiteral(Smi::FromInt(JSGeneratorObject::kThrow)) 2196 .LoadLiteral(Smi::FromInt(JSGeneratorObject::kThrow))
2437 .CompareOperation(Token::EQ_STRICT, resume_mode) 2197 .CompareOperation(Token::EQ_STRICT, resume_mode)
2438 .JumpIfTrue(&resume_with_throw) 2198 .JumpIfTrue(&resume_with_throw)
2439 .Jump(&resume_with_return); 2199 .Jump(&resume_with_return);
2440 2200
2441 builder()->Bind(&resume_with_return); 2201 builder()->Bind(&resume_with_return);
2442 { 2202 {
2443 register_allocator()->PrepareForConsecutiveAllocations(2); 2203 RegisterList args = register_allocator()->NewRegisterList(2);
2444 Register value = register_allocator()->NextConsecutiveRegister();
2445 Register done = register_allocator()->NextConsecutiveRegister();
2446 builder() 2204 builder()
2447 ->MoveRegister(input, value) 2205 ->MoveRegister(input, args[0])
2448 .LoadTrue() 2206 .LoadTrue()
2449 .StoreAccumulatorInRegister(done) 2207 .StoreAccumulatorInRegister(args[1])
2450 .CallRuntime(Runtime::kInlineCreateIterResultObject, value, 2); 2208 .CallRuntime(Runtime::kInlineCreateIterResultObject, args);
2451 execution_control()->ReturnAccumulator(); 2209 execution_control()->ReturnAccumulator();
2452 } 2210 }
2453 2211
2454 builder()->Bind(&resume_with_throw); 2212 builder()->Bind(&resume_with_throw);
2455 builder()->SetExpressionPosition(expr); 2213 builder()->SetExpressionPosition(expr);
2456 builder()->LoadAccumulatorWithRegister(input); 2214 builder()->LoadAccumulatorWithRegister(input);
2457 if (expr->rethrow_on_exception()) { 2215 if (expr->rethrow_on_exception()) {
2458 builder()->ReThrow(); 2216 builder()->ReThrow();
2459 } else { 2217 } else {
2460 builder()->Throw(); 2218 builder()->Throw();
2461 } 2219 }
2462 2220
2463 builder()->Bind(&resume_with_next); 2221 builder()->Bind(&resume_with_next);
2464 builder()->LoadAccumulatorWithRegister(input); 2222 builder()->LoadAccumulatorWithRegister(input);
2465 } 2223 }
2466 execution_result()->SetResultInAccumulator();
2467 } 2224 }
2468 2225
2469 void BytecodeGenerator::VisitThrow(Throw* expr) { 2226 void BytecodeGenerator::VisitThrow(Throw* expr) {
2470 VisitForAccumulatorValue(expr->exception()); 2227 VisitForAccumulatorValue(expr->exception());
2471 builder()->SetExpressionPosition(expr); 2228 builder()->SetExpressionPosition(expr);
2472 builder()->Throw(); 2229 builder()->Throw();
2473 // Throw statements are modeled as expressions instead of statements. These
2474 // are converted from assignment statements in Rewriter::ReWrite pass. An
2475 // assignment statement expects a value in the accumulator. This is a hack to
2476 // avoid DCHECK fails assert accumulator has been set.
2477 execution_result()->SetResultInAccumulator();
2478 } 2230 }
2479 2231
2480 void BytecodeGenerator::VisitPropertyLoad(Register obj, Property* expr) { 2232 void BytecodeGenerator::VisitPropertyLoad(Register obj, Property* expr) {
2481 LhsKind property_kind = Property::GetAssignType(expr); 2233 LhsKind property_kind = Property::GetAssignType(expr);
2482 FeedbackVectorSlot slot = expr->PropertyFeedbackSlot(); 2234 FeedbackVectorSlot slot = expr->PropertyFeedbackSlot();
2483 builder()->SetExpressionPosition(expr); 2235 builder()->SetExpressionPosition(expr);
2484 switch (property_kind) { 2236 switch (property_kind) {
2485 case VARIABLE: 2237 case VARIABLE:
2486 UNREACHABLE(); 2238 UNREACHABLE();
2487 case NAMED_PROPERTY: { 2239 case NAMED_PROPERTY: {
2488 builder()->LoadNamedProperty(obj, 2240 builder()->LoadNamedProperty(obj,
2489 expr->key()->AsLiteral()->AsPropertyName(), 2241 expr->key()->AsLiteral()->AsPropertyName(),
2490 feedback_index(slot)); 2242 feedback_index(slot));
2491 break; 2243 break;
2492 } 2244 }
2493 case KEYED_PROPERTY: { 2245 case KEYED_PROPERTY: {
2494 VisitForAccumulatorValue(expr->key()); 2246 VisitForAccumulatorValue(expr->key());
2495 builder()->LoadKeyedProperty(obj, feedback_index(slot)); 2247 builder()->LoadKeyedProperty(obj, feedback_index(slot));
2496 break; 2248 break;
2497 } 2249 }
2498 case NAMED_SUPER_PROPERTY: 2250 case NAMED_SUPER_PROPERTY:
2499 VisitNamedSuperPropertyLoad(expr, Register::invalid_value()); 2251 VisitNamedSuperPropertyLoad(expr, Register::invalid_value());
2500 break; 2252 break;
2501 case KEYED_SUPER_PROPERTY: 2253 case KEYED_SUPER_PROPERTY:
2502 VisitKeyedSuperPropertyLoad(expr, Register::invalid_value()); 2254 VisitKeyedSuperPropertyLoad(expr, Register::invalid_value());
2503 break; 2255 break;
2504 } 2256 }
2505 execution_result()->SetResultInAccumulator();
2506 } 2257 }
2507 2258
2508 void BytecodeGenerator::VisitPropertyLoadForAccumulator(Register obj, 2259 void BytecodeGenerator::VisitPropertyLoadForAccumulator(Register obj,
2509 Property* expr) { 2260 Property* expr) {
2510 AccumulatorResultScope result_scope(this); 2261 ValueResultScope result_scope(this);
2511 VisitPropertyLoad(obj, expr); 2262 VisitPropertyLoad(obj, expr);
2512 } 2263 }
2513 2264
2514 void BytecodeGenerator::VisitNamedSuperPropertyLoad(Property* property, 2265 void BytecodeGenerator::VisitNamedSuperPropertyLoad(Property* property,
2515 Register opt_receiver_out) { 2266 Register opt_receiver_out) {
2516 RegisterAllocationScope register_scope(this); 2267 RegisterAllocationScope register_scope(this);
2517 register_allocator()->PrepareForConsecutiveAllocations(3);
2518
2519 Register receiver, home_object, name;
2520 receiver = register_allocator()->NextConsecutiveRegister();
2521 home_object = register_allocator()->NextConsecutiveRegister();
2522 name = register_allocator()->NextConsecutiveRegister();
2523 SuperPropertyReference* super_property = 2268 SuperPropertyReference* super_property =
2524 property->obj()->AsSuperPropertyReference(); 2269 property->obj()->AsSuperPropertyReference();
2525 VisitForRegisterValue(super_property->this_var(), receiver); 2270 RegisterList args = register_allocator()->NewRegisterList(3);
2526 VisitForRegisterValue(super_property->home_object(), home_object); 2271 VisitForRegisterValue(super_property->this_var(), args[0]);
2272 VisitForRegisterValue(super_property->home_object(), args[1]);
2527 builder() 2273 builder()
2528 ->LoadLiteral(property->key()->AsLiteral()->AsPropertyName()) 2274 ->LoadLiteral(property->key()->AsLiteral()->AsPropertyName())
2529 .StoreAccumulatorInRegister(name); 2275 .StoreAccumulatorInRegister(args[2])
2530 BuildNamedSuperPropertyLoad(receiver, home_object, name); 2276 .CallRuntime(Runtime::kLoadFromSuper, args);
2531 2277
2532 if (opt_receiver_out.is_valid()) { 2278 if (opt_receiver_out.is_valid()) {
2533 builder()->MoveRegister(receiver, opt_receiver_out); 2279 builder()->MoveRegister(args[0], opt_receiver_out);
2534 } 2280 }
2535 } 2281 }
2536 2282
2537 void BytecodeGenerator::VisitKeyedSuperPropertyLoad(Property* property, 2283 void BytecodeGenerator::VisitKeyedSuperPropertyLoad(Property* property,
2538 Register opt_receiver_out) { 2284 Register opt_receiver_out) {
2539 RegisterAllocationScope register_scope(this); 2285 RegisterAllocationScope register_scope(this);
2540 register_allocator()->PrepareForConsecutiveAllocations(3);
2541
2542 Register receiver, home_object, key;
2543 receiver = register_allocator()->NextConsecutiveRegister();
2544 home_object = register_allocator()->NextConsecutiveRegister();
2545 key = register_allocator()->NextConsecutiveRegister();
2546 SuperPropertyReference* super_property = 2286 SuperPropertyReference* super_property =
2547 property->obj()->AsSuperPropertyReference(); 2287 property->obj()->AsSuperPropertyReference();
2548 VisitForRegisterValue(super_property->this_var(), receiver); 2288 RegisterList args = register_allocator()->NewRegisterList(3);
2549 VisitForRegisterValue(super_property->home_object(), home_object); 2289 VisitForRegisterValue(super_property->this_var(), args[0]);
2550 VisitForRegisterValue(property->key(), key); 2290 VisitForRegisterValue(super_property->home_object(), args[1]);
2551 BuildKeyedSuperPropertyLoad(receiver, home_object, key); 2291 VisitForRegisterValue(property->key(), args[2]);
2292 builder()->CallRuntime(Runtime::kLoadKeyedFromSuper, args);
2552 2293
2553 if (opt_receiver_out.is_valid()) { 2294 if (opt_receiver_out.is_valid()) {
2554 builder()->MoveRegister(receiver, opt_receiver_out); 2295 builder()->MoveRegister(args[0], opt_receiver_out);
2555 } 2296 }
2556 } 2297 }
2557 2298
2558 void BytecodeGenerator::VisitProperty(Property* expr) { 2299 void BytecodeGenerator::VisitProperty(Property* expr) {
2559 LhsKind property_kind = Property::GetAssignType(expr); 2300 LhsKind property_kind = Property::GetAssignType(expr);
2560 if (property_kind != NAMED_SUPER_PROPERTY && 2301 if (property_kind != NAMED_SUPER_PROPERTY &&
2561 property_kind != KEYED_SUPER_PROPERTY) { 2302 property_kind != KEYED_SUPER_PROPERTY) {
2562 Register obj = VisitForRegisterValue(expr->obj()); 2303 Register obj = VisitForRegisterValue(expr->obj());
2563 VisitPropertyLoad(obj, expr); 2304 VisitPropertyLoad(obj, expr);
2564 } else { 2305 } else {
2565 VisitPropertyLoad(Register::invalid_value(), expr); 2306 VisitPropertyLoad(Register::invalid_value(), expr);
2566 } 2307 }
2567 } 2308 }
2568 2309
2569 Register BytecodeGenerator::VisitArguments(ZoneList<Expression*>* args) { 2310 void BytecodeGenerator::VisitArguments(ZoneList<Expression*>* args,
2570 if (args->length() == 0) { 2311 RegisterList arg_regs,
2571 return Register(); 2312 size_t first_argument_register) {
2313 // Visit arguments.
2314 for (int i = 0; i < static_cast<int>(args->length()); i++) {
2315 VisitForRegisterValue(args->at(i), arg_regs[first_argument_register + i]);
2572 } 2316 }
2573
2574 // Visit arguments and place in a contiguous block of temporary
2575 // registers. Return the first temporary register corresponding to
2576 // the first argument.
2577 //
2578 // NB the caller may have already called
2579 // PrepareForConsecutiveAllocations() with args->length() + N. The
2580 // second call here will be a no-op provided there have been N or
2581 // less calls to NextConsecutiveRegister(). Otherwise, the arguments
2582 // here will be consecutive, but they will not be consecutive with
2583 // earlier consecutive allocations made by the caller.
2584 register_allocator()->PrepareForConsecutiveAllocations(args->length());
2585
2586 // Visit for first argument that goes into returned register
2587 Register first_arg = register_allocator()->NextConsecutiveRegister();
2588 VisitForAccumulatorValue(args->at(0));
2589 builder()->StoreAccumulatorInRegister(first_arg);
2590
2591 // Visit remaining arguments
2592 for (int i = 1; i < static_cast<int>(args->length()); i++) {
2593 Register ith_arg = register_allocator()->NextConsecutiveRegister();
2594 VisitForAccumulatorValue(args->at(i));
2595 builder()->StoreAccumulatorInRegister(ith_arg);
2596 DCHECK(ith_arg.index() - i == first_arg.index());
2597 }
2598 return first_arg;
2599 } 2317 }
2600 2318
2601 void BytecodeGenerator::VisitCall(Call* expr) { 2319 void BytecodeGenerator::VisitCall(Call* expr) {
2602 Expression* callee_expr = expr->expression(); 2320 Expression* callee_expr = expr->expression();
2603 Call::CallType call_type = expr->GetCallType(); 2321 Call::CallType call_type = expr->GetCallType();
2604 2322
2605 if (call_type == Call::SUPER_CALL) { 2323 if (call_type == Call::SUPER_CALL) {
2606 return VisitCallSuper(expr); 2324 return VisitCallSuper(expr);
2607 } 2325 }
2608 2326
2327 Register callee = register_allocator()->NewRegister();
2328
2329 // Add an argument register for the receiver.
2330 RegisterList args =
2331 register_allocator()->NewRegisterList(expr->arguments()->length() + 1);
2332 Register receiver = args[0];
2333
2609 // Prepare the callee and the receiver to the function call. This depends on 2334 // Prepare the callee and the receiver to the function call. This depends on
2610 // the semantics of the underlying call type. 2335 // the semantics of the underlying call type.
2611
2612 // The receiver and arguments need to be allocated consecutively for
2613 // Call(). We allocate the callee and receiver consecutively for calls to
2614 // %LoadLookupSlotForCall. Future optimizations could avoid this there are
2615 // no arguments or the receiver and arguments are already consecutive.
2616 ZoneList<Expression*>* args = expr->arguments();
2617 register_allocator()->PrepareForConsecutiveAllocations(args->length() + 2);
2618 Register callee = register_allocator()->NextConsecutiveRegister();
2619 Register receiver = register_allocator()->NextConsecutiveRegister();
2620
2621 switch (call_type) { 2336 switch (call_type) {
2622 case Call::NAMED_PROPERTY_CALL: 2337 case Call::NAMED_PROPERTY_CALL:
2623 case Call::KEYED_PROPERTY_CALL: { 2338 case Call::KEYED_PROPERTY_CALL: {
2624 Property* property = callee_expr->AsProperty(); 2339 Property* property = callee_expr->AsProperty();
2625 VisitForAccumulatorValue(property->obj()); 2340 VisitForAccumulatorValue(property->obj());
2626 builder()->StoreAccumulatorInRegister(receiver); 2341 builder()->StoreAccumulatorInRegister(receiver);
2627 VisitPropertyLoadForAccumulator(receiver, property); 2342 VisitPropertyLoadForAccumulator(receiver, property);
2628 builder()->StoreAccumulatorInRegister(callee); 2343 builder()->StoreAccumulatorInRegister(callee);
2629 break; 2344 break;
2630 } 2345 }
(...skipping 12 matching lines...) Expand all
2643 if (callee_expr->AsVariableProxy()->var()->IsLookupSlot()) { 2358 if (callee_expr->AsVariableProxy()->var()->IsLookupSlot()) {
2644 RegisterAllocationScope inner_register_scope(this); 2359 RegisterAllocationScope inner_register_scope(this);
2645 Register name = register_allocator()->NewRegister(); 2360 Register name = register_allocator()->NewRegister();
2646 2361
2647 // Call %LoadLookupSlotForCall to get the callee and receiver. 2362 // Call %LoadLookupSlotForCall to get the callee and receiver.
2648 DCHECK(Register::AreContiguous(callee, receiver)); 2363 DCHECK(Register::AreContiguous(callee, receiver));
2649 Variable* variable = callee_expr->AsVariableProxy()->var(); 2364 Variable* variable = callee_expr->AsVariableProxy()->var();
2650 builder() 2365 builder()
2651 ->LoadLiteral(variable->name()) 2366 ->LoadLiteral(variable->name())
2652 .StoreAccumulatorInRegister(name) 2367 .StoreAccumulatorInRegister(name)
2653 .CallRuntimeForPair(Runtime::kLoadLookupSlotForCall, name, 1, 2368 .CallRuntimeForPair(Runtime::kLoadLookupSlotForCall, name, callee);
2654 callee);
2655 break; 2369 break;
2656 } 2370 }
2657 // Fall through. 2371 // Fall through.
2658 DCHECK_EQ(call_type, Call::POSSIBLY_EVAL_CALL); 2372 DCHECK_EQ(call_type, Call::POSSIBLY_EVAL_CALL);
2659 } 2373 }
2660 case Call::OTHER_CALL: { 2374 case Call::OTHER_CALL: {
2661 builder()->LoadUndefined().StoreAccumulatorInRegister(receiver); 2375 builder()->LoadUndefined().StoreAccumulatorInRegister(receiver);
2662 VisitForAccumulatorValue(callee_expr); 2376 VisitForRegisterValue(callee_expr, callee);
2663 builder()->StoreAccumulatorInRegister(callee);
2664 break; 2377 break;
2665 } 2378 }
2666 case Call::NAMED_SUPER_PROPERTY_CALL: { 2379 case Call::NAMED_SUPER_PROPERTY_CALL: {
2667 Property* property = callee_expr->AsProperty(); 2380 Property* property = callee_expr->AsProperty();
2668 VisitNamedSuperPropertyLoad(property, receiver); 2381 VisitNamedSuperPropertyLoad(property, receiver);
2669 builder()->StoreAccumulatorInRegister(callee); 2382 builder()->StoreAccumulatorInRegister(callee);
2670 break; 2383 break;
2671 } 2384 }
2672 case Call::KEYED_SUPER_PROPERTY_CALL: { 2385 case Call::KEYED_SUPER_PROPERTY_CALL: {
2673 Property* property = callee_expr->AsProperty(); 2386 Property* property = callee_expr->AsProperty();
2674 VisitKeyedSuperPropertyLoad(property, receiver); 2387 VisitKeyedSuperPropertyLoad(property, receiver);
2675 builder()->StoreAccumulatorInRegister(callee); 2388 builder()->StoreAccumulatorInRegister(callee);
2676 break; 2389 break;
2677 } 2390 }
2678 case Call::SUPER_CALL: 2391 case Call::SUPER_CALL:
2679 UNREACHABLE(); 2392 UNREACHABLE();
2680 break; 2393 break;
2681 } 2394 }
2682 2395
2683 // Evaluate all arguments to the function call and store in sequential 2396 // Evaluate all arguments to the function call and store in sequential args
2684 // registers. 2397 // registers.
2685 Register arg = VisitArguments(args); 2398 VisitArguments(expr->arguments(), args, 1);
2686 CHECK(args->length() == 0 || arg.index() == receiver.index() + 1);
2687 2399
2688 // Resolve callee for a potential direct eval call. This block will mutate the 2400 // Resolve callee for a potential direct eval call. This block will mutate the
2689 // callee value. 2401 // callee value.
2690 if (call_type == Call::POSSIBLY_EVAL_CALL && args->length() > 0) { 2402 if (call_type == Call::POSSIBLY_EVAL_CALL &&
2403 expr->arguments()->length() > 0) {
2691 RegisterAllocationScope inner_register_scope(this); 2404 RegisterAllocationScope inner_register_scope(this);
2692 register_allocator()->PrepareForConsecutiveAllocations(6);
2693 Register callee_for_eval = register_allocator()->NextConsecutiveRegister();
2694 Register source = register_allocator()->NextConsecutiveRegister();
2695 Register function = register_allocator()->NextConsecutiveRegister();
2696 Register language = register_allocator()->NextConsecutiveRegister();
2697 Register eval_scope_position =
2698 register_allocator()->NextConsecutiveRegister();
2699 Register eval_position = register_allocator()->NextConsecutiveRegister();
2700
2701 // Set up arguments for ResolvePossiblyDirectEval by copying callee, source 2405 // Set up arguments for ResolvePossiblyDirectEval by copying callee, source
2702 // strings and function closure, and loading language and 2406 // strings and function closure, and loading language and
2703 // position. 2407 // position.
2408 RegisterList runtime_call_args = register_allocator()->NewRegisterList(6);
2704 builder() 2409 builder()
2705 ->MoveRegister(callee, callee_for_eval) 2410 ->MoveRegister(callee, runtime_call_args[0])
2706 .MoveRegister(arg, source) 2411 .MoveRegister(args[1], runtime_call_args[1])
2707 .MoveRegister(Register::function_closure(), function) 2412 .MoveRegister(Register::function_closure(), runtime_call_args[2])
2708 .LoadLiteral(Smi::FromInt(language_mode())) 2413 .LoadLiteral(Smi::FromInt(language_mode()))
2709 .StoreAccumulatorInRegister(language) 2414 .StoreAccumulatorInRegister(runtime_call_args[3])
2710 .LoadLiteral( 2415 .LoadLiteral(
2711 Smi::FromInt(execution_context()->scope()->start_position())) 2416 Smi::FromInt(execution_context()->scope()->start_position()))
2712 .StoreAccumulatorInRegister(eval_scope_position) 2417 .StoreAccumulatorInRegister(runtime_call_args[4])
2713 .LoadLiteral(Smi::FromInt(expr->position())) 2418 .LoadLiteral(Smi::FromInt(expr->position()))
2714 .StoreAccumulatorInRegister(eval_position); 2419 .StoreAccumulatorInRegister(runtime_call_args[5]);
2715 2420
2716 // Call ResolvePossiblyDirectEval and modify the callee. 2421 // Call ResolvePossiblyDirectEval and modify the callee.
2717 builder() 2422 builder()
2718 ->CallRuntime(Runtime::kResolvePossiblyDirectEval, callee_for_eval, 6) 2423 ->CallRuntime(Runtime::kResolvePossiblyDirectEval, runtime_call_args)
2719 .StoreAccumulatorInRegister(callee); 2424 .StoreAccumulatorInRegister(callee);
2720 } 2425 }
2721 2426
2722 builder()->SetExpressionPosition(expr); 2427 builder()->SetExpressionPosition(expr);
2723 2428
2724 int feedback_slot_index; 2429 int feedback_slot_index;
2725 if (expr->CallFeedbackICSlot().IsInvalid()) { 2430 if (expr->CallFeedbackICSlot().IsInvalid()) {
2726 DCHECK(call_type == Call::POSSIBLY_EVAL_CALL); 2431 DCHECK(call_type == Call::POSSIBLY_EVAL_CALL);
2727 // Valid type feedback slots can only be greater than kReservedIndexCount. 2432 // Valid type feedback slots can only be greater than kReservedIndexCount.
2728 // We use 0 to indicate an invalid slot id. Statically assert that 0 cannot 2433 // We use 0 to indicate an invalid slot id. Statically assert that 0 cannot
2729 // be a valid slot id. 2434 // be a valid slot id.
2730 STATIC_ASSERT(TypeFeedbackVector::kReservedIndexCount > 0); 2435 STATIC_ASSERT(TypeFeedbackVector::kReservedIndexCount > 0);
2731 feedback_slot_index = 0; 2436 feedback_slot_index = 0;
2732 } else { 2437 } else {
2733 feedback_slot_index = feedback_index(expr->CallFeedbackICSlot()); 2438 feedback_slot_index = feedback_index(expr->CallFeedbackICSlot());
2734 } 2439 }
2735 builder()->Call(callee, receiver, 1 + args->length(), feedback_slot_index, 2440 builder()->Call(callee, args, feedback_slot_index, expr->tail_call_mode());
2736 expr->tail_call_mode());
2737 execution_result()->SetResultInAccumulator();
2738 } 2441 }
2739 2442
2740 void BytecodeGenerator::VisitCallSuper(Call* expr) { 2443 void BytecodeGenerator::VisitCallSuper(Call* expr) {
2741 RegisterAllocationScope register_scope(this); 2444 RegisterAllocationScope register_scope(this);
2742 SuperCallReference* super = expr->expression()->AsSuperCallReference(); 2445 SuperCallReference* super = expr->expression()->AsSuperCallReference();
2743 2446
2744 // Prepare the constructor to the super call. 2447 // Prepare the constructor to the super call.
2745 Register this_function = register_allocator()->NewRegister(); 2448 Register this_function = VisitForRegisterValue(super->this_function_var());
2746 VisitForAccumulatorValue(super->this_function_var()); 2449 builder()->CallRuntime(Runtime::kInlineGetSuperConstructor, this_function);
2747 builder()
2748 ->StoreAccumulatorInRegister(this_function)
2749 .CallRuntime(Runtime::kInlineGetSuperConstructor, this_function, 1);
2750 2450
2751 Register constructor = this_function; // Re-use dead this_function register. 2451 Register constructor = this_function; // Re-use dead this_function register.
2752 builder()->StoreAccumulatorInRegister(constructor); 2452 builder()->StoreAccumulatorInRegister(constructor);
2753 2453
2754 ZoneList<Expression*>* args = expr->arguments(); 2454 RegisterList args =
2755 Register first_arg = VisitArguments(args); 2455 register_allocator()->NewRegisterList(expr->arguments()->length());
2456 VisitArguments(expr->arguments(), args);
2756 2457
2757 // The new target is loaded into the accumulator from the 2458 // The new target is loaded into the accumulator from the
2758 // {new.target} variable. 2459 // {new.target} variable.
2759 VisitForAccumulatorValue(super->new_target_var()); 2460 VisitForAccumulatorValue(super->new_target_var());
2760 2461
2761 // Call construct. 2462 // Call construct.
2762 builder()->SetExpressionPosition(expr); 2463 builder()->SetExpressionPosition(expr);
2763 // Valid type feedback slots can only be greater than kReservedIndexCount. 2464 // Valid type feedback slots can only be greater than kReservedIndexCount.
2764 // Assert that 0 cannot be valid a valid slot id. 2465 // Assert that 0 cannot be valid a valid slot id.
2765 STATIC_ASSERT(TypeFeedbackVector::kReservedIndexCount > 0); 2466 STATIC_ASSERT(TypeFeedbackVector::kReservedIndexCount > 0);
2766 // Type feedback is not necessary for super constructor calls. The type 2467 // Type feedback is not necessary for super constructor calls. The type
2767 // information can be inferred in most cases. Slot id 0 indicates type 2468 // information can be inferred in most cases. Slot id 0 indicates type
2768 // feedback is not required. 2469 // feedback is not required.
2769 builder()->New(constructor, first_arg, args->length(), 0); 2470 builder()->New(constructor, args, 0);
2770 execution_result()->SetResultInAccumulator();
2771 } 2471 }
2772 2472
2773 void BytecodeGenerator::VisitCallNew(CallNew* expr) { 2473 void BytecodeGenerator::VisitCallNew(CallNew* expr) {
2774 Register constructor = register_allocator()->NewRegister(); 2474 Register constructor = VisitForRegisterValue(expr->expression());
2775 VisitForAccumulatorValue(expr->expression()); 2475 RegisterList args =
2776 builder()->StoreAccumulatorInRegister(constructor); 2476 register_allocator()->NewRegisterList(expr->arguments()->length());
2777 2477 VisitArguments(expr->arguments(), args);
2778 ZoneList<Expression*>* args = expr->arguments();
2779 Register first_arg = VisitArguments(args);
2780 2478
2781 builder()->SetExpressionPosition(expr); 2479 builder()->SetExpressionPosition(expr);
2782 // The accumulator holds new target which is the same as the 2480 // The accumulator holds new target which is the same as the
2783 // constructor for CallNew. 2481 // constructor for CallNew.
2784 builder() 2482 builder()
2785 ->LoadAccumulatorWithRegister(constructor) 2483 ->LoadAccumulatorWithRegister(constructor)
2786 .New(constructor, first_arg, args->length(), 2484 .New(constructor, args, feedback_index(expr->CallNewFeedbackSlot()));
2787 feedback_index(expr->CallNewFeedbackSlot()));
2788 execution_result()->SetResultInAccumulator();
2789 } 2485 }
2790 2486
2791 void BytecodeGenerator::VisitCallRuntime(CallRuntime* expr) { 2487 void BytecodeGenerator::VisitCallRuntime(CallRuntime* expr) {
2792 ZoneList<Expression*>* args = expr->arguments();
2793 if (expr->is_jsruntime()) { 2488 if (expr->is_jsruntime()) {
2794 // Allocate a register for the receiver and load it with undefined. 2489 // Allocate a register for the receiver and load it with undefined.
2795 register_allocator()->PrepareForConsecutiveAllocations(1 + args->length()); 2490 RegisterList args =
2796 Register receiver = register_allocator()->NextConsecutiveRegister(); 2491 register_allocator()->NewRegisterList(expr->arguments()->length() + 1);
2492 Register receiver = args[0];
2797 builder()->LoadUndefined().StoreAccumulatorInRegister(receiver); 2493 builder()->LoadUndefined().StoreAccumulatorInRegister(receiver);
2798 Register first_arg = VisitArguments(args); 2494 VisitArguments(expr->arguments(), args, 1);
2799 CHECK(args->length() == 0 || first_arg.index() == receiver.index() + 1); 2495 builder()->CallJSRuntime(expr->context_index(), args);
2800 builder()->CallJSRuntime(expr->context_index(), receiver,
2801 1 + args->length());
2802 } else { 2496 } else {
2803 // Evaluate all arguments to the runtime call. 2497 // Evaluate all arguments to the runtime call.
2804 Register first_arg = VisitArguments(args); 2498 RegisterList args =
2499 register_allocator()->NewRegisterList(expr->arguments()->length());
2500 VisitArguments(expr->arguments(), args);
2805 Runtime::FunctionId function_id = expr->function()->function_id; 2501 Runtime::FunctionId function_id = expr->function()->function_id;
2806 builder()->CallRuntime(function_id, first_arg, args->length()); 2502 builder()->CallRuntime(function_id, args);
2807 } 2503 }
2808 execution_result()->SetResultInAccumulator();
2809 } 2504 }
2810 2505
2811 void BytecodeGenerator::VisitVoid(UnaryOperation* expr) { 2506 void BytecodeGenerator::VisitVoid(UnaryOperation* expr) {
2812 VisitForEffect(expr->expression()); 2507 VisitForEffect(expr->expression());
2813 builder()->LoadUndefined(); 2508 builder()->LoadUndefined();
2814 execution_result()->SetResultInAccumulator();
2815 } 2509 }
2816 2510
2817 void BytecodeGenerator::VisitTypeOf(UnaryOperation* expr) { 2511 void BytecodeGenerator::VisitTypeOf(UnaryOperation* expr) {
2818 if (expr->expression()->IsVariableProxy()) { 2512 if (expr->expression()->IsVariableProxy()) {
2819 // Typeof does not throw a reference error on global variables, hence we 2513 // Typeof does not throw a reference error on global variables, hence we
2820 // perform a non-contextual load in case the operand is a variable proxy. 2514 // perform a non-contextual load in case the operand is a variable proxy.
2821 VariableProxy* proxy = expr->expression()->AsVariableProxy(); 2515 VariableProxy* proxy = expr->expression()->AsVariableProxy();
2822 VisitVariableLoadForAccumulatorValue( 2516 VisitVariableLoadForAccumulatorValue(
2823 proxy->var(), proxy->VariableFeedbackSlot(), INSIDE_TYPEOF); 2517 proxy->var(), proxy->VariableFeedbackSlot(), INSIDE_TYPEOF);
2824 } else { 2518 } else {
2825 VisitForAccumulatorValue(expr->expression()); 2519 VisitForAccumulatorValue(expr->expression());
2826 } 2520 }
2827 builder()->TypeOf(); 2521 builder()->TypeOf();
2828 execution_result()->SetResultInAccumulator();
2829 } 2522 }
2830 2523
2831 void BytecodeGenerator::VisitNot(UnaryOperation* expr) { 2524 void BytecodeGenerator::VisitNot(UnaryOperation* expr) {
2832 if (execution_result()->IsEffect()) { 2525 if (execution_result()->IsEffect()) {
2833 VisitForEffect(expr->expression()); 2526 VisitForEffect(expr->expression());
2834 } else if (execution_result()->IsTest()) { 2527 } else if (execution_result()->IsTest()) {
2835 TestResultScope* test_result = execution_result()->AsTest(); 2528 TestResultScope* test_result = execution_result()->AsTest();
2836 // No actual logical negation happening, we just swap the control flow by 2529 // No actual logical negation happening, we just swap the control flow by
2837 // swapping the target labels and the fallthrough branch. 2530 // swapping the target labels and the fallthrough branch.
2838 VisitForTest(expr->expression(), test_result->else_labels(), 2531 VisitForTest(expr->expression(), test_result->else_labels(),
2839 test_result->then_labels(), 2532 test_result->then_labels(),
2840 test_result->inverted_fallthrough()); 2533 test_result->inverted_fallthrough());
2841 test_result->SetResultConsumedByTest(); 2534 test_result->SetResultConsumedByTest();
2842 } else { 2535 } else {
2843 VisitForAccumulatorValue(expr->expression()); 2536 VisitForAccumulatorValue(expr->expression());
2844 builder()->LogicalNot(); 2537 builder()->LogicalNot();
2845 execution_result()->SetResultInAccumulator();
2846 } 2538 }
2847 } 2539 }
2848 2540
2849 void BytecodeGenerator::VisitUnaryOperation(UnaryOperation* expr) { 2541 void BytecodeGenerator::VisitUnaryOperation(UnaryOperation* expr) {
2850 switch (expr->op()) { 2542 switch (expr->op()) {
2851 case Token::Value::NOT: 2543 case Token::Value::NOT:
2852 VisitNot(expr); 2544 VisitNot(expr);
2853 break; 2545 break;
2854 case Token::Value::TYPEOF: 2546 case Token::Value::TYPEOF:
2855 VisitTypeOf(expr); 2547 VisitTypeOf(expr);
(...skipping 54 matching lines...) Expand 10 before | Expand all | Expand 10 after
2910 } else { 2602 } else {
2911 builder()->LoadFalse(); 2603 builder()->LoadFalse();
2912 } 2604 }
2913 break; 2605 break;
2914 } 2606 }
2915 case VariableLocation::LOOKUP: { 2607 case VariableLocation::LOOKUP: {
2916 Register name_reg = register_allocator()->NewRegister(); 2608 Register name_reg = register_allocator()->NewRegister();
2917 builder() 2609 builder()
2918 ->LoadLiteral(variable->name()) 2610 ->LoadLiteral(variable->name())
2919 .StoreAccumulatorInRegister(name_reg) 2611 .StoreAccumulatorInRegister(name_reg)
2920 .CallRuntime(Runtime::kDeleteLookupSlot, name_reg, 1); 2612 .CallRuntime(Runtime::kDeleteLookupSlot, name_reg);
2921 break; 2613 break;
2922 } 2614 }
2923 default: 2615 default:
2924 UNREACHABLE(); 2616 UNREACHABLE();
2925 } 2617 }
2926 } else { 2618 } else {
2927 // Delete of an unresolvable reference returns true. 2619 // Delete of an unresolvable reference returns true.
2928 VisitForEffect(expr->expression()); 2620 VisitForEffect(expr->expression());
2929 builder()->LoadTrue(); 2621 builder()->LoadTrue();
2930 } 2622 }
2931 execution_result()->SetResultInAccumulator();
2932 } 2623 }
2933 2624
2934 void BytecodeGenerator::VisitCountOperation(CountOperation* expr) { 2625 void BytecodeGenerator::VisitCountOperation(CountOperation* expr) {
2935 DCHECK(expr->expression()->IsValidReferenceExpressionOrThis()); 2626 DCHECK(expr->expression()->IsValidReferenceExpressionOrThis());
2936 2627
2937 // Left-hand side can only be a property, a global or a variable slot. 2628 // Left-hand side can only be a property, a global or a variable slot.
2938 Property* property = expr->expression()->AsProperty(); 2629 Property* property = expr->expression()->AsProperty();
2939 LhsKind assign_type = Property::GetAssignType(property); 2630 LhsKind assign_type = Property::GetAssignType(property);
2940 2631
2941 bool is_postfix = expr->is_postfix() && !execution_result()->IsEffect(); 2632 bool is_postfix = expr->is_postfix() && !execution_result()->IsEffect();
2942 2633
2943 // Evaluate LHS expression and get old value. 2634 // Evaluate LHS expression and get old value.
2944 Register object, home_object, key, old_value, value; 2635 Register object, key, old_value;
2636 RegisterList super_property_args;
2945 Handle<String> name; 2637 Handle<String> name;
2946 switch (assign_type) { 2638 switch (assign_type) {
2947 case VARIABLE: { 2639 case VARIABLE: {
2948 VariableProxy* proxy = expr->expression()->AsVariableProxy(); 2640 VariableProxy* proxy = expr->expression()->AsVariableProxy();
2949 VisitVariableLoadForAccumulatorValue(proxy->var(), 2641 VisitVariableLoadForAccumulatorValue(proxy->var(),
2950 proxy->VariableFeedbackSlot()); 2642 proxy->VariableFeedbackSlot());
2951 break; 2643 break;
2952 } 2644 }
2953 case NAMED_PROPERTY: { 2645 case NAMED_PROPERTY: {
2954 FeedbackVectorSlot slot = property->PropertyFeedbackSlot(); 2646 FeedbackVectorSlot slot = property->PropertyFeedbackSlot();
2955 object = VisitForRegisterValue(property->obj()); 2647 object = VisitForRegisterValue(property->obj());
2956 name = property->key()->AsLiteral()->AsPropertyName(); 2648 name = property->key()->AsLiteral()->AsPropertyName();
2957 builder()->LoadNamedProperty(object, name, feedback_index(slot)); 2649 builder()->LoadNamedProperty(object, name, feedback_index(slot));
2958 break; 2650 break;
2959 } 2651 }
2960 case KEYED_PROPERTY: { 2652 case KEYED_PROPERTY: {
2961 FeedbackVectorSlot slot = property->PropertyFeedbackSlot(); 2653 FeedbackVectorSlot slot = property->PropertyFeedbackSlot();
2962 object = VisitForRegisterValue(property->obj()); 2654 object = VisitForRegisterValue(property->obj());
2963 // Use visit for accumulator here since we need the key in the accumulator 2655 // Use visit for accumulator here since we need the key in the accumulator
2964 // for the LoadKeyedProperty. 2656 // for the LoadKeyedProperty.
2965 key = register_allocator()->NewRegister(); 2657 key = register_allocator()->NewRegister();
2966 VisitForAccumulatorValue(property->key()); 2658 VisitForAccumulatorValue(property->key());
2967 builder()->StoreAccumulatorInRegister(key).LoadKeyedProperty( 2659 builder()->StoreAccumulatorInRegister(key).LoadKeyedProperty(
2968 object, feedback_index(slot)); 2660 object, feedback_index(slot));
2969 break; 2661 break;
2970 } 2662 }
2971 case NAMED_SUPER_PROPERTY: { 2663 case NAMED_SUPER_PROPERTY: {
2972 register_allocator()->PrepareForConsecutiveAllocations(4); 2664 super_property_args = register_allocator()->NewRegisterList(4);
2973 object = register_allocator()->NextConsecutiveRegister(); 2665 RegisterList load_super_args = super_property_args.Truncate(3);
2974 home_object = register_allocator()->NextConsecutiveRegister();
2975 key = register_allocator()->NextConsecutiveRegister();
2976 value = register_allocator()->NextConsecutiveRegister();
2977 SuperPropertyReference* super_property = 2666 SuperPropertyReference* super_property =
2978 property->obj()->AsSuperPropertyReference(); 2667 property->obj()->AsSuperPropertyReference();
2979 VisitForRegisterValue(super_property->this_var(), object); 2668 VisitForRegisterValue(super_property->this_var(), load_super_args[0]);
2980 VisitForRegisterValue(super_property->home_object(), home_object); 2669 VisitForRegisterValue(super_property->home_object(), load_super_args[1]);
2981 builder() 2670 builder()
2982 ->LoadLiteral(property->key()->AsLiteral()->AsPropertyName()) 2671 ->LoadLiteral(property->key()->AsLiteral()->AsPropertyName())
2983 .StoreAccumulatorInRegister(key); 2672 .StoreAccumulatorInRegister(load_super_args[2])
2984 BuildNamedSuperPropertyLoad(object, home_object, key); 2673 .CallRuntime(Runtime::kLoadFromSuper, load_super_args);
2985 break; 2674 break;
2986 } 2675 }
2987 case KEYED_SUPER_PROPERTY: { 2676 case KEYED_SUPER_PROPERTY: {
2988 register_allocator()->PrepareForConsecutiveAllocations(4); 2677 super_property_args = register_allocator()->NewRegisterList(4);
2989 object = register_allocator()->NextConsecutiveRegister(); 2678 RegisterList load_super_args = super_property_args.Truncate(3);
2990 home_object = register_allocator()->NextConsecutiveRegister();
2991 key = register_allocator()->NextConsecutiveRegister();
2992 value = register_allocator()->NextConsecutiveRegister();
2993 builder()->StoreAccumulatorInRegister(value);
2994 SuperPropertyReference* super_property = 2679 SuperPropertyReference* super_property =
2995 property->obj()->AsSuperPropertyReference(); 2680 property->obj()->AsSuperPropertyReference();
2996 VisitForRegisterValue(super_property->this_var(), object); 2681 VisitForRegisterValue(super_property->this_var(), load_super_args[0]);
2997 VisitForRegisterValue(super_property->home_object(), home_object); 2682 VisitForRegisterValue(super_property->home_object(), load_super_args[1]);
2998 VisitForRegisterValue(property->key(), key); 2683 VisitForRegisterValue(property->key(), load_super_args[2]);
2999 BuildKeyedSuperPropertyLoad(object, home_object, key); 2684 builder()->CallRuntime(Runtime::kLoadKeyedFromSuper, load_super_args);
3000 break; 2685 break;
3001 } 2686 }
3002 } 2687 }
3003 2688
3004 // Save result for postfix expressions. 2689 // Save result for postfix expressions.
3005 if (is_postfix) { 2690 if (is_postfix) {
3006 old_value = register_allocator()->outer()->NewRegister();
3007
3008 // Convert old value into a number before saving it. 2691 // Convert old value into a number before saving it.
2692 old_value = register_allocator()->NewRegister();
3009 builder()->ConvertAccumulatorToNumber(old_value); 2693 builder()->ConvertAccumulatorToNumber(old_value);
3010 } 2694 }
3011 2695
3012 // Perform +1/-1 operation. 2696 // Perform +1/-1 operation.
3013 FeedbackVectorSlot slot = expr->CountBinaryOpFeedbackSlot(); 2697 FeedbackVectorSlot slot = expr->CountBinaryOpFeedbackSlot();
3014 builder()->CountOperation(expr->binary_op(), feedback_index(slot)); 2698 builder()->CountOperation(expr->binary_op(), feedback_index(slot));
3015 2699
3016 // Store the value. 2700 // Store the value.
3017 builder()->SetExpressionPosition(expr); 2701 builder()->SetExpressionPosition(expr);
3018 FeedbackVectorSlot feedback_slot = expr->CountSlot(); 2702 FeedbackVectorSlot feedback_slot = expr->CountSlot();
3019 switch (assign_type) { 2703 switch (assign_type) {
3020 case VARIABLE: { 2704 case VARIABLE: {
3021 Variable* variable = expr->expression()->AsVariableProxy()->var(); 2705 Variable* variable = expr->expression()->AsVariableProxy()->var();
3022 VisitVariableAssignment(variable, expr->op(), feedback_slot); 2706 VisitVariableAssignment(variable, expr->op(), feedback_slot);
3023 break; 2707 break;
3024 } 2708 }
3025 case NAMED_PROPERTY: { 2709 case NAMED_PROPERTY: {
3026 builder()->StoreNamedProperty(object, name, feedback_index(feedback_slot), 2710 builder()->StoreNamedProperty(object, name, feedback_index(feedback_slot),
3027 language_mode()); 2711 language_mode());
3028 break; 2712 break;
3029 } 2713 }
3030 case KEYED_PROPERTY: { 2714 case KEYED_PROPERTY: {
3031 builder()->StoreKeyedProperty(object, key, feedback_index(feedback_slot), 2715 builder()->StoreKeyedProperty(object, key, feedback_index(feedback_slot),
3032 language_mode()); 2716 language_mode());
3033 break; 2717 break;
3034 } 2718 }
3035 case NAMED_SUPER_PROPERTY: { 2719 case NAMED_SUPER_PROPERTY: {
3036 builder()->StoreAccumulatorInRegister(value); 2720 builder()
3037 BuildNamedSuperPropertyStore(object, home_object, key, value); 2721 ->StoreAccumulatorInRegister(super_property_args[3])
2722 .CallRuntime(StoreToSuperRuntimeId(), super_property_args);
3038 break; 2723 break;
3039 } 2724 }
3040 case KEYED_SUPER_PROPERTY: { 2725 case KEYED_SUPER_PROPERTY: {
3041 builder()->StoreAccumulatorInRegister(value); 2726 builder()
3042 BuildKeyedSuperPropertyStore(object, home_object, key, value); 2727 ->StoreAccumulatorInRegister(super_property_args[3])
2728 .CallRuntime(StoreKeyedToSuperRuntimeId(), super_property_args);
3043 break; 2729 break;
3044 } 2730 }
3045 } 2731 }
3046 2732
3047 // Restore old value for postfix expressions. 2733 // Restore old value for postfix expressions.
3048 if (is_postfix) { 2734 if (is_postfix) {
3049 execution_result()->SetResultInRegister(old_value); 2735 builder()->LoadAccumulatorWithRegister(old_value);
3050 } else {
3051 execution_result()->SetResultInAccumulator();
3052 } 2736 }
3053 } 2737 }
3054 2738
3055 void BytecodeGenerator::VisitBinaryOperation(BinaryOperation* binop) { 2739 void BytecodeGenerator::VisitBinaryOperation(BinaryOperation* binop) {
3056 switch (binop->op()) { 2740 switch (binop->op()) {
3057 case Token::COMMA: 2741 case Token::COMMA:
3058 VisitCommaExpression(binop); 2742 VisitCommaExpression(binop);
3059 break; 2743 break;
3060 case Token::OR: 2744 case Token::OR:
3061 VisitLogicalOrExpression(binop); 2745 VisitLogicalOrExpression(binop);
3062 break; 2746 break;
3063 case Token::AND: 2747 case Token::AND:
3064 VisitLogicalAndExpression(binop); 2748 VisitLogicalAndExpression(binop);
3065 break; 2749 break;
3066 default: 2750 default:
3067 VisitArithmeticExpression(binop); 2751 VisitArithmeticExpression(binop);
3068 break; 2752 break;
3069 } 2753 }
3070 } 2754 }
3071 2755
3072 void BytecodeGenerator::VisitCompareOperation(CompareOperation* expr) { 2756 void BytecodeGenerator::VisitCompareOperation(CompareOperation* expr) {
3073 Register lhs = VisitForRegisterValue(expr->left()); 2757 Register lhs = VisitForRegisterValue(expr->left());
3074 VisitForAccumulatorValue(expr->right()); 2758 VisitForAccumulatorValue(expr->right());
3075 builder()->SetExpressionPosition(expr); 2759 builder()->SetExpressionPosition(expr);
3076 FeedbackVectorSlot slot = expr->CompareOperationFeedbackSlot(); 2760 FeedbackVectorSlot slot = expr->CompareOperationFeedbackSlot();
3077 builder()->CompareOperation(expr->op(), lhs, feedback_index(slot)); 2761 builder()->CompareOperation(expr->op(), lhs, feedback_index(slot));
3078 execution_result()->SetResultInAccumulator();
3079 } 2762 }
3080 2763
3081 void BytecodeGenerator::VisitArithmeticExpression(BinaryOperation* expr) { 2764 void BytecodeGenerator::VisitArithmeticExpression(BinaryOperation* expr) {
3082 // TODO(rmcilroy): Special case "x * 1.0" and "x * -1" which are generated for 2765 // TODO(rmcilroy): Special case "x * 1.0" and "x * -1" which are generated for
3083 // +x and -x by the parser. 2766 // +x and -x by the parser.
3084 Register lhs = VisitForRegisterValue(expr->left()); 2767 Register lhs = VisitForRegisterValue(expr->left());
3085 VisitForAccumulatorValue(expr->right()); 2768 VisitForAccumulatorValue(expr->right());
3086 FeedbackVectorSlot slot = expr->BinaryOperationFeedbackSlot(); 2769 FeedbackVectorSlot slot = expr->BinaryOperationFeedbackSlot();
3087 builder()->BinaryOperation(expr->op(), lhs, feedback_index(slot)); 2770 builder()->BinaryOperation(expr->op(), lhs, feedback_index(slot));
3088 execution_result()->SetResultInAccumulator();
3089 } 2771 }
3090 2772
3091 void BytecodeGenerator::VisitSpread(Spread* expr) { UNREACHABLE(); } 2773 void BytecodeGenerator::VisitSpread(Spread* expr) { UNREACHABLE(); }
3092 2774
3093 void BytecodeGenerator::VisitEmptyParentheses(EmptyParentheses* expr) { 2775 void BytecodeGenerator::VisitEmptyParentheses(EmptyParentheses* expr) {
3094 UNREACHABLE(); 2776 UNREACHABLE();
3095 } 2777 }
3096 2778
3097 void BytecodeGenerator::VisitThisFunction(ThisFunction* expr) { 2779 void BytecodeGenerator::VisitThisFunction(ThisFunction* expr) {
3098 execution_result()->SetResultInRegister(Register::function_closure()); 2780 builder()->LoadAccumulatorWithRegister(Register::function_closure());
3099 } 2781 }
3100 2782
3101 void BytecodeGenerator::VisitSuperCallReference(SuperCallReference* expr) { 2783 void BytecodeGenerator::VisitSuperCallReference(SuperCallReference* expr) {
3102 // Handled by VisitCall(). 2784 // Handled by VisitCall().
3103 UNREACHABLE(); 2785 UNREACHABLE();
3104 } 2786 }
3105 2787
3106 void BytecodeGenerator::VisitSuperPropertyReference( 2788 void BytecodeGenerator::VisitSuperPropertyReference(
3107 SuperPropertyReference* expr) { 2789 SuperPropertyReference* expr) {
3108 builder()->CallRuntime(Runtime::kThrowUnsupportedSuperError, Register(0), 0); 2790 builder()->CallRuntime(Runtime::kThrowUnsupportedSuperError);
3109 execution_result()->SetResultInAccumulator();
3110 } 2791 }
3111 2792
3112 void BytecodeGenerator::VisitCommaExpression(BinaryOperation* binop) { 2793 void BytecodeGenerator::VisitCommaExpression(BinaryOperation* binop) {
3113 VisitForEffect(binop->left()); 2794 VisitForEffect(binop->left());
3114 Visit(binop->right()); 2795 Visit(binop->right());
3115 } 2796 }
3116 2797
3117 void BytecodeGenerator::VisitLogicalOrExpression(BinaryOperation* binop) { 2798 void BytecodeGenerator::VisitLogicalOrExpression(BinaryOperation* binop) {
3118 Expression* left = binop->left(); 2799 Expression* left = binop->left();
3119 Expression* right = binop->right(); 2800 Expression* right = binop->right();
(...skipping 19 matching lines...) Expand all
3139 VisitForAccumulatorValue(left); 2820 VisitForAccumulatorValue(left);
3140 } else if (left->ToBooleanIsFalse()) { 2821 } else if (left->ToBooleanIsFalse()) {
3141 VisitForAccumulatorValue(right); 2822 VisitForAccumulatorValue(right);
3142 } else { 2823 } else {
3143 BytecodeLabel end_label; 2824 BytecodeLabel end_label;
3144 VisitForAccumulatorValue(left); 2825 VisitForAccumulatorValue(left);
3145 builder()->JumpIfTrue(&end_label); 2826 builder()->JumpIfTrue(&end_label);
3146 VisitForAccumulatorValue(right); 2827 VisitForAccumulatorValue(right);
3147 builder()->Bind(&end_label); 2828 builder()->Bind(&end_label);
3148 } 2829 }
3149 execution_result()->SetResultInAccumulator();
3150 } 2830 }
3151 } 2831 }
3152 2832
3153 void BytecodeGenerator::VisitLogicalAndExpression(BinaryOperation* binop) { 2833 void BytecodeGenerator::VisitLogicalAndExpression(BinaryOperation* binop) {
3154 Expression* left = binop->left(); 2834 Expression* left = binop->left();
3155 Expression* right = binop->right(); 2835 Expression* right = binop->right();
3156 2836
3157 if (execution_result()->IsTest()) { 2837 if (execution_result()->IsTest()) {
3158 TestResultScope* test_result = execution_result()->AsTest(); 2838 TestResultScope* test_result = execution_result()->AsTest();
3159 2839
(...skipping 15 matching lines...) Expand all
3175 VisitForAccumulatorValue(left); 2855 VisitForAccumulatorValue(left);
3176 } else if (left->ToBooleanIsTrue()) { 2856 } else if (left->ToBooleanIsTrue()) {
3177 VisitForAccumulatorValue(right); 2857 VisitForAccumulatorValue(right);
3178 } else { 2858 } else {
3179 BytecodeLabel end_label; 2859 BytecodeLabel end_label;
3180 VisitForAccumulatorValue(left); 2860 VisitForAccumulatorValue(left);
3181 builder()->JumpIfFalse(&end_label); 2861 builder()->JumpIfFalse(&end_label);
3182 VisitForAccumulatorValue(right); 2862 VisitForAccumulatorValue(right);
3183 builder()->Bind(&end_label); 2863 builder()->Bind(&end_label);
3184 } 2864 }
3185 execution_result()->SetResultInAccumulator();
3186 } 2865 }
3187 } 2866 }
3188 2867
3189 void BytecodeGenerator::VisitRewritableExpression(RewritableExpression* expr) { 2868 void BytecodeGenerator::VisitRewritableExpression(RewritableExpression* expr) {
3190 Visit(expr->expression()); 2869 Visit(expr->expression());
3191 } 2870 }
3192 2871
3193 void BytecodeGenerator::BuildNewLocalActivationContext() { 2872 void BytecodeGenerator::BuildNewLocalActivationContext() {
3194 AccumulatorResultScope accumulator_execution_result(this); 2873 ValueResultScope value_execution_result(this);
3195 Scope* scope = this->scope(); 2874 Scope* scope = this->scope();
3196 2875
3197 // Create the appropriate context. 2876 // Create the appropriate context.
3198 if (scope->is_script_scope()) { 2877 if (scope->is_script_scope()) {
3199 RegisterAllocationScope register_scope(this); 2878 RegisterList args = register_allocator()->NewRegisterList(2);
3200 register_allocator()->PrepareForConsecutiveAllocations(2);
3201 Register closure = register_allocator()->NextConsecutiveRegister();
3202 Register scope_info = register_allocator()->NextConsecutiveRegister();
3203 builder() 2879 builder()
3204 ->LoadAccumulatorWithRegister(Register::function_closure()) 2880 ->LoadAccumulatorWithRegister(Register::function_closure())
3205 .StoreAccumulatorInRegister(closure) 2881 .StoreAccumulatorInRegister(args[0])
3206 .LoadLiteral(scope->scope_info()) 2882 .LoadLiteral(scope->scope_info())
3207 .StoreAccumulatorInRegister(scope_info) 2883 .StoreAccumulatorInRegister(args[1])
3208 .CallRuntime(Runtime::kNewScriptContext, closure, 2); 2884 .CallRuntime(Runtime::kNewScriptContext, args);
3209 } else if (scope->is_module_scope()) { 2885 } else if (scope->is_module_scope()) {
3210 // We don't need to do anything for the outer script scope. 2886 // We don't need to do anything for the outer script scope.
3211 DCHECK(scope->outer_scope()->is_script_scope()); 2887 DCHECK(scope->outer_scope()->is_script_scope());
3212 2888
3213 RegisterAllocationScope register_scope(this);
3214 register_allocator()->PrepareForConsecutiveAllocations(3);
3215 Register module = register_allocator()->NextConsecutiveRegister();
3216 Register closure = register_allocator()->NextConsecutiveRegister();
3217 Register scope_info = register_allocator()->NextConsecutiveRegister();
3218 // A JSFunction representing a module is called with the module object as 2889 // A JSFunction representing a module is called with the module object as
3219 // its sole argument, which we pass on to PushModuleContext. 2890 // its sole argument, which we pass on to PushModuleContext.
2891 RegisterList args = register_allocator()->NewRegisterList(3);
3220 builder() 2892 builder()
3221 ->MoveRegister(builder()->Parameter(1), module) 2893 ->MoveRegister(builder()->Parameter(1), args[0])
3222 .LoadAccumulatorWithRegister(Register::function_closure()) 2894 .LoadAccumulatorWithRegister(Register::function_closure())
3223 .StoreAccumulatorInRegister(closure) 2895 .StoreAccumulatorInRegister(args[1])
3224 .LoadLiteral(scope->scope_info()) 2896 .LoadLiteral(scope->scope_info())
3225 .StoreAccumulatorInRegister(scope_info) 2897 .StoreAccumulatorInRegister(args[2])
3226 .CallRuntime(Runtime::kPushModuleContext, module, 3); 2898 .CallRuntime(Runtime::kPushModuleContext, args);
3227 } else { 2899 } else {
3228 int slot_count = scope->num_heap_slots() - Context::MIN_CONTEXT_SLOTS; 2900 int slot_count = scope->num_heap_slots() - Context::MIN_CONTEXT_SLOTS;
3229 builder()->CreateFunctionContext(slot_count); 2901 builder()->CreateFunctionContext(slot_count);
3230 } 2902 }
3231 execution_result()->SetResultInAccumulator();
3232 } 2903 }
3233 2904
3234 void BytecodeGenerator::BuildLocalActivationContextInitialization() { 2905 void BytecodeGenerator::BuildLocalActivationContextInitialization() {
3235 DeclarationScope* scope = this->scope(); 2906 DeclarationScope* scope = this->scope();
3236 2907
3237 if (scope->has_this_declaration() && scope->receiver()->IsContextSlot()) { 2908 if (scope->has_this_declaration() && scope->receiver()->IsContextSlot()) {
3238 Variable* variable = scope->receiver(); 2909 Variable* variable = scope->receiver();
3239 Register receiver(builder()->Parameter(0)); 2910 Register receiver(builder()->Parameter(0));
3240 // Context variable (at bottom of the context chain). 2911 // Context variable (at bottom of the context chain).
3241 DCHECK_EQ(0, scope->ContextChainLength(variable->scope())); 2912 DCHECK_EQ(0, scope->ContextChainLength(variable->scope()));
(...skipping 11 matching lines...) Expand all
3253 // index -1 but is parameter index 0 in BytecodeArrayBuilder). 2924 // index -1 but is parameter index 0 in BytecodeArrayBuilder).
3254 Register parameter(builder()->Parameter(i + 1)); 2925 Register parameter(builder()->Parameter(i + 1));
3255 // Context variable (at bottom of the context chain). 2926 // Context variable (at bottom of the context chain).
3256 DCHECK_EQ(0, scope->ContextChainLength(variable->scope())); 2927 DCHECK_EQ(0, scope->ContextChainLength(variable->scope()));
3257 builder()->LoadAccumulatorWithRegister(parameter).StoreContextSlot( 2928 builder()->LoadAccumulatorWithRegister(parameter).StoreContextSlot(
3258 execution_context()->reg(), variable->index(), 0); 2929 execution_context()->reg(), variable->index(), 0);
3259 } 2930 }
3260 } 2931 }
3261 2932
3262 void BytecodeGenerator::BuildNewLocalBlockContext(Scope* scope) { 2933 void BytecodeGenerator::BuildNewLocalBlockContext(Scope* scope) {
3263 AccumulatorResultScope accumulator_execution_result(this); 2934 ValueResultScope value_execution_result(this);
3264 DCHECK(scope->is_block_scope()); 2935 DCHECK(scope->is_block_scope());
3265 2936
3266 VisitFunctionClosureForContext(); 2937 VisitFunctionClosureForContext();
3267 builder()->CreateBlockContext(scope->scope_info()); 2938 builder()->CreateBlockContext(scope->scope_info());
3268 execution_result()->SetResultInAccumulator();
3269 } 2939 }
3270 2940
3271 void BytecodeGenerator::BuildNewLocalWithContext(Scope* scope) { 2941 void BytecodeGenerator::BuildNewLocalWithContext(Scope* scope) {
3272 AccumulatorResultScope accumulator_execution_result(this); 2942 ValueResultScope value_execution_result(this);
3273 2943
3274 Register extension_object = register_allocator()->NewRegister(); 2944 Register extension_object = register_allocator()->NewRegister();
3275 2945
3276 builder()->ConvertAccumulatorToObject(extension_object); 2946 builder()->ConvertAccumulatorToObject(extension_object);
3277 VisitFunctionClosureForContext(); 2947 VisitFunctionClosureForContext();
3278 builder()->CreateWithContext(extension_object, scope->scope_info()); 2948 builder()->CreateWithContext(extension_object, scope->scope_info());
3279 execution_result()->SetResultInAccumulator();
3280 } 2949 }
3281 2950
3282 void BytecodeGenerator::BuildNewLocalCatchContext(Variable* variable, 2951 void BytecodeGenerator::BuildNewLocalCatchContext(Variable* variable,
3283 Scope* scope) { 2952 Scope* scope) {
3284 AccumulatorResultScope accumulator_execution_result(this); 2953 ValueResultScope value_execution_result(this);
3285 DCHECK(variable->IsContextSlot()); 2954 DCHECK(variable->IsContextSlot());
3286 2955
3287 Register exception = register_allocator()->NewRegister(); 2956 Register exception = register_allocator()->NewRegister();
3288 builder()->StoreAccumulatorInRegister(exception); 2957 builder()->StoreAccumulatorInRegister(exception);
3289 VisitFunctionClosureForContext(); 2958 VisitFunctionClosureForContext();
3290 builder()->CreateCatchContext(exception, variable->name(), 2959 builder()->CreateCatchContext(exception, variable->name(),
3291 scope->scope_info()); 2960 scope->scope_info());
3292 execution_result()->SetResultInAccumulator();
3293 } 2961 }
3294 2962
3295 void BytecodeGenerator::VisitObjectLiteralAccessor( 2963 void BytecodeGenerator::VisitObjectLiteralAccessor(
3296 Register home_object, ObjectLiteralProperty* property, Register value_out) { 2964 Register home_object, ObjectLiteralProperty* property, Register value_out) {
3297 // TODO(rmcilroy): Replace value_out with VisitForRegister();
3298 if (property == nullptr) { 2965 if (property == nullptr) {
3299 builder()->LoadNull().StoreAccumulatorInRegister(value_out); 2966 builder()->LoadNull().StoreAccumulatorInRegister(value_out);
3300 } else { 2967 } else {
3301 VisitForAccumulatorValue(property->value()); 2968 VisitForRegisterValue(property->value(), value_out);
3302 builder()->StoreAccumulatorInRegister(value_out);
3303 VisitSetHomeObject(value_out, home_object, property); 2969 VisitSetHomeObject(value_out, home_object, property);
3304 } 2970 }
3305 } 2971 }
3306 2972
3307 void BytecodeGenerator::VisitSetHomeObject(Register value, Register home_object, 2973 void BytecodeGenerator::VisitSetHomeObject(Register value, Register home_object,
3308 LiteralProperty* property, 2974 LiteralProperty* property,
3309 int slot_number) { 2975 int slot_number) {
3310 Expression* expr = property->value(); 2976 Expression* expr = property->value();
3311 if (FunctionLiteral::NeedsHomeObject(expr)) { 2977 if (FunctionLiteral::NeedsHomeObject(expr)) {
3312 FeedbackVectorSlot slot = property->GetSlot(slot_number); 2978 FeedbackVectorSlot slot = property->GetSlot(slot_number);
(...skipping 47 matching lines...) Expand 10 before | Expand all | Expand 10 after
3360 3026
3361 // TODO(mstarzinger): The <new.target> register is not set by the deoptimizer 3027 // TODO(mstarzinger): The <new.target> register is not set by the deoptimizer
3362 // and we need to make sure {BytecodeRegisterOptimizer} flushes its state 3028 // and we need to make sure {BytecodeRegisterOptimizer} flushes its state
3363 // before a local variable containing the <new.target> is used. Using a label 3029 // before a local variable containing the <new.target> is used. Using a label
3364 // as below flushes the entire pipeline, we should be more specific here. 3030 // as below flushes the entire pipeline, we should be more specific here.
3365 BytecodeLabel flush_state_label; 3031 BytecodeLabel flush_state_label;
3366 builder()->Bind(&flush_state_label); 3032 builder()->Bind(&flush_state_label);
3367 } 3033 }
3368 3034
3369 void BytecodeGenerator::VisitFunctionClosureForContext() { 3035 void BytecodeGenerator::VisitFunctionClosureForContext() {
3370 AccumulatorResultScope accumulator_execution_result(this); 3036 ValueResultScope value_execution_result(this);
3371 DeclarationScope* closure_scope = 3037 DeclarationScope* closure_scope =
3372 execution_context()->scope()->GetClosureScope(); 3038 execution_context()->scope()->GetClosureScope();
3373 if (closure_scope->is_script_scope()) { 3039 if (closure_scope->is_script_scope()) {
3374 // Contexts nested in the native context have a canonical empty function as 3040 // Contexts nested in the native context have a canonical empty function as
3375 // their closure, not the anonymous closure containing the global code. 3041 // their closure, not the anonymous closure containing the global code.
3376 Register native_context = register_allocator()->NewRegister(); 3042 Register native_context = register_allocator()->NewRegister();
3377 builder() 3043 builder()
3378 ->LoadContextSlot(execution_context()->reg(), 3044 ->LoadContextSlot(execution_context()->reg(),
3379 Context::NATIVE_CONTEXT_INDEX, 0) 3045 Context::NATIVE_CONTEXT_INDEX, 0)
3380 .StoreAccumulatorInRegister(native_context) 3046 .StoreAccumulatorInRegister(native_context)
3381 .LoadContextSlot(native_context, Context::CLOSURE_INDEX, 0); 3047 .LoadContextSlot(native_context, Context::CLOSURE_INDEX, 0);
3382 } else if (closure_scope->is_eval_scope()) { 3048 } else if (closure_scope->is_eval_scope()) {
3383 // Contexts created by a call to eval have the same closure as the 3049 // Contexts created by a call to eval have the same closure as the
3384 // context calling eval, not the anonymous closure containing the eval 3050 // context calling eval, not the anonymous closure containing the eval
3385 // code. Fetch it from the context. 3051 // code. Fetch it from the context.
3386 builder()->LoadContextSlot(execution_context()->reg(), 3052 builder()->LoadContextSlot(execution_context()->reg(),
3387 Context::CLOSURE_INDEX, 0); 3053 Context::CLOSURE_INDEX, 0);
3388 } else { 3054 } else {
3389 DCHECK(closure_scope->is_function_scope() || 3055 DCHECK(closure_scope->is_function_scope() ||
3390 closure_scope->is_module_scope()); 3056 closure_scope->is_module_scope());
3391 builder()->LoadAccumulatorWithRegister(Register::function_closure()); 3057 builder()->LoadAccumulatorWithRegister(Register::function_closure());
3392 } 3058 }
3393 execution_result()->SetResultInAccumulator();
3394 } 3059 }
3395 3060
3396 // Visits the expression |expr| and places the result in the accumulator. 3061 // Visits the expression |expr| and places the result in the accumulator.
3397 void BytecodeGenerator::VisitForAccumulatorValue(Expression* expr) { 3062 void BytecodeGenerator::VisitForAccumulatorValue(Expression* expr) {
3398 AccumulatorResultScope accumulator_scope(this); 3063 ValueResultScope accumulator_scope(this);
3399 Visit(expr); 3064 Visit(expr);
3400 } 3065 }
3401 3066
3402 void BytecodeGenerator::VisitForAccumulatorValueOrTheHole(Expression* expr) { 3067 void BytecodeGenerator::VisitForAccumulatorValueOrTheHole(Expression* expr) {
3403 if (expr == nullptr) { 3068 if (expr == nullptr) {
3404 builder()->LoadTheHole(); 3069 builder()->LoadTheHole();
3405 } else { 3070 } else {
3406 VisitForAccumulatorValue(expr); 3071 VisitForAccumulatorValue(expr);
3407 } 3072 }
3408 } 3073 }
3409 3074
3410 // Visits the expression |expr| and discards the result. 3075 // Visits the expression |expr| and discards the result.
3411 void BytecodeGenerator::VisitForEffect(Expression* expr) { 3076 void BytecodeGenerator::VisitForEffect(Expression* expr) {
3412 EffectResultScope effect_scope(this); 3077 EffectResultScope effect_scope(this);
3413 Visit(expr); 3078 Visit(expr);
3414 } 3079 }
3415 3080
3416 // Visits the expression |expr| and returns the register containing 3081 // Visits the expression |expr| and returns the register containing
3417 // the expression result. 3082 // the expression result.
3418 Register BytecodeGenerator::VisitForRegisterValue(Expression* expr) { 3083 Register BytecodeGenerator::VisitForRegisterValue(Expression* expr) {
3419 RegisterResultScope register_scope(this); 3084 VisitForAccumulatorValue(expr);
3420 Visit(expr); 3085 Register result = register_allocator()->NewRegister();
3421 return register_scope.ResultRegister(); 3086 builder()->StoreAccumulatorInRegister(result);
3087 return result;
3422 } 3088 }
3423 3089
3424 // Visits the expression |expr| and stores the expression result in 3090 // Visits the expression |expr| and stores the expression result in
3425 // |destination|. 3091 // |destination|.
3426 void BytecodeGenerator::VisitForRegisterValue(Expression* expr, 3092 void BytecodeGenerator::VisitForRegisterValue(Expression* expr,
3427 Register destination) { 3093 Register destination) {
3428 AccumulatorResultScope register_scope(this); 3094 ValueResultScope register_scope(this);
3429 Visit(expr); 3095 Visit(expr);
3430 builder()->StoreAccumulatorInRegister(destination); 3096 builder()->StoreAccumulatorInRegister(destination);
3431 } 3097 }
3432 3098
3433 // Visits the expression |expr| for testing its boolean value and jumping to the 3099 // Visits the expression |expr| for testing its boolean value and jumping to the
3434 // |then| or |other| label depending on value and short-circuit semantics 3100 // |then| or |other| label depending on value and short-circuit semantics
3435 void BytecodeGenerator::VisitForTest(Expression* expr, 3101 void BytecodeGenerator::VisitForTest(Expression* expr,
3436 BytecodeLabels* then_labels, 3102 BytecodeLabels* then_labels,
3437 BytecodeLabels* else_labels, 3103 BytecodeLabels* else_labels,
3438 TestFallthrough fallthrough) { 3104 TestFallthrough fallthrough) {
(...skipping 28 matching lines...) Expand all
3467 } 3133 }
3468 3134
3469 LanguageMode BytecodeGenerator::language_mode() const { 3135 LanguageMode BytecodeGenerator::language_mode() const {
3470 return execution_context()->scope()->language_mode(); 3136 return execution_context()->scope()->language_mode();
3471 } 3137 }
3472 3138
3473 int BytecodeGenerator::feedback_index(FeedbackVectorSlot slot) const { 3139 int BytecodeGenerator::feedback_index(FeedbackVectorSlot slot) const {
3474 return TypeFeedbackVector::GetIndex(slot); 3140 return TypeFeedbackVector::GetIndex(slot);
3475 } 3141 }
3476 3142
3143 Runtime::FunctionId BytecodeGenerator::StoreToSuperRuntimeId() {
3144 return is_strict(language_mode()) ? Runtime::kStoreToSuper_Strict
3145 : Runtime::kStoreToSuper_Sloppy;
3146 }
3147
3148 Runtime::FunctionId BytecodeGenerator::StoreKeyedToSuperRuntimeId() {
3149 return is_strict(language_mode()) ? Runtime::kStoreKeyedToSuper_Strict
3150 : Runtime::kStoreKeyedToSuper_Sloppy;
3151 }
3152
3477 } // namespace interpreter 3153 } // namespace interpreter
3478 } // namespace internal 3154 } // namespace internal
3479 } // namespace v8 3155 } // namespace v8
OLDNEW
« no previous file with comments | « src/interpreter/bytecode-generator.h ('k') | src/interpreter/bytecode-register-allocator.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698