From a287406e1f9aa835dba20d9a062335c2c7d9dfb3 Mon Sep 17 00:00:00 2001 From: Ruben Ayrapetyan Date: Mon, 22 Sep 2014 18:19:31 +0400 Subject: [PATCH] Implementing 'new Object(...)' built-in constructor. --- .../ecma-builtin-object-object.c | 65 +++++++++++ src/libecmabuiltins/ecma-builtins-internal.h | 6 + src/libecmabuiltins/ecma-builtins.c | 108 +++++++++++++++++- 3 files changed, 177 insertions(+), 2 deletions(-) diff --git a/src/libecmabuiltins/ecma-builtin-object-object.c b/src/libecmabuiltins/ecma-builtin-object-object.c index d9c925d1e..ae68a4bfc 100644 --- a/src/libecmabuiltins/ecma-builtin-object-object.c +++ b/src/libecmabuiltins/ecma-builtin-object-object.c @@ -19,6 +19,7 @@ #include "ecma-gc.h" #include "ecma-globals.h" #include "ecma-helpers.h" +#include "ecma-objects-general.h" #include "ecma-try-catch-macro.h" #include "globals.h" @@ -193,6 +194,70 @@ ecma_builtin_object_get_routine_parameters_number (ecma_magic_string_id_t builti } } /* ecma_builtin_object_get_routine_parameters_number */ +/** + * Handle calling [[Call]] of built-in Object object + * + * @return completion-value + */ +ecma_completion_value_t +ecma_builtin_object_dispatch_call (ecma_value_t *arguments_list_p, /**< arguments list */ + ecma_length_t arguments_list_len) /**< number of arguments */ +{ + JERRY_ASSERT (arguments_list_len == 0 || arguments_list_p != NULL); + + if (arguments_list_len == 0 + || ecma_is_value_undefined (arguments_list_p[0]) + || ecma_is_value_null (arguments_list_p [0])) + { + return ecma_builtin_object_dispatch_construct (arguments_list_p, arguments_list_len); + } + else + { + ecma_completion_value_t new_obj_value = ecma_op_to_object (arguments_list_p [0]); + + if (!ecma_is_completion_value_normal (new_obj_value)) + { + return new_obj_value; + } + else + { + return ecma_make_return_completion_value (new_obj_value.u.value); + } + } +} /* ecma_builtin_object_dispatch_call */ + +/** + * Handle calling [[Construct]] of built-in Object object + * + * @return completion-value + */ +ecma_completion_value_t +ecma_builtin_object_dispatch_construct (ecma_value_t *arguments_list_p, /**< arguments list */ + ecma_length_t arguments_list_len) /**< number of arguments */ +{ + JERRY_ASSERT (arguments_list_len == 0 || arguments_list_p != NULL); + + if (arguments_list_len == 0) + { + ecma_object_t *obj_p = ecma_op_create_object_object_noarg (); + + return ecma_make_return_completion_value (ecma_make_object_value (obj_p)); + } + else + { + ecma_completion_value_t new_obj_value = ecma_op_create_object_object_arg (arguments_list_p [0]); + + if (!ecma_is_completion_value_normal (new_obj_value)) + { + return new_obj_value; + } + else + { + return ecma_make_return_completion_value (new_obj_value.u.value); + } + } +} /* ecma_builtin_object_dispatch_construct */ + /** * The Object object's 'getPrototypeOf' routine * diff --git a/src/libecmabuiltins/ecma-builtins-internal.h b/src/libecmabuiltins/ecma-builtins-internal.h index 4e73dee55..886704c37 100644 --- a/src/libecmabuiltins/ecma-builtins-internal.h +++ b/src/libecmabuiltins/ecma-builtins-internal.h @@ -110,6 +110,12 @@ ecma_builtin_object_dispatch_routine (ecma_magic_string_id_t builtin_routine_id, extern ecma_property_t* ecma_builtin_object_try_to_instantiate_property (ecma_object_t *obj_p, ecma_string_t *prop_name_p); +extern ecma_completion_value_t +ecma_builtin_object_dispatch_call (ecma_value_t *arguments_list_p, + ecma_length_t arguments_list_len); +extern ecma_completion_value_t +ecma_builtin_object_dispatch_construct (ecma_value_t *arguments_list_p, + ecma_length_t arguments_list_len); extern void ecma_builtin_init_object_prototype_object (void); extern void ecma_builtin_finalize_object_prototype_object (void); diff --git a/src/libecmabuiltins/ecma-builtins.c b/src/libecmabuiltins/ecma-builtins.c index a63a570b5..664419d8b 100644 --- a/src/libecmabuiltins/ecma-builtins.c +++ b/src/libecmabuiltins/ecma-builtins.c @@ -223,8 +223,60 @@ ecma_builtin_dispatch_call (ecma_object_t *obj_p, /**< built-in object */ { JERRY_ASSERT (ecma_get_object_type (obj_p) == ECMA_OBJECT_TYPE_FUNCTION); - JERRY_UNIMPLEMENTED (); + 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: + { + JERRY_ASSERT (ecma_builtin_is_object_object (obj_p)); + + return ecma_builtin_object_dispatch_call (arguments_list_p, arguments_list_len); + } + + case ECMA_BUILTIN_ID_OBJECT_PROTOTYPE: + case ECMA_BUILTIN_ID_FUNCTION: + case ECMA_BUILTIN_ID_FUNCTION_PROTOTYPE: + case ECMA_BUILTIN_ID_ARRAY: + case ECMA_BUILTIN_ID_ARRAY_PROTOTYPE: + case ECMA_BUILTIN_ID_STRING: + case ECMA_BUILTIN_ID_STRING_PROTOTYPE: + case ECMA_BUILTIN_ID_BOOLEAN: + case ECMA_BUILTIN_ID_BOOLEAN_PROTOTYPE: + case ECMA_BUILTIN_ID_NUMBER: + case ECMA_BUILTIN_ID_NUMBER_PROTOTYPE: + case ECMA_BUILTIN_ID_DATE: + case ECMA_BUILTIN_ID_REGEXP: + case ECMA_BUILTIN_ID_REGEXP_PROTOTYPE: + case ECMA_BUILTIN_ID_ERROR: + case ECMA_BUILTIN_ID_ERROR_PROTOTYPE: + 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_SYNTAX_URI_ERROR: + { + JERRY_UNIMPLEMENTED (); + } + + case ECMA_BUILTIN_ID_GLOBAL: + case ECMA_BUILTIN_ID_MATH: + case ECMA_BUILTIN_ID_JSON: + { + JERRY_UNREACHABLE (); + } + + case ECMA_BUILTIN_ID__COUNT: + { + JERRY_UNREACHABLE (); + } + } } + + JERRY_UNREACHABLE (); } /* ecma_builtin_dispatch_call */ /** @@ -242,7 +294,59 @@ ecma_builtin_dispatch_construct (ecma_object_t *obj_p, /**< built-in object */ JERRY_ASSERT (ecma_get_object_is_builtin (obj_p)); JERRY_ASSERT (arguments_list_len == 0 || arguments_list_p != NULL); - JERRY_UNIMPLEMENTED_REF_UNUSED_VARS (obj_p, arguments_list_p, arguments_list_len); + 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: + { + JERRY_ASSERT (ecma_builtin_is_object_object (obj_p)); + + return ecma_builtin_object_dispatch_construct (arguments_list_p, arguments_list_len); + } + + case ECMA_BUILTIN_ID_OBJECT_PROTOTYPE: + case ECMA_BUILTIN_ID_FUNCTION: + case ECMA_BUILTIN_ID_FUNCTION_PROTOTYPE: + case ECMA_BUILTIN_ID_ARRAY: + case ECMA_BUILTIN_ID_ARRAY_PROTOTYPE: + case ECMA_BUILTIN_ID_STRING: + case ECMA_BUILTIN_ID_STRING_PROTOTYPE: + case ECMA_BUILTIN_ID_BOOLEAN: + case ECMA_BUILTIN_ID_BOOLEAN_PROTOTYPE: + case ECMA_BUILTIN_ID_NUMBER: + case ECMA_BUILTIN_ID_NUMBER_PROTOTYPE: + case ECMA_BUILTIN_ID_DATE: + case ECMA_BUILTIN_ID_REGEXP: + case ECMA_BUILTIN_ID_REGEXP_PROTOTYPE: + case ECMA_BUILTIN_ID_ERROR: + case ECMA_BUILTIN_ID_ERROR_PROTOTYPE: + 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_SYNTAX_URI_ERROR: + { + JERRY_UNIMPLEMENTED (); + } + + case ECMA_BUILTIN_ID_GLOBAL: + case ECMA_BUILTIN_ID_MATH: + case ECMA_BUILTIN_ID_JSON: + { + JERRY_UNREACHABLE (); + } + + case ECMA_BUILTIN_ID__COUNT: + { + JERRY_UNREACHABLE (); + } + } + + JERRY_UNREACHABLE (); } /* ecma_builtin_dispatch_construct */ /**