| OLD | NEW |
| 1 // Copyright 2013 the V8 project authors. All rights reserved. | 1 // Copyright 2013 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_ARM64 | 7 #if V8_TARGET_ARCH_ARM64 |
| 8 | 8 |
| 9 #include "src/code-stubs.h" | 9 #include "src/code-stubs.h" |
| 10 #include "src/codegen.h" | 10 #include "src/codegen.h" |
| (...skipping 841 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 852 // Note: For variables we must not push an initial value (such as | 852 // Note: For variables we must not push an initial value (such as |
| 853 // 'undefined') because we may have a (legal) redeclaration and we | 853 // 'undefined') because we may have a (legal) redeclaration and we |
| 854 // must not destroy the current value. | 854 // must not destroy the current value. |
| 855 if (hole_init) { | 855 if (hole_init) { |
| 856 __ LoadRoot(x0, Heap::kTheHoleValueRootIndex); | 856 __ LoadRoot(x0, Heap::kTheHoleValueRootIndex); |
| 857 __ Push(cp, x2, x1, x0); | 857 __ Push(cp, x2, x1, x0); |
| 858 } else { | 858 } else { |
| 859 // Pushing 0 (xzr) indicates no initial value. | 859 // Pushing 0 (xzr) indicates no initial value. |
| 860 __ Push(cp, x2, x1, xzr); | 860 __ Push(cp, x2, x1, xzr); |
| 861 } | 861 } |
| 862 __ CallRuntime(Runtime::kDeclareContextSlot, 4); | 862 __ CallRuntime(Runtime::kDeclareLookupSlot, 4); |
| 863 break; | 863 break; |
| 864 } | 864 } |
| 865 } | 865 } |
| 866 } | 866 } |
| 867 | 867 |
| 868 | 868 |
| 869 void FullCodeGenerator::VisitFunctionDeclaration( | 869 void FullCodeGenerator::VisitFunctionDeclaration( |
| 870 FunctionDeclaration* declaration) { | 870 FunctionDeclaration* declaration) { |
| 871 VariableProxy* proxy = declaration->proxy(); | 871 VariableProxy* proxy = declaration->proxy(); |
| 872 Variable* variable = proxy->var(); | 872 Variable* variable = proxy->var(); |
| (...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 908 break; | 908 break; |
| 909 } | 909 } |
| 910 | 910 |
| 911 case Variable::LOOKUP: { | 911 case Variable::LOOKUP: { |
| 912 Comment cmnt(masm_, "[ Function Declaration"); | 912 Comment cmnt(masm_, "[ Function Declaration"); |
| 913 __ Mov(x2, Operand(variable->name())); | 913 __ Mov(x2, Operand(variable->name())); |
| 914 __ Mov(x1, Smi::FromInt(NONE)); | 914 __ Mov(x1, Smi::FromInt(NONE)); |
| 915 __ Push(cp, x2, x1); | 915 __ Push(cp, x2, x1); |
| 916 // Push initial value for function declaration. | 916 // Push initial value for function declaration. |
| 917 VisitForStackValue(declaration->fun()); | 917 VisitForStackValue(declaration->fun()); |
| 918 __ CallRuntime(Runtime::kDeclareContextSlot, 4); | 918 __ CallRuntime(Runtime::kDeclareLookupSlot, 4); |
| 919 break; | 919 break; |
| 920 } | 920 } |
| 921 } | 921 } |
| 922 } | 922 } |
| 923 | 923 |
| 924 | 924 |
| 925 void FullCodeGenerator::VisitModuleDeclaration(ModuleDeclaration* declaration) { | 925 void FullCodeGenerator::VisitModuleDeclaration(ModuleDeclaration* declaration) { |
| 926 Variable* variable = declaration->proxy()->var(); | 926 Variable* variable = declaration->proxy()->var(); |
| 927 ASSERT(variable->location() == Variable::CONTEXT); | 927 ASSERT(variable->location() == Variable::CONTEXT); |
| 928 ASSERT(variable->interface()->IsFrozen()); | 928 ASSERT(variable->interface()->IsFrozen()); |
| (...skipping 1204 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2133 if (var->IsContextSlot()) { | 2133 if (var->IsContextSlot()) { |
| 2134 // RecordWrite may destroy all its register arguments. | 2134 // RecordWrite may destroy all its register arguments. |
| 2135 __ Mov(x10, result_register()); | 2135 __ Mov(x10, result_register()); |
| 2136 int offset = Context::SlotOffset(var->index()); | 2136 int offset = Context::SlotOffset(var->index()); |
| 2137 __ RecordWriteContextSlot( | 2137 __ RecordWriteContextSlot( |
| 2138 x1, offset, x10, x11, kLRHasBeenSaved, kDontSaveFPRegs); | 2138 x1, offset, x10, x11, kLRHasBeenSaved, kDontSaveFPRegs); |
| 2139 } | 2139 } |
| 2140 } | 2140 } |
| 2141 | 2141 |
| 2142 | 2142 |
| 2143 void FullCodeGenerator::EmitCallStoreContextSlot( | |
| 2144 Handle<String> name, StrictMode strict_mode) { | |
| 2145 __ Mov(x11, Operand(name)); | |
| 2146 __ Mov(x10, Smi::FromInt(strict_mode)); | |
| 2147 // jssp[0] : mode. | |
| 2148 // jssp[8] : name. | |
| 2149 // jssp[16] : context. | |
| 2150 // jssp[24] : value. | |
| 2151 __ Push(x0, cp, x11, x10); | |
| 2152 __ CallRuntime(Runtime::kStoreContextSlot, 4); | |
| 2153 } | |
| 2154 | |
| 2155 | |
| 2156 void FullCodeGenerator::EmitVariableAssignment(Variable* var, | 2143 void FullCodeGenerator::EmitVariableAssignment(Variable* var, |
| 2157 Token::Value op) { | 2144 Token::Value op) { |
| 2158 ASM_LOCATION("FullCodeGenerator::EmitVariableAssignment"); | 2145 ASM_LOCATION("FullCodeGenerator::EmitVariableAssignment"); |
| 2159 if (var->IsUnallocated()) { | 2146 if (var->IsUnallocated()) { |
| 2160 // Global var, const, or let. | 2147 // Global var, const, or let. |
| 2161 __ Mov(x2, Operand(var->name())); | 2148 __ Mov(x2, Operand(var->name())); |
| 2162 __ Ldr(x1, GlobalObjectMemOperand()); | 2149 __ Ldr(x1, GlobalObjectMemOperand()); |
| 2163 CallStoreIC(); | 2150 CallStoreIC(); |
| 2164 | 2151 |
| 2165 } else if (op == Token::INIT_CONST_LEGACY) { | 2152 } else if (op == Token::INIT_CONST_LEGACY) { |
| 2166 // Const initializers need a write barrier. | 2153 // Const initializers need a write barrier. |
| 2167 ASSERT(!var->IsParameter()); // No const parameters. | 2154 ASSERT(!var->IsParameter()); // No const parameters. |
| 2168 if (var->IsLookupSlot()) { | 2155 if (var->IsLookupSlot()) { |
| 2169 __ Mov(x1, Operand(var->name())); | 2156 __ Mov(x1, Operand(var->name())); |
| 2170 __ Push(x0, cp, x1); | 2157 __ Push(x0, cp, x1); |
| 2171 __ CallRuntime(Runtime::kInitializeConstContextSlot, 3); | 2158 __ CallRuntime(Runtime::kInitializeLegacyConstLookupSlot, 3); |
| 2172 } else { | 2159 } else { |
| 2173 ASSERT(var->IsStackLocal() || var->IsContextSlot()); | 2160 ASSERT(var->IsStackLocal() || var->IsContextSlot()); |
| 2174 Label skip; | 2161 Label skip; |
| 2175 MemOperand location = VarOperand(var, x1); | 2162 MemOperand location = VarOperand(var, x1); |
| 2176 __ Ldr(x10, location); | 2163 __ Ldr(x10, location); |
| 2177 __ JumpIfNotRoot(x10, Heap::kTheHoleValueRootIndex, &skip); | 2164 __ JumpIfNotRoot(x10, Heap::kTheHoleValueRootIndex, &skip); |
| 2178 EmitStoreToStackLocalOrContextSlot(var, location); | 2165 EmitStoreToStackLocalOrContextSlot(var, location); |
| 2179 __ Bind(&skip); | 2166 __ Bind(&skip); |
| 2180 } | 2167 } |
| 2181 | 2168 |
| 2182 } else if (var->mode() == LET && op != Token::INIT_LET) { | 2169 } else if (var->mode() == LET && op != Token::INIT_LET) { |
| 2183 // Non-initializing assignment to let variable needs a write barrier. | 2170 // Non-initializing assignment to let variable needs a write barrier. |
| 2184 if (var->IsLookupSlot()) { | 2171 ASSERT(!var->IsLookupSlot()); |
| 2185 EmitCallStoreContextSlot(var->name(), strict_mode()); | 2172 ASSERT(var->IsStackAllocated() || var->IsContextSlot()); |
| 2186 } else { | 2173 Label assign; |
| 2187 ASSERT(var->IsStackAllocated() || var->IsContextSlot()); | 2174 MemOperand location = VarOperand(var, x1); |
| 2188 Label assign; | 2175 __ Ldr(x10, location); |
| 2189 MemOperand location = VarOperand(var, x1); | 2176 __ JumpIfNotRoot(x10, Heap::kTheHoleValueRootIndex, &assign); |
| 2190 __ Ldr(x10, location); | 2177 __ Mov(x10, Operand(var->name())); |
| 2191 __ JumpIfNotRoot(x10, Heap::kTheHoleValueRootIndex, &assign); | 2178 __ Push(x10); |
| 2192 __ Mov(x10, Operand(var->name())); | 2179 __ CallRuntime(Runtime::kThrowReferenceError, 1); |
| 2193 __ Push(x10); | 2180 // Perform the assignment. |
| 2194 __ CallRuntime(Runtime::kThrowReferenceError, 1); | 2181 __ Bind(&assign); |
| 2195 // Perform the assignment. | 2182 EmitStoreToStackLocalOrContextSlot(var, location); |
| 2196 __ Bind(&assign); | |
| 2197 EmitStoreToStackLocalOrContextSlot(var, location); | |
| 2198 } | |
| 2199 | 2183 |
| 2200 } else if (!var->is_const_mode() || op == Token::INIT_CONST) { | 2184 } else if (!var->is_const_mode() || op == Token::INIT_CONST) { |
| 2201 // Assignment to var or initializing assignment to let/const | |
| 2202 // in harmony mode. | |
| 2203 if (var->IsLookupSlot()) { | 2185 if (var->IsLookupSlot()) { |
| 2204 EmitCallStoreContextSlot(var->name(), strict_mode()); | 2186 ASSERT(op == Token::ASSIGN || op == Token::INIT_VAR || |
| 2187 op == Token::ASSIGN_ADD); |
| 2188 // Assignment to var. |
| 2189 __ Mov(x11, Operand(var->name())); |
| 2190 __ Mov(x10, Smi::FromInt(strict_mode())); |
| 2191 // jssp[0] : mode. |
| 2192 // jssp[8] : name. |
| 2193 // jssp[16] : context. |
| 2194 // jssp[24] : value. |
| 2195 __ Push(x0, cp, x11, x10); |
| 2196 __ CallRuntime(Runtime::kStoreLookupSlot, 4); |
| 2205 } else { | 2197 } else { |
| 2198 // Assignment to var or initializing assignment to let/const in harmony |
| 2199 // mode. |
| 2206 ASSERT(var->IsStackAllocated() || var->IsContextSlot()); | 2200 ASSERT(var->IsStackAllocated() || var->IsContextSlot()); |
| 2207 MemOperand location = VarOperand(var, x1); | 2201 MemOperand location = VarOperand(var, x1); |
| 2208 if (FLAG_debug_code && op == Token::INIT_LET) { | 2202 if (FLAG_debug_code && op == Token::INIT_LET) { |
| 2209 __ Ldr(x10, location); | 2203 __ Ldr(x10, location); |
| 2210 __ CompareRoot(x10, Heap::kTheHoleValueRootIndex); | 2204 __ CompareRoot(x10, Heap::kTheHoleValueRootIndex); |
| 2211 __ Check(eq, kLetBindingReInitialization); | 2205 __ Check(eq, kLetBindingReInitialization); |
| 2212 } | 2206 } |
| 2213 EmitStoreToStackLocalOrContextSlot(var, location); | 2207 EmitStoreToStackLocalOrContextSlot(var, location); |
| 2214 } | 2208 } |
| 2215 } | 2209 } |
| (...skipping 2675 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 4891 return previous_; | 4885 return previous_; |
| 4892 } | 4886 } |
| 4893 | 4887 |
| 4894 | 4888 |
| 4895 #undef __ | 4889 #undef __ |
| 4896 | 4890 |
| 4897 | 4891 |
| 4898 } } // namespace v8::internal | 4892 } } // namespace v8::internal |
| 4899 | 4893 |
| 4900 #endif // V8_TARGET_ARCH_ARM64 | 4894 #endif // V8_TARGET_ARCH_ARM64 |
| OLD | NEW |