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 |
|
915542 |
ANN m_bool isa(const restrict Type var, const restrict Type parent) { |
62 |
✓✓✓✓
|
915542 |
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 |
|
|
} |