GCC Code Coverage Report
Directory: src/ Exec Total Coverage
File: src/lib/object.c Lines: 82 83 98.8 %
Date: 2020-10-03 11:19:27 Branches: 53 56 94.6 %

Line Branch Exec Source
1
#include <stdlib.h>
2
#include <string.h>
3
#include "gwion_util.h"
4
#include "gwion_ast.h"
5
#include "gwion_env.h"
6
#include "vm.h"
7
#include "gwion.h"
8
#include "instr.h"
9
#include "object.h"
10
#include "operator.h"
11
#include "import.h"
12
#include "emit.h"
13
#include "traverse.h"
14
#include "template.h"
15
#include "parse.h"
16
#include "specialid.h"
17
18
#include "gwi.h"
19
#include "gack.h"
20
21
#undef insert_symbol
22
40
ANN void exception(const VM_Shred shred, const m_str c) {
23
120
  gw_err("%s: shred[id=%" UINT_F ":%s], PC=[%" UINT_F "]\n",
24
120
          c, shred->tick->xid, shred->info->name, shred->pc - 1);
25
40
  vm_shred_exit(shred);
26
40
}
27
28
8840
M_Object new_object(MemPool p, const VM_Shred shred, const Type t) {
29
8840
  const M_Object a = mp_calloc(p, M_Object);
30
8840
  a->ref = 1;
31
8840
  a->type_ref = t;
32
8840
  if(t->nspc) {
33
7203
    a->vtable = &t->nspc->info->vtable;
34
7203
    if(t->nspc->info->offset)
35
7151
      a->data = (m_bit*)_mp_calloc(p, t->nspc->info->offset);
36
  }
37
8840
  if(shred)
38
1876
    vector_add(&shred->gc, (vtype)a);
39
8840
  return a;
40
}
41
42
27
M_Object new_string(MemPool p, const VM_Shred shred, const m_str str) {
43
27
  const M_Object o = new_object(p, shred, shred->info->vm->gwion->type[et_string]);
44
27
  STRING(o) = s_name(insert_symbol(shred->info->vm->gwion->st, str));
45
27
  return o;
46
}
47
48
244
M_Object new_string2(const struct Gwion_ *gwion, const VM_Shred shred, const m_str str) {
49
244
  const M_Object o = new_object(gwion->mp, shred, gwion->type[et_string]);
50
244
  STRING(o) = str;
51
244
  return o;
52
}
53
54
7
ANN static void handle_dtor(const M_Object o, const VM_Shred shred) {
55
7
  const VM_Shred sh = new_vm_shred(shred->info->mp, o->type_ref->nspc->dtor);
56
7
  ADD_REF(o->type_ref->nspc->dtor);
57
7
  sh->base = shred->base;
58
7
  *(M_Object*)sh->mem = o;
59
7
  vm_add_shred(shred->info->vm, sh);
60
7
  ++sh->info->me->ref;
61
7
}
62
63
__attribute__((hot))
64
7856
ANN void __release(const M_Object o, const VM_Shred shred) {
65
7856
  MemPool p = shred->info->mp;
66
7856
  Type t = o->type_ref;
67
  do {
68

22491
    if(!t->nspc || is_special(t))
69
15707
      continue;
70
6784
    struct scope_iter iter = { t->nspc->info->value, 0, 0 };\
71
    Value v;
72
81350
    while(scope_iter(&iter, &v) > 0) {
73

134504
      if(!GET_FLAG(v, static) && !GET_FLAG(v, pure) &&
74
66722
          isa(v->type, shred->info->vm->gwion->type[et_object]) > 0)
75
26
        release(*(M_Object*)(o->data + v->from->offset), shred);
76

67759
      else if(GET_FLAG(v->type, struct) &&
77

5
            !GET_FLAG(v, static) && !GET_FLAG(v, pure) && v->type->e->tuple) {
78
1
        const TupleForm tf = v->type->e->tuple;
79
5
        for(m_uint i = 0; i < vector_size(&tf->types); ++i) {
80
4
          const m_bit *data = o->data + v->from->offset;
81
4
          const Type t = (Type)vector_at(&tf->types, i);
82
4
          if(isa(t, shred->info->vm->gwion->type[et_object]) > 0)
83
1
            release(*(M_Object*)(data + vector_at(&tf->offset, i)), shred);
84
        }
85
      }
86
    }
87

6784
    if(GET_FLAG(t, dtor) && t->nspc->dtor) {
88
6076
      if(GET_FLAG(t->nspc->dtor, builtin))
89
6069
        ((f_xtor)t->nspc->dtor->native_func)(o, NULL, shred);
90
      else {
91
7
        o->type_ref = t;
92
7
        handle_dtor(o, shred);
93
7
        return;
94
      }
95
    }
96
22484
  } while((t = t->e->parent));
97
7849
  free_object(p, o);
98
}
99
100
7856
ANN void free_object(MemPool p, const M_Object o) {
101

7856
  if(o->type_ref->nspc && o->type_ref->nspc->info->offset)
102
6171
    mp_free2(p, o->type_ref->nspc->info->offset, o->data);
103
7856
  mp_free(p, M_Object, o);
104
7856
}
105
106
60
static ID_CHECK(opck_this) {
107
60
  if(!env->class_def)
108
1
    ERR_O(exp_self(prim)->pos, _("keyword 'this' can be used only inside class definition..."))
109

59
  if(env->func && !GET_FLAG(env->func, member))
110
1
      ERR_O(exp_self(prim)->pos, _("keyword 'this' cannot be used inside static functions..."))
111

58
  if(env->func && !strcmp(s_name(env->func->def->base->xid), "@gack"))
112
    return force_type(env, get_gack(env->class_def->e->parent)); // get_gack ?
113
58
  return env->class_def;
114
}
115
116
160
static ID_EMIT(opem_this) {
117

160
  if(!exp_getvar(exp_self(prim)) && GET_FLAG(exp_self(prim)->info->type, struct)) {
118
1
    const Instr instr = emit_add_instr(emit, RegPushMemDeref);
119
1
    instr->m_val2 = emit->env->class_def->size;
120
1
    return (Instr)GW_OK;
121
  }
122
159
  return emit_add_instr(emit, RegPushMem);
123
}
124
125
713
GWION_IMPORT(object) {
126
713
  const Type t_object  = gwi_mk_type(gwi, "Object", SZ_INT, "@Compound");
127
713
  gwi_set_global_type(gwi, t_object, et_object);
128
713
  struct SpecialId_ spid = { .ck=opck_this, .em=opem_this, .is_const=1 };
129
713
  gwi_specialid(gwi, "this", &spid);
130
713
  return GW_OK;
131
}