beta-0.89.2
[luatex.git] / source / texk / web2c / luatexdir / lua / llualib.c
bloba8760674911769ac74d20dccd3bc64af4619c925
1 /* llualib.c
3 Copyright 2006-2008 Taco Hoekwater <taco@luatex.org>
5 This file is part of LuaTeX.
7 LuaTeX is free software; you can redistribute it and/or modify it under
8 the terms of the GNU General Public License as published by the Free
9 Software Foundation; either version 2 of the License, or (at your
10 option) any later version.
12 LuaTeX is distributed in the hope that it will be useful, but WITHOUT
13 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
14 FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
15 License for more details.
17 You should have received a copy of the GNU General Public License along
18 with LuaTeX; if not, see <http://www.gnu.org/licenses/>. */
20 #include "ptexlib.h"
21 #include "lua/luatex-api.h"
24 #define LOAD_BUF_SIZE 256
25 #define UINT_MAX32 0xFFFFFFFF
27 typedef struct {
28 unsigned char *buf;
29 int size;
30 int done;
31 int alloc;
32 } bytecode;
34 static bytecode *lua_bytecode_registers = NULL;
36 int luabytecode_max = -1;
37 unsigned int luabytecode_bytes = 0;
39 char *luanames[65536] = { NULL };
41 char *get_lua_name(int i)
43 if (i < 0 || i > 65535)
44 return NULL;
45 return luanames[i];
48 void dump_luac_registers(void)
50 int x;
51 int k, n;
52 bytecode b;
53 dump_int(luabytecode_max);
54 if (lua_bytecode_registers != NULL) {
55 n = 0;
56 for (k = 0; k <= luabytecode_max; k++) {
57 if (lua_bytecode_registers[k].size != 0)
58 n++;
60 dump_int(n);
61 for (k = 0; k <= luabytecode_max; k++) {
62 b = lua_bytecode_registers[k];
63 if (b.size != 0) {
64 dump_int(k);
65 dump_int(b.size);
66 do_zdump((char *) b.buf, 1, (b.size), DUMP_FILE);
70 for (k = 0; k < 65536; k++) {
71 char *a = luanames[k];
72 if (a != NULL) {
73 x = (int) strlen(a) + 1;
74 dump_int(x);
75 dump_things(*a, x);
76 } else {
77 x = 0;
78 dump_int(x);
83 void undump_luac_registers(void)
85 int x;
86 int k, n;
87 unsigned int i;
88 bytecode b;
89 undump_int(luabytecode_max);
90 if (luabytecode_max >= 0) {
91 i = (unsigned) (luabytecode_max + 1);
92 if ((int) (UINT_MAX32 / (int) sizeof(bytecode) + 1) <= i) {
93 fatal_error("Corrupt format file");
95 lua_bytecode_registers = xmalloc((unsigned) (i * sizeof(bytecode)));
96 luabytecode_bytes = (unsigned) (i * sizeof(bytecode));
97 for (i = 0; i <= (unsigned) luabytecode_max; i++) {
98 lua_bytecode_registers[i].done = 0;
99 lua_bytecode_registers[i].size = 0;
100 lua_bytecode_registers[i].buf = NULL;
102 undump_int(n);
103 for (i = 0; i < (unsigned) n; i++) {
104 undump_int(k);
105 undump_int(x);
106 b.size = x;
107 b.buf = xmalloc((unsigned) b.size);
108 luabytecode_bytes += (unsigned) b.size;
109 memset(b.buf, 0, (size_t) b.size);
110 do_zundump((char *) b.buf, 1, b.size, DUMP_FILE);
111 lua_bytecode_registers[k].size = b.size;
112 lua_bytecode_registers[k].alloc = b.size;
113 lua_bytecode_registers[k].buf = b.buf;
116 for (k = 0; k < 65536; k++) {
117 undump_int(x);
118 if (x > 0) {
119 char *s = xmalloc((unsigned) x);
120 undump_things(*s, x);
121 luanames[k] = s;
126 static void bytecode_register_shadow_set(lua_State * L, int k)
128 /* the stack holds the value to be set */
129 lua_pushstring(L, "lua.bytecode_shadow"); /* lua.bytecode_shadow */
130 lua_rawget(L, LUA_REGISTRYINDEX);
131 if (lua_istable(L, -1)) {
132 lua_pushvalue(L, -2);
133 lua_rawseti(L, -2, k);
135 lua_pop(L, 1); /* pop table or nil */
136 lua_pop(L, 1); /* pop value */
140 static int bytecode_register_shadow_get(lua_State * L, int k)
142 /* the stack holds the value to be set */
143 int ret = 0;
144 lua_pushstring(L, "lua.bytecode_shadow");
145 lua_rawget(L, LUA_REGISTRYINDEX);
146 if (lua_istable(L, -1)) {
147 lua_rawgeti(L, -1, k);
148 if (!lua_isnil(L, -1))
149 ret = 1;
150 lua_insert(L, -3); /* store the value or nil, deeper down */
151 lua_pop(L, 1); /* pop the value or nil at top */
153 lua_pop(L, 1); /* pop table or nil */
154 return ret;
158 static int writer(lua_State * L, const void *b, size_t size, void *B)
160 bytecode *buf = (bytecode *) B;
161 (void) L; /* for -Wunused */
162 if ((int) (buf->size + (int) size) > buf->alloc) {
163 buf->buf =
164 xrealloc(buf->buf,
165 (unsigned) (buf->alloc + (int) size + LOAD_BUF_SIZE));
166 buf->alloc = buf->alloc + (int) size + LOAD_BUF_SIZE;
168 memcpy(buf->buf + buf->size, b, size);
169 buf->size += (int) size;
170 luabytecode_bytes += (unsigned) size;
171 return 0;
174 static const char *reader(lua_State * L, void *ud, size_t * size)
176 bytecode *buf = (bytecode *) ud;
177 (void) L; /* for -Wunused */
178 if (buf->done == buf->size) {
179 *size = 0;
180 buf->done = 0;
181 return NULL;
183 *size = (size_t) buf->size;
184 buf->done = buf->size;
185 return (const char *) buf->buf;
188 static int get_bytecode(lua_State * L)
190 int k;
191 k = (int) luaL_checkinteger(L, -1);
192 if (k < 0) {
193 lua_pushnil(L);
194 } else if (!bytecode_register_shadow_get(L, k)) {
195 if (k <= luabytecode_max && lua_bytecode_registers[k].buf != NULL) {
196 if (lua_load
197 (L, reader, (void *) (lua_bytecode_registers + k),
198 #ifdef LuajitTeX
199 "bytecode")) {
200 #else
201 "bytecode", NULL)) {
202 #endif
203 return luaL_error(L, "bad bytecode register");
204 } else {
205 lua_pushvalue(L, -1);
206 bytecode_register_shadow_set(L, k);
208 } else {
209 lua_pushnil(L);
212 return 1;
215 static int set_bytecode(lua_State * L)
217 int k, ltype;
218 unsigned int i;
219 k = (int) luaL_checkinteger(L, -2);
220 i = (unsigned) k + 1;
221 if ((int) (UINT_MAX32 / sizeof(bytecode) + 1) < i) {
222 luaL_error(L, "value too large");
224 if (k < 0) {
225 luaL_error(L, "negative values not allowed");
227 ltype = lua_type(L, -1);
228 if (ltype != LUA_TFUNCTION && ltype != LUA_TNIL) {
229 luaL_error(L, "unsupported type");
231 if (k > luabytecode_max) {
232 i = (unsigned) (sizeof(bytecode) * ((unsigned) k + 1));
233 lua_bytecode_registers = xrealloc(lua_bytecode_registers, i);
234 if (luabytecode_max == -1) {
235 luabytecode_bytes +=
236 (unsigned) (sizeof(bytecode) * (unsigned) (k + 1));
237 } else {
238 luabytecode_bytes +=
239 (unsigned) (sizeof(bytecode) *
240 (unsigned) (k + 1 - luabytecode_max));
242 for (i = (unsigned) (luabytecode_max + 1); i <= (unsigned) k; i++) {
243 lua_bytecode_registers[i].buf = NULL;
244 lua_bytecode_registers[i].size = 0;
245 lua_bytecode_registers[i].done = 0;
247 luabytecode_max = k;
249 if (lua_bytecode_registers[k].buf != NULL) {
250 xfree(lua_bytecode_registers[k].buf);
251 luabytecode_bytes -= (unsigned) lua_bytecode_registers[k].size;
252 lua_bytecode_registers[k].size = 0;
253 lua_bytecode_registers[k].done = 0;
254 lua_pushnil(L);
255 bytecode_register_shadow_set(L, k);
257 if (ltype == LUA_TFUNCTION) {
258 lua_bytecode_registers[k].buf = xmalloc(LOAD_BUF_SIZE);
259 lua_bytecode_registers[k].alloc = LOAD_BUF_SIZE;
260 memset(lua_bytecode_registers[k].buf, 0, LOAD_BUF_SIZE);
261 lua_dump(L, writer, (void *) (lua_bytecode_registers + k));
263 lua_pop(L, 1);
264 return 0;
268 static int set_luaname(lua_State * L)
270 int k;
271 const char *s;
272 if (lua_gettop(L) == 3) {
273 k = (int) luaL_checkinteger(L, 2);
274 if (k > 65535 || k < 0) {
275 /* error */
276 } else {
277 if (luanames[k] != NULL) {
278 free(luanames[k]);
279 luanames[k] = NULL;
281 if (lua_type(L,3) == LUA_TSTRING) {
282 s = lua_tostring(L, 3);
283 if (s != NULL)
284 luanames[k] = xstrdup(s);
288 return 0;
291 static int get_luaname(lua_State * L)
293 int k;
294 k = (int) luaL_checkinteger(L, 2);
295 if (k > 65535 || k < 0) {
296 /* error */
297 lua_pushnil(L);
298 } else {
299 if (luanames[k] != NULL)
300 lua_pushstring(L, luanames[k]);
301 else
302 lua_pushnil(L);
304 return 1;
307 static int lua_functions_get_table(lua_State * L) /* hh */
309 lua_rawgeti(L, LUA_REGISTRYINDEX, lua_key_index(lua_functions));
310 lua_gettable(L, LUA_REGISTRYINDEX);
311 return 1;
315 static const struct luaL_Reg lualib[] = {
316 /* *INDENT-OFF* */
317 {"getluaname", get_luaname},
318 {"setluaname", set_luaname},
319 {"getbytecode", get_bytecode},
320 {"setbytecode", set_bytecode},
321 {"get_functions_table",lua_functions_get_table},
322 /* *INDENT-ON* */
323 {NULL, NULL} /* sentinel */
326 int luaopen_lua(lua_State * L, char *fname)
328 luaL_register(L, "lua", lualib);
329 make_table(L, "bytecode", "tex.bytecode", "getbytecode", "setbytecode");
330 make_table(L, "name", "tex.name", "getluaname", "setluaname");
331 lua_newtable(L);
332 lua_setfield(L, LUA_REGISTRYINDEX, "lua.bytecode_shadow");
333 lua_pushstring(L, LUA_VERSION);
334 lua_setfield(L, -2, "version");
335 if (fname == NULL) {
336 lua_pushnil(L);
337 } else {
338 lua_pushstring(L, fname);
340 lua_setfield(L, -2, "startupfile");
341 return 1;