]> Nishi Git Mirror - gwion.git/commitdiff
:bug: Thanks AFL
authorfennecdjay <astor.jeremie@wanadoo.fr>
Sun, 5 May 2019 18:12:16 +0000 (20:12 +0200)
committerfennecdjay <astor.jeremie@wanadoo.fr>
Sun, 5 May 2019 18:12:16 +0000 (20:12 +0200)
src/emit/emit.c
src/lib/func.c
src/lib/shred.c
src/lib/string.c
src/parse/check.c
src/parse/scan1.c
src/parse/scan2.c
src/vm/shreduler.c
src/vm/vm_shred.c

index 2964fc16ce70e86e7460dc69a150a04b718844fa..8d21d35b3e9896afccfd77bfb97997c688c8c3a7 100644 (file)
@@ -437,8 +437,8 @@ ANN static m_bool prim_id(const Emitter emit, const Exp_Primary* prim) {
     emit_add_instr(emit, RegPushMem);
   else if(prim->d.var == insert_symbol("me"))
     emit_add_instr(emit, RegPushMe);
-  else if(prim->d.var == insert_symbol("now"))
-    emit_add_instr(emit, RegPushNow);
+  else if(prim->d.var == insert_symbol("now") && exp_self(prim)->type == t_now)
+    emit_add_instr(emit, RegPushNow);// 'now' is not reserved for ... now ;-)
   else if(prim->d.var == insert_symbol("maybe"))
     emit_add_instr(emit, RegPushMaybe);
   else if(prim->d.var == insert_symbol("__func__")) {
@@ -1020,7 +1020,7 @@ ANN2(1) static m_bool emit_exp(const Emitter emit, Exp exp, const m_bool ref) {
     CHECK_BB(exp_func[exp->exp_type](emit, &exp->d))
     if(exp->cast_to)
       CHECK_BB(emit_implicit_cast(emit, exp->type, exp->cast_to))
-    if(ref && isa(exp->type, t_object) > 0 && isa(exp->type, t_fork) < 0 ) { // beware fork
+    if(ref && isa(exp->type, t_object) > 0 && isa(exp->type, t_shred) < 0 ) { // beware fork
       const Instr instr = emit_add_instr(emit, RegAddRef);
       instr->m_val = exp->emit_var;
     }
@@ -1079,7 +1079,7 @@ ANN static m_bool emit_stmt_return(const Emitter emit, const Stmt_Exp stmt) {
   if(stmt->val) {
     OPTIMIZE_TCO
     CHECK_BB(emit_exp(emit, stmt->val, 0))
-    if(isa(stmt->val->type, t_object) > 0 && isa(stmt->val->type , t_fork) < 0) // beware fork
+    if(isa(stmt->val->type, t_object) > 0 && isa(stmt->val->type , t_shred) < 0) // beware shred
       emit_add_instr(emit, RegAddRef);
   }
   vector_add(&emit->code->stack_return, (vtype)emit_add_instr(emit, Goto));
@@ -1726,6 +1726,8 @@ ANN static m_bool emit_func_def(const Emitter emit, const Func_Def func_def) {
   emit_func_def_code(emit, func);
   emit->env->func = former;
   emit_pop_code(emit);
+  if(GET_FLAG(func_def, op))
+    SET_FLAG(func->code, op);
   if(!emit->env->class_def && !GET_FLAG(func_def, global) && !func_def->tmpl)
     emit_func_def_global(emit, func->value_ref);
   if(emit->memoize && GET_FLAG(func, pure))
index 97ea35f98fcbd7fa02d7ab29cd44225e6e7da05b..434b5ae173625b7612fc0c132758d0464055fc96 100644 (file)
@@ -40,13 +40,13 @@ static OP_EMIT(opem_func_assign) {
   Exp_Binary* bin = (Exp_Binary*)data;
   emit_add_instr(emit, int_r_assign);
   if(bin->lhs->type != t_lambda && GET_FLAG(bin->rhs->type->d.func, member)
-    && !emit->env->class_def
-) {
+    && !emit->env->class_def) {
     const Instr instr = emit_add_instr(emit, LambdaAssign);
     instr->m_val = SZ_INT;
   }
   return GW_OK;
 }
+
 ANN static Type fptr_type(const Env env, Exp_Binary* bin) {
   const Func l_func = bin->lhs->type->d.func;
   const Func r_func = bin->rhs->type->d.func;
@@ -164,7 +164,12 @@ static OP_CHECK(opck_spork) {
   if(unary->exp && unary->exp->exp_type == ae_exp_call)
     return unary->op == op_spork ? t_shred : t_fork;
   else if(unary->code) {
-    CHECK_BO(check_stmt(env, unary->code))
+    ++env->scope->depth;        \
+    nspc_push_value(env->gwion->p, env->curr); \
+    const m_bool ret = check_stmt(env, unary->code);
+    nspc_pop_value(env->gwion->p, env->curr);  \
+    --env->scope->depth;
+    CHECK_BO(ret)
     return unary->op == op_spork ? t_shred : t_fork;
   } else
     ERR_O(exp_self(unary)->pos, "only function calls can be sporked...")
index 616d097ae2f97a8e30a031fa0bdef26d6941ff42..9398f679b7a7abf2e79f4c37e640c55e64a69c36 100644 (file)
@@ -61,14 +61,16 @@ static MFUN(shred_yield) {
 
 static SFUN(vm_shred_from_id) {
   const m_int index =  *(m_int*)MEM(0);
-// TODO vector_size_safe()
-  if(index <= 0 && (m_uint)index < vector_size(&shred->tick->shreduler->shreds)) {
-    const VM_Shred s = (VM_Shred)vector_at(&shred->tick->shreduler->shreds, (vtype)index);
-    if(s)
-      *(M_Object*)RETURN = s->info->me;
-    else
+  if(index > 0) {
+    for(m_uint i = 0; i < vector_size(&shred->tick->shreduler->shreds); ++i) {
+      const VM_Shred s = (VM_Shred)vector_at(&shred->tick->shreduler->shreds, i);
+      if(s->tick->xid == (m_uint)index) {
+        *(M_Object*)RETURN = s->info->me;
+        return;
+      }
+    }
+  } else
       *(m_uint*)RETURN = 0;
-  }
 }
 
 static MFUN(shred_args) {
index bf59b3b82daceed8cc2711d77f5a3c442e6f2fcd..c8f60843730615290e57ceebee0b96ff2a1c4d83 100644 (file)
@@ -98,6 +98,8 @@ static INSTR(name##_String) {\
   POP_REG(shred, offset); \
   const type lhs = *(type*)REG(-SZ_INT);\
   const M_Object rhs = *(M_Object*)REG(offset-SZ_INT);\
+  if(!rhs)                                          \
+    Except(shred, "NullPtrException");              \
   char str[(len)];\
   sprintf(str, format, __VA_ARGS__);\
   push_new_string(shred, str);\
index 2682819a9bda20a0a45e7f4eb34f20cc7ee57b76..ec766026b46a6f234d4eefd2d079e1d1ae719448 100644 (file)
@@ -417,6 +417,7 @@ ANN static Func _find_template_match(const Env env, const Value v, const Exp_Cal
   const Type_List types = exp->tmpl->types;
   Func m_func = exp->m_func, former = env->func;
   const m_str tmpl_name = tl2str(env, types);
+  const m_uint sz = vector_size((Vector)env->curr->info->type);
   const m_uint scope = env_push(env, v->owner_class, v->owner);
   for(m_uint i = 0; i < v->offset + 1; ++i) {
     Func_Def def = NULL;
@@ -457,6 +458,9 @@ ANN static Func _find_template_match(const Env env, const Value v, const Exp_Cal
         }
       }
     }
+// check m_func => maybe assert
+    if(!m_func && sz != vector_size((Vector)env->curr->info->type))
+     nspc_pop_type(env->gwion->p, env->curr);
     SET_FLAG(base, template);
   }
 end:
@@ -638,7 +642,10 @@ ANN static Type check_exp_cast(const Env env, const Exp_Cast* cast) {
 ANN static Type check_exp_post(const Env env, const Exp_Postfix* post) {
   struct Op_Import opi = { .op=post->op, .lhs=check_exp(env, post->exp), .data=(uintptr_t)post, .pos=exp_self(post)->pos };
   CHECK_OO(opi.lhs)
-  return op_check(env, &opi);
+  const Type t = op_check(env, &opi);
+  if(t && isa(t, t_object) < 0)
+    exp_self(post)->meta = ae_meta_value;
+  return t;
 }
 
 ANN static Type check_exp_call(const Env env, Exp_Call* exp) {
@@ -664,7 +671,10 @@ ANN static Type check_exp_unary(const Env env, const Exp_Unary* unary) {
     .data=(uintptr_t)unary, .pos=exp_self(unary)->pos };
   if(unary->exp && !opi.rhs)
     return NULL;
-  return op_check(env, &opi);
+  const Type t = op_check(env, &opi);
+  if(t && isa(t, t_object) < 0)
+    exp_self(unary)->meta = ae_meta_value;
+  return t;
 }
 
 ANN static Type check_exp_if(const Env env, const Exp_If* exp_if) {
index 76fdcb349ecf125cb0a0b0b9480ce923e94ee4ef..3caf575f98cd2d35bd76c943495efe2493b49b86 100644 (file)
@@ -138,8 +138,9 @@ ANN static m_bool scan1_exp_if(const Env env, const Exp_If* exp_if) {
 }
 
 ANN static inline m_bool scan1_exp_unary(const restrict Env env, const Exp_Unary *unary) {
-  if((unary->op == op_spork || unary->op == op_fork) && unary->code)
-    return scan1_stmt(env, unary->code);
+  if((unary->op == op_spork || unary->op == op_fork) && unary->code) {
+    RET_NSPC(scan1_stmt(env, unary->code))
+  }
   return unary->exp ? scan1_exp(env, unary->exp) : GW_OK;
 }
 
index 99fe0382602888229e8ada4650e3654ff2909ea7..e3cf95012dc3a49313e52a9ad8f941bd93a650bf 100644 (file)
@@ -201,9 +201,9 @@ ANN static inline m_bool scan2_exp_if(const Env env, const Exp_If* exp_if) {
 }
 
 ANN static m_bool scan2_exp_unary(const Env env, const Exp_Unary * unary) {
-  if((unary->op == op_spork || unary->op == op_fork) && unary->code)
-    return scan2_stmt(env, unary->code);
-  else if(unary->exp)
+  if((unary->op == op_spork || unary->op == op_fork) && unary->code) {
+    RET_NSPC(scan2_stmt(env, unary->code))
+  else if(unary->exp)
     return scan2_exp(env, unary->exp);
   return GW_OK;
 }
@@ -446,6 +446,10 @@ ANN static m_str func_tmpl_name(const Env env, const Func_Def f) {
   vector_init(&v);
   do {
     const Type t = nspc_lookup_type0(env->curr, id->xid);
+    if(!t) {
+      vector_release(&v);
+      return NULL;
+    }
     vector_add(&v, (vtype)t);
     tlen += strlen(t->name);
   } while((id = id->next) && ++tlen);
@@ -488,7 +492,10 @@ ANN m_bool scan2_func_def(const Env env, const Func_Def f) {
   if(GET_FLAG(f, global))
     scope = env_push_global(env);
   const Value overload = nspc_lookup_value0(env->curr, f->base->xid);
+  const Value res = nspc_lookup_value1(env->global_nspc, f->base->xid);
   m_str func_name = s_name(f->base->xid);
+  if(res)
+    ERR_B(f->pos, "'%s' already declared as type", func_name)
   if(overload)
     CHECK_BB(scan2_func_def_overload(env, f, overload))
   if(tmpl_list_base(f->tmpl))
@@ -500,7 +507,7 @@ ANN m_bool scan2_func_def(const Env env, const Func_Def f) {
     if(f->base->func)
       func_name = f->base->func->name;
     else
-      func_name = func_tmpl_name(env, f);
+      CHECK_OB((func_name = func_tmpl_name(env, f)))
     const Func func = nspc_lookup_func1(env->curr, insert_symbol(func_name));
     if(func) {
       if(GET_FLAG(func, member))
index dcb4c6c0d6bcef591a2692f4b2ebf7971e84ff62..dbf01813c4782d0455876c3d087e95b047c341c6 100644 (file)
@@ -41,11 +41,15 @@ ANN static void shreduler_parent(const VM_Shred out, const Vector v) {
 
 ANN static void unwind(const VM_Shred shred) {
   VM_Code code = shred->code;
-  while(1) {
+  while(code) {
     const m_bit exec = (m_bit)((Instr)vector_back(code->instr))->opcode;
     if(exec == eFuncReturn) {
-      code = *(VM_Code*)(shred->mem - SZ_INT*3);
-      REM_REF(code, shred->info->vm->gwion);
+      if(GET_FLAG(code, op))
+        code = *(VM_Code*)(shred->mem - SZ_INT);
+      else {
+        code = *(VM_Code*)(shred->mem - SZ_INT*3);
+        REM_REF(code, shred->info->vm->gwion);
+      }
       shred->mem -= *(m_uint*)(shred->mem - SZ_INT*4) + SZ_INT*4;
       if(shred->mem <= (((m_bit*)(shred) + sizeof(struct VM_Shred_) + SIZEOF_REG)))break;
     } else break;
index 6b8ec5f7e7f5d7326e677800f822ffa690ecc845..4afcb0536fa31925101583ebf551f9682443a1c7 100644 (file)
@@ -54,4 +54,4 @@ void free_vm_shred(VM_Shred shred) {
   mp_free(mp, ShredTick, shred->tick);
   free_shredinfo(mp, shred->info);
   mp_free(mp, Stack, shred);
-}
\ No newline at end of file
+}