Chromium Code Reviews| 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/scopes.h" | 7 #include "src/ast/scopes.h" |
| 8 #include "src/code-stubs.h" | 8 #include "src/code-stubs.h" |
| 9 #include "src/compiler.h" | 9 #include "src/compiler.h" |
| 10 #include "src/interpreter/bytecode-flags.h" | 10 #include "src/interpreter/bytecode-flags.h" |
| (...skipping 582 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 593 BytecodeLabels* else_labels_; | 593 BytecodeLabels* else_labels_; |
| 594 TestFallthrough fallthrough_; | 594 TestFallthrough fallthrough_; |
| 595 bool result_consumed_by_test_; | 595 bool result_consumed_by_test_; |
| 596 | 596 |
| 597 DISALLOW_COPY_AND_ASSIGN(TestResultScope); | 597 DISALLOW_COPY_AND_ASSIGN(TestResultScope); |
| 598 }; | 598 }; |
| 599 | 599 |
| 600 // Used to build a list of global declaration initial value pairs. | 600 // Used to build a list of global declaration initial value pairs. |
| 601 class BytecodeGenerator::GlobalDeclarationsBuilder final : public ZoneObject { | 601 class BytecodeGenerator::GlobalDeclarationsBuilder final : public ZoneObject { |
| 602 public: | 602 public: |
| 603 GlobalDeclarationsBuilder(Isolate* isolate, Zone* zone) | 603 explicit GlobalDeclarationsBuilder(Zone* zone) |
| 604 : isolate_(isolate), | 604 : declarations_(0, zone), |
| 605 declarations_(0, zone), | |
| 606 constant_pool_entry_(0), | 605 constant_pool_entry_(0), |
| 607 has_constant_pool_entry_(false) {} | 606 has_constant_pool_entry_(false) {} |
| 608 | 607 |
| 609 void AddFunctionDeclaration(FeedbackVectorSlot slot, FunctionLiteral* func) { | 608 void AddFunctionDeclaration(FeedbackVectorSlot slot, FunctionLiteral* func) { |
| 610 DCHECK(!slot.IsInvalid()); | 609 DCHECK(!slot.IsInvalid()); |
| 611 declarations_.push_back(std::make_pair(slot, func)); | 610 declarations_.push_back(std::make_pair(slot, func)); |
| 612 } | 611 } |
| 613 | 612 |
| 614 void AddUndefinedDeclaration(FeedbackVectorSlot slot) { | 613 void AddUndefinedDeclaration(FeedbackVectorSlot slot) { |
| 615 DCHECK(!slot.IsInvalid()); | 614 DCHECK(!slot.IsInvalid()); |
| 616 declarations_.push_back(std::make_pair(slot, nullptr)); | 615 declarations_.push_back(std::make_pair(slot, nullptr)); |
| 617 } | 616 } |
| 618 | 617 |
| 619 Handle<FixedArray> AllocateDeclarationPairs(CompilationInfo* info) { | 618 Handle<FixedArray> AllocateDeclarationPairs(CompilationInfo* info) { |
| 620 DCHECK(has_constant_pool_entry_); | 619 DCHECK(has_constant_pool_entry_); |
| 621 int array_index = 0; | 620 int array_index = 0; |
| 622 Handle<FixedArray> pairs = isolate_->factory()->NewFixedArray( | 621 Handle<FixedArray> pairs = info->isolate()->factory()->NewFixedArray( |
| 623 static_cast<int>(declarations_.size() * 2), TENURED); | 622 static_cast<int>(declarations_.size() * 2), TENURED); |
| 624 for (std::pair<FeedbackVectorSlot, FunctionLiteral*> declaration : | 623 for (std::pair<FeedbackVectorSlot, FunctionLiteral*> declaration : |
| 625 declarations_) { | 624 declarations_) { |
| 626 FunctionLiteral* func = declaration.second; | 625 FunctionLiteral* func = declaration.second; |
| 627 Handle<Object> initial_value; | 626 Handle<Object> initial_value; |
| 628 if (func == nullptr) { | 627 if (func == nullptr) { |
| 629 initial_value = isolate_->factory()->undefined_value(); | 628 initial_value = info->isolate()->factory()->undefined_value(); |
| 630 } else { | 629 } else { |
| 631 initial_value = | 630 initial_value = |
| 632 Compiler::GetSharedFunctionInfo(func, info->script(), info); | 631 Compiler::GetSharedFunctionInfo(func, info->script(), info); |
| 633 } | 632 } |
| 634 | 633 |
| 635 // Return a null handle if any initial values can't be created. Caller | 634 // Return a null handle if any initial values can't be created. Caller |
| 636 // will set stack overflow. | 635 // will set stack overflow. |
| 637 if (initial_value.is_null()) return Handle<FixedArray>(); | 636 if (initial_value.is_null()) return Handle<FixedArray>(); |
| 638 | 637 |
| 639 pairs->set(array_index++, Smi::FromInt(declaration.first.ToInt())); | 638 pairs->set(array_index++, Smi::FromInt(declaration.first.ToInt())); |
| (...skipping 10 matching lines...) Expand all Loading... | |
| 650 void set_constant_pool_entry(size_t constant_pool_entry) { | 649 void set_constant_pool_entry(size_t constant_pool_entry) { |
| 651 DCHECK(!empty()); | 650 DCHECK(!empty()); |
| 652 DCHECK(!has_constant_pool_entry_); | 651 DCHECK(!has_constant_pool_entry_); |
| 653 constant_pool_entry_ = constant_pool_entry; | 652 constant_pool_entry_ = constant_pool_entry; |
| 654 has_constant_pool_entry_ = true; | 653 has_constant_pool_entry_ = true; |
| 655 } | 654 } |
| 656 | 655 |
| 657 bool empty() { return declarations_.empty(); } | 656 bool empty() { return declarations_.empty(); } |
| 658 | 657 |
| 659 private: | 658 private: |
| 660 Isolate* isolate_; | |
| 661 ZoneVector<std::pair<FeedbackVectorSlot, FunctionLiteral*>> declarations_; | 659 ZoneVector<std::pair<FeedbackVectorSlot, FunctionLiteral*>> declarations_; |
| 662 size_t constant_pool_entry_; | 660 size_t constant_pool_entry_; |
| 663 bool has_constant_pool_entry_; | 661 bool has_constant_pool_entry_; |
| 664 }; | 662 }; |
| 665 | 663 |
| 666 BytecodeGenerator::BytecodeGenerator(CompilationInfo* info) | 664 BytecodeGenerator::BytecodeGenerator(CompilationInfo* info) |
| 667 : isolate_(info->isolate()), | 665 : zone_(info->zone()), |
| 668 zone_(info->zone()), | |
| 669 builder_(new (zone()) BytecodeArrayBuilder( | 666 builder_(new (zone()) BytecodeArrayBuilder( |
| 670 info->isolate(), info->zone(), info->num_parameters_including_this(), | 667 info->isolate(), info->zone(), info->num_parameters_including_this(), |
| 671 info->scope()->MaxNestedContextChainLength(), | 668 info->scope()->MaxNestedContextChainLength(), |
| 672 info->scope()->num_stack_slots(), info->literal(), | 669 info->scope()->num_stack_slots(), info->literal(), |
| 673 info->SourcePositionRecordingMode())), | 670 info->SourcePositionRecordingMode())), |
| 674 info_(info), | 671 info_(info), |
| 675 scope_(info->scope()), | 672 scope_(info->scope()), |
| 676 globals_builder_(new (zone()) GlobalDeclarationsBuilder(info->isolate(), | 673 isolate_access_allowed_(true), |
|
Michael Starzinger
2016/08/16 12:26:50
nit: Field should no longer be required. Lets drop
rmcilroy
2016/08/16 14:22:30
Oops, done.
| |
| 677 info->zone())), | 674 globals_builder_(new (zone()) GlobalDeclarationsBuilder(info->zone())), |
| 678 global_declarations_(0, info->zone()), | 675 global_declarations_(0, info->zone()), |
| 679 function_literals_(0, info->zone()), | 676 function_literals_(0, info->zone()), |
| 680 native_function_literals_(0, info->zone()), | 677 native_function_literals_(0, info->zone()), |
| 681 execution_control_(nullptr), | 678 execution_control_(nullptr), |
| 682 execution_context_(nullptr), | 679 execution_context_(nullptr), |
| 683 execution_result_(nullptr), | 680 execution_result_(nullptr), |
| 684 register_allocator_(nullptr), | 681 register_allocator_(nullptr), |
| 685 generator_resume_points_(info->literal()->yield_count(), info->zone()), | 682 generator_resume_points_(info->literal()->yield_count(), info->zone()), |
| 686 generator_state_(), | 683 generator_state_(), |
| 687 loop_depth_(0) { | 684 loop_depth_(0), |
| 688 InitializeAstVisitor(isolate()->stack_guard()->real_climit()); | 685 home_object_symbol_(info->isolate()->factory()->home_object_symbol()), |
| 686 prototype_string_(info->isolate()->factory()->prototype_string()) { | |
| 687 InitializeAstVisitor(info->isolate()->stack_guard()->real_climit()); | |
| 689 } | 688 } |
| 690 | 689 |
| 691 Handle<BytecodeArray> BytecodeGenerator::MakeBytecode() { | 690 Handle<BytecodeArray> BytecodeGenerator::MakeBytecode(Isolate* isolate) { |
| 692 // Create an inner HandleScope to avoid unnecessarily canonicalizing handles | 691 // Create an inner HandleScope to avoid unnecessarily canonicalizing handles |
| 693 // created as part of bytecode finalization. | 692 // created as part of bytecode finalization. |
| 694 HandleScope scope(isolate()); | 693 HandleScope scope(isolate); |
| 695 | 694 |
| 696 GenerateBytecode(); | 695 GenerateBytecode(); |
| 697 FinalizeBytecode(); | 696 FinalizeBytecode(isolate); |
| 698 | 697 |
| 699 if (HasStackOverflow()) return Handle<BytecodeArray>(); | 698 if (HasStackOverflow()) return Handle<BytecodeArray>(); |
| 700 | 699 |
| 701 return scope.CloseAndEscape(builder()->ToBytecodeArray()); | 700 return scope.CloseAndEscape(builder()->ToBytecodeArray(isolate)); |
| 702 } | 701 } |
| 703 | 702 |
| 704 void BytecodeGenerator::FinalizeBytecode() { | 703 void BytecodeGenerator::FinalizeBytecode(Isolate* isolate) { |
| 705 // Build global declaration pair arrays. | 704 // Build global declaration pair arrays. |
| 706 for (GlobalDeclarationsBuilder* globals_builder : global_declarations_) { | 705 for (GlobalDeclarationsBuilder* globals_builder : global_declarations_) { |
| 707 Handle<FixedArray> declarations = | 706 Handle<FixedArray> declarations = |
| 708 globals_builder->AllocateDeclarationPairs(info()); | 707 globals_builder->AllocateDeclarationPairs(info()); |
| 709 if (declarations.is_null()) return SetStackOverflow(); | 708 if (declarations.is_null()) return SetStackOverflow(); |
| 710 builder()->InsertConstantPoolEntryAt(globals_builder->constant_pool_entry(), | 709 builder()->InsertConstantPoolEntryAt(globals_builder->constant_pool_entry(), |
| 711 declarations); | 710 declarations); |
| 712 } | 711 } |
| 713 | 712 |
| 714 // Find or build shared function infos. | 713 // Find or build shared function infos. |
| (...skipping 300 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1015 builder() | 1014 builder() |
| 1016 ->LoadConstantPoolEntry(globals_builder()->constant_pool_entry()) | 1015 ->LoadConstantPoolEntry(globals_builder()->constant_pool_entry()) |
| 1017 .StoreAccumulatorInRegister(pairs) | 1016 .StoreAccumulatorInRegister(pairs) |
| 1018 .LoadLiteral(Smi::FromInt(encoded_flags)) | 1017 .LoadLiteral(Smi::FromInt(encoded_flags)) |
| 1019 .StoreAccumulatorInRegister(flags) | 1018 .StoreAccumulatorInRegister(flags) |
| 1020 .MoveRegister(Register::function_closure(), function) | 1019 .MoveRegister(Register::function_closure(), function) |
| 1021 .CallRuntime(Runtime::kDeclareGlobalsForInterpreter, pairs, 3); | 1020 .CallRuntime(Runtime::kDeclareGlobalsForInterpreter, pairs, 3); |
| 1022 | 1021 |
| 1023 // Push and reset globals builder. | 1022 // Push and reset globals builder. |
| 1024 global_declarations_.push_back(globals_builder()); | 1023 global_declarations_.push_back(globals_builder()); |
| 1025 globals_builder_ = new (zone()) GlobalDeclarationsBuilder(isolate(), zone()); | 1024 globals_builder_ = new (zone()) GlobalDeclarationsBuilder(zone()); |
| 1026 } | 1025 } |
| 1027 | 1026 |
| 1028 void BytecodeGenerator::VisitStatements(ZoneList<Statement*>* statements) { | 1027 void BytecodeGenerator::VisitStatements(ZoneList<Statement*>* statements) { |
| 1029 for (int i = 0; i < statements->length(); i++) { | 1028 for (int i = 0; i < statements->length(); i++) { |
| 1030 // Allocate an outer register allocations scope for the statement. | 1029 // Allocate an outer register allocations scope for the statement. |
| 1031 RegisterAllocationScope allocation_scope(this); | 1030 RegisterAllocationScope allocation_scope(this); |
| 1032 Statement* stmt = statements->at(i); | 1031 Statement* stmt = statements->at(i); |
| 1033 Visit(stmt); | 1032 Visit(stmt); |
| 1034 if (stmt->IsJump()) break; | 1033 if (stmt->IsJump()) break; |
| 1035 } | 1034 } |
| (...skipping 451 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1487 execution_result()->SetResultInAccumulator(); | 1486 execution_result()->SetResultInAccumulator(); |
| 1488 } | 1487 } |
| 1489 | 1488 |
| 1490 void BytecodeGenerator::VisitClassLiteral(ClassLiteral* expr) { | 1489 void BytecodeGenerator::VisitClassLiteral(ClassLiteral* expr) { |
| 1491 VisitClassLiteralForRuntimeDefinition(expr); | 1490 VisitClassLiteralForRuntimeDefinition(expr); |
| 1492 | 1491 |
| 1493 // Load the "prototype" from the constructor. | 1492 // Load the "prototype" from the constructor. |
| 1494 register_allocator()->PrepareForConsecutiveAllocations(2); | 1493 register_allocator()->PrepareForConsecutiveAllocations(2); |
| 1495 Register literal = register_allocator()->NextConsecutiveRegister(); | 1494 Register literal = register_allocator()->NextConsecutiveRegister(); |
| 1496 Register prototype = register_allocator()->NextConsecutiveRegister(); | 1495 Register prototype = register_allocator()->NextConsecutiveRegister(); |
| 1497 Handle<String> name = isolate()->factory()->prototype_string(); | |
| 1498 FeedbackVectorSlot slot = expr->PrototypeSlot(); | 1496 FeedbackVectorSlot slot = expr->PrototypeSlot(); |
| 1499 builder() | 1497 builder() |
| 1500 ->StoreAccumulatorInRegister(literal) | 1498 ->StoreAccumulatorInRegister(literal) |
| 1501 .LoadNamedProperty(literal, name, feedback_index(slot)) | 1499 .LoadNamedProperty(literal, prototype_string(), feedback_index(slot)) |
| 1502 .StoreAccumulatorInRegister(prototype); | 1500 .StoreAccumulatorInRegister(prototype); |
| 1503 | 1501 |
| 1504 VisitClassLiteralProperties(expr, literal, prototype); | 1502 VisitClassLiteralProperties(expr, literal, prototype); |
| 1505 builder()->CallRuntime(Runtime::kToFastProperties, literal, 1); | 1503 builder()->CallRuntime(Runtime::kToFastProperties, literal, 1); |
| 1506 // Assign to class variable. | 1504 // Assign to class variable. |
| 1507 if (expr->class_variable_proxy() != nullptr) { | 1505 if (expr->class_variable_proxy() != nullptr) { |
| 1508 Variable* var = expr->class_variable_proxy()->var(); | 1506 Variable* var = expr->class_variable_proxy()->var(); |
| 1509 FeedbackVectorSlot slot = expr->NeedsProxySlot() | 1507 FeedbackVectorSlot slot = expr->NeedsProxySlot() |
| 1510 ? expr->ProxySlot() | 1508 ? expr->ProxySlot() |
| 1511 : FeedbackVectorSlot::Invalid(); | 1509 : FeedbackVectorSlot::Invalid(); |
| (...skipping 97 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1609 break; | 1607 break; |
| 1610 } | 1608 } |
| 1611 } | 1609 } |
| 1612 } | 1610 } |
| 1613 } | 1611 } |
| 1614 | 1612 |
| 1615 void BytecodeGenerator::VisitClassLiteralStaticPrototypeWithComputedName( | 1613 void BytecodeGenerator::VisitClassLiteralStaticPrototypeWithComputedName( |
| 1616 Register key) { | 1614 Register key) { |
| 1617 BytecodeLabel done; | 1615 BytecodeLabel done; |
| 1618 builder() | 1616 builder() |
| 1619 ->LoadLiteral(isolate()->factory()->prototype_string()) | 1617 ->LoadLiteral(prototype_string()) |
| 1620 .CompareOperation(Token::Value::EQ_STRICT, key) | 1618 .CompareOperation(Token::Value::EQ_STRICT, key) |
| 1621 .JumpIfFalse(&done) | 1619 .JumpIfFalse(&done) |
| 1622 .CallRuntime(Runtime::kThrowStaticPrototypeError, Register(0), 0) | 1620 .CallRuntime(Runtime::kThrowStaticPrototypeError, Register(0), 0) |
| 1623 .Bind(&done); | 1621 .Bind(&done); |
| 1624 } | 1622 } |
| 1625 | 1623 |
| 1626 void BytecodeGenerator::VisitNativeFunctionLiteral( | 1624 void BytecodeGenerator::VisitNativeFunctionLiteral( |
| 1627 NativeFunctionLiteral* expr) { | 1625 NativeFunctionLiteral* expr) { |
| 1628 size_t entry = builder()->AllocateConstantPoolEntry(); | 1626 size_t entry = builder()->AllocateConstantPoolEntry(); |
| 1629 builder()->CreateClosure(entry, NOT_TENURED); | 1627 builder()->CreateClosure(entry, NOT_TENURED); |
| (...skipping 1532 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 3162 | 3160 |
| 3163 // Allocate a new local context. | 3161 // Allocate a new local context. |
| 3164 if (scope->is_script_scope()) { | 3162 if (scope->is_script_scope()) { |
| 3165 RegisterAllocationScope register_scope(this); | 3163 RegisterAllocationScope register_scope(this); |
| 3166 Register closure = register_allocator()->NewRegister(); | 3164 Register closure = register_allocator()->NewRegister(); |
| 3167 Register scope_info = register_allocator()->NewRegister(); | 3165 Register scope_info = register_allocator()->NewRegister(); |
| 3168 DCHECK(Register::AreContiguous(closure, scope_info)); | 3166 DCHECK(Register::AreContiguous(closure, scope_info)); |
| 3169 builder() | 3167 builder() |
| 3170 ->LoadAccumulatorWithRegister(Register::function_closure()) | 3168 ->LoadAccumulatorWithRegister(Register::function_closure()) |
| 3171 .StoreAccumulatorInRegister(closure) | 3169 .StoreAccumulatorInRegister(closure) |
| 3172 .LoadLiteral(scope->GetScopeInfo(isolate())) | 3170 .LoadLiteral(scope->scope_info()) |
| 3173 .StoreAccumulatorInRegister(scope_info) | 3171 .StoreAccumulatorInRegister(scope_info) |
| 3174 .CallRuntime(Runtime::kNewScriptContext, closure, 2); | 3172 .CallRuntime(Runtime::kNewScriptContext, closure, 2); |
| 3175 } else { | 3173 } else { |
| 3176 int slot_count = scope->num_heap_slots() - Context::MIN_CONTEXT_SLOTS; | 3174 int slot_count = scope->num_heap_slots() - Context::MIN_CONTEXT_SLOTS; |
| 3177 builder()->CreateFunctionContext(slot_count); | 3175 builder()->CreateFunctionContext(slot_count); |
| 3178 } | 3176 } |
| 3179 execution_result()->SetResultInAccumulator(); | 3177 execution_result()->SetResultInAccumulator(); |
| 3180 } | 3178 } |
| 3181 | 3179 |
| 3182 void BytecodeGenerator::VisitBuildLocalActivationContext() { | 3180 void BytecodeGenerator::VisitBuildLocalActivationContext() { |
| (...skipping 27 matching lines...) Expand all Loading... | |
| 3210 void BytecodeGenerator::VisitNewLocalBlockContext(Scope* scope) { | 3208 void BytecodeGenerator::VisitNewLocalBlockContext(Scope* scope) { |
| 3211 AccumulatorResultScope accumulator_execution_result(this); | 3209 AccumulatorResultScope accumulator_execution_result(this); |
| 3212 DCHECK(scope->is_block_scope()); | 3210 DCHECK(scope->is_block_scope()); |
| 3213 | 3211 |
| 3214 // Allocate a new local block context. | 3212 // Allocate a new local block context. |
| 3215 register_allocator()->PrepareForConsecutiveAllocations(2); | 3213 register_allocator()->PrepareForConsecutiveAllocations(2); |
| 3216 Register scope_info = register_allocator()->NextConsecutiveRegister(); | 3214 Register scope_info = register_allocator()->NextConsecutiveRegister(); |
| 3217 Register closure = register_allocator()->NextConsecutiveRegister(); | 3215 Register closure = register_allocator()->NextConsecutiveRegister(); |
| 3218 | 3216 |
| 3219 builder() | 3217 builder() |
| 3220 ->LoadLiteral(scope->GetScopeInfo(isolate())) | 3218 ->LoadLiteral(scope->scope_info()) |
| 3221 .StoreAccumulatorInRegister(scope_info); | 3219 .StoreAccumulatorInRegister(scope_info); |
| 3222 VisitFunctionClosureForContext(); | 3220 VisitFunctionClosureForContext(); |
| 3223 builder() | 3221 builder() |
| 3224 ->StoreAccumulatorInRegister(closure) | 3222 ->StoreAccumulatorInRegister(closure) |
| 3225 .CallRuntime(Runtime::kPushBlockContext, scope_info, 2); | 3223 .CallRuntime(Runtime::kPushBlockContext, scope_info, 2); |
| 3226 execution_result()->SetResultInAccumulator(); | 3224 execution_result()->SetResultInAccumulator(); |
| 3227 } | 3225 } |
| 3228 | 3226 |
| 3229 void BytecodeGenerator::VisitNewLocalWithContext() { | 3227 void BytecodeGenerator::VisitNewLocalWithContext() { |
| 3230 AccumulatorResultScope accumulator_execution_result(this); | 3228 AccumulatorResultScope accumulator_execution_result(this); |
| (...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 3270 builder()->StoreAccumulatorInRegister(value_out); | 3268 builder()->StoreAccumulatorInRegister(value_out); |
| 3271 VisitSetHomeObject(value_out, home_object, property); | 3269 VisitSetHomeObject(value_out, home_object, property); |
| 3272 } | 3270 } |
| 3273 } | 3271 } |
| 3274 | 3272 |
| 3275 void BytecodeGenerator::VisitSetHomeObject(Register value, Register home_object, | 3273 void BytecodeGenerator::VisitSetHomeObject(Register value, Register home_object, |
| 3276 ObjectLiteralProperty* property, | 3274 ObjectLiteralProperty* property, |
| 3277 int slot_number) { | 3275 int slot_number) { |
| 3278 Expression* expr = property->value(); | 3276 Expression* expr = property->value(); |
| 3279 if (FunctionLiteral::NeedsHomeObject(expr)) { | 3277 if (FunctionLiteral::NeedsHomeObject(expr)) { |
| 3280 Handle<Name> name = isolate()->factory()->home_object_symbol(); | |
| 3281 FeedbackVectorSlot slot = property->GetSlot(slot_number); | 3278 FeedbackVectorSlot slot = property->GetSlot(slot_number); |
| 3282 builder() | 3279 builder() |
| 3283 ->LoadAccumulatorWithRegister(home_object) | 3280 ->LoadAccumulatorWithRegister(home_object) |
| 3284 .StoreNamedProperty(value, name, feedback_index(slot), language_mode()); | 3281 .StoreNamedProperty(value, home_object_symbol(), feedback_index(slot), |
| 3282 language_mode()); | |
| 3285 } | 3283 } |
| 3286 } | 3284 } |
| 3287 | 3285 |
| 3288 void BytecodeGenerator::VisitArgumentsObject(Variable* variable) { | 3286 void BytecodeGenerator::VisitArgumentsObject(Variable* variable) { |
| 3289 if (variable == nullptr) return; | 3287 if (variable == nullptr) return; |
| 3290 | 3288 |
| 3291 DCHECK(variable->IsContextSlot() || variable->IsStackAllocated()); | 3289 DCHECK(variable->IsContextSlot() || variable->IsStackAllocated()); |
| 3292 | 3290 |
| 3293 // Allocate and initialize a new arguments object and assign to the | 3291 // Allocate and initialize a new arguments object and assign to the |
| 3294 // {arguments} variable. | 3292 // {arguments} variable. |
| (...skipping 136 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 3431 return execution_context()->scope()->language_mode(); | 3429 return execution_context()->scope()->language_mode(); |
| 3432 } | 3430 } |
| 3433 | 3431 |
| 3434 int BytecodeGenerator::feedback_index(FeedbackVectorSlot slot) const { | 3432 int BytecodeGenerator::feedback_index(FeedbackVectorSlot slot) const { |
| 3435 return TypeFeedbackVector::GetIndex(slot); | 3433 return TypeFeedbackVector::GetIndex(slot); |
| 3436 } | 3434 } |
| 3437 | 3435 |
| 3438 } // namespace interpreter | 3436 } // namespace interpreter |
| 3439 } // namespace internal | 3437 } // namespace internal |
| 3440 } // namespace v8 | 3438 } // namespace v8 |
| OLD | NEW |