1 |
|
|
#include <stdlib.h> |
2 |
|
|
#include <string.h> |
3 |
|
|
#include <ctype.h> |
4 |
|
|
#include "gwion_util.h" |
5 |
|
|
#include "gwion_ast.h" |
6 |
|
|
#include "gwion_env.h" |
7 |
|
|
#include "vm.h" |
8 |
|
|
#include "traverse.h" |
9 |
|
|
#include "object.h" |
10 |
|
|
#include "instr.h" |
11 |
|
|
#include "emit.h" |
12 |
|
|
#include "gwion.h" |
13 |
|
|
#include "operator.h" |
14 |
|
|
#include "import.h" |
15 |
|
|
#include "gwi.h" |
16 |
|
|
#include "clean.h" |
17 |
|
|
|
18 |
|
42038 |
ANN2(1,2,3) static m_bool dl_func_init(const Gwi gwi, const restrict m_str t, |
19 |
|
|
const restrict m_str n) { |
20 |
✓✓ |
42038 |
CHECK_BB(ck_ini(gwi, ck_fdef)) |
21 |
|
42037 |
gwi->ck->name = n; |
22 |
✗✓ |
42037 |
CHECK_BB(check_typename_def(gwi, gwi->ck)) |
23 |
✓✓ |
42037 |
CHECK_OB((gwi->ck->td = str2decl(gwi, t))) |
24 |
|
42034 |
vector_init(&gwi->ck->v); |
25 |
|
42034 |
return GW_OK; |
26 |
|
|
} |
27 |
|
|
|
28 |
|
42033 |
ANN m_int gwi_func_ini(const Gwi gwi, const restrict m_str t, const restrict m_str n) { |
29 |
|
42033 |
return dl_func_init(gwi, t, n); |
30 |
|
|
} |
31 |
|
|
|
32 |
|
42028 |
ANN Arg_List make_dll_arg_list(const Vector v) { |
33 |
|
42028 |
Arg_List base = (Arg_List)vector_front(v), arg_list = base; |
34 |
✓✓ |
49170 |
for(m_uint i = 1; i < vector_size(v); ++i) |
35 |
|
7142 |
arg_list = (arg_list->next = (Arg_List)vector_at(v, i)); |
36 |
|
42028 |
vector_release(v); |
37 |
|
42028 |
v->ptr = NULL; |
38 |
|
42028 |
return base; |
39 |
|
|
} |
40 |
|
|
|
41 |
|
42028 |
ANEW ANN static Func_Base* gwi_func_base(const Gwi gwi, ImportCK *ck) { |
42 |
|
42028 |
const Arg_List arg_list = make_dll_arg_list(&gwi->ck->v); |
43 |
|
42028 |
Func_Base *base = new_func_base(gwi->gwion->mp, ck->td, ck->sym, arg_list, ck->flag | ae_flag_builtin); |
44 |
|
42028 |
ck->td = NULL; |
45 |
✓✓ |
42028 |
if(ck->tmpl) { |
46 |
|
4 |
base->tmpl = gwi_tmpl(gwi); |
47 |
|
4 |
ck->tmpl = NULL; |
48 |
|
|
} |
49 |
|
42028 |
return base; |
50 |
|
|
} |
51 |
|
|
|
52 |
|
42024 |
ANEW ANN static Func_Def import_fdef(const Gwi gwi, ImportCK *ck) { |
53 |
|
42024 |
Func_Base* base = gwi_func_base(gwi, ck); |
54 |
|
42024 |
const Func_Def fdef = new_func_def(gwi->gwion->mp, base, NULL, loc(gwi)); |
55 |
|
42024 |
fdef->d.dl_func_ptr = (void*)(m_uint)ck->addr; |
56 |
✓✓ |
42024 |
if(base->tmpl) |
57 |
|
3 |
SET_FLAG(fdef->base, template); |
58 |
|
42024 |
return fdef; |
59 |
|
|
} |
60 |
|
|
|
61 |
|
1 |
ANN static m_bool section_fdef(const Gwi gwi, const Func_Def fdef) { |
62 |
|
1 |
Section* section = new_section_func_def(gwi->gwion->mp, fdef); |
63 |
|
1 |
const Ast body = new_ast(gwi->gwion->mp, section, NULL); |
64 |
|
1 |
gwi_body(gwi, body); |
65 |
|
1 |
return GW_OK; |
66 |
|
|
} |
67 |
|
|
|
68 |
|
2 |
ANN static m_bool error_fdef(const Gwi gwi, const Func_Def fdef) { |
69 |
|
2 |
func_def_cleaner(gwi->gwion, fdef); |
70 |
|
2 |
return GW_ERROR; |
71 |
|
|
} |
72 |
|
|
|
73 |
|
42024 |
ANN m_int gwi_func_valid(const Gwi gwi, ImportCK *ck) { |
74 |
|
42024 |
const Func_Def fdef = import_fdef(gwi, ck); |
75 |
✓✓✓✓
|
42024 |
if(SAFE_FLAG(gwi->gwion->env->class_def, template)) |
76 |
|
1 |
/*return*/ section_fdef(gwi, fdef); |
77 |
✓✓ |
42024 |
if(traverse_func_def(gwi->gwion->env, fdef) < 0) |
78 |
|
2 |
return error_fdef(gwi, fdef); |
79 |
|
42022 |
ck_end(gwi); |
80 |
|
42022 |
return GW_OK; |
81 |
|
|
} |
82 |
|
|
|
83 |
|
42024 |
ANN m_int gwi_func_end(const Gwi gwi, const f_xfun addr, const ae_flag flag) { |
84 |
✗✓ |
42024 |
CHECK_BB(ck_ok(gwi, ck_fdef)) |
85 |
|
42024 |
gwi->ck->addr = addr; |
86 |
|
42024 |
gwi->ck->flag = flag; |
87 |
✓✓ |
42024 |
if(gwi_func_valid(gwi, gwi->ck) > 0) |
88 |
|
42022 |
return GW_OK; |
89 |
|
2 |
return GW_ERROR; |
90 |
|
|
} |
91 |
|
|
|
92 |
|
23533 |
ANN m_int gwi_func_arg(const Gwi gwi, const restrict m_str t, const restrict m_str n) { |
93 |
✗✓ |
23533 |
CHECK_BB(ck_ok(gwi, ck_fdef)) |
94 |
✓✓ |
23533 |
DECL_OB(Type_Decl*, td, = str2decl(gwi, t)) |
95 |
|
23530 |
const Var_Decl var = str2var(gwi, n); |
96 |
✓✓ |
23530 |
if(var) { |
97 |
|
23529 |
const Arg_List arg = new_arg_list(gwi->gwion->mp, td, var, NULL); |
98 |
|
23529 |
vector_add(&gwi->ck->v, (vtype)arg); |
99 |
|
23529 |
return GW_OK; |
100 |
|
|
} |
101 |
|
1 |
free_type_decl(gwi->gwion->mp, td); |
102 |
|
1 |
return GW_ERROR; |
103 |
|
|
} |
104 |
|
|
|
105 |
|
5 |
ANN m_int gwi_fptr_ini(const Gwi gwi, const restrict m_str type, const restrict m_str name) { |
106 |
|
5 |
return dl_func_init(gwi, type, name); |
107 |
|
|
} |
108 |
|
|
|
109 |
|
4 |
ANN static Fptr_Def import_fptr(const Gwi gwi) { |
110 |
|
4 |
Func_Base *base = gwi_func_base(gwi, gwi->ck); |
111 |
|
4 |
return new_fptr_def(gwi->gwion->mp, base); |
112 |
|
|
} |
113 |
|
|
|
114 |
|
4 |
ANN Type gwi_fptr_end(const Gwi gwi, const ae_flag flag) { |
115 |
✗✓ |
4 |
CHECK_BO(ck_ok(gwi, ck_fdef)) |
116 |
✗✓ |
4 |
DECL_OO(const Fptr_Def, fptr, = import_fptr(gwi)) |
117 |
|
4 |
fptr->base->flag |= flag; |
118 |
|
|
// what happens if it is in a template class ? |
119 |
|
4 |
const m_bool ret = traverse_fptr_def(gwi->gwion->env, fptr); |
120 |
✓✓ |
4 |
if(fptr->base->func) // is it needed ? |
121 |
|
3 |
SET_FLAG(fptr->base->func, builtin); |
122 |
✓✓ |
4 |
const Type t = ret > 0 ? fptr->type : NULL; |
123 |
|
4 |
free_fptr_def(gwi->gwion->mp, fptr); |
124 |
✓✓ |
4 |
if(fptr->type) |
125 |
|
3 |
REM_REF(fptr->type, gwi->gwion) |
126 |
|
4 |
ck_end(gwi); |
127 |
|
4 |
return t; |
128 |
|
|
} |
129 |
|
|
|
130 |
|
11 |
ANN void ck_clean_fdef(MemPool mp, ImportCK *ck) { |
131 |
✓✓ |
11 |
if(ck->td) |
132 |
|
6 |
free_type_decl(mp, ck->td); |
133 |
✓✓ |
11 |
if(ck->v.ptr) { |
134 |
✓✓ |
9 |
for(m_uint i = 0; i < vector_size(&ck->v); ++i) { |
135 |
|
3 |
Arg_List list = (Arg_List)vector_at(&ck->v, i); |
136 |
|
3 |
list->next = NULL; |
137 |
|
3 |
free_arg_list(mp, list); |
138 |
|
|
} |
139 |
|
6 |
vector_release(&ck->v); |
140 |
|
|
} |
141 |
✓✓ |
11 |
if(ck->tmpl) |
142 |
|
3 |
free_id_list(mp, ck->tmpl); |
143 |
|
11 |
} |