Berry fix problem when stack resize

This commit is contained in:
Stephan Hadinger 2021-11-07 20:02:56 +01:00
parent 0ecf398a38
commit b9b6531c7d
3 changed files with 30 additions and 29 deletions

View File

@ -217,18 +217,18 @@ static binstance* newobject(bvm *vm, bclass *c)
/* Instanciate new instance from stack with argc parameters */ /* Instanciate new instance from stack with argc parameters */
/* Pushes the constructor on the stack to be executed if a construtor is found */ /* Pushes the constructor on the stack to be executed if a construtor is found */
/* Returns true if a constructor 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; bvalue init;
size_t pos = reg - vm->reg;
binstance *obj = newobject(vm, c); /* create empty object hierarchy from class hierarchy */ 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 */ // 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(vm->reg + pos, obj);
var_setinstance(reg + mode, obj); /* copy to reg and reg+1 if mode==1 */ var_setinstance(vm->reg + pos - mode, obj); /* copy to reg and reg+1 if mode==1 */
/* find constructor */ /* find constructor */
obj = instance_member(vm, obj, str_literal(vm, "init"), &init); obj = instance_member(vm, obj, str_literal(vm, "init"), &init);
if (obj && var_type(&init) != MT_VARIABLE) { if (obj && var_type(&init) != MT_VARIABLE) {
/* copy argv */ /* copy argv */
bvalue * reg;
for (reg = vm->reg + pos + 1; argc > 0; --argc) { for (reg = vm->reg + pos + 1; argc > 0; --argc) {
reg[argc] = reg[argc - 2]; reg[argc] = reg[argc - 2];
} }

View File

@ -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); void be_closure_method_bind(bvm *vm, bclass *c, bstring *name, bclosure *cl);
int be_class_closure_count(bclass *c); int be_class_closure_count(bclass *c);
void be_class_upvalue_init(bvm *vm, 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_simple(bvm *vm, binstance *obj, bstring *name, bvalue *dst);
int be_instance_member(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); int be_class_member(bvm *vm, bclass *obj, bstring *name, bvalue *dst);

View File

@ -142,7 +142,7 @@
_vm->cf->status = PRIM_FUNC; \ _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) 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; ++var, --argc, mode = 1;
goto recall; goto recall;
case BE_CLASS: 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 */ reg = vm->reg + mode; /* constructor found */
mode = 0; mode = 0;
var = RA() + 1; /* to next register */ var = RA() + 1; /* to next register */
reg = vm->reg;
goto recall; /* call constructor */ goto recall; /* call constructor */
} }
break; 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 */ // *(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 */ // 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 */ reg = vm->reg; /* `reg` has changed, now new base register */
goto newframe; /* continue execution of the closure */ 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; bvalue *v, *end;
bproto *proto = var2cl(reg)->proto; bproto *proto = var2cl(vm->reg + pos)->proto;
push_closure(vm, reg, proto->nstack, mode); push_closure(vm, vm->reg + pos, proto->nstack, mode);
v = vm->reg + argc;
end = vm->reg + proto->argc; end = vm->reg + proto->argc;
for (; v <= end; ++v) { for (v = vm->reg + argc; v <= end; ++v) {
var_setnil(v); var_setnil(v);
} }
if (proto->varg) { /* there are vararg at the last argument, build the list */ 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; // bvalue *v, *end;
// bproto *proto = var2cl(reg)->proto; // bproto *proto = var2cl(reg)->proto;
@ -1199,31 +1199,31 @@ static void do_closure(bvm *vm, bvalue *reg, int argc)
// for (; v <= end; ++v) { // for (; v <= end; ++v) {
// var_setnil(v); // var_setnil(v);
// } // }
prep_closure(vm, reg, argc, 0); prep_closure(vm, pos, argc, 0);
vm_exec(vm); 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); bntvclos *f = var_toobj(vm->reg + pos);
push_native(vm, reg, argc, 0); push_native(vm, vm->reg + pos, argc, 0);
f->f(vm); /* call C primitive function */ f->f(vm); /* call C primitive function */
ret_native(vm); 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); bntvfunc f = var_tontvfunc(vm->reg + pos);
push_native(vm, reg, argc, 0); push_native(vm, vm->reg + pos, argc, 0);
f(vm); /* call C primitive function */ f(vm); /* call C primitive function */
ret_native(vm); 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_incrtop(vm);
be_dofunc(vm, reg + 1, argc); be_dofunc(vm, vm->reg + pos + 1, argc);
be_stackpop(vm, 1); 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->reg <= v && v < vm->stacktop);
be_assert(vm->stack <= vm->reg && vm->reg < vm->stacktop); be_assert(vm->stack <= vm->reg && vm->reg < vm->stacktop);
int32_t pos = v - vm->reg;
switch (var_type(v)) { switch (var_type(v)) {
case BE_CLASS: do_class(vm, v, argc); break; case BE_CLASS: do_class(vm, pos, argc); break;
case BE_CLOSURE: do_closure(vm, v, argc); break; case BE_CLOSURE: do_closure(vm, pos, argc); break;
case BE_NTVCLOS: do_ntvclos(vm, v, argc); break; case BE_NTVCLOS: do_ntvclos(vm, pos, argc); break;
case BE_NTVFUNC: do_ntvfunc(vm, v, argc); break; case BE_NTVFUNC: do_ntvfunc(vm, pos, argc); break;
default: call_error(vm, v); default: call_error(vm, v);
} }
} }