| 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...) Expand 10 before | Expand all | Expand 10 after 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, | |
| 502 FunctionLiteral* func) { | 501 FunctionLiteral* func) { |
| 503 DCHECK(!slot.IsInvalid()); | 502 DCHECK(!slot.IsInvalid()); |
| 504 declarations_.push_back(Declaration(name, slot, literal_slot, func)); | 503 declarations_.push_back(Declaration(name, slot, func)); |
| 505 } | 504 } |
| 506 | 505 |
| 507 void AddUndefinedDeclaration(Handle<String> name, FeedbackVectorSlot slot) { | 506 void AddUndefinedDeclaration(Handle<String> name, FeedbackVectorSlot slot) { |
| 508 DCHECK(!slot.IsInvalid()); | 507 DCHECK(!slot.IsInvalid()); |
| 509 declarations_.push_back(Declaration(name, slot, nullptr)); | 508 declarations_.push_back(Declaration(name, slot, nullptr)); |
| 510 } | 509 } |
| 511 | 510 |
| 512 Handle<FixedArray> AllocateDeclarations(CompilationInfo* info) { | 511 Handle<FixedArray> AllocateDeclarations(CompilationInfo* info) { |
| 513 DCHECK(has_constant_pool_entry_); | 512 DCHECK(has_constant_pool_entry_); |
| 514 int array_index = 0; | 513 int array_index = 0; |
| 515 Handle<FixedArray> data = info->isolate()->factory()->NewFixedArray( | 514 Handle<FixedArray> data = info->isolate()->factory()->NewFixedArray( |
| 516 static_cast<int>(declarations_.size() * 4), TENURED); | 515 static_cast<int>(declarations_.size() * 3), TENURED); |
| 517 for (const Declaration& declaration : declarations_) { | 516 for (const Declaration& declaration : declarations_) { |
| 518 FunctionLiteral* func = declaration.func; | 517 FunctionLiteral* func = declaration.func; |
| 519 Handle<Object> initial_value; | 518 Handle<Object> initial_value; |
| 520 if (func == nullptr) { | 519 if (func == nullptr) { |
| 521 initial_value = info->isolate()->factory()->undefined_value(); | 520 initial_value = info->isolate()->factory()->undefined_value(); |
| 522 } else { | 521 } else { |
| 523 initial_value = | 522 initial_value = |
| 524 Compiler::GetSharedFunctionInfo(func, info->script(), info); | 523 Compiler::GetSharedFunctionInfo(func, info->script(), info); |
| 525 } | 524 } |
| 526 | 525 |
| 527 // Return a null handle if any initial values can't be created. Caller | 526 // Return a null handle if any initial values can't be created. Caller |
| 528 // will set stack overflow. | 527 // will set stack overflow. |
| 529 if (initial_value.is_null()) return Handle<FixedArray>(); | 528 if (initial_value.is_null()) return Handle<FixedArray>(); |
| 530 | 529 |
| 531 data->set(array_index++, *declaration.name); | 530 data->set(array_index++, *declaration.name); |
| 532 data->set(array_index++, Smi::FromInt(declaration.slot.ToInt())); | 531 data->set(array_index++, Smi::FromInt(declaration.slot.ToInt())); |
| 533 Object* undefined_or_literal_slot; | |
| 534 if (declaration.literal_slot.IsInvalid()) { | |
| 535 undefined_or_literal_slot = info->isolate()->heap()->undefined_value(); | |
| 536 } else { | |
| 537 undefined_or_literal_slot = | |
| 538 Smi::FromInt(declaration.literal_slot.ToInt()); | |
| 539 } | |
| 540 data->set(array_index++, undefined_or_literal_slot); | |
| 541 data->set(array_index++, *initial_value); | 532 data->set(array_index++, *initial_value); |
| 542 } | 533 } |
| 543 return data; | 534 return data; |
| 544 } | 535 } |
| 545 | 536 |
| 546 size_t constant_pool_entry() { | 537 size_t constant_pool_entry() { |
| 547 DCHECK(has_constant_pool_entry_); | 538 DCHECK(has_constant_pool_entry_); |
| 548 return constant_pool_entry_; | 539 return constant_pool_entry_; |
| 549 } | 540 } |
| 550 | 541 |
| 551 void set_constant_pool_entry(size_t constant_pool_entry) { | 542 void set_constant_pool_entry(size_t constant_pool_entry) { |
| 552 DCHECK(!empty()); | 543 DCHECK(!empty()); |
| 553 DCHECK(!has_constant_pool_entry_); | 544 DCHECK(!has_constant_pool_entry_); |
| 554 constant_pool_entry_ = constant_pool_entry; | 545 constant_pool_entry_ = constant_pool_entry; |
| 555 has_constant_pool_entry_ = true; | 546 has_constant_pool_entry_ = true; |
| 556 } | 547 } |
| 557 | 548 |
| 558 bool empty() { return declarations_.empty(); } | 549 bool empty() { return declarations_.empty(); } |
| 559 | 550 |
| 560 private: | 551 private: |
| 561 struct Declaration { | 552 struct Declaration { |
| 562 Declaration() : slot(FeedbackVectorSlot::Invalid()), func(nullptr) {} | 553 Declaration() : slot(FeedbackVectorSlot::Invalid()), func(nullptr) {} |
| 563 Declaration(Handle<String> name, FeedbackVectorSlot slot, | 554 Declaration(Handle<String> name, FeedbackVectorSlot slot, |
| 564 FeedbackVectorSlot literal_slot, FunctionLiteral* func) | |
| 565 : name(name), slot(slot), literal_slot(literal_slot), func(func) {} | |
| 566 Declaration(Handle<String> name, FeedbackVectorSlot slot, | |
| 567 FunctionLiteral* func) | 555 FunctionLiteral* func) |
| 568 : name(name), | 556 : name(name), slot(slot), func(func) {} |
| 569 slot(slot), | |
| 570 literal_slot(FeedbackVectorSlot::Invalid()), | |
| 571 func(func) {} | |
| 572 | 557 |
| 573 Handle<String> name; | 558 Handle<String> name; |
| 574 FeedbackVectorSlot slot; | 559 FeedbackVectorSlot slot; |
| 575 FeedbackVectorSlot literal_slot; | |
| 576 FunctionLiteral* func; | 560 FunctionLiteral* func; |
| 577 }; | 561 }; |
| 578 ZoneVector<Declaration> declarations_; | 562 ZoneVector<Declaration> declarations_; |
| 579 size_t constant_pool_entry_; | 563 size_t constant_pool_entry_; |
| 580 bool has_constant_pool_entry_; | 564 bool has_constant_pool_entry_; |
| 581 }; | 565 }; |
| 582 | 566 |
| 583 BytecodeGenerator::BytecodeGenerator(CompilationInfo* info) | 567 BytecodeGenerator::BytecodeGenerator(CompilationInfo* info) |
| 584 : zone_(info->zone()), | 568 : zone_(info->zone()), |
| 585 builder_(new (zone()) BytecodeArrayBuilder( | 569 builder_(new (zone()) BytecodeArrayBuilder( |
| (...skipping 312 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 898 break; | 882 break; |
| 899 } | 883 } |
| 900 } | 884 } |
| 901 | 885 |
| 902 void BytecodeGenerator::VisitFunctionDeclaration(FunctionDeclaration* decl) { | 886 void BytecodeGenerator::VisitFunctionDeclaration(FunctionDeclaration* decl) { |
| 903 Variable* variable = decl->proxy()->var(); | 887 Variable* variable = decl->proxy()->var(); |
| 904 DCHECK(variable->mode() == LET || variable->mode() == VAR); | 888 DCHECK(variable->mode() == LET || variable->mode() == VAR); |
| 905 switch (variable->location()) { | 889 switch (variable->location()) { |
| 906 case VariableLocation::UNALLOCATED: { | 890 case VariableLocation::UNALLOCATED: { |
| 907 FeedbackVectorSlot slot = decl->proxy()->VariableFeedbackSlot(); | 891 FeedbackVectorSlot slot = decl->proxy()->VariableFeedbackSlot(); |
| 908 globals_builder()->AddFunctionDeclaration( | 892 globals_builder()->AddFunctionDeclaration(variable->name(), slot, |
| 909 variable->name(), slot, decl->fun()->LiteralFeedbackSlot(), | 893 decl->fun()); |
| 910 decl->fun()); | |
| 911 break; | 894 break; |
| 912 } | 895 } |
| 913 case VariableLocation::PARAMETER: | 896 case VariableLocation::PARAMETER: |
| 914 case VariableLocation::LOCAL: { | 897 case VariableLocation::LOCAL: { |
| 915 VisitForAccumulatorValue(decl->fun()); | 898 VisitForAccumulatorValue(decl->fun()); |
| 916 BuildVariableAssignment(variable, Token::INIT, | 899 BuildVariableAssignment(variable, Token::INIT, |
| 917 FeedbackVectorSlot::Invalid(), | 900 FeedbackVectorSlot::Invalid(), |
| 918 HoleCheckMode::kElided); | 901 HoleCheckMode::kElided); |
| 919 break; | 902 break; |
| 920 } | 903 } |
| (...skipping 2437 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3358 } | 3341 } |
| 3359 | 3342 |
| 3360 Runtime::FunctionId BytecodeGenerator::StoreKeyedToSuperRuntimeId() { | 3343 Runtime::FunctionId BytecodeGenerator::StoreKeyedToSuperRuntimeId() { |
| 3361 return is_strict(language_mode()) ? Runtime::kStoreKeyedToSuper_Strict | 3344 return is_strict(language_mode()) ? Runtime::kStoreKeyedToSuper_Strict |
| 3362 : Runtime::kStoreKeyedToSuper_Sloppy; | 3345 : Runtime::kStoreKeyedToSuper_Sloppy; |
| 3363 } | 3346 } |
| 3364 | 3347 |
| 3365 } // namespace interpreter | 3348 } // namespace interpreter |
| 3366 } // namespace internal | 3349 } // namespace internal |
| 3367 } // namespace v8 | 3350 } // namespace v8 |
| OLD | NEW |