Removed ECMA_TRY_CATCH macros from RegExp built-in (#2642)
JerryScript-DCO-1.0-Signed-off-by: László Langó llango.u-szeged@partner.samsung.com
This commit is contained in:
@@ -63,156 +63,157 @@ ecma_builtin_regexp_prototype_compile (ecma_value_t this_arg, /**< this argument
|
||||
ecma_value_t pattern_arg, /**< pattern or RegExp object */
|
||||
ecma_value_t flags_arg) /**< flags */
|
||||
{
|
||||
ecma_value_t ret_value = ECMA_VALUE_EMPTY;
|
||||
|
||||
if (!ecma_is_value_object (this_arg)
|
||||
|| !ecma_object_class_is (ecma_get_object_from_value (this_arg), LIT_MAGIC_STRING_REGEXP_UL))
|
||||
{
|
||||
ret_value = ecma_raise_type_error (ECMA_ERR_MSG ("Incomplete RegExp type"));
|
||||
return ecma_raise_type_error (ECMA_ERR_MSG ("Incomplete RegExp type"));
|
||||
}
|
||||
else
|
||||
|
||||
uint16_t flags = 0;
|
||||
|
||||
if (ecma_is_value_object (pattern_arg)
|
||||
&& ecma_object_class_is (ecma_get_object_from_value (pattern_arg), LIT_MAGIC_STRING_REGEXP_UL))
|
||||
{
|
||||
uint16_t flags = 0;
|
||||
|
||||
if (ecma_is_value_object (pattern_arg)
|
||||
&& ecma_object_class_is (ecma_get_object_from_value (pattern_arg), LIT_MAGIC_STRING_REGEXP_UL))
|
||||
if (!ecma_is_value_undefined (flags_arg))
|
||||
{
|
||||
if (!ecma_is_value_undefined (flags_arg))
|
||||
{
|
||||
ret_value = ecma_raise_type_error (ECMA_ERR_MSG ("Invalid argument of RegExp compile."));
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Compile from existing RegExp pbject. */
|
||||
ecma_object_t *target_p = ecma_get_object_from_value (pattern_arg);
|
||||
|
||||
/* Get source. */
|
||||
ecma_string_t *magic_string_p = ecma_get_magic_string (LIT_MAGIC_STRING_SOURCE);
|
||||
ecma_value_t source_value = ecma_op_object_get_own_data_prop (target_p, magic_string_p);
|
||||
ecma_string_t *pattern_string_p = ecma_get_string_from_value (source_value);
|
||||
|
||||
/* Get flags. */
|
||||
magic_string_p = ecma_get_magic_string (LIT_MAGIC_STRING_GLOBAL);
|
||||
ecma_value_t global_value = ecma_op_object_get_own_data_prop (target_p, magic_string_p);
|
||||
|
||||
JERRY_ASSERT (ecma_is_value_boolean (global_value));
|
||||
|
||||
if (ecma_is_value_true (global_value))
|
||||
{
|
||||
flags |= RE_FLAG_GLOBAL;
|
||||
}
|
||||
|
||||
magic_string_p = ecma_get_magic_string (LIT_MAGIC_STRING_IGNORECASE_UL);
|
||||
ecma_value_t ignore_case_value = ecma_op_object_get_own_data_prop (target_p, magic_string_p);
|
||||
|
||||
JERRY_ASSERT (ecma_is_value_boolean (ignore_case_value));
|
||||
|
||||
if (ecma_is_value_true (ignore_case_value))
|
||||
{
|
||||
flags |= RE_FLAG_IGNORE_CASE;
|
||||
}
|
||||
|
||||
magic_string_p = ecma_get_magic_string (LIT_MAGIC_STRING_MULTILINE);
|
||||
ecma_value_t multiline_value = ecma_op_object_get_own_data_prop (target_p, magic_string_p);
|
||||
|
||||
JERRY_ASSERT (ecma_is_value_boolean (multiline_value));
|
||||
|
||||
if (ecma_is_value_true (multiline_value))
|
||||
{
|
||||
flags |= RE_FLAG_MULTILINE;
|
||||
}
|
||||
|
||||
ECMA_TRY_CATCH (obj_this, ecma_op_to_object (this_arg), ret_value);
|
||||
ecma_object_t *this_obj_p = ecma_get_object_from_value (obj_this);
|
||||
|
||||
/* Get bytecode property. */
|
||||
ecma_value_t *bc_prop_p = &(((ecma_extended_object_t *) this_obj_p)->u.class_prop.u.value);
|
||||
|
||||
/* TODO: We currently have to re-compile the bytecode, because
|
||||
* we can't copy it without knowing its length. */
|
||||
const re_compiled_code_t *new_bc_p = NULL;
|
||||
ecma_value_t bc_comp = re_compile_bytecode (&new_bc_p, pattern_string_p, flags);
|
||||
/* Should always succeed, since we're compiling from a source that has been compiled previously. */
|
||||
JERRY_ASSERT (ecma_is_value_empty (bc_comp));
|
||||
|
||||
ecma_deref_ecma_string (pattern_string_p);
|
||||
|
||||
re_compiled_code_t *old_bc_p = ECMA_GET_INTERNAL_VALUE_ANY_POINTER (re_compiled_code_t, *bc_prop_p);
|
||||
|
||||
if (old_bc_p != NULL)
|
||||
{
|
||||
/* Free the old bytecode */
|
||||
ecma_bytecode_deref ((ecma_compiled_code_t *) old_bc_p);
|
||||
}
|
||||
|
||||
ECMA_SET_INTERNAL_VALUE_POINTER (*bc_prop_p, new_bc_p);
|
||||
|
||||
re_initialize_props (this_obj_p, pattern_string_p, flags);
|
||||
|
||||
ret_value = ECMA_VALUE_UNDEFINED;
|
||||
|
||||
ECMA_FINALIZE (obj_this);
|
||||
}
|
||||
return ecma_raise_type_error (ECMA_ERR_MSG ("Invalid argument of RegExp compile."));
|
||||
}
|
||||
else
|
||||
/* Compile from existing RegExp pbject. */
|
||||
ecma_object_t *target_p = ecma_get_object_from_value (pattern_arg);
|
||||
|
||||
/* Get source. */
|
||||
ecma_string_t *magic_string_p = ecma_get_magic_string (LIT_MAGIC_STRING_SOURCE);
|
||||
ecma_value_t source_value = ecma_op_object_get_own_data_prop (target_p, magic_string_p);
|
||||
ecma_string_t *pattern_string_p = ecma_get_string_from_value (source_value);
|
||||
|
||||
/* Get flags. */
|
||||
magic_string_p = ecma_get_magic_string (LIT_MAGIC_STRING_GLOBAL);
|
||||
ecma_value_t global_value = ecma_op_object_get_own_data_prop (target_p, magic_string_p);
|
||||
|
||||
JERRY_ASSERT (ecma_is_value_boolean (global_value));
|
||||
|
||||
if (ecma_is_value_true (global_value))
|
||||
{
|
||||
ecma_string_t *pattern_string_p = NULL;
|
||||
flags |= RE_FLAG_GLOBAL;
|
||||
}
|
||||
|
||||
/* Get source string. */
|
||||
ret_value = ecma_regexp_read_pattern_str_helper (pattern_arg, &pattern_string_p);
|
||||
magic_string_p = ecma_get_magic_string (LIT_MAGIC_STRING_IGNORECASE_UL);
|
||||
ecma_value_t ignore_case_value = ecma_op_object_get_own_data_prop (target_p, magic_string_p);
|
||||
|
||||
/* Parse flags. */
|
||||
if (ecma_is_value_empty (ret_value) && !ecma_is_value_undefined (flags_arg))
|
||||
{
|
||||
ECMA_TRY_CATCH (flags_str_value,
|
||||
ecma_op_to_string (flags_arg),
|
||||
ret_value);
|
||||
JERRY_ASSERT (ecma_is_value_boolean (ignore_case_value));
|
||||
|
||||
ECMA_TRY_CATCH (flags_dummy,
|
||||
re_parse_regexp_flags (ecma_get_string_from_value (flags_str_value), &flags),
|
||||
ret_value);
|
||||
ECMA_FINALIZE (flags_dummy);
|
||||
ECMA_FINALIZE (flags_str_value);
|
||||
}
|
||||
if (ecma_is_value_true (ignore_case_value))
|
||||
{
|
||||
flags |= RE_FLAG_IGNORE_CASE;
|
||||
}
|
||||
|
||||
if (ecma_is_value_empty (ret_value))
|
||||
{
|
||||
ECMA_TRY_CATCH (obj_this, ecma_op_to_object (this_arg), ret_value);
|
||||
ecma_object_t *this_obj_p = ecma_get_object_from_value (obj_this);
|
||||
magic_string_p = ecma_get_magic_string (LIT_MAGIC_STRING_MULTILINE);
|
||||
ecma_value_t multiline_value = ecma_op_object_get_own_data_prop (target_p, magic_string_p);
|
||||
|
||||
ecma_value_t *bc_prop_p = &(((ecma_extended_object_t *) this_obj_p)->u.class_prop.u.value);
|
||||
JERRY_ASSERT (ecma_is_value_boolean (multiline_value));
|
||||
|
||||
/* Try to compile bytecode from new source. */
|
||||
const re_compiled_code_t *new_bc_p = NULL;
|
||||
ECMA_TRY_CATCH (bc_dummy,
|
||||
re_compile_bytecode (&new_bc_p, pattern_string_p, flags),
|
||||
ret_value);
|
||||
if (ecma_is_value_true (multiline_value))
|
||||
{
|
||||
flags |= RE_FLAG_MULTILINE;
|
||||
}
|
||||
|
||||
re_compiled_code_t *old_bc_p = ECMA_GET_INTERNAL_VALUE_ANY_POINTER (re_compiled_code_t, *bc_prop_p);
|
||||
ecma_value_t obj_this = ecma_op_to_object (this_arg);
|
||||
if (ECMA_IS_VALUE_ERROR (obj_this))
|
||||
{
|
||||
return obj_this;
|
||||
}
|
||||
ecma_object_t *this_obj_p = ecma_get_object_from_value (obj_this);
|
||||
|
||||
if (old_bc_p != NULL)
|
||||
{
|
||||
/* Free the old bytecode */
|
||||
ecma_bytecode_deref ((ecma_compiled_code_t *) old_bc_p);
|
||||
}
|
||||
/* Get bytecode property. */
|
||||
ecma_value_t *bc_prop_p = &(((ecma_extended_object_t *) this_obj_p)->u.class_prop.u.value);
|
||||
|
||||
ECMA_SET_INTERNAL_VALUE_POINTER (*bc_prop_p, new_bc_p);
|
||||
re_initialize_props (this_obj_p, pattern_string_p, flags);
|
||||
ret_value = ECMA_VALUE_UNDEFINED;
|
||||
/* TODO: We currently have to re-compile the bytecode, because
|
||||
* we can't copy it without knowing its length. */
|
||||
const re_compiled_code_t *new_bc_p = NULL;
|
||||
ecma_value_t bc_comp = re_compile_bytecode (&new_bc_p, pattern_string_p, flags);
|
||||
/* Should always succeed, since we're compiling from a source that has been compiled previously. */
|
||||
JERRY_ASSERT (ecma_is_value_empty (bc_comp));
|
||||
|
||||
ECMA_FINALIZE (bc_dummy);
|
||||
ecma_deref_ecma_string (pattern_string_p);
|
||||
|
||||
ECMA_FINALIZE (obj_this);
|
||||
}
|
||||
re_compiled_code_t *old_bc_p = ECMA_GET_INTERNAL_VALUE_ANY_POINTER (re_compiled_code_t, *bc_prop_p);
|
||||
|
||||
if (pattern_string_p != NULL)
|
||||
{
|
||||
ecma_deref_ecma_string (pattern_string_p);
|
||||
}
|
||||
if (old_bc_p != NULL)
|
||||
{
|
||||
/* Free the old bytecode */
|
||||
ecma_bytecode_deref ((ecma_compiled_code_t *) old_bc_p);
|
||||
}
|
||||
|
||||
ECMA_SET_INTERNAL_VALUE_POINTER (*bc_prop_p, new_bc_p);
|
||||
|
||||
re_initialize_props (this_obj_p, pattern_string_p, flags);
|
||||
ecma_free_value (obj_this);
|
||||
|
||||
return ECMA_VALUE_UNDEFINED;
|
||||
}
|
||||
|
||||
ecma_string_t *pattern_string_p = NULL;
|
||||
|
||||
/* Get source string. */
|
||||
ecma_value_t ret_value = ecma_regexp_read_pattern_str_helper (pattern_arg, &pattern_string_p);
|
||||
if (ECMA_IS_VALUE_ERROR (ret_value))
|
||||
{
|
||||
JERRY_ASSERT (pattern_string_p == NULL);
|
||||
return ret_value;
|
||||
}
|
||||
JERRY_ASSERT (ecma_is_value_empty (ret_value));
|
||||
|
||||
/* Parse flags. */
|
||||
if (!ecma_is_value_undefined (flags_arg))
|
||||
{
|
||||
ecma_value_t flags_str_value = ecma_op_to_string (flags_arg);
|
||||
if (ECMA_IS_VALUE_ERROR (flags_str_value))
|
||||
{
|
||||
ecma_deref_ecma_string (pattern_string_p);
|
||||
return flags_str_value;
|
||||
}
|
||||
|
||||
ecma_value_t parsed_flags_val = re_parse_regexp_flags (ecma_get_string_from_value (flags_str_value), &flags);
|
||||
ecma_free_value (flags_str_value);
|
||||
if (ECMA_IS_VALUE_ERROR (parsed_flags_val))
|
||||
{
|
||||
ecma_deref_ecma_string (pattern_string_p);
|
||||
return parsed_flags_val;
|
||||
}
|
||||
}
|
||||
|
||||
return ret_value;
|
||||
/* Try to compile bytecode from new source. */
|
||||
const re_compiled_code_t *new_bc_p = NULL;
|
||||
ecma_value_t bc_val = re_compile_bytecode (&new_bc_p, pattern_string_p, flags);
|
||||
if (ECMA_IS_VALUE_ERROR (bc_val))
|
||||
{
|
||||
ecma_deref_ecma_string (pattern_string_p);
|
||||
return bc_val;
|
||||
}
|
||||
|
||||
ecma_value_t obj_this = ecma_op_to_object (this_arg);
|
||||
if (ECMA_IS_VALUE_ERROR (obj_this))
|
||||
{
|
||||
ecma_deref_ecma_string (pattern_string_p);
|
||||
return obj_this;
|
||||
}
|
||||
ecma_object_t *this_obj_p = ecma_get_object_from_value (obj_this);
|
||||
ecma_value_t *bc_prop_p = &(((ecma_extended_object_t *) this_obj_p)->u.class_prop.u.value);
|
||||
|
||||
re_compiled_code_t *old_bc_p = ECMA_GET_INTERNAL_VALUE_ANY_POINTER (re_compiled_code_t, *bc_prop_p);
|
||||
|
||||
if (old_bc_p != NULL)
|
||||
{
|
||||
/* Free the old bytecode */
|
||||
ecma_bytecode_deref ((ecma_compiled_code_t *) old_bc_p);
|
||||
}
|
||||
|
||||
ECMA_SET_INTERNAL_VALUE_POINTER (*bc_prop_p, new_bc_p);
|
||||
re_initialize_props (this_obj_p, pattern_string_p, flags);
|
||||
ecma_free_value (obj_this);
|
||||
ecma_deref_ecma_string (pattern_string_p);
|
||||
|
||||
return ECMA_VALUE_UNDEFINED;
|
||||
} /* ecma_builtin_regexp_prototype_compile */
|
||||
|
||||
#endif /* !CONFIG_DISABLE_ANNEXB_BUILTIN */
|
||||
@@ -232,48 +233,49 @@ static ecma_value_t
|
||||
ecma_builtin_regexp_prototype_exec (ecma_value_t this_arg, /**< this argument */
|
||||
ecma_value_t arg) /**< routine's argument */
|
||||
{
|
||||
ecma_value_t ret_value = ECMA_VALUE_EMPTY;
|
||||
|
||||
if (!ecma_is_value_object (this_arg)
|
||||
|| !ecma_object_class_is (ecma_get_object_from_value (this_arg), LIT_MAGIC_STRING_REGEXP_UL))
|
||||
{
|
||||
ret_value = ecma_raise_type_error (ECMA_ERR_MSG ("Incomplete RegExp type"));
|
||||
return ecma_raise_type_error (ECMA_ERR_MSG ("Incomplete RegExp type"));
|
||||
}
|
||||
|
||||
ecma_value_t obj_this = ecma_op_to_object (this_arg);
|
||||
if (ECMA_IS_VALUE_ERROR (obj_this))
|
||||
{
|
||||
return obj_this;
|
||||
}
|
||||
|
||||
ecma_value_t input_str_value = ecma_op_to_string (arg);
|
||||
if (ECMA_IS_VALUE_ERROR (input_str_value))
|
||||
{
|
||||
ecma_free_value (obj_this);
|
||||
return input_str_value;
|
||||
}
|
||||
|
||||
ecma_object_t *obj_p = ecma_get_object_from_value (obj_this);
|
||||
ecma_value_t *bytecode_prop_p = &(((ecma_extended_object_t *) obj_p)->u.class_prop.u.value);
|
||||
|
||||
void *bytecode_p = ECMA_GET_INTERNAL_VALUE_ANY_POINTER (void, *bytecode_prop_p);
|
||||
|
||||
ecma_value_t ret_value;
|
||||
if (bytecode_p == NULL)
|
||||
{
|
||||
/* Missing bytecode means empty RegExp: '/(?:)/', so always return empty string. */
|
||||
ecma_value_t empty_str_val = ecma_make_magic_string_value (LIT_MAGIC_STRING__EMPTY);
|
||||
ret_value = ecma_op_create_array_object (&empty_str_val, 1, false);
|
||||
re_set_result_array_properties (ecma_get_object_from_value (ret_value),
|
||||
ecma_get_string_from_value (input_str_value),
|
||||
1,
|
||||
0);
|
||||
}
|
||||
else
|
||||
{
|
||||
ECMA_TRY_CATCH (obj_this, ecma_op_to_object (this_arg), ret_value);
|
||||
|
||||
ECMA_TRY_CATCH (input_str_value,
|
||||
ecma_op_to_string (arg),
|
||||
ret_value);
|
||||
|
||||
ecma_object_t *obj_p = ecma_get_object_from_value (obj_this);
|
||||
ecma_value_t *bytecode_prop_p = &(((ecma_extended_object_t *) obj_p)->u.class_prop.u.value);
|
||||
|
||||
void *bytecode_p = ECMA_GET_INTERNAL_VALUE_ANY_POINTER (void, *bytecode_prop_p);
|
||||
|
||||
if (bytecode_p == NULL)
|
||||
{
|
||||
/* Missing bytecode means empty RegExp: '/(?:)/', so always return empty string. */
|
||||
ecma_value_t arguments_list[1];
|
||||
arguments_list[0] = ecma_make_magic_string_value (LIT_MAGIC_STRING__EMPTY);
|
||||
|
||||
ret_value = ecma_op_create_array_object (arguments_list, 1, false);
|
||||
|
||||
re_set_result_array_properties (ecma_get_object_from_value (ret_value),
|
||||
ecma_get_string_from_value (input_str_value),
|
||||
1,
|
||||
0);
|
||||
}
|
||||
else
|
||||
{
|
||||
ret_value = ecma_regexp_exec_helper (obj_this, input_str_value, false);
|
||||
}
|
||||
|
||||
ECMA_FINALIZE (input_str_value);
|
||||
ECMA_FINALIZE (obj_this);
|
||||
ret_value = ecma_regexp_exec_helper (obj_this, input_str_value, false);
|
||||
}
|
||||
|
||||
ecma_free_value (obj_this);
|
||||
ecma_free_value (input_str_value);
|
||||
|
||||
return ret_value;
|
||||
} /* ecma_builtin_regexp_prototype_exec */
|
||||
|
||||
|
||||
@@ -64,7 +64,6 @@ ecma_value_t
|
||||
ecma_builtin_regexp_dispatch_construct (const ecma_value_t *arguments_list_p, /**< arguments list */
|
||||
ecma_length_t arguments_list_len) /**< number of arguments */
|
||||
{
|
||||
ecma_value_t ret_value = ECMA_VALUE_EMPTY;
|
||||
ecma_value_t pattern_value = ECMA_VALUE_UNDEFINED;
|
||||
ecma_value_t flags_value = ECMA_VALUE_UNDEFINED;
|
||||
|
||||
@@ -84,54 +83,46 @@ ecma_builtin_regexp_dispatch_construct (const ecma_value_t *arguments_list_p, /*
|
||||
{
|
||||
if (ecma_is_value_undefined (flags_value))
|
||||
{
|
||||
ret_value = ecma_copy_value (pattern_value);
|
||||
}
|
||||
else
|
||||
{
|
||||
ret_value = ecma_raise_type_error (ECMA_ERR_MSG ("Invalid argument of RegExp call."));
|
||||
return ecma_copy_value (pattern_value);
|
||||
}
|
||||
|
||||
return ecma_raise_type_error (ECMA_ERR_MSG ("Invalid argument of RegExp call."));
|
||||
}
|
||||
else
|
||||
|
||||
ecma_string_t *pattern_string_p = NULL;
|
||||
ecma_value_t ret_value = ecma_regexp_read_pattern_str_helper (pattern_value, &pattern_string_p);
|
||||
if (ECMA_IS_VALUE_ERROR (ret_value))
|
||||
{
|
||||
ecma_string_t *pattern_string_p = NULL;
|
||||
ecma_string_t *flags_string_p = NULL;
|
||||
return ret_value;
|
||||
}
|
||||
JERRY_ASSERT (ecma_is_value_empty (ret_value));
|
||||
|
||||
ret_value = ecma_regexp_read_pattern_str_helper (pattern_value, &pattern_string_p);
|
||||
uint16_t flags = 0;
|
||||
if (!ecma_is_value_undefined (flags_value))
|
||||
{
|
||||
ecma_value_t flags_str_value = ecma_op_to_string (flags_value);
|
||||
|
||||
if (ecma_is_value_empty (ret_value) && !ecma_is_value_undefined (flags_value))
|
||||
{
|
||||
ECMA_TRY_CATCH (flags_str_value,
|
||||
ecma_op_to_string (flags_value),
|
||||
ret_value);
|
||||
|
||||
flags_string_p = ecma_get_string_from_value (flags_str_value);
|
||||
ecma_ref_ecma_string (flags_string_p);
|
||||
|
||||
ECMA_FINALIZE (flags_str_value);
|
||||
}
|
||||
|
||||
uint16_t flags = 0;
|
||||
if (ecma_is_value_empty (ret_value) && (flags_string_p != NULL))
|
||||
{
|
||||
ret_value = re_parse_regexp_flags (flags_string_p, &flags);
|
||||
}
|
||||
|
||||
if (ecma_is_value_empty (ret_value))
|
||||
{
|
||||
ret_value = ecma_op_create_regexp_object (pattern_string_p, flags);
|
||||
}
|
||||
|
||||
if (pattern_string_p != NULL)
|
||||
if (ECMA_IS_VALUE_ERROR (flags_str_value))
|
||||
{
|
||||
ecma_deref_ecma_string (pattern_string_p);
|
||||
return flags_str_value;
|
||||
}
|
||||
|
||||
if (flags_string_p != NULL)
|
||||
ecma_string_t *flags_string_p = ecma_get_string_from_value (flags_str_value);
|
||||
JERRY_ASSERT (flags_string_p != NULL);
|
||||
ret_value = re_parse_regexp_flags (flags_string_p, &flags);
|
||||
ecma_free_value (flags_str_value); // implicit frees flags_string_p
|
||||
|
||||
if (ECMA_IS_VALUE_ERROR (ret_value))
|
||||
{
|
||||
ecma_deref_ecma_string (flags_string_p);
|
||||
ecma_deref_ecma_string (pattern_string_p);
|
||||
return ret_value;
|
||||
}
|
||||
JERRY_ASSERT (ecma_is_value_empty (ret_value));
|
||||
}
|
||||
|
||||
ret_value = ecma_op_create_regexp_object (pattern_string_p, flags);
|
||||
ecma_deref_ecma_string (pattern_string_p);
|
||||
return ret_value;
|
||||
} /* ecma_builtin_regexp_dispatch_construct */
|
||||
|
||||
|
||||
Reference in New Issue
Block a user