-
Notifications
You must be signed in to change notification settings - Fork 6
/
Copy pathtcc.lua
184 lines (141 loc) · 4.65 KB
/
tcc.lua
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
-----------------------------------------------------------
-- Binding for TCC v0.9.26
-----------------------------------------------------------
local ffi = require 'ffi'
local jit = require 'jit'
local const = {}
const.output_memory = 0
const.output_exe = 1
const.output_dll = 2
const.output_obj = 3
const.output_preprocess = 4
const.relocate_auto = ffi.cast('void*', 1)
local function get_const(value)
if type(value) == 'string' then
if const[value] then
return const[value]
else
error('unknown const name', 3)
end
end
return value
end
local header = [[
typedef struct TCCState TCCState;
TCCState *tcc_new(void);
void tcc_delete(TCCState *s);
void tcc_set_lib_path(TCCState *s, const char *path);
void tcc_set_error_func(TCCState *s, void *error_opaque, void (*error_func)(void *opaque, const char *msg));
int tcc_set_options(TCCState *s, const char *str);
int tcc_add_include_path(TCCState *s, const char *pathname);
int tcc_add_sysinclude_path(TCCState *s, const char *pathname);
void tcc_define_symbol(TCCState *s, const char *sym, const char *value);
void tcc_undefine_symbol(TCCState *s, const char *sym);
int tcc_add_file(TCCState *s, const char *filename);
int tcc_compile_string(TCCState *s, const char *buf);
int tcc_set_output_type(TCCState *s, int output_type);
int tcc_add_library_path(TCCState *s, const char *pathname);
int tcc_add_library(TCCState *s, const char *libraryname);
int tcc_add_symbol(TCCState *s, const char *name, const void *val);
int tcc_output_file(TCCState *s, const char *filename);
int tcc_run(TCCState *s, int argc, char **argv);
int tcc_relocate(TCCState *s1, void *ptr);
void *tcc_get_symbol(TCCState *s, const char *name);
]]
local bind = {}
local mod = {}
function mod.new()
return bind.tcc_new()
end
function mod.delete(s)
bind.tcc_delete(s)
end
function mod.set_lib_path(s, path)
bind.tcc_set_lib_path(s, path)
end
function mod.set_error_func(s, opaque, error_func)
bind.tcc_set_error_func(s, opaque, error_func)
end
function mod.set_options(s, str)
return bind.tcc_set_options(s, str)
end
function mod.add_include_path(s, pathname)
return bind.tcc_add_include_path(s, pathname)
end
function mod.add_sysinclude_path(s, pathname)
return bind.tcc_add_sysinclude_path(s, pathname)
end
function mod.define_symbol(s, sym, value)
bind.tcc_define_symbol(s, sym, value)
end
function mod.undefine_symbol(s, sym)
bind.tcc_undefine_symbol(s, sym)
end
function mod.add_file(s, filename)
return bind.tcc_add_file(s, filename)
end
function mod.compile_string(s, buf)
return bind.tcc_compile_string(s, buf)
end
function mod.set_output_type(s, type)
return bind.tcc_set_output_type(s, get_const(type))
end
function mod.add_library_path(s, pathname)
return bind.tcc_add_library_path(s, pathname)
end
function mod.add_library(s, libraryname)
return bind.tcc_add_library(s, libraryname)
end
function mod.add_symbol(s, name, val, ctype)
val = ctype and ffi.cast(ctype, val) or val
return bind.tcc_add_symbol(s, name, val)
end
function mod.output_file(s, filename)
return bind.tcc_output_file(s, filename)
end
function mod.run(s, t)
local argc = #t
local argv = ffi.new('char*[?]', argc)
for i = 1, argc do
local str = tostring(t[i])
argv[i - 1] = ffi.new('char[?]', #str + 1, str)
end
return bind.tcc_run(s, argc, argv)
end
function mod.relocate(s, ptr)
return bind.tcc_relocate(s, get_const(ptr))
end
function mod.get_symbol(s, name, ctype)
local symbol = bind.tcc_get_symbol(s, name)
return ctype and ffi.cast(ctype, symbol) or symbol
end
state_mt = {}
state_mt.__index = state_mt
state_mt.delete = mod.delete
state_mt.set_lib_path = mod.set_lib_path
state_mt.set_error_func = mod.set_error_func
state_mt.set_options = mod.set_options
state_mt.add_include_path = mod.add_include_path
state_mt.add_sysinclude_path = mod.add_sysinclude_path
state_mt.define_symbol = mod.define_symbol
state_mt.undefine_symbol = mod.undefine_symbol
state_mt.add_file = mod.add_file
state_mt.compile_string = mod.compile_string
state_mt.set_output_type = mod.set_output_type
state_mt.add_library_path = mod.add_library_path
state_mt.add_library = mod.add_library
state_mt.add_symbol = mod.add_symbol
state_mt.output_file = mod.output_file
state_mt.run = mod.run
state_mt.relocate = mod.relocate
state_mt.get_symbol = mod.get_symbol
mod.const = const
setmetatable(mod, {
__call = function(self, name)
ffi.cdef(header)
bind = ffi.load(name)
ffi.metatype('TCCState', state_mt)
return self
end
})
return mod