| OLD | NEW |
| 1 // Copyright 2014 the V8 project authors. All rights reserved. | 1 // Copyright 2014 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_PPC | 5 #if V8_TARGET_ARCH_PPC |
| 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 705 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 716 | 716 |
| 717 | 717 |
| 718 void FullCodeGenerator::VisitVariableDeclaration( | 718 void FullCodeGenerator::VisitVariableDeclaration( |
| 719 VariableDeclaration* declaration) { | 719 VariableDeclaration* declaration) { |
| 720 // If it was not possible to allocate the variable at compile time, we | 720 // If it was not possible to allocate the variable at compile time, we |
| 721 // need to "declare" it at runtime to make sure it actually exists in the | 721 // need to "declare" it at runtime to make sure it actually exists in the |
| 722 // local context. | 722 // local context. |
| 723 VariableProxy* proxy = declaration->proxy(); | 723 VariableProxy* proxy = declaration->proxy(); |
| 724 VariableMode mode = declaration->mode(); | 724 VariableMode mode = declaration->mode(); |
| 725 Variable* variable = proxy->var(); | 725 Variable* variable = proxy->var(); |
| 726 bool hole_init = mode == LET || mode == CONST || mode == CONST_LEGACY; | 726 bool hole_init = mode == LET || mode == CONST; |
| 727 switch (variable->location()) { | 727 switch (variable->location()) { |
| 728 case VariableLocation::GLOBAL: | 728 case VariableLocation::GLOBAL: |
| 729 case VariableLocation::UNALLOCATED: | 729 case VariableLocation::UNALLOCATED: |
| 730 globals_->Add(variable->name(), zone()); | 730 globals_->Add(variable->name(), zone()); |
| 731 globals_->Add(variable->binding_needs_init() | 731 globals_->Add(variable->binding_needs_init() |
| 732 ? isolate()->factory()->the_hole_value() | 732 ? isolate()->factory()->the_hole_value() |
| 733 : isolate()->factory()->undefined_value(), | 733 : isolate()->factory()->undefined_value(), |
| 734 zone()); | 734 zone()); |
| 735 break; | 735 break; |
| 736 | 736 |
| (...skipping 502 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1239 // introducing variables. In those cases, we do not want to | 1239 // introducing variables. In those cases, we do not want to |
| 1240 // perform a runtime call for all variables in the scope | 1240 // perform a runtime call for all variables in the scope |
| 1241 // containing the eval. | 1241 // containing the eval. |
| 1242 Variable* var = proxy->var(); | 1242 Variable* var = proxy->var(); |
| 1243 if (var->mode() == DYNAMIC_GLOBAL) { | 1243 if (var->mode() == DYNAMIC_GLOBAL) { |
| 1244 EmitLoadGlobalCheckExtensions(proxy, typeof_mode, slow); | 1244 EmitLoadGlobalCheckExtensions(proxy, typeof_mode, slow); |
| 1245 __ b(done); | 1245 __ b(done); |
| 1246 } else if (var->mode() == DYNAMIC_LOCAL) { | 1246 } else if (var->mode() == DYNAMIC_LOCAL) { |
| 1247 Variable* local = var->local_if_not_shadowed(); | 1247 Variable* local = var->local_if_not_shadowed(); |
| 1248 __ LoadP(r3, ContextSlotOperandCheckExtensions(local, slow)); | 1248 __ LoadP(r3, ContextSlotOperandCheckExtensions(local, slow)); |
| 1249 if (local->mode() == LET || local->mode() == CONST || | 1249 if (local->mode() == LET || local->mode() == CONST) { |
| 1250 local->mode() == CONST_LEGACY) { | |
| 1251 __ CompareRoot(r3, Heap::kTheHoleValueRootIndex); | 1250 __ CompareRoot(r3, Heap::kTheHoleValueRootIndex); |
| 1252 __ bne(done); | 1251 __ bne(done); |
| 1253 if (local->mode() == CONST_LEGACY) { | 1252 __ mov(r3, Operand(var->name())); |
| 1254 __ LoadRoot(r3, Heap::kUndefinedValueRootIndex); | 1253 __ push(r3); |
| 1255 } else { // LET || CONST | 1254 __ CallRuntime(Runtime::kThrowReferenceError); |
| 1256 __ mov(r3, Operand(var->name())); | |
| 1257 __ push(r3); | |
| 1258 __ CallRuntime(Runtime::kThrowReferenceError); | |
| 1259 } | |
| 1260 } | 1255 } |
| 1261 __ b(done); | 1256 __ b(done); |
| 1262 } | 1257 } |
| 1263 } | 1258 } |
| 1264 | 1259 |
| 1265 | 1260 |
| 1266 void FullCodeGenerator::EmitGlobalVariableLoad(VariableProxy* proxy, | 1261 void FullCodeGenerator::EmitGlobalVariableLoad(VariableProxy* proxy, |
| 1267 TypeofMode typeof_mode) { | 1262 TypeofMode typeof_mode) { |
| 1268 Variable* var = proxy->var(); | 1263 Variable* var = proxy->var(); |
| 1269 DCHECK(var->IsUnallocatedOrGlobalSlot() || | 1264 DCHECK(var->IsUnallocatedOrGlobalSlot() || |
| (...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1305 // Let and const need a read barrier. | 1300 // Let and const need a read barrier. |
| 1306 GetVar(r3, var); | 1301 GetVar(r3, var); |
| 1307 __ CompareRoot(r3, Heap::kTheHoleValueRootIndex); | 1302 __ CompareRoot(r3, Heap::kTheHoleValueRootIndex); |
| 1308 __ bne(&done); | 1303 __ bne(&done); |
| 1309 if (var->mode() == LET || var->mode() == CONST) { | 1304 if (var->mode() == LET || var->mode() == CONST) { |
| 1310 // Throw a reference error when using an uninitialized let/const | 1305 // Throw a reference error when using an uninitialized let/const |
| 1311 // binding in harmony mode. | 1306 // binding in harmony mode. |
| 1312 __ mov(r3, Operand(var->name())); | 1307 __ mov(r3, Operand(var->name())); |
| 1313 __ push(r3); | 1308 __ push(r3); |
| 1314 __ CallRuntime(Runtime::kThrowReferenceError); | 1309 __ CallRuntime(Runtime::kThrowReferenceError); |
| 1315 } else { | |
| 1316 // Uninitialized legacy const bindings are unholed. | |
| 1317 DCHECK(var->mode() == CONST_LEGACY); | |
| 1318 __ LoadRoot(r3, Heap::kUndefinedValueRootIndex); | |
| 1319 } | 1310 } |
| 1320 __ bind(&done); | 1311 __ bind(&done); |
| 1321 context()->Plug(r3); | 1312 context()->Plug(r3); |
| 1322 break; | 1313 break; |
| 1323 } | 1314 } |
| 1324 context()->Plug(var); | 1315 context()->Plug(var); |
| 1325 break; | 1316 break; |
| 1326 } | 1317 } |
| 1327 | 1318 |
| 1328 case VariableLocation::LOOKUP: { | 1319 case VariableLocation::LOOKUP: { |
| (...skipping 902 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2231 MemOperand location = VarOperand(var, r4); | 2222 MemOperand location = VarOperand(var, r4); |
| 2232 __ LoadP(r6, location); | 2223 __ LoadP(r6, location); |
| 2233 __ CompareRoot(r6, Heap::kTheHoleValueRootIndex); | 2224 __ CompareRoot(r6, Heap::kTheHoleValueRootIndex); |
| 2234 __ beq(&uninitialized_this); | 2225 __ beq(&uninitialized_this); |
| 2235 __ mov(r4, Operand(var->name())); | 2226 __ mov(r4, Operand(var->name())); |
| 2236 __ push(r4); | 2227 __ push(r4); |
| 2237 __ CallRuntime(Runtime::kThrowReferenceError); | 2228 __ CallRuntime(Runtime::kThrowReferenceError); |
| 2238 __ bind(&uninitialized_this); | 2229 __ bind(&uninitialized_this); |
| 2239 EmitStoreToStackLocalOrContextSlot(var, location); | 2230 EmitStoreToStackLocalOrContextSlot(var, location); |
| 2240 | 2231 |
| 2241 } else if (!var->is_const_mode() || | 2232 } else if (!var->is_const_mode() || op == Token::INIT) { |
| 2242 (var->mode() == CONST && op == Token::INIT)) { | |
| 2243 if (var->IsLookupSlot()) { | 2233 if (var->IsLookupSlot()) { |
| 2244 // Assignment to var. | 2234 // Assignment to var. |
| 2245 __ Push(var->name()); | 2235 __ Push(var->name()); |
| 2246 __ Push(r3); | 2236 __ Push(r3); |
| 2247 __ CallRuntime(is_strict(language_mode()) | 2237 __ CallRuntime(is_strict(language_mode()) |
| 2248 ? Runtime::kStoreLookupSlot_Strict | 2238 ? Runtime::kStoreLookupSlot_Strict |
| 2249 : Runtime::kStoreLookupSlot_Sloppy); | 2239 : Runtime::kStoreLookupSlot_Sloppy); |
| 2250 } else { | 2240 } else { |
| 2251 // Assignment to var or initializing assignment to let/const in harmony | 2241 // Assignment to var or initializing assignment to let/const in harmony |
| 2252 // mode. | 2242 // mode. |
| 2253 DCHECK((var->IsStackAllocated() || var->IsContextSlot())); | 2243 DCHECK((var->IsStackAllocated() || var->IsContextSlot())); |
| 2254 MemOperand location = VarOperand(var, r4); | 2244 MemOperand location = VarOperand(var, r4); |
| 2255 if (FLAG_debug_code && var->mode() == LET && op == Token::INIT) { | 2245 if (FLAG_debug_code && var->mode() == LET && op == Token::INIT) { |
| 2256 // Check for an uninitialized let binding. | 2246 // Check for an uninitialized let binding. |
| 2257 __ LoadP(r5, location); | 2247 __ LoadP(r5, location); |
| 2258 __ CompareRoot(r5, Heap::kTheHoleValueRootIndex); | 2248 __ CompareRoot(r5, Heap::kTheHoleValueRootIndex); |
| 2259 __ Check(eq, kLetBindingReInitialization); | 2249 __ Check(eq, kLetBindingReInitialization); |
| 2260 } | 2250 } |
| 2261 EmitStoreToStackLocalOrContextSlot(var, location); | 2251 EmitStoreToStackLocalOrContextSlot(var, location); |
| 2262 } | 2252 } |
| 2263 } else if (var->mode() == CONST_LEGACY && op == Token::INIT) { | |
| 2264 // Const initializers need a write barrier. | |
| 2265 DCHECK(!var->IsParameter()); // No const parameters. | |
| 2266 if (var->IsLookupSlot()) { | |
| 2267 __ push(r3); | |
| 2268 __ mov(r3, Operand(var->name())); | |
| 2269 __ Push(cp, r3); // Context and name. | |
| 2270 __ CallRuntime(Runtime::kInitializeLegacyConstLookupSlot); | |
| 2271 } else { | |
| 2272 DCHECK(var->IsStackAllocated() || var->IsContextSlot()); | |
| 2273 Label skip; | |
| 2274 MemOperand location = VarOperand(var, r4); | |
| 2275 __ LoadP(r5, location); | |
| 2276 __ CompareRoot(r5, Heap::kTheHoleValueRootIndex); | |
| 2277 __ bne(&skip); | |
| 2278 EmitStoreToStackLocalOrContextSlot(var, location); | |
| 2279 __ bind(&skip); | |
| 2280 } | |
| 2281 | |
| 2282 } else { | 2253 } else { |
| 2283 DCHECK(var->mode() == CONST_LEGACY && op != Token::INIT); | 2254 DCHECK(var->mode() == CONST_LEGACY && op != Token::INIT); |
| 2284 if (is_strict(language_mode())) { | 2255 if (is_strict(language_mode())) { |
| 2285 __ CallRuntime(Runtime::kThrowConstAssignError); | 2256 __ CallRuntime(Runtime::kThrowConstAssignError); |
| 2286 } | 2257 } |
| 2287 // Silently ignore store in sloppy mode. | 2258 // Silently ignore store in sloppy mode. |
| 2288 } | 2259 } |
| 2289 } | 2260 } |
| 2290 | 2261 |
| 2291 | 2262 |
| (...skipping 1676 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3968 | 3939 |
| 3969 DCHECK(Assembler::IsCrSet(Assembler::instr_at(cmp_address))); | 3940 DCHECK(Assembler::IsCrSet(Assembler::instr_at(cmp_address))); |
| 3970 | 3941 |
| 3971 DCHECK(interrupt_address == | 3942 DCHECK(interrupt_address == |
| 3972 isolate->builtins()->OnStackReplacement()->entry()); | 3943 isolate->builtins()->OnStackReplacement()->entry()); |
| 3973 return ON_STACK_REPLACEMENT; | 3944 return ON_STACK_REPLACEMENT; |
| 3974 } | 3945 } |
| 3975 } // namespace internal | 3946 } // namespace internal |
| 3976 } // namespace v8 | 3947 } // namespace v8 |
| 3977 #endif // V8_TARGET_ARCH_PPC | 3948 #endif // V8_TARGET_ARCH_PPC |
| OLD | NEW |