Implementing API for invocation of a function object as a constructor.
This commit is contained in:
@@ -149,6 +149,12 @@ bool jerry_api_call_function (jerry_api_object_t *function_object_p,
|
||||
const jerry_api_value_t args_p [],
|
||||
uint16_t args_count);
|
||||
|
||||
extern EXTERN_C
|
||||
bool jerry_api_construct_object (jerry_api_object_t *function_object_p,
|
||||
jerry_api_value_t *retval_p,
|
||||
const jerry_api_value_t args_p [],
|
||||
uint16_t args_count);
|
||||
|
||||
extern EXTERN_C
|
||||
jerry_api_object_t* jerry_api_get_global (void);
|
||||
|
||||
|
||||
+112
-22
@@ -652,25 +652,35 @@ jerry_api_set_object_native_handle (jerry_api_object_t *object_p, /**< object to
|
||||
} /* jerry_api_set_object_native_handle */
|
||||
|
||||
/**
|
||||
* Call function specified by a function object
|
||||
* Invoke function specified by a function object
|
||||
*
|
||||
* Note:
|
||||
* if call was performed successfully, returned value should be freed
|
||||
* if invocation was performed successfully, returned value should be freed
|
||||
* with jerry_api_release_value just when the value becomes unnecessary.
|
||||
*
|
||||
* @return true, if call was performed successfully, i.e.:
|
||||
* Note:
|
||||
* If function is invoked as constructor, it should support [[Construct]] method,
|
||||
* otherwise, if function is simply called - it should support [[Call]] method.
|
||||
*
|
||||
* @return true, if invocation was performed successfully, i.e.:
|
||||
* - no unhandled exceptions were thrown in connection with the call;
|
||||
* false - otherwise.
|
||||
*/
|
||||
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) */
|
||||
jerry_api_value_t *retval_p, /**< pointer to place for function's return value
|
||||
* or NULL (to ignore the return value) */
|
||||
const jerry_api_value_t args_p [], /**< function's call arguments
|
||||
* (NULL if arguments number is zero) */
|
||||
uint16_t args_count) /**< number of the arguments */
|
||||
static bool
|
||||
jerry_api_invoke_function (bool is_invoke_as_constructor, /**< true - invoke function as constructor
|
||||
* (this_arg_p should be NULL, as it is ignored),
|
||||
* false - perform function call */
|
||||
jerry_api_object_t *function_object_p, /**< function object to call */
|
||||
jerry_api_object_t *this_arg_p, /**< object for 'this' binding
|
||||
* or NULL (set 'this' binding to newly constructed object,
|
||||
* if function is invoked as constructor;
|
||||
* in case of simple function call set 'this'
|
||||
* binding to the global object) */
|
||||
jerry_api_value_t *retval_p, /**< pointer to place for function's return value
|
||||
* or NULL (to ignore the return value) */
|
||||
const jerry_api_value_t args_p [], /**< function's call arguments
|
||||
* (NULL if arguments number is zero) */
|
||||
uint16_t args_count) /**< number of the arguments */
|
||||
{
|
||||
JERRY_ASSERT (args_count == 0 || args_p != NULL);
|
||||
JERRY_STATIC_ASSERT (sizeof (args_count) == sizeof (ecma_length_t));
|
||||
@@ -686,21 +696,35 @@ 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;
|
||||
|
||||
if (this_arg_p == NULL)
|
||||
if (is_invoke_as_constructor)
|
||||
{
|
||||
this_arg_val = ecma_make_simple_value (ECMA_SIMPLE_VALUE_UNDEFINED);
|
||||
JERRY_ASSERT (this_arg_p == NULL);
|
||||
JERRY_ASSERT (jerry_api_is_constructor (function_object_p));
|
||||
|
||||
call_completion = ecma_op_function_construct (function_object_p,
|
||||
arg_values,
|
||||
args_count);
|
||||
}
|
||||
else
|
||||
{
|
||||
this_arg_val = ecma_make_object_value (this_arg_p);
|
||||
}
|
||||
JERRY_ASSERT (jerry_api_is_function (function_object_p));
|
||||
|
||||
call_completion = ecma_op_function_call (function_object_p,
|
||||
this_arg_val,
|
||||
arg_values,
|
||||
args_count);
|
||||
ecma_value_t this_arg_val;
|
||||
|
||||
if (this_arg_p == NULL)
|
||||
{
|
||||
this_arg_val = ecma_make_simple_value (ECMA_SIMPLE_VALUE_UNDEFINED);
|
||||
}
|
||||
else
|
||||
{
|
||||
this_arg_val = ecma_make_object_value (this_arg_p);
|
||||
}
|
||||
|
||||
call_completion = ecma_op_function_call (function_object_p,
|
||||
this_arg_val,
|
||||
arg_values,
|
||||
args_count);
|
||||
}
|
||||
|
||||
if (ecma_is_completion_value_normal (call_completion))
|
||||
{
|
||||
@@ -716,6 +740,11 @@ jerry_api_call_function (jerry_api_object_t *function_object_p, /**< function ob
|
||||
|
||||
JERRY_ASSERT (ecma_is_completion_value_throw (call_completion));
|
||||
|
||||
if (retval_p != NULL)
|
||||
{
|
||||
jerry_api_convert_ecma_value_to_api_value (retval_p, ecma_make_simple_value (ECMA_SIMPLE_VALUE_UNDEFINED));
|
||||
}
|
||||
|
||||
is_successful = false;
|
||||
}
|
||||
|
||||
@@ -729,8 +758,69 @@ jerry_api_call_function (jerry_api_object_t *function_object_p, /**< function ob
|
||||
MEM_FINALIZE_LOCAL_ARRAY (arg_values);
|
||||
|
||||
return is_successful;
|
||||
} /* jerry_api_invoke_function */
|
||||
|
||||
/**
|
||||
* Call function specified by a function object
|
||||
*
|
||||
* Note:
|
||||
* if call was performed successfully, returned value should be freed
|
||||
* with jerry_api_release_value just when the value becomes unnecessary.
|
||||
*
|
||||
* @return true, if call was performed successfully, i.e.:
|
||||
* - specified object is a function object (see also jerry_api_is_function);
|
||||
* - no unhandled exceptions were thrown in connection with the call;
|
||||
* false - otherwise.
|
||||
*/
|
||||
bool
|
||||
jerry_api_call_function (jerry_api_object_t *function_object_p, /**< function object to call */
|
||||
jerry_api_object_t *this_arg_p, /**< object for 'this' binding
|
||||
* or NULL (set 'this' binding to the global object) */
|
||||
jerry_api_value_t *retval_p, /**< pointer to place for function's return value
|
||||
* or NULL (to ignore the return value) */
|
||||
const jerry_api_value_t args_p [], /**< function's call arguments
|
||||
* (NULL if arguments number is zero) */
|
||||
uint16_t args_count) /**< number of the arguments */
|
||||
{
|
||||
if (jerry_api_is_function (function_object_p))
|
||||
{
|
||||
return jerry_api_invoke_function (false, function_object_p, this_arg_p, retval_p, args_p, args_count);
|
||||
}
|
||||
{
|
||||
return false;
|
||||
}
|
||||
} /* jerry_api_call_function */
|
||||
|
||||
/**
|
||||
* Construct object invoking specified function object as a constructor
|
||||
*
|
||||
* Note:
|
||||
* if construction was performed successfully, returned value should be freed
|
||||
* with jerry_api_release_value just when the value becomes unnecessary.
|
||||
*
|
||||
* @return true, if construction was performed successfully, i.e.:
|
||||
* - specified object is a constructor function object (see also jerry_api_is_constructor);
|
||||
* - no unhandled exceptions were thrown in connection with the invocation;
|
||||
* false - otherwise.
|
||||
*/
|
||||
bool
|
||||
jerry_api_construct_object (jerry_api_object_t *function_object_p, /**< function object to call */
|
||||
jerry_api_value_t *retval_p, /**< pointer to place for function's return value
|
||||
* or NULL (to ignore the return value) */
|
||||
const jerry_api_value_t args_p [], /**< function's call arguments
|
||||
* (NULL if arguments number is zero) */
|
||||
uint16_t args_count) /**< number of the arguments */
|
||||
{
|
||||
if (jerry_api_is_constructor (function_object_p))
|
||||
{
|
||||
return jerry_api_invoke_function (true, function_object_p, NULL, retval_p, args_p, args_count);
|
||||
}
|
||||
else
|
||||
{
|
||||
return false;
|
||||
}
|
||||
} /* jerry_api_construct_object */
|
||||
|
||||
/**
|
||||
* Get global object
|
||||
*
|
||||
|
||||
+15
-13
@@ -38,11 +38,19 @@ const char *test_source = (
|
||||
"function call_external () {"
|
||||
" return this.external ('1', true);"
|
||||
"}"
|
||||
"function call_external_construct () {"
|
||||
" return new external_construct (true);"
|
||||
"}"
|
||||
);
|
||||
|
||||
/**
|
||||
* Initialize Jerry API value with specified boolean value
|
||||
*/
|
||||
static void
|
||||
test_api_init_api_value_bool (jerry_api_value_t *out_value_p, /**< out: API value */
|
||||
bool v) /**< boolean value to initialize with */
|
||||
{
|
||||
out_value_p->type = JERRY_API_DATA_TYPE_BOOLEAN;
|
||||
out_value_p->v_bool = v;
|
||||
} /* test_api_init_api_value_bool */
|
||||
|
||||
/**
|
||||
* Initialize Jerry API value with specified float64 number
|
||||
*/
|
||||
@@ -138,7 +146,7 @@ main (void)
|
||||
bool is_ok;
|
||||
ssize_t sz;
|
||||
jerry_api_value_t val_t, val_foo, val_bar, val_A, val_A_prototype, val_a, val_a_foo, val_value_field;
|
||||
jerry_api_value_t val_external, val_external_construct, val_call_external, val_call_external_construct;
|
||||
jerry_api_value_t val_external, val_external_construct, val_call_external;
|
||||
jerry_api_object_t* global_obj_p;
|
||||
jerry_api_object_t* external_func_p, *external_construct_p;
|
||||
jerry_api_value_t res, args [2];
|
||||
@@ -303,15 +311,9 @@ main (void)
|
||||
jerry_api_release_value (&val_external_construct);
|
||||
jerry_api_release_object (external_construct_p);
|
||||
|
||||
// Call 'call_external_construct' function that should call external function created above, as constructor
|
||||
is_ok = jerry_api_get_object_field_value (global_obj_p, "call_external_construct", &val_call_external_construct);
|
||||
assert (is_ok
|
||||
&& val_call_external_construct.type == JERRY_API_DATA_TYPE_OBJECT);
|
||||
is_ok = jerry_api_call_function (val_call_external_construct.v_object,
|
||||
global_obj_p,
|
||||
&res,
|
||||
NULL, 0);
|
||||
jerry_api_release_value (&val_call_external_construct);
|
||||
// Call external function created above, as constructor
|
||||
test_api_init_api_value_bool (&args[0], true);
|
||||
is_ok = jerry_api_construct_object (external_construct_p, &res, args, 1);
|
||||
assert (is_ok
|
||||
&& res.type == JERRY_API_DATA_TYPE_OBJECT);
|
||||
is_ok = jerry_api_get_object_field_value (res.v_object,
|
||||
|
||||
Reference in New Issue
Block a user