GCC Code Coverage Report
Directory: src/ Exec Total Coverage
File: src/env/type.c Lines: 134 142 94.4 %
Date: 2020-10-03 11:19:27 Branches: 85 108 78.7 %

Line Branch Exec Source
1
#include "gwion_util.h"
2
#include "gwion_ast.h"
3
#include "gwion_env.h"
4
#include "vm.h"
5
#include "traverse.h"
6
#include "parse.h"
7
#include "gwion.h"
8
#include "clean.h"
9
#include "object.h"
10
11
36776
ANN static inline m_bool freeable(const Type a) {
12

36776
  return !GET_FLAG(a, nonnull) && GET_FLAG(a, template);
13
}
14
15
36776
ANN static void free_type(Type a, Gwion gwion) {
16
36776
  if(freeable(a)) {
17
1522
    if(GET_FLAG(a, union)) {
18
8
      if(a->e->def->union_def) {
19
8
        if(!GET_FLAG(a, pure))
20
3
          free_union_def(gwion->mp, a->e->def->union_def);
21
        else
22
5
          free_decl_list(gwion->mp, a->e->def->list);
23
      }
24
8
      a->e->def->union_def = NULL;
25
    }
26
1522
    if(a->e->def)
27
1496
      class_def_cleaner(gwion, a->e->def);
28
  }
29
36776
  if(a->nspc)
30
17638
    REM_REF(a->nspc, gwion);
31
36776
  if(a->e->tuple)
32
13162
    free_tupleform(a->e->tuple, gwion);
33
36776
  mp_free(gwion->mp, TypeInfo, a->e);
34
36776
  mp_free(gwion->mp, Type, a);
35
36776
}
36
37
106477
Type new_type(MemPool p, const m_uint xid, const m_str name, const Type parent) {
38
106477
  const Type type = mp_calloc(p, Type);
39
106477
  type->xid    = xid;
40
106477
  type->name   = name;
41
106477
  type->e = mp_calloc(p, TypeInfo);
42
106477
  type->e->parent = parent;
43
106477
  if(parent)
44
21988
    type->size = parent->size;
45
106477
  type->ref = new_refcount(p, free_type);
46
106477
  return type;
47
}
48
49
80299
ANN Type type_copy(MemPool p, const Type type) {
50
80299
  const Type a = new_type(p, type->xid, type->name, type->e->parent);
51
80299
  a->nspc           = type->nspc;
52
80299
  a->e->owner       = type->e->owner;
53
80299
  a->e->owner_class = type->e->owner_class;
54
80299
  a->size           = type->size;
55
80299
  a->e->d.base_type = type->e->d.base_type;
56
80299
  a->array_depth    = type->array_depth;
57
80299
  a->e->gack        = type->e->gack;
58
80299
  return a;
59
}
60
61
915851
ANN m_bool isa(const restrict Type var, const restrict Type parent) {
62

915851
  return (var->xid == parent->xid) ? 1 : var->e->parent ? isa(var->e->parent, parent) : -1;
63
}
64
65
75
ANN Type find_common_anc(const restrict Type lhs, const restrict Type rhs) {
66

75
  return isa(lhs, rhs) > 0 ? rhs : isa(rhs, lhs) > 0 ? lhs : NULL;
67
}
68
69
#define describe_find(name, t)                                       \
70
ANN t find_##name(const Type type, const Symbol xid) {               \
71
  if(type->nspc) {                                                   \
72
  const t val = nspc_lookup_##name##2(type->nspc, xid);              \
73
  if(val)                                                            \
74
    return val;                                                      \
75
  }                                                                  \
76
  return type->e->parent ? find_##name(type->e->parent, xid) : NULL; \
77
}
78

