| 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 #if V8_TARGET_ARCH_ARM64 | 5 #if V8_TARGET_ARCH_ARM64 |
| 6 | 6 |
| 7 #include "src/ast/scopes.h" | 7 #include "src/ast/scopes.h" |
| 8 #include "src/code-factory.h" | 8 #include "src/code-factory.h" |
| 9 #include "src/code-stubs.h" | 9 #include "src/code-stubs.h" |
| 10 #include "src/codegen.h" | 10 #include "src/codegen.h" |
| (...skipping 739 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 750 | 750 |
| 751 | 751 |
| 752 void FullCodeGenerator::VisitVariableDeclaration( | 752 void FullCodeGenerator::VisitVariableDeclaration( |
| 753 VariableDeclaration* declaration) { | 753 VariableDeclaration* declaration) { |
| 754 // If it was not possible to allocate the variable at compile time, we | 754 // If it was not possible to allocate the variable at compile time, we |
| 755 // need to "declare" it at runtime to make sure it actually exists in the | 755 // need to "declare" it at runtime to make sure it actually exists in the |
| 756 // local context. | 756 // local context. |
| 757 VariableProxy* proxy = declaration->proxy(); | 757 VariableProxy* proxy = declaration->proxy(); |
| 758 VariableMode mode = declaration->mode(); | 758 VariableMode mode = declaration->mode(); |
| 759 Variable* variable = proxy->var(); | 759 Variable* variable = proxy->var(); |
| 760 bool hole_init = mode == LET || mode == CONST || mode == CONST_LEGACY; | 760 bool hole_init = mode == LET || mode == CONST; |
| 761 | 761 |
| 762 switch (variable->location()) { | 762 switch (variable->location()) { |
| 763 case VariableLocation::GLOBAL: | 763 case VariableLocation::GLOBAL: |
| 764 case VariableLocation::UNALLOCATED: | 764 case VariableLocation::UNALLOCATED: |
| 765 globals_->Add(variable->name(), zone()); | 765 globals_->Add(variable->name(), zone()); |
| 766 globals_->Add(variable->binding_needs_init() | 766 globals_->Add(variable->binding_needs_init() |
| 767 ? isolate()->factory()->the_hole_value() | 767 ? isolate()->factory()->the_hole_value() |
| 768 : isolate()->factory()->undefined_value(), | 768 : isolate()->factory()->undefined_value(), |
| 769 zone()); | 769 zone()); |
| 770 break; | 770 break; |
| (...skipping 492 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1263 // introducing variables. In those cases, we do not want to | 1263 // introducing variables. In those cases, we do not want to |
| 1264 // perform a runtime call for all variables in the scope | 1264 // perform a runtime call for all variables in the scope |
| 1265 // containing the eval. | 1265 // containing the eval. |
| 1266 Variable* var = proxy->var(); | 1266 Variable* var = proxy->var(); |
| 1267 if (var->mode() == DYNAMIC_GLOBAL) { | 1267 if (var->mode() == DYNAMIC_GLOBAL) { |
| 1268 EmitLoadGlobalCheckExtensions(proxy, typeof_mode, slow); | 1268 EmitLoadGlobalCheckExtensions(proxy, typeof_mode, slow); |
| 1269 __ B(done); | 1269 __ B(done); |
| 1270 } else if (var->mode() == DYNAMIC_LOCAL) { | 1270 } else if (var->mode() == DYNAMIC_LOCAL) { |
| 1271 Variable* local = var->local_if_not_shadowed(); | 1271 Variable* local = var->local_if_not_shadowed(); |
| 1272 __ Ldr(x0, ContextSlotOperandCheckExtensions(local, slow)); | 1272 __ Ldr(x0, ContextSlotOperandCheckExtensions(local, slow)); |
| 1273 if (local->mode() == LET || local->mode() == CONST || | 1273 if (local->mode() == LET || local->mode() == CONST) { |
| 1274 local->mode() == CONST_LEGACY) { | |
| 1275 __ JumpIfNotRoot(x0, Heap::kTheHoleValueRootIndex, done); | 1274 __ JumpIfNotRoot(x0, Heap::kTheHoleValueRootIndex, done); |
| 1276 if (local->mode() == CONST_LEGACY) { | 1275 __ Mov(x0, Operand(var->name())); |
| 1277 __ LoadRoot(x0, Heap::kUndefinedValueRootIndex); | 1276 __ Push(x0); |
| 1278 } else { // LET || CONST | 1277 __ CallRuntime(Runtime::kThrowReferenceError); |
| 1279 __ Mov(x0, Operand(var->name())); | |
| 1280 __ Push(x0); | |
| 1281 __ CallRuntime(Runtime::kThrowReferenceError); | |
| 1282 } | |
| 1283 } | 1278 } |
| 1284 __ B(done); | 1279 __ B(done); |
| 1285 } | 1280 } |
| 1286 } | 1281 } |
| 1287 | 1282 |
| 1288 | 1283 |
| 1289 void FullCodeGenerator::EmitGlobalVariableLoad(VariableProxy* proxy, | 1284 void FullCodeGenerator::EmitGlobalVariableLoad(VariableProxy* proxy, |
| 1290 TypeofMode typeof_mode) { | 1285 TypeofMode typeof_mode) { |
| 1291 Variable* var = proxy->var(); | 1286 Variable* var = proxy->var(); |
| 1292 DCHECK(var->IsUnallocatedOrGlobalSlot() || | 1287 DCHECK(var->IsUnallocatedOrGlobalSlot() || |
| (...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1329 GetVar(x0, var); | 1324 GetVar(x0, var); |
| 1330 Label done; | 1325 Label done; |
| 1331 __ JumpIfNotRoot(x0, Heap::kTheHoleValueRootIndex, &done); | 1326 __ JumpIfNotRoot(x0, Heap::kTheHoleValueRootIndex, &done); |
| 1332 if (var->mode() == LET || var->mode() == CONST) { | 1327 if (var->mode() == LET || var->mode() == CONST) { |
| 1333 // Throw a reference error when using an uninitialized let/const | 1328 // Throw a reference error when using an uninitialized let/const |
| 1334 // binding in harmony mode. | 1329 // binding in harmony mode. |
| 1335 __ Mov(x0, Operand(var->name())); | 1330 __ Mov(x0, Operand(var->name())); |
| 1336 __ Push(x0); | 1331 __ Push(x0); |
| 1337 __ CallRuntime(Runtime::kThrowReferenceError); | 1332 __ CallRuntime(Runtime::kThrowReferenceError); |
| 1338 __ Bind(&done); | 1333 __ Bind(&done); |
| 1339 } else { | |
| 1340 // Uninitialized legacy const bindings are unholed. | |
| 1341 DCHECK(var->mode() == CONST_LEGACY); | |
| 1342 __ LoadRoot(x0, Heap::kUndefinedValueRootIndex); | |
| 1343 __ Bind(&done); | |
| 1344 } | 1334 } |
| 1345 context()->Plug(x0); | 1335 context()->Plug(x0); |
| 1346 break; | 1336 break; |
| 1347 } | 1337 } |
| 1348 context()->Plug(var); | 1338 context()->Plug(var); |
| 1349 break; | 1339 break; |
| 1350 } | 1340 } |
| 1351 | 1341 |
| 1352 case VariableLocation::LOOKUP: { | 1342 case VariableLocation::LOOKUP: { |
| 1353 Label done, slow; | 1343 Label done, slow; |
| (...skipping 767 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2121 Label uninitialized_this; | 2111 Label uninitialized_this; |
| 2122 MemOperand location = VarOperand(var, x1); | 2112 MemOperand location = VarOperand(var, x1); |
| 2123 __ Ldr(x10, location); | 2113 __ Ldr(x10, location); |
| 2124 __ JumpIfRoot(x10, Heap::kTheHoleValueRootIndex, &uninitialized_this); | 2114 __ JumpIfRoot(x10, Heap::kTheHoleValueRootIndex, &uninitialized_this); |
| 2125 __ Mov(x0, Operand(var->name())); | 2115 __ Mov(x0, Operand(var->name())); |
| 2126 __ Push(x0); | 2116 __ Push(x0); |
| 2127 __ CallRuntime(Runtime::kThrowReferenceError); | 2117 __ CallRuntime(Runtime::kThrowReferenceError); |
| 2128 __ bind(&uninitialized_this); | 2118 __ bind(&uninitialized_this); |
| 2129 EmitStoreToStackLocalOrContextSlot(var, location); | 2119 EmitStoreToStackLocalOrContextSlot(var, location); |
| 2130 | 2120 |
| 2131 } else if (!var->is_const_mode() || | 2121 } else if (!var->is_const_mode() || op == Token::INIT) { |
| 2132 (var->mode() == CONST && op == Token::INIT)) { | |
| 2133 if (var->IsLookupSlot()) { | 2122 if (var->IsLookupSlot()) { |
| 2134 // Assignment to var. | 2123 // Assignment to var. |
| 2135 __ Push(var->name()); | 2124 __ Push(var->name()); |
| 2136 __ Push(x0); | 2125 __ Push(x0); |
| 2137 __ CallRuntime(is_strict(language_mode()) | 2126 __ CallRuntime(is_strict(language_mode()) |
| 2138 ? Runtime::kStoreLookupSlot_Strict | 2127 ? Runtime::kStoreLookupSlot_Strict |
| 2139 : Runtime::kStoreLookupSlot_Sloppy); | 2128 : Runtime::kStoreLookupSlot_Sloppy); |
| 2140 } else { | 2129 } else { |
| 2141 // Assignment to var or initializing assignment to let/const in harmony | 2130 // Assignment to var or initializing assignment to let/const in harmony |
| 2142 // mode. | 2131 // mode. |
| 2143 DCHECK(var->IsStackAllocated() || var->IsContextSlot()); | 2132 DCHECK(var->IsStackAllocated() || var->IsContextSlot()); |
| 2144 MemOperand location = VarOperand(var, x1); | 2133 MemOperand location = VarOperand(var, x1); |
| 2145 if (FLAG_debug_code && var->mode() == LET && op == Token::INIT) { | 2134 if (FLAG_debug_code && var->mode() == LET && op == Token::INIT) { |
| 2146 __ Ldr(x10, location); | 2135 __ Ldr(x10, location); |
| 2147 __ CompareRoot(x10, Heap::kTheHoleValueRootIndex); | 2136 __ CompareRoot(x10, Heap::kTheHoleValueRootIndex); |
| 2148 __ Check(eq, kLetBindingReInitialization); | 2137 __ Check(eq, kLetBindingReInitialization); |
| 2149 } | 2138 } |
| 2150 EmitStoreToStackLocalOrContextSlot(var, location); | 2139 EmitStoreToStackLocalOrContextSlot(var, location); |
| 2151 } | 2140 } |
| 2152 | 2141 |
| 2153 } else if (var->mode() == CONST_LEGACY && op == Token::INIT) { | |
| 2154 // Const initializers need a write barrier. | |
| 2155 DCHECK(!var->IsParameter()); // No const parameters. | |
| 2156 if (var->IsLookupSlot()) { | |
| 2157 __ Mov(x1, Operand(var->name())); | |
| 2158 __ Push(x0, cp, x1); | |
| 2159 __ CallRuntime(Runtime::kInitializeLegacyConstLookupSlot); | |
| 2160 } else { | |
| 2161 DCHECK(var->IsStackLocal() || var->IsContextSlot()); | |
| 2162 Label skip; | |
| 2163 MemOperand location = VarOperand(var, x1); | |
| 2164 __ Ldr(x10, location); | |
| 2165 __ JumpIfNotRoot(x10, Heap::kTheHoleValueRootIndex, &skip); | |
| 2166 EmitStoreToStackLocalOrContextSlot(var, location); | |
| 2167 __ Bind(&skip); | |
| 2168 } | |
| 2169 | |
| 2170 } else { | 2142 } else { |
| 2171 DCHECK(var->mode() == CONST_LEGACY && op != Token::INIT); | 2143 DCHECK(var->mode() == CONST_LEGACY && op != Token::INIT); |
| 2172 if (is_strict(language_mode())) { | 2144 if (is_strict(language_mode())) { |
| 2173 __ CallRuntime(Runtime::kThrowConstAssignError); | 2145 __ CallRuntime(Runtime::kThrowConstAssignError); |
| 2174 } | 2146 } |
| 2175 // Silently ignore store in sloppy mode. | 2147 // Silently ignore store in sloppy mode. |
| 2176 } | 2148 } |
| 2177 } | 2149 } |
| 2178 | 2150 |
| 2179 | 2151 |
| (...skipping 1877 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 4057 } | 4029 } |
| 4058 | 4030 |
| 4059 return INTERRUPT; | 4031 return INTERRUPT; |
| 4060 } | 4032 } |
| 4061 | 4033 |
| 4062 | 4034 |
| 4063 } // namespace internal | 4035 } // namespace internal |
| 4064 } // namespace v8 | 4036 } // namespace v8 |
| 4065 | 4037 |
| 4066 #endif // V8_TARGET_ARCH_ARM64 | 4038 #endif // V8_TARGET_ARCH_ARM64 |
| OLD | NEW |