Update the webpage (#2037)
JerryScript-DCO-1.0-Signed-off-by: Zsolt Borbély zsborbely.u-szeged@partner.samsung.com
This commit is contained in:
+48
-11
@@ -677,7 +677,7 @@ jerry_parse (const jerry_char_t *source_p,
|
||||
bool is_strict);
|
||||
```
|
||||
|
||||
- `source_p` - string, containing source code to parse. It must be a valid utf8 string.
|
||||
- `source_p` - string, containing source code to parse (must be a valid UTF8 string).
|
||||
- `source_size` - size of the string, in bytes.
|
||||
- `is_strict` - defines strict mode.
|
||||
- return value
|
||||
@@ -716,8 +716,8 @@ main (void)
|
||||
**Summary**
|
||||
|
||||
Parse script and construct an ECMAScript function. The lexical
|
||||
environment is set to the global lexical environment. The name
|
||||
(usually a file name) is also passed to this function which is
|
||||
environment is set to the global lexical environment. The resource
|
||||
name (usually a file name) is also passed to this function which is
|
||||
used by the debugger to find the source code.
|
||||
|
||||
*Note*: The returned value must be freed with [jerry_release_value](#jerry_release_value) when it
|
||||
@@ -727,25 +727,62 @@ is no longer needed.
|
||||
|
||||
```c
|
||||
jerry_value_t
|
||||
jerry_parse_named_resource (const jerry_char_t *name_p, /**< name (usually a file name) */
|
||||
size_t name_length, /**< length of name */
|
||||
jerry_parse_named_resource (const jerry_char_t *resource_name_p, /**< resource name (usually a file name) */
|
||||
size_t resource_name_length, /**< length of resource name */
|
||||
const jerry_char_t *source_p, /**< script source */
|
||||
size_t source_size, /**< script source size */
|
||||
bool is_strict) /**< strict mode */
|
||||
{
|
||||
```
|
||||
|
||||
- `name_p` - name, usually a file name
|
||||
- `name_length` - size of the file name, in bytes
|
||||
- `source_p` - string, containing source code to parse. It must be a valid UTF8 string
|
||||
- `source_size` - size of the string, in bytes
|
||||
- `is_strict` - defines strict mode
|
||||
- `resource_name_p` - resource name, usually a file name (must be a valid UTF8 string).
|
||||
- `resource_name_length` - size of the resource name, in bytes.
|
||||
- `source_p` - string, containing source code to parse (must be a valid UTF8 string).
|
||||
- `source_size` - size of the string, in bytes.
|
||||
- `is_strict` - defines strict mode.
|
||||
- return value
|
||||
- function object value, if script was parsed successfully,
|
||||
- thrown error, otherwise
|
||||
|
||||
This function is identical to [jerry_parse](#jerry_parse), except that an additional filename parameter has been added.
|
||||
|
||||
## jerry_parse_function
|
||||
|
||||
**Summary**
|
||||
|
||||
Parse function source code and construct an ECMAScript
|
||||
function. The function arguments and function body are
|
||||
passed as separated arguments. The lexical environment
|
||||
is set to the global lexical environment. The resource
|
||||
name (usually a file name) is also passed to this function
|
||||
which is used by the debugger to find the source code.
|
||||
|
||||
*Note*: The returned value must be freed with [jerry_release_value](#jerry_release_value) when it
|
||||
is no longer needed.
|
||||
|
||||
**Prototype**
|
||||
|
||||
```c
|
||||
jerry_value_t
|
||||
jerry_parse_function (const jerry_char_t *resource_name_p, /**< resource name (usually a file name) */
|
||||
size_t resource_name_length, /**< length of resource name */
|
||||
const jerry_char_t *arg_list_p, /**< script source */
|
||||
size_t arg_list_size, /**< script source size */
|
||||
const jerry_char_t *source_p, /**< script source */
|
||||
size_t source_size, /**< script source size */
|
||||
bool is_strict) /**< strict mode */
|
||||
```
|
||||
|
||||
- `resource_name_p` - resource name, usually a file name (must be a valid UTF8 string).
|
||||
- `resource_name_length` - size of the resource name, in bytes.
|
||||
- `arg_list_p` - argument list of the function (must be a valid UTF8 string).
|
||||
- `arg_list_size` - size of the argument list, in bytes.
|
||||
- `source_p` - string, containing source code to parse (must be a valid UTF8 string).
|
||||
- `source_size` - size of the string, in bytes.
|
||||
- `is_strict` - defines strict mode.
|
||||
- return value
|
||||
- function object value, if script was parsed successfully,
|
||||
- thrown error, otherwise
|
||||
|
||||
## jerry_run
|
||||
|
||||
**Summary**
|
||||
|
||||
+85
-16
@@ -93,6 +93,35 @@ debugger is disabled.
|
||||
The following section describes the debugger functions
|
||||
available for the host application.
|
||||
|
||||
## JerryScript debugger types
|
||||
|
||||
## jerry_debugger_wait_for_source_callback_t
|
||||
|
||||
**Summary**
|
||||
|
||||
This callback function is called by
|
||||
[jerry_debugger_wait_for_client_source](#jerry_debugger_wait_for_client_source)
|
||||
when a source code is received successfully.
|
||||
|
||||
**Prototype**
|
||||
|
||||
```c
|
||||
typedef jerry_value_t
|
||||
(*jerry_debugger_wait_for_source_callback_t) (const jerry_char_t *resource_name_p,
|
||||
size_t resource_name_size,
|
||||
const jerry_char_t *source_p,
|
||||
size_t source_size, void *user_p);
|
||||
```
|
||||
|
||||
- `resource_name_p` - resource (usually a file) name of the source code
|
||||
- `resource_name_size` - size of resource name
|
||||
- `source_p` - source code character data
|
||||
- `source_size` - size of source code
|
||||
- `user_p` - custom pointer passed to [jerry_debugger_wait_for_client_source](#jerry_debugger_wait_for_client_source)
|
||||
|
||||
|
||||
## JerryScript debugger functions
|
||||
|
||||
### jerry_debugger_init
|
||||
|
||||
**Summary**
|
||||
@@ -254,46 +283,86 @@ jerry_debugger_stop_at_breakpoint (bool enable_stop_at_breakpoint)
|
||||
}
|
||||
```
|
||||
|
||||
### jerry_debugger_wait_and_run_client_source
|
||||
### jerry_debugger_wait_for_client_source
|
||||
|
||||
**Summary**
|
||||
|
||||
Stops the engine and puts it into a waiting loop. If the client sends
|
||||
a source code and JerryScript receives that, then the function will
|
||||
run the source with the initialized options, after that the engine will
|
||||
wait for a new source until the client send a close signal.
|
||||
Asks the client to provide the next source code. The function
|
||||
waits until the whole source code is received. As a reply the
|
||||
the client may request a context reset or notify that no more
|
||||
source is available. These notifications are passed back as the
|
||||
return value of the function.
|
||||
|
||||
**Prototype**
|
||||
|
||||
```c
|
||||
jerry_debugger_wait_and_run_type_t
|
||||
jerry_debugger_wait_and_run_client_source (jerry_value_t *return_value)
|
||||
jerry_debugger_wait_for_source_status_t
|
||||
jerry_debugger_wait_for_client_source (jerry_debugger_wait_for_source_callback_t callback_p,
|
||||
void *user_p, jerry_value_t *return_value)
|
||||
```
|
||||
|
||||
**Example**
|
||||
|
||||
```c
|
||||
/**
|
||||
* Runs the source code received by jerry_debugger_wait_for_client_source.
|
||||
*/
|
||||
static jerry_value_t
|
||||
wait_for_source_callback (const jerry_char_t *resource_name_p, /**< resource name */
|
||||
size_t resource_name_size, /**< size of resource name */
|
||||
const jerry_char_t *source_p, /**< source code */
|
||||
size_t source_size, /**< source code size */
|
||||
void *user_p __attribute__((unused))) /**< user pointer */
|
||||
{
|
||||
jerry_value_t ret_val = jerry_parse_named_resource (resource_name_p,
|
||||
resource_name_size,
|
||||
source_p,
|
||||
source_size,
|
||||
false);
|
||||
|
||||
if (!jerry_value_has_error_flag (ret_val))
|
||||
{
|
||||
jerry_value_t func_val = ret_val;
|
||||
ret_val = jerry_run (func_val);
|
||||
jerry_release_value (func_val);
|
||||
}
|
||||
|
||||
return ret_val;
|
||||
} /* wait_for_source_callback */
|
||||
|
||||
int main ()
|
||||
{
|
||||
do
|
||||
{
|
||||
/* Create a new JerryScript instance when a context reset is
|
||||
* received. Applications usually registers their core bindings
|
||||
* here as well (e.g. print, setTimeout). */
|
||||
jerry_init (JERRY_INIT_EMPTY);
|
||||
jerry_debugger_init (5001);
|
||||
|
||||
jerry_value_t run_result;
|
||||
jerry_debugger_wait_and_run_type_t receive_status;
|
||||
|
||||
do
|
||||
{
|
||||
receive_status = jerry_debugger_wait_and_run_client_source (&run_result);
|
||||
jerry_value_t run_result;
|
||||
jerry_debugger_wait_for_source_status_t receive_status;
|
||||
|
||||
if (receive_status == JERRY_DEBUGGER_SOURCE_RECEIVE_FAILED)
|
||||
{
|
||||
// Handle the failure (e.g. create an error).
|
||||
}
|
||||
}
|
||||
receive_status = jerry_debugger_wait_for_client_source (wait_for_source_callback,
|
||||
NULL,
|
||||
&run_result);
|
||||
|
||||
jerry_release_value (run_result);
|
||||
}
|
||||
while (receive_status == JERRY_DEBUGGER_SOURCE_RECEIVED);
|
||||
|
||||
jerry_cleanup ();
|
||||
}
|
||||
while (receive_status == JERRY_DEBUGGER_CONTEXT_RESET_RECEIVED);
|
||||
|
||||
if (receive_status == JERRY_DEBUGGER_SOURCE_RECEIVE_FAILED)
|
||||
{
|
||||
// Handle the failure (e.g. display an error).
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
```
|
||||
|
||||
### jerry_debugger_send_output
|
||||
|
||||
+148
-46
@@ -12,25 +12,37 @@ permalink: /ext-reference-module/
|
||||
|
||||
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.
|
||||
accepts the name of the module being requested as well as an array of so-called "resolvers" - structures containing two
|
||||
function pointers: one for a function which computes a canonical name for the requested module or returns a reference
|
||||
to the requested name, and one that converts a canonical name to a `jerry_value_t`, thus "resolving" or "loading" the
|
||||
requested module.
|
||||
|
||||
The resolvers are first called in sequence to each compute the canonical name of the requested module. This is
|
||||
accomplished by calling the `get_canonical_name` function pointer they provide. If the function pointer is `NULL`, the
|
||||
requested module name is assumed to be what the resolver considers to be its canonical name. `jerryx_module_resolve`
|
||||
searches its cache of loaded modules for each canonical name as returned by a `get_canonical_name` function pointer. If
|
||||
one of the loaded modules in the cache corresponds to a canonical name, it is returned.
|
||||
|
||||
If no cached module is found, `jerryx_module_resolve` calls each resolver's `resolve` function pointer, passing it its
|
||||
previously computed interpretation of the requested module's canonical name. If the resolver successfully creates the
|
||||
`jerry_value_t` that represents the loaded module, it returns `true` and the `jerry_value_t` in its out parameter.
|
||||
|
||||
When `jerryx_module_resolve` receives a value of `true` from a resolver, it stops iterating over the remaining
|
||||
resolvers in the sequence and, if the `jerry_value_t` returned from the resolver's `resolve` does not have the error
|
||||
flag set, it will add the `jerry_value_t` to its cache under the module's canonical name and return it. Thus, on
|
||||
subsequent calls to `jerryx_module_resolve` with a module name whose canonical name is associated with the
|
||||
`jerry_value_t`, no `resolve` callback need be called again.
|
||||
|
||||
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.
|
||||
resolved using the native JerryScript module resolver `jerryx_module_native_resolver`, which can be passed to
|
||||
`jerryx_module_resolve()`. Native modules are registered during application startup and by calling `dlopen()` by means
|
||||
of library constructors, support for which can be turned on using the `FEATURE_INIT_FINI` build flag. In the absence of
|
||||
such a flag, the module registration and unregistration functions are exposed as global symbols which can be called
|
||||
explicitly.
|
||||
|
||||
## jerryx_module_resolve
|
||||
|
||||
@@ -38,10 +50,17 @@ native JerryScript modules is available.
|
||||
|
||||
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.
|
||||
For each resolver passed in via `resolvers_p`, its `get_canonical_name` function pointer gets called in order to
|
||||
establish the resolver's interpretation of what the canonical name for the module should be. If `get_canonical_name` is
|
||||
`NULL`, it is assumed that the requested module's name as passed in is its canonical name.
|
||||
|
||||
Then, for each resolver passed in via `resolvers_p`, its `resolve` function pointer gets called with its interpretation
|
||||
of what the module's canonical name should be, as computed in the previous step.
|
||||
|
||||
If the resolver's `resolve` function pointer returns `true`, the `jerry_value_t` returned in its out-parameter will be
|
||||
returned by `jerryx_module_resolve` as the result of the request. If no error flag is set on the `jerry_value_t` it
|
||||
will be cached under its canonical name so as to avoid loading the same module twice in the event of a subsequent call
|
||||
to `jerryx_module_resolve` with a module name whose canonical name matches an already loaded module.
|
||||
|
||||
**Prototype**
|
||||
|
||||
@@ -62,58 +81,79 @@ jerryx_module_resolve (const jerry_char_t *name,
|
||||
|
||||
**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.
|
||||
The resolver for native JerryScript modules. A pointer to this structure can be passed in the second parameter to
|
||||
`jerryx_module_resolve` to search for the module among the native 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)
|
||||
extern jerry_module_resolver_t jerryx_native_module_resolver;
|
||||
```
|
||||
- `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
|
||||
## jerryx_module_get_canonical_name_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.
|
||||
The function pointer type for converting a module's requested name to its canonical name.
|
||||
|
||||
**Prototype**
|
||||
|
||||
```c
|
||||
typedef jerry_value_t (*jerryx_native_module_on_resolve_t) (void);
|
||||
typedef jerry_value_t (*jerryx_module_get_canonical_name_t) (const jerry_value_t name);
|
||||
```
|
||||
|
||||
## jerryx_module_resolve_t
|
||||
|
||||
**Summary**
|
||||
|
||||
Function pointer type for module resolution.
|
||||
|
||||
**Prototype**
|
||||
|
||||
```c
|
||||
typedef bool (*jerryx_module_resolve_t) (const jerry_value_t canonical_name,
|
||||
jerry_value_t *result);
|
||||
```
|
||||
|
||||
## jerryx_module_resolver_t
|
||||
|
||||
**Summary**
|
||||
|
||||
Function pointer type for a module resolver
|
||||
Structure defining a module resolver.
|
||||
|
||||
**Prototype**
|
||||
|
||||
```c
|
||||
typedef bool (*jerryx_module_resolver_t) (const jerry_char_t *name, jerry_value_t *result);
|
||||
typedef struct
|
||||
{
|
||||
jerryx_module_get_canonical_name_t get_canonical_name_p;
|
||||
jerryx_module_resolve_t resolve_p;
|
||||
} jerryx_module_resolver_t;
|
||||
```
|
||||
|
||||
- `get_canonical_name_p` - function pointer to be called when the canonical name corresponding to the requested name
|
||||
of a module must be established.
|
||||
- `resolve_p` - function pointer to be called when a module with the given canonical name needs to be converted to the
|
||||
`jerry_value_t` that will become the loaded module.
|
||||
|
||||
**Example**
|
||||
```c
|
||||
bool
|
||||
load_and_evaluate_js_file (const jerry_char_t *name, jerry_value_t *result)
|
||||
static bool
|
||||
load_and_evaluate_js_file (const jerry_value_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");
|
||||
|
||||
jerry_size_t name_size = jerry_get_utf8_string_size (name);
|
||||
jerry_char_t name_string[name_size + 1];
|
||||
jerry_string_to_utf8_char_buffer (name, name_string, name_size);
|
||||
name_string[name_size] = 0;
|
||||
|
||||
FILE *js_file = fopen (name_string, "r");
|
||||
|
||||
if (js_file)
|
||||
{
|
||||
@@ -140,20 +180,44 @@ load_and_evaluate_js_file (const jerry_char_t *name, jerry_value_t *result)
|
||||
|
||||
return return_value;
|
||||
}
|
||||
|
||||
static jerry_value_t
|
||||
canonicalize_file_path (const jerry_value_t name)
|
||||
{
|
||||
jerry_value_t absolute_path;
|
||||
|
||||
/**
|
||||
* Since a file on the file system can be referred to by multiple relative paths, but only by one absolute path, the
|
||||
* absolute path becomes the canonical name for the module. Thus, to establish this canonical name, we must search
|
||||
* name for "./" and "../", follow symlinks, etc., then create absolute_path via jerry_create_string () and return
|
||||
* it, because it is the canonical name for this module. Thus, we avoid loading the same JavaScript file twice.
|
||||
*/
|
||||
|
||||
return absolute_path;
|
||||
}
|
||||
|
||||
static jerryx_module_resolver_t js_file_loader
|
||||
{
|
||||
canonicalize_file_path,
|
||||
load_and_evaluate_js_file
|
||||
};
|
||||
```
|
||||
|
||||
We can now load JavaScript files:
|
||||
```c
|
||||
static const jerryx_module_resolver_t resolvers[] =
|
||||
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,
|
||||
/*
|
||||
* Consult the resolver for native JerryScript modules first, in case the requested module is a native 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.
|
||||
* If the requested module is not a native 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
|
||||
&js_file_loader
|
||||
};
|
||||
jerry_value_t js_module = jerryx_module_resolve (requested_module, resolvers, 2);
|
||||
```
|
||||
@@ -164,9 +228,11 @@ jerry_value_t js_module = jerryx_module_resolve (requested_module, resolvers, 2)
|
||||
|
||||
**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.
|
||||
Helper macro to define a native JerryScript module. Currently declares a global static structure of type
|
||||
`jerryx_native_module_t` and a constructor/destructor pair that calls `jerryx_native_module_register()` resp.
|
||||
`jerryx_native_module_unregister()`. If the extension is built without the FEATURE_INIT_FINI flag, indicating that
|
||||
support for library constructors and destructors is absent, the constructor and destructor are declared as global
|
||||
symbols so that they may be called explicitly from within the application.
|
||||
|
||||
**Note**: The helper macro must appear at the bottom of a source file, and no semicolon must follow it.
|
||||
|
||||
@@ -175,7 +241,8 @@ is defined.
|
||||
#define JERRYX_NATIVE_MODULE(module_name, on_resolve_cb)
|
||||
```
|
||||
|
||||
- `module_name` - the name of the module without quotes
|
||||
- `module_name` - the name of the module without quotes. This value is used as the prefix for the registration and unregistration funtions. For example, when `module_name` is `example_module`, this results in the declaration of two functions `example_module_register()` and `example_module_unregister()`. These functions are declared global if support for library constructors/destructors is absent, allowing you to call them from other parts of the code by
|
||||
first forward-declaring them.
|
||||
- `on_resolve_cb` - the function of type `jerryx_native_module_on_resolve_t` that will be called when the module needs to be
|
||||
loaded.
|
||||
|
||||
@@ -194,3 +261,38 @@ my_module_on_resolve (void)
|
||||
/* 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)
|
||||
```
|
||||
|
||||
**Example Usage When Library Constructors Are Unavailable**
|
||||
|
||||
```c
|
||||
#include "jerryscript.h"
|
||||
#include "jerryscript-ext/module.h"
|
||||
|
||||
/**
|
||||
* Forward-declare the module registration and unregistration function.
|
||||
*/
|
||||
extern void my_module_register (void);
|
||||
extern void my_module_unregister (void);
|
||||
int
|
||||
main (int argc, char **argv)
|
||||
{
|
||||
jerryx_module_resolver_t resolvers[] =
|
||||
{
|
||||
jerryx_native_module_resolver
|
||||
};
|
||||
|
||||
/* This plays the role of the library constructor. */
|
||||
my_module_register ();
|
||||
|
||||
jerry_init (JERRY_INIT_EMPTY);
|
||||
...
|
||||
jerry_value_t my_module = jerryx_module_resolve ("my_module", resolvers, 1);
|
||||
...
|
||||
jerry_cleanup ();
|
||||
|
||||
/* This plays the role of the library destructor */
|
||||
my_module_unregister();
|
||||
|
||||
return 0;
|
||||
}
|
||||
```
|
||||
|
||||
Reference in New Issue
Block a user