Skip to content

Commit 678a241

Browse files
authored
Merge pull request #456 from s-hadinger/berry_parser_022025
Fix parser bug in rare case
2 parents 23c6576 + a01304a commit 678a241

File tree

2 files changed

+21
-2
lines changed

2 files changed

+21
-2
lines changed

src/be_code.c

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -698,15 +698,20 @@ static void setsfxvar(bfuncinfo *finfo, bopcode op, bexpdesc *e1, int src)
698698
int be_code_setvar(bfuncinfo *finfo, bexpdesc *e1, bexpdesc *e2, bbool keep_reg)
699699
{
700700
/* free_e2 indicates special case where ETINDEX or ETMEMBER need to be freed if top of registers */
701-
bbool free_e2 = (e2->type == ETINDEX || e2->type == ETMEMBER) && (e2->v.ss.idx != e1->v.idx) && (e2->v.ss.idx == finfo->freereg - 1);
701+
bbool free_e2 = (e2->type == ETINDEX || e2->type == ETMEMBER) &&
702+
(((e2->v.ss.idx != e1->v.idx) && (e2->v.ss.idx == finfo->freereg - 1)) ||
703+
((e2->v.ss.obj != e1->v.idx) && (e2->v.ss.obj == finfo->freereg - 1)) );
702704
int src = exp2reg(finfo, e2,
703705
e1->type == ETLOCAL ? e1->v.idx : -1); /* Convert e2 to kreg */
704706
/* If e1 is a local variable, use the register */
705707

706708
if (!keep_reg && (e1->type != ETLOCAL || e1->v.idx != src)) {
707709
free_expreg(finfo, e2); /* free source (checks only ETREG) */ /* TODO e2 is at top */
708710
} else if (!keep_reg && free_e2) {
709-
be_code_freeregs(finfo, 1);
711+
/* remove only if we know it's not a local variable */
712+
if (finfo->freereg > (bbyte)be_list_count(finfo->local)) {
713+
be_code_freeregs(finfo, 1);
714+
}
710715
}
711716
switch (e1->type) {
712717
case ETLOCAL: /* It can't be ETREG. */

tests/parser.be

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,3 +9,17 @@ def f()
99
end
1010
end
1111
assert(f() == 2)
12+
13+
# Parser error reported in Feb 2025
14+
def parse_022025()
15+
var s, value
16+
var js = {'a':{'a':1}}
17+
value = js['a']['a']
18+
19+
if value != nil
20+
for x:0..1
21+
return x
22+
end
23+
end
24+
end
25+
assert(parse_022025() == 0)

0 commit comments

Comments
 (0)