From eb3686a49d7225c48d0cd3b7753d7cfe41699cd1 Mon Sep 17 00:00:00 2001 From: Ruben Ayrapetyan Date: Wed, 1 Apr 2015 12:14:29 +0300 Subject: [PATCH] Adding jerry_api_is_constructor interface that check if specified object is a function object that implement [[Construct]] method; changing jerry_api_is_function to recognize bound and built-in functions; optimizing jerry_api_call_function. --- jerry-core/jerry-api.h | 4 +++- jerry-core/jerry.cpp | 36 +++++++++++++++++++++++++----------- tests/unit/test_api.cpp | 40 ++++++++++++++++++++-------------------- 3 files changed, 48 insertions(+), 32 deletions(-) diff --git a/jerry-core/jerry-api.h b/jerry-core/jerry-api.h index 1dd7dfbcd..ce5f135e1 100644 --- a/jerry-core/jerry-api.h +++ b/jerry-core/jerry-api.h @@ -103,7 +103,9 @@ extern EXTERN_C jerry_api_object_t* jerry_api_create_object (void); extern EXTERN_C -bool jerry_api_is_function(const jerry_api_object_t *object_p); +bool jerry_api_is_function (const jerry_api_object_t *object_p); +extern EXTERN_C +bool jerry_api_is_constructor (const jerry_api_object_t *object_p); extern EXTERN_C bool jerry_api_add_object_field (jerry_api_object_t *object_p, diff --git a/jerry-core/jerry.cpp b/jerry-core/jerry.cpp index 63a8599dd..380e69a21 100644 --- a/jerry-core/jerry.cpp +++ b/jerry-core/jerry.cpp @@ -133,8 +133,6 @@ static void jerry_api_convert_api_value_to_ecma_value (ecma_value_t *out_value_p, /**< out: ecma-value */ const jerry_api_value_t* api_value_p) /**< value in Jerry API format */ { - *out_value_p = 0; - switch (api_value_p->type) { case JERRY_API_DATA_TYPE_UNDEFINED: @@ -346,16 +344,33 @@ jerry_api_create_object (void) /** * Check if the specified object is a function object. * - * @return true, if the sepcfied object is a function object. + * @return true - if the specified object is a function object, * false - otherwise. */ bool -jerry_api_is_function(const jerry_api_object_t* object_p) +jerry_api_is_function (const jerry_api_object_t* object_p) /**< an object */ { JERRY_ASSERT (object_p != NULL); - return ecma_get_object_type (object_p) == ECMA_OBJECT_TYPE_FUNCTION; -} + return (ecma_get_object_type (object_p) == ECMA_OBJECT_TYPE_FUNCTION + || ecma_get_object_type (object_p) == ECMA_OBJECT_TYPE_BOUND_FUNCTION + || ecma_get_object_type (object_p) == ECMA_OBJECT_TYPE_BUILT_IN_FUNCTION); +} /* jerry_api_is_function */ + +/** + * Check if the specified object is a constructor function object. + * + * @return true - if the specified object is a function object that implements [[Construct]], + * false - otherwise. + */ +bool +jerry_api_is_constructor (const jerry_api_object_t* object_p) /**< an object */ +{ + JERRY_ASSERT (object_p != NULL); + + return (ecma_get_object_type (object_p) == ECMA_OBJECT_TYPE_FUNCTION + || ecma_get_object_type (object_p) == ECMA_OBJECT_TYPE_BOUND_FUNCTION); +} /* jerry_api_is_constructor */ /** * Create field (named data property) in the specified object @@ -532,7 +547,7 @@ jerry_api_set_object_field_value (jerry_api_object_t *object_p, /**< object */ bool jerry_api_call_function (jerry_api_object_t *function_object_p, /**< function object to call */ jerry_api_object_t *this_arg_p, /**< this arg for this binding - * or NULL (set this binding to the global object) */ + * or NULL (set this binding to the global object) */ jerry_api_value_t *retval_p, /**< place for function's return value (if it is required) * or NULL (if it should be 'undefined') */ const jerry_api_value_t args_p [], /**< function's call arguments @@ -553,14 +568,14 @@ jerry_api_call_function (jerry_api_object_t *function_object_p, /**< function ob ecma_completion_value_t call_completion; - ecma_value_t this_arg_val = 0; + ecma_value_t this_arg_val; + if (this_arg_p == NULL) { this_arg_val = ecma_make_simple_value (ECMA_SIMPLE_VALUE_UNDEFINED); } else { - ecma_ref_object(this_arg_p); this_arg_val = ecma_make_object_value (this_arg_p); } @@ -586,7 +601,6 @@ jerry_api_call_function (jerry_api_object_t *function_object_p, /**< function ob is_successful = false; } - ecma_free_value (this_arg_val, true); ecma_free_completion_value (call_completion); for (uint32_t i = 0; i < args_count; i++) @@ -597,7 +611,7 @@ jerry_api_call_function (jerry_api_object_t *function_object_p, /**< function ob MEM_FINALIZE_LOCAL_ARRAY (arg_values); return is_successful; -} /* jerry_api_call_funition */ +} /* jerry_api_call_function */ /** * Get global object diff --git a/tests/unit/test_api.cpp b/tests/unit/test_api.cpp index 479b374d2..e998c1026 100644 --- a/tests/unit/test_api.cpp +++ b/tests/unit/test_api.cpp @@ -21,20 +21,21 @@ #include "jerry.h" #include "jerry-api.h" -const char *test_source = - "this.t = 1; " - "function f () { " - "return this.t; " - "} " - "this.foo = f; " - "this.bar = function (a) { " - "return a + t; " - "} " - "function A () { " - "this.t = 12; " - "} " - "this.A = A; " - "this.a = new A (); "; +const char *test_source = ( + "this.t = 1; " + "function f () { " + "return this.t; " + "} " + "this.foo = f; " + "this.bar = function (a) { " + "return a + t; " + "} " + "function A () { " + "this.t = 12; " + "} " + "this.A = A; " + "this.a = new A (); " + ); /** * Initialize Jerry API value with specified float64 number @@ -48,7 +49,7 @@ test_api_init_api_value_float64 (jerry_api_value_t *out_value_p, /**< out: API v } /* test_api_init_api_value_float64 */ /** - * Initialize Jerry API value with specified float64 number + * Initialize Jerry API value with specified string */ static void test_api_init_api_value_string (jerry_api_value_t *out_value_p, /**< out: API value */ @@ -90,10 +91,9 @@ main (void) assert (is_ok && val_foo.type == JERRY_API_DATA_TYPE_OBJECT); + // Call foo (4, 2) test_api_init_api_value_float64 (&args[0], 4); test_api_init_api_value_float64 (&args[1], 2); - - // Call foo (4, 2) is_ok = jerry_api_call_function (val_foo.v_object, NULL, &res, args, 2); assert (is_ok && res.type == JERRY_API_DATA_TYPE_FLOAT64 @@ -138,8 +138,8 @@ main (void) && val_A.type == JERRY_API_DATA_TYPE_OBJECT); // Get A.prototype - is_ok = jerry_api_is_function (val_A.v_object); - assert(is_ok); + is_ok = jerry_api_is_constructor (val_A.v_object); + assert (is_ok); is_ok = jerry_api_get_object_field_value (val_A.v_object, "prototype", &val_A_prototype); @@ -187,4 +187,4 @@ main (void) jerry_cleanup (); return 0; -} \ No newline at end of file +}