Merge pull request #14534 from s-hadinger/berry_constants

Berry improvement to constants
This commit is contained in:
s-hadinger 2022-01-20 22:37:15 +01:00 committed by GitHub
commit 6db87a5614
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
8 changed files with 677 additions and 627 deletions

View File

@ -37,9 +37,10 @@ extern "C" {
.v.nf = (_func), \ .v.nf = (_func), \
.type = BE_NTVFUNC \ .type = BE_NTVFUNC \
} }
typedef const void * constptr;
typedef const void* be_constptr;
#define be_const_ctype_func(_f, ...) { \ #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 \ .type = BE_CTYPE_FUNC \
} }
@ -259,10 +260,9 @@ const bntvmodule be_native_module(_module) = { \
BE_NTVFUNC \ BE_NTVFUNC \
} }
typedef const void * constptr;
#define be_const_ctype_func(_f, ...) { \ #define be_const_ctype_func(_f, ...) { \
bvaldata(((const void*) \ bvaldata(((const void*) \
&(constptr[]) { (const void*) _f, __VA_ARGS__ })), \ &((const void *)[]) { (const void*) _f, __VA_ARGS__ })), \
BE_CTYPE_FUNC \ BE_CTYPE_FUNC \
} }

View File

@ -13,6 +13,9 @@
#include "be_exec.h" #include "be_exec.h"
#include <string.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 * 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. // read a single value at stack position idx, convert to int.
// if object instance, get `_p` member and convert it recursively // 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) { 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; int ret = 0;
char provided_type = 0; char provided_type = 0;
idx = be_absindex(vm, idx); // make sure we have an absolute index 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")) { if (!be_getmember(vm, idx, "_p")) {
be_pop(vm, 1); // remove `nil` be_pop(vm, 1); // remove `nil`
be_getmember(vm, idx, ".p"); be_getmember(vm, idx, ".p");
} } // else `nil` is on top of stack
int32_t ret = be_convert_single_elt(vm, -1, NULL, NULL); // recurse int32_t ret = be_convert_single_elt(vm, -1, NULL, NULL); // recurse
be_pop(vm, 1); 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++; 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); 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]); // berry_log_C("< ret[%i]=%i", p_idx, p[p_idx]);
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) { if (buf_len < 0) {
be_raisef(vm, "value_error", "no bytes() length known"); 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 // 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]); be_raisef(vm, "value_error", "Missing arguments, remaining type '%s'", &arg_type[arg_idx]);
} }
return p_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 * CType handler for Berry
\*********************************************************************************************/ \*********************************************************************************************/
int be_call_ctype_func(bvm *vm, const void *definition) { 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); 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*` fn_any_callable f = (fn_any_callable) func;
size_t return_len = 0; 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); int c_args = be_check_arg_type(vm, arg_start, arg_count, arg_type, p);
if (return_type != NULL && return_type[0] == '&') { if (return_type != NULL && return_type[0] == '&') {
if (c_args < 8) { p[c_args] = (intptr_t) &return_len; } if (c_args < 8) { p[c_args] = (intptr_t) &return_len; }

View File

@ -13,9 +13,11 @@
* Returns true if a match was found. In such case the result is on Berry stack * 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): * Encoding depend on prefix (which is skipped when matching names):
* 1. `COLOR_WHITE` int value * - `COLOR_WHITE` int value
* 3. `$SYMBOL_OK"` string pointer * - `$SYMBOL_OK"` string pointer
* 4. `&seg7_font` comptr * - `&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" #include "be_mapping.h"
@ -29,16 +31,19 @@
* berry stack at position 1. * berry stack at position 1.
* *
* Encoding depend on prefix (which is skipped when matching names): * Encoding depend on prefix (which is skipped when matching names):
* 1. `COLOR_WHITE` int value * - `COLOR_WHITE` int value
* 3. `$SYMBOL_OK"` string pointer * - `$SYMBOL_OK"` string pointer
* 4. `&seg7_font` comptr * - `&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 int32_t argc = be_top(vm); // Get the number of arguments
if (argc == 1 && be_isstring(vm, 1)) { if (argc == arg_idx && be_isstring(vm, arg_idx)) {
const char * needle = be_tostring(vm, 1); const char * needle = be_tostring(vm, arg_idx);
int32_t idx; int32_t idx;
idx = be_map_bin_search(needle, &definitions[0].name, sizeof(definitions[0]), def_len); 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 case '&': // native function
be_pushntvfunction(vm, (bntvfunc) definitions[idx].value); be_pushntvfunction(vm, (bntvfunc) definitions[idx].value);
break; 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 default: // int
be_pushint(vm, definitions[idx].value); be_pushint(vm, definitions[idx].value);
break; break;
@ -61,4 +88,12 @@ bbool be_const_member(bvm *vm, const be_const_member_t * definitions, size_t def
} }
} }
return bfalse; 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
}

View File

@ -17,18 +17,35 @@ extern "C" {
* as virtual members * as virtual members
\*********************************************************************************************/ \*********************************************************************************************/
typedef intptr_t (*fn_any_callable)(intptr_t p0, intptr_t p1, intptr_t p2, intptr_t p3, #define be_cconst_int(_v) ((intptr_t)(_v))
intptr_t p4, intptr_t p5, intptr_t p6, intptr_t p7); #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 { typedef struct be_const_member_t {
const char * name; const char * name;
int value; intptr_t value;
} be_const_member_t; } be_const_member_t;
// table of functions per class // table of functions per class
typedef struct be_ntv_func_def_t { typedef struct be_ntv_func_def_t {
const char * name; const char * name;
void * func; const void * func;
const char * return_type; const char * return_type;
const char * arg_type; const char * arg_type;
} be_ntv_func_def_t; } 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 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 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 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_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); 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

View File

@ -259,7 +259,7 @@ extern const size_t be_ctypes_lvgl_classes_size;
int lv0_member(bvm *vm); int lv0_member(bvm *vm);
int lv0_member(bvm *vm) { int lv0_member(bvm *vm) {
// first try the standard way // 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); be_return(vm);
} }
// try alternative members // try alternative members

View File

@ -774,11 +774,12 @@ for k in sorted(lv_module2):
# otherwise it's an int, leave if unchanged # otherwise it's an int, leave if unchanged
if v is not None: if v is not None:
v_prefix = "" v_prefix = ""
if v[0] == '"': v_prefix = "$" v_macro = "be_cconst_int"
if v[0] == '&': v_prefix = "&" if v[0] == '"': v_prefix = "$"; v_macro = "be_cconst_string"
print(f" {{ \"{v_prefix}{k}\", (int32_t) {v} }},") if v[0] == '&': v_prefix = "&"; v_macro = "be_cconst_ptr"
print(f" {{ \"{v_prefix}{k}\", {v_macro}({v}) }},")
else: else:
print(f" {{ \"{k}\", LV_{k} }},") print(f" {{ \"{k}\", be_cconst_int(LV_{k}) }},")
print(""" print("""
}; };

View File

@ -39,7 +39,7 @@ extern "C" {
// virtual member // virtual member
int gp_member(bvm *vm); int gp_member(bvm *vm);
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); be_return(vm);
} else { } else {
be_return_nil(vm); be_return_nil(vm);