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/full-codegen/full-codegen.h" | 7 #include "src/full-codegen/full-codegen.h" |
8 #include "src/ast/compile-time-value.h" | 8 #include "src/ast/compile-time-value.h" |
9 #include "src/ast/scopes.h" | 9 #include "src/ast/scopes.h" |
10 #include "src/code-factory.h" | 10 #include "src/code-factory.h" |
(...skipping 1141 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1152 __ CallStub(&stub); | 1152 __ CallStub(&stub); |
1153 RestoreContext(); | 1153 RestoreContext(); |
1154 } | 1154 } |
1155 PrepareForBailoutForId(expr->CreateLiteralId(), BailoutState::TOS_REGISTER); | 1155 PrepareForBailoutForId(expr->CreateLiteralId(), BailoutState::TOS_REGISTER); |
1156 | 1156 |
1157 // If result_saved is true the result is on top of the stack. If | 1157 // If result_saved is true the result is on top of the stack. If |
1158 // result_saved is false the result is in r2. | 1158 // result_saved is false the result is in r2. |
1159 bool result_saved = false; | 1159 bool result_saved = false; |
1160 | 1160 |
1161 AccessorTable accessor_table(zone()); | 1161 AccessorTable accessor_table(zone()); |
1162 int property_index = 0; | 1162 for (int i = 0; i < expr->properties()->length(); i++) { |
1163 for (; property_index < expr->properties()->length(); property_index++) { | 1163 ObjectLiteral::Property* property = expr->properties()->at(i); |
1164 ObjectLiteral::Property* property = expr->properties()->at(property_index); | 1164 DCHECK(!property->is_computed_name()); |
1165 if (property->is_computed_name()) break; | |
1166 if (property->IsCompileTimeValue()) continue; | 1165 if (property->IsCompileTimeValue()) continue; |
1167 | 1166 |
1168 Literal* key = property->key()->AsLiteral(); | 1167 Literal* key = property->key()->AsLiteral(); |
1169 Expression* value = property->value(); | 1168 Expression* value = property->value(); |
1170 if (!result_saved) { | 1169 if (!result_saved) { |
1171 PushOperand(r2); // Save result on stack | 1170 PushOperand(r2); // Save result on stack |
1172 result_saved = true; | 1171 result_saved = true; |
1173 } | 1172 } |
1174 switch (property->kind()) { | 1173 switch (property->kind()) { |
1175 case ObjectLiteral::Property::CONSTANT: | 1174 case ObjectLiteral::Property::CONSTANT: |
(...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1213 DropOperands(3); | 1212 DropOperands(3); |
1214 } | 1213 } |
1215 break; | 1214 break; |
1216 case ObjectLiteral::Property::PROTOTYPE: | 1215 case ObjectLiteral::Property::PROTOTYPE: |
1217 // Duplicate receiver on stack. | 1216 // Duplicate receiver on stack. |
1218 __ LoadP(r2, MemOperand(sp)); | 1217 __ LoadP(r2, MemOperand(sp)); |
1219 PushOperand(r2); | 1218 PushOperand(r2); |
1220 VisitForStackValue(value); | 1219 VisitForStackValue(value); |
1221 DCHECK(property->emit_store()); | 1220 DCHECK(property->emit_store()); |
1222 CallRuntimeWithOperands(Runtime::kInternalSetPrototype); | 1221 CallRuntimeWithOperands(Runtime::kInternalSetPrototype); |
1223 PrepareForBailoutForId(expr->GetIdForPropertySet(property_index), | 1222 PrepareForBailoutForId(expr->GetIdForPropertySet(i), |
1224 BailoutState::NO_REGISTERS); | 1223 BailoutState::NO_REGISTERS); |
1225 break; | 1224 break; |
1226 case ObjectLiteral::Property::GETTER: | 1225 case ObjectLiteral::Property::GETTER: |
1227 if (property->emit_store()) { | 1226 if (property->emit_store()) { |
1228 AccessorTable::Iterator it = accessor_table.lookup(key); | 1227 AccessorTable::Iterator it = accessor_table.lookup(key); |
1229 it->second->bailout_id = expr->GetIdForPropertySet(property_index); | 1228 it->second->bailout_id = expr->GetIdForPropertySet(i); |
1230 it->second->getter = property; | 1229 it->second->getter = property; |
1231 } | 1230 } |
1232 break; | 1231 break; |
1233 case ObjectLiteral::Property::SETTER: | 1232 case ObjectLiteral::Property::SETTER: |
1234 if (property->emit_store()) { | 1233 if (property->emit_store()) { |
1235 AccessorTable::Iterator it = accessor_table.lookup(key); | 1234 AccessorTable::Iterator it = accessor_table.lookup(key); |
1236 it->second->bailout_id = expr->GetIdForPropertySet(property_index); | 1235 it->second->bailout_id = expr->GetIdForPropertySet(i); |
1237 it->second->setter = property; | 1236 it->second->setter = property; |
1238 } | 1237 } |
1239 break; | 1238 break; |
1240 } | 1239 } |
1241 } | 1240 } |
1242 | 1241 |
1243 // Emit code to define accessors, using only a single call to the runtime for | 1242 // Emit code to define accessors, using only a single call to the runtime for |
1244 // each pair of corresponding getters and setters. | 1243 // each pair of corresponding getters and setters. |
1245 for (AccessorTable::Iterator it = accessor_table.begin(); | 1244 for (AccessorTable::Iterator it = accessor_table.begin(); |
1246 it != accessor_table.end(); ++it) { | 1245 it != accessor_table.end(); ++it) { |
1247 __ LoadP(r2, MemOperand(sp)); // Duplicate receiver. | 1246 __ LoadP(r2, MemOperand(sp)); // Duplicate receiver. |
1248 PushOperand(r2); | 1247 PushOperand(r2); |
1249 VisitForStackValue(it->first); | 1248 VisitForStackValue(it->first); |
1250 EmitAccessor(it->second->getter); | 1249 EmitAccessor(it->second->getter); |
1251 EmitAccessor(it->second->setter); | 1250 EmitAccessor(it->second->setter); |
1252 __ LoadSmiLiteral(r2, Smi::FromInt(NONE)); | 1251 __ LoadSmiLiteral(r2, Smi::FromInt(NONE)); |
1253 PushOperand(r2); | 1252 PushOperand(r2); |
1254 CallRuntimeWithOperands(Runtime::kDefineAccessorPropertyUnchecked); | 1253 CallRuntimeWithOperands(Runtime::kDefineAccessorPropertyUnchecked); |
1255 PrepareForBailoutForId(it->second->bailout_id, BailoutState::NO_REGISTERS); | 1254 PrepareForBailoutForId(it->second->bailout_id, BailoutState::NO_REGISTERS); |
1256 } | 1255 } |
1257 | 1256 |
1258 // Object literals have two parts. The "static" part on the left contains no | |
1259 // computed property names, and so we can compute its map ahead of time; see | |
1260 // runtime.cc::CreateObjectLiteralBoilerplate. The second "dynamic" part | |
1261 // starts with the first computed property name, and continues with all | |
1262 // properties to its right. All the code from above initializes the static | |
1263 // component of the object literal, and arranges for the map of the result to | |
1264 // reflect the static order in which the keys appear. For the dynamic | |
1265 // properties, we compile them into a series of "SetOwnProperty" runtime | |
1266 // calls. This will preserve insertion order. | |
1267 for (; property_index < expr->properties()->length(); property_index++) { | |
1268 ObjectLiteral::Property* property = expr->properties()->at(property_index); | |
1269 | |
1270 Expression* value = property->value(); | |
1271 if (!result_saved) { | |
1272 PushOperand(r2); // Save result on the stack | |
1273 result_saved = true; | |
1274 } | |
1275 | |
1276 __ LoadP(r2, MemOperand(sp)); // Duplicate receiver. | |
1277 PushOperand(r2); | |
1278 | |
1279 if (property->kind() == ObjectLiteral::Property::PROTOTYPE) { | |
1280 DCHECK(!property->is_computed_name()); | |
1281 VisitForStackValue(value); | |
1282 DCHECK(property->emit_store()); | |
1283 CallRuntimeWithOperands(Runtime::kInternalSetPrototype); | |
1284 PrepareForBailoutForId(expr->GetIdForPropertySet(property_index), | |
1285 BailoutState::NO_REGISTERS); | |
1286 } else { | |
1287 EmitPropertyKey(property, expr->GetIdForPropertyName(property_index)); | |
1288 VisitForStackValue(value); | |
1289 if (NeedsHomeObject(value)) { | |
1290 EmitSetHomeObject(value, 2, property->GetSlot()); | |
1291 } | |
1292 | |
1293 switch (property->kind()) { | |
1294 case ObjectLiteral::Property::CONSTANT: | |
1295 case ObjectLiteral::Property::MATERIALIZED_LITERAL: | |
1296 case ObjectLiteral::Property::COMPUTED: | |
1297 case ObjectLiteral::Property::PROTOTYPE: | |
1298 UNREACHABLE(); | |
1299 break; | |
1300 | |
1301 case ObjectLiteral::Property::GETTER: | |
1302 PushOperand(Smi::FromInt(NONE)); | |
1303 CallRuntimeWithOperands(Runtime::kDefineGetterPropertyUnchecked); | |
1304 break; | |
1305 | |
1306 case ObjectLiteral::Property::SETTER: | |
1307 PushOperand(Smi::FromInt(NONE)); | |
1308 CallRuntimeWithOperands(Runtime::kDefineSetterPropertyUnchecked); | |
1309 break; | |
1310 } | |
1311 } | |
1312 } | |
1313 | |
1314 if (result_saved) { | 1257 if (result_saved) { |
1315 context()->PlugTOS(); | 1258 context()->PlugTOS(); |
1316 } else { | 1259 } else { |
1317 context()->Plug(r2); | 1260 context()->Plug(r2); |
1318 } | 1261 } |
1319 } | 1262 } |
1320 | 1263 |
1321 void FullCodeGenerator::VisitArrayLiteral(ArrayLiteral* expr) { | 1264 void FullCodeGenerator::VisitArrayLiteral(ArrayLiteral* expr) { |
1322 Comment cmnt(masm_, "[ ArrayLiteral"); | 1265 Comment cmnt(masm_, "[ ArrayLiteral"); |
1323 | 1266 |
(...skipping 1739 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3063 DCHECK(kOSRBranchInstruction == br_instr); | 3006 DCHECK(kOSRBranchInstruction == br_instr); |
3064 | 3007 |
3065 DCHECK(interrupt_address == | 3008 DCHECK(interrupt_address == |
3066 isolate->builtins()->OnStackReplacement()->entry()); | 3009 isolate->builtins()->OnStackReplacement()->entry()); |
3067 return ON_STACK_REPLACEMENT; | 3010 return ON_STACK_REPLACEMENT; |
3068 } | 3011 } |
3069 | 3012 |
3070 } // namespace internal | 3013 } // namespace internal |
3071 } // namespace v8 | 3014 } // namespace v8 |
3072 #endif // V8_TARGET_ARCH_S390 | 3015 #endif // V8_TARGET_ARCH_S390 |
OLD | NEW |