OLD | NEW |
1 // Copyright 2009 the V8 project authors. All rights reserved. | 1 // Copyright 2009 the V8 project authors. All rights reserved. |
2 // Redistribution and use in source and binary forms, with or without | 2 // Redistribution and use in source and binary forms, with or without |
3 // modification, are permitted provided that the following conditions are | 3 // modification, are permitted provided that the following conditions are |
4 // met: | 4 // met: |
5 // | 5 // |
6 // * Redistributions of source code must retain the above copyright | 6 // * Redistributions of source code must retain the above copyright |
7 // notice, this list of conditions and the following disclaimer. | 7 // notice, this list of conditions and the following disclaimer. |
8 // * Redistributions in binary form must reproduce the above | 8 // * Redistributions in binary form must reproduce the above |
9 // copyright notice, this list of conditions and the following | 9 // copyright notice, this list of conditions and the following |
10 // disclaimer in the documentation and/or other materials provided | 10 // disclaimer in the documentation and/or other materials provided |
(...skipping 82 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
93 } else { | 93 } else { |
94 __ CallRuntime(Runtime::kNewContext, 1); | 94 __ CallRuntime(Runtime::kNewContext, 1); |
95 } | 95 } |
96 function_in_register = false; | 96 function_in_register = false; |
97 // Context is returned in both r0 and cp. It replaces the context | 97 // Context is returned in both r0 and cp. It replaces the context |
98 // passed to us. It's saved in the stack and kept live in cp. | 98 // passed to us. It's saved in the stack and kept live in cp. |
99 __ str(cp, MemOperand(fp, StandardFrameConstants::kContextOffset)); | 99 __ str(cp, MemOperand(fp, StandardFrameConstants::kContextOffset)); |
100 // Copy any necessary parameters into the context. | 100 // Copy any necessary parameters into the context. |
101 int num_parameters = scope()->num_parameters(); | 101 int num_parameters = scope()->num_parameters(); |
102 for (int i = 0; i < num_parameters; i++) { | 102 for (int i = 0; i < num_parameters; i++) { |
103 Slot* slot = scope()->parameter(i)->slot(); | 103 Slot* slot = scope()->parameter(i)->AsSlot(); |
104 if (slot != NULL && slot->type() == Slot::CONTEXT) { | 104 if (slot != NULL && slot->type() == Slot::CONTEXT) { |
105 int parameter_offset = StandardFrameConstants::kCallerSPOffset + | 105 int parameter_offset = StandardFrameConstants::kCallerSPOffset + |
106 (num_parameters - 1 - i) * kPointerSize; | 106 (num_parameters - 1 - i) * kPointerSize; |
107 // Load parameter from stack. | 107 // Load parameter from stack. |
108 __ ldr(r0, MemOperand(fp, parameter_offset)); | 108 __ ldr(r0, MemOperand(fp, parameter_offset)); |
109 // Store it in the context. | 109 // Store it in the context. |
110 __ mov(r1, Operand(Context::SlotOffset(slot->index()))); | 110 __ mov(r1, Operand(Context::SlotOffset(slot->index()))); |
111 __ str(r0, MemOperand(cp, r1)); | 111 __ str(r0, MemOperand(cp, r1)); |
112 // Update the write barrier. This clobbers all involved | 112 // Update the write barrier. This clobbers all involved |
113 // registers, so we have to use two more registers to avoid | 113 // registers, so we have to use two more registers to avoid |
114 // clobbering cp. | 114 // clobbering cp. |
115 __ mov(r2, Operand(cp)); | 115 __ mov(r2, Operand(cp)); |
116 __ RecordWrite(r2, Operand(r1), r3, r0); | 116 __ RecordWrite(r2, Operand(r1), r3, r0); |
117 } | 117 } |
118 } | 118 } |
119 } | 119 } |
120 | 120 |
121 Variable* arguments = scope()->arguments()->AsVariable(); | 121 Variable* arguments = scope()->arguments(); |
122 if (arguments != NULL) { | 122 if (arguments != NULL) { |
123 // Function uses arguments object. | 123 // Function uses arguments object. |
124 Comment cmnt(masm_, "[ Allocate arguments object"); | 124 Comment cmnt(masm_, "[ Allocate arguments object"); |
125 if (!function_in_register) { | 125 if (!function_in_register) { |
126 // Load this again, if it's used by the local context below. | 126 // Load this again, if it's used by the local context below. |
127 __ ldr(r3, MemOperand(fp, JavaScriptFrameConstants::kFunctionOffset)); | 127 __ ldr(r3, MemOperand(fp, JavaScriptFrameConstants::kFunctionOffset)); |
128 } else { | 128 } else { |
129 __ mov(r3, r1); | 129 __ mov(r3, r1); |
130 } | 130 } |
131 // Receiver is just before the parameters on the caller's stack. | 131 // Receiver is just before the parameters on the caller's stack. |
132 int offset = scope()->num_parameters() * kPointerSize; | 132 int offset = scope()->num_parameters() * kPointerSize; |
133 __ add(r2, fp, | 133 __ add(r2, fp, |
134 Operand(StandardFrameConstants::kCallerSPOffset + offset)); | 134 Operand(StandardFrameConstants::kCallerSPOffset + offset)); |
135 __ mov(r1, Operand(Smi::FromInt(scope()->num_parameters()))); | 135 __ mov(r1, Operand(Smi::FromInt(scope()->num_parameters()))); |
136 __ Push(r3, r2, r1); | 136 __ Push(r3, r2, r1); |
137 | 137 |
138 // Arguments to ArgumentsAccessStub: | 138 // Arguments to ArgumentsAccessStub: |
139 // function, receiver address, parameter count. | 139 // function, receiver address, parameter count. |
140 // The stub will rewrite receiever and parameter count if the previous | 140 // The stub will rewrite receiever and parameter count if the previous |
141 // stack frame was an arguments adapter frame. | 141 // stack frame was an arguments adapter frame. |
142 ArgumentsAccessStub stub(ArgumentsAccessStub::NEW_OBJECT); | 142 ArgumentsAccessStub stub(ArgumentsAccessStub::NEW_OBJECT); |
143 __ CallStub(&stub); | 143 __ CallStub(&stub); |
144 // Duplicate the value; move-to-slot operation might clobber registers. | 144 // Duplicate the value; move-to-slot operation might clobber registers. |
145 __ mov(r3, r0); | 145 __ mov(r3, r0); |
146 Move(arguments->slot(), r0, r1, r2); | 146 Move(arguments->AsSlot(), r0, r1, r2); |
147 Slot* dot_arguments_slot = | 147 Slot* dot_arguments_slot = scope()->arguments_shadow()->AsSlot(); |
148 scope()->arguments_shadow()->AsVariable()->slot(); | |
149 Move(dot_arguments_slot, r3, r1, r2); | 148 Move(dot_arguments_slot, r3, r1, r2); |
150 } | 149 } |
151 | 150 |
152 { Comment cmnt(masm_, "[ Declarations"); | 151 { Comment cmnt(masm_, "[ Declarations"); |
153 // For named function expressions, declare the function name as a | 152 // For named function expressions, declare the function name as a |
154 // constant. | 153 // constant. |
155 if (scope()->is_function_scope() && scope()->function() != NULL) { | 154 if (scope()->is_function_scope() && scope()->function() != NULL) { |
156 EmitDeclaration(scope()->function(), Variable::CONST, NULL); | 155 EmitDeclaration(scope()->function(), Variable::CONST, NULL); |
157 } | 156 } |
158 // Visit all the explicit declarations unless there is an illegal | 157 // Visit all the explicit declarations unless there is an illegal |
(...skipping 364 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
523 src); | 522 src); |
524 } | 523 } |
525 } | 524 } |
526 | 525 |
527 | 526 |
528 void FullCodeGenerator::EmitDeclaration(Variable* variable, | 527 void FullCodeGenerator::EmitDeclaration(Variable* variable, |
529 Variable::Mode mode, | 528 Variable::Mode mode, |
530 FunctionLiteral* function) { | 529 FunctionLiteral* function) { |
531 Comment cmnt(masm_, "[ Declaration"); | 530 Comment cmnt(masm_, "[ Declaration"); |
532 ASSERT(variable != NULL); // Must have been resolved. | 531 ASSERT(variable != NULL); // Must have been resolved. |
533 Slot* slot = variable->slot(); | 532 Slot* slot = variable->AsSlot(); |
534 Property* prop = variable->AsProperty(); | 533 Property* prop = variable->AsProperty(); |
535 | 534 |
536 if (slot != NULL) { | 535 if (slot != NULL) { |
537 switch (slot->type()) { | 536 switch (slot->type()) { |
538 case Slot::PARAMETER: | 537 case Slot::PARAMETER: |
539 case Slot::LOCAL: | 538 case Slot::LOCAL: |
540 if (mode == Variable::CONST) { | 539 if (mode == Variable::CONST) { |
541 __ LoadRoot(ip, Heap::kTheHoleValueRootIndex); | 540 __ LoadRoot(ip, Heap::kTheHoleValueRootIndex); |
542 __ str(ip, MemOperand(fp, SlotOffset(slot))); | 541 __ str(ip, MemOperand(fp, SlotOffset(slot))); |
543 } else if (function != NULL) { | 542 } else if (function != NULL) { |
(...skipping 373 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
917 Label* done) { | 916 Label* done) { |
918 // Generate fast-case code for variables that might be shadowed by | 917 // Generate fast-case code for variables that might be shadowed by |
919 // eval-introduced variables. Eval is used a lot without | 918 // eval-introduced variables. Eval is used a lot without |
920 // introducing variables. In those cases, we do not want to | 919 // introducing variables. In those cases, we do not want to |
921 // perform a runtime call for all variables in the scope | 920 // perform a runtime call for all variables in the scope |
922 // containing the eval. | 921 // containing the eval. |
923 if (slot->var()->mode() == Variable::DYNAMIC_GLOBAL) { | 922 if (slot->var()->mode() == Variable::DYNAMIC_GLOBAL) { |
924 EmitLoadGlobalSlotCheckExtensions(slot, typeof_state, slow); | 923 EmitLoadGlobalSlotCheckExtensions(slot, typeof_state, slow); |
925 __ jmp(done); | 924 __ jmp(done); |
926 } else if (slot->var()->mode() == Variable::DYNAMIC_LOCAL) { | 925 } else if (slot->var()->mode() == Variable::DYNAMIC_LOCAL) { |
927 Slot* potential_slot = slot->var()->local_if_not_shadowed()->slot(); | 926 Slot* potential_slot = slot->var()->local_if_not_shadowed()->AsSlot(); |
928 Expression* rewrite = slot->var()->local_if_not_shadowed()->rewrite(); | 927 Expression* rewrite = slot->var()->local_if_not_shadowed()->rewrite(); |
929 if (potential_slot != NULL) { | 928 if (potential_slot != NULL) { |
930 // Generate fast case for locals that rewrite to slots. | 929 // Generate fast case for locals that rewrite to slots. |
931 __ ldr(r0, ContextSlotOperandCheckExtensions(potential_slot, slow)); | 930 __ ldr(r0, ContextSlotOperandCheckExtensions(potential_slot, slow)); |
932 if (potential_slot->var()->mode() == Variable::CONST) { | 931 if (potential_slot->var()->mode() == Variable::CONST) { |
933 __ LoadRoot(ip, Heap::kTheHoleValueRootIndex); | 932 __ LoadRoot(ip, Heap::kTheHoleValueRootIndex); |
934 __ cmp(r0, ip); | 933 __ cmp(r0, ip); |
935 __ LoadRoot(r0, Heap::kUndefinedValueRootIndex, eq); | 934 __ LoadRoot(r0, Heap::kUndefinedValueRootIndex, eq); |
936 } | 935 } |
937 __ jmp(done); | 936 __ jmp(done); |
938 } else if (rewrite != NULL) { | 937 } else if (rewrite != NULL) { |
939 // Generate fast case for calls of an argument function. | 938 // Generate fast case for calls of an argument function. |
940 Property* property = rewrite->AsProperty(); | 939 Property* property = rewrite->AsProperty(); |
941 if (property != NULL) { | 940 if (property != NULL) { |
942 VariableProxy* obj_proxy = property->obj()->AsVariableProxy(); | 941 VariableProxy* obj_proxy = property->obj()->AsVariableProxy(); |
943 Literal* key_literal = property->key()->AsLiteral(); | 942 Literal* key_literal = property->key()->AsLiteral(); |
944 if (obj_proxy != NULL && | 943 if (obj_proxy != NULL && |
945 key_literal != NULL && | 944 key_literal != NULL && |
946 obj_proxy->IsArguments() && | 945 obj_proxy->IsArguments() && |
947 key_literal->handle()->IsSmi()) { | 946 key_literal->handle()->IsSmi()) { |
948 // Load arguments object if there are no eval-introduced | 947 // Load arguments object if there are no eval-introduced |
949 // variables. Then load the argument from the arguments | 948 // variables. Then load the argument from the arguments |
950 // object using keyed load. | 949 // object using keyed load. |
951 __ ldr(r1, | 950 __ ldr(r1, |
952 ContextSlotOperandCheckExtensions(obj_proxy->var()->slot(), | 951 ContextSlotOperandCheckExtensions(obj_proxy->var()->AsSlot(), |
953 slow)); | 952 slow)); |
954 __ mov(r0, Operand(key_literal->handle())); | 953 __ mov(r0, Operand(key_literal->handle())); |
955 Handle<Code> ic(Builtins::builtin(Builtins::KeyedLoadIC_Initialize)); | 954 Handle<Code> ic(Builtins::builtin(Builtins::KeyedLoadIC_Initialize)); |
956 EmitCallIC(ic, RelocInfo::CODE_TARGET); | 955 EmitCallIC(ic, RelocInfo::CODE_TARGET); |
957 __ jmp(done); | 956 __ jmp(done); |
958 } | 957 } |
959 } | 958 } |
960 } | 959 } |
961 } | 960 } |
962 } | 961 } |
(...skipping 57 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1020 : RelocInfo::CODE_TARGET_CONTEXT; | 1019 : RelocInfo::CODE_TARGET_CONTEXT; |
1021 Handle<Code> ic(Builtins::builtin(Builtins::LoadIC_Initialize)); | 1020 Handle<Code> ic(Builtins::builtin(Builtins::LoadIC_Initialize)); |
1022 EmitCallIC(ic, mode); | 1021 EmitCallIC(ic, mode); |
1023 } | 1022 } |
1024 | 1023 |
1025 | 1024 |
1026 void FullCodeGenerator::EmitVariableLoad(Variable* var) { | 1025 void FullCodeGenerator::EmitVariableLoad(Variable* var) { |
1027 // Four cases: non-this global variables, lookup slots, all other | 1026 // Four cases: non-this global variables, lookup slots, all other |
1028 // types of slots, and parameters that rewrite to explicit property | 1027 // types of slots, and parameters that rewrite to explicit property |
1029 // accesses on the arguments object. | 1028 // accesses on the arguments object. |
1030 Slot* slot = var->slot(); | 1029 Slot* slot = var->AsSlot(); |
1031 Property* property = var->AsProperty(); | 1030 Property* property = var->AsProperty(); |
1032 | 1031 |
1033 if (var->is_global() && !var->is_this()) { | 1032 if (var->is_global() && !var->is_this()) { |
1034 Comment cmnt(masm_, "Global variable"); | 1033 Comment cmnt(masm_, "Global variable"); |
1035 // Use inline caching. Variable name is passed in r2 and the global | 1034 // Use inline caching. Variable name is passed in r2 and the global |
1036 // object (receiver) in r0. | 1035 // object (receiver) in r0. |
1037 __ ldr(r0, CodeGenerator::GlobalObject()); | 1036 __ ldr(r0, CodeGenerator::GlobalObject()); |
1038 __ mov(r2, Operand(var->name())); | 1037 __ mov(r2, Operand(var->name())); |
1039 Handle<Code> ic(Builtins::builtin(Builtins::LoadIC_Initialize)); | 1038 Handle<Code> ic(Builtins::builtin(Builtins::LoadIC_Initialize)); |
1040 EmitCallIC(ic, RelocInfo::CODE_TARGET_CONTEXT); | 1039 EmitCallIC(ic, RelocInfo::CODE_TARGET_CONTEXT); |
(...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1073 context()->Plug(slot); | 1072 context()->Plug(slot); |
1074 } | 1073 } |
1075 } else { | 1074 } else { |
1076 Comment cmnt(masm_, "Rewritten parameter"); | 1075 Comment cmnt(masm_, "Rewritten parameter"); |
1077 ASSERT_NOT_NULL(property); | 1076 ASSERT_NOT_NULL(property); |
1078 // Rewritten parameter accesses are of the form "slot[literal]". | 1077 // Rewritten parameter accesses are of the form "slot[literal]". |
1079 | 1078 |
1080 // Assert that the object is in a slot. | 1079 // Assert that the object is in a slot. |
1081 Variable* object_var = property->obj()->AsVariableProxy()->AsVariable(); | 1080 Variable* object_var = property->obj()->AsVariableProxy()->AsVariable(); |
1082 ASSERT_NOT_NULL(object_var); | 1081 ASSERT_NOT_NULL(object_var); |
1083 Slot* object_slot = object_var->slot(); | 1082 Slot* object_slot = object_var->AsSlot(); |
1084 ASSERT_NOT_NULL(object_slot); | 1083 ASSERT_NOT_NULL(object_slot); |
1085 | 1084 |
1086 // Load the object. | 1085 // Load the object. |
1087 Move(r1, object_slot); | 1086 Move(r1, object_slot); |
1088 | 1087 |
1089 // Assert that the key is a smi. | 1088 // Assert that the key is a smi. |
1090 Literal* key_literal = property->key()->AsLiteral(); | 1089 Literal* key_literal = property->key()->AsLiteral(); |
1091 ASSERT_NOT_NULL(key_literal); | 1090 ASSERT_NOT_NULL(key_literal); |
1092 ASSERT(key_literal->handle()->IsSmi()); | 1091 ASSERT(key_literal->handle()->IsSmi()); |
1093 | 1092 |
(...skipping 388 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1482 } | 1481 } |
1483 } | 1482 } |
1484 } | 1483 } |
1485 | 1484 |
1486 | 1485 |
1487 void FullCodeGenerator::EmitVariableAssignment(Variable* var, | 1486 void FullCodeGenerator::EmitVariableAssignment(Variable* var, |
1488 Token::Value op) { | 1487 Token::Value op) { |
1489 // Left-hand sides that rewrite to explicit property accesses do not reach | 1488 // Left-hand sides that rewrite to explicit property accesses do not reach |
1490 // here. | 1489 // here. |
1491 ASSERT(var != NULL); | 1490 ASSERT(var != NULL); |
1492 ASSERT(var->is_global() || var->slot() != NULL); | 1491 ASSERT(var->is_global() || var->AsSlot() != NULL); |
1493 | 1492 |
1494 if (var->is_global()) { | 1493 if (var->is_global()) { |
1495 ASSERT(!var->is_this()); | 1494 ASSERT(!var->is_this()); |
1496 // Assignment to a global variable. Use inline caching for the | 1495 // Assignment to a global variable. Use inline caching for the |
1497 // assignment. Right-hand-side value is passed in r0, variable name in | 1496 // assignment. Right-hand-side value is passed in r0, variable name in |
1498 // r2, and the global object in r1. | 1497 // r2, and the global object in r1. |
1499 __ mov(r2, Operand(var->name())); | 1498 __ mov(r2, Operand(var->name())); |
1500 __ ldr(r1, CodeGenerator::GlobalObject()); | 1499 __ ldr(r1, CodeGenerator::GlobalObject()); |
1501 Handle<Code> ic(Builtins::builtin(Builtins::StoreIC_Initialize)); | 1500 Handle<Code> ic(Builtins::builtin(Builtins::StoreIC_Initialize)); |
1502 EmitCallIC(ic, RelocInfo::CODE_TARGET); | 1501 EmitCallIC(ic, RelocInfo::CODE_TARGET); |
1503 | 1502 |
1504 } else if (var->mode() != Variable::CONST || op == Token::INIT_CONST) { | 1503 } else if (var->mode() != Variable::CONST || op == Token::INIT_CONST) { |
1505 // Perform the assignment for non-const variables and for initialization | 1504 // Perform the assignment for non-const variables and for initialization |
1506 // of const variables. Const assignments are simply skipped. | 1505 // of const variables. Const assignments are simply skipped. |
1507 Label done; | 1506 Label done; |
1508 Slot* slot = var->slot(); | 1507 Slot* slot = var->AsSlot(); |
1509 switch (slot->type()) { | 1508 switch (slot->type()) { |
1510 case Slot::PARAMETER: | 1509 case Slot::PARAMETER: |
1511 case Slot::LOCAL: | 1510 case Slot::LOCAL: |
1512 if (op == Token::INIT_CONST) { | 1511 if (op == Token::INIT_CONST) { |
1513 // Detect const reinitialization by checking for the hole value. | 1512 // Detect const reinitialization by checking for the hole value. |
1514 __ ldr(r1, MemOperand(fp, SlotOffset(slot))); | 1513 __ ldr(r1, MemOperand(fp, SlotOffset(slot))); |
1515 __ LoadRoot(ip, Heap::kTheHoleValueRootIndex); | 1514 __ LoadRoot(ip, Heap::kTheHoleValueRootIndex); |
1516 __ cmp(r1, ip); | 1515 __ cmp(r1, ip); |
1517 __ b(ne, &done); | 1516 __ b(ne, &done); |
1518 } | 1517 } |
(...skipping 259 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1778 CallFunctionStub stub(arg_count, in_loop, RECEIVER_MIGHT_BE_VALUE); | 1777 CallFunctionStub stub(arg_count, in_loop, RECEIVER_MIGHT_BE_VALUE); |
1779 __ CallStub(&stub); | 1778 __ CallStub(&stub); |
1780 // Restore context register. | 1779 // Restore context register. |
1781 __ ldr(cp, MemOperand(fp, StandardFrameConstants::kContextOffset)); | 1780 __ ldr(cp, MemOperand(fp, StandardFrameConstants::kContextOffset)); |
1782 context()->DropAndPlug(1, r0); | 1781 context()->DropAndPlug(1, r0); |
1783 } else if (var != NULL && !var->is_this() && var->is_global()) { | 1782 } else if (var != NULL && !var->is_this() && var->is_global()) { |
1784 // Push global object as receiver for the call IC. | 1783 // Push global object as receiver for the call IC. |
1785 __ ldr(r0, CodeGenerator::GlobalObject()); | 1784 __ ldr(r0, CodeGenerator::GlobalObject()); |
1786 __ push(r0); | 1785 __ push(r0); |
1787 EmitCallWithIC(expr, var->name(), RelocInfo::CODE_TARGET_CONTEXT); | 1786 EmitCallWithIC(expr, var->name(), RelocInfo::CODE_TARGET_CONTEXT); |
1788 } else if (var != NULL && var->slot() != NULL && | 1787 } else if (var != NULL && var->AsSlot() != NULL && |
1789 var->slot()->type() == Slot::LOOKUP) { | 1788 var->AsSlot()->type() == Slot::LOOKUP) { |
1790 // Call to a lookup slot (dynamically introduced variable). | 1789 // Call to a lookup slot (dynamically introduced variable). |
1791 Label slow, done; | 1790 Label slow, done; |
1792 | 1791 |
1793 // Generate code for loading from variables potentially shadowed | 1792 // Generate code for loading from variables potentially shadowed |
1794 // by eval-introduced variables. | 1793 // by eval-introduced variables. |
1795 EmitDynamicLoadFromSlotFastCase(var->slot(), | 1794 EmitDynamicLoadFromSlotFastCase(var->AsSlot(), |
1796 NOT_INSIDE_TYPEOF, | 1795 NOT_INSIDE_TYPEOF, |
1797 &slow, | 1796 &slow, |
1798 &done); | 1797 &done); |
1799 | 1798 |
1800 __ bind(&slow); | 1799 __ bind(&slow); |
1801 // Call the runtime to find the function to call (returned in r0) | 1800 // Call the runtime to find the function to call (returned in r0) |
1802 // and the object holding it (returned in edx). | 1801 // and the object holding it (returned in edx). |
1803 __ push(context_register()); | 1802 __ push(context_register()); |
1804 __ mov(r2, Operand(var->name())); | 1803 __ mov(r2, Operand(var->name())); |
1805 __ push(r2); | 1804 __ push(r2); |
(...skipping 969 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2775 Comment cmnt(masm_, "[ UnaryOperation (DELETE)"); | 2774 Comment cmnt(masm_, "[ UnaryOperation (DELETE)"); |
2776 Property* prop = expr->expression()->AsProperty(); | 2775 Property* prop = expr->expression()->AsProperty(); |
2777 Variable* var = expr->expression()->AsVariableProxy()->AsVariable(); | 2776 Variable* var = expr->expression()->AsVariableProxy()->AsVariable(); |
2778 if (prop == NULL && var == NULL) { | 2777 if (prop == NULL && var == NULL) { |
2779 // Result of deleting non-property, non-variable reference is true. | 2778 // Result of deleting non-property, non-variable reference is true. |
2780 // The subexpression may have side effects. | 2779 // The subexpression may have side effects. |
2781 VisitForEffect(expr->expression()); | 2780 VisitForEffect(expr->expression()); |
2782 context()->Plug(true); | 2781 context()->Plug(true); |
2783 } else if (var != NULL && | 2782 } else if (var != NULL && |
2784 !var->is_global() && | 2783 !var->is_global() && |
2785 var->slot() != NULL && | 2784 var->AsSlot() != NULL && |
2786 var->slot()->type() != Slot::LOOKUP) { | 2785 var->AsSlot()->type() != Slot::LOOKUP) { |
2787 // Result of deleting non-global, non-dynamic variables is false. | 2786 // Result of deleting non-global, non-dynamic variables is false. |
2788 // The subexpression does not have side effects. | 2787 // The subexpression does not have side effects. |
2789 context()->Plug(false); | 2788 context()->Plug(false); |
2790 } else { | 2789 } else { |
2791 // Property or variable reference. Call the delete builtin with | 2790 // Property or variable reference. Call the delete builtin with |
2792 // object and property name as arguments. | 2791 // object and property name as arguments. |
2793 if (prop != NULL) { | 2792 if (prop != NULL) { |
2794 VisitForStackValue(prop->obj()); | 2793 VisitForStackValue(prop->obj()); |
2795 VisitForStackValue(prop->key()); | 2794 VisitForStackValue(prop->key()); |
2796 } else if (var->is_global()) { | 2795 } else if (var->is_global()) { |
(...skipping 264 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3061 if (proxy != NULL && !proxy->var()->is_this() && proxy->var()->is_global()) { | 3060 if (proxy != NULL && !proxy->var()->is_this() && proxy->var()->is_global()) { |
3062 Comment cmnt(masm_, "Global variable"); | 3061 Comment cmnt(masm_, "Global variable"); |
3063 __ ldr(r0, CodeGenerator::GlobalObject()); | 3062 __ ldr(r0, CodeGenerator::GlobalObject()); |
3064 __ mov(r2, Operand(proxy->name())); | 3063 __ mov(r2, Operand(proxy->name())); |
3065 Handle<Code> ic(Builtins::builtin(Builtins::LoadIC_Initialize)); | 3064 Handle<Code> ic(Builtins::builtin(Builtins::LoadIC_Initialize)); |
3066 // Use a regular load, not a contextual load, to avoid a reference | 3065 // Use a regular load, not a contextual load, to avoid a reference |
3067 // error. | 3066 // error. |
3068 EmitCallIC(ic, RelocInfo::CODE_TARGET); | 3067 EmitCallIC(ic, RelocInfo::CODE_TARGET); |
3069 context()->Plug(r0); | 3068 context()->Plug(r0); |
3070 } else if (proxy != NULL && | 3069 } else if (proxy != NULL && |
3071 proxy->var()->slot() != NULL && | 3070 proxy->var()->AsSlot() != NULL && |
3072 proxy->var()->slot()->type() == Slot::LOOKUP) { | 3071 proxy->var()->AsSlot()->type() == Slot::LOOKUP) { |
3073 Label done, slow; | 3072 Label done, slow; |
3074 | 3073 |
3075 // Generate code for loading from variables potentially shadowed | 3074 // Generate code for loading from variables potentially shadowed |
3076 // by eval-introduced variables. | 3075 // by eval-introduced variables. |
3077 Slot* slot = proxy->var()->slot(); | 3076 Slot* slot = proxy->var()->AsSlot(); |
3078 EmitDynamicLoadFromSlotFastCase(slot, INSIDE_TYPEOF, &slow, &done); | 3077 EmitDynamicLoadFromSlotFastCase(slot, INSIDE_TYPEOF, &slow, &done); |
3079 | 3078 |
3080 __ bind(&slow); | 3079 __ bind(&slow); |
3081 __ mov(r0, Operand(proxy->name())); | 3080 __ mov(r0, Operand(proxy->name())); |
3082 __ Push(cp, r0); | 3081 __ Push(cp, r0); |
3083 __ CallRuntime(Runtime::kLoadContextSlotNoReferenceError, 2); | 3082 __ CallRuntime(Runtime::kLoadContextSlotNoReferenceError, 2); |
3084 __ bind(&done); | 3083 __ bind(&done); |
3085 | 3084 |
3086 context()->Plug(r0); | 3085 context()->Plug(r0); |
3087 } else { | 3086 } else { |
(...skipping 296 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3384 __ mov(r1, Operand(r1, ASR, 1)); // Un-smi-tag value. | 3383 __ mov(r1, Operand(r1, ASR, 1)); // Un-smi-tag value. |
3385 __ add(pc, r1, Operand(masm_->CodeObject())); | 3384 __ add(pc, r1, Operand(masm_->CodeObject())); |
3386 } | 3385 } |
3387 | 3386 |
3388 | 3387 |
3389 #undef __ | 3388 #undef __ |
3390 | 3389 |
3391 } } // namespace v8::internal | 3390 } } // namespace v8::internal |
3392 | 3391 |
3393 #endif // V8_TARGET_ARCH_ARM | 3392 #endif // V8_TARGET_ARCH_ARM |
OLD | NEW |