]> Nishi Git Mirror - gwion.git/commitdiff
On ctor/and/stuff: hahabutbetter
authorfennecdjay <fennecdjay@gmail.com>
Fri, 6 Jan 2023 02:07:31 +0000 (03:07 +0100)
committerfennecdjay <fennecdjay@gmail.com>
Fri, 6 Jan 2023 02:07:31 +0000 (03:07 +0100)
14 files changed:
1  2 
include/env/func.h
include/env/nspc.h
include/env/type.h
include/env/value.h
include/vm.h
src/emit/emit.c
src/env/value.c
src/lib/closure.c
src/lib/lib_class.c
src/lib/ref.c
src/parse/check.c
src/parse/operator.c
src/parse/scan1.c
src/vm/vm.c

index 7f3a742511ee288bc0d64ee55b7db7425a6665e7,7f3a742511ee288bc0d64ee55b7db7425a6665e7..d0fa07248e704662a053a8f8c5db10202426fbc6
@@@ -17,6 -17,6 +17,7 @@@ struct Func_ 
    Value            value_ref;
    Func             next;
    m_str            name;
++  uint32_t         wait;
    float            inline_mult;
    uint16_t         weight;  // used to mark gack use in scan1
    uint16_t         memoize; // used to mark return in scan1
index 63e1b8b7a35815783f3c72c4fc59e7bcaff692e4,63e1b8b7a35815783f3c72c4fc59e7bcaff692e4..e63fc13131641aa286621647b7e0773e39fd945d
@@@ -18,7 -18,7 +18,7 @@@ struct Nspc_ 
    m_str             name;
    NspcInfo       *info;
    uint16_t       offset;
--  uint16_t          ref;
++  uint16_t       ref;
    uint16_t       class_data_size;
  };
  
index d6cb26f94c667687ce6a7492fb74344059c8137f,d6cb26f94c667687ce6a7492fb74344059c8137f..85165b2fe247ddc0d49438515553dce83c5601c9
@@@ -51,7 -51,7 +51,9 @@@ struct Type_ 
    uint64_t          size;
    uint64_t          actual_size;
    struct Vector_    effects; // pre-ctor effects
--  uint32_t            array_depth;
++//  struct MP_Vector  *wait;
++  uint32_t wait;
++  uint32_t          array_depth;
    uint16_t          ref;
    uint16_t          weight;
    ae_flag           flag;
index 1e89694f0f823ab6a9ac74097875e003f76fe74d,1e89694f0f823ab6a9ac74097875e003f76fe74d..67d24b397ca5dafbeaadb84420c210829714d75a
@@@ -34,6 -34,6 +34,7 @@@ struct Value_ 
    Type               type;
    m_str              name;
    ValueFrom *from;
++  MP_Vector *used_by; // list of functions using this global
    union value_data   d;
    uint16_t           ref;
    ae_flag            flag;
diff --cc include/vm.h
index 6ef06b77597779956afa97cc10cad070457b9863,6ef06b77597779956afa97cc10cad070457b9863..395c737806e78525f028da08ad329690cc4ad83a
@@@ -18,6 -18,6 +18,7 @@@ struct VM_Code_ 
    m_str            name;
    struct Map_      handlers;
    struct M_Vector_ live_values;
++  uint32_t wait;
    uint16_t         stack_depth;
    uint16_t         ref;
  //  bool             is_prepared;
diff --cc src/emit/emit.c
index 7838adcd38933c36c2003fb824fad930d170c5e8,7838adcd38933c36c2003fb824fad930d170c5e8..100c65140b71cd1c63aa0f220ab0760028247922
@@@ -223,6 -223,6 +223,7 @@@ ANEW static Code *new_code(const Emitte
  }
  
  ANN static void free_code(MemPool p, Code *code) {
++// we should use instr destructors
    if(code->instr.ptr) vector_release(&code->instr);
    vector_release(&code->stack_break);
    vector_release(&code->stack_cont);
@@@ -438,7 -438,7 +439,8 @@@ m_bool emit_instantiate_object(const Em
                                        is_ref));
      return GW_OK;
    } else if (!is_ref) {
--    if(!tflag(type, tflag_typedef) || isa(type, emit->gwion->type[et_closure]) > 0) {
++    if(!tflag(type, tflag_typedef) || isa(type, emit->gwion->type[et_closure]) > 0 ||
++       tflag(type, tflag_union)) {
        const Instr instr = emit_add_instr(emit, ObjectInstantiate);
        instr->m_val2     = (m_uint)type;
      } // maybe we should instantiate the first actual type
@@@ -474,6 -474,6 +476,12 @@@ ANN static m_bool emit_symbol_builtin(c
  
  ANN static m_bool _emit_symbol(const Emitter emit, const Symbol *data) {
    const Value v = prim_self(data)->value;
++
++//else
++if(emit->env->class_def && safe_vflag(v, vflag_fglobal) && !emit->env->scope->depth) {
++emit->env->class_def->wait--;
++printf("=> %s\n", s_name(*data));
++  }
    if (is_class(emit->gwion, v->type)) {
      emit_pushimm(emit, (m_uint)actual_type(emit->gwion, v->type));
      return GW_OK;
@@@ -529,6 -529,6 +537,12 @@@ ANN static VM_Code finalyze(const Emitt
    return code;
  }
  
++ANN static VM_Code finalyze_func(const Emitter emit, const f_instr exec, const Func f) {
++  const VM_Code code = finalyze(emit, exec);
++  code->wait = f->wait;
++  return code;
++}
++
  ANN static inline m_uint exp_size(const Exp e) {
    if (exp_getvar(e)) return SZ_INT;
    const Type type = e->cast_to ?: e->type;
@@@ -806,6 -806,6 +820,7 @@@ ANN static void emit_gack_type(const Em
  
  ANN /*static*/ m_bool emit_interp(const Emitter emit, const Exp exp) {
    emit_pushimm(emit, 0);
++  emit_local(emit, emit->gwion->type[et_int]);
    Exp e = exp, next = NULL;
    do {
      next    = e->next;
@@@ -876,6 -876,6 +891,7 @@@ ANN static m_bool emit_prim_locale(cons
    vm_run(emit->gwion->vm);
    emit->gwion->vm->bbq->is_running = true;
    const m_float ret = *(m_float*)shred->reg;
++  release(shred->info->me, shred);
    if(ret == -1.0)
      ERR_B(prim_pos(id), "error in locale");
    const Instr instr = emit_add_instr(emit, RegPushImm2);
@@@ -994,6 -994,6 +1010,14 @@@ ANN void unset_local(const Emitter emit
    }
  }
  
++static INSTR(UsedBy) {
++  const MP_Vector *v =(MP_Vector*)instr->m_val;
++  for(uint32_t i = 0; i < v->len; i++) {
++    const Func f = *mp_vector_at(v, Func, i);
++    f->code->wait--;
++  }
++}
++
  ANN static m_bool emit_exp_decl_non_static(const Emitter   emit,
                                             const Exp_Decl *decl,
                                             const Var_Decl *var_decl,
    f_instr *exec = (f_instr *)allocmember;
    if (!emit->env->scope->depth) emit_debug(emit, v);
    if (!vflag(v, vflag_member)) {
++if(v->used_by) { // maybe later
++  const Instr instr = emit_add_instr(emit, UsedBy);
++  instr->m_val = (m_uint)v->used_by;
++}
      v->from->offset = decl_non_static_offset(emit, decl, type);
      exec            = (f_instr *)(allocword);
      if (GET_FLAG(v, late)) { // ref or emit_var ?
@@@ -1051,7 -1051,7 +1079,7 @@@ ANN static m_bool emit_exp_decl_global(
    if (type->size > SZ_INT)
      v->d.ptr = mp_calloc2(emit->gwion->mp, v->type->size);
    emit_dotstatic(emit, (m_uint)&v->d.ptr, v->type->size, !struct_ctor(v) ? emit_addr : 1);
--  set_vflag(v, vflag_direct); // mpalloc
++//  set_vflag(v, vflag_direct); // mpalloc // set in check.c
    if (is_obj && !is_ref) {
      const Instr assign = emit_add_instr(emit, Assign);
      assign->m_val      = emit_var;
@@@ -1122,13 -1122,13 +1150,15 @@@ ANN /*static */ m_bool emit_exp_decl(co
    const Type t = decl->type;
    if(decl->args && !strncmp(decl->args->type->name, "partial:", 8))
      ERR_B(decl->args->pos, "unresolved partial");
++//  if(t->wait) exit(3);
++  if(t->wait) { puts(t->name); puts(decl->vd.value->name); /*exit(3); */}
    CHECK_BB(ensure_emit(emit, t));
    const m_bool global = GET_FLAG(decl->td, global);
    const m_uint scope =
        !global ? emit->env->scope->depth : emit_push_global(emit);
    const m_bool ret = emit_decl(emit, decl);
    if (global) emit_pop(emit, scope);
--  if(isa(t, emit->gwion->type[et_object]) > 0 && emit->status.in_return && GET_FLAG(decl->vd.value, late))
++  if(emit->status.in_return && GET_FLAG(decl->vd.value, late) && isa(t, emit->gwion->type[et_object]) > 0)
      emit_add_instr(emit, GWOP_EXCEPT);
    return ret;
  }
@@@ -1329,7 -1329,7 +1359,6 @@@ ANN static m_bool _emit_exp_call(const 
                              .pos  = exp_self(call)->pos};
      CHECK_BB(op_emit(emit, &opi));
    }
--
    const Func f = t->info->func;
    if(unlikely(is_new_struct(f, exp_self(call)->type)))
      emit_new_struct(emit, call);
@@@ -1388,9 -1388,9 +1417,6 @@@ ANN static m_bool emit_exp_binary(cons
    const Exp rhs = bin->rhs;
    CHECK_BB(emit_exp_pop_next(emit, lhs));
    CHECK_BB(emit_exp_pop_next(emit, rhs));
--  //  const m_int size = exp_size(rhs);
--  //  emit_exp_addref1(emit, lhs, -exp_size(lhs) - size);
--  //  emit_exp_addref1(emit, rhs, -size);
    struct Op_Import opi = {.op   = bin->op,
                            .lhs  = lhs->type,
                            .rhs  = rhs->type,
@@@ -1623,7 -1623,7 +1649,14 @@@ ANN m_bool emit_exp_call1(const Emitte
    if(unlikely(fflag(f, fflag_fptr))) emit_fptr_call(emit, f);
    else if (unlikely(!f->code && emit->env->func != f)) {
      if (fflag(f, fflag_tmpl)) CHECK_BB(emit_template_code(emit, f));
--    else CHECK_BB(emit_ensure_func(emit, f));
++    else //if(is_new(f->def))//if(tflag(f->value_ref->type, tflag_ftmpl))
++{
++const Type t = f->value_ref->from->owner_class;
++if(t && (!emit->env->curr || isa(t, emit->env->class_def) < 0))
++//!is_new(f->def) || f->value_ref->from->owner_class->array_depth)
++//if(f->value_ref->from->owner_class->array_depth)
++CHECK_BB(emit_ensure_func(emit, f));
++}
    } else if(is_static)
      push_func_code(emit, f);
    call_finish(emit, f, is_static);
@@@ -2672,18 -2672,18 +2705,19 @@@ ANN static m_bool emit_func_def_return(
  }
  
  ANN static VM_Code emit_internal(const Emitter emit, const Func f) {
++// use wait everywhere
    if (f->def->base->xid == insert_symbol("@dtor")) {
--    emit->env->class_def->nspc->dtor = f->code = finalyze(emit, DTOR_EOC);
++    emit->env->class_def->nspc->dtor = f->code = finalyze_func(emit, DTOR_EOC, f);
      vmcode_addref(f->code);
      return f->code;
    } else if (f->def->base->xid == insert_symbol("@gack")) {
      emit_regmove(emit, -SZ_INT - f->value_ref->from->owner_class->size);
      const Instr instr                       = emit_add_instr(emit, RegPushMem);
      instr->m_val                            = SZ_INT;
--    f->code                                 = finalyze(emit, FuncReturn);
++    f->code                                 = finalyze_func(emit, FuncReturn, f);
      return emit->env->class_def->info->gack = f->code;
    }
--  return finalyze(emit, FuncReturn);
++  return finalyze_func(emit, FuncReturn, f);
  }
  
  ANN static inline VM_Code _emit_func_def_code(const Emitter emit,
        instr->m_val2 = t->size;
      }
    }
--  return !fbflag(func->def->base, fbflag_internal) ? finalyze(emit, FuncReturn)
++//  return !fbflag(func->def->base, fbflag_internal) ? finalyze(emit, FuncReturn)
++//                                                   : emit_internal(emit, func);
++  const VM_Code code = !fbflag(func->def->base, fbflag_internal) ? finalyze_func(emit, FuncReturn, func)
                                                     : emit_internal(emit, func);
++  code->wait = func->wait;
++  return code;
  }
  
  ANN static VM_Code emit_func_def_code(const Emitter emit, const Func func) {
diff --cc src/env/value.c
index 0c06360d5bf3e13b9c1d44aca2855626d5d35338,0c06360d5bf3e13b9c1d44aca2855626d5d35338..e5b9691320d4827badb6495e22510499c3acf683
@@@ -10,6 -10,6 +10,7 @@@ ANN void free_value(Value a, Gwion gwio
      _mp_free(gwion->mp, t->size, a->d.ptr);
    else if (is_class(gwion, t))
      type_remref(t, gwion);
++  if(a->used_by) free_mp_vector(gwion->mp, Func, a->used_by);
    mp_free(gwion->mp, ValueFrom, a->from);
    mp_free(gwion->mp, Value, a);
  }
index b747f0a3e168afdf081a619b025f75c33600f59b,b747f0a3e168afdf081a619b025f75c33600f59b..ed4b4e98feb7ee3fa166aeef57f0663d2320af55
@@@ -51,9 -51,9 +51,9 @@@ ANN static Exp uncurry(const Env env, c
  }
  
  ANN static Type mk_call(const Env env, const Exp e, const Exp func, const Exp args) {
--  Exp_Call    call = {.func = func, .args = args };
--  e->exp_type      = ae_exp_call;
--  memcpy(&e->d.exp_call, &call, sizeof(Exp_Call));
++  Exp_Call call = {.func = func, .args = args };
++  e->exp_type   = ae_exp_call;
++  e->d.exp_call = call;
    return check_exp_call1(env, &e->d.exp_call) ?: env->gwion->type[et_error];
  }
  
index 6aa7df5a68ff2b0f37eab611c6fdd9b172ff858b,6aa7df5a68ff2b0f37eab611c6fdd9b172ff858b..2def08a051415a2a2aeb2d68bda5c7f83ddce568
@@@ -37,20 -37,20 +37,21 @@@ static OP_CHECK(opck_basic_ctor) 
  // change to *no know constructor for {+G}%s{0}*?
    ERR_N(call->func->pos, _("can't call a non-callable value"));
  }
--
++/*
  static OP_EMIT(opem_implicit_class) {
    struct Implicit *imp = (struct Implicit*)data;
    const Type t = actual_type(emit->gwion, imp->e->type);
    emit_pushimm(emit, map_size(&t->nspc->info->value->map));
--  return GW_OK; emit_exp(emit, imp->e);
++  return GW_OK;
  }
  
  static OP_CHECK(opck_implicit_class) {
    struct Implicit *imp = (struct Implicit*)data;
    const Type t = actual_type(env->gwion, imp->e->type);
++  if(isa(t, env->gwion->type[et_enum]) > 0) return imp->e->type;
    return env->gwion->type[et_error];
  }
--
++*/
  GWION_IMPORT(class) {
  
    gwidoc(gwi, "Operators class types.");
    GWI_BB(gwi_oper_ini(gwi, NULL, (m_str)OP_ANY_TYPE, NULL))
    GWI_BB(gwi_oper_add(gwi, opck_basic_ctor))
    GWI_BB(gwi_oper_end(gwi, "@ctor", NULL))
--
++/*
    gwidoc(gwi, "Allow enum for array size");
    GWI_BB(gwi_oper_ini(gwi, "Class", "int", NULL))
    GWI_BB(gwi_oper_add(gwi, opck_implicit_class))
    GWI_BB(gwi_oper_emi(gwi, opem_implicit_class))
    GWI_BB(gwi_oper_end(gwi, "@implicit", NULL))
--
++*/
    return GW_OK;
  }
diff --cc src/lib/ref.c
index 6f75b68d19374ee9bd5efd92ec83e1af52992741,6f75b68d19374ee9bd5efd92ec83e1af52992741..521822b83d961e321470b38570838828970cde20
@@@ -93,8 -93,8 +93,7 @@@ static OP_EMIT(opem_ref_contract_simila
    emit_regmove(emit, -imp->e->type->size);
    exp_setvar(imp->e, true);
    imp->e->cast_to = NULL;
--  emit_exp(emit, imp->e);
--  return GW_OK;
++  return emit_exp(emit, imp->e);
  }
  
  ANN static void base2ref(Env env, const Type lhs, const Type rhs) {
index 6089c2817b8152af935cde30ebea3c61082adec3,6089c2817b8152af935cde30ebea3c61082adec3..90c76eda6d17b828cedf558bfa8183152be3d318
@@@ -304,9 -304,9 +304,13 @@@ ANN static Value check_non_res_value(co
    const Symbol var   = *data;
    const Value  value = get_value(env, var);
    if (env->class_def) {
--    if (value && value->from->owner_class)
--      CHECK_BO(
--          not_from_owner_class(env, env->class_def, value, prim_pos(data)));
++    if (value) {
++      if(value->from->owner_class)
++      CHECK_BO(not_from_owner_class(env,
++        env->class_def, value, prim_pos(data)));
++      else if(safe_vflag(value, vflag_fglobal) && !env->scope->depth)
++        env->class_def->wait++;
++    }
      const Value v = value ?: find_value(env->class_def, var);
      if (v) {
        if (env->func && GET_FLAG(env->func->def->base, static) &&
@@@ -388,7 -388,7 +392,29 @@@ ANN static Type prim_id_non_res(const E
    prim_self(data)->value = v;
    if (v->from->owner_class) return prim_owned(env, data);
    if (GET_FLAG(v, const)) exp_setmeta(prim_exp(data), 1);
--  if (env->func) {
++
++  if (env->func && strcmp(env->func->name, "in spork")) {
++    if(vflag(v, vflag_fglobal) /*&& !vflag(v, vflag_builtin) */&& !is_func(env->gwion, v->type)) {
++      if (!v->used_by) {
++        v->used_by = new_mp_vector(env->gwion->mp, Func, 1);
++        mp_vector_set(v->used_by, Func, 0, env->func);
++        env->func->wait++;
++      } else {
++        bool found = false;
++        for(uint32_t i = 0; i < v->used_by->len; i++) {
++          const Func f = *mp_vector_at(v->used_by, Func, i);
++          if(f == env->func) {
++            found = true;
++            break;
++          }
++        }
++        if(!found) {
++          env->func->wait++;
++          mp_vector_add(env->gwion->mp, &v->used_by, Func, env->func);
++        }
++      }
++    }
++
      if (!GET_FLAG(v, const) && v->from->owner)
        unset_fflag(env->func, fflag_pure);
      if (fbflag(env->func->def->base, fbflag_lambda))
@@@ -886,7 -886,7 +912,8 @@@ ANN m_bool func_check(const Env env, Ex
                            .rhs  = t,
                            .pos  = e->pos,
                            .data = (uintptr_t)e};
--  CHECK_NB(op_check(env, &opi)); // doesn't really return NULL
++  if(op_get(env, &opi))
++    CHECK_OB(op_check(env, &opi));
    if (e->exp_type != ae_exp_call) return 0;
    return e->type != env->gwion->type[et_error] ? GW_OK : GW_ERROR;
  }
index d6c21521cb2423038af40fb57ef40b9644d709f2,d6c21521cb2423038af40fb57ef40b9644d709f2..23e9db1297c9939a71bcd9c3aa2e3d45a0260d46
@@@ -305,6 -305,6 +305,12 @@@ ANN static Type chuck_rewrite(const En
    char c[len - 1];
    strncpy(c, op, len - 2);
    c[len - 2] = '\0';
++  // are there other expressions that would need such a test?
++  if(!strcmp(c, "$")) {
++    env_err(env, opi->pos, "can't rewrite cast operations");
++    env_set_error(env,  true);
++    return NULL;
++  }
    const Exp bin = new_exp_binary(env->gwion->mp, lhs, insert_symbol(env->gwion->st, c), call, exp_self(base)->pos);
    base->lhs = bin;
    base->op = insert_symbol(env->gwion->st, "=>");
index a537a7da4073ac9920bbc1d8d35b9e3cb0463716,a537a7da4073ac9920bbc1d8d35b9e3cb0463716..4f6602ffd83f99b6733158c441cd17a2b509c9a5
@@@ -37,17 -37,17 +37,15 @@@ ANN static m_bool check_global(const En
    const ValueFrom *from = t->info->value->from;
    if(from->owner_class && isa(from->owner_class, env->class_def) > 0)
      return true;
--  if(!GET_FLAG(t, global) && !from_global_nspc(env, from->owner)) {
--    if(from->owner_class && type_global(env, from->owner_class))
++  if(from_global_nspc(env, from->owner) ||
++    (from->owner_class && type_global(env, from->owner_class)))
        return true;
--    gwerr_basic("can't use non-global type in a global class", NULL, NULL, env->name, pos, 0);
--    gwerr_secondary_from("not declared global", from);
--    const ValueFrom *ownerFrom = env->class_def->info->value->from;
--    gwerr_secondary_from("is global", ownerFrom);
--    env_set_error(env, true);
--    return false;
--  }
--  return true;
++  gwerr_basic("can't use non-global type in a global class", NULL, NULL, env->name, pos, 0);
++  gwerr_secondary_from("not declared global", from);
++  const ValueFrom *ownerFrom = env->class_def->info->value->from;
++  gwerr_secondary_from("is global", ownerFrom);
++  env_set_error(env, true);
++  return false;
  }
  
  ANN static Type scan1_type(const Env env, Type_Decl *td) {
@@@ -81,10 -81,10 +79,11 @@@ ANN static Type scan1_exp_decl_type(con
  static inline m_bool scan1_defined(const Env env, const Var_Decl *var) {
    if (var->value) // from an auto declaration
      return GW_OK;
--  if (((!env->class_def || !GET_FLAG(env->class_def, final) ||
++  const Value v = ((!env->class_def || !GET_FLAG(env->class_def, final) ||
          env->scope->depth)
             ? nspc_lookup_value1
--           : nspc_lookup_value2)(env->curr, var->xid))
++           : nspc_lookup_value2)(env->curr, var->xid);
++  if(v && (!v->from->owner_class || isa(env->class_def, v->from->owner_class) > 0))
      ERR_B(var->pos,
            _("variable %s has already been defined in the same scope..."),
            s_name(var->xid))
diff --cc src/vm/vm.c
index e3c5c3e3228fef749bfec3e333b848813b81b595,e3c5c3e3228fef749bfec3e333b848813b81b595..0df19eff37e453f4c51be52f817e83882d78801c
@@@ -912,6 -912,6 +912,11 @@@ vm_prepare(const VM *vm, m_bit *prepare
        DISPATCH();
      setcode:
        a.code = *(VM_Code *)(reg - SZ_INT);
++if(a.code->wait) {
++handle(shred, "FuncWithGlobalUninit");
++break;
++}
++
        if (!a.code->builtin) {
          register const uint push =
              *(m_uint *)reg /*+ code->stack_depth*/ + sizeof(frame_t);