mirror of
https://github.com/arendst/Tasmota.git
synced 2025-07-29 05:36:39 +00:00
Merge pull request #16080 from s-hadinger/berry_fix_reference_exception
Berry fix reference when exeception is raised
This commit is contained in:
commit
9a14602e6d
@ -61,6 +61,7 @@ struct pcall {
|
|||||||
|
|
||||||
struct vmstate {
|
struct vmstate {
|
||||||
int top, reg, depth;
|
int top, reg, depth;
|
||||||
|
int refcount;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct strbuf {
|
struct strbuf {
|
||||||
@ -125,6 +126,7 @@ static void vm_state_save(bvm *vm, struct vmstate *state)
|
|||||||
state->depth = be_stack_count(&vm->callstack);
|
state->depth = be_stack_count(&vm->callstack);
|
||||||
state->top = cast_int(vm->top - vm->stack);
|
state->top = cast_int(vm->top - vm->stack);
|
||||||
state->reg = cast_int(vm->reg - 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)
|
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)
|
static void vm_state_restore(bvm *vm, const struct vmstate *state, int res)
|
||||||
{
|
{
|
||||||
vm->reg = vm->stack + state->reg;
|
vm->reg = vm->stack + state->reg;
|
||||||
|
be_vector_resize(vm, &vm->refstack, state->refcount);
|
||||||
/* copy exception information to top */
|
/* copy exception information to top */
|
||||||
copy_exception(vm, res, state->top);
|
copy_exception(vm, res, state->top);
|
||||||
be_assert(be_stack_count(&vm->callstack) >= state->depth);
|
be_assert(be_stack_count(&vm->callstack) >= state->depth);
|
||||||
@ -444,6 +447,7 @@ void be_except_block_setup(bvm *vm)
|
|||||||
/* set longjmp() jump point */
|
/* set longjmp() jump point */
|
||||||
frame->errjmp.status = 0;
|
frame->errjmp.status = 0;
|
||||||
frame->errjmp.prev = vm->errjmp; /* save long jump list */
|
frame->errjmp.prev = vm->errjmp; /* save long jump list */
|
||||||
|
frame->refcount = vm->refstack.count; /* save reference pointer */
|
||||||
vm->errjmp = &frame->errjmp;
|
vm->errjmp = &frame->errjmp;
|
||||||
fixup_exceptstack(vm, lbase);
|
fixup_exceptstack(vm, lbase);
|
||||||
}
|
}
|
||||||
@ -455,6 +459,7 @@ void be_except_block_resume(bvm *vm)
|
|||||||
struct bexecptframe *frame = be_stack_top(&vm->exceptstack);
|
struct bexecptframe *frame = be_stack_top(&vm->exceptstack);
|
||||||
if (errorcode == BE_EXCEPTION) {
|
if (errorcode == BE_EXCEPTION) {
|
||||||
vm->errjmp = vm->errjmp->prev;
|
vm->errjmp = vm->errjmp->prev;
|
||||||
|
be_vector_resize(vm, &vm->refstack, frame->refcount);
|
||||||
/* jump to except instruction */
|
/* jump to except instruction */
|
||||||
vm->ip = frame->ip + IGET_sBx(frame->ip[-1]);
|
vm->ip = frame->ip + IGET_sBx(frame->ip[-1]);
|
||||||
if (be_stack_count(&vm->callstack) > frame->depth) {
|
if (be_stack_count(&vm->callstack) > frame->depth) {
|
||||||
|
@ -45,6 +45,7 @@ struct bexecptframe {
|
|||||||
struct blongjmp errjmp; /* long jump information */
|
struct blongjmp errjmp; /* long jump information */
|
||||||
int depth; /* function call stack depth */
|
int depth; /* function call stack depth */
|
||||||
binstruction *ip; /* instruction pointer */
|
binstruction *ip; /* instruction pointer */
|
||||||
|
int refcount; /* save object reference stack */
|
||||||
};
|
};
|
||||||
|
|
||||||
void be_throw(bvm *vm, int errorcode);
|
void be_throw(bvm *vm, int errorcode);
|
||||||
|
31
lib/libesp32/berry/tests/reference.be
Normal file
31
lib/libesp32/berry/tests/reference.be
Normal file
@ -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…
x
Reference in New Issue
Block a user