OLD | NEW |
---|---|
1 // Copyright 2015 the V8 project authors. All rights reserved. | 1 // Copyright 2015 the V8 project authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include "src/interpreter/bytecode-generator.h" | 5 #include "src/interpreter/bytecode-generator.h" |
6 | 6 |
7 #include "src/ast/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/builtins/builtins-constructor.h" | 9 #include "src/builtins/builtins-constructor.h" |
10 #include "src/code-stubs.h" | 10 #include "src/code-stubs.h" |
(...skipping 480 matching lines...) Loading... | |
491 | 491 |
492 // Used to build a list of global declaration initial value pairs. | 492 // Used to build a list of global declaration initial value pairs. |
493 class BytecodeGenerator::GlobalDeclarationsBuilder final : public ZoneObject { | 493 class BytecodeGenerator::GlobalDeclarationsBuilder final : public ZoneObject { |
494 public: | 494 public: |
495 explicit GlobalDeclarationsBuilder(Zone* zone) | 495 explicit GlobalDeclarationsBuilder(Zone* zone) |
496 : declarations_(0, zone), | 496 : declarations_(0, zone), |
497 constant_pool_entry_(0), | 497 constant_pool_entry_(0), |
498 has_constant_pool_entry_(false) {} | 498 has_constant_pool_entry_(false) {} |
499 | 499 |
500 void AddFunctionDeclaration(Handle<String> name, FeedbackVectorSlot slot, | 500 void AddFunctionDeclaration(Handle<String> name, FeedbackVectorSlot slot, |
501 FeedbackVectorSlot literal_slot, | |
501 FunctionLiteral* func) { | 502 FunctionLiteral* func) { |
502 DCHECK(!slot.IsInvalid()); | 503 DCHECK(!slot.IsInvalid()); |
503 declarations_.push_back(Declaration(name, slot, func)); | 504 declarations_.push_back(Declaration(name, slot, literal_slot, func)); |
504 } | 505 } |
505 | 506 |
506 void AddUndefinedDeclaration(Handle<String> name, FeedbackVectorSlot slot) { | 507 void AddUndefinedDeclaration(Handle<String> name, FeedbackVectorSlot slot) { |
507 DCHECK(!slot.IsInvalid()); | 508 DCHECK(!slot.IsInvalid()); |
508 declarations_.push_back(Declaration(name, slot, nullptr)); | 509 declarations_.push_back(Declaration(name, slot, nullptr)); |
509 } | 510 } |
510 | 511 |
511 Handle<FixedArray> AllocateDeclarations(CompilationInfo* info) { | 512 Handle<FixedArray> AllocateDeclarations(CompilationInfo* info) { |
512 DCHECK(has_constant_pool_entry_); | 513 DCHECK(has_constant_pool_entry_); |
513 int array_index = 0; | 514 int array_index = 0; |
514 Handle<FixedArray> data = info->isolate()->factory()->NewFixedArray( | 515 Handle<FixedArray> data = info->isolate()->factory()->NewFixedArray( |
515 static_cast<int>(declarations_.size() * 3), TENURED); | 516 static_cast<int>(declarations_.size() * 4), TENURED); |
516 for (const Declaration& declaration : declarations_) { | 517 for (const Declaration& declaration : declarations_) { |
517 FunctionLiteral* func = declaration.func; | 518 FunctionLiteral* func = declaration.func; |
518 Handle<Object> initial_value; | 519 Handle<Object> initial_value; |
519 if (func == nullptr) { | 520 if (func == nullptr) { |
520 initial_value = info->isolate()->factory()->undefined_value(); | 521 initial_value = info->isolate()->factory()->undefined_value(); |
521 } else { | 522 } else { |
522 initial_value = | 523 initial_value = |
523 Compiler::GetSharedFunctionInfo(func, info->script(), info); | 524 Compiler::GetSharedFunctionInfo(func, info->script(), info); |
524 } | 525 } |
525 | 526 |
526 // Return a null handle if any initial values can't be created. Caller | 527 // Return a null handle if any initial values can't be created. Caller |
527 // will set stack overflow. | 528 // will set stack overflow. |
528 if (initial_value.is_null()) return Handle<FixedArray>(); | 529 if (initial_value.is_null()) return Handle<FixedArray>(); |
529 | 530 |
530 data->set(array_index++, *declaration.name); | 531 data->set(array_index++, *declaration.name); |
531 data->set(array_index++, Smi::FromInt(declaration.slot.ToInt())); | 532 data->set(array_index++, Smi::FromInt(declaration.slot.ToInt())); |
533 if (declaration.literal_slot.IsInvalid()) { | |
Michael Starzinger
2017/01/17 12:48:21
nit: We could pull out the case distinction into a
mvstanton
2017/01/17 13:04:39
Good idea, thanks!
| |
534 data->set(array_index++, info->isolate()->heap()->undefined_value()); | |
535 } else { | |
536 data->set(array_index++, | |
537 Smi::FromInt(declaration.literal_slot.ToInt())); | |
538 } | |
532 data->set(array_index++, *initial_value); | 539 data->set(array_index++, *initial_value); |
533 } | 540 } |
534 return data; | 541 return data; |
535 } | 542 } |
536 | 543 |
537 size_t constant_pool_entry() { | 544 size_t constant_pool_entry() { |
538 DCHECK(has_constant_pool_entry_); | 545 DCHECK(has_constant_pool_entry_); |
539 return constant_pool_entry_; | 546 return constant_pool_entry_; |
540 } | 547 } |
541 | 548 |
542 void set_constant_pool_entry(size_t constant_pool_entry) { | 549 void set_constant_pool_entry(size_t constant_pool_entry) { |
543 DCHECK(!empty()); | 550 DCHECK(!empty()); |
544 DCHECK(!has_constant_pool_entry_); | 551 DCHECK(!has_constant_pool_entry_); |
545 constant_pool_entry_ = constant_pool_entry; | 552 constant_pool_entry_ = constant_pool_entry; |
546 has_constant_pool_entry_ = true; | 553 has_constant_pool_entry_ = true; |
547 } | 554 } |
548 | 555 |
549 bool empty() { return declarations_.empty(); } | 556 bool empty() { return declarations_.empty(); } |
550 | 557 |
551 private: | 558 private: |
552 struct Declaration { | 559 struct Declaration { |
553 Declaration() : slot(FeedbackVectorSlot::Invalid()), func(nullptr) {} | 560 Declaration() : slot(FeedbackVectorSlot::Invalid()), func(nullptr) {} |
554 Declaration(Handle<String> name, FeedbackVectorSlot slot, | 561 Declaration(Handle<String> name, FeedbackVectorSlot slot, |
562 FeedbackVectorSlot literal_slot, FunctionLiteral* func) | |
563 : name(name), slot(slot), literal_slot(literal_slot), func(func) {} | |
564 Declaration(Handle<String> name, FeedbackVectorSlot slot, | |
555 FunctionLiteral* func) | 565 FunctionLiteral* func) |
556 : name(name), slot(slot), func(func) {} | 566 : name(name), slot(slot), func(func) {} |
Michael Starzinger
2017/01/17 12:48:21
nit: Let's explicitly initialize the {literal_slot
mvstanton
2017/01/17 13:04:39
Done.
| |
557 | 567 |
558 Handle<String> name; | 568 Handle<String> name; |
559 FeedbackVectorSlot slot; | 569 FeedbackVectorSlot slot; |
570 FeedbackVectorSlot literal_slot; | |
560 FunctionLiteral* func; | 571 FunctionLiteral* func; |
561 }; | 572 }; |
562 ZoneVector<Declaration> declarations_; | 573 ZoneVector<Declaration> declarations_; |
563 size_t constant_pool_entry_; | 574 size_t constant_pool_entry_; |
564 bool has_constant_pool_entry_; | 575 bool has_constant_pool_entry_; |
565 }; | 576 }; |
566 | 577 |
567 BytecodeGenerator::BytecodeGenerator(CompilationInfo* info) | 578 BytecodeGenerator::BytecodeGenerator(CompilationInfo* info) |
568 : zone_(info->zone()), | 579 : zone_(info->zone()), |
569 builder_(new (zone()) BytecodeArrayBuilder( | 580 builder_(new (zone()) BytecodeArrayBuilder( |
(...skipping 289 matching lines...) Loading... | |
859 break; | 870 break; |
860 } | 871 } |
861 } | 872 } |
862 | 873 |
863 void BytecodeGenerator::VisitFunctionDeclaration(FunctionDeclaration* decl) { | 874 void BytecodeGenerator::VisitFunctionDeclaration(FunctionDeclaration* decl) { |
864 Variable* variable = decl->proxy()->var(); | 875 Variable* variable = decl->proxy()->var(); |
865 DCHECK(variable->mode() == LET || variable->mode() == VAR); | 876 DCHECK(variable->mode() == LET || variable->mode() == VAR); |
866 switch (variable->location()) { | 877 switch (variable->location()) { |
867 case VariableLocation::UNALLOCATED: { | 878 case VariableLocation::UNALLOCATED: { |
868 FeedbackVectorSlot slot = decl->proxy()->VariableFeedbackSlot(); | 879 FeedbackVectorSlot slot = decl->proxy()->VariableFeedbackSlot(); |
869 globals_builder()->AddFunctionDeclaration(variable->name(), slot, | 880 globals_builder()->AddFunctionDeclaration( |
870 decl->fun()); | 881 variable->name(), slot, decl->fun()->LiteralFeedbackSlot(), |
882 decl->fun()); | |
871 break; | 883 break; |
872 } | 884 } |
873 case VariableLocation::PARAMETER: | 885 case VariableLocation::PARAMETER: |
874 case VariableLocation::LOCAL: { | 886 case VariableLocation::LOCAL: { |
875 VisitForAccumulatorValue(decl->fun()); | 887 VisitForAccumulatorValue(decl->fun()); |
876 BuildVariableAssignment(variable, Token::INIT, | 888 BuildVariableAssignment(variable, Token::INIT, |
877 FeedbackVectorSlot::Invalid(), | 889 FeedbackVectorSlot::Invalid(), |
878 HoleCheckMode::kElided); | 890 HoleCheckMode::kElided); |
879 break; | 891 break; |
880 } | 892 } |
(...skipping 2440 matching lines...) Loading... | |
3321 } | 3333 } |
3322 | 3334 |
3323 Runtime::FunctionId BytecodeGenerator::StoreKeyedToSuperRuntimeId() { | 3335 Runtime::FunctionId BytecodeGenerator::StoreKeyedToSuperRuntimeId() { |
3324 return is_strict(language_mode()) ? Runtime::kStoreKeyedToSuper_Strict | 3336 return is_strict(language_mode()) ? Runtime::kStoreKeyedToSuper_Strict |
3325 : Runtime::kStoreKeyedToSuper_Sloppy; | 3337 : Runtime::kStoreKeyedToSuper_Sloppy; |
3326 } | 3338 } |
3327 | 3339 |
3328 } // namespace interpreter | 3340 } // namespace interpreter |
3329 } // namespace internal | 3341 } // namespace internal |
3330 } // namespace v8 | 3342 } // namespace v8 |
OLD | NEW |