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:
@@ -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)
|
||||
+30
-9
@@ -13,9 +13,14 @@
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#include "jerryscript-port-default.h"
|
||||
#include <stdlib.h>
|
||||
|
||||
#include "jerryscript-port.h"
|
||||
|
||||
#ifndef JERRY_GLOBAL_HEAP_SIZE
|
||||
#define JERRY_GLOBAL_HEAP_SIZE 512
|
||||
#endif /* JERRY_GLOBAL_HEAP_SIZE */
|
||||
|
||||
/**
|
||||
* Pointer to the current context.
|
||||
* Note that it is a global variable, and is not a thread safe implementation.
|
||||
@@ -23,21 +28,37 @@
|
||||
static jerry_context_t *current_context_p = NULL;
|
||||
|
||||
/**
|
||||
* Set the current_context_p as the passed pointer.
|
||||
* Allocate a new external context.
|
||||
*
|
||||
* @param context_size: requested context size
|
||||
*
|
||||
* @return total allcoated size
|
||||
*/
|
||||
void
|
||||
jerry_port_default_set_current_context (jerry_context_t *context_p) /**< points to the created context */
|
||||
size_t JERRY_ATTR_WEAK
|
||||
jerry_port_context_alloc (size_t context_size)
|
||||
{
|
||||
current_context_p = context_p;
|
||||
} /* jerry_port_default_set_current_context */
|
||||
size_t total_size = context_size + JERRY_GLOBAL_HEAP_SIZE * 1024;
|
||||
current_context_p = malloc (total_size);
|
||||
|
||||
return total_size;
|
||||
} /* jerry_port_context_alloc */
|
||||
|
||||
/**
|
||||
* Get the current context.
|
||||
*
|
||||
* @return the pointer to the current context
|
||||
*/
|
||||
jerry_context_t *
|
||||
jerry_port_get_current_context (void)
|
||||
jerry_context_t *JERRY_ATTR_WEAK
|
||||
jerry_port_context_get (void)
|
||||
{
|
||||
return current_context_p;
|
||||
} /* jerry_port_get_current_context */
|
||||
} /* jerry_port_context_get */
|
||||
|
||||
/**
|
||||
* Free the currently allocated external context.
|
||||
*/
|
||||
void JERRY_ATTR_WEAK
|
||||
jerry_port_context_free (void)
|
||||
{
|
||||
free (current_context_p);
|
||||
} /* jerry_port_context_free */
|
||||
@@ -0,0 +1,162 @@
|
||||
/* Copyright JS Foundation and other contributors, http://js.foundation
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "jerryscript-port.h"
|
||||
|
||||
#if defined(__GLIBC__) || defined(_WIN32)
|
||||
#include <sys/stat.h>
|
||||
|
||||
#ifndef S_ISDIR
|
||||
#define S_ISDIR(mode) (((mode) &S_IFMT) == S_IFDIR)
|
||||
#endif /* !defined(S_ISDIR) */
|
||||
#endif /* __GLIBC__ */
|
||||
|
||||
/**
|
||||
* Determines the size of the given file.
|
||||
* @return size of the file
|
||||
*/
|
||||
static jerry_size_t
|
||||
jerry_port_get_file_size (FILE *file_p) /**< opened file */
|
||||
{
|
||||
fseek (file_p, 0, SEEK_END);
|
||||
long size = ftell (file_p);
|
||||
fseek (file_p, 0, SEEK_SET);
|
||||
|
||||
return (jerry_size_t) size;
|
||||
} /* jerry_port_get_file_size */
|
||||
|
||||
/**
|
||||
* Opens file with the given path and reads its source.
|
||||
* @return the source of the file
|
||||
*/
|
||||
jerry_char_t *JERRY_ATTR_WEAK
|
||||
jerry_port_source_read (const char *file_name_p, /**< file name */
|
||||
jerry_size_t *out_size_p) /**< [out] read bytes */
|
||||
{
|
||||
/* TODO(dbatyai): Temporary workaround for nuttx target
|
||||
* The nuttx target builds and copies the jerryscript libraries as a separate build step, which causes linking issues
|
||||
* later due to different libc libraries. It should incorporate the amalgam sources into the main nuttx build so that
|
||||
* the correct libraries are used, then this guard should be removed from here and also from the includes. */
|
||||
#if defined(__GLIBC__) || defined(_WIN32)
|
||||
struct stat stat_buffer;
|
||||
if (stat (file_name_p, &stat_buffer) == -1 || S_ISDIR (stat_buffer.st_mode))
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
#endif /* __GLIBC__ */
|
||||
|
||||
FILE *file_p = fopen (file_name_p, "rb");
|
||||
|
||||
if (file_p == NULL)
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
|
||||
jerry_size_t file_size = jerry_port_get_file_size (file_p);
|
||||
jerry_char_t *buffer_p = (jerry_char_t *) malloc (file_size);
|
||||
|
||||
if (buffer_p == NULL)
|
||||
{
|
||||
fclose (file_p);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
size_t bytes_read = fread (buffer_p, 1u, file_size, file_p);
|
||||
|
||||
if (bytes_read != file_size)
|
||||
{
|
||||
fclose (file_p);
|
||||
free (buffer_p);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
fclose (file_p);
|
||||
*out_size_p = (jerry_size_t) bytes_read;
|
||||
|
||||
return buffer_p;
|
||||
} /* jerry_port_source_read */
|
||||
|
||||
/**
|
||||
* Release the previously opened file's content.
|
||||
*/
|
||||
void JERRY_ATTR_WEAK
|
||||
jerry_port_source_free (uint8_t *buffer_p) /**< buffer to free */
|
||||
{
|
||||
free (buffer_p);
|
||||
} /* jerry_port_source_free */
|
||||
|
||||
/**
|
||||
* These functions provide generic implementation for paths and are only enabled when the compiler support weak symbols,
|
||||
* and we are not building for a platform that has platform specific versions.
|
||||
*/
|
||||
#if defined(JERRY_WEAK_SYMBOL_SUPPORT) && !(defined(__unix__) || defined(__APPLE__) || defined(_WIN32))
|
||||
|
||||
/**
|
||||
* Normalize a file path.
|
||||
*
|
||||
* @return a newly allocated buffer with the normalized path if the operation is successful,
|
||||
* NULL otherwise
|
||||
*/
|
||||
jerry_char_t *JERRY_ATTR_WEAK
|
||||
jerry_port_path_normalize (const jerry_char_t *path_p, /**< input path */
|
||||
jerry_size_t path_size) /**< size of the path */
|
||||
{
|
||||
jerry_char_t *buffer_p = (jerry_char_t *) malloc (path_size + 1);
|
||||
|
||||
if (buffer_p == NULL)
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/* Also copy terminating zero byte. */
|
||||
memcpy (buffer_p, path_p, path_size + 1);
|
||||
|
||||
return buffer_p;
|
||||
} /* jerry_port_normalize_path */
|
||||
|
||||
/**
|
||||
* Free a path buffer returned by jerry_port_path_normalize.
|
||||
*
|
||||
* @param path_p: the path to free
|
||||
*/
|
||||
void JERRY_ATTR_WEAK
|
||||
jerry_port_path_free (jerry_char_t *path_p)
|
||||
{
|
||||
free (path_p);
|
||||
} /* jerry_port_normalize_path */
|
||||
|
||||
/**
|
||||
* Computes the end of the directory part of a path.
|
||||
*
|
||||
* @return end of the directory part of a path.
|
||||
*/
|
||||
jerry_size_t JERRY_ATTR_WEAK
|
||||
jerry_port_path_base (const jerry_char_t *path_p) /**< path */
|
||||
{
|
||||
const jerry_char_t *basename_p = (jerry_char_t *) strrchr ((char *) path_p, '/') + 1;
|
||||
|
||||
if (basename_p == NULL)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
return (jerry_size_t) (basename_p - path_p);
|
||||
} /* jerry_port_get_directory_end */
|
||||
|
||||
#endif /* defined(JERRY_WEAK_SYMBOL_SUPPORT) && !(defined(__unix__) || defined(__APPLE__) || defined(_WIN32)) */
|
||||
@@ -0,0 +1,106 @@
|
||||
/* Copyright JS Foundation and other contributors, http://js.foundation
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "jerryscript-port.h"
|
||||
|
||||
/**
|
||||
* Default implementation of jerry_port_log. Prints log messages to stderr.
|
||||
*/
|
||||
void JERRY_ATTR_WEAK
|
||||
jerry_port_log (const char *message_p) /**< message */
|
||||
{
|
||||
fputs (message_p, stderr);
|
||||
} /* jerry_port_log */
|
||||
|
||||
/**
|
||||
* Default implementation of jerry_port_print_byte. Uses 'putchar' to
|
||||
* print a single character to standard output.
|
||||
*/
|
||||
void JERRY_ATTR_WEAK
|
||||
jerry_port_print_byte (jerry_char_t byte) /**< the character to print */
|
||||
{
|
||||
putchar (byte);
|
||||
} /* jerry_port_print_byte */
|
||||
|
||||
/**
|
||||
* Default implementation of jerry_port_print_buffer. Uses 'jerry_port_print_byte' to
|
||||
* print characters of the input buffer.
|
||||
*/
|
||||
void JERRY_ATTR_WEAK
|
||||
jerry_port_print_buffer (const jerry_char_t *buffer_p, /**< string buffer */
|
||||
jerry_size_t buffer_size) /**< string size*/
|
||||
{
|
||||
for (jerry_size_t i = 0; i < buffer_size; i++)
|
||||
{
|
||||
jerry_port_print_byte (buffer_p[i]);
|
||||
}
|
||||
} /* jerry_port_print_byte */
|
||||
|
||||
/**
|
||||
* Read a line from standard input as a zero-terminated string.
|
||||
*
|
||||
* @param out_size_p: length of the string
|
||||
*
|
||||
* @return pointer to the buffer storing the string,
|
||||
* or NULL if end of input
|
||||
*/
|
||||
jerry_char_t *JERRY_ATTR_WEAK
|
||||
jerry_port_line_read (jerry_size_t *out_size_p)
|
||||
{
|
||||
char *line_p = NULL;
|
||||
size_t allocated = 0;
|
||||
size_t bytes = 0;
|
||||
|
||||
while (true)
|
||||
{
|
||||
allocated += 64;
|
||||
line_p = realloc (line_p, allocated);
|
||||
|
||||
while (bytes < allocated - 1)
|
||||
{
|
||||
char ch = (char) fgetc (stdin);
|
||||
|
||||
if (feof (stdin))
|
||||
{
|
||||
free (line_p);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
line_p[bytes++] = ch;
|
||||
|
||||
if (ch == '\n')
|
||||
{
|
||||
*out_size_p = (jerry_size_t) bytes;
|
||||
line_p[bytes++] = '\0';
|
||||
return (jerry_char_t *) line_p;
|
||||
}
|
||||
}
|
||||
}
|
||||
} /* jerry_port_line_read */
|
||||
|
||||
/**
|
||||
* Free a line buffer allocated by jerry_port_line_read
|
||||
*
|
||||
* @param buffer_p: buffer that has been allocated by jerry_port_line_read
|
||||
*/
|
||||
void JERRY_ATTR_WEAK
|
||||
jerry_port_line_free (jerry_char_t *buffer_p)
|
||||
{
|
||||
free (buffer_p);
|
||||
} /* jerry_port_line_free */
|
||||
@@ -15,17 +15,16 @@
|
||||
|
||||
#include <stdlib.h>
|
||||
|
||||
#include "jerryscript-port-default.h"
|
||||
#include "jerryscript-port.h"
|
||||
|
||||
/**
|
||||
* Default implementation of jerry_port_fatal. Calls 'abort' if exit code is
|
||||
* non-zero, 'exit' otherwise.
|
||||
*/
|
||||
void
|
||||
void JERRY_ATTR_WEAK
|
||||
jerry_port_fatal (jerry_fatal_code_t code) /**< cause of error */
|
||||
{
|
||||
if (code != 0 && code != ERR_OUT_OF_MEMORY)
|
||||
if (code != 0 && code != JERRY_FATAL_OUT_OF_MEMORY)
|
||||
{
|
||||
abort ();
|
||||
}
|
||||
@@ -1,163 +0,0 @@
|
||||
/* Copyright JS Foundation and other contributors, http://js.foundation
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#include <time.h>
|
||||
|
||||
#ifdef _WIN32
|
||||
#include <windows.h>
|
||||
|
||||
#include <winbase.h>
|
||||
#include <winnt.h>
|
||||
#endif /* _WIN32 */
|
||||
|
||||
#if defined(__GNUC__) || defined(__clang__)
|
||||
#include <sys/time.h>
|
||||
#endif /* __GNUC__ || __clang__ */
|
||||
|
||||
#include "jerryscript-port-default.h"
|
||||
#include "jerryscript-port.h"
|
||||
|
||||
#ifdef _WIN32
|
||||
static const LONGLONG UnixEpochInTicks = 116444736000000000; /* difference between 1970 and 1601 */
|
||||
static const LONGLONG TicksPerMs = 10000; /* 1 tick is 100 nanoseconds */
|
||||
|
||||
/* https://support.microsoft.com/en-us/help/167296/how-to-convert-a-unix-time-t-to-a-win32-filetime-or-systemtime */
|
||||
static void
|
||||
UnixTimeMsToFileTime (double t, LPFILETIME pft)
|
||||
{
|
||||
LONGLONG ll = (LONGLONG) t * TicksPerMs + UnixEpochInTicks;
|
||||
pft->dwLowDateTime = (DWORD) ll;
|
||||
pft->dwHighDateTime = (DWORD) (ll >> 32);
|
||||
} /* UnixTimeMsToFileTime */
|
||||
|
||||
static double
|
||||
FileTimeToUnixTimeMs (FILETIME ft)
|
||||
{
|
||||
ULARGE_INTEGER date;
|
||||
date.HighPart = ft.dwHighDateTime;
|
||||
date.LowPart = ft.dwLowDateTime;
|
||||
return (double) (((LONGLONG) date.QuadPart - UnixEpochInTicks) / TicksPerMs);
|
||||
} /* FileTimeToUnixTimeMs */
|
||||
|
||||
#endif /* _WIN32 */
|
||||
|
||||
/**
|
||||
* Default implementation of jerry_port_get_local_time_zone_adjustment.
|
||||
*
|
||||
* @return offset between UTC and local time at the given unix timestamp, if
|
||||
* available. Otherwise, returns 0, assuming UTC time.
|
||||
*/
|
||||
double
|
||||
jerry_port_get_local_time_zone_adjustment (double unix_ms, /**< ms since unix epoch */
|
||||
bool is_utc) /**< is the time above in UTC? */
|
||||
{
|
||||
#if defined(HAVE_TM_GMTOFF)
|
||||
struct tm tm;
|
||||
time_t now = (time_t) (unix_ms / 1000);
|
||||
localtime_r (&now, &tm);
|
||||
|
||||
if (!is_utc)
|
||||
{
|
||||
now -= tm.tm_gmtoff;
|
||||
localtime_r (&now, &tm);
|
||||
}
|
||||
|
||||
return ((double) tm.tm_gmtoff) * 1000;
|
||||
#elif defined(_WIN32)
|
||||
FILETIME fileTime, localFileTime;
|
||||
SYSTEMTIME systemTime, localSystemTime;
|
||||
ULARGE_INTEGER time, localTime;
|
||||
|
||||
UnixTimeMsToFileTime (unix_ms, &fileTime);
|
||||
/* If time is earlier than year 1601, then always using year 1601 to query time zone adjustment */
|
||||
if (fileTime.dwHighDateTime >= 0x80000000)
|
||||
{
|
||||
fileTime.dwHighDateTime = 0;
|
||||
fileTime.dwLowDateTime = 0;
|
||||
}
|
||||
|
||||
if (FileTimeToSystemTime (&fileTime, &systemTime)
|
||||
&& SystemTimeToTzSpecificLocalTime (0, &systemTime, &localSystemTime)
|
||||
&& SystemTimeToFileTime (&localSystemTime, &localFileTime))
|
||||
{
|
||||
time.LowPart = fileTime.dwLowDateTime;
|
||||
time.HighPart = fileTime.dwHighDateTime;
|
||||
localTime.LowPart = localFileTime.dwLowDateTime;
|
||||
localTime.HighPart = localFileTime.dwHighDateTime;
|
||||
return (double) (((LONGLONG) localTime.QuadPart - (LONGLONG) time.QuadPart) / TicksPerMs);
|
||||
}
|
||||
return 0.0;
|
||||
#elif defined(__GNUC__) || defined(__clang__)
|
||||
time_t now_time = (time_t) (unix_ms / 1000);
|
||||
double tza_s = 0.0;
|
||||
|
||||
while (true)
|
||||
{
|
||||
struct tm now_tm;
|
||||
if (!gmtime_r (&now_time, &now_tm))
|
||||
{
|
||||
break;
|
||||
}
|
||||
now_tm.tm_isdst = -1; /* if not overridden, DST will not be taken into account */
|
||||
time_t local_time = mktime (&now_tm);
|
||||
if (local_time == (time_t) -1)
|
||||
{
|
||||
break;
|
||||
}
|
||||
tza_s = difftime (now_time, local_time);
|
||||
|
||||
if (is_utc)
|
||||
{
|
||||
break;
|
||||
}
|
||||
now_time -= (time_t) tza_s;
|
||||
is_utc = true;
|
||||
}
|
||||
|
||||
return tza_s * 1000;
|
||||
#else /* !HAVE_TM_GMTOFF && !_WIN32 && !__GNUC__ && !__clang__ */
|
||||
(void) unix_ms; /* unused */
|
||||
(void) is_utc; /* unused */
|
||||
return 0.0;
|
||||
#endif /* HAVE_TM_GMTOFF */
|
||||
} /* jerry_port_get_local_time_zone_adjustment */
|
||||
|
||||
/**
|
||||
* Default implementation of jerry_port_get_current_time. Uses 'gettimeofday' if
|
||||
* available on the system, does nothing otherwise.
|
||||
*
|
||||
* @return milliseconds since Unix epoch - if 'gettimeofday' is available and
|
||||
* executed successfully,
|
||||
* 0 - otherwise.
|
||||
*/
|
||||
double
|
||||
jerry_port_get_current_time (void)
|
||||
{
|
||||
#ifdef _WIN32
|
||||
FILETIME ft;
|
||||
GetSystemTimeAsFileTime (&ft);
|
||||
return FileTimeToUnixTimeMs (ft);
|
||||
#elif defined(__GNUC__) || defined(__clang__)
|
||||
struct timeval tv;
|
||||
|
||||
if (gettimeofday (&tv, NULL) == 0)
|
||||
{
|
||||
return ((double) tv.tv_sec) * 1000.0 + ((double) tv.tv_usec) / 1000.0;
|
||||
}
|
||||
return 0.0;
|
||||
#else /* !_WIN32 && !__GNUC__ && !__clang__ */
|
||||
return 0.0;
|
||||
#endif /* _WIN32 */
|
||||
} /* jerry_port_get_current_time */
|
||||
@@ -1,109 +0,0 @@
|
||||
/* Copyright JS Foundation and other contributors, http://js.foundation
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#include <stdarg.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "jerryscript-debugger.h"
|
||||
#include "jerryscript-port-default.h"
|
||||
#include "jerryscript-port.h"
|
||||
|
||||
/**
|
||||
* Actual log level
|
||||
*/
|
||||
static jerry_log_level_t jerry_port_default_log_level = JERRY_LOG_LEVEL_ERROR;
|
||||
|
||||
/**
|
||||
* Get the log level
|
||||
*
|
||||
* @return current log level
|
||||
*/
|
||||
jerry_log_level_t
|
||||
jerry_port_default_get_log_level (void)
|
||||
{
|
||||
return jerry_port_default_log_level;
|
||||
} /* jerry_port_default_get_log_level */
|
||||
|
||||
/**
|
||||
* Set the log level
|
||||
*/
|
||||
void
|
||||
jerry_port_default_set_log_level (jerry_log_level_t level) /**< log level */
|
||||
{
|
||||
jerry_port_default_log_level = level;
|
||||
} /* jerry_port_default_set_log_level */
|
||||
|
||||
/**
|
||||
* Default implementation of jerry_port_log. Prints log message to the standard
|
||||
* error with 'vfprintf' if message log level is less than or equal to the
|
||||
* current log level.
|
||||
*
|
||||
* If debugger support is enabled, printing happens first to an in-memory buffer,
|
||||
* which is then sent both to the standard error and to the debugger client.
|
||||
*/
|
||||
void
|
||||
jerry_port_log (jerry_log_level_t level, /**< message log level */
|
||||
const char *format, /**< format string */
|
||||
...) /**< parameters */
|
||||
{
|
||||
if (level <= jerry_port_default_log_level)
|
||||
{
|
||||
va_list args;
|
||||
va_start (args, format);
|
||||
#if defined(JERRY_DEBUGGER) && (JERRY_DEBUGGER == 1)
|
||||
int length = vsnprintf (NULL, 0, format, args);
|
||||
va_end (args);
|
||||
va_start (args, format);
|
||||
|
||||
JERRY_VLA (char, buffer, length + 1);
|
||||
vsnprintf (buffer, (size_t) length + 1, format, args);
|
||||
|
||||
fprintf (stderr, "%s", buffer);
|
||||
jerry_debugger_send_log (level, (jerry_char_t *) buffer, (jerry_size_t) length);
|
||||
#else /* If jerry-debugger isn't defined, libc is turned on */
|
||||
vfprintf (stderr, format, args);
|
||||
#endif /* defined (JERRY_DEBUGGER) && (JERRY_DEBUGGER == 1) */
|
||||
va_end (args);
|
||||
}
|
||||
} /* jerry_port_log */
|
||||
|
||||
#if defined(JERRY_DEBUGGER) && (JERRY_DEBUGGER == 1)
|
||||
|
||||
#define DEBUG_BUFFER_SIZE (256)
|
||||
static char debug_buffer[DEBUG_BUFFER_SIZE];
|
||||
static int debug_buffer_index = 0;
|
||||
|
||||
#endif /* defined (JERRY_DEBUGGER) && (JERRY_DEBUGGER == 1) */
|
||||
|
||||
/**
|
||||
* Default implementation of jerry_port_print_char. Uses 'putchar' to
|
||||
* print a single character to standard output.
|
||||
*/
|
||||
void
|
||||
jerry_port_print_char (char c) /**< the character to print */
|
||||
{
|
||||
putchar (c);
|
||||
|
||||
#if defined(JERRY_DEBUGGER) && (JERRY_DEBUGGER == 1)
|
||||
debug_buffer[debug_buffer_index++] = c;
|
||||
|
||||
if ((debug_buffer_index == DEBUG_BUFFER_SIZE) || (c == '\n'))
|
||||
{
|
||||
jerry_debugger_send_output ((jerry_char_t *) debug_buffer, (jerry_size_t) debug_buffer_index);
|
||||
debug_buffer_index = 0;
|
||||
}
|
||||
#endif /* defined (JERRY_DEBUGGER) && (JERRY_DEBUGGER == 1) */
|
||||
} /* jerry_port_print_char */
|
||||
@@ -1,410 +0,0 @@
|
||||
/* Copyright JS Foundation and other contributors, http://js.foundation
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#include <limits.h>
|
||||
#include <stdarg.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "jerryscript-port-default.h"
|
||||
#include "jerryscript-port.h"
|
||||
|
||||
#include <sys/stat.h>
|
||||
|
||||
#ifndef S_ISDIR
|
||||
#define S_ISDIR(mode) (((mode) &S_IFMT) == S_IFDIR)
|
||||
#endif /* !defined(S_ISDIR) */
|
||||
|
||||
/**
|
||||
* Determines the size of the given file.
|
||||
* @return size of the file
|
||||
*/
|
||||
static size_t
|
||||
jerry_port_get_file_size (FILE *file_p) /**< opened file */
|
||||
{
|
||||
fseek (file_p, 0, SEEK_END);
|
||||
long size = ftell (file_p);
|
||||
fseek (file_p, 0, SEEK_SET);
|
||||
|
||||
return (size_t) size;
|
||||
} /* jerry_port_get_file_size */
|
||||
|
||||
/**
|
||||
* Opens file with the given path and reads its source.
|
||||
* @return the source of the file
|
||||
*/
|
||||
uint8_t *
|
||||
jerry_port_read_source (const char *file_name_p, /**< file name */
|
||||
size_t *out_size_p) /**< [out] read bytes */
|
||||
{
|
||||
struct stat stat_buffer;
|
||||
if (stat (file_name_p, &stat_buffer) == -1 || S_ISDIR (stat_buffer.st_mode))
|
||||
{
|
||||
jerry_port_log (JERRY_LOG_LEVEL_ERROR, "Error: Failed to open file: %s\n", file_name_p);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
FILE *file_p = fopen (file_name_p, "rb");
|
||||
|
||||
if (file_p == NULL)
|
||||
{
|
||||
jerry_port_log (JERRY_LOG_LEVEL_ERROR, "Error: Failed to open file: %s\n", file_name_p);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
size_t file_size = jerry_port_get_file_size (file_p);
|
||||
uint8_t *buffer_p = (uint8_t *) malloc (file_size);
|
||||
|
||||
if (buffer_p == NULL)
|
||||
{
|
||||
fclose (file_p);
|
||||
|
||||
jerry_port_log (JERRY_LOG_LEVEL_ERROR, "Error: Failed to allocate memory for file: %s\n", file_name_p);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
size_t bytes_read = fread (buffer_p, 1u, file_size, file_p);
|
||||
|
||||
if (bytes_read != file_size)
|
||||
{
|
||||
fclose (file_p);
|
||||
free (buffer_p);
|
||||
|
||||
jerry_port_log (JERRY_LOG_LEVEL_ERROR, "Error: Failed to read file: %s\n", file_name_p);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
fclose (file_p);
|
||||
*out_size_p = bytes_read;
|
||||
|
||||
return buffer_p;
|
||||
} /* jerry_port_read_source */
|
||||
|
||||
/**
|
||||
* Release the previously opened file's content.
|
||||
*/
|
||||
void
|
||||
jerry_port_release_source (uint8_t *buffer_p) /**< buffer to free */
|
||||
{
|
||||
free (buffer_p);
|
||||
} /* jerry_port_release_source */
|
||||
|
||||
/**
|
||||
* Computes the end of the directory part of a path.
|
||||
*
|
||||
* @return end of the directory part of a path.
|
||||
*/
|
||||
static size_t
|
||||
jerry_port_get_directory_end (const jerry_char_t *path_p) /**< path */
|
||||
{
|
||||
const jerry_char_t *end_p = path_p + strlen ((const char *) path_p);
|
||||
|
||||
while (end_p > path_p)
|
||||
{
|
||||
#if defined(_WIN32)
|
||||
if (end_p[-1] == '/' || end_p[-1] == '\\')
|
||||
{
|
||||
return (size_t) (end_p - path_p);
|
||||
}
|
||||
#else /* !_WIN32 */
|
||||
if (end_p[-1] == '/')
|
||||
{
|
||||
return (size_t) (end_p - path_p);
|
||||
}
|
||||
#endif /* _WIN32 */
|
||||
|
||||
end_p--;
|
||||
}
|
||||
|
||||
return 0;
|
||||
} /* jerry_port_get_directory_end */
|
||||
|
||||
/**
|
||||
* Normalize a file path.
|
||||
*
|
||||
* @return a newly allocated buffer with the normalized path if the operation is successful,
|
||||
* NULL otherwise
|
||||
*/
|
||||
static jerry_char_t *
|
||||
jerry_port_normalize_path (const jerry_char_t *in_path_p, /**< path to the referenced module */
|
||||
size_t in_path_length, /**< length of the path */
|
||||
const jerry_char_t *base_path_p, /**< base path */
|
||||
size_t base_path_length) /**< length of the base path */
|
||||
{
|
||||
char *path_p;
|
||||
|
||||
if (base_path_length > 0)
|
||||
{
|
||||
path_p = (char *) malloc (base_path_length + in_path_length + 1);
|
||||
|
||||
if (path_p == NULL)
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
|
||||
memcpy (path_p, base_path_p, base_path_length);
|
||||
memcpy (path_p + base_path_length, in_path_p, in_path_length);
|
||||
path_p[base_path_length + in_path_length] = '\0';
|
||||
}
|
||||
else
|
||||
{
|
||||
path_p = (char *) malloc (in_path_length + 1);
|
||||
|
||||
if (path_p == NULL)
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
|
||||
memcpy (path_p, in_path_p, in_path_length);
|
||||
path_p[in_path_length] = '\0';
|
||||
}
|
||||
|
||||
#if defined(_WIN32)
|
||||
char full_path[_MAX_PATH];
|
||||
|
||||
if (_fullpath (full_path, path_p, _MAX_PATH) != NULL)
|
||||
{
|
||||
free (path_p);
|
||||
|
||||
size_t full_path_len = strlen (full_path);
|
||||
|
||||
path_p = (char *) malloc (full_path_len + 1);
|
||||
|
||||
if (path_p == NULL)
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
|
||||
memcpy (path_p, full_path, full_path_len + 1);
|
||||
}
|
||||
#elif defined(__unix__) || defined(__APPLE__)
|
||||
char *norm_p = realpath (path_p, NULL);
|
||||
|
||||
if (norm_p != NULL)
|
||||
{
|
||||
free (path_p);
|
||||
path_p = norm_p;
|
||||
}
|
||||
#endif /* _WIN32 */
|
||||
|
||||
return (jerry_char_t *) path_p;
|
||||
} /* jerry_port_normalize_path */
|
||||
|
||||
/**
|
||||
* A module descriptor.
|
||||
*/
|
||||
typedef struct jerry_port_module_t
|
||||
{
|
||||
struct jerry_port_module_t *next_p; /**< next_module */
|
||||
jerry_char_t *path_p; /**< path to the module */
|
||||
size_t base_path_length; /**< base path length for relative difference */
|
||||
jerry_value_t realm; /**< the realm of the module */
|
||||
jerry_value_t module; /**< the module itself */
|
||||
} jerry_port_module_t;
|
||||
|
||||
/**
|
||||
* Native info descriptor for modules.
|
||||
*/
|
||||
static const jerry_object_native_info_t jerry_port_module_native_info = {
|
||||
.free_cb = NULL,
|
||||
};
|
||||
|
||||
/**
|
||||
* Default module manager.
|
||||
*/
|
||||
typedef struct
|
||||
{
|
||||
jerry_port_module_t *module_head_p; /**< first module */
|
||||
} jerry_port_module_manager_t;
|
||||
|
||||
/**
|
||||
* Release known modules.
|
||||
*/
|
||||
static void
|
||||
jerry_port_module_free (jerry_port_module_manager_t *manager_p, /**< module manager */
|
||||
const jerry_value_t realm) /**< if this argument is object, release only those modules,
|
||||
* which realm value is equal to this argument. */
|
||||
{
|
||||
jerry_port_module_t *module_p = manager_p->module_head_p;
|
||||
|
||||
bool release_all = !jerry_value_is_object (realm);
|
||||
|
||||
jerry_port_module_t *prev_p = NULL;
|
||||
|
||||
while (module_p != NULL)
|
||||
{
|
||||
jerry_port_module_t *next_p = module_p->next_p;
|
||||
|
||||
if (release_all || module_p->realm == realm)
|
||||
{
|
||||
free (module_p->path_p);
|
||||
jerry_value_free (module_p->realm);
|
||||
jerry_value_free (module_p->module);
|
||||
|
||||
free (module_p);
|
||||
|
||||
if (prev_p == NULL)
|
||||
{
|
||||
manager_p->module_head_p = next_p;
|
||||
}
|
||||
else
|
||||
{
|
||||
prev_p->next_p = next_p;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
prev_p = module_p;
|
||||
}
|
||||
|
||||
module_p = next_p;
|
||||
}
|
||||
} /* jerry_port_module_free */
|
||||
|
||||
/**
|
||||
* Initialize the default module manager.
|
||||
*/
|
||||
static void
|
||||
jerry_port_module_manager_init (void *user_data_p)
|
||||
{
|
||||
((jerry_port_module_manager_t *) user_data_p)->module_head_p = NULL;
|
||||
} /* jerry_port_module_manager_init */
|
||||
|
||||
/**
|
||||
* Deinitialize the default module manager.
|
||||
*/
|
||||
static void
|
||||
jerry_port_module_manager_deinit (void *user_data_p) /**< context pointer to deinitialize */
|
||||
{
|
||||
jerry_value_t undef = jerry_undefined ();
|
||||
jerry_port_module_free ((jerry_port_module_manager_t *) user_data_p, undef);
|
||||
jerry_value_free (undef);
|
||||
} /* jerry_port_module_manager_deinit */
|
||||
|
||||
/**
|
||||
* Declare the context data manager for modules.
|
||||
*/
|
||||
static const jerry_context_data_manager_t jerry_port_module_manager = { .init_cb = jerry_port_module_manager_init,
|
||||
.deinit_cb = jerry_port_module_manager_deinit,
|
||||
.bytes_needed =
|
||||
sizeof (jerry_port_module_manager_t) };
|
||||
|
||||
/**
|
||||
* Default module resolver.
|
||||
*
|
||||
* @return a module object if resolving is successful, an error otherwise
|
||||
*/
|
||||
jerry_value_t
|
||||
jerry_port_module_resolve (const jerry_value_t specifier, /**< module specifier string */
|
||||
const jerry_value_t referrer, /**< parent module */
|
||||
void *user_p) /**< user data */
|
||||
{
|
||||
(void) user_p;
|
||||
|
||||
const jerry_char_t *base_path_p = NULL;
|
||||
size_t base_path_length = 0;
|
||||
jerry_port_module_t *module_p = jerry_object_get_native_ptr (referrer, &jerry_port_module_native_info);
|
||||
|
||||
if (module_p != NULL)
|
||||
{
|
||||
base_path_p = module_p->path_p;
|
||||
base_path_length = module_p->base_path_length;
|
||||
}
|
||||
|
||||
jerry_size_t in_path_length = jerry_string_size (specifier, JERRY_ENCODING_UTF8);
|
||||
jerry_char_t *in_path_p = (jerry_char_t *) malloc (in_path_length + 1);
|
||||
jerry_string_to_buffer (specifier, JERRY_ENCODING_UTF8, in_path_p, in_path_length);
|
||||
in_path_p[in_path_length] = '\0';
|
||||
|
||||
jerry_char_t *path_p = jerry_port_normalize_path (in_path_p, in_path_length, base_path_p, base_path_length);
|
||||
|
||||
if (path_p == NULL)
|
||||
{
|
||||
return jerry_throw_sz (JERRY_ERROR_COMMON, "Out of memory");
|
||||
}
|
||||
|
||||
jerry_value_t realm = jerry_current_realm ();
|
||||
|
||||
jerry_port_module_manager_t *manager_p;
|
||||
manager_p = (jerry_port_module_manager_t *) jerry_context_data (&jerry_port_module_manager);
|
||||
|
||||
module_p = manager_p->module_head_p;
|
||||
|
||||
while (module_p != NULL)
|
||||
{
|
||||
if (module_p->realm == realm && strcmp ((const char *) module_p->path_p, (const char *) path_p) == 0)
|
||||
{
|
||||
free (path_p);
|
||||
free (in_path_p);
|
||||
jerry_value_free (realm);
|
||||
return jerry_value_copy (module_p->module);
|
||||
}
|
||||
|
||||
module_p = module_p->next_p;
|
||||
}
|
||||
|
||||
size_t source_size;
|
||||
uint8_t *source_p = jerry_port_read_source ((const char *) path_p, &source_size);
|
||||
|
||||
if (source_p == NULL)
|
||||
{
|
||||
free (path_p);
|
||||
free (in_path_p);
|
||||
jerry_value_free (realm);
|
||||
/* TODO: This is incorrect, but makes test262 module tests pass
|
||||
* (they should throw SyntaxError, but not because the module cannot be found). */
|
||||
return jerry_throw_sz (JERRY_ERROR_SYNTAX, "Module file not found");
|
||||
}
|
||||
|
||||
jerry_parse_options_t parse_options;
|
||||
parse_options.options = JERRY_PARSE_MODULE | JERRY_PARSE_HAS_SOURCE_NAME;
|
||||
parse_options.source_name = jerry_string (in_path_p, in_path_length, JERRY_ENCODING_UTF8);
|
||||
|
||||
jerry_value_t ret_value = jerry_parse (source_p, source_size, &parse_options);
|
||||
jerry_value_free (parse_options.source_name);
|
||||
|
||||
jerry_port_release_source (source_p);
|
||||
free (in_path_p);
|
||||
|
||||
if (jerry_value_is_exception (ret_value))
|
||||
{
|
||||
free (path_p);
|
||||
jerry_value_free (realm);
|
||||
return ret_value;
|
||||
}
|
||||
|
||||
module_p = (jerry_port_module_t *) malloc (sizeof (jerry_port_module_t));
|
||||
|
||||
module_p->next_p = manager_p->module_head_p;
|
||||
module_p->path_p = path_p;
|
||||
module_p->base_path_length = jerry_port_get_directory_end (module_p->path_p);
|
||||
module_p->realm = realm;
|
||||
module_p->module = jerry_value_copy (ret_value);
|
||||
|
||||
jerry_object_set_native_ptr (ret_value, &jerry_port_module_native_info, module_p);
|
||||
manager_p->module_head_p = module_p;
|
||||
|
||||
return ret_value;
|
||||
} /* jerry_port_module_resolve */
|
||||
|
||||
/**
|
||||
* Release known modules.
|
||||
*/
|
||||
void
|
||||
jerry_port_module_release (const jerry_value_t realm) /**< if this argument is object, release only those modules,
|
||||
* which realm value is equal to this argument. */
|
||||
{
|
||||
jerry_port_module_free ((jerry_port_module_manager_t *) jerry_context_data (&jerry_port_module_manager), realm);
|
||||
} /* jerry_port_module_release */
|
||||
@@ -2,9 +2,9 @@ prefix=@CMAKE_INSTALL_PREFIX@
|
||||
libdir=${prefix}/lib
|
||||
includedir=${prefix}/include
|
||||
|
||||
Name: libjerry-port-default
|
||||
Name: libjerry-port
|
||||
Description: JerryScript: lightweight JavaScript engine (default port library)
|
||||
URL: https://github.com/jerryscript-project/jerryscript
|
||||
Version: @JERRY_VERSION@
|
||||
Libs: -L${libdir} -ljerry-port-default
|
||||
Libs: -L${libdir} -ljerry-port
|
||||
Cflags: -I${includedir}
|
||||
@@ -0,0 +1,70 @@
|
||||
/* Copyright JS Foundation and other contributors, http://js.foundation
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#include "jerryscript-port.h"
|
||||
|
||||
#if defined(__unix__) || defined(__APPLE__)
|
||||
|
||||
#include <sys/time.h>
|
||||
#include <time.h>
|
||||
|
||||
/**
|
||||
* Default implementation of jerry_port_local_tza.
|
||||
*
|
||||
* @return offset between UTC and local time at the given unix timestamp, if
|
||||
* available. Otherwise, returns 0, assuming UTC time.
|
||||
*/
|
||||
int32_t
|
||||
jerry_port_local_tza (double unix_ms)
|
||||
{
|
||||
time_t time = (time_t) unix_ms / 1000;
|
||||
|
||||
#if defined(HAVE_TM_GMTOFF)
|
||||
struct tm tm;
|
||||
localtime_r (&time, &tm);
|
||||
|
||||
return ((int32_t) tm.tm_gmtoff) * 1000;
|
||||
#else /* !defined(HAVE_TM_GMTOFF) */
|
||||
struct tm gmt_tm;
|
||||
struct tm local_tm;
|
||||
|
||||
gmtime_r (&time, &gmt_tm);
|
||||
localtime_r (&time, &local_tm);
|
||||
|
||||
time_t gmt = mktime (&gmt_tm);
|
||||
|
||||
/* mktime removes the daylight saving time from the result time value, however we want to keep it */
|
||||
local_tm.tm_isdst = 0;
|
||||
time_t local = mktime (&local_tm);
|
||||
|
||||
return (int32_t) difftime (local, gmt) * 1000;
|
||||
#endif /* HAVE_TM_GMTOFF */
|
||||
} /* jerry_port_local_tza */
|
||||
|
||||
/**
|
||||
* Default implementation of jerry_port_current_time.
|
||||
*
|
||||
* @return milliseconds since Unix epoch
|
||||
*/
|
||||
double
|
||||
jerry_port_current_time (void)
|
||||
{
|
||||
struct timeval tv;
|
||||
gettimeofday (&tv, NULL);
|
||||
|
||||
return ((double) tv.tv_sec) * 1000.0 + ((double) tv.tv_usec) / 1000.0;
|
||||
} /* jerry_port_current_time */
|
||||
|
||||
#endif /* defined(__unix__) || defined(__APPLE__) */
|
||||
@@ -0,0 +1,63 @@
|
||||
/* Copyright JS Foundation and other contributors, http://js.foundation
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#include "jerryscript-port.h"
|
||||
|
||||
#if defined(__unix__) || defined(__APPLE__)
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
/**
|
||||
* Normalize a file path using realpath.
|
||||
*
|
||||
* @param path_p: input path
|
||||
* @param path_size: input path size
|
||||
*
|
||||
* @return a newly allocated buffer with the normalized path if the operation is successful,
|
||||
* NULL otherwise
|
||||
*/
|
||||
jerry_char_t *
|
||||
jerry_port_path_normalize (const jerry_char_t *path_p, /**< input path */
|
||||
jerry_size_t path_size) /**< size of the path */
|
||||
{
|
||||
(void) path_size;
|
||||
|
||||
return (jerry_char_t *) realpath ((char *) path_p, NULL);
|
||||
} /* jerry_port_path_normalize */
|
||||
|
||||
/**
|
||||
* Free a path buffer returned by jerry_port_path_normalize.
|
||||
*/
|
||||
void
|
||||
jerry_port_path_free (jerry_char_t *path_p)
|
||||
{
|
||||
free (path_p);
|
||||
} /* jerry_port_path_free */
|
||||
|
||||
/**
|
||||
* Computes the end of the directory part of a path.
|
||||
*
|
||||
* @return end of the directory part of a path.
|
||||
*/
|
||||
jerry_size_t JERRY_ATTR_WEAK
|
||||
jerry_port_path_base (const jerry_char_t *path_p) /**< path */
|
||||
{
|
||||
const jerry_char_t *basename_p = (jerry_char_t *) strrchr ((char *) path_p, '/') + 1;
|
||||
|
||||
return (jerry_size_t) (basename_p - path_p);
|
||||
} /* jerry_port_get_directory_end */
|
||||
|
||||
#endif /* defined(__unix__) || defined(__APPLE__) */
|
||||
@@ -13,31 +13,25 @@
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#include "jerryscript-port.h"
|
||||
|
||||
#if defined(__unix__) || defined(__APPLE__)
|
||||
|
||||
#if !defined(_XOPEN_SOURCE) || _XOPEN_SOURCE < 500
|
||||
#undef _XOPEN_SOURCE
|
||||
/* Required macro for sleep functions (nanosleep or usleep) */
|
||||
#define _XOPEN_SOURCE 500
|
||||
#endif /* !(defined(_XOPEN_SOURCE) || _XOPEN_SOURCE < 500) */
|
||||
|
||||
#ifdef _WIN32
|
||||
#include <windows.h>
|
||||
#else /* !_WIN32 */
|
||||
#include <unistd.h>
|
||||
#endif /* _WIN32 */
|
||||
|
||||
#include "jerryscript-port-default.h"
|
||||
#include "jerryscript-port.h"
|
||||
|
||||
/**
|
||||
* Default implementation of jerry_port_sleep. Uses 'usleep' if available on the
|
||||
* system, does nothing otherwise.
|
||||
* Default implementation of jerry_port_sleep, uses 'usleep'.
|
||||
*/
|
||||
void
|
||||
jerry_port_sleep (uint32_t sleep_time) /**< milliseconds to sleep */
|
||||
{
|
||||
#ifdef _WIN32
|
||||
Sleep (sleep_time);
|
||||
#else /* !_WIN32 */
|
||||
usleep ((useconds_t) sleep_time * 1000);
|
||||
#endif /* _WIN32 */
|
||||
} /* jerry_port_sleep */
|
||||
|
||||
#endif /* defined(__unix__) || defined(__APPLE__) */
|
||||
@@ -0,0 +1,102 @@
|
||||
/* Copyright JS Foundation and other contributors, http://js.foundation
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#include "jerryscript-port.h"
|
||||
|
||||
#if defined(_WIN32)
|
||||
|
||||
#include <windows.h>
|
||||
|
||||
#include <time.h>
|
||||
#include <winbase.h>
|
||||
#include <winnt.h>
|
||||
|
||||
#define UNIX_EPOCH_IN_TICKS 116444736000000000ull /* difference between 1970 and 1601 */
|
||||
#define TICKS_PER_MS 10000ull /* 1 tick is 100 nanoseconds */
|
||||
|
||||
/**
|
||||
* Convert unix time to a FILETIME value.
|
||||
*
|
||||
* https://support.microsoft.com/en-us/help/167296/how-to-convert-a-unix-time-t-to-a-win32-filetime-or-systemtime
|
||||
*/
|
||||
static void
|
||||
unix_time_to_filetime (double t, LPFILETIME ft_p)
|
||||
{
|
||||
LONGLONG ll = (LONGLONG) t * TICKS_PER_MS + UNIX_EPOCH_IN_TICKS;
|
||||
|
||||
/* FILETIME values before the epoch are invalid. */
|
||||
if (ll < 0)
|
||||
{
|
||||
ll = 0;
|
||||
}
|
||||
|
||||
ft_p->dwLowDateTime = (DWORD) ll;
|
||||
ft_p->dwHighDateTime = (DWORD) (ll >> 32);
|
||||
} /* unix_time_to_file_time */
|
||||
|
||||
/**
|
||||
* Convert a FILETIME to a unix time value.
|
||||
*
|
||||
* @return unix time
|
||||
*/
|
||||
static double
|
||||
filetime_to_unix_time (LPFILETIME ft_p)
|
||||
{
|
||||
ULARGE_INTEGER date;
|
||||
date.HighPart = ft_p->dwHighDateTime;
|
||||
date.LowPart = ft_p->dwLowDateTime;
|
||||
return (double) (((LONGLONG) date.QuadPart - UNIX_EPOCH_IN_TICKS) / TICKS_PER_MS);
|
||||
} /* FileTimeToUnixTimeMs */
|
||||
|
||||
/**
|
||||
* Default implementation of jerry_port_local_tza.
|
||||
*
|
||||
* @return offset between UTC and local time at the given unix timestamp, if
|
||||
* available. Otherwise, returns 0, assuming UTC time.
|
||||
*/
|
||||
int32_t
|
||||
jerry_port_local_tza (double unix_ms)
|
||||
{
|
||||
FILETIME utc;
|
||||
FILETIME local;
|
||||
SYSTEMTIME utc_sys;
|
||||
SYSTEMTIME local_sys;
|
||||
|
||||
unix_time_to_filetime (unix_ms, &utc);
|
||||
|
||||
if (FileTimeToSystemTime (&utc, &utc_sys) && SystemTimeToTzSpecificLocalTime (NULL, &utc_sys, &local_sys)
|
||||
&& SystemTimeToFileTime (&local_sys, &local))
|
||||
{
|
||||
double unix_local = filetime_to_unix_time (&local);
|
||||
return (int32_t) (unix_local - unix_ms);
|
||||
}
|
||||
|
||||
return 0;
|
||||
} /* jerry_port_local_tza */
|
||||
|
||||
/**
|
||||
* Default implementation of jerry_port_current_time.
|
||||
*
|
||||
* @return milliseconds since Unix epoch
|
||||
*/
|
||||
double
|
||||
jerry_port_current_time (void)
|
||||
{
|
||||
FILETIME ft;
|
||||
GetSystemTimeAsFileTime (&ft);
|
||||
return filetime_to_unix_time (&ft);
|
||||
} /* jerry_port_current_time */
|
||||
|
||||
#endif /* defined(_WIN32) */
|
||||
@@ -0,0 +1,72 @@
|
||||
/* Copyright JS Foundation and other contributors, http://js.foundation
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#include "jerryscript-port.h"
|
||||
|
||||
#if defined(_WIN32)
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
/**
|
||||
* Normalize a file path.
|
||||
*
|
||||
* @return a newly allocated buffer with the normalized path if the operation is successful,
|
||||
* NULL otherwise
|
||||
*/
|
||||
jerry_char_t *
|
||||
jerry_port_path_normalize (const jerry_char_t *path_p, /**< input path */
|
||||
jerry_size_t path_size) /**< size of the path */
|
||||
{
|
||||
(void) path_size;
|
||||
|
||||
return (jerry_char_t *) _fullpath (NULL, path_p, _MAX_PATH);
|
||||
} /* jerry_port_path_normalize */
|
||||
|
||||
/**
|
||||
* Free a path buffer returned by jerry_port_path_normalize.
|
||||
*/
|
||||
void
|
||||
jerry_port_path_free (jerry_char_t *path_p)
|
||||
{
|
||||
free (path_p);
|
||||
} /* jerry_port_path_free */
|
||||
|
||||
/**
|
||||
* Get the end of the directory part of the input path.
|
||||
*
|
||||
* @param path_p: input zero-terminated path string
|
||||
*
|
||||
* @return offset of the directory end in the input path string
|
||||
*/
|
||||
jerry_size_t
|
||||
jerry_port_path_base (const jerry_char_t *path_p)
|
||||
{
|
||||
const jerry_char_t *end_p = path_p + strlen ((const char *) path_p);
|
||||
|
||||
while (end_p > path_p)
|
||||
{
|
||||
if (end_p[-1] == '/' || end_p[-1] == '\\')
|
||||
{
|
||||
return (jerry_size_t) (end_p - path_p);
|
||||
}
|
||||
|
||||
end_p--;
|
||||
}
|
||||
|
||||
return 0;
|
||||
} /* jerry_port_path_base */
|
||||
|
||||
#endif /* defined(_WIN32) */
|
||||
+9
-21
@@ -12,31 +12,19 @@
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#ifndef JERRYSCRIPT_PORT_DEFAULT_H
|
||||
#define JERRYSCRIPT_PORT_DEFAULT_H
|
||||
|
||||
#include <stdbool.h>
|
||||
|
||||
#include "jerryscript-port.h"
|
||||
#include "jerryscript.h"
|
||||
|
||||
JERRY_C_API_BEGIN
|
||||
#if defined(_WIN32)
|
||||
|
||||
/** \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);
|
||||
#include <windows.h>
|
||||
|
||||
/**
|
||||
* @}
|
||||
* Default implementation of jerry_port_sleep, uses 'Sleep'.
|
||||
*/
|
||||
void
|
||||
jerry_port_sleep (uint32_t sleep_time) /**< milliseconds to sleep */
|
||||
{
|
||||
Sleep (sleep_time);
|
||||
} /* jerry_port_sleep */
|
||||
|
||||
JERRY_C_API_END
|
||||
|
||||
#endif /* !JERRYSCRIPT_PORT_DEFAULT_H */
|
||||
#endif /* defined(_WIN32) */
|
||||
Reference in New Issue
Block a user