Fix the types of builtin prototype objects (#3663)
In ES2015 many builtin prototypes are no longer valid instances of their respective classes. This change updates affected prototypes to be regular objects as required. JerryScript-DCO-1.0-Signed-off-by: Dániel Bátyai dbatyai@inf.u-szeged.hu
This commit is contained in:
@@ -616,12 +616,10 @@ ecma_builtin_date_prototype_dispatch_routine (uint16_t builtin_routine_id, /**<
|
||||
if (!ecma_is_value_object (this_arg)
|
||||
|| !ecma_object_class_is (ecma_get_object_from_value (this_arg), LIT_MAGIC_STRING_DATE_UL))
|
||||
{
|
||||
return ecma_raise_type_error (ECMA_ERR_MSG ("Date object expected"));
|
||||
return ecma_raise_type_error (ECMA_ERR_MSG ("'this' is not a Date object"));
|
||||
}
|
||||
|
||||
ecma_object_t *object_p = ecma_get_object_from_value (this_arg);
|
||||
|
||||
ecma_extended_object_t *ext_object_p = (ecma_extended_object_t *) object_p;
|
||||
ecma_extended_object_t *ext_object_p = (ecma_extended_object_t *) ecma_get_object_from_value (this_arg);
|
||||
ecma_number_t *prim_value_p = ECMA_GET_INTERNAL_VALUE_POINTER (ecma_number_t,
|
||||
ext_object_p->u.class_prop.u.value);
|
||||
|
||||
|
||||
@@ -60,23 +60,17 @@ static ecma_value_t
|
||||
ecma_builtin_regexp_prototype_flags_helper (ecma_value_t this, /**< this value */
|
||||
uint16_t *flags_p) /**< [out] flags */
|
||||
{
|
||||
ecma_extended_object_t *ext_obj_p = ecma_op_check_object_type_is_class (this);
|
||||
|
||||
if (ext_obj_p != NULL)
|
||||
if (!ecma_object_is_regexp_object (this))
|
||||
{
|
||||
if (ext_obj_p->u.class_prop.class_id == LIT_MAGIC_STRING_REGEXP_UL
|
||||
|| ext_obj_p->u.class_prop.class_id == LIT_INTERNAL_MAGIC_STRING_REGEXP_PROTO)
|
||||
{
|
||||
re_compiled_code_t *bc_p = ECMA_GET_INTERNAL_VALUE_POINTER (re_compiled_code_t,
|
||||
ext_obj_p->u.class_prop.u.value);
|
||||
|
||||
*flags_p = bc_p->header.status_flags;
|
||||
|
||||
return ECMA_VALUE_EMPTY;
|
||||
}
|
||||
return ecma_raise_type_error (ECMA_ERR_MSG ("'this' is not a RegExp object"));
|
||||
}
|
||||
|
||||
return ecma_raise_type_error (ECMA_ERR_MSG ("Incompatible type"));
|
||||
ecma_extended_object_t *re_obj_p = (ecma_extended_object_t *) ecma_get_object_from_value (this);
|
||||
re_compiled_code_t *bc_p = ECMA_GET_INTERNAL_VALUE_POINTER (re_compiled_code_t,
|
||||
re_obj_p->u.class_prop.u.value);
|
||||
|
||||
*flags_p = bc_p->header.status_flags;
|
||||
return ECMA_VALUE_EMPTY;
|
||||
} /* ecma_builtin_regexp_prototype_flags_helper */
|
||||
|
||||
/**
|
||||
@@ -222,21 +216,16 @@ ecma_op_escape_regexp_pattern (ecma_string_t *pattern_str_p) /**< RegExp pattern
|
||||
static ecma_value_t
|
||||
ecma_builtin_regexp_prototype_get_source (ecma_value_t this_arg) /**< this argument */
|
||||
{
|
||||
ecma_extended_object_t *ext_obj_p = ecma_op_check_object_type_is_class (this_arg);
|
||||
|
||||
if (ext_obj_p != NULL)
|
||||
if (!ecma_object_is_regexp_object (this_arg))
|
||||
{
|
||||
if (ext_obj_p->u.class_prop.class_id == LIT_MAGIC_STRING_REGEXP_UL
|
||||
|| ext_obj_p->u.class_prop.class_id == LIT_INTERNAL_MAGIC_STRING_REGEXP_PROTO)
|
||||
{
|
||||
re_compiled_code_t *bc_p = ECMA_GET_INTERNAL_VALUE_POINTER (re_compiled_code_t,
|
||||
ext_obj_p->u.class_prop.u.value);
|
||||
|
||||
return ecma_op_escape_regexp_pattern (ecma_get_string_from_value (bc_p->source));
|
||||
}
|
||||
return ecma_raise_type_error (ECMA_ERR_MSG ("'this' is not a RegExp object"));
|
||||
}
|
||||
|
||||
return ecma_raise_type_error (ECMA_ERR_MSG ("Incompatible type"));
|
||||
ecma_extended_object_t *re_obj_p = (ecma_extended_object_t *) ecma_get_object_from_value (this_arg);
|
||||
re_compiled_code_t *bc_p = ECMA_GET_INTERNAL_VALUE_POINTER (re_compiled_code_t,
|
||||
re_obj_p->u.class_prop.u.value);
|
||||
|
||||
return ecma_op_escape_regexp_pattern (ecma_get_string_from_value (bc_p->source));
|
||||
} /* ecma_builtin_regexp_prototype_get_source */
|
||||
|
||||
/**
|
||||
@@ -389,11 +378,13 @@ ecma_builtin_regexp_prototype_compile (ecma_value_t this_arg, /**< this argument
|
||||
#endif /* !ENABLED (JERRY_ES2015) */
|
||||
)
|
||||
{
|
||||
return ecma_raise_type_error (ECMA_ERR_MSG ("Incompatible type"));
|
||||
return ecma_raise_type_error (ECMA_ERR_MSG ("'this' is not a RegExp object"));
|
||||
}
|
||||
|
||||
ecma_object_t *this_obj_p = ecma_get_object_from_value (this_arg);
|
||||
ecma_ref_object (this_obj_p);
|
||||
ecma_extended_object_t *regexp_obj_p = (ecma_extended_object_t *) this_obj_p;
|
||||
re_compiled_code_t *old_bc_p = ECMA_GET_INTERNAL_VALUE_POINTER (re_compiled_code_t,
|
||||
regexp_obj_p->u.class_prop.u.value);
|
||||
|
||||
ecma_value_t status = ecma_builtin_helper_def_prop (this_obj_p,
|
||||
ecma_get_magic_string (LIT_MAGIC_STRING_LASTINDEX_UL),
|
||||
@@ -406,7 +397,6 @@ ecma_builtin_regexp_prototype_compile (ecma_value_t this_arg, /**< this argument
|
||||
{
|
||||
if (!ecma_is_value_undefined (flags_arg))
|
||||
{
|
||||
ecma_deref_object (this_obj_p);
|
||||
return ecma_raise_type_error (ECMA_ERR_MSG ("Invalid argument"));
|
||||
}
|
||||
|
||||
@@ -414,14 +404,19 @@ ecma_builtin_regexp_prototype_compile (ecma_value_t this_arg, /**< this argument
|
||||
re_compiled_code_t *bc_p = ECMA_GET_INTERNAL_VALUE_POINTER (re_compiled_code_t,
|
||||
pattern_obj_p->u.class_prop.u.value);
|
||||
|
||||
ecma_ref_object (this_obj_p);
|
||||
/* ecma_op_create_regexp_from_bytecode will never throw an error while re-initalizing the regexp object, so we
|
||||
* can deref the old bytecode without leaving a dangling pointer. */
|
||||
ecma_bytecode_deref ((ecma_compiled_code_t *) old_bc_p);
|
||||
return ecma_op_create_regexp_from_bytecode (this_obj_p, bc_p);
|
||||
}
|
||||
|
||||
ecma_value_t ret_value = ecma_op_create_regexp_from_pattern (this_obj_p, pattern_arg, flags_arg);
|
||||
|
||||
if (ECMA_IS_VALUE_ERROR (ret_value))
|
||||
if (!ECMA_IS_VALUE_ERROR (ret_value))
|
||||
{
|
||||
ecma_deref_object (this_obj_p);
|
||||
ecma_ref_object (this_obj_p);
|
||||
ecma_bytecode_deref ((ecma_compiled_code_t *) old_bc_p);
|
||||
}
|
||||
|
||||
return ret_value;
|
||||
@@ -567,22 +562,11 @@ ecma_builtin_regexp_prototype_to_string (ecma_value_t this_arg) /**< this argume
|
||||
ecma_object_t *obj_p = ecma_get_object_from_value (this_arg);
|
||||
ecma_extended_object_t *re_obj_p = (ecma_extended_object_t *) obj_p;
|
||||
|
||||
re_compiled_code_t *bc_p = ECMA_GET_INTERNAL_VALUE_ANY_POINTER (re_compiled_code_t,
|
||||
re_obj_p->u.class_prop.u.value);
|
||||
re_compiled_code_t *bc_p = ECMA_GET_INTERNAL_VALUE_POINTER (re_compiled_code_t,
|
||||
re_obj_p->u.class_prop.u.value);
|
||||
|
||||
ecma_string_t *source_p;
|
||||
uint16_t flags;
|
||||
|
||||
if (bc_p != NULL)
|
||||
{
|
||||
source_p = ecma_get_string_from_value (bc_p->source);
|
||||
flags = bc_p->header.status_flags;
|
||||
}
|
||||
else
|
||||
{
|
||||
source_p = ecma_get_magic_string (LIT_MAGIC_STRING_EMPTY_NON_CAPTURE_GROUP);
|
||||
flags = RE_FLAG_EMPTY;
|
||||
}
|
||||
ecma_string_t *source_p = ecma_get_string_from_value (bc_p->source);
|
||||
uint16_t flags = bc_p->header.status_flags;
|
||||
|
||||
ecma_stringbuilder_t result = ecma_stringbuilder_create ();
|
||||
ecma_stringbuilder_append_byte (&result, LIT_CHAR_SLASH);
|
||||
|
||||
@@ -445,6 +445,7 @@ ecma_instantiate_builtin (ecma_builtin_id_t obj_builtin_id) /**< built-in id */
|
||||
}
|
||||
#endif /* ENABLED (JERRY_BUILTIN_ARRAY) */
|
||||
|
||||
#if !ENABLED (JERRY_ES2015)
|
||||
#if ENABLED (JERRY_BUILTIN_STRING)
|
||||
case ECMA_BUILTIN_ID_STRING_PROTOTYPE:
|
||||
{
|
||||
@@ -502,35 +503,21 @@ ecma_instantiate_builtin (ecma_builtin_id_t obj_builtin_id) /**< built-in id */
|
||||
JERRY_ASSERT (obj_type == ECMA_OBJECT_TYPE_CLASS);
|
||||
ecma_extended_object_t *ext_object_p = (ecma_extended_object_t *) obj_p;
|
||||
|
||||
#if ENABLED (JERRY_ES2015)
|
||||
ext_object_p->u.class_prop.class_id = LIT_INTERNAL_MAGIC_STRING_REGEXP_PROTO;
|
||||
#else /* !ENABLED (JERRY_ES2015) */
|
||||
ext_object_p->u.class_prop.class_id = LIT_MAGIC_STRING_REGEXP_UL;
|
||||
#endif /* ENABLED (JERRY_ES2015) */
|
||||
|
||||
/* In the ECMA v6 version, we create a dummy bytecode for the RegExp prototype object for backwards compatibility,
|
||||
* so we can use the existing methods to get the source and flags from the [[OriginalSource]] and [[OriginalFlags]]
|
||||
* internal properties.
|
||||
*/
|
||||
#if ENABLED (JERRY_ES2015)
|
||||
re_compiled_code_t *bc_p = (re_compiled_code_t *) jmem_heap_alloc_block (ECMA_REGEXP_PROTO_COMPILED_CODE_SIZE);
|
||||
|
||||
bc_p->header.status_flags = RE_FLAG_EMPTY;
|
||||
bc_p->source = ecma_make_magic_string_value (LIT_MAGIC_STRING_EMPTY_NON_CAPTURE_GROUP);
|
||||
#else /* !ENABLED (JERRY_ES2015) */
|
||||
const re_compiled_code_t *bc_p = NULL;
|
||||
ecma_value_t ret_value = re_compile_bytecode (&bc_p,
|
||||
ecma_get_magic_string (LIT_MAGIC_STRING_EMPTY_NON_CAPTURE_GROUP),
|
||||
RE_FLAG_EMPTY);
|
||||
|
||||
JERRY_ASSERT (ecma_is_value_empty (ret_value));
|
||||
#endif /* ENABLED (JERRY_ES2015) */
|
||||
|
||||
ECMA_SET_INTERNAL_VALUE_POINTER (ext_object_p->u.class_prop.u.value, bc_p);
|
||||
|
||||
break;
|
||||
}
|
||||
#endif /* ENABLED (JERRY_BUILTIN_REGEXP) */
|
||||
#endif /* !ENABLED (JERRY_ES2015) */
|
||||
default:
|
||||
{
|
||||
JERRY_ASSERT (obj_type != ECMA_OBJECT_TYPE_CLASS);
|
||||
|
||||
@@ -46,14 +46,99 @@ BUILTIN_ROUTINE (ECMA_BUILTIN_ID_ARRAY,
|
||||
array)
|
||||
#endif /* ENABLED (JERRY_BUILTIN_ARRAY) */
|
||||
|
||||
#if ENABLED (JERRY_BUILTIN_STRING)
|
||||
#if ENABLED (JERRY_ES2015)
|
||||
# if ENABLED (JERRY_BUILTIN_STRING)
|
||||
/* The String.prototype object (21.1.3) */
|
||||
BUILTIN (ECMA_BUILTIN_ID_STRING_PROTOTYPE,
|
||||
ECMA_OBJECT_TYPE_GENERAL,
|
||||
ECMA_BUILTIN_ID_OBJECT_PROTOTYPE,
|
||||
true,
|
||||
string_prototype)
|
||||
# endif /* ENABLED (JERRY_BUILTIN_STRING) */
|
||||
|
||||
# if ENABLED (JERRY_BUILTIN_BOOLEAN)
|
||||
/* The Boolean.prototype object (19.3.3) */
|
||||
BUILTIN (ECMA_BUILTIN_ID_BOOLEAN_PROTOTYPE,
|
||||
ECMA_OBJECT_TYPE_GENERAL,
|
||||
ECMA_BUILTIN_ID_OBJECT_PROTOTYPE,
|
||||
true,
|
||||
boolean_prototype)
|
||||
# endif /* ENABLED (JERRY_BUILTIN_BOOLEAN) */
|
||||
|
||||
# if ENABLED (JERRY_BUILTIN_NUMBER)
|
||||
/* The Number.prototype object (20.1.3) */
|
||||
BUILTIN (ECMA_BUILTIN_ID_NUMBER_PROTOTYPE,
|
||||
ECMA_OBJECT_TYPE_GENERAL,
|
||||
ECMA_BUILTIN_ID_OBJECT_PROTOTYPE,
|
||||
true,
|
||||
number_prototype)
|
||||
# endif /* ENABLED (JERRY_BUILTIN_NUMBER) */
|
||||
|
||||
# if ENABLED (JERRY_BUILTIN_DATE)
|
||||
/* The Date.prototype object (20.3.4) */
|
||||
BUILTIN (ECMA_BUILTIN_ID_DATE_PROTOTYPE,
|
||||
ECMA_OBJECT_TYPE_GENERAL,
|
||||
ECMA_BUILTIN_ID_OBJECT_PROTOTYPE,
|
||||
true,
|
||||
date_prototype)
|
||||
# endif /* ENABLED (JERRY_BUILTIN_DATE) */
|
||||
|
||||
# if ENABLED (JERRY_BUILTIN_REGEXP)
|
||||
/* The RegExp.prototype object (21.2.5) */
|
||||
BUILTIN (ECMA_BUILTIN_ID_REGEXP_PROTOTYPE,
|
||||
ECMA_OBJECT_TYPE_GENERAL,
|
||||
ECMA_BUILTIN_ID_OBJECT_PROTOTYPE,
|
||||
true,
|
||||
regexp_prototype)
|
||||
# endif /* ENABLED (JERRY_BUILTIN_REGEXP) */
|
||||
#else /* !ENABLED (JERRY_ES2015) */
|
||||
# if ENABLED (JERRY_BUILTIN_STRING)
|
||||
/* The String.prototype object (15.5.4) */
|
||||
BUILTIN (ECMA_BUILTIN_ID_STRING_PROTOTYPE,
|
||||
ECMA_OBJECT_TYPE_CLASS,
|
||||
ECMA_BUILTIN_ID_OBJECT_PROTOTYPE,
|
||||
true,
|
||||
string_prototype)
|
||||
# endif /* ENABLED (JERRY_BUILTIN_STRING) */
|
||||
|
||||
# if ENABLED (JERRY_BUILTIN_BOOLEAN)
|
||||
/* The Boolean.prototype object (15.6.4) */
|
||||
BUILTIN (ECMA_BUILTIN_ID_BOOLEAN_PROTOTYPE,
|
||||
ECMA_OBJECT_TYPE_CLASS,
|
||||
ECMA_BUILTIN_ID_OBJECT_PROTOTYPE,
|
||||
true,
|
||||
boolean_prototype)
|
||||
# endif /* ENABLED (JERRY_BUILTIN_BOOLEAN) */
|
||||
|
||||
# if ENABLED (JERRY_BUILTIN_NUMBER)
|
||||
/* The Number.prototype object (15.7.4) */
|
||||
BUILTIN (ECMA_BUILTIN_ID_NUMBER_PROTOTYPE,
|
||||
ECMA_OBJECT_TYPE_CLASS,
|
||||
ECMA_BUILTIN_ID_OBJECT_PROTOTYPE,
|
||||
true,
|
||||
number_prototype)
|
||||
# endif /* ENABLED (JERRY_BUILTIN_NUMBER) */
|
||||
|
||||
# if ENABLED (JERRY_BUILTIN_DATE)
|
||||
/* The Date.prototype object (15.9.4) */
|
||||
BUILTIN (ECMA_BUILTIN_ID_DATE_PROTOTYPE,
|
||||
ECMA_OBJECT_TYPE_CLASS,
|
||||
ECMA_BUILTIN_ID_OBJECT_PROTOTYPE,
|
||||
true,
|
||||
date_prototype)
|
||||
# endif /* ENABLED (JERRY_BUILTIN_DATE) */
|
||||
|
||||
# if ENABLED (JERRY_BUILTIN_REGEXP)
|
||||
/* The RegExp.prototype object (15.10.6) */
|
||||
BUILTIN (ECMA_BUILTIN_ID_REGEXP_PROTOTYPE,
|
||||
ECMA_OBJECT_TYPE_CLASS,
|
||||
ECMA_BUILTIN_ID_OBJECT_PROTOTYPE,
|
||||
true,
|
||||
regexp_prototype)
|
||||
# endif /* ENABLED (JERRY_BUILTIN_REGEXP) */
|
||||
#endif /* !ENABLED (JERRY_ES2015) */
|
||||
|
||||
#if ENABLED (JERRY_BUILTIN_STRING)
|
||||
/* The String object (15.5.1) */
|
||||
BUILTIN_ROUTINE (ECMA_BUILTIN_ID_STRING,
|
||||
ECMA_OBJECT_TYPE_FUNCTION,
|
||||
@@ -63,13 +148,6 @@ BUILTIN_ROUTINE (ECMA_BUILTIN_ID_STRING,
|
||||
#endif /* ENABLED (JERRY_BUILTIN_STRING) */
|
||||
|
||||
#if ENABLED (JERRY_BUILTIN_BOOLEAN)
|
||||
/* The Boolean.prototype object (15.6.4) */
|
||||
BUILTIN (ECMA_BUILTIN_ID_BOOLEAN_PROTOTYPE,
|
||||
ECMA_OBJECT_TYPE_CLASS,
|
||||
ECMA_BUILTIN_ID_OBJECT_PROTOTYPE,
|
||||
true,
|
||||
boolean_prototype)
|
||||
|
||||
/* The Boolean object (15.6.1) */
|
||||
BUILTIN_ROUTINE (ECMA_BUILTIN_ID_BOOLEAN,
|
||||
ECMA_OBJECT_TYPE_FUNCTION,
|
||||
@@ -79,13 +157,6 @@ BUILTIN_ROUTINE (ECMA_BUILTIN_ID_BOOLEAN,
|
||||
#endif /* ENABLED (JERRY_BUILTIN_BOOLEAN) */
|
||||
|
||||
#if ENABLED (JERRY_BUILTIN_NUMBER)
|
||||
/* The Number.prototype object (15.7.4) */
|
||||
BUILTIN (ECMA_BUILTIN_ID_NUMBER_PROTOTYPE,
|
||||
ECMA_OBJECT_TYPE_CLASS,
|
||||
ECMA_BUILTIN_ID_OBJECT_PROTOTYPE,
|
||||
true,
|
||||
number_prototype)
|
||||
|
||||
/* The Number object (15.7.1) */
|
||||
BUILTIN_ROUTINE (ECMA_BUILTIN_ID_NUMBER,
|
||||
ECMA_OBJECT_TYPE_FUNCTION,
|
||||
@@ -137,13 +208,6 @@ BUILTIN (ECMA_BUILTIN_ID_JSON,
|
||||
#endif /* ENABLED (JERRY_BUILTIN_JSON) */
|
||||
|
||||
#if ENABLED (JERRY_BUILTIN_DATE)
|
||||
/* The Date.prototype object (15.9.4) */
|
||||
BUILTIN (ECMA_BUILTIN_ID_DATE_PROTOTYPE,
|
||||
ECMA_OBJECT_TYPE_CLASS,
|
||||
ECMA_BUILTIN_ID_OBJECT_PROTOTYPE,
|
||||
true,
|
||||
date_prototype)
|
||||
|
||||
/* The Date object (15.9.3) */
|
||||
BUILTIN_ROUTINE (ECMA_BUILTIN_ID_DATE,
|
||||
ECMA_OBJECT_TYPE_FUNCTION,
|
||||
@@ -153,13 +217,6 @@ BUILTIN_ROUTINE (ECMA_BUILTIN_ID_DATE,
|
||||
#endif /* ENABLED (JERRY_BUILTIN_DATE) */
|
||||
|
||||
#if ENABLED (JERRY_BUILTIN_REGEXP)
|
||||
/* The RegExp.prototype object (15.10.6) */
|
||||
BUILTIN (ECMA_BUILTIN_ID_REGEXP_PROTOTYPE,
|
||||
ECMA_OBJECT_TYPE_CLASS,
|
||||
ECMA_BUILTIN_ID_OBJECT_PROTOTYPE,
|
||||
true,
|
||||
regexp_prototype)
|
||||
|
||||
/* The RegExp object (15.10) */
|
||||
BUILTIN_ROUTINE (ECMA_BUILTIN_ID_REGEXP,
|
||||
ECMA_OBJECT_TYPE_FUNCTION,
|
||||
|
||||
Reference in New Issue
Block a user