diff --git a/src/libcoreint/interpreter.c b/src/libcoreint/interpreter.c index e803d618e..50cc6b6f5 100644 --- a/src/libcoreint/interpreter.c +++ b/src/libcoreint/interpreter.c @@ -350,7 +350,7 @@ run_int (void) ecma_init (); - ecma_object_t *glob_obj_p = ecma_builtin_get_global_object (); + ecma_object_t *glob_obj_p = ecma_builtin_get (ECMA_BUILTIN_ID_GLOBAL); ecma_object_t *lex_env_p = ecma_op_create_global_environment (glob_obj_p); ecma_value_t this_binding_value = ecma_make_object_value (glob_obj_p); diff --git a/src/libecmabuiltins/ecma-builtin-global-object.c b/src/libecmabuiltins/ecma-builtin-global-object.c index cb58b77a4..8af8d946d 100644 --- a/src/libecmabuiltins/ecma-builtin-global-object.c +++ b/src/libecmabuiltins/ecma-builtin-global-object.c @@ -82,50 +82,17 @@ static const ecma_length_t ecma_builtin_global_property_number = (sizeof (ecma_b sizeof (ecma_magic_string_id_t)); JERRY_STATIC_ASSERT (sizeof (ecma_builtin_global_property_names) > sizeof (void*)); -/** - * Global object - */ -static ecma_object_t* ecma_global_object_p = NULL; - -/** - * Get Global object - * - * @return pointer to the Global object - * caller should free the reference by calling ecma_deref_object - */ -ecma_object_t* -ecma_builtin_get_global_object (void) -{ - JERRY_ASSERT(ecma_global_object_p != NULL); - - ecma_ref_object (ecma_global_object_p); - - return ecma_global_object_p; -} /* ecma_builtin_get_global_object */ - -/** - * Check if passed object is the Global object. - * - * @return true - if passed pointer points to the Global object, - * false - otherwise. - */ -bool -ecma_builtin_is_global_object (ecma_object_t *object_p) /**< an object */ -{ - return (object_p == ecma_global_object_p); -} /* ecma_builtin_is_global_object */ - /** * Initialize Global object. * * Warning: * the routine should be called only from ecma_init_builtins + * + * @return pointer to the object */ -void +ecma_object_t* ecma_builtin_init_global_object (void) { - JERRY_ASSERT(ecma_global_object_p == NULL); - ecma_object_t *glob_obj_p = ecma_create_object (NULL, true, ECMA_OBJECT_TYPE_GENERAL); ecma_property_t *class_prop_p = ecma_create_internal_property (glob_obj_p, @@ -146,24 +113,9 @@ ecma_builtin_init_global_object (void) ecma_set_object_is_builtin (glob_obj_p, true); - ecma_global_object_p = glob_obj_p; + return glob_obj_p; } /* ecma_builtin_init_global_object */ -/** - * Remove global reference to the Global object. - * - * Warning: - * the routine should be called only from ecma_finalize_builtins - */ -void -ecma_builtin_finalize_global_object (void) -{ - JERRY_ASSERT (ecma_global_object_p != NULL); - - ecma_deref_object (ecma_global_object_p); - ecma_global_object_p = NULL; -} /* ecma_builtin_finalize_global_object */ - /** * The Global object's 'eval' routine * @@ -461,7 +413,7 @@ ecma_property_t* ecma_builtin_global_try_to_instantiate_property (ecma_object_t *obj_p, /**< object */ ecma_string_t *prop_name_p) /**< property's name */ { - JERRY_ASSERT (ecma_builtin_is_global_object (obj_p)); + JERRY_ASSERT (ecma_builtin_is (obj_p, ECMA_BUILTIN_ID_GLOBAL)); JERRY_ASSERT (ecma_find_named_property (obj_p, prop_name_p) == NULL); ecma_magic_string_id_t id; @@ -560,7 +512,7 @@ ecma_builtin_global_try_to_instantiate_property (ecma_object_t *obj_p, /**< obje } case ECMA_MAGIC_STRING_OBJECT_UL: { - ecma_object_t *object_obj_p = ecma_builtin_get_object_object (); + ecma_object_t *object_obj_p = ecma_builtin_get (ECMA_BUILTIN_ID_OBJECT); value = ecma_make_object_value (object_obj_p); diff --git a/src/libecmabuiltins/ecma-builtin-object-object.c b/src/libecmabuiltins/ecma-builtin-object-object.c index ce4b5dac7..bb95346ff 100644 --- a/src/libecmabuiltins/ecma-builtin-object-object.c +++ b/src/libecmabuiltins/ecma-builtin-object-object.c @@ -71,50 +71,17 @@ static const ecma_length_t ecma_builtin_object_property_number = (sizeof (ecma_b sizeof (ecma_magic_string_id_t)); JERRY_STATIC_ASSERT (sizeof (ecma_builtin_object_property_names) > sizeof (void*)); -/** - * Object object - */ -static ecma_object_t* ecma_object_object_p = NULL; - -/** - * Get Object object - * - * @return pointer to the Object object - * caller should free the reference by calling ecma_deref_object - */ -ecma_object_t* -ecma_builtin_get_object_object (void) -{ - JERRY_ASSERT(ecma_object_object_p != NULL); - - ecma_ref_object (ecma_object_object_p); - - return ecma_object_object_p; -} /* ecma_builtin_get_object_object */ - -/** - * Check if passed object is the Object object. - * - * @return true - if passed pointer points to the Object object, - * false - otherwise. - */ -bool -ecma_builtin_is_object_object (ecma_object_t *object_p) /**< an object */ -{ - return (object_p == ecma_object_object_p); -} /* ecma_builtin_is_object_object */ - /** * Initialize Object object. * * Warning: * the routine should be called only from ecma_init_builtins + * + * @return pointer to the object */ -void +ecma_object_t* ecma_builtin_init_object_object (void) { - JERRY_ASSERT(ecma_object_object_p == NULL); - ecma_object_t *object_obj_p = ecma_create_object (NULL, true, ECMA_OBJECT_TYPE_FUNCTION); ecma_property_t *class_prop_p = ecma_create_internal_property (object_obj_p, @@ -135,24 +102,9 @@ ecma_builtin_init_object_object (void) ecma_set_object_is_builtin (object_obj_p, true); - ecma_object_object_p = object_obj_p; + return object_obj_p; } /* ecma_builtin_init_object_object */ -/** - * Remove global reference to the Object object. - * - * Warning: - * the routine should be called only from ecma_finalize_builtins - */ -void -ecma_builtin_finalize_object_object (void) -{ - JERRY_ASSERT (ecma_object_object_p != NULL); - - ecma_deref_object (ecma_object_object_p); - ecma_object_object_p = NULL; -} /* ecma_builtin_finalize_object_object */ - /** * Get number of routine's parameters * @@ -627,7 +579,7 @@ ecma_property_t* ecma_builtin_object_try_to_instantiate_property (ecma_object_t *obj_p, /**< object */ ecma_string_t *prop_name_p) /**< property's name */ { - JERRY_ASSERT (ecma_builtin_is_object_object (obj_p)); + JERRY_ASSERT (ecma_builtin_is (obj_p, ECMA_BUILTIN_ID_OBJECT)); JERRY_ASSERT (ecma_find_named_property (obj_p, prop_name_p) == NULL); ecma_magic_string_id_t id; diff --git a/src/libecmabuiltins/ecma-builtins-internal.h b/src/libecmabuiltins/ecma-builtins-internal.h index 886704c37..9d9c0ce8b 100644 --- a/src/libecmabuiltins/ecma-builtins-internal.h +++ b/src/libecmabuiltins/ecma-builtins-internal.h @@ -20,42 +20,9 @@ # error "!ECMA_BUILTINS_INTERNAL" #endif /* !ECMA_BUILTINS_INTERNAL */ +#include "ecma-builtins.h" #include "ecma-globals.h" -/** - * A built-in object's identifier - */ -typedef enum -{ - ECMA_BUILTIN_ID_GLOBAL, /**< the Global object (15.1) */ - ECMA_BUILTIN_ID_OBJECT, /**< the Object object (15.2.1) */ - ECMA_BUILTIN_ID_OBJECT_PROTOTYPE, /**< the Object object (15.2.4) */ - ECMA_BUILTIN_ID_FUNCTION, /**< the Function object (15.3.1) */ - ECMA_BUILTIN_ID_FUNCTION_PROTOTYPE, /**< the Function object (15.3.4) */ - ECMA_BUILTIN_ID_ARRAY, /**< the Array object (15.4.1) */ - ECMA_BUILTIN_ID_ARRAY_PROTOTYPE, /**< the Array object (15.4.4) */ - ECMA_BUILTIN_ID_STRING, /**< the String object (15.5.1) */ - ECMA_BUILTIN_ID_STRING_PROTOTYPE, /**< the String object (15.5.4) */ - ECMA_BUILTIN_ID_BOOLEAN, /**< the Boolean object (15.6.1) */ - ECMA_BUILTIN_ID_BOOLEAN_PROTOTYPE, /**< the Boolean object (15.6.4) */ - ECMA_BUILTIN_ID_NUMBER, /**< the Number object (15.7.1) */ - ECMA_BUILTIN_ID_NUMBER_PROTOTYPE, /**< the Number object (15.7.4) */ - ECMA_BUILTIN_ID_DATE, /**< the Date object (15.9.2) */ - ECMA_BUILTIN_ID_REGEXP, /**< the RegExp object (15.10.3) */ - ECMA_BUILTIN_ID_REGEXP_PROTOTYPE, /**< the RegExp object (15.10.6) */ - ECMA_BUILTIN_ID_ERROR, /**< the Error object (15.11.1) */ - ECMA_BUILTIN_ID_ERROR_PROTOTYPE, /**< the Error object (15.11.4) */ - ECMA_BUILTIN_ID_EVAL_ERROR, /**< the EvalError object (15.11.6.1) */ - ECMA_BUILTIN_ID_RANGE_ERROR, /**< the RangeError object (15.11.6.2) */ - ECMA_BUILTIN_ID_REFERENCE_ERROR, /**< the ReferenceError object (15.11.6.3) */ - ECMA_BUILTIN_ID_SYNTAX_ERROR, /**< the SyntaxError object (15.11.6.4) */ - ECMA_BUILTIN_ID_TYPE_ERROR, /**< the SyntaxError object (15.11.6.5) */ - ECMA_BUILTIN_ID_SYNTAX_URI_ERROR, /**< the URIError object (15.11.6.6) */ - ECMA_BUILTIN_ID_MATH, /**< the Math object (15.8) */ - ECMA_BUILTIN_ID_JSON, /**< the JSON object (15.12) */ - ECMA_BUILTIN_ID__COUNT /**< number of built-in objects */ -} ecma_builtin_id_t; - /** * Position of built-in object's id field in [[Built-in routine ID]] internal property */ @@ -84,8 +51,7 @@ ecma_builtin_make_function_object_for_routine (ecma_builtin_id_t builtin_id, ecma_magic_string_id_t routine_id); /* ecma-builtin-global-object.c */ -extern void ecma_builtin_init_global_object (void); -extern void ecma_builtin_finalize_global_object (void); +extern ecma_object_t* ecma_builtin_init_global_object (void); extern ecma_length_t ecma_builtin_global_get_routine_parameters_number (ecma_magic_string_id_t routine_id); @@ -98,8 +64,7 @@ ecma_builtin_global_try_to_instantiate_property (ecma_object_t *obj_p, ecma_string_t *prop_name_p); /* ecma-builtin-object-object.c */ -extern void ecma_builtin_init_object_object (void); -extern void ecma_builtin_finalize_object_object (void); +extern ecma_object_t* ecma_builtin_init_object_object (void); extern ecma_length_t ecma_builtin_object_get_routine_parameters_number (ecma_magic_string_id_t routine_id); diff --git a/src/libecmabuiltins/ecma-builtins.c b/src/libecmabuiltins/ecma-builtins.c index 664419d8b..4c3b6bac1 100644 --- a/src/libecmabuiltins/ecma-builtins.c +++ b/src/libecmabuiltins/ecma-builtins.c @@ -15,6 +15,7 @@ #include "ecma-alloc.h" #include "ecma-builtins.h" +#include "ecma-gc.h" #include "ecma-globals.h" #include "ecma-helpers.h" #include "ecma-objects.h" @@ -39,15 +40,57 @@ ecma_builtin_dispatch_routine (ecma_builtin_id_t builtin_object_id, ecma_value_t arguments_list [], ecma_length_t arguments_number); +/** + * Pointer to instances of built-in objects + */ +static ecma_object_t* ecma_builtin_objects [ECMA_BUILTIN_ID__COUNT]; + +/** + * Check if passed object is the instance of specified built-in. + */ +bool +ecma_builtin_is (ecma_object_t *obj_p, /**< pointer to an object */ + ecma_builtin_id_t builtin_id) /**< id of built-in to check on */ +{ + JERRY_ASSERT (obj_p != NULL && !ecma_is_lexical_environment (obj_p)); + JERRY_ASSERT (builtin_id < ECMA_BUILTIN_ID__COUNT); + JERRY_ASSERT (ecma_builtin_objects [builtin_id] != NULL); + + return (obj_p == ecma_builtin_objects [builtin_id]); +} /* ecma_builtin_is */ + +/** + * Get reference to specified built-in object + * + * @return pointer to the object's instance + */ +ecma_object_t* +ecma_builtin_get (ecma_builtin_id_t builtin_id) /**< id of built-in to check on */ +{ + JERRY_ASSERT (builtin_id < ECMA_BUILTIN_ID__COUNT); + JERRY_ASSERT (ecma_builtin_objects [builtin_id] != NULL); + + ecma_ref_object (ecma_builtin_objects [builtin_id]); + + return ecma_builtin_objects [builtin_id]; +} /* ecma_builtin_get */ + /** * Initialize ECMA built-in objects */ void ecma_init_builtins (void) { - ecma_builtin_init_object_object (); + for (ecma_builtin_id_t id = 0; + id < ECMA_BUILTIN_ID__COUNT; + id++) + { + ecma_builtin_objects [id] = NULL; + } - ecma_builtin_init_global_object (); + ecma_builtin_objects [ECMA_BUILTIN_ID_OBJECT] = ecma_builtin_init_object_object (); + + ecma_builtin_objects [ECMA_BUILTIN_ID_GLOBAL] = ecma_builtin_init_global_object (); } /* ecma_init_builtins */ /** @@ -56,9 +99,17 @@ ecma_init_builtins (void) void ecma_finalize_builtins (void) { - ecma_builtin_finalize_global_object (); + for (ecma_builtin_id_t id = 0; + id < ECMA_BUILTIN_ID__COUNT; + id++) + { + if (ecma_builtin_objects [id] != NULL) + { + ecma_deref_object (ecma_builtin_objects [id]); - ecma_builtin_finalize_object_object (); + ecma_builtin_objects [id] = NULL; + } + } } /* ecma_finalize_builtins */ /** @@ -79,19 +130,17 @@ ecma_builtin_try_to_instantiate_property (ecma_object_t *object_p, /**< object * 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; + JERRY_ASSERT (ecma_builtin_is (object_p, builtin_id)); + switch (builtin_id) { case ECMA_BUILTIN_ID_GLOBAL: { - JERRY_ASSERT (ecma_builtin_is_global_object (object_p)); - return ecma_builtin_global_try_to_instantiate_property (object_p, string_p); } case ECMA_BUILTIN_ID_OBJECT: { - JERRY_ASSERT (ecma_builtin_is_object_object (object_p)); - return ecma_builtin_object_try_to_instantiate_property (object_p, string_p); } @@ -227,12 +276,12 @@ ecma_builtin_dispatch_call (ecma_object_t *obj_p, /**< built-in object */ 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; + JERRY_ASSERT (ecma_builtin_is (obj_p, builtin_id)); + switch (builtin_id) { case ECMA_BUILTIN_ID_OBJECT: { - JERRY_ASSERT (ecma_builtin_is_object_object (obj_p)); - return ecma_builtin_object_dispatch_call (arguments_list_p, arguments_list_len); } @@ -298,12 +347,12 @@ ecma_builtin_dispatch_construct (ecma_object_t *obj_p, /**< built-in object */ 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; + JERRY_ASSERT (ecma_builtin_is (obj_p, builtin_id)); + switch (builtin_id) { case ECMA_BUILTIN_ID_OBJECT: { - JERRY_ASSERT (ecma_builtin_is_object_object (obj_p)); - return ecma_builtin_object_dispatch_construct (arguments_list_p, arguments_list_len); } diff --git a/src/libecmabuiltins/ecma-builtins.h b/src/libecmabuiltins/ecma-builtins.h index 400e15aa3..9eb015757 100644 --- a/src/libecmabuiltins/ecma-builtins.h +++ b/src/libecmabuiltins/ecma-builtins.h @@ -18,7 +18,41 @@ #include "ecma-globals.h" -/* ecma-builtin.c */ +/** + * A built-in object's identifier + */ +typedef enum +{ + ECMA_BUILTIN_ID_GLOBAL, /**< the Global object (15.1) */ + ECMA_BUILTIN_ID_OBJECT, /**< the Object object (15.2.1) */ + ECMA_BUILTIN_ID_OBJECT_PROTOTYPE, /**< the Object object (15.2.4) */ + ECMA_BUILTIN_ID_FUNCTION, /**< the Function object (15.3.1) */ + ECMA_BUILTIN_ID_FUNCTION_PROTOTYPE, /**< the Function object (15.3.4) */ + ECMA_BUILTIN_ID_ARRAY, /**< the Array object (15.4.1) */ + ECMA_BUILTIN_ID_ARRAY_PROTOTYPE, /**< the Array object (15.4.4) */ + ECMA_BUILTIN_ID_STRING, /**< the String object (15.5.1) */ + ECMA_BUILTIN_ID_STRING_PROTOTYPE, /**< the String object (15.5.4) */ + ECMA_BUILTIN_ID_BOOLEAN, /**< the Boolean object (15.6.1) */ + ECMA_BUILTIN_ID_BOOLEAN_PROTOTYPE, /**< the Boolean object (15.6.4) */ + ECMA_BUILTIN_ID_NUMBER, /**< the Number object (15.7.1) */ + ECMA_BUILTIN_ID_NUMBER_PROTOTYPE, /**< the Number object (15.7.4) */ + ECMA_BUILTIN_ID_DATE, /**< the Date object (15.9.2) */ + ECMA_BUILTIN_ID_REGEXP, /**< the RegExp object (15.10.3) */ + ECMA_BUILTIN_ID_REGEXP_PROTOTYPE, /**< the RegExp object (15.10.6) */ + ECMA_BUILTIN_ID_ERROR, /**< the Error object (15.11.1) */ + ECMA_BUILTIN_ID_ERROR_PROTOTYPE, /**< the Error object (15.11.4) */ + ECMA_BUILTIN_ID_EVAL_ERROR, /**< the EvalError object (15.11.6.1) */ + ECMA_BUILTIN_ID_RANGE_ERROR, /**< the RangeError object (15.11.6.2) */ + ECMA_BUILTIN_ID_REFERENCE_ERROR, /**< the ReferenceError object (15.11.6.3) */ + ECMA_BUILTIN_ID_SYNTAX_ERROR, /**< the SyntaxError object (15.11.6.4) */ + ECMA_BUILTIN_ID_TYPE_ERROR, /**< the SyntaxError object (15.11.6.5) */ + ECMA_BUILTIN_ID_SYNTAX_URI_ERROR, /**< the URIError object (15.11.6.6) */ + ECMA_BUILTIN_ID_MATH, /**< the Math object (15.8) */ + ECMA_BUILTIN_ID_JSON, /**< the JSON object (15.12) */ + ECMA_BUILTIN_ID__COUNT /**< number of built-in objects */ +} ecma_builtin_id_t; + +/* ecma-builtins.c */ extern void ecma_init_builtins (void); extern void ecma_finalize_builtins (void); @@ -33,23 +67,9 @@ ecma_builtin_dispatch_construct (ecma_object_t *obj_p, extern ecma_property_t* ecma_builtin_try_to_instantiate_property (ecma_object_t *object_p, ecma_string_t *string_p); - -/* ecma-builtin-global-object.c */ -extern ecma_object_t* ecma_builtin_get_global_object (void); -extern bool ecma_builtin_is_global_object (ecma_object_t *object_p); - -/* ecma-builtin-object-object.c */ -extern ecma_object_t* ecma_builtin_get_object_object (void); -extern bool ecma_builtin_is_object_object (ecma_object_t *object_p); - -extern ecma_object_t* ecma_builtin_get_object_prototype_object (void); -extern bool ecma_builtin_is_object_prototype_object (ecma_object_t *object_p); - -/* ecma-builtin-array-object.c */ -extern ecma_object_t* ecma_builtin_get_array_object (void); -extern bool ecma_builtin_is_array_object (ecma_object_t *object_p); - -extern ecma_object_t* ecma_builtin_get_array_prototype_object (void); -extern bool ecma_builtin_is_array_prototype_object (ecma_object_t *object_p); - +extern bool +ecma_builtin_is (ecma_object_t *obj_p, + ecma_builtin_id_t builtin_id); +extern ecma_object_t* +ecma_builtin_get (ecma_builtin_id_t builtin_id); #endif /* !ECMA_BUILTINS_H */ diff --git a/src/libecmaoperations/ecma-function-object.c b/src/libecmaoperations/ecma-function-object.c index 7c80b3b9d..d03bb62f6 100644 --- a/src/libecmaoperations/ecma-function-object.c +++ b/src/libecmaoperations/ecma-function-object.c @@ -504,7 +504,7 @@ ecma_op_function_call (ecma_object_t *func_obj_p, /**< Function object */ || ecma_is_value_null (this_arg_value)) { // 2. - this_binding = ecma_make_object_value (ecma_builtin_get_global_object ()); + this_binding = ecma_make_object_value (ecma_builtin_get (ECMA_BUILTIN_ID_GLOBAL)); } else { @@ -702,7 +702,7 @@ ecma_op_function_declaration (ecma_object_t *lex_env_p, /**< lexical environment else if (ecma_is_lexical_environment_global (lex_env_p)) { // e. - ecma_object_t *glob_obj_p = ecma_builtin_get_global_object (); + ecma_object_t *glob_obj_p = ecma_builtin_get (ECMA_BUILTIN_ID_GLOBAL); ecma_property_t *existing_prop_p = ecma_op_object_get_property (glob_obj_p, function_name_p); diff --git a/src/libecmaoperations/ecma-get-put-value.c b/src/libecmaoperations/ecma-get-put-value.c index faf847f43..fe6f37553 100644 --- a/src/libecmaoperations/ecma-get-put-value.c +++ b/src/libecmaoperations/ecma-get-put-value.c @@ -157,7 +157,7 @@ ecma_op_put_value (ecma_reference_t ref, /**< ECMA-reference */ else { // 3.b. - ecma_object_t *global_object_p = ecma_builtin_get_global_object (); + ecma_object_t *global_object_p = ecma_builtin_get (ECMA_BUILTIN_ID_GLOBAL); ecma_completion_value_t completion = ecma_op_object_put (global_object_p, ref.referenced_name_p, diff --git a/src/libecmaoperations/ecma-lex-env.c b/src/libecmaoperations/ecma-lex-env.c index 2004cfbde..9ec8818a2 100644 --- a/src/libecmaoperations/ecma-lex-env.c +++ b/src/libecmaoperations/ecma-lex-env.c @@ -526,7 +526,7 @@ ecma_is_lexical_environment_global (ecma_object_t *lex_env_p) /**< lexical envir { ecma_object_t *binding_obj_p = ecma_get_lex_env_binding_object (lex_env_p); - return ecma_builtin_is_global_object (binding_obj_p); + return ecma_builtin_is (binding_obj_p, ECMA_BUILTIN_ID_GLOBAL); } else {