From 02ba19f24d3828c3e805730b8d4e9bf4fc360416 Mon Sep 17 00:00:00 2001 From: Akos Kiss Date: Mon, 18 Apr 2016 11:18:12 +0200 Subject: [PATCH] Introduce the Termination Port API * Moved the error codes to jerry-port.h and declared port function `jerry_port_fatal`. * Moved "exit or abort on fail" functionality to the newly added jerry-port-default-fatal.c. * This implied that a default port-specific API had to be introduced: functions `jerry_port_default_set_abort_on_fail` and `jerry_port_default_is_abort_on_fail` declared in jerry-port-default.h control the fatal exit behaviour. * For the sake of clarity, renamed jerry-port.c to jerry-port-default-io.c. * Adapted CMakeLists to deal with port implementations consisting of more then one source file and exposing headers. This also required the renaming of `EXTERNAL_PORT_FILE` cmake option to `EXTERNAL_PORT_DIR`. * Adapted main sources to use the default port header for the abort-on-fail functionality, as that is not part of the core jerry API anymore. * Added default port implementation to the static source code checker tools. JerryScript-DCO-1.0-Signed-off-by: Akos Kiss akiss@inf.u-szeged.hu --- CMakeLists.txt | 10 ++-- jerry-core/CMakeLists.txt | 6 +- jerry-core/jerry-internal.h | 3 - jerry-core/jerry-port.h | 36 +++++++++++ jerry-core/jerry.c | 12 ---- jerry-core/jerry.h | 13 ---- jerry-core/jrt/jrt-fatals.c | 11 +--- main-unix.c | 3 +- targets/default/jerry-port-default-fatal.c | 60 +++++++++++++++++++ .../{jerry-port.c => jerry-port-default-io.c} | 3 +- targets/default/jerry-port-default.h | 42 +++++++++++++ targets/nuttx-stm32f4/main-nuttx.c | 3 +- tools/check-cppcheck.sh | 5 +- tools/check-vera.sh | 3 +- 14 files changed, 156 insertions(+), 54 deletions(-) create mode 100644 targets/default/jerry-port-default-fatal.c rename targets/default/{jerry-port.c => jerry-port-default-io.c} (99%) create mode 100644 targets/default/jerry-port-default.h diff --git a/CMakeLists.txt b/CMakeLists.txt index 78c25f6fd2..fb1f5c442a 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -132,12 +132,11 @@ project (Jerry C ASM) endif() - # Should we use external jerry-port.c? - if(DEFINED EXTERNAL_PORT_FILE AND NOT EXTERNAL_PORT_FILE STREQUAL "UNDEFINED") - set(SOURCE_PORT_IMPLEMENTATION ${EXTERNAL_PORT_FILE}) - set(USE_DEFAULT_PORT FALSE) + # Should we use external port? + if(DEFINED EXTERNAL_PORT_DIR AND NOT EXTERNAL_PORT_DIR STREQUAL "UNDEFINED") + set(PORT_DIR ${EXTERNAL_PORT_DIR}) else() - set(USE_DEFAULT_PORT TRUE) + set(PORT_DIR ${CMAKE_SOURCE_DIR}/targets/default) endif() # Are there any interfaces for external libraries, other than libc, that should be registered? @@ -420,6 +419,7 @@ endif() PROPERTY LINK_FLAGS "${COMPILE_FLAGS_JERRY} ${FLAGS_COMMON_${BUILD_MODE}} ${LINKER_FLAGS_COMMON} ${LINKER_FLAGS_STATIC}") target_compile_definitions(${TARGET_NAME} PRIVATE ${DEFINES_JERRY}) target_include_directories(${TARGET_NAME} PRIVATE ${INCLUDE_CORE_INTERFACE}) + target_include_directories(${TARGET_NAME} PRIVATE ${PORT_DIR}) target_include_directories(${TARGET_NAME} SYSTEM PRIVATE ${INCLUDE_LIBC_INTERFACE}) target_include_directories(${TARGET_NAME} SYSTEM PRIVATE ${INCLUDE_EXTERNAL_LIBS_INTERFACE}) if(("${PLATFORM}" STREQUAL "DARWIN") AND (NOT (CMAKE_COMPILER_IS_GNUCC))) diff --git a/jerry-core/CMakeLists.txt b/jerry-core/CMakeLists.txt index 89cdece556..2d326214cc 100644 --- a/jerry-core/CMakeLists.txt +++ b/jerry-core/CMakeLists.txt @@ -148,11 +148,7 @@ project (JerryCore C ASM) ${SOURCE_CORE_JRT}) # Jerry port - if(USE_DEFAULT_PORT) - file(GLOB SOURCE_PORT_FILES ${CMAKE_SOURCE_DIR}/targets/default/*.c) - else() - set(SOURCE_PORT_FILES ${SOURCE_PORT_IMPLEMENTATION}) - endif() + file(GLOB SOURCE_PORT_FILES ${PORT_DIR}/*.c) # All-in-one build if("${ENABLE_ALL_IN_ONE}" STREQUAL "ON") diff --git a/jerry-core/jerry-internal.h b/jerry-core/jerry-internal.h index f13702d4fc..c7170f8e25 100644 --- a/jerry-core/jerry-internal.h +++ b/jerry-core/jerry-internal.h @@ -29,7 +29,4 @@ jerry_dispatch_external_function (ecma_object_t *, ecma_external_pointer_t, ecma extern void jerry_dispatch_object_free_callback (ecma_external_pointer_t, ecma_external_pointer_t); -extern bool -jerry_is_abort_on_fail (void); - #endif /* !JERRY_INTERNAL_H */ diff --git a/jerry-core/jerry-port.h b/jerry-core/jerry-port.h index ba34f3aca4..14b7398f4c 100644 --- a/jerry-core/jerry-port.h +++ b/jerry-core/jerry-port.h @@ -35,6 +35,42 @@ int jerry_port_logmsg (FILE *stream, const char *format, ...); int jerry_port_errormsg (const char *format, ...); int jerry_port_putchar (int c); +/* + * Termination Port API + * + * Note: + * It is questionable whether a library should be able to terminate an + * application. However, as of now, we only have the concept of completion + * code around jerry_parse and jerry_run. Most of the other API functions + * have no way of signaling an error. So, we keep the termination approach + * with this port function. + */ + +/** + * Error codes + */ +typedef enum +{ + ERR_OUT_OF_MEMORY = 10, + ERR_SYSCALL = 11, + ERR_REF_COUNT_LIMIT = 12, + ERR_UNIMPLEMENTED_CASE = 118, + ERR_FAILED_INTERNAL_ASSERTION = 120 +} jerry_fatal_code_t; + +/** + * Signal the port that jerry experienced a fatal failure from which it cannot + * recover. + * + * @param code gives the cause of the error. + * + * Note: + * Jerry expects the function not to return. + * + * Example: a libc-based port may implement this with exit() or abort(), or both. + */ +void jerry_port_fatal (jerry_fatal_code_t code); + /** * @} */ diff --git a/jerry-core/jerry.c b/jerry-core/jerry.c index 3f0dac7017..99dae48ba3 100644 --- a/jerry-core/jerry.c +++ b/jerry-core/jerry.c @@ -1689,18 +1689,6 @@ jerry_get_memory_limits (size_t *out_data_bss_brk_limit_p, /**< [out] Jerry's ma *out_stack_limit_p = CONFIG_MEM_STACK_LIMIT; } /* jerry_get_memory_limits */ -/** - * Check whether 'abort' should be called instead of 'exit' upon exiting with non-zero exit code. - * - * @return true - if 'abort on fail' flag is set, - * false - otherwise. - */ -bool -jerry_is_abort_on_fail (void) -{ - return ((jerry_flags & JERRY_FLAG_ABORT_ON_FAIL) != 0); -} /* jerry_is_abort_on_fail */ - /** * Parse script for specified context * diff --git a/jerry-core/jerry.h b/jerry-core/jerry.h index a5aa252369..83b81a5b19 100644 --- a/jerry-core/jerry.h +++ b/jerry-core/jerry.h @@ -44,21 +44,8 @@ typedef enum JERRY_FLAG_PARSE_ONLY = (1u << 3), /**< parse only, prevents script execution (only for testing) * TODO: Remove. */ JERRY_FLAG_ENABLE_LOG = (1u << 4), /**< enable logging */ - JERRY_FLAG_ABORT_ON_FAIL = (1u << 5), /**< abort instead of exit in case of failure */ } jerry_flag_t; -/** - * Error codes - */ -typedef enum -{ - ERR_OUT_OF_MEMORY = 10, - ERR_SYSCALL = 11, - ERR_REF_COUNT_LIMIT = 12, - ERR_UNIMPLEMENTED_CASE = 118, - ERR_FAILED_INTERNAL_ASSERTION = 120 -} jerry_fatal_code_t; - /** * Jerry engine build date */ diff --git a/jerry-core/jrt/jrt-fatals.c b/jerry-core/jrt/jrt-fatals.c index 7d98e17273..a0afb3d3f0 100644 --- a/jerry-core/jrt/jrt-fatals.c +++ b/jerry-core/jrt/jrt-fatals.c @@ -65,16 +65,7 @@ jerry_fatal (jerry_fatal_code_t code) /**< status code */ } #endif /* !JERRY_NDEBUG */ - if (code != 0 - && code != ERR_OUT_OF_MEMORY - && jerry_is_abort_on_fail ()) - { - abort (); - } - else - { - exit (code); - } + jerry_port_fatal (code); /* to make compiler happy for some RTOS: 'control reaches end of non-void function' */ while (true) diff --git a/main-unix.c b/main-unix.c index b1b00c78c4..cd86cb4af3 100644 --- a/main-unix.c +++ b/main-unix.c @@ -20,6 +20,7 @@ #include "jerry.h" #include "jerry-port.h" +#include "jerry-port-default.h" /** * Maximum command line arguments number @@ -358,7 +359,7 @@ main (int argc, } else if (!strcmp ("--abort-on-fail", argv[i])) { - flags |= JERRY_FLAG_ABORT_ON_FAIL; + jerry_port_default_set_abort_on_fail (true); } else if (!strncmp ("-", argv[i], 1)) { diff --git a/targets/default/jerry-port-default-fatal.c b/targets/default/jerry-port-default-fatal.c new file mode 100644 index 0000000000..afa272e5b1 --- /dev/null +++ b/targets/default/jerry-port-default-fatal.c @@ -0,0 +1,60 @@ +/* Copyright 2016 Samsung Electronics Co., Ltd. + * Copyright 2016 University of Szeged + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include + +#include "jerry-port.h" +#include "jerry-port-default.h" + +static bool abort_on_fail = false; + +/** + * Sets whether 'abort' should be called instead of 'exit' upon exiting with + * non-zero exit code in the default implementation of jerry_port_fatal. + */ +void jerry_port_default_set_abort_on_fail (bool flag) /**< new value of 'abort on fail' flag */ +{ + abort_on_fail = flag; +} /* jerry_port_default_set_abort_on_fail */ + +/** + * Check whether 'abort' should be called instead of 'exit' upon exiting with + * non-zero exit code in the default implementation of jerry_port_fatal. + * + * @return true - if 'abort on fail' flag is set, + * false - otherwise. + */ +bool jerry_port_default_is_abort_on_fail () +{ + return abort_on_fail; +} /* jerry_port_default_is_abort_on_fail */ + +/** + * Default implementation of jerry_port_fatal. + */ +void jerry_port_fatal (jerry_fatal_code_t code) +{ + if (code != 0 + && code != ERR_OUT_OF_MEMORY + && jerry_port_default_is_abort_on_fail ()) + { + abort (); + } + else + { + exit (code); + } +} /* jerry_port_fatal */ diff --git a/targets/default/jerry-port.c b/targets/default/jerry-port-default-io.c similarity index 99% rename from targets/default/jerry-port.c rename to targets/default/jerry-port-default-io.c index 3a8cb8b3d1..2589eed167 100644 --- a/targets/default/jerry-port.c +++ b/targets/default/jerry-port-default-io.c @@ -13,9 +13,10 @@ * limitations under the License. */ -#include "jerry-port.h" #include +#include "jerry-port.h" + /** * Provide log message to filestream implementation for the engine. */ diff --git a/targets/default/jerry-port-default.h b/targets/default/jerry-port-default.h new file mode 100644 index 0000000000..b6b5a527dc --- /dev/null +++ b/targets/default/jerry-port-default.h @@ -0,0 +1,42 @@ +/* Copyright 2016 Samsung Electronics Co., Ltd. + * Copyright 2016 University of Szeged + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef JERRY_PORT_DEFAULT_H +#define JERRY_PORT_DEFAULT_H + +#include + +#ifdef __cplusplus +extern "C" +{ +#endif /* __cplusplus */ + +/** \addtogroup jerry_port_default Default Jerry engine port API + * These functions are only available if the default port of Jerry is used. + * @{ + */ + +void jerry_port_default_set_abort_on_fail (bool); +bool jerry_port_default_is_abort_on_fail (void); + +/** + * @} + */ + +#ifdef __cplusplus +} +#endif /* __cplusplus */ +#endif /* !JERRY_PORT_DEFAULT_H */ diff --git a/targets/nuttx-stm32f4/main-nuttx.c b/targets/nuttx-stm32f4/main-nuttx.c index cfb4e75e22..0ad33fd98b 100644 --- a/targets/nuttx-stm32f4/main-nuttx.c +++ b/targets/nuttx-stm32f4/main-nuttx.c @@ -19,6 +19,7 @@ #include "jerry.h" #include "jerry-port.h" +#include "jerry-port-default.h" /** * The module interface routine @@ -199,7 +200,7 @@ int jerryscript_entry (int argc, char *argv[]) } else if (!strcmp ("--abort-on-fail", argv[i])) { - flags |= JERRY_FLAG_ABORT_ON_FAIL; + jerry_port_default_set_abort_on_fail (true); } else if (!strcmp ("--log-level", argv[i])) { diff --git a/tools/check-cppcheck.sh b/tools/check-cppcheck.sh index 4083348344..8632e1ae64 100755 --- a/tools/check-cppcheck.sh +++ b/tools/check-cppcheck.sh @@ -24,11 +24,12 @@ else fi JERRY_CORE_DIRS=`find jerry-core -type d` +JERRY_PORT_DEFAULT_DIRS=`find targets/default -type d` JERRY_LIBC_DIRS=`find jerry-libc -type d` JERRY_LIBM_DIRS=`find jerry-libm -type d` INCLUDE_DIRS=() -for DIR in $JERRY_CORE_DIRS $JERRY_LIBC_DIRS $JERRY_LIBM_DIRS +for DIR in $JERRY_CORE_DIRS $JERRY_PORT_DEFAULT_DIRS $JERRY_LIBC_DIRS $JERRY_LIBM_DIRS do INCLUDE_DIRS=("${INCLUDE_DIRS[@]}" "-I$DIR") done @@ -39,4 +40,4 @@ cppcheck -j$CPPCHECK_JOBS --force \ --error-exitcode=1 \ --exitcode-suppressions=tools/cppcheck/suppressions-list \ "${INCLUDE_DIRS[@]}" \ - jerry-core jerry-libc jerry-libm *.c *h tests/unit + jerry-core targets/default jerry-libc jerry-libm *.c *h tests/unit diff --git a/tools/check-vera.sh b/tools/check-vera.sh index 251087a3a2..e83774af3a 100755 --- a/tools/check-vera.sh +++ b/tools/check-vera.sh @@ -16,6 +16,7 @@ # limitations under the License. JERRY_CORE_FILES=`find ./jerry-core -name "*.c" -or -name "*.h"` +JERRY_PORT_DEFAULT_FILES=`find ./targets/default -name "*.c" -or -name "*.h"` JERRY_LIBC_FILES=`find ./jerry-libc -name "*.c" -or -name "*.h"` JERRY_LIBM_FILES=`find ./jerry-libm -name "*.c" -or -name "*.h"` JERRY_MAIN_FILES=`find . -maxdepth 1 -name "*.c" -or -name "*.h"` @@ -23,4 +24,4 @@ UNIT_TEST_FILES=`find ./tests/unit -name "*.c" -or -name "*.h"` vera++ -r tools/vera++ -p jerry \ -e --no-duplicate \ - $JERRY_CORE_FILES $JERRY_LIBC_FILES $JERRY_LIBM_FILES $JERRY_MAIN_FILES $UNIT_TEST_FILES + $JERRY_CORE_FILES $JERRY_PORT_DEFAULT_FILES $JERRY_LIBC_FILES $JERRY_LIBM_FILES $JERRY_MAIN_FILES $UNIT_TEST_FILES