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-utils.h" | 5 #include "src/builtins/builtins-utils.h" |
6 #include "src/builtins/builtins.h" | 6 #include "src/builtins/builtins.h" |
7 | 7 |
8 #include "src/code-factory.h" | 8 #include "src/code-factory.h" |
9 #include "src/regexp/jsregexp.h" | 9 #include "src/regexp/jsregexp.h" |
10 #include "src/regexp/regexp-utils.h" | 10 #include "src/regexp/regexp-utils.h" |
(...skipping 208 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
219 | 219 |
220 void StoreLastIndex(CodeStubAssembler* a, Node* context, Node* regexp, | 220 void StoreLastIndex(CodeStubAssembler* a, Node* context, Node* regexp, |
221 Node* value, bool is_fastpath) { | 221 Node* value, bool is_fastpath) { |
222 if (is_fastpath) { | 222 if (is_fastpath) { |
223 FastStoreLastIndex(a, regexp, value); | 223 FastStoreLastIndex(a, regexp, value); |
224 } else { | 224 } else { |
225 SlowStoreLastIndex(a, context, regexp, value); | 225 SlowStoreLastIndex(a, context, regexp, value); |
226 } | 226 } |
227 } | 227 } |
228 | 228 |
229 Node* LoadMatchInfoField(CodeStubAssembler* a, Node* const match_info, | |
Igor Sheludko
2016/11/30 23:17:22
I think you should add CSA::LoadFieldArrayElement(
jgruber
2016/12/01 09:48:27
Will do this in a follow-up CL since it also affec
| |
230 const int index) { | |
231 const ParameterMode mode = CodeStubAssembler::INTPTR_PARAMETERS; | |
232 Node* const result = | |
233 a->LoadFixedArrayElement(match_info, a->IntPtrConstant(index), 0, mode); | |
234 return result; | |
235 } | |
236 | |
229 Node* ConstructNewResultFromMatchInfo(Isolate* isolate, CodeStubAssembler* a, | 237 Node* ConstructNewResultFromMatchInfo(Isolate* isolate, CodeStubAssembler* a, |
230 Node* context, Node* match_info, | 238 Node* context, Node* match_info, |
231 Node* string) { | 239 Node* string) { |
232 CLabel out(a); | 240 CLabel out(a); |
233 | 241 |
234 ParameterMode mode = CodeStubAssembler::INTPTR_PARAMETERS; | 242 ParameterMode mode = CodeStubAssembler::INTPTR_PARAMETERS; |
235 Node* const num_indices = a->SmiUntag(a->LoadFixedArrayElement( | 243 Node* const num_indices = a->SmiUntag(a->LoadFixedArrayElement( |
Igor Sheludko
2016/11/30 23:17:22
LoadMatchInfoField (or new LoadFixedArrayElement)
jgruber
2016/12/01 09:48:27
Done.
| |
236 match_info, a->IntPtrConstant(RegExpMatchInfo::kNumberOfCapturesIndex), 0, | 244 match_info, a->IntPtrConstant(RegExpMatchInfo::kNumberOfCapturesIndex), 0, |
237 mode)); | 245 mode)); |
238 Node* const num_results = a->SmiTag(a->WordShr(num_indices, 1)); | 246 Node* const num_results = a->SmiTag(a->WordShr(num_indices, 1)); |
239 Node* const start = a->LoadFixedArrayElement( | 247 Node* const start = a->LoadFixedArrayElement( |
240 match_info, a->IntPtrConstant(RegExpMatchInfo::kFirstCaptureIndex), 0, | 248 match_info, a->IntPtrConstant(RegExpMatchInfo::kFirstCaptureIndex), 0, |
241 mode); | 249 mode); |
242 Node* const end = a->LoadFixedArrayElement( | 250 Node* const end = a->LoadFixedArrayElement( |
243 match_info, a->IntPtrConstant(RegExpMatchInfo::kFirstCaptureIndex + 1), 0, | 251 match_info, a->IntPtrConstant(RegExpMatchInfo::kFirstCaptureIndex + 1), 0, |
244 mode); | 252 mode); |
245 | 253 |
(...skipping 157 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
403 | 411 |
404 StoreLastIndex(a, context, regexp, smi_zero, is_fastpath); | 412 StoreLastIndex(a, context, regexp, smi_zero, is_fastpath); |
405 a->Goto(if_didnotmatch); | 413 a->Goto(if_didnotmatch); |
406 } | 414 } |
407 | 415 |
408 a->Bind(&successful_match); | 416 a->Bind(&successful_match); |
409 { | 417 { |
410 a->GotoUnless(should_update_last_index, &out); | 418 a->GotoUnless(should_update_last_index, &out); |
411 | 419 |
412 // Update the new last index from {match_indices}. | 420 // Update the new last index from {match_indices}. |
413 Node* const new_lastindex = a->LoadFixedArrayElement( | 421 Node* const new_lastindex = a->LoadFixedArrayElement( |
Igor Sheludko
2016/11/30 23:17:22
Same here.
jgruber
2016/12/01 09:48:27
Done and at all other places as well.
| |
414 match_indices, | 422 match_indices, |
415 a->IntPtrConstant(RegExpMatchInfo::kFirstCaptureIndex + 1)); | 423 a->IntPtrConstant(RegExpMatchInfo::kFirstCaptureIndex + 1)); |
416 | 424 |
417 StoreLastIndex(a, context, regexp, new_lastindex, is_fastpath); | 425 StoreLastIndex(a, context, regexp, new_lastindex, is_fastpath); |
418 a->Goto(&out); | 426 a->Goto(&out); |
419 } | 427 } |
420 | 428 |
421 a->Bind(&out); | 429 a->Bind(&out); |
422 return var_result.value(); | 430 return var_result.value(); |
423 } | 431 } |
(...skipping 699 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1123 void Builtins::Generate_RegExpPrototypeTest(CodeAssemblerState* state) { | 1131 void Builtins::Generate_RegExpPrototypeTest(CodeAssemblerState* state) { |
1124 CodeStubAssembler a(state); | 1132 CodeStubAssembler a(state); |
1125 | 1133 |
1126 Isolate* const isolate = a.isolate(); | 1134 Isolate* const isolate = a.isolate(); |
1127 | 1135 |
1128 Node* const maybe_receiver = a.Parameter(0); | 1136 Node* const maybe_receiver = a.Parameter(0); |
1129 Node* const maybe_string = a.Parameter(1); | 1137 Node* const maybe_string = a.Parameter(1); |
1130 Node* const context = a.Parameter(4); | 1138 Node* const context = a.Parameter(4); |
1131 | 1139 |
1132 // Ensure {maybe_receiver} is a JSReceiver. | 1140 // Ensure {maybe_receiver} is a JSReceiver. |
1133 ThrowIfNotJSReceiver(&a, isolate, context, maybe_receiver, | 1141 Node* const map = ThrowIfNotJSReceiver( |
1134 MessageTemplate::kIncompatibleMethodReceiver, | 1142 &a, isolate, context, maybe_receiver, |
1135 "RegExp.prototype.test"); | 1143 MessageTemplate::kIncompatibleMethodReceiver, "RegExp.prototype.test"); |
1136 Node* const receiver = maybe_receiver; | 1144 Node* const receiver = maybe_receiver; |
1137 | 1145 |
1138 // Convert {maybe_string} to a String. | 1146 // Convert {maybe_string} to a String. |
1139 Node* const string = a.ToString(context, maybe_string); | 1147 Node* const string = a.ToString(context, maybe_string); |
1140 | 1148 |
1141 // Call exec. | 1149 CLabel fast_path(&a), slow_path(&a); |
1142 Node* const match_indices = RegExpExec(&a, context, receiver, string); | 1150 BranchIfFastPath(&a, context, map, &fast_path, &slow_path); |
1143 | 1151 |
1144 // Return true iff exec matched successfully. | 1152 a.Bind(&fast_path); |
1145 Node* const result = a.Select(a.WordEqual(match_indices, a.NullConstant()), | 1153 { |
1146 a.FalseConstant(), a.TrueConstant()); | 1154 CLabel if_didnotmatch(&a); |
1147 a.Return(result); | 1155 Generate_RegExpPrototypeExecBodyWithoutResult(&a, context, receiver, string, |
1156 &if_didnotmatch, true); | |
1157 a.Return(a.TrueConstant()); | |
1158 | |
1159 a.Bind(&if_didnotmatch); | |
1160 a.Return(a.FalseConstant()); | |
1161 } | |
1162 | |
1163 a.Bind(&slow_path); | |
1164 { | |
1165 // Call exec. | |
1166 Node* const match_indices = RegExpExec(&a, context, receiver, string); | |
1167 | |
1168 // Return true iff exec matched successfully. | |
1169 Node* const result = a.Select(a.WordEqual(match_indices, a.NullConstant()), | |
1170 a.FalseConstant(), a.TrueConstant()); | |
1171 a.Return(result); | |
1172 } | |
1148 } | 1173 } |
1149 | 1174 |
1150 namespace { | 1175 namespace { |
1151 | 1176 |
1152 Node* AdvanceStringIndex(CodeStubAssembler* a, Node* const string, | 1177 Node* AdvanceStringIndex(CodeStubAssembler* a, Node* const string, |
1153 Node* const index, Node* const is_unicode) { | 1178 Node* const index, Node* const is_unicode) { |
1154 CVariable var_result(a, MachineRepresentation::kTagged); | 1179 CVariable var_result(a, MachineRepresentation::kTagged); |
1155 | 1180 |
1156 // Default to last_index + 1. | 1181 // Default to last_index + 1. |
1157 Node* const index_plus_one = a->SmiAdd(index, a->SmiConstant(1)); | 1182 Node* const index_plus_one = a->SmiAdd(index, a->SmiConstant(1)); |
(...skipping 195 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1353 // Loop preparations. Within the loop, collect results from RegExpExec | 1378 // Loop preparations. Within the loop, collect results from RegExpExec |
1354 // and store match strings in the array. | 1379 // and store match strings in the array. |
1355 | 1380 |
1356 CVariable* vars[] = {array.var_array(), array.var_length(), | 1381 CVariable* vars[] = {array.var_array(), array.var_length(), |
1357 array.var_capacity()}; | 1382 array.var_capacity()}; |
1358 CLabel loop(a, 3, vars), out(a); | 1383 CLabel loop(a, 3, vars), out(a); |
1359 a->Goto(&loop); | 1384 a->Goto(&loop); |
1360 | 1385 |
1361 a->Bind(&loop); | 1386 a->Bind(&loop); |
1362 { | 1387 { |
1363 Node* const result = is_fastpath ? Generate_RegExpPrototypeExecBody( | 1388 CVariable var_match(a, MachineRepresentation::kTagged); |
1364 a, context, regexp, string, true) | |
1365 : RegExpExec(a, context, regexp, string); | |
1366 | 1389 |
1367 CLabel if_didmatch(a), if_didnotmatch(a); | 1390 CLabel if_didmatch(a), if_didnotmatch(a); |
1368 a->Branch(a->WordEqual(result, null), &if_didnotmatch, &if_didmatch); | 1391 if (is_fastpath) { |
1392 // On the fast path, grab the matching string from the raw match index | |
1393 // array. | |
1394 Node* const match_indices = | |
1395 Generate_RegExpPrototypeExecBodyWithoutResult( | |
1396 a, context, regexp, string, &if_didnotmatch, true); | |
1369 | 1397 |
1370 a->Bind(&if_didnotmatch); | 1398 Node* const match_from = LoadMatchInfoField( |
1371 { | 1399 a, match_indices, RegExpMatchInfo::kFirstCaptureIndex); |
1372 // Return null if there were no matches, otherwise just exit the loop. | 1400 Node* const match_to = LoadMatchInfoField( |
1373 a->GotoUnless(a->IntPtrEqual(array.length(), int_zero), &out); | 1401 a, match_indices, RegExpMatchInfo::kFirstCaptureIndex + 1); |
1374 a->Return(null); | |
1375 } | |
1376 | 1402 |
1377 a->Bind(&if_didmatch); | 1403 Node* match = a->SubString(context, string, match_from, match_to); |
1378 { | 1404 var_match.Bind(match); |
1379 Node* match = nullptr; | |
1380 if (is_fastpath) { | |
1381 // TODO(jgruber): We could optimize further here and in other | |
1382 // methods (e.g. @@search) by bypassing RegExp result construction. | |
1383 Node* const result_fixed_array = a->LoadElements(result); | |
1384 const ParameterMode mode = CodeStubAssembler::INTPTR_PARAMETERS; | |
1385 match = | |
1386 a->LoadFixedArrayElement(result_fixed_array, int_zero, 0, mode); | |
1387 | 1405 |
1388 // The match is guaranteed to be a string on the fast path. | 1406 a->Goto(&if_didmatch); |
1389 CSA_ASSERT(a, a->IsStringInstanceType(a->LoadInstanceType(match))); | 1407 } else { |
1390 } else { | 1408 DCHECK(!is_fastpath); |
1391 DCHECK(!is_fastpath); | 1409 Node* const result = RegExpExec(a, context, regexp, string); |
1392 | 1410 |
1393 CVariable var_match(a, MachineRepresentation::kTagged); | 1411 CLabel load_match(a); |
1394 CLabel fast_result(a), slow_result(a), match_loaded(a); | 1412 a->Branch(a->WordEqual(result, null), &if_didnotmatch, &load_match); |
1413 | |
1414 a->Bind(&load_match); | |
1415 { | |
1416 CLabel fast_result(a), slow_result(a); | |
1395 BranchIfFastRegExpResult(a, context, a->LoadMap(result), &fast_result, | 1417 BranchIfFastRegExpResult(a, context, a->LoadMap(result), &fast_result, |
1396 &slow_result); | 1418 &slow_result); |
1397 | 1419 |
1398 a->Bind(&fast_result); | 1420 a->Bind(&fast_result); |
1399 { | 1421 { |
1400 // TODO(jgruber): We could optimize further here and in other | |
1401 // methods (e.g. @@search) by bypassing RegExp result construction. | |
1402 Node* const result_fixed_array = a->LoadElements(result); | 1422 Node* const result_fixed_array = a->LoadElements(result); |
1403 const ParameterMode mode = CodeStubAssembler::INTPTR_PARAMETERS; | 1423 const ParameterMode mode = CodeStubAssembler::INTPTR_PARAMETERS; |
1404 Node* const match = | 1424 Node* const match = |
1405 a->LoadFixedArrayElement(result_fixed_array, int_zero, 0, mode); | 1425 a->LoadFixedArrayElement(result_fixed_array, int_zero, 0, mode); |
1406 | 1426 |
1407 // The match is guaranteed to be a string on the fast path. | 1427 // The match is guaranteed to be a string on the fast path. |
1408 CSA_ASSERT(a, a->IsStringInstanceType(a->LoadInstanceType(match))); | 1428 CSA_ASSERT(a, a->IsStringInstanceType(a->LoadInstanceType(match))); |
1409 | 1429 |
1410 var_match.Bind(match); | 1430 var_match.Bind(match); |
1411 a->Goto(&match_loaded); | 1431 a->Goto(&if_didmatch); |
1412 } | 1432 } |
1413 | 1433 |
1414 a->Bind(&slow_result); | 1434 a->Bind(&slow_result); |
1415 { | 1435 { |
1416 // TODO(ishell): Use GetElement stub once it's available. | 1436 // TODO(ishell): Use GetElement stub once it's available. |
1417 Node* const name = smi_zero; | 1437 Node* const name = smi_zero; |
1418 Callable getproperty_callable = CodeFactory::GetProperty(isolate); | 1438 Callable getproperty_callable = CodeFactory::GetProperty(isolate); |
1419 Node* const match = | 1439 Node* const match = |
1420 a->CallStub(getproperty_callable, context, result, name); | 1440 a->CallStub(getproperty_callable, context, result, name); |
1421 | 1441 |
1422 var_match.Bind(match); | 1442 var_match.Bind(a->ToString(context, match)); |
1423 a->Goto(&match_loaded); | 1443 a->Goto(&if_didmatch); |
1424 } | 1444 } |
1445 } | |
1446 } | |
1425 | 1447 |
1426 a->Bind(&match_loaded); | 1448 a->Bind(&if_didnotmatch); |
1427 match = a->ToString(context, var_match.value()); | 1449 { |
1428 } | 1450 // Return null if there were no matches, otherwise just exit the loop. |
1429 DCHECK(match != nullptr); | 1451 a->GotoUnless(a->IntPtrEqual(array.length(), int_zero), &out); |
1452 a->Return(null); | |
1453 } | |
1454 | |
1455 a->Bind(&if_didmatch); | |
1456 { | |
1457 Node* match = var_match.value(); | |
1430 | 1458 |
1431 // Store the match, growing the fixed array if needed. | 1459 // Store the match, growing the fixed array if needed. |
1432 | 1460 |
1433 array.Push(match); | 1461 array.Push(match); |
1434 | 1462 |
1435 // Advance last index if the match is the empty string. | 1463 // Advance last index if the match is the empty string. |
1436 | 1464 |
1437 Node* const match_length = a->LoadStringLength(match); | 1465 Node* const match_length = a->LoadStringLength(match); |
1438 a->GotoUnless(a->SmiEqual(match_length, smi_zero), &loop); | 1466 a->GotoUnless(a->SmiEqual(match_length, smi_zero), &loop); |
1439 | 1467 |
(...skipping 46 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1486 | 1514 |
1487 a.Bind(&fast_path); | 1515 a.Bind(&fast_path); |
1488 Generate_RegExpPrototypeMatchBody(&a, receiver, string, context, true); | 1516 Generate_RegExpPrototypeMatchBody(&a, receiver, string, context, true); |
1489 | 1517 |
1490 a.Bind(&slow_path); | 1518 a.Bind(&slow_path); |
1491 Generate_RegExpPrototypeMatchBody(&a, receiver, string, context, false); | 1519 Generate_RegExpPrototypeMatchBody(&a, receiver, string, context, false); |
1492 } | 1520 } |
1493 | 1521 |
1494 namespace { | 1522 namespace { |
1495 | 1523 |
1496 void Generate_RegExpPrototypeSearchBody(CodeStubAssembler* a, | 1524 void Generate_RegExpPrototypeSearchBodyFast(CodeStubAssembler* a, |
Igor Sheludko
2016/11/30 23:17:22
I think you can drop Generate_ prefixes from helpe
jgruber
2016/12/01 09:48:27
Done.
| |
1497 Node* const receiver, | 1525 Node* const receiver, |
1498 Node* const string, Node* const context, | 1526 Node* const string, |
1499 bool is_fastpath) { | 1527 Node* const context) { |
1528 // Grab the initial value of last index. | |
1529 Node* const previous_last_index = FastLoadLastIndex(a, receiver); | |
1530 | |
1531 // Ensure last index is 0. | |
1532 FastStoreLastIndex(a, receiver, a->SmiConstant(Smi::kZero)); | |
1533 | |
1534 // Call exec. | |
1535 CLabel if_didnotmatch(a); | |
1536 Node* const match_indices = Generate_RegExpPrototypeExecBodyWithoutResult( | |
1537 a, context, receiver, string, &if_didnotmatch, true); | |
1538 | |
1539 // Successful match. | |
1540 { | |
1541 // Reset last index. | |
1542 FastStoreLastIndex(a, receiver, previous_last_index); | |
1543 | |
1544 // Return the index of the match. | |
1545 Node* const index = LoadMatchInfoField(a, match_indices, | |
1546 RegExpMatchInfo::kFirstCaptureIndex); | |
1547 a->Return(index); | |
1548 } | |
1549 | |
1550 a->Bind(&if_didnotmatch); | |
1551 { | |
1552 // Reset last index and return -1. | |
1553 FastStoreLastIndex(a, receiver, previous_last_index); | |
1554 a->Return(a->SmiConstant(-1)); | |
1555 } | |
1556 } | |
1557 | |
1558 void Generate_RegExpPrototypeSearchBodySlow(CodeStubAssembler* a, | |
1559 Node* const receiver, | |
1560 Node* const string, | |
1561 Node* const context) { | |
1500 Isolate* const isolate = a->isolate(); | 1562 Isolate* const isolate = a->isolate(); |
1501 | 1563 |
1502 Node* const smi_zero = a->SmiConstant(Smi::kZero); | 1564 Node* const smi_zero = a->SmiConstant(Smi::kZero); |
1503 | 1565 |
1504 // Grab the initial value of last index. | 1566 // Grab the initial value of last index. |
1505 Node* const previous_last_index = | 1567 Node* const previous_last_index = SlowLoadLastIndex(a, context, receiver); |
1506 LoadLastIndex(a, context, receiver, is_fastpath); | |
1507 | 1568 |
1508 // Ensure last index is 0. | 1569 // Ensure last index is 0. |
1509 if (is_fastpath) { | 1570 { |
1510 FastStoreLastIndex(a, receiver, smi_zero); | |
1511 } else { | |
1512 CLabel next(a); | 1571 CLabel next(a); |
1513 a->GotoIf(a->SameValue(previous_last_index, smi_zero, context), &next); | 1572 a->GotoIf(a->SameValue(previous_last_index, smi_zero, context), &next); |
1514 | 1573 |
1515 SlowStoreLastIndex(a, context, receiver, smi_zero); | 1574 SlowStoreLastIndex(a, context, receiver, smi_zero); |
1516 a->Goto(&next); | 1575 a->Goto(&next); |
1517 a->Bind(&next); | 1576 a->Bind(&next); |
1518 } | 1577 } |
1519 | 1578 |
1520 // Call exec. | 1579 // Call exec. |
1521 Node* const match_indices = | 1580 Node* const exec_result = RegExpExec(a, context, receiver, string); |
1522 is_fastpath | |
1523 ? Generate_RegExpPrototypeExecBody(a, context, receiver, string, true) | |
1524 : RegExpExec(a, context, receiver, string); | |
1525 | 1581 |
1526 // Reset last index if necessary. | 1582 // Reset last index if necessary. |
1527 if (is_fastpath) { | 1583 { |
1528 FastStoreLastIndex(a, receiver, previous_last_index); | |
1529 } else { | |
1530 CLabel next(a); | 1584 CLabel next(a); |
1531 Node* const current_last_index = SlowLoadLastIndex(a, context, receiver); | 1585 Node* const current_last_index = SlowLoadLastIndex(a, context, receiver); |
1532 | 1586 |
1533 a->GotoIf(a->SameValue(current_last_index, previous_last_index, context), | 1587 a->GotoIf(a->SameValue(current_last_index, previous_last_index, context), |
1534 &next); | 1588 &next); |
1535 | 1589 |
1536 SlowStoreLastIndex(a, context, receiver, previous_last_index); | 1590 SlowStoreLastIndex(a, context, receiver, previous_last_index); |
1537 a->Goto(&next); | 1591 a->Goto(&next); |
1592 | |
1538 a->Bind(&next); | 1593 a->Bind(&next); |
1539 } | 1594 } |
1540 | 1595 |
1541 // Return -1 if no match was found. | 1596 // Return -1 if no match was found. |
1542 { | 1597 { |
1543 CLabel next(a); | 1598 CLabel next(a); |
1544 a->GotoUnless(a->WordEqual(match_indices, a->NullConstant()), &next); | 1599 a->GotoUnless(a->WordEqual(exec_result, a->NullConstant()), &next); |
1545 a->Return(a->SmiConstant(-1)); | 1600 a->Return(a->SmiConstant(-1)); |
1546 a->Bind(&next); | 1601 a->Bind(&next); |
1547 } | 1602 } |
1548 | 1603 |
1549 // Return the index of the match. | 1604 // Return the index of the match. |
1550 if (is_fastpath) { | 1605 { |
1551 Node* const index = a->LoadObjectField( | |
1552 match_indices, JSRegExpResult::kIndexOffset, MachineType::AnyTagged()); | |
1553 a->Return(index); | |
1554 } else { | |
1555 DCHECK(!is_fastpath); | |
1556 | |
1557 CLabel fast_result(a), slow_result(a, CLabel::kDeferred); | 1606 CLabel fast_result(a), slow_result(a, CLabel::kDeferred); |
1558 BranchIfFastRegExpResult(a, context, a->LoadMap(match_indices), | 1607 BranchIfFastRegExpResult(a, context, a->LoadMap(exec_result), &fast_result, |
1559 &fast_result, &slow_result); | 1608 &slow_result); |
1560 | 1609 |
1561 a->Bind(&fast_result); | 1610 a->Bind(&fast_result); |
1562 { | 1611 { |
1563 Node* const index = | 1612 Node* const index = a->LoadObjectField( |
1564 a->LoadObjectField(match_indices, JSRegExpResult::kIndexOffset, | 1613 exec_result, JSRegExpResult::kIndexOffset, MachineType::AnyTagged()); |
Igor Sheludko
2016/11/30 23:17:22
AnyTagged() is default, you can drop it for readab
jgruber
2016/12/01 09:48:27
Done.
| |
1565 MachineType::AnyTagged()); | |
1566 a->Return(index); | 1614 a->Return(index); |
1567 } | 1615 } |
1568 | 1616 |
1569 a->Bind(&slow_result); | 1617 a->Bind(&slow_result); |
1570 { | 1618 { |
1571 Node* const name = a->HeapConstant(isolate->factory()->index_string()); | 1619 Node* const name = a->HeapConstant(isolate->factory()->index_string()); |
1572 Callable getproperty_callable = CodeFactory::GetProperty(a->isolate()); | 1620 Callable getproperty_callable = CodeFactory::GetProperty(a->isolate()); |
1573 Node* const index = | 1621 Node* const index = |
1574 a->CallStub(getproperty_callable, context, match_indices, name); | 1622 a->CallStub(getproperty_callable, context, exec_result, name); |
1575 a->Return(index); | 1623 a->Return(index); |
1576 } | 1624 } |
1577 } | 1625 } |
1578 } | 1626 } |
1579 | 1627 |
1580 } // namespace | 1628 } // namespace |
1581 | 1629 |
1582 // ES#sec-regexp.prototype-@@search | 1630 // ES#sec-regexp.prototype-@@search |
1583 // RegExp.prototype [ @@search ] ( string ) | 1631 // RegExp.prototype [ @@search ] ( string ) |
1584 void Builtins::Generate_RegExpPrototypeSearch(CodeAssemblerState* state) { | 1632 void Builtins::Generate_RegExpPrototypeSearch(CodeAssemblerState* state) { |
(...skipping 12 matching lines...) Expand all Loading... | |
1597 "RegExp.prototype.@@search"); | 1645 "RegExp.prototype.@@search"); |
1598 Node* const receiver = maybe_receiver; | 1646 Node* const receiver = maybe_receiver; |
1599 | 1647 |
1600 // Convert {maybe_string} to a String. | 1648 // Convert {maybe_string} to a String. |
1601 Node* const string = a.ToString(context, maybe_string); | 1649 Node* const string = a.ToString(context, maybe_string); |
1602 | 1650 |
1603 CLabel fast_path(&a), slow_path(&a); | 1651 CLabel fast_path(&a), slow_path(&a); |
1604 BranchIfFastPath(&a, context, map, &fast_path, &slow_path); | 1652 BranchIfFastPath(&a, context, map, &fast_path, &slow_path); |
1605 | 1653 |
1606 a.Bind(&fast_path); | 1654 a.Bind(&fast_path); |
1607 Generate_RegExpPrototypeSearchBody(&a, receiver, string, context, true); | 1655 Generate_RegExpPrototypeSearchBodyFast(&a, receiver, string, context); |
1608 | 1656 |
1609 a.Bind(&slow_path); | 1657 a.Bind(&slow_path); |
1610 Generate_RegExpPrototypeSearchBody(&a, receiver, string, context, false); | 1658 Generate_RegExpPrototypeSearchBodySlow(&a, receiver, string, context); |
1611 } | 1659 } |
1612 | 1660 |
1613 namespace { | 1661 namespace { |
1614 | 1662 |
1615 // Generates the fast path for @@split. {regexp} is an unmodified JSRegExp, | 1663 // Generates the fast path for @@split. {regexp} is an unmodified JSRegExp, |
1616 // {string} is a String, and {limit} is a Smi. | 1664 // {string} is a String, and {limit} is a Smi. |
1617 void Generate_RegExpPrototypeSplitBody(CodeStubAssembler* a, Node* const regexp, | 1665 void Generate_RegExpPrototypeSplitBody(CodeStubAssembler* a, Node* const regexp, |
1618 Node* const string, Node* const limit, | 1666 Node* const string, Node* const limit, |
1619 Node* const context) { | 1667 Node* const context) { |
1620 Isolate* isolate = a->isolate(); | 1668 Isolate* isolate = a->isolate(); |
(...skipping 761 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
2382 a.Bind(&if_matched); | 2430 a.Bind(&if_matched); |
2383 { | 2431 { |
2384 Node* result = ConstructNewResultFromMatchInfo(isolate, &a, context, | 2432 Node* result = ConstructNewResultFromMatchInfo(isolate, &a, context, |
2385 match_indices, string); | 2433 match_indices, string); |
2386 a.Return(result); | 2434 a.Return(result); |
2387 } | 2435 } |
2388 } | 2436 } |
2389 | 2437 |
2390 } // namespace internal | 2438 } // namespace internal |
2391 } // namespace v8 | 2439 } // namespace v8 |
OLD | NEW |