add jerryscript source code
@@ -0,0 +1,186 @@
|
||||
## Setting up prerequisites
|
||||
|
||||
Currently, only Ubuntu 18.04+ is officially supported as primary development environment.
|
||||
|
||||
There are several dependencies, that should be installed manually. The following list is the absolute minimum for building:
|
||||
|
||||
- `gcc` or any C99-compliant compiler (native or cross, e.g., arm-none-eabi)
|
||||
- `cmake` >= `2.8.12.2`
|
||||
|
||||
Several scripts and tools help the building and development process, thus it is recommended to have the following installed as well:
|
||||
|
||||
- `bash` >= `4.3.11`
|
||||
- `cppcheck` >= `1.61`
|
||||
- `vera++` >= `1.2.1`
|
||||
- `python` >= `2.7.6`
|
||||
|
||||
```bash
|
||||
sudo apt-get install gcc gcc-arm-none-eabi cmake cppcheck vera++ python
|
||||
```
|
||||
|
||||
To make our scripts run correctly, several shell utilities should be available on the system:
|
||||
|
||||
- `awk`
|
||||
- `bc`
|
||||
- `find`
|
||||
- `sed`
|
||||
|
||||
## Building JerryScript
|
||||
|
||||
**To build debug version for Linux**
|
||||
|
||||
```bash
|
||||
python tools/build.py --debug
|
||||
```
|
||||
|
||||
**To build debug version for Linux without LTO (Link Time Optimization)**
|
||||
|
||||
```bash
|
||||
python tools/build.py --debug --lto=off
|
||||
```
|
||||
|
||||
**To enable more verbose outputs for debugging**
|
||||
|
||||
```bash
|
||||
tools/build.py --debug --logging=on --error-messages=on --line-info=on
|
||||
```
|
||||
|
||||
**Add custom arguments to CMake**
|
||||
|
||||
```bash
|
||||
python tools/build.py --cmake-param=CMAKE_PARAM
|
||||
```
|
||||
|
||||
**Set a profile mode (ES.next, ES5.1, minimal)**
|
||||
|
||||
```bash
|
||||
python tools/build.py --profile=es.next|es5.1|minimal
|
||||
```
|
||||
|
||||
See also the related [README.md](https://github.com/jerryscript-project/jerryscript/blob/master/jerry-core/profiles/README.md).
|
||||
|
||||
**Use (compiler-default, external) libc**
|
||||
|
||||
The default libc is the compiler-default libc but you can use an external libc as well:
|
||||
|
||||
- compiler-default libc:
|
||||
|
||||
```bash
|
||||
python tools/build.py
|
||||
```
|
||||
|
||||
- external libc:
|
||||
|
||||
```bash
|
||||
python tools/build.py --compile-flag="-nostdlib -I/path/to/ext-libc/include" --link-lib="ext-c"
|
||||
```
|
||||
|
||||
**Add toolchain file**
|
||||
|
||||
The ```cmake``` dir already contains some usable toolchain files, which you can use in the following format:
|
||||
|
||||
```bash
|
||||
python tools/build.py --toolchain=TOOLCHAIN
|
||||
```
|
||||
|
||||
For example the cross-compile to RaspberryPi 2 is something like this:
|
||||
|
||||
```bash
|
||||
python tools/build.py --toolchain=cmake/toolchain_linux_armv7l.cmake
|
||||
```
|
||||
|
||||
**Use system memory allocator**
|
||||
|
||||
```bash
|
||||
python tools/build.py --system-allocator=on
|
||||
```
|
||||
|
||||
*Note*: System allocator is only supported on 32 bit systems.
|
||||
|
||||
**Enable 32bit compressed pointers**
|
||||
|
||||
```bash
|
||||
python tools/build.py --cpointer-32bit=on
|
||||
```
|
||||
|
||||
*Note*: There is no compression/decompression on 32 bit systems, if enabled.
|
||||
|
||||
**Change default heap size (512K)**
|
||||
|
||||
```bash
|
||||
python tools/build.py --mem-heap=256
|
||||
```
|
||||
|
||||
If you would like to use more than 512K, then you must enable the 32 bit compressed pointers.
|
||||
|
||||
```bash
|
||||
python tools/build.py --cpointer-32bit=on --mem-heap=1024
|
||||
```
|
||||
|
||||
*Note*: The heap size will be allocated statically at compile time, when JerryScript memory
|
||||
allocator is used.
|
||||
|
||||
**To build with libfuzzer support**
|
||||
|
||||
```bash
|
||||
CC=clang python tools/build.py --libfuzzer=on --compile-flag=-fsanitize=address --lto=off
|
||||
```
|
||||
|
||||
Check the documentation of libfuzzer to get the runtime settings of the created fuzzer
|
||||
binary: https://llvm.org/docs/LibFuzzer.html.
|
||||
|
||||
**To get a list of all the available buildoptions for Linux**
|
||||
|
||||
```bash
|
||||
python tools/build.py --help
|
||||
```
|
||||
|
||||
## Checking patch
|
||||
|
||||
```bash
|
||||
python tools/run-tests.py --precommit
|
||||
```
|
||||
|
||||
### Running only one type of test
|
||||
|
||||
**To run build option tests**
|
||||
|
||||
```bash
|
||||
python tools/run-tests.py --buildoption-test
|
||||
```
|
||||
|
||||
**To run unittests**
|
||||
|
||||
```bash
|
||||
python tools/run-tests.py --unittests
|
||||
```
|
||||
|
||||
**To run jerry-tests**
|
||||
|
||||
```bash
|
||||
python tools/run-tests.py --jerry-tests
|
||||
```
|
||||
|
||||
**To run signed-off check**
|
||||
|
||||
```bash
|
||||
python tools/run-tests.py --check-signed-off
|
||||
```
|
||||
|
||||
**To run cppcheck**
|
||||
|
||||
```bash
|
||||
python tools/run-tests.py --check-cppcheck
|
||||
```
|
||||
|
||||
**To run vera check**
|
||||
|
||||
```bash
|
||||
python tools/run-tests.py --check-vera
|
||||
```
|
||||
|
||||
**To get a list of all the available test options**
|
||||
|
||||
```bash
|
||||
python tools/run-tests.py --help
|
||||
```
|
||||
@@ -0,0 +1,338 @@
|
||||
# Configuration
|
||||
|
||||
JerryScript provides a large number of configuration options which can be used to enable or disable specific features, allowing users to fine tune the engine to best suit their needs.
|
||||
A configuration option's value can be changed either by providing specific C preprocessor definitions, by adding CMake defininitions, or by using the arguments of the `tools/build.py` script.
|
||||
This document lists the available configuration options, shows the configuration name for C, CMake, and python, and provides a brief description that explains the effect of the options.
|
||||
|
||||
|
||||
### Amalgamated build
|
||||
|
||||
Enables the amalgamated build process, which aggregates the contents of each source file per library
|
||||
(i.e., JerryScript's core, port, and math libraries), and uses these combined files to compile the project.
|
||||
This process can provide comparable results to link-time optimization, and can be useful when LTO is not available otherwise.
|
||||
|
||||
| Options | |
|
||||
|---------|----------------------------------------------|
|
||||
| C: | `<none>` |
|
||||
| CMake: | `-DENABLE_AMALGAM=ON/OFF` |
|
||||
| Python: | `--amalgam=ON/OFF` |
|
||||
|
||||
See also: [Amalgamated sources](#amalgamated-sources)
|
||||
|
||||
### Jerry debugger
|
||||
|
||||
Enables debugger support in the engine, which can be used to debug running JavaScript code. For more information on using the debugger see [Debugger](07.DEBUGGER.md).
|
||||
The debugger is disabled by default.
|
||||
|
||||
| Options | |
|
||||
|---------|----------------------------------------------|
|
||||
| C: | `-DJERRY_DEBUGGER=0/1` |
|
||||
| CMake: | `-DJERRY_DEBUGGER=ON/OFF` |
|
||||
| Python: | `--jerry-debugger=ON/OFF` |
|
||||
|
||||
### Line information
|
||||
|
||||
By default, all source code information is discarded after parsing is complete. This option can be used to augment the created bytecode to provide line information during runtime,
|
||||
that can be used by the debugger to identify the currently executed source context. See [Debugger](07.DEBUGGER.md).
|
||||
|
||||
| Options | |
|
||||
|---------|----------------------------------------------|
|
||||
| C: | `-DJERRY_LINE_INFO=0/1` |
|
||||
| CMake: | `-DJERRY_LINE_INFO=ON/OFF` |
|
||||
| Python: | `--line-info=ON/OFF` |
|
||||
|
||||
### Profiles
|
||||
|
||||
This option can be used to enable/disable available JavaScript language features by providing profile files. Profile files contain a list of C definitions that configure each individual feature.
|
||||
The `path` value for CMake and Python arguments should be a file path to the profile file, or one of `es.next`, `es5.1`, or `minimal`, which are the pre-defined profiles.
|
||||
To see how a profile file should be created, or what configuration options are available in C, see the profile [README](https://github.com/jerryscript-project/jerryscript/blob/master/jerry-core/profiles/README.md).
|
||||
|
||||
| Options | |
|
||||
|---------|----------------------------------------------|
|
||||
| C: | `<see description>` |
|
||||
| CMake: | `-DJERRY_PROFILE="path"` |
|
||||
| Python: | `--profile="path"` |
|
||||
|
||||
### External context
|
||||
|
||||
Enables external context support in the engine. By default, JerryScript uses a statically allocated context to store the current state of the engine internals.
|
||||
When this option is enabled, an externally allocated memory region can be provided through the port API to the engine, to be used as the context.
|
||||
|
||||
| Options | |
|
||||
|---------|----------------------------------------------|
|
||||
| C: | `-DJERRY_EXTERNAL_CONTEXT=0/1` |
|
||||
| CMake: | `-DJERRY_EXTERNAL_CONTEXT=ON/OFF` |
|
||||
| Python: | `--external-context=ON/OFF` |
|
||||
|
||||
### Snapshot execution
|
||||
|
||||
This option can be used to enable snapshot execution in the engine.
|
||||
This option is disabled by default.
|
||||
|
||||
| Options | |
|
||||
|---------|----------------------------------------------|
|
||||
| C: | `-DJERRY_SNAPSHOT_EXEC=0/1` |
|
||||
| CMake: | `-DJERRY_SNAPSHOT_EXEC=ON/OFF` |
|
||||
| Python: | `--snapshot-exec=ON/OFF` |
|
||||
|
||||
### Snapshot saving
|
||||
|
||||
This option can be used to enable snapshot saving in the engine.
|
||||
This option is disabled by default.
|
||||
|
||||
| Options | |
|
||||
|---------|----------------------------------------------|
|
||||
| C: | `-DJERRY_SNAPSHOT_SAVE=0/1` |
|
||||
| CMake: | `-DJERRY_SNAPSHOT_SAVE=ON/OFF` |
|
||||
| Python: | `--snapshot-save=ON/OFF` |
|
||||
|
||||
### Jerry parser
|
||||
|
||||
This option can be used to enable or disable the parser. When the parser is disabled all features that depend on source parsing are unavailable (eg. `jerry_parse`, `eval`, Function constructor).
|
||||
This option can be useful in combination with the snapshot feature. The parser is enabled by default.
|
||||
|
||||
| Options | |
|
||||
|---------|----------------------------------------------|
|
||||
| C: | `-DJERRY_PARSER=0/1` |
|
||||
| CMake: | `-DJERRY_PARSER=ON/OFF` |
|
||||
| Python: | `--js-parser=ON/OFF` |
|
||||
|
||||
### Dump bytecode
|
||||
|
||||
This option can be used to display created bytecode in a human readable format. See [Internals](04.INTERNALS.md#byte-code) for more details.
|
||||
This option is disabled by default.
|
||||
|
||||
| Options | |
|
||||
|---------|----------------------------------------------|
|
||||
| C: | `-DJERRY_PARSER_DUMP_BYTE_CODE=0/1` |
|
||||
| CMake: | `-DJERRY_PARSER_DUMP_BYTE_CODE=ON/OFF` |
|
||||
| Python: | `--show-opcodes=ON/OFF` |
|
||||
|
||||
### Dump RegExp bytecode
|
||||
|
||||
This option can be used to display created RegExp bytecode in a human readable format. The RegExp bytecode is different from the bytecode used by the virtual machine.
|
||||
This option is disabled by default.
|
||||
|
||||
| Options | |
|
||||
|---------|----------------------------------------------|
|
||||
| C: | `-DJERRY_REGEXP_DUMP_BYTE_CODE=0/1` |
|
||||
| CMake: | `-DJERRY_REGEXP_DUMP_BYTE_CODE=ON/OFF` |
|
||||
| Python: | `--show-regexp-opcodes=ON/OFF` |
|
||||
|
||||
### Strict RegExp
|
||||
|
||||
This option can be used to enable strict RegExp mode. The standard RegExp syntax is a lot stricter than what is common in current JavaScript implementations.
|
||||
When enabled, this flag disables all of the non-standard, quality-of-life RegExp features, that are implemented to provide compatibility with other commonly used engines.
|
||||
This option is disabled by default.
|
||||
|
||||
| Options | |
|
||||
|---------|----------------------------------------------|
|
||||
| C: | `-DJERRY_REGEXP_STRICT_MODE=0/1` |
|
||||
| CMake: | `-DJERRY_REGEXP_STRICT_MODE=ON/OFF` |
|
||||
| Python: | `--regexp-strict-mode=ON/OFF` |
|
||||
|
||||
### Error messages
|
||||
|
||||
Enables error messages for thrown Error objects. By default, error messages are omitted to reduce memory usage.
|
||||
Enabling this feature provides detailed error messages where available, like line information for Syntax errors, variable names for Reference errors, Type/Range error messages for built-in routines, etc.
|
||||
|
||||
| Options | |
|
||||
|---------|----------------------------------------------|
|
||||
| C: | `-DJERRY_ERROR_MESSAGES=0/1` |
|
||||
| CMake: | `--DJERRY_ERROR_MESSAGES=ON/OFF` |
|
||||
| Python: | `--error-messages=ON/OFF` |
|
||||
|
||||
### Logging
|
||||
|
||||
This option can be used to enable log messages during runtime. When enabled the engine will use the `jerry_port_log` port API function to print relevant log messages.
|
||||
This feature is disabled by default.
|
||||
|
||||
| Options | |
|
||||
|---------|----------------------------------------------|
|
||||
| C: | `-DJERRY_LOGGING=0/1` |
|
||||
| CMake: | `-DJERRY_LOGGING=ON/OFF` |
|
||||
| Python: | `--logging=ON/OFF` |
|
||||
|
||||
### LCache
|
||||
|
||||
This option enables the LCache, allowing faster access to object properties. The LCache uses a statically allocated hash-map, which increases memory consumption.
|
||||
See [Internals](04.INTERNALS.md#lcache) for further details.
|
||||
This option is enabled by default.
|
||||
|
||||
| Options | |
|
||||
|---------|----------------------------------------------|
|
||||
| C: | `-DJERRY_LCACHE=0/1` |
|
||||
| CMake: | `<none>` |
|
||||
| Python: | `<none>` |
|
||||
|
||||
### Property hashmaps
|
||||
|
||||
This option enables the creation of hashmaps for object properties, which allows faster property access, at the cost of increased memory consumption.
|
||||
See [Internals](04.INTERNALS.md#property-hashmap) for further details.
|
||||
This option is enabled by default.
|
||||
|
||||
| Options | |
|
||||
|---------|----------------------------------------------|
|
||||
| C: | `-DJERRY_PROPRETY_HASHMAP=0/1` |
|
||||
| CMake: | `<none>` |
|
||||
| Python: | `<none>` |
|
||||
|
||||
### Memory statistics
|
||||
|
||||
This option can be used to provide memory usage statistics either upon engine termination, or during runtime using the `jerry_get_memory_stats` jerry API function.
|
||||
The feature can create a significant performance overhead, and should only be used for measurement purposes. This option is disabled by default.
|
||||
|
||||
| Options | |
|
||||
|---------|----------------------------------------------|
|
||||
| C: | `-DJERRY_MEM_STATS=0/1` |
|
||||
| CMake: | `-DJERRY_MEM_STATS=ON/OFF` |
|
||||
| Python: | `--mem-stats=ON/OFF` |
|
||||
|
||||
### Heap size
|
||||
|
||||
This option can be used to adjust the size of the internal heap, represented in kilobytes. The provided value should be an integer. Values larger than 512 require 32-bit compressed pointers to be enabled.
|
||||
The default value is 512.
|
||||
|
||||
| Options | |
|
||||
|---------|----------------------------------------------|
|
||||
| C: | `-DJERRY_GLOBAL_HEAP_SIZE=(int)` |
|
||||
| CMake: | `--DJERRY_GLOBAL_HEAP_SIZE=(int)` |
|
||||
| Python: | `--mem-heap=(int)` |
|
||||
|
||||
### Garbage collection limit
|
||||
|
||||
This option can be used to adjust the maximum allowed heap usage increase until triggering the next garbage collection, in bytes.
|
||||
When the total allocated memory size reaches the current gc limit, garbage collection will be triggered to try and reduce clutter from unreachable objects.
|
||||
If the total allocated memory can't be reduced below the current limit, then the limit will be increased by the amount specified via this option.
|
||||
Similarly, when the total allocated memory goes well below the current gc limit, the limit is reduced by this amount.
|
||||
The default value is 1/32 of the total heap size, but not greater than 8192 bytes.
|
||||
A value of 0 will use the default value.
|
||||
|
||||
| Options | |
|
||||
|---------|----------------------------------------------|
|
||||
| C: | `-DJERRY_GC_LIMIT=(int)` |
|
||||
| CMake: | `-DJERRY_GC_LIMIT=(int)` |
|
||||
| Python: | `--gc-limit=(int)` |
|
||||
|
||||
### GC mark recursion limit
|
||||
|
||||
This option can be used to adjust the maximum recursion depth during the GC mark phase. The provided value should be an integer, which represents the allowed number of recursive calls. Increasing the depth of the recursion reduces the time of GC cycles, however increases stack usage.
|
||||
A value of 0 will prevent any recursive GC calls.
|
||||
|
||||
| Options | |
|
||||
|---------|---------------------------------------------------|
|
||||
| C: | `-DJERRY_GC_MARK_LIMIT=(int)` |
|
||||
| CMake: | `-DJERRY_GC_MARK_LIMIT=(int)` |
|
||||
| Python: | `--gc-mark-limit=(int)` |
|
||||
|
||||
### Stack limit
|
||||
|
||||
This option can be used to cap the stack usage of the engine, and prevent stack overflows due to recursion. The provided value should be an integer, which represents the allowed stack usage in kilobytes.
|
||||
The default value is 0 (unlimited).
|
||||
|
||||
| Options | |
|
||||
|---------|----------------------------------------------|
|
||||
| C: | `-DJERRY_STACK_LIMIT=(int)` |
|
||||
| CMake: | `-DJERRY_STACK_LIMIT=(int)` |
|
||||
| Python: | `--stack-limit=(int)` |
|
||||
|
||||
### 32-bit compressed pointers
|
||||
|
||||
Enables 32-bit pointers instead of the default 16-bit compressed pointers. This allows the engine to use a much larger heap, but also comes with slightly increased memory usage, as objects can't be packed as tightly.
|
||||
This option must be enabled when using the system allocator.
|
||||
|
||||
| Options | |
|
||||
|---------|----------------------------------------------|
|
||||
| C: | `-DJERRY_CPOINTER_32_BIT=0/1` |
|
||||
| CMake: | `-DJERRY_CPOINTER_32_BIT=ON/OFF` |
|
||||
| Python: | `--cpointer-32bit=ON/OFF` |
|
||||
|
||||
### System allocator
|
||||
|
||||
This option enables the use of malloc/free instead of the internal JerryScript allocator. This feature requires 32-bit compressed pointers, and is unsupported on 64-bit architectures.
|
||||
This option is disabled by default.
|
||||
|
||||
| Options | |
|
||||
|---------|----------------------------------------------|
|
||||
| C: | `-DJERRY_SYSTEM_ALLOCATOR=0/1` |
|
||||
| CMake: | `-DJERRY_SYSTEM_ALLOCATOR=ON/OFF` |
|
||||
| Python: | `--system-allocator=ON/OFF` |
|
||||
|
||||
### Valgrind support
|
||||
|
||||
This option enables valgrind support for the internal allocator. When enabled, valgrind will be able to properly identify allocated memory regions, and report leaks or out-of-bounds memory accesses.
|
||||
This option is disabled by default.
|
||||
|
||||
| Options | |
|
||||
|---------|----------------------------------------------|
|
||||
| C: | `-DJERRY_VALGRIND=0/1` |
|
||||
| CMake: | `-DJERRY_VALGRIND=ON/OFF` |
|
||||
| Python: | `--valgrind=ON/OFF` |
|
||||
|
||||
### Memory stress test
|
||||
|
||||
This option can be used to stress test memory management, by running garbage collection before every allocation attempt.
|
||||
This option is disabled by default.
|
||||
|
||||
| Options | |
|
||||
|---------|----------------------------------------------|
|
||||
| C: | `-DJERRY_MEM_GC_BEFORE_EACH_ALLOC=0/1` |
|
||||
| CMake: | `-DJERRY_MEM_GC_BEFORE_EACH_ALLOC=ON/OFF` |
|
||||
| Python: | `--mem-stress-test=ON/OFF` |
|
||||
|
||||
|
||||
# Amalgamated sources
|
||||
|
||||
The sources of JerryScript can be combined into a handful of files to allow their easy integration
|
||||
in other projects. To achieve this, the following command can be executed to create a set of files
|
||||
into the `amalgam` directory:
|
||||
|
||||
```sh
|
||||
$ python tools/amalgam.py --output-dir amalgam --jerry-core --jerry-port-default --jerry-math
|
||||
```
|
||||
|
||||
(Note: In the example above, the command is executed from the project's root directory, but that is
|
||||
not mandatory.)
|
||||
|
||||
The command creates the following files in the `amalgam` dir:
|
||||
|
||||
* `jerryscript.c`
|
||||
* `jerryscript.h`
|
||||
* `jerryscript-config.h`
|
||||
* `jerryscript-port-default.c`
|
||||
* `jerryscript-port-default.h`
|
||||
* `jerryscript-math.c`
|
||||
* `math.h`
|
||||
|
||||
**Important**: the `jerryscript-config.h` contains the configurations mentioned above and
|
||||
should be adapted to the required use-case. See the file contents for more details and for the
|
||||
default configuration. (Note: This config file is created from the the `jerry-core/config.h` file.)
|
||||
|
||||
These files can be directly compiled with an application using the JerryScript API.
|
||||
E.g., using a command similar to the one below:
|
||||
|
||||
```sh
|
||||
$ gcc -Wall -o demo_app demo_app.c amalgam/jerryscript.c amalgam/jerryscript-port-default.c amalgam/jerryscript-math.c -Iamalgam/
|
||||
```
|
||||
|
||||
(Note: The headers must be available on the include path.)
|
||||
|
||||
This approach is also under the hood of the [amalgamated build](#amalgamated-build) process.
|
||||
|
||||
# Target specific information
|
||||
|
||||
## x86 with GCC
|
||||
|
||||
When building for Intel 32 bit architecture it is possible that GCC uses conservative options, thus assuming the most
|
||||
basic floating-point support (that is it does not generate SSE or others instructions).
|
||||
However this could lead to loss off precision and/or different results than what is required by the JavaScript standard
|
||||
in regards of floating-point values and arithmetic.
|
||||
|
||||
To resolve this precision problem it is advised to use at least SSE2.
|
||||
To do this with GCC please provide the `-mfpmath=sse -msse2` options during build.
|
||||
|
||||
These options can also be specified via the `build.py` script:
|
||||
|
||||
```sh
|
||||
$ ./tools/build.py --compile-flag=-mfpmath=sse --compile-flag=-msse2 --compile-flag=-m32
|
||||
```
|
||||
10197
APP_Framework/lib/JerryScript/jerryscript/docs/02.API-REFERENCE.md
Normal file
1115
APP_Framework/lib/JerryScript/jerryscript/docs/03.API-EXAMPLE.md
Normal file
334
APP_Framework/lib/JerryScript/jerryscript/docs/04.INTERNALS.md
Normal file
@@ -0,0 +1,334 @@
|
||||
# High-Level Design
|
||||

|
||||
|
||||
The diagram above shows the interactions between the major components of JerryScript: Parser and Virtual Machine (VM). Parser performs translation of input ECMAScript application into the byte-code with the specified format (refer to [Bytecode](#byte-code) and [Parser](#parser) page for details). Prepared bytecode is executed by the Virtual Machine that performs interpretation (refer to [Virtual Machine](#virtual-machine) and [ECMA](#ecma) pages for details).
|
||||
|
||||
# Parser
|
||||
|
||||
The parser is implemented as a recursive descent parser. The parser converts the JavaScript source code directly into byte-code without building an Abstract Syntax Tree. The parser depends on the following subcomponents.
|
||||
|
||||
## Lexer
|
||||
|
||||
The lexer splits input string (ECMAScript program) into sequence of tokens. It is able to scan the input string not only forward, but it is possible to move to an arbitrary position. The token structure described by structure `lexer_token_t` in `./jerry-core/parser/js/js-lexer.h`.
|
||||
|
||||
## Scanner
|
||||
|
||||
Scanner (`./jerry-core/parser/js/js-parser-scanner.c`) pre-scans the input string to find certain tokens. For example, scanner determines whether the keyword `for` defines a general for or a for-in loop. Reading tokens in a while loop is not enough because a slash (`/`) can indicate the start of a regular expression or can be a division operator.
|
||||
|
||||
## Expression Parser
|
||||
|
||||
Expression parser is responsible for parsing JavaScript expressions. It is implemented in `./jerry-core/parser/js/js-parser-expr.c`.
|
||||
|
||||
## Statement Parser
|
||||
|
||||
JavaScript statements are parsed by this component. It uses the [Expression parser](#expression-parser) to parse the constituent expressions. The implementation of Statement parser is located in `./jerry-core/parser/js/js-parser-statm.c`.
|
||||
|
||||
Function `parser_parse_source` carries out the parsing and compiling of the input ECMAScript source code. When a function appears in the source `parser_parse_source` calls `parser_parse_function` which is responsible for processing the source code of functions recursively including argument parsing and context handling. After the parsing, function `parser_post_processing` dumps the created opcodes and returns an `ecma_compiled_code_t*` that points to the compiled bytecode sequence.
|
||||
|
||||
The interactions between the major components shown on the following figure.
|
||||
|
||||

|
||||
|
||||
# Byte-code
|
||||
|
||||
This section describes the compact byte-code (CBC) representation. The key focus is reducing memory consumption of the byte-code representation without sacrificing considerable performance. Other byte-code representations often focus on performance only so inventing this representation is an original research.
|
||||
|
||||
CBC is a CISC like instruction set which assigns shorter instructions for frequent operations. Many instructions represent multiple atomic tasks which reduces the bytecode size. This technique is basically a data compression method.
|
||||
|
||||
## Compiled Code Format
|
||||
|
||||
The memory layout of the compiled bytecode is the following.
|
||||
|
||||

|
||||
|
||||
The header is a `cbc_compiled_code` structure with several fields. These fields contain the key properties of the compiled code.
|
||||
|
||||
The literals part is an array of ecma values. These values can contain any ECMAScript value types, e.g. strings, numbers, functions and regexp templates. The number of literals is stored in the `literal_end` field of the header.
|
||||
|
||||
CBC instruction list is a sequence of bytecode instructions which represents the compiled code.
|
||||
|
||||
## Byte-code Format
|
||||
|
||||
The memory layout of a byte-code is the following:
|
||||
|
||||

|
||||
|
||||
Each byte-code starts with an opcode. The opcode is one byte long for frequent and two byte long for rare instructions. The first byte of the rare instructions is always zero (`CBC_EXT_OPCODE`), and the second byte represents the extended opcode. The name of common and rare instructions start with `CBC_` and `CBC_EXT_` prefix respectively.
|
||||
|
||||
The maximum number of opcodes is 511, since 255 common (zero value excluded) and 256 rare instructions can be defined. Currently around 215 frequent and 70 rare instructions are available.
|
||||
|
||||
There are three types of bytecode arguments in CBC:
|
||||
|
||||
* __byte argument__: A value between 0 and 255, which often represents the argument count of call like opcodes (function call, new, eval, etc.).
|
||||
|
||||
* __literal argument__: An integer index which is greater or equal than zero and less than the `literal_end` field of the header. For further information see next section Literals (next).
|
||||
|
||||
* __relative branch__: An 1-3 byte long offset. The branch argument might also represent the end of an instruction range. For example the branch argument of `CBC_EXT_WITH_CREATE_CONTEXT` shows the end of a `with` statement. More precisely the position after the last instruction in the with clause.
|
||||
|
||||
Argument combinations are limited to the following seven forms:
|
||||
|
||||
* no arguments
|
||||
* a literal argument
|
||||
* a byte argument
|
||||
* a branch argument
|
||||
* a byte and a literal arguments
|
||||
* two literal arguments
|
||||
* three literal arguments
|
||||
|
||||
## Literals
|
||||
|
||||
Literals are organized into groups whose represent various literal types. Having these groups consuming less space than assigning flag bits to each literal.
|
||||
(In the followings, the mentioned ranges represent those indicies which are greater than or equal to the left side and less than the right side of the range. For example a range between `ident_end` and `literal_end` fields of the byte-code header contains those indicies, which are greater than or equal to `ident_end`
|
||||
and less than `literal_end`. If `ident_end` equals to `literal_end` the range is empty.)
|
||||
|
||||
The two major group of literals are _identifiers_ and _values_.
|
||||
|
||||
* __identifier__: A named reference to a variable. Literals between zero and `ident_end` of the header belongs to here. All of these literals must be a string or undefined. Undefined can only be used for those literals which cannot be accessed by a literal name. For example `function (arg,arg)` has two arguments, but the `arg` identifier only refers to the second argument. In such cases the name of the first argument is undefined. Furthermore optimizations such as *CSE* may also introduce literals without name.
|
||||
|
||||
* __value__: A reference to an immediate value. Literals between `ident_end` and `const_literal_end` are constant values such as numbers or strings. These literals can be used directly by the Virtual Machine. Literals between `const_literal_end` and `literal_end` are template literals. A new object needs to be constructed each time when their value is accessed. These literals are functions and regular expressions.
|
||||
|
||||
There are two other sub-groups of identifiers. *Registers* are those identifiers which are stored in the function call stack. *Arguments* are those registers which are passed by a caller function.
|
||||
|
||||
There are two types of literal encoding in CBC. Both are variable length, where the length is one or two byte long.
|
||||
|
||||
* __small__: maximum 511 literals can be encoded.
|
||||
|
||||
One byte encoding for literals 0 - 254.
|
||||
|
||||
```c
|
||||
byte[0] = literal_index
|
||||
```
|
||||
|
||||
Two byte encoding for literals 255 - 510.
|
||||
|
||||
```c
|
||||
byte[0] = 0xff
|
||||
byte[1] = literal_index - 0xff
|
||||
```
|
||||
|
||||
* __full__: maximum 32767 literal can be encoded.
|
||||
|
||||
One byte encoding for literals 0 - 127.
|
||||
|
||||
```c
|
||||
byte[0] = literal_index
|
||||
```
|
||||
|
||||
Two byte encoding for literals 128 - 32767.
|
||||
|
||||
```c
|
||||
byte[0] = (literal_index >> 8) | 0x80
|
||||
byte[1] = (literal_index & 0xff)
|
||||
```
|
||||
|
||||
Since most functions require less than 255 literal, small encoding provides a single byte literal index for all literals. Small encoding consumes less space than full encoding, but it has a limited range.
|
||||
|
||||
## Literal Store
|
||||
|
||||
JerryScript does not have a global string table for literals, but stores them into the Literal Store. During the parsing phase, when a new literal appears with the same identifier that has already occurred before, the string won't be stored once again, but the identifier in the Literal Store will be used. If a new literal is not in the Literal Store yet, it will be inserted.
|
||||
|
||||
## Byte-code Categories
|
||||
|
||||
Byte-codes can be placed into four main categories.
|
||||
|
||||
### Push Byte-codes
|
||||
|
||||
Byte-codes of this category serve for placing objects onto the stack. As there are many instructions representing multiple atomic tasks in CBC, there are also many instructions for pushing objects onto the stack according to the number and the type of the arguments. The following table list a few of these opcodes with a brief description.
|
||||
|
||||
<span class="CSSTableGenerator" markdown="block">
|
||||
|
||||
| byte-code | description |
|
||||
| --------------------- | ----------------------------------------------------- |
|
||||
| CBC_PUSH_LITERAL | Pushes the value of the given literal argument. |
|
||||
| CBC_PUSH_TWO_LITERALS | Pushes the values of the given two literal arguments. |
|
||||
| CBC_PUSH_UNDEFINED | Pushes an undefined value. |
|
||||
| CBC_PUSH_TRUE | Pushes a logical true. |
|
||||
| CBC_PUSH_PROP_LITERAL | Pushes a property whose base object is popped from the stack, and the property name is passed as a literal argument. |
|
||||
|
||||
</span>
|
||||
|
||||
### Call Byte-codes
|
||||
|
||||
The byte-codes of this category perform calls in different ways.
|
||||
|
||||
<span class="CSSTableGenerator" markdown="block">
|
||||
|
||||
| byte-code | description |
|
||||
| --------------------- | ------------------------------------------------------------------------------------ |
|
||||
| CBC_CALL0 | Calls a function without arguments. The return value won't be pushed onto the stack. |
|
||||
| CBC_CALL1 | Calls a function with one argument. The return value won't be pushed onto the stack. |
|
||||
| CBC_CALL | Calls a function with n arguments. n is passed as a byte argument. The return value won't be pushed onto the stack. |
|
||||
| CBC_CALL0_PUSH_RESULT | Calls a function without arguments. The return value will be pushed onto the stack. |
|
||||
| CBC_CALL1_PUSH_RESULT | Calls a function with one argument. The return value will be pushed onto the stack. |
|
||||
| CBC_CALL2_PROP | Calls a property function with two arguments. The base object, the property name, and the two arguments are on the stack. |
|
||||
|
||||
</span>
|
||||
|
||||
### Arithmetic, Logical, Bitwise and Assignment Byte-codes
|
||||
|
||||
The opcodes of this category perform arithmetic, logical, bitwise and assignment operations.
|
||||
|
||||
<span class="CSSTableGenerator" markdown="block">
|
||||
|
||||
| byte-code | description |
|
||||
| ----------------------- | --------------------------------------------------------------------------------------------------- |
|
||||
| CBC_LOGICAL_NOT | Negates the logical value that popped from the stack. The result is pushed onto the stack. |
|
||||
| CBC_LOGICAL_NOT_LITERAL | Negates the logical value that given in literal argument. The result is pushed onto the stack. |
|
||||
| CBC_ADD | Adds two values that are popped from the stack. The result is pushed onto the stack. |
|
||||
| CBC_ADD_RIGHT_LITERAL | Adds two values. The left one popped from the stack, the right one is given as literal argument. |
|
||||
| CBC_ADD_TWO_LITERALS | Adds two values. Both are given as literal arguments. |
|
||||
| CBC_ASSIGN | Assigns a value to a property. It has three arguments: base object, property name, value to assign. |
|
||||
| CBC_ASSIGN_PUSH_RESULT | Assigns a value to a property. It has three arguments: base object, property name, value to assign. The result will be pushed onto the stack. |
|
||||
|
||||
</span>
|
||||
|
||||
### Branch Byte-codes
|
||||
|
||||
Branch byte-codes are used to perform conditional and unconditional jumps in the byte-code. The arguments of these instructions are 1-3 byte long relative offsets. The number of bytes is part of the opcode, so each byte-code with a branch argument has three forms. The direction (forward, backward) is also defined by the opcode since the offset is an unsigned value. Thus, certain branch instructions has six forms. Some examples can be found in the following table.
|
||||
|
||||
<span class="CSSTableGenerator" markdown="block">
|
||||
|
||||
| byte-code | description |
|
||||
| -------------------------- | ----------------------------------------------------------- |
|
||||
| CBC_JUMP_FORWARD | Jumps forward by the 1 byte long relative offset argument. |
|
||||
| CBC_JUMP_FORWARD_2 | Jumps forward by the 2 byte long relative offset argument. |
|
||||
| CBC_JUMP_FORWARD_3 | Jumps forward by the 3 byte long relative offset argument. |
|
||||
| CBC_JUMP_BACKWARD | Jumps backward by the 1 byte long relative offset argument. |
|
||||
| CBC_JUMP_BACKWARD_2 | Jumps backward by the 2 byte long relative offset argument. |
|
||||
| CBC_JUMP_BACKWARD_3 | Jumps backward by the 3 byte long relative offset argument. |
|
||||
| CBC_BRANCH_IF_TRUE_FORWARD | Jumps forward if the value on the top of the stack is true by the 1 byte long relative offset argument. |
|
||||
|
||||
</span>
|
||||
|
||||
## Snapshot
|
||||
|
||||
The compiled byte-code can be saved into a snapshot, which also can be loaded back for execution. Directly executing the snapshot saves the costs of parsing the source in terms of memory consumption and performance. The snapshot can also be executed from ROM, in which case the overhead of loading it into the memory can also be saved.
|
||||
|
||||
|
||||
# Virtual Machine
|
||||
|
||||
Virtual machine is an interpreter which executes byte-code instructions one by one. The function that starts the interpretation is `vm_run` in `./jerry-core/vm/vm.c`. `vm_loop` is the main loop of the virtual machine, which has the peculiarity that it is *non-recursive*. This means that in case of function calls it does not calls itself recursively but returns, which has the benefit that it does not burdens the stack as a recursive implementation.
|
||||
|
||||
# ECMA
|
||||
|
||||
ECMA component of the engine is responsible for the following notions:
|
||||
|
||||
* Data representation
|
||||
* Runtime representation
|
||||
* Garbage collection (GC)
|
||||
|
||||
## Data Representation
|
||||
|
||||
The major structure for data representation is `ECMA_value`. The lower three bits of this structure encode value tag, which determines the type of the value:
|
||||
|
||||
* simple
|
||||
* number
|
||||
* string
|
||||
* object
|
||||
* symbol
|
||||
* error
|
||||
|
||||

|
||||
|
||||
In case of number, string and object the value contains an encoded pointer, and
|
||||
simple value is a pre-defined constant which can be:
|
||||
|
||||
* undefined
|
||||
* null
|
||||
* true
|
||||
* false
|
||||
* empty (uninitialized value)
|
||||
|
||||
### Compressed Pointers
|
||||
|
||||
Compressed pointers were introduced to save heap space.
|
||||
|
||||

|
||||
|
||||
These pointers are 8 byte aligned 16 bit long pointers which can address 512 Kb of
|
||||
memory which is also the maximum size of the JerryScript heap. To support even more
|
||||
memory the size of compressed pointers can be extended to 32 bit to cover the entire
|
||||
address space of a 32 bit system by passing "--cpointer_32_bit on" to the build
|
||||
system. These "uncompressed pointers" increases the memory consumption by around 20%.
|
||||
|
||||
### Number
|
||||
|
||||
There are two possible representation of numbers according to standard IEEE 754:
|
||||
The default is 8-byte (double),
|
||||
but the engine supports the 4-byte (single precision) representation by setting JERRY_NUMBER_TYPE_FLOAT64 to 0 as well.
|
||||
|
||||

|
||||
|
||||
Several references to single allocated number are not supported. Each reference holds its own copy of a number.
|
||||
|
||||
### String
|
||||
|
||||
Strings in JerryScript are not just character sequences, but can hold numbers and so-called magic ids too. For common character sequences (defined in `./jerry-core/lit/lit-magic-strings.ini`) there is a table in the read only memory that contains magic id and character sequence pairs. If a string is already in this table, the magic id of its string is stored, not the character sequence itself. Using numbers speeds up the property access. These techniques save memory.
|
||||
|
||||
### Object / Lexical Environment
|
||||
|
||||
An object can be a conventional data object or a lexical environment object. Unlike other data types, object can have references (called properties) to other data types. Because of circular references, reference counting is not always enough to determine dead objects. Hence a chain list is formed from all existing objects, which can be used to find unreferenced objects during garbage collection. The `gc-next` pointer of each object shows the next allocated object in the chain list.
|
||||
|
||||
[Lexical environments](http://www.ecma-international.org/ecma-262/5.1/#sec-10.2) are implemented as objects in JerryScript, since lexical environments contains key-value pairs (called bindings) like objects. This simplifies the implementation and reduces code size.
|
||||
|
||||

|
||||
|
||||
The objects are represented as following structure:
|
||||
|
||||
* Reference counter - number of hard (non-property) references
|
||||
* Next object pointer for the garbage collector
|
||||
* type (function object, lexical environment, etc.)
|
||||
|
||||
### Properties of Objects
|
||||
|
||||

|
||||
|
||||
Objects have a linked list that contains their properties. This list actually contains property pairs, in order to save memory described in the followings:
|
||||
A property has a one byte long descriptor, a two byte long name and four byte long value. Hence 14 bytes consumed by a property pair. Another two bytes is
|
||||
used to show the next property pair, so the total size (16 byte) is divisible by 8.
|
||||
|
||||
#### Property Hashmap
|
||||
|
||||
If the number of property pairs reach a limit (currently this limit is defined to 16), a hash map (called [Property Hashmap](#property-hashmap)) is inserted at the first position of the property pair list, in order to find a property using it, instead of finding it by iterating linearly over the property pairs.
|
||||
|
||||
Property hashmap contains 2<sup>n</sup> elements, where 2<sup>n</sup> is larger than the number of properties of the object. Each element can have tree types of value:
|
||||
|
||||
* null, indicating an empty element
|
||||
* deleted, indicating a deleted property, or
|
||||
* reference to the existing property
|
||||
|
||||
This hashmap is a must-return type cache, meaning that every property that the object have, can be found using it.
|
||||
|
||||
#### Internal Properties
|
||||
|
||||
Internal properties are special properties that carry meta-information that cannot be accessed by the JavaScript code, but important for the engine itself. Some examples of internal properties are listed below:
|
||||
|
||||
* [[Class]] - class (type) of the object (ECMA-defined)
|
||||
* [[Code]] - points where to find bytecode of the function
|
||||
* native code - points where to find the code of a native function
|
||||
* [[PrimitiveValue]] for Boolean - stores the boolean value of a Boolean object
|
||||
* [[PrimitiveValue]] for Number - stores the numeric value of a Number object
|
||||
|
||||
### LCache
|
||||
|
||||
LCache is a hashmap for finding a property specified by an object and by a property name. The object-name-property layout of the LCache presents multiple times in a row as it is shown in the figure below.
|
||||
|
||||

|
||||
|
||||
When a property access occurs, a hash value is extracted from the demanded property name and than this hash is used to index the LCache. After that, in the indexed row the specified object and property name will be searched.
|
||||
|
||||
It is important to note, that if the specified property is not found in the LCache, it does not mean that it does not exist (i.e. LCache is a may-return cache). If the property is not found, it will be searched in the property-list of the object, and if it is found there, the property will be placed into the LCache.
|
||||
|
||||
### Collections
|
||||
|
||||
Collections are array-like data structures, which are optimized to save memory. Actually, a collection is a linked list whose elements are not single elements, but arrays which can contain multiple elements.
|
||||
|
||||
### Exception Handling
|
||||
|
||||
In order to implement a sense of exception handling, the return values of JerryScript functions are able to indicate their faulty or "exceptional" operation. The return values are ECMA values (see section [Data Representation](#data-representation)) and if an erroneous operation occurred the ECMA_VALUE_ERROR simple value is returned.
|
||||
|
||||
### Value Management and Ownership
|
||||
|
||||
Every ECMA value stored by the engine is associated with a virtual "ownership", that defines how to manage the value: when to free it when it is not needed anymore and how to pass the value to an other function.
|
||||
|
||||
Initially, value is allocated by its owner (i.e. with ownership). The owner has the responsibility for freeing the allocated value. When the value is passed to a function as an argument, the ownership of it will not pass, the called function have to make an own copy of the value. However, as long as a function returns a value, the ownership will pass, thus the caller will be responsible for freeing it.
|
||||
449
APP_Framework/lib/JerryScript/jerryscript/docs/05.PORT-API.md
Normal file
@@ -0,0 +1,449 @@
|
||||
# Reference
|
||||
|
||||
## Termination
|
||||
|
||||
It is questionable whether a library should be able to terminate an application. Any API function can signal an error (ex.: cannot allocate memory), so the engine use the termination approach with this port function.
|
||||
|
||||
```c
|
||||
/**
|
||||
* Signal the port that jerry experienced a fatal failure from which it cannot
|
||||
* recover.
|
||||
*
|
||||
* @param code gives the cause of the error.
|
||||
*
|
||||
* Note:
|
||||
* Jerry expects the function not to return.
|
||||
*
|
||||
* Example: a libc-based port may implement this with exit() or abort(), or both.
|
||||
*/
|
||||
void jerry_port_fatal (jerry_fatal_code_t code);
|
||||
```
|
||||
|
||||
Error codes
|
||||
|
||||
```c
|
||||
typedef enum
|
||||
{
|
||||
ERR_OUT_OF_MEMORY = 10,
|
||||
ERR_REF_COUNT_LIMIT = 12,
|
||||
ERR_DISABLED_BYTE_CODE = 13,
|
||||
ERR_FAILED_INTERNAL_ASSERTION = 120
|
||||
} jerry_fatal_code_t;
|
||||
```
|
||||
|
||||
## I/O
|
||||
|
||||
These are the only I/O functions jerry calls.
|
||||
|
||||
```c
|
||||
/**
|
||||
* Jerry log levels. The levels are in severity order
|
||||
* where the most serious levels come first.
|
||||
*/
|
||||
typedef enum
|
||||
{
|
||||
JERRY_LOG_LEVEL_ERROR, /**< the engine will terminate after the message is printed */
|
||||
JERRY_LOG_LEVEL_WARNING, /**< a request is aborted, but the engine continues its operation */
|
||||
JERRY_LOG_LEVEL_DEBUG, /**< debug messages from the engine, low volume */
|
||||
JERRY_LOG_LEVEL_TRACE /**< detailed info about engine internals, potentially high volume */
|
||||
} jerry_log_level_t;
|
||||
|
||||
/**
|
||||
* Display or log a debug/error message, and sends it to the debugger client as well.
|
||||
* The function should implement a printf-like interface, where the first argument
|
||||
* specifies the log level and the second argument specifies a format string on how
|
||||
* to stringify the rest of the parameter list.
|
||||
*
|
||||
* This function is only called with messages coming from the jerry engine as
|
||||
* the result of some abnormal operation or describing its internal operations
|
||||
* (e.g., data structure dumps or tracing info).
|
||||
*
|
||||
* It should be the port that decides whether error and debug messages are logged to
|
||||
* the console, or saved to a database or to a file.
|
||||
*
|
||||
* Example: a libc-based port may implement this with vfprintf(stderr) or
|
||||
* vfprintf(logfile), or both, depending on log level.
|
||||
*
|
||||
* Note:
|
||||
* This port function is called by jerry-core when JERRY_LOGGING is
|
||||
* enabled. It is also common practice though to use this function in
|
||||
* application code.
|
||||
*/
|
||||
void jerry_port_log (jerry_log_level_t level, const char *fmt, ...);
|
||||
```
|
||||
|
||||
The `jerry_port_print_char` is currenlty not used by the jerry-core directly.
|
||||
However, it provides a port specifc way for `jerry-ext` components to print
|
||||
information.
|
||||
|
||||
```c
|
||||
/**
|
||||
* Print a character to stdout.
|
||||
*/
|
||||
void jerry_port_print_char (char c);
|
||||
```
|
||||
|
||||
### Jerry Module system
|
||||
|
||||
The port API provides functions that can be used by the module system to open
|
||||
and close source files, and normalize file paths.
|
||||
The `jerry_port_get_native_module` port function can be used to provide native
|
||||
modules to the engine. This function will be called when an import/export
|
||||
statement is encountered with an unknown module specifier, which embedders can
|
||||
use to supply native module objects based on the module name argument.
|
||||
|
||||
```c
|
||||
/**
|
||||
* Opens file with the given path and reads its source.
|
||||
* @return the source of the file
|
||||
*/
|
||||
uint8_t *
|
||||
jerry_port_read_source (const char *file_name_p, /**< file name */
|
||||
size_t *out_size_p) /**< [out] read bytes */
|
||||
{
|
||||
// open file from given path
|
||||
// return its source
|
||||
} /* jerry_port_read_source */
|
||||
|
||||
/**
|
||||
* Release the previously opened file's content.
|
||||
*/
|
||||
void
|
||||
jerry_port_release_source (uint8_t *buffer_p) /**< buffer to free */
|
||||
{
|
||||
free (buffer_p);
|
||||
} /* jerry_port_release_source */
|
||||
|
||||
/**
|
||||
* Normalize a file path
|
||||
*
|
||||
* @return length of the path written to the output buffer
|
||||
*/
|
||||
size_t
|
||||
jerry_port_normalize_path (const char *in_path_p, /**< input file path */
|
||||
char *out_buf_p, /**< output buffer */
|
||||
size_t out_buf_size, /**< size of output buffer */
|
||||
char *base_file_p) /**< base file path */
|
||||
{
|
||||
// normalize in_path_p by expanding relative paths etc.
|
||||
// if base_file_p is not NULL, in_path_p is relative to that file
|
||||
// write to out_buf_p the normalized path
|
||||
// return length of written path
|
||||
} /* jerry_port_normalize_path */
|
||||
|
||||
/**
|
||||
* Get the module object of a native module.
|
||||
*
|
||||
* Note:
|
||||
* This port function is called by jerry-core when JERRY_MODULE_SYSTEM
|
||||
* is enabled.
|
||||
*
|
||||
* @param name String value of the module specifier.
|
||||
*
|
||||
* @return Undefined, if 'name' is not a native module
|
||||
* jerry_value_t containing the module object, otherwise
|
||||
*/
|
||||
jerry_value_t
|
||||
jerry_port_get_native_module (jerry_value_t name) /**< module specifier */
|
||||
{
|
||||
(void) name;
|
||||
return jerry_create_undefined ();
|
||||
}
|
||||
```
|
||||
|
||||
## Promise
|
||||
|
||||
```c
|
||||
/**
|
||||
* HostPromiseRejectionTracker operations
|
||||
*/
|
||||
typedef enum
|
||||
{
|
||||
JERRY_PROMISE_REJECTION_OPERATION_REJECT, /**< promise is rejected without any handlers */
|
||||
JERRY_PROMISE_REJECTION_OPERATION_HANDLE, /**< handler is added to a rejected promise for the first time */
|
||||
} jerry_promise_rejection_operation_t;
|
||||
|
||||
/**
|
||||
* Track unhandled promise rejections.
|
||||
*
|
||||
* Note:
|
||||
* This port function is called by jerry-core when JERRY_BUILTIN_PROMISE
|
||||
* is enabled.
|
||||
*
|
||||
* @param promise rejected promise
|
||||
* @param operation HostPromiseRejectionTracker operation
|
||||
*/
|
||||
void jerry_port_track_promise_rejection (const jerry_value_t promise,
|
||||
const jerry_promise_rejection_operation_t operation);
|
||||
```
|
||||
|
||||
## Date
|
||||
|
||||
```c
|
||||
/**
|
||||
* Get local time zone adjustment, in milliseconds, for the given timestamp.
|
||||
* The timestamp can be specified in either UTC or local time, depending on
|
||||
* the value of is_utc. Adding the value returned from this function to
|
||||
* a timestamp in UTC time should result in local time for the current time
|
||||
* zone, and subtracting it from a timestamp in local time should result in
|
||||
* UTC time.
|
||||
*
|
||||
* Ideally, this function should satisfy the stipulations applied to LocalTZA
|
||||
* in section 20.3.1.7 of the ECMAScript version 9.0 spec.
|
||||
*
|
||||
* See Also:
|
||||
* ECMA-262 v9, 20.3.1.7
|
||||
*
|
||||
* Note:
|
||||
* This port function is called by jerry-core when
|
||||
* JERRY_BUILTIN_DATE is set to 1. Otherwise this function is
|
||||
* not used.
|
||||
*
|
||||
* @param unix_ms The unix timestamp we want an offset for, given in
|
||||
* millisecond precision (could be now, in the future,
|
||||
* or in the past). As with all unix timestamps, 0 refers to
|
||||
* 1970-01-01, a day is exactly 86 400 000 milliseconds, and
|
||||
* leap seconds cause the same second to occur twice.
|
||||
* @param is_utc Is the given timestamp in UTC time? If false, it is in local
|
||||
* time.
|
||||
*
|
||||
* @return milliseconds between local time and UTC for the given timestamp,
|
||||
* if available
|
||||
*. 0 if not available / we are in UTC.
|
||||
*/
|
||||
double jerry_port_get_local_time_zone_adjustment (double unix_ms, bool is_utc);
|
||||
|
||||
/**
|
||||
* Get system time
|
||||
*
|
||||
* Note:
|
||||
* This port function is called by jerry-core when
|
||||
* JERRY_BUILTIN_DATE is set to 1. It is also common practice
|
||||
* in application code to use this function for the initialization of the
|
||||
* random number generator.
|
||||
*
|
||||
* @return milliseconds since Unix epoch
|
||||
*/
|
||||
double jerry_port_get_current_time (void);
|
||||
```
|
||||
|
||||
## External context
|
||||
|
||||
Allow user to provide external buffer for isolated engine contexts, so that user
|
||||
can configure the heap size at runtime and run multiple JS applications
|
||||
simultaneously.
|
||||
|
||||
```c
|
||||
/**
|
||||
* Get the current context of the engine. Each port should provide its own
|
||||
* implementation of this interface.
|
||||
*
|
||||
* Note:
|
||||
* This port function is called by jerry-core when
|
||||
* JERRY_EXTERNAL_CONTEXT is enabled. Otherwise this function is not
|
||||
* used.
|
||||
*
|
||||
* @return the pointer to the engine context.
|
||||
*/
|
||||
struct jerry_context_t *jerry_port_get_current_context (void);
|
||||
```
|
||||
|
||||
## Sleep
|
||||
|
||||
```c
|
||||
/**
|
||||
* Makes the process sleep for a given time.
|
||||
*
|
||||
* Note:
|
||||
* This port function is called by jerry-core when JERRY_DEBUGGER is set to 1.
|
||||
* Otherwise this function is not used.
|
||||
*
|
||||
* @param sleep_time milliseconds to sleep.
|
||||
*/
|
||||
void jerry_port_sleep (uint32_t sleep_time);
|
||||
```
|
||||
|
||||
# How to port JerryScript
|
||||
|
||||
This section describes a basic port implementation which was created for Unix based systems.
|
||||
|
||||
## Termination
|
||||
|
||||
```c
|
||||
#include <stdlib.h>
|
||||
#include "jerryscript-port.h"
|
||||
|
||||
/**
|
||||
* Default implementation of jerry_port_fatal.
|
||||
*/
|
||||
void jerry_port_fatal (jerry_fatal_code_t code)
|
||||
{
|
||||
exit (code);
|
||||
} /* jerry_port_fatal */
|
||||
```
|
||||
|
||||
## I/O
|
||||
|
||||
```c
|
||||
#include <stdarg.h>
|
||||
#include "jerryscript-port.h"
|
||||
|
||||
/**
|
||||
* Provide log message implementation for the engine.
|
||||
*
|
||||
* Note:
|
||||
* This example ignores the log level.
|
||||
*/
|
||||
void
|
||||
jerry_port_log (jerry_log_level_t level, /**< log level */
|
||||
const char *format, /**< format string */
|
||||
...) /**< parameters */
|
||||
{
|
||||
va_list args;
|
||||
va_start (args, format);
|
||||
vfprintf (stderr, format, args);
|
||||
va_end (args);
|
||||
} /* jerry_port_log */
|
||||
```
|
||||
|
||||
```c
|
||||
/**
|
||||
* Print a character to stdout with putchar.
|
||||
*/
|
||||
void
|
||||
jerry_port_print_char (char c)
|
||||
{
|
||||
putchar (c);
|
||||
} /* jerr_port_print_char */
|
||||
```
|
||||
|
||||
## Date
|
||||
|
||||
```c
|
||||
#include <time.h>
|
||||
#include <sys/time.h>
|
||||
#include "jerryscript-port.h"
|
||||
|
||||
/**
|
||||
* Default implementation of jerry_port_get_local_time_zone_adjustment.
|
||||
*/
|
||||
double jerry_port_get_local_time_zone_adjustment (double unix_ms, /**< ms since unix epoch */
|
||||
bool is_utc) /**< is the time above in UTC? */
|
||||
{
|
||||
struct tm tm;
|
||||
time_t now = (time_t) (unix_ms / 1000);
|
||||
localtime_r (&now, &tm);
|
||||
if (!is_utc)
|
||||
{
|
||||
now -= tm.tm_gmtoff;
|
||||
localtime_r (&now, &tm);
|
||||
}
|
||||
return ((double) tm.tm_gmtoff) * 1000;
|
||||
} /* jerry_port_get_local_time_zone_adjustment */
|
||||
|
||||
/**
|
||||
* Default implementation of jerry_port_get_current_time.
|
||||
*/
|
||||
double jerry_port_get_current_time (void)
|
||||
{
|
||||
struct timeval tv;
|
||||
|
||||
if (gettimeofday (&tv, NULL) != 0)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
return ((double) tv.tv_sec) * 1000.0 + ((double) tv.tv_usec) / 1000.0;
|
||||
} /* jerry_port_get_current_time */
|
||||
```
|
||||
|
||||
## External context
|
||||
|
||||
```c
|
||||
#include "jerryscript-port.h"
|
||||
#include "jerryscript-port-default.h"
|
||||
|
||||
/**
|
||||
* Pointer to the current context.
|
||||
* Note that it is a global variable, and is not a thread safe implementation.
|
||||
*/
|
||||
static jerry_context_t *current_context_p = NULL;
|
||||
|
||||
/**
|
||||
* Set the current_context_p as the passed pointer.
|
||||
*/
|
||||
void
|
||||
jerry_port_default_set_current_context (jerry_context_t *context_p) /**< points to the created context */
|
||||
{
|
||||
current_context_p = context_p;
|
||||
} /* jerry_port_default_set_current_context */
|
||||
|
||||
/**
|
||||
* Get the current context.
|
||||
*
|
||||
* @return the pointer to the current context
|
||||
*/
|
||||
jerry_context_t *
|
||||
jerry_port_get_current_context (void)
|
||||
{
|
||||
return current_context_p;
|
||||
} /* jerry_port_get_current_context */
|
||||
```
|
||||
|
||||
## Sleep
|
||||
|
||||
```c
|
||||
#include "jerryscript-port.h"
|
||||
#include "jerryscript-port-default.h"
|
||||
|
||||
#ifdef HAVE_TIME_H
|
||||
#include <time.h>
|
||||
#elif defined (HAVE_UNISTD_H)
|
||||
#include <unistd.h>
|
||||
#endif /* HAVE_TIME_H */
|
||||
|
||||
#if defined (JERRY_DEBUGGER) && (JERRY_DEBUGGER == 1)
|
||||
void jerry_port_sleep (uint32_t sleep_time)
|
||||
{
|
||||
#ifdef HAVE_TIME_H
|
||||
nanosleep (&(const struct timespec)
|
||||
{
|
||||
(time_t) sleep_time / 1000, ((long int) sleep_time % 1000) * 1000000L /* Seconds, nanoseconds */
|
||||
}
|
||||
, NULL);
|
||||
#elif defined (HAVE_UNISTD_H)
|
||||
usleep ((useconds_t) sleep_time * 1000);
|
||||
#endif /* HAVE_TIME_H */
|
||||
(void) sleep_time;
|
||||
} /* jerry_port_sleep */
|
||||
#endif /* defined (JERRY_DEBUGGER) && (JERRY_DEBUGGER == 1) */
|
||||
```
|
||||
|
||||
## Promise
|
||||
|
||||
```c
|
||||
#include "jerryscript-port.h"
|
||||
|
||||
/**
|
||||
* Default implementation of jerry_port_track_promise_rejection.
|
||||
* Prints the reason of the unhandled rejections.
|
||||
*/
|
||||
void
|
||||
jerry_port_track_promise_rejection (const jerry_value_t promise, /**< rejected promise */
|
||||
const jerry_promise_rejection_operation_t operation) /**< operation */
|
||||
{
|
||||
(void) operation; /* unused */
|
||||
|
||||
jerry_value_t reason = jerry_get_promise_result (promise);
|
||||
jerry_value_t reason_to_string = jerry_value_to_string (reason);
|
||||
jerry_size_t req_sz = jerry_get_utf8_string_size (reason_to_string);
|
||||
jerry_char_t str_buf_p[req_sz + 1];
|
||||
jerry_string_to_utf8_char_buffer (reason_to_string, str_buf_p, req_sz);
|
||||
str_buf_p[req_sz] = '\0';
|
||||
|
||||
jerry_release_value (reason_to_string);
|
||||
jerry_release_value (reason);
|
||||
|
||||
printf ("Uncaught (in promise) %s\n", str_buf_p);
|
||||
} /* jerry_port_track_promise_rejection */
|
||||
```
|
||||
@@ -0,0 +1,176 @@
|
||||
## Reference counting in JerryScript
|
||||
|
||||
In JerryScript all `jerry_value_t` values are independent
|
||||
references to internal objects. Values returned by JerryScript
|
||||
API functions are always live references and must be released
|
||||
by `jerry_release_value`.
|
||||
|
||||
```c
|
||||
jerry_value_t global = jerry_get_global_object ();
|
||||
|
||||
/* The value stored in the 'global' variable contains a live
|
||||
* reference to the global object. The system also keeps its
|
||||
* own live reference to the global object. These two references
|
||||
* are independent, and both must be destroyed before the global
|
||||
* object can be freed. */
|
||||
|
||||
jerry_release_value (global);
|
||||
|
||||
/* Without jerry_release_value() the global object will not
|
||||
* be freed even by jerry_cleanup(). After the reference
|
||||
* is released it becomes a dead reference and cannot be
|
||||
* used anymore. */
|
||||
```
|
||||
|
||||
Multiple references might refer to the same internal object
|
||||
even though their `jerry_value_t` representation might be different.
|
||||
|
||||
```c
|
||||
jerry_value_t pi_ref1 = jerry_create_number (3.14);
|
||||
jerry_value_t pi_ref2 = jerry_acquire_value (pi_ref1);
|
||||
|
||||
/* Both pi_ref1 and pi_ref2 refer to the same 3.14 value
|
||||
* although they might not be equal in C (pi_ref1 != pi_ref2). */
|
||||
|
||||
/* Both references must be released. */
|
||||
jerry_release_value (pi_ref1);
|
||||
jerry_release_value (pi_ref2);
|
||||
```
|
||||
|
||||
Releasing the same `jerry_value_t` twice to release two live
|
||||
references is not allowed and it might cause crashes. Hence the
|
||||
following code is an **INCORRECT WAY** of releasing the 3.14 value.
|
||||
|
||||
```c
|
||||
jerry_release_value (pi_ref1);
|
||||
jerry_release_value (pi_ref1);
|
||||
```
|
||||
|
||||
JerryScript API functions returning with a `jerry_value_t` always
|
||||
return with a new live reference. Passing a `jerry_value_t` to
|
||||
an API function never releases its reference (unless explicitly
|
||||
stated in the documentation). The next example shows this
|
||||
behaviour through property getting and setting.
|
||||
|
||||
```c
|
||||
jerry_value_t prop_value = jerry_get_property (...);
|
||||
|
||||
/* The prop_value must be released later because both the base
|
||||
* object and the prop_value have an independent reference to
|
||||
* the same JavaScript value. When the operation fails, the
|
||||
* prop_value contains a live reference to an error object.
|
||||
* This reference must be released as well. */
|
||||
|
||||
if (jerry_value_is_error (prop_value))
|
||||
{
|
||||
/* Errors can be handled here. */
|
||||
}
|
||||
else
|
||||
{
|
||||
/* The application has a live reference to the property
|
||||
* value even if the base object is freed by the garbage
|
||||
* collector. */
|
||||
}
|
||||
|
||||
/* The prop_value must be released. */
|
||||
jerry_release_value (prop_value);
|
||||
|
||||
/* Property setting is the same. */
|
||||
|
||||
jerry_value_t new_prop_value = jerry_create_number (2.718);
|
||||
jerry_value_t result = jerry_set_property (..., new_prop_value);
|
||||
|
||||
/* If the property set is successful, a new reference is created
|
||||
* for the value referenced by new_prop_value. The new_prop_value
|
||||
* reference must be released regardless of whether the operation
|
||||
* is successful. */
|
||||
|
||||
/* The new_prop_value can be passed to other JerryScript API
|
||||
* functions before the jerry_release_value () call. */
|
||||
|
||||
jerry_release_value (new_prop_value);
|
||||
|
||||
/* The reference stored in the 'result' variable is live whether
|
||||
* the operation is successful or not, and must also be freed. */
|
||||
|
||||
if (jerry_value_is_error (result))
|
||||
{
|
||||
/* Errors can be handled here. */
|
||||
}
|
||||
else
|
||||
{
|
||||
/* A reference to a true primitive value is returned. */
|
||||
}
|
||||
|
||||
jerry_release_value (result);
|
||||
```
|
||||
|
||||
The simplest form of setting a property without error checking
|
||||
is the following:
|
||||
|
||||
```c
|
||||
/* There are no 'ifs' in this snippet. */
|
||||
jerry_release_value (jerry_set_property (..., new_prop_value));
|
||||
jerry_release_value (new_prop_value);
|
||||
```
|
||||
|
||||
The reference returned by a `jerry_external_handler_t` callback
|
||||
transfers the ownership of the live reference. Otherwise the
|
||||
referenced object could be freed by the garbage collector.
|
||||
|
||||
```c
|
||||
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
|
||||
{
|
||||
/* Do not release function_obj, this_val, and args_p because
|
||||
* these references are automatically released after the handler
|
||||
* is returned. This approach reduces code size which is useful
|
||||
* on embedded systems. However you can create other references
|
||||
* to them by calling jerry_acquire_value () if needed. */
|
||||
|
||||
/* Since the ownership of the reference is transferred to the
|
||||
* caller the following snippet is valid. */
|
||||
|
||||
/* If the value to be returned is needed for other purposes the
|
||||
* jerry_acquire_value () can be used to create new references. */
|
||||
return jerry_create_string (...);
|
||||
}
|
||||
```
|
||||
|
||||
Duplicating a `jerry_value_t` in C does not create another live reference.
|
||||
|
||||
```c
|
||||
jerry_value_t undef = jerry_create_undefined ();
|
||||
jerry_value_t undef2 = undef;
|
||||
|
||||
/* Releasing either undef or undef2 is valid but not both.
|
||||
* After the release both references become dead (invalid). */
|
||||
jerry_release_value (undef2);
|
||||
|
||||
/* Dead references can be reassigned again. */
|
||||
undef = jerry_create_boolean (true);
|
||||
```
|
||||
|
||||
References can be duplicated in C as long as only one of them is freed.
|
||||
|
||||
```c
|
||||
jerry_value_t a = jerry_create_boolean (true);
|
||||
|
||||
jerry_value_t b = a;
|
||||
jerry_value_t c = a;
|
||||
|
||||
/* A new reference is assigned to 'a'. */
|
||||
a = jerry_create_boolean (false);
|
||||
|
||||
[...]
|
||||
|
||||
jerry_release_value (a);
|
||||
/* The 'a' (boolean false) reference becomes dead (invalid). */
|
||||
|
||||
jerry_release_value (c);
|
||||
/* Both 'b' and 'c' (boolean true) references become dead. */
|
||||
|
||||
/* Since all references are released, no memory leak occurs. */
|
||||
```
|
||||
443
APP_Framework/lib/JerryScript/jerryscript/docs/07.DEBUGGER.md
Normal file
@@ -0,0 +1,443 @@
|
||||
## JerryScript debugger interface
|
||||
|
||||
JerryScript provides a remote debugger which allows debugging
|
||||
JavaScript programs. The debugger has two main components:
|
||||
a server which is part of the JerryScript binary and a
|
||||
separate client application. Currently a Python-based debugger
|
||||
client is available in the /jerry-debugger subdirectory.
|
||||
This simple application demonstrates the communication protocol
|
||||
between the client and server, and can be reused by integrated
|
||||
development environments.
|
||||
|
||||
## Setting up the debugger server
|
||||
|
||||
The following arguments must be passed to `tools/build.py`:
|
||||
|
||||
`--jerry-debugger=on`
|
||||
|
||||
The transport layer of the communication protocol is pluggable.
|
||||
At the moment, a WebSocket-based implementation is provided as a
|
||||
JerryScript extension, which transmits messages over TCP/IP networks.
|
||||
If necessary/implemented, any reliable stream or datagram based
|
||||
protocol can be used for transmitting debugger messages.
|
||||
|
||||
## Debugging JavaScript applications
|
||||
|
||||
The debugger client must be connected to the server before the
|
||||
JavaScript application runs. On-the-fly attachment is supported
|
||||
for more than one file, right after the engine initialization
|
||||
(this feature is available with the python client). The debugging
|
||||
information (e.g. line index of each possible breakpoint location)
|
||||
is not preserved by JerryScript. The client is expected to be run
|
||||
on a system with much more resources and it should be capable of
|
||||
storing this information. JerryScript frees all debug information
|
||||
after it is transmitted to the client to save memory.
|
||||
|
||||
The following argument makes JerryScript wait for a client
|
||||
connection:
|
||||
|
||||
`--start-debug-server`
|
||||
|
||||
The following argument makes JerryScript wait for a client
|
||||
source code:
|
||||
|
||||
`--debugger-wait-source`
|
||||
|
||||
It is also recommended to increase the log level to see
|
||||
the *Waiting for client connection* message:
|
||||
|
||||
`--log-level 2`
|
||||
|
||||
The Python client can connect to the server by specifying its
|
||||
IP address on the command line. The address can be localhost
|
||||
if the server and the client are running on the same machine.
|
||||
|
||||
After the connection is established the execution can be
|
||||
controlled by the debugger. The debugger always stops at
|
||||
the first possible breakpoint location. The effect is the
|
||||
same as using the `stop` command. This allows inserting
|
||||
breakpoints right before the meaningful part of the execution
|
||||
starts.
|
||||
|
||||
All available commands of the client can be queried by the
|
||||
`help` command.
|
||||
|
||||
## Integrating debugger support into applications using JerryScript
|
||||
|
||||
When using the extension-provided WebSocket transport layer, the
|
||||
debugger can be enabled by calling `jerryx_debugger_after_connect
|
||||
(jerryx_debugger_tcp_create (debug_port) && jerryx_debugger_ws_create ())`
|
||||
after the `jerry_init ()` function. It initializes the debugger and
|
||||
blocks until a client connects.
|
||||
(Custom transport layers may be implemented and initialized similarly.
|
||||
Currently, `jerryx_debugger_rp_create ()` for raw packet transport layer and
|
||||
`jerryx_debugger_serial_create (const char* config)` for serial protocol
|
||||
are also available.)
|
||||
|
||||
The resource name provided to `jerry_parse ()` is used by the client
|
||||
to identify the resource name of the source code. This resource name
|
||||
is usually a file name.
|
||||
|
||||
## JerryScript debugger C-API interface
|
||||
|
||||
The following section describes the debugger functions
|
||||
available to 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_is_connected
|
||||
|
||||
**Summary**
|
||||
|
||||
Returns true if a remote debugger client is connected.
|
||||
|
||||
**Prototype**
|
||||
|
||||
```c
|
||||
bool
|
||||
jerry_debugger_is_connected (void);
|
||||
```
|
||||
|
||||
**Example**
|
||||
|
||||
[doctest]: # (test="link")
|
||||
|
||||
```c
|
||||
#include "jerryscript.h"
|
||||
#include "jerryscript-ext/debugger.h"
|
||||
|
||||
int
|
||||
main (void)
|
||||
{
|
||||
jerry_init (JERRY_INIT_EMPTY);
|
||||
jerryx_debugger_after_connect (jerryx_debugger_tcp_create (5001)
|
||||
&& jerryx_debugger_ws_create ());
|
||||
|
||||
if (jerry_debugger_is_connected ())
|
||||
{
|
||||
printf ("A remote debugger client is connected.");
|
||||
}
|
||||
|
||||
jerry_cleanup ();
|
||||
}
|
||||
```
|
||||
|
||||
### jerry_debugger_stop
|
||||
|
||||
**Summary**
|
||||
|
||||
Stops execution at the next available breakpoint if a remote
|
||||
debugger client is connected and the engine is not waiting at
|
||||
a breakpoint. The engine will stop regardless the breakpoint
|
||||
is enabled or not.
|
||||
|
||||
**Prototype**
|
||||
|
||||
```c
|
||||
void
|
||||
jerry_debugger_stop (void)
|
||||
```
|
||||
|
||||
**Example**
|
||||
|
||||
[doctest]: # (test="link")
|
||||
|
||||
```c
|
||||
#include "jerryscript.h"
|
||||
#include "jerryscript-ext/debugger.h"
|
||||
|
||||
int
|
||||
main (void)
|
||||
{
|
||||
jerry_init (JERRY_INIT_EMPTY);
|
||||
jerryx_debugger_after_connect (jerryx_debugger_tcp_create (5001)
|
||||
&& jerryx_debugger_ws_create ());
|
||||
|
||||
jerry_debugger_stop ();
|
||||
|
||||
jerry_cleanup ();
|
||||
}
|
||||
```
|
||||
|
||||
**See also**
|
||||
|
||||
- [jerry_debugger_continue](#jerry_debugger_continue)
|
||||
|
||||
### jerry_debugger_continue
|
||||
|
||||
**Summary**
|
||||
|
||||
If the engine would stop at the next available breakpoint it
|
||||
cancels this effect. The engine will still stop at enabled
|
||||
breakpoints. This function effectively negates the effect of
|
||||
[jerry_debugger_stop ()](#jerry_debugger_stop) calls or stop
|
||||
requests issued by the debugger client.
|
||||
|
||||
**Prototype**
|
||||
|
||||
```c
|
||||
void
|
||||
jerry_debugger_continue (void)
|
||||
```
|
||||
|
||||
**Example**
|
||||
|
||||
[doctest]: # (test="link")
|
||||
|
||||
```c
|
||||
#include "jerryscript.h"
|
||||
#include "jerryscript-ext/debugger.h"
|
||||
|
||||
int
|
||||
main (void)
|
||||
{
|
||||
jerry_init (JERRY_INIT_EMPTY);
|
||||
jerryx_debugger_after_connect (jerryx_debugger_tcp_create (5001)
|
||||
&& jerryx_debugger_ws_create ());
|
||||
|
||||
jerry_debugger_continue ();
|
||||
|
||||
jerry_cleanup ();
|
||||
}
|
||||
```
|
||||
|
||||
**See also**
|
||||
|
||||
- [jerry_debugger_stop](#jerry_debugger_stop)
|
||||
|
||||
### jerry_debugger_stop_at_breakpoint
|
||||
|
||||
**Summary**
|
||||
|
||||
Enables or disables stopping at breakpoints. When stopping is
|
||||
disabled all breakpoints are ignored including user enabled
|
||||
breakpoints. This allows hidden execution of ECMAScript code.
|
||||
|
||||
**Prototype**
|
||||
|
||||
```c
|
||||
void
|
||||
jerry_debugger_stop_at_breakpoint (bool enable_stop_at_breakpoint)
|
||||
```
|
||||
|
||||
- `enable_stop_at_breakpoint` - enable (=`true`) or disable (=`false`) stopping at breakpoints
|
||||
|
||||
**Example**
|
||||
|
||||
[doctest]: # (test="link")
|
||||
|
||||
```c
|
||||
#include "jerryscript.h"
|
||||
#include "jerryscript-ext/debugger.h"
|
||||
|
||||
int
|
||||
main (void)
|
||||
{
|
||||
jerry_init (JERRY_INIT_EMPTY);
|
||||
jerryx_debugger_after_connect (jerryx_debugger_tcp_create (5001)
|
||||
&& jerryx_debugger_ws_create ());
|
||||
|
||||
jerry_debugger_stop_at_breakpoint (true);
|
||||
|
||||
// Protected execution of JavaScript code.
|
||||
const jerry_char_t script[] = "42";
|
||||
jerry_eval (script, sizeof (script) - 1, JERRY_PARSE_NO_OPTS);
|
||||
|
||||
jerry_debugger_stop_at_breakpoint (false);
|
||||
|
||||
jerry_cleanup ();
|
||||
}
|
||||
```
|
||||
|
||||
### jerry_debugger_wait_for_client_source
|
||||
|
||||
**Summary**
|
||||
|
||||
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_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**
|
||||
|
||||
[doctest]: # (test="link")
|
||||
|
||||
```c
|
||||
#include "jerryscript.h"
|
||||
#include "jerryscript-ext/debugger.h"
|
||||
|
||||
/**
|
||||
* 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 /**< user pointer */)
|
||||
{
|
||||
(void) user_p;
|
||||
|
||||
jerry_value_t ret_val = jerry_parse (resource_name_p,
|
||||
resource_name_size,
|
||||
source_p,
|
||||
source_size,
|
||||
JERRY_PARSE_NO_OPTS);
|
||||
|
||||
if (!jerry_value_is_error (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 (void)
|
||||
{
|
||||
jerry_debugger_wait_for_source_status_t receive_status;
|
||||
|
||||
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);
|
||||
jerryx_debugger_after_connect (jerryx_debugger_tcp_create (5001)
|
||||
&& jerryx_debugger_ws_create ());
|
||||
|
||||
do
|
||||
{
|
||||
jerry_value_t run_result;
|
||||
|
||||
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
|
||||
|
||||
**Summary**
|
||||
|
||||
Sends the program's output to the debugger client.
|
||||
|
||||
**Prototype**
|
||||
|
||||
```c
|
||||
void
|
||||
jerry_debugger_send_output (const jerry_char_t *buffer, jerry_size_t string_size)
|
||||
```
|
||||
|
||||
**Example**
|
||||
|
||||
[doctest]: # (test="link")
|
||||
|
||||
```c
|
||||
#include "jerryscript.h"
|
||||
#include "jerryscript-ext/debugger.h"
|
||||
|
||||
int
|
||||
main (void)
|
||||
{
|
||||
jerry_init (JERRY_INIT_EMPTY);
|
||||
jerryx_debugger_after_connect (jerryx_debugger_tcp_create (5001)
|
||||
&& jerryx_debugger_ws_create ());
|
||||
|
||||
jerry_char_t my_output[] = "Hey, this should be sent too!";
|
||||
jerry_size_t my_output_size = sizeof (my_output);
|
||||
|
||||
jerry_debugger_send_output (my_output, my_output_size);
|
||||
|
||||
jerry_cleanup ();
|
||||
}
|
||||
```
|
||||
|
||||
### jerry_debugger_send_log
|
||||
|
||||
**Summary**
|
||||
|
||||
Sends the program's log to the debugger client.
|
||||
|
||||
**Prototype**
|
||||
|
||||
```c
|
||||
void
|
||||
jerry_debugger_send_log (jerry_log_level_t level, const jerry_char_t *buffer, jerry_size_t string_size)
|
||||
```
|
||||
|
||||
**Example**
|
||||
|
||||
[doctest]: # (test="link")
|
||||
|
||||
```c
|
||||
#include "jerryscript.h"
|
||||
#include "jerryscript-ext/debugger.h"
|
||||
|
||||
int
|
||||
main (void)
|
||||
{
|
||||
jerry_init (JERRY_INIT_EMPTY);
|
||||
jerryx_debugger_after_connect (jerryx_debugger_tcp_create (5001)
|
||||
&& jerryx_debugger_ws_create ());
|
||||
|
||||
jerry_char_t my_log[] = "Custom diagnostics";
|
||||
jerry_size_t my_log_size = sizeof (my_log);
|
||||
|
||||
jerry_debugger_send_log (JERRY_LOG_LEVEL_DEBUG, my_log, my_log_size);
|
||||
|
||||
jerry_cleanup ();
|
||||
}
|
||||
```
|
||||
@@ -0,0 +1,803 @@
|
||||
# JerryScript Coding Standards
|
||||
|
||||
This text is a brief overview of JerryScript Coding Standards.
|
||||
Each rule starts with a short description followed by several
|
||||
examples. We believe examples are better than long explanations.
|
||||
Please follow these guidelines when you submit a patch for
|
||||
review.
|
||||
|
||||
## General rules
|
||||
|
||||
* Indentation is two spaces.
|
||||
* Tab characters are not allowed.
|
||||
* Maximum line length is 120 characters (excluding newline).
|
||||
* No trailing white space is allowed.
|
||||
* Run `tools/run-tests.py --check-vera` to check several
|
||||
of the coding conventions automatically.
|
||||
|
||||
## Comments
|
||||
|
||||
Only block comments (`/* */`) are allowed in JerryScript.
|
||||
Comments should be complete sentences (e.g. start with an
|
||||
upper case letter), except for return value, field and
|
||||
argument descriptions (see the exceptions below). The
|
||||
text part of a comment should focus on explaining *why*
|
||||
the code is doing something rather than *what* the code
|
||||
is doing.
|
||||
|
||||
```diff
|
||||
+++ Good +++
|
||||
```
|
||||
|
||||
```c
|
||||
/* A perfect comment. */
|
||||
|
||||
/* A perfect multiline
|
||||
* comment. Each line should
|
||||
* start with an asterisk. */
|
||||
```
|
||||
|
||||
```diff
|
||||
--- Bad ---
|
||||
```
|
||||
|
||||
```c
|
||||
// Double slash comments are not allowed.
|
||||
|
||||
/* not a complete sentence */
|
||||
|
||||
/* A bad mulitiline
|
||||
comment. */
|
||||
```
|
||||
|
||||
All types, constants and functions require a description in
|
||||
JerryScript. These comments should start with `/**`. The starting
|
||||
`/**` and ending `*/` must be on separate lines.
|
||||
|
||||
```diff
|
||||
+++ Good +++
|
||||
```
|
||||
|
||||
```c
|
||||
/**
|
||||
* A correct description.
|
||||
*/
|
||||
```
|
||||
|
||||
```diff
|
||||
--- Bad ---
|
||||
```
|
||||
|
||||
```c
|
||||
/** An incorrect description. */
|
||||
```
|
||||
|
||||
## Preprocessor defines
|
||||
|
||||
The name of a preprocessor macro must be an uppercase string
|
||||
and these macros must be preceded by a description.
|
||||
Abbreviations are allowed but not preferred in new code.
|
||||
|
||||
```diff
|
||||
+++ Good +++
|
||||
```
|
||||
|
||||
```c
|
||||
/**
|
||||
* Short description about the constant.
|
||||
*/
|
||||
#define JERRY_VALUE_SEVEN 7
|
||||
|
||||
/**
|
||||
* Short description about the macro function.
|
||||
*/
|
||||
#define JERRY_ADD_TWO_NUMBERS(arg1, arg2) \
|
||||
((arg1) + (arg2))
|
||||
|
||||
/**
|
||||
* Although this is correct, a reviewer might request
|
||||
* to change NUMS to NUMBERS. Hence it is recommended
|
||||
* to use NUMBERS in the first place.
|
||||
*/
|
||||
#define JERRY_ADD_TWO_NUMS(arg1, arg2) \
|
||||
((arg1) + (arg2))
|
||||
```
|
||||
|
||||
```diff
|
||||
--- Bad ---
|
||||
```
|
||||
|
||||
```c
|
||||
#define JERRY_CONSTANT_WITHOUT_DESCRIPTION 5
|
||||
|
||||
#define JeRrY_mIxEd_CaSe_NaMe "str"
|
||||
```
|
||||
|
||||
## Conditional preprocessor directives
|
||||
|
||||
A comment is required after `#else` and `#endif` in JerryScript.
|
||||
The defined keyword should be omitted from these comments.
|
||||
|
||||
```diff
|
||||
+++ Good +++
|
||||
```
|
||||
|
||||
```c
|
||||
#ifdef JERRY_A
|
||||
|
||||
#else /* !JERRY_A */
|
||||
|
||||
#endif /* JERRY_A */
|
||||
|
||||
#ifdef JERRY_A
|
||||
#if defined JERRY_B && defined JERRY_C && (JERRY_C > 6)
|
||||
|
||||
#else /* !(JERRY_B && JERRY_C && (JERRY_C > 6)) */
|
||||
|
||||
#endif /* JERRY_B && JERRY_C && (JERRY_C > 6) */
|
||||
#endif /* JERRY_A */
|
||||
```
|
||||
|
||||
```diff
|
||||
--- Bad ---
|
||||
```
|
||||
|
||||
```c
|
||||
#ifdef JERRY_A
|
||||
|
||||
#endif
|
||||
|
||||
#ifdef JERRY_A
|
||||
|
||||
#endif /* defined JERRY_A */
|
||||
|
||||
#ifdef JERRY_B
|
||||
/* Missing comment after else. */
|
||||
#else
|
||||
|
||||
#endif /* JERRY_B */
|
||||
```
|
||||
|
||||
## Code blocks
|
||||
|
||||
Each code block must be enclosed in curly braces even
|
||||
if it is a single line statement. These braces must
|
||||
be on separate lines. There must be a single space
|
||||
before the opening parenthesis of the expression
|
||||
after if/while/switch keywords.
|
||||
|
||||
```diff
|
||||
+++ Good +++
|
||||
```
|
||||
|
||||
```c
|
||||
if (value > 6)
|
||||
{
|
||||
function_call ();
|
||||
}
|
||||
|
||||
if (value > 1)
|
||||
{
|
||||
function_call_a ();
|
||||
}
|
||||
else
|
||||
{
|
||||
function_call_b ();
|
||||
}
|
||||
|
||||
do
|
||||
{
|
||||
function_call ();
|
||||
value++;
|
||||
}
|
||||
while (value < 6);
|
||||
|
||||
switch (value)
|
||||
{
|
||||
case A:
|
||||
{
|
||||
/* FALLTHRU comment is allowed if a
|
||||
* switch-case is not terminated by
|
||||
* break/continue/return. */
|
||||
|
||||
/* FALLTHRU */
|
||||
}
|
||||
case B:
|
||||
case C:
|
||||
{
|
||||
break;
|
||||
}
|
||||
case D:
|
||||
{
|
||||
/* We can use continue if we are in a loop. */
|
||||
continue;
|
||||
}
|
||||
default:
|
||||
{
|
||||
return;
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
```diff
|
||||
--- Bad ---
|
||||
```
|
||||
|
||||
```c
|
||||
if (value > 6)
|
||||
function_call_a ();
|
||||
else
|
||||
function_call_b ();
|
||||
|
||||
if (value > 6) {
|
||||
function_call_a ();
|
||||
}
|
||||
|
||||
if (value > 6) function_call_a ();
|
||||
else { function_call_b (); }
|
||||
|
||||
if
|
||||
(value > 6)
|
||||
{
|
||||
}
|
||||
|
||||
switch (value) {
|
||||
case 0: break;
|
||||
default: {
|
||||
return 5;
|
||||
}
|
||||
}
|
||||
|
||||
switch (value)
|
||||
{
|
||||
case A:
|
||||
{
|
||||
if (value > 6)
|
||||
{
|
||||
CASE B:
|
||||
{
|
||||
/* This is allowed in C but
|
||||
* not in JerryScript. */
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
do
|
||||
value++;
|
||||
while (value < 5);
|
||||
|
||||
do {
|
||||
value++;
|
||||
} while (value < 5);
|
||||
|
||||
do
|
||||
{
|
||||
value++;
|
||||
} while (value < 5);
|
||||
```
|
||||
|
||||
## Newlines
|
||||
|
||||
A newline in JerryScript is a separator which separates different
|
||||
parts of the source code. Its primary purpose is to improve
|
||||
readability. Unlike other rules developers have some freedom
|
||||
to add newlines to their code. However there are some rules.
|
||||
|
||||
* Only a single newline separator is allowed.
|
||||
* Source files must be terminated by a newline.
|
||||
* Global declarations must be separated by a newline.
|
||||
* Newlines are not allowed after an opening curly brace or before
|
||||
a closing curly brace
|
||||
* No newlines are allowed between control statements (if-else, while,
|
||||
for, switch, etc.) and their code blocks.
|
||||
* There should be a newline after the variable declarations
|
||||
if they are the first statements of a block.
|
||||
|
||||
```diff
|
||||
+++ Good +++
|
||||
```
|
||||
|
||||
```c
|
||||
if (a > 5)
|
||||
{
|
||||
/* Newline must be present after the first
|
||||
* variable declarations of a code block. */
|
||||
int j = a - 1;
|
||||
int k = a * 2;
|
||||
|
||||
return j + k;
|
||||
}
|
||||
|
||||
while (a < 5)
|
||||
{
|
||||
a++;
|
||||
|
||||
/* It is recommended to put a newline after
|
||||
* intermediate variable declarations. */
|
||||
int i = a * 2;
|
||||
|
||||
b = i - 3;
|
||||
}
|
||||
|
||||
/* It is a recommended to put newlines around asserts. */
|
||||
a = b + 5;
|
||||
|
||||
JERRY_ASSERT (a < 20);
|
||||
|
||||
c = a + 7;
|
||||
|
||||
/* It is a good practice to put a newline after a multiline
|
||||
* function call (see Function calls later). */
|
||||
f (a,
|
||||
b,
|
||||
c);
|
||||
|
||||
a = 6;
|
||||
```
|
||||
|
||||
```diff
|
||||
--- Bad ---
|
||||
```
|
||||
|
||||
```c
|
||||
/* No newlines are allowed after an opening curly
|
||||
* brace or before a closing curly brace */
|
||||
|
||||
while (a > 0)
|
||||
{
|
||||
|
||||
a = 6;
|
||||
|
||||
}
|
||||
|
||||
if (a > 5)
|
||||
{
|
||||
while (b < 6)
|
||||
{
|
||||
|
||||
b++;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
/* Two or more newlines are not allowed. */
|
||||
a = 6;
|
||||
|
||||
|
||||
b = 7;
|
||||
|
||||
/* No newlines are allowed between control staments
|
||||
* and their code blocks. */
|
||||
|
||||
if (a > 6)
|
||||
|
||||
{
|
||||
}
|
||||
|
||||
else
|
||||
|
||||
{
|
||||
}
|
||||
|
||||
do
|
||||
|
||||
{
|
||||
}
|
||||
|
||||
while (a < 6);
|
||||
```
|
||||
|
||||
## Expressions
|
||||
|
||||
Spaces are required around binary operators. No space is
|
||||
needed otherwise.
|
||||
|
||||
```diff
|
||||
+++ Good +++
|
||||
```
|
||||
|
||||
```c
|
||||
a = b + c;
|
||||
a = (b + c) << 3;
|
||||
a = b = c + ~d;
|
||||
a += ++c + d++;
|
||||
call_function (a * (b + !!c) - d + (e % f));
|
||||
if (a)
|
||||
{
|
||||
}
|
||||
```
|
||||
|
||||
```diff
|
||||
--- Bad ---
|
||||
```
|
||||
|
||||
```c
|
||||
a=b+c;
|
||||
a = b+c;
|
||||
a += c + ( d );
|
||||
/* Introduce temporary variables or macros
|
||||
* if the expression is too long. Occures rarely.. */
|
||||
a = b
|
||||
+ c;
|
||||
if ( a + b > 0 )
|
||||
{
|
||||
}
|
||||
```
|
||||
|
||||
## Logical operators
|
||||
|
||||
All expressions with && and || logical operators must be
|
||||
enclosed in parentheses. A single and multiline form is
|
||||
allowed for these expressions. In the latter case each
|
||||
line must start with the logical operator and each line
|
||||
must be aligned to the column right after the opening
|
||||
parenthesis.
|
||||
|
||||
```diff
|
||||
+++ Good +++
|
||||
```
|
||||
|
||||
```c
|
||||
/* Single line form. */
|
||||
a = ((c && d) || (e && f));
|
||||
|
||||
a = (c
|
||||
&& d);
|
||||
|
||||
a = (c
|
||||
&& (d || e)
|
||||
&& f);
|
||||
|
||||
do
|
||||
{
|
||||
}
|
||||
while (a
|
||||
&& b);
|
||||
|
||||
/* This form is rarely used but it is ok. */
|
||||
if (a
|
||||
&& (b
|
||||
|| c
|
||||
|| d)
|
||||
&& e)
|
||||
{
|
||||
}
|
||||
```
|
||||
|
||||
```diff
|
||||
--- Bad ---
|
||||
```
|
||||
|
||||
```c
|
||||
if (a || b ||
|
||||
c)
|
||||
{
|
||||
}
|
||||
|
||||
/* Parentheses are missing. */
|
||||
a = b || c;
|
||||
|
||||
/* Misaligned &&. */
|
||||
if (a
|
||||
&& b)
|
||||
{
|
||||
}
|
||||
```
|
||||
|
||||
## Ternary conditional operators
|
||||
|
||||
A special form of ternary conditional operators are allowed
|
||||
in JerryScript where the ? and : operators are on separate
|
||||
lines in the same column.
|
||||
|
||||
```diff
|
||||
+++ Good +++
|
||||
```
|
||||
|
||||
```c
|
||||
a = (b ? c
|
||||
: d);
|
||||
|
||||
/* Single line form is accepted as well. */
|
||||
a = (b ? c : d);
|
||||
|
||||
/* This form is rarely used but it is ok. */
|
||||
if (a ? b
|
||||
: (c ? d
|
||||
: e))
|
||||
{
|
||||
}
|
||||
```
|
||||
|
||||
```diff
|
||||
--- Bad ---
|
||||
```
|
||||
|
||||
```c
|
||||
a = b ?
|
||||
c : d;
|
||||
|
||||
while (a ? b
|
||||
: c)
|
||||
{
|
||||
}
|
||||
|
||||
if (a
|
||||
? b
|
||||
: c)
|
||||
{
|
||||
}
|
||||
```
|
||||
|
||||
## Function calls
|
||||
|
||||
There must be a space after the function name. Each argument
|
||||
must be in the same or separated lines. In the former case
|
||||
there must be a space before the next argument and in the
|
||||
latter case all arguments must be aligned to the same column.
|
||||
|
||||
```diff
|
||||
+++ Good +++
|
||||
```
|
||||
|
||||
```c
|
||||
function_a ();
|
||||
function_b (a);
|
||||
function_c (a, b, c);
|
||||
|
||||
function_c (a,
|
||||
b,
|
||||
c);
|
||||
|
||||
function_c (a,
|
||||
b,
|
||||
function_c (a,
|
||||
b,
|
||||
c);
|
||||
```
|
||||
|
||||
```diff
|
||||
--- Bad ---
|
||||
```
|
||||
|
||||
```c
|
||||
/* No space before the opening parenthesis. */
|
||||
function_f();
|
||||
|
||||
function_f (
|
||||
);
|
||||
|
||||
function_g(a);
|
||||
|
||||
function_g
|
||||
(a
|
||||
);
|
||||
|
||||
/* Two arguments on the same line. */
|
||||
function_h (a, b,
|
||||
c);
|
||||
|
||||
function_h (a,
|
||||
b, c);
|
||||
|
||||
/* Misaligned arguments. */
|
||||
function_h (a,
|
||||
b,
|
||||
c);
|
||||
```
|
||||
|
||||
## Variable declarations
|
||||
|
||||
JerryScript is a pure C99 codebase so variable
|
||||
declarations can be anywhere in the code including
|
||||
inside for-loops. It is recommended to declare a
|
||||
variable before the first use.
|
||||
|
||||
```diff
|
||||
+++ Good +++
|
||||
```
|
||||
|
||||
```c
|
||||
for (int i = 0; i < 10; i++)
|
||||
{
|
||||
int j = i + 1;
|
||||
while (j < 10)
|
||||
{
|
||||
++j;
|
||||
}
|
||||
}
|
||||
|
||||
/* Multiline form of for loops. */
|
||||
for (int i = 0;
|
||||
i < 10;
|
||||
i++)
|
||||
{
|
||||
}
|
||||
```
|
||||
|
||||
## Type casting
|
||||
|
||||
There must be a space after the closing parenthesis
|
||||
of the type cast. Type casting has no multiline form
|
||||
in JerryScript.
|
||||
|
||||
```diff
|
||||
+++ Good +++
|
||||
```
|
||||
|
||||
```c
|
||||
int a = (int) double_variable;
|
||||
|
||||
int a = (int) (long) (float) double_variable;
|
||||
```
|
||||
|
||||
```diff
|
||||
--- Bad ---
|
||||
```
|
||||
|
||||
```c
|
||||
/* Wrong spaces. */
|
||||
int a = ( int )double_variable;
|
||||
|
||||
/* No multiline form. */
|
||||
int a = (int)
|
||||
double_variable;
|
||||
```
|
||||
|
||||
## Pointers and asterisk character
|
||||
|
||||
Each pointer in JerryScript must be a lowercase string
|
||||
which is ending with a `_p` suffix. Furthermore there
|
||||
must be a space before the asterisk character.
|
||||
|
||||
```diff
|
||||
+++ Good +++
|
||||
```
|
||||
|
||||
```c
|
||||
int *int_p;
|
||||
|
||||
/* No need to add multiple _p-s for multiple indirections.
|
||||
* It is recommended to avoid these constructs using typedef
|
||||
* declarations. A reviewer might request such a change. */
|
||||
int ***int_p;
|
||||
|
||||
/* This rule applies for type casting as well. */
|
||||
char = *(char *) type_p;
|
||||
```
|
||||
|
||||
```diff
|
||||
--- Bad ---
|
||||
```
|
||||
|
||||
```c
|
||||
/* No _p after the name. */
|
||||
int *ptr;
|
||||
|
||||
/* Wrong asterisk position. */
|
||||
int* ptr_p;
|
||||
|
||||
char_p = * (char*)type_p;
|
||||
```
|
||||
|
||||
## Types
|
||||
|
||||
Each type in JerryScript must be a lowercase string
|
||||
which ends with a `_t` suffix. Furthermore each type
|
||||
declaration must be preceded by a short description
|
||||
of the type and each field must have a short description
|
||||
as well.
|
||||
|
||||
```diff
|
||||
+++ Good +++
|
||||
```
|
||||
|
||||
```c
|
||||
/**
|
||||
* Short description of the following structure.
|
||||
*/
|
||||
typedef struct
|
||||
{
|
||||
/* Field descriptions do not start with capital letters
|
||||
* and there is no full stop at the end. */
|
||||
field1_t field1; /**< description of field 1 */
|
||||
field2_t field2; /**< description of field 2 */
|
||||
|
||||
field_n_t field_n; /**< description of field n */
|
||||
} structure_name_t;
|
||||
|
||||
/**
|
||||
* Another integer type.
|
||||
*/
|
||||
typedef int jerry_int;
|
||||
```
|
||||
|
||||
```diff
|
||||
--- Bad ---
|
||||
```
|
||||
|
||||
```c
|
||||
typedef struct
|
||||
{
|
||||
field_t field_without_description;
|
||||
} structure_without_description_t;
|
||||
|
||||
typedef struct { int a; } single_line_struct;
|
||||
|
||||
typedef
|
||||
union {
|
||||
}
|
||||
wrong_newlines_t;
|
||||
|
||||
/*
|
||||
* Bad comment format.
|
||||
*/
|
||||
typedef
|
||||
char wrong_newlines_again_t;
|
||||
```
|
||||
|
||||
### Type usage conventions
|
||||
|
||||
- Passing the number of arguments for a function call is always `uint32_t`
|
||||
- String size/length/position related operation should use `lit_utf8_size_t`
|
||||
- Extended objects internal fields must be `uint32_t`
|
||||
|
||||
## Function declarations
|
||||
|
||||
Function declarations in JerryScript are verbose but this format
|
||||
reduces the maintenance cost and allows faster understanding of
|
||||
the code.
|
||||
|
||||
```diff
|
||||
+++ Good +++
|
||||
```
|
||||
|
||||
```c
|
||||
/**
|
||||
* Short overview about the purpose of this function.
|
||||
*
|
||||
* A more detailed explanation if needed.
|
||||
*
|
||||
* Note:
|
||||
* Extra notes if needed.
|
||||
*
|
||||
* @return short description about the value
|
||||
* returned by the function
|
||||
*/
|
||||
return_value_type_t
|
||||
function_name (argument1, /**< description of argument1 */
|
||||
argument2, /**< description of argument2 */
|
||||
...
|
||||
argument_n, /**< description of argument n */
|
||||
{
|
||||
|
||||
/* Function body. */
|
||||
|
||||
} /* function_name */
|
||||
```
|
||||
|
||||
```diff
|
||||
--- Bad ---
|
||||
```
|
||||
|
||||
```c
|
||||
static int
|
||||
print (char *text) /**< description of text argument */
|
||||
{
|
||||
/* Missing comment before the function. */
|
||||
} /* print */
|
||||
|
||||
/**
|
||||
* Prints the text received by the function.
|
||||
*
|
||||
* @return number of characters printed by the function
|
||||
*/
|
||||
int print(char *text)
|
||||
{
|
||||
/* No description of text argument. */
|
||||
/* Missing comment at the end of the function. */
|
||||
}
|
||||
```
|
||||
@@ -0,0 +1,855 @@
|
||||
# jerryx_arg types
|
||||
|
||||
## jerryx_arg_t
|
||||
|
||||
**Summary**
|
||||
|
||||
The structure defining a single validation/transformation step.
|
||||
|
||||
*Note*: For commonly used validators, `arg.h` provides helpers to create the `jerryx_arg_t`s.
|
||||
For example, `jerryx_arg_number ()`, `jerryx_arg_boolean ()`, etc.
|
||||
|
||||
**Prototype**
|
||||
|
||||
```c
|
||||
typedef struct
|
||||
{
|
||||
/** the transform function */
|
||||
jerryx_arg_transform_func_t func;
|
||||
/** pointer to destination where func should store the result */
|
||||
void *dest;
|
||||
/** extra information, specific to func */
|
||||
uintptr_t extra_info;
|
||||
} jerryx_arg_t;
|
||||
```
|
||||
|
||||
**See also**
|
||||
|
||||
- [jerryx_arg_number](#jerryx_arg_number)
|
||||
- [jerryx_arg_boolean](#jerryx_arg_boolean)
|
||||
- [jerryx_arg_string](#jerryx_arg_string)
|
||||
- [jerryx_arg_utf8_string](#jerryx_arg_utf8_string)
|
||||
- [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_array_items_t
|
||||
|
||||
**Summary**
|
||||
|
||||
The structure is used in `jerryx_arg_array`. It provides the array items' corresponding
|
||||
JS-to-C mappings and count.
|
||||
|
||||
**Prototype**
|
||||
|
||||
```c
|
||||
typedef struct
|
||||
{
|
||||
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_array_items_t;
|
||||
```
|
||||
|
||||
**See also**
|
||||
|
||||
- [jerryx_arg_array](#jerryx_arg_array)
|
||||
|
||||
## jerryx_arg_transform_func_t
|
||||
|
||||
**Summary**
|
||||
|
||||
Signature of the transform function.
|
||||
|
||||
Users can create custom transformations by implementing a transform function
|
||||
and using `jerryx_arg_custom ()`.
|
||||
|
||||
The function is expected to return `undefined` if it ran successfully or
|
||||
return an `Error` in case it failed. The function can use the iterator and the
|
||||
helpers `jerryx_arg_js_iterator_pop ()` and `jerryx_arg_js_iterator_peek ()` to
|
||||
get the next input value.
|
||||
|
||||
*Note*: A transform function is allowed to consume any number of input values!
|
||||
This enables complex validation like handling different JS function signatures,
|
||||
mapping multiple input arguments to a C struct, etc.
|
||||
|
||||
The function is expected to store the result of
|
||||
a successful transformation into `c_arg_p->dest`. In case the validation did
|
||||
not pass, the transform should not modify `c_arg_p->dest`.
|
||||
|
||||
Additional parameters can be provided to the function through `c_arg_p->extra_info`.
|
||||
|
||||
**Prototype**
|
||||
|
||||
```c
|
||||
typedef jerry_value_t (*jerryx_arg_transform_func_t) (jerryx_arg_js_iterator_t *js_arg_iter_p,
|
||||
const jerryx_arg_t *c_arg_p);
|
||||
```
|
||||
|
||||
**See also**
|
||||
|
||||
- [jerryx_arg_custom](#jerryx_arg_custom)
|
||||
- [jerryx_arg_js_iterator_pop](#jerryx_arg_js_iterator_pop)
|
||||
- [jerryx_arg_js_iterator_peek](#jerryx_arg_js_iterator_peek)
|
||||
|
||||
|
||||
## jerryx_arg_coerce_t
|
||||
|
||||
Enum that indicates whether an argument is allowed to be coerced into the expected JS type.
|
||||
|
||||
- JERRYX_ARG_COERCE - the transform will invoke toNumber, toBoolean, toString, etc.
|
||||
- JERRYX_ARG_NO_COERCE - the type coercion is not allowed. The transform will fail if the type does not match the expectation.
|
||||
|
||||
**See also**
|
||||
|
||||
- [jerryx_arg_number](#jerryx_arg_number)
|
||||
- [jerryx_arg_boolean](#jerryx_arg_boolean)
|
||||
- [jerryx_arg_string](#jerryx_arg_string)
|
||||
|
||||
## jerryx_arg_optional_t
|
||||
|
||||
Enum that indicates whether an argument is optional or required.
|
||||
|
||||
- JERRYX_ARG_OPTIONAL - The argument is optional. If the argument is `undefined` the transform is successful and `c_arg_p->dest` remains untouched.
|
||||
- JERRYX_ARG_REQUIRED - The argument is required. If the argument is `undefined` the transform will fail and `c_arg_p->dest` remains untouched.
|
||||
|
||||
**See also**
|
||||
|
||||
- [jerryx_arg_number](#jerryx_arg_number)
|
||||
- [jerryx_arg_boolean](#jerryx_arg_boolean)
|
||||
- [jerryx_arg_string](#jerryx_arg_string)
|
||||
- [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
|
||||
|
||||
**Summary**
|
||||
|
||||
Validate the this value and the JS arguments, and assign them to the native arguments.
|
||||
This function is useful to perform input validation inside external function handlers (see `jerry_external_handler_t`).
|
||||
|
||||
**Prototype**
|
||||
|
||||
```c
|
||||
jerry_value_t
|
||||
jerryx_arg_transform_this_and_args (const jerry_value_t this_val,
|
||||
const jerry_value_t *js_arg_p,
|
||||
const jerry_length_t js_arg_cnt,
|
||||
const jerryx_arg_t *c_arg_p,
|
||||
jerry_length_t c_arg_cnt)
|
||||
```
|
||||
|
||||
- `this_val` - `this` value. Note this is processed as the first value, before the array of arguments.
|
||||
- `js_arg_p` - points to the array with JS arguments.
|
||||
- `js_arg_cnt` - the count of the `js_arg_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.
|
||||
|
||||
**Example**
|
||||
|
||||
[doctest]: # (test="compile")
|
||||
|
||||
```c
|
||||
#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. */
|
||||
const jerryx_arg_t mapping[] =
|
||||
{
|
||||
/* `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_number (&optional_num, JERRYX_ARG_NO_COERCE, JERRYX_ARG_OPTIONAL),
|
||||
};
|
||||
|
||||
/* Validate and transform. */
|
||||
const jerry_value_t rv = jerryx_arg_transform_this_and_args (this_val,
|
||||
args_p,
|
||||
args_count,
|
||||
mapping,
|
||||
4);
|
||||
|
||||
if (jerry_value_is_error (rv))
|
||||
{
|
||||
/* Handle error. */
|
||||
return rv;
|
||||
}
|
||||
|
||||
/*
|
||||
* Validated and transformed successfully!
|
||||
* required_bool, required_str and optional_num can now be used.
|
||||
*/
|
||||
|
||||
return jerry_create_undefined (); /* Or return something more meaningful. */
|
||||
}
|
||||
```
|
||||
|
||||
**See also**
|
||||
|
||||
- [jerryx_arg_ignore](#jerryx_arg_ignore)
|
||||
- [jerryx_arg_number](#jerryx_arg_number)
|
||||
- [jerryx_arg_boolean](#jerryx_arg_boolean)
|
||||
- [jerryx_arg_string](#jerryx_arg_string)
|
||||
- [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
|
||||
|
||||
**Summary**
|
||||
|
||||
Validate an array of `jerry_value_t` and assign them to the native arguments.
|
||||
|
||||
**Prototype**
|
||||
|
||||
```c
|
||||
jerry_value_t
|
||||
jerryx_arg_transform_args (const jerry_value_t *js_arg_p,
|
||||
const jerry_length_t js_arg_cnt,
|
||||
const jerryx_arg_t *c_arg_p,
|
||||
jerry_length_t c_arg_cnt)
|
||||
```
|
||||
|
||||
- `js_arg_p` - points to the array with JS arguments.
|
||||
- `js_arg_cnt` - the count of the `js_arg_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_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)
|
||||
|
||||
## jerryx_arg_transform_array
|
||||
|
||||
**Summary**
|
||||
|
||||
Validate the JS array and assign its items to the native arguments.
|
||||
|
||||
*Note*: This function transforms items of a single JS array into native C values.
|
||||
To transform multiple JS arguments in one pass, please use `jerryx_arg_array` together with
|
||||
`jerryx_arg_transform_this_and_args` or `jerryx_arg_transform_args`.
|
||||
|
||||
**Prototype**
|
||||
|
||||
```c
|
||||
jerry_value_t
|
||||
jerryx_arg_transform_array (const jerry_value_t array_val,
|
||||
const jerryx_arg_t *c_arg_p,
|
||||
jerry_length_t c_arg_cnt);
|
||||
|
||||
```
|
||||
|
||||
- `array_val` - the JS 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_array](#jerryx_arg_array)
|
||||
|
||||
|
||||
# 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**
|
||||
|
||||
Create a validation/transformation step (`jerryx_arg_t`) that expects to consume
|
||||
one `number` JS argument and stores it into a C `double`.
|
||||
|
||||
**Prototype**
|
||||
|
||||
```c
|
||||
static inline jerryx_arg_t
|
||||
jerryx_arg_number (double *dest,
|
||||
jerryx_arg_coerce_t coerce_flag,
|
||||
jerryx_arg_optional_t opt_flag)
|
||||
```
|
||||
|
||||
- return value - the created `jerryx_arg_t` instance.
|
||||
- `dest` - pointer to the `double` where the result should be stored.
|
||||
- `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_boolean
|
||||
|
||||
**Summary**
|
||||
|
||||
Create a validation/transformation step (`jerryx_arg_t`) that expects to
|
||||
consume one `boolean` JS argument and stores it into a C `bool`.
|
||||
|
||||
**Prototype**
|
||||
|
||||
```c
|
||||
static inline jerryx_arg_t
|
||||
jerryx_arg_boolean (bool *dest,
|
||||
jerryx_arg_coerce_t coerce_flag,
|
||||
jerryx_arg_optional_t opt_flag)
|
||||
```
|
||||
- return value - the created `jerryx_arg_t` instance.
|
||||
- `dest` - pointer to the `bool` where the result should be stored.
|
||||
- `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_string
|
||||
|
||||
**Summary**
|
||||
|
||||
Create a validation/transformation step (`jerryx_arg_t`) that expects to
|
||||
consume one `string` JS argument and stores it into a CESU-8 C `char` array.
|
||||
|
||||
**Prototype**
|
||||
|
||||
```c
|
||||
static inline jerryx_arg_t
|
||||
jerryx_arg_string (char *dest,
|
||||
uint32_t size,
|
||||
jerryx_arg_coerce_t coerce_flag,
|
||||
jerryx_arg_optional_t opt_flag)
|
||||
```
|
||||
|
||||
- return value - the created `jerryx_arg_t` instance.
|
||||
- `dest` - pointer to the native char array where the result should be stored.
|
||||
- `size` - the size of native char array.
|
||||
- `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)
|
||||
- [jerry_arg_utf8_string](#jerry_arg_utf8_string)
|
||||
|
||||
|
||||
## jerryx_arg_utf8_string
|
||||
|
||||
**Summary**
|
||||
|
||||
Create a validation/transformation step (`jerryx_arg_t`) that expects to
|
||||
consume one `string` JS argument and stores it into a UTF-8 C `char` array.
|
||||
|
||||
**Prototype**
|
||||
|
||||
```c
|
||||
static inline jerryx_arg_t
|
||||
jerryx_arg_utf8_string (char *dest,
|
||||
uint32_t size,
|
||||
jerryx_arg_coerce_t coerce_flag,
|
||||
jerryx_arg_optional_t opt_flag)
|
||||
```
|
||||
|
||||
- return value - the created `jerryx_arg_t` instance.
|
||||
- `dest` - pointer to the native char array where the result should be stored.
|
||||
- `size` - the size of native char array.
|
||||
- `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)
|
||||
- [jerry_arg_string](#jerry_arg_string)
|
||||
|
||||
|
||||
## jerryx_arg_function
|
||||
|
||||
**Summary**
|
||||
|
||||
Create a validation/transformation step (`jerryx_arg_t`) that expects to
|
||||
consume one `function` JS argument and stores it into a C `jerry_value_t`.
|
||||
|
||||
**Prototype**
|
||||
|
||||
```c
|
||||
static inline jerryx_arg_t
|
||||
jerryx_arg_function (jerry_value_t *dest,
|
||||
jerryx_arg_optional_t opt_flag)
|
||||
|
||||
```
|
||||
- return value - the created `jerryx_arg_t` instance.
|
||||
- `dest` - pointer to the `jerry_value_t` where the result should be stored.
|
||||
- `opt_flag` - whether the argument is optional.
|
||||
|
||||
**See also**
|
||||
|
||||
- [jerryx_arg_transform_this_and_args](#jerryx_arg_transform_this_and_args)
|
||||
|
||||
## jerryx_arg_native_pointer
|
||||
|
||||
**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
|
||||
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`.
|
||||
|
||||
**Prototype**
|
||||
|
||||
```c
|
||||
static inline jerryx_arg_t
|
||||
jerryx_arg_native_pointer (void **dest,
|
||||
const jerry_object_native_info_t *info_p,
|
||||
jerryx_arg_optional_t opt_flag)
|
||||
```
|
||||
- return value - the created `jerryx_arg_t` instance.
|
||||
- `dest` - pointer to where the resulting native pointer should be stored.
|
||||
- `info_p` - expected the type info.
|
||||
- `opt_flag` - whether the argument is optional.
|
||||
|
||||
**See also**
|
||||
|
||||
- [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_is_error (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)
|
||||
|
||||
## jerryx_arg_array
|
||||
|
||||
**Summary**
|
||||
|
||||
Create a validation/transformation step (`jerryx_arg_t`) that expects to
|
||||
consume one `array` JS argument and call `jerryx_arg_transform_array_items` inside
|
||||
to transform its items to native arguments.
|
||||
User should prepare the `jerryx_arg_array_items_t` instance, and pass it to this function.
|
||||
|
||||
**Prototype**
|
||||
|
||||
```c
|
||||
static inline jerryx_arg_t
|
||||
jerryx_arg_array (const jerryx_arg_array_items_t *array_items_p, jerryx_arg_optional_t opt_flag);
|
||||
```
|
||||
- return value - the created `jerryx_arg_t` instance.
|
||||
- `array_items_p` - provides items information for 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 array, which has 3 items:
|
||||
* first: boolean
|
||||
* second: number
|
||||
* third: 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
|
||||
|
||||
/* "item_mapping" defines the steps to transform array items to C variables. */
|
||||
const jerryx_arg_t item_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_array_items_t instance. */
|
||||
const jerryx_arg_array_items_t array_info =
|
||||
{
|
||||
.c_arg_p = item_mapping,
|
||||
.c_arg_cnt = 3
|
||||
};
|
||||
|
||||
/* It is the mapping used in the jerryx_arg_transform_args. */
|
||||
const jerryx_arg_t mapping[] =
|
||||
{
|
||||
jerryx_arg_array (&array_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_is_error (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
|
||||
|
||||
## jerryx_arg_custom
|
||||
|
||||
**Summary**
|
||||
|
||||
Create a jerryx_arg_t instance with custom transform.
|
||||
|
||||
**Prototype**
|
||||
|
||||
```c
|
||||
static inline jerryx_arg_t
|
||||
jerryx_arg_custom (void *dest,
|
||||
uintptr_t extra_info,
|
||||
jerryx_arg_transform_func_t func)
|
||||
|
||||
```
|
||||
- return value - the created `jerryx_arg_t` instance.
|
||||
- `dest` - pointer to the native argument where the result should be stored.
|
||||
- `extra_info` - the extra parameter data, specific to the transform function.
|
||||
- `func` - the custom transform function.
|
||||
|
||||
**See also**
|
||||
|
||||
- [jerryx_arg_transform_this_and_args](#jerryx_arg_transform_this_and_args)
|
||||
|
||||
|
||||
|
||||
## jerryx_arg_js_iterator_pop
|
||||
|
||||
**Summary**
|
||||
|
||||
Pop the current `jerry_value_t` argument from the iterator.
|
||||
It will change the `js_arg_idx` and `js_arg_p` value in the iterator.
|
||||
|
||||
**Prototype**
|
||||
|
||||
```c
|
||||
jerry_value_t
|
||||
jerryx_arg_js_iterator_pop (jerryx_arg_js_iterator_t *js_arg_iter_p)
|
||||
```
|
||||
- return value - the `jerry_value_t` argument that was popped.
|
||||
- `js_arg_iter_p` - the JS arg iterator from which to pop.
|
||||
|
||||
## jerryx_arg_js_iterator_peek
|
||||
|
||||
**Summary**
|
||||
|
||||
Get the current JS argument from the iterator, without moving the iterator forward.
|
||||
*Note:* Unlike `jerryx_arg_js_iterator_pop ()`, it will not change `js_arg_idx` and
|
||||
`js_arg_p` value in the iterator.
|
||||
|
||||
**Prototype**
|
||||
|
||||
```c
|
||||
jerry_value_t
|
||||
jerryx_arg_js_iterator_peek (jerryx_arg_js_iterator_t *js_arg_iter_p)
|
||||
```
|
||||
- return value - the current `jerry_value_t` argument.
|
||||
- `js_arg_iter_p` - the JS arg iterator from which to peek.
|
||||
|
||||
## jerryx_arg_js_iterator_restore
|
||||
|
||||
**Summary**
|
||||
|
||||
Restore the last item popped from the stack. This can be called as
|
||||
many times as there are arguments on the stack -- if called when the
|
||||
first element in the array is the current top of the stack, this
|
||||
function does nothing.
|
||||
|
||||
*Note:* This function relies on the underlying implementation of the
|
||||
arg stack as an array, as its function is to simply back up the "top
|
||||
of stack" pointer to point to the previous element of the array.
|
||||
|
||||
*Note:* Like `jerryx_arg_js_iterator_pop ()`, this function will
|
||||
change the `js_arg_idx` and `js_arg_p` values in the iterator.
|
||||
|
||||
**Prototype**
|
||||
|
||||
```c
|
||||
jerry_value_t
|
||||
jerryx_arg_js_iterator_restore (jerryx_arg_js_iterator_t *js_arg_iter_p)
|
||||
```
|
||||
- return value - the the new top of the stack.
|
||||
- `js_arg_iter_p` - the JS arg iterator to restore.
|
||||
|
||||
|
||||
## jerryx_arg_js_iterator_index
|
||||
|
||||
**Summary**
|
||||
|
||||
Get the index of the current JS argument from the iterator.
|
||||
|
||||
**Prototype**
|
||||
|
||||
```c
|
||||
jerry_length_t
|
||||
jerryx_arg_js_iterator_index (jerryx_arg_js_iterator_t *js_arg_iter_p)
|
||||
```
|
||||
- return value - the index of current JS argument.
|
||||
- `js_arg_iter_p` - the JS arg iterator from which to peek.
|
||||
@@ -0,0 +1,604 @@
|
||||
# Common methods to handle properties
|
||||
|
||||
The `jerryscript-ext/handler.h` header defines a set of convenience methods
|
||||
which makes the property access a bit straightforward.
|
||||
|
||||
## jerryx_set_property_str
|
||||
|
||||
**Summary**
|
||||
|
||||
Set a property on a target object with a given name.
|
||||
|
||||
*Note*:
|
||||
- The property name must be a zero terminated UTF-8 string.
|
||||
- There should be no '\0' (NULL) character in the name excluding the string terminator.
|
||||
- Returned value must be freed with [jerry_release_value](#jerry_release_value) when it
|
||||
is no longer needed.
|
||||
|
||||
|
||||
**Prototype**
|
||||
|
||||
```c
|
||||
jerry_value_t
|
||||
jerryx_set_property_str (const jerry_value_t target_object,
|
||||
const char *name,
|
||||
const jerry_value_t value);
|
||||
```
|
||||
|
||||
- `target_object` - the object where the property should be set
|
||||
- `name` - name of the property
|
||||
- `value` - property value to be set
|
||||
- return value
|
||||
- JS true value, if success
|
||||
- thrown error, if there was a problem setting the property
|
||||
|
||||
**Example**
|
||||
|
||||
[doctest]: # ()
|
||||
|
||||
```c
|
||||
#include "jerryscript.h"
|
||||
#include "jerryscript-ext/handler.h"
|
||||
|
||||
int
|
||||
main (int argc, char **argv)
|
||||
{
|
||||
jerry_init (JERRY_INIT_EMPTY);
|
||||
|
||||
jerry_value_t global = jerry_get_global_object ();
|
||||
|
||||
jerry_value_t value = jerry_create_number (3.3);
|
||||
jerry_value_t result = jerryx_set_property_str (global, "value", value);
|
||||
if (jerry_value_is_error (result))
|
||||
{
|
||||
/* The error type/reason can be extracted via the `jerry_get_value_from_error` method */
|
||||
printf ("Error during property configuration\r\n");
|
||||
}
|
||||
|
||||
jerry_release_value (result);
|
||||
jerry_release_value (value);
|
||||
jerry_release_value (global);
|
||||
jerry_cleanup();
|
||||
|
||||
return 0;
|
||||
}
|
||||
```
|
||||
|
||||
## jerryx_get_property_str
|
||||
|
||||
**Summary**
|
||||
|
||||
Get the value of a property from the specified object with the given name.
|
||||
|
||||
*Notes*:
|
||||
- The property name must be a zero terminated UTF-8 string.
|
||||
- There should be no '\0' (NULL) character in the name excluding the string terminator.
|
||||
- Returned value must be freed with [jerry_release_value](#jerry_release_value) when it
|
||||
is no longer needed.
|
||||
|
||||
|
||||
**Prototype**
|
||||
|
||||
```
|
||||
jerry_value_t
|
||||
jerryx_get_property_str (const jerry_value_t target_object,
|
||||
const char *name);
|
||||
```
|
||||
|
||||
- `target_object` - object on which the property name is accessed
|
||||
- `name` - property name as an UTF-8 `char*`
|
||||
- return value
|
||||
- value of property, if success
|
||||
- thrown error, if there was a problem accessing the property
|
||||
|
||||
**Example**
|
||||
|
||||
[doctest]: # ()
|
||||
|
||||
```c
|
||||
#include "jerryscript.h"
|
||||
#include "jerryscript-ext/handler.h"
|
||||
|
||||
int
|
||||
main (int argc, char **argv)
|
||||
{
|
||||
jerry_init (JERRY_INIT_EMPTY);
|
||||
|
||||
jerry_value_t global = jerry_get_global_object ();
|
||||
|
||||
jerry_value_t math_object = jerryx_get_property_str (global, "Math");
|
||||
|
||||
/* use math_object */
|
||||
|
||||
jerry_release_value (math_object);
|
||||
jerry_release_value (global);
|
||||
jerry_cleanup();
|
||||
|
||||
return 0;
|
||||
}
|
||||
```
|
||||
|
||||
## jerryx_has_property_str
|
||||
|
||||
**Summary**
|
||||
|
||||
Check if a property exists on an object.
|
||||
|
||||
*Notes*:
|
||||
- The operation performed is the same as what the `jerry_has_property` method.
|
||||
- The property name must be a zero terminated UTF-8 string.
|
||||
- There should be no '\0' (NULL) character in the name excluding the string terminator.
|
||||
|
||||
|
||||
**Prototype**
|
||||
|
||||
```
|
||||
bool
|
||||
jerryx_has_property_str (const jerry_value_t target_object,
|
||||
const char *name);
|
||||
```
|
||||
|
||||
- `target_object` - object on which the property name is accessed
|
||||
- `name` - property name as an UTF-8 `char*`
|
||||
- return value
|
||||
- true, if the given property name exsits on the object
|
||||
- false, if there is no such property name or there was an error accessing the property
|
||||
|
||||
**Example**
|
||||
|
||||
[doctest]: # ()
|
||||
|
||||
```c
|
||||
#include "jerryscript.h"
|
||||
#include "jerryscript-ext/handler.h"
|
||||
|
||||
int
|
||||
main (int argc, char **argv)
|
||||
{
|
||||
jerry_init (JERRY_INIT_EMPTY);
|
||||
|
||||
jerry_value_t global = jerry_get_global_object ();
|
||||
|
||||
bool have_math = jerryx_has_property_str (global, "Math");
|
||||
|
||||
jerry_release_value (global);
|
||||
jerry_cleanup();
|
||||
|
||||
return have_math ? 0 : 1;
|
||||
}
|
||||
```
|
||||
|
||||
# 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 initialied before specifying the `jerry_value_t` in the struct.
|
||||
|
||||
|
||||
**Prototype**
|
||||
|
||||
```c
|
||||
typedef struct {
|
||||
const char *name;
|
||||
jerry_value_t value;
|
||||
} jerryx_function_list_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 occured 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 "jerryscript.h"
|
||||
#include "jerryscript-ext/handler.h"
|
||||
|
||||
static jerry_value_t
|
||||
handler (const jerry_value_t function_obj,
|
||||
const jerry_value_t this_val,
|
||||
const jerry_value_t args_p[],
|
||||
const jerry_length_t args_cnt)
|
||||
{
|
||||
printf ("native handler called!\n");
|
||||
|
||||
return jerry_create_boolean (true);
|
||||
}
|
||||
|
||||
int
|
||||
main (int argc, char **argv)
|
||||
{
|
||||
jerry_init (JERRY_INIT_EMPTY);
|
||||
|
||||
jerryx_property_entry methods[] =
|
||||
{
|
||||
{ "demo", jerry_create_external_function (handler) },
|
||||
{ NULL, 0 },
|
||||
};
|
||||
|
||||
jerry_value_t global = jerry_get_global_object ();
|
||||
jerryx_register_result reg = jerryx_set_properties (global, methods);
|
||||
/* if `reg.result` is undefined all methods are registered */
|
||||
if (jerry_value_is_error (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_release_value (reg.result);
|
||||
}
|
||||
|
||||
jerry_release_value (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)` - creates an UTF-8 string entry. This string must be zero terminated.
|
||||
* `JERRYX_PROPERTY_STRING_SZ(NAME, STR, SIZE)` - creates an UTF-8 string entry using only `SIZE` bytes from the string.
|
||||
* `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 "jerryscript.h"
|
||||
#include "jerryscript-ext/handler.h"
|
||||
|
||||
static jerry_value_t
|
||||
handler (const jerry_value_t function_obj,
|
||||
const jerry_value_t this_val,
|
||||
const jerry_value_t args_p[],
|
||||
const jerry_length_t args_cnt)
|
||||
{
|
||||
printf ("native handler called!\n");
|
||||
|
||||
return jerry_create_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_get_global_object ();
|
||||
jerryx_register_result reg = jerryx_set_properties (global, methods);
|
||||
/* if `reg.result` is undefined all methods are registered */
|
||||
if (jerry_value_is_error (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_release_value (reg.result);
|
||||
}
|
||||
|
||||
jerry_release_value (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 `ęntries` 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);
|
||||
```
|
||||
|
||||
- `entires` - 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_fatal
|
||||
|
||||
**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_fatal (const jerry_value_t func_obj_val, const jerry_value_t this_p,
|
||||
const jerry_value_t args_p[], const jerry_length_t args_cnt);
|
||||
```
|
||||
|
||||
- `func_obj_val` - the function object that was called (unused).
|
||||
- `this_p` - the `this` value of the call (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_handler_register_global](#jerryx_handler_register_global)
|
||||
|
||||
|
||||
## jerryx_handler_assert_throw
|
||||
|
||||
**Summary**
|
||||
|
||||
Soft assert for scripts. The routine throws an error on assertion failure.
|
||||
|
||||
**Prototype**
|
||||
|
||||
```c
|
||||
jerry_value_t
|
||||
jerryx_handler_assert_throw (const jerry_value_t func_obj_val, const jerry_value_t this_p,
|
||||
const jerry_value_t args_p[], const jerry_length_t args_cnt);
|
||||
```
|
||||
|
||||
- `func_obj_val` - the function object that was called (unused).
|
||||
- `this_p` - the `this` value of the call (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, an error otherwise.
|
||||
|
||||
**See also**
|
||||
|
||||
- [jerryx_handler_register_global](#jerryx_handler_register_global)
|
||||
|
||||
|
||||
## jerryx_handler_assert
|
||||
|
||||
**Summary**
|
||||
|
||||
An alias to `jerryx_handler_assert_fatal`.
|
||||
|
||||
**See also**
|
||||
|
||||
- [jerryx_handler_assert_fatal](#jerryx_handler_assert_fatal)
|
||||
|
||||
|
||||
## 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_value_t func_obj_val, const jerry_value_t this_p,
|
||||
const jerry_value_t args_p[], const jerry_length_t args_cnt);
|
||||
```
|
||||
|
||||
- `func_obj_val` - the function object that was called (unused).
|
||||
- `this_p` - the `this` value of the call (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_handler_register_global](#jerryx_handler_register_global)
|
||||
|
||||
|
||||
## jerryx_handler_print
|
||||
|
||||
**Summary**
|
||||
|
||||
Provide a `print` implementation for scripts. The routine converts all of its
|
||||
arguments to strings and outputs them char-by-char using
|
||||
`jerry_port_print_char`. The NUL 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_char`.
|
||||
|
||||
**Prototype**
|
||||
|
||||
```c
|
||||
jerry_value_t
|
||||
jerryx_handler_print (const jerry_value_t func_obj_val, const jerry_value_t this_p,
|
||||
const jerry_value_t args_p[], const jerry_length_t args_cnt);
|
||||
```
|
||||
|
||||
- `func_obj_val` - the function object that was called (unused).
|
||||
- `this_p` - the `this` value of the call (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_handler_register_global](#jerryx_handler_register_global)
|
||||
- [jerry_port_print_char](05.PORT-API.md#jerry_port_print_char)
|
||||
|
||||
|
||||
# Handler registration helper
|
||||
|
||||
## jerryx_handler_register_global
|
||||
|
||||
**Summary**
|
||||
|
||||
Register a JavaScript function in the global object.
|
||||
|
||||
*Note*: Returned value must be freed with `jerry_release_value`, when it is no
|
||||
longer needed.
|
||||
|
||||
**Prototype**
|
||||
|
||||
```c
|
||||
jerry_value_t
|
||||
jerryx_handler_register_global (const jerry_char_t *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/handler.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_create_undefined ();
|
||||
|
||||
for (int i = 0; common_functions[i].name_p != NULL && !jerry_value_is_error (ret); i++)
|
||||
{
|
||||
ret = jerryx_handler_register_global ((const jerry_char_t *) common_functions[i].name_p,
|
||||
common_functions[i].handler_p);
|
||||
}
|
||||
|
||||
jerry_release_value (ret);
|
||||
}
|
||||
```
|
||||
@@ -0,0 +1,50 @@
|
||||
# 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", name="11.EXT-REFERENCE-AUTORELEASE.c")
|
||||
|
||||
```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](../docs/02.API-REFERENCE.md#jerry_value_t)
|
||||
- [jerry_acquire_value](../docs/02.API-REFERENCE.md#jerry_acquire_value)
|
||||
- [jerry_release_value](../docs/02.API-REFERENCE.md#jerry_release_value)
|
||||
@@ -0,0 +1,314 @@
|
||||
# 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" - 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.
|
||||
|
||||
Individual modules may be removed from the cache by calling `jerryx_module_clear_cache`. This function behaves
|
||||
identically to `jerryx_module_resolve` in that it first checks the cache for the requested module, except that it
|
||||
removes the module if found. Additionally, it clears the entire cache of all modules if called using a JavaScript value
|
||||
of `undefined` as its first parameter.
|
||||
|
||||
Additionally, this extension provides a means of easily defining so-called "native" JerryScript modules which can be
|
||||
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. Note: `FEATURE_INIT_FINI` build flag isn't supported on Windows, because Microsoft Visual C/C++ Compiler
|
||||
doesn't support library constructors and destructors.
|
||||
|
||||
## 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.
|
||||
|
||||
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**
|
||||
|
||||
```c
|
||||
jerry_value_t
|
||||
jerryx_module_resolve (const jerry_value_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_clear_cache
|
||||
|
||||
**Summary**
|
||||
|
||||
Remove a module from the current context's cache, or clear the cache entirely.
|
||||
|
||||
**Prototype**
|
||||
|
||||
```c
|
||||
void
|
||||
jerryx_module_clear_cache (const jerry_value_t name,
|
||||
const jerryx_module_resolver_t *resolvers_p,
|
||||
size_t resolver_count);
|
||||
```
|
||||
|
||||
- `name` - the name of the module to remove from cache or a JavaScript `undefined` to clear the entire cache
|
||||
- `resolvers_p` - the list of resolvers to call in sequence
|
||||
- `resolver_count` - the number of resolvers in `resolvers_p`
|
||||
|
||||
|
||||
## jerryx_module_native_resolver
|
||||
|
||||
**Summary**
|
||||
|
||||
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
|
||||
extern jerry_module_resolver_t jerryx_native_module_resolver;
|
||||
```
|
||||
|
||||
# Module data types
|
||||
|
||||
## jerryx_module_get_canonical_name_t
|
||||
|
||||
**Summary**
|
||||
|
||||
The function pointer type for converting a module's requested name to its canonical name.
|
||||
|
||||
**Prototype**
|
||||
|
||||
```c
|
||||
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**
|
||||
|
||||
Structure defining a module resolver.
|
||||
|
||||
**Prototype**
|
||||
|
||||
```c
|
||||
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
|
||||
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;
|
||||
|
||||
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)
|
||||
{
|
||||
/* 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, JERRY_PARSE_NO_OPTS);
|
||||
|
||||
/* 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;
|
||||
}
|
||||
|
||||
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[] =
|
||||
{
|
||||
/*
|
||||
* 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 native JerryScript module, assume it is a JavaScript file on disk and use the
|
||||
* above-defined JavaScript file loader to load it.
|
||||
*/
|
||||
&js_file_loader
|
||||
};
|
||||
jerry_value_t js_module = jerryx_module_resolve (requested_module, resolvers, 2);
|
||||
```
|
||||
|
||||
# Module helper macros
|
||||
|
||||
## JERRYX_NATIVE_MODULE
|
||||
|
||||
**Summary**
|
||||
|
||||
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.
|
||||
|
||||
**Prototype**
|
||||
```c
|
||||
#define JERRYX_NATIVE_MODULE(module_name, on_resolve_cb)
|
||||
```
|
||||
|
||||
- `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.
|
||||
|
||||
**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)
|
||||
```
|
||||
|
||||
**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;
|
||||
}
|
||||
```
|
||||
@@ -0,0 +1,217 @@
|
||||
# JerryScript debugger transport interface
|
||||
|
||||
The transport interface support allows dynamic selection of transportation
|
||||
layers which can encode/decode or send/receive messages transmitted between
|
||||
the debugger client and server.
|
||||
|
||||
# Types
|
||||
|
||||
## jerry_debugger_transport_receive_context_t
|
||||
|
||||
**Summary**
|
||||
|
||||
This context represents the current status of processing received data.
|
||||
The final state is returned by
|
||||
[jerry_debugger_transport_receive](#jerry_debugger_transport_receive)
|
||||
and must be passed to
|
||||
[jerry_debugger_transport_receive_completed](#jerry_debugger_transport_receive_completed)
|
||||
after the message is processed.
|
||||
|
||||
**Prototype**
|
||||
|
||||
```c
|
||||
typedef struct
|
||||
{
|
||||
uint8_t *buffer_p; /**< buffer for storing the received data */
|
||||
size_t received_length; /**< number of currently received bytes */
|
||||
uint8_t *message_p; /**< start of the received message */
|
||||
size_t message_length; /**< length of the received message */
|
||||
size_t message_total_length; /**< total length for datagram protocols,
|
||||
* 0 for stream protocols */
|
||||
} jerry_debugger_transport_receive_context_t;
|
||||
```
|
||||
|
||||
## jerry_debugger_transport_header_t
|
||||
|
||||
**Summary**
|
||||
|
||||
Shared header for each transport interface. It mostly contains callback functions
|
||||
used by the JerryScript debugger server.
|
||||
|
||||
**Prototype**
|
||||
|
||||
```c
|
||||
typedef struct jerry_debugger_transport_layer_t
|
||||
{
|
||||
/* The following fields must be filled before calling jerry_debugger_transport_add(). */
|
||||
jerry_debugger_transport_close_t close; /**< close connection callback */
|
||||
jerry_debugger_transport_send_t send; /**< send data callback */
|
||||
jerry_debugger_transport_receive_t receive; /**< receive data callback */
|
||||
|
||||
/* The following fields are filled by jerry_debugger_transport_add(). */
|
||||
struct jerry_debugger_transport_layer_t *next_p; /**< next transport layer */
|
||||
} jerry_debugger_transport_header_t;
|
||||
```
|
||||
|
||||
## jerry_debugger_transport_close_t
|
||||
|
||||
**Summary**
|
||||
|
||||
Called when the connection is closed. Must release all resources (including the
|
||||
memory area for the transport interface) allocated for the transport interface.
|
||||
|
||||
**Prototype**
|
||||
|
||||
```c
|
||||
typedef void (*jerry_debugger_transport_close_t) (struct jerry_debugger_transport_interface_t *header_p);
|
||||
```
|
||||
|
||||
## jerry_debugger_transport_send_t
|
||||
|
||||
**Summary**
|
||||
|
||||
Called when a message needs to be sent. Must either transmit the message or call
|
||||
the `header_p->next_p->send()` method.
|
||||
|
||||
**Prototype**
|
||||
|
||||
```c
|
||||
typedef bool (*jerry_debugger_transport_send_t) (struct jerry_debugger_transport_interface_t *header_p,
|
||||
uint8_t *message_p, size_t message_length);
|
||||
```
|
||||
|
||||
## jerry_debugger_transport_receive_t
|
||||
|
||||
**Summary**
|
||||
|
||||
Called during message processing. If messages are available it must return with
|
||||
the next message.
|
||||
|
||||
**Prototype**
|
||||
|
||||
```c
|
||||
typedef bool (*jerry_debugger_transport_receive_t) (struct jerry_debugger_transport_interface_t *header_p,
|
||||
jerry_debugger_transport_receive_context_t *context_p);
|
||||
```
|
||||
|
||||
# Transport interface API functions
|
||||
|
||||
## jerry_debugger_transport_add
|
||||
|
||||
**Summary**
|
||||
|
||||
Add a new interface to the transporation interface chain. The interface
|
||||
will be the first item of the interface chain.
|
||||
|
||||
**Prototype**
|
||||
|
||||
```c
|
||||
void jerry_debugger_transport_add (jerry_debugger_transport_header_t *header_p,
|
||||
size_t send_message_header_size, size_t max_send_message_size,
|
||||
size_t receive_message_header_size, size_t max_receive_message_size);
|
||||
```
|
||||
|
||||
- `header_p`: header of a transporation interface.
|
||||
- `send_message_header_size`: size of the outgoing message header, can be 0.
|
||||
- `max_send_message_size`: maximum outgoing message size supported by the interface.
|
||||
- `receive_message_header_size`: size of the incoming message header, can be 0.
|
||||
- `max_receive_message_size`: maximum incoming message size supported by the interface.
|
||||
|
||||
## jerry_debugger_transport_start
|
||||
|
||||
**Summary**
|
||||
|
||||
Starts the communication to the debugger client. Must be called after the
|
||||
connection is successfully established.
|
||||
|
||||
**Prototype**
|
||||
|
||||
```c
|
||||
void jerry_debugger_transport_start (void);
|
||||
```
|
||||
|
||||
## jerry_debugger_transport_is_connected
|
||||
|
||||
**Summary**
|
||||
|
||||
Tells whether a debugger client is connected to the debugger server.
|
||||
|
||||
**Prototype**
|
||||
|
||||
```c
|
||||
bool jerry_debugger_transport_is_connected (void);
|
||||
```
|
||||
|
||||
- return value: `true`, if a client is connected, `false` otherwise.
|
||||
|
||||
## jerry_debugger_transport_close
|
||||
|
||||
**Summary**
|
||||
|
||||
Disconnect from the current debugger client. It does nothing if a client is
|
||||
not connected.
|
||||
|
||||
**Prototype**
|
||||
|
||||
```c
|
||||
void jerry_debugger_transport_close (void);
|
||||
```
|
||||
|
||||
## jerry_debugger_transport_send
|
||||
|
||||
**Summary**
|
||||
|
||||
Send message to the client.
|
||||
|
||||
**Prototype**
|
||||
|
||||
```c
|
||||
bool jerry_debugger_transport_send (const uint8_t *message_p, size_t message_length);
|
||||
```
|
||||
|
||||
- `message_p`: message to be sent.
|
||||
- `message_length`: message length in bytes.
|
||||
- return value: `true`, if a client is still connected, `false` otherwise.
|
||||
|
||||
## jerry_debugger_transport_receive
|
||||
|
||||
**Summary**
|
||||
|
||||
Receive message from the client.
|
||||
|
||||
**Prototype**
|
||||
|
||||
```c
|
||||
bool jerry_debugger_transport_receive (jerry_debugger_transport_receive_context_t *context_p);
|
||||
```
|
||||
|
||||
- `context_p`: an unused [jerry_debugger_transport_receive_context_t](#jerry_debugger_transport_receive_context_t).
|
||||
- return value: `true`, if a client is still connected, `false` otherwise.
|
||||
|
||||
## jerry_debugger_transport_receive_completed
|
||||
|
||||
**Summary**
|
||||
|
||||
Must be called after [jerry_debugger_transport_receive](#jerry_debugger_transport_receive)
|
||||
returns with a valid message. Must not be called otherwise.
|
||||
|
||||
**Prototype**
|
||||
|
||||
```c
|
||||
void jerry_debugger_transport_receive_completed (jerry_debugger_transport_receive_context_t *context_p);
|
||||
```
|
||||
|
||||
- `context_p`: a [jerry_debugger_transport_receive_context_t](#jerry_debugger_transport_receive_context_t)
|
||||
passed to [jerry_debugger_transport_receive](#jerry_debugger_transport_receive).
|
||||
|
||||
## jerry_debugger_transport_sleep
|
||||
|
||||
**Summary**
|
||||
|
||||
Can be used to wait for incoming messages. Currently the delay is 100ms.
|
||||
|
||||
**Prototype**
|
||||
|
||||
```c
|
||||
void jerry_debugger_transport_sleep (void);
|
||||
```
|
||||
@@ -0,0 +1,112 @@
|
||||
# Handle Scope
|
||||
|
||||
## jerryx_handle_scope
|
||||
|
||||
**Summary**
|
||||
It is often necessary to make the lifespan of handles shorter than the lifespan of a native method. Even though the native code could only use the most recent handle, all of the associated objects would also be kept alive since they all share the same scope.
|
||||
|
||||
To handle this case, JerryScript HandleScope extension provides the ability to establish a new 'scope' to which newly created handles will be associated. Once those handles are no longer required, the scope can be 'closed' and any handles associated with the scope are invalidated. The methods available to open/close scopes are `jerryx_open_handle_scope` and `jerryx_close_handle_scope`.
|
||||
|
||||
JerryScript only supports a single nested hierarchy of scopes. There is only one active scope at any time, and all new handles will be associated with that scope while it is active. Scopes must be closed in the reverse order from which they are opened. In addition, all scopes created within a native method must be closed before returning from that method.
|
||||
|
||||
**Example**
|
||||
|
||||
[doctest]: # (test="compile")
|
||||
|
||||
```c
|
||||
#include "jerryscript.h"
|
||||
#include "jerryscript-ext/handle-scope.h"
|
||||
|
||||
static jerry_value_t
|
||||
create_object (void)
|
||||
{
|
||||
jerry_value_t obj = jerry_create_object ();
|
||||
return obj;
|
||||
} /* create_object */
|
||||
|
||||
static void
|
||||
test_handle_scope_val (void)
|
||||
{
|
||||
jerryx_handle_scope scope;
|
||||
jerryx_open_handle_scope (&scope);
|
||||
jerry_value_t obj = jerryx_create_handle (create_object ());
|
||||
|
||||
jerryx_close_handle_scope (scope);
|
||||
// now obj has been released
|
||||
} /* test_handle_scope_val */
|
||||
|
||||
int
|
||||
main (void)
|
||||
{
|
||||
jerry_init (JERRY_INIT_EMPTY);
|
||||
|
||||
test_handle_scope_val ();
|
||||
jerry_gc (JERRY_GC_PRESSURE_LOW);
|
||||
|
||||
jerry_cleanup ();
|
||||
} /* main */
|
||||
```
|
||||
|
||||
## jerryx_escapable_handle_scope
|
||||
|
||||
**Summary**
|
||||
|
||||
It is necessary in common cases that a handle has to be promote to outer scope and prevent from been garbage collected. To handle this case, a escapable handle scope has been proposed from which one object can be promoted to the outer scope. The method available to escape an object from been release at current scope is `jerryx_escape_handle`.
|
||||
|
||||
**Example**
|
||||
|
||||
[doctest]: # (test="compile")
|
||||
|
||||
```c
|
||||
#include "jerryscript.h"
|
||||
#include "jerryscript-ext/handle-scope.h"
|
||||
|
||||
static jerry_value_t
|
||||
create_object (void)
|
||||
{
|
||||
jerryx_escapable_handle_scope scope;
|
||||
jerryx_open_escapable_handle_scope (&scope);
|
||||
jerry_value_t obj = jerryx_create_handle (jerry_create_object ());
|
||||
|
||||
jerry_value_t escaped_obj;
|
||||
jerryx_escape_handle(scope, obj, &escaped_obj);
|
||||
jerryx_close_handle_scope (scope);
|
||||
// escaped_obj has now been escaped to outer scope, thus not released at this point
|
||||
|
||||
return escaped_obj;
|
||||
} /* create_object */
|
||||
|
||||
static void
|
||||
test_handle_scope_val (void)
|
||||
{
|
||||
jerryx_handle_scope scope;
|
||||
jerryx_open_handle_scope (&scope);
|
||||
jerry_value_t obj = create_object ();
|
||||
|
||||
jerryx_close_handle_scope (scope);
|
||||
// now obj has been released
|
||||
} /* test_handle_scope_val */
|
||||
|
||||
int
|
||||
main (void)
|
||||
{
|
||||
jerry_init (JERRY_INIT_EMPTY);
|
||||
|
||||
test_handle_scope_val ();
|
||||
jerry_gc (JERRY_GC_PRESSURE_LOW);
|
||||
|
||||
jerry_cleanup ();
|
||||
} /* main */
|
||||
```
|
||||
|
||||
**See also**
|
||||
|
||||
- [jerry_value_t](../docs/02.API-REFERENCE.md#jerry_value_t)
|
||||
- [jerry_acquire_value](../docs/02.API-REFERENCE.md#jerry_acquire_value)
|
||||
- [jerry_release_value](../docs/02.API-REFERENCE.md#jerry_release_value)
|
||||
|
||||
## Pre-allocated list of handle scopes and handles
|
||||
|
||||
To prevent trapping into system calls frequently, a pre-allocated dedicated list mechanism has been introduced to the implementation of JerryX handle scope.
|
||||
|
||||
To change the size of pre-allocation list, use build definition `JERRYX_HANDLE_PRELIST_SIZE` and `JERRYX_SCOPE_PRELIST_SIZE` to alter the default value of 20.
|
||||
@@ -0,0 +1,159 @@
|
||||
# ES6 module support for JerryScript
|
||||
|
||||
The module system allows users to write import and export statements in scripts, which can be used to separate the logic of the application into custom modules.
|
||||
The standard's relevant part can be found [here](https://www.ecma-international.org/ecma-262/6.0/#sec-modules).
|
||||
Embedders wishing to use native builtin modules with ES6 imports can use the [Port API](05.PORT-API.md#jerry-module-system) to do so.
|
||||
|
||||
## General
|
||||
|
||||
If a script contains import statements, then JerryScript will open and evaluate the the referenced modules before the main script runs, resolving and creating bindings for the referenced identifiers in the process.
|
||||
It is not necessary to use any specific filename extensions for modules, JerryScript will try to open the given file paths as they are, but will try to normalize them before doing so. The exact normalization process is dependant on the port implementation provided. It is the user's responsibility to verify that the given files are valid EcmaScript modules.
|
||||
|
||||
main.js
|
||||
|
||||
```js
|
||||
import { exported_value } from "./module.js"
|
||||
|
||||
print (exported_value);
|
||||
```
|
||||
|
||||
module.js
|
||||
|
||||
```js
|
||||
var exported_value = 42;
|
||||
|
||||
export exported_value;
|
||||
```
|
||||
|
||||
## Supported features
|
||||
|
||||
* exporting identifiers from the module's lexical environment
|
||||
* specifying export names for the exported values
|
||||
* importing exported identifiers from a module
|
||||
* specifying local binding names for the imported values
|
||||
* module namespace imports
|
||||
* `import * as module from 'module.js`
|
||||
* indirect export statements
|
||||
* `export {variable} from 'module.js'`
|
||||
* star export statements
|
||||
* `export * from 'module.js'`
|
||||
* importing a module for side-effects
|
||||
* `import 'module.js'`
|
||||
* default import and export statements
|
||||
* `export default local_identifier`
|
||||
* `import def from 'module.js'`
|
||||
* anonymous default exports
|
||||
* `export default function () {}`
|
||||
|
||||
### Example
|
||||
|
||||
```js
|
||||
import {
|
||||
engine,
|
||||
version as v
|
||||
} from "./module.js"
|
||||
|
||||
import { getFeatureDetails } from "./module_2.js"
|
||||
|
||||
var version = "v3.1415";
|
||||
|
||||
print("> main.js");
|
||||
|
||||
print(">> Engine: " + engine);
|
||||
print(">> Version: " + v);
|
||||
|
||||
print (">> " + getFeatureDetails());
|
||||
print (">> Script version: " + version);
|
||||
```
|
||||
|
||||
```js
|
||||
// module.js
|
||||
var _engine = "JerryScript";
|
||||
export _engine as engine;
|
||||
|
||||
export var version = "1.0 (e92ae0fb)";
|
||||
```
|
||||
|
||||
```js
|
||||
// module_2.js
|
||||
var featureName = "EcmaScript modules";
|
||||
var year = 2018;
|
||||
|
||||
export function getFeatureDetails() {
|
||||
return "Feature name: " + featureName + " | developed in " + year;
|
||||
}
|
||||
```
|
||||
|
||||
### Module namespace import statements
|
||||
|
||||
A module namespace object can be imported. In this case the local binding will contain an object holding the exported values of the module, including local exports and all indirect exports. Ambiguous exported names are exluded from the namespace object.
|
||||
|
||||
```js
|
||||
import * as module from './module.js';
|
||||
|
||||
print(">> Engine: " + module.engine);
|
||||
print(">> Version: " + module.version);
|
||||
```
|
||||
|
||||
### Indirect export statements
|
||||
|
||||
An export statement can transitively export variables from another module, either via named indirect exports or a star export statement. In this case the resolving process will follow the chain until it reaches a module containing a local binding for that export name. If there are multiple modules which satisfy the export, that means the export is ambiguous, and will result in a SyntaxError.
|
||||
|
||||
```js
|
||||
import { a, b } from 'module.js'
|
||||
|
||||
print (a + b);
|
||||
```
|
||||
|
||||
```js
|
||||
// module.js
|
||||
export var a = 2;
|
||||
export { b } from 'module2.js'
|
||||
```
|
||||
|
||||
```js
|
||||
// module2.js
|
||||
export var b = 40;
|
||||
```
|
||||
|
||||
### Default imports and exports
|
||||
|
||||
Each module can optionally provide a single default export by using the `export default` statement. Default exports can either reference identifiers in the module's lexical environment, or be an anonymous default export, in which case they will only be accessible by an importing script.
|
||||
|
||||
```js
|
||||
import defaultExport, { b as c } from 'module.js'
|
||||
|
||||
print (defaultExport); // 2
|
||||
print (c ()); // 42
|
||||
```
|
||||
|
||||
```js
|
||||
// module.js
|
||||
export default 2;
|
||||
export function b () {
|
||||
return 42;
|
||||
}
|
||||
```
|
||||
|
||||
### Importing modules for side-effects
|
||||
|
||||
Evaluate a module without importing anything. Any errors encountered in the module will be propagated.
|
||||
|
||||
```js
|
||||
import 'module.js' // > module.js
|
||||
// "> module.js" is printed
|
||||
b (); // (ReferenceError) b is not defined
|
||||
```
|
||||
|
||||
```js
|
||||
// module.js
|
||||
export function b () {
|
||||
print ("> module.js");
|
||||
return 42;
|
||||
}
|
||||
b ();
|
||||
```
|
||||
|
||||
## Unsupported features
|
||||
|
||||
* **snapshot**
|
||||
@@ -0,0 +1,772 @@
|
||||
# Migration guide
|
||||
|
||||
This guide intends to describe the major changes between the JerryScript 1.0 and 2.0 versions.
|
||||
In addtion it is designed to provide a guide on how to modify the 1.0 version code to a
|
||||
2.0 compliant code.
|
||||
|
||||
During the development it was important to minimize the changes in the API functions and types.
|
||||
Each API method removal or chang is described below providing a ***before*** and ***after***
|
||||
code example.
|
||||
For more information on the current API methods please check the [API reference](02.API-REFERENCE.md) document.
|
||||
|
||||
# Short list of removed/renamed headers, types, functions, and macros
|
||||
|
||||
***Removed legacy headers***
|
||||
|
||||
- `jerry-internal.h`
|
||||
|
||||
***Renamed headers***
|
||||
|
||||
- `jerry-api.h` to `jerryscript.h`
|
||||
- `jerry-port.h` to `jerryscript-port.h`
|
||||
|
||||
***Removed API types***
|
||||
|
||||
- `jerry_char_ptr_t` usage replaced with `jerry_char_t *`
|
||||
- `jerry_object_free_callback_t` replaced by `jerry_object_native_free_callback_t`
|
||||
|
||||
***Removed API methods***
|
||||
|
||||
- `jerry_get_memory_limits`
|
||||
- `jerry_get_object_native_handle` replaced by `jerry_get_object_native_pointer`
|
||||
- `jerry_set_object_native_handle` replaced by `jerry_set_object_native_pointer`
|
||||
- `jerry_value_set_abort_flag` replaced by `jerry_create_abort_from_value`
|
||||
- `jerry_value_has_abort_flag` replaced by `jerry_value_is_abort`
|
||||
- `jerry_value_set_error_flag` replaced by `jerry_create_error_from_value`
|
||||
- `jerry_value_has_error_flag` replaced by `jerry_value_is_error`
|
||||
- `jerry_value_clear_error_flag` replaced by `jerry_get_value_from_error`
|
||||
- `jerry_get_value_without_error_flag` replaced by `jerry_get_value_from_error`
|
||||
- `jerry_parse_and_save_snapshot` replaced by `jerry_generate_snapshot`
|
||||
- `jerry_parse_and_save_function_snapshot` replaced by `jerry_generate_function_snapshot`
|
||||
|
||||
|
||||
***Removed unused configuration macros***
|
||||
|
||||
- `CONFIG_MEM_DATA_LIMIT_MINUS_HEAP_SIZE`
|
||||
- `CONFIG_MEM_STACK_LIMIT`
|
||||
- `CONFIG_VM_STACK_FRAME_INLINED_VALUES_NUMBER`
|
||||
- `CONFIG_ECMA_GLOBAL_ENVIRONMENT_DECLARATIVE`
|
||||
- All `CONFIG_..` macros have been renamed to use the `JERRY_` prefix format.
|
||||
|
||||
|
||||
# Modified API functions
|
||||
|
||||
## Error manipulating functions
|
||||
|
||||
The most important changes in the API are releated to error handling and manipulation.
|
||||
|
||||
### jerry_value_set_abort_flag
|
||||
|
||||
This function was replaced with [`jerry_create_abort_from_value`](02.API-REFERENCE.md#jerry_create_abort_from_value).
|
||||
Take note of the second argument of the new `jerry_create_abort_from_value` function which controls if the
|
||||
first argument should be usable after the call or not.
|
||||
|
||||
**Before**
|
||||
|
||||
```c
|
||||
{
|
||||
jerry_value_t value;
|
||||
// create or acquire value
|
||||
// ...
|
||||
|
||||
jerry_value_set_abort_flag (&value);
|
||||
|
||||
jerry_release_value (value);
|
||||
}
|
||||
```
|
||||
|
||||
**After**
|
||||
|
||||
```c
|
||||
{
|
||||
jerry_value_t value;
|
||||
// create or acquire value
|
||||
// ...
|
||||
|
||||
jerry_value_t abort = jerry_create_abort_from_value (value, true);
|
||||
// using the 'value' variable after release is invalid
|
||||
|
||||
jerry_release_value (abort);
|
||||
}
|
||||
```
|
||||
|
||||
- OR
|
||||
|
||||
```c
|
||||
{
|
||||
jerry_value_t value;
|
||||
... // create or acquire value
|
||||
|
||||
jerry_value_t abort = jerry_create_abort_from_value (value, false);
|
||||
// both 'abort' and 'value' can be used and must be released when they are no longer needed
|
||||
|
||||
jerry_release_value (abort);
|
||||
jerry_release_value (value);
|
||||
}
|
||||
```
|
||||
|
||||
### jerry_value_has_abort_flag
|
||||
|
||||
This function was renamed to [`jerry_value_is_abort`](02.API-REFERENCE.md#jerry_value_is_abort).
|
||||
|
||||
**Before**
|
||||
|
||||
```c
|
||||
{
|
||||
jerry_value_t value;
|
||||
// create or acquire value
|
||||
// ...
|
||||
|
||||
if (jerry_value_has_abort_flag (value))
|
||||
{
|
||||
// ...
|
||||
}
|
||||
|
||||
jerry_release_value (value);
|
||||
}
|
||||
```
|
||||
|
||||
**After**
|
||||
|
||||
```c
|
||||
{
|
||||
jerry_value_t value;
|
||||
// create or acquire value
|
||||
// ...
|
||||
|
||||
if (jerry_value_is_abort (value))
|
||||
{
|
||||
// ...
|
||||
}
|
||||
|
||||
jerry_release_value (value);
|
||||
}
|
||||
```
|
||||
|
||||
### jerry_value_set_error_flag
|
||||
|
||||
This function was replaced with [`jerry_create_error_from_value`](02.API-REFERENCE.md#jerry_create_error_from_value).
|
||||
Take note of the second argument of the new `jerry_create_error_from_value` function which controls if the
|
||||
first argument should be usable after the call or not.
|
||||
|
||||
**Before**
|
||||
|
||||
```c
|
||||
{
|
||||
jerry_value_t value;
|
||||
// create or acquire value
|
||||
// ...
|
||||
|
||||
jerry_value_set_error_flag (&value);
|
||||
|
||||
jerry_release_value (value);
|
||||
}
|
||||
```
|
||||
|
||||
**After**
|
||||
|
||||
```c
|
||||
{
|
||||
jerry_value_t value;
|
||||
// create or acquire value
|
||||
// ...
|
||||
|
||||
jerry_value_t error = jerry_create_error_from_value (value, true);
|
||||
// using the 'value' variable after release is invalid
|
||||
|
||||
jerry_release_value (error);
|
||||
}
|
||||
```
|
||||
|
||||
- OR
|
||||
|
||||
```c
|
||||
{
|
||||
jerry_value_t value;
|
||||
// create or acquire value
|
||||
// ...
|
||||
|
||||
jerry_value_t error = jerry_create_error_from_value (value, false);
|
||||
// both 'error' and 'value' can be used and must be released when they are no longer needed
|
||||
|
||||
jerry_release_value (error);
|
||||
jerry_release_value (value);
|
||||
}
|
||||
```
|
||||
|
||||
### jerry_value_has_error_flag
|
||||
|
||||
This function was renamed to [`jerry_value_is_error`](02.API-REFERENCE.md#jerry_value_is_error).
|
||||
|
||||
**Before**
|
||||
|
||||
```c
|
||||
{
|
||||
jerry_value_t value;
|
||||
// create or acquire value
|
||||
// ...
|
||||
|
||||
if (jerry_value_has_error_flag (value))
|
||||
{
|
||||
// ...
|
||||
}
|
||||
|
||||
jerry_release_value (value);
|
||||
}
|
||||
```
|
||||
|
||||
**After**
|
||||
|
||||
```c
|
||||
{
|
||||
jerry_value_t value;
|
||||
// create or acquire value
|
||||
// ...
|
||||
|
||||
if (jerry_value_is_error (value))
|
||||
{
|
||||
// ...
|
||||
}
|
||||
|
||||
jerry_release_value (value);
|
||||
}
|
||||
```
|
||||
|
||||
### jerry_value_clear_error_flag AND jerry_get_value_without_error_flag
|
||||
|
||||
These functions were merged into [`jerry_get_value_from_error`](02.API-REFERENCE.md#jerry_get_value_from_error).
|
||||
Please note the second argument of the new function which controls if the first argument passed should be released
|
||||
or not.
|
||||
|
||||
**Before**
|
||||
|
||||
```c
|
||||
{
|
||||
jerry_value_t value;
|
||||
// create or acquire value
|
||||
// ...
|
||||
|
||||
jerry_value_set_error_flag (&value);
|
||||
jerry_value_clear_error_flag (&value);
|
||||
// or
|
||||
jerry_value_t real_value = jerry_get_value_without_error_flag (value);
|
||||
|
||||
jerry_release_value (value);
|
||||
jerry_release_value (real_value);
|
||||
}
|
||||
```
|
||||
|
||||
**After**
|
||||
|
||||
```c
|
||||
{
|
||||
jerry_value_t value;
|
||||
// create or acquire value
|
||||
// ...
|
||||
|
||||
jerry_value_t error = jerry_create_error_from_value (value, true);
|
||||
|
||||
jerry_value_t real_value = jerry_get_value_from_error (error, true);
|
||||
|
||||
jerry_release_value (real_value);
|
||||
}
|
||||
```
|
||||
|
||||
## Other functions changed
|
||||
|
||||
### jerry_register_magic_strings
|
||||
|
||||
In case of the `jerry_register_magic_strings` function the change is that
|
||||
the first argument's base type `jerry_char_ptr_t` was changed to `jerry_char_t*`.
|
||||
For more details see: [`jerry_register_magic_strings`](02.API-REFERENCE.md#jerry_register_magic_strings).
|
||||
|
||||
In the following code parts please take note of the type used for the `magic_string_items` array.
|
||||
|
||||
**Before**
|
||||
|
||||
```c
|
||||
{
|
||||
// must be static, because 'jerry_register_magic_strings' does not copy
|
||||
// the items must be sorted by size at first, then lexicographically
|
||||
static const jerry_char_ptr_t magic_string_items[] = {
|
||||
(const jerry_char_ptr_t) "magicstring1",
|
||||
(const jerry_char_ptr_t) "magicstring2",
|
||||
(const jerry_char_ptr_t) "magicstring3"
|
||||
};
|
||||
uint32_t num_magic_string_items = (uint32_t) (sizeof (magic_string_items) / sizeof (jerry_char_ptr_t));
|
||||
|
||||
// must be static, because 'jerry_register_magic_strings' does not copy
|
||||
static const jerry_length_t magic_string_lengths[] = { 12, 12, 12 };
|
||||
jerry_register_magic_strings (magic_string_items, num_magic_string_items, magic_string_lengths);
|
||||
}
|
||||
```
|
||||
|
||||
**After**
|
||||
|
||||
```c
|
||||
{
|
||||
// must be static, because 'jerry_register_magic_strings' does not copy
|
||||
// the items must be sorted by size at first, then lexicographically
|
||||
static const jerry_char_t *magic_string_items[] = {
|
||||
(const jerry_char_t *) "magicstring1",
|
||||
(const jerry_char_t *) "magicstring2",
|
||||
(const jerry_char_t *) "magicstring3"
|
||||
};
|
||||
uint32_t num_magic_string_items = (uint32_t) (sizeof (magic_string_items) / sizeof (jerry_char_t *));
|
||||
|
||||
// must be static, because 'jerry_register_magic_strings' does not copy
|
||||
static const jerry_length_t magic_string_lengths[] = { 12, 12, 12 };
|
||||
jerry_register_magic_strings (magic_string_items, num_magic_string_items, magic_string_lengths);
|
||||
}
|
||||
```
|
||||
|
||||
## Snapshot generating API
|
||||
|
||||
### jerry_parse_and_save_snapshot
|
||||
|
||||
This function was replaced with [`jerry_generate_snapshot`](02.API-REFERENCE.md#jerry_generate_snapshot).
|
||||
The function returns an error object if there was any problem during snapshot generation and
|
||||
if there was no problem the return value is a number value containing the snapshot size in bytes.
|
||||
|
||||
**Before**
|
||||
|
||||
```c
|
||||
{
|
||||
static uint32_t global_mode_snapshot_buffer[256];
|
||||
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),
|
||||
true,
|
||||
false,
|
||||
global_mode_snapshot_buffer,
|
||||
sizeof (global_mode_snapshot_buffer) / sizeof (uint32_t));
|
||||
// use "global_mode_snapshot_buffer"
|
||||
}
|
||||
```
|
||||
|
||||
**After**
|
||||
|
||||
```c
|
||||
{
|
||||
static uint32_t global_mode_snapshot_buffer[256];
|
||||
const jerry_char_t *code_to_snapshot_p = (const jerry_char_t *) "(function () { return 'string from snapshot'; }) ();";
|
||||
|
||||
jerry_value_t generate_result;
|
||||
generate_result = jerry_generate_snapshot (NULL,
|
||||
0,
|
||||
code_to_snapshot_p,
|
||||
strlen ((const char *) code_to_snapshot_p),
|
||||
global_mode_snapshot_buffer,
|
||||
sizeof (global_mode_snapshot_buffer) / sizeof (uint32_t));
|
||||
if (jerry_value_is_error (generate_result))
|
||||
{
|
||||
// There was a problem during snapshot generation, for example there is a SyntaxError.
|
||||
// Use the "generate_result" to check the error.
|
||||
}
|
||||
else
|
||||
{
|
||||
size_t snapshot_size = (size_t) jerry_get_number_value (generate_result);
|
||||
// use "global_mode_snapshot_buffer"
|
||||
}
|
||||
jerry_release_value (generate_result);
|
||||
}
|
||||
```
|
||||
|
||||
### jerry_parse_and_save_function_snapshot
|
||||
|
||||
This function was replaced with [`jerry_generate_function_snapshot`](02.API-REFERENCE.md#jerry_parse_and_save_function_snapshot).
|
||||
The function returns an error object if there was any problem during snapshot generation and
|
||||
if there was no problem the return value is a number value containing the snapshot size in bytes.
|
||||
|
||||
**Before**
|
||||
|
||||
```c
|
||||
{
|
||||
static uint32_t func_snapshot_buffer[1024];
|
||||
|
||||
const jerry_char_t *args_p = (const jerry_char_t *) "a, b";
|
||||
const jerry_char_t *src_p = (const jerry_char_t *) "return a + b;";
|
||||
|
||||
size_t func_snapshot_size =
|
||||
jerry_parse_and_save_function_snapshot (src_p,
|
||||
strlen ((const char *) src_p),
|
||||
args_p,
|
||||
strlen ((const char *) args_p),
|
||||
false,
|
||||
func_snapshot_buffer,
|
||||
sizeof (func_snapshot_buffer) / sizeof (uint32_t));
|
||||
// check "function_snapshot_size" and use "func_snapshot_buffer"
|
||||
}
|
||||
```
|
||||
|
||||
**After**
|
||||
|
||||
```c
|
||||
{
|
||||
static uint32_t func_snapshot_buffer[1024];
|
||||
|
||||
const jerry_char_t *args_p = (const jerry_char_t *) "a, b";
|
||||
const jerry_char_t *src_p = (const jerry_char_t *) "return a + b;";
|
||||
|
||||
jerry_value_t generate_result;
|
||||
generate_result = jerry_generate_function_snapshot (NULL,
|
||||
0,
|
||||
src_p,
|
||||
strlen ((const char *) src_p),
|
||||
args_p,
|
||||
strlen ((const char *) args_p),
|
||||
0,
|
||||
func_snapshot_buffer,
|
||||
sizeof (func_snapshot_buffer) / sizeof (uint32_t));
|
||||
if (jerry_value_is_error (generate_result))
|
||||
{
|
||||
// There was a problem during snapshot generation, for example there is a SyntaxError.
|
||||
// Use the "generate_result" to check the error.
|
||||
}
|
||||
else
|
||||
{
|
||||
size_t snapshot_size = (size_t) jerry_get_number_value (generate_result);
|
||||
// use "func_snapshot_buffer"
|
||||
}
|
||||
|
||||
jerry_release_value (generate_result)
|
||||
}
|
||||
```
|
||||
|
||||
## Garbage collection
|
||||
|
||||
### jerry_gc
|
||||
|
||||
The [`jerry_gc`](02.API-REFERENCE.md#jerry_gc) function was modified to handle an argument which represents the pressure for the garbage collector.
|
||||
For more information checkout the [`jerry_gc_mode_t`](02.API-REFERENCE.md#jerry_gc_mode_t) reference.
|
||||
|
||||
**Before**
|
||||
|
||||
```c
|
||||
{
|
||||
jerry_gc ();
|
||||
}
|
||||
```
|
||||
|
||||
**After**
|
||||
|
||||
```c
|
||||
{
|
||||
jerry_gc (JERRY_GC_PRESSURE_LOW);
|
||||
}
|
||||
```
|
||||
|
||||
## jerry_eval
|
||||
|
||||
The third argument of [`jerry_eval`](02.API-REFERENCE.md#jerry_eval) has been changed
|
||||
from `bool` to [`jerry_parse_opts_t`](02.API-REFERENCE.md#jerry_parse_opts_t).
|
||||
|
||||
**Before**
|
||||
|
||||
```c
|
||||
const jerry_char_t *str_to_eval = (const jerry_char_t *) "1 + 1";
|
||||
jerry_value_t ret_val = jerry_eval (str_to_eval,
|
||||
strlen ((const char *) str_to_eval),
|
||||
false);
|
||||
```
|
||||
|
||||
**After**
|
||||
|
||||
```c
|
||||
const jerry_char_t *str_to_eval = (const jerry_char_t *) "1 + 1";
|
||||
jerry_value_t ret_val = jerry_eval (str_to_eval,
|
||||
strlen ((const char *) str_to_eval),
|
||||
JERRY_PARSE_NO_OPTS);
|
||||
```
|
||||
|
||||
## Port API
|
||||
|
||||
### jerry_port_get_time_zone
|
||||
|
||||
The port API of handling timezones has been changed. The previous interface did not
|
||||
allow timezones to be handled correctly, even if the host system was up to the task.
|
||||
Check [the related issue](https://github.com/jerryscript-project/jerryscript/issues/1661)
|
||||
for more details.
|
||||
|
||||
The new port API function name is [jerry_port_get_local_time_zone_adjustment](05.PORT-API.md#date-1].
|
||||
|
||||
Below is the default implementations for both versions:
|
||||
|
||||
**Before**
|
||||
|
||||
```c
|
||||
bool jerry_port_get_time_zone (jerry_time_zone_t *tz_p)
|
||||
{
|
||||
struct timeval tv;
|
||||
struct timezone tz;
|
||||
|
||||
/* gettimeofday may not fill tz, so zero-initializing */
|
||||
tz.tz_minuteswest = 0;
|
||||
tz.tz_dsttime = 0;
|
||||
|
||||
if (gettimeofday (&tv, &tz) != 0)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
tz_p->offset = tz.tz_minuteswest;
|
||||
tz_p->daylight_saving_time = tz.tz_dsttime > 0 ? 1 : 0;
|
||||
|
||||
return true;
|
||||
} /* jerry_port_get_time_zone */
|
||||
```
|
||||
|
||||
**After**
|
||||
|
||||
```c
|
||||
double jerry_port_get_local_time_zone_adjustment (double unix_ms,
|
||||
bool is_utc)
|
||||
{
|
||||
struct tm tm;
|
||||
time_t now = (time_t) (unix_ms / 1000);
|
||||
localtime_r (&now, &tm);
|
||||
if (!is_utc)
|
||||
{
|
||||
now -= tm.tm_gmtoff;
|
||||
localtime_r (&now, &tm);
|
||||
}
|
||||
return ((double) tm.tm_gmtoff) * 1000;
|
||||
} /* jerry_port_get_local_time_zone_adjustment */
|
||||
```
|
||||
|
||||
## Native pointers
|
||||
|
||||
The assignment of native pointers (previously called handles) have been changed
|
||||
since v1.0. In the previous version only one native pointer could be assigned to
|
||||
a `jerry_value_t`. Now it is allowed to register multiple native infos, which
|
||||
can be accessed with the corresponding
|
||||
[`jerry_object_native_info_t`](02.API-REFERENCE.md#jerry_object_native_info_t).
|
||||
The old functions were removed and replaced by new ones.
|
||||
|
||||
- `jerry_object_free_callback_t` callback type is replaced by `jerry_object_native_info_t`
|
||||
- `jerry_get_object_native_handle` is replaced by [`jerry_get_object_native_pointer`](02.API-REFERENCE.md#jerry_get_object_native_pointer)
|
||||
- `jerry_set_object_native_handle` is replaced by [`jerry_set_object_native_pointer`](02.API-REFERENCE.md#jerry_set_object_native_pointer)
|
||||
|
||||
**Before**
|
||||
|
||||
```c
|
||||
struct
|
||||
{
|
||||
int data;
|
||||
} my_info;
|
||||
|
||||
static void
|
||||
handler_construct_freecb (uintptr_t native_p)
|
||||
{
|
||||
// Invoked when the JS object is released and the
|
||||
// native data should be freed.
|
||||
|
||||
struct my_info *info = (struct my_info *) native_p;
|
||||
free (info);
|
||||
}
|
||||
|
||||
void
|
||||
demo (void)
|
||||
{
|
||||
jerry_value_t this_val;
|
||||
// create or acquire this_val
|
||||
// ...
|
||||
|
||||
struct my_info *info = (struct my_info *) malloc (sizeof (struct my_info));
|
||||
info->data = 11;
|
||||
|
||||
// setting the native handle
|
||||
jerry_set_object_native_handle (this_val,
|
||||
(uintptr_t) info,
|
||||
handler_construct_freecb);
|
||||
// ...
|
||||
// reading back the native handle
|
||||
uintptr_t ptr = (uintptr_t) NULL;
|
||||
bool is_ok = jerry_get_object_native_handle (this_val, &ptr);
|
||||
if (is_ok)
|
||||
{
|
||||
struct my_info *obj_info = (struct my_info *) ptr;
|
||||
// use "obj_info"
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
|
||||
**After**
|
||||
|
||||
```c
|
||||
struct
|
||||
{
|
||||
int data;
|
||||
} my_info;
|
||||
|
||||
static void
|
||||
handler_construct_freecb (void *native_p)
|
||||
{
|
||||
// Invoked when the JS object is released and the
|
||||
// native data should be freed.
|
||||
|
||||
struct my_info *info = (struct my_info *) native_p;
|
||||
free (info);
|
||||
}
|
||||
|
||||
static const jerry_object_native_info_t my_info_type_info =
|
||||
{
|
||||
.free_cb = handler_construct_freecb
|
||||
};
|
||||
|
||||
void
|
||||
demo (void)
|
||||
{
|
||||
jerry_value_t this_val;
|
||||
// create or acquire this_val
|
||||
// ...
|
||||
|
||||
struct my_info *info = (struct my_info *) malloc (sizeof (struct my_info));
|
||||
info->data = 11;
|
||||
|
||||
// setting the native handle
|
||||
jerry_set_object_native_pointer (this_val,
|
||||
info,
|
||||
&my_info_type_info);
|
||||
// ...
|
||||
// reading back the native handle pointed by the "my_info_type_info" variable
|
||||
void *ptr = NULL;
|
||||
bool has_p = jerry_get_object_native_pointer (this_val, &ptr, &my_info_type_info);
|
||||
if (has_p)
|
||||
{
|
||||
struct my_info *obj_info = (struct my_info *) ptr;
|
||||
// use "obj_info"
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
# New API functions
|
||||
|
||||
In this section the new API functions are listed.
|
||||
|
||||
## Built-in objects
|
||||
|
||||
***ArrayBuffer***
|
||||
|
||||
- [`jerry_create_arraybuffer`](02.API-REFERENCE.md#jerry_create_arraybuffer)
|
||||
- [`jerry_create_arraybuffer_external`](02.API-REFERENCE.md#jerry_create_arraybuffer_external)
|
||||
- [`jerry_get_arraybuffer_pointer`](02.API-REFERENCE.md#jerry_get_arraybuffer_pointer)
|
||||
|
||||
***DataView***
|
||||
|
||||
- [`jerry_create_dataview`](02.API-REFERENCE.md#jerry_create_dataview)
|
||||
- [`jerry_value_is_dataview`](02.API-REFERENCE.md#jerry_value_is_dataview)
|
||||
- [`jerry_get_dataview_buffer`](02.API-REFERENCE.md#jerry_get_dataview_buffer)
|
||||
|
||||
***JSON***
|
||||
|
||||
- [`jerry_json_parse`](02.API-REFERENCE.md#jerry_json_parse)
|
||||
- [`jerry_json_stringify`](02.API-REFERENCE.md#jerry_json_stringify)
|
||||
|
||||
***Number***
|
||||
|
||||
- [`jerry_create_number_infinity`](02.API-REFERENCE.md#jerry_create_number_infinity)
|
||||
- [`jerry_create_number_nan`](02.API-REFERENCE.md#jerry_create_number_nan)
|
||||
|
||||
***Promise***
|
||||
|
||||
- [`jerry_run_all_enqueued_jobs`](02.API-REFERENCE.md#jerry_run_all_enqueued_jobs)
|
||||
- [`jerry_create_promise`](02.API-REFERENCE.md#jerry_create_promise)
|
||||
- [`jerry_resolve_or_reject_promise`](02.API-REFERENCE.md#jerry_resolve_or_reject_promise)
|
||||
- [`jerry_value_is_promise`](02.API-REFERENCE.md#jerry_value_is_promise)
|
||||
|
||||
***RegExp***
|
||||
|
||||
- [`jerry_create_regexp`](02.API-REFERENCE.md#jerry_create_regexp)
|
||||
- [`jerry_create_regexp_sz`](02.API-REFERENCE.md#jerry_create_regexp_sz)
|
||||
|
||||
***String***
|
||||
|
||||
- [`jerry_substring_to_utf8_char_buffer`](02.API-REFERENCE.md#jerry_substring_to_utf8_char_buffer)
|
||||
- [`jerry_get_utf8_string_size`](02.API-REFERENCE.md#jerry_get_utf8_string_size)
|
||||
- [`jerry_get_utf8_string_length`](02.API-REFERENCE.md#jerry_get_utf8_string_length)
|
||||
- [`jerry_create_string_from_utf8`](02.API-REFERENCE.md#jerry_create_string_from_utf8)
|
||||
- [`jerry_create_string_sz_from_utf8`](02.API-REFERENCE.md#jerry_create_string_sz_from_utf8)
|
||||
|
||||
***Symbol***
|
||||
|
||||
- [`jerry_create_symbol`](02.API-REFERENCE.md#jerry_create_symbol)
|
||||
- [`jerry_get_symbol_descriptive_string`](02.API-REFERENCE.md#jerry_get_symbol_descriptive_string)
|
||||
- [`jerry_value_is_symbol`](02.API-REFERENCE.md#jerry_value_is_symbol)
|
||||
|
||||
***TypedArray***
|
||||
|
||||
- [`jerry_create_typedarray`](02.API-REFERENCE.md#jerry_create_typedarray)
|
||||
- [`jerry_create_typedarray_for_arraybuffer`](02.API-REFERENCE.md#jerry_create_typedarray_for_arraybuffer)
|
||||
- [`jerry_create_typedarray_for_arraybuffer_sz`](02.API-REFERENCE.md#jerry_create_typedarray_for_arraybuffer_sz)
|
||||
- [`jerry_get_typedarray_type`](02.API-REFERENCE.md#jerry_get_typedarray_type)
|
||||
- [`jerry_get_typedarray_length`](02.API-REFERENCE.md#jerry_get_typedarray_length)
|
||||
- [`jerry_get_typedarray_buffer`](02.API-REFERENCE.md#jerry_get_typedarray_buffer)
|
||||
- [`jerry_value_is_typedarray`](02.API-REFERENCE.md#jerry_value_is_typedarray)
|
||||
|
||||
|
||||
## Instances and memory management
|
||||
|
||||
***JerryScript instances***
|
||||
|
||||
- [`jerry_create_context`](02.API-REFERENCE.md#jerry_create_context)
|
||||
- [`jerry_get_context_data`](02.API-REFERENCE.md#jerry_get_context_data)
|
||||
|
||||
***Memory management***
|
||||
|
||||
- [`jerry_heap_alloc`](02.API-REFERENCE.md#jerry_heap_alloc)
|
||||
- [`jerry_heap_free`](02.API-REFERENCE.md#jerry_heap_free)
|
||||
|
||||
|
||||
## Operations with JavaScript values
|
||||
|
||||
***Binary operations***
|
||||
|
||||
- [`jerry_binary_operation`](02.API-REFERENCE.md#jerry_binary_operation)
|
||||
|
||||
***Error manipulating***
|
||||
|
||||
- [`jerry_get_error_type`](02.API-REFERENCE.md#jerry_get_error_type)
|
||||
- [`jerry_get_backtrace`](02.API-REFERENCE.md#jerry_get_backtrace)
|
||||
|
||||
***Native pointers***
|
||||
|
||||
- [`jerry_delete_object_native_pointer`](02.API-REFERENCE.md#jerry_delete_object_native_pointer)
|
||||
- [`jerry_objects_foreach_by_native_info`](02.API-REFERENCE.md#jerry_objects_foreach_by_native_info)
|
||||
|
||||
***Property***
|
||||
|
||||
- [`jerry_delete_property_by_index`](02.API-REFERENCE.md#jerry_delete_property_by_index)
|
||||
- [`jerry_objects_foreach`](02.API-REFERENCE.md#jerry_objects_foreach)
|
||||
|
||||
|
||||
## Debugger
|
||||
|
||||
- [`jerry_debugger_is_connected`](07.DEBUGGER.md#jerry_debugger_is_connected)
|
||||
- [`jerry_debugger_stop`](07.DEBUGGER.md#jerry_debugger_stop)
|
||||
- [`jerry_debugger_continue`](07.DEBUGGER.md#jerry_debugger_continue)
|
||||
- [`jerry_debugger_stop_at_breakpoint`](07.DEBUGGER.md#jerry_debugger_stop_at_breakpoint)
|
||||
- [`jerry_debugger_wait_for_client_source`](07.DEBUGGER.md#jerry_debugger_wait_for_client_source)
|
||||
- [`jerry_debugger_send_output`](07.DEBUGGER.md#jerry_debugger_send_output)
|
||||
- [`jerry_debugger_send_log`](07.DEBUGGER.md#jerry_debugger_send_log)
|
||||
|
||||
|
||||
## Other
|
||||
|
||||
- [`jerry_is_feature_enabled`](02.API-REFERENCE.md#jerry_is_feature_enabled)
|
||||
- [`jerry_parse_and_save_literals`](02.API-REFERENCE.md#jerry_parse_and_save_literals)
|
||||
- [`jerry_set_vm_exec_stop_callback`](02.API-REFERENCE.md#jerry_set_vm_exec_stop_callback)
|
||||
|
||||
|
||||
## Port API functions
|
||||
|
||||
- [`jerry_port_normalize_path`](05.PORT-API.md#jerry_port_normalize_path)
|
||||
- [`jerry_port_read_source`](05.PORT-API.md#jerry_port_read_source)
|
||||
- [`jerry_port_release_source`](05.PORT-API.md#jerry_port_release_source)
|
||||
- [`jerry_port_print_char`](05.PORT-API.md#jerry_port_print_char)
|
||||
- [`jerry_port_get_current_context`](05.PORT-API.md#jerry_port_get_current_context)
|
||||
- [`jerry_port_fatal`](05.PORT-API.md#jerry_port_fatal)
|
||||
- [`jerry_port_sleep`](05.PORT-API.md#jerry_port_sleep)
|
||||
|
After Width: | Height: | Size: 8.6 KiB |
|
After Width: | Height: | Size: 10 KiB |
|
After Width: | Height: | Size: 5.1 KiB |
|
After Width: | Height: | Size: 18 KiB |
|
After Width: | Height: | Size: 30 KiB |
|
After Width: | Height: | Size: 33 KiB |
|
After Width: | Height: | Size: 6.2 KiB |
|
After Width: | Height: | Size: 12 KiB |
BIN
APP_Framework/lib/JerryScript/jerryscript/docs/img/number.png
Normal file
|
After Width: | Height: | Size: 5.2 KiB |
|
After Width: | Height: | Size: 9.3 KiB |
|
After Width: | Height: | Size: 54 KiB |