From: Jérémie Astor Date: Fri, 8 May 2020 18:45:14 +0000 (+0200) Subject: :art: Fix envset, improve array and VM X-Git-Tag: nightly~1628 X-Git-Url: http://10.10.0.4:5575/?a=commitdiff_plain;h=2102a44506dfe000632a259bcd7a144ea96aceef;p=gwion.git :art: Fix envset, improve array and VM --- diff --git a/src/env/envset.c b/src/env/envset.c index de3917a5..cfa938c9 100644 --- a/src/env/envset.c +++ b/src/env/envset.c @@ -8,7 +8,7 @@ ANN static void check(struct EnvSet *es, const Type t) { const Vector v = &es->env->scope->class_stack; Type owner = t->e->owner_class; - for(vtype i = vector_size(v); owner && --i;) { + for(vtype i = vector_size(v) + 1; owner && --i;) { if(owner != (Type)vector_at(v, i - 1)) { es->run = 1; return; @@ -54,7 +54,8 @@ ANN m_bool envset_run(struct EnvSet *es, const Type t) { check(es, t); if(es->run) CHECK_BB(push(es, t->e->owner_class)) - const m_bool ret = es->func(es->data, t->e->def); + const m_bool ret = !(t->flag & es->flag) ? + es->func(es->data, t->e->def) : GW_OK; if(es->run) envset_pop(es, t->e->owner_class); return ret; diff --git a/src/gwion.c b/src/gwion.c index 97d42f06..d1f0e336 100644 --- a/src/gwion.c +++ b/src/gwion.c @@ -184,5 +184,5 @@ ANN void push_global(struct Gwion_ *gwion, const m_str name) { ANN Nspc pop_global(struct Gwion_ *gwion) { const Nspc nspc = gwion->env->global_nspc->parent; REM_REF(gwion->env->global_nspc, gwion) - return gwion->env->global_nspc = nspc; + return gwion->env->curr = gwion->env->global_nspc = nspc; } diff --git a/src/lib/array.c b/src/lib/array.c index c9b3b239..81a3ebe5 100644 --- a/src/lib/array.c +++ b/src/lib/array.c @@ -138,18 +138,20 @@ ANN static Type get_array_type(Type t) { } #define ARRAY_OPCK \ - const Exp_Binary* bin = (Exp_Binary*)data; \ const Type l = get_array_type(bin->lhs->info->type); \ const Type r = get_array_type(bin->rhs->info->type); \ if(isa(l, r) < 0) \ ERR_N(exp_self(bin)->pos, _("array types do not match.")) static OP_CHECK(opck_array_at) { - ARRAY_OPCK + const Exp_Binary* bin = (Exp_Binary*)data; if(opck_const_rhs(env, data, mut) == env->gwion->type[et_null]) return env->gwion->type[et_null]; - if(bin->lhs->info->type->array_depth != bin->rhs->info->type->array_depth) - ERR_N(exp_self(bin)->pos, _("array depths do not match.")) + if(bin->lhs->info->type != env->gwion->type[et_null]) { + ARRAY_OPCK + if(bin->lhs->info->type->array_depth != bin->rhs->info->type->array_depth) + ERR_N(exp_self(bin)->pos, _("array depths do not match.")) + } if(bin->rhs->exp_type == ae_exp_decl) { if(bin->rhs->d.exp_decl.list->self->array && bin->rhs->d.exp_decl.list->self->array->exp) @@ -160,6 +162,10 @@ static OP_CHECK(opck_array_at) { } static OP_CHECK(opck_array_shift) { + const Exp_Binary* bin = (Exp_Binary*)data; + if(bin->rhs->info->type == env->gwion->type[et_null] && + bin->lhs->info->type->array_depth > 1) + return bin->lhs->info->type; ARRAY_OPCK if(bin->lhs->info->type->array_depth != bin->rhs->info->type->array_depth + 1) ERR_N(exp_self(bin)->pos, "array depths do not match for '<<'."); @@ -294,6 +300,7 @@ ANN static inline Exp emit_n_exp(const Emitter emit, struct ArrayAccessInfo *co e->next = next; return ret > 0 ? next : NULL; } + static OP_EMIT(opem_array_access) { struct ArrayAccessInfo *const info = (struct ArrayAccessInfo*)data; if(info->array.type->array_depth >= info->array.depth) { @@ -329,7 +336,7 @@ GWION_IMPORT(array) { GWI_BB(gwi_func_end(gwi, vm_vector_rem, ae_flag_none)) GWI_BB(gwi_class_end(gwi)) - GWI_BB(gwi_oper_ini(gwi, "@Array", (m_str)OP_ANY_TYPE, NULL)) + GWI_BB(gwi_oper_ini(gwi, (m_str)OP_ANY_TYPE, "@Array", NULL)) GWI_BB(gwi_oper_add(gwi, opck_array_at)) GWI_BB(gwi_oper_end(gwi, "@=>", ObjectAssign)) GWI_BB(gwi_oper_ini(gwi, "nonnull @Array", (m_str)OP_ANY_TYPE, NULL)) diff --git a/src/lib/engine.c b/src/lib/engine.c index 688f2721..b920d6b3 100644 --- a/src/lib/engine.c +++ b/src/lib/engine.c @@ -67,7 +67,7 @@ OP_CHECK(opck_object_dot); OP_EMIT(opem_object_dot); ANN static m_bool import_core_libs(const Gwi gwi) { const Type t_class = gwi_mk_type(gwi, "@Class", SZ_INT, NULL); - gwi->gwion->type[et_class] = t_class; + GWI_BB(gwi_set_global_type(gwi, t_class, et_class)) GWI_BB(gwi_add_type(gwi, t_class)) GWI_BB(gwi_oper_ini(gwi, (m_str)OP_ANY_TYPE, (m_str)OP_ANY_TYPE, NULL)) GWI_BB(gwi_oper_add(gwi, opck_object_dot)) @@ -77,8 +77,9 @@ ANN static m_bool import_core_libs(const Gwi gwi) { const Type t_undefined = gwi_mk_type(gwi, "@Undefined", SZ_INT, NULL); GWI_BB(gwi_set_global_type(gwi, t_undefined, et_undefined)) const Type t_auto = gwi_mk_type(gwi, "auto", SZ_INT, NULL); + SET_FLAG(t_auto, infer); GWI_BB(gwi_set_global_type(gwi, t_auto, et_auto)) - SET_FLAG(t_class, abstract); + SET_FLAG(t_class, infer); const Type t_void = gwi_mk_type(gwi, "void", 0, NULL); GWI_BB(gwi_gack(gwi, t_void, gack_void)) GWI_BB(gwi_set_global_type(gwi, t_void, et_void)) @@ -113,11 +114,12 @@ ANN static m_bool import_core_libs(const Gwi gwi) { GWI_BB(gwi_gack(gwi, t_fptr, gack_fptr)) GWI_BB(gwi_set_global_type(gwi, t_fptr, et_fptr)) const Type t_lambda = gwi_mk_type(gwi, "@lambda", SZ_INT, "@function"); + SET_FLAG(t_lambda, infer); GWI_BB(gwi_set_global_type(gwi, t_lambda, et_lambda)) + GWI_BB(gwi_typedef_ini(gwi, "int", "@internal")) GWI_BB(gwi_typedef_end(gwi, ae_flag_none)) - GWI_BB(import_object_op(gwi)) GWI_BB(import_values(gwi)) diff --git a/src/lib/object_op.c b/src/lib/object_op.c index 86e69862..3b6f05c7 100644 --- a/src/lib/object_op.c +++ b/src/lib/object_op.c @@ -406,7 +406,7 @@ ANN static Type scan_class(const Env env, const Type t, const Type_Decl* td) { return a->base.type; struct EnvSet es = { .env=env, .data=env, .func=(_exp_func)scan0_cdef, .scope=env->scope->depth, .flag=ae_flag_scan0 }; - CHECK_BO(envset_push(&es, t->e->owner_class, t->e->owner)) + CHECK_BO(envset_push(&es, t->e->owner_class, env->context->nspc)) a->base.tmpl = mk_tmpl(env, t->e->def->base.tmpl, td->types); const m_bool ret = _scan_class(env, t, a); if(es.run) diff --git a/src/main.c b/src/main.c index 597130d2..156e85fc 100644 --- a/src/main.c +++ b/src/main.c @@ -17,12 +17,13 @@ static void sig(int unused NUSED) { #ifdef __AFL_HAVE_MANUAL_CONTROL -#define BUFSIZE 256 +#define BUFSIZE 128 static void afl_run(const Gwion gwion) { + __AFL_INIT(); char buf[BUFSIZE]; struct GwText_ text = { .mp=gwion->mp }; - while (__AFL_LOOP(128)) { + while (__AFL_LOOP(256)) { ssize_t sz; memset(buf, 0, BUFSIZE); while((sz = read(0, buf, BUFSIZE)) > 0) { @@ -33,12 +34,12 @@ static void afl_run(const Gwion gwion) { push_global(gwion, "[afl]"); gwion_run(gwion); pop_global(gwion); - } + } text_reset(&text); } text_release(&text); } -#define gwion_run(a) afl_run(a) +#define gwion_run(a) { afl_run(a); return; } #endif int main(int argc, char** argv) { diff --git a/src/parse/check.c b/src/parse/check.c index a1147bda..8e7b7f5b 100644 --- a/src/parse/check.c +++ b/src/parse/check.c @@ -159,8 +159,7 @@ ANN Type check_exp_decl(const Env env, const Exp_Decl* decl) { clear_decl(env, decl); CHECK_BO(scan1_exp(env, exp_self(decl))) CHECK_BO(scan2_exp(env, exp_self(decl))) - const Type t_auto = env->gwion->type[et_auto]; - if(decl->type == t_auto) + if(GET_FLAG(decl->type, infer)) ERR_O(td_pos(decl->td), _("can't infer type.")); } if(!decl->type) @@ -175,7 +174,7 @@ ANN Type check_exp_decl(const Env env, const Exp_Decl* decl) { const m_bool ret = check_decl(env, decl); if(global) env_pop(env, scope); - return ret > 0 ? decl->type : NULL; + return ret > 0 ? decl->list->self->value->type : NULL; } @@ -980,8 +979,11 @@ ANN static m_bool do_stmt_auto(const Env env, const Stmt_Auto stmt) { td.array = &array; } ptr = known_type(env, &td); - if(!GET_FLAG(ptr, checked) && ptr->e->def) - CHECK_BB(ensure_check(env, ptr)) + if(!GET_FLAG(ptr, checked) && ptr->e->def) { + struct EnvSet es = { .env=env, .data=env, .func=(_exp_func)traverse_cdef, + .scope=env->scope->depth, .flag=ae_flag_check }; + CHECK_BB(envset_run(&es, get_type(ptr))) + } } t = depth ? array_type(env, ptr, depth) : ptr; stmt->v = new_value(env->gwion->mp, t, s_name(stmt->sym)); @@ -1138,9 +1140,11 @@ ANN static Symbol case_op(const Env env, const Exp e, const m_uint i) { } ANN static m_bool match_case_exp(const Env env, Exp e) { + Exp last = e; for(m_uint i = 0; i < map_size(&env->scope->match->map); e = e->next, ++i) { if(!e) - ERR_B(e->pos, _("no enough to match")) + ERR_B(last->pos, _("no enough to match")) + last = e; const Symbol op = case_op(env, e, i); if(op) { const Exp base = (Exp)VKEY(&env->scope->match->map, i); diff --git a/src/parse/template.c b/src/parse/template.c index a0a52c6f..932c63a1 100644 --- a/src/parse/template.c +++ b/src/parse/template.c @@ -113,15 +113,14 @@ ANN Type scan_type(const Env env, const Type t, Type_Decl* td) { CHECK_OO(owner) if(!owner->nspc) ERR_O(td_pos(td), "type '%s' has no namespace", owner->name) - const Tmpl *tmpl = GET_FLAG(owner, template) ? - owner->e->def->base.tmpl : NULL; - if(tmpl) - CHECK_BO(template_push_types(env, tmpl)) - const m_uint scope = env_push(env, owner, owner->nspc); + struct EnvSet es = { .env=env, .data=env, + .scope=env->scope->depth, .flag=ae_flag_none }; + envset_push(&es, owner, owner->nspc); + (void)env_push(env, owner, owner->nspc); const Type ret = scan_type(env, t, td->next); - env_pop(env, scope); - if(tmpl) - nspc_pop_type(env->gwion->mp, env->curr); + env_pop(env, es.scope); + if(es.run) + envset_pop(&es, owner); return ret; } return _scan_type(env, t, td); diff --git a/src/vm/vm.c b/src/vm/vm.c index 248d56e0..008a8425 100644 --- a/src/vm/vm.c +++ b/src/vm/vm.c @@ -705,16 +705,19 @@ branchnefloat: reg -= SZ_FLOAT; BRANCH_DISPATCH(*(m_float*)reg); arrayappend: - m_vector_add(ARRAY(a.obj), reg); - release(a.obj, shred); + m_vector_add(ARRAY(*(M_Object*)(reg-SZ_INT)), reg); + release(*(M_Object*)(reg-SZ_INT), shred); DISPATCH() autoloop: - m_vector_get(ARRAY(a.obj), *(m_uint*)(mem + VAL), mem + VAL + SZ_INT); +// m_vector_get(ARRAY(a.obj), *(m_uint*)(mem + VAL), mem + VAL + SZ_INT); + m_vector_get(ARRAY(*(M_Object*)(reg-SZ_INT)), *(m_uint*)(mem + VAL), mem + VAL + SZ_INT); goto autoloopcount; autoloopptr: - *(m_bit**)(*(M_Object*)(mem + VAL + SZ_INT))->data = m_vector_addr(ARRAY(a.obj), *(m_uint*)(mem + VAL)); + *(m_bit**)(*(M_Object*)(mem + VAL + SZ_INT))->data = m_vector_addr(ARRAY(*(M_Object*)(reg-SZ_INT)), *(m_uint*)(mem + VAL)); +// *(m_bit**)(*(M_Object*)(mem + VAL + SZ_INT))->data = m_vector_addr(ARRAY(a.obj), *(m_uint*)(mem + VAL)); autoloopcount: - *(m_uint*)reg = m_vector_size(ARRAY(a.obj)) - (*(m_uint*)(mem + VAL))++; + *(m_uint*)reg = m_vector_size(ARRAY(*(M_Object*)(reg-SZ_INT))) - (*(m_uint*)(mem + VAL))++; +// *(m_uint*)reg = m_vector_size(ARRAY(a.obj)) - (*(m_uint*)(mem + VAL))++; reg += SZ_INT; DISPATCH() arraytop: @@ -726,6 +729,7 @@ arrayaccess: { register const m_int idx = *(m_int*)(reg + SZ_INT * VAL); if(idx < 0 || (m_uint)idx >= m_vector_size(ARRAY(a.obj))) { +// if(idx < 0 || (m_uint)idx >= m_vector_size(ARRAY(*(M_Object*)(reg-SZ_INT)))) { gw_err(_(" ... at index [%" INT_F "]\n"), idx); gw_err(_(" ... at dimension [%" INT_F "]\n"), VAL); VM_OUT @@ -766,9 +770,6 @@ objassign: } assign: reg -= SZ_INT; -// a.obj = *(M_Object*)(reg-SZ_INT); -// **(M_Object**)reg = a.obj; -// a.obj = **(M_Object**)reg = *(M_Object*)(reg-SZ_INT); DISPATCH() remref: