| 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 |