From 7ce37489471bd00fdfd5d4aa954177a52ab308d7 Mon Sep 17 00:00:00 2001 From: wgzAIIT <820906721@qq.com> Date: Tue, 8 Aug 2023 15:10:21 +0800 Subject: [PATCH] add JerryScript test case --- APP_Framework/lib/JerryScript/Makefile | 2 +- APP_Framework/lib/JerryScript/jerry_main.c | 579 ++++++++++++++------- APP_Framework/lib/JerryScript/jerry_test.c | 271 ++++++++++ 3 files changed, 661 insertions(+), 191 deletions(-) create mode 100644 APP_Framework/lib/JerryScript/jerry_test.c diff --git a/APP_Framework/lib/JerryScript/Makefile b/APP_Framework/lib/JerryScript/Makefile index 3381f2fb0..671d2ebb5 100644 --- a/APP_Framework/lib/JerryScript/Makefile +++ b/APP_Framework/lib/JerryScript/Makefile @@ -3,6 +3,6 @@ SRC_FILES += jerryscript/build/lib/libjerry-core.a \ jerryscript/build/lib/libjerry-ext.a \ jerryscript/build/lib/libjerry-math.a -SRC_FILES += setjmp.S jerry_port.c jerry_main.c +SRC_FILES += setjmp.S jerry_port.c jerry_main.c jerry_test.c include $(KERNEL_ROOT)/compiler.mk diff --git a/APP_Framework/lib/JerryScript/jerry_main.c b/APP_Framework/lib/JerryScript/jerry_main.c index 5503a8e75..f39fbb616 100644 --- a/APP_Framework/lib/JerryScript/jerry_main.c +++ b/APP_Framework/lib/JerryScript/jerry_main.c @@ -18,225 +18,424 @@ * @date 2023.08.07 */ -#include +#include #include #include -#include +#include -bool js_parse_test1(void* parameter) +#include "jerryscript.h" +#include "jerryscript-ext/debugger.h" +#include "jerryscript-ext/handler.h" +#include "jerryscript-port.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 + + +static void print_help(char *name) { - bool run_ok = false; + 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); +} - const jerry_char_t script[] = "var str = 'Hello, World!';"; +/** + * 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, size_t *out_size_p) +{ + 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; + } - /* Initialize engine */ - jerry_init (JERRY_INIT_EMPTY); + 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; + } - /* Setup Global scope code */ - jerry_value_t parsed_code = jerry_parse (NULL, 0, script, sizeof (script) - 1, JERRY_PARSE_NO_OPTS); + 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; + } - /* Check if there is any JS code parse error */ - if (!jerry_value_is_error (parsed_code)) + 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; +} + +/** + * Convert string into unsigned integer + * + * @return converted number + */ +static uint32_t str_to_uint (const char *num_str_p) /**< string to convert */ +{ + uint32_t result = 0; + + while (*num_str_p != '\0') + { + result *= 10; + result += (uint32_t) (*num_str_p - '0'); + num_str_p++; + } + return result; +} + +/** + * Print error value + */ +static void print_unhandled_exception (jerry_value_t error_value, const jerry_char_t *source_p) +{ + error_value = jerry_get_value_from_error (error_value, false); + jerry_value_t err_str_val = jerry_value_to_string (error_value); + jerry_size_t err_str_size = jerry_get_string_size (err_str_val); + jerry_char_t err_str_buf[256]; + + jerry_release_value (error_value); + + if (err_str_size >= 256) + { + const char msg[] = "[Error message too long]"; + err_str_size = sizeof (msg) / sizeof (char) - 1; + memcpy (err_str_buf, msg, err_str_size); + } + else + { + jerry_size_t sz = jerry_string_to_char_buffer (err_str_val, err_str_buf, err_str_size); + err_str_buf[err_str_size] = 0; + + if (jerry_is_feature_enabled (JERRY_FEATURE_ERROR_MESSAGES) + && jerry_get_error_type (error_value) == JERRY_ERROR_SYNTAX) { - /* Execute the parsed source code in the Global scope */ - jerry_value_t ret_value = jerry_run (parsed_code); + uint32_t err_line = 0; + uint32_t err_col = 0; - /* Check the execution return value if there is any error */ - run_ok = !jerry_value_is_error (ret_value); + /* 1. parse column and line information */ + for (uint32_t i = 0; i < sz; i++) + { + if (!strncmp ((char *) (err_str_buf + i), "[line: ", 7)) + { + i += 7; - /* Returned value must be freed */ - jerry_release_value (ret_value); - printf("jerry_run ret=%d\n", ret_value); + char num_str[8]; + uint32_t j = 0; + + while (i < sz && err_str_buf[i] != ',') + { + num_str[j] = (char) err_str_buf[i]; + j++; + i++; + } + num_str[j] = '\0'; + + err_line = str_to_uint (num_str); + + if (strncmp ((char *) (err_str_buf + i), ", column: ", 10)) + { + break; /* wrong position info format */ + } + + i += 10; + j = 0; + + while (i < sz && err_str_buf[i] != ']') + { + num_str[j] = (char) err_str_buf[i]; + j++; + i++; + } + num_str[j] = '\0'; + + err_col = str_to_uint (num_str); + break; + } + } /* for */ + + if (err_line != 0 && err_col != 0) + { + uint32_t curr_line = 1; + + bool is_printing_context = false; + uint32_t pos = 0; + + /* 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"); + } } - - /* Parsed source code must be freed */ - jerry_release_value (parsed_code); - - /* Cleanup engine */ - jerry_cleanup (); - - printf("run_ok is %d.\n", run_ok); - - return (run_ok ? 0 : 1); -} - -int js_parse_test2(void* parameter) -{ - int return_value = 1; - - /* Initialize engine */ - jerry_init (JERRY_INIT_EMPTY); - - /* Parse the 'function (a,b) { return a + b; }' function */ - const char function_args[] = "a, b"; - const char function_source[] = "return a * b"; - - jerry_value_t parsed_function = jerry_parse_function (NULL, - 0, - (const jerry_char_t *) function_args, - strlen (function_args), - (const jerry_char_t *) function_source, - strlen (function_source), - JERRY_PARSE_NO_OPTS); - - if (!jerry_value_is_error (parsed_function)) - { - /* Run the parsed function */ - jerry_value_t args[] = { - jerry_create_number (3), - jerry_create_number (55), - }; - jerry_size_t argc = sizeof (args) / sizeof (args[0]); - jerry_value_t ret_value = jerry_call_function (parsed_function, - jerry_create_undefined(), - args, - argc); - - /* Process result value */ - if (jerry_value_is_number (ret_value)) { - double value = jerry_get_number_value (ret_value); - printf ("Function result: %lf\n", value); - - return_value = !(value == (3 * 55)); - } - - /* Release the function arguments */ - for (jerry_size_t idx = 0; idx < argc; idx++) { - jerry_release_value (args[idx]); - } - - /* Returned value must be freed */ - jerry_release_value (ret_value); } - /* Parsed function must be freed */ - jerry_release_value (parsed_function); - - /* Cleanup engine */ - jerry_cleanup (); - - return return_value; + jerry_port_log (JERRY_LOG_LEVEL_ERROR, "Script Error: %s\n", err_str_buf); + jerry_release_value (err_str_val); } -int js_parse_test3(void* parameter) +/** + * Register a JavaScript function in the global object. + */ +static void register_js_function (const char *name_p,jerry_external_handler_t handler_p) { - jerry_init (JERRY_INIT_EMPTY); + jerry_value_t result_val = jerryx_handler_register_global ((const jerry_char_t *) name_p, handler_p); - jerry_value_t value; - // create or acquire value - value = jerry_create_string ((const jerry_char_t *) "Demo string"); - - // Read the string into a byte buffer. - jerry_size_t string_size = jerry_get_string_size (value); - jerry_char_t *string_buffer_p = (jerry_char_t *) malloc (sizeof (jerry_char_t) * (string_size + 1)); - - jerry_size_t copied_bytes = jerry_string_to_char_buffer (value, string_buffer_p, string_size); - string_buffer_p[copied_bytes] = '\0'; - - jerry_release_value (value); - - jerry_cleanup (); - - printf ("Test string: %s\n", string_buffer_p); - free (string_buffer_p); - - return 0; -} - - -static int counter = 0; - -static jerry_value_t -method_getter (const jerry_value_t this_obj, - const jerry_value_t func_obj, - const jerry_value_t args[], - const jerry_length_t argc) -{ - counter++; - printf("Getter called, returning: %d\n", counter); - - return jerry_create_number (counter); -} - -static jerry_value_t -method_setter (const jerry_value_t this_obj, - const jerry_value_t func_obj, - const jerry_value_t args[], - const jerry_length_t argc) -{ - // Note: the arguments count and type should be checked - // in this example it is ommitted! - - double new_value = jerry_get_number_value (args[0]); - counter = (int) new_value; - - printf("Setter called, setting: %d\n", counter); - - return jerry_create_undefined (); -} - -int js_parse_test4(void* parameter) -{ - jerry_init (JERRY_INIT_EMPTY); - - jerry_value_t global_obj_val = jerry_get_global_object (); - - // configure the property - jerry_property_descriptor_t prop_desc; - jerry_init_property_descriptor_fields (&prop_desc); - - // set the property descriptor fields: - - prop_desc.is_get_defined = true; - prop_desc.getter = jerry_create_external_function (method_getter); - prop_desc.is_set_defined = true; - prop_desc.setter = jerry_create_external_function (method_setter); - - // add the property as "my_prop" for the global object - jerry_value_t prop_name = jerry_create_string ((const jerry_char_t *) "my_prop"); - jerry_value_t return_value = jerry_define_own_property (global_obj_val, prop_name, &prop_desc); - if (jerry_value_is_error (return_value)) + if (jerry_value_is_error (result_val)) { - // there was an error + jerry_port_log (JERRY_LOG_LEVEL_WARNING, "Warning: failed to register '%s' method.", name_p); } - // if there was no error at this point the global object should have a "my_prop" property + jerry_release_value (result_val); +} - jerry_release_value (return_value); - jerry_release_value (prop_name); +static jerry_log_level_t jerry_log_level = JERRY_LOG_LEVEL_ERROR; - jerry_free_property_descriptor_fields (&prop_desc); - jerry_release_value (global_obj_val); - // run an example js code to use the getter/setters +int jerrytest(int argc, char *argv[]) +{ + 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); - const char *src_p = "this.my_prop; this.my_prop; this.my_prop = 4; this.my_prop"; - jerry_value_t eval_result = jerry_eval ((const jerry_char_t *) src_p, strlen (src_p), JERRY_PARSE_NO_OPTS); + return JERRY_STANDALONE_EXIT_CODE_FAIL; + } - // "eval_result" is the last result of "this.my_prop" that is "5" currently. - double result_number = jerry_get_number_value (eval_result); - printf("output: %lf\n", result_number); + 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_level = JERRY_LOG_LEVEL_DEBUG; + } + else if (!strcmp ("--mem-stats-separate", argv[i])) + { + flags |= JERRY_INIT_MEM_STATS_SEPARATE; + jerry_log_level = JERRY_LOG_LEVEL_DEBUG; + } + else if (!strcmp ("--show-opcodes", argv[i])) + { + flags |= JERRY_INIT_SHOW_OPCODES | JERRY_INIT_SHOW_REGEXP_OPCODES; + jerry_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') + { + jerry_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]); + } + 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 ("gc", jerryx_handler_gc); + register_js_function ("print", jerryx_handler_print); + + jerry_value_t ret_value = jerry_create_undefined (); + + if (files_counter == 0) + { + printf ("running a hello world demo:"); + const jerry_char_t script[] = "var str = 'Hello World'; print(str + ' from JerryScript.')"; + + ret_value = jerry_parse (NULL, 0, script, sizeof (script) - 1, JERRY_PARSE_NO_OPTS); + + if (!jerry_value_is_error (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; + } + + ret_value = jerry_parse ((jerry_char_t *) file_names[i], + strlen (file_names[i]), + source_p, + source_size, + JERRY_PARSE_NO_OPTS); + + if (!jerry_value_is_error (ret_value)) + { + jerry_value_t func_val = ret_value; + ret_value = jerry_run (func_val); + jerry_release_value (func_val); + } + + if (jerry_value_is_error (ret_value)) + { + print_unhandled_exception (ret_value, source_p); + free ((void*) source_p); + + break; + } + + free ((void*) source_p); + + jerry_release_value (ret_value); + ret_value = jerry_create_undefined (); + } + } + + int ret_code = JERRY_STANDALONE_EXIT_CODE_OK; + + if (jerry_value_is_error (ret_value)) + { + ret_code = JERRY_STANDALONE_EXIT_CODE_FAIL; + } + + jerry_release_value (ret_value); + + ret_value = jerry_run_all_enqueued_jobs (); + + if (jerry_value_is_error (ret_value)) + { + ret_code = JERRY_STANDALONE_EXIT_CODE_FAIL; + } + + jerry_release_value (ret_value); jerry_cleanup (); - return result_number != 5.0; - return 0; + return ret_code; } -void jstest(void) -{ - int ret; - pthread_t thread; - pthread_attr_t attr; - attr.schedparam.sched_priority = 22; - attr.stacksize = 8192; - int32 task = 0; - - ret = PrivTaskCreate(&thread, &attr, (void*)js_parse_test4, NULL); - if (ret < 0) { - printf("taskcreate failed, status=%d\n", ret); - return; - } -} -PRIV_SHELL_CMD_FUNCTION(jstest, jerryscript test cmd, PRIV_SHELL_CMD_FUNC_ATTR); +PRIV_SHELL_CMD_FUNCTION(jerrytest, jerryscript test sample, PRIV_SHELL_CMD_MAIN_ATTR); diff --git a/APP_Framework/lib/JerryScript/jerry_test.c b/APP_Framework/lib/JerryScript/jerry_test.c new file mode 100644 index 000000000..9a48d8dfa --- /dev/null +++ b/APP_Framework/lib/JerryScript/jerry_test.c @@ -0,0 +1,271 @@ +/* + * Copyright (c) 2022 AIIT XUOS Lab + * XiUOS is licensed under Mulan PSL v2. + * You can use this software according to the terms and conditions of the Mulan PSL v2. + * You may obtain a copy of Mulan PSL v2 at: + * http://license.coscl.org.cn/MulanPSL2 + * THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, + * EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, + * MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE. + * See the Mulan PSL v2 for more details. + */ + +/** + * @file jerry_test.c + * @brief support jerryscript + * @version 1.0 + * @author AIIT XUOS Lab + * @date 2023.08.07 + */ +#include +#include +#include +#include "jerryscript.h" +#include "jerryscript-ext/handler.h" + +bool js_parse_test1(void* parameter) +{ + bool run_ok = false; + + const jerry_char_t script[] = "var str = 'Hello, World!';"; + + /* Initialize engine */ + jerry_init (JERRY_INIT_EMPTY); + + /* Setup Global scope code */ + jerry_value_t parsed_code = jerry_parse (NULL, 0, script, sizeof (script) - 1, JERRY_PARSE_NO_OPTS); + + /* Check if there is any JS code parse error */ + if (!jerry_value_is_error (parsed_code)) + { + /* Execute the parsed source code in the Global scope */ + jerry_value_t ret_value = jerry_run (parsed_code); + + /* Check the execution return value if there is any error */ + run_ok = !jerry_value_is_error (ret_value); + + /* Returned value must be freed */ + jerry_release_value (ret_value); + printf("jerry_run ret=%d\n", ret_value); + } + + /* Parsed source code must be freed */ + jerry_release_value (parsed_code); + + /* Cleanup engine */ + jerry_cleanup (); + + printf("run_ok is %d.\n", run_ok); + + return (run_ok ? 0 : 1); +} + +int js_parse_test2(void* parameter) +{ + int return_value = 1; + + /* Initialize engine */ + jerry_init (JERRY_INIT_EMPTY); + + /* Parse the 'function (a,b) { return a + b; }' function */ + const char function_args[] = "a, b"; + const char function_source[] = "return a * b"; + + jerry_value_t parsed_function = jerry_parse_function (NULL, + 0, + (const jerry_char_t *) function_args, + strlen (function_args), + (const jerry_char_t *) function_source, + strlen (function_source), + JERRY_PARSE_NO_OPTS); + + if (!jerry_value_is_error (parsed_function)) + { + /* Run the parsed function */ + jerry_value_t args[] = { + jerry_create_number (3), + jerry_create_number (55), + }; + jerry_size_t argc = sizeof (args) / sizeof (args[0]); + jerry_value_t ret_value = jerry_call_function (parsed_function, + jerry_create_undefined(), + args, + argc); + + /* Process result value */ + if (jerry_value_is_number (ret_value)) { + double value = jerry_get_number_value (ret_value); + printf ("Function result: %lf\n", value); + + return_value = !(value == (3 * 55)); + } + + /* Release the function arguments */ + for (jerry_size_t idx = 0; idx < argc; idx++) { + jerry_release_value (args[idx]); + } + + /* Returned value must be freed */ + jerry_release_value (ret_value); + } + + /* Parsed function must be freed */ + jerry_release_value (parsed_function); + + /* Cleanup engine */ + jerry_cleanup (); + + return return_value; +} + + +int js_parse_test3(void* parameter) +{ + jerry_init (JERRY_INIT_EMPTY); + + jerry_value_t value; + // create or acquire value + value = jerry_create_string ((const jerry_char_t *) "Demo string"); + + // Read the string into a byte buffer. + jerry_size_t string_size = jerry_get_string_size (value); + jerry_char_t *string_buffer_p = (jerry_char_t *) malloc (sizeof (jerry_char_t) * (string_size + 1)); + + jerry_size_t copied_bytes = jerry_string_to_char_buffer (value, string_buffer_p, string_size); + string_buffer_p[copied_bytes] = '\0'; + + jerry_release_value (value); + + jerry_cleanup (); + + printf ("Test string: %s\n", string_buffer_p); + free (string_buffer_p); + + return 0; +} + + +static int counter = 0; + +static jerry_value_t +method_getter (const jerry_value_t this_obj, + const jerry_value_t func_obj, + const jerry_value_t args[], + const jerry_length_t argc) +{ + counter++; + printf("Getter called, returning: %d\n", counter); + + return jerry_create_number (counter); +} + +static jerry_value_t +method_setter (const jerry_value_t this_obj, + const jerry_value_t func_obj, + const jerry_value_t args[], + const jerry_length_t argc) +{ + // Note: the arguments count and type should be checked + // in this example it is ommitted! + + double new_value = jerry_get_number_value (args[0]); + counter = (int) new_value; + + printf("Setter called, setting: %d\n", counter); + + return jerry_create_undefined (); +} + +int js_parse_test4(void* parameter) +{ + jerry_init (JERRY_INIT_EMPTY); + + jerry_value_t global_obj_val = jerry_get_global_object (); + + // configure the property + jerry_property_descriptor_t prop_desc; + jerry_init_property_descriptor_fields (&prop_desc); + + // set the property descriptor fields: + + prop_desc.is_get_defined = true; + prop_desc.getter = jerry_create_external_function (method_getter); + prop_desc.is_set_defined = true; + prop_desc.setter = jerry_create_external_function (method_setter); + + // add the property as "my_prop" for the global object + jerry_value_t prop_name = jerry_create_string ((const jerry_char_t *) "my_prop"); + jerry_value_t return_value = jerry_define_own_property (global_obj_val, prop_name, &prop_desc); + if (jerry_value_is_error (return_value)) + { + // there was an error + } + + // if there was no error at this point the global object should have a "my_prop" property + + jerry_release_value (return_value); + jerry_release_value (prop_name); + + jerry_free_property_descriptor_fields (&prop_desc); + jerry_release_value (global_obj_val); + + // run an example js code to use the getter/setters + + const char *src_p = "this.my_prop; this.my_prop; this.my_prop = 4; this.my_prop"; + jerry_value_t eval_result = jerry_eval ((const jerry_char_t *) src_p, strlen (src_p), JERRY_PARSE_NO_OPTS); + + // "eval_result" is the last result of "this.my_prop" that is "5" currently. + double result_number = jerry_get_number_value (eval_result); + printf("output: %lf\n", result_number); + + jerry_cleanup (); + + return result_number != 5.0; +} + +int js_parse_test5(void* parameter) +{ + const jerry_char_t script[] = "print ('Hello, World!');"; + + /* Initialize engine */ + jerry_init (JERRY_INIT_EMPTY); + + /* Register 'print' function from the extensions */ + jerryx_handler_register_global ((const jerry_char_t *) "print",jerryx_handler_print); + + /* Setup Global scope code */ + jerry_value_t parsed_code = jerry_parse (NULL, 0, script, sizeof (script) - 1, JERRY_PARSE_NO_OPTS); + + if (!jerry_value_is_error (parsed_code)) + { + /* Execute the parsed source code in the Global scope */ + jerry_value_t ret_value = jerry_run (parsed_code); + + /* Returned value must be freed */ + jerry_release_value (ret_value); + } + + /* Parsed source code must be freed */ + jerry_release_value (parsed_code); + + /* Cleanup engine */ + jerry_cleanup (); + return 0; +} + +void jstest(void) +{ + int ret; + pthread_t thread; + pthread_attr_t attr; + attr.schedparam.sched_priority = 22; + attr.stacksize = 8192; + int32 task = 0; + + ret = PrivTaskCreate(&thread, &attr, (void*)js_parse_test5, NULL); + if (ret < 0) { + printf("taskcreate failed, status=%d\n", ret); + return; + } +} +PRIV_SHELL_CMD_FUNCTION(jstest, jerryscript test cmd, PRIV_SHELL_CMD_FUNC_ATTR);