| OLD | NEW |
| 1 // Copyright 2012 the V8 project authors. All rights reserved. | 1 // Copyright 2012 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/v8.h" | 5 #include "src/v8.h" |
| 6 | 6 |
| 7 #if V8_TARGET_ARCH_X64 | 7 #if V8_TARGET_ARCH_X64 |
| 8 | 8 |
| 9 #include "src/code-factory.h" | 9 #include "src/code-factory.h" |
| 10 #include "src/code-stubs.h" | 10 #include "src/code-stubs.h" |
| (...skipping 333 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 344 | 344 |
| 345 } else { | 345 } else { |
| 346 PrepareForBailoutForId(BailoutId::FunctionEntry(), NO_REGISTERS); | 346 PrepareForBailoutForId(BailoutId::FunctionEntry(), NO_REGISTERS); |
| 347 { Comment cmnt(masm_, "[ Declarations"); | 347 { Comment cmnt(masm_, "[ Declarations"); |
| 348 // For named function expressions, declare the function name as a | 348 // For named function expressions, declare the function name as a |
| 349 // constant. | 349 // constant. |
| 350 if (scope()->is_function_scope() && scope()->function() != NULL) { | 350 if (scope()->is_function_scope() && scope()->function() != NULL) { |
| 351 VariableDeclaration* function = scope()->function(); | 351 VariableDeclaration* function = scope()->function(); |
| 352 DCHECK(function->proxy()->var()->mode() == CONST || | 352 DCHECK(function->proxy()->var()->mode() == CONST || |
| 353 function->proxy()->var()->mode() == CONST_LEGACY); | 353 function->proxy()->var()->mode() == CONST_LEGACY); |
| 354 DCHECK(function->proxy()->var()->location() != Variable::UNALLOCATED); | 354 DCHECK(!function->proxy()->var()->IsUnallocatedOrGlobalSlot()); |
| 355 VisitVariableDeclaration(function); | 355 VisitVariableDeclaration(function); |
| 356 } | 356 } |
| 357 VisitDeclarations(scope()->declarations()); | 357 VisitDeclarations(scope()->declarations()); |
| 358 } | 358 } |
| 359 | 359 |
| 360 { Comment cmnt(masm_, "[ Stack check"); | 360 { Comment cmnt(masm_, "[ Stack check"); |
| 361 PrepareForBailoutForId(BailoutId::Declarations(), NO_REGISTERS); | 361 PrepareForBailoutForId(BailoutId::Declarations(), NO_REGISTERS); |
| 362 Label ok; | 362 Label ok; |
| 363 __ CompareRoot(rsp, Heap::kStackLimitRootIndex); | 363 __ CompareRoot(rsp, Heap::kStackLimitRootIndex); |
| 364 __ j(above_equal, &ok, Label::kNear); | 364 __ j(above_equal, &ok, Label::kNear); |
| (...skipping 472 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 837 void FullCodeGenerator::VisitVariableDeclaration( | 837 void FullCodeGenerator::VisitVariableDeclaration( |
| 838 VariableDeclaration* declaration) { | 838 VariableDeclaration* declaration) { |
| 839 // If it was not possible to allocate the variable at compile time, we | 839 // If it was not possible to allocate the variable at compile time, we |
| 840 // need to "declare" it at runtime to make sure it actually exists in the | 840 // need to "declare" it at runtime to make sure it actually exists in the |
| 841 // local context. | 841 // local context. |
| 842 VariableProxy* proxy = declaration->proxy(); | 842 VariableProxy* proxy = declaration->proxy(); |
| 843 VariableMode mode = declaration->mode(); | 843 VariableMode mode = declaration->mode(); |
| 844 Variable* variable = proxy->var(); | 844 Variable* variable = proxy->var(); |
| 845 bool hole_init = mode == LET || mode == CONST || mode == CONST_LEGACY; | 845 bool hole_init = mode == LET || mode == CONST || mode == CONST_LEGACY; |
| 846 switch (variable->location()) { | 846 switch (variable->location()) { |
| 847 case Variable::UNALLOCATED: | 847 case VariableLocation::GLOBAL: |
| 848 case VariableLocation::UNALLOCATED: |
| 848 globals_->Add(variable->name(), zone()); | 849 globals_->Add(variable->name(), zone()); |
| 849 globals_->Add(variable->binding_needs_init() | 850 globals_->Add(variable->binding_needs_init() |
| 850 ? isolate()->factory()->the_hole_value() | 851 ? isolate()->factory()->the_hole_value() |
| 851 : isolate()->factory()->undefined_value(), | 852 : isolate()->factory()->undefined_value(), |
| 852 zone()); | 853 zone()); |
| 853 break; | 854 break; |
| 854 | 855 |
| 855 case Variable::PARAMETER: | 856 case VariableLocation::PARAMETER: |
| 856 case Variable::LOCAL: | 857 case VariableLocation::LOCAL: |
| 857 if (hole_init) { | 858 if (hole_init) { |
| 858 Comment cmnt(masm_, "[ VariableDeclaration"); | 859 Comment cmnt(masm_, "[ VariableDeclaration"); |
| 859 __ LoadRoot(kScratchRegister, Heap::kTheHoleValueRootIndex); | 860 __ LoadRoot(kScratchRegister, Heap::kTheHoleValueRootIndex); |
| 860 __ movp(StackOperand(variable), kScratchRegister); | 861 __ movp(StackOperand(variable), kScratchRegister); |
| 861 } | 862 } |
| 862 break; | 863 break; |
| 863 | 864 |
| 864 case Variable::CONTEXT: | 865 case VariableLocation::CONTEXT: |
| 865 if (hole_init) { | 866 if (hole_init) { |
| 866 Comment cmnt(masm_, "[ VariableDeclaration"); | 867 Comment cmnt(masm_, "[ VariableDeclaration"); |
| 867 EmitDebugCheckDeclarationContext(variable); | 868 EmitDebugCheckDeclarationContext(variable); |
| 868 __ LoadRoot(kScratchRegister, Heap::kTheHoleValueRootIndex); | 869 __ LoadRoot(kScratchRegister, Heap::kTheHoleValueRootIndex); |
| 869 __ movp(ContextOperand(rsi, variable->index()), kScratchRegister); | 870 __ movp(ContextOperand(rsi, variable->index()), kScratchRegister); |
| 870 // No write barrier since the hole value is in old space. | 871 // No write barrier since the hole value is in old space. |
| 871 PrepareForBailoutForId(proxy->id(), NO_REGISTERS); | 872 PrepareForBailoutForId(proxy->id(), NO_REGISTERS); |
| 872 } | 873 } |
| 873 break; | 874 break; |
| 874 | 875 |
| 875 case Variable::LOOKUP: { | 876 case VariableLocation::LOOKUP: { |
| 876 Comment cmnt(masm_, "[ VariableDeclaration"); | 877 Comment cmnt(masm_, "[ VariableDeclaration"); |
| 877 __ Push(rsi); | 878 __ Push(rsi); |
| 878 __ Push(variable->name()); | 879 __ Push(variable->name()); |
| 879 // Declaration nodes are always introduced in one of four modes. | 880 // Declaration nodes are always introduced in one of four modes. |
| 880 DCHECK(IsDeclaredVariableMode(mode)); | 881 DCHECK(IsDeclaredVariableMode(mode)); |
| 881 PropertyAttributes attr = | 882 PropertyAttributes attr = |
| 882 IsImmutableVariableMode(mode) ? READ_ONLY : NONE; | 883 IsImmutableVariableMode(mode) ? READ_ONLY : NONE; |
| 883 __ Push(Smi::FromInt(attr)); | 884 __ Push(Smi::FromInt(attr)); |
| 884 // Push initial value, if any. | 885 // Push initial value, if any. |
| 885 // Note: For variables we must not push an initial value (such as | 886 // Note: For variables we must not push an initial value (such as |
| 886 // 'undefined') because we may have a (legal) redeclaration and we | 887 // 'undefined') because we may have a (legal) redeclaration and we |
| 887 // must not destroy the current value. | 888 // must not destroy the current value. |
| 888 if (hole_init) { | 889 if (hole_init) { |
| 889 __ PushRoot(Heap::kTheHoleValueRootIndex); | 890 __ PushRoot(Heap::kTheHoleValueRootIndex); |
| 890 } else { | 891 } else { |
| 891 __ Push(Smi::FromInt(0)); // Indicates no initial value. | 892 __ Push(Smi::FromInt(0)); // Indicates no initial value. |
| 892 } | 893 } |
| 893 __ CallRuntime(Runtime::kDeclareLookupSlot, 4); | 894 __ CallRuntime(Runtime::kDeclareLookupSlot, 4); |
| 894 break; | 895 break; |
| 895 } | 896 } |
| 896 } | 897 } |
| 897 } | 898 } |
| 898 | 899 |
| 899 | 900 |
| 900 void FullCodeGenerator::VisitFunctionDeclaration( | 901 void FullCodeGenerator::VisitFunctionDeclaration( |
| 901 FunctionDeclaration* declaration) { | 902 FunctionDeclaration* declaration) { |
| 902 VariableProxy* proxy = declaration->proxy(); | 903 VariableProxy* proxy = declaration->proxy(); |
| 903 Variable* variable = proxy->var(); | 904 Variable* variable = proxy->var(); |
| 904 switch (variable->location()) { | 905 switch (variable->location()) { |
| 905 case Variable::UNALLOCATED: { | 906 case VariableLocation::GLOBAL: |
| 907 case VariableLocation::UNALLOCATED: { |
| 906 globals_->Add(variable->name(), zone()); | 908 globals_->Add(variable->name(), zone()); |
| 907 Handle<SharedFunctionInfo> function = | 909 Handle<SharedFunctionInfo> function = |
| 908 Compiler::GetSharedFunctionInfo(declaration->fun(), script(), info_); | 910 Compiler::GetSharedFunctionInfo(declaration->fun(), script(), info_); |
| 909 // Check for stack-overflow exception. | 911 // Check for stack-overflow exception. |
| 910 if (function.is_null()) return SetStackOverflow(); | 912 if (function.is_null()) return SetStackOverflow(); |
| 911 globals_->Add(function, zone()); | 913 globals_->Add(function, zone()); |
| 912 break; | 914 break; |
| 913 } | 915 } |
| 914 | 916 |
| 915 case Variable::PARAMETER: | 917 case VariableLocation::PARAMETER: |
| 916 case Variable::LOCAL: { | 918 case VariableLocation::LOCAL: { |
| 917 Comment cmnt(masm_, "[ FunctionDeclaration"); | 919 Comment cmnt(masm_, "[ FunctionDeclaration"); |
| 918 VisitForAccumulatorValue(declaration->fun()); | 920 VisitForAccumulatorValue(declaration->fun()); |
| 919 __ movp(StackOperand(variable), result_register()); | 921 __ movp(StackOperand(variable), result_register()); |
| 920 break; | 922 break; |
| 921 } | 923 } |
| 922 | 924 |
| 923 case Variable::CONTEXT: { | 925 case VariableLocation::CONTEXT: { |
| 924 Comment cmnt(masm_, "[ FunctionDeclaration"); | 926 Comment cmnt(masm_, "[ FunctionDeclaration"); |
| 925 EmitDebugCheckDeclarationContext(variable); | 927 EmitDebugCheckDeclarationContext(variable); |
| 926 VisitForAccumulatorValue(declaration->fun()); | 928 VisitForAccumulatorValue(declaration->fun()); |
| 927 __ movp(ContextOperand(rsi, variable->index()), result_register()); | 929 __ movp(ContextOperand(rsi, variable->index()), result_register()); |
| 928 int offset = Context::SlotOffset(variable->index()); | 930 int offset = Context::SlotOffset(variable->index()); |
| 929 // We know that we have written a function, which is not a smi. | 931 // We know that we have written a function, which is not a smi. |
| 930 __ RecordWriteContextSlot(rsi, | 932 __ RecordWriteContextSlot(rsi, |
| 931 offset, | 933 offset, |
| 932 result_register(), | 934 result_register(), |
| 933 rcx, | 935 rcx, |
| 934 kDontSaveFPRegs, | 936 kDontSaveFPRegs, |
| 935 EMIT_REMEMBERED_SET, | 937 EMIT_REMEMBERED_SET, |
| 936 OMIT_SMI_CHECK); | 938 OMIT_SMI_CHECK); |
| 937 PrepareForBailoutForId(proxy->id(), NO_REGISTERS); | 939 PrepareForBailoutForId(proxy->id(), NO_REGISTERS); |
| 938 break; | 940 break; |
| 939 } | 941 } |
| 940 | 942 |
| 941 case Variable::LOOKUP: { | 943 case VariableLocation::LOOKUP: { |
| 942 Comment cmnt(masm_, "[ FunctionDeclaration"); | 944 Comment cmnt(masm_, "[ FunctionDeclaration"); |
| 943 __ Push(rsi); | 945 __ Push(rsi); |
| 944 __ Push(variable->name()); | 946 __ Push(variable->name()); |
| 945 __ Push(Smi::FromInt(NONE)); | 947 __ Push(Smi::FromInt(NONE)); |
| 946 VisitForStackValue(declaration->fun()); | 948 VisitForStackValue(declaration->fun()); |
| 947 __ CallRuntime(Runtime::kDeclareLookupSlot, 4); | 949 __ CallRuntime(Runtime::kDeclareLookupSlot, 4); |
| 948 break; | 950 break; |
| 949 } | 951 } |
| 950 } | 952 } |
| 951 } | 953 } |
| 952 | 954 |
| 953 | 955 |
| 954 void FullCodeGenerator::VisitImportDeclaration(ImportDeclaration* declaration) { | 956 void FullCodeGenerator::VisitImportDeclaration(ImportDeclaration* declaration) { |
| 955 VariableProxy* proxy = declaration->proxy(); | 957 VariableProxy* proxy = declaration->proxy(); |
| 956 Variable* variable = proxy->var(); | 958 Variable* variable = proxy->var(); |
| 957 switch (variable->location()) { | 959 switch (variable->location()) { |
| 958 case Variable::UNALLOCATED: | 960 case VariableLocation::UNALLOCATED: |
| 961 case VariableLocation::GLOBAL: |
| 959 // TODO(rossberg) | 962 // TODO(rossberg) |
| 960 break; | 963 break; |
| 961 | 964 |
| 962 case Variable::CONTEXT: { | 965 case VariableLocation::CONTEXT: { |
| 963 Comment cmnt(masm_, "[ ImportDeclaration"); | 966 Comment cmnt(masm_, "[ ImportDeclaration"); |
| 964 EmitDebugCheckDeclarationContext(variable); | 967 EmitDebugCheckDeclarationContext(variable); |
| 965 // TODO(rossberg) | 968 // TODO(rossberg) |
| 966 break; | 969 break; |
| 967 } | 970 } |
| 968 | 971 |
| 969 case Variable::PARAMETER: | 972 case VariableLocation::PARAMETER: |
| 970 case Variable::LOCAL: | 973 case VariableLocation::LOCAL: |
| 971 case Variable::LOOKUP: | 974 case VariableLocation::LOOKUP: |
| 972 UNREACHABLE(); | 975 UNREACHABLE(); |
| 973 } | 976 } |
| 974 } | 977 } |
| 975 | 978 |
| 976 | 979 |
| 977 void FullCodeGenerator::VisitExportDeclaration(ExportDeclaration* declaration) { | 980 void FullCodeGenerator::VisitExportDeclaration(ExportDeclaration* declaration) { |
| 978 // TODO(rossberg) | 981 // TODO(rossberg) |
| 979 } | 982 } |
| 980 | 983 |
| 981 | 984 |
| (...skipping 474 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1456 | 1459 |
| 1457 void FullCodeGenerator::EmitVariableLoad(VariableProxy* proxy) { | 1460 void FullCodeGenerator::EmitVariableLoad(VariableProxy* proxy) { |
| 1458 // Record position before possible IC call. | 1461 // Record position before possible IC call. |
| 1459 SetExpressionPosition(proxy); | 1462 SetExpressionPosition(proxy); |
| 1460 PrepareForBailoutForId(proxy->BeforeId(), NO_REGISTERS); | 1463 PrepareForBailoutForId(proxy->BeforeId(), NO_REGISTERS); |
| 1461 Variable* var = proxy->var(); | 1464 Variable* var = proxy->var(); |
| 1462 | 1465 |
| 1463 // Three cases: global variables, lookup variables, and all other types of | 1466 // Three cases: global variables, lookup variables, and all other types of |
| 1464 // variables. | 1467 // variables. |
| 1465 switch (var->location()) { | 1468 switch (var->location()) { |
| 1466 case Variable::UNALLOCATED: { | 1469 case VariableLocation::GLOBAL: |
| 1470 case VariableLocation::UNALLOCATED: { |
| 1467 Comment cmnt(masm_, "[ Global variable"); | 1471 Comment cmnt(masm_, "[ Global variable"); |
| 1468 __ Move(LoadDescriptor::NameRegister(), var->name()); | 1472 __ Move(LoadDescriptor::NameRegister(), var->name()); |
| 1469 __ movp(LoadDescriptor::ReceiverRegister(), GlobalObjectOperand()); | 1473 __ movp(LoadDescriptor::ReceiverRegister(), GlobalObjectOperand()); |
| 1470 __ Move(LoadDescriptor::SlotRegister(), | 1474 __ Move(LoadDescriptor::SlotRegister(), |
| 1471 SmiFromSlot(proxy->VariableFeedbackSlot())); | 1475 SmiFromSlot(proxy->VariableFeedbackSlot())); |
| 1472 CallGlobalLoadIC(var->name()); | 1476 CallGlobalLoadIC(var->name()); |
| 1473 context()->Plug(rax); | 1477 context()->Plug(rax); |
| 1474 break; | 1478 break; |
| 1475 } | 1479 } |
| 1476 | 1480 |
| 1477 case Variable::PARAMETER: | 1481 case VariableLocation::PARAMETER: |
| 1478 case Variable::LOCAL: | 1482 case VariableLocation::LOCAL: |
| 1479 case Variable::CONTEXT: { | 1483 case VariableLocation::CONTEXT: { |
| 1480 Comment cmnt(masm_, var->IsContextSlot() ? "[ Context slot" | 1484 Comment cmnt(masm_, var->IsContextSlot() ? "[ Context slot" |
| 1481 : "[ Stack slot"); | 1485 : "[ Stack slot"); |
| 1482 if (var->binding_needs_init()) { | 1486 if (var->binding_needs_init()) { |
| 1483 // var->scope() may be NULL when the proxy is located in eval code and | 1487 // var->scope() may be NULL when the proxy is located in eval code and |
| 1484 // refers to a potential outside binding. Currently those bindings are | 1488 // refers to a potential outside binding. Currently those bindings are |
| 1485 // always looked up dynamically, i.e. in that case | 1489 // always looked up dynamically, i.e. in that case |
| 1486 // var->location() == LOOKUP. | 1490 // var->location() == LOOKUP. |
| 1487 // always holds. | 1491 // always holds. |
| 1488 DCHECK(var->scope() != NULL); | 1492 DCHECK(var->scope() != NULL); |
| 1489 | 1493 |
| (...skipping 47 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1537 } | 1541 } |
| 1538 __ bind(&done); | 1542 __ bind(&done); |
| 1539 context()->Plug(rax); | 1543 context()->Plug(rax); |
| 1540 break; | 1544 break; |
| 1541 } | 1545 } |
| 1542 } | 1546 } |
| 1543 context()->Plug(var); | 1547 context()->Plug(var); |
| 1544 break; | 1548 break; |
| 1545 } | 1549 } |
| 1546 | 1550 |
| 1547 case Variable::LOOKUP: { | 1551 case VariableLocation::LOOKUP: { |
| 1548 Comment cmnt(masm_, "[ Lookup slot"); | 1552 Comment cmnt(masm_, "[ Lookup slot"); |
| 1549 Label done, slow; | 1553 Label done, slow; |
| 1550 // Generate code for loading from variables potentially shadowed | 1554 // Generate code for loading from variables potentially shadowed |
| 1551 // by eval-introduced variables. | 1555 // by eval-introduced variables. |
| 1552 EmitDynamicLookupFastCase(proxy, NOT_INSIDE_TYPEOF, &slow, &done); | 1556 EmitDynamicLookupFastCase(proxy, NOT_INSIDE_TYPEOF, &slow, &done); |
| 1553 __ bind(&slow); | 1557 __ bind(&slow); |
| 1554 __ Push(rsi); // Context. | 1558 __ Push(rsi); // Context. |
| 1555 __ Push(var->name()); | 1559 __ Push(var->name()); |
| 1556 __ CallRuntime(Runtime::kLoadLookupSlot, 2); | 1560 __ CallRuntime(Runtime::kLoadLookupSlot, 2); |
| 1557 __ bind(&done); | 1561 __ bind(&done); |
| (...skipping 1081 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2639 if (var->IsContextSlot()) { | 2643 if (var->IsContextSlot()) { |
| 2640 __ movp(rdx, rax); | 2644 __ movp(rdx, rax); |
| 2641 __ RecordWriteContextSlot( | 2645 __ RecordWriteContextSlot( |
| 2642 rcx, Context::SlotOffset(var->index()), rdx, rbx, kDontSaveFPRegs); | 2646 rcx, Context::SlotOffset(var->index()), rdx, rbx, kDontSaveFPRegs); |
| 2643 } | 2647 } |
| 2644 } | 2648 } |
| 2645 | 2649 |
| 2646 | 2650 |
| 2647 void FullCodeGenerator::EmitVariableAssignment(Variable* var, Token::Value op, | 2651 void FullCodeGenerator::EmitVariableAssignment(Variable* var, Token::Value op, |
| 2648 FeedbackVectorICSlot slot) { | 2652 FeedbackVectorICSlot slot) { |
| 2649 if (var->IsUnallocated()) { | 2653 if (var->IsUnallocatedOrGlobalSlot()) { |
| 2650 // Global var, const, or let. | 2654 // Global var, const, or let. |
| 2651 __ Move(StoreDescriptor::NameRegister(), var->name()); | 2655 __ Move(StoreDescriptor::NameRegister(), var->name()); |
| 2652 __ movp(StoreDescriptor::ReceiverRegister(), GlobalObjectOperand()); | 2656 __ movp(StoreDescriptor::ReceiverRegister(), GlobalObjectOperand()); |
| 2653 if (FLAG_vector_stores) EmitLoadStoreICSlot(slot); | 2657 if (FLAG_vector_stores) EmitLoadStoreICSlot(slot); |
| 2654 CallStoreIC(); | 2658 CallStoreIC(); |
| 2655 | 2659 |
| 2656 } else if (var->mode() == LET && op != Token::INIT_LET) { | 2660 } else if (var->mode() == LET && op != Token::INIT_LET) { |
| 2657 // Non-initializing assignment to let variable needs a write barrier. | 2661 // Non-initializing assignment to let variable needs a write barrier. |
| 2658 DCHECK(!var->IsLookupSlot()); | 2662 DCHECK(!var->IsLookupSlot()); |
| 2659 DCHECK(var->IsStackAllocated() || var->IsContextSlot()); | 2663 DCHECK(var->IsStackAllocated() || var->IsContextSlot()); |
| (...skipping 2086 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 4746 VisitForStackValue(property->key()); | 4750 VisitForStackValue(property->key()); |
| 4747 __ Push(Smi::FromInt(language_mode())); | 4751 __ Push(Smi::FromInt(language_mode())); |
| 4748 __ InvokeBuiltin(Builtins::DELETE, CALL_FUNCTION); | 4752 __ InvokeBuiltin(Builtins::DELETE, CALL_FUNCTION); |
| 4749 context()->Plug(rax); | 4753 context()->Plug(rax); |
| 4750 } else if (proxy != NULL) { | 4754 } else if (proxy != NULL) { |
| 4751 Variable* var = proxy->var(); | 4755 Variable* var = proxy->var(); |
| 4752 // Delete of an unqualified identifier is disallowed in strict mode but | 4756 // Delete of an unqualified identifier is disallowed in strict mode but |
| 4753 // "delete this" is allowed. | 4757 // "delete this" is allowed. |
| 4754 bool is_this = var->HasThisName(isolate()); | 4758 bool is_this = var->HasThisName(isolate()); |
| 4755 DCHECK(is_sloppy(language_mode()) || is_this); | 4759 DCHECK(is_sloppy(language_mode()) || is_this); |
| 4756 if (var->IsUnallocated()) { | 4760 if (var->IsUnallocatedOrGlobalSlot()) { |
| 4757 __ Push(GlobalObjectOperand()); | 4761 __ Push(GlobalObjectOperand()); |
| 4758 __ Push(var->name()); | 4762 __ Push(var->name()); |
| 4759 __ Push(Smi::FromInt(SLOPPY)); | 4763 __ Push(Smi::FromInt(SLOPPY)); |
| 4760 __ InvokeBuiltin(Builtins::DELETE, CALL_FUNCTION); | 4764 __ InvokeBuiltin(Builtins::DELETE, CALL_FUNCTION); |
| 4761 context()->Plug(rax); | 4765 context()->Plug(rax); |
| 4762 } else if (var->IsStackAllocated() || var->IsContextSlot()) { | 4766 } else if (var->IsStackAllocated() || var->IsContextSlot()) { |
| 4763 // Result of deleting non-global variables is false. 'this' is | 4767 // Result of deleting non-global variables is false. 'this' is |
| 4764 // not really a variable, though we implement it as one. The | 4768 // not really a variable, though we implement it as one. The |
| 4765 // subexpression does not have side effects. | 4769 // subexpression does not have side effects. |
| 4766 context()->Plug(is_this); | 4770 context()->Plug(is_this); |
| (...skipping 339 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 5106 } | 5110 } |
| 5107 } | 5111 } |
| 5108 } | 5112 } |
| 5109 | 5113 |
| 5110 | 5114 |
| 5111 void FullCodeGenerator::VisitForTypeofValue(Expression* expr) { | 5115 void FullCodeGenerator::VisitForTypeofValue(Expression* expr) { |
| 5112 VariableProxy* proxy = expr->AsVariableProxy(); | 5116 VariableProxy* proxy = expr->AsVariableProxy(); |
| 5113 DCHECK(!context()->IsEffect()); | 5117 DCHECK(!context()->IsEffect()); |
| 5114 DCHECK(!context()->IsTest()); | 5118 DCHECK(!context()->IsTest()); |
| 5115 | 5119 |
| 5116 if (proxy != NULL && proxy->var()->IsUnallocated()) { | 5120 if (proxy != NULL && proxy->var()->IsUnallocatedOrGlobalSlot()) { |
| 5117 Comment cmnt(masm_, "[ Global variable"); | 5121 Comment cmnt(masm_, "[ Global variable"); |
| 5118 __ Move(LoadDescriptor::NameRegister(), proxy->name()); | 5122 __ Move(LoadDescriptor::NameRegister(), proxy->name()); |
| 5119 __ movp(LoadDescriptor::ReceiverRegister(), GlobalObjectOperand()); | 5123 __ movp(LoadDescriptor::ReceiverRegister(), GlobalObjectOperand()); |
| 5120 __ Move(LoadDescriptor::SlotRegister(), | 5124 __ Move(LoadDescriptor::SlotRegister(), |
| 5121 SmiFromSlot(proxy->VariableFeedbackSlot())); | 5125 SmiFromSlot(proxy->VariableFeedbackSlot())); |
| 5122 // Use a regular load, not a contextual load, to avoid a reference | 5126 // Use a regular load, not a contextual load, to avoid a reference |
| 5123 // error. | 5127 // error. |
| 5124 CallLoadIC(NOT_CONTEXTUAL); | 5128 CallLoadIC(NOT_CONTEXTUAL); |
| 5125 PrepareForBailout(expr, TOS_REG); | 5129 PrepareForBailout(expr, TOS_REG); |
| 5126 context()->Plug(rax); | 5130 context()->Plug(rax); |
| (...skipping 382 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 5509 Assembler::target_address_at(call_target_address, | 5513 Assembler::target_address_at(call_target_address, |
| 5510 unoptimized_code)); | 5514 unoptimized_code)); |
| 5511 return OSR_AFTER_STACK_CHECK; | 5515 return OSR_AFTER_STACK_CHECK; |
| 5512 } | 5516 } |
| 5513 | 5517 |
| 5514 | 5518 |
| 5515 } // namespace internal | 5519 } // namespace internal |
| 5516 } // namespace v8 | 5520 } // namespace v8 |
| 5517 | 5521 |
| 5518 #endif // V8_TARGET_ARCH_X64 | 5522 #endif // V8_TARGET_ARCH_X64 |
| OLD | NEW |