mirror of
https://github.com/jerryscript-project/jerryscript.git
synced 2025-12-15 16:29:21 +00:00
Update jerry-port and jerry-ext (#4907)
Notable changes:
- Updated and the port API interface, new functions have been added
and some have been changed. The port library is now cleaned up to
not have any dependency on jerry-core, as it should be. The port library
is now strictly a collection of functions that implement
embedding/platform specific behavior.
- The default port implementation has been split for windows and unix.
Implemented port functions have been categorized and reorganized,
and marked with attribute((weak)) for better reusability.
- External context allocation has been moved to the port API instead
of a core API callback. The iterface has also been extended with a
function to free the allocated context. When external context is
enabled, jerry_init now automatically calls the port implementation
to allocate the context and jerry_cleanup automatically calls the port
to free the context.
- jerry_port_log has been changed to no longer require formatting to
be implemented by the port. The reason beind this is that it was vague what
format specifiers were used by the engine, and in what manner. The port
function now takes a zero-terminated string, and should only implement
how the string should be logged.
- Logging and log message formatting is now handled by the core jerry library
where it can be implemented as necessary. Logging can be done through a new
core API function, which uses the port to output the final log message.
- Log level has been moved into jerry-core, and an API function has
been added to set the log level. It should be the library that
filters log messages based on the requested log level, instead of
logging everything and requiring the user to do so.
- Module resolving logic has been moved into jerry-core. There's no
reason to have it in the port library and requiring embedders to
duplicate the code. It also added an unnecessary dependency on
jerry-core to the port. Platform specific behavior is still used through
the port API, like resolving module specifiers, and reading source file
contents. If necessary, the resolving logic can still be overridden as
previously.
- The jerry-ext library has also been cleaned up, and many utility
functions have been added that previously were implemented in
jerry-main. This allows easier reusability for some common operations,
like printing unhandled exceptions or providing a repl console.
- Debugger interaction with logged/printed messages has been fixed, so
that it's no longer the port implementations responsibility to send
the output to the debugger, as the port should have no notion of what a
debugger is. The printing and logging functions will now pass the
result message to the debugger, if connected.
- Cleaned up TZA handling in the date port implementation, and simplified
the API function prototype.
- Moved property access helper functions that use ASCII strings as
keys from jerry-ext to the core API.
JerryScript-DCO-1.0-Signed-off-by: Dániel Bátyai dbatyai@inf.u-szeged.hu
This commit is contained in:
parent
79fd540ec9
commit
ac1c48eeff
@ -44,7 +44,7 @@ IncludeBlocks: Regroup
|
||||
IncludeCategories:
|
||||
- Regex: '<windows.h>'
|
||||
Priority: 0
|
||||
- Regex: '<[-.a-z]*>'
|
||||
- Regex: '<[-./a-z]*>'
|
||||
Priority: 1
|
||||
- Regex: '"jerryscript[-.a-z]*"'
|
||||
Priority: 2
|
||||
|
||||
@ -54,7 +54,7 @@ set(JERRY_CMDLINE ON CACHE BOOL "Build jerry command line tool?")
|
||||
set(JERRY_CMDLINE_TEST OFF CACHE BOOL "Build jerry test command line tool?")
|
||||
set(JERRY_CMDLINE_SNAPSHOT OFF CACHE BOOL "Build jerry snapshot command line tool?")
|
||||
set(JERRY_LIBFUZZER OFF CACHE BOOL "Build jerry with libfuzzer support?")
|
||||
set(JERRY_PORT_DEFAULT ON CACHE BOOL "Build default jerry port implementation?")
|
||||
set(JERRY_PORT ON CACHE BOOL "Build default jerry port implementation?")
|
||||
set(JERRY_EXT ON CACHE BOOL "Build jerry-ext?")
|
||||
set(JERRY_MATH OFF CACHE BOOL "Build and use jerry-math?")
|
||||
set(UNITTESTS OFF CACHE BOOL "Build unit tests?")
|
||||
@ -75,9 +75,9 @@ if(NOT USING_CLANG)
|
||||
endif()
|
||||
|
||||
if(JERRY_CMDLINE OR JERRY_CMDLINE_TEST OR JERRY_CMDLINE_SNAPSHOT OR JERRY_LIBFUZZER OR UNITTESTS OR DOCTESTS)
|
||||
set(JERRY_PORT_DEFAULT ON)
|
||||
set(JERRY_PORT ON)
|
||||
|
||||
set(JERRY_PORT_DEFAULT_MESSAGE " (FORCED BY CMDLINE OR LIBFUZZER OR TESTS)")
|
||||
set(JERRY_PORT_MESSAGE " (FORCED BY CMDLINE OR LIBFUZZER OR TESTS)")
|
||||
endif()
|
||||
|
||||
if(JERRY_CMDLINE OR DOCTESTS)
|
||||
@ -138,7 +138,7 @@ message(STATUS "JERRY_CMDLINE " ${JERRY_CMDLINE} ${JERRY_CMDLIN
|
||||
message(STATUS "JERRY_CMDLINE_TEST " ${JERRY_CMDLINE_TEST} ${JERRY_CMDLINE_TEST_MESSAGE})
|
||||
message(STATUS "JERRY_CMDLINE_SNAPSHOT " ${JERRY_CMDLINE_SNAPSHOT} ${JERRY_CMDLINE_SNAPSHOT_MESSAGE})
|
||||
message(STATUS "JERRY_LIBFUZZER " ${JERRY_LIBFUZZER} ${JERRY_LIBFUZZER_MESSAGE})
|
||||
message(STATUS "JERRY_PORT_DEFAULT " ${JERRY_PORT_DEFAULT} ${JERRY_PORT_DEFAULT_MESSAGE})
|
||||
message(STATUS "JERRY_PORT " ${JERRY_PORT} ${JERRY_PORT_MESSAGE})
|
||||
message(STATUS "JERRY_EXT " ${JERRY_EXT} ${JERRY_EXT_MESSAGE})
|
||||
message(STATUS "JERRY_MATH " ${JERRY_MATH} ${JERRY_MATH_MESSAGE})
|
||||
message(STATUS "UNITTESTS " ${UNITTESTS})
|
||||
@ -278,8 +278,8 @@ if(JERRY_EXT)
|
||||
endif()
|
||||
|
||||
# Jerry's default port implementation
|
||||
if(JERRY_PORT_DEFAULT)
|
||||
add_subdirectory(jerry-port/default)
|
||||
if(JERRY_PORT)
|
||||
add_subdirectory(jerry-port)
|
||||
endif()
|
||||
|
||||
# Jerry command line tool
|
||||
|
||||
@ -299,7 +299,7 @@ in other projects. To achieve this, the following command can be executed to cre
|
||||
into the `amalgam` directory:
|
||||
|
||||
```sh
|
||||
$ python tools/amalgam.py --output-dir amalgam --jerry-core --jerry-port-default --jerry-math
|
||||
$ python tools/amalgam.py --output-dir amalgam --jerry-core --jerry-port --jerry-math
|
||||
```
|
||||
|
||||
(Note: In the example above, the command is executed from the project's root directory, but that is
|
||||
@ -310,8 +310,7 @@ 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-port.c`
|
||||
* `jerryscript-math.c`
|
||||
* `math.h`
|
||||
|
||||
@ -323,7 +322,7 @@ These files can be directly compiled with an application using the JerryScript A
|
||||
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/
|
||||
$ gcc -Wall -o demo_app demo_app.c amalgam/jerryscript.c amalgam/jerryscript-port.c amalgam/jerryscript-math.c -Iamalgam/
|
||||
```
|
||||
|
||||
(Note: The headers must be available on the include path.)
|
||||
|
||||
@ -6385,6 +6385,8 @@ jerry_bigint_digit_count (jerry_value_t value)
|
||||
[doctest]: # ()
|
||||
|
||||
```c
|
||||
#include <stdio.h>
|
||||
|
||||
#include "jerryscript.h"
|
||||
|
||||
int
|
||||
@ -10527,106 +10529,6 @@ void jerry_heap_free (void *mem_p, size_t size);
|
||||
- [jerry_heap_alloc](#jerry_heap_alloc)
|
||||
|
||||
|
||||
# External context functions
|
||||
|
||||
## jerry_context_alloc
|
||||
|
||||
**Summary**
|
||||
|
||||
Create an external JerryScript engine context.
|
||||
|
||||
**Prototype**
|
||||
|
||||
```c
|
||||
jerry_context_t *
|
||||
jerry_context_alloc (uint32_t heap_size,
|
||||
jerry_context_alloc_t alloc,
|
||||
void *cb_data_p);
|
||||
```
|
||||
|
||||
- `heap_size` - requested heap size of the JerryScript context
|
||||
- `alloc` - function for allocation
|
||||
- `cb_data_p` - user data
|
||||
- return value
|
||||
- pointer to the newly created JerryScript context if success
|
||||
- NULL otherwise.
|
||||
|
||||
*New in version 2.0*.
|
||||
|
||||
**Example**
|
||||
|
||||
[doctest]: # (test="compile", name="02.API-REFERENCE-create-context.c")
|
||||
|
||||
```c
|
||||
#include <stdlib.h>
|
||||
#include <pthread.h>
|
||||
|
||||
#include "jerryscript.h"
|
||||
#include "jerryscript-port.h"
|
||||
|
||||
/* A different Thread Local Storage variable for each jerry context. */
|
||||
__thread jerry_context_t *tls_context;
|
||||
|
||||
jerry_context_t *
|
||||
jerry_port_get_current_context (void)
|
||||
{
|
||||
/* Returns the context assigned to the thread. */
|
||||
return tls_context;
|
||||
}
|
||||
|
||||
/* Allocate JerryScript heap for each thread. */
|
||||
static void *
|
||||
context_alloc_fn (size_t size, void *cb_data)
|
||||
{
|
||||
(void) cb_data;
|
||||
return malloc (size);
|
||||
}
|
||||
|
||||
static void *
|
||||
thread_function (void *param)
|
||||
{
|
||||
tls_context = jerry_context_alloc (512 * 1024, context_alloc_fn, NULL);
|
||||
|
||||
jerry_init (JERRY_INIT_EMPTY);
|
||||
/* Run JerryScript in the context (e.g.: jerry_parse & jerry_run) */
|
||||
jerry_cleanup ();
|
||||
|
||||
/* Deallocate JerryScript context */
|
||||
free (tls_context);
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
#define NUM_OF_THREADS 8
|
||||
|
||||
int
|
||||
main (void)
|
||||
{
|
||||
pthread_t threads[NUM_OF_THREADS];
|
||||
|
||||
/* Create the threads. */
|
||||
for (int i = 0; i < NUM_OF_THREADS; i++)
|
||||
{
|
||||
pthread_create (&threads[i], NULL, thread_function, (void *) (intptr_t) i);
|
||||
}
|
||||
|
||||
/* Wait for the threads to complete, and release their resources. */
|
||||
for (int i = 0; i < NUM_OF_THREADS; i++)
|
||||
{
|
||||
pthread_join (threads[i], NULL);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
```
|
||||
|
||||
**See also**
|
||||
|
||||
- [jerry_context_t](#jerry_context_t)
|
||||
- [jerry_context_alloc_t](#jerry_context_alloc_t)
|
||||
- [jerry_port_get_current_context](05.PORT-API.md#jerry_port_get_current_context)
|
||||
|
||||
|
||||
# Snapshot functions
|
||||
|
||||
## jerry_generate_snapshot
|
||||
|
||||
@ -32,7 +32,7 @@ $ export PKG_CONFIG_PATH=$(pwd)/example_install/lib/pkgconfig/
|
||||
Test if the `pkg-config` works for JerryScript:
|
||||
|
||||
```sh
|
||||
$ pkg-config --cflags --libs libjerry-core libjerry-port-default libjerry-ext libjerry-math
|
||||
$ pkg-config --cflags --libs libjerry-core libjerry-port libjerry-ext libjerry-math
|
||||
```
|
||||
|
||||
## Example 2. Split engine initialization and script execution.
|
||||
@ -85,7 +85,7 @@ main (void)
|
||||
To compile it one can use the following command:
|
||||
|
||||
```sh
|
||||
$ gcc api-example-2.c -o api-example-2 $(pkg-config --cflags --libs libjerry-core libjerry-port-default libjerry-math)
|
||||
$ gcc api-example-2.c -o api-example-2 $(pkg-config --cflags --libs libjerry-core libjerry-port libjerry-math)
|
||||
```
|
||||
|
||||
If everything is correct the application returns with a zero exit code:
|
||||
@ -148,7 +148,7 @@ main (void)
|
||||
To compile it one can use the following command:
|
||||
|
||||
```sh
|
||||
$ gcc api-example-3.c -o api-example-3 $(pkg-config --cflags --libs libjerry-core libjerry-port-default libjerry-math)
|
||||
$ gcc api-example-3.c -o api-example-3 $(pkg-config --cflags --libs libjerry-core libjerry-port libjerry-math)
|
||||
```
|
||||
|
||||
If everything is correct the application returns with a zero exit code:
|
||||
@ -251,7 +251,7 @@ main (void)
|
||||
To compile it one can use the following command:
|
||||
|
||||
```sh
|
||||
$ gcc api-example-4.c -o api-example-4 $(pkg-config --cflags --libs libjerry-core libjerry-port-default libjerry-math)
|
||||
$ gcc api-example-4.c -o api-example-4 $(pkg-config --cflags --libs libjerry-core libjerry-port libjerry-math)
|
||||
```
|
||||
|
||||
If everything is correct the application should print out the message present in the `print_handler` method:
|
||||
@ -370,7 +370,7 @@ main (void)
|
||||
To compile it one can use the following command:
|
||||
|
||||
```sh
|
||||
$ gcc api-example-5.c -o api-example-5 $(pkg-config --cflags --libs libjerry-core libjerry-port-default libjerry-math)
|
||||
$ gcc api-example-5.c -o api-example-5 $(pkg-config --cflags --libs libjerry-core libjerry-port libjerry-math)
|
||||
```
|
||||
|
||||
If everything is correct the application should print out the string passed for the `print` method in the JS code:
|
||||
@ -388,14 +388,14 @@ can be used by other applications.
|
||||
|
||||
In this example the following extension methods are used:
|
||||
|
||||
- `jerryx_handler_register_global`
|
||||
- `jerryx_register_global`
|
||||
- `jerryx_handler_print`
|
||||
|
||||
In further examples this "print" handler will be used.
|
||||
|
||||
```c
|
||||
#include "jerryscript.h"
|
||||
#include "jerryscript-ext/handler.h"
|
||||
#include "jerryscript-ext/handlers.h"
|
||||
|
||||
int
|
||||
main (void)
|
||||
@ -407,7 +407,7 @@ main (void)
|
||||
jerry_init (JERRY_INIT_EMPTY);
|
||||
|
||||
/* Register 'print' function from the extensions to the global object */
|
||||
jerryx_handler_register_global ("print", jerryx_handler_print);
|
||||
jerryx_register_global ("print", jerryx_handler_print);
|
||||
|
||||
/* Setup Global scope code */
|
||||
jerry_value_t parsed_code = jerry_parse (script, script_size, NULL);
|
||||
@ -434,10 +434,10 @@ main (void)
|
||||
|
||||
To compile it one can use the following command:
|
||||
|
||||
(**Note** that the `libjerry-ext` was added **before** the `libjerry-port-default` entry for the `pkg-config` call.
|
||||
(**Note** that the `libjerry-ext` was added **before** the `libjerry-port` entry for the `pkg-config` call.
|
||||
|
||||
```sh
|
||||
$ gcc api-example-6.c -o api-example-6 $(pkg-config --cflags --libs libjerry-core libjerry-ext libjerry-port-default libjerry-math)
|
||||
$ gcc api-example-6.c -o api-example-6 $(pkg-config --cflags --libs libjerry-core libjerry-ext libjerry-port libjerry-math)
|
||||
```
|
||||
|
||||
If everything is correct the application should print out the string passed for the `print` method in the JS code:
|
||||
@ -456,8 +456,10 @@ Use the following code as the `api-example-7.c` file:
|
||||
[doctest]: # ()
|
||||
|
||||
```c
|
||||
#include <stdio.h>
|
||||
#include "jerryscript.h"
|
||||
#include "jerryscript-ext/handler.h"
|
||||
#include "jerryscript-ext/handlers.h"
|
||||
#include "jerryscript-ext/properties.h"
|
||||
|
||||
int
|
||||
main (void)
|
||||
@ -468,7 +470,7 @@ main (void)
|
||||
jerry_init (JERRY_INIT_EMPTY);
|
||||
|
||||
/* Register 'print' function from the extensions */
|
||||
jerryx_handler_register_global ("print", jerryx_handler_print);
|
||||
jerryx_register_global ("print", jerryx_handler_print);
|
||||
|
||||
/* Getting pointer to the Global object */
|
||||
jerry_value_t global_object = jerry_current_realm ();
|
||||
@ -509,10 +511,10 @@ main (void)
|
||||
|
||||
To compile it one can use the following command:
|
||||
|
||||
(**Note** that the `libjerry-ext` was added **before** the `libjerry-port-default` entry for the `pkg-config` call.
|
||||
(**Note** that the `libjerry-ext` was added **before** the `libjerry-port` entry for the `pkg-config` call.
|
||||
|
||||
```sh
|
||||
$ gcc api-example-7.c -o api-example-7 $(pkg-config --cflags --libs libjerry-core libjerry-ext libjerry-port-default libjerry-math)
|
||||
$ gcc api-example-7.c -o api-example-7 $(pkg-config --cflags --libs libjerry-core libjerry-ext libjerry-port libjerry-math)
|
||||
```
|
||||
|
||||
The sample will output 'Hello from C!'. However, now it is not just a part of the source script, but the value, dynamically supplied to the engine:
|
||||
@ -647,7 +649,8 @@ See the following `api-example-8-shell.c` file:
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include "jerryscript.h"
|
||||
#include "jerryscript-ext/handler.h"
|
||||
#include "jerryscript-ext/handlers.h"
|
||||
#include "jerryscript-ext/properties.h"
|
||||
|
||||
static void
|
||||
print_value (const jerry_value_t jsvalue)
|
||||
@ -726,7 +729,7 @@ main (void)
|
||||
jerry_init (JERRY_INIT_EMPTY);
|
||||
|
||||
/* Register 'print' function from the extensions */
|
||||
jerryx_handler_register_global ("print", jerryx_handler_print);
|
||||
jerryx_register_global ("print", jerryx_handler_print);
|
||||
|
||||
while (!is_done)
|
||||
{
|
||||
@ -781,10 +784,10 @@ main (void)
|
||||
|
||||
To compile it one can use the following command:
|
||||
|
||||
(**Note** that the `libjerry-ext` was added **before** the `libjerry-port-default` entry for the `pkg-config` call.
|
||||
(**Note** that the `libjerry-ext` was added **before** the `libjerry-port` entry for the `pkg-config` call.
|
||||
|
||||
```sh
|
||||
$ gcc api-example-8-shell.c -o api-example-8-shell $(pkg-config --cflags --libs libjerry-core libjerry-ext libjerry-port-default libjerry-math)
|
||||
$ gcc api-example-8-shell.c -o api-example-8-shell $(pkg-config --cflags --libs libjerry-core libjerry-ext libjerry-port libjerry-math)
|
||||
```
|
||||
|
||||
The application reads lines from standard input and evaluates them, one after another. To try out run:
|
||||
@ -802,7 +805,8 @@ In this example (`api-example-9.c`) an object with a native function is added to
|
||||
|
||||
```c
|
||||
#include "jerryscript.h"
|
||||
#include "jerryscript-ext/handler.h"
|
||||
#include "jerryscript-ext/handlers.h"
|
||||
#include "jerryscript-ext/properties.h"
|
||||
|
||||
struct my_struct
|
||||
{
|
||||
@ -827,7 +831,7 @@ main (void)
|
||||
jerry_init (JERRY_INIT_EMPTY);
|
||||
|
||||
/* Register 'print' function from the extensions */
|
||||
jerryx_handler_register_global ("print", jerryx_handler_print);
|
||||
jerryx_register_global ("print", jerryx_handler_print);
|
||||
|
||||
/* Do something with the native object */
|
||||
my_struct.msg = "Hello, World!";
|
||||
@ -879,10 +883,10 @@ main (void)
|
||||
|
||||
To compile it one can use the following command:
|
||||
|
||||
(**Note** that the `libjerry-ext` was added **before** the `libjerry-port-default` entry for the `pkg-config` call.
|
||||
(**Note** that the `libjerry-ext` was added **before** the `libjerry-port` entry for the `pkg-config` call.
|
||||
|
||||
```sh
|
||||
$ gcc api-example-9.c -o api-example-9 $(pkg-config --cflags --libs libjerry-core libjerry-ext libjerry-port-default libjerry-math)
|
||||
$ gcc api-example-9.c -o api-example-9 $(pkg-config --cflags --libs libjerry-core libjerry-ext libjerry-port libjerry-math)
|
||||
```
|
||||
|
||||
Execute the example with:
|
||||
@ -909,7 +913,8 @@ Use the following code for `api-example-10.c`:
|
||||
|
||||
```c
|
||||
#include "jerryscript.h"
|
||||
#include "jerryscript-ext/handler.h"
|
||||
#include "jerryscript-ext/handlers.h"
|
||||
#include "jerryscript-ext/properties.h"
|
||||
|
||||
/**
|
||||
* Add param to 'this.x'
|
||||
@ -953,7 +958,7 @@ main (void)
|
||||
jerry_init (JERRY_INIT_EMPTY);
|
||||
|
||||
/* Register 'print' function from the extensions */
|
||||
jerryx_handler_register_global ("print", jerryx_handler_print);
|
||||
jerryx_register_global ("print", jerryx_handler_print);
|
||||
|
||||
/* Create a JS object */
|
||||
const jerry_char_t my_js_object[] = " \
|
||||
@ -1008,10 +1013,10 @@ main (void)
|
||||
|
||||
To compile it one can use the following command:
|
||||
|
||||
(**Note** that the `libjerry-ext` was added **before** the `libjerry-port-default` entry for the `pkg-config` call.
|
||||
(**Note** that the `libjerry-ext` was added **before** the `libjerry-port` entry for the `pkg-config` call.
|
||||
|
||||
```sh
|
||||
$ gcc api-example-10.c -o api-example-10 $(pkg-config --cflags --libs libjerry-core libjerry-ext libjerry-port-default libjerry-math)
|
||||
$ gcc api-example-10.c -o api-example-10 $(pkg-config --cflags --libs libjerry-core libjerry-ext libjerry-port libjerry-math)
|
||||
```
|
||||
|
||||
Execute the example with:
|
||||
@ -1028,7 +1033,7 @@ Value of x is 17
|
||||
## Example 11. Changing the seed of pseudorandom generated numbers
|
||||
|
||||
If you want to change the seed of `Math.random()` generated numbers, you have to initialize the seed value with `srand`.
|
||||
A recommended method is using `jerry_port_get_current_time()` or something based on a constantly changing value, therefore every run produces truly random numbers.
|
||||
A recommended method is using `jerry_port_current_time()` or something based on a constantly changing value, therefore every run produces truly random numbers.
|
||||
|
||||
[doctest]: # ()
|
||||
|
||||
@ -1036,13 +1041,14 @@ A recommended method is using `jerry_port_get_current_time()` or something based
|
||||
#include <stdlib.h>
|
||||
#include "jerryscript.h"
|
||||
#include "jerryscript-port.h"
|
||||
#include "jerryscript-ext/handler.h"
|
||||
#include "jerryscript-ext/handlers.h"
|
||||
#include "jerryscript-ext/properties.h"
|
||||
|
||||
int
|
||||
main (void)
|
||||
{
|
||||
/* Initialize srand value */
|
||||
union { double d; unsigned u; } now = { .d = jerry_port_get_current_time () };
|
||||
union { double d; unsigned u; } now = { .d = jerry_port_current_time () };
|
||||
srand (now.u);
|
||||
|
||||
/* Generate a random number, and print it */
|
||||
@ -1052,7 +1058,7 @@ main (void)
|
||||
jerry_init (JERRY_INIT_EMPTY);
|
||||
|
||||
/* Register the print function */
|
||||
jerryx_handler_register_global ("print", jerryx_handler_print);
|
||||
jerryx_register_global ("print", jerryx_handler_print);
|
||||
|
||||
/* Evaluate the script */
|
||||
jerry_value_t eval_ret = jerry_eval (script, sizeof (script) - 1, JERRY_PARSE_NO_OPTS);
|
||||
|
||||
@ -1,6 +1,6 @@
|
||||
# Reference
|
||||
|
||||
## Termination
|
||||
## Process management
|
||||
|
||||
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.
|
||||
|
||||
@ -24,202 +24,14 @@ 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_OUT_OF_MEMORY = 10,
|
||||
JERRY_FATAL_REF_COUNT_LIMIT = 12,
|
||||
JERRY_FATAL_DISABLED_BYTE_CODE = 13,
|
||||
JERRY_FATAL_UNTERMINATED_GC_LOOPS = 14,
|
||||
JERRY_FATAL_FAILED_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 currently not used by the jerry-core directly.
|
||||
However, it provides a port specific 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 optional functions that can be used by the
|
||||
user application to resolve modules. If no callback is provided
|
||||
to `jerry_module_link`, the `jerry_port_module_resolve` function
|
||||
is used for resolving modules.
|
||||
|
||||
```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 */
|
||||
|
||||
/**
|
||||
* Default module resolver.
|
||||
*
|
||||
* @return a module object if resolving is successful, an error otherwise
|
||||
*/
|
||||
jerry_value_t
|
||||
jerry_port_module_resolve (const jerry_value_t specifier, /**< module specifier string */
|
||||
const jerry_value_t referrer, /**< parent module */
|
||||
void *user_p) /**< user data */
|
||||
{
|
||||
// Resolves a module using the specifier string. If a referrer is a module,
|
||||
// and specifier is a relative path, the base path should be the directory
|
||||
// part extracted from the path of the referrer module.
|
||||
|
||||
// The callback function of jerry_module_link may call this function
|
||||
// if it cannot resolve a module. Furthermore if the callback is NULL,
|
||||
// this function is used for resolving modules.
|
||||
|
||||
// The default implementation only resolves ECMAScript modules, and does
|
||||
// not (currently) use the user data.
|
||||
} /* jerry_port_module_resolve */
|
||||
|
||||
/**
|
||||
* Release known modules.
|
||||
*/
|
||||
void
|
||||
jerry_port_module_release (const jerry_value_t realm) /**< if this argument is object, release only those modules,
|
||||
* which realm value is equal to this argument. */
|
||||
{
|
||||
// This function releases the known modules, forcing their reload
|
||||
// when resolved again later. The released modules can be filtered
|
||||
// by realms. This function is only called by user applications.
|
||||
} /* jerry_port_module_release */
|
||||
```
|
||||
|
||||
## 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.
|
||||
@ -233,158 +45,237 @@ struct jerry_context_t *jerry_port_get_current_context (void);
|
||||
void jerry_port_sleep (uint32_t sleep_time);
|
||||
```
|
||||
|
||||
# How to port JerryScript
|
||||
## External context
|
||||
|
||||
This section describes a basic port implementation which was created for Unix based systems.
|
||||
|
||||
## Termination
|
||||
Allows the 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
|
||||
#include <stdlib.h>
|
||||
#include "jerryscript-port.h"
|
||||
|
||||
/**
|
||||
* Default implementation of jerry_port_fatal.
|
||||
* Allocate a new context for the engine.
|
||||
*
|
||||
* This port function is called by jerry_init when JERRY_EXTERNAL_CONTEXT is enabled. Otherwise this function is not
|
||||
* used. The engine will pass the size required for the context structure. An implementation must make sure to
|
||||
* allocate at least this amount.
|
||||
*
|
||||
* Excess allocated space will be used as the engine heap when jerryscript is configured to use it's internal allocator,
|
||||
* this can be used to control the internal heap size.
|
||||
*
|
||||
* NOTE: The allocated memory must be pointer-aligned, otherwise the behavior is
|
||||
* undefined.
|
||||
*
|
||||
* @param context_size: the size of the internal context structure
|
||||
*
|
||||
* @return total size of the allocated buffer
|
||||
*/
|
||||
void jerry_port_fatal (jerry_fatal_code_t code)
|
||||
{
|
||||
exit (code);
|
||||
} /* jerry_port_fatal */
|
||||
size_t jerry_port_context_alloc (size_t context_size);
|
||||
```
|
||||
|
||||
```c
|
||||
/**
|
||||
* Get the currently active context of the engine.
|
||||
*
|
||||
* 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 currently used engine context.
|
||||
*/
|
||||
struct jerry_context_t *jerry_port_context_get (void);
|
||||
```
|
||||
|
||||
```c
|
||||
/**
|
||||
* Free the currently used context.
|
||||
*
|
||||
* This port function is called by jerry_cleanup when JERRY_EXTERNAL_CONTEXT is enabled.
|
||||
* Otherwise this function is not used.
|
||||
*
|
||||
* @return the pointer to the engine context.
|
||||
*/
|
||||
void jerry_port_context_free (void);
|
||||
```
|
||||
|
||||
## I/O
|
||||
|
||||
```c
|
||||
#include <stdarg.h>
|
||||
#include "jerryscript-port.h"
|
||||
|
||||
/**
|
||||
* Provide log message implementation for the engine.
|
||||
* Display or log a debug/error message.
|
||||
*
|
||||
* Note:
|
||||
* This example ignores the log level.
|
||||
* The message is passed as a zero-terminated string. Messages may be logged in parts, which
|
||||
* will result in multiple calls to this functions. The implementation should consider
|
||||
* this before appending or prepending strings to the argument.
|
||||
*
|
||||
* This function is 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).
|
||||
*
|
||||
* The implementation can decide whether error and debug messages are logged to
|
||||
* the console, or saved to a database or to a file.
|
||||
*/
|
||||
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 */
|
||||
void jerry_port_log (const char *message_p);
|
||||
```
|
||||
|
||||
```c
|
||||
/**
|
||||
* Print a character to stdout with putchar.
|
||||
* Print a single character to standard output.
|
||||
*
|
||||
* This port function is never called from jerry-core directly, it is only used by jerry-ext components to print
|
||||
* information.
|
||||
*
|
||||
* @param byte: the byte to print.
|
||||
*/
|
||||
void
|
||||
jerry_port_print_char (char c)
|
||||
{
|
||||
putchar (c);
|
||||
} /* jerry_port_print_char */
|
||||
void jerry_port_print_byte (jerry_char_t byte);
|
||||
```
|
||||
|
||||
```c
|
||||
/**
|
||||
* Print a buffer to standard output
|
||||
*
|
||||
* This port function is never called from jerry-core directly, it is only used by jerry-ext components to print
|
||||
* information.
|
||||
*
|
||||
* @param buffer_p: input buffer
|
||||
* @param buffer_size: data size
|
||||
*/
|
||||
void jerry_port_print_buffer (const jerry_char_t *buffer_p, jerry_size_t buffer_size);
|
||||
```
|
||||
|
||||
```c
|
||||
/**
|
||||
* Read a line from standard input.
|
||||
*
|
||||
* The implementation should allocate storage necessary for the string. The result string should include the ending line
|
||||
* terminator character(s) and should be zero terminated.
|
||||
*
|
||||
* An implementation may return NULL to signal that the end of input is reached, or an error occured.
|
||||
*
|
||||
* When a non-NULL value is returned, the caller will pass the returned value to `jerry_port_line_free` when the line is
|
||||
* no longer needed. This can be used to finalize dynamically allocated buffers if necessary.
|
||||
*
|
||||
* This port function is never called from jerry-core directly, it is only used by some jerry-ext components that
|
||||
* require user input.
|
||||
*
|
||||
* @param out_size_p: size of the input string in bytes, excluding terminating zero byte
|
||||
*
|
||||
* @return pointer to the buffer storing the string,
|
||||
* or NULL if end of input
|
||||
*/
|
||||
jerry_char_t *jerry_port_line_read (jerry_size_t *out_size_p);
|
||||
```
|
||||
|
||||
```c
|
||||
/**
|
||||
* Free a line buffer allocated by jerry_port_line_read
|
||||
*
|
||||
* @param buffer_p: buffer returned by jerry_port_line_read
|
||||
*/
|
||||
void jerry_port_line_free (jerry_char_t *buffer_p);
|
||||
```
|
||||
|
||||
## Filesystem
|
||||
|
||||
```
|
||||
/**
|
||||
* Canonicalize a file path.
|
||||
*
|
||||
* If possible, the implementation should resolve symbolic links and other directory references found in the input path,
|
||||
* and create a fully canonicalized file path as the result.
|
||||
*
|
||||
* The function may return with NULL in case an error is encountered, in which case the calling operation will not
|
||||
* proceed.
|
||||
*
|
||||
* The implementation should allocate storage for the result path as necessary. Non-NULL return values will be passed
|
||||
* to `jerry_port_path_free` when the result is no longer needed by the caller, which can be used to finalize
|
||||
* dynamically allocated buffers.
|
||||
*
|
||||
* NOTE: The implementation must not return directly with the input, as the input buffer is released after the call.
|
||||
*
|
||||
* @param path_p: zero-terminated string containing the input path
|
||||
* @param path_size: size of the input path string in bytes, excluding terminating zero
|
||||
*
|
||||
* @return buffer with the normalized path if the operation is successful,
|
||||
* NULL otherwise
|
||||
*/
|
||||
jerry_char_t *jerry_port_path_normalize (const jerry_char_t *path_p, jerry_size_t path_size);
|
||||
```
|
||||
|
||||
```c
|
||||
/**
|
||||
* Free a path buffer returned by jerry_port_path_normalize.
|
||||
*
|
||||
* @param path_p: the path buffer to free
|
||||
*/
|
||||
void jerry_port_path_free (jerry_char_t *path_p);
|
||||
```
|
||||
|
||||
```c
|
||||
/**
|
||||
* Get the offset of the basename component in the input path.
|
||||
*
|
||||
* The implementation should return the offset of the first character after the last path separator found in the path.
|
||||
* This is used by the caller to split the path into a directory name and a file name.
|
||||
*
|
||||
* @param path_p: input zero-terminated path string
|
||||
*
|
||||
* @return offset of the basename component in the input path
|
||||
*/
|
||||
jerry_size_t jerry_port_path_base (const jerry_char_t *path_p);
|
||||
```
|
||||
|
||||
```c
|
||||
/**
|
||||
* Open a source file and read its contents into a buffer.
|
||||
*
|
||||
* When the source file is no longer needed by the caller, the returned pointer will be passed to
|
||||
* `jerry_port_source_free`, which can be used to finalize the buffer.
|
||||
*
|
||||
* @param file_name_p: Path that points to the source file in the filesystem.
|
||||
* @param out_size_p: The opened file's size in bytes.
|
||||
*
|
||||
* @return pointer to the buffer which contains the content of the file.
|
||||
*/
|
||||
jerry_char_t *jerry_port_source_read (const char *file_name_p, jerry_size_t *out_size_p);
|
||||
```
|
||||
|
||||
```c
|
||||
/**
|
||||
* Free a source file buffer.
|
||||
*
|
||||
* @param buffer_p: buffer returned by jerry_port_source_read
|
||||
*/
|
||||
void jerry_port_source_free (jerry_char_t *buffer_p);
|
||||
```
|
||||
|
||||
## 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.
|
||||
* Get local time zone adjustment in milliseconds for the given input time.
|
||||
*
|
||||
* @return the pointer to the current context
|
||||
* The argument is a time value representing milliseconds since unix epoch.
|
||||
*
|
||||
* Ideally, this function should satisfy the stipulations applied to LocalTZA
|
||||
* in section 21.4.1.7 of the ECMAScript version 12.0, as if called with isUTC true.
|
||||
*
|
||||
* This port function can be called by jerry-core when JERRY_BUILTIN_DATE is enabled.
|
||||
* Otherwise this function is not used.
|
||||
*
|
||||
* @param unix_ms: time value in milliseconds since unix epoch
|
||||
*
|
||||
* @return local time offset in milliseconds applied to UTC for the given time value
|
||||
*/
|
||||
jerry_context_t *
|
||||
jerry_port_get_current_context (void)
|
||||
{
|
||||
return current_context_p;
|
||||
} /* jerry_port_get_current_context */
|
||||
int32_t jerry_port_local_tza (double unix_ms);
|
||||
```
|
||||
|
||||
## 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) */
|
||||
/**
|
||||
* Get the current system time in UTC.
|
||||
*
|
||||
* This port function is called by jerry-core when JERRY_BUILTIN_DATE is enabled.
|
||||
* It can also be used in the implementing application to initialize the random number generator.
|
||||
*
|
||||
* @return milliseconds since Unix epoch
|
||||
*/
|
||||
double jerry_port_current_time (void);
|
||||
```
|
||||
|
||||
@ -130,6 +130,8 @@ jerry_debugger_is_connected (void);
|
||||
[doctest]: # (test="link")
|
||||
|
||||
```c
|
||||
#include <stdio.h>
|
||||
|
||||
#include "jerryscript.h"
|
||||
#include "jerryscript-ext/debugger.h"
|
||||
|
||||
@ -409,40 +411,3 @@ main (void)
|
||||
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 ();
|
||||
}
|
||||
```
|
||||
|
||||
@ -1,173 +1,8 @@
|
||||
# Common methods to handle properties
|
||||
|
||||
The `jerryscript-ext/handler.h` header defines a set of convenience methods
|
||||
The `jerryscript-ext/properties.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_value_free](#jerry_value_free) 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_current_realm ();
|
||||
|
||||
jerry_value_t value = jerry_number (3.3);
|
||||
jerry_value_t result = jerryx_set_property_str (global, "value", value);
|
||||
if (jerry_value_is_exception (result))
|
||||
{
|
||||
/* The error type/reason can be extracted via the `jerry_exception_value` method */
|
||||
printf ("Error during property configuration\r\n");
|
||||
}
|
||||
|
||||
jerry_value_free (result);
|
||||
jerry_value_free (value);
|
||||
jerry_value_free (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_value_free](#jerry_value_free) 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_current_realm ();
|
||||
|
||||
jerry_value_t math_object = jerryx_get_property_str (global, "Math");
|
||||
|
||||
/* use math_object */
|
||||
|
||||
jerry_value_free (math_object);
|
||||
jerry_value_free (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_object_has` 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 exists 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_current_realm ();
|
||||
|
||||
bool have_math = jerryx_has_property_str (global, "Math");
|
||||
|
||||
jerry_value_free (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
|
||||
@ -263,8 +98,10 @@ jerryx_set_properties (const jerry_value_t target_object,
|
||||
[doctest]: # ()
|
||||
|
||||
```c
|
||||
#include <stdio.h>
|
||||
#include "jerryscript.h"
|
||||
#include "jerryscript-ext/handler.h"
|
||||
#include "jerryscript-ext/handlers.h"
|
||||
#include "jerryscript-ext/properties.h"
|
||||
|
||||
static jerry_value_t
|
||||
handler (const jerry_call_info_t *call_info_p,
|
||||
@ -326,8 +163,10 @@ when setting a property entry:
|
||||
[doctest]: # ()
|
||||
|
||||
```c
|
||||
#include <stdio.h>
|
||||
#include "jerryscript.h"
|
||||
#include "jerryscript-ext/handler.h"
|
||||
#include "jerryscript-ext/handlers.h"
|
||||
#include "jerryscript-ext/properties.h"
|
||||
|
||||
static jerry_value_t
|
||||
handler (const jerry_call_info_t *call_info_p,
|
||||
@ -440,7 +279,7 @@ jerryx_handler_assert_fatal (const jerry_value_t func_obj_val, const jerry_value
|
||||
|
||||
**See also**
|
||||
|
||||
- [jerryx_handler_register_global](#jerryx_handler_register_global)
|
||||
- [jerryx_register_global](#jerryx_register_global)
|
||||
|
||||
|
||||
## jerryx_handler_assert_throw
|
||||
@ -466,7 +305,7 @@ jerryx_handler_assert_throw (const jerry_value_t func_obj_val, const jerry_value
|
||||
|
||||
**See also**
|
||||
|
||||
- [jerryx_handler_register_global](#jerryx_handler_register_global)
|
||||
- [jerryx_register_global](#jerryx_register_global)
|
||||
|
||||
|
||||
## jerryx_handler_assert
|
||||
@ -504,7 +343,7 @@ jerryx_handler_gc (const jerry_value_t func_obj_val, const jerry_value_t this_p,
|
||||
|
||||
**See also**
|
||||
|
||||
- [jerryx_handler_register_global](#jerryx_handler_register_global)
|
||||
- [jerryx_register_global](#jerryx_register_global)
|
||||
|
||||
|
||||
## jerryx_handler_print
|
||||
@ -513,14 +352,14 @@ jerryx_handler_gc (const jerry_value_t func_obj_val, const jerry_value_t this_p,
|
||||
|
||||
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 NULL character is output as "\u0000",
|
||||
`jerry_port_print_byte`. The NULL character is output as "\u0000",
|
||||
other characters are output bytewise.
|
||||
|
||||
*Note*: This implementation does not use standard C `printf` to print its
|
||||
output. This allows more flexibility but also extends the core JerryScript
|
||||
engine port API. Applications that want to use `jerryx_handler_print` must
|
||||
ensure that their port implementation also provides
|
||||
`jerry_port_print_char`.
|
||||
`jerry_port_print_byte`.
|
||||
|
||||
**Prototype**
|
||||
|
||||
@ -539,13 +378,13 @@ jerryx_handler_print (const jerry_value_t func_obj_val, const jerry_value_t this
|
||||
|
||||
**See also**
|
||||
|
||||
- [jerryx_handler_register_global](#jerryx_handler_register_global)
|
||||
- [jerry_port_print_char](05.PORT-API.md#jerry_port_print_char)
|
||||
- [jerryx_register_global](#jerryx_register_global)
|
||||
- [jerry_port_print_byte](05.PORT-API.md#jerry_port_print_char)
|
||||
|
||||
|
||||
# Handler registration helper
|
||||
|
||||
## jerryx_handler_register_global
|
||||
## jerryx_register_global
|
||||
|
||||
**Summary**
|
||||
|
||||
@ -558,7 +397,7 @@ longer needed.
|
||||
|
||||
```c
|
||||
jerry_value_t
|
||||
jerryx_handler_register_global (const char *name_p,
|
||||
jerryx_register_global (const char *name_p,
|
||||
jerry_external_handler_t handler_p);
|
||||
```
|
||||
|
||||
@ -573,7 +412,8 @@ jerryx_handler_register_global (const char *name_p,
|
||||
|
||||
```c
|
||||
#include "jerryscript.h"
|
||||
#include "jerryscript-ext/handler.h"
|
||||
#include "jerryscript-ext/handlers.h"
|
||||
#include "jerryscript-ext/properties.h"
|
||||
|
||||
static const struct {
|
||||
const char *name_p;
|
||||
@ -593,8 +433,8 @@ register_common_functions (void)
|
||||
|
||||
for (int i = 0; common_functions[i].name_p != NULL && !jerry_value_is_exception (ret); i++)
|
||||
{
|
||||
ret = jerryx_handler_register_global (common_functions[i].name_p,
|
||||
common_functions[i].handler_p);
|
||||
ret = jerryx_register_global (common_functions[i].name_p,
|
||||
common_functions[i].handler_p);
|
||||
}
|
||||
|
||||
jerry_value_free (ret);
|
||||
|
||||
@ -131,6 +131,7 @@ set(INCLUDE_CORE_PRIVATE ${INCLUDE_CORE_PRIVATE} PARENT_SCOPE) # for tests/unit-
|
||||
set(SOURCE_CORE_FILES
|
||||
api/jerry-debugger-transport.c
|
||||
api/jerry-debugger.c
|
||||
api/jerry-module.c
|
||||
api/jerry-snapshot.c
|
||||
api/jerryscript.c
|
||||
debugger/debugger.c
|
||||
@ -527,6 +528,8 @@ if(ENABLE_AMALGAM)
|
||||
add_dependencies(amalgam amalgam-jerry)
|
||||
|
||||
set(SOURCE_CORE_FILES ${AMALGAM_CORE_C} ${AMALGAM_CORE_H} ${AMALGAM_CONFIG_H})
|
||||
set(INCLUDE_CORE_PUBLIC PARENT_SCOPE)
|
||||
set(INCLUDE_CORE_PRIVATE PARENT_SCOPE)
|
||||
endif()
|
||||
|
||||
# Third-party
|
||||
@ -743,6 +746,7 @@ add_library(${JERRY_CORE_NAME} ${SOURCE_CORE_FILES})
|
||||
target_compile_definitions(${JERRY_CORE_NAME} PUBLIC ${DEFINES_JERRY})
|
||||
target_include_directories(${JERRY_CORE_NAME} PUBLIC ${INCLUDE_CORE_PUBLIC})
|
||||
target_include_directories(${JERRY_CORE_NAME} PRIVATE ${INCLUDE_CORE_PRIVATE})
|
||||
add_dependencies(${JERRY_CORE_NAME} amalgam)
|
||||
|
||||
set(JERRY_CORE_PKGCONFIG_REQUIRES)
|
||||
set(JERRY_CORE_PKGCONFIG_LIBS)
|
||||
|
||||
@ -140,7 +140,7 @@ jerry_debugger_transport_close (void)
|
||||
current_p = next_p;
|
||||
} while (current_p != NULL);
|
||||
|
||||
jerry_port_log (JERRY_LOG_LEVEL_DEBUG, "Debugger client connection closed.\n");
|
||||
jerry_log (JERRY_LOG_LEVEL_DEBUG, "Debugger client connection closed.\n");
|
||||
|
||||
jerry_debugger_free_unreferenced_byte_code ();
|
||||
} /* jerry_debugger_transport_close */
|
||||
|
||||
@ -197,7 +197,7 @@ jerry_debugger_send_output (const jerry_char_t *buffer, /**< buffer */
|
||||
if (JERRY_CONTEXT (debugger_flags) & JERRY_DEBUGGER_CONNECTED)
|
||||
{
|
||||
jerry_debugger_send_string (JERRY_DEBUGGER_OUTPUT_RESULT,
|
||||
JERRY_DEBUGGER_OUTPUT_OK,
|
||||
JERRY_DEBUGGER_OUTPUT_PRINT,
|
||||
(const uint8_t *) buffer,
|
||||
sizeof (uint8_t) * str_size);
|
||||
}
|
||||
@ -206,26 +206,3 @@ jerry_debugger_send_output (const jerry_char_t *buffer, /**< buffer */
|
||||
JERRY_UNUSED (str_size);
|
||||
#endif /* JERRY_DEBUGGER */
|
||||
} /* jerry_debugger_send_output */
|
||||
|
||||
/**
|
||||
* Send the log of the program to the debugger client.
|
||||
*/
|
||||
void
|
||||
jerry_debugger_send_log (jerry_log_level_t level, /**< level of the diagnostics message */
|
||||
const jerry_char_t *buffer, /**< buffer */
|
||||
jerry_size_t str_size) /**< string size */
|
||||
{
|
||||
#if JERRY_DEBUGGER
|
||||
if (JERRY_CONTEXT (debugger_flags) & JERRY_DEBUGGER_CONNECTED)
|
||||
{
|
||||
jerry_debugger_send_string (JERRY_DEBUGGER_OUTPUT_RESULT,
|
||||
(uint8_t) (level + 2),
|
||||
(const uint8_t *) buffer,
|
||||
sizeof (uint8_t) * str_size);
|
||||
}
|
||||
#else /* !JERRY_DEBUGGER */
|
||||
JERRY_UNUSED (level);
|
||||
JERRY_UNUSED (buffer);
|
||||
JERRY_UNUSED (str_size);
|
||||
#endif /* JERRY_DEBUGGER */
|
||||
} /* jerry_debugger_send_log */
|
||||
|
||||
247
jerry-core/api/jerry-module.c
Normal file
247
jerry-core/api/jerry-module.c
Normal file
@ -0,0 +1,247 @@
|
||||
/* Copyright JS Foundation and other contributors, http://js.foundation
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#include <lit-magic-strings.h>
|
||||
#include <lit-strings.h>
|
||||
|
||||
#include "jerryscript-core.h"
|
||||
#include "jerryscript-port.h"
|
||||
|
||||
#include "ecma-errors.h"
|
||||
|
||||
#if JERRY_MODULE_SYSTEM
|
||||
|
||||
/**
|
||||
* A module descriptor.
|
||||
*/
|
||||
typedef struct jerry_module_t
|
||||
{
|
||||
struct jerry_module_t *next_p; /**< next_module */
|
||||
jerry_char_t *path_p; /**< path to the module */
|
||||
jerry_size_t basename_offset; /**< offset of the basename in the module path*/
|
||||
jerry_value_t realm; /**< the realm of the module */
|
||||
jerry_value_t module; /**< the module itself */
|
||||
} jerry_module_t;
|
||||
|
||||
/**
|
||||
* Native info descriptor for modules.
|
||||
*/
|
||||
static const jerry_object_native_info_t jerry_module_native_info JERRY_ATTR_CONST_DATA = {
|
||||
.free_cb = NULL,
|
||||
};
|
||||
|
||||
/**
|
||||
* Default module manager.
|
||||
*/
|
||||
typedef struct
|
||||
{
|
||||
jerry_module_t *module_head_p; /**< first module */
|
||||
} jerry_module_manager_t;
|
||||
|
||||
/**
|
||||
* Release known modules.
|
||||
*/
|
||||
static void
|
||||
jerry_module_free (jerry_module_manager_t *manager_p, /**< module manager */
|
||||
const jerry_value_t realm) /**< if this argument is object, release only those modules,
|
||||
* which realm value is equal to this argument. */
|
||||
{
|
||||
jerry_module_t *module_p = manager_p->module_head_p;
|
||||
|
||||
bool release_all = !jerry_value_is_object (realm);
|
||||
|
||||
jerry_module_t *prev_p = NULL;
|
||||
|
||||
while (module_p != NULL)
|
||||
{
|
||||
jerry_module_t *next_p = module_p->next_p;
|
||||
|
||||
if (release_all || module_p->realm == realm)
|
||||
{
|
||||
jerry_port_path_free (module_p->path_p);
|
||||
jerry_value_free (module_p->realm);
|
||||
jerry_value_free (module_p->module);
|
||||
|
||||
jerry_heap_free (module_p, sizeof (jerry_module_t));
|
||||
|
||||
if (prev_p == NULL)
|
||||
{
|
||||
manager_p->module_head_p = next_p;
|
||||
}
|
||||
else
|
||||
{
|
||||
prev_p->next_p = next_p;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
prev_p = module_p;
|
||||
}
|
||||
|
||||
module_p = next_p;
|
||||
}
|
||||
} /* jerry_module_free */
|
||||
|
||||
/**
|
||||
* Initialize the default module manager.
|
||||
*/
|
||||
static void
|
||||
jerry_module_manager_init (void *user_data_p)
|
||||
{
|
||||
((jerry_module_manager_t *) user_data_p)->module_head_p = NULL;
|
||||
} /* jerry_module_manager_init */
|
||||
|
||||
/**
|
||||
* Deinitialize the default module manager.
|
||||
*/
|
||||
static void
|
||||
jerry_module_manager_deinit (void *user_data_p) /**< context pointer to deinitialize */
|
||||
{
|
||||
jerry_value_t undef = jerry_undefined ();
|
||||
jerry_module_free ((jerry_module_manager_t *) user_data_p, undef);
|
||||
jerry_value_free (undef);
|
||||
} /* jerry_module_manager_deinit */
|
||||
|
||||
/**
|
||||
* Declare the context data manager for modules.
|
||||
*/
|
||||
static const jerry_context_data_manager_t jerry_module_manager JERRY_ATTR_CONST_DATA = {
|
||||
.init_cb = jerry_module_manager_init,
|
||||
.deinit_cb = jerry_module_manager_deinit,
|
||||
.bytes_needed = sizeof (jerry_module_manager_t)
|
||||
};
|
||||
|
||||
#endif /* JERRY_MODULE_SYSTEM */
|
||||
|
||||
/**
|
||||
* Default module resolver.
|
||||
*
|
||||
* @return a module object if resolving is successful, an error otherwise
|
||||
*/
|
||||
jerry_value_t
|
||||
jerry_module_resolve (const jerry_value_t specifier, /**< module specifier string */
|
||||
const jerry_value_t referrer, /**< parent module */
|
||||
void *user_p) /**< user data */
|
||||
{
|
||||
#if JERRY_MODULE_SYSTEM
|
||||
JERRY_UNUSED (user_p);
|
||||
|
||||
const jerry_char_t *directory_p = lit_get_magic_string_utf8 (LIT_MAGIC_STRING__EMPTY);
|
||||
jerry_size_t directory_size = lit_get_magic_string_size (LIT_MAGIC_STRING__EMPTY);
|
||||
|
||||
jerry_module_t *module_p = jerry_object_get_native_ptr (referrer, &jerry_module_native_info);
|
||||
|
||||
if (module_p != NULL)
|
||||
{
|
||||
directory_p = module_p->path_p;
|
||||
directory_size = module_p->basename_offset;
|
||||
}
|
||||
|
||||
jerry_size_t specifier_size = jerry_string_size (specifier, JERRY_ENCODING_UTF8);
|
||||
jerry_size_t reference_size = directory_size + specifier_size;
|
||||
jerry_char_t *reference_path_p = jerry_heap_alloc (reference_size + 1);
|
||||
|
||||
memcpy (reference_path_p, directory_p, directory_size);
|
||||
jerry_string_to_buffer (specifier, JERRY_ENCODING_UTF8, reference_path_p + directory_size, specifier_size);
|
||||
reference_path_p[reference_size] = '\0';
|
||||
|
||||
jerry_char_t *path_p = jerry_port_path_normalize (reference_path_p, reference_size);
|
||||
jerry_heap_free (reference_path_p, reference_size + 1);
|
||||
|
||||
if (path_p == NULL)
|
||||
{
|
||||
return jerry_throw_sz (JERRY_ERROR_SYNTAX, "Failed to resolve module");
|
||||
}
|
||||
|
||||
jerry_value_t realm = jerry_current_realm ();
|
||||
|
||||
jerry_module_manager_t *manager_p;
|
||||
manager_p = (jerry_module_manager_t *) jerry_context_data (&jerry_module_manager);
|
||||
|
||||
module_p = manager_p->module_head_p;
|
||||
|
||||
while (module_p != NULL)
|
||||
{
|
||||
if (module_p->realm == realm && strcmp ((const char *) module_p->path_p, (const char *) path_p) == 0)
|
||||
{
|
||||
jerry_value_free (realm);
|
||||
jerry_port_path_free (path_p);
|
||||
return jerry_value_copy (module_p->module);
|
||||
}
|
||||
|
||||
module_p = module_p->next_p;
|
||||
}
|
||||
|
||||
jerry_size_t source_size;
|
||||
jerry_char_t *source_p = jerry_port_source_read ((const char *) path_p, &source_size);
|
||||
|
||||
if (source_p == NULL)
|
||||
{
|
||||
jerry_value_free (realm);
|
||||
jerry_port_path_free (path_p);
|
||||
|
||||
return jerry_throw_sz (JERRY_ERROR_SYNTAX, "Module file not found");
|
||||
}
|
||||
|
||||
jerry_parse_options_t parse_options;
|
||||
parse_options.options = JERRY_PARSE_MODULE | JERRY_PARSE_HAS_SOURCE_NAME;
|
||||
parse_options.source_name = jerry_value_copy (specifier);
|
||||
|
||||
jerry_value_t ret_value = jerry_parse (source_p, source_size, &parse_options);
|
||||
jerry_value_free (parse_options.source_name);
|
||||
|
||||
jerry_port_source_free (source_p);
|
||||
|
||||
if (jerry_value_is_exception (ret_value))
|
||||
{
|
||||
jerry_port_path_free (path_p);
|
||||
jerry_value_free (realm);
|
||||
return ret_value;
|
||||
}
|
||||
|
||||
module_p = (jerry_module_t *) jerry_heap_alloc (sizeof (jerry_module_t));
|
||||
|
||||
module_p->next_p = manager_p->module_head_p;
|
||||
module_p->path_p = path_p;
|
||||
module_p->basename_offset = jerry_port_path_base (module_p->path_p);
|
||||
module_p->realm = realm;
|
||||
module_p->module = jerry_value_copy (ret_value);
|
||||
|
||||
jerry_object_set_native_ptr (ret_value, &jerry_module_native_info, module_p);
|
||||
manager_p->module_head_p = module_p;
|
||||
|
||||
return ret_value;
|
||||
#else /* JERRY_MODULE_SYSTEM */
|
||||
JERRY_UNUSED (specifier);
|
||||
JERRY_UNUSED (referrer);
|
||||
JERRY_UNUSED (user_p);
|
||||
|
||||
return jerry_throw_sz (JERRY_ERROR_TYPE, ecma_get_error_msg (ECMA_ERR_MODULE_NOT_SUPPORTED));
|
||||
#endif /* JERRY_MODULE_SYSTEM */
|
||||
} /* jerry_module_resolve */
|
||||
|
||||
/**
|
||||
* Release known modules.
|
||||
*/
|
||||
void
|
||||
jerry_module_cleanup (const jerry_value_t realm) /**< if this argument is object, release only those modules,
|
||||
* which realm value is equal to this argument. */
|
||||
{
|
||||
#if JERRY_MODULE_SYSTEM
|
||||
jerry_module_free ((jerry_module_manager_t *) jerry_context_data (&jerry_module_manager), realm);
|
||||
#else /* JERRY_MODULE_SYSTEM */
|
||||
JERRY_UNUSED (realm);
|
||||
#endif /* JERRY_MODULE_SYSTEM */
|
||||
} /* jerry_module_cleanup */
|
||||
@ -576,7 +576,7 @@ snapshot_load_compiled_code (const uint8_t *base_addr_p, /**< base address of th
|
||||
if (JERRY_UNLIKELY (script_p->refs_and_type >= CBC_SCRIPT_REF_MAX))
|
||||
{
|
||||
/* This is probably never happens in practice. */
|
||||
jerry_fatal (ERR_REF_COUNT_LIMIT);
|
||||
jerry_fatal (JERRY_FATAL_REF_COUNT_LIMIT);
|
||||
}
|
||||
|
||||
script_p->refs_and_type += CBC_SCRIPT_REF_ONE;
|
||||
|
||||
@ -16,6 +16,7 @@
|
||||
#include "jerryscript.h"
|
||||
|
||||
#include <math.h>
|
||||
#include <stdarg.h>
|
||||
#include <stdio.h>
|
||||
|
||||
#include "jerryscript-debugger-transport.h"
|
||||
@ -54,6 +55,7 @@
|
||||
#include "debugger.h"
|
||||
#include "jcontext.h"
|
||||
#include "jmem.h"
|
||||
#include "jrt.h"
|
||||
#include "js-parser.h"
|
||||
#include "lit-char-helpers.h"
|
||||
#include "opcodes.h"
|
||||
@ -166,13 +168,24 @@ jerry_return (const jerry_value_t value) /**< return value */
|
||||
void
|
||||
jerry_init (jerry_init_flag_t flags) /**< combination of Jerry flags */
|
||||
{
|
||||
/* This function cannot be called twice unless jerry_cleanup is called. */
|
||||
JERRY_ASSERT (!(JERRY_CONTEXT (status_flags) & ECMA_STATUS_API_ENABLED));
|
||||
#if JERRY_EXTERNAL_CONTEXT
|
||||
size_t total_size = jerry_port_context_alloc (sizeof (jerry_context_t));
|
||||
JERRY_UNUSED (total_size);
|
||||
#endif /* JERRY_EXTERNAL_CONTEXT */
|
||||
|
||||
/* Zero out all non-external members. */
|
||||
memset ((char *) &JERRY_CONTEXT_STRUCT + offsetof (jerry_context_t, JERRY_CONTEXT_FIRST_MEMBER),
|
||||
0,
|
||||
sizeof (jerry_context_t) - offsetof (jerry_context_t, JERRY_CONTEXT_FIRST_MEMBER));
|
||||
jerry_context_t *context_p = &JERRY_CONTEXT_STRUCT;
|
||||
memset (context_p, 0, sizeof (jerry_context_t));
|
||||
|
||||
#if JERRY_EXTERNAL_CONTEXT && !JERRY_SYSTEM_ALLOCATOR
|
||||
uint32_t heap_start_offset = JERRY_ALIGNUP (sizeof (jerry_context_t), JMEM_ALIGNMENT);
|
||||
uint8_t *heap_p = ((uint8_t *) context_p) + heap_start_offset;
|
||||
uint32_t heap_size = JERRY_ALIGNDOWN (total_size - heap_start_offset, JMEM_ALIGNMENT);
|
||||
|
||||
JERRY_ASSERT (heap_p + heap_size <= ((uint8_t *) context_p) + total_size);
|
||||
|
||||
context_p->heap_p = (jmem_heap_t *) heap_p;
|
||||
context_p->heap_size = heap_size;
|
||||
#endif /* JERRY_EXTERNAL_CONTEXT && !JERRY_SYSTEM_ALLOCATOR */
|
||||
|
||||
JERRY_CONTEXT (jerry_init_flags) = flags;
|
||||
|
||||
@ -218,15 +231,20 @@ jerry_cleanup (void)
|
||||
this_p = next_p)
|
||||
{
|
||||
next_p = this_p->next_p;
|
||||
|
||||
if (this_p->manager_p->finalize_cb)
|
||||
{
|
||||
void *data = (this_p->manager_p->bytes_needed > 0) ? JERRY_CONTEXT_DATA_HEADER_USER_DATA (this_p) : NULL;
|
||||
this_p->manager_p->finalize_cb (data);
|
||||
}
|
||||
|
||||
jmem_heap_free_block (this_p, sizeof (jerry_context_data_header_t) + this_p->manager_p->bytes_needed);
|
||||
}
|
||||
|
||||
jmem_finalize ();
|
||||
#if JERRY_EXTERNAL_CONTEXT
|
||||
jerry_port_context_free ();
|
||||
#endif /* JERRY_EXTERNAL_CONTEXT */
|
||||
} /* jerry_cleanup */
|
||||
|
||||
/**
|
||||
@ -574,7 +592,7 @@ jerry_eval (const jerry_char_t *source_p, /**< source code */
|
||||
jerry_value_t
|
||||
jerry_module_link (const jerry_value_t module, /**< root module */
|
||||
jerry_module_resolve_cb_t callback, /**< resolve module callback, uses
|
||||
* jerry_port_module_resolve when NULL is passed */
|
||||
* jerry_module_resolve when NULL is passed */
|
||||
void *user_p) /**< pointer passed to the resolve callback */
|
||||
{
|
||||
jerry_assert_api_enabled ();
|
||||
@ -582,7 +600,7 @@ jerry_module_link (const jerry_value_t module, /**< root module */
|
||||
#if JERRY_MODULE_SYSTEM
|
||||
if (callback == NULL)
|
||||
{
|
||||
callback = jerry_port_module_resolve;
|
||||
callback = jerry_module_resolve;
|
||||
}
|
||||
|
||||
ecma_module_t *module_p = ecma_module_get_resolved_module (module);
|
||||
@ -3010,7 +3028,7 @@ jerry_string_substr (const jerry_value_t value, jerry_length_t start, jerry_leng
|
||||
} /* jerry_string_substr */
|
||||
|
||||
/**
|
||||
* Iterate over the input string value in the specified encoding, visiting each byte of the encoded string once. If
|
||||
* Iterate over the input string value in the specified encoding, visiting each unit of the encoded string once. If
|
||||
* the input value is not a string, the function will do nothing.
|
||||
*
|
||||
* @param value the input string value
|
||||
@ -3080,45 +3098,6 @@ jerry_string_iterate (const jerry_value_t value,
|
||||
ECMA_FINALIZE_UTF8_STRING (buffer_p, buffer_size);
|
||||
} /* jerry_string_iterate */
|
||||
|
||||
/**
|
||||
* Print char wrapper that casts the argument to an unsigned type
|
||||
*
|
||||
* @param byte encoded byte value
|
||||
* @param user_p user pointer
|
||||
*/
|
||||
static void
|
||||
jerry_print_char_wrapper (uint8_t byte, void *user_p)
|
||||
{
|
||||
JERRY_UNUSED (user_p);
|
||||
static const char *const null_str_p = "\\u0000";
|
||||
|
||||
if (JERRY_UNLIKELY (byte == '\0'))
|
||||
{
|
||||
const char *curr_p = null_str_p;
|
||||
|
||||
while (*curr_p != '\0')
|
||||
{
|
||||
jerry_port_print_char (*curr_p++);
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
jerry_port_print_char ((char) byte);
|
||||
} /* jerry_print_char_wrapper */
|
||||
|
||||
/**
|
||||
* Print the argument string in utf8 encoding using jerry_port_print_char.
|
||||
* If the argument is not a string, the function does nothing.
|
||||
*
|
||||
* @param value the input string value
|
||||
*/
|
||||
void
|
||||
jerry_string_print (const jerry_value_t value)
|
||||
{
|
||||
jerry_string_iterate (value, JERRY_ENCODING_UTF8, &jerry_print_char_wrapper, NULL);
|
||||
} /* jerry_string_print */
|
||||
|
||||
/**
|
||||
* Sets the global callback which is called when an external string is freed.
|
||||
*/
|
||||
@ -3195,6 +3174,25 @@ jerry_object_has (const jerry_value_t object, /**< object value */
|
||||
return jerry_return (ecma_op_object_has_property (obj_p, prop_name_p));
|
||||
} /* jerry_object_has */
|
||||
|
||||
/**
|
||||
* Checks whether the object or it's prototype objects have the given property.
|
||||
*
|
||||
* @return raised error - if the operation fail
|
||||
* true/false API value - depend on whether the property exists
|
||||
*/
|
||||
jerry_value_t
|
||||
jerry_object_has_sz (const jerry_value_t object, /**< object value */
|
||||
const char *key_p) /**< property key */
|
||||
{
|
||||
jerry_assert_api_enabled ();
|
||||
|
||||
jerry_value_t key_str = jerry_string_sz (key_p);
|
||||
jerry_value_t result = jerry_object_has (object, key_str);
|
||||
ecma_free_value (key_str);
|
||||
|
||||
return result;
|
||||
} /* jerry_object_has */
|
||||
|
||||
/**
|
||||
* Checks whether the object has the given property.
|
||||
*
|
||||
@ -3264,7 +3262,7 @@ jerry_object_has_internal (const jerry_value_t object, /**< object value */
|
||||
* exception - otherwise
|
||||
*/
|
||||
jerry_value_t
|
||||
jerry_object_delete (const jerry_value_t object, /**< object value */
|
||||
jerry_object_delete (jerry_value_t object, /**< object value */
|
||||
const jerry_value_t key) /**< property name (string value) */
|
||||
{
|
||||
jerry_assert_api_enabled ();
|
||||
@ -3277,6 +3275,25 @@ jerry_object_delete (const jerry_value_t object, /**< object value */
|
||||
return ecma_op_object_delete (ecma_get_object_from_value (object), ecma_get_prop_name_from_value (key), false);
|
||||
} /* jerry_object_delete */
|
||||
|
||||
/**
|
||||
* Delete a property from an object.
|
||||
*
|
||||
* @return boolean value - wether the property was deleted successfully
|
||||
* exception - otherwise
|
||||
*/
|
||||
jerry_value_t
|
||||
jerry_object_delete_sz (jerry_value_t object, /**< object value */
|
||||
const char *key_p) /**< property key */
|
||||
{
|
||||
jerry_assert_api_enabled ();
|
||||
|
||||
jerry_value_t key_str = jerry_string_sz (key_p);
|
||||
jerry_value_t result = jerry_object_delete (object, key_str);
|
||||
ecma_free_value (key_str);
|
||||
|
||||
return result;
|
||||
} /* jerry_object_delete */
|
||||
|
||||
/**
|
||||
* Delete indexed property from the specified object.
|
||||
*
|
||||
@ -3284,7 +3301,7 @@ jerry_object_delete (const jerry_value_t object, /**< object value */
|
||||
* false - otherwise
|
||||
*/
|
||||
jerry_value_t
|
||||
jerry_object_delete_index (const jerry_value_t object, /**< object value */
|
||||
jerry_object_delete_index (jerry_value_t object, /**< object value */
|
||||
uint32_t index) /**< index to be written */
|
||||
{
|
||||
jerry_assert_api_enabled ();
|
||||
@ -3308,7 +3325,7 @@ jerry_object_delete_index (const jerry_value_t object, /**< object value */
|
||||
* false - otherwise
|
||||
*/
|
||||
bool
|
||||
jerry_object_delete_internal (const jerry_value_t object, /**< object value */
|
||||
jerry_object_delete_internal (jerry_value_t object, /**< object value */
|
||||
const jerry_value_t key) /**< property name value */
|
||||
{
|
||||
jerry_assert_api_enabled ();
|
||||
@ -3372,6 +3389,28 @@ jerry_object_get (const jerry_value_t object, /**< object value */
|
||||
return jerry_return (ret_value);
|
||||
} /* jerry_object_get */
|
||||
|
||||
/**
|
||||
* Get value of a property to the specified object with the given name.
|
||||
*
|
||||
* Note:
|
||||
* returned value must be freed with jerry_value_free, when it is no longer needed.
|
||||
*
|
||||
* @return value of the property - if success
|
||||
* value marked with error flag - otherwise
|
||||
*/
|
||||
jerry_value_t
|
||||
jerry_object_get_sz (const jerry_value_t object, /**< object value */
|
||||
const char *key_p) /**< property key */
|
||||
{
|
||||
jerry_assert_api_enabled ();
|
||||
|
||||
jerry_value_t key_str = jerry_string_sz (key_p);
|
||||
jerry_value_t result = jerry_object_get (object, key_str);
|
||||
ecma_free_value (key_str);
|
||||
|
||||
return result;
|
||||
} /* jerry_object_get */
|
||||
|
||||
/**
|
||||
* Get value by an index from the specified object.
|
||||
*
|
||||
@ -3513,7 +3552,7 @@ jerry_object_get_internal (const jerry_value_t object, /**< object value */
|
||||
* value marked with error flag - otherwise
|
||||
*/
|
||||
jerry_value_t
|
||||
jerry_object_set (const jerry_value_t object, /**< object value */
|
||||
jerry_object_set (jerry_value_t object, /**< object value */
|
||||
const jerry_value_t key, /**< property name (string value) */
|
||||
const jerry_value_t value) /**< value to set */
|
||||
{
|
||||
@ -3528,6 +3567,29 @@ jerry_object_set (const jerry_value_t object, /**< object value */
|
||||
ecma_op_object_put (ecma_get_object_from_value (object), ecma_get_prop_name_from_value (key), value, true));
|
||||
} /* jerry_object_set */
|
||||
|
||||
/**
|
||||
* Set a property to the specified object with the given name.
|
||||
*
|
||||
* Note:
|
||||
* returned value must be freed with jerry_value_free, when it is no longer needed.
|
||||
*
|
||||
* @return true value - if the operation was successful
|
||||
* value marked with error flag - otherwise
|
||||
*/
|
||||
jerry_value_t
|
||||
jerry_object_set_sz (jerry_value_t object, /**< object value */
|
||||
const char *key_p, /**< property key */
|
||||
const jerry_value_t value) /**< value to set */
|
||||
{
|
||||
jerry_assert_api_enabled ();
|
||||
|
||||
jerry_value_t key_str = jerry_string_sz (key_p);
|
||||
jerry_value_t result = jerry_object_set (object, key_str, value);
|
||||
ecma_free_value (key_str);
|
||||
|
||||
return result;
|
||||
} /* jerry_object_set */
|
||||
|
||||
/**
|
||||
* Set indexed value in the specified object
|
||||
*
|
||||
@ -3538,7 +3600,7 @@ jerry_object_set (const jerry_value_t object, /**< object value */
|
||||
* value marked with error flag - otherwise
|
||||
*/
|
||||
jerry_value_t
|
||||
jerry_object_set_index (const jerry_value_t object, /**< object value */
|
||||
jerry_object_set_index (jerry_value_t object, /**< object value */
|
||||
uint32_t index, /**< index to be written */
|
||||
const jerry_value_t value) /**< value to set */
|
||||
{
|
||||
@ -3565,7 +3627,7 @@ jerry_object_set_index (const jerry_value_t object, /**< object value */
|
||||
* value marked with error flag - otherwise
|
||||
*/
|
||||
bool
|
||||
jerry_object_set_internal (const jerry_value_t object, /**< object value */
|
||||
jerry_object_set_internal (jerry_value_t object, /**< object value */
|
||||
const jerry_value_t key, /**< property name value */
|
||||
const jerry_value_t value) /**< value to set */
|
||||
{
|
||||
@ -3807,7 +3869,7 @@ jerry_type_error_or_false (ecma_error_msg_t msg, /**< message */
|
||||
* value marked with error flag - otherwise
|
||||
*/
|
||||
jerry_value_t
|
||||
jerry_object_define_own_prop (const jerry_value_t object, /**< object value */
|
||||
jerry_object_define_own_prop (jerry_value_t object, /**< object value */
|
||||
const jerry_value_t key, /**< property name (string value) */
|
||||
const jerry_property_descriptor_t *prop_desc_p) /**< property descriptor */
|
||||
{
|
||||
@ -4083,7 +4145,7 @@ jerry_object_proto (const jerry_value_t object) /**< object value */
|
||||
* value marked with error flag - otherwise
|
||||
*/
|
||||
jerry_value_t
|
||||
jerry_object_set_proto (const jerry_value_t object, /**< object value */
|
||||
jerry_object_set_proto (jerry_value_t object, /**< object value */
|
||||
const jerry_value_t proto) /**< prototype object value */
|
||||
{
|
||||
jerry_assert_api_enabled ();
|
||||
@ -4259,7 +4321,7 @@ jerry_object_get_native_ptr (const jerry_value_t object, /**< object to get nati
|
||||
* a NULL value deletes the current type info.
|
||||
*/
|
||||
void
|
||||
jerry_object_set_native_ptr (const jerry_value_t object, /**< object to set native pointer in */
|
||||
jerry_object_set_native_ptr (jerry_value_t object, /**< object to set native pointer in */
|
||||
const jerry_object_native_info_t *native_info_p, /**< object's native type info */
|
||||
void *native_pointer_p) /**< native pointer */
|
||||
{
|
||||
@ -4310,7 +4372,7 @@ jerry_object_has_native_ptr (const jerry_value_t object, /**< object to set nati
|
||||
* false - otherwise
|
||||
*/
|
||||
bool
|
||||
jerry_object_delete_native_ptr (const jerry_value_t object, /**< object to delete native pointer from */
|
||||
jerry_object_delete_native_ptr (jerry_value_t object, /**< object to delete native pointer from */
|
||||
const jerry_object_native_info_t *native_info_p) /**< object's native type info */
|
||||
{
|
||||
jerry_assert_api_enabled ();
|
||||
@ -4388,7 +4450,7 @@ jerry_native_ptr_free (void *native_pointer_p, /**< a valid non-NULL pointer to
|
||||
void
|
||||
jerry_native_ptr_set (jerry_value_t *reference_p, /**< a valid non-NULL pointer to
|
||||
* a reference in a native buffer. */
|
||||
jerry_value_t value) /**< new value of the reference */
|
||||
const jerry_value_t value) /**< new value of the reference */
|
||||
{
|
||||
jerry_assert_api_enabled ();
|
||||
|
||||
@ -4397,12 +4459,14 @@ jerry_native_ptr_set (jerry_value_t *reference_p, /**< a valid non-NULL pointer
|
||||
return;
|
||||
}
|
||||
|
||||
ecma_free_value_if_not_object (*reference_p);
|
||||
|
||||
if (ecma_is_value_exception (value))
|
||||
{
|
||||
value = ECMA_VALUE_UNDEFINED;
|
||||
*reference_p = ECMA_VALUE_UNDEFINED;
|
||||
return;
|
||||
}
|
||||
|
||||
ecma_free_value_if_not_object (*reference_p);
|
||||
*reference_p = ecma_copy_value_if_not_object (value);
|
||||
} /* jerry_native_ptr_set */
|
||||
|
||||
@ -4957,7 +5021,7 @@ jerry_bigint_digit_count (const jerry_value_t value) /**< BigInt value */
|
||||
* Get the uint64 digits of a BigInt value (lowest digit first)
|
||||
*/
|
||||
void
|
||||
jerry_bigint_to_digits (jerry_value_t value, /**< BigInt value */
|
||||
jerry_bigint_to_digits (const jerry_value_t value, /**< BigInt value */
|
||||
uint64_t *digits_p, /**< [out] buffer for digits */
|
||||
uint32_t digit_count, /**< buffer size in digits */
|
||||
bool *sign_p) /**< [out] sign of BigInt */
|
||||
@ -5080,6 +5144,150 @@ jerry_validate_string (const jerry_char_t *buffer_p, /**< string buffer */
|
||||
}
|
||||
} /* jerry_validate_string */
|
||||
|
||||
/**
|
||||
* Set the log level of the engine.
|
||||
*
|
||||
* Log messages with lower significance than the current log level will be ignored by `jerry_log`.
|
||||
*
|
||||
* @param level: requested log level
|
||||
*/
|
||||
void
|
||||
jerry_log_set_level (jerry_log_level_t level)
|
||||
{
|
||||
JERRY_CONTEXT (log_level) = level;
|
||||
} /* jerry_log_set_level */
|
||||
|
||||
/**
|
||||
* Log buffer size
|
||||
*/
|
||||
#define JERRY_LOG_BUFFER_SIZE 64
|
||||
|
||||
/**
|
||||
* Log a zero-terminated string message.
|
||||
*
|
||||
* @param str_p: message
|
||||
*/
|
||||
static void
|
||||
jerry_log_string (const char *str_p)
|
||||
{
|
||||
jerry_port_log (str_p);
|
||||
|
||||
#if JERRY_DEBUGGER
|
||||
if (jerry_debugger_is_connected ())
|
||||
{
|
||||
jerry_debugger_send_string (JERRY_DEBUGGER_OUTPUT_RESULT,
|
||||
JERRY_DEBUGGER_OUTPUT_LOG,
|
||||
(const uint8_t *) str_p,
|
||||
strlen (str_p));
|
||||
}
|
||||
#endif /* JERRY_DEBUGGER */
|
||||
} /* jerry_log_string */
|
||||
|
||||
/**
|
||||
* Log an unsigned number.
|
||||
*
|
||||
* @param num: number
|
||||
* @param buffer_p: buffer used to construct the number string
|
||||
*/
|
||||
static void
|
||||
jerry_log_unsigned (unsigned int num, char *buffer_p)
|
||||
{
|
||||
char *cursor_p = buffer_p + JERRY_LOG_BUFFER_SIZE;
|
||||
*(--cursor_p) = '\0';
|
||||
|
||||
while (num > 0)
|
||||
{
|
||||
*(--cursor_p) = (char) ((num % 10) + '0');
|
||||
num /= 10;
|
||||
}
|
||||
|
||||
jerry_log_string (cursor_p);
|
||||
} /* jerry_log_unsigned */
|
||||
|
||||
/**
|
||||
* Log a zero-terminated formatted message with the specified log level.
|
||||
*
|
||||
* Supported format specifiers:
|
||||
* %s: zero-terminated string
|
||||
* %c: character
|
||||
* %u: unsigned int
|
||||
*
|
||||
* @param format_p: format string
|
||||
* @param level: message log level
|
||||
*/
|
||||
void
|
||||
jerry_log (jerry_log_level_t level, const char *format_p, ...)
|
||||
{
|
||||
if (level > JERRY_CONTEXT (log_level))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
va_list vl;
|
||||
char buffer_p[JERRY_LOG_BUFFER_SIZE];
|
||||
uint32_t buffer_index = 0;
|
||||
const char *cursor_p = format_p;
|
||||
va_start (vl, format_p);
|
||||
|
||||
while (*cursor_p != '\0')
|
||||
{
|
||||
if (*cursor_p == '%' || buffer_index > JERRY_LOG_BUFFER_SIZE - 2)
|
||||
{
|
||||
buffer_p[buffer_index] = '\0';
|
||||
jerry_log_string (buffer_p);
|
||||
buffer_index = 0;
|
||||
}
|
||||
|
||||
if (*cursor_p != '%')
|
||||
{
|
||||
buffer_p[buffer_index++] = *cursor_p++;
|
||||
continue;
|
||||
}
|
||||
|
||||
++cursor_p;
|
||||
|
||||
if (*cursor_p == '\0')
|
||||
{
|
||||
buffer_p[buffer_index++] = '%';
|
||||
break;
|
||||
}
|
||||
|
||||
switch (*cursor_p++)
|
||||
{
|
||||
case 's':
|
||||
{
|
||||
jerry_log_string (va_arg (vl, char *));
|
||||
break;
|
||||
}
|
||||
case 'c':
|
||||
{
|
||||
/* Arguments of types narrower than int are promoted to int for variadic functions */
|
||||
buffer_p[buffer_index++] = (char) va_arg (vl, int);
|
||||
break;
|
||||
}
|
||||
case 'u':
|
||||
{
|
||||
/* The buffer is always flushed before a substitution, and can be reused to print the number. */
|
||||
jerry_log_unsigned (va_arg (vl, unsigned int), buffer_p);
|
||||
break;
|
||||
}
|
||||
default:
|
||||
{
|
||||
buffer_p[buffer_index++] = '%';
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (buffer_index > 0)
|
||||
{
|
||||
buffer_p[buffer_index] = '\0';
|
||||
jerry_log_string (buffer_p);
|
||||
}
|
||||
|
||||
va_end (vl);
|
||||
} /* jerry_log */
|
||||
|
||||
/**
|
||||
* Allocate memory on the engine's heap.
|
||||
*
|
||||
@ -5111,71 +5319,6 @@ jerry_heap_free (void *mem_p, /**< value returned by jerry_heap_alloc */
|
||||
jmem_heap_free_block (mem_p, size);
|
||||
} /* jerry_heap_free */
|
||||
|
||||
/**
|
||||
* Create an external engine context.
|
||||
*
|
||||
* @return the pointer to the context.
|
||||
*/
|
||||
jerry_context_t *
|
||||
jerry_context_alloc (jerry_size_t heap_size, /**< the size of heap */
|
||||
jerry_context_alloc_cb_t alloc, /**< the alloc function */
|
||||
void *cb_data_p) /**< the cb_data for alloc function */
|
||||
{
|
||||
JERRY_UNUSED (heap_size);
|
||||
|
||||
#if JERRY_EXTERNAL_CONTEXT
|
||||
|
||||
size_t total_size = sizeof (jerry_context_t) + JMEM_ALIGNMENT;
|
||||
|
||||
#if !JERRY_SYSTEM_ALLOCATOR
|
||||
heap_size = JERRY_ALIGNUP (heap_size, JMEM_ALIGNMENT);
|
||||
|
||||
/* Minimum heap size is 1Kbyte. */
|
||||
if (heap_size < 1024)
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
|
||||
total_size += heap_size;
|
||||
#endif /* !JERRY_SYSTEM_ALLOCATOR */
|
||||
|
||||
total_size = JERRY_ALIGNUP (total_size, JMEM_ALIGNMENT);
|
||||
|
||||
jerry_context_t *context_p = (jerry_context_t *) alloc (total_size, cb_data_p);
|
||||
|
||||
if (context_p == NULL)
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
|
||||
memset (context_p, 0, total_size);
|
||||
|
||||
uintptr_t context_ptr = ((uintptr_t) context_p) + sizeof (jerry_context_t);
|
||||
context_ptr = JERRY_ALIGNUP (context_ptr, (uintptr_t) JMEM_ALIGNMENT);
|
||||
|
||||
uint8_t *byte_p = (uint8_t *) context_ptr;
|
||||
|
||||
#if !JERRY_SYSTEM_ALLOCATOR
|
||||
context_p->heap_p = (jmem_heap_t *) byte_p;
|
||||
context_p->heap_size = heap_size;
|
||||
byte_p += heap_size;
|
||||
#endif /* !JERRY_SYSTEM_ALLOCATOR */
|
||||
|
||||
JERRY_ASSERT (byte_p <= ((uint8_t *) context_p) + total_size);
|
||||
|
||||
JERRY_UNUSED (byte_p);
|
||||
return context_p;
|
||||
|
||||
#else /* !JERRY_EXTERNAL_CONTEXT */
|
||||
|
||||
JERRY_UNUSED (alloc);
|
||||
JERRY_UNUSED (cb_data_p);
|
||||
|
||||
return NULL;
|
||||
|
||||
#endif /* JERRY_EXTERNAL_CONTEXT */
|
||||
} /* jerry_context_alloc */
|
||||
|
||||
/**
|
||||
* When JERRY_VM_HALT is enabled, the callback passed to this function
|
||||
* is periodically called with the user_p argument. If interval is greater
|
||||
@ -5790,7 +5933,7 @@ jerry_arraybuffer (const jerry_length_t size) /**< size of the backing store all
|
||||
*/
|
||||
jerry_value_t
|
||||
jerry_arraybuffer_external (uint8_t *buffer_p, /**< the backing store used by the array buffer object */
|
||||
const jerry_length_t size, /**< size of the buffer in bytes */
|
||||
jerry_length_t size, /**< size of the buffer in bytes */
|
||||
void *user_p) /**< user pointer assigned to the array buffer object */
|
||||
{
|
||||
jerry_assert_api_enabled ();
|
||||
@ -5850,8 +5993,8 @@ jerry_value_is_shared_arraybuffer (const jerry_value_t value) /**< value to chec
|
||||
* @return value of the constructed SharedArrayBuffer object
|
||||
*/
|
||||
jerry_value_t
|
||||
jerry_shared_arraybuffer (const jerry_length_t size) /**< size of the backing store allocated
|
||||
* for the shared array buffer in bytes */
|
||||
jerry_shared_arraybuffer (jerry_length_t size) /**< size of the backing store allocated
|
||||
* for the shared array buffer in bytes */
|
||||
{
|
||||
jerry_assert_api_enabled ();
|
||||
|
||||
@ -5877,7 +6020,7 @@ jerry_shared_arraybuffer (const jerry_length_t size) /**< size of the backing st
|
||||
jerry_value_t
|
||||
jerry_shared_arraybuffer_external (uint8_t *buffer_p, /**< the backing store used by the
|
||||
* shared array buffer object */
|
||||
const jerry_length_t size, /**< size of the buffer in bytes */
|
||||
jerry_length_t size, /**< size of the buffer in bytes */
|
||||
void *user_p) /**< user pointer assigned to the
|
||||
* shared array buffer object */
|
||||
{
|
||||
@ -5945,7 +6088,7 @@ jerry_arraybuffer_allocate_buffer_no_throw (ecma_object_t *arraybuffer_p) /**< A
|
||||
* @return number of bytes copied into the ArrayBuffer or SharedArrayBuffer.
|
||||
*/
|
||||
jerry_length_t
|
||||
jerry_arraybuffer_write (const jerry_value_t value, /**< target ArrayBuffer or SharedArrayBuffer */
|
||||
jerry_arraybuffer_write (jerry_value_t value, /**< target ArrayBuffer or SharedArrayBuffer */
|
||||
jerry_length_t offset, /**< start offset of the ArrayBuffer */
|
||||
const uint8_t *buf_p, /**< buffer to copy from */
|
||||
jerry_length_t buf_size) /**< number of bytes to copy from the buffer */
|
||||
@ -6145,7 +6288,7 @@ jerry_arraybuffer_is_detachable (const jerry_value_t value) /**< ArrayBuffer */
|
||||
* value marked with error flag - otherwise
|
||||
*/
|
||||
jerry_value_t
|
||||
jerry_arraybuffer_detach (const jerry_value_t value) /**< ArrayBuffer */
|
||||
jerry_arraybuffer_detach (jerry_value_t value) /**< ArrayBuffer */
|
||||
{
|
||||
jerry_assert_api_enabled ();
|
||||
|
||||
@ -6207,8 +6350,8 @@ jerry_arraybuffer_has_buffer (const jerry_value_t value) /**< array buffer or ty
|
||||
* are not called for these array buffers. The default limit is 256 bytes.
|
||||
*/
|
||||
void
|
||||
jerry_arraybuffer_heap_allocation_limit (const jerry_length_t allocation_limit) /**< maximum size of
|
||||
* compact allocation */
|
||||
jerry_arraybuffer_heap_allocation_limit (jerry_length_t allocation_limit) /**< maximum size of
|
||||
* compact allocation */
|
||||
{
|
||||
jerry_assert_api_enabled ();
|
||||
|
||||
@ -6258,8 +6401,8 @@ jerry_arraybuffer_allocator (jerry_arraybuffer_allocate_cb_t allocate_callback,
|
||||
*/
|
||||
jerry_value_t
|
||||
jerry_dataview (const jerry_value_t array_buffer, /**< arraybuffer to create DataView from */
|
||||
const jerry_length_t byte_offset, /**< offset in bytes, to the first byte in the buffer */
|
||||
const jerry_length_t byte_length) /**< number of elements in the byte array */
|
||||
jerry_length_t byte_offset, /**< offset in bytes, to the first byte in the buffer */
|
||||
jerry_length_t byte_length) /**< number of elements in the byte array */
|
||||
{
|
||||
jerry_assert_api_enabled ();
|
||||
|
||||
@ -6373,7 +6516,7 @@ jerry_dataview_buffer (const jerry_value_t value, /**< DataView to get the array
|
||||
* false - otherwise
|
||||
*/
|
||||
bool
|
||||
jerry_value_is_typedarray (jerry_value_t value) /**< value to check if it is a TypedArray */
|
||||
jerry_value_is_typedarray (const jerry_value_t value) /**< value to check if it is a TypedArray */
|
||||
{
|
||||
jerry_assert_api_enabled ();
|
||||
|
||||
@ -6584,7 +6727,7 @@ jerry_typedarray_with_buffer (jerry_typedarray_type_t type, /**< type of TypedAr
|
||||
* - JERRY_TYPEDARRAY_INVALID if the argument is not a TypedArray
|
||||
*/
|
||||
jerry_typedarray_type_t
|
||||
jerry_typedarray_type (jerry_value_t value) /**< object to get the TypedArray type */
|
||||
jerry_typedarray_type (const jerry_value_t value) /**< object to get the TypedArray type */
|
||||
{
|
||||
jerry_assert_api_enabled ();
|
||||
|
||||
@ -6617,7 +6760,7 @@ jerry_typedarray_type (jerry_value_t value) /**< object to get the TypedArray ty
|
||||
* @return length of the TypedArray.
|
||||
*/
|
||||
jerry_length_t
|
||||
jerry_typedarray_length (jerry_value_t value) /**< TypedArray to query */
|
||||
jerry_typedarray_length (const jerry_value_t value) /**< TypedArray to query */
|
||||
{
|
||||
jerry_assert_api_enabled ();
|
||||
|
||||
@ -6647,7 +6790,7 @@ jerry_typedarray_length (jerry_value_t value) /**< TypedArray to query */
|
||||
* TypeError if the object is not a TypedArray.
|
||||
*/
|
||||
jerry_value_t
|
||||
jerry_typedarray_buffer (jerry_value_t value, /**< TypedArray to get the arraybuffer from */
|
||||
jerry_typedarray_buffer (const jerry_value_t value, /**< TypedArray to get the arraybuffer from */
|
||||
jerry_length_t *byte_offset, /**< [out] byteOffset property */
|
||||
jerry_length_t *byte_length) /**< [out] byteLength property */
|
||||
{
|
||||
@ -6892,7 +7035,7 @@ jerry_container_type (const jerry_value_t value) /**< the container object */
|
||||
* @return an array of items for maps/sets or their iterators, error otherwise
|
||||
*/
|
||||
jerry_value_t
|
||||
jerry_container_to_array (jerry_value_t value, /**< the container or iterator object */
|
||||
jerry_container_to_array (const jerry_value_t value, /**< the container or iterator object */
|
||||
bool *is_key_value_p) /**< [out] is key-value structure */
|
||||
{
|
||||
jerry_assert_api_enabled ();
|
||||
|
||||
@ -227,11 +227,8 @@ typedef enum
|
||||
*/
|
||||
typedef enum
|
||||
{
|
||||
JERRY_DEBUGGER_OUTPUT_OK = 1, /**< output result, no error */
|
||||
JERRY_DEBUGGER_OUTPUT_ERROR = 2, /**< output result, error */
|
||||
JERRY_DEBUGGER_OUTPUT_WARNING = 3, /**< output result, warning */
|
||||
JERRY_DEBUGGER_OUTPUT_DEBUG = 4, /**< output result, debug */
|
||||
JERRY_DEBUGGER_OUTPUT_TRACE = 5, /**< output result, trace */
|
||||
JERRY_DEBUGGER_OUTPUT_PRINT = 1, /**< printed output */
|
||||
JERRY_DEBUGGER_OUTPUT_LOG = 2, /**< logged output */
|
||||
} jerry_debugger_output_subtype_t;
|
||||
|
||||
/**
|
||||
|
||||
@ -139,7 +139,7 @@ ecma_ref_object_inline (ecma_object_t *object_p) /**< object */
|
||||
}
|
||||
else
|
||||
{
|
||||
jerry_fatal (ERR_REF_COUNT_LIMIT);
|
||||
jerry_fatal (JERRY_FATAL_REF_COUNT_LIMIT);
|
||||
}
|
||||
} /* ecma_ref_object_inline */
|
||||
|
||||
@ -2287,7 +2287,7 @@ ecma_gc_run (void)
|
||||
/**
|
||||
* Try to free some memory (depending on memory pressure).
|
||||
*
|
||||
* When called with JMEM_PRESSURE_FULL, the engine will be terminated with ERR_OUT_OF_MEMORY.
|
||||
* When called with JMEM_PRESSURE_FULL, the engine will be terminated with JERRY_FATAL_OUT_OF_MEMORY.
|
||||
*/
|
||||
void
|
||||
ecma_free_unused_memory (jmem_pressure_t pressure) /**< current pressure */
|
||||
@ -2379,7 +2379,7 @@ ecma_free_unused_memory (jmem_pressure_t pressure) /**< current pressure */
|
||||
}
|
||||
else if (JERRY_UNLIKELY (pressure == JMEM_PRESSURE_FULL))
|
||||
{
|
||||
jerry_fatal (ERR_OUT_OF_MEMORY);
|
||||
jerry_fatal (JERRY_FATAL_OUT_OF_MEMORY);
|
||||
}
|
||||
else
|
||||
{
|
||||
|
||||
@ -748,7 +748,7 @@ ecma_append_chars_to_string (ecma_string_t *string1_p, /**< base ecma-string */
|
||||
/* Poor man's carry flag check: it is impossible to allocate this large string. */
|
||||
if (new_size < (cesu8_string1_size | cesu8_string2_size))
|
||||
{
|
||||
jerry_fatal (ERR_OUT_OF_MEMORY);
|
||||
jerry_fatal (JERRY_FATAL_OUT_OF_MEMORY);
|
||||
}
|
||||
|
||||
lit_magic_string_id_t magic_string_id;
|
||||
@ -880,7 +880,7 @@ ecma_ref_ecma_string_non_direct (ecma_string_t *string_p) /**< string descriptor
|
||||
}
|
||||
else
|
||||
{
|
||||
jerry_fatal (ERR_REF_COUNT_LIMIT);
|
||||
jerry_fatal (JERRY_FATAL_REF_COUNT_LIMIT);
|
||||
}
|
||||
} /* ecma_ref_ecma_string_non_direct */
|
||||
|
||||
|
||||
@ -1246,7 +1246,7 @@ ecma_ref_extended_primitive (ecma_extended_primitive_t *primitve_p) /**< extende
|
||||
}
|
||||
else
|
||||
{
|
||||
jerry_fatal (ERR_REF_COUNT_LIMIT);
|
||||
jerry_fatal (JERRY_FATAL_REF_COUNT_LIMIT);
|
||||
}
|
||||
} /* ecma_ref_extended_primitive */
|
||||
|
||||
@ -1470,7 +1470,7 @@ ecma_bytecode_ref (ecma_compiled_code_t *bytecode_p) /**< byte code pointer */
|
||||
/* Abort program if maximum reference number is reached. */
|
||||
if (bytecode_p->refs >= UINT16_MAX)
|
||||
{
|
||||
jerry_fatal (ERR_REF_COUNT_LIMIT);
|
||||
jerry_fatal (JERRY_FATAL_REF_COUNT_LIMIT);
|
||||
}
|
||||
|
||||
bytecode_p->refs++;
|
||||
|
||||
@ -89,7 +89,7 @@ ecma_finalize (void)
|
||||
ecma_gc_run ();
|
||||
if (++runs >= JERRY_GC_LOOP_LIMIT)
|
||||
{
|
||||
jerry_fatal (ERR_UNTERMINATED_GC_LOOPS);
|
||||
jerry_fatal (JERRY_FATAL_UNTERMINATED_GC_LOOPS);
|
||||
}
|
||||
} while (JERRY_CONTEXT (ecma_gc_new_objects) != 0);
|
||||
|
||||
|
||||
@ -683,7 +683,7 @@ ecma_snapshot_get_literal (const uint8_t *literal_base_p, /**< literal start */
|
||||
|
||||
if (bigint_p == NULL)
|
||||
{
|
||||
jerry_fatal (ERR_OUT_OF_MEMORY);
|
||||
jerry_fatal (JERRY_FATAL_OUT_OF_MEMORY);
|
||||
}
|
||||
|
||||
/* Only the sign bit can differ. */
|
||||
|
||||
@ -297,7 +297,7 @@ ecma_builtin_date_prototype_dispatch_get (uint16_t builtin_routine_id, /**< buil
|
||||
{
|
||||
JERRY_ASSERT (builtin_routine_id == ECMA_DATE_PROTOTYPE_GET_UTC_TIMEZONE_OFFSET);
|
||||
|
||||
result = (int32_t) ((-ecma_date_local_time_zone_adjustment (date_value)) / ECMA_DATE_MS_PER_MINUTE);
|
||||
result = -ecma_date_local_time_zone_adjustment (date_value) / ECMA_DATE_MS_PER_MINUTE;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
@ -698,7 +698,7 @@ ecma_builtin_date_utc (const ecma_value_t args[], /**< arguments list */
|
||||
static ecma_number_t
|
||||
ecma_builtin_date_now_helper (void)
|
||||
{
|
||||
return floor (DOUBLE_TO_ECMA_NUMBER_T (jerry_port_get_current_time ()));
|
||||
return floor (DOUBLE_TO_ECMA_NUMBER_T (jerry_port_current_time ()));
|
||||
} /* ecma_builtin_date_now_helper */
|
||||
|
||||
/**
|
||||
|
||||
@ -271,10 +271,10 @@ ecma_date_week_day (ecma_number_t time) /**< time value */
|
||||
*
|
||||
* @return local time zone adjustment
|
||||
*/
|
||||
extern inline ecma_number_t JERRY_ATTR_ALWAYS_INLINE
|
||||
extern inline int32_t JERRY_ATTR_ALWAYS_INLINE
|
||||
ecma_date_local_time_zone_adjustment (ecma_number_t time) /**< time value */
|
||||
{
|
||||
return jerry_port_get_local_time_zone_adjustment (time, true);
|
||||
return jerry_port_local_tza (time);
|
||||
} /* ecma_date_local_time_zone_adjustment */
|
||||
|
||||
/**
|
||||
@ -288,7 +288,7 @@ ecma_date_local_time_zone_adjustment (ecma_number_t time) /**< time value */
|
||||
ecma_number_t
|
||||
ecma_date_utc (ecma_number_t time) /**< time value */
|
||||
{
|
||||
return time - jerry_port_get_local_time_zone_adjustment (time, false);
|
||||
return time - jerry_port_local_tza (time);
|
||||
} /* ecma_date_utc */
|
||||
|
||||
/**
|
||||
@ -607,7 +607,7 @@ ecma_date_to_string_format (ecma_number_t datetime_number, /**< datetime */
|
||||
}
|
||||
case LIT_CHAR_LOWERCASE_Z: /* Time zone hours part. */
|
||||
{
|
||||
int32_t time_zone = (int32_t) ecma_date_local_time_zone_adjustment (datetime_number);
|
||||
int32_t time_zone = ecma_date_local_time_zone_adjustment (datetime_number);
|
||||
|
||||
if (time_zone >= 0)
|
||||
{
|
||||
@ -627,7 +627,7 @@ ecma_date_to_string_format (ecma_number_t datetime_number, /**< datetime */
|
||||
{
|
||||
JERRY_ASSERT (*format_p == LIT_CHAR_UPPERCASE_Z); /* Time zone minutes part. */
|
||||
|
||||
int32_t time_zone = (int32_t) ecma_date_local_time_zone_adjustment (datetime_number);
|
||||
int32_t time_zone = ecma_date_local_time_zone_adjustment (datetime_number);
|
||||
|
||||
if (time_zone < 0)
|
||||
{
|
||||
|
||||
@ -159,7 +159,7 @@ int32_t ecma_date_sec_from_time (ecma_number_t time);
|
||||
int32_t ecma_date_ms_from_time (ecma_number_t time);
|
||||
int32_t ecma_date_time_in_day_from_time (ecma_number_t time);
|
||||
|
||||
ecma_number_t ecma_date_local_time_zone_adjustment (ecma_number_t time);
|
||||
int32_t ecma_date_local_time_zone_adjustment (ecma_number_t time);
|
||||
ecma_number_t ecma_date_utc (ecma_number_t time);
|
||||
ecma_number_t ecma_date_make_time (ecma_number_t hour, ecma_number_t min, ecma_number_t sec, ecma_number_t ms);
|
||||
ecma_number_t ecma_date_make_day (ecma_number_t year, ecma_number_t month, ecma_number_t date);
|
||||
|
||||
@ -45,6 +45,9 @@ JERRY_C_API_BEGIN
|
||||
#define JERRY_ATTR_NORETURN __attribute__ ((noreturn))
|
||||
#define JERRY_ATTR_PURE __attribute__ ((pure))
|
||||
#define JERRY_ATTR_WARN_UNUSED_RESULT __attribute__ ((warn_unused_result))
|
||||
#define JERRY_ATTR_WEAK __attribute__ ((weak))
|
||||
|
||||
#define JERRY_WEAK_SYMBOL_SUPPORT
|
||||
|
||||
#ifndef JERRY_LIKELY
|
||||
#define JERRY_LIKELY(x) __builtin_expect (!!(x), 1)
|
||||
@ -154,6 +157,13 @@ void *__cdecl _alloca (size_t _Size);
|
||||
#define JERRY_ATTR_WARN_UNUSED_RESULT
|
||||
#endif /* !JERRY_ATTR_WARN_UNUSED_RESULT */
|
||||
|
||||
/**
|
||||
* Function attribute to declare a function a weak symbol
|
||||
*/
|
||||
#ifndef JERRY_ATTR_WEAK
|
||||
#define JERRY_ATTR_WEAK
|
||||
#endif /* !JERRY_ATTR_WEAK */
|
||||
|
||||
/**
|
||||
* Helper to predict that a condition is likely.
|
||||
*/
|
||||
|
||||
@ -37,7 +37,6 @@ JERRY_C_API_BEGIN
|
||||
void jerry_init (jerry_init_flag_t flags);
|
||||
void jerry_cleanup (void);
|
||||
|
||||
jerry_context_t *jerry_context_alloc (jerry_size_t heap_size, jerry_context_alloc_cb_t alloc, void *cb_data_p);
|
||||
void *jerry_context_data (const jerry_context_data_manager_t *manager_p);
|
||||
|
||||
jerry_value_t jerry_current_realm (void);
|
||||
@ -69,8 +68,10 @@ bool jerry_foreach_live_object_with_info (const jerry_object_native_info_t *nati
|
||||
* @{
|
||||
*/
|
||||
|
||||
void JERRY_ATTR_FORMAT (printf, 2, 3) jerry_log (jerry_log_level_t level, const char *format_p, ...);
|
||||
void jerry_log_set_level (jerry_log_level_t level);
|
||||
bool jerry_validate_string (const jerry_char_t *buffer_p, jerry_size_t buffer_size, jerry_encoding_t encoding);
|
||||
bool jerry_feature_enabled (const jerry_feature_t feature);
|
||||
bool JERRY_ATTR_CONST jerry_feature_enabled (const jerry_feature_t feature);
|
||||
void jerry_register_magic_strings (const jerry_char_t *const *ext_strings_p,
|
||||
uint32_t count,
|
||||
const jerry_length_t *str_lengths_p);
|
||||
@ -171,7 +172,7 @@ bool jerry_frame_is_strict (jerry_frame_t *frame_p);
|
||||
*/
|
||||
|
||||
/* Reference management */
|
||||
jerry_value_t jerry_value_copy (const jerry_value_t value);
|
||||
jerry_value_t JERRY_ATTR_WARN_UNUSED_RESULT jerry_value_copy (const jerry_value_t value);
|
||||
void jerry_value_free (jerry_value_t value);
|
||||
|
||||
/**
|
||||
@ -256,8 +257,8 @@ jerry_value_t jerry_binary_op (jerry_binary_op_t operation, const jerry_value_t
|
||||
*/
|
||||
jerry_value_t jerry_throw (jerry_error_t type, const jerry_value_t message);
|
||||
jerry_value_t jerry_throw_sz (jerry_error_t type, const char *message_p);
|
||||
jerry_value_t jerry_throw_value (const jerry_value_t value, bool take_ownership);
|
||||
jerry_value_t jerry_throw_abort (const jerry_value_t value, bool take_ownership);
|
||||
jerry_value_t jerry_throw_value (jerry_value_t value, bool take_ownership);
|
||||
jerry_value_t jerry_throw_abort (jerry_value_t value, bool take_ownership);
|
||||
/**
|
||||
* jerry-api-exception-ctor @}
|
||||
*/
|
||||
@ -309,7 +310,7 @@ void jerry_on_throw (jerry_throw_cb_t callback, void *user_p);
|
||||
* @{
|
||||
*/
|
||||
|
||||
jerry_value_t jerry_undefined (void);
|
||||
jerry_value_t JERRY_ATTR_CONST jerry_undefined (void);
|
||||
|
||||
/**
|
||||
* jerry-api-undefined-ctor @}
|
||||
@ -329,7 +330,7 @@ jerry_value_t jerry_undefined (void);
|
||||
* @{
|
||||
*/
|
||||
|
||||
jerry_value_t jerry_null (void);
|
||||
jerry_value_t JERRY_ATTR_CONST jerry_null (void);
|
||||
|
||||
/**
|
||||
* jerry-api-null-ctor @}
|
||||
@ -349,7 +350,7 @@ jerry_value_t jerry_null (void);
|
||||
* @{
|
||||
*/
|
||||
|
||||
jerry_value_t jerry_boolean (bool value);
|
||||
jerry_value_t JERRY_ATTR_CONST jerry_boolean (bool value);
|
||||
|
||||
/**
|
||||
* jerry-api-boolean-ctor @}
|
||||
@ -458,7 +459,6 @@ void jerry_string_iterate (const jerry_value_t value,
|
||||
jerry_encoding_t encoding,
|
||||
jerry_string_iterate_cb_t callback,
|
||||
void *user_p);
|
||||
void jerry_string_print (const jerry_value_t value);
|
||||
/**
|
||||
* jerry-api-string-op @}
|
||||
*/
|
||||
@ -550,6 +550,7 @@ bool jerry_object_foreach (const jerry_value_t object, jerry_object_property_for
|
||||
* @{
|
||||
*/
|
||||
jerry_value_t jerry_object_set (jerry_value_t object, const jerry_value_t key, const jerry_value_t value);
|
||||
jerry_value_t jerry_object_set_sz (jerry_value_t object, const char *key_p, const jerry_value_t value);
|
||||
jerry_value_t jerry_object_set_index (jerry_value_t object, uint32_t index, const jerry_value_t value);
|
||||
jerry_value_t jerry_object_define_own_prop (jerry_value_t object,
|
||||
const jerry_value_t key,
|
||||
@ -567,6 +568,7 @@ void jerry_object_set_native_ptr (jerry_value_t object,
|
||||
* @{
|
||||
*/
|
||||
jerry_value_t jerry_object_has (const jerry_value_t object, const jerry_value_t key);
|
||||
jerry_value_t jerry_object_has_sz (const jerry_value_t object, const char *key_p);
|
||||
jerry_value_t jerry_object_has_own (const jerry_value_t object, const jerry_value_t key);
|
||||
bool jerry_object_has_internal (const jerry_value_t object, const jerry_value_t key);
|
||||
bool jerry_object_has_native_ptr (const jerry_value_t object, const jerry_object_native_info_t *native_info_p);
|
||||
@ -579,6 +581,7 @@ bool jerry_object_has_native_ptr (const jerry_value_t object, const jerry_object
|
||||
* @{
|
||||
*/
|
||||
jerry_value_t jerry_object_get (const jerry_value_t object, const jerry_value_t key);
|
||||
jerry_value_t jerry_object_get_sz (const jerry_value_t object, const char *key_p);
|
||||
jerry_value_t jerry_object_get_index (const jerry_value_t object, uint32_t index);
|
||||
jerry_value_t jerry_object_get_own_prop (const jerry_value_t object,
|
||||
const jerry_value_t key,
|
||||
@ -599,6 +602,7 @@ jerry_value_t jerry_object_find_own (const jerry_value_t object,
|
||||
* @{
|
||||
*/
|
||||
jerry_value_t jerry_object_delete (jerry_value_t object, const jerry_value_t key);
|
||||
jerry_value_t jerry_object_delete_sz (const jerry_value_t object, const char *key_p);
|
||||
jerry_value_t jerry_object_delete_index (jerry_value_t object, uint32_t index);
|
||||
bool jerry_object_delete_internal (jerry_value_t object, const jerry_value_t key);
|
||||
bool jerry_object_delete_native_ptr (jerry_value_t object, const jerry_object_native_info_t *native_info_p);
|
||||
@ -1101,8 +1105,30 @@ jerry_value_t jerry_module_namespace (const jerry_value_t module);
|
||||
* @defgroup jerry-api-module-op Operations
|
||||
* @{
|
||||
*/
|
||||
|
||||
/**
|
||||
* Resolve and parse a module file
|
||||
*
|
||||
* @param specifier: module request specifier string.
|
||||
* @param referrer: parent module.
|
||||
* @param user_p: user specified pointer.
|
||||
*
|
||||
* @return module object if resolving is successful, error otherwise.
|
||||
*/
|
||||
jerry_value_t jerry_module_resolve (const jerry_value_t specifier, const jerry_value_t referrer, void *user_p);
|
||||
|
||||
jerry_value_t jerry_module_link (const jerry_value_t module, jerry_module_resolve_cb_t callback, void *user_p);
|
||||
jerry_value_t jerry_module_evaluate (const jerry_value_t module);
|
||||
|
||||
/**
|
||||
* Release known modules in the current context. If realm parameter is supplied, cleans up modules native to that realm
|
||||
* only. This function should be called by the user application when the module database in the current context is no
|
||||
* longer needed.
|
||||
*
|
||||
* @param realm: release only those modules which realm value is equal to this argument.
|
||||
*/
|
||||
void jerry_module_cleanup (const jerry_value_t realm);
|
||||
|
||||
/**
|
||||
* jerry-api-module-op @}
|
||||
*/
|
||||
@ -1116,7 +1142,7 @@ jerry_value_t jerry_native_module (jerry_native_module_evaluate_cb_t callback,
|
||||
size_t export_count);
|
||||
jerry_value_t jerry_native_module_get (const jerry_value_t native_module, const jerry_value_t export_name);
|
||||
jerry_value_t
|
||||
jerry_native_module_set (const jerry_value_t native_module, const jerry_value_t export_name, const jerry_value_t value);
|
||||
jerry_native_module_set (jerry_value_t native_module, const jerry_value_t export_name, const jerry_value_t value);
|
||||
/**
|
||||
* jerry-api-module-native @}
|
||||
*/
|
||||
|
||||
@ -16,7 +16,7 @@
|
||||
#ifndef JERRYSCRIPT_DEBUGGER_H
|
||||
#define JERRYSCRIPT_DEBUGGER_H
|
||||
|
||||
#include "jerryscript-port.h"
|
||||
#include "jerryscript-types.h"
|
||||
|
||||
JERRY_C_API_BEGIN
|
||||
|
||||
@ -65,7 +65,6 @@ jerry_debugger_wait_for_client_source (jerry_debugger_wait_for_source_callback_t
|
||||
void *user_p,
|
||||
jerry_value_t *return_value);
|
||||
void jerry_debugger_send_output (const jerry_char_t *buffer, jerry_size_t str_size);
|
||||
void jerry_debugger_send_log (jerry_log_level_t level, const jerry_char_t *buffer, jerry_size_t str_size);
|
||||
|
||||
/**
|
||||
* @}
|
||||
|
||||
@ -16,233 +16,301 @@
|
||||
#ifndef JERRYSCRIPT_PORT_H
|
||||
#define JERRYSCRIPT_PORT_H
|
||||
|
||||
#include <stdbool.h>
|
||||
#include <stdint.h>
|
||||
#include <stdio.h>
|
||||
|
||||
#include "jerryscript-types.h"
|
||||
|
||||
JERRY_C_API_BEGIN
|
||||
|
||||
/** \addtogroup jerry_port Jerry engine port
|
||||
/**
|
||||
* @defgroup jerry-port JerryScript Port API
|
||||
* @{
|
||||
*/
|
||||
|
||||
/*
|
||||
* Termination Port API
|
||||
/**
|
||||
* @defgroup jerry-port-process Process management API
|
||||
*
|
||||
* Note:
|
||||
* It is questionable whether a library should be able to terminate an
|
||||
* application. However, as of now, we only have the concept of completion
|
||||
* code around jerry_parse and jerry_run. Most of the other API functions
|
||||
* have no way of signaling an error. So, we keep the termination approach
|
||||
* with this port function.
|
||||
* It is questionable whether a library should be able to terminate an
|
||||
* application. However, as of now, we only have the concept of completion
|
||||
* code around jerry_parse and jerry_run. Most of the other API functions
|
||||
* have no way of signaling an error. So, we keep the termination approach
|
||||
* with this port function.
|
||||
*
|
||||
* @{
|
||||
*/
|
||||
|
||||
/**
|
||||
* Error codes
|
||||
* Error codes that can be passed by the engine when calling jerry_port_fatal
|
||||
*/
|
||||
typedef enum
|
||||
{
|
||||
ERR_OUT_OF_MEMORY = 10,
|
||||
ERR_REF_COUNT_LIMIT = 12,
|
||||
ERR_DISABLED_BYTE_CODE = 13,
|
||||
ERR_UNTERMINATED_GC_LOOPS = 14,
|
||||
ERR_FAILED_INTERNAL_ASSERTION = 120
|
||||
JERRY_FATAL_OUT_OF_MEMORY = 10, /**< Out of memory */
|
||||
JERRY_FATAL_REF_COUNT_LIMIT = 12, /**< Reference count limit reached */
|
||||
JERRY_FATAL_DISABLED_BYTE_CODE = 13, /**< Executed disabled instruction */
|
||||
JERRY_FATAL_UNTERMINATED_GC_LOOPS = 14, /**< Garbage collection loop limit reached */
|
||||
JERRY_FATAL_FAILED_ASSERTION = 120 /**< Assertion failed */
|
||||
} jerry_fatal_code_t;
|
||||
|
||||
/**
|
||||
* Signal the port that jerry experienced a fatal failure from which it cannot
|
||||
* Signal the port that the process experienced a fatal failure from which it cannot
|
||||
* recover.
|
||||
*
|
||||
* @param code gives the cause of the error.
|
||||
* A libc-based port may implement this with exit() or abort(), or both.
|
||||
*
|
||||
* Note:
|
||||
* Jerry expects the function not to return.
|
||||
* Note: This function is expected to not return.
|
||||
*
|
||||
* Example: a libc-based port may implement this with exit() or abort(), or both.
|
||||
* @param code: the cause of the error.
|
||||
*/
|
||||
void JERRY_ATTR_NORETURN jerry_port_fatal (jerry_fatal_code_t code);
|
||||
|
||||
/*
|
||||
* I/O Port API
|
||||
*/
|
||||
|
||||
/**
|
||||
* 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. 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.
|
||||
* Make the process sleep for a given time.
|
||||
*
|
||||
* 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).
|
||||
* This port function can be called by jerry-core when JERRY_DEBUGGER is enabled.
|
||||
* Otherwise this function is not used.
|
||||
*
|
||||
* 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_ATTR_FORMAT (printf, 2, 3) jerry_port_log (jerry_log_level_t level, const char *format, ...);
|
||||
|
||||
/*
|
||||
* Date Port API
|
||||
*/
|
||||
|
||||
/**
|
||||
* 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 defined 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 defined 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);
|
||||
|
||||
/**
|
||||
* 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);
|
||||
|
||||
/**
|
||||
* Makes the process sleep for a given time.
|
||||
*
|
||||
* Note:
|
||||
* This port function is called by jerry-core when JERRY_DEBUGGER is
|
||||
* enabled (set to 1). Otherwise this function is not used.
|
||||
*
|
||||
* @param sleep_time milliseconds to sleep.
|
||||
* @param sleep_time: milliseconds to sleep.
|
||||
*/
|
||||
void jerry_port_sleep (uint32_t sleep_time);
|
||||
|
||||
/**
|
||||
* Print a single character.
|
||||
*
|
||||
* Note:
|
||||
* This port function is here so the jerry-ext components would have
|
||||
* a common way to print out information.
|
||||
* If possible do not use from the jerry-core.
|
||||
*
|
||||
* @param c the character to print.
|
||||
* jerry-port-process @}
|
||||
*/
|
||||
void jerry_port_print_char (char c);
|
||||
|
||||
/**
|
||||
* Open a source file and read its contents into a buffer.
|
||||
*
|
||||
* Note:
|
||||
* This port function is called by jerry-core when JERRY_MODULE_SYSTEM
|
||||
* is enabled. The path is specified in the import statement's 'from "..."'
|
||||
* section.
|
||||
*
|
||||
* @param file_name_p Path that points to the EcmaScript file in the
|
||||
* filesystem.
|
||||
* @param out_size_p The opened file's size in bytes.
|
||||
*
|
||||
* @return the pointer to the buffer which contains the content of the file.
|
||||
* @defgroup jerry-port-context External Context API
|
||||
* @{
|
||||
*/
|
||||
uint8_t *jerry_port_read_source (const char *file_name_p, size_t *out_size_p);
|
||||
|
||||
/**
|
||||
* Frees the allocated buffer after the contents of the file are not needed
|
||||
* anymore.
|
||||
* Allocate a new context for the engine.
|
||||
*
|
||||
* @param buffer_p The pointer the allocated buffer.
|
||||
* This port function is called by jerry_init when JERRY_EXTERNAL_CONTEXT is enabled. Otherwise this function is not
|
||||
* used.
|
||||
*
|
||||
* The engine will pass the size required for the context structure. An implementation must make sure to
|
||||
* allocate at least this amount.
|
||||
*
|
||||
* Excess allocated space will be used as the engine heap when JerryScript is configured to use it's internal allocator,
|
||||
* this can be used to control the internal heap size.
|
||||
*
|
||||
* NOTE: The allocated memory must be pointer-aligned, otherwise the behavior is undefined.
|
||||
*
|
||||
* @param context_size: the size of the internal context structure
|
||||
*
|
||||
* @return total size of the allocated buffer
|
||||
*/
|
||||
void jerry_port_release_source (uint8_t *buffer_p);
|
||||
size_t jerry_port_context_alloc (size_t context_size);
|
||||
|
||||
/**
|
||||
* Default module resolver.
|
||||
* Get the currently active context of the engine.
|
||||
*
|
||||
* Note:
|
||||
* This port function is only used when JERRY_MODULE_SYSTEM is enabled.
|
||||
* This port function is called by jerry-core when JERRY_EXTERNAL_CONTEXT is enabled.
|
||||
* Otherwise this function is not used.
|
||||
*
|
||||
* @param specifier Module specifier string.
|
||||
* @param referrer Parent module.
|
||||
* @param user_p An unused pointer.
|
||||
*
|
||||
* @return A module object if resolving is successful, an error otherwise.
|
||||
* @return the pointer to the currently used engine context.
|
||||
*/
|
||||
jerry_value_t jerry_port_module_resolve (const jerry_value_t specifier, const jerry_value_t referrer, void *user_p);
|
||||
struct jerry_context_t *jerry_port_context_get (void);
|
||||
|
||||
/**
|
||||
* Release known modules.
|
||||
* Free the currently used context.
|
||||
*
|
||||
* Note:
|
||||
* This port function should be called by the user application when
|
||||
* the module database is no longer needed.
|
||||
* This port function is called by jerry_cleanup when JERRY_EXTERNAL_CONTEXT is enabled.
|
||||
* Otherwise this function is not used.
|
||||
*
|
||||
* @param realm If this argument is object, release only those modules,
|
||||
* which realm value is equal to this argument.
|
||||
* @return the pointer to the engine context.
|
||||
*/
|
||||
void jerry_port_module_release (const jerry_value_t realm);
|
||||
void jerry_port_context_free (void);
|
||||
|
||||
/**
|
||||
* @}
|
||||
* jerry-port-context @}
|
||||
*/
|
||||
|
||||
/**
|
||||
* @defgroup jerry-port-io I/O API
|
||||
* @{
|
||||
*/
|
||||
|
||||
/**
|
||||
* Display or log a debug/error message.
|
||||
*
|
||||
* The message is passed as a zero-terminated string. Messages may be logged in parts, which
|
||||
* will result in multiple calls to this functions. The implementation should consider
|
||||
* this before appending or prepending strings to the argument.
|
||||
*
|
||||
* This function is 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).
|
||||
*
|
||||
* The implementation can decide whether error and debug messages are logged to
|
||||
* the console, or saved to a database or to a file.
|
||||
*/
|
||||
void jerry_port_log (const char *message_p);
|
||||
|
||||
/**
|
||||
* Print a single character to standard output.
|
||||
*
|
||||
* This port function is never called from jerry-core directly, it is only used by jerry-ext components to print
|
||||
* information.
|
||||
*
|
||||
* @param byte: the byte to print.
|
||||
*/
|
||||
void jerry_port_print_byte (jerry_char_t byte);
|
||||
|
||||
/**
|
||||
* Print a buffer to standard output
|
||||
*
|
||||
* This port function is never called from jerry-core directly, it is only used by jerry-ext components to print
|
||||
* information.
|
||||
*
|
||||
* @param buffer_p: input buffer
|
||||
* @param buffer_size: data size
|
||||
*/
|
||||
void jerry_port_print_buffer (const jerry_char_t *buffer_p, jerry_size_t buffer_size);
|
||||
|
||||
/**
|
||||
* Read a line from standard input.
|
||||
*
|
||||
* The implementation should allocate storage necessary for the string. The result string should include the ending line
|
||||
* terminator character(s) and should be zero terminated.
|
||||
*
|
||||
* An implementation may return NULL to signal that the end of input is reached, or an error occured.
|
||||
*
|
||||
* When a non-NULL value is returned, the caller will pass the returned value to `jerry_port_line_free` when the line is
|
||||
* no longer needed. This can be used to finalize dynamically allocated buffers if necessary.
|
||||
*
|
||||
* This port function is never called from jerry-core directly, it is only used by some jerry-ext components that
|
||||
* require user input.
|
||||
*
|
||||
* @param out_size_p: size of the input string in bytes, excluding terminating zero byte
|
||||
*
|
||||
* @return pointer to the buffer storing the string,
|
||||
* or NULL if end of input
|
||||
*/
|
||||
jerry_char_t *jerry_port_line_read (jerry_size_t *out_size_p);
|
||||
|
||||
/**
|
||||
* Free a line buffer allocated by jerry_port_line_read
|
||||
*
|
||||
* @param buffer_p: buffer returned by jerry_port_line_read
|
||||
*/
|
||||
void jerry_port_line_free (jerry_char_t *buffer_p);
|
||||
|
||||
/**
|
||||
* jerry-port-io @}
|
||||
*/
|
||||
|
||||
/**
|
||||
* @defgroup jerry-port-fd Filesystem API
|
||||
* @{
|
||||
*/
|
||||
|
||||
/**
|
||||
* Canonicalize a file path.
|
||||
*
|
||||
* If possible, the implementation should resolve symbolic links and other directory references found in the input path,
|
||||
* and create a fully canonicalized file path as the result.
|
||||
*
|
||||
* The function may return with NULL in case an error is encountered, in which case the calling operation will not
|
||||
* proceed.
|
||||
*
|
||||
* The implementation should allocate storage for the result path as necessary. Non-NULL return values will be passed
|
||||
* to `jerry_port_path_free` when the result is no longer needed by the caller, which can be used to finalize
|
||||
* dynamically allocated buffers.
|
||||
*
|
||||
* NOTE: The implementation must not return directly with the input, as the input buffer is released after the call.
|
||||
*
|
||||
* @param path_p: zero-terminated string containing the input path
|
||||
* @param path_size: size of the input path string in bytes, excluding terminating zero
|
||||
*
|
||||
* @return buffer with the normalized path if the operation is successful,
|
||||
* NULL otherwise
|
||||
*/
|
||||
jerry_char_t *jerry_port_path_normalize (const jerry_char_t *path_p, jerry_size_t path_size);
|
||||
|
||||
/**
|
||||
* Free a path buffer returned by jerry_port_path_normalize.
|
||||
*
|
||||
* @param path_p: the path buffer to free
|
||||
*/
|
||||
void jerry_port_path_free (jerry_char_t *path_p);
|
||||
|
||||
/**
|
||||
* Get the offset of the basename component in the input path.
|
||||
*
|
||||
* The implementation should return the offset of the first character after the last path separator found in the path.
|
||||
* This is used by the caller to split the path into a directory name and a file name.
|
||||
*
|
||||
* @param path_p: input zero-terminated path string
|
||||
*
|
||||
* @return offset of the basename component in the input path
|
||||
*/
|
||||
jerry_size_t jerry_port_path_base (const jerry_char_t *path_p);
|
||||
|
||||
/**
|
||||
* Open a source file and read the content into a buffer.
|
||||
*
|
||||
* When the source file is no longer needed by the caller, the returned pointer will be passed to
|
||||
* `jerry_port_source_free`, which can be used to finalize the buffer.
|
||||
*
|
||||
* @param file_name_p: Path that points to the source file in the filesystem.
|
||||
* @param out_size_p: The opened file's size in bytes.
|
||||
*
|
||||
* @return pointer to the buffer which contains the content of the file.
|
||||
*/
|
||||
jerry_char_t *jerry_port_source_read (const char *file_name_p, jerry_size_t *out_size_p);
|
||||
|
||||
/**
|
||||
* Free a source file buffer.
|
||||
*
|
||||
* @param buffer_p: buffer returned by jerry_port_source_read
|
||||
*/
|
||||
void jerry_port_source_free (jerry_char_t *buffer_p);
|
||||
|
||||
/**
|
||||
* jerry-port-fs @}
|
||||
*/
|
||||
|
||||
/**
|
||||
* @defgroup jerry-port-date Date API
|
||||
* @{
|
||||
*/
|
||||
|
||||
/**
|
||||
* Get local time zone adjustment in milliseconds for the given input time.
|
||||
*
|
||||
* The argument is a time value representing milliseconds since unix epoch.
|
||||
*
|
||||
* Ideally, this function should satisfy the stipulations applied to LocalTZA
|
||||
* in section 21.4.1.7 of the ECMAScript version 12.0, as if called with isUTC true.
|
||||
*
|
||||
* This port function can be called by jerry-core when JERRY_BUILTIN_DATE is enabled.
|
||||
* Otherwise this function is not used.
|
||||
*
|
||||
* @param unix_ms: time value in milliseconds since unix epoch
|
||||
*
|
||||
* @return local time offset in milliseconds applied to UTC for the given time value
|
||||
*/
|
||||
int32_t jerry_port_local_tza (double unix_ms);
|
||||
|
||||
/**
|
||||
* Get the current system time in UTC.
|
||||
*
|
||||
* This port function is called by jerry-core when JERRY_BUILTIN_DATE is enabled.
|
||||
* It can also be used in the implementing application to initialize the random number generator.
|
||||
*
|
||||
* @return milliseconds since Unix epoch
|
||||
*/
|
||||
double jerry_port_current_time (void);
|
||||
|
||||
/**
|
||||
* jerry-port-date @}
|
||||
*/
|
||||
|
||||
/**
|
||||
* jerry-port @}
|
||||
*/
|
||||
|
||||
JERRY_C_API_END
|
||||
|
||||
#endif /* !JERRYSCRIPT_PORT_H */
|
||||
|
||||
/* vim: set fdm=marker fmr=@{,@}: */
|
||||
|
||||
@ -40,6 +40,18 @@ typedef enum
|
||||
JERRY_INIT_MEM_STATS = (1u << 2), /**< dump memory statistics */
|
||||
} jerry_init_flag_t;
|
||||
|
||||
/**
|
||||
* Jerry log levels. The levels are in severity order
|
||||
* where the most serious levels come first.
|
||||
*/
|
||||
typedef enum
|
||||
{
|
||||
JERRY_LOG_LEVEL_ERROR = 0u, /**< the engine will terminate after the message is printed */
|
||||
JERRY_LOG_LEVEL_WARNING = 1u, /**< a request is aborted, but the engine continues its operation */
|
||||
JERRY_LOG_LEVEL_DEBUG = 2u, /**< debug messages from the engine, low volume */
|
||||
JERRY_LOG_LEVEL_TRACE = 3u /**< detailed info about engine internals, potentially high volume */
|
||||
} jerry_log_level_t;
|
||||
|
||||
/**
|
||||
* JerryScript API Error object types.
|
||||
*/
|
||||
@ -316,9 +328,9 @@ typedef jerry_value_t (*jerry_halt_cb_t) (void *user_p);
|
||||
typedef void (*jerry_throw_cb_t) (const jerry_value_t exception_value, void *user_p);
|
||||
|
||||
/**
|
||||
* Function type applied each byte of a string
|
||||
* Function type applied to each unit of encoding when iterating over a string.
|
||||
*/
|
||||
typedef void (*jerry_string_iterate_cb_t) (uint8_t byte, void *user_p);
|
||||
typedef void (*jerry_string_iterate_cb_t) (uint32_t value, void *user_p);
|
||||
|
||||
/**
|
||||
* Function type applied for each data property of an object.
|
||||
|
||||
@ -102,11 +102,6 @@ typedef struct jerry_context_data_header
|
||||
|
||||
#define JERRY_CONTEXT_DATA_HEADER_USER_DATA(item_p) ((uint8_t *) (item_p + 1))
|
||||
|
||||
/**
|
||||
* First non-external member of the jerry context
|
||||
*/
|
||||
#define JERRY_CONTEXT_FIRST_MEMBER global_object_p
|
||||
|
||||
/**
|
||||
* JerryScript context
|
||||
*
|
||||
@ -123,7 +118,6 @@ struct jerry_context_t
|
||||
#endif /* !JERRY_SYSTEM_ALLOCATOR */
|
||||
#endif /* JERRY_EXTERNAL_CONTEXT */
|
||||
|
||||
/* Update JERRY_CONTEXT_FIRST_MEMBER if the first non-external member changes */
|
||||
ecma_global_object_t *global_object_p; /**< current global object */
|
||||
jmem_heap_free_t *jmem_heap_list_skip_p; /**< improves deallocation performance */
|
||||
jmem_pools_chunk_t *jmem_free_8_byte_chunk_p; /**< list of free eight byte pool chunks */
|
||||
@ -175,6 +169,8 @@ struct jerry_context_t
|
||||
uint32_t lit_magic_string_ex_count; /**< external magic strings count */
|
||||
uint32_t jerry_init_flags; /**< run-time configuration flags */
|
||||
uint32_t status_flags; /**< run-time flags (the top 8 bits are used for passing class parsing options) */
|
||||
jerry_log_level_t log_level; /**< current log level */
|
||||
|
||||
#if (JERRY_GC_MARK_LIMIT != 0)
|
||||
uint32_t ecma_gc_mark_recursion_limit; /**< GC mark recursion limit */
|
||||
#endif /* (JERRY_GC_MARK_LIMIT != 0) */
|
||||
@ -268,8 +264,8 @@ struct jerry_context_t
|
||||
* This part is for JerryScript which uses external context.
|
||||
*/
|
||||
|
||||
#define JERRY_CONTEXT_STRUCT (*jerry_port_get_current_context ())
|
||||
#define JERRY_CONTEXT(field) (jerry_port_get_current_context ()->field)
|
||||
#define JERRY_CONTEXT_STRUCT (*jerry_port_context_get ())
|
||||
#define JERRY_CONTEXT(field) (jerry_port_context_get ()->field)
|
||||
|
||||
#if !JERRY_SYSTEM_ALLOCATOR
|
||||
|
||||
|
||||
@ -261,7 +261,7 @@ jmem_heap_alloc (const size_t size) /**< size of requested block */
|
||||
* Note:
|
||||
* Each failed allocation attempt tries to reclaim memory with an increasing pressure,
|
||||
* up to 'max_pressure', or until a sufficient memory block is found. When JMEM_PRESSURE_FULL
|
||||
* is reached, the engine is terminated with ERR_OUT_OF_MEMORY. The `max_pressure` argument
|
||||
* is reached, the engine is terminated with JERRY_FATAL_OUT_OF_MEMORY. The `max_pressure` argument
|
||||
* can be used to limit the maximum pressure, and prevent the engine from terminating.
|
||||
*
|
||||
* @return NULL, if the required memory size is 0 or not enough memory
|
||||
@ -313,7 +313,7 @@ jmem_heap_alloc_block_internal (const size_t size) /**< required memory size */
|
||||
* Allocation of memory block, reclaiming unused memory if there is not enough.
|
||||
*
|
||||
* Note:
|
||||
* If a sufficiently sized block can't be found, the engine will be terminated with ERR_OUT_OF_MEMORY.
|
||||
* If a sufficiently sized block can't be found, the engine will be terminated with JERRY_FATAL_OUT_OF_MEMORY.
|
||||
*
|
||||
* @return NULL, if the required memory is 0
|
||||
* pointer to allocated memory block, otherwise
|
||||
|
||||
@ -112,7 +112,7 @@ typedef uint32_t jmem_cpointer_tag_t;
|
||||
* until enough memory is freed to fulfill the allocation request.
|
||||
*
|
||||
* If not enough memory is freed and JMEM_PRESSURE_FULL is reached,
|
||||
* then the engine is shut down with ERR_OUT_OF_MEMORY.
|
||||
* then the engine is shut down with JERRY_FATAL_OUT_OF_MEMORY.
|
||||
*/
|
||||
typedef enum
|
||||
{
|
||||
@ -197,7 +197,7 @@ void *JERRY_ATTR_PURE jmem_decompress_pointer (uintptr_t compressed_pointer);
|
||||
* If requested number of elements is zero, assign NULL to the variable.
|
||||
*
|
||||
* Warning:
|
||||
* if there is not enough memory on the heap, shutdown engine with ERR_OUT_OF_MEMORY.
|
||||
* if there is not enough memory on the heap, shutdown engine with JERRY_FATAL_OUT_OF_MEMORY.
|
||||
*/
|
||||
#define JMEM_DEFINE_LOCAL_ARRAY(var_name, number, type) \
|
||||
{ \
|
||||
|
||||
@ -32,29 +32,29 @@ jerry_fatal (jerry_fatal_code_t code) /**< status code */
|
||||
#ifndef JERRY_NDEBUG
|
||||
switch (code)
|
||||
{
|
||||
case ERR_OUT_OF_MEMORY:
|
||||
case JERRY_FATAL_OUT_OF_MEMORY:
|
||||
{
|
||||
JERRY_ERROR_MSG ("Error: ERR_OUT_OF_MEMORY\n");
|
||||
JERRY_ERROR_MSG ("Error: JERRY_FATAL_OUT_OF_MEMORY\n");
|
||||
break;
|
||||
}
|
||||
case ERR_REF_COUNT_LIMIT:
|
||||
case JERRY_FATAL_REF_COUNT_LIMIT:
|
||||
{
|
||||
JERRY_ERROR_MSG ("Error: ERR_REF_COUNT_LIMIT\n");
|
||||
JERRY_ERROR_MSG ("Error: JERRY_FATAL_REF_COUNT_LIMIT\n");
|
||||
break;
|
||||
}
|
||||
case ERR_UNTERMINATED_GC_LOOPS:
|
||||
case JERRY_FATAL_UNTERMINATED_GC_LOOPS:
|
||||
{
|
||||
JERRY_ERROR_MSG ("Error: ERR_UNTERMINATED_GC_LOOPS\n");
|
||||
JERRY_ERROR_MSG ("Error: JERRY_FATAL_UNTERMINATED_GC_LOOPS\n");
|
||||
break;
|
||||
}
|
||||
case ERR_DISABLED_BYTE_CODE:
|
||||
case JERRY_FATAL_DISABLED_BYTE_CODE:
|
||||
{
|
||||
JERRY_ERROR_MSG ("Error: ERR_DISABLED_BYTE_CODE\n");
|
||||
JERRY_ERROR_MSG ("Error: JERRY_FATAL_DISABLED_BYTE_CODE\n");
|
||||
break;
|
||||
}
|
||||
case ERR_FAILED_INTERNAL_ASSERTION:
|
||||
case JERRY_FATAL_FAILED_ASSERTION:
|
||||
{
|
||||
JERRY_ERROR_MSG ("Error: ERR_FAILED_INTERNAL_ASSERTION\n");
|
||||
JERRY_ERROR_MSG ("Error: JERRY_FATAL_FAILED_ASSERTION\n");
|
||||
break;
|
||||
}
|
||||
}
|
||||
@ -78,9 +78,9 @@ jerry_assert_fail (const char *assertion, /**< assertion condition string */
|
||||
const char *function, /**< function name */
|
||||
const uint32_t line) /**< line */
|
||||
{
|
||||
JERRY_ERROR_MSG ("ICE: Assertion '%s' failed at %s(%s):%lu.\n", assertion, file, function, (unsigned long) line);
|
||||
JERRY_ERROR_MSG ("ICE: Assertion '%s' failed at %s(%s):%u.\n", assertion, file, function, line);
|
||||
|
||||
jerry_fatal (ERR_FAILED_INTERNAL_ASSERTION);
|
||||
jerry_fatal (JERRY_FATAL_FAILED_ASSERTION);
|
||||
} /* jerry_assert_fail */
|
||||
|
||||
/**
|
||||
@ -91,8 +91,8 @@ jerry_unreachable (const char *file, /**< file name */
|
||||
const char *function, /**< function name */
|
||||
const uint32_t line) /**< line */
|
||||
{
|
||||
JERRY_ERROR_MSG ("ICE: Unreachable control path at %s(%s):%lu was executed.\n", file, function, (unsigned long) line);
|
||||
JERRY_ERROR_MSG ("ICE: Unreachable control path at %s(%s):%u was executed.\n", file, function, line);
|
||||
|
||||
jerry_fatal (ERR_FAILED_INTERNAL_ASSERTION);
|
||||
jerry_fatal (JERRY_FATAL_FAILED_ASSERTION);
|
||||
} /* jerry_unreachable */
|
||||
#endif /* !JERRY_NDEBUG */
|
||||
|
||||
@ -19,6 +19,7 @@
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "jerryscript-core.h"
|
||||
#include "jerryscript-port.h"
|
||||
|
||||
#include "config.h"
|
||||
@ -120,10 +121,10 @@ void JERRY_ATTR_NORETURN jerry_fatal (jerry_fatal_code_t code);
|
||||
* Logging
|
||||
*/
|
||||
#if JERRY_LOGGING
|
||||
#define JERRY_ERROR_MSG(...) jerry_port_log (JERRY_LOG_LEVEL_ERROR, __VA_ARGS__)
|
||||
#define JERRY_WARNING_MSG(...) jerry_port_log (JERRY_LOG_LEVEL_WARNING, __VA_ARGS__)
|
||||
#define JERRY_DEBUG_MSG(...) jerry_port_log (JERRY_LOG_LEVEL_DEBUG, __VA_ARGS__)
|
||||
#define JERRY_TRACE_MSG(...) jerry_port_log (JERRY_LOG_LEVEL_TRACE, __VA_ARGS__)
|
||||
#define JERRY_ERROR_MSG(...) jerry_log (JERRY_LOG_LEVEL_ERROR, __VA_ARGS__)
|
||||
#define JERRY_WARNING_MSG(...) jerry_log (JERRY_LOG_LEVEL_WARNING, __VA_ARGS__)
|
||||
#define JERRY_DEBUG_MSG(...) jerry_log (JERRY_LOG_LEVEL_DEBUG, __VA_ARGS__)
|
||||
#define JERRY_TRACE_MSG(...) jerry_log (JERRY_LOG_LEVEL_TRACE, __VA_ARGS__)
|
||||
#else /* !JERRY_LOGGING */
|
||||
#define JERRY_ERROR_MSG(...) \
|
||||
do \
|
||||
@ -171,6 +172,11 @@ void JERRY_ATTR_NORETURN jerry_fatal (jerry_fatal_code_t code);
|
||||
*/
|
||||
#define JERRY_ALIGNUP(value, alignment) (((value) + ((alignment) -1)) & ~((alignment) -1))
|
||||
|
||||
/**
|
||||
* Align value down
|
||||
*/
|
||||
#define JERRY_ALIGNDOWN(value, alignment) ((value) & ~((alignment) -1))
|
||||
|
||||
/*
|
||||
* min, max
|
||||
*/
|
||||
|
||||
@ -6,7 +6,7 @@ Name: libjerry-core
|
||||
Description: JerryScript: lightweight JavaScript engine (core engine library)
|
||||
URL: https://github.com/jerryscript-project/jerryscript
|
||||
Version: @JERRY_VERSION@
|
||||
Requires.private: @JERRY_CORE_PKGCONFIG_REQUIRES@ # NOTE: libjerry-port-default is not added as a required package
|
||||
Requires.private: @JERRY_CORE_PKGCONFIG_REQUIRES@ # NOTE: libjerry-port is not added as a required package
|
||||
Libs: -L${libdir} -ljerry-core
|
||||
Libs.private: @JERRY_CORE_PKGCONFIG_LIBS@
|
||||
Cflags: -I${includedir} @JERRY_CORE_PKGCONFIG_CFLAGS@
|
||||
|
||||
@ -648,7 +648,7 @@ parser_post_processing (parser_context_t *context_p) /**< context */
|
||||
if (JERRY_UNLIKELY (context_p->script_p->refs_and_type >= CBC_SCRIPT_REF_MAX))
|
||||
{
|
||||
/* This is probably never happens in practice. */
|
||||
jerry_fatal (ERR_REF_COUNT_LIMIT);
|
||||
jerry_fatal (JERRY_FATAL_REF_COUNT_LIMIT);
|
||||
}
|
||||
|
||||
context_p->script_p->refs_and_type += CBC_SCRIPT_REF_ONE;
|
||||
|
||||
@ -3916,12 +3916,12 @@ scan_completed:
|
||||
}
|
||||
case SCANNER_TYPE_ERR_REDECLARED:
|
||||
{
|
||||
JERRY_DEBUG_MSG (" ERR_REDECLARED: source:%d\n", (int) (info_p->source_p - source_start_p));
|
||||
JERRY_DEBUG_MSG (" JERRY_FATAL_REDECLARED: source:%d\n", (int) (info_p->source_p - source_start_p));
|
||||
break;
|
||||
}
|
||||
case SCANNER_TYPE_ERR_ASYNC_FUNCTION:
|
||||
{
|
||||
JERRY_DEBUG_MSG (" ERR_ASYNC_FUNCTION: source:%d\n", (int) (info_p->source_p - source_start_p));
|
||||
JERRY_DEBUG_MSG (" JERRY_FATAL_ASYNC_FUNCTION: source:%d\n", (int) (info_p->source_p - source_start_p));
|
||||
break;
|
||||
}
|
||||
case SCANNER_TYPE_LITERAL_FLAGS:
|
||||
|
||||
@ -1167,7 +1167,7 @@ opfunc_create_implicit_class_constructor (uint8_t opcode, /**< current cbc opcod
|
||||
|
||||
if (JERRY_UNLIKELY (script_p->refs_and_type >= CBC_SCRIPT_REF_MAX))
|
||||
{
|
||||
jerry_fatal (ERR_REF_COUNT_LIMIT);
|
||||
jerry_fatal (JERRY_FATAL_REF_COUNT_LIMIT);
|
||||
}
|
||||
|
||||
ecma_object_t *function_object_p = ecma_create_object (ecma_builtin_get (ECMA_BUILTIN_ID_FUNCTION_PROTOTYPE),
|
||||
|
||||
@ -4733,7 +4733,7 @@ vm_loop (vm_frame_ctx_t *frame_ctx_p) /**< frame context */
|
||||
{
|
||||
JERRY_ASSERT (VM_OC_GROUP_GET_INDEX (opcode_data) == VM_OC_NONE);
|
||||
|
||||
jerry_fatal (ERR_DISABLED_BYTE_CODE);
|
||||
jerry_fatal (JERRY_FATAL_DISABLED_BYTE_CODE);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -72,12 +72,8 @@ JERRY_DEBUGGER_EVAL_OK = 1
|
||||
JERRY_DEBUGGER_EVAL_ERROR = 2
|
||||
|
||||
# Subtypes of output
|
||||
JERRY_DEBUGGER_OUTPUT_OK = 1
|
||||
JERRY_DEBUGGER_OUTPUT_ERROR = 2
|
||||
JERRY_DEBUGGER_OUTPUT_WARNING = 3
|
||||
JERRY_DEBUGGER_OUTPUT_DEBUG = 4
|
||||
JERRY_DEBUGGER_OUTPUT_TRACE = 5
|
||||
|
||||
JERRY_DEBUGGER_OUTPUT_PRINT = 1
|
||||
JERRY_DEBUGGER_OUTPUT_LOG = 2
|
||||
|
||||
# Messages sent by the client to server.
|
||||
JERRY_DEBUGGER_FREE_BYTE_CODE_CP = 1
|
||||
@ -1147,33 +1143,20 @@ class JerryDebugger(object):
|
||||
|
||||
# Subtypes of output
|
||||
if buffer_type == JERRY_DEBUGGER_OUTPUT_RESULT_END:
|
||||
if subtype == JERRY_DEBUGGER_OUTPUT_OK:
|
||||
log_type = "%sout:%s " % (self.blue, self.nocolor)
|
||||
if subtype == JERRY_DEBUGGER_OUTPUT_PRINT:
|
||||
|
||||
message = self.current_out + message
|
||||
lines = message.split("\n")
|
||||
self.current_out = lines.pop()
|
||||
|
||||
return "".join(["%s%s\n" % (log_type, line) for line in lines])
|
||||
|
||||
if subtype == JERRY_DEBUGGER_OUTPUT_DEBUG:
|
||||
log_type = "%slog:%s " % (self.yellow, self.nocolor)
|
||||
return "".join(["%s\n" % line for line in lines])
|
||||
|
||||
if subtype == JERRY_DEBUGGER_OUTPUT_LOG:
|
||||
message = self.current_log + message
|
||||
lines = message.split("\n")
|
||||
self.current_log = lines.pop()
|
||||
|
||||
return "".join(["%s%s\n" % (log_type, line) for line in lines])
|
||||
|
||||
if not message.endswith("\n"):
|
||||
message += "\n"
|
||||
|
||||
if subtype == JERRY_DEBUGGER_OUTPUT_WARNING:
|
||||
return "%swarning: %s%s" % (self.yellow, self.nocolor, message)
|
||||
elif subtype == JERRY_DEBUGGER_OUTPUT_ERROR:
|
||||
return "%serr: %s%s" % (self.red, self.nocolor, message)
|
||||
elif subtype == JERRY_DEBUGGER_OUTPUT_TRACE:
|
||||
return "%strace: %s%s" % (self.blue, self.nocolor, message)
|
||||
return "".join(["%s\n" % line for line in lines])
|
||||
|
||||
# Subtypes of eval
|
||||
self.prompt = True
|
||||
|
||||
@ -45,12 +45,13 @@ set(SOURCE_EXT
|
||||
debugger/debugger-ws.c
|
||||
handle-scope/handle-scope-allocator.c
|
||||
handle-scope/handle-scope.c
|
||||
handler/handler-assert.c
|
||||
handler/handler-gc.c
|
||||
handler/handler-print.c
|
||||
handler/handler-register.c
|
||||
handler/handler-source-name.c
|
||||
module/module.c
|
||||
util/handlers.c
|
||||
util/print.c
|
||||
util/properties.c
|
||||
util/repl.c
|
||||
util/sources.c
|
||||
util/test262.c
|
||||
)
|
||||
|
||||
add_library(${JERRY_EXT_NAME} ${SOURCE_EXT})
|
||||
|
||||
@ -91,9 +91,9 @@ void JERRY_ATTR_NORETURN jerry_unreachable (const char *file, const char *functi
|
||||
/*
|
||||
* Logging
|
||||
*/
|
||||
#define JERRYX_ERROR_MSG(...) jerry_port_log (JERRY_LOG_LEVEL_ERROR, __VA_ARGS__)
|
||||
#define JERRYX_WARNING_MSG(...) jerry_port_log (JERRY_LOG_LEVEL_WARNING, __VA_ARGS__)
|
||||
#define JERRYX_DEBUG_MSG(...) jerry_port_log (JERRY_LOG_LEVEL_DEBUG, __VA_ARGS__)
|
||||
#define JERRYX_TRACE_MSG(...) jerry_port_log (JERRY_LOG_LEVEL_TRACE, __VA_ARGS__)
|
||||
#define JERRYX_ERROR_MSG(...) jerry_log (JERRY_LOG_LEVEL_ERROR, __VA_ARGS__)
|
||||
#define JERRYX_WARNING_MSG(...) jerry_log (JERRY_LOG_LEVEL_WARNING, __VA_ARGS__)
|
||||
#define JERRYX_DEBUG_MSG(...) jerry_log (JERRY_LOG_LEVEL_DEBUG, __VA_ARGS__)
|
||||
#define JERRYX_TRACE_MSG(...) jerry_log (JERRY_LOG_LEVEL_TRACE, __VA_ARGS__)
|
||||
|
||||
#endif /* !JEXT_COMMON_H */
|
||||
|
||||
@ -13,6 +13,8 @@
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#include <assert.h>
|
||||
|
||||
#include "jerryscript-ext/debugger.h"
|
||||
#include "jext-common.h"
|
||||
|
||||
@ -36,3 +38,49 @@ jerryx_debugger_after_connect (bool success) /**< tells whether the connection
|
||||
JERRYX_UNUSED (success);
|
||||
#endif /* defined (JERRY_DEBUGGER) && (JERRY_DEBUGGER == 1) */
|
||||
} /* jerryx_debugger_after_connect */
|
||||
|
||||
/**
|
||||
* Check that value contains the reset abort value.
|
||||
*
|
||||
* Note: if the value is the reset abort value, the value is released.
|
||||
*
|
||||
* return true, if reset abort
|
||||
* false, otherwise
|
||||
*/
|
||||
bool
|
||||
jerryx_debugger_is_reset (jerry_value_t value) /**< jerry value */
|
||||
{
|
||||
if (!jerry_value_is_abort (value))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
jerry_value_t abort_value = jerry_exception_value (value, false);
|
||||
|
||||
if (!jerry_value_is_string (abort_value))
|
||||
{
|
||||
jerry_value_free (abort_value);
|
||||
return false;
|
||||
}
|
||||
|
||||
static const char restart_str[] = "r353t";
|
||||
|
||||
jerry_size_t str_size = jerry_string_size (abort_value, JERRY_ENCODING_CESU8);
|
||||
bool is_reset = false;
|
||||
|
||||
if (str_size == sizeof (restart_str) - 1)
|
||||
{
|
||||
JERRY_VLA (jerry_char_t, str_buf, str_size);
|
||||
jerry_string_to_buffer (abort_value, JERRY_ENCODING_CESU8, str_buf, str_size);
|
||||
|
||||
is_reset = memcmp (restart_str, (char *) (str_buf), str_size) == 0;
|
||||
|
||||
if (is_reset)
|
||||
{
|
||||
jerry_value_free (value);
|
||||
}
|
||||
}
|
||||
|
||||
jerry_value_free (abort_value);
|
||||
return is_reset;
|
||||
} /* jerryx_debugger_is_reset */
|
||||
|
||||
@ -45,11 +45,10 @@ typedef SOCKET jerryx_socket_t;
|
||||
typedef char jerryx_socket_void_t;
|
||||
typedef int jerryx_socket_size_t;
|
||||
#else /* !_WIN32 */
|
||||
#include <fcntl.h>
|
||||
#include <unistd.h>
|
||||
|
||||
#include <arpa/inet.h>
|
||||
#include <fcntl.h>
|
||||
#include <sys/socket.h>
|
||||
#include <unistd.h>
|
||||
|
||||
/* On *nix the EWOULDBLOCK errno value can be returned for non-blocking operations */
|
||||
#define JERRYX_EWOULDBLOCK EWOULDBLOCK
|
||||
@ -130,10 +129,10 @@ jerryx_debugger_tcp_log_error (int errno_value) /**< error value to log */
|
||||
(LPTSTR) &error_message,
|
||||
0,
|
||||
NULL);
|
||||
jerry_port_log (JERRY_LOG_LEVEL_ERROR, "TCP Error: %s\n", error_message);
|
||||
JERRYX_ERROR_MSG ("TCP Error: %s\n", error_message);
|
||||
LocalFree (error_message);
|
||||
#else /* !_WIN32 */
|
||||
jerry_port_log (JERRY_LOG_LEVEL_ERROR, "TCP Error: %s\n", strerror (errno_value));
|
||||
JERRYX_ERROR_MSG ("TCP Error: %s\n", strerror (errno_value));
|
||||
#endif /* _WIN32 */
|
||||
} /* jerryx_debugger_tcp_log_error */
|
||||
|
||||
|
||||
@ -1,114 +0,0 @@
|
||||
/* Copyright JS Foundation and other contributors, http://js.foundation
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#include <inttypes.h>
|
||||
|
||||
#include "jerryscript-port.h"
|
||||
|
||||
#include "jerryscript-ext/handler.h"
|
||||
|
||||
/**
|
||||
* Hard assert for scripts. The routine calls jerry_port_fatal on assertion failure.
|
||||
*
|
||||
* Notes:
|
||||
* * If the `JERRY_FEATURE_LINE_INFO` runtime feature is enabled (build option: `JERRY_LINE_INFO`)
|
||||
* a backtrace is also printed out.
|
||||
*
|
||||
* @return true - if only one argument was passed and that argument was a boolean true.
|
||||
* Note that the function does not return otherwise.
|
||||
*/
|
||||
jerry_value_t
|
||||
jerryx_handler_assert_fatal (const jerry_call_info_t *call_info_p, /**< call information */
|
||||
const jerry_value_t args_p[], /**< function arguments */
|
||||
const jerry_length_t args_cnt) /**< number of function arguments */
|
||||
{
|
||||
(void) call_info_p; /* unused */
|
||||
|
||||
if (args_cnt == 1 && jerry_value_is_true (args_p[0]))
|
||||
{
|
||||
return jerry_boolean (true);
|
||||
}
|
||||
|
||||
/* Assert failed, print a bit of JS backtrace */
|
||||
jerry_port_log (JERRY_LOG_LEVEL_ERROR, "Script Error: assertion failed\n");
|
||||
|
||||
if (jerry_feature_enabled (JERRY_FEATURE_LINE_INFO))
|
||||
{
|
||||
jerry_port_log (JERRY_LOG_LEVEL_ERROR, "Script backtrace (top 5):\n");
|
||||
|
||||
/* If the line info feature is disabled an empty array will be returned. */
|
||||
jerry_value_t backtrace_array = jerry_backtrace (5);
|
||||
uint32_t array_length = jerry_array_length (backtrace_array);
|
||||
|
||||
for (uint32_t idx = 0; idx < array_length; idx++)
|
||||
{
|
||||
jerry_value_t property = jerry_object_get_index (backtrace_array, idx);
|
||||
|
||||
/* On some systems the uint32_t values can't be printed with "%u" and
|
||||
* on some systems it can be printed. To avoid differences in the uint32_t typdef
|
||||
* The "PRIu32" macro is used to correctly add the formatter.
|
||||
*/
|
||||
jerry_port_log (JERRY_LOG_LEVEL_ERROR, " %" PRIu32 ": ", idx);
|
||||
|
||||
jerry_char_t string_buffer[256];
|
||||
const jerry_length_t buffer_size = (jerry_length_t) (sizeof (string_buffer) - 1);
|
||||
|
||||
jerry_size_t copied_bytes = jerry_string_to_buffer (property, JERRY_ENCODING_UTF8, string_buffer, buffer_size);
|
||||
string_buffer[copied_bytes] = '\0';
|
||||
|
||||
jerry_port_log (JERRY_LOG_LEVEL_ERROR, "%s\n", string_buffer);
|
||||
jerry_value_free (property);
|
||||
}
|
||||
|
||||
jerry_value_free (backtrace_array);
|
||||
}
|
||||
|
||||
jerry_port_fatal (ERR_FAILED_INTERNAL_ASSERTION);
|
||||
} /* jerryx_handler_assert_fatal */
|
||||
|
||||
/**
|
||||
* Soft assert for scripts. The routine throws an error on assertion failure.
|
||||
*
|
||||
* @return true - if only one argument was passed and that argument was a boolean true.
|
||||
* error - otherwise.
|
||||
*/
|
||||
jerry_value_t
|
||||
jerryx_handler_assert_throw (const jerry_call_info_t *call_info_p, /**< call information */
|
||||
const jerry_value_t args_p[], /**< function arguments */
|
||||
const jerry_length_t args_cnt) /**< number of function arguments */
|
||||
{
|
||||
(void) call_info_p; /* unused */
|
||||
|
||||
if (args_cnt == 1 && jerry_value_is_true (args_p[0]))
|
||||
{
|
||||
return jerry_boolean (true);
|
||||
}
|
||||
|
||||
return jerry_throw_sz (JERRY_ERROR_COMMON, "assertion failed");
|
||||
} /* jerryx_handler_assert_throw */
|
||||
|
||||
/**
|
||||
* An alias to `jerryx_handler_assert_fatal`.
|
||||
*
|
||||
* @return true - if only one argument was passed and that argument was a boolean true.
|
||||
* Note that the function does not return otherwise.
|
||||
*/
|
||||
jerry_value_t
|
||||
jerryx_handler_assert (const jerry_call_info_t *call_info_p, /**< call information */
|
||||
const jerry_value_t args_p[], /**< function arguments */
|
||||
const jerry_length_t args_cnt) /**< number of function arguments */
|
||||
{
|
||||
return jerryx_handler_assert_fatal (call_info_p, args_p, args_cnt);
|
||||
} /* jerryx_handler_assert */
|
||||
@ -1,80 +0,0 @@
|
||||
/* Copyright JS Foundation and other contributors, http://js.foundation
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#include "jerryscript-debugger.h"
|
||||
#include "jerryscript-port.h"
|
||||
|
||||
#include "jerryscript-ext/handler.h"
|
||||
|
||||
/**
|
||||
* 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`.
|
||||
*
|
||||
* @return undefined - if all arguments could be converted to strings,
|
||||
* error - otherwise.
|
||||
*/
|
||||
jerry_value_t
|
||||
jerryx_handler_print (const jerry_call_info_t *call_info_p, /**< call information */
|
||||
const jerry_value_t args_p[], /**< function arguments */
|
||||
const jerry_length_t args_cnt) /**< number of function arguments */
|
||||
{
|
||||
(void) call_info_p; /* unused */
|
||||
|
||||
jerry_value_t ret_val = jerry_undefined ();
|
||||
|
||||
for (jerry_length_t arg_index = 0; arg_index < args_cnt; arg_index++)
|
||||
{
|
||||
jerry_value_t str_val;
|
||||
|
||||
if (jerry_value_is_symbol (args_p[arg_index]))
|
||||
{
|
||||
str_val = jerry_symbol_descriptive_string (args_p[arg_index]);
|
||||
}
|
||||
else
|
||||
{
|
||||
str_val = jerry_value_to_string (args_p[arg_index]);
|
||||
}
|
||||
|
||||
if (jerry_value_is_exception (str_val))
|
||||
{
|
||||
/* There is no need to free the undefined value. */
|
||||
ret_val = str_val;
|
||||
break;
|
||||
}
|
||||
|
||||
if (arg_index > 0)
|
||||
{
|
||||
jerry_port_print_char (' ');
|
||||
}
|
||||
|
||||
jerry_string_print (str_val);
|
||||
jerry_value_free (str_val);
|
||||
}
|
||||
|
||||
jerry_port_print_char ('\n');
|
||||
return ret_val;
|
||||
} /* jerryx_handler_print */
|
||||
@ -1,40 +0,0 @@
|
||||
/* Copyright JS Foundation and other contributors, http://js.foundation
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#include "jerryscript-ext/handler.h"
|
||||
|
||||
/**
|
||||
* Get the source name (usually a file name) of the currently executed script or the given function object
|
||||
*
|
||||
* Note: returned value must be freed with jerry_value_free, when it is no longer needed
|
||||
*
|
||||
* @return JS string constructed from
|
||||
* - the currently executed function object's source name, if the given value is undefined
|
||||
* - source name of the function object, if the given value is a function object
|
||||
* - "<anonymous>", otherwise
|
||||
*/
|
||||
jerry_value_t
|
||||
jerryx_handler_source_name (const jerry_call_info_t *call_info_p, /**< call information */
|
||||
const jerry_value_t args_p[], /**< function arguments */
|
||||
const jerry_length_t args_cnt) /**< number of function arguments */
|
||||
{
|
||||
(void) call_info_p; /* unused */
|
||||
|
||||
jerry_value_t undefined_value = jerry_undefined ();
|
||||
jerry_value_t source_name = jerry_source_name (args_cnt > 0 ? args_p[0] : undefined_value);
|
||||
jerry_value_free (undefined_value);
|
||||
|
||||
return source_name;
|
||||
} /* jerryx_handler_source_name */
|
||||
@ -35,6 +35,8 @@ bool jerryx_debugger_serial_create (const char *config);
|
||||
bool jerryx_debugger_ws_create (void);
|
||||
bool jerryx_debugger_rp_create (void);
|
||||
|
||||
bool jerryx_debugger_is_reset (jerry_value_t value);
|
||||
|
||||
JERRY_C_API_END
|
||||
|
||||
#endif /* !JERRYX_HANDLER_H */
|
||||
|
||||
48
jerry-ext/include/jerryscript-ext/handlers.h
Normal file
48
jerry-ext/include/jerryscript-ext/handlers.h
Normal file
@ -0,0 +1,48 @@
|
||||
/* Copyright JS Foundation and other contributors, http://js.foundation
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#ifndef JERRYX_HANDLERS_H
|
||||
#define JERRYX_HANDLERS_H
|
||||
|
||||
#include "jerryscript-types.h"
|
||||
|
||||
JERRY_C_API_BEGIN
|
||||
|
||||
jerry_value_t jerryx_handler_assert (const jerry_call_info_t *call_info_p,
|
||||
const jerry_value_t args_p[],
|
||||
const jerry_length_t args_cnt);
|
||||
jerry_value_t
|
||||
jerryx_handler_gc (const jerry_call_info_t *call_info_p, const jerry_value_t args_p[], const jerry_length_t args_cnt);
|
||||
jerry_value_t jerryx_handler_print (const jerry_call_info_t *call_info_p,
|
||||
const jerry_value_t args_p[],
|
||||
const jerry_length_t args_cnt);
|
||||
jerry_value_t jerryx_handler_source_name (const jerry_call_info_t *call_info_p,
|
||||
const jerry_value_t args_p[],
|
||||
const jerry_length_t args_cnt);
|
||||
jerry_value_t jerryx_handler_create_realm (const jerry_call_info_t *call_info_p,
|
||||
const jerry_value_t args_p[],
|
||||
const jerry_length_t args_cnt);
|
||||
void jerryx_handler_promise_reject (jerry_promise_event_type_t event_type,
|
||||
const jerry_value_t object,
|
||||
const jerry_value_t value,
|
||||
void *user_p);
|
||||
jerry_value_t jerryx_handler_source_received (const jerry_char_t *source_name_p,
|
||||
size_t source_name_size,
|
||||
const jerry_char_t *source_p,
|
||||
size_t source_size,
|
||||
void *user_p);
|
||||
JERRY_C_API_END
|
||||
|
||||
#endif /* !JERRYX_HANDLERS_H */
|
||||
@ -13,30 +13,22 @@
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#ifndef JERRYSCRIPT_PORT_DEFAULT_H
|
||||
#define JERRYSCRIPT_PORT_DEFAULT_H
|
||||
|
||||
#include <stdbool.h>
|
||||
#ifndef JERRYX_PRINT_H
|
||||
#define JERRYX_PRINT_H
|
||||
|
||||
#include "jerryscript-port.h"
|
||||
#include "jerryscript.h"
|
||||
#include "jerryscript-types.h"
|
||||
|
||||
JERRY_C_API_BEGIN
|
||||
|
||||
/** \addtogroup jerry_port_default Default Jerry engine port API
|
||||
* These functions are only available if the default port of Jerry is used.
|
||||
* @{
|
||||
*/
|
||||
|
||||
jerry_log_level_t jerry_port_default_get_log_level (void);
|
||||
void jerry_port_default_set_log_level (jerry_log_level_t level);
|
||||
|
||||
void jerry_port_default_set_current_context (jerry_context_t *context_p);
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
jerry_value_t jerryx_print_value (const jerry_value_t value);
|
||||
void jerryx_print_byte (jerry_char_t ch);
|
||||
void jerryx_print_buffer (const jerry_char_t *buffer_p, jerry_size_t buffer_size);
|
||||
void jerryx_print_string (const char *str_p);
|
||||
void jerryx_print_backtrace (unsigned depth);
|
||||
void jerryx_print_unhandled_exception (jerry_value_t exception);
|
||||
void jerryx_print_unhandled_rejection (jerry_value_t exception);
|
||||
|
||||
JERRY_C_API_END
|
||||
|
||||
#endif /* !JERRYSCRIPT_PORT_DEFAULT_H */
|
||||
#endif /* !JERRYX_PRINT_H */
|
||||
@ -13,10 +13,10 @@
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#ifndef JERRYX_HANDLER_H
|
||||
#define JERRYX_HANDLER_H
|
||||
#ifndef JERRYX_PROPERTIES_H
|
||||
#define JERRYX_PROPERTIES_H
|
||||
|
||||
#include "jerryscript.h"
|
||||
#include "jerryscript-types.h"
|
||||
|
||||
JERRY_C_API_BEGIN
|
||||
|
||||
@ -24,29 +24,7 @@ JERRY_C_API_BEGIN
|
||||
* Handler registration helper
|
||||
*/
|
||||
|
||||
jerry_value_t jerryx_handler_register_global (const char *name_p, jerry_external_handler_t handler_p);
|
||||
|
||||
/*
|
||||
* Common external function handlers
|
||||
*/
|
||||
|
||||
jerry_value_t jerryx_handler_assert_fatal (const jerry_call_info_t *call_info_p,
|
||||
const jerry_value_t args_p[],
|
||||
const jerry_length_t args_cnt);
|
||||
jerry_value_t jerryx_handler_assert_throw (const jerry_call_info_t *call_info_p,
|
||||
const jerry_value_t args_p[],
|
||||
const jerry_length_t args_cnt);
|
||||
jerry_value_t jerryx_handler_assert (const jerry_call_info_t *call_info_p,
|
||||
const jerry_value_t args_p[],
|
||||
const jerry_length_t args_cnt);
|
||||
jerry_value_t
|
||||
jerryx_handler_gc (const jerry_call_info_t *call_info_p, const jerry_value_t args_p[], const jerry_length_t args_cnt);
|
||||
jerry_value_t jerryx_handler_print (const jerry_call_info_t *call_info_p,
|
||||
const jerry_value_t args_p[],
|
||||
const jerry_length_t args_cnt);
|
||||
jerry_value_t jerryx_handler_source_name (const jerry_call_info_t *call_info_p,
|
||||
const jerry_value_t args_p[],
|
||||
const jerry_length_t args_cnt);
|
||||
bool jerryx_register_global (const char *name_p, jerry_external_handler_t handler_p);
|
||||
|
||||
/**
|
||||
* Struct used by the `jerryx_set_functions` method to
|
||||
@ -108,12 +86,6 @@ jerryx_register_result jerryx_set_properties (const jerry_value_t target_object,
|
||||
void jerryx_release_property_entry (const jerryx_property_entry entries[],
|
||||
const jerryx_register_result register_result);
|
||||
|
||||
jerry_value_t jerryx_set_property_str (const jerry_value_t target_object, const char *name, const jerry_value_t value);
|
||||
|
||||
jerry_value_t jerryx_get_property_str (const jerry_value_t target_object, const char *name);
|
||||
|
||||
bool jerryx_has_property_str (const jerry_value_t target_object, const char *name);
|
||||
|
||||
JERRY_C_API_END
|
||||
|
||||
#endif /* !JERRYX_HANDLER_H */
|
||||
#endif /* !JERRYX_PROPERTIES_H */
|
||||
27
jerry-ext/include/jerryscript-ext/repl.h
Normal file
27
jerry-ext/include/jerryscript-ext/repl.h
Normal file
@ -0,0 +1,27 @@
|
||||
/* Copyright JS Foundation and other contributors, http://js.foundation
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#ifndef JERRYX_REPL_H
|
||||
#define JERRYX_REPL_H
|
||||
|
||||
#include "jerryscript-types.h"
|
||||
|
||||
JERRY_C_API_BEGIN
|
||||
|
||||
void jerryx_repl (const char* prompt_p);
|
||||
|
||||
JERRY_C_API_END
|
||||
|
||||
#endif /* !JERRYX_REPL_H */
|
||||
31
jerry-ext/include/jerryscript-ext/sources.h
Normal file
31
jerry-ext/include/jerryscript-ext/sources.h
Normal file
@ -0,0 +1,31 @@
|
||||
/* Copyright JS Foundation and other contributors, http://js.foundation
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#ifndef JERRYX_SOURCES_H
|
||||
#define JERRYX_SOURCES_H
|
||||
|
||||
#include "jerryscript-types.h"
|
||||
|
||||
JERRY_C_API_BEGIN
|
||||
|
||||
jerry_value_t jerryx_source_parse_script (const char* path);
|
||||
jerry_value_t jerryx_source_exec_script (const char* path);
|
||||
jerry_value_t jerryx_source_exec_module (const char* path);
|
||||
jerry_value_t jerryx_source_exec_snapshot (const char* path, size_t function_index);
|
||||
jerry_value_t jerryx_source_exec_stdin (void);
|
||||
|
||||
JERRY_C_API_END
|
||||
|
||||
#endif /* !JERRYX_EXEC_H */
|
||||
27
jerry-ext/include/jerryscript-ext/test262.h
Normal file
27
jerry-ext/include/jerryscript-ext/test262.h
Normal file
@ -0,0 +1,27 @@
|
||||
/* Copyright JS Foundation and other contributors, http://js.foundation
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#ifndef JERRYX_TEST262_H
|
||||
#define JERRYX_TEST262_H
|
||||
|
||||
#include "jerryscript-types.h"
|
||||
|
||||
JERRY_C_API_BEGIN
|
||||
|
||||
void jerryx_test262_register (void);
|
||||
|
||||
JERRY_C_API_END
|
||||
|
||||
#endif /* !JERRYX_TEST262_H */
|
||||
210
jerry-ext/util/handlers.c
Normal file
210
jerry-ext/util/handlers.c
Normal file
@ -0,0 +1,210 @@
|
||||
/* Copyright JS Foundation and other contributors, http://js.foundation
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#include "jerryscript-ext/handlers.h"
|
||||
|
||||
#include "jerryscript-core.h"
|
||||
#include "jerryscript-debugger.h"
|
||||
#include "jerryscript-port.h"
|
||||
|
||||
#include "jerryscript-ext/print.h"
|
||||
|
||||
/**
|
||||
* 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_byte.
|
||||
*
|
||||
* 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_byte`.
|
||||
*
|
||||
* @return undefined - if all arguments could be converted to strings,
|
||||
* error - otherwise.
|
||||
*/
|
||||
jerry_value_t
|
||||
jerryx_handler_print (const jerry_call_info_t *call_info_p, /**< call information */
|
||||
const jerry_value_t args_p[], /**< function arguments */
|
||||
const jerry_length_t args_cnt) /**< number of function arguments */
|
||||
{
|
||||
(void) call_info_p; /* unused */
|
||||
|
||||
for (jerry_length_t index = 0; index < args_cnt; index++)
|
||||
{
|
||||
if (index > 0)
|
||||
{
|
||||
jerryx_print_byte (' ');
|
||||
}
|
||||
|
||||
jerry_value_t result = jerryx_print_value (args_p[index]);
|
||||
|
||||
if (jerry_value_is_exception (result))
|
||||
{
|
||||
return result;
|
||||
}
|
||||
}
|
||||
|
||||
jerryx_print_byte ('\n');
|
||||
return jerry_undefined ();
|
||||
} /* jerryx_handler_print */
|
||||
|
||||
/**
|
||||
* Hard assert for scripts. The routine calls jerry_port_fatal on assertion failure.
|
||||
*
|
||||
* Notes:
|
||||
* * If the `JERRY_FEATURE_LINE_INFO` runtime feature is enabled (build option: `JERRY_LINE_INFO`)
|
||||
* a backtrace is also printed out.
|
||||
*
|
||||
* @return true - if only one argument was passed and that argument was a boolean true.
|
||||
* Note that the function does not return otherwise.
|
||||
*/
|
||||
jerry_value_t
|
||||
jerryx_handler_assert (const jerry_call_info_t *call_info_p, /**< call information */
|
||||
const jerry_value_t args_p[], /**< function arguments */
|
||||
const jerry_length_t args_cnt) /**< number of function arguments */
|
||||
{
|
||||
(void) call_info_p; /* unused */
|
||||
|
||||
if (args_cnt == 1 && jerry_value_is_true (args_p[0]))
|
||||
{
|
||||
return jerry_boolean (true);
|
||||
}
|
||||
|
||||
/* Assert failed, print a bit of JS backtrace */
|
||||
jerry_log (JERRY_LOG_LEVEL_ERROR, "Script Error: assertion failed\n");
|
||||
jerryx_print_backtrace (5);
|
||||
|
||||
jerry_port_fatal (JERRY_FATAL_FAILED_ASSERTION);
|
||||
} /* jerryx_handler_assert_fatal */
|
||||
|
||||
/**
|
||||
* Expose garbage collector to scripts.
|
||||
*
|
||||
* @return undefined.
|
||||
*/
|
||||
jerry_value_t
|
||||
jerryx_handler_gc (const jerry_call_info_t *call_info_p, /**< call information */
|
||||
const jerry_value_t args_p[], /**< function arguments */
|
||||
const jerry_length_t args_cnt) /**< number of function arguments */
|
||||
{
|
||||
(void) call_info_p; /* unused */
|
||||
|
||||
jerry_gc_mode_t mode =
|
||||
((args_cnt > 0 && jerry_value_to_boolean (args_p[0])) ? JERRY_GC_PRESSURE_HIGH : JERRY_GC_PRESSURE_LOW);
|
||||
|
||||
jerry_heap_gc (mode);
|
||||
return jerry_undefined ();
|
||||
} /* jerryx_handler_gc */
|
||||
|
||||
/**
|
||||
* Get the resource name (usually a file name) of the currently executed script or the given function object
|
||||
*
|
||||
* Note: returned value must be freed with jerry_value_free, when it is no longer needed
|
||||
*
|
||||
* @return JS string constructed from
|
||||
* - the currently executed function object's resource name, if the given value is undefined
|
||||
* - resource name of the function object, if the given value is a function object
|
||||
* - "<anonymous>", otherwise
|
||||
*/
|
||||
jerry_value_t
|
||||
jerryx_handler_source_name (const jerry_call_info_t *call_info_p, /**< call information */
|
||||
const jerry_value_t args_p[], /**< function arguments */
|
||||
const jerry_length_t args_cnt) /**< number of function arguments */
|
||||
{
|
||||
(void) call_info_p; /* unused */
|
||||
|
||||
jerry_value_t undefined_value = jerry_undefined ();
|
||||
jerry_value_t source_name = jerry_source_name (args_cnt > 0 ? args_p[0] : undefined_value);
|
||||
jerry_value_free (undefined_value);
|
||||
|
||||
return source_name;
|
||||
} /* jerryx_handler_source_name */
|
||||
|
||||
/**
|
||||
* Create a new realm.
|
||||
*
|
||||
* @return new Realm object
|
||||
*/
|
||||
jerry_value_t
|
||||
jerryx_handler_create_realm (const jerry_call_info_t *call_info_p, /**< call information */
|
||||
const jerry_value_t args_p[], /**< function arguments */
|
||||
const jerry_length_t args_cnt) /**< number of function arguments */
|
||||
{
|
||||
(void) call_info_p; /* unused */
|
||||
(void) args_p; /* unused */
|
||||
(void) args_cnt; /* unused */
|
||||
return jerry_realm ();
|
||||
} /* jerryx_handler_create_realm */
|
||||
|
||||
/**
|
||||
* Handler for unhandled promise rejection events.
|
||||
*/
|
||||
void
|
||||
jerryx_handler_promise_reject (jerry_promise_event_type_t event_type, /**< event type */
|
||||
const jerry_value_t object, /**< target object */
|
||||
const jerry_value_t value, /**< optional argument */
|
||||
void *user_p) /**< user pointer passed to the callback */
|
||||
{
|
||||
(void) value;
|
||||
(void) user_p;
|
||||
|
||||
if (event_type != JERRY_PROMISE_EVENT_REJECT_WITHOUT_HANDLER)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
jerry_value_t result = jerry_promise_result (object);
|
||||
jerryx_print_unhandled_rejection (result);
|
||||
|
||||
jerry_value_free (result);
|
||||
} /* jerryx_handler_promise_reject */
|
||||
|
||||
/**
|
||||
* Runs the source code received by jerry_debugger_wait_for_client_source.
|
||||
*
|
||||
* @return result fo the source code execution
|
||||
*/
|
||||
jerry_value_t
|
||||
jerryx_handler_source_received (const jerry_char_t *source_name_p, /**< resource name */
|
||||
size_t source_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; /* unused */
|
||||
|
||||
jerry_parse_options_t parse_options;
|
||||
parse_options.options = JERRY_PARSE_HAS_SOURCE_NAME;
|
||||
parse_options.source_name = jerry_string (source_name_p, (jerry_size_t) source_name_size, JERRY_ENCODING_UTF8);
|
||||
|
||||
jerry_value_t ret_val = jerry_parse (source_p, source_size, &parse_options);
|
||||
|
||||
jerry_value_free (parse_options.source_name);
|
||||
|
||||
if (!jerry_value_is_exception (ret_val))
|
||||
{
|
||||
jerry_value_t func_val = ret_val;
|
||||
ret_val = jerry_run (func_val);
|
||||
jerry_value_free (func_val);
|
||||
}
|
||||
|
||||
return ret_val;
|
||||
} /* jerryx_handler_source_received */
|
||||
367
jerry-ext/util/print.c
Normal file
367
jerry-ext/util/print.c
Normal file
@ -0,0 +1,367 @@
|
||||
/* Copyright JS Foundation and other contributors, http://js.foundation
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#include "jerryscript-ext/print.h"
|
||||
|
||||
#include <assert.h>
|
||||
#include <inttypes.h>
|
||||
#include <stdarg.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "jerryscript-core.h"
|
||||
#include "jerryscript-debugger.h"
|
||||
#include "jerryscript-port.h"
|
||||
|
||||
/**
|
||||
* Print buffer size
|
||||
*/
|
||||
#define JERRYX_PRINT_BUFFER_SIZE 64
|
||||
|
||||
/**
|
||||
* Max line size that will be printed on a Syntax Error
|
||||
*/
|
||||
#define JERRYX_SYNTAX_ERROR_MAX_LINE_LENGTH 256
|
||||
|
||||
/**
|
||||
* Struct for buffering print outpu
|
||||
*/
|
||||
typedef struct
|
||||
{
|
||||
jerry_size_t index; /**< write index */
|
||||
jerry_char_t data[JERRYX_PRINT_BUFFER_SIZE]; /**< buffer data */
|
||||
} jerryx_print_buffer_t;
|
||||
|
||||
/**
|
||||
* Callback used by jerryx_print_value to batch written characters and print them in bulk.
|
||||
* NULL bytes are escaped and written as '\u0000'.
|
||||
*
|
||||
* @param value: encoded byte value
|
||||
* @param user_p: user pointer
|
||||
*/
|
||||
static void
|
||||
jerryx_buffered_print (uint32_t value, void *user_p)
|
||||
{
|
||||
jerryx_print_buffer_t *buffer_p = (jerryx_print_buffer_t *) user_p;
|
||||
|
||||
if (value == '\0')
|
||||
{
|
||||
jerryx_print_buffer (buffer_p->data, buffer_p->index);
|
||||
buffer_p->index = 0;
|
||||
|
||||
jerryx_print_string ("\\u0000");
|
||||
return;
|
||||
}
|
||||
|
||||
assert (value <= UINT8_MAX);
|
||||
buffer_p->data[buffer_p->index++] = (uint8_t) value;
|
||||
|
||||
if (buffer_p->index >= JERRYX_PRINT_BUFFER_SIZE)
|
||||
{
|
||||
jerryx_print_buffer (buffer_p->data, buffer_p->index);
|
||||
buffer_p->index = 0;
|
||||
}
|
||||
} /* jerryx_buffered_print */
|
||||
|
||||
/**
|
||||
* Convert a value to string and print it to standard output.
|
||||
* NULL characters are escaped to "\u0000", other characters are output as-is.
|
||||
*
|
||||
* @param value: input value
|
||||
*/
|
||||
jerry_value_t
|
||||
jerryx_print_value (const jerry_value_t value)
|
||||
{
|
||||
jerry_value_t string;
|
||||
|
||||
if (jerry_value_is_symbol (value))
|
||||
{
|
||||
string = jerry_symbol_descriptive_string (value);
|
||||
}
|
||||
else
|
||||
{
|
||||
string = jerry_value_to_string (value);
|
||||
|
||||
if (jerry_value_is_exception (string))
|
||||
{
|
||||
return string;
|
||||
}
|
||||
}
|
||||
|
||||
jerryx_print_buffer_t buffer;
|
||||
buffer.index = 0;
|
||||
|
||||
jerry_string_iterate (string, JERRY_ENCODING_UTF8, &jerryx_buffered_print, &buffer);
|
||||
jerry_value_free (string);
|
||||
|
||||
jerryx_print_buffer (buffer.data, buffer.index);
|
||||
|
||||
return jerry_undefined ();
|
||||
} /* jerryx_print */
|
||||
|
||||
/**
|
||||
* Print a character to standard output, also sending it to the debugger, if connected.
|
||||
*
|
||||
* @param ch: input character
|
||||
*/
|
||||
void
|
||||
jerryx_print_byte (jerry_char_t byte)
|
||||
{
|
||||
jerry_port_print_byte (byte);
|
||||
#if JERRY_DEBUGGER
|
||||
jerry_debugger_send_output (&byte, 1);
|
||||
#endif /* JERRY_DEBUGGER */
|
||||
} /* jerryx_print_char */
|
||||
|
||||
/**
|
||||
* Print a buffer to standard output, also sending it to the debugger, if connected.
|
||||
*
|
||||
* @param buffer_p: inptut string buffer
|
||||
* @param buffer_size: size of the string
|
||||
*/
|
||||
void
|
||||
jerryx_print_buffer (const jerry_char_t *buffer_p, jerry_size_t buffer_size)
|
||||
{
|
||||
jerry_port_print_buffer (buffer_p, buffer_size);
|
||||
#if JERRY_DEBUGGER
|
||||
jerry_debugger_send_output (buffer_p, buffer_size);
|
||||
#endif /* JERRY_DEBUGGER */
|
||||
} /* jerryx_print_buffer */
|
||||
|
||||
/**
|
||||
* Print a zero-terminated string to standard output, also sending it to the debugger, if connected.
|
||||
*
|
||||
* @param buffer_p: inptut string buffer
|
||||
* @param buffer_size: size of the string
|
||||
*/
|
||||
void
|
||||
jerryx_print_string (const char *str_p)
|
||||
{
|
||||
const jerry_char_t *buffer_p = (jerry_char_t *) str_p;
|
||||
jerry_size_t buffer_size = (jerry_size_t) (strlen (str_p));
|
||||
|
||||
jerry_port_print_buffer (buffer_p, buffer_size);
|
||||
#if JERRY_DEBUGGER
|
||||
jerry_debugger_send_output (buffer_p, buffer_size);
|
||||
#endif /* JERRY_DEBUGGER */
|
||||
} /* jerryx_print_string */
|
||||
|
||||
/**
|
||||
* Print backtrace as log messages up to a specific depth.
|
||||
*
|
||||
* @param depth: backtrace depth
|
||||
*/
|
||||
void
|
||||
jerryx_print_backtrace (unsigned depth)
|
||||
{
|
||||
if (!jerry_feature_enabled (JERRY_FEATURE_LINE_INFO))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
jerry_log (JERRY_LOG_LEVEL_ERROR, "Script backtrace (top %u):\n", depth);
|
||||
|
||||
jerry_value_t backtrace_array = jerry_backtrace (depth);
|
||||
unsigned array_length = jerry_array_length (backtrace_array);
|
||||
|
||||
for (unsigned idx = 0; idx < array_length; idx++)
|
||||
{
|
||||
jerry_value_t property = jerry_object_get_index (backtrace_array, idx);
|
||||
|
||||
jerry_char_t buffer[JERRYX_PRINT_BUFFER_SIZE];
|
||||
|
||||
jerry_size_t copied = jerry_string_to_buffer (property, JERRY_ENCODING_UTF8, buffer, JERRYX_PRINT_BUFFER_SIZE - 1);
|
||||
buffer[copied] = '\0';
|
||||
|
||||
jerry_log (JERRY_LOG_LEVEL_ERROR, " %u: %s\n", idx, buffer);
|
||||
jerry_value_free (property);
|
||||
}
|
||||
|
||||
jerry_value_free (backtrace_array);
|
||||
} /* jerryx_handler_assert_fatal */
|
||||
|
||||
/**
|
||||
* Print an unhandled exception value
|
||||
*
|
||||
* The function will take ownership of the value, and free it.
|
||||
*
|
||||
* @param exception: unhandled exception value
|
||||
*/
|
||||
void
|
||||
jerryx_print_unhandled_exception (jerry_value_t exception) /**< exception value */
|
||||
{
|
||||
assert (jerry_value_is_exception (exception));
|
||||
jerry_value_t value = jerry_exception_value (exception, true);
|
||||
|
||||
JERRY_VLA (jerry_char_t, buffer_p, JERRYX_PRINT_BUFFER_SIZE);
|
||||
|
||||
jerry_value_t string = jerry_value_to_string (value);
|
||||
|
||||
jerry_size_t copied = jerry_string_to_buffer (string, JERRY_ENCODING_UTF8, buffer_p, JERRYX_PRINT_BUFFER_SIZE - 1);
|
||||
buffer_p[copied] = '\0';
|
||||
|
||||
if (jerry_feature_enabled (JERRY_FEATURE_ERROR_MESSAGES) && jerry_error_type (value) == JERRY_ERROR_SYNTAX)
|
||||
{
|
||||
jerry_char_t *string_end_p = buffer_p + copied;
|
||||
jerry_size_t err_line = 0;
|
||||
jerry_size_t err_col = 0;
|
||||
char *path_str_p = NULL;
|
||||
char *path_str_end_p = NULL;
|
||||
|
||||
/* 1. parse column and line information */
|
||||
for (jerry_char_t *current_p = buffer_p; current_p < string_end_p; current_p++)
|
||||
{
|
||||
if (*current_p == '[')
|
||||
{
|
||||
current_p++;
|
||||
|
||||
if (*current_p == '<')
|
||||
{
|
||||
break;
|
||||
}
|
||||
|
||||
path_str_p = (char *) current_p;
|
||||
while (current_p < string_end_p && *current_p != ':')
|
||||
{
|
||||
current_p++;
|
||||
}
|
||||
|
||||
path_str_end_p = (char *) current_p++;
|
||||
|
||||
err_line = (unsigned int) strtol ((char *) current_p, (char **) ¤t_p, 10);
|
||||
|
||||
current_p++;
|
||||
|
||||
err_col = (unsigned int) strtol ((char *) current_p, NULL, 10);
|
||||
break;
|
||||
}
|
||||
} /* for */
|
||||
|
||||
if (err_line > 0 && err_col > 0 && err_col < JERRYX_SYNTAX_ERROR_MAX_LINE_LENGTH)
|
||||
{
|
||||
/* Temporarily modify the error message, so we can use the path. */
|
||||
*path_str_end_p = '\0';
|
||||
|
||||
jerry_size_t source_size;
|
||||
jerry_char_t *source_p = jerry_port_source_read (path_str_p, &source_size);
|
||||
|
||||
/* Revert the error message. */
|
||||
*path_str_end_p = ':';
|
||||
|
||||
if (source_p != NULL)
|
||||
{
|
||||
uint32_t curr_line = 1;
|
||||
jerry_size_t pos = 0;
|
||||
|
||||
/* 2. seek and print */
|
||||
while (pos < source_size && curr_line < err_line)
|
||||
{
|
||||
if (source_p[pos] == '\n')
|
||||
{
|
||||
curr_line++;
|
||||
}
|
||||
|
||||
pos++;
|
||||
}
|
||||
|
||||
/* Print character if:
|
||||
* - The max line length is not reached.
|
||||
* - The current position is valid (it is not the end of the source).
|
||||
* - The current character is not a newline.
|
||||
**/
|
||||
for (uint32_t char_count = 0;
|
||||
(char_count < JERRYX_SYNTAX_ERROR_MAX_LINE_LENGTH) && (pos < source_size) && (source_p[pos] != '\n');
|
||||
char_count++, pos++)
|
||||
{
|
||||
jerry_log (JERRY_LOG_LEVEL_ERROR, "%c", source_p[pos]);
|
||||
}
|
||||
|
||||
jerry_log (JERRY_LOG_LEVEL_ERROR, "\n");
|
||||
jerry_port_source_free (source_p);
|
||||
|
||||
while (--err_col)
|
||||
{
|
||||
jerry_log (JERRY_LOG_LEVEL_ERROR, "~");
|
||||
}
|
||||
|
||||
jerry_log (JERRY_LOG_LEVEL_ERROR, "^\n\n");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
jerry_log (JERRY_LOG_LEVEL_ERROR, "Unhandled exception: %s\n", buffer_p);
|
||||
jerry_value_free (string);
|
||||
|
||||
if (jerry_value_is_object (value))
|
||||
{
|
||||
jerry_value_t backtrace_val = jerry_object_get_sz (value, "stack");
|
||||
|
||||
if (jerry_value_is_array (backtrace_val))
|
||||
{
|
||||
uint32_t length = jerry_array_length (backtrace_val);
|
||||
|
||||
/* This length should be enough. */
|
||||
if (length > 32)
|
||||
{
|
||||
length = 32;
|
||||
}
|
||||
|
||||
for (unsigned i = 0; i < length; i++)
|
||||
{
|
||||
jerry_value_t item_val = jerry_object_get_index (backtrace_val, i);
|
||||
|
||||
if (jerry_value_is_string (item_val))
|
||||
{
|
||||
copied = jerry_string_to_buffer (item_val, JERRY_ENCODING_UTF8, buffer_p, JERRYX_PRINT_BUFFER_SIZE - 1);
|
||||
buffer_p[copied] = '\0';
|
||||
|
||||
jerry_log (JERRY_LOG_LEVEL_ERROR, " %u: %s\n", i, buffer_p);
|
||||
}
|
||||
|
||||
jerry_value_free (item_val);
|
||||
}
|
||||
}
|
||||
|
||||
jerry_value_free (backtrace_val);
|
||||
}
|
||||
|
||||
jerry_value_free (value);
|
||||
} /* jerryx_print_unhandled_exception */
|
||||
|
||||
/**
|
||||
* Print unhandled promise rejection.
|
||||
*
|
||||
* @param result: promise rejection result
|
||||
*/
|
||||
void
|
||||
jerryx_print_unhandled_rejection (jerry_value_t result) /**< result value */
|
||||
{
|
||||
jerry_value_t reason = jerry_value_to_string (result);
|
||||
|
||||
if (!jerry_value_is_exception (reason))
|
||||
{
|
||||
JERRY_VLA (jerry_char_t, buffer_p, JERRYX_PRINT_BUFFER_SIZE);
|
||||
jerry_size_t copied = jerry_string_to_buffer (reason, JERRY_ENCODING_UTF8, buffer_p, JERRYX_PRINT_BUFFER_SIZE - 1);
|
||||
buffer_p[copied] = '\0';
|
||||
|
||||
jerry_log (JERRY_LOG_LEVEL_WARNING, "Uncaught Promise rejection: %s\n", buffer_p);
|
||||
}
|
||||
else
|
||||
{
|
||||
jerry_log (JERRY_LOG_LEVEL_WARNING, "Uncaught Promise rejection: (reason cannot be converted to string)\n");
|
||||
}
|
||||
|
||||
jerry_value_free (reason);
|
||||
} /* jerryx_print_unhandled_rejection */
|
||||
@ -13,33 +13,34 @@
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#include "jerryscript-ext/handler.h"
|
||||
#include "jerryscript-ext/properties.h"
|
||||
|
||||
#include "jerryscript-core.h"
|
||||
|
||||
/**
|
||||
* Register a JavaScript function in the global object.
|
||||
*
|
||||
* Note:
|
||||
* returned value must be freed with jerry_value_free, when it is no longer needed.
|
||||
*
|
||||
* @return true value - if the operation was successful,
|
||||
* error - otherwise.
|
||||
* @return true - if the operation was successful,
|
||||
* false - otherwise.
|
||||
*/
|
||||
jerry_value_t
|
||||
jerryx_handler_register_global (const char *name_p, /**< name of the function */
|
||||
jerry_external_handler_t handler_p) /**< function callback */
|
||||
bool
|
||||
jerryx_register_global (const char *name_p, /**< name of the function */
|
||||
jerry_external_handler_t handler_p) /**< function callback */
|
||||
{
|
||||
jerry_value_t global_obj_val = jerry_current_realm ();
|
||||
jerry_value_t function_name_val = jerry_string_sz (name_p);
|
||||
jerry_value_t function_val = jerry_function_external (handler_p);
|
||||
|
||||
jerry_value_t result_val = jerry_object_set (global_obj_val, function_name_val, function_val);
|
||||
bool result = jerry_value_is_true (result_val);
|
||||
|
||||
jerry_value_free (result_val);
|
||||
jerry_value_free (function_val);
|
||||
jerry_value_free (function_name_val);
|
||||
jerry_value_free (global_obj_val);
|
||||
|
||||
return result_val;
|
||||
} /* jerryx_handler_register_global */
|
||||
return result;
|
||||
} /* jerryx_register_global */
|
||||
|
||||
/**
|
||||
* Set multiple properties on a target object.
|
||||
@ -115,81 +116,3 @@ jerryx_release_property_entry (const jerryx_property_entry entries[], /**< list
|
||||
jerry_value_free (entries[idx].value);
|
||||
}
|
||||
} /* jerryx_release_property_entry */
|
||||
|
||||
/**
|
||||
* Set a property to a specified value with a given name.
|
||||
*
|
||||
* Notes:
|
||||
* - The operation performed is the same as what the `jerry_object_set` 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.
|
||||
* - Returned value must be freed with jerry_value_free, when it is no longer needed.
|
||||
*
|
||||
* @return true value - if the operation was successful
|
||||
* thrown error - otherwise
|
||||
*/
|
||||
jerry_value_t
|
||||
jerryx_set_property_str (const jerry_value_t target_object, /**< target object */
|
||||
const char *name, /**< property name */
|
||||
const jerry_value_t value) /**< value to set */
|
||||
{
|
||||
jerry_value_t property_name_val = jerry_string_sz (name);
|
||||
jerry_value_t result_val = jerry_object_set (target_object, property_name_val, value);
|
||||
|
||||
jerry_value_free (property_name_val);
|
||||
|
||||
return result_val;
|
||||
} /* jerryx_set_property_str */
|
||||
|
||||
/**
|
||||
* Get a property value of a specified object.
|
||||
*
|
||||
* Notes:
|
||||
* - The operation performed is the same as what the `jerry_object_get` 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.
|
||||
* - Returned value must be freed with jerry_value_free, when it is no longer needed.
|
||||
*
|
||||
* @return jerry_value_t - the property value
|
||||
*/
|
||||
jerry_value_t
|
||||
jerryx_get_property_str (const jerry_value_t target_object, /**< target object */
|
||||
const char *name) /**< property name */
|
||||
{
|
||||
jerry_value_t prop_name = jerry_string_sz (name);
|
||||
jerry_value_t result_val = jerry_object_get (target_object, prop_name);
|
||||
jerry_value_free (prop_name);
|
||||
|
||||
return result_val;
|
||||
} /* jerryx_get_property_str */
|
||||
|
||||
/**
|
||||
* Check if a property exists on an object.
|
||||
*
|
||||
* Notes:
|
||||
* - The operation performed is the same as what the `jerry_object_has` 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.
|
||||
*
|
||||
* @return true - if the property exists on the given object.
|
||||
* false - if there is no such property or there was an error accessing the property.
|
||||
*/
|
||||
bool
|
||||
jerryx_has_property_str (const jerry_value_t target_object, /**< target object */
|
||||
const char *name) /**< property name */
|
||||
{
|
||||
bool has_property = false;
|
||||
|
||||
jerry_value_t prop_name = jerry_string_sz (name);
|
||||
jerry_value_t has_prop_val = jerry_object_has (target_object, prop_name);
|
||||
|
||||
if (!jerry_value_is_exception (has_prop_val))
|
||||
{
|
||||
has_property = jerry_value_is_true (has_prop_val);
|
||||
}
|
||||
|
||||
jerry_value_free (has_prop_val);
|
||||
jerry_value_free (prop_name);
|
||||
|
||||
return has_property;
|
||||
} /* jerryx_has_property_str */
|
||||
97
jerry-ext/util/repl.c
Normal file
97
jerry-ext/util/repl.c
Normal file
@ -0,0 +1,97 @@
|
||||
/* Copyright JS Foundation and other contributors, http://js.foundation
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#include "jerryscript-ext/repl.h"
|
||||
|
||||
#include <string.h>
|
||||
|
||||
#include "jerryscript-port.h"
|
||||
#include "jerryscript.h"
|
||||
|
||||
#include "jerryscript-ext/print.h"
|
||||
|
||||
void
|
||||
jerryx_repl (const char *prompt_p)
|
||||
{
|
||||
jerry_value_t result;
|
||||
|
||||
while (true)
|
||||
{
|
||||
jerryx_print_string (prompt_p);
|
||||
|
||||
jerry_size_t length;
|
||||
jerry_char_t *line_p = jerry_port_line_read (&length);
|
||||
|
||||
if (line_p == NULL)
|
||||
{
|
||||
jerryx_print_byte ('\n');
|
||||
return;
|
||||
}
|
||||
|
||||
if (length == 0)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
if (!jerry_validate_string (line_p, length, JERRY_ENCODING_UTF8))
|
||||
{
|
||||
jerry_port_line_free (line_p);
|
||||
result = jerry_throw_sz (JERRY_ERROR_SYNTAX, "Input is not a valid UTF-8 string");
|
||||
goto exception;
|
||||
}
|
||||
|
||||
result = jerry_parse (line_p, length, NULL);
|
||||
jerry_port_line_free (line_p);
|
||||
|
||||
if (jerry_value_is_exception (result))
|
||||
{
|
||||
goto exception;
|
||||
}
|
||||
|
||||
jerry_value_t script = result;
|
||||
result = jerry_run (script);
|
||||
jerry_value_free (script);
|
||||
|
||||
if (jerry_value_is_exception (result))
|
||||
{
|
||||
goto exception;
|
||||
}
|
||||
|
||||
jerry_value_t print_result = jerryx_print_value (result);
|
||||
jerry_value_free (result);
|
||||
result = print_result;
|
||||
|
||||
if (jerry_value_is_exception (result))
|
||||
{
|
||||
goto exception;
|
||||
}
|
||||
|
||||
jerryx_print_byte ('\n');
|
||||
|
||||
jerry_value_free (result);
|
||||
result = jerry_run_jobs ();
|
||||
|
||||
if (jerry_value_is_exception (result))
|
||||
{
|
||||
goto exception;
|
||||
}
|
||||
|
||||
jerry_value_free (result);
|
||||
continue;
|
||||
|
||||
exception:
|
||||
jerryx_print_unhandled_exception (result);
|
||||
}
|
||||
} /* jerryx_repl */
|
||||
174
jerry-ext/util/sources.c
Normal file
174
jerry-ext/util/sources.c
Normal file
@ -0,0 +1,174 @@
|
||||
/* Copyright JS Foundation and other contributors, http://js.foundation
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#include "jerryscript-ext/sources.h"
|
||||
|
||||
#include <assert.h>
|
||||
#include <inttypes.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "jerryscript-debugger.h"
|
||||
#include "jerryscript-port.h"
|
||||
#include "jerryscript.h"
|
||||
|
||||
#include "jerryscript-ext/print.h"
|
||||
|
||||
jerry_value_t
|
||||
jerryx_source_parse_script (const char *path_p)
|
||||
{
|
||||
jerry_size_t source_size;
|
||||
jerry_char_t *source_p = jerry_port_source_read (path_p, &source_size);
|
||||
|
||||
if (source_p == NULL)
|
||||
{
|
||||
jerry_log (JERRY_LOG_LEVEL_ERROR, "Failed to open file: %s\n", path_p);
|
||||
return jerry_throw_sz (JERRY_ERROR_SYNTAX, "Source file not found");
|
||||
}
|
||||
|
||||
if (!jerry_validate_string (source_p, source_size, JERRY_ENCODING_UTF8))
|
||||
{
|
||||
jerry_port_source_free (source_p);
|
||||
return jerry_throw_sz (JERRY_ERROR_SYNTAX, "Input is not a valid UTF-8 encoded string.");
|
||||
}
|
||||
|
||||
jerry_parse_options_t parse_options;
|
||||
parse_options.options = JERRY_PARSE_HAS_SOURCE_NAME;
|
||||
parse_options.source_name =
|
||||
jerry_string ((const jerry_char_t *) path_p, (jerry_size_t) strlen (path_p), JERRY_ENCODING_UTF8);
|
||||
|
||||
jerry_value_t result = jerry_parse (source_p, source_size, &parse_options);
|
||||
|
||||
jerry_value_free (parse_options.source_name);
|
||||
jerry_port_source_free (source_p);
|
||||
|
||||
return result;
|
||||
} /* jerryx_source_parse_script */
|
||||
|
||||
jerry_value_t
|
||||
jerryx_source_exec_script (const char *path_p)
|
||||
{
|
||||
jerry_value_t result = jerryx_source_parse_script (path_p);
|
||||
|
||||
if (!jerry_value_is_exception (result))
|
||||
{
|
||||
jerry_value_t script = result;
|
||||
result = jerry_run (script);
|
||||
jerry_value_free (script);
|
||||
}
|
||||
|
||||
return result;
|
||||
} /* jerryx_source_exec_script */
|
||||
|
||||
jerry_value_t
|
||||
jerryx_source_exec_module (const char *path_p)
|
||||
{
|
||||
jerry_value_t specifier =
|
||||
jerry_string ((const jerry_char_t *) path_p, (jerry_size_t) strlen (path_p), JERRY_ENCODING_UTF8);
|
||||
jerry_value_t referrer = jerry_undefined ();
|
||||
|
||||
jerry_value_t module = jerry_module_resolve (specifier, referrer, NULL);
|
||||
|
||||
jerry_value_free (referrer);
|
||||
jerry_value_free (specifier);
|
||||
|
||||
if (jerry_value_is_exception (module))
|
||||
{
|
||||
return module;
|
||||
}
|
||||
|
||||
if (jerry_module_state (module) == JERRY_MODULE_STATE_UNLINKED)
|
||||
{
|
||||
jerry_value_t link_result = jerry_module_link (module, NULL, NULL);
|
||||
|
||||
if (jerry_value_is_exception (link_result))
|
||||
{
|
||||
jerry_value_free (module);
|
||||
return link_result;
|
||||
}
|
||||
|
||||
jerry_value_free (link_result);
|
||||
}
|
||||
|
||||
jerry_value_t result = jerry_module_evaluate (module);
|
||||
jerry_value_free (module);
|
||||
|
||||
jerry_module_cleanup (jerry_undefined ());
|
||||
return result;
|
||||
} /* jerryx_source_exec_module */
|
||||
|
||||
jerry_value_t
|
||||
jerryx_source_exec_snapshot (const char *path_p, size_t function_index)
|
||||
{
|
||||
jerry_size_t source_size;
|
||||
jerry_char_t *source_p = jerry_port_source_read (path_p, &source_size);
|
||||
|
||||
if (source_p == NULL)
|
||||
{
|
||||
jerry_log (JERRY_LOG_LEVEL_ERROR, "Failed to open file: %s\n", path_p);
|
||||
return jerry_throw_sz (JERRY_ERROR_SYNTAX, "Snapshot file not found");
|
||||
}
|
||||
|
||||
jerry_value_t result =
|
||||
jerry_exec_snapshot ((uint32_t *) source_p, source_size, function_index, JERRY_SNAPSHOT_EXEC_COPY_DATA, NULL);
|
||||
|
||||
jerry_port_source_free (source_p);
|
||||
return result;
|
||||
} /* jerryx_source_exec_snapshot */
|
||||
|
||||
jerry_value_t
|
||||
jerryx_source_exec_stdin (void)
|
||||
{
|
||||
jerry_char_t *source_p = NULL;
|
||||
jerry_size_t source_size = 0;
|
||||
|
||||
while (true)
|
||||
{
|
||||
jerry_size_t line_size;
|
||||
jerry_char_t *line_p = jerry_port_line_read (&line_size);
|
||||
|
||||
if (line_p == NULL)
|
||||
{
|
||||
break;
|
||||
}
|
||||
|
||||
jerry_size_t new_size = source_size + line_size;
|
||||
source_p = realloc (source_p, new_size);
|
||||
|
||||
memcpy (source_p + source_size, line_p, line_size);
|
||||
jerry_port_line_free (line_p);
|
||||
source_size = new_size;
|
||||
}
|
||||
|
||||
if (!jerry_validate_string (source_p, source_size, JERRY_ENCODING_UTF8))
|
||||
{
|
||||
free (source_p);
|
||||
return jerry_throw_sz (JERRY_ERROR_SYNTAX, "Input is not a valid UTF-8 encoded string.");
|
||||
}
|
||||
|
||||
jerry_value_t result = jerry_parse (source_p, source_size, NULL);
|
||||
free (source_p);
|
||||
|
||||
if (jerry_value_is_exception (result))
|
||||
{
|
||||
return result;
|
||||
}
|
||||
|
||||
jerry_value_t script = result;
|
||||
result = jerry_run (script);
|
||||
jerry_value_free (script);
|
||||
|
||||
return result;
|
||||
} /* jerryx_source_exec_stdin */
|
||||
163
jerry-ext/util/test262.c
Normal file
163
jerry-ext/util/test262.c
Normal file
@ -0,0 +1,163 @@
|
||||
/* Copyright JS Foundation and other contributors, http://js.foundation
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#include "jerryscript-ext/test262.h"
|
||||
|
||||
#include <assert.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "jerryscript.h"
|
||||
|
||||
#include "jerryscript-ext/handlers.h"
|
||||
|
||||
/**
|
||||
* Register a method for the $262 object.
|
||||
*/
|
||||
static void
|
||||
jerryx_test262_register_function (jerry_value_t test262_obj, /** $262 object */
|
||||
const char *name_p, /**< name of the function */
|
||||
jerry_external_handler_t handler_p) /**< function callback */
|
||||
{
|
||||
jerry_value_t function_val = jerry_function_external (handler_p);
|
||||
jerry_value_t result_val = jerry_object_set_sz (test262_obj, name_p, function_val);
|
||||
jerry_value_free (function_val);
|
||||
|
||||
assert (!jerry_value_is_exception (result_val));
|
||||
jerry_value_free (result_val);
|
||||
} /* jerryx_test262_register_function */
|
||||
|
||||
/**
|
||||
* $262.detachArrayBuffer
|
||||
*
|
||||
* A function which implements the DetachArrayBuffer abstract operation
|
||||
*
|
||||
* @return null value - if success
|
||||
* value marked with error flag - otherwise
|
||||
*/
|
||||
static jerry_value_t
|
||||
jerryx_test262_detach_array_buffer (const jerry_call_info_t *call_info_p, /**< call information */
|
||||
const jerry_value_t args_p[], /**< function arguments */
|
||||
const jerry_length_t args_cnt) /**< number of function arguments */
|
||||
{
|
||||
(void) call_info_p; /* unused */
|
||||
|
||||
if (args_cnt < 1 || !jerry_value_is_arraybuffer (args_p[0]))
|
||||
{
|
||||
return jerry_throw_sz (JERRY_ERROR_TYPE, "Expected an ArrayBuffer object");
|
||||
}
|
||||
|
||||
/* TODO: support the optional 'key' argument */
|
||||
|
||||
return jerry_arraybuffer_detach (args_p[0]);
|
||||
} /* jerryx_test262_detach_array_buffer */
|
||||
|
||||
/**
|
||||
* $262.evalScript
|
||||
*
|
||||
* A function which accepts a string value as its first argument and executes it
|
||||
*
|
||||
* @return completion of the script parsing and execution.
|
||||
*/
|
||||
static jerry_value_t
|
||||
jerryx_test262_eval_script (const jerry_call_info_t *call_info_p, /**< call information */
|
||||
const jerry_value_t args_p[], /**< function arguments */
|
||||
const jerry_length_t args_cnt) /**< number of function arguments */
|
||||
{
|
||||
(void) call_info_p; /* unused */
|
||||
|
||||
if (args_cnt < 1 || !jerry_value_is_string (args_p[0]))
|
||||
{
|
||||
return jerry_throw_sz (JERRY_ERROR_TYPE, "Expected a string");
|
||||
}
|
||||
|
||||
jerry_value_t ret_value = jerry_parse_value (args_p[0], NULL);
|
||||
|
||||
if (!jerry_value_is_exception (ret_value))
|
||||
{
|
||||
jerry_value_t func_val = ret_value;
|
||||
ret_value = jerry_run (func_val);
|
||||
jerry_value_free (func_val);
|
||||
}
|
||||
|
||||
return ret_value;
|
||||
} /* jerryx_test262_eval_script */
|
||||
|
||||
static jerry_value_t jerryx_test262_create (jerry_value_t global_obj);
|
||||
|
||||
/**
|
||||
* $262.createRealm
|
||||
*
|
||||
* A function which creates a new realm object, and returns a newly created $262 object
|
||||
*
|
||||
* @return a new $262 object
|
||||
*/
|
||||
static jerry_value_t
|
||||
jerryx_test262_create_realm (const jerry_call_info_t *call_info_p, /**< call information */
|
||||
const jerry_value_t args_p[], /**< function arguments */
|
||||
const jerry_length_t args_cnt) /**< number of function arguments */
|
||||
{
|
||||
(void) call_info_p; /* unused */
|
||||
(void) args_p; /* unused */
|
||||
(void) args_cnt; /* unused */
|
||||
|
||||
jerry_value_t realm_object = jerry_realm ();
|
||||
jerry_value_t previous_realm = jerry_set_realm (realm_object);
|
||||
assert (!jerry_value_is_exception (previous_realm));
|
||||
|
||||
jerry_value_t test262_object = jerryx_test262_create (realm_object);
|
||||
jerry_set_realm (previous_realm);
|
||||
jerry_value_free (realm_object);
|
||||
|
||||
return test262_object;
|
||||
} /* jerryx_test262_create_realm */
|
||||
|
||||
/**
|
||||
* Create a new $262 object
|
||||
*
|
||||
* @return a new $262 object
|
||||
*/
|
||||
static jerry_value_t
|
||||
jerryx_test262_create (jerry_value_t global_obj) /**< global object */
|
||||
{
|
||||
jerry_value_t test262_object = jerry_object ();
|
||||
|
||||
jerryx_test262_register_function (test262_object, "detachArrayBuffer", jerryx_test262_detach_array_buffer);
|
||||
jerryx_test262_register_function (test262_object, "evalScript", jerryx_test262_eval_script);
|
||||
jerryx_test262_register_function (test262_object, "createRealm", jerryx_test262_create_realm);
|
||||
jerryx_test262_register_function (test262_object, "gc", jerryx_handler_gc);
|
||||
|
||||
jerry_value_t result = jerry_object_set_sz (test262_object, "global", global_obj);
|
||||
assert (!jerry_value_is_exception (result));
|
||||
jerry_value_free (result);
|
||||
|
||||
return test262_object;
|
||||
} /* create_test262 */
|
||||
|
||||
/**
|
||||
* Add a new test262 object to the current global object.
|
||||
*/
|
||||
void
|
||||
jerryx_test262_register (void)
|
||||
{
|
||||
jerry_value_t global_obj = jerry_current_realm ();
|
||||
jerry_value_t test262_obj = jerryx_test262_create (global_obj);
|
||||
|
||||
jerry_value_t result = jerry_object_set_sz (global_obj, "$262", test262_obj);
|
||||
assert (!jerry_value_is_exception (result));
|
||||
|
||||
jerry_value_free (result);
|
||||
jerry_value_free (test262_obj);
|
||||
jerry_value_free (global_obj);
|
||||
} /* jerryx_test262_register */
|
||||
@ -58,25 +58,25 @@ endmacro()
|
||||
|
||||
# Jerry with libfuzzer support
|
||||
if(JERRY_LIBFUZZER)
|
||||
jerry_create_executable("jerry-libfuzzer" "libfuzzer.c")
|
||||
target_link_libraries("jerry-libfuzzer" jerry-port-default -fsanitize=fuzzer)
|
||||
jerry_create_executable("jerry-libfuzzer" "main-libfuzzer.c")
|
||||
target_link_libraries("jerry-libfuzzer" jerry-port-fsanitize=fuzzer)
|
||||
endif()
|
||||
|
||||
# Jerry standalones
|
||||
if(JERRY_CMDLINE)
|
||||
jerry_create_executable("jerry" "main-jerry.c" "main-utils.c" "main-options.c" "cli.c")
|
||||
target_link_libraries("jerry" jerry-ext jerry-port-default)
|
||||
jerry_create_executable("jerry" "main-desktop.c" "arguments/options.c" "arguments/cli.c")
|
||||
target_link_libraries("jerry" jerry-ext jerry-port)
|
||||
endif()
|
||||
|
||||
if(JERRY_CMDLINE_TEST)
|
||||
jerry_create_executable("jerry-test" "main-jerry-test.c" "benchmarking.c")
|
||||
target_link_libraries("jerry-test" jerry-port-default)
|
||||
jerry_create_executable("jerry-test" "benchmark/main-benchmark.c" "benchmark/stubs.c")
|
||||
target_link_libraries("jerry-test" jerry-port)
|
||||
if (JERRY_TEST_STACK_MEASURE)
|
||||
target_compile_definitions("jerry-test" PRIVATE -DJERRY_TEST_STACK_MEASURE=1)
|
||||
endif()
|
||||
endif()
|
||||
|
||||
if(JERRY_CMDLINE_SNAPSHOT)
|
||||
jerry_create_executable("jerry-snapshot" "main-jerry-snapshot.c" "cli.c")
|
||||
target_link_libraries("jerry-snapshot" jerry-port-default)
|
||||
jerry_create_executable("jerry-snapshot" "main-snapshot.c" "arguments/cli.c")
|
||||
target_link_libraries("jerry-snapshot" jerry-port)
|
||||
endif()
|
||||
|
||||
@ -13,17 +13,17 @@
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#include "main-options.h"
|
||||
#include "options.h"
|
||||
|
||||
#include <stdbool.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
#include "jerryscript-port-default.h"
|
||||
#include "jerryscript-port.h"
|
||||
#include "jerryscript.h"
|
||||
|
||||
#include "cli.h"
|
||||
#include "main-utils.h"
|
||||
#include "jerryscript-ext/print.h"
|
||||
|
||||
/**
|
||||
* Command line option IDs
|
||||
@ -108,7 +108,7 @@ static const cli_opt_t main_opts[] = {
|
||||
* Check whether a usage-related condition holds. If not, print an error
|
||||
* message, print the usage, and terminate the application.
|
||||
*/
|
||||
static void
|
||||
static bool
|
||||
check_usage (bool condition, /**< the condition that must hold */
|
||||
const char *name, /**< name of the application (argv[0]) */
|
||||
const char *msg, /**< error message to print if condition does not hold */
|
||||
@ -116,9 +116,11 @@ check_usage (bool condition, /**< the condition that must hold */
|
||||
{
|
||||
if (!condition)
|
||||
{
|
||||
jerry_port_log (JERRY_LOG_LEVEL_ERROR, "%s: %s%s\n", name, msg, opt != NULL ? opt : "");
|
||||
exit (JERRY_STANDALONE_EXIT_CODE_FAIL);
|
||||
jerry_log (JERRY_LOG_LEVEL_ERROR, "%s: %s%s\n", name, msg, opt != NULL ? opt : "");
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
} /* check_usage */
|
||||
|
||||
/**
|
||||
@ -133,17 +135,21 @@ check_feature (jerry_feature_t feature, /**< feature to check */
|
||||
{
|
||||
if (!jerry_feature_enabled (feature))
|
||||
{
|
||||
jerry_port_default_set_log_level (JERRY_LOG_LEVEL_WARNING);
|
||||
jerry_port_log (JERRY_LOG_LEVEL_WARNING, "Ignoring '%s' option because this feature is disabled!\n", option);
|
||||
jerry_log_set_level (JERRY_LOG_LEVEL_WARNING);
|
||||
jerry_log (JERRY_LOG_LEVEL_WARNING, "Ignoring '%s' option because this feature is disabled!\n", option);
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
} /* check_feature */
|
||||
|
||||
/**
|
||||
* parse input arguments
|
||||
* Parse input arguments
|
||||
*
|
||||
* @return true, if application should continue execution
|
||||
* false, if application should exit
|
||||
*/
|
||||
void
|
||||
bool
|
||||
main_parse_args (int argc, /**< argc */
|
||||
char **argv, /**< argv */
|
||||
main_args_t *arguments_p) /**< [in/out] arguments reference */
|
||||
@ -159,6 +165,8 @@ main_parse_args (int argc, /**< argc */
|
||||
arguments_p->init_flags = JERRY_INIT_EMPTY;
|
||||
arguments_p->option_flags = OPT_FLAG_EMPTY;
|
||||
|
||||
arguments_p->parse_result = JERRY_STANDALONE_EXIT_CODE_FAIL;
|
||||
|
||||
cli_state_t cli_state = cli_init (main_opts, argc, argv);
|
||||
for (int id = cli_consume_option (&cli_state); id != CLI_OPT_END; id = cli_consume_option (&cli_state))
|
||||
{
|
||||
@ -167,9 +175,9 @@ main_parse_args (int argc, /**< argc */
|
||||
case OPT_HELP:
|
||||
{
|
||||
cli_help (argv[0], NULL, main_opts);
|
||||
exit (JERRY_STANDALONE_EXIT_CODE_OK);
|
||||
|
||||
break;
|
||||
arguments_p->parse_result = JERRY_STANDALONE_EXIT_CODE_OK;
|
||||
return false;
|
||||
}
|
||||
case OPT_VERSION:
|
||||
{
|
||||
@ -178,15 +186,15 @@ main_parse_args (int argc, /**< argc */
|
||||
JERRY_API_MINOR_VERSION,
|
||||
JERRY_API_PATCH_VERSION,
|
||||
JERRY_COMMIT_HASH);
|
||||
exit (JERRY_STANDALONE_EXIT_CODE_OK);
|
||||
|
||||
break;
|
||||
arguments_p->parse_result = JERRY_STANDALONE_EXIT_CODE_OK;
|
||||
return false;
|
||||
}
|
||||
case OPT_MEM_STATS:
|
||||
{
|
||||
if (check_feature (JERRY_FEATURE_HEAP_STATS, cli_state.arg))
|
||||
{
|
||||
jerry_port_default_set_log_level (JERRY_LOG_LEVEL_DEBUG);
|
||||
jerry_log_set_level (JERRY_LOG_LEVEL_DEBUG);
|
||||
arguments_p->init_flags |= JERRY_INIT_MEM_STATS;
|
||||
}
|
||||
break;
|
||||
@ -205,7 +213,7 @@ main_parse_args (int argc, /**< argc */
|
||||
{
|
||||
if (check_feature (JERRY_FEATURE_PARSER_DUMP, cli_state.arg))
|
||||
{
|
||||
jerry_port_default_set_log_level (JERRY_LOG_LEVEL_DEBUG);
|
||||
jerry_log_set_level (JERRY_LOG_LEVEL_DEBUG);
|
||||
arguments_p->init_flags |= JERRY_INIT_SHOW_OPCODES;
|
||||
}
|
||||
break;
|
||||
@ -219,7 +227,7 @@ main_parse_args (int argc, /**< argc */
|
||||
{
|
||||
if (check_feature (JERRY_FEATURE_REGEXP_DUMP, cli_state.arg))
|
||||
{
|
||||
jerry_port_default_set_log_level (JERRY_LOG_LEVEL_DEBUG);
|
||||
jerry_log_set_level (JERRY_LOG_LEVEL_DEBUG);
|
||||
arguments_p->init_flags |= JERRY_INIT_SHOW_REGEXP_OPCODES;
|
||||
}
|
||||
break;
|
||||
@ -245,10 +253,13 @@ main_parse_args (int argc, /**< argc */
|
||||
if (check_feature (JERRY_FEATURE_DEBUGGER, cli_state.arg))
|
||||
{
|
||||
const char *debug_channel = cli_consume_string (&cli_state);
|
||||
check_usage (!strcmp (debug_channel, "websocket") || !strcmp (debug_channel, "rawpacket"),
|
||||
argv[0],
|
||||
"Error: invalid value for --debug-channel: ",
|
||||
cli_state.arg);
|
||||
if (!check_usage (!strcmp (debug_channel, "websocket") || !strcmp (debug_channel, "rawpacket"),
|
||||
argv[0],
|
||||
"Error: invalid value for --debug-channel: ",
|
||||
cli_state.arg))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
arguments_p->debug_channel = debug_channel;
|
||||
}
|
||||
@ -259,10 +270,14 @@ main_parse_args (int argc, /**< argc */
|
||||
if (check_feature (JERRY_FEATURE_DEBUGGER, cli_state.arg))
|
||||
{
|
||||
const char *debug_protocol = cli_consume_string (&cli_state);
|
||||
check_usage (!strcmp (debug_protocol, "tcp") || !strcmp (debug_protocol, "serial"),
|
||||
argv[0],
|
||||
"Error: invalid value for --debug-protocol: ",
|
||||
cli_state.arg);
|
||||
|
||||
if (!check_usage (!strcmp (debug_protocol, "tcp") || !strcmp (debug_protocol, "serial"),
|
||||
argv[0],
|
||||
"Error: invalid value for --debug-protocol: ",
|
||||
cli_state.arg))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
arguments_p->debug_protocol = debug_protocol;
|
||||
}
|
||||
@ -335,12 +350,15 @@ main_parse_args (int argc, /**< argc */
|
||||
case OPT_LOG_LEVEL:
|
||||
{
|
||||
long int log_level = cli_consume_int (&cli_state);
|
||||
check_usage (log_level >= 0 && log_level <= 3,
|
||||
argv[0],
|
||||
"Error: invalid value for --log-level: ",
|
||||
cli_state.arg);
|
||||
if (!check_usage (log_level >= 0 && log_level <= 3,
|
||||
argv[0],
|
||||
"Error: invalid value for --log-level: ",
|
||||
cli_state.arg))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
jerry_port_default_set_log_level ((jerry_log_level_t) log_level);
|
||||
jerry_log_set_level ((jerry_log_level_t) log_level);
|
||||
break;
|
||||
}
|
||||
case OPT_NO_PROMPT:
|
||||
@ -374,13 +392,16 @@ main_parse_args (int argc, /**< argc */
|
||||
{
|
||||
if (cli_state.arg != NULL)
|
||||
{
|
||||
jerry_port_log (JERRY_LOG_LEVEL_ERROR, "Error: %s %s\n", cli_state.error, cli_state.arg);
|
||||
jerry_log (JERRY_LOG_LEVEL_ERROR, "Error: %s %s\n", cli_state.error, cli_state.arg);
|
||||
}
|
||||
else
|
||||
{
|
||||
jerry_port_log (JERRY_LOG_LEVEL_ERROR, "Error: %s\n", cli_state.error);
|
||||
jerry_log (JERRY_LOG_LEVEL_ERROR, "Error: %s\n", cli_state.error);
|
||||
}
|
||||
|
||||
exit (JERRY_STANDALONE_EXIT_CODE_FAIL);
|
||||
return false;
|
||||
}
|
||||
|
||||
arguments_p->parse_result = JERRY_STANDALONE_EXIT_CODE_OK;
|
||||
return true;
|
||||
} /* main_parse_args */
|
||||
@ -16,8 +16,15 @@
|
||||
#ifndef MAIN_OPTIONS_H
|
||||
#define MAIN_OPTIONS_H
|
||||
|
||||
#include <stdbool.h>
|
||||
#include <stdint.h>
|
||||
|
||||
/**
|
||||
* Standalone Jerry exit codes
|
||||
*/
|
||||
#define JERRY_STANDALONE_EXIT_CODE_OK (0)
|
||||
#define JERRY_STANDALONE_EXIT_CODE_FAIL (1)
|
||||
|
||||
/**
|
||||
* Argument option flags.
|
||||
*/
|
||||
@ -69,8 +76,9 @@ typedef struct
|
||||
|
||||
uint16_t option_flags;
|
||||
uint16_t init_flags;
|
||||
uint8_t parse_result;
|
||||
} main_args_t;
|
||||
|
||||
void main_parse_args (int argc, char **argv, main_args_t *arguments_p);
|
||||
bool main_parse_args (int argc, char **argv, main_args_t *arguments_p);
|
||||
|
||||
#endif /* !MAIN_OPTIONS_H */
|
||||
@ -13,6 +13,7 @@
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
@ -38,14 +39,14 @@ read_file (const char *file_name, size_t *out_size_p)
|
||||
FILE *file = fopen (file_name, "rb");
|
||||
if (file == NULL)
|
||||
{
|
||||
jerry_port_log (JERRY_LOG_LEVEL_ERROR, "Error: failed to open file: %s\n", file_name);
|
||||
jerry_log (JERRY_LOG_LEVEL_ERROR, "Error: failed to open file: %s\n", file_name);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
size_t bytes_read = fread (buffer, 1u, sizeof (buffer), file);
|
||||
if (!bytes_read)
|
||||
{
|
||||
jerry_port_log (JERRY_LOG_LEVEL_ERROR, "Error: failed to read file: %s\n", file_name);
|
||||
jerry_log (JERRY_LOG_LEVEL_ERROR, "Error: failed to read file: %s\n", file_name);
|
||||
fclose (file);
|
||||
return NULL;
|
||||
}
|
||||
@ -210,7 +211,7 @@ stack_usage (uint32_t *stack_top_p, size_t length_in_bytes)
|
||||
stack_p++;
|
||||
}
|
||||
|
||||
jerry_port_log (JERRY_LOG_LEVEL_ERROR, "Used stack: %d\n", (int) ((uint8_t *) stack_bottom_p - (uint8_t *) stack_p));
|
||||
jerry_log (JERRY_LOG_LEVEL_ERROR, "Used stack: %d\n", (int) ((uint8_t *) stack_bottom_p - (uint8_t *) stack_p));
|
||||
} /* stack_usage */
|
||||
|
||||
#else /* (JERRY_TEST_STACK_MEASURE) && (JERRY_TEST_STACK_MEASURE) */
|
||||
@ -226,7 +227,7 @@ main (int main_argc, char **main_argv)
|
||||
{
|
||||
double d;
|
||||
unsigned u;
|
||||
} now = { .d = jerry_port_get_current_time () };
|
||||
} now = { .d = jerry_port_current_time () };
|
||||
srand (now.u);
|
||||
|
||||
argc = main_argc;
|
||||
@ -247,7 +248,7 @@ main (int main_argc, char **main_argv)
|
||||
|
||||
if (result == JERRY_STANDALONE_EXIT_CODE_FAIL)
|
||||
{
|
||||
jerry_port_log (JERRY_LOG_LEVEL_ERROR, "Unhandled exception: Script Error!\n");
|
||||
jerry_log (JERRY_LOG_LEVEL_ERROR, "Unhandled exception: Script Error!\n");
|
||||
}
|
||||
|
||||
return result;
|
||||
267
jerry-main/main-desktop.c
Normal file
267
jerry-main/main-desktop.c
Normal file
@ -0,0 +1,267 @@
|
||||
/* Copyright JS Foundation and other contributors, http://js.foundation
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#include <assert.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "jerryscript-port.h"
|
||||
#include "jerryscript.h"
|
||||
|
||||
#include "arguments/options.h"
|
||||
#include "jerryscript-ext/debugger.h"
|
||||
#include "jerryscript-ext/handlers.h"
|
||||
#include "jerryscript-ext/print.h"
|
||||
#include "jerryscript-ext/properties.h"
|
||||
#include "jerryscript-ext/repl.h"
|
||||
#include "jerryscript-ext/sources.h"
|
||||
#include "jerryscript-ext/test262.h"
|
||||
|
||||
/**
|
||||
* Initialize random seed
|
||||
*/
|
||||
static void
|
||||
main_init_random_seed (void)
|
||||
{
|
||||
union
|
||||
{
|
||||
double d;
|
||||
unsigned u;
|
||||
} now = { .d = jerry_port_current_time () };
|
||||
|
||||
srand (now.u);
|
||||
} /* main_init_random_seed */
|
||||
|
||||
/**
|
||||
* Initialize debugger
|
||||
*/
|
||||
static bool
|
||||
main_init_debugger (main_args_t *arguments_p) /**< main arguments */
|
||||
{
|
||||
bool result = false;
|
||||
|
||||
if (!strcmp (arguments_p->debug_protocol, "tcp"))
|
||||
{
|
||||
result = jerryx_debugger_tcp_create (arguments_p->debug_port);
|
||||
}
|
||||
else
|
||||
{
|
||||
assert (!strcmp (arguments_p->debug_protocol, "serial"));
|
||||
result = jerryx_debugger_serial_create (arguments_p->debug_serial_config);
|
||||
}
|
||||
|
||||
if (!strcmp (arguments_p->debug_channel, "rawpacket"))
|
||||
{
|
||||
result = result && jerryx_debugger_rp_create ();
|
||||
}
|
||||
else
|
||||
{
|
||||
assert (!strcmp (arguments_p->debug_channel, "websocket"));
|
||||
result = result && jerryx_debugger_ws_create ();
|
||||
}
|
||||
|
||||
jerryx_debugger_after_connect (result);
|
||||
return result;
|
||||
} /* main_init_debugger */
|
||||
|
||||
/**
|
||||
* Inits the engine and the debugger
|
||||
*/
|
||||
static void
|
||||
main_init_engine (main_args_t *arguments_p) /**< main arguments */
|
||||
{
|
||||
jerry_init (arguments_p->init_flags);
|
||||
|
||||
jerry_promise_on_event (JERRY_PROMISE_EVENT_FILTER_ERROR, jerryx_handler_promise_reject, NULL);
|
||||
|
||||
if (arguments_p->option_flags & OPT_FLAG_DEBUG_SERVER)
|
||||
{
|
||||
if (!main_init_debugger (arguments_p))
|
||||
{
|
||||
jerry_log (JERRY_LOG_LEVEL_WARNING, "Failed to initialize debugger!\n");
|
||||
}
|
||||
}
|
||||
|
||||
if (arguments_p->option_flags & OPT_FLAG_TEST262_OBJECT)
|
||||
{
|
||||
jerryx_test262_register ();
|
||||
}
|
||||
|
||||
jerryx_register_global ("assert", jerryx_handler_assert);
|
||||
jerryx_register_global ("gc", jerryx_handler_gc);
|
||||
jerryx_register_global ("print", jerryx_handler_print);
|
||||
jerryx_register_global ("sourceName", jerryx_handler_source_name);
|
||||
jerryx_register_global ("createRealm", jerryx_handler_create_realm);
|
||||
} /* main_init_engine */
|
||||
|
||||
int
|
||||
main (int argc, char **argv)
|
||||
{
|
||||
main_init_random_seed ();
|
||||
JERRY_VLA (main_source_t, sources_p, argc);
|
||||
|
||||
main_args_t arguments;
|
||||
arguments.sources_p = sources_p;
|
||||
|
||||
if (!main_parse_args (argc, argv, &arguments))
|
||||
{
|
||||
return arguments.parse_result;
|
||||
}
|
||||
|
||||
restart:
|
||||
main_init_engine (&arguments);
|
||||
int return_code = JERRY_STANDALONE_EXIT_CODE_FAIL;
|
||||
jerry_value_t result;
|
||||
|
||||
for (uint32_t source_index = 0; source_index < arguments.source_count; source_index++)
|
||||
{
|
||||
main_source_t *source_file_p = sources_p + source_index;
|
||||
const char *file_path_p = argv[source_file_p->path_index];
|
||||
|
||||
switch (source_file_p->type)
|
||||
{
|
||||
case SOURCE_MODULE:
|
||||
{
|
||||
result = jerryx_source_exec_module (file_path_p);
|
||||
break;
|
||||
}
|
||||
case SOURCE_SNAPSHOT:
|
||||
{
|
||||
result = jerryx_source_exec_snapshot (file_path_p, source_file_p->snapshot_index);
|
||||
break;
|
||||
}
|
||||
default:
|
||||
{
|
||||
assert (source_file_p->type == SOURCE_SCRIPT);
|
||||
|
||||
if ((arguments.option_flags & OPT_FLAG_PARSE_ONLY) != 0)
|
||||
{
|
||||
result = jerryx_source_parse_script (file_path_p);
|
||||
}
|
||||
else
|
||||
{
|
||||
result = jerryx_source_exec_script (file_path_p);
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (jerry_value_is_exception (result))
|
||||
{
|
||||
if (jerryx_debugger_is_reset (result))
|
||||
{
|
||||
jerry_cleanup ();
|
||||
|
||||
goto restart;
|
||||
}
|
||||
|
||||
jerryx_print_unhandled_exception (result);
|
||||
goto exit;
|
||||
}
|
||||
|
||||
jerry_value_free (result);
|
||||
}
|
||||
|
||||
if (arguments.option_flags & OPT_FLAG_WAIT_SOURCE)
|
||||
{
|
||||
while (true)
|
||||
{
|
||||
jerry_debugger_wait_for_source_status_t receive_status;
|
||||
receive_status = jerry_debugger_wait_for_client_source (jerryx_handler_source_received, NULL, &result);
|
||||
|
||||
if (receive_status == JERRY_DEBUGGER_SOURCE_RECEIVE_FAILED)
|
||||
{
|
||||
jerry_log (JERRY_LOG_LEVEL_ERROR, "Connection aborted before source arrived.");
|
||||
goto exit;
|
||||
}
|
||||
|
||||
if (receive_status == JERRY_DEBUGGER_SOURCE_END)
|
||||
{
|
||||
jerry_log (JERRY_LOG_LEVEL_DEBUG, "No more client source.\n");
|
||||
break;
|
||||
}
|
||||
|
||||
assert (receive_status == JERRY_DEBUGGER_CONTEXT_RESET_RECEIVED
|
||||
|| receive_status == JERRY_DEBUGGER_SOURCE_RECEIVED);
|
||||
|
||||
if (receive_status == JERRY_DEBUGGER_CONTEXT_RESET_RECEIVED || jerryx_debugger_is_reset (result))
|
||||
{
|
||||
jerry_cleanup ();
|
||||
goto restart;
|
||||
}
|
||||
|
||||
assert (receive_status == JERRY_DEBUGGER_SOURCE_RECEIVED);
|
||||
jerry_value_free (result);
|
||||
}
|
||||
}
|
||||
else if (arguments.option_flags & OPT_FLAG_USE_STDIN)
|
||||
{
|
||||
result = jerryx_source_exec_stdin ();
|
||||
|
||||
if (jerry_value_is_exception (result))
|
||||
{
|
||||
jerryx_print_unhandled_exception (result);
|
||||
goto exit;
|
||||
}
|
||||
|
||||
jerry_value_free (result);
|
||||
}
|
||||
else if (arguments.source_count == 0)
|
||||
{
|
||||
const char *prompt_p = (arguments.option_flags & OPT_FLAG_NO_PROMPT) ? "" : "jerry> ";
|
||||
jerryx_repl (prompt_p);
|
||||
}
|
||||
|
||||
result = jerry_run_jobs ();
|
||||
|
||||
if (jerry_value_is_exception (result))
|
||||
{
|
||||
jerryx_print_unhandled_exception (result);
|
||||
goto exit;
|
||||
}
|
||||
|
||||
jerry_value_free (result);
|
||||
|
||||
if (arguments.exit_cb_name_p != NULL)
|
||||
{
|
||||
jerry_value_t global = jerry_current_realm ();
|
||||
jerry_value_t callback_fn = jerry_object_get_sz (global, arguments.exit_cb_name_p);
|
||||
jerry_value_free (global);
|
||||
|
||||
if (jerry_value_is_function (callback_fn))
|
||||
{
|
||||
result = jerry_call (callback_fn, jerry_undefined (), NULL, 0);
|
||||
|
||||
if (jerry_value_is_exception (result))
|
||||
{
|
||||
jerryx_print_unhandled_exception (result);
|
||||
goto exit;
|
||||
}
|
||||
|
||||
jerry_value_free (result);
|
||||
}
|
||||
|
||||
jerry_value_free (callback_fn);
|
||||
}
|
||||
|
||||
return_code = JERRY_STANDALONE_EXIT_CODE_OK;
|
||||
|
||||
exit:
|
||||
jerry_cleanup ();
|
||||
|
||||
return return_code;
|
||||
} /* main */
|
||||
@ -1,371 +0,0 @@
|
||||
/* Copyright JS Foundation and other contributors, http://js.foundation
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#include <assert.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "jerryscript-port-default.h"
|
||||
#include "jerryscript-port.h"
|
||||
#include "jerryscript.h"
|
||||
|
||||
#include "jerryscript-ext/debugger.h"
|
||||
#include "jerryscript-ext/handler.h"
|
||||
#include "main-options.h"
|
||||
#include "main-utils.h"
|
||||
|
||||
/**
|
||||
* Temporal buffer size.
|
||||
*/
|
||||
#define JERRY_BUFFER_SIZE 256u
|
||||
|
||||
#if defined(JERRY_EXTERNAL_CONTEXT) && (JERRY_EXTERNAL_CONTEXT == 1)
|
||||
/**
|
||||
* The alloc function passed to jerry_context_create
|
||||
*/
|
||||
static void *
|
||||
context_alloc (size_t size, void *cb_data_p)
|
||||
{
|
||||
(void) cb_data_p; /* unused */
|
||||
return malloc (size);
|
||||
} /* context_alloc */
|
||||
#endif /* defined (JERRY_EXTERNAL_CONTEXT) && (JERRY_EXTERNAL_CONTEXT == 1) */
|
||||
|
||||
int
|
||||
main (int argc, char **argv)
|
||||
{
|
||||
union
|
||||
{
|
||||
double d;
|
||||
unsigned u;
|
||||
} now = { .d = jerry_port_get_current_time () };
|
||||
srand (now.u);
|
||||
|
||||
JERRY_VLA (main_source_t, sources_p, argc);
|
||||
|
||||
main_args_t arguments;
|
||||
arguments.sources_p = sources_p;
|
||||
|
||||
main_parse_args (argc, argv, &arguments);
|
||||
|
||||
#if defined(JERRY_EXTERNAL_CONTEXT) && (JERRY_EXTERNAL_CONTEXT == 1)
|
||||
jerry_context_t *context_p = jerry_context_alloc (JERRY_GLOBAL_HEAP_SIZE * 1024, context_alloc, NULL);
|
||||
jerry_port_default_set_current_context (context_p);
|
||||
#endif /* defined (JERRY_EXTERNAL_CONTEXT) && (JERRY_EXTERNAL_CONTEXT == 1) */
|
||||
|
||||
restart:
|
||||
main_init_engine (&arguments);
|
||||
int return_code = JERRY_STANDALONE_EXIT_CODE_FAIL;
|
||||
jerry_value_t ret_value;
|
||||
|
||||
for (uint32_t source_index = 0; source_index < arguments.source_count; source_index++)
|
||||
{
|
||||
main_source_t *source_file_p = sources_p + source_index;
|
||||
const char *file_path_p = argv[source_file_p->path_index];
|
||||
|
||||
if (source_file_p->type == SOURCE_MODULE)
|
||||
{
|
||||
jerry_value_t specifier =
|
||||
jerry_string ((const jerry_char_t *) file_path_p, (jerry_size_t) strlen (file_path_p), JERRY_ENCODING_UTF8);
|
||||
jerry_value_t referrer = jerry_undefined ();
|
||||
ret_value = jerry_port_module_resolve (specifier, referrer, NULL);
|
||||
jerry_value_free (referrer);
|
||||
jerry_value_free (specifier);
|
||||
|
||||
if (!jerry_value_is_exception (ret_value))
|
||||
{
|
||||
if (jerry_module_state (ret_value) != JERRY_MODULE_STATE_UNLINKED)
|
||||
{
|
||||
/* A module can be evaluated only once. */
|
||||
jerry_value_free (ret_value);
|
||||
continue;
|
||||
}
|
||||
|
||||
jerry_value_t link_val = jerry_module_link (ret_value, NULL, NULL);
|
||||
|
||||
if (jerry_value_is_exception (link_val))
|
||||
{
|
||||
jerry_value_free (ret_value);
|
||||
ret_value = link_val;
|
||||
}
|
||||
else
|
||||
{
|
||||
jerry_value_free (link_val);
|
||||
|
||||
jerry_value_t module_val = ret_value;
|
||||
ret_value = jerry_module_evaluate (module_val);
|
||||
jerry_value_free (module_val);
|
||||
}
|
||||
}
|
||||
|
||||
if (jerry_value_is_exception (ret_value))
|
||||
{
|
||||
main_print_unhandled_exception (ret_value);
|
||||
goto exit;
|
||||
}
|
||||
|
||||
jerry_value_free (ret_value);
|
||||
continue;
|
||||
}
|
||||
|
||||
size_t source_size;
|
||||
uint8_t *source_p = jerry_port_read_source (file_path_p, &source_size);
|
||||
|
||||
if (source_p == NULL)
|
||||
{
|
||||
goto exit;
|
||||
}
|
||||
|
||||
switch (source_file_p->type)
|
||||
{
|
||||
case SOURCE_SNAPSHOT:
|
||||
{
|
||||
ret_value = jerry_exec_snapshot ((uint32_t *) source_p,
|
||||
source_size,
|
||||
source_file_p->snapshot_index,
|
||||
JERRY_SNAPSHOT_EXEC_COPY_DATA,
|
||||
NULL);
|
||||
|
||||
jerry_port_release_source (source_p);
|
||||
break;
|
||||
}
|
||||
default:
|
||||
{
|
||||
assert (source_file_p->type == SOURCE_SCRIPT || source_file_p->type == SOURCE_MODULE);
|
||||
|
||||
if (!jerry_validate_string ((jerry_char_t *) source_p, (jerry_size_t) source_size, JERRY_ENCODING_UTF8))
|
||||
{
|
||||
jerry_port_release_source (source_p);
|
||||
jerry_port_log (JERRY_LOG_LEVEL_ERROR, "Error: Input must be a valid UTF-8 string.");
|
||||
goto exit;
|
||||
}
|
||||
|
||||
jerry_parse_options_t parse_options;
|
||||
parse_options.options = JERRY_PARSE_HAS_SOURCE_NAME;
|
||||
parse_options.source_name =
|
||||
jerry_string ((const jerry_char_t *) file_path_p, (jerry_size_t) strlen (file_path_p), JERRY_ENCODING_UTF8);
|
||||
|
||||
ret_value = jerry_parse (source_p, source_size, &parse_options);
|
||||
|
||||
jerry_value_free (parse_options.source_name);
|
||||
jerry_port_release_source (source_p);
|
||||
|
||||
if (!jerry_value_is_exception (ret_value) && !(arguments.option_flags & OPT_FLAG_PARSE_ONLY))
|
||||
{
|
||||
jerry_value_t func_val = ret_value;
|
||||
ret_value = jerry_run (func_val);
|
||||
jerry_value_free (func_val);
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (jerry_value_is_exception (ret_value))
|
||||
{
|
||||
if (main_is_value_reset (ret_value))
|
||||
{
|
||||
jerry_cleanup ();
|
||||
|
||||
goto restart;
|
||||
}
|
||||
|
||||
main_print_unhandled_exception (ret_value);
|
||||
goto exit;
|
||||
}
|
||||
|
||||
jerry_value_free (ret_value);
|
||||
}
|
||||
|
||||
if (arguments.option_flags & OPT_FLAG_WAIT_SOURCE)
|
||||
{
|
||||
while (true)
|
||||
{
|
||||
jerry_debugger_wait_for_source_status_t receive_status;
|
||||
receive_status = jerry_debugger_wait_for_client_source (main_wait_for_source_callback, NULL, &ret_value);
|
||||
|
||||
if (receive_status == JERRY_DEBUGGER_SOURCE_RECEIVE_FAILED)
|
||||
{
|
||||
jerry_port_log (JERRY_LOG_LEVEL_ERROR, "Connection aborted before source arrived.");
|
||||
goto exit;
|
||||
}
|
||||
|
||||
if (receive_status == JERRY_DEBUGGER_SOURCE_END)
|
||||
{
|
||||
jerry_port_log (JERRY_LOG_LEVEL_DEBUG, "No more client source.\n");
|
||||
break;
|
||||
}
|
||||
|
||||
assert (receive_status == JERRY_DEBUGGER_CONTEXT_RESET_RECEIVED
|
||||
|| receive_status == JERRY_DEBUGGER_SOURCE_RECEIVED);
|
||||
|
||||
if (receive_status == JERRY_DEBUGGER_CONTEXT_RESET_RECEIVED || main_is_value_reset (ret_value))
|
||||
{
|
||||
jerry_cleanup ();
|
||||
goto restart;
|
||||
}
|
||||
|
||||
assert (receive_status == JERRY_DEBUGGER_SOURCE_RECEIVED);
|
||||
jerry_value_free (ret_value);
|
||||
}
|
||||
}
|
||||
else if (arguments.option_flags & OPT_FLAG_USE_STDIN)
|
||||
{
|
||||
char buffer[JERRY_BUFFER_SIZE];
|
||||
char *source_p = NULL;
|
||||
size_t source_size = 0;
|
||||
|
||||
while (!feof (stdin))
|
||||
{
|
||||
size_t read_bytes = fread (buffer, 1u, JERRY_BUFFER_SIZE, stdin);
|
||||
|
||||
size_t new_size = source_size + read_bytes;
|
||||
source_p = realloc (source_p, new_size);
|
||||
|
||||
memcpy (source_p + source_size, buffer, read_bytes);
|
||||
source_size = new_size;
|
||||
}
|
||||
|
||||
ret_value = jerry_parse ((jerry_char_t *) source_p, source_size, NULL);
|
||||
free (source_p);
|
||||
|
||||
if (jerry_value_is_exception (ret_value))
|
||||
{
|
||||
main_print_unhandled_exception (ret_value);
|
||||
goto exit;
|
||||
}
|
||||
|
||||
jerry_value_t func_val = ret_value;
|
||||
ret_value = jerry_run (func_val);
|
||||
jerry_value_free (func_val);
|
||||
|
||||
if (jerry_value_is_exception (ret_value))
|
||||
{
|
||||
main_print_unhandled_exception (ret_value);
|
||||
goto exit;
|
||||
}
|
||||
|
||||
jerry_value_free (ret_value);
|
||||
}
|
||||
else if (arguments.source_count == 0)
|
||||
{
|
||||
const char *prompt = (arguments.option_flags & OPT_FLAG_NO_PROMPT) ? "" : "jerry> ";
|
||||
char buffer[JERRY_BUFFER_SIZE];
|
||||
|
||||
while (true)
|
||||
{
|
||||
printf ("%s", prompt);
|
||||
char *str_p = fgets (buffer, JERRY_BUFFER_SIZE, stdin);
|
||||
|
||||
if (str_p == NULL)
|
||||
{
|
||||
printf ("\n");
|
||||
break;
|
||||
}
|
||||
|
||||
size_t len = strlen (str_p);
|
||||
|
||||
if (len == 0)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
if (!jerry_validate_string ((jerry_char_t *) str_p, (jerry_size_t) len, JERRY_ENCODING_UTF8))
|
||||
{
|
||||
jerry_port_log (JERRY_LOG_LEVEL_ERROR, "Error: Input must be a valid UTF-8 string.\n");
|
||||
continue;
|
||||
}
|
||||
|
||||
ret_value = jerry_parse ((jerry_char_t *) str_p, len, NULL);
|
||||
|
||||
if (jerry_value_is_exception (ret_value))
|
||||
{
|
||||
main_print_unhandled_exception (ret_value);
|
||||
continue;
|
||||
}
|
||||
|
||||
jerry_value_t func_val = ret_value;
|
||||
ret_value = jerry_run (func_val);
|
||||
jerry_value_free (func_val);
|
||||
|
||||
if (jerry_value_is_exception (ret_value))
|
||||
{
|
||||
main_print_unhandled_exception (ret_value);
|
||||
continue;
|
||||
}
|
||||
|
||||
const jerry_value_t args[] = { ret_value };
|
||||
jerry_value_t ret_val_print = jerryx_handler_print (NULL, args, 1);
|
||||
jerry_value_free (ret_val_print);
|
||||
jerry_value_free (ret_value);
|
||||
ret_value = jerry_run_jobs ();
|
||||
|
||||
if (jerry_value_is_exception (ret_value))
|
||||
{
|
||||
main_print_unhandled_exception (ret_value);
|
||||
continue;
|
||||
}
|
||||
|
||||
jerry_value_free (ret_value);
|
||||
}
|
||||
}
|
||||
|
||||
ret_value = jerry_run_jobs ();
|
||||
|
||||
if (jerry_value_is_exception (ret_value))
|
||||
{
|
||||
main_print_unhandled_exception (ret_value);
|
||||
goto exit;
|
||||
}
|
||||
|
||||
jerry_value_free (ret_value);
|
||||
|
||||
if (arguments.exit_cb_name_p != NULL)
|
||||
{
|
||||
jerry_value_t global = jerry_current_realm ();
|
||||
jerry_value_t name_str = jerry_string_sz (arguments.exit_cb_name_p);
|
||||
jerry_value_t callback_fn = jerry_object_get (global, name_str);
|
||||
|
||||
jerry_value_free (global);
|
||||
jerry_value_free (name_str);
|
||||
|
||||
if (jerry_value_is_function (callback_fn))
|
||||
{
|
||||
ret_value = jerry_call (callback_fn, jerry_undefined (), NULL, 0);
|
||||
|
||||
if (jerry_value_is_exception (ret_value))
|
||||
{
|
||||
main_print_unhandled_exception (ret_value);
|
||||
goto exit;
|
||||
}
|
||||
|
||||
jerry_value_free (ret_value);
|
||||
}
|
||||
|
||||
jerry_value_free (callback_fn);
|
||||
}
|
||||
|
||||
return_code = JERRY_STANDALONE_EXIT_CODE_OK;
|
||||
|
||||
exit:
|
||||
jerry_cleanup ();
|
||||
|
||||
#if defined(JERRY_EXTERNAL_CONTEXT) && (JERRY_EXTERNAL_CONTEXT == 1)
|
||||
free (context_p);
|
||||
#endif /* defined (JERRY_EXTERNAL_CONTEXT) && (JERRY_EXTERNAL_CONTEXT == 1) */
|
||||
|
||||
return return_code;
|
||||
} /* main */
|
||||
@ -14,14 +14,14 @@
|
||||
*/
|
||||
|
||||
#include <assert.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "jerryscript-port-default.h"
|
||||
#include "jerryscript-port.h"
|
||||
#include "jerryscript.h"
|
||||
|
||||
#include "cli.h"
|
||||
#include "arguments/cli.h"
|
||||
|
||||
/**
|
||||
* Maximum size for loaded snapshots
|
||||
@ -46,29 +46,6 @@ static const char *output_file_name_p = "js.snapshot";
|
||||
static jerry_length_t magic_string_lengths[JERRY_LITERAL_LENGTH];
|
||||
static const jerry_char_t *magic_string_items[JERRY_LITERAL_LENGTH];
|
||||
|
||||
#if defined(JERRY_EXTERNAL_CONTEXT) && (JERRY_EXTERNAL_CONTEXT == 1)
|
||||
/**
|
||||
* The alloc function passed to jerry_context_create
|
||||
*/
|
||||
static void *
|
||||
context_alloc (size_t size, void *cb_data_p)
|
||||
{
|
||||
(void) cb_data_p; /* unused */
|
||||
return malloc (size);
|
||||
} /* context_alloc */
|
||||
|
||||
/**
|
||||
* Create and set the default external context.
|
||||
*/
|
||||
static void
|
||||
context_init (void)
|
||||
{
|
||||
jerry_context_t *context_p = jerry_context_alloc (JERRY_GLOBAL_HEAP_SIZE * 1024, context_alloc, NULL);
|
||||
jerry_port_default_set_current_context (context_p);
|
||||
} /* context_init */
|
||||
|
||||
#endif /* defined (JERRY_EXTERNAL_CONTEXT) && (JERRY_EXTERNAL_CONTEXT == 1) */
|
||||
|
||||
/**
|
||||
* Check whether JerryScript has a requested feature enabled or not. If not,
|
||||
* print a warning message.
|
||||
@ -81,8 +58,8 @@ check_feature (jerry_feature_t feature, /**< feature to check */
|
||||
{
|
||||
if (!jerry_feature_enabled (feature))
|
||||
{
|
||||
jerry_port_default_set_log_level (JERRY_LOG_LEVEL_WARNING);
|
||||
jerry_port_log (JERRY_LOG_LEVEL_WARNING, "Ignoring '%s' option because this feature is disabled!\n", option);
|
||||
jerry_log_set_level (JERRY_LOG_LEVEL_WARNING);
|
||||
jerry_log (JERRY_LOG_LEVEL_WARNING, "Ignoring '%s' option because this feature is disabled!\n", option);
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
@ -101,11 +78,11 @@ check_cli_error (const cli_state_t *const cli_state_p)
|
||||
{
|
||||
if (cli_state_p->arg != NULL)
|
||||
{
|
||||
jerry_port_log (JERRY_LOG_LEVEL_ERROR, "Error: %s %s\n", cli_state_p->error, cli_state_p->arg);
|
||||
jerry_log (JERRY_LOG_LEVEL_ERROR, "Error: %s %s\n", cli_state_p->error, cli_state_p->arg);
|
||||
}
|
||||
else
|
||||
{
|
||||
jerry_port_log (JERRY_LOG_LEVEL_ERROR, "Error: %s\n", cli_state_p->error);
|
||||
jerry_log (JERRY_LOG_LEVEL_ERROR, "Error: %s\n", cli_state_p->error);
|
||||
}
|
||||
|
||||
return true;
|
||||
@ -128,7 +105,7 @@ read_file (uint8_t *input_pos_p, /**< next position in the input buffer */
|
||||
|
||||
if (file == NULL)
|
||||
{
|
||||
jerry_port_log (JERRY_LOG_LEVEL_ERROR, "Error: failed to open file: %s\n", file_name);
|
||||
jerry_log (JERRY_LOG_LEVEL_ERROR, "Error: failed to open file: %s\n", file_name);
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -139,13 +116,13 @@ read_file (uint8_t *input_pos_p, /**< next position in the input buffer */
|
||||
|
||||
if (bytes_read == 0)
|
||||
{
|
||||
jerry_port_log (JERRY_LOG_LEVEL_ERROR, "Error: failed to read file: %s\n", file_name);
|
||||
jerry_log (JERRY_LOG_LEVEL_ERROR, "Error: failed to read file: %s\n", file_name);
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (bytes_read == max_size)
|
||||
{
|
||||
jerry_port_log (JERRY_LOG_LEVEL_ERROR, "Error: file too large: %s\n", file_name);
|
||||
jerry_log (JERRY_LOG_LEVEL_ERROR, "Error: file too large: %s\n", file_name);
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -166,7 +143,7 @@ print_unhandled_exception (jerry_value_t error_value) /**< error value */
|
||||
if (jerry_value_is_exception (err_str_val))
|
||||
{
|
||||
/* Avoid recursive error throws. */
|
||||
jerry_port_log (JERRY_LOG_LEVEL_ERROR, "Snapshot error: [value cannot be converted to string]\n");
|
||||
jerry_log (JERRY_LOG_LEVEL_ERROR, "Snapshot error: [value cannot be converted to string]\n");
|
||||
jerry_value_free (err_str_val);
|
||||
return;
|
||||
}
|
||||
@ -175,7 +152,7 @@ print_unhandled_exception (jerry_value_t error_value) /**< error value */
|
||||
jerry_size_t bytes = jerry_string_to_buffer (err_str_val, JERRY_ENCODING_UTF8, err_str_buf, sizeof (err_str_buf) - 1);
|
||||
err_str_buf[bytes] = '\0';
|
||||
|
||||
jerry_port_log (JERRY_LOG_LEVEL_ERROR, "Snapshot error: %s\n", (char *) err_str_buf);
|
||||
jerry_log (JERRY_LOG_LEVEL_ERROR, "Snapshot error: %s\n", (char *) err_str_buf);
|
||||
jerry_value_free (err_str_val);
|
||||
} /* print_unhandled_exception */
|
||||
|
||||
@ -266,7 +243,7 @@ process_generate (cli_state_t *cli_state_p, /**< cli state */
|
||||
{
|
||||
if (check_feature (JERRY_FEATURE_PARSER_DUMP, cli_state_p->arg))
|
||||
{
|
||||
jerry_port_default_set_log_level (JERRY_LOG_LEVEL_DEBUG);
|
||||
jerry_log_set_level (JERRY_LOG_LEVEL_DEBUG);
|
||||
flags |= JERRY_INIT_SHOW_OPCODES;
|
||||
}
|
||||
break;
|
||||
@ -280,7 +257,7 @@ process_generate (cli_state_t *cli_state_p, /**< cli state */
|
||||
{
|
||||
if (file_name_p != NULL)
|
||||
{
|
||||
jerry_port_log (JERRY_LOG_LEVEL_ERROR, "Error: Exactly one input file must be specified\n");
|
||||
jerry_log (JERRY_LOG_LEVEL_ERROR, "Error: Exactly one input file must be specified\n");
|
||||
return JERRY_STANDALONE_EXIT_CODE_FAIL;
|
||||
}
|
||||
|
||||
@ -292,7 +269,7 @@ process_generate (cli_state_t *cli_state_p, /**< cli state */
|
||||
|
||||
if (source_length == 0)
|
||||
{
|
||||
jerry_port_log (JERRY_LOG_LEVEL_ERROR, "Input file is empty\n");
|
||||
jerry_log (JERRY_LOG_LEVEL_ERROR, "Input file is empty\n");
|
||||
return JERRY_STANDALONE_EXIT_CODE_FAIL;
|
||||
}
|
||||
}
|
||||
@ -313,19 +290,15 @@ process_generate (cli_state_t *cli_state_p, /**< cli state */
|
||||
|
||||
if (file_name_p == NULL)
|
||||
{
|
||||
jerry_port_log (JERRY_LOG_LEVEL_ERROR, "Error: Exactly one input file must be specified\n");
|
||||
jerry_log (JERRY_LOG_LEVEL_ERROR, "Error: Exactly one input file must be specified\n");
|
||||
return JERRY_STANDALONE_EXIT_CODE_FAIL;
|
||||
}
|
||||
|
||||
#if defined(JERRY_EXTERNAL_CONTEXT) && (JERRY_EXTERNAL_CONTEXT == 1)
|
||||
context_init ();
|
||||
#endif /* defined (JERRY_EXTERNAL_CONTEXT) && (JERRY_EXTERNAL_CONTEXT == 1) */
|
||||
|
||||
jerry_init (flags);
|
||||
|
||||
if (!jerry_validate_string (source_p, (jerry_size_t) source_length, JERRY_ENCODING_UTF8))
|
||||
{
|
||||
jerry_port_log (JERRY_LOG_LEVEL_ERROR, "Error: Input must be a valid UTF-8 string.\n");
|
||||
jerry_log (JERRY_LOG_LEVEL_ERROR, "Error: Input must be a valid UTF-8 string.\n");
|
||||
jerry_cleanup ();
|
||||
return JERRY_STANDALONE_EXIT_CODE_FAIL;
|
||||
}
|
||||
@ -395,7 +368,7 @@ process_generate (cli_state_t *cli_state_p, /**< cli state */
|
||||
|
||||
if (jerry_value_is_exception (snapshot_result))
|
||||
{
|
||||
jerry_port_log (JERRY_LOG_LEVEL_ERROR, "Error: Generating snapshot failed!\n");
|
||||
jerry_log (JERRY_LOG_LEVEL_ERROR, "Error: Generating snapshot failed!\n");
|
||||
|
||||
snapshot_result = jerry_exception_value (snapshot_result, true);
|
||||
|
||||
@ -412,7 +385,7 @@ process_generate (cli_state_t *cli_state_p, /**< cli state */
|
||||
FILE *snapshot_file_p = fopen (output_file_name_p, "wb");
|
||||
if (snapshot_file_p == NULL)
|
||||
{
|
||||
jerry_port_log (JERRY_LOG_LEVEL_ERROR, "Error: Unable to write snapshot file: '%s'\n", output_file_name_p);
|
||||
jerry_log (JERRY_LOG_LEVEL_ERROR, "Error: Unable to write snapshot file: '%s'\n", output_file_name_p);
|
||||
jerry_cleanup ();
|
||||
return JERRY_STANDALONE_EXIT_CODE_FAIL;
|
||||
}
|
||||
@ -491,7 +464,7 @@ process_literal_dump (cli_state_t *cli_state_p, /**< cli state */
|
||||
}
|
||||
else
|
||||
{
|
||||
jerry_port_log (JERRY_LOG_LEVEL_ERROR, "Error: Unsupported literal dump format.");
|
||||
jerry_log (JERRY_LOG_LEVEL_ERROR, "Error: Unsupported literal dump format.");
|
||||
return JERRY_STANDALONE_EXIT_CODE_FAIL;
|
||||
}
|
||||
break;
|
||||
@ -538,7 +511,7 @@ process_literal_dump (cli_state_t *cli_state_p, /**< cli state */
|
||||
|
||||
if (number_of_files < 1)
|
||||
{
|
||||
jerry_port_log (JERRY_LOG_LEVEL_ERROR, "Error: at least one input file must be specified.\n");
|
||||
jerry_log (JERRY_LOG_LEVEL_ERROR, "Error: at least one input file must be specified.\n");
|
||||
return JERRY_STANDALONE_EXIT_CODE_FAIL;
|
||||
}
|
||||
|
||||
@ -570,7 +543,7 @@ process_literal_dump (cli_state_t *cli_state_p, /**< cli state */
|
||||
|
||||
if (merged_snapshot_size == 0)
|
||||
{
|
||||
jerry_port_log (JERRY_LOG_LEVEL_ERROR, "Error: %s\n", error_p);
|
||||
jerry_log (JERRY_LOG_LEVEL_ERROR, "Error: %s\n", error_p);
|
||||
jerry_cleanup ();
|
||||
return JERRY_STANDALONE_EXIT_CODE_FAIL;
|
||||
}
|
||||
@ -586,8 +559,8 @@ process_literal_dump (cli_state_t *cli_state_p, /**< cli state */
|
||||
|
||||
if (lit_buf_sz == 0)
|
||||
{
|
||||
jerry_port_log (JERRY_LOG_LEVEL_ERROR,
|
||||
"Error: Literal saving failed! No literals were found in the input snapshot(s).\n");
|
||||
jerry_log (JERRY_LOG_LEVEL_ERROR,
|
||||
"Error: Literal saving failed! No literals were found in the input snapshot(s).\n");
|
||||
jerry_cleanup ();
|
||||
return JERRY_STANDALONE_EXIT_CODE_FAIL;
|
||||
}
|
||||
@ -601,7 +574,7 @@ process_literal_dump (cli_state_t *cli_state_p, /**< cli state */
|
||||
|
||||
if (file_p == NULL)
|
||||
{
|
||||
jerry_port_log (JERRY_LOG_LEVEL_ERROR, "Error: cannot open file: '%s'\n", literals_file_name_p);
|
||||
jerry_log (JERRY_LOG_LEVEL_ERROR, "Error: cannot open file: '%s'\n", literals_file_name_p);
|
||||
jerry_cleanup ();
|
||||
return JERRY_STANDALONE_EXIT_CODE_FAIL;
|
||||
}
|
||||
@ -702,7 +675,7 @@ process_merge (cli_state_t *cli_state_p, /**< cli state */
|
||||
|
||||
if (number_of_files < 2)
|
||||
{
|
||||
jerry_port_log (JERRY_LOG_LEVEL_ERROR, "Error: at least two input files must be passed.\n");
|
||||
jerry_log (JERRY_LOG_LEVEL_ERROR, "Error: at least two input files must be passed.\n");
|
||||
return JERRY_STANDALONE_EXIT_CODE_FAIL;
|
||||
}
|
||||
|
||||
@ -722,7 +695,7 @@ process_merge (cli_state_t *cli_state_p, /**< cli state */
|
||||
|
||||
if (merged_snapshot_size == 0)
|
||||
{
|
||||
jerry_port_log (JERRY_LOG_LEVEL_ERROR, "Error: %s\n", error_p);
|
||||
jerry_log (JERRY_LOG_LEVEL_ERROR, "Error: %s\n", error_p);
|
||||
jerry_cleanup ();
|
||||
return JERRY_STANDALONE_EXIT_CODE_FAIL;
|
||||
}
|
||||
@ -731,7 +704,7 @@ process_merge (cli_state_t *cli_state_p, /**< cli state */
|
||||
|
||||
if (file_p == NULL)
|
||||
{
|
||||
jerry_port_log (JERRY_LOG_LEVEL_ERROR, "Error: cannot open file: '%s'\n", output_file_name_p);
|
||||
jerry_log (JERRY_LOG_LEVEL_ERROR, "Error: cannot open file: '%s'\n", output_file_name_p);
|
||||
jerry_cleanup ();
|
||||
return JERRY_STANDALONE_EXIT_CODE_FAIL;
|
||||
}
|
||||
@ -820,7 +793,7 @@ main (int argc, /**< number of arguments */
|
||||
return process_generate (&cli_state, argc, argv[0]);
|
||||
}
|
||||
|
||||
jerry_port_log (JERRY_LOG_LEVEL_ERROR, "Error: unknown command: %s\n\n", command_p);
|
||||
jerry_log (JERRY_LOG_LEVEL_ERROR, "Error: unknown command: %s\n\n", command_p);
|
||||
print_commands (argv[0]);
|
||||
|
||||
return JERRY_STANDALONE_EXIT_CODE_FAIL;
|
||||
@ -1,522 +0,0 @@
|
||||
/* Copyright JS Foundation and other contributors, http://js.foundation
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#include "main-utils.h"
|
||||
|
||||
#include <assert.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "jerryscript-port-default.h"
|
||||
#include "jerryscript-port.h"
|
||||
#include "jerryscript.h"
|
||||
|
||||
#include "jerryscript-ext/debugger.h"
|
||||
#include "jerryscript-ext/handler.h"
|
||||
#include "main-options.h"
|
||||
|
||||
/**
|
||||
* Max line size that will be printed on a Syntax Error
|
||||
*/
|
||||
#define SYNTAX_ERROR_MAX_LINE_LENGTH 256
|
||||
|
||||
/**
|
||||
* Register a JavaScript function in the global object.
|
||||
*/
|
||||
static void
|
||||
main_register_global_function (const char *name_p, /**< name of the function */
|
||||
jerry_external_handler_t handler_p) /**< function callback */
|
||||
{
|
||||
jerry_value_t result_val = jerryx_handler_register_global (name_p, handler_p);
|
||||
assert (!jerry_value_is_exception (result_val));
|
||||
jerry_value_free (result_val);
|
||||
} /* main_register_global_function */
|
||||
|
||||
static jerry_value_t
|
||||
main_create_realm (const jerry_call_info_t *call_info_p, /**< call information */
|
||||
const jerry_value_t args_p[], /**< function arguments */
|
||||
const jerry_length_t args_cnt) /**< number of function arguments */
|
||||
{
|
||||
(void) call_info_p; /* unused */
|
||||
(void) args_p; /* unused */
|
||||
(void) args_cnt; /* unused */
|
||||
return jerry_realm ();
|
||||
} /* main_create_realm */
|
||||
|
||||
/**
|
||||
* Register a method for the $262 object.
|
||||
*/
|
||||
static void
|
||||
test262_register_function (jerry_value_t test262_obj, /** $262 object */
|
||||
const char *name_p, /**< name of the function */
|
||||
jerry_external_handler_t handler_p) /**< function callback */
|
||||
{
|
||||
jerry_value_t function_name_val = jerry_string_sz (name_p);
|
||||
jerry_value_t function_val = jerry_function_external (handler_p);
|
||||
|
||||
jerry_value_t result_val = jerry_object_set (test262_obj, function_name_val, function_val);
|
||||
|
||||
jerry_value_free (function_val);
|
||||
jerry_value_free (function_name_val);
|
||||
|
||||
assert (!jerry_value_is_exception (result_val));
|
||||
jerry_value_free (result_val);
|
||||
} /* test262_register_function */
|
||||
|
||||
/**
|
||||
* $262.detachArrayBuffer
|
||||
*
|
||||
* A function which implements the DetachArrayBuffer abstract operation
|
||||
*
|
||||
* @return null value - if success
|
||||
* value marked with error flag - otherwise
|
||||
*/
|
||||
static jerry_value_t
|
||||
test262_detach_array_buffer (const jerry_call_info_t *call_info_p, /**< call information */
|
||||
const jerry_value_t args_p[], /**< function arguments */
|
||||
const jerry_length_t args_cnt) /**< number of function arguments */
|
||||
{
|
||||
(void) call_info_p; /* unused */
|
||||
|
||||
if (args_cnt < 1 || !jerry_value_is_arraybuffer (args_p[0]))
|
||||
{
|
||||
return jerry_throw_sz (JERRY_ERROR_TYPE, "Expected an ArrayBuffer object");
|
||||
}
|
||||
|
||||
/* TODO: support the optional 'key' argument */
|
||||
|
||||
return jerry_arraybuffer_detach (args_p[0]);
|
||||
} /* test262_detach_array_buffer */
|
||||
|
||||
/**
|
||||
* $262.evalScript
|
||||
*
|
||||
* A function which accepts a string value as its first argument and executes it
|
||||
*
|
||||
* @return completion of the script parsing and execution.
|
||||
*/
|
||||
static jerry_value_t
|
||||
test262_eval_script (const jerry_call_info_t *call_info_p, /**< call information */
|
||||
const jerry_value_t args_p[], /**< function arguments */
|
||||
const jerry_length_t args_cnt) /**< number of function arguments */
|
||||
{
|
||||
(void) call_info_p; /* unused */
|
||||
|
||||
if (args_cnt < 1 || !jerry_value_is_string (args_p[0]))
|
||||
{
|
||||
return jerry_throw_sz (JERRY_ERROR_TYPE, "Expected a string");
|
||||
}
|
||||
|
||||
jerry_size_t str_size = jerry_string_size (args_p[0], JERRY_ENCODING_UTF8);
|
||||
jerry_char_t *str_buf_p = malloc (str_size * sizeof (jerry_char_t));
|
||||
|
||||
if (str_buf_p == NULL)
|
||||
{
|
||||
return jerry_throw_sz (JERRY_ERROR_RANGE, "Internal allocation error");
|
||||
}
|
||||
|
||||
jerry_string_to_buffer (args_p[0], JERRY_ENCODING_UTF8, str_buf_p, str_size);
|
||||
|
||||
jerry_value_t ret_value = jerry_parse (str_buf_p, str_size, NULL);
|
||||
|
||||
if (!jerry_value_is_exception (ret_value))
|
||||
{
|
||||
jerry_value_t func_val = ret_value;
|
||||
ret_value = jerry_run (func_val);
|
||||
jerry_value_free (func_val);
|
||||
}
|
||||
|
||||
free (str_buf_p);
|
||||
|
||||
return ret_value;
|
||||
} /* test262_eval_script */
|
||||
|
||||
static jerry_value_t create_test262 (jerry_value_t global_obj);
|
||||
|
||||
/**
|
||||
* $262.createRealm
|
||||
*
|
||||
* A function which creates a new realm object, and returns a newly created $262 object
|
||||
*
|
||||
* @return a new $262 object
|
||||
*/
|
||||
static jerry_value_t
|
||||
test262_create_realm (const jerry_call_info_t *call_info_p, /**< call information */
|
||||
const jerry_value_t args_p[], /**< function arguments */
|
||||
const jerry_length_t args_cnt) /**< number of function arguments */
|
||||
{
|
||||
(void) call_info_p; /* unused */
|
||||
(void) args_p; /* unused */
|
||||
(void) args_cnt; /* unused */
|
||||
|
||||
jerry_value_t realm_object = jerry_realm ();
|
||||
jerry_value_t previous_realm = jerry_set_realm (realm_object);
|
||||
assert (!jerry_value_is_exception (previous_realm));
|
||||
jerry_value_t test262_object = create_test262 (realm_object);
|
||||
jerry_set_realm (previous_realm);
|
||||
jerry_value_free (realm_object);
|
||||
|
||||
return test262_object;
|
||||
} /* test262_create_realm */
|
||||
|
||||
/**
|
||||
* Create a new $262 object
|
||||
*
|
||||
* @return a new $262 object
|
||||
*/
|
||||
static jerry_value_t
|
||||
create_test262 (jerry_value_t global_obj) /**< global object */
|
||||
{
|
||||
jerry_value_t test262_object = jerry_object ();
|
||||
|
||||
test262_register_function (test262_object, "detachArrayBuffer", test262_detach_array_buffer);
|
||||
test262_register_function (test262_object, "evalScript", test262_eval_script);
|
||||
test262_register_function (test262_object, "createRealm", test262_create_realm);
|
||||
test262_register_function (test262_object, "gc", jerryx_handler_gc);
|
||||
|
||||
jerry_value_t prop_name = jerry_string_sz ("global");
|
||||
jerry_value_t result = jerry_object_set (test262_object, prop_name, global_obj);
|
||||
assert (!jerry_value_is_exception (result));
|
||||
|
||||
jerry_value_free (prop_name);
|
||||
jerry_value_free (result);
|
||||
|
||||
prop_name = jerry_string_sz ("$262");
|
||||
result = jerry_object_set (global_obj, prop_name, test262_object);
|
||||
assert (!jerry_value_is_exception (result));
|
||||
|
||||
jerry_value_free (prop_name);
|
||||
jerry_value_free (result);
|
||||
|
||||
return test262_object;
|
||||
} /* create_test262 */
|
||||
|
||||
static void
|
||||
promise_callback (jerry_promise_event_type_t event_type, /**< event type */
|
||||
const jerry_value_t object, /**< target object */
|
||||
const jerry_value_t value, /**< optional argument */
|
||||
void *user_p) /**< user pointer passed to the callback */
|
||||
{
|
||||
(void) value; /* unused */
|
||||
(void) user_p; /* unused */
|
||||
const jerry_size_t max_allowed_size = 5 * 1024 - 1;
|
||||
|
||||
if (event_type != JERRY_PROMISE_EVENT_REJECT_WITHOUT_HANDLER)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
jerry_value_t reason = jerry_promise_result (object);
|
||||
jerry_value_t reason_to_string = jerry_value_to_string (reason);
|
||||
|
||||
if (!jerry_value_is_exception (reason_to_string))
|
||||
{
|
||||
jerry_size_t buffer_size = jerry_string_size (reason_to_string, JERRY_ENCODING_UTF8);
|
||||
|
||||
if (buffer_size > max_allowed_size)
|
||||
{
|
||||
buffer_size = max_allowed_size;
|
||||
}
|
||||
|
||||
JERRY_VLA (jerry_char_t, str_buf_p, buffer_size + 1);
|
||||
jerry_string_to_buffer (reason_to_string, JERRY_ENCODING_UTF8, str_buf_p, buffer_size);
|
||||
str_buf_p[buffer_size] = '\0';
|
||||
|
||||
jerry_port_log (JERRY_LOG_LEVEL_WARNING, "Uncaught Promise rejection: %s\n", str_buf_p);
|
||||
}
|
||||
else
|
||||
{
|
||||
jerry_port_log (JERRY_LOG_LEVEL_WARNING, "Uncaught Promise rejection (reason cannot be converted to string)\n");
|
||||
}
|
||||
|
||||
jerry_value_free (reason_to_string);
|
||||
jerry_value_free (reason);
|
||||
} /* promise_callback */
|
||||
|
||||
/**
|
||||
* Inits the engine and the debugger
|
||||
*/
|
||||
void
|
||||
main_init_engine (main_args_t *arguments_p) /**< main arguments */
|
||||
{
|
||||
jerry_init (arguments_p->init_flags);
|
||||
|
||||
jerry_promise_on_event (JERRY_PROMISE_EVENT_FILTER_ERROR, promise_callback, NULL);
|
||||
|
||||
if (arguments_p->option_flags & OPT_FLAG_DEBUG_SERVER)
|
||||
{
|
||||
bool protocol = false;
|
||||
|
||||
if (!strcmp (arguments_p->debug_protocol, "tcp"))
|
||||
{
|
||||
protocol = jerryx_debugger_tcp_create (arguments_p->debug_port);
|
||||
}
|
||||
else
|
||||
{
|
||||
assert (!strcmp (arguments_p->debug_protocol, "serial"));
|
||||
protocol = jerryx_debugger_serial_create (arguments_p->debug_serial_config);
|
||||
}
|
||||
|
||||
if (!strcmp (arguments_p->debug_channel, "rawpacket"))
|
||||
{
|
||||
jerryx_debugger_after_connect (protocol && jerryx_debugger_rp_create ());
|
||||
}
|
||||
else
|
||||
{
|
||||
assert (!strcmp (arguments_p->debug_channel, "websocket"));
|
||||
jerryx_debugger_after_connect (protocol && jerryx_debugger_ws_create ());
|
||||
}
|
||||
}
|
||||
if (arguments_p->option_flags & OPT_FLAG_TEST262_OBJECT)
|
||||
{
|
||||
jerry_value_t global_obj = jerry_current_realm ();
|
||||
jerry_value_t test262_object = create_test262 (global_obj);
|
||||
jerry_value_free (test262_object);
|
||||
jerry_value_free (global_obj);
|
||||
}
|
||||
main_register_global_function ("assert", jerryx_handler_assert);
|
||||
main_register_global_function ("gc", jerryx_handler_gc);
|
||||
main_register_global_function ("print", jerryx_handler_print);
|
||||
main_register_global_function ("sourceName", jerryx_handler_source_name);
|
||||
main_register_global_function ("createRealm", main_create_realm);
|
||||
} /* main_init_engine */
|
||||
|
||||
/**
|
||||
* Print an error value.
|
||||
*
|
||||
* Note: the error value will be released.
|
||||
*/
|
||||
void
|
||||
main_print_unhandled_exception (jerry_value_t error_value) /**< error value */
|
||||
{
|
||||
assert (jerry_value_is_exception (error_value));
|
||||
error_value = jerry_exception_value (error_value, true);
|
||||
|
||||
jerry_char_t err_str_buf[256];
|
||||
|
||||
jerry_value_t err_str_val = jerry_value_to_string (error_value);
|
||||
|
||||
jerry_size_t string_end =
|
||||
jerry_string_to_buffer (err_str_val, JERRY_ENCODING_UTF8, err_str_buf, sizeof (err_str_buf) - 1);
|
||||
err_str_buf[string_end] = '\0';
|
||||
|
||||
if (jerry_feature_enabled (JERRY_FEATURE_ERROR_MESSAGES) && jerry_error_type (error_value) == JERRY_ERROR_SYNTAX)
|
||||
{
|
||||
jerry_char_t *string_end_p = err_str_buf + string_end;
|
||||
unsigned int err_line = 0;
|
||||
unsigned int err_col = 0;
|
||||
char *path_str_p = NULL;
|
||||
char *path_str_end_p = NULL;
|
||||
|
||||
/* 1. parse column and line information */
|
||||
for (jerry_char_t *current_p = err_str_buf; current_p < string_end_p; current_p++)
|
||||
{
|
||||
if (*current_p == '[')
|
||||
{
|
||||
current_p++;
|
||||
|
||||
if (*current_p == '<')
|
||||
{
|
||||
break;
|
||||
}
|
||||
|
||||
path_str_p = (char *) current_p;
|
||||
while (current_p < string_end_p && *current_p != ':')
|
||||
{
|
||||
current_p++;
|
||||
}
|
||||
|
||||
path_str_end_p = (char *) current_p++;
|
||||
|
||||
err_line = (unsigned int) strtol ((char *) current_p, (char **) ¤t_p, 10);
|
||||
|
||||
current_p++;
|
||||
|
||||
err_col = (unsigned int) strtol ((char *) current_p, NULL, 10);
|
||||
break;
|
||||
}
|
||||
} /* for */
|
||||
|
||||
if (err_line != 0 && err_col > 0 && err_col < SYNTAX_ERROR_MAX_LINE_LENGTH)
|
||||
{
|
||||
/* Temporarily modify the error message, so we can use the path. */
|
||||
*path_str_end_p = '\0';
|
||||
|
||||
size_t source_size;
|
||||
uint8_t *source_p = jerry_port_read_source (path_str_p, &source_size);
|
||||
|
||||
/* Revert the error message. */
|
||||
*path_str_end_p = ':';
|
||||
|
||||
if (source_p != NULL)
|
||||
{
|
||||
uint32_t curr_line = 1;
|
||||
uint32_t pos = 0;
|
||||
|
||||
/* 2. seek and print */
|
||||
while (pos < source_size && curr_line < err_line)
|
||||
{
|
||||
if (source_p[pos] == '\n')
|
||||
{
|
||||
curr_line++;
|
||||
}
|
||||
|
||||
pos++;
|
||||
}
|
||||
|
||||
/* Print character if:
|
||||
* - The max line length is not reached.
|
||||
* - The current position is valid (it is not the end of the source).
|
||||
* - The current character is not a newline.
|
||||
**/
|
||||
for (uint32_t char_count = 0;
|
||||
(char_count < SYNTAX_ERROR_MAX_LINE_LENGTH) && (pos < source_size) && (source_p[pos] != '\n');
|
||||
char_count++, pos++)
|
||||
{
|
||||
jerry_port_log (JERRY_LOG_LEVEL_ERROR, "%c", source_p[pos]);
|
||||
}
|
||||
jerry_port_log (JERRY_LOG_LEVEL_ERROR, "\n");
|
||||
|
||||
jerry_port_release_source (source_p);
|
||||
|
||||
while (--err_col)
|
||||
{
|
||||
jerry_port_log (JERRY_LOG_LEVEL_ERROR, "~");
|
||||
}
|
||||
|
||||
jerry_port_log (JERRY_LOG_LEVEL_ERROR, "^\n\n");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
jerry_port_log (JERRY_LOG_LEVEL_ERROR, "Unhandled exception: %s\n", err_str_buf);
|
||||
jerry_value_free (err_str_val);
|
||||
|
||||
if (jerry_value_is_object (error_value))
|
||||
{
|
||||
jerry_value_t stack_str = jerry_string_sz ("stack");
|
||||
jerry_value_t backtrace_val = jerry_object_get (error_value, stack_str);
|
||||
jerry_value_free (stack_str);
|
||||
|
||||
if (jerry_value_is_array (backtrace_val))
|
||||
{
|
||||
uint32_t length = jerry_array_length (backtrace_val);
|
||||
|
||||
/* This length should be enough. */
|
||||
if (length > 32)
|
||||
{
|
||||
length = 32;
|
||||
}
|
||||
|
||||
for (uint32_t i = 0; i < length; i++)
|
||||
{
|
||||
jerry_value_t item_val = jerry_object_get_index (backtrace_val, i);
|
||||
|
||||
if (jerry_value_is_string (item_val))
|
||||
{
|
||||
string_end = jerry_string_to_buffer (item_val, JERRY_ENCODING_UTF8, err_str_buf, sizeof (err_str_buf) - 1);
|
||||
err_str_buf[string_end] = '\0';
|
||||
|
||||
printf ("%6u: %s\n", i, err_str_buf);
|
||||
}
|
||||
|
||||
jerry_value_free (item_val);
|
||||
}
|
||||
}
|
||||
|
||||
jerry_value_free (backtrace_val);
|
||||
}
|
||||
|
||||
jerry_value_free (error_value);
|
||||
} /* main_print_unhandled_exception */
|
||||
|
||||
/**
|
||||
* Runs the source code received by jerry_debugger_wait_for_client_source.
|
||||
*
|
||||
* @return result fo the source code execution
|
||||
*/
|
||||
jerry_value_t
|
||||
main_wait_for_source_callback (const jerry_char_t *source_name_p, /**< source name */
|
||||
size_t source_name_size, /**< size of source name */
|
||||
const jerry_char_t *source_p, /**< source code */
|
||||
size_t source_size, /**< source code size */
|
||||
void *user_p) /**< user pointer */
|
||||
{
|
||||
(void) user_p; /* unused */
|
||||
|
||||
jerry_parse_options_t parse_options;
|
||||
parse_options.options = JERRY_PARSE_HAS_SOURCE_NAME;
|
||||
parse_options.source_name = jerry_string (source_name_p, (jerry_size_t) source_name_size, JERRY_ENCODING_UTF8);
|
||||
|
||||
jerry_value_t ret_val = jerry_parse (source_p, source_size, &parse_options);
|
||||
|
||||
jerry_value_free (parse_options.source_name);
|
||||
|
||||
if (!jerry_value_is_exception (ret_val))
|
||||
{
|
||||
jerry_value_t func_val = ret_val;
|
||||
ret_val = jerry_run (func_val);
|
||||
jerry_value_free (func_val);
|
||||
}
|
||||
|
||||
return ret_val;
|
||||
} /* main_wait_for_source_callback */
|
||||
|
||||
/**
|
||||
* Check that value contains the reset abort value.
|
||||
*
|
||||
* Note: if the value is the reset abort value, the value is release.
|
||||
*
|
||||
* return true, if reset abort
|
||||
* false, otherwise
|
||||
*/
|
||||
bool
|
||||
main_is_value_reset (jerry_value_t value) /**< jerry value */
|
||||
{
|
||||
if (!jerry_value_is_abort (value))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
jerry_value_t abort_value = jerry_exception_value (value, false);
|
||||
|
||||
if (!jerry_value_is_string (abort_value))
|
||||
{
|
||||
jerry_value_free (abort_value);
|
||||
return false;
|
||||
}
|
||||
|
||||
static const char restart_str[] = "r353t";
|
||||
|
||||
jerry_size_t str_size = jerry_string_size (abort_value, JERRY_ENCODING_CESU8);
|
||||
bool is_reset = false;
|
||||
|
||||
if (str_size == sizeof (restart_str) - 1)
|
||||
{
|
||||
JERRY_VLA (jerry_char_t, str_buf, str_size);
|
||||
jerry_string_to_buffer (abort_value, JERRY_ENCODING_CESU8, str_buf, str_size);
|
||||
|
||||
is_reset = memcmp (restart_str, (char *) (str_buf), str_size) == 0;
|
||||
|
||||
if (is_reset)
|
||||
{
|
||||
jerry_value_free (value);
|
||||
}
|
||||
}
|
||||
|
||||
jerry_value_free (abort_value);
|
||||
return is_reset;
|
||||
} /* main_is_value_reset */
|
||||
@ -1,40 +0,0 @@
|
||||
/* Copyright JS Foundation and other contributors, http://js.foundation
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#ifndef MAIN_UTILS_H
|
||||
#define MAIN_UTILS_H
|
||||
|
||||
#include "jerryscript.h"
|
||||
|
||||
#include "main-options.h"
|
||||
|
||||
/**
|
||||
* Standalone Jerry exit codes
|
||||
*/
|
||||
#define JERRY_STANDALONE_EXIT_CODE_OK (0)
|
||||
#define JERRY_STANDALONE_EXIT_CODE_FAIL (1)
|
||||
|
||||
void main_init_engine (main_args_t *arguments_p);
|
||||
void main_print_unhandled_exception (jerry_value_t error_value);
|
||||
|
||||
jerry_value_t main_wait_for_source_callback (const jerry_char_t *source_name_p,
|
||||
size_t source_name_size,
|
||||
const jerry_char_t *source_p,
|
||||
size_t source_size,
|
||||
void *user_p);
|
||||
|
||||
bool main_is_value_reset (jerry_value_t value);
|
||||
|
||||
#endif /* !MAIN_UTILS_H */
|
||||
@ -90,6 +90,7 @@ if(USING_GCC OR USING_CLANG)
|
||||
PROPERTY COMPILE_FLAGS "${COMPILE_FLAGS_MATH_GCC_CLANG}")
|
||||
endif()
|
||||
target_include_directories(${JERRY_MATH_NAME} PUBLIC ${INCLUDE_MATH})
|
||||
add_dependencies(${JERRY_MATH_NAME} amalgam)
|
||||
|
||||
configure_file(libjerry-math.pc.in libjerry-math.pc @ONLY)
|
||||
|
||||
|
||||
@ -13,51 +13,51 @@
|
||||
# limitations under the License.
|
||||
|
||||
cmake_minimum_required (VERSION 2.8.12)
|
||||
set(JERRY_PORT_DEFAULT_NAME jerry-port-default)
|
||||
project (${JERRY_PORT_DEFAULT_NAME} C)
|
||||
|
||||
# Include directories
|
||||
set(INCLUDE_PORT_DEFAULT "${CMAKE_CURRENT_SOURCE_DIR}/include")
|
||||
set(JERRY_PORT_NAME jerry-port)
|
||||
project (${JERRY_PORT_NAME} C)
|
||||
|
||||
# Source directories
|
||||
set(SOURCE_PORT_DEFAULT
|
||||
default-date.c
|
||||
default-debugger.c
|
||||
default-external-context.c
|
||||
default-fatal.c
|
||||
default-io.c
|
||||
default-module.c
|
||||
set(PORT_SOURCES
|
||||
common/jerry-port-context.c
|
||||
common/jerry-port-fs.c
|
||||
common/jerry-port-io.c
|
||||
common/jerry-port-process.c
|
||||
unix/jerry-port-unix-date.c
|
||||
unix/jerry-port-unix-fs.c
|
||||
unix/jerry-port-unix-process.c
|
||||
win/jerry-port-win-date.c
|
||||
win/jerry-port-win-fs.c
|
||||
win/jerry-port-win-process.c
|
||||
)
|
||||
|
||||
# Define _BSD_SOURCE and _DEFAULT_SOURCE
|
||||
# (should only be necessary if we used compiler default libc but not checking that)
|
||||
set(PORT_DEFINES
|
||||
_BSD_SOURCE
|
||||
_DEFAULT_SOURCE
|
||||
JERRY_GLOBAL_HEAP_SIZE=${JERRY_GLOBAL_HEAP_SIZE}
|
||||
)
|
||||
|
||||
# Amalgamated JerryScript source/header build.
|
||||
# The process will create the following files:
|
||||
# * jerryscript-port-default.c
|
||||
# * jerryscript-port-default.h
|
||||
# * jerryscript-port.c
|
||||
# * jerryscript-port.h
|
||||
if(ENABLE_AMALGAM)
|
||||
set(HEADER_PORT_DEFAULT
|
||||
include/jerryscript-port-default.h
|
||||
)
|
||||
set(AMALGAM_PORT_C "${CMAKE_BINARY_DIR}/amalgam/jerryscript-port-default.c")
|
||||
set(AMALGAM_PORT_H "${CMAKE_BINARY_DIR}/amalgam/jerryscript-port-default.h")
|
||||
set(AMALGAM_PORT_C "${CMAKE_BINARY_DIR}/amalgam/jerryscript-port.c")
|
||||
|
||||
add_custom_command(OUTPUT ${AMALGAM_PORT_C} ${AMALGAM_PORT_H}
|
||||
add_custom_command(OUTPUT ${AMALGAM_PORT_C}
|
||||
COMMAND ${PYTHON} ${CMAKE_SOURCE_DIR}/tools/amalgam.py
|
||||
--jerry-port-default
|
||||
--jerry-port
|
||||
--output-dir ${CMAKE_BINARY_DIR}/amalgam
|
||||
DEPENDS ${SOURCE_PORT_DEFAULT}
|
||||
${HEADER_PORT_DEFAULT}
|
||||
DEPENDS ${PORT_SOURCES}
|
||||
${CMAKE_SOURCE_DIR}/tools/amalgam.py
|
||||
)
|
||||
add_custom_target(amalgam-port DEPENDS ${AMALGAM_PORT_C} ${AMALGAM_PORT_H})
|
||||
add_custom_target(amalgam-port DEPENDS ${AMALGAM_PORT_C})
|
||||
add_dependencies(amalgam amalgam-port)
|
||||
|
||||
set(SOURCE_PORT_DEFAULT ${AMALGAM_PORT_C} ${AMALGAM_PORT_H})
|
||||
set(PORT_SOURCES ${AMALGAM_PORT_C})
|
||||
endif()
|
||||
|
||||
# Define _BSD_SOURCE and _DEFAULT_SOURCE
|
||||
# (should only be necessary if we used compiler default libc but not checking that)
|
||||
set(DEFINES_PORT_DEFAULT _BSD_SOURCE _DEFAULT_SOURCE)
|
||||
|
||||
INCLUDE (CheckStructHasMember)
|
||||
# CHECK_STRUCT_HAS_MEMBER works by trying to compile some C code that accesses the
|
||||
# given field of the given struct. However, our default compiler options break this
|
||||
@ -65,26 +65,25 @@ INCLUDE (CheckStructHasMember)
|
||||
if(USING_GCC OR USING_CLANG)
|
||||
set(CMAKE_REQUIRED_FLAGS "-Wno-error=strict-prototypes -Wno-error=old-style-definition -Wno-error=unused-value")
|
||||
endif()
|
||||
|
||||
# tm.tm_gmtoff is non-standard, so glibc doesn't expose it in c99 mode
|
||||
# (our default). Define some macros to expose it anyway.
|
||||
set(CMAKE_REQUIRED_DEFINITIONS "-D_BSD_SOURCE -D_DEFAULT_SOURCE")
|
||||
CHECK_STRUCT_HAS_MEMBER ("struct tm" tm_gmtoff time.h HAVE_TM_GMTOFF)
|
||||
|
||||
# localtime_r is is not threadsafe with clang on OSX
|
||||
if(HAVE_TM_GMTOFF AND NOT "${PLATFORM}" STREQUAL "DARWIN" AND NOT USING_CLANG)
|
||||
set(DEFINES_PORT_DEFAULT ${DEFINES_PORT_DEFAULT} HAVE_TM_GMTOFF)
|
||||
set(PORT_DEFINES ${PORT_DEFINES} HAVE_TM_GMTOFF)
|
||||
endif()
|
||||
|
||||
# Default Jerry port implementation library
|
||||
add_library(${JERRY_PORT_DEFAULT_NAME} ${SOURCE_PORT_DEFAULT})
|
||||
target_include_directories(${JERRY_PORT_DEFAULT_NAME} PUBLIC ${INCLUDE_PORT_DEFAULT})
|
||||
target_include_directories(${JERRY_PORT_DEFAULT_NAME} PRIVATE ${INCLUDE_CORE_PUBLIC})
|
||||
target_include_directories(${JERRY_PORT_DEFAULT_NAME} PRIVATE ${INCLUDE_EXT_PUBLIC})
|
||||
target_compile_definitions(${JERRY_PORT_DEFAULT_NAME} PRIVATE ${DEFINES_PORT_DEFAULT})
|
||||
target_link_libraries(${JERRY_PORT_DEFAULT_NAME} jerry-core) # FIXME: remove this dependency as soon as possible
|
||||
add_library(${JERRY_PORT_NAME} ${PORT_SOURCES})
|
||||
add_dependencies(${JERRY_PORT_NAME} amalgam)
|
||||
target_include_directories(${JERRY_PORT_NAME} PRIVATE ${INCLUDE_CORE_PUBLIC})
|
||||
target_compile_definitions(${JERRY_PORT_NAME} PRIVATE ${PORT_DEFINES})
|
||||
|
||||
# Installation
|
||||
configure_file(libjerry-port-default.pc.in libjerry-port-default.pc @ONLY)
|
||||
configure_file(libjerry-port.pc.in libjerry-port.pc @ONLY)
|
||||
|
||||
install(TARGETS ${JERRY_PORT_DEFAULT_NAME} DESTINATION lib)
|
||||
install(FILES ${CMAKE_CURRENT_BINARY_DIR}/libjerry-port-default.pc DESTINATION lib/pkgconfig)
|
||||
install(DIRECTORY ${INCLUDE_PORT_DEFAULT}/ DESTINATION include)
|
||||
install(TARGETS ${JERRY_PORT_NAME} DESTINATION lib)
|
||||
install(FILES ${CMAKE_CURRENT_BINARY_DIR}/libjerry-port.pc DESTINATION lib/pkgconfig)
|
||||
@ -13,9 +13,14 @@
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#include "jerryscript-port-default.h"
|
||||
#include <stdlib.h>
|
||||
|
||||
#include "jerryscript-port.h"
|
||||
|
||||
#ifndef JERRY_GLOBAL_HEAP_SIZE
|
||||
#define JERRY_GLOBAL_HEAP_SIZE 512
|
||||
#endif /* JERRY_GLOBAL_HEAP_SIZE */
|
||||
|
||||
/**
|
||||
* Pointer to the current context.
|
||||
* Note that it is a global variable, and is not a thread safe implementation.
|
||||
@ -23,21 +28,37 @@
|
||||
static jerry_context_t *current_context_p = NULL;
|
||||
|
||||
/**
|
||||
* Set the current_context_p as the passed pointer.
|
||||
* Allocate a new external context.
|
||||
*
|
||||
* @param context_size: requested context size
|
||||
*
|
||||
* @return total allcoated size
|
||||
*/
|
||||
void
|
||||
jerry_port_default_set_current_context (jerry_context_t *context_p) /**< points to the created context */
|
||||
size_t JERRY_ATTR_WEAK
|
||||
jerry_port_context_alloc (size_t context_size)
|
||||
{
|
||||
current_context_p = context_p;
|
||||
} /* jerry_port_default_set_current_context */
|
||||
size_t total_size = context_size + JERRY_GLOBAL_HEAP_SIZE * 1024;
|
||||
current_context_p = malloc (total_size);
|
||||
|
||||
return total_size;
|
||||
} /* jerry_port_context_alloc */
|
||||
|
||||
/**
|
||||
* Get the current context.
|
||||
*
|
||||
* @return the pointer to the current context
|
||||
*/
|
||||
jerry_context_t *
|
||||
jerry_port_get_current_context (void)
|
||||
jerry_context_t *JERRY_ATTR_WEAK
|
||||
jerry_port_context_get (void)
|
||||
{
|
||||
return current_context_p;
|
||||
} /* jerry_port_get_current_context */
|
||||
} /* jerry_port_context_get */
|
||||
|
||||
/**
|
||||
* Free the currently allocated external context.
|
||||
*/
|
||||
void JERRY_ATTR_WEAK
|
||||
jerry_port_context_free (void)
|
||||
{
|
||||
free (current_context_p);
|
||||
} /* jerry_port_context_free */
|
||||
162
jerry-port/common/jerry-port-fs.c
Normal file
162
jerry-port/common/jerry-port-fs.c
Normal file
@ -0,0 +1,162 @@
|
||||
/* Copyright JS Foundation and other contributors, http://js.foundation
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "jerryscript-port.h"
|
||||
|
||||
#if defined(__GLIBC__) || defined(_WIN32)
|
||||
#include <sys/stat.h>
|
||||
|
||||
#ifndef S_ISDIR
|
||||
#define S_ISDIR(mode) (((mode) &S_IFMT) == S_IFDIR)
|
||||
#endif /* !defined(S_ISDIR) */
|
||||
#endif /* __GLIBC__ */
|
||||
|
||||
/**
|
||||
* Determines the size of the given file.
|
||||
* @return size of the file
|
||||
*/
|
||||
static jerry_size_t
|
||||
jerry_port_get_file_size (FILE *file_p) /**< opened file */
|
||||
{
|
||||
fseek (file_p, 0, SEEK_END);
|
||||
long size = ftell (file_p);
|
||||
fseek (file_p, 0, SEEK_SET);
|
||||
|
||||
return (jerry_size_t) size;
|
||||
} /* jerry_port_get_file_size */
|
||||
|
||||
/**
|
||||
* Opens file with the given path and reads its source.
|
||||
* @return the source of the file
|
||||
*/
|
||||
jerry_char_t *JERRY_ATTR_WEAK
|
||||
jerry_port_source_read (const char *file_name_p, /**< file name */
|
||||
jerry_size_t *out_size_p) /**< [out] read bytes */
|
||||
{
|
||||
/* TODO(dbatyai): Temporary workaround for nuttx target
|
||||
* The nuttx target builds and copies the jerryscript libraries as a separate build step, which causes linking issues
|
||||
* later due to different libc libraries. It should incorporate the amalgam sources into the main nuttx build so that
|
||||
* the correct libraries are used, then this guard should be removed from here and also from the includes. */
|
||||
#if defined(__GLIBC__) || defined(_WIN32)
|
||||
struct stat stat_buffer;
|
||||
if (stat (file_name_p, &stat_buffer) == -1 || S_ISDIR (stat_buffer.st_mode))
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
#endif /* __GLIBC__ */
|
||||
|
||||
FILE *file_p = fopen (file_name_p, "rb");
|
||||
|
||||
if (file_p == NULL)
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
|
||||
jerry_size_t file_size = jerry_port_get_file_size (file_p);
|
||||
jerry_char_t *buffer_p = (jerry_char_t *) malloc (file_size);
|
||||
|
||||
if (buffer_p == NULL)
|
||||
{
|
||||
fclose (file_p);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
size_t bytes_read = fread (buffer_p, 1u, file_size, file_p);
|
||||
|
||||
if (bytes_read != file_size)
|
||||
{
|
||||
fclose (file_p);
|
||||
free (buffer_p);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
fclose (file_p);
|
||||
*out_size_p = (jerry_size_t) bytes_read;
|
||||
|
||||
return buffer_p;
|
||||
} /* jerry_port_source_read */
|
||||
|
||||
/**
|
||||
* Release the previously opened file's content.
|
||||
*/
|
||||
void JERRY_ATTR_WEAK
|
||||
jerry_port_source_free (uint8_t *buffer_p) /**< buffer to free */
|
||||
{
|
||||
free (buffer_p);
|
||||
} /* jerry_port_source_free */
|
||||
|
||||
/**
|
||||
* These functions provide generic implementation for paths and are only enabled when the compiler support weak symbols,
|
||||
* and we are not building for a platform that has platform specific versions.
|
||||
*/
|
||||
#if defined(JERRY_WEAK_SYMBOL_SUPPORT) && !(defined(__unix__) || defined(__APPLE__) || defined(_WIN32))
|
||||
|
||||
/**
|
||||
* Normalize a file path.
|
||||
*
|
||||
* @return a newly allocated buffer with the normalized path if the operation is successful,
|
||||
* NULL otherwise
|
||||
*/
|
||||
jerry_char_t *JERRY_ATTR_WEAK
|
||||
jerry_port_path_normalize (const jerry_char_t *path_p, /**< input path */
|
||||
jerry_size_t path_size) /**< size of the path */
|
||||
{
|
||||
jerry_char_t *buffer_p = (jerry_char_t *) malloc (path_size + 1);
|
||||
|
||||
if (buffer_p == NULL)
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/* Also copy terminating zero byte. */
|
||||
memcpy (buffer_p, path_p, path_size + 1);
|
||||
|
||||
return buffer_p;
|
||||
} /* jerry_port_normalize_path */
|
||||
|
||||
/**
|
||||
* Free a path buffer returned by jerry_port_path_normalize.
|
||||
*
|
||||
* @param path_p: the path to free
|
||||
*/
|
||||
void JERRY_ATTR_WEAK
|
||||
jerry_port_path_free (jerry_char_t *path_p)
|
||||
{
|
||||
free (path_p);
|
||||
} /* jerry_port_normalize_path */
|
||||
|
||||
/**
|
||||
* Computes the end of the directory part of a path.
|
||||
*
|
||||
* @return end of the directory part of a path.
|
||||
*/
|
||||
jerry_size_t JERRY_ATTR_WEAK
|
||||
jerry_port_path_base (const jerry_char_t *path_p) /**< path */
|
||||
{
|
||||
const jerry_char_t *basename_p = (jerry_char_t *) strrchr ((char *) path_p, '/') + 1;
|
||||
|
||||
if (basename_p == NULL)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
return (jerry_size_t) (basename_p - path_p);
|
||||
} /* jerry_port_get_directory_end */
|
||||
|
||||
#endif /* defined(JERRY_WEAK_SYMBOL_SUPPORT) && !(defined(__unix__) || defined(__APPLE__) || defined(_WIN32)) */
|
||||
106
jerry-port/common/jerry-port-io.c
Normal file
106
jerry-port/common/jerry-port-io.c
Normal file
@ -0,0 +1,106 @@
|
||||
/* Copyright JS Foundation and other contributors, http://js.foundation
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "jerryscript-port.h"
|
||||
|
||||
/**
|
||||
* Default implementation of jerry_port_log. Prints log messages to stderr.
|
||||
*/
|
||||
void JERRY_ATTR_WEAK
|
||||
jerry_port_log (const char *message_p) /**< message */
|
||||
{
|
||||
fputs (message_p, stderr);
|
||||
} /* jerry_port_log */
|
||||
|
||||
/**
|
||||
* Default implementation of jerry_port_print_byte. Uses 'putchar' to
|
||||
* print a single character to standard output.
|
||||
*/
|
||||
void JERRY_ATTR_WEAK
|
||||
jerry_port_print_byte (jerry_char_t byte) /**< the character to print */
|
||||
{
|
||||
putchar (byte);
|
||||
} /* jerry_port_print_byte */
|
||||
|
||||
/**
|
||||
* Default implementation of jerry_port_print_buffer. Uses 'jerry_port_print_byte' to
|
||||
* print characters of the input buffer.
|
||||
*/
|
||||
void JERRY_ATTR_WEAK
|
||||
jerry_port_print_buffer (const jerry_char_t *buffer_p, /**< string buffer */
|
||||
jerry_size_t buffer_size) /**< string size*/
|
||||
{
|
||||
for (jerry_size_t i = 0; i < buffer_size; i++)
|
||||
{
|
||||
jerry_port_print_byte (buffer_p[i]);
|
||||
}
|
||||
} /* jerry_port_print_byte */
|
||||
|
||||
/**
|
||||
* Read a line from standard input as a zero-terminated string.
|
||||
*
|
||||
* @param out_size_p: length of the string
|
||||
*
|
||||
* @return pointer to the buffer storing the string,
|
||||
* or NULL if end of input
|
||||
*/
|
||||
jerry_char_t *JERRY_ATTR_WEAK
|
||||
jerry_port_line_read (jerry_size_t *out_size_p)
|
||||
{
|
||||
char *line_p = NULL;
|
||||
size_t allocated = 0;
|
||||
size_t bytes = 0;
|
||||
|
||||
while (true)
|
||||
{
|
||||
allocated += 64;
|
||||
line_p = realloc (line_p, allocated);
|
||||
|
||||
while (bytes < allocated - 1)
|
||||
{
|
||||
char ch = (char) fgetc (stdin);
|
||||
|
||||
if (feof (stdin))
|
||||
{
|
||||
free (line_p);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
line_p[bytes++] = ch;
|
||||
|
||||
if (ch == '\n')
|
||||
{
|
||||
*out_size_p = (jerry_size_t) bytes;
|
||||
line_p[bytes++] = '\0';
|
||||
return (jerry_char_t *) line_p;
|
||||
}
|
||||
}
|
||||
}
|
||||
} /* jerry_port_line_read */
|
||||
|
||||
/**
|
||||
* Free a line buffer allocated by jerry_port_line_read
|
||||
*
|
||||
* @param buffer_p: buffer that has been allocated by jerry_port_line_read
|
||||
*/
|
||||
void JERRY_ATTR_WEAK
|
||||
jerry_port_line_free (jerry_char_t *buffer_p)
|
||||
{
|
||||
free (buffer_p);
|
||||
} /* jerry_port_line_free */
|
||||
@ -15,17 +15,16 @@
|
||||
|
||||
#include <stdlib.h>
|
||||
|
||||
#include "jerryscript-port-default.h"
|
||||
#include "jerryscript-port.h"
|
||||
|
||||
/**
|
||||
* Default implementation of jerry_port_fatal. Calls 'abort' if exit code is
|
||||
* non-zero, 'exit' otherwise.
|
||||
*/
|
||||
void
|
||||
void JERRY_ATTR_WEAK
|
||||
jerry_port_fatal (jerry_fatal_code_t code) /**< cause of error */
|
||||
{
|
||||
if (code != 0 && code != ERR_OUT_OF_MEMORY)
|
||||
if (code != 0 && code != JERRY_FATAL_OUT_OF_MEMORY)
|
||||
{
|
||||
abort ();
|
||||
}
|
||||
@ -1,163 +0,0 @@
|
||||
/* Copyright JS Foundation and other contributors, http://js.foundation
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#include <time.h>
|
||||
|
||||
#ifdef _WIN32
|
||||
#include <windows.h>
|
||||
|
||||
#include <winbase.h>
|
||||
#include <winnt.h>
|
||||
#endif /* _WIN32 */
|
||||
|
||||
#if defined(__GNUC__) || defined(__clang__)
|
||||
#include <sys/time.h>
|
||||
#endif /* __GNUC__ || __clang__ */
|
||||
|
||||
#include "jerryscript-port-default.h"
|
||||
#include "jerryscript-port.h"
|
||||
|
||||
#ifdef _WIN32
|
||||
static const LONGLONG UnixEpochInTicks = 116444736000000000; /* difference between 1970 and 1601 */
|
||||
static const LONGLONG TicksPerMs = 10000; /* 1 tick is 100 nanoseconds */
|
||||
|
||||
/* https://support.microsoft.com/en-us/help/167296/how-to-convert-a-unix-time-t-to-a-win32-filetime-or-systemtime */
|
||||
static void
|
||||
UnixTimeMsToFileTime (double t, LPFILETIME pft)
|
||||
{
|
||||
LONGLONG ll = (LONGLONG) t * TicksPerMs + UnixEpochInTicks;
|
||||
pft->dwLowDateTime = (DWORD) ll;
|
||||
pft->dwHighDateTime = (DWORD) (ll >> 32);
|
||||
} /* UnixTimeMsToFileTime */
|
||||
|
||||
static double
|
||||
FileTimeToUnixTimeMs (FILETIME ft)
|
||||
{
|
||||
ULARGE_INTEGER date;
|
||||
date.HighPart = ft.dwHighDateTime;
|
||||
date.LowPart = ft.dwLowDateTime;
|
||||
return (double) (((LONGLONG) date.QuadPart - UnixEpochInTicks) / TicksPerMs);
|
||||
} /* FileTimeToUnixTimeMs */
|
||||
|
||||
#endif /* _WIN32 */
|
||||
|
||||
/**
|
||||
* Default implementation of jerry_port_get_local_time_zone_adjustment.
|
||||
*
|
||||
* @return offset between UTC and local time at the given unix timestamp, if
|
||||
* available. Otherwise, returns 0, assuming UTC time.
|
||||
*/
|
||||
double
|
||||
jerry_port_get_local_time_zone_adjustment (double unix_ms, /**< ms since unix epoch */
|
||||
bool is_utc) /**< is the time above in UTC? */
|
||||
{
|
||||
#if defined(HAVE_TM_GMTOFF)
|
||||
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;
|
||||
#elif defined(_WIN32)
|
||||
FILETIME fileTime, localFileTime;
|
||||
SYSTEMTIME systemTime, localSystemTime;
|
||||
ULARGE_INTEGER time, localTime;
|
||||
|
||||
UnixTimeMsToFileTime (unix_ms, &fileTime);
|
||||
/* If time is earlier than year 1601, then always using year 1601 to query time zone adjustment */
|
||||
if (fileTime.dwHighDateTime >= 0x80000000)
|
||||
{
|
||||
fileTime.dwHighDateTime = 0;
|
||||
fileTime.dwLowDateTime = 0;
|
||||
}
|
||||
|
||||
if (FileTimeToSystemTime (&fileTime, &systemTime)
|
||||
&& SystemTimeToTzSpecificLocalTime (0, &systemTime, &localSystemTime)
|
||||
&& SystemTimeToFileTime (&localSystemTime, &localFileTime))
|
||||
{
|
||||
time.LowPart = fileTime.dwLowDateTime;
|
||||
time.HighPart = fileTime.dwHighDateTime;
|
||||
localTime.LowPart = localFileTime.dwLowDateTime;
|
||||
localTime.HighPart = localFileTime.dwHighDateTime;
|
||||
return (double) (((LONGLONG) localTime.QuadPart - (LONGLONG) time.QuadPart) / TicksPerMs);
|
||||
}
|
||||
return 0.0;
|
||||
#elif defined(__GNUC__) || defined(__clang__)
|
||||
time_t now_time = (time_t) (unix_ms / 1000);
|
||||
double tza_s = 0.0;
|
||||
|
||||
while (true)
|
||||
{
|
||||
struct tm now_tm;
|
||||
if (!gmtime_r (&now_time, &now_tm))
|
||||
{
|
||||
break;
|
||||
}
|
||||
now_tm.tm_isdst = -1; /* if not overridden, DST will not be taken into account */
|
||||
time_t local_time = mktime (&now_tm);
|
||||
if (local_time == (time_t) -1)
|
||||
{
|
||||
break;
|
||||
}
|
||||
tza_s = difftime (now_time, local_time);
|
||||
|
||||
if (is_utc)
|
||||
{
|
||||
break;
|
||||
}
|
||||
now_time -= (time_t) tza_s;
|
||||
is_utc = true;
|
||||
}
|
||||
|
||||
return tza_s * 1000;
|
||||
#else /* !HAVE_TM_GMTOFF && !_WIN32 && !__GNUC__ && !__clang__ */
|
||||
(void) unix_ms; /* unused */
|
||||
(void) is_utc; /* unused */
|
||||
return 0.0;
|
||||
#endif /* HAVE_TM_GMTOFF */
|
||||
} /* jerry_port_get_local_time_zone_adjustment */
|
||||
|
||||
/**
|
||||
* Default implementation of jerry_port_get_current_time. Uses 'gettimeofday' if
|
||||
* available on the system, does nothing otherwise.
|
||||
*
|
||||
* @return milliseconds since Unix epoch - if 'gettimeofday' is available and
|
||||
* executed successfully,
|
||||
* 0 - otherwise.
|
||||
*/
|
||||
double
|
||||
jerry_port_get_current_time (void)
|
||||
{
|
||||
#ifdef _WIN32
|
||||
FILETIME ft;
|
||||
GetSystemTimeAsFileTime (&ft);
|
||||
return FileTimeToUnixTimeMs (ft);
|
||||
#elif defined(__GNUC__) || defined(__clang__)
|
||||
struct timeval tv;
|
||||
|
||||
if (gettimeofday (&tv, NULL) == 0)
|
||||
{
|
||||
return ((double) tv.tv_sec) * 1000.0 + ((double) tv.tv_usec) / 1000.0;
|
||||
}
|
||||
return 0.0;
|
||||
#else /* !_WIN32 && !__GNUC__ && !__clang__ */
|
||||
return 0.0;
|
||||
#endif /* _WIN32 */
|
||||
} /* jerry_port_get_current_time */
|
||||
@ -1,109 +0,0 @@
|
||||
/* Copyright JS Foundation and other contributors, http://js.foundation
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#include <stdarg.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "jerryscript-debugger.h"
|
||||
#include "jerryscript-port-default.h"
|
||||
#include "jerryscript-port.h"
|
||||
|
||||
/**
|
||||
* Actual log level
|
||||
*/
|
||||
static jerry_log_level_t jerry_port_default_log_level = JERRY_LOG_LEVEL_ERROR;
|
||||
|
||||
/**
|
||||
* Get the log level
|
||||
*
|
||||
* @return current log level
|
||||
*/
|
||||
jerry_log_level_t
|
||||
jerry_port_default_get_log_level (void)
|
||||
{
|
||||
return jerry_port_default_log_level;
|
||||
} /* jerry_port_default_get_log_level */
|
||||
|
||||
/**
|
||||
* Set the log level
|
||||
*/
|
||||
void
|
||||
jerry_port_default_set_log_level (jerry_log_level_t level) /**< log level */
|
||||
{
|
||||
jerry_port_default_log_level = level;
|
||||
} /* jerry_port_default_set_log_level */
|
||||
|
||||
/**
|
||||
* Default implementation of jerry_port_log. Prints log message to the standard
|
||||
* error with 'vfprintf' if message log level is less than or equal to the
|
||||
* current log level.
|
||||
*
|
||||
* If debugger support is enabled, printing happens first to an in-memory buffer,
|
||||
* which is then sent both to the standard error and to the debugger client.
|
||||
*/
|
||||
void
|
||||
jerry_port_log (jerry_log_level_t level, /**< message log level */
|
||||
const char *format, /**< format string */
|
||||
...) /**< parameters */
|
||||
{
|
||||
if (level <= jerry_port_default_log_level)
|
||||
{
|
||||
va_list args;
|
||||
va_start (args, format);
|
||||
#if defined(JERRY_DEBUGGER) && (JERRY_DEBUGGER == 1)
|
||||
int length = vsnprintf (NULL, 0, format, args);
|
||||
va_end (args);
|
||||
va_start (args, format);
|
||||
|
||||
JERRY_VLA (char, buffer, length + 1);
|
||||
vsnprintf (buffer, (size_t) length + 1, format, args);
|
||||
|
||||
fprintf (stderr, "%s", buffer);
|
||||
jerry_debugger_send_log (level, (jerry_char_t *) buffer, (jerry_size_t) length);
|
||||
#else /* If jerry-debugger isn't defined, libc is turned on */
|
||||
vfprintf (stderr, format, args);
|
||||
#endif /* defined (JERRY_DEBUGGER) && (JERRY_DEBUGGER == 1) */
|
||||
va_end (args);
|
||||
}
|
||||
} /* jerry_port_log */
|
||||
|
||||
#if defined(JERRY_DEBUGGER) && (JERRY_DEBUGGER == 1)
|
||||
|
||||
#define DEBUG_BUFFER_SIZE (256)
|
||||
static char debug_buffer[DEBUG_BUFFER_SIZE];
|
||||
static int debug_buffer_index = 0;
|
||||
|
||||
#endif /* defined (JERRY_DEBUGGER) && (JERRY_DEBUGGER == 1) */
|
||||
|
||||
/**
|
||||
* Default implementation of jerry_port_print_char. Uses 'putchar' to
|
||||
* print a single character to standard output.
|
||||
*/
|
||||
void
|
||||
jerry_port_print_char (char c) /**< the character to print */
|
||||
{
|
||||
putchar (c);
|
||||
|
||||
#if defined(JERRY_DEBUGGER) && (JERRY_DEBUGGER == 1)
|
||||
debug_buffer[debug_buffer_index++] = c;
|
||||
|
||||
if ((debug_buffer_index == DEBUG_BUFFER_SIZE) || (c == '\n'))
|
||||
{
|
||||
jerry_debugger_send_output ((jerry_char_t *) debug_buffer, (jerry_size_t) debug_buffer_index);
|
||||
debug_buffer_index = 0;
|
||||
}
|
||||
#endif /* defined (JERRY_DEBUGGER) && (JERRY_DEBUGGER == 1) */
|
||||
} /* jerry_port_print_char */
|
||||
@ -1,410 +0,0 @@
|
||||
/* Copyright JS Foundation and other contributors, http://js.foundation
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#include <limits.h>
|
||||
#include <stdarg.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "jerryscript-port-default.h"
|
||||
#include "jerryscript-port.h"
|
||||
|
||||
#include <sys/stat.h>
|
||||
|
||||
#ifndef S_ISDIR
|
||||
#define S_ISDIR(mode) (((mode) &S_IFMT) == S_IFDIR)
|
||||
#endif /* !defined(S_ISDIR) */
|
||||
|
||||
/**
|
||||
* Determines the size of the given file.
|
||||
* @return size of the file
|
||||
*/
|
||||
static size_t
|
||||
jerry_port_get_file_size (FILE *file_p) /**< opened file */
|
||||
{
|
||||
fseek (file_p, 0, SEEK_END);
|
||||
long size = ftell (file_p);
|
||||
fseek (file_p, 0, SEEK_SET);
|
||||
|
||||
return (size_t) size;
|
||||
} /* jerry_port_get_file_size */
|
||||
|
||||
/**
|
||||
* 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 */
|
||||
{
|
||||
struct stat stat_buffer;
|
||||
if (stat (file_name_p, &stat_buffer) == -1 || S_ISDIR (stat_buffer.st_mode))
|
||||
{
|
||||
jerry_port_log (JERRY_LOG_LEVEL_ERROR, "Error: Failed to open file: %s\n", file_name_p);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
FILE *file_p = fopen (file_name_p, "rb");
|
||||
|
||||
if (file_p == NULL)
|
||||
{
|
||||
jerry_port_log (JERRY_LOG_LEVEL_ERROR, "Error: Failed to open file: %s\n", file_name_p);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
size_t file_size = jerry_port_get_file_size (file_p);
|
||||
uint8_t *buffer_p = (uint8_t *) malloc (file_size);
|
||||
|
||||
if (buffer_p == NULL)
|
||||
{
|
||||
fclose (file_p);
|
||||
|
||||
jerry_port_log (JERRY_LOG_LEVEL_ERROR, "Error: Failed to allocate memory for file: %s\n", file_name_p);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
size_t bytes_read = fread (buffer_p, 1u, file_size, file_p);
|
||||
|
||||
if (bytes_read != file_size)
|
||||
{
|
||||
fclose (file_p);
|
||||
free (buffer_p);
|
||||
|
||||
jerry_port_log (JERRY_LOG_LEVEL_ERROR, "Error: Failed to read file: %s\n", file_name_p);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
fclose (file_p);
|
||||
*out_size_p = bytes_read;
|
||||
|
||||
return buffer_p;
|
||||
} /* 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 */
|
||||
|
||||
/**
|
||||
* Computes the end of the directory part of a path.
|
||||
*
|
||||
* @return end of the directory part of a path.
|
||||
*/
|
||||
static size_t
|
||||
jerry_port_get_directory_end (const jerry_char_t *path_p) /**< path */
|
||||
{
|
||||
const jerry_char_t *end_p = path_p + strlen ((const char *) path_p);
|
||||
|
||||
while (end_p > path_p)
|
||||
{
|
||||
#if defined(_WIN32)
|
||||
if (end_p[-1] == '/' || end_p[-1] == '\\')
|
||||
{
|
||||
return (size_t) (end_p - path_p);
|
||||
}
|
||||
#else /* !_WIN32 */
|
||||
if (end_p[-1] == '/')
|
||||
{
|
||||
return (size_t) (end_p - path_p);
|
||||
}
|
||||
#endif /* _WIN32 */
|
||||
|
||||
end_p--;
|
||||
}
|
||||
|
||||
return 0;
|
||||
} /* jerry_port_get_directory_end */
|
||||
|
||||
/**
|
||||
* Normalize a file path.
|
||||
*
|
||||
* @return a newly allocated buffer with the normalized path if the operation is successful,
|
||||
* NULL otherwise
|
||||
*/
|
||||
static jerry_char_t *
|
||||
jerry_port_normalize_path (const jerry_char_t *in_path_p, /**< path to the referenced module */
|
||||
size_t in_path_length, /**< length of the path */
|
||||
const jerry_char_t *base_path_p, /**< base path */
|
||||
size_t base_path_length) /**< length of the base path */
|
||||
{
|
||||
char *path_p;
|
||||
|
||||
if (base_path_length > 0)
|
||||
{
|
||||
path_p = (char *) malloc (base_path_length + in_path_length + 1);
|
||||
|
||||
if (path_p == NULL)
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
|
||||
memcpy (path_p, base_path_p, base_path_length);
|
||||
memcpy (path_p + base_path_length, in_path_p, in_path_length);
|
||||
path_p[base_path_length + in_path_length] = '\0';
|
||||
}
|
||||
else
|
||||
{
|
||||
path_p = (char *) malloc (in_path_length + 1);
|
||||
|
||||
if (path_p == NULL)
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
|
||||
memcpy (path_p, in_path_p, in_path_length);
|
||||
path_p[in_path_length] = '\0';
|
||||
}
|
||||
|
||||
#if defined(_WIN32)
|
||||
char full_path[_MAX_PATH];
|
||||
|
||||
if (_fullpath (full_path, path_p, _MAX_PATH) != NULL)
|
||||
{
|
||||
free (path_p);
|
||||
|
||||
size_t full_path_len = strlen (full_path);
|
||||
|
||||
path_p = (char *) malloc (full_path_len + 1);
|
||||
|
||||
if (path_p == NULL)
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
|
||||
memcpy (path_p, full_path, full_path_len + 1);
|
||||
}
|
||||
#elif defined(__unix__) || defined(__APPLE__)
|
||||
char *norm_p = realpath (path_p, NULL);
|
||||
|
||||
if (norm_p != NULL)
|
||||
{
|
||||
free (path_p);
|
||||
path_p = norm_p;
|
||||
}
|
||||
#endif /* _WIN32 */
|
||||
|
||||
return (jerry_char_t *) path_p;
|
||||
} /* jerry_port_normalize_path */
|
||||
|
||||
/**
|
||||
* A module descriptor.
|
||||
*/
|
||||
typedef struct jerry_port_module_t
|
||||
{
|
||||
struct jerry_port_module_t *next_p; /**< next_module */
|
||||
jerry_char_t *path_p; /**< path to the module */
|
||||
size_t base_path_length; /**< base path length for relative difference */
|
||||
jerry_value_t realm; /**< the realm of the module */
|
||||
jerry_value_t module; /**< the module itself */
|
||||
} jerry_port_module_t;
|
||||
|
||||
/**
|
||||
* Native info descriptor for modules.
|
||||
*/
|
||||
static const jerry_object_native_info_t jerry_port_module_native_info = {
|
||||
.free_cb = NULL,
|
||||
};
|
||||
|
||||
/**
|
||||
* Default module manager.
|
||||
*/
|
||||
typedef struct
|
||||
{
|
||||
jerry_port_module_t *module_head_p; /**< first module */
|
||||
} jerry_port_module_manager_t;
|
||||
|
||||
/**
|
||||
* Release known modules.
|
||||
*/
|
||||
static void
|
||||
jerry_port_module_free (jerry_port_module_manager_t *manager_p, /**< module manager */
|
||||
const jerry_value_t realm) /**< if this argument is object, release only those modules,
|
||||
* which realm value is equal to this argument. */
|
||||
{
|
||||
jerry_port_module_t *module_p = manager_p->module_head_p;
|
||||
|
||||
bool release_all = !jerry_value_is_object (realm);
|
||||
|
||||
jerry_port_module_t *prev_p = NULL;
|
||||
|
||||
while (module_p != NULL)
|
||||
{
|
||||
jerry_port_module_t *next_p = module_p->next_p;
|
||||
|
||||
if (release_all || module_p->realm == realm)
|
||||
{
|
||||
free (module_p->path_p);
|
||||
jerry_value_free (module_p->realm);
|
||||
jerry_value_free (module_p->module);
|
||||
|
||||
free (module_p);
|
||||
|
||||
if (prev_p == NULL)
|
||||
{
|
||||
manager_p->module_head_p = next_p;
|
||||
}
|
||||
else
|
||||
{
|
||||
prev_p->next_p = next_p;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
prev_p = module_p;
|
||||
}
|
||||
|
||||
module_p = next_p;
|
||||
}
|
||||
} /* jerry_port_module_free */
|
||||
|
||||
/**
|
||||
* Initialize the default module manager.
|
||||
*/
|
||||
static void
|
||||
jerry_port_module_manager_init (void *user_data_p)
|
||||
{
|
||||
((jerry_port_module_manager_t *) user_data_p)->module_head_p = NULL;
|
||||
} /* jerry_port_module_manager_init */
|
||||
|
||||
/**
|
||||
* Deinitialize the default module manager.
|
||||
*/
|
||||
static void
|
||||
jerry_port_module_manager_deinit (void *user_data_p) /**< context pointer to deinitialize */
|
||||
{
|
||||
jerry_value_t undef = jerry_undefined ();
|
||||
jerry_port_module_free ((jerry_port_module_manager_t *) user_data_p, undef);
|
||||
jerry_value_free (undef);
|
||||
} /* jerry_port_module_manager_deinit */
|
||||
|
||||
/**
|
||||
* Declare the context data manager for modules.
|
||||
*/
|
||||
static const jerry_context_data_manager_t jerry_port_module_manager = { .init_cb = jerry_port_module_manager_init,
|
||||
.deinit_cb = jerry_port_module_manager_deinit,
|
||||
.bytes_needed =
|
||||
sizeof (jerry_port_module_manager_t) };
|
||||
|
||||
/**
|
||||
* Default module resolver.
|
||||
*
|
||||
* @return a module object if resolving is successful, an error otherwise
|
||||
*/
|
||||
jerry_value_t
|
||||
jerry_port_module_resolve (const jerry_value_t specifier, /**< module specifier string */
|
||||
const jerry_value_t referrer, /**< parent module */
|
||||
void *user_p) /**< user data */
|
||||
{
|
||||
(void) user_p;
|
||||
|
||||
const jerry_char_t *base_path_p = NULL;
|
||||
size_t base_path_length = 0;
|
||||
jerry_port_module_t *module_p = jerry_object_get_native_ptr (referrer, &jerry_port_module_native_info);
|
||||
|
||||
if (module_p != NULL)
|
||||
{
|
||||
base_path_p = module_p->path_p;
|
||||
base_path_length = module_p->base_path_length;
|
||||
}
|
||||
|
||||
jerry_size_t in_path_length = jerry_string_size (specifier, JERRY_ENCODING_UTF8);
|
||||
jerry_char_t *in_path_p = (jerry_char_t *) malloc (in_path_length + 1);
|
||||
jerry_string_to_buffer (specifier, JERRY_ENCODING_UTF8, in_path_p, in_path_length);
|
||||
in_path_p[in_path_length] = '\0';
|
||||
|
||||
jerry_char_t *path_p = jerry_port_normalize_path (in_path_p, in_path_length, base_path_p, base_path_length);
|
||||
|
||||
if (path_p == NULL)
|
||||
{
|
||||
return jerry_throw_sz (JERRY_ERROR_COMMON, "Out of memory");
|
||||
}
|
||||
|
||||
jerry_value_t realm = jerry_current_realm ();
|
||||
|
||||
jerry_port_module_manager_t *manager_p;
|
||||
manager_p = (jerry_port_module_manager_t *) jerry_context_data (&jerry_port_module_manager);
|
||||
|
||||
module_p = manager_p->module_head_p;
|
||||
|
||||
while (module_p != NULL)
|
||||
{
|
||||
if (module_p->realm == realm && strcmp ((const char *) module_p->path_p, (const char *) path_p) == 0)
|
||||
{
|
||||
free (path_p);
|
||||
free (in_path_p);
|
||||
jerry_value_free (realm);
|
||||
return jerry_value_copy (module_p->module);
|
||||
}
|
||||
|
||||
module_p = module_p->next_p;
|
||||
}
|
||||
|
||||
size_t source_size;
|
||||
uint8_t *source_p = jerry_port_read_source ((const char *) path_p, &source_size);
|
||||
|
||||
if (source_p == NULL)
|
||||
{
|
||||
free (path_p);
|
||||
free (in_path_p);
|
||||
jerry_value_free (realm);
|
||||
/* TODO: This is incorrect, but makes test262 module tests pass
|
||||
* (they should throw SyntaxError, but not because the module cannot be found). */
|
||||
return jerry_throw_sz (JERRY_ERROR_SYNTAX, "Module file not found");
|
||||
}
|
||||
|
||||
jerry_parse_options_t parse_options;
|
||||
parse_options.options = JERRY_PARSE_MODULE | JERRY_PARSE_HAS_SOURCE_NAME;
|
||||
parse_options.source_name = jerry_string (in_path_p, in_path_length, JERRY_ENCODING_UTF8);
|
||||
|
||||
jerry_value_t ret_value = jerry_parse (source_p, source_size, &parse_options);
|
||||
jerry_value_free (parse_options.source_name);
|
||||
|
||||
jerry_port_release_source (source_p);
|
||||
free (in_path_p);
|
||||
|
||||
if (jerry_value_is_exception (ret_value))
|
||||
{
|
||||
free (path_p);
|
||||
jerry_value_free (realm);
|
||||
return ret_value;
|
||||
}
|
||||
|
||||
module_p = (jerry_port_module_t *) malloc (sizeof (jerry_port_module_t));
|
||||
|
||||
module_p->next_p = manager_p->module_head_p;
|
||||
module_p->path_p = path_p;
|
||||
module_p->base_path_length = jerry_port_get_directory_end (module_p->path_p);
|
||||
module_p->realm = realm;
|
||||
module_p->module = jerry_value_copy (ret_value);
|
||||
|
||||
jerry_object_set_native_ptr (ret_value, &jerry_port_module_native_info, module_p);
|
||||
manager_p->module_head_p = module_p;
|
||||
|
||||
return ret_value;
|
||||
} /* jerry_port_module_resolve */
|
||||
|
||||
/**
|
||||
* Release known modules.
|
||||
*/
|
||||
void
|
||||
jerry_port_module_release (const jerry_value_t realm) /**< if this argument is object, release only those modules,
|
||||
* which realm value is equal to this argument. */
|
||||
{
|
||||
jerry_port_module_free ((jerry_port_module_manager_t *) jerry_context_data (&jerry_port_module_manager), realm);
|
||||
} /* jerry_port_module_release */
|
||||
@ -2,9 +2,9 @@ prefix=@CMAKE_INSTALL_PREFIX@
|
||||
libdir=${prefix}/lib
|
||||
includedir=${prefix}/include
|
||||
|
||||
Name: libjerry-port-default
|
||||
Name: libjerry-port
|
||||
Description: JerryScript: lightweight JavaScript engine (default port library)
|
||||
URL: https://github.com/jerryscript-project/jerryscript
|
||||
Version: @JERRY_VERSION@
|
||||
Libs: -L${libdir} -ljerry-port-default
|
||||
Libs: -L${libdir} -ljerry-port
|
||||
Cflags: -I${includedir}
|
||||
70
jerry-port/unix/jerry-port-unix-date.c
Normal file
70
jerry-port/unix/jerry-port-unix-date.c
Normal file
@ -0,0 +1,70 @@
|
||||
/* Copyright JS Foundation and other contributors, http://js.foundation
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#include "jerryscript-port.h"
|
||||
|
||||
#if defined(__unix__) || defined(__APPLE__)
|
||||
|
||||
#include <sys/time.h>
|
||||
#include <time.h>
|
||||
|
||||
/**
|
||||
* Default implementation of jerry_port_local_tza.
|
||||
*
|
||||
* @return offset between UTC and local time at the given unix timestamp, if
|
||||
* available. Otherwise, returns 0, assuming UTC time.
|
||||
*/
|
||||
int32_t
|
||||
jerry_port_local_tza (double unix_ms)
|
||||
{
|
||||
time_t time = (time_t) unix_ms / 1000;
|
||||
|
||||
#if defined(HAVE_TM_GMTOFF)
|
||||
struct tm tm;
|
||||
localtime_r (&time, &tm);
|
||||
|
||||
return ((int32_t) tm.tm_gmtoff) * 1000;
|
||||
#else /* !defined(HAVE_TM_GMTOFF) */
|
||||
struct tm gmt_tm;
|
||||
struct tm local_tm;
|
||||
|
||||
gmtime_r (&time, &gmt_tm);
|
||||
localtime_r (&time, &local_tm);
|
||||
|
||||
time_t gmt = mktime (&gmt_tm);
|
||||
|
||||
/* mktime removes the daylight saving time from the result time value, however we want to keep it */
|
||||
local_tm.tm_isdst = 0;
|
||||
time_t local = mktime (&local_tm);
|
||||
|
||||
return (int32_t) difftime (local, gmt) * 1000;
|
||||
#endif /* HAVE_TM_GMTOFF */
|
||||
} /* jerry_port_local_tza */
|
||||
|
||||
/**
|
||||
* Default implementation of jerry_port_current_time.
|
||||
*
|
||||
* @return milliseconds since Unix epoch
|
||||
*/
|
||||
double
|
||||
jerry_port_current_time (void)
|
||||
{
|
||||
struct timeval tv;
|
||||
gettimeofday (&tv, NULL);
|
||||
|
||||
return ((double) tv.tv_sec) * 1000.0 + ((double) tv.tv_usec) / 1000.0;
|
||||
} /* jerry_port_current_time */
|
||||
|
||||
#endif /* defined(__unix__) || defined(__APPLE__) */
|
||||
63
jerry-port/unix/jerry-port-unix-fs.c
Normal file
63
jerry-port/unix/jerry-port-unix-fs.c
Normal file
@ -0,0 +1,63 @@
|
||||
/* Copyright JS Foundation and other contributors, http://js.foundation
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#include "jerryscript-port.h"
|
||||
|
||||
#if defined(__unix__) || defined(__APPLE__)
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
/**
|
||||
* Normalize a file path using realpath.
|
||||
*
|
||||
* @param path_p: input path
|
||||
* @param path_size: input path size
|
||||
*
|
||||
* @return a newly allocated buffer with the normalized path if the operation is successful,
|
||||
* NULL otherwise
|
||||
*/
|
||||
jerry_char_t *
|
||||
jerry_port_path_normalize (const jerry_char_t *path_p, /**< input path */
|
||||
jerry_size_t path_size) /**< size of the path */
|
||||
{
|
||||
(void) path_size;
|
||||
|
||||
return (jerry_char_t *) realpath ((char *) path_p, NULL);
|
||||
} /* jerry_port_path_normalize */
|
||||
|
||||
/**
|
||||
* Free a path buffer returned by jerry_port_path_normalize.
|
||||
*/
|
||||
void
|
||||
jerry_port_path_free (jerry_char_t *path_p)
|
||||
{
|
||||
free (path_p);
|
||||
} /* jerry_port_path_free */
|
||||
|
||||
/**
|
||||
* Computes the end of the directory part of a path.
|
||||
*
|
||||
* @return end of the directory part of a path.
|
||||
*/
|
||||
jerry_size_t JERRY_ATTR_WEAK
|
||||
jerry_port_path_base (const jerry_char_t *path_p) /**< path */
|
||||
{
|
||||
const jerry_char_t *basename_p = (jerry_char_t *) strrchr ((char *) path_p, '/') + 1;
|
||||
|
||||
return (jerry_size_t) (basename_p - path_p);
|
||||
} /* jerry_port_get_directory_end */
|
||||
|
||||
#endif /* defined(__unix__) || defined(__APPLE__) */
|
||||
@ -13,31 +13,25 @@
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#include "jerryscript-port.h"
|
||||
|
||||
#if defined(__unix__) || defined(__APPLE__)
|
||||
|
||||
#if !defined(_XOPEN_SOURCE) || _XOPEN_SOURCE < 500
|
||||
#undef _XOPEN_SOURCE
|
||||
/* Required macro for sleep functions (nanosleep or usleep) */
|
||||
#define _XOPEN_SOURCE 500
|
||||
#endif /* !(defined(_XOPEN_SOURCE) || _XOPEN_SOURCE < 500) */
|
||||
|
||||
#ifdef _WIN32
|
||||
#include <windows.h>
|
||||
#else /* !_WIN32 */
|
||||
#include <unistd.h>
|
||||
#endif /* _WIN32 */
|
||||
|
||||
#include "jerryscript-port-default.h"
|
||||
#include "jerryscript-port.h"
|
||||
|
||||
/**
|
||||
* Default implementation of jerry_port_sleep. Uses 'usleep' if available on the
|
||||
* system, does nothing otherwise.
|
||||
* Default implementation of jerry_port_sleep, uses 'usleep'.
|
||||
*/
|
||||
void
|
||||
jerry_port_sleep (uint32_t sleep_time) /**< milliseconds to sleep */
|
||||
{
|
||||
#ifdef _WIN32
|
||||
Sleep (sleep_time);
|
||||
#else /* !_WIN32 */
|
||||
usleep ((useconds_t) sleep_time * 1000);
|
||||
#endif /* _WIN32 */
|
||||
} /* jerry_port_sleep */
|
||||
|
||||
#endif /* defined(__unix__) || defined(__APPLE__) */
|
||||
102
jerry-port/win/jerry-port-win-date.c
Normal file
102
jerry-port/win/jerry-port-win-date.c
Normal file
@ -0,0 +1,102 @@
|
||||
/* Copyright JS Foundation and other contributors, http://js.foundation
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#include "jerryscript-port.h"
|
||||
|
||||
#if defined(_WIN32)
|
||||
|
||||
#include <windows.h>
|
||||
|
||||
#include <time.h>
|
||||
#include <winbase.h>
|
||||
#include <winnt.h>
|
||||
|
||||
#define UNIX_EPOCH_IN_TICKS 116444736000000000ull /* difference between 1970 and 1601 */
|
||||
#define TICKS_PER_MS 10000ull /* 1 tick is 100 nanoseconds */
|
||||
|
||||
/**
|
||||
* Convert unix time to a FILETIME value.
|
||||
*
|
||||
* https://support.microsoft.com/en-us/help/167296/how-to-convert-a-unix-time-t-to-a-win32-filetime-or-systemtime
|
||||
*/
|
||||
static void
|
||||
unix_time_to_filetime (double t, LPFILETIME ft_p)
|
||||
{
|
||||
LONGLONG ll = (LONGLONG) t * TICKS_PER_MS + UNIX_EPOCH_IN_TICKS;
|
||||
|
||||
/* FILETIME values before the epoch are invalid. */
|
||||
if (ll < 0)
|
||||
{
|
||||
ll = 0;
|
||||
}
|
||||
|
||||
ft_p->dwLowDateTime = (DWORD) ll;
|
||||
ft_p->dwHighDateTime = (DWORD) (ll >> 32);
|
||||
} /* unix_time_to_file_time */
|
||||
|
||||
/**
|
||||
* Convert a FILETIME to a unix time value.
|
||||
*
|
||||
* @return unix time
|
||||
*/
|
||||
static double
|
||||
filetime_to_unix_time (LPFILETIME ft_p)
|
||||
{
|
||||
ULARGE_INTEGER date;
|
||||
date.HighPart = ft_p->dwHighDateTime;
|
||||
date.LowPart = ft_p->dwLowDateTime;
|
||||
return (double) (((LONGLONG) date.QuadPart - UNIX_EPOCH_IN_TICKS) / TICKS_PER_MS);
|
||||
} /* FileTimeToUnixTimeMs */
|
||||
|
||||
/**
|
||||
* Default implementation of jerry_port_local_tza.
|
||||
*
|
||||
* @return offset between UTC and local time at the given unix timestamp, if
|
||||
* available. Otherwise, returns 0, assuming UTC time.
|
||||
*/
|
||||
int32_t
|
||||
jerry_port_local_tza (double unix_ms)
|
||||
{
|
||||
FILETIME utc;
|
||||
FILETIME local;
|
||||
SYSTEMTIME utc_sys;
|
||||
SYSTEMTIME local_sys;
|
||||
|
||||
unix_time_to_filetime (unix_ms, &utc);
|
||||
|
||||
if (FileTimeToSystemTime (&utc, &utc_sys) && SystemTimeToTzSpecificLocalTime (NULL, &utc_sys, &local_sys)
|
||||
&& SystemTimeToFileTime (&local_sys, &local))
|
||||
{
|
||||
double unix_local = filetime_to_unix_time (&local);
|
||||
return (int32_t) (unix_local - unix_ms);
|
||||
}
|
||||
|
||||
return 0;
|
||||
} /* jerry_port_local_tza */
|
||||
|
||||
/**
|
||||
* Default implementation of jerry_port_current_time.
|
||||
*
|
||||
* @return milliseconds since Unix epoch
|
||||
*/
|
||||
double
|
||||
jerry_port_current_time (void)
|
||||
{
|
||||
FILETIME ft;
|
||||
GetSystemTimeAsFileTime (&ft);
|
||||
return filetime_to_unix_time (&ft);
|
||||
} /* jerry_port_current_time */
|
||||
|
||||
#endif /* defined(_WIN32) */
|
||||
72
jerry-port/win/jerry-port-win-fs.c
Normal file
72
jerry-port/win/jerry-port-win-fs.c
Normal file
@ -0,0 +1,72 @@
|
||||
/* Copyright JS Foundation and other contributors, http://js.foundation
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#include "jerryscript-port.h"
|
||||
|
||||
#if defined(_WIN32)
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
/**
|
||||
* Normalize a file path.
|
||||
*
|
||||
* @return a newly allocated buffer with the normalized path if the operation is successful,
|
||||
* NULL otherwise
|
||||
*/
|
||||
jerry_char_t *
|
||||
jerry_port_path_normalize (const jerry_char_t *path_p, /**< input path */
|
||||
jerry_size_t path_size) /**< size of the path */
|
||||
{
|
||||
(void) path_size;
|
||||
|
||||
return (jerry_char_t *) _fullpath (NULL, path_p, _MAX_PATH);
|
||||
} /* jerry_port_path_normalize */
|
||||
|
||||
/**
|
||||
* Free a path buffer returned by jerry_port_path_normalize.
|
||||
*/
|
||||
void
|
||||
jerry_port_path_free (jerry_char_t *path_p)
|
||||
{
|
||||
free (path_p);
|
||||
} /* jerry_port_path_free */
|
||||
|
||||
/**
|
||||
* Get the end of the directory part of the input path.
|
||||
*
|
||||
* @param path_p: input zero-terminated path string
|
||||
*
|
||||
* @return offset of the directory end in the input path string
|
||||
*/
|
||||
jerry_size_t
|
||||
jerry_port_path_base (const jerry_char_t *path_p)
|
||||
{
|
||||
const jerry_char_t *end_p = path_p + strlen ((const char *) path_p);
|
||||
|
||||
while (end_p > path_p)
|
||||
{
|
||||
if (end_p[-1] == '/' || end_p[-1] == '\\')
|
||||
{
|
||||
return (jerry_size_t) (end_p - path_p);
|
||||
}
|
||||
|
||||
end_p--;
|
||||
}
|
||||
|
||||
return 0;
|
||||
} /* jerry_port_path_base */
|
||||
|
||||
#endif /* defined(_WIN32) */
|
||||
30
jerry-port/win/jerry-port-win-process.c
Normal file
30
jerry-port/win/jerry-port-win-process.c
Normal file
@ -0,0 +1,30 @@
|
||||
/* Copyright JS Foundation and other contributors, http://js.foundation
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
#include "jerryscript-port.h"
|
||||
|
||||
#if defined(_WIN32)
|
||||
|
||||
#include <windows.h>
|
||||
|
||||
/**
|
||||
* Default implementation of jerry_port_sleep, uses 'Sleep'.
|
||||
*/
|
||||
void
|
||||
jerry_port_sleep (uint32_t sleep_time) /**< milliseconds to sleep */
|
||||
{
|
||||
Sleep (sleep_time);
|
||||
} /* jerry_port_sleep */
|
||||
|
||||
#endif /* defined(_WIN32) */
|
||||
@ -1,7 +1,7 @@
|
||||
This is a port for espressif's esp-idf (esp32). The MATH, LTO and STRIP options should be disabled, so to build under the IDF toolchain, just run the following command
|
||||
|
||||
```
|
||||
python tools\build.py --toolchain=cmake/toolchain-esp32.cmake --cmake-param "-GUnix Makefiles" --jerry-cmdline=OFF --jerry-port-default=OFF --lto=OFF --strip=OFF
|
||||
python tools\build.py --toolchain=cmake/toolchain-esp32.cmake --cmake-param "-GUnix Makefiles" --jerry-cmdline=OFF --jerry-port=OFF --lto=OFF --strip=OFF
|
||||
```
|
||||
|
||||
NB: the MATH, STRIP and LTO might be disabled by platform as well. I strongly suggest limiting heap memory with '--mem-heap=128' but that really depends on the SRAM available on your esp32.
|
||||
|
||||
@ -1,293 +0,0 @@
|
||||
/* Copyright JS Foundation and other contributors, http://js.foundation
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <unistd.h>
|
||||
|
||||
#include "jerryscript-port.h"
|
||||
#include "jerryscript.h"
|
||||
|
||||
/**
|
||||
* Computes the end of the directory part of a path.
|
||||
*
|
||||
* @return end of the directory part of a path.
|
||||
*/
|
||||
static size_t
|
||||
jerry_port_get_directory_end (const jerry_char_t *path_p) /**< path */
|
||||
{
|
||||
const jerry_char_t *end_p = path_p + strlen ((const char *) path_p);
|
||||
|
||||
while (end_p > path_p)
|
||||
{
|
||||
if (end_p[-1] == '/')
|
||||
{
|
||||
return (size_t) (end_p - path_p);
|
||||
}
|
||||
|
||||
end_p--;
|
||||
}
|
||||
|
||||
return 0;
|
||||
} /* jerry_port_get_directory_end */
|
||||
|
||||
/**
|
||||
* Normalize a file path.
|
||||
*
|
||||
* @return a newly allocated buffer with the normalized path if the operation is successful,
|
||||
* NULL otherwise
|
||||
*/
|
||||
static jerry_char_t *
|
||||
jerry_port_normalize_path (const jerry_char_t *in_path_p, /**< path to the referenced module */
|
||||
size_t in_path_length, /**< length of the path */
|
||||
const jerry_char_t *base_path_p, /**< base path */
|
||||
size_t base_path_length) /**< length of the base path */
|
||||
{
|
||||
char *path_p;
|
||||
|
||||
if (base_path_length > 0)
|
||||
{
|
||||
path_p = (char *) malloc (base_path_length + in_path_length + 1);
|
||||
|
||||
if (path_p == NULL)
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
|
||||
memcpy (path_p, base_path_p, base_path_length);
|
||||
memcpy (path_p + base_path_length, in_path_p, in_path_length);
|
||||
path_p[base_path_length + in_path_length] = '\0';
|
||||
}
|
||||
else
|
||||
{
|
||||
path_p = (char *) malloc (in_path_length + 1);
|
||||
|
||||
if (path_p == NULL)
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
|
||||
memcpy (path_p, in_path_p, in_path_length);
|
||||
path_p[in_path_length] = '\0';
|
||||
}
|
||||
|
||||
return (jerry_char_t *) path_p;
|
||||
} /* jerry_port_normalize_path */
|
||||
|
||||
/**
|
||||
* A module descriptor.
|
||||
*/
|
||||
typedef struct jerry_port_module_t
|
||||
{
|
||||
struct jerry_port_module_t *next_p; /**< next_module */
|
||||
jerry_char_t *path_p; /**< path to the module */
|
||||
size_t base_path_length; /**< base path length for relative difference */
|
||||
jerry_value_t realm; /**< the realm of the module */
|
||||
jerry_value_t module; /**< the module itself */
|
||||
} jerry_port_module_t;
|
||||
|
||||
/**
|
||||
* Native info descriptor for modules.
|
||||
*/
|
||||
static const jerry_object_native_info_t jerry_port_module_native_info = {
|
||||
.free_cb = NULL,
|
||||
};
|
||||
|
||||
/**
|
||||
* Default module manager.
|
||||
*/
|
||||
typedef struct
|
||||
{
|
||||
jerry_port_module_t *module_head_p; /**< first module */
|
||||
} jerry_port_module_manager_t;
|
||||
|
||||
/**
|
||||
* Release known modules.
|
||||
*/
|
||||
static void
|
||||
jerry_port_module_free (jerry_port_module_manager_t *manager_p, /**< module manager */
|
||||
const jerry_value_t realm) /**< if this argument is object, release only those modules,
|
||||
* which realm value is equal to this argument. */
|
||||
{
|
||||
jerry_port_module_t *module_p = manager_p->module_head_p;
|
||||
|
||||
bool release_all = !jerry_value_is_object (realm);
|
||||
|
||||
jerry_port_module_t *prev_p = NULL;
|
||||
|
||||
while (module_p != NULL)
|
||||
{
|
||||
jerry_port_module_t *next_p = module_p->next_p;
|
||||
|
||||
if (release_all || module_p->realm == realm)
|
||||
{
|
||||
free (module_p->path_p);
|
||||
jerry_value_free (module_p->realm);
|
||||
jerry_value_free (module_p->module);
|
||||
|
||||
free (module_p);
|
||||
|
||||
if (prev_p == NULL)
|
||||
{
|
||||
manager_p->module_head_p = next_p;
|
||||
}
|
||||
else
|
||||
{
|
||||
prev_p->next_p = next_p;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
prev_p = module_p;
|
||||
}
|
||||
|
||||
module_p = next_p;
|
||||
}
|
||||
} /* jerry_port_module_free */
|
||||
|
||||
/**
|
||||
* Initialize the default module manager.
|
||||
*/
|
||||
static void
|
||||
jerry_port_module_manager_init (void *user_data_p)
|
||||
{
|
||||
((jerry_port_module_manager_t *) user_data_p)->module_head_p = NULL;
|
||||
} /* jerry_port_module_manager_init */
|
||||
|
||||
/**
|
||||
* Deinitialize the default module manager.
|
||||
*/
|
||||
static void
|
||||
jerry_port_module_manager_deinit (void *user_data_p) /**< context pointer to deinitialize */
|
||||
{
|
||||
jerry_value_t undef = jerry_undefined ();
|
||||
jerry_port_module_free ((jerry_port_module_manager_t *) user_data_p, undef);
|
||||
jerry_value_free (undef);
|
||||
} /* jerry_port_module_manager_deinit */
|
||||
|
||||
/**
|
||||
* Declare the context data manager for modules.
|
||||
*/
|
||||
static const jerry_context_data_manager_t jerry_port_module_manager = { .init_cb = jerry_port_module_manager_init,
|
||||
.deinit_cb = jerry_port_module_manager_deinit,
|
||||
.bytes_needed =
|
||||
sizeof (jerry_port_module_manager_t) };
|
||||
|
||||
/**
|
||||
* Default module resolver.
|
||||
*
|
||||
* @return a module object if resolving is successful, an error otherwise
|
||||
*/
|
||||
jerry_value_t
|
||||
jerry_port_module_resolve (const jerry_value_t specifier, /**< module specifier string */
|
||||
const jerry_value_t referrer, /**< parent module */
|
||||
void *user_p) /**< user data */
|
||||
{
|
||||
(void) user_p;
|
||||
|
||||
const jerry_char_t *base_path_p = NULL;
|
||||
size_t base_path_length = 0;
|
||||
jerry_port_module_t *module_p = jerry_object_get_native_ptr (referrer, &jerry_port_module_native_info);
|
||||
|
||||
if (module_p != NULL)
|
||||
{
|
||||
base_path_p = module_p->path_p;
|
||||
base_path_length = module_p->base_path_length;
|
||||
}
|
||||
|
||||
jerry_size_t in_path_length = jerry_string_size (specifier, JERRY_ENCODING_UTF8);
|
||||
jerry_char_t *in_path_p = (jerry_char_t *) malloc (in_path_length + 1);
|
||||
jerry_string_to_buffer (specifier, JERRY_ENCODING_UTF8, in_path_p, in_path_length);
|
||||
in_path_p[in_path_length] = '\0';
|
||||
|
||||
jerry_char_t *path_p = jerry_port_normalize_path (in_path_p, in_path_length, base_path_p, base_path_length);
|
||||
|
||||
if (path_p == NULL)
|
||||
{
|
||||
return jerry_throw_sz (JERRY_ERROR_COMMON, "Out of memory");
|
||||
}
|
||||
|
||||
jerry_value_t realm = jerry_current_realm ();
|
||||
|
||||
jerry_port_module_manager_t *manager_p;
|
||||
manager_p = (jerry_port_module_manager_t *) jerry_context_data (&jerry_port_module_manager);
|
||||
|
||||
module_p = manager_p->module_head_p;
|
||||
|
||||
while (module_p != NULL)
|
||||
{
|
||||
if (module_p->realm == realm && strcmp ((const char *) module_p->path_p, (const char *) path_p) == 0)
|
||||
{
|
||||
free (path_p);
|
||||
free (in_path_p);
|
||||
jerry_value_free (realm);
|
||||
return jerry_value_copy (module_p->module);
|
||||
}
|
||||
|
||||
module_p = module_p->next_p;
|
||||
}
|
||||
|
||||
size_t source_size;
|
||||
uint8_t *source_p = jerry_port_read_source ((const char *) path_p, &source_size);
|
||||
|
||||
if (source_p == NULL)
|
||||
{
|
||||
free (path_p);
|
||||
free (in_path_p);
|
||||
jerry_value_free (realm);
|
||||
return jerry_throw_sz (JERRY_ERROR_SYNTAX, "Module file not found");
|
||||
}
|
||||
|
||||
jerry_parse_options_t parse_options;
|
||||
parse_options.options = JERRY_PARSE_MODULE | JERRY_PARSE_HAS_SOURCE_NAME;
|
||||
parse_options.source_name = jerry_string ((const jerry_char_t *) in_path_p, in_path_length, JERRY_ENCODING_UTF8);
|
||||
|
||||
jerry_value_t ret_value = jerry_parse (source_p, source_size, &parse_options);
|
||||
|
||||
jerry_value_free (parse_options.source_name);
|
||||
jerry_port_release_source (source_p);
|
||||
free (in_path_p);
|
||||
|
||||
if (jerry_value_is_exception (ret_value))
|
||||
{
|
||||
free (path_p);
|
||||
jerry_value_free (realm);
|
||||
return ret_value;
|
||||
}
|
||||
|
||||
module_p = (jerry_port_module_t *) malloc (sizeof (jerry_port_module_t));
|
||||
|
||||
module_p->next_p = manager_p->module_head_p;
|
||||
module_p->path_p = path_p;
|
||||
module_p->base_path_length = jerry_port_get_directory_end (module_p->path_p);
|
||||
module_p->realm = realm;
|
||||
module_p->module = jerry_value_copy (ret_value);
|
||||
|
||||
jerry_object_set_native_ptr (ret_value, &jerry_port_module_native_info, module_p);
|
||||
manager_p->module_head_p = module_p;
|
||||
|
||||
return ret_value;
|
||||
} /* jerry_port_module_resolve */
|
||||
|
||||
/**
|
||||
* Release known modules.
|
||||
*/
|
||||
void
|
||||
jerry_port_module_release (const jerry_value_t realm) /**< if this argument is object, release only those modules,
|
||||
* which realm value is equal to this argument. */
|
||||
{
|
||||
jerry_port_module_free ((jerry_port_module_manager_t *) jerry_context_data (&jerry_port_module_manager), realm);
|
||||
} /* jerry_port_module_release */
|
||||
@ -13,198 +13,68 @@
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#include <limits.h>
|
||||
#include <stdarg.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <sys/stat.h>
|
||||
#include <sys/time.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/stat.h>
|
||||
#include <unistd.h>
|
||||
|
||||
#include "freertos/FreeRTOS.h"
|
||||
#include "freertos/task.h"
|
||||
#include "jerryscript-port.h"
|
||||
#include "jerryscript.h"
|
||||
|
||||
#include "esp_log.h"
|
||||
#include "esp_system.h"
|
||||
|
||||
#include "jerryscript.h"
|
||||
#include "jerryscript-port.h"
|
||||
#include "freertos/FreeRTOS.h"
|
||||
#include "freertos/task.h"
|
||||
|
||||
static const char TAG[] = "JS";
|
||||
|
||||
static esp_log_level_t crosslog(jerry_log_level_t level)
|
||||
{
|
||||
switch(level)
|
||||
{
|
||||
case JERRY_LOG_LEVEL_ERROR: return ESP_LOG_ERROR;
|
||||
case JERRY_LOG_LEVEL_WARNING: return ESP_LOG_WARN;
|
||||
case JERRY_LOG_LEVEL_DEBUG: return ESP_LOG_DEBUG;
|
||||
case JERRY_LOG_LEVEL_TRACE: return ESP_LOG_VERBOSE;
|
||||
}
|
||||
|
||||
return ESP_LOG_NONE;
|
||||
}
|
||||
|
||||
/**
|
||||
* Actual log level
|
||||
*/
|
||||
static jerry_log_level_t jerry_port_default_log_level = JERRY_LOG_LEVEL_ERROR;
|
||||
|
||||
/**
|
||||
* Get the log level
|
||||
*
|
||||
* @return current log level
|
||||
*/
|
||||
jerry_log_level_t
|
||||
jerry_port_default_get_log_level (void)
|
||||
{
|
||||
return jerry_port_default_log_level;
|
||||
} /* jerry_port_default_get_log_level */
|
||||
|
||||
/**
|
||||
* Set the log level
|
||||
*/
|
||||
void
|
||||
jerry_port_default_set_log_level (jerry_log_level_t level) /**< log level */
|
||||
{
|
||||
jerry_port_default_log_level = level;
|
||||
} /* jerry_port_default_set_log_level */
|
||||
|
||||
/**
|
||||
* Default implementation of jerry_port_log. Prints log message to the standard
|
||||
* error with 'vfprintf' if message log level is less than or equal to the
|
||||
* current log level.
|
||||
*
|
||||
* If debugger support is enabled, printing happens first to an in-memory buffer,
|
||||
* which is then sent both to the standard error and to the debugger client.
|
||||
*/
|
||||
void
|
||||
jerry_port_log (jerry_log_level_t level, /**< message log level */
|
||||
const char *format, /**< format string */
|
||||
...) /**< parameters */
|
||||
{
|
||||
if (level <= jerry_port_default_log_level)
|
||||
{
|
||||
va_list args;
|
||||
va_start (args, format);
|
||||
#if defined (JERRY_DEBUGGER) && (JERRY_DEBUGGER == 1)
|
||||
int length = vsnprintf (NULL, 0, format, args);
|
||||
va_end (args);
|
||||
va_start (args, format);
|
||||
|
||||
JERRY_VLA (char, buffer, length + 1);
|
||||
vsnprintf (buffer, (size_t) length + 1, format, args);
|
||||
|
||||
esp_log_write(crosslog(level), TAG, buffer);
|
||||
jerry_debugger_send_log (level, (jerry_char_t *) buffer, (jerry_size_t) length);
|
||||
#else /* If jerry-debugger isn't defined, libc is turned on */
|
||||
esp_log_writev(crosslog(level), TAG, format, args);
|
||||
#endif /* defined (JERRY_DEBUGGER) && (JERRY_DEBUGGER == 1) */
|
||||
va_end (args);
|
||||
}
|
||||
} /* jerry_port_log */
|
||||
|
||||
#if defined (JERRY_DEBUGGER) && (JERRY_DEBUGGER == 1)
|
||||
|
||||
#define DEBUG_BUFFER_SIZE (256)
|
||||
static char debug_buffer[DEBUG_BUFFER_SIZE];
|
||||
static int debug_buffer_index = 0;
|
||||
|
||||
#endif /* defined (JERRY_DEBUGGER) && (JERRY_DEBUGGER == 1) */
|
||||
|
||||
/**
|
||||
* Default implementation of jerry_port_print_char. Uses 'putchar' to
|
||||
* print a single character to standard output.
|
||||
*/
|
||||
void
|
||||
jerry_port_print_char (char c) /**< the character to print */
|
||||
{
|
||||
putchar(c);
|
||||
|
||||
#if defined (JERRY_DEBUGGER) && (JERRY_DEBUGGER == 1)
|
||||
debug_buffer[debug_buffer_index++] = c;
|
||||
|
||||
if ((debug_buffer_index == DEBUG_BUFFER_SIZE) || (c == '\n'))
|
||||
{
|
||||
jerry_debugger_send_output ((jerry_char_t *) debug_buffer, (jerry_size_t) debug_buffer_index);
|
||||
debug_buffer_index = 0;
|
||||
}
|
||||
#endif /* defined (JERRY_DEBUGGER) && (JERRY_DEBUGGER == 1) */
|
||||
} /* jerry_port_print_char */
|
||||
|
||||
/**
|
||||
* Default implementation of jerry_port_fatal. Calls 'abort' if exit code is
|
||||
* non-zero, 'exit' otherwise.
|
||||
*/
|
||||
void jerry_port_fatal (jerry_fatal_code_t code) /**< cause of error */
|
||||
{
|
||||
ESP_LOGE(TAG, "Fatal error %d", code);
|
||||
vTaskSuspend(NULL);
|
||||
abort();
|
||||
} /* jerry_port_fatal */
|
||||
|
||||
/**
|
||||
* Pointer to the current context.
|
||||
* Note that it is a global variable, and is not a thread safe implementation.
|
||||
* But I don't see how jerryscript can make that thread-safe, only the appication can
|
||||
*/
|
||||
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 */
|
||||
jerry_port_fatal (jerry_fatal_code_t code) /**< cause of error */
|
||||
{
|
||||
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 */
|
||||
ESP_LOGE (TAG, "Fatal error %d", code);
|
||||
vTaskSuspend (NULL);
|
||||
abort ();
|
||||
} /* jerry_port_fatal */
|
||||
|
||||
/**
|
||||
* Default implementation of jerry_port_sleep. Uses 'nanosleep' or 'usleep' if
|
||||
* available on the system, does nothing otherwise.
|
||||
*/
|
||||
void jerry_port_sleep (uint32_t sleep_time) /**< milliseconds to sleep */
|
||||
void
|
||||
jerry_port_sleep (uint32_t sleep_time) /**< milliseconds to sleep */
|
||||
{
|
||||
vTaskDelay( sleep_time / portTICK_PERIOD_MS);
|
||||
vTaskDelay (sleep_time / portTICK_PERIOD_MS);
|
||||
} /* jerry_port_sleep */
|
||||
|
||||
/**
|
||||
* 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 */
|
||||
jerry_char_t *
|
||||
jerry_port_source_read (const char *file_name_p, /**< file name */
|
||||
jerry_size_t *out_size_p) /**< [out] read bytes */
|
||||
{
|
||||
FILE *file_p = fopen (file_name_p, "rb");
|
||||
|
||||
if (file_p == NULL)
|
||||
{
|
||||
jerry_port_log (JERRY_LOG_LEVEL_ERROR, "Error: Failed to open file: %s\n", file_name_p);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
struct stat info = { };
|
||||
fstat(fileno(file_p), &info);
|
||||
uint8_t *buffer_p = (uint8_t *) malloc (info.st_size);
|
||||
struct stat info = {};
|
||||
fstat (fileno (file_p), &info);
|
||||
jerry_char_t *buffer_p = (jerry_char_t *) malloc (info.st_size);
|
||||
|
||||
if (buffer_p == NULL)
|
||||
{
|
||||
fclose (file_p);
|
||||
|
||||
jerry_port_log (JERRY_LOG_LEVEL_ERROR, "Error: Failed to allocate memory for file: %s\n", file_name_p);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
@ -214,63 +84,54 @@ jerry_port_read_source (const char *file_name_p, /**< file name */
|
||||
fclose (file_p);
|
||||
free (buffer_p);
|
||||
|
||||
jerry_port_log (JERRY_LOG_LEVEL_ERROR, "Error: Failed to read file: %s\n", file_name_p);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
fclose (file_p);
|
||||
*out_size_p = bytes_read;
|
||||
*out_size_p = (jerry_size_t) bytes_read;
|
||||
|
||||
return buffer_p;
|
||||
} /* jerry_port_read_source */
|
||||
} /* jerry_port_source_read */
|
||||
|
||||
/**
|
||||
* Release the previously opened file's content.
|
||||
*/
|
||||
void
|
||||
jerry_port_release_source (uint8_t *buffer_p) /**< buffer to free */
|
||||
jerry_port_source_free (uint8_t *buffer_p) /**< buffer to free */
|
||||
{
|
||||
free (buffer_p);
|
||||
} /* jerry_port_release_source */
|
||||
} /* jerry_port_source_free */
|
||||
|
||||
/**
|
||||
* Default implementation of jerry_port_get_local_time_zone_adjustment. Uses the 'tm_gmtoff' field
|
||||
* Default implementation of jerry_port_local_tza. Uses the 'tm_gmtoff' field
|
||||
* of 'struct tm' (a GNU extension) filled by 'localtime_r' if available on the
|
||||
* system, does nothing otherwise.
|
||||
*
|
||||
* @return offset between UTC and local time at the given unix timestamp, if
|
||||
* available. Otherwise, returns 0, assuming UTC time.
|
||||
*/
|
||||
double jerry_port_get_local_time_zone_adjustment (double unix_ms, /**< ms since unix epoch */
|
||||
bool is_utc) /**< is the time above in UTC? */
|
||||
int32_t
|
||||
jerry_port_local_tza (double unix_ms)
|
||||
{
|
||||
struct tm tm;
|
||||
char buf[8];
|
||||
time_t now = (time_t) (unix_ms / 1000);
|
||||
time_t now = (time_t) unix_ms / 1000;
|
||||
|
||||
localtime_r (&now, &tm);
|
||||
|
||||
if (!is_utc)
|
||||
{
|
||||
strftime(buf, 8, "%z", &tm);
|
||||
now -= -atof(buf) * 3600 * 1000 / 100;
|
||||
localtime_r (&now, &tm);
|
||||
}
|
||||
|
||||
strftime(buf, 8, "%z", &tm);
|
||||
|
||||
return -atof(buf) * 3600 * 1000 / 100;
|
||||
} /* jerry_port_get_local_time_zone_adjustment */
|
||||
strftime (buf, 8, "%z", &tm);
|
||||
return -atoi (buf) * 3600 * 1000 / 100;
|
||||
} /* jerry_port_local_tza */
|
||||
|
||||
/**
|
||||
* Default implementation of jerry_port_get_current_time. Uses 'gettimeofday' if
|
||||
* Default implementation of jerry_port_current_time. Uses 'gettimeofday' if
|
||||
* available on the system, does nothing otherwise.
|
||||
*
|
||||
* @return milliseconds since Unix epoch - if 'gettimeofday' is available and
|
||||
* executed successfully,
|
||||
* 0 - otherwise.
|
||||
*/
|
||||
double jerry_port_get_current_time (void)
|
||||
double
|
||||
jerry_port_current_time (void)
|
||||
{
|
||||
struct timeval tv;
|
||||
|
||||
@ -279,5 +140,4 @@ double jerry_port_get_current_time (void)
|
||||
return ((double) tv.tv_sec) * 1000.0 + ((double) tv.tv_usec) / 1000.0;
|
||||
}
|
||||
return 0.0;
|
||||
} /* jerry_port_get_current_time */
|
||||
|
||||
} /* jerry_port_current_time */
|
||||
|
||||
@ -56,8 +56,9 @@ jerry:
|
||||
-DEXTERNAL_COMPILE_FLAGS="$(ESP_CFLAGS)" \
|
||||
-DJERRY_GLOBAL_HEAP_SIZE=$(JERRYHEAP)
|
||||
|
||||
make -C$(BUILD_DIR) jerry-core jerry-math
|
||||
make -C$(BUILD_DIR) jerry-core jerry-ext jerry-math
|
||||
cp $(BUILD_DIR)/lib/libjerry-core.a $(COPYTARGET)/
|
||||
cp $(BUILD_DIR)/lib/libjerry-ext.a $(COPYTARGET)/
|
||||
cp $(BUILD_DIR)/lib/libjerry-math.a $(COPYTARGET)/
|
||||
|
||||
js2c:
|
||||
|
||||
@ -13,29 +13,21 @@
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdarg.h>
|
||||
#include <stdio.h>
|
||||
#include <sys/time.h>
|
||||
|
||||
#include "esp_common.h"
|
||||
|
||||
#include "jerryscript-port.h"
|
||||
|
||||
#include "esp_common.h"
|
||||
|
||||
/**
|
||||
* Provide log message implementation for the engine.
|
||||
*/
|
||||
void
|
||||
jerry_port_log (jerry_log_level_t level, /**< log level */
|
||||
const char *format, /**< format string */
|
||||
...) /**< parameters */
|
||||
jerry_port_log (const char *message_p) /**< message */
|
||||
{
|
||||
(void) level; /* ignore log level */
|
||||
|
||||
va_list args;
|
||||
va_start (args, format);
|
||||
vfprintf (stderr, format, args);
|
||||
va_end (args);
|
||||
fputs (message_p, stderr);
|
||||
} /* jerry_port_log */
|
||||
|
||||
/**
|
||||
@ -44,30 +36,37 @@ jerry_port_log (jerry_log_level_t level, /**< log level */
|
||||
void
|
||||
jerry_port_fatal (jerry_fatal_code_t code)
|
||||
{
|
||||
jerry_port_log (JERRY_LOG_LEVEL_ERROR, "Jerry Fatal Error!\n");
|
||||
while (true);
|
||||
(void) code;
|
||||
|
||||
jerry_port_log ("Jerry Fatal Error!\n");
|
||||
|
||||
while (true)
|
||||
{
|
||||
}
|
||||
} /* jerry_port_fatal */
|
||||
|
||||
/**
|
||||
* Implementation of jerry_port_get_current_time.
|
||||
* Implementation of jerry_port_current_time.
|
||||
*
|
||||
* @return current timer's counter value in milliseconds
|
||||
*/
|
||||
double
|
||||
jerry_port_get_current_time (void)
|
||||
jerry_port_current_time (void)
|
||||
{
|
||||
uint32_t rtc_time = system_rtc_clock_cali_proc();
|
||||
uint32_t rtc_time = system_rtc_clock_cali_proc ();
|
||||
return (double) rtc_time;
|
||||
} /* jerry_port_get_current_time */
|
||||
} /* jerry_port_current_time */
|
||||
|
||||
/**
|
||||
* Dummy function to get the time zone adjustment.
|
||||
*
|
||||
* @return 0
|
||||
*/
|
||||
double
|
||||
jerry_port_get_local_time_zone_adjustment (double unix_ms, bool is_utc)
|
||||
int32_t
|
||||
jerry_port_local_tza (double unix_ms)
|
||||
{
|
||||
(void) unix_ms;
|
||||
|
||||
/* We live in UTC. */
|
||||
return 0;
|
||||
} /* jerry_port_get_local_time_zone_adjustment */
|
||||
} /* jerry_port_local_tza */
|
||||
|
||||
@ -32,7 +32,7 @@ js_entry ()
|
||||
{
|
||||
double d;
|
||||
unsigned u;
|
||||
} now = { .d = jerry_port_get_current_time () };
|
||||
} now = { .d = jerry_port_current_time () };
|
||||
srand (now.u);
|
||||
|
||||
jerry_init (JERRY_INIT_EMPTY);
|
||||
|
||||
@ -2,7 +2,6 @@ cmake/*
|
||||
docs/*
|
||||
jerry-main/*
|
||||
jerry-math/*
|
||||
jerry-port/*
|
||||
targets/*
|
||||
tests/*
|
||||
third-party/*
|
||||
|
||||
@ -13,11 +13,12 @@
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#include "mbed.h"
|
||||
#include "jerryscript-port.h"
|
||||
#include "jerryscript.h"
|
||||
|
||||
#include "jerry-core/include/jerryscript.h"
|
||||
#include "jerry-core/include/jerryscript-port.h"
|
||||
#include "jerryscript-ext/handler.h"
|
||||
#include "jerryscript-ext/handlers.h"
|
||||
#include "jerryscript-ext/properties.h"
|
||||
#include "mbed.h"
|
||||
|
||||
/**
|
||||
* Standalone Jerry exit codes
|
||||
@ -25,40 +26,23 @@
|
||||
#define JERRY_STANDALONE_EXIT_CODE_OK (0)
|
||||
#define JERRY_STANDALONE_EXIT_CODE_FAIL (1)
|
||||
|
||||
/**
|
||||
* Register a JavaScript function in the global object.
|
||||
*/
|
||||
static void
|
||||
register_js_function (const char *name_p, /**< name of the function */
|
||||
jerry_external_handler_t handler_p) /**< function callback */
|
||||
int
|
||||
main ()
|
||||
{
|
||||
jerry_value_t result_val = jerryx_handler_register_global (name_p, handler_p);
|
||||
|
||||
if (jerry_value_is_exception (result_val))
|
||||
{
|
||||
jerry_port_log (JERRY_LOG_LEVEL_WARNING, "[Warning] Failed to register '%s' method.", name_p);
|
||||
}
|
||||
|
||||
jerry_value_free (result_val);
|
||||
} /* register_js_function */
|
||||
|
||||
int main()
|
||||
{
|
||||
Serial device(USBTX, USBRX); // tx, rx
|
||||
device.baud(115200);
|
||||
Serial device (USBTX, USBRX); // tx, rx
|
||||
device.baud (115200);
|
||||
|
||||
/* Initialize engine */
|
||||
jerry_init (JERRY_INIT_EMPTY);
|
||||
|
||||
jerry_value_t ret_value = jerry_undefined ();
|
||||
const jerry_char_t script[] = "print ('Hello, World!');";
|
||||
jerry_port_log (JERRY_LOG_LEVEL_DEBUG, "This test run the following script code: [%s]\n\n", script);
|
||||
jerry_log (JERRY_LOG_LEVEL_DEBUG, "This test run the following script code: [%s]\n\n", script);
|
||||
|
||||
/* Register the print function in the global object. */
|
||||
register_js_function ("print", jerryx_handler_print);
|
||||
jerryx_register_global ("print", jerryx_handler_print);
|
||||
|
||||
/* Setup Global scope code */
|
||||
ret_value = jerry_parse (script, sizeof (script) - 1, NULL);
|
||||
jerry_value_t ret_value = jerry_parse (script, sizeof (script) - 1, NULL);
|
||||
|
||||
if (!jerry_value_is_exception (ret_value))
|
||||
{
|
||||
@ -70,7 +54,7 @@ int main()
|
||||
|
||||
if (jerry_value_is_exception (ret_value))
|
||||
{
|
||||
jerry_port_log (JERRY_LOG_LEVEL_ERROR, "[Error] Script Error!");
|
||||
jerry_log (JERRY_LOG_LEVEL_ERROR, "[Error] Script Error!");
|
||||
|
||||
ret_code = JERRY_STANDALONE_EXIT_CODE_FAIL;
|
||||
}
|
||||
|
||||
@ -13,55 +13,37 @@
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#include <stdarg.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "jerryscript.h"
|
||||
#include "jerryscript-port.h"
|
||||
|
||||
#include "mbed.h"
|
||||
|
||||
/**
|
||||
* JerryScript log level.
|
||||
*/
|
||||
static jerry_log_level_t jerry_log_level = JERRY_LOG_LEVEL_ERROR;
|
||||
|
||||
/**
|
||||
* Sets log level.
|
||||
*/
|
||||
void set_log_level (jerry_log_level_t level)
|
||||
{
|
||||
jerry_log_level = level;
|
||||
} /* set_log_level */
|
||||
|
||||
/**
|
||||
* Aborts the program.
|
||||
*/
|
||||
void jerry_port_fatal (jerry_fatal_code_t code)
|
||||
void
|
||||
jerry_port_fatal (jerry_fatal_code_t code)
|
||||
{
|
||||
exit (1);
|
||||
exit ((int) code);
|
||||
} /* jerry_port_fatal */
|
||||
|
||||
/**
|
||||
* Provide log message implementation for the engine.
|
||||
*/
|
||||
void
|
||||
jerry_port_log (jerry_log_level_t level, /**< log level */
|
||||
const char *format, /**< format string */
|
||||
...) /**< parameters */
|
||||
jerry_port_log (const char *message_p) /**< message */
|
||||
{
|
||||
(void) level; /* ignore log level */
|
||||
|
||||
va_list args;
|
||||
va_start (args, format);
|
||||
vfprintf (stderr, format, args);
|
||||
va_end (args);
|
||||
|
||||
if (strlen (format) == 1 && format[0] == 0x0a) /* line feed (\n) */
|
||||
while (*message_p != '\0')
|
||||
{
|
||||
printf ("\r"); /* add CR for proper display in serial monitors */
|
||||
if (*message_p == '\n')
|
||||
{
|
||||
/* add CR for proper display in serial monitors */
|
||||
fputc ('\r', stderr);
|
||||
}
|
||||
|
||||
fputc (*message_p++, stderr);
|
||||
}
|
||||
} /* jerry_port_log */
|
||||
|
||||
@ -70,27 +52,28 @@ jerry_port_log (jerry_log_level_t level, /**< log level */
|
||||
*
|
||||
* @return 0
|
||||
*/
|
||||
double
|
||||
jerry_port_get_local_time_zone_adjustment (double unix_ms, bool is_utc)
|
||||
int32_t
|
||||
jerry_port_local_tza (double unix_ms)
|
||||
{
|
||||
/* We live in UTC. */
|
||||
(void) unix_ms;
|
||||
|
||||
return 0;
|
||||
} /* jerry_port_get_local_time_zone_adjustment */
|
||||
} /* jerry_port_local_tza */
|
||||
|
||||
/**
|
||||
* Implementation of jerry_port_get_current_time.
|
||||
* Implementation of jerry_port_current_time.
|
||||
*
|
||||
* @return current timer's counter value in milliseconds
|
||||
*/
|
||||
double
|
||||
jerry_port_get_current_time (void)
|
||||
jerry_port_current_time (void)
|
||||
{
|
||||
static uint64_t last_tick = 0;
|
||||
static time_t last_time = 0;
|
||||
static uint32_t skew = 0;
|
||||
|
||||
uint64_t curr_tick = us_ticker_read (); /* The value is in microseconds. */
|
||||
time_t curr_time = time(NULL); /* The value is in seconds. */
|
||||
time_t curr_time = time (NULL); /* The value is in seconds. */
|
||||
double result = curr_time * 1000;
|
||||
|
||||
/* The us_ticker_read () has an overflow for each UINT_MAX microseconds
|
||||
@ -100,9 +83,12 @@ jerry_port_get_current_time (void)
|
||||
* are within the mentioned 71 mins. Above that interval we can assume
|
||||
* that the milliseconds part of the time is negligibe.
|
||||
*/
|
||||
if (curr_time - last_time > (time_t) (((uint32_t) - 1) / 1000000)) {
|
||||
if (curr_time - last_time > (time_t) (((uint32_t) -1) / 1000000))
|
||||
{
|
||||
skew = 0;
|
||||
} else if (last_tick > curr_tick) {
|
||||
}
|
||||
else if (last_tick > curr_tick)
|
||||
{
|
||||
skew = (skew + 33) % 1000;
|
||||
}
|
||||
result += (curr_tick / 1000 - skew) % 1000;
|
||||
@ -110,14 +96,4 @@ jerry_port_get_current_time (void)
|
||||
last_tick = curr_tick;
|
||||
last_time = curr_time;
|
||||
return result;
|
||||
} /* jerry_port_get_current_time */
|
||||
|
||||
/**
|
||||
* Provide the implementation of jerry_port_print_char.
|
||||
* Uses 'printf' to print a single character to standard output.
|
||||
*/
|
||||
void
|
||||
jerry_port_print_char (char c) /**< the character to print */
|
||||
{
|
||||
printf ("%c", c);
|
||||
} /* jerry_port_print_char */
|
||||
} /* jerry_port_current_time */
|
||||
|
||||
@ -21,8 +21,8 @@ STACKSIZE = $(CONFIG_INTERPRETERS_JERRYSCRIPT_STACKSIZE)
|
||||
|
||||
# Path to the JerryScript and NuttX projects. If not specified, it is
|
||||
# supposed that JerryScript is located next to the nuttx folder.
|
||||
JERRYSCRIPT_ROOT_DIR ?= ../../../../jerryscript
|
||||
NUTTX_ROOT_DIR ?= $(JERRYSCRIPT_ROOT_DIR)/../nuttx
|
||||
JERRYSCRIPT_ROOT_DIR ?= $(abspath ../../../../jerryscript)
|
||||
NUTTX_INCLUDE_DIR ?= $(abspath $(JERRYSCRIPT_ROOT_DIR)/../nuttx/include)
|
||||
|
||||
CFLAGS += -std=c99
|
||||
CFLAGS += -I$(JERRYSCRIPT_ROOT_DIR)/jerry-core/include
|
||||
@ -30,11 +30,11 @@ CFLAGS += -I$(JERRYSCRIPT_ROOT_DIR)/jerry-ext/include
|
||||
CFLAGS += -I$(JERRYSCRIPT_ROOT_DIR)/jerry-math/include
|
||||
|
||||
# These libs should be copied from the JerryScript project.
|
||||
LIBS = libjerry-core.a libjerry-ext.a libjerry-math.a
|
||||
LIBS = libjerry-core.a libjerry-ext.a libjerry-math.a libjerry-port.a
|
||||
|
||||
ASRCS = setjmp.S
|
||||
CSRCS = jerry_port.c jerry_module.c
|
||||
MAINSRC = jerry_main.c
|
||||
CSRCS = jerry-port.c
|
||||
MAINSRC = jerry-main.c
|
||||
|
||||
.PHONY: copylibs
|
||||
copylibs:
|
||||
@ -61,7 +61,7 @@ libjerry:
|
||||
--amalgam=ON \
|
||||
--mem-heap=70 \
|
||||
--profile=es.next \
|
||||
--compile-flag="--sysroot=${NUTTX_ROOT_DIR}" \
|
||||
--compile-flag="-I${NUTTX_INCLUDE_DIR}" \
|
||||
--toolchain=$(abspath $(JERRYSCRIPT_ROOT_DIR)/cmake/toolchain_mcu_stm32f4.cmake)
|
||||
|
||||
clean:: cleanlibs
|
||||
|
||||
@ -60,6 +60,7 @@ script-configure-usbnsh:
|
||||
# Configure and build the firmware (NuttX with JerryScript).
|
||||
script: script-add-jerryscript-app script-configure-usbnsh
|
||||
echo 'CONFIG_ARCH_FPU=y' >> ../nuttx/.config
|
||||
echo 'CONFIG_SCHED_ONEXIT=y' >> ../nuttx/.config
|
||||
echo 'CONFIG_INTERPRETERS_JERRYSCRIPT=y'>> ../nuttx/.config
|
||||
PATH=$(LOCAL_INSTALL)/bin:$$PATH $(MAKE) -C ../nuttx olddefconfig
|
||||
PATH=$(LOCAL_INSTALL)/bin:$$PATH $(MAKE) -C ../nuttx
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Loading…
x
Reference in New Issue
Block a user