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

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

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

Powered by Google App Engine
This is Rietveld 408576698