From 2f70c0b99bd50dd0520f1ce78c4b356c196f3209 Mon Sep 17 00:00:00 2001 From: s-hadinger <49731213+s-hadinger@users.noreply.github.com> Date: Tue, 11 Nov 2025 18:42:36 +0100 Subject: [PATCH] Berry pointer arithmetic and fast bytes access (#24102) --- lib/libesp32/berry/src/be_object.h | 1 + lib/libesp32/berry/src/be_vm.c | 14 ++++++++++++++ lib/libesp32/berry/tests/comptr.be | 25 +++++++++++++++++++++++++ 3 files changed, 40 insertions(+) create mode 100644 lib/libesp32/berry/tests/comptr.be diff --git a/lib/libesp32/berry/src/be_object.h b/lib/libesp32/berry/src/be_object.h index 1c8d40572..ca6d52048 100644 --- a/lib/libesp32/berry/src/be_object.h +++ b/lib/libesp32/berry/src/be_object.h @@ -249,6 +249,7 @@ typedef const char* (*breader)(struct blexer*, void*, size_t*); #define var_setmodule(_v, _o) var_setobj(_v, BE_MODULE, _o) #define var_setindex(_v, _i) { var_settype(_v, BE_INDEX); (_v)->v.i = (_i); } #define var_setproto(_v, _o) var_setobj(_v, BE_PROTO, _o) +#define var_setcomptr(_v, _o) var_setobj(_v, BE_COMPTR, _o) #define var_tobool(_v) ((_v)->v.b) #define var_toint(_v) ((_v)->v.i) diff --git a/lib/libesp32/berry/src/be_vm.c b/lib/libesp32/berry/src/be_vm.c index 9a2c5a204..4b2a98ebe 100644 --- a/lib/libesp32/berry/src/be_vm.c +++ b/lib/libesp32/berry/src/be_vm.c @@ -680,6 +680,10 @@ newframe: /* a new call frame */ var_setstr(dst, s); } else if (var_isinstance(a)) { ins_binop(vm, "+", ins); + } else if (var_iscomptr(a) && var_isint(b)) { + uint8_t * p = (uint8_t*) var_toobj(a); + p += var_toint(b); + var_setcomptr(dst, p); } else { binop_error(vm, "+", a, b); } @@ -703,6 +707,10 @@ newframe: /* a new call frame */ #endif // CONFIG_IDF_TARGET_ESP32 } else if (var_isinstance(a)) { ins_binop(vm, "-", ins); + } else if (var_iscomptr(a) && var_isint(b)) { + uint8_t * p = (uint8_t*) var_toobj(a); + p -= var_toint(b); + var_setcomptr(dst, p); } else { binop_error(vm, "-", a, b); } @@ -1086,6 +1094,9 @@ newframe: /* a new call frame */ bstring *s = be_strindex(vm, var_tostr(b), c); reg = vm->reg; var_setstr(RA(), s); + } else if (var_iscomptr(b) && var_isint(c)) { + uint8_t * p = var_toobj(b); + var_setint(RA(), p[var_toint(c)]); } else { vm_error(vm, "type_error", "value '%s' does not support subscriptable", @@ -1106,6 +1117,9 @@ newframe: /* a new call frame */ be_dofunc(vm, top, 3); /* call method 'setitem' */ vm->top -= 4; reg = vm->reg; + } else if (var_iscomptr(a) && var_isint(b) && var_isint(c)) { + uint8_t * p = var_toobj(a); + p[var_toint(b)] = var_toint(c); } else { vm_error(vm, "type_error", "value '%s' does not support index assignment", diff --git a/lib/libesp32/berry/tests/comptr.be b/lib/libesp32/berry/tests/comptr.be new file mode 100644 index 000000000..e666ac17d --- /dev/null +++ b/lib/libesp32/berry/tests/comptr.be @@ -0,0 +1,25 @@ +# test about comptr +import introspect + +var p = introspect.toptr(1024) +assert(str(p) == '') + +p += 1 +assert(p == introspect.toptr(1025)) + +p -= 2 +assert(p == introspect.toptr(1023)) + +# use comptr[idx] to read or write bytes +var b = bytes("11223344") +p = b._buffer() # p is comptr +assert(p[0] == 0x11) +assert(p[1] == 0x22) +assert(p[2] == 0x33) +assert(p[3] == 0x44) + +p[0] = 0xFF +p[1] = 0x55 +p[2] = 0xFEBC # shoud truncate to 0xBC +assert(b == bytes("FF55BC44")) +assert(p[0] == 255) # check it's unsigned