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) {
obj prd = ac, cns = spop();
/* arrange return to cwmv code w/cns */
ckx(prd); ckx(cns);
spush(cns);
spush(cx_callmv_2Dadapter_2Dclosure);
spush(obj_from_fixnum(0));
/* call the producer */
rd = prd; rx = obj_from_fixnum(0); ac = obj_from_fixnum(0);
callsubi();
obj t = ac, x = spop();
ckx(t); ckx(x);
if (vmcloref(x, 0) == cx_continuation_2Dadapter_2Dcode) {
/* arrange call of t with x as continuation */
int n = vmclolen(x) - 1;
assert((cxg_rend - cxg_regs - VM_REGC) > n);
sp = r + VM_REGC; /* stack is empty */
memcpy(sp, &vmcloref(x, 1), n*sizeof(obj));
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) {
/* 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 */
spush(val); ac = obj_from_fixnum(1);
rd = cns; rx = obj_from_fixnum(0);
rd = x; rx = obj_from_fixnum(0);
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)
/* 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, "%cwmv", 2, "%2_!K4")
declare_integrable(NULL, NULL, 0, "%sdmv", -1, "K6")