--- /dev/null
+-Iutil/include
+-Iast/include
+-Iinclude
+-Ifmt/include
Value value_ref;
Func next;
m_str name;
- uint32_t wait;
+ MP_Vector *_wait;
float inline_mult;
uint16_t weight; // used to mark gack use in scan1
uint16_t memoize; // used to mark return in scan1
uint16_t ref;
-// uint16_t vt_index;
ae_flag flag;
enum fflag fflag;
};
}
ANN static inline m_uint captures_sz(const Capture_List captures) {
- const Capture *cap = mp_vector_at(captures, Capture, (captures->len - 1));
+ const Capture *cap = mp_vector_back(captures, Capture);
return cap->temp->from->offset + cap->temp->type->size;
}
+
+ANN static inline bool is_ctor(const Func_Def fdef) {
+ return !strcmp(s_name(fdef->base->xid), "@ctor");
+}
#endif
struct TypeInfo_ *info;
uint64_t size;
uint64_t actual_size;
- struct Vector_ effects; // pre-ctor effects
-// struct MP_Vector *wait;
- uint32_t wait;
+// struct Vector_ effects; // pre-ctor effects
uint32_t array_depth;
uint16_t ref;
uint16_t weight;
INSTR(SetFunc);
INSTR(SetCtor);
+INSTR(FuncWait);
#include "opcode.h"
INSTR(dict_ctor_alt);
}
ANN static inline bool not_upvalue(const Env env, const Value v) {
+ if (unlikely(is_class(env->gwion, v->type))) return true;
return GET_FLAG(v, global) || vflag(v, vflag_fglobal) ||
(v->from->owner_class && isa(v->from->owner_class, env->class_def) > 0) ||
nspc_lookup_value1(env->curr, insert_symbol(v->name));
m_str name;
struct Map_ handlers;
struct M_Vector_ live_values;
- uint32_t wait;
uint16_t stack_depth;
uint16_t ref;
// bool is_prepared;
ANN m_str code_name(const m_str, const bool);
ANN uint32_t gw_rand(uint32_t s[2]);
ANN void gw_seed(uint32_t s[2], const uint64_t);
-ANN void handle(VM_Shred shred, const m_str effect);
+ANN bool handle(VM_Shred shred, const m_str effect);
#define xfun_handle(shred, effect) {\
shred->mem -= ((Instr)vector_at(&shred->code->instr, shred->pc-1))->m_val2; \
handle(shred, effect); \
ANN /*static inline*/ m_bool ensure_emit(const Emitter emit, const Type t) {
if (tflag(t, tflag_emit) || !(tflag(t, tflag_cdef) || tflag(t, tflag_udef)))
return GW_OK; // clean callers
-if(!tflag(t, tflag_tmpl))return GW_OK;
+ if(!tflag(t, tflag_tmpl))return GW_OK;
struct EnvSet es = {.env = emit->env,
.data = emit,
.func = (_exp_func)emit_cdef,
}
const m_uint offset = emit_code_offset(emit);
emit_setimm(emit, offset, SZ_INT*2);
- emit_regmove(emit, SZ_INT * 2);
+ emit_regmove(emit, SZ_INT*2);
const Instr prelude = emit_add_instr(emit, SetCode);
prelude->m_val = -SZ_INT * 2;
prelude->udata.one = 2;
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);
- 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 inline int struct_ctor(const Value v) {
- return tflag(v->type, tflag_struct) && v->type->nspc && v->type->nspc->pre_ctor;
-// return tflag(v->type, tflag_struct) && v->type->nspc->pre_ctor;
+ return tflag(v->type, tflag_struct) && tflag(v->type, tflag_ctor);
}
ANN static void decl_expand(const Emitter emit, const Type t) {
CHECK_BB(emit_exp(emit, decl->args));
if (emit_addr) {
emit_regmove(emit, -t->size);
- emit_regpushmem4(emit, 0, 0);
+ emit_regpushmem4(emit, decl->vd.value->from->offset, 0);
}
return GW_OK;
}
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--;
+ const Instr instr = (Instr)vector_front(&f->code->instr);
+ instr->m_val2++;
}
}
+ANN static void used_by(const Emitter emit, const Value v) {
+ MP_Vector *vec = new_mp_vector(emit->gwion->mp, Func, 0);
+ for(uint32_t i = 0; i < v->used_by->len; i++) {
+ const Func f = *mp_vector_at(v->used_by, Func, i);
+ if(f->_wait) mp_vector_add(emit->gwion->mp, &vec, Func, f);
+ }
+ free_mp_vector(emit->gwion->mp, Func, v->used_by);
+ v->used_by = vec;
+ if(vec->len) {
+ const Instr instr = emit_add_instr(emit, UsedBy);
+ instr->m_val = (m_uint)vec;
+ }
+}
ANN static m_bool emit_exp_decl_non_static(const Emitter emit,
const Exp_Decl *decl,
const Var_Decl *var_decl,
const bool is_obj = isa(type, emit->gwion->type[et_object]) > 0;
const bool emit_addr = (!is_obj || is_ref) ? emit_var : true;
if (is_obj && !is_ref && !exp_self(decl)->ref) {
-// if (is_obj && ((is_array && !exp_self(decl)->ref) || !is_ref))
if(!decl->args) CHECK_BB(emit_instantiate_decl(emit, type, decl->td, is_ref));
else CHECK_BB(emit_exp(emit, decl->args));
}
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;
-}
+ if(v->used_by) used_by(emit, v);
v->from->offset = decl_non_static_offset(emit, decl, type);
exec = (f_instr *)(allocword);
if (GET_FLAG(v, late)) { // ref or emit_var ?
const Instr instr = emit_add_instr(emit, Reg2Reg);
instr->m_val = -SZ_INT;
}
- if(safe_tflag(emit->env->class_def, tflag_struct) && GET_FLAG(emit->env->class_def, global))
- emit_object_addref(emit, 0, emit_addr);
+// if(safe_tflag(emit->env->class_def, tflag_struct) && GET_FLAG(emit->env->class_def, global))
+// emit_object_addref(emit, 0, emit_addr);
} else if (tflag(v->type, tflag_struct))
CHECK_BB(struct_finish(emit, decl));
return GW_OK;
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 in check.c
+ if(v->used_by) used_by(emit, v);
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 =
else if(tflag(t, tflag_ctor))
emit_regpushmem4(emit, offset, 0);
if(tflag(t, tflag_ctor)) emit_ext_ctor(emit, t);
- else if(!back) {
+ else if(!back) {
emit_regmove(emit, -SZ_INT + t->size);
emit_regpushmem4(emit, offset, 0);
}
ANN static inline void emit_func_def_init(const Emitter emit, const Func func) {
emit_push_code(emit, func->name);
+ if(mp_vector_len(func->_wait)) {
+ const Instr instr = emit_add_instr(emit, FuncWait);
+ instr->m_val = (m_uint) func;
+ }
}
ANN static void emit_func_def_args(const Emitter emit, Arg_List args) {
}
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_func(emit, DTOR_EOC, f);
- vmcode_addref(f->code);
- return f->code;
- } else if (f->def->base->xid == insert_symbol("@gack")) {
+ if (f->def->base->xid == insert_symbol("@dtor"))
+ return emit->env->class_def->nspc->dtor = finalyze(emit, DTOR_EOC);
+ 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_func(emit, FuncReturn, f);
+ f->code = finalyze(emit, FuncReturn);
return emit->env->class_def->info->gack = f->code;
}
- return finalyze_func(emit, FuncReturn, f);
+ return finalyze(emit, FuncReturn);
}
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)
-// : emit_internal(emit, func);
- const VM_Code code = !fbflag(func->def->base, fbflag_internal) ? finalyze_func(emit, FuncReturn, func)
+ const VM_Code code = !fbflag(func->def->base, fbflag_internal) ? finalyze(emit, FuncReturn)
: emit_internal(emit, func);
- code->wait = func->wait;
+ if(is_ctor(func->def) && !emit->env->class_def->nspc->pre_ctor)
+ emit->env->class_def->nspc->pre_ctor = code;
return code;
}
if (fdef->base->args) emit_func_def_args(emit, fdef->base->args);
if (fdef->d.code) {
if(!fdef->builtin) {
- scoped_ini(emit);
+ const bool ctor = is_ctor(fdef);
+ if(!ctor)
+ scoped_ini(emit);
const m_bool ret = emit_stmt_list(emit, fdef->d.code);
- scoped_end(emit);
+ if(!ctor)
+ scoped_end(emit);
CHECK_BB(ret);
}
else fdef->base->func->code = (VM_Code)vector_at(&fdef->base->func->value_ref->from->owner_class->nspc->vtable, fdef->vt_index);
if(fdef->builtin) {
fdef->base->func->code = new_vmcode(emit->gwion->mp, NULL, NULL, func->name, fdef->stack_depth, true, false);
fdef->base->func->code->native_func = (m_uint)fdef->d.dl_func_ptr;
+ if(is_ctor(fdef))
+ emit->env->class_def->nspc->pre_ctor = fdef->base->func->code;
return GW_OK;
}
if ((vflag(func->value_ref, vflag_builtin) &&
if (c->base.ext && t->info->parent->info->cdef &&
!tflag(t->info->parent, tflag_emit)) // ?????
CHECK_BB(cdef_parent(emit, c));
- if (c->body) {
- emit_class_code(emit, t->name);
- const m_bool ret = scanx_body(emit->env, c, (_exp_func)emit_section, emit);
- if (ret > 0 && tflag(t, tflag_ctor))
- t->nspc->pre_ctor = finalyze(emit, FuncReturn);
- else{
- free_code(emit->gwion->mp, emit->code);
- emit_pop_code(emit);
- }
- return ret;
- }
+ if (c->body)
+ return scanx_body(emit->env, c, (_exp_func)emit_section, emit);
return GW_OK;
}
ANN void free_func(Func a, Gwion gwion) {
if (fflag(a, fflag_tmpl)) func_def_cleaner(gwion, a->def);
if (a->code) vmcode_remref(a->code, gwion);
+ if (a->_wait) free_mp_vector(gwion->mp, Value, a->_wait);
mp_free(gwion->mp, Func, a);
}
}
// if (tflag(a, tflag_cdef) && a->info->parent)
// type_remref(a->info->parent, gwion);
- if (a->effects.ptr) vector_release(&a->effects);
if (a->nspc) nspc_remref(a->nspc, gwion);
if (a->info->tuple) free_tupleform(a->info->tuple, gwion);
mp_free(gwion->mp, TypeInfo, a->info);
}
ANN void env_error_footer(const Env env) {
- if (env->class_def && tflag(env->class_def, tflag_cdef))
+ bool ctor = false;
+ if (env->func && env->func->def) {
+ if(!is_ctor(env->func->def))
+ gwerr_secondary("in function", env->name, env->func->def->base->pos);
+ else {
+ gwerr_secondary("in class pre constructor", env->name, env->class_def->info->cdef->pos);
+ ctor = true;
+ }
+ }
+ if (!ctor && env->class_def && tflag(env->class_def, tflag_cdef))
gwerr_secondary("in class", env->name, env->class_def->info->cdef->pos);
- if (env->func && env->func->def)
- gwerr_secondary("in function", env->name, env->func->def->base->pos);
}
ANN static void env_xxx(const Env env, const loc_t pos, const m_str fmt,
#include "specialid.h"
#include "template.h"
-ANN static m_bool mk_xtor(MemPool p, const Type type, const m_uint d,
- const enum tflag e) {
- VM_Code *code = e == tflag_ctor ? &type->nspc->pre_ctor : &type->nspc->dtor;
- const m_str name = type->name;
- *code = new_vmcode(p, NULL, NULL, name, SZ_INT, true, false);
- (*code)->native_func = (m_uint)d;
- type->tflag |= e;
+ANN static m_bool mk_dtor(MemPool p, const Type t, const m_uint d) {
+ VM_Code code = t->nspc->dtor = new_vmcode(p, NULL, NULL, t->name, SZ_INT, true, false);
+ code->native_func = (m_uint)d;
+ set_tflag(t, tflag_dtor);
return GW_OK;
}
ANN2(1)
void gwi_class_xtor(const Gwi gwi, const f_xtor ctor, const f_xtor dtor) {
const Type t = gwi->gwion->env->class_def;
- if (ctor) mk_xtor(gwi->gwion->mp, t, (m_uint)ctor, tflag_ctor);
- if (dtor) mk_xtor(gwi->gwion->mp, t, (m_uint)dtor, tflag_dtor);
+ if (dtor) mk_dtor(gwi->gwion->mp, t, (m_uint)dtor);
+ if (ctor) {
+ gwi_func_ini(gwi, "void", "@ctor");
+ gwi_func_end(gwi, ctor, ae_flag_none);
+ if(t->nspc->vtable.ptr) {
+ set_tflag(t, tflag_ctor);
+ const Func f = (Func)vector_front(&t->nspc->vtable);
+ t->nspc->pre_ctor = f->code;
+ }
+ }
}
ANN static inline void gwi_type_flag(const Type t) {
--gwi->tmpls;
nspc_pop_type(gwi->gwion->mp, gwi->gwion->env->curr);
}
+/*
+// we need to use @ctor
if (gwi->effects.ptr) {
vector_init(&t->effects);
vector_copy2(&gwi->effects, &t->effects);
vector_release(&gwi->effects);
}
+*/
env_pop(gwi->gwion->env, 0);
return GW_OK;
}
}
static CTOR(fptr_ctor) {
- *(VM_Code*)o->data = ((Func)vector_front(&o->type_ref->nspc->vtable))->code;
+ *(VM_Code*)o->data = ((Func)vector_at(&o->type_ref->nspc->vtable, 1))->code;
}
ANN m_bool tmpl_fptr(const Env env, const Fptr_Def fptr, const Func_Def fdef) {
HMapInfo *const hinfo = (HMapInfo*)t->nspc->class_data;
if(isa(args->type, hinfo->key) < 0 || args->next)
ERR_N(e->pos, "dict.remove must be called with one Key argument");
- return e->type = hinfo->val;
+ return e->type = env->gwion->type[et_void];
}
ANN static m_bool emit_dict_iter(const Emitter emit, const HMapInfo *hinfo,
const Type t = cdef->base.type;
t->nspc->class_data_size = sizeof(struct HMapInfo);
const m_bool ret = traverse_cdef(env, t);
+ set_tflag(t, tflag_cdef);
if(is_global) {
env_pop(env, scope);
type_addref(t);
add_op(env->gwion, &opi);
{
- const Func f = (Func)vector_front(&t->nspc->vtable);
+ const Func f = (Func)vector_at(&t->nspc->vtable, 1);
const struct Op_Func opfunc = {.ck = opck_dict_remove_toop};
const struct Op_Import opi = {
.rhs = f->value_ref->type,
CHECK_BN(add_op(env->gwion, &opi));
}
-
return ret > 0 ? t : NULL;
}
t_dict->nspc->offset += sizeof(struct HMap);
gwi->gwion->type[et_dict] = t_dict;
set_tflag(t_dict, tflag_infer);
- GWI_BB(gwi_func_ini(gwi, "bool", "remove"));
+ GWI_BB(gwi_func_ini(gwi, "void", "remove"));
GWI_BB(gwi_func_arg(gwi, "Key", "key"));
GWI_BB(gwi_func_end(gwi, (f_xfun)1, ae_flag_none));
VAL2 = SZ_INT;
}
+INSTR(FuncWait) {
+ const Func f = (Func)instr->m_val;
+ if(f->_wait->len - instr->m_val2) {
+ if(!handle(shred, "UninitValue")) {
+ gw_err("{-}some values are not instantiated yet{0}\n");
+ for(uint32_t i = instr->m_val2; i < f->_wait->len; i++) {
+ Value v = *mp_vector_at(f->_wait, Value, i);
+ defined_here(v);
+ }
+ }
+ } else {
+ BYTE(eNoOp);
+ }
+}
+
INSTR(fast_except) {
struct FastExceptInfo *info = (struct FastExceptInfo *)instr->m_val2;
if(*(m_uint*)REG(-SZ_INT)) {
static ID_CHECK(opck_super) {
const Exp self = exp_self(prim);
- if(!env->func)
+ if(!env->func || is_ctor(env->func->def))
ERR_O(self->pos, "can't use 'super' outside of constructor");
const Type parent = env->class_def->info->parent;
DECL_OO(const Value, v, = find_value(parent, insert_symbol("new")));
describe_check_decl(member, offset, v->vflag |= vflag_member);
describe_check_decl(static, class_data_size, SET_FLAG(v, static));
+ANN static void var_effects(const Env env, const Type t, const Symbol sym, const loc_t loc) {
+ if (t->info->parent) var_effects(env, t->info->parent, sym, loc);
+ if(!tflag(t, tflag_ctor)) return;
+ const Value ctor = nspc_lookup_value0(t->nspc, sym);
+ if(!ctor) return; // bit sus
+ const Func f = ctor->d.func_ref;
+ const Vector v = &f->def->base->effects;
+ if(!v->ptr) return;
+ for (m_uint i = 0; i < vector_size(v); i++)
+ env_add_effect(env, (Symbol)vector_at(v, i), loc);
+}
+
ANN static m_bool check_var(const Env env, const Var_Decl *var) {
if (env->class_def && !env->scope->depth && env->class_def->info->parent)
CHECK_BB(check_exp_decl_parent(env, var));
- if (var->value->type->effects.ptr) {
- const Vector v = &var->value->type->effects;
- for (m_uint i = 0; i < vector_size(v); i++)
- env_add_effect(env, (Symbol)vector_at(v, i), var->pos);
- }
+ var_effects(env, var->value->type, insert_symbol("@ctor"), var->pos);
return GW_OK;
}
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 (GET_FLAG(v, const)) exp_setmeta(prim_exp(data), 1);
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(vflag(v, vflag_fglobal) /*&& !vflag(v, vflag_builtin) */&& !is_func(env->gwion, v->type)) {
+ if((GET_FLAG(v, global) || vflag(v, vflag_fglobal)) && !vflag(v, vflag_builtin) && !is_func(env->gwion, v->type)) {
+ if(!env->func->_wait)
+ env->func->_wait = new_mp_vector(env->gwion->mp, Value, 0);
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++;
+ mp_vector_add(env->gwion->mp, &env->func->_wait, Value, v);
} else {
bool found = false;
for(uint32_t i = 0; i < v->used_by->len; i++) {
}
}
if(!found) {
- env->func->wait++;
mp_vector_add(env->gwion->mp, &v->used_by, Func, env->func);
+ mp_vector_add(env->gwion->mp, &env->func->_wait, Value, v);
}
}
}
return GW_OK;
}
-ANN static bool effect_find(const MP_Vector *v, const Symbol sym) {
- for(m_uint i = 0; i < v->len; i++) {
- struct ScopeEffect *eff = mp_vector_at(v, struct ScopeEffect, i);
- if(eff->sym == sym) return true;
- }
- return false;
-}
-
ANN static m_bool check_fdef_effects(const Env env, const Func_Def fdef) {
MP_Vector *v = (MP_Vector*)vector_back(&env->scope->effects);
if (v) {
if (!base->ptr) vector_init(base);
for (uint32_t i = 0; i < v->len; i++) {
struct ScopeEffect *eff = mp_vector_at(v, struct ScopeEffect, i);
- if(!effect_find(v, eff->sym))
+ if(vector_find(base, (m_uint)eff->sym) == -1)
vector_add(base, (m_uint)eff->sym);
}
free_mp_vector(env->gwion->mp, struct ScopeEffect, v);
if (fdef->base->args) CHECK_BB(check_func_args(env, fdef->base->args));
if(fdef->builtin) return GW_OK;
if (fdef->d.code && fdef->d.code) {
- env->scope->depth++;
- nspc_push_value(env->gwion->mp, env->curr);
+ const bool ctor = is_ctor(fdef);
+ if(!ctor) {
+ env->scope->depth++;
+ nspc_push_value(env->gwion->mp, env->curr);
+ }
const m_bool ret = check_stmt_list(env, fdef->d.code);
- nspc_pop_value(env->gwion->mp, env->curr);
- env->scope->depth--;
+ if(!ctor) {
+ nspc_pop_value(env->gwion->mp, env->curr);
+ env->scope->depth--;
+ }
CHECK_BB(check_fdef_effects(env, fdef));
return ret;
}
}
return !err ? GW_OK : GW_ERROR;
}
-
+/*
ANN static inline void ctor_effects(const Env env) {
const Vector v = &env->scope->effects;
MP_Vector *const w = (MP_Vector*)vector_back(v);
free_mp_vector(env->gwion->mp, struct ScopeEffect, w);
vector_pop(v);
}
-
+*/
ANN static m_bool check_body(const Env env, Section *const section) {
const m_bool ret = check_section(env, section);
- ctor_effects(env);
+// ctor_effects(env);
return ret;
}
ANN static bool class_def_has_body(Ast ast) {
- for(m_uint i = 0; i < ast->len; i++) {
- const Section *section = mp_vector_at(ast, Section, i);
- if (section->section_type == ae_section_stmt) {
- Stmt_List l = section->d.stmt_list;
- for(m_uint i = 0; i < l->len; i++) {
- const Stmt stmt = mp_vector_at(l, struct Stmt_, i);
- if (stmt->stmt_type == ae_stmt_pp) continue;
- if (stmt->stmt_type == ae_stmt_exp) {
- const Exp exp = stmt->d.stmt_exp.val;
- if (!exp) continue;
- if (exp->exp_type != ae_exp_decl) return true;
- if (GET_FLAG(exp->d.exp_decl.td, late)) continue;
- Var_Decl vd = exp->d.exp_decl.vd;
- if (GET_FLAG(vd.value, late)) continue;
- if (tflag(vd.value->type, tflag_compound))
- return true;
- } else return true;
- }
- }
+ const Section *section = mp_vector_at(ast, Section, 0);
+ if(section->section_type != ae_section_func) return false;
+ Func_Def f = section->d.func_def;
+ if(strcmp(s_name(f->base->xid), "@ctor"))return false;
+ Stmt_List l = f->d.code;
+ for(m_uint i = 0; i < l->len; i++) {
+ const Stmt stmt = mp_vector_at(l, struct Stmt_, i);
+ if (stmt->stmt_type == ae_stmt_pp) continue;
+ if (stmt->stmt_type == ae_stmt_exp) {
+ const Exp exp = stmt->d.stmt_exp.val;
+ if (!exp) continue;
+ if (exp->exp_type != ae_exp_decl) return true;
+ if (GET_FLAG(exp->d.exp_decl.td, late)) continue;
+ Var_Decl vd = exp->d.exp_decl.vd;
+ if (GET_FLAG(vd.value, late)) continue;
+ if (tflag(vd.value->type, tflag_compound))
+ return true;
+ } else return true;
}
return false;
}
if (cdef->body) {
CHECK_BB(env_body(env, cdef, check_body));
if (cflag(cdef, cflag_struct) || class_def_has_body(cdef->body))
+// if (class_def_has_body(cdef->body))
set_tflag(t, tflag_ctor);
}
if (!GET_FLAG(cdef, abstract)) CHECK_BB(check_abstract(env, cdef));
#include "traverse.h"
#include "template.h"
#include "parse.h"
+#include "object.h"
+#include "operator.h"
+#include "instr.h"
+#include "import.h"
ANN static m_bool scan1_stmt_list(const Env env, Stmt_List list);
ANN static m_bool scan1_stmt(const Env env, Stmt stmt);
env->class_def->size += t->size;
}
}
- } else if(env->context)
+ } else if (GET_FLAG(decl->td, global))
+ SET_FLAG(v, global);
+ else if(env->context)
set_vflag(v, vflag_fglobal); // file global
} else if (GET_FLAG(decl->td, global))
SET_FLAG(v, global);
Nspc nspc = env->curr;
do {
const Value v = nspc_lookup_value0(nspc, sym);
- if (v && !env->func->def->builtin) return shadow_err(env, v, loc);
+ if (v && !env->func->def->builtin) {
+ const Type owner = v->from->owner_class;
+ if (owner && env->class_def && isa(env->class_def, owner) < 0)
+ continue;
+ return shadow_err(env, v, loc);
+ }
} while ((nspc = nspc->parent));
return GW_OK;
}
CHECK_BB(scan_internal(env, fdef->base));
else if (fbflag(fdef->base, fbflag_op) && env->class_def)
SET_FLAG(fdef->base, static);
- RET_NSPC(scan1_fbody(env, fdef))
+ if(!is_ctor(fdef)) {
+ RET_NSPC(scan1_fbody(env, fdef))
+ } else if(!fdef->builtin)
+ CHECK_BB(scan1_stmt_list(env, fdef->d.code));
return GW_OK;
}
return ret;
}
+ANN static m_bool scan1_class_def_body(const Env env, const Class_Def cdef) {
+ if(!tmpl_base(cdef->base.tmpl) && isa(cdef->base.type, env->gwion->type[et_closure]) < 0 &&
+ isa(cdef->base.type, env->gwion->type[et_dict]) < 0) {
+ MemPool mp = env->gwion->mp;
+ Ast base = cdef->body;
+ Stmt_List ctor = new_mp_vector(mp, struct Stmt_, 0);
+ Ast body = new_mp_vector(mp, Section, 1); // room for ctor
+ for(uint32_t i = 0; i < base->len; i++) {
+ Section section = *mp_vector_at(base, Section, i);
+ if(section.section_type == ae_section_stmt) {
+ Stmt_List list = section.d.stmt_list;
+ for(uint32_t j = 0; j < list->len; j++) {
+ Stmt stmt = mp_vector_at(list, struct Stmt_, j);
+ mp_vector_add(mp, &ctor, struct Stmt_, *stmt);
+ }
+ } else mp_vector_add(mp, &body, Section, section);
+ }
+ Type_Decl *td = type2td(env->gwion, env->gwion->type[et_void], cdef->base.pos);
+ Symbol sym = insert_symbol("@ctor");
+ Func_Base *fb = new_func_base(mp, td, sym, NULL, ae_flag_none, cdef->base.pos);
+ Func_Def fdef = new_func_def(mp, fb, ctor);
+ mp_vector_set(body, Section, 0, MK_SECTION(func, func_def, fdef));
+ free_mp_vector(mp, Section, base);
+ cdef->body = body;
+ }
+ return env_body(env, cdef, scan1_section);
+}
+
ANN m_bool scan1_class_def(const Env env, const Class_Def cdef) {
if (tmpl_base(cdef->base.tmpl)) return GW_OK;
const Type t = cdef->base.type;
set_tflag(t, tflag_scan1);
const Class_Def c = t->info->cdef;
if (c->base.ext) CHECK_BB(cdef_parent(env, c));
- if (c->body) CHECK_BB(env_body(env, c, scan1_section));
+ if (c->body) CHECK_BB(scan1_class_def_body(env, c));
return GW_OK;
}
ANN static m_bool scan2_func_def_code(const Env env, const Func_Def f) {
const Func former = env->func;
env->func = f->base->func;
- env->scope->depth++;
- nspc_push_value(env->gwion->mp, env->curr);
+ const bool ctor = is_ctor(f);
+ if(!ctor) {
+ env->scope->depth++;
+ nspc_push_value(env->gwion->mp, env->curr);
+ }
const m_bool ret = scan2_stmt_list(env, f->d.code); // scope depth?
- nspc_pop_value(env->gwion->mp, env->curr);
- env->scope->depth--;
+ if(!ctor) {
+ nspc_pop_value(env->gwion->mp, env->curr);
+ env->scope->depth--;
+ }
env->func = former;
return ret;
}
shreduler_remove(shred->tick->shreduler, shred, true);
}
-ANN void handle(VM_Shred shred, const m_str effect) {
+ANN bool handle(VM_Shred shred, const m_str effect) {
shreduler_remove(shred->tick->shreduler, shred, false);
// store trace info
struct TraceStart ts = {
const m_uint size =
shred->info->frame.ptr ? vector_size(&shred->info->frame) : 0;
// maybe we should use a string to avoid the insert_symbol call
- if (!unwind(shred, insert_symbol(shred->info->vm->gwion->st, effect), size))
+ if (!unwind(shred, insert_symbol(shred->info->vm->gwion->st, effect), size)) {
handle_fail(shred, effect, &ts);
+ return false;
+ }
+ return true;
}
ANN bool vm_remove(const VM *vm, const m_uint index) {
const f_instr exec = *(f_instr*)(prepare_code + SZ_INT *2);
if(exec == DTOR_EOC)return;
const Instr instr = *(Instr*)(prepare_code + SZ_INT);
- if(exec == fast_except)
+ if(exec == fast_except || exec == FuncWait)
instr->opcode = (m_uint)&&noop;
else if(exec == SetFunc)
instr->opcode = (m_uint)&®pushimm;
-Subproject commit 8b2644578a7489ef9c8d87cd19a6326fb775fd3f
+Subproject commit 4588df17c998d18e8db40ce1391a714cd893b469