3 % Copyright
(C
) 1994-2007 Lua.org
, PUC-Rio. All rights reserved.
4 % Copyright
2006-2013 Taco Hoekwater
<taco@@luatex.org
>
6 % Permission is hereby granted
, free of charge
, to any person obtaining
7 % a copy of this software and associated documentation files
(the
8 % "Software"), to deal in the Software without restriction
, including
9 % without limitation the rights to use
, copy
, modify
, merge
, publish
,
10 % distribute
, sublicense
, and
/or sell copies of the Software
, and to
11 % permit persons to whom the Software is furnished to do so
, subject to
12 % the following conditions
:
14 % The above copyright notice and this permission notice shall be
15 % included in all copies or substantial portions of the Software.
17 % THE SOFTWARE
IS PROVIDED
"AS IS", WITHOUT WARRANTY
OF ANY KIND
,
18 % EXPRESS
OR IMPLIED
, INCLUDING BUT
NOT LIMITED
TO THE WARRANTIES
OF
19 % MERCHANTABILITY
, FITNESS
FOR A PARTICULAR PURPOSE
AND NONINFRINGEMENT.
20 % IN NO EVENT SHALL THE AUTHORS
OR COPYRIGHT HOLDERS BE LIABLE
FOR ANY
21 % CLAIM
, DAMAGES
OR OTHER LIABILITY
, WHETHER
IN AN ACTION
OF CONTRACT
,
22 % TORT
OR OTHERWISE, ARISING
FROM, OUT
OF OR IN CONNECTION
WITH THE
23 % SOFTWARE
OR THE
USE OR OTHER DEALINGS
IN THE SOFTWARE.
25 % This file is part of LuaTeX.
51 #include
"lua/luatex-api.h"
53 static void PrintFunction
(const Proto
* f
, int full
);
54 #define luaU_print PrintFunction
57 /* fix for non-gcc compilation
: */
58 #if
!defined
(__GNUC__
) ||
(__GNUC__
< 2)
59 # define __attribute__
(x
)
60 #endif
/* !defined
(__GNUC__
) ||
(__GNUC__
< 2) */
63 #define PROGNAME
"texluac" /* default program name
*/
64 #define
OUTPUT PROGNAME
".out" /* default output file
*/
66 static int listing
=0; /* list bytecodes?
*/
67 static int dumping
= 1; /* dump bytecodes?
*/
68 static int stripping
= 0; /* strip debug information?
*/
69 static char Output
[] = { OUTPUT }; /* default output file name
*/
71 static const char
*output
= Output
; /* actual output file name
*/
72 static const char
*progname
= PROGNAME
; /* actual program name
*/
75 __attribute__
((noreturn
))
76 static void fatal
(const char
*message
)
78 fprintf
(stderr
,"%s: %s\n",progname
,message
);
83 __attribute__
((noreturn
))
84 static void cannot
(const char
*what
)
86 fprintf
(stderr
,"%s: cannot %s %s: %s\n",progname
,what
,output
,strerror
(errno
));
91 __attribute__
((noreturn
))
92 static void usage
(const char
* message
)
95 fprintf
(stderr
,"%s: unrecognized option " LUA_QS
"\n",progname
,message
);
97 fprintf
(stderr
,"%s: %s\n",progname
,message
);
99 "usage: %s [options] [filenames]\n"
100 "Available options are:\n"
101 " -l list (use -l -l for full listing)\n"
102 " -o name output to file " LUA_QL
("name") " (default is \"%s\
")\n"
104 " -s strip debug information\n"
105 " -v show version information\n"
106 " -- stop handling options\n"
107 " - stop handling options and process stdin\n"
113 #define
IS(s
) (strcmp
(argv
[i
],s
)==0)
115 static int doargs
(int argc
, char
* argv
[])
119 if
(argv
[0]!=NULL && *argv[0]!=0) progname=argv[0];
120 for
(i
=1; i
<argc
; i
++)
122 if
(*argv
[i
]!='
-'
) /* end of options
; keep it
*/
124 else if
(IS("--")) /* end of options
; skip it
*/
127 if
(version
) ++version
;
130 else if
(IS("-")) /* end of options
; use stdin
*/
132 else if
(IS("-l")) /* list
*/
134 else if
(IS("-o")) /* output file
*/
137 if
(output
==NULL ||
*output
==0 ||
(*output
=='
-'
&& output[1]!=0))
138 usage
(LUA_QL
("-o") " needs argument");
139 if
(IS("-")) output
=NULL;
141 else if
(IS("-p")) /* parse only
*/
143 else if
(IS("-s")) /* strip debug information
*/
145 else if
(IS("-v")) /* show version
*/
147 else
/* unknown option
*/
150 if
(i
==argc
&& (listing || !dumping))
157 printf
("%s\n",LUA_COPYRIGHT
);
158 if
(version
==argc-1
) exit
(EXIT_SUCCESS
);
164 #define
FUNCTION "(function()end)();"
166 static const char
* reader
(lua_State
*L
, void
*ud
, size_t
*size
)
171 *size
=sizeof
(FUNCTION)-1;
181 #define toproto
(L
,i
) getproto
(L-
>top
+(i
))
183 static const Proto
* combine
(lua_State
* L
, int n
)
186 return toproto
(L
,-1);
191 if
(lua_load
(L
,reader
,&i,"=(" PROGNAME ")",NULL)!=LUA_OK) fatal(lua_tostring(L,-1));
195 f-
>p
[i
]=toproto
(L
,i-n-1
);
196 if
(f-
>p
[i
]->sizeupvalues
>0) f-
>p
[i
]->upvalues
[0].instack
=0;
204 static int writer
(lua_State
* L
, const void
* p
, size_t size
, void
* u
)
207 return
(fwrite
(p
,size
,1,(FILE*)u
)!=1) && (size!=0);
210 static int pmain
(lua_State
* L
)
212 int argc
=(int
)lua_tointeger
(L
,1);
213 char
** argv
=(char
**)lua_touserdata
(L
,2);
216 if
(!lua_checkstack
(L
,argc
)) fatal
("too many input files");
217 /* open standard libraries
: */
218 /* we need to to this to keep
*/
219 /* the symbol luaL_openlibs
*/
220 luaL_checkversion
(L
);
221 lua_gc
(L
, LUA_GCSTOP
, 0); /* stop collector during initialization
*/
222 luaL_openlibs
(L
); /* open libraries
*/
223 lua_gc
(L
, LUA_GCRESTART
, 0);
224 for
(i
=0; i
<argc
; i
++)
226 const char
* filename
=IS("-") ?
NULL : argv
[i
];
227 if
(luaL_loadfile
(L
,filename
)!=LUA_OK
) fatal
(lua_tostring
(L
,-1));
230 if
(listing
) luaU_print
(f
,listing
>1);
233 FILE* D
= (output
==NULL) ? stdout
: fopen
(output
,"wb");
234 if
(D
==NULL) cannot
("open");
236 luaU_dump
(L
,f
,writer
,D
,stripping
);
238 if
(ferror
(D
)) cannot
("write");
239 if
(fclose
(D
)) cannot
("close");
245 int luac_main
(int ac
, char
*av
[])
248 int i
= doargs
(ac
, av
);
252 usage
("no input files given");
255 fatal
("not enough memory for state");
256 lua_pushcfunction
(L
,&pmain);
257 lua_pushinteger
(L
,ac
);
258 lua_pushlightuserdata
(L
,av
);
259 if
(lua_pcall
(L
,2,0,0)!=LUA_OK
)
260 fatal
(lua_tostring
(L
,-1));
267 ** See Copyright Notice in lua.h
270 #define VOID
(p
) ((const void
*)(p
))
272 static void PrintString
(const TString
* ts
)
274 const char
* s
=getstr
(ts
);
275 size_t i
,n
=ts-
>tsv.len
;
279 int c=(int)(unsigned char)s[i];
282 case '"'
: printf
("\\\""); break;
283 case '\\': printf("\\\\
"); break;
284 case '\a': printf("\\a
"); break;
285 case '\b': printf("\\b
"); break;
286 case '\f': printf("\\f
"); break;
287 case '\n': printf("\\n
"); break;
288 case '\r': printf("\\r
"); break;
289 case '\t': printf("\\t
"); break;
290 case '\v': printf("\\v
"); break;
291 default: if (isprint(c))
300 static void PrintConstant
(const Proto
* f
, int i
)
302 const TValue
* o
=&f->k[i];
309 printf
(bvalue
(o
) ?
"true" : "false");
312 printf
(LUA_NUMBER_FMT
,nvalue
(o
));
315 PrintString
(rawtsvalue
(o
));
317 default
: /* cannot happen
*/
318 printf
("? type=%d",ttype
(o
));
323 #define UPVALNAME
(x
) ((f-
>upvalues
[x
].name
) ? getstr
(f-
>upvalues
[x
].name
) : "-")
324 #define MYK
(x
) (-1-(x
))
326 static void PrintCode
(const Proto
* f
)
328 const Instruction
* code
=f-
>code
;
329 int pc
,n
=f-
>sizecode
;
330 for
(pc
=0; pc
<n
; pc
++)
332 Instruction i
=code
[pc
];
333 OpCode o
=GET_OPCODE
(i
);
339 int sbx
=GETARG_sBx
(i
);
340 int line
=getfuncline
(f
,pc
);
341 printf
("\t%d\t",pc
+1);
342 if
(line
>0) printf
("[%d]\t",line
); else printf
("[-]\t");
343 printf
("%-9s\t",luaP_opnames
[o
]);
344 switch
(getOpMode
(o
))
348 if
(getBMode
(o
)!=OpArgN
) printf
(" %d",ISK
(b
) ?
(MYK
(INDEXK
(b
))) : b
);
349 if
(getCMode
(o
)!=OpArgN
) printf
(" %d",ISK
(c
) ?
(MYK
(INDEXK
(c
))) : c
);
353 if
(getBMode
(o
)==OpArgK
) printf
(" %d",MYK
(bx
));
354 if
(getBMode
(o
)==OpArgU
) printf
(" %d",bx
);
357 printf
("%d %d",a
,sbx
);
360 printf
("%d",MYK
(ax
));
366 printf
("\t; "); PrintConstant
(f
,bx
);
370 printf
("\t; %s",UPVALNAME
(b
));
373 printf
("\t; %s",UPVALNAME
(b
));
374 if
(ISK
(c
)) { printf
(" "); PrintConstant
(f
,INDEXK
(c
)); }
377 printf
("\t; %s",UPVALNAME
(a
));
378 if
(ISK
(b
)) { printf
(" "); PrintConstant
(f
,INDEXK
(b
)); }
379 if
(ISK
(c
)) { printf
(" "); PrintConstant
(f
,INDEXK
(c
)); }
383 if
(ISK
(c
)) { printf
("\t; "); PrintConstant
(f
,INDEXK
(c
)); }
394 if
(ISK
(b
) || ISK
(c
))
397 if
(ISK
(b
)) PrintConstant
(f
,INDEXK
(b
)); else printf
("-");
399 if
(ISK
(c
)) PrintConstant
(f
,INDEXK
(c
)); else printf
("-");
406 printf
("\t; to %d",sbx
+pc
+2);
409 printf
("\t; %p",VOID
(f-
>p
[bx
]));
412 if
(c
==0) printf
("\t; %d",(int
)code
[++pc
]); else printf
("\t; %d",c
);
415 printf
("\t; "); PrintConstant
(f
,ax
);
424 #define SS
(x
) ((x
==1)?
"":"s")
425 #define S
(x
) (int
)(x
),SS
(x
)
427 static void PrintHeader
(const Proto
* f
)
429 const char
* s
=f-
>source ? getstr
(f-
>source
) : "=?";
430 if
(*s
=='@@' ||
*s
=='
='
)
432 else if
(*s
==LUA_SIGNATURE
[0])
436 printf
("\n%s <%s:%d,%d> (%d instruction%s at %p)\n",
437 (f-
>linedefined
==0)?
"main":"function",s
,
438 f-
>linedefined
,f-
>lastlinedefined
,
439 S
(f-
>sizecode
),VOID
(f
));
440 printf
("%d%s param%s, %d slot%s, %d upvalue%s, ",
441 (int
)(f-
>numparams
),f-
>is_vararg?
"+":"",SS
(f-
>numparams
),
442 S
(f-
>maxstacksize
),S
(f-
>sizeupvalues
));
443 printf
("%d local%s, %d constant%s, %d function%s\n",
444 S
(f-
>sizelocvars
),S
(f-
>sizek
),S
(f-
>sizep
));
447 static void PrintDebug
(const Proto
* f
)
451 printf
("constants (%d) for %p:\n",n
,VOID
(f
));
454 printf
("\t%d\t",i
+1);
459 printf
("locals (%d) for %p:\n",n
,VOID
(f
));
462 printf
("\t%d\t%s\t%d\t%d\n",
463 i
,getstr
(f-
>locvars
[i
].varname
),f-
>locvars
[i
].startpc
+1,f-
>locvars
[i
].endpc
+1);
466 printf
("upvalues (%d) for %p:\n",n
,VOID
(f
));
469 printf
("\t%d\t%s\t%d\t%d\n",
470 i
,UPVALNAME
(i
),f-
>upvalues
[i
].instack
,f-
>upvalues
[i
].idx
);
474 static void PrintFunction
(const Proto
* f
, int full
)
479 if
(full
) PrintDebug
(f
);
480 for
(i
=0; i
<n
; i
++) PrintFunction
(f-
>p
[i
],full
);