return code;
}
+ANN static inline m_uint exp_size(const Exp e) {
+ if(exp_getvar(e))
+ return SZ_INT;
+ const Type type = e->info->cast_to ?: e->info->type;
+ return type->size;
+}
+
+
+ANN static inline m_uint exp_totalsize(Exp e) {
+ m_uint size = 0;
+ do size += exp_size(e);
+ while((e = e->next));
+ return size;
+}
+
+ANN static Instr emit_addref(const Emitter emit, const m_bool emit_var) {
+ const f_instr exec = !emit_var ? RegAddRef : RegAddRefAddr;
+ const Instr instr = emit_add_instr(emit, exec);
+ instr->m_val = -SZ_INT;
+ return instr;
+}
+
+ANN static void struct_addref(const Emitter emit, const Type type,
+ const m_int size, const m_bool offset, const m_bool emit_var) {
+ if(!type->info->tuple)
+ return;
+ 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) {
+ const Instr instr = emit_addref(emit, emit_var);
+ instr->m_val = size;
+ instr->m_val2 = vector_at(&type->info->tuple->offset, i);
+ } else if(tflag(t, tflag_struct))
+ struct_addref(emit, t, size, offset + vector_at(&type->info->tuple->offset, i), emit_var);
+ }
+}
+
+ANN2(1) static void emit_exp_addref1(const Emitter emit, /* const */Exp exp, m_int size) {
+ if(isa(exp->info->type, emit->gwion->type[et_object]) > 0 &&
+ (exp->info->cast_to ? isa(exp->info->cast_to, emit->gwion->type[et_object]) > 0 : 1)) {
+ if(exp->exp_type == ae_exp_decl && GET_FLAG(exp->d.exp_decl.td, ref) && !exp_getvar(exp)) {
+ const Instr instr = emit_add_instr(emit, GWOP_EXCEPT);
+ instr->m_val = size;
+ }
+ const Instr instr = emit_addref(emit, exp_getvar(exp));
+ instr->m_val = size;
+ } else if(tflag(exp->info->type, tflag_struct)) // check cast_to ?
+ struct_addref(emit, exp->info->type, size, 0, exp_getvar(exp));
+}
+
+ANN2(1) static void emit_exp_addref(const Emitter emit, /* const */Exp exp, m_int size) {
+ do {
+ emit_exp_addref1(emit, exp, size);
+ size += exp_size(exp);
+ } while((exp = exp->next));
+}
+
ANN static m_bool emit_prim_array(const Emitter emit, const Array_Sub *data) {
Exp e = (*data)->exp;
CHECK_BB(emit_exp(emit, e))
+ emit_exp_addref(emit, e, -exp_totalsize(e));
m_uint count = 0;
do ++count;
while((e = e->next));
return GW_OK;
}
-ANN static Instr emit_addref(const Emitter emit, const m_bool emit_var) {
- const f_instr exec = !emit_var ? RegAddRef : RegAddRefAddr;
- const Instr instr = emit_add_instr(emit, exec);
- instr->m_val = -SZ_INT;
- return instr;
-}
-
ANN static m_bool emit_prim_str(const Emitter emit, const m_str *str) {
char c[strlen(*str) + 1];
if(strlen(*str)) {
CHECK_BB(emit_exp_decl_non_static(emit, decl, list->self, ref, var))
else
CHECK_BB(emit_exp_decl_global(emit, decl, list->self, ref, var))
- if(!var && !decl->td->option && (GET_FLAG(decl->td, ref) || is_fptr(emit->gwion, list->self->value->type)))
- ERR_B(list->self->pos, "kljlkj")
} while((list = list->next));
return GW_OK;
}
free_vector(emit->gwion->mp, kinds);
}
-ANN static inline m_uint exp_size(Exp e);
-ANN static inline m_uint exp_totalsize(Exp e) {
- m_uint size = 0;
- do size += exp_size(e);
- while((e = e->next));
- return size;
-}
-ANN static /*inline */void emit_exp_addref1(const Emitter emit, Exp, const m_int size);
-ANN static /*inline */void emit_exp_addref(const Emitter emit, Exp, const m_int size);
-
ANN static m_bool emit_func_args(const Emitter emit, const Exp_Call* exp_call) {
if(exp_call->args) {
CHECK_BB(emit_exp(emit, exp_call->args))
if(vector_size(&emit->code->instr) && vflag(f->value_ref, vflag_member) &&
is_fptr(emit->gwion, f->value_ref->type)) {
const Instr back = (Instr)vector_back(&emit->code->instr);
- m_bit exec = back->opcode;
- m_uint val = back->m_val;
- m_uint val2 = back->m_val2;
- back->opcode = eReg2Reg;
- back->m_val2 = -SZ_INT;
+ const Instr base = back->opcode != eGWOP_EXCEPT ?
+ back : (Instr)vector_at(&emit->code->instr, vector_size(&emit->code->instr) -2);
+ const m_bit exec = base->opcode;
+ const m_uint val = base->m_val;
+ const m_uint val2 = base->m_val2;
+ base->opcode = eReg2Reg;
+ base->m_val2 = -SZ_INT;
regpush(emit, SZ_INT);
const Instr instr = emit_add_instr(emit, (f_instr)(m_uint)exec);
instr->m_val = val;
return ret;
}
-ANN static void struct_addref(const Emitter emit, const Type type,
- const m_int size, const m_bool offset, const m_bool emit_var) {
- if(!type->info->tuple)
- return;
- 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) {
- const Instr instr = emit_addref(emit, emit_var);
- instr->m_val = size;
- instr->m_val2 = vector_at(&type->info->tuple->offset, i);
- } else if(tflag(t, tflag_struct))
- struct_addref(emit, t, size, offset + vector_at(&type->info->tuple->offset, i), emit_var);
- }
-}
-
-ANN static inline m_uint exp_size(const Exp e) {
- if(exp_getvar(e))
- return SZ_INT;
- const Type type = e->info->cast_to ?: e->info->type;
- return type->size;
-}
-
-ANN2(1) static void emit_exp_addref1(const Emitter emit, /* const */Exp exp, m_int size) {
- if(isa(exp->info->type, emit->gwion->type[et_object]) > 0 &&
- (exp->info->cast_to ? isa(exp->info->cast_to, emit->gwion->type[et_object]) > 0 : 1)) {
- const Instr instr = emit_addref(emit, exp_getvar(exp));
- instr->m_val = size;
- } else if(tflag(exp->info->type, tflag_struct)) // check cast_to ?
- struct_addref(emit, exp->info->type, size, 0, exp_getvar(exp));
-}
-
-ANN2(1) static void emit_exp_addref(const Emitter emit, /* const */Exp exp, m_int size) {
- do {
- emit_exp_addref1(emit, exp, size);
- size += exp_size(exp);
- } while((exp = exp->next));
-}
-
-
ANN static inline m_bool emit_prim_novar(const Emitter emit, const Exp_Primary *prim) {
const Exp e = exp_self(prim);
const uint var = exp_getvar(e);
const Value v = prim->value;
CHECK_BB(emit_prim_novar(emit, prim));
if(isa(prim->value->type, emit->gwion->type[et_compound]) > 0) {
- emit_exp_addref1(emit, exp_self(prim), -v->type->size);
if(vflag(v, vflag_fglobal) && !vflag(v, vflag_closed))
emit_exp_addref1(emit, exp_self(prim), -v->type->size);
map_set(&func->code->closure->m, (vtype)v->type, VVAL(map, i));
const Instr instr = emit_add_instr(emit, RegPushImm);
instr->m_val = (m_uint)value->type;
}
+ if(GET_FLAG(value, ref)) {
+ const Instr instr = emit_add_instr(emit, GWOP_EXCEPT);
+ instr->m_val = -SZ_INT;
+ }
return (Instr)GW_OK;
}
free_class_def(env->gwion->mp, cdef);
return ret;
}
-/*
-ANN static OP_CHECK(opck_option_get) {
- Exp_Binary *bin = (Exp_Binary*)data;
- exp_setvar(bin->rhs, 1);
- return bin->rhs->info->type;
-}
-
-static INSTR(OptionCheck) {
- const M_Object o = *(M_Object*)REG(-SZ_INT*2);
- if(*(m_uint*)(o->data) != instr->m_val2)
- Except(shred, "invalid union access");
- memcpy(*(m_bit**)REG(-SZ_INT), o->data + SZ_INT, instr->m_val);
- POP_REG(shred, SZ_INT*2 - instr->m_val);
- memcpy(&*(m_bit*)REG(-instr->m_val), o->data + SZ_INT, instr->m_val);
-}
-
-ANN static OP_EMIT(opem_option_get) {
- Exp_Binary *bin = (Exp_Binary*)data;
- const Instr instr = emit_add_instr(emit, OptionCheck);
- instr->m_val = bin->rhs->info->type->size;
- instr->m_val2 = 1;
- return instr;
-}
-
-ANN static OP_CHECK(opck_option_set) {
- Exp_Binary *bin = (Exp_Binary*)data;
- CHECK_NN(opck_rassign(env, data, mut)) // check those two lines
- exp_setvar(bin->rhs, 0);
- const Type rhs = bin->rhs->info->type;
- const Nspc nspc = bin->lhs->info->type->nspc;
- for(m_uint i = 0; i < nspc->info->class_data_size; i += SZ_INT) {
- if(rhs == *(Type*)(nspc->info->class_data + i))
- return rhs;
- }
-// ERR_N(exp_self(data)->pos, _(
-// const Value v = nspc_lookup_value0(bin->rhs->info->type->nspc, insert_symbol(env->gwion->st, "@val"));
-// return v->type;
-}
-
-static INSTR(OptionSet) {
- M_Object o = *(M_Object*)REG(-SZ_INT);
- *(m_uint*)(o->data) = instr->m_val2;
- *(m_bit**)(o->data + SZ_INT) = *(void**)REG(-instr->m_val);
-}
-
-ANN static OP_EMIT(opem_option_set) {
- Exp_Binary *bin = (Exp_Binary*)data;
- const Value v = nspc_lookup_value0(bin->rhs->info->type->nspc, insert_symbol(emit->gwion->st, "@val"));
- const Instr set = emit_add_instr(emit, OptionSet);
- set->m_val = SZ_INT + v->type->size;
- set->m_val2 = 1;
- const Instr pop = emit_add_instr(emit, RegPop);
- pop->m_val = SZ_INT;
- return set;
-}
-
-ANN static OP_CHECK(opck_option_setn) {
- Exp_Binary *bin = (Exp_Binary*)data;
- CHECK_NN(opck_rassign(env, data, mut))
- exp_setvar(bin->rhs, 1);
- return env->gwion->type[et_void];
-}
-
-ANN static OP_EMIT(opem_option_setn) {
- Exp_Binary *bin = (Exp_Binary*)data;
- const Instr instr = emit_add_instr(emit, OptionSet);
- instr->m_val = bin->rhs->info->type->nspc->info->offset;
- const Instr pop2 = emit_add_instr(emit, RegPop);
- pop2->m_val = SZ_INT * 2;
- return instr;
-}
-
-ANN static OP_EMIT(opem_option_not) {
- Exp_Unary *unary = (Exp_Unary*)data;
- const Instr pop = emit_add_instr(emit, RegPop);
- pop->m_val = unary->exp->info->type->size - SZ_INT;
- return emit_add_instr(emit, IntNot);
-}
-
-ANN static OP_EMIT(opem_option_cond) {
- Exp exp = (Exp)data;
- const Instr pop = emit_add_instr(emit, RegPop);
- pop->m_val = exp->info->type->size - SZ_INT;
- return emit_add_instr(emit, BranchEqInt);
-}
-
-ANN static OP_EMIT(opem_option_uncond) {
- Exp exp = (Exp)data;
- const Instr pop = emit_add_instr(emit, RegPop);
- pop->m_val = exp->info->type->size - SZ_INT;
- return emit_add_instr(emit, BranchNeqInt);
-}
-*/
ANN static m_bool scantmpl_union_def(const Env env, struct tmpl_info *info) {
const Union_Def u = info->base->info->udef;
return GW_OK;
}
+ANN static void set_late(const Gwion gwion, const Exp_Decl *decl, const Value v) {
+ if(!exp_getvar(exp_self(decl)) &&
+ (GET_FLAG(decl->td, ref) || is_fptr(gwion, v->type))) {
+ SET_FLAG(decl->td, ref);
+ SET_FLAG(v, ref);
+ } else
+ UNSET_FLAG(v, ref);
+}
+
ANN static m_bool check_decl(const Env env, const Exp_Decl *decl) {
Var_Decl_List list = decl->list;
do {
CHECK_BB(check_var_td(env, var, decl->td))
if(is_fptr(env->gwion, decl->type))
CHECK_BB(check_fptr_decl(env, var))
+ set_late(env->gwion, decl, list->self->value);
set_vflag(var->value, vflag_valid);
//set_vflag(var->value, vflag_used));
nspc_add_value(env->curr, var->xid, var->value);
ANN m_bool func_check(const Env env, const Exp_Call *exp) {
CHECK_OB(check_exp(env, exp->func))
+ if(exp->func->exp_type == ae_exp_decl)
+ ERR_B(exp->func->pos, _("Can't call late function pointer at declaration site"))
const Type t = actual_type(env->gwion, exp->func->info->type);
const Exp e = exp_self(exp);
struct Op_Import opi = { .op=insert_symbol("@func_check"),