]> Nishi Git Mirror - gwion.git/commitdiff
:bug: Fix fptr bugs
authorfennecdjay <astor.jeremie@wanadoo.fr>
Fri, 10 May 2019 07:32:25 +0000 (09:32 +0200)
committerfennecdjay <astor.jeremie@wanadoo.fr>
Fri, 10 May 2019 07:32:25 +0000 (09:32 +0200)
src/emit/emit.c
src/lib/func.c
src/lib/gack.c
src/parse/check.c
src/parse/scan0.c
src/vm/shreduler.c
src/vm/vm.c

index 7fad5a9562da60569e8672e45d3a4fb026567062..a6aa0fdf1b165bc7ddccfa8cf98c81caff65cf8f 100644 (file)
@@ -517,7 +517,6 @@ ANN static m_bool emit_dot_static_data(const Emitter emit, const Value v, const
   const m_uint size = v->type->size;
   if(isa(v->type, t_class) < 0) {
     if(isa(v->type, t_union) < 0) {
-printf("%s %lu %p·\n", v->name, v->offset, v->owner->info->class_data);
       const Instr instr = emit_kind(emit, size, emit_var, dotstatic);
       instr->m_val = (m_uint)(v->owner->info->class_data + v->offset);
       instr->m_val2 = size;
@@ -882,6 +881,7 @@ ANN static void emit_exp_spork_finish(const Emitter emit, const m_uint depth) {
   pop->m_val = depth;
   const Instr spork = emit_add_instr(emit, SporkFunc);
   spork->m_val = depth + SZ_INT;
+  spork->m_val2 = -SZ_INT;
 }
 
 static inline void stack_alloc(const Emitter emit) {
@@ -927,7 +927,8 @@ ANN static m_bool spork_func(const Emitter emit, const Exp_Call* exp) {
 
 ANN m_bool emit_exp_spork(const Emitter emit, const Exp_Unary* unary) {
   const m_bool is_spork = unary->op == op_spork;
-  if(unary->code) {
+  const Func f = !unary->code ? unary->exp->d.exp_call.m_func : NULL;
+  if(!f) {
     emit_add_instr(emit, RegPushImm);
     push_spork_code(emit, is_spork ? SPORK_CODE_PREFIX : FORK_CODE_PREFIX, unary->code->pos);
     if(!SAFE_FLAG(emit->env->func, member))
@@ -942,7 +943,7 @@ ANN m_bool emit_exp_spork(const Emitter emit, const Exp_Unary* unary) {
   const Instr ini = emit_add_instr(emit, unary->op == op_spork ? SporkIni : ForkIni);
   ini->m_val = (m_uint)code;
   ini->m_val2 = is_spork;
-  if(unary->code) {
+  if(!f) {
     if(!is_spork) {
       const Instr push = emit_add_instr(emit, RegPush);
       push->m_val = SZ_INT;
@@ -950,8 +951,23 @@ ANN m_bool emit_exp_spork(const Emitter emit, const Exp_Unary* unary) {
     const Instr spork = emit_add_instr(emit, is_spork ? SporkExp : ForkEnd);
     spork->m_val = emit->code->stack_depth;
   } else {
-    const Func f = unary->exp->d.exp_call.m_func;
-    emit_exp_spork_finish(emit, f->def->stack_depth);
+    if(GET_FLAG(f, member) && isa(actual_type(f->value_ref->type), t_fptr) > 0) {
+      const m_uint depth = f->def->stack_depth;
+      const Instr pop = emit_add_instr(emit, RegPop);
+      pop->m_val = depth;
+      emit_add_instr(emit, RegPushMem);
+      const Instr arg = emit_add_instr(emit, SporkFunc);
+      arg->m_val = depth - SZ_INT;
+      const Instr cpy = emit_add_instr(emit, SporkFunc);
+      cpy->m_val = SZ_INT;
+      cpy->m_val2 = -SZ_INT;
+      const Instr cpy1 = emit_add_instr(emit, SporkFunc);
+      cpy1->m_val = SZ_INT;
+      cpy1->m_val2 = SZ_INT;
+      const Instr code = emit_add_instr(emit, DotMember);
+      code->m_val = f->value_ref->offset;
+    } else
+      emit_exp_spork_finish(emit, f->def->stack_depth);
     const Instr end = emit_add_instr(emit, is_spork ? SporkEnd : ForkEnd);
     end->m_val2 = f->def->base->ret_type->size;
   }
@@ -1426,16 +1442,8 @@ ANN static m_bool emit_stmt_union(const Emitter emit, const Stmt_Union stmt) {
     SET_FLAG(stmt->l->self->d.exp_decl.list->self->value, enum);
   }
   if(stmt->xid){
-//    if(!emit->env->class_def) {
       const Instr instr = emit_add_instr(emit, RegPop);
       instr->m_val = !GET_FLAG(stmt, static) ? SZ_INT : SZ_INT*2;
-/*
-    } else if(!GET_FLAG(stmt, static)) {
-      const Instr instr = emit_add_instr(emit, RegPop);
-      instr->m_val = SZ_INT;
-      printf("stmt->o %lu\n", stmt->o);
-    }
-*/
   }
   emit_union_offset(stmt->l, stmt->o);
   if(stmt->xid || stmt->type_xid || global)
@@ -1696,27 +1704,11 @@ ANN static m_bool emit_func_def(const Emitter emit, const Func_Def func_def) {
   emit_push_scope(emit);
   emit->env->func = func;
   CHECK_BB(emit_func_def_body(emit, func_def))
-//  if(GET_FLAG(func_def, variadic) && !emit->env->func->variadic)
   if(GET_FLAG(func_def, variadic)) {
     if(!emit->env->func->variadic)
       ERR_B(func_def->pos, "invalid variadic use")
     if(!GET_FLAG(func, empty))
       ERR_B(func_def->pos, "invalid variadic use")
-//printf("opcode %p %p %p\n", emit->env->func->variadic->execute, VarargTop, VarargEnd);
-
-/*
-    if(emit->env->func->variadic->execute == VarargIni ||
-      emit->env->func->variadic->execute == VarargTop
-) {
-//assert(emit->env->func->variadic->execute == VarargTop);
-//free_code(emit->gwion->p, emit->code);
-//  emit_func_def_code(emit, func);
-//  REM_REF(func->code, emit->gwion);
-//  emit->env->func = former;
-//  emit_pop_code(emit);
-      ERR_B(func_def->pos, "invalid variadic use")
-    }
-*/
   }
   emit_func_def_return(emit);
   emit_func_def_code(emit, func);
@@ -1782,6 +1774,7 @@ ANN static m_bool emit_class_def(const Emitter emit, const Class_Def class_def)
     while((body = body->next));
   }
   emit_class_finish(emit, nspc);
+  SET_FLAG(class_def->base.type->nspc->pre_ctor, ctor);
   emit_class_pop(emit);
   SET_FLAG(type, emit);
   return GW_OK;
index 434b5ae173625b7612fc0c132758d0464055fc96..315874092e863e15b490d82dc1e67944fcb0f180 100644 (file)
@@ -39,8 +39,7 @@ static OP_CHECK(opck_func_call) {
 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) {
+  if((bin->lhs->type != t_lambda && isa(bin->lhs->type, t_fptr) < 0) && GET_FLAG(bin->rhs->type->d.func, member)) {
     const Instr instr = emit_add_instr(emit, LambdaAssign);
     instr->m_val = SZ_INT;
   }
@@ -149,7 +148,7 @@ static OP_EMIT(opem_fptr_cast) {
     const Instr instr = emit_add_instr(emit, RegPop);
     instr->m_val = SZ_INT*2;
     const Instr dup = emit_add_instr(emit, Reg2Reg);
-    dup->m_val = -SZ_INT;
+    dup->m_val2 = SZ_INT;
   }
   return GW_OK;
 }
index 2eecff797fb637066f717c3ecb3d270def2f76b5..0b3e847257d0e73e3a6dc2354253bab04874ea36 100644 (file)
@@ -79,10 +79,9 @@ ANN static inline void print_func(const Type type, const m_bit* stack) {
   if(type->d.func) {
     const VM_Code code = isa(type, t_fptr) > 0 ?
       *(VM_Code*)stack : type->d.func->code;
-    gw_out("%s %p", type->name, (void*)code ? code->name : NULL);
-  } else {
+    gw_out("%s %s %p", type->name, (void*)code ? code->name : NULL, code);
+  } else
     gw_out("%s %p", type->name, NULL);
-  }
 }
 
 ANN static void print_prim(const Type type, const m_bit* stack) {
index 2a3642892cebbb468a3f58c445ce5c90553c8e7a..0a9585802d97a06fe4a5b34c5e87b9669efad9be 100644 (file)
@@ -64,12 +64,8 @@ ANN static m_bool check_fptr_decl(const Env env, const Var_Decl var) {
   }
   if(isa(type, env->class_def) < 0 && !GET_FLAG(func, global))
     ERR_B(var->pos, "can't use non global fptr of other class.")
-  if(GET_FLAG(func, member)) {
-    if(GET_FLAG(v, static))
+  if(GET_FLAG(func, member) && GET_FLAG(v, static))
       ERR_B(var->pos, "can't use static variables for member function.")
-    if(!GET_FLAG(v, member))
-      ERR_B(var->pos, "can't use member variables for static function.")
-  }
   return GW_OK;
 }
 
@@ -704,7 +700,7 @@ ANN static Type check_exp_dot(const Env env, Exp_Dot* member) {
     ERR_O(member->base->pos,
           "type '%s' does not have members - invalid use in dot expression of %s",
           the_base->name, str)
-  if(!strcmp(str, "this") && base_static)
+  if(member->xid ==  insert_symbol("this") && base_static)
     ERR_O(exp_self(member)->pos,
           "keyword 'this' must be associated with object instance...")
   const Value value = find_value(the_base, member->xid);
index 9703ac49e12adfb627c2384f8d69d7c1b6440aeb..891b4409ab9371db08ae7631dd519aaaae1d26d7 100644 (file)
@@ -46,7 +46,7 @@ ANN m_bool scan0_stmt_type(const Env env, const Stmt_Type stmt) {
   CHECK_BB(env_access(env, stmt->ext->flag, stmt_self(stmt)->pos))
   const Type base = known_type(env, stmt->ext);
   CHECK_OB(base)
-  CHECK_BB(scan0_defined(env, stmt->xid, stmt->ext->xid->pos))
+  CHECK_BB(scan0_defined(env, stmt->xid, td_pos(stmt->ext)))
   if(!stmt->ext->types && (!stmt->ext->array || !stmt->ext->array->exp)) {
     const Type t = new_type(env->gwion->p, ++env->scope->type_xid, s_name(stmt->xid), base);
     t->size = base->size;
index dbf01813c4782d0455876c3d087e95b047c341c6..c1319b2906d64dc852f5671126fff536648260b3 100644 (file)
@@ -47,8 +47,11 @@ ANN static void unwind(const VM_Shred shred) {
       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);
+        if(GET_FLAG(code, ctor))
+          code = *(VM_Code*)(shred->mem - SZ_INT*2);
+        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;
index 2a15f8585461793520997d05ee8c78772ef8f07f..58c9309567eed2b2d2140e6e07b1c4175272323f 100644 (file)
@@ -624,7 +624,7 @@ sporkini:
 sporkfunc:
 //  LOOP_OPTIM
   for(m_uint i = 0; i < instr->m_val; i+= SZ_INT)
-    *(m_uint*)(a.child->reg + i) = *(m_uint*)(reg + i - SZ_INT);
+    *(m_uint*)(a.child->reg + i) = *(m_uint*)(reg + i + (m_int)instr->m_val2);
   a.child->reg += instr->m_val;
   DISPATCH()
 sporkexp: