matrix:
allow_failures:
- - os: osx
+ - os: windows
compiler:
- gcc
--- /dev/null
+spork \ a { <<<a>>>;}(1);
+me.yield();
assert_leak() {
grep "All heap blocks were freed -- no leaks are possible" "$2.valgrind.log" > /dev/null && return 0
- [ "$suppressions" -eq 0 ] && echo "mem leak" > "$2.log" && return 1
+ #[ "$suppressions" -eq 0 ] && echo "mem leak" > "$2.log" && return 1
+ #[ -z "$suppressions" ] && echo "mem leak" > "$2.log" && return 1
heap=$(grep "in use at exit:" "$2.valgrind.log" | cut -d ":" -f2)
supp=$(grep "suppressed: .* bytes" "$2.valgrind.log" | cut -d ":" -f2)
+ #[ -z "$supp" ] && echo "mem leak" > "$2.log" && return 1
[ "$heap" = "$supp" ] && return 0
echo "mem leak" > "$2.log"
return 1
if [ "$VALGRIND" == "NO_VALGRIND" ]
then ./gwion "$GWOPT" -d "$DRIVER" "$file" > "$slog" 2>"$elog" |:
else
- "$VALGRIND" --log-file="$vlog" \
+ "$VALGRIND" --suppressions=supp --log-file="$vlog" \
./gwion "$GWOPT" -d "$DRIVER" "$file" > "$slog" 2>"$elog" |:
fi
ret=$?
VM* vm;
};
ANN m_bool gwion_ini(const Gwion, struct Arg_*);
+ANN VM* gwion_cpy(const VM*);
ANN void gwion_run(const Gwion gwion);
ANN void gwion_end(const Gwion gwion);
#endif
#define DLARG_MAX 6
typedef void (*f_xtor)(const M_Object o, const m_bit*, const VM_Shred);
-//typedef void (*f_xtor)(const M_Object o, const VM_Shred);
typedef void (*f_mfun)(const M_Object o, const m_bit* RETURN, const VM_Shred sh);
-//typedef void (*f_sfun)(const m_bit* RETURN, const VM_Shred sh);
typedef void (*f_sfun)(const m_bit*, const m_bit* RETURN, const VM_Shred sh);
typedef void (*f_xfun)();
typedef struct Gwi_* Gwi;
#define MFUN(a) ANN void a(const M_Object o __attribute__((unused)), const m_bit* RETURN __attribute__((unused)), const VM_Shred shred __attribute__((unused)))
#define SFUN(a) ANN void a(const M_Object o __attribute__((unused)), const m_bit* RETURN __attribute__((unused)), const VM_Shred shred __attribute__((unused)))
-//#define SFUN(a) ANN void a(const m_bit* mem __attribute__((unused)), const m_bit* RETURN
-//__attribute__((unused)), const VM_Shred shred __attribute__((unused)))
-#define CTOR(a) ANN void a(const M_Object o, const m_bit* _ __attribute__((unused)), const VM_Shred shred __attribute__((unused)))
-//#define CTOR(a) ANN void a(const M_Object o, const VM_Shred shred __attribute__((unused)))
-#define DTOR(a) ANN void a(const M_Object o, const m_bit* _ __attribute__((unused)), const VM_Shred shred __attribute__((unused)))
-//#define DTOR(a) ANN void a(const M_Object o, const VM_Shred shred __attribute__((unused)))
+#define CTOR(a) ANN void a(const M_Object o __attribute__((unused)), const m_bit* _ __attribute__((unused)), const VM_Shred shred __attribute__((unused)))
+#define DTOR(a) ANN void a(const M_Object o __attribute__((unused)), const m_bit* _ __attribute__((unused)), const VM_Shred shred __attribute__((unused)))
#define OP_CHECK(a) ANN Type a(const Env env __attribute__((unused)), void* data __attribute__((unused)))
#define OP_EMIT(a) ANN m_bool a(const Emitter emit __attribute__((unused)), void* data __attribute__((unused)))
#ifdef GWION_BUILTIN
OP_EMIT(opem_basic_cast);
OP_EMIT(opem_new);
-
-ANN /*static */ Type_List str2tl(const Env env, const m_str s, m_uint *depth);
-
+ANN Type_List str2tl(const Env env, const m_str s, m_uint *depth);
#endif
ANN ANEW M_Object new_array(const Type t, const m_uint length);
ANEW M_Object new_string(const VM_Shred, const m_str);
ANEW M_Object new_string2(const VM_Shred, const m_str);
-ANEW M_Object new_shred(const VM_Shred);
+ANEW M_Object new_shred(const VM_Shred, const m_bool);
+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);
ANN void broadcast(const M_Object);
eFuncUsrEnd,
eFuncMemberEnd,
eSporkIni,
+ eForkIni,
eSporkFunc,
eSporkThis,
eSporkExp,
+ eForkEnd,
eSporkEnd,
eBranchEqInt,
eBranchNeqInt,
#define FuncUsrEnd (f_instr)eFuncUsrEnd
#define FuncMemberEnd (f_instr)eFuncMemberEnd
#define SporkIni (f_instr)eSporkIni
+#define ForkIni (f_instr)eForkIni
#define SporkFunc (f_instr)eSporkFunc
#define SporkThis (f_instr)eSporkThis
#define SporkExp (f_instr)eSporkExp
+#define ForkEnd (f_instr)eForkEnd
#define SporkEnd (f_instr)eSporkEnd
#define BranchEqInt (f_instr)eBranchEqInt
#define BranchNeqInt (f_instr)eBranchNeqInt
ANN m_uint union_push(const Env, const Stmt_Union);
ANN void union_pop(const Env, const Stmt_Union, const m_uint);
+ANN m_bool check_stmt(const Env env, const Stmt stmt);
#endif
uint8_t in, out;
m_str arg;
};
+struct SoundInfo_ *soundinfo_cpy(const struct SoundInfo_ *src);
#endif
};
Type t_void, t_int, t_float, t_dur, t_time, t_now, t_complex, t_polar, t_vec3, t_vec4,
- t_null, t_object, t_shred, t_event, t_ugen, t_string, t_ptr, t_array, t_gack,
+ t_null, t_object, t_shred, t_fork, t_event, t_ugen, t_string, t_ptr, t_array, t_gack,
t_function, t_fptr, t_vararg, t_lambda, t_class, t_union;
ANN2(2) ANEW Type new_type(const m_uint xid, const m_str name, const Type);
FuncUsrEnd
FuncMemberEnd
SporkIni
+ForkIni
SporkFunc
SporkThis
SporkExp
+ForkEnd
SporkEnd
BranchEqInt
BranchNeqInt
return GW_OK;
}
-ANN2(1,2) static m_bool emit_exp_spork_finish(const Emitter emit, const VM_Code code,
- const m_uint depth, const m_bool f) {
- const Instr ini = emit_add_instr(emit, SporkIni);
- ini->m_val = (m_uint)code;
- if(!f) {
- const m_uint member = GET_FLAG(code, member) ? SZ_INT : 0;
- const Instr pop = emit_add_instr(emit, RegPop);
- pop->m_val = depth + member;
- if(depth) {
- const Instr spork = emit_add_instr(emit, SporkFunc);
- spork->m_val = depth;
- }
- if(member) {
- const Instr m = emit_add_instr(emit, SporkThis);
- m->m_val = depth;
- }
- } else {
- const Instr spork = emit_add_instr(emit, SporkExp);
+ANN2(1,2) static void emit_exp_spork_finish(const Emitter emit, const VM_Code code,
+ const m_uint depth) {
+ const m_uint member = GET_FLAG(code, member) ? SZ_INT : 0;
+ const Instr pop = emit_add_instr(emit, RegPop);
+ pop->m_val = depth + member;
+ if(depth) {
+ const Instr spork = emit_add_instr(emit, SporkFunc);
spork->m_val = depth;
}
- emit_add_instr(emit, SporkEnd);
- return GW_OK;
+ if(member) {
+ const Instr m = emit_add_instr(emit, SporkThis);
+ m->m_val = depth;
+ }
}
static inline void stack_alloc(const Emitter emit) {
}
#define SPORK_FUNC_PREFIX "spork~func:%i"
+#define FORK_FUNC_PREFIX "fork~func:%i"
#define SPORK_CODE_PREFIX "spork~code:%i"
+#define FORK_CODE_PREFIX "fork~code:%i"
static void push_spork_code(const Emitter emit, const m_str prefix, const int pos) {
char c[strlen(SPORK_FUNC_PREFIX) + num_digit(pos) + 1];
}
ANN static m_bool spork_func(const Emitter emit, const Exp_Call* exp) { GWDEBUG_EXE
- CHECK_BB(prepare_call(emit, exp))
- push_spork_code(emit, SPORK_FUNC_PREFIX, exp->self->pos);
if(GET_FLAG(exp->m_func, member))
SET_FLAG(emit->code, member);
if(exp->m_func->code) {
const Instr p = emit_add_instr(emit, PushStaticCode);
p->m_val = (m_uint)exp->m_func;
}
- CHECK_BB(emit_exp_call1(emit, exp->m_func))
- const VM_Code code = finalyze(emit);
- const m_uint size = exp->m_func->def->stack_depth - (GET_FLAG(exp->m_func,
- member) ? SZ_INT : 0);
- return emit_exp_spork_finish(emit, code, size, 0);
-}
-
-ANN static m_bool spork_code(const Emitter emit, const Stmt stmt) { GWDEBUG_EXE
- emit_add_instr(emit, RegPushImm);
- push_spork_code(emit, SPORK_CODE_PREFIX, stmt->pos);
- if(!SAFE_FLAG(emit->env->func, member))
- stack_alloc_this(emit);
- CHECK_BB(scoped_stmt(emit, stmt, 0))
- const VM_Code code = finalyze(emit);
- return emit_exp_spork_finish(emit, code, emit->code->stack_depth, 1);
+ return emit_exp_call1(emit, exp->m_func);
}
ANN m_bool emit_exp_spork(const Emitter emit, const Exp_Unary* unary) {
- return unary->code ? spork_code(emit, unary->code) :
- spork_func(emit, &unary->exp->d.exp_call);
+ const m_bool is_spork = unary->op == op_spork;
+ if(unary->code) {
+ emit_add_instr(emit, RegPushImm);
+ push_spork_code(emit, is_spork ? SPORK_CODE_PREFIX : FORK_CODE_PREFIX, unary->code->pos);
+ if(!SAFE_FLAG(emit->env->func, member))
+ stack_alloc_this(emit);
+ CHECK_BB(scoped_stmt(emit, unary->code, 0))
+ } else {
+ CHECK_BB(prepare_call(emit, &unary->exp->d.exp_call))
+ push_spork_code(emit, is_spork ? SPORK_FUNC_PREFIX : FORK_CODE_PREFIX, unary->exp->pos);
+ CHECK_BB(spork_func(emit, &unary->exp->d.exp_call))
+ }
+ const VM_Code code = finalyze(emit);
+ const Instr ini = emit_add_instr(emit, unary->op == op_spork ? SporkIni : ForkIni);
+ ini->m_val = (m_uint)code;
+ ini->m_val2 = is_spork;
+ if(unary->code) {
+ const Instr spork = emit_add_instr(emit, is_spork ? SporkExp : ForkEnd);
+ spork->m_val = emit->code->stack_depth;
+ emit_add_instr(emit, is_spork ? SporkEnd : ForkEnd);
+ } else {
+ const Func f = unary->exp->d.exp_call.m_func;
+ const m_uint size = f->def->stack_depth - (GET_FLAG(f, member) ? SZ_INT : 0);
+ emit_exp_spork_finish(emit, code, size);
+ const Instr end = emit_add_instr(emit, is_spork ? SporkEnd : ForkEnd);
+ end->m_val2 = unary->exp->d.exp_call.m_func->def->ret_type->size;
+ }
+ return GW_OK;
}
ANN static m_bool emit_exp_unary(const Emitter emit, const Exp_Unary* unary) { GWDEBUG_EXE
compile_filename(gwion, (m_str)vector_at(v, i));
}
+
+ANN VM* gwion_cpy(const VM* src) {
+ const Gwion gwion = mp_alloc(Gwion);
+ gwion->vm = new_vm();
+ gwion->vm->gwion = gwion;
+ gwion->vm->bbq->si = soundinfo_cpy(src->bbq->si);
+ gwion->emit = src->gwion->emit;
+ gwion->env = src->gwion->env;
+ return gwion->vm;
+}
ANN m_bool gwion_ini(const Gwion gwion, Arg* arg) {
gwion->vm = new_vm();
gwion->emit = new_emitter();
#include "nspc.h"
#include "operator.h"
#include "traverse.h"
+#include "parse.h"
ANN Type check_exp_call1(const Env env, const Exp_Call *exp);
ANN m_bool emit_exp_spork(const Emitter, const Exp_Unary*);
static OP_CHECK(opck_spork) {
const Exp_Unary* unary = (Exp_Unary*)data;
if(unary->exp && unary->exp->exp_type == ae_exp_call)
- return t_shred;
- else if(unary->code)
- return check_exp_unary_spork(env, unary->code);
- else
+ return unary->op == op_spork ? t_shred : t_fork;
+ else if(unary->code) {
+ CHECK_BO(check_stmt(env, unary->code))
+ return unary->op == op_spork ? t_shred : t_fork;
+ } else
ERR_O(unary->self->pos, "only function calls can be sporked...")
return NULL;
}
struct scope_iter iter = { &t->nspc->info->value, 0, 0 };\
Value v;
while(scope_iter(&iter, &v) > 0) {
- if(!GET_FLAG(v, static) && isa(v->type, t_object) > 0)
+ if(!GET_FLAG(v, static) && !GET_FLAG(v, pure) &&
+ isa(v->type, t_object) > 0)
release(*(M_Object*)(obj->data + v->offset), shred);
}
if(GET_FLAG(t, dtor)) {
#include <libgen.h>
#include "gwion_util.h"
#include "gwion_ast.h"
+#include "gwion_thread.h"
#include "oo.h"
#include "vm.h"
#include "env.h"
#include "instr.h"
#include "object.h"
#include "import.h"
+#include "shreduler_private.h"
+#include "gwion.h"
+
+static m_int o_fork_thread, o_fork_retsize, o_fork_retval;
+#define FORK_THREAD(o) *(THREAD_TYPE*)(o->data + o_fork_thread)
+#define FORK_RETSIZE(o) *(m_int*)(o->data + o_fork_retsize)
+#define FORK_RETVAL(o) (o->data + o_fork_retval)
-M_Object new_shred(const VM_Shred shred) {
- const M_Object obj = new_object(NULL, t_shred);
+M_Object new_shred(const VM_Shred shred, m_bool is_spork) {
+ const M_Object obj = new_object(NULL, is_spork ? t_shred : t_fork);
ME(obj) = shred;
+ if(!is_spork) {
+// *(M_Object*)(obj->data + o_fork_ev) = new_object(NULL, t_event);
+// EV_SHREDS(*(M_Object*)(obj->data + o_fork_ev)) = new_vector();
+ }
return obj;
}
const VM_Shred s = ME(o);
const Shreduler sh = shred->info->vm->shreduler;
shredule(sh, s, .5);
-// shred->mem += (m_bit*)o - shred->mem;
-// shred->mem -= SZ_INT;//!!!
}
-#include "shreduler_private.h"
+
static SFUN(vm_shred_from_id) {
const m_int index = *(m_int*)MEM(0);
const VM_Shred s = (VM_Shred)vector_at(&shred->info->vm->shreduler->shreds, (vtype)index);
if(s) {
*(M_Object*)RETURN = s->info->me;
- s->info->me->ref++;
- vector_add(&shred->gc, (vtype) s->info->me);
+// s->info->me->ref++;
+// vector_add(&shred->gc, (vtype) s->info->me);
} else
*(m_uint*)RETURN = 0;
}
describe_path_and_dir(, s->info->name)
describe_path_and_dir(_code, s->code->name)
+static DTOR(shred_dtor) { free_vm_shred(*(VM_Shred*)o->data); }
+
+static DTOR(fork_dtor) {
+ mp_free(Gwion, ME(o)->info->vm->gwion);
+ free_vm(ME(o)->info->vm);
+}
+
+static MFUN(fork_join) {
+ /* int pret = */ THREAD_JOIN(FORK_THREAD(o));
+ release(o, shred);
+}
+
+void fork_retval(const M_Object o) {
+ const m_uint sz = FORK_RETSIZE(o);
+ memcpy(FORK_RETVAL(o), ME(o)->reg - sz, sz);
+}
+
+static ANN void* fork_run(void* data) {
+ M_Object me = (M_Object)data;
+ VM *vm = ME(me)->info->vm;
+ vm_run(vm);
+ fork_retval(me);
+ THREAD_RETURN(NULL);
+}
+
+void fork_launch(const M_Object o, const m_uint sz) {
+ ++o->ref;
+ FORK_RETSIZE(o) = sz;
+ THREAD_CREATE(FORK_THREAD(o), fork_run, o);
+}
+
+#include "nspc.h"
GWION_IMPORT(shred) {
CHECK_OB((t_shred = gwi_mk_type(gwi, "Shred", SZ_INT, t_object)))
- CHECK_BB(gwi_class_ini(gwi, t_shred, NULL, NULL))
+ CHECK_BB(gwi_class_ini(gwi, t_shred, NULL, shred_dtor))
gwi_item_ini(gwi, "int", "@me");
CHECK_BB(gwi_item_end(gwi, ae_flag_member, NULL))
gwi_item_ini(gwi, "Shred", "me");
gwi_item_end(gwi, ae_flag_const, NULL);
SET_FLAG((t_shred), abstract);
+
+ CHECK_OB((t_fork = gwi_mk_type(gwi, "Fork", SZ_INT, t_shred)))
+ CHECK_BB(gwi_class_ini(gwi, t_fork, NULL, fork_dtor))
+ gwi_item_ini(gwi, "int", "@thread");
+ CHECK_BB((o_fork_thread = gwi_item_end(gwi, ae_flag_const, NULL)))
+ gwi_item_ini(gwi, "int", "retsize");
+ CHECK_BB((o_fork_retsize = gwi_item_end(gwi, ae_flag_const, NULL)))
+ o_fork_retval = t_fork->nspc->info->offset;
+ CHECK_BB(gwi_union_ini(gwi, NULL))
+ CHECK_BB(gwi_union_add(gwi, "int", "i"))
+ CHECK_BB(gwi_union_add(gwi, "float", "f"))
+ CHECK_BB(gwi_union_add(gwi, "Vec3", "v"))
+ CHECK_BB(gwi_union_add(gwi, "Vec4", "w"))
+ CHECK_BB(gwi_union_add(gwi, "VarObject", "o"))
+ CHECK_BB(gwi_union_end(gwi, ae_flag_const))
+ gwi_func_ini(gwi, "int", "join", fork_join);
+ CHECK_BB(gwi_func_end(gwi, 0))
+ CHECK_BB(gwi_class_end(gwi))
+ SET_FLAG((t_fork), abstract);
return GW_OK;
}
return op_ret;
ANN static Type check_exp(const Env env, Exp exp);
-ANN static m_bool check_stmt(const Env env, const Stmt stmt);
ANN static m_bool check_stmt_list(const Env env, Stmt_List list);
ANN m_bool check_class_def(const Env env, const Class_Def class_def);
return check_exp_call1(env, exp);
}
-ANN static inline m_bool check_exp_unary_spork1(const Env env, const Stmt code) {
- RET_NSPC(check_stmt(env, code))
-}
-
-ANN Type check_exp_unary_spork(const Env env, const Stmt code) { GWDEBUG_EXE
- CHECK_BO(check_exp_unary_spork1(env, code))
- return t_shred;
-}
-
ANN static Type check_exp_unary(const Env env, const Exp_Unary* unary) { GWDEBUG_EXE
struct Op_Import opi = { .op=unary->op, .rhs=unary->exp ? check_exp(env, unary->exp) : NULL,
.data=(uintptr_t)unary };
if(isa(ret_type, t_null) > 0 &&
isa(env->func->def->ret_type, t_object) > 0)
return GW_OK;
- if(isa(ret_type, env->func->def->ret_type) < 0)
+ if(env->func->def->ret_type && isa(ret_type, env->func->def->ret_type) < 0)
ERR_B(stmt->self->pos, "invalid return type '%s' -- expecting '%s'",
ret_type->name, env->func->def->ret_type->name)
+ else //! set defulat return type for lambdas
+ env->func->def->ret_type = ret_type;
return GW_OK;
}
Decl_List l = stmt->l;
do {
CHECK_OB(check_exp(env, l->self))
- if(isa(l->self->type, t_object) > 0 && !GET_FLAG(l->self->d.exp_decl.td, ref))
+ if(isa(l->self->type, t_object) > 0) {
+ if(!GET_FLAG(l->self->d.exp_decl.td, ref))
ERR_B(l->self->pos, "In union, Objects must be declared as reference (use '@')")
+ Var_Decl_List list = l->self->d.exp_decl.list;
+ do SET_FLAG(list->self->value, pure);
+ while((list = list->next));
+ }
if(l->self->type->size > stmt->s)
stmt->s = l->self->type->size;
} while((l = l->next));
(_exp_func)dummy_func, (_exp_func)check_stmt_type, (_exp_func)check_stmt_union,
};
-ANN static m_bool check_stmt(const Env env, const Stmt stmt) { GWDEBUG_EXE
+ANN m_bool check_stmt(const Env env, const Stmt stmt) { GWDEBUG_EXE
return stmt_func[stmt->stmt_type](env, &stmt->d);
}
--- /dev/null
+#include <gwion_util.h>
+#include <soundinfo.h>
+
+struct SoundInfo_ *new_soundinfo(void) {
+ struct SoundInfo_ *si = mp_alloc(SoundInfo);
+ si->in = si->out = 2;
+ si->sr = 48000;
+ return si;
+}
+
+struct SoundInfo_ *soundinfo_cpy(const struct SoundInfo_ *src) {
+ struct SoundInfo_ *si = mp_alloc(SoundInfo);
+ si->in = src->in;
+ si->out = src->out;
+ si->sr = src->sr;
+ return si;
+}
}
}
-ANN static void shreduler_child(const Shreduler s, const Vector v) {
+ANN static void shreduler_child(const Vector v) {
for(m_uint i = vector_size(v) + 1; --i;) {
const VM_Shred child = (VM_Shred)vector_at(v, i - 1);
unwind(child);
- shreduler_remove(s, child, 1);
+ shreduler_remove(child->info->vm->shreduler, child, 1);
}
}
if(tk->parent)
shreduler_parent(tk->self, &tk->parent->child);
if(tk->child.ptr)
- shreduler_child(s, &tk->child);
+ shreduler_child(&tk->child);
vector_rem2(&s->shreds, (vtype)tk->self);
}
tk->prev = tk->next = NULL;
if(erase) {
shreduler_erase(s, tk);
- free_vm_shred(out);
+ _release(out->info->me, out);
}
}
ANN m_uint vm_add_shred(const VM* vm, const VM_Shred shred) {
shred->info->vm = (VM*)vm;
- shred->info->me = new_shred(shred);
+ shred->info->me = new_shred(shred, 1);
shreduler_add(vm->shreduler, shred);
shredule(vm->shreduler, shred, .5);
return shred->tick->xid;
}
+#include "gwion.h"
+static int n;
+ANN m_uint vm_fork(const VM* src, const VM_Shred shred) {
+ VM* vm = shred->info->vm = gwion_cpy(src);
+ shred->info->me = new_shred(shred, 0);
+ shreduler_add(vm->shreduler, shred);
+ shredule(vm->shreduler, shred, .5);
+shred->tick->xid += (n += 100);
+ return shred->tick->xid;
+}
__attribute__((hot))
ANN static inline void vm_ugen_init(const VM* vm) {
return mem > (((m_bit*)c + sizeof(struct VM_Shred_) + SIZEOF_REG) + (SIZEOF_MEM) - (MEM_STEP));
}
-ANN static inline VM_Shred init_spork_shred(const VM_Shred shred, const VM_Code code) {
+ANN static inline VM_Shred init_spork_shred(const VM_Shred shred, const Instr instr) {
+ const VM_Code code = (VM_Code)instr->m_val;
const VM_Shred sh = new_vm_shred(code);
ADD_REF(code)
sh->tick->parent = shred->tick;
vector_init(&shred->tick->child);
vector_add(&shred->tick->child, (vtype)sh);
sh->base = shred->base;
- vm_add_shred(shred->info->vm, sh);
+ return sh;
+}
+
+ANN static inline VM_Shred init_fork_shred(const VM_Shred shred, const Instr instr) {
+ const VM_Code code = (VM_Code)instr->m_val;
+ const VM_Shred sh = new_vm_shred(code);
+ ADD_REF(code)
+ sh->base = shred->base;
return sh;
}
&&timeadv,
&&setcode, &&funcptr, &&funcmember,
&&funcusr, &®pop, &®tomem, &&overflow, &&next, &&funcusrend, &&funcmemberend,
- &&sporkini, &&sporkfunc, &&sporkthis, &&sporkexp, &&sporkend,
+ &&sporkini, &&sporkini, &&sporkfunc, &&sporkthis, &&sporkexp, &&forkend, &&sporkend,
&&brancheqint, &&branchneint, &&brancheqfloat, &&branchnefloat,
&&decintaddr, &&initloop,
&&arraytop, &&newobj,
pc = shred->pc;
DISPATCH()
sporkini:
- a.child = init_spork_shred(shred, (VM_Code)instr->m_val);
+ a.child = (instr->m_val2 ? init_spork_shred : init_fork_shred)(shred, instr);
+ if(instr->m_val2)
+ vm_add_shred(vm, a.child);
+ else
+ vm_fork(vm, a.child);
DISPATCH()
sporkfunc:
// LOOP_OPTIM
for(m_uint i = 0; i < instr->m_val; i+= SZ_INT)
*(m_uint*)(a.child->mem + i) = *(m_uint*)(mem+i);
DISPATCH()
+forkend:
+ fork_launch(a.child->info->me, instr->m_val2);
sporkend:
*(M_Object*)(reg-SZ_INT) = a.child->info->me;
DISPATCH()
ANN static void free_code_instr(const Vector v) {
for(m_uint i = vector_size(v) + 1; --i;) {
const Instr instr = (Instr)vector_at(v, i - 1);
- if(instr->opcode == (m_uint)SporkIni)
+ if(instr->opcode == eSporkIni || instr->opcode == eForkIni)
REM_REF((VM_Code)instr->m_val)
else if(instr->execute == ArrayAlloc)
free_array_info((ArrayInfo*)instr->m_val);
else if(instr->execute == SwitchIni) {
free_vector((Vector)instr->m_val);
free_map((Map)instr->m_val2);
- } else if(instr->opcode == (m_uint)InitLoopCounter)
+ } else if(instr->opcode == eInitLoopCounter)
free((m_int*)instr->m_val);
else if(instr->execute == VarargIni) {
if(instr->m_val2)
--- /dev/null
+fork \a b { <<<me.id(), " fork ", a, " " , b>>>; return 9; }(1, 2)
+@=> Fork @e;
+fork \a b { <<<me.id(), " fork ", a, " " , b>>>; }(1, 2) @=> Fork @f;
+//fork \a b { <<<me.id(), " fork ", a, " " , b>>>; }(1, 2) @=> Fork @g;
+//fork \a { <<<me.id(), " ", a>>>; }(1) @=> Fork @h;
+
+<<<"before wait">>>;
+e.join();
+f.join();
+//g.join();
+//h.join();
+<<<e.i>>>;
+<<<"after wait">>>;
+<<<me>>>;
-Subproject commit b846edc401451e7291655a03940094550a339551
+Subproject commit a25a0c0e88bfdf69041c658ff14f7992d78ddcb4