diff --git a/.clang-format b/.clang-format index f0202bc7e..65de78321 100644 --- a/.clang-format +++ b/.clang-format @@ -44,7 +44,7 @@ IncludeBlocks: Regroup IncludeCategories: - Regex: '' Priority: 0 - - Regex: '<[-.a-z]*>' + - Regex: '<[-./a-z]*>' Priority: 1 - Regex: '"jerryscript[-.a-z]*"' Priority: 2 diff --git a/CMakeLists.txt b/CMakeLists.txt index 044a2de8a..352b20ed2 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -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 diff --git a/docs/01.CONFIGURATION.md b/docs/01.CONFIGURATION.md index aee35fd27..c914d1e75 100644 --- a/docs/01.CONFIGURATION.md +++ b/docs/01.CONFIGURATION.md @@ -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.) diff --git a/docs/02.API-REFERENCE.md b/docs/02.API-REFERENCE.md index be1da0a43..10ec7fdfe 100644 --- a/docs/02.API-REFERENCE.md +++ b/docs/02.API-REFERENCE.md @@ -6385,6 +6385,8 @@ jerry_bigint_digit_count (jerry_value_t value) [doctest]: # () ```c +#include + #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 -#include - -#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 diff --git a/docs/03.API-EXAMPLE.md b/docs/03.API-EXAMPLE.md index 87437b617..e8616cc44 100644 --- a/docs/03.API-EXAMPLE.md +++ b/docs/03.API-EXAMPLE.md @@ -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 #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 #include #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 #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); diff --git a/docs/05.PORT-API.md b/docs/05.PORT-API.md index 10eca0a95..4577f598e 100644 --- a/docs/05.PORT-API.md +++ b/docs/05.PORT-API.md @@ -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 -#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 -#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 -#include -#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 -#elif defined (HAVE_UNISTD_H) -#include -#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); ``` diff --git a/docs/07.DEBUGGER.md b/docs/07.DEBUGGER.md index b3552aad7..09c9c582d 100644 --- a/docs/07.DEBUGGER.md +++ b/docs/07.DEBUGGER.md @@ -130,6 +130,8 @@ jerry_debugger_is_connected (void); [doctest]: # (test="link") ```c +#include + #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 (); -} -``` diff --git a/docs/10.EXT-REFERENCE-HANDLER.md b/docs/10.EXT-REFERENCE-HANDLER.md index e1d991fa0..d14daafab 100644 --- a/docs/10.EXT-REFERENCE-HANDLER.md +++ b/docs/10.EXT-REFERENCE-HANDLER.md @@ -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 #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 #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); diff --git a/jerry-core/CMakeLists.txt b/jerry-core/CMakeLists.txt index f1ceee3b8..52c774f1f 100644 --- a/jerry-core/CMakeLists.txt +++ b/jerry-core/CMakeLists.txt @@ -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) diff --git a/jerry-core/api/jerry-debugger-transport.c b/jerry-core/api/jerry-debugger-transport.c index 0d2ec6c94..838f0418c 100644 --- a/jerry-core/api/jerry-debugger-transport.c +++ b/jerry-core/api/jerry-debugger-transport.c @@ -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 */ diff --git a/jerry-core/api/jerry-debugger.c b/jerry-core/api/jerry-debugger.c index 0d52f7a91..caa9548e7 100644 --- a/jerry-core/api/jerry-debugger.c +++ b/jerry-core/api/jerry-debugger.c @@ -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 */ diff --git a/jerry-core/api/jerry-module.c b/jerry-core/api/jerry-module.c new file mode 100644 index 000000000..b262a7c2f --- /dev/null +++ b/jerry-core/api/jerry-module.c @@ -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 +#include + +#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 */ diff --git a/jerry-core/api/jerry-snapshot.c b/jerry-core/api/jerry-snapshot.c index b9ae0b3a5..55e905a4f 100644 --- a/jerry-core/api/jerry-snapshot.c +++ b/jerry-core/api/jerry-snapshot.c @@ -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; diff --git a/jerry-core/api/jerryscript.c b/jerry-core/api/jerryscript.c index 97f527c4e..f559df615 100644 --- a/jerry-core/api/jerryscript.c +++ b/jerry-core/api/jerryscript.c @@ -16,6 +16,7 @@ #include "jerryscript.h" #include +#include #include #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 (); diff --git a/jerry-core/debugger/debugger.h b/jerry-core/debugger/debugger.h index f4469fd3a..55a56ce9a 100644 --- a/jerry-core/debugger/debugger.h +++ b/jerry-core/debugger/debugger.h @@ -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; /** diff --git a/jerry-core/ecma/base/ecma-gc.c b/jerry-core/ecma/base/ecma-gc.c index a91918047..38b48f81b 100644 --- a/jerry-core/ecma/base/ecma-gc.c +++ b/jerry-core/ecma/base/ecma-gc.c @@ -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 { diff --git a/jerry-core/ecma/base/ecma-helpers-string.c b/jerry-core/ecma/base/ecma-helpers-string.c index 69f1e72f1..bc4b43476 100644 --- a/jerry-core/ecma/base/ecma-helpers-string.c +++ b/jerry-core/ecma/base/ecma-helpers-string.c @@ -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 */ diff --git a/jerry-core/ecma/base/ecma-helpers.c b/jerry-core/ecma/base/ecma-helpers.c index 95fd4f489..908c8388a 100644 --- a/jerry-core/ecma/base/ecma-helpers.c +++ b/jerry-core/ecma/base/ecma-helpers.c @@ -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++; diff --git a/jerry-core/ecma/base/ecma-init-finalize.c b/jerry-core/ecma/base/ecma-init-finalize.c index acfb0422d..63801b3a4 100644 --- a/jerry-core/ecma/base/ecma-init-finalize.c +++ b/jerry-core/ecma/base/ecma-init-finalize.c @@ -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); diff --git a/jerry-core/ecma/base/ecma-literal-storage.c b/jerry-core/ecma/base/ecma-literal-storage.c index a6d1b1355..3b97afbdf 100644 --- a/jerry-core/ecma/base/ecma-literal-storage.c +++ b/jerry-core/ecma/base/ecma-literal-storage.c @@ -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. */ diff --git a/jerry-core/ecma/builtin-objects/ecma-builtin-date-prototype.c b/jerry-core/ecma/builtin-objects/ecma-builtin-date-prototype.c index 63d535875..082273e82 100644 --- a/jerry-core/ecma/builtin-objects/ecma-builtin-date-prototype.c +++ b/jerry-core/ecma/builtin-objects/ecma-builtin-date-prototype.c @@ -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; } } diff --git a/jerry-core/ecma/builtin-objects/ecma-builtin-date.c b/jerry-core/ecma/builtin-objects/ecma-builtin-date.c index d1dd4183f..af90c7a13 100644 --- a/jerry-core/ecma/builtin-objects/ecma-builtin-date.c +++ b/jerry-core/ecma/builtin-objects/ecma-builtin-date.c @@ -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 */ /** diff --git a/jerry-core/ecma/builtin-objects/ecma-builtin-helpers-date.c b/jerry-core/ecma/builtin-objects/ecma-builtin-helpers-date.c index f9e697ff8..3387c7184 100644 --- a/jerry-core/ecma/builtin-objects/ecma-builtin-helpers-date.c +++ b/jerry-core/ecma/builtin-objects/ecma-builtin-helpers-date.c @@ -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) { diff --git a/jerry-core/ecma/builtin-objects/ecma-builtin-helpers.h b/jerry-core/ecma/builtin-objects/ecma-builtin-helpers.h index 1cf50c15f..71ae115b3 100644 --- a/jerry-core/ecma/builtin-objects/ecma-builtin-helpers.h +++ b/jerry-core/ecma/builtin-objects/ecma-builtin-helpers.h @@ -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); diff --git a/jerry-core/include/jerryscript-compiler.h b/jerry-core/include/jerryscript-compiler.h index 946a7959b..8ebe6efce 100644 --- a/jerry-core/include/jerryscript-compiler.h +++ b/jerry-core/include/jerryscript-compiler.h @@ -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. */ diff --git a/jerry-core/include/jerryscript-core.h b/jerry-core/include/jerryscript-core.h index 51056d913..b034b1091 100644 --- a/jerry-core/include/jerryscript-core.h +++ b/jerry-core/include/jerryscript-core.h @@ -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 @} */ diff --git a/jerry-core/include/jerryscript-debugger.h b/jerry-core/include/jerryscript-debugger.h index 6d5dec89b..34585982a 100644 --- a/jerry-core/include/jerryscript-debugger.h +++ b/jerry-core/include/jerryscript-debugger.h @@ -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); /** * @} diff --git a/jerry-core/include/jerryscript-port.h b/jerry-core/include/jerryscript-port.h index 91bb3fe39..7317a12b2 100644 --- a/jerry-core/include/jerryscript-port.h +++ b/jerry-core/include/jerryscript-port.h @@ -16,233 +16,301 @@ #ifndef JERRYSCRIPT_PORT_H #define JERRYSCRIPT_PORT_H -#include -#include -#include - #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=@{,@}: */ diff --git a/jerry-core/include/jerryscript-types.h b/jerry-core/include/jerryscript-types.h index 4c12fb437..4f0b98f03 100644 --- a/jerry-core/include/jerryscript-types.h +++ b/jerry-core/include/jerryscript-types.h @@ -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. diff --git a/jerry-core/jcontext/jcontext.h b/jerry-core/jcontext/jcontext.h index e7a1ae891..139526147 100644 --- a/jerry-core/jcontext/jcontext.h +++ b/jerry-core/jcontext/jcontext.h @@ -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 diff --git a/jerry-core/jmem/jmem-heap.c b/jerry-core/jmem/jmem-heap.c index 152909a69..d800376cf 100644 --- a/jerry-core/jmem/jmem-heap.c +++ b/jerry-core/jmem/jmem-heap.c @@ -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 diff --git a/jerry-core/jmem/jmem.h b/jerry-core/jmem/jmem.h index 1fc1a7196..368e611bc 100644 --- a/jerry-core/jmem/jmem.h +++ b/jerry-core/jmem/jmem.h @@ -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) \ { \ diff --git a/jerry-core/jrt/jrt-fatals.c b/jerry-core/jrt/jrt-fatals.c index 36c022773..c2e09488f 100644 --- a/jerry-core/jrt/jrt-fatals.c +++ b/jerry-core/jrt/jrt-fatals.c @@ -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 */ diff --git a/jerry-core/jrt/jrt.h b/jerry-core/jrt/jrt.h index 5dbec73b8..6d4447208 100644 --- a/jerry-core/jrt/jrt.h +++ b/jerry-core/jrt/jrt.h @@ -19,6 +19,7 @@ #include #include +#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 */ diff --git a/jerry-core/libjerry-core.pc.in b/jerry-core/libjerry-core.pc.in index 8b7cd932c..ac29dd253 100644 --- a/jerry-core/libjerry-core.pc.in +++ b/jerry-core/libjerry-core.pc.in @@ -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@ diff --git a/jerry-core/parser/js/js-parser.c b/jerry-core/parser/js/js-parser.c index c290b8782..c9b6fa584 100644 --- a/jerry-core/parser/js/js-parser.c +++ b/jerry-core/parser/js/js-parser.c @@ -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; diff --git a/jerry-core/parser/js/js-scanner.c b/jerry-core/parser/js/js-scanner.c index 2ac7798dd..54909fb9d 100644 --- a/jerry-core/parser/js/js-scanner.c +++ b/jerry-core/parser/js/js-scanner.c @@ -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: diff --git a/jerry-core/vm/opcodes.c b/jerry-core/vm/opcodes.c index 9819f343b..933a724f0 100644 --- a/jerry-core/vm/opcodes.c +++ b/jerry-core/vm/opcodes.c @@ -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), diff --git a/jerry-core/vm/vm.c b/jerry-core/vm/vm.c index 95b5840dd..df7ce69f2 100644 --- a/jerry-core/vm/vm.c +++ b/jerry-core/vm/vm.c @@ -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); } } diff --git a/jerry-debugger/jerry_client_main.py b/jerry-debugger/jerry_client_main.py index e65d0e149..88c1be61e 100644 --- a/jerry-debugger/jerry_client_main.py +++ b/jerry-debugger/jerry_client_main.py @@ -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 diff --git a/jerry-ext/CMakeLists.txt b/jerry-ext/CMakeLists.txt index a697ad781..edfb06262 100644 --- a/jerry-ext/CMakeLists.txt +++ b/jerry-ext/CMakeLists.txt @@ -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}) diff --git a/jerry-ext/common/jext-common.h b/jerry-ext/common/jext-common.h index 345f21f2f..946de890b 100644 --- a/jerry-ext/common/jext-common.h +++ b/jerry-ext/common/jext-common.h @@ -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 */ diff --git a/jerry-ext/debugger/debugger-common.c b/jerry-ext/debugger/debugger-common.c index f7856f8cd..9b03f2239 100644 --- a/jerry-ext/debugger/debugger-common.c +++ b/jerry-ext/debugger/debugger-common.c @@ -13,6 +13,8 @@ * limitations under the License. */ +#include + #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 */ diff --git a/jerry-ext/debugger/debugger-tcp.c b/jerry-ext/debugger/debugger-tcp.c index 8a47daa71..848347055 100644 --- a/jerry-ext/debugger/debugger-tcp.c +++ b/jerry-ext/debugger/debugger-tcp.c @@ -45,11 +45,10 @@ typedef SOCKET jerryx_socket_t; typedef char jerryx_socket_void_t; typedef int jerryx_socket_size_t; #else /* !_WIN32 */ -#include -#include - #include +#include #include +#include /* 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 */ diff --git a/jerry-ext/handler/handler-assert.c b/jerry-ext/handler/handler-assert.c deleted file mode 100644 index 89c5b766d..000000000 --- a/jerry-ext/handler/handler-assert.c +++ /dev/null @@ -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 - -#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 */ diff --git a/jerry-ext/handler/handler-print.c b/jerry-ext/handler/handler-print.c deleted file mode 100644 index c220ba4de..000000000 --- a/jerry-ext/handler/handler-print.c +++ /dev/null @@ -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 */ diff --git a/jerry-ext/handler/handler-source-name.c b/jerry-ext/handler/handler-source-name.c deleted file mode 100644 index 670131136..000000000 --- a/jerry-ext/handler/handler-source-name.c +++ /dev/null @@ -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 - * - "", 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 */ diff --git a/jerry-ext/include/jerryscript-ext/debugger.h b/jerry-ext/include/jerryscript-ext/debugger.h index 6ed847b9e..802570d7a 100644 --- a/jerry-ext/include/jerryscript-ext/debugger.h +++ b/jerry-ext/include/jerryscript-ext/debugger.h @@ -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 */ diff --git a/jerry-ext/include/jerryscript-ext/handlers.h b/jerry-ext/include/jerryscript-ext/handlers.h new file mode 100644 index 000000000..f52022853 --- /dev/null +++ b/jerry-ext/include/jerryscript-ext/handlers.h @@ -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 */ diff --git a/jerry-port/default/include/jerryscript-port-default.h b/jerry-ext/include/jerryscript-ext/print.h similarity index 57% rename from jerry-port/default/include/jerryscript-port-default.h rename to jerry-ext/include/jerryscript-ext/print.h index 4966f6b3a..d4257b6f2 100644 --- a/jerry-port/default/include/jerryscript-port-default.h +++ b/jerry-ext/include/jerryscript-ext/print.h @@ -13,30 +13,22 @@ * limitations under the License. */ -#ifndef JERRYSCRIPT_PORT_DEFAULT_H -#define JERRYSCRIPT_PORT_DEFAULT_H - -#include +#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 */ diff --git a/jerry-ext/include/jerryscript-ext/handler.h b/jerry-ext/include/jerryscript-ext/properties.h similarity index 62% rename from jerry-ext/include/jerryscript-ext/handler.h rename to jerry-ext/include/jerryscript-ext/properties.h index 393586109..3ad644680 100644 --- a/jerry-ext/include/jerryscript-ext/handler.h +++ b/jerry-ext/include/jerryscript-ext/properties.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 */ diff --git a/jerry-ext/include/jerryscript-ext/repl.h b/jerry-ext/include/jerryscript-ext/repl.h new file mode 100644 index 000000000..6d6e62aca --- /dev/null +++ b/jerry-ext/include/jerryscript-ext/repl.h @@ -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 */ diff --git a/jerry-ext/include/jerryscript-ext/sources.h b/jerry-ext/include/jerryscript-ext/sources.h new file mode 100644 index 000000000..e33aa6b9a --- /dev/null +++ b/jerry-ext/include/jerryscript-ext/sources.h @@ -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 */ diff --git a/jerry-ext/include/jerryscript-ext/test262.h b/jerry-ext/include/jerryscript-ext/test262.h new file mode 100644 index 000000000..7a6c4bee9 --- /dev/null +++ b/jerry-ext/include/jerryscript-ext/test262.h @@ -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 */ diff --git a/jerry-ext/util/handlers.c b/jerry-ext/util/handlers.c new file mode 100644 index 000000000..35d5f78a8 --- /dev/null +++ b/jerry-ext/util/handlers.c @@ -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 + * - "", 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 */ diff --git a/jerry-ext/util/print.c b/jerry-ext/util/print.c new file mode 100644 index 000000000..85e9ade68 --- /dev/null +++ b/jerry-ext/util/print.c @@ -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 +#include +#include +#include +#include + +#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 */ diff --git a/jerry-ext/handler/handler-register.c b/jerry-ext/util/properties.c similarity index 53% rename from jerry-ext/handler/handler-register.c rename to jerry-ext/util/properties.c index 687f2547c..58b4085db 100644 --- a/jerry-ext/handler/handler-register.c +++ b/jerry-ext/util/properties.c @@ -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 */ diff --git a/jerry-ext/util/repl.c b/jerry-ext/util/repl.c new file mode 100644 index 000000000..56361fd2e --- /dev/null +++ b/jerry-ext/util/repl.c @@ -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 + +#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 */ diff --git a/jerry-ext/util/sources.c b/jerry-ext/util/sources.c new file mode 100644 index 000000000..30cbe56d1 --- /dev/null +++ b/jerry-ext/util/sources.c @@ -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 +#include +#include +#include + +#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 */ diff --git a/jerry-ext/util/test262.c b/jerry-ext/util/test262.c new file mode 100644 index 000000000..278075d1d --- /dev/null +++ b/jerry-ext/util/test262.c @@ -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 +#include + +#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 */ diff --git a/jerry-main/CMakeLists.txt b/jerry-main/CMakeLists.txt index ccd62f4ec..6f8841e5b 100644 --- a/jerry-main/CMakeLists.txt +++ b/jerry-main/CMakeLists.txt @@ -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() diff --git a/jerry-main/cli.c b/jerry-main/arguments/cli.c similarity index 100% rename from jerry-main/cli.c rename to jerry-main/arguments/cli.c diff --git a/jerry-main/cli.h b/jerry-main/arguments/cli.h similarity index 100% rename from jerry-main/cli.h rename to jerry-main/arguments/cli.h diff --git a/jerry-main/main-options.c b/jerry-main/arguments/options.c similarity index 83% rename from jerry-main/main-options.c rename to jerry-main/arguments/options.c index 99cc29d70..abaa91d8f 100644 --- a/jerry-main/main-options.c +++ b/jerry-main/arguments/options.c @@ -13,17 +13,17 @@ * limitations under the License. */ -#include "main-options.h" +#include "options.h" #include #include #include -#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 */ diff --git a/jerry-main/main-options.h b/jerry-main/arguments/options.h similarity index 87% rename from jerry-main/main-options.h rename to jerry-main/arguments/options.h index 5b0f13c69..a3ef0b315 100644 --- a/jerry-main/main-options.h +++ b/jerry-main/arguments/options.h @@ -16,8 +16,15 @@ #ifndef MAIN_OPTIONS_H #define MAIN_OPTIONS_H +#include #include +/** + * 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 */ diff --git a/jerry-main/main-jerry-test.c b/jerry-main/benchmark/main-benchmark.c similarity index 93% rename from jerry-main/main-jerry-test.c rename to jerry-main/benchmark/main-benchmark.c index bec9b8ba8..0232647cc 100644 --- a/jerry-main/main-jerry-test.c +++ b/jerry-main/benchmark/main-benchmark.c @@ -13,6 +13,7 @@ * limitations under the License. */ +#include #include #include @@ -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; diff --git a/jerry-main/benchmarking.c b/jerry-main/benchmark/stubs.c similarity index 100% rename from jerry-main/benchmarking.c rename to jerry-main/benchmark/stubs.c diff --git a/jerry-main/main-desktop.c b/jerry-main/main-desktop.c new file mode 100644 index 000000000..3c321c967 --- /dev/null +++ b/jerry-main/main-desktop.c @@ -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 +#include +#include +#include + +#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 */ diff --git a/jerry-main/main-jerry.c b/jerry-main/main-jerry.c deleted file mode 100644 index 950f707c3..000000000 --- a/jerry-main/main-jerry.c +++ /dev/null @@ -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 -#include -#include -#include - -#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 */ diff --git a/jerry-main/libfuzzer.c b/jerry-main/main-libfuzzer.c similarity index 100% rename from jerry-main/libfuzzer.c rename to jerry-main/main-libfuzzer.c diff --git a/jerry-main/main-jerry-snapshot.c b/jerry-main/main-snapshot.c similarity index 87% rename from jerry-main/main-jerry-snapshot.c rename to jerry-main/main-snapshot.c index 20fe39a7e..f6c913fe4 100644 --- a/jerry-main/main-jerry-snapshot.c +++ b/jerry-main/main-snapshot.c @@ -14,14 +14,14 @@ */ #include +#include #include #include -#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; diff --git a/jerry-main/main-utils.c b/jerry-main/main-utils.c deleted file mode 100644 index 5f77ac682..000000000 --- a/jerry-main/main-utils.c +++ /dev/null @@ -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 -#include -#include -#include - -#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 */ diff --git a/jerry-main/main-utils.h b/jerry-main/main-utils.h deleted file mode 100644 index 9e6958d4e..000000000 --- a/jerry-main/main-utils.h +++ /dev/null @@ -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 */ diff --git a/jerry-math/CMakeLists.txt b/jerry-math/CMakeLists.txt index 4b5bba49a..4031059d1 100644 --- a/jerry-math/CMakeLists.txt +++ b/jerry-math/CMakeLists.txt @@ -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) diff --git a/jerry-port/default/CMakeLists.txt b/jerry-port/CMakeLists.txt similarity index 53% rename from jerry-port/default/CMakeLists.txt rename to jerry-port/CMakeLists.txt index 17f3d4781..5644c4cf2 100644 --- a/jerry-port/default/CMakeLists.txt +++ b/jerry-port/CMakeLists.txt @@ -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) diff --git a/jerry-port/default/default-external-context.c b/jerry-port/common/jerry-port-context.c similarity index 56% rename from jerry-port/default/default-external-context.c rename to jerry-port/common/jerry-port-context.c index 012cb3e10..2aa65b82b 100644 --- a/jerry-port/default/default-external-context.c +++ b/jerry-port/common/jerry-port-context.c @@ -13,9 +13,14 @@ * limitations under the License. */ -#include "jerryscript-port-default.h" +#include + #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 */ diff --git a/jerry-port/common/jerry-port-fs.c b/jerry-port/common/jerry-port-fs.c new file mode 100644 index 000000000..d3eecce7d --- /dev/null +++ b/jerry-port/common/jerry-port-fs.c @@ -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 +#include +#include + +#include "jerryscript-port.h" + +#if defined(__GLIBC__) || defined(_WIN32) +#include + +#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)) */ diff --git a/jerry-port/common/jerry-port-io.c b/jerry-port/common/jerry-port-io.c new file mode 100644 index 000000000..593d74474 --- /dev/null +++ b/jerry-port/common/jerry-port-io.c @@ -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 +#include +#include + +#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 */ diff --git a/jerry-port/default/default-fatal.c b/jerry-port/common/jerry-port-process.c similarity index 91% rename from jerry-port/default/default-fatal.c rename to jerry-port/common/jerry-port-process.c index 329f253c2..25c6f9027 100644 --- a/jerry-port/default/default-fatal.c +++ b/jerry-port/common/jerry-port-process.c @@ -15,17 +15,16 @@ #include -#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 (); } diff --git a/jerry-port/default/default-date.c b/jerry-port/default/default-date.c deleted file mode 100644 index 09dfb5bec..000000000 --- a/jerry-port/default/default-date.c +++ /dev/null @@ -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 - -#ifdef _WIN32 -#include - -#include -#include -#endif /* _WIN32 */ - -#if defined(__GNUC__) || defined(__clang__) -#include -#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 */ diff --git a/jerry-port/default/default-io.c b/jerry-port/default/default-io.c deleted file mode 100644 index 05788d59a..000000000 --- a/jerry-port/default/default-io.c +++ /dev/null @@ -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 -#include -#include - -#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 */ diff --git a/jerry-port/default/default-module.c b/jerry-port/default/default-module.c deleted file mode 100644 index 7fef0940a..000000000 --- a/jerry-port/default/default-module.c +++ /dev/null @@ -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 -#include -#include -#include - -#include "jerryscript-port-default.h" -#include "jerryscript-port.h" - -#include - -#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 */ diff --git a/jerry-port/default/libjerry-port-default.pc.in b/jerry-port/libjerry-port.pc.in similarity index 79% rename from jerry-port/default/libjerry-port-default.pc.in rename to jerry-port/libjerry-port.pc.in index 7dbf44a68..ad5022b88 100644 --- a/jerry-port/default/libjerry-port-default.pc.in +++ b/jerry-port/libjerry-port.pc.in @@ -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} diff --git a/jerry-port/unix/jerry-port-unix-date.c b/jerry-port/unix/jerry-port-unix-date.c new file mode 100644 index 000000000..2e895ab67 --- /dev/null +++ b/jerry-port/unix/jerry-port-unix-date.c @@ -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 +#include + +/** + * 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__) */ diff --git a/jerry-port/unix/jerry-port-unix-fs.c b/jerry-port/unix/jerry-port-unix-fs.c new file mode 100644 index 000000000..d610a7e29 --- /dev/null +++ b/jerry-port/unix/jerry-port-unix-fs.c @@ -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 +#include + +/** + * 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__) */ diff --git a/jerry-port/default/default-debugger.c b/jerry-port/unix/jerry-port-unix-process.c similarity index 77% rename from jerry-port/default/default-debugger.c rename to jerry-port/unix/jerry-port-unix-process.c index ed3afe5e2..b08caaf24 100644 --- a/jerry-port/default/default-debugger.c +++ b/jerry-port/unix/jerry-port-unix-process.c @@ -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 -#else /* !_WIN32 */ #include -#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__) */ diff --git a/jerry-port/win/jerry-port-win-date.c b/jerry-port/win/jerry-port-win-date.c new file mode 100644 index 000000000..6d82f1514 --- /dev/null +++ b/jerry-port/win/jerry-port-win-date.c @@ -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 + +#include +#include +#include + +#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) */ diff --git a/jerry-port/win/jerry-port-win-fs.c b/jerry-port/win/jerry-port-win-fs.c new file mode 100644 index 000000000..c0f18a9ec --- /dev/null +++ b/jerry-port/win/jerry-port-win-fs.c @@ -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 +#include + +/** + * 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) */ diff --git a/jerry-port/win/jerry-port-win-process.c b/jerry-port/win/jerry-port-win-process.c new file mode 100644 index 000000000..c4949a2bf --- /dev/null +++ b/jerry-port/win/jerry-port-win-process.c @@ -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 + +/** + * 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) */ diff --git a/targets/baremetal-sdk/esp-idf/CMakeLists.txt.example b/targets/baremetal-sdk/esp-idf/CMakeLists.txt.example index e7e9d7c0b..93ee76276 100644 --- a/targets/baremetal-sdk/esp-idf/CMakeLists.txt.example +++ b/targets/baremetal-sdk/esp-idf/CMakeLists.txt.example @@ -1,4 +1,4 @@ -# assumes there is a component with this the following +# assumes there is a component with this the following # - set the JERRY_DIR wherever the jerryscript source code (the include files) is # - a "lib" directory with the 2 libraries below diff --git a/targets/baremetal-sdk/esp-idf/README.md b/targets/baremetal-sdk/esp-idf/README.md index ec29ca60e..7abb45ee1 100644 --- a/targets/baremetal-sdk/esp-idf/README.md +++ b/targets/baremetal-sdk/esp-idf/README.md @@ -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. diff --git a/targets/baremetal-sdk/esp-idf/jerry_module.c b/targets/baremetal-sdk/esp-idf/jerry_module.c deleted file mode 100644 index 6a623d26a..000000000 --- a/targets/baremetal-sdk/esp-idf/jerry_module.c +++ /dev/null @@ -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 -#include -#include -#include - -#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 */ diff --git a/targets/baremetal-sdk/esp-idf/jerry_port.c b/targets/baremetal-sdk/esp-idf/jerry_port.c index 2c0e7b479..6eba60cfe 100644 --- a/targets/baremetal-sdk/esp-idf/jerry_port.c +++ b/targets/baremetal-sdk/esp-idf/jerry_port.c @@ -13,198 +13,68 @@ * limitations under the License. */ -#include -#include #include #include +#include #include #include -#include #include -#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 */ diff --git a/targets/baremetal-sdk/esp8266-rtos-sdk/Makefile.esp8266 b/targets/baremetal-sdk/esp8266-rtos-sdk/Makefile.esp8266 index a2a7277ba..b8eac346b 100644 --- a/targets/baremetal-sdk/esp8266-rtos-sdk/Makefile.esp8266 +++ b/targets/baremetal-sdk/esp8266-rtos-sdk/Makefile.esp8266 @@ -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: diff --git a/targets/baremetal-sdk/esp8266-rtos-sdk/user/jerry_port.c b/targets/baremetal-sdk/esp8266-rtos-sdk/user/jerry_port.c index f4d587697..f88daf68d 100644 --- a/targets/baremetal-sdk/esp8266-rtos-sdk/user/jerry_port.c +++ b/targets/baremetal-sdk/esp8266-rtos-sdk/user/jerry_port.c @@ -13,29 +13,21 @@ * limitations under the License. */ - -#include #include +#include #include -#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 */ diff --git a/targets/baremetal-sdk/esp8266-rtos-sdk/user/jerry_run.c b/targets/baremetal-sdk/esp8266-rtos-sdk/user/jerry_run.c index b3205bac8..b9a43df1a 100644 --- a/targets/baremetal-sdk/esp8266-rtos-sdk/user/jerry_run.c +++ b/targets/baremetal-sdk/esp8266-rtos-sdk/user/jerry_run.c @@ -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); diff --git a/targets/os/mbedos5/.mbedignore b/targets/os/mbedos5/.mbedignore index 0db735b70..233643dc6 100644 --- a/targets/os/mbedos5/.mbedignore +++ b/targets/os/mbedos5/.mbedignore @@ -2,7 +2,6 @@ cmake/* docs/* jerry-main/* jerry-math/* -jerry-port/* targets/* tests/* third-party/* diff --git a/targets/os/mbedos5/jerry-main.cpp b/targets/os/mbedos5/jerry-main.cpp index ee74e9a2f..43ee09b90 100644 --- a/targets/os/mbedos5/jerry-main.cpp +++ b/targets/os/mbedos5/jerry-main.cpp @@ -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; } diff --git a/targets/os/mbedos5/jerry-port.cpp b/targets/os/mbedos5/jerry-port.cpp index 50d9fd3c8..9ba1383c4 100644 --- a/targets/os/mbedos5/jerry-port.cpp +++ b/targets/os/mbedos5/jerry-port.cpp @@ -13,55 +13,37 @@ * limitations under the License. */ -#include #include #include -#include -#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 */ diff --git a/targets/os/nuttx/Makefile b/targets/os/nuttx/Makefile index f0d46272b..c405bd5a6 100644 --- a/targets/os/nuttx/Makefile +++ b/targets/os/nuttx/Makefile @@ -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 diff --git a/targets/os/nuttx/Makefile.travis b/targets/os/nuttx/Makefile.travis index aaa9e61e8..2e55fa8b2 100644 --- a/targets/os/nuttx/Makefile.travis +++ b/targets/os/nuttx/Makefile.travis @@ -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 diff --git a/targets/os/nuttx/README.md b/targets/os/nuttx/README.md index a33be14a9..704ce1024 100644 --- a/targets/os/nuttx/README.md +++ b/targets/os/nuttx/README.md @@ -129,6 +129,7 @@ Note: These options are for the micro-sd card slot of STM32F4-Discovery base-boa * Enable `System Type -> STM32 Peripheral Support -> SDIO` * Enable `RTOS Features -> Work queue support -> High priority (kernel) worker thread` * Enable `RTOS Features -> RTOS hooks -> Custom board late initialization` +* Enable `RTOS Features -> RTOS hooks -> Enable on_exit() API` * Enable `Driver Support -> MMC/SD Driver Support` * Disable `Driver Support -> MMC/SD Driver Support -> MMC/SD write protect pin` * Disable `Driver Support -> MMC/SD Driver Support -> MMC/SD SPI transfer support` @@ -145,6 +146,7 @@ A simpler solution is to append the necessary content to the `.config` configura # Assuming you are in jerry-nuttx folder. cat >> nuttx/.config << EOL CONFIG_ARCH_FPU=y +CONFIG_SCHED_ONEXIT=y CONFIG_INTERPRETERS_JERRYSCRIPT=y CONFIG_INTERPRETERS_JERRYSCRIPT_PRIORITY=100 CONFIG_INTERPRETERS_JERRYSCRIPT_STACKSIZE=16384 diff --git a/targets/os/nuttx/jerry-main.c b/targets/os/nuttx/jerry-main.c new file mode 100644 index 000000000..917aa5301 --- /dev/null +++ b/targets/os/nuttx/jerry-main.c @@ -0,0 +1,238 @@ +/* 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 +#include +#include +#include + +#include "jerryscript-port.h" +#include "jerryscript.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 "setjmp.h" + +/** + * Maximum command line arguments number. + */ +#define JERRY_MAX_COMMAND_LINE_ARGS (16) + +/** + * Standalone Jerry exit codes. + */ +#define JERRY_STANDALONE_EXIT_CODE_OK (0) +#define JERRY_STANDALONE_EXIT_CODE_FAIL (1) + +/** + * Context size of the SYNTAX_ERROR + */ +#define SYNTAX_ERROR_CONTEXT_SIZE 2 + +/** + * Print usage and available options + */ +static void +print_help (char *name) +{ + printf ("Usage: %s [OPTION]... [FILE]...\n" + "\n" + "Options:\n" + " --log-level [0-3]\n" + " --mem-stats\n" + " --mem-stats-separate\n" + " --show-opcodes\n" + " --start-debug-server\n" + " --debug-server-port [port]\n" + "\n", + name); +} /* print_help */ + +/** + * Convert string into unsigned integer + * + * @return converted number + */ +static uint32_t +str_to_uint (const char *num_str_p, /**< string to convert */ + char **out_p) /**< [out] end of the number */ +{ + assert (jerry_feature_enabled (JERRY_FEATURE_ERROR_MESSAGES)); + + uint32_t result = 0; + + while (*num_str_p >= '0' && *num_str_p <= '9') + { + result *= 10; + result += (uint32_t) (*num_str_p - '0'); + num_str_p++; + } + + if (out_p != NULL) + { + *out_p = num_str_p; + } + + return result; +} /* str_to_uint */ + +/** + * 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 */ +{ + jerry_value_t result_val = jerryx_register_global (name_p, handler_p); + + if (jerry_value_is_exception (result_val)) + { + jerry_log (JERRY_LOG_LEVEL_WARNING, "Warning: failed to register '%s' method.", name_p); + } + + jerry_value_free (result_val); +} /* register_js_function */ + +/** + * Main program. + * + * @return 0 if success, error code otherwise + */ +#ifdef CONFIG_BUILD_KERNEL +int +main (int argc, FAR char *argv[]) +#else /* !defined(CONFIG_BUILD_KERNEL) */ +int +jerry_main (int argc, char *argv[]) +#endif /* defined(CONFIG_BUILD_KERNEL) */ +{ + if (argc > JERRY_MAX_COMMAND_LINE_ARGS) + { + jerry_log (JERRY_LOG_LEVEL_ERROR, + "Too many command line arguments. Current maximum is %d\n", + JERRY_MAX_COMMAND_LINE_ARGS); + + return JERRY_STANDALONE_EXIT_CODE_FAIL; + } + + const char *file_names[JERRY_MAX_COMMAND_LINE_ARGS]; + int i; + int files_counter = 0; + bool start_debug_server = false; + uint16_t debug_port = 5001; + + jerry_init_flag_t flags = JERRY_INIT_EMPTY; + + for (i = 1; i < argc; i++) + { + if (!strcmp ("-h", argv[i]) || !strcmp ("--help", argv[i])) + { + print_help (argv[0]); + return JERRY_STANDALONE_EXIT_CODE_OK; + } + else if (!strcmp ("--mem-stats", argv[i])) + { + flags |= JERRY_INIT_MEM_STATS; + jerry_log_set_level (JERRY_LOG_LEVEL_DEBUG); + } + else if (!strcmp ("--show-opcodes", argv[i])) + { + flags |= JERRY_INIT_SHOW_OPCODES | JERRY_INIT_SHOW_REGEXP_OPCODES; + jerry_log_set_level (JERRY_LOG_LEVEL_DEBUG); + } + else if (!strcmp ("--log-level", argv[i])) + { + if (++i < argc && strlen (argv[i]) == 1 && argv[i][0] >= '0' && argv[i][0] <= '3') + { + jerry_log_set_level (argv[i][0] - '0'); + } + else + { + jerry_log (JERRY_LOG_LEVEL_ERROR, "Error: wrong format or invalid argument\n"); + return JERRY_STANDALONE_EXIT_CODE_FAIL; + } + } + else if (!strcmp ("--start-debug-server", argv[i])) + { + start_debug_server = true; + } + else if (!strcmp ("--debug-server-port", argv[i])) + { + if (++i < argc) + { + debug_port = str_to_uint (argv[i], NULL); + } + else + { + jerry_log (JERRY_LOG_LEVEL_ERROR, "Error: wrong format or invalid argument\n"); + return JERRY_STANDALONE_EXIT_CODE_FAIL; + } + } + else + { + file_names[files_counter++] = argv[i]; + } + } + + jerry_init (flags); + + if (start_debug_server) + { + jerryx_debugger_after_connect (jerryx_debugger_tcp_create (debug_port) && jerryx_debugger_ws_create ()); + } + + register_js_function ("assert", jerryx_handler_assert); + register_js_function ("gc", jerryx_handler_gc); + register_js_function ("print", jerryx_handler_print); + + jerry_value_t ret_value = jerry_undefined (); + int ret_code = JERRY_STANDALONE_EXIT_CODE_OK; + + if (files_counter == 0) + { + jerryx_repl ("jerry> "); + } + else + { + for (i = 0; i < files_counter; i++) + { + ret_value = jerryx_source_exec_script (file_names[i]); + if (jerry_value_is_exception (ret_value)) + { + ret_code = JERRY_STANDALONE_EXIT_CODE_FAIL; + jerryx_print_unhandled_exception (ret_value); + break; + } + + jerry_value_free (ret_value); + } + } + + ret_value = jerry_run_jobs (); + + if (jerry_value_is_exception (ret_value)) + { + ret_code = JERRY_STANDALONE_EXIT_CODE_FAIL; + } + + jerry_value_free (ret_value); + jerry_cleanup (); + + return ret_code; +} /* main */ diff --git a/targets/os/nuttx/jerry-port.c b/targets/os/nuttx/jerry-port.c new file mode 100644 index 000000000..c4f65a44a --- /dev/null +++ b/targets/os/nuttx/jerry-port.c @@ -0,0 +1,78 @@ +/* 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 +#include +#include + +#include "jerryscript-port.h" + +/** + * Default implementation of jerry_port_log. Prints log messages to stderr. + */ +void +jerry_port_log (const char *message_p) /**< message */ +{ + (void) message_p; +} /* jerry_port_log */ + +/** + * 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_port_line_read (jerry_size_t *out_size_p) +{ + (void) out_size_p; + return NULL; +} /* jerry_port_line_read */ + +/** + * Aborts the program. + */ +void +jerry_port_fatal (jerry_fatal_code_t code) +{ + exit ((int) code); +} /* jerry_port_fatal */ + +/** + * Dummy function to get the time zone adjustment. + * + * @return 0 + */ +int32_t +jerry_port_local_tza (double unix_ms) +{ + (void) unix_ms; + + /* We live in UTC. */ + return 0; +} /* jerry_port_local_tza */ + +/** + * Dummy function to get the current time. + * + * @return 0 + */ +double +jerry_port_current_time (void) +{ + return 0; +} /* jerry_port_current_time */ diff --git a/targets/os/nuttx/jerry_main.c b/targets/os/nuttx/jerry_main.c deleted file mode 100644 index e4cb83927..000000000 --- a/targets/os/nuttx/jerry_main.c +++ /dev/null @@ -1,450 +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 -#include -#include -#include - -#include "jerryscript-port.h" -#include "jerryscript.h" - -#include "jerryscript-ext/debugger.h" -#include "jerryscript-ext/handler.h" -#include "setjmp.h" - -/** - * Maximum command line arguments number. - */ -#define JERRY_MAX_COMMAND_LINE_ARGS (16) - -/** - * Standalone Jerry exit codes. - */ -#define JERRY_STANDALONE_EXIT_CODE_OK (0) -#define JERRY_STANDALONE_EXIT_CODE_FAIL (1) - -/** - * Context size of the SYNTAX_ERROR - */ -#define SYNTAX_ERROR_CONTEXT_SIZE 2 - -void set_log_level (jerry_log_level_t level); - -/** - * Print usage and available options - */ -static void -print_help (char *name) -{ - printf ("Usage: %s [OPTION]... [FILE]...\n" - "\n" - "Options:\n" - " --log-level [0-3]\n" - " --mem-stats\n" - " --mem-stats-separate\n" - " --show-opcodes\n" - " --start-debug-server\n" - " --debug-server-port [port]\n" - "\n", - name); -} /* print_help */ - -/** - * Read source code into buffer. - * - * Returned value must be freed with jmem_heap_free_block if it's not NULL. - * @return NULL, if read or allocation has failed - * pointer to the allocated memory block, otherwise - */ -static const uint8_t * -read_file (const char *file_name, /**< source code */ - size_t *out_size_p) /**< [out] number of bytes successfully read from source */ -{ - FILE *file = fopen (file_name, "r"); - if (file == NULL) - { - jerry_port_log (JERRY_LOG_LEVEL_ERROR, "Error: cannot open file: %s\n", file_name); - return NULL; - } - - int fseek_status = fseek (file, 0, SEEK_END); - if (fseek_status != 0) - { - jerry_port_log (JERRY_LOG_LEVEL_ERROR, "Failed to seek (error: %d)\n", fseek_status); - fclose (file); - return NULL; - } - - long script_len = ftell (file); - if (script_len < 0) - { - jerry_port_log (JERRY_LOG_LEVEL_ERROR, "Failed to get the file size(error %ld)\n", script_len); - fclose (file); - return NULL; - } - - rewind (file); - - uint8_t *buffer = (uint8_t *) malloc (script_len); - - if (buffer == NULL) - { - jerry_port_log (JERRY_LOG_LEVEL_ERROR, "Out of memory error\n"); - fclose (file); - return NULL; - } - - size_t bytes_read = fread (buffer, 1u, script_len, file); - - if (!bytes_read || bytes_read != script_len) - { - jerry_port_log (JERRY_LOG_LEVEL_ERROR, "Error: failed to read file: %s\n", file_name); - free ((void *) buffer); - - fclose (file); - return NULL; - } - - fclose (file); - - *out_size_p = bytes_read; - return (const uint8_t *) buffer; -} /* read_file */ - -/** - * Convert string into unsigned integer - * - * @return converted number - */ -static uint32_t -str_to_uint (const char *num_str_p, /**< string to convert */ - char **out_p) /**< [out] end of the number */ -{ - assert (jerry_feature_enabled (JERRY_FEATURE_ERROR_MESSAGES)); - - uint32_t result = 0; - - while (*num_str_p >= '0' && *num_str_p <= '9') - { - result *= 10; - result += (uint32_t) (*num_str_p - '0'); - num_str_p++; - } - - if (out_p != NULL) - { - *out_p = num_str_p; - } - - return result; -} /* str_to_uint */ - -/** - * Print error value - */ -static void -print_unhandled_exception (jerry_value_t error_value) /**< error value */ -{ - assert (jerry_value_is_exception (error_value)); - - error_value = jerry_exception_value (error_value, false); - jerry_value_t err_str_val = jerry_value_to_string (error_value); - jerry_char_t err_str_buf[256]; - - jerry_value_free (error_value); - - jerry_size_t sz = jerry_string_to_buffer (err_str_val, JERRY_ENCODING_UTF8, err_str_buf, sizeof (err_str_buf) - 1); - err_str_buf[sz] = '\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 + sz; - uint32_t err_line = 0; - uint32_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 = 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 = str_to_uint ((char *) current_p, (char **) ¤t_p); - - current_p++; - - err_col = str_to_uint ((char *) current_p, NULL); - break; - } - } /* for */ - - if (err_line != 0 && err_col != 0) - { - uint32_t curr_line = 1; - - bool is_printing_context = false; - uint32_t pos = 0; - - /* Temporarily modify the error message, so we can use the path. */ - *path_str_end_p = '\0'; - - size_t source_size; - const jerry_char_t *source_p = read_file (path_str_p, &source_size); - - /* Revert the error message. */ - *path_str_end_p = ':'; - - /* 2. seek and print */ - while (source_p[pos] != '\0') - { - if (source_p[pos] == '\n') - { - curr_line++; - } - - if (err_line < SYNTAX_ERROR_CONTEXT_SIZE - || (err_line >= curr_line && (err_line - curr_line) <= SYNTAX_ERROR_CONTEXT_SIZE)) - { - /* context must be printed */ - is_printing_context = true; - } - - if (curr_line > err_line) - { - break; - } - - if (is_printing_context) - { - jerry_port_log (JERRY_LOG_LEVEL_ERROR, "%c", source_p[pos]); - } - - pos++; - } - - jerry_port_log (JERRY_LOG_LEVEL_ERROR, "\n"); - - while (--err_col) - { - jerry_port_log (JERRY_LOG_LEVEL_ERROR, "~"); - } - - jerry_port_log (JERRY_LOG_LEVEL_ERROR, "^\n"); - } - } - - jerry_port_log (JERRY_LOG_LEVEL_ERROR, "Script Error: %s\n", err_str_buf); - jerry_value_free (err_str_val); -} /* print_unhandled_exception */ - -/** - * 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 */ -{ - 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 */ - -/** - * Main program. - * - * @return 0 if success, error code otherwise - */ -#ifdef CONFIG_BUILD_KERNEL -int -main (int argc, FAR char *argv[]) -#else /* !defined(CONFIG_BUILD_KERNEL) */ -int -jerry_main (int argc, char *argv[]) -#endif /* defined(CONFIG_BUILD_KERNEL) */ -{ - if (argc > JERRY_MAX_COMMAND_LINE_ARGS) - { - jerry_port_log (JERRY_LOG_LEVEL_ERROR, - "Too many command line arguments. Current maximum is %d\n", - JERRY_MAX_COMMAND_LINE_ARGS); - - return JERRY_STANDALONE_EXIT_CODE_FAIL; - } - - const char *file_names[JERRY_MAX_COMMAND_LINE_ARGS]; - int i; - int files_counter = 0; - bool start_debug_server = false; - uint16_t debug_port = 5001; - - jerry_init_flag_t flags = JERRY_INIT_EMPTY; - - for (i = 1; i < argc; i++) - { - if (!strcmp ("-h", argv[i]) || !strcmp ("--help", argv[i])) - { - print_help (argv[0]); - return JERRY_STANDALONE_EXIT_CODE_OK; - } - else if (!strcmp ("--mem-stats", argv[i])) - { - flags |= JERRY_INIT_MEM_STATS; - set_log_level (JERRY_LOG_LEVEL_DEBUG); - } - else if (!strcmp ("--show-opcodes", argv[i])) - { - flags |= JERRY_INIT_SHOW_OPCODES | JERRY_INIT_SHOW_REGEXP_OPCODES; - set_log_level (JERRY_LOG_LEVEL_DEBUG); - } - else if (!strcmp ("--log-level", argv[i])) - { - if (++i < argc && strlen (argv[i]) == 1 && argv[i][0] >= '0' && argv[i][0] <= '3') - { - set_log_level (argv[i][0] - '0'); - } - else - { - jerry_port_log (JERRY_LOG_LEVEL_ERROR, "Error: wrong format or invalid argument\n"); - return JERRY_STANDALONE_EXIT_CODE_FAIL; - } - } - else if (!strcmp ("--start-debug-server", argv[i])) - { - start_debug_server = true; - } - else if (!strcmp ("--debug-server-port", argv[i])) - { - if (++i < argc) - { - debug_port = str_to_uint (argv[i], NULL); - } - else - { - jerry_port_log (JERRY_LOG_LEVEL_ERROR, "Error: wrong format or invalid argument\n"); - return JERRY_STANDALONE_EXIT_CODE_FAIL; - } - } - else - { - file_names[files_counter++] = argv[i]; - } - } - - jerry_init (flags); - - if (start_debug_server) - { - jerryx_debugger_after_connect (jerryx_debugger_tcp_create (debug_port) && jerryx_debugger_ws_create ()); - } - - register_js_function ("assert", jerryx_handler_assert); - register_js_function ("gc", jerryx_handler_gc); - register_js_function ("print", jerryx_handler_print); - - jerry_value_t ret_value = jerry_undefined (); - - if (files_counter == 0) - { - printf ("No input files, running a hello world demo:\n"); - const jerry_char_t script[] = "var str = 'Hello World'; print(str + ' from JerryScript')"; - - ret_value = jerry_parse (script, sizeof (script) - 1, NULL); - - if (!jerry_value_is_exception (ret_value)) - { - ret_value = jerry_run (ret_value); - } - } - else - { - for (i = 0; i < files_counter; i++) - { - size_t source_size; - const jerry_char_t *source_p = read_file (file_names[i], &source_size); - - if (source_p == NULL) - { - jerry_port_log (JERRY_LOG_LEVEL_ERROR, "Source file load error\n"); - return JERRY_STANDALONE_EXIT_CODE_FAIL; - } - - jerry_parse_options_t parse_options; - parse_options.options = JERRY_PARSE_HAS_SOURCE_NAME; - parse_options.source_name = jerry_string_sz (file_names[i]); - - ret_value = jerry_parse (source_p, source_size, &parse_options); - jerry_value_free (parse_options.source_name); - free ((void *) source_p); - - 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); - } - - if (jerry_value_is_exception (ret_value)) - { - print_unhandled_exception (ret_value); - break; - } - - jerry_value_free (ret_value); - ret_value = jerry_undefined (); - } - } - - int ret_code = JERRY_STANDALONE_EXIT_CODE_OK; - - if (jerry_value_is_exception (ret_value)) - { - ret_code = JERRY_STANDALONE_EXIT_CODE_FAIL; - } - - jerry_value_free (ret_value); - - ret_value = jerry_run_jobs (); - - if (jerry_value_is_exception (ret_value)) - { - ret_code = JERRY_STANDALONE_EXIT_CODE_FAIL; - } - - jerry_value_free (ret_value); - jerry_cleanup (); - - return ret_code; -} /* main */ diff --git a/targets/os/nuttx/jerry_module.c b/targets/os/nuttx/jerry_module.c deleted file mode 100644 index 39494d168..000000000 --- a/targets/os/nuttx/jerry_module.c +++ /dev/null @@ -1,294 +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 -#include -#include -#include - -#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 (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 */ diff --git a/targets/os/nuttx/jerry_port.c b/targets/os/nuttx/jerry_port.c deleted file mode 100644 index 6814fbad3..000000000 --- a/targets/os/nuttx/jerry_port.c +++ /dev/null @@ -1,193 +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 -#include -#include -#include - -#include "jerryscript.h" -#include "jerryscript-port.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) -{ - exit (1); -} /* 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 */ -{ - if (level <= jerry_log_level) - { - va_list args; - va_start (args, format); - vfprintf (stderr, format, args); - va_end (args); - } -} /* jerry_port_log */ - -/** - * 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 */ -{ - 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 module"); - return NULL; - } - - size_t bytes_read = fread (buffer_p, 1u, file_size, file_p); - - if (!bytes_read) - { - 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 */ - -/** - * Dummy function to get the time zone adjustment. - * - * @return 0 - */ -double -jerry_port_get_local_time_zone_adjustment (double unix_ms, bool is_utc) -{ - /* We live in UTC. */ - return 0; -} /* jerry_port_get_local_time_zone_adjustment */ - -/** - * Dummy function to get the current time. - * - * @return 0 - */ -double -jerry_port_get_current_time (void) -{ - return 0; -} /* 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 */ - -/** - * Provide implementation of jerry_port_sleep. - */ -void jerry_port_sleep (uint32_t sleep_time) /**< milliseconds to sleep */ -{ - usleep ((useconds_t) sleep_time * 1000); -} /* jerry_port_sleep */ - -/** - * Pointer to the current context. - */ -static jerry_context_t *current_context_p = NULL; - -/** - * Set the current_context_p as the passed pointer. - */ -void -jerry_port_default_set_current_context (jerry_context_t *context_p) /**< points to the created context */ -{ - current_context_p = context_p; -} /* jerry_port_default_set_current_context */ - -/** - * Get the current context. - * - * @return the pointer to the current context - */ -jerry_context_t * -jerry_port_get_current_context (void) -{ - return current_context_p; -} /* jerry_port_get_current_context */ diff --git a/targets/os/riot/Makefile b/targets/os/riot/Makefile index 811041268..dfaebd54c 100644 --- a/targets/os/riot/Makefile +++ b/targets/os/riot/Makefile @@ -44,7 +44,7 @@ INCLUDES += -I$(JERRYDIR)/jerry-ext/include ARCHIVES += $(JERRYDIR)/build/lib/libjerry-core.a ARCHIVES += $(JERRYDIR)/build/lib/libjerry-ext.a -ARCHIVES += $(JERRYDIR)/build/lib/libjerry-port-default.a +ARCHIVES += $(JERRYDIR)/build/lib/libjerry-port.a USEMODULE += shell USEMODULE += shell_commands diff --git a/targets/os/riot/source/main-riotos.c b/targets/os/riot/source/jerry-main.c similarity index 78% rename from targets/os/riot/source/main-riotos.c rename to targets/os/riot/source/jerry-main.c index 9ffd355e8..9ca1583c8 100644 --- a/targets/os/riot/source/main-riotos.c +++ b/targets/os/riot/source/jerry-main.c @@ -20,7 +20,8 @@ #include "jerryscript-port.h" #include "jerryscript.h" -#include "jerryscript-ext/handler.h" +#include "jerryscript-ext/handlers.h" +#include "jerryscript-ext/properties.h" #include "shell.h" /** @@ -29,23 +30,6 @@ #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 */ -{ - jerry_value_t result_val = jerryx_handler_register_global (name_p, handler_p); - - if (jerry_value_is_exception (result_val)) - { - printf ("Warning: failed to register '%s' method.", name_p); - } - - jerry_value_free (result_val); -} /* register_js_function */ - /** * Jerryscript simple test */ @@ -65,7 +49,7 @@ test_jerry (int argc, char **argv) jerry_init (JERRY_INIT_EMPTY); /* 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); @@ -104,7 +88,7 @@ main (void) { double d; unsigned u; - } now = { .d = jerry_port_get_current_time () }; + } now = { .d = jerry_port_current_time () }; srand (now.u); printf ("You are running RIOT on a(n) %s board.\n", RIOT_BOARD); printf ("This board features a(n) %s MCU.\n", RIOT_MCU); diff --git a/jerry-ext/handler/handler-gc.c b/targets/os/riot/source/jerry-port.c similarity index 51% rename from jerry-ext/handler/handler-gc.c rename to targets/os/riot/source/jerry-port.c index e755ea738..bd7192c6f 100644 --- a/jerry-ext/handler/handler-gc.c +++ b/targets/os/riot/source/jerry-port.c @@ -13,23 +13,32 @@ * limitations under the License. */ -#include "jerryscript-ext/handler.h" +#include +#include + +#include "jerryscript-port.h" /** - * Expose garbage collector to scripts. + * Dummy function to get the time zone adjustment. * - * @return undefined. + * @return 0 */ -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 */ +int32_t +jerry_port_local_tza (double unix_ms) { - (void) call_info_p; /* unused */ + (void) unix_ms; - jerry_gc_mode_t mode = - ((args_cnt > 0 && jerry_value_to_boolean (args_p[0])) ? JERRY_GC_PRESSURE_HIGH : JERRY_GC_PRESSURE_LOW); + /* We live in UTC. */ + return 0; +} /* jerry_port_local_tza */ - jerry_heap_gc (mode); - return jerry_undefined (); -} /* jerryx_handler_gc */ +/** + * Dummy function to get the current time. + * + * @return 0 + */ +double +jerry_port_current_time (void) +{ + return 0; +} /* jerry_port_current_time */ diff --git a/targets/os/zephyr/CMakeLists.txt b/targets/os/zephyr/CMakeLists.txt index de3da6b4e..95db09d34 100644 --- a/targets/os/zephyr/CMakeLists.txt +++ b/targets/os/zephyr/CMakeLists.txt @@ -28,18 +28,19 @@ execute_process(COMMAND ${JERRY_BASE}/tools/build.py --amalgam=ON --mem-heap=70 --profile=es.next - --compile-flag=--sysroot=${ZEPHYR_BASE} --toolchain=${JERRY_BASE}/cmake/toolchain_mcu_stm32f4.cmake) # Define library targets add_library(jerry-core STATIC IMPORTED) add_library(jerry-ext STATIC IMPORTED) +add_library(jerry-port STATIC IMPORTED) # Define include directories and archives set_target_properties(jerry-core PROPERTIES IMPORTED_LOCATION ${JERRY_BASE}/build/lib/libjerry-core.a) set_target_properties(jerry-core PROPERTIES INTERFACE_INCLUDE_DIRECTORIES ${JERRY_BASE}/jerry-core/include) set_target_properties(jerry-ext PROPERTIES IMPORTED_LOCATION ${JERRY_BASE}/build/lib/libjerry-ext.a) set_target_properties(jerry-ext PROPERTIES INTERFACE_INCLUDE_DIRECTORIES ${JERRY_BASE}/jerry-ext/include) +set_target_properties(jerry-port PROPERTIES IMPORTED_LOCATION ${JERRY_BASE}/build/lib/libjerry-port.a) -target_sources(app PRIVATE src/main-zephyr.c src/getline-zephyr.c src/jerry-port.c src/jerry-module.c) -target_link_libraries(app PUBLIC jerry-core jerry-ext) +target_sources(app PRIVATE src/jerry-main.c src/getline-zephyr.c src/jerry-port.c) +target_link_libraries(app PUBLIC jerry-core jerry-ext jerry-port) diff --git a/targets/os/zephyr/src/jerry-main.c b/targets/os/zephyr/src/jerry-main.c new file mode 100644 index 000000000..63849d5e2 --- /dev/null +++ b/targets/os/zephyr/src/jerry-main.c @@ -0,0 +1,55 @@ +/* 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 +#include +#include +#include +#include + +#include "jerryscript-port.h" +#include "jerryscript.h" + +#include "getline-zephyr.h" +#include "jerryscript-ext/handlers.h" +#include "jerryscript-ext/properties.h" +#include "jerryscript-ext/repl.h" + +void +main (void) +{ + union + { + double d; + unsigned u; + } now = { .d = jerry_port_current_time () }; + srand (now.u); + + uint32_t zephyr_ver = sys_kernel_version_get (); + printf ("JerryScript build: " __DATE__ " " __TIME__ "\n"); + printf ("JerryScript API %d.%d.%d\n", JERRY_API_MAJOR_VERSION, JERRY_API_MINOR_VERSION, JERRY_API_PATCH_VERSION); + printf ("Zephyr version %d.%d.%d\n", + (int) SYS_KERNEL_VER_MAJOR (zephyr_ver), + (int) SYS_KERNEL_VER_MINOR (zephyr_ver), + (int) SYS_KERNEL_VER_PATCHLEVEL (zephyr_ver)); + + zephyr_getline_init (); + jerry_init (JERRY_INIT_EMPTY); + jerryx_register_global ("print", jerryx_handler_print); + + jerryx_repl ("js> "); + + jerry_cleanup (); +} /* main */ diff --git a/targets/os/zephyr/src/jerry-module.c b/targets/os/zephyr/src/jerry-module.c deleted file mode 100644 index 209e047af..000000000 --- a/targets/os/zephyr/src/jerry-module.c +++ /dev/null @@ -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 -#include -#include -#include - -#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; - - jerry_port_module_t *module_p = jerry_object_get_native_ptr (referrer, &jerry_port_module_native_info); - const jerry_char_t *base_path_p = NULL; - size_t base_path_length = 0; - - 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 */ diff --git a/targets/os/zephyr/src/jerry-port.c b/targets/os/zephyr/src/jerry-port.c index 567782183..de5df897d 100644 --- a/targets/os/zephyr/src/jerry-port.c +++ b/targets/os/zephyr/src/jerry-port.c @@ -13,128 +13,37 @@ * limitations under the License. */ -#include -#include #include +#include +#include +#include #include "jerryscript-port.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 */ +#include "getline-zephyr.h" /** * 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 */ -{ - if (level <= jerry_log_level) - { - va_list args; - va_start (args, format); - vfprintf (stderr, format, args); - va_end (args); - } -} /* jerry_port_log */ - -/** - * 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 */ -{ - 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 module"); - return NULL; - } - - size_t bytes_read = fread (buffer_p, 1u, file_size, file_p); - - if (!bytes_read) - { - 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 */ - /** * 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 */ /** * Dummy function to get the current time. @@ -142,51 +51,38 @@ jerry_port_get_local_time_zone_adjustment (double unix_ms, bool is_utc) * @return 0 */ double -jerry_port_get_current_time (void) +jerry_port_current_time (void) { - int64_t ms = k_uptime_get(); + int64_t ms = k_uptime_get (); return (double) ms; -} /* 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 */ /** * Provide implementation of jerry_port_sleep. */ -void jerry_port_sleep (uint32_t sleep_time) /**< milliseconds to sleep */ +void +jerry_port_sleep (uint32_t sleep_time) /**< milliseconds to sleep */ { k_usleep ((useconds_t) sleep_time * 1000); } /* jerry_port_sleep */ /** - * Pointer to the current context. + * Read line from stdin */ -static jerry_context_t *current_context_p = NULL; +jerry_char_t * +jerry_port_line_read (jerry_size_t *out_size_p) +{ + char *line_p = zephyr_getline (); + + *out_size_p = (jerry_size_t) strlen (line_p); + return (jerry_char_t *) line_p; +} /* jerry_port_line_read */ /** - * Set the current_context_p as the passed pointer. + * Free line, no-op. */ void -jerry_port_default_set_current_context (jerry_context_t *context_p) /**< points to the created context */ +jerry_port_line_free (jerry_char_t *line_p) { - 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 */ + (void) line_p; +} /* jerry_port_line_free */ diff --git a/targets/os/zephyr/src/main-zephyr.c b/targets/os/zephyr/src/main-zephyr.c deleted file mode 100644 index db81a3c2a..000000000 --- a/targets/os/zephyr/src/main-zephyr.c +++ /dev/null @@ -1,120 +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 -#include -#include -#include - -#include "jerryscript-port.h" -#include "jerryscript.h" - -#include "getline-zephyr.h" -#include "jerryscript-ext/handler.h" -#include - -static jerry_value_t print_function; - -/** - * 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 */ -{ - 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 */ - -static int -shell_cmd_handler (char *source_buffer) -{ - jerry_value_t ret_val; - - ret_val = jerry_eval ((jerry_char_t *) source_buffer, strlen (source_buffer), JERRY_PARSE_NO_OPTS); - - if (jerry_value_is_exception (ret_val)) - { - /* User-friendly error messages require at least "cp" JerryScript - profile. Include a message prefix in case "cp_minimal" profile - is used. */ - printf ("Error executing statement: "); - /* Clear error flag, otherwise print call below won't produce any - output. */ - ret_val = jerry_exception_value (ret_val, true); - } - - if (!jerry_value_is_exception (print_function)) - { - jerry_value_t ret_val_print = jerry_call (print_function, jerry_undefined (), &ret_val, 1); - jerry_value_free (ret_val_print); - } - - jerry_value_free (ret_val); - - return 0; -} /* shell_cmd_handler */ - -void -main (void) -{ - union - { - double d; - unsigned u; - } now = { .d = jerry_port_get_current_time () }; - srand (now.u); - uint32_t zephyr_ver = sys_kernel_version_get (); - printf ("JerryScript build: " __DATE__ " " __TIME__ "\n"); - printf ("JerryScript API %d.%d.%d\n", JERRY_API_MAJOR_VERSION, JERRY_API_MINOR_VERSION, JERRY_API_PATCH_VERSION); - printf ("Zephyr version %d.%d.%d\n", - (int) SYS_KERNEL_VER_MAJOR (zephyr_ver), - (int) SYS_KERNEL_VER_MINOR (zephyr_ver), - (int) SYS_KERNEL_VER_PATCHLEVEL (zephyr_ver)); - - zephyr_getline_init (); - jerry_init (JERRY_INIT_EMPTY); - register_js_function ("print", jerryx_handler_print); - jerry_value_t global_obj_val = jerry_current_realm (); - - jerry_value_t print_func_name_val = jerry_string_sz ("print"); - print_function = jerry_object_get (global_obj_val, print_func_name_val); - jerry_value_free (print_func_name_val); - jerry_value_free (global_obj_val); - if (jerry_value_is_exception (print_function)) - { - printf ("Error: could not look up print function, expression results won't be printed\n"); - } - - while (1) - { - char *s; - printf ("js> "); - fflush (stdout); - s = zephyr_getline (); - if (*s) - { - shell_cmd_handler (s); - } - } - - /* As we never retturn from REPL above, don't call jerry_cleanup() here. */ -} /* main */ diff --git a/tests/debugger/client_source.expected b/tests/debugger/client_source.expected index d062652a5..8cd90436c 100644 --- a/tests/debugger/client_source.expected +++ b/tests/debugger/client_source.expected @@ -1,15 +1,15 @@ Connecting to: localhost:5001 Stopped at tests/debugger/client_source.js:15 (jerry-debugger) s -out: client-source-test +client-source-test Stopped at tests/debugger/client_source.js:40 (jerry-debugger) s Stopped at tests/debugger/client_source.js:35 (in test() at line:33, col:1) (jerry-debugger) s -out: function test +function test Stopped at tests/debugger/client_source.js:36 (in test() at line:33, col:1) (jerry-debugger) continue -out: function foo -out: function bar -out: function finish -out: finish: test-foo-bar +function foo +function bar +function finish +finish: test-foo-bar diff --git a/tests/debugger/client_source_multiple.expected b/tests/debugger/client_source_multiple.expected index 76e52b825..c69749c7f 100644 --- a/tests/debugger/client_source_multiple.expected +++ b/tests/debugger/client_source_multiple.expected @@ -1,22 +1,22 @@ Connecting to: localhost:5001 Stopped at tests/debugger/client_source_multiple_2.js:15 (jerry-debugger) n -out: multiple-client-source-test-file-2 +multiple-client-source-test-file-2 Stopped at tests/debugger/client_source_multiple_1.js:15 (jerry-debugger) n -out: multiple-client-source-test-file-1 +multiple-client-source-test-file-1 Stopped at tests/debugger/client_source_multiple_1.js:27 (jerry-debugger) s Stopped at tests/debugger/client_source_multiple_1.js:18 (in foo() at line:17, col:1) (jerry-debugger) s -out: foo +foo Stopped at tests/debugger/client_source_multiple_1.js:19 (in foo() at line:17, col:1) (jerry-debugger) s Stopped at tests/debugger/client_source_multiple_2.js:18 (in bar() at line:17, col:1) (jerry-debugger) s -out: bar +bar Stopped at tests/debugger/client_source_multiple_2.js:19 (in bar() at line:17, col:1) (jerry-debugger) c -out: str-argument: called-from-test-file-1 -out: crossFoo -out: str-argument: called-from-test-file-2 +str-argument: called-from-test-file-1 +crossFoo +str-argument: called-from-test-file-2 diff --git a/tests/debugger/do_abort.expected b/tests/debugger/do_abort.expected index b659d0358..f1a05a99e 100644 --- a/tests/debugger/do_abort.expected +++ b/tests/debugger/do_abort.expected @@ -9,4 +9,4 @@ Stopped at tests/debugger/do_abort.js:20 (in g() at line:19, col:1) (jerry-debugger) s Stopped at tests/debugger/do_abort.js:16 (in f() at line:15, col:1) (jerry-debugger) abort new Error('Fatal error :)') -err: Unhandled exception: Error: Fatal error :) +Unhandled exception: Error: Fatal error :) diff --git a/tests/debugger/do_backtrace.expected b/tests/debugger/do_backtrace.expected index 21b73f509..2d86a7a37 100644 --- a/tests/debugger/do_backtrace.expected +++ b/tests/debugger/do_backtrace.expected @@ -1,7 +1,7 @@ Connecting to: localhost:5001 Stopped at tests/debugger/do_backtrace.js:15 (jerry-debugger) next -out: backtrace-test +backtrace-test Stopped at tests/debugger/do_backtrace.js:28 (jerry-debugger) n Stopped at tests/debugger/do_backtrace.js:37 @@ -10,7 +10,7 @@ Stopped at tests/debugger/do_backtrace.js:40 (jerry-debugger) step Stopped at tests/debugger/do_backtrace.js:32 (in test() at line:30, col:1) (jerry-debugger) next -out: function test +function test Stopped at tests/debugger/do_backtrace.js:33 (in test() at line:30, col:1) (jerry-debugger) s Stopped at tests/debugger/do_backtrace.js:23 (in foo() at line:21, col:1) @@ -36,7 +36,7 @@ Total number of frames: 3 Frame 0: tests/debugger/do_backtrace.js:23 (in foo() at line:21, col:1) Frame 1: tests/debugger/do_backtrace.js:33 (in test() at line:30, col:1) (jerry-debugger) n -out: function foo +function foo Stopped at tests/debugger/do_backtrace.js:24 (in foo() at line:21, col:1) (jerry-debugger) n Stopped at tests/debugger/do_backtrace.js:25 (in foo() at line:21, col:1) @@ -59,4 +59,4 @@ Frame 3: tests/debugger/do_backtrace.js:40 (jerry-debugger) bt 4 3 Error: Start depth needs to be lower than or equal to max depth (jerry-debugger) c -out: function f4 +function f4 diff --git a/tests/debugger/do_break.expected b/tests/debugger/do_break.expected index 07217421e..fd8391ed4 100644 --- a/tests/debugger/do_break.expected +++ b/tests/debugger/do_break.expected @@ -14,8 +14,8 @@ Breakpoint 4 at tests/debugger/do_break.js:45 (in f() at line:43, col:1) 3: tests/debugger/do_break.js:33 (in f() at line:31, col:3) 4: tests/debugger/do_break.js:45 (in f() at line:43, col:1) (jerry-debugger) c -out: break test -out: var cat +break test +var cat Stopped at breakpoint:1 tests/debugger/do_break.js:51 (jerry-debugger) delete 1 Breakpoint 1 deleted @@ -27,6 +27,6 @@ Breakpoint 1 deleted (jerry-debugger) c Stopped at breakpoint:2 tests/debugger/do_break.js:36 (in test() at line:20, col:1) (jerry-debugger) continue -out: function test +function test Stopped at breakpoint:3 tests/debugger/do_break.js:33 (in f() at line:31, col:3) (jerry-debugger) c diff --git a/tests/debugger/do_delete.expected b/tests/debugger/do_delete.expected index 8ce1b6f12..a109c15d5 100644 --- a/tests/debugger/do_delete.expected +++ b/tests/debugger/do_delete.expected @@ -1,7 +1,7 @@ Connecting to: localhost:5001 Stopped at tests/debugger/do_delete.js:15 (jerry-debugger) next -out: delete tests +delete tests Stopped at tests/debugger/do_delete.js:17 (jerry-debugger) b do_delete.js:17 Breakpoint 1 at tests/debugger/do_delete.js:17 diff --git a/tests/debugger/do_display.expected b/tests/debugger/do_display.expected index 5cef2b3c5..41cd52c38 100644 --- a/tests/debugger/do_display.expected +++ b/tests/debugger/do_display.expected @@ -14,7 +14,7 @@ Non-negative integer number expected, 0 turns off this function Stopped at breakpoint:1 tests/debugger/do_display.js:15 (in a() at line:15, col:1) (jerry-debugger) display 2 (jerry-debugger) c -out: hi +hi Stopped at breakpoint:2 tests/debugger/do_display.js:16 (in b() at line:16, col:1) Source: tests/debugger/do_display.js 15 function a() { print("hi"); } @@ -22,7 +22,7 @@ Source: tests/debugger/do_display.js 17 function c() { print("hello"); } (jerry-debugger) display 5435 (jerry-debugger) c -out: welcome +welcome Stopped at breakpoint:3 tests/debugger/do_display.js:17 (in c() at line:17, col:1) Source: tests/debugger/do_display.js 1 // Copyright JS Foundation and other contributors, http://js.foundation @@ -50,7 +50,7 @@ Source: tests/debugger/do_display.js 23 d(); (jerry-debugger) display 0 (jerry-debugger) c -out: hello +hello Stopped at breakpoint:4 tests/debugger/do_display.js:18 (in d() at line:18, col:1) (jerry-debugger) c -out: goodbye +goodbye diff --git a/tests/debugger/do_eval_syntax.expected b/tests/debugger/do_eval_syntax.expected index f078975eb..67100aa01 100644 --- a/tests/debugger/do_eval_syntax.expected +++ b/tests/debugger/do_eval_syntax.expected @@ -5,4 +5,4 @@ Stopped at tests/debugger/do_eval_syntax.js:26 (jerry-debugger) eval loop Uncaught exception: Error (jerry-debugger) c -out: bar function +bar function diff --git a/tests/debugger/do_exception.expected b/tests/debugger/do_exception.expected index 8899b84ef..f5789459c 100644 --- a/tests/debugger/do_exception.expected +++ b/tests/debugger/do_exception.expected @@ -1,7 +1,7 @@ Connecting to: localhost:5001 Stopped at tests/debugger/do_exception.js:15 (jerry-debugger) c -out: exception handler configuration test +exception handler configuration test Exception throw detected (to disable automatic stop type exception 0) Exception hint: TypeError Stopped around tests/debugger/do_exception.js:19 (in foo() at line:17, col:1) diff --git a/tests/debugger/do_finish.expected b/tests/debugger/do_finish.expected index 81c3a1eba..e315a129c 100644 --- a/tests/debugger/do_finish.expected +++ b/tests/debugger/do_finish.expected @@ -1,20 +1,20 @@ Connecting to: localhost:5001 Stopped at tests/debugger/do_finish.js:15 (jerry-debugger) finish -out: finish-test +finish-test Stopped at tests/debugger/do_finish.js:26 (jerry-debugger) finish Stopped at tests/debugger/do_finish.js:18 (in foo() at line:17, col:1) (jerry-debugger) finish -out: foo -out: bar +foo +bar Stopped at tests/debugger/do_finish.js:42 (jerry-debugger) step Stopped at tests/debugger/do_finish.js:29 (in dog() at line:28, col:1) (jerry-debugger) finish -out: *bark* -out: *sit* -out: *bark* +*bark* +*sit* +*bark* Stopped at tests/debugger/do_finish.js:44 (jerry-debugger) continue -out: END: finish-test +END: finish-test diff --git a/tests/debugger/do_next.expected b/tests/debugger/do_next.expected index dbeab2f86..67005735c 100644 --- a/tests/debugger/do_next.expected +++ b/tests/debugger/do_next.expected @@ -1,15 +1,15 @@ Connecting to: localhost:5001 Stopped at tests/debugger/do_next.js:15 (jerry-debugger) next -out: next test +next test Stopped at tests/debugger/do_next.js:28 (jerry-debugger) next -out: Func +Func Stopped at tests/debugger/do_next.js:30 (jerry-debugger) n Stopped at tests/debugger/do_next.js:33 (jerry-debugger) n -out: Func +Func Stopped at tests/debugger/do_next.js:35 (jerry-debugger) next Stopped at tests/debugger/do_next.js:39 diff --git a/tests/debugger/do_pending_breakpoints.expected b/tests/debugger/do_pending_breakpoints.expected index 69faafb28..e2db02ee3 100644 --- a/tests/debugger/do_pending_breakpoints.expected +++ b/tests/debugger/do_pending_breakpoints.expected @@ -9,7 +9,7 @@ No breakpoint found, do you want to add a pending breakpoint? (y or [n]) Pending 1: :1 (pending) 2: f() (pending) (jerry-debugger) c -out: pending-breakpoints +pending-breakpoints Breakpoint 3 at :1 Breakpoint 4 at :3 (in f() at line:2, col:1) Stopped at breakpoint:3 :1 diff --git a/tests/debugger/do_print.expected b/tests/debugger/do_print.expected index c551d6529..1ccba3175 100644 --- a/tests/debugger/do_print.expected +++ b/tests/debugger/do_print.expected @@ -1,112 +1,22 @@ Connecting to: localhost:5001 Stopped at tests/debugger/do_print.js:15 (jerry-debugger) c -out: Hello world! -out: A [ ] 110 null true undefined -out: -out: [A -out: B C -out: D E -out: F -out: G] -out: 1: Az élet gyönyörű. -out: 2: Az élet gyönyörű. -out: 3: Az élet gyönyörű. -out: 4: Az élet gyönyörű. -out: 5: Az élet gyönyörű. -out: 6: Az élet gyönyörű. -out: 7: Az élet gyönyörű. -out: 8: Az élet gyönyörű. -out: 9: Az élet gyönyörű. -out: 10: Az élet gyönyörű. -out: 11: Az élet gyönyörű. -out: 12: Az élet gyönyörű. -out: 13: Az élet gyönyörű. -out: 14: Az élet gyönyörű. -out: 15: Az élet gyönyörű. -out: 16: Az élet gyönyörű. -out: 17: Az élet gyönyörű. -out: 18: Az élet gyönyörű. -out: 19: Az élet gyönyörű. -out: 20: Az élet gyönyörű. -out: 21: Az élet gyönyörű. -out: 22: Az élet gyönyörű. -out: 23: Az élet gyönyörű. -out: 24: Az élet gyönyörű. -out: 25: Az élet gyönyörű. -out: 26: Az élet gyönyörű. -out: 27: Az élet gyönyörű. -out: 28: Az élet gyönyörű. -out: 29: Az élet gyönyörű. -out: 30: Az élet gyönyörű. -out: 31: Az élet gyönyörű. -out: 32: Az élet gyönyörű. -out: 33: Az élet gyönyörű. -out: 34: Az élet gyönyörű. -out: 35: Az élet gyönyörű. -out: 36: Az élet gyönyörű. -out: 37: Az élet gyönyörű. -out: 38: Az élet gyönyörű. -out: 39: Az élet gyönyörű. -out: 40: Az élet gyönyörű. -out: 41: Az élet gyönyörű. -out: 42: Az élet gyönyörű. -out: 43: Az élet gyönyörű. -out: 44: Az élet gyönyörű. -out: 45: Az élet gyönyörű. -out: 46: Az élet gyönyörű. -out: 47: Az élet gyönyörű. -out: 48: Az élet gyönyörű. -out: 49: Az élet gyönyörű. -out: 50: Az élet gyönyörű. -out: 51: Az élet gyönyörű. -out: 52: Az élet gyönyörű. -out: 53: Az élet gyönyörű. -out: 54: Az élet gyönyörű. -out: 55: Az élet gyönyörű. -out: 56: Az élet gyönyörű. -out: 57: Az élet gyönyörű. -out: 58: Az élet gyönyörű. -out: 59: Az élet gyönyörű. -out: 60: Az élet gyönyörű. -out: 61: Az élet gyönyörű. -out: 62: Az élet gyönyörű. -out: 63: Az élet gyönyörű. -out: 64: Az élet gyönyörű. -out: 65: Az élet gyönyörű. -out: 66: Az élet gyönyörű. -out: 67: Az élet gyönyörű. -out: 68: Az élet gyönyörű. -out: 69: Az élet gyönyörű. -out: 70: Az élet gyönyörű. -out: 71: Az élet gyönyörű. -out: 72: Az élet gyönyörű. -out: 73: Az élet gyönyörű. -out: 74: Az élet gyönyörű. -out: 75: Az élet gyönyörű. -out: 76: Az élet gyönyörű. -out: 77: Az élet gyönyörű. -out: 78: Az élet gyönyörű. -out: 79: Az élet gyönyörű. -out: 80: Az élet gyönyörű. -out: 81: Az élet gyönyörű. -out: 82: Az élet gyönyörű. -out: 83: Az élet gyönyörű. -out: 84: Az élet gyönyörű. -out: 85: Az élet gyönyörű. -out: 86: Az élet gyönyörű. -out: 87: Az élet gyönyörű. -out: 88: Az élet gyönyörű. -out: 89: Az élet gyönyörű. -out: 90: Az élet gyönyörű. -out: 91: Az élet gyönyörű. -out: 92: Az élet gyönyörű. -out: 93: Az élet gyönyörű. -out: 94: Az élet gyönyörű. -out: 95: Az élet gyönyörű. -out: 96: Az élet gyönyörű. -out: 97: Az élet gyönyörű. -out: 98: Az élet gyönyörű. -out: 99: Az élet gyönyörű. -out: 100: Az élet gyönyörű. -out: +Hello world! +A [ ] 110 null true undefined + +[A +B C +D E +F +G] +1: Az élet gyönyörű. +2: Az élet gyönyörű. +3: Az élet gyönyörű. +4: Az élet gyönyörű. +5: Az élet gyönyörű. +6: Az élet gyönyörű. +7: Az élet gyönyörű. +8: Az élet gyönyörű. +9: Az élet gyönyörű. +10: Az élet gyönyörű. + diff --git a/tests/debugger/do_print.js b/tests/debugger/do_print.js index 9b7496e4e..8d9ac7dfe 100644 --- a/tests/debugger/do_print.js +++ b/tests/debugger/do_print.js @@ -19,7 +19,7 @@ print("[A\nB", "C\nD", "E\nF\nG]"); var s = ""; -for (i = 1; i <= 100; i++) { +for (i = 1; i <= 10; i++) { /* Translated from hungarian: life is beautiful */ s += i + ": Az élet gyönyörű.\n"; } diff --git a/tests/debugger/do_restart.expected b/tests/debugger/do_restart.expected index b92be8240..84a88feb1 100644 --- a/tests/debugger/do_restart.expected +++ b/tests/debugger/do_restart.expected @@ -3,16 +3,16 @@ Stopped at tests/debugger/do_restart.js:23 (jerry-debugger) n Stopped at tests/debugger/do_restart.js:24 (jerry-debugger) n -out: foo +foo Stopped at tests/debugger/do_restart.js:25 (jerry-debugger) n -out: bar +bar Stopped at tests/debugger/do_restart.js:24 (jerry-debugger) restart Connecting to: localhost:5001 Stopped at tests/debugger/do_restart.js:23 (jerry-debugger) continue -out: foo -out: bar -out: foo -out: bar +foo +bar +foo +bar diff --git a/tests/debugger/do_src.expected b/tests/debugger/do_src.expected index b023ef3cd..6a804485e 100644 --- a/tests/debugger/do_src.expected +++ b/tests/debugger/do_src.expected @@ -5,7 +5,7 @@ Breakpoint 1 at tests/debugger/do_src.js:16 (in f() at line:15, col:1) (jerry-debugger) n Stopped at breakpoint:1 tests/debugger/do_src.js:16 (in f() at line:15, col:1) (jerry-debugger) next -out: F1 +F1 Stopped at tests/debugger/do_src.js:20 (jerry-debugger) s Stopped at :1 @@ -20,4 +20,4 @@ Stopped at :2 (in f() at line:1, col:5) 1 f = function f() { 2 > print('F2') } (jerry-debugger) c -out: F2 +F2 diff --git a/tests/debugger/do_throw.expected b/tests/debugger/do_throw.expected index 39a8b86a1..0adc22f11 100644 --- a/tests/debugger/do_throw.expected +++ b/tests/debugger/do_throw.expected @@ -17,4 +17,4 @@ Stopped at tests/debugger/do_throw.js:34 (jerry-debugger) eval e.message.length 538 (jerry-debugger) throw new Error('Exit') -err: Unhandled exception: Error: Exit +Unhandled exception: Error: Exit diff --git a/tests/debugger/do_throw_adv.expected b/tests/debugger/do_throw_adv.expected index d6176bf52..132210346 100644 --- a/tests/debugger/do_throw_adv.expected +++ b/tests/debugger/do_throw_adv.expected @@ -39,4 +39,4 @@ Exception throw detected (to disable automatic stop type exception 0) Exception hint: 16 Stopped at tests/debugger/do_throw_adv.js:18 (in f() at line:17, col:1) (jerry-debugger) c -err: Unhandled exception: 16 +Unhandled exception: 16 diff --git a/tests/jerry/date-getters.js b/tests/jerry/date-getters.js index ad9cedc9e..e32e7e694 100644 --- a/tests/jerry/date-getters.js +++ b/tests/jerry/date-getters.js @@ -43,7 +43,7 @@ assert (d.getDate() == 9); assert (d.getUTCDate() == 9); assert (d.getDay() == 4); assert (d.getUTCDay() == 4); -assert (d.getHours() == Math.floor(12 - 1.5 + d.getTimezoneOffset() / 60)); +assert (d.getHours() == Math.floor(12 - 1.5 - d.getTimezoneOffset() / 60)); assert (d.getUTCHours() == Math.floor(12 - 1.5)); assert (d.getMinutes() == 43); assert (d.getUTCMinutes() == 43); diff --git a/tests/jerry/date-tostring.js b/tests/jerry/date-tostring.js index 7f1913389..8d26bebd2 100644 --- a/tests/jerry/date-tostring.js +++ b/tests/jerry/date-tostring.js @@ -58,8 +58,9 @@ catch (e) assert (new Date (NaN).toTimeString () == "Invalid Date"); assert (new Date (Number.POSITIVE_INFINITY).toString () === "Invalid Date"); -assert (new Date ("2015-02-13").toTimeString () == "00:00:00 GMT+0000"); -assert (new Date ("2015-07-08T11:29:05.023").toTimeString () == "11:29:05 GMT+0000"); +assert (new Date ("2015-02-13").toGMTString () == "Fri, 13 Feb 2015 00:00:00 GMT"); +assert (new Date ("2015-07-08T11:29:05.023+01:00").toGMTString () == "Wed, 08 Jul 2015 10:29:05 GMT"); +assert (new Date ("2015-07-08T11:29:05.023+10:00").toGMTString () == "Wed, 08 Jul 2015 01:29:05 GMT"); try { @@ -72,7 +73,7 @@ catch (e) } assert (new Date ("2015-07-16").toISOString () == "2015-07-16T00:00:00.000Z"); -assert (new Date ("2015-07-16T11:29:05.023").toISOString () == "2015-07-16T11:29:05.023Z"); +assert (new Date ("2015-07-16T11:29:05.023+00:00").toISOString () == "2015-07-16T11:29:05.023Z"); try { @@ -106,7 +107,7 @@ catch (e) assert (new Date (NaN).toUTCString () == "Invalid Date"); assert (new Date ("2015-07-16").toUTCString () == "Thu, 16 Jul 2015 00:00:00 GMT"); -assert (new Date ("2015-07-16T11:29:05.023").toUTCString () == "Thu, 16 Jul 2015 11:29:05 GMT"); +assert (new Date ("2015-07-16T11:29:05.023+00:00").toUTCString () == "Thu, 16 Jul 2015 11:29:05 GMT"); try { @@ -120,7 +121,7 @@ catch (e) assert (new Date (NaN).toJSON () == null); assert (new Date ("2015-07-16").toJSON () == "2015-07-16T00:00:00.000Z"); -assert (new Date ("2015-07-16T11:29:05.023").toJSON () == "2015-07-16T11:29:05.023Z"); +assert (new Date ("2015-07-16T11:29:05.023+00:00").toJSON () == "2015-07-16T11:29:05.023Z"); try { @@ -132,7 +133,7 @@ catch (e) assert (e instanceof TypeError); } -date_time = new Date ("2015-07-08T11:29:05.023").toJSON (); +date_time = new Date ("2015-07-08T11:29:05.023+00:00").toJSON (); assert (new Date (date_time).toISOString () == "2015-07-08T11:29:05.023Z"); assert (typeof Date (2015) == "string"); @@ -145,26 +146,26 @@ assert (new Date ("2015-07-08T11:29:05.023Z").toISOString() == "2015-07-08T11:29 // corner cases assert (new Date (-8640000000000001).toString() == "Invalid Date") -assert (new Date (-8640000000000000).toString() == "Tue Apr 20 -271821 00:00:00 GMT+0000") +assert (new Date (-8640000000000000).toGMTString() == "Tue, 20 Apr -271821 00:00:00 GMT") -assert (new Date(-62167219200001).toString() == "Fri Dec 31 -0001 23:59:59 GMT+0000") -assert (new Date(-62167219200000).toString() == "Sat Jan 01 0000 00:00:00 GMT+0000") +assert (new Date(-62167219200001).toGMTString() == "Fri, 31 Dec -0001 23:59:59 GMT") +assert (new Date(-62167219200000).toGMTString() == "Sat, 01 Jan 0000 00:00:00 GMT") -assert (new Date(-61851600000001).toString() == "Thu Dec 31 0009 23:59:59 GMT+0000") -assert (new Date(-61851600000000).toString() == "Fri Jan 01 0010 00:00:00 GMT+0000") +assert (new Date(-61851600000001).toGMTString() == "Thu, 31 Dec 0009 23:59:59 GMT") +assert (new Date(-61851600000000).toGMTString() == "Fri, 01 Jan 0010 00:00:00 GMT") -assert (new Date(-59011459200001).toString() == "Thu Dec 31 0099 23:59:59 GMT+0000") -assert (new Date(-59011459200000).toString() == "Fri Jan 01 0100 00:00:00 GMT+0000") +assert (new Date(-59011459200001).toGMTString() == "Thu, 31 Dec 0099 23:59:59 GMT") +assert (new Date(-59011459200000).toGMTString() == "Fri, 01 Jan 0100 00:00:00 GMT") -assert (new Date(-30610224000001).toString() == "Tue Dec 31 0999 23:59:59 GMT+0000") -assert (new Date(-30610224000000).toString() == "Wed Jan 01 1000 00:00:00 GMT+0000") +assert (new Date(-30610224000001).toGMTString() == "Tue, 31 Dec 0999 23:59:59 GMT") +assert (new Date(-30610224000000).toGMTString() == "Wed, 01 Jan 1000 00:00:00 GMT") -assert (new Date(-1).toString() == "Wed Dec 31 1969 23:59:59 GMT+0000") -assert (new Date(0).toString() == "Thu Jan 01 1970 00:00:00 GMT+0000") -assert (new Date(1).toString() == "Thu Jan 01 1970 00:00:00 GMT+0000") +assert (new Date(-1).toGMTString() == "Wed, 31 Dec 1969 23:59:59 GMT") +assert (new Date(0).toGMTString() == "Thu, 01 Jan 1970 00:00:00 GMT") +assert (new Date(1).toGMTString() == "Thu, 01 Jan 1970 00:00:00 GMT") -assert (new Date(253402300799999).toString() == "Fri Dec 31 9999 23:59:59 GMT+0000") -assert (new Date(253402300800000).toString() == "Sat Jan 01 10000 00:00:00 GMT+0000") +assert (new Date(253402300799999).toGMTString() == "Fri, 31 Dec 9999 23:59:59 GMT") +assert (new Date(253402300800000).toGMTString() == "Sat, 01 Jan 10000 00:00:00 GMT") -assert (new Date (8640000000000000).toString() == "Sat Sep 13 275760 00:00:00 GMT+0000") -assert (new Date (8640000000000001).toString() == "Invalid Date") +assert (new Date (8640000000000000).toGMTString() == "Sat, 13 Sep 275760 00:00:00 GMT") +assert (new Date (8640000000000001).toGMTString() == "Invalid Date") diff --git a/tests/unit-core/CMakeLists.txt b/tests/unit-core/CMakeLists.txt index bc287a8b0..7ecea3205 100644 --- a/tests/unit-core/CMakeLists.txt +++ b/tests/unit-core/CMakeLists.txt @@ -113,7 +113,7 @@ foreach(SOURCE_UNIT_TEST_MAIN ${SOURCE_UNIT_TEST_MAIN_MODULES}) target_include_directories(${TARGET_NAME} PRIVATE ${INCLUDE_CORE_PRIVATE}) set_property(TARGET ${TARGET_NAME} PROPERTY LINK_FLAGS "${LINKER_FLAGS_COMMON}") set_property(TARGET ${TARGET_NAME} PROPERTY RUNTIME_OUTPUT_DIRECTORY "${CMAKE_BINARY_DIR}/tests") - target_link_libraries(${TARGET_NAME} jerry-core jerry-port-default) + target_link_libraries(${TARGET_NAME} jerry-core jerry-port) add_dependencies(unittests-core ${TARGET_NAME}) endforeach() diff --git a/tests/unit-core/test-api-functiontype.c b/tests/unit-core/test-api-functiontype.c index 2c22b79bc..6792e5a6f 100644 --- a/tests/unit-core/test-api-functiontype.c +++ b/tests/unit-core/test-api-functiontype.c @@ -13,7 +13,6 @@ * limitations under the License. */ -#include "jerryscript-port-default.h" #include "jerryscript-port.h" #include "jerryscript.h" diff --git a/tests/unit-core/test-api-iteratortype.c b/tests/unit-core/test-api-iteratortype.c index 5d0bdfc96..262212ec1 100644 --- a/tests/unit-core/test-api-iteratortype.c +++ b/tests/unit-core/test-api-iteratortype.c @@ -13,7 +13,6 @@ * limitations under the License. */ -#include "jerryscript-port-default.h" #include "jerryscript-port.h" #include "jerryscript.h" diff --git a/tests/unit-core/test-api-object-property-names.c b/tests/unit-core/test-api-object-property-names.c index 5d87aae9a..783b1b528 100644 --- a/tests/unit-core/test-api-object-property-names.c +++ b/tests/unit-core/test-api-object-property-names.c @@ -13,7 +13,6 @@ * limitations under the License. */ -#include "jerryscript-port-default.h" #include "jerryscript-port.h" #include "jerryscript.h" diff --git a/tests/unit-core/test-api-objecttype.c b/tests/unit-core/test-api-objecttype.c index 000179b09..0e35c8fc7 100644 --- a/tests/unit-core/test-api-objecttype.c +++ b/tests/unit-core/test-api-objecttype.c @@ -13,7 +13,6 @@ * limitations under the License. */ -#include "jerryscript-port-default.h" #include "jerryscript-port.h" #include "jerryscript.h" diff --git a/tests/unit-core/test-api-promise.c b/tests/unit-core/test-api-promise.c index 3947250ce..3ad7050e9 100644 --- a/tests/unit-core/test-api-promise.c +++ b/tests/unit-core/test-api-promise.c @@ -13,7 +13,6 @@ * limitations under the License. */ -#include "jerryscript-port-default.h" #include "jerryscript-port.h" #include "jerryscript.h" @@ -184,7 +183,7 @@ main (void) { if (!jerry_feature_enabled (JERRY_FEATURE_PROMISE)) { - jerry_port_log (JERRY_LOG_LEVEL_ERROR, "Promise is disabled!\n"); + jerry_log (JERRY_LOG_LEVEL_ERROR, "Promise is disabled!\n"); return 0; } diff --git a/tests/unit-core/test-api-value-type.c b/tests/unit-core/test-api-value-type.c index 9b2ec7f38..b3b2c82ba 100644 --- a/tests/unit-core/test-api-value-type.c +++ b/tests/unit-core/test-api-value-type.c @@ -13,7 +13,6 @@ * limitations under the License. */ -#include "jerryscript-port-default.h" #include "jerryscript-port.h" #include "jerryscript.h" diff --git a/tests/unit-core/test-arraybuffer.c b/tests/unit-core/test-arraybuffer.c index f6c2bf725..c759d72ef 100644 --- a/tests/unit-core/test-arraybuffer.c +++ b/tests/unit-core/test-arraybuffer.c @@ -13,7 +13,6 @@ * limitations under the License. */ -#include "jerryscript-port-default.h" #include "jerryscript-port.h" #include "jerryscript.h" @@ -207,7 +206,7 @@ main (void) if (!jerry_feature_enabled (JERRY_FEATURE_TYPEDARRAY)) { - jerry_port_log (JERRY_LOG_LEVEL_ERROR, "ArrayBuffer is disabled!\n"); + jerry_log (JERRY_LOG_LEVEL_ERROR, "ArrayBuffer is disabled!\n"); jerry_cleanup (); return 0; } diff --git a/tests/unit-core/test-bigint.c b/tests/unit-core/test-bigint.c index 2f1a6ae58..640da0bd9 100644 --- a/tests/unit-core/test-bigint.c +++ b/tests/unit-core/test-bigint.c @@ -22,7 +22,7 @@ main (void) { if (!jerry_feature_enabled (JERRY_FEATURE_BIGINT)) { - jerry_port_log (JERRY_LOG_LEVEL_ERROR, "Bigint support is disabled!\n"); + jerry_log (JERRY_LOG_LEVEL_ERROR, "Bigint support is disabled!\n"); return 0; } diff --git a/tests/unit-core/test-common.h b/tests/unit-core/test-common.h index 67785c3f0..b6d83491c 100644 --- a/tests/unit-core/test-common.h +++ b/tests/unit-core/test-common.h @@ -27,53 +27,53 @@ #define JERRY_UNUSED(x) ((void) (x)) -#define TEST_ASSERT(x) \ - do \ - { \ - if (JERRY_UNLIKELY (!(x))) \ - { \ - jerry_port_log (JERRY_LOG_LEVEL_ERROR, \ - "TEST: Assertion '%s' failed at %s(%s):%lu.\n", \ - #x, \ - __FILE__, \ - __func__, \ - (unsigned long) __LINE__); \ - jerry_port_fatal (ERR_FAILED_INTERNAL_ASSERTION); \ - } \ +#define TEST_ASSERT(x) \ + do \ + { \ + if (JERRY_UNLIKELY (!(x))) \ + { \ + jerry_log (JERRY_LOG_LEVEL_ERROR, \ + "TEST: Assertion '%s' failed at %s(%s):%lu.\n", \ + #x, \ + __FILE__, \ + __func__, \ + (unsigned long) __LINE__); \ + jerry_port_fatal (JERRY_FATAL_FAILED_ASSERTION); \ + } \ } while (0) -#define TEST_ASSERT_STR(EXPECTED, RESULT) \ - do \ - { \ - const char* __expected = (const char*) (EXPECTED); \ - const char* __result = (const char*) (RESULT); \ - if (strcmp (__expected, __result) != 0) \ - { \ - jerry_port_log (JERRY_LOG_LEVEL_ERROR, \ - "TEST: String comparison failed at %s(%s):%lu.\n" \ - " Expected: '%s'\n Got: '%s'\n", \ - __FILE__, \ - __func__, \ - (unsigned long) __LINE__, \ - __expected, \ - __result); \ - jerry_port_fatal (ERR_FAILED_INTERNAL_ASSERTION); \ - } \ +#define TEST_ASSERT_STR(EXPECTED, RESULT) \ + do \ + { \ + const char* __expected = (const char*) (EXPECTED); \ + const char* __result = (const char*) (RESULT); \ + if (strcmp (__expected, __result) != 0) \ + { \ + jerry_log (JERRY_LOG_LEVEL_ERROR, \ + "TEST: String comparison failed at %s(%s):%lu.\n" \ + " Expected: '%s'\n Got: '%s'\n", \ + __FILE__, \ + __func__, \ + (unsigned long) __LINE__, \ + __expected, \ + __result); \ + jerry_port_fatal (JERRY_FATAL_FAILED_ASSERTION); \ + } \ } while (0) /** * Test initialization statement that should be included * at the beginning of main function in every unit test. */ -#define TEST_INIT() \ - do \ - { \ - union \ - { \ - double d; \ - unsigned u; \ - } now = { .d = jerry_port_get_current_time () }; \ - srand (now.u); \ +#define TEST_INIT() \ + do \ + { \ + union \ + { \ + double d; \ + unsigned u; \ + } now = { .d = jerry_port_current_time () }; \ + srand (now.u); \ } while (0) /** diff --git a/tests/unit-core/test-container-operation.c b/tests/unit-core/test-container-operation.c index fd29ec61d..a641ea91a 100644 --- a/tests/unit-core/test-container-operation.c +++ b/tests/unit-core/test-container-operation.c @@ -25,7 +25,7 @@ main (void) if (!jerry_feature_enabled (JERRY_FEATURE_MAP) || !jerry_feature_enabled (JERRY_FEATURE_SET) || !jerry_feature_enabled (JERRY_FEATURE_WEAKMAP) || !jerry_feature_enabled (JERRY_FEATURE_WEAKSET)) { - jerry_port_log (JERRY_LOG_LEVEL_ERROR, "Containers are disabled!\n"); + jerry_log (JERRY_LOG_LEVEL_ERROR, "Containers are disabled!\n"); jerry_cleanup (); return 0; } diff --git a/tests/unit-core/test-container.c b/tests/unit-core/test-container.c index dffcb1d7c..389a8a6b7 100644 --- a/tests/unit-core/test-container.c +++ b/tests/unit-core/test-container.c @@ -77,7 +77,7 @@ main (void) if (!jerry_feature_enabled (JERRY_FEATURE_MAP) || !jerry_feature_enabled (JERRY_FEATURE_SET) || !jerry_feature_enabled (JERRY_FEATURE_WEAKMAP) || !jerry_feature_enabled (JERRY_FEATURE_WEAKSET)) { - jerry_port_log (JERRY_LOG_LEVEL_ERROR, "Containers are disabled!\n"); + jerry_log (JERRY_LOG_LEVEL_ERROR, "Containers are disabled!\n"); jerry_cleanup (); return 0; } diff --git a/tests/unit-core/test-dataview.c b/tests/unit-core/test-dataview.c index 089bbb9a6..d392bb799 100644 --- a/tests/unit-core/test-dataview.c +++ b/tests/unit-core/test-dataview.c @@ -13,7 +13,6 @@ * limitations under the License. */ -#include "jerryscript-port-default.h" #include "jerryscript-port.h" #include "jerryscript.h" @@ -24,7 +23,7 @@ main (void) { if (!jerry_feature_enabled (JERRY_FEATURE_DATAVIEW)) { - jerry_port_log (JERRY_LOG_LEVEL_ERROR, "DataView support is disabled!\n"); + jerry_log (JERRY_LOG_LEVEL_ERROR, "DataView support is disabled!\n"); return 0; } diff --git a/tests/unit-core/test-internal-properties.c b/tests/unit-core/test-internal-properties.c index 2dee7c5f0..a0010fac1 100644 --- a/tests/unit-core/test-internal-properties.c +++ b/tests/unit-core/test-internal-properties.c @@ -13,7 +13,6 @@ * limitations under the License. */ -#include "jerryscript-port-default.h" #include "jerryscript-port.h" #include "jerryscript.h" diff --git a/tests/unit-core/test-module-dynamic.c b/tests/unit-core/test-module-dynamic.c index 3144f2920..ee99ed3fb 100644 --- a/tests/unit-core/test-module-dynamic.c +++ b/tests/unit-core/test-module-dynamic.c @@ -13,7 +13,6 @@ * limitations under the License. */ -#include "jerryscript-port-default.h" #include "jerryscript-port.h" #include "jerryscript.h" @@ -192,7 +191,7 @@ main (void) if (!jerry_feature_enabled (JERRY_FEATURE_MODULE)) { - jerry_port_log (JERRY_LOG_LEVEL_ERROR, "Module is disabled!\n"); + jerry_log (JERRY_LOG_LEVEL_ERROR, "Module is disabled!\n"); jerry_cleanup (); return 0; } diff --git a/tests/unit-core/test-module-import-meta.c b/tests/unit-core/test-module-import-meta.c index c2804259b..9adaab033 100644 --- a/tests/unit-core/test-module-import-meta.c +++ b/tests/unit-core/test-module-import-meta.c @@ -100,7 +100,7 @@ main (void) if (!jerry_feature_enabled (JERRY_FEATURE_MODULE)) { - jerry_port_log (JERRY_LOG_LEVEL_ERROR, "Module is disabled!\n"); + jerry_log (JERRY_LOG_LEVEL_ERROR, "Module is disabled!\n"); jerry_cleanup (); return 0; } diff --git a/tests/unit-core/test-module.c b/tests/unit-core/test-module.c index f4ffb466d..cd01dd45e 100644 --- a/tests/unit-core/test-module.c +++ b/tests/unit-core/test-module.c @@ -282,7 +282,7 @@ main (void) if (!jerry_feature_enabled (JERRY_FEATURE_MODULE)) { - jerry_port_log (JERRY_LOG_LEVEL_ERROR, "Module is disabled!\n"); + jerry_log (JERRY_LOG_LEVEL_ERROR, "Module is disabled!\n"); jerry_cleanup (); return 0; } diff --git a/tests/unit-core/test-native-callback-nested.c b/tests/unit-core/test-native-callback-nested.c index d891909cb..148a9d1ff 100644 --- a/tests/unit-core/test-native-callback-nested.c +++ b/tests/unit-core/test-native-callback-nested.c @@ -13,7 +13,6 @@ * limitations under the License. */ -#include "jerryscript-port-default.h" #include "jerryscript-port.h" #include "jerryscript.h" @@ -48,18 +47,9 @@ static const jerry_object_native_info_t native_info = { .offset_of_references = 0, }; -static void * -context_alloc_fn (size_t size, void *cb_data) -{ - (void) cb_data; - return malloc (size); -} /* context_alloc_fn */ - int main (void) { - jerry_context_t *ctx_p = jerry_context_alloc (1024, context_alloc_fn, NULL); - jerry_port_default_set_current_context (ctx_p); jerry_init (JERRY_INIT_EMPTY); jerry_value_t obj = jerry_object (); @@ -68,6 +58,5 @@ main (void) jerry_value_free (obj); jerry_cleanup (); - free (ctx_p); return 0; } /* main */ diff --git a/tests/unit-core/test-newtarget.c b/tests/unit-core/test-newtarget.c index e03e02424..031916c88 100644 --- a/tests/unit-core/test-newtarget.c +++ b/tests/unit-core/test-newtarget.c @@ -13,7 +13,6 @@ * limitations under the License. */ -#include "jerryscript-port-default.h" #include "jerryscript-port.h" #include "jerryscript.h" @@ -112,7 +111,7 @@ main (void) /* Test JERRY_FEATURE_SYMBOL feature as it is a must-have in ES.next */ if (!jerry_feature_enabled (JERRY_FEATURE_SYMBOL)) { - jerry_port_log (JERRY_LOG_LEVEL_ERROR, "Skipping test, ES.next support is disabled.\n"); + jerry_log (JERRY_LOG_LEVEL_ERROR, "Skipping test, ES.next support is disabled.\n"); return 0; } diff --git a/tests/unit-core/test-objects-foreach.c b/tests/unit-core/test-objects-foreach.c index 6ad0783d1..d97cfe6da 100644 --- a/tests/unit-core/test-objects-foreach.c +++ b/tests/unit-core/test-objects-foreach.c @@ -44,7 +44,7 @@ test_container (void) /* If there is no Map function this is not an es.next profile build, skip this test case. */ if (type != JERRY_TYPE_FUNCTION) { - jerry_port_log (JERRY_LOG_LEVEL_ERROR, "Container based test is disabled!\n"); + jerry_log (JERRY_LOG_LEVEL_ERROR, "Container based test is disabled!\n"); return; } diff --git a/tests/unit-core/test-promise-callback.c b/tests/unit-core/test-promise-callback.c index f59588aa5..8686cd6f3 100644 --- a/tests/unit-core/test-promise-callback.c +++ b/tests/unit-core/test-promise-callback.c @@ -125,7 +125,7 @@ main (void) if (!jerry_feature_enabled (JERRY_FEATURE_PROMISE)) { - jerry_port_log (JERRY_LOG_LEVEL_ERROR, "Promise is disabled!\n"); + jerry_log (JERRY_LOG_LEVEL_ERROR, "Promise is disabled!\n"); return 0; } diff --git a/tests/unit-core/test-promise.c b/tests/unit-core/test-promise.c index caf9ded06..2800f6e9a 100644 --- a/tests/unit-core/test-promise.c +++ b/tests/unit-core/test-promise.c @@ -13,7 +13,6 @@ * limitations under the License. */ -#include "jerryscript-port-default.h" #include "jerryscript-port.h" #include "jerryscript.h" @@ -110,7 +109,7 @@ main (void) if (!jerry_feature_enabled (JERRY_FEATURE_PROMISE)) { - jerry_port_log (JERRY_LOG_LEVEL_ERROR, "Promise is disabled!\n"); + jerry_log (JERRY_LOG_LEVEL_ERROR, "Promise is disabled!\n"); jerry_cleanup (); return 0; } diff --git a/tests/unit-core/test-regexp-dotall-unicode.c b/tests/unit-core/test-regexp-dotall-unicode.c index 8c5770c0c..1a54aeec8 100644 --- a/tests/unit-core/test-regexp-dotall-unicode.c +++ b/tests/unit-core/test-regexp-dotall-unicode.c @@ -25,7 +25,7 @@ main (void) if (!jerry_feature_enabled (JERRY_FEATURE_SYMBOL)) { - jerry_port_log (JERRY_LOG_LEVEL_ERROR, "ES.next support is disabled\n"); + jerry_log (JERRY_LOG_LEVEL_ERROR, "ES.next support is disabled\n"); jerry_cleanup (); return 0; } diff --git a/tests/unit-core/test-regression-3588.c b/tests/unit-core/test-regression-3588.c index a69a0d8ee..35eb55387 100644 --- a/tests/unit-core/test-regression-3588.c +++ b/tests/unit-core/test-regression-3588.c @@ -13,7 +13,6 @@ * limitations under the License. */ -#include "jerryscript-port-default.h" #include "jerryscript-port.h" #include "jerryscript.h" @@ -41,7 +40,7 @@ main (void) /* Test JERRY_FEATURE_SYMBOL feature as it is a must-have in ES.next */ if (!jerry_feature_enabled (JERRY_FEATURE_SYMBOL)) { - jerry_port_log (JERRY_LOG_LEVEL_ERROR, "Skipping test, ES.next support is disabled.\n"); + jerry_log (JERRY_LOG_LEVEL_ERROR, "Skipping test, ES.next support is disabled.\n"); return 0; } diff --git a/tests/unit-core/test-source-info.c b/tests/unit-core/test-source-info.c index 53100cafd..d664ba996 100644 --- a/tests/unit-core/test-source-info.c +++ b/tests/unit-core/test-source-info.c @@ -40,7 +40,7 @@ main (void) if (!jerry_feature_enabled (JERRY_FEATURE_FUNCTION_TO_STRING)) { - jerry_port_log (JERRY_LOG_LEVEL_ERROR, "Source code is not stored!\n"); + jerry_log (JERRY_LOG_LEVEL_ERROR, "Source code is not stored!\n"); jerry_cleanup (); return 0; } diff --git a/tests/unit-core/test-source-name.c b/tests/unit-core/test-source-name.c index 1bf2542e3..9ecd16bde 100644 --- a/tests/unit-core/test-source-name.c +++ b/tests/unit-core/test-source-name.c @@ -39,7 +39,7 @@ main (void) if (!jerry_feature_enabled (JERRY_FEATURE_LINE_INFO)) { - jerry_port_log (JERRY_LOG_LEVEL_ERROR, "Line info support is disabled!\n"); + jerry_log (JERRY_LOG_LEVEL_ERROR, "Line info support is disabled!\n"); return 0; } diff --git a/tests/unit-core/test-symbol.c b/tests/unit-core/test-symbol.c index 7c351f70b..20b196c20 100644 --- a/tests/unit-core/test-symbol.c +++ b/tests/unit-core/test-symbol.c @@ -13,7 +13,6 @@ * limitations under the License. */ -#include "jerryscript-port-default.h" #include "jerryscript-port.h" #include "jerryscript.h" @@ -36,7 +35,7 @@ main (void) { if (!jerry_feature_enabled (JERRY_FEATURE_SYMBOL)) { - jerry_port_log (JERRY_LOG_LEVEL_ERROR, "Symbol support is disabled!\n"); + jerry_log (JERRY_LOG_LEVEL_ERROR, "Symbol support is disabled!\n"); return 0; } diff --git a/tests/unit-core/test-typedarray.c b/tests/unit-core/test-typedarray.c index 00e8077f6..78535b3e7 100644 --- a/tests/unit-core/test-typedarray.c +++ b/tests/unit-core/test-typedarray.c @@ -15,7 +15,6 @@ #include -#include "jerryscript-port-default.h" #include "jerryscript-port.h" #include "jerryscript.h" @@ -570,7 +569,7 @@ main (void) if (!jerry_feature_enabled (JERRY_FEATURE_TYPEDARRAY)) { - jerry_port_log (JERRY_LOG_LEVEL_ERROR, "TypedArray is disabled!\n"); + jerry_log (JERRY_LOG_LEVEL_ERROR, "TypedArray is disabled!\n"); jerry_cleanup (); return 0; } diff --git a/tests/unit-doc/CMakeLists.txt b/tests/unit-doc/CMakeLists.txt index aa80b0061..63f9355ae 100644 --- a/tests/unit-doc/CMakeLists.txt +++ b/tests/unit-doc/CMakeLists.txt @@ -100,7 +100,7 @@ add_custom_target(all-doc-files DEPENDS ${DOCTEST_COMPILE} ${DOCTEST_LINK} ${DOC if(NOT ("${DOCTEST_COMPILE}" STREQUAL "")) add_library(compile-doc-tests ${DOCTEST_COMPILE}) add_dependencies(compile-doc-tests all-doc-files) - target_link_libraries(compile-doc-tests jerry-ext jerry-core jerry-port-default) + target_link_libraries(compile-doc-tests jerry-ext jerry-core jerry-port) set_property(TARGET compile-doc-tests APPEND_STRING PROPERTY COMPILE_FLAGS "${COMPILE_FLAGS_DOCTEST}") endif() @@ -115,7 +115,7 @@ macro(doctest_add_executables NAME_PREFIX) set_property(TARGET ${TARGET_NAME} APPEND_STRING PROPERTY COMPILE_FLAGS "${COMPILE_FLAGS_DOCTEST}") set_property(TARGET ${TARGET_NAME} PROPERTY LINK_FLAGS "${LINKER_FLAGS_COMMON}") set_property(TARGET ${TARGET_NAME} PROPERTY RUNTIME_OUTPUT_DIRECTORY "${CMAKE_BINARY_DIR}/tests") - target_link_libraries(${TARGET_NAME} jerry-ext jerry-core jerry-port-default) + target_link_libraries(${TARGET_NAME} jerry-ext jerry-core jerry-port) endforeach() endmacro() diff --git a/tests/unit-ext/CMakeLists.txt b/tests/unit-ext/CMakeLists.txt index d048bf736..0b4008b50 100644 --- a/tests/unit-ext/CMakeLists.txt +++ b/tests/unit-ext/CMakeLists.txt @@ -49,7 +49,7 @@ foreach(SOURCE_UNIT_TEST_EXT ${SOURCE_UNIT_TEST_EXT_MODULES}) set_property(TARGET ${TARGET_NAME} PROPERTY LINK_FLAGS "${LINKER_FLAGS_COMMON}") set_property(TARGET ${TARGET_NAME} PROPERTY RUNTIME_OUTPUT_DIRECTORY "${CMAKE_BINARY_DIR}/tests") - target_link_libraries(${TARGET_NAME} jerry-ext jerry-core jerry-port-default) + target_link_libraries(${TARGET_NAME} jerry-ext jerry-core jerry-port) add_dependencies(unittests-ext ${TARGET_NAME}) endforeach() diff --git a/tests/unit-ext/module/CMakeLists.txt b/tests/unit-ext/module/CMakeLists.txt index b9301c1b7..db4fccff4 100644 --- a/tests/unit-ext/module/CMakeLists.txt +++ b/tests/unit-ext/module/CMakeLists.txt @@ -29,5 +29,5 @@ endif() add_executable(${JERRYX_MODULE_UNITTEST_NAME} ${JERRYX_MODULE_UNIT_TEST_SOURCES}) set_property(TARGET ${JERRYX_MODULE_UNITTEST_NAME} PROPERTY LINK_FLAGS "${LINKER_FLAGS_COMMON}") set_property(TARGET ${JERRYX_MODULE_UNITTEST_NAME} PROPERTY RUNTIME_OUTPUT_DIRECTORY "${CMAKE_BINARY_DIR}/tests") -target_link_libraries(${JERRYX_MODULE_UNITTEST_NAME} jerry-ext jerry-core jerry-port-default) +target_link_libraries(${JERRYX_MODULE_UNITTEST_NAME} jerry-ext jerry-core jerry-port) target_include_directories(${JERRYX_MODULE_UNITTEST_NAME} PRIVATE ${INCLUDE_UNIT_EXT}) diff --git a/tests/unit-ext/test-common.h b/tests/unit-ext/test-common.h index b65772c23..5941f4618 100644 --- a/tests/unit-ext/test-common.h +++ b/tests/unit-ext/test-common.h @@ -22,19 +22,19 @@ #define JERRY_UNUSED(x) ((void) (x)) -#define TEST_ASSERT(x) \ - do \ - { \ - if (!(x)) \ - { \ - jerry_port_log (JERRY_LOG_LEVEL_ERROR, \ - "TEST: Assertion '%s' failed at %s(%s):%lu.\n", \ - #x, \ - __FILE__, \ - __func__, \ - (unsigned long) __LINE__); \ - jerry_port_fatal (ERR_FAILED_INTERNAL_ASSERTION); \ - } \ +#define TEST_ASSERT(x) \ + do \ + { \ + if (!(x)) \ + { \ + jerry_log (JERRY_LOG_LEVEL_ERROR, \ + "TEST: Assertion '%s' failed at %s(%s):%lu.\n", \ + #x, \ + __FILE__, \ + __func__, \ + (unsigned long) __LINE__); \ + jerry_port_fatal (JERRY_FATAL_FAILED_ASSERTION); \ + } \ } while (0) #define TEST_STRING_LITERAL(x) x diff --git a/tests/unit-ext/test-ext-method-register.c b/tests/unit-ext/test-ext-method-register.c index 405b4ae6e..566ea9c6c 100644 --- a/tests/unit-ext/test-ext-method-register.c +++ b/tests/unit-ext/test-ext-method-register.c @@ -21,7 +21,7 @@ #include "jerryscript.h" -#include "jerryscript-ext/handler.h" +#include "jerryscript-ext/properties.h" #include "test-common.h" static jerry_value_t @@ -81,7 +81,7 @@ test_simple_registration (void) jerry_value_free (register_result.result); jerry_value_t global_obj = jerry_current_realm (); - jerryx_set_property_str (global_obj, "test", target_object); + jerry_object_set_sz (global_obj, "test", target_object); jerry_value_free (target_object); jerry_value_free (global_obj); @@ -167,7 +167,7 @@ test_error_setvalue (void) freeze_property (global_obj, target_prop); jerry_value_t new_object = jerry_object (); - jerry_value_t set_result = jerryx_set_property_str (global_obj, target_prop, new_object); + jerry_value_t set_result = jerry_object_set_sz (global_obj, target_prop, new_object); TEST_ASSERT (jerry_value_is_exception (set_result)); jerry_value_free (set_result); diff --git a/tools/amalgam.py b/tools/amalgam.py index f84629da8..5fcdfe659 100755 --- a/tools/amalgam.py +++ b/tools/amalgam.py @@ -26,7 +26,7 @@ import shutil ROOT_DIR = os.path.dirname(os.path.dirname(os.path.abspath(__file__))) JERRY_CORE = os.path.join(ROOT_DIR, 'jerry-core') -JERRY_PORT = os.path.join(ROOT_DIR, 'jerry-port', 'default') +JERRY_PORT = os.path.join(ROOT_DIR, 'jerry-port') JERRY_MATH = os.path.join(ROOT_DIR, 'jerry-math') @@ -259,7 +259,6 @@ def amalgamate_jerry_core(output_dir): append_c_files=True, remove_includes=[ 'jerryscript.h', - 'jerryscript-port.h', 'jerryscript-compiler.h', 'jerryscript-core.h', 'jerryscript-debugger.h', @@ -275,6 +274,7 @@ def amalgamate_jerry_core(output_dir): base_dir=JERRY_CORE, input_files=[ os.path.join(JERRY_CORE, 'include', 'jerryscript.h'), + os.path.join(JERRY_CORE, 'include', 'jerryscript-port.h'), os.path.join(JERRY_CORE, 'include', 'jerryscript-debugger-transport.h'), ], output_file=os.path.join(output_dir, 'jerryscript.h'), @@ -286,33 +286,19 @@ def amalgamate_jerry_core(output_dir): os.path.join(output_dir, 'jerryscript-config.h')) -def amalgamate_jerry_port_default(output_dir): +def amalgamate_jerry_port(output_dir): amalgamate( base_dir=JERRY_PORT, - output_file=os.path.join(output_dir, 'jerryscript-port-default.c'), + output_file=os.path.join(output_dir, 'jerryscript-port.c'), append_c_files=True, remove_includes=[ 'jerryscript-port.h', - 'jerryscript-port-default.h', - 'jerryscript-debugger.h', ], extra_includes=[ 'jerryscript.h', - 'jerryscript-port-default.h', ], ) - amalgamate( - base_dir=JERRY_PORT, - input_files=[os.path.join(JERRY_PORT, 'include', 'jerryscript-port-default.h')], - output_file=os.path.join(output_dir, 'jerryscript-port-default.h'), - remove_includes=[ - 'jerryscript-port.h', - 'jerryscript.h', - ], - extra_includes=['jerryscript.h'], - ) - def amalgamate_jerry_math(output_dir): amalgamate( @@ -328,8 +314,8 @@ def main(): parser = argparse.ArgumentParser(description='Generate amalgamated sources.') parser.add_argument('--jerry-core', action='store_true', help='amalgamate jerry-core files') - parser.add_argument('--jerry-port-default', action='store_true', - help='amalgamate jerry-port-default files') + parser.add_argument('--jerry-port', action='store_true', + help='amalgamate jerry-port files') parser.add_argument('--jerry-math', action='store_true', help='amalgamate jerry-math files') parser.add_argument('--output-dir', metavar='DIR', default='amalgam', @@ -350,8 +336,8 @@ def main(): if args.jerry_core: amalgamate_jerry_core(args.output_dir) - if args.jerry_port_default: - amalgamate_jerry_port_default(args.output_dir) + if args.jerry_port: + amalgamate_jerry_port(args.output_dir) if args.jerry_math: amalgamate_jerry_math(args.output_dir) diff --git a/tools/build.py b/tools/build.py index c7b66c520..1a80b8dfb 100755 --- a/tools/build.py +++ b/tools/build.py @@ -104,7 +104,7 @@ def get_arguments(): help='build jerry-ext (%(choices)s)') compgrp.add_argument('--jerry-math', metavar='X', choices=['ON', 'OFF'], type=str.upper, help='build and use jerry-math (%(choices)s)') - compgrp.add_argument('--jerry-port-default', metavar='X', choices=['ON', 'OFF'], type=str.upper, + compgrp.add_argument('--jerry-port', metavar='X', choices=['ON', 'OFF'], type=str.upper, help='build default jerry port implementation (%(choices)s)') compgrp.add_argument('--unittests', metavar='X', choices=['ON', 'OFF'], type=str.upper, help=devhelp('build unittests (%(choices)s)')) @@ -201,7 +201,7 @@ def generate_build_options(arguments): build_options_append('JERRY_LIBFUZZER', arguments.libfuzzer) build_options_append('JERRY_EXT', arguments.jerry_ext) build_options_append('JERRY_MATH', arguments.jerry_math) - build_options_append('JERRY_PORT_DEFAULT', arguments.jerry_port_default) + build_options_append('JERRY_PORT', arguments.jerry_port) build_options_append('UNITTESTS', arguments.unittests) # jerry-core options