| 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_X87 | 7 #if V8_TARGET_ARCH_X87 |
| 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 332 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 343 | 343 |
| 344 } else { | 344 } else { |
| 345 PrepareForBailoutForId(BailoutId::FunctionEntry(), NO_REGISTERS); | 345 PrepareForBailoutForId(BailoutId::FunctionEntry(), NO_REGISTERS); |
| 346 { Comment cmnt(masm_, "[ Declarations"); | 346 { Comment cmnt(masm_, "[ Declarations"); |
| 347 // For named function expressions, declare the function name as a | 347 // For named function expressions, declare the function name as a |
| 348 // constant. | 348 // constant. |
| 349 if (scope()->is_function_scope() && scope()->function() != NULL) { | 349 if (scope()->is_function_scope() && scope()->function() != NULL) { |
| 350 VariableDeclaration* function = scope()->function(); | 350 VariableDeclaration* function = scope()->function(); |
| 351 DCHECK(function->proxy()->var()->mode() == CONST || | 351 DCHECK(function->proxy()->var()->mode() == CONST || |
| 352 function->proxy()->var()->mode() == CONST_LEGACY); | 352 function->proxy()->var()->mode() == CONST_LEGACY); |
| 353 DCHECK(function->proxy()->var()->location() != Variable::UNALLOCATED); | 353 DCHECK(!function->proxy()->var()->IsUnallocatedOrGlobalSlot()); |
| 354 VisitVariableDeclaration(function); | 354 VisitVariableDeclaration(function); |
| 355 } | 355 } |
| 356 VisitDeclarations(scope()->declarations()); | 356 VisitDeclarations(scope()->declarations()); |
| 357 } | 357 } |
| 358 | 358 |
| 359 { Comment cmnt(masm_, "[ Stack check"); | 359 { Comment cmnt(masm_, "[ Stack check"); |
| 360 PrepareForBailoutForId(BailoutId::Declarations(), NO_REGISTERS); | 360 PrepareForBailoutForId(BailoutId::Declarations(), NO_REGISTERS); |
| 361 Label ok; | 361 Label ok; |
| 362 ExternalReference stack_limit | 362 ExternalReference stack_limit |
| 363 = ExternalReference::address_of_stack_limit(isolate()); | 363 = ExternalReference::address_of_stack_limit(isolate()); |
| (...skipping 449 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 813 void FullCodeGenerator::VisitVariableDeclaration( | 813 void FullCodeGenerator::VisitVariableDeclaration( |
| 814 VariableDeclaration* declaration) { | 814 VariableDeclaration* declaration) { |
| 815 // If it was not possible to allocate the variable at compile time, we | 815 // If it was not possible to allocate the variable at compile time, we |
| 816 // need to "declare" it at runtime to make sure it actually exists in the | 816 // need to "declare" it at runtime to make sure it actually exists in the |
| 817 // local context. | 817 // local context. |
| 818 VariableProxy* proxy = declaration->proxy(); | 818 VariableProxy* proxy = declaration->proxy(); |
| 819 VariableMode mode = declaration->mode(); | 819 VariableMode mode = declaration->mode(); |
| 820 Variable* variable = proxy->var(); | 820 Variable* variable = proxy->var(); |
| 821 bool hole_init = mode == LET || mode == CONST || mode == CONST_LEGACY; | 821 bool hole_init = mode == LET || mode == CONST || mode == CONST_LEGACY; |
| 822 switch (variable->location()) { | 822 switch (variable->location()) { |
| 823 case Variable::UNALLOCATED: | 823 case VariableLocation::GLOBAL: |
| 824 case VariableLocation::UNALLOCATED: |
| 824 globals_->Add(variable->name(), zone()); | 825 globals_->Add(variable->name(), zone()); |
| 825 globals_->Add(variable->binding_needs_init() | 826 globals_->Add(variable->binding_needs_init() |
| 826 ? isolate()->factory()->the_hole_value() | 827 ? isolate()->factory()->the_hole_value() |
| 827 : isolate()->factory()->undefined_value(), zone()); | 828 : isolate()->factory()->undefined_value(), zone()); |
| 828 break; | 829 break; |
| 829 | 830 |
| 830 case Variable::PARAMETER: | 831 case VariableLocation::PARAMETER: |
| 831 case Variable::LOCAL: | 832 case VariableLocation::LOCAL: |
| 832 if (hole_init) { | 833 if (hole_init) { |
| 833 Comment cmnt(masm_, "[ VariableDeclaration"); | 834 Comment cmnt(masm_, "[ VariableDeclaration"); |
| 834 __ mov(StackOperand(variable), | 835 __ mov(StackOperand(variable), |
| 835 Immediate(isolate()->factory()->the_hole_value())); | 836 Immediate(isolate()->factory()->the_hole_value())); |
| 836 } | 837 } |
| 837 break; | 838 break; |
| 838 | 839 |
| 839 case Variable::CONTEXT: | 840 case VariableLocation::CONTEXT: |
| 840 if (hole_init) { | 841 if (hole_init) { |
| 841 Comment cmnt(masm_, "[ VariableDeclaration"); | 842 Comment cmnt(masm_, "[ VariableDeclaration"); |
| 842 EmitDebugCheckDeclarationContext(variable); | 843 EmitDebugCheckDeclarationContext(variable); |
| 843 __ mov(ContextOperand(esi, variable->index()), | 844 __ mov(ContextOperand(esi, variable->index()), |
| 844 Immediate(isolate()->factory()->the_hole_value())); | 845 Immediate(isolate()->factory()->the_hole_value())); |
| 845 // No write barrier since the hole value is in old space. | 846 // No write barrier since the hole value is in old space. |
| 846 PrepareForBailoutForId(proxy->id(), NO_REGISTERS); | 847 PrepareForBailoutForId(proxy->id(), NO_REGISTERS); |
| 847 } | 848 } |
| 848 break; | 849 break; |
| 849 | 850 |
| 850 case Variable::LOOKUP: { | 851 case VariableLocation::LOOKUP: { |
| 851 Comment cmnt(masm_, "[ VariableDeclaration"); | 852 Comment cmnt(masm_, "[ VariableDeclaration"); |
| 852 __ push(esi); | 853 __ push(esi); |
| 853 __ push(Immediate(variable->name())); | 854 __ push(Immediate(variable->name())); |
| 854 // VariableDeclaration nodes are always introduced in one of four modes. | 855 // VariableDeclaration nodes are always introduced in one of four modes. |
| 855 DCHECK(IsDeclaredVariableMode(mode)); | 856 DCHECK(IsDeclaredVariableMode(mode)); |
| 856 PropertyAttributes attr = | 857 PropertyAttributes attr = |
| 857 IsImmutableVariableMode(mode) ? READ_ONLY : NONE; | 858 IsImmutableVariableMode(mode) ? READ_ONLY : NONE; |
| 858 __ push(Immediate(Smi::FromInt(attr))); | 859 __ push(Immediate(Smi::FromInt(attr))); |
| 859 // Push initial value, if any. | 860 // Push initial value, if any. |
| 860 // Note: For variables we must not push an initial value (such as | 861 // Note: For variables we must not push an initial value (such as |
| 861 // 'undefined') because we may have a (legal) redeclaration and we | 862 // 'undefined') because we may have a (legal) redeclaration and we |
| 862 // must not destroy the current value. | 863 // must not destroy the current value. |
| 863 if (hole_init) { | 864 if (hole_init) { |
| 864 __ push(Immediate(isolate()->factory()->the_hole_value())); | 865 __ push(Immediate(isolate()->factory()->the_hole_value())); |
| 865 } else { | 866 } else { |
| 866 __ push(Immediate(Smi::FromInt(0))); // Indicates no initial value. | 867 __ push(Immediate(Smi::FromInt(0))); // Indicates no initial value. |
| 867 } | 868 } |
| 868 __ CallRuntime(Runtime::kDeclareLookupSlot, 4); | 869 __ CallRuntime(Runtime::kDeclareLookupSlot, 4); |
| 869 break; | 870 break; |
| 870 } | 871 } |
| 871 } | 872 } |
| 872 } | 873 } |
| 873 | 874 |
| 874 | 875 |
| 875 void FullCodeGenerator::VisitFunctionDeclaration( | 876 void FullCodeGenerator::VisitFunctionDeclaration( |
| 876 FunctionDeclaration* declaration) { | 877 FunctionDeclaration* declaration) { |
| 877 VariableProxy* proxy = declaration->proxy(); | 878 VariableProxy* proxy = declaration->proxy(); |
| 878 Variable* variable = proxy->var(); | 879 Variable* variable = proxy->var(); |
| 879 switch (variable->location()) { | 880 switch (variable->location()) { |
| 880 case Variable::UNALLOCATED: { | 881 case VariableLocation::GLOBAL: |
| 882 case VariableLocation::UNALLOCATED: { |
| 881 globals_->Add(variable->name(), zone()); | 883 globals_->Add(variable->name(), zone()); |
| 882 Handle<SharedFunctionInfo> function = | 884 Handle<SharedFunctionInfo> function = |
| 883 Compiler::GetSharedFunctionInfo(declaration->fun(), script(), info_); | 885 Compiler::GetSharedFunctionInfo(declaration->fun(), script(), info_); |
| 884 // Check for stack-overflow exception. | 886 // Check for stack-overflow exception. |
| 885 if (function.is_null()) return SetStackOverflow(); | 887 if (function.is_null()) return SetStackOverflow(); |
| 886 globals_->Add(function, zone()); | 888 globals_->Add(function, zone()); |
| 887 break; | 889 break; |
| 888 } | 890 } |
| 889 | 891 |
| 890 case Variable::PARAMETER: | 892 case VariableLocation::PARAMETER: |
| 891 case Variable::LOCAL: { | 893 case VariableLocation::LOCAL: { |
| 892 Comment cmnt(masm_, "[ FunctionDeclaration"); | 894 Comment cmnt(masm_, "[ FunctionDeclaration"); |
| 893 VisitForAccumulatorValue(declaration->fun()); | 895 VisitForAccumulatorValue(declaration->fun()); |
| 894 __ mov(StackOperand(variable), result_register()); | 896 __ mov(StackOperand(variable), result_register()); |
| 895 break; | 897 break; |
| 896 } | 898 } |
| 897 | 899 |
| 898 case Variable::CONTEXT: { | 900 case VariableLocation::CONTEXT: { |
| 899 Comment cmnt(masm_, "[ FunctionDeclaration"); | 901 Comment cmnt(masm_, "[ FunctionDeclaration"); |
| 900 EmitDebugCheckDeclarationContext(variable); | 902 EmitDebugCheckDeclarationContext(variable); |
| 901 VisitForAccumulatorValue(declaration->fun()); | 903 VisitForAccumulatorValue(declaration->fun()); |
| 902 __ mov(ContextOperand(esi, variable->index()), result_register()); | 904 __ mov(ContextOperand(esi, variable->index()), result_register()); |
| 903 // We know that we have written a function, which is not a smi. | 905 // We know that we have written a function, which is not a smi. |
| 904 __ RecordWriteContextSlot(esi, Context::SlotOffset(variable->index()), | 906 __ RecordWriteContextSlot(esi, Context::SlotOffset(variable->index()), |
| 905 result_register(), ecx, kDontSaveFPRegs, | 907 result_register(), ecx, kDontSaveFPRegs, |
| 906 EMIT_REMEMBERED_SET, OMIT_SMI_CHECK); | 908 EMIT_REMEMBERED_SET, OMIT_SMI_CHECK); |
| 907 PrepareForBailoutForId(proxy->id(), NO_REGISTERS); | 909 PrepareForBailoutForId(proxy->id(), NO_REGISTERS); |
| 908 break; | 910 break; |
| 909 } | 911 } |
| 910 | 912 |
| 911 case Variable::LOOKUP: { | 913 case VariableLocation::LOOKUP: { |
| 912 Comment cmnt(masm_, "[ FunctionDeclaration"); | 914 Comment cmnt(masm_, "[ FunctionDeclaration"); |
| 913 __ push(esi); | 915 __ push(esi); |
| 914 __ push(Immediate(variable->name())); | 916 __ push(Immediate(variable->name())); |
| 915 __ push(Immediate(Smi::FromInt(NONE))); | 917 __ push(Immediate(Smi::FromInt(NONE))); |
| 916 VisitForStackValue(declaration->fun()); | 918 VisitForStackValue(declaration->fun()); |
| 917 __ CallRuntime(Runtime::kDeclareLookupSlot, 4); | 919 __ CallRuntime(Runtime::kDeclareLookupSlot, 4); |
| 918 break; | 920 break; |
| 919 } | 921 } |
| 920 } | 922 } |
| 921 } | 923 } |
| 922 | 924 |
| 923 | 925 |
| 924 void FullCodeGenerator::VisitImportDeclaration(ImportDeclaration* declaration) { | 926 void FullCodeGenerator::VisitImportDeclaration(ImportDeclaration* declaration) { |
| 925 VariableProxy* proxy = declaration->proxy(); | 927 VariableProxy* proxy = declaration->proxy(); |
| 926 Variable* variable = proxy->var(); | 928 Variable* variable = proxy->var(); |
| 927 switch (variable->location()) { | 929 switch (variable->location()) { |
| 928 case Variable::UNALLOCATED: | 930 case VariableLocation::GLOBAL: |
| 931 case VariableLocation::UNALLOCATED: |
| 929 // TODO(rossberg) | 932 // TODO(rossberg) |
| 930 break; | 933 break; |
| 931 | 934 |
| 932 case Variable::CONTEXT: { | 935 case VariableLocation::CONTEXT: { |
| 933 Comment cmnt(masm_, "[ ImportDeclaration"); | 936 Comment cmnt(masm_, "[ ImportDeclaration"); |
| 934 EmitDebugCheckDeclarationContext(variable); | 937 EmitDebugCheckDeclarationContext(variable); |
| 935 // TODO(rossberg) | 938 // TODO(rossberg) |
| 936 break; | 939 break; |
| 937 } | 940 } |
| 938 | 941 |
| 939 case Variable::PARAMETER: | 942 case VariableLocation::PARAMETER: |
| 940 case Variable::LOCAL: | 943 case VariableLocation::LOCAL: |
| 941 case Variable::LOOKUP: | 944 case VariableLocation::LOOKUP: |
| 942 UNREACHABLE(); | 945 UNREACHABLE(); |
| 943 } | 946 } |
| 944 } | 947 } |
| 945 | 948 |
| 946 | 949 |
| 947 void FullCodeGenerator::VisitExportDeclaration(ExportDeclaration* declaration) { | 950 void FullCodeGenerator::VisitExportDeclaration(ExportDeclaration* declaration) { |
| 948 // TODO(rossberg) | 951 // TODO(rossberg) |
| 949 } | 952 } |
| 950 | 953 |
| 951 | 954 |
| (...skipping 462 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1414 | 1417 |
| 1415 void FullCodeGenerator::EmitVariableLoad(VariableProxy* proxy) { | 1418 void FullCodeGenerator::EmitVariableLoad(VariableProxy* proxy) { |
| 1416 // Record position before possible IC call. | 1419 // Record position before possible IC call. |
| 1417 SetSourcePosition(proxy->position()); | 1420 SetSourcePosition(proxy->position()); |
| 1418 PrepareForBailoutForId(proxy->BeforeId(), NO_REGISTERS); | 1421 PrepareForBailoutForId(proxy->BeforeId(), NO_REGISTERS); |
| 1419 Variable* var = proxy->var(); | 1422 Variable* var = proxy->var(); |
| 1420 | 1423 |
| 1421 // Three cases: global variables, lookup variables, and all other types of | 1424 // Three cases: global variables, lookup variables, and all other types of |
| 1422 // variables. | 1425 // variables. |
| 1423 switch (var->location()) { | 1426 switch (var->location()) { |
| 1424 case Variable::UNALLOCATED: { | 1427 case VariableLocation::GLOBAL: |
| 1428 case VariableLocation::UNALLOCATED: { |
| 1425 Comment cmnt(masm_, "[ Global variable"); | 1429 Comment cmnt(masm_, "[ Global variable"); |
| 1426 __ mov(LoadDescriptor::ReceiverRegister(), GlobalObjectOperand()); | 1430 __ mov(LoadDescriptor::ReceiverRegister(), GlobalObjectOperand()); |
| 1427 __ mov(LoadDescriptor::NameRegister(), var->name()); | 1431 __ mov(LoadDescriptor::NameRegister(), var->name()); |
| 1428 __ mov(LoadDescriptor::SlotRegister(), | 1432 __ mov(LoadDescriptor::SlotRegister(), |
| 1429 Immediate(SmiFromSlot(proxy->VariableFeedbackSlot()))); | 1433 Immediate(SmiFromSlot(proxy->VariableFeedbackSlot()))); |
| 1430 CallGlobalLoadIC(var->name()); | 1434 CallGlobalLoadIC(var->name()); |
| 1431 context()->Plug(eax); | 1435 context()->Plug(eax); |
| 1432 break; | 1436 break; |
| 1433 } | 1437 } |
| 1434 | 1438 |
| 1435 case Variable::PARAMETER: | 1439 case VariableLocation::PARAMETER: |
| 1436 case Variable::LOCAL: | 1440 case VariableLocation::LOCAL: |
| 1437 case Variable::CONTEXT: { | 1441 case VariableLocation::CONTEXT: { |
| 1438 Comment cmnt(masm_, var->IsContextSlot() ? "[ Context variable" | 1442 Comment cmnt(masm_, var->IsContextSlot() ? "[ Context variable" |
| 1439 : "[ Stack variable"); | 1443 : "[ Stack variable"); |
| 1440 if (var->binding_needs_init()) { | 1444 if (var->binding_needs_init()) { |
| 1441 // var->scope() may be NULL when the proxy is located in eval code and | 1445 // var->scope() may be NULL when the proxy is located in eval code and |
| 1442 // refers to a potential outside binding. Currently those bindings are | 1446 // refers to a potential outside binding. Currently those bindings are |
| 1443 // always looked up dynamically, i.e. in that case | 1447 // always looked up dynamically, i.e. in that case |
| 1444 // var->location() == LOOKUP. | 1448 // var->location() == LOOKUP. |
| 1445 // always holds. | 1449 // always holds. |
| 1446 DCHECK(var->scope() != NULL); | 1450 DCHECK(var->scope() != NULL); |
| 1447 | 1451 |
| (...skipping 47 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1495 } | 1499 } |
| 1496 __ bind(&done); | 1500 __ bind(&done); |
| 1497 context()->Plug(eax); | 1501 context()->Plug(eax); |
| 1498 break; | 1502 break; |
| 1499 } | 1503 } |
| 1500 } | 1504 } |
| 1501 context()->Plug(var); | 1505 context()->Plug(var); |
| 1502 break; | 1506 break; |
| 1503 } | 1507 } |
| 1504 | 1508 |
| 1505 case Variable::LOOKUP: { | 1509 case VariableLocation::LOOKUP: { |
| 1506 Comment cmnt(masm_, "[ Lookup variable"); | 1510 Comment cmnt(masm_, "[ Lookup variable"); |
| 1507 Label done, slow; | 1511 Label done, slow; |
| 1508 // Generate code for loading from variables potentially shadowed | 1512 // Generate code for loading from variables potentially shadowed |
| 1509 // by eval-introduced variables. | 1513 // by eval-introduced variables. |
| 1510 EmitDynamicLookupFastCase(proxy, NOT_INSIDE_TYPEOF, &slow, &done); | 1514 EmitDynamicLookupFastCase(proxy, NOT_INSIDE_TYPEOF, &slow, &done); |
| 1511 __ bind(&slow); | 1515 __ bind(&slow); |
| 1512 __ push(esi); // Context. | 1516 __ push(esi); // Context. |
| 1513 __ push(Immediate(var->name())); | 1517 __ push(Immediate(var->name())); |
| 1514 __ CallRuntime(Runtime::kLoadLookupSlot, 2); | 1518 __ CallRuntime(Runtime::kLoadLookupSlot, 2); |
| 1515 __ bind(&done); | 1519 __ bind(&done); |
| (...skipping 1115 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2631 if (var->IsContextSlot()) { | 2635 if (var->IsContextSlot()) { |
| 2632 __ mov(edx, eax); | 2636 __ mov(edx, eax); |
| 2633 int offset = Context::SlotOffset(var->index()); | 2637 int offset = Context::SlotOffset(var->index()); |
| 2634 __ RecordWriteContextSlot(ecx, offset, edx, ebx, kDontSaveFPRegs); | 2638 __ RecordWriteContextSlot(ecx, offset, edx, ebx, kDontSaveFPRegs); |
| 2635 } | 2639 } |
| 2636 } | 2640 } |
| 2637 | 2641 |
| 2638 | 2642 |
| 2639 void FullCodeGenerator::EmitVariableAssignment(Variable* var, Token::Value op, | 2643 void FullCodeGenerator::EmitVariableAssignment(Variable* var, Token::Value op, |
| 2640 FeedbackVectorICSlot slot) { | 2644 FeedbackVectorICSlot slot) { |
| 2641 if (var->IsUnallocated()) { | 2645 if (var->IsUnallocatedOrGlobalSlot()) { |
| 2642 // Global var, const, or let. | 2646 // Global var, const, or let. |
| 2643 __ mov(StoreDescriptor::NameRegister(), var->name()); | 2647 __ mov(StoreDescriptor::NameRegister(), var->name()); |
| 2644 __ mov(StoreDescriptor::ReceiverRegister(), GlobalObjectOperand()); | 2648 __ mov(StoreDescriptor::ReceiverRegister(), GlobalObjectOperand()); |
| 2645 if (FLAG_vector_stores) EmitLoadStoreICSlot(slot); | 2649 if (FLAG_vector_stores) EmitLoadStoreICSlot(slot); |
| 2646 CallStoreIC(); | 2650 CallStoreIC(); |
| 2647 | 2651 |
| 2648 } else if (var->mode() == LET && op != Token::INIT_LET) { | 2652 } else if (var->mode() == LET && op != Token::INIT_LET) { |
| 2649 // Non-initializing assignment to let variable needs a write barrier. | 2653 // Non-initializing assignment to let variable needs a write barrier. |
| 2650 DCHECK(!var->IsLookupSlot()); | 2654 DCHECK(!var->IsLookupSlot()); |
| 2651 DCHECK(var->IsStackAllocated() || var->IsContextSlot()); | 2655 DCHECK(var->IsStackAllocated() || var->IsContextSlot()); |
| (...skipping 2076 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 4728 VisitForStackValue(property->key()); | 4732 VisitForStackValue(property->key()); |
| 4729 __ push(Immediate(Smi::FromInt(language_mode()))); | 4733 __ push(Immediate(Smi::FromInt(language_mode()))); |
| 4730 __ InvokeBuiltin(Builtins::DELETE, CALL_FUNCTION); | 4734 __ InvokeBuiltin(Builtins::DELETE, CALL_FUNCTION); |
| 4731 context()->Plug(eax); | 4735 context()->Plug(eax); |
| 4732 } else if (proxy != NULL) { | 4736 } else if (proxy != NULL) { |
| 4733 Variable* var = proxy->var(); | 4737 Variable* var = proxy->var(); |
| 4734 // Delete of an unqualified identifier is disallowed in strict mode but | 4738 // Delete of an unqualified identifier is disallowed in strict mode but |
| 4735 // "delete this" is allowed. | 4739 // "delete this" is allowed. |
| 4736 bool is_this = var->HasThisName(isolate()); | 4740 bool is_this = var->HasThisName(isolate()); |
| 4737 DCHECK(is_sloppy(language_mode()) || is_this); | 4741 DCHECK(is_sloppy(language_mode()) || is_this); |
| 4738 if (var->IsUnallocated()) { | 4742 if (var->IsUnallocatedOrGlobalSlot()) { |
| 4739 __ push(GlobalObjectOperand()); | 4743 __ push(GlobalObjectOperand()); |
| 4740 __ push(Immediate(var->name())); | 4744 __ push(Immediate(var->name())); |
| 4741 __ push(Immediate(Smi::FromInt(SLOPPY))); | 4745 __ push(Immediate(Smi::FromInt(SLOPPY))); |
| 4742 __ InvokeBuiltin(Builtins::DELETE, CALL_FUNCTION); | 4746 __ InvokeBuiltin(Builtins::DELETE, CALL_FUNCTION); |
| 4743 context()->Plug(eax); | 4747 context()->Plug(eax); |
| 4744 } else if (var->IsStackAllocated() || var->IsContextSlot()) { | 4748 } else if (var->IsStackAllocated() || var->IsContextSlot()) { |
| 4745 // Result of deleting non-global variables is false. 'this' is | 4749 // Result of deleting non-global variables is false. 'this' is |
| 4746 // not really a variable, though we implement it as one. The | 4750 // not really a variable, though we implement it as one. The |
| 4747 // subexpression does not have side effects. | 4751 // subexpression does not have side effects. |
| 4748 context()->Plug(is_this); | 4752 context()->Plug(is_this); |
| (...skipping 346 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 5095 } | 5099 } |
| 5096 } | 5100 } |
| 5097 } | 5101 } |
| 5098 | 5102 |
| 5099 | 5103 |
| 5100 void FullCodeGenerator::VisitForTypeofValue(Expression* expr) { | 5104 void FullCodeGenerator::VisitForTypeofValue(Expression* expr) { |
| 5101 VariableProxy* proxy = expr->AsVariableProxy(); | 5105 VariableProxy* proxy = expr->AsVariableProxy(); |
| 5102 DCHECK(!context()->IsEffect()); | 5106 DCHECK(!context()->IsEffect()); |
| 5103 DCHECK(!context()->IsTest()); | 5107 DCHECK(!context()->IsTest()); |
| 5104 | 5108 |
| 5105 if (proxy != NULL && proxy->var()->IsUnallocated()) { | 5109 if (proxy != NULL && proxy->var()->IsUnallocatedOrGlobalSlot()) { |
| 5106 Comment cmnt(masm_, "[ Global variable"); | 5110 Comment cmnt(masm_, "[ Global variable"); |
| 5107 __ mov(LoadDescriptor::ReceiverRegister(), GlobalObjectOperand()); | 5111 __ mov(LoadDescriptor::ReceiverRegister(), GlobalObjectOperand()); |
| 5108 __ mov(LoadDescriptor::NameRegister(), Immediate(proxy->name())); | 5112 __ mov(LoadDescriptor::NameRegister(), Immediate(proxy->name())); |
| 5109 __ mov(LoadDescriptor::SlotRegister(), | 5113 __ mov(LoadDescriptor::SlotRegister(), |
| 5110 Immediate(SmiFromSlot(proxy->VariableFeedbackSlot()))); | 5114 Immediate(SmiFromSlot(proxy->VariableFeedbackSlot()))); |
| 5111 // Use a regular load, not a contextual load, to avoid a reference | 5115 // Use a regular load, not a contextual load, to avoid a reference |
| 5112 // error. | 5116 // error. |
| 5113 CallLoadIC(NOT_CONTEXTUAL); | 5117 CallLoadIC(NOT_CONTEXTUAL); |
| 5114 PrepareForBailout(expr, TOS_REG); | 5118 PrepareForBailout(expr, TOS_REG); |
| 5115 context()->Plug(eax); | 5119 context()->Plug(eax); |
| (...skipping 383 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 5499 Assembler::target_address_at(call_target_address, | 5503 Assembler::target_address_at(call_target_address, |
| 5500 unoptimized_code)); | 5504 unoptimized_code)); |
| 5501 return OSR_AFTER_STACK_CHECK; | 5505 return OSR_AFTER_STACK_CHECK; |
| 5502 } | 5506 } |
| 5503 | 5507 |
| 5504 | 5508 |
| 5505 } // namespace internal | 5509 } // namespace internal |
| 5506 } // namespace v8 | 5510 } // namespace v8 |
| 5507 | 5511 |
| 5508 #endif // V8_TARGET_ARCH_X87 | 5512 #endif // V8_TARGET_ARCH_X87 |
| OLD | NEW |