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 |