-
Notifications
You must be signed in to change notification settings - Fork 683
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], | ||
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. 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 :) 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. 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? 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. 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? 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; | ||
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))) | ||
{ | ||
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) | ||
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); | ||
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:
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 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