diff --git a/CHANGELOG.md b/CHANGELOG.md index 898d03825..9ba59092e 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -11,6 +11,7 @@ All notable changes to this project will be documented in this file. ### Changed ### Fixed +- Berry bug when parsing ternary operator ### Removed diff --git a/lib/libesp32/berry/default/be_re_lib.c b/lib/libesp32/berry/default/be_re_lib.c index 43999e400..ab7f6644c 100644 --- a/lib/libesp32/berry/default/be_re_lib.c +++ b/lib/libesp32/berry/default/be_re_lib.c @@ -8,6 +8,7 @@ #include "be_constobj.h" #include "be_mem.h" #include "be_object.h" +#include "be_exec.h" #include "../../re1.5/re1.5.h" /******************************************************************** diff --git a/lib/libesp32/berry/src/be_code.c b/lib/libesp32/berry/src/be_code.c index 7a1b2bd00..103dbb31a 100644 --- a/lib/libesp32/berry/src/be_code.c +++ b/lib/libesp32/berry/src/be_code.c @@ -84,7 +84,7 @@ static int codeABx(bfuncinfo *finfo, bopcode op, int a, int bx) /* returns false if the move operation happened, or true if there was a register optimization and `b` should be replaced by `a` */ static bbool code_move(bfuncinfo *finfo, int a, int b) { - if (finfo->pc) { /* If not the first instruction of the function */ + if (finfo->pc > finfo->binfo->lastjmp) { /* If not the first instruction of the function */ binstruction *i = be_vector_end(&finfo->code); /* get the last instruction */ bopcode op = IGET_OP(*i); if (op <= OP_LDNIL) { /* binop or unop */ @@ -171,6 +171,13 @@ static int get_jump(bfuncinfo *finfo, int pc) static void patchlistaux(bfuncinfo *finfo, int list, int vtarget, int dtarget) { + /* mark the last destination point of a jump to avoid false register optimization */ + if (vtarget > finfo->binfo->lastjmp) { + finfo->binfo->lastjmp = vtarget; + } + if (dtarget > finfo->binfo->lastjmp) { + finfo->binfo->lastjmp = dtarget; + } while (list != NO_JUMP) { int next = get_jump(finfo, list); if (isjumpbool(finfo, list)) { diff --git a/lib/libesp32/berry/src/be_introspectlib.c b/lib/libesp32/berry/src/be_introspectlib.c index ba54aad25..78e7eb0e5 100644 --- a/lib/libesp32/berry/src/be_introspectlib.c +++ b/lib/libesp32/berry/src/be_introspectlib.c @@ -122,7 +122,7 @@ static int m_toptr(bvm *vm) if (top >= 1) { bvalue *v = be_indexof(vm, 1); if (var_type(v) == BE_STRING) { - be_pushcomptr(vm, be_tostring(vm, 1)); + be_pushcomptr(vm, (void*)be_tostring(vm, 1)); be_return(vm); } else if (var_basetype(v) >= BE_FUNCTION || var_type(v) == BE_COMPTR) { be_pushcomptr(vm, var_toobj(v)); diff --git a/lib/libesp32/berry/src/be_parser.c b/lib/libesp32/berry/src/be_parser.c index be001bf97..0c79a66c5 100644 --- a/lib/libesp32/berry/src/be_parser.c +++ b/lib/libesp32/berry/src/be_parser.c @@ -197,6 +197,7 @@ static void begin_block(bfuncinfo *finfo, bblockinfo *binfo, int type) binfo->type = (bbyte)type; binfo->hasupval = 0; binfo->sideeffect = 0; + binfo->lastjmp = 0; binfo->beginpc = finfo->pc; /* set starting pc for this block */ binfo->nactlocals = (bbyte)be_list_count(finfo->local); /* count number of local variables in previous block */ if (type & BLOCK_LOOP) { diff --git a/lib/libesp32/berry/src/be_parser.h b/lib/libesp32/berry/src/be_parser.h index 8498bfa99..9b7d11e0e 100644 --- a/lib/libesp32/berry/src/be_parser.h +++ b/lib/libesp32/berry/src/be_parser.h @@ -53,7 +53,8 @@ typedef struct bblockinfo { bbyte nactlocals; /* number of active local variables */ bbyte type; /* block type mask */ bbyte hasupval; /* has upvalue mark */ - bbyte sideeffect; /* did the last expr/statement had a side effect */ + bbyte sideeffect; /* did the last expr/statement had a side effect */ + int lastjmp; /* pc for the last jump, prevents false register optimizations */ int breaklist; /* break list */ int beginpc; /* begin pc */ int continuelist; /* continue list */ diff --git a/lib/libesp32/berry/tests/parser.be b/lib/libesp32/berry/tests/parser.be new file mode 100644 index 000000000..2b64b4c50 --- /dev/null +++ b/lib/libesp32/berry/tests/parser.be @@ -0,0 +1,11 @@ +# Test some sparser specific bugs + +# https://github.com/berry-lang/berry/issues/396 +def f() + if true + var a = 1 + a = true ? a+1 : a+2 + return a + end +end +assert(f() == 2)