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