From 768624ba067ef7b574b2e3d39fa076388fe8d995 Mon Sep 17 00:00:00 2001 From: =?utf8?q?J=C3=A9r=C3=A9mie=20Astor?= Date: Sat, 19 Jun 2021 22:31:37 +0200 Subject: [PATCH] :art: Fixes --- ast | 2 +- include/emit.h | 6 ++-- include/env/env.h | 1 + include/env/func.h | 5 +-- include/env/nspc.h | 17 +++++----- include/env/value.h | 3 +- include/instr.h | 2 +- include/parse.h | 7 ++-- include/vm.h | 23 ++++++------- src/emit/emit.c | 51 ++++++++++++++++------------- src/import/import_checker.c | 2 +- src/lib/array.c | 11 +++++-- src/lib/engine.c | 1 - src/lib/lib_func.c | 64 ++++++++++++++++++++----------------- src/lib/object_op.c | 10 ++++-- src/lib/prim.c | 4 +-- src/lib/shred.c | 4 +-- src/lib/string.c | 15 +++------ src/lib/ugen.c | 6 ++-- src/main.c | 2 ++ src/parse/check.c | 15 ++++----- src/parse/scan1.c | 4 +-- src/parse/scan2.c | 10 +++--- src/parse/template.c | 23 +++++++++---- 24 files changed, 162 insertions(+), 126 deletions(-) diff --git a/ast b/ast index 5796cf89..476773ee 160000 --- a/ast +++ b/ast @@ -1 +1 @@ -Subproject commit 5796cf89170539636d4f1405c59bc938e055acb0 +Subproject commit 476773eed83abcd74bf28cccebc59cf9eccca8bb diff --git a/include/emit.h b/include/emit.h index 2d6a7770..56837bcf 100644 --- a/include/emit.h +++ b/include/emit.h @@ -11,7 +11,7 @@ typedef struct Frame_ { } Frame; typedef struct VMValue_ { - Type t; + Type t; uint16_t offset; uint16_t start; uint16_t end; @@ -87,11 +87,13 @@ ANN static inline bool is_static_call(const Emitter emit, const Exp e) { if (e->exp_type != ae_exp_dot) return true; const Exp_Dot *member = &e->d.exp_dot; return GET_FLAG(member->base->type, final) || + !vflag(exp_self(member)->type->info->value, vflag_member) || is_class(emit->gwion, member->base->type) || member->base->exp_type == ae_exp_cast; } -ANN Instr emit_kind(Emitter, const m_uint size, const bool addr, const f_instr func[]); +ANN Instr emit_kind(Emitter, const m_uint size, const bool addr, + const f_instr func[]); ANN Instr emit_regpushimm(Emitter, const m_uint, const bool); ANN Instr emit_regpushmem(Emitter, const m_uint, const bool); ANN Instr emit_regpushbase(Emitter, const m_uint, const bool); diff --git a/include/env/env.h b/include/env/env.h index 7ece02a5..822956c4 100644 --- a/include/env/env.h +++ b/include/env/env.h @@ -25,6 +25,7 @@ struct Env_Scope_ { uint16_t depth; bool in_try; bool in_loop; + bool allow_curry; }; typedef struct Env_ { diff --git a/include/env/func.h b/include/env/func.h index f2a5d968..d567a548 100644 --- a/include/env/func.h +++ b/include/env/func.h @@ -7,8 +7,9 @@ enum fflag { fflag_ftmpl = 1 << 2, fflag_tmpl = 1 << 3, fflag_valid = 1 << 4, - fflag_return = 1 << 5, - fflag_recurs = 1 << 6, + fflag_emit = 1 << 5, + fflag_return = 1 << 6, + fflag_recurs = 1 << 7, } __attribute__((packed)); struct Func_ { diff --git a/include/env/nspc.h b/include/env/nspc.h index a988f253..53624c66 100644 --- a/include/env/nspc.h +++ b/include/env/nspc.h @@ -1,14 +1,15 @@ #ifndef __NSPC #define __NSPC struct NspcInfo_ { - m_bit * class_data; - struct Map_ op_map; - Scope value; - Scope type; - Scope func; - Scope trait; - size_t offset; - size_t class_data_size; + m_bit * class_data; + struct Map_ op_map; + Scope value; + Scope type; + Scope func; + Scope trait; + struct Vector_ op_map_tmpl; + uint16_t offset; + uint16_t class_data_size; }; struct Nspc_ { diff --git a/include/env/value.h b/include/env/value.h index c4c70097..67879b7b 100644 --- a/include/env/value.h +++ b/include/env/value.h @@ -46,6 +46,7 @@ ANEW ANN Value new_value(MemPool p, const Type type, const m_str name); ANN void valuefrom(const Env, struct ValueFrom_ *, const loc_t loc); ANN static inline void defined_here(const Value v) { - gwerr_secondary(_("defined here"), v->from->filename, v->from->loc); + if (v->from->filename) // TODO: check why is that from check + gwerr_secondary(_("defined here"), v->from->filename, v->from->loc); } #endif diff --git a/include/instr.h b/include/instr.h index b2887574..82bf384f 100644 --- a/include/instr.h +++ b/include/instr.h @@ -11,7 +11,7 @@ __attribute__((hot)) ANN2(1) void a(const VM_Shred shred NUSED, \ const Instr instr NUSED) -//enum Kind { KIND_INT, KIND_FLOAT, KIND_OTHER, KIND_ADDR }; +// enum Kind { KIND_INT, KIND_FLOAT, KIND_OTHER, KIND_ADDR }; typedef struct Instr_ *Instr; typedef void (*f_instr)(const VM_Shred, const Instr); diff --git a/include/parse.h b/include/parse.h index 4de09fd6..0bd829e9 100644 --- a/include/parse.h +++ b/include/parse.h @@ -101,10 +101,9 @@ ANN static inline void env_inline_mult(const Env env, const float mult) { ANN static inline bool is_hole(const Env env, const Exp exp) { const Symbol hole = insert_symbol("_"); - if(exp->exp_type == ae_exp_primary) { - if(exp->d.prim.prim_type == ae_prim_id) { - if(exp->d.prim.d.var == hole) - return true; + if (exp->exp_type == ae_exp_primary) { + if (exp->d.prim.prim_type == ae_prim_id) { + if (exp->d.prim.d.var == hole) return true; } } return false; diff --git a/include/vm.h b/include/vm.h index 1735c550..777e33ee 100644 --- a/include/vm.h +++ b/include/vm.h @@ -16,19 +16,19 @@ struct VM_Code_ { struct Vector_ instr; m_uint native_func; }; - Type ret_type; // could be `struct Vector_ tmpl_types;` + Type ret_type; // could be `struct Vector_ tmpl_types;` union { void * memoize; Closure *closure; }; - m_str name; - struct Map_ handlers; + m_str name; + struct Map_ handlers; struct M_Vector_ live_values; - uint16_t stack_depth; - uint16_t ref; - bool builtin; - bool callback; - bool is_memoize; + uint16_t stack_depth; + uint16_t ref; + bool builtin; + bool callback; + bool is_memoize; }; typedef struct frame_t { @@ -97,9 +97,10 @@ struct VM_Shred_ { struct ShredInfo_ *info; }; REF_FUNC(VM_Code, vmcode) -ANN2(1,4) -ANEW VM_Code new_vmcode(MemPool p, const Vector instr, const M_Vector live_values, const m_str name, - const uint16_t stack_depth, const bool builtin); +ANN2(1, 4) +ANEW VM_Code new_vmcode(MemPool p, const Vector instr, + const M_Vector live_values, const m_str name, + const uint16_t stack_depth, const bool builtin); ANN ANEW VM_Code vmcode_callback(MemPool p, const VM_Code code); ANN VM_Shred shreduler_get(const Shreduler s) __attribute__((hot)); diff --git a/src/emit/emit.c b/src/emit/emit.c index 480c4081..64d87120 100644 --- a/src/emit/emit.c +++ b/src/emit/emit.c @@ -498,7 +498,8 @@ ANN static m_bool _emit_symbol(const Emitter emit, const Symbol *data) { : emit_regpushbase(emit, size, exp_getvar(prim_exp(data))); instr->m_val = v->from->offset; if (GET_FLAG(v, late) && !exp_getvar(prim_exp(data)) && - (isa(v->type, emit->gwion->type[et_object]) > 0 || is_fptr(emit->gwion, v->type))) { + (isa(v->type, emit->gwion->type[et_object]) > 0 || + is_fptr(emit->gwion, v->type))) { const Instr instr = emit_add_instr(emit, GWOP_EXCEPT); instr->m_val = -SZ_INT; } @@ -506,6 +507,8 @@ ANN static m_bool _emit_symbol(const Emitter emit, const Symbol *data) { } ANN static m_bool emit_symbol(const Emitter emit, const Exp_Primary *prim) { + if (!prim->value) // assume it's an operator + ERR_B(exp_self(prim)->pos, "missing value for operator"); return _emit_symbol(emit, &prim->d.var); } @@ -1137,8 +1140,8 @@ ANN static m_bool _emit_exp_call(const Emitter emit, const Exp_Call *exp_call) { // skip when recursing const Type t = actual_type(emit->gwion, exp_call->func->type); const Func f = t->info->func; - if (is_fptr(emit->gwion, t) || f != emit->env->func || - f->value_ref->from->owner_class || strstr(emit->code->name, "ork~")) + if (is_fptr(emit->gwion, t) || strstr(emit->code->name, "ork~") || + (f != emit->env->func || f->value_ref->from->owner_class)) CHECK_BB(prepare_call(emit, exp_call)); else CHECK_BB(emit_func_args(emit, exp_call)); @@ -1180,10 +1183,11 @@ ANN static m_uint get_decl_size(Var_Decl_List a, bool emit_addr) { ANN static m_uint pop_exp_size(Exp e) { const bool emit_addr = exp_getvar(e); m_uint size = 0; - do { // account for emit_var ? + do { size += (e->exp_type == ae_exp_decl ? get_decl_size(e->d.exp_decl.list, emit_addr) - : e->type->size); + : !emit_addr ? e->type->size + : SZ_INT); } while ((e = e->next)); return size; } @@ -1435,12 +1439,12 @@ ANN m_bool emit_exp_call1(const Emitter emit, const Func f, } } else if (emit->env->func != f && !f->value_ref->from->owner_class && !f->code && !is_fptr(emit->gwion, f->value_ref->type)) { + // ensure env? + CHECK_BB(emit_func_def(emit, f->def)); if (fbflag(f->def->base, fbflag_op)) { const Instr back = (Instr)vector_back(&emit->code->instr); back->m_val = (m_uint)f; } else { - // ensure env? - CHECK_BB(emit_func_def(emit, f->def)); const Instr instr = emit_add_instr(emit, RegSetImm); instr->m_val = (m_uint)f->code; instr->m_val2 = -SZ_INT; @@ -1457,14 +1461,13 @@ ANN m_bool emit_exp_call1(const Emitter emit, const Func f, } 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); - const bool is_except = back->opcode == eGWOP_EXCEPT; - const Instr base = !is_except - ? back - : (Instr)vector_at(&emit->code->instr, - vector_size(&emit->code->instr) - 2); - if(is_except) - vector_pop(&emit->code->instr); + const Instr back = (Instr)vector_back(&emit->code->instr); + const bool is_except = back->opcode == eGWOP_EXCEPT; + const Instr base = + !is_except ? back + : (Instr)vector_at(&emit->code->instr, + vector_size(&emit->code->instr) - 2); + if (is_except) vector_pop(&emit->code->instr); const m_bit exec = base->opcode; const m_uint val = base->m_val; const m_uint val2 = base->m_val2; @@ -1474,9 +1477,9 @@ ANN m_bool emit_exp_call1(const Emitter emit, const Func f, const Instr instr = emit_add_instr(emit, (f_instr)(m_uint)exec); instr->m_val = val; instr->m_val2 = val2; - if(is_except) { - vector_add(&emit->code->instr, (m_uint)back); - back->m_val = -SZ_INT; + if (is_except) { + vector_add(&emit->code->instr, (m_uint)back); + back->m_val = -SZ_INT; } } else if (f != emit->env->func && !f->code && !is_fptr(emit->gwion, f->value_ref->type)) { @@ -1696,7 +1699,7 @@ ANN static m_bool emit_exp_if(const Emitter emit, const Exp_If *exp_if) { exp_setvar(exp_if->else_exp, 1); } DECL_OB(const Instr, op, = emit_flow(emit, exp_if->cond)); - CHECK_BB(emit_exp_pop_next(emit, exp_if->if_exp ?: exp_if->cond)); + CHECK_BB(emit_exp_pop_next(emit, e)); const Instr op2 = emit_add_instr(emit, Goto); op->m_val = emit_code_size(emit); const m_bool ret = emit_exp_pop_next(emit, exp_if->else_exp); @@ -1775,7 +1778,9 @@ ANN static m_bool emit_exp_lambda(const Emitter emit, } ANN static m_bool emit_exp_td(const Emitter emit, Type_Decl *td) { - regpushi(emit, (m_uint)_class_base(exp_self(td)->type)); + const Type base = exp_self(td)->type; + const Type t = _class_base(base) ?: base; + regpushi(emit, (m_uint)t); return GW_OK; } @@ -2649,7 +2654,9 @@ ANN m_bool emit_func_def(const Emitter emit, const Func_Def f) { const Func func = f->base->func; const Func_Def fdef = func->def; const Func former = emit->env->func; - if (func->code || tmpl_base(fdef->base->tmpl)) return GW_OK; + if (func->code || tmpl_base(fdef->base->tmpl) || fflag(func, fflag_emit)) + return GW_OK; + set_fflag(func, fflag_emit); if (vflag(func->value_ref, vflag_builtin) && safe_tflag(emit->env->class_def, tflag_tmpl)) { const Func base = @@ -2731,7 +2738,7 @@ ANN static m_bool cdef_parent(const Emitter emit, const Class_Def cdef) { ANN static m_bool emit_class_def(const Emitter emit, const Class_Def cdef) { if (tmpl_base(cdef->base.tmpl)) return GW_OK; - const Type t = cdef->base.type; + const Type t = cdef->base.type; const Class_Def c = t->info->cdef; if (tflag(t, tflag_emit)) return GW_OK; set_tflag(t, tflag_emit); diff --git a/src/import/import_checker.c b/src/import/import_checker.c index c855a586..ae7c1fce 100644 --- a/src/import/import_checker.c +++ b/src/import/import_checker.c @@ -209,7 +209,7 @@ ANN Type_Decl *str2td(const Gwion gwion, const m_str str, const loc_t pos) { DECL_OO(Type_Decl *, td, = _str2td(gwion, &tdc)); if (*tdc.str) { free_type_decl(gwion->mp, td); - GWION_ERR_O(pos, "excedental character '%c'", *tdc.str); + GWION_ERR_O(pos, "excedental character '%c' in '%s'", *tdc.str, str); } return td; } diff --git a/src/lib/array.c b/src/lib/array.c index 042dc928..c3c38f89 100644 --- a/src/lib/array.c +++ b/src/lib/array.c @@ -634,6 +634,12 @@ static OP_CHECK(opck_array_scan) { const Class_Def c = t_array->info->cdef; DECL_ON(const Type, base, = ts->t != t_array ? ts->t : known_type(env, ts->td->types->td)); + if (base->size == 0) { + gwerr_basic("Can't use type of size 0 as array base", NULL, NULL, + "/dev/null", (loc_t) {}, 0); + env->context->error = true; + return env->gwion->type[et_error]; + } if (!strncmp(base->name, "Ref:[", 5)) { gwerr_basic("Can't use ref types as array base", NULL, NULL, "/dev/null", (loc_t) {}, 0); @@ -660,10 +666,11 @@ static OP_CHECK(opck_array_scan) { const m_uint scope = env_push(env, base->info->value->from->owner_class, base->info->value->from->owner); (void)scan0_class_def(env, cdef); - const Type t = cdef->base.type; - (void)traverse_cdef(env, t); + const Type t = cdef->base.type; + const m_bool ret = traverse_cdef(env, t); env_pop(env, scope); env->context = ctx; + if (ret == GW_ERROR) return NULL; if (GET_FLAG(base, abstract)) SET_FLAG(t, abstract); else diff --git a/src/lib/engine.c b/src/lib/engine.c index 3d88d507..4f08b734 100644 --- a/src/lib/engine.c +++ b/src/lib/engine.c @@ -157,7 +157,6 @@ ANN static m_bool import_core_libs(const Gwi gwi) { const Type t_curry = gwi_mk_type(gwi, "@Curry", 0, NULL); GWI_BB(gwi_set_global_type(gwi, t_curry, et_curry)) - gwidoc(gwi, "type for internal pointer data."); GWI_BB(gwi_typedef_ini(gwi, "int", "@internal")) GWI_BB(gwi_typedef_end(gwi, ae_flag_none)) diff --git a/src/lib/lib_func.c b/src/lib/lib_func.c index 3eabfa43..2cdec9e3 100644 --- a/src/lib/lib_func.c +++ b/src/lib/lib_func.c @@ -23,12 +23,12 @@ static OP_CHECK(opck_func_call) { } ANN static inline Exp cpy_nonext(const Env env, const Exp e) { - const MemPool mp = env->gwion->mp; - const Exp next = e->next; - e->next = NULL; - const Exp ret = cpy_exp(mp, e); - e->next = next; - if(!check_exp(env, ret)) { + const MemPool mp = env->gwion->mp; + const Exp next = e->next; + e->next = NULL; + const Exp ret = cpy_exp(mp, e); + e->next = next; + if (!check_exp(env, ret)) { free_exp(mp, ret); return NULL; } @@ -36,29 +36,28 @@ ANN static inline Exp cpy_nonext(const Env env, const Exp e) { } ANN static Exp order_curry(const Env env, Exp fn, Exp arg) { - const MemPool mp = env->gwion->mp; - Exp base = NULL; - Exp next = NULL; + const MemPool mp = env->gwion->mp; + Exp base = NULL; + Exp next = NULL; do { const bool hole = is_hole(env, fn); - const Exp curr = !hole ? fn : arg; - if(hole) { - if(!arg) { - if(base) - free_exp(mp, base); + const Exp curr = !hole ? fn : arg; + if (hole) { + if (!arg) { + if (base) free_exp(mp, base); ERR_O(fn->pos, "no enough arguments for holes"); } arg = arg->next; } - if(!base) + if (!base) base = next = cpy_nonext(env, curr); else { next->next = cpy_nonext(env, curr); - next = next->next; + next = next->next; } } while ((fn = fn->next)); assert(base); - if(arg) { + if (arg) { free_exp(mp, base); ERR_O(arg->pos, "too many arguments for holes"); } @@ -69,15 +68,16 @@ static OP_CHECK(opck_curry) { Exp_Binary *bin = (Exp_Binary *)data; Exp lhs = bin->lhs; Exp_Call base = bin->rhs->d.exp_call; - DECL_OO(const Exp, args, = order_curry(env, base.args, lhs)); - Exp_Call call = {.func = base.func, .args = args}; - Exp e = exp_self(bin); - e->exp_type = ae_exp_call; - e->type = NULL; + DECL_ON(const Exp, args, = order_curry(env, base.args, lhs)); + Exp_Call call = {.func = base.func, .args = args}; + Exp e = exp_self(bin); + e->exp_type = ae_exp_call; + e->type = NULL; memcpy(&e->d.exp_call, &call, sizeof(Exp_Call)); const MemPool mp = env->gwion->mp; free_exp(mp, base.args); free_exp(mp, lhs); + env->scope->allow_curry = true; return check_exp_call1(env, &e->d.exp_call) ?: env->gwion->type[et_error]; } @@ -94,7 +94,8 @@ static OP_EMIT(opem_func_assign) { fptr_instr(emit, bin->lhs->type->info->func, 2); (void)emit_add_instr(emit, int_r_assign); if (!is_fptr(emit->gwion, bin->lhs->type) && - vflag(bin->rhs->type->info->func->value_ref, vflag_member)) { + vflag(bin->rhs->type->info->func->value_ref, vflag_member)/*&& + bin->lhs->exp_type != ae_exp_td*/) { const Instr pop = emit_add_instr(emit, RegMove); pop->m_val = -SZ_INT; const Instr cpy = emit_add_instr(emit, Reg2Reg); @@ -341,6 +342,9 @@ static OP_CHECK(opck_fptr_at) { Exp_Binary *bin = (Exp_Binary *)data; if (bin->rhs->exp_type == ae_exp_decl) UNSET_FLAG(bin->rhs->d.exp_decl.list->self->value, late); + if (bin->lhs->exp_type == ae_exp_td) + ERR_N(bin->lhs->pos, "can't use type_decl expression"); + // UNSET_FLAG(bin->rhs->d.exp_decl.list->self->value, late); if (bin->rhs->type->info->func->def->base->tmpl && bin->rhs->type->info->func->def->base->tmpl->call) { struct FptrInfo info = {bin->lhs->type->info->func, @@ -357,7 +361,7 @@ static OP_CHECK(opck_fptr_at) { exp_setvar(bin->rhs, 1); return bin->rhs->type; } - +/* static OP_CHECK(opck_fptr_cast) { Exp_Cast * cast = (Exp_Cast *)data; const Type t = exp_self(cast)->type; @@ -366,7 +370,7 @@ static OP_CHECK(opck_fptr_cast) { CHECK_BN(fptr_do(env, &info)); return t; } - +*/ static void member_fptr(const Emitter emit) { const Instr instr = emit_add_instr(emit, RegMove); instr->m_val = -SZ_INT; @@ -377,7 +381,7 @@ static void member_fptr(const Emitter emit) { static inline int is_member(const Type from) { return vflag(from->info->func->value_ref, vflag_member); } - +/* static OP_EMIT(opem_fptr_cast) { const Exp_Cast *cast = (Exp_Cast *)data; if (is_member(cast->exp->type)) member_fptr(emit); @@ -385,7 +389,7 @@ static OP_EMIT(opem_fptr_cast) { fptr_instr(emit, cast->exp->type->info->func, 1); return GW_OK; } - +*/ static OP_CHECK(opck_fptr_impl) { struct Implicit *impl = (struct Implicit *)data; struct FptrInfo info = {impl->e->type->info->func, impl->t->info->func, @@ -657,9 +661,9 @@ GWION_IMPORT(func) { GWI_BB(gwi_oper_add(gwi, opck_fptr_at)) GWI_BB(gwi_oper_emi(gwi, opem_func_assign)) GWI_BB(gwi_oper_end(gwi, "@=>", NULL)) - GWI_BB(gwi_oper_add(gwi, opck_fptr_cast)) - GWI_BB(gwi_oper_emi(gwi, opem_fptr_cast)) - GWI_BB(gwi_oper_end(gwi, "$", NULL)) + // GWI_BB(gwi_oper_add(gwi, opck_fptr_cast)) + // GWI_BB(gwi_oper_emi(gwi, opem_fptr_cast)) + // GWI_BB(gwi_oper_end(gwi, "$", NULL)) GWI_BB(gwi_oper_add(gwi, opck_fptr_impl)) GWI_BB(gwi_oper_emi(gwi, opem_fptr_impl)) GWI_BB(gwi_oper_end(gwi, "@implicit", NULL)) diff --git a/src/lib/object_op.c b/src/lib/object_op.c index 92aead95..906284e4 100644 --- a/src/lib/object_op.c +++ b/src/lib/object_op.c @@ -70,6 +70,7 @@ static Type opck_object_scan(const Env env, const struct TemplateScan *ts) { static OP_CHECK(opck_struct_scan) { struct TemplateScan *ts = (struct TemplateScan *)data; + CHECK_OO(ts->td); return opck_object_scan(env, ts); } @@ -128,7 +129,6 @@ ANN static inline void emit_member(const Emitter emit, const Value v, const m_uint size = v->type->size; const Instr instr = emit_dotmember(emit, size, emit_addr); instr->m_val = v->from->offset; - instr->m_val2 = size; } ANN static inline void emit_struct_data(const Emitter emit, const Value v, @@ -199,11 +199,17 @@ OP_EMIT(opem_object_dot) { 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; + return GW_OK; + } if (!is_class(emit->gwion, member->base->type) && (vflag(value, vflag_member) || (isa(exp_self(member)->type, emit->gwion->type[et_function]) > 0 && !is_fptr(emit->gwion, exp_self(member)->type)))) { - if (!tflag(t_base, tflag_struct)) CHECK_BB(emit_exp(emit, member->base)); + if (!tflag(t_base, tflag_struct) && vflag(value, vflag_member)) + CHECK_BB(emit_exp(emit, member->base)); } if (isa(exp_self(member)->type, emit->gwion->type[et_function]) > 0 && !is_fptr(emit->gwion, exp_self(member)->type)) diff --git a/src/lib/prim.c b/src/lib/prim.c index 5d73847c..0f67c3f5 100644 --- a/src/lib/prim.c +++ b/src/lib/prim.c @@ -173,8 +173,8 @@ static OP_EMIT(opem_int_range) { static OP_CHECK(opck_##ntype##_##name) { \ /*const*/ Exp_Unary *unary = (Exp_Unary *)data; \ const Type t = env->gwion->type[TYPE]; \ - if (!exp_self(unary)->pos.first.line || !func(unary->exp)) return t; \ CHECK_NN(opck_unary_meta(env, data)); \ + if (!func(unary->exp)) return t; \ const ctype num = OP unary->exp->d.prim.d.member; \ exp_self(unary)->exp_type = ae_exp_primary; \ exp_self(unary)->d.prim.prim_type = exptype; \ @@ -255,7 +255,7 @@ static OP_CHECK(opck_implicit_i2f) { return env->gwion->type[et_float]; } is_prim_float, m_float, ae_prim_float, num, fnum, fnum) #define BINARY_INT_FLOAT_FOLD2(name, TYPE, OP, pre, post) \ BINARY_FOLD(int_float, name, TYPE, OP, pre, post, is_prim_int, \ - is_prim_float, m_float, ae_prim_float, num, fnum, num) + is_prim_float, m_float, ae_prim_num, num, fnum, num) BINARY_INT_FLOAT_FOLD(add, et_float, +, , ) BINARY_INT_FLOAT_FOLD(sub, et_float, -, , ) diff --git a/src/lib/shred.c b/src/lib/shred.c index 31b875fc..b570e8ef 100644 --- a/src/lib/shred.c +++ b/src/lib/shred.c @@ -93,7 +93,7 @@ static SFUN(vm_shred_from_id) { } } } - *(m_uint *)RETURN = 0; + handle(shred, "InvalidShredRequest"); } static MFUN(shred_args) { @@ -108,7 +108,7 @@ static MFUN(shred_arg) { const m_str str = (m_str)vector_at(&s->info->args, *(m_uint *)MEM(SZ_INT)); *(M_Object *)RETURN = str ? new_string(shred->info->mp, shred, str) : NULL; } else - *(m_uint *)RETURN = 0; + handle(shred, "InvalidShredArgumentRequest"); } #ifndef BUILD_ON_WINDOWS diff --git a/src/lib/string.c b/src/lib/string.c index dd6c827a..68ff08d3 100644 --- a/src/lib/string.c +++ b/src/lib/string.c @@ -153,7 +153,7 @@ static MFUN(string_trim) { break; } if (len - start - end <= 0) { - *(m_uint *)RETURN = 0; + handle(shred, "InvalidStringTrimRequest"); return; } char c[len - start - end + 1]; @@ -191,12 +191,7 @@ static MFUN(string_insert) { strcpy(str, STRING(o)); m_int i, len_insert = 0, index = *(m_int *)MEM(SZ_INT); const M_Object arg = *(M_Object *)MEM(SZ_INT * 2); - - if (!arg) { - *(M_Object *)RETURN = NULL; - return; - } - char insert[strlen(STRING(arg)) + 1]; + char insert[strlen(STRING(arg)) + 1]; strcpy(insert, STRING(arg)); const m_uint len = strlen(str); len_insert = strlen(insert); @@ -223,7 +218,7 @@ static MFUN(string_replace) { const m_uint len = strlen(str); len_insert = strlen(insert); if (index >= (m_int)len || index < 0 || (index + len_insert + 1) <= 0) { - *(M_Object *)RETURN = NULL; + handle(shred, "InvalidStringReplace"); return; } char c[index + len_insert + 1]; @@ -242,7 +237,7 @@ static MFUN(string_replaceN) { const m_int _len = *(m_int *)MEM(SZ_INT * 2); if (!arg || index > (m_int)strlen(STRING(o)) || _len > (m_int)strlen(STRING(arg))) { - *(M_Object *)RETURN = NULL; + handle(shred, "InvalidStringReplace"); return; } char insert[strlen(STRING(arg)) + 1]; @@ -358,7 +353,7 @@ static MFUN(string_erase) { const m_int len = strlen(str); const m_int size = len - rem + 1; if (start >= len || size <= 0) { - *(M_Object *)RETURN = NULL; + handle(shred, "InvalidStringErase"); return; } char c[size]; diff --git a/src/lib/ugen.c b/src/lib/ugen.c index 1dff2c77..742b42df 100644 --- a/src/lib/ugen.c +++ b/src/lib/ugen.c @@ -323,10 +323,10 @@ static MFUN(ugen_channel) { const m_int i = *(m_int *)MEM(SZ_INT); if (!UGEN(o)->multi) *(M_Object *)RETURN = !i ? o : NULL; - else if (i < 0 || (m_uint)i >= UGEN(o)->connect.multi->n_chan) - *(M_Object *)RETURN = NULL; - else + else if (i > 0 || (m_uint)i < UGEN(o)->connect.multi->n_chan) *(M_Object *)RETURN = UGEN(o)->connect.multi->channel[i]; + else + handle(shred, "InvalidChannelRequest"); } static MFUN(ugen_get_op) { *(m_uint *)RETURN = UGEN(o)->op + 1; } diff --git a/src/main.c b/src/main.c index 864cb9dc..bdf756b9 100644 --- a/src/main.c +++ b/src/main.c @@ -17,6 +17,8 @@ static void sig(int unused NUSED) { #ifdef __AFL_HAVE_MANUAL_CONTROL +#include "compile.h" + static void afl_run(const Gwion gwion) { gw_seed(gwion->vm->rand, 0); __AFL_INIT(); diff --git a/src/parse/check.c b/src/parse/check.c index 1337c325..85b4ee2d 100644 --- a/src/parse/check.c +++ b/src/parse/check.c @@ -888,17 +888,15 @@ ANN static m_bool predefined_call(const Env env, const Type t, } ANN2(1) static inline bool curried(const Env env, Exp exp) { - while(exp) { - if (is_hole(env, exp)) - return true; + while (exp) { + if (is_hole(env, exp)) return true; exp = exp->next; } return false; } ANN static Type check_exp_call(const Env env, Exp_Call *exp) { - if(curried(env, exp->args)) - return env->gwion->type[et_curry]; + if (curried(env, exp->args)) return env->gwion->type[et_curry]; if (exp->tmpl) { DECL_BO(const m_bool, ret, = func_check(env, exp)); if (!ret) return exp_self(exp)->type; @@ -952,7 +950,7 @@ ANN static Type _flow(const Env env, const Exp e, const m_bool b) { #define check_flow(emit, b) _flow(emit, b, 1) ANN static Type check_exp_if(const Env env, Exp_If *const exp_if) { - if(!exp_if->if_exp) { + if (!exp_if->if_exp) { const Exp e = exp_if->if_exp = cpy_exp(env->gwion->mp, exp_if->cond); scan1_exp(env, e); scan2_exp(env, e); @@ -961,7 +959,8 @@ ANN static Type check_exp_if(const Env env, Exp_If *const exp_if) { DECL_OO(const Type, if_exp, = check_exp(env, exp_if->if_exp)); DECL_OO(const Type, else_exp, = check_exp(env, exp_if->else_exp)); - const uint meta = exp_getmeta(exp_if->if_exp) || exp_getmeta(exp_if->else_exp); + const uint meta = + exp_getmeta(exp_if->if_exp) || exp_getmeta(exp_if->else_exp); exp_setmeta(exp_self(exp_if), meta); const Type ret = find_common_anc(if_exp, else_exp); if (!ret) @@ -1056,7 +1055,7 @@ ANN static Type check_exp_lambda(const Env env, const Exp_If *exp_if NUSED) { ANN static Type check_exp_td(const Env env, Type_Decl **td) { DECL_OO(const Type, t, = known_type(env, *td)); - if(isa(t, env->gwion->type[et_function]) > 0 && !is_fptr(env->gwion, t)) + if (isa(t, env->gwion->type[et_function]) > 0 && !is_fptr(env->gwion, t)) return type_class(env->gwion, t); return t; } diff --git a/src/parse/scan1.c b/src/parse/scan1.c index 4a812bb1..de04f4bf 100644 --- a/src/parse/scan1.c +++ b/src/parse/scan1.c @@ -365,7 +365,7 @@ ANN m_bool scan1_enum_def(const Env env, const Enum_Def edef) { ID_List list = edef->list; do { CHECK_BB(already_defined(env, list->xid, edef->pos)); - if(nspc_lookup_value1(edef->t->info->value->from->owner, list->xid)) + if (nspc_lookup_value1(edef->t->info->value->from->owner, list->xid)) ERR_B(edef->pos, "'%s' already defined", s_name(list->xid)); const Value v = new_value(env->gwion->mp, edef->t, s_name(list->xid)); valuefrom(env, v->from, edef->pos); @@ -687,7 +687,7 @@ ANN static m_bool cdef_parent(const Env env, const Class_Def cdef) { 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; + const Type t = cdef->base.type; const Class_Def c = t->info->cdef; if (tflag(t, tflag_scan1)) return GW_OK; set_tflag(t, tflag_scan1); diff --git a/src/parse/scan2.c b/src/parse/scan2.c index 1e0e648c..e65ca195 100644 --- a/src/parse/scan2.c +++ b/src/parse/scan2.c @@ -329,10 +329,10 @@ ANN static void func_no_overload(const Env env, const Func f, const Value v) { value_addref(v); nspc_add_value_front(env->curr, f->def->base->xid, v); - const Type newt = type_copy(env->gwion->mp, t); - t->info->parent = newt; - newt->name = s_name(f->def->base->xid); - newt->info->func = f; + const Type newt = type_copy(env->gwion->mp, t); + t->info->parent = newt; + newt->name = s_name(f->def->base->xid); + newt->info->func = f; nspc_add_type_front(env->curr, f->def->base->xid, newt); newt->info->value = v; } @@ -591,7 +591,7 @@ ANN static m_bool cdef_parent(const Env env, const Class_Def cdef) { ANN m_bool scan2_class_def(const Env env, const Class_Def cdef) { if (tmpl_base(cdef->base.tmpl)) return GW_OK; - const Type t = cdef->base.type; + const Type t = cdef->base.type; const Class_Def c = t->info->cdef; if (tflag(t, tflag_scan2)) return GW_OK; if (t->info->value->from->owner_class) diff --git a/src/parse/template.c b/src/parse/template.c index 5691dd9b..03395c4c 100644 --- a/src/parse/template.c +++ b/src/parse/template.c @@ -12,24 +12,35 @@ #include "object.h" #include "import.h" -ANN static m_bool push_types(const Env env, const Tmpl *tmpl) { +ANN static m_bool _push_types(const Env env, const Nspc nspc, + const Tmpl *tmpl) { Specialized_List list = tmpl->list; Type_List call = tmpl->call; do { if (!call) break; const Type t = known_type(env, call->td); - if (!t) return 1; - nspc_add_type(env->curr, list->xid, t); + if (!t) return GW_OK; + nspc_add_type(nspc, list->xid, t); call = call->next; } while ((list = list->next)); - return !call; + return !call ? GW_OK : GW_ERROR; +} + +ANN static m_bool push_types(const Env env, const Nspc nspc, const Tmpl *tmpl) { + if (nspc->parent) env->curr = env->curr->parent; + const Type t = env->class_def; + if (t) env->class_def = t->info->value->from->owner_class; + const m_bool ret = _push_types(env, nspc, tmpl); + if (nspc->parent) env->curr = nspc; + env->class_def = t; + return ret; } ANN static m_bool _template_push(const Env env, const Type t) { if (t->info->value->from->owner_class) CHECK_BB(template_push(env, t->info->value->from->owner_class)); if (tflag(t, tflag_tmpl)) - return push_types(env, t->info->cdef->base.tmpl); // incorrect + return push_types(env, t->nspc, t->info->cdef->base.tmpl); // incorrect return GW_OK; } @@ -40,7 +51,7 @@ ANN m_bool template_push(const Env env, const Type t) { ANN m_bool template_push_types(const Env env, const Tmpl *tmpl) { nspc_push_type(env->gwion->mp, env->curr); - if (push_types(env, tmpl)) return GW_OK; + if (push_types(env, env->curr, tmpl) > 0) return GW_OK; POP_RET(GW_ERROR); } -- 2.43.0