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 |