ANN static inline void set_tflag(const Type t, const enum tflag flag) {
t->tflag |= flag;
}
+
+static inline void unset_tflag(const Type t, const enum tflag flag) {
+ t->tflag &= ~flag;
+}
#else
ANN static inline void set_tflag(const Type t, const enum tflag flag) {
auto ff = t->tflag | flag;
t->tflag = static_cast<enum tflag>(ff);
}
+
+static inline void unset_tflag(const Type t, const enum tflag flag) {
+ const auto ff = t->tflag & ~flag;
+ t->tflag = static_cast<enum fflag>(tt);
+}
#endif
ANN2(1,3) ANEW Type new_type(MemPool, const m_uint xid, const m_str name, const Type);
ANEW ANN Type type_copy(MemPool, const Type type);
vector_add(&frame->stack, (vtype)NULL);
}
+static const f_instr regpushimm[] = { RegPushImm, RegPushImm2, RegPushImm3, RegPushImm4 };
+static const f_instr regpushmem[] = { RegPushMem, RegPushMem2, RegPushMem3, RegPushMem4 };
+static const f_instr regpushbase[] = { RegPushBase, RegPushBase2, RegPushBase3, RegPushBase4 };
+static const f_instr dotstatic[] = { DotStatic, DotStatic2, DotStatic3, RegPushImm };
+static const f_instr allocmember[] = { RegPushImm, RegPushImm2, RegPushImm3, AllocMember4 };
+static const f_instr allocword[] = { AllocWord, AllocWord2, AllocWord3, RegPushMem4 };
+static const f_instr structmember[] = { StructMember, StructMemberFloat, StructMemberOther, StructMemberAddr };
+
+#define regxxx(name, instr) \
+ANN static inline Instr reg##name(const Emitter emit, const m_uint sz) { \
+ const Instr instr = emit_add_instr(emit, Reg##instr); \
+ instr->m_val = sz; \
+ return instr; \
+}
+regxxx(pop, Pop)
+regxxx(push, Push)
+regxxx(pushi, PushImm)
+regxxx(seti, SetImm)
+
+static inline enum Kind kindof(const m_uint size, const uint emit_var) {
+ if(emit_var)
+ return KIND_ADDR;
+ return size == SZ_INT ? KIND_INT : size == SZ_FLOAT ? KIND_FLOAT : KIND_OTHER;
+}
+
+ANN /*static */Instr emit_kind(Emitter emit, const m_uint size, const uint addr, const f_instr func[]) {
+ const enum Kind kind = kindof(size, addr);
+ const Instr instr = emit_add_instr(emit, func[kind]);
+ instr->m_val2 = size;
+ return instr;
+}
+
+ANN static void emit_struct_ctor(const Emitter emit, const Type type, const m_uint offset) {
+ emit->code->frame->curr_offset += SZ_INT;
+ const Instr instr = emit_add_instr(emit, RegPushMem4);
+ instr->m_val = offset;
+ const Instr tomem = emit_add_instr(emit, Reg2Mem);
+ tomem->m_val = emit->code->frame->curr_offset;
+ tomem->m_val2 = -SZ_INT;
+ regpushi(emit, (m_uint)type);
+ const Instr tomem2 = emit_add_instr(emit, Reg2Mem);
+ tomem2->m_val = emit->code->frame->curr_offset + SZ_INT;
+ tomem2->m_val2 = -SZ_INT;
+ const Instr set_code = regseti(emit, (m_uint)type->nspc->dtor);
+ set_code->m_val2 = SZ_INT;
+ const m_uint code_offset = emit_code_offset(emit);
+ const Instr regset = regseti(emit, code_offset);
+ regset->m_val2 = SZ_INT *2;
+ regpush(emit, SZ_INT *2);
+ const Instr prelude = emit_add_instr(emit, SetCode);
+ prelude->m_val2 = 2;
+ prelude->m_val = SZ_INT*3;
+ const Instr next = emit_add_instr(emit, Overflow);
+ next->m_val2 = code_offset;
+ emit->code->frame->curr_offset -= SZ_INT;
+}
+
ANN static void struct_pop(const Emitter emit, const Type type, const m_uint offset) {
if(!type->info->tuple)
return;
+ if(type->nspc->dtor)
+ emit_struct_ctor(emit, type, offset);
for(m_uint i = 0; i < vector_size(&type->info->tuple->types); ++i) {
const Type t = (Type)vector_at(&type->info->tuple->types, i);
if(isa(t, emit->gwion->type[et_object]) > 0) {
emit_array_extend(emit, type->info->parent, type->info->cdef->base.ext->array->exp);
}
-#define regxxx(name, instr) \
-ANN static inline Instr reg##name(const Emitter emit, const m_uint sz) { \
- const Instr instr = emit_add_instr(emit, Reg##instr); \
- instr->m_val = sz; \
- return instr; \
-}
-regxxx(pop, Pop)
-regxxx(push, Push)
-regxxx(pushi, PushImm)
-regxxx(seti, SetImm)
-
ANN static void struct_expand(const Emitter emit, const Type t) {
const Instr instr = emit_add_instr(emit, Reg2RegDeref);
instr->m_val = -SZ_INT;
const m_uint offset = emit_code_offset(emit);
const Instr regset = regseti(emit, offset);
regset->m_val2 = SZ_INT *2;
- const Instr push = emit_add_instr(emit, RegPush);
- push->m_val = SZ_INT *2;
+ regpush(emit, SZ_INT*2);
const Instr prelude = emit_add_instr(emit, SetCode);
prelude->m_val2 = 2;
prelude->m_val = SZ_INT;
return GW_OK;
}
-static inline enum Kind kindof(const m_uint size, const uint emit_var) {
- if(emit_var)
- return KIND_ADDR;
- return size == SZ_INT ? KIND_INT : size == SZ_FLOAT ? KIND_FLOAT : KIND_OTHER;
-}
-
-ANN /*static */Instr emit_kind(Emitter emit, const m_uint size, const uint addr, const f_instr func[]) {
- const enum Kind kind = kindof(size, addr);
- const Instr instr = emit_add_instr(emit, func[kind]);
- instr->m_val2 = size;
- return instr;
-}
-
-static const f_instr regpushimm[] = { RegPushImm, RegPushImm2, RegPushImm3, RegPushImm4 };
-static const f_instr regpushmem[] = { RegPushMem, RegPushMem2, RegPushMem3, RegPushMem4 };
-static const f_instr regpushbase[] = { RegPushBase, RegPushBase2, RegPushBase3, RegPushBase4 };
-static const f_instr dotstatic[] = { DotStatic, DotStatic2, DotStatic3, RegPushImm };
-static const f_instr allocmember[] = { RegPushImm, RegPushImm2, RegPushImm3, AllocMember4 };
-static const f_instr allocword[] = { AllocWord, AllocWord2, AllocWord3, RegPushMem4 };
-static const f_instr structmember[] = { StructMember, StructMemberFloat, StructMemberOther, StructMemberAddr };
-
ANN Exp symbol_owned_exp(const Gwion gwion, const Symbol *data);
ANN static m_bool emit_symbol_owned(const Emitter emit, const Symbol *data) {
const Exp dot = symbol_owned_exp(emit->gwion, data);
return ret;
}
-ANN static Instr emit_stmt_eachptr_init(const Emitter emit, const Type type) {
- const Instr new_obj = emit_add_instr(emit, ObjectInstantiate);
- new_obj->m_val2 = (m_uint)type;
- (void)emit_addref(emit, 0);
- regpop(emit, SZ_INT);
- return emit_add_instr(emit, Reg2Mem);
-}
-
ANN static m_bool _emit_stmt_each(const Emitter emit, const Stmt_Each stmt, m_uint *end_pc) {
const Instr s1 = emit_add_instr(emit, MemSetImm);
- Instr cpy = stmt->is_ptr ? emit_stmt_eachptr_init(emit, stmt->v->type) : NULL;
+ Instr cpy = stmt->is_ptr ? emit_add_instr(emit, MemSetImm) : NULL;
emit_local(emit, emit->gwion->type[et_int]);
const m_uint offset = emit_local(emit, emit->gwion->type[et_int]);
- emit_local(emit, emit->gwion->type[et_int]);
+ emit_local(emit, emit->gwion->type[et_ptr]);//et_int
stmt->v->from->offset = offset + SZ_INT;
const m_uint ini_pc = emit_code_size(emit);
emit_except(emit, stmt->exp->info->type);
}
ANN Type gwi_struct_ini(const Gwi gwi, const m_str name) {
- CHECK_OO(gwi_str2sym(gwi, name))
- const Type t = new_type(gwi->gwion->mp, ++gwi->gwion->env->scope->type_xid, name, gwi->gwion->type[et_compound]);
- t->info->tuple = new_tupleform(gwi->gwion->mp, NULL);
- gwi_type_flag(t);
+ struct ImportCK ck = { .name=name };
+ CHECK_BO(check_typename_def(gwi, &ck))
+ const Type t = new_type(gwi->gwion->mp, ++gwi->gwion->env->scope->type_xid, s_name(ck.sym), gwi->gwion->type[et_compound]);
set_tflag(t, tflag_struct);
+ if(!ck.tmpl)
+ gwi_type_flag(t);
+ else {
+ t->info->cdef = new_class_def(gwi->gwion->mp, 0, ck.sym, NULL, NULL, loc(gwi));
+ t->info->cdef->base.type = t;
+ t->info->cdef->base.tmpl = new_tmpl_base(gwi->gwion->mp, ck.tmpl);
+ t->info->tuple = new_tupleform(gwi->gwion->mp, NULL);
+ t->info->parent = NULL;
+ t->info->cdef->cflag |= cflag_struct;
+ set_tflag(t, tflag_tmpl);
+ }
return type_finish(gwi, t);
}
}
struct tmpl_info {
-// const Class_Def cdef;
Symbol name;
ID_List list;
Type_List call;
const Class_Def cdef = new_class_def(env->gwion->mp, c->flag, info->name, c->base.ext ? cpy_type_decl(env->gwion->mp, c->base.ext) : NULL,
c->body ?cpy_ast(env->gwion->mp, c->body) : NULL,
loc_cpy(env->gwion->mp, c->pos));
+ cdef->cflag = c->cflag;
cdef->base.tmpl = mk_tmpl(env, c->base.tmpl, info->call);
const m_bool ret = scan0_class_def(env, cdef);
if((info->ret = cdef->base.type)) {
CHECK_BO(ptr_access(env, bin->lhs))
CHECK_BO(ptr_access(env, bin->rhs))
exp_setvar(bin->lhs, 1);
+ exp_setvar(bin->rhs, 1);
Type t = bin->lhs->info->type;
do {
// t = unflag_type(t);
}
static INSTR(instr_ptr_assign) {
- POP_REG(shred, SZ_INT)
- const M_Object o = *(M_Object*)REG(0);
- *(m_uint**)o->data = *(m_uint**)REG(-SZ_INT);
- _release(o, shred);
+ m_bit **o = *(m_bit***)REG(0);
+ *o = *(m_bit**)REG(-SZ_INT);
+}
+
+static INSTR(instr_ptr_assign_obj) {
+ m_bit **o = *(m_bit***)REG(0);
+ release(*(M_Object*)o, shred);
+ *o = *(m_bit**)REG(-SZ_INT);
+}
+
+static OP_EMIT(opem_ptr_assign) {
+ const Instr pop = emit_add_instr(emit, RegPop);
+ pop->m_val = SZ_INT;
+ const Exp_Binary* bin = (Exp_Binary*)data;
+ if(isa(bin->lhs->info->type, emit->gwion->type[et_object]) > 0) {
+ const Instr instr = emit_add_instr(emit, RegAddRefAddr);
+ instr->m_val = -SZ_INT;
+ emit_add_instr(emit, instr_ptr_assign_obj);
+ } else
+ emit_add_instr(emit, instr_ptr_assign);
+ return pop;
}
static OP_CHECK(opck_ptr_deref) {
}
static INSTR(instr_ptr_deref) {
- const M_Object o = *(M_Object*)REG(-SZ_INT);
- if(!*(m_bit**)o->data)
+ const m_bit *o = *(m_bit**)REG(-SZ_INT);
+ if(!o)
Except(shred, _("EmptyPointerException"));
if(instr->m_val2)
- memcpy(REG(-SZ_INT), o->data, SZ_INT);
+ memcpy(REG(-SZ_INT), &o, SZ_INT);
else {
shred->reg -= SZ_INT - instr->m_val;
- memcpy(REG(-instr->m_val), *(m_bit**)o->data, instr->m_val);
+ memcpy(REG(-instr->m_val), o, instr->m_val);
}
}
static INSTR(Cast2Ptr) {
- const M_Object o = new_object(shred->info->mp, shred, (Type)instr->m_val);
- *(m_uint**)o->data = *(m_uint**)REG(-SZ_INT);
- *(M_Object*)REG(-SZ_INT) = o;
+ m_bit *o = *(m_bit**)REG(-SZ_INT);
+ *(m_bit**)REG(-SZ_INT) = o;
}
static OP_EMIT(opem_ptr_cast) {
ANN Type scan_class(const Env env, const Type t, const Type_Decl* td);
static DTOR(ptr_object_dtor) {
- release(*(M_Object*)o->data, shred);
+ release(**(M_Object**)o, shred);
}
static DTOR(ptr_struct_dtor) {
- const Type t = (Type)vector_front(&o->type_ref->info->tuple->types);
- struct_release(shred, t, *(m_bit**)o->data);
+ const Type base = *(Type*)(shred->mem + SZ_INT);
+ const m_uint scope = env_push(shred->info->vm->gwion->env, base->info->owner_class, base->info->owner);
+ const Type t = known_type(shred->info->vm->gwion->env, base->info->cdef->base.tmpl->call->td);
+ env_pop(shred->info->vm->gwion->env, scope);
+ struct_release(shred, t, *(m_bit**)o);
}
static OP_CHECK(opck_ptr_scan) {
struct TemplateScan *ts = (struct TemplateScan*)data;
DECL_ON(const Type, t, = (Type)scan_class(env, ts->t, ts->td))
-set_tflag(t, tflag_tmpl);
-//if(!tflag(t, tflag_scan1))exit(3);
const Type base = known_type(env, t->info->cdef->base.tmpl->call->td);
- if(isa(base, env->gwion->type[et_compound]) > 0 && !t->nspc->dtor) {
+ if(isa(base, env->gwion->type[et_compound]) > 0) {
t->nspc->dtor = new_vm_code(env->gwion->mp, NULL, SZ_INT, 1, "@PtrDtor");
- if(!tflag(t, tflag_struct))
+ if(!tflag(base, tflag_struct))
t->nspc->dtor->native_func = (m_uint)ptr_object_dtor;
else
t->nspc->dtor->native_func = (m_uint)ptr_struct_dtor;
}
GWION_IMPORT(ptr) {
- const Type _t_ptr = gwi_class_ini(gwi, "@Ptr", NULL);
- GWI_BB(gwi_class_end(gwi))
- set_tflag(_t_ptr, tflag_ntmpl);
-// set_tflag(_t_ptr, tflag_tmpl);
- GWI_BB(gwi_oper_ini(gwi, "@Ptr", NULL, NULL))
- GWI_BB(gwi_oper_add(gwi, opck_ptr_scan))
- GWI_BB(gwi_oper_end(gwi, "@scan", NULL))
- const Type t_ptr = gwi_class_ini(gwi, "Ptr:[A]", "@Ptr");
+ const Type t_ptr = gwi_struct_ini(gwi, "Ptr:[A]");
gwi->gwion->type[et_ptr] = t_ptr;
GWI_BB(gwi_item_ini(gwi, "@internal", "@val"))
GWI_BB(gwi_item_end(gwi, 0, NULL))
GWI_BB(gwi_class_end(gwi))
set_tflag(t_ptr, tflag_ntmpl);
-// set_tflag(t_ptr, tflag_tmpl);
+ GWI_BB(gwi_oper_ini(gwi, "Ptr", NULL, NULL))
+ GWI_BB(gwi_oper_add(gwi, opck_ptr_scan))
+ GWI_BB(gwi_oper_end(gwi, "@scan", NULL))
GWI_BB(gwi_oper_ini(gwi, (m_str)OP_ANY_TYPE, "nonnull Ptr", NULL))
GWI_BB(gwi_oper_add(gwi, opck_ptr_assign))
- GWI_BB(gwi_oper_end(gwi, ":=>", instr_ptr_assign))
+ GWI_BB(gwi_oper_emi(gwi, opem_ptr_assign))
+ GWI_BB(gwi_oper_end(gwi, ":=>", NULL))
GWI_BB(gwi_oper_add(gwi, opck_ptr_implicit))
GWI_BB(gwi_oper_emi(gwi, opem_ptr_implicit))
GWI_BB(gwi_oper_end(gwi, "@implicit", Cast2Ptr))
if(!a.code->builtin) {
register const m_uint push = *(m_uint*)(reg + SZ_INT) + *(m_uint*)(mem-SZ_INT);
mem += push;
- *(m_uint*) mem = push;mem += SZ_INT;
+ *(m_uint*) mem = push; mem += SZ_INT;
*(VM_Code*) mem = code; mem += SZ_INT;
*(m_uint*) mem = PC + VAL2; mem += SZ_INT;
*(m_uint*) mem = a.code->stack_depth; mem += SZ_INT;
m_vector_get(ARRAY(*(M_Object*)(reg-SZ_INT)), *(m_uint*)(mem + VAL), mem + VAL + SZ_INT);
goto autoloopcount;
autoloopptr:
- *(m_bit**)(*(M_Object*)(mem + VAL + SZ_INT))->data = m_vector_addr(ARRAY(*(M_Object*)(reg-SZ_INT)), *(m_uint*)(mem + VAL));
+ *(m_bit**)(mem + VAL + SZ_INT) = m_vector_addr(ARRAY(*(M_Object*)(reg-SZ_INT)), *(m_uint*)(mem + VAL));
autoloopcount:
*(m_uint*)reg = m_vector_size(ARRAY(*(M_Object*)(reg-SZ_INT))) - (*(m_uint*)(mem + VAL))++;
reg += SZ_INT;