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-regexp.h" | 5 #include "src/builtins/builtins-regexp.h" |
6 | 6 |
7 #include "src/builtins/builtins-constructor.h" | 7 #include "src/builtins/builtins-constructor.h" |
8 #include "src/builtins/builtins-utils.h" | 8 #include "src/builtins/builtins-utils.h" |
9 #include "src/builtins/builtins.h" | 9 #include "src/builtins/builtins.h" |
10 #include "src/code-factory.h" | 10 #include "src/code-factory.h" |
(...skipping 322 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
333 match_indices, RegExpMatchInfo::kFirstCaptureIndex + 1); | 333 match_indices, RegExpMatchInfo::kFirstCaptureIndex + 1); |
334 | 334 |
335 StoreLastIndex(context, regexp, new_lastindex, is_fastpath); | 335 StoreLastIndex(context, regexp, new_lastindex, is_fastpath); |
336 Goto(&out); | 336 Goto(&out); |
337 } | 337 } |
338 | 338 |
339 Bind(&out); | 339 Bind(&out); |
340 return var_result.value(); | 340 return var_result.value(); |
341 } | 341 } |
342 | 342 |
343 // Wrapper around RegExpPrototypeExecBody to reduce code duplication. | |
344 TF_BUILTIN(RegExpExecInternalFast, RegExpBuiltinsAssembler) { | |
345 typedef RegExpExecInternalDescriptor Descriptor; | |
346 | |
347 Node* const regexp = Parameter(Descriptor::kReceiver); | |
348 Node* const string = Parameter(Descriptor::kString); | |
349 Node* const context = Parameter(Descriptor::kContext); | |
350 | |
351 CSA_ASSERT(this, HasInstanceType(regexp, JS_REGEXP_TYPE)); | |
352 CSA_ASSERT(this, IsString(string)); | |
353 | |
354 Return(RegExpPrototypeExecBody(context, regexp, string, true)); | |
355 } | |
356 | |
357 // Wrapper around RegExpPrototypeExecBody to reduce code duplication. | |
358 TF_BUILTIN(RegExpExecInternalSlow, RegExpBuiltinsAssembler) { | |
359 typedef RegExpExecInternalDescriptor Descriptor; | |
360 | |
361 Node* const regexp = Parameter(Descriptor::kReceiver); | |
362 Node* const string = Parameter(Descriptor::kString); | |
363 Node* const context = Parameter(Descriptor::kContext); | |
364 | |
365 CSA_ASSERT(this, IsString(string)); | |
366 | |
367 Return(RegExpPrototypeExecBody(context, regexp, string, false)); | |
368 } | |
369 | |
370 // ES#sec-regexp.prototype.exec | 343 // ES#sec-regexp.prototype.exec |
371 // RegExp.prototype.exec ( string ) | 344 // RegExp.prototype.exec ( string ) |
372 Node* RegExpBuiltinsAssembler::RegExpPrototypeExecBody(Node* const context, | 345 Node* RegExpBuiltinsAssembler::RegExpPrototypeExecBody(Node* const context, |
373 Node* const regexp, | 346 Node* const regexp, |
374 Node* const string, | 347 Node* const string, |
375 const bool is_fastpath) { | 348 const bool is_fastpath) { |
376 Node* const null = NullConstant(); | 349 Node* const null = NullConstant(); |
377 | 350 |
378 Variable var_result(this, MachineRepresentation::kTagged); | 351 Variable var_result(this, MachineRepresentation::kTagged); |
379 | 352 |
(...skipping 138 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
518 | 491 |
519 // Convert {maybe_string} to a String. | 492 // Convert {maybe_string} to a String. |
520 Node* const string = ToString(context, maybe_string); | 493 Node* const string = ToString(context, maybe_string); |
521 | 494 |
522 Label if_isfastpath(this), if_isslowpath(this); | 495 Label if_isfastpath(this), if_isslowpath(this); |
523 Branch(IsInitialRegExpMap(context, regexp_map), &if_isfastpath, | 496 Branch(IsInitialRegExpMap(context, regexp_map), &if_isfastpath, |
524 &if_isslowpath); | 497 &if_isslowpath); |
525 | 498 |
526 Bind(&if_isfastpath); | 499 Bind(&if_isfastpath); |
527 { | 500 { |
528 Callable exec_callable = CodeFactory::RegExpExecInternal(isolate(), true); | 501 Node* const result = |
529 Return(CallStub(exec_callable, context, receiver, string)); | 502 RegExpPrototypeExecBody(context, receiver, string, true); |
| 503 Return(result); |
530 } | 504 } |
531 | 505 |
532 Bind(&if_isslowpath); | 506 Bind(&if_isslowpath); |
533 { | 507 { |
534 Callable exec_callable = CodeFactory::RegExpExecInternal(isolate(), false); | 508 Node* const result = |
535 Return(CallStub(exec_callable, context, receiver, string)); | 509 RegExpPrototypeExecBody(context, receiver, string, false); |
| 510 Return(result); |
536 } | 511 } |
537 } | 512 } |
538 | 513 |
539 Node* RegExpBuiltinsAssembler::FlagsGetter(Node* const context, | 514 Node* RegExpBuiltinsAssembler::FlagsGetter(Node* const context, |
540 Node* const regexp, | 515 Node* const regexp, |
541 bool is_fastpath) { | 516 bool is_fastpath) { |
542 Isolate* isolate = this->isolate(); | 517 Isolate* isolate = this->isolate(); |
543 | 518 |
544 Node* const int_zero = IntPtrConstant(0); | 519 Node* const int_zero = IntPtrConstant(0); |
545 Node* const int_one = IntPtrConstant(1); | 520 Node* const int_one = IntPtrConstant(1); |
(...skipping 696 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1242 Node* const null = NullConstant(); | 1217 Node* const null = NullConstant(); |
1243 | 1218 |
1244 Variable var_result(this, MachineRepresentation::kTagged); | 1219 Variable var_result(this, MachineRepresentation::kTagged); |
1245 Label out(this), if_isfastpath(this), if_isslowpath(this); | 1220 Label out(this), if_isfastpath(this), if_isslowpath(this); |
1246 | 1221 |
1247 Node* const map = LoadMap(regexp); | 1222 Node* const map = LoadMap(regexp); |
1248 BranchIfFastRegExp(context, map, &if_isfastpath, &if_isslowpath); | 1223 BranchIfFastRegExp(context, map, &if_isfastpath, &if_isslowpath); |
1249 | 1224 |
1250 Bind(&if_isfastpath); | 1225 Bind(&if_isfastpath); |
1251 { | 1226 { |
1252 Callable exec_callable = CodeFactory::RegExpExecInternal(isolate, true); | 1227 Node* const result = RegExpPrototypeExecBody(context, regexp, string, true); |
1253 Node* const result = CallStub(exec_callable, context, regexp, string); | |
1254 var_result.Bind(result); | 1228 var_result.Bind(result); |
1255 Goto(&out); | 1229 Goto(&out); |
1256 } | 1230 } |
1257 | 1231 |
1258 Bind(&if_isslowpath); | 1232 Bind(&if_isslowpath); |
1259 { | 1233 { |
1260 // Take the slow path of fetching the exec property, calling it, and | 1234 // Take the slow path of fetching the exec property, calling it, and |
1261 // verifying its return value. | 1235 // verifying its return value. |
1262 | 1236 |
1263 // Get the exec property. | 1237 // Get the exec property. |
(...skipping 21 matching lines...) Expand all Loading... |
1285 MessageTemplate::kInvalidRegExpExecResult, "unused"); | 1259 MessageTemplate::kInvalidRegExpExecResult, "unused"); |
1286 | 1260 |
1287 Goto(&out); | 1261 Goto(&out); |
1288 } | 1262 } |
1289 | 1263 |
1290 Bind(&if_isnotcallable); | 1264 Bind(&if_isnotcallable); |
1291 { | 1265 { |
1292 ThrowIfNotInstanceType(context, regexp, JS_REGEXP_TYPE, | 1266 ThrowIfNotInstanceType(context, regexp, JS_REGEXP_TYPE, |
1293 "RegExp.prototype.exec"); | 1267 "RegExp.prototype.exec"); |
1294 | 1268 |
1295 Callable exec_callable = CodeFactory::RegExpExecInternal(isolate, false); | 1269 Node* const result = |
1296 Node* const result = CallStub(exec_callable, context, regexp, string); | 1270 RegExpPrototypeExecBody(context, regexp, string, false); |
1297 var_result.Bind(result); | 1271 var_result.Bind(result); |
1298 Goto(&out); | 1272 Goto(&out); |
1299 } | 1273 } |
1300 } | 1274 } |
1301 | 1275 |
1302 Bind(&out); | 1276 Bind(&out); |
1303 return var_result.value(); | 1277 return var_result.value(); |
1304 } | 1278 } |
1305 | 1279 |
1306 // ES#sec-regexp.prototype.test | 1280 // ES#sec-regexp.prototype.test |
(...skipping 236 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1543 Node* const smi_zero = SmiConstant(Smi::kZero); | 1517 Node* const smi_zero = SmiConstant(Smi::kZero); |
1544 | 1518 |
1545 Node* const is_global = | 1519 Node* const is_global = |
1546 FlagGetter(context, regexp, JSRegExp::kGlobal, is_fastpath); | 1520 FlagGetter(context, regexp, JSRegExp::kGlobal, is_fastpath); |
1547 | 1521 |
1548 Label if_isglobal(this), if_isnotglobal(this); | 1522 Label if_isglobal(this), if_isnotglobal(this); |
1549 Branch(is_global, &if_isglobal, &if_isnotglobal); | 1523 Branch(is_global, &if_isglobal, &if_isnotglobal); |
1550 | 1524 |
1551 Bind(&if_isnotglobal); | 1525 Bind(&if_isnotglobal); |
1552 { | 1526 { |
1553 if (is_fastpath) { | 1527 Node* const result = |
1554 Callable exec_callable = CodeFactory::RegExpExecInternal(isolate, true); | 1528 is_fastpath ? RegExpPrototypeExecBody(context, regexp, string, true) |
1555 Return(CallStub(exec_callable, context, regexp, string)); | 1529 : RegExpExec(context, regexp, string); |
1556 } else { | 1530 Return(result); |
1557 Return(RegExpExec(context, regexp, string)); | |
1558 } | |
1559 } | 1531 } |
1560 | 1532 |
1561 Bind(&if_isglobal); | 1533 Bind(&if_isglobal); |
1562 { | 1534 { |
1563 Node* const is_unicode = | 1535 Node* const is_unicode = |
1564 FlagGetter(context, regexp, JSRegExp::kUnicode, is_fastpath); | 1536 FlagGetter(context, regexp, JSRegExp::kUnicode, is_fastpath); |
1565 | 1537 |
1566 StoreLastIndex(context, regexp, smi_zero, is_fastpath); | 1538 StoreLastIndex(context, regexp, smi_zero, is_fastpath); |
1567 | 1539 |
1568 // Allocate an array to store the resulting match strings. | 1540 // Allocate an array to store the resulting match strings. |
(...skipping 1015 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2584 Bind(&if_matched); | 2556 Bind(&if_matched); |
2585 { | 2557 { |
2586 Node* result = | 2558 Node* result = |
2587 ConstructNewResultFromMatchInfo(context, regexp, match_indices, string); | 2559 ConstructNewResultFromMatchInfo(context, regexp, match_indices, string); |
2588 Return(result); | 2560 Return(result); |
2589 } | 2561 } |
2590 } | 2562 } |
2591 | 2563 |
2592 } // namespace internal | 2564 } // namespace internal |
2593 } // namespace v8 | 2565 } // namespace v8 |
OLD | NEW |