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)