3 % Copyright
2006-2013 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
/>.
22 #include
"lua/luatex-api.h"
23 #include
"lua/lauxlib_bridge.h"
26 lua_State
*Luas
= NULL;
28 int luastate_bytes
= 0;
32 void make_table
(lua_State
* L
, const char
*tab
, const char
*mttab
, const char
*getfunc
,
35 /* make the table
*//* |
[{<tex
>}]|
*/
36 lua_pushstring
(L
, tab
); /* |
[{<tex
>},"dimen"]|
*/
37 lua_newtable
(L
); /* |
[{<tex
>},"dimen",{}]|
*/
38 lua_settable
(L
, -3); /* |
[{<tex
>}]|
*/
40 lua_pushstring
(L
, tab
); /* |
[{<tex
>},"dimen"]|
*/
41 lua_gettable
(L
, -2); /* |
[{<tex
>},{<dimen
>}]|
*/
42 /* make the meta entries
*/
43 luaL_newmetatable
(L
, mttab
); /* |
[{<tex
>},{<dimen
>},{<dimen_m
>}]|
*/
44 lua_pushstring
(L
, "__index"); /* |
[{<tex
>},{<dimen
>},{<dimen_m
>},"__index"]|
*/
45 lua_pushstring
(L
, getfunc
); /* |
[{<tex
>},{<dimen
>},{<dimen_m
>},"__index","getdimen"]|
*/
46 lua_gettable
(L
, -5); /* |
[{<tex
>},{<dimen
>},{<dimen_m
>},"__index",<tex.getdimen
>]|
*/
47 lua_settable
(L
, -3); /* |
[{<tex
>},{<dimen
>},{<dimen_m
>}]|
*/
48 lua_pushstring
(L
, "__newindex"); /* |
[{<tex
>},{<dimen
>},{<dimen_m
>},"__newindex"]|
*/
49 lua_pushstring
(L
, setfunc
); /* |
[{<tex
>},{<dimen
>},{<dimen_m
>},"__newindex","setdimen"]|
*/
50 lua_gettable
(L
, -5); /* |
[{<tex
>},{<dimen
>},{<dimen_m
>},"__newindex",<tex.setdimen
>]|
*/
51 lua_settable
(L
, -3); /* |
[{<tex
>},{<dimen
>},{<dimen_m
>}]|
*/
52 lua_setmetatable
(L
, -2); /* |
[{<tex
>},{<dimen
>}]|
: assign the metatable
*/
53 lua_pop
(L
, 1); /* |
[{<tex
>}]|
: clean the stack
*/
57 static const char
*getS
(lua_State
* L
, void
*ud
, size_t
* size
)
59 LoadS
*ls
= (LoadS
*) ud
;
69 #if
0 /* currently unused
*/
70 static void
*my_luaalloc
(void
*ud
, void
*ptr
, size_t osize
, size_t nsize
)
73 (void
) ud
; /* for
-Wunused
*/
77 ret
= realloc
(ptr
, nsize
);
78 luastate_bytes
+= (int
) (nsize
- osize
);
84 static int my_luapanic
(lua_State
* L
)
86 (void
) L
; /* to avoid warnings
*/
87 fprintf
(stderr
, "PANIC: unprotected error in call to Lua API (%s)\n",
93 void luafunctioncall
(int slot
)
96 int stacktop
= lua_gettop
(Luas
);
98 lua_rawgeti
(Luas
, LUA_REGISTRYINDEX
, lua_key_index
(lua_functions
));
99 lua_gettable
(Luas
, LUA_REGISTRYINDEX
);
100 lua_rawgeti
(Luas
, -1,slot
);
101 if
(lua_isfunction
(Luas
,-1)) {
102 int base
= lua_gettop
(Luas
); /* function index
*/
103 lua_pushinteger
(Luas
, slot
);
104 lua_pushcfunction
(Luas
, lua_traceback
); /* push traceback function
*/
105 lua_insert
(Luas
, base
); /* put it under chunk
*/
106 i
= lua_pcall
(Luas
, 1, 0, base
);
107 lua_remove
(Luas
, base
); /* remove traceback function
*/
109 lua_gc
(Luas
, LUA_GCCOLLECT
, 0);
110 Luas
= luatex_error
(Luas
, (i
== LUA_ERRRUN ?
0 : 1));
113 lua_settop
(Luas
,stacktop
);
118 static const luaL_Reg lualibs
[] = {
120 {"package", luaopen_package
},
121 /*{"coroutine", luaopen_coroutine
},*/
122 {"table", luaopen_table
},
123 {"io", open_iolibext
},
125 {"string", luaopen_string
},
126 {"math", luaopen_math
},
127 {"debug", luaopen_debug
},
128 {"unicode", luaopen_unicode
},
129 {"zip", luaopen_zip
},
130 {"bit32", luaopen_bit32
},
131 {"md5", luaopen_md5
},
132 {"lfs", luaopen_lfs
},
133 {"profiler", luaopen_profiler
},
134 {"jit", luaopen_jit
},
135 {"ffi", luaopen_ffi
},
136 {"bit", luaopen_bit
},
140 static const luaL_Reg lualibs_nofenv
[] = {
141 {"lpeg", luaopen_lpeg
},
146 static void do_openlibs
(lua_State
* L
)
148 const luaL_Reg
*lib
= lualibs
;
149 for
(; lib-
>func
; lib
++) {
150 lua_pushcfunction
(L
, lib-
>func
);
151 lua_pushstring
(L
, lib-
>name
);
154 lib
= lualibs_nofenv
;
155 for
(; lib-
>func
; lib
++) {
156 lua_pushcfunction
(L
, lib-
>func
);
159 lua_pushstring
(L
, lib-
>name
);
165 static int load_aux
(lua_State
*L
, int status
) {
166 if
(status
== 0) /* OK?
*/
170 lua_insert
(L
, -2); /* put before error message
*/
171 return
2; /* return nil plus error message
*/
176 static int luatex_loadfile
(lua_State
*L
) {
178 const char
*fname
= luaL_optstring
(L
, 1, NULL);
179 const char
*mode
= luaL_optstring
(L
, 2, NULL);
180 int env
= !lua_isnone
(L
, 3); /* 'env' parameter?
*/
181 if
(!lua_only
&& !fname && interaction == batch_mode) {
183 lua_pushstring
(L
, "reading from stdin is disabled in batch mode");
184 return
2; /* return nil plus error message
*/
186 status
= luaL_loadfilex
(L
, fname
, mode
);
187 if
(status
== LUA_OK
) {
188 recorder_record_input
(fname
);
189 if
(env
) { /* 'env' parameter?
*/
191 lua_setupvalue
(L
, -2, 1); /* set it as
1st upvalue of loaded chunk
*/
194 return load_aux
(L
, status
);
198 static int luatex_dofile
(lua_State
*L
) {
199 const char
*fname
= luaL_optstring
(L
, 1, NULL);
200 int n
= lua_gettop
(L
);
201 if
(!lua_only
&& !fname) {
202 if
(interaction
== batch_mode
) {
204 lua_pushstring
(L
, "reading from stdin is disabled in batch mode");
205 return
2; /* return nil plus error message
*/
210 if
(luaL_loadfile
(L
, fname
) != 0) lua_error
(L
);
211 recorder_record_input
(fname
);
212 lua_call
(L
, 0, LUA_MULTRET
);
213 return lua_gettop
(L
) - n
;
217 void luainterpreter
(void
)
221 if
(jithash_hashname
==NULL){
223 luajittex_choose_hash_function
= 0;
224 jithash_hashname
= (char
*) xmalloc
(strlen
("lua51")+1);
225 jithash_hashname
= strcpy
( jithash_hashname
, "lua51");
227 if
(strcmp
((const char
*)jithash_hashname
,"lua51")==0){
228 luajittex_choose_hash_function
= 0;
229 }else if
(strcmp
((const char
*)jithash_hashname
,"luajit20")==0){
230 luajittex_choose_hash_function
= 1;
233 luajittex_choose_hash_function
= 0;
234 jithash_hashname
= strcpy
( jithash_hashname
, "lua51");
238 L
= luaL_newstate
() ;
239 /*L
= lua_newstate
(my_luaalloc
, NULL);*/
241 fprintf
(stderr
, "Can't create the Lua state.\n");
244 lua_atpanic
(L
, &my_luapanic);
246 do_openlibs
(L
); /* does all the 'simple' libraries
*/
249 luaJIT_setmode
(L
, 0, LUAJIT_MODE_ENGINE|LUAJIT_MODE_ON
);
252 luaJIT_setmode
(L
, 0, LUAJIT_MODE_ENGINE|LUAJIT_MODE_OFF
);
255 lua_pushcfunction
(L
,luatex_dofile
);
256 lua_setglobal
(L
, "dofile");
257 lua_pushcfunction
(L
,luatex_loadfile
);
258 lua_setglobal
(L
, "loadfile");
260 luatex_md5_lua_open
(L
);
262 open_oslibext
(L
, safer_option
);
270 /* socket and mime are a bit tricky to open because
271 they use a load-time dependency that has to be
272 worked around for luatex
, where the C module is
273 loaded way before the lua module.
275 if
(!nosocket_option
) {
276 lua_getglobal
(L
, "package");
277 lua_getfield
(L
, -1, "loaded");
278 if
(!lua_istable
(L
, -1)) {
280 lua_setfield
(L
, -2, "loaded");
281 lua_getfield
(L
, -1, "loaded");
283 luaopen_socket_core
(L
);
284 lua_setfield
(L
, -2, "socket.core");
286 lua_setfield
(L
, -2, "socket"); /* package.loaded.socket
= nil
*/
288 luaopen_mime_core
(L
);
289 lua_setfield
(L
, -2, "mime.core");
291 lua_setfield
(L
, -2, "mime"); /* package.loaded.mime
= nil
*/
292 lua_pop
(L
, 2); /* pop the tables
*/
294 luatex_socketlua_open
(L
); /* preload the pure lua modules
*/
296 /* zlib. slightly odd calling convention
*/
298 lua_setglobal
(L
, "zlib");
301 /* our own libraries
*/
309 luaopen_lua
(L
, startup_filename
);
316 /* |luaopen_pdf
(L
);|
*/
317 /* environment table at |LUA_ENVIRONINDEX| needs to load this way
: */
318 lua_pushcfunction
(L
, luaopen_pdf
);
319 lua_pushstring
(L
, "pdf");
323 /* |luaopen_img
(L
);|
*/
324 lua_pushcfunction
(L
, luaopen_img
);
325 lua_pushstring
(L
, "img");
329 /* |luaopen_epdf
(L
);|
*/
330 lua_pushcfunction
(L
, luaopen_epdf
);
331 lua_pushstring
(L
, "epdf");
334 /* |luaopen_pdfscanner
(L
);|
*/
335 lua_pushcfunction
(L
, luaopen_pdfscanner
);
336 lua_pushstring
(L
, "pdfscanner");
339 lua_createtable
(L
, 0, 0);
340 lua_setglobal
(L
, "texconfig");
343 /* disable some stuff if
--safer
*/
344 (void
) hide_lua_value
(L
, "os", "execute");
345 (void
) hide_lua_value
(L
, "os", "rename");
346 (void
) hide_lua_value
(L
, "os", "remove");
347 (void
) hide_lua_value
(L
, "io", "popen");
348 /* make io.open only read files
*/
349 luaL_checkstack
(L
, 2, "out of stack space");
350 lua_getglobal
(L
, "io");
351 lua_getfield
(L
, -1, "open_ro");
352 lua_setfield
(L
, -2, "open");
353 (void
) hide_lua_value
(L
, "io", "tmpfile");
354 (void
) hide_lua_value
(L
, "io", "output");
355 (void
) hide_lua_value
(L
, "lfs", "chdir");
356 (void
) hide_lua_value
(L
, "lfs", "lock");
357 (void
) hide_lua_value
(L
, "lfs", "touch");
358 (void
) hide_lua_value
(L
, "lfs", "rmdir");
359 (void
) hide_lua_value
(L
, "lfs", "mkdir");
361 /* fprintf
(stdout
, "\nLuajitTeX default hash function type:%s\n", */
362 /* jithash_hashname
); */
367 int hide_lua_table
(lua_State
* L
, const char
*name
)
370 lua_getglobal
(L
, name
);
371 if
(lua_istable
(L
, -1)) {
372 r
= luaL_ref
(L
, LUA_REGISTRYINDEX
);
374 lua_setglobal
(L
, name
);
380 void unhide_lua_table
(lua_State
* L
, const char
*name
, int r
)
382 lua_rawgeti
(L
, LUA_REGISTRYINDEX
, r
);
383 lua_setglobal
(L
, name
);
384 luaL_unref
(L
, LUA_REGISTRYINDEX
, r
);
388 int hide_lua_value
(lua_State
* L
, const char
*name
, const char
*item
)
391 lua_getglobal
(L
, name
);
392 if
(lua_istable
(L
, -1)) {
393 lua_getfield
(L
, -1, item
);
394 r
= luaL_ref
(L
, LUA_REGISTRYINDEX
);
396 lua_setfield
(L
, -2, item
);
402 void unhide_lua_value
(lua_State
* L
, const char
*name
, const char
*item
, int r
)
404 lua_getglobal
(L
, name
);
405 if
(lua_istable
(L
, -1)) {
406 lua_rawgeti
(L
, LUA_REGISTRYINDEX
, r
);
407 lua_setfield
(L
, -2, item
);
408 luaL_unref
(L
, LUA_REGISTRYINDEX
, r
);
413 int lua_traceback
(lua_State
* L
)
415 lua_getglobal
(L
, "debug");
416 if
(!lua_istable
(L
, -1)) {
420 lua_getfield
(L
, -1, "traceback");
421 if
(!lua_isfunction
(L
, -1)) {
425 lua_pushvalue
(L
, 1); /* pass error message
*/
426 lua_pushinteger
(L
, 2); /* skip this function and traceback
*/
427 lua_call
(L
, 2, 1); /* call debug.traceback
*/
432 static void luacall
(int p
, int nameptr
, boolean is_string
) /* hh-ls
: optimized lua_id resolving
*/
445 const char
*ss
= NULL;
446 lua_rawgeti
(Luas
, LUA_REGISTRYINDEX
, p
);
447 if
(lua_isfunction
(Luas
,-1)) {
448 int base
= lua_gettop
(Luas
); /* function index
*/
449 lua_checkstack
(Luas
, 1);
450 lua_pushcfunction
(Luas
, lua_traceback
); /* push traceback function
*/
451 lua_insert
(Luas
, base
); /* put it under chunk
*/
452 i
= lua_pcall
(Luas
, 0, 0, base
);
453 lua_remove
(Luas
, base
); /* remove traceback function
*/
455 lua_gc
(Luas
, LUA_GCCOLLECT
, 0);
456 Luas
= luatex_error
(Luas
, (i
== LUA_ERRRUN ?
0 : 1));
461 ss
= lua_tolstring
(Luas
, -1, &ll);
467 s
= tokenlist_to_cstring
(p
, 1, &l);
474 int l
= 0; /* not used
*/
475 lua_id
= tokenlist_to_cstring
(nameptr
, 1, &l);
476 i
= lua_load
(Luas
, getS
, &ls, lua_id);
478 } else if
(nameptr
< 0) {
479 lua_id
= get_lua_name
((nameptr
+ 65536));
480 if
(lua_id
!= NULL) {
481 i
= lua_load
(Luas
, getS
, &ls, lua_id);
483 i
= lua_load
(Luas
, getS
, &ls, "=[\\latelua]");
486 i
= lua_load
(Luas
, getS
, &ls, "=[\\latelua]");
489 Luas
= luatex_error
(Luas
, (i
== LUA_ERRSYNTAX ?
0 : 1));
491 int base
= lua_gettop
(Luas
); /* function index
*/
492 lua_checkstack
(Luas
, 1);
493 lua_pushcfunction
(Luas
, lua_traceback
); /* push traceback function
*/
494 lua_insert
(Luas
, base
); /* put it under chunk
*/
495 i
= lua_pcall
(Luas
, 0, 0, base
);
496 lua_remove
(Luas
, base
); /* remove traceback function
*/
498 lua_gc
(Luas
, LUA_GCCOLLECT
, 0);
499 Luas
= luatex_error
(Luas
, (i
== LUA_ERRRUN ?
0 : 1));
508 void late_lua
(PDF pdf
, halfword p
)
511 if
(late_lua_type
(p
)==normal
) {
512 expand_macros_in_tokenlist
(p
); /* sets |def_ref|
*/
513 luacall
(def_ref
, late_lua_name
(p
), false
);
516 luacall
(late_lua_data
(p
), late_lua_name
(p
), true
);
521 void luatokencall
(int p
, int nameptr
) /* hh-ls
: optimized lua_id resolving
*/
530 s
= tokenlist_to_cstring
(p
, 1, &l);
532 ls.size
= (size_t
) l
;
535 lua_id
= tokenlist_to_cstring
(nameptr
, 1, &l);
536 i
= lua_load
(Luas
, getS
, &ls, lua_id);
538 } else if
(nameptr
< 0) {
539 lua_id
= get_lua_name
((nameptr
+ 65536));
540 if
(lua_id
!= NULL) {
541 i
= lua_load
(Luas
, getS
, &ls, lua_id);
543 i
= lua_load
(Luas
, getS
, &ls, "=[\\directlua]");
546 i
= lua_load
(Luas
, getS
, &ls, "=[\\directlua]");
550 Luas
= luatex_error
(Luas
, (i
== LUA_ERRSYNTAX ?
0 : 1));
552 int base
= lua_gettop
(Luas
); /* function index
*/
553 lua_checkstack
(Luas
, 1);
554 lua_pushcfunction
(Luas
, lua_traceback
); /* push traceback function
*/
555 lua_insert
(Luas
, base
); /* put it under chunk
*/
556 i
= lua_pcall
(Luas
, 0, 0, base
);
557 lua_remove
(Luas
, base
); /* remove traceback function
*/
559 lua_gc
(Luas
, LUA_GCCOLLECT
, 0);
560 Luas
= luatex_error
(Luas
, (i
== LUA_ERRRUN ?
0 : 1));
568 lua_State
*luatex_error
(lua_State
* L
, int is_fatal
)
571 const_lstring luaerr
;
573 if
(lua_type
(L
, -1) == LUA_TSTRING
) {
574 luaerr.s
= lua_tolstring
(L
, -1, &luaerr.l);
575 /* free last one ?
*/
576 err
= (char
*) xmalloc
((unsigned
) (luaerr.l
+ 1));
577 snprintf
(err
, (luaerr.l
+ 1), "%s", luaerr.s
);
578 last_lua_error
= err
; /* hm
, what if we have several .. not freed
*/
581 /* Normally a memory error from lua.
582 The pool may overflow during the |maketexlstring
()|
, but we
583 are crashing anyway so we may as well abort on the pool size
*/
584 normal_error
("lua",err
);
587 return
(lua_State
*) NULL;
589 normal_warning
("lua",err
);
595 void preset_environment
(lua_State
* L
, const parm_struct
* p
, const char
*s
)
599 /* double call with same s gives assert
(0) */
600 lua_pushstring
(L
, s
); /* s
*/
601 lua_gettable
(L
, LUA_REGISTRYINDEX
); /* t
*/
602 assert
(lua_isnil
(L
, -1));
603 lua_pop
(L
, 1); /* - */
604 lua_pushstring
(L
, s
); /* s
*/
605 lua_newtable
(L
); /* t s
*/
606 for
(i
= 1, ++p
; p-
>name
!= NULL; i
++, p
++) {
608 lua_pushstring
(L
, p-
>name
); /* k t s
*/
609 lua_pushinteger
(L
, p-
>idx
); /* v k t s
*/
610 lua_settable
(L
, -3); /* t s
*/
612 lua_settable
(L
, LUA_REGISTRYINDEX
); /* - */
617 int luaL_typerror
(void
*LL
, int narg
, const char
*tname
)
619 lua_State
*L
= (lua_State
*)LL
;
620 const char
*msg
= lua_pushfstring
(L
, "%s expected, got %s",
621 tname
, luaL_typename
(L
, narg
));
622 return luaL_argerror
(L
, narg
, msg
);
627 Compatibility layer for luatex lua5.2
631 LUALIB_API void
*luaL_testudata
(lua_State
*L
, int ud
, const char
*tname
) {
632 void
*p
= lua_touserdata
(L
, ud
);
633 if
(p
!= NULL) { /* value is a userdata?
*/
634 if
(lua_getmetatable
(L
, ud
)) { /* does it have a metatable?
*/
635 luaL_getmetatable
(L
, tname
); /* get correct metatable
*/
636 if
(!lua_rawequal
(L
, -1, -2)) /* not the same?
*/
637 p
= NULL; /* value is a userdata with wrong metatable
*/
638 lua_pop
(L
, 2); /* remove both metatables
*/
642 return
NULL; /* value is not a userdata with a metatable
*/
647 /* It's not ok. See lua-users.org
/wiki
/CompatibilityWithLuaFive for another solution
*/
649 LUALIB_API void luaL_setfuncs
(lua_State
*L
, const luaL_Reg
*l
, int nup
) {
650 /*luaL_checkversion
(L
);*/
651 luaL_checkstack
(L
, nup
, "too many upvalues");
652 for
(; l-
>name
!= NULL; l
++) { /* fill the table with given functions
*/
654 for
(i
= 0; i
< nup
; i
++) /* copy upvalues to the top
*/
655 lua_pushvalue
(L
, -nup
);
656 lua_pushcclosure
(L
, l-
>func
, nup
); /* closure with those upvalues
*/
657 lua_setfield
(L
, -(nup
+ 2), l-
>name
);
659 lua_pop
(L
, nup
); /* remove upvalues
*/
663 LUALIB_API char
*luaL_prepbuffsize
(luaL_Buffer
*B
, size_t sz
) {
665 if
(sz
> LUAL_BUFFERSIZE
)
666 luaL_error
(L
, "buffer too large");
667 return luaL_prepbuffer
(B
) ;
671 LUA_API int lua_compare
(lua_State
*L
, int o1
, int o2
, int op
) {
674 lua_lock
(L
); /* may call tag method
*/
675 /* o1
= index2addr
(L
, index1
); */
676 /* o2
= index2addr
(L
, index2
); */
677 /*if
(isvalid
(o1
) && isvalid(o2)) {*/
679 case LUA_OPEQ
: i
= lua_equal
(L
, o1
, o2
); break
;
680 case LUA_OPLT
: i
= lua_lessthan
(L
, o1
, o2
); break
;
681 case LUA_OPLE
: i
= (lua_lessthan
(L
, o1
, o2
) || lua_equal
(L
, o1
, o2
)) ; break
;
682 default
: luaL_error
(L
, "invalid option");