1425bb815Sopenharmony_ci/* Copyright JS Foundation and other contributors, http://js.foundation
2425bb815Sopenharmony_ci *
3425bb815Sopenharmony_ci * Licensed under the Apache License, Version 2.0 (the "License");
4425bb815Sopenharmony_ci * you may not use this file except in compliance with the License.
5425bb815Sopenharmony_ci * You may obtain a copy of the License at
6425bb815Sopenharmony_ci *
7425bb815Sopenharmony_ci *     http://www.apache.org/licenses/LICENSE-2.0
8425bb815Sopenharmony_ci *
9425bb815Sopenharmony_ci * Unless required by applicable law or agreed to in writing, software
10425bb815Sopenharmony_ci * distributed under the License is distributed on an "AS IS" BASIS
11425bb815Sopenharmony_ci * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12425bb815Sopenharmony_ci * See the License for the specific language governing permissions and
13425bb815Sopenharmony_ci * limitations under the License.
14425bb815Sopenharmony_ci */
15425bb815Sopenharmony_ci
16425bb815Sopenharmony_ci#include "ecma-alloc.h"
17425bb815Sopenharmony_ci#include "ecma-builtins.h"
18425bb815Sopenharmony_ci#include "ecma-conversion.h"
19425bb815Sopenharmony_ci#include "ecma-exceptions.h"
20425bb815Sopenharmony_ci#include "ecma-gc.h"
21425bb815Sopenharmony_ci#include "ecma-helpers.h"
22425bb815Sopenharmony_ci#include "jcontext.h"
23425bb815Sopenharmony_ci#include "ecma-objects.h"
24425bb815Sopenharmony_ci#include "ecma-regexp-object.h"
25425bb815Sopenharmony_ci#include "ecma-try-catch-macro.h"
26425bb815Sopenharmony_ci
27425bb815Sopenharmony_ci#if ENABLED (JERRY_BUILTIN_REGEXP)
28425bb815Sopenharmony_ci
29425bb815Sopenharmony_ci#define ECMA_BUILTINS_INTERNAL
30425bb815Sopenharmony_ci#include "ecma-builtins-internal.h"
31425bb815Sopenharmony_ci
32425bb815Sopenharmony_ci#define BUILTIN_INC_HEADER_NAME "ecma-builtin-regexp.inc.h"
33425bb815Sopenharmony_ci#define BUILTIN_UNDERSCORED_ID regexp
34425bb815Sopenharmony_ci#include "ecma-builtin-internal-routines-template.inc.h"
35425bb815Sopenharmony_ci
36425bb815Sopenharmony_ci/** \addtogroup ecma ECMA
37425bb815Sopenharmony_ci * @{
38425bb815Sopenharmony_ci *
39425bb815Sopenharmony_ci * \addtogroup ecmabuiltins
40425bb815Sopenharmony_ci * @{
41425bb815Sopenharmony_ci *
42425bb815Sopenharmony_ci * \addtogroup regexp ECMA RegExp object built-in
43425bb815Sopenharmony_ci * @{
44425bb815Sopenharmony_ci */
45425bb815Sopenharmony_ci
46425bb815Sopenharmony_cistatic ecma_value_t
47425bb815Sopenharmony_ciecma_builtin_regexp_dispatch_helper (const ecma_value_t *arguments_list_p, /**< arguments list */
48425bb815Sopenharmony_ci                                     ecma_length_t arguments_list_len) /**< number of arguments */
49425bb815Sopenharmony_ci{
50425bb815Sopenharmony_ci  ecma_value_t pattern_value = ECMA_VALUE_UNDEFINED;
51425bb815Sopenharmony_ci  ecma_value_t flags_value = ECMA_VALUE_UNDEFINED;
52425bb815Sopenharmony_ci#if ENABLED (JERRY_ES2015)
53425bb815Sopenharmony_ci  bool create_regexp_from_bc = false;
54425bb815Sopenharmony_ci  bool free_arguments = false;
55425bb815Sopenharmony_ci  ecma_object_t *new_target_p = JERRY_CONTEXT (current_new_target);
56425bb815Sopenharmony_ci#else /* !ENABLED (JERRY_ES2015) */
57425bb815Sopenharmony_ci  ecma_object_t *new_target_p = NULL;
58425bb815Sopenharmony_ci#endif /* ENABLED (JERRY_ES2015) */
59425bb815Sopenharmony_ci
60425bb815Sopenharmony_ci  if (arguments_list_len > 0)
61425bb815Sopenharmony_ci  {
62425bb815Sopenharmony_ci    /* pattern string or RegExp object */
63425bb815Sopenharmony_ci    pattern_value = arguments_list_p[0];
64425bb815Sopenharmony_ci
65425bb815Sopenharmony_ci    if (arguments_list_len > 1)
66425bb815Sopenharmony_ci    {
67425bb815Sopenharmony_ci      flags_value = arguments_list_p[1];
68425bb815Sopenharmony_ci    }
69425bb815Sopenharmony_ci  }
70425bb815Sopenharmony_ci
71425bb815Sopenharmony_ci#if ENABLED (JERRY_ES2015)
72425bb815Sopenharmony_ci  ecma_value_t regexp_value = ecma_op_is_regexp (pattern_value);
73425bb815Sopenharmony_ci
74425bb815Sopenharmony_ci  if (ECMA_IS_VALUE_ERROR (regexp_value))
75425bb815Sopenharmony_ci  {
76425bb815Sopenharmony_ci    return regexp_value;
77425bb815Sopenharmony_ci  }
78425bb815Sopenharmony_ci
79425bb815Sopenharmony_ci  bool pattern_is_regexp = regexp_value == ECMA_VALUE_TRUE;
80425bb815Sopenharmony_ci  re_compiled_code_t *bc_p = NULL;
81425bb815Sopenharmony_ci
82425bb815Sopenharmony_ci  if (new_target_p == NULL)
83425bb815Sopenharmony_ci  {
84425bb815Sopenharmony_ci    new_target_p = ecma_builtin_get (ECMA_BUILTIN_ID_REGEXP);
85425bb815Sopenharmony_ci
86425bb815Sopenharmony_ci    if (pattern_is_regexp && ecma_is_value_undefined (flags_value))
87425bb815Sopenharmony_ci    {
88425bb815Sopenharmony_ci      ecma_object_t *pattern_obj_p = ecma_get_object_from_value (pattern_value);
89425bb815Sopenharmony_ci
90425bb815Sopenharmony_ci      ecma_value_t pattern_constructor = ecma_op_object_get_by_magic_id (pattern_obj_p, LIT_MAGIC_STRING_CONSTRUCTOR);
91425bb815Sopenharmony_ci
92425bb815Sopenharmony_ci      if (ECMA_IS_VALUE_ERROR (pattern_constructor))
93425bb815Sopenharmony_ci      {
94425bb815Sopenharmony_ci        return pattern_constructor;
95425bb815Sopenharmony_ci      }
96425bb815Sopenharmony_ci
97425bb815Sopenharmony_ci      bool is_same = ecma_op_same_value (ecma_make_object_value (new_target_p), pattern_constructor);
98425bb815Sopenharmony_ci      ecma_free_value (pattern_constructor);
99425bb815Sopenharmony_ci
100425bb815Sopenharmony_ci      if (is_same)
101425bb815Sopenharmony_ci      {
102425bb815Sopenharmony_ci        return ecma_copy_value (pattern_value);
103425bb815Sopenharmony_ci      }
104425bb815Sopenharmony_ci    }
105425bb815Sopenharmony_ci  }
106425bb815Sopenharmony_ci
107425bb815Sopenharmony_ci  if (ecma_object_is_regexp_object (pattern_value))
108425bb815Sopenharmony_ci  {
109425bb815Sopenharmony_ci    ecma_extended_object_t *pattern_obj_p = (ecma_extended_object_t *) ecma_get_object_from_value (pattern_value);
110425bb815Sopenharmony_ci    bc_p = ECMA_GET_INTERNAL_VALUE_POINTER (re_compiled_code_t,
111425bb815Sopenharmony_ci                                            pattern_obj_p->u.class_prop.u.value);
112425bb815Sopenharmony_ci
113425bb815Sopenharmony_ci    create_regexp_from_bc = ecma_is_value_undefined (flags_value);
114425bb815Sopenharmony_ci
115425bb815Sopenharmony_ci    if (!create_regexp_from_bc)
116425bb815Sopenharmony_ci    {
117425bb815Sopenharmony_ci      pattern_value = bc_p->source;
118425bb815Sopenharmony_ci    }
119425bb815Sopenharmony_ci  }
120425bb815Sopenharmony_ci  else if (pattern_is_regexp)
121425bb815Sopenharmony_ci  {
122425bb815Sopenharmony_ci    ecma_object_t *pattern_obj_p = ecma_get_object_from_value (pattern_value);
123425bb815Sopenharmony_ci
124425bb815Sopenharmony_ci    pattern_value = ecma_op_object_get_by_magic_id (pattern_obj_p, LIT_MAGIC_STRING_SOURCE);
125425bb815Sopenharmony_ci
126425bb815Sopenharmony_ci    if (ECMA_IS_VALUE_ERROR (pattern_value))
127425bb815Sopenharmony_ci    {
128425bb815Sopenharmony_ci      return pattern_value;
129425bb815Sopenharmony_ci    }
130425bb815Sopenharmony_ci
131425bb815Sopenharmony_ci    if (ecma_is_value_undefined (flags_value))
132425bb815Sopenharmony_ci    {
133425bb815Sopenharmony_ci      flags_value = ecma_op_object_get_by_magic_id (pattern_obj_p, LIT_MAGIC_STRING_FLAGS);
134425bb815Sopenharmony_ci
135425bb815Sopenharmony_ci      if (ECMA_IS_VALUE_ERROR (flags_value))
136425bb815Sopenharmony_ci      {
137425bb815Sopenharmony_ci        ecma_free_value (pattern_value);
138425bb815Sopenharmony_ci        return flags_value;
139425bb815Sopenharmony_ci      }
140425bb815Sopenharmony_ci    }
141425bb815Sopenharmony_ci    else
142425bb815Sopenharmony_ci    {
143425bb815Sopenharmony_ci      flags_value = ecma_copy_value (flags_value);
144425bb815Sopenharmony_ci    }
145425bb815Sopenharmony_ci
146425bb815Sopenharmony_ci    free_arguments = true;
147425bb815Sopenharmony_ci  }
148425bb815Sopenharmony_ci#else /* !ENABLED (JERRY_ES2015) */
149425bb815Sopenharmony_ci  if (ecma_object_is_regexp_object (pattern_value))
150425bb815Sopenharmony_ci  {
151425bb815Sopenharmony_ci    if (ecma_is_value_undefined (flags_value))
152425bb815Sopenharmony_ci    {
153425bb815Sopenharmony_ci      return ecma_copy_value (pattern_value);
154425bb815Sopenharmony_ci    }
155425bb815Sopenharmony_ci
156425bb815Sopenharmony_ci    return ecma_raise_type_error (ECMA_ERR_MSG ("Invalid argument of RegExp call."));
157425bb815Sopenharmony_ci  }
158425bb815Sopenharmony_ci#endif /* ENABLED (JERRY_ES2015) */
159425bb815Sopenharmony_ci
160425bb815Sopenharmony_ci  ecma_value_t ret_value = ECMA_VALUE_ERROR;
161425bb815Sopenharmony_ci  ecma_object_t *new_target_obj_p = ecma_op_regexp_alloc (new_target_p);
162425bb815Sopenharmony_ci
163425bb815Sopenharmony_ci  if (JERRY_LIKELY (new_target_obj_p != NULL))
164425bb815Sopenharmony_ci  {
165425bb815Sopenharmony_ci#if ENABLED (JERRY_ES2015)
166425bb815Sopenharmony_ci    if (create_regexp_from_bc)
167425bb815Sopenharmony_ci    {
168425bb815Sopenharmony_ci      ret_value = ecma_op_create_regexp_from_bytecode (new_target_obj_p, bc_p);
169425bb815Sopenharmony_ci      JERRY_ASSERT (!ECMA_IS_VALUE_ERROR (ret_value));
170425bb815Sopenharmony_ci    }
171425bb815Sopenharmony_ci    else
172425bb815Sopenharmony_ci#endif /* ENABLED (JERRY_ES2015) */
173425bb815Sopenharmony_ci    {
174425bb815Sopenharmony_ci      ret_value = ecma_op_create_regexp_from_pattern (new_target_obj_p, pattern_value, flags_value);
175425bb815Sopenharmony_ci
176425bb815Sopenharmony_ci      if (ECMA_IS_VALUE_ERROR (ret_value))
177425bb815Sopenharmony_ci      {
178425bb815Sopenharmony_ci        ecma_deref_object (new_target_obj_p);
179425bb815Sopenharmony_ci      }
180425bb815Sopenharmony_ci    }
181425bb815Sopenharmony_ci  }
182425bb815Sopenharmony_ci
183425bb815Sopenharmony_ci#if ENABLED (JERRY_ES2015)
184425bb815Sopenharmony_ci  if (free_arguments)
185425bb815Sopenharmony_ci  {
186425bb815Sopenharmony_ci    ecma_free_value (pattern_value);
187425bb815Sopenharmony_ci    ecma_free_value (flags_value);
188425bb815Sopenharmony_ci  }
189425bb815Sopenharmony_ci#endif /* ENABLED (JERRY_ES2015) */
190425bb815Sopenharmony_ci
191425bb815Sopenharmony_ci  return ret_value;
192425bb815Sopenharmony_ci} /* ecma_builtin_regexp_dispatch_helper */
193425bb815Sopenharmony_ci
194425bb815Sopenharmony_ci/**
195425bb815Sopenharmony_ci * Handle calling [[Call]] of built-in RegExp object
196425bb815Sopenharmony_ci *
197425bb815Sopenharmony_ci * @return ecma value
198425bb815Sopenharmony_ci *         Returned value must be freed with ecma_free_value.
199425bb815Sopenharmony_ci */
200425bb815Sopenharmony_ciecma_value_t
201425bb815Sopenharmony_ciecma_builtin_regexp_dispatch_call (const ecma_value_t *arguments_list_p, /**< arguments list */
202425bb815Sopenharmony_ci                                   ecma_length_t arguments_list_len) /**< number of arguments */
203425bb815Sopenharmony_ci{
204425bb815Sopenharmony_ci  return ecma_builtin_regexp_dispatch_helper (arguments_list_p,
205425bb815Sopenharmony_ci                                              arguments_list_len);
206425bb815Sopenharmony_ci} /* ecma_builtin_regexp_dispatch_call */
207425bb815Sopenharmony_ci
208425bb815Sopenharmony_ci/**
209425bb815Sopenharmony_ci * Handle calling [[Construct]] of built-in RegExp object
210425bb815Sopenharmony_ci *
211425bb815Sopenharmony_ci * @return ecma value
212425bb815Sopenharmony_ci *         Returned value must be freed with ecma_free_value.
213425bb815Sopenharmony_ci */
214425bb815Sopenharmony_ciecma_value_t
215425bb815Sopenharmony_ciecma_builtin_regexp_dispatch_construct (const ecma_value_t *arguments_list_p, /**< arguments list */
216425bb815Sopenharmony_ci                                        ecma_length_t arguments_list_len) /**< number of arguments */
217425bb815Sopenharmony_ci{
218425bb815Sopenharmony_ci  return ecma_builtin_regexp_dispatch_helper (arguments_list_p,
219425bb815Sopenharmony_ci                                              arguments_list_len);
220425bb815Sopenharmony_ci} /* ecma_builtin_regexp_dispatch_construct */
221425bb815Sopenharmony_ci
222425bb815Sopenharmony_ci#if ENABLED (JERRY_ES2015)
223425bb815Sopenharmony_ci/**
224425bb815Sopenharmony_ci * 21.2.4.2 get RegExp [ @@species ] accessor
225425bb815Sopenharmony_ci *
226425bb815Sopenharmony_ci * @return ecma_value
227425bb815Sopenharmony_ci *         returned value must be freed with ecma_free_value
228425bb815Sopenharmony_ci */
229425bb815Sopenharmony_ciecma_value_t
230425bb815Sopenharmony_ciecma_builtin_regexp_species_get (ecma_value_t this_value) /**< This Value */
231425bb815Sopenharmony_ci{
232425bb815Sopenharmony_ci  return ecma_copy_value (this_value);
233425bb815Sopenharmony_ci} /* ecma_builtin_regexp_species_get */
234425bb815Sopenharmony_ci#endif /* ENABLED (JERRY_ES2015) */
235425bb815Sopenharmony_ci
236425bb815Sopenharmony_ci/**
237425bb815Sopenharmony_ci * @}
238425bb815Sopenharmony_ci * @}
239425bb815Sopenharmony_ci * @}
240425bb815Sopenharmony_ci */
241425bb815Sopenharmony_ci
242425bb815Sopenharmony_ci#endif /* ENABLED (JERRY_BUILTIN_REGEXP) */
243