|
68 | 68 | ECMA_REGEXP_PROTOTYPE_ROUTINE_SYMBOL_MATCH,
|
69 | 69 | ECMA_REGEXP_PROTOTYPE_ROUTINE_SYMBOL_REPLACE,
|
70 | 70 | ECMA_REGEXP_PROTOTYPE_ROUTINE_SYMBOL_SPLIT,
|
| 71 | + ECMA_REGEXP_PROTOTYPE_ROUTINE_SYMBOL_MATCH_ALL, |
71 | 72 | #endif /* ENABLED (JERRY_ESNEXT) */
|
72 | 73 | };
|
73 | 74 |
|
@@ -514,6 +515,147 @@ ecma_builtin_is_regexp_exec (ecma_extended_object_t *obj_p)
|
514 | 515 | } /* ecma_builtin_is_regexp_exec */
|
515 | 516 | #endif /* ENABLED (JERRY_ESNEXT) */
|
516 | 517 |
|
| 518 | +#if ENABLED (JERRY_ESNEXT) |
| 519 | +/** |
| 520 | + * The RegExp.prototype object's 'matchAll' routine |
| 521 | + * |
| 522 | + * See also: |
| 523 | + * ECMA-262 v11, 21.2.5.8 |
| 524 | + * |
| 525 | + * @return ecma_value_t |
| 526 | + */ |
| 527 | +static ecma_value_t |
| 528 | +ecma_builtin_regexp_prototype_match_all (ecma_object_t *regexp_obj_p, /**< this argument */ |
| 529 | + ecma_value_t string_arg) /**< source string */ |
| 530 | +{ |
| 531 | + /* 3. */ |
| 532 | + ecma_string_t *str_p = ecma_op_to_string (string_arg); |
| 533 | + |
| 534 | + if (JERRY_UNLIKELY (str_p == NULL)) |
| 535 | + { |
| 536 | + return ECMA_VALUE_ERROR; |
| 537 | + } |
| 538 | + |
| 539 | + /* 4. */ |
| 540 | + ecma_value_t constructor = ecma_op_species_constructor (regexp_obj_p, ECMA_BUILTIN_ID_REGEXP); |
| 541 | + |
| 542 | + if (ECMA_IS_VALUE_ERROR (constructor)) |
| 543 | + { |
| 544 | + ecma_deref_ecma_string (str_p); |
| 545 | + return constructor; |
| 546 | + } |
| 547 | + |
| 548 | + /* 5. */ |
| 549 | + ecma_value_t get_flag = ecma_op_object_get_by_magic_id (regexp_obj_p, LIT_MAGIC_STRING_FLAGS); |
| 550 | + |
| 551 | + if (ECMA_IS_VALUE_ERROR (get_flag)) |
| 552 | + { |
| 553 | + ecma_deref_ecma_string (str_p); |
| 554 | + ecma_free_value (constructor); |
| 555 | + return get_flag; |
| 556 | + } |
| 557 | + |
| 558 | + ecma_string_t *flags = ecma_op_to_string (get_flag); |
| 559 | + |
| 560 | + ecma_free_value (get_flag); |
| 561 | + |
| 562 | + if (JERRY_UNLIKELY (flags == NULL)) |
| 563 | + { |
| 564 | + ecma_deref_ecma_string (str_p); |
| 565 | + ecma_free_value (constructor); |
| 566 | + return ECMA_VALUE_ERROR; |
| 567 | + } |
| 568 | + |
| 569 | + /* 6. */ |
| 570 | + ecma_object_t *constructor_obj_p = ecma_get_object_from_value (constructor); |
| 571 | + ecma_value_t flags_value = ecma_make_string_value (flags); |
| 572 | + ecma_value_t match_args[] = { ecma_make_object_value (regexp_obj_p), flags_value}; |
| 573 | + ecma_value_t matcher = ecma_op_function_construct (constructor_obj_p, constructor_obj_p, match_args, 2); |
| 574 | + |
| 575 | + ecma_deref_object (constructor_obj_p); |
| 576 | + |
| 577 | + if (ECMA_IS_VALUE_ERROR (matcher)) |
| 578 | + { |
| 579 | + ecma_deref_ecma_string (str_p); |
| 580 | + ecma_deref_ecma_string (flags); |
| 581 | + return matcher; |
| 582 | + } |
| 583 | + |
| 584 | + /* 7. */ |
| 585 | + ecma_value_t get_last_index = ecma_op_object_get_by_magic_id (regexp_obj_p, LIT_MAGIC_STRING_LASTINDEX_UL); |
| 586 | + |
| 587 | + if (ECMA_IS_VALUE_ERROR (get_last_index)) |
| 588 | + { |
| 589 | + ecma_deref_ecma_string (str_p); |
| 590 | + ecma_deref_ecma_string (flags); |
| 591 | + ecma_free_value (matcher); |
| 592 | + return get_last_index; |
| 593 | + } |
| 594 | + |
| 595 | + ecma_length_t last_index; |
| 596 | + ecma_value_t to_len = ecma_op_to_length (get_last_index, &last_index); |
| 597 | + |
| 598 | + ecma_free_value (get_last_index); |
| 599 | + |
| 600 | + if (ECMA_IS_VALUE_ERROR (to_len)) |
| 601 | + { |
| 602 | + ecma_deref_ecma_string (str_p); |
| 603 | + ecma_deref_ecma_string (flags); |
| 604 | + ecma_free_value (matcher); |
| 605 | + return to_len; |
| 606 | + } |
| 607 | + |
| 608 | + /* 8. */ |
| 609 | + ecma_object_t *matcher_obj_p = ecma_get_object_from_value (matcher); |
| 610 | + ecma_value_t last_index_value = ecma_make_length_value (last_index); |
| 611 | + ecma_value_t set = ecma_op_object_put (matcher_obj_p, |
| 612 | + ecma_get_magic_string (LIT_MAGIC_STRING_LASTINDEX_UL), |
| 613 | + last_index_value, |
| 614 | + true); |
| 615 | + |
| 616 | + ecma_free_value (last_index_value); |
| 617 | + |
| 618 | + if (ECMA_IS_VALUE_ERROR (set)) |
| 619 | + { |
| 620 | + ecma_deref_ecma_string (str_p); |
| 621 | + ecma_deref_ecma_string (flags); |
| 622 | + ecma_deref_object (matcher_obj_p); |
| 623 | + } |
| 624 | + |
| 625 | + uint16_t parsed_flag; |
| 626 | + ecma_value_t flag_parse = ecma_regexp_parse_flags (flags, &parsed_flag); |
| 627 | + |
| 628 | + ecma_deref_ecma_string (flags); |
| 629 | + |
| 630 | + if (ECMA_IS_VALUE_ERROR (flag_parse)) |
| 631 | + { |
| 632 | + ecma_deref_ecma_string (str_p); |
| 633 | + ecma_deref_object (matcher_obj_p); |
| 634 | + return flag_parse; |
| 635 | + } |
| 636 | + |
| 637 | + /* 13. */ |
| 638 | + ecma_object_t *result_obj; |
| 639 | + ecma_object_t *proto_p = ecma_builtin_get (ECMA_BUILTIN_ID_REGEXP_STRING_ITERATOR_PROTOTYPE); |
| 640 | + result_obj = ecma_create_object (proto_p, |
| 641 | + sizeof (ecma_regexp_string_iterator_t), |
| 642 | + ECMA_OBJECT_TYPE_PSEUDO_ARRAY); |
| 643 | + |
| 644 | + ecma_extended_object_t *ext_obj_p = (ecma_extended_object_t *) result_obj; |
| 645 | + ext_obj_p->u.pseudo_array.type = (uint8_t) ECMA_PSEUDO_REGEXP_STRING_ITERATOR; |
| 646 | + ext_obj_p->u.pseudo_array.extra_info = (uint8_t) (parsed_flag & (RE_FLAG_GLOBAL | RE_FLAG_UNICODE)); |
| 647 | + |
| 648 | + ecma_regexp_string_iterator_t *regexp_string_iterator_obj = (ecma_regexp_string_iterator_t *) result_obj; |
| 649 | + |
| 650 | + regexp_string_iterator_obj->iterating_regexp = matcher; |
| 651 | + regexp_string_iterator_obj->iterated_string = ecma_make_string_value (str_p); |
| 652 | + |
| 653 | + ecma_deref_object (matcher_obj_p); |
| 654 | + |
| 655 | + return ecma_make_object_value (result_obj); |
| 656 | +} /* ecma_builtin_regexp_prototype_match_all */ |
| 657 | +#endif /* ENABLED (JERRY_ESNEXT) */ |
| 658 | + |
517 | 659 | /**
|
518 | 660 | * Dispatcher of the Regexp built-in's routines
|
519 | 661 | *
|
@@ -584,6 +726,10 @@ ecma_builtin_regexp_prototype_dispatch_routine (uint8_t builtin_routine_id, /**<
|
584 | 726 | {
|
585 | 727 | return ecma_regexp_match_helper (this_arg, arguments_list_p[0]);
|
586 | 728 | }
|
| 729 | + case ECMA_REGEXP_PROTOTYPE_ROUTINE_SYMBOL_MATCH_ALL: |
| 730 | + { |
| 731 | + return ecma_builtin_regexp_prototype_match_all (obj_p, arguments_list_p[0]); |
| 732 | + } |
587 | 733 | case ECMA_REGEXP_PROTOTYPE_ROUTINE_SYMBOL_REPLACE:
|
588 | 734 | {
|
589 | 735 | return ecma_regexp_replace_helper (this_arg, arguments_list_p[0], arguments_list_p[1]);
|
|
0 commit comments