Berry pointer arithmetic and fast bytes access (#24102)

This commit is contained in:
s-hadinger 2025-11-11 18:42:36 +01:00 committed by GitHub
parent f237e16203
commit 2f70c0b99b
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
3 changed files with 40 additions and 0 deletions

View File

@ -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_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_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_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_tobool(_v) ((_v)->v.b)
#define var_toint(_v) ((_v)->v.i) #define var_toint(_v) ((_v)->v.i)

View File

@ -680,6 +680,10 @@ newframe: /* a new call frame */
var_setstr(dst, s); var_setstr(dst, s);
} else if (var_isinstance(a)) { } else if (var_isinstance(a)) {
ins_binop(vm, "+", ins); 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 { } else {
binop_error(vm, "+", a, b); binop_error(vm, "+", a, b);
} }
@ -703,6 +707,10 @@ newframe: /* a new call frame */
#endif // CONFIG_IDF_TARGET_ESP32 #endif // CONFIG_IDF_TARGET_ESP32
} else if (var_isinstance(a)) { } else if (var_isinstance(a)) {
ins_binop(vm, "-", ins); 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 { } else {
binop_error(vm, "-", a, b); binop_error(vm, "-", a, b);
} }
@ -1086,6 +1094,9 @@ newframe: /* a new call frame */
bstring *s = be_strindex(vm, var_tostr(b), c); bstring *s = be_strindex(vm, var_tostr(b), c);
reg = vm->reg; reg = vm->reg;
var_setstr(RA(), s); 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 { } else {
vm_error(vm, "type_error", vm_error(vm, "type_error",
"value '%s' does not support subscriptable", "value '%s' does not support subscriptable",
@ -1106,6 +1117,9 @@ newframe: /* a new call frame */
be_dofunc(vm, top, 3); /* call method 'setitem' */ be_dofunc(vm, top, 3); /* call method 'setitem' */
vm->top -= 4; vm->top -= 4;
reg = vm->reg; 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 { } else {
vm_error(vm, "type_error", vm_error(vm, "type_error",
"value '%s' does not support index assignment", "value '%s' does not support index assignment",

View File

@ -0,0 +1,25 @@
# test about comptr
import introspect
var p = introspect.toptr(1024)
assert(str(p) == '<ptr: 0x400>')
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