0b1d75a7db
There was some issues and typos in the EXT-REFERENCE documentation. This patch fixes these issues and typos. JerryScript-DCO-1.0-Signed-off-by: Gergo Csizi gergocs@inf.u-szeged.hu
408 lines
11 KiB
Markdown
408 lines
11 KiB
Markdown
# Common methods to handle properties
|
|
|
|
The `jerryscript-ext/properties.h` header defines a set of convenience methods
|
|
which makes the property access a bit straightforward.
|
|
|
|
# Utility to register multiple properties in bulk
|
|
|
|
In some cases it is useful to register multiple properties for a given object
|
|
for this the following utility structures and methods are provided.
|
|
|
|
## jerryx_property_entry
|
|
|
|
**Summary**
|
|
|
|
Structure to define an array of properties with `name` and `value` fields which
|
|
can be registered to a target object.
|
|
|
|
The engine must be initialized before specifying the `jerry_value_t` in the struct.
|
|
|
|
|
|
**Prototype**
|
|
|
|
```c
|
|
typedef struct {
|
|
const char *name;
|
|
jerry_value_t value;
|
|
} jerryx_property_entry;
|
|
```
|
|
|
|
**See also**
|
|
|
|
- [jerryx_set_properties](#jerryx_set_properties)
|
|
|
|
|
|
## jerryx_register_result
|
|
|
|
**Summary**
|
|
|
|
Structure returned as the result of the [jerryx_set_properties](#jerryx_set_properties) operation.
|
|
The `result` field will either be a JavaScript undefined value or an error object.
|
|
In every case the `registered` field is used to indicated the number of
|
|
successfully registered methods.
|
|
|
|
This must be passed for the [jerryx_release_property_entry](#jerryx_release_property_entry) method
|
|
after the property registration.
|
|
|
|
If any error occurred during the property registration the `result` field of the structure
|
|
must be manually released after processing the error value.
|
|
|
|
**Prototype**
|
|
|
|
```c
|
|
typedef struct {
|
|
jerry_value_t result;
|
|
uint32_t registered;
|
|
} jerryx_register_result;
|
|
```
|
|
|
|
**See also**
|
|
|
|
- [jerryx_set_properties](#jerryx_set_properties)
|
|
- [jerryx_release_property_entry](#jerryx_release_property_entry)
|
|
|
|
|
|
## jerryx_set_properties
|
|
|
|
**Summary**
|
|
|
|
Set multiple properties on a target object.
|
|
|
|
The properties are an array of (name, jerry_value_t) pairs and
|
|
this list must end with a (NULL, 0) entry.
|
|
|
|
Important notes:
|
|
* Each property value in the input array is released after a successful property registration.
|
|
* The method [jerryx_release_property_entry](#jerryx_release_property_entry) must be called if there is any failed registration
|
|
to release the values in the entries array.
|
|
It is safe to call this cleanup method in every case not just in case of failure.
|
|
* If the error value is reported via the result it must be freed manually.
|
|
|
|
**Prototype**
|
|
|
|
```c
|
|
jerryx_register_result
|
|
jerryx_set_properties (const jerry_value_t target_object,
|
|
const jerryx_property_entry entries[]);
|
|
```
|
|
|
|
- `target_object` - object on which the entries will be set.
|
|
- `entries` - array of (name, jerry_value_t) pairs.
|
|
- return a [jerryx_register_result](#jerryx_register_result).
|
|
- if everything is ok, the struct's `result` field is set to a JS undefined value.
|
|
- otherwise the `result` field is an error object indicating the problem.
|
|
- in every case the `registered` field contains the number of successfully registered properties.
|
|
|
|
**Example**
|
|
|
|
[doctest]: # ()
|
|
|
|
```c
|
|
#include <stdio.h>
|
|
#include "jerryscript.h"
|
|
#include "jerryscript-ext/handlers.h"
|
|
#include "jerryscript-ext/properties.h"
|
|
|
|
static jerry_value_t
|
|
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");
|
|
|
|
return jerry_boolean (true);
|
|
}
|
|
|
|
int
|
|
main (int argc, char **argv)
|
|
{
|
|
jerry_init (JERRY_INIT_EMPTY);
|
|
|
|
jerryx_property_entry methods[] =
|
|
{
|
|
{ "demo", jerry_function_external (handler) },
|
|
{ NULL, 0 },
|
|
};
|
|
|
|
jerry_value_t global = jerry_current_realm ();
|
|
jerryx_register_result reg = jerryx_set_properties (global, methods);
|
|
/* if `reg.result` is undefined all methods are registered */
|
|
if (jerry_value_is_exception (reg.result))
|
|
{
|
|
printf ("Only registered %d properties\r\n", reg.registered);
|
|
/* clean up not registered property values */
|
|
jerryx_release_property_entry (methods, reg);
|
|
|
|
/* clean up the error */
|
|
jerry_value_free (reg.result);
|
|
}
|
|
|
|
jerry_value_free (global);
|
|
|
|
jerry_cleanup();
|
|
|
|
return 0;
|
|
}
|
|
```
|
|
|
|
**Convenience macros**
|
|
|
|
To make property registration convenient, there are a set of macros to use
|
|
when setting a property entry:
|
|
|
|
* `JERRYX_PROPERTY_NUMBER(NAME, NUMBER)` - creates a number entry.
|
|
* `JERRYX_PROPERTY_STRING(NAME, STR, SIZE)` - creates an UTF-8 string entry using `SIZE` bytes from the string.
|
|
* `JERRYX_PROPERTY_STRING_SZ(NAME, STR)` - creates an ASCII string entry. This string must be zero terminated.
|
|
* `JERRYX_PROPERTY_BOOLEAN(NAME, VALUE)` - creates a boolean entry.
|
|
* `JERRYX_PROPERTY_FUNCTION(NAME, NATIVE)` - creates a native C function entry.
|
|
* `JERRYX_PROPERTY_UNDEFINED(NAME)` - creates an undefined property entry.
|
|
* `JERRYX_PROPERTY_LIST_END()` - indicates the end of the property list.
|
|
|
|
**Example usage of Convenience macros**
|
|
|
|
[doctest]: # ()
|
|
|
|
```c
|
|
#include <stdio.h>
|
|
#include "jerryscript.h"
|
|
#include "jerryscript-ext/handlers.h"
|
|
#include "jerryscript-ext/properties.h"
|
|
|
|
static jerry_value_t
|
|
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");
|
|
|
|
return jerry_boolean (true);
|
|
}
|
|
|
|
int
|
|
main (int argc, char **argv)
|
|
{
|
|
jerry_init (JERRY_INIT_EMPTY);
|
|
|
|
/**
|
|
* Create a array of properties to be registered.
|
|
* This must be done after initializing the engine as creating `jerry_value_t`
|
|
* elements are invalid before `jerry_init`.
|
|
*/
|
|
jerryx_property_entry methods[] =
|
|
{
|
|
JERRYX_PROPERTY_FUNCTION ("demo", handler),
|
|
JERRYX_PROPERTY_NUMBER ("test_num", 2.3),
|
|
JERRYX_PROPERTY_UNDEFINED ("this_is_undefined"),
|
|
JERRYX_PROPERTY_LIST_END(),
|
|
};
|
|
|
|
jerry_value_t global = jerry_current_realm ();
|
|
jerryx_register_result reg = jerryx_set_properties (global, methods);
|
|
/* if `reg.result` is undefined all methods are registered */
|
|
if (jerry_value_is_exception (reg.result))
|
|
{
|
|
printf ("Only registered %d properties\r\n", reg.registered);
|
|
/* clean up not registered property values */
|
|
jerryx_release_property_entry (methods, reg);
|
|
|
|
/* clean up the error */
|
|
jerry_value_free (reg.result);
|
|
}
|
|
|
|
jerry_value_free (global);
|
|
|
|
jerry_cleanup();
|
|
|
|
return 0;
|
|
}
|
|
```
|
|
|
|
|
|
**See also**
|
|
|
|
- [jerryx_property_entry](#jerryx_property_entry)
|
|
- [jerryx_release_property_entry](#jerryx_release_property_entry)
|
|
- [jerryx_register_result](#jerryx_register_result)
|
|
|
|
## jerryx_release_property_entry
|
|
|
|
**Summary**
|
|
|
|
Release all `jerry_value_t` in a `jerryx_property_entry` array based on a previous [jerryx_set_properties](#jerryx_set_properties) call
|
|
and also the error value (if any) in the `jerryx_register_result` structure.
|
|
In case of a successful registration it is safe to call this method.
|
|
|
|
After the method call the `entries` array should not be used as all values are released.
|
|
|
|
**Prototype**
|
|
|
|
```
|
|
void
|
|
jerryx_release_property_entry (const jerryx_property_entry entries[],
|
|
const jerryx_register_result register_result);
|
|
```
|
|
|
|
- `entries` - array of [jerryx_property_entry](#jerryx_property_entry).
|
|
- `register_result` - result of a previous [jerryx_set_properties](#jerryx_set_properties) call.
|
|
|
|
**Example**
|
|
|
|
For example usage see [jerryx_set_properties](#jerryx_set_properties).
|
|
|
|
|
|
# Common external function handlers
|
|
|
|
## jerryx_handler_assert
|
|
|
|
**Summary**
|
|
|
|
Hard assert for scripts. The routine calls `jerry_port_fatal` on assertion failure.
|
|
|
|
If the `JERRY_FEATURE_LINE_INFO` runtime feature is enabled (build option: `JERRY_LINE_INFO`)
|
|
a backtrace is also printed out.
|
|
|
|
**Prototype**
|
|
|
|
```c
|
|
jerry_value_t
|
|
jerryx_handler_assert (const jerry_call_info_t *call_info_p,
|
|
const jerry_value_t args_p[],
|
|
const jerry_length_t args_cnt);
|
|
```
|
|
|
|
- `call_info_p` - pointer to a [jerry_call_info_t](#jerry_call_info_t)
|
|
structure which holds call related information (unused).
|
|
- `args_p` - the array of function arguments.
|
|
- `args_cnt` - the number of function arguments.
|
|
- return value - `jerry_value_t` representing boolean true, if only one argument
|
|
was passed and that argument was a boolean true. Note that the function does
|
|
not return otherwise.
|
|
|
|
**See also**
|
|
|
|
- [jerryx_register_global](#jerryx_register_global)
|
|
|
|
|
|
## jerryx_handler_gc
|
|
|
|
**Summary**
|
|
|
|
Expose garbage collector to scripts. If the first argument of the function
|
|
is logical true, it performs a high pressure gc. Otherwise a low pressure
|
|
gc is performed, which is also the default if no parameters passed.
|
|
|
|
**Prototype**
|
|
|
|
```c
|
|
jerry_value_t
|
|
jerryx_handler_gc (const jerry_call_info_t *call_info_p,
|
|
const jerry_value_t args_p[],
|
|
const jerry_length_t args_cnt);
|
|
```
|
|
|
|
- `call_info_p` - pointer to a [jerry_call_info_t](#jerry_call_info_t)
|
|
structure which holds call related information (unused).
|
|
- `args_p` - the array of function arguments (unused).
|
|
- `args_cnt` - the number of function arguments (unused).
|
|
- return value - `jerry_value_t` representing `undefined`.
|
|
|
|
**See also**
|
|
|
|
- [jerryx_register_global](#jerryx_register_global)
|
|
|
|
|
|
## jerryx_handler_print
|
|
|
|
**Summary**
|
|
|
|
Provide a `print` implementation for scripts. The routine converts all of its
|
|
arguments to strings and outputs them by using `jerry_port_print_buffer`.
|
|
The NULL character is output as "\u0000", other characters are output bytewise.
|
|
|
|
*Note*: This implementation does not use standard C `printf` to print its
|
|
output. This allows more flexibility but also extends the core JerryScript
|
|
engine port API. Applications that want to use `jerryx_handler_print` must
|
|
ensure that their port implementation also provides
|
|
`jerry_port_print_buffer`.
|
|
|
|
**Prototype**
|
|
|
|
```c
|
|
jerry_value_t
|
|
jerryx_handler_print (const jerry_call_info_t *call_info_p,
|
|
const jerry_value_t args_p[],
|
|
const jerry_length_t args_cnt);
|
|
```
|
|
|
|
- `call_info_p` - pointer to a [jerry_call_info_t](#jerry_call_info_t)
|
|
structure which holds call related information (unused).
|
|
- `args_p` - the array of function arguments.
|
|
- `args_cnt` - the number of function arguments.
|
|
- return value - `jerry_value_t` representing `undefined` if all arguments could
|
|
be converted to strings, an `Error` otherwise.
|
|
|
|
**See also**
|
|
|
|
- [jerryx_register_global](#jerryx_register_global)
|
|
- [jerry_port_print_buffer](05.PORT-API.md#jerry_port_print_buffer)
|
|
|
|
|
|
# Handler registration helper
|
|
|
|
## jerryx_register_global
|
|
|
|
**Summary**
|
|
|
|
Register a JavaScript function in the global object.
|
|
|
|
*Note*: Returned value must be freed with `jerry_value_free`, when it is no
|
|
longer needed.
|
|
|
|
**Prototype**
|
|
|
|
```c
|
|
jerry_value_t
|
|
jerryx_register_global (const char *name_p,
|
|
jerry_external_handler_t handler_p);
|
|
```
|
|
|
|
- `name_p` - the name of the function to be registered.
|
|
- `handler_p` - the address of the external function handler.
|
|
- return value - `jerry_value_t` representing boolean true, if the operation was
|
|
successful, an `Error` otherwise.
|
|
|
|
**Example**
|
|
|
|
[doctest]: # (test="compile")
|
|
|
|
```c
|
|
#include "jerryscript.h"
|
|
#include "jerryscript-ext/handlers.h"
|
|
#include "jerryscript-ext/properties.h"
|
|
|
|
static const struct {
|
|
const char *name_p;
|
|
jerry_external_handler_t handler_p;
|
|
} common_functions[] =
|
|
{
|
|
{ "assert", jerryx_handler_assert },
|
|
{ "gc", jerryx_handler_gc },
|
|
{ "print", jerryx_handler_print },
|
|
{ NULL, NULL }
|
|
};
|
|
|
|
static void
|
|
register_common_functions (void)
|
|
{
|
|
jerry_value_t ret = jerry_undefined ();
|
|
|
|
for (int i = 0; common_functions[i].name_p != NULL && !jerry_value_is_exception (ret); i++)
|
|
{
|
|
ret = jerryx_register_global (common_functions[i].name_p,
|
|
common_functions[i].handler_p);
|
|
}
|
|
|
|
jerry_value_free (ret);
|
|
}
|
|
```
|