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