From 4629bb4436367c810585677095ea72ef8d898984 Mon Sep 17 00:00:00 2001 From: Stephan Hadinger Date: Wed, 6 Apr 2022 19:19:17 +0200 Subject: [PATCH] Berry support for int keys in map in solidification --- lib/libesp32/berry/src/be_constobj.h | 12 ++++++++++ lib/libesp32/berry/src/be_solidifylib.c | 31 ++++++++++++++----------- lib/libesp32/berry/src/be_string.c | 2 +- tasmota/xdrv_52_3_berry_tasmota.ino | 1 + 4 files changed, 32 insertions(+), 14 deletions(-) diff --git a/lib/libesp32/berry/src/be_constobj.h b/lib/libesp32/berry/src/be_constobj.h index 708cce03d..96ac1b794 100644 --- a/lib/libesp32/berry/src/be_constobj.h +++ b/lib/libesp32/berry/src/be_constobj.h @@ -33,6 +33,12 @@ extern "C" { .next = (uint32_t)(_next) & 0xFFFFFF \ } +#define be_const_key_int(_i, _next) { \ + .v.i = _i, \ + .type = BE_INT, \ + .next = (uint32_t)(_next) & 0xFFFFFF \ +} + #define be_const_func(_func) { \ .v.nf = (_func), \ .type = BE_NTVFUNC \ @@ -249,6 +255,12 @@ const bntvmodule be_native_module(_module) = { \ uint32_t((_next)&0xFFFFFF) \ } +#define be_const_key_int(_i, _next) { \ + bvaldata(i), \ + BE_INT, \ + uint32_t((_next)&0xFFFFFF) \ +} + #define be_const_func(_func) { \ bvaldata(_func), \ BE_NTVFUNC \ diff --git a/lib/libesp32/berry/src/be_solidifylib.c b/lib/libesp32/berry/src/be_solidifylib.c index 5a8937928..1f08389d6 100644 --- a/lib/libesp32/berry/src/be_solidifylib.c +++ b/lib/libesp32/berry/src/be_solidifylib.c @@ -109,22 +109,26 @@ static void m_solidify_map(bvm *vm, bmap * map, const char *class_name) 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; if (0xFFFFFF == key_next) { key_next = -1; /* more readable */ } - /* convert the string literal to identifier */ - const char * key = str(node->key.v.s); - size_t id_len = toidentifier_length(key); - char id_buf[id_len]; - toidentifier(id_buf, key); - logfmt(" { be_const_key(%s, %i), ", id_buf, key_next); - m_solidify_bvalue(vm, &node->value, class_name, str(node->key.v.s)); + if (node->key.type == BE_STRING) { + /* convert the string literal to identifier */ + const char * key = str(node->key.v.s); + size_t id_len = toidentifier_length(key); + char id_buf[id_len]; + toidentifier(id_buf, key); + logfmt(" { be_const_key(%s, %i), ", id_buf, key_next); + m_solidify_bvalue(vm, &node->value, class_name, str(node->key.v.s)); + } else if (node->key.type == BE_INT) { + logfmt(" { be_const_key_int(%i, %i), ", node->key.v.i, key_next); + m_solidify_bvalue(vm, &node->value, class_name, NULL); + } else { + char error[64]; + snprintf(error, sizeof(error), "Unsupported type in key: %i", node->key.type); + be_raise(vm, "internal_error", error); + } logfmt(" },\n"); } @@ -358,7 +362,8 @@ static void m_solidify_closure(bvm *vm, bclosure *cl, const char * classname, in const char * func_name = str(pr->name); if (cl->nupvals > 0) { - be_raise(vm, "internal_error", "Unsupported upvals in closure"); + logfmt("--> Unsupported upvals in closure <---"); + // be_raise(vm, "internal_error", "Unsupported upvals in closure"); } int indent = 2; diff --git a/lib/libesp32/berry/src/be_string.c b/lib/libesp32/berry/src/be_string.c index 798437420..2ab0d1004 100644 --- a/lib/libesp32/berry/src/be_string.c +++ b/lib/libesp32/berry/src/be_string.c @@ -113,7 +113,7 @@ static void free_sstring(bvm *vm, bstring *str) static uint32_t str_hash(const char *str, size_t len) { uint32_t hash = 2166136261u; - be_assert(str || len); + be_assert(str || !len); while (len--) { hash = (hash ^ (unsigned char)*str++) * 16777619u; } diff --git a/tasmota/xdrv_52_3_berry_tasmota.ino b/tasmota/xdrv_52_3_berry_tasmota.ino index 9e306ca8f..6b9fd8842 100644 --- a/tasmota/xdrv_52_3_berry_tasmota.ino +++ b/tasmota/xdrv_52_3_berry_tasmota.ino @@ -92,6 +92,7 @@ extern "C" { int32_t top = be_top(vm); // Get the number of arguments if (top >= 2 && be_isstring(vm, 2)) { // 1 mandatory string argument const char * payload = be_tostring(vm, 2); + be_pop(vm, top); // clear the stack before calling, because of re-entrant call to Berry in a Rule bool handled = XdrvRulesProcess(0, payload); be_pushbool(vm, handled); be_return(vm); // Return