ANN Type check_op_call(const Env env, Exp_Call *const exp);
ANN void builtin_func(const MemPool mp, const Func f, void *func_ptr);
-static inline Value upvalues_lookup(const Upvalues *upvalues, const Symbol sym) {
+ANN static inline Value upvalues_lookup(const Upvalues *upvalues, const Symbol sym) {
const Value v = (Value)scope_lookup1(upvalues->values, (m_uint)sym);
if(v) return v;
return upvalues->parent ? upvalues_lookup(upvalues->parent, sym) : NULL;
}
+
+ANN static inline m_uint captures_sz(const Capture_List captures) {
+ const Capture *cap = mp_vector_at(captures, Capture, (captures->len - 1));
+ return cap->new->from->offset + cap->new->type->size;
+}
#endif
eDotStatic,
eDotStatic2,
eDotStatic3,
- eUpvalueInt,
- eUpvalueFloat,
- eUpvalueOther,
- eUpvalueAddr,
eDotFunc,
eGackType,
eGackEnd,
#define DotStatic (f_instr)eDotStatic
#define DotStatic2 (f_instr)eDotStatic2
#define DotStatic3 (f_instr)eDotStatic3
-#define UpvalueInt (f_instr)eUpvalueInt
-#define UpvalueFloat (f_instr)eUpvalueFloat
-#define UpvalueOther (f_instr)eUpvalueOther
-#define UpvalueAddr (f_instr)eUpvalueAddr
#define DotFunc (f_instr)eDotFunc
#define GackType (f_instr)eGackType
#define GackEnd (f_instr)eGackEnd
gw_out(" {-M}%-14"UINT_F"{0}", instr->m_val2);
gw_out("\n");
break;
- case eUpvalueInt:
- gw_out("{Y}┃{0}{-}% 4lu{0}: UpvalueInt ", j);
- gw_out(" {-R}%-14"UINT_F"{0}", instr->m_val);
- gw_out("\n");
- break;
- case eUpvalueFloat:
- gw_out("{Y}┃{0}{-}% 4lu{0}: UpvalueFloat", j);
- gw_out(" {-R}%-14"UINT_F"{0}", instr->m_val);
- gw_out("\n");
- break;
- case eUpvalueOther:
- gw_out("{Y}┃{0}{-}% 4lu{0}: UpvalueOther", j);
- gw_out(" {-R}%-14"UINT_F"{0}", instr->m_val);
- gw_out(" {-M}%-14"UINT_F"{0}", instr->m_val2);
- gw_out("\n");
- break;
- case eUpvalueAddr:
- gw_out("{Y}┃{0}{-}% 4lu{0}: UpvalueAddr ", j);
- gw_out(" {-R}%-14"UINT_F"{0}", instr->m_val);
- gw_out("\n");
- break;
case eDotFunc:
gw_out("{Y}┃{0}{-}% 4lu{0}: DotFunc ", j);
gw_out(" {-R}%-14"UINT_F"{0}", instr->m_val);
#ifndef __VM
#define __VM
-typedef struct Closure_ {
- struct Map_ m;
- m_uint sz;
- m_bit data[];
-} Closure;
-ANN Closure *new_closure(MemPool mp, const m_uint sz);
-ANN void free_closure(Closure *a, const Gwion gwion);
-
typedef struct VM_Code_ *VM_Code;
struct VM_Code_ {
m_bit *bytecode;
m_uint native_func;
};
Type ret_type; // could be `struct Vector_ tmpl_types;`
- union {
- void * memoize;
- Closure *closure;
- };
+ void * memoize;
m_str name;
struct Map_ handlers;
struct M_Vector_ live_values;
DotStatic~p
DotStatic2~p
DotStatic3~p~u
-UpvalueInt~u
-UpvalueFloat~u
-UpvalueOther~u~u
-UpvalueAddr~u
DotFunc~u~u
GackType
GackEnd~u
ANN static void clean_captures(Clean *a, Capture_List b) {
for(uint32_t i = 0; i < b->len; i++) {
const Capture *cap = mp_vector_at(b, Capture, i);
- if(cap->v) value_remref(cap->v, a->gwion);
+ if(cap->new) value_remref(cap->new, a->gwion);
}
}
return spid->exec ? emit_add_instr(emit, spid->exec) : spid->em(emit, prim);
}
-static const f_instr upvalue[] = {UpvalueInt, UpvalueFloat, UpvalueOther,
- UpvalueAddr};
ANN static m_bool emit_prim_id(const Emitter emit, const Symbol *data) {
const Exp_Primary *prim = prim_self(data);
- if (prim->value && emit->env->func && emit->env->func->def->captures) {
- const Capture_List caps = emit->env->func->def->captures;
- for (uint32_t i = 0; i < caps->len; ++i) {
- Capture *cap = mp_vector_at(caps, Capture, i);
- if (!strcmp(prim->value->name, cap->v->name)) {
- const Instr instr = emit_kind(emit, prim->value->type->size,
- exp_getvar(exp_self(prim)), upvalue);
- instr->m_val = cap->offset;
- return GW_OK;
- }
- }
- }
struct SpecialId_ *spid = specialid_get(emit->gwion, *data);
if (spid)
return specialid_instr(emit, spid, prim_self(data)) ? GW_OK : GW_ERROR;
if (emit->env->class_def) stack_alloc(emit);
if (emit->env->func && vflag(emit->env->func->value_ref, vflag_member))
stack_alloc(emit);
+ if(sp->captures) emit->code->frame->curr_offset += captures_sz(sp->captures);
return scoped_stmt(emit, sp->code, 0);
}
if(cap->is_ref) exp_setvar(&exp, true);
offset += exp_size(&exp);
emit_exp(emit, &exp);
+// emit_exp_addref(emit, &exp, -exp_size(&exp));
}
}
if(offset) {
return GW_OK;
}
-ANN static m_bool emit_upvalues(const Emitter emit, const Func func) {
- const Capture_List caps = func->def->captures;
- for (uint32_t i = 0; i < caps->len; ++i) {
- Capture *cap = mp_vector_at(caps, Capture, i);
- const Value value = cap->v;
- struct Exp_ exp = {
- .d = { .prim = {
- .d = { .var = cap->xid },
- .value = value,
- .prim_type = ae_prim_id
- }},
- .type = value->type,
- .exp_type = ae_exp_primary,
- .pos = cap->pos
- };
- if(cap->is_ref) exp_setvar(&exp, true);
- CHECK_BB(emit_exp(emit, &exp));
- if (isa(value->type, emit->gwion->type[et_compound]) > 0) {
- emit_exp_addref1(emit, &exp, -value->type->size);
- map_set(&func->code->closure->m, (vtype)value->type, cap->offset);
- }
- }
- return GW_OK;
-}
-
-ANN static m_bool emit_closure(const Emitter emit, const Func func) {
- const Capture *cap = mp_vector_at(func->def->captures, Capture, (func->def->captures->len - 1));
- const m_uint sz = cap->offset + cap->v->type->size;
- func->code->closure = new_closure(emit->gwion->mp, sz);
- regpushi(emit, (m_uint)func->code->closure->data);
- CHECK_BB(emit_upvalues(emit, func));
- regpop(emit, sz);
- const Instr cpy = emit_add_instr(emit, Reg2RegOther);
- cpy->m_val2 = sz;
- regpop(emit, SZ_INT);
- return GW_OK;
-}
-
ANN static m_bool emit_lambda(const Emitter emit, const Exp_Lambda *lambda) {
CHECK_BB(emit_func_def(emit, lambda->def));
- if (lambda->def->captures)
- CHECK_BB(emit_closure(emit, lambda->def->base->func));
if (vflag(lambda->def->base->func->value_ref, vflag_member) &&
!exp_getvar(exp_self(lambda)))
emit_add_instr(emit, RegPushMem);
const Vector l, const Vector r) {
const m_uint lsz = vector_size(l),
rsz = vector_size(r);
- if(lsz && rsz >= lsz) {
-// if(rsz >= lsz) {
+// if(lsz && rsz >= lsz) {
+ if(rsz >= lsz) {
for(m_uint i = 0; i < lsz; i++) {
const Value lval = (Value)vector_at(l, i),
rval = (Value)vector_at(r, i);
const Value v = nspc_lookup_value1(env->curr, cap->xid);
if(!v) ERR_B(cap->pos, _("unknown value in capture"));
offset += (!cap->is_ref ? SZ_INT : v->type->size);
- cap->v = v;
+ cap->orig = v;
cap->offset = offset;
}
}
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;
+ cap->orig = 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);
}
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, t, s_name(cap->xid), cap->pos);
- cap->v->from->offset = offset;
- offset += cap->v->type->size;
+ cap->new = new_value(env, t, s_name(cap->xid), cap->pos);
+ cap->new->from->offset = offset;
+ offset += cap->new->type->size;
}
}
- ++env->scope->depth;
- Upvalues values = {
- .values = env->curr->info->value
- };
+ Upvalues upvalues = { .values = env->curr->info->value };
if(env->func && env->func->def->base->values)
- values.parent = env->func->def->base->values;
+ upvalues.parent = env->func->def->base->values;
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);
+ valid_value(env, cap->xid, cap->new);
}
}
const Func f = env->func;
struct Value_ value = { .type = env->gwion->type[et_lambda]};
if(env->class_def)
set_vflag(&value, vflag_member);
- struct Func_Base_ fbase = { .xid=insert_symbol("in spork"), .values = &values};
+ struct Func_Base_ fbase = { .xid=insert_symbol("in spork"), .values = &upvalues};
set_fbflag(&fbase, fbflag_lambda);
struct Func_Def_ fdef = { .base = &fbase};
struct Func_ func = { .name = "in spork", .def = &fdef, .value_ref = &value};
env->func = &func;
+// ++env->scope->depth;
+//nspc_push_value(env->gwion->mp, env->curr);
const m_bool ret = check_stmt(env, unary->code);
+// nspc_push_value(env->gwion->mp, env->curr);
+// --env->scope->depth;
env->func = f;
free_scope(env->gwion->mp, env->curr->info->value);
- env->curr->info->value = values.values;
- --env->scope->depth;
+ env->curr->info->value = upvalues.values;
CHECK_BN(ret);
return env->gwion
->type[unary->op == insert_symbol("spork") ? et_shred : et_fork];
+++ /dev/null
-#include "gwion_util.h"
-#include "gwion_ast.h"
-#include "gwion_env.h"
-#include "vm.h"
-#include "instr.h"
-#include "memoize.h"
-#include "gwion.h"
-#include "object.h"
-#include "array.h"
-#include "operator.h"
-#include "import.h"
-
-ANN Closure *new_closure(MemPool mp, const m_uint sz) {
- Closure *a = mp_malloc2(mp, sizeof(Closure) + sz);
- map_init(&a->m);
- a->sz = sz;
- return a;
-}
-
-ANN void free_closure(Closure *a, const Gwion gwion) {
- const Map m = &a->m;
- for (m_uint i = 0; i < map_size(m); ++i) {
- const Type t = (Type)VKEY(m, i);
- const m_bit *data = tflag(t, tflag_ref) ?
- (a->data + VVAL(m, i)) : *(m_bit**)(a->data + VVAL(m, i));
- compound_release(gwion->vm->cleaner_shred, t, data);
- }
- map_release(m);
- _mp_free(gwion->mp, sizeof(Closure) + a->sz, a);
-}
&&remref, &&remref2, &&except, &&allocmemberaddr, &&dotmember, &&dotfloat,
&&dotother, &&dotaddr, &&unioncheck, &&unionint, &&unionfloat,
&&unionother, &&unionaddr, &&staticint, &&staticfloat, &&staticother,
- &&upvalueint, &&upvaluefloat, &&upvalueother, &&upvalueaddr, &&dotfunc,
- &&gacktype, &&gackend, &&gack, &&try_ini,
+ &&dotfunc, &&gacktype, &&gackend, &&gack, &&try_ini,
&&try_end, &&handleeffect, &&performeffect, &&noop, &&debugline,
&&debugvalue, &&debugpush, &&debugpop, &&eoc, &&unroll2, &&other,
&®pushimm};
memcpy(reg, (m_bit *)VAL, VAL2);
reg += VAL2;
DISPATCH()
- upvalueint:
- *(m_uint *)reg = *(m_uint *)(code->closure->data + VAL);
- reg += SZ_INT;
- DISPATCH()
- upvaluefloat:
- *(m_float *)reg = *(m_float *)(code->closure->data + VAL);
- reg += SZ_FLOAT;
- DISPATCH()
- upvalueother:
- memcpy(reg, code->closure->data + VAL, VAL2);
- reg += VAL2;
- DISPATCH()
- upvalueaddr:
- *(m_uint **)reg = (m_uint *)(code->closure->data + VAL);
- reg += SZ_INT;
- DISPATCH()
dotfunc:
*(VM_Code *)(reg + (m_uint)VAL2) =
((Func)(*(M_Object *)(reg - SZ_INT))->type_ref->nspc->vtable.ptr[OFFSET + VAL])->code;
&&_remref, &&_remref2, &&_except, &&_allocmemberaddr, &&_dotmember, &&_dotfloat,
&&_dotother, &&_dotaddr, &&_unioncheck, &&_unionint, &&_unionfloat,
&&_unionother, &&_unionaddr, &&_staticint, &&_staticfloat, &&_staticother,
- &&_upvalueint, &&_upvaluefloat, &&_upvalueother, &&_upvalueaddr, &&_dotfunc,
- &&_gacktype, &&_gackend, &&_gack, &&_try_ini,
+ &&_dotfunc, &&_gacktype, &&_gackend, &&_gack, &&_try_ini,
&&_try_end, &&_handleeffect, &&_performeffect, &&_noop, &&_debugline,
&&_debugvalue, &&_debugpush, &&_debugpop, &&_eoc, &&_unroll2, &&_other,
&&_regpushimm};
PREPARE(staticint);
PREPARE(staticfloat);
PREPARE(staticother);
- PREPARE(upvalueint);
- PREPARE(upvaluefloat);
- PREPARE(upvalueother);
- PREPARE(upvalueaddr);
PREPARE(dotfunc);
PREPARE(gacktype);
PREPARE(gackend);
if (!a->builtin) {
_mp_free(gwion->mp, vector_size(&a->instr) * BYTECODE_SZ, a->bytecode);
if (likely(!a->callback)) {
- if (a->closure) {
- if (!a->is_memoize)
- free_closure(a->closure, gwion);
- else
- memoize_end(gwion->mp, a->memoize);
- }
+ if(a->memoize) memoize_end(gwion->mp, a->memoize);
free_code_instr(&a->instr, gwion);
}
if (a->handlers.ptr) map_release(&a->handlers);
instr->opcode = eEOC;
const VM_Code code = new_vmcode(mp, &base->instr, &base->live_values, name,
base->stack_depth, base->builtin, false);
- code->closure = base->closure;
code->callback = 1;
instr->opcode = eFuncReturn;
return code;