}
ANN static void free_code(MemPool p, Code *code) {
++// we should use instr destructors
if(code->instr.ptr) vector_release(&code->instr);
vector_release(&code->stack_break);
vector_release(&code->stack_cont);
is_ref));
return GW_OK;
} else if (!is_ref) {
-- if(!tflag(type, tflag_typedef) || isa(type, emit->gwion->type[et_closure]) > 0) {
++ if(!tflag(type, tflag_typedef) || isa(type, emit->gwion->type[et_closure]) > 0 ||
++ tflag(type, tflag_union)) {
const Instr instr = emit_add_instr(emit, ObjectInstantiate);
instr->m_val2 = (m_uint)type;
} // maybe we should instantiate the first actual type
ANN static m_bool _emit_symbol(const Emitter emit, const Symbol *data) {
const Value v = prim_self(data)->value;
++
++//else
++if(emit->env->class_def && safe_vflag(v, vflag_fglobal) && !emit->env->scope->depth) {
++emit->env->class_def->wait--;
++printf("=> %s\n", s_name(*data));
++ }
if (is_class(emit->gwion, v->type)) {
emit_pushimm(emit, (m_uint)actual_type(emit->gwion, v->type));
return GW_OK;
return code;
}
++ANN static VM_Code finalyze_func(const Emitter emit, const f_instr exec, const Func f) {
++ const VM_Code code = finalyze(emit, exec);
++ code->wait = f->wait;
++ return code;
++}
++
ANN static inline m_uint exp_size(const Exp e) {
if (exp_getvar(e)) return SZ_INT;
const Type type = e->cast_to ?: e->type;
ANN /*static*/ m_bool emit_interp(const Emitter emit, const Exp exp) {
emit_pushimm(emit, 0);
++ emit_local(emit, emit->gwion->type[et_int]);
Exp e = exp, next = NULL;
do {
next = e->next;
vm_run(emit->gwion->vm);
emit->gwion->vm->bbq->is_running = true;
const m_float ret = *(m_float*)shred->reg;
++ release(shred->info->me, shred);
if(ret == -1.0)
ERR_B(prim_pos(id), "error in locale");
const Instr instr = emit_add_instr(emit, RegPushImm2);
}
}
++static INSTR(UsedBy) {
++ const MP_Vector *v =(MP_Vector*)instr->m_val;
++ for(uint32_t i = 0; i < v->len; i++) {
++ const Func f = *mp_vector_at(v, Func, i);
++ f->code->wait--;
++ }
++}
++
ANN static m_bool emit_exp_decl_non_static(const Emitter emit,
const Exp_Decl *decl,
const Var_Decl *var_decl,
f_instr *exec = (f_instr *)allocmember;
if (!emit->env->scope->depth) emit_debug(emit, v);
if (!vflag(v, vflag_member)) {
++if(v->used_by) { // maybe later
++ const Instr instr = emit_add_instr(emit, UsedBy);
++ instr->m_val = (m_uint)v->used_by;
++}
v->from->offset = decl_non_static_offset(emit, decl, type);
exec = (f_instr *)(allocword);
if (GET_FLAG(v, late)) { // ref or emit_var ?
if (type->size > SZ_INT)
v->d.ptr = mp_calloc2(emit->gwion->mp, v->type->size);
emit_dotstatic(emit, (m_uint)&v->d.ptr, v->type->size, !struct_ctor(v) ? emit_addr : 1);
-- set_vflag(v, vflag_direct); // mpalloc
++// set_vflag(v, vflag_direct); // mpalloc // set in check.c
if (is_obj && !is_ref) {
const Instr assign = emit_add_instr(emit, Assign);
assign->m_val = emit_var;
const Type t = decl->type;
if(decl->args && !strncmp(decl->args->type->name, "partial:", 8))
ERR_B(decl->args->pos, "unresolved partial");
++// if(t->wait) exit(3);
++ if(t->wait) { puts(t->name); puts(decl->vd.value->name); /*exit(3); */}
CHECK_BB(ensure_emit(emit, t));
const m_bool global = GET_FLAG(decl->td, global);
const m_uint scope =
!global ? emit->env->scope->depth : emit_push_global(emit);
const m_bool ret = emit_decl(emit, decl);
if (global) emit_pop(emit, scope);
-- if(isa(t, emit->gwion->type[et_object]) > 0 && emit->status.in_return && GET_FLAG(decl->vd.value, late))
++ if(emit->status.in_return && GET_FLAG(decl->vd.value, late) && isa(t, emit->gwion->type[et_object]) > 0)
emit_add_instr(emit, GWOP_EXCEPT);
return ret;
}
.pos = exp_self(call)->pos};
CHECK_BB(op_emit(emit, &opi));
}
--
const Func f = t->info->func;
if(unlikely(is_new_struct(f, exp_self(call)->type)))
emit_new_struct(emit, call);
const Exp rhs = bin->rhs;
CHECK_BB(emit_exp_pop_next(emit, lhs));
CHECK_BB(emit_exp_pop_next(emit, rhs));
-- // const m_int size = exp_size(rhs);
-- // emit_exp_addref1(emit, lhs, -exp_size(lhs) - size);
-- // emit_exp_addref1(emit, rhs, -size);
struct Op_Import opi = {.op = bin->op,
.lhs = lhs->type,
.rhs = rhs->type,
if(unlikely(fflag(f, fflag_fptr))) emit_fptr_call(emit, f);
else if (unlikely(!f->code && emit->env->func != f)) {
if (fflag(f, fflag_tmpl)) CHECK_BB(emit_template_code(emit, f));
-- else CHECK_BB(emit_ensure_func(emit, f));
++ else //if(is_new(f->def))//if(tflag(f->value_ref->type, tflag_ftmpl))
++{
++const Type t = f->value_ref->from->owner_class;
++if(t && (!emit->env->curr || isa(t, emit->env->class_def) < 0))
++//!is_new(f->def) || f->value_ref->from->owner_class->array_depth)
++//if(f->value_ref->from->owner_class->array_depth)
++CHECK_BB(emit_ensure_func(emit, f));
++}
} else if(is_static)
push_func_code(emit, f);
call_finish(emit, f, is_static);
}
ANN static VM_Code emit_internal(const Emitter emit, const Func f) {
++// use wait everywhere
if (f->def->base->xid == insert_symbol("@dtor")) {
-- emit->env->class_def->nspc->dtor = f->code = finalyze(emit, DTOR_EOC);
++ emit->env->class_def->nspc->dtor = f->code = finalyze_func(emit, DTOR_EOC, f);
vmcode_addref(f->code);
return f->code;
} else if (f->def->base->xid == insert_symbol("@gack")) {
emit_regmove(emit, -SZ_INT - f->value_ref->from->owner_class->size);
const Instr instr = emit_add_instr(emit, RegPushMem);
instr->m_val = SZ_INT;
-- f->code = finalyze(emit, FuncReturn);
++ f->code = finalyze_func(emit, FuncReturn, f);
return emit->env->class_def->info->gack = f->code;
}
-- return finalyze(emit, FuncReturn);
++ return finalyze_func(emit, FuncReturn, f);
}
ANN static inline VM_Code _emit_func_def_code(const Emitter emit,
instr->m_val2 = t->size;
}
}
-- return !fbflag(func->def->base, fbflag_internal) ? finalyze(emit, FuncReturn)
++// return !fbflag(func->def->base, fbflag_internal) ? finalyze(emit, FuncReturn)
++// : emit_internal(emit, func);
++ const VM_Code code = !fbflag(func->def->base, fbflag_internal) ? finalyze_func(emit, FuncReturn, func)
: emit_internal(emit, func);
++ code->wait = func->wait;
++ return code;
}
ANN static VM_Code emit_func_def_code(const Emitter emit, const Func func) {
// change to *no know constructor for {+G}%s{0}*?
ERR_N(call->func->pos, _("can't call a non-callable value"));
}
--
++/*
static OP_EMIT(opem_implicit_class) {
struct Implicit *imp = (struct Implicit*)data;
const Type t = actual_type(emit->gwion, imp->e->type);
emit_pushimm(emit, map_size(&t->nspc->info->value->map));
-- return GW_OK; emit_exp(emit, imp->e);
++ return GW_OK;
}
static OP_CHECK(opck_implicit_class) {
struct Implicit *imp = (struct Implicit*)data;
const Type t = actual_type(env->gwion, imp->e->type);
++ if(isa(t, env->gwion->type[et_enum]) > 0) return imp->e->type;
return env->gwion->type[et_error];
}
--
++*/
GWION_IMPORT(class) {
gwidoc(gwi, "Operators class types.");
GWI_BB(gwi_oper_ini(gwi, NULL, (m_str)OP_ANY_TYPE, NULL))
GWI_BB(gwi_oper_add(gwi, opck_basic_ctor))
GWI_BB(gwi_oper_end(gwi, "@ctor", NULL))
--
++/*
gwidoc(gwi, "Allow enum for array size");
GWI_BB(gwi_oper_ini(gwi, "Class", "int", NULL))
GWI_BB(gwi_oper_add(gwi, opck_implicit_class))
GWI_BB(gwi_oper_emi(gwi, opem_implicit_class))
GWI_BB(gwi_oper_end(gwi, "@implicit", NULL))
--
++*/
return GW_OK;
}
const Symbol var = *data;
const Value value = get_value(env, var);
if (env->class_def) {
-- if (value && value->from->owner_class)
-- CHECK_BO(
-- not_from_owner_class(env, env->class_def, value, prim_pos(data)));
++ if (value) {
++ if(value->from->owner_class)
++ CHECK_BO(not_from_owner_class(env,
++ env->class_def, value, prim_pos(data)));
++ else if(safe_vflag(value, vflag_fglobal) && !env->scope->depth)
++ env->class_def->wait++;
++ }
const Value v = value ?: find_value(env->class_def, var);
if (v) {
if (env->func && GET_FLAG(env->func->def->base, static) &&
prim_self(data)->value = v;
if (v->from->owner_class) return prim_owned(env, data);
if (GET_FLAG(v, const)) exp_setmeta(prim_exp(data), 1);
-- if (env->func) {
++
++ if (env->func && strcmp(env->func->name, "in spork")) {
++ if(vflag(v, vflag_fglobal) /*&& !vflag(v, vflag_builtin) */&& !is_func(env->gwion, v->type)) {
++ if (!v->used_by) {
++ v->used_by = new_mp_vector(env->gwion->mp, Func, 1);
++ mp_vector_set(v->used_by, Func, 0, env->func);
++ env->func->wait++;
++ } else {
++ bool found = false;
++ for(uint32_t i = 0; i < v->used_by->len; i++) {
++ const Func f = *mp_vector_at(v->used_by, Func, i);
++ if(f == env->func) {
++ found = true;
++ break;
++ }
++ }
++ if(!found) {
++ env->func->wait++;
++ mp_vector_add(env->gwion->mp, &v->used_by, Func, env->func);
++ }
++ }
++ }
++
if (!GET_FLAG(v, const) && v->from->owner)
unset_fflag(env->func, fflag_pure);
if (fbflag(env->func->def->base, fbflag_lambda))
.rhs = t,
.pos = e->pos,
.data = (uintptr_t)e};
-- CHECK_NB(op_check(env, &opi)); // doesn't really return NULL
++ if(op_get(env, &opi))
++ CHECK_OB(op_check(env, &opi));
if (e->exp_type != ae_exp_call) return 0;
return e->type != env->gwion->type[et_error] ? GW_OK : GW_ERROR;
}
const ValueFrom *from = t->info->value->from;
if(from->owner_class && isa(from->owner_class, env->class_def) > 0)
return true;
-- if(!GET_FLAG(t, global) && !from_global_nspc(env, from->owner)) {
-- if(from->owner_class && type_global(env, from->owner_class))
++ if(from_global_nspc(env, from->owner) ||
++ (from->owner_class && type_global(env, from->owner_class)))
return true;
-- gwerr_basic("can't use non-global type in a global class", NULL, NULL, env->name, pos, 0);
-- gwerr_secondary_from("not declared global", from);
-- const ValueFrom *ownerFrom = env->class_def->info->value->from;
-- gwerr_secondary_from("is global", ownerFrom);
-- env_set_error(env, true);
-- return false;
-- }
-- return true;
++ gwerr_basic("can't use non-global type in a global class", NULL, NULL, env->name, pos, 0);
++ gwerr_secondary_from("not declared global", from);
++ const ValueFrom *ownerFrom = env->class_def->info->value->from;
++ gwerr_secondary_from("is global", ownerFrom);
++ env_set_error(env, true);
++ return false;
}
ANN static Type scan1_type(const Env env, Type_Decl *td) {
static inline m_bool scan1_defined(const Env env, const Var_Decl *var) {
if (var->value) // from an auto declaration
return GW_OK;
-- if (((!env->class_def || !GET_FLAG(env->class_def, final) ||
++ const Value v = ((!env->class_def || !GET_FLAG(env->class_def, final) ||
env->scope->depth)
? nspc_lookup_value1
-- : nspc_lookup_value2)(env->curr, var->xid))
++ : nspc_lookup_value2)(env->curr, var->xid);
++ if(v && (!v->from->owner_class || isa(env->class_def, v->from->owner_class) > 0))
ERR_B(var->pos,
_("variable %s has already been defined in the same scope..."),
s_name(var->xid))