Fixing retrieval of [[Class]] properties for built-in function objects, optimizing memory related to [[Class]] property.
- introduced ecma_object_get_class_name interface; - removed creation of [[Class]] internal property for types of objects that unambiguously determine the [[Class]] value. Related issue: #112 JerryScript-DCO-1.0-Signed-off-by: Ruben Ayrapetyan r.ayrapetyan@samsung.com
This commit is contained in:
@@ -110,8 +110,11 @@ ecma_op_create_array_object (const ecma_value_t *arguments_list_p, /**< list of
|
||||
ecma_object_t *obj_p = ecma_create_object (array_prototype_obj_p, true, ECMA_OBJECT_TYPE_ARRAY);
|
||||
ecma_deref_object (array_prototype_obj_p);
|
||||
|
||||
ecma_property_t *class_prop_p = ecma_create_internal_property (obj_p, ECMA_INTERNAL_PROPERTY_CLASS);
|
||||
class_prop_p->u.internal_property.value = ECMA_MAGIC_STRING_ARRAY_UL;
|
||||
/*
|
||||
* [[Class]] property is not stored explicitly for objects of ECMA_OBJECT_TYPE_ARRAY type.
|
||||
*
|
||||
* See also: ecma_object_get_class_name
|
||||
*/
|
||||
|
||||
ecma_string_t *length_magic_string_p = ecma_get_magic_string (ECMA_MAGIC_STRING_LENGTH);
|
||||
ecma_number_t *length_num_p = ecma_alloc_number ();
|
||||
|
||||
@@ -176,8 +176,11 @@ ecma_op_create_function_object (ecma_string_t* formal_parameter_list_p[], /**< f
|
||||
*/
|
||||
|
||||
// 3.
|
||||
ecma_property_t *class_prop_p = ecma_create_internal_property (f, ECMA_INTERNAL_PROPERTY_CLASS);
|
||||
class_prop_p->u.internal_property.value = ECMA_MAGIC_STRING_FUNCTION_UL;
|
||||
/*
|
||||
* [[Class]] property is not stored explicitly for objects of ECMA_OBJECT_TYPE_FUNCTION type.
|
||||
*
|
||||
* See also: ecma_object_get_class_name
|
||||
*/
|
||||
|
||||
// 9.
|
||||
ecma_property_t *scope_prop_p = ecma_create_internal_property (f, ECMA_INTERNAL_PROPERTY_SCOPE);
|
||||
@@ -321,8 +324,11 @@ ecma_op_create_external_function_object (ecma_external_pointer_t code_p) /**< po
|
||||
|
||||
ecma_deref_object (prototype_obj_p);
|
||||
|
||||
ecma_property_t *class_prop_p = ecma_create_internal_property (function_obj_p, ECMA_INTERNAL_PROPERTY_CLASS);
|
||||
class_prop_p->u.internal_property.value = ECMA_MAGIC_STRING_FUNCTION_UL;
|
||||
/*
|
||||
* [[Class]] property is not stored explicitly for objects of ECMA_OBJECT_TYPE_EXTERNAL_FUNCTION type.
|
||||
*
|
||||
* See also: ecma_object_get_class_name
|
||||
*/
|
||||
|
||||
bool is_created = ecma_create_external_pointer_property (function_obj_p,
|
||||
ECMA_INTERNAL_PROPERTY_NATIVE_CODE,
|
||||
@@ -751,12 +757,17 @@ ecma_op_function_construct_simple_or_external (ecma_object_t *func_obj_p, /**< F
|
||||
// 1., 2., 4.
|
||||
ecma_object_t *obj_p = ecma_create_object (prototype_p, true, ECMA_OBJECT_TYPE_GENERAL);
|
||||
|
||||
// 3.
|
||||
ecma_property_t *class_prop_p = ecma_create_internal_property (obj_p, ECMA_INTERNAL_PROPERTY_CLASS);
|
||||
class_prop_p->u.internal_property.value = ECMA_MAGIC_STRING_OBJECT_UL;
|
||||
|
||||
ecma_deref_object (prototype_p);
|
||||
|
||||
// 3.
|
||||
/*
|
||||
* [[Class]] property of ECMA_OBJECT_TYPE_GENERAL type objects
|
||||
* without ECMA_INTERNAL_PROPERTY_CLASS internal property
|
||||
* is "Object".
|
||||
*
|
||||
* See also: ecma_object_get_class_name.
|
||||
*/
|
||||
|
||||
// 8.
|
||||
ECMA_TRY_CATCH (call_completion,
|
||||
ecma_op_function_call (func_obj_p,
|
||||
|
||||
@@ -200,6 +200,13 @@ ecma_op_create_arguments_object (ecma_object_t *func_obj_p, /**< callee function
|
||||
// 12.
|
||||
ecma_set_object_type (obj_p, ECMA_OBJECT_TYPE_ARGUMENTS);
|
||||
|
||||
/*
|
||||
* [[Class]] property is not stored explicitly for objects of ECMA_OBJECT_TYPE_ARGUMENTS type.
|
||||
*
|
||||
* See also: ecma_object_get_class_name
|
||||
*/
|
||||
ecma_delete_property (obj_p, class_prop_p);
|
||||
|
||||
ecma_property_t *parameters_map_prop_p = ecma_create_internal_property (obj_p,
|
||||
ECMA_INTERNAL_PROPERTY_PARAMETERS_MAP);
|
||||
ECMA_SET_POINTER (parameters_map_prop_p->u.internal_property.value, map_p);
|
||||
|
||||
@@ -66,8 +66,13 @@ ecma_op_create_object_object_noarg (void)
|
||||
|
||||
ecma_deref_object (object_prototype_p);
|
||||
|
||||
ecma_property_t *class_prop_p = ecma_create_internal_property (obj_p, ECMA_INTERNAL_PROPERTY_CLASS);
|
||||
class_prop_p->u.internal_property.value = ECMA_MAGIC_STRING_OBJECT_UL;
|
||||
/*
|
||||
* [[Class]] property of ECMA_OBJECT_TYPE_GENERAL type objects
|
||||
* without ECMA_INTERNAL_PROPERTY_CLASS internal property
|
||||
* is "Object".
|
||||
*
|
||||
* See also: ecma_object_get_class_name
|
||||
*/
|
||||
|
||||
return obj_p;
|
||||
} /* ecma_op_create_object_object_noarg */
|
||||
@@ -503,11 +508,7 @@ ecma_op_general_object_default_value (ecma_object_t *obj_p, /**< the object */
|
||||
|
||||
if (hint == ECMA_PREFERRED_TYPE_NO)
|
||||
{
|
||||
ecma_property_t *class_prop_p = ecma_get_internal_property (obj_p,
|
||||
ECMA_INTERNAL_PROPERTY_CLASS);
|
||||
ecma_magic_string_id_t obj_class = (ecma_magic_string_id_t) class_prop_p->u.internal_property.value;
|
||||
|
||||
if (obj_class == ECMA_MAGIC_STRING_DATE_UL)
|
||||
if (ecma_object_get_class_name (obj_p) == ECMA_MAGIC_STRING_DATE_UL)
|
||||
{
|
||||
hint = ECMA_PREFERRED_TYPE_STRING;
|
||||
}
|
||||
|
||||
@@ -504,8 +504,6 @@ ecma_op_object_has_instance (ecma_object_t *obj_p, /**< the object */
|
||||
JERRY_UNREACHABLE ();
|
||||
} /* ecma_op_object_has_instance */
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Object's isPrototypeOf operation
|
||||
*
|
||||
@@ -533,6 +531,204 @@ ecma_op_object_is_prototype_of (ecma_object_t *base_p, /** < base object */
|
||||
} while (true);
|
||||
} /* ecma_op_object_is_prototype_of */
|
||||
|
||||
/**
|
||||
* Get [[Class]] string of specified object
|
||||
*
|
||||
* @return class name magic string
|
||||
*/
|
||||
ecma_magic_string_id_t
|
||||
ecma_object_get_class_name (ecma_object_t *obj_p) /**< object */
|
||||
{
|
||||
ecma_object_type_t type = ecma_get_object_type (obj_p);
|
||||
|
||||
switch (type)
|
||||
{
|
||||
case ECMA_OBJECT_TYPE_ARRAY:
|
||||
{
|
||||
return ECMA_MAGIC_STRING_ARRAY_UL;
|
||||
}
|
||||
case ECMA_OBJECT_TYPE_STRING:
|
||||
{
|
||||
return ECMA_MAGIC_STRING_STRING_UL;
|
||||
}
|
||||
case ECMA_OBJECT_TYPE_ARGUMENTS:
|
||||
{
|
||||
return ECMA_MAGIC_STRING_ARGUMENTS_UL;
|
||||
}
|
||||
case ECMA_OBJECT_TYPE_EXTENSION:
|
||||
{
|
||||
return ECMA_MAGIC_STRING_OBJECT_UL;
|
||||
}
|
||||
case ECMA_OBJECT_TYPE_FUNCTION:
|
||||
{
|
||||
ecma_magic_string_id_t class_name;
|
||||
|
||||
if (ecma_get_object_is_builtin (obj_p))
|
||||
{
|
||||
ecma_property_t *built_in_id_prop_p = ecma_get_internal_property (obj_p,
|
||||
ECMA_INTERNAL_PROPERTY_BUILT_IN_ID);
|
||||
ecma_builtin_id_t builtin_id = (ecma_builtin_id_t) built_in_id_prop_p->u.internal_property.value;
|
||||
|
||||
switch (builtin_id)
|
||||
{
|
||||
case ECMA_BUILTIN_ID_OBJECT:
|
||||
{
|
||||
class_name = ECMA_MAGIC_STRING_OBJECT_UL;
|
||||
break;
|
||||
}
|
||||
#ifndef CONFIG_ECMA_COMPACT_PROFILE_DISABLE_ARRAY_BUILTIN
|
||||
case ECMA_BUILTIN_ID_ARRAY:
|
||||
{
|
||||
class_name = ECMA_MAGIC_STRING_ARRAY_UL;
|
||||
break;
|
||||
}
|
||||
#endif /* !CONFIG_ECMA_COMPACT_PROFILE_DISABLE_ARRAY_BUILTIN */
|
||||
#ifndef CONFIG_ECMA_COMPACT_PROFILE_DISABLE_STRING_BUILTIN
|
||||
case ECMA_BUILTIN_ID_STRING:
|
||||
{
|
||||
class_name = ECMA_MAGIC_STRING_STRING_UL;
|
||||
break;
|
||||
}
|
||||
#endif /* !CONFIG_ECMA_COMPACT_PROFILE_DISABLE_STRING_BUILTIN */
|
||||
#ifndef CONFIG_ECMA_COMPACT_PROFILE_DISABLE_BOOLEAN_BUILTIN
|
||||
case ECMA_BUILTIN_ID_BOOLEAN:
|
||||
{
|
||||
class_name = ECMA_MAGIC_STRING_BOOLEAN_UL;
|
||||
break;
|
||||
}
|
||||
#endif /* !CONFIG_ECMA_COMPACT_PROFILE_DISABLE_BOOLEAN_BUILTIN */
|
||||
#ifndef CONFIG_ECMA_COMPACT_PROFILE_DISABLE_NUMBER_BUILTIN
|
||||
case ECMA_BUILTIN_ID_NUMBER:
|
||||
{
|
||||
class_name = ECMA_MAGIC_STRING_NUMBER_UL;
|
||||
break;
|
||||
}
|
||||
#endif /* !CONFIG_ECMA_COMPACT_PROFILE_DISABLE_NUMBER_BUILTIN */
|
||||
case ECMA_BUILTIN_ID_FUNCTION:
|
||||
{
|
||||
class_name = ECMA_MAGIC_STRING_FUNCTION_UL;
|
||||
break;
|
||||
}
|
||||
#ifdef CONFIG_ECMA_COMPACT_PROFILE
|
||||
case ECMA_BUILTIN_ID_COMPACT_PROFILE_ERROR:
|
||||
{
|
||||
class_name = ECMA_MAGIC_STRING_COMPACT_PROFILE_ERROR_UL;
|
||||
break;
|
||||
}
|
||||
#endif /* CONFIG_ECMA_COMPACT_PROFILE */
|
||||
#ifndef CONFIG_ECMA_COMPACT_PROFILE_DISABLE_ERROR_BUILTINS
|
||||
case ECMA_BUILTIN_ID_ERROR:
|
||||
case ECMA_BUILTIN_ID_EVAL_ERROR:
|
||||
case ECMA_BUILTIN_ID_RANGE_ERROR:
|
||||
case ECMA_BUILTIN_ID_REFERENCE_ERROR:
|
||||
case ECMA_BUILTIN_ID_SYNTAX_ERROR:
|
||||
case ECMA_BUILTIN_ID_TYPE_ERROR:
|
||||
case ECMA_BUILTIN_ID_URI_ERROR:
|
||||
{
|
||||
class_name = ECMA_MAGIC_STRING_ERROR_UL;
|
||||
break;
|
||||
}
|
||||
#endif /* !CONFIG_ECMA_COMPACT_PROFILE_DISABLE_ERROR_BUILTINS */
|
||||
default:
|
||||
{
|
||||
JERRY_ASSERT (builtin_id == ECMA_BUILTIN_ID_TYPE_ERROR_THROWER);
|
||||
|
||||
class_name = ECMA_MAGIC_STRING_FUNCTION_UL;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
class_name = ECMA_MAGIC_STRING_FUNCTION_UL;
|
||||
}
|
||||
|
||||
return class_name;
|
||||
}
|
||||
case ECMA_OBJECT_TYPE_BOUND_FUNCTION:
|
||||
case ECMA_OBJECT_TYPE_EXTERNAL_FUNCTION:
|
||||
case ECMA_OBJECT_TYPE_BUILT_IN_FUNCTION:
|
||||
{
|
||||
return ECMA_MAGIC_STRING_FUNCTION_UL;
|
||||
}
|
||||
default:
|
||||
{
|
||||
JERRY_ASSERT (type == ECMA_OBJECT_TYPE_GENERAL);
|
||||
|
||||
if (ecma_get_object_is_builtin (obj_p))
|
||||
{
|
||||
ecma_property_t *built_in_id_prop_p = ecma_get_internal_property (obj_p,
|
||||
ECMA_INTERNAL_PROPERTY_BUILT_IN_ID);
|
||||
ecma_builtin_id_t builtin_id = (ecma_builtin_id_t) built_in_id_prop_p->u.internal_property.value;
|
||||
|
||||
switch (builtin_id)
|
||||
{
|
||||
case ECMA_BUILTIN_ID_OBJECT_PROTOTYPE:
|
||||
{
|
||||
return ECMA_MAGIC_STRING_OBJECT_UL;
|
||||
}
|
||||
#ifndef CONFIG_ECMA_COMPACT_PROFILE_DISABLE_STRING_BUILTIN
|
||||
case ECMA_BUILTIN_ID_STRING_PROTOTYPE:
|
||||
{
|
||||
return ECMA_MAGIC_STRING_STRING_UL;
|
||||
}
|
||||
#endif /* !CONFIG_ECMA_COMPACT_PROFILE_DISABLE_STRING_BUILTIN */
|
||||
#ifndef CONFIG_ECMA_COMPACT_PROFILE_DISABLE_BOOLEAN_BUILTIN
|
||||
case ECMA_BUILTIN_ID_BOOLEAN_PROTOTYPE:
|
||||
{
|
||||
return ECMA_MAGIC_STRING_BOOLEAN_UL;
|
||||
}
|
||||
#endif /* !CONFIG_ECMA_COMPACT_PROFILE_DISABLE_BOOLEAN_BUILTIN */
|
||||
#ifndef CONFIG_ECMA_COMPACT_PROFILE_DISABLE_NUMBER_BUILTIN
|
||||
case ECMA_BUILTIN_ID_NUMBER_PROTOTYPE:
|
||||
{
|
||||
return ECMA_MAGIC_STRING_NUMBER_UL;
|
||||
}
|
||||
#endif /* !CONFIG_ECMA_COMPACT_PROFILE_DISABLE_NUMBER_BUILTIN */
|
||||
#ifndef CONFIG_ECMA_COMPACT_PROFILE_DISABLE_MATH_BUILTIN
|
||||
case ECMA_BUILTIN_ID_MATH:
|
||||
{
|
||||
return ECMA_MAGIC_STRING_MATH_UL;
|
||||
}
|
||||
#endif /* !CONFIG_ECMA_COMPACT_PROFILE_DISABLE_MATH_BUILTIN */
|
||||
#ifndef CONFIG_ECMA_COMPACT_PROFILE_DISABLE_ERROR_BUILTINS
|
||||
case ECMA_BUILTIN_ID_ERROR_PROTOTYPE:
|
||||
case ECMA_BUILTIN_ID_EVAL_ERROR_PROTOTYPE:
|
||||
case ECMA_BUILTIN_ID_RANGE_ERROR_PROTOTYPE:
|
||||
case ECMA_BUILTIN_ID_REFERENCE_ERROR_PROTOTYPE:
|
||||
case ECMA_BUILTIN_ID_SYNTAX_ERROR_PROTOTYPE:
|
||||
case ECMA_BUILTIN_ID_TYPE_ERROR_PROTOTYPE:
|
||||
case ECMA_BUILTIN_ID_URI_ERROR_PROTOTYPE:
|
||||
{
|
||||
return ECMA_MAGIC_STRING_ERROR_UL;
|
||||
}
|
||||
#endif /* !CONFIG_ECMA_COMPACT_PROFILE_DISABLE_ERROR_BUILTINS */
|
||||
default:
|
||||
{
|
||||
JERRY_ASSERT (ecma_builtin_is (obj_p, ECMA_BUILTIN_ID_GLOBAL)
|
||||
|| ecma_builtin_is (obj_p, ECMA_BUILTIN_ID_JERRY));
|
||||
|
||||
return ECMA_MAGIC_STRING_OBJECT_UL;
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
ecma_property_t *class_name_prop_p = ecma_find_internal_property (obj_p,
|
||||
ECMA_INTERNAL_PROPERTY_CLASS);
|
||||
|
||||
if (class_name_prop_p == NULL)
|
||||
{
|
||||
return ECMA_MAGIC_STRING_OBJECT_UL;
|
||||
}
|
||||
else
|
||||
{
|
||||
return (ecma_magic_string_id_t) class_name_prop_p->u.internal_property.value;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
} /* ecma_object_get_class_name */
|
||||
|
||||
/**
|
||||
* @}
|
||||
|
||||
@@ -47,6 +47,8 @@ extern ecma_completion_value_t ecma_op_object_has_instance (ecma_object_t *obj_p
|
||||
ecma_value_t value);
|
||||
extern bool ecma_op_object_is_prototype_of (ecma_object_t *base_p, ecma_object_t *target_p);
|
||||
|
||||
extern ecma_magic_string_id_t ecma_object_get_class_name (ecma_object_t *obj_p);
|
||||
|
||||
/**
|
||||
* @}
|
||||
* @}
|
||||
|
||||
@@ -88,8 +88,11 @@ ecma_op_create_string_object (const ecma_value_t *arguments_list_p, /**< list of
|
||||
ECMA_OBJECT_TYPE_STRING);
|
||||
ecma_deref_object (prototype_obj_p);
|
||||
|
||||
ecma_property_t *class_prop_p = ecma_create_internal_property (obj_p, ECMA_INTERNAL_PROPERTY_CLASS);
|
||||
class_prop_p->u.internal_property.value = ECMA_MAGIC_STRING_STRING_UL;
|
||||
/*
|
||||
* [[Class]] property is not stored explicitly for objects of ECMA_OBJECT_TYPE_STRING type.
|
||||
*
|
||||
* See also: ecma_object_get_class_name
|
||||
*/
|
||||
|
||||
ecma_property_t *prim_value_prop_p = ecma_create_internal_property (obj_p,
|
||||
ECMA_INTERNAL_PROPERTY_PRIMITIVE_STRING_VALUE);
|
||||
|
||||
Reference in New Issue
Block a user