]> Nishi Git Mirror - gwion.git/commitdiff
:bug: after AFL run
authorJérémie Astor <fennecdjay@gmail.com>
Fri, 25 Jun 2021 11:23:16 +0000 (13:23 +0200)
committerJérémie Astor <fennecdjay@gmail.com>
Fri, 25 Jun 2021 11:49:46 +0000 (13:49 +0200)
16 files changed:
ast
fmt
include/env/value.h
plug
src/emit/emit.c
src/env/env.c
src/env/value.c
src/import/import_oper.c
src/lib/engine.c
src/lib/lib_func.c
src/lib/object_op.c
src/lib/string.c
src/main.c
src/parse/check.c
src/parse/scan1.c
src/vm/vm.c

diff --git a/ast b/ast
index d7cc060e0fe49405ca5494810c181ef211daf7f2..c3a97d173da142bccfafb48ab532359ba77bb6aa 160000 (submodule)
--- a/ast
+++ b/ast
@@ -1 +1 @@
-Subproject commit d7cc060e0fe49405ca5494810c181ef211daf7f2
+Subproject commit c3a97d173da142bccfafb48ab532359ba77bb6aa
diff --git a/fmt b/fmt
index 11f86a1a1aad81ff6dba21605398007898e2fb3f..d78297aacc14071b97ae22e47f9e1c06054c15de 160000 (submodule)
--- a/fmt
+++ b/fmt
@@ -1 +1 @@
-Subproject commit 11f86a1a1aad81ff6dba21605398007898e2fb3f
+Subproject commit d78297aacc14071b97ae22e47f9e1c06054c15de
index 67879b7b3d83cad28b3d8a2b2e5cea79f2b84360..aa498b6d9e18f2eb137cc9eb98b07c2aef247a2a 100644 (file)
@@ -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 857e0e59f0bb00b6de35ad770814960c3e442d6a..37f2a1e20f85c2f455abb85340557b994c294cf0 160000 (submodule)
--- a/plug
+++ b/plug
@@ -1 +1 @@
-Subproject commit 857e0e59f0bb00b6de35ad770814960c3e442d6a
+Subproject commit 37f2a1e20f85c2f455abb85340557b994c294cf0
index b8346af002cd56c70da4ce717e1cf410a3448785..140cd98294cf6c91d1f10b5a1ad72ce107d704c4 100644 (file)
@@ -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;
 }
index 5f5a9e57cd5259c0ed7dbfb548471346c8ad0154..1bac40a4f926c8370a02e8cd5eabee50a90a64f5 100644 (file)
@@ -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) {
index 5c95cf31671ae5f6e00873fd522c0c4532daad51..a82e2661ec9b070c91f85ab76d26121c16b68c93 100644 (file)
@@ -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);
 }
index 970a1003db69ead7e9ffdcdea11bc7efaa72c9b9..68adceaaebabbd394e6e5f57013989fa2817b9b5 100644 (file)
@@ -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}",
index 4f08b734050e2c97b7111a93b442b588ba56b00a..300ffe76182ca9c1dca5a85cdd90913b1627b7e9 100644 (file)
@@ -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;
 }
 
index a3bb28f5edcd35e9a069e097dee18cde83959fb2..bdfe3e417cb6cceac368437f32bb3aca62abed06 100644 (file)
@@ -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);
index 7ab2001e5fce257e5820a07ecc6789886fb17c1f..2ff6400dc09cf209abf99a703fee0e6d1c1f1c4c 100644 (file)
@@ -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;
index 68ff08d33e4023c1f86bd0eadc7699b48cb37b31..06814347d3149743c20b02b40c644c9b0d584690 100644 (file)
@@ -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;
index bdf756b98b1e294b39d9a4b55f46651c31fdb45c..41dd4219cbcea7b281640d795d5be12eeb61e3d0 100644 (file)
@@ -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
index 963afe8bfcbe16625201136549a66c68b47c64c7..849d73e83a8a65ba395c4836fb7ecaad730b0ec0 100644 (file)
@@ -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)))
index 57927f1880bb692e7d7c88f42984fe24b86a4398..be80961269b2401cdc9b80750cc3b5b38d961425 100644 (file)
@@ -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;
index 5075d1148235b46adf86b3729a3382e1d7596dd0..040f7062b85a2294bc2db920f27660d9cef84abc 100644 (file)
@@ -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);
     }