]> Nishi Git Mirror - gwion.git/commitdiff
:art: fptr and struct improv
authorJérémie Astor <astor.jeremie@wanadoo.fr>
Mon, 18 May 2020 08:49:11 +0000 (10:49 +0200)
committerJérémie Astor <astor.jeremie@wanadoo.fr>
Mon, 18 May 2020 08:49:11 +0000 (10:49 +0200)
include/opcode.h
src/compile.c
src/emit/emit.c
src/lib/func.c
src/lib/instr.c
src/lib/object_op.c
src/parse/check.c
src/parse/scan2.c
src/vm/vm.c
src/vm/vm_code.c

index 2b33fe5be67c8c5bc82f0d404ea1455253735e3b..6fb4aba1b44c2b89927ef4a3ad492422211c2152 100644 (file)
@@ -20,6 +20,8 @@ enum {
   eReg2RegAddr,
   eReg2RegDeref,
   eStructMember,
+  eStructMemberFloat,
+  eStructMemberOther,
   eStructMemberAddr,
   eMemSetImm,
   eRegPushMe,
@@ -174,9 +176,9 @@ enum {
   eGackEnd,
   eGack,
   eNoOp,
-  eDotTmplVal,
-  eOP_MAX,
   eEOC,
+  eOP_MAX,
+  eDotTmplVal,
 };
 
 #define  RegSetImm           (f_instr)eRegSetImm
@@ -198,6 +200,8 @@ enum {
 #define  Reg2RegAddr         (f_instr)eReg2RegAddr
 #define  Reg2RegDeref        (f_instr)eReg2RegDeref
 #define  StructMember        (f_instr)eStructMember
+#define  StructMemberFloat   (f_instr)eStructMemberFloat
+#define  StructMemberOther   (f_instr)eStructMemberOther
 #define  StructMemberAddr    (f_instr)eStructMemberAddr
 #define  MemSetImm           (f_instr)eMemSetImm
 #define  RegPushMe           (f_instr)eRegPushMe
@@ -352,7 +356,7 @@ enum {
 #define  GackEnd             (f_instr)eGackEnd
 #define  Gack                (f_instr)eGack
 #define  NoOp                (f_instr)eNoOp
-#define  DotTmplVal          (f_instr)eDotTmplVal
-#define  OP_MAX              (f_instr)eOP_MAX
 #define  EOC                 (f_instr)eEOC
+#define  OP_MAX              (f_instr)eOP_MAX
+#define  DotTmplVal          (f_instr)eDotTmplVal
 #endif
index 0b80a42344b96fee8b0b0c685417864d64eb2bb8..13e717b9ae4a9c96e5528f8d3c3baf4fd98f298d 100644 (file)
@@ -87,10 +87,10 @@ ANN static m_bool is_reg(const m_str path) {
 ANN static inline m_bool compiler_open(MemPool p, struct Compiler* c) {
   char name[strlen(c->name) + 1];
   strcpy(name, c->name);
-  if(c->type == COMPILE_FILE && !is_reg(name)) {
-    gw_err(_("'%s': is a not a regular file\n"), name);
-    return GW_ERROR;
-  }
+//  if(c->type == COMPILE_FILE && !is_reg(name)) {
+//    gw_err(_("'%s': is a not a regular file\n"), name);
+//    return GW_ERROR;
+//  }
   if(_compiler_open(c) < 0) {
     compiler_error(p, c);
     gw_err(_("can't open '%s'\n"), name);
index 01e6e9d5ece9a9abc0248c11af829d7eebb68657..a13f3c7a9f35619bc161f68bc4c16eb2476cc4d9 100644 (file)
@@ -301,6 +301,7 @@ static const f_instr regpushbase[] = { RegPushBase, RegPushBase2, RegPushBase3,
 static const f_instr dotstatic[]  = { DotStatic, DotStatic2, DotStatic3, RegPushImm };
 static const f_instr allocmember[]  = { RegPushImm, RegPushImm2, RegPushImm3, AllocMember4 };
 static const f_instr allocword[]  = { AllocWord, AllocWord2, AllocWord3, RegPushMem4 };
+static const f_instr structmember[]  = { StructMember, StructMemberFloat, StructMemberOther, StructMemberAddr };
 
 ANN Exp symbol_owned_exp(const Gwion gwion, const Symbol *data);
 ANN static m_bool emit_symbol_owned(const Emitter emit, const Symbol *data) {
@@ -608,11 +609,10 @@ ANN static m_bool emit_exp_decl_static(const Emitter emit, const Var_Decl var_de
 
 ANN static Instr emit_struct_decl(const Emitter emit, const Value v, const m_bool emit_addr) {
   emit_add_instr(emit, RegPushMem);
-  const Instr instr = emit_add_instr(emit, !emit_addr ? StructMember : StructMemberAddr);
-  instr->m_val2 = v->from->offset;
+  const Instr instr = emit_kind(emit, v->type->size, emit_addr, structmember);
   if(!emit_addr)
     regpush(emit, v->type->size - SZ_INT);
-  return instr; // m_val set after but ignored
+  return instr;
 }
 
 ANN static m_bool emit_exp_decl_non_static(const Emitter emit, const Exp_Decl *decl, const Var_Decl var_decl,
@@ -635,7 +635,7 @@ ANN static m_bool emit_exp_decl_non_static(const Emitter emit, const Exp_Decl *d
     }
   }
   const Instr instr = !(SAFE_FLAG(emit->env->class_def, struct) && !emit->env->scope->depth) ?
-    emit_kind(emit, v->type->size, !struct_ctor(v) ? emit_addr : 1, exec) : emit_struct_decl(emit, v, emit_addr);
+    emit_kind(emit, v->type->size, !struct_ctor(v) ? emit_addr : 1, exec) : emit_struct_decl(emit, v, !struct_ctor(v) ? emit_addr : 1);
   instr->m_val = v->from->offset;
   if(is_obj && (is_array || !is_ref)) {
     emit_add_instr(emit, Assign);
@@ -645,14 +645,10 @@ ANN static m_bool emit_exp_decl_non_static(const Emitter emit, const Exp_Decl *d
       push->m_val = -(missing_depth) * SZ_INT;
     }
   } else if(struct_ctor(v) /* && !GET_FLAG(decl->td, ref) */) {
-    if(GET_FLAG(v, member)) {
-      const Instr instr = emit_add_instr(emit, DotMember4);
-      instr->m_val = v->from->offset;
-    }
     emit_ext_ctor(emit, v->type->nspc->pre_ctor);
     if(!emit_addr)
       emit_struct_decl_finish(emit, v);
-  }
+    }
   return GW_OK;
 }
 
index ce84739e26f7c7aec4e63c1d6ad658acb4a3f68f..b2fc0e1f8f2b09bec86a71acd72556e2fa572187 100644 (file)
 #include "template.h"
 #include "parse.h"
 
-static INSTR(LambdaAssign) {
-  POP_REG(shred, SZ_INT)
-  *(Func*)REG(-SZ_INT) = *(Func*)REG(0);
-}
-
 static OP_CHECK(opck_func_call) {
   Exp_Binary* bin = (Exp_Binary*)data;
   Exp_Call call = { .func=bin->rhs, .args=bin->lhs };
@@ -40,8 +35,10 @@ static OP_EMIT(opem_func_assign) {
     fptr_instr(emit, bin->lhs->info->type->e->d.func, 2);
   const Instr instr = emit_add_instr(emit, int_r_assign);
   if(!is_fptr(emit->gwion, bin->lhs->info->type) && GET_FLAG(bin->rhs->info->type->e->d.func, member)) {
-    const Instr pop = emit_add_instr(emit, LambdaAssign);
+    const Instr pop = emit_add_instr(emit, RegPop);
     pop->m_val = SZ_INT;
+    const Instr cpy = emit_add_instr(emit, Reg2Reg);
+    cpy->m_val = -SZ_INT;
   }
   return instr;
 }
@@ -68,7 +65,6 @@ ANN static m_bool fptr_tmpl_push(const Env env, struct FptrInfo *info) {
   return GW_OK;
 }
 
-
 static m_bool td_match(const Env env, Type_Decl *id[2]) {
   DECL_OB(const Type, t0, = known_type(env, id[0]))
   DECL_OB(const Type, t1, = known_type(env, id[1]))
index de018cf1652ee2ea4e449b6898ea30851e23922e..8312c936640e52373f0de00cbb308d11acfca9ec 100644 (file)
@@ -34,7 +34,7 @@ ANN static Func_Def from_base(const Env env, struct dottmpl_ *const dt, const Ns
   const Func_Def fdef = dt->def ?: dt->base;
   const Symbol sym = func_symbol(env, nspc->name, s_name(fdef->base->xid),
     "template", dt->vt_index);
-  DECL_OO(const Value, v, = nspc_lookup_value0(nspc, sym))
+  DECL_OO(const Value, v, = nspc_lookup_value0(nspc, sym) ?: nspc_lookup_value0(nspc, fdef->base->xid))
   const Func_Def def = cpy_func_def(env->gwion->mp, v->d.func_ref->def);
   def->base->tmpl->call = cpy_type_list(env->gwion->mp, dt->tl);
   def->base->tmpl->base = dt->vt_index;
index 2d1932e568e53f9c1e652493f5d749299d8e4787..1ae6d75991d8d95c6442bde3d6973be44221cbbf 100644 (file)
@@ -127,6 +127,8 @@ static OP_CHECK(opck_struct_scan) {
 }
 
 static const f_instr dotstatic[]  = { DotStatic, DotStatic2, DotStatic3, RegPushImm };
+static const f_instr structmember[]  = { StructMember, StructMemberFloat, StructMemberOther, StructMemberAddr };
+
 ANN Instr emit_kind(Emitter emit, const m_uint size, const uint addr, const f_instr func[]);
 ANN static void emit_dot_static_data(const Emitter emit, const Value v, const uint emit_var) {
   const m_uint size = v->type->size;
@@ -181,27 +183,24 @@ ANN static inline void emit_member(const Emitter emit, const Value v, const uint
 
 ANN static inline void emit_struct_addr(const Emitter emit, const Value v) {
   const Instr set = emit_add_instr(emit, StructMemberAddr);
-  set->m_val = v->from->owner_class->size - v->type->size;
-  set->m_val2 = v->from->offset;
+  set->m_val = v->from->offset;
 }
 
 ANN static inline void emit_struct_var(const Emitter emit, const Value v) {
   for(m_uint i = 0; i < v->type->size; i += SZ_INT) {
     const Instr set = emit_add_instr(emit, Reg2Reg);
-    set->m_val = -v->type->size + i;
-    set->m_val2 = -v->type->size + v->from->offset + i;
+    set->m_val2 = -v->type->size + i;
+    set->m_val = -v->type->size + v->from->offset + i;
   }
 }
 
 ANN static inline void emit_struct_data(const Emitter emit, const Value v, const uint emit_addr) {
-  if(emit_addr) {
-    emit_struct_addr(emit, v);
-    return;
+  const Instr instr = emit_kind(emit, v->type->size, emit_addr, structmember);
+  instr->m_val = v->from->offset;
+  if(!emit_addr) {
+    const Instr instr = emit_add_instr(emit, RegPush);
+    instr->m_val = v->type->size -SZ_INT;
   }
-  const Instr push = emit_add_instr(emit, RegPush);
-  push->m_val = v->type->size - v->from->owner_class->size;
-  if(v->from->offset)
-    emit_struct_var(emit, v);
 }
 
 ANN m_bool not_from_owner_class(const Env env, const Type t, const Value v, const loc_t pos);
@@ -260,7 +259,8 @@ OP_EMIT(opem_object_dot) {
     if(!GET_FLAG(t_base, struct))
       emit_member(emit, value, exp_getvar(exp_self(member)));
     else {
-      exp_setvar(member->base, exp_getvar(exp_self(member)));
+//      exp_setvar(member->base, exp_getvar(exp_self(member)));
+      exp_setvar(member->base, 1);
       CHECK_BO(emit_exp(emit, member->base))
       emit_struct_data(emit, value, exp_getvar(exp_self(member)));
     }
index 67e824cda6390383abff93f5d1a3ea990ee3752e..69e9137c96620eec4ea412f78e9a30affd23920f 100644 (file)
@@ -747,6 +747,8 @@ ANN static Type check_lambda_call(const Env env, const Exp_Call *exp) {
 }
 
 ANN Type check_exp_call1(const Env env, const Exp_Call *exp) {
+  if(exp->func->exp_type == ae_exp_decl)
+    ERR_O(exp_self(exp)->pos, _("It makes no sense to call a function pointer at declaration"))
   CHECK_OO(check_exp(env, exp->func))
   if(isa(exp->func->info->type, env->gwion->type[et_function]) < 0) {
     // use func flag?
index 1624695ea4e32499ea403b41943a36cf902404ea..72898b027cc3fdd86a40ec5467a6181d01e472c3 100644 (file)
@@ -501,7 +501,7 @@ ANN2(1,2) m_bool scan2_fdef_std(const Env env, const Func_Def f, const Value ove
 }
 
 ANN m_bool scan2_fdef(const Env env, const Func_Def f) {
-  const Value overload = nspc_lookup_value2(env->curr, f->base->xid);
+  const Value overload = nspc_lookup_value2(env->curr, f->base->xid); // try0
   if(overload)
     CHECK_BB(scan2_func_def_overload(env, f, overload))
   return (!tmpl_base(f->base->tmpl) ? scan2_fdef_std : scan2_fdef_tmpl)(env, f, overload);
index f9207a296e89689d7977a5dc568ece15357e5f4b..3e65d43f931f0419a7e63f117a964db71e2b3b8a 100644 (file)
@@ -291,7 +291,7 @@ ANN void vm_run(const VM* vm) { // lgtm [cpp/use-of-goto]
     &&pushnow,
     &&baseint, &&basefloat, &&baseother, &&baseaddr,
     &&regtoreg, &&regtoregaddr, &&regtoregderef,
-    &&structmember, &&structmemberaddr,
+    &&structmember, &&structmemberfloat, &&structmemberother, &&structmemberaddr,
     &&memsetimm,
     &&regpushme, &&regpushmaybe,
     &&funcreturn,
@@ -332,7 +332,7 @@ ANN void vm_run(const VM* vm) { // lgtm [cpp/use-of-goto]
     &&staticint, &&staticfloat, &&staticother,
     &&dotfunc, &&dotstaticfunc, &&pushstaticcode,
     &&gcini, &&gcadd, &&gcend,
-    &&gacktype, &&gackend, &&gack, &&noop, &&regpushimm, &&other, &&eoc
+    &&gacktype, &&gackend, &&gack, &&noop, &&eoc, &&other, &&regpushimm
   };
   const Shreduler s = vm->shreduler;
   register VM_Shred shred;
@@ -428,10 +428,16 @@ regtoregderef:
   memcpy(*(m_bit**)(reg - SZ_INT), *(m_bit**)(reg + (m_int)VAL), VAL2);
   DISPATCH()
 structmember:
-  *(m_bit**)(reg-SZ_INT) =  *(m_bit**)(*(m_bit**)(reg-SZ_INT) + (m_int)VAL2);
+  *(m_bit**)(reg-SZ_INT) =  *(m_bit**)(*(m_bit**)(reg-SZ_INT) + (m_int)VAL);
+  DISPATCH()
+structmemberfloat:
+  *(m_bit**)(reg-SZ_INT) =  *(m_bit**)(*(m_bit**)(reg-SZ_INT) + (m_int)VAL);
+  DISPATCH()
+structmemberother:
+  *(m_bit**)(reg-SZ_INT) =  *(m_bit**)(*(m_bit**)(reg-SZ_INT) + (m_int)VAL);
   DISPATCH()
 structmemberaddr:
-  *(m_bit**)(reg-SZ_INT) =  &*(*(m_bit**)(reg-SZ_INT) + (m_int)VAL2);
+  *(m_bit**)(reg-SZ_INT) =  &*(*(m_bit**)(reg-SZ_INT) + (m_int)VAL);
   DISPATCH()
 memsetimm:
   *(m_uint*)(mem+VAL) = VAL2;
index e2b8f6c3ebc9594851b47384abc8e57c03e8e634..f571fe8bd40651bfe9cd1a611488eaf182e57813 100644 (file)
@@ -51,6 +51,7 @@ ANN static m_bit* tobytecode(MemPool p, const VM_Code code) {
       memcpy(ptr + i*BYTECODE_SZ, instr, BYTECODE_SZ);
     else {
       *(m_bit*)(ptr + (i*BYTECODE_SZ)) = instr->opcode;
+//      *(m_bit*)(ptr + (i*BYTECODE_SZ)) = eOP_MAX;
       *(Instr*)(ptr + (i*BYTECODE_SZ) + SZ_INT) = instr;
       *(f_instr*)(ptr + (i*BYTECODE_SZ) + SZ_INT*2) = instr->execute;
     }