2 * Copyright (c) 2006-2007 Jérôme Vuarand
3 * Copyright (c) 2009 Miriam Ruiz
5 * Permission is hereby granted, free of charge, to any person obtaining a copy
6 * of this software and associated documentation files (the "Software"), to deal
7 * in the Software without restriction, including without limitation the rights
8 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 * copies of the Software, and to permit persons to whom the Software is
10 * furnished to do so, subject to the following conditions:
12 * The above copyright notice and this permission notice shall be included in
13 * all copies or substantial portions of the Software.
15 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
30 #define LUATCC_DEBUG_LEVEL 2
32 #if LUATCC_DEBUG_LEVEL > 2
33 #define MSG_INFO printf
38 #if LUATCC_DEBUG_LEVEL > 1
39 #define MSG_WARNING printf
41 #define MSG_WARNING(...)
44 #define MSG_ERROR printf
46 typedef struct S_LuaTCCState
50 #if LUATCC_DEBUG_LEVEL > 3
55 #if LUATCC_DEBUG_LEVEL > 3
56 static unsigned int last_id
= 0;
59 static int busy_tcc
= 0;
61 /* function context:compile(source [, chunkname]) return true end */
62 static int lua__tcc__compile(lua_State
* L
)
66 const char* chunkname
= NULL
;
69 luaL_checktype(L
, 1, LUA_TUSERDATA
);
70 state
= *(LuaTCCState
**)lua_touserdata(L
, 1);
73 code
= luaL_checkstring(L
, 2);
75 if (lua_isstring(L
, 3))
76 chunkname
= lua_tostring(L
, 3);
79 if (tcc_compile_named_string(tcc
, code
, chunkname
))
81 return luaL_error(L
, "unknown compilation error");
84 lua_pushboolean(L
, 1);
88 /* function context:add_library(libraryname) return true end */
89 static int lua__tcc__add_library(lua_State
* L
)
93 const char* libname
= NULL
;
95 luaL_checktype(L
, 1, LUA_TUSERDATA
);
96 state
= *(LuaTCCState
**)lua_touserdata(L
, 1);
99 libname
= luaL_checkstring(L
, 2);
102 if (tcc_add_library(tcc
, libname
))
103 return luaL_error(L
, "can't load library %s", libname
);
105 lua_pushboolean(L
, 1);
109 /* function context:relocate() return true end */
110 static int lua__tcc__relocate(lua_State
* L
)
116 luaL_checktype(L
, 1, LUA_TUSERDATA
);
117 state
= *(LuaTCCState
**)lua_touserdata(L
, 1);
120 if (state
->mem
!= NULL
)
122 return luaL_error(L
, "cannot relocate twice the same context");
125 /* get needed size of the code */
126 size
= tcc_relocate(tcc
, NULL
);
129 return luaL_error(L
, "unknown relocation (link) error");
132 state
->mem
= malloc(size
);
133 tcc_relocate(tcc
, state
->mem
);
137 lua_pushboolean(L
, 1);
141 /* function context:get_symbol(symbolname) return symbol end */
142 static int lua__tcc__get_symbol(lua_State
* L
)
146 const char* funcname
= NULL
;
150 luaL_checktype(L
, 1, LUA_TUSERDATA
);
151 state
= *(LuaTCCState
**)lua_touserdata(L
, 1);
154 funcname
= luaL_checkstring(L
, 2);
156 func
= tcc_get_symbol(tcc
, funcname
);
158 return luaL_error(L
, "can't get symbol %s", funcname
);
160 f
= (lua_CFunction
)func
;
162 lua_pushcclosure(L
, f
, 0);
167 /* function context:define_symbol(symbolname) return true end */
168 static int lua__tcc__define_symbol(lua_State
* L
)
172 const char* defname
= NULL
;
173 const char* defvalue
= NULL
;
175 luaL_checktype(L
, 1, LUA_TUSERDATA
);
176 state
= *(LuaTCCState
**)lua_touserdata(L
, 1);
179 defname
= luaL_checkstring(L
, 2);
180 defvalue
= luaL_checkstring(L
, 3);
182 tcc_define_symbol(tcc
, defname
, defvalue
);
184 lua_pushboolean(L
, 1);
188 /* function context:undefine_symbol(symbolname) return true end */
189 static int lua__tcc__undefine_symbol(lua_State
* L
)
193 const char* defname
= NULL
;
195 luaL_checktype(L
, 1, LUA_TUSERDATA
);
196 state
= *(LuaTCCState
**)lua_touserdata(L
, 1);
199 defname
= luaL_checkstring(L
, 2);
201 tcc_undefine_symbol(tcc
, defname
);
203 lua_pushboolean(L
, 1);
207 /* function context:add_library_path(path) end */
208 static int lua__tcc__add_library_path(lua_State
*L
)
214 luaL_checktype(L
, 1, LUA_TUSERDATA
);
215 state
= *(LuaTCCState
**)lua_touserdata(L
, 1);
218 path
= luaL_checkstring (L
, 2);
220 tcc_add_library_path(tcc
, path
);
225 /* function context:add_include_path(path) end */
226 static int lua__tcc__add_include_path(lua_State
*L
)
232 luaL_checktype(L
, 1, LUA_TUSERDATA
);
233 state
= *(LuaTCCState
**)lua_touserdata(L
, 1);
236 path
= luaL_checkstring (L
, 2);
238 tcc_add_include_path(tcc
, path
);
243 static int lua__tcc___gc(lua_State
* L
)
245 LuaTCCState
** pstate
;
246 MSG_INFO("TCC: Garbage Collector\n");
248 luaL_checktype(L
, 1, LUA_TUSERDATA
);
249 pstate
= (LuaTCCState
**)lua_touserdata(L
, 1);
251 if (pstate
&& *pstate
)
253 #if LUATCC_DEBUG_LEVEL > 3
254 MSG_INFO("TCC: - Deleting state #%d\n", (*pstate
)->id
);
256 if ((*pstate
)->tcc
!= NULL
)
258 tcc_delete((*pstate
)->tcc
);
259 (*pstate
)->tcc
= NULL
;
261 if ((*pstate
)->mem
!= NULL
)
263 free((*pstate
)->mem
);
264 (*pstate
)->mem
= NULL
;
272 static const struct luaL_reg tcc_methods
[] = {
273 {"compile", lua__tcc__compile
},
274 {"add_library", lua__tcc__add_library
},
275 {"relocate", lua__tcc__relocate
},
276 {"get_symbol", lua__tcc__get_symbol
},
277 {"define_symbol", lua__tcc__define_symbol
},
278 {"undefine_symbol", lua__tcc__undefine_symbol
},
279 {"add_library_path", lua__tcc__add_library_path
},
280 {"add_include_path", lua__tcc__add_include_path
},
284 void luatcc__error_func(void* opaque
, const char* msg
)
286 luaL_error((lua_State
*)opaque
, "%s", msg
);
289 static int lua__new(lua_State
* L
)
291 MSG_INFO("TCC: New TCC Context\n");
294 return luaL_error(L
, "state compilation needs to be finished before creating new ones");
296 LuaTCCState
* state
= malloc(sizeof(LuaTCCState
));
297 memset(state
, 0, sizeof(LuaTCCState
));
300 state
->tcc
= tcc_new();
302 return luaL_error(L
, "can't create tcc state");
304 #if LUATCC_DEBUG_LEVEL > 3
305 state
->id
= ++last_id
;
306 MSG_INFO("TCC: + Creating state #%d\n", state
->id
);
311 tcc_set_output_type(state
->tcc
, TCC_OUTPUT_MEMORY
);
312 tcc_set_error_func(state
->tcc
, (void*)L
, luatcc__error_func
);
314 LuaTCCState
** pstate
= (LuaTCCState
**)lua_newuserdata(L
, sizeof(LuaTCCState
*));
316 lua_newtable(L
); /* Metatable */
317 lua_newtable(L
); /* __index */
318 luaL_register(L
, 0, tcc_methods
);
319 lua_setfield(L
, -2, "__index");
320 lua_pushcfunction(L
, lua__tcc___gc
);
321 lua_setfield(L
, -2, "__gc");
322 lua_setmetatable(L
, -2);
327 static const struct luaL_reg module_functions
[] = {
332 MODULE_API
int luaopen_module(lua_State
*L
)
334 lua_getglobal(L
, "module");
338 lua_pushvalue(L
, LUA_ENVIRONINDEX
);
339 luaL_register(L
, 0, module_functions
);