-
Notifications
You must be signed in to change notification settings - Fork 99
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Bad code and parser confusion with closure, upval and assignment with modification #344
Comments
Thanks. As discussed on Discord this will not be a high priority, especially if fixing this risks breaking something else. |
Yeah, for now I'll cut back on using the assignment with modification combined operator. |
There is definitely a problem in register allocation: def test()
var nv = 1
var f =
def()
nv += 2*1
end
end
import solidify
solidify.dump(test) Here is the output: /********************************************************************
** Solidified function: test
********************************************************************/
be_local_closure(test, /* name */
be_nested_proto(
2, /* nstack */
0, /* argc */
0, /* varg */
0, /* has upvals */
NULL, /* no upvals */
1, /* has sup protos */
( &(const struct bproto*[ 1]) {
be_nested_proto(
1, /* nstack */
0, /* argc */
0, /* varg */
1, /* has upvals */
( &(const bupvaldesc[ 1]) { /* upvals */
be_local_const_upval(1, 0),
}),
0, /* has sup protos */
NULL, /* no sub protos */
1, /* has constants */
( &(const bvalue[ 2]) { /* constants */
/* K0 */ be_const_int(2),
/* K1 */ be_const_int(1),
}),
&be_const_str__anonymous_,
&be_const_str_solidified,
( &(const binstruction[ 5]) { /* code */
0x08020101, // 0000 MUL R0 K0 K1
0x68000000, // 0001 GETUPV R0 U0
0x00000000, // 0002 ADD R0 R0 R0
0x6C000000, // 0003 SETUPV R0 U0
0x80000000, // 0004 RET 0
})
),
}),
1, /* has constants */
( &(const bvalue[ 1]) { /* constants */
/* K0 */ be_const_int(1),
}),
&be_const_str_test,
&be_const_str_solidified,
( &(const binstruction[ 4]) { /* code */
0x58000000, // 0000 LDCONST R0 K0
0x84040000, // 0001 CLOSURE R1 P0
0xA0000000, // 0002 CLOSE R0
0x80000000, // 0003 RET 0
})
)
);
/*******************************************************************/ The culprit is obviously 0x08020101, // 0000 MUL R0 K0 K1
0x68000000, // 0001 GETUPV R0 U0 <---- R0 is being overriden
0x00000000, // 0002 ADD R0 R0 R0 <---- WRONG!!!
0x6C000000, // 0003 SETUPV R0 U0 It should be something like 0x08020101, // 0000 MUL R0 K0 K1
0x68000000, // 0001 GETUPV R1 U0
0x00000000, // 0002 ADD R1 R0 R1
0x6C000000, // 0003 SETUPV R1 U0 To double check: def test()
var nv = 1
var f =
def()
nv += 2
end
end
import solidify
solidify.dump(test) Now the output is correct: [...]
( &(const bvalue[ 1]) { /* constants */
/* K0 */ be_const_int(2),
}),
&be_const_str__anonymous_,
&be_const_str_solidified,
( &(const binstruction[ 4]) { /* code */
0x68000000, // 0000 GETUPV R0 U0
0x00000100, // 0001 ADD R0 R0 K0
0x6C000000, // 0002 SETUPV R0 U0
0x80000000, // 0003 RET 0
})
[...] |
Unsurprisingly, testing did no longer produce errors. |
Debugging some surprising behavior when coding in Berry, I whittled the anomaly experienced down to a couple of simple test cases easy to repeat. The basis is that I have a local var expected to be captured and modified as an upval in a closure.
The "perpetrator" seems to be the line
nv += 2*1
- it works if I reduce it tonv += 2
or "flatten" it tonv = nv + 2*1
.The above was one result of reducing code from a more concerning case with bad code generated. Here's a "less reduced" variant exhibiting that behavior.
Expected outcome of this "stupid" code is that nv simply should be incremented each iteration. Instead it is doubled. If I move the
print(nv)
after the assignment, I get the register overflow error instead, basically the first test case. Does not seem to depend on the use of theset_timer_repeat
convenience function.To further simplify, here's the same situation without involving any Tasmota extensions:
If I instead of the test() function enter the body 3 lines in the REPL, I get the correct increments instead of the bad doubling. Seems to make a difference with a local vs global variable.
The text was updated successfully, but these errors were encountered: