Update jerry-port and jerry-ext (#4907)

Notable changes:
  - Updated and the port API interface, new functions have been added
    and some have been changed. The port library is now cleaned up to
    not have any dependency on jerry-core, as it should be. The port library
    is now strictly a collection of functions that implement
    embedding/platform specific behavior.
  - The default port implementation has been split for windows and unix.
    Implemented port functions have been categorized and reorganized,
    and marked with attribute((weak)) for better reusability.
  - External context allocation has been moved to the port API instead
    of a core API callback. The iterface has also been extended with a
    function to free the allocated context. When external context is
    enabled, jerry_init now automatically calls the port implementation
    to allocate the context and jerry_cleanup automatically calls the port
    to free the context.
  - jerry_port_log has been changed to no longer require formatting to
    be implemented by the port. The reason beind this is that it was vague what
    format specifiers were used by the engine, and in what manner. The port
    function now takes a zero-terminated string, and should only implement
    how the string should be logged.
  - Logging and log message formatting is now handled by the core jerry library
    where it can be implemented as necessary. Logging can be done through a new
    core API function, which uses the port to output the final log message.
  - Log level has been moved into jerry-core, and an API function has
    been added to set the log level. It should be the library that
    filters log messages based on the requested log level, instead of
    logging everything and requiring the user to do so.
  - Module resolving logic has been moved into jerry-core. There's no
    reason to have it in the port library and requiring embedders to
    duplicate the code. It also added an unnecessary dependency on
    jerry-core to the port. Platform specific behavior is still used through
    the port API, like resolving module specifiers, and reading source file
    contents. If necessary, the resolving logic can still be overridden as
    previously.
  - The jerry-ext library has also been cleaned up, and many utility
    functions have been added that previously were implemented in
    jerry-main. This allows easier reusability for some common operations,
    like printing unhandled exceptions or providing a repl console.
  - Debugger interaction with logged/printed messages has been fixed, so
    that it's no longer the port implementations responsibility to send
    the output to the debugger, as the port should have no notion of what a
    debugger is.  The printing and logging functions will now pass the
    result message to the debugger, if connected.
  - Cleaned up TZA handling in the date port implementation, and simplified
    the API function prototype.
  - Moved property access helper functions that use ASCII strings as
    keys from jerry-ext to the core API.

JerryScript-DCO-1.0-Signed-off-by: Dániel Bátyai dbatyai@inf.u-szeged.hu
This commit is contained in:
Dániel Bátyai
2022-01-20 13:53:47 +01:00
committed by GitHub
parent 79fd540ec9
commit ac1c48eeff
170 changed files with 4201 additions and 5698 deletions
@@ -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
+1 -1
View File
@@ -1,7 +1,7 @@
This is a port for espressif's esp-idf (esp32). The MATH, LTO and STRIP options should be disabled, so to build under the IDF toolchain, just run the following command
```
python tools\build.py --toolchain=cmake/toolchain-esp32.cmake --cmake-param "-GUnix Makefiles" --jerry-cmdline=OFF --jerry-port-default=OFF --lto=OFF --strip=OFF
python tools\build.py --toolchain=cmake/toolchain-esp32.cmake --cmake-param "-GUnix Makefiles" --jerry-cmdline=OFF --jerry-port=OFF --lto=OFF --strip=OFF
```
NB: the MATH, STRIP and LTO might be disabled by platform as well. I strongly suggest limiting heap memory with '--mem-heap=128' but that really depends on the SRAM available on your esp32.
@@ -1,293 +0,0 @@
/* Copyright JS Foundation and other contributors, http://js.foundation
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include "jerryscript-port.h"
#include "jerryscript.h"
/**
* Computes the end of the directory part of a path.
*
* @return end of the directory part of a path.
*/
static size_t
jerry_port_get_directory_end (const jerry_char_t *path_p) /**< path */
{
const jerry_char_t *end_p = path_p + strlen ((const char *) path_p);
while (end_p > path_p)
{
if (end_p[-1] == '/')
{
return (size_t) (end_p - path_p);
}
end_p--;
}
return 0;
} /* jerry_port_get_directory_end */
/**
* Normalize a file path.
*
* @return a newly allocated buffer with the normalized path if the operation is successful,
* NULL otherwise
*/
static jerry_char_t *
jerry_port_normalize_path (const jerry_char_t *in_path_p, /**< path to the referenced module */
size_t in_path_length, /**< length of the path */
const jerry_char_t *base_path_p, /**< base path */
size_t base_path_length) /**< length of the base path */
{
char *path_p;
if (base_path_length > 0)
{
path_p = (char *) malloc (base_path_length + in_path_length + 1);
if (path_p == NULL)
{
return NULL;
}
memcpy (path_p, base_path_p, base_path_length);
memcpy (path_p + base_path_length, in_path_p, in_path_length);
path_p[base_path_length + in_path_length] = '\0';
}
else
{
path_p = (char *) malloc (in_path_length + 1);
if (path_p == NULL)
{
return NULL;
}
memcpy (path_p, in_path_p, in_path_length);
path_p[in_path_length] = '\0';
}
return (jerry_char_t *) path_p;
} /* jerry_port_normalize_path */
/**
* A module descriptor.
*/
typedef struct jerry_port_module_t
{
struct jerry_port_module_t *next_p; /**< next_module */
jerry_char_t *path_p; /**< path to the module */
size_t base_path_length; /**< base path length for relative difference */
jerry_value_t realm; /**< the realm of the module */
jerry_value_t module; /**< the module itself */
} jerry_port_module_t;
/**
* Native info descriptor for modules.
*/
static const jerry_object_native_info_t jerry_port_module_native_info = {
.free_cb = NULL,
};
/**
* Default module manager.
*/
typedef struct
{
jerry_port_module_t *module_head_p; /**< first module */
} jerry_port_module_manager_t;
/**
* Release known modules.
*/
static void
jerry_port_module_free (jerry_port_module_manager_t *manager_p, /**< module manager */
const jerry_value_t realm) /**< if this argument is object, release only those modules,
* which realm value is equal to this argument. */
{
jerry_port_module_t *module_p = manager_p->module_head_p;
bool release_all = !jerry_value_is_object (realm);
jerry_port_module_t *prev_p = NULL;
while (module_p != NULL)
{
jerry_port_module_t *next_p = module_p->next_p;
if (release_all || module_p->realm == realm)
{
free (module_p->path_p);
jerry_value_free (module_p->realm);
jerry_value_free (module_p->module);
free (module_p);
if (prev_p == NULL)
{
manager_p->module_head_p = next_p;
}
else
{
prev_p->next_p = next_p;
}
}
else
{
prev_p = module_p;
}
module_p = next_p;
}
} /* jerry_port_module_free */
/**
* Initialize the default module manager.
*/
static void
jerry_port_module_manager_init (void *user_data_p)
{
((jerry_port_module_manager_t *) user_data_p)->module_head_p = NULL;
} /* jerry_port_module_manager_init */
/**
* Deinitialize the default module manager.
*/
static void
jerry_port_module_manager_deinit (void *user_data_p) /**< context pointer to deinitialize */
{
jerry_value_t undef = jerry_undefined ();
jerry_port_module_free ((jerry_port_module_manager_t *) user_data_p, undef);
jerry_value_free (undef);
} /* jerry_port_module_manager_deinit */
/**
* Declare the context data manager for modules.
*/
static const jerry_context_data_manager_t jerry_port_module_manager = { .init_cb = jerry_port_module_manager_init,
.deinit_cb = jerry_port_module_manager_deinit,
.bytes_needed =
sizeof (jerry_port_module_manager_t) };
/**
* Default module resolver.
*
* @return a module object if resolving is successful, an error otherwise
*/
jerry_value_t
jerry_port_module_resolve (const jerry_value_t specifier, /**< module specifier string */
const jerry_value_t referrer, /**< parent module */
void *user_p) /**< user data */
{
(void) user_p;
const jerry_char_t *base_path_p = NULL;
size_t base_path_length = 0;
jerry_port_module_t *module_p = jerry_object_get_native_ptr (referrer, &jerry_port_module_native_info);
if (module_p != NULL)
{
base_path_p = module_p->path_p;
base_path_length = module_p->base_path_length;
}
jerry_size_t in_path_length = jerry_string_size (specifier, JERRY_ENCODING_UTF8);
jerry_char_t *in_path_p = (jerry_char_t *) malloc (in_path_length + 1);
jerry_string_to_buffer (specifier, JERRY_ENCODING_UTF8, in_path_p, in_path_length);
in_path_p[in_path_length] = '\0';
jerry_char_t *path_p = jerry_port_normalize_path (in_path_p, in_path_length, base_path_p, base_path_length);
if (path_p == NULL)
{
return jerry_throw_sz (JERRY_ERROR_COMMON, "Out of memory");
}
jerry_value_t realm = jerry_current_realm ();
jerry_port_module_manager_t *manager_p;
manager_p = (jerry_port_module_manager_t *) jerry_context_data (&jerry_port_module_manager);
module_p = manager_p->module_head_p;
while (module_p != NULL)
{
if (module_p->realm == realm && strcmp ((const char *) module_p->path_p, (const char *) path_p) == 0)
{
free (path_p);
free (in_path_p);
jerry_value_free (realm);
return jerry_value_copy (module_p->module);
}
module_p = module_p->next_p;
}
size_t source_size;
uint8_t *source_p = jerry_port_read_source ((const char *) path_p, &source_size);
if (source_p == NULL)
{
free (path_p);
free (in_path_p);
jerry_value_free (realm);
return jerry_throw_sz (JERRY_ERROR_SYNTAX, "Module file not found");
}
jerry_parse_options_t parse_options;
parse_options.options = JERRY_PARSE_MODULE | JERRY_PARSE_HAS_SOURCE_NAME;
parse_options.source_name = jerry_string ((const jerry_char_t *) in_path_p, in_path_length, JERRY_ENCODING_UTF8);
jerry_value_t ret_value = jerry_parse (source_p, source_size, &parse_options);
jerry_value_free (parse_options.source_name);
jerry_port_release_source (source_p);
free (in_path_p);
if (jerry_value_is_exception (ret_value))
{
free (path_p);
jerry_value_free (realm);
return ret_value;
}
module_p = (jerry_port_module_t *) malloc (sizeof (jerry_port_module_t));
module_p->next_p = manager_p->module_head_p;
module_p->path_p = path_p;
module_p->base_path_length = jerry_port_get_directory_end (module_p->path_p);
module_p->realm = realm;
module_p->module = jerry_value_copy (ret_value);
jerry_object_set_native_ptr (ret_value, &jerry_port_module_native_info, module_p);
manager_p->module_head_p = module_p;
return ret_value;
} /* jerry_port_module_resolve */
/**
* Release known modules.
*/
void
jerry_port_module_release (const jerry_value_t realm) /**< if this argument is object, release only those modules,
* which realm value is equal to this argument. */
{
jerry_port_module_free ((jerry_port_module_manager_t *) jerry_context_data (&jerry_port_module_manager), realm);
} /* jerry_port_module_release */
+34 -174
View File
@@ -13,198 +13,68 @@
* limitations under the License.
*/
#include <limits.h>
#include <stdarg.h>
#include <stdlib.h>
#include <string.h>
#include <sys/stat.h>
#include <sys/time.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <unistd.h>
#include "freertos/FreeRTOS.h"
#include "freertos/task.h"
#include "jerryscript-port.h"
#include "jerryscript.h"
#include "esp_log.h"
#include "esp_system.h"
#include "jerryscript.h"
#include "jerryscript-port.h"
#include "freertos/FreeRTOS.h"
#include "freertos/task.h"
static const char TAG[] = "JS";
static esp_log_level_t crosslog(jerry_log_level_t level)
{
switch(level)
{
case JERRY_LOG_LEVEL_ERROR: return ESP_LOG_ERROR;
case JERRY_LOG_LEVEL_WARNING: return ESP_LOG_WARN;
case JERRY_LOG_LEVEL_DEBUG: return ESP_LOG_DEBUG;
case JERRY_LOG_LEVEL_TRACE: return ESP_LOG_VERBOSE;
}
return ESP_LOG_NONE;
}
/**
* Actual log level
*/
static jerry_log_level_t jerry_port_default_log_level = JERRY_LOG_LEVEL_ERROR;
/**
* Get the log level
*
* @return current log level
*/
jerry_log_level_t
jerry_port_default_get_log_level (void)
{
return jerry_port_default_log_level;
} /* jerry_port_default_get_log_level */
/**
* Set the log level
*/
void
jerry_port_default_set_log_level (jerry_log_level_t level) /**< log level */
{
jerry_port_default_log_level = level;
} /* jerry_port_default_set_log_level */
/**
* Default implementation of jerry_port_log. Prints log message to the standard
* error with 'vfprintf' if message log level is less than or equal to the
* current log level.
*
* If debugger support is enabled, printing happens first to an in-memory buffer,
* which is then sent both to the standard error and to the debugger client.
*/
void
jerry_port_log (jerry_log_level_t level, /**< message log level */
const char *format, /**< format string */
...) /**< parameters */
{
if (level <= jerry_port_default_log_level)
{
va_list args;
va_start (args, format);
#if defined (JERRY_DEBUGGER) && (JERRY_DEBUGGER == 1)
int length = vsnprintf (NULL, 0, format, args);
va_end (args);
va_start (args, format);
JERRY_VLA (char, buffer, length + 1);
vsnprintf (buffer, (size_t) length + 1, format, args);
esp_log_write(crosslog(level), TAG, buffer);
jerry_debugger_send_log (level, (jerry_char_t *) buffer, (jerry_size_t) length);
#else /* If jerry-debugger isn't defined, libc is turned on */
esp_log_writev(crosslog(level), TAG, format, args);
#endif /* defined (JERRY_DEBUGGER) && (JERRY_DEBUGGER == 1) */
va_end (args);
}
} /* jerry_port_log */
#if defined (JERRY_DEBUGGER) && (JERRY_DEBUGGER == 1)
#define DEBUG_BUFFER_SIZE (256)
static char debug_buffer[DEBUG_BUFFER_SIZE];
static int debug_buffer_index = 0;
#endif /* defined (JERRY_DEBUGGER) && (JERRY_DEBUGGER == 1) */
/**
* Default implementation of jerry_port_print_char. Uses 'putchar' to
* print a single character to standard output.
*/
void
jerry_port_print_char (char c) /**< the character to print */
{
putchar(c);
#if defined (JERRY_DEBUGGER) && (JERRY_DEBUGGER == 1)
debug_buffer[debug_buffer_index++] = c;
if ((debug_buffer_index == DEBUG_BUFFER_SIZE) || (c == '\n'))
{
jerry_debugger_send_output ((jerry_char_t *) debug_buffer, (jerry_size_t) debug_buffer_index);
debug_buffer_index = 0;
}
#endif /* defined (JERRY_DEBUGGER) && (JERRY_DEBUGGER == 1) */
} /* jerry_port_print_char */
/**
* Default implementation of jerry_port_fatal. Calls 'abort' if exit code is
* non-zero, 'exit' otherwise.
*/
void jerry_port_fatal (jerry_fatal_code_t code) /**< cause of error */
{
ESP_LOGE(TAG, "Fatal error %d", code);
vTaskSuspend(NULL);
abort();
} /* jerry_port_fatal */
/**
* Pointer to the current context.
* Note that it is a global variable, and is not a thread safe implementation.
* But I don't see how jerryscript can make that thread-safe, only the appication can
*/
static jerry_context_t *current_context_p = NULL;
/**
* Set the current_context_p as the passed pointer.
*/
void
jerry_port_default_set_current_context (jerry_context_t *context_p) /**< points to the created context */
jerry_port_fatal (jerry_fatal_code_t code) /**< cause of error */
{
current_context_p = context_p;
} /* jerry_port_default_set_current_context */
/**
* Get the current context.
*
* @return the pointer to the current context
*/
jerry_context_t *
jerry_port_get_current_context (void)
{
return current_context_p;
} /* jerry_port_get_current_context */
ESP_LOGE (TAG, "Fatal error %d", code);
vTaskSuspend (NULL);
abort ();
} /* jerry_port_fatal */
/**
* Default implementation of jerry_port_sleep. Uses 'nanosleep' or 'usleep' if
* available on the system, does nothing otherwise.
*/
void jerry_port_sleep (uint32_t sleep_time) /**< milliseconds to sleep */
void
jerry_port_sleep (uint32_t sleep_time) /**< milliseconds to sleep */
{
vTaskDelay( sleep_time / portTICK_PERIOD_MS);
vTaskDelay (sleep_time / portTICK_PERIOD_MS);
} /* jerry_port_sleep */
/**
* Opens file with the given path and reads its source.
* @return the source of the file
*/
uint8_t *
jerry_port_read_source (const char *file_name_p, /**< file name */
size_t *out_size_p) /**< [out] read bytes */
jerry_char_t *
jerry_port_source_read (const char *file_name_p, /**< file name */
jerry_size_t *out_size_p) /**< [out] read bytes */
{
FILE *file_p = fopen (file_name_p, "rb");
if (file_p == NULL)
{
jerry_port_log (JERRY_LOG_LEVEL_ERROR, "Error: Failed to open file: %s\n", file_name_p);
return NULL;
}
struct stat info = { };
fstat(fileno(file_p), &info);
uint8_t *buffer_p = (uint8_t *) malloc (info.st_size);
struct stat info = {};
fstat (fileno (file_p), &info);
jerry_char_t *buffer_p = (jerry_char_t *) malloc (info.st_size);
if (buffer_p == NULL)
{
fclose (file_p);
jerry_port_log (JERRY_LOG_LEVEL_ERROR, "Error: Failed to allocate memory for file: %s\n", file_name_p);
return NULL;
}
@@ -214,63 +84,54 @@ jerry_port_read_source (const char *file_name_p, /**< file name */
fclose (file_p);
free (buffer_p);
jerry_port_log (JERRY_LOG_LEVEL_ERROR, "Error: Failed to read file: %s\n", file_name_p);
return NULL;
}
fclose (file_p);
*out_size_p = bytes_read;
*out_size_p = (jerry_size_t) bytes_read;
return buffer_p;
} /* jerry_port_read_source */
} /* jerry_port_source_read */
/**
* Release the previously opened file's content.
*/
void
jerry_port_release_source (uint8_t *buffer_p) /**< buffer to free */
jerry_port_source_free (uint8_t *buffer_p) /**< buffer to free */
{
free (buffer_p);
} /* jerry_port_release_source */
} /* jerry_port_source_free */
/**
* Default implementation of jerry_port_get_local_time_zone_adjustment. Uses the 'tm_gmtoff' field
* Default implementation of jerry_port_local_tza. Uses the 'tm_gmtoff' field
* of 'struct tm' (a GNU extension) filled by 'localtime_r' if available on the
* system, does nothing otherwise.
*
* @return offset between UTC and local time at the given unix timestamp, if
* available. Otherwise, returns 0, assuming UTC time.
*/
double jerry_port_get_local_time_zone_adjustment (double unix_ms, /**< ms since unix epoch */
bool is_utc) /**< is the time above in UTC? */
int32_t
jerry_port_local_tza (double unix_ms)
{
struct tm tm;
char buf[8];
time_t now = (time_t) (unix_ms / 1000);
time_t now = (time_t) unix_ms / 1000;
localtime_r (&now, &tm);
if (!is_utc)
{
strftime(buf, 8, "%z", &tm);
now -= -atof(buf) * 3600 * 1000 / 100;
localtime_r (&now, &tm);
}
strftime(buf, 8, "%z", &tm);
return -atof(buf) * 3600 * 1000 / 100;
} /* jerry_port_get_local_time_zone_adjustment */
strftime (buf, 8, "%z", &tm);
return -atoi (buf) * 3600 * 1000 / 100;
} /* jerry_port_local_tza */
/**
* Default implementation of jerry_port_get_current_time. Uses 'gettimeofday' if
* Default implementation of jerry_port_current_time. Uses 'gettimeofday' if
* available on the system, does nothing otherwise.
*
* @return milliseconds since Unix epoch - if 'gettimeofday' is available and
* executed successfully,
* 0 - otherwise.
*/
double jerry_port_get_current_time (void)
double
jerry_port_current_time (void)
{
struct timeval tv;
@@ -279,5 +140,4 @@ double jerry_port_get_current_time (void)
return ((double) tv.tv_sec) * 1000.0 + ((double) tv.tv_usec) / 1000.0;
}
return 0.0;
} /* jerry_port_get_current_time */
} /* jerry_port_current_time */
@@ -56,8 +56,9 @@ jerry:
-DEXTERNAL_COMPILE_FLAGS="$(ESP_CFLAGS)" \
-DJERRY_GLOBAL_HEAP_SIZE=$(JERRYHEAP)
make -C$(BUILD_DIR) jerry-core jerry-math
make -C$(BUILD_DIR) jerry-core jerry-ext jerry-math
cp $(BUILD_DIR)/lib/libjerry-core.a $(COPYTARGET)/
cp $(BUILD_DIR)/lib/libjerry-ext.a $(COPYTARGET)/
cp $(BUILD_DIR)/lib/libjerry-math.a $(COPYTARGET)/
js2c:
@@ -13,29 +13,21 @@
* limitations under the License.
*/
#include <stdio.h>
#include <stdarg.h>
#include <stdio.h>
#include <sys/time.h>
#include "esp_common.h"
#include "jerryscript-port.h"
#include "esp_common.h"
/**
* Provide log message implementation for the engine.
*/
void
jerry_port_log (jerry_log_level_t level, /**< log level */
const char *format, /**< format string */
...) /**< parameters */
jerry_port_log (const char *message_p) /**< message */
{
(void) level; /* ignore log level */
va_list args;
va_start (args, format);
vfprintf (stderr, format, args);
va_end (args);
fputs (message_p, stderr);
} /* jerry_port_log */
/**
@@ -44,30 +36,37 @@ jerry_port_log (jerry_log_level_t level, /**< log level */
void
jerry_port_fatal (jerry_fatal_code_t code)
{
jerry_port_log (JERRY_LOG_LEVEL_ERROR, "Jerry Fatal Error!\n");
while (true);
(void) code;
jerry_port_log ("Jerry Fatal Error!\n");
while (true)
{
}
} /* jerry_port_fatal */
/**
* Implementation of jerry_port_get_current_time.
* Implementation of jerry_port_current_time.
*
* @return current timer's counter value in milliseconds
*/
double
jerry_port_get_current_time (void)
jerry_port_current_time (void)
{
uint32_t rtc_time = system_rtc_clock_cali_proc();
uint32_t rtc_time = system_rtc_clock_cali_proc ();
return (double) rtc_time;
} /* jerry_port_get_current_time */
} /* jerry_port_current_time */
/**
* Dummy function to get the time zone adjustment.
*
* @return 0
*/
double
jerry_port_get_local_time_zone_adjustment (double unix_ms, bool is_utc)
int32_t
jerry_port_local_tza (double unix_ms)
{
(void) unix_ms;
/* We live in UTC. */
return 0;
} /* jerry_port_get_local_time_zone_adjustment */
} /* jerry_port_local_tza */
@@ -32,7 +32,7 @@ js_entry ()
{
double d;
unsigned u;
} now = { .d = jerry_port_get_current_time () };
} now = { .d = jerry_port_current_time () };
srand (now.u);
jerry_init (JERRY_INIT_EMPTY);
-1
View File
@@ -2,7 +2,6 @@ cmake/*
docs/*
jerry-main/*
jerry-math/*
jerry-port/*
targets/*
tests/*
third-party/*
+13 -29
View File
@@ -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;
}
+26 -50
View File
@@ -13,55 +13,37 @@
* limitations under the License.
*/
#include <stdarg.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "jerryscript.h"
#include "jerryscript-port.h"
#include "mbed.h"
/**
* JerryScript log level.
*/
static jerry_log_level_t jerry_log_level = JERRY_LOG_LEVEL_ERROR;
/**
* Sets log level.
*/
void set_log_level (jerry_log_level_t level)
{
jerry_log_level = level;
} /* set_log_level */
/**
* Aborts the program.
*/
void jerry_port_fatal (jerry_fatal_code_t code)
void
jerry_port_fatal (jerry_fatal_code_t code)
{
exit (1);
exit ((int) code);
} /* jerry_port_fatal */
/**
* Provide log message implementation for the engine.
*/
void
jerry_port_log (jerry_log_level_t level, /**< log level */
const char *format, /**< format string */
...) /**< parameters */
jerry_port_log (const char *message_p) /**< message */
{
(void) level; /* ignore log level */
va_list args;
va_start (args, format);
vfprintf (stderr, format, args);
va_end (args);
if (strlen (format) == 1 && format[0] == 0x0a) /* line feed (\n) */
while (*message_p != '\0')
{
printf ("\r"); /* add CR for proper display in serial monitors */
if (*message_p == '\n')
{
/* add CR for proper display in serial monitors */
fputc ('\r', stderr);
}
fputc (*message_p++, stderr);
}
} /* jerry_port_log */
@@ -70,27 +52,28 @@ jerry_port_log (jerry_log_level_t level, /**< log level */
*
* @return 0
*/
double
jerry_port_get_local_time_zone_adjustment (double unix_ms, bool is_utc)
int32_t
jerry_port_local_tza (double unix_ms)
{
/* We live in UTC. */
(void) unix_ms;
return 0;
} /* jerry_port_get_local_time_zone_adjustment */
} /* jerry_port_local_tza */
/**
* Implementation of jerry_port_get_current_time.
* Implementation of jerry_port_current_time.
*
* @return current timer's counter value in milliseconds
*/
double
jerry_port_get_current_time (void)
jerry_port_current_time (void)
{
static uint64_t last_tick = 0;
static time_t last_time = 0;
static uint32_t skew = 0;
uint64_t curr_tick = us_ticker_read (); /* The value is in microseconds. */
time_t curr_time = time(NULL); /* The value is in seconds. */
time_t curr_time = time (NULL); /* The value is in seconds. */
double result = curr_time * 1000;
/* The us_ticker_read () has an overflow for each UINT_MAX microseconds
@@ -100,9 +83,12 @@ jerry_port_get_current_time (void)
* are within the mentioned 71 mins. Above that interval we can assume
* that the milliseconds part of the time is negligibe.
*/
if (curr_time - last_time > (time_t) (((uint32_t) - 1) / 1000000)) {
if (curr_time - last_time > (time_t) (((uint32_t) -1) / 1000000))
{
skew = 0;
} else if (last_tick > curr_tick) {
}
else if (last_tick > curr_tick)
{
skew = (skew + 33) % 1000;
}
result += (curr_tick / 1000 - skew) % 1000;
@@ -110,14 +96,4 @@ jerry_port_get_current_time (void)
last_tick = curr_tick;
last_time = curr_time;
return result;
} /* jerry_port_get_current_time */
/**
* Provide the implementation of jerry_port_print_char.
* Uses 'printf' to print a single character to standard output.
*/
void
jerry_port_print_char (char c) /**< the character to print */
{
printf ("%c", c);
} /* jerry_port_print_char */
} /* jerry_port_current_time */
+6 -6
View File
@@ -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
+1
View File
@@ -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
+2
View File
@@ -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
+238
View File
@@ -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 <assert.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#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 */
+78
View File
@@ -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 <stdlib.h>
#include <string.h>
#include <unistd.h>
#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 */
-450
View File
@@ -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 <assert.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#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 **) &current_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 */
-294
View File
@@ -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 <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include "jerryscript-port.h"
#include "jerryscript.h"
/**
* Computes the end of the directory part of a path.
*
* @return end of the directory part of a path.
*/
static size_t
jerry_port_get_directory_end (const jerry_char_t *path_p) /**< path */
{
const jerry_char_t *end_p = path_p + strlen ((const char *) path_p);
while (end_p > path_p)
{
if (end_p[-1] == '/')
{
return (size_t) (end_p - path_p);
}
end_p--;
}
return 0;
} /* jerry_port_get_directory_end */
/**
* Normalize a file path.
*
* @return a newly allocated buffer with the normalized path if the operation is successful,
* NULL otherwise
*/
static jerry_char_t *
jerry_port_normalize_path (const jerry_char_t *in_path_p, /**< path to the referenced module */
size_t in_path_length, /**< length of the path */
const jerry_char_t *base_path_p, /**< base path */
size_t base_path_length) /**< length of the base path */
{
char *path_p;
if (base_path_length > 0)
{
path_p = (char *) malloc (base_path_length + in_path_length + 1);
if (path_p == NULL)
{
return NULL;
}
memcpy (path_p, base_path_p, base_path_length);
memcpy (path_p + base_path_length, in_path_p, in_path_length);
path_p[base_path_length + in_path_length] = '\0';
}
else
{
path_p = (char *) malloc (in_path_length + 1);
if (path_p == NULL)
{
return NULL;
}
memcpy (path_p, in_path_p, in_path_length);
path_p[in_path_length] = '\0';
}
return (jerry_char_t *) path_p;
} /* jerry_port_normalize_path */
/**
* A module descriptor.
*/
typedef struct jerry_port_module_t
{
struct jerry_port_module_t *next_p; /**< next_module */
jerry_char_t *path_p; /**< path to the module */
size_t base_path_length; /**< base path length for relative difference */
jerry_value_t realm; /**< the realm of the module */
jerry_value_t module; /**< the module itself */
} jerry_port_module_t;
/**
* Native info descriptor for modules.
*/
static const jerry_object_native_info_t jerry_port_module_native_info = {
.free_cb = NULL,
};
/**
* Default module manager.
*/
typedef struct
{
jerry_port_module_t *module_head_p; /**< first module */
} jerry_port_module_manager_t;
/**
* Release known modules.
*/
static void
jerry_port_module_free (jerry_port_module_manager_t *manager_p, /**< module manager */
const jerry_value_t realm) /**< if this argument is object, release only those modules,
* which realm value is equal to this argument. */
{
jerry_port_module_t *module_p = manager_p->module_head_p;
bool release_all = !jerry_value_is_object (realm);
jerry_port_module_t *prev_p = NULL;
while (module_p != NULL)
{
jerry_port_module_t *next_p = module_p->next_p;
if (release_all || module_p->realm == realm)
{
free (module_p->path_p);
jerry_value_free (module_p->realm);
jerry_value_free (module_p->module);
free (module_p);
if (prev_p == NULL)
{
manager_p->module_head_p = next_p;
}
else
{
prev_p->next_p = next_p;
}
}
else
{
prev_p = module_p;
}
module_p = next_p;
}
} /* jerry_port_module_free */
/**
* Initialize the default module manager.
*/
static void
jerry_port_module_manager_init (void *user_data_p)
{
((jerry_port_module_manager_t *) user_data_p)->module_head_p = NULL;
} /* jerry_port_module_manager_init */
/**
* Deinitialize the default module manager.
*/
static void
jerry_port_module_manager_deinit (void *user_data_p) /**< context pointer to deinitialize */
{
jerry_value_t undef = jerry_undefined ();
jerry_port_module_free ((jerry_port_module_manager_t *) user_data_p, undef);
jerry_value_free (undef);
} /* jerry_port_module_manager_deinit */
/**
* Declare the context data manager for modules.
*/
static const jerry_context_data_manager_t jerry_port_module_manager = { .init_cb = jerry_port_module_manager_init,
.deinit_cb = jerry_port_module_manager_deinit,
.bytes_needed =
sizeof (jerry_port_module_manager_t) };
/**
* Default module resolver.
*
* @return a module object if resolving is successful, an error otherwise
*/
jerry_value_t
jerry_port_module_resolve (const jerry_value_t specifier, /**< module specifier string */
const jerry_value_t referrer, /**< parent module */
void *user_p) /**< user data */
{
(void) user_p;
const jerry_char_t *base_path_p = NULL;
size_t base_path_length = 0;
jerry_port_module_t *module_p = jerry_object_get_native_ptr (referrer, &jerry_port_module_native_info);
if (module_p != NULL)
{
base_path_p = module_p->path_p;
base_path_length = module_p->base_path_length;
}
jerry_size_t in_path_length = jerry_string_size (specifier, JERRY_ENCODING_UTF8);
jerry_char_t *in_path_p = (jerry_char_t *) malloc (in_path_length + 1);
jerry_string_to_buffer (specifier, JERRY_ENCODING_UTF8, in_path_p, in_path_length);
in_path_p[in_path_length] = '\0';
jerry_char_t *path_p = jerry_port_normalize_path (in_path_p, in_path_length, base_path_p, base_path_length);
if (path_p == NULL)
{
return jerry_throw_sz (JERRY_ERROR_COMMON, "Out of memory");
}
jerry_value_t realm = jerry_current_realm ();
jerry_port_module_manager_t *manager_p;
manager_p = (jerry_port_module_manager_t *) jerry_context_data (&jerry_port_module_manager);
module_p = manager_p->module_head_p;
while (module_p != NULL)
{
if (module_p->realm == realm && strcmp ((const char *) module_p->path_p, (const char *) path_p) == 0)
{
free (path_p);
free (in_path_p);
jerry_value_free (realm);
return jerry_value_copy (module_p->module);
}
module_p = module_p->next_p;
}
size_t source_size;
uint8_t *source_p = jerry_port_read_source ((const char *) path_p, &source_size);
if (source_p == NULL)
{
free (path_p);
free (in_path_p);
jerry_value_free (realm);
return jerry_throw_sz (JERRY_ERROR_SYNTAX, "Module file not found");
}
jerry_parse_options_t parse_options;
parse_options.options = JERRY_PARSE_MODULE | JERRY_PARSE_HAS_SOURCE_NAME;
parse_options.source_name = jerry_string (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 */
-193
View File
@@ -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 <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <unistd.h>
#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 */
+1 -1
View File
@@ -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
@@ -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);
+44
View File
@@ -0,0 +1,44 @@
/* 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 <stdlib.h>
#include <string.h>
#include "jerryscript-port.h"
/**
* 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 */
+4 -3
View File
@@ -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)
+55
View File
@@ -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 <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/printk.h>
#include <zephyr.h>
#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 */
-293
View File
@@ -1,293 +0,0 @@
/* Copyright JS Foundation and other contributors, http://js.foundation
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include "jerryscript-port.h"
#include "jerryscript.h"
/**
* Computes the end of the directory part of a path.
*
* @return end of the directory part of a path.
*/
static size_t
jerry_port_get_directory_end (const jerry_char_t *path_p) /**< path */
{
const jerry_char_t *end_p = path_p + strlen ((const char *) path_p);
while (end_p > path_p)
{
if (end_p[-1] == '/')
{
return (size_t) (end_p - path_p);
}
end_p--;
}
return 0;
} /* jerry_port_get_directory_end */
/**
* Normalize a file path.
*
* @return a newly allocated buffer with the normalized path if the operation is successful,
* NULL otherwise
*/
static jerry_char_t *
jerry_port_normalize_path (const jerry_char_t *in_path_p, /**< path to the referenced module */
size_t in_path_length, /**< length of the path */
const jerry_char_t *base_path_p, /**< base path */
size_t base_path_length) /**< length of the base path */
{
char *path_p;
if (base_path_length > 0)
{
path_p = (char *) malloc (base_path_length + in_path_length + 1);
if (path_p == NULL)
{
return NULL;
}
memcpy (path_p, base_path_p, base_path_length);
memcpy (path_p + base_path_length, in_path_p, in_path_length);
path_p[base_path_length + in_path_length] = '\0';
}
else
{
path_p = (char *) malloc (in_path_length + 1);
if (path_p == NULL)
{
return NULL;
}
memcpy (path_p, in_path_p, in_path_length);
path_p[in_path_length] = '\0';
}
return (jerry_char_t *) path_p;
} /* jerry_port_normalize_path */
/**
* A module descriptor.
*/
typedef struct jerry_port_module_t
{
struct jerry_port_module_t *next_p; /**< next_module */
jerry_char_t *path_p; /**< path to the module */
size_t base_path_length; /**< base path length for relative difference */
jerry_value_t realm; /**< the realm of the module */
jerry_value_t module; /**< the module itself */
} jerry_port_module_t;
/**
* Native info descriptor for modules.
*/
static const jerry_object_native_info_t jerry_port_module_native_info = {
.free_cb = NULL,
};
/**
* Default module manager.
*/
typedef struct
{
jerry_port_module_t *module_head_p; /**< first module */
} jerry_port_module_manager_t;
/**
* Release known modules.
*/
static void
jerry_port_module_free (jerry_port_module_manager_t *manager_p, /**< module manager */
const jerry_value_t realm) /**< if this argument is object, release only those modules,
* which realm value is equal to this argument. */
{
jerry_port_module_t *module_p = manager_p->module_head_p;
bool release_all = !jerry_value_is_object (realm);
jerry_port_module_t *prev_p = NULL;
while (module_p != NULL)
{
jerry_port_module_t *next_p = module_p->next_p;
if (release_all || module_p->realm == realm)
{
free (module_p->path_p);
jerry_value_free (module_p->realm);
jerry_value_free (module_p->module);
free (module_p);
if (prev_p == NULL)
{
manager_p->module_head_p = next_p;
}
else
{
prev_p->next_p = next_p;
}
}
else
{
prev_p = module_p;
}
module_p = next_p;
}
} /* jerry_port_module_free */
/**
* Initialize the default module manager.
*/
static void
jerry_port_module_manager_init (void *user_data_p)
{
((jerry_port_module_manager_t *) user_data_p)->module_head_p = NULL;
} /* jerry_port_module_manager_init */
/**
* Deinitialize the default module manager.
*/
static void
jerry_port_module_manager_deinit (void *user_data_p) /**< context pointer to deinitialize */
{
jerry_value_t undef = jerry_undefined ();
jerry_port_module_free ((jerry_port_module_manager_t *) user_data_p, undef);
jerry_value_free (undef);
} /* jerry_port_module_manager_deinit */
/**
* Declare the context data manager for modules.
*/
static const jerry_context_data_manager_t jerry_port_module_manager = { .init_cb = jerry_port_module_manager_init,
.deinit_cb = jerry_port_module_manager_deinit,
.bytes_needed =
sizeof (jerry_port_module_manager_t) };
/**
* Default module resolver.
*
* @return a module object if resolving is successful, an error otherwise
*/
jerry_value_t
jerry_port_module_resolve (const jerry_value_t specifier, /**< module specifier string */
const jerry_value_t referrer, /**< parent module */
void *user_p) /**< user data */
{
(void) user_p;
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 */
+30 -134
View File
@@ -13,128 +13,37 @@
* limitations under the License.
*/
#include <zephyr.h>
#include <stdarg.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <zephyr.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 */
#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 */
-120
View File
@@ -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 <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <zephyr.h>
#include "jerryscript-port.h"
#include "jerryscript.h"
#include "getline-zephyr.h"
#include "jerryscript-ext/handler.h"
#include <sys/printk.h>
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 */