-Subproject commit 35dae816a65843488b03d4dce27b1dfa8ddc09ea
+Subproject commit f7c8eadcf1727a3132a8a5b970f1fc879e44138e
typedef struct VMValue_ {
Type t;
+ void *local; /// :.....
uint16_t offset;
uint16_t start;
uint16_t end;
--- /dev/null
+#ifndef __LOOPER
+#define __LOOPER
+
+typedef struct Looper Looper;
+
+typedef Instr (*f_looper)(const Emitter, const Looper *);
+
+struct Looper {
+ const Exp exp;
+ const Stmt stmt;
+ /*const */ m_uint offset;
+ const m_uint n;
+ const f_looper roll;
+ const f_looper unroll;
+// union {
+ struct Vector_ unroll_v;
+ Instr instr;
+// };
+ struct EachIdx_ *idx;
+ bool init;
+};
+#endif
typedef struct M_Object_ *M_Object;
struct M_Object_ {
Type type_ref;
- struct Vector_ vtable;
- /*volatile */uint32_t ref;
- uint32_t offset;
+// struct Vector_ vtable;
+ /*volatile */uint64_t ref;
+// uint32_t offset;
m_bit data[];
};
#include "match.h"
#include "specialid.h"
#include "vararg.h"
+#include "looper.h"
#undef insert_symbol
#define insert_symbol(a) insert_symbol(emit->gwion->st, (a))
mp_free(p, Frame, a);
}
-ANN static Local *new_local(MemPool p, const Type type) {
- Local *local = mp_calloc(p, Local);
+ANN static inline Local *new_local(MemPool p, const Type type) {
+ Local *const local = mp_calloc(p, Local);
local->type = type;
return local;
}
if (isa(t, emit->gwion->type[et_compound]) > 0) {
l->is_compound = true;
VMValue vmval = {
- .t = t, .offset = l->offset, .start = emit_code_size(emit)};
+ .t = t, .local = l, .offset = l->offset, .start = emit_code_size(emit)};
m_vector_add(&emit->code->live_values, &vmval);
++emit->code->frame->value_count;
}
Local *const l = frame_local(emit->gwion->mp, emit->code->frame, t);
l->is_compound = true;
VMValue vmval = {
- .t = t, .offset = l->offset, .start = emit_code_size(emit)};
+ .t = t, .local = l, .offset = l->offset, .start = emit_code_size(emit)};
m_vector_add(&emit->code->live_values, &vmval);
++emit->code->frame->value_count;
l->instr = emit_add_instr(emit, Reg2Mem);
}
ANN void unset_local(const Emitter emit, Local *const l) {
+puts("unset");
l->instr->opcode = eNoOp;
for(m_uint i = m_vector_size(&emit->code->live_values) + 1; --i;) {
VMValue vmval = *(VMValue*)(ARRAY_PTR((&emit->code->live_values)) + (i-1) * sizeof(VMValue));
- if(vmval.offset != l->offset) continue;
+// if(vmval.offset != l->offset) continue;
+ if(vmval.local != l) continue;
m_vector_rem(&emit->code->live_values, i-1);
+ vector_rem2(&emit->code->frame->stack, (vtype)l);
+//vector_rem2(&emit->code->instr, l->instr);
+// free instr
+ --emit->code->frame->value_count;
break;
}
- --emit->code->frame->value_count;
}
ANN static m_uint decl_non_static_offset(const Emitter emit, const Exp_Decl *decl, const Type t) {
- if(!exp_self(decl)->data)
+// if(!exp_self(decl)->data)
return emit_local(emit, t);
- Local *const l = exp_self(decl)->data;
- return l->offset;
+// Local *const l = exp_self(decl)->data;
+// return l->offset;
}
ANN static m_bool emit_exp_decl_non_static(const Emitter emit,
const bool is_array = array && array->exp;
const bool is_obj = isa(type, emit->gwion->type[et_object]) > 0;
const bool emit_addr = (!is_obj || (is_ref && !is_array)) ? emit_var : true;
- if (is_obj && (is_array || !is_ref))
+ if (is_obj && (is_array || !is_ref) && !exp_self(decl)->ref)
+// if (is_obj && ((is_array && !exp_self(decl)->ref) || !is_ref))
CHECK_BB(emit_instantiate_decl(emit, type, decl->td, array, is_ref));
f_instr *exec = (f_instr *)allocmember;
if (!emit->env->scope->depth) emit_debug(emit, v);
exec)
: emit_struct_decl(emit, v, !struct_ctor(v) ? emit_addr : 1);
instr->m_val = v->from->offset;
- if (is_obj && (is_array || !is_ref)) {
+ if (is_obj && (is_array || !is_ref) && !exp_self(decl)->ref) {
if (!emit_var)
emit_add_instr(emit, Assign);
else {
const Instr instr = emit_add_instr(emit, Reg2RegAddr);
instr->m_val = -SZ_INT;
} else {
-// if(isa(t, emit->gwion->type[et_object]) > 0)
-// if(isa(t, emit->gwion->type[et_object]) > 0)
-// emit_local_exp(emit, e);
-// emit_localx(emit, t);
+ if(isa(t, emit->gwion->type[et_object]) > 0) {
+//emit_object_addref(emit, -SZ_INT, 0);
+ emit_local_exp(emit, e);
+// emit_localx(emit, t);
+ }
if (!is_func(emit->gwion, exp_call->func->type) &&
tflag(e->type, tflag_struct))
regpop(emit, SZ_INT);
return ret;
}
-struct Looper;
-typedef Instr (*f_looper_init)(const Emitter, const struct Looper *);
-typedef void (*f_looper)(const Emitter, const struct Looper *);
-struct Looper {
- const Exp exp;
- const Stmt stmt;
- /*const */ m_uint offset;
- const m_uint n;
- const f_looper_init roll;
- const f_looper_init unroll;
-// union {
- struct Vector_ unroll_v;
- Instr instr;
-// };
-};
-
-ANN static inline m_bool roll(const Emitter emit, struct Looper *const loop) {
- const Instr instr = loop->roll(emit, loop);
- CHECK_BB(scoped_stmt(emit, loop->stmt, 1));
- instr->m_val = emit_code_size(emit) + 1; // pass after goto
- return GW_OK;
-}
-
-ANN static Instr stmt_each_roll(const Emitter emit, const struct Looper *loop) {
-// const Instr instr = emit_add_instr(emit, AutoLoop);
-// instr->m_val2 = loop->offset + SZ_INT;
-// return instr;
+ANN static Instr each_op(const Emitter emit, const Looper *loop) {
struct Op_Import opi = {
.lhs = loop->exp->type,
- .op = insert_symbol("@autoloop"),
+ .op = insert_symbol("@each"),
.data = (m_uint)loop
};
CHECK_BO(op_emit(emit, &opi));
return loop->instr;
}
+ANN static inline m_bool roll(const Emitter emit, Looper*const loop) {
+const Instr instr = loop->roll(emit, loop);
+// DECL_OB(const Instr, instr, = each_op(emit, loop)); // maybe check in check.c
+ CHECK_BB(scoped_stmt(emit, loop->stmt, 1));
+ instr->m_val = emit_code_size(emit) + 1; // pass after goto
+ return GW_OK;
+}
+
ANN static inline void unroll_init(const Emitter emit, const m_uint n) {
- emit->info->unroll = 0;
const Instr instr = emit_add_instr(emit, MemSetImm);
instr->m_val = emit_local(emit, emit->gwion->type[et_int]);
instr->m_val2 = n;
}
ANN static inline m_bool unroll_run(const Emitter emit,
- struct Looper *const loop) {
- const Instr instr = loop->unroll ? loop->unroll(emit, loop) : NULL;
+ struct Looper *loop) {
+ const Instr instr = each_op(emit, loop);
CHECK_BB(scoped_stmt(emit, loop->stmt, 1));
if(instr)
vector_add(&loop->unroll_v, (m_uint)instr);
return GW_OK;
}
-ANN static m_bool _unroll(const Emitter emit, struct Looper *loop) {
+ANN static m_bool _unroll(const Emitter emit, Looper *loop) {
scoped_ini(emit);
const Instr unroll = emit_add_instr(emit, Unroll);
unroll->m_val = loop->offset;
return GW_OK;
}
-ANN static m_bool unroll(const Emitter emit, struct Looper *loop) {
+ANN static m_bool unroll(const Emitter emit, Looper *loop) {
if(loop->unroll)
vector_init(&loop->unroll_v);
const m_bool ret = _unroll(emit, loop);
if(loop->unroll) {
for(m_uint i = 0; i < vector_size(&loop->unroll_v); i++) {
const Instr instr = (Instr)vector_at(&loop->unroll_v, i);
- instr->m_val = emit_code_size(emit) + 2;
+ instr->m_val = emit_code_size(emit) + 1; // + 2 for arrays
}
vector_release(&loop->unroll_v);
}
return ret;
}
-ANN static Instr stmt_each_unroll(const Emitter emit,
- const struct Looper *loop) {
- struct Op_Import opi = {
- .lhs = loop->exp->type,
- .op = insert_symbol("@autoloop"),
- .data = (m_uint)loop
- };
- CHECK_BO(op_emit(emit, &opi));
- return loop->instr;
-// const Instr instr = emit_add_instr(emit, AutoLoop);
-// instr->m_val2 = loop->offset + SZ_INT * 2;
-// return instr;
-}
ANN static inline m_bool looper_run(const Emitter emit,
- struct Looper *const loop) {
+ Looper *const loop) {
return (!loop->n ? roll : unroll)(emit, loop);
}
ANN static m_bool _emit_stmt_each(const Emitter emit, const Stmt_Each stmt,
m_uint *end_pc) {
const uint n = emit->info->unroll;
- if (n) {
- unroll_init(emit, n);
- emit_local(emit, emit->gwion->type[et_int]);
- }
-
- CHECK_BB(emit_exp(emit, stmt->exp)); // add ref?
- regpop(emit, SZ_INT);
- const m_uint offset = emit_local(emit, emit->gwion->type[et_int]); // array?
- emit_local(emit, emit->gwion->type[et_int]);
- emit_local(emit, emit->gwion->type[et_int]);
+ const m_uint arr_offset = emit_local(emit, emit->gwion->type[et_int]); // array?
+ const m_uint key_offset = /*!stmt->idx
+ ? */emit_local(emit, emit->gwion->type[et_int])
+ /*: emit_local(emit, stmt->idx->v->type)*/;
+ const m_uint val_offset = emit_local(emit, stmt->v->type);
const Instr tomem = emit_add_instr(emit, Reg2Mem);
- tomem->m_val = offset;
+ tomem->m_val = arr_offset;
const Instr loop_idx = emit_add_instr(emit, MemSetImm);
- loop_idx->m_val = offset + SZ_INT;
+ loop_idx->m_val = key_offset;
loop_idx->m_val2 = -1;
- stmt->v->from->offset = offset + SZ_INT * 2;
+ stmt->v->from->offset = val_offset;
emit_debug(emit, stmt->v);
- if (stmt->idx) stmt->idx->v->from->offset = offset + SZ_INT;
- if (n) {
- const Instr instr = emit_add_instr(emit, AutoUnrollInit);
- instr->m_val = offset - SZ_INT;
+ if (stmt->idx) {
+ stmt->idx->v->from->offset = key_offset;
+ emit_debug(emit, stmt->v);
}
- const m_uint ini_pc = emit_code_size(emit);
struct Looper loop = {.exp = stmt->exp,
.stmt = stmt->body,
- .offset = offset,
+ .offset = arr_offset,
.n = n,
- .roll = stmt_each_roll,
- .unroll = stmt_each_unroll};
- if (n) loop.offset -= SZ_INT;
+ .roll = each_op,
+ .unroll = each_op,
+ .idx = stmt->idx,
+.init = false
+ };
+ if (n) {
+ loop.offset -= SZ_INT;
+ struct Op_Import opi = {
+ .lhs = loop.exp->type,
+ .op = insert_symbol("@each_init"),
+ .data = (m_uint)&loop
+ };
+ CHECK_BB(op_emit(emit, &opi));
+ }
+ const m_uint ini_pc = emit_code_size(emit);
CHECK_BB(looper_run(emit, &loop));
*end_pc = emit_code_size(emit);
const Instr tgt = emit_add_instr(emit, Goto);
}
ANN static m_bool emit_stmt_each(const Emitter emit, const Stmt_Each stmt) {
+ const uint n = emit->info->unroll;
+
+ CHECK_BB(emit_exp(emit, stmt->exp)); // add ref?
+ regpop(emit, SZ_INT);
+
+ if (n) {
+ unroll_init(emit, n);
+ emit_local(emit, emit->gwion->type[et_int]);
+ }
+
emit_push_stack(emit);
m_uint end_pc = 0;
const m_bool ret = _emit_stmt_each(emit, stmt, &end_pc);
emit_pop_stack(emit, end_pc);
+ emit->info->unroll = 0;
return ret;
}
-ANN static Instr stmt_loop_roll(const Emitter emit, const struct Looper *loop) {
+ANN static Instr stmt_loop_roll(const Emitter emit, const Looper *loop) {
const Instr eq = emit_add_instr(emit, Repeat);
eq->m_val2 = loop->offset;
return eq;
}
ANN static Instr stmt_loop_roll_idx(const Emitter emit,
- const struct Looper *loop) {
+ const Looper *loop) {
const Instr instr = emit_add_instr(emit, RepeatIdx);
instr->m_val2 = loop->offset;
return instr;
ANN static m_bool _emit_stmt_loop(const Emitter emit, const Stmt_Loop stmt,
m_uint *index) {
const uint n = emit->info->unroll;
- if (n) unroll_init(emit, n);
+ if (n) {
+ unroll_init(emit, n);
+ emit->info->unroll = 0;
+ }
const m_uint offset = emit_local(emit, emit->gwion->type[et_int]);
if (stmt->idx) {
const Instr instr = emit_add_instr(emit, MemSetImm);
}
ANN static m_bool emit_func_def_body(const Emitter emit, const Func_Def fdef) {
+ if (fdef->base->xid == insert_symbol("@dtor")) emit_local(emit, emit->gwion->type[et_int]);
if (fdef->base->args) emit_func_def_args(emit, fdef->base->args);
if (fbflag(fdef->base, fbflag_variadic)) stack_alloc(emit);
if (fdef->d.code) {
ANN void valuefrom(const Env env, struct ValueFrom_ *from, const loc_t loc) {
from->owner = env->curr;
- from->owner_class = env->class_def;
+ from->owner_class = env->scope->depth ? NULL : env->class_def;
from->ctx = env->context;
from->filename = env->name;
from->loc = loc;
#include "parse.h"
#include "gwi.h"
#include "emit.h"
-
+#include "looper.h"
static DTOR(array_dtor) {
if (*(void **)(o->data + SZ_INT)) xfree(*(void **)(o->data + SZ_INT));
struct M_Vector_ *a = ARRAY(o);
ERR_N(exp_self(bin)->pos,
_("do not provide array for 'xxx => declaration'."));
}
+ bin->rhs->ref = bin->lhs;
+// bin->rhs->data = bin->lhs;
+ if(bin->rhs->exp_type == ae_exp_decl)
+ SET_FLAG(bin->rhs->d.exp_decl.list->self->value, late);
exp_setvar(bin->rhs, 1);
return bin->rhs->type;
}
return imp->t;
}
-struct Looper;
-typedef Instr (*f_looper_init)(const Emitter, const struct Looper *);
-typedef void (*f_looper)(const Emitter, const struct Looper *);
-struct Looper {
- const Exp exp;
- const Stmt stmt;
- /*const */ m_uint offset;
- const m_uint n;
- const f_looper_init roll;
- const f_looper_init unroll;
-// union {
- struct Vector_ unroll_v;
- Instr instr;
-// };
-};
-
-static OP_EMIT(opem_array_autoloop) {
- struct Looper *loop = (struct Looper *)data;
+static OP_EMIT(opem_array_each_init) {
+ Looper *loop = (Looper *)data;
+ const Instr instr = emit_add_instr(emit, AutoUnrollInit);
+ instr->m_val = loop->offset;
+ return GW_OK;
+}
+
+
+ANN static inline Type foreach_type(const Env env, const Exp exp) {
+ 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;
+}
+
+// rewrite me
+static OP_CHECK(opck_array_each_val) {
+ const Exp exp = (const Exp) data;
+ DECL_ON(const Type, base, = foreach_type(env, exp));
+ CHECK_BN(ensure_traverse(env, base));
+ const m_str basename = type2str(env->gwion, base, exp->pos);
+ char c[15 + strlen(basename)];
+ sprintf(c, "Ref:[%s]", basename);
+ return str2type(env->gwion, c, exp->pos);
+}
+
+static OP_EMIT(opem_array_each) {
+ Looper *loop = (Looper *)data;
const Instr instr = emit_add_instr(emit, AutoLoop);
if(!loop->n) {
instr->m_val2 = loop->offset + SZ_INT;
+ loop->instr = instr;
} else {
instr->m_val2 = loop->offset + SZ_INT*2;
vector_add(&loop->unroll_v, (m_uint)instr);
}
- loop->instr = instr;
return GW_OK;
}
GWI_BB(gwi_oper_add(gwi, opck_array))
GWI_BB(gwi_oper_emi(gwi, opem_array_access))
GWI_BB(gwi_oper_end(gwi, "@array", NULL))
+ GWI_BB(gwi_oper_ini(gwi, "@Array", NULL, "void"))
+ GWI_BB(gwi_oper_emi(gwi, opem_array_each_init))
+ GWI_BB(gwi_oper_end(gwi, "@each_init", NULL))
+ GWI_BB(gwi_oper_ini(gwi, "@Array", NULL, "int"))
+ GWI_BB(gwi_oper_emi(gwi, opem_array_each))
+ GWI_BB(gwi_oper_end(gwi, "@each", NULL))
+ GWI_BB(gwi_oper_ini(gwi, "@Array", NULL, NULL))
+ GWI_BB(gwi_oper_add(gwi, opck_array_each_val))
+ GWI_BB(gwi_oper_end(gwi, "@each_val", NULL))
GWI_BB(gwi_oper_ini(gwi, "@Array", NULL, "int"))
- GWI_BB(gwi_oper_emi(gwi, opem_array_autoloop))
- GWI_BB(gwi_oper_end(gwi, "@autoloop", NULL))
+ GWI_BB(gwi_oper_end(gwi, "@each_idx", NULL))
GWI_BB(gwi_oper_ini(gwi, "@Array", NULL, NULL))
GWI_BB(gwi_oper_add(gwi, opck_array_scan))
GWI_BB(gwi_oper_end(gwi, "@scan", NULL))
if (!ref) {
gw_err("{-}[{0}{+}Gwion{0}{-}](VM):{0} (note: in shred[id=%" UINT_F ":%s])\n",
shred->tick->xid, shred->code->name);
- if (info->is_obj) free(aai.data);
+ if (info->is_obj) xfree(aai.data);
handle(shred, "ArrayAllocException");
return; // TODO make exception vararg
}
#include "gwi.h"
#include "tmpl_info.h"
#include "array.h"
+#include "looper.h"
#define HMAP_MIN_CAP 32
#define HMAP_MAX_LOAD 0.75
static CTOR(dict_ctor) {
const HMapInfo *hinfo = (HMapInfo*)o->type_ref->nspc->class_data;
- HMap *a = &*(struct HMap*)o->data;
- a->key_size = hinfo->key->size;
- a->val_size = hinfo->val->size;
- a->data = (m_bit*)mp_calloc2(shred->info->mp, hinfo->sz * HMAP_MIN_CAP);
- a->state = (m_bit*)mp_calloc2(shred->info->mp, sizeof(HState) * HMAP_MIN_CAP);
- a->capacity = HMAP_MIN_CAP;
- a->count = 0;
+ HMap *const a = &*(struct HMap*)o->data;
+ a->key_size = hinfo->key->size;
+ a->val_size = hinfo->val->size;
+ a->data = (m_bit*)mp_calloc2(shred->info->mp, hinfo->sz * HMAP_MIN_CAP);
+ a->state = (m_bit*)mp_calloc2(shred->info->mp, sizeof(HState) * HMAP_MIN_CAP);
+ a->capacity = HMAP_MIN_CAP;
+ a->count = 0;
}
static DTOR(dict_dtor) {
- HMap *a = &*(struct HMap*)o->data;
+ HMap *const a = &*(struct HMap*)o->data;
const HMapInfo *hinfo = (HMapInfo*)o->type_ref->nspc->class_data;
mp_free2(shred->info->mp, hinfo->sz * a->capacity, a->data);
mp_free2(shred->info->mp, sizeof(HState) * a->capacity, a->state);
*(m_uint*)(shred->reg -SZ_INT) = 1;
}
-static INSTR(hmap_wtf) {
+static INSTR(hmap_find) {
const M_Object o = *(M_Object*)(shred->reg - SZ_INT*6);
HMap *const hmap = (HMap*)o->data;
const HMapInfo *hinfo = (HMapInfo*)o->type_ref->nspc->class_data;
const Instr endgrow = emit_add_instr(emit, BranchNeqInt);
emit_exp(emit, call.d.exp_call.func);
emit_exp_call1(emit, call.d.exp_call.func->type->info->func, true);
- emit_add_instr(emit, hmap_wtf);
+ emit_add_instr(emit, hmap_find);
const Instr regrow = emit_add_instr(emit, BranchEqInt);
regrow->m_val = grow_pc;
nogrow->m_val = emit_code_size(emit);
return check_array_access(env, &next) ?: env->gwion->type[et_error];
}
+static INSTR(DictEach) {
+ const M_Object o = *(M_Object *)(shred->mem + instr->m_val2);
+ HMapInfo *const hinfo = (HMapInfo*)o->type_ref->nspc->class_data;
+ const HMap *hmap = (HMap*)o->data;
+ m_uint bucket = ++*(m_uint *)(shred->mem + instr->m_val2 + SZ_INT);
+ while(bucket < hmap->capacity) {
+ const HState *state = (HState *)(hmap->state + bucket * sizeof(HState));
+ if (state->set && !state->deleted)
+ break;
+ bucket++;
+ }
+ *(m_uint *)(shred->mem + instr->m_val2 + SZ_INT) = bucket;
+ memcpy(shred->mem + instr->m_val2 + SZ_INT*2, hmap->data + (bucket * hinfo->sz) + hinfo->key->size, hinfo->val->size);
+ *(m_uint*)shred->reg = (bucket == hmap->capacity);
+ PUSH_REG(shred, SZ_INT);
+}
+
+static INSTR(DictEachIdx) {
+ const M_Object o = *(M_Object *)(shred->mem + instr->m_val2);
+ HMapInfo *const hinfo = (HMapInfo*)o->type_ref->nspc->class_data;
+ const HMap *hmap = (HMap*)o->data;
+ DictEach(shred, instr);
+ const m_int bucket = *(m_uint *)(shred->mem + instr->m_val2 + SZ_INT);
+ memcpy(shred->mem + instr->m_val, hmap->data + (bucket * hinfo->sz), hinfo->key->size);
+}
+
+static OP_EMIT(opem_dict_each) {
+ Looper *loop = (Looper *)data;
+ HMapInfo *const hinfo = (HMapInfo*)loop->exp->type->nspc->class_data;
+ if(loop->idx && !loop->init) loop->idx->v->from->offset = emit_localn(emit, hinfo->key);
+ const Instr instr = emit_add_instr(emit, !loop->idx ? DictEach : DictEachIdx);
+ instr->m_val2 = loop->offset;
+ if(loop->idx) instr->m_val = loop->idx->v->from->offset;
+ if(loop->n)instr->m_val2 += SZ_INT;
+ const Instr go = emit_add_instr(emit, BranchNeqInt);
+ if(!loop->n) loop->instr = go;
+ else vector_add(&loop->unroll_v, (m_uint)go);
+ loop->init = true;
+ return GW_OK;
+}
+
+static INSTR(DictEachInit) {
+ const M_Object o = *(M_Object *)(shred->mem + instr->m_val + SZ_INT);
+ *(m_uint *)(shred->mem + instr->m_val) = ((HMap*)o->data)->capacity;
+}
+
+static OP_EMIT(opem_dict_each_init) {
+ const Looper *loop = (Looper *)data;
+ const Instr instr = emit_add_instr(emit, DictEachInit);
+ instr->m_val = loop->offset;
+ return GW_OK;
+}
+
+static OP_CHECK(opck_dict_each_key) {
+ const Exp exp = (const Exp)data;
+ HMapInfo *const hinfo = (HMapInfo*)exp->type->nspc->class_data;
+ return hinfo->key;
+}
+
+static OP_CHECK(opck_dict_each_val) {
+ const Exp exp = (const Exp)data;
+ HMapInfo *const hinfo = (HMapInfo*)exp->type->nspc->class_data;
+ return hinfo->val;
+}
+
static OP_CHECK(opck_dict_scan) {
struct TemplateScan *ts = (struct TemplateScan *)data;
struct tmpl_info info = {
}
return ret > 0 ? t : NULL;
-// return t;
}
GWION_IMPORT(dict) {
GWI_BB(gwi_oper_add(gwi, opck_dict_scan))
GWI_BB(gwi_oper_end(gwi, "@scan", NULL))
+ GWI_BB(gwi_oper_ini(gwi, "Dict", NULL, "int"))
+ GWI_BB(gwi_oper_emi(gwi, opem_dict_each))
+ GWI_BB(gwi_oper_end(gwi, "@each", NULL))
+
+ GWI_BB(gwi_oper_ini(gwi, "Dict", NULL, "void"))
+ GWI_BB(gwi_oper_emi(gwi, opem_dict_each_init))
+ GWI_BB(gwi_oper_end(gwi, "@each_init", NULL))
+
+ GWI_BB(gwi_oper_ini(gwi, "Dict", NULL, NULL))
+ GWI_BB(gwi_oper_add(gwi, opck_dict_each_val))
+ GWI_BB(gwi_oper_end(gwi, "@each_val", NULL))
+
+ GWI_BB(gwi_oper_ini(gwi, "Dict", NULL, NULL))
+ GWI_BB(gwi_oper_add(gwi, opck_dict_each_key))
+ GWI_BB(gwi_oper_end(gwi, "@each_idx", NULL))
+
GWI_BB(gwi_func_ini(gwi, "int", "hash"));
GWI_BB(gwi_func_arg(gwi, "int", "key"));
GWI_BB(gwi_func_end(gwi, mfun_int_h, ae_flag_none));
#include "import.h"
#include "emit.h"
#include "template.h"
-
+/*
INSTR(DTOR_EOC) {
const M_Object o = *(M_Object *)MEM(0);
o->type_ref = o->type_ref->info->parent;
shred->info->me->ref = 1;
vm_shred_exit(shred);
}
-
+*/
ANN static Func_Def from_base(const Env env, struct dottmpl_ *const dt,
const Nspc nspc) {
const Func_Def fdef = dt->def ?: dt->base;
const M_Object a = _mp_calloc(p, offset);
a->ref = 1;
a->type_ref = t;
- a->offset = t->nspc->offset;
- a->vtable.ptr = t->nspc->vtable.ptr;
return a;
}
}
ANN static void user_dtor(const M_Object o, const VM_Shred shred, const Type t) {
- o->type_ref = t;
- const VM_Shred sh = new_vm_shred(shred->info->mp, o->type_ref->nspc->dtor);
- vmcode_addref(o->type_ref->nspc->dtor);
+ const VM_Shred sh = new_vm_shred(shred->info->mp, t->nspc->dtor);
+ vmcode_addref(t->nspc->dtor);
sh->base = shred->base;
*(M_Object *)sh->mem = o;
+ *(Type *)(sh->mem + SZ_INT) = t;
vm_add_shred(shred->info->vm, sh);
++sh->info->me->ref;
}
return do_release(o, shred, t->info->parent);
}
+
+INSTR(DTOR_EOC) {
+ const M_Object o = *(M_Object *)MEM(0);
+ const Type t = *(Type *)MEM(SZ_INT);
+ do_release(o, shred, t->info->parent);
+ shred->info->me->ref = 1;
+ vm_shred_exit(shred);
+}
+
ANN void __release(const M_Object o, const VM_Shred shred) {
-// vector_rem2(&shred->gc, (vtype)o);
do_release(o, shred, o->type_ref);
}
ANN void free_object(MemPool p, const M_Object o) {
- mp_free2(p, o->offset, o);
+ mp_free2(p, o->type_ref->nspc->offset, o);
}
static ID_CHECK(opck_this) {
exp_setvar(bin->rhs, 1);
CHECK_BO(isa(bin->lhs->type, bin->rhs->type));
bin->lhs->ref = bin->rhs;
+// bin->lhs->acquire = true;
// bin->rhs-> = bin->lhs;
return bin->rhs->type;
}
ANN void unset_local(const Emitter emit, void *const l);
static OP_EMIT(opem_object_at) {
const Exp_Binary *bin = (Exp_Binary *)data;
-
if(!bin->rhs->data) {
const Instr addref = emit_add_instr(emit, RegAddRef);
addref->m_val = -SZ_INT * 2;
const Exp_Unary *unary = (Exp_Unary *)data;
CHECK_BB(emit_instantiate_object(emit, exp_self(unary)->type,
unary->ctor.td->array, 0));
- if(!unary->ctor.exp)
- emit_localx(emit, exp_self(unary)->type);
+// if(!unary->ctor.exp)
+// emit_local_exp(emit, exp_self(unary)->type);
return GW_OK;
}
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;
do {
CHECK_BB(check_var(env, var));
CHECK_BB(check_var_td(env, var, decl->td));
if (is_fptr(env->gwion, decl->type)) CHECK_BB(check_fptr_decl(env, var));
- set_vflag(var->value, vflag_valid);
+ valid_value(env, var->xid, var->value);
// set_vflag(var->value, vflag_used));
- nspc_add_value(env->curr, var->xid, var->value);
} while ((list = list->next));
return GW_OK;
}
const Var_Decl decl = arg_list->var_decl;
const Value v = decl->value;
CHECK_BB(already_defined(env, decl->xid, decl->pos));
- set_vflag(v, vflag_valid);
- nspc_add_value(env->curr, decl->xid, v);
+ valid_value(env, decl->xid, v);
} while ((arg_list = arg_list->next));
return GW_OK;
}
}
ANN static inline Type foreach_type(const Env env, const Exp exp) {
- DECL_OO(Type, et, = check_exp(env, exp));
+ const Type et = exp->type;
if (isa(et, env->gwion->type[et_array]) < 0)
ERR_O(exp->pos,
_("type '%s' is not array.\n"
return depth ? array_type(env, t, depth) : t;
}
-ANN static void check_idx(const Env env, struct EachIdx_ *const idx) {
- idx->v =
- new_value(env->gwion->mp, env->gwion->type[et_int], s_name(idx->sym));
+ANN static void check_idx(const Env env, const Type base, struct EachIdx_ *const idx) {
+ idx->v = new_value(env->gwion->mp, base, s_name(idx->sym));
valuefrom(env, idx->v->from, idx->pos);
- idx->v->from->owner_class = NULL;
- set_vflag(idx->v, vflag_valid);
- nspc_add_value(env->curr, idx->sym, idx->v);
+ valid_value(env, idx->sym, idx->v);
+}
+
+/** sets for the key expression value
+ with eg type *int* for an array or the *Key* type of a Dict **/
+ANN static m_bool check_each_idx(const Env env, const Exp exp, struct EachIdx_ *const idx) {
+ struct Op_Import opi = {
+ .lhs = exp->type,
+ .op = insert_symbol("@each_idx"),
+ .data = exp,
+ .pos = idx->pos
+ };
+ DECL_OB(const Type, t, = op_check(env, &opi));
+ check_idx(env, t, idx);
+ return GW_OK;
+}
+
+/** return the base type for the foreach expression
+ eg the base type of an array or the *Val* type of a Dict **/
+ANN static Type check_each_val(const Env env, const Exp exp) {
+ struct Op_Import opi = {
+ .lhs = exp->type,
+ .op = insert_symbol("@each_val"),
+ .data = (m_uint)exp
+ };
+ return op_check(env, &opi);
}
ANN static m_bool do_stmt_each(const Env env, const Stmt_Each stmt) {
- DECL_OB(const Type, base, = foreach_type(env, stmt->exp));
- CHECK_BB(ensure_traverse(env, base));
- const m_str basename = type2str(env->gwion, base, stmt->exp->pos);
- char c[15 + strlen(basename)];
- sprintf(c, "Ref:[%s]", basename);
- const Type ret = str2type(env->gwion, c, stmt->exp->pos);
- if (base->array_depth) set_tflag(ret, tflag_typedef);
+ CHECK_OB(check_exp(env, stmt->exp));
+ if (stmt->idx)
+ CHECK_BB(check_each_idx(env, stmt->exp, stmt->idx));
+ DECL_OB(const Type, ret, = check_each_val(env, stmt->exp));
stmt->v = new_value(env->gwion->mp, ret, s_name(stmt->sym));
- set_vflag(stmt->v, vflag_valid);
- nspc_add_value(env->curr, stmt->sym, stmt->v);
- if (stmt->idx) check_idx(env, stmt->idx);
+ valid_value(env, stmt->sym, stmt->v);
return check_conts(env, stmt_self(stmt), stmt->body);
}
ANN static m_bool do_stmt_repeat(const Env env, const Stmt_Loop stmt) {
- if (stmt->idx) check_idx(env, stmt->idx);
+ if (stmt->idx) check_idx(env, env->gwion->type[et_int], stmt->idx);
return check_conts(env, stmt_self(stmt), stmt->body);
}
-ANN static inline m_bool cond_type(const Env env, const Exp e) {
+ANN static inline m_bool repeat_type(const Env env, const Exp e) {
const Type t_int = env->gwion->type[et_int];
if (check_implicit(env, e, t_int) < 0) {
char explain[40 + strlen(e->type->name)];
(stmt->c3 && !check_exp(env, stmt->c3)) ||
check_conts(env, stmt_self(stmt), stmt->body) < 0) ? 1 : -1)
stmt_func_xxx(loop, Stmt_Loop, env_inline_mult(env, 1.5); check_idx(env, stmt->idx), !(!check_exp(env, stmt->cond) ||
- cond_type(env, stmt->cond) < 0 ||
+ repeat_type(env, stmt->cond) < 0 ||
do_stmt_repeat(env, stmt) < 0) ? 1 : -1)
stmt_func_xxx(each, Stmt_Each, env_inline_mult(env, 1.5), do_stmt_each(env, stmt))
const Exp_Primary *prim) {
const Symbol sym = prim->d.var;
const Value v = new_value(env->gwion->mp, base, s_name(sym));
- set_vflag(v, vflag_valid);
- nspc_add_value(env->curr, sym, v);
+ valid_value(env, sym, v);
return v;
}
ANN m_bool check_class_def(const Env env, const Class_Def cdef) {
if (tmpl_base(cdef->base.tmpl)) return GW_OK;
const Type t = cdef->base.type;
+ if (tflag(t, tflag_check)) return GW_OK;
const Class_Def c = t->info->cdef;
struct Op_Import opi = {.op = insert_symbol("@class_check"),
.lhs = t,
.data = (uintptr_t)c,
.pos = c->pos};
CHECK_OB(op_check(env, &opi));
- if (tflag(t, tflag_check)) return GW_OK;
set_tflag(t, tflag_check);
return _check_class_def(env, c);
}
DISPATCH()
autounrollinit:
*(m_uint *)(mem + VAL) =
- m_vector_size(ARRAY(*(M_Object *)(mem + VAL + SZ_INT)));
+ m_vector_size(ARRAY(*(M_Object *)(mem + VAL + SZ_INT))) + 1;
DISPATCH()
autoloop: {
const M_Vector array = ARRAY(*(M_Object *)(mem + VAL2 - SZ_INT));
DISPATCH()
dotfunc:
*(VM_Code *)(reg + (m_uint)VAL2) =
- ((Func)(*(M_Object *)(reg - SZ_INT))->vtable.ptr[OFFSET + VAL])->code;
+ ((Func)(*(M_Object *)(reg - SZ_INT))->type_ref->nspc->vtable.ptr[OFFSET + VAL])->code;
DISPATCH()
gacktype : {
const M_Object o = *(M_Object *)(reg - SZ_INT);
+++ /dev/null
-#! [contains] not allowed in foreach loop
-var Object i;
-foreach(a: i)
- <<< a >>>;
-Subproject commit 7643ceba751766ae5cd42da19667e1377a2b89d0
+Subproject commit 7b668adba0cd3d9e6af45e9c30456b5a6f171d74