208893
describe_find(value, Value)
79
//describe_find(func,  Func)
80
81
2866
ANN Type typedef_base(Type t) {
82
5733
  while(GET_FLAG(t, typedef))
83
1
    t = t->e->parent;
84
2866
  return t;
85
}
86
87
2816
ANN Type array_base(Type type) {
88
2816
  const Type t = typedef_base(type);
89
2816
  return t->array_depth ? t->e->d.base_type : t;
90
}
91
92
171
ANN static Symbol array_sym(const Env env, const Type src, const m_uint depth) {
93
171
  size_t len = strlen(src->name);
94
171
  char name[len + 2* depth + 1];
95
171
  strcpy(name, src->name);
96
171
  m_uint i = depth + 1;
97
538
  while(--i) {
98
196
    strcpy(name+len, "[]");
99
196
    len += 2;
100
  }
101
171
  return insert_symbol(name);
102
}
103
104
171
ANN Type array_type(const Env env, const Type src, const m_uint depth) {
105
171
  const Symbol sym = array_sym(env, src, depth);
106
171
  const Type type = nspc_lookup_type1(src->e->owner, sym);
107
171
  if(type)
108
75
    return type;
109
96
  const Type t = new_type(env->gwion->mp, env->gwion->type[et_array]->xid,
110
96
      s_name(sym), env->gwion->type[et_array]);
111
96
  t->array_depth = depth + src->array_depth;
112
96
  t->e->d.base_type = array_base(src) ?: src;
113
96
  t->e->owner = src->e->owner;
114

96
  if(depth > 1 || isa(src, env->gwion->type[et_compound]) > 0) {
115
38
    t->nspc = new_nspc(env->gwion->mp, s_name(sym));
116
38
    inherit(t);
117
38
    t->nspc->info->class_data_size = SZ_INT;
118
38
    nspc_allocdata(env->gwion->mp, t->nspc);
119

38
    *(f_release**)(t->nspc->info->class_data) = (depth > 1 || !GET_FLAG(src, struct)) ?
120
      object_release : struct_release;
121
  } else
122
58
  ADD_REF((t->nspc = env->gwion->type[et_array]->nspc))
123
96
  SET_FLAG(t, valid);
124
96
  mk_class(env, t);
125
96
  nspc_add_type_front(src->e->owner, sym, t);
126
96
  return t;
127
}
128
129
1505
ANN m_bool type_ref(Type t) {
130
  do {
131
1505
    if(GET_FLAG(t, empty))
132
2
      return GW_OK;
133

1503
    if(GET_FLAG(t, typedef) && t->e->def)
134

11
      if(t->e->def->base.ext && t->e->def->base.ext->array) {
135
9
        if(!t->e->def->base.ext->array->exp)
136
          return GW_OK;
137
        else {
138
9
          const Type type = t->e->parent->e->d.base_type;
139

9
          if(SAFE_FLAG(type, empty))
140
            return GW_OK;
141
        }
142
      }
143
1503
  } while((t = t->e->parent));
144
674
  return 0;
145
}
146
147
148
34
ANN m_str get_type_name(const Env env, const Type t, const m_uint index) {
149
34
  if(!index)
150
    return NULL;
151
34
  m_str name = strchr(t->name, ':');
152
34
  if(!name)
153
15
    return NULL;
154
19
  name += 2;
155
19
  const size_t slen = strlen(name);
156
19
  m_uint lvl = 0;
157
19
  m_uint n = 1;
158
19
  char c, buf[slen + 1], *tmp = buf;
159
91
  while((c = *name)) {
160
72
    if(c == ':')
161
      ++lvl;
162
72
    else if(c == ']') {
163

19
      if(!lvl-- && n == index)
164
19
        break;
165
53
    } else if(c == ',') {
166
      if(!lvl && n++ == index)
167
        break;
168
      if(!lvl)
169
        ++name;
170
    }
171
53
    if(n == index)
172
53
      *tmp++ = *name;
173
53
    ++name;
174
  }
175
19
  *tmp = '\0';
176
19
  return tmp - buf ? s_name(insert_symbol(buf)) : NULL;
177
}
178
179
10
ANN m_uint get_depth(const Type type) {
180
10
  m_uint depth = 0;
181
10
  Type t = type;
182
  do {
183
20
    if(t->array_depth) {
184
6
      depth += t->array_depth;
185
6
      t = t->e->d.base_type;
186
    } else
187
14
      t = t->e->parent;
188
20
  } while(t);
189
10
  return depth;
190
}
191
192
31819
ANN m_bool is_fptr(const struct Gwion_* gwion, const Type t) {
193
31819
  return isa(actual_type(gwion, t), gwion->type[et_fptr]) > 0;
194
}
195
140916
ANN inline m_bool is_class(const struct Gwion_* gwion, const Type t) {
196
140916
  return isa(t, gwion->type[et_class]) > 0;
197
}
198
199
41885
ANN Type actual_type(const struct Gwion_* gwion, const Type t) {
200
41885
  return is_class(gwion, t) ? t->e->d.base_type : t;
201
}
202
203
13128
ANN void inherit(const Type t) {
204
13128
  const Nspc nspc = t->nspc, parent = t->e->parent->nspc;
205

13128
  if(!nspc || !parent)
206
5892
    return;
207
7236
  nspc->info->offset = parent->info->offset;
208
7236
  if(parent->info->vtable.ptr)
209
6492
    vector_copy2(&parent->info->vtable, &nspc->info->vtable);
210
}