]> Nishi Git Mirror - gwion.git/commitdiff
:art: Improve function calling
authorJérémie Astor <fennecdjay@gmail.com>
Sun, 13 Jun 2021 09:54:39 +0000 (11:54 +0200)
committerJérémie Astor <fennecdjay@gmail.com>
Sun, 13 Jun 2021 09:54:39 +0000 (11:54 +0200)
15 files changed:
ast
plug
src/emit/emit.c
src/env/type.c
src/gwion.c
src/import/import_checker.c
src/import/import_enum.c
src/import/import_internals.c
src/import/import_special.c
src/import/import_tdef.c
src/lib/array.c
src/lib/object_op.c
src/parse/operator.c
src/parse/scan1.c
src/vm/vm.c

diff --git a/ast b/ast
index 269c530719fc73ae9427a01b379b184f2596911e..bbaaa66e1ecae79f4b48c45e433cba1709dba938 160000 (submodule)
--- a/ast
+++ b/ast
@@ -1 +1 @@
-Subproject commit 269c530719fc73ae9427a01b379b184f2596911e
+Subproject commit bbaaa66e1ecae79f4b48c45e433cba1709dba938
diff --git a/plug b/plug
index 98feefdb89f5cdcedd50e9f39b8ada210b02ab55..1144c836130b2016626c3bd761f23eef6f7b3f3c 160000 (submodule)
--- a/plug
+++ b/plug
@@ -1 +1 @@
-Subproject commit 98feefdb89f5cdcedd50e9f39b8ada210b02ab55
+Subproject commit 1144c836130b2016626c3bd761f23eef6f7b3f3c
index 526e4d9608d9f9386cca5ace22a571c3b73d01ab..1338094d380ccc9f5802f8c46b17768c863003d3 100644 (file)
@@ -152,12 +152,13 @@ ANN static void emit_struct_ctor(const Emitter emit, const Type type, const m_ui
   const Instr set_code = regseti(emit, (m_uint)type->nspc->dtor);
   set_code->m_val2 = SZ_INT;
   const m_uint code_offset = emit_code_offset(emit);
-  const Instr regset = regseti(emit, code_offset);
+  const Instr regset = regseti(emit, code_offset /*+ SZ_INT*/ /*+ sizeof(frame_t)*/);
   regset->m_val2 = SZ_INT *2;
   regpush(emit, SZ_INT *2);
   const Instr prelude = emit_add_instr(emit, SetCode);
-  prelude->m_val2 = 2;
   prelude->m_val = -SZ_INT*4;
+  prelude->udata.one = 2;
+//  prelude->udata.two = emit_code_offset(emit) + SZ_INT + sizeof(frame_t);
   const Instr next = emit_add_instr(emit, Overflow);
   next->m_val2 = code_offset;
   emit->code->frame->curr_offset -= SZ_INT;
@@ -385,12 +386,13 @@ ANN void emit_ext_ctor(const Emitter emit, const Type t) {
     instr->m_val = (m_uint)t;
   }
   const m_uint offset = emit_code_offset(emit);
-  const Instr regset = regseti(emit, offset);
+  const Instr regset = regseti(emit, offset /*+ SZ_INT */ /*+ sizeof(frame_t)*/);
   regset->m_val2 = SZ_INT *2;
   regpush(emit, SZ_INT*2);
   const Instr prelude = emit_add_instr(emit, SetCode);
-  prelude->m_val2 = 2;
   prelude->m_val = -SZ_INT * 2;
+  prelude->udata.one = 2;
+//  prelude->udata.two = emit_code_offset(emit) + SZ_INT + sizeof(frame_t);
   emit_add_instr(emit, Reg2Mem);
   const Instr next = emit_add_instr(emit, Overflow);
   next->m_val2 = offset;
@@ -1079,7 +1081,7 @@ ANN static m_bool _emit_exp_call(const Emitter emit, const Exp_Call* exp_call) {
   else
     CHECK_BB(emit_func_args(emit, exp_call));
   if(isa(t, emit->gwion->type[et_function]) > 0)
-    CHECK_BB(emit_exp_call1(emit, t->info->func));
+    CHECK_BB(emit_exp_call1(emit, t->info->func, is_static_call(emit, exp_call->func)));
   else {
     struct Op_Import opi = { .op=insert_symbol("@ctor"), .rhs=t,
       .data=(uintptr_t)exp_call, .pos=exp_self(exp_call)->pos };
@@ -1246,21 +1248,21 @@ ANN static void tmpl_prelude(const Emitter emit, const Func f) {
   gtmpl->m_val2 = strlen(c);
 }
 
-ANN static Instr get_prelude(const Emitter emit, const Func f) {
+ANN static Instr get_prelude(const Emitter emit, const Func f, const bool is_static) {
   const Type t = actual_type(emit->gwion, f->value_ref->type);
   const bool fp = is_fptr(emit->gwion, t);
   if(is_fptr(emit->gwion, t)) {
     if(f->def->base->tmpl)
       tmpl_prelude(emit, f);
   }
-  if(fp || f != emit->env->func || f->value_ref->from->owner_class || strstr(emit->code->name, "ork~")) {
+  if(fp || f != emit->env->func || !is_static || strstr(emit->code->name, "ork~")) {
     const Instr instr = emit_add_instr(emit, SetCode);
-    instr->m_val2 = 1;
+    instr->udata.one = 1;
     return instr;
   }
   const Instr instr = emit_add_instr(emit, Recurs);
-  instr->m_val2 = 1;
   instr->m_val = SZ_INT;
+  instr->udata.one = 1;
   return instr;
 }
 
@@ -1315,9 +1317,10 @@ ANN static m_bool me_arg(MemoizeEmitter *me) {
   return GW_OK;
 }
 
-ANN static Instr emit_call(const Emitter emit, const Func f) {
-  const Instr prelude = get_prelude(emit, f);
+ANN static Instr emit_call(const Emitter emit, const Func f, const bool is_static) {
+  const Instr prelude = get_prelude(emit, f, is_static);
   prelude->m_val += -f->def->stack_depth - SZ_INT;
+  prelude->udata.two = emit_code_offset(emit) + f->def->stack_depth + sizeof(frame_t);
   const m_uint member = vflag(f->value_ref, vflag_member) ? SZ_INT : 0;
   if(member) {
     const Instr instr = emit_add_instr(emit, Reg2Mem);
@@ -1334,7 +1337,7 @@ ANN static Instr emit_call(const Emitter emit, const Func f) {
   return emit_add_instr(emit, Overflow);
 }
 
-ANN m_bool emit_exp_call1(const Emitter emit, const Func f) {
+ANN m_bool emit_exp_call1(const Emitter emit, const Func f, const bool is_static) {
   const m_uint this_offset = emit->this_offset;
   const m_uint vararg_offset = emit->vararg_offset;
   emit->this_offset = 0;
@@ -1399,8 +1402,9 @@ ANN m_bool emit_exp_call1(const Emitter emit, const Func f) {
     }
   }
   const m_uint offset = emit_code_offset(emit);
-  regseti(emit, offset);
-  const Instr instr = emit_call(emit, f);
+  if(f != emit->env->func || !is_static)
+    regseti(emit, offset /*+ f->def->stack_depth + */ /*+ sizeof(frame_t)*/);
+  const Instr instr = emit_call(emit, f, is_static);
   instr->m_val = f->def->base->ret_type->size;
   instr->m_val2 = offset;
   emit->this_offset = this_offset;
@@ -1474,7 +1478,7 @@ ANN static m_bool spork_prepare_code(const Emitter emit, const struct Sporker *s
 ANN static m_bool spork_prepare_func(const Emitter emit, const struct Sporker *sp) {
   push_spork_code(emit, sp->is_spork ? SPORK_FUNC_PREFIX : FORK_CODE_PREFIX, sp->exp->pos);
   const Type t = actual_type(emit->gwion, sp->exp->d.exp_call.func->type);
-  return emit_exp_call1(emit, t->info->func);
+  return emit_exp_call1(emit, t->info->func, false);
 }
 
 ANN static VM_Code spork_prepare(const Emitter emit, const struct Sporker *sp) {
index 24b8a7a913b62fb6bf5666d047564d7ed8fd238f..2ac183fb6454543e67cdfbd30a8e9705d7c40f5d 100644 (file)
@@ -83,11 +83,12 @@ ANN Type array_base(Type type) {
 ANN /*static */Symbol array_sym(const Env env, const Type src, const m_uint depth) {
   if(src->array_depth == depth)
     return insert_symbol(src->name);
+  const m_uint total_depth = src->array_depth + depth;
   const Type t = array_base(src);
   size_t len = strlen(t->name);
-  char name[len + 2depth + 1];
+  char name[len + 2 * total_depth + 1];
   strcpy(name, t->name);
-  m_uint i = src->array_depth + depth + 1;
+  m_uint i = total_depth + 1;
   while(--i) {
     strcpy(name+len, "[]");
     len += 2;
index 0ab82621ddacc07e4ba713caffd9b04168acd32f..17b05f60b520d3b2df97dfa3bef2ea8d11ad8f22 100644 (file)
@@ -157,7 +157,7 @@ ANN void gwion_end(const Gwion gwion) {
 }
 
 ANN void env_error_footer(const Env env) {
-  if(env->class_def)
+  if(env->class_def && tflag(env->class_def, tflag_cdef))
     gwerr_secondary("in class", env->name, env->class_def->info->cdef->pos);
   if(env->func && env->func->def)
     gwerr_secondary("in function", env->name, env->func->def->base->pos);
index 85628e6665a1ea9053aa2b37c09dd68f4a1b3f01..45c297df547fc90f25ca2358e15d423d8a75527d 100644 (file)
@@ -314,6 +314,8 @@ ANN static m_bool _ac_run(const Gwion gwion, struct AC *const ac) {
     CHECK_BB(ac_num(gwion, ac, num));
     CHECK_BB(ac_exp(gwion, ac));
     const Exp exp = new_prim_int(gwion->mp, num, ac->pos);
+    // set type: otherwise could fail at emit time
+    exp->type = gwion->type[et_int];
     ac_add_exp(ac, exp);
   } else
     CHECK_BB(ac_noexp(gwion, ac));
index d1922c92739002b4b90362599b0eb78967e3ad41..499d61a0930d6e2a78c201a320a62e0641faf8d9 100644 (file)
@@ -99,6 +99,7 @@ ANN Type gwi_enum_end(const Gwi gwi) {
 }
 
 ANN void ck_clean_edef(MemPool mp, ImportCK *ck) {
+/*
   if(ck->tmpl)
     free_id_list(mp, ck->tmpl);
   if(ck->v.ptr) {
@@ -106,5 +107,6 @@ ANN void ck_clean_edef(MemPool mp, ImportCK *ck) {
       mp_free2(mp, SZ_INT, (m_uint*)vector_at(&ck->v, i));
     vector_release(&ck->v);
   }
+*/
 }
 
index 467184bd262447af0988ccc8408bc2f40b6ea11c..93f2587cf87a7c6a47bf4be6196a8f688794d22a 100644 (file)
@@ -35,8 +35,11 @@ ANN static m_bool run_with_doc(const Gwi gwi, m_bool (*f)(const Gwi)) {
   gwi->lint = &linter;
   return f(gwi);
 }
+
 ANN m_bool gwi_run(const Gwion gwion, m_bool (*f)(const Gwi)) {
   const m_str name = gwion->env->name;
+//  const Context ctx = gwion->env->context;
+//  gwion->env->context = NULL;
   OperCK oper = {};
   struct Gwi_ gwi = { .gwion=gwion, .oper=&oper };
   const m_bool ret = !gwion->data->cdoc ?
@@ -44,5 +47,6 @@ ANN m_bool gwi_run(const Gwion gwion, m_bool (*f)(const Gwi)) {
   if(ret < 0)
     gwi_reset(&gwi);
   gwion->env->name = name;
+//  gwion->env->context = ctx;
   return ret;
 }
index f1be4ebdbdd42d35fcb6cfd8585195c44f5fca32..c062929c7f70b73a4cd81ade5bbcf4f59ff4804f 100644 (file)
@@ -37,6 +37,7 @@ ANN void gwi_specialid(const Gwi gwi, const m_str id, const SpecialId spid) {
 
 ANN void gwi_set_loc(const Gwi gwi, const m_str file, const uint line) {
   gwi->loc.first.line = gwi->loc.last.line = line;
+  gwi->loc.first.column = 1; gwi->loc.last.column = 2;
   gwi->gwion->env->name = file;
 }
 
index 47ae799637e7ff2444baa8a268119ae8d0b395ea..f08323ccd408808f3b2dbbcb21a151ee68399e60 100644 (file)
@@ -38,7 +38,8 @@ ANN Type gwi_typedef_end(const Gwi gwi, const ae_flag flag) {
     lint_type_def(gwi->lint, tdef);
   }
   const Type t = tdef->type;
-  set_tflag(t, tflag_scan0 | tflag_scan1 | tflag_scan2 | tflag_check | tflag_emit);
+  if(ret > 0)
+    set_tflag(t, tflag_scan0 | tflag_scan1 | tflag_scan2 | tflag_check | tflag_emit);
   free_type_def(gwi->gwion->mp, tdef);
   ck_end(gwi);
   return ret > 0 ? t : NULL;
index 344f1f2cdaabc4f5ab06dc8189a66f276ff89415..d9852bb466eeb20738c1f28ffcf2e742c759a86b 100644 (file)
@@ -414,7 +414,7 @@ ANN static inline void _init(const VM_Shred shred,
   frame->code = shred->code;
   frame->offset = offset;
   frame->index = 0;
-  *(m_uint*)REG(SZ_INT) = offset;
+  *(m_uint*)REG(SZ_INT) = offset;// + sizeof(frame_t);// + shred->code->stack_depth;
   shred->code = (VM_Code)code;
   shred->pc = 0;
   shredule(shred->tick->shreduler, shred, 0);
@@ -422,7 +422,7 @@ ANN static inline void _init(const VM_Shred shred,
 
 ANN static inline void _next(const VM_Shred shred, const m_uint offset) {
   shred->pc = 0;
-  *(m_uint*)REG(0) = offset;
+  *(m_uint*)REG(0) = offset;// + sizeof(frame_t);
   POP_REG(shred, SZ_INT);
 }
 
@@ -711,7 +711,9 @@ ANN static void prepare_run(m_bit *const byte, const f_instr ini, const f_instr
   *(unsigned*)byte = eOP_MAX;
   *(f_instr*)(byte + SZ_INT*2) = ini;
   *(unsigned*)(byte+ BYTECODE_SZ) = eSetCode;
-  *(m_uint*)(byte + BYTECODE_SZ + SZ_INT*2) = 3;
+//  *(m_uint*)(byte + BYTECODE_SZ + SZ_INT*2) = 3;
+  *(uint16_t*)(byte + BYTECODE_SZ + SZ_INT*2) = 3;
+//  *(uint16_t*)(byte + BYTECODE_SZ + SZ_INT*2 + sizeof(uint16_t)) = sizeof(frame_t);
   *(unsigned*)(byte+ BYTECODE_SZ*2) = eOverflow;
   *(unsigned*)(byte+ BYTECODE_SZ*3) = eOP_MAX;
   *(f_instr*)(byte + BYTECODE_SZ*3 + SZ_INT*2) = end;
index 104d6532c3bf2dac74b804fbce6c422afc834003..05e15b44e9c586d236e57775f160cff9ead132e5 100644 (file)
@@ -98,14 +98,13 @@ ANN static void emit_member_func(const Emitter emit, const Exp_Dot* member) {
   const Func f = exp_self(member)->type->info->func;
   if(f->def->base->tmpl)
     emit_add_instr(emit, DotTmplVal);
-  else if(GET_FLAG(member->base->type, final) || is_class(emit->gwion, member->base->type) || member->base->exp_type == ae_exp_cast) {
+  else if(is_static_call(emit, exp_self(member))) {
+    if(f == emit->env->func)
+      return;
     const Instr func_i = emit_add_instr(emit, f->code ? RegPushImm : SetFunc);
     func_i->m_val = (m_uint)f->code ?: (m_uint)f;
     return;
-  }
-//  if(f->def->base->tmpl)
-//    emit_add_instr(emit, DotTmplVal);
-  else {
+  } else {
     if(tflag(member->base->type, tflag_struct)) {
       if(!GET_FLAG(f->def->base, static)) {
         exp_setvar(member->base, 1);
index 76fab568be4f4f2e03e5b7758a8570afeb710202..b1e20632764f56fea860955037c69bde7e309a54 100644 (file)
@@ -219,7 +219,7 @@ ANN static m_bool handle_instr(const Emitter emit, const M_Operator* mo) {
   if(mo->func) {
     const Instr push = emit_add_instr(emit, mo->func->code ? RegPushImm : SetFunc);
     push->m_val = ((m_uint)mo->func->code ?:(m_uint)mo->func);
-    CHECK_BB(emit_exp_call1(emit, mo->func));
+    CHECK_BB(emit_exp_call1(emit, mo->func, true));
     if(mo->func->def->base->xid == insert_symbol(emit->gwion->st, "@conditional"))
       emit_add_instr(emit, BranchEqInt);
     else if(mo->func->def->base->xid == insert_symbol(emit->gwion->st, "@unconditional"))
index 6fff9351937c3a49e065629e04efc24100fd50f5..ef20822c20761a29842c6b1052c37e1a6fb70bd7 100644 (file)
@@ -83,7 +83,7 @@ ANN static m_bool scan1_decl(const Env env, const Exp_Decl* decl) {
     if(var->array) {
       if(var->array->exp)
         CHECK_BB(scan1_exp(env, var->array->exp));
-      t = array_type(env, decl->type, var->array->depth);
+      CHECK_OB((t = array_type(env, decl->type, var->array->depth)));
     }
     if(GET_FLAG(array_base(t), abstract) && ((var->array && var->array->exp)
                                                   || (decl->td->array && decl->td->array->exp)))
index 37fb33e7344130934bd179272778e4e5af55fe6d..ae27350b8edb347c3c40f7558665ffc8d75cfaea 100644 (file)
@@ -41,7 +41,7 @@ uint32_t gw_rand(uint32_t s[2]) {
 }
 
 ANN static inline void shred_unwind(const VM_Shred shred) {
-  register struct frame_t *frame = &*(struct frame_t*)(shred->mem - sizeof(struct frame_t));
+  register frame_t *frame = &*(frame_t*)(shred->mem - sizeof(frame_t));
   shred->code = frame->code;
   shred->pc   = frame->pc;
   shred->mem -= frame->push;
@@ -549,7 +549,7 @@ regpushmaybe:
   DISPATCH();
 funcreturn:
 {
-  register struct frame_t frame = *(struct frame_t*)(mem - sizeof(struct frame_t));
+  register frame_t frame = *(frame_t*)(mem - sizeof(frame_t));
   bytecode = (code = frame.code)->bytecode;
   mem -= frame.push;
   PC_DISPATCH(frame.pc);
@@ -713,9 +713,9 @@ timeadv:
   break;
 recurs:
 {
-  register const uint push = *(m_uint*)reg + code->stack_depth + sizeof(struct frame_t);
+  register const uint push = UVAL2;
   mem += push;
-  *(struct frame_t*)(mem - sizeof(struct frame_t)) = (struct frame_t){.code=code,.pc=VAL2,.push=push};
+  *(frame_t*)(mem - sizeof(frame_t)) = (frame_t){.code=code,.pc=UVAL,.push=push};
   reg += (m_int)VAL;
   next = eFuncUsrEnd2;
 }
@@ -724,12 +724,12 @@ setcode:
 PRAGMA_PUSH()
   a.code = *(VM_Code*)(reg - SZ_INT);
   if(!a.code->builtin) {
-    register const uint push = *(m_uint*)reg + code->stack_depth + sizeof(struct frame_t);
+    register const uint push = *(m_uint*)reg + code->stack_depth + sizeof(frame_t);
     mem += push;
-    *(struct frame_t*)(mem - sizeof(struct frame_t)) = (struct frame_t){.code=code,.pc=PC+VAL2,.push=push};
+    *(frame_t*)(mem - sizeof(frame_t)) = (frame_t){ .code=code, .pc=PC+UVAL, .push=push };
     next = eFuncUsrEnd;
   } else {
-    mem += *(m_uint*)reg;
+    mem += *(m_uint*)reg /*- (code->stack_depth + */ /*- sizeof(frame_t)*/;
     next = eFuncMemberEnd;
   }
 PRAGMA_POP()