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::kProtectorInvalid)); | 2251 assembler.SmiConstant(Smi::FromInt(Isolate::kProtectorInvalid)); |
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::kProtectorInvalid)); | 2271 assembler.SmiConstant(Smi::FromInt(Isolate::kProtectorInvalid)); |
2272 Node* cell = assembler->LoadRoot(Heap::kArrayProtectorRootIndex); | 2272 Node* cell = assembler.LoadRoot(Heap::kArrayProtectorRootIndex); |
2273 Node* cell_value = | 2273 Node* cell_value = |
2274 assembler->LoadObjectField(cell, PropertyCell::kValueOffset); | 2274 assembler.LoadObjectField(cell, PropertyCell::kValueOffset); |
2275 assembler->GotoIf(assembler->WordEqual(cell_value, invalid), | 2275 assembler.GotoIf(assembler.WordEqual(cell_value, invalid), |
2276 &generic_values); | 2276 &generic_values); |
2277 | 2277 |
2278 var_value.Bind(assembler->UndefinedConstant()); | 2278 var_value.Bind(assembler.UndefinedConstant()); |
2279 Node* value = assembler->LoadFixedDoubleArrayElement( | 2279 Node* value = assembler.LoadFixedDoubleArrayElement( |
2280 elements, index, MachineType::Float64(), 0, | 2280 elements, index, MachineType::Float64(), 0, |
2281 CodeStubAssembler::SMI_PARAMETERS, &allocate_entry_if_needed); | 2281 CodeStubAssembler::SMI_PARAMETERS, &allocate_entry_if_needed); |
2282 var_value.Bind(assembler->AllocateHeapNumberWithValue(value)); | 2282 var_value.Bind(assembler.AllocateHeapNumberWithValue(value)); |
2283 assembler->Goto(&allocate_entry_if_needed); | 2283 assembler.Goto(&allocate_entry_if_needed); |
2284 } | 2284 } |
2285 } | 2285 } |
2286 | 2286 |
2287 assembler->Bind(&if_isnotfastarray); | 2287 assembler.Bind(&if_isnotfastarray); |
2288 { | 2288 { |
2289 Label if_istypedarray(assembler), if_isgeneric(assembler); | 2289 Label if_istypedarray(&assembler), if_isgeneric(&assembler); |
2290 | 2290 |
2291 // If a is undefined, return CreateIterResultObject(undefined, true) | 2291 // If a is undefined, return CreateIterResultObject(undefined, true) |
2292 assembler->GotoIf( | 2292 assembler.GotoIf(assembler.WordEqual(array, assembler.UndefinedConstant()), |
2293 assembler->WordEqual(array, assembler->UndefinedConstant()), | 2293 &allocate_iterator_result); |
2294 &allocate_iterator_result); | 2294 |
2295 | 2295 Node* array_type = assembler.LoadInstanceType(array); |
2296 Node* array_type = assembler->LoadInstanceType(array); | 2296 assembler.Branch( |
2297 assembler->Branch( | 2297 assembler.Word32Equal(array_type, |
2298 assembler->Word32Equal(array_type, | 2298 assembler.Int32Constant(JS_TYPED_ARRAY_TYPE)), |
2299 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 Label if_wasfastarray(assembler); | 2303 Label if_wasfastarray(&assembler); |
2305 | 2304 |
2306 Node* length = nullptr; | 2305 Node* length = nullptr; |
2307 { | 2306 { |
2308 Variable var_length(assembler, MachineRepresentation::kTagged); | 2307 Variable var_length(&assembler, MachineRepresentation::kTagged); |
2309 Label if_isarray(assembler), if_isnotarray(assembler), done(assembler); | 2308 Label if_isarray(&assembler), if_isnotarray(&assembler), |
2310 assembler->Branch( | 2309 done(&assembler); |
2311 assembler->Word32Equal(array_type, | 2310 assembler.Branch( |
2312 assembler->Int32Constant(JS_ARRAY_TYPE)), | 2311 assembler.Word32Equal(array_type, |
| 2312 assembler.Int32Constant(JS_ARRAY_TYPE)), |
2313 &if_isarray, &if_isnotarray); | 2313 &if_isarray, &if_isnotarray); |
2314 | 2314 |
2315 assembler->Bind(&if_isarray); | 2315 assembler.Bind(&if_isarray); |
2316 { | 2316 { |
2317 var_length.Bind( | 2317 var_length.Bind( |
2318 assembler->LoadObjectField(array, JSArray::kLengthOffset)); | 2318 assembler.LoadObjectField(array, JSArray::kLengthOffset)); |
2319 | 2319 |
2320 // Invalidate protector cell if needed | 2320 // Invalidate protector cell if needed |
2321 assembler->Branch( | 2321 assembler.Branch( |
2322 assembler->WordNotEqual(orig_map, assembler->UndefinedConstant()), | 2322 assembler.WordNotEqual(orig_map, assembler.UndefinedConstant()), |
2323 &if_wasfastarray, &done); | 2323 &if_wasfastarray, &done); |
2324 | 2324 |
2325 assembler->Bind(&if_wasfastarray); | 2325 assembler.Bind(&if_wasfastarray); |
2326 { | 2326 { |
2327 Label if_invalid(assembler, Label::kDeferred); | 2327 Label if_invalid(&assembler, Label::kDeferred); |
2328 // A fast array iterator transitioned to a slow iterator during | 2328 // A fast array iterator transitioned to a slow iterator during |
2329 // iteration. Invalidate fast_array_iteration_prtoector cell to | 2329 // iteration. Invalidate fast_array_iteration_prtoector cell to |
2330 // prevent potential deopt loops. | 2330 // prevent potential deopt loops. |
2331 assembler->StoreObjectFieldNoWriteBarrier( | 2331 assembler.StoreObjectFieldNoWriteBarrier( |
2332 iterator, JSArrayIterator::kIteratedObjectMapOffset, | 2332 iterator, JSArrayIterator::kIteratedObjectMapOffset, |
2333 assembler->UndefinedConstant()); | 2333 assembler.UndefinedConstant()); |
2334 assembler->GotoIf( | 2334 assembler.GotoIf( |
2335 assembler->Uint32LessThanOrEqual( | 2335 assembler.Uint32LessThanOrEqual( |
2336 instance_type, assembler->Int32Constant( | 2336 instance_type, assembler.Int32Constant( |
2337 JS_GENERIC_ARRAY_KEY_ITERATOR_TYPE)), | 2337 JS_GENERIC_ARRAY_KEY_ITERATOR_TYPE)), |
2338 &done); | 2338 &done); |
2339 | 2339 |
2340 Node* invalid = assembler->SmiConstant( | 2340 Node* invalid = |
2341 Smi::FromInt(Isolate::kProtectorInvalid)); | 2341 assembler.SmiConstant(Smi::FromInt(Isolate::kProtectorInvalid)); |
2342 Node* cell = assembler->LoadRoot( | 2342 Node* cell = |
2343 Heap::kFastArrayIterationProtectorRootIndex); | 2343 assembler.LoadRoot(Heap::kFastArrayIterationProtectorRootIndex); |
2344 assembler->StoreObjectFieldNoWriteBarrier(cell, Cell::kValueOffset, | 2344 assembler.StoreObjectFieldNoWriteBarrier(cell, Cell::kValueOffset, |
2345 invalid); | 2345 invalid); |
2346 assembler->Goto(&done); | 2346 assembler.Goto(&done); |
2347 } | 2347 } |
2348 } | 2348 } |
2349 | 2349 |
2350 assembler->Bind(&if_isnotarray); | 2350 assembler.Bind(&if_isnotarray); |
2351 { | 2351 { |
2352 Node* length_string = assembler->HeapConstant( | 2352 Node* length_string = assembler.HeapConstant( |
2353 assembler->isolate()->factory()->length_string()); | 2353 assembler.isolate()->factory()->length_string()); |
2354 Callable get_property = | 2354 Callable get_property = CodeFactory::GetProperty(assembler.isolate()); |
2355 CodeFactory::GetProperty(assembler->isolate()); | |
2356 Node* length = | 2355 Node* length = |
2357 assembler->CallStub(get_property, context, array, length_string); | 2356 assembler.CallStub(get_property, context, array, length_string); |
2358 Callable to_length = CodeFactory::ToLength(assembler->isolate()); | 2357 Callable to_length = CodeFactory::ToLength(assembler.isolate()); |
2359 var_length.Bind(assembler->CallStub(to_length, context, length)); | 2358 var_length.Bind(assembler.CallStub(to_length, context, length)); |
2360 assembler->Goto(&done); | 2359 assembler.Goto(&done); |
2361 } | 2360 } |
2362 | 2361 |
2363 assembler->Bind(&done); | 2362 assembler.Bind(&done); |
2364 length = var_length.value(); | 2363 length = var_length.value(); |
2365 } | 2364 } |
2366 | 2365 |
2367 assembler->GotoUnlessNumberLessThan(index, length, &set_done); | 2366 assembler.GotoUnlessNumberLessThan(index, length, &set_done); |
2368 | 2367 |
2369 assembler->StoreObjectField(iterator, JSArrayIterator::kNextIndexOffset, | 2368 assembler.StoreObjectField(iterator, JSArrayIterator::kNextIndexOffset, |
2370 assembler->NumberInc(index)); | 2369 assembler.NumberInc(index)); |
2371 var_done.Bind(assembler->FalseConstant()); | 2370 var_done.Bind(assembler.FalseConstant()); |
2372 | 2371 |
2373 assembler->Branch( | 2372 assembler.Branch( |
2374 assembler->Uint32LessThanOrEqual( | 2373 assembler.Uint32LessThanOrEqual( |
2375 instance_type, | 2374 instance_type, |
2376 assembler->Int32Constant(JS_GENERIC_ARRAY_KEY_ITERATOR_TYPE)), | 2375 assembler.Int32Constant(JS_GENERIC_ARRAY_KEY_ITERATOR_TYPE)), |
2377 &allocate_key_result, &generic_values); | 2376 &allocate_key_result, &generic_values); |
2378 | 2377 |
2379 assembler->Bind(&generic_values); | 2378 assembler.Bind(&generic_values); |
2380 { | 2379 { |
2381 Callable get_property = CodeFactory::GetProperty(assembler->isolate()); | 2380 Callable get_property = CodeFactory::GetProperty(assembler.isolate()); |
2382 var_value.Bind( | 2381 var_value.Bind(assembler.CallStub(get_property, context, array, index)); |
2383 assembler->CallStub(get_property, context, array, index)); | 2382 assembler.Goto(&allocate_entry_if_needed); |
2384 assembler->Goto(&allocate_entry_if_needed); | |
2385 } | 2383 } |
2386 } | 2384 } |
2387 | 2385 |
2388 assembler->Bind(&if_istypedarray); | 2386 assembler.Bind(&if_istypedarray); |
2389 { | 2387 { |
2390 Node* length = nullptr; | 2388 Node* length = nullptr; |
2391 { | 2389 { |
2392 Variable var_length(assembler, MachineRepresentation::kTagged); | 2390 Variable var_length(&assembler, MachineRepresentation::kTagged); |
2393 Label if_isdetached(assembler, Label::kDeferred), | 2391 Label if_isdetached(&assembler, Label::kDeferred), |
2394 if_isnotdetached(assembler), done(assembler); | 2392 if_isnotdetached(&assembler), done(&assembler); |
2395 | 2393 |
2396 Node* buffer = | 2394 Node* buffer = |
2397 assembler->LoadObjectField(array, JSTypedArray::kBufferOffset); | 2395 assembler.LoadObjectField(array, JSTypedArray::kBufferOffset); |
2398 assembler->Branch(assembler->IsDetachedBuffer(buffer), &if_isdetached, | 2396 assembler.Branch(assembler.IsDetachedBuffer(buffer), &if_isdetached, |
2399 &if_isnotdetached); | 2397 &if_isnotdetached); |
2400 | 2398 |
2401 assembler->Bind(&if_isnotdetached); | 2399 assembler.Bind(&if_isnotdetached); |
2402 { | 2400 { |
2403 var_length.Bind( | 2401 var_length.Bind( |
2404 assembler->LoadObjectField(array, JSTypedArray::kLengthOffset)); | 2402 assembler.LoadObjectField(array, JSTypedArray::kLengthOffset)); |
2405 assembler->Goto(&done); | 2403 assembler.Goto(&done); |
2406 } | 2404 } |
2407 | 2405 |
2408 assembler->Bind(&if_isdetached); | 2406 assembler.Bind(&if_isdetached); |
2409 { | 2407 { |
2410 // TODO(caitp): If IsDetached(buffer) is true, throw a TypeError, per | 2408 // TODO(caitp): If IsDetached(buffer) is true, throw a TypeError, per |
2411 // https://github.com/tc39/ecma262/issues/713 | 2409 // https://github.com/tc39/ecma262/issues/713 |
2412 var_length.Bind(assembler->SmiConstant(Smi::kZero)); | 2410 var_length.Bind(assembler.SmiConstant(Smi::kZero)); |
2413 assembler->Goto(&done); | 2411 assembler.Goto(&done); |
2414 } | 2412 } |
2415 | 2413 |
2416 assembler->Bind(&done); | 2414 assembler.Bind(&done); |
2417 length = var_length.value(); | 2415 length = var_length.value(); |
2418 } | 2416 } |
2419 CSA_ASSERT(assembler, assembler->TaggedIsSmi(length)); | 2417 CSA_ASSERT(&assembler, assembler.TaggedIsSmi(length)); |
2420 CSA_ASSERT(assembler, assembler->TaggedIsSmi(index)); | 2418 CSA_ASSERT(&assembler, assembler.TaggedIsSmi(index)); |
2421 | 2419 |
2422 assembler->GotoUnless(assembler->SmiBelow(index, length), &set_done); | 2420 assembler.GotoUnless(assembler.SmiBelow(index, length), &set_done); |
2423 | 2421 |
2424 Node* one = assembler->SmiConstant(Smi::FromInt(1)); | 2422 Node* one = assembler.SmiConstant(Smi::FromInt(1)); |
2425 assembler->StoreObjectFieldNoWriteBarrier( | 2423 assembler.StoreObjectFieldNoWriteBarrier( |
2426 iterator, JSArrayIterator::kNextIndexOffset, | 2424 iterator, JSArrayIterator::kNextIndexOffset, |
2427 assembler->IntPtrAdd(assembler->BitcastTaggedToWord(index), | 2425 assembler.IntPtrAdd(assembler.BitcastTaggedToWord(index), |
2428 assembler->BitcastTaggedToWord(one))); | 2426 assembler.BitcastTaggedToWord(one))); |
2429 var_done.Bind(assembler->FalseConstant()); | 2427 var_done.Bind(assembler.FalseConstant()); |
2430 | 2428 |
2431 Node* elements = assembler->LoadElements(array); | 2429 Node* elements = assembler.LoadElements(array); |
2432 Node* base_ptr = assembler->LoadObjectField( | 2430 Node* base_ptr = assembler.LoadObjectField( |
2433 elements, FixedTypedArrayBase::kBasePointerOffset); | 2431 elements, FixedTypedArrayBase::kBasePointerOffset); |
2434 Node* external_ptr = assembler->LoadObjectField( | 2432 Node* external_ptr = assembler.LoadObjectField( |
2435 elements, FixedTypedArrayBase::kExternalPointerOffset); | 2433 elements, FixedTypedArrayBase::kExternalPointerOffset); |
2436 Node* data_ptr = assembler->IntPtrAdd(base_ptr, external_ptr); | 2434 Node* data_ptr = assembler.IntPtrAdd(base_ptr, external_ptr); |
2437 | 2435 |
2438 static int32_t kInstanceType[] = { | 2436 static int32_t kInstanceType[] = { |
2439 JS_TYPED_ARRAY_KEY_ITERATOR_TYPE, | 2437 JS_TYPED_ARRAY_KEY_ITERATOR_TYPE, |
2440 JS_UINT8_ARRAY_KEY_VALUE_ITERATOR_TYPE, | 2438 JS_UINT8_ARRAY_KEY_VALUE_ITERATOR_TYPE, |
2441 JS_UINT8_CLAMPED_ARRAY_KEY_VALUE_ITERATOR_TYPE, | 2439 JS_UINT8_CLAMPED_ARRAY_KEY_VALUE_ITERATOR_TYPE, |
2442 JS_INT8_ARRAY_KEY_VALUE_ITERATOR_TYPE, | 2440 JS_INT8_ARRAY_KEY_VALUE_ITERATOR_TYPE, |
2443 JS_UINT16_ARRAY_KEY_VALUE_ITERATOR_TYPE, | 2441 JS_UINT16_ARRAY_KEY_VALUE_ITERATOR_TYPE, |
2444 JS_INT16_ARRAY_KEY_VALUE_ITERATOR_TYPE, | 2442 JS_INT16_ARRAY_KEY_VALUE_ITERATOR_TYPE, |
2445 JS_UINT32_ARRAY_KEY_VALUE_ITERATOR_TYPE, | 2443 JS_UINT32_ARRAY_KEY_VALUE_ITERATOR_TYPE, |
2446 JS_INT32_ARRAY_KEY_VALUE_ITERATOR_TYPE, | 2444 JS_INT32_ARRAY_KEY_VALUE_ITERATOR_TYPE, |
2447 JS_FLOAT32_ARRAY_KEY_VALUE_ITERATOR_TYPE, | 2445 JS_FLOAT32_ARRAY_KEY_VALUE_ITERATOR_TYPE, |
2448 JS_FLOAT64_ARRAY_KEY_VALUE_ITERATOR_TYPE, | 2446 JS_FLOAT64_ARRAY_KEY_VALUE_ITERATOR_TYPE, |
2449 JS_UINT8_ARRAY_VALUE_ITERATOR_TYPE, | 2447 JS_UINT8_ARRAY_VALUE_ITERATOR_TYPE, |
2450 JS_UINT8_CLAMPED_ARRAY_VALUE_ITERATOR_TYPE, | 2448 JS_UINT8_CLAMPED_ARRAY_VALUE_ITERATOR_TYPE, |
2451 JS_INT8_ARRAY_VALUE_ITERATOR_TYPE, | 2449 JS_INT8_ARRAY_VALUE_ITERATOR_TYPE, |
2452 JS_UINT16_ARRAY_VALUE_ITERATOR_TYPE, | 2450 JS_UINT16_ARRAY_VALUE_ITERATOR_TYPE, |
2453 JS_INT16_ARRAY_VALUE_ITERATOR_TYPE, | 2451 JS_INT16_ARRAY_VALUE_ITERATOR_TYPE, |
2454 JS_UINT32_ARRAY_VALUE_ITERATOR_TYPE, | 2452 JS_UINT32_ARRAY_VALUE_ITERATOR_TYPE, |
2455 JS_INT32_ARRAY_VALUE_ITERATOR_TYPE, | 2453 JS_INT32_ARRAY_VALUE_ITERATOR_TYPE, |
2456 JS_FLOAT32_ARRAY_VALUE_ITERATOR_TYPE, | 2454 JS_FLOAT32_ARRAY_VALUE_ITERATOR_TYPE, |
2457 JS_FLOAT64_ARRAY_VALUE_ITERATOR_TYPE, | 2455 JS_FLOAT64_ARRAY_VALUE_ITERATOR_TYPE, |
2458 }; | 2456 }; |
2459 | 2457 |
2460 Label uint8_values(assembler), int8_values(assembler), | 2458 Label uint8_values(&assembler), int8_values(&assembler), |
2461 uint16_values(assembler), int16_values(assembler), | 2459 uint16_values(&assembler), int16_values(&assembler), |
2462 uint32_values(assembler), int32_values(assembler), | 2460 uint32_values(&assembler), int32_values(&assembler), |
2463 float32_values(assembler), float64_values(assembler); | 2461 float32_values(&assembler), float64_values(&assembler); |
2464 Label* kInstanceTypeHandlers[] = { | 2462 Label* kInstanceTypeHandlers[] = { |
2465 &allocate_key_result, &uint8_values, &uint8_values, | 2463 &allocate_key_result, &uint8_values, &uint8_values, |
2466 &int8_values, &uint16_values, &int16_values, | 2464 &int8_values, &uint16_values, &int16_values, |
2467 &uint32_values, &int32_values, &float32_values, | 2465 &uint32_values, &int32_values, &float32_values, |
2468 &float64_values, &uint8_values, &uint8_values, | 2466 &float64_values, &uint8_values, &uint8_values, |
2469 &int8_values, &uint16_values, &int16_values, | 2467 &int8_values, &uint16_values, &int16_values, |
2470 &uint32_values, &int32_values, &float32_values, | 2468 &uint32_values, &int32_values, &float32_values, |
2471 &float64_values, | 2469 &float64_values, |
2472 }; | 2470 }; |
2473 | 2471 |
2474 var_done.Bind(assembler->FalseConstant()); | 2472 var_done.Bind(assembler.FalseConstant()); |
2475 assembler->Switch(instance_type, &throw_bad_receiver, kInstanceType, | 2473 assembler.Switch(instance_type, &throw_bad_receiver, kInstanceType, |
2476 kInstanceTypeHandlers, arraysize(kInstanceType)); | 2474 kInstanceTypeHandlers, arraysize(kInstanceType)); |
2477 | 2475 |
2478 assembler->Bind(&uint8_values); | 2476 assembler.Bind(&uint8_values); |
2479 { | 2477 { |
2480 Node* value_uint8 = assembler->LoadFixedTypedArrayElement( | 2478 Node* value_uint8 = assembler.LoadFixedTypedArrayElement( |
2481 data_ptr, index, UINT8_ELEMENTS, CodeStubAssembler::SMI_PARAMETERS); | 2479 data_ptr, index, UINT8_ELEMENTS, CodeStubAssembler::SMI_PARAMETERS); |
2482 var_value.Bind(assembler->SmiFromWord(value_uint8)); | 2480 var_value.Bind(assembler.SmiFromWord(value_uint8)); |
2483 assembler->Goto(&allocate_entry_if_needed); | 2481 assembler.Goto(&allocate_entry_if_needed); |
2484 } | 2482 } |
2485 | 2483 |
2486 assembler->Bind(&int8_values); | 2484 assembler.Bind(&int8_values); |
2487 { | 2485 { |
2488 Node* value_int8 = assembler->LoadFixedTypedArrayElement( | 2486 Node* value_int8 = assembler.LoadFixedTypedArrayElement( |
2489 data_ptr, index, INT8_ELEMENTS, CodeStubAssembler::SMI_PARAMETERS); | 2487 data_ptr, index, INT8_ELEMENTS, CodeStubAssembler::SMI_PARAMETERS); |
2490 var_value.Bind(assembler->SmiFromWord(value_int8)); | 2488 var_value.Bind(assembler.SmiFromWord(value_int8)); |
2491 assembler->Goto(&allocate_entry_if_needed); | 2489 assembler.Goto(&allocate_entry_if_needed); |
2492 } | 2490 } |
2493 | 2491 |
2494 assembler->Bind(&uint16_values); | 2492 assembler.Bind(&uint16_values); |
2495 { | 2493 { |
2496 Node* value_uint16 = assembler->LoadFixedTypedArrayElement( | 2494 Node* value_uint16 = assembler.LoadFixedTypedArrayElement( |
2497 data_ptr, index, UINT16_ELEMENTS, | 2495 data_ptr, index, UINT16_ELEMENTS, |
2498 CodeStubAssembler::SMI_PARAMETERS); | 2496 CodeStubAssembler::SMI_PARAMETERS); |
2499 var_value.Bind(assembler->SmiFromWord(value_uint16)); | 2497 var_value.Bind(assembler.SmiFromWord(value_uint16)); |
2500 assembler->Goto(&allocate_entry_if_needed); | 2498 assembler.Goto(&allocate_entry_if_needed); |
2501 } | 2499 } |
2502 | 2500 |
2503 assembler->Bind(&int16_values); | 2501 assembler.Bind(&int16_values); |
2504 { | 2502 { |
2505 Node* value_int16 = assembler->LoadFixedTypedArrayElement( | 2503 Node* value_int16 = assembler.LoadFixedTypedArrayElement( |
2506 data_ptr, index, INT16_ELEMENTS, CodeStubAssembler::SMI_PARAMETERS); | 2504 data_ptr, index, INT16_ELEMENTS, CodeStubAssembler::SMI_PARAMETERS); |
2507 var_value.Bind(assembler->SmiFromWord(value_int16)); | 2505 var_value.Bind(assembler.SmiFromWord(value_int16)); |
2508 assembler->Goto(&allocate_entry_if_needed); | 2506 assembler.Goto(&allocate_entry_if_needed); |
2509 } | 2507 } |
2510 | 2508 |
2511 assembler->Bind(&uint32_values); | 2509 assembler.Bind(&uint32_values); |
2512 { | 2510 { |
2513 Node* value_uint32 = assembler->LoadFixedTypedArrayElement( | 2511 Node* value_uint32 = assembler.LoadFixedTypedArrayElement( |
2514 data_ptr, index, UINT32_ELEMENTS, | 2512 data_ptr, index, UINT32_ELEMENTS, |
2515 CodeStubAssembler::SMI_PARAMETERS); | 2513 CodeStubAssembler::SMI_PARAMETERS); |
2516 var_value.Bind(assembler->ChangeUint32ToTagged(value_uint32)); | 2514 var_value.Bind(assembler.ChangeUint32ToTagged(value_uint32)); |
2517 assembler->Goto(&allocate_entry_if_needed); | 2515 assembler.Goto(&allocate_entry_if_needed); |
2518 } | 2516 } |
2519 assembler->Bind(&int32_values); | 2517 assembler.Bind(&int32_values); |
2520 { | 2518 { |
2521 Node* value_int32 = assembler->LoadFixedTypedArrayElement( | 2519 Node* value_int32 = assembler.LoadFixedTypedArrayElement( |
2522 data_ptr, index, INT32_ELEMENTS, CodeStubAssembler::SMI_PARAMETERS); | 2520 data_ptr, index, INT32_ELEMENTS, CodeStubAssembler::SMI_PARAMETERS); |
2523 var_value.Bind(assembler->ChangeInt32ToTagged(value_int32)); | 2521 var_value.Bind(assembler.ChangeInt32ToTagged(value_int32)); |
2524 assembler->Goto(&allocate_entry_if_needed); | 2522 assembler.Goto(&allocate_entry_if_needed); |
2525 } | 2523 } |
2526 assembler->Bind(&float32_values); | 2524 assembler.Bind(&float32_values); |
2527 { | 2525 { |
2528 Node* value_float32 = assembler->LoadFixedTypedArrayElement( | 2526 Node* value_float32 = assembler.LoadFixedTypedArrayElement( |
2529 data_ptr, index, FLOAT32_ELEMENTS, | 2527 data_ptr, index, FLOAT32_ELEMENTS, |
2530 CodeStubAssembler::SMI_PARAMETERS); | 2528 CodeStubAssembler::SMI_PARAMETERS); |
2531 var_value.Bind(assembler->AllocateHeapNumberWithValue( | 2529 var_value.Bind(assembler.AllocateHeapNumberWithValue( |
2532 assembler->ChangeFloat32ToFloat64(value_float32))); | 2530 assembler.ChangeFloat32ToFloat64(value_float32))); |
2533 assembler->Goto(&allocate_entry_if_needed); | 2531 assembler.Goto(&allocate_entry_if_needed); |
2534 } | 2532 } |
2535 assembler->Bind(&float64_values); | 2533 assembler.Bind(&float64_values); |
2536 { | 2534 { |
2537 Node* value_float64 = assembler->LoadFixedTypedArrayElement( | 2535 Node* value_float64 = assembler.LoadFixedTypedArrayElement( |
2538 data_ptr, index, FLOAT64_ELEMENTS, | 2536 data_ptr, index, FLOAT64_ELEMENTS, |
2539 CodeStubAssembler::SMI_PARAMETERS); | 2537 CodeStubAssembler::SMI_PARAMETERS); |
2540 var_value.Bind(assembler->AllocateHeapNumberWithValue(value_float64)); | 2538 var_value.Bind(assembler.AllocateHeapNumberWithValue(value_float64)); |
2541 assembler->Goto(&allocate_entry_if_needed); | 2539 assembler.Goto(&allocate_entry_if_needed); |
2542 } | 2540 } |
2543 } | 2541 } |
2544 } | 2542 } |
2545 | 2543 |
2546 assembler->Bind(&set_done); | 2544 assembler.Bind(&set_done); |
2547 { | 2545 { |
2548 assembler->StoreObjectFieldNoWriteBarrier( | 2546 assembler.StoreObjectFieldNoWriteBarrier( |
2549 iterator, JSArrayIterator::kIteratedObjectOffset, | 2547 iterator, JSArrayIterator::kIteratedObjectOffset, |
2550 assembler->UndefinedConstant()); | 2548 assembler.UndefinedConstant()); |
2551 assembler->Goto(&allocate_iterator_result); | 2549 assembler.Goto(&allocate_iterator_result); |
2552 } | 2550 } |
2553 | 2551 |
2554 assembler->Bind(&allocate_key_result); | 2552 assembler.Bind(&allocate_key_result); |
2555 { | 2553 { |
2556 var_value.Bind(index); | 2554 var_value.Bind(index); |
2557 var_done.Bind(assembler->FalseConstant()); | 2555 var_done.Bind(assembler.FalseConstant()); |
2558 assembler->Goto(&allocate_iterator_result); | 2556 assembler.Goto(&allocate_iterator_result); |
2559 } | 2557 } |
2560 | 2558 |
2561 assembler->Bind(&allocate_entry_if_needed); | 2559 assembler.Bind(&allocate_entry_if_needed); |
2562 { | 2560 { |
2563 assembler->GotoIf( | 2561 assembler.GotoIf( |
2564 assembler->Int32GreaterThan( | 2562 assembler.Int32GreaterThan( |
2565 instance_type, | 2563 instance_type, |
2566 assembler->Int32Constant(LAST_ARRAY_KEY_VALUE_ITERATOR_TYPE)), | 2564 assembler.Int32Constant(LAST_ARRAY_KEY_VALUE_ITERATOR_TYPE)), |
2567 &allocate_iterator_result); | 2565 &allocate_iterator_result); |
2568 | 2566 |
2569 Node* elements = assembler->AllocateFixedArray(FAST_ELEMENTS, | 2567 Node* elements = |
2570 assembler->Int32Constant(2)); | 2568 assembler.AllocateFixedArray(FAST_ELEMENTS, assembler.Int32Constant(2)); |
2571 assembler->StoreFixedArrayElement(elements, assembler->Int32Constant(0), | 2569 assembler.StoreFixedArrayElement(elements, assembler.Int32Constant(0), |
2572 index, SKIP_WRITE_BARRIER); | 2570 index, SKIP_WRITE_BARRIER); |
2573 assembler->StoreFixedArrayElement(elements, assembler->Int32Constant(1), | 2571 assembler.StoreFixedArrayElement(elements, assembler.Int32Constant(1), |
2574 var_value.value(), SKIP_WRITE_BARRIER); | 2572 var_value.value(), SKIP_WRITE_BARRIER); |
2575 | 2573 |
2576 Node* entry = assembler->Allocate(JSArray::kSize); | 2574 Node* entry = assembler.Allocate(JSArray::kSize); |
2577 Node* map = assembler->LoadContextElement( | 2575 Node* map = |
2578 assembler->LoadNativeContext(context), | 2576 assembler.LoadContextElement(assembler.LoadNativeContext(context), |
2579 Context::JS_ARRAY_FAST_ELEMENTS_MAP_INDEX); | 2577 Context::JS_ARRAY_FAST_ELEMENTS_MAP_INDEX); |
2580 | 2578 |
2581 assembler->StoreMapNoWriteBarrier(entry, map); | 2579 assembler.StoreMapNoWriteBarrier(entry, map); |
2582 assembler->StoreObjectFieldRoot(entry, JSArray::kPropertiesOffset, | 2580 assembler.StoreObjectFieldRoot(entry, JSArray::kPropertiesOffset, |
2583 Heap::kEmptyFixedArrayRootIndex); | 2581 Heap::kEmptyFixedArrayRootIndex); |
2584 assembler->StoreObjectFieldNoWriteBarrier(entry, JSArray::kElementsOffset, | 2582 assembler.StoreObjectFieldNoWriteBarrier(entry, JSArray::kElementsOffset, |
2585 elements); | 2583 elements); |
2586 assembler->StoreObjectFieldNoWriteBarrier( | 2584 assembler.StoreObjectFieldNoWriteBarrier( |
2587 entry, JSArray::kLengthOffset, assembler->SmiConstant(Smi::FromInt(2))); | 2585 entry, JSArray::kLengthOffset, assembler.SmiConstant(Smi::FromInt(2))); |
2588 | 2586 |
2589 var_value.Bind(entry); | 2587 var_value.Bind(entry); |
2590 assembler->Goto(&allocate_iterator_result); | 2588 assembler.Goto(&allocate_iterator_result); |
2591 } | 2589 } |
2592 | 2590 |
2593 assembler->Bind(&allocate_iterator_result); | 2591 assembler.Bind(&allocate_iterator_result); |
2594 { | 2592 { |
2595 Node* result = assembler->Allocate(JSIteratorResult::kSize); | 2593 Node* result = assembler.Allocate(JSIteratorResult::kSize); |
2596 Node* map = | 2594 Node* map = |
2597 assembler->LoadContextElement(assembler->LoadNativeContext(context), | 2595 assembler.LoadContextElement(assembler.LoadNativeContext(context), |
2598 Context::ITERATOR_RESULT_MAP_INDEX); | 2596 Context::ITERATOR_RESULT_MAP_INDEX); |
2599 assembler->StoreMapNoWriteBarrier(result, map); | 2597 assembler.StoreMapNoWriteBarrier(result, map); |
2600 assembler->StoreObjectFieldRoot(result, JSIteratorResult::kPropertiesOffset, | 2598 assembler.StoreObjectFieldRoot(result, JSIteratorResult::kPropertiesOffset, |
2601 Heap::kEmptyFixedArrayRootIndex); | 2599 Heap::kEmptyFixedArrayRootIndex); |
2602 assembler->StoreObjectFieldRoot(result, JSIteratorResult::kElementsOffset, | 2600 assembler.StoreObjectFieldRoot(result, JSIteratorResult::kElementsOffset, |
2603 Heap::kEmptyFixedArrayRootIndex); | 2601 Heap::kEmptyFixedArrayRootIndex); |
2604 assembler->StoreObjectFieldNoWriteBarrier( | 2602 assembler.StoreObjectFieldNoWriteBarrier( |
2605 result, JSIteratorResult::kValueOffset, var_value.value()); | 2603 result, JSIteratorResult::kValueOffset, var_value.value()); |
2606 assembler->StoreObjectFieldNoWriteBarrier( | 2604 assembler.StoreObjectFieldNoWriteBarrier( |
2607 result, JSIteratorResult::kDoneOffset, var_done.value()); | 2605 result, JSIteratorResult::kDoneOffset, var_done.value()); |
2608 assembler->Return(result); | 2606 assembler.Return(result); |
2609 } | 2607 } |
2610 | 2608 |
2611 assembler->Bind(&throw_bad_receiver); | 2609 assembler.Bind(&throw_bad_receiver); |
2612 { | 2610 { |
2613 // The {receiver} is not a valid JSArrayIterator. | 2611 // The {receiver} is not a valid JSArrayIterator. |
2614 Node* result = assembler->CallRuntime( | 2612 Node* result = assembler.CallRuntime( |
2615 Runtime::kThrowIncompatibleMethodReceiver, context, | 2613 Runtime::kThrowIncompatibleMethodReceiver, context, |
2616 assembler->HeapConstant(assembler->factory()->NewStringFromAsciiChecked( | 2614 assembler.HeapConstant(assembler.factory()->NewStringFromAsciiChecked( |
2617 "Array Iterator.prototype.next", TENURED)), | 2615 "Array Iterator.prototype.next", TENURED)), |
2618 iterator); | 2616 iterator); |
2619 assembler->Return(result); | 2617 assembler.Return(result); |
2620 } | 2618 } |
2621 } | 2619 } |
2622 | 2620 |
2623 } // namespace internal | 2621 } // namespace internal |
2624 } // namespace v8 | 2622 } // namespace v8 |
OLD | NEW |