From c135198ca33a84922cbf7436729fc847b1057f8e Mon Sep 17 00:00:00 2001 From: Kristian Larsson Date: Wed, 22 Jul 2026 18:42:31 +0200 Subject: [PATCH] Split Msg into transport envelope and future MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit One B_Msg object used to play three roles: the mailbox envelope carrying a call to an actor, that actor's activation frame while the call runs, and the future the caller awaits. Three roles with two different owners and two different lifetimes in one allocation. This splits it into two objects, and the names land where they belong: B_Msg now denotes the message itself — the transport envelope — and the awaitable becomes Future[A] / B_Future. - B_Msg is the transport envelope, a hand-written RTS type not exposed to Acton source: $next linkage, $to, $cont, $baseline, value, and a $fut link to the future it fulfills. The actor mailbox fields become $msg/$msg_tail/$msg_lock/$outgoing, typed B_Msg; the compiler's prim environment types those slots so generated actor headers agree with the RTS, and builtin.h forward-declares B_Msg for generated code. - The future keeps the surface role under its proper name: with the envelope split out, what remains of Msg[A] is precisely the future an async call returns, so the surface type becomes Future[A] and its C type B_Future. It keeps $waiting/$wait_lock (the waiter list) and gains an explicit $state (FUT_PENDING/FUT_VALUE/FUT_EXCEPTION) replacing the old encoding of result state in the $cont field. $ASYNC/$AFTER allocate one of each and link them via env->$fut; the dispatch loop freezes results into the future and wakes its waiters. The waiter helpers (ADD_waiting, FREEZE_waiting, $AWAIT) take the future. The rename is user-visible (source annotating Msg[A] must say Future[A]) but behavior-neutral: generated code treats the future opaquely, only calling $ASYNC/$AWAIT/$AFTER. The rename portions in the compiler passes, the lib-test fixtures, net.ext.c, function.h and __builtin__.act are mechanical token substitutions. In the class id table the future's id is FUTURE_ID and the envelope gets its own preassigned MSG_ID, like the other RTS types. With --db, both kinds of row live in MSGS_TABLE and recovery branches on the class id to allocate the right struct. serialize_msg/serialize_future are split accordingly. The dead $waitsfor persistence branch is dropped: it is provably NULL at every serialize point, since recovery replays a parked actor's whole turn from the envelope at its mailbox head. After envelopes carry no future at all: "after" is a statement, its value cannot be bound or awaited (the parser rejects it), so the future $AFTER used to allocate was bound by generated code into a dead temporary and dropped, once per timer. The AFTER prims are now typed to return None, $AFTER returns B_None and leaves $fut NULL, and the dispatch loop skips result delivery for a NULL future. Timer handling deals purely in envelopes. A dev-guide page (runtime/messages.md) documents the design: the two roles and lifetimes, why the per-actor memory model forces the separation, how $ASYNC links the two, and how the split shows up in DB persistence. The await semantics tests' docstrings are updated to the split terminology (waiter lists, freezing and result state belong to the future); the test bodies are unchanged. --- base/builtin/builtin.h | 2 + base/builtin/function.h | 6 +- base/builtin/registration.h | 10 +- base/rts/q.c | 52 +-- base/rts/rts.c | 312 +++++++++++------- base/rts/rts.h | 108 ++++-- base/src/__builtin__.act | 2 +- base/src/net.ext.c | 2 +- compiler/lib/src/Acton/Boxing.hs | 18 +- compiler/lib/src/Acton/Builtin.hs | 8 +- compiler/lib/src/Acton/CodeGen.hs | 28 +- compiler/lib/src/Acton/Deactorizer.hs | 6 +- compiler/lib/src/Acton/LambdaLifter.hs | 2 +- compiler/lib/src/Acton/Prim.hs | 32 +- compiler/lib/src/Acton/QuickType.hs | 4 +- compiler/lib/src/Acton/Types.hs | 4 +- compiler/lib/test/3-types/deact.output | 4 +- compiler/lib/test/4-normalizer/deact.input | 4 +- compiler/lib/test/4-normalizer/deact.output | 4 +- compiler/lib/test/5-deactorizer/deact.input | 4 +- compiler/lib/test/5-deactorizer/deact.output | 4 +- compiler/lib/test/7-lambdalifting/deact.input | 4 +- .../lib/test/7-lambdalifting/deact.output | 4 +- compiler/lib/test/8-boxing/deact.input | 4 +- compiler/lib/test/8-boxing/deact.output | 4 +- compiler/lib/test/9-codegen/deact.c | 82 ++--- compiler/lib/test/9-codegen/deact.h | 44 +-- compiler/lib/test/9-codegen/deact.input | 4 +- compiler/lib/test/9-codegen/lines.c | 86 ++--- compiler/lib/test/9-codegen/lines.h | 48 +-- compiler/lib/test/9-codegen/lines.input | 4 +- compiler/tests/env.c | 18 +- compiler/tests/test.act | 2 +- docs/acton-dev-guide/src/SUMMARY.md | 1 + docs/acton-dev-guide/src/runtime/messages.md | 161 +++++++++ test/core_lang_auto/await_already_done.act | 12 +- test/core_lang_auto/await_already_failed.act | 11 +- test/core_lang_auto/await_chain.act | 16 +- test/core_lang_auto/await_exc_escaped.act | 5 +- test/core_lang_auto/await_exc_multi.act | 6 +- test/core_lang_auto/await_fan_in.act | 10 +- test/core_lang_auto/await_fan_out.act | 11 +- test/core_lang_auto/await_mixed_outcomes.act | 12 +- test/core_lang_auto/await_queued_msgs.act | 2 +- test/core_lang_auto/await_relay.act | 14 +- test/core_lang_auto/await_values.act | 9 +- 46 files changed, 752 insertions(+), 438 deletions(-) create mode 100644 docs/acton-dev-guide/src/runtime/messages.md diff --git a/base/builtin/builtin.h b/base/builtin/builtin.h index 5d9dadb4d..35ffeb069 100644 --- a/base/builtin/builtin.h +++ b/base/builtin/builtin.h @@ -73,8 +73,10 @@ typedef struct $R $R; struct $Actor; struct $Catcher; +struct B_Msg; typedef struct $Actor *$Actor; typedef struct $Catcher *$Catcher; +typedef struct B_Msg *B_Msg; #define $Lock volatile atomic_flag diff --git a/base/builtin/function.h b/base/builtin/function.h index a7c193037..cafd4908c 100644 --- a/base/builtin/function.h +++ b/base/builtin/function.h @@ -55,7 +55,7 @@ struct $actionG_class { B_str (*__repr__)($action); $R (*__call__)($action, $Cont, $WORD); $R (*__exec__)($action, $Cont, $WORD); - B_Msg (*__asyn__)($action, $WORD); + B_Future (*__asyn__)($action, $WORD); }; struct $action { struct $actionG_class *$class; @@ -118,7 +118,7 @@ struct $action2G_class { B_str (*__repr__)($action2); $R (*__call__)($action2, $Cont, $WORD, $WORD); $R (*__exec__)($action2, $Cont, $WORD, $WORD); - B_Msg (*__asyn__)($action2, $WORD, $WORD); + B_Future (*__asyn__)($action2, $WORD, $WORD); }; struct $action2 { struct $action2G_class *$class; @@ -138,7 +138,7 @@ struct $action3G_class { B_str (*__repr__)($action3); $R (*__call__)($action3, $Cont, $WORD, $WORD, $WORD); $R (*__exec__)($action3, $WORD, $WORD, $WORD); - B_Msg (*__asyn__)($action3, $WORD, $WORD, $WORD); + B_Future (*__asyn__)($action3, $WORD, $WORD, $WORD); }; struct $action3 { struct $action3G_class *$class; diff --git a/base/builtin/registration.h b/base/builtin/registration.h index 68a329e11..b4b2dd5ff 100644 --- a/base/builtin/registration.h +++ b/base/builtin/registration.h @@ -26,7 +26,7 @@ #define BYTEARRAY_ID 12 #define BYTES_ID 13 #define ITEM_ID 14 -#define MSG_ID 15 +#define FUTURE_ID 15 #define ACTOR_ID 16 #define CATCHER_ID 17 #define SLICE_ID 18 // Adding SLICE_ID by using a gap in the numbering... @@ -90,13 +90,15 @@ #define WEQNONE_ID 68 #define IDENTITYACTOR_ID 69 -#define PREASSIGNED 72 +#define MSG_ID 72 // transport envelope B_Msg (RTS-internal, see rts.h) + +#define PREASSIGNED 73 /* - * Register the builtin classes (those with the above class id's except MSG_ID -- CONSTCONT_ID). + * Register the builtin classes (those with the above class id's except FUTURE_ID -- CONSTCONT_ID and MSG_ID). * This must be the first registration call, since it also initializes the data structures containing the mapping. - * This call does *not* register the rts class id's MSG_ID -- CONSTCONT_ID, which must be registered by + * This call does *not* register the rts class id's FUTURE_ID -- CONSTCONT_ID and MSG_ID, which must be registered by * a call to register_rts in rts.h. */ diff --git a/base/rts/q.c b/base/rts/q.c index f536a7345..e001f1357 100644 --- a/base/rts/q.c +++ b/base/rts/q.c @@ -136,17 +136,17 @@ int ENQ_ready($Actor a) { // return true if the queue was previously empty. bool ENQ_msg(B_Msg m, $Actor a) { bool did_enq = true; - spinlock_lock(&a->B_Msg_lock); + spinlock_lock(&a->$msg_lock); m->$next = NULL; - if (a->B_Msg_tail) { - a->B_Msg_tail->$next = m; - a->B_Msg_tail = m; + if (a->$msg_tail) { + a->$msg_tail->$next = m; + a->$msg_tail = m; did_enq = false; } else { - a->B_Msg = m; - a->B_Msg_tail = m; + a->$msg = m; + a->$msg_tail = m; } - spinlock_unlock(&a->B_Msg_lock); + spinlock_unlock(&a->$msg_lock); return did_enq; } @@ -154,19 +154,19 @@ bool ENQ_msg(B_Msg m, $Actor a) { // return true if the queue still holds messages. bool DEQ_msg($Actor a) { bool has_more = false; - spinlock_lock(&a->B_Msg_lock); - B_Msg x = a->B_Msg; + spinlock_lock(&a->$msg_lock); + B_Msg x = a->$msg; if (x) { - a->B_Msg = x->$next; + a->$msg = x->$next; x->$next = NULL; - if (a->B_Msg == NULL) { - a->B_Msg_tail = NULL; + if (a->$msg == NULL) { + a->$msg_tail = NULL; } - has_more = a->B_Msg != NULL; + has_more = a->$msg != NULL; } else { - a->B_Msg_tail = NULL; + a->$msg_tail = NULL; } - spinlock_unlock(&a->B_Msg_lock); + spinlock_unlock(&a->$msg_lock); return has_more; } #else // MSGQ == 1 @@ -174,18 +174,18 @@ bool DEQ_msg($Actor a) { // return true if the queue was previously empty. bool ENQ_msg(B_Msg m, $Actor a) { bool did_enq = true; - spinlock_lock(&a->B_Msg_lock); + spinlock_lock(&a->$msg_lock); m->$next = NULL; - if (a->B_Msg) { - B_Msg x = a->B_Msg; + if (a->$msg) { + B_Msg x = a->$msg; while (x->$next) x = x->$next; x->$next = m; did_enq = false; } else { - a->B_Msg = m; + a->$msg = m; } - spinlock_unlock(&a->B_Msg_lock); + spinlock_unlock(&a->$msg_lock); return did_enq; } @@ -193,14 +193,14 @@ bool ENQ_msg(B_Msg m, $Actor a) { // return true if the queue still holds messages. bool DEQ_msg($Actor a) { bool has_more = false; - spinlock_lock(&a->B_Msg_lock); - if (a->B_Msg) { - B_Msg x = a->B_Msg; - a->B_Msg = x->$next; + spinlock_lock(&a->$msg_lock); + if (a->$msg) { + B_Msg x = a->$msg; + a->$msg = x->$next; x->$next = NULL; - has_more = a->B_Msg != NULL; + has_more = a->$msg != NULL; } - spinlock_unlock(&a->B_Msg_lock); + spinlock_unlock(&a->$msg_lock); return has_more; } #endif // MSGQ diff --git a/base/rts/rts.c b/base/rts/rts.c index 85221f925..b53be01a5 100644 --- a/base/rts/rts.c +++ b/base/rts/rts.c @@ -427,44 +427,39 @@ struct termios old_stdin_attr; //////////////////////////////////////////////////////////////////////////////////////// -/* - -The strangeness of the next 30 lines are caused by the unfortunate presence of Msg in __builtin__.act. - --- This generates a stub of B_MsgD___init__ with wrong parameters, and its presence in the method table, so we define it here, but never use it. --- The out-commented version is how __init__ should really be defined --- The B_msgG_newXX function now inlines the proper __init__; it has to be renamed because of a generated and improper B_msgG_new. - -*/ - -B_NoneType B_MsgD___init__ (B_Msg G_1p) { +// B_Future is the compiler-generated Future[A] builtin (from __builtin__.act). +// The compiler emits a B_FutureD___init__ stub with the wrong signature into the +// method table; we provide this never-called definition to satisfy it. Futures are +// actually created via B_FutureG_new() below. +B_NoneType B_FutureD___init__ (B_Future G_1p) { // Must (and will) never be called! return B_None; } -/* -void B_MsgD___init__(B_Msg m, $Actor to, $Cont cont, time_t baseline, $WORD value) { - m->$next = NULL; - m->$to = to; - m->$cont = cont; - m->$waiting = NULL; - m->$baseline = baseline; - m->value = value; - atomic_flag_clear(&m->$wait_lock); - m->$globkey = get_next_key(); +// Allocate a fresh pending future. +B_Future B_FutureG_new() { + B_Future f = GC_malloc(sizeof(struct B_Future)); + f->$class = &B_FutureG_methods; + f->$waiting = NULL; + f->$state = FUT_PENDING; + f->value = NULL; + atomic_flag_clear(&f->$wait_lock); + f->$globkey = get_next_key(); + return f; } -*/ -B_Msg B_MsgG_newXX( $Actor to, $Cont cont, time_t baseline, $WORD value) { +// Allocate a transport envelope addressed to actor "to", carrying continuation +// "cont" with argument "value", to run at logical time "baseline". $fut is set by +// the caller ($ASYNC/$AFTER) to the future this envelope fulfills. +B_Msg B_MsgG_newXX($Actor to, $Cont cont, time_t baseline, $WORD value) { B_Msg m = GC_malloc(sizeof(struct B_Msg)); m->$class = &B_MsgG_methods; m->$next = NULL; m->$to = to; m->$cont = cont; - m->$waiting = NULL; m->$baseline = baseline; m->value = value; - atomic_flag_clear(&m->$wait_lock); + m->$fut = NULL; m->$globkey = get_next_key(); return m; } @@ -472,6 +467,46 @@ B_Msg B_MsgG_newXX( $Actor to, $Cont cont, time_t baseline, $WORD value) { //////////////////////////////////////////////////////////////////////// +bool B_FutureD___bool__(B_Future self) { + return true; +} + +B_str B_FutureD___str__(B_Future self) { + return $FORMAT("", self); +} + +B_str B_FutureD___repr__(B_Future self) { + return B_FutureD___str__(self); +} + +void B_FutureD___serialize__(B_Future self, $Serial$state state) { + $step_serialize(self->value,state); + $val_serialize(ITEM_ID,&self->$state,state); +} + + +B_Future B_FutureD___deserialize__(B_Future res, $Serial$state state) { + if (!res) { + if (!state) { + res = GC_malloc(sizeof (struct B_Future)); + res->$class = &B_FutureG_methods; + return res; + } + res = $DNEW(B_Future,state); + } + res->$waiting = NULL; + res->value = $step_deserialize(state); + res->$state = ($int64)$val_deserialize(state); + atomic_flag_clear(&res->$wait_lock); + return res; +} + +//////////////////////////////////////////////////////////////////////// + +void B_MsgD___init__(B_Msg self) { + // Must (and will) never be called! +} + bool B_MsgD___bool__(B_Msg self) { return true; } @@ -489,9 +524,9 @@ void B_MsgD___serialize__(B_Msg self, $Serial$state state) { $step_serialize(self->$cont,state); $val_serialize(ITEM_ID,&self->$baseline,state); $step_serialize(self->value,state); + $step_serialize(self->$fut,state); // envelope→future link } - B_Msg B_MsgD___deserialize__(B_Msg res, $Serial$state state) { if (!res) { if (!state) { @@ -504,10 +539,9 @@ B_Msg B_MsgD___deserialize__(B_Msg res, $Serial$state state) { res->$next = NULL; res->$to = $step_deserialize(state); res->$cont = $step_deserialize(state); - res->$waiting = NULL; res->$baseline = (time_t)$val_deserialize(state); res->value = $step_deserialize(state); - atomic_flag_clear(&res->$wait_lock); + res->$fut = $step_deserialize(state); // restore envelope→future link (resolved via globdict) return res; } @@ -515,12 +549,13 @@ B_Msg B_MsgD___deserialize__(B_Msg res, $Serial$state state) { void $ActorD___init__($Actor a) { a->$next = NULL; - a->B_Msg = NULL; + a->$msg = NULL; + a->$msg_tail = NULL; a->$outgoing = NULL; a->$waitsfor = NULL; a->$consume_hd = 0; a->$catcher = NULL; - atomic_flag_clear(&a->B_Msg_lock); + atomic_flag_clear(&a->$msg_lock); a->$globkey = get_next_key(); a->$affinity = SHARED_RQ; rtsd_printf("# New Actor %ld at %p of class %s", a->$globkey, a, a->$class->$GCINFO); @@ -558,12 +593,13 @@ void $ActorD___serialize__($Actor self, $Serial$state state) { res = $DNEW($Actor, state); } res->$next = NULL; - res->B_Msg = NULL; + res->$msg = NULL; + res->$msg_tail = NULL; res->$outgoing = NULL; res->$waitsfor = $step_deserialize(state); res->$consume_hd = (long)$val_deserialize(state); res->$catcher = $step_deserialize(state); - atomic_flag_clear(&res->B_Msg_lock); + atomic_flag_clear(&res->$msg_lock); if (res->$affinity > 0) res->$affinity = SHARED_RQ; return res; @@ -639,19 +675,19 @@ void $ConstContD___serialize__($ConstCont self, $Serial$state state) { //////////////////////////////////////////////////////////////////////////////////////// -/* +// Method table for the RTS-internal B_Msg transport envelope. Hand-written (cf. +// the compiler-generated B_FutureG_methods). struct B_MsgG_class B_MsgG_methods = { MSG_HEADER, UNASSIGNED, NULL, - NULL, + B_MsgD___init__, B_MsgD___serialize__, B_MsgD___deserialize__, B_MsgD___bool__, B_MsgD___str__, - B_MsgD___str__ + B_MsgD___repr__ }; -*/ struct $ActorG_class $ActorG_methods = { ACTOR_HEADER, @@ -695,37 +731,36 @@ struct $ConstContG_class $ConstContG_methods = { //////////////////////////////////////////////////////////////////////////////////////// -#define MARK_RESULT NULL -#define MARK_EXCEPTION ($Cont)1 - -#define EXCEPTIONAL(m) (m->$cont == MARK_EXCEPTION) -#define FROZEN(m) (m->$cont == MARK_RESULT || EXCEPTIONAL(m)) +// Future result-state constants FUT_PENDING/FUT_VALUE/FUT_EXCEPTION are in rts.h. +#define EXCEPTIONAL(m) (m->$state == FUT_EXCEPTION) +#define FROZEN(m) (m->$state != FUT_PENDING) -// Atomically add actor "a" to the waiting list of messasge "m" if it is not frozen (and return true), +// Atomically add actor "a" to the waiting list of future "fut" if it is not frozen (and return true), // else immediately return false. -bool ADD_waiting($Actor a, B_Msg m) { +bool ADD_waiting($Actor a, B_Future fut) { bool did_add = false; - assert(m != NULL); + assert(fut != NULL); - spinlock_lock(&m->$wait_lock); - if (!FROZEN(m)) { - a->$next = m->$waiting; - m->$waiting = a; - a->$waitsfor = m; + spinlock_lock(&fut->$wait_lock); + if (!FROZEN(fut)) { + a->$next = fut->$waiting; + fut->$waiting = a; + a->$waitsfor = fut; did_add = true; } - spinlock_unlock(&m->$wait_lock); + spinlock_unlock(&fut->$wait_lock); return did_add; } -// Atomically freeze message "m" using "mark", and return its list of waiting actors. -$Actor FREEZE_waiting(B_Msg m, $Cont mark) { - spinlock_lock(&m->$wait_lock); - m->$cont = mark; - $Actor res = m->$waiting; - m->$waiting = NULL; - spinlock_unlock(&m->$wait_lock); +// Atomically freeze future "fut" into result-state "st" (FUT_VALUE / FUT_EXCEPTION), +// and return its list of waiting actors. +$Actor FREEZE_waiting(B_Future fut, $int64 st) { + spinlock_lock(&fut->$wait_lock); + fut->$state = st; + $Actor res = fut->$waiting; + fut->$waiting = NULL; + spinlock_unlock(&fut->$wait_lock); return res; } @@ -753,7 +788,7 @@ bool ENQ_timed(B_Msg m) { return new_head; } -// Atomically dequeue and return the first message from the global timer-queue if +// Atomically dequeue and return the first message from the global timer-queue if // its baseline is less or equal to "now", else return NULL. B_Msg DEQ_timed(time_t now) { spinlock_lock(&timerQ_lock); @@ -930,34 +965,44 @@ void PUSH_catcher($Actor a, $Catcher c) { return c; } -B_Msg $ASYNC($Actor to, $Cont cont) { +// An async call allocates TWO objects — a short-lived transport envelope delivered +// to the callee, and the future/promise returned to the caller — linked by +// env->$fut. The dispatch loop delivers the result into the future via env->$fut +// (see $RDONE/$RFAIL). Their lifetimes are separate: the envelope (B_Msg) is +// consumed on delivery; the future (B_Future) lives while the caller holds it. +B_Future $ASYNC($Actor to, $Cont cont) { $Actor self = GET_SELF(); time_t baseline = 0; - B_Msg m = B_MsgG_newXX(to, cont, baseline, &$Done$instance); + B_Future fut = B_FutureG_new(); // future returned to the caller + B_Msg env = B_MsgG_newXX(to, cont, baseline, &$Done$instance); // envelope delivered to the callee + env->$fut = fut; // envelope fulfills this future if (self) { // $ASYNC called by actor code - m->$baseline = self->B_Msg->$baseline; - PUSH_outgoing(self, m); + env->$baseline = self->$msg->$baseline; + PUSH_outgoing(self, env); } else { // $ASYNC called by the event loop - m->$baseline = current_time(); - if (ENQ_msg(m, to)) { + env->$baseline = current_time(); + if (ENQ_msg(env, to)) { int wtid = ENQ_ready(to); wake_wt(wtid); } } - return m; + return fut; } -B_Msg $AFTER(B_float sec, $Cont cont) { +B_NoneType $AFTER(B_float sec, $Cont cont) { $Actor self = GET_SELF(); rtsd_printf("# AFTER by %ld", self->$globkey); - time_t baseline = self->B_Msg->$baseline + sec->val * 1000000; - B_Msg m = B_MsgG_newXX(self, cont, baseline, &$Done$instance); - PUSH_outgoing(self, m); - return m; + time_t baseline = self->$msg->$baseline + sec->val * 1000000; + B_Msg env = B_MsgG_newXX(self, cont, baseline, &$Done$instance); // timer envelope + // "after" is a statement: the surface language cannot bind or await its + // result, so no future is materialized ($fut stays NULL and the dispatch + // loop skips result delivery). + PUSH_outgoing(self, env); + return B_None; } -$R $AWAIT($Cont cont, B_Msg m) { - return $R_WAIT(cont, m); +$R $AWAIT($Cont cont, B_Future fut) { + return $R_WAIT(cont, fut); } $R $PUSH_C($Cont cont) { @@ -1086,7 +1131,7 @@ void FLUSH_outgoing_db($Actor self, uuid_t *txnid) { rtsd_printf("#### FLUSH_outgoing messages from %ld to DB queues", self->$globkey); B_Msg m = self->$outgoing; while (m) { - long dest = (m->$baseline == self->B_Msg->$baseline)? m->$to->$globkey : 0; + long dest = (m->$baseline == self->$msg->$baseline)? m->$to->$globkey : 0; int ret = 0, minority_status = 0; while(!rts_exit) { ret = remote_enqueue_in_txn(($WORD*)&m->$globkey, 1, NULL, 0, MSG_QUEUE, (WORD)dest, &minority_status, txnid, db); @@ -1113,7 +1158,7 @@ void FLUSH_outgoing_local($Actor self) { B_Msg next = m->$next; m->$next = NULL; long dest; - if (m->$baseline == self->B_Msg->$baseline) { + if (m->$baseline == self->$msg->$baseline) { $Actor to = m->$to; if (ENQ_msg(m, to)) { ENQ_ready(to); @@ -1261,7 +1306,7 @@ void print_msg(B_Msg m) { rtsd_printf(" next: %p", m->$next); rtsd_printf(" to: %p", m->$to); rtsd_printf(" cont: %p", m->$cont); - rtsd_printf(" waiting: %p", m->$waiting); + rtsd_printf(" fut: %p", m->$fut); rtsd_printf(" baseline: %ld", m->$baseline); rtsd_printf(" value: %p", m->value); rtsd_printf(" globkey: %ld", m->$globkey); @@ -1270,7 +1315,7 @@ void print_msg(B_Msg m) { void print_actor($Actor a) { rtsd_printf("==== Actor %p", a); rtsd_printf(" next: %p", a->$next); - rtsd_printf(" msg: %p", a->B_Msg); + rtsd_printf(" msg: %p", a->$msg); rtsd_printf(" outgoing: %p", a->$outgoing); rtsd_printf(" waitsfor: %p", a->$waitsfor); rtsd_printf(" consume_hd: %ld", (long)a->$consume_hd); @@ -1309,10 +1354,16 @@ void deserialize_system(snode_t *actors_start) { db_row_t* r2 = (HEAD(r->cells))->value; rtsd_printf("# r2 %p, key: %ld, cells: %p, columns: %p, no_cols: %d, blobsize: %d", r2, (long)r2->key, r2->cells, r2->column_array, r2->no_columns, r2->last_blob_size); BlobHd *head = (BlobHd*)r2->column_array[0]; - B_Msg msg = (B_Msg)$GET_METHODS(head->class_id)->__deserialize__(NULL, NULL); - msg->$globkey = key; - B_dictD_setitem(globdict, (B_Hashable)B_HashableD_intG_witness, to$int(key), msg); - rtsd_printf("# Allocated Msg %p = %ld of class %s = %d", msg, msg->$globkey, msg->$class->$GCINFO, msg->$class->$class_id); + // A MSGS_TABLE row is either a B_Msg envelope or a B_Future future; the + // stored class_id selects which. $globkey lives at a different offset in + // each, so set it via the correct type. + $WORD obj = $GET_METHODS(head->class_id)->__deserialize__(NULL, NULL); + if (head->class_id == MSG_ID) + ((B_Msg)obj)->$globkey = key; + else + ((B_Future)obj)->$globkey = key; + B_dictD_setitem(globdict, (B_Hashable)B_HashableD_intG_witness, to$int(key), obj); + rtsd_printf("# Allocated Msg/Future %p = %ld", obj, key); if (key < min_key) min_key = key; } @@ -1346,11 +1397,10 @@ void deserialize_system(snode_t *actors_start) { $WORD *blob = ($WORD*)r2->column_array[0]; int blob_size = r2->last_blob_size; $ROW row = extract_row(blob, blob_size); - B_Msg msg = (B_Msg)B_dictD_get(globdict, (B_Hashable)B_HashableD_intG_witness, to$int(key), NULL); - rtsd_printf("####### Deserializing msg %p = %ld of class %s = %d", msg, msg->$globkey, msg->$class->$GCINFO, msg->$class->$class_id); + $Serializable msg = ($Serializable)B_dictD_get(globdict, (B_Hashable)B_HashableD_intG_witness, to$int(key), NULL); + rtsd_printf("####### Deserializing msg %p = %ld of class %s = %d", msg, key, msg->$class->$GCINFO, msg->$class->$class_id); print_rows(row); - $glob_deserialize(($Serializable)msg, row, try_globdict); - print_msg(msg); + $glob_deserialize(msg, row, try_globdict); } } @@ -1368,10 +1418,10 @@ void deserialize_system(snode_t *actors_start) { print_rows(row); $glob_deserialize(($Serializable)act, row, try_globdict); - B_Msg m = act->$waitsfor; - if (m && !FROZEN(m)) { - ADD_waiting(act, m); - rtsd_printf("# Adding Actor %ld to wait for Msg %ld", act->$globkey, m->$globkey); + B_Future fut = act->$waitsfor; + if (fut && !FROZEN(fut)) { + ADD_waiting(act, fut); + rtsd_printf("# Adding Actor %ld to wait for future %ld", act->$globkey, fut->$globkey); } else { act->$waitsfor = NULL; @@ -1384,11 +1434,11 @@ void deserialize_system(snode_t *actors_start) { long msg_key = read_queued_msg(key, &prev_read_head); if (!msg_key) break; - m = B_dictD_get(globdict, (B_Hashable)B_HashableD_intG_witness, to$int(msg_key), NULL); - rtsd_printf("# Adding Msg %ld to Actor %ld", m->$globkey, act->$globkey); - ENQ_msg(m, act); + B_Msg env = (B_Msg)B_dictD_get(globdict, (B_Hashable)B_HashableD_intG_witness, to$int(msg_key), NULL); + rtsd_printf("# Adding Msg %ld to Actor %ld", env->$globkey, act->$globkey); + ENQ_msg(env, act); } - if (act->B_Msg && !act->$waitsfor) { + if (act->$msg && !act->$waitsfor) { ENQ_ready(act); rtsd_printf("# Adding Actor %ld to the readyQ", act->$globkey); } @@ -1412,7 +1462,7 @@ void deserialize_system(snode_t *actors_start) { long msg_key = read_queued_msg(TIMER_QUEUE, &prev_read_head); if (!msg_key) break; - B_Msg m = B_dictD_get(globdict, (B_Hashable)B_HashableD_intG_witness, to$int(msg_key), NULL); + B_Msg m = (B_Msg)B_dictD_get(globdict, (B_Hashable)B_HashableD_intG_witness, to$int(msg_key), NULL); if (m->$baseline < now) m->$baseline = now; rtsd_printf("# Adding Msg %ld to the timerQ", m->$globkey); @@ -1438,9 +1488,12 @@ void deserialize_system(snode_t *actors_start) { $WORD try_globkey($WORD obj) { $SerializableG_class c = (($Serializable)obj)->$class; - if (c->$class_id == MSG_ID) { + if (c == ($SerializableG_class)&B_MsgG_methods) { // transport envelope long key = ((B_Msg)obj)->$globkey; return ($WORD)key; + } else if (c->$class_id == FUTURE_ID) { // future + long key = ((B_Future)obj)->$globkey; + return ($WORD)key; } else if (c->$class_id == ACTOR_ID || c->$superclass && c->$superclass->$class_id == ACTOR_ID) { long key = (($Actor)obj)->$globkey; return ($WORD)key; @@ -1492,11 +1545,24 @@ void insert_row(long key, size_t total, $ROW row, $WORD table, uuid_t *txnid) { } } +// Persist a future into MSGS_TABLE (futures and envelopes share the table; each +// row carries its own class_id so recovery allocates the right type). +void serialize_future(B_Future f, uuid_t *txnid) { + rtsd_printf("#### Serializing Future %ld", f->$globkey); + $ROW row = $glob_serialize(($Serializable)f, try_globkey); + print_rows(row); + insert_row(f->$globkey, $total_rowsize(row), row, MSGS_TABLE, txnid); +} + +// Persist a transport envelope into MSGS_TABLE, plus the future it fulfills so the +// env->$fut reference resolves on recovery. void serialize_msg(B_Msg m, uuid_t *txnid) { rtsd_printf("#### Serializing Msg %ld", m->$globkey); $ROW row = $glob_serialize(($Serializable)m, try_globkey); print_rows(row); insert_row(m->$globkey, $total_rowsize(row), row, MSGS_TABLE, txnid); + if (m->$fut) + serialize_future(m->$fut, txnid); } void serialize_actor($Actor a, uuid_t *txnid) { @@ -1510,6 +1576,10 @@ void serialize_actor($Actor a, uuid_t *txnid) { serialize_msg(out, txnid); out = out->$next; } + // NOTE: a->$waitsfor is provably NULL at every call site (the $RWAIT commit + // serializes before ADD_waiting, and woken actors are cleared before they + // are re-scheduled), so no waiter state is persisted: recovery relies on + // whole-turn replay of the parked envelope. } #endif @@ -1544,7 +1614,9 @@ void BOOTSTRAP(int argc, char *argv[]) { root_actor = $ROOT(); // Assumed to return $NEWACTOR(X) for the selected root actor X time_t now = current_time(); + B_Future fut = B_FutureG_new(); B_Msg m = B_MsgG_newXX(root_actor, &$InitRoot$cont, now, &$Done$instance); + m->$fut = fut; // nothing awaits the root, but $RDONE delivers into $fut #ifdef ACTON_DB if (db) { int ret = 0, minority_status = 0; @@ -1574,7 +1646,7 @@ void save_actor_state($Actor current, B_Msg m) { current->$consume_hd++; serialize_actor(current, txnid); FLUSH_outgoing_db(current, txnid); - serialize_msg(current->B_Msg, txnid); + serialize_msg(current->$msg, txnid); long key = current->$globkey; snode_t *m_start, *m_end; @@ -1681,7 +1753,7 @@ void wt_work_cb(uv_check_t *ev) { wake_wt(SHARED_RQ); SET_SELF(current); - volatile B_Msg m = current->B_Msg; + volatile B_Msg m = current->$msg; $Cont cont = m->$cont; $WORD val = m->value; @@ -1724,15 +1796,18 @@ void wt_work_cb(uv_check_t *ev) { switch (r.tag) { case $RDONE: { save_actor_state(current, m); - m->value = r.value; // m->value holds the message result, - $Actor b = FREEZE_waiting(m, MARK_RESULT); // so mark this and stop further m->waiting additions - while (b) { - b->B_Msg->value = r.value; - b->$waitsfor = NULL; - $Actor c = b->$next; - ENQ_ready(b); - rtsd_printf("## Waking up actor %ld : %s", b->$globkey, b->$class->$GCINFO); - b = c; + B_Future fut = m->$fut; // the future this envelope fulfills + if (fut) { // NULL for after envelopes: nothing can await them + fut->value = r.value; // deliver the result into the future + $Actor b = FREEZE_waiting(fut, FUT_VALUE); // freeze as VALUE; stop further $waiting additions + while (b) { + b->$msg->value = fut->value; + b->$waitsfor = NULL; + $Actor c = b->$next; + ENQ_ready(b); + rtsd_printf("## Waking up actor %ld : %s", b->$globkey, b->$class->$GCINFO); + b = c; + } } rtsd_printf("## DONE actor %ld : %s", current->$globkey, current->$class->$GCINFO); if (DEQ_msg(current)) { @@ -1758,8 +1833,12 @@ void wt_work_cb(uv_check_t *ev) { } else { // An unhandled exception save_actor_state(current, m); B_BaseException ex = (B_BaseException)r.value; - m->value = r.value; // m->value holds the raised exception, - $Actor b = FREEZE_waiting(m, MARK_EXCEPTION); // so mark this and stop further m->waiting additions + B_Future fut = m->$fut; // the future this envelope fulfills + $Actor b = NULL; + if (fut) { // NULL for after envelopes: nothing can await them + fut->value = r.value; // deliver the exception into the future + b = FREEZE_waiting(fut, FUT_EXCEPTION); // freeze as EXCEPTION; stop further $waiting additions + } // If any other actor is waiting for our result / exception, // then we consider the exception handled and we can avoid // printing the exception both in the originating actor and in @@ -1768,8 +1847,8 @@ void wt_work_cb(uv_check_t *ev) { if (!b) fprintf(stderr, "Unhandled exception in actor: %s[%ld]:\n %s\n", unmangle_name(current->$class->$GCINFO), current->$globkey, fromB_str(ex->$class->__str__(ex))); while (b) { - b->B_Msg->$cont = &$Fail$instance; - b->B_Msg->value = r.value; + b->$msg->$cont = &$Fail$instance; + b->$msg->value = fut->value; b->$waitsfor = NULL; $Actor c = b->$next; ENQ_ready(b); @@ -1794,7 +1873,7 @@ void wt_work_cb(uv_check_t *ev) { continue; serialize_actor(current, txnid); FLUSH_outgoing_db(current, txnid); - serialize_msg(current->B_Msg, txnid); + serialize_msg(current->$msg, txnid); ret = remote_commit_txn(txnid, &minority_status, db); rtsd_printf("############## Commit returned %d, minority_status %d", ret, minority_status); if(handle_status_and_schema_mismatch(ret, minority_status, current->$globkey)) @@ -1809,20 +1888,20 @@ void wt_work_cb(uv_check_t *ev) { } #endif m->$cont = r.cont; - B_Msg x = (B_Msg)r.value; + B_Future x = (B_Future)r.value; assert(x != NULL); bool added_waiting = ADD_waiting(current, x); FLUSH_outgoing_local(current); - if (added_waiting) { // x->cont is a proper $Cont: x is still being processed so current was added to x->waiting + if (added_waiting) { // x still PENDING: current was added to x->$waiting rtsd_printf("## AWAIT actor %ld : %s", current->$globkey, current->$class->$GCINFO); - } else if (EXCEPTIONAL(x)) { // x->cont == MARK_EXCEPTION: x->value holds the raised exception, current is not in x->waiting + } else if (EXCEPTIONAL(x)) { // x->$state == FUT_EXCEPTION: x->value holds the raised exception; current not in x->$waiting rtsd_printf("## AWAIT/fail actor %ld : %s", current->$globkey, current->$class->$GCINFO); m->$cont = &$Fail$instance; m->value = x->value; ENQ_ready(current); - } else { // x->cont == MARK_RESULT: x->value holds the final response, current is not in x->waiting + } else { // x->$state == FUT_VALUE: x->value holds the final result; current not in x->$waiting rtsd_printf("## AWAIT/wakeup actor %ld : %s", current->$globkey, current->$class->$GCINFO); m->value = x->value; ENQ_ready(current); @@ -1899,7 +1978,7 @@ void *main_loop(void *idx) { //////////////////////////////////////////////////////////////////////////////////////// void $register_rts () { - $register_force(MSG_ID,&B_MsgG_methods); + $register_force(FUTURE_ID,&B_FutureG_methods); $register_force(ACTOR_ID,&$ActorG_methods); $register_force(CATCHER_ID,&$CatcherG_methods); $register_force(PROC_ID,&$procG_methods); @@ -1917,6 +1996,9 @@ void $register_rts () { // must be registered like $Done, or serializing such a message emits no // header row for the $cont field and the blob misaligns on recovery. $register(&$FailG_methods); + // The transport envelope B_Msg is serialized into MSGS_TABLE alongside futures; + // recovery tells the two row kinds apart by class id. + $register_force(MSG_ID,&B_MsgG_methods); } //////////////////////////////////////////////////////////////////////////////////////// diff --git a/base/rts/rts.h b/base/rts/rts.h index 271f6bf24..f0c8354f0 100644 --- a/base/rts/rts.h +++ b/base/rts/rts.h @@ -81,7 +81,7 @@ struct wt_stat { }; extern struct wt_stat wt_stats[MAX_WTHREADS]; -struct B_Msg; +struct B_Future; struct $ConstCont; #ifdef ACTON_THREADS @@ -99,9 +99,10 @@ extern pthread_cond_t work_to_do; extern $Actor self_actor; -typedef struct B_Msg *B_Msg; +typedef struct B_Future *B_Future; typedef struct $ConstCont *$ConstCont; +extern struct B_FutureG_class B_FutureG_methods; extern struct B_MsgG_class B_MsgG_methods; extern struct $ActorG_class $ActorG_methods; extern struct $CatcherG_class $CatcherG_methods; @@ -115,30 +116,73 @@ extern struct $ConstContG_class $ConstContG_methods; #define CLOS_HEADER "Clos" /* Defined in builtin/__builtin__.h with wrong type for __init__ +struct B_FutureG_class { + char *$GCINFO; + int $class_id; + $SuperG_class $superclass; + void (*__init__)(B_Future, $Actor, $Cont, time_t, $WORD); + void (*__serialize__)(B_Future, $Serial$state); + B_Future (*__deserialize__)(B_Future, $Serial$state); + B_bool (*__bool__)(B_Future); + B_str (*__str__)(B_Future); + B_str (*__repr__)(B_Future); +}; +*/ +// An async call has two distinct objects with separate lifetimes: +// +// - B_Msg: the transport envelope (RTS-internal). A message in flight to an +// actor: the dispatch loop runs $cont(value) and steps it; it is consumed when +// its turn ends. +// +// - B_Future: the future/promise (the compiler-generated builtin behind the +// surface type Future[A]). The value an async call returns to its caller, which +// the caller awaits; the producing envelope delivers its result here. It is +// opaque to generated code (returned, stored, awaited; never field-accessed or +// sized), so its layout is ours. It lives as long as the caller holds it. +// +// $ASYNC allocates one of each and links them via env->$fut. After envelopes +// carry no future ("after" is a statement; its value cannot be bound). + +// Method table (vtable) for B_Msg. Hand-written RTS type (cf. compiler-generated +// B_FutureG_class). The serializable prefix ($GCINFO, $class_id, $superclass, +// __init__, __serialize__, __deserialize__, ...) matches $SerializableG_class so +// the generic serialization machinery can drive it. struct B_MsgG_class { char *$GCINFO; int $class_id; $SuperG_class $superclass; - void (*__init__)(B_Msg, $Actor, $Cont, time_t, $WORD); + void (*__init__)(B_Msg); void (*__serialize__)(B_Msg, $Serial$state); B_Msg (*__deserialize__)(B_Msg, $Serial$state); - B_bool (*__bool__)(B_Msg); + bool (*__bool__)(B_Msg); B_str (*__str__)(B_Msg); B_str (*__repr__)(B_Msg); }; -*/ struct B_Msg { struct B_MsgG_class *$class; - B_Msg $next; - $Actor $to; - $Cont $cont; - $Actor $waiting; - time_t $baseline; - $Lock $wait_lock; - $WORD value; - $long $globkey; + B_Msg $next; // mailbox / outgoing / timer linkage + $Actor $to; // recipient actor + $Cont $cont; // activation: continuation to run + time_t $baseline; // logical delivery time (normal vs timer) + $WORD value; // activation: continuation argument + B_Future $fut; // the future this envelope fulfills + $long $globkey; // identity (used for DB persistence) +}; + +struct B_Future { + struct B_FutureG_class *$class; + $Actor $waiting; // head of waiting-actor list (waiters chained via their own $next) + $Lock $wait_lock; // protects $waiting + $int64 $state; // result state — 0=PENDING, 1=VALUE, 2=EXCEPTION (see FUT_* below) + $WORD value; // the result + $long $globkey; // identity (used for DB persistence) }; +// Result-state values for B_Future.$state. +#define FUT_PENDING 0 +#define FUT_VALUE 1 +#define FUT_EXCEPTION 2 + struct $ActorG_class { char *$GCINFO; int $class_id; @@ -152,18 +196,22 @@ struct $ActorG_class { B_NoneType (*__resume__)($Actor); B_NoneType (*__cleanup__)($Actor); }; +// The mailbox/outgoing fields below hold B_Msg envelopes (messages in flight to +// this actor); $waitsfor is the future this actor is currently blocked on. The +// compiler emits the matching actor header (see Prim.hs) with these as pointer +// fields it never accesses, so the layout stays pointer-compatible. struct $Actor { struct $ActorG_class *$class; - $Actor $next; - B_Msg B_Msg; - B_Msg B_Msg_tail; - $Lock B_Msg_lock; - $int64 $affinity; - B_Msg $outgoing; - B_Msg $waitsfor; - $int64 $consume_hd; - $Catcher $catcher; - $long $globkey; + $Actor $next; // ready-queue / waiter-list linkage + B_Msg $msg; // mailbox head (envelope) — also the actor's current activation frame + B_Msg $msg_tail; // mailbox tail (envelope) + $Lock $msg_lock; // protects the mailbox + $int64 $affinity; // worker thread this actor runs on + B_Msg $outgoing; // buffered outgoing envelopes (flushed at turn end) + B_Future $waitsfor; // the future this actor is awaiting (NULL if runnable) + $int64 $consume_hd; // DB consume head + $Catcher $catcher; // exception handler stack + $long $globkey; // identity (used for DB persistence) }; struct $CatcherG_class { @@ -204,9 +252,10 @@ struct $ConstCont { }; $Cont $CONSTCONT($WORD, $Cont); -B_Msg $ASYNC($Actor, $Cont); -B_Msg $AFTER(B_float, $Cont); -$R $AWAIT($Cont, B_Msg); +B_Future $ASYNC($Actor, $Cont); +B_NoneType $AFTER(B_float, $Cont); +$R $AWAIT($Cont, B_Future); +B_Msg B_MsgG_newXX($Actor to, $Cont cont, time_t baseline, $WORD value); void init_db_queue(long); void register_actor(long key); @@ -295,6 +344,13 @@ void $Actor$serialize($Actor, B_NoneType); void $Actor$deserialize($Actor, B_NoneType); B_NoneType $ActorD___cleanup__($Actor); +bool B_FutureD___bool__(B_Future self); +B_str B_FutureD___str__(B_Future self); +B_str B_FutureD___repr__(B_Future self); +void B_FutureD___serialize__(B_Future self, $Serial$state state); +B_Future B_FutureD___deserialize__(B_Future res, $Serial$state state); + +void B_MsgD___init__(B_Msg self); bool B_MsgD___bool__(B_Msg self); B_str B_MsgD___str__(B_Msg self); B_str B_MsgD___repr__(B_Msg self); diff --git a/base/src/__builtin__.act b/base/src/__builtin__.act index d75153361..fd6314b1d 100644 --- a/base/src/__builtin__.act +++ b/base/src/__builtin__.act @@ -353,7 +353,7 @@ class bytearray (object): def zfill (self, width: int) -> bytearray: NotImplemented -class Msg[A] (value): +class Future[A] (value): NotImplemented ## Exceptions ################################################################################## diff --git a/base/src/net.ext.c b/base/src/net.ext.c index 207c6207b..35d415af7 100644 --- a/base/src/net.ext.c +++ b/base/src/net.ext.c @@ -191,7 +191,7 @@ struct udp_send_req_state { }; static void udp_call_receive($WORD cb, $WORD actor, B_bytes data, B_str address, B_int port) { - ((B_Msg (*)($WORD, $WORD, $WORD, $WORD, $WORD))(($action)cb)->$class->__asyn__)(cb, actor, data, address, port); + ((B_Future (*)($WORD, $WORD, $WORD, $WORD, $WORD))(($action)cb)->$class->__asyn__)(cb, actor, data, address, port); } static int sockaddr_to_addr_port(const struct sockaddr *addr, char *addrbuf, size_t addrbuf_len, int *port) { diff --git a/compiler/lib/src/Acton/Boxing.hs b/compiler/lib/src/Acton/Boxing.hs index aa6ede6ad..9f51b8576 100644 --- a/compiler/lib/src/Acton/Boxing.hs +++ b/compiler/lib/src/Acton/Boxing.hs @@ -260,17 +260,17 @@ boxedResultExpr env (Paren _ e) = boxedResultExpr env e boxedResultExpr env DotI{} = True boxedResultExpr env c@(Call _ f _ KwdNil) | rawClassConstructor env c f = False - | callReturnsMsg env f = False + | callReturnsFuture env f = False | otherwise = callReturnsBoxed env f boxedResultExpr env _ = False rawClassConstructor env c f = callIsClass env f && isUnboxable (boxedRepType (typeOf env c)) -exposeMsg fx t - | fx == fxAction = tMsg t +exposeFuture fx t + | fx == fxAction = tFuture t | otherwise = t -callReturnsMsg env f = case rtypeOfFun env f of +callReturnsFuture env f = case rtypeOfFun env f of TFun _ fx _ _ _ -> fx == fxAction _ -> False @@ -321,7 +321,7 @@ generatedExprType env (Box t _) = Just t generatedExprType env (UnBox t _) = Just t generatedExprType env (Call _ f _ KwdNil) = case generatedCallableType env f of - Just (TFun _ fx _ _ t) -> Just (exposeMsg fx t) + Just (TFun _ fx _ _ t) -> Just (exposeFuture fx t) _ -> Nothing generatedExprType env (Dot _ e n) = do t <- generatedExprType env e generatedDotType env t n @@ -431,7 +431,7 @@ exprUnboxedRep env c@(Call _ f _ KwdNil) = Just t | Just _ <- generatedCallableType env f = Nothing - | callReturnsMsg env f = Nothing + | callReturnsFuture env f = Nothing | rawClassConstructor env c f = unboxedRepType (typeOf env c) | Just t <- callableRawRep env f = Just t exprUnboxedRep env e @@ -645,7 +645,7 @@ instance Boxing Expr where | f `elem` prims = do (ws1,p1) <- boxing env p return (ws1, Box tBool $ eCallP e' (fixargs env p1 r)) | otherwise = do (ws1,p1) <- boxing env p - return (ws1, tryBox (exposeMsg fx t) $ eCallP e (fixargs env p1 r)) + return (ws1, tryBox (exposeFuture fx t) $ eCallP e (fixargs env p1 r)) where e' = tApp (eQVar (unboxedPrim f)) ts TFun _ fx r _ t = rtypeOfFun env e boxing env (Call l f@Async{} p KwdNil) @@ -662,7 +662,7 @@ instance Boxing Expr where boxing env (Call l f p KwdNil) = do (ws1,f1) <- boxing env f (ws2,p1) <- boxing env p let c = eCallP f1 (fixargs env p1 r) - return (HashSet.union ws1 ws2, tryBox (exposeMsg fx t) c) + return (HashSet.union ws1 ws2, tryBox (exposeFuture fx t) c) where TFun _ fx r _ t = rtypeOfFun env f boxing env (TApp l f ts) = do (ws1,f1) <- boxing env f return (ws1, TApp l f1 ts) @@ -743,7 +743,7 @@ boxValueExpr env e e1 | Box{} <- e1 = e1 | boxedResultExpr env e = e1 boxValueExpr env (Call _ f _ KwdNil) e1 - | callReturnsMsg env f = e1 + | callReturnsFuture env f = e1 boxValueExpr env (Paren _ e) e1 = boxValueExpr env e e1 boxValueExpr env e e1 | Just rt <- exprUnboxedRep env e diff --git a/compiler/lib/src/Acton/Builtin.hs b/compiler/lib/src/Acton/Builtin.hs index 5c52287fe..51c0095d5 100644 --- a/compiler/lib/src/Acton/Builtin.hs +++ b/compiler/lib/src/Acton/Builtin.hs @@ -127,7 +127,7 @@ nStr = name "str" nRepr = name "repr" nBytes = name "bytes" nRef = name "Ref" -nMsg = name "Msg" +nFuture = name "Future" nBaseException = name "BaseException" nException = name "Exception" nStopIteration = name "StopIteration" @@ -195,7 +195,7 @@ qnStr = gBuiltin nStr qnRepr = gBuiltin nRepr qnBytes = gBuiltin nBytes qnRef = gBuiltin nRef -qnMsg = gBuiltin nMsg +qnFuture = gBuiltin nFuture qnBaseException = gBuiltin nBaseException qnException = gBuiltin nException qnStopIteration = gBuiltin nStopIteration @@ -262,7 +262,7 @@ cStr = TC qnStr [] cRepr = TC qnRepr [] cBytes = TC qnBytes [] cRef = TC qnRef [] -cMsg a = TC qnMsg [a] +cFuture a = TC qnFuture [a] cList a = TC qnList [a] cDict a b = TC qnDict [a,b] cSet a = TC qnSetT [a] @@ -319,7 +319,7 @@ tBool = tCon cBool tStr = tCon cStr tBytes = tCon cBytes tRef = tCon cRef -tMsg a = tCon (cMsg a) +tFuture a = tCon (cFuture a) tList a = tCon (cList a) tDict a b = tCon (cDict a b) tSet a = tCon (cSet a) diff --git a/compiler/lib/src/Acton/CodeGen.hs b/compiler/lib/src/Acton/CodeGen.hs index e359db199..2f91c360e 100644 --- a/compiler/lib/src/Acton/CodeGen.hs +++ b/compiler/lib/src/Acton/CodeGen.hs @@ -265,7 +265,7 @@ decl env (Class _ n q a b ddoc) = (text "struct" <+> classname env n <+> cha char '}' <> semi initNotImpl = any hasNotImpl [ b' | Decl _ ds <- b, Def{dname=n',dbody=b'} <- ds, n' == initKW ] decl env (Def _ n q p _ (Just t) _ _ fx ddoc) - = repType env (exposeMsg fx t) <+> genTopName env n <+> parens (repParams env $ prowOf p) <> semi + = repType env (exposeFuture fx t) <+> genTopName env n <+> parens (repParams env $ prowOf p) <> semi decl env Typedef{} = empty methstub env (Class _ n q a b ddoc) = text "extern" <+> text "struct" <+> classname env n <+> methodtable env n <> semi $+$ constub env t n r b $+$ @@ -296,7 +296,7 @@ methodDefStub env (Def _ n q p KwdNIL (Just t) _ d fx _) NClass q _ _ _ <- findQName (NoQ c) env = Just $ B.rtypeOf env (TC (NoQ c) (map tVar $ qbound q)) n0 methodType n = B.generalType env (methnm n) - t2 = exposeMsg fx t + t2 = exposeFuture fx t t3 = settype env (rawReturn (restype t1)) t2 rawReturn TUnboxed{} = True rawReturn _ = False @@ -317,14 +317,14 @@ funsig env n (TFun _ _ r _ t) = repType env t <+> parens (char '*' <> gen funsig env n t = varsig env n t funsig2 :: GenEnv -> Maybe Name -> Type -> Doc -funsig2 env mbn (TFun _ fx p _ t) = repType env (exposeMsg fx t) <+> parens (char '*' <> maybe empty (gen env) mbn) <+> parens (repParams env p) +funsig2 env mbn (TFun _ fx p _ t) = repType env (exposeFuture fx t) <+> parens (char '*' <> maybe empty (gen env) mbn) <+> parens (repParams env p) -methsig env c n (TFun _ fx r _ t) = repType env (exposeMsg fx t) <+> parens (char '*' <> gen env n) <+> parens (repParams env $ posRow (tCon c) r) +methsig env c n (TFun _ fx r _ t) = repType env (exposeFuture fx t) <+> parens (char '*' <> gen env n) <+> parens (repParams env $ posRow (tCon c) r) methsig env c n t = varsig env n t methsig2 :: GenEnv -> TCon -> Maybe Name -> Type -> Doc methsig2 env c mbn (TFun _ fx p _ t) - = repType env (exposeMsg fx t) <+> parens (char '*' <> maybe empty (gen env) mbn) <+> parens (repParams env (posRow (tCon c) p)) + = repType env (exposeFuture fx t) <+> parens (char '*' <> maybe empty (gen env) mbn) <+> parens (repParams env (posRow (tCon c) p)) {- params env (TNil _ _) = empty @@ -334,10 +334,10 @@ params env (TRow _ _ _ t TVar{}) = gen env t params env t = error ("codegen unexpected row: " ++ prstr t) -} -exposeMsg fx t = if fx == fxAction then tMsg t else t +exposeFuture fx t = if fx == fxAction then tFuture t else t -exposeMsg' t@TFun{} = t{ restype = exposeMsg (effect t) (restype t) } -exposeMsg' t = t +exposeFuture' t@TFun{} = t{ restype = exposeFuture (effect t) (restype t) } +exposeFuture' t = t varsig env n t = storageType env t <+> gen env n @@ -524,7 +524,7 @@ declDecl env (Def dloc n q p KwdNIL (Just t) b d fx ddoc) nest 4 ss' $+$ char '}' env1 = setRet t2 $ ldefine (envOf p) $ defineTVars q env - t2 = exposeMsg fx t + t2 = exposeFuture fx t t3 = genVolatile env n <+> settype env (rawReturn (restype t1)) t2 rawReturn TUnboxed{} = True rawReturn _ = False @@ -880,7 +880,7 @@ compatibleSlots _ _ = False dropFirstRow (TRow _ _ _ _ r) = r dropFirstRow r = r -forwardResult env (TFun _ fx _ _ t) = repType env (exposeMsg fx t) +forwardResult env (TFun _ fx _ _ t) = repType env (exposeFuture fx t) forwardResult _ _ = empty repPar env (n : ns) (TRow _ _ _ t r@TRow{}) @@ -1394,7 +1394,7 @@ generatedClass env qn n ts directMethodCallResult env (Call _ f _ KwdNil) = case directMethodCallableType env f of - Just (TFun _ fx _ _ t) -> Just (exposeMsg fx t) + Just (TFun _ fx _ _ t) -> Just (exposeFuture fx t) _ -> Nothing directMethodCallResult _ _ = Nothing @@ -1684,9 +1684,9 @@ dotCast env ent ts e n TTuple{} -> ([], cValue, cValue) (sc, dec) = findAttr' env c0 n t = vsubst fullsubst $ if ent then addSelf t1 dec else t1 - t1 = exposeMsg' (sctype sc) + t1 = exposeFuture' (sctype sc) t' sc' = if ent then addSelf (t1' sc') dec else t1' sc' - t1' sc' = exposeMsg' (sctype sc') + t1' sc' = exposeFuture' (sctype sc') fullsubst = (tvSelf,t0) : (qbound (scbind sc) `zip` ts) ++ argsubst te = findAttrSchemas env (tcname c0) gen_t @@ -1696,7 +1696,7 @@ dotCast env ent ts e n Just (NSig sc' _ _) -> gen env (B.matchTypes t (t' sc')) Just (NVar t) -> gen env t ni -> error ("Internal error in CodeGen.dotCast: looking for NameInfo for " ++ show n ++ ", found "++ show ni) - rt = exposeMsg' (B.rtypeOf env rtc n) + rt = exposeFuture' (B.rtypeOf env rtc n) needsPrimCallableCast (TCon _ (TC q _)) n | q == primCont = n == attr_call_ diff --git a/compiler/lib/src/Acton/Deactorizer.hs b/compiler/lib/src/Acton/Deactorizer.hs index 30b5aec2b..a37c9ca3b 100644 --- a/compiler/lib/src/Acton/Deactorizer.hs +++ b/compiler/lib/src/Acton/Deactorizer.hs @@ -213,9 +213,9 @@ addSelfPar p = PosPar selfKW (Just tSelf) Nothing p selfRef n = Dot l0 (Var l0 (NoQ selfKW)) n --- $ASYNCf : [A] => action($Actor, proc()->A) -> Msg[A] --- $AFTERf : [A] => proc(int, proc()->A) -> Msg[A] --- $AWAITf : [A] => proc(Msg[A]) -> A +-- $ASYNCf : [A] => action($Actor, proc()->A) -> Future[A] +-- $AFTERf : [A] => proc(int, proc()->A) -> Future[A] +-- $AWAITf : [A] => proc(Future[A]) -> A instance Deact Branch where diff --git a/compiler/lib/src/Acton/LambdaLifter.hs b/compiler/lib/src/Acton/LambdaLifter.hs index f8b983c08..175c137f5 100644 --- a/compiler/lib/src/Acton/LambdaLifter.hs +++ b/compiler/lib/src/Acton/LambdaLifter.hs @@ -350,7 +350,7 @@ instance Lift Expr where | closedType env e = do e <- ll env e let vts = restrict (locals env) (free e) call = Call l0 (eDot e attr_asyn_) (pArg par) KwdNil - closureConvert env (Lambda l0 par KwdNIL call fxProc) (tMsg t) vts (map (eVar . fst) vts) + closureConvert env (Lambda l0 par KwdNIL call fxProc) (tFuture t) vts (map (eVar . fst) vts) | otherwise = do e <- ll env e return $ Async l e where par = pPar paramNames p diff --git a/compiler/lib/src/Acton/Prim.hs b/compiler/lib/src/Acton/Prim.hs index 352b92240..af3dc91ad 100644 --- a/compiler/lib/src/Acton/Prim.hs +++ b/compiler/lib/src/Acton/Prim.hs @@ -297,12 +297,12 @@ clCell = NClass [qbind a] (leftpath [cObject, cValue]) te Nothing -- class $Actor (): pass clActor = NClass [] (leftpath [cValue]) te Nothing where te = [ (primKW "next", NSig (monotype tActor) Property Nothing), - (primKW "msg", NSig (monotype (tMsg tWild)) Property Nothing), - (primKW "msg_tail", NSig (monotype (tMsg tWild)) Property Nothing), + (primKW "msg", NSig (monotype $ tCon $ TC (gBuiltin (name "Msg")) []) Property Nothing), + (primKW "msg_tail", NSig (monotype $ tCon $ TC (gBuiltin (name "Msg")) []) Property Nothing), (primKW "msg_lock", NSig (monotype $ tCon $ TC (gPrim "Lock") []) Property Nothing), (primKW "affinity", NSig (monotype $ tCon $ TC (gPrim "int64") []) Property Nothing), - (primKW "outgoing", NSig (monotype (tMsg tWild)) Property Nothing), - (primKW "waitsfor", NSig (monotype (tMsg tWild)) Property Nothing), + (primKW "outgoing", NSig (monotype $ tCon $ TC (gBuiltin (name "Msg")) []) Property Nothing), + (primKW "waitsfor", NSig (monotype (tFuture tWild)) Property Nothing), (primKW "consume_hd", NSig (monotype $ tCon $ TC (gPrim "int64") []) Property Nothing), (primKW "catcher", NSig (monotype $ tCon $ TC (gPrim "Catcher") []) Property Nothing), (primKW "globkey", NSig (monotype $ tCon $ TC (gPrim "long") []) Property Nothing), @@ -346,15 +346,15 @@ scASYNCf = tSchema [qbind a] tASYNC a = TV KType $ name "A" tFun' = tFun fxProc posNil kwdNil (tVar a) --- $AFTERf : [A] => action(int, proc()->A) -> A +-- $AFTERf : [A] => action(int, proc()->A) -> None scAFTERf = tSchema [qbind a] tAFTER - where tAFTER = tFun fxAction (posRow tFloat $ posRow tFun' posNil) kwdNil (tVar a) + where tAFTER = tFun fxAction (posRow tFloat $ posRow tFun' posNil) kwdNil tNone a = TV KType $ name "A" tFun' = tFun fxProc posNil kwdNil (tVar a) --- $AWAITf : [A] => proc(Msg[A]) -> A +-- $AWAITf : [A] => proc(Future[A]) -> A scAWAITf = tSchema [qbind a] tAWAIT - where tAWAIT = tFun fxProc (posRow (tMsg $ tVar a) posNil) kwdNil (tVar a) + where tAWAIT = tFun fxProc (posRow (tFuture $ tVar a) posNil) kwdNil (tVar a) a = TV KType $ name "T" @@ -365,16 +365,16 @@ scASYNCc = tSchema [qbind a] tASYNC tCont' = tFun fxProc (posRow tCont'' posNil) kwdNil tR tCont'' = tFun fxProc (posRow (tVar a) posNil) kwdNil tR --- $AFTERc : [A] => action(int, proc(proc(A)->$R)->$R) -> A +-- $AFTERc : [A] => action(int, proc(proc(A)->$R)->$R) -> None scAFTERc = tSchema [qbind a] tAFTER - where tAFTER = tFun fxAction (posRow tFloat $ posRow tCont' posNil) kwdNil (tVar a) + where tAFTER = tFun fxAction (posRow tFloat $ posRow tCont' posNil) kwdNil tNone a = TV KType $ name "A" tCont' = tFun fxProc (posRow tCont'' posNil) kwdNil tR tCont'' = tFun fxProc (posRow (tVar a) posNil) kwdNil tR --- $AWAITc : [A] => proc(proc(A)->$R, Msg[A]) -> $R +-- $AWAITc : [A] => proc(proc(A)->$R, Future[A]) -> $R scAWAITc = tSchema [qbind a] tAWAIT - where tAWAIT = tFun fxProc (posRow tCont' $ posRow (tMsg $ tVar a) posNil) kwdNil tR + where tAWAIT = tFun fxProc (posRow tCont' $ posRow (tFuture $ tVar a) posNil) kwdNil tR a = TV KType $ name "A" tCont' = tFun fxProc (posRow (tVar a) posNil) kwdNil tR @@ -386,16 +386,16 @@ scASYNC = tSchema [qbind a] tASYNC tCont' = tCont tCont'' tCont'' = tCont (tVar a) --- $AFTER : [A] => action(int, $Cont[$Cont[A]]) -> A +-- $AFTER : [A] => action(int, $Cont[$Cont[A]]) -> None scAFTER = tSchema [qbind a] tAFTER - where tAFTER = tFun fxAction (posRow tFloat $ posRow tCont' posNil) kwdNil (tVar a) + where tAFTER = tFun fxAction (posRow tFloat $ posRow tCont' posNil) kwdNil tNone a = TV KType $ name "A" tCont' = tCont tCont'' tCont'' = tCont (tVar a) --- $AWAIT : [A] => proc($Cont[A], Msg[A]) -> $R +-- $AWAIT : [A] => proc($Cont[A], Future[A]) -> $R scAWAIT = tSchema [qbind a] tAWAIT - where tAWAIT = tFun fxProc (posRow tCont' $ posRow (tMsg $ tVar a) posNil) kwdNil tR + where tAWAIT = tFun fxProc (posRow tCont' $ posRow (tFuture $ tVar a) posNil) kwdNil tR a = TV KType $ name "A" tCont' = tCont (tVar a) diff --git a/compiler/lib/src/Acton/QuickType.hs b/compiler/lib/src/Acton/QuickType.hs index af4f450d2..e3c309ccc 100644 --- a/compiler/lib/src/Acton/QuickType.hs +++ b/compiler/lib/src/Acton/QuickType.hs @@ -190,10 +190,10 @@ instance QType Expr where where te = envOf ss (t,fx,e') = qType (define te env) f e qType env f (Async l e) = case expanded env t of - TFun _ (TFX _ FXAction) p k t' -> (tFun fxProc p k (tMsg t'), fx, Async l e') + TFun _ (TFX _ FXAction) p k t' -> (tFun fxProc p k (tFuture t'), fx, Async l e') where (t, fx, e') = qType env f e qType env f (Await l e) = case expanded env t of - TCon _ (TC c [t]) | c == qnMsg -> (t, fxProc, Await l e') + TCon _ (TC c [t]) | c == qnFuture -> (t, fxProc, Await l e') where (t, fx, e') = qType env f e qType env f e@(BinOp l e1 op e2) | isUnboxedExpr e = (t, fx, BinOp l e1' op e2') diff --git a/compiler/lib/src/Acton/Types.hs b/compiler/lib/src/Acton/Types.hs index fa740eb5d..3837913c0 100644 --- a/compiler/lib/src/Acton/Types.hs +++ b/compiler/lib/src/Acton/Types.hs @@ -1989,9 +1989,9 @@ instance Infer Expr where t' <- newUnivar env let tf fx = tFun fx prow krow return (Cast (locinfo2 74 e) env t (tf fxAction t') : - cs, tf fxProc (tMsg t'), Async l e) -- produce a proc returning Msg[t'] + cs, tf fxProc (tFuture t'), Async l e) -- produce a proc returning Future[t'] infer env (Await l e) = do t0 <- newUnivar env - (cs1,e') <- inferSub env (tMsg t0) e + (cs1,e') <- inferSub env (tFuture t0) e fx <- currFX return (Cast (locinfo2 75 e) env fxProc fx : cs1, t0, Await l e') diff --git a/compiler/lib/test/3-types/deact.output b/compiler/lib/test/3-types/deact.output index 731fb254b..94f16289c 100644 --- a/compiler/lib/test/3-types/deact.output +++ b/compiler/lib/test/3-types/deact.output @@ -14,7 +14,7 @@ actor Apa (): proc def compute (cb : action(__builtin__.int) -> __builtin__.int) -> __builtin__.int: print@[(__builtin__.str,)](*("compute",), sep = None, end = None, err = None, flush = None) v: __builtin__.int = cb(W_Apa_39.__fromatom__(1)) - m: __builtin__.Msg[__builtin__.int] = (async cb)(W_Apa_39.__fromatom__(2)) + m: __builtin__.Future[__builtin__.int] = (async cb)(W_Apa_39.__fromatom__(2)) return W_Apa_105.__mul__(v, W_Apa_39.__fromatom__(10)) proc def notice (i : __builtin__.int) -> __builtin__.int: print@[(__builtin__.str,)](*("notice",), sep = None, end = None, err = None, flush = None) @@ -36,7 +36,7 @@ actor main (env : __builtin__.Env): b: Bepa = Bepa() print@[(__builtin__.str,)](*("-----",), sep = None, end = None, err = None, flush = None) a.setup(cb = action lambda (G_1y : __builtin__.int): a.notice(i = G_1y)) - x: __builtin__.Msg[__builtin__.int] = (async action lambda (G_1p : action(__builtin__.int) -> __builtin__.int): a.compute(cb = G_1p))(action lambda (G_1y : __builtin__.int): b.callback(i = G_1y)) + x: __builtin__.Future[__builtin__.int] = (async action lambda (G_1p : action(__builtin__.int) -> __builtin__.int): a.compute(cb = G_1p))(action lambda (G_1y : __builtin__.int): b.callback(i = G_1y)) r: __builtin__.int = await x print@[(__builtin__.str, __builtin__.int)](*("r =", r), sep = None, end = None, err = None, flush = None) a.compute(cb = action lambda (G_1y : __builtin__.int): $WRAP@[(), (i: __builtin__.int), __builtin__.int](self, myproc)(i = G_1y)) diff --git a/compiler/lib/test/4-normalizer/deact.input b/compiler/lib/test/4-normalizer/deact.input index 731fb254b..94f16289c 100644 --- a/compiler/lib/test/4-normalizer/deact.input +++ b/compiler/lib/test/4-normalizer/deact.input @@ -14,7 +14,7 @@ actor Apa (): proc def compute (cb : action(__builtin__.int) -> __builtin__.int) -> __builtin__.int: print@[(__builtin__.str,)](*("compute",), sep = None, end = None, err = None, flush = None) v: __builtin__.int = cb(W_Apa_39.__fromatom__(1)) - m: __builtin__.Msg[__builtin__.int] = (async cb)(W_Apa_39.__fromatom__(2)) + m: __builtin__.Future[__builtin__.int] = (async cb)(W_Apa_39.__fromatom__(2)) return W_Apa_105.__mul__(v, W_Apa_39.__fromatom__(10)) proc def notice (i : __builtin__.int) -> __builtin__.int: print@[(__builtin__.str,)](*("notice",), sep = None, end = None, err = None, flush = None) @@ -36,7 +36,7 @@ actor main (env : __builtin__.Env): b: Bepa = Bepa() print@[(__builtin__.str,)](*("-----",), sep = None, end = None, err = None, flush = None) a.setup(cb = action lambda (G_1y : __builtin__.int): a.notice(i = G_1y)) - x: __builtin__.Msg[__builtin__.int] = (async action lambda (G_1p : action(__builtin__.int) -> __builtin__.int): a.compute(cb = G_1p))(action lambda (G_1y : __builtin__.int): b.callback(i = G_1y)) + x: __builtin__.Future[__builtin__.int] = (async action lambda (G_1p : action(__builtin__.int) -> __builtin__.int): a.compute(cb = G_1p))(action lambda (G_1y : __builtin__.int): b.callback(i = G_1y)) r: __builtin__.int = await x print@[(__builtin__.str, __builtin__.int)](*("r =", r), sep = None, end = None, err = None, flush = None) a.compute(cb = action lambda (G_1y : __builtin__.int): $WRAP@[(), (i: __builtin__.int), __builtin__.int](self, myproc)(i = G_1y)) diff --git a/compiler/lib/test/4-normalizer/deact.output b/compiler/lib/test/4-normalizer/deact.output index bd9374fa4..56ed61038 100644 --- a/compiler/lib/test/4-normalizer/deact.output +++ b/compiler/lib/test/4-normalizer/deact.output @@ -15,7 +15,7 @@ actor Apa (): proc def compute (cb : action(__builtin__.int) -> __builtin__.int) -> __builtin__.int: print@[(__builtin__.str,)](("\"compute\"",), None, None, None, None) v: __builtin__.int = cb(W_Apa_39.__fromatom__(1)) - m: __builtin__.Msg[__builtin__.int] = (async cb)(W_Apa_39.__fromatom__(2)) + m: __builtin__.Future[__builtin__.int] = (async cb)(W_Apa_39.__fromatom__(2)) N_tmp: __builtin__.int = W_Apa_105.__mul__(v, W_Apa_39.__fromatom__(10)) return N_tmp proc def notice (i : __builtin__.int) -> __builtin__.int: @@ -40,7 +40,7 @@ actor main (env : __builtin__.Env): b: Bepa = Bepa() print@[(__builtin__.str,)](("\"-----\"",), None, None, None, None) a.setup(a.notice) - x: __builtin__.Msg[__builtin__.int] = (async a.compute)(b.callback) + x: __builtin__.Future[__builtin__.int] = (async a.compute)(b.callback) r: __builtin__.int = await x print@[(__builtin__.str, __builtin__.int)](("\"r =\"", r), None, None, None, None) a.compute($WRAP@[(), (__builtin__.int,), __builtin__.int](self, myproc)) diff --git a/compiler/lib/test/5-deactorizer/deact.input b/compiler/lib/test/5-deactorizer/deact.input index bd9374fa4..56ed61038 100644 --- a/compiler/lib/test/5-deactorizer/deact.input +++ b/compiler/lib/test/5-deactorizer/deact.input @@ -15,7 +15,7 @@ actor Apa (): proc def compute (cb : action(__builtin__.int) -> __builtin__.int) -> __builtin__.int: print@[(__builtin__.str,)](("\"compute\"",), None, None, None, None) v: __builtin__.int = cb(W_Apa_39.__fromatom__(1)) - m: __builtin__.Msg[__builtin__.int] = (async cb)(W_Apa_39.__fromatom__(2)) + m: __builtin__.Future[__builtin__.int] = (async cb)(W_Apa_39.__fromatom__(2)) N_tmp: __builtin__.int = W_Apa_105.__mul__(v, W_Apa_39.__fromatom__(10)) return N_tmp proc def notice (i : __builtin__.int) -> __builtin__.int: @@ -40,7 +40,7 @@ actor main (env : __builtin__.Env): b: Bepa = Bepa() print@[(__builtin__.str,)](("\"-----\"",), None, None, None, None) a.setup(a.notice) - x: __builtin__.Msg[__builtin__.int] = (async a.compute)(b.callback) + x: __builtin__.Future[__builtin__.int] = (async a.compute)(b.callback) r: __builtin__.int = await x print@[(__builtin__.str, __builtin__.int)](("\"r =\"", r), None, None, None, None) a.compute($WRAP@[(), (__builtin__.int,), __builtin__.int](self, myproc)) diff --git a/compiler/lib/test/5-deactorizer/deact.output b/compiler/lib/test/5-deactorizer/deact.output index 2faeca588..389768c1f 100644 --- a/compiler/lib/test/5-deactorizer/deact.output +++ b/compiler/lib/test/5-deactorizer/deact.output @@ -18,7 +18,7 @@ class Apa ($Actor, __builtin__.value): proc def computeG_local (self : Self, cb : action(__builtin__.int) -> __builtin__.int) -> __builtin__.int: print@[(__builtin__.str,)](("\"compute\"",), None, None, None, None) v: __builtin__.int = $AWAITf@[__builtin__.int]((async cb)(W_Apa_39.__fromatom__(1))) - m: __builtin__.Msg[__builtin__.int] = (async cb)(W_Apa_39.__fromatom__(2)) + m: __builtin__.Future[__builtin__.int] = (async cb)(W_Apa_39.__fromatom__(2)) N_tmp: __builtin__.int = W_Apa_105.__mul__(v, W_Apa_39.__fromatom__(10)) return N_tmp proc def noticeG_local (self : Self, i : __builtin__.int) -> __builtin__.int: @@ -48,7 +48,7 @@ class main ($Actor, __builtin__.value): @property b : Bepa @property - x : __builtin__.Msg[__builtin__.int] + x : __builtin__.Future[__builtin__.int] @property r : __builtin__.int proc def __init__ (self : Self, env : __builtin__.Env) -> None: diff --git a/compiler/lib/test/7-lambdalifting/deact.input b/compiler/lib/test/7-lambdalifting/deact.input index a8e5a9643..2be6da32a 100644 --- a/compiler/lib/test/7-lambdalifting/deact.input +++ b/compiler/lib/test/7-lambdalifting/deact.input @@ -21,7 +21,7 @@ class Apa ($Actor, __builtin__.value): print@[(__builtin__.str,)](("\"compute\"",), None, None, None, None) proc def C_3cont (C_4res : __builtin__.int) -> $R: v: __builtin__.int = C_4res - m: __builtin__.Msg[__builtin__.int] = (async cb)(W_Apa_39.__fromatom__(2)) + m: __builtin__.Future[__builtin__.int] = (async cb)(W_Apa_39.__fromatom__(2)) N_tmp: __builtin__.int = W_Apa_105.__mul__(v, W_Apa_39.__fromatom__(10)) return $R_CONTc@[__builtin__.int](C_cont, N_tmp) return $AWAITc@[__builtin__.int](C_3cont, (async cb)(W_Apa_39.__fromatom__(1))) @@ -53,7 +53,7 @@ class main ($Actor, __builtin__.value): @property b : Bepa @property - x : __builtin__.Msg[__builtin__.int] + x : __builtin__.Future[__builtin__.int] @property r : __builtin__.int proc def __init__ (self : Self, C_cont : proc(None) -> $R, env : __builtin__.Env) -> $R: diff --git a/compiler/lib/test/7-lambdalifting/deact.output b/compiler/lib/test/7-lambdalifting/deact.output index 5c2d24fbc..d5f8bb027 100644 --- a/compiler/lib/test/7-lambdalifting/deact.output +++ b/compiler/lib/test/7-lambdalifting/deact.output @@ -36,7 +36,7 @@ class L_4action ($action[(__builtin__.int,), __builtin__.int], $proc[(__builtin_ # (recursive group) proc def L_5C_3cont (cb : $action[(__builtin__.int,), __builtin__.int], C_cont : $Cont[__builtin__.int], C_4res : __builtin__.int) -> $R: v: __builtin__.int = C_4res - m: __builtin__.Msg[__builtin__.int] = cb.__asyn__(W_Apa_39.__fromatom__(2)) + m: __builtin__.Future[__builtin__.int] = cb.__asyn__(W_Apa_39.__fromatom__(2)) N_tmp: __builtin__.int = W_Apa_105.__mul__(v, W_Apa_39.__fromatom__(10)) return $R_CONT@[__builtin__.int](C_cont, N_tmp) class L_6Cont ($Cont[__builtin__.int], __builtin__.value): @@ -362,7 +362,7 @@ class main ($Actor, __builtin__.value): @property b : Bepa @property - x : __builtin__.Msg[__builtin__.int] + x : __builtin__.Future[__builtin__.int] @property r : __builtin__.int proc def __init__ (self : Self, C_cont : $Cont[None], env : __builtin__.Env) -> $R: diff --git a/compiler/lib/test/8-boxing/deact.input b/compiler/lib/test/8-boxing/deact.input index 5c2d24fbc..d5f8bb027 100644 --- a/compiler/lib/test/8-boxing/deact.input +++ b/compiler/lib/test/8-boxing/deact.input @@ -36,7 +36,7 @@ class L_4action ($action[(__builtin__.int,), __builtin__.int], $proc[(__builtin_ # (recursive group) proc def L_5C_3cont (cb : $action[(__builtin__.int,), __builtin__.int], C_cont : $Cont[__builtin__.int], C_4res : __builtin__.int) -> $R: v: __builtin__.int = C_4res - m: __builtin__.Msg[__builtin__.int] = cb.__asyn__(W_Apa_39.__fromatom__(2)) + m: __builtin__.Future[__builtin__.int] = cb.__asyn__(W_Apa_39.__fromatom__(2)) N_tmp: __builtin__.int = W_Apa_105.__mul__(v, W_Apa_39.__fromatom__(10)) return $R_CONT@[__builtin__.int](C_cont, N_tmp) class L_6Cont ($Cont[__builtin__.int], __builtin__.value): @@ -362,7 +362,7 @@ class main ($Actor, __builtin__.value): @property b : Bepa @property - x : __builtin__.Msg[__builtin__.int] + x : __builtin__.Future[__builtin__.int] @property r : __builtin__.int proc def __init__ (self : Self, C_cont : $Cont[None], env : __builtin__.Env) -> $R: diff --git a/compiler/lib/test/8-boxing/deact.output b/compiler/lib/test/8-boxing/deact.output index db1230c9b..c56715e22 100644 --- a/compiler/lib/test/8-boxing/deact.output +++ b/compiler/lib/test/8-boxing/deact.output @@ -28,7 +28,7 @@ class L_4action ($action[(__builtin__.int,), __builtin__.int], $proc[(__builtin_ # (recursive group) proc def L_5C_3cont (cb : $action[(__builtin__.int,), __builtin__.int], C_cont : $Cont[__builtin__.int], C_4res : UNBOXED __builtin__.int) -> $R: v: UNBOXED __builtin__.int = (UNBOX __builtin__.int C_4res) - m: __builtin__.Msg[__builtin__.int] = cb.__asyn__((BOX __builtin__.int (UNBOX __builtin__.int 2))) + m: __builtin__.Future[__builtin__.int] = cb.__asyn__((BOX __builtin__.int (UNBOX __builtin__.int 2))) N_tmp: UNBOXED __builtin__.int = ((UNBOX __builtin__.int v) * (UNBOX __builtin__.int 10)) return $R_CONT@[__builtin__.int](C_cont, (BOX __builtin__.int N_tmp)) class L_6Cont ($Cont[__builtin__.int], __builtin__.value): @@ -354,7 +354,7 @@ class main ($Actor, __builtin__.value): @property b : Bepa @property - x : __builtin__.Msg[__builtin__.int] + x : __builtin__.Future[__builtin__.int] @property r : __builtin__.int proc def __init__ (self : main, C_cont : $Cont[None], env : __builtin__.Env) -> $R: diff --git a/compiler/lib/test/9-codegen/deact.c b/compiler/lib/test/9-codegen/deact.c index c3a99a98b..be98b44fb 100644 --- a/compiler/lib/test/9-codegen/deact.c +++ b/compiler/lib/test/9-codegen/deact.c @@ -42,14 +42,14 @@ B_NoneType deactQ_L_4actionD___init__ (deactQ_L_4action L_self, deactQ_Apa L_3ob return B_None; } $R deactQ_L_4actionD___call__ (deactQ_L_4action L_self, $Cont L_cont, B_int G_1) { - return $AWAIT(L_cont, ((B_Msg)((B_Msg (*) ($WORD, B_int))((deactQ_L_4action)(L_self))->$class->__asyn__)(L_self, toB_int(((B_int)G_1)->val)))); + return $AWAIT(L_cont, ((B_Future)((B_Future (*) ($WORD, B_int))((deactQ_L_4action)(L_self))->$class->__asyn__)(L_self, toB_int(((B_int)G_1)->val)))); } $R deactQ_L_4actionD___exec__ (deactQ_L_4action L_self, $Cont L_cont, B_int G_1) { - return $R_CONT(L_cont, ((B_value)((B_Msg (*) ($WORD, B_int))((deactQ_L_4action)(L_self))->$class->__asyn__)(L_self, toB_int(((B_int)G_1)->val)))); + return $R_CONT(L_cont, ((B_value)((B_Future (*) ($WORD, B_int))((deactQ_L_4action)(L_self))->$class->__asyn__)(L_self, toB_int(((B_int)G_1)->val)))); } -B_Msg deactQ_L_4actionD___asyn__ (deactQ_L_4action L_self, B_int G_1) { +B_Future deactQ_L_4actionD___asyn__ (deactQ_L_4action L_self, B_int G_1) { deactQ_Apa L_3obj = ((deactQ_L_4action)(L_self))->L_3obj; - return ((B_Msg)((B_Msg (*) ($WORD, int64_t))((deactQ_Apa)(L_3obj))->$class->notice)(L_3obj, ((B_int)G_1)->val)); + return ((B_Future)((B_Future (*) ($WORD, int64_t))((deactQ_Apa)(L_3obj))->$class->notice)(L_3obj, ((B_int)G_1)->val)); } void deactQ_L_4actionD___serialize__ (deactQ_L_4action self, $Serial$state state) { $step_serialize(self->L_3obj, state); @@ -78,7 +78,7 @@ struct deactQ_L_4actionG_class deactQ_L_4actionG_methods; #line 7 "test/src/deact.act" int64_t v = C_4res; #line 8 "test/src/deact.act" - B_Msg m = ((B_Msg)((B_Msg (*) ($WORD, B_int))(($action)(cb))->$class->__asyn__)(cb, toB_int(2LL))); + B_Future m = ((B_Future)((B_Future (*) ($WORD, B_int))(($action)(cb))->$class->__asyn__)(cb, toB_int(2LL))); int64_t N_tmp = (((int64_t)(v * 10LL))); return $R_CONT(C_cont, toB_int(N_tmp)); } @@ -276,14 +276,14 @@ B_NoneType deactQ_L_14actionD___init__ (deactQ_L_14action L_self, deactQ_Apa L_1 return B_None; } $R deactQ_L_14actionD___call__ (deactQ_L_14action L_self, $Cont L_cont, B_int G_1) { - return $AWAIT(L_cont, ((B_Msg)((B_Msg (*) ($WORD, B_int))((deactQ_L_14action)(L_self))->$class->__asyn__)(L_self, toB_int(((B_int)G_1)->val)))); + return $AWAIT(L_cont, ((B_Future)((B_Future (*) ($WORD, B_int))((deactQ_L_14action)(L_self))->$class->__asyn__)(L_self, toB_int(((B_int)G_1)->val)))); } $R deactQ_L_14actionD___exec__ (deactQ_L_14action L_self, $Cont L_cont, B_int G_1) { - return $R_CONT(L_cont, ((B_value)((B_Msg (*) ($WORD, B_int))((deactQ_L_14action)(L_self))->$class->__asyn__)(L_self, toB_int(((B_int)G_1)->val)))); + return $R_CONT(L_cont, ((B_value)((B_Future (*) ($WORD, B_int))((deactQ_L_14action)(L_self))->$class->__asyn__)(L_self, toB_int(((B_int)G_1)->val)))); } -B_Msg deactQ_L_14actionD___asyn__ (deactQ_L_14action L_self, B_int G_1) { +B_Future deactQ_L_14actionD___asyn__ (deactQ_L_14action L_self, B_int G_1) { deactQ_Apa L_13obj = ((deactQ_L_14action)(L_self))->L_13obj; - return ((B_Msg)((B_Msg (*) ($WORD, int64_t))((deactQ_Apa)(L_13obj))->$class->notice)(L_13obj, ((B_int)G_1)->val)); + return ((B_Future)((B_Future (*) ($WORD, int64_t))((deactQ_Apa)(L_13obj))->$class->notice)(L_13obj, ((B_int)G_1)->val)); } void deactQ_L_14actionD___serialize__ (deactQ_L_14action self, $Serial$state state) { $step_serialize(self->L_13obj, state); @@ -313,14 +313,14 @@ B_NoneType deactQ_L_16actionD___init__ (deactQ_L_16action L_self, deactQ_Bepa L_ return B_None; } $R deactQ_L_16actionD___call__ (deactQ_L_16action L_self, $Cont L_cont, B_int G_1) { - return $AWAIT(L_cont, ((B_Msg)((B_Msg (*) ($WORD, B_int))((deactQ_L_16action)(L_self))->$class->__asyn__)(L_self, toB_int(((B_int)G_1)->val)))); + return $AWAIT(L_cont, ((B_Future)((B_Future (*) ($WORD, B_int))((deactQ_L_16action)(L_self))->$class->__asyn__)(L_self, toB_int(((B_int)G_1)->val)))); } $R deactQ_L_16actionD___exec__ (deactQ_L_16action L_self, $Cont L_cont, B_int G_1) { - return $R_CONT(L_cont, ((B_value)((B_Msg (*) ($WORD, B_int))((deactQ_L_16action)(L_self))->$class->__asyn__)(L_self, toB_int(((B_int)G_1)->val)))); + return $R_CONT(L_cont, ((B_value)((B_Future (*) ($WORD, B_int))((deactQ_L_16action)(L_self))->$class->__asyn__)(L_self, toB_int(((B_int)G_1)->val)))); } -B_Msg deactQ_L_16actionD___asyn__ (deactQ_L_16action L_self, B_int G_1) { +B_Future deactQ_L_16actionD___asyn__ (deactQ_L_16action L_self, B_int G_1) { deactQ_Bepa L_15obj = ((deactQ_L_16action)(L_self))->L_15obj; - return ((B_Msg)((B_Msg (*) ($WORD, int64_t))((deactQ_Bepa)(L_15obj))->$class->callback)(L_15obj, ((B_int)G_1)->val)); + return ((B_Future)((B_Future (*) ($WORD, int64_t))((deactQ_Bepa)(L_15obj))->$class->callback)(L_15obj, ((B_int)G_1)->val)); } void deactQ_L_16actionD___serialize__ (deactQ_L_16action self, $Serial$state state) { $step_serialize(self->L_15obj, state); @@ -350,14 +350,14 @@ B_NoneType deactQ_L_19actionD___init__ (deactQ_L_19action L_self, deactQ_main L_ return B_None; } $R deactQ_L_19actionD___call__ (deactQ_L_19action L_self, $Cont L_cont, B_int G_1) { - return $AWAIT(L_cont, ((B_Msg)((B_Msg (*) ($WORD, B_int))((deactQ_L_19action)(L_self))->$class->__asyn__)(L_self, toB_int(((B_int)G_1)->val)))); + return $AWAIT(L_cont, ((B_Future)((B_Future (*) ($WORD, B_int))((deactQ_L_19action)(L_self))->$class->__asyn__)(L_self, toB_int(((B_int)G_1)->val)))); } $R deactQ_L_19actionD___exec__ (deactQ_L_19action L_self, $Cont L_cont, B_int G_1) { - return $R_CONT(L_cont, ((B_value)((B_Msg (*) ($WORD, B_int))((deactQ_L_19action)(L_self))->$class->__asyn__)(L_self, toB_int(((B_int)G_1)->val)))); + return $R_CONT(L_cont, ((B_value)((B_Future (*) ($WORD, B_int))((deactQ_L_19action)(L_self))->$class->__asyn__)(L_self, toB_int(((B_int)G_1)->val)))); } -B_Msg deactQ_L_19actionD___asyn__ (deactQ_L_19action L_self, B_int G_1) { +B_Future deactQ_L_19actionD___asyn__ (deactQ_L_19action L_self, B_int G_1) { deactQ_main L_18obj = ((deactQ_L_19action)(L_self))->L_18obj; - return ((B_Msg)((B_Msg (*) ($WORD, int64_t))((deactQ_main)(L_18obj))->$class->myproc)(L_18obj, ((B_int)G_1)->val)); + return ((B_Future)((B_Future (*) ($WORD, int64_t))((deactQ_main)(L_18obj))->$class->myproc)(L_18obj, ((B_int)G_1)->val)); } void deactQ_L_19actionD___serialize__ (deactQ_L_19action self, $Serial$state state) { $step_serialize(self->L_18obj, state); @@ -388,7 +388,7 @@ struct deactQ_L_19actionG_class deactQ_L_19actionG_methods; #line 35 "test/src/deact.act" ((B_NoneType (*) (B_tuple, B_str, B_str, B_bool, B_bool))B_print)($NEWTUPLE(2, to$str("r ="), toB_int(((int64_t)((deactQ_main)(self))->r))), B_None, B_None, B_None, B_None); #line 36 "test/src/deact.act" - ((B_Msg (*) ($WORD, $action))((deactQ_Apa)(((deactQ_main)(self))->a))->$class->compute)(((deactQ_main)(self))->a, (($action)deactQ_L_19actionG_new(self))); + ((B_Future (*) ($WORD, $action))((deactQ_Apa)(((deactQ_main)(self))->a))->$class->compute)(((deactQ_main)(self))->a, (($action)deactQ_L_19actionG_new(self))); #line 37 "test/src/deact.act" ((B_NoneType (*) (B_tuple, B_str, B_str, B_bool, B_bool))B_print)($NEWTUPLE(1, to$str("main")), B_None, B_None, B_None, B_None); return $R_CONT(C_cont, B_None); @@ -434,9 +434,9 @@ struct deactQ_L_20ContG_class deactQ_L_20ContG_methods; #line 31 "test/src/deact.act" ((B_NoneType (*) (B_tuple, B_str, B_str, B_bool, B_bool))B_print)($NEWTUPLE(1, to$str("-----")), B_None, B_None, B_None, B_None); #line 32 "test/src/deact.act" - ((B_Msg (*) ($WORD, $action))((deactQ_Apa)(((deactQ_main)(self))->a))->$class->setup)(((deactQ_main)(self))->a, (($action)deactQ_L_14actionG_new(((deactQ_main)(self))->a))); + ((B_Future (*) ($WORD, $action))((deactQ_Apa)(((deactQ_main)(self))->a))->$class->setup)(((deactQ_main)(self))->a, (($action)deactQ_L_14actionG_new(((deactQ_main)(self))->a))); #line 33 "test/src/deact.act" - ((deactQ_main)(self))->x = ((B_Msg (*) ($WORD, $action))((deactQ_Apa)(((deactQ_main)(self))->a))->$class->compute)(((deactQ_main)(self))->a, (($action)deactQ_L_16actionG_new(((deactQ_main)(self))->b))); + ((deactQ_main)(self))->x = ((B_Future (*) ($WORD, $action))((deactQ_Apa)(((deactQ_main)(self))->a))->$class->compute)(((deactQ_main)(self))->a, (($action)deactQ_L_16actionG_new(((deactQ_main)(self))->b))); return $AWAIT((($Cont)deactQ_L_20ContG_new(self, C_cont)), ((deactQ_main)(self))->x); } B_NoneType deactQ_L_21ContD___init__ (deactQ_L_21Cont L_self, deactQ_main self, $Cont C_cont) { @@ -781,14 +781,14 @@ struct deactQ_L_32procG_class deactQ_L_32procG_methods; #line 3 "test/src/deact.act" ((B_NoneType (*) (B_tuple, B_str, B_str, B_bool, B_bool))B_print)($NEWTUPLE(1, to$str("setup")), B_None, B_None, B_None, B_None); #line 4 "test/src/deact.act" - ((B_Msg (*) ($WORD, B_int))(($action)(cb))->$class->__asyn__)(cb, toB_int(0LL)); + ((B_Future (*) ($WORD, B_int))(($action)(cb))->$class->__asyn__)(cb, toB_int(0LL)); return $R_CONT(C_cont, B_None); } #line 5 "test/src/deact.act" $R deactQ_ApaD_computeG_local (deactQ_Apa self, $Cont C_cont, $action cb) { #line 6 "test/src/deact.act" ((B_NoneType (*) (B_tuple, B_str, B_str, B_bool, B_bool))B_print)($NEWTUPLE(1, to$str("compute")), B_None, B_None, B_None, B_None); - return $AWAIT((($Cont)deactQ_L_6ContG_new(cb, C_cont)), ((B_Msg)((B_Msg (*) ($WORD, B_int))(($action)(cb))->$class->__asyn__)(cb, toB_int(1LL)))); + return $AWAIT((($Cont)deactQ_L_6ContG_new(cb, C_cont)), ((B_Future)((B_Future (*) ($WORD, B_int))(($action)(cb))->$class->__asyn__)(cb, toB_int(1LL)))); } #line 10 "test/src/deact.act" $R deactQ_ApaD_noticeG_local (deactQ_Apa self, $Cont C_cont, int64_t i) { @@ -797,14 +797,14 @@ struct deactQ_L_32procG_class deactQ_L_32procG_methods; int64_t N_1tmp = (((int64_t)(i + 1LL))); return $R_CONT(C_cont, toB_int(N_1tmp)); } -B_Msg deactQ_ApaD_setup (deactQ_Apa self, $action cb) { +B_Future deactQ_ApaD_setup (deactQ_Apa self, $action cb) { return $ASYNC((($Actor)self), (($Cont)deactQ_L_7procG_new(self, cb))); } -B_Msg deactQ_ApaD_compute (deactQ_Apa self, $action cb) { - return ((B_Msg)$ASYNC((($Actor)self), (($Cont)deactQ_L_8procG_new(self, cb)))); +B_Future deactQ_ApaD_compute (deactQ_Apa self, $action cb) { + return ((B_Future)$ASYNC((($Actor)self), (($Cont)deactQ_L_8procG_new(self, cb)))); } -B_Msg deactQ_ApaD_notice (deactQ_Apa self, int64_t i) { - return ((B_Msg)$ASYNC((($Actor)self), (($Cont)deactQ_L_9procG_new(self, i)))); +B_Future deactQ_ApaD_notice (deactQ_Apa self, int64_t i) { + return ((B_Future)$ASYNC((($Actor)self), (($Cont)deactQ_L_9procG_new(self, i)))); } void deactQ_ApaD___serialize__ (deactQ_Apa self, $Serial$state state) { $ActorG_methods.__serialize__(($Actor)self, state); @@ -844,8 +844,8 @@ struct deactQ_ApaG_class deactQ_ApaG_methods; int64_t N_2tmp = (((int64_t)(i + 1LL))); return $R_CONT(C_cont, toB_int(N_2tmp)); } -B_Msg deactQ_BepaD_callback (deactQ_Bepa self, int64_t i) { - return ((B_Msg)$ASYNC((($Actor)self), (($Cont)deactQ_L_10procG_new(self, i)))); +B_Future deactQ_BepaD_callback (deactQ_Bepa self, int64_t i) { + return ((B_Future)$ASYNC((($Actor)self), (($Cont)deactQ_L_10procG_new(self, i)))); } void deactQ_BepaD___serialize__ (deactQ_Bepa self, $Serial$state state) { $ActorG_methods.__serialize__(($Actor)self, state); @@ -884,12 +884,12 @@ struct deactQ_BepaG_class deactQ_BepaG_methods; #line 26 "test/src/deact.act" if (i == 2LL) { #line 27 "test/src/deact.act" - ((B_Msg (*) ($WORD, int64_t))((B_Env)(((deactQ_main)(self))->env))->$class->exit)(((deactQ_main)(self))->env, 0LL); + ((B_Future (*) ($WORD, int64_t))((B_Env)(((deactQ_main)(self))->env))->$class->exit)(((deactQ_main)(self))->env, 0LL); } return $R_CONT(C_cont, toB_int(i)); } -B_Msg deactQ_mainD_myproc (deactQ_main self, int64_t i) { - return ((B_Msg)$ASYNC((($Actor)self), (($Cont)deactQ_L_23procG_new(self, i)))); +B_Future deactQ_mainD_myproc (deactQ_main self, int64_t i) { + return ((B_Future)$ASYNC((($Actor)self), (($Cont)deactQ_L_23procG_new(self, i)))); } void deactQ_mainD___serialize__ (deactQ_main self, $Serial$state state) { $ActorG_methods.__serialize__(($Actor)self, state); @@ -968,7 +968,7 @@ void deactQ___init__ () { deactQ_L_4actionG_methods.__init__ = (B_NoneType (*) (deactQ_L_4action, deactQ_Apa))deactQ_L_4actionD___init__; deactQ_L_4actionG_methods.__call__ = ($R (*) (deactQ_L_4action, $Cont, B_int))deactQ_L_4actionD___call__; deactQ_L_4actionG_methods.__exec__ = ($R (*) (deactQ_L_4action, $Cont, B_int))deactQ_L_4actionD___exec__; - deactQ_L_4actionG_methods.__asyn__ = (B_Msg (*) (deactQ_L_4action, B_int))deactQ_L_4actionD___asyn__; + deactQ_L_4actionG_methods.__asyn__ = (B_Future (*) (deactQ_L_4action, B_int))deactQ_L_4actionD___asyn__; deactQ_L_4actionG_methods.__serialize__ = deactQ_L_4actionD___serialize__; deactQ_L_4actionG_methods.__deserialize__ = deactQ_L_4actionD___deserialize__; $register(&deactQ_L_4actionG_methods); @@ -1046,7 +1046,7 @@ void deactQ___init__ () { deactQ_L_14actionG_methods.__init__ = (B_NoneType (*) (deactQ_L_14action, deactQ_Apa))deactQ_L_14actionD___init__; deactQ_L_14actionG_methods.__call__ = ($R (*) (deactQ_L_14action, $Cont, B_int))deactQ_L_14actionD___call__; deactQ_L_14actionG_methods.__exec__ = ($R (*) (deactQ_L_14action, $Cont, B_int))deactQ_L_14actionD___exec__; - deactQ_L_14actionG_methods.__asyn__ = (B_Msg (*) (deactQ_L_14action, B_int))deactQ_L_14actionD___asyn__; + deactQ_L_14actionG_methods.__asyn__ = (B_Future (*) (deactQ_L_14action, B_int))deactQ_L_14actionD___asyn__; deactQ_L_14actionG_methods.__serialize__ = deactQ_L_14actionD___serialize__; deactQ_L_14actionG_methods.__deserialize__ = deactQ_L_14actionD___deserialize__; $register(&deactQ_L_14actionG_methods); @@ -1060,7 +1060,7 @@ void deactQ___init__ () { deactQ_L_16actionG_methods.__init__ = (B_NoneType (*) (deactQ_L_16action, deactQ_Bepa))deactQ_L_16actionD___init__; deactQ_L_16actionG_methods.__call__ = ($R (*) (deactQ_L_16action, $Cont, B_int))deactQ_L_16actionD___call__; deactQ_L_16actionG_methods.__exec__ = ($R (*) (deactQ_L_16action, $Cont, B_int))deactQ_L_16actionD___exec__; - deactQ_L_16actionG_methods.__asyn__ = (B_Msg (*) (deactQ_L_16action, B_int))deactQ_L_16actionD___asyn__; + deactQ_L_16actionG_methods.__asyn__ = (B_Future (*) (deactQ_L_16action, B_int))deactQ_L_16actionD___asyn__; deactQ_L_16actionG_methods.__serialize__ = deactQ_L_16actionD___serialize__; deactQ_L_16actionG_methods.__deserialize__ = deactQ_L_16actionD___deserialize__; $register(&deactQ_L_16actionG_methods); @@ -1074,7 +1074,7 @@ void deactQ___init__ () { deactQ_L_19actionG_methods.__init__ = (B_NoneType (*) (deactQ_L_19action, deactQ_main))deactQ_L_19actionD___init__; deactQ_L_19actionG_methods.__call__ = ($R (*) (deactQ_L_19action, $Cont, B_int))deactQ_L_19actionD___call__; deactQ_L_19actionG_methods.__exec__ = ($R (*) (deactQ_L_19action, $Cont, B_int))deactQ_L_19actionD___exec__; - deactQ_L_19actionG_methods.__asyn__ = (B_Msg (*) (deactQ_L_19action, B_int))deactQ_L_19actionD___asyn__; + deactQ_L_19actionG_methods.__asyn__ = (B_Future (*) (deactQ_L_19action, B_int))deactQ_L_19actionD___asyn__; deactQ_L_19actionG_methods.__serialize__ = deactQ_L_19actionD___serialize__; deactQ_L_19actionG_methods.__deserialize__ = deactQ_L_19actionD___deserialize__; $register(&deactQ_L_19actionG_methods); @@ -1215,9 +1215,9 @@ void deactQ___init__ () { deactQ_ApaG_methods.setupG_local = ($R (*) (deactQ_Apa, $Cont, $action))deactQ_ApaD_setupG_local; deactQ_ApaG_methods.computeG_local = ($R (*) (deactQ_Apa, $Cont, $action))deactQ_ApaD_computeG_local; deactQ_ApaG_methods.noticeG_local = ($R (*) (deactQ_Apa, $Cont, int64_t))deactQ_ApaD_noticeG_local; - deactQ_ApaG_methods.setup = (B_Msg (*) (deactQ_Apa, $action))deactQ_ApaD_setup; - deactQ_ApaG_methods.compute = (B_Msg (*) (deactQ_Apa, $action))deactQ_ApaD_compute; - deactQ_ApaG_methods.notice = (B_Msg (*) (deactQ_Apa, int64_t))deactQ_ApaD_notice; + deactQ_ApaG_methods.setup = (B_Future (*) (deactQ_Apa, $action))deactQ_ApaD_setup; + deactQ_ApaG_methods.compute = (B_Future (*) (deactQ_Apa, $action))deactQ_ApaD_compute; + deactQ_ApaG_methods.notice = (B_Future (*) (deactQ_Apa, int64_t))deactQ_ApaD_notice; deactQ_ApaG_methods.__serialize__ = deactQ_ApaD___serialize__; deactQ_ApaG_methods.__deserialize__ = deactQ_ApaD___deserialize__; $register(&deactQ_ApaG_methods); @@ -1232,7 +1232,7 @@ void deactQ___init__ () { deactQ_BepaG_methods.__cleanup__ = (B_NoneType (*) (deactQ_Bepa))$ActorG_methods.__cleanup__; deactQ_BepaG_methods.__init__ = ($R (*) (deactQ_Bepa, $Cont))deactQ_BepaD___init__; deactQ_BepaG_methods.callbackG_local = ($R (*) (deactQ_Bepa, $Cont, int64_t))deactQ_BepaD_callbackG_local; - deactQ_BepaG_methods.callback = (B_Msg (*) (deactQ_Bepa, int64_t))deactQ_BepaD_callback; + deactQ_BepaG_methods.callback = (B_Future (*) (deactQ_Bepa, int64_t))deactQ_BepaD_callback; deactQ_BepaG_methods.__serialize__ = deactQ_BepaD___serialize__; deactQ_BepaG_methods.__deserialize__ = deactQ_BepaD___deserialize__; $register(&deactQ_BepaG_methods); @@ -1247,7 +1247,7 @@ void deactQ___init__ () { deactQ_mainG_methods.__cleanup__ = (B_NoneType (*) (deactQ_main))$ActorG_methods.__cleanup__; deactQ_mainG_methods.__init__ = ($R (*) (deactQ_main, $Cont, B_Env))deactQ_mainD___init__; deactQ_mainG_methods.myprocG_local = ($R (*) (deactQ_main, $Cont, int64_t))deactQ_mainD_myprocG_local; - deactQ_mainG_methods.myproc = (B_Msg (*) (deactQ_main, int64_t))deactQ_mainD_myproc; + deactQ_mainG_methods.myproc = (B_Future (*) (deactQ_main, int64_t))deactQ_mainD_myproc; deactQ_mainG_methods.__serialize__ = deactQ_mainD___serialize__; deactQ_mainG_methods.__deserialize__ = deactQ_mainD___deserialize__; $register(&deactQ_mainG_methods); diff --git a/compiler/lib/test/9-codegen/deact.h b/compiler/lib/test/9-codegen/deact.h index 43358a41e..515b24c69 100644 --- a/compiler/lib/test/9-codegen/deact.h +++ b/compiler/lib/test/9-codegen/deact.h @@ -77,7 +77,7 @@ struct deactQ_L_4actionG_class { B_str (*__repr__) (deactQ_L_4action); $R (*__call__) (deactQ_L_4action, $Cont, B_int); $R (*__exec__) (deactQ_L_4action, $Cont, B_int); - B_Msg (*__asyn__) (deactQ_L_4action, B_int); + B_Future (*__asyn__) (deactQ_L_4action, B_int); }; struct deactQ_L_4action { struct deactQ_L_4actionG_class *$class; @@ -185,7 +185,7 @@ struct deactQ_L_14actionG_class { B_str (*__repr__) (deactQ_L_14action); $R (*__call__) (deactQ_L_14action, $Cont, B_int); $R (*__exec__) (deactQ_L_14action, $Cont, B_int); - B_Msg (*__asyn__) (deactQ_L_14action, B_int); + B_Future (*__asyn__) (deactQ_L_14action, B_int); }; struct deactQ_L_14action { struct deactQ_L_14actionG_class *$class; @@ -203,7 +203,7 @@ struct deactQ_L_16actionG_class { B_str (*__repr__) (deactQ_L_16action); $R (*__call__) (deactQ_L_16action, $Cont, B_int); $R (*__exec__) (deactQ_L_16action, $Cont, B_int); - B_Msg (*__asyn__) (deactQ_L_16action, B_int); + B_Future (*__asyn__) (deactQ_L_16action, B_int); }; struct deactQ_L_16action { struct deactQ_L_16actionG_class *$class; @@ -221,7 +221,7 @@ struct deactQ_L_19actionG_class { B_str (*__repr__) (deactQ_L_19action); $R (*__call__) (deactQ_L_19action, $Cont, B_int); $R (*__exec__) (deactQ_L_19action, $Cont, B_int); - B_Msg (*__asyn__) (deactQ_L_19action, B_int); + B_Future (*__asyn__) (deactQ_L_19action, B_int); }; struct deactQ_L_19action { struct deactQ_L_19actionG_class *$class; @@ -420,9 +420,9 @@ struct deactQ_ApaG_class { $R (*setupG_local) (deactQ_Apa, $Cont, $action); $R (*computeG_local) (deactQ_Apa, $Cont, $action); $R (*noticeG_local) (deactQ_Apa, $Cont, int64_t); - B_Msg (*setup) (deactQ_Apa, $action); - B_Msg (*compute) (deactQ_Apa, $action); - B_Msg (*notice) (deactQ_Apa, int64_t); + B_Future (*setup) (deactQ_Apa, $action); + B_Future (*compute) (deactQ_Apa, $action); + B_Future (*notice) (deactQ_Apa, int64_t); }; struct deactQ_Apa { struct deactQ_ApaG_class *$class; @@ -432,7 +432,7 @@ struct deactQ_Apa { $Lock $msg_lock; $int64 $affinity; B_Msg $outgoing; - B_Msg $waitsfor; + B_Future $waitsfor; $int64 $consume_hd; $Catcher $catcher; $long $globkey; @@ -450,7 +450,7 @@ struct deactQ_BepaG_class { B_NoneType (*__resume__) (deactQ_Bepa); B_NoneType (*__cleanup__) (deactQ_Bepa); $R (*callbackG_local) (deactQ_Bepa, $Cont, int64_t); - B_Msg (*callback) (deactQ_Bepa, int64_t); + B_Future (*callback) (deactQ_Bepa, int64_t); }; struct deactQ_Bepa { struct deactQ_BepaG_class *$class; @@ -460,7 +460,7 @@ struct deactQ_Bepa { $Lock $msg_lock; $int64 $affinity; B_Msg $outgoing; - B_Msg $waitsfor; + B_Future $waitsfor; $int64 $consume_hd; $Catcher $catcher; $long $globkey; @@ -478,7 +478,7 @@ struct deactQ_mainG_class { B_NoneType (*__resume__) (deactQ_main); B_NoneType (*__cleanup__) (deactQ_main); $R (*myprocG_local) (deactQ_main, $Cont, int64_t); - B_Msg (*myproc) (deactQ_main, int64_t); + B_Future (*myproc) (deactQ_main, int64_t); }; struct deactQ_main { struct deactQ_mainG_class *$class; @@ -488,14 +488,14 @@ struct deactQ_main { $Lock $msg_lock; $int64 $affinity; B_Msg $outgoing; - B_Msg $waitsfor; + B_Future $waitsfor; $int64 $consume_hd; $Catcher $catcher; $long $globkey; B_Env env; deactQ_Apa a; deactQ_Bepa b; - B_Msg x; + B_Future x; int64_t r; }; $R deactQ_ApaG_newact ($Cont); @@ -510,7 +510,7 @@ deactQ_L_4action deactQ_L_4actionG_new(deactQ_Apa); B_NoneType deactQ_L_4actionD___init__(deactQ_L_4action L_self, deactQ_Apa L_3obj); $R deactQ_L_4actionD___call__(deactQ_L_4action L_self, $Cont L_cont, B_int G_1); $R deactQ_L_4actionD___exec__(deactQ_L_4action L_self, $Cont L_cont, B_int G_1); -B_Msg deactQ_L_4actionD___asyn__(deactQ_L_4action L_self, B_int G_1); +B_Future deactQ_L_4actionD___asyn__(deactQ_L_4action L_self, B_int G_1); extern struct deactQ_L_6ContG_class deactQ_L_6ContG_methods; deactQ_L_6Cont deactQ_L_6ContG_new($action, $Cont); B_NoneType deactQ_L_6ContD___init__(deactQ_L_6Cont L_self, $action cb, $Cont C_cont); @@ -540,19 +540,19 @@ deactQ_L_14action deactQ_L_14actionG_new(deactQ_Apa); B_NoneType deactQ_L_14actionD___init__(deactQ_L_14action L_self, deactQ_Apa L_13obj); $R deactQ_L_14actionD___call__(deactQ_L_14action L_self, $Cont L_cont, B_int G_1); $R deactQ_L_14actionD___exec__(deactQ_L_14action L_self, $Cont L_cont, B_int G_1); -B_Msg deactQ_L_14actionD___asyn__(deactQ_L_14action L_self, B_int G_1); +B_Future deactQ_L_14actionD___asyn__(deactQ_L_14action L_self, B_int G_1); extern struct deactQ_L_16actionG_class deactQ_L_16actionG_methods; deactQ_L_16action deactQ_L_16actionG_new(deactQ_Bepa); B_NoneType deactQ_L_16actionD___init__(deactQ_L_16action L_self, deactQ_Bepa L_15obj); $R deactQ_L_16actionD___call__(deactQ_L_16action L_self, $Cont L_cont, B_int G_1); $R deactQ_L_16actionD___exec__(deactQ_L_16action L_self, $Cont L_cont, B_int G_1); -B_Msg deactQ_L_16actionD___asyn__(deactQ_L_16action L_self, B_int G_1); +B_Future deactQ_L_16actionD___asyn__(deactQ_L_16action L_self, B_int G_1); extern struct deactQ_L_19actionG_class deactQ_L_19actionG_methods; deactQ_L_19action deactQ_L_19actionG_new(deactQ_main); B_NoneType deactQ_L_19actionD___init__(deactQ_L_19action L_self, deactQ_main L_18obj); $R deactQ_L_19actionD___call__(deactQ_L_19action L_self, $Cont L_cont, B_int G_1); $R deactQ_L_19actionD___exec__(deactQ_L_19action L_self, $Cont L_cont, B_int G_1); -B_Msg deactQ_L_19actionD___asyn__(deactQ_L_19action L_self, B_int G_1); +B_Future deactQ_L_19actionD___asyn__(deactQ_L_19action L_self, B_int G_1); extern struct deactQ_L_20ContG_class deactQ_L_20ContG_methods; deactQ_L_20Cont deactQ_L_20ContG_new(deactQ_main, $Cont); B_NoneType deactQ_L_20ContD___init__(deactQ_L_20Cont L_self, deactQ_main self, $Cont C_cont); @@ -603,17 +603,17 @@ extern struct deactQ_ApaG_class deactQ_ApaG_methods; $R deactQ_ApaD_setupG_local(deactQ_Apa self, $Cont C_cont, $action cb); $R deactQ_ApaD_computeG_local(deactQ_Apa self, $Cont C_cont, $action cb); $R deactQ_ApaD_noticeG_local(deactQ_Apa self, $Cont C_cont, int64_t i); -B_Msg deactQ_ApaD_setup(deactQ_Apa self, $action cb); -B_Msg deactQ_ApaD_compute(deactQ_Apa self, $action cb); -B_Msg deactQ_ApaD_notice(deactQ_Apa self, int64_t i); +B_Future deactQ_ApaD_setup(deactQ_Apa self, $action cb); +B_Future deactQ_ApaD_compute(deactQ_Apa self, $action cb); +B_Future deactQ_ApaD_notice(deactQ_Apa self, int64_t i); extern struct deactQ_BepaG_class deactQ_BepaG_methods; $R deactQ_BepaG_new($Cont); $R deactQ_BepaD___init__(deactQ_Bepa self, $Cont C_cont); $R deactQ_BepaD_callbackG_local(deactQ_Bepa self, $Cont C_cont, int64_t i); -B_Msg deactQ_BepaD_callback(deactQ_Bepa self, int64_t i); +B_Future deactQ_BepaD_callback(deactQ_Bepa self, int64_t i); extern struct deactQ_mainG_class deactQ_mainG_methods; $R deactQ_mainG_new($Cont, B_Env); $R deactQ_mainD___init__(deactQ_main self, $Cont C_cont, B_Env env); $R deactQ_mainD_myprocG_local(deactQ_main self, $Cont C_cont, int64_t i); -B_Msg deactQ_mainD_myproc(deactQ_main self, int64_t i); +B_Future deactQ_mainD_myproc(deactQ_main self, int64_t i); void deactQ___init__ (); \ No newline at end of file diff --git a/compiler/lib/test/9-codegen/deact.input b/compiler/lib/test/9-codegen/deact.input index db1230c9b..c56715e22 100644 --- a/compiler/lib/test/9-codegen/deact.input +++ b/compiler/lib/test/9-codegen/deact.input @@ -28,7 +28,7 @@ class L_4action ($action[(__builtin__.int,), __builtin__.int], $proc[(__builtin_ # (recursive group) proc def L_5C_3cont (cb : $action[(__builtin__.int,), __builtin__.int], C_cont : $Cont[__builtin__.int], C_4res : UNBOXED __builtin__.int) -> $R: v: UNBOXED __builtin__.int = (UNBOX __builtin__.int C_4res) - m: __builtin__.Msg[__builtin__.int] = cb.__asyn__((BOX __builtin__.int (UNBOX __builtin__.int 2))) + m: __builtin__.Future[__builtin__.int] = cb.__asyn__((BOX __builtin__.int (UNBOX __builtin__.int 2))) N_tmp: UNBOXED __builtin__.int = ((UNBOX __builtin__.int v) * (UNBOX __builtin__.int 10)) return $R_CONT@[__builtin__.int](C_cont, (BOX __builtin__.int N_tmp)) class L_6Cont ($Cont[__builtin__.int], __builtin__.value): @@ -354,7 +354,7 @@ class main ($Actor, __builtin__.value): @property b : Bepa @property - x : __builtin__.Msg[__builtin__.int] + x : __builtin__.Future[__builtin__.int] @property r : __builtin__.int proc def __init__ (self : main, C_cont : $Cont[None], env : __builtin__.Env) -> $R: diff --git a/compiler/lib/test/9-codegen/lines.c b/compiler/lib/test/9-codegen/lines.c index 5277ffc7d..eabb11e4d 100644 --- a/compiler/lib/test/9-codegen/lines.c +++ b/compiler/lib/test/9-codegen/lines.c @@ -52,14 +52,14 @@ B_NoneType linesQ_L_4actionD___init__ (linesQ_L_4action L_self, linesQ_Apa L_3ob return B_None; } $R linesQ_L_4actionD___call__ (linesQ_L_4action L_self, $Cont L_cont, B_int G_1) { - return $AWAIT(L_cont, ((B_Msg)((B_Msg (*) ($WORD, B_int))((linesQ_L_4action)(L_self))->$class->__asyn__)(L_self, toB_int(((B_int)G_1)->val)))); + return $AWAIT(L_cont, ((B_Future)((B_Future (*) ($WORD, B_int))((linesQ_L_4action)(L_self))->$class->__asyn__)(L_self, toB_int(((B_int)G_1)->val)))); } $R linesQ_L_4actionD___exec__ (linesQ_L_4action L_self, $Cont L_cont, B_int G_1) { - return $R_CONT(L_cont, ((B_value)((B_Msg (*) ($WORD, B_int))((linesQ_L_4action)(L_self))->$class->__asyn__)(L_self, toB_int(((B_int)G_1)->val)))); + return $R_CONT(L_cont, ((B_value)((B_Future (*) ($WORD, B_int))((linesQ_L_4action)(L_self))->$class->__asyn__)(L_self, toB_int(((B_int)G_1)->val)))); } -B_Msg linesQ_L_4actionD___asyn__ (linesQ_L_4action L_self, B_int G_1) { +B_Future linesQ_L_4actionD___asyn__ (linesQ_L_4action L_self, B_int G_1) { linesQ_Apa L_3obj = ((linesQ_L_4action)(L_self))->L_3obj; - return ((B_Msg)((B_Msg (*) ($WORD, int64_t))((linesQ_Apa)(L_3obj))->$class->notice)(L_3obj, ((B_int)G_1)->val)); + return ((B_Future)((B_Future (*) ($WORD, int64_t))((linesQ_Apa)(L_3obj))->$class->notice)(L_3obj, ((B_int)G_1)->val)); } void linesQ_L_4actionD___serialize__ (linesQ_L_4action self, $Serial$state state) { $step_serialize(self->L_3obj, state); @@ -88,7 +88,7 @@ struct linesQ_L_4actionG_class linesQ_L_4actionG_methods; #line 9 "test/src/lines.act" int64_t v = C_4res; #line 10 "test/src/lines.act" - B_Msg m = ((B_Msg)((B_Msg (*) ($WORD, B_int))(($action)(cb))->$class->__asyn__)(cb, toB_int(2LL))); + B_Future m = ((B_Future)((B_Future (*) ($WORD, B_int))(($action)(cb))->$class->__asyn__)(cb, toB_int(2LL))); int64_t N_tmp = (((int64_t)(v * 10LL))); return $R_CONT(C_cont, toB_int(N_tmp)); } @@ -286,14 +286,14 @@ B_NoneType linesQ_L_14actionD___init__ (linesQ_L_14action L_self, linesQ_Apa L_1 return B_None; } $R linesQ_L_14actionD___call__ (linesQ_L_14action L_self, $Cont L_cont, B_int G_1) { - return $AWAIT(L_cont, ((B_Msg)((B_Msg (*) ($WORD, B_int))((linesQ_L_14action)(L_self))->$class->__asyn__)(L_self, toB_int(((B_int)G_1)->val)))); + return $AWAIT(L_cont, ((B_Future)((B_Future (*) ($WORD, B_int))((linesQ_L_14action)(L_self))->$class->__asyn__)(L_self, toB_int(((B_int)G_1)->val)))); } $R linesQ_L_14actionD___exec__ (linesQ_L_14action L_self, $Cont L_cont, B_int G_1) { - return $R_CONT(L_cont, ((B_value)((B_Msg (*) ($WORD, B_int))((linesQ_L_14action)(L_self))->$class->__asyn__)(L_self, toB_int(((B_int)G_1)->val)))); + return $R_CONT(L_cont, ((B_value)((B_Future (*) ($WORD, B_int))((linesQ_L_14action)(L_self))->$class->__asyn__)(L_self, toB_int(((B_int)G_1)->val)))); } -B_Msg linesQ_L_14actionD___asyn__ (linesQ_L_14action L_self, B_int G_1) { +B_Future linesQ_L_14actionD___asyn__ (linesQ_L_14action L_self, B_int G_1) { linesQ_Apa L_13obj = ((linesQ_L_14action)(L_self))->L_13obj; - return ((B_Msg)((B_Msg (*) ($WORD, int64_t))((linesQ_Apa)(L_13obj))->$class->notice)(L_13obj, ((B_int)G_1)->val)); + return ((B_Future)((B_Future (*) ($WORD, int64_t))((linesQ_Apa)(L_13obj))->$class->notice)(L_13obj, ((B_int)G_1)->val)); } void linesQ_L_14actionD___serialize__ (linesQ_L_14action self, $Serial$state state) { $step_serialize(self->L_13obj, state); @@ -323,14 +323,14 @@ B_NoneType linesQ_L_16actionD___init__ (linesQ_L_16action L_self, linesQ_Bepa L_ return B_None; } $R linesQ_L_16actionD___call__ (linesQ_L_16action L_self, $Cont L_cont, B_int G_1) { - return $AWAIT(L_cont, ((B_Msg)((B_Msg (*) ($WORD, B_int))((linesQ_L_16action)(L_self))->$class->__asyn__)(L_self, toB_int(((B_int)G_1)->val)))); + return $AWAIT(L_cont, ((B_Future)((B_Future (*) ($WORD, B_int))((linesQ_L_16action)(L_self))->$class->__asyn__)(L_self, toB_int(((B_int)G_1)->val)))); } $R linesQ_L_16actionD___exec__ (linesQ_L_16action L_self, $Cont L_cont, B_int G_1) { - return $R_CONT(L_cont, ((B_value)((B_Msg (*) ($WORD, B_int))((linesQ_L_16action)(L_self))->$class->__asyn__)(L_self, toB_int(((B_int)G_1)->val)))); + return $R_CONT(L_cont, ((B_value)((B_Future (*) ($WORD, B_int))((linesQ_L_16action)(L_self))->$class->__asyn__)(L_self, toB_int(((B_int)G_1)->val)))); } -B_Msg linesQ_L_16actionD___asyn__ (linesQ_L_16action L_self, B_int G_1) { +B_Future linesQ_L_16actionD___asyn__ (linesQ_L_16action L_self, B_int G_1) { linesQ_Bepa L_15obj = ((linesQ_L_16action)(L_self))->L_15obj; - return ((B_Msg)((B_Msg (*) ($WORD, int64_t))((linesQ_Bepa)(L_15obj))->$class->callback)(L_15obj, ((B_int)G_1)->val)); + return ((B_Future)((B_Future (*) ($WORD, int64_t))((linesQ_Bepa)(L_15obj))->$class->callback)(L_15obj, ((B_int)G_1)->val)); } void linesQ_L_16actionD___serialize__ (linesQ_L_16action self, $Serial$state state) { $step_serialize(self->L_15obj, state); @@ -360,14 +360,14 @@ B_NoneType linesQ_L_19actionD___init__ (linesQ_L_19action L_self, linesQ_main L_ return B_None; } $R linesQ_L_19actionD___call__ (linesQ_L_19action L_self, $Cont L_cont, B_int G_1) { - return $AWAIT(L_cont, ((B_Msg)((B_Msg (*) ($WORD, B_int))((linesQ_L_19action)(L_self))->$class->__asyn__)(L_self, toB_int(((B_int)G_1)->val)))); + return $AWAIT(L_cont, ((B_Future)((B_Future (*) ($WORD, B_int))((linesQ_L_19action)(L_self))->$class->__asyn__)(L_self, toB_int(((B_int)G_1)->val)))); } $R linesQ_L_19actionD___exec__ (linesQ_L_19action L_self, $Cont L_cont, B_int G_1) { - return $R_CONT(L_cont, ((B_value)((B_Msg (*) ($WORD, B_int))((linesQ_L_19action)(L_self))->$class->__asyn__)(L_self, toB_int(((B_int)G_1)->val)))); + return $R_CONT(L_cont, ((B_value)((B_Future (*) ($WORD, B_int))((linesQ_L_19action)(L_self))->$class->__asyn__)(L_self, toB_int(((B_int)G_1)->val)))); } -B_Msg linesQ_L_19actionD___asyn__ (linesQ_L_19action L_self, B_int G_1) { +B_Future linesQ_L_19actionD___asyn__ (linesQ_L_19action L_self, B_int G_1) { linesQ_main L_18obj = ((linesQ_L_19action)(L_self))->L_18obj; - return ((B_Msg)((B_Msg (*) ($WORD, int64_t))((linesQ_main)(L_18obj))->$class->myproc)(L_18obj, ((B_int)G_1)->val)); + return ((B_Future)((B_Future (*) ($WORD, int64_t))((linesQ_main)(L_18obj))->$class->myproc)(L_18obj, ((B_int)G_1)->val)); } void linesQ_L_19actionD___serialize__ (linesQ_L_19action self, $Serial$state state) { $step_serialize(self->L_18obj, state); @@ -432,7 +432,7 @@ struct linesQ_L_20procG_class linesQ_L_20procG_methods; #line 39 "test/src/lines.act" ((B_NoneType (*) (B_tuple, B_str, B_str, B_bool, B_bool))B_print)($NEWTUPLE(2, to$str("r ="), toB_int(((int64_t)((linesQ_main)(self))->r))), B_None, B_None, B_None, B_None); #line 40 "test/src/lines.act" - ((B_Msg (*) ($WORD, $action))((linesQ_Apa)(((linesQ_main)(self))->a))->$class->compute)(((linesQ_main)(self))->a, (($action)linesQ_L_19actionG_new(self))); + ((B_Future (*) ($WORD, $action))((linesQ_Apa)(((linesQ_main)(self))->a))->$class->compute)(((linesQ_main)(self))->a, (($action)linesQ_L_19actionG_new(self))); #line 41 "test/src/lines.act" ((B_NoneType (*) (B_tuple, B_str, B_str, B_bool, B_bool))B_print)($NEWTUPLE(1, to$str("main")), B_None, B_None, B_None, B_None); #line 44 "test/src/lines.act" @@ -602,9 +602,9 @@ struct linesQ_L_21ContG_class linesQ_L_21ContG_methods; #line 35 "test/src/lines.act" ((B_NoneType (*) (B_tuple, B_str, B_str, B_bool, B_bool))B_print)($NEWTUPLE(1, to$str("-----")), B_None, B_None, B_None, B_None); #line 36 "test/src/lines.act" - ((B_Msg (*) ($WORD, $action))((linesQ_Apa)(((linesQ_main)(self))->a))->$class->setup)(((linesQ_main)(self))->a, (($action)linesQ_L_14actionG_new(((linesQ_main)(self))->a))); + ((B_Future (*) ($WORD, $action))((linesQ_Apa)(((linesQ_main)(self))->a))->$class->setup)(((linesQ_main)(self))->a, (($action)linesQ_L_14actionG_new(((linesQ_main)(self))->a))); #line 37 "test/src/lines.act" - ((linesQ_main)(self))->x = ((B_Msg (*) ($WORD, $action))((linesQ_Apa)(((linesQ_main)(self))->a))->$class->compute)(((linesQ_main)(self))->a, (($action)linesQ_L_16actionG_new(((linesQ_main)(self))->b))); + ((linesQ_main)(self))->x = ((B_Future (*) ($WORD, $action))((linesQ_Apa)(((linesQ_main)(self))->a))->$class->compute)(((linesQ_main)(self))->a, (($action)linesQ_L_16actionG_new(((linesQ_main)(self))->b))); return $AWAIT((($Cont)linesQ_L_21ContG_new(self, C_cont)), ((linesQ_main)(self))->x); } B_NoneType linesQ_L_22ContD___init__ (linesQ_L_22Cont L_self, linesQ_main self, $Cont C_cont) { @@ -989,14 +989,14 @@ struct linesQ_L_34procG_class linesQ_L_34procG_methods; #line 4 "test/src/lines.act" ((B_NoneType (*) (B_tuple, B_str, B_str, B_bool, B_bool))B_print)($NEWTUPLE(1, to$str("setup")), B_None, B_None, B_None, B_None); #line 5 "test/src/lines.act" - ((B_Msg (*) ($WORD, B_int))(($action)(cb))->$class->__asyn__)(cb, toB_int(0LL)); + ((B_Future (*) ($WORD, B_int))(($action)(cb))->$class->__asyn__)(cb, toB_int(0LL)); return $R_CONT(C_cont, B_None); } #line 7 "test/src/lines.act" $R linesQ_ApaD_computeG_local (linesQ_Apa self, $Cont C_cont, $action cb) { #line 8 "test/src/lines.act" ((B_NoneType (*) (B_tuple, B_str, B_str, B_bool, B_bool))B_print)($NEWTUPLE(1, to$str("compute")), B_None, B_None, B_None, B_None); - return $AWAIT((($Cont)linesQ_L_6ContG_new(cb, C_cont)), ((B_Msg)((B_Msg (*) ($WORD, B_int))(($action)(cb))->$class->__asyn__)(cb, toB_int(1LL)))); + return $AWAIT((($Cont)linesQ_L_6ContG_new(cb, C_cont)), ((B_Future)((B_Future (*) ($WORD, B_int))(($action)(cb))->$class->__asyn__)(cb, toB_int(1LL)))); } #line 12 "test/src/lines.act" $R linesQ_ApaD_noticeG_local (linesQ_Apa self, $Cont C_cont, int64_t i) { @@ -1005,14 +1005,14 @@ struct linesQ_L_34procG_class linesQ_L_34procG_methods; int64_t N_1tmp = (((int64_t)(i + 1LL))); return $R_CONT(C_cont, toB_int(N_1tmp)); } -B_Msg linesQ_ApaD_setup (linesQ_Apa self, $action cb) { +B_Future linesQ_ApaD_setup (linesQ_Apa self, $action cb) { return $ASYNC((($Actor)self), (($Cont)linesQ_L_7procG_new(self, cb))); } -B_Msg linesQ_ApaD_compute (linesQ_Apa self, $action cb) { - return ((B_Msg)$ASYNC((($Actor)self), (($Cont)linesQ_L_8procG_new(self, cb)))); +B_Future linesQ_ApaD_compute (linesQ_Apa self, $action cb) { + return ((B_Future)$ASYNC((($Actor)self), (($Cont)linesQ_L_8procG_new(self, cb)))); } -B_Msg linesQ_ApaD_notice (linesQ_Apa self, int64_t i) { - return ((B_Msg)$ASYNC((($Actor)self), (($Cont)linesQ_L_9procG_new(self, i)))); +B_Future linesQ_ApaD_notice (linesQ_Apa self, int64_t i) { + return ((B_Future)$ASYNC((($Actor)self), (($Cont)linesQ_L_9procG_new(self, i)))); } void linesQ_ApaD___serialize__ (linesQ_Apa self, $Serial$state state) { $ActorG_methods.__serialize__(($Actor)self, state); @@ -1064,8 +1064,8 @@ struct linesQ_ApaG_class linesQ_ApaG_methods; int64_t N_2tmp = (((int64_t)(i + 1LL))); return $R_CONT(C_cont, toB_int(N_2tmp)); } -B_Msg linesQ_BepaD_callback (linesQ_Bepa self, int64_t i) { - return ((B_Msg)$ASYNC((($Actor)self), (($Cont)linesQ_L_10procG_new(self, i)))); +B_Future linesQ_BepaD_callback (linesQ_Bepa self, int64_t i) { + return ((B_Future)$ASYNC((($Actor)self), (($Cont)linesQ_L_10procG_new(self, i)))); } void linesQ_BepaD___serialize__ (linesQ_Bepa self, $Serial$state state) { $ActorG_methods.__serialize__(($Actor)self, state); @@ -1104,7 +1104,7 @@ struct linesQ_BepaG_class linesQ_BepaG_methods; #line 30 "test/src/lines.act" if (((bool (*) ($WORD, B_int, B_int))((B_Eq)(linesQ_W_Apa_331))->$class->__eq__)(linesQ_W_Apa_331, toB_int(i), toB_int(2LL))) { #line 31 "test/src/lines.act" - ((B_Msg (*) ($WORD, int64_t))((B_Env)(((linesQ_main)(self))->env))->$class->exit)(((linesQ_main)(self))->env, 0LL); + ((B_Future (*) ($WORD, int64_t))((B_Env)(((linesQ_main)(self))->env))->$class->exit)(((linesQ_main)(self))->env, 0LL); } return $R_CONT(C_cont, toB_int(i)); } @@ -1113,10 +1113,10 @@ struct linesQ_BepaG_class linesQ_BepaG_methods; #line 93 "test/src/lines.act" return $R_CONT(C_cont, B_None); } -B_Msg linesQ_mainD_myproc (linesQ_main self, int64_t i) { - return ((B_Msg)$ASYNC((($Actor)self), (($Cont)linesQ_L_24procG_new(self, i)))); +B_Future linesQ_mainD_myproc (linesQ_main self, int64_t i) { + return ((B_Future)$ASYNC((($Actor)self), (($Cont)linesQ_L_24procG_new(self, i)))); } -B_Msg linesQ_mainD_nop (linesQ_main self) { +B_Future linesQ_mainD_nop (linesQ_main self) { return $ASYNC((($Actor)self), (($Cont)linesQ_L_25procG_new(self))); } void linesQ_mainD___serialize__ (linesQ_main self, $Serial$state state) { @@ -1208,7 +1208,7 @@ void linesQ___init__ () { linesQ_L_4actionG_methods.__init__ = (B_NoneType (*) (linesQ_L_4action, linesQ_Apa))linesQ_L_4actionD___init__; linesQ_L_4actionG_methods.__call__ = ($R (*) (linesQ_L_4action, $Cont, B_int))linesQ_L_4actionD___call__; linesQ_L_4actionG_methods.__exec__ = ($R (*) (linesQ_L_4action, $Cont, B_int))linesQ_L_4actionD___exec__; - linesQ_L_4actionG_methods.__asyn__ = (B_Msg (*) (linesQ_L_4action, B_int))linesQ_L_4actionD___asyn__; + linesQ_L_4actionG_methods.__asyn__ = (B_Future (*) (linesQ_L_4action, B_int))linesQ_L_4actionD___asyn__; linesQ_L_4actionG_methods.__serialize__ = linesQ_L_4actionD___serialize__; linesQ_L_4actionG_methods.__deserialize__ = linesQ_L_4actionD___deserialize__; $register(&linesQ_L_4actionG_methods); @@ -1286,7 +1286,7 @@ void linesQ___init__ () { linesQ_L_14actionG_methods.__init__ = (B_NoneType (*) (linesQ_L_14action, linesQ_Apa))linesQ_L_14actionD___init__; linesQ_L_14actionG_methods.__call__ = ($R (*) (linesQ_L_14action, $Cont, B_int))linesQ_L_14actionD___call__; linesQ_L_14actionG_methods.__exec__ = ($R (*) (linesQ_L_14action, $Cont, B_int))linesQ_L_14actionD___exec__; - linesQ_L_14actionG_methods.__asyn__ = (B_Msg (*) (linesQ_L_14action, B_int))linesQ_L_14actionD___asyn__; + linesQ_L_14actionG_methods.__asyn__ = (B_Future (*) (linesQ_L_14action, B_int))linesQ_L_14actionD___asyn__; linesQ_L_14actionG_methods.__serialize__ = linesQ_L_14actionD___serialize__; linesQ_L_14actionG_methods.__deserialize__ = linesQ_L_14actionD___deserialize__; $register(&linesQ_L_14actionG_methods); @@ -1300,7 +1300,7 @@ void linesQ___init__ () { linesQ_L_16actionG_methods.__init__ = (B_NoneType (*) (linesQ_L_16action, linesQ_Bepa))linesQ_L_16actionD___init__; linesQ_L_16actionG_methods.__call__ = ($R (*) (linesQ_L_16action, $Cont, B_int))linesQ_L_16actionD___call__; linesQ_L_16actionG_methods.__exec__ = ($R (*) (linesQ_L_16action, $Cont, B_int))linesQ_L_16actionD___exec__; - linesQ_L_16actionG_methods.__asyn__ = (B_Msg (*) (linesQ_L_16action, B_int))linesQ_L_16actionD___asyn__; + linesQ_L_16actionG_methods.__asyn__ = (B_Future (*) (linesQ_L_16action, B_int))linesQ_L_16actionD___asyn__; linesQ_L_16actionG_methods.__serialize__ = linesQ_L_16actionD___serialize__; linesQ_L_16actionG_methods.__deserialize__ = linesQ_L_16actionD___deserialize__; $register(&linesQ_L_16actionG_methods); @@ -1314,7 +1314,7 @@ void linesQ___init__ () { linesQ_L_19actionG_methods.__init__ = (B_NoneType (*) (linesQ_L_19action, linesQ_main))linesQ_L_19actionD___init__; linesQ_L_19actionG_methods.__call__ = ($R (*) (linesQ_L_19action, $Cont, B_int))linesQ_L_19actionD___call__; linesQ_L_19actionG_methods.__exec__ = ($R (*) (linesQ_L_19action, $Cont, B_int))linesQ_L_19actionD___exec__; - linesQ_L_19actionG_methods.__asyn__ = (B_Msg (*) (linesQ_L_19action, B_int))linesQ_L_19actionD___asyn__; + linesQ_L_19actionG_methods.__asyn__ = (B_Future (*) (linesQ_L_19action, B_int))linesQ_L_19actionD___asyn__; linesQ_L_19actionG_methods.__serialize__ = linesQ_L_19actionD___serialize__; linesQ_L_19actionG_methods.__deserialize__ = linesQ_L_19actionD___deserialize__; $register(&linesQ_L_19actionG_methods); @@ -1481,9 +1481,9 @@ void linesQ___init__ () { linesQ_ApaG_methods.setupG_local = ($R (*) (linesQ_Apa, $Cont, $action))linesQ_ApaD_setupG_local; linesQ_ApaG_methods.computeG_local = ($R (*) (linesQ_Apa, $Cont, $action))linesQ_ApaD_computeG_local; linesQ_ApaG_methods.noticeG_local = ($R (*) (linesQ_Apa, $Cont, int64_t))linesQ_ApaD_noticeG_local; - linesQ_ApaG_methods.setup = (B_Msg (*) (linesQ_Apa, $action))linesQ_ApaD_setup; - linesQ_ApaG_methods.compute = (B_Msg (*) (linesQ_Apa, $action))linesQ_ApaD_compute; - linesQ_ApaG_methods.notice = (B_Msg (*) (linesQ_Apa, int64_t))linesQ_ApaD_notice; + linesQ_ApaG_methods.setup = (B_Future (*) (linesQ_Apa, $action))linesQ_ApaD_setup; + linesQ_ApaG_methods.compute = (B_Future (*) (linesQ_Apa, $action))linesQ_ApaD_compute; + linesQ_ApaG_methods.notice = (B_Future (*) (linesQ_Apa, int64_t))linesQ_ApaD_notice; linesQ_ApaG_methods.__serialize__ = linesQ_ApaD___serialize__; linesQ_ApaG_methods.__deserialize__ = linesQ_ApaD___deserialize__; $register(&linesQ_ApaG_methods); @@ -1498,7 +1498,7 @@ void linesQ___init__ () { linesQ_BepaG_methods.__cleanup__ = (B_NoneType (*) (linesQ_Bepa))$ActorG_methods.__cleanup__; linesQ_BepaG_methods.__init__ = ($R (*) (linesQ_Bepa, $Cont))linesQ_BepaD___init__; linesQ_BepaG_methods.callbackG_local = ($R (*) (linesQ_Bepa, $Cont, int64_t))linesQ_BepaD_callbackG_local; - linesQ_BepaG_methods.callback = (B_Msg (*) (linesQ_Bepa, int64_t))linesQ_BepaD_callback; + linesQ_BepaG_methods.callback = (B_Future (*) (linesQ_Bepa, int64_t))linesQ_BepaD_callback; linesQ_BepaG_methods.__serialize__ = linesQ_BepaD___serialize__; linesQ_BepaG_methods.__deserialize__ = linesQ_BepaD___deserialize__; $register(&linesQ_BepaG_methods); @@ -1514,8 +1514,8 @@ void linesQ___init__ () { linesQ_mainG_methods.__init__ = ($R (*) (linesQ_main, $Cont, B_Env))linesQ_mainD___init__; linesQ_mainG_methods.myprocG_local = ($R (*) (linesQ_main, $Cont, int64_t))linesQ_mainD_myprocG_local; linesQ_mainG_methods.nopG_local = ($R (*) (linesQ_main, $Cont))linesQ_mainD_nopG_local; - linesQ_mainG_methods.myproc = (B_Msg (*) (linesQ_main, int64_t))linesQ_mainD_myproc; - linesQ_mainG_methods.nop = (B_Msg (*) (linesQ_main))linesQ_mainD_nop; + linesQ_mainG_methods.myproc = (B_Future (*) (linesQ_main, int64_t))linesQ_mainD_myproc; + linesQ_mainG_methods.nop = (B_Future (*) (linesQ_main))linesQ_mainD_nop; linesQ_mainG_methods.__serialize__ = linesQ_mainD___serialize__; linesQ_mainG_methods.__deserialize__ = linesQ_mainD___deserialize__; $register(&linesQ_mainG_methods); diff --git a/compiler/lib/test/9-codegen/lines.h b/compiler/lib/test/9-codegen/lines.h index e570f9406..ff4b4451d 100644 --- a/compiler/lib/test/9-codegen/lines.h +++ b/compiler/lib/test/9-codegen/lines.h @@ -82,7 +82,7 @@ struct linesQ_L_4actionG_class { B_str (*__repr__) (linesQ_L_4action); $R (*__call__) (linesQ_L_4action, $Cont, B_int); $R (*__exec__) (linesQ_L_4action, $Cont, B_int); - B_Msg (*__asyn__) (linesQ_L_4action, B_int); + B_Future (*__asyn__) (linesQ_L_4action, B_int); }; struct linesQ_L_4action { struct linesQ_L_4actionG_class *$class; @@ -190,7 +190,7 @@ struct linesQ_L_14actionG_class { B_str (*__repr__) (linesQ_L_14action); $R (*__call__) (linesQ_L_14action, $Cont, B_int); $R (*__exec__) (linesQ_L_14action, $Cont, B_int); - B_Msg (*__asyn__) (linesQ_L_14action, B_int); + B_Future (*__asyn__) (linesQ_L_14action, B_int); }; struct linesQ_L_14action { struct linesQ_L_14actionG_class *$class; @@ -208,7 +208,7 @@ struct linesQ_L_16actionG_class { B_str (*__repr__) (linesQ_L_16action); $R (*__call__) (linesQ_L_16action, $Cont, B_int); $R (*__exec__) (linesQ_L_16action, $Cont, B_int); - B_Msg (*__asyn__) (linesQ_L_16action, B_int); + B_Future (*__asyn__) (linesQ_L_16action, B_int); }; struct linesQ_L_16action { struct linesQ_L_16actionG_class *$class; @@ -226,7 +226,7 @@ struct linesQ_L_19actionG_class { B_str (*__repr__) (linesQ_L_19action); $R (*__call__) (linesQ_L_19action, $Cont, B_int); $R (*__exec__) (linesQ_L_19action, $Cont, B_int); - B_Msg (*__asyn__) (linesQ_L_19action, B_int); + B_Future (*__asyn__) (linesQ_L_19action, B_int); }; struct linesQ_L_19action { struct linesQ_L_19actionG_class *$class; @@ -459,9 +459,9 @@ struct linesQ_ApaG_class { $R (*setupG_local) (linesQ_Apa, $Cont, $action); $R (*computeG_local) (linesQ_Apa, $Cont, $action); $R (*noticeG_local) (linesQ_Apa, $Cont, int64_t); - B_Msg (*setup) (linesQ_Apa, $action); - B_Msg (*compute) (linesQ_Apa, $action); - B_Msg (*notice) (linesQ_Apa, int64_t); + B_Future (*setup) (linesQ_Apa, $action); + B_Future (*compute) (linesQ_Apa, $action); + B_Future (*notice) (linesQ_Apa, int64_t); }; struct linesQ_Apa { struct linesQ_ApaG_class *$class; @@ -471,7 +471,7 @@ struct linesQ_Apa { $Lock $msg_lock; $int64 $affinity; B_Msg $outgoing; - B_Msg $waitsfor; + B_Future $waitsfor; $int64 $consume_hd; $Catcher $catcher; $long $globkey; @@ -493,7 +493,7 @@ struct linesQ_BepaG_class { B_NoneType (*__resume__) (linesQ_Bepa); B_NoneType (*__cleanup__) (linesQ_Bepa); $R (*callbackG_local) (linesQ_Bepa, $Cont, int64_t); - B_Msg (*callback) (linesQ_Bepa, int64_t); + B_Future (*callback) (linesQ_Bepa, int64_t); }; struct linesQ_Bepa { struct linesQ_BepaG_class *$class; @@ -503,7 +503,7 @@ struct linesQ_Bepa { $Lock $msg_lock; $int64 $affinity; B_Msg $outgoing; - B_Msg $waitsfor; + B_Future $waitsfor; $int64 $consume_hd; $Catcher $catcher; $long $globkey; @@ -522,8 +522,8 @@ struct linesQ_mainG_class { B_NoneType (*__cleanup__) (linesQ_main); $R (*myprocG_local) (linesQ_main, $Cont, int64_t); $R (*nopG_local) (linesQ_main, $Cont); - B_Msg (*myproc) (linesQ_main, int64_t); - B_Msg (*nop) (linesQ_main); + B_Future (*myproc) (linesQ_main, int64_t); + B_Future (*nop) (linesQ_main); }; struct linesQ_main { struct linesQ_mainG_class *$class; @@ -533,14 +533,14 @@ struct linesQ_main { $Lock $msg_lock; $int64 $affinity; B_Msg $outgoing; - B_Msg $waitsfor; + B_Future $waitsfor; $int64 $consume_hd; $Catcher $catcher; $long $globkey; B_Env env; linesQ_Apa a; linesQ_Bepa b; - B_Msg x; + B_Future x; int64_t r; int64_t v; int64_t i; @@ -557,7 +557,7 @@ linesQ_L_4action linesQ_L_4actionG_new(linesQ_Apa); B_NoneType linesQ_L_4actionD___init__(linesQ_L_4action L_self, linesQ_Apa L_3obj); $R linesQ_L_4actionD___call__(linesQ_L_4action L_self, $Cont L_cont, B_int G_1); $R linesQ_L_4actionD___exec__(linesQ_L_4action L_self, $Cont L_cont, B_int G_1); -B_Msg linesQ_L_4actionD___asyn__(linesQ_L_4action L_self, B_int G_1); +B_Future linesQ_L_4actionD___asyn__(linesQ_L_4action L_self, B_int G_1); extern struct linesQ_L_6ContG_class linesQ_L_6ContG_methods; linesQ_L_6Cont linesQ_L_6ContG_new($action, $Cont); B_NoneType linesQ_L_6ContD___init__(linesQ_L_6Cont L_self, $action cb, $Cont C_cont); @@ -587,19 +587,19 @@ linesQ_L_14action linesQ_L_14actionG_new(linesQ_Apa); B_NoneType linesQ_L_14actionD___init__(linesQ_L_14action L_self, linesQ_Apa L_13obj); $R linesQ_L_14actionD___call__(linesQ_L_14action L_self, $Cont L_cont, B_int G_1); $R linesQ_L_14actionD___exec__(linesQ_L_14action L_self, $Cont L_cont, B_int G_1); -B_Msg linesQ_L_14actionD___asyn__(linesQ_L_14action L_self, B_int G_1); +B_Future linesQ_L_14actionD___asyn__(linesQ_L_14action L_self, B_int G_1); extern struct linesQ_L_16actionG_class linesQ_L_16actionG_methods; linesQ_L_16action linesQ_L_16actionG_new(linesQ_Bepa); B_NoneType linesQ_L_16actionD___init__(linesQ_L_16action L_self, linesQ_Bepa L_15obj); $R linesQ_L_16actionD___call__(linesQ_L_16action L_self, $Cont L_cont, B_int G_1); $R linesQ_L_16actionD___exec__(linesQ_L_16action L_self, $Cont L_cont, B_int G_1); -B_Msg linesQ_L_16actionD___asyn__(linesQ_L_16action L_self, B_int G_1); +B_Future linesQ_L_16actionD___asyn__(linesQ_L_16action L_self, B_int G_1); extern struct linesQ_L_19actionG_class linesQ_L_19actionG_methods; linesQ_L_19action linesQ_L_19actionG_new(linesQ_main); B_NoneType linesQ_L_19actionD___init__(linesQ_L_19action L_self, linesQ_main L_18obj); $R linesQ_L_19actionD___call__(linesQ_L_19action L_self, $Cont L_cont, B_int G_1); $R linesQ_L_19actionD___exec__(linesQ_L_19action L_self, $Cont L_cont, B_int G_1); -B_Msg linesQ_L_19actionD___asyn__(linesQ_L_19action L_self, B_int G_1); +B_Future linesQ_L_19actionD___asyn__(linesQ_L_19action L_self, B_int G_1); extern struct linesQ_L_20procG_class linesQ_L_20procG_methods; linesQ_L_20proc linesQ_L_20procG_new(linesQ_main); B_NoneType linesQ_L_20procD___init__(linesQ_L_20proc L_self, linesQ_main self); @@ -660,21 +660,21 @@ extern struct linesQ_ApaG_class linesQ_ApaG_methods; $R linesQ_ApaD_setupG_local(linesQ_Apa self, $Cont C_cont, $action cb); $R linesQ_ApaD_computeG_local(linesQ_Apa self, $Cont C_cont, $action cb); $R linesQ_ApaD_noticeG_local(linesQ_Apa self, $Cont C_cont, int64_t i); -B_Msg linesQ_ApaD_setup(linesQ_Apa self, $action cb); -B_Msg linesQ_ApaD_compute(linesQ_Apa self, $action cb); -B_Msg linesQ_ApaD_notice(linesQ_Apa self, int64_t i); +B_Future linesQ_ApaD_setup(linesQ_Apa self, $action cb); +B_Future linesQ_ApaD_compute(linesQ_Apa self, $action cb); +B_Future linesQ_ApaD_notice(linesQ_Apa self, int64_t i); extern struct linesQ_BepaG_class linesQ_BepaG_methods; $R linesQ_BepaG_new($Cont); $R linesQ_BepaD___init__(linesQ_Bepa self, $Cont C_cont); $R linesQ_BepaD_callbackG_local(linesQ_Bepa self, $Cont C_cont, int64_t i); -B_Msg linesQ_BepaD_callback(linesQ_Bepa self, int64_t i); +B_Future linesQ_BepaD_callback(linesQ_Bepa self, int64_t i); extern struct linesQ_mainG_class linesQ_mainG_methods; $R linesQ_mainG_new($Cont, B_Env); $R linesQ_mainD___init__(linesQ_main self, $Cont C_cont, B_Env env); $R linesQ_mainD_myprocG_local(linesQ_main self, $Cont C_cont, int64_t i); $R linesQ_mainD_nopG_local(linesQ_main self, $Cont C_cont); -B_Msg linesQ_mainD_myproc(linesQ_main self, int64_t i); -B_Msg linesQ_mainD_nop(linesQ_main self); +B_Future linesQ_mainD_myproc(linesQ_main self, int64_t i); +B_Future linesQ_mainD_nop(linesQ_main self); extern B_Eq linesQ_W_Apa_1097; extern B_Eq linesQ_W_Apa_759; extern B_Eq linesQ_W_Apa_331; diff --git a/compiler/lib/test/9-codegen/lines.input b/compiler/lib/test/9-codegen/lines.input index 604363e6b..a91b44d17 100644 --- a/compiler/lib/test/9-codegen/lines.input +++ b/compiler/lib/test/9-codegen/lines.input @@ -41,7 +41,7 @@ class L_4action ($action[(__builtin__.int,), __builtin__.int], $proc[(__builtin_ # (recursive group) proc def L_5C_3cont (cb : $action[(__builtin__.int,), __builtin__.int], C_cont : $Cont[__builtin__.int], C_4res : UNBOXED __builtin__.int) -> $R: v: UNBOXED __builtin__.int = (UNBOX __builtin__.int C_4res) - m: __builtin__.Msg[__builtin__.int] = cb.__asyn__((BOX __builtin__.int (UNBOX __builtin__.int 2))) + m: __builtin__.Future[__builtin__.int] = cb.__asyn__((BOX __builtin__.int (UNBOX __builtin__.int 2))) N_tmp: UNBOXED __builtin__.int = ((UNBOX __builtin__.int v) * (UNBOX __builtin__.int 10)) return $R_CONT@[__builtin__.int](C_cont, (BOX __builtin__.int N_tmp)) class L_6Cont ($Cont[__builtin__.int], __builtin__.value): @@ -472,7 +472,7 @@ class main ($Actor, __builtin__.value): @property b : Bepa @property - x : __builtin__.Msg[__builtin__.int] + x : __builtin__.Future[__builtin__.int] @property r : __builtin__.int @property diff --git a/compiler/tests/env.c b/compiler/tests/env.c index 20177d50e..641466785 100644 --- a/compiler/tests/env.c +++ b/compiler/tests/env.c @@ -27,9 +27,9 @@ struct Connection { }; struct ConnectionD___class__ { char *$GCINFO; - B_Msg (*deliver)(ConnectionD___class__, $WORD, B_str); - B_Msg (*close)(ConnectionD___class__, $WORD); - B_Msg (*receive_on)(ConnectionD___class__, $WORD, $function, $function); + B_Future (*deliver)(ConnectionD___class__, $WORD, B_str); + B_Future (*close)(ConnectionD___class__, $WORD); + B_Future (*receive_on)(ConnectionD___class__, $WORD, $function, $function); }; Connection ConnectionD___pack__(ConnectionD___class__ __class__, $WORD __impl__) { @@ -52,7 +52,7 @@ struct Env { }; struct EnvD___class__ { char *$GCINFO; - B_Msg (*open)(EnvD___class__, $WORD, B_str, B_int, $function); + B_Future (*open)(EnvD___class__, $WORD, B_str, B_int, $function); }; Env EnvD___pack__(EnvD___class__ __class__, $WORD __impl__) { @@ -74,17 +74,17 @@ struct TrueConnection { // more... }; -B_Msg TrueConnection$deliver (ConnectionD___class__ cls, $WORD __impl__, B_str data) { +B_Future TrueConnection$deliver (ConnectionD___class__ cls, $WORD __impl__, B_str data) { TrueConnection trueSelf = (TrueConnection)__impl__; return NULL; } -B_Msg TrueConnection$close (ConnectionD___class__ cls, $WORD __impl__) { +B_Future TrueConnection$close (ConnectionD___class__ cls, $WORD __impl__) { TrueConnection trueSelf = (TrueConnection)__impl__; return NULL; } -B_Msg TrueConnection$receive_on (ConnectionD___class__ cls, $WORD __impl__, $function input, $function error) { +B_Future TrueConnection$receive_on (ConnectionD___class__ cls, $WORD __impl__, $function input, $function error) { TrueConnection trueSelf = (TrueConnection)__impl__; return NULL; } @@ -101,12 +101,12 @@ struct ConnectionD___class__ Connection___TrueConnection = { struct TrueEnv; typedef struct TrueEnv *TrueEnv; -B_Msg TrueEnv$open(EnvD___class__ cls, $WORD __impl__, B_str address, B_int port, $function callback) { +B_Future TrueEnv$open(EnvD___class__ cls, $WORD __impl__, B_str address, B_int port, $function callback) { TrueEnv self = (TrueEnv)__impl__; TrueConnection trueConn = /* create socket, etc, ... */ NULL; Connection conn = ConnectionD___pack__(&Connection___TrueConnection, trueConn); - B_Msg m = /* ASYNC... */ NULL; + B_Future m = /* ASYNC... */ NULL; return m; } diff --git a/compiler/tests/test.act b/compiler/tests/test.act index 09c85afa2..014d73f71 100644 --- a/compiler/tests/test.act +++ b/compiler/tests/test.act @@ -22,7 +22,7 @@ x7 : [A(Hashable), B, S(Mapping[A,B])] => (S)->dict[A,B] # Qualified/constrained x8 : ((int) -> int,(b : bool),(int,int)) # more complicated tuple x9 : act[X] (int,*A,b : bool,**B) -> set[int] # function with effects and all kinds of parameters -x10: action(int, *A, b: bool) -> Msg[int] +x10: action(int, *A, b: bool) -> Future[int] x11: X(f: X(A)->B, a: [A]) -> [B] #x12: st[Y](int, list[Y,str]) -> str #x13: st(int, dict[int]) -> None diff --git a/docs/acton-dev-guide/src/SUMMARY.md b/docs/acton-dev-guide/src/SUMMARY.md index 6eb1acb1b..19aeee2ee 100644 --- a/docs/acton-dev-guide/src/SUMMARY.md +++ b/docs/acton-dev-guide/src/SUMMARY.md @@ -31,6 +31,7 @@ - [Scheduler](runtime/scheduler.md) - [RTS sync pause](runtime/sync_pause.md) - [Actors](runtime/actors.md) + - [Messages and futures](runtime/messages.md) - [Memory and GC](runtime/memory.md) - [IO memory management](runtime/io_memory.md) - [Tooling](tooling/index.md) diff --git a/docs/acton-dev-guide/src/runtime/messages.md b/docs/acton-dev-guide/src/runtime/messages.md new file mode 100644 index 000000000..2f0c99e2c --- /dev/null +++ b/docs/acton-dev-guide/src/runtime/messages.md @@ -0,0 +1,161 @@ +# Messages and futures + +This note explains how an asynchronous call is represented in the runtime, and +why the representation is split into two distinct objects: a short-lived +**transport message** (the envelope, `B_Msg`) and a longer-lived **future** +(`B_Future`, the C type behind the surface type `Future[A]`). + +The split matters because the runtime is moving towards a **per-actor** memory +model: each actor has its own heap and is garbage-collected independently (see +[Memory and GC](memory.md)). Under per-actor heaps an actor may only write objects +on its *own* heap; the two roles a message plays — being delivered-and-run versus +being awaited-for-a-result — have different owners and different lifetimes, so +conflating them into one object makes the ownership story impossible. Splitting +them is what makes the per-actor model expressible. + +Implementation lives in `base/rts/rts.c`, `base/rts/rts.h`, and `base/rts/q.c`. + +## Background: how an async call works + +When actor A calls a method on actor B, the call does not run on A. It is turned +into a message delivered to B, which runs it during one of B's turns. A may want +the result later — that is what `await` retrieves. Two things therefore have to +exist: + +1. something to **carry the call to B and drive it** while B runs it, and +2. something to **hold the eventual result** so A (or whoever holds the handle) + can read it. + +These are distinct jobs with different owners and different lifetimes: the +envelope belongs to the machinery delivering one call and dies with it, while +the result handle belongs to whoever awaits it and lives as long as they hold +it. The runtime therefore represents them as two objects. + +## The two objects + +### The message envelope (`B_Msg`) + +The envelope is an RTS-internal type (a hand-written runtime object like `$Actor` +and `$Cont`, not exposed to Acton source; its C type is `B_Msg`). It is the message +in flight to an actor and the actor's **activation frame** while that message runs. + +```c +struct B_Msg { + struct B_MsgG_class *$class; + B_Msg $next; // mailbox / outgoing / timer linkage + $Actor $to; // recipient actor + $Cont $cont; // activation: continuation to run + time_t $baseline; // logical delivery time (normal vs timer) + $WORD value; // activation: continuation argument + B_Future $fut; // the future this envelope fulfills + $long $globkey; // identity (used for DB persistence) +}; +``` + +The scheduler loop (`wt_work_cb` in `rts.c`) takes the actor's current envelope +`current->$msg`, and runs `m->$cont(m->value)`. A continuation step (`$RCONT`) +rewrites `$cont`/`value` and re-runs the same envelope. On `await` of a pending +future (`$RWAIT`) the envelope is *parked*: it stays at the mailbox head, holding +the suspended continuation, until the result arrives and the turn eventually +finishes. Only `$RDONE` (or an unhandled `$RFAIL`) consumes (dequeues) it. So an +envelope lives for exactly one call — but that call may span an await. + +### The future (`B_Future`) + +The future is the runtime object behind the surface type `Future[A]` (its C type is +`B_Future`). It is the promise/result cell: produced by an async call, completed +once, read by whoever holds the handle. + +```c +struct B_Future { + struct B_FutureG_class *$class; + $Actor $waiting; // head of the waiting-actor list + $Lock $wait_lock; // protects $waiting + $int64 $state; // FUT_PENDING / FUT_VALUE / FUT_EXCEPTION + $WORD value; // the result (or the raised exception) + $long $globkey; // identity (used for DB persistence) +}; +``` + +Result state is an explicit enum: + +```c +#define FUT_PENDING 0 +#define FUT_VALUE 1 +#define FUT_EXCEPTION 2 +``` + +A future lives as long as something holds a reference to it — potentially much +longer than the envelope that produced it, which is exactly why it must be a +separate object with its own lifetime. + +> **Note — naming.** A *message* is the thing in transit; a *future* is the +> result you await. The envelope is RTS-internal (`B_Msg`, invisible to Acton +> source, like `$Actor`); the future is the builtin behind the surface type +> `Future[A]` (`B_Future`). Generated code treats the future opaquely — it only +> ever calls the `$ASYNC`/`$AWAIT`/`$AFTER` primitives and never inspects the +> object's fields — and compiler-emitted actor headers declare the mailbox +> slots `$msg`/`$msg_tail`/`$outgoing` as `B_Msg` (an opaque pointer type to +> generated code). + +## How a call is built: `$ASYNC` and `$AFTER` + +An async call allocates **one of each** and links them. `$ASYNC` (in `rts.c`): + +```c +B_Future $ASYNC($Actor to, $Cont cont) { + $Actor self = GET_SELF(); + B_Future fut = B_FutureG_new(); // the future, returned to the caller + B_Msg env = B_MsgG_newXX(to, cont, 0, &$Done$instance); + env->$fut = fut; // envelope -> the future it fulfills + ... // buffer env on the caller's outgoing queue (flushed to `to`'s + ... // mailbox when the caller's turn ends); return fut + +} +``` + +The envelope goes to the callee `to`; the future is returned to the caller. The +link `env->$fut` is how the running envelope knows which future to complete. When +the callee's turn ends, the result is frozen into `env->$fut` and any waiting +actors are woken. + +`$AFTER` builds only the envelope, addressed back to `self` with a future-dated +`$baseline`, and allocates no future: `after` is a statement, so its value +cannot be bound or awaited, and the dispatch loop skips result delivery for an +envelope whose `$fut` is NULL. + +## DB persistence + +With `--db` (the distributed backend), actors and in-flight messages are persisted +so a node can recover. The split is reflected in the persistence layer: + +- The envelope and the future are distinct serializable classes with their own + preassigned class ids (`MSG_ID` / `FUTURE_ID`). Both kinds of row live in + `MSGS_TABLE`; each row carries its class id, so recovery + (`deserialize_system`) allocates the correct struct for each. +- `serialize_msg` persists an envelope and, via `serialize_future`, the future it + fulfills; `serialize_actor` persists the actor's outgoing envelopes. No waiter + state is persisted: an actor parked on an `await` is recovered by replaying its + whole turn from the parked envelope at its mailbox head, so `$waitsfor` is + rebuilt by re-execution rather than stored. + +This path is validated by `make test-rts-db`. + +> **Note — future direction.** A later transport layer is expected to carry +> messages in a pooled mailbox whose envelopes are not themselves serializable. +> Persisting in-flight messages for DB recovery will then need a separate +> serializable record (or snapshotting only at turn boundaries). This is a known +> seam for that work, not a property of the current split. + +## Direction + +The landed split is deliberately mechanical: the runtime still completes a +future with a direct write and wakes waiters via `ADD_waiting`/`FREEZE_waiting`, +which mutate objects across actor boundaries. Under per-actor heaps those +cross-actor writes have to become messages between the actors involved; the +waiter bookkeeping then becomes local to a single actor and `$wait_lock` +disappears. That await redesign is tracked separately and builds on this split; +nothing in the current layout presupposes a particular protocol. + +See also: [Actors](actors.md), [Scheduler](scheduler.md), and +[Memory and GC](memory.md). diff --git a/test/core_lang_auto/await_already_done.act b/test/core_lang_auto/await_already_done.act index b3326eecf..a69976e84 100644 --- a/test/core_lang_auto/await_already_done.act +++ b/test/core_lang_auto/await_already_done.act @@ -3,16 +3,18 @@ # # RTS coverage: # - Zero-waiter freeze: produce() is issued in main's __init__ turn and -# completes while nobody awaits: its $RDONE runs FREEZE_waiting on an -# empty waiter list (the wake loop iterates zero times) and the value must -# be retained on the frozen message. +# completes while nobody awaits: its $RDONE delivers the value into the +# envelope's future (m->$fut) and FREEZE_waiting(fut, FUT_VALUE) returns an +# empty waiter list (the wake loop iterates zero times). The envelope is +# consumed (DEQ_msg) but the value must be retained on the future, which +# lives on in x. # - Structural determinism: phase2's warm = b.produce() is a fresh sync # round trip; Prod's mailbox is FIFO (ENQ_msg tail-append), so warm # returning proves the original produce was consumed and frozen — under # any load, with no reliance on the 0.3s timer figure. # - Foreign frozen read: Rel's `await fut` inside consume takes the $RWAIT -# frozen-value fast arm: ADD_waiting finds the message frozen, the stored -# value is copied into Rel's parked frame, and Rel is immediately +# frozen-value fast arm: ADD_waiting declines (the future is already +# FUT_VALUE), x->value is copied into Rel's parked frame, and Rel is immediately # ENQ_readyd — no waiter registration, no involvement of the producer. # - Creator frozen read across turns: x lives in actor state (deactorized to # a main attribute); phase2 arrives via the timer path (ENQ_timed -> diff --git a/test/core_lang_auto/await_already_failed.act b/test/core_lang_auto/await_already_failed.act index c13179960..9a6f4b9a9 100644 --- a/test/core_lang_auto/await_already_failed.act +++ b/test/core_lang_auto/await_already_failed.act @@ -2,8 +2,9 @@ # kinds — plus the genuinely waiter-less failure and producer survival. # # RTS coverage: -# - Waiter-less failure: boom() raises with NO waiter registered: $RFAIL -# no-catcher arm freezes the message as an exception, the propagation loop +# - Waiter-less failure: boom() raises with NO waiter registered: the $RFAIL +# no-catcher arm delivers the exception into the envelope's future and +# freezes it (FREEZE_waiting(fut, FUT_EXCEPTION)); the propagation loop # iterates zero times, and — uniquely in this suite — the "Unhandled # exception" stderr notice prints (the branch taken only when # FREEZE_waiting returns an empty list). Prod then DEQ_msgs and continues @@ -13,9 +14,9 @@ # await runs, and asserts the producer still answers after an unhandled # failure. # - Frozen-exception reads: both Rel's `await fut` and main's own -# check_self() hit the $RWAIT frozen-exception fast arm: ADD_waiting finds -# the message frozen-exceptional, the parked frame's cont is set to -# $Fail$instance with the stored exception as value, and the awaiter is +# check_self() hit the $RWAIT frozen-exception fast arm: ADD_waiting +# declines (the future is already FUT_EXCEPTION), the parked frame's cont is +# set to $Fail$instance with fut->value (the exception), and the awaiter is # immediately ENQ_readyd. Resume runs $Fail$instance -> $R_FAIL -> # $RFAIL-with-catcher into the $PUSH_C catcher for the enclosing try -> # typed except -> -1. Without this test, the frozen-exception arm is diff --git a/test/core_lang_auto/await_chain.act b/test/core_lang_auto/await_chain.act index 454254195..f28f56df4 100644 --- a/test/core_lang_auto/await_chain.act +++ b/test/core_lang_auto/await_chain.act @@ -4,16 +4,18 @@ # # RTS coverage: # - Deterministic pending registration at every level: each sync call -# ($ASYNCf+$AWAITf -> $RWAIT) runs ADD_waiting BEFORE -# reverse_outgoing_queue/FLUSH_outgoing_local, so the caller is on the -# callee message's waiter list before the callee can possibly run: no -# interleaving reaches the frozen arms here. +# ($ASYNCf+$AWAITf -> $RWAIT) runs ADD_waiting on the call's future BEFORE +# FLUSH_outgoing_local delivers the buffered envelopes (reverse_outgoing_queue +# only restores program order first), so the caller is on the future's +# waiter list before the callee can possibly run: no interleaving reaches +# the frozen arms here. # - Simultaneous park chain: while Leaf computes, main->$waitsfor, # Top->$waitsfor and Mid->$waitsfor are all set; Top and Mid are each at -# once ON a waiter list (of their callee's message) and HOLDING a waiter -# list (on their own in-progress message) — the dual role an owner-local +# once ON a waiter list (of their callee call's future) and HOLDING a +# waiter list (on the future their own in-progress envelope fulfills) — the +# dual role an owner-local # waiter redesign must preserve. -# - Unwind: three $RDONE freeze+single-waiter-wake sequences in strict LIFO +# - Unwind: three $RDONE future-freeze+single-waiter-wake sequences in strict LIFO # order, each writing its value into the next parked frame's value slot # and ENQ_readying exactly one actor. The +1 per hop makes any # wrong-frame value write (cross-wiring) visible in the final sum. diff --git a/test/core_lang_auto/await_exc_escaped.act b/test/core_lang_auto/await_exc_escaped.act index c88d7610d..b11f83c09 100644 --- a/test/core_lang_auto/await_exc_escaped.act +++ b/test/core_lang_auto/await_exc_escaped.act @@ -5,8 +5,9 @@ # RTS coverage: # - Producer failure: boom()'s raise longjmps to the worker's jump buffer; # wt_work_cb's exceptional path converts it to $R_FAIL. Prod has no -# catcher, so the $RFAIL no-catcher arm runs: the message is frozen as an -# exception (FREEZE_waiting) and — because Rel IS registered — the waiter +# catcher, so the $RFAIL no-catcher arm runs: the exception is delivered +# into the envelope's future, which is frozen (FREEZE_waiting(fut, +# FUT_EXCEPTION)), and — because Rel IS registered — the waiter # propagation loop writes $Fail$instance into Rel's parked consume frame's # cont slot plus the exception as its value, clears $waitsfor, and # ENQ_readys Rel. A registered waiter suppresses the "Unhandled exception" diff --git a/test/core_lang_auto/await_exc_multi.act b/test/core_lang_auto/await_exc_multi.act index b556d70bc..b065571b8 100644 --- a/test/core_lang_auto/await_exc_multi.act +++ b/test/core_lang_auto/await_exc_multi.act @@ -1,13 +1,13 @@ # The $RFAIL waiter propagation loop with SEVERAL registered waiters: one -# failing message, three pending waiters, each woken with the exception +# failing call's future, three pending waiters, each woken with the exception # exactly once and each catching it independently. # # RTS coverage: # - Registration as in await_fan_in: trivial-init Waiters, go() fired async, # three ADD_waiting pending registrations building a 3-deep waiter chain -# on boom()'s message (spin margin keeps it unresolved). +# on boom()'s future (spin margin keeps it PENDING). # - Target path: boom() raises -> $R_FAIL -> $RFAIL no-catcher arm freezes -# the message as an exception and the propagation loop walks all three +# the future as FUT_EXCEPTION and the propagation loop walks all three # waiters, writing $Fail$instance + the exception into each parked go # frame and ENQ_readying each. This is the only test where that loop # iterates more than once. No "Unhandled exception" notice: waiters exist. diff --git a/test/core_lang_auto/await_fan_in.act b/test/core_lang_auto/await_fan_in.act index 95f6b6b95..9ff5f696d 100644 --- a/test/core_lang_auto/await_fan_in.act +++ b/test/core_lang_auto/await_fan_in.act @@ -1,4 +1,4 @@ -# The N-waiter wake loop: four actors registered on ONE unresolved message, +# The N-waiter wake loop: four actors registered on ONE pending future, # all woken by a single completion, each exactly once. # # RTS coverage: @@ -6,10 +6,10 @@ # __init__ (newact = $ASYNCf(init)+$AWAITf), so the inits are kept trivial # and go() is fired with `async`, letting all four go() turns run # concurrently. Each takes the $RWAIT pending arm: ADD_waiting pushes the -# waiter onto the message's singly-linked waiter list (linked through the -# waiters' own $next fields), guarded by the message's wait lock; the spin -# margin keeps produce unresolved throughout. -# - Target path: produce's $RDONE runs FREEZE_waiting once and the wake loop +# waiter onto the future's singly-linked waiter list (linked through the +# waiters' own $next fields), guarded by the future's $wait_lock; the spin +# margin keeps the future PENDING throughout. +# - Target path: produce's $RDONE freezes the future (FUT_VALUE) once and the wake loop # walks the 4-deep waiter chain: for each waiter it writes 42 into the # waiter's parked go frame, clears $waitsfor, and ENQ_readys it. This is # the only test where that loop iterates more than once for a value. diff --git a/test/core_lang_auto/await_fan_out.act b/test/core_lang_auto/await_fan_out.act index a3901705c..90480b946 100644 --- a/test/core_lang_auto/await_fan_out.act +++ b/test/core_lang_auto/await_fan_out.act @@ -1,18 +1,19 @@ # Per-future result routing: one actor with five outstanding futures must # get each producer's value delivered to the await of THAT future — the -# direct probe for cross-wiring in per-message waiter bookkeeping. +# direct probe for cross-wiring in per-future waiter bookkeeping. # # RTS coverage: -# - One turn issues five $ASYNCs (five messages PUSH_outgoing'd, restored +# - One turn issues five $ASYNCs (five envelopes PUSH_outgoing'd, restored # to program order by reverse_outgoing_queue, flushed to five different # producers at the first $RWAIT). -# - `await f4` is a same-turn await: its $RWAIT runs ADD_waiting before the -# flush, so it is a deterministic pending park and its wake comes from +# - `await f4` is a same-turn await: its $RWAIT registers on f4 before the +# flush delivers the envelopes, so it is a deterministic pending park and +# its wake comes from # b4's $RDONE single-waiter loop. # - The remaining awaits (f3..f0, reverse issue order) race their # producers: each independently resolves via EITHER the pending # park/wake OR the $RWAIT frozen-value fast arm. Both arms must key the -# value by message identity; the per-await assertions (v_i == i) catch a +# value by future identity; the per-await assertions (v_i == i) catch a # value delivered to the wrong await on either arm — a plain sum would be # permutation-invariant and mask exactly that swap. # - A lost completion parks main with $waitsfor set forever; the Watchdog diff --git a/test/core_lang_auto/await_mixed_outcomes.act b/test/core_lang_auto/await_mixed_outcomes.act index f8b2a4c21..61dabc7a3 100644 --- a/test/core_lang_auto/await_mixed_outcomes.act +++ b/test/core_lang_auto/await_mixed_outcomes.act @@ -1,22 +1,22 @@ # One producer, two outstanding futures with DIVERGENT outcomes: the -# exception stays keyed to bad()'s message and the value to good()'s, and +# exception stays keyed to bad()'s future and the value to good()'s, and # the producer keeps serving between them. # # RTS coverage: # - Prod's mailbox receives [bad, good] in program order (LIFO outgoing # buffer restored by reverse_outgoing_queue, ENQ_msg tail-append). -# - check_bad(h): a deterministic pending park (ADD_waiting on h's message -# precedes the flush). bad() raises -> $RFAIL no-catcher arm freezes h's -# message as an exception and the propagation loop writes $Fail$instance +# - check_bad(h): a deterministic pending park (ADD_waiting on the future h +# precedes the envelope flush). bad() raises -> $RFAIL no-catcher arm +# freezes h as FUT_EXCEPTION and the propagation loop writes $Fail$instance # + the exception into main's parked frame (waiter present, so no # "Unhandled exception" notice); main resumes through its $PUSH_C catcher # into the typed except -> -1. # - Producer survival on the $RFAIL path: after the failure Prod DEQ_msgs -# and runs good(), whose $RDONE freezes 21 onto g's message — good() +# and runs good(), whose $RDONE freezes 21 onto the future g — good() # delivering at all requires the failed actor to keep serving. # - check_good(g): main's resume races Prod's good() turn, so this await # exercises EITHER the pending park/wake or the $RWAIT frozen-value fast -# arm; both must key by message identity. Cross-contamination in either +# arm; both must key by future identity. Cross-contamination in either # direction (value 21 surfacing at h's await, or the ValueError at g's) # is converted by the sentinel excepts (-1 expected / -2 unexpected) into # a failed final comparison rather than an uncaught abort. diff --git a/test/core_lang_auto/await_queued_msgs.act b/test/core_lang_auto/await_queued_msgs.act index 9fd616460..4fa10c83b 100644 --- a/test/core_lang_auto/await_queued_msgs.act +++ b/test/core_lang_auto/await_queued_msgs.act @@ -7,7 +7,7 @@ # go() turn and flushed at the $RWAIT — FLUSH_outgoing_local ENQ_msgs # them onto main's OWN mailbox, tail-appended behind the parked __init__ # head frame. -# - Parked semantics: while main sits in $RWAIT on produce()'s message, +# - Parked semantics: while main sits in $RWAIT on produce()'s future, # those envelopes must not be dispatched (the mailbox head is only # advanced by DEQ_msg at $RDONE / final $RFAIL). The awaited-guard in # ping() converts any early execution — e.g. a control-queue rewrite diff --git a/test/core_lang_auto/await_relay.act b/test/core_lang_auto/await_relay.act index 1efde2476..811963b62 100644 --- a/test/core_lang_auto/await_relay.act +++ b/test/core_lang_auto/await_relay.act @@ -5,21 +5,23 @@ # # RTS coverage (rts.c wt_work_cb dispatch, q.c queues): # - Deterministic pending park of main: c.consume(x) lowers to -# $ASYNCf+$AWAITf -> $RWAIT, and ADD_waiting(main, consume_msg) runs -# BEFORE reverse_outgoing_queue/FLUSH_outgoing_local, so main is on the -# consume message's waiter list before Rel has even received it. +# $ASYNCf+$AWAITf -> $RWAIT, which registers main on the consume call's +# future (ADD_waiting) before FLUSH_outgoing_local delivers the buffered +# envelopes (reverse_outgoing_queue only restores program order first) — +# so main is on the future's waiter list before Rel has even received the +# consume envelope. # - Flush ordering: spin/produce/consume envelopes are PUSH_outgoing'd # (LIFO), restored to program order by reverse_outgoing_queue, and # tail-appended by ENQ_msg; spin keeps Prod's mailbox busy so produce runs # tens of ms later. # - Target path: Rel's `await fut` takes the $RWAIT pending arm -# (ADD_waiting under the wait lock finds the message unfrozen); produce's -# $RDONE then runs FREEZE_waiting (value) and the waiter wake loop, which +# (ADD_waiting under the future's $wait_lock finds it still PENDING); +# produce's $RDONE then freezes the future (FUT_VALUE) and the waiter wake loop # writes 42 into Rel's parked consume frame, clears Rel->$waitsfor, and # ENQ_ready(Rel) — all while main stays parked. Rel's consume $RDONE then # repeats freeze+wake with main as the sole waiter. # - Degraded arm (heavily loaded host, spin margin lost): Rel instead hits -# the $RWAIT frozen-value fast arm (stored value copied into the parked +# the $RWAIT frozen-value fast arm (the future's stored value copied into the parked # frame, immediate ENQ_ready) — still a pass; that arm is owned by # await_already_done. # - Watchdog is a separate never-parked actor because handle_timeout diff --git a/test/core_lang_auto/await_values.act b/test/core_lang_auto/await_values.act index 0f64aacd7..356cd363c 100644 --- a/test/core_lang_auto/await_values.act +++ b/test/core_lang_auto/await_values.act @@ -12,10 +12,11 @@ # itself — a rewrite that ships results as messages must not confuse a # None payload with "no result yet"; that confusion parks main at this # await and is bounded by the Watchdog actor. -# - Effect visibility: bump() and effects_seen() are tail-appended to -# Prod's FIFO mailbox across two successive parks of main, so -# effects_seen() must observe bump()'s write (n == 1) — mailbox FIFO -# ordering across await boundaries. +# - Effect visibility: effects_seen() must observe bump()'s write (n == 1). +# The guarantee is completion-before-wake: the $RDONE wake fires only +# after bump's turn (and its effect) completed, and main issues the +# effects_seen envelope only after that wake — the two envelopes are +# never both pending in Prod's mailbox. actor Watchdog(env): after 10.0: env.exit(1)