GCC Code Coverage Report
Directory: src/ Exec Total Coverage
File: src/env/type.c Lines: 133 140 95.0 %
Date: 2020-07-24 14:14:26 Branches: 84 108 77.8 %

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
36896
ANN static inline m_bool freeable(const Type a) {
12

36896
  return !GET_FLAG(a, nonnull) && GET_FLAG(a, template);
13
}
14
15
36896
ANN static void free_type(Type a, Gwion gwion) {
16
36896
  if(freeable(a)) {
17
808
    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
808
    if(a->e->def)
27
808
      class_def_cleaner(gwion, a->e->def);
28
  }
29
36896
  if(a->nspc)
30
17321
    REM_REF(a->nspc, gwion);
31
36896
  if(a->e->tuple)
32
12744
    free_tupleform(a->e->tuple, gwion);
33
36896
  mp_free(gwion->mp, TypeInfo, a->e);
34
36896
  mp_free(gwion->mp, Type, a);
35
36896
}
36
37
106761
Type new_type(MemPool p, const m_uint xid, const m_str name, const Type parent) {
38
106761
  const Type type = mp_calloc(p, Type);
39
106761
  type->xid    = xid;
40
106761
  type->name   = name;
41
106761
  type->e = mp_calloc(p, TypeInfo);
42
106761
  type->e->parent = parent;
43
106761
  if(parent)
44
22499
    type->size = parent->size;
45
106761
  type->ref = new_refcount(p, free_type);
46
106761
  return type;
47
}
48
49
80697
ANN Type type_copy(MemPool p, const Type type) {
50
80697
  const Type a = new_type(p, type->xid, type->name, type->e->parent);
51
80697
  a->nspc           = type->nspc;
52
80697
  a->e->owner       = type->e->owner;
53
80697
  a->e->owner_class = type->e->owner_class;
54
80697
  a->size           = type->size;
55
80697
  a->e->d.base_type = type->e->d.base_type;
56
80697
  a->array_depth    = type->array_depth;
57
80697
  a->e->gack        = type->e->gack;
58
80697
  return a;
59
}
60
61
922863
ANN m_bool isa(const restrict Type var, const restrict Type parent) {
62

922863
  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

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

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

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

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

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

10
          if(SAFE_FLAG(type, empty))
140
            return GW_OK;
141
        }
142
      }
143
1486
  } while((t = t->e->parent));
144
669
  return 0;
145
}
146
147
34
ANN m_str get_type_name(const Env env, const Type t, const m_uint index) {
148

34
  if(!index || t->name[0] != '<')
149
15
    return NULL;
150
19
  m_str name = t->name + 2;
151
19
  m_uint lvl = 0;
152
19
  m_uint n = 1;
153
19
  const size_t slen = strlen(name);
154
19
  char c, buf[slen + 1], *tmp = buf;
155
110
  while((c = *name)) {
156
91
    if(c == '<')
157
      ++lvl;
158
91
    else if(c == '>') {
159

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

12702
  if(!nspc || !parent)
205
6024
    return;
206
6678
  nspc->info->offset = parent->info->offset;
207
6678
  if(parent->info->vtable.ptr)
208
5918
    vector_copy2(&parent->info->vtable, &nspc->info->vtable);
209
}