GCC Code Coverage Report
Directory: src/ Exec Total Coverage
File: src/env/type.c Lines: 133 140 95.0 %
Date: 2020-09-12 17:36:58 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
36687
ANN static inline m_bool freeable(const Type a) {
12

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

897697
  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

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

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

41
    *(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
99
  SET_FLAG(t, valid);
124
99
  mk_class(env, t);
125
99
  nspc_add_type_front(src->e->owner, sym, t);
126
99
  return t;
127
}
128
129
1515
ANN m_bool type_ref(Type t) {
130
  do {
131
1515
    if(GET_FLAG(t, empty))
132
2
      return GW_OK;
133

1513
    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
1513
  } while((t = t->e->parent));
144
682
  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
10
ANN m_uint get_depth(const Type type) {
179
10
  m_uint depth = 0;
180
10
  Type t = type;
181
  do {
182
20
    if(t->array_depth) {
183
6
      depth += t->array_depth;
184
6
      t = t->e->d.base_type;
185
    } else
186
14
      t = t->e->parent;
187
20
  } while(t);
188
10
  return depth;
189
}
190
191
31727
ANN m_bool is_fptr(const struct Gwion_* gwion, const Type t) {
192
31727
  return isa(actual_type(gwion, t), gwion->type[et_fptr]) > 0;
193
}
194
140564
ANN inline m_bool is_class(const struct Gwion_* gwion, const Type t) {
195
140564
  return isa(t, gwion->type[et_class]) > 0;
196
}
197
198
41763
ANN Type actual_type(const struct Gwion_* gwion, const Type t) {
199
41763
  return is_class(gwion, t) ? t->e->d.base_type : t;
200
}
201
202
13100
ANN void inherit(const Type t) {
203
13100
  const Nspc nspc = t->nspc, parent = t->e->parent->nspc;
204

13100
  if(!nspc || !parent)
205
5880
    return;
206
7220
  nspc->info->offset = parent->info->offset;
207
7220
  if(parent->info->vtable.ptr)
208
6477
    vector_copy2(&parent->info->vtable, &nspc->info->vtable);
209
}