mirror of https://github.com/arendst/Tasmota.git
Berry improvement to constants
This commit is contained in:
parent
a538f35df4
commit
fb59c63084
|
@ -37,9 +37,10 @@ extern "C" {
|
|||
.v.nf = (_func), \
|
||||
.type = BE_NTVFUNC \
|
||||
}
|
||||
typedef const void * constptr;
|
||||
|
||||
typedef const void* be_constptr;
|
||||
#define be_const_ctype_func(_f, ...) { \
|
||||
.v.nf = ((const void*) &(constptr[]) { _f, __VA_ARGS__ }), \
|
||||
.v.nf = ((const void*) &(be_constptr[]) { _f, __VA_ARGS__ }),\
|
||||
.type = BE_CTYPE_FUNC \
|
||||
}
|
||||
|
||||
|
@ -259,10 +260,9 @@ const bntvmodule be_native_module(_module) = { \
|
|||
BE_NTVFUNC \
|
||||
}
|
||||
|
||||
typedef const void * constptr;
|
||||
#define be_const_ctype_func(_f, ...) { \
|
||||
bvaldata(((const void*) \
|
||||
&(constptr[]) { (const void*) _f, __VA_ARGS__ })), \
|
||||
&((const void *)[]) { (const void*) _f, __VA_ARGS__ })), \
|
||||
BE_CTYPE_FUNC \
|
||||
}
|
||||
|
||||
|
|
|
@ -13,6 +13,9 @@
|
|||
#include "be_exec.h"
|
||||
#include <string.h>
|
||||
|
||||
typedef intptr_t (*fn_any_callable)(intptr_t p0, intptr_t p1, intptr_t p2, intptr_t p3,
|
||||
intptr_t p4, intptr_t p5, intptr_t p6, intptr_t p7);
|
||||
|
||||
/*********************************************************************************************\
|
||||
* Converision from real <-> int
|
||||
*
|
||||
|
@ -161,7 +164,7 @@ int be_find_global_or_module_member(bvm *vm, const char * name) {
|
|||
// read a single value at stack position idx, convert to int.
|
||||
// if object instance, get `_p` member and convert it recursively
|
||||
intptr_t be_convert_single_elt(bvm *vm, int idx, const char * arg_type, int *buf_len) {
|
||||
// berry_log_C("be_convert_single_elt(idx=%i, argtype='%s', type=%s", idx, arg_type ? arg_type : "", be_typename(vm, idx));
|
||||
// berry_log_C("be_convert_single_elt(idx=%i, argtype='%s', type=%s)", idx, arg_type ? arg_type : "", be_typename(vm, idx));
|
||||
int ret = 0;
|
||||
char provided_type = 0;
|
||||
idx = be_absindex(vm, idx); // make sure we have an absolute index
|
||||
|
@ -233,7 +236,7 @@ intptr_t be_convert_single_elt(bvm *vm, int idx, const char * arg_type, int *buf
|
|||
if (!be_getmember(vm, idx, "_p")) {
|
||||
be_pop(vm, 1); // remove `nil`
|
||||
be_getmember(vm, idx, ".p");
|
||||
}
|
||||
} // else `nil` is on top of stack
|
||||
int32_t ret = be_convert_single_elt(vm, -1, NULL, NULL); // recurse
|
||||
be_pop(vm, 1);
|
||||
|
||||
|
@ -347,12 +350,12 @@ int be_check_arg_type(bvm *vm, int arg_start, int argc, const char * arg_type, i
|
|||
arg_idx++;
|
||||
}
|
||||
}
|
||||
// AddLog(LOG_LEVEL_INFO, ">> be_call_c_func arg %i, type %s", i, arg_type_check ? type_short_name : "<null>");
|
||||
// berry_log_C(">> be_call_c_func arg %i, type %s", i, arg_type_check ? type_short_name : "<null>");
|
||||
p[p_idx] = be_convert_single_elt(vm, i + arg_start, arg_type_check ? type_short_name : NULL, &buf_len);
|
||||
// berry_log_C("< ret[%i]=%i", p_idx, p[p_idx]);
|
||||
p_idx++;
|
||||
|
||||
if (arg_type[arg_idx] == '~') { // if next argument is virtual
|
||||
if (arg_type && arg_type[arg_idx] == '~') { // if next argument is virtual
|
||||
if (buf_len < 0) {
|
||||
be_raisef(vm, "value_error", "no bytes() length known");
|
||||
}
|
||||
|
@ -363,7 +366,7 @@ int be_check_arg_type(bvm *vm, int arg_start, int argc, const char * arg_type, i
|
|||
}
|
||||
|
||||
// check if we are missing arguments
|
||||
if (!arg_optional && arg_type != NULL && arg_type[arg_idx] != 0) {
|
||||
if (!arg_optional && arg_type && arg_type[arg_idx] != 0) {
|
||||
be_raisef(vm, "value_error", "Missing arguments, remaining type '%s'", &arg_type[arg_idx]);
|
||||
}
|
||||
return p_idx;
|
||||
|
@ -399,18 +402,11 @@ static void be_set_ctor_ptr(bvm *vm, void * ptr, const char *name) {
|
|||
}
|
||||
}
|
||||
|
||||
/* C arguments are coded as an array of 3 pointers */
|
||||
typedef struct ctype_args {
|
||||
void* func;
|
||||
const char* return_type;
|
||||
const char* arg_type;
|
||||
} ctype_args;
|
||||
|
||||
/*********************************************************************************************\
|
||||
* CType handler for Berry
|
||||
\*********************************************************************************************/
|
||||
int be_call_ctype_func(bvm *vm, const void *definition) {
|
||||
ctype_args* args = (ctype_args*) definition;
|
||||
be_ctype_args* args = (be_ctype_args*) definition;
|
||||
return be_call_c_func(vm, args->func, args->return_type, args->arg_type);
|
||||
}
|
||||
|
||||
|
@ -449,8 +445,8 @@ int be_call_c_func(bvm *vm, const void * func, const char * return_type, const c
|
|||
}
|
||||
}
|
||||
|
||||
fn_any_callable f = (fn_any_callable) func; // when returning a bytes buffer, this holds the length of the buffer, while the return value of the function is `void*`
|
||||
size_t return_len = 0;
|
||||
fn_any_callable f = (fn_any_callable) func;
|
||||
size_t return_len = 0; // when returning a bytes buffer, this holds the length of the buffer, while the return value of the function is `void*`
|
||||
int c_args = be_check_arg_type(vm, arg_start, arg_count, arg_type, p);
|
||||
if (return_type != NULL && return_type[0] == '&') {
|
||||
if (c_args < 8) { p[c_args] = (intptr_t) &return_len; }
|
||||
|
|
|
@ -13,9 +13,11 @@
|
|||
* Returns true if a match was found. In such case the result is on Berry stack
|
||||
*
|
||||
* Encoding depend on prefix (which is skipped when matching names):
|
||||
* 1. `COLOR_WHITE` int value
|
||||
* 3. `$SYMBOL_OK"` string pointer
|
||||
* 4. `&seg7_font` comptr
|
||||
* - `COLOR_WHITE` int value
|
||||
* - `$SYMBOL_OK"` string pointer
|
||||
* - `&seg7_font` comptr
|
||||
* - `*my_func` native function - the function is called and return value passed back.
|
||||
* This allows to create dynamic virtual members that are the result of a call.
|
||||
\*********************************************************************************************/
|
||||
|
||||
#include "be_mapping.h"
|
||||
|
@ -29,16 +31,19 @@
|
|||
* berry stack at position 1.
|
||||
*
|
||||
* Encoding depend on prefix (which is skipped when matching names):
|
||||
* 1. `COLOR_WHITE` int value
|
||||
* 3. `$SYMBOL_OK"` string pointer
|
||||
* 4. `&seg7_font` comptr
|
||||
* - `COLOR_WHITE` int value
|
||||
* - `$SYMBOL_OK"` string pointer
|
||||
* - `&seg7_font` comptr
|
||||
* - `*my_func` native function - the function is called and return value passed back.
|
||||
* This allows to create dynamic virtual members that are the result of a call.
|
||||
*
|
||||
* The array must be lexically sorted, but the sort function must ignore the prefix `$` or `&`
|
||||
* The array must be lexically sorted, but the sort function must ignore the prefix `$`, `&`, `*`
|
||||
\*********************************************************************************************/
|
||||
bbool be_const_member(bvm *vm, const be_const_member_t * definitions, size_t def_len) {
|
||||
static bbool be_const_member_dual(bvm *vm, const be_const_member_t * definitions, size_t def_len, bbool is_method) {
|
||||
int32_t arg_idx = is_method ? 2 : 1; // index for name argument, 1 if module, 2 if method since 1 is self.
|
||||
int32_t argc = be_top(vm); // Get the number of arguments
|
||||
if (argc == 1 && be_isstring(vm, 1)) {
|
||||
const char * needle = be_tostring(vm, 1);
|
||||
if (argc == arg_idx && be_isstring(vm, arg_idx)) {
|
||||
const char * needle = be_tostring(vm, arg_idx);
|
||||
int32_t idx;
|
||||
|
||||
idx = be_map_bin_search(needle, &definitions[0].name, sizeof(definitions[0]), def_len);
|
||||
|
@ -53,6 +58,28 @@ bbool be_const_member(bvm *vm, const be_const_member_t * definitions, size_t def
|
|||
case '&': // native function
|
||||
be_pushntvfunction(vm, (bntvfunc) definitions[idx].value);
|
||||
break;
|
||||
case '*': // call to a native function
|
||||
{
|
||||
bntvfunc f = (bntvfunc) definitions[idx].value;
|
||||
int ret = f(vm);
|
||||
if ((ret == BE_OK) && !be_isnil(vm, -1)) {
|
||||
return btrue;
|
||||
} else {
|
||||
return bfalse;
|
||||
}
|
||||
break;
|
||||
}
|
||||
case '>': // call to a ctype function
|
||||
{
|
||||
be_ctype_var_args* args = (be_ctype_var_args*) definitions[idx].value;
|
||||
int ret = be_call_c_func(vm, args->func, args->return_type, NULL);
|
||||
if ((ret == BE_OK) && !be_isnil(vm, -1)) {
|
||||
return btrue;
|
||||
} else {
|
||||
return bfalse;
|
||||
}
|
||||
break;
|
||||
}
|
||||
default: // int
|
||||
be_pushint(vm, definitions[idx].value);
|
||||
break;
|
||||
|
@ -62,3 +89,11 @@ bbool be_const_member(bvm *vm, const be_const_member_t * definitions, size_t def
|
|||
}
|
||||
return bfalse;
|
||||
}
|
||||
|
||||
bbool be_const_module_member(bvm *vm, const be_const_member_t * definitions, size_t def_len) {
|
||||
return be_const_member_dual(vm, definitions, def_len, bfalse); // call for module, non-method
|
||||
}
|
||||
|
||||
bbool be_const_class_member(bvm *vm, const be_const_member_t * definitions, size_t def_len) {
|
||||
return be_const_member_dual(vm, definitions, def_len, btrue); // call for method
|
||||
}
|
||||
|
|
|
@ -17,18 +17,35 @@ extern "C" {
|
|||
* as virtual members
|
||||
\*********************************************************************************************/
|
||||
|
||||
typedef intptr_t (*fn_any_callable)(intptr_t p0, intptr_t p1, intptr_t p2, intptr_t p3,
|
||||
intptr_t p4, intptr_t p5, intptr_t p6, intptr_t p7);
|
||||
#define be_cconst_int(_v) ((intptr_t)(_v))
|
||||
#define be_cconst_string(_v) ((intptr_t)(_v))
|
||||
#define be_cconst_ptr(_v) ((intptr_t)(_v))
|
||||
#define be_cconst_func(_v) ((intptr_t)(_v))
|
||||
#define be_cconst_ctype_func(_f, _r) ((intptr_t) &(be_ctype_var_args) { (const void*) _f, _r })
|
||||
|
||||
/* C arguments are coded as an array of 3 pointers */
|
||||
typedef struct be_ctype_args {
|
||||
void* func;
|
||||
const char* return_type;
|
||||
const char* arg_type;
|
||||
} be_ctype_args;
|
||||
|
||||
/* ctype constant function as an array of 2 pointers: function and return type. arg_type is always NULL */
|
||||
typedef struct be_ctype_var_args {
|
||||
const void* func;
|
||||
const char* return_type;
|
||||
} be_ctype_var_args;
|
||||
|
||||
|
||||
typedef struct be_const_member_t {
|
||||
const char * name;
|
||||
int value;
|
||||
intptr_t value;
|
||||
} be_const_member_t;
|
||||
|
||||
// table of functions per class
|
||||
typedef struct be_ntv_func_def_t {
|
||||
const char * name;
|
||||
void * func;
|
||||
const void * func;
|
||||
const char * return_type;
|
||||
const char * arg_type;
|
||||
} be_ntv_func_def_t;
|
||||
|
@ -55,7 +72,8 @@ extern int be_map_bin_search(const char * needle, const void * table, size_t elt
|
|||
extern void be_create_class_wrapper(bvm *vm, const char * class_name, void * ptr);
|
||||
extern int be_find_global_or_module_member(bvm *vm, const char * cl_name);
|
||||
|
||||
extern bbool be_const_member(bvm *vm, const be_const_member_t * definitions, size_t def_len);
|
||||
extern bbool be_const_module_member(bvm *vm, const be_const_member_t * definitions, size_t def_len);
|
||||
extern bbool be_const_class_member(bvm *vm, const be_const_member_t * definitions, size_t def_len);
|
||||
extern intptr_t be_convert_single_elt(bvm *vm, int idx, const char * arg_type, int *len);
|
||||
extern int be_check_arg_type(bvm *vm, int arg_start, int argc, const char * arg_type, intptr_t p[8]);
|
||||
extern int be_call_c_func(bvm *vm, const void * func, const char * return_type, const char * arg_type);
|
||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -259,7 +259,7 @@ extern const size_t be_ctypes_lvgl_classes_size;
|
|||
int lv0_member(bvm *vm);
|
||||
int lv0_member(bvm *vm) {
|
||||
// first try the standard way
|
||||
if (be_const_member(vm, lv0_constants, lv0_constants_size)) {
|
||||
if (be_const_module_member(vm, lv0_constants, lv0_constants_size)) {
|
||||
be_return(vm);
|
||||
}
|
||||
// try alternative members
|
||||
|
|
|
@ -774,11 +774,12 @@ for k in sorted(lv_module2):
|
|||
# otherwise it's an int, leave if unchanged
|
||||
if v is not None:
|
||||
v_prefix = ""
|
||||
if v[0] == '"': v_prefix = "$"
|
||||
if v[0] == '&': v_prefix = "&"
|
||||
print(f" {{ \"{v_prefix}{k}\", (int32_t) {v} }},")
|
||||
v_macro = "be_cconst_int"
|
||||
if v[0] == '"': v_prefix = "$"; v_macro = "be_cconst_string"
|
||||
if v[0] == '&': v_prefix = "&"; v_macro = "be_cconst_ptr"
|
||||
print(f" {{ \"{v_prefix}{k}\", {v_macro}({v}) }},")
|
||||
else:
|
||||
print(f" {{ \"{k}\", LV_{k} }},")
|
||||
print(f" {{ \"{k}\", be_cconst_int(LV_{k}) }},")
|
||||
|
||||
print("""
|
||||
};
|
||||
|
|
|
@ -39,7 +39,7 @@ extern "C" {
|
|||
// virtual member
|
||||
int gp_member(bvm *vm);
|
||||
int gp_member(bvm *vm) {
|
||||
if (be_const_member(vm, lv_gpio_constants, lv_gpio_constants_size)) {
|
||||
if (be_const_module_member(vm, lv_gpio_constants, lv_gpio_constants_size)) {
|
||||
be_return(vm);
|
||||
} else {
|
||||
be_return_nil(vm);
|
||||
|
|
Loading…
Reference in New Issue