Berry improvement to constants

This commit is contained in:
Stephan Hadinger 2022-01-20 22:02:21 +01:00
parent a538f35df4
commit fb59c63084
8 changed files with 677 additions and 627 deletions

View File

@ -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 \
}

View File

@ -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; }

View File

@ -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;
@ -61,4 +88,12 @@ 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
}

View File

@ -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

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) {
// 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

View File

@ -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("""
};

View File

@ -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);