tflag_noret = 1 << 18,
tflag_contract = 1 << 19,
tflag_float = 1 << 20,
+ tflag_union = 1 << 21,
} __attribute__((packed));
struct Type_ {
vflag_builtin = 1 << 5,
vflag_member = 1 << 6,
vflag_closed = 1 << 7,
- vflag_inner = 1 << 8 // value is in a scope
+ vflag_inner = 1 << 8, // value is in a scope
+ vflag_release = 1 << 9
// vflag_used = 1 << 3
} __attribute__((packed));
#define __OBJECT
typedef struct M_Object_ *M_Object;
struct M_Object_ {
- m_bit * data;
- Type type_ref;
- struct Vector_ vtable;
- volatile size_t ref;
+ Type type_ref;
+ struct Vector_ vtable;
+ /*volatile */uint32_t ref;
+ uint32_t offset;
+ m_bit data[];
};
ANN void instantiate_object(const VM_Shred, const Type);
}
}
-static inline void compound_release(const VM_Shred shred, const Type t,
+ANN static inline void compound_release(const VM_Shred shred, const Type t,
const m_bit *ptr) {
if (!tflag(t, tflag_struct))
object_release(shred, t, ptr);
#define MAX(a, b) (a >= b ? a : b)
ANN void free_value(Value a, Gwion gwion) {
const Type t = a->type;
+// if(t) {
+
if (t->size > SZ_INT && !vflag(a, vflag_func) && a->d.ptr)
_mp_free(gwion->mp, t->size, a->d.ptr);
else if (is_class(gwion, t))
type_remref(t, gwion);
- /* else */if (vflag(a, vflag_inner))
+ else if (vflag(a, vflag_inner))
type_remref(t, gwion);
+// }
+
mp_free(gwion->mp, ValueFrom, a->from);
mp_free(gwion->mp, Value, a);
}
return; // TODO make exception vararg
}
*(void **)(ref->data + SZ_INT) = aai.data;
-// vector_add(&shred->gc, (m_uint)ref); // heyo
+ vector_add(&shred->gc, (m_uint)ref); // heyo
if (!info->is_obj) {
POP_REG(shred, SZ_INT * (info->depth - 1));
*(M_Object *)REG(-SZ_INT) = ref;
#undef insert_symbol
M_Object new_object(MemPool p, const VM_Shred shred, const Type t) {
- const M_Object a = mp_calloc(p, M_Object);
+ const uint32_t offset = sizeof(struct M_Object_) + t->nspc->offset;
+ const M_Object a = _mp_calloc(p, offset);
a->ref = 1;
a->type_ref = t;
- if (t->nspc) {
- a->vtable.ptr = t->nspc->vtable.ptr;
- if (t->nspc->offset)
- a->data = (m_bit *)_mp_calloc(p, t->nspc->offset);
- }
+ a->offset = t->nspc->offset;
+ a->vtable.ptr = t->nspc->vtable.ptr;
if (shred) vector_add(&shred->gc, (vtype)a);
return a;
}
return o;
}
-ANN static void handle_dtor(const M_Object o, const VM_Shred shred) {
+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);
sh->base = shred->base;
++sh->info->me->ref;
}
-__attribute__((hot)) ANN void __release(const M_Object o,
- const VM_Shred shred) {
- vector_rem2(&shred->gc, (vtype)o);
- MemPool p = shred->info->mp;
- Type t = o->type_ref;
- do {
- if (!t->nspc) continue;
- if (isa(t, shred->info->vm->gwion->type[et_union]) < 0) {
- struct scope_iter iter = {t->nspc->info->value, 0, 0};
- Value v;
- while (scope_iter(&iter, &v) > 0) {
- if (!GET_FLAG(v, static) &&
- isa(v->type, shred->info->vm->gwion->type[et_compound]) > 0)
- compound_release(shred, v->type, o->data + v->from->offset);
- }
- }
- if (tflag(t, tflag_dtor)) {
- if (t->nspc->dtor->builtin)
- ((f_xtor)t->nspc->dtor->native_func)(o, NULL, shred);
- else {
- o->type_ref = t;
- handle_dtor(o, shred);
- return;
- }
- }
- } while ((t = t->info->parent));
- free_object(p, o);
+static DTOR(object_dtor) {
+ free_object(shred->info->mp, o);
+}
+
+ANN static inline Type next_type(Type t) {
+ do if(t->nspc) return t;
+ while((t = t->info->parent));
+ return NULL;
+}
+
+ANN static inline void release_not_union(const m_bit *data, const VM_Shred shred, const Scope s) {
+ const Map m = &s->map;
+ for(m_uint i = map_size(m) + 1; --i;) {
+ const Value v = (Value) VVAL(m, i-1);
+ if (vflag(v, vflag_release))
+ compound_release(shred, v->type, data + v->from->offset);
+ }
+}
+
+ANN static void do_release(const M_Object o,
+ const VM_Shred shred, const Type t) {
+ const Type next = next_type(t);
+ if(!next) return;
+ if (!tflag(t, tflag_union))
+ release_not_union(o->data, shred, t->nspc->info->value);
+ if (tflag(t, tflag_dtor)) {
+ if (t->nspc->dtor->builtin)
+ ((f_xtor)t->nspc->dtor->native_func)(o, NULL, shred);
+ else
+ return user_dtor(o, shred, t);
+ }
+ return do_release(o, shred, t->info->parent);
+}
+
+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) {
- if (o->type_ref->nspc && o->type_ref->nspc->offset)
- mp_free2(p, o->type_ref->nspc->offset, o->data);
- mp_free(p, M_Object, o);
+ mp_free2(p, o->offset, o);
}
static ID_CHECK(opck_this) {
GWION_IMPORT(object) {
const Type t_object = gwi_mk_type(gwi, "Object", SZ_INT, "@Compound");
gwi_set_global_type(gwi, t_object, et_object);
+ t_object->nspc = new_nspc(gwi->gwion->mp, "Object");
+ t_object->nspc->dtor = new_vmcode(gwi->gwion->mp, NULL, NULL, "Object", SZ_INT, true, false);
+ t_object->nspc->dtor->native_func = (m_uint)object_dtor;
+ t_object->tflag |= tflag_dtor;
struct SpecialId_ spid = {.ck = opck_this, .em = opem_this, .is_const = 1};
gwi_specialid(gwi, "this", &spid);
return GW_OK;
const Exp_Dot *member = (Exp_Dot *)data;
const Type t_base = actual_type(emit->gwion, member->base->type);
const Value value = find_value(t_base, member->xid);
-
if (is_class(emit->gwion, value->type)) {
const Instr instr = emit_add_instr(emit, RegPushImm);
instr->m_val = (m_uint)value->type;
static void afl_run(const Gwion gwion) {
__AFL_INIT();
- while (__AFL_LOOP(128)) {
+// while (__AFL_LOOP(128)) {
+ while (__AFL_LOOP(32)) {
push_global(gwion, "[afl]");
FILE *f = fdopen(0, "r");
if (compile_file(gwion, "afl", f)) gwion_run(gwion);
}
if (!decl->type) ERR_O(decl->td->pos, _("can't find type"));
{
- CHECK_BO(inferable(env, decl->type, decl->td->pos));
CHECK_BO(ensure_check(env, decl->type));
+ if(inferable(env, decl->type, decl->td->pos) < 0) {
+ if(!tflag(decl->type, tflag_check) && decl->type->ref > 1 && env->class_def && !env->scope->depth)
+ type_remref(decl->type, env->gwion);
+ return NULL;
+ }
}
const m_bool global = GET_FLAG(decl->td, global);
const m_uint scope = !global ? env->scope->depth : env_push_global(env);
const m_bool ret = check_decl(env, decl);
if (global) env_pop(env, scope);
+ env_weight(env, 1 + isa(decl->type, env->gwion->type[et_object]) > 0);
return ret > 0 ? decl->list->self->value->type : NULL;
}
if (!e)
ERR_O(prim_pos(data), _("must provide values/expressions for array [...]"))
CHECK_OO(check_exp(env, e));
+ env_weight(env, 1);
return array->type = prim_array_match(env, e);
}
ANN static Type check_prim_range(const Env env, Range **data) {
Range *range = *data;
CHECK_BO(check_range(env, range));
+ env_weight(env, 1);
const Exp e = range->start ?: range->end;
assert(e);
const Symbol sym = insert_symbol("@range");
.lhs = member->base->type,
.data = (uintptr_t)member,
.pos = exp_self(member)->pos};
+ env_weight(env, 1);
return op_check(env, &opi);
}
ANN static Type check_prim_perform(const Env env, const Symbol *data) {
env_add_effect(env, *data, prim_pos(data));
+ env_weight(env, 1);
return env->gwion->type[et_void];
}
ANN static Type check_prim_interp(const Env env, const Exp *exp) {
CHECK_OO(check_exp(env, *exp));
+ env_weight(env, 1);
return env->gwion->type[et_string];
}
ANN static Type check_prim_hack(const Env env, const Exp *data) {
if (env->func) unset_fflag(env->func, fflag_pure);
CHECK_OO(check_prim_interp(env, data));
+ env_weight(env, 1);
return env->gwion->type[et_gack];
}
/*
static ANN Type check_exp_slice(const Env env, const Exp_Slice *range) {
CHECK_OO(check_exp(env, range->base));
CHECK_BO(check_range(env, range->range));
+ env_weight(env, 1);
const Symbol sym = insert_symbol("@slice");
const Exp e = range->range->start ?: range->range->end;
assert(e);
return isa(tgt, t) > 0 || isa(t, tgt) > 0 || (tgt->info->tuple && vector_find(&tgt->info->tuple->contains, (m_uint)t) > -1);
}
+ANN static m_bool recursive_type_base(const Env env, const Type t);
+ANN static bool recursive_type(const Env env, const Type t, const Type tgt);
+ANN static bool recursive_value(const Env env, const Type t, const Value v) {
+//if(!v->from->owner_class)exit(13);
+ const Type tgt = array_base(v->type);
+ if(type_is_recurs(t, tgt)) {
+ env_err(env, v->from->loc, _("recursive type"));
+ env->context->error = false;
+ gwerr_secondary("in class", t->name, t->info->cdef->base.pos);
+
+ const Type first = tgt->info->value->from->loc.first.line < t->info->value->from->loc.first.line ?
+// tgt : t;
+ v->type : t;
+ const Type second = tgt->info->value->from->loc.first.line > t->info->value->from->loc.first.line ?
+// tgt : t;
+ v->type : t;
+
+printf("%s %s\n", first->name, second->name);
+
+ if(first != second) {
+ const Map m1 = &first->info->value->from->owner->info->type->map;
+ map_remove(m1, (m_uint)insert_symbol(first->name));
+ const Map m2 = &second->info->value->from->owner->info->type->map;
+ map_remove(m2, (m_uint)insert_symbol(second->name));
+ if(first->ref > 2)
+ type_remref(first, env->gwion);
+ if(second->ref > 2)
+ type_remref(second, env->gwion);
+ if(tgt != t && v->type == tgt && strncmp(tgt->name, "Option:[", 8))
+ recursive_type_base(env, tgt);
+ }
+ set_tflag(t, tflag_infer);
+ set_tflag(tgt, tflag_infer);
+ unset_tflag(t, tflag_check);
+ unset_tflag(tgt, tflag_check);
+ return true;
+ }
+ if(v->type->nspc && !GET_FLAG(v, late) &&
+ isa(tgt, env->gwion->type[et_compound]) > 0)
+ return recursive_type(env, t, tgt);
+ return false;
+}
+
+ANN static bool recursive_type(const Env env, const Type t, const Type tgt) {
+ Value v;
+ struct scope_iter inner = {tgt->nspc->info->value, 0, 0};
+ bool error = false;
+ while (scope_iter(&inner, &v) > 0) {
+ if(!GET_FLAG(v, late) && recursive_value(env, t, v)) {
+ error = true;
+ }
+ }
+ return error;
+}
+
+ANN static m_bool recursive_type_base(const Env env, const Type t) {
+ Value value;
+ bool error = false;
+ struct scope_iter iter = {t->nspc->info->value, 0, 0};
+ while (scope_iter(&iter, &value) > 0) {
+ if (isa(value->type, env->gwion->type[et_compound]) < 0) continue;
+ if (value->type->nspc && !GET_FLAG(value, late)) {
+ if(recursive_type(env, t, value->type)) {
+ env_err(env, value->from->loc, _("recursive type"));
+ gw_err("use {+G}late{0} on one (or more) of the variables?\n");
+ error = true;
+ }
+ }
+ }
+ return error;
+}
+
ANN bool check_trait_requests(const Env env, const Type t, const ID_List list);
ANN static m_bool _check_class_def(const Env env, const Class_Def cdef) {
const Type t = cdef->base.type;
return GW_ERROR;
}
}
-
- Value value;
- struct scope_iter iter = {t->nspc->info->value, 0, 0};
- while (scope_iter(&iter, &value) > 0) {
- if (isa(value->type, env->gwion->type[et_compound]) < 0) continue;
-// const Type t = array_base(value->type);
- if (value->type->nspc && !GET_FLAG(value, late)) {
- Value v;
- struct scope_iter inner = {value->type->nspc->info->value, 0, 0};
-bool error = false;
- while (scope_iter(&inner, &v) > 0) {
- const Type tgt = array_base(v->type);
-// if(isa(tgt, t) > 0 || isa(t, tgt) > 0 || (tgt->info->tuple && vector_find(&tgt->info->tuple->contains, (m_uint)t) > -1)) {
- if(type_is_recurs(t, tgt)) {
- env_err(env, v->from->loc, _("recursive type"));
- env->context->error = false;
- env_err(env, value->from->loc, _("recursive type"));
- gw_err("use {+G}late{0} on one (or more) of the variables?\n");
-// env_set_error(env);
-vector_rem2(&t->info->tuple->contains, (m_uint)tgt);
-vector_rem2(&tgt->info->tuple->contains, (m_uint)t);
-type_remref(t, env->gwion);
-//type_remref(tgt, env->gwion);
-//nspc_add_type_front(t->nspc, insert_symbol(tgt->name), tgt);
-//nspc_add_type_front(tgt->nspc, insert_symbol(tgt->name), t);
- set_tflag(t, tflag_infer);
- set_tflag(tgt, tflag_infer);
- unset_tflag(t, tflag_check);
- unset_tflag(tgt, tflag_check);
-//value->type = env->gwion->type[et_error];
-//v->type = env->gwion->type[et_error];
-//env->gwion->type[et_error]->ref += 2;
-
-error = true;
-// return GW_OK;
- }
- }
-if(error)
-// return GW_OK;
- return GW_ERROR;
- }
- }
+ CHECK_BB(recursive_type_base(env, t));
nspc_allocdata(env->gwion->mp, t->nspc);
return GW_OK;
}
t->nspc = new_nspc(env->gwion->mp, name);
t->nspc->parent = env->curr;
t->info->tuple = new_tupleform(env->gwion->mp, NULL); // ???
+ set_tflag(t, tflag_union);
add_type(env, env->curr, t);
mk_class(env, t, loc);
SET_FLAG(t, final);
}
ANN2(1,2) static Ast scan0_func_def_default(const MemPool p, const Ast ast,
- const Ast next) {
+ const Ast next) {
const Func_Def base_fdef = ast->section->d.func_def;
Arg_List base_arg = base_fdef->base->args, former = NULL;
while (base_arg) {
}
ANN m_bool scan0_ast(const Env env, Ast ast) {
+ Ast next;
do {
+ next = ast->next;
CHECK_BB(scan0_section(env, ast->section));
if (ast->section->section_type != ae_section_func ||
!fdef_defaults(ast->section->d.func_def))
continue;
- const Ast next = ast->next;
- scan0_func_def_default(env->gwion->mp, ast, next);
- if(!(ast = next))break;
- } while ((ast = ast->next));
+ (void)scan0_func_def_default(env->gwion->mp, ast, ast->next);
+ } while ((ast = next));
return GW_OK;
}
if (env->class_def->info->tuple) tuple_contains(env, v);
if (!GET_FLAG(decl->td, static)) {
set_vflag(v, vflag_member);
+ if(isa(t, env->gwion->type[et_object]) > 0)
+ set_vflag(v, vflag_release);
if (tflag(env->class_def, tflag_struct)) {
v->from->offset = env->class_def->size;
env->class_def->size += t->size;
if (nspc_lookup_value0(env->curr, l->xid))
ERR_B(l->pos, _("'%s' already declared in union"), s_name(l->xid))
const Value v = new_value(env->gwion->mp, t, s_name(l->xid));
- if (!tflag(t, tflag_scan1)) // ???
+// if (!tflag(t, tflag_scan1)) // ???
tuple_contains(env, v); // ???
- v->from->offset = SZ_INT;
+// v->from->offset = SZ_INT;
+ v->from->offset = v->type->size;
valuefrom(env, v->from, udef->pos);
nspc_add_value_front(env->curr, l->xid, v);
if (t->size > sz) sz = t->size;
GWI_BB(gwi_enum_add(gwi, "TYPED_ENUM9", 9))
GWI_OB(gwi_enum_end(gwi))
- GWI_OB(gwi_class_ini(gwi, "Enum", NULL))
- GWI_BB(gwi_enum_ini(gwi, "MyTest"))
- GWI_BB(gwi_enum_add(gwi, "ENUM0", 0))
- GWI_BB(gwi_enum_add(gwi, "ENUM1", 1))
- GWI_BB(gwi_enum_add(gwi, "ENUM2", 2))
- GWI_BB(gwi_enum_add(gwi, "ENUM3", 3))
- GWI_BB(gwi_enum_add(gwi, "ENUM4", 4))
- GWI_BB(gwi_enum_add(gwi, "ENUM5", 5))
- GWI_BB(gwi_enum_add(gwi, "ENUM6", 6))
- GWI_BB(gwi_enum_add(gwi, "ENUM7", 7))
- GWI_BB(gwi_enum_add(gwi, "ENUM8", 8))
- GWI_BB(gwi_enum_add(gwi, "ENUM9", 9))
- GWI_OB(gwi_enum_end(gwi))
-
GWI_OB(gwi_class_end(gwi))
return GW_OK;
#include "import.h"
GWION_IMPORT(enum_test) {
- GWI_BB(gwi_enum_ini(gwi, NULL))
+ GWI_BB(gwi_enum_ini(gwi, "test"))
GWI_BB(gwi_enum_add(gwi, "adc", 0))
GWI_BB(gwi_enum_ini(gwi, NULL))
return GW_OK;