-
Notifications
You must be signed in to change notification settings - Fork 686
Initial refactoring of the code to match the latest API. #1212
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -16,7 +16,7 @@ | |
| #include <stdlib.h> | ||
| #include <stdio.h> | ||
|
|
||
| #include "jerry-core/jerry.h" | ||
| #include "jerry-core/jerry-api.h" | ||
| #include "jerry_extapi.h" | ||
|
|
||
| #include "native_esp8266.h" | ||
|
|
@@ -31,12 +31,11 @@ | |
| #define __UNSED__ __attribute__((unused)) | ||
|
|
||
| #define DELCARE_HANDLER(NAME) \ | ||
| static bool \ | ||
| NAME ## _handler (const jerry_api_object_t * function_obj_p __UNSED__, \ | ||
| const jerry_api_value_t * this_p __UNSED__, \ | ||
| jerry_api_value_t * ret_val_p __UNSED__, \ | ||
| const jerry_api_value_t args_p[], \ | ||
| const jerry_api_length_t args_cnt) | ||
| static jerry_value_t \ | ||
| NAME ## _handler (const jerry_value_t function_obj_val __UNSED__, \ | ||
| const jerry_value_t this_val __UNSED__, \ | ||
| const jerry_value_t args_p[], \ | ||
| const jerry_length_t args_cnt) | ||
|
|
||
| #define REGISTER_HANDLER(NAME) \ | ||
| register_native_function ( # NAME, NAME ## _handler) | ||
|
|
@@ -45,46 +44,54 @@ NAME ## _handler (const jerry_api_object_t * function_obj_p __UNSED__, \ | |
|
|
||
| DELCARE_HANDLER(assert) { | ||
| if (args_cnt == 1 | ||
| && args_p[0].type == JERRY_API_DATA_TYPE_BOOLEAN | ||
| && args_p[0].u.v_bool == true) | ||
| && jerry_value_is_boolean (args_p[0]) | ||
| && jerry_get_boolean_value (args_p[0])) | ||
| { | ||
| printf (">> Jerry assert true\r\n"); | ||
| return true; | ||
| return jerry_create_boolean (true); | ||
| } | ||
| printf ("Script assertion failed\n"); | ||
| exit (JERRY_STANDALONE_EXIT_CODE_FAIL); | ||
| return false; | ||
| return jerry_create_boolean (false); | ||
| } | ||
|
|
||
|
|
||
| DELCARE_HANDLER(print) { | ||
| jerry_api_length_t cc; | ||
| jerry_length_t cc; | ||
|
|
||
| if (args_cnt) | ||
| { | ||
| printf(">> print(%d) :", (int)args_cnt); | ||
| printf(">> print(%d) :", (int) args_cnt); | ||
| for (cc=0; cc<args_cnt; cc++) | ||
| { | ||
| if (args_p[cc].type == JERRY_API_DATA_TYPE_STRING && args_p[cc].u.v_string) | ||
| if (jerry_value_is_string (args_p[cc])) | ||
| { | ||
| static char buffer[128]; | ||
| jerry_api_size_t length, maxlength; | ||
| length = -jerry_api_string_to_char_buffer (args_p[0].u.v_string, NULL, 0); | ||
| maxlength = MIN(length, 126); | ||
| jerry_api_string_to_char_buffer (args_p[cc].u.v_string, | ||
| (jerry_api_char_t *) buffer, | ||
| maxlength); | ||
| *(buffer + length) = 0; | ||
| char *buffer; | ||
| jerry_size_t size = jerry_get_string_size (args_p[0]); | ||
| buffer = (char *) malloc(size + 1); | ||
|
|
||
| if(!buffer) | ||
| { | ||
| // not enough memory for this string. | ||
| printf("[<too-long-string>]"); | ||
| continue; | ||
| } | ||
|
|
||
| jerry_string_to_char_buffer (args_p[cc], | ||
|
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I hope you are aware that if the buffer is too small, no bytes are copied.
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. the line above should do the trick :)
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Do the trick? I mean if string length > 126, than MIN() returns with 126, and no bytes will be copied since buffer is too small.
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I guess the initial code was to allow the native "print" function to print string(s) with max length of 128 characters. What do you suggest to be changed here?
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. You can allocate a large enough buffer with malloc, or you can just print that string is too long.
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. @zherczeg, the current code will load maximum 126 bytes into a 128 bytes buffer. How could it be too small?
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. BTW, I agree that it would look nicer, if we always allocate the buffer with the appropriate size. I'm just trying to say here the current code is valid and should work. :) |
||
| (jerry_char_t *) buffer, | ||
| size); | ||
| *(buffer + size) = 0; | ||
|
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. No the code is unfortunately not correct. This expression can be a buffer overrun, and a byte on the stack will be replaced with 0. But even if we change size to maxsize, a random character sequence will be printed for strings > 126 bytes. |
||
| printf("[%s] ", buffer); | ||
| free (buffer); | ||
| } | ||
| else | ||
| { | ||
| printf ("(%d) ", args_p[cc].type); | ||
| printf ("(%d) ", args_p[cc]); | ||
| } | ||
| } | ||
| printf ("\r\n"); | ||
| } | ||
| return true; | ||
| return jerry_create_boolean (true); | ||
| } | ||
|
|
||
|
|
||
|
|
@@ -97,27 +104,27 @@ DELCARE_HANDLER(gpio_dir) { | |
| return false; | ||
| } | ||
|
|
||
| port = (int)JS_VALUE_TO_NUMBER (&args_p[0]); | ||
| value = (int)JS_VALUE_TO_NUMBER (&args_p[1]); | ||
| port = (int) jerry_get_number_value (args_p[0]); | ||
| value = (int) jerry_get_number_value (args_p[1]); | ||
|
|
||
| native_gpio_dir (port, value); | ||
|
|
||
| return true; | ||
| return jerry_create_boolean (true); | ||
| } /* gpio_dir_handler */ | ||
|
|
||
| DELCARE_HANDLER(gpio_set) { | ||
| int port, value; | ||
| if (args_cnt < 2) | ||
| { | ||
| return false; | ||
| return jerry_create_boolean (false); | ||
| } | ||
|
|
||
| port = (int)JS_VALUE_TO_NUMBER (&args_p[0]); | ||
| value = (int)JS_VALUE_TO_NUMBER (&args_p[1]); | ||
| port = (int) jerry_get_number_value (args_p[0]); | ||
| value = (int) jerry_get_number_value (args_p[1]); | ||
|
|
||
| native_gpio_set (port, value); | ||
|
|
||
| return true; | ||
| return jerry_create_boolean (true); | ||
| } /* gpio_dir_handler */ | ||
|
|
||
|
|
||
|
|
@@ -128,14 +135,11 @@ DELCARE_HANDLER(gpio_get) { | |
| return false; | ||
| } | ||
|
|
||
| port = (int)JS_VALUE_TO_NUMBER (&args_p[0]); | ||
| port = (int) jerry_get_number_value (args_p[0]); | ||
|
|
||
| value = native_gpio_get (port) ? 1 : 0; | ||
|
|
||
| ret_val_p->type = JERRY_API_DATA_TYPE_FLOAT64; | ||
| ret_val_p->u.v_float64 = (double)value; | ||
|
|
||
| return true; | ||
| return jerry_create_number ((double) value); | ||
| } /* gpio_dir_handler */ | ||
|
|
||
|
|
||
|
|
@@ -145,34 +149,37 @@ static bool | |
| register_native_function (const char* name, | ||
| jerry_external_handler_t handler) | ||
| { | ||
| jerry_api_object_t *global_obj_p; | ||
| jerry_api_object_t *reg_func_p; | ||
| jerry_api_value_t reg_value; | ||
| jerry_value_t global_obj_val; | ||
| jerry_value_t reg_func_val; | ||
| jerry_value_t prop_name_val; | ||
| jerry_value_t res; | ||
| bool bok; | ||
|
|
||
| global_obj_p = jerry_api_get_global (); | ||
| reg_func_p = jerry_api_create_external_function (handler); | ||
| global_obj_val = jerry_get_global_object (); | ||
| reg_func_val = jerry_create_external_function (handler); | ||
| bok = true; | ||
|
|
||
| if (!(reg_func_p != NULL | ||
| && jerry_api_is_function (reg_func_p) | ||
| && jerry_api_is_constructor (reg_func_p))) | ||
| if (!(jerry_value_is_function (reg_func_val) | ||
| && jerry_value_is_constructor (reg_func_val))) | ||
| { | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. if (!(jerry_value_is_function (reg_func_val)
&& jerry_value_is_constructor (reg_func_val))) { |
||
| printf ("!!! create_external_function failed !!!\r\n"); | ||
| jerry_api_release_object (global_obj_p); | ||
| jerry_release_value (reg_func_val); | ||
| jerry_release_value (global_obj_val); | ||
| return false; | ||
| } | ||
|
|
||
| jerry_api_acquire_object (reg_func_p); | ||
| reg_value.type = JERRY_API_DATA_TYPE_OBJECT; | ||
| reg_value.u.v_object = reg_func_p; | ||
| prop_name_val = jerry_create_string ((const jerry_char_t *) name); | ||
| res = jerry_set_property (global_obj_val, prop_name_val, reg_func_val); | ||
|
|
||
| bok = jerry_api_set_object_field_value (global_obj_p, | ||
| (jerry_api_char_t *)name, | ||
| ®_value); | ||
| if (jerry_value_has_error_flag (res)) | ||
| { | ||
| bok = false; | ||
| } | ||
|
|
||
| jerry_api_release_value (®_value); | ||
| jerry_api_release_object (reg_func_p); | ||
| jerry_api_release_object (global_obj_p); | ||
| jerry_release_value (res); | ||
| jerry_release_value (prop_name_val); | ||
| jerry_release_value (reg_func_val); | ||
| jerry_release_value (global_obj_val); | ||
|
|
||
| if (!bok) | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
|
||
| { | ||
|
|
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -16,105 +16,101 @@ | |
| #include <stdlib.h> | ||
| #include <stdio.h> | ||
|
|
||
| #include "jerry-core/jerry.h" | ||
| #include "jerry-core/jerry-api.h" | ||
| #include "jerry_extapi.h" | ||
| #include "jerry_run.h" | ||
|
|
||
|
|
||
| static const char* fn_sys_loop_name = "sysloop"; | ||
| jerry_value_t parsed_res; | ||
|
|
||
|
|
||
| /*---------------------------------------------------------------------------*/ | ||
|
|
||
| int js_entry (const char *source_p, const size_t source_size) | ||
| { | ||
| const jerry_api_char_t *jerry_src = (const jerry_api_char_t *) source_p; | ||
| jerry_completion_code_t ret_code = JERRY_COMPLETION_CODE_OK; | ||
| jerry_flag_t flags = JERRY_FLAG_EMPTY; | ||
| jerry_api_object_t *err_obj_p = NULL; | ||
| const jerry_char_t *jerry_src = (const jerry_char_t *) source_p; | ||
| int ret_code = 0; /* JERRY_COMPLETION_CODE_OK */ | ||
| jerry_init_flag_t flags = JERRY_INIT_EMPTY; | ||
|
|
||
| jerry_init (flags); | ||
|
|
||
| js_register_functions (); | ||
|
|
||
| if (!jerry_parse ((jerry_api_char_t *)jerry_src, source_size, &err_obj_p)) | ||
| parsed_res = jerry_parse ((jerry_char_t *) jerry_src, source_size, false); | ||
|
|
||
| if (jerry_value_has_error_flag (parsed_res)) | ||
| { | ||
| printf ("Error: jerry_parse failed\r\n"); | ||
| ret_code = JERRY_COMPLETION_CODE_UNHANDLED_EXCEPTION; | ||
| } | ||
| else | ||
| { | ||
| if ((flags & JERRY_FLAG_PARSE_ONLY) == 0) | ||
| { | ||
| jerry_api_value_t err_value = jerry_api_create_void_value (); | ||
| ret_code = jerry_run (&err_value); | ||
| } | ||
| ret_code = JERRY_ERROR_SYNTAX; | ||
| } | ||
|
|
||
| return ret_code; | ||
| } | ||
|
|
||
| int js_eval (const char *source_p, const size_t source_size) | ||
| { | ||
| jerry_completion_code_t status; | ||
| jerry_api_value_t res; | ||
| int status = 0; | ||
| jerry_value_t res; | ||
|
|
||
| status = jerry_api_eval ((jerry_api_char_t *) source_p, | ||
| res = jerry_eval ((jerry_char_t *) source_p, | ||
| source_size, | ||
| false, | ||
| false, | ||
| &res); | ||
| false); | ||
| if (jerry_value_has_error_flag (res)) { | ||
| status = -1; | ||
| } | ||
|
|
||
| jerry_api_release_value (&res); | ||
| jerry_release_value (res); | ||
|
|
||
| return status; | ||
| } | ||
|
|
||
| int js_loop (uint32_t ticknow) | ||
| { | ||
| jerry_api_object_t *global_obj_p; | ||
| jerry_api_value_t sysloop_func; | ||
| jerry_api_value_t* val_args; | ||
| jerry_value_t global_obj_val; | ||
| jerry_value_t sysloop_func; | ||
| jerry_value_t val_args[1]; | ||
| uint16_t val_argv; | ||
| jerry_api_value_t res; | ||
| bool is_ok; | ||
|
|
||
| global_obj_p = jerry_api_get_global (); | ||
| is_ok = jerry_api_get_object_field_value (global_obj_p, | ||
| (const jerry_api_char_t*)fn_sys_loop_name, | ||
| &sysloop_func); | ||
| if (!is_ok) | ||
| { | ||
| jerry_value_t res; | ||
| jerry_value_t prop_name_val; | ||
| int ret_code = 0; | ||
|
|
||
| global_obj_val = jerry_get_global_object (); | ||
| prop_name_val = jerry_create_string ((const jerry_char_t *) fn_sys_loop_name); | ||
| sysloop_func = jerry_get_property (global_obj_val, prop_name_val); | ||
| jerry_release_value (prop_name_val); | ||
|
|
||
| if (jerry_value_has_error_flag (sysloop_func)) { | ||
| printf ("Error: '%s' not defined!!!\r\n", fn_sys_loop_name); | ||
| jerry_api_release_object (global_obj_p); | ||
| jerry_release_value (sysloop_func); | ||
| jerry_release_value (global_obj_val); | ||
| return -1; | ||
| } | ||
|
|
||
| if (!API_DATA_IS_FUNCTION (&sysloop_func)) | ||
| { | ||
| if (!jerry_value_is_function (sysloop_func)) { | ||
| printf ("Error: '%s' is not a function!!!\r\n", fn_sys_loop_name); | ||
| jerry_api_release_value (&sysloop_func); | ||
| jerry_api_release_object (global_obj_p); | ||
| jerry_release_value (sysloop_func); | ||
| jerry_release_value (global_obj_val); | ||
| return -2; | ||
| } | ||
|
|
||
| val_argv = 1; | ||
| val_args = (jerry_api_value_t*)malloc (sizeof (jerry_api_value_t) * val_argv); | ||
| val_args[0].type = JERRY_API_DATA_TYPE_UINT32; | ||
| val_args[0].u.v_uint32 = ticknow; | ||
|
|
||
| is_ok = jerry_api_call_function (sysloop_func.u.v_object, | ||
| global_obj_p, | ||
| &res, | ||
| val_args, | ||
| val_argv); | ||
| jerry_api_release_value (&res); | ||
| free (val_args); | ||
|
|
||
| jerry_api_release_value (&sysloop_func); | ||
| jerry_api_release_object (global_obj_p); | ||
|
|
||
| return 0; | ||
| val_args[0] = jerry_create_number (ticknow); | ||
|
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. You could use a stack allocated array here:
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. @zherczeg you mean
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Of course. Sorry. |
||
|
|
||
| res = jerry_call_function (sysloop_func, | ||
| global_obj_val, | ||
| val_args, | ||
| val_argv); | ||
|
|
||
| if (jerry_value_has_error_flag (res)) { | ||
| ret_code = -3; | ||
| } | ||
|
|
||
| jerry_release_value (res); | ||
| jerry_release_value (sysloop_func); | ||
| jerry_release_value (global_obj_val); | ||
|
|
||
| return ret_code; | ||
| } | ||
|
|
||
| void js_exit (void) | ||
|
|
||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
ditto