From a08b54b29557ff687b3c40c6800833a4dc949be5 Mon Sep 17 00:00:00 2001 From: Stephan Hadinger Date: Mon, 15 Nov 2021 19:14:35 +0100 Subject: [PATCH] Fix Berry compound assignment --- lib/libesp32/Berry/src/be_code.c | 18 +++++++++++------- 1 file changed, 11 insertions(+), 7 deletions(-) diff --git a/lib/libesp32/Berry/src/be_code.c b/lib/libesp32/Berry/src/be_code.c index 6a332bb07..3fac0bbcd 100644 --- a/lib/libesp32/Berry/src/be_code.c +++ b/lib/libesp32/Berry/src/be_code.c @@ -335,12 +335,15 @@ static void free_suffix(bfuncinfo *finfo, bexpdesc *e) } } -static int suffix_destreg(bfuncinfo *finfo, bexpdesc *e1, int dst) +static int suffix_destreg(bfuncinfo *finfo, bexpdesc *e1, int dst, bbool no_reg_reuse) { int cand_dst = dst; /* candidate for new dst */ int nlocal = be_list_count(finfo->local); int reg1 = (e1->v.ss.tt == ETREG) ? e1->v.ss.obj : -1; /* check if obj is ETREG or -1 */ int reg2 = (!isK(e1->v.ss.idx) && e1->v.ss.idx >= nlocal) ? e1->v.ss.idx : -1; /* check if idx is ETREG or -1 */ + if (no_reg_reuse) { /* if no_reg_reuse flag, then don't reuse any register, this is useful for compound assignments */ + reg1 = reg2 = -1; + } if (reg1 >= 0 && reg2 >= 0) { /* both are ETREG, we keep the lowest and discard the other */ @@ -364,9 +367,9 @@ static int suffix_destreg(bfuncinfo *finfo, bexpdesc *e1, int dst) return dst; } -static int code_suffix(bfuncinfo *finfo, bopcode op, bexpdesc *e, int dst) +static int code_suffix(bfuncinfo *finfo, bopcode op, bexpdesc *e, int dst, bbool no_reg_reuse) { - dst = suffix_destreg(finfo, e, dst); + dst = suffix_destreg(finfo, e, dst, no_reg_reuse); if (dst > finfo->freereg) { dst = finfo->freereg; } @@ -400,6 +403,7 @@ static bbool constint(bfuncinfo *finfo, bint i) /* At exit, If dst is `freereg`, the register is allocated */ static int var2reg(bfuncinfo *finfo, bexpdesc *e, int dst) { + bbool no_reg_reuse = (dst >= 0); /* if dst reg is explicitly specified, do not optimize register allocation */ if (dst < 0) { /* if unspecified, allocate a new register if needed */ dst = finfo->freereg; } @@ -434,10 +438,10 @@ static int var2reg(bfuncinfo *finfo, bexpdesc *e, int dst) codeABx(finfo, OP_GETUPV, dst, e->v.idx); break; case ETMEMBER: - dst = code_suffix(finfo, OP_GETMBR, e, dst); + dst = code_suffix(finfo, OP_GETMBR, e, dst, no_reg_reuse); break; case ETINDEX: - dst = code_suffix(finfo, OP_GETIDX, e, dst); + dst = code_suffix(finfo, OP_GETIDX, e, dst, no_reg_reuse); break; case ETLOCAL: case ETREG: case ETCONST: return e->v.idx; @@ -479,6 +483,7 @@ static int exp2reg(bfuncinfo *finfo, bexpdesc *e, int dst) /* Returns the destination register, guaranteed to be ETREG */ static int codedestreg(bfuncinfo *finfo, bexpdesc *e1, bexpdesc *e2, int dst) { + if (dst < 0) { dst = finfo->freereg; } int cand_dst = dst; int con1 = e1->type == ETREG, con2 = e2->type == ETREG; @@ -506,7 +511,6 @@ static int codedestreg(bfuncinfo *finfo, bexpdesc *e1, bexpdesc *e2, int dst) /* On exit, e1 is guaranteed to be ETREG, which may have been allocated */ static void binaryexp(bfuncinfo *finfo, bopcode op, bexpdesc *e1, bexpdesc *e2, int dst) { - if (dst < 0) { dst = finfo->freereg; } int src1 = exp2reg(finfo, e1, dst); /* potentially force the target for src1 reg */ int src2 = exp2anyreg(finfo, e2); dst = codedestreg(finfo, e1, e2, dst); @@ -720,7 +724,7 @@ int be_code_getmethod(bfuncinfo *finfo, bexpdesc *e) { int dst = finfo->freereg; be_assert(e->type == ETMEMBER); - dst = code_suffix(finfo, OP_GETMET, e, dst); + dst = code_suffix(finfo, OP_GETMET, e, dst, bfalse); /* method [object] args */ be_code_allocregs(finfo, dst == finfo->freereg ? 2 : 1); return dst;