mirror of https://github.com/arendst/Tasmota.git
Merge pull request #13559 from s-hadinger/berry_updates
Berry multiple updates
This commit is contained in:
commit
b9f47f93c9
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
|
@ -1,24 +1,25 @@
|
|||
#include "be_constobj.h"
|
||||
|
||||
static be_define_const_map_slots(be_class_map_map) {
|
||||
{ be_const_key(tostring, -1), be_const_func(m_tostring) },
|
||||
{ be_const_key(size, -1), be_const_func(m_size) },
|
||||
{ be_const_key(item, 4), be_const_func(m_item) },
|
||||
{ be_const_key(setitem, 9), be_const_func(m_setitem) },
|
||||
{ be_const_key(has, -1), be_const_func(m_has) },
|
||||
{ be_const_key(keys, -1), be_const_func(m_keys) },
|
||||
{ be_const_key(init, -1), be_const_func(m_init) },
|
||||
{ be_const_key(remove, 5), be_const_func(m_remove) },
|
||||
{ be_const_key(reduce, -1), be_const_func(m_reduce) },
|
||||
{ be_const_key(iter, -1), be_const_func(m_iter) },
|
||||
{ be_const_key(setitem, -1), be_const_func(m_setitem) },
|
||||
{ be_const_key(remove, 8), be_const_func(m_remove) },
|
||||
{ be_const_key(insert, -1), be_const_func(m_insert) },
|
||||
{ be_const_key(dot_p, -1), be_const_var(0) },
|
||||
{ be_const_key(find, 1), be_const_func(m_find) },
|
||||
{ be_const_key(tostring, 4), be_const_func(m_tostring) },
|
||||
{ be_const_key(has, -1), be_const_func(m_contains) },
|
||||
{ be_const_key(init, -1), be_const_func(m_init) },
|
||||
{ be_const_key(contains, 9), be_const_func(m_contains) },
|
||||
{ be_const_key(dot_p, 13), be_const_var(0) },
|
||||
{ be_const_key(reduce, -1), be_const_func(m_reduce) },
|
||||
{ be_const_key(size, -1), be_const_func(m_size) },
|
||||
{ be_const_key(find, -1), be_const_func(m_find) },
|
||||
{ be_const_key(keys, -1), be_const_func(m_keys) },
|
||||
{ be_const_key(item, -1), be_const_func(m_item) },
|
||||
{ be_const_key(iter, -1), be_const_func(m_iter) },
|
||||
};
|
||||
|
||||
static be_define_const_map(
|
||||
be_class_map_map,
|
||||
13
|
||||
14
|
||||
);
|
||||
|
||||
BE_EXPORT_VARIABLE be_define_const_class(
|
||||
|
|
|
@ -1125,15 +1125,20 @@ static int m_buffer(bvm *vm)
|
|||
/*
|
||||
* External API
|
||||
*/
|
||||
BERRY_API void be_pushbytes(bvm *vm, const void * bytes, size_t len)
|
||||
BERRY_API void * be_pushbytes(bvm *vm, const void * bytes, size_t len)
|
||||
{
|
||||
bytes_new_object(vm, len);
|
||||
buf_impl attr = m_read_attributes(vm, -1);
|
||||
if ((int32_t)len > attr.size) { len = attr.size; } /* double check if the buffer allocated was smaller */
|
||||
memmove((void*)attr.bufptr, bytes, len);
|
||||
if (bytes) { /* if bytes is null, buffer is filled with zeros */
|
||||
memmove((void*)attr.bufptr, bytes, len);
|
||||
} else {
|
||||
memset((void*)attr.bufptr, 0, len);
|
||||
}
|
||||
attr.len = len;
|
||||
m_write_attributes(vm, -1, &attr); /* update instance */
|
||||
/* bytes instance is on top of stack */
|
||||
return (void*)attr.bufptr;
|
||||
}
|
||||
|
||||
BERRY_API const void *be_tobytes(bvm *vm, int rel_index, size_t *len)
|
||||
|
|
|
@ -15,6 +15,7 @@ extern "C" {
|
|||
#include "be_object.h"
|
||||
#include "be_gc.h"
|
||||
#include "be_map.h"
|
||||
#include "be_list.h"
|
||||
#include "be_class.h"
|
||||
#include "be_string.h"
|
||||
#include "be_module.h"
|
||||
|
@ -92,6 +93,21 @@ extern "C" {
|
|||
.type = BE_MODULE \
|
||||
}
|
||||
|
||||
#define be_const_simple_instance(_instance) { \
|
||||
.v.c = (_instance), \
|
||||
.type = BE_INSTANCE \
|
||||
}
|
||||
|
||||
#define be_const_map(_map) { \
|
||||
.v.c = &(_map), \
|
||||
.type = BE_MAP \
|
||||
}
|
||||
|
||||
#define be_const_list(_list) { \
|
||||
.v.c = &(_list), \
|
||||
.type = BE_LIST \
|
||||
}
|
||||
|
||||
#define be_define_const_map_slots(_name) \
|
||||
const bmapnode _name##_slots[] =
|
||||
|
||||
|
@ -164,6 +180,26 @@ const bntvmodule be_native_module(_module) = { \
|
|||
.info.name = _module_name \
|
||||
}
|
||||
|
||||
/* only instances with no super and no sub instance are supported */
|
||||
/* primarily for `list` and `map`*/
|
||||
#define be_nested_simple_instance(_class_ptr, _members) \
|
||||
& (const binstance) { \
|
||||
be_const_header(BE_INSTANCE), \
|
||||
.super = NULL, \
|
||||
.sub = NULL, \
|
||||
._class = (bclass*) _class_ptr, \
|
||||
.members = _members \
|
||||
}
|
||||
|
||||
// #define be_local_instance(_name, _class_ptr, _members) \
|
||||
// static const binstance i_##_name = { \
|
||||
// be_const_header(BE_INSTANCE), \
|
||||
// .super = NULL, \
|
||||
// .sub = NULL, \
|
||||
// ._class = (bclass*) _class_ptr, \
|
||||
// .members = _members \
|
||||
// }
|
||||
|
||||
#define be_nested_map(_size, _slots) \
|
||||
& (const bmap) { \
|
||||
be_const_header(BE_MAP), \
|
||||
|
@ -173,6 +209,14 @@ const bntvmodule be_native_module(_module) = { \
|
|||
.count = _size \
|
||||
}
|
||||
|
||||
#define be_nested_list(_size, _items) \
|
||||
& (const blist) { \
|
||||
be_const_header(BE_LIST), \
|
||||
.count = _size, \
|
||||
.capacity = _size, \
|
||||
.data = _items \
|
||||
}
|
||||
|
||||
#define be_nested_string(_str, _hash, _len) \
|
||||
{ \
|
||||
{ .s=(be_nested_const_str(_str, _hash, _len )) \
|
||||
|
@ -284,16 +328,19 @@ const bvector _name = { \
|
|||
(void*)_data, (void*)(_data + (_size) - 1) \
|
||||
}
|
||||
|
||||
#define be_define_const_native_module(_module, _init) \
|
||||
#define be_define_const_native_module(_module) \
|
||||
const bntvmodule be_native_module(_module) = { \
|
||||
#_module, \
|
||||
0, 0, \
|
||||
(bmodule*)&(m_lib##_module), \
|
||||
_init \
|
||||
(bmodule*)&(m_lib##_module) \
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
/* provide pointers to map and list classes for solidified code */
|
||||
extern const bclass be_class_list;
|
||||
extern const bclass be_class_map;
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
|
|
@ -69,7 +69,6 @@ static int m_findmember(bvm *vm)
|
|||
if (top >= 2 && (be_isinstance(vm, 1) || be_ismodule(vm, 1) || be_isclass(vm, 1)) && be_isstring(vm, 2)) {
|
||||
int ret = be_execprotected(vm, &m_findmember_protected, (void*) be_tostring(vm, 2));
|
||||
if (ret == BE_OK) {
|
||||
// be_getmember(vm, 1, be_tostring(vm, 2));
|
||||
be_return(vm);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -121,7 +121,7 @@ static int m_find(bvm *vm)
|
|||
be_return(vm);
|
||||
}
|
||||
|
||||
static int m_has(bvm *vm)
|
||||
static int m_contains(bvm *vm)
|
||||
{
|
||||
be_getmember(vm, 1, ".p");
|
||||
map_check_data(vm, 2);
|
||||
|
@ -279,6 +279,8 @@ void be_load_maplib(bvm *vm)
|
|||
{ "item", m_item },
|
||||
{ "setitem", m_setitem },
|
||||
{ "find", m_find },
|
||||
{ "contains", m_contains },
|
||||
{ "has", m_contains }, /* deprecated */
|
||||
{ "size", m_size },
|
||||
{ "insert", m_insert },
|
||||
{ "iter", m_iter },
|
||||
|
@ -298,7 +300,8 @@ class be_class_map (scope: global, name: map) {
|
|||
item, func(m_item)
|
||||
setitem, func(m_setitem)
|
||||
find, func(m_find)
|
||||
has, func(m_has)
|
||||
contains, func(m_contains)
|
||||
has, func(m_contains)
|
||||
size, func(m_size)
|
||||
insert, func(m_insert)
|
||||
iter, func(m_iter)
|
||||
|
|
|
@ -10,6 +10,7 @@
|
|||
#include "be_string.h"
|
||||
#include "be_vector.h"
|
||||
#include "be_class.h"
|
||||
#include "be_list.h"
|
||||
#include "be_debug.h"
|
||||
#include "be_map.h"
|
||||
#include "be_vm.h"
|
||||
|
@ -17,6 +18,9 @@
|
|||
#include <string.h>
|
||||
#include <stdio.h>
|
||||
|
||||
extern const bclass be_class_list;
|
||||
extern const bclass be_class_map;
|
||||
|
||||
#if BE_USE_SOLIDIFY_MODULE
|
||||
#include <inttypes.h>
|
||||
|
||||
|
@ -33,6 +37,50 @@
|
|||
be_writestring(__lbuf); \
|
||||
} while (0)
|
||||
|
||||
static void m_solidify_bvalue(bvm *vm, bvalue * value, const char *classname, const char *key);
|
||||
|
||||
static void m_solidify_map(bvm *vm, bmap * map, const char *class_name)
|
||||
{
|
||||
logfmt(" be_nested_map(%i,\n", map->count);
|
||||
|
||||
logfmt(" ( (struct bmapnode*) &(const bmapnode[]) {\n");
|
||||
for (int i = 0; i < map->size; i++) {
|
||||
bmapnode * node = &map->slots[i];
|
||||
if (node->key.type == BE_NIL) {
|
||||
continue; /* key not used */
|
||||
}
|
||||
if (node->key.type != BE_STRING) {
|
||||
char error[64];
|
||||
snprintf(error, sizeof(error), "Unsupported type in key: %i", node->key.type);
|
||||
be_raise(vm, "internal_error", error);
|
||||
}
|
||||
int key_next = node->key.next;
|
||||
size_t len = strlen(str(node->key.v.s));
|
||||
if (0xFFFFFF == key_next) {
|
||||
key_next = -1; /* more readable */
|
||||
}
|
||||
logfmt(" { be_nested_key(\"%s\", %i, %zu, %i), ", str(node->key.v.s), be_strhash(node->key.v.s), len >= 255 ? 255 : len, key_next);
|
||||
m_solidify_bvalue(vm, &node->value, class_name, str(node->key.v.s));
|
||||
|
||||
logfmt(" },\n");
|
||||
}
|
||||
logfmt(" }))"); // TODO need terminal comma?
|
||||
|
||||
}
|
||||
|
||||
static void m_solidify_list(bvm *vm, blist * list, const char *class_name)
|
||||
{
|
||||
logfmt(" be_nested_list(%i,\n", list->count);
|
||||
|
||||
logfmt(" ( (struct bvalue*) &(const bvalue[]) {\n");
|
||||
for (int i = 0; i < list->count; i++) {
|
||||
logfmt(" ");
|
||||
m_solidify_bvalue(vm, &list->data[i], class_name, "");
|
||||
logfmt(",\n");
|
||||
}
|
||||
logfmt(" }))"); // TODO need terminal comma?
|
||||
}
|
||||
|
||||
// pass key name in case of class, or NULL if none
|
||||
static void m_solidify_bvalue(bvm *vm, bvalue * value, const char *classname, const char *key)
|
||||
{
|
||||
|
@ -88,6 +136,35 @@ static void m_solidify_bvalue(bvm *vm, bvalue * value, const char *classname, co
|
|||
case BE_NTVFUNC:
|
||||
logfmt("be_const_func(be_ntv_%s_%s)", classname ? classname : "unknown", key ? key : "unknown");
|
||||
break;
|
||||
case BE_INSTANCE:
|
||||
{
|
||||
binstance * ins = (binstance *) var_toobj(value);
|
||||
bclass * cl = ins->_class;
|
||||
if (ins->super || ins->sub) {
|
||||
be_raise(vm, "internal_error", "instance must not have a super/sub class");
|
||||
} else if (cl->nvar != 1) {
|
||||
be_raise(vm, "internal_error", "instance must have only one instance variable");
|
||||
} else if ((cl != &be_class_map && cl != &be_class_list) || 1) { // TODO
|
||||
const char * cl_ptr = "";
|
||||
if (cl == &be_class_map) { cl_ptr = "map"; }
|
||||
if (cl == &be_class_list) { cl_ptr = "list"; }
|
||||
logfmt("be_const_simple_instance(be_nested_simple_instance(&be_class_%s, {\n", cl_ptr);
|
||||
if (cl == &be_class_map) {
|
||||
logfmt(" be_const_map( * ");
|
||||
} else {
|
||||
logfmt(" be_const_list( * ");
|
||||
}
|
||||
m_solidify_bvalue(vm, &ins->members[0], classname, key);
|
||||
logfmt(" ) } ))");
|
||||
}
|
||||
}
|
||||
break;
|
||||
case BE_MAP:
|
||||
m_solidify_map(vm, (bmap *) var_toobj(value), classname);
|
||||
break;
|
||||
case BE_LIST:
|
||||
m_solidify_list(vm, (blist *) var_toobj(value), classname);
|
||||
break;
|
||||
default:
|
||||
{
|
||||
char error[64];
|
||||
|
@ -253,27 +330,8 @@ static void m_solidify_subclass(bvm *vm, bclass *cl, int builtins)
|
|||
}
|
||||
|
||||
if (cl->members) {
|
||||
logfmt(" be_nested_map(%i,\n", cl->members->count);
|
||||
|
||||
logfmt(" ( (struct bmapnode*) &(const bmapnode[]) {\n");
|
||||
for (int i = 0; i < cl->members->count; i++) {
|
||||
bmapnode * node = &cl->members->slots[i];
|
||||
if (node->key.type != BE_STRING) {
|
||||
char error[64];
|
||||
snprintf(error, sizeof(error), "Unsupported type in key: %i", node->key.type);
|
||||
be_raise(vm, "internal_error", error);
|
||||
}
|
||||
int key_next = node->key.next;
|
||||
size_t len = strlen(str(node->key.v.s));
|
||||
if (0xFFFFFF == key_next) {
|
||||
key_next = -1; /* more readable */
|
||||
}
|
||||
logfmt(" { be_nested_key(\"%s\", %i, %zu, %i), ", str(node->key.v.s), be_strhash(node->key.v.s), len >= 255 ? 255 : len, key_next);
|
||||
m_solidify_bvalue(vm, &node->value, class_name, str(node->key.v.s));
|
||||
|
||||
logfmt(" },\n");
|
||||
}
|
||||
logfmt(" })),\n");
|
||||
m_solidify_map(vm, cl->members, class_name);
|
||||
logfmt(",\n");
|
||||
} else {
|
||||
logfmt(" NULL,\n");
|
||||
}
|
||||
|
@ -299,7 +357,8 @@ static void m_solidify_class(bvm *vm, bclass *cl, int builtins)
|
|||
|
||||
static void m_solidify_module(bvm *vm, bmodule *ml, int builtins)
|
||||
{
|
||||
const char * module_name = ml->info.name;
|
||||
const char * module_name = be_module_name(ml);
|
||||
if (!module_name) { module_name = ""; }
|
||||
|
||||
/* iterate on members to dump closures */
|
||||
if (ml->table) {
|
||||
|
@ -323,33 +382,14 @@ static void m_solidify_module(bvm *vm, bmodule *ml, int builtins)
|
|||
logfmt(" \"%s\",\n", module_name);
|
||||
|
||||
if (ml->table) {
|
||||
logfmt(" be_nested_map(%i,\n", ml->table->count);
|
||||
|
||||
logfmt(" ( (struct bmapnode*) &(const bmapnode[]) {\n");
|
||||
for (int i = 0; i < ml->table->count; i++) {
|
||||
bmapnode * node = &ml->table->slots[i];
|
||||
if (node->key.type != BE_STRING) {
|
||||
char error[64];
|
||||
snprintf(error, sizeof(error), "Unsupported type in key: %i", node->key.type);
|
||||
be_raise(vm, "internal_error", error);
|
||||
}
|
||||
int key_next = node->key.next;
|
||||
size_t len = strlen(str(node->key.v.s));
|
||||
if (0xFFFFFF == key_next) {
|
||||
key_next = -1; /* more readable */
|
||||
}
|
||||
logfmt(" { be_nested_key(\"%s\", %i, %zu, %i), ", str(node->key.v.s), be_strhash(node->key.v.s), len >= 255 ? 255 : len, key_next);
|
||||
m_solidify_bvalue(vm, &node->value, module_name, str(node->key.v.s));
|
||||
|
||||
logfmt(" },\n");
|
||||
}
|
||||
logfmt(" }))\n");
|
||||
m_solidify_map(vm, ml->table, module_name);
|
||||
logfmt("\n");
|
||||
} else {
|
||||
logfmt(" NULL,\n");
|
||||
}
|
||||
logfmt(");\n");
|
||||
logfmt("BE_EXPORT_VARIABLE be_define_const_native_module(%s, NULL);\n", module_name);
|
||||
logfmt("/********************************************************************\n");
|
||||
logfmt("/********************************************************************/\n");
|
||||
|
||||
}
|
||||
|
||||
|
@ -366,6 +406,8 @@ static int m_dump(bvm *vm)
|
|||
m_solidify_class(vm, var_toobj(v), be_builtin_count(vm));
|
||||
} else if (var_ismodule(v)) {
|
||||
m_solidify_module(vm, var_toobj(v), be_builtin_count(vm));
|
||||
} else {
|
||||
be_raise(vm, "value_error", "unsupported type");
|
||||
}
|
||||
}
|
||||
be_return_nil(vm);
|
||||
|
|
|
@ -821,7 +821,6 @@ newframe: /* a new call frame */
|
|||
vm->counter_get++;
|
||||
#endif
|
||||
bvalue a_temp; /* copy result to a temp variable because the stack may be relocated in virtual member calls */
|
||||
// bvalue *a = RA(), *b = RKB(), *c = RKC();
|
||||
bvalue *b = RKB(), *c = RKC();
|
||||
if (var_isinstance(b) && var_isstr(c)) {
|
||||
obj_attribute(vm, b, var_tostr(c), &a_temp);
|
||||
|
@ -834,6 +833,7 @@ newframe: /* a new call frame */
|
|||
reg = vm->reg;
|
||||
} else {
|
||||
attribute_error(vm, "attribute", b, c);
|
||||
a_temp = *RA(); /* avoid gcc warning for uninitialized variable a_temp, this code is never reached */
|
||||
}
|
||||
bvalue *a = RA();
|
||||
*a = a_temp; /* assign the resul to the specified register on the updated stack */
|
||||
|
|
|
@ -562,7 +562,7 @@ BERRY_API void be_module_path(bvm *vm);
|
|||
BERRY_API void be_module_path_set(bvm *vm, const char *path);
|
||||
|
||||
/* bytes operations */
|
||||
BERRY_API void be_pushbytes(bvm *vm, const void *buf, size_t len);
|
||||
BERRY_API void* be_pushbytes(bvm *vm, const void *buf, size_t len);
|
||||
BERRY_API const void* be_tobytes(bvm *vm, int index, size_t *len);
|
||||
|
||||
/* registry operation */
|
||||
|
|
Loading…
Reference in New Issue