1
4
5# include "luametatex.h"
6
7
18
19# define LOAD_BUF_SIZE 64*1024
20# define UINT_MAX32 0xFFFFFFFF
21
22# define LUA_FUNCTIONS "lua.functions"
23# define LUA_BYTECODES "lua.bytecodes"
24# define LUA_BYTECODES_INDIRECT "lua.bytecodes.indirect"
25
26typedef struct bytecode {
27 unsigned char *buf;
28 int size;
29 int alloc;
30} bytecode;
31
32static bytecode *lmt_bytecode_registers = NULL;
33
34void lmt_dump_registers(dumpstream f)
35{
36 dump_int(f, lmt_lua_state.version_number);
37 dump_int(f, lmt_lua_state.release_number);
38 dump_int(f, lmt_lua_state.integer_size);
39 dump_int(f, lmt_lua_state.bytecode_max);
40 if (lmt_bytecode_registers) {
41 int n = 0;
42 for (int k = 0; k <= lmt_lua_state.bytecode_max; k++) {
43 if (lmt_bytecode_registers[k].size != 0) {
44 n++;
45 }
46 }
47 dump_int(f, n);
48 for (int k = 0; k <= lmt_lua_state.bytecode_max; k++) {
49 bytecode b = lmt_bytecode_registers[k];
50 if (b.size != 0) {
51 dump_int(f, k);
52 dump_int(f, b.size);
53 dump_items(f, (char *) b.buf, 1, b.size);
54 }
55 }
56 }
57}
58
59void lmt_undump_registers(dumpstream f)
60{
61 int version_number = 0;
62 int release_number = 0;
63 int integer_size = 0;
64 undump_int(f, version_number);
65 if (version_number != lmt_lua_state.version_number) {
66 tex_fatal_undump_error("mismatching Lua version number");
67 }
68 undump_int(f, release_number);
69 if (release_number != lmt_lua_state.release_number) {
70 tex_fatal_undump_error("mismatching Lua release number");
71 }
72 undump_int(f, integer_size);
73 if (integer_size != lmt_lua_state.integer_size) {
74 tex_fatal_undump_error("different integer size");
75 }
76 undump_int(f, lmt_lua_state.bytecode_max);
77 if (lmt_lua_state.bytecode_max < 0) {
78 tex_fatal_undump_error("not enough memory for undumping bytecodes");
79 } else {
80 size_t s = (lmt_lua_state.bytecode_max + 1) * sizeof(bytecode);
81 int n = (int) s;
82 lmt_bytecode_registers = (bytecode *) lmt_memory_malloc(s);
83 if (lmt_bytecode_registers) {
84 lmt_lua_state.bytecode_bytes = n;
85 for (int j = 0; j <= lmt_lua_state.bytecode_max; j++) {
86 lmt_bytecode_registers[j].buf = NULL;
87 lmt_bytecode_registers[j].size = 0;
88 lmt_bytecode_registers[j].alloc = 0;
89 }
90 undump_int(f, n);
91 for (int j = 0; j < n; j++) {
92 unsigned char *buffer;
93 int slot, size;
94 undump_int(f, slot);
95 undump_int(f, size);
96 buffer = (unsigned char *) lmt_memory_malloc((unsigned) size);
97 if (buffer) {
98 memset(buffer, 0, (size_t) size);
99 undump_items(f, buffer, 1, size);
100 lmt_bytecode_registers[slot].buf = buffer;
101 lmt_bytecode_registers[slot].size = size;
102 lmt_bytecode_registers[slot].alloc = size;
103 lmt_lua_state.bytecode_bytes += size;
104 } else {
105 tex_fatal_undump_error("not enough memory for undumping bytecodes");
106 }
107 }
108 }
109 }
110}
111
112static void lualib_aux_bytecode_register_shadow_set(lua_State *L, int k)
113{
114
115 luaL_getmetatable(L, LUA_BYTECODES_INDIRECT);
116 if (lua_istable(L, -1)) {
117 lua_pushvalue(L, -2);
118 lua_rawseti(L, -2, k);
119 }
120 lua_pop(L, 2);
121}
122
123static int lualib_aux_bytecode_register_shadow_get(lua_State *L, int k)
124{
125
126 int ret = 0;
127 luaL_getmetatable(L, LUA_BYTECODES_INDIRECT);
128 if (lua_istable(L, -1)) {
129 if (lua_rawgeti(L, -1, k) != LUA_TNIL) {
130 ret = 1;
131 }
132
133 lua_insert(L, -3);
134
135 lua_pop(L, 1);
136 }
137
138 lua_pop(L, 1);
139 return ret;
140}
141
142static int lualib_aux_writer(lua_State *L, const void *b, size_t size, void *B)
143{
144 bytecode *buf = (bytecode *) B;
145 (void) L;
146 if ((int) (buf->size + (int) size) > buf->alloc) {
147 unsigned newalloc = (unsigned) (buf->alloc + (int) size + LOAD_BUF_SIZE);
148 unsigned char *bb = lmt_memory_realloc(buf->buf, newalloc);
149 if (bb) {
150 buf->buf = bb;
151 buf->alloc = newalloc;
152 } else {
153 return luaL_error(L, "something went wrong with handling bytecodes");
154 }
155 }
156 memcpy(buf->buf + buf->size, b, size);
157 buf->size += (int) size;
158 lmt_lua_state.bytecode_bytes += (unsigned) size;
159 return 0;
160}
161
162static const char *lualib_aux_reader(lua_State *L, void *ud, size_t *size)
163{
164 bytecode *buf = (bytecode *) ud;
165 (void) L;
166 *size = (size_t) buf->size;
167 return (const char *) buf->buf;
168}
169
170static int lualib_valid_bytecode(lua_State *L, int slot)
171{
172 if (slot < 0 || slot > lmt_lua_state.bytecode_max) {
173 return luaL_error(L, "bytecode register out of range");
174 } else if (lualib_aux_bytecode_register_shadow_get(L, slot) || ! lmt_bytecode_registers[slot].buf) {
175 return luaL_error(L, "undefined bytecode register");
176 } else if (lua_load(L, lualib_aux_reader, (void *) (lmt_bytecode_registers + slot), "bytecode", NULL)) {
177 return luaL_error(L, "bytecode register doesn't load well");
178 } else {
179 return 1;
180 }
181}
182
183static int lualib_get_bytecode(lua_State *L)
184{
185 int slot = lmt_checkinteger(L, 1);
186 if (lualib_valid_bytecode(L, slot)) {
187 lua_pushvalue(L, -1);
188 lualib_aux_bytecode_register_shadow_set(L, slot);
189 return 1;
190 } else {
191 return 0;
192 }
193}
194
195static int lmt_handle_bytecode_call(lua_State *L, int slot)
196{
197 int stacktop = lua_gettop(L);
198 int error = 1;
199 if (lualib_valid_bytecode(L, slot)) {
200
201 lua_pushinteger(L, slot);
202
203 lua_pushcfunction(L, lmt_traceback);
204
205 lua_insert(L, stacktop);
206 ++lmt_lua_state.bytecode_callback_count;
207 error = lua_pcall(L, 1, 0, stacktop);
208
209 lua_remove(L, stacktop);
210 if (error) {
211 lua_gc(L, LUA_GCCOLLECT, 0);
212 lmt_error(L, "bytecode call", slot, (error == LUA_ERRRUN ? 0 : 1));
213 }
214 }
215 lua_settop(L, stacktop);
216 return ! error;
217}
218
219void lmt_bytecode_call(int slot)
220{
221 lmt_handle_bytecode_call(lmt_lua_state.lua_instance, slot);
222}
223
224
227
228static int lualib_call_bytecode(lua_State *L)
229{
230 int k = lmt_checkinteger(L, -1);
231 if (k >= 0 && ! lualib_aux_bytecode_register_shadow_get(L, k)) {
232 if (k <= lmt_lua_state.bytecode_max && lmt_bytecode_registers[k].buf) {
233 lmt_handle_bytecode_call(L, k);
234
235 } else {
236 k = -1;
237 }
238 } else {
239 k = -1;
240 }
241 lua_pushboolean(L, k != -1);
242
243 return 1;
244}
245
246static int lualib_set_bytecode(lua_State *L)
247{
248 int k = lmt_checkinteger(L, 1);
249 int i = k + 1;
250 if ((k < 0) || (k > max_bytecode_index)) {
251 return luaL_error(L, "bytecode register out of range");
252 } else {
253 int ltype = lua_type(L, 2);
254 int strip = lua_toboolean(L, 3);
255 if (ltype != LUA_TFUNCTION && ltype != LUA_TNIL) {
256 return luaL_error(L, "bytecode register should be a function or nil");
257 } else {
258
259 lua_settop(L, 2);
260 if (k > lmt_lua_state.bytecode_max) {
261 bytecode *r = lmt_memory_realloc(lmt_bytecode_registers, (size_t) i * sizeof(bytecode));
262 if (r) {
263 lmt_bytecode_registers = r;
264 lmt_lua_state.bytecode_bytes += ((int) sizeof(bytecode) * (k + 1 - (lmt_lua_state.bytecode_max > 0 ? lmt_lua_state.bytecode_max : 0)));
265 for (unsigned j = (unsigned) (lmt_lua_state.bytecode_max + 1); j <= (unsigned) k; j++) {
266 lmt_bytecode_registers[j].buf = NULL;
267 lmt_bytecode_registers[j].size = 0;
268 lmt_bytecode_registers[j].alloc = 0;
269 }
270 lmt_lua_state.bytecode_max = k;
271 } else {
272 return luaL_error(L, "bytecode register exceeded memory");
273 }
274 }
275 if (lmt_bytecode_registers[k].buf) {
276 lmt_memory_free(lmt_bytecode_registers[k].buf);
277 lmt_lua_state.bytecode_bytes -= lmt_bytecode_registers[k].size;
278 lmt_bytecode_registers[k].size = 0;
279 lmt_bytecode_registers[k].buf = NULL;
280 lua_pushnil(L);
281 lualib_aux_bytecode_register_shadow_set(L, k);
282 }
283 if (ltype == LUA_TFUNCTION) {
284 lmt_bytecode_registers[k].buf = lmt_memory_calloc(1, LOAD_BUF_SIZE);
285 if (lmt_bytecode_registers[k].buf) {
286 lmt_bytecode_registers[k].alloc = LOAD_BUF_SIZE;
287
288 lua_dump(L, lualib_aux_writer, (void *) (lmt_bytecode_registers + k), strip);
289 } else {
290 return luaL_error(L, "bytecode register exceeded memory");
291 }
292 }
293 lua_pop(L, 1);
294 }
295 }
296 return 0;
297}
298
299void lmt_initialize_functions(int set_size)
300{
301 lua_State *L = lmt_lua_state.lua_instance;
302 if (set_size) {
303 tex_engine_get_config_number("functionsize", &lmt_lua_state.function_table_size);
304 if (lmt_lua_state.function_table_size < 0) {
305 lmt_lua_state.function_table_size = 0;
306 }
307 lua_createtable(L, lmt_lua_state.function_table_size, 0);
308 } else {
309 lua_newtable(L);
310 }
311 lmt_lua_state.function_table_id = luaL_ref(L, LUA_REGISTRYINDEX);
312
313 lua_pushstring(L, LUA_FUNCTIONS);
314 lua_rawgeti(L, LUA_REGISTRYINDEX, lmt_lua_state.function_table_id);
315 lua_settable(L, LUA_REGISTRYINDEX);
316}
317
318static int lualib_get_functions_table(lua_State *L)
319{
320 if (lua_toboolean(L, lua_gettop(L))) {
321
322 lmt_initialize_functions(1);
323 }
324 lua_rawgeti(L, LUA_REGISTRYINDEX, lmt_lua_state.function_table_id);
325 return 1;
326}
327
328static int lualib_new_table(lua_State *L)
329{
330 int i = lmt_checkinteger(L, 1);
331 int h = lmt_checkinteger(L, 2);
332 lua_createtable(L, i < 0 ? 0 : i, h < 0 ? 0 : h);
333 return 1;
334}
335
336static int lualib_new_index(lua_State *L)
337{
338 int n = lmt_checkinteger(L, 1);
339 int t = lua_gettop(L);
340 lua_createtable(L, n < 0 ? 0 : n, 0);
341 if (t == 2) {
342 for (lua_Integer i = 1; i <= n; i++) {
343 lua_pushvalue(L, 2);
344 lua_rawseti(L, -2, i);
345 }
346 }
347 return 1;
348}
349
350static int lualib_get_stack_top(lua_State *L)
351{
352 lua_pushinteger(L, lua_gettop(L));
353 return 1;
354}
355
356static int lualib_get_runtime(lua_State *L)
357{
358 lua_pushnumber(L, aux_get_run_time());
359 return 1;
360}
361
362static int lualib_get_currenttime(lua_State *L)
363{
364 lua_pushnumber(L, aux_get_current_time());
365 return 1;
366}
367
368static int lualib_set_exitcode(lua_State *L)
369{
370 lmt_error_state.default_exit_code = lmt_checkinteger(L, 1);
371 return 0;
372}
373
374static int lualib_get_exitcode(lua_State *L)
375{
376 lua_pushinteger(L, lmt_error_state.default_exit_code);
377 return 1;
378}
379
380
387
388# ifdef _WIN32
389
390# define clock_inittime()
391
392 static int lualib_get_preciseticks(lua_State *L)
393 {
394 LARGE_INTEGER t;
395 QueryPerformanceCounter(&t);
396 lua_pushnumber(L, (double) t.QuadPart);
397 return 1;
398 }
399
400 static int lualib_get_preciseseconds(lua_State *L)
401 {
402 LARGE_INTEGER t;
403 QueryPerformanceFrequency(&t);
404 lua_pushnumber(L, luaL_optnumber(L, 1, 0) / (double) t.QuadPart);
405 return 1;
406 }
407
408# else
409
410# if (defined(__MACH__) && ! defined(CLOCK_PROCESS_CPUTIME_ID))
411
412
413
414# include <mach/mach_time.h>
415# define CLOCK_PROCESS_CPUTIME_ID 1
416
417 static double conversion_factor;
418
419 static void clock_inittime()
420 {
421 mach_timebase_info_data_t timebase;
422 mach_timebase_info(&timebase);
423 conversion_factor = (double)timebase.numer / (double)timebase.denom;
424 }
425
426 static int clock_gettime(int clk_id, struct timespec *t)
427 {
428 uint64_t time;
429 double nseconds, seconds;
430 (void) clk_id;
431 time = mach_absolute_time();
432 nseconds = ((double)time * conversion_factor);
433 seconds = ((double)time * conversion_factor / 1e9);
434 t->tv_sec = seconds;
435 t->tv_nsec = nseconds;
436 return 0;
437 }
438
439# else
440
441# define clock_inittime()
442
443# endif
444
445 static int lualib_get_preciseticks(lua_State *L)
446 {
447 struct timespec t;
448 clock_gettime(CLOCK_PROCESS_CPUTIME_ID,&t);
449 lua_pushnumber(L, t.tv_sec*1000000000.0 + t.tv_nsec);
450 return 1;
451 }
452
453 static int lualib_get_preciseseconds(lua_State *L)
454 {
455 lua_pushnumber(L, ((double) luaL_optnumber(L, 1, 0)) / 1000000000.0);
456 return 1;
457 }
458
459# endif
460
461static int lualib_get_startupfile(lua_State *L)
462{
463 lua_pushstring(L, lmt_engine_state.startup_filename);
464 return 1;
465}
466
467static int lualib_get_version(lua_State *L)
468{
469 lua_pushstring(L, LUA_VERSION);
470 return 1;
471}
472
473
480
481
488
489
490
491
512
513
537
538
542
543static int lualib_get_debug_info(lua_State *L) {
544 if (! lua_isthread(L, 1)) {
545 lua_Debug ar;
546 if (lua_getstack(L, 2, &ar) && lua_getinfo(L, "nS", &ar)) {
547 lua_pushstring(L, ar.name ? ar.name : (ar.namewhat ? ar.namewhat : (ar.what ? ar.what : "<unknown>")));
548 lua_pushstring(L, ar.short_src);
549 lua_pushinteger(L, ar.linedefined);
550 return 3;
551 }
552 }
553 return 0;
554}
555
556
557
558static const struct luaL_Reg lualib_function_list[] = {
559 { "newtable", lualib_new_table },
560 { "newindex", lualib_new_index },
561 { "getstacktop", lualib_get_stack_top },
562 { "getruntime", lualib_get_runtime },
563 { "getcurrenttime", lualib_get_currenttime },
564 { "getpreciseticks", lualib_get_preciseticks },
565 { "getpreciseseconds", lualib_get_preciseseconds },
566 { "getbytecode", lualib_get_bytecode },
567 { "setbytecode", lualib_set_bytecode },
568 { "callbytecode", lualib_call_bytecode },
569 { "getfunctionstable", lualib_get_functions_table },
570 { "getstartupfile", lualib_get_startupfile },
571 { "getversion", lualib_get_version },
572
573 { "setexitcode", lualib_set_exitcode },
574 { "getexitcode", lualib_get_exitcode },
575
576 { "getdebuginfo", lualib_get_debug_info },
577 { NULL, NULL },
578};
579
580static const struct luaL_Reg lualib_function_list_only[] = {
581 { "newtable", lualib_new_table },
582 { "newindex", lualib_new_index },
583 { "getstacktop", lualib_get_stack_top },
584 { "getruntime", lualib_get_runtime },
585 { "getcurrenttime", lualib_get_currenttime },
586 { "getpreciseticks", lualib_get_preciseticks },
587 { "getpreciseseconds", lualib_get_preciseseconds },
588 { "getstartupfile", lualib_get_startupfile },
589 { "getversion", lualib_get_version },
590
591 { "setexitcode", lualib_set_exitcode },
592 { "getexitcode", lualib_get_exitcode },
593 { NULL, NULL },
594};
595
596static int lualib_index_bytecode(lua_State *L)
597{
598 lua_remove(L, 1);
599 return lualib_get_bytecode(L);
600}
601
602static int lualib_newindex_bytecode(lua_State *L)
603{
604 lua_remove(L, 1);
605 return lualib_set_bytecode(L);
606}
607
608int luaopen_lua(lua_State *L)
609{
610 lua_newtable(L);
611 if (lmt_engine_state.lua_only) {
612 luaL_setfuncs(L, lualib_function_list_only, 0);
613 } else {
614 luaL_setfuncs(L, lualib_function_list, 0);
615 lmt_make_table(L, "bytecode", LUA_BYTECODES, lualib_index_bytecode, lualib_newindex_bytecode);
616 lua_newtable(L);
617 lua_setfield(L, LUA_REGISTRYINDEX, LUA_BYTECODES_INDIRECT);
618 }
619 lua_pushstring(L, LUA_VERSION);
620 lua_setfield(L, -2, "version");
621 if (lmt_engine_state.startup_filename) {
622 lua_pushstring(L, lmt_engine_state.startup_filename);
623 lua_setfield(L, -2, "startupfile");
624 }
625 clock_inittime();
626 return 1;
627}
628 |