if (v->from->filename) // TODO: check why is that from check
gwerr_secondary(_("defined here"), v->from->filename, v->from->loc);
}
+
+ANN static inline void valid_value(const Env env, const Symbol xid, const Value v) {
+ set_vflag(v, vflag_valid);
+ nspc_add_value(env->curr, xid, v);
+}
#endif
eSporkFunc,
eSporkMemberFptr,
eSporkExp,
+ eSporkCode,
+ eForkEnd,
eSporkEnd,
eBranchEqInt,
eBranchNeqInt,
#define SporkFunc (f_instr)eSporkFunc
#define SporkMemberFptr (f_instr)eSporkMemberFptr
#define SporkExp (f_instr)eSporkExp
+#define SporkCode (f_instr)eSporkCode
+#define ForkEnd (f_instr)eForkEnd
#define SporkEnd (f_instr)eSporkEnd
#define BranchEqInt (f_instr)eBranchEqInt
#define BranchNeqInt (f_instr)eBranchNeqInt
gw_out(" {-R}%-14"UINT_F"{0}", instr->m_val);
gw_out("\n");
break;
+ case eSporkCode:
+ gw_out("{Y}┃{0}{-}% 4lu{0}: SporkCode ", j);
+ gw_out(" {-R}%-14"UINT_F"{0}", instr->m_val);
+ gw_out("\n");
+ break;
+ case eForkEnd:
+ gw_out("{Y}┃{0}{-}% 4lu{0}: ForkEnd ", j);
+ gw_out("\n");
+ break;
case eSporkEnd:
gw_out("{Y}┃{0}{-}% 4lu{0}: SporkEnd ", j);
gw_out("\n");
SporkFunc
SporkMemberFptr~u
SporkExp~u
+SporkCode~u
+ForkEnd
SporkEnd
BranchEqInt~pc
BranchNeqInt~pc
const Exp exp;
VM_Code vm_code;
const Type type;
+ const Capture_List captures;
const bool emit_var;
const bool is_spork;
};
ANN void spork_code(const Emitter emit, const struct Sporker *sp) {
const Instr args = emit_add_instr(emit, SporkExp);
args->m_val = emit->code->stack_depth;
- const Instr instr = emit_add_instr(emit, SporkEnd);
+ const Instr instr = emit_add_instr(emit, sp->is_spork ? SporkEnd : ForkEnd);
instr->m_val = sp->emit_var;
}
.exp = unary->unary_type == unary_exp ? unary->exp : NULL,
.code = unary->unary_type == unary_code ? unary->code : NULL,
.type = exp_self(unary)->type,
+ .captures = unary->captures,
.is_spork = (unary->op == insert_symbol("spork")),
.emit_var = exp_getvar(exp_self(unary))};
CHECK_OB((sporker.vm_code = spork_prepare(emit, &sporker)));
if(!sporker.is_spork)
emit_local_exp(emit, exp_self(unary));
spork_ini(emit, &sporker);
+
+if(sporker.captures) {
+ Capture_List caps = sporker.captures;
+// what about types?
+ uint32_t offset = 0;
+ for (uint32_t i = 0; i < caps->len; i++) {
+ Capture *cap = mp_vector_at(caps, Capture, i);
+ const Value v = nspc_lookup_value1(emit->env->curr, cap->xid);
+ struct Exp_ exp = {
+ .d = { .prim = {
+ .d = { .var = cap->xid },
+ .value = v,
+ .prim_type = ae_prim_id
+ }},
+ .type = v->type,
+ .exp_type = ae_exp_primary
+ };
+// handle emit var?
+//exp_setvar(&exp, false);
+ emit_exp(emit, &exp);
+ }
+// pop_exp(emit, &exp);
+regpop(emit, SZ_INT);
+ const Instr args = emit_add_instr(emit, SporkCode);
+ args->m_val = 8; //emit->code->stack_depth;
+ }
+
+// emit_local_exp(emit, exp_self(unary));
(unary->unary_type == unary_code ? spork_code : spork_func)(emit, &sporker);
return GW_OK;
}
loop_idx->m_val = key_offset;
loop_idx->m_val2 = -1;
stmt->v->from->offset = val_offset;
+//value_addref(stmt->v);
+nspc_add_value(emit->env->curr, stmt->sym, stmt->v);
emit_debug(emit, stmt->v);
if (stmt->idx) {
stmt->idx->v->from->offset = key_offset;
- emit_debug(emit, stmt->v);
+nspc_add_value(emit->env->curr, stmt->idx->sym, stmt->idx->v);
+//value_addref(stmt->idx->v);
+ emit_debug(emit, stmt->idx->v);
}
struct Looper loop = {.exp = stmt->exp,
.stmt = stmt->body,
const Type et = exp->type;
DECL_OO(Type, base, = typedef_base(et));
DECL_OO(const Type, t, = array_base_simple(base));
- const m_uint depth = base->array_depth - 1;
- return depth ? array_type(env, t, depth) : t;
+ if(!tflag(base, tflag_ref)) {
+ const m_uint depth = base->array_depth - 1;
+ return depth ? array_type(env, t, depth) : t;
+ }
+ const Type inner = (Type)vector_front(&base->info->tuple->contains);
+ const Type refbase = array_base_simple(inner);
+ const m_uint depth = inner->array_depth - 1;
+ return depth ? array_type(env, refbase, depth) : refbase;
}
// rewrite me
instr->m_val2 = -SZ_INT;
return ret;
}
-
-ANN Type check_exp_unary_spork(const Env env, const Stmt code);
-
+/*
ANN static void fork_exp(const Env env, const Exp_Unary *unary) {
Stmt_List slist = new_mp_vector(env->gwion->mp, sizeof(struct Stmt_), 1);
mp_vector_set(slist, struct Stmt_, 0,
((Exp_Unary *)unary)->code = code;
((Exp_Unary *)unary)->unary_type = unary_code;
}
-
+*/
ANN static Type fork_type(const Env env, const Exp_Unary *unary) {
const Type t = unary->exp->type;
- fork_exp(env, unary);
+// fork_exp(env, unary);
if (t == env->gwion->type[et_void]) return env->gwion->type[et_fork];
char c[21 + strlen(t->name)];
sprintf(c, "TypedFork:[%s]", t->name);
return ret;
}
+ANN Type upvalue_type(const Env env, Capture *cap) {
+ const Value v = nspc_lookup_value1(env->curr, cap->xid);
+ if(!v)exit(3);
+ if(cap->is_ref && not_upvalue(env, v))
+ ERR_O(cap->pos, _("can't take ref of a scoped value"));
+ cap->v = v;
+ const Type base_type = !tflag(v->type, tflag_ref) ? v->type : (Type)vector_front(&v->type->info->tuple->contains);
+ return !cap->is_ref ? base_type : ref_type(env->gwion, base_type, cap->pos);
+}
+
static OP_CHECK(opck_spork) {
const Exp_Unary *unary = (Exp_Unary *)data;
if (unary->unary_type == unary_exp && unary->exp->exp_type == ae_exp_call) {
return is_spork ? env->gwion->type[et_shred] : fork_type(env, unary);
}
if (unary->unary_type == unary_code) {
+ if(unary->captures) {
+ uint32_t offset = 0;
+ for(uint32_t i = 0; i < unary->captures->len; i++) {
+ Capture *const cap = mp_vector_at(unary->captures, Capture, i);
+ DECL_OO(const Type, t, = upvalue_type(env, cap));
+ cap->v = new_value(env->gwion->mp, t, s_name(cap->xid));
+ cap->v->from->offset = offset;
+ offset += cap->v->type->size;
+ }
+ }
++env->scope->depth;
- nspc_push_value(env->gwion->mp, env->curr);
+ const Scope scope = env->curr->info->value;
+ env->curr->info->value = new_scope(env->gwion->mp);
+ if(unary->captures) {
+ for(uint32_t i = 0; i < unary->captures->len; i++) {
+ Capture *const cap = mp_vector_at(unary->captures, Capture, i);
+ valid_value(env, cap->xid, cap->v);
+ }
+ }
+ const Func f = env->func;
+ struct Value_ value = {};
+ set_vflag(&value, vflag_member);
+ struct Func_Base_ fbase = { .xid=insert_symbol("in spork"), .values = scope};
+ struct Func_Def_ fdef = { .base = &fbase};
+ struct Func_ func = { .name = "in spork", .def = &fdef, .value_ref = &value};
+ env->func = &func;
const m_bool ret = check_stmt(env, unary->code);
- nspc_pop_value(env->gwion->mp, env->curr);
+ env->func = f;
+ free_scope(env->gwion->mp, env->curr->info->value);
+ env->curr->info->value = scope;
--env->scope->depth;
CHECK_BN(ret);
return env->gwion
return GW_OK;
}
-ANN static inline void valid_value(const Env env, const Symbol xid, const Value v) {
- set_vflag(v, vflag_valid);
- nspc_add_value(env->curr, xid, v);
-}
-
ANN static m_bool check_decl(const Env env, const Exp_Decl *decl) {
Var_Decl_List list = decl->list;
for(uint32_t i = 0; i < list->len; i++) {
prim_self(data)->value = env->gwion->type[et_op]->info->value;
return env->gwion->type[et_op];
}
- gwerr_basic(_("Invalid variable"), _("not legit at this point."), NULL,
+ const m_str hint = (!env->func || strcmp(env->func->name, "in spork")) ?
+ NULL : "vapturelist?";
+ gwerr_basic(_("Invalid variable"), _("not legit at this point."), hint,
env->name, prim_pos(data), 0);
did_you_mean_nspc(v ? value_owner(env, v) : env->curr, s_name(sym));
env_set_error(env);
func->def->base->ret_type : exp->func->d.exp_dot.base->type;
}
+ANN Type upvalue_type(const Env env, Capture *cap);
ANN static Type check_lambda_call(const Env env, Exp_Call *const exp) {
const Func_Def fdef = exp->func->d.exp_lambda.def;
if (exp->args) {
fdef->base->args = new_mp_vector(env->gwion->mp, sizeof(Arg), 0);
for(uint32_t i = 0; i < fdef->captures->len; i++) {
Capture *const cap = mp_vector_at(fdef->captures, Capture, i);
- const Value v = nspc_lookup_value1(env->curr, cap->xid);
- if(!v)exit(3);
- if(cap->is_ref && not_upvalue(env, v))
- ERR_O(cap->pos, _("can't take ref of a scoped value"));
- cap->v = v;
- const Type base_type = !tflag(v->type, tflag_ref) ? v->type : (Type)vector_front(&v->type->info->tuple->contains);
- const Type t = !cap->is_ref ? base_type : ref_type(env->gwion, base_type, cap->pos);
+ DECL_OO(const Type, t, = upvalue_type(env, cap)); // could leak
Arg arg = {
.td = type2td(env->gwion, t, exp->func->pos),
.var_decl = { .xid = cap->xid }
ANN static inline m_bool scan1_exp_unary(const restrict Env env,
Exp_Unary *const unary) {
if (unary->unary_type == unary_code) {
+if(strcmp("fork", s_name(unary->op))) {
const loc_t pos = exp_self(unary)->pos;
const Symbol sym = lambda_name(env->gwion->st, pos.first);
Exp lambda = new_exp_lambda(env->gwion->mp, sym, NULL, unary->code, pos);
mp_free(env->gwion->mp, Stmt, unary->code);
unary->exp = new_exp_call(env->gwion->mp, lambda, NULL, pos);
unary->unary_type = unary_exp;
+} else {
+return scan1_stmt(env, unary->code);
+}
+
}
return unary->unary_type == unary_exp ? scan1_exp(env, unary->exp) : GW_OK;
}
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);
return ME(o);
}
&®tomem, &®tomemother,
&&overflow,
&&funcusrend, &&funcusrend2, &&funcmemberend,
- &&sporkini, &&forkini, &&sporkfunc, &&sporkmemberfptr, &&sporkexp,
- &&sporkend, &&brancheqint, &&branchneint, &&brancheqfloat,
+ &&sporkini, &&forkini, &&sporkfunc, &&sporkmemberfptr, &&sporkexp, &&sporkcode,
+ &&forkend, &&sporkend, &&brancheqint, &&branchneint, &&brancheqfloat,
&&branchnefloat, &&unroll, &&arrayappend, &&autounrollinit, &&autoloop,
&&arraytop, &&arrayaccess, &&arrayget, &&arrayaddr, &&newobj, &&addref,
&&addrefaddr, &&structaddref, &&structaddrefaddr, &&objassign, &&assign,
regpushmemaddr:
*(m_bit **)reg = &*(m_bit *)(mem + IVAL);
reg += SZ_INT;
- DISPATCH()
+ DISPATCH();
regpushmemderef:
memcpy(reg, *(m_bit **)(mem + IVAL), VAL2);
reg += VAL2;
for (m_uint i = 0; i < VAL; i += SZ_INT)
*(m_uint *)(child->mem + i) = *(m_uint *)(mem + i);
DISPATCH()
+ sporkcode:
+ // LOOP_OPTIM
+ for (m_uint i = 0; i < VAL; i += SZ_INT)
+ *(m_uint *)(child->mem + i) = *(m_uint *)(reg + i);
+ DISPATCH()
+ forkend:
+ fork_launch(child->info->me);
sporkend:
assert(!VAL); // spork are not mutable
*(M_Object *)(reg - SZ_INT) = child->info->me;
&&_regtomem, &&_regtomemother,
&&_overflow,
&&_funcusrend, &&_funcusrend2, &&_funcmemberend,
- &&_sporkini, &&_forkini, &&_sporkfunc, &&_sporkmemberfptr, &&_sporkexp,
+ &&_sporkini, &&_forkini, &&_sporkfunc, &&_sporkmemberfptr, &&_sporkexp, &&_sporkcode, &&_forkend,
&&_sporkend, &&_brancheqint, &&_branchneint, &&_brancheqfloat,
&&_branchnefloat, &&_unroll, &&_arrayappend, &&_autounrollinit, &&_autoloop,
&&_arraytop, &&_arrayaccess, &&_arrayget, &&_arrayaddr, &&_newobj, &&_addref,
PREPARE(sporkfunc);
PREPARE(sporkmemberfptr);
PREPARE(sporkexp);
+ PREPARE(sporkcode);
+ PREPARE(forkend);
PREPARE(sporkend);
PREPARE(brancheqint);
PREPARE(branchneint);