mirror of https://github.com/arendst/Tasmota.git
Berry fix reference when exeception is raised
This commit is contained in:
parent
a0d6670a5a
commit
197e25132c
|
@ -61,6 +61,7 @@ struct pcall {
|
|||
|
||||
struct vmstate {
|
||||
int top, reg, depth;
|
||||
int refcount;
|
||||
};
|
||||
|
||||
struct strbuf {
|
||||
|
@ -125,6 +126,7 @@ static void vm_state_save(bvm *vm, struct vmstate *state)
|
|||
state->depth = be_stack_count(&vm->callstack);
|
||||
state->top = cast_int(vm->top - vm->stack);
|
||||
state->reg = cast_int(vm->reg - vm->stack);
|
||||
state->refcount = vm->refstack.count;
|
||||
}
|
||||
|
||||
static void copy_exception(bvm *vm, int res, int dstindex)
|
||||
|
@ -143,6 +145,7 @@ static void copy_exception(bvm *vm, int res, int dstindex)
|
|||
static void vm_state_restore(bvm *vm, const struct vmstate *state, int res)
|
||||
{
|
||||
vm->reg = vm->stack + state->reg;
|
||||
be_vector_resize(vm, &vm->refstack, state->refcount);
|
||||
/* copy exception information to top */
|
||||
copy_exception(vm, res, state->top);
|
||||
be_assert(be_stack_count(&vm->callstack) >= state->depth);
|
||||
|
@ -444,6 +447,7 @@ void be_except_block_setup(bvm *vm)
|
|||
/* set longjmp() jump point */
|
||||
frame->errjmp.status = 0;
|
||||
frame->errjmp.prev = vm->errjmp; /* save long jump list */
|
||||
frame->refcount = vm->refstack.count; /* save reference pointer */
|
||||
vm->errjmp = &frame->errjmp;
|
||||
fixup_exceptstack(vm, lbase);
|
||||
}
|
||||
|
@ -455,6 +459,7 @@ void be_except_block_resume(bvm *vm)
|
|||
struct bexecptframe *frame = be_stack_top(&vm->exceptstack);
|
||||
if (errorcode == BE_EXCEPTION) {
|
||||
vm->errjmp = vm->errjmp->prev;
|
||||
be_vector_resize(vm, &vm->refstack, frame->refcount);
|
||||
/* jump to except instruction */
|
||||
vm->ip = frame->ip + IGET_sBx(frame->ip[-1]);
|
||||
if (be_stack_count(&vm->callstack) > frame->depth) {
|
||||
|
|
|
@ -45,6 +45,7 @@ struct bexecptframe {
|
|||
struct blongjmp errjmp; /* long jump information */
|
||||
int depth; /* function call stack depth */
|
||||
binstruction *ip; /* instruction pointer */
|
||||
int refcount; /* save object reference stack */
|
||||
};
|
||||
|
||||
void be_throw(bvm *vm, int errorcode);
|
||||
|
|
|
@ -0,0 +1,31 @@
|
|||
# try to exercise bug in reference
|
||||
|
||||
class failable
|
||||
var fail # if 'true', tostring() raises an exception
|
||||
|
||||
def tostring()
|
||||
if self.fail
|
||||
raise "internal_error", "FAIL"
|
||||
return "FAIL"
|
||||
else
|
||||
return "SUCCESS"
|
||||
end
|
||||
end
|
||||
end
|
||||
f = failable()
|
||||
|
||||
l1 = [1, 2, f]
|
||||
l2 = ["foo", l1]
|
||||
l1.push(l1)
|
||||
|
||||
assert(str(l2) == "['foo', [1, 2, SUCCESS, [...]]]")
|
||||
assert(str(l1) == "[1, 2, SUCCESS, [...]]")
|
||||
|
||||
f.fail = true
|
||||
try
|
||||
print(str(l1))
|
||||
except ..
|
||||
end
|
||||
|
||||
f.fail = false
|
||||
assert(str(l1) == "[1, 2, SUCCESS, [...]]") # FAILS
|
Loading…
Reference in New Issue