bc: fix compiler for set!
as first subexpression of begin0
An optimization relatively late in the BC bytecode compiler pipeline was wrong for `begin0`. The transformation and bug must be a very old, since it's intended to help the bytecode interpreter. Thanks to Sage for reporting and Alexis for initial debugging.
This commit is contained in:
parent
2de28c8cf3
commit
22069faebc
|
@ -2273,6 +2273,15 @@
|
||||||
(err/rt-test (write c (open-output-bytes))
|
(err/rt-test (write c (open-output-bytes))
|
||||||
exn:fail?))
|
exn:fail?))
|
||||||
|
|
||||||
|
;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||||
|
;; Regression test to make sure `(set! ...)` on a local variable
|
||||||
|
;; in the first position of ` begin0` is not miscompiled
|
||||||
|
|
||||||
|
(test (void) (let ([i 0])
|
||||||
|
(λ () (begin0
|
||||||
|
(set! i (add1 i))
|
||||||
|
(+ i 1)))))
|
||||||
|
|
||||||
;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||||
|
|
||||||
(report-errs)
|
(report-errs)
|
||||||
|
|
|
@ -506,13 +506,15 @@ static Scheme_Object *resolve_wcm(Scheme_Object *o, Resolve_Info *info)
|
||||||
|
|
||||||
static Scheme_Object *look_for_letv_change(Scheme_Sequence *s)
|
static Scheme_Object *look_for_letv_change(Scheme_Sequence *s)
|
||||||
{
|
{
|
||||||
int i;
|
int i, start;
|
||||||
|
|
||||||
/* Change (begin e1 ... (set!-for-let [x 10] (void)) e2 ...)
|
/* Change (begin e1 ... (set!-for-let [x 10] (void)) e2 ...)
|
||||||
to (begin e1 ... (set!-for-let [x 10] e2 ...)), which
|
to (begin e1 ... (set!-for-let [x 10] e2 ...)), which
|
||||||
avoids an unneeded recursive call in the evaluator */
|
avoids an unneeded recursive call in the evaluator */
|
||||||
|
|
||||||
for (i = 0; i < s->count - 1; i++) {
|
start = ((SCHEME_TYPE(s) == scheme_begin0_sequence_type) ? 1 : 0);
|
||||||
|
|
||||||
|
for (i = start; i < s->count - 1; i++) {
|
||||||
Scheme_Object *v;
|
Scheme_Object *v;
|
||||||
v = s->array[i];
|
v = s->array[i];
|
||||||
if (SAME_TYPE(SCHEME_TYPE(v), scheme_let_value_type)) {
|
if (SAME_TYPE(SCHEME_TYPE(v), scheme_let_value_type)) {
|
||||||
|
@ -570,7 +572,7 @@ static Scheme_Object *resolve_sequence(Scheme_Object *o, Resolve_Info *info)
|
||||||
le = resolve_expr(s->array[i], info);
|
le = resolve_expr(s->array[i], info);
|
||||||
s->array[i] = le;
|
s->array[i] = le;
|
||||||
}
|
}
|
||||||
|
|
||||||
return look_for_letv_change(s);
|
return look_for_letv_change(s);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue
Block a user