OLD | NEW |
1 // Copyright 2013 the V8 project authors. All rights reserved. | 1 // Copyright 2013 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_ARM64 | 5 #if V8_TARGET_ARCH_ARM64 |
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 1194 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1205 __ CallStub(&stub); | 1205 __ CallStub(&stub); |
1206 RestoreContext(); | 1206 RestoreContext(); |
1207 } | 1207 } |
1208 PrepareForBailoutForId(expr->CreateLiteralId(), BailoutState::TOS_REGISTER); | 1208 PrepareForBailoutForId(expr->CreateLiteralId(), BailoutState::TOS_REGISTER); |
1209 | 1209 |
1210 // If result_saved is true the result is on top of the stack. If | 1210 // If result_saved is true the result is on top of the stack. If |
1211 // result_saved is false the result is in x0. | 1211 // result_saved is false the result is in x0. |
1212 bool result_saved = false; | 1212 bool result_saved = false; |
1213 | 1213 |
1214 AccessorTable accessor_table(zone()); | 1214 AccessorTable accessor_table(zone()); |
1215 int property_index = 0; | 1215 for (int i = 0; i < expr->properties()->length(); i++) { |
1216 for (; property_index < expr->properties()->length(); property_index++) { | 1216 ObjectLiteral::Property* property = expr->properties()->at(i); |
1217 ObjectLiteral::Property* property = expr->properties()->at(property_index); | 1217 DCHECK(!property->is_computed_name()); |
1218 if (property->is_computed_name()) break; | |
1219 if (property->IsCompileTimeValue()) continue; | 1218 if (property->IsCompileTimeValue()) continue; |
1220 | 1219 |
1221 Literal* key = property->key()->AsLiteral(); | 1220 Literal* key = property->key()->AsLiteral(); |
1222 Expression* value = property->value(); | 1221 Expression* value = property->value(); |
1223 if (!result_saved) { | 1222 if (!result_saved) { |
1224 PushOperand(x0); // Save result on stack | 1223 PushOperand(x0); // Save result on stack |
1225 result_saved = true; | 1224 result_saved = true; |
1226 } | 1225 } |
1227 switch (property->kind()) { | 1226 switch (property->kind()) { |
1228 case ObjectLiteral::Property::CONSTANT: | 1227 case ObjectLiteral::Property::CONSTANT: |
(...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1265 DropOperands(3); | 1264 DropOperands(3); |
1266 } | 1265 } |
1267 break; | 1266 break; |
1268 case ObjectLiteral::Property::PROTOTYPE: | 1267 case ObjectLiteral::Property::PROTOTYPE: |
1269 DCHECK(property->emit_store()); | 1268 DCHECK(property->emit_store()); |
1270 // Duplicate receiver on stack. | 1269 // Duplicate receiver on stack. |
1271 __ Peek(x0, 0); | 1270 __ Peek(x0, 0); |
1272 PushOperand(x0); | 1271 PushOperand(x0); |
1273 VisitForStackValue(value); | 1272 VisitForStackValue(value); |
1274 CallRuntimeWithOperands(Runtime::kInternalSetPrototype); | 1273 CallRuntimeWithOperands(Runtime::kInternalSetPrototype); |
1275 PrepareForBailoutForId(expr->GetIdForPropertySet(property_index), | 1274 PrepareForBailoutForId(expr->GetIdForPropertySet(i), |
1276 BailoutState::NO_REGISTERS); | 1275 BailoutState::NO_REGISTERS); |
1277 break; | 1276 break; |
1278 case ObjectLiteral::Property::GETTER: | 1277 case ObjectLiteral::Property::GETTER: |
1279 if (property->emit_store()) { | 1278 if (property->emit_store()) { |
1280 AccessorTable::Iterator it = accessor_table.lookup(key); | 1279 AccessorTable::Iterator it = accessor_table.lookup(key); |
1281 it->second->bailout_id = expr->GetIdForPropertySet(property_index); | 1280 it->second->bailout_id = expr->GetIdForPropertySet(i); |
1282 it->second->getter = property; | 1281 it->second->getter = property; |
1283 } | 1282 } |
1284 break; | 1283 break; |
1285 case ObjectLiteral::Property::SETTER: | 1284 case ObjectLiteral::Property::SETTER: |
1286 if (property->emit_store()) { | 1285 if (property->emit_store()) { |
1287 AccessorTable::Iterator it = accessor_table.lookup(key); | 1286 AccessorTable::Iterator it = accessor_table.lookup(key); |
1288 it->second->bailout_id = expr->GetIdForPropertySet(property_index); | 1287 it->second->bailout_id = expr->GetIdForPropertySet(i); |
1289 it->second->setter = property; | 1288 it->second->setter = property; |
1290 } | 1289 } |
1291 break; | 1290 break; |
1292 } | 1291 } |
1293 } | 1292 } |
1294 | 1293 |
1295 // Emit code to define accessors, using only a single call to the runtime for | 1294 // Emit code to define accessors, using only a single call to the runtime for |
1296 // each pair of corresponding getters and setters. | 1295 // each pair of corresponding getters and setters. |
1297 for (AccessorTable::Iterator it = accessor_table.begin(); | 1296 for (AccessorTable::Iterator it = accessor_table.begin(); |
1298 it != accessor_table.end(); | 1297 it != accessor_table.end(); |
1299 ++it) { | 1298 ++it) { |
1300 __ Peek(x10, 0); // Duplicate receiver. | 1299 __ Peek(x10, 0); // Duplicate receiver. |
1301 PushOperand(x10); | 1300 PushOperand(x10); |
1302 VisitForStackValue(it->first); | 1301 VisitForStackValue(it->first); |
1303 EmitAccessor(it->second->getter); | 1302 EmitAccessor(it->second->getter); |
1304 EmitAccessor(it->second->setter); | 1303 EmitAccessor(it->second->setter); |
1305 __ Mov(x10, Smi::FromInt(NONE)); | 1304 __ Mov(x10, Smi::FromInt(NONE)); |
1306 PushOperand(x10); | 1305 PushOperand(x10); |
1307 CallRuntimeWithOperands(Runtime::kDefineAccessorPropertyUnchecked); | 1306 CallRuntimeWithOperands(Runtime::kDefineAccessorPropertyUnchecked); |
1308 PrepareForBailoutForId(it->second->bailout_id, BailoutState::NO_REGISTERS); | 1307 PrepareForBailoutForId(it->second->bailout_id, BailoutState::NO_REGISTERS); |
1309 } | 1308 } |
1310 | 1309 |
1311 // Object literals have two parts. The "static" part on the left contains no | |
1312 // computed property names, and so we can compute its map ahead of time; see | |
1313 // runtime.cc::CreateObjectLiteralBoilerplate. The second "dynamic" part | |
1314 // starts with the first computed property name, and continues with all | |
1315 // properties to its right. All the code from above initializes the static | |
1316 // component of the object literal, and arranges for the map of the result to | |
1317 // reflect the static order in which the keys appear. For the dynamic | |
1318 // properties, we compile them into a series of "SetOwnProperty" runtime | |
1319 // calls. This will preserve insertion order. | |
1320 for (; property_index < expr->properties()->length(); property_index++) { | |
1321 ObjectLiteral::Property* property = expr->properties()->at(property_index); | |
1322 | |
1323 Expression* value = property->value(); | |
1324 if (!result_saved) { | |
1325 PushOperand(x0); // Save result on stack | |
1326 result_saved = true; | |
1327 } | |
1328 | |
1329 __ Peek(x10, 0); // Duplicate receiver. | |
1330 PushOperand(x10); | |
1331 | |
1332 if (property->kind() == ObjectLiteral::Property::PROTOTYPE) { | |
1333 DCHECK(!property->is_computed_name()); | |
1334 VisitForStackValue(value); | |
1335 DCHECK(property->emit_store()); | |
1336 CallRuntimeWithOperands(Runtime::kInternalSetPrototype); | |
1337 PrepareForBailoutForId(expr->GetIdForPropertySet(property_index), | |
1338 BailoutState::NO_REGISTERS); | |
1339 } else { | |
1340 EmitPropertyKey(property, expr->GetIdForPropertyName(property_index)); | |
1341 VisitForStackValue(value); | |
1342 if (NeedsHomeObject(value)) { | |
1343 EmitSetHomeObject(value, 2, property->GetSlot()); | |
1344 } | |
1345 | |
1346 switch (property->kind()) { | |
1347 case ObjectLiteral::Property::CONSTANT: | |
1348 case ObjectLiteral::Property::MATERIALIZED_LITERAL: | |
1349 case ObjectLiteral::Property::COMPUTED: | |
1350 case ObjectLiteral::Property::PROTOTYPE: | |
1351 UNREACHABLE(); | |
1352 break; | |
1353 | |
1354 case ObjectLiteral::Property::GETTER: | |
1355 PushOperand(Smi::FromInt(NONE)); | |
1356 CallRuntimeWithOperands(Runtime::kDefineGetterPropertyUnchecked); | |
1357 break; | |
1358 | |
1359 case ObjectLiteral::Property::SETTER: | |
1360 PushOperand(Smi::FromInt(NONE)); | |
1361 CallRuntimeWithOperands(Runtime::kDefineSetterPropertyUnchecked); | |
1362 break; | |
1363 } | |
1364 } | |
1365 } | |
1366 | |
1367 if (result_saved) { | 1310 if (result_saved) { |
1368 context()->PlugTOS(); | 1311 context()->PlugTOS(); |
1369 } else { | 1312 } else { |
1370 context()->Plug(x0); | 1313 context()->Plug(x0); |
1371 } | 1314 } |
1372 } | 1315 } |
1373 | 1316 |
1374 | 1317 |
1375 void FullCodeGenerator::VisitArrayLiteral(ArrayLiteral* expr) { | 1318 void FullCodeGenerator::VisitArrayLiteral(ArrayLiteral* expr) { |
1376 Comment cmnt(masm_, "[ ArrayLiteral"); | 1319 Comment cmnt(masm_, "[ ArrayLiteral"); |
(...skipping 1821 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3198 } | 3141 } |
3199 | 3142 |
3200 return INTERRUPT; | 3143 return INTERRUPT; |
3201 } | 3144 } |
3202 | 3145 |
3203 | 3146 |
3204 } // namespace internal | 3147 } // namespace internal |
3205 } // namespace v8 | 3148 } // namespace v8 |
3206 | 3149 |
3207 #endif // V8_TARGET_ARCH_ARM64 | 3150 #endif // V8_TARGET_ARCH_ARM64 |
OLD | NEW |