OLD | NEW |
1 // Copyright 2016 the V8 project authors. All rights reserved. | 1 // Copyright 2016 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 #include "src/builtins/builtins.h" | 5 #include "src/builtins/builtins.h" |
6 #include "src/builtins/builtins-utils.h" | 6 #include "src/builtins/builtins-utils.h" |
7 | 7 |
8 #include "src/code-factory.h" | 8 #include "src/code-factory.h" |
9 #include "src/contexts.h" | 9 #include "src/contexts.h" |
10 #include "src/elements.h" | 10 #include "src/elements.h" |
(...skipping 1209 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1220 isolate, species, Object::ArraySpeciesConstructor(isolate, receiver)); | 1220 isolate, species, Object::ArraySpeciesConstructor(isolate, receiver)); |
1221 if (*species == *isolate->array_function()) { | 1221 if (*species == *isolate->array_function()) { |
1222 if (Fast_ArrayConcat(isolate, &args).ToHandle(&result_array)) { | 1222 if (Fast_ArrayConcat(isolate, &args).ToHandle(&result_array)) { |
1223 return *result_array; | 1223 return *result_array; |
1224 } | 1224 } |
1225 if (isolate->has_pending_exception()) return isolate->heap()->exception(); | 1225 if (isolate->has_pending_exception()) return isolate->heap()->exception(); |
1226 } | 1226 } |
1227 return Slow_ArrayConcat(&args, species, isolate); | 1227 return Slow_ArrayConcat(&args, species, isolate); |
1228 } | 1228 } |
1229 | 1229 |
1230 void Builtins::Generate_ArrayIsArray(compiler::CodeAssemblerState* state) { | 1230 void Builtins::Generate_ArrayIsArray(CodeStubAssembler* assembler) { |
1231 typedef compiler::Node Node; | 1231 typedef compiler::Node Node; |
1232 typedef CodeStubAssembler::Label Label; | 1232 typedef CodeStubAssembler::Label Label; |
1233 CodeStubAssembler assembler(state); | |
1234 | 1233 |
1235 Node* object = assembler.Parameter(1); | 1234 Node* object = assembler->Parameter(1); |
1236 Node* context = assembler.Parameter(4); | 1235 Node* context = assembler->Parameter(4); |
1237 | 1236 |
1238 Label call_runtime(&assembler), return_true(&assembler), | 1237 Label call_runtime(assembler), return_true(assembler), |
1239 return_false(&assembler); | 1238 return_false(assembler); |
1240 | 1239 |
1241 assembler.GotoIf(assembler.TaggedIsSmi(object), &return_false); | 1240 assembler->GotoIf(assembler->TaggedIsSmi(object), &return_false); |
1242 Node* instance_type = assembler.LoadInstanceType(object); | 1241 Node* instance_type = assembler->LoadInstanceType(object); |
1243 | 1242 |
1244 assembler.GotoIf(assembler.Word32Equal( | 1243 assembler->GotoIf(assembler->Word32Equal( |
1245 instance_type, assembler.Int32Constant(JS_ARRAY_TYPE)), | 1244 instance_type, assembler->Int32Constant(JS_ARRAY_TYPE)), |
1246 &return_true); | 1245 &return_true); |
1247 | 1246 |
1248 // TODO(verwaest): Handle proxies in-place. | 1247 // TODO(verwaest): Handle proxies in-place. |
1249 assembler.Branch(assembler.Word32Equal( | 1248 assembler->Branch(assembler->Word32Equal( |
1250 instance_type, assembler.Int32Constant(JS_PROXY_TYPE)), | 1249 instance_type, assembler->Int32Constant(JS_PROXY_TYPE)), |
1251 &call_runtime, &return_false); | 1250 &call_runtime, &return_false); |
1252 | 1251 |
1253 assembler.Bind(&return_true); | 1252 assembler->Bind(&return_true); |
1254 assembler.Return(assembler.BooleanConstant(true)); | 1253 assembler->Return(assembler->BooleanConstant(true)); |
1255 | 1254 |
1256 assembler.Bind(&return_false); | 1255 assembler->Bind(&return_false); |
1257 assembler.Return(assembler.BooleanConstant(false)); | 1256 assembler->Return(assembler->BooleanConstant(false)); |
1258 | 1257 |
1259 assembler.Bind(&call_runtime); | 1258 assembler->Bind(&call_runtime); |
1260 assembler.Return( | 1259 assembler->Return( |
1261 assembler.CallRuntime(Runtime::kArrayIsArray, context, object)); | 1260 assembler->CallRuntime(Runtime::kArrayIsArray, context, object)); |
1262 } | 1261 } |
1263 | 1262 |
1264 void Builtins::Generate_ArrayIncludes(compiler::CodeAssemblerState* state) { | 1263 void Builtins::Generate_ArrayIncludes(CodeStubAssembler* assembler) { |
1265 typedef compiler::Node Node; | 1264 typedef compiler::Node Node; |
1266 typedef CodeStubAssembler::Label Label; | 1265 typedef CodeStubAssembler::Label Label; |
1267 typedef CodeStubAssembler::Variable Variable; | 1266 typedef CodeStubAssembler::Variable Variable; |
1268 CodeStubAssembler assembler(state); | |
1269 | 1267 |
1270 Node* array = assembler.Parameter(0); | 1268 Node* array = assembler->Parameter(0); |
1271 Node* search_element = assembler.Parameter(1); | 1269 Node* search_element = assembler->Parameter(1); |
1272 Node* start_from = assembler.Parameter(2); | 1270 Node* start_from = assembler->Parameter(2); |
1273 Node* context = assembler.Parameter(3 + 2); | 1271 Node* context = assembler->Parameter(3 + 2); |
1274 | 1272 |
1275 Node* intptr_zero = assembler.IntPtrConstant(0); | 1273 Node* intptr_zero = assembler->IntPtrConstant(0); |
1276 Node* intptr_one = assembler.IntPtrConstant(1); | 1274 Node* intptr_one = assembler->IntPtrConstant(1); |
1277 | 1275 |
1278 Node* the_hole = assembler.TheHoleConstant(); | 1276 Node* the_hole = assembler->TheHoleConstant(); |
1279 Node* undefined = assembler.UndefinedConstant(); | 1277 Node* undefined = assembler->UndefinedConstant(); |
1280 Node* heap_number_map = assembler.HeapNumberMapConstant(); | 1278 Node* heap_number_map = assembler->HeapNumberMapConstant(); |
1281 | 1279 |
1282 Variable len_var(&assembler, MachineType::PointerRepresentation()), | 1280 Variable len_var(assembler, MachineType::PointerRepresentation()), |
1283 index_var(&assembler, MachineType::PointerRepresentation()), | 1281 index_var(assembler, MachineType::PointerRepresentation()), |
1284 start_from_var(&assembler, MachineType::PointerRepresentation()); | 1282 start_from_var(assembler, MachineType::PointerRepresentation()); |
1285 | 1283 |
1286 Label init_k(&assembler), return_true(&assembler), return_false(&assembler), | 1284 Label init_k(assembler), return_true(assembler), return_false(assembler), |
1287 call_runtime(&assembler); | 1285 call_runtime(assembler); |
1288 | 1286 |
1289 Label init_len(&assembler); | 1287 Label init_len(assembler); |
1290 | 1288 |
1291 index_var.Bind(intptr_zero); | 1289 index_var.Bind(intptr_zero); |
1292 len_var.Bind(intptr_zero); | 1290 len_var.Bind(intptr_zero); |
1293 | 1291 |
1294 // Take slow path if not a JSArray, if retrieving elements requires | 1292 // Take slow path if not a JSArray, if retrieving elements requires |
1295 // traversing prototype, or if access checks are required. | 1293 // traversing prototype, or if access checks are required. |
1296 assembler.BranchIfFastJSArray(array, context, &init_len, &call_runtime); | 1294 assembler->BranchIfFastJSArray(array, context, &init_len, &call_runtime); |
1297 | 1295 |
1298 assembler.Bind(&init_len); | 1296 assembler->Bind(&init_len); |
1299 { | 1297 { |
1300 // Handle case where JSArray length is not an Smi in the runtime | 1298 // Handle case where JSArray length is not an Smi in the runtime |
1301 Node* len = assembler.LoadObjectField(array, JSArray::kLengthOffset); | 1299 Node* len = assembler->LoadObjectField(array, JSArray::kLengthOffset); |
1302 assembler.GotoUnless(assembler.TaggedIsSmi(len), &call_runtime); | 1300 assembler->GotoUnless(assembler->TaggedIsSmi(len), &call_runtime); |
1303 | 1301 |
1304 len_var.Bind(assembler.SmiToWord(len)); | 1302 len_var.Bind(assembler->SmiToWord(len)); |
1305 assembler.Branch(assembler.WordEqual(len_var.value(), intptr_zero), | 1303 assembler->Branch(assembler->WordEqual(len_var.value(), intptr_zero), |
1306 &return_false, &init_k); | 1304 &return_false, &init_k); |
1307 } | 1305 } |
1308 | 1306 |
1309 assembler.Bind(&init_k); | 1307 assembler->Bind(&init_k); |
1310 { | 1308 { |
1311 Label done(&assembler), init_k_smi(&assembler), init_k_heap_num(&assembler), | 1309 Label done(assembler), init_k_smi(assembler), init_k_heap_num(assembler), |
1312 init_k_zero(&assembler), init_k_n(&assembler); | 1310 init_k_zero(assembler), init_k_n(assembler); |
1313 Node* tagged_n = assembler.ToInteger(context, start_from); | 1311 Node* tagged_n = assembler->ToInteger(context, start_from); |
1314 | 1312 |
1315 assembler.Branch(assembler.TaggedIsSmi(tagged_n), &init_k_smi, | 1313 assembler->Branch(assembler->TaggedIsSmi(tagged_n), &init_k_smi, |
1316 &init_k_heap_num); | 1314 &init_k_heap_num); |
1317 | 1315 |
1318 assembler.Bind(&init_k_smi); | 1316 assembler->Bind(&init_k_smi); |
1319 { | 1317 { |
1320 start_from_var.Bind(assembler.SmiUntag(tagged_n)); | 1318 start_from_var.Bind(assembler->SmiUntag(tagged_n)); |
1321 assembler.Goto(&init_k_n); | 1319 assembler->Goto(&init_k_n); |
1322 } | 1320 } |
1323 | 1321 |
1324 assembler.Bind(&init_k_heap_num); | 1322 assembler->Bind(&init_k_heap_num); |
1325 { | 1323 { |
1326 Label do_return_false(&assembler); | 1324 Label do_return_false(assembler); |
1327 // This round is lossless for all valid lengths. | 1325 // This round is lossless for all valid lengths. |
1328 Node* fp_len = assembler.RoundIntPtrToFloat64(len_var.value()); | 1326 Node* fp_len = assembler->RoundIntPtrToFloat64(len_var.value()); |
1329 Node* fp_n = assembler.LoadHeapNumberValue(tagged_n); | 1327 Node* fp_n = assembler->LoadHeapNumberValue(tagged_n); |
1330 assembler.GotoIf(assembler.Float64GreaterThanOrEqual(fp_n, fp_len), | 1328 assembler->GotoIf(assembler->Float64GreaterThanOrEqual(fp_n, fp_len), |
1331 &do_return_false); | 1329 &do_return_false); |
1332 start_from_var.Bind(assembler.ChangeInt32ToIntPtr( | 1330 start_from_var.Bind(assembler->ChangeInt32ToIntPtr( |
1333 assembler.TruncateFloat64ToWord32(fp_n))); | 1331 assembler->TruncateFloat64ToWord32(fp_n))); |
1334 assembler.Goto(&init_k_n); | 1332 assembler->Goto(&init_k_n); |
1335 | 1333 |
1336 assembler.Bind(&do_return_false); | 1334 assembler->Bind(&do_return_false); |
1337 { | 1335 { |
1338 index_var.Bind(intptr_zero); | 1336 index_var.Bind(intptr_zero); |
1339 assembler.Goto(&return_false); | 1337 assembler->Goto(&return_false); |
1340 } | 1338 } |
1341 } | 1339 } |
1342 | 1340 |
1343 assembler.Bind(&init_k_n); | 1341 assembler->Bind(&init_k_n); |
1344 { | 1342 { |
1345 Label if_positive(&assembler), if_negative(&assembler), done(&assembler); | 1343 Label if_positive(assembler), if_negative(assembler), done(assembler); |
1346 assembler.Branch( | 1344 assembler->Branch( |
1347 assembler.IntPtrLessThan(start_from_var.value(), intptr_zero), | 1345 assembler->IntPtrLessThan(start_from_var.value(), intptr_zero), |
1348 &if_negative, &if_positive); | 1346 &if_negative, &if_positive); |
1349 | 1347 |
1350 assembler.Bind(&if_positive); | 1348 assembler->Bind(&if_positive); |
1351 { | 1349 { |
1352 index_var.Bind(start_from_var.value()); | 1350 index_var.Bind(start_from_var.value()); |
1353 assembler.Goto(&done); | 1351 assembler->Goto(&done); |
1354 } | 1352 } |
1355 | 1353 |
1356 assembler.Bind(&if_negative); | 1354 assembler->Bind(&if_negative); |
1357 { | 1355 { |
1358 index_var.Bind( | 1356 index_var.Bind( |
1359 assembler.IntPtrAdd(len_var.value(), start_from_var.value())); | 1357 assembler->IntPtrAdd(len_var.value(), start_from_var.value())); |
1360 assembler.Branch( | 1358 assembler->Branch( |
1361 assembler.IntPtrLessThan(index_var.value(), intptr_zero), | 1359 assembler->IntPtrLessThan(index_var.value(), intptr_zero), |
1362 &init_k_zero, &done); | 1360 &init_k_zero, &done); |
1363 } | 1361 } |
1364 | 1362 |
1365 assembler.Bind(&init_k_zero); | 1363 assembler->Bind(&init_k_zero); |
1366 { | 1364 { |
1367 index_var.Bind(intptr_zero); | 1365 index_var.Bind(intptr_zero); |
1368 assembler.Goto(&done); | 1366 assembler->Goto(&done); |
1369 } | 1367 } |
1370 | 1368 |
1371 assembler.Bind(&done); | 1369 assembler->Bind(&done); |
1372 } | 1370 } |
1373 } | 1371 } |
1374 | 1372 |
1375 static int32_t kElementsKind[] = { | 1373 static int32_t kElementsKind[] = { |
1376 FAST_SMI_ELEMENTS, FAST_HOLEY_SMI_ELEMENTS, FAST_ELEMENTS, | 1374 FAST_SMI_ELEMENTS, FAST_HOLEY_SMI_ELEMENTS, FAST_ELEMENTS, |
1377 FAST_HOLEY_ELEMENTS, FAST_DOUBLE_ELEMENTS, FAST_HOLEY_DOUBLE_ELEMENTS, | 1375 FAST_HOLEY_ELEMENTS, FAST_DOUBLE_ELEMENTS, FAST_HOLEY_DOUBLE_ELEMENTS, |
1378 }; | 1376 }; |
1379 | 1377 |
1380 Label if_smiorobjects(&assembler), if_packed_doubles(&assembler), | 1378 Label if_smiorobjects(assembler), if_packed_doubles(assembler), |
1381 if_holey_doubles(&assembler); | 1379 if_holey_doubles(assembler); |
1382 Label* element_kind_handlers[] = {&if_smiorobjects, &if_smiorobjects, | 1380 Label* element_kind_handlers[] = {&if_smiorobjects, &if_smiorobjects, |
1383 &if_smiorobjects, &if_smiorobjects, | 1381 &if_smiorobjects, &if_smiorobjects, |
1384 &if_packed_doubles, &if_holey_doubles}; | 1382 &if_packed_doubles, &if_holey_doubles}; |
1385 | 1383 |
1386 Node* map = assembler.LoadMap(array); | 1384 Node* map = assembler->LoadMap(array); |
1387 Node* elements_kind = assembler.LoadMapElementsKind(map); | 1385 Node* elements_kind = assembler->LoadMapElementsKind(map); |
1388 Node* elements = assembler.LoadElements(array); | 1386 Node* elements = assembler->LoadElements(array); |
1389 assembler.Switch(elements_kind, &return_false, kElementsKind, | 1387 assembler->Switch(elements_kind, &return_false, kElementsKind, |
1390 element_kind_handlers, arraysize(kElementsKind)); | 1388 element_kind_handlers, arraysize(kElementsKind)); |
1391 | 1389 |
1392 assembler.Bind(&if_smiorobjects); | 1390 assembler->Bind(&if_smiorobjects); |
1393 { | 1391 { |
1394 Variable search_num(&assembler, MachineRepresentation::kFloat64); | 1392 Variable search_num(assembler, MachineRepresentation::kFloat64); |
1395 Label ident_loop(&assembler, &index_var), | 1393 Label ident_loop(assembler, &index_var), |
1396 heap_num_loop(&assembler, &search_num), | 1394 heap_num_loop(assembler, &search_num), |
1397 string_loop(&assembler, &index_var), simd_loop(&assembler), | 1395 string_loop(assembler, &index_var), simd_loop(assembler), |
1398 undef_loop(&assembler, &index_var), not_smi(&assembler), | 1396 undef_loop(assembler, &index_var), not_smi(assembler), |
1399 not_heap_num(&assembler); | 1397 not_heap_num(assembler); |
1400 | 1398 |
1401 assembler.GotoUnless(assembler.TaggedIsSmi(search_element), ¬_smi); | 1399 assembler->GotoUnless(assembler->TaggedIsSmi(search_element), ¬_smi); |
1402 search_num.Bind(assembler.SmiToFloat64(search_element)); | 1400 search_num.Bind(assembler->SmiToFloat64(search_element)); |
1403 assembler.Goto(&heap_num_loop); | 1401 assembler->Goto(&heap_num_loop); |
1404 | 1402 |
1405 assembler.Bind(¬_smi); | 1403 assembler->Bind(¬_smi); |
1406 assembler.GotoIf(assembler.WordEqual(search_element, undefined), | 1404 assembler->GotoIf(assembler->WordEqual(search_element, undefined), |
1407 &undef_loop); | 1405 &undef_loop); |
1408 Node* map = assembler.LoadMap(search_element); | 1406 Node* map = assembler->LoadMap(search_element); |
1409 assembler.GotoIf(assembler.WordNotEqual(map, heap_number_map), | 1407 assembler->GotoIf(assembler->WordNotEqual(map, heap_number_map), |
1410 ¬_heap_num); | 1408 ¬_heap_num); |
1411 search_num.Bind(assembler.LoadHeapNumberValue(search_element)); | 1409 search_num.Bind(assembler->LoadHeapNumberValue(search_element)); |
1412 assembler.Goto(&heap_num_loop); | 1410 assembler->Goto(&heap_num_loop); |
1413 | 1411 |
1414 assembler.Bind(¬_heap_num); | 1412 assembler->Bind(¬_heap_num); |
1415 Node* search_type = assembler.LoadMapInstanceType(map); | 1413 Node* search_type = assembler->LoadMapInstanceType(map); |
1416 assembler.GotoIf(assembler.IsStringInstanceType(search_type), &string_loop); | 1414 assembler->GotoIf(assembler->IsStringInstanceType(search_type), |
1417 assembler.GotoIf( | 1415 &string_loop); |
1418 assembler.Word32Equal(search_type, | 1416 assembler->GotoIf( |
1419 assembler.Int32Constant(SIMD128_VALUE_TYPE)), | 1417 assembler->Word32Equal(search_type, |
| 1418 assembler->Int32Constant(SIMD128_VALUE_TYPE)), |
1420 &simd_loop); | 1419 &simd_loop); |
1421 assembler.Goto(&ident_loop); | 1420 assembler->Goto(&ident_loop); |
1422 | 1421 |
1423 assembler.Bind(&ident_loop); | 1422 assembler->Bind(&ident_loop); |
1424 { | 1423 { |
1425 assembler.GotoUnless( | 1424 assembler->GotoUnless( |
1426 assembler.UintPtrLessThan(index_var.value(), len_var.value()), | 1425 assembler->UintPtrLessThan(index_var.value(), len_var.value()), |
1427 &return_false); | 1426 &return_false); |
1428 Node* element_k = assembler.LoadFixedArrayElement( | 1427 Node* element_k = assembler->LoadFixedArrayElement( |
1429 elements, index_var.value(), 0, CodeStubAssembler::INTPTR_PARAMETERS); | 1428 elements, index_var.value(), 0, CodeStubAssembler::INTPTR_PARAMETERS); |
1430 assembler.GotoIf(assembler.WordEqual(element_k, search_element), | 1429 assembler->GotoIf(assembler->WordEqual(element_k, search_element), |
1431 &return_true); | 1430 &return_true); |
1432 | 1431 |
1433 index_var.Bind(assembler.IntPtrAdd(index_var.value(), intptr_one)); | 1432 index_var.Bind(assembler->IntPtrAdd(index_var.value(), intptr_one)); |
1434 assembler.Goto(&ident_loop); | 1433 assembler->Goto(&ident_loop); |
1435 } | 1434 } |
1436 | 1435 |
1437 assembler.Bind(&undef_loop); | 1436 assembler->Bind(&undef_loop); |
1438 { | 1437 { |
1439 assembler.GotoUnless( | 1438 assembler->GotoUnless( |
1440 assembler.UintPtrLessThan(index_var.value(), len_var.value()), | 1439 assembler->UintPtrLessThan(index_var.value(), len_var.value()), |
1441 &return_false); | 1440 &return_false); |
1442 Node* element_k = assembler.LoadFixedArrayElement( | 1441 Node* element_k = assembler->LoadFixedArrayElement( |
1443 elements, index_var.value(), 0, CodeStubAssembler::INTPTR_PARAMETERS); | 1442 elements, index_var.value(), 0, CodeStubAssembler::INTPTR_PARAMETERS); |
1444 assembler.GotoIf(assembler.WordEqual(element_k, undefined), &return_true); | 1443 assembler->GotoIf(assembler->WordEqual(element_k, undefined), |
1445 assembler.GotoIf(assembler.WordEqual(element_k, the_hole), &return_true); | 1444 &return_true); |
1446 | 1445 assembler->GotoIf(assembler->WordEqual(element_k, the_hole), |
1447 index_var.Bind(assembler.IntPtrAdd(index_var.value(), intptr_one)); | 1446 &return_true); |
1448 assembler.Goto(&undef_loop); | 1447 |
1449 } | 1448 index_var.Bind(assembler->IntPtrAdd(index_var.value(), intptr_one)); |
1450 | 1449 assembler->Goto(&undef_loop); |
1451 assembler.Bind(&heap_num_loop); | 1450 } |
1452 { | 1451 |
1453 Label nan_loop(&assembler, &index_var), | 1452 assembler->Bind(&heap_num_loop); |
1454 not_nan_loop(&assembler, &index_var); | 1453 { |
1455 assembler.BranchIfFloat64IsNaN(search_num.value(), &nan_loop, | 1454 Label nan_loop(assembler, &index_var), |
1456 ¬_nan_loop); | 1455 not_nan_loop(assembler, &index_var); |
1457 | 1456 assembler->BranchIfFloat64IsNaN(search_num.value(), &nan_loop, |
1458 assembler.Bind(¬_nan_loop); | 1457 ¬_nan_loop); |
1459 { | 1458 |
1460 Label continue_loop(&assembler), not_smi(&assembler); | 1459 assembler->Bind(¬_nan_loop); |
1461 assembler.GotoUnless( | 1460 { |
1462 assembler.UintPtrLessThan(index_var.value(), len_var.value()), | 1461 Label continue_loop(assembler), not_smi(assembler); |
| 1462 assembler->GotoUnless( |
| 1463 assembler->UintPtrLessThan(index_var.value(), len_var.value()), |
1463 &return_false); | 1464 &return_false); |
1464 Node* element_k = assembler.LoadFixedArrayElement( | 1465 Node* element_k = assembler->LoadFixedArrayElement( |
1465 elements, index_var.value(), 0, | 1466 elements, index_var.value(), 0, |
1466 CodeStubAssembler::INTPTR_PARAMETERS); | 1467 CodeStubAssembler::INTPTR_PARAMETERS); |
1467 assembler.GotoUnless(assembler.TaggedIsSmi(element_k), ¬_smi); | 1468 assembler->GotoUnless(assembler->TaggedIsSmi(element_k), ¬_smi); |
1468 assembler.Branch( | 1469 assembler->Branch( |
1469 assembler.Float64Equal(search_num.value(), | 1470 assembler->Float64Equal(search_num.value(), |
1470 assembler.SmiToFloat64(element_k)), | 1471 assembler->SmiToFloat64(element_k)), |
1471 &return_true, &continue_loop); | 1472 &return_true, &continue_loop); |
1472 | 1473 |
1473 assembler.Bind(¬_smi); | 1474 assembler->Bind(¬_smi); |
1474 assembler.GotoIf(assembler.WordNotEqual(assembler.LoadMap(element_k), | 1475 assembler->GotoIf(assembler->WordNotEqual(assembler->LoadMap(element_k), |
1475 heap_number_map), | 1476 heap_number_map), |
1476 &continue_loop); | 1477 &continue_loop); |
1477 assembler.Branch( | 1478 assembler->Branch( |
1478 assembler.Float64Equal(search_num.value(), | 1479 assembler->Float64Equal(search_num.value(), |
1479 assembler.LoadHeapNumberValue(element_k)), | 1480 assembler->LoadHeapNumberValue(element_k)), |
1480 &return_true, &continue_loop); | 1481 &return_true, &continue_loop); |
1481 | 1482 |
1482 assembler.Bind(&continue_loop); | 1483 assembler->Bind(&continue_loop); |
1483 index_var.Bind(assembler.IntPtrAdd(index_var.value(), intptr_one)); | 1484 index_var.Bind(assembler->IntPtrAdd(index_var.value(), intptr_one)); |
1484 assembler.Goto(¬_nan_loop); | 1485 assembler->Goto(¬_nan_loop); |
1485 } | 1486 } |
1486 | 1487 |
1487 assembler.Bind(&nan_loop); | 1488 assembler->Bind(&nan_loop); |
1488 { | 1489 { |
1489 Label continue_loop(&assembler); | 1490 Label continue_loop(assembler); |
1490 assembler.GotoUnless( | 1491 assembler->GotoUnless( |
1491 assembler.UintPtrLessThan(index_var.value(), len_var.value()), | 1492 assembler->UintPtrLessThan(index_var.value(), len_var.value()), |
1492 &return_false); | 1493 &return_false); |
1493 Node* element_k = assembler.LoadFixedArrayElement( | 1494 Node* element_k = assembler->LoadFixedArrayElement( |
1494 elements, index_var.value(), 0, | 1495 elements, index_var.value(), 0, |
1495 CodeStubAssembler::INTPTR_PARAMETERS); | 1496 CodeStubAssembler::INTPTR_PARAMETERS); |
1496 assembler.GotoIf(assembler.TaggedIsSmi(element_k), &continue_loop); | 1497 assembler->GotoIf(assembler->TaggedIsSmi(element_k), &continue_loop); |
1497 assembler.GotoIf(assembler.WordNotEqual(assembler.LoadMap(element_k), | 1498 assembler->GotoIf(assembler->WordNotEqual(assembler->LoadMap(element_k), |
1498 heap_number_map), | 1499 heap_number_map), |
1499 &continue_loop); | 1500 &continue_loop); |
1500 assembler.BranchIfFloat64IsNaN(assembler.LoadHeapNumberValue(element_k), | 1501 assembler->BranchIfFloat64IsNaN( |
1501 &return_true, &continue_loop); | 1502 assembler->LoadHeapNumberValue(element_k), &return_true, |
1502 | 1503 &continue_loop); |
1503 assembler.Bind(&continue_loop); | 1504 |
1504 index_var.Bind(assembler.IntPtrAdd(index_var.value(), intptr_one)); | 1505 assembler->Bind(&continue_loop); |
1505 assembler.Goto(&nan_loop); | 1506 index_var.Bind(assembler->IntPtrAdd(index_var.value(), intptr_one)); |
1506 } | 1507 assembler->Goto(&nan_loop); |
1507 } | 1508 } |
1508 | 1509 } |
1509 assembler.Bind(&string_loop); | 1510 |
1510 { | 1511 assembler->Bind(&string_loop); |
1511 Label continue_loop(&assembler); | 1512 { |
1512 assembler.GotoUnless( | 1513 Label continue_loop(assembler); |
1513 assembler.UintPtrLessThan(index_var.value(), len_var.value()), | 1514 assembler->GotoUnless( |
1514 &return_false); | 1515 assembler->UintPtrLessThan(index_var.value(), len_var.value()), |
1515 Node* element_k = assembler.LoadFixedArrayElement( | 1516 &return_false); |
| 1517 Node* element_k = assembler->LoadFixedArrayElement( |
1516 elements, index_var.value(), 0, CodeStubAssembler::INTPTR_PARAMETERS); | 1518 elements, index_var.value(), 0, CodeStubAssembler::INTPTR_PARAMETERS); |
1517 assembler.GotoIf(assembler.TaggedIsSmi(element_k), &continue_loop); | 1519 assembler->GotoIf(assembler->TaggedIsSmi(element_k), &continue_loop); |
1518 assembler.GotoUnless( | 1520 assembler->GotoUnless(assembler->IsStringInstanceType( |
1519 assembler.IsStringInstanceType(assembler.LoadInstanceType(element_k)), | 1521 assembler->LoadInstanceType(element_k)), |
1520 &continue_loop); | 1522 &continue_loop); |
1521 | 1523 |
1522 // TODO(bmeurer): Consider inlining the StringEqual logic here. | 1524 // TODO(bmeurer): Consider inlining the StringEqual logic here. |
1523 Callable callable = CodeFactory::StringEqual(assembler.isolate()); | 1525 Callable callable = CodeFactory::StringEqual(assembler->isolate()); |
1524 Node* result = | 1526 Node* result = |
1525 assembler.CallStub(callable, context, search_element, element_k); | 1527 assembler->CallStub(callable, context, search_element, element_k); |
1526 assembler.Branch( | 1528 assembler->Branch( |
1527 assembler.WordEqual(assembler.BooleanConstant(true), result), | 1529 assembler->WordEqual(assembler->BooleanConstant(true), result), |
1528 &return_true, &continue_loop); | 1530 &return_true, &continue_loop); |
1529 | 1531 |
1530 assembler.Bind(&continue_loop); | 1532 assembler->Bind(&continue_loop); |
1531 index_var.Bind(assembler.IntPtrAdd(index_var.value(), intptr_one)); | 1533 index_var.Bind(assembler->IntPtrAdd(index_var.value(), intptr_one)); |
1532 assembler.Goto(&string_loop); | 1534 assembler->Goto(&string_loop); |
1533 } | 1535 } |
1534 | 1536 |
1535 assembler.Bind(&simd_loop); | 1537 assembler->Bind(&simd_loop); |
1536 { | 1538 { |
1537 Label continue_loop(&assembler, &index_var), | 1539 Label continue_loop(assembler, &index_var), |
1538 loop_body(&assembler, &index_var); | 1540 loop_body(assembler, &index_var); |
1539 Node* map = assembler.LoadMap(search_element); | 1541 Node* map = assembler->LoadMap(search_element); |
1540 | 1542 |
1541 assembler.Goto(&loop_body); | 1543 assembler->Goto(&loop_body); |
1542 assembler.Bind(&loop_body); | 1544 assembler->Bind(&loop_body); |
1543 assembler.GotoUnless( | 1545 assembler->GotoUnless( |
1544 assembler.UintPtrLessThan(index_var.value(), len_var.value()), | 1546 assembler->UintPtrLessThan(index_var.value(), len_var.value()), |
1545 &return_false); | 1547 &return_false); |
1546 | 1548 |
1547 Node* element_k = assembler.LoadFixedArrayElement( | 1549 Node* element_k = assembler->LoadFixedArrayElement( |
1548 elements, index_var.value(), 0, CodeStubAssembler::INTPTR_PARAMETERS); | 1550 elements, index_var.value(), 0, CodeStubAssembler::INTPTR_PARAMETERS); |
1549 assembler.GotoIf(assembler.TaggedIsSmi(element_k), &continue_loop); | 1551 assembler->GotoIf(assembler->TaggedIsSmi(element_k), &continue_loop); |
1550 | 1552 |
1551 Node* map_k = assembler.LoadMap(element_k); | 1553 Node* map_k = assembler->LoadMap(element_k); |
1552 assembler.BranchIfSimd128Equal(search_element, map, element_k, map_k, | 1554 assembler->BranchIfSimd128Equal(search_element, map, element_k, map_k, |
1553 &return_true, &continue_loop); | 1555 &return_true, &continue_loop); |
1554 | 1556 |
1555 assembler.Bind(&continue_loop); | 1557 assembler->Bind(&continue_loop); |
1556 index_var.Bind(assembler.IntPtrAdd(index_var.value(), intptr_one)); | 1558 index_var.Bind(assembler->IntPtrAdd(index_var.value(), intptr_one)); |
1557 assembler.Goto(&loop_body); | 1559 assembler->Goto(&loop_body); |
1558 } | 1560 } |
1559 } | 1561 } |
1560 | 1562 |
1561 assembler.Bind(&if_packed_doubles); | 1563 assembler->Bind(&if_packed_doubles); |
1562 { | 1564 { |
1563 Label nan_loop(&assembler, &index_var), | 1565 Label nan_loop(assembler, &index_var), not_nan_loop(assembler, &index_var), |
1564 not_nan_loop(&assembler, &index_var), hole_loop(&assembler, &index_var), | 1566 hole_loop(assembler, &index_var), search_notnan(assembler); |
1565 search_notnan(&assembler); | 1567 Variable search_num(assembler, MachineRepresentation::kFloat64); |
1566 Variable search_num(&assembler, MachineRepresentation::kFloat64); | 1568 |
1567 | 1569 assembler->GotoUnless(assembler->TaggedIsSmi(search_element), |
1568 assembler.GotoUnless(assembler.TaggedIsSmi(search_element), &search_notnan); | 1570 &search_notnan); |
1569 search_num.Bind(assembler.SmiToFloat64(search_element)); | 1571 search_num.Bind(assembler->SmiToFloat64(search_element)); |
1570 assembler.Goto(¬_nan_loop); | 1572 assembler->Goto(¬_nan_loop); |
1571 | 1573 |
1572 assembler.Bind(&search_notnan); | 1574 assembler->Bind(&search_notnan); |
1573 assembler.GotoIf(assembler.WordNotEqual(assembler.LoadMap(search_element), | 1575 assembler->GotoIf(assembler->WordNotEqual( |
1574 heap_number_map), | 1576 assembler->LoadMap(search_element), heap_number_map), |
1575 &return_false); | 1577 &return_false); |
1576 | 1578 |
1577 search_num.Bind(assembler.LoadHeapNumberValue(search_element)); | 1579 search_num.Bind(assembler->LoadHeapNumberValue(search_element)); |
1578 | 1580 |
1579 assembler.BranchIfFloat64IsNaN(search_num.value(), &nan_loop, | 1581 assembler->BranchIfFloat64IsNaN(search_num.value(), &nan_loop, |
1580 ¬_nan_loop); | 1582 ¬_nan_loop); |
1581 | 1583 |
1582 // Search for HeapNumber | 1584 // Search for HeapNumber |
1583 assembler.Bind(¬_nan_loop); | 1585 assembler->Bind(¬_nan_loop); |
1584 { | 1586 { |
1585 Label continue_loop(&assembler); | 1587 Label continue_loop(assembler); |
1586 assembler.GotoUnless( | 1588 assembler->GotoUnless( |
1587 assembler.UintPtrLessThan(index_var.value(), len_var.value()), | 1589 assembler->UintPtrLessThan(index_var.value(), len_var.value()), |
1588 &return_false); | 1590 &return_false); |
1589 Node* element_k = assembler.LoadFixedDoubleArrayElement( | 1591 Node* element_k = assembler->LoadFixedDoubleArrayElement( |
1590 elements, index_var.value(), MachineType::Float64(), 0, | 1592 elements, index_var.value(), MachineType::Float64(), 0, |
1591 CodeStubAssembler::INTPTR_PARAMETERS); | 1593 CodeStubAssembler::INTPTR_PARAMETERS); |
1592 assembler.Branch(assembler.Float64Equal(element_k, search_num.value()), | 1594 assembler->Branch(assembler->Float64Equal(element_k, search_num.value()), |
1593 &return_true, &continue_loop); | 1595 &return_true, &continue_loop); |
1594 assembler.Bind(&continue_loop); | 1596 assembler->Bind(&continue_loop); |
1595 index_var.Bind(assembler.IntPtrAdd(index_var.value(), intptr_one)); | 1597 index_var.Bind(assembler->IntPtrAdd(index_var.value(), intptr_one)); |
1596 assembler.Goto(¬_nan_loop); | 1598 assembler->Goto(¬_nan_loop); |
1597 } | 1599 } |
1598 | 1600 |
1599 // Search for NaN | 1601 // Search for NaN |
1600 assembler.Bind(&nan_loop); | 1602 assembler->Bind(&nan_loop); |
1601 { | 1603 { |
1602 Label continue_loop(&assembler); | 1604 Label continue_loop(assembler); |
1603 assembler.GotoUnless( | 1605 assembler->GotoUnless( |
1604 assembler.UintPtrLessThan(index_var.value(), len_var.value()), | 1606 assembler->UintPtrLessThan(index_var.value(), len_var.value()), |
1605 &return_false); | 1607 &return_false); |
1606 Node* element_k = assembler.LoadFixedDoubleArrayElement( | 1608 Node* element_k = assembler->LoadFixedDoubleArrayElement( |
1607 elements, index_var.value(), MachineType::Float64(), 0, | 1609 elements, index_var.value(), MachineType::Float64(), 0, |
1608 CodeStubAssembler::INTPTR_PARAMETERS); | 1610 CodeStubAssembler::INTPTR_PARAMETERS); |
1609 assembler.BranchIfFloat64IsNaN(element_k, &return_true, &continue_loop); | 1611 assembler->BranchIfFloat64IsNaN(element_k, &return_true, &continue_loop); |
1610 assembler.Bind(&continue_loop); | 1612 assembler->Bind(&continue_loop); |
1611 index_var.Bind(assembler.IntPtrAdd(index_var.value(), intptr_one)); | 1613 index_var.Bind(assembler->IntPtrAdd(index_var.value(), intptr_one)); |
1612 assembler.Goto(&nan_loop); | 1614 assembler->Goto(&nan_loop); |
1613 } | 1615 } |
1614 } | 1616 } |
1615 | 1617 |
1616 assembler.Bind(&if_holey_doubles); | 1618 assembler->Bind(&if_holey_doubles); |
1617 { | 1619 { |
1618 Label nan_loop(&assembler, &index_var), | 1620 Label nan_loop(assembler, &index_var), not_nan_loop(assembler, &index_var), |
1619 not_nan_loop(&assembler, &index_var), hole_loop(&assembler, &index_var), | 1621 hole_loop(assembler, &index_var), search_notnan(assembler); |
1620 search_notnan(&assembler); | 1622 Variable search_num(assembler, MachineRepresentation::kFloat64); |
1621 Variable search_num(&assembler, MachineRepresentation::kFloat64); | 1623 |
1622 | 1624 assembler->GotoUnless(assembler->TaggedIsSmi(search_element), |
1623 assembler.GotoUnless(assembler.TaggedIsSmi(search_element), &search_notnan); | 1625 &search_notnan); |
1624 search_num.Bind(assembler.SmiToFloat64(search_element)); | 1626 search_num.Bind(assembler->SmiToFloat64(search_element)); |
1625 assembler.Goto(¬_nan_loop); | 1627 assembler->Goto(¬_nan_loop); |
1626 | 1628 |
1627 assembler.Bind(&search_notnan); | 1629 assembler->Bind(&search_notnan); |
1628 assembler.GotoIf(assembler.WordEqual(search_element, undefined), | 1630 assembler->GotoIf(assembler->WordEqual(search_element, undefined), |
1629 &hole_loop); | 1631 &hole_loop); |
1630 assembler.GotoIf(assembler.WordNotEqual(assembler.LoadMap(search_element), | 1632 assembler->GotoIf(assembler->WordNotEqual( |
1631 heap_number_map), | 1633 assembler->LoadMap(search_element), heap_number_map), |
1632 &return_false); | 1634 &return_false); |
1633 | 1635 |
1634 search_num.Bind(assembler.LoadHeapNumberValue(search_element)); | 1636 search_num.Bind(assembler->LoadHeapNumberValue(search_element)); |
1635 | 1637 |
1636 assembler.BranchIfFloat64IsNaN(search_num.value(), &nan_loop, | 1638 assembler->BranchIfFloat64IsNaN(search_num.value(), &nan_loop, |
1637 ¬_nan_loop); | 1639 ¬_nan_loop); |
1638 | 1640 |
1639 // Search for HeapNumber | 1641 // Search for HeapNumber |
1640 assembler.Bind(¬_nan_loop); | 1642 assembler->Bind(¬_nan_loop); |
1641 { | 1643 { |
1642 Label continue_loop(&assembler); | 1644 Label continue_loop(assembler); |
1643 assembler.GotoUnless( | 1645 assembler->GotoUnless( |
1644 assembler.UintPtrLessThan(index_var.value(), len_var.value()), | 1646 assembler->UintPtrLessThan(index_var.value(), len_var.value()), |
1645 &return_false); | 1647 &return_false); |
1646 | 1648 |
1647 // Load double value or continue if it contains a double hole. | 1649 // Load double value or continue if it contains a double hole. |
1648 Node* element_k = assembler.LoadFixedDoubleArrayElement( | 1650 Node* element_k = assembler->LoadFixedDoubleArrayElement( |
1649 elements, index_var.value(), MachineType::Float64(), 0, | 1651 elements, index_var.value(), MachineType::Float64(), 0, |
1650 CodeStubAssembler::INTPTR_PARAMETERS, &continue_loop); | 1652 CodeStubAssembler::INTPTR_PARAMETERS, &continue_loop); |
1651 | 1653 |
1652 assembler.Branch(assembler.Float64Equal(element_k, search_num.value()), | 1654 assembler->Branch(assembler->Float64Equal(element_k, search_num.value()), |
1653 &return_true, &continue_loop); | 1655 &return_true, &continue_loop); |
1654 assembler.Bind(&continue_loop); | 1656 assembler->Bind(&continue_loop); |
1655 index_var.Bind(assembler.IntPtrAdd(index_var.value(), intptr_one)); | 1657 index_var.Bind(assembler->IntPtrAdd(index_var.value(), intptr_one)); |
1656 assembler.Goto(¬_nan_loop); | 1658 assembler->Goto(¬_nan_loop); |
1657 } | 1659 } |
1658 | 1660 |
1659 // Search for NaN | 1661 // Search for NaN |
1660 assembler.Bind(&nan_loop); | 1662 assembler->Bind(&nan_loop); |
1661 { | 1663 { |
1662 Label continue_loop(&assembler); | 1664 Label continue_loop(assembler); |
1663 assembler.GotoUnless( | 1665 assembler->GotoUnless( |
1664 assembler.UintPtrLessThan(index_var.value(), len_var.value()), | 1666 assembler->UintPtrLessThan(index_var.value(), len_var.value()), |
1665 &return_false); | 1667 &return_false); |
1666 | 1668 |
1667 // Load double value or continue if it contains a double hole. | 1669 // Load double value or continue if it contains a double hole. |
1668 Node* element_k = assembler.LoadFixedDoubleArrayElement( | 1670 Node* element_k = assembler->LoadFixedDoubleArrayElement( |
1669 elements, index_var.value(), MachineType::Float64(), 0, | 1671 elements, index_var.value(), MachineType::Float64(), 0, |
1670 CodeStubAssembler::INTPTR_PARAMETERS, &continue_loop); | 1672 CodeStubAssembler::INTPTR_PARAMETERS, &continue_loop); |
1671 | 1673 |
1672 assembler.BranchIfFloat64IsNaN(element_k, &return_true, &continue_loop); | 1674 assembler->BranchIfFloat64IsNaN(element_k, &return_true, &continue_loop); |
1673 assembler.Bind(&continue_loop); | 1675 assembler->Bind(&continue_loop); |
1674 index_var.Bind(assembler.IntPtrAdd(index_var.value(), intptr_one)); | 1676 index_var.Bind(assembler->IntPtrAdd(index_var.value(), intptr_one)); |
1675 assembler.Goto(&nan_loop); | 1677 assembler->Goto(&nan_loop); |
1676 } | 1678 } |
1677 | 1679 |
1678 // Search for the Hole | 1680 // Search for the Hole |
1679 assembler.Bind(&hole_loop); | 1681 assembler->Bind(&hole_loop); |
1680 { | 1682 { |
1681 assembler.GotoUnless( | 1683 assembler->GotoUnless( |
1682 assembler.UintPtrLessThan(index_var.value(), len_var.value()), | 1684 assembler->UintPtrLessThan(index_var.value(), len_var.value()), |
1683 &return_false); | 1685 &return_false); |
1684 | 1686 |
1685 // Check if the element is a double hole, but don't load it. | 1687 // Check if the element is a double hole, but don't load it. |
1686 assembler.LoadFixedDoubleArrayElement( | 1688 assembler->LoadFixedDoubleArrayElement( |
1687 elements, index_var.value(), MachineType::None(), 0, | 1689 elements, index_var.value(), MachineType::None(), 0, |
1688 CodeStubAssembler::INTPTR_PARAMETERS, &return_true); | 1690 CodeStubAssembler::INTPTR_PARAMETERS, &return_true); |
1689 | 1691 |
1690 index_var.Bind(assembler.IntPtrAdd(index_var.value(), intptr_one)); | 1692 index_var.Bind(assembler->IntPtrAdd(index_var.value(), intptr_one)); |
1691 assembler.Goto(&hole_loop); | 1693 assembler->Goto(&hole_loop); |
1692 } | 1694 } |
1693 } | 1695 } |
1694 | 1696 |
1695 assembler.Bind(&return_true); | 1697 assembler->Bind(&return_true); |
1696 assembler.Return(assembler.BooleanConstant(true)); | 1698 assembler->Return(assembler->BooleanConstant(true)); |
1697 | 1699 |
1698 assembler.Bind(&return_false); | 1700 assembler->Bind(&return_false); |
1699 assembler.Return(assembler.BooleanConstant(false)); | 1701 assembler->Return(assembler->BooleanConstant(false)); |
1700 | 1702 |
1701 assembler.Bind(&call_runtime); | 1703 assembler->Bind(&call_runtime); |
1702 assembler.Return(assembler.CallRuntime(Runtime::kArrayIncludes_Slow, context, | 1704 assembler->Return(assembler->CallRuntime(Runtime::kArrayIncludes_Slow, |
1703 array, search_element, start_from)); | 1705 context, array, search_element, |
| 1706 start_from)); |
1704 } | 1707 } |
1705 | 1708 |
1706 void Builtins::Generate_ArrayIndexOf(compiler::CodeAssemblerState* state) { | 1709 void Builtins::Generate_ArrayIndexOf(CodeStubAssembler* assembler) { |
1707 typedef compiler::Node Node; | 1710 typedef compiler::Node Node; |
1708 typedef CodeStubAssembler::Label Label; | 1711 typedef CodeStubAssembler::Label Label; |
1709 typedef CodeStubAssembler::Variable Variable; | 1712 typedef CodeStubAssembler::Variable Variable; |
1710 CodeStubAssembler assembler(state); | 1713 |
1711 | 1714 Node* array = assembler->Parameter(0); |
1712 Node* array = assembler.Parameter(0); | 1715 Node* search_element = assembler->Parameter(1); |
1713 Node* search_element = assembler.Parameter(1); | 1716 Node* start_from = assembler->Parameter(2); |
1714 Node* start_from = assembler.Parameter(2); | 1717 Node* context = assembler->Parameter(3 + 2); |
1715 Node* context = assembler.Parameter(3 + 2); | 1718 |
1716 | 1719 Node* intptr_zero = assembler->IntPtrConstant(0); |
1717 Node* intptr_zero = assembler.IntPtrConstant(0); | 1720 Node* intptr_one = assembler->IntPtrConstant(1); |
1718 Node* intptr_one = assembler.IntPtrConstant(1); | 1721 |
1719 | 1722 Node* undefined = assembler->UndefinedConstant(); |
1720 Node* undefined = assembler.UndefinedConstant(); | 1723 Node* heap_number_map = assembler->HeapNumberMapConstant(); |
1721 Node* heap_number_map = assembler.HeapNumberMapConstant(); | 1724 |
1722 | 1725 Variable len_var(assembler, MachineType::PointerRepresentation()), |
1723 Variable len_var(&assembler, MachineType::PointerRepresentation()), | 1726 index_var(assembler, MachineType::PointerRepresentation()), |
1724 index_var(&assembler, MachineType::PointerRepresentation()), | 1727 start_from_var(assembler, MachineType::PointerRepresentation()); |
1725 start_from_var(&assembler, MachineType::PointerRepresentation()); | 1728 |
1726 | 1729 Label init_k(assembler), return_found(assembler), return_not_found(assembler), |
1727 Label init_k(&assembler), return_found(&assembler), | 1730 call_runtime(assembler); |
1728 return_not_found(&assembler), call_runtime(&assembler); | 1731 |
1729 | 1732 Label init_len(assembler); |
1730 Label init_len(&assembler); | |
1731 | 1733 |
1732 index_var.Bind(intptr_zero); | 1734 index_var.Bind(intptr_zero); |
1733 len_var.Bind(intptr_zero); | 1735 len_var.Bind(intptr_zero); |
1734 | 1736 |
1735 // Take slow path if not a JSArray, if retrieving elements requires | 1737 // Take slow path if not a JSArray, if retrieving elements requires |
1736 // traversing prototype, or if access checks are required. | 1738 // traversing prototype, or if access checks are required. |
1737 assembler.BranchIfFastJSArray(array, context, &init_len, &call_runtime); | 1739 assembler->BranchIfFastJSArray(array, context, &init_len, &call_runtime); |
1738 | 1740 |
1739 assembler.Bind(&init_len); | 1741 assembler->Bind(&init_len); |
1740 { | 1742 { |
1741 // Handle case where JSArray length is not an Smi in the runtime | 1743 // Handle case where JSArray length is not an Smi in the runtime |
1742 Node* len = assembler.LoadObjectField(array, JSArray::kLengthOffset); | 1744 Node* len = assembler->LoadObjectField(array, JSArray::kLengthOffset); |
1743 assembler.GotoUnless(assembler.TaggedIsSmi(len), &call_runtime); | 1745 assembler->GotoUnless(assembler->TaggedIsSmi(len), &call_runtime); |
1744 | 1746 |
1745 len_var.Bind(assembler.SmiToWord(len)); | 1747 len_var.Bind(assembler->SmiToWord(len)); |
1746 assembler.Branch(assembler.WordEqual(len_var.value(), intptr_zero), | 1748 assembler->Branch(assembler->WordEqual(len_var.value(), intptr_zero), |
1747 &return_not_found, &init_k); | 1749 &return_not_found, &init_k); |
1748 } | 1750 } |
1749 | 1751 |
1750 assembler.Bind(&init_k); | 1752 assembler->Bind(&init_k); |
1751 { | 1753 { |
1752 Label done(&assembler), init_k_smi(&assembler), init_k_heap_num(&assembler), | 1754 Label done(assembler), init_k_smi(assembler), init_k_heap_num(assembler), |
1753 init_k_zero(&assembler), init_k_n(&assembler); | 1755 init_k_zero(assembler), init_k_n(assembler); |
1754 Node* tagged_n = assembler.ToInteger(context, start_from); | 1756 Node* tagged_n = assembler->ToInteger(context, start_from); |
1755 | 1757 |
1756 assembler.Branch(assembler.TaggedIsSmi(tagged_n), &init_k_smi, | 1758 assembler->Branch(assembler->TaggedIsSmi(tagged_n), &init_k_smi, |
1757 &init_k_heap_num); | 1759 &init_k_heap_num); |
1758 | 1760 |
1759 assembler.Bind(&init_k_smi); | 1761 assembler->Bind(&init_k_smi); |
1760 { | 1762 { |
1761 start_from_var.Bind(assembler.SmiUntag(tagged_n)); | 1763 start_from_var.Bind(assembler->SmiUntag(tagged_n)); |
1762 assembler.Goto(&init_k_n); | 1764 assembler->Goto(&init_k_n); |
1763 } | 1765 } |
1764 | 1766 |
1765 assembler.Bind(&init_k_heap_num); | 1767 assembler->Bind(&init_k_heap_num); |
1766 { | 1768 { |
1767 Label do_return_not_found(&assembler); | 1769 Label do_return_not_found(assembler); |
1768 // This round is lossless for all valid lengths. | 1770 // This round is lossless for all valid lengths. |
1769 Node* fp_len = assembler.RoundIntPtrToFloat64(len_var.value()); | 1771 Node* fp_len = assembler->RoundIntPtrToFloat64(len_var.value()); |
1770 Node* fp_n = assembler.LoadHeapNumberValue(tagged_n); | 1772 Node* fp_n = assembler->LoadHeapNumberValue(tagged_n); |
1771 assembler.GotoIf(assembler.Float64GreaterThanOrEqual(fp_n, fp_len), | 1773 assembler->GotoIf(assembler->Float64GreaterThanOrEqual(fp_n, fp_len), |
1772 &do_return_not_found); | 1774 &do_return_not_found); |
1773 start_from_var.Bind(assembler.ChangeInt32ToIntPtr( | 1775 start_from_var.Bind(assembler->ChangeInt32ToIntPtr( |
1774 assembler.TruncateFloat64ToWord32(fp_n))); | 1776 assembler->TruncateFloat64ToWord32(fp_n))); |
1775 assembler.Goto(&init_k_n); | 1777 assembler->Goto(&init_k_n); |
1776 | 1778 |
1777 assembler.Bind(&do_return_not_found); | 1779 assembler->Bind(&do_return_not_found); |
1778 { | 1780 { |
1779 index_var.Bind(intptr_zero); | 1781 index_var.Bind(intptr_zero); |
1780 assembler.Goto(&return_not_found); | 1782 assembler->Goto(&return_not_found); |
1781 } | 1783 } |
1782 } | 1784 } |
1783 | 1785 |
1784 assembler.Bind(&init_k_n); | 1786 assembler->Bind(&init_k_n); |
1785 { | 1787 { |
1786 Label if_positive(&assembler), if_negative(&assembler), done(&assembler); | 1788 Label if_positive(assembler), if_negative(assembler), done(assembler); |
1787 assembler.Branch( | 1789 assembler->Branch( |
1788 assembler.IntPtrLessThan(start_from_var.value(), intptr_zero), | 1790 assembler->IntPtrLessThan(start_from_var.value(), intptr_zero), |
1789 &if_negative, &if_positive); | 1791 &if_negative, &if_positive); |
1790 | 1792 |
1791 assembler.Bind(&if_positive); | 1793 assembler->Bind(&if_positive); |
1792 { | 1794 { |
1793 index_var.Bind(start_from_var.value()); | 1795 index_var.Bind(start_from_var.value()); |
1794 assembler.Goto(&done); | 1796 assembler->Goto(&done); |
1795 } | 1797 } |
1796 | 1798 |
1797 assembler.Bind(&if_negative); | 1799 assembler->Bind(&if_negative); |
1798 { | 1800 { |
1799 index_var.Bind( | 1801 index_var.Bind( |
1800 assembler.IntPtrAdd(len_var.value(), start_from_var.value())); | 1802 assembler->IntPtrAdd(len_var.value(), start_from_var.value())); |
1801 assembler.Branch( | 1803 assembler->Branch( |
1802 assembler.IntPtrLessThan(index_var.value(), intptr_zero), | 1804 assembler->IntPtrLessThan(index_var.value(), intptr_zero), |
1803 &init_k_zero, &done); | 1805 &init_k_zero, &done); |
1804 } | 1806 } |
1805 | 1807 |
1806 assembler.Bind(&init_k_zero); | 1808 assembler->Bind(&init_k_zero); |
1807 { | 1809 { |
1808 index_var.Bind(intptr_zero); | 1810 index_var.Bind(intptr_zero); |
1809 assembler.Goto(&done); | 1811 assembler->Goto(&done); |
1810 } | 1812 } |
1811 | 1813 |
1812 assembler.Bind(&done); | 1814 assembler->Bind(&done); |
1813 } | 1815 } |
1814 } | 1816 } |
1815 | 1817 |
1816 static int32_t kElementsKind[] = { | 1818 static int32_t kElementsKind[] = { |
1817 FAST_SMI_ELEMENTS, FAST_HOLEY_SMI_ELEMENTS, FAST_ELEMENTS, | 1819 FAST_SMI_ELEMENTS, FAST_HOLEY_SMI_ELEMENTS, FAST_ELEMENTS, |
1818 FAST_HOLEY_ELEMENTS, FAST_DOUBLE_ELEMENTS, FAST_HOLEY_DOUBLE_ELEMENTS, | 1820 FAST_HOLEY_ELEMENTS, FAST_DOUBLE_ELEMENTS, FAST_HOLEY_DOUBLE_ELEMENTS, |
1819 }; | 1821 }; |
1820 | 1822 |
1821 Label if_smiorobjects(&assembler), if_packed_doubles(&assembler), | 1823 Label if_smiorobjects(assembler), if_packed_doubles(assembler), |
1822 if_holey_doubles(&assembler); | 1824 if_holey_doubles(assembler); |
1823 Label* element_kind_handlers[] = {&if_smiorobjects, &if_smiorobjects, | 1825 Label* element_kind_handlers[] = {&if_smiorobjects, &if_smiorobjects, |
1824 &if_smiorobjects, &if_smiorobjects, | 1826 &if_smiorobjects, &if_smiorobjects, |
1825 &if_packed_doubles, &if_holey_doubles}; | 1827 &if_packed_doubles, &if_holey_doubles}; |
1826 | 1828 |
1827 Node* map = assembler.LoadMap(array); | 1829 Node* map = assembler->LoadMap(array); |
1828 Node* elements_kind = assembler.LoadMapElementsKind(map); | 1830 Node* elements_kind = assembler->LoadMapElementsKind(map); |
1829 Node* elements = assembler.LoadElements(array); | 1831 Node* elements = assembler->LoadElements(array); |
1830 assembler.Switch(elements_kind, &return_not_found, kElementsKind, | 1832 assembler->Switch(elements_kind, &return_not_found, kElementsKind, |
1831 element_kind_handlers, arraysize(kElementsKind)); | 1833 element_kind_handlers, arraysize(kElementsKind)); |
1832 | 1834 |
1833 assembler.Bind(&if_smiorobjects); | 1835 assembler->Bind(&if_smiorobjects); |
1834 { | 1836 { |
1835 Variable search_num(&assembler, MachineRepresentation::kFloat64); | 1837 Variable search_num(assembler, MachineRepresentation::kFloat64); |
1836 Label ident_loop(&assembler, &index_var), | 1838 Label ident_loop(assembler, &index_var), |
1837 heap_num_loop(&assembler, &search_num), | 1839 heap_num_loop(assembler, &search_num), |
1838 string_loop(&assembler, &index_var), simd_loop(&assembler), | 1840 string_loop(assembler, &index_var), simd_loop(assembler), |
1839 undef_loop(&assembler, &index_var), not_smi(&assembler), | 1841 undef_loop(assembler, &index_var), not_smi(assembler), |
1840 not_heap_num(&assembler); | 1842 not_heap_num(assembler); |
1841 | 1843 |
1842 assembler.GotoUnless(assembler.TaggedIsSmi(search_element), ¬_smi); | 1844 assembler->GotoUnless(assembler->TaggedIsSmi(search_element), ¬_smi); |
1843 search_num.Bind(assembler.SmiToFloat64(search_element)); | 1845 search_num.Bind(assembler->SmiToFloat64(search_element)); |
1844 assembler.Goto(&heap_num_loop); | 1846 assembler->Goto(&heap_num_loop); |
1845 | 1847 |
1846 assembler.Bind(¬_smi); | 1848 assembler->Bind(¬_smi); |
1847 assembler.GotoIf(assembler.WordEqual(search_element, undefined), | 1849 assembler->GotoIf(assembler->WordEqual(search_element, undefined), |
1848 &undef_loop); | 1850 &undef_loop); |
1849 Node* map = assembler.LoadMap(search_element); | 1851 Node* map = assembler->LoadMap(search_element); |
1850 assembler.GotoIf(assembler.WordNotEqual(map, heap_number_map), | 1852 assembler->GotoIf(assembler->WordNotEqual(map, heap_number_map), |
1851 ¬_heap_num); | 1853 ¬_heap_num); |
1852 search_num.Bind(assembler.LoadHeapNumberValue(search_element)); | 1854 search_num.Bind(assembler->LoadHeapNumberValue(search_element)); |
1853 assembler.Goto(&heap_num_loop); | 1855 assembler->Goto(&heap_num_loop); |
1854 | 1856 |
1855 assembler.Bind(¬_heap_num); | 1857 assembler->Bind(¬_heap_num); |
1856 Node* search_type = assembler.LoadMapInstanceType(map); | 1858 Node* search_type = assembler->LoadMapInstanceType(map); |
1857 assembler.GotoIf(assembler.IsStringInstanceType(search_type), &string_loop); | 1859 assembler->GotoIf(assembler->IsStringInstanceType(search_type), |
1858 assembler.GotoIf( | 1860 &string_loop); |
1859 assembler.Word32Equal(search_type, | 1861 assembler->GotoIf( |
1860 assembler.Int32Constant(SIMD128_VALUE_TYPE)), | 1862 assembler->Word32Equal(search_type, |
| 1863 assembler->Int32Constant(SIMD128_VALUE_TYPE)), |
1861 &simd_loop); | 1864 &simd_loop); |
1862 assembler.Goto(&ident_loop); | 1865 assembler->Goto(&ident_loop); |
1863 | 1866 |
1864 assembler.Bind(&ident_loop); | 1867 assembler->Bind(&ident_loop); |
1865 { | 1868 { |
1866 assembler.GotoUnless( | 1869 assembler->GotoUnless( |
1867 assembler.UintPtrLessThan(index_var.value(), len_var.value()), | 1870 assembler->UintPtrLessThan(index_var.value(), len_var.value()), |
1868 &return_not_found); | 1871 &return_not_found); |
1869 Node* element_k = assembler.LoadFixedArrayElement( | 1872 Node* element_k = assembler->LoadFixedArrayElement( |
1870 elements, index_var.value(), 0, CodeStubAssembler::INTPTR_PARAMETERS); | 1873 elements, index_var.value(), 0, CodeStubAssembler::INTPTR_PARAMETERS); |
1871 assembler.GotoIf(assembler.WordEqual(element_k, search_element), | 1874 assembler->GotoIf(assembler->WordEqual(element_k, search_element), |
1872 &return_found); | 1875 &return_found); |
1873 | 1876 |
1874 index_var.Bind(assembler.IntPtrAdd(index_var.value(), intptr_one)); | 1877 index_var.Bind(assembler->IntPtrAdd(index_var.value(), intptr_one)); |
1875 assembler.Goto(&ident_loop); | 1878 assembler->Goto(&ident_loop); |
1876 } | 1879 } |
1877 | 1880 |
1878 assembler.Bind(&undef_loop); | 1881 assembler->Bind(&undef_loop); |
1879 { | 1882 { |
1880 assembler.GotoUnless( | 1883 assembler->GotoUnless( |
1881 assembler.UintPtrLessThan(index_var.value(), len_var.value()), | 1884 assembler->UintPtrLessThan(index_var.value(), len_var.value()), |
1882 &return_not_found); | 1885 &return_not_found); |
1883 Node* element_k = assembler.LoadFixedArrayElement( | 1886 Node* element_k = assembler->LoadFixedArrayElement( |
1884 elements, index_var.value(), 0, CodeStubAssembler::INTPTR_PARAMETERS); | 1887 elements, index_var.value(), 0, CodeStubAssembler::INTPTR_PARAMETERS); |
1885 assembler.GotoIf(assembler.WordEqual(element_k, undefined), | 1888 assembler->GotoIf(assembler->WordEqual(element_k, undefined), |
1886 &return_found); | 1889 &return_found); |
1887 | 1890 |
1888 index_var.Bind(assembler.IntPtrAdd(index_var.value(), intptr_one)); | 1891 index_var.Bind(assembler->IntPtrAdd(index_var.value(), intptr_one)); |
1889 assembler.Goto(&undef_loop); | 1892 assembler->Goto(&undef_loop); |
1890 } | 1893 } |
1891 | 1894 |
1892 assembler.Bind(&heap_num_loop); | 1895 assembler->Bind(&heap_num_loop); |
1893 { | 1896 { |
1894 Label not_nan_loop(&assembler, &index_var); | 1897 Label not_nan_loop(assembler, &index_var); |
1895 assembler.BranchIfFloat64IsNaN(search_num.value(), &return_not_found, | 1898 assembler->BranchIfFloat64IsNaN(search_num.value(), &return_not_found, |
1896 ¬_nan_loop); | 1899 ¬_nan_loop); |
1897 | 1900 |
1898 assembler.Bind(¬_nan_loop); | 1901 assembler->Bind(¬_nan_loop); |
1899 { | 1902 { |
1900 Label continue_loop(&assembler), not_smi(&assembler); | 1903 Label continue_loop(assembler), not_smi(assembler); |
1901 assembler.GotoUnless( | 1904 assembler->GotoUnless( |
1902 assembler.UintPtrLessThan(index_var.value(), len_var.value()), | 1905 assembler->UintPtrLessThan(index_var.value(), len_var.value()), |
1903 &return_not_found); | 1906 &return_not_found); |
1904 Node* element_k = assembler.LoadFixedArrayElement( | 1907 Node* element_k = assembler->LoadFixedArrayElement( |
1905 elements, index_var.value(), 0, | 1908 elements, index_var.value(), 0, |
1906 CodeStubAssembler::INTPTR_PARAMETERS); | 1909 CodeStubAssembler::INTPTR_PARAMETERS); |
1907 assembler.GotoUnless(assembler.TaggedIsSmi(element_k), ¬_smi); | 1910 assembler->GotoUnless(assembler->TaggedIsSmi(element_k), ¬_smi); |
1908 assembler.Branch( | 1911 assembler->Branch( |
1909 assembler.Float64Equal(search_num.value(), | 1912 assembler->Float64Equal(search_num.value(), |
1910 assembler.SmiToFloat64(element_k)), | 1913 assembler->SmiToFloat64(element_k)), |
1911 &return_found, &continue_loop); | 1914 &return_found, &continue_loop); |
1912 | 1915 |
1913 assembler.Bind(¬_smi); | 1916 assembler->Bind(¬_smi); |
1914 assembler.GotoIf(assembler.WordNotEqual(assembler.LoadMap(element_k), | 1917 assembler->GotoIf(assembler->WordNotEqual(assembler->LoadMap(element_k), |
1915 heap_number_map), | 1918 heap_number_map), |
1916 &continue_loop); | 1919 &continue_loop); |
1917 assembler.Branch( | 1920 assembler->Branch( |
1918 assembler.Float64Equal(search_num.value(), | 1921 assembler->Float64Equal(search_num.value(), |
1919 assembler.LoadHeapNumberValue(element_k)), | 1922 assembler->LoadHeapNumberValue(element_k)), |
1920 &return_found, &continue_loop); | 1923 &return_found, &continue_loop); |
1921 | 1924 |
1922 assembler.Bind(&continue_loop); | 1925 assembler->Bind(&continue_loop); |
1923 index_var.Bind(assembler.IntPtrAdd(index_var.value(), intptr_one)); | 1926 index_var.Bind(assembler->IntPtrAdd(index_var.value(), intptr_one)); |
1924 assembler.Goto(¬_nan_loop); | 1927 assembler->Goto(¬_nan_loop); |
1925 } | 1928 } |
1926 } | 1929 } |
1927 | 1930 |
1928 assembler.Bind(&string_loop); | 1931 assembler->Bind(&string_loop); |
1929 { | 1932 { |
1930 Label continue_loop(&assembler); | 1933 Label continue_loop(assembler); |
1931 assembler.GotoUnless( | 1934 assembler->GotoUnless( |
1932 assembler.UintPtrLessThan(index_var.value(), len_var.value()), | 1935 assembler->UintPtrLessThan(index_var.value(), len_var.value()), |
1933 &return_not_found); | 1936 &return_not_found); |
1934 Node* element_k = assembler.LoadFixedArrayElement( | 1937 Node* element_k = assembler->LoadFixedArrayElement( |
1935 elements, index_var.value(), 0, CodeStubAssembler::INTPTR_PARAMETERS); | 1938 elements, index_var.value(), 0, CodeStubAssembler::INTPTR_PARAMETERS); |
1936 assembler.GotoIf(assembler.TaggedIsSmi(element_k), &continue_loop); | 1939 assembler->GotoIf(assembler->TaggedIsSmi(element_k), &continue_loop); |
1937 assembler.GotoUnless( | 1940 assembler->GotoUnless(assembler->IsStringInstanceType( |
1938 assembler.IsStringInstanceType(assembler.LoadInstanceType(element_k)), | 1941 assembler->LoadInstanceType(element_k)), |
1939 &continue_loop); | 1942 &continue_loop); |
1940 | 1943 |
1941 // TODO(bmeurer): Consider inlining the StringEqual logic here. | 1944 // TODO(bmeurer): Consider inlining the StringEqual logic here. |
1942 Callable callable = CodeFactory::StringEqual(assembler.isolate()); | 1945 Callable callable = CodeFactory::StringEqual(assembler->isolate()); |
1943 Node* result = | 1946 Node* result = |
1944 assembler.CallStub(callable, context, search_element, element_k); | 1947 assembler->CallStub(callable, context, search_element, element_k); |
1945 assembler.Branch( | 1948 assembler->Branch( |
1946 assembler.WordEqual(assembler.BooleanConstant(true), result), | 1949 assembler->WordEqual(assembler->BooleanConstant(true), result), |
1947 &return_found, &continue_loop); | 1950 &return_found, &continue_loop); |
1948 | 1951 |
1949 assembler.Bind(&continue_loop); | 1952 assembler->Bind(&continue_loop); |
1950 index_var.Bind(assembler.IntPtrAdd(index_var.value(), intptr_one)); | 1953 index_var.Bind(assembler->IntPtrAdd(index_var.value(), intptr_one)); |
1951 assembler.Goto(&string_loop); | 1954 assembler->Goto(&string_loop); |
1952 } | 1955 } |
1953 | 1956 |
1954 assembler.Bind(&simd_loop); | 1957 assembler->Bind(&simd_loop); |
1955 { | 1958 { |
1956 Label continue_loop(&assembler, &index_var), | 1959 Label continue_loop(assembler, &index_var), |
1957 loop_body(&assembler, &index_var); | 1960 loop_body(assembler, &index_var); |
1958 Node* map = assembler.LoadMap(search_element); | 1961 Node* map = assembler->LoadMap(search_element); |
1959 | 1962 |
1960 assembler.Goto(&loop_body); | 1963 assembler->Goto(&loop_body); |
1961 assembler.Bind(&loop_body); | 1964 assembler->Bind(&loop_body); |
1962 assembler.GotoUnless( | 1965 assembler->GotoUnless( |
1963 assembler.UintPtrLessThan(index_var.value(), len_var.value()), | 1966 assembler->UintPtrLessThan(index_var.value(), len_var.value()), |
1964 &return_not_found); | 1967 &return_not_found); |
1965 | 1968 |
1966 Node* element_k = assembler.LoadFixedArrayElement( | 1969 Node* element_k = assembler->LoadFixedArrayElement( |
1967 elements, index_var.value(), 0, CodeStubAssembler::INTPTR_PARAMETERS); | 1970 elements, index_var.value(), 0, CodeStubAssembler::INTPTR_PARAMETERS); |
1968 assembler.GotoIf(assembler.TaggedIsSmi(element_k), &continue_loop); | 1971 assembler->GotoIf(assembler->TaggedIsSmi(element_k), &continue_loop); |
1969 | 1972 |
1970 Node* map_k = assembler.LoadMap(element_k); | 1973 Node* map_k = assembler->LoadMap(element_k); |
1971 assembler.BranchIfSimd128Equal(search_element, map, element_k, map_k, | 1974 assembler->BranchIfSimd128Equal(search_element, map, element_k, map_k, |
1972 &return_found, &continue_loop); | 1975 &return_found, &continue_loop); |
1973 | 1976 |
1974 assembler.Bind(&continue_loop); | 1977 assembler->Bind(&continue_loop); |
1975 index_var.Bind(assembler.IntPtrAdd(index_var.value(), intptr_one)); | 1978 index_var.Bind(assembler->IntPtrAdd(index_var.value(), intptr_one)); |
1976 assembler.Goto(&loop_body); | 1979 assembler->Goto(&loop_body); |
1977 } | 1980 } |
1978 } | 1981 } |
1979 | 1982 |
1980 assembler.Bind(&if_packed_doubles); | 1983 assembler->Bind(&if_packed_doubles); |
1981 { | 1984 { |
1982 Label not_nan_loop(&assembler, &index_var), search_notnan(&assembler); | 1985 Label not_nan_loop(assembler, &index_var), search_notnan(assembler); |
1983 Variable search_num(&assembler, MachineRepresentation::kFloat64); | 1986 Variable search_num(assembler, MachineRepresentation::kFloat64); |
1984 | 1987 |
1985 assembler.GotoUnless(assembler.TaggedIsSmi(search_element), &search_notnan); | 1988 assembler->GotoUnless(assembler->TaggedIsSmi(search_element), |
1986 search_num.Bind(assembler.SmiToFloat64(search_element)); | 1989 &search_notnan); |
1987 assembler.Goto(¬_nan_loop); | 1990 search_num.Bind(assembler->SmiToFloat64(search_element)); |
1988 | 1991 assembler->Goto(¬_nan_loop); |
1989 assembler.Bind(&search_notnan); | 1992 |
1990 assembler.GotoIf(assembler.WordNotEqual(assembler.LoadMap(search_element), | 1993 assembler->Bind(&search_notnan); |
1991 heap_number_map), | 1994 assembler->GotoIf(assembler->WordNotEqual( |
1992 &return_not_found); | 1995 assembler->LoadMap(search_element), heap_number_map), |
1993 | 1996 &return_not_found); |
1994 search_num.Bind(assembler.LoadHeapNumberValue(search_element)); | 1997 |
1995 | 1998 search_num.Bind(assembler->LoadHeapNumberValue(search_element)); |
1996 assembler.BranchIfFloat64IsNaN(search_num.value(), &return_not_found, | 1999 |
1997 ¬_nan_loop); | 2000 assembler->BranchIfFloat64IsNaN(search_num.value(), &return_not_found, |
| 2001 ¬_nan_loop); |
1998 | 2002 |
1999 // Search for HeapNumber | 2003 // Search for HeapNumber |
2000 assembler.Bind(¬_nan_loop); | 2004 assembler->Bind(¬_nan_loop); |
2001 { | 2005 { |
2002 Label continue_loop(&assembler); | 2006 Label continue_loop(assembler); |
2003 assembler.GotoUnless( | 2007 assembler->GotoUnless( |
2004 assembler.UintPtrLessThan(index_var.value(), len_var.value()), | 2008 assembler->UintPtrLessThan(index_var.value(), len_var.value()), |
2005 &return_not_found); | 2009 &return_not_found); |
2006 Node* element_k = assembler.LoadFixedDoubleArrayElement( | 2010 Node* element_k = assembler->LoadFixedDoubleArrayElement( |
2007 elements, index_var.value(), MachineType::Float64(), 0, | 2011 elements, index_var.value(), MachineType::Float64(), 0, |
2008 CodeStubAssembler::INTPTR_PARAMETERS); | 2012 CodeStubAssembler::INTPTR_PARAMETERS); |
2009 assembler.Branch(assembler.Float64Equal(element_k, search_num.value()), | 2013 assembler->Branch(assembler->Float64Equal(element_k, search_num.value()), |
2010 &return_found, &continue_loop); | 2014 &return_found, &continue_loop); |
2011 assembler.Bind(&continue_loop); | 2015 assembler->Bind(&continue_loop); |
2012 index_var.Bind(assembler.IntPtrAdd(index_var.value(), intptr_one)); | 2016 index_var.Bind(assembler->IntPtrAdd(index_var.value(), intptr_one)); |
2013 assembler.Goto(¬_nan_loop); | 2017 assembler->Goto(¬_nan_loop); |
2014 } | 2018 } |
2015 } | 2019 } |
2016 | 2020 |
2017 assembler.Bind(&if_holey_doubles); | 2021 assembler->Bind(&if_holey_doubles); |
2018 { | 2022 { |
2019 Label not_nan_loop(&assembler, &index_var), search_notnan(&assembler); | 2023 Label not_nan_loop(assembler, &index_var), search_notnan(assembler); |
2020 Variable search_num(&assembler, MachineRepresentation::kFloat64); | 2024 Variable search_num(assembler, MachineRepresentation::kFloat64); |
2021 | 2025 |
2022 assembler.GotoUnless(assembler.TaggedIsSmi(search_element), &search_notnan); | 2026 assembler->GotoUnless(assembler->TaggedIsSmi(search_element), |
2023 search_num.Bind(assembler.SmiToFloat64(search_element)); | 2027 &search_notnan); |
2024 assembler.Goto(¬_nan_loop); | 2028 search_num.Bind(assembler->SmiToFloat64(search_element)); |
2025 | 2029 assembler->Goto(¬_nan_loop); |
2026 assembler.Bind(&search_notnan); | 2030 |
2027 assembler.GotoIf(assembler.WordNotEqual(assembler.LoadMap(search_element), | 2031 assembler->Bind(&search_notnan); |
2028 heap_number_map), | 2032 assembler->GotoIf(assembler->WordNotEqual( |
2029 &return_not_found); | 2033 assembler->LoadMap(search_element), heap_number_map), |
2030 | 2034 &return_not_found); |
2031 search_num.Bind(assembler.LoadHeapNumberValue(search_element)); | 2035 |
2032 | 2036 search_num.Bind(assembler->LoadHeapNumberValue(search_element)); |
2033 assembler.BranchIfFloat64IsNaN(search_num.value(), &return_not_found, | 2037 |
2034 ¬_nan_loop); | 2038 assembler->BranchIfFloat64IsNaN(search_num.value(), &return_not_found, |
| 2039 ¬_nan_loop); |
2035 | 2040 |
2036 // Search for HeapNumber | 2041 // Search for HeapNumber |
2037 assembler.Bind(¬_nan_loop); | 2042 assembler->Bind(¬_nan_loop); |
2038 { | 2043 { |
2039 Label continue_loop(&assembler); | 2044 Label continue_loop(assembler); |
2040 assembler.GotoUnless( | 2045 assembler->GotoUnless( |
2041 assembler.UintPtrLessThan(index_var.value(), len_var.value()), | 2046 assembler->UintPtrLessThan(index_var.value(), len_var.value()), |
2042 &return_not_found); | 2047 &return_not_found); |
2043 | 2048 |
2044 // Load double value or continue if it contains a double hole. | 2049 // Load double value or continue if it contains a double hole. |
2045 Node* element_k = assembler.LoadFixedDoubleArrayElement( | 2050 Node* element_k = assembler->LoadFixedDoubleArrayElement( |
2046 elements, index_var.value(), MachineType::Float64(), 0, | 2051 elements, index_var.value(), MachineType::Float64(), 0, |
2047 CodeStubAssembler::INTPTR_PARAMETERS, &continue_loop); | 2052 CodeStubAssembler::INTPTR_PARAMETERS, &continue_loop); |
2048 | 2053 |
2049 assembler.Branch(assembler.Float64Equal(element_k, search_num.value()), | 2054 assembler->Branch(assembler->Float64Equal(element_k, search_num.value()), |
2050 &return_found, &continue_loop); | 2055 &return_found, &continue_loop); |
2051 assembler.Bind(&continue_loop); | 2056 assembler->Bind(&continue_loop); |
2052 index_var.Bind(assembler.IntPtrAdd(index_var.value(), intptr_one)); | 2057 index_var.Bind(assembler->IntPtrAdd(index_var.value(), intptr_one)); |
2053 assembler.Goto(¬_nan_loop); | 2058 assembler->Goto(¬_nan_loop); |
2054 } | 2059 } |
2055 } | 2060 } |
2056 | 2061 |
2057 assembler.Bind(&return_found); | 2062 assembler->Bind(&return_found); |
2058 assembler.Return(assembler.ChangeInt32ToTagged(index_var.value())); | 2063 assembler->Return(assembler->ChangeInt32ToTagged(index_var.value())); |
2059 | 2064 |
2060 assembler.Bind(&return_not_found); | 2065 assembler->Bind(&return_not_found); |
2061 assembler.Return(assembler.NumberConstant(-1)); | 2066 assembler->Return(assembler->NumberConstant(-1)); |
2062 | 2067 |
2063 assembler.Bind(&call_runtime); | 2068 assembler->Bind(&call_runtime); |
2064 assembler.Return(assembler.CallRuntime(Runtime::kArrayIndexOf, context, array, | 2069 assembler->Return(assembler->CallRuntime(Runtime::kArrayIndexOf, context, |
2065 search_element, start_from)); | 2070 array, search_element, start_from)); |
2066 } | 2071 } |
2067 | 2072 |
2068 namespace { | 2073 namespace { |
2069 | 2074 |
2070 template <IterationKind kIterationKind> | 2075 template <IterationKind kIterationKind> |
2071 void Generate_ArrayPrototypeIterationMethod( | 2076 void Generate_ArrayPrototypeIterationMethod(CodeStubAssembler* assembler) { |
2072 compiler::CodeAssemblerState* state) { | |
2073 typedef compiler::Node Node; | 2077 typedef compiler::Node Node; |
2074 typedef CodeStubAssembler::Label Label; | 2078 typedef CodeStubAssembler::Label Label; |
2075 typedef CodeStubAssembler::Variable Variable; | 2079 typedef CodeStubAssembler::Variable Variable; |
2076 CodeStubAssembler assembler(state); | 2080 |
2077 | 2081 Node* receiver = assembler->Parameter(0); |
2078 Node* receiver = assembler.Parameter(0); | 2082 Node* context = assembler->Parameter(3); |
2079 Node* context = assembler.Parameter(3); | 2083 |
2080 | 2084 Variable var_array(assembler, MachineRepresentation::kTagged); |
2081 Variable var_array(&assembler, MachineRepresentation::kTagged); | 2085 Variable var_map(assembler, MachineRepresentation::kTagged); |
2082 Variable var_map(&assembler, MachineRepresentation::kTagged); | 2086 Variable var_type(assembler, MachineRepresentation::kWord32); |
2083 Variable var_type(&assembler, MachineRepresentation::kWord32); | 2087 |
2084 | 2088 Label if_isnotobject(assembler, Label::kDeferred); |
2085 Label if_isnotobject(&assembler, Label::kDeferred); | 2089 Label create_array_iterator(assembler); |
2086 Label create_array_iterator(&assembler); | 2090 |
2087 | 2091 assembler->GotoIf(assembler->TaggedIsSmi(receiver), &if_isnotobject); |
2088 assembler.GotoIf(assembler.TaggedIsSmi(receiver), &if_isnotobject); | |
2089 var_array.Bind(receiver); | 2092 var_array.Bind(receiver); |
2090 var_map.Bind(assembler.LoadMap(receiver)); | 2093 var_map.Bind(assembler->LoadMap(receiver)); |
2091 var_type.Bind(assembler.LoadMapInstanceType(var_map.value())); | 2094 var_type.Bind(assembler->LoadMapInstanceType(var_map.value())); |
2092 assembler.Branch(assembler.IsJSReceiverInstanceType(var_type.value()), | 2095 assembler->Branch(assembler->IsJSReceiverInstanceType(var_type.value()), |
2093 &create_array_iterator, &if_isnotobject); | 2096 &create_array_iterator, &if_isnotobject); |
2094 | 2097 |
2095 assembler.Bind(&if_isnotobject); | 2098 assembler->Bind(&if_isnotobject); |
2096 { | 2099 { |
2097 Callable callable = CodeFactory::ToObject(assembler.isolate()); | 2100 Callable callable = CodeFactory::ToObject(assembler->isolate()); |
2098 Node* result = assembler.CallStub(callable, context, receiver); | 2101 Node* result = assembler->CallStub(callable, context, receiver); |
2099 var_array.Bind(result); | 2102 var_array.Bind(result); |
2100 var_map.Bind(assembler.LoadMap(result)); | 2103 var_map.Bind(assembler->LoadMap(result)); |
2101 var_type.Bind(assembler.LoadMapInstanceType(var_map.value())); | 2104 var_type.Bind(assembler->LoadMapInstanceType(var_map.value())); |
2102 assembler.Goto(&create_array_iterator); | 2105 assembler->Goto(&create_array_iterator); |
2103 } | 2106 } |
2104 | 2107 |
2105 assembler.Bind(&create_array_iterator); | 2108 assembler->Bind(&create_array_iterator); |
2106 assembler.Return( | 2109 assembler->Return(assembler->CreateArrayIterator( |
2107 assembler.CreateArrayIterator(var_array.value(), var_map.value(), | 2110 var_array.value(), var_map.value(), var_type.value(), context, |
2108 var_type.value(), context, kIterationKind)); | 2111 kIterationKind)); |
2109 } | 2112 } |
2110 | 2113 |
2111 } // namespace | 2114 } // namespace |
2112 | 2115 |
2113 void Builtins::Generate_ArrayPrototypeValues( | 2116 void Builtins::Generate_ArrayPrototypeValues(CodeStubAssembler* assembler) { |
2114 compiler::CodeAssemblerState* state) { | 2117 Generate_ArrayPrototypeIterationMethod<IterationKind::kValues>(assembler); |
2115 Generate_ArrayPrototypeIterationMethod<IterationKind::kValues>(state); | 2118 } |
2116 } | 2119 |
2117 | 2120 void Builtins::Generate_ArrayPrototypeEntries(CodeStubAssembler* assembler) { |
2118 void Builtins::Generate_ArrayPrototypeEntries( | 2121 Generate_ArrayPrototypeIterationMethod<IterationKind::kEntries>(assembler); |
2119 compiler::CodeAssemblerState* state) { | 2122 } |
2120 Generate_ArrayPrototypeIterationMethod<IterationKind::kEntries>(state); | 2123 |
2121 } | 2124 void Builtins::Generate_ArrayPrototypeKeys(CodeStubAssembler* assembler) { |
2122 | 2125 Generate_ArrayPrototypeIterationMethod<IterationKind::kKeys>(assembler); |
2123 void Builtins::Generate_ArrayPrototypeKeys( | |
2124 compiler::CodeAssemblerState* state) { | |
2125 Generate_ArrayPrototypeIterationMethod<IterationKind::kKeys>(state); | |
2126 } | 2126 } |
2127 | 2127 |
2128 void Builtins::Generate_ArrayIteratorPrototypeNext( | 2128 void Builtins::Generate_ArrayIteratorPrototypeNext( |
2129 compiler::CodeAssemblerState* state) { | 2129 CodeStubAssembler* assembler) { |
2130 typedef compiler::Node Node; | 2130 typedef compiler::Node Node; |
2131 typedef CodeStubAssembler::Label Label; | 2131 typedef CodeStubAssembler::Label Label; |
2132 typedef CodeStubAssembler::Variable Variable; | 2132 typedef CodeStubAssembler::Variable Variable; |
2133 CodeStubAssembler assembler(state); | 2133 |
2134 | 2134 Node* iterator = assembler->Parameter(0); |
2135 Node* iterator = assembler.Parameter(0); | 2135 Node* context = assembler->Parameter(3); |
2136 Node* context = assembler.Parameter(3); | 2136 |
2137 | 2137 Variable var_value(assembler, MachineRepresentation::kTagged); |
2138 Variable var_value(&assembler, MachineRepresentation::kTagged); | 2138 Variable var_done(assembler, MachineRepresentation::kTagged); |
2139 Variable var_done(&assembler, MachineRepresentation::kTagged); | |
2140 | 2139 |
2141 // Required, or else `throw_bad_receiver` fails a DCHECK due to these | 2140 // Required, or else `throw_bad_receiver` fails a DCHECK due to these |
2142 // variables not being bound along all paths, despite not being used. | 2141 // variables not being bound along all paths, despite not being used. |
2143 var_done.Bind(assembler.TrueConstant()); | 2142 var_done.Bind(assembler->TrueConstant()); |
2144 var_value.Bind(assembler.UndefinedConstant()); | 2143 var_value.Bind(assembler->UndefinedConstant()); |
2145 | 2144 |
2146 Label throw_bad_receiver(&assembler, Label::kDeferred); | 2145 Label throw_bad_receiver(assembler, Label::kDeferred); |
2147 Label set_done(&assembler); | 2146 Label set_done(assembler); |
2148 Label allocate_key_result(&assembler); | 2147 Label allocate_key_result(assembler); |
2149 Label allocate_entry_if_needed(&assembler); | 2148 Label allocate_entry_if_needed(assembler); |
2150 Label allocate_iterator_result(&assembler); | 2149 Label allocate_iterator_result(assembler); |
2151 Label generic_values(&assembler); | 2150 Label generic_values(assembler); |
2152 | 2151 |
2153 // If O does not have all of the internal slots of an Array Iterator Instance | 2152 // If O does not have all of the internal slots of an Array Iterator Instance |
2154 // (22.1.5.3), throw a TypeError exception | 2153 // (22.1.5.3), throw a TypeError exception |
2155 assembler.GotoIf(assembler.TaggedIsSmi(iterator), &throw_bad_receiver); | 2154 assembler->GotoIf(assembler->TaggedIsSmi(iterator), &throw_bad_receiver); |
2156 Node* instance_type = assembler.LoadInstanceType(iterator); | 2155 Node* instance_type = assembler->LoadInstanceType(iterator); |
2157 assembler.GotoIf( | 2156 assembler->GotoIf( |
2158 assembler.Uint32LessThan( | 2157 assembler->Uint32LessThan( |
2159 assembler.Int32Constant(LAST_ARRAY_ITERATOR_TYPE - | 2158 assembler->Int32Constant(LAST_ARRAY_ITERATOR_TYPE - |
2160 FIRST_ARRAY_ITERATOR_TYPE), | 2159 FIRST_ARRAY_ITERATOR_TYPE), |
2161 assembler.Int32Sub(instance_type, assembler.Int32Constant( | 2160 assembler->Int32Sub(instance_type, assembler->Int32Constant( |
2162 FIRST_ARRAY_ITERATOR_TYPE))), | 2161 FIRST_ARRAY_ITERATOR_TYPE))), |
2163 &throw_bad_receiver); | 2162 &throw_bad_receiver); |
2164 | 2163 |
2165 // Let a be O.[[IteratedObject]]. | 2164 // Let a be O.[[IteratedObject]]. |
2166 Node* array = assembler.LoadObjectField( | 2165 Node* array = assembler->LoadObjectField( |
2167 iterator, JSArrayIterator::kIteratedObjectOffset); | 2166 iterator, JSArrayIterator::kIteratedObjectOffset); |
2168 | 2167 |
2169 // Let index be O.[[ArrayIteratorNextIndex]]. | 2168 // Let index be O.[[ArrayIteratorNextIndex]]. |
2170 Node* index = | 2169 Node* index = |
2171 assembler.LoadObjectField(iterator, JSArrayIterator::kNextIndexOffset); | 2170 assembler->LoadObjectField(iterator, JSArrayIterator::kNextIndexOffset); |
2172 Node* orig_map = assembler.LoadObjectField( | 2171 Node* orig_map = assembler->LoadObjectField( |
2173 iterator, JSArrayIterator::kIteratedObjectMapOffset); | 2172 iterator, JSArrayIterator::kIteratedObjectMapOffset); |
2174 Node* array_map = assembler.LoadMap(array); | 2173 Node* array_map = assembler->LoadMap(array); |
2175 | 2174 |
2176 Label if_isfastarray(&assembler), if_isnotfastarray(&assembler); | 2175 Label if_isfastarray(assembler), if_isnotfastarray(assembler); |
2177 | 2176 |
2178 assembler.Branch(assembler.WordEqual(orig_map, array_map), &if_isfastarray, | 2177 assembler->Branch(assembler->WordEqual(orig_map, array_map), &if_isfastarray, |
2179 &if_isnotfastarray); | 2178 &if_isnotfastarray); |
2180 | 2179 |
2181 assembler.Bind(&if_isfastarray); | 2180 assembler->Bind(&if_isfastarray); |
2182 { | 2181 { |
2183 CSA_ASSERT(&assembler, | 2182 CSA_ASSERT(assembler, |
2184 assembler.Word32Equal(assembler.LoadMapInstanceType(array_map), | 2183 assembler->Word32Equal(assembler->LoadMapInstanceType(array_map), |
2185 assembler.Int32Constant(JS_ARRAY_TYPE))); | 2184 assembler->Int32Constant(JS_ARRAY_TYPE))); |
2186 | 2185 |
2187 Node* length = assembler.LoadObjectField(array, JSArray::kLengthOffset); | 2186 Node* length = assembler->LoadObjectField(array, JSArray::kLengthOffset); |
2188 | 2187 |
2189 CSA_ASSERT(&assembler, assembler.TaggedIsSmi(length)); | 2188 CSA_ASSERT(assembler, assembler->TaggedIsSmi(length)); |
2190 CSA_ASSERT(&assembler, assembler.TaggedIsSmi(index)); | 2189 CSA_ASSERT(assembler, assembler->TaggedIsSmi(index)); |
2191 | 2190 |
2192 assembler.GotoUnless(assembler.SmiBelow(index, length), &set_done); | 2191 assembler->GotoUnless(assembler->SmiBelow(index, length), &set_done); |
2193 | 2192 |
2194 Node* one = assembler.SmiConstant(Smi::FromInt(1)); | 2193 Node* one = assembler->SmiConstant(Smi::FromInt(1)); |
2195 assembler.StoreObjectFieldNoWriteBarrier( | 2194 assembler->StoreObjectFieldNoWriteBarrier( |
2196 iterator, JSArrayIterator::kNextIndexOffset, | 2195 iterator, JSArrayIterator::kNextIndexOffset, |
2197 assembler.IntPtrAdd(assembler.BitcastTaggedToWord(index), | 2196 assembler->IntPtrAdd(assembler->BitcastTaggedToWord(index), |
2198 assembler.BitcastTaggedToWord(one))); | 2197 assembler->BitcastTaggedToWord(one))); |
2199 | 2198 |
2200 var_done.Bind(assembler.FalseConstant()); | 2199 var_done.Bind(assembler->FalseConstant()); |
2201 Node* elements = assembler.LoadElements(array); | 2200 Node* elements = assembler->LoadElements(array); |
2202 | 2201 |
2203 static int32_t kInstanceType[] = { | 2202 static int32_t kInstanceType[] = { |
2204 JS_FAST_ARRAY_KEY_ITERATOR_TYPE, | 2203 JS_FAST_ARRAY_KEY_ITERATOR_TYPE, |
2205 JS_FAST_SMI_ARRAY_KEY_VALUE_ITERATOR_TYPE, | 2204 JS_FAST_SMI_ARRAY_KEY_VALUE_ITERATOR_TYPE, |
2206 JS_FAST_HOLEY_SMI_ARRAY_KEY_VALUE_ITERATOR_TYPE, | 2205 JS_FAST_HOLEY_SMI_ARRAY_KEY_VALUE_ITERATOR_TYPE, |
2207 JS_FAST_ARRAY_KEY_VALUE_ITERATOR_TYPE, | 2206 JS_FAST_ARRAY_KEY_VALUE_ITERATOR_TYPE, |
2208 JS_FAST_HOLEY_ARRAY_KEY_VALUE_ITERATOR_TYPE, | 2207 JS_FAST_HOLEY_ARRAY_KEY_VALUE_ITERATOR_TYPE, |
2209 JS_FAST_DOUBLE_ARRAY_KEY_VALUE_ITERATOR_TYPE, | 2208 JS_FAST_DOUBLE_ARRAY_KEY_VALUE_ITERATOR_TYPE, |
2210 JS_FAST_HOLEY_DOUBLE_ARRAY_KEY_VALUE_ITERATOR_TYPE, | 2209 JS_FAST_HOLEY_DOUBLE_ARRAY_KEY_VALUE_ITERATOR_TYPE, |
2211 JS_FAST_SMI_ARRAY_VALUE_ITERATOR_TYPE, | 2210 JS_FAST_SMI_ARRAY_VALUE_ITERATOR_TYPE, |
2212 JS_FAST_HOLEY_SMI_ARRAY_VALUE_ITERATOR_TYPE, | 2211 JS_FAST_HOLEY_SMI_ARRAY_VALUE_ITERATOR_TYPE, |
2213 JS_FAST_ARRAY_VALUE_ITERATOR_TYPE, | 2212 JS_FAST_ARRAY_VALUE_ITERATOR_TYPE, |
2214 JS_FAST_HOLEY_ARRAY_VALUE_ITERATOR_TYPE, | 2213 JS_FAST_HOLEY_ARRAY_VALUE_ITERATOR_TYPE, |
2215 JS_FAST_DOUBLE_ARRAY_VALUE_ITERATOR_TYPE, | 2214 JS_FAST_DOUBLE_ARRAY_VALUE_ITERATOR_TYPE, |
2216 JS_FAST_HOLEY_DOUBLE_ARRAY_VALUE_ITERATOR_TYPE, | 2215 JS_FAST_HOLEY_DOUBLE_ARRAY_VALUE_ITERATOR_TYPE, |
2217 }; | 2216 }; |
2218 | 2217 |
2219 Label packed_object_values(&assembler), holey_object_values(&assembler), | 2218 Label packed_object_values(assembler), holey_object_values(assembler), |
2220 packed_double_values(&assembler), holey_double_values(&assembler); | 2219 packed_double_values(assembler), holey_double_values(assembler); |
2221 Label* kInstanceTypeHandlers[] = { | 2220 Label* kInstanceTypeHandlers[] = { |
2222 &allocate_key_result, &packed_object_values, &holey_object_values, | 2221 &allocate_key_result, &packed_object_values, &holey_object_values, |
2223 &packed_object_values, &holey_object_values, &packed_double_values, | 2222 &packed_object_values, &holey_object_values, &packed_double_values, |
2224 &holey_double_values, &packed_object_values, &holey_object_values, | 2223 &holey_double_values, &packed_object_values, &holey_object_values, |
2225 &packed_object_values, &holey_object_values, &packed_double_values, | 2224 &packed_object_values, &holey_object_values, &packed_double_values, |
2226 &holey_double_values}; | 2225 &holey_double_values}; |
2227 | 2226 |
2228 assembler.Switch(instance_type, &throw_bad_receiver, kInstanceType, | 2227 assembler->Switch(instance_type, &throw_bad_receiver, kInstanceType, |
2229 kInstanceTypeHandlers, arraysize(kInstanceType)); | 2228 kInstanceTypeHandlers, arraysize(kInstanceType)); |
2230 | 2229 |
2231 assembler.Bind(&packed_object_values); | 2230 assembler->Bind(&packed_object_values); |
2232 { | 2231 { |
2233 var_value.Bind(assembler.LoadFixedArrayElement( | 2232 var_value.Bind(assembler->LoadFixedArrayElement( |
2234 elements, index, 0, CodeStubAssembler::SMI_PARAMETERS)); | 2233 elements, index, 0, CodeStubAssembler::SMI_PARAMETERS)); |
2235 assembler.Goto(&allocate_entry_if_needed); | 2234 assembler->Goto(&allocate_entry_if_needed); |
2236 } | 2235 } |
2237 | 2236 |
2238 assembler.Bind(&packed_double_values); | 2237 assembler->Bind(&packed_double_values); |
2239 { | 2238 { |
2240 Node* value = assembler.LoadFixedDoubleArrayElement( | 2239 Node* value = assembler->LoadFixedDoubleArrayElement( |
2241 elements, index, MachineType::Float64(), 0, | 2240 elements, index, MachineType::Float64(), 0, |
2242 CodeStubAssembler::SMI_PARAMETERS); | 2241 CodeStubAssembler::SMI_PARAMETERS); |
2243 var_value.Bind(assembler.AllocateHeapNumberWithValue(value)); | 2242 var_value.Bind(assembler->AllocateHeapNumberWithValue(value)); |
2244 assembler.Goto(&allocate_entry_if_needed); | 2243 assembler->Goto(&allocate_entry_if_needed); |
2245 } | 2244 } |
2246 | 2245 |
2247 assembler.Bind(&holey_object_values); | 2246 assembler->Bind(&holey_object_values); |
2248 { | 2247 { |
2249 // Check the array_protector cell, and take the slow path if it's invalid. | 2248 // Check the array_protector cell, and take the slow path if it's invalid. |
2250 Node* invalid = | 2249 Node* invalid = |
2251 assembler.SmiConstant(Smi::FromInt(Isolate::kProtectorInvalid)); | 2250 assembler->SmiConstant(Smi::FromInt(Isolate::kProtectorInvalid)); |
2252 Node* cell = assembler.LoadRoot(Heap::kArrayProtectorRootIndex); | 2251 Node* cell = assembler->LoadRoot(Heap::kArrayProtectorRootIndex); |
2253 Node* cell_value = | 2252 Node* cell_value = |
2254 assembler.LoadObjectField(cell, PropertyCell::kValueOffset); | 2253 assembler->LoadObjectField(cell, PropertyCell::kValueOffset); |
2255 assembler.GotoIf(assembler.WordEqual(cell_value, invalid), | 2254 assembler->GotoIf(assembler->WordEqual(cell_value, invalid), |
2256 &generic_values); | 2255 &generic_values); |
2257 | 2256 |
2258 var_value.Bind(assembler.UndefinedConstant()); | 2257 var_value.Bind(assembler->UndefinedConstant()); |
2259 Node* value = assembler.LoadFixedArrayElement( | 2258 Node* value = assembler->LoadFixedArrayElement( |
2260 elements, index, 0, CodeStubAssembler::SMI_PARAMETERS); | 2259 elements, index, 0, CodeStubAssembler::SMI_PARAMETERS); |
2261 assembler.GotoIf(assembler.WordEqual(value, assembler.TheHoleConstant()), | 2260 assembler->GotoIf( |
2262 &allocate_entry_if_needed); | 2261 assembler->WordEqual(value, assembler->TheHoleConstant()), |
| 2262 &allocate_entry_if_needed); |
2263 var_value.Bind(value); | 2263 var_value.Bind(value); |
2264 assembler.Goto(&allocate_entry_if_needed); | 2264 assembler->Goto(&allocate_entry_if_needed); |
2265 } | 2265 } |
2266 | 2266 |
2267 assembler.Bind(&holey_double_values); | 2267 assembler->Bind(&holey_double_values); |
2268 { | 2268 { |
2269 // Check the array_protector cell, and take the slow path if it's invalid. | 2269 // Check the array_protector cell, and take the slow path if it's invalid. |
2270 Node* invalid = | 2270 Node* invalid = |
2271 assembler.SmiConstant(Smi::FromInt(Isolate::kProtectorInvalid)); | 2271 assembler->SmiConstant(Smi::FromInt(Isolate::kProtectorInvalid)); |
2272 Node* cell = assembler.LoadRoot(Heap::kArrayProtectorRootIndex); | 2272 Node* cell = assembler->LoadRoot(Heap::kArrayProtectorRootIndex); |
2273 Node* cell_value = | 2273 Node* cell_value = |
2274 assembler.LoadObjectField(cell, PropertyCell::kValueOffset); | 2274 assembler->LoadObjectField(cell, PropertyCell::kValueOffset); |
2275 assembler.GotoIf(assembler.WordEqual(cell_value, invalid), | 2275 assembler->GotoIf(assembler->WordEqual(cell_value, invalid), |
2276 &generic_values); | 2276 &generic_values); |
2277 | 2277 |
2278 var_value.Bind(assembler.UndefinedConstant()); | 2278 var_value.Bind(assembler->UndefinedConstant()); |
2279 Node* value = assembler.LoadFixedDoubleArrayElement( | 2279 Node* value = assembler->LoadFixedDoubleArrayElement( |
2280 elements, index, MachineType::Float64(), 0, | 2280 elements, index, MachineType::Float64(), 0, |
2281 CodeStubAssembler::SMI_PARAMETERS, &allocate_entry_if_needed); | 2281 CodeStubAssembler::SMI_PARAMETERS, &allocate_entry_if_needed); |
2282 var_value.Bind(assembler.AllocateHeapNumberWithValue(value)); | 2282 var_value.Bind(assembler->AllocateHeapNumberWithValue(value)); |
2283 assembler.Goto(&allocate_entry_if_needed); | 2283 assembler->Goto(&allocate_entry_if_needed); |
2284 } | 2284 } |
2285 } | 2285 } |
2286 | 2286 |
2287 assembler.Bind(&if_isnotfastarray); | 2287 assembler->Bind(&if_isnotfastarray); |
2288 { | 2288 { |
2289 Label if_istypedarray(&assembler), if_isgeneric(&assembler); | 2289 Label if_istypedarray(assembler), if_isgeneric(assembler); |
2290 | 2290 |
2291 // If a is undefined, return CreateIterResultObject(undefined, true) | 2291 // If a is undefined, return CreateIterResultObject(undefined, true) |
2292 assembler.GotoIf(assembler.WordEqual(array, assembler.UndefinedConstant()), | 2292 assembler->GotoIf( |
2293 &allocate_iterator_result); | 2293 assembler->WordEqual(array, assembler->UndefinedConstant()), |
2294 | 2294 &allocate_iterator_result); |
2295 Node* array_type = assembler.LoadInstanceType(array); | 2295 |
2296 assembler.Branch( | 2296 Node* array_type = assembler->LoadInstanceType(array); |
2297 assembler.Word32Equal(array_type, | 2297 assembler->Branch( |
2298 assembler.Int32Constant(JS_TYPED_ARRAY_TYPE)), | 2298 assembler->Word32Equal(array_type, |
| 2299 assembler->Int32Constant(JS_TYPED_ARRAY_TYPE)), |
2299 &if_istypedarray, &if_isgeneric); | 2300 &if_istypedarray, &if_isgeneric); |
2300 | 2301 |
2301 assembler.Bind(&if_isgeneric); | 2302 assembler->Bind(&if_isgeneric); |
2302 { | 2303 { |
2303 Label if_wasfastarray(&assembler); | 2304 Label if_wasfastarray(assembler); |
2304 | 2305 |
2305 Node* length = nullptr; | 2306 Node* length = nullptr; |
2306 { | 2307 { |
2307 Variable var_length(&assembler, MachineRepresentation::kTagged); | 2308 Variable var_length(assembler, MachineRepresentation::kTagged); |
2308 Label if_isarray(&assembler), if_isnotarray(&assembler), | 2309 Label if_isarray(assembler), if_isnotarray(assembler), done(assembler); |
2309 done(&assembler); | 2310 assembler->Branch( |
2310 assembler.Branch( | 2311 assembler->Word32Equal(array_type, |
2311 assembler.Word32Equal(array_type, | 2312 assembler->Int32Constant(JS_ARRAY_TYPE)), |
2312 assembler.Int32Constant(JS_ARRAY_TYPE)), | |
2313 &if_isarray, &if_isnotarray); | 2313 &if_isarray, &if_isnotarray); |
2314 | 2314 |
2315 assembler.Bind(&if_isarray); | 2315 assembler->Bind(&if_isarray); |
2316 { | 2316 { |
2317 var_length.Bind( | 2317 var_length.Bind( |
2318 assembler.LoadObjectField(array, JSArray::kLengthOffset)); | 2318 assembler->LoadObjectField(array, JSArray::kLengthOffset)); |
2319 | 2319 |
2320 // Invalidate protector cell if needed | 2320 // Invalidate protector cell if needed |
2321 assembler.Branch( | 2321 assembler->Branch( |
2322 assembler.WordNotEqual(orig_map, assembler.UndefinedConstant()), | 2322 assembler->WordNotEqual(orig_map, assembler->UndefinedConstant()), |
2323 &if_wasfastarray, &done); | 2323 &if_wasfastarray, &done); |
2324 | 2324 |
2325 assembler.Bind(&if_wasfastarray); | 2325 assembler->Bind(&if_wasfastarray); |
2326 { | 2326 { |
2327 Label if_invalid(&assembler, Label::kDeferred); | 2327 Label if_invalid(assembler, Label::kDeferred); |
2328 // A fast array iterator transitioned to a slow iterator during | 2328 // A fast array iterator transitioned to a slow iterator during |
2329 // iteration. Invalidate fast_array_iteration_prtoector cell to | 2329 // iteration. Invalidate fast_array_iteration_prtoector cell to |
2330 // prevent potential deopt loops. | 2330 // prevent potential deopt loops. |
2331 assembler.StoreObjectFieldNoWriteBarrier( | 2331 assembler->StoreObjectFieldNoWriteBarrier( |
2332 iterator, JSArrayIterator::kIteratedObjectMapOffset, | 2332 iterator, JSArrayIterator::kIteratedObjectMapOffset, |
2333 assembler.UndefinedConstant()); | 2333 assembler->UndefinedConstant()); |
2334 assembler.GotoIf( | 2334 assembler->GotoIf( |
2335 assembler.Uint32LessThanOrEqual( | 2335 assembler->Uint32LessThanOrEqual( |
2336 instance_type, assembler.Int32Constant( | 2336 instance_type, assembler->Int32Constant( |
2337 JS_GENERIC_ARRAY_KEY_ITERATOR_TYPE)), | 2337 JS_GENERIC_ARRAY_KEY_ITERATOR_TYPE)), |
2338 &done); | 2338 &done); |
2339 | 2339 |
2340 Node* invalid = | 2340 Node* invalid = assembler->SmiConstant( |
2341 assembler.SmiConstant(Smi::FromInt(Isolate::kProtectorInvalid)); | 2341 Smi::FromInt(Isolate::kProtectorInvalid)); |
2342 Node* cell = | 2342 Node* cell = assembler->LoadRoot( |
2343 assembler.LoadRoot(Heap::kFastArrayIterationProtectorRootIndex); | 2343 Heap::kFastArrayIterationProtectorRootIndex); |
2344 assembler.StoreObjectFieldNoWriteBarrier(cell, Cell::kValueOffset, | 2344 assembler->StoreObjectFieldNoWriteBarrier(cell, Cell::kValueOffset, |
2345 invalid); | 2345 invalid); |
2346 assembler.Goto(&done); | 2346 assembler->Goto(&done); |
2347 } | 2347 } |
2348 } | 2348 } |
2349 | 2349 |
2350 assembler.Bind(&if_isnotarray); | 2350 assembler->Bind(&if_isnotarray); |
2351 { | 2351 { |
2352 Node* length_string = assembler.HeapConstant( | 2352 Node* length_string = assembler->HeapConstant( |
2353 assembler.isolate()->factory()->length_string()); | 2353 assembler->isolate()->factory()->length_string()); |
2354 Callable get_property = CodeFactory::GetProperty(assembler.isolate()); | 2354 Callable get_property = |
| 2355 CodeFactory::GetProperty(assembler->isolate()); |
2355 Node* length = | 2356 Node* length = |
2356 assembler.CallStub(get_property, context, array, length_string); | 2357 assembler->CallStub(get_property, context, array, length_string); |
2357 Callable to_length = CodeFactory::ToLength(assembler.isolate()); | 2358 Callable to_length = CodeFactory::ToLength(assembler->isolate()); |
2358 var_length.Bind(assembler.CallStub(to_length, context, length)); | 2359 var_length.Bind(assembler->CallStub(to_length, context, length)); |
2359 assembler.Goto(&done); | 2360 assembler->Goto(&done); |
2360 } | 2361 } |
2361 | 2362 |
2362 assembler.Bind(&done); | 2363 assembler->Bind(&done); |
2363 length = var_length.value(); | 2364 length = var_length.value(); |
2364 } | 2365 } |
2365 | 2366 |
2366 assembler.GotoUnlessNumberLessThan(index, length, &set_done); | 2367 assembler->GotoUnlessNumberLessThan(index, length, &set_done); |
2367 | 2368 |
2368 assembler.StoreObjectField(iterator, JSArrayIterator::kNextIndexOffset, | 2369 assembler->StoreObjectField(iterator, JSArrayIterator::kNextIndexOffset, |
2369 assembler.NumberInc(index)); | 2370 assembler->NumberInc(index)); |
2370 var_done.Bind(assembler.FalseConstant()); | 2371 var_done.Bind(assembler->FalseConstant()); |
2371 | 2372 |
2372 assembler.Branch( | 2373 assembler->Branch( |
2373 assembler.Uint32LessThanOrEqual( | 2374 assembler->Uint32LessThanOrEqual( |
2374 instance_type, | 2375 instance_type, |
2375 assembler.Int32Constant(JS_GENERIC_ARRAY_KEY_ITERATOR_TYPE)), | 2376 assembler->Int32Constant(JS_GENERIC_ARRAY_KEY_ITERATOR_TYPE)), |
2376 &allocate_key_result, &generic_values); | 2377 &allocate_key_result, &generic_values); |
2377 | 2378 |
2378 assembler.Bind(&generic_values); | 2379 assembler->Bind(&generic_values); |
2379 { | 2380 { |
2380 Callable get_property = CodeFactory::GetProperty(assembler.isolate()); | 2381 Callable get_property = CodeFactory::GetProperty(assembler->isolate()); |
2381 var_value.Bind(assembler.CallStub(get_property, context, array, index)); | 2382 var_value.Bind( |
2382 assembler.Goto(&allocate_entry_if_needed); | 2383 assembler->CallStub(get_property, context, array, index)); |
| 2384 assembler->Goto(&allocate_entry_if_needed); |
2383 } | 2385 } |
2384 } | 2386 } |
2385 | 2387 |
2386 assembler.Bind(&if_istypedarray); | 2388 assembler->Bind(&if_istypedarray); |
2387 { | 2389 { |
2388 Node* length = nullptr; | 2390 Node* length = nullptr; |
2389 { | 2391 { |
2390 Variable var_length(&assembler, MachineRepresentation::kTagged); | 2392 Variable var_length(assembler, MachineRepresentation::kTagged); |
2391 Label if_isdetached(&assembler, Label::kDeferred), | 2393 Label if_isdetached(assembler, Label::kDeferred), |
2392 if_isnotdetached(&assembler), done(&assembler); | 2394 if_isnotdetached(assembler), done(assembler); |
2393 | 2395 |
2394 Node* buffer = | 2396 Node* buffer = |
2395 assembler.LoadObjectField(array, JSTypedArray::kBufferOffset); | 2397 assembler->LoadObjectField(array, JSTypedArray::kBufferOffset); |
2396 assembler.Branch(assembler.IsDetachedBuffer(buffer), &if_isdetached, | 2398 assembler->Branch(assembler->IsDetachedBuffer(buffer), &if_isdetached, |
2397 &if_isnotdetached); | 2399 &if_isnotdetached); |
2398 | 2400 |
2399 assembler.Bind(&if_isnotdetached); | 2401 assembler->Bind(&if_isnotdetached); |
2400 { | 2402 { |
2401 var_length.Bind( | 2403 var_length.Bind( |
2402 assembler.LoadObjectField(array, JSTypedArray::kLengthOffset)); | 2404 assembler->LoadObjectField(array, JSTypedArray::kLengthOffset)); |
2403 assembler.Goto(&done); | 2405 assembler->Goto(&done); |
2404 } | 2406 } |
2405 | 2407 |
2406 assembler.Bind(&if_isdetached); | 2408 assembler->Bind(&if_isdetached); |
2407 { | 2409 { |
2408 // TODO(caitp): If IsDetached(buffer) is true, throw a TypeError, per | 2410 // TODO(caitp): If IsDetached(buffer) is true, throw a TypeError, per |
2409 // https://github.com/tc39/ecma262/issues/713 | 2411 // https://github.com/tc39/ecma262/issues/713 |
2410 var_length.Bind(assembler.SmiConstant(Smi::kZero)); | 2412 var_length.Bind(assembler->SmiConstant(Smi::kZero)); |
2411 assembler.Goto(&done); | 2413 assembler->Goto(&done); |
2412 } | 2414 } |
2413 | 2415 |
2414 assembler.Bind(&done); | 2416 assembler->Bind(&done); |
2415 length = var_length.value(); | 2417 length = var_length.value(); |
2416 } | 2418 } |
2417 CSA_ASSERT(&assembler, assembler.TaggedIsSmi(length)); | 2419 CSA_ASSERT(assembler, assembler->TaggedIsSmi(length)); |
2418 CSA_ASSERT(&assembler, assembler.TaggedIsSmi(index)); | 2420 CSA_ASSERT(assembler, assembler->TaggedIsSmi(index)); |
2419 | 2421 |
2420 assembler.GotoUnless(assembler.SmiBelow(index, length), &set_done); | 2422 assembler->GotoUnless(assembler->SmiBelow(index, length), &set_done); |
2421 | 2423 |
2422 Node* one = assembler.SmiConstant(Smi::FromInt(1)); | 2424 Node* one = assembler->SmiConstant(Smi::FromInt(1)); |
2423 assembler.StoreObjectFieldNoWriteBarrier( | 2425 assembler->StoreObjectFieldNoWriteBarrier( |
2424 iterator, JSArrayIterator::kNextIndexOffset, | 2426 iterator, JSArrayIterator::kNextIndexOffset, |
2425 assembler.IntPtrAdd(assembler.BitcastTaggedToWord(index), | 2427 assembler->IntPtrAdd(assembler->BitcastTaggedToWord(index), |
2426 assembler.BitcastTaggedToWord(one))); | 2428 assembler->BitcastTaggedToWord(one))); |
2427 var_done.Bind(assembler.FalseConstant()); | 2429 var_done.Bind(assembler->FalseConstant()); |
2428 | 2430 |
2429 Node* elements = assembler.LoadElements(array); | 2431 Node* elements = assembler->LoadElements(array); |
2430 Node* base_ptr = assembler.LoadObjectField( | 2432 Node* base_ptr = assembler->LoadObjectField( |
2431 elements, FixedTypedArrayBase::kBasePointerOffset); | 2433 elements, FixedTypedArrayBase::kBasePointerOffset); |
2432 Node* external_ptr = assembler.LoadObjectField( | 2434 Node* external_ptr = assembler->LoadObjectField( |
2433 elements, FixedTypedArrayBase::kExternalPointerOffset); | 2435 elements, FixedTypedArrayBase::kExternalPointerOffset); |
2434 Node* data_ptr = assembler.IntPtrAdd(base_ptr, external_ptr); | 2436 Node* data_ptr = assembler->IntPtrAdd(base_ptr, external_ptr); |
2435 | 2437 |
2436 static int32_t kInstanceType[] = { | 2438 static int32_t kInstanceType[] = { |
2437 JS_TYPED_ARRAY_KEY_ITERATOR_TYPE, | 2439 JS_TYPED_ARRAY_KEY_ITERATOR_TYPE, |
2438 JS_UINT8_ARRAY_KEY_VALUE_ITERATOR_TYPE, | 2440 JS_UINT8_ARRAY_KEY_VALUE_ITERATOR_TYPE, |
2439 JS_UINT8_CLAMPED_ARRAY_KEY_VALUE_ITERATOR_TYPE, | 2441 JS_UINT8_CLAMPED_ARRAY_KEY_VALUE_ITERATOR_TYPE, |
2440 JS_INT8_ARRAY_KEY_VALUE_ITERATOR_TYPE, | 2442 JS_INT8_ARRAY_KEY_VALUE_ITERATOR_TYPE, |
2441 JS_UINT16_ARRAY_KEY_VALUE_ITERATOR_TYPE, | 2443 JS_UINT16_ARRAY_KEY_VALUE_ITERATOR_TYPE, |
2442 JS_INT16_ARRAY_KEY_VALUE_ITERATOR_TYPE, | 2444 JS_INT16_ARRAY_KEY_VALUE_ITERATOR_TYPE, |
2443 JS_UINT32_ARRAY_KEY_VALUE_ITERATOR_TYPE, | 2445 JS_UINT32_ARRAY_KEY_VALUE_ITERATOR_TYPE, |
2444 JS_INT32_ARRAY_KEY_VALUE_ITERATOR_TYPE, | 2446 JS_INT32_ARRAY_KEY_VALUE_ITERATOR_TYPE, |
2445 JS_FLOAT32_ARRAY_KEY_VALUE_ITERATOR_TYPE, | 2447 JS_FLOAT32_ARRAY_KEY_VALUE_ITERATOR_TYPE, |
2446 JS_FLOAT64_ARRAY_KEY_VALUE_ITERATOR_TYPE, | 2448 JS_FLOAT64_ARRAY_KEY_VALUE_ITERATOR_TYPE, |
2447 JS_UINT8_ARRAY_VALUE_ITERATOR_TYPE, | 2449 JS_UINT8_ARRAY_VALUE_ITERATOR_TYPE, |
2448 JS_UINT8_CLAMPED_ARRAY_VALUE_ITERATOR_TYPE, | 2450 JS_UINT8_CLAMPED_ARRAY_VALUE_ITERATOR_TYPE, |
2449 JS_INT8_ARRAY_VALUE_ITERATOR_TYPE, | 2451 JS_INT8_ARRAY_VALUE_ITERATOR_TYPE, |
2450 JS_UINT16_ARRAY_VALUE_ITERATOR_TYPE, | 2452 JS_UINT16_ARRAY_VALUE_ITERATOR_TYPE, |
2451 JS_INT16_ARRAY_VALUE_ITERATOR_TYPE, | 2453 JS_INT16_ARRAY_VALUE_ITERATOR_TYPE, |
2452 JS_UINT32_ARRAY_VALUE_ITERATOR_TYPE, | 2454 JS_UINT32_ARRAY_VALUE_ITERATOR_TYPE, |
2453 JS_INT32_ARRAY_VALUE_ITERATOR_TYPE, | 2455 JS_INT32_ARRAY_VALUE_ITERATOR_TYPE, |
2454 JS_FLOAT32_ARRAY_VALUE_ITERATOR_TYPE, | 2456 JS_FLOAT32_ARRAY_VALUE_ITERATOR_TYPE, |
2455 JS_FLOAT64_ARRAY_VALUE_ITERATOR_TYPE, | 2457 JS_FLOAT64_ARRAY_VALUE_ITERATOR_TYPE, |
2456 }; | 2458 }; |
2457 | 2459 |
2458 Label uint8_values(&assembler), int8_values(&assembler), | 2460 Label uint8_values(assembler), int8_values(assembler), |
2459 uint16_values(&assembler), int16_values(&assembler), | 2461 uint16_values(assembler), int16_values(assembler), |
2460 uint32_values(&assembler), int32_values(&assembler), | 2462 uint32_values(assembler), int32_values(assembler), |
2461 float32_values(&assembler), float64_values(&assembler); | 2463 float32_values(assembler), float64_values(assembler); |
2462 Label* kInstanceTypeHandlers[] = { | 2464 Label* kInstanceTypeHandlers[] = { |
2463 &allocate_key_result, &uint8_values, &uint8_values, | 2465 &allocate_key_result, &uint8_values, &uint8_values, |
2464 &int8_values, &uint16_values, &int16_values, | 2466 &int8_values, &uint16_values, &int16_values, |
2465 &uint32_values, &int32_values, &float32_values, | 2467 &uint32_values, &int32_values, &float32_values, |
2466 &float64_values, &uint8_values, &uint8_values, | 2468 &float64_values, &uint8_values, &uint8_values, |
2467 &int8_values, &uint16_values, &int16_values, | 2469 &int8_values, &uint16_values, &int16_values, |
2468 &uint32_values, &int32_values, &float32_values, | 2470 &uint32_values, &int32_values, &float32_values, |
2469 &float64_values, | 2471 &float64_values, |
2470 }; | 2472 }; |
2471 | 2473 |
2472 var_done.Bind(assembler.FalseConstant()); | 2474 var_done.Bind(assembler->FalseConstant()); |
2473 assembler.Switch(instance_type, &throw_bad_receiver, kInstanceType, | 2475 assembler->Switch(instance_type, &throw_bad_receiver, kInstanceType, |
2474 kInstanceTypeHandlers, arraysize(kInstanceType)); | 2476 kInstanceTypeHandlers, arraysize(kInstanceType)); |
2475 | 2477 |
2476 assembler.Bind(&uint8_values); | 2478 assembler->Bind(&uint8_values); |
2477 { | 2479 { |
2478 Node* value_uint8 = assembler.LoadFixedTypedArrayElement( | 2480 Node* value_uint8 = assembler->LoadFixedTypedArrayElement( |
2479 data_ptr, index, UINT8_ELEMENTS, CodeStubAssembler::SMI_PARAMETERS); | 2481 data_ptr, index, UINT8_ELEMENTS, CodeStubAssembler::SMI_PARAMETERS); |
2480 var_value.Bind(assembler.SmiFromWord(value_uint8)); | 2482 var_value.Bind(assembler->SmiFromWord(value_uint8)); |
2481 assembler.Goto(&allocate_entry_if_needed); | 2483 assembler->Goto(&allocate_entry_if_needed); |
2482 } | 2484 } |
2483 | 2485 |
2484 assembler.Bind(&int8_values); | 2486 assembler->Bind(&int8_values); |
2485 { | 2487 { |
2486 Node* value_int8 = assembler.LoadFixedTypedArrayElement( | 2488 Node* value_int8 = assembler->LoadFixedTypedArrayElement( |
2487 data_ptr, index, INT8_ELEMENTS, CodeStubAssembler::SMI_PARAMETERS); | 2489 data_ptr, index, INT8_ELEMENTS, CodeStubAssembler::SMI_PARAMETERS); |
2488 var_value.Bind(assembler.SmiFromWord(value_int8)); | 2490 var_value.Bind(assembler->SmiFromWord(value_int8)); |
2489 assembler.Goto(&allocate_entry_if_needed); | 2491 assembler->Goto(&allocate_entry_if_needed); |
2490 } | 2492 } |
2491 | 2493 |
2492 assembler.Bind(&uint16_values); | 2494 assembler->Bind(&uint16_values); |
2493 { | 2495 { |
2494 Node* value_uint16 = assembler.LoadFixedTypedArrayElement( | 2496 Node* value_uint16 = assembler->LoadFixedTypedArrayElement( |
2495 data_ptr, index, UINT16_ELEMENTS, | 2497 data_ptr, index, UINT16_ELEMENTS, |
2496 CodeStubAssembler::SMI_PARAMETERS); | 2498 CodeStubAssembler::SMI_PARAMETERS); |
2497 var_value.Bind(assembler.SmiFromWord(value_uint16)); | 2499 var_value.Bind(assembler->SmiFromWord(value_uint16)); |
2498 assembler.Goto(&allocate_entry_if_needed); | 2500 assembler->Goto(&allocate_entry_if_needed); |
2499 } | 2501 } |
2500 | 2502 |
2501 assembler.Bind(&int16_values); | 2503 assembler->Bind(&int16_values); |
2502 { | 2504 { |
2503 Node* value_int16 = assembler.LoadFixedTypedArrayElement( | 2505 Node* value_int16 = assembler->LoadFixedTypedArrayElement( |
2504 data_ptr, index, INT16_ELEMENTS, CodeStubAssembler::SMI_PARAMETERS); | 2506 data_ptr, index, INT16_ELEMENTS, CodeStubAssembler::SMI_PARAMETERS); |
2505 var_value.Bind(assembler.SmiFromWord(value_int16)); | 2507 var_value.Bind(assembler->SmiFromWord(value_int16)); |
2506 assembler.Goto(&allocate_entry_if_needed); | 2508 assembler->Goto(&allocate_entry_if_needed); |
2507 } | 2509 } |
2508 | 2510 |
2509 assembler.Bind(&uint32_values); | 2511 assembler->Bind(&uint32_values); |
2510 { | 2512 { |
2511 Node* value_uint32 = assembler.LoadFixedTypedArrayElement( | 2513 Node* value_uint32 = assembler->LoadFixedTypedArrayElement( |
2512 data_ptr, index, UINT32_ELEMENTS, | 2514 data_ptr, index, UINT32_ELEMENTS, |
2513 CodeStubAssembler::SMI_PARAMETERS); | 2515 CodeStubAssembler::SMI_PARAMETERS); |
2514 var_value.Bind(assembler.ChangeUint32ToTagged(value_uint32)); | 2516 var_value.Bind(assembler->ChangeUint32ToTagged(value_uint32)); |
2515 assembler.Goto(&allocate_entry_if_needed); | 2517 assembler->Goto(&allocate_entry_if_needed); |
2516 } | 2518 } |
2517 assembler.Bind(&int32_values); | 2519 assembler->Bind(&int32_values); |
2518 { | 2520 { |
2519 Node* value_int32 = assembler.LoadFixedTypedArrayElement( | 2521 Node* value_int32 = assembler->LoadFixedTypedArrayElement( |
2520 data_ptr, index, INT32_ELEMENTS, CodeStubAssembler::SMI_PARAMETERS); | 2522 data_ptr, index, INT32_ELEMENTS, CodeStubAssembler::SMI_PARAMETERS); |
2521 var_value.Bind(assembler.ChangeInt32ToTagged(value_int32)); | 2523 var_value.Bind(assembler->ChangeInt32ToTagged(value_int32)); |
2522 assembler.Goto(&allocate_entry_if_needed); | 2524 assembler->Goto(&allocate_entry_if_needed); |
2523 } | 2525 } |
2524 assembler.Bind(&float32_values); | 2526 assembler->Bind(&float32_values); |
2525 { | 2527 { |
2526 Node* value_float32 = assembler.LoadFixedTypedArrayElement( | 2528 Node* value_float32 = assembler->LoadFixedTypedArrayElement( |
2527 data_ptr, index, FLOAT32_ELEMENTS, | 2529 data_ptr, index, FLOAT32_ELEMENTS, |
2528 CodeStubAssembler::SMI_PARAMETERS); | 2530 CodeStubAssembler::SMI_PARAMETERS); |
2529 var_value.Bind(assembler.AllocateHeapNumberWithValue( | 2531 var_value.Bind(assembler->AllocateHeapNumberWithValue( |
2530 assembler.ChangeFloat32ToFloat64(value_float32))); | 2532 assembler->ChangeFloat32ToFloat64(value_float32))); |
2531 assembler.Goto(&allocate_entry_if_needed); | 2533 assembler->Goto(&allocate_entry_if_needed); |
2532 } | 2534 } |
2533 assembler.Bind(&float64_values); | 2535 assembler->Bind(&float64_values); |
2534 { | 2536 { |
2535 Node* value_float64 = assembler.LoadFixedTypedArrayElement( | 2537 Node* value_float64 = assembler->LoadFixedTypedArrayElement( |
2536 data_ptr, index, FLOAT64_ELEMENTS, | 2538 data_ptr, index, FLOAT64_ELEMENTS, |
2537 CodeStubAssembler::SMI_PARAMETERS); | 2539 CodeStubAssembler::SMI_PARAMETERS); |
2538 var_value.Bind(assembler.AllocateHeapNumberWithValue(value_float64)); | 2540 var_value.Bind(assembler->AllocateHeapNumberWithValue(value_float64)); |
2539 assembler.Goto(&allocate_entry_if_needed); | 2541 assembler->Goto(&allocate_entry_if_needed); |
2540 } | 2542 } |
2541 } | 2543 } |
2542 } | 2544 } |
2543 | 2545 |
2544 assembler.Bind(&set_done); | 2546 assembler->Bind(&set_done); |
2545 { | 2547 { |
2546 assembler.StoreObjectFieldNoWriteBarrier( | 2548 assembler->StoreObjectFieldNoWriteBarrier( |
2547 iterator, JSArrayIterator::kIteratedObjectOffset, | 2549 iterator, JSArrayIterator::kIteratedObjectOffset, |
2548 assembler.UndefinedConstant()); | 2550 assembler->UndefinedConstant()); |
2549 assembler.Goto(&allocate_iterator_result); | 2551 assembler->Goto(&allocate_iterator_result); |
2550 } | 2552 } |
2551 | 2553 |
2552 assembler.Bind(&allocate_key_result); | 2554 assembler->Bind(&allocate_key_result); |
2553 { | 2555 { |
2554 var_value.Bind(index); | 2556 var_value.Bind(index); |
2555 var_done.Bind(assembler.FalseConstant()); | 2557 var_done.Bind(assembler->FalseConstant()); |
2556 assembler.Goto(&allocate_iterator_result); | 2558 assembler->Goto(&allocate_iterator_result); |
2557 } | 2559 } |
2558 | 2560 |
2559 assembler.Bind(&allocate_entry_if_needed); | 2561 assembler->Bind(&allocate_entry_if_needed); |
2560 { | 2562 { |
2561 assembler.GotoIf( | 2563 assembler->GotoIf( |
2562 assembler.Int32GreaterThan( | 2564 assembler->Int32GreaterThan( |
2563 instance_type, | 2565 instance_type, |
2564 assembler.Int32Constant(LAST_ARRAY_KEY_VALUE_ITERATOR_TYPE)), | 2566 assembler->Int32Constant(LAST_ARRAY_KEY_VALUE_ITERATOR_TYPE)), |
2565 &allocate_iterator_result); | 2567 &allocate_iterator_result); |
2566 | 2568 |
2567 Node* elements = | 2569 Node* elements = assembler->AllocateFixedArray(FAST_ELEMENTS, |
2568 assembler.AllocateFixedArray(FAST_ELEMENTS, assembler.Int32Constant(2)); | 2570 assembler->Int32Constant(2)); |
2569 assembler.StoreFixedArrayElement(elements, assembler.Int32Constant(0), | 2571 assembler->StoreFixedArrayElement(elements, assembler->Int32Constant(0), |
2570 index, SKIP_WRITE_BARRIER); | 2572 index, SKIP_WRITE_BARRIER); |
2571 assembler.StoreFixedArrayElement(elements, assembler.Int32Constant(1), | 2573 assembler->StoreFixedArrayElement(elements, assembler->Int32Constant(1), |
2572 var_value.value(), SKIP_WRITE_BARRIER); | 2574 var_value.value(), SKIP_WRITE_BARRIER); |
2573 | 2575 |
2574 Node* entry = assembler.Allocate(JSArray::kSize); | 2576 Node* entry = assembler->Allocate(JSArray::kSize); |
2575 Node* map = | 2577 Node* map = assembler->LoadContextElement( |
2576 assembler.LoadContextElement(assembler.LoadNativeContext(context), | 2578 assembler->LoadNativeContext(context), |
2577 Context::JS_ARRAY_FAST_ELEMENTS_MAP_INDEX); | 2579 Context::JS_ARRAY_FAST_ELEMENTS_MAP_INDEX); |
2578 | 2580 |
2579 assembler.StoreMapNoWriteBarrier(entry, map); | 2581 assembler->StoreMapNoWriteBarrier(entry, map); |
2580 assembler.StoreObjectFieldRoot(entry, JSArray::kPropertiesOffset, | 2582 assembler->StoreObjectFieldRoot(entry, JSArray::kPropertiesOffset, |
2581 Heap::kEmptyFixedArrayRootIndex); | 2583 Heap::kEmptyFixedArrayRootIndex); |
2582 assembler.StoreObjectFieldNoWriteBarrier(entry, JSArray::kElementsOffset, | 2584 assembler->StoreObjectFieldNoWriteBarrier(entry, JSArray::kElementsOffset, |
2583 elements); | 2585 elements); |
2584 assembler.StoreObjectFieldNoWriteBarrier( | 2586 assembler->StoreObjectFieldNoWriteBarrier( |
2585 entry, JSArray::kLengthOffset, assembler.SmiConstant(Smi::FromInt(2))); | 2587 entry, JSArray::kLengthOffset, assembler->SmiConstant(Smi::FromInt(2))); |
2586 | 2588 |
2587 var_value.Bind(entry); | 2589 var_value.Bind(entry); |
2588 assembler.Goto(&allocate_iterator_result); | 2590 assembler->Goto(&allocate_iterator_result); |
2589 } | 2591 } |
2590 | 2592 |
2591 assembler.Bind(&allocate_iterator_result); | 2593 assembler->Bind(&allocate_iterator_result); |
2592 { | 2594 { |
2593 Node* result = assembler.Allocate(JSIteratorResult::kSize); | 2595 Node* result = assembler->Allocate(JSIteratorResult::kSize); |
2594 Node* map = | 2596 Node* map = |
2595 assembler.LoadContextElement(assembler.LoadNativeContext(context), | 2597 assembler->LoadContextElement(assembler->LoadNativeContext(context), |
2596 Context::ITERATOR_RESULT_MAP_INDEX); | 2598 Context::ITERATOR_RESULT_MAP_INDEX); |
2597 assembler.StoreMapNoWriteBarrier(result, map); | 2599 assembler->StoreMapNoWriteBarrier(result, map); |
2598 assembler.StoreObjectFieldRoot(result, JSIteratorResult::kPropertiesOffset, | 2600 assembler->StoreObjectFieldRoot(result, JSIteratorResult::kPropertiesOffset, |
2599 Heap::kEmptyFixedArrayRootIndex); | 2601 Heap::kEmptyFixedArrayRootIndex); |
2600 assembler.StoreObjectFieldRoot(result, JSIteratorResult::kElementsOffset, | 2602 assembler->StoreObjectFieldRoot(result, JSIteratorResult::kElementsOffset, |
2601 Heap::kEmptyFixedArrayRootIndex); | 2603 Heap::kEmptyFixedArrayRootIndex); |
2602 assembler.StoreObjectFieldNoWriteBarrier( | 2604 assembler->StoreObjectFieldNoWriteBarrier( |
2603 result, JSIteratorResult::kValueOffset, var_value.value()); | 2605 result, JSIteratorResult::kValueOffset, var_value.value()); |
2604 assembler.StoreObjectFieldNoWriteBarrier( | 2606 assembler->StoreObjectFieldNoWriteBarrier( |
2605 result, JSIteratorResult::kDoneOffset, var_done.value()); | 2607 result, JSIteratorResult::kDoneOffset, var_done.value()); |
2606 assembler.Return(result); | 2608 assembler->Return(result); |
2607 } | 2609 } |
2608 | 2610 |
2609 assembler.Bind(&throw_bad_receiver); | 2611 assembler->Bind(&throw_bad_receiver); |
2610 { | 2612 { |
2611 // The {receiver} is not a valid JSArrayIterator. | 2613 // The {receiver} is not a valid JSArrayIterator. |
2612 Node* result = assembler.CallRuntime( | 2614 Node* result = assembler->CallRuntime( |
2613 Runtime::kThrowIncompatibleMethodReceiver, context, | 2615 Runtime::kThrowIncompatibleMethodReceiver, context, |
2614 assembler.HeapConstant(assembler.factory()->NewStringFromAsciiChecked( | 2616 assembler->HeapConstant(assembler->factory()->NewStringFromAsciiChecked( |
2615 "Array Iterator.prototype.next", TENURED)), | 2617 "Array Iterator.prototype.next", TENURED)), |
2616 iterator); | 2618 iterator); |
2617 assembler.Return(result); | 2619 assembler->Return(result); |
2618 } | 2620 } |
2619 } | 2621 } |
2620 | 2622 |
2621 } // namespace internal | 2623 } // namespace internal |
2622 } // namespace v8 | 2624 } // namespace v8 |
OLD | NEW |