ANN ANEW M_Object new_array(MemPool, const Type t, const m_uint length);
ANEW M_Object new_string(MemPool, const VM_Shred, const m_str);
ANEW M_Object new_string2(const struct Gwion_*, const VM_Shred, const m_str);
-ANEW M_Object new_shred(const VM_Shred, const m_bool);
+ANEW M_Object new_shred(const VM_Shred);
ANN void fork_launch(const M_Object, const m_uint);
ANN void __release(const M_Object, const VM_Shred);
ANN void exception(const VM_Shred, const m_str);
const Stmt code;
const Exp exp;
VM_Code vm_code;
+ const Type type;
const m_bool emit_var;
const m_bool is_spork;
};
instr->m_val2 = sp->is_spork;
return instr;
}
+ regpushi(emit, (m_uint)sp->type);
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;
struct Sporker sporker = {
.exp=unary->exp,
.code=unary->code,
+ .type=exp_self(unary)->info->type,
.is_spork=(unary->op == insert_symbol("spork")),
.emit_var=exp_getvar(exp_self(unary))
};
static OP_EMIT(opem_spork) {
const Exp_Unary* unary = (Exp_Unary*)data;
- const Env env = emit->env;
- const Instr ret = emit_exp_spork(emit, unary);
- if(unary->op == insert_symbol("fork"))
- emit_add_instr(emit, GcAdd);
- return ret;
+ return emit_exp_spork(emit, unary);
}
static FREEARG(freearg_xork) {
return sh;
}
-M_Object new_shred(const VM_Shred shred, m_bool is_spork) {
+M_Object new_shred(const VM_Shred shred) {
const M_Object obj = new_object(shred->info->mp, NULL,
- shred->info->vm->gwion->type[is_spork ? et_shred :et_fork]);
+ shred->info->vm->gwion->type[et_shred]);
ME(obj) = shred;
- if(!is_spork) {
- *(M_Object*)(obj->data + o_fork_ev) = new_object(shred->info->mp, NULL, shred->info->vm->gwion->type[et_event]);
- EV_SHREDS(*(M_Object*)(obj->data + o_fork_ev)) = new_vector(shred->info->mp);
- }
return obj;
}
+ANN static inline M_Object fork_object(const VM_Shred shred, const Type t) {
+ const Gwion gwion = shred->info->vm->gwion;
+ const M_Object o = new_object(gwion->mp, shred, t);
+ *(M_Object*)(o->data + o_fork_ev) = new_object(gwion->mp, NULL, gwion->type[et_event]);
+ EV_SHREDS(*(M_Object*)(o->data + o_fork_ev)) = new_vector(gwion->mp);
+ return o;
+}
+
+ANN M_Object new_fork(const VM_Shred shred, const VM_Code code, const Type t) {
+ VM* parent = shred->info->vm;
+ const VM_Shred sh = new_shred_base(shred, code);
+ VM* vm = (sh->info->vm = gwion_cpy(parent));
+ vm->parent = parent;
+ const M_Object o = sh->info->me = fork_object(shred, t);
+ ME(o) = sh;
+ ++o->ref;
+ shreduler_add(vm->shreduler, sh);
+ return o;
+}
+
+
static MFUN(gw_shred_exit) {
const VM_Shred s = ME(o);
s->mem -= SZ_INT;
GWION_IMPORT(shred) {
const Type t_shred = gwi_class_ini(gwi, "Shred", NULL);
gwi_class_xtor(gwi, NULL, shred_dtor);
- gwi->gwion->type[et_shred] = t_shred;
gwi_item_ini(gwi, "@internal", "@me");
GWI_BB(gwi_item_end(gwi, ae_flag_const, NULL))
gwi_func_ini(gwi, "float", "get_now");
GWI_BB(gwi_func_end(gwi, shred_now, ae_flag_none))
GWI_BB(gwi_class_end(gwi))
+ gwi_set_global_type(gwi, t_shred, et_shred);
struct SpecialId_ spid = { .type=t_shred, .exec=RegPushMe, .is_const=1 };
gwi_specialid(gwi, "me", &spid);
ANN void vm_add_shred(const VM* vm, const VM_Shred shred) {
shred->info->vm = (VM*)vm;
- shred->info->me = new_shred(shred, 1);
+ shred->info->me = new_shred(shred);
shreduler_add(vm->shreduler, shred);
}
ANN void vm_ini_shred(const VM* vm, const VM_Shred shred) {
shred->info->vm = (VM*)vm;
- shred->info->me = new_shred(shred, 1);
+ shred->info->me = new_shred(shred);
shreduler_ini(vm->shreduler, shred);
}
return sh;
}
-ANN static VM_Shred init_fork_shred(const VM_Shred shred, const VM_Code code, const m_uint retsz) {
- VM* parent = shred->info->vm;
- const VM_Shred sh = new_shred_base(shred, code);
- VM* vm = (sh->info->vm = gwion_cpy(parent));
- vm->parent = parent;
- const M_Object o = sh->info->me = new_shred(sh, 0);
- ++sh->info->me->ref;
- if(!parent->gwion->data->child.ptr)
- vector_init(&parent->gwion->data->child);
- vector_add(&parent->gwion->data->child, (vtype)o);
- shreduler_add(vm->shreduler, sh);
- fork_launch(sh->info->me, retsz);
- return sh;
+ANN M_Object new_fork(const VM_Shred, const VM_Code code, const Type);
+ANN static VM_Shred init_fork_shred(const VM_Shred shred, const VM_Code code, const Type t, const m_uint retsz) {
+ const M_Object o = new_fork(shred, code, t);
+ VM* vm = shred->info->vm;
+ if(!vm->gwion->data->child.ptr)
+ vector_init(&vm->gwion->data->child);
+ vector_add(&vm->gwion->data->child, (vtype)o);
+ fork_launch(o, retsz);
+ return ME(o);
}
#define TEST0(t, pos) if(!*(t*)(reg-pos)){ shred->pc = PC; exception(shred, "ZeroDivideException"); break; }
child = init_spork_shred(shred, (VM_Code)VAL);
DISPATCH()
forkini:
- child = init_fork_shred(shred, (VM_Code)VAL, VAL2),
+ reg -= SZ_INT;
+ child = init_fork_shred(shred, (VM_Code)VAL, *(Type*)reg, VAL2),
DISPATCH()
sporkfunc:
// LOOP_OPTIM