From: Jérémie Astor Date: Fri, 25 Jun 2021 11:23:16 +0000 (+0200) Subject: :bug: after AFL run X-Git-Tag: nightly~571 X-Git-Url: http://10.10.0.4:5575/?a=commitdiff_plain;h=73f888a03ab3def5863d10ca147bf9b5ce9cd164;p=gwion.git :bug: after AFL run --- diff --git a/ast b/ast index d7cc060e..c3a97d17 160000 --- a/ast +++ b/ast @@ -1 +1 @@ -Subproject commit d7cc060e0fe49405ca5494810c181ef211daf7f2 +Subproject commit c3a97d173da142bccfafb48ab532359ba77bb6aa diff --git a/fmt b/fmt index 11f86a1a..d78297aa 160000 --- a/fmt +++ b/fmt @@ -1 +1 @@ -Subproject commit 11f86a1a1aad81ff6dba21605398007898e2fb3f +Subproject commit d78297aacc14071b97ae22e47f9e1c06054c15de diff --git a/include/env/value.h b/include/env/value.h index 67879b7b..aa498b6d 100644 --- a/include/env/value.h +++ b/include/env/value.h @@ -17,7 +17,8 @@ enum vflag { vflag_direct = 1 << 4, vflag_builtin = 1 << 5, vflag_member = 1 << 6, - vflag_closed = 1 << 7 + vflag_closed = 1 << 7, + vflag_inner = 1 << 8 // value is in a scope // vflag_used = 1 << 3 } __attribute__((packed)); diff --git a/plug b/plug index 857e0e59..37f2a1e2 160000 --- a/plug +++ b/plug @@ -1 +1 @@ -Subproject commit 857e0e59f0bb00b6de35ad770814960c3e442d6a +Subproject commit 37f2a1e20f85c2f455abb85340557b994c294cf0 diff --git a/src/emit/emit.c b/src/emit/emit.c index b8346af0..140cd982 100644 --- a/src/emit/emit.c +++ b/src/emit/emit.c @@ -516,7 +516,7 @@ ANN static VM_Code finalyze(const Emitter emit, const f_instr exec) { emit_add_instr(emit, exec); const VM_Code code = emit->info->emit_code(emit); free_code(emit->gwion->mp, emit->code); - emit->code = (Code *)vector_pop(&emit->stack); + emit_pop_code(emit); return code; } @@ -1442,7 +1442,13 @@ ANN m_bool emit_exp_call1(const Emitter emit, const Func f, 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; + assert(back->execute == SetFunc); + if(f->code) { + back->opcode = eRegPushImm; + back->m_val = f->code; + // back->m_val2 = SZ_INT; + } else + back->m_val = (m_uint)f; } else { const Instr instr = emit_add_instr(emit, RegSetImm); instr->m_val = (m_uint)f->code; @@ -1471,6 +1477,7 @@ ANN m_bool emit_exp_call1(const Emitter emit, const Func f, const m_uint val = base->m_val; const m_uint val2 = base->m_val2; base->opcode = eReg2Reg; +// base->m_val = 0;//-SZ_INT; base->m_val2 = -SZ_INT; regpush(emit, SZ_INT); const Instr instr = emit_add_instr(emit, (f_instr)(m_uint)exec); @@ -1491,8 +1498,11 @@ ANN m_bool emit_exp_call1(const Emitter emit, const Func f, instr->execute = SetFunc; instr->m_val = (m_uint)f; } else { - const Instr instr = emit_add_instr(emit, SetFunc); - instr->m_val = (m_uint)f; + const Instr back = (Instr)vector_back(&emit->code->instr); + if(back->execute != SetFunc) { + const Instr instr = emit_add_instr(emit, SetFunc); + instr->m_val = (m_uint)f; + } } } const m_uint offset = emit_code_offset(emit); @@ -2636,6 +2646,7 @@ ANN static m_bool emit_fdef(const Emitter emit, const Func_Def fdef) { static ANN int fdef_is_file_global(const Emitter emit, const Func_Def fdef) { return !fbflag(fdef->base, fbflag_lambda) && !emit->env->class_def && !GET_FLAG(fdef->base, global) && !fdef->base->tmpl && + !fbflag(fdef->base, fbflag_op) && !emit->env->scope->depth; } @@ -2775,13 +2786,17 @@ ANN static VM_Code emit_free_stack(const Emitter emit) { return NULL; } -ANN m_bool emit_ast(const Env env, Ast ast) { - const Emitter emit = env->gwion->emit; +ANN static inline void emit_clear(const Emitter emit) { emit->info->memoize = 0; emit->info->unroll = 0; emit->info->line = 0; emit->this_offset = 0; emit->vararg_offset = 0; +} + +ANN m_bool emit_ast(const Env env, Ast ast) { + const Emitter emit = env->gwion->emit; + emit_clear(emit); emit->code = new_code(emit, emit->env->name); emit_push_scope(emit); const m_bool ret = emit_ast_inner(emit, ast); @@ -2790,5 +2805,6 @@ ANN m_bool emit_ast(const Env env, Ast ast) { emit->info->code = finalyze(emit, EOC); else emit_free_stack(emit); + emit_clear(emit); return ret; } diff --git a/src/env/env.c b/src/env/env.c index 5f5a9e57..1bac40a4 100644 --- a/src/env/env.c +++ b/src/env/env.c @@ -81,7 +81,7 @@ ANN void free_env(const Env a) { free_env_scope(a->scope, a->gwion); while (pop_global(a->gwion)) ; - xfree(a); + mp_free(a->gwion->mp, Env, a); } ANN2(1, 3) m_uint env_push(const Env env, const Type type, const Nspc nspc) { diff --git a/src/env/value.c b/src/env/value.c index 5c95cf31..a82e2661 100644 --- a/src/env/value.c +++ b/src/env/value.c @@ -11,6 +11,8 @@ ANN void free_value(Value a, Gwion gwion) { _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)) + type_remref(t, gwion); mp_free(gwion->mp, ValueFrom, a->from); mp_free(gwion->mp, Value, a); } diff --git a/src/import/import_oper.c b/src/import/import_oper.c index 970a1003..68adceaa 100644 --- a/src/import/import_oper.c +++ b/src/import/import_oper.c @@ -86,6 +86,7 @@ ANN m_int gwi_oper_end(const Gwi gwi, const m_str op, const f_instr f) { lint_space(gwi->lint); } lint(gwi->lint, "{/}%s{0}", op); + lint_space(gwi->lint); lint_lparen(gwi->lint); if (gwi->oper->lhs && gwi->oper->rhs) { lint(gwi->lint, "{+}%s{0}", diff --git a/src/lib/engine.c b/src/lib/engine.c index 4f08b734..300ffe76 100644 --- a/src/lib/engine.c +++ b/src/lib/engine.c @@ -12,6 +12,7 @@ #include "lang_private.h" #include "specialid.h" #include "gack.h" +#include "traverse.h" static GACK(gack_class) { const Type type = actual_type(shred->info->vm->gwion, t) ?: t; @@ -57,6 +58,15 @@ static OP_CHECK(opck_basic_ctor) { ERR_N(exp_self(call)->pos, _("can't call a non-callable value")); } +static OP_CHECK(opck_class_call) { + const Exp_Binary *bin = (Exp_Binary *)data; + Exp_Call call = {.func = bin->rhs, .args = bin->lhs}; + Exp e = exp_self(bin); + e->exp_type = ae_exp_call; + memcpy(&e->d.exp_call, &call, sizeof(Exp_Call)); + return check_exp_call1(env, &e->d.exp_call) ?: env->gwion->type[et_error]; +} + static ID_CHECK(idck_predicate) { set_fflag(env->func, fflag_return); return exp_self(prim)->type; @@ -206,6 +216,11 @@ ANN static m_bool import_core_libs(const Gwi gwi) { GWI_BB(gwi_oper_emi(gwi, opem_object_dot)) GWI_BB(gwi_oper_end(gwi, "@dot", NULL)) + gwidoc(gwi, "Allow binary call to constructors."); + GWI_BB(gwi_oper_ini(gwi, (m_str)OP_ANY_TYPE, "@Class", NULL)) + GWI_BB(gwi_oper_add(gwi, opck_class_call)) + GWI_BB(gwi_oper_end(gwi, "=>", NULL)) + return GW_OK; } diff --git a/src/lib/lib_func.c b/src/lib/lib_func.c index a3bb28f5..bdfe3e41 100644 --- a/src/lib/lib_func.c +++ b/src/lib/lib_func.c @@ -282,6 +282,7 @@ ANN static m_bool _check_lambda(const Env env, Exp_Lambda *l, // if(GET_FLAG(def->base, global) && !l->owner && // def->base->func->value_ref->from->owner_class) // env_pop(env, scope); + if (l->def->base->func) { if (env->curr->info->value != l->def->base->values) { free_scope(env->gwion->mp, env->curr->info->value); diff --git a/src/lib/object_op.c b/src/lib/object_op.c index 7ab2001e..2ff6400d 100644 --- a/src/lib/object_op.c +++ b/src/lib/object_op.c @@ -24,9 +24,9 @@ *(m_uint *)REG(-SZ_INT) = (lhs op rhs); \ } -describe_logical(Eq, ==) describe_logical(Neq, !=) +describe_logical(Eq, ==) describe_logical(Neq, !=); - static OP_CHECK(opck_object_at) { +static OP_CHECK(opck_object_at) { const Exp_Binary *bin = (Exp_Binary *)data; if (opck_rassign(env, data) == env->gwion->type[et_error]) return env->gwion->type[et_error]; @@ -147,7 +147,8 @@ ANN m_bool not_from_owner_class(const Env env, const Type t, const Value v, ANN static inline Value get_value(const Env env, const Exp_Dot *member, const Type t) { const Value value = find_value(t, member->xid); - if (value) return value; + if (value) + return value; if (env->func && env->func->def->base->values) return (Value)scope_lookup1(env->func->def->base->values, (m_uint)member->xid); @@ -160,17 +161,15 @@ OP_CHECK(opck_object_dot) { const m_bool base_static = is_class(env->gwion, member->base->type); const Type the_base = base_static ? _class_base(member->base->type) : member->base->type; - // if(!the_base->nspc) - // ERR_N(&member->base->pos, - // _("type '%s' does not have members - invalid use in dot expression - // of %s"), the_base->name, str); + if (member->xid == insert_symbol(env->gwion->st, "this") && base_static) ERR_N(exp_self(member)->pos, _("keyword 'this' must be associated with object instance...")); const Value value = get_value(env, member, the_base); if (!value) { const Value v = nspc_lookup_value1(env->curr, member->xid); - if (v && is_func(env->gwion, v->type)) return v->type; + if (v && member->is_call && is_func(env->gwion, v->type)) + return v->type; env_err(env, exp_self(member)->pos, _("class '%s' has no member '%s'"), the_base->name, str); if (member->base->type->nspc) did_you_mean_type(the_base, str); @@ -199,6 +198,7 @@ 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; diff --git a/src/lib/string.c b/src/lib/string.c index 68ff08d3..06814347 100644 --- a/src/lib/string.c +++ b/src/lib/string.c @@ -348,10 +348,11 @@ static MFUN(string_rfindStrStart) { static MFUN(string_erase) { const m_str str = STRING(o); - const m_int start = *(m_int *)MEM(SZ_INT); + const m_int _start = *(m_int *)MEM(SZ_INT); const m_int rem = *(m_int *)MEM(SZ_INT * 2); const m_int len = strlen(str); const m_int size = len - rem + 1; + const m_int start = _start >= 0 ? _start : len - _start; if (start >= len || size <= 0) { handle(shred, "InvalidStringErase"); return; diff --git a/src/main.c b/src/main.c index bdf756b9..41dd4219 100644 --- a/src/main.c +++ b/src/main.c @@ -20,22 +20,25 @@ static void sig(int unused NUSED) { #include "compile.h" static void afl_run(const Gwion gwion) { - gw_seed(gwion->vm->rand, 0); __AFL_INIT(); - while (__AFL_LOOP(256)) { - FILE *f = fdopen(0, "r"); + while (__AFL_LOOP(128)) { push_global(gwion, "[afl]"); + FILE *f = fdopen(0, "r"); if (compile_file(gwion, "afl", f)) gwion_run(gwion); pop_global(gwion); } } -#define gwion_run(a) \ - { \ - afl_run(a); \ - return 0; \ - } -#endif +int main(int argc, char **argv) { + Arg arg = {}; + struct Gwion_ gwion = {}; + gwion_ini(&gwion, &arg); + arg_release(&arg); + afl_run(&gwion); + return EXIT_SUCCESS; +} + +#else int main(int argc, char **argv) { Arg arg = {.arg = {.argc = argc, .argv = argv}, .loop = false}; @@ -51,3 +54,5 @@ int main(int argc, char **argv) { #endif return EXIT_SUCCESS; } + +#endif diff --git a/src/parse/check.c b/src/parse/check.c index 963afe8b..849d73e8 100644 --- a/src/parse/check.c +++ b/src/parse/check.c @@ -457,11 +457,25 @@ static ANN Type check_exp_slice(const Env env, const Exp_Slice *range) { return op_check(env, &opi); } +// get the type of the function +// without the mangling +ANN static inline Type type_list_base_func(const Type type) { + const Nspc owner = type->info->value->from->owner; + const Symbol xid = type->info->func->def->base->xid; + return nspc_lookup_type0(owner, xid); +} + +ANN static inline Type type_list_base(const Gwion gwion, const Type type) { + return !(is_func(gwion, type) && !is_fptr(gwion, type)) ? + type : type_list_base_func(type); +} + ANN static Type_List mk_type_list(const Env env, const Arg_List arg, const Type type, const loc_t pos) { - const Type t = - !arg->td->array ? type : array_type(env, type, arg->td->array->depth); - Type_Decl *td = type2td(env->gwion, t, pos); + const Type base = type_list_base(env->gwion, type); + const Type t = !arg->td->array ? + base : array_type(env, base, arg->td->array->depth); + Type_Decl *td = type2td(env->gwion, t, pos); return new_type_list(env->gwion->mp, td, NULL); } @@ -518,14 +532,13 @@ ANN static Func call2ufcs(const Env env, Exp_Call *call, const Value v) { call->func->d.prim.d.var = call->func->d.exp_dot.xid; call->func->exp_type = ae_exp_primary; call->func->d.prim.prim_type = ae_prim_id; - call->args = this; CHECK_OO(check_exp_call(env, call)); return call->func->type->info->func; } ANN Func ufcs(const Env env, const Func up, Exp_Call *const call) { const Value v = nspc_lookup_value1(env->curr, up->def->base->xid); - if (v && is_func(env->gwion, v->type) && !vflag(v, vflag_member)) + if (v && is_func(env->gwion, v->type) && !v->from->owner_class) return call2ufcs(env, call, v); return NULL; } @@ -684,6 +697,9 @@ ANN static Type_List check_template_args(const Env env, Exp_Call *exp, Exp template_arg = exp->args; while (arg && template_arg) { if (list->xid == arg->td->xid) { + if (isa(template_arg->type, env->gwion->type[et_lambda]) > 0 && + !template_arg->type->info->func) + break; tl[args_number] = mk_type_list(env, arg, template_arg->type, fdef->base->pos); if (args_number) tl[args_number - 1]->next = tl[args_number]; @@ -695,7 +711,7 @@ ANN static Type_List check_template_args(const Env env, Exp_Call *exp, } list = list->next; } - if (args_number < type_number) + if (args_number < type_number) // TODO: free type_list ERR_O(exp->func->pos, _("not able to guess types for template call.")) return tl[0]; } @@ -721,6 +737,8 @@ ANN static Type check_lambda_call(const Env env, const Exp_Call *exp) { Exp e = exp->args; while (arg && e) { arg->type = e->type; + if(is_class(env->gwion, arg->type)) + type_addref(arg->type); arg = arg->next; e = e->next; } @@ -740,6 +758,8 @@ ANN static Type check_lambda_call(const Env env, const Exp_Call *exp) { } ANN m_bool func_check(const Env env, Exp_Call *const exp) { + if(exp->func->exp_type == ae_exp_dot) + exp->func->d.exp_dot.is_call = true; CHECK_OB(check_exp(env, exp->func)); if (exp->func->exp_type == ae_exp_decl) ERR_B(exp->func->pos, _("Can't call late function pointer at declaration " @@ -893,6 +913,9 @@ ANN static Type check_exp_call(const Env env, Exp_Call *exp) { if (!ret) return exp_self(exp)->type; const Type t = actual_type(env->gwion, exp->func->type); if (!is_func(env->gwion, t)) return check_exp_call1(env, exp); + if(isa(t, env->gwion->type[et_lambda]) > 0) + if (!t->info->func) + ERR_O(exp->func->pos, _("invalid lambda use.")) if (exp->args) CHECK_OO(check_exp(env, exp->args)); if (!t->info->func->def->base->tmpl) ERR_O(exp_self(exp)->pos, _("template call of non-template function.")) @@ -1540,6 +1563,8 @@ ANN m_bool check_func_def(const Env env, const Func_Def f) { if (tmpl_base(f->base->tmpl) && fbflag(f->base, fbflag_op)) return GW_OK; const Func func = f->base->func; const Func_Def fdef = func->def; + if(fflag(func, fflag_valid))return GW_OK; + set_fflag(fdef->base->func, fflag_valid); assert(func == fdef->base->func); if (env->class_def) // tmpl ? CHECK_BB(check_parent_match(env, fdef)); @@ -1580,7 +1605,6 @@ ANN m_bool check_func_def(const Env env, const Func_Def f) { --env->scope->depth; env->func = former; if (ret > 0) { - set_fflag(fdef->base->func, fflag_valid); if (env->class_def && fdef->base->effects.ptr && (override && !check_effect_overload(&fdef->base->effects, override->d.func_ref))) diff --git a/src/parse/scan1.c b/src/parse/scan1.c index 57927f18..be809612 100644 --- a/src/parse/scan1.c +++ b/src/parse/scan1.c @@ -112,10 +112,14 @@ ANN static m_bool scan1_decl(const Env env, const Exp_Decl *decl) { env->class_def->size += t->size; } } - } - set_vflag(v, vflag_fglobal); // file global + } else + set_vflag(v, vflag_fglobal); // file global } else if (GET_FLAG(decl->td, global)) SET_FLAG(v, global); + else if(v->type != env->gwion->type[et_auto] && v->type != env->class_def) { + type_addref(v->type); + set_vflag(v, vflag_inner); // file global + } } while ((list = list->next)); ((Exp_Decl *)decl)->type = decl->list->self->value->type; return GW_OK; diff --git a/src/vm/vm.c b/src/vm/vm.c index 5075d114..040f7062 100644 --- a/src/vm/vm.c +++ b/src/vm/vm.c @@ -53,8 +53,8 @@ ANN static bool unwind(VM_Shred shred, const Symbol effect, const m_uint size) { const uint16_t pc = shred->pc; for (m_uint i = 0; i < m_vector_size(&code->live_values); i++) { VMValue *vmval = (VMValue *)m_vector_addr(&code->live_values, i); - if (pc < vmval->start) break; - if (pc > vmval->end) continue; + if (pc <= vmval->start) break; + if (pc >= vmval->end) continue; m_bit *const data = &*(m_bit *)(shred->mem + vmval->offset); compound_release(shred, vmval->t, data); }