Rework external function handlers (#4599)
Instead of a fixed number of arguments, a call info structure is passed to the handlers, which can be extended in the future without breaknig the API. This structure holds new.target value, so its getter function is removed. JerryScript-DCO-1.0-Signed-off-by: Zoltan Herczeg zherczeg.u-szeged@partner.samsung.com
This commit is contained in:
+35
-154
@@ -603,6 +603,29 @@ typedef struct
|
||||
|
||||
- [jerry_get_memory_stats](#jerry_get_memory_stats)
|
||||
|
||||
## jerry_call_info_t
|
||||
|
||||
**Summary**
|
||||
|
||||
Call related information passed to [jerry_external_handler_t](#jerry_external_handler_t).
|
||||
|
||||
**Prototype**
|
||||
|
||||
```c
|
||||
typedef struct jerry_call_info_t
|
||||
{
|
||||
jerry_value_t function; /**< invoked function object */
|
||||
jerry_value_t this_value; /**< this value passed to the function */
|
||||
jerry_value_t new_target; /**< current new target value, undefined for non-constructor calls */
|
||||
} jerry_call_info_t;
|
||||
```
|
||||
|
||||
*New in version [[NEXT_RELEASE]]*.
|
||||
|
||||
**See also**
|
||||
|
||||
- [jerry_external_handler_t](#jerry_external_handler_t)
|
||||
|
||||
## jerry_external_handler_t
|
||||
|
||||
**Summary**
|
||||
@@ -612,14 +635,13 @@ Type of an external function handler
|
||||
**Prototype**
|
||||
|
||||
```c
|
||||
typedef jerry_value_t (*jerry_external_handler_t) (const jerry_value_t function_obj,
|
||||
const jerry_value_t this_val,
|
||||
typedef jerry_value_t (*jerry_external_handler_t) (const jerry_call_info_t *call_info_p,
|
||||
const jerry_value_t args_p[],
|
||||
const jerry_length_t args_count);
|
||||
```
|
||||
|
||||
- `function_object` - the JavaScript function object which was invoked.
|
||||
- `this_val` - the `this` value provided for the function call.
|
||||
- `call_info_p` - pointer to a [jerry_call_info_t](#jerry_call_info_t)
|
||||
structure which holds call related information.
|
||||
- `args_p` - the function arguments, array of JavaScript values.
|
||||
- `args_count` - the number of arguments.
|
||||
- return value
|
||||
@@ -2830,8 +2852,7 @@ jerry_binary_operation (jerry_binary_operation_t op,
|
||||
#include "jerryscript.h"
|
||||
|
||||
static jerry_value_t
|
||||
my_constructor (const jerry_value_t func_val,
|
||||
const jerry_value_t this_val,
|
||||
my_constructor (const jerry_call_info_t *call_info_p,
|
||||
const jerry_value_t argv[],
|
||||
const jerry_length_t argc)
|
||||
{
|
||||
@@ -5161,12 +5182,11 @@ jerry_create_external_function (jerry_external_handler_t handler_p);
|
||||
#include "jerryscript.h"
|
||||
|
||||
static jerry_value_t
|
||||
handler (const jerry_value_t function_obj,
|
||||
const jerry_value_t this_val,
|
||||
handler (const jerry_call_info_t *call_info_p,
|
||||
const jerry_value_t args_p[],
|
||||
const jerry_length_t args_cnt)
|
||||
{
|
||||
printf ("native handler called!\n");
|
||||
printf ("Native handler called!\n");
|
||||
|
||||
return jerry_create_boolean (true);
|
||||
}
|
||||
@@ -7139,8 +7159,7 @@ Registering a getter/setter property via the `jerry_define_own_property` method:
|
||||
static int counter = 0;
|
||||
|
||||
static jerry_value_t
|
||||
method_getter (const jerry_value_t this_obj,
|
||||
const jerry_value_t func_obj,
|
||||
method_getter (const jerry_call_info_t *call_info_p,
|
||||
const jerry_value_t args[],
|
||||
const jerry_length_t argc)
|
||||
{
|
||||
@@ -7151,8 +7170,7 @@ method_getter (const jerry_value_t this_obj,
|
||||
}
|
||||
|
||||
static jerry_value_t
|
||||
method_setter (const jerry_value_t this_obj,
|
||||
const jerry_value_t func_obj,
|
||||
method_setter (const jerry_call_info_t *call_info_p,
|
||||
const jerry_value_t args[],
|
||||
const jerry_length_t argc)
|
||||
{
|
||||
@@ -9052,8 +9070,7 @@ jerry_get_backtrace (uint32_t max_depth);
|
||||
#include "jerryscript.h"
|
||||
|
||||
static jerry_value_t
|
||||
backtrace_handler (const jerry_value_t function_obj,
|
||||
const jerry_value_t this_val,
|
||||
backtrace_handler (const jerry_call_info_t *call_info_p,
|
||||
const jerry_value_t args_p[],
|
||||
const jerry_length_t args_count)
|
||||
{
|
||||
@@ -9178,13 +9195,11 @@ backtrace_callback (jerry_backtrace_frame_t *frame_p,
|
||||
}
|
||||
|
||||
static jerry_value_t
|
||||
backtrace_handler (const jerry_value_t function_obj,
|
||||
const jerry_value_t this_val,
|
||||
backtrace_handler (const jerry_call_info_t *call_info_p,
|
||||
const jerry_value_t args_p[],
|
||||
const jerry_length_t args_count)
|
||||
{
|
||||
(void) function_obj;
|
||||
(void) this_val;
|
||||
(void) call_info_p;
|
||||
(void) args_p;
|
||||
(void) args_count;
|
||||
|
||||
@@ -9594,8 +9609,7 @@ jerry_get_resource_name (jerry_value_t value);
|
||||
#include "jerryscript.h"
|
||||
|
||||
static jerry_value_t
|
||||
resource_name_handler (const jerry_value_t function_obj,
|
||||
const jerry_value_t this_val,
|
||||
resource_name_handler (const jerry_call_info_t *call_info_p,
|
||||
const jerry_value_t args_p[],
|
||||
const jerry_length_t args_count)
|
||||
{
|
||||
@@ -9655,139 +9669,6 @@ main (void)
|
||||
|
||||
- [jerry_create_external_function](#jerry_create_external_function)
|
||||
|
||||
## jerry_get_new_target
|
||||
|
||||
**Summary**
|
||||
|
||||
Returns the current "new.target" JavaScript function at the call site.
|
||||
|
||||
If used outside of a native C function it will return "undefined" value.
|
||||
|
||||
*Notes*:
|
||||
- Returned value must be freed with [jerry_release_value](#jerry_release_value) when it
|
||||
is no longer needed.
|
||||
- This feature depends on build option (`JERRY_ESNEXT`) and can be checked
|
||||
in runtime with the `JERRY_FEATURE_SYMBOL` feature enum value (as symbols are enabled in case of ES.next),
|
||||
see: [jerry_is_feature_enabled](#jerry_is_feature_enabled).
|
||||
- If the ES.next mode is not enabled this method will always return the "undefined" value.
|
||||
|
||||
**Prototype**
|
||||
|
||||
```c
|
||||
jerry_value_t
|
||||
jerry_get_new_target (void);
|
||||
```
|
||||
- return
|
||||
- "undefined" - if at the call site it was not a constructor call.
|
||||
- function object - if the current call site is in a constructor call.
|
||||
|
||||
*New in version 2.2*.
|
||||
|
||||
**Example 1**
|
||||
|
||||
[doctest]: # (name="02.API-REFERENCE-jsnewtarget-01.c")
|
||||
|
||||
```c
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <jerryscript.h>
|
||||
|
||||
static jerry_value_t
|
||||
demo_handler (const jerry_value_t func_obj_val,
|
||||
const jerry_value_t this_val,
|
||||
const jerry_value_t args_p[],
|
||||
const jerry_length_t args_cnt)
|
||||
{
|
||||
jerry_value_t new_target = jerry_get_new_target ();
|
||||
|
||||
/* new_target is the "demo" JS function object */
|
||||
if (jerry_value_get_type (new_target) == JERRY_TYPE_FUNCTION)
|
||||
{
|
||||
printf ("This is a construct call\r\n");
|
||||
}
|
||||
|
||||
jerry_release_value (new_target);
|
||||
|
||||
return jerry_create_undefined ();
|
||||
}
|
||||
|
||||
int
|
||||
main (int argc, char** argv)
|
||||
{
|
||||
jerry_init (JERRY_INIT_EMPTY);
|
||||
|
||||
jerry_value_t function_val = jerry_create_external_function (demo_handler);
|
||||
|
||||
jerry_value_t ret_val = jerry_construct_object (function_val, NULL, 0);
|
||||
|
||||
jerry_release_value (ret_val);
|
||||
jerry_release_value (function_val);
|
||||
|
||||
jerry_cleanup ();
|
||||
return 0;
|
||||
}
|
||||
```
|
||||
|
||||
**Example 2**
|
||||
|
||||
[doctest]: # (name="02.API-REFERENCE-jsnewtarget-02.c")
|
||||
|
||||
```c
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <jerryscript.h>
|
||||
|
||||
static jerry_value_t
|
||||
demo_handler (const jerry_value_t func_obj_val,
|
||||
const jerry_value_t this_val,
|
||||
const jerry_value_t args_p[],
|
||||
const jerry_length_t args_cnt)
|
||||
{
|
||||
jerry_value_t new_target = jerry_get_new_target ();
|
||||
|
||||
/* new_target is a JS function object */
|
||||
if (jerry_value_get_type (new_target) == JERRY_TYPE_FUNCTION)
|
||||
{
|
||||
printf ("This is a construct call\r\n");
|
||||
}
|
||||
|
||||
jerry_release_value (new_target);
|
||||
|
||||
return jerry_create_undefined ();
|
||||
}
|
||||
|
||||
int
|
||||
main (int argc, char** argv)
|
||||
{
|
||||
jerry_init (JERRY_INIT_EMPTY);
|
||||
|
||||
/* register C method */
|
||||
jerry_value_t global_obj_val = jerry_get_global_object ();
|
||||
jerry_value_t function_val = jerry_create_external_function (demo_handler);
|
||||
jerry_value_t function_name_val = jerry_create_string ((const jerry_char_t *) "demo");
|
||||
jerry_value_t result_val = jerry_set_property (global_obj_val, function_name_val, function_val);
|
||||
jerry_release_value (result_val);
|
||||
jerry_release_value (function_name_val);
|
||||
jerry_release_value (function_val);
|
||||
jerry_release_value (global_obj_val);
|
||||
|
||||
/* Invoke C method via JS */
|
||||
const char *src = "new demo ()";
|
||||
jerry_value_t ret_val = jerry_eval ((const jerry_char_t *) src,
|
||||
strlen (src),
|
||||
JERRY_PARSE_NO_OPTS);
|
||||
|
||||
jerry_release_value (ret_val);
|
||||
|
||||
jerry_cleanup ();
|
||||
return 0;
|
||||
}
|
||||
```
|
||||
|
||||
**See also**
|
||||
|
||||
- [jerry_construct_object](#jerry_construct_object)
|
||||
|
||||
# Functions for realm objects
|
||||
|
||||
These APIs all depend on build option (`JERRY_BUILTIN_REALMS`).
|
||||
|
||||
+6
-10
@@ -214,8 +214,7 @@ The `api-example-4.c` file should contain the following code:
|
||||
#include "jerryscript.h"
|
||||
|
||||
static jerry_value_t
|
||||
print_handler (const jerry_value_t function_object,
|
||||
const jerry_value_t function_this,
|
||||
print_handler (const jerry_call_info_t *call_info_p,
|
||||
const jerry_value_t arguments[],
|
||||
const jerry_length_t argument_count)
|
||||
{
|
||||
@@ -316,8 +315,7 @@ The `api-example-5.c` file should contain the following code:
|
||||
#include "jerryscript.h"
|
||||
|
||||
static jerry_value_t
|
||||
print_handler (const jerry_value_t function_object,
|
||||
const jerry_value_t function_this,
|
||||
print_handler (const jerry_call_info_t *call_info_p,
|
||||
const jerry_value_t arguments[],
|
||||
const jerry_length_t arguments_count)
|
||||
{
|
||||
@@ -851,8 +849,7 @@ struct my_struct
|
||||
* Get a string from a native object
|
||||
*/
|
||||
static jerry_value_t
|
||||
get_msg_handler (const jerry_value_t func_value, /**< function object */
|
||||
const jerry_value_t this_value, /**< this arg */
|
||||
get_msg_handler (const jerry_call_info_t *call_info_p, /**< call information */
|
||||
const jerry_value_t *args_p, /**< function arguments */
|
||||
const jerry_length_t args_cnt) /**< number of function arguments */
|
||||
{
|
||||
@@ -955,8 +952,7 @@ Use the following code for `api-example-10.c`:
|
||||
* Add param to 'this.x'
|
||||
*/
|
||||
static jerry_value_t
|
||||
add_handler (const jerry_value_t func_value, /**< function object */
|
||||
const jerry_value_t this_val, /**< this arg */
|
||||
add_handler (const jerry_call_info_t *call_info_p, /**< call information */
|
||||
const jerry_value_t args_p[], /**< function arguments */
|
||||
const jerry_length_t args_cnt) /**< number of function arguments */
|
||||
{
|
||||
@@ -965,7 +961,7 @@ add_handler (const jerry_value_t func_value, /**< function object */
|
||||
|
||||
/* Get 'this.x' */
|
||||
jerry_value_t prop_name = jerry_create_string ((const jerry_char_t *) "x");
|
||||
jerry_value_t x_val = jerry_get_property (this_val, prop_name);
|
||||
jerry_value_t x_val = jerry_get_property (call_info_p->this_value, prop_name);
|
||||
|
||||
if (!jerry_value_is_error (x_val))
|
||||
{
|
||||
@@ -977,7 +973,7 @@ add_handler (const jerry_value_t func_value, /**< function object */
|
||||
jerry_value_t res_val = jerry_create_number (x + d);
|
||||
|
||||
/* Set the new value of 'this.x' */
|
||||
jerry_release_value (jerry_set_property (this_val, prop_name, res_val));
|
||||
jerry_release_value (jerry_set_property (call_info_p->this_value, prop_name, res_val));
|
||||
jerry_release_value (res_val);
|
||||
}
|
||||
|
||||
|
||||
@@ -267,8 +267,7 @@ jerryx_set_properties (const jerry_value_t target_object,
|
||||
#include "jerryscript-ext/handler.h"
|
||||
|
||||
static jerry_value_t
|
||||
handler (const jerry_value_t function_obj,
|
||||
const jerry_value_t this_val,
|
||||
handler (const jerry_call_info_t *call_info_p,
|
||||
const jerry_value_t args_p[],
|
||||
const jerry_length_t args_cnt)
|
||||
{
|
||||
@@ -331,8 +330,7 @@ when setting a property entry:
|
||||
#include "jerryscript-ext/handler.h"
|
||||
|
||||
static jerry_value_t
|
||||
handler (const jerry_value_t function_obj,
|
||||
const jerry_value_t this_val,
|
||||
handler (const jerry_call_info_t *call_info_p,
|
||||
const jerry_value_t args_p[],
|
||||
const jerry_length_t args_cnt)
|
||||
{
|
||||
|
||||
Reference in New Issue
Block a user