Skip to content

Remove ECMA_OBJECT_TYPE_BUILT_IN_FUNCTION to free an object type. #1164

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 1 commit into from
Jun 24, 2016
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 4 additions & 6 deletions jerry-core/ecma/base/ecma-globals.h
Original file line number Diff line number Diff line change
Expand Up @@ -430,13 +430,11 @@ typedef enum
ECMA_OBJECT_TYPE_GENERAL = 0, /**< all objects that are not String (15.5), Function (15.3),
Arguments (10.6), Array (15.4) specification-defined objects */
ECMA_OBJECT_TYPE_FUNCTION = 1, /**< Function objects (15.3), created through 13.2 routine */
ECMA_OBJECT_TYPE_BUILT_IN_FUNCTION = 2, /** One of built-in functions described in section 15
* of ECMA-262 v5 specification */
ECMA_OBJECT_TYPE_EXTERNAL_FUNCTION = 2, /**< External (host) function object */
ECMA_OBJECT_TYPE_ARRAY = 3, /**< Array object (15.4) */
ECMA_OBJECT_TYPE_STRING = 4, /**< String objects (15.5) */
ECMA_OBJECT_TYPE_EXTERNAL_FUNCTION = 5, /**< External (host) function object */
ECMA_OBJECT_TYPE_BOUND_FUNCTION = 6, /**< Function objects (15.3), created through 15.3.4.5 routine */
ECMA_OBJECT_TYPE_ARGUMENTS = 7, /**< Arguments object (10.6) */
ECMA_OBJECT_TYPE_BOUND_FUNCTION = 5, /**< Function objects (15.3), created through 15.3.4.5 routine */
ECMA_OBJECT_TYPE_ARGUMENTS = 6, /**< Arguments object (10.6) */

ECMA_OBJECT_TYPE__MAX = ECMA_OBJECT_TYPE_ARGUMENTS /**< maximum value */
} ecma_object_type_t;
Expand All @@ -448,7 +446,7 @@ typedef enum
{
/* ECMA_OBJECT_TYPE_GENERAL (0) with built-in flag. */
/* ECMA_OBJECT_TYPE_FUNCTION (1) with built-in flag. */
/* ECMA_OBJECT_TYPE_BUILT_IN_FUNCTION (2) with built-in flag. */
/* ECMA_OBJECT_TYPE_EXTERNAL_FUNCTION (2) with built-in flag. */
/* ECMA_OBJECT_TYPE_ARRAY (3) with built-in flag. */
/* ECMA_OBJECT_TYPE_STRING (4) with built-in flag. */
ECMA_LEXICAL_ENVIRONMENT_DECLARATIVE = 5, /**< declarative lexical environment */
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -50,21 +50,11 @@
#undef ROUTINE_ARG_LIST_0
#undef ROUTINE_ARG

#define ECMA_BUILTIN_PROPERTY_NAME_INDEX(name) \
PASTE (PASTE (PASTE (PASTE (ecma_builtin_property_names, _), BUILTIN_UNDERSCORED_ID), _), name)

enum
{
#define SIMPLE_VALUE(name, simple_value, prop_attributes) \
ECMA_BUILTIN_PROPERTY_NAME_INDEX(name),
#define NUMBER_VALUE(name, number_value, prop_attributes) \
ECMA_BUILTIN_PROPERTY_NAME_INDEX(name),
#define STRING_VALUE(name, magic_string_id, prop_attributes) \
ECMA_BUILTIN_PROPERTY_NAME_INDEX(name),
#define OBJECT_VALUE(name, obj_builtin_id, prop_attributes) \
ECMA_BUILTIN_PROPERTY_NAME_INDEX(name),
PASTE (ECMA_ROUTINE_START_, BUILTIN_UNDERSCORED_ID) = ECMA_BUILTIN_ID__COUNT - 1,
#define ROUTINE(name, c_function_name, args_number, length_prop_value) \
ECMA_BUILTIN_PROPERTY_NAME_INDEX(name),
ECMA_ROUTINE_ ## name ## c_function_name,
#include BUILTIN_INC_HEADER_NAME
};

Expand All @@ -78,7 +68,7 @@ const ecma_builtin_property_descriptor_t PROPERTY_DESCRIPTOR_LIST_NAME[] =
name, \
ECMA_BUILTIN_PROPERTY_ROUTINE, \
ECMA_PROPERTY_CONFIGURABLE_WRITABLE, \
length_prop_value \
ECMA_ROUTINE_VALUE (ECMA_ROUTINE_ ## name ## c_function_name, length_prop_value) \
},
#define OBJECT_VALUE(name, obj_builtin_id, prop_attributes) \
{ \
Expand Down Expand Up @@ -148,7 +138,7 @@ DISPATCH_ROUTINE_ROUTINE_NAME (uint16_t builtin_routine_id, /**< built-in wide r
#define ROUTINE_ARG_LIST_3 ROUTINE_ARG_LIST_2, ROUTINE_ARG(3)
#define ROUTINE_ARG_LIST_NON_FIXED , arguments_list, arguments_number
#define ROUTINE(name, c_function_name, args_number, length_prop_value) \
case name: \
case ECMA_ROUTINE_ ## name ## c_function_name: \
{ \
return c_function_name (this_arg_value ROUTINE_ARG_LIST_ ## args_number); \
}
Expand Down
48 changes: 33 additions & 15 deletions jerry-core/ecma/builtin-objects/ecma-builtins.c
Original file line number Diff line number Diff line change
Expand Up @@ -87,6 +87,22 @@ ecma_builtin_get (ecma_builtin_id_t builtin_id) /**< id of built-in to check on
return ecma_builtin_objects[builtin_id];
} /* ecma_builtin_get */

/**
* Checks whether the given function is a built-in routine
*
* @return true if the function object is a built-in routine
* false otherwise
*/
inline bool __attr_always_inline___
ecma_builtin_function_is_routine (ecma_object_t *func_obj_p) /**< function object */
{
JERRY_ASSERT (ecma_get_object_type (func_obj_p) == ECMA_OBJECT_TYPE_FUNCTION);
JERRY_ASSERT (ecma_get_object_is_builtin (func_obj_p));

ecma_extended_object_t *ext_func_obj_p = (ecma_extended_object_t *) func_obj_p;
return (ext_func_obj_p->u.built_in.routine_id >= ECMA_BUILTIN_ID__COUNT);
} /* ecma_builtin_function_is_routine */

/**
* Initialize specified built-in object.
*
Expand All @@ -113,6 +129,7 @@ ecma_builtin_init_object (ecma_builtin_id_t obj_builtin_id, /**< built-in ID */

ecma_extended_object_t *ext_obj_p = (ecma_extended_object_t *) obj_p;
ext_obj_p->u.built_in.id = obj_builtin_id;
ext_obj_p->u.built_in.routine_id = obj_builtin_id;
ext_obj_p->u.built_in.instantiated_bitset = 0;

/** Initializing [[PrimitiveValue]] properties of built-in prototype objects */
Expand Down Expand Up @@ -285,12 +302,14 @@ ecma_builtin_make_function_object_for_routine (ecma_builtin_id_t builtin_id, /**
{
ecma_object_t *prototype_obj_p = ecma_builtin_get (ECMA_BUILTIN_ID_FUNCTION_PROTOTYPE);

ecma_object_t *func_obj_p = ecma_create_object (prototype_obj_p, true, true, ECMA_OBJECT_TYPE_BUILT_IN_FUNCTION);
ecma_object_t *func_obj_p = ecma_create_object (prototype_obj_p, true, true, ECMA_OBJECT_TYPE_FUNCTION);

ecma_deref_object (prototype_obj_p);

ecma_set_object_is_builtin (func_obj_p);

JERRY_ASSERT (routine_id >= ECMA_BUILTIN_ID__COUNT);

ecma_extended_object_t *ext_func_obj_p = (ecma_extended_object_t *) func_obj_p;
ext_func_obj_p->u.built_in.id = builtin_id;
ext_func_obj_p->u.built_in.length = length_prop_value;
Expand Down Expand Up @@ -328,9 +347,10 @@ ecma_builtin_try_to_instantiate_property (ecma_object_t *object_p, /**< object *
{
JERRY_ASSERT (ecma_get_object_is_builtin (object_p));

const ecma_object_type_t type = ecma_get_object_type (object_p);
ecma_extended_object_t *ext_obj_p = (ecma_extended_object_t *) object_p;

if (type == ECMA_OBJECT_TYPE_BUILT_IN_FUNCTION)
if (ecma_get_object_type (object_p) == ECMA_OBJECT_TYPE_FUNCTION
&& ecma_builtin_function_is_routine (object_p))
{
ecma_string_t *magic_string_length_p = ecma_get_magic_string (LIT_MAGIC_STRING_LENGTH);

Expand All @@ -348,8 +368,6 @@ ecma_builtin_try_to_instantiate_property (ecma_object_t *object_p, /**< object *
* as it is non-configurable and so can't be deleted
*/

ecma_extended_object_t *ext_obj_p = (ecma_extended_object_t *) object_p;

ecma_property_t *len_prop_p = ecma_create_named_data_property (object_p,
string_p,
ECMA_PROPERTY_FIXED);
Expand All @@ -371,8 +389,6 @@ ecma_builtin_try_to_instantiate_property (ecma_object_t *object_p, /**< object *
return NULL;
}

ecma_extended_object_t *ext_obj_p = (ecma_extended_object_t *) object_p;

ecma_builtin_id_t builtin_id = (ecma_builtin_id_t) ext_obj_p->u.built_in.id;

JERRY_ASSERT (builtin_id < ECMA_BUILTIN_ID__COUNT);
Expand Down Expand Up @@ -513,9 +529,10 @@ ecma_builtin_try_to_instantiate_property (ecma_object_t *object_p, /**< object *
}
case ECMA_BUILTIN_PROPERTY_ROUTINE:
{
ecma_object_t *func_obj_p = ecma_builtin_make_function_object_for_routine (builtin_id,
magic_string_id,
(uint8_t) curr_property_p->value);
ecma_object_t *func_obj_p;
func_obj_p = ecma_builtin_make_function_object_for_routine (builtin_id,
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ecma_object_t *func_obj_p;
func_obj_p = ecma_builtin_make_function_object_for_routine (builtin_id

ECMA_GET_ROUTINE_ID (curr_property_p->value),
ECMA_GET_ROUTINE_LENGTH (curr_property_p->value));
value = ecma_make_object_value (func_obj_p);
break;
}
Expand Down Expand Up @@ -559,9 +576,12 @@ ecma_builtin_list_lazy_property_names (ecma_object_t *object_p, /**< a built-in
ecma_collection_header_t *non_enum_collection_p) /**< skipped 'non-enumerable'
* collection */
{
const ecma_object_type_t type = ecma_get_object_type (object_p);
JERRY_ASSERT (ecma_get_object_is_builtin (object_p));

ecma_extended_object_t *ext_obj_p = (ecma_extended_object_t *) object_p;

if (type == ECMA_OBJECT_TYPE_BUILT_IN_FUNCTION)
if (ecma_get_object_type (object_p) == ECMA_OBJECT_TYPE_FUNCTION
&& ecma_builtin_function_is_routine (object_p))
{
ecma_collection_header_t *for_enumerable_p = main_collection_p;
(void) for_enumerable_p;
Expand All @@ -575,8 +595,6 @@ ecma_builtin_list_lazy_property_names (ecma_object_t *object_p, /**< a built-in
}
else
{
ecma_extended_object_t *ext_obj_p = (ecma_extended_object_t *) object_p;

ecma_builtin_id_t builtin_id = (ecma_builtin_id_t) ext_obj_p->u.built_in.id;

JERRY_ASSERT (builtin_id < ECMA_BUILTIN_ID__COUNT);
Expand Down Expand Up @@ -659,7 +677,7 @@ ecma_builtin_dispatch_call (ecma_object_t *obj_p, /**< built-in object */
ecma_value_t ret_value = ecma_make_simple_value (ECMA_SIMPLE_VALUE_EMPTY);
ecma_extended_object_t *ext_obj_p = (ecma_extended_object_t *) obj_p;

if (ecma_get_object_type (obj_p) == ECMA_OBJECT_TYPE_BUILT_IN_FUNCTION)
if (ecma_builtin_function_is_routine (obj_p))
{
ret_value = ecma_builtin_dispatch_routine (ext_obj_p->u.built_in.id,
ext_obj_p->u.built_in.routine_id,
Expand Down
18 changes: 18 additions & 0 deletions jerry-core/ecma/builtin-objects/ecma-builtins.h
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,21 @@ typedef enum
ECMA_BUILTIN_ID__COUNT /**< number of built-in objects */
} ecma_builtin_id_t;

/**
* Construct a routine value
*/
#define ECMA_ROUTINE_VALUE(id, length) (((id) << 4) | length)

/**
* Get routine length
*/
#define ECMA_GET_ROUTINE_LENGTH(value) ((uint8_t) ((value) & 0xf))

/**
* Get routine ID
*/
#define ECMA_GET_ROUTINE_ID(value) ((uint16_t) ((value) >> 4))

/* ecma-builtins.c */
extern void ecma_init_builtins (void);
extern void ecma_finalize_builtins (void);
Expand All @@ -55,4 +70,7 @@ extern bool
ecma_builtin_is (ecma_object_t *, ecma_builtin_id_t);
extern ecma_object_t *
ecma_builtin_get (ecma_builtin_id_t);
extern bool
ecma_builtin_function_is_routine (ecma_object_t *);

#endif /* !ECMA_BUILTINS_H */
36 changes: 19 additions & 17 deletions jerry-core/ecma/operations/ecma-function-object.c
Original file line number Diff line number Diff line change
Expand Up @@ -59,9 +59,8 @@ ecma_op_is_callable (ecma_value_t value) /**< ecma value */
JERRY_ASSERT (!ecma_is_lexical_environment (obj_p));

return (ecma_get_object_type (obj_p) == ECMA_OBJECT_TYPE_FUNCTION
|| ecma_get_object_type (obj_p) == ECMA_OBJECT_TYPE_BOUND_FUNCTION
|| ecma_get_object_type (obj_p) == ECMA_OBJECT_TYPE_EXTERNAL_FUNCTION
|| ecma_get_object_type (obj_p) == ECMA_OBJECT_TYPE_BUILT_IN_FUNCTION);
|| ecma_get_object_type (obj_p) == ECMA_OBJECT_TYPE_BOUND_FUNCTION);
} /* ecma_op_is_callable */

/**
Expand All @@ -83,8 +82,13 @@ ecma_is_constructor (ecma_value_t value) /**< ecma value */
JERRY_ASSERT (obj_p != NULL);
JERRY_ASSERT (!ecma_is_lexical_environment (obj_p));

return (ecma_get_object_type (obj_p) == ECMA_OBJECT_TYPE_FUNCTION
|| ecma_get_object_type (obj_p) == ECMA_OBJECT_TYPE_BOUND_FUNCTION
if (ecma_get_object_type (obj_p) == ECMA_OBJECT_TYPE_FUNCTION)
{
return (!ecma_get_object_is_builtin (obj_p)
|| !ecma_builtin_function_is_routine (obj_p));
}

return (ecma_get_object_type (obj_p) == ECMA_OBJECT_TYPE_BOUND_FUNCTION
|| ecma_get_object_type (obj_p) == ECMA_OBJECT_TYPE_EXTERNAL_FUNCTION);
} /* ecma_is_constructor */

Expand Down Expand Up @@ -444,7 +448,7 @@ ecma_op_create_external_function_object (ecma_external_pointer_t code_p) /**< po
* created through 13.2 (ECMA_OBJECT_TYPE_FUNCTION)
* or 15.3.4.5 (ECMA_OBJECT_TYPE_BOUND_FUNCTION),
* and for built-in Function objects
* from section 15 (ECMA_OBJECT_TYPE_BUILT_IN_FUNCTION).
* from section 15 (ECMA_OBJECT_TYPE_FUNCTION).
*
* @return ecma value
* Returned value must be freed with ecma_free_value
Expand All @@ -460,6 +464,12 @@ ecma_op_function_has_instance (ecma_object_t *func_obj_p, /**< Function object *

if (ecma_get_object_type (func_obj_p) == ECMA_OBJECT_TYPE_FUNCTION)
{
if (ecma_get_object_is_builtin (func_obj_p)
&& ecma_builtin_function_is_routine (func_obj_p))
{
return ecma_raise_type_error (ECMA_ERR_MSG (""));
}

if (!ecma_is_value_object (value))
{
return ecma_make_simple_value (ECMA_SIMPLE_VALUE_FALSE);
Expand Down Expand Up @@ -505,8 +515,7 @@ ecma_op_function_has_instance (ecma_object_t *func_obj_p, /**< Function object *

ecma_deref_ecma_string (prototype_magic_string_p);
}
else if (ecma_get_object_type (func_obj_p) == ECMA_OBJECT_TYPE_BUILT_IN_FUNCTION ||
ecma_get_object_type (func_obj_p) == ECMA_OBJECT_TYPE_EXTERNAL_FUNCTION)
else if (ecma_get_object_type (func_obj_p) == ECMA_OBJECT_TYPE_EXTERNAL_FUNCTION)
{
ret_value = ecma_raise_type_error (ECMA_ERR_MSG (""));
}
Expand Down Expand Up @@ -535,7 +544,7 @@ ecma_op_function_has_instance (ecma_object_t *func_obj_p, /**< Function object *
* created through 13.2 (ECMA_OBJECT_TYPE_FUNCTION)
* or 15.3.4.5 (ECMA_OBJECT_TYPE_BOUND_FUNCTION),
* and for built-in Function objects
* from section 15 (ECMA_OBJECT_TYPE_BUILT_IN_FUNCTION).
* from section 15 (ECMA_OBJECT_TYPE_FUNCTION).
*
* @return ecma value
* Returned value must be freed with ecma_free_value
Expand Down Expand Up @@ -636,13 +645,6 @@ ecma_op_function_call (ecma_object_t *func_obj_p, /**< Function object */
ecma_free_value (this_binding);
}
}
else if (ecma_get_object_type (func_obj_p) == ECMA_OBJECT_TYPE_BUILT_IN_FUNCTION)
{
ret_value = ecma_builtin_dispatch_call (func_obj_p,
this_arg_value,
arguments_list_p,
arguments_list_len);
}
else if (ecma_get_object_type (func_obj_p) == ECMA_OBJECT_TYPE_EXTERNAL_FUNCTION)
{
ecma_extended_object_t *ext_func_obj_p = (ecma_extended_object_t *) func_obj_p;
Expand Down Expand Up @@ -822,8 +824,8 @@ ecma_op_function_construct (ecma_object_t *func_obj_p, /**< Function object */

if (ecma_get_object_type (func_obj_p) == ECMA_OBJECT_TYPE_FUNCTION)
{
if (unlikely (ecma_get_object_type (func_obj_p) == ECMA_OBJECT_TYPE_FUNCTION
&& ecma_get_object_is_builtin (func_obj_p)))
if (unlikely (ecma_get_object_is_builtin (func_obj_p)
&& !ecma_builtin_function_is_routine (func_obj_p)))
{
ret_value = ecma_builtin_dispatch_construct (func_obj_p,
arguments_list_p,
Expand Down
Loading