call-with-values w/continuation as consumer tail-calls

This commit is contained in:
ESL 2023-03-11 15:40:06 -05:00
parent be7f66fe9d
commit 75e26a58d9
2 changed files with 23 additions and 12 deletions

34
i.c
View file

@ -400,23 +400,35 @@ define_instruction(appl) {
} }
define_instruction(cwmv) { define_instruction(cwmv) {
obj prd = ac, cns = spop(); obj t = ac, x = spop();
/* arrange return to cwmv code w/cns */ ckx(t); ckx(x);
ckx(prd); ckx(cns); if (vmcloref(x, 0) == cx_continuation_2Dadapter_2Dcode) {
spush(cns); /* arrange call of t with x as continuation */
spush(cx_callmv_2Dadapter_2Dclosure); int n = vmclolen(x) - 1;
spush(obj_from_fixnum(0)); assert((cxg_rend - cxg_regs - VM_REGC) > n);
/* call the producer */ sp = r + VM_REGC; /* stack is empty */
rd = prd; rx = obj_from_fixnum(0); ac = obj_from_fixnum(0); memcpy(sp, &vmcloref(x, 1), n*sizeof(obj));
callsubi(); sp += n; /* contains n elements now */
rd = t; rx = obj_from_fixnum(0);
ac = obj_from_fixnum(0);
callsubi();
} else {
/* arrange return to cwmv code w/x */
spush(x);
spush(cx_callmv_2Dadapter_2Dclosure);
spush(obj_from_fixnum(0));
/* call the producer */
rd = t; rx = obj_from_fixnum(0); ac = obj_from_fixnum(0);
callsubi();
}
} }
define_instruction(rcmv) { define_instruction(rcmv) {
/* single-value producer call returns here with result in ac, cns on stack */ /* single-value producer call returns here with result in ac, cns on stack */
obj val = ac, cns = spop(); obj val = ac, x = spop();
/* tail-call the consumer with the returned value */ /* tail-call the consumer with the returned value */
spush(val); ac = obj_from_fixnum(1); spush(val); ac = obj_from_fixnum(1);
rd = cns; rx = obj_from_fixnum(0); rd = x; rx = obj_from_fixnum(0);
callsubi(); callsubi();
} }

1
i.h
View file

@ -482,7 +482,6 @@ declare_integrable(NULL, "addd", 0, "%cdddar", 1, INLINED)
declare_integrable(NULL, "dddd", 0, "%cddddr", 1, INLINED) declare_integrable(NULL, "dddd", 0, "%cddddr", 1, INLINED)
/* globals */ /* globals */
declare_integrable(NULL, NULL, 0, "%ccc", 1, "%1K1,.1[11")
declare_integrable(NULL, NULL, 0, "%appl", 2, "%2_!K3") declare_integrable(NULL, NULL, 0, "%appl", 2, "%2_!K3")
declare_integrable(NULL, NULL, 0, "%cwmv", 2, "%2_!K4") declare_integrable(NULL, NULL, 0, "%cwmv", 2, "%2_!K4")
declare_integrable(NULL, NULL, 0, "%sdmv", -1, "K6") declare_integrable(NULL, NULL, 0, "%sdmv", -1, "K6")