OLD | NEW |
1 // Copyright 2015 the V8 project authors. All rights reserved. | 1 // Copyright 2015 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_S390 | 5 #if V8_TARGET_ARCH_S390 |
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 682 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
693 } | 693 } |
694 | 694 |
695 void FullCodeGenerator::VisitVariableDeclaration( | 695 void FullCodeGenerator::VisitVariableDeclaration( |
696 VariableDeclaration* declaration) { | 696 VariableDeclaration* declaration) { |
697 // If it was not possible to allocate the variable at compile time, we | 697 // If it was not possible to allocate the variable at compile time, we |
698 // need to "declare" it at runtime to make sure it actually exists in the | 698 // need to "declare" it at runtime to make sure it actually exists in the |
699 // local context. | 699 // local context. |
700 VariableProxy* proxy = declaration->proxy(); | 700 VariableProxy* proxy = declaration->proxy(); |
701 VariableMode mode = declaration->mode(); | 701 VariableMode mode = declaration->mode(); |
702 Variable* variable = proxy->var(); | 702 Variable* variable = proxy->var(); |
703 bool hole_init = mode == LET || mode == CONST || mode == CONST_LEGACY; | 703 bool hole_init = mode == LET || mode == CONST; |
704 switch (variable->location()) { | 704 switch (variable->location()) { |
705 case VariableLocation::GLOBAL: | 705 case VariableLocation::GLOBAL: |
706 case VariableLocation::UNALLOCATED: | 706 case VariableLocation::UNALLOCATED: |
707 globals_->Add(variable->name(), zone()); | 707 globals_->Add(variable->name(), zone()); |
708 globals_->Add(variable->binding_needs_init() | 708 globals_->Add(variable->binding_needs_init() |
709 ? isolate()->factory()->the_hole_value() | 709 ? isolate()->factory()->the_hole_value() |
710 : isolate()->factory()->undefined_value(), | 710 : isolate()->factory()->undefined_value(), |
711 zone()); | 711 zone()); |
712 break; | 712 break; |
713 | 713 |
(...skipping 489 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1203 // introducing variables. In those cases, we do not want to | 1203 // introducing variables. In those cases, we do not want to |
1204 // perform a runtime call for all variables in the scope | 1204 // perform a runtime call for all variables in the scope |
1205 // containing the eval. | 1205 // containing the eval. |
1206 Variable* var = proxy->var(); | 1206 Variable* var = proxy->var(); |
1207 if (var->mode() == DYNAMIC_GLOBAL) { | 1207 if (var->mode() == DYNAMIC_GLOBAL) { |
1208 EmitLoadGlobalCheckExtensions(proxy, typeof_mode, slow); | 1208 EmitLoadGlobalCheckExtensions(proxy, typeof_mode, slow); |
1209 __ b(done); | 1209 __ b(done); |
1210 } else if (var->mode() == DYNAMIC_LOCAL) { | 1210 } else if (var->mode() == DYNAMIC_LOCAL) { |
1211 Variable* local = var->local_if_not_shadowed(); | 1211 Variable* local = var->local_if_not_shadowed(); |
1212 __ LoadP(r2, ContextSlotOperandCheckExtensions(local, slow)); | 1212 __ LoadP(r2, ContextSlotOperandCheckExtensions(local, slow)); |
1213 if (local->mode() == LET || local->mode() == CONST || | 1213 if (local->mode() == LET || local->mode() == CONST) { |
1214 local->mode() == CONST_LEGACY) { | |
1215 __ CompareRoot(r2, Heap::kTheHoleValueRootIndex); | 1214 __ CompareRoot(r2, Heap::kTheHoleValueRootIndex); |
1216 __ bne(done); | 1215 __ bne(done); |
1217 if (local->mode() == CONST_LEGACY) { | 1216 __ mov(r2, Operand(var->name())); |
1218 __ LoadRoot(r2, Heap::kUndefinedValueRootIndex); | 1217 __ push(r2); |
1219 } else { // LET || CONST | 1218 __ CallRuntime(Runtime::kThrowReferenceError); |
1220 __ mov(r2, Operand(var->name())); | |
1221 __ push(r2); | |
1222 __ CallRuntime(Runtime::kThrowReferenceError); | |
1223 } | |
1224 } | 1219 } |
1225 __ b(done); | 1220 __ b(done); |
1226 } | 1221 } |
1227 } | 1222 } |
1228 | 1223 |
1229 void FullCodeGenerator::EmitGlobalVariableLoad(VariableProxy* proxy, | 1224 void FullCodeGenerator::EmitGlobalVariableLoad(VariableProxy* proxy, |
1230 TypeofMode typeof_mode) { | 1225 TypeofMode typeof_mode) { |
1231 Variable* var = proxy->var(); | 1226 Variable* var = proxy->var(); |
1232 DCHECK(var->IsUnallocatedOrGlobalSlot() || | 1227 DCHECK(var->IsUnallocatedOrGlobalSlot() || |
1233 (var->IsLookupSlot() && var->mode() == DYNAMIC_GLOBAL)); | 1228 (var->IsLookupSlot() && var->mode() == DYNAMIC_GLOBAL)); |
(...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1267 // Let and const need a read barrier. | 1262 // Let and const need a read barrier. |
1268 GetVar(r2, var); | 1263 GetVar(r2, var); |
1269 __ CompareRoot(r2, Heap::kTheHoleValueRootIndex); | 1264 __ CompareRoot(r2, Heap::kTheHoleValueRootIndex); |
1270 __ bne(&done); | 1265 __ bne(&done); |
1271 if (var->mode() == LET || var->mode() == CONST) { | 1266 if (var->mode() == LET || var->mode() == CONST) { |
1272 // Throw a reference error when using an uninitialized let/const | 1267 // Throw a reference error when using an uninitialized let/const |
1273 // binding in harmony mode. | 1268 // binding in harmony mode. |
1274 __ mov(r2, Operand(var->name())); | 1269 __ mov(r2, Operand(var->name())); |
1275 __ push(r2); | 1270 __ push(r2); |
1276 __ CallRuntime(Runtime::kThrowReferenceError); | 1271 __ CallRuntime(Runtime::kThrowReferenceError); |
1277 } else { | |
1278 // Uninitialized legacy const bindings are unholed. | |
1279 DCHECK(var->mode() == CONST_LEGACY); | |
1280 __ LoadRoot(r2, Heap::kUndefinedValueRootIndex); | |
1281 } | 1272 } |
1282 __ bind(&done); | 1273 __ bind(&done); |
1283 context()->Plug(r2); | 1274 context()->Plug(r2); |
1284 break; | 1275 break; |
1285 } | 1276 } |
1286 context()->Plug(var); | 1277 context()->Plug(var); |
1287 break; | 1278 break; |
1288 } | 1279 } |
1289 | 1280 |
1290 case VariableLocation::LOOKUP: { | 1281 case VariableLocation::LOOKUP: { |
(...skipping 893 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2184 MemOperand location = VarOperand(var, r3); | 2175 MemOperand location = VarOperand(var, r3); |
2185 __ LoadP(r5, location); | 2176 __ LoadP(r5, location); |
2186 __ CompareRoot(r5, Heap::kTheHoleValueRootIndex); | 2177 __ CompareRoot(r5, Heap::kTheHoleValueRootIndex); |
2187 __ beq(&uninitialized_this); | 2178 __ beq(&uninitialized_this); |
2188 __ mov(r3, Operand(var->name())); | 2179 __ mov(r3, Operand(var->name())); |
2189 __ push(r3); | 2180 __ push(r3); |
2190 __ CallRuntime(Runtime::kThrowReferenceError); | 2181 __ CallRuntime(Runtime::kThrowReferenceError); |
2191 __ bind(&uninitialized_this); | 2182 __ bind(&uninitialized_this); |
2192 EmitStoreToStackLocalOrContextSlot(var, location); | 2183 EmitStoreToStackLocalOrContextSlot(var, location); |
2193 | 2184 |
2194 } else if (!var->is_const_mode() || | 2185 } else if (!var->is_const_mode() || op == Token::INIT) { |
2195 (var->mode() == CONST && op == Token::INIT)) { | |
2196 if (var->IsLookupSlot()) { | 2186 if (var->IsLookupSlot()) { |
2197 // Assignment to var. | 2187 // Assignment to var. |
2198 __ Push(var->name()); | 2188 __ Push(var->name()); |
2199 __ Push(r2); | 2189 __ Push(r2); |
2200 __ CallRuntime(is_strict(language_mode()) | 2190 __ CallRuntime(is_strict(language_mode()) |
2201 ? Runtime::kStoreLookupSlot_Strict | 2191 ? Runtime::kStoreLookupSlot_Strict |
2202 : Runtime::kStoreLookupSlot_Sloppy); | 2192 : Runtime::kStoreLookupSlot_Sloppy); |
2203 } else { | 2193 } else { |
2204 // Assignment to var or initializing assignment to let/const in harmony | 2194 // Assignment to var or initializing assignment to let/const in harmony |
2205 // mode. | 2195 // mode. |
2206 DCHECK((var->IsStackAllocated() || var->IsContextSlot())); | 2196 DCHECK((var->IsStackAllocated() || var->IsContextSlot())); |
2207 MemOperand location = VarOperand(var, r3); | 2197 MemOperand location = VarOperand(var, r3); |
2208 if (FLAG_debug_code && var->mode() == LET && op == Token::INIT) { | 2198 if (FLAG_debug_code && var->mode() == LET && op == Token::INIT) { |
2209 // Check for an uninitialized let binding. | 2199 // Check for an uninitialized let binding. |
2210 __ LoadP(r4, location); | 2200 __ LoadP(r4, location); |
2211 __ CompareRoot(r4, Heap::kTheHoleValueRootIndex); | 2201 __ CompareRoot(r4, Heap::kTheHoleValueRootIndex); |
2212 __ Check(eq, kLetBindingReInitialization); | 2202 __ Check(eq, kLetBindingReInitialization); |
2213 } | 2203 } |
2214 EmitStoreToStackLocalOrContextSlot(var, location); | 2204 EmitStoreToStackLocalOrContextSlot(var, location); |
2215 } | 2205 } |
2216 } else if (var->mode() == CONST_LEGACY && op == Token::INIT) { | |
2217 // Const initializers need a write barrier. | |
2218 DCHECK(!var->IsParameter()); // No const parameters. | |
2219 if (var->IsLookupSlot()) { | |
2220 __ push(r2); | |
2221 __ mov(r2, Operand(var->name())); | |
2222 __ Push(cp, r2); // Context and name. | |
2223 __ CallRuntime(Runtime::kInitializeLegacyConstLookupSlot); | |
2224 } else { | |
2225 DCHECK(var->IsStackAllocated() || var->IsContextSlot()); | |
2226 Label skip; | |
2227 MemOperand location = VarOperand(var, r3); | |
2228 __ LoadP(r4, location); | |
2229 __ CompareRoot(r4, Heap::kTheHoleValueRootIndex); | |
2230 __ bne(&skip); | |
2231 EmitStoreToStackLocalOrContextSlot(var, location); | |
2232 __ bind(&skip); | |
2233 } | |
2234 | |
2235 } else { | 2206 } else { |
2236 DCHECK(var->mode() == CONST_LEGACY && op != Token::INIT); | 2207 DCHECK(var->mode() == CONST_LEGACY && op != Token::INIT); |
2237 if (is_strict(language_mode())) { | 2208 if (is_strict(language_mode())) { |
2238 __ CallRuntime(Runtime::kThrowConstAssignError); | 2209 __ CallRuntime(Runtime::kThrowConstAssignError); |
2239 } | 2210 } |
2240 // Silently ignore store in sloppy mode. | 2211 // Silently ignore store in sloppy mode. |
2241 } | 2212 } |
2242 } | 2213 } |
2243 | 2214 |
2244 void FullCodeGenerator::EmitNamedPropertyAssignment(Assignment* expr) { | 2215 void FullCodeGenerator::EmitNamedPropertyAssignment(Assignment* expr) { |
(...skipping 1629 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3874 DCHECK(kOSRBranchInstruction == br_instr); | 3845 DCHECK(kOSRBranchInstruction == br_instr); |
3875 | 3846 |
3876 DCHECK(interrupt_address == | 3847 DCHECK(interrupt_address == |
3877 isolate->builtins()->OnStackReplacement()->entry()); | 3848 isolate->builtins()->OnStackReplacement()->entry()); |
3878 return ON_STACK_REPLACEMENT; | 3849 return ON_STACK_REPLACEMENT; |
3879 } | 3850 } |
3880 | 3851 |
3881 } // namespace internal | 3852 } // namespace internal |
3882 } // namespace v8 | 3853 } // namespace v8 |
3883 #endif // V8_TARGET_ARCH_S390 | 3854 #endif // V8_TARGET_ARCH_S390 |
OLD | NEW |