ANN Type check_exp_unary_spork(const Env env, const Stmt code);
+ANN static void fork_exp(const Env env, const Exp_Unary* unary) {
+ const Stmt stmt = new_stmt_exp(env->gwion->mp, ae_stmt_exp, unary->exp);
+ const Stmt_List list = new_stmt_list(env->gwion->mp, stmt, NULL);
+ const Stmt code = new_stmt_code(env->gwion->mp, list);
+ ((Exp_Unary*)unary)->exp = NULL;
+ ((Exp_Unary*)unary)->code = code;
+}
+
+ANN static Type fork_type(const Env env, const Exp_Unary* unary) {
+ const Type t = unary->exp->info->type;
+ fork_exp(env, unary);
+ if(t == env->gwion->type[et_void])
+ return env->gwion->type[et_fork];
+ Type_Decl td0 = { .xid=insert_symbol(t->name), .pos=exp_self(unary)->pos };
+ struct Type_List_ tl = { .td=&td0 };
+ Type_Decl td = { .xid=insert_symbol("TypedFork"), .types=&tl, .pos=exp_self(unary)->pos };
+ return known_type(env, &td);
+}
+
static OP_CHECK(opck_spork) {
const Exp_Unary* unary = (Exp_Unary*)data;
if(unary->exp && unary->exp->exp_type == ae_exp_call) {
const m_bool is_spork = unary->op == insert_symbol("spork");
- if(!is_spork) {
- const Stmt stmt = new_stmt_exp(env->gwion->mp, ae_stmt_exp, unary->exp);
- const Stmt_List list = new_stmt_list(env->gwion->mp, stmt, NULL);
- const Stmt code = new_stmt_code(env->gwion->mp, list);
- ((Exp_Unary*)unary)->exp = NULL;
- ((Exp_Unary*)unary)->code = code;
- }
- return env->gwion->type[is_spork ? et_shred : et_fork];
+ return is_spork ? env->gwion->type[et_shred] : fork_type(env, unary);
}
if(unary->code) {
++env->scope->depth;
#include "specialid.h"
#include "gwi.h"
-static m_int o_fork_thread, o_fork_cond, o_fork_mutex, o_shred_cancel, o_fork_done, o_fork_ev, o_fork_retsize, o_fork_ptr;
+static m_int o_fork_thread, o_fork_cond, o_fork_mutex, o_shred_cancel, o_fork_done, o_fork_ev, o_fork_retsize;
#define FORK_THREAD(o) *(THREAD_TYPE*)(o->data + o_fork_thread)
#define FORK_COND(o) *(THREAD_COND_TYPE*)(o->data + o_fork_cond)
#define FORK_MUTEX(o) *(MUTEX_TYPE*)(o->data + o_fork_mutex)
#define FORK_RETSIZE(o) *(m_int*)(o->data + o_fork_retsize)
-#define FORK_PTR(o) *(m_uint**)(o->data + o_fork_ptr)
VM_Shred new_shred_base(const VM_Shred shred, const VM_Code code) {
const VM_Shred sh = new_vm_shred(shred->info->mp, code);
vector_init(&parent->gwion->data->child2);
vector_add(&parent->gwion->data->child2, (vtype)ME(o)->info->vm->gwion);
REM_REF(ME(o)->code, ME(o)->info->vm->gwion);
- mp_free2(shred->info->vm->gwion->mp, FORK_RETSIZE(o), FORK_PTR(o));
MUTEX_UNLOCK(parent->shreduler->mutex);
}
vm_run(vm);
++vm->bbq->pos;
}
- memcpy(FORK_PTR(me), ME(me)->reg, FORK_RETSIZE(me));
+ memcpy(me->data + vm->gwion->type[et_fork]->nspc->info->offset, *(m_bit**)ME(me)->reg, FORK_RETSIZE(me));
gwion_end_child(ME(me), vm->gwion);
MUTEX_LOCK(vm->parent->shreduler->mutex);
*(m_int*)(me->data + o_fork_done) = 1;
ANN void fork_launch(const M_Object o, const m_uint sz) {
FORK_RETSIZE(o) = sz;
- FORK_PTR(o) = mp_calloc2(ME(o)->info->vm->gwion->mp, sz);
MUTEX_SETUP(FORK_MUTEX(o));
THREAD_COND_SETUP(FORK_COND(o));
struct ThreadLauncher tl = { .mutex=FORK_MUTEX(o), .cond=FORK_COND(o), .vm=ME(o)->info->vm };
GWI_BB((o_fork_ev = gwi_item_end(gwi, ae_flag_const, NULL)))
gwi_item_ini(gwi, "int", "retsize");
GWI_BB((o_fork_retsize = gwi_item_end(gwi, ae_flag_const, NULL)))
- gwi_item_ini(gwi, "@internal", "@ptr");
- GWI_BB((o_fork_ptr = gwi_item_end(gwi, ae_flag_const, NULL)))
gwi_func_ini(gwi, "void", "join");
GWI_BB(gwi_func_end(gwi, fork_join, ae_flag_none))
gwi_func_ini(gwi, "void", "test_cancel");
GWI_BB(gwi_func_end(gwi, fork_test_cancel, ae_flag_none))
GWI_BB(gwi_class_end(gwi))
SET_FLAG((t_fork), abstract);
+
+ const Type t_typed = gwi_class_ini(gwi, "<~A~>TypedFork", "Fork");
+ gwi_item_ini(gwi, "A", "retval");
+ GWI_BB((gwi_item_end(gwi, ae_flag_const, NULL)))
+ GWI_BB(gwi_class_end(gwi))
+ SET_FLAG((t_typed), abstract);
+
return GW_OK;
}