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/>. */
21 #include "lua/luatex-api.h"
24 #define LOAD_BUF_SIZE 256
25 #define UINT_MAX32 0xFFFFFFFF
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)
48 void dump_luac_registers(void)
53 dump_int(luabytecode_max
);
54 if (lua_bytecode_registers
!= NULL
) {
56 for (k
= 0; k
<= luabytecode_max
; k
++) {
57 if (lua_bytecode_registers
[k
].size
!= 0)
61 for (k
= 0; k
<= luabytecode_max
; k
++) {
62 b
= lua_bytecode_registers
[k
];
66 do_zdump((char *) b
.buf
, 1, (b
.size
), DUMP_FILE
);
70 for (k
= 0; k
< 65536; k
++) {
71 char *a
= luanames
[k
];
73 x
= (int) strlen(a
) + 1;
83 void undump_luac_registers(void)
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
;
103 for (i
= 0; i
< (unsigned) n
; i
++) {
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
++) {
119 char *s
= xmalloc((unsigned) x
);
120 undump_things(*s
, x
);
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 */
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))
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 */
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
) {
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
;
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
) {
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
)
191 k
= (int) luaL_checkinteger(L
, -1);
194 } else if (!bytecode_register_shadow_get(L
, k
)) {
195 if (k
<= luabytecode_max
&& lua_bytecode_registers
[k
].buf
!= NULL
) {
197 (L
, reader
, (void *) (lua_bytecode_registers
+ k
),
203 return luaL_error(L
, "bad bytecode register");
205 lua_pushvalue(L
, -1);
206 bytecode_register_shadow_set(L
, k
);
215 static int set_bytecode(lua_State
* L
)
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");
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) {
236 (unsigned) (sizeof(bytecode
) * (unsigned) (k
+ 1));
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;
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;
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
));
268 static int set_luaname(lua_State
* L
)
272 if (lua_gettop(L
) == 3) {
273 k
= (int) luaL_checkinteger(L
, 2);
274 if (k
> 65535 || k
< 0) {
277 if (luanames
[k
] != NULL
) {
281 if (lua_type(L
,3) == LUA_TSTRING
) {
282 s
= lua_tostring(L
, 3);
284 luanames
[k
] = xstrdup(s
);
291 static int get_luaname(lua_State
* L
)
294 k
= (int) luaL_checkinteger(L
, 2);
295 if (k
> 65535 || k
< 0) {
299 if (luanames
[k
] != NULL
)
300 lua_pushstring(L
, luanames
[k
]);
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
);
315 static const struct luaL_Reg lualib
[] = {
317 {"getluaname", get_luaname
},
318 {"setluaname", set_luaname
},
319 {"getbytecode", get_bytecode
},
320 {"setbytecode", set_bytecode
},
321 {"get_functions_table",lua_functions_get_table
},
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");
332 lua_setfield(L
, LUA_REGISTRYINDEX
, "lua.bytecode_shadow");
333 lua_pushstring(L
, LUA_VERSION
);
334 lua_setfield(L
, -2, "version");
338 lua_pushstring(L
, fname
);
340 lua_setfield(L
, -2, "startupfile");