mirror of
https://github.com/arendst/Tasmota.git
synced 2025-04-24 23:07:17 +00:00
Berry apply fixes from upstream (#18470)
* Berry apply fixes from upstream * Fix
This commit is contained in:
parent
a6aa8924ea
commit
01ba3d28cd
@ -75,7 +75,7 @@ be_extern_native_module(matter);
|
||||
/* user-defined modules declare end */
|
||||
|
||||
/* module list declaration */
|
||||
BERRY_LOCAL const bntvmodule* const be_module_table[] = {
|
||||
BERRY_LOCAL const bntvmodule_t* const be_module_table[] = {
|
||||
/* default modules register */
|
||||
#if BE_USE_STRING_MODULE
|
||||
&be_native_module(string),
|
||||
|
@ -196,7 +196,7 @@ const bvector _name = { \
|
||||
}
|
||||
|
||||
#define be_define_const_native_module(_module) \
|
||||
const bntvmodule be_native_module(_module) = { \
|
||||
const bntvmodule_t be_native_module(_module) = { \
|
||||
.name = #_module, \
|
||||
.attrs = NULL, \
|
||||
.size = 0, \
|
||||
@ -422,7 +422,7 @@ const bvector _name = { \
|
||||
}
|
||||
|
||||
#define be_define_const_native_module(_module) \
|
||||
const bntvmodule be_native_module_##_module = { \
|
||||
const bntvmodule_t be_native_module_##_module = { \
|
||||
#_module, \
|
||||
0, 0, \
|
||||
(bmodule*)&(m_lib##_module) \
|
||||
|
@ -49,7 +49,7 @@ static const char* opc2str(bopcode op)
|
||||
|
||||
void be_print_inst(binstruction ins, int pc, void* fout)
|
||||
{
|
||||
char __lbuf[INST_BUF_SIZE];
|
||||
char __lbuf[INST_BUF_SIZE + 1], __lbuf_tmp[INST_BUF_SIZE];
|
||||
bopcode op = IGET_OP(ins);
|
||||
|
||||
logbuf(" %.4X ", pc);
|
||||
@ -137,7 +137,8 @@ void be_print_inst(binstruction ins, int pc, void* fout)
|
||||
logbuf("%s", opc2str(op));
|
||||
break;
|
||||
}
|
||||
logbuf("%s\n", __lbuf);
|
||||
memcpy(__lbuf_tmp, __lbuf, strlen(__lbuf));
|
||||
logbuf("%s\n", __lbuf_tmp);
|
||||
if (fout) {
|
||||
be_fwrite(fout, __lbuf, strlen(__lbuf));
|
||||
} else {
|
||||
@ -253,7 +254,7 @@ void be_tracestack(bvm *vm)
|
||||
|
||||
static void hook_callnative(bvm *vm, int mask)
|
||||
{
|
||||
bhookinfo info;
|
||||
bhookinfo_t info;
|
||||
int top = be_top(vm);
|
||||
bcallframe *cf = vm->cf;
|
||||
bclosure *cl = var_toobj(cf->func);
|
||||
|
@ -202,6 +202,7 @@ static const char* parser_string(bvm *vm, const char *json)
|
||||
|
||||
static const char* parser_field(bvm *vm, const char *json)
|
||||
{
|
||||
be_stack_require(vm, 2 + BE_STACK_FREE_MIN);
|
||||
if (json && *json == '"') {
|
||||
json = parser_string(vm, json);
|
||||
if (json) {
|
||||
@ -368,6 +369,11 @@ static const char* parser_number(bvm *vm, const char *json)
|
||||
static const char* parser_value(bvm *vm, const char *json)
|
||||
{
|
||||
json = skip_space(json);
|
||||
/*
|
||||
Each value will push at least one thig to the stack, so we must ensure it's big enough.
|
||||
We need to take special care to extend the stack in values which have variable length (arrays and objects)
|
||||
*/
|
||||
be_stack_require(vm, 1 + BE_STACK_FREE_MIN);
|
||||
switch (*json) {
|
||||
case '{': /* object */
|
||||
return parser_object(vm, json);
|
||||
@ -404,6 +410,7 @@ static int m_json_load(bvm *vm)
|
||||
static void make_indent(bvm *vm, int stridx, int indent)
|
||||
{
|
||||
if (indent) {
|
||||
be_stack_require(vm, 1 + BE_STACK_FREE_MIN);
|
||||
char buf[MAX_INDENT * INDENT_WIDTH + 1];
|
||||
indent = (indent < MAX_INDENT ? indent : MAX_INDENT) * INDENT_WIDTH;
|
||||
memset(buf, INDENT_CHAR, indent);
|
||||
@ -417,6 +424,7 @@ static void make_indent(bvm *vm, int stridx, int indent)
|
||||
|
||||
void string_dump(bvm *vm, int index)
|
||||
{
|
||||
be_stack_require(vm, 1 + BE_STACK_FREE_MIN);
|
||||
be_tostring(vm, index); /* convert value to string */
|
||||
be_toescape(vm, index, 'u');
|
||||
be_pushvalue(vm, index);
|
||||
@ -424,11 +432,14 @@ void string_dump(bvm *vm, int index)
|
||||
|
||||
static void object_dump(bvm *vm, int *indent, int idx, int fmt)
|
||||
{
|
||||
|
||||
be_stack_require(vm, 3 + BE_STACK_FREE_MIN); /* 3 pushes outside the loop */
|
||||
be_getmember(vm, idx, ".p");
|
||||
be_pushstring(vm, fmt ? "{\n" : "{");
|
||||
be_pushiter(vm, -2); /* map iterator use 1 register */
|
||||
*indent += fmt;
|
||||
while (be_iter_hasnext(vm, -3)) {
|
||||
be_stack_require(vm, 3 + BE_STACK_FREE_MIN); /* 3 pushes inside the loop */
|
||||
make_indent(vm, -2, fmt ? *indent : 0);
|
||||
be_iter_next(vm, -3);
|
||||
/* key.tostring() */
|
||||
@ -463,6 +474,7 @@ static void object_dump(bvm *vm, int *indent, int idx, int fmt)
|
||||
|
||||
static void array_dump(bvm *vm, int *indent, int idx, int fmt)
|
||||
{
|
||||
be_stack_require(vm, 3 + BE_STACK_FREE_MIN);
|
||||
be_getmember(vm, idx, ".p");
|
||||
be_pushstring(vm, fmt ? "[\n" : "[");
|
||||
be_pushiter(vm, -2);
|
||||
@ -473,6 +485,7 @@ static void array_dump(bvm *vm, int *indent, int idx, int fmt)
|
||||
value_dump(vm, indent, -1, fmt);
|
||||
be_strconcat(vm, -4);
|
||||
be_pop(vm, 2);
|
||||
be_stack_require(vm, 1 + BE_STACK_FREE_MIN);
|
||||
if (be_iter_hasnext(vm, -3)) {
|
||||
be_pushstring(vm, fmt ? ",\n" : ",");
|
||||
be_strconcat(vm, -3);
|
||||
@ -494,13 +507,16 @@ static void array_dump(bvm *vm, int *indent, int idx, int fmt)
|
||||
|
||||
static void value_dump(bvm *vm, int *indent, int idx, int fmt)
|
||||
{
|
||||
// be_stack_require(vm, 1 + BE_STACK_FREE_MIN);
|
||||
if (is_object(vm, "map", idx)) { /* convert to json object */
|
||||
object_dump(vm, indent, idx, fmt);
|
||||
} else if (is_object(vm, "list", idx)) { /* convert to json array */
|
||||
array_dump(vm, indent, idx, fmt);
|
||||
} else if (be_isnil(vm, idx)) { /* convert to json null */
|
||||
be_stack_require(vm, 1 + BE_STACK_FREE_MIN);
|
||||
be_pushstring(vm, "null");
|
||||
} else if (be_isnumber(vm, idx) || be_isbool(vm, idx)) { /* convert to json number and boolean */
|
||||
be_stack_require(vm, 1 + BE_STACK_FREE_MIN);
|
||||
be_tostring(vm, idx);
|
||||
be_pushvalue(vm, idx); /* push to top */
|
||||
} else { /* convert to string */
|
||||
|
@ -36,14 +36,14 @@
|
||||
#endif
|
||||
#endif
|
||||
|
||||
extern BERRY_LOCAL const bntvmodule* const be_module_table[];
|
||||
extern BERRY_LOCAL const bntvmodule_t* const be_module_table[];
|
||||
|
||||
static bmodule* native_module(bvm *vm, const bntvmodule *nm, bvalue *dst);
|
||||
static bmodule* native_module(bvm *vm, const bntvmodule_t *nm, bvalue *dst);
|
||||
|
||||
static const bntvmodule* find_native(bstring *path)
|
||||
static const bntvmodule_t* find_native(bstring *path)
|
||||
{
|
||||
const bntvmodule *module;
|
||||
const bntvmodule* const *node = be_module_table;
|
||||
const bntvmodule_t *module;
|
||||
const bntvmodule_t* const *node = be_module_table;
|
||||
for (; (module = *node) != NULL; ++node) {
|
||||
if (!strcmp(module->name, str(path))) {
|
||||
return module;
|
||||
@ -52,11 +52,11 @@ static const bntvmodule* find_native(bstring *path)
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static void insert_attrs(bvm *vm, bmap *table, const bntvmodule *nm)
|
||||
static void insert_attrs(bvm *vm, bmap *table, const bntvmodule_t *nm)
|
||||
{
|
||||
size_t i;
|
||||
for (i = 0; i < nm->size; ++i) {
|
||||
const bntvmodobj *node = nm->attrs + i;
|
||||
const bntvmodobj_t *node = nm->attrs + i;
|
||||
bstring *name = be_newstr(vm, node->name);
|
||||
bvalue *v = be_map_insertstr(vm, table, name, NULL);
|
||||
be_assert(node->type <= BE_CMODULE);
|
||||
@ -88,7 +88,7 @@ static void insert_attrs(bvm *vm, bmap *table, const bntvmodule *nm)
|
||||
}
|
||||
}
|
||||
|
||||
static bmodule* new_module(bvm *vm, const bntvmodule *nm)
|
||||
static bmodule* new_module(bvm *vm, const bntvmodule_t *nm)
|
||||
{
|
||||
bgcobject *gco = be_gcnew(vm, BE_MODULE, bmodule);
|
||||
bmodule *obj = cast_module(gco);
|
||||
@ -105,7 +105,7 @@ static bmodule* new_module(bvm *vm, const bntvmodule *nm)
|
||||
return obj;
|
||||
}
|
||||
|
||||
static bmodule* native_module(bvm *vm, const bntvmodule *nm, bvalue *dst)
|
||||
static bmodule* native_module(bvm *vm, const bntvmodule_t *nm, bvalue *dst)
|
||||
{
|
||||
if (nm) {
|
||||
bmodule *obj;
|
||||
@ -221,7 +221,7 @@ static int load_package(bvm *vm, bstring *path)
|
||||
|
||||
static int load_native(bvm *vm, bstring *path)
|
||||
{
|
||||
const bntvmodule *nm = find_native(path);
|
||||
const bntvmodule_t *nm = find_native(path);
|
||||
bmodule *mod = native_module(vm, nm, NULL);
|
||||
if (mod != NULL) {
|
||||
/* the pointer vm->top may be changed */
|
||||
|
@ -16,7 +16,7 @@ typedef struct bmodule {
|
||||
bcommon_header;
|
||||
bmap *table;
|
||||
union infodata {
|
||||
const bntvmodule *native;
|
||||
const bntvmodule_t *native;
|
||||
const char *name;
|
||||
const bstring *sname;
|
||||
#ifdef __cplusplus
|
||||
|
@ -109,31 +109,54 @@
|
||||
} \
|
||||
return res
|
||||
|
||||
#define relop_rule(op) \
|
||||
bbool res; \
|
||||
if (var_isint(a) && var_isint(b)) { \
|
||||
res = ibinop(op, a, b); \
|
||||
} else if (var_isnumber(a) && var_isnumber(b)) { \
|
||||
/* res = var2real(a) op var2real(b); */ \
|
||||
union bvaldata x, y; /* TASMOTA workaround for ESP32 rev0 bug */ \
|
||||
x.i = a->v.i;\
|
||||
if (var_isint(a)) { x.r = (breal) x.i; }\
|
||||
y.i = b->v.i;\
|
||||
if (var_isint(b)) { y.r = (breal) y.i; }\
|
||||
res = x.r op y.r; \
|
||||
} else if (var_isstr(a) && var_isstr(b)) { \
|
||||
bstring *s1 = var_tostr(a), *s2 = var_tostr(b); \
|
||||
res = be_strcmp(s1, s2) op 0; \
|
||||
} else if (var_isinstance(a)) { \
|
||||
binstance *obj = var_toobj(a); \
|
||||
object_binop(vm, #op, *a, *b); \
|
||||
check_bool(vm, obj, #op); \
|
||||
res = var_tobool(vm->top); \
|
||||
} else { \
|
||||
binop_error(vm, #op, a, b); \
|
||||
res = bfalse; /* will not be executed */ \
|
||||
} \
|
||||
return res
|
||||
/* when running on ESP32 in IRAM, there is a bug in early chip revision */
|
||||
#ifdef ESP32
|
||||
#define relop_rule(op) \
|
||||
bbool res; \
|
||||
if (var_isint(a) && var_isint(b)) { \
|
||||
res = ibinop(op, a, b); \
|
||||
} else if (var_isnumber(a) && var_isnumber(b)) { \
|
||||
/* res = var2real(a) op var2real(b); */ \
|
||||
union bvaldata x, y; /* TASMOTA workaround for ESP32 rev0 bug */ \
|
||||
x.i = a->v.i;\
|
||||
if (var_isint(a)) { x.r = (breal) x.i; }\
|
||||
y.i = b->v.i;\
|
||||
if (var_isint(b)) { y.r = (breal) y.i; }\
|
||||
res = x.r op y.r; \
|
||||
} else if (var_isstr(a) && var_isstr(b)) { \
|
||||
bstring *s1 = var_tostr(a), *s2 = var_tostr(b); \
|
||||
res = be_strcmp(s1, s2) op 0; \
|
||||
} else if (var_isinstance(a)) { \
|
||||
binstance *obj = var_toobj(a); \
|
||||
object_binop(vm, #op, *a, *b); \
|
||||
check_bool(vm, obj, #op); \
|
||||
res = var_tobool(vm->top); \
|
||||
} else { \
|
||||
binop_error(vm, #op, a, b); \
|
||||
res = bfalse; /* will not be executed */ \
|
||||
} \
|
||||
return res
|
||||
#else // ESP32
|
||||
#define relop_rule(op) \
|
||||
bbool res; \
|
||||
if (var_isint(a) && var_isint(b)) { \
|
||||
res = ibinop(op, a, b); \
|
||||
} else if (var_isnumber(a) && var_isnumber(b)) { \
|
||||
res = var2real(a) op var2real(b); \
|
||||
} else if (var_isstr(a) && var_isstr(b)) { \
|
||||
bstring *s1 = var_tostr(a), *s2 = var_tostr(b); \
|
||||
res = be_strcmp(s1, s2) op 0; \
|
||||
} else if (var_isinstance(a)) { \
|
||||
binstance *obj = var_toobj(a); \
|
||||
object_binop(vm, #op, *a, *b); \
|
||||
check_bool(vm, obj, #op); \
|
||||
res = var_tobool(vm->top); \
|
||||
} else { \
|
||||
binop_error(vm, #op, a, b); \
|
||||
res = bfalse; /* will not be executed */ \
|
||||
} \
|
||||
return res
|
||||
#endif // ESP32
|
||||
|
||||
#define bitwise_block(op) \
|
||||
bvalue *dst = RA(), *a = RKB(), *b = RKC(); \
|
||||
@ -264,7 +287,6 @@ static bbool obj2bool(bvm *vm, bvalue *var)
|
||||
binstance *obj = var_toobj(var);
|
||||
bstring *tobool = str_literal(vm, "tobool");
|
||||
/* get operator method */
|
||||
// TODO what if `tobool` is static
|
||||
int type = be_instance_member(vm, obj, tobool, vm->top);
|
||||
if (type != BE_NONE && type != BE_NIL) {
|
||||
vm->top[1] = *var; /* move self to argv[0] */
|
||||
@ -357,7 +379,6 @@ static bbool object_eqop(bvm *vm,
|
||||
bbool isself = var_isinstance(b) && o == var_toobj(b);
|
||||
/* first, try to call the overloaded operator of the object */
|
||||
int type = be_instance_member(vm, o, be_newstr(vm, op), vm->top);
|
||||
// TODO check that method is not static
|
||||
if (basetype(type) == BE_FUNCTION) { /* call method */
|
||||
bvalue *top = vm->top;
|
||||
top[1] = self; /* move self to argv[0] */
|
||||
@ -615,13 +636,17 @@ newframe: /* a new call frame */
|
||||
if (var_isint(a) && var_isint(b)) {
|
||||
var_setint(dst, ibinop(+, a, b));
|
||||
} else if (var_isnumber(a) && var_isnumber(b)) {
|
||||
#ifdef ESP32 /* when running on ESP32 in IRAM, there is a bug in early chip revision */
|
||||
union bvaldata x, y; // TASMOTA workaround for ESP32 rev0 bug
|
||||
x.i = a->v.i;
|
||||
if (var_isint(a)) { x.r = (breal) x.i; }
|
||||
y.i = b->v.i;
|
||||
if (var_isint(b)) { y.r = (breal) y.i; }
|
||||
// breal x = var2real(a), y = var2real(b);
|
||||
var_setreal(dst, x.r + y.r);
|
||||
#else // ESP32
|
||||
breal x = var2real(a), y = var2real(b);
|
||||
var_setreal(dst, x + y);
|
||||
#endif // ESP32
|
||||
} else if (var_isstr(a) && var_isstr(b)) { /* strcat */
|
||||
bstring *s = be_strcat(vm, var_tostr(a), var_tostr(b));
|
||||
reg = vm->reg;
|
||||
|
File diff suppressed because it is too large
Load Diff
Loading…
x
Reference in New Issue
Block a user