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`).
|
||||
|
||||
Reference in New Issue
Block a user