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 |