Skip to content

Commit 20c4a8d

Browse files
committed
Adding initial implementation of call-with-continuation-mark
1 parent 8140707 commit 20c4a8d

File tree

2 files changed

+32
-2
lines changed

2 files changed

+32
-2
lines changed

src/sagittarius/private/vm.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -442,6 +442,8 @@ SG_EXTERN SgObject Sg_VMCallCP(SgObject proc, SgObject tag,
442442
SgObject handler, SgObject args);
443443
/* call-with-continuation-barrier */
444444
SG_EXTERN SgObject Sg_VMCallCB(SgObject thunk);
445+
/* call-with-continuation-mark */
446+
SG_EXTERN SgObject Sg_VMCallCM(SgObject key, SgObject value, SgObject thunk);
445447
SG_EXTERN SgObject Sg_VMCallComp(SgObject proc, SgObject tag);
446448
SG_EXTERN SgObject Sg_VMCallDelimitedCC(SgObject proc, SgObject tag);
447449
SG_EXTERN SgObject Sg_VMAbortCC(SgObject tag, SgObject args);

src/vm.c

Lines changed: 30 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1019,6 +1019,15 @@ static void expand_stack(SgVM *vm);
10191019

10201020
#define C_CONT_MARK NULL
10211021

1022+
static void push_cont_marks(SgVM *vm, SgContFrame *cont)
1023+
{
1024+
SgContMarks *cm = SG_NEW(SgContMarks);
1025+
cm->frame = cont;
1026+
cm->entries = NULL;
1027+
cm->prev = vm->marks;
1028+
vm->marks = cm;
1029+
}
1030+
10221031
void Sg_VMPushCC(SgCContinuationProc *after, void **data, int datasize)
10231032
{
10241033
int i;
@@ -1039,6 +1048,7 @@ void Sg_VMPushCC(SgCContinuationProc *after, void **data, int datasize)
10391048
for (i = 0; i < datasize; i++) {
10401049
PUSH(s, SG_OBJ(data[i]));
10411050
}
1051+
push_cont_marks(vm, cc);
10421052
CONT(vm) = cc;
10431053
FP(vm) = SP(vm) = s;
10441054
}
@@ -1063,6 +1073,7 @@ enum {
10631073
newcont->pc = (SgWord *)next_pc; \
10641074
newcont->cl = CL(vm); \
10651075
newcont->fp = FP(vm); \
1076+
push_cont_marks(vm, newcont); \
10661077
CONT(vm) = newcont; \
10671078
SP(vm) += CONT_FRAME_SIZE; \
10681079
} while (0)
@@ -2336,6 +2347,18 @@ SgObject Sg_VMCallCB(SgObject thunk)
23362347
return Sg_VMApply0(thunk);
23372348
}
23382349

2350+
/* this will be wrapped by the with-continuation-mark macro */
2351+
SgObject Sg_VMCallCM(SgObject key, SgObject value, SgObject thunk)
2352+
{
2353+
SgVM *vm = theVM;
2354+
SgMarkEntry *e = SG_NEW(SgMarkEntry);
2355+
e->key = key;
2356+
e->value = value;
2357+
e->next = vm->marks->entries;
2358+
vm->marks->entries = e;
2359+
return Sg_VMApply0(thunk);
2360+
}
2361+
23392362
SgObject Sg_MakeContinuationPromptTag(SgObject name)
23402363
{
23412364
return make_prompt_tag(name);
@@ -2698,18 +2721,23 @@ static SG_DEFINE_SUBR(default_exception_handler_rec, 1, 0,
26982721

26992722
#define TAIL_POS(vm) (*PC(vm) == RET)
27002723

2701-
static SgContFrame *skip_prompt_frame(SgContFrame *cont)
2724+
static SgContFrame *skip_prompt_frame(SgVM *vm)
27022725
{
2726+
SgContFrame *cont = vm->cont;
2727+
SgContMarks *marks = vm->marks;
27032728
while (PROMPT_FRAME_MARK_P(cont)) {
27042729
remove_prompt(theVM, (SgPrompt *)cont->pc);
27052730
cont = cont->prev;
2731+
marks = marks->prev;
27062732
}
2733+
vm->marks = marks;
27072734
return cont;
27082735
}
27092736

27102737
#define POP_CONT() \
27112738
do { \
2712-
SgContFrame *cont__ = skip_prompt_frame(CONT(vm)); \
2739+
SgContFrame *cont__ = skip_prompt_frame(vm); \
2740+
vm->marks = vm->marks->prev; \
27132741
if (cont__->fp == C_CONT_MARK) { \
27142742
void *data__[SG_CCONT_DATA_SIZE]; \
27152743
SgObject v__ = AC(vm); \

0 commit comments

Comments
 (0)