]> Nishi Git Mirror - gwion.git/commitdiff
:art: Introduce TypedSpork
authorJérémie Astor <astor.jeremie@wanadoo.fr>
Thu, 10 Sep 2020 19:12:49 +0000 (21:12 +0200)
committerJérémie Astor <astor.jeremie@wanadoo.fr>
Thu, 10 Sep 2020 19:12:49 +0000 (21:12 +0200)
src/emit/emit.c
src/lib/func.c
src/lib/shred.c
tests/fork/fork_call.gw [new file with mode: 0644]

index dcb4b58094864aa3d251ded124099ddd79ecde08..0329cd1d397dd812eae6465259dd4657831c42e7 100644 (file)
@@ -1245,7 +1245,7 @@ ANN static Instr spork_ini(const Emitter emit, const struct Sporker *sp) {
   const Func f = !sp->code ? sp->exp->d.exp_call.m_func : NULL;
   const Instr instr = emit_add_instr(emit, ForkIni);
   instr->m_val = (m_uint)sp->vm_code;
-  instr->m_val2 = f ? f->def->base->ret_type->size : 0;
+  instr->m_val2 = f ? sp->type->size : 0;
   return instr;
 }
 
index e1f3479b89a97f6c76b524cbae578279364a40b8..da0f858665b88d5fcc5f4bcf7b49044e063a8f71 100644 (file)
@@ -288,18 +288,30 @@ static OP_EMIT(opem_fptr_impl) {
 
 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;
index 1c067f237d16d31dbe95f69fc32e2ac129ddaa6d..33dadda8370fce5325f46a56e18713dc4cf8d51f 100644 (file)
 #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);
@@ -199,7 +198,6 @@ static DTOR(fork_dtor) {
     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);
 }
 
@@ -263,7 +261,7 @@ struct ThreadLauncher *tl = data;
     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;
@@ -275,7 +273,6 @@ struct ThreadLauncher *tl = data;
 
 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 };
@@ -399,13 +396,18 @@ GWION_IMPORT(shred) {
   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;
 }
diff --git a/tests/fork/fork_call.gw b/tests/fork/fork_call.gw
new file mode 100644 (file)
index 0000000..9f01711
--- /dev/null
@@ -0,0 +1,9 @@
+#! fork me.id() @=> auto ref sh;
+fun int test() {
+  return 12;
+}
+
+fork test() @=> <~int~>TypedFork ref sh;
+<<< typeof(sh) >>>;
+sh.ev => now;
+<<< sh.retval >>>;