Update the webpage (#1941)

* Add new documents about autorelease values and module support

JerryScript-DCO-1.0-Signed-off-by: Zsolt Borbély zsborbely.u-szeged@partner.samsung.com
This commit is contained in:
Zsolt Borbély 2017-08-01 16:00:13 +02:00 committed by GitHub
parent 5d2b25659d
commit 49c24ca464
7 changed files with 923 additions and 153 deletions

View File

@ -111,6 +111,25 @@ created by API functions has the error flag set.
typedef uint32_t jerry_value_t;
```
## jerry_context_data_manager_t
**Summary**
Structure that defines how a context data item will be initialized and deinitialized. JerryScript zeroes out the memory
for the item by default, and if the `init_cb` field is not NULL, it will be called with the pointer to the memory as
an additional custom initializer.
**Prototype**
```c
typedef struct
{
void (*init_cb) (void *); /**< callback responsible for initializing a context item, or NULL */
void (*deinit_cb) (void *); /**< callback responsible for deinitializing a context item */
size_t bytes_needed; /**< number of bytes to allocate for this manager */
} jerry_context_data_manager_t;
```
## jerry_property_descriptor_t
**Summary**
@ -274,9 +293,7 @@ typedef jerry_value_t (*jerry_vm_exec_stop_callback_t) (void *user_p);
**Summary**
Initializes the JerryScript engine, making it possible to run JavaScript code and perform operations
on JavaScript values. See also [jerry_init_with_user_context](#jerry_init_with_user_context) if you
wish to initialize the JerryScript engine in such a way that its context contains a custom pointer
which you can later retrieve using [jerry_get_user_context](#jerry_get_user_context).
on JavaScript values.
**Prototype**
@ -296,7 +313,13 @@ jerry_init (jerry_init_flag_t flags)
**Example**
[doctest]: # ()
```c
#include "jerryscript.h"
int
main (void)
{
jerry_init (JERRY_INIT_SHOW_OPCODES | JERRY_INIT_SHOW_REGEXP_OPCODES);
@ -309,91 +332,13 @@ jerry_init (jerry_init_flag_t flags)
**See also**
- [jerry_cleanup](#jerry_cleanup)
- [jerry_init_with_user_context](#jerry_init_with_user_context)
## jerry_init_with_user_context
**Summary**
Calls [jerry_init](#jerry_init) to initialize the JerryScript engine, thereby making it possible
to run JavaScript code and perform operations on JavaScript values. In addition to the first
parameter this function accepts two more parameters with which it allows the caller to store a
`void *` pointer inside the context being initialized with `jerry_init ()`. The function calls the
callback given in its `init_cb` parameter to allocate the memory for the pointer and it stores the
function pointer given in the `deinit_cb` parameter along with the pointer so that it may be called
to free the stored pointer when `jerry_cleanup ()` is later called to dispose of the context.
**Prototype**
```c
void
jerry_init_with_user_context (jerry_init_flag_t flags,
jerry_user_context_init_cb init_cb,
jerry_user_context_deinit_cb deinit_cb);
```
`flags` - combination of various engine configuration flags:
- `JERRY_INIT_EMPTY` - no flags, just initialize in default configuration.
- `JERRY_INIT_SHOW_OPCODES` - print compiled byte-code.
- `JERRY_INIT_SHOW_REGEXP_OPCODES` - print compiled regexp byte-code.
- `JERRY_INIT_MEM_STATS` - dump memory statistics.
- `JERRY_INIT_MEM_STATS_SEPARATE` - dump memory statistics and reset peak values after parse.
- `JERRY_INIT_DEBUGGER` - enable all features required by debugging.
`init_cb` - a function pointer that will be called to allocate the custom pointer.
`deinit_cb` - a function pointer that will be called when the custom pointer must be freed.
**Example**
```c
void *
init_user_context (void)
{
void *return_value;
/* allocate and initialize return_value */
return return_value;
} /* init_user_context */
void
free_user_context (void *context)
{
/* free the value allocated above */
} /* free_user_context */
{
/* init_user_context () will be called before the call below returns */
jerry_init_with_user_context (JERRY_INIT_SHOW_OPCODES | JERRY_INIT_SHOW_REGEXP_OPCODES,
init_user_context,
free_user_context);
/* ... */
/* free_user_context () will be called before the call below returns */
jerry_cleanup ();
}
```
**See also**
- [jerry_cleanup](#jerry_cleanup)
- [jerry_get_user_context](#jerry_get_user_context)
## jerry_cleanup
**Summary**
Finish JavaScript engine execution, freeing memory and JavaScript values. If the context was
initialized with `jerry_init_with_user_context ()` and a `deinit_cb` was provided, then it will
be called to free the memory at the custom pointer which was associated with the context being
cleaned up.
Finish JavaScript engine execution, freeing memory and JavaScript values.
*Note*: JavaScript values, received from engine, will be inaccessible after the cleanup.
@ -407,38 +352,86 @@ jerry_cleanup (void);
**See also**
- [jerry_init](#jerry_init)
- [jerry_init_with_user_context](#jerry_init_with_user_context)
## jerry_get_user_context
## jerry_get_context_data
**Summary**
Retrieve the pointer stored within the current context.
Retrieve a pointer to the item stored within the current context by the given manager.
*Note*: Since internally the pointer to a manager's context data item is linked to the next such pointer in a linked
list, it is inadvisable to invoke too many different managers, because doing so will increase the time it takes
to retrieve a manager's context data item, degrading performance. For example, try to keep the number of
managers below five.
**Prototype**
```c
void *
jerry_get_user_context (void);
jerry_get_context_data (const jerry_context_data_manager *manager_p);
```
- return value: the pointer that was assigned during `jerry_init_with_user_context ()`
- `manager_p`: the manager of this context data item.
- return value: the item created by `manager_p` when `jerry_get_context_data ()` was first called, or a new item created
by `manager_p`, which will be stored for future identical calls to `jerry_get_context_data ()`, and which will be
deinitialized using the `deinit_cb` callback provided by `manager_p` when the context will be destroyed.
**Example**
[doctest]: # (test="compile")
```c
#include "jerryscript.h"
typedef struct
{
/* ... */
my_context *custom_data = (my_context *) jerry_get_user_context ();
/* ... */
int my_data1;
double my_data2;
char *my_data3;
} my_context_data_t;
/* Define how context items will be initialized. */
static void
my_context_data_new (void *user_data_p)
{
my_context_data_t *my_data_p = (my_context_data_t *) user_data_p;
/*
* Initialize my_data_p. JerryScript will store it on the current context and return it whenever
* jerry_get_context_data () is called with a pointer to my_manager as defined below.
*/
}
/* Define how context items will be deinitialized */
static void
my_context_data_free (void *user_data_p)
{
my_context_data_t *my_data_p = ((my_context_data_t *) user_data_p);
/* Perform any necessary cleanup on my_data. JerryScript will free the pointer after this function completes. */
}
/* Wrap the creation and destruction functions into a manager */
static const jerry_context_data_manager_t my_manager =
{
.init_cb = my_context_data_new,
.deinit_cb = my_context_data_free,
.bytes_needed = sizeof (my_context_data_t)
};
/*
* Then, in some function in your code, you can retrieve an item of type my_context_data_t from the currently active
* context such that JerryScript will create and store such an item if one was not previously created
*/
static void
someplace_in_the_code (void)
{
my_context_data_t *my_data = (my_context_data_t *) jerry_get_context_data (&my_manager);
/* Perform useful things using the data found in my_data */
}
```
**See also**
- [jerry_init_with_user_context](#jerry_init_with_user_context)
- [jerry_cleanup](#jerry_cleanup)
## jerry_register_magic_strings
@ -463,7 +456,13 @@ jerry_register_magic_strings (const jerry_char_ptr_t *ex_str_items_p,
**Example**
[doctest]: # ()
```c
#include "jerryscript.h"
int
main (void)
{
jerry_init (JERRY_INIT_EMPTY);
@ -478,9 +477,9 @@ jerry_register_magic_strings (const jerry_char_ptr_t *ex_str_items_p,
// must be static, because 'jerry_register_magic_strings' does not copy
static const jerry_length_t magic_string_lengths[] = {
(jerry_length_t)strlen (magic_string_items[0]),
(jerry_length_t)strlen (magic_string_items[1]),
(jerry_length_t)strlen (magic_string_items[2])
12,
12,
12
};
jerry_register_magic_strings (magic_string_items, num_magic_string_items, magic_string_lengths);
}
@ -512,7 +511,13 @@ jerry_get_memory_limits (size_t *out_data_bss_brk_limit_p,
**Example**
[doctest]: # ()
```c
#include "jerryscript.h"
int
main (void)
{
jerry_init (JERRY_INIT_EMPTY);
@ -580,9 +585,16 @@ jerry_run_simple (const jerry_char_t *script_source_p,
**Example**
[doctest]: # ()
```c
#include <string.h>
#include "jerryscript.h"
int
main (void)
{
const jerry_char_t *script = "print ('Hello, World!');";
const jerry_char_t *script = (const jerry_char_t *) "print ('Hello, World!');";
jerry_run_simple (script, strlen ((const char *) script), JERRY_INIT_EMPTY);
}
@ -624,7 +636,14 @@ jerry_parse (const jerry_char_t *source_p,
**Example**
[doctest]: # ()
```c
#include <string.h>
#include "jerryscript.h"
int
main (void)
{
jerry_init (JERRY_INIT_EMPTY);
@ -699,7 +718,14 @@ jerry_run (const jerry_value_t func_val);
**Example**
[doctest]: # ()
```c
#include <string.h>
#include "jerryscript.h"
int
main (void)
{
const jerry_char_t script[] = "print ('Hello, World!');";
size_t script_size = strlen ((const char *) script);
@ -767,6 +793,49 @@ jerry_eval (const jerry_char_t *source_p,
- [jerry_create_external_function](#jerry_create_external_function)
- [jerry_external_handler_t](#jerry_external_handler_t)
## jerry_run_all_enqueued_jobs
**Summary**
Run enqueued Promise jobs until the first thrown error or until all get executed.
**Prototype**
```c
jerry_value_t
jerry_run_all_enqueued_jobs (void)
```
- return value - result of last executed job, may be error value.
**Example**
[doctest]: # ()
```c
#include <string.h>
#include "jerryscript.h"
int
main (void)
{
jerry_init (JERRY_INIT_EMPTY);
const jerry_char_t script[] = "new Promise(function(f,r) { f('Hello, World!'); }).then(function(x) { print(x); });";
size_t script_size = strlen ((const char *) script);
jerry_value_t parsed_code = jerry_parse (script, script_size, false);
jerry_value_t script_value = jerry_run (parsed_code);
jerry_value_t job_value = jerry_run_all_enqueued_jobs ();
jerry_release_value (job_value);
jerry_release_value (script_value);
jerry_release_value (parsed_code);
jerry_cleanup ();
}
```
# Get the global context
@ -2562,6 +2631,7 @@ jerry_create_promise (void)
jerry_release_value (p);
}
```
**See also**
@ -2759,19 +2829,22 @@ jerry_create_undefined (void);
**Summary**
Checks whether the object or it's prototype objects have the given property.
Checks whether the object or its prototype objects have the given property.
*Note*: Returned value must be freed with [jerry_release_value](#jerry_release_value) when it
is no longer needed.
**Prototype**
```c
bool
jerry_value_t
jerry_has_property (const jerry_value_t obj_val,
const jerry_value_t prop_name_val);
```
- `obj_val` - object value
- `prop_name_val` - property name
- return value
- return value - JavaScript boolean value that evaluates to
- true, if the property exists
- false, otherwise
@ -2782,8 +2855,10 @@ jerry_has_property (const jerry_value_t obj_val,
jerry_value_t global_object = jerry_get_global_object ();
jerry_value_t prop_name = jerry_create_string ((const jerry_char_t *) "handler_field");
bool has_prop = jerry_has_property (global_object, prop_name);
jerry_value_t has_prop_js = jerry_has_property (global_object, prop_name);
bool has_prop = jerry_get_boolean_value (has_prop_js);
jerry_release_value (has_prop_js);
jerry_release_value (prop_name);
jerry_release_value (global_object);
}
@ -2801,17 +2876,20 @@ jerry_has_property (const jerry_value_t obj_val,
Checks whether the object has the given property.
*Note*: Returned value must be freed with [jerry_release_value](#jerry_release_value) when it
is no longer needed.
**Prototype**
```c
bool
jerry_value_t
jerry_has_own_property (const jerry_value_t obj_val,
const jerry_value_t prop_name_val);
```
- `obj_val` - object value
- `prop_name_val` - property name
- return value
- return value - JavaScript boolean value that evaluates to
- true, if the property exists
- false, otherwise
@ -2822,8 +2900,10 @@ jerry_has_own_property (const jerry_value_t obj_val,
jerry_value_t global_object = jerry_get_global_object ();
jerry_value_t prop_name = jerry_create_string ((const jerry_char_t *) "handler_field");
bool has_prop = jerry_has_own_property (global_object, prop_name);
jerry_value_t has_prop_js = jerry_has_own_property (global_object, prop_name);
bool has_prop = jerry_get_boolean_value (has_prop_js);
jerry_release_value (jas_prop_js);
jerry_release_value (prop_name);
jerry_release_value (global_object);
}
@ -2873,9 +2953,55 @@ jerry_delete_property (const jerry_value_t obj_val,
- [jerry_has_property](#jerry_has_property)
- [jerry_has_own_property](#jerry_has_own_property)
- [jerry_delete_property_by_index](#jerry_delete_property_by_index)
- [jerry_get_property](#jerry_get_property)
## jerry_delete_property_by_index
**Summary**
Delete indexed property from the specified object.
**Prototype**
```c
bool
jerry_delete_property_by_index (const jerry_value_t obj_val,
uint32_t index);
```
- `obj_val` - object value
- `index` - index number
- return value
- true, if property was deleted successfully
- false, otherwise
**Example**
```c
{
jerry_value_t object;
... // create or acquire object
jerry_delete_property_by_index (object, 5);
jerry_release_value (object);
}
```
**See also**
- [jerry_has_property](#jerry_has_property)
- [jerry_has_own_property](#jerry_has_own_property)
- [jerry_delete_property](#jerry_delete_property)
- [jerry_get_property](#jerry_get_property)
- [jerry_set_property](#jerry_set_property)
- [jerry_get_property_by_index](#jerry_get_property_by_index)
- [jerry_set_property_by_index](#jerry_set_property_by_index)
## jerry_get_property
**Summary**
@ -2918,6 +3044,7 @@ jerry_get_property (const jerry_value_t obj_val,
- [jerry_has_property](#jerry_has_property)
- [jerry_has_own_property](#jerry_has_own_property)
- [jerry_delete_property](#jerry_delete_property)
- [jerry_delete_property_by_index](#jerry_delete_property_by_index)
- [jerry_set_property](#jerry_set_property)
- [jerry_get_property_by_index](#jerry_get_property_by_index)
- [jerry_set_property_by_index](#jerry_set_property_by_index)
@ -2968,6 +3095,7 @@ jerry_get_property_by_index (const jerry_value_t obj_val,
- [jerry_has_property](#jerry_has_property)
- [jerry_has_own_property](#jerry_has_own_property)
- [jerry_delete_property](#jerry_delete_property)
- [jerry_delete_property_by_index](#jerry_delete_property_by_index)
- [jerry_get_property](#jerry_get_property)
- [jerry_set_property](#jerry_set_property)
- [jerry_set_property_by_index](#jerry_set_property_by_index)
@ -3028,6 +3156,7 @@ jerry_set_property (const jerry_value_t obj_val,
- [jerry_has_property](#jerry_has_property)
- [jerry_has_own_property](#jerry_has_own_property)
- [jerry_delete_property](#jerry_delete_property)
- [jerry_delete_property_by_index](#jerry_delete_property_by_index)
- [jerry_get_property](#jerry_get_property)
- [jerry_get_property_by_index](#jerry_get_property_by_index)
- [jerry_set_property_by_index](#jerry_set_property_by_index)
@ -3082,6 +3211,7 @@ jerry_set_property_by_index (const jerry_value_t obj_val,
- [jerry_has_property](#jerry_has_property)
- [jerry_has_own_property](#jerry_has_own_property)
- [jerry_delete_property](#jerry_delete_property)
- [jerry_delete_property_by_index](#jerry_delete_property_by_index)
- [jerry_get_property](#jerry_get_property)
- [jerry_set_property](#jerry_set_property)
- [jerry_get_property_by_index](#jerry_get_property_by_index)
@ -3611,6 +3741,9 @@ The pointer and the type information are previously associated with the object b
`out_native_pointer_p` is of the expected type, before casting
and dereferencing `out_native_pointer_p`.
*Note*: `out_native_pointer_p` and `out_native_info_p` can be NULL, and it means the
caller doesn't want to get the native_pointer or type infomation.
**Prototype**
```c
@ -3808,7 +3941,14 @@ jerry_is_valid_utf8_string (const jerry_char_t *utf8_buf_p, /**< UTF-8 string */
**Example**
[doctest]: # ()
```c
#include <string.h>
#include "jerryscript.h"
int
main (void)
{
const jerry_char_t script[] = "print ('Hello, World!');";
size_t script_size = strlen ((const char *) script);
@ -3849,7 +3989,14 @@ jerry_is_valid_cesu8_string (const jerry_char_t *cesu8_buf_p, /**< CESU-8 string
**Example**
[doctest]: # ()
```c
#include <string.h>
#include "jerryscript.h"
int
main (void)
{
jerry_init (JERRY_INIT_EMPTY);
@ -3859,9 +4006,9 @@ jerry_is_valid_cesu8_string (const jerry_char_t *cesu8_buf_p, /**< CESU-8 string
if (jerry_is_valid_cesu8_string (script, (jerry_size_t) script_size))
{
jerry_value_t string_value = jerry_create_string_sz (script,
(jerry_size_t) script_size));
(jerry_size_t) script_size);
... // usage of string_value
// usage of string_value
jerry_release_value (string_value);
}
@ -3914,12 +4061,19 @@ jerry_parse_and_save_snapshot (const jerry_char_t *source_p,
**Example**
[doctest]: # ()
```c
#include <string.h>
#include "jerryscript.h"
int
main (void)
{
jerry_init (JERRY_INIT_EMPTY);
static uint32_t global_mode_snapshot_buffer[256];
const jerry_char_t *code_to_snapshot_p = "(function () { return 'string from snapshot'; }) ();";
const jerry_char_t *code_to_snapshot_p = (const jerry_char_t *) "(function () { return 'string from snapshot'; }) ();";
size_t global_mode_snapshot_size = jerry_parse_and_save_snapshot (code_to_snapshot_p,
strlen ((const char *) code_to_snapshot_p),
@ -3969,11 +4123,17 @@ jerry_exec_snapshot (const uint32_t *snapshot_p,
**Example**
[doctest]: # ()
```c
#include <string.h>
#include "jerryscript.h"
int
main (void)
{
jerry_value_t res;
static uint32_t global_mode_snapshot_buffer[256];
const jerry_char_t *code_to_snapshot_p = "(function () { return 'string from snapshot'; }) ();";
const jerry_char_t *code_to_snapshot_p = (const jerry_char_t *) "(function () { return 'string from snapshot'; }) ();";
jerry_init (JERRY_INIT_EMPTY);
size_t global_mode_snapshot_size = jerry_parse_and_save_snapshot (code_to_snapshot_p,
@ -3986,9 +4146,10 @@ jerry_exec_snapshot (const uint32_t *snapshot_p,
jerry_init (JERRY_INIT_EMPTY);
res = (jerry_exec_snapshot (global_mode_snapshot_buffer,
global_mode_snapshot_size,
false);
jerry_value_t res = jerry_exec_snapshot (global_mode_snapshot_buffer,
global_mode_snapshot_size,
false);
jerry_release_value (res);
jerry_cleanup ();
}
@ -4033,12 +4194,20 @@ jerry_parse_and_save_literals (const jerry_char_t *source_p,
**Example**
[doctest]: # (test="link")
```c
#include <stdio.h>
#include <string.h>
#include "jerryscript.h"
int
main (void)
{
jerry_init (JERRY_INIT_EMPTY);
static uint32_t save_literal_buffer[256];
const jerry_char_t *code_for_literal_save_p = "var obj = { a:'aa', bb:'Bb' }";
const jerry_char_t *code_for_literal_save_p = (const jerry_char_t *) "var obj = { a:'aa', bb:'Bb' }";
size_t literal_sizes = jerry_parse_and_save_literals (code_for_literal_save_p,
strlen ((const char *) code_for_literal_save_p),
@ -4103,12 +4272,17 @@ jerry_set_vm_exec_stop_callback (jerry_vm_exec_stop_callback_t stop_cb,
**Example**
[doctest]: # (test="link")
```c
#include <string.h>
#include "jerryscript.h"
static int countdown = 10;
static jerry_value_t
vm_exec_stop_callback (void *user_p)
{
static int countdown = 10;
while (countdown > 0)
{
countdown--;
@ -4119,6 +4293,8 @@ vm_exec_stop_callback (void *user_p)
return jerry_create_string ((const jerry_char_t *) "Abort script");
}
int
main (void)
{
jerry_init (JERRY_INIT_EMPTY);

View File

@ -14,14 +14,16 @@ This guide is intended to introduce you to JerryScript embedding API through cre
## Step 1. Execute JavaScript from your application
[doctest]: # ()
```c
#include <string.h>
#include "jerryscript.h"
int
main (int argc, char *argv[])
main (void)
{
const jerry_char_t script[] = "print ('Hello, World!');";
const jerry_char_t script[] = "var str = 'Hello, World!';";
size_t script_size = strlen ((const char *) script);
bool ret_value = jerry_run_simple (script, script_size, JERRY_INIT_EMPTY);
@ -30,11 +32,7 @@ main (int argc, char *argv[])
}
```
The application will generate the following output:
```bash
Hello, World!
```
The application will return with zero exit code.
## Step 2. Split engine initialization and script execution
@ -46,12 +44,15 @@ Here we perform the same actions, as `jerry_run_simple`, while splitting into se
- engine cleanup
[doctest]: # ()
```c
#include <string.h>
#include "jerryscript.h"
#include "jerryscript-ext/handler.h"
int
main (int argc, char *argv[])
main (void)
{
const jerry_char_t script[] = "print ('Hello, World!');";
size_t script_size = strlen ((const char *) script);
@ -59,6 +60,10 @@ main (int argc, char *argv[])
/* Initialize engine */
jerry_init (JERRY_INIT_EMPTY);
/* Register 'print' function from the extensions */
jerryx_handler_register_global ((const jerry_char_t *) "print",
jerryx_handler_print);
/* Setup Global scope code */
jerry_value_t parsed_code = jerry_parse (script, script_size, false);
@ -85,12 +90,15 @@ Our code is more complex now, but it introduces possibilities to interact with J
## Step 3. Execution in 'eval'-mode
[doctest]: # ()
```c
#include <string.h>
#include "jerryscript.h"
#include "jerryscript-ext/handler.h"
int
main (int argc, char *argv[])
main (void)
{
const jerry_char_t script_1[] = "var s = 'Hello, World!';";
const jerry_char_t script_2[] = "print (s);";
@ -98,6 +106,10 @@ main (int argc, char *argv[])
/* Initialize engine */
jerry_init (JERRY_INIT_EMPTY);
/* Register 'print' function from the extensions */
jerryx_handler_register_global ((const jerry_char_t *) "print",
jerryx_handler_print);
jerry_value_t eval_ret;
/* Evaluate script1 */
@ -127,18 +139,26 @@ This way, we execute two independent script parts in one execution environment.
## Step 4. Interaction with JavaScript environment
[doctest]: # ()
```c
#include <string.h>
#include "jerryscript.h"
#include "jerryscript-ext/handler.h"
int
main (int argc, char *argv[]) {
main (void)
{
const jerry_char_t str[] = "Hello, World!";
const jerry_char_t script[] = "print (s);";
/* Initializing JavaScript environment */
jerry_init (JERRY_INIT_EMPTY);
/* Register 'print' function from the extensions */
jerryx_handler_register_global ((const jerry_char_t *) "print",
jerryx_handler_print);
/* Getting pointer to the Global object */
jerry_value_t global_object = jerry_get_global_object ();
@ -182,11 +202,12 @@ created by API functions has the error flag set.
The following example function will output a JavaScript value:
[doctest]: # (test="compile")
```c
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "jerryscript.h"
static void
@ -221,7 +242,7 @@ print_value (const jerry_value_t value)
{
/* Determining required buffer size */
jerry_size_t req_sz = jerry_get_string_size (value);
jerry_char_t str_buf_p[req_sz];
jerry_char_t str_buf_p[req_sz + 1];
jerry_string_to_char_buffer (value, str_buf_p, req_sz);
str_buf_p[req_sz] = '\0';
@ -252,26 +273,32 @@ Shell operation can be described with the following loop:
- print result of eval;
- loop.
[doctest]: # (test="compile")
```c
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "jerryscript.h"
#include "jerryscript-ext/handler.h"
static void print_value (const jerry_value_t);
void print_value (const jerry_value_t);
int
main (int argc, char *argv[])
main (void)
{
bool is_done = false;
/* Initialize engine */
jerry_init (JERRY_INIT_EMPTY);
/* Register 'print' function from the extensions */
jerryx_handler_register_global ((const jerry_char_t *) "print",
jerryx_handler_print);
while (!is_done)
{
char cmd[256] = {};
char cmd[256];
char *cmd_tail = cmd;
size_t len = 0;
@ -312,7 +339,7 @@ main (int argc, char *argv[])
{
/* Evaluated JS code thrown an exception
* and didn't handle it with try-catch-finally */
printf ("Unhandled JS exception occured: ");
printf ("Unhandled JS exception occurred: ");
}
print_value (ret_val);
@ -332,9 +359,12 @@ The application inputs commands and evaluates them, one after another.
In this example we demonstrate how to use native function and structures in JavaScript.
[doctest]: # ()
```c
#include <string.h>
#include "jerryscript.h"
#include "jerryscript-ext/handler.h"
struct my_struct
{
@ -354,13 +384,17 @@ get_msg_handler (const jerry_value_t func_value, /**< function object */
} /* get_msg_handler */
int
main (int argc, char *argv[])
main (void)
{
/* Initialize engine */
jerry_init (JERRY_INIT_EMPTY);
/* Register 'print' function from the extensions */
jerryx_handler_register_global ((const jerry_char_t *) "print",
jerryx_handler_print);
/* Do something with the native object */
my_struct.msg = "Hello World";
my_struct.msg = "Hello, World!";
/* Create an empty JS object */
jerry_value_t object = jerry_create_object ();
@ -418,9 +452,12 @@ Hello World
Here we create a JS Object with `jerry_eval`, then extend it with a native function. This function shows how to get a property value from the object and how to manipulate it.
[doctest]: # ()
```c
#include <string.h>
#include "jerryscript.h"
#include "jerryscript-ext/handler.h"
/**
* Add param to 'this.x'
@ -456,11 +493,15 @@ add_handler (const jerry_value_t func_value, /**< function object */
} /* add_handler */
int
main (int argc, char *argv[])
main (void)
{
/* Initialize engine */
jerry_init (JERRY_INIT_EMPTY);
/* Register 'print' function from the extensions */
jerryx_handler_register_global ((const jerry_char_t *) "print",
jerryx_handler_print);
/* Create a JS object */
const jerry_char_t my_js_object[] = " \
MyObject = \

View File

@ -104,6 +104,24 @@ bool jerry_port_get_time_zone (jerry_time_zone_t *);
double jerry_port_get_current_time (void);
```
## External instance
Allow user to provide external buffer for jerry instance (which includes an isolated context and heap with other instances), so that user can config the heap size in runtime and run multiple JS apps simultaneously.
```c
/**
* Get the current instance, which contains the current context, heap and other infomation.
* Each port should provide its own implementation of this interface.
*
*Note:
* This port function will be called automatically by jerry-core
* wnen JERRY_ENABLE_EXTERNAL_CONTEXT is defined. If not, this function will never be called.
*
* @return the pointer to the jerry instance.
*/
struct jerry_instance_t *jerry_port_get_current_instance (void);
```
# How to port JerryScript
This section describes a basic port implementation which was created for Unix based systems.
@ -191,3 +209,35 @@ double jerry_port_get_current_time (void)
return ((double) tv.tv_sec) * 1000.0 + ((double) tv.tv_usec) / 1000.0;
} /* jerry_port_get_current_time */
```
## External instance
```c
#include "jerryscript-port.h"
#include "jerryscript-port-default.h"
/**
* Pointer to the current instance.
* Note that it is a global variable, and is not a thread safe implementation.
*/
static jerry_instance_t *current_instance_p = NULL;
/**
* Set the current_instance_p as the passed pointer.
*/
void
jerry_port_default_set_instance (jerry_instance_t *instance_p) /**< points to the created instance */
{
current_instance_p = instance_p;
} /* jerry_port_default_set_instance */
/**
* Get the current instance.
*
* @return the pointer to the current instance
*/
jerry_instance_t *
jerry_port_get_current_instance (void)
{
return current_instance_p;
} /* jerry_port_get_current_instance */
```

View File

@ -41,6 +41,30 @@ typedef struct
- [jerryx_arg_function](#jerryx_arg_function)
- [jerryx_arg_native_pointer](#jerryx_arg_native_pointer)
- [jerryx_arg_ignore](#jerryx_arg_ignore)
- [jerryx_arg_object_properties](#jerryx_arg_object_properties)
## jerryx_arg_object_props_t
**Summary**
The structure is used in `jerryx_arg_object_properties`. It provides the properties' names,
its corresponding JS-to-C mapping and other related information.
**Prototype**
```c
typedef struct
{
const jerry_char_t **name_p; /**< property name list of the JS object */
jerry_length_t name_cnt; /**< count of the name list */
const jerryx_arg_t *c_arg_p; /**< points to the array of transformation steps */
jerry_length_t c_arg_cnt; /**< the count of the `c_arg_p` array */
} jerryx_arg_object_props_t;
```
**See also**
- [jerryx_arg_object_properties](#jerryx_arg_object_properties)
## jerryx_arg_transform_func_t
@ -108,6 +132,42 @@ Enum that indicates whether an argument is optional or required.
- [jerryx_arg_function](#jerryx_arg_function)
- [jerryx_arg_native_pointer](#jerryx_arg_native_pointer)
## jerryx_arg_round_t
Enum that indicates the rounding policy which will be chosen to transform an integer.
- JERRYX_ARG_ROUND - use round() method.
- JERRYX_ARG_FLOOR - use floor() method.
- JERRYX_ARG_CEIL - use ceil() method.
**See also**
- [jerryx_arg_uint8](#jerryx_arg_uint8)
- [jerryx_arg_uint16](#jerryx_arg_uint16)
- [jerryx_arg_uint32](#jerryx_arg_uint32)
- [jerryx_arg_int8](#jerryx_arg_int8)
- [jerryx_arg_int16](#jerryx_arg_int16)
- [jerryx_arg_int32](#jerryx_arg_int32)
## jerryx_arg_clamp_t
Indicates the clamping policy which will be chosen to transform an integer.
If the policy is NO_CLAMP, and the number is out of range,
then the transformer will throw a range error.
- JERRYX_ARG_CLAMP - clamp the number when it is out of range
- JERRYX_ARG_NO_CLAMP - throw a range error
**See also**
- [jerryx_arg_uint8](#jerryx_arg_uint8)
- [jerryx_arg_uint16](#jerryx_arg_uint16)
- [jerryx_arg_uint32](#jerryx_arg_uint32)
- [jerryx_arg_int8](#jerryx_arg_int8)
- [jerryx_arg_int16](#jerryx_arg_int16)
- [jerryx_arg_int32](#jerryx_arg_int32)
# Main functions
## jerryx_arg_transform_this_and_args
@ -137,44 +197,53 @@ jerryx_arg_transform_this_and_args (const jerry_value_t this_val,
**Example**
[doctest]: # (test="compile")
```c
// JS signature: function (requiredBool, requiredString, optionalNumber)
static jerry_value_t my_external_handler (const jerry_value_t function_obj,
const jerry_value_t this_val,
const jerry_value_t args_p[],
const jerry_length_t args_count)
#include "jerryscript.h"
#include "jerryscript-ext/arg.h"
/* JS signature: function (requiredBool, requiredString, optionalNumber) */
static jerry_value_t
my_external_handler (const jerry_value_t function_obj,
const jerry_value_t this_val,
const jerry_value_t args_p[],
const jerry_length_t args_count)
{
bool required_bool;
char required_str[16];
double optional_num = 1234.567; // default value
// "mapping" defines the steps to transform input arguments to C variables:
/* "mapping" defines the steps to transform input arguments to C variables. */
const jerryx_arg_t mapping[] =
{
// `this` is the first value. No checking needed on `this` for this function.
/* `this` is the first value. No checking needed on `this` for this function. */
jerryx_arg_ignore (),
jerryx_arg_boolean (&required_bool, JERRYX_ARG_NO_COERCE, JERRYX_ARG_REQUIRED),
jerryx_arg_string (&required_str, sizeof (required_str), JERRYX_ARG_NO_COERCE, JERRYX_ARG_REQUIRED),
jerryx_arg_string (required_str, sizeof (required_str), JERRYX_ARG_NO_COERCE, JERRYX_ARG_REQUIRED),
jerryx_arg_number (&optional_num, JERRYX_ARG_NO_COERCE, JERRYX_ARG_OPTIONAL),
};
// Validate and transform:
/* Validate and transform. */
const jerry_value_t rv = jerryx_arg_transform_this_and_args (this_val,
args_p,
args_count,
mapping,
ARRAY_LENGTH (mapping));
4);
if (jerry_value_has_error_flag (rv))
{
// Handle error
/* Handle error. */
return rv;
}
// Validated and tranformed successfully!
// required_bool, required_str and optional_num can now be used.
// ...
/*
* Validated and transformed successfully!
* required_bool, required_str and optional_num can now be used.
*/
return jerry_create_undefined (); /* Or return something more meaningful. */
}
```
@ -187,6 +256,7 @@ static jerry_value_t my_external_handler (const jerry_value_t function_obj,
- [jerryx_arg_function](#jerryx_arg_function)
- [jerryx_arg_native_pointer](#jerryx_arg_native_pointer)
- [jerryx_arg_custom](#jerryx_arg_custom)
- [jerryx_arg_object_properties](#jerryx_arg_object_properties)
## jerryx_arg_transform_args
@ -216,8 +286,86 @@ jerryx_arg_transform_args (const jerry_value_t *js_arg_p,
- [jerryx_arg_transform_this_and_args](#jerryx_arg_transform_this_and_args)
## jerryx_arg_transform_object_properties
**Summary**
Validate the properties of a JS object and assign them to the native arguments.
*Note*: This function transforms properties of a single JS object into native C values.
To transform multiple objects in one pass (for example when converting multiple arguments
to an external handler), please use `jerryx_arg_object_properties` together with
`jerryx_arg_transform_this_and_args` or `jerryx_arg_transform_args`.
**Prototype**
```c
jerry_value_t
jerryx_arg_transform_object_properties (const jerry_value_t obj_val,
const jerry_char_t **name_p,
const jerry_length_t name_cnt,
const jerryx_arg_t *c_arg_p,
jerry_length_t c_arg_cnt);
```
- `obj_val` - the JS object.
- `name_p` - points to the array of property names.
- `name_cnt` - the count of the `name_p` array.
- `c_arg_p` - points to the array of validation/transformation steps
- `c_arg_cnt` - the count of the `c_arg_p` array.
- return value - a `jerry_value_t` representing `undefined` if all validators passed or an `Error` if a validator failed.
**See also**
- [jerryx_arg_object_properties](#jerryx_arg_object_properties)
# Helpers for commonly used validations
## jerryx_arg_uint8
## jerryx_arg_uint16
## jerryx_arg_uint32
## jerryx_arg_int8
## jerryx_arg_int16
## jerryx_arg_int32
**Summary**
All above jerryx_arg_[u]intX functions are used to create a validation/transformation step
(`jerryx_arg_t`) that expects to consume one `number` JS argument
and stores it into a C integer (uint8, int8, uint16, ...)
**Prototype**
Take jerryx_arg_int32 as an example
```c
static inline jerryx_arg_t
jerryx_arg_int32 (int32_t *dest,
jerryx_arg_round_t round_flag,
jerryx_arg_clamp_t clamp_flag,
jerryx_arg_coerce_t coerce_flag,
jerryx_arg_optional_t opt_flag);
```
- return value - the created `jerryx_arg_t` instance.
- `dest` - pointer to the `int32_t` where the result should be stored.
- `round_flag` - the rounding policy.
- `clamp_flag` - the clamping policy.
- `coerce_flag` - whether type coercion is allowed.
- `opt_flag` - whether the argument is optional.
**See also**
- [jerryx_arg_transform_this_and_args](#jerryx_arg_transform_this_and_args)
## jerryx_arg_number
**Summary**
@ -324,7 +472,7 @@ jerryx_arg_function (jerry_value_t *dest,
**Summary**
Create a validation/transformation step (`jerryx_arg_t`) that expects to
consume one `Object` JS argument that is 'backed' with a native pointer with
consume one `object` JS argument that is 'backed' with a native pointer with
a given type info. In case the native pointer info matches, the transform
will succeed and the object's native pointer will be assigned to `*dest`.
@ -345,6 +493,102 @@ jerryx_arg_native_pointer (void **dest,
- [jerryx_arg_transform_this_and_args](#jerryx_arg_transform_this_and_args)
## jerryx_arg_object_properties
**Summary**
Create a validation/transformation step (`jerryx_arg_t`) that expects to
consume one `object` JS argument and call `jerryx_arg_transform_object_properties` inside
to transform its properties to native arguments.
User should prepare the `jerryx_arg_object_props_t` instance, and pass it to this function.
**Prototype**
```c
static inline jerryx_arg_t
jerryx_arg_object_properties (const jerryx_arg_object_props_t *object_props_p,
jerryx_arg_optional_t opt_flag);
```
- return value - the created `jerryx_arg_t` instance.
- `object_props_p` - provides information for properties transform.
- `opt_flag` - whether the argument is optional.
**Example**
[doctest]: # (test="compile")
```c
#include "jerryscript.h"
#include "jerryscript-ext/arg.h"
/**
* The binding function expects args_p[0] is an object, which has 3 properties:
* "enable": boolean
* "data": number
* "extra_data": number, optional
*/
static jerry_value_t
my_external_handler (const jerry_value_t function_obj,
const jerry_value_t this_val,
const jerry_value_t args_p[],
const jerry_length_t args_count)
{
bool required_bool;
double required_num;
double optional_num = 1234.567; // default value
/* "prop_name_p" defines the name list of the expected properties' names. */
const char *prop_name_p[] = { "enable", "data", "extra_data" };
/* "prop_mapping" defines the steps to transform properties to C variables. */
const jerryx_arg_t prop_mapping[] =
{
jerryx_arg_boolean (&required_bool, JERRYX_ARG_COERCE, JERRYX_ARG_REQUIRED),
jerryx_arg_number (&required_num, JERRYX_ARG_COERCE, JERRYX_ARG_REQUIRED),
jerryx_arg_number (&optional_num, JERRYX_ARG_COERCE, JERRYX_ARG_OPTIONAL)
};
/* Prepare the jerryx_arg_object_props_t instance. */
const jerryx_arg_object_props_t prop_info =
{
.name_p = (const jerry_char_t **) prop_name_p,
.name_cnt = 3,
.c_arg_p = prop_mapping,
.c_arg_cnt = 3
};
/* It is the mapping used in the jerryx_arg_transform_args. */
const jerryx_arg_t mapping[] =
{
jerryx_arg_object_properties (&prop_info, JERRYX_ARG_REQUIRED)
};
/* Validate and transform. */
const jerry_value_t rv = jerryx_arg_transform_args (args_p,
args_count,
mapping,
1);
if (jerry_value_has_error_flag (rv))
{
/* Handle error. */
return rv;
}
/*
* Validated and transformed successfully!
* required_bool, required_num and optional_num can now be used.
*/
return jerry_create_undefined (); /* Or return something more meaningful. */
}
```
**See also**
- [jerryx_arg_transform_this_and_args](#jerryx_arg_transform_this_and_args)
- [jerryx_arg_transform_object_properties](#jerryx_arg_transform_object_properties)
# Functions to create custom validations

View File

@ -124,6 +124,8 @@ jerryx_handler_register_global (const jerry_char_t *name_p,
**Example**
[doctest]: # (test="compile")
```c
#include "jerryscript.h"
#include "jerryscript-ext/handler.h"
@ -139,7 +141,8 @@ static const struct {
{ NULL, NULL }
};
static void register_common_functions ()
static void
register_common_functions (void)
{
jerry_value_t ret = jerry_create_undefined ();
@ -149,7 +152,7 @@ static void register_common_functions ()
common_functions[i].handler_p);
}
return ret;
jerry_release_value (ret);
}
```

View File

@ -0,0 +1,60 @@
---
layout: page
title: 'Extension API: Autorelease Values'
category: documents
permalink: /ext-reference-autorelease/
---
* toc
{:toc}
# Autorelease values
## JERRYX_AR_VALUE_T
**Summary**
Macro for `const jerry_value_t` for which jerry_release_value() is
automatically called when the variable goes out of scope.
*Note*: The macro depends on compiler support. For GCC and LLVM/clang, the macro is implemented
using the `__cleanup__` variable attribute. For other compilers, no support has been added yet.
**Example**
[doctest]: # (test="compile")
```c
#include "jerryscript.h"
#include "jerryscript-ext/autorelease.h"
static void
foo (bool enable)
{
JERRYX_AR_VALUE_T bar = jerry_create_string ((const jerry_char_t *) "...");
if (enable)
{
JERRYX_AR_VALUE_T baz = jerry_get_global_object ();
/* bar and baz can now be used. */
/*
* jerry_release_value (baz) and jerry_release_value (bar) is called automatically before
* returning, because `baz` and `bar` go out of scope.
*/
return;
}
/*
* jerry_release_value (bar) is called automatically when the function returns,
* because `bar` goes out of scope.
*/
}
```
**See also**
- [jerry_value_t](../api-reference#jerry_value_t)
- [jerry_acquire_value](../api-reference#jerry_acquire_value)
- [jerry_release_value](../api-reference#jerry_release_value)

196
12.EXT-REFERENCE-MODULE.md Normal file
View File

@ -0,0 +1,196 @@
---
layout: page
title: 'Extension API: Module Support'
category: documents
permalink: /ext-reference-module/
---
* toc
{:toc}
# Module API
This is a JerryScript extension that provides a means of loading modules. Fundamentally, a module is a name (stored as
a string) that resolves to a `jerry_value_t`. This extension provides the function `jerryx_module_resolve()` which
accepts the name of the module being requested as well as an array of so-called "resolvers" - functions which satisfy
the signature `jerryx_module_resolver_t`. The resolvers in the list are called in sequence until one of them returns
`true` and a `jerry_value_t` in its out parameter. The value is cached if it is not an error, so subsequent requests
for the same name will not result in additional calls to the resolvers.
The purpose of having resolvers is to be able to account for the fact that different types of modules may be structured
differently and thus, for each type of module a module resolver must be supplied at the point where an instance of that
type of module is requested.
Additionally, this extension provides a means of easily defining so-called "native" JerryScript modules which can be
resolved using the JerryScript native module resolver `jerryx_module_native_resolver()`, which can be passed to
`jerryx_module_resolve()`. Note, however, that native JerryScript modules are only supported and
`jerryx_module_native_resolver()` is only compiled in if compiler support for `__attribute__` extensions is present. In
effect this means that native JerryScript modules are available only when this extension is built with GCC or
LLVM/clang. In the absence of such support, you may construct alternative module systems and provide your own resolver
to `jerryx_module_resolve()`.
`jerryscript-ext/module.h` defines the preprocessor directive `JERRYX_NATIVE_MODULES_SUPPORTED` only if support for
native JerryScript modules is available.
## jerryx_module_resolve
**Summary**
Load a copy of a module into the current context or return one that was already loaded if it is found.
Each function in `resolvers_p` will be called in sequence until one returns `true` and fills out its out-parameter with
the `jerry_value_t` representing the requested module. If the `jerry_value_t` does not have the error flag set it will
be cached. Thus, on subsequent calls with the same value for `name`, none of the functions in `resolvers_p` will be
called.
**Prototype**
```c
jerry_value_t
jerryx_module_resolve (const jerry_char_t *name,
const jerryx_module_resolver_t *resolvers_p,
size_t resolver_count);
```
- `name` - the name of the module to load
- `resolvers_p` - the list of resolvers to call in sequence
- `resolver_count` - the number of resolvers in `resolvers_p`
- return value - `jerry_value_t` representing the module that was loaded, or the error that occurred in the process.
## jerryx_module_native_resolver
**Summary**
The resolver for JerryScript modules. A pointer to this function can be passed in the second parameter to
`jerryx_module_resolve` to search for the module among the JerryScript modules built into the binary. This function is
available only if the preprocessor directive `JERRYX_NATIVE_MODULES_SUPPORTED` is defined.
**Prototype**
```c
bool
jerryx_module_native_resolver (const jerry_char_t *name,
jerry_value_t *result)
```
- `name` - the name of the module to find
- `result` - out - place where to store the resulting module instance
- return value - `true` if the module was found and stored in `result`, and `false` otherwise
# Module data types
## jerryx_native_module_on_resolve_t
**Summary**
Function pointer type for a function that will create an instance of a native module. This type is only defined if the
preprocessor directive `JERRYX_NATIVE_MODULES_SUPPORTED` is defined.
**Prototype**
```c
typedef jerry_value_t (*jerryx_native_module_on_resolve_t) (void);
```
## jerryx_module_resolver_t
**Summary**
Function pointer type for a module resolver
**Prototype**
```c
typedef bool (*jerryx_module_resolver_t) (const jerry_char_t *name, jerry_value_t *result);
```
**Example**
```c
bool
load_and_evaluate_js_file (const jerry_char_t *name, jerry_value_t *result)
{
bool return_value = false;
char *js_file_contents = NULL;
int file_size = 0;
FILE *js_file = fopen (name, "r");
if (js_file)
{
/* We have successfully opened the file. Now, we establish its size. */
file_size = fseek (js_file, 0, SEEK_END);
fseek (js_file, 0, SEEK_SET);
/* We allocate enough memory to store the contents of the file. */
js_file_contents = malloc (file_size);
if (js_file_contents)
{
/* We read the file into memory and call jerry_eval (), assigning the result to the out-parameter. */
fread (js_file_contents, file_size, 1, js_file);
(*result) = jerry_eval (js_file_contents, file_size, false);
/* We release the memory holding the contents of the file. */
free (js_file_contents);
return_value = true;
}
/* We close the file. */
fclose (js_file);
}
return return_value;
}
```
We can now load JavaScript files:
```c
static const jerryx_module_resolver_t resolvers[] =
{
/* Consult the JerryScript module resolver first, in case the requested module is a compiled-in JerryScript module. */
jerryx_module_native_resolver,
/*
* If the requested module is not a JerryScript module, assume it is a JavaScript file on disk and use the above-
* defined JavaScript file loader to load it.
*/
load_and_evaluate_js_file
};
jerry_value_t js_module = jerryx_module_resolve (requested_module, resolvers, 2);
```
# Module helper macros
## JERRYX_NATIVE_MODULE
**Summary**
Helper macro to define a JerryScript module. Currently stores the name of the module and its initializer in an
executable linker section. This macro is available only if the preprocessor directive `JERRYX_NATIVE_MODULES_SUPPORTED`
is defined.
**Note**: The helper macro must appear at the bottom of a source file, and no semicolon must follow it.
**Prototype**
```c
#define JERRYX_NATIVE_MODULE(module_name, on_resolve_cb)
```
- `module_name` - the name of the module without quotes
- `on_resolve_cb` - the function of type `jerryx_native_module_on_resolve_t` that will be called when the module needs to be
loaded.
**Example**
```c
#include "jerryscript.h"
#include "jerryscript-ext/module.h"
static jerry_value_t
my_module_on_resolve (void)
{
return jerry_create_external_function (very_useful_function);
} /* my_module_on_resolve */
/* Note that there is no semicolon at the end of the next line. This is how it must be. */
JERRYX_NATIVE_MODULE (my_module, my_module_on_resolve)
```