From 35fa39ceb8fc79b6ce33c07d753f3ff2c8d3d39a Mon Sep 17 00:00:00 2001 From: Ruben Ayrapetyan Date: Wed, 11 Feb 2015 16:12:21 +0300 Subject: [PATCH] Initial version of Embedded API. --- src/jerry.cpp | 147 ++++++++++++++++++++++++++++++++++++----- src/jerry.h | 48 ++++++++++++-- src/jrt/jerry-exit.cpp | 2 +- src/jrt/jrt.h | 6 +- src/main_linux.cpp | 16 ++--- src/main_mcu.cpp | 3 +- 6 files changed, 185 insertions(+), 37 deletions(-) diff --git a/src/jerry.cpp b/src/jerry.cpp index 8d4697b37..226b30f61 100644 --- a/src/jerry.cpp +++ b/src/jerry.cpp @@ -20,36 +20,149 @@ #include "serializer.h" #include "vm.h" -bool -jerry_run (const char *script_source, size_t script_source_size, - bool is_parse_only, bool is_show_opcodes, bool is_show_mem_stats) +/** + * Jerry run-time configuration flags + */ +static jerry_flag_t jerry_flags; + +/** + * Jerry engine initialization + */ +void +jerry_init (jerry_flag_t flags) /**< combination of Jerry flags */ { - const opcode_t *opcodes; + jerry_flags = flags; mem_init (); deserializer_init (); +} /* jerry_init */ - parser_init (script_source, script_source_size, is_show_opcodes); +/** + * Terminate Jerry engine + * + * Warning: + * All contexts should be freed with jerry_cleanup_ctx + * before calling the cleanup routine. + */ +void +jerry_cleanup (void) +{ + bool is_show_mem_stats = ((jerry_flags & JERRY_FLAG_MEM_STATS) != 0); + + deserializer_free (); + mem_finalize (is_show_mem_stats); +} /* jerry_cleanup */ + +/** + * Get Jerry configured memory limits + */ +void +jerry_get_memory_limits (size_t *out_data_bss_brk_limit_p, /**< out: Jerry's maximum usage of + * data + bss + brk sections */ + size_t *out_stack_limit_p) /**< out: Jerry's maximum usage of stack */ +{ + *out_data_bss_brk_limit_p = CONFIG_MEM_HEAP_AREA_SIZE + CONFIG_MEM_DATA_LIMIT_MINUS_HEAP_SIZE; + *out_stack_limit_p = CONFIG_MEM_STACK_LIMIT; +} /* jerry_get_memory_limits */ + +/** + * Register Jerry's fatal error callback + */ +void +jerry_reg_err_callback (jerry_error_callback_t callback) /**< pointer to callback function */ +{ + JERRY_UNIMPLEMENTED_REF_UNUSED_VARS ("Error callback is not implemented", callback); +} /* jerry_reg_err_callback */ + +/** + * Allocate new run context + */ +jerry_ctx_t* +jerry_new_ctx (void) +{ + JERRY_UNIMPLEMENTED ("Run contexts are not implemented"); +} /* jerry_new_ctx */ + +/** + * Cleanup resources associated with specified run context + */ +void +jerry_cleanup_ctx (jerry_ctx_t* ctx_p) /**< run context */ +{ + JERRY_UNIMPLEMENTED_REF_UNUSED_VARS ("Run contexts are not implemented", ctx_p); +} /* jerry_cleanup_ctx */ + +/** + * Parse script for specified context + */ +bool +jerry_parse (jerry_ctx_t* ctx_p, /**< run context */ + const char* source_p, /**< script source */ + size_t source_size) /**< script source size */ +{ + /* FIXME: Remove after implementation of run contexts */ + (void) ctx_p; + + bool is_show_opcodes = ((jerry_flags & JERRY_FLAG_SHOW_OPCODES) != 0); + + parser_init (source_p, source_size, is_show_opcodes); parser_parse_program (); - opcodes = (const opcode_t*) deserialize_bytecode (); + const opcode_t* opcodes = (const opcode_t*) deserialize_bytecode (); serializer_print_opcodes (); parser_free (); - if (is_parse_only) - { - deserializer_free (); - mem_finalize (is_show_mem_stats); - return true; - } - + bool is_show_mem_stats = ((jerry_flags & JERRY_FLAG_MEM_STATS) != 0); init_int (opcodes, is_show_mem_stats); - bool is_success = run_int (); + return true; +} /* jerry_parse */ - deserializer_free (); - mem_finalize (is_show_mem_stats); +/** + * Run Jerry in specified run context + */ +jerry_err_t +jerry_run (jerry_ctx_t* ctx_p) /**< run context */ +{ + /* FIXME: Remove after implementation of run contexts */ + (void) ctx_p; - return is_success; + if (run_int()) + { + return ERR_OK; + } + else + { + return ERR_FAILED_ASSERTION_IN_SCRIPT; + } } /* jerry_run */ + +/** + * Simple jerry runner + */ +jerry_err_t +jerry_run_simple (const char *script_source, /**< script source */ + size_t script_source_size, /**< script source size */ + jerry_flag_t flags) /**< combination of Jerry flags */ +{ + jerry_init (flags); + + jerry_err_t ret_code = ERR_OK; + + if (!jerry_parse (NULL, script_source, script_source_size)) + { + ret_code = ERR_PARSER; + } + else + { + if ((flags & JERRY_FLAG_PARSE_ONLY) == 0) + { + ret_code = jerry_run (NULL); + } + } + + jerry_cleanup (); + + return ret_code; +} /* jerry_run_simple */ diff --git a/src/jerry.h b/src/jerry.h index da560eee0..8190b3a97 100644 --- a/src/jerry.h +++ b/src/jerry.h @@ -18,16 +18,52 @@ #include "jrt_types.h" +/* FIXME: Remove when jerry_err_t will be in this header */ +#include "jrt.h" + /** \addtogroup jerry Jerry engine interface * @{ */ -extern bool -jerry_run (const char *script_source, - size_t script_source_size, - bool is_parse_only, - bool is_show_opcodes, - bool is_show_mem_stats); +/** + * Jerry flags + */ +typedef uint32_t jerry_flag_t; + +#define JERRY_FLAG_EMPTY (0) /**< empty flag set */ +#define JERRY_FLAG_SHOW_OPCODES (1 << 0) /**< dump opcodes to stdout after parse */ +#define JERRY_FLAG_MEM_STATS (1 << 1) /**< dump per-opcode memory statistics during execution + * (in the mode full GC is performed after each opcode handler) */ +#define JERRY_FLAG_PARSE_ONLY (1 << 2) /**< parse only, prevents script execution (only for testing) + * FIXME: Remove. + */ + +/** + * Jerry run context + */ +typedef struct jerry_ctx_t jerry_ctx_t; + +/** + * Jerry error callback type + */ +typedef void (*jerry_error_callback_t) (jerry_err_t); + +extern void jerry_init (jerry_flag_t flags); +extern void jerry_cleanup (void); + +extern void jerry_get_memory_limits (size_t *out_data_bss_brk_limit_p, size_t *out_stack_limit_p); +extern void jerry_reg_err_callback (jerry_error_callback_t callback); + +extern jerry_ctx_t* jerry_new_ctx (void); +extern void jerry_cleanup_ctx (jerry_ctx_t*); + +extern bool jerry_parse (jerry_ctx_t*, const char* source_p, size_t source_size); +extern jerry_err_t jerry_run (jerry_ctx_t *); + +extern jerry_err_t +jerry_run_simple (const char *script_source, + size_t script_source_size, + jerry_flag_t flags); /** * @} diff --git a/src/jrt/jerry-exit.cpp b/src/jrt/jerry-exit.cpp index f011ab9c1..c8fb632aa 100644 --- a/src/jrt/jerry-exit.cpp +++ b/src/jrt/jerry-exit.cpp @@ -27,7 +27,7 @@ * and call assertion fail handler. */ void __noreturn -jerry_exit (jerry_status_t code) /**< status code */ +jerry_exit (jerry_err_t code) /**< status code */ { #ifndef JERRY_NDEBUG if (code != ERR_OK) diff --git a/src/jrt/jrt.h b/src/jrt/jrt.h index 4b315b6ee..3045c4a5b 100644 --- a/src/jrt/jrt.h +++ b/src/jrt/jrt.h @@ -44,6 +44,8 @@ /** * Error codes + * + * TODO: Move to jerry.h */ typedef enum { @@ -63,7 +65,7 @@ typedef enum ERR_UNIMPLEMENTED_CASE = -118, ERR_FAILED_ASSERTION_IN_SCRIPT = -119, ERR_FAILED_INTERNAL_ASSERTION = -120, -} jerry_status_t; +} jerry_err_t; /** * Asserts @@ -173,7 +175,7 @@ template extern void jerry_ref_unused_variables (const value /** * Exit */ -extern void __noreturn jerry_exit (jerry_status_t code); +extern void __noreturn jerry_exit (jerry_err_t code); /** * sizeof, offsetof, ... diff --git a/src/main_linux.cpp b/src/main_linux.cpp index 371fb3f68..340ca1803 100644 --- a/src/main_linux.cpp +++ b/src/main_linux.cpp @@ -90,14 +90,14 @@ main (int argc __unused, } const char *file_names[CONFIG_JERRY_MAX_COMMAND_LINE_ARGS]; - bool parse_only = false, show_opcodes = false; - bool print_mem_stats = false; int i; size_t files_counter = 0; jrt_set_mem_limits (CONFIG_MEM_HEAP_AREA_SIZE + CONFIG_MEM_DATA_LIMIT_MINUS_HEAP_SIZE, CONFIG_MEM_STACK_LIMIT); + jerry_flag_t flags = JERRY_FLAG_EMPTY; + for (i = 1; i < argc; i++) { if (!__strcmp ("-v", argv[i])) @@ -110,20 +110,18 @@ main (int argc __unused, if (!__strcmp ("--mem-stats", argv[i])) { #ifdef MEM_STATS - print_mem_stats = true; + flags |= JERRY_FLAG_MEM_STATS; #else /* MEM_STATS */ __printf ("Ignoring --mem-stats because of '!MEM_STATS' build configuration.\n"); - - print_mem_stats = false; #endif /* !MEM_STATS */ } else if (!__strcmp ("--parse-only", argv[i])) { - parse_only = true; + flags |= JERRY_FLAG_PARSE_ONLY; } else if (!__strcmp ("--show-opcodes", argv[i])) { - show_opcodes = true; + flags |= JERRY_FLAG_SHOW_OPCODES; } else { @@ -139,7 +137,7 @@ main (int argc __unused, size_t source_size; const char *source_p = read_sources (file_names, files_counter, &source_size); - bool is_success = jerry_run (source_p, source_size, parse_only, show_opcodes, print_mem_stats); + jerry_err_t ret_code = jerry_run_simple (source_p, source_size, flags); - jerry_exit (is_success ? ERR_OK : ERR_FAILED_ASSERTION_IN_SCRIPT); + jerry_exit (ret_code); } diff --git a/src/main_mcu.cpp b/src/main_mcu.cpp index 0b5c08854..3732c88ed 100644 --- a/src/main_mcu.cpp +++ b/src/main_mcu.cpp @@ -39,7 +39,6 @@ main (void) set_sys_tick_counter ((uint32_t) - 1); start = get_sys_tick_counter (); - jerry_run (source_p, - source_size, false, false, false); + jerry_run_simple (source_p, source_size, JERRY_FLAG_EMPTY); finish_parse_ms = (start - get_sys_tick_counter ()) / 1000; }