-Subproject commit 368e64e5442209148ef1e8b271e645e05b125fdb
+Subproject commit d8d61d8a6395dd2b79e96bd1fcaaec54e324685b
} HMap;
-enum HMapKind {
- HKIND_NONE,
- HKIND_OBJ,
- HKIND_STRUCT
-};
-
typedef struct HMapInfo {
Type key;
Type val;
m_uint sz;
- enum HMapKind keyk;
- enum HMapKind valk;
} HMapInfo;
#endif
ANN void free_emitter(MemPool, Emitter);
ANN m_bool emit_ast(const Env env, Ast *ast);
ANN m_bool emit_func_def(const Emitter emit, const Func_Def fdef);
-ANN m_bool emit_exp_call1(const Emitter, const Func, const bool is_static);
+ANN m_bool emit_exp_call1(const Emitter, const Func, const m_uint size, const bool is_static);
ANN2(1)
Instr emit_add_instr(const Emitter, const f_instr)
__attribute__((returns_nonnull));
const m_bit *ptr);
#define RELEASE_FUNC(a) \
void(a)(const VM_Shred shred, const Type t NUSED, const m_bit *ptr)
-static inline RELEASE_FUNC(object_release) { release(*(M_Object *)ptr, shred); }
RELEASE_FUNC(struct_release);
+RELEASE_FUNC(union_release);
+static inline RELEASE_FUNC(object_release) { release(*(M_Object *)ptr, shred); }
+static inline RELEASE_FUNC(compound_release) {
+ if (!tflag(t, tflag_struct))
+ object_release(shred, t, ptr);
+ else if (!tflag(t, tflag_union))
+ struct_release(shred, t, ptr);
+ else union_release(shred, t, ptr);
+}
+static inline RELEASE_FUNC(anytype_release) {
+ if (tflag(t, tflag_release))
+ compound_release(shred, t, ptr);
+}
+static inline void object_addref(const m_bit *ptr) {
+ M_Object o = (M_Object)ptr;
+ if(o) o->ref++;
+}
-static inline void struct_addref(const Gwion gwion, const Type type,
- const m_bit *ptr) {
- 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 (tflag(t, tflag_compound)) {
- if (!tflag(t, tflag_struct)) {
- const M_Object o =
- *(M_Object *)(ptr + vector_at(&type->info->tuple->offset, i));
- if(o) o->ref++;
- } else struct_addref(gwion, t,
- *(m_bit **)(ptr + vector_at(&type->info->tuple->offset, i)));
- }
+ANN static inline void union_addref(const Type type, const m_bit*);
+ANN static inline void struct_addref(const Type type, const m_bit*);
+ANN static inline void compound_addref(const Type t, const m_bit *ptr) {
+ if (!tflag(t, tflag_struct))
+ object_addref(ptr);
+ else if (!tflag(t, tflag_union))
+ struct_addref(t, ptr);
+ else union_addref(t, ptr);
+}
+
+ANN static inline void struct_addref(const Type type, const m_bit *ptr) {
+ const Vector v = &type->info->tuple->types;
+ for (m_uint i = 0; i < vector_size(v); ++i) {
+ const Type t = (Type)vector_at(v, i);
+ const m_bit *data = *(m_bit**)(ptr + vector_at(v, i));
+ if (tflag(t, tflag_release)) compound_addref(t, data);
}
}
-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);
- else
- struct_release(shred, t, ptr);
+ANN static inline void union_addref(const Type t, const m_bit *ptr) {
+ const m_uint idx = *(m_uint *)ptr;
+ if (idx) {
+ const Map map = &t->nspc->info->value->map;
+ const Value v = (Value)map_at(map, idx - 1);
+ if (tflag(v->type, tflag_release))
+ compound_addref(v->type, ptr + SZ_INT);
+ }
}
+ANN static inline void anytype_addref(const Type t, const m_bit *ptr) {
+ if(tflag(t, tflag_release)) compound_addref(t, ptr);
+}
#endif
eRegAddRefAddr,
eStructRegAddRef,
eStructRegAddRefAddr,
+ eUnionRegAddRef,
+ eUnionRegAddRefAddr,
eObjectAssign,
eAssign,
eObjectRelease,
eObjectRelease2,
eStructReleaseRegAddr,
eStructReleaseMem,
+ eUnionReleaseRegAddr,
+ eUnionReleaseMem,
eGWOP_EXCEPT,
eDotMemberMem,
eDotMemberMem2,
#define RegAddRefAddr (f_instr)eRegAddRefAddr
#define StructRegAddRef (f_instr)eStructRegAddRef
#define StructRegAddRefAddr (f_instr)eStructRegAddRefAddr
+#define UnionRegAddRef (f_instr)eUnionRegAddRef
+#define UnionRegAddRefAddr (f_instr)eUnionRegAddRefAddr
#define ObjectAssign (f_instr)eObjectAssign
#define Assign (f_instr)eAssign
#define ObjectRelease (f_instr)eObjectRelease
#define ObjectRelease2 (f_instr)eObjectRelease2
#define StructReleaseRegAddr (f_instr)eStructReleaseRegAddr
#define StructReleaseMem (f_instr)eStructReleaseMem
+#define UnionReleaseRegAddr (f_instr)eUnionReleaseRegAddr
+#define UnionReleaseMem (f_instr)eUnionReleaseMem
#define GWOP_EXCEPT (f_instr)eGWOP_EXCEPT
#define DotMemberMem (f_instr)eDotMemberMem
#define DotMemberMem2 (f_instr)eDotMemberMem2
gw_out(" {-R}%-14"INT_F"{0}", instr->m_val);
gw_out("\n");
break;
+ case eUnionRegAddRef:
+ gw_out("{Y}┃{0}{-}% 4lu{0}: UnionRegAddRef", j);
+ gw_out(" {-R}%-14"INT_F"{0}", instr->m_val);
+ gw_out(" {-M}%-14"UINT_F"{0}", instr->m_val2);
+ gw_out("\n");
+ break;
+ case eUnionRegAddRefAddr:
+ gw_out("{Y}┃{0}{-}% 4lu{0}: UnionRegAddRefAddr", j);
+ gw_out(" {-R}%-14"INT_F"{0}", instr->m_val);
+ gw_out("\n");
+ break;
case eObjectAssign:
gw_out("{Y}┃{0}{-}% 4lu{0}: ObjectAssign", j);
gw_out("\n");
gw_out(" {-B}%-14s"UINT_F"{0}", ((Type)instr->m_val2)->name);
gw_out("\n");
break;
+ case eUnionReleaseRegAddr:
+ gw_out("{Y}┃{0}{-}% 4lu{0}: UnionReleaseRegAddr", j);
+ gw_out(" {-R}%-14"UINT_F"{0}", instr->m_val);
+ gw_out(" {-B}%-14s"UINT_F"{0}", ((Type)instr->m_val2)->name);
+ gw_out("\n");
+ break;
+ case eUnionReleaseMem:
+ gw_out("{Y}┃{0}{-}% 4lu{0}: UnionReleaseMem", j);
+ gw_out(" {-R}%-14"UINT_F"{0}", instr->m_val);
+ gw_out(" {-B}%-14s"UINT_F"{0}", ((Type)instr->m_val2)->name);
+ gw_out("\n");
+ break;
case eGWOP_EXCEPT:
gw_out("{Y}┃{0}{-}% 4lu{0}: GWOP_EXCEPT ", j);
gw_out(" {-R}%-14"UINT_F"{0}", instr->m_val);
RegAddRefAddr~i
StructRegAddRef~i~u
StructRegAddRefAddr~i
+UnionRegAddRef~i~u
+UnionRegAddRefAddr~i
ObjectAssign
Assign
ObjectRelease~u
ObjectRelease2~p
StructReleaseRegAddr~u~t
StructReleaseMem~u~t
+UnionReleaseRegAddr~u~t
+UnionReleaseMem~u~t
GWOP_EXCEPT~u
DotMemberMem~u
DotMemberMem2~u
-Subproject commit d868f2419d0981580c2e85a717ea6c42995582b2
+Subproject commit ce09a14cc01ba003fcbc2120f5a4434e6cccc671
ANN void emit_struct_release(const Emitter emit, const Type type,
const m_uint offset) {
if(!tflag(type, tflag_release)) return;
- const Instr instr = emit_add_instr(emit, StructReleaseMem);
+ f_instr exec = tflag(type, tflag_union)
+ ? UnionReleaseMem
+ : StructReleaseMem;
+ const Instr instr = emit_add_instr(emit, exec);
instr->m_val = offset;
instr->m_val2 = (m_uint)type;
}
return l->offset;
}
+ANN m_uint emit_local_exp2(const Emitter emit, const Exp e) {
+ Local *const l = emit_localx(emit, e->type);
+ e->data = l;
+ return l->offset;
+}
+
ANN m_uint emit_localn(const Emitter emit, const Type t) {
Local *const l = frame_local(emit->gwion->mp, emit->code->frame, t);
l->skip = true;
return info;
}
-ANN static void call_finish(const Emitter emit, const Func f,const bool);
+ANN static void call_finish(const Emitter emit, const Func f, const m_uint size, const bool);
ANN void emit_ext_ctor(const Emitter emit, const Type t) {
const Instr cpy = emit_add_instr(emit, Reg2Reg);
cpy->m_val2 = -SZ_INT;
- const Func f = (Func)vector_front(&t->nspc->vtable);
emit_regmove(emit, SZ_INT);
+ const Func f = (Func)vector_front(&t->nspc->vtable);
emit_pushfunc(emit, f);
- call_finish(emit, f, false);
+ const m_uint size = !tflag(t, tflag_union) ? 0 : t->size;
+ call_finish(emit, f, size, false);
}
ANN static inline void emit_notpure(const Emitter emit) {
is_ref));
return GW_OK;
} else if (!is_ref) {
- if(!tflag(type, tflag_typedef) || isa(type, emit->gwion->type[et_closure]) > 0 ||
- tflag(type, tflag_union)) {
+ if(!tflag(type, tflag_typedef) || isa(type, emit->gwion->type[et_closure]) > 0) {
const Instr instr = emit_add_instr(emit, ObjectInstantiate);
instr->m_val2 = (m_uint)type;
} // maybe we should instantiate the first actual type
}
e->next = next;
CHECK_BB(emit_exp(emit, &func));
- CHECK_BB(emit_exp_call1(emit, func.type->info->func, true));
+ CHECK_BB(emit_exp_call1(emit, func.type->info->func,
+ func.type->info->func->def->base->ret_type->size, true));
count++;
} while((e = e->next->next));
init->m_val = int2pow2(count);
const M_Object string = new_string(emit->gwion, s_name(*id));
emit_pushimm(emit, (m_uint)string);
emit_pushimm(emit, (m_uint)emit->locale->code);
- CHECK_BB(emit_exp_call1(emit, emit->locale, true));
+ CHECK_BB(emit_exp_call1(emit, emit->locale, SZ_FLOAT, true));
emit_regmove(emit, -emit->locale->def->base->ret_type->size);
const VM_Code code = finalyze(emit, EOC);
const VM_Shred shred = new_vm_shred(emit->gwion->mp, code);
}
ANN static inline int struct_ctor(const Value v) {
- return tflag(v->type, tflag_struct) && tflag(v->type, tflag_ctor);
+ return tflag(v->type, tflag_struct) /*&& tflag(v->type, tflag_ctor)*/;
}
ANN static void decl_expand(const Emitter emit, const Type t) {
ANN static m_bool struct_finish(const Emitter emit, const Exp_Decl *decl) {
const Type t = decl->type;
const bool emit_addr = exp_getvar(exp_self(decl));
+ if(GET_FLAG(decl->vd.value, late) || GET_FLAG(decl->td, late)) {
+ if(!emit_addr)
+ decl_expand(emit, t);
+ return GW_OK;
+ }
+ if(!decl->args && !tflag(t, tflag_ctor) && emit_addr)
+ return GW_OK;
if (decl->args) {
- CHECK_BB(emit_exp(emit, decl->args));
if (emit_addr) {
- emit_regmove(emit, -t->size);
- emit_regpushmem4(emit, decl->vd.value->from->offset, 0);
+ const Instr back = (Instr)vector_back(&emit->code->instr);
+ const Instr instr = emit_add_instr(emit, NoOp);
+ memcpy(instr, back, sizeof(struct Instr_));
}
+ CHECK_BB(emit_exp(emit, decl->args));
+ if (emit_addr) emit_regmove(emit, -t->size);
return GW_OK;
}
- if(tflag(t, tflag_ctor)) {
- emit_ext_ctor(emit, t);
- if (!emit_addr) decl_expand(emit, t);
- }
+ if(tflag(t, tflag_ctor)) emit_ext_ctor(emit, t);
+ if (!emit_addr) decl_expand(emit, t);
return GW_OK;
}
}
return GW_ERROR;
}
- if(GET_FLAG(v, late) && exp_getuse(exp_self(decl)))
+ if(isa(v->type, emit->gwion->type[et_object]) > 0 && GET_FLAG(v, late) && exp_getuse(exp_self(decl)))
emit_add_instr(emit, GWOP_EXCEPT);
return GW_OK;
}
const m_int offset = self->ref ? emit->code->frame->curr_offset - t->size: emit_local(emit, t);
const Instr back = self->ref ? (Instr)vector_pop(&emit->code->instr) : NULL;
CHECK_BB(emit_func_args(emit, call));
- if(back)
- vector_add(&emit->code->instr, (m_uint)back);
- else if(tflag(t, tflag_ctor))
- emit_regpushmem4(emit, offset, 0);
+ if(back) vector_add(&emit->code->instr, (m_uint)back);
+ else emit_regpushmem(emit, offset, t->size, true);
if(tflag(t, tflag_ctor)) emit_ext_ctor(emit, t);
- else if(!back) {
- emit_regmove(emit, -SZ_INT + t->size);
- emit_regpushmem4(emit, offset, 0);
- }
emit_add_instr(emit, NoOp);
- CHECK_BB(emit_exp_call1(emit, call->func->type->info->func, is_static_call(emit->gwion, call->func))); // is a ctor, is_static is true
+ CHECK_BB(emit_exp_call1(emit, call->func->type->info->func, t->size, is_static_call(emit->gwion, call->func))); // is a ctor, is_static is true
return GW_OK;
}
#endif
const Type t = call->func->type;
-
if(unlikely(!is_func(emit->gwion, t))) {
const Type t = actual_type(emit->gwion, call->func->type);
struct Op_Import opi = {.op = insert_symbol("call_type"),
if (f != emit->env->func || (f && f->value_ref->from->owner_class))
CHECK_BB(prepare_call(emit, call));
else CHECK_BB(emit_func_args(emit, call));
- CHECK_BB(emit_exp_call1(emit, f, is_static_call(emit->gwion, call->func)));
+ CHECK_BB(emit_exp_call1(emit, f, exp_self(call)->type->size, is_static_call(emit->gwion, call->func)));
}
return GW_OK;
}
CHECK_BB(_emit_exp_call(emit, exp_call));
const Exp e = exp_self(exp_call);
if (exp_getvar(e)) {
- const m_uint size = exp_self(exp_call)->type->size;
+ const m_uint size = e->type->size;
emit_regmove(emit, -size);
const Local *l = e->ref ? e->ref->data : NULL;
const m_uint offset = l ? l->offset : emit_local_exp(emit, e);
}
ANN static void call_finish(const Emitter emit, const Func f,
- const bool is_static) {
+ const m_uint size, const bool is_static) {
const m_uint offset = emit_code_offset(emit);
if (f != emit->env->func || !is_static || !is_new(f->def))
emit_regsetimm(emit, offset, 0);
const Instr instr = emit_call(emit, f, is_static);
- instr->m_val = f->def->base->ret_type->size;
+ instr->m_val = size;
instr->m_val2 = offset;
}
ANN m_bool emit_exp_call1(const Emitter emit, const Func f,
- const bool is_static) {
+ const m_uint size, const bool is_static) {
const EmitterStatus status = emit->status;
emit->status = (EmitterStatus){};
if(unlikely(fflag(f, fflag_fptr))) emit_fptr_call(emit, f);
}
} else if(is_static)
push_func_code(emit, f);
- call_finish(emit, f, is_static);
+ call_finish(emit, f, size, is_static);
emit->status = status;
return GW_OK;
}
CHECK_BB(emit_ensure_func(emit, f));
push_spork_code(emit, sp->is_spork ? SPORK_FUNC_PREFIX : FORK_CODE_PREFIX,
sp->exp->pos);
- return emit_exp_call1(emit, f, false);
+ return emit_exp_call1(emit, f, f->def->base->ret_type->size, false);
}
ANN static VM_Code spork_prepare(const Emitter emit, const struct Sporker *sp) {
return CASE_PASS;
}
}
- } else if (isa(base->type, emit->gwion->type[et_union]) > 0 &&
+ } else if (tflag(base->type, tflag_union) &&
e->exp_type == ae_exp_call) {
const Exp func = e->d.exp_call.func;
if (func->d.prim.prim_type == ae_prim_id) {
scope_commit(nspc->info->trait);
}
-ANN static inline void nspc_release_object(const Nspc a, Value value,
- Gwion gwion) {
- if ((GET_FLAG(value, static) && a->class_data) ||
- (value->d.ptr && vflag(value, vflag_builtin))) {
- const M_Object obj =
- value->d.ptr ? (M_Object)value->d.ptr
- : *(M_Object *)(a->class_data + value->from->offset);
- release(obj, gwion->vm->cleaner_shred);
- }
-}
-
-ANN2(1, 3)
-static inline void nspc_release_struct(const Nspc a, Value value, Gwion gwion) {
- if (value && ((GET_FLAG(value, static) && a->class_data) ||
- (vflag(value, vflag_builtin) && value->d.ptr))) {
- const m_bit *ptr =
- (value && value->d.ptr)
- ? (m_bit *)value->d.ptr
- : (m_bit *)(a->class_data + value->from->offset);
- for (m_uint i = 0; i < vector_size(&value->type->info->tuple->types); ++i) {
- const Type t = (Type)vector_at(&value->type->info->tuple->types, i);
- if (isa(t, gwion->type[et_object]) > 0)
- release(*(M_Object *)(ptr +
- vector_at(&value->type->info->tuple->offset, i)),
- gwion->vm->cleaner_shred);
- else if (tflag(t, tflag_struct))
- nspc_release_struct(t->nspc, NULL, gwion);
- }
- }
-}
-
static inline void _free_nspc_value(const Nspc a, const Value v, Gwion gwion) {
if(v->from->ctx && v->from->ctx->error) return; // this is quite a hack
- if (tflag(v->type, tflag_compound) ) {
- if (!tflag(v->type, tflag_struct))
- nspc_release_object(a, v, gwion);
- else nspc_release_struct(a, v, gwion);
+ if (GET_FLAG(v, static) && a->class_data) {
+ const m_bit *ptr = *(m_bit **)(a->class_data + v->from->offset);
+ anytype_release(gwion->vm->cleaner_shred, v->type, ptr);
+ } else if (vflag(v, vflag_builtin) && v->d.ptr) {
+ const m_bit *ptr = (m_bit*)v->d.ptr;
+ anytype_release(gwion->vm->cleaner_shred, v->type, ptr);
}
value_remref(v, gwion);
}
describe_nspc_free(Type, type, type_remref(a, gwion));
describe_nspc_free(Trait, trait, free_trait(gwion->mp, a));
+ANN static void free_operators(NspcOp *a, const Gwion gwion) {
+ if (a->map.ptr) free_op_map(&a->map, gwion);
+ if (a->tmpl.ptr) free_op_tmpl(&a->tmpl, gwion);
+ mp_free(gwion->mp, NspcOp, a);
+
+}
ANN void free_nspc(const Nspc a, const Gwion gwion) {
nspc_free_value(a, gwion);
nspc_free_func(a, gwion);
nspc_free_trait(a, gwion);
- if(a->operators) {
- if (a->operators->map.ptr) free_op_map(&a->operators->map, gwion);
- if (a->operators->tmpl.ptr) free_op_tmpl(&a->operators->tmpl, gwion);
- mp_free(gwion->mp, NspcOp, a->operators);
- }
+ if(a->operators) free_operators(a->operators, gwion);
nspc_free_type(a, gwion);
if (a->class_data && a->class_data_size)
mp_free2(gwion->mp, a->class_data_size, a->class_data);
&*(m_bit *)(ARRAY_PTR(a) + i * SZ_INT));
}
+static DTOR(array_dtor_union) {
+ struct M_Vector_ *a = ARRAY(o);
+ for (m_uint i = 0; i < ARRAY_LEN(a); ++i)
+ union_release(shred, array_base(o->type_ref),
+ &*(m_bit *)(ARRAY_PTR(a) + i * SZ_INT));
+}
+
ANN M_Object new_array(MemPool p, const Type t, const m_uint length) {
const M_Object a = new_object(p, t);
const m_uint depth =
m_vector_rem(v, (vtype)index);
}
+static MFUN(vm_vector_rem_union) {
+ const m_int index = *(m_int *)(shred->mem + SZ_INT);
+ const M_Vector v = ARRAY(o);
+ if (index < 0 || (m_uint)index >= ARRAY_LEN(v)) return;
+ const Type t = o->type_ref;
+ union_release(shred, array_base(t), ARRAY_PTR(v) + index * ARRAY_SIZE(v));
+ m_vector_rem(v, (vtype)index);
+}
+
static MFUN(vm_vector_insert) {
const m_int index = *(m_int *)(shred->mem + SZ_INT);
const M_Vector v = ARRAY(o);
const M_Vector v = ARRAY(o);
if (index < 0 || (m_uint)index > ARRAY_LEN(v)) return;
m_vector_insert(v, index, shred->mem + SZ_INT * 2);
- struct_addref(shred->info->vm->gwion, array_base(o->type_ref),
- shred->mem + SZ_INT * 2);
+ struct_addref(array_base(o->type_ref), shred->mem + SZ_INT * 2);
+}
+
+static MFUN(vm_vector_insert_union) {
+ const m_int index = *(m_int *)(shred->mem + SZ_INT);
+ const M_Vector v = ARRAY(o);
+ if (index < 0 || (m_uint)index > ARRAY_LEN(v)) return;
+ m_vector_insert(v, index, shred->mem + SZ_INT * 2);
+ union_addref(array_base(o->type_ref), shred->mem + SZ_INT * 2);
}
static MFUN(vm_vector_size) { *(m_uint *)RETURN = ARRAY_LEN(ARRAY(o)); }
builtin_func(env->gwion, v->d.func_ref, fun);
}
+ANN static f_xfun get_rem(const Type t) {
+ if(!tflag(t, tflag_release)) return vm_vector_rem;
+ if(!tflag(t, tflag_struct)) return vm_vector_rem_obj;
+ if(!tflag(t, tflag_union)) return vm_vector_rem_struct;
+ return vm_vector_rem_union;
+}
+
+ANN static f_xfun get_insert(const Type t) {
+ if(!tflag(t, tflag_release)) return vm_vector_insert;
+ if(!tflag(t, tflag_struct)) return vm_vector_insert_obj;
+ if(!tflag(t, tflag_union)) return vm_vector_insert_struct;
+ return vm_vector_insert_union;
+}
+
+ANN static f_xfun get_dtor(const Type t) {
+ if(!tflag(t, tflag_struct)) return array_dtor_obj;
+ if(!tflag(t, tflag_union)) return array_dtor_struct;
+ return array_dtor_union;
+}
+
static OP_CHECK(opck_array_scan) {
struct TemplateScan *ts = (struct TemplateScan *)data;
const Type t_array = env->gwion->type[et_array];
env_set_error(env, true);
return env->gwion->type[et_error];
}
-/*
- if (!strncmp(base->name, "Option:[", 5)) {
- gwerr_basic("Can't use option types as array base", NULL, NULL, "/dev/null",
- (loc_t) {}, 0);
- env_set_error(env, true);
- return env->gwion->type[et_error];
- }
-*/
const Symbol sym = array_sym(env, array_base_simple(base), base->array_depth + 1);
const Type type = nspc_lookup_type1(base->info->value->from->owner, sym);
if (type) return type;
t->array_depth = base->array_depth + 1;
t->info->base_type = array_base(base);
set_tflag(t, tflag_cdef | tflag_tmpl);
- void *rem = tflag(base, tflag_compound)
- ? !tflag(base, tflag_struct) ? vm_vector_rem_obj
- : vm_vector_rem_struct
- : vm_vector_rem;
- builtin_func(env->gwion, (Func)vector_at(&t->nspc->vtable, 0), rem);
- void *insert = tflag(base, tflag_compound)
- ? !tflag(base, tflag_struct) ? vm_vector_insert_obj
- : vm_vector_insert_struct
- : vm_vector_insert;
- array_func(env, t, "insert", insert);
+
+ builtin_func(env->gwion, (Func)vector_at(&t->nspc->vtable, 0), get_rem(t));
+ array_func(env, t, "insert", get_insert(t));
array_func(env, t, "size", vm_vector_size);
array_func(env, t, "depth", vm_vector_depth);
array_func(env, t, "cap", vm_vector_cap);
array_func(env, t, "count", vm_vector_count);
array_func(env, t, "foldl", vm_vector_foldl);
array_func(env, t, "foldr", vm_vector_foldr);
-// array_func(env, t, "new", vm_vector_new);
if (tflag(base, tflag_compound)) {
t->nspc->dtor = new_vmcode(env->gwion->mp, NULL, NULL,
"array component dtor", SZ_INT, true, false);
set_tflag(t, tflag_dtor);
- t->nspc->dtor->native_func = (m_uint)(
- !tflag(base, tflag_struct) ? array_dtor_obj : array_dtor_struct);
+ t->nspc->dtor->native_func = (m_uint)get_dtor(base);
}
return t;
}
#define HMAP_MIN_CAP 32
#define HMAP_MAX_LOAD 0.75
-typedef void (clear_fn)(const HMap*, const VM_Shred, const struct HMapInfo*, const m_uint);
-
// TODO: arch sensible hash
static SFUN(mfun_int_h) {
m_int x = *(m_uint*)MEM(0);
*(m_int*)RETURN = hash(STRING(*(M_Object*)MEM(0)));
}
-ANN static void clear_oo(const HMap *a, const VM_Shred shred, const HMapInfo *info NUSED, const m_uint idx) {
- release(*(M_Object*)(a->data + idx * SZ_INT*2), shred);
- release(*(M_Object*)((a->data + idx * SZ_INT*2) + SZ_INT), shred);
-}
-
-ANN static void clear_ss(const HMap *a, const VM_Shred shred, const HMapInfo *info, const m_uint idx) {
- struct_release(shred, info->key, a->data + idx * info->sz);
- struct_release(shred, info->val, a->data + idx * info->sz + info->key->size);
-}
-
-ANN static void clear_os(const HMap *a, const VM_Shred shred, const HMapInfo *info, const m_uint idx) {
- release(*(M_Object*)(a->data + idx * info->sz), shred);
- struct_release(shred, info->val, a->data + idx * info->sz + SZ_INT);
-}
-
-ANN static void clear_so(const HMap *a, const VM_Shred shred, const HMapInfo *info, const m_uint idx) {
- struct_release(shred, info->key, a->data + idx * info->sz);
- release(*(M_Object*)(a->data + idx * info->sz + info->key->size), shred);
-}
-
-ANN static void clear_on(const HMap *a, const VM_Shred shred, const HMapInfo *info, const m_uint idx) {
- release(*(M_Object*)(a->data + idx * info->sz), shred);
-}
-
-ANN static void clear_sn(const HMap *a, const VM_Shred shred, const HMapInfo *info, const m_uint idx) {
- struct_release(shred, info->key, a->data + idx * info->sz);
-}
-
-ANN static void clear_no(const HMap *a, const VM_Shred shred, const HMapInfo *info, const m_uint idx) {
- release(*(M_Object*)(a->data + idx * info->sz + info->key->size), shred);
-}
-
-
-ANN static void clear_ns(const HMap *a, const VM_Shred shred, const HMapInfo *info, const m_uint idx) {
- struct_release(shred, info->val, a->data + idx * info->sz + info->key->size);
+ANN static void clear_all(const HMap *a, const VM_Shred shred, const HMapInfo *info, const m_uint idx) {
+ compound_release(shred, info->key, a->data + idx * info->sz);
+ compound_release(shred, info->val, a->data + idx * info->sz + info->key->size);
}
-static clear_fn *const n_clear[3] = { NULL, clear_no, clear_ns };
-static clear_fn* o_clear[3] = { clear_on, clear_oo, clear_os };
-static clear_fn* s_clear[3] = { clear_sn, clear_so, clear_ss };
-static clear_fn*const* clear[3] = { n_clear, o_clear, s_clear };
-
ANN static void hmapinfo_init(HMapInfo *const info, const Type key, const Type val) {
info->key = key;
info->val = val;
info->sz = key->size + val->size;
- info->keyk = tflag(key, tflag_compound) + tflag(key, tflag_struct);
- info->valk = tflag(val, tflag_compound) + tflag(val, tflag_struct);
}
static DTOR(dict_clear_dtor) {
const HMapInfo *hinfo = (HMapInfo*)o->type_ref->nspc->class_data;
- clear_fn *fn = clear[hinfo->keyk][hinfo->valk];
HMap *a = &*(struct HMap*)o->data;
for(m_uint i = a->capacity; --i;) {
const HState state = *(HState*)(a->state + (i-1) * sizeof(HState));
if(!state.set || state.deleted) continue;
- fn(a, shred, hinfo, i-1);
+ clear_all(a, shred, hinfo, i-1);
}
}
HState *const state = (HState*)(hmap->state + sizeof(HState) * bucket);
m_bit *const data = hmap->data + hinfo->sz * bucket;
if (!state->set || state->deleted) {
-
- if(hinfo->keyk) {
- if(hinfo->keyk == HKIND_OBJ)
- (*(M_Object*)REG(-instr->m_val))->ref++;
- else
- struct_addref(shred->info->vm->gwion, hinfo->key, REG(-instr->m_val));
- }
-
+ compound_addref(hinfo->key, REG(-instr->m_val));
state->set = true;
state->deleted = false;
memcpy(data, REG(-instr->m_val), instr->m_val);
memcpy(REG(-hinfo->val->size), new_data + hinfo->key->size, hinfo->val->size);
}
-static INSTR(hmap_remove_clear) {
- const M_Object o = *(M_Object*)(shred->reg - SZ_INT*2);
- const HMap *hmap = (HMap*)o->data;
- const HMapInfo *hinfo = (HMapInfo*)o->type_ref->nspc->class_data;
- const m_uint bucket = *(m_uint*)REG(0);
- clear_fn *fn = (clear_fn*)instr->m_val;
- fn(hmap, shred, hinfo, bucket);
-}
-
static INSTR(hmap_remove) {
const M_Object o = *(M_Object*)(shred->reg - SZ_INT*2);
HMap *const hmap = (HMap*)o->data;
const HMapInfo *hinfo = (HMapInfo*)o->type_ref->nspc->class_data;
const m_uint bucket = *(m_uint*)REG(0);
+ clear_all(hmap, shred, hinfo, bucket);
m_bit *data = hmap->data + hinfo->sz * bucket;
hmap->count--;
HState *const state = (HState *)(hmap->state + bucket * sizeof(HState));
emit_add_instr(emit, hmap_grow_dec);
const Instr endgrow = emit_add_instr(emit, BranchNeqInt);
CHECK_BB(emit_exp(emit, call.d.exp_call.func));
- CHECK_BB(emit_exp_call1(emit, call.d.exp_call.func->type->info->func, true));
+ CHECK_BB(emit_exp_call1(emit, call.d.exp_call.func->type->info->func,
+ call.d.exp_call.func->type->info->func->def->base->ret_type->size, true));
emit_add_instr(emit, hmap_find);
const Instr regrow = emit_add_instr(emit, BranchEqInt);
regrow->m_val = grow_pc;
CHECK_BB(traverse_exp(env, &call));
CHECK_BB(emit_dict_iter(emit, hinfo, &opi, &call, bin->lhs));
- if(hinfo->keyk || hinfo->valk) {
- clear_fn *const fn = clear[hinfo->keyk][hinfo->valk];
- const Instr instr = emit_add_instr(emit, hmap_remove_clear);
- instr->m_val = (m_uint)fn;
- }
-
const Instr pushval = emit_add_instr(emit, hmap_remove);
pushval->m_val2 = hinfo->key->size;
return GW_OK;
}
HMapInfo *const hinfo = (HMapInfo*)t->nspc->class_data;
hmapinfo_init(hinfo, key, val);
- if(hinfo->keyk + hinfo->valk) {
+ if(tflag(key, tflag_release) || tflag(val, tflag_release)) {
t->nspc->dtor = new_vmcode(env->gwion->mp, NULL, NULL, "@dtor", SZ_INT, true, false);
t->nspc->dtor->native_func = (m_uint)dict_clear_dtor;
set_tflag(t, tflag_dtor);
return GW_OK;
}
+static INSTR(UnionIndex) {
+ // probs exosts already
+ *(m_uint*)REG(-SZ_INT) = **(m_uint**)REG(-SZ_INT);
+}
static OP_EMIT(opem_union_dot) {
const Exp_Dot *member = (Exp_Dot *)data;
const Map map = &member->base->type->nspc->info->value->map;
+ exp_setvar(member->base, true);
CHECK_BB(emit_exp(emit, member->base));
if (is_func(emit->gwion, exp_self(member)->type)) { // is_callable? can only be a func
emit_pushimm(emit, (m_uint)exp_self(member)->type->info->func->code);
return GW_OK;
}
if (!strcmp(s_name(member->xid), "index")) {
- emit_add_instr(emit, DotMember);
+ //emit_add_instr(emit, DotMember);
+ emit_add_instr(emit, UnionIndex);
return GW_OK;
}
for (m_uint i = 0; i < map_size(map); ++i) {
return GW_ERROR;
}
-static DTOR(UnionDtor) {
- const m_uint idx = *(m_uint *)o->data;
+ANN void union_release(const VM_Shred shred, const Type t, const m_bit *data) {
+ const m_uint idx = *(m_uint *)data;
if (idx) {
- const Map map = &o->type_ref->nspc->info->value->map;
+ const Map map = &t->nspc->info->value->map;
const Value v = (Value)map_at(map, idx - 1);
if (tflag(v->type, tflag_compound))
- compound_release(shred, v->type, (o->data + SZ_INT));
+ compound_release(shred, v->type, data + SZ_INT);
}
}
}
static MFUN(union_new) {
- memcpy(o->data, MEM(SZ_INT*2), *(m_uint*)MEM(SZ_INT));
- *(M_Object *)RETURN = o;
+ m_bit *data = *(m_bit**)MEM(0);
+ memcpy(data, MEM(SZ_INT*2), *(m_uint*)MEM(SZ_INT));
+ memcpy((m_bit*)RETURN, data, *(m_uint*)MEM(SZ_INT));
}
-
+#include "parse.h"
+#undef insert_symbol
static OP_CHECK(opck_union_new) {
Exp_Call *call = (Exp_Call *)data;
const Exp name = call->args;
- if (!name || !name->next || name->next->next)
- ERR_N(call->func->pos, "Union constructor takes two arguments, "
+ if (!name)
+ ERR_N(call->func->pos, "Union constructor takes one or two arguments, "
"'id' and 'value'");
if (name->exp_type != ae_exp_primary || name->d.prim.prim_type != ae_prim_id)
- return env->gwion->type[et_error];
+ ERR_N(call->func->pos, "Union constructor first argument me be an identifier");
const Exp val = name->next;
const Type base = call->func->d.exp_dot.base->type;
const Map map = &base->nspc->info->value->map;
+
for (m_uint i = 0; i < map_size(map); ++i) {
if (VKEY(map, i) == (m_uint)name->d.prim.d.var) {
const Value v = (Value)VVAL(map, i);
name->d.prim.prim_type = ae_prim_num;
name->d.prim.d.num = i;
name->type = env->gwion->type[et_int];
- DECL_ON(const Type, t, = check_exp(env, val));
- if (isa(t, v->type) < 0) {
- ERR_N(val->pos, "Invalid type '%s' for '%s', should be '%s'", t->name,
- v->name, v->type->name);
+ if(!val && v->type == env->gwion->type[et_none]) {
+ const Exp e = new_prim_int(env->gwion->mp, SZ_INT, name->pos);
+ e->next = name;
+ e->type = env->gwion->type[et_int];
+ name->next = new_prim_int(env->gwion->mp, 0, name->pos);
+ name->next->type = env->gwion->type[et_int];
+ call->args = e;
+ } else {
+ if (val->next)
+ ERR_N(call->func->pos, "too many arguments for union constructor");
+ DECL_ON(const Type, t, = check_exp(env, val));
+ if (check_implicit(env, val, v->type) < 0) { // add implicit
+ ERR_N(val->pos, "Invalid type '%s' for '%s', should be '%s'", t->name,
+ v->name, v->type->name);
+ }
+ const Exp e = new_prim_int(env->gwion->mp, t->size + SZ_INT, val->pos);
+ e->next = name;
+ e->type = env->gwion->type[et_int];
+ call->args = e;
}
- const Exp e = new_prim_int(env->gwion->mp, t->size + SZ_INT, val->pos);
- e->next = name;
- e->type = env->gwion->type[et_int];
- call->args = e;
return base;
}
}
- return env->gwion->type[et_error];
+ ERR_N(name->pos, "%s has no member %s\n", base->name, s_name(name->d.prim.d.var));
}
ANN GWION_IMPORT(union) {
GWI_BB(gwi_oper_emi(gwi, opem_none))
GWI_BB(gwi_oper_end(gwi, ":=>", NoOp))
- const Type t_union = gwi_class_ini(gwi, "union", "Object");
- gwi_class_xtor(gwi, NULL, UnionDtor);
+ const Type t_union = gwi_struct_ini(gwi, "union");
+ //gwi_class_xtor(gwi, NULL, UnionDtor);
gwi->gwion->type[et_union] = t_union;
GWI_BB(gwi_item_ini(gwi, "int", "index"))
GWI_BB(gwi_item_end(gwi, ae_flag_const, num, 0))
+ /*
+ GWI_BB(gwi_func_ini(gwi, "void", "@ctor"))
+ GWI_BB(gwi_func_end(gwi, union_ctor, ae_flag_none))
+ */
GWI_BB(gwi_func_ini(gwi, "bool", "is"))
GWI_BB(gwi_func_arg(gwi, "int", "member"))
GWI_BB(gwi_func_end(gwi, union_is, ae_flag_none))
GWI_BB(gwi_func_arg(gwi, "int", "id"))
GWI_BB(gwi_func_arg(gwi, "T", "value"))
GWI_BB(gwi_func_end(gwi, union_new, ae_flag_none))
+
GWI_BB(gwi_class_end(gwi))
- const Func f = (Func)vector_front(&t_union->nspc->vtable);
+ const Func f = (Func)vector_at(&t_union->nspc->vtable, 0);
const struct Op_Func opfunc = {.ck = opck_union_is};
const struct Op_Import opi = {
.rhs = f->value_ref->type,
.op = insert_symbol(gwi->gwion->st, "@func_check")};
CHECK_BB(add_op(gwi->gwion, &opi1));
- gwi->gwion->type[et_union] = t_union;
-
GWI_BB(gwi_oper_ini(gwi, "union", (m_str)OP_ANY_TYPE, NULL))
GWI_BB(gwi_oper_emi(gwi, opem_union_dot))
GWI_BB(gwi_oper_end(gwi, ".", NULL))
return NULL;
}
}
- } else if (isa(base, env->gwion->type[et_union]) > 0 &&
+ } else if (tflag(base, tflag_union) &&
e->exp_type == ae_exp_call) {
const Exp func = e->d.exp_call.func;
if (func->d.prim.prim_type == ae_prim_id) {
ANN static m_bool handle_instr(const Emitter emit, const M_Operator *mo) {
if (mo->func) {
emit_pushfunc(emit, mo->func);
- CHECK_BB(emit_exp_call1(emit, mo->func, true));
+ CHECK_BB(emit_exp_call1(emit, mo->func,
+ mo->func->def->base->ret_type->size, true));
if (mo->func->def->base->xid ==
insert_symbol(emit->gwion->st, "@conditional"))
emit_add_instr(emit, BranchEqInt);
return GW_OK;
}
+static INSTR(StructAssign) {
+ memcpy(*(m_bit**)REG(-SZ_INT), REG((m_int)instr->m_val), instr->m_val2);
+}
+
+static OP_EMIT(opem_struct_assign) {
+ const Exp_Binary *bin = data;
+ const Type t = bin->lhs->type;
+ const Exp e = exp_self(bin);
+
+ if(tflag(t, tflag_release)) {
+ const f_instr exec = !tflag(t, tflag_union)
+ ? StructReleaseRegAddr
+ : UnionReleaseRegAddr;
+ const Instr release = emit_add_instr(emit, exec);
+ release->m_val = -SZ_INT;
+ release->m_val2 = (m_uint)t;
+ }
+
+ const Instr instr = emit_add_instr(emit, StructAssign);
+ instr->m_val = -t->size - SZ_INT;
+ instr->m_val2 = t->size;
+ emit_struct_addref(emit, t, -SZ_INT, true);
+ if(exp_getvar(e)) {
+ emit_regmove(emit, -t->size);
+ const Instr instr = emit_add_instr(emit, Reg2Reg);
+ instr->m_val = -SZ_INT;
+ instr->m_val2 = t->size - SZ_INT;
+ } else emit_regmove(emit, -SZ_INT);
+ return GW_OK;
+}
+
+ANN static OP_CHECK(opck_struct_assign) {
+ CHECK_NN(opck_rassign(env, data));
+ Exp_Binary *bin = data;
+ bin->rhs->ref = bin->lhs;
+ return bin->lhs->type;
+}
+
+ANN static void scan0_struct_assign(const Env env, const Type t) {
+ struct Op_Func opfunc = {.ck = opck_struct_assign, .em = opem_struct_assign };
+ struct Op_Import opi = {
+ .op = insert_symbol(":=>"), .lhs = t, .rhs = t, .ret = t, .func = &opfunc};
+ add_op(env->gwion, &opi);
+}
+
ANN static Type union_type(const Env env, const Symbol s, const loc_t loc) {
const m_str name = s_name(s);
const Type t = new_type(env->gwion->mp, name, env->gwion->type[et_union]);
t->nspc->parent = env->curr;
t->info->tuple = new_tupleform(env->gwion->mp, NULL); // ???
set_tflag(t, tflag_union);
+ set_tflag(t, tflag_struct);
add_type(env, env->curr, t);
mk_class(env, t, loc);
SET_FLAG(t, final);
set_tflag(t, tflag_compound);
- if (strncmp(t->name, "Option", 6)) SET_FLAG(t, abstract);
+ SET_FLAG(t, abstract);
+ scan0_struct_assign(env, t);
return t;
}
ANN Ast spread_class(const Env env, const Ast body);
-static INSTR(StructAssign) {
- memcpy(*(m_bit**)REG(-SZ_INT), REG((m_int)instr->m_val), instr->m_val2);
-}
-
-static OP_EMIT(opem_struct_assign) {
- const Exp_Binary *bin = data;
- const Type t = bin->lhs->type;
- const Exp e = exp_self(bin);
-
- if(tflag(t, tflag_release)) {
- const Instr release = emit_add_instr(emit, StructReleaseRegAddr);
- release->m_val = -SZ_INT;
- release->m_val2 = (m_uint)t;
- }
-
- const Instr instr = emit_add_instr(emit, StructAssign);
- instr->m_val = -t->size - SZ_INT;
- instr->m_val2 = t->size;
- emit_struct_addref(emit, t, -SZ_INT, true); // add ref on lhs
- if(exp_getvar(e)) {
- emit_regmove(emit, -t->size);
- const Instr instr = emit_add_instr(emit, Reg2Reg);
- instr->m_val = -SZ_INT;
- instr->m_val2 = t->size - SZ_INT;
- } else emit_regmove(emit, -SZ_INT);
- return GW_OK;
-}
-
-ANN static OP_CHECK(opck_struct_assign) {
- CHECK_NN(opck_rassign(env, data));
- Exp_Binary *bin = data;
- bin->rhs->ref = bin->lhs;
- return bin->lhs->type;
-}
-
-ANN static void scan0_struct_assign(const Env env, const Type t) {
- struct Op_Func opfunc = {.ck = opck_struct_assign, .em = opem_struct_assign };
- struct Op_Import opi = {
- .op = insert_symbol(":=>"), .lhs = t, .rhs = t, .ret = t, .func = &opfunc};
- add_op(env->gwion, &opi);
-}
-
ANN m_bool scan0_class_def(const Env env, const Class_Def c) {
DECL_BB(const m_bool, global, = scan0_global(env, c->flag, c->pos));
const Ast old_extend = env->context ? env->context->extend : NULL;
if (t->size > sz) sz = t->size;
}
udef->type->nspc->offset = SZ_INT + sz;
+ udef->type->size = SZ_INT + sz;
return GW_OK;
}
if (opt) *opt = '\0';
for (m_uint i = 0; i < map_size(map); ++i) {
const m_str name = (m_str)VKEY(map, i);
- printf("%s %s\n", name, dname);
if (!strcmp(name, dname)) {
- puts("hey");
const Plug plug = (Plug)VVAL(map, i);
const gwdriver_t drv = plug->driver;
if (!drv) break;
&&forkend, &&sporkend, &&brancheqint, &&branchneint, &&brancheqfloat,
&&branchnefloat, &&unroll, &&arrayappend, &&autounrollinit, &&autoloop,
&&arraytop, &&arrayaccess, &&arrayget, &&arrayaddr, &&newobj, &&addref,
- &&addrefaddr, &&structaddref, &&structaddrefaddr, &&objassign, &&assign,
+ &&addrefaddr, &&structaddref, &&structaddrefaddr,
+ &&unionaddref, &&unionaddrefaddr,
+ &&objassign, &&assign,
&&_remref, &&_remref2, &&_structreleaseregaddr, &&structreleasemem,
+ &&_unionreleaseregaddr, &&unionreleasemem,
&&_except,
&&dotmembermem, &&dotmembermem2, /*&&dotmembermem3, */&&dotmembermem4,
&&dotmember, &&dotfloat, &&dotother, &&dotaddr,
*(m_uint *)(reg + IVAL) = *(m_uint *)(reg + IVAL2);
DISPATCH()
regtoregother2:
- memcpy(reg - VAL2, reg + IVAL, VAL2);
+ //memcpy(reg - VAL2, reg + IVAL, VAL2);
+ memmove(reg - VAL2, reg + IVAL, VAL2);
DISPATCH()
regtoregaddr:
*(m_uint **)(reg + IVAL) = &*(m_uint *)(reg + IVAL2);
}
DISPATCH()
structaddref:
- struct_addref(vm->gwion, (Type)VAL2, (reg + IVAL));
+ struct_addref((Type)VAL2, (reg + IVAL));
DISPATCH()
structaddrefaddr:
- struct_addref(vm->gwion, (Type)VAL2, *(m_bit **)(reg + IVAL));
+ struct_addref((Type)VAL2, *(m_bit **)(reg + IVAL));
+ DISPATCH()
+ unionaddref:
+ union_addref((Type)VAL2, (reg + IVAL));
+ DISPATCH()
+ unionaddrefaddr:
+ union_addref((Type)VAL2, *(m_bit **)(reg + IVAL));
DISPATCH()
objassign : {
const M_Object o = **(M_Object **)(reg - SZ_INT);
structreleasemem:
struct_release(shred, (Type)VAL2, mem + IVAL);
DISPATCH();
+ unionreleaseregaddr:
+ union_release(shred, (Type)VAL2, *(m_bit**)(reg + IVAL));
+ DISPATCH();
+ unionreleasemem:
+ union_release(shred, (Type)VAL2, mem + IVAL);
+ DISPATCH();
except:
/* TODO: Refactor except instruction *
* so that *
DISPATCH()
#define UNION_CHECK \
- register const m_bit *data = (*(M_Object *)(reg - SZ_INT))->data; \
+ register const m_bit *data = (*(m_bit**)(reg - SZ_INT)); \
if (*(m_uint *)data != VAL) { \
- handle(shred, "invalid union acces"); \
+ handle(shred, "InvalidUnionAcces"); \
continue; \
}
unioncheck : {
- if (*(m_uint *)(*(M_Object *)(reg - SZ_INT))->data != VAL2) {
+ if (*(m_uint *)(*(m_bit* *)(reg - SZ_INT)) != VAL2) {
reg -= SZ_INT;
PC_DISPATCH(VAL);
}
DISPATCH()
}
unionaddr : {
- *(m_uint *)(*(M_Object *)(reg - SZ_INT))->data = VAL;
- *(m_bit **)(reg - SZ_INT) =
- &*(m_bit *)((*(M_Object *)(reg - SZ_INT))->data + SZ_INT);
+ m_bit *data = *(m_bit**)(reg-SZ_INT);
+ *(m_uint*)data = VAL;
+ *(m_bit **)(reg - SZ_INT) = data + SZ_INT;
DISPATCH()
}
staticint:
&&_sporkend, &&_brancheqint, &&_branchneint, &&_brancheqfloat,
&&_branchnefloat, &&_unroll, &&_arrayappend, &&_autounrollinit, &&_autoloop,
&&_arraytop, &&_arrayaccess, &&_arrayget, &&_arrayaddr, &&_newobj, &&_addref,
- &&_addrefaddr, &&_structaddref, &&_structaddrefaddr, &&_objassign, &&_assign,
+ &&_addrefaddr, &&_structaddref, &&_structaddrefaddr,
+ &&_unionaddref, &&_unionaddrefaddr, &&_objassign, &&_assign,
&&_remref, &&_remref2, &&_structreleaseregaddr, &&_structreleasemem,
+ &&_unionreleaseregaddr, &&_unionreleasemem,
&&_except,
&&_dotmembermem, &&_dotmembermem2, /*&&_dotmembermem3, */&&_dotmembermem4,
&&_dotmember, &&_dotfloat, &&_dotother, &&_dotaddr,
PREPARE(addrefaddr);
PREPARE(structaddref);
PREPARE(structaddrefaddr);
+ PREPARE(unionaddref);
+ PREPARE(unionaddrefaddr);
PREPARE(objassign);
PREPARE(assign);
PREPARE(remref);
PREPARE(remref2);
PREPARE(structreleaseregaddr);
PREPARE(structreleasemem);
+ PREPARE(unionreleaseregaddr);
+ PREPARE(unionreleasemem);
PREPARE(except);
PREPARE(dotmembermem);
PREPARE(dotmembermem2);
class C {
- 1 :=> test;
+ 1 => test;
fun int test(int i) {
13 :=> var int j;
return j;
}
var C c;
-12 => c.test => var int ret;
+12 => c.test :=> var int ret;
<<< 1394 >>>;
<<<ret>>>;
+++ /dev/null
-
-struct S {
- 13 :=> var int i;
- operator void @gack () { <<< "test", i >>>; }
- <<< this >>>;
-}
-
-var S s;
-<<< s >>>;
+++ /dev/null
-struct global GlobalStruct {
- var int i;
- var float f;
- var string s;
-}
-
-struct global GlobalStructWithCtor {
- var int i;
- var float f;
- var string s;
-}
-
-var global GlobalStruct global_s;
-var GlobalStructWithCtor sctor;
+++ /dev/null
-var GlobalStruct s;
#! [contains] 12
-var int? i;
-<<< 12 :=> i.val >>>;
+var int?(val, 12) i;
<<< i.val >>>;
#! [contains] val: 12
-var int? i;
+var int?(none) i;
12 :=> i.val;
if(i.is(val))
-#! [contains] invalid union acces
-var int? i;
+#! [contains] InvalidUnionAcces
+var int?(none) i;
<<< i.val >>>;