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