From b9b6531c7d6b8dbd9a2ec9d9ecd6128efccb9e77 Mon Sep 17 00:00:00 2001 From: Stephan Hadinger Date: Sun, 7 Nov 2021 20:02:56 +0100 Subject: [PATCH] Berry fix problem when stack resize --- lib/libesp32/Berry/src/be_class.c | 10 +++---- lib/libesp32/Berry/src/be_class.h | 2 +- lib/libesp32/Berry/src/be_vm.c | 47 ++++++++++++++++--------------- 3 files changed, 30 insertions(+), 29 deletions(-) diff --git a/lib/libesp32/Berry/src/be_class.c b/lib/libesp32/Berry/src/be_class.c index a6b94a1cf..c8c826371 100644 --- a/lib/libesp32/Berry/src/be_class.c +++ b/lib/libesp32/Berry/src/be_class.c @@ -217,18 +217,18 @@ static binstance* newobject(bvm *vm, bclass *c) /* Instanciate new instance from stack with argc parameters */ /* Pushes the constructor on the stack to be executed if a construtor is found */ /* Returns true if a constructor is found */ -bbool be_class_newobj(bvm *vm, bclass *c, bvalue *reg, int argc, int mode) +bbool be_class_newobj(bvm *vm, bclass *c, int32_t pos, int argc, int mode) { bvalue init; - size_t pos = reg - vm->reg; binstance *obj = newobject(vm, c); /* create empty object hierarchy from class hierarchy */ - reg = vm->reg + pos - mode; /* the stack may have changed, mode=1 when class is instanciated from module #104 */ - var_setinstance(reg, obj); - var_setinstance(reg + mode, obj); /* copy to reg and reg+1 if mode==1 */ + // reg = vm->reg + pos - mode; /* the stack may have changed, mode=1 when class is instanciated from module #104 */ + var_setinstance(vm->reg + pos, obj); + var_setinstance(vm->reg + pos - mode, obj); /* copy to reg and reg+1 if mode==1 */ /* find constructor */ obj = instance_member(vm, obj, str_literal(vm, "init"), &init); if (obj && var_type(&init) != MT_VARIABLE) { /* copy argv */ + bvalue * reg; for (reg = vm->reg + pos + 1; argc > 0; --argc) { reg[argc] = reg[argc - 2]; } diff --git a/lib/libesp32/Berry/src/be_class.h b/lib/libesp32/Berry/src/be_class.h index 6a114f53b..8bc0a6af7 100644 --- a/lib/libesp32/Berry/src/be_class.h +++ b/lib/libesp32/Berry/src/be_class.h @@ -58,7 +58,7 @@ void be_prim_method_bind(bvm *vm, bclass *c, bstring *name, bntvfunc f); void be_closure_method_bind(bvm *vm, bclass *c, bstring *name, bclosure *cl); int be_class_closure_count(bclass *c); void be_class_upvalue_init(bvm *vm, bclass *c); -bbool be_class_newobj(bvm *vm, bclass *c, bvalue *argv, int argc, int mode); +bbool be_class_newobj(bvm *vm, bclass *c, int32_t pos, int argc, int mode); int be_instance_member_simple(bvm *vm, binstance *obj, bstring *name, bvalue *dst); int be_instance_member(bvm *vm, binstance *obj, bstring *name, bvalue *dst); int be_class_member(bvm *vm, bclass *obj, bstring *name, bvalue *dst); diff --git a/lib/libesp32/Berry/src/be_vm.c b/lib/libesp32/Berry/src/be_vm.c index 83d1d5cfb..ac2ede585 100644 --- a/lib/libesp32/Berry/src/be_vm.c +++ b/lib/libesp32/Berry/src/be_vm.c @@ -142,7 +142,7 @@ _vm->cf->status = PRIM_FUNC; \ } -static void prep_closure(bvm *vm, bvalue *reg, int argc, int mode); +static void prep_closure(bvm *vm, int32_t pos, int argc, int mode); static void attribute_error(bvm *vm, const char *t, bvalue *b, bvalue *c) { @@ -1062,10 +1062,11 @@ newframe: /* a new call frame */ ++var, --argc, mode = 1; goto recall; case BE_CLASS: - if (be_class_newobj(vm, var_toobj(var), var, ++argc, mode)) { /* instanciate object and find constructor */ + if (be_class_newobj(vm, var_toobj(var), var - reg, ++argc, mode)) { /* instanciate object and find constructor */ reg = vm->reg + mode; /* constructor found */ mode = 0; var = RA() + 1; /* to next register */ + reg = vm->reg; goto recall; /* call constructor */ } break; @@ -1101,7 +1102,7 @@ newframe: /* a new call frame */ // *(reg + proto->argc - 1) = *(vm->top-2); /* change the vararg argument to now contain the list instance */ // vm->top = top_save; /* restore top of stack pointer */ // } - prep_closure(vm, var, argc, mode); + prep_closure(vm, var - reg, argc, mode); reg = vm->reg; /* `reg` has changed, now new base register */ goto newframe; /* continue execution of the closure */ } @@ -1163,14 +1164,13 @@ newframe: /* a new call frame */ } } -static void prep_closure(bvm *vm, bvalue *reg, int argc, int mode) +static void prep_closure(bvm *vm, int32_t pos, int argc, int mode) { bvalue *v, *end; - bproto *proto = var2cl(reg)->proto; - push_closure(vm, reg, proto->nstack, mode); - v = vm->reg + argc; + bproto *proto = var2cl(vm->reg + pos)->proto; + push_closure(vm, vm->reg + pos, proto->nstack, mode); end = vm->reg + proto->argc; - for (; v <= end; ++v) { + for (v = vm->reg + argc; v <= end; ++v) { var_setnil(v); } if (proto->varg) { /* there are vararg at the last argument, build the list */ @@ -1189,7 +1189,7 @@ static void prep_closure(bvm *vm, bvalue *reg, int argc, int mode) } } -static void do_closure(bvm *vm, bvalue *reg, int argc) +static void do_closure(bvm *vm, int32_t pos, int argc) { // bvalue *v, *end; // bproto *proto = var2cl(reg)->proto; @@ -1199,31 +1199,31 @@ static void do_closure(bvm *vm, bvalue *reg, int argc) // for (; v <= end; ++v) { // var_setnil(v); // } - prep_closure(vm, reg, argc, 0); + prep_closure(vm, pos, argc, 0); vm_exec(vm); } -static void do_ntvclos(bvm *vm, bvalue *reg, int argc) +static void do_ntvclos(bvm *vm, int32_t pos, int argc) { - bntvclos *f = var_toobj(reg); - push_native(vm, reg, argc, 0); + bntvclos *f = var_toobj(vm->reg + pos); + push_native(vm, vm->reg + pos, argc, 0); f->f(vm); /* call C primitive function */ ret_native(vm); } -static void do_ntvfunc(bvm *vm, bvalue *reg, int argc) +static void do_ntvfunc(bvm *vm, int32_t pos, int argc) { - bntvfunc f = var_tontvfunc(reg); - push_native(vm, reg, argc, 0); + bntvfunc f = var_tontvfunc(vm->reg + pos); + push_native(vm, vm->reg + pos, argc, 0); f(vm); /* call C primitive function */ ret_native(vm); } -static void do_class(bvm *vm, bvalue *reg, int argc) +static void do_class(bvm *vm, int32_t pos, int argc) { - if (be_class_newobj(vm, var_toobj(reg), reg, ++argc, 0)) { + if (be_class_newobj(vm, var_toobj(vm->reg + pos), pos, ++argc, 0)) { be_incrtop(vm); - be_dofunc(vm, reg + 1, argc); + be_dofunc(vm, vm->reg + pos + 1, argc); be_stackpop(vm, 1); } } @@ -1232,11 +1232,12 @@ void be_dofunc(bvm *vm, bvalue *v, int argc) { be_assert(vm->reg <= v && v < vm->stacktop); be_assert(vm->stack <= vm->reg && vm->reg < vm->stacktop); + int32_t pos = v - vm->reg; switch (var_type(v)) { - case BE_CLASS: do_class(vm, v, argc); break; - case BE_CLOSURE: do_closure(vm, v, argc); break; - case BE_NTVCLOS: do_ntvclos(vm, v, argc); break; - case BE_NTVFUNC: do_ntvfunc(vm, v, argc); break; + case BE_CLASS: do_class(vm, pos, argc); break; + case BE_CLOSURE: do_closure(vm, pos, argc); break; + case BE_NTVCLOS: do_ntvclos(vm, pos, argc); break; + case BE_NTVFUNC: do_ntvfunc(vm, pos, argc); break; default: call_error(vm, v); } }