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