Large diffs are not rendered by default.

Large diffs are not rendered by default.

Large diffs are not rendered by default.

Large diffs are not rendered by default.

Large diffs are not rendered by default.

Large diffs are not rendered by default.

@@ -0,0 +1,83 @@
/*
** DynASM encoding engine prototypes.
** Copyright (C) 2005-2013 Mike Pall. All rights reserved.
** Released under the MIT license. See dynasm.lua for full copyright notice.
*/

#ifndef _DASM_PROTO_H
#define _DASM_PROTO_H

#include <stddef.h>
#include <stdarg.h>

#define DASM_IDENT "DynASM 1.3.0"
#define DASM_VERSION 10300 /* 1.3.0 */

#ifndef Dst_DECL
#define Dst_DECL dasm_State **Dst
#endif

#ifndef Dst_REF
#define Dst_REF (*Dst)
#endif

#ifndef DASM_FDEF
#define DASM_FDEF extern
#endif

#ifndef DASM_M_GROW
#define DASM_M_GROW(ctx, t, p, sz, need) \
do { \
size_t _sz = (sz), _need = (need); \
if (_sz < _need) { \
if (_sz < 16) _sz = 16; \
while (_sz < _need) _sz += _sz; \
(p) = (t *)realloc((p), _sz); \
if ((p) == NULL) exit(1); \
(sz) = _sz; \
} \
} while(0)
#endif

#ifndef DASM_M_FREE
#define DASM_M_FREE(ctx, p, sz) free(p)
#endif

/* Internal DynASM encoder state. */
typedef struct dasm_State dasm_State;


/* Initialize and free DynASM state. */
DASM_FDEF void dasm_init(Dst_DECL, int maxsection);
DASM_FDEF void dasm_free(Dst_DECL);

/* Setup global array. Must be called before dasm_setup(). */
DASM_FDEF void dasm_setupglobal(Dst_DECL, void **gl, unsigned int maxgl);

/* Grow PC label array. Can be called after dasm_setup(), too. */
DASM_FDEF void dasm_growpc(Dst_DECL, unsigned int maxpc);

/* Setup encoder. */
DASM_FDEF void dasm_setup(Dst_DECL, const void *actionlist);

/* Feed encoder with actions. Calls are generated by pre-processor. */
DASM_FDEF void dasm_put(Dst_DECL, int start, ...);

/* Link sections and return the resulting size. */
DASM_FDEF int dasm_link(Dst_DECL, size_t *szp);

/* Encode sections into buffer. */
DASM_FDEF int dasm_encode(Dst_DECL, void *buffer);

/* Get PC label offset. */
DASM_FDEF int dasm_getpclabel(Dst_DECL, unsigned int pc);

#ifdef DASM_CHECKS
/* Optional sanity checker to call between isolated encoding steps. */
DASM_FDEF int dasm_checkstep(Dst_DECL, int secmatch);
#else
#define dasm_checkstep(a, b) 0
#endif


#endif /* _DASM_PROTO_H */
@@ -0,0 +1,12 @@
------------------------------------------------------------------------------
-- DynASM x64 module.
--
-- Copyright (C) 2005-2013 Mike Pall. All rights reserved.
-- See dynasm.lua for full copyright notice.
------------------------------------------------------------------------------
-- This module just sets 64 bit mode for the combined x86/x64 module.
-- All the interesting stuff is there.
------------------------------------------------------------------------------

x64 = true -- Using a global is an ugly, but effective solution.
return require("dasm_x86")

Large diffs are not rendered by default.

Large diffs are not rendered by default.

Large diffs are not rendered by default.

@@ -0,0 +1,88 @@
.TH luajit 1 "" "" "LuaJIT documentation"
.SH NAME
luajit \- Just-In-Time Compiler for the Lua Language
\fB
.SH SYNOPSIS
.B luajit
[\fIoptions\fR]... [\fIscript\fR [\fIargs\fR]...]
.SH "WEB SITE"
.IR http://luajit.org
.SH DESCRIPTION
.PP
This is the command-line program to run Lua programs with \fBLuaJIT\fR.
.PP
\fBLuaJIT\fR is a just-in-time (JIT) compiler for the Lua language.
The virtual machine (VM) is based on a fast interpreter combined with
a trace compiler. It can significantly improve the performance of Lua programs.
.PP
\fBLuaJIT\fR is API\- and ABI-compatible with the VM of the standard
Lua\ 5.1 interpreter. When embedding the VM into an application,
the built library can be used as a drop-in replacement.
.SH OPTIONS
.TP
.BI "\-e " chunk
Run the given chunk of Lua code.
.TP
.BI "\-l " library
Load the named library, just like \fBrequire("\fR\fIlibrary\fR\fB")\fR.
.TP
.BI "\-b " ...
Save or list bytecode. Run without arguments to get help on options.
.TP
.BI "\-j " command
Perform LuaJIT control command (optional space after \fB\-j\fR).
.TP
.BI "\-O" [opt]
Control LuaJIT optimizations.
.TP
.B "\-i"
Run in interactive mode.
.TP
.B "\-v"
Show \fBLuaJIT\fR version.
.TP
.B "\-E"
Ignore environment variables.
.TP
.B "\-\-"
Stop processing options.
.TP
.B "\-"
Read script from stdin instead.
.PP
After all options are processed, the given \fIscript\fR is run.
The arguments are passed in the global \fIarg\fR table.
.PP
Interactive mode is only entered, if no \fIscript\fR and no \fB\-e\fR
option is given. Interactive mode can be left with EOF (\fICtrl\-Z\fB).
.SH EXAMPLES
.TP
luajit hello.lua world

Prints "Hello world", assuming \fIhello.lua\fR contains:
.br
print("Hello", arg[1])
.TP
luajit \-e "local x=0; for i=1,1e9 do x=x+i end; print(x)"

Calculates the sum of the numbers from 1 to 1000000000.
.br
And finishes in a reasonable amount of time, too.
.TP
luajit \-jv \-e "for i=1,10 do for j=1,10 do for k=1,100 do end end end"

Runs some nested loops and shows the resulting traces.
.SH COPYRIGHT
.PP
\fBLuaJIT\fR is Copyright \(co 2005-2013 Mike Pall.
.br
\fBLuaJIT\fR is open source software, released under the MIT license.
.SH SEE ALSO
.PP
More details in the provided HTML docs or at:
.IR http://luajit.org
.br
More about the Lua language can be found at:
.IR http://lua.org/docs.html
.PP
lua(1)
@@ -0,0 +1,24 @@
# Package information for LuaJIT to be used by pkg-config.
majver=2
minver=0
relver=2
version=${majver}.${minver}.${relver}
abiver=5.1

prefix=/usr/local
exec_prefix=${prefix}
libdir=${exec_prefix}/lib
libname=luajit-${abiver}
includedir=${prefix}/include/luajit-${majver}.${minver}

INSTALL_LMOD=${prefix}/share/lua/${abiver}
INSTALL_CMOD=${prefix}/lib/lua/${abiver}

Name: LuaJIT
Description: Just-in-time compiler for Lua
URL: http://luajit.org
Version: ${version}
Requires:
Libs: -L${libdir} -l${libname}
Libs.private: -Wl,-E -lm -ldl
Cflags: -I${includedir}

Large diffs are not rendered by default.

@@ -0,0 +1,226 @@
lib_aux.o: lib_aux.c lua.h luaconf.h lauxlib.h lj_obj.h lj_def.h \
lj_arch.h lj_err.h lj_errmsg.h lj_state.h lj_trace.h lj_jit.h lj_ir.h \
lj_dispatch.h lj_bc.h lj_traceerr.h lj_lib.h lj_alloc.h
lib_base.o: lib_base.c lua.h luaconf.h lauxlib.h lualib.h lj_obj.h \
lj_def.h lj_arch.h lj_gc.h lj_err.h lj_errmsg.h lj_debug.h lj_str.h \
lj_tab.h lj_meta.h lj_state.h lj_ctype.h lj_cconv.h lj_bc.h lj_ff.h \
lj_ffdef.h lj_dispatch.h lj_jit.h lj_ir.h lj_char.h lj_strscan.h \
lj_lib.h lj_libdef.h
lib_bit.o: lib_bit.c lua.h luaconf.h lauxlib.h lualib.h lj_obj.h lj_def.h \
lj_arch.h lj_err.h lj_errmsg.h lj_str.h lj_lib.h lj_libdef.h
lib_debug.o: lib_debug.c lua.h luaconf.h lauxlib.h lualib.h lj_obj.h \
lj_def.h lj_arch.h lj_gc.h lj_err.h lj_errmsg.h lj_debug.h lj_lib.h \
lj_libdef.h
lib_ffi.o: lib_ffi.c lua.h luaconf.h lauxlib.h lualib.h lj_obj.h lj_def.h \
lj_arch.h lj_gc.h lj_err.h lj_errmsg.h lj_str.h lj_tab.h lj_meta.h \
lj_ctype.h lj_cparse.h lj_cdata.h lj_cconv.h lj_carith.h lj_ccall.h \
lj_ccallback.h lj_clib.h lj_ff.h lj_ffdef.h lj_lib.h lj_libdef.h
lib_init.o: lib_init.c lua.h luaconf.h lauxlib.h lualib.h lj_arch.h
lib_io.o: lib_io.c lua.h luaconf.h lauxlib.h lualib.h lj_obj.h lj_def.h \
lj_arch.h lj_err.h lj_errmsg.h lj_str.h lj_state.h lj_ff.h lj_ffdef.h \
lj_lib.h lj_libdef.h
lib_jit.o: lib_jit.c lua.h luaconf.h lauxlib.h lualib.h lj_arch.h \
lj_obj.h lj_def.h lj_err.h lj_errmsg.h lj_debug.h lj_str.h lj_tab.h \
lj_bc.h lj_ir.h lj_jit.h lj_ircall.h lj_iropt.h lj_target.h \
lj_target_*.h lj_dispatch.h lj_vm.h lj_vmevent.h lj_lib.h luajit.h \
lj_libdef.h
lib_math.o: lib_math.c lua.h luaconf.h lauxlib.h lualib.h lj_obj.h \
lj_def.h lj_arch.h lj_lib.h lj_vm.h lj_libdef.h
lib_os.o: lib_os.c lua.h luaconf.h lauxlib.h lualib.h lj_obj.h lj_def.h \
lj_arch.h lj_err.h lj_errmsg.h lj_lib.h lj_libdef.h
lib_package.o: lib_package.c lua.h luaconf.h lauxlib.h lualib.h lj_obj.h \
lj_def.h lj_arch.h lj_err.h lj_errmsg.h lj_lib.h
lib_string.o: lib_string.c lua.h luaconf.h lauxlib.h lualib.h lj_obj.h \
lj_def.h lj_arch.h lj_gc.h lj_err.h lj_errmsg.h lj_str.h lj_tab.h \
lj_meta.h lj_state.h lj_ff.h lj_ffdef.h lj_bcdump.h lj_lex.h lj_char.h \
lj_lib.h lj_libdef.h
lib_table.o: lib_table.c lua.h luaconf.h lauxlib.h lualib.h lj_obj.h \
lj_def.h lj_arch.h lj_gc.h lj_err.h lj_errmsg.h lj_tab.h lj_lib.h \
lj_libdef.h
lj_alloc.o: lj_alloc.c lj_def.h lua.h luaconf.h lj_arch.h lj_alloc.h
lj_api.o: lj_api.c lj_obj.h lua.h luaconf.h lj_def.h lj_arch.h lj_gc.h \
lj_err.h lj_errmsg.h lj_debug.h lj_str.h lj_tab.h lj_func.h lj_udata.h \
lj_meta.h lj_state.h lj_bc.h lj_frame.h lj_trace.h lj_jit.h lj_ir.h \
lj_dispatch.h lj_traceerr.h lj_vm.h lj_strscan.h
lj_asm.o: lj_asm.c lj_obj.h lua.h luaconf.h lj_def.h lj_arch.h lj_gc.h \
lj_str.h lj_tab.h lj_frame.h lj_bc.h lj_ctype.h lj_ir.h lj_jit.h \
lj_ircall.h lj_iropt.h lj_mcode.h lj_trace.h lj_dispatch.h lj_traceerr.h \
lj_snap.h lj_asm.h lj_vm.h lj_target.h lj_target_*.h lj_emit_*.h \
lj_asm_*.h
lj_bc.o: lj_bc.c lj_obj.h lua.h luaconf.h lj_def.h lj_arch.h lj_bc.h \
lj_bcdef.h
lj_bcread.o: lj_bcread.c lj_obj.h lua.h luaconf.h lj_def.h lj_arch.h \
lj_gc.h lj_err.h lj_errmsg.h lj_str.h lj_tab.h lj_bc.h lj_ctype.h \
lj_cdata.h lualib.h lj_lex.h lj_bcdump.h lj_state.h
lj_bcwrite.o: lj_bcwrite.c lj_obj.h lua.h luaconf.h lj_def.h lj_arch.h \
lj_gc.h lj_str.h lj_bc.h lj_ctype.h lj_dispatch.h lj_jit.h lj_ir.h \
lj_bcdump.h lj_lex.h lj_err.h lj_errmsg.h lj_vm.h
lj_carith.o: lj_carith.c lj_obj.h lua.h luaconf.h lj_def.h lj_arch.h \
lj_gc.h lj_err.h lj_errmsg.h lj_tab.h lj_meta.h lj_ctype.h lj_cconv.h \
lj_cdata.h lj_carith.h
lj_ccall.o: lj_ccall.c lj_obj.h lua.h luaconf.h lj_def.h lj_arch.h \
lj_gc.h lj_err.h lj_errmsg.h lj_str.h lj_tab.h lj_ctype.h lj_cconv.h \
lj_cdata.h lj_ccall.h lj_trace.h lj_jit.h lj_ir.h lj_dispatch.h lj_bc.h \
lj_traceerr.h
lj_ccallback.o: lj_ccallback.c lj_obj.h lua.h luaconf.h lj_def.h \
lj_arch.h lj_gc.h lj_err.h lj_errmsg.h lj_tab.h lj_state.h lj_frame.h \
lj_bc.h lj_ctype.h lj_cconv.h lj_ccall.h lj_ccallback.h lj_target.h \
lj_target_*.h lj_mcode.h lj_jit.h lj_ir.h lj_trace.h lj_dispatch.h \
lj_traceerr.h lj_vm.h
lj_cconv.o: lj_cconv.c lj_obj.h lua.h luaconf.h lj_def.h lj_arch.h \
lj_err.h lj_errmsg.h lj_tab.h lj_ctype.h lj_gc.h lj_cdata.h lj_cconv.h \
lj_ccallback.h
lj_cdata.o: lj_cdata.c lj_obj.h lua.h luaconf.h lj_def.h lj_arch.h \
lj_gc.h lj_err.h lj_errmsg.h lj_str.h lj_tab.h lj_ctype.h lj_cconv.h \
lj_cdata.h
lj_char.o: lj_char.c lj_char.h lj_def.h lua.h luaconf.h
lj_clib.o: lj_clib.c lj_obj.h lua.h luaconf.h lj_def.h lj_arch.h lj_gc.h \
lj_err.h lj_errmsg.h lj_tab.h lj_str.h lj_udata.h lj_ctype.h lj_cconv.h \
lj_cdata.h lj_clib.h
lj_cparse.o: lj_cparse.c lj_obj.h lua.h luaconf.h lj_def.h lj_arch.h \
lj_gc.h lj_err.h lj_errmsg.h lj_str.h lj_ctype.h lj_cparse.h lj_frame.h \
lj_bc.h lj_vm.h lj_char.h lj_strscan.h
lj_crecord.o: lj_crecord.c lj_obj.h lua.h luaconf.h lj_def.h lj_arch.h \
lj_err.h lj_errmsg.h lj_str.h lj_tab.h lj_frame.h lj_bc.h lj_ctype.h \
lj_gc.h lj_cdata.h lj_cparse.h lj_cconv.h lj_clib.h lj_ccall.h lj_ff.h \
lj_ffdef.h lj_ir.h lj_jit.h lj_ircall.h lj_iropt.h lj_trace.h \
lj_dispatch.h lj_traceerr.h lj_record.h lj_ffrecord.h lj_snap.h \
lj_crecord.h
lj_ctype.o: lj_ctype.c lj_obj.h lua.h luaconf.h lj_def.h lj_arch.h \
lj_gc.h lj_err.h lj_errmsg.h lj_str.h lj_tab.h lj_ctype.h lj_ccallback.h
lj_debug.o: lj_debug.c lj_obj.h lua.h luaconf.h lj_def.h lj_arch.h \
lj_err.h lj_errmsg.h lj_debug.h lj_str.h lj_tab.h lj_state.h lj_frame.h \
lj_bc.h lj_jit.h lj_ir.h
lj_dispatch.o: lj_dispatch.c lj_obj.h lua.h luaconf.h lj_def.h lj_arch.h \
lj_err.h lj_errmsg.h lj_func.h lj_str.h lj_tab.h lj_meta.h lj_debug.h \
lj_state.h lj_frame.h lj_bc.h lj_ff.h lj_ffdef.h lj_jit.h lj_ir.h \
lj_ccallback.h lj_ctype.h lj_gc.h lj_trace.h lj_dispatch.h lj_traceerr.h \
lj_vm.h luajit.h
lj_err.o: lj_err.c lj_obj.h lua.h luaconf.h lj_def.h lj_arch.h lj_err.h \
lj_errmsg.h lj_debug.h lj_str.h lj_func.h lj_state.h lj_frame.h lj_bc.h \
lj_ff.h lj_ffdef.h lj_trace.h lj_jit.h lj_ir.h lj_dispatch.h \
lj_traceerr.h lj_vm.h
lj_ffrecord.o: lj_ffrecord.c lj_obj.h lua.h luaconf.h lj_def.h lj_arch.h \
lj_err.h lj_errmsg.h lj_str.h lj_tab.h lj_frame.h lj_bc.h lj_ff.h \
lj_ffdef.h lj_ir.h lj_jit.h lj_ircall.h lj_iropt.h lj_trace.h \
lj_dispatch.h lj_traceerr.h lj_record.h lj_ffrecord.h lj_crecord.h \
lj_vm.h lj_strscan.h lj_recdef.h
lj_func.o: lj_func.c lj_obj.h lua.h luaconf.h lj_def.h lj_arch.h lj_gc.h \
lj_func.h lj_trace.h lj_jit.h lj_ir.h lj_dispatch.h lj_bc.h \
lj_traceerr.h lj_vm.h
lj_gc.o: lj_gc.c lj_obj.h lua.h luaconf.h lj_def.h lj_arch.h lj_gc.h \
lj_err.h lj_errmsg.h lj_str.h lj_tab.h lj_func.h lj_udata.h lj_meta.h \
lj_state.h lj_frame.h lj_bc.h lj_ctype.h lj_cdata.h lj_trace.h lj_jit.h \
lj_ir.h lj_dispatch.h lj_traceerr.h lj_vm.h
lj_gdbjit.o: lj_gdbjit.c lj_obj.h lua.h luaconf.h lj_def.h lj_arch.h \
lj_gc.h lj_err.h lj_errmsg.h lj_debug.h lj_frame.h lj_bc.h lj_jit.h \
lj_ir.h lj_dispatch.h
lj_ir.o: lj_ir.c lj_obj.h lua.h luaconf.h lj_def.h lj_arch.h lj_gc.h \
lj_str.h lj_tab.h lj_ir.h lj_jit.h lj_ircall.h lj_iropt.h lj_trace.h \
lj_dispatch.h lj_bc.h lj_traceerr.h lj_ctype.h lj_cdata.h lj_carith.h \
lj_vm.h lj_strscan.h lj_lib.h
lj_lex.o: lj_lex.c lj_obj.h lua.h luaconf.h lj_def.h lj_arch.h lj_gc.h \
lj_err.h lj_errmsg.h lj_str.h lj_tab.h lj_ctype.h lj_cdata.h lualib.h \
lj_state.h lj_lex.h lj_parse.h lj_char.h lj_strscan.h
lj_lib.o: lj_lib.c lauxlib.h lua.h luaconf.h lj_obj.h lj_def.h lj_arch.h \
lj_gc.h lj_err.h lj_errmsg.h lj_str.h lj_tab.h lj_func.h lj_bc.h \
lj_dispatch.h lj_jit.h lj_ir.h lj_vm.h lj_strscan.h lj_lib.h
lj_load.o: lj_load.c lua.h luaconf.h lauxlib.h lj_obj.h lj_def.h \
lj_arch.h lj_gc.h lj_err.h lj_errmsg.h lj_str.h lj_func.h lj_frame.h \
lj_bc.h lj_vm.h lj_lex.h lj_bcdump.h lj_parse.h
lj_mcode.o: lj_mcode.c lj_obj.h lua.h luaconf.h lj_def.h lj_arch.h \
lj_gc.h lj_jit.h lj_ir.h lj_mcode.h lj_trace.h lj_dispatch.h lj_bc.h \
lj_traceerr.h lj_vm.h
lj_meta.o: lj_meta.c lj_obj.h lua.h luaconf.h lj_def.h lj_arch.h lj_gc.h \
lj_err.h lj_errmsg.h lj_str.h lj_tab.h lj_meta.h lj_frame.h lj_bc.h \
lj_vm.h lj_strscan.h
lj_obj.o: lj_obj.c lj_obj.h lua.h luaconf.h lj_def.h lj_arch.h
lj_opt_dce.o: lj_opt_dce.c lj_obj.h lua.h luaconf.h lj_def.h lj_arch.h \
lj_ir.h lj_jit.h lj_iropt.h
lj_opt_fold.o: lj_opt_fold.c lj_obj.h lua.h luaconf.h lj_def.h lj_arch.h \
lj_str.h lj_tab.h lj_ir.h lj_jit.h lj_iropt.h lj_trace.h lj_dispatch.h \
lj_bc.h lj_traceerr.h lj_ctype.h lj_gc.h lj_carith.h lj_vm.h \
lj_strscan.h lj_folddef.h
lj_opt_loop.o: lj_opt_loop.c lj_obj.h lua.h luaconf.h lj_def.h lj_arch.h \
lj_err.h lj_errmsg.h lj_str.h lj_ir.h lj_jit.h lj_iropt.h lj_trace.h \
lj_dispatch.h lj_bc.h lj_traceerr.h lj_snap.h lj_vm.h
lj_opt_mem.o: lj_opt_mem.c lj_obj.h lua.h luaconf.h lj_def.h lj_arch.h \
lj_tab.h lj_ir.h lj_jit.h lj_iropt.h
lj_opt_narrow.o: lj_opt_narrow.c lj_obj.h lua.h luaconf.h lj_def.h \
lj_arch.h lj_bc.h lj_ir.h lj_jit.h lj_iropt.h lj_trace.h lj_dispatch.h \
lj_traceerr.h lj_vm.h lj_strscan.h
lj_opt_sink.o: lj_opt_sink.c lj_obj.h lua.h luaconf.h lj_def.h lj_arch.h \
lj_ir.h lj_jit.h lj_iropt.h lj_target.h lj_target_*.h
lj_opt_split.o: lj_opt_split.c lj_obj.h lua.h luaconf.h lj_def.h \
lj_arch.h lj_err.h lj_errmsg.h lj_str.h lj_ir.h lj_jit.h lj_ircall.h \
lj_iropt.h lj_vm.h
lj_parse.o: lj_parse.c lj_obj.h lua.h luaconf.h lj_def.h lj_arch.h \
lj_gc.h lj_err.h lj_errmsg.h lj_debug.h lj_str.h lj_tab.h lj_func.h \
lj_state.h lj_bc.h lj_ctype.h lj_lex.h lj_parse.h lj_vm.h lj_vmevent.h
lj_record.o: lj_record.c lj_obj.h lua.h luaconf.h lj_def.h lj_arch.h \
lj_err.h lj_errmsg.h lj_str.h lj_tab.h lj_meta.h lj_frame.h lj_bc.h \
lj_ctype.h lj_gc.h lj_ff.h lj_ffdef.h lj_ir.h lj_jit.h lj_ircall.h \
lj_iropt.h lj_trace.h lj_dispatch.h lj_traceerr.h lj_record.h \
lj_ffrecord.h lj_snap.h lj_vm.h
lj_snap.o: lj_snap.c lj_obj.h lua.h luaconf.h lj_def.h lj_arch.h lj_gc.h \
lj_tab.h lj_state.h lj_frame.h lj_bc.h lj_ir.h lj_jit.h lj_iropt.h \
lj_trace.h lj_dispatch.h lj_traceerr.h lj_snap.h lj_target.h \
lj_target_*.h lj_ctype.h lj_cdata.h
lj_state.o: lj_state.c lj_obj.h lua.h luaconf.h lj_def.h lj_arch.h \
lj_gc.h lj_err.h lj_errmsg.h lj_str.h lj_tab.h lj_func.h lj_meta.h \
lj_state.h lj_frame.h lj_bc.h lj_ctype.h lj_trace.h lj_jit.h lj_ir.h \
lj_dispatch.h lj_traceerr.h lj_vm.h lj_lex.h lj_alloc.h
lj_str.o: lj_str.c lj_obj.h lua.h luaconf.h lj_def.h lj_arch.h lj_gc.h \
lj_err.h lj_errmsg.h lj_str.h lj_state.h lj_char.h
lj_strscan.o: lj_strscan.c lj_obj.h lua.h luaconf.h lj_def.h lj_arch.h \
lj_char.h lj_strscan.h
lj_tab.o: lj_tab.c lj_obj.h lua.h luaconf.h lj_def.h lj_arch.h lj_gc.h \
lj_err.h lj_errmsg.h lj_tab.h
lj_trace.o: lj_trace.c lj_obj.h lua.h luaconf.h lj_def.h lj_arch.h \
lj_gc.h lj_err.h lj_errmsg.h lj_debug.h lj_str.h lj_frame.h lj_bc.h \
lj_state.h lj_ir.h lj_jit.h lj_iropt.h lj_mcode.h lj_trace.h \
lj_dispatch.h lj_traceerr.h lj_snap.h lj_gdbjit.h lj_record.h lj_asm.h \
lj_vm.h lj_vmevent.h lj_target.h lj_target_*.h
lj_udata.o: lj_udata.c lj_obj.h lua.h luaconf.h lj_def.h lj_arch.h \
lj_gc.h lj_udata.h
lj_vmevent.o: lj_vmevent.c lj_obj.h lua.h luaconf.h lj_def.h lj_arch.h \
lj_str.h lj_tab.h lj_state.h lj_dispatch.h lj_bc.h lj_jit.h lj_ir.h \
lj_vm.h lj_vmevent.h
lj_vmmath.o: lj_vmmath.c lj_obj.h lua.h luaconf.h lj_def.h lj_arch.h \
lj_ir.h lj_vm.h
ljamalg.o: ljamalg.c lua.h luaconf.h lauxlib.h lj_gc.c lj_obj.h lj_def.h \
lj_arch.h lj_gc.h lj_err.h lj_errmsg.h lj_str.h lj_tab.h lj_func.h \
lj_udata.h lj_meta.h lj_state.h lj_frame.h lj_bc.h lj_ctype.h lj_cdata.h \
lj_trace.h lj_jit.h lj_ir.h lj_dispatch.h lj_traceerr.h lj_vm.h lj_err.c \
lj_debug.h lj_ff.h lj_ffdef.h lj_char.c lj_char.h lj_bc.c lj_bcdef.h \
lj_obj.c lj_str.c lj_tab.c lj_func.c lj_udata.c lj_meta.c lj_strscan.h \
lj_debug.c lj_state.c lj_lex.h lj_alloc.h lj_dispatch.c lj_ccallback.h \
luajit.h lj_vmevent.c lj_vmevent.h lj_vmmath.c lj_strscan.c lj_api.c \
lj_lex.c lualib.h lj_parse.h lj_parse.c lj_bcread.c lj_bcdump.h \
lj_bcwrite.c lj_load.c lj_ctype.c lj_cdata.c lj_cconv.h lj_cconv.c \
lj_ccall.c lj_ccall.h lj_ccallback.c lj_target.h lj_target_*.h \
lj_mcode.h lj_carith.c lj_carith.h lj_clib.c lj_clib.h lj_cparse.c \
lj_cparse.h lj_lib.c lj_lib.h lj_ir.c lj_ircall.h lj_iropt.h \
lj_opt_mem.c lj_opt_fold.c lj_folddef.h lj_opt_narrow.c lj_opt_dce.c \
lj_opt_loop.c lj_snap.h lj_opt_split.c lj_opt_sink.c lj_mcode.c \
lj_snap.c lj_record.c lj_record.h lj_ffrecord.h lj_crecord.c \
lj_crecord.h lj_ffrecord.c lj_recdef.h lj_asm.c lj_asm.h lj_emit_*.h \
lj_asm_*.h lj_trace.c lj_gdbjit.h lj_gdbjit.c lj_alloc.c lib_aux.c \
lib_base.c lj_libdef.h lib_math.c lib_string.c lib_table.c lib_io.c \
lib_os.c lib_package.c lib_debug.c lib_bit.c lib_jit.c lib_ffi.c \
lib_init.c
luajit.o: luajit.c lua.h luaconf.h lauxlib.h lualib.h luajit.h lj_arch.h
host/buildvm.o: host/buildvm.c host/buildvm.h lj_def.h lua.h luaconf.h \
lj_arch.h lj_obj.h lj_def.h lj_arch.h lj_gc.h lj_obj.h lj_bc.h lj_ir.h \
lj_ircall.h lj_ir.h lj_jit.h lj_frame.h lj_bc.h lj_dispatch.h lj_ctype.h \
lj_gc.h lj_ccall.h lj_ctype.h luajit.h \
host/buildvm_arch.h lj_traceerr.h
host/buildvm_asm.o: host/buildvm_asm.c host/buildvm.h lj_def.h lua.h luaconf.h \
lj_arch.h lj_bc.h lj_def.h lj_arch.h
host/buildvm_fold.o: host/buildvm_fold.c host/buildvm.h lj_def.h lua.h \
luaconf.h lj_arch.h lj_obj.h lj_def.h lj_arch.h lj_ir.h lj_obj.h
host/buildvm_lib.o: host/buildvm_lib.c host/buildvm.h lj_def.h lua.h luaconf.h \
lj_arch.h lj_obj.h lj_def.h lj_arch.h lj_lib.h lj_obj.h
host/buildvm_peobj.o: host/buildvm_peobj.c host/buildvm.h lj_def.h lua.h \
luaconf.h lj_arch.h lj_bc.h lj_def.h lj_arch.h
host/minilua.o: host/minilua.c
@@ -0,0 +1,4 @@
The files in this directory are only used during the build process of LuaJIT.
For cross-compilation, they must be executed on the host, not on the target.

These files should NOT be installed!

Large diffs are not rendered by default.

@@ -0,0 +1,104 @@
/*
** LuaJIT VM builder.
** Copyright (C) 2005-2013 Mike Pall. See Copyright Notice in luajit.h
*/

#ifndef _BUILDVM_H
#define _BUILDVM_H

#include <sys/types.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <errno.h>

#include "lj_def.h"
#include "lj_arch.h"

/* Hardcoded limits. Increase as needed. */
#define BUILD_MAX_RELOC 200 /* Max. number of relocations. */
#define BUILD_MAX_FOLD 4096 /* Max. number of fold rules. */

/* Prefix for scanned library definitions. */
#define LIBDEF_PREFIX "LJLIB_"

/* Prefix for scanned fold definitions. */
#define FOLDDEF_PREFIX "LJFOLD"

/* Prefixes for generated labels. */
#define LABEL_PREFIX "lj_"
#define LABEL_PREFIX_BC LABEL_PREFIX "BC_"
#define LABEL_PREFIX_FF LABEL_PREFIX "ff_"
#define LABEL_PREFIX_CF LABEL_PREFIX "cf_"
#define LABEL_PREFIX_FFH LABEL_PREFIX "ffh_"
#define LABEL_PREFIX_LIBCF LABEL_PREFIX "lib_cf_"
#define LABEL_PREFIX_LIBINIT LABEL_PREFIX "lib_init_"

/* Forward declaration. */
struct dasm_State;

/* Build modes. */
#define BUILDDEF(_) \
_(elfasm) _(coffasm) _(machasm) _(peobj) _(raw) \
_(bcdef) _(ffdef) _(libdef) _(recdef) _(vmdef) \
_(folddef)

typedef enum {
#define BUILDENUM(name) BUILD_##name,
BUILDDEF(BUILDENUM)
#undef BUILDENUM
BUILD__MAX
} BuildMode;

/* Code relocation. */
typedef struct BuildReloc {
int32_t ofs;
int sym;
int type;
} BuildReloc;

typedef struct BuildSym {
const char *name;
int32_t ofs;
} BuildSym;

/* Build context structure. */
typedef struct BuildCtx {
/* DynASM state pointer. Should be first member. */
struct dasm_State *D;
/* Parsed command line. */
BuildMode mode;
FILE *fp;
const char *outname;
char **args;
/* Code and symbols generated by DynASM. */
uint8_t *code;
size_t codesz;
int npc, nglob, nsym, nreloc, nrelocsym;
void **glob;
BuildSym *sym;
const char **relocsym;
int32_t *bc_ofs;
const char *beginsym;
/* Strings generated by DynASM. */
const char *const *globnames;
const char *dasm_ident;
const char *dasm_arch;
/* Relocations. */
BuildReloc reloc[BUILD_MAX_RELOC];
} BuildCtx;

extern void owrite(BuildCtx *ctx, const void *ptr, size_t sz);
extern void emit_asm(BuildCtx *ctx);
extern void emit_peobj(BuildCtx *ctx);
extern void emit_lib(BuildCtx *ctx);
extern void emit_fold(BuildCtx *ctx);

extern const char *const bc_names[];
extern const char *const ir_names[];
extern const char *const irt_names[];
extern const char *const irfpm_names[];
extern const char *const irfield_names[];
extern const char *const ircall_names[];

#endif
@@ -0,0 +1,313 @@
/*
** LuaJIT VM builder: Assembler source code emitter.
** Copyright (C) 2005-2013 Mike Pall. See Copyright Notice in luajit.h
*/

#include "buildvm.h"
#include "lj_bc.h"

/* ------------------------------------------------------------------------ */

#if LJ_TARGET_X86ORX64
/* Emit bytes piecewise as assembler text. */
static void emit_asm_bytes(BuildCtx *ctx, uint8_t *p, int n)
{
int i;
for (i = 0; i < n; i++) {
if ((i & 15) == 0)
fprintf(ctx->fp, "\t.byte %d", p[i]);
else
fprintf(ctx->fp, ",%d", p[i]);
if ((i & 15) == 15) putc('\n', ctx->fp);
}
if ((n & 15) != 0) putc('\n', ctx->fp);
}

/* Emit relocation */
static void emit_asm_reloc(BuildCtx *ctx, int type, const char *sym)
{
switch (ctx->mode) {
case BUILD_elfasm:
if (type)
fprintf(ctx->fp, "\t.long %s-.-4\n", sym);
else
fprintf(ctx->fp, "\t.long %s\n", sym);
break;
case BUILD_coffasm:
fprintf(ctx->fp, "\t.def %s; .scl 3; .type 32; .endef\n", sym);
if (type)
fprintf(ctx->fp, "\t.long %s-.-4\n", sym);
else
fprintf(ctx->fp, "\t.long %s\n", sym);
break;
default: /* BUILD_machasm for relative relocations handled below. */
fprintf(ctx->fp, "\t.long %s\n", sym);
break;
}
}

static const char *const jccnames[] = {
"jo", "jno", "jb", "jnb", "jz", "jnz", "jbe", "ja",
"js", "jns", "jpe", "jpo", "jl", "jge", "jle", "jg"
};

/* Emit relocation for the incredibly stupid OSX assembler. */
static void emit_asm_reloc_mach(BuildCtx *ctx, uint8_t *cp, int n,
const char *sym)
{
const char *opname = NULL;
if (--n < 0) goto err;
if (cp[n] == 0xe8) {
opname = "call";
} else if (cp[n] == 0xe9) {
opname = "jmp";
} else if (cp[n] >= 0x80 && cp[n] <= 0x8f && n > 0 && cp[n-1] == 0x0f) {
opname = jccnames[cp[n]-0x80];
n--;
} else {
err:
fprintf(stderr, "Error: unsupported opcode for %s symbol relocation.\n",
sym);
exit(1);
}
emit_asm_bytes(ctx, cp, n);
fprintf(ctx->fp, "\t%s %s\n", opname, sym);
}
#else
/* Emit words piecewise as assembler text. */
static void emit_asm_words(BuildCtx *ctx, uint8_t *p, int n)
{
int i;
for (i = 0; i < n; i += 4) {
if ((i & 15) == 0)
fprintf(ctx->fp, "\t.long 0x%08x", *(uint32_t *)(p+i));
else
fprintf(ctx->fp, ",0x%08x", *(uint32_t *)(p+i));
if ((i & 15) == 12) putc('\n', ctx->fp);
}
if ((n & 15) != 0) putc('\n', ctx->fp);
}

/* Emit relocation as part of an instruction. */
static void emit_asm_wordreloc(BuildCtx *ctx, uint8_t *p, int n,
const char *sym)
{
uint32_t ins;
emit_asm_words(ctx, p, n-4);
ins = *(uint32_t *)(p+n-4);
#if LJ_TARGET_ARM
if ((ins & 0xff000000u) == 0xfa000000u) {
fprintf(ctx->fp, "\tblx %s\n", sym);
} else if ((ins & 0x0e000000u) == 0x0a000000u) {
fprintf(ctx->fp, "\t%s%.2s %s\n", (ins & 0x01000000u) ? "bl" : "b",
"eqnecsccmiplvsvchilsgeltgtle" + 2*(ins >> 28), sym);
} else {
fprintf(stderr,
"Error: unsupported opcode %08x for %s symbol relocation.\n",
ins, sym);
exit(1);
}
#elif LJ_TARGET_PPC || LJ_TARGET_PPCSPE
#if LJ_TARGET_PS3
#define TOCPREFIX "."
#else
#define TOCPREFIX ""
#endif
if ((ins >> 26) == 16) {
fprintf(ctx->fp, "\t%s %d, %d, " TOCPREFIX "%s\n",
(ins & 1) ? "bcl" : "bc", (ins >> 21) & 31, (ins >> 16) & 31, sym);
} else if ((ins >> 26) == 18) {
fprintf(ctx->fp, "\t%s " TOCPREFIX "%s\n", (ins & 1) ? "bl" : "b", sym);
} else {
fprintf(stderr,
"Error: unsupported opcode %08x for %s symbol relocation.\n",
ins, sym);
exit(1);
}
#elif LJ_TARGET_MIPS
fprintf(stderr,
"Error: unsupported opcode %08x for %s symbol relocation.\n",
ins, sym);
exit(1);
#else
#error "missing relocation support for this architecture"
#endif
}
#endif

#if LJ_TARGET_ARM
#define ELFASM_PX "%%"
#else
#define ELFASM_PX "@"
#endif

/* Emit an assembler label. */
static void emit_asm_label(BuildCtx *ctx, const char *name, int size, int isfunc)
{
switch (ctx->mode) {
case BUILD_elfasm:
#if LJ_TARGET_PS3
if (!strncmp(name, "lj_vm_", 6) &&
strcmp(name, ctx->beginsym) &&
!strstr(name, "hook")) {
fprintf(ctx->fp,
"\n\t.globl %s\n"
"\t.section \".opd\",\"aw\"\n"
"%s:\n"
"\t.long .%s,.TOC.@tocbase32\n"
"\t.size %s,8\n"
"\t.previous\n"
"\t.globl .%s\n"
"\t.hidden .%s\n"
"\t.type .%s, " ELFASM_PX "function\n"
"\t.size .%s, %d\n"
".%s:\n",
name, name, name, name, name, name, name, name, size, name);
break;
}
#endif
fprintf(ctx->fp,
"\n\t.globl %s\n"
"\t.hidden %s\n"
"\t.type %s, " ELFASM_PX "%s\n"
"\t.size %s, %d\n"
"%s:\n",
name, name, name, isfunc ? "function" : "object", name, size, name);
break;
case BUILD_coffasm:
fprintf(ctx->fp, "\n\t.globl %s\n", name);
if (isfunc)
fprintf(ctx->fp, "\t.def %s; .scl 3; .type 32; .endef\n", name);
fprintf(ctx->fp, "%s:\n", name);
break;
case BUILD_machasm:
fprintf(ctx->fp,
"\n\t.private_extern %s\n"
"%s:\n", name, name);
break;
default:
break;
}
}

/* Emit alignment. */
static void emit_asm_align(BuildCtx *ctx, int bits)
{
switch (ctx->mode) {
case BUILD_elfasm:
case BUILD_coffasm:
fprintf(ctx->fp, "\t.p2align %d\n", bits);
break;
case BUILD_machasm:
fprintf(ctx->fp, "\t.align %d\n", bits);
break;
default:
break;
}
}

/* ------------------------------------------------------------------------ */

/* Emit assembler source code. */
void emit_asm(BuildCtx *ctx)
{
int i, rel;

fprintf(ctx->fp, "\t.file \"buildvm_%s.dasc\"\n", ctx->dasm_arch);
fprintf(ctx->fp, "\t.text\n");
emit_asm_align(ctx, 4);

#if LJ_TARGET_PS3
emit_asm_label(ctx, ctx->beginsym, ctx->codesz, 0);
#else
emit_asm_label(ctx, ctx->beginsym, 0, 0);
#endif
if (ctx->mode != BUILD_machasm)
fprintf(ctx->fp, ".Lbegin:\n");

#if LJ_TARGET_ARM && defined(__GNUC__) && !LJ_NO_UNWIND
/* This should really be moved into buildvm_arm.dasc. */
fprintf(ctx->fp,
".fnstart\n"
".save {r4, r5, r6, r7, r8, r9, r10, r11, lr}\n"
".pad #28\n");
#endif
#if LJ_TARGET_MIPS
fprintf(ctx->fp, ".set nomips16\n.abicalls\n.set noreorder\n.set nomacro\n");
#endif

for (i = rel = 0; i < ctx->nsym; i++) {
int32_t ofs = ctx->sym[i].ofs;
int32_t next = ctx->sym[i+1].ofs;
#if LJ_TARGET_ARM && defined(__GNUC__) && !LJ_NO_UNWIND && LJ_HASFFI
if (!strcmp(ctx->sym[i].name, "lj_vm_ffi_call"))
fprintf(ctx->fp,
".globl lj_err_unwind_arm\n"
".personality lj_err_unwind_arm\n"
".fnend\n"
".fnstart\n"
".save {r4, r5, r11, lr}\n"
".setfp r11, sp\n");
#endif
emit_asm_label(ctx, ctx->sym[i].name, next - ofs, 1);
while (rel < ctx->nreloc && ctx->reloc[rel].ofs <= next) {
BuildReloc *r = &ctx->reloc[rel];
int n = r->ofs - ofs;
#if LJ_TARGET_X86ORX64
if (ctx->mode == BUILD_machasm && r->type != 0) {
emit_asm_reloc_mach(ctx, ctx->code+ofs, n, ctx->relocsym[r->sym]);
} else {
emit_asm_bytes(ctx, ctx->code+ofs, n);
emit_asm_reloc(ctx, r->type, ctx->relocsym[r->sym]);
}
ofs += n+4;
#else
emit_asm_wordreloc(ctx, ctx->code+ofs, n, ctx->relocsym[r->sym]);
ofs += n;
#endif
rel++;
}
#if LJ_TARGET_X86ORX64
emit_asm_bytes(ctx, ctx->code+ofs, next-ofs);
#else
emit_asm_words(ctx, ctx->code+ofs, next-ofs);
#endif
}

#if LJ_TARGET_ARM && defined(__GNUC__) && !LJ_NO_UNWIND
fprintf(ctx->fp,
#if !LJ_HASFFI
".globl lj_err_unwind_arm\n"
".personality lj_err_unwind_arm\n"
#endif
".fnend\n");
#endif

fprintf(ctx->fp, "\n");
switch (ctx->mode) {
case BUILD_elfasm:
#if !LJ_TARGET_PS3
fprintf(ctx->fp, "\t.section .note.GNU-stack,\"\"," ELFASM_PX "progbits\n");
#endif
#if LJ_TARGET_PPCSPE
/* Soft-float ABI + SPE. */
fprintf(ctx->fp, "\t.gnu_attribute 4, 2\n\t.gnu_attribute 8, 3\n");
#elif LJ_TARGET_PPC && !LJ_TARGET_PS3
/* Hard-float ABI. */
fprintf(ctx->fp, "\t.gnu_attribute 4, 1\n");
#endif
/* fallthrough */
case BUILD_coffasm:
fprintf(ctx->fp, "\t.ident \"%s\"\n", ctx->dasm_ident);
break;
case BUILD_machasm:
fprintf(ctx->fp,
"\t.cstring\n"
"\t.ascii \"%s\\0\"\n", ctx->dasm_ident);
break;
default:
break;
}
fprintf(ctx->fp, "\n");
}

@@ -0,0 +1,229 @@
/*
** LuaJIT VM builder: IR folding hash table generator.
** Copyright (C) 2005-2013 Mike Pall. See Copyright Notice in luajit.h
*/

#include "buildvm.h"
#include "lj_obj.h"
#include "lj_ir.h"

/* Context for the folding hash table generator. */
static int lineno;
static int funcidx;
static uint32_t foldkeys[BUILD_MAX_FOLD];
static uint32_t nkeys;

/* Try to fill the hash table with keys using the hash parameters. */
static int tryhash(uint32_t *htab, uint32_t sz, uint32_t r, int dorol)
{
uint32_t i;
if (dorol && ((r & 31) == 0 || (r>>5) == 0))
return 0; /* Avoid zero rotates. */
memset(htab, 0xff, (sz+1)*sizeof(uint32_t));
for (i = 0; i < nkeys; i++) {
uint32_t key = foldkeys[i];
uint32_t k = key & 0xffffff;
uint32_t h = (dorol ? lj_rol(lj_rol(k, r>>5) - k, r&31) :
(((k << (r>>5)) - k) << (r&31))) % sz;
if (htab[h] != 0xffffffff) { /* Collision on primary slot. */
if (htab[h+1] != 0xffffffff) { /* Collision on secondary slot. */
/* Try to move the colliding key, if possible. */
if (h < sz-1 && htab[h+2] == 0xffffffff) {
uint32_t k2 = htab[h+1] & 0xffffff;
uint32_t h2 = (dorol ? lj_rol(lj_rol(k2, r>>5) - k2, r&31) :
(((k2 << (r>>5)) - k2) << (r&31))) % sz;
if (h2 != h+1) return 0; /* Cannot resolve collision. */
htab[h+2] = htab[h+1]; /* Move colliding key to secondary slot. */
} else {
return 0; /* Collision. */
}
}
htab[h+1] = key;
} else {
htab[h] = key;
}
}
return 1; /* Success, all keys could be stored. */
}

/* Print the generated hash table. */
static void printhash(BuildCtx *ctx, uint32_t *htab, uint32_t sz)
{
uint32_t i;
fprintf(ctx->fp, "static const uint32_t fold_hash[%d] = {\n0x%08x",
sz+1, htab[0]);
for (i = 1; i < sz+1; i++)
fprintf(ctx->fp, ",\n0x%08x", htab[i]);
fprintf(ctx->fp, "\n};\n\n");
}

/* Exhaustive search for the shortest semi-perfect hash table. */
static void makehash(BuildCtx *ctx)
{
uint32_t htab[BUILD_MAX_FOLD*2+1];
uint32_t sz, r;
/* Search for the smallest hash table with an odd size. */
for (sz = (nkeys|1); sz < BUILD_MAX_FOLD*2; sz += 2) {
/* First try all shift hash combinations. */
for (r = 0; r < 32*32; r++) {
if (tryhash(htab, sz, r, 0)) {
printhash(ctx, htab, sz);
fprintf(ctx->fp,
"#define fold_hashkey(k)\t(((((k)<<%u)-(k))<<%u)%%%u)\n\n",
r>>5, r&31, sz);
return;
}
}
/* Then try all rotate hash combinations. */
for (r = 0; r < 32*32; r++) {
if (tryhash(htab, sz, r, 1)) {
printhash(ctx, htab, sz);
fprintf(ctx->fp,
"#define fold_hashkey(k)\t(lj_rol(lj_rol((k),%u)-(k),%u)%%%u)\n\n",
r>>5, r&31, sz);
return;
}
}
}
fprintf(stderr, "Error: search for perfect hash failed\n");
exit(1);
}

/* Parse one token of a fold rule. */
static uint32_t nexttoken(char **pp, int allowlit, int allowany)
{
char *p = *pp;
if (p) {
uint32_t i;
char *q = strchr(p, ' ');
if (q) *q++ = '\0';
*pp = q;
if (allowlit && !strncmp(p, "IRFPM_", 6)) {
for (i = 0; irfpm_names[i]; i++)
if (!strcmp(irfpm_names[i], p+6))
return i;
} else if (allowlit && !strncmp(p, "IRFL_", 5)) {
for (i = 0; irfield_names[i]; i++)
if (!strcmp(irfield_names[i], p+5))
return i;
} else if (allowlit && !strncmp(p, "IRCALL_", 7)) {
for (i = 0; ircall_names[i]; i++)
if (!strcmp(ircall_names[i], p+7))
return i;
} else if (allowlit && !strncmp(p, "IRCONV_", 7)) {
for (i = 0; irt_names[i]; i++) {
const char *r = strchr(p+7, '_');
if (r && !strncmp(irt_names[i], p+7, r-(p+7))) {
uint32_t j;
for (j = 0; irt_names[j]; j++)
if (!strcmp(irt_names[j], r+1))
return (i << 5) + j;
}
}
} else if (allowlit && *p >= '0' && *p <= '9') {
for (i = 0; *p >= '0' && *p <= '9'; p++)
i = i*10 + (*p - '0');
if (*p == '\0')
return i;
} else if (allowany && !strcmp("any", p)) {
return allowany;
} else {
for (i = 0; ir_names[i]; i++)
if (!strcmp(ir_names[i], p))
return i;
}
fprintf(stderr, "Error: bad fold definition token \"%s\" at line %d\n", p, lineno);
exit(1);
}
return 0;
}

/* Parse a fold rule. */
static void foldrule(char *p)
{
uint32_t op = nexttoken(&p, 0, 0);
uint32_t left = nexttoken(&p, 0, 0x7f);
uint32_t right = nexttoken(&p, 1, 0x3ff);
uint32_t key = (funcidx << 24) | (op << 17) | (left << 10) | right;
uint32_t i;
if (nkeys >= BUILD_MAX_FOLD) {
fprintf(stderr, "Error: too many fold rules, increase BUILD_MAX_FOLD.\n");
exit(1);
}
/* Simple insertion sort to detect duplicates. */
for (i = nkeys; i > 0; i--) {
if ((foldkeys[i-1]&0xffffff) < (key & 0xffffff))
break;
if ((foldkeys[i-1]&0xffffff) == (key & 0xffffff)) {
fprintf(stderr, "Error: duplicate fold definition at line %d\n", lineno);
exit(1);
}
foldkeys[i] = foldkeys[i-1];
}
foldkeys[i] = key;
nkeys++;
}

/* Emit C source code for IR folding hash table. */
void emit_fold(BuildCtx *ctx)
{
char buf[256]; /* We don't care about analyzing lines longer than that. */
const char *fname = ctx->args[0];
FILE *fp;

if (fname == NULL) {
fprintf(stderr, "Error: missing input filename\n");
exit(1);
}

if (fname[0] == '-' && fname[1] == '\0') {
fp = stdin;
} else {
fp = fopen(fname, "r");
if (!fp) {
fprintf(stderr, "Error: cannot open input file '%s': %s\n",
fname, strerror(errno));
exit(1);
}
}

fprintf(ctx->fp, "/* This is a generated file. DO NOT EDIT! */\n\n");
fprintf(ctx->fp, "static const FoldFunc fold_func[] = {\n");

lineno = 0;
funcidx = 0;
nkeys = 0;
while (fgets(buf, sizeof(buf), fp) != NULL) {
lineno++;
/* The prefix must be at the start of a line, otherwise it's ignored. */
if (!strncmp(buf, FOLDDEF_PREFIX, sizeof(FOLDDEF_PREFIX)-1)) {
char *p = buf+sizeof(FOLDDEF_PREFIX)-1;
char *q = strchr(p, ')');
if (p[0] == '(' && q) {
p++;
*q = '\0';
foldrule(p);
} else if ((p[0] == 'F' || p[0] == 'X') && p[1] == '(' && q) {
p += 2;
*q = '\0';
if (funcidx)
fprintf(ctx->fp, ",\n");
if (p[-2] == 'X')
fprintf(ctx->fp, " %s", p);
else
fprintf(ctx->fp, " fold_%s", p);
funcidx++;
} else {
buf[strlen(buf)-1] = '\0';
fprintf(stderr, "Error: unknown fold definition tag %s%s at line %d\n",
FOLDDEF_PREFIX, p, lineno);
exit(1);
}
}
}
fclose(fp);
fprintf(ctx->fp, "\n};\n\n");

makehash(ctx);
}

@@ -0,0 +1,398 @@
/*
** LuaJIT VM builder: library definition compiler.
** Copyright (C) 2005-2013 Mike Pall. See Copyright Notice in luajit.h
*/

#include "buildvm.h"
#include "lj_obj.h"
#include "lj_lib.h"

/* Context for library definitions. */
static uint8_t obuf[8192];
static uint8_t *optr;
static char modname[80];
static size_t modnamelen;
static char funcname[80];
static int modstate, regfunc;
static int ffid, recffid, ffasmfunc;

enum {
REGFUNC_OK,
REGFUNC_NOREG,
REGFUNC_NOREGUV
};

static void libdef_name(const char *p, int kind)
{
size_t n = strlen(p);
if (kind != LIBINIT_STRING) {
if (n > modnamelen && p[modnamelen] == '_' &&
!strncmp(p, modname, modnamelen)) {
p += modnamelen+1;
n -= modnamelen+1;
}
}
if (n > LIBINIT_MAXSTR) {
fprintf(stderr, "Error: string too long: '%s'\n", p);
exit(1);
}
if (optr+1+n+2 > obuf+sizeof(obuf)) { /* +2 for caller. */
fprintf(stderr, "Error: output buffer overflow\n");
exit(1);
}
*optr++ = (uint8_t)(n | kind);
memcpy(optr, p, n);
optr += n;
}

static void libdef_endmodule(BuildCtx *ctx)
{
if (modstate != 0) {
char line[80];
const uint8_t *p;
int n;
if (modstate == 1)
fprintf(ctx->fp, " (lua_CFunction)0");
fprintf(ctx->fp, "\n};\n");
fprintf(ctx->fp, "static const uint8_t %s%s[] = {\n",
LABEL_PREFIX_LIBINIT, modname);
line[0] = '\0';
for (n = 0, p = obuf; p < optr; p++) {
n += sprintf(line+n, "%d,", *p);
if (n >= 75) {
fprintf(ctx->fp, "%s\n", line);
n = 0;
line[0] = '\0';
}
}
fprintf(ctx->fp, "%s%d\n};\n#endif\n\n", line, LIBINIT_END);
}
}

static void libdef_module(BuildCtx *ctx, char *p, int arg)
{
UNUSED(arg);
if (ctx->mode == BUILD_libdef) {
libdef_endmodule(ctx);
optr = obuf;
*optr++ = (uint8_t)ffid;
*optr++ = (uint8_t)ffasmfunc;
*optr++ = 0; /* Hash table size. */
modstate = 1;
fprintf(ctx->fp, "#ifdef %sMODULE_%s\n", LIBDEF_PREFIX, p);
fprintf(ctx->fp, "#undef %sMODULE_%s\n", LIBDEF_PREFIX, p);
fprintf(ctx->fp, "static const lua_CFunction %s%s[] = {\n",
LABEL_PREFIX_LIBCF, p);
}
modnamelen = strlen(p);
if (modnamelen > sizeof(modname)-1) {
fprintf(stderr, "Error: module name too long: '%s'\n", p);
exit(1);
}
strcpy(modname, p);
}

static int find_ffofs(BuildCtx *ctx, const char *name)
{
int i;
for (i = 0; i < ctx->nglob; i++) {
const char *gl = ctx->globnames[i];
if (gl[0] == 'f' && gl[1] == 'f' && gl[2] == '_' && !strcmp(gl+3, name)) {
return (int)((uint8_t *)ctx->glob[i] - ctx->code);
}
}
fprintf(stderr, "Error: undefined fast function %s%s\n",
LABEL_PREFIX_FF, name);
exit(1);
}

static void libdef_func(BuildCtx *ctx, char *p, int arg)
{
if (arg != LIBINIT_CF)
ffasmfunc++;
if (ctx->mode == BUILD_libdef) {
if (modstate == 0) {
fprintf(stderr, "Error: no module for function definition %s\n", p);
exit(1);
}
if (regfunc == REGFUNC_NOREG) {
if (optr+1 > obuf+sizeof(obuf)) {
fprintf(stderr, "Error: output buffer overflow\n");
exit(1);
}
*optr++ = LIBINIT_FFID;
} else {
if (arg != LIBINIT_ASM_) {
if (modstate != 1) fprintf(ctx->fp, ",\n");
modstate = 2;
fprintf(ctx->fp, " %s%s", arg ? LABEL_PREFIX_FFH : LABEL_PREFIX_CF, p);
}
if (regfunc != REGFUNC_NOREGUV) obuf[2]++; /* Bump hash table size. */
libdef_name(regfunc == REGFUNC_NOREGUV ? "" : p, arg);
}
} else if (ctx->mode == BUILD_ffdef) {
fprintf(ctx->fp, "FFDEF(%s)\n", p);
} else if (ctx->mode == BUILD_recdef) {
if (strlen(p) > sizeof(funcname)-1) {
fprintf(stderr, "Error: function name too long: '%s'\n", p);
exit(1);
}
strcpy(funcname, p);
} else if (ctx->mode == BUILD_vmdef) {
int i;
for (i = 1; p[i] && modname[i-1]; i++)
if (p[i] == '_') p[i] = '.';
fprintf(ctx->fp, "\"%s\",\n", p);
} else if (ctx->mode == BUILD_bcdef) {
if (arg != LIBINIT_CF)
fprintf(ctx->fp, ",\n%d", find_ffofs(ctx, p));
}
ffid++;
regfunc = REGFUNC_OK;
}

static uint32_t find_rec(char *name)
{
char *p = (char *)obuf;
uint32_t n;
for (n = 2; *p; n++) {
if (strcmp(p, name) == 0)
return n;
p += strlen(p)+1;
}
if (p+strlen(name)+1 >= (char *)obuf+sizeof(obuf)) {
fprintf(stderr, "Error: output buffer overflow\n");
exit(1);
}
strcpy(p, name);
return n;
}

static void libdef_rec(BuildCtx *ctx, char *p, int arg)
{
UNUSED(arg);
if (ctx->mode == BUILD_recdef) {
char *q;
uint32_t n;
for (; recffid+1 < ffid; recffid++)
fprintf(ctx->fp, ",\n0");
recffid = ffid;
if (*p == '.') p = funcname;
q = strchr(p, ' ');
if (q) *q++ = '\0';
n = find_rec(p);
if (q)
fprintf(ctx->fp, ",\n0x%02x00+(%s)", n, q);
else
fprintf(ctx->fp, ",\n0x%02x00", n);
}
}

static void memcpy_endian(void *dst, void *src, size_t n)
{
union { uint8_t b; uint32_t u; } host_endian;
host_endian.u = 1;
if (host_endian.b == LJ_ENDIAN_SELECT(1, 0)) {
memcpy(dst, src, n);
} else {
size_t i;
for (i = 0; i < n; i++)
((uint8_t *)dst)[i] = ((uint8_t *)src)[n-i-1];
}
}

static void libdef_push(BuildCtx *ctx, char *p, int arg)
{
UNUSED(arg);
if (ctx->mode == BUILD_libdef) {
int len = (int)strlen(p);
if (*p == '"') {
if (len > 1 && p[len-1] == '"') {
p[len-1] = '\0';
libdef_name(p+1, LIBINIT_STRING);
return;
}
} else if (*p >= '0' && *p <= '9') {
char *ep;
double d = strtod(p, &ep);
if (*ep == '\0') {
if (optr+1+sizeof(double) > obuf+sizeof(obuf)) {
fprintf(stderr, "Error: output buffer overflow\n");
exit(1);
}
*optr++ = LIBINIT_NUMBER;
memcpy_endian(optr, &d, sizeof(double));
optr += sizeof(double);
return;
}
} else if (!strcmp(p, "lastcl")) {
if (optr+1 > obuf+sizeof(obuf)) {
fprintf(stderr, "Error: output buffer overflow\n");
exit(1);
}
*optr++ = LIBINIT_LASTCL;
return;
} else if (len > 4 && !strncmp(p, "top-", 4)) {
if (optr+2 > obuf+sizeof(obuf)) {
fprintf(stderr, "Error: output buffer overflow\n");
exit(1);
}
*optr++ = LIBINIT_COPY;
*optr++ = (uint8_t)atoi(p+4);
return;
}
fprintf(stderr, "Error: bad value for %sPUSH(%s)\n", LIBDEF_PREFIX, p);
exit(1);
}
}

static void libdef_set(BuildCtx *ctx, char *p, int arg)
{
UNUSED(arg);
if (ctx->mode == BUILD_libdef) {
if (p[0] == '!' && p[1] == '\0') p[0] = '\0'; /* Set env. */
libdef_name(p, LIBINIT_STRING);
*optr++ = LIBINIT_SET;
obuf[2]++; /* Bump hash table size. */
}
}

static void libdef_regfunc(BuildCtx *ctx, char *p, int arg)
{
UNUSED(ctx); UNUSED(p);
regfunc = arg;
}

typedef void (*LibDefFunc)(BuildCtx *ctx, char *p, int arg);

typedef struct LibDefHandler {
const char *suffix;
const char *stop;
const LibDefFunc func;
const int arg;
} LibDefHandler;

static const LibDefHandler libdef_handlers[] = {
{ "MODULE_", " \t\r\n", libdef_module, 0 },
{ "CF(", ")", libdef_func, LIBINIT_CF },
{ "ASM(", ")", libdef_func, LIBINIT_ASM },
{ "ASM_(", ")", libdef_func, LIBINIT_ASM_ },
{ "REC(", ")", libdef_rec, 0 },
{ "PUSH(", ")", libdef_push, 0 },
{ "SET(", ")", libdef_set, 0 },
{ "NOREGUV", NULL, libdef_regfunc, REGFUNC_NOREGUV },
{ "NOREG", NULL, libdef_regfunc, REGFUNC_NOREG },
{ NULL, NULL, (LibDefFunc)0, 0 }
};

/* Emit C source code for library function definitions. */
void emit_lib(BuildCtx *ctx)
{
const char *fname;

if (ctx->mode == BUILD_ffdef || ctx->mode == BUILD_libdef ||
ctx->mode == BUILD_recdef)
fprintf(ctx->fp, "/* This is a generated file. DO NOT EDIT! */\n\n");
else if (ctx->mode == BUILD_vmdef)
fprintf(ctx->fp, "ffnames = {\n[0]=\"Lua\",\n\"C\",\n");
if (ctx->mode == BUILD_recdef)
fprintf(ctx->fp, "static const uint16_t recff_idmap[] = {\n0,\n0x0100");
recffid = ffid = FF_C+1;
ffasmfunc = 0;

while ((fname = *ctx->args++)) {
char buf[256]; /* We don't care about analyzing lines longer than that. */
FILE *fp;
if (fname[0] == '-' && fname[1] == '\0') {
fp = stdin;
} else {
fp = fopen(fname, "r");
if (!fp) {
fprintf(stderr, "Error: cannot open input file '%s': %s\n",
fname, strerror(errno));
exit(1);
}
}
modstate = 0;
regfunc = REGFUNC_OK;
while (fgets(buf, sizeof(buf), fp) != NULL) {
char *p;
/* Simplistic pre-processor. Only handles top-level #if/#endif. */
if (buf[0] == '#' && buf[1] == 'i' && buf[2] == 'f') {
int ok = 1;
if (!strcmp(buf, "#if LJ_52\n"))
ok = LJ_52;
else if (!strcmp(buf, "#if LJ_HASJIT\n"))
ok = LJ_HASJIT;
else if (!strcmp(buf, "#if LJ_HASFFI\n"))
ok = LJ_HASFFI;
if (!ok) {
int lvl = 1;
while (fgets(buf, sizeof(buf), fp) != NULL) {
if (buf[0] == '#' && buf[1] == 'e' && buf[2] == 'n') {
if (--lvl == 0) break;
} else if (buf[0] == '#' && buf[1] == 'i' && buf[2] == 'f') {
lvl++;
}
}
continue;
}
}
for (p = buf; (p = strstr(p, LIBDEF_PREFIX)) != NULL; ) {
const LibDefHandler *ldh;
p += sizeof(LIBDEF_PREFIX)-1;
for (ldh = libdef_handlers; ldh->suffix != NULL; ldh++) {
size_t n, len = strlen(ldh->suffix);
if (!strncmp(p, ldh->suffix, len)) {
p += len;
n = ldh->stop ? strcspn(p, ldh->stop) : 0;
if (!p[n]) break;
p[n] = '\0';
ldh->func(ctx, p, ldh->arg);
p += n+1;
break;
}
}
if (ldh->suffix == NULL) {
buf[strlen(buf)-1] = '\0';
fprintf(stderr, "Error: unknown library definition tag %s%s\n",
LIBDEF_PREFIX, p);
exit(1);
}
}
}
fclose(fp);
if (ctx->mode == BUILD_libdef) {
libdef_endmodule(ctx);
}
}

if (ctx->mode == BUILD_ffdef) {
fprintf(ctx->fp, "\n#undef FFDEF\n\n");
fprintf(ctx->fp,
"#ifndef FF_NUM_ASMFUNC\n#define FF_NUM_ASMFUNC %d\n#endif\n\n",
ffasmfunc);
} else if (ctx->mode == BUILD_vmdef) {
fprintf(ctx->fp, "}\n\n");
} else if (ctx->mode == BUILD_bcdef) {
int i;
fprintf(ctx->fp, "\n};\n\n");
fprintf(ctx->fp, "LJ_DATADEF const uint16_t lj_bc_mode[] = {\n");
fprintf(ctx->fp, "BCDEF(BCMODE)\n");
for (i = ffasmfunc-1; i > 0; i--)
fprintf(ctx->fp, "BCMODE_FF,\n");
fprintf(ctx->fp, "BCMODE_FF\n};\n\n");
} else if (ctx->mode == BUILD_recdef) {
char *p = (char *)obuf;
fprintf(ctx->fp, "\n};\n\n");
fprintf(ctx->fp, "static const RecordFunc recff_func[] = {\n"
"recff_nyi,\n"
"recff_c");
while (*p) {
fprintf(ctx->fp, ",\nrecff_%s", p);
p += strlen(p)+1;
}
fprintf(ctx->fp, "\n};\n\n");
}
}

@@ -0,0 +1,368 @@
/*
** LuaJIT VM builder: PE object emitter.
** Copyright (C) 2005-2013 Mike Pall. See Copyright Notice in luajit.h
**
** Only used for building on Windows, since we cannot assume the presence
** of a suitable assembler. The host and target byte order must match.
*/

#include "buildvm.h"
#include "lj_bc.h"

#if LJ_TARGET_X86ORX64 || LJ_TARGET_PPC

/* Context for PE object emitter. */
static char *strtab;
static size_t strtabofs;

/* -- PE object definitions ----------------------------------------------- */

/* PE header. */
typedef struct PEheader {
uint16_t arch;
uint16_t nsects;
uint32_t time;
uint32_t symtabofs;
uint32_t nsyms;
uint16_t opthdrsz;
uint16_t flags;
} PEheader;

/* PE section. */
typedef struct PEsection {
char name[8];
uint32_t vsize;
uint32_t vaddr;
uint32_t size;
uint32_t ofs;
uint32_t relocofs;
uint32_t lineofs;
uint16_t nreloc;
uint16_t nline;
uint32_t flags;
} PEsection;

/* PE relocation. */
typedef struct PEreloc {
uint32_t vaddr;
uint32_t symidx;
uint16_t type;
} PEreloc;

/* Cannot use sizeof, because it pads up to the max. alignment. */
#define PEOBJ_RELOC_SIZE (4+4+2)

/* PE symbol table entry. */
typedef struct PEsym {
union {
char name[8];
uint32_t nameref[2];
} n;
uint32_t value;
int16_t sect;
uint16_t type;
uint8_t scl;
uint8_t naux;
} PEsym;

/* PE symbol table auxiliary entry for a section. */
typedef struct PEsymaux {
uint32_t size;
uint16_t nreloc;
uint16_t nline;
uint32_t cksum;
uint16_t assoc;
uint8_t comdatsel;
uint8_t unused[3];
} PEsymaux;

/* Cannot use sizeof, because it pads up to the max. alignment. */
#define PEOBJ_SYM_SIZE (8+4+2+2+1+1)

/* PE object CPU specific defines. */
#if LJ_TARGET_X86
#define PEOBJ_ARCH_TARGET 0x014c
#define PEOBJ_RELOC_REL32 0x14 /* MS: REL32, GNU: DISP32. */
#define PEOBJ_RELOC_DIR32 0x06
#define PEOBJ_RELOC_OFS 0
#define PEOBJ_TEXT_FLAGS 0x60500020 /* 60=r+x, 50=align16, 20=code. */
#elif LJ_TARGET_X64
#define PEOBJ_ARCH_TARGET 0x8664
#define PEOBJ_RELOC_REL32 0x04 /* MS: REL32, GNU: DISP32. */
#define PEOBJ_RELOC_DIR32 0x02
#define PEOBJ_RELOC_ADDR32NB 0x03
#define PEOBJ_RELOC_OFS 0
#define PEOBJ_TEXT_FLAGS 0x60500020 /* 60=r+x, 50=align16, 20=code. */
#elif LJ_TARGET_PPC
#define PEOBJ_ARCH_TARGET 0x01f2
#define PEOBJ_RELOC_REL32 0x06
#define PEOBJ_RELOC_DIR32 0x02
#define PEOBJ_RELOC_OFS (-4)
#define PEOBJ_TEXT_FLAGS 0x60400020 /* 60=r+x, 40=align8, 20=code. */
#endif

/* Section numbers (0-based). */
enum {
PEOBJ_SECT_ABS = -2,
PEOBJ_SECT_UNDEF = -1,
PEOBJ_SECT_TEXT,
#if LJ_TARGET_X64
PEOBJ_SECT_PDATA,
PEOBJ_SECT_XDATA,
#endif
PEOBJ_SECT_RDATA_Z,
PEOBJ_NSECTIONS
};

/* Symbol types. */
#define PEOBJ_TYPE_NULL 0
#define PEOBJ_TYPE_FUNC 0x20

/* Symbol storage class. */
#define PEOBJ_SCL_EXTERN 2
#define PEOBJ_SCL_STATIC 3

/* -- PE object emitter --------------------------------------------------- */

/* Emit PE object symbol. */
static void emit_peobj_sym(BuildCtx *ctx, const char *name, uint32_t value,
int sect, int type, int scl)
{
PEsym sym;
size_t len = strlen(name);
if (!strtab) { /* Pass 1: only calculate string table length. */
if (len > 8) strtabofs += len+1;
return;
}
if (len <= 8) {
memcpy(sym.n.name, name, len);
memset(sym.n.name+len, 0, 8-len);
} else {
sym.n.nameref[0] = 0;
sym.n.nameref[1] = (uint32_t)strtabofs;
memcpy(strtab + strtabofs, name, len);
strtab[strtabofs+len] = 0;
strtabofs += len+1;
}
sym.value = value;
sym.sect = (int16_t)(sect+1); /* 1-based section number. */
sym.type = (uint16_t)type;
sym.scl = (uint8_t)scl;
sym.naux = 0;
owrite(ctx, &sym, PEOBJ_SYM_SIZE);
}

/* Emit PE object section symbol. */
static void emit_peobj_sym_sect(BuildCtx *ctx, PEsection *pesect, int sect)
{
PEsym sym;
PEsymaux aux;
if (!strtab) return; /* Pass 1: no output. */
memcpy(sym.n.name, pesect[sect].name, 8);
sym.value = 0;
sym.sect = (int16_t)(sect+1); /* 1-based section number. */
sym.type = PEOBJ_TYPE_NULL;
sym.scl = PEOBJ_SCL_STATIC;
sym.naux = 1;
owrite(ctx, &sym, PEOBJ_SYM_SIZE);
memset(&aux, 0, sizeof(PEsymaux));
aux.size = pesect[sect].size;
aux.nreloc = pesect[sect].nreloc;
owrite(ctx, &aux, PEOBJ_SYM_SIZE);
}

/* Emit Windows PE object file. */
void emit_peobj(BuildCtx *ctx)
{
PEheader pehdr;
PEsection pesect[PEOBJ_NSECTIONS];
uint32_t sofs;
int i, nrsym;
union { uint8_t b; uint32_t u; } host_endian;

sofs = sizeof(PEheader) + PEOBJ_NSECTIONS*sizeof(PEsection);

/* Fill in PE sections. */
memset(&pesect, 0, PEOBJ_NSECTIONS*sizeof(PEsection));
memcpy(pesect[PEOBJ_SECT_TEXT].name, ".text", sizeof(".text")-1);
pesect[PEOBJ_SECT_TEXT].ofs = sofs;
sofs += (pesect[PEOBJ_SECT_TEXT].size = (uint32_t)ctx->codesz);
pesect[PEOBJ_SECT_TEXT].relocofs = sofs;
sofs += (pesect[PEOBJ_SECT_TEXT].nreloc = (uint16_t)ctx->nreloc) * PEOBJ_RELOC_SIZE;
/* Flags: 60 = read+execute, 50 = align16, 20 = code. */
pesect[PEOBJ_SECT_TEXT].flags = PEOBJ_TEXT_FLAGS;

#if LJ_TARGET_X64
memcpy(pesect[PEOBJ_SECT_PDATA].name, ".pdata", sizeof(".pdata")-1);
pesect[PEOBJ_SECT_PDATA].ofs = sofs;
sofs += (pesect[PEOBJ_SECT_PDATA].size = 6*4);
pesect[PEOBJ_SECT_PDATA].relocofs = sofs;
sofs += (pesect[PEOBJ_SECT_PDATA].nreloc = 6) * PEOBJ_RELOC_SIZE;
/* Flags: 40 = read, 30 = align4, 40 = initialized data. */
pesect[PEOBJ_SECT_PDATA].flags = 0x40300040;

memcpy(pesect[PEOBJ_SECT_XDATA].name, ".xdata", sizeof(".xdata")-1);
pesect[PEOBJ_SECT_XDATA].ofs = sofs;
sofs += (pesect[PEOBJ_SECT_XDATA].size = 8*2+4+6*2); /* See below. */
pesect[PEOBJ_SECT_XDATA].relocofs = sofs;
sofs += (pesect[PEOBJ_SECT_XDATA].nreloc = 1) * PEOBJ_RELOC_SIZE;
/* Flags: 40 = read, 30 = align4, 40 = initialized data. */
pesect[PEOBJ_SECT_XDATA].flags = 0x40300040;
#endif

memcpy(pesect[PEOBJ_SECT_RDATA_Z].name, ".rdata$Z", sizeof(".rdata$Z")-1);
pesect[PEOBJ_SECT_RDATA_Z].ofs = sofs;
sofs += (pesect[PEOBJ_SECT_RDATA_Z].size = (uint32_t)strlen(ctx->dasm_ident)+1);
/* Flags: 40 = read, 30 = align4, 40 = initialized data. */
pesect[PEOBJ_SECT_RDATA_Z].flags = 0x40300040;

/* Fill in PE header. */
pehdr.arch = PEOBJ_ARCH_TARGET;
pehdr.nsects = PEOBJ_NSECTIONS;
pehdr.time = 0; /* Timestamp is optional. */
pehdr.symtabofs = sofs;
pehdr.opthdrsz = 0;
pehdr.flags = 0;

/* Compute the size of the symbol table:
** @feat.00 + nsections*2
** + asm_start + nsym
** + nrsym
*/
nrsym = ctx->nrelocsym;
pehdr.nsyms = 1+PEOBJ_NSECTIONS*2 + 1+ctx->nsym + nrsym;
#if LJ_TARGET_X64
pehdr.nsyms += 1; /* Symbol for lj_err_unwind_win64. */
#endif

/* Write PE object header and all sections. */
owrite(ctx, &pehdr, sizeof(PEheader));
owrite(ctx, &pesect, sizeof(PEsection)*PEOBJ_NSECTIONS);

/* Write .text section. */
host_endian.u = 1;
if (host_endian.b != LJ_ENDIAN_SELECT(1, 0)) {
#if LJ_TARGET_PPC
uint32_t *p = (uint32_t *)ctx->code;
int n = (int)(ctx->codesz >> 2);
for (i = 0; i < n; i++, p++)
*p = lj_bswap(*p); /* Byteswap .text section. */
#else
fprintf(stderr, "Error: different byte order for host and target\n");
exit(1);
#endif
}
owrite(ctx, ctx->code, ctx->codesz);
for (i = 0; i < ctx->nreloc; i++) {
PEreloc reloc;
reloc.vaddr = (uint32_t)ctx->reloc[i].ofs + PEOBJ_RELOC_OFS;
reloc.symidx = 1+2+ctx->reloc[i].sym; /* Reloc syms are after .text sym. */
reloc.type = ctx->reloc[i].type ? PEOBJ_RELOC_REL32 : PEOBJ_RELOC_DIR32;
owrite(ctx, &reloc, PEOBJ_RELOC_SIZE);
}

#if LJ_TARGET_X64
{ /* Write .pdata section. */
uint32_t fcofs = (uint32_t)ctx->sym[ctx->nsym-1].ofs;
uint32_t pdata[3]; /* Start of .text, end of .text and .xdata. */
PEreloc reloc;
pdata[0] = 0; pdata[1] = fcofs; pdata[2] = 0;
owrite(ctx, &pdata, sizeof(pdata));
pdata[0] = fcofs; pdata[1] = (uint32_t)ctx->codesz; pdata[2] = 20;
owrite(ctx, &pdata, sizeof(pdata));
reloc.vaddr = 0; reloc.symidx = 1+2+nrsym+2+2+1;
reloc.type = PEOBJ_RELOC_ADDR32NB;
owrite(ctx, &reloc, PEOBJ_RELOC_SIZE);
reloc.vaddr = 4; reloc.symidx = 1+2+nrsym+2+2+1;
reloc.type = PEOBJ_RELOC_ADDR32NB;
owrite(ctx, &reloc, PEOBJ_RELOC_SIZE);
reloc.vaddr = 8; reloc.symidx = 1+2+nrsym+2;
reloc.type = PEOBJ_RELOC_ADDR32NB;
owrite(ctx, &reloc, PEOBJ_RELOC_SIZE);
reloc.vaddr = 12; reloc.symidx = 1+2+nrsym+2+2+1;
reloc.type = PEOBJ_RELOC_ADDR32NB;
owrite(ctx, &reloc, PEOBJ_RELOC_SIZE);
reloc.vaddr = 16; reloc.symidx = 1+2+nrsym+2+2+1;
reloc.type = PEOBJ_RELOC_ADDR32NB;
owrite(ctx, &reloc, PEOBJ_RELOC_SIZE);
reloc.vaddr = 20; reloc.symidx = 1+2+nrsym+2;
reloc.type = PEOBJ_RELOC_ADDR32NB;
owrite(ctx, &reloc, PEOBJ_RELOC_SIZE);
}
{ /* Write .xdata section. */
uint16_t xdata[8+2+6];
PEreloc reloc;
xdata[0] = 0x01|0x08|0x10; /* Ver. 1, uhandler/ehandler, prolog size 0. */
xdata[1] = 0x0005; /* Number of unwind codes, no frame pointer. */
xdata[2] = 0x4200; /* Stack offset 4*8+8 = aword*5. */
xdata[3] = 0x3000; /* Push rbx. */
xdata[4] = 0x6000; /* Push rsi. */
xdata[5] = 0x7000; /* Push rdi. */
xdata[6] = 0x5000; /* Push rbp. */
xdata[7] = 0; /* Alignment. */
xdata[8] = xdata[9] = 0; /* Relocated address of exception handler. */
xdata[10] = 0x01; /* Ver. 1, no handler, prolog size 0. */
xdata[11] = 0x1504; /* Number of unwind codes, fp = rbp, fpofs = 16. */
xdata[12] = 0x0300; /* set_fpreg. */
xdata[13] = 0x0200; /* stack offset 0*8+8 = aword*1. */
xdata[14] = 0x3000; /* Push rbx. */
xdata[15] = 0x5000; /* Push rbp. */
owrite(ctx, &xdata, sizeof(xdata));
reloc.vaddr = 2*8; reloc.symidx = 1+2+nrsym+2+2;
reloc.type = PEOBJ_RELOC_ADDR32NB;
owrite(ctx, &reloc, PEOBJ_RELOC_SIZE);
}
#endif

/* Write .rdata$Z section. */
owrite(ctx, ctx->dasm_ident, strlen(ctx->dasm_ident)+1);

/* Write symbol table. */
strtab = NULL; /* 1st pass: collect string sizes. */
for (;;) {
strtabofs = 4;
/* Mark as SafeSEH compliant. */
emit_peobj_sym(ctx, "@feat.00", 1,
PEOBJ_SECT_ABS, PEOBJ_TYPE_NULL, PEOBJ_SCL_STATIC);

emit_peobj_sym_sect(ctx, pesect, PEOBJ_SECT_TEXT);
for (i = 0; i < nrsym; i++)
emit_peobj_sym(ctx, ctx->relocsym[i], 0,
PEOBJ_SECT_UNDEF, PEOBJ_TYPE_FUNC, PEOBJ_SCL_EXTERN);

#if LJ_TARGET_X64
emit_peobj_sym_sect(ctx, pesect, PEOBJ_SECT_PDATA);
emit_peobj_sym_sect(ctx, pesect, PEOBJ_SECT_XDATA);
emit_peobj_sym(ctx, "lj_err_unwind_win64", 0,
PEOBJ_SECT_UNDEF, PEOBJ_TYPE_FUNC, PEOBJ_SCL_EXTERN);
#endif

emit_peobj_sym(ctx, ctx->beginsym, 0,
PEOBJ_SECT_TEXT, PEOBJ_TYPE_NULL, PEOBJ_SCL_EXTERN);
for (i = 0; i < ctx->nsym; i++)
emit_peobj_sym(ctx, ctx->sym[i].name, (uint32_t)ctx->sym[i].ofs,
PEOBJ_SECT_TEXT, PEOBJ_TYPE_FUNC, PEOBJ_SCL_EXTERN);

emit_peobj_sym_sect(ctx, pesect, PEOBJ_SECT_RDATA_Z);

if (strtab)
break;
/* 2nd pass: alloc strtab, write syms and copy strings. */
strtab = (char *)malloc(strtabofs);
*(uint32_t *)strtab = (uint32_t)strtabofs;
}

/* Write string table. */
owrite(ctx, strtab, strtabofs);
}

#else

void emit_peobj(BuildCtx *ctx)
{
UNUSED(ctx);
fprintf(stderr, "Error: no PE object support for this target\n");
exit(1);
}

#endif

Large diffs are not rendered by default.

Large diffs are not rendered by default.

@@ -0,0 +1,191 @@
----------------------------------------------------------------------------
-- LuaJIT bytecode listing module.
--
-- Copyright (C) 2005-2013 Mike Pall. All rights reserved.
-- Released under the MIT license. See Copyright Notice in luajit.h
----------------------------------------------------------------------------
--
-- This module lists the bytecode of a Lua function. If it's loaded by -jbc
-- it hooks into the parser and lists all functions of a chunk as they
-- are parsed.
--
-- Example usage:
--
-- luajit -jbc -e 'local x=0; for i=1,1e6 do x=x+i end; print(x)'
-- luajit -jbc=- foo.lua
-- luajit -jbc=foo.list foo.lua
--
-- Default output is to stderr. To redirect the output to a file, pass a
-- filename as an argument (use '-' for stdout) or set the environment
-- variable LUAJIT_LISTFILE. The file is overwritten every time the module
-- is started.
--
-- This module can also be used programmatically:
--
-- local bc = require("jit.bc")
--
-- local function foo() print("hello") end
--
-- bc.dump(foo) --> -- BYTECODE -- [...]
-- print(bc.line(foo, 2)) --> 0002 KSTR 1 1 ; "hello"
--
-- local out = {
-- -- Do something with each line:
-- write = function(t, ...) io.write(...) end,
-- close = function(t) end,
-- flush = function(t) end,
-- }
-- bc.dump(foo, out)
--
------------------------------------------------------------------------------

-- Cache some library functions and objects.
local jit = require("jit")
assert(jit.version_num == 20002, "LuaJIT core/library version mismatch")
local jutil = require("jit.util")
local vmdef = require("jit.vmdef")
local bit = require("bit")
local sub, gsub, format = string.sub, string.gsub, string.format
local byte, band, shr = string.byte, bit.band, bit.rshift
local funcinfo, funcbc, funck = jutil.funcinfo, jutil.funcbc, jutil.funck
local funcuvname = jutil.funcuvname
local bcnames = vmdef.bcnames
local stdout, stderr = io.stdout, io.stderr

------------------------------------------------------------------------------

local function ctlsub(c)
if c == "\n" then return "\\n"
elseif c == "\r" then return "\\r"
elseif c == "\t" then return "\\t"
else return format("\\%03d", byte(c))
end
end

-- Return one bytecode line.
local function bcline(func, pc, prefix)
local ins, m = funcbc(func, pc)
if not ins then return end
local ma, mb, mc = band(m, 7), band(m, 15*8), band(m, 15*128)
local a = band(shr(ins, 8), 0xff)
local oidx = 6*band(ins, 0xff)
local op = sub(bcnames, oidx+1, oidx+6)
local s = format("%04d %s %-6s %3s ",
pc, prefix or " ", op, ma == 0 and "" or a)
local d = shr(ins, 16)
if mc == 13*128 then -- BCMjump
return format("%s=> %04d\n", s, pc+d-0x7fff)
end
if mb ~= 0 then
d = band(d, 0xff)
elseif mc == 0 then
return s.."\n"
end
local kc
if mc == 10*128 then -- BCMstr
kc = funck(func, -d-1)
kc = format(#kc > 40 and '"%.40s"~' or '"%s"', gsub(kc, "%c", ctlsub))
elseif mc == 9*128 then -- BCMnum
kc = funck(func, d)
if op == "TSETM " then kc = kc - 2^52 end
elseif mc == 12*128 then -- BCMfunc
local fi = funcinfo(funck(func, -d-1))
if fi.ffid then
kc = vmdef.ffnames[fi.ffid]
else
kc = fi.loc
end
elseif mc == 5*128 then -- BCMuv
kc = funcuvname(func, d)
end
if ma == 5 then -- BCMuv
local ka = funcuvname(func, a)
if kc then kc = ka.." ; "..kc else kc = ka end
end
if mb ~= 0 then
local b = shr(ins, 24)
if kc then return format("%s%3d %3d ; %s\n", s, b, d, kc) end
return format("%s%3d %3d\n", s, b, d)
end
if kc then return format("%s%3d ; %s\n", s, d, kc) end
if mc == 7*128 and d > 32767 then d = d - 65536 end -- BCMlits
return format("%s%3d\n", s, d)
end

-- Collect branch targets of a function.
local function bctargets(func)
local target = {}
for pc=1,1000000000 do
local ins, m = funcbc(func, pc)
if not ins then break end
if band(m, 15*128) == 13*128 then target[pc+shr(ins, 16)-0x7fff] = true end
end
return target
end

-- Dump bytecode instructions of a function.
local function bcdump(func, out, all)
if not out then out = stdout end
local fi = funcinfo(func)
if all and fi.children then
for n=-1,-1000000000,-1 do
local k = funck(func, n)
if not k then break end
if type(k) == "proto" then bcdump(k, out, true) end
end
end
out:write(format("-- BYTECODE -- %s-%d\n", fi.loc, fi.lastlinedefined))
local target = bctargets(func)
for pc=1,1000000000 do
local s = bcline(func, pc, target[pc] and "=>")
if not s then break end
out:write(s)
end
out:write("\n")
out:flush()
end

------------------------------------------------------------------------------

-- Active flag and output file handle.
local active, out

-- List handler.
local function h_list(func)
return bcdump(func, out)
end

-- Detach list handler.
local function bclistoff()
if active then
active = false
jit.attach(h_list)
if out and out ~= stdout and out ~= stderr then out:close() end
out = nil
end
end

-- Open the output file and attach list handler.
local function bcliston(outfile)
if active then bclistoff() end
if not outfile then outfile = os.getenv("LUAJIT_LISTFILE") end
if outfile then
out = outfile == "-" and stdout or assert(io.open(outfile, "w"))
else
out = stderr
end
jit.attach(h_list, "bc")
active = true
end

-- Public module functions.
module(...)

line = bcline
dump = bcdump
targets = bctargets

on = bcliston
off = bclistoff
start = bcliston -- For -j command line option.

Large diffs are not rendered by default.

Large diffs are not rendered by default.

Large diffs are not rendered by default.

@@ -0,0 +1,20 @@
----------------------------------------------------------------------------
-- LuaJIT MIPSEL disassembler wrapper module.
--
-- Copyright (C) 2005-2013 Mike Pall. All rights reserved.
-- Released under the MIT license. See Copyright Notice in luajit.h
----------------------------------------------------------------------------
-- This module just exports the little-endian functions from the
-- MIPS disassembler module. All the interesting stuff is there.
------------------------------------------------------------------------------

local require = require

module(...)

local dis_mips = require(_PACKAGE.."dis_mips")

create = dis_mips.create_el
disass = dis_mips.disass_el
regname = dis_mips.regname

Large diffs are not rendered by default.

@@ -0,0 +1,20 @@
----------------------------------------------------------------------------
-- LuaJIT x64 disassembler wrapper module.
--
-- Copyright (C) 2005-2013 Mike Pall. All rights reserved.
-- Released under the MIT license. See Copyright Notice in luajit.h
----------------------------------------------------------------------------
-- This module just exports the 64 bit functions from the combined
-- x86/x64 disassembler module. All the interesting stuff is there.
------------------------------------------------------------------------------

local require = require

module(...)

local dis_x86 = require(_PACKAGE.."dis_x86")

create = dis_x86.create64
disass = dis_x86.disass64
regname = dis_x86.regname64

Large diffs are not rendered by default.

Large diffs are not rendered by default.

@@ -0,0 +1,167 @@
----------------------------------------------------------------------------
-- Verbose mode of the LuaJIT compiler.
--
-- Copyright (C) 2005-2013 Mike Pall. All rights reserved.
-- Released under the MIT license. See Copyright Notice in luajit.h
----------------------------------------------------------------------------
--
-- This module shows verbose information about the progress of the
-- JIT compiler. It prints one line for each generated trace. This module
-- is useful to see which code has been compiled or where the compiler
-- punts and falls back to the interpreter.
--
-- Example usage:
--
-- luajit -jv -e "for i=1,1000 do for j=1,1000 do end end"
-- luajit -jv=myapp.out myapp.lua
--
-- Default output is to stderr. To redirect the output to a file, pass a
-- filename as an argument (use '-' for stdout) or set the environment
-- variable LUAJIT_VERBOSEFILE. The file is overwritten every time the
-- module is started.
--
-- The output from the first example should look like this:
--
-- [TRACE 1 (command line):1 loop]
-- [TRACE 2 (1/3) (command line):1 -> 1]
--
-- The first number in each line is the internal trace number. Next are
-- the file name ('(command line)') and the line number (':1') where the
-- trace has started. Side traces also show the parent trace number and
-- the exit number where they are attached to in parentheses ('(1/3)').
-- An arrow at the end shows where the trace links to ('-> 1'), unless
-- it loops to itself.
--
-- In this case the inner loop gets hot and is traced first, generating
-- a root trace. Then the last exit from the 1st trace gets hot, too,
-- and triggers generation of the 2nd trace. The side trace follows the
-- path along the outer loop and *around* the inner loop, back to its
-- start, and then links to the 1st trace. Yes, this may seem unusual,
-- if you know how traditional compilers work. Trace compilers are full
-- of surprises like this -- have fun! :-)
--
-- Aborted traces are shown like this:
--
-- [TRACE --- foo.lua:44 -- leaving loop in root trace at foo:lua:50]
--
-- Don't worry -- trace aborts are quite common, even in programs which
-- can be fully compiled. The compiler may retry several times until it
-- finds a suitable trace.
--
-- Of course this doesn't work with features that are not-yet-implemented
-- (NYI error messages). The VM simply falls back to the interpreter. This
-- may not matter at all if the particular trace is not very high up in
-- the CPU usage profile. Oh, and the interpreter is quite fast, too.
--
-- Also check out the -jdump module, which prints all the gory details.
--
------------------------------------------------------------------------------

-- Cache some library functions and objects.
local jit = require("jit")
assert(jit.version_num == 20002, "LuaJIT core/library version mismatch")
local jutil = require("jit.util")
local vmdef = require("jit.vmdef")
local funcinfo, traceinfo = jutil.funcinfo, jutil.traceinfo
local type, format = type, string.format
local stdout, stderr = io.stdout, io.stderr

-- Active flag and output file handle.
local active, out

------------------------------------------------------------------------------

local startloc, startex

local function fmtfunc(func, pc)
local fi = funcinfo(func, pc)
if fi.loc then
return fi.loc
elseif fi.ffid then
return vmdef.ffnames[fi.ffid]
elseif fi.addr then
return format("C:%x", fi.addr)
else
return "(?)"
end
end

-- Format trace error message.
local function fmterr(err, info)
if type(err) == "number" then
if type(info) == "function" then info = fmtfunc(info) end
err = format(vmdef.traceerr[err], info)
end
return err
end

-- Dump trace states.
local function dump_trace(what, tr, func, pc, otr, oex)
if what == "start" then
startloc = fmtfunc(func, pc)
startex = otr and "("..otr.."/"..oex..") " or ""
else
if what == "abort" then
local loc = fmtfunc(func, pc)
if loc ~= startloc then
out:write(format("[TRACE --- %s%s -- %s at %s]\n",
startex, startloc, fmterr(otr, oex), loc))
else
out:write(format("[TRACE --- %s%s -- %s]\n",
startex, startloc, fmterr(otr, oex)))
end
elseif what == "stop" then
local info = traceinfo(tr)
local link, ltype = info.link, info.linktype
if ltype == "interpreter" then
out:write(format("[TRACE %3s %s%s -- fallback to interpreter]\n",
tr, startex, startloc))
elseif link == tr or link == 0 then
out:write(format("[TRACE %3s %s%s %s]\n",
tr, startex, startloc, ltype))
elseif ltype == "root" then
out:write(format("[TRACE %3s %s%s -> %d]\n",
tr, startex, startloc, link))
else
out:write(format("[TRACE %3s %s%s -> %d %s]\n",
tr, startex, startloc, link, ltype))
end
else
out:write(format("[TRACE %s]\n", what))
end
out:flush()
end
end

------------------------------------------------------------------------------

-- Detach dump handlers.
local function dumpoff()
if active then
active = false
jit.attach(dump_trace)
if out and out ~= stdout and out ~= stderr then out:close() end
out = nil
end
end

-- Open the output file and attach dump handlers.
local function dumpon(outfile)
if active then dumpoff() end
if not outfile then outfile = os.getenv("LUAJIT_VERBOSEFILE") end
if outfile then
out = outfile == "-" and stdout or assert(io.open(outfile, "w"))
else
out = stderr
end
jit.attach(dump_trace, "trace")
active = true
end

-- Public module functions.
module(...)

on = dumpon
off = dumpoff
start = dumpon -- For -j command line option.

@@ -0,0 +1,167 @@
/*
** $Id: lauxlib.h,v 1.88.1.1 2007/12/27 13:02:25 roberto Exp $
** Auxiliary functions for building Lua libraries
** See Copyright Notice in lua.h
*/


#ifndef lauxlib_h
#define lauxlib_h


#include <stddef.h>
#include <stdio.h>

#include "lua.h"


#define luaL_getn(L,i) ((int)lua_objlen(L, i))
#define luaL_setn(L,i,j) ((void)0) /* no op! */

/* extra error code for `luaL_load' */
#define LUA_ERRFILE (LUA_ERRERR+1)

typedef struct luaL_Reg {
const char *name;
lua_CFunction func;
} luaL_Reg;

LUALIB_API void (luaL_openlib) (lua_State *L, const char *libname,
const luaL_Reg *l, int nup);
LUALIB_API void (luaL_register) (lua_State *L, const char *libname,
const luaL_Reg *l);
LUALIB_API int (luaL_getmetafield) (lua_State *L, int obj, const char *e);
LUALIB_API int (luaL_callmeta) (lua_State *L, int obj, const char *e);
LUALIB_API int (luaL_typerror) (lua_State *L, int narg, const char *tname);
LUALIB_API int (luaL_argerror) (lua_State *L, int numarg, const char *extramsg);
LUALIB_API const char *(luaL_checklstring) (lua_State *L, int numArg,
size_t *l);
LUALIB_API const char *(luaL_optlstring) (lua_State *L, int numArg,
const char *def, size_t *l);
LUALIB_API lua_Number (luaL_checknumber) (lua_State *L, int numArg);
LUALIB_API lua_Number (luaL_optnumber) (lua_State *L, int nArg, lua_Number def);

LUALIB_API lua_Integer (luaL_checkinteger) (lua_State *L, int numArg);
LUALIB_API lua_Integer (luaL_optinteger) (lua_State *L, int nArg,
lua_Integer def);

LUALIB_API void (luaL_checkstack) (lua_State *L, int sz, const char *msg);
LUALIB_API void (luaL_checktype) (lua_State *L, int narg, int t);
LUALIB_API void (luaL_checkany) (lua_State *L, int narg);

LUALIB_API int (luaL_newmetatable) (lua_State *L, const char *tname);
LUALIB_API void *(luaL_checkudata) (lua_State *L, int ud, const char *tname);

LUALIB_API void (luaL_where) (lua_State *L, int lvl);
LUALIB_API int (luaL_error) (lua_State *L, const char *fmt, ...);

LUALIB_API int (luaL_checkoption) (lua_State *L, int narg, const char *def,
const char *const lst[]);

LUALIB_API int (luaL_ref) (lua_State *L, int t);
LUALIB_API void (luaL_unref) (lua_State *L, int t, int ref);

LUALIB_API int (luaL_loadfile) (lua_State *L, const char *filename);
LUALIB_API int (luaL_loadbuffer) (lua_State *L, const char *buff, size_t sz,
const char *name);
LUALIB_API int (luaL_loadstring) (lua_State *L, const char *s);

LUALIB_API lua_State *(luaL_newstate) (void);


LUALIB_API const char *(luaL_gsub) (lua_State *L, const char *s, const char *p,
const char *r);

LUALIB_API const char *(luaL_findtable) (lua_State *L, int idx,
const char *fname, int szhint);

/* From Lua 5.2. */
LUALIB_API int luaL_fileresult(lua_State *L, int stat, const char *fname);
LUALIB_API int luaL_execresult(lua_State *L, int stat);
LUALIB_API int (luaL_loadfilex) (lua_State *L, const char *filename,
const char *mode);
LUALIB_API int (luaL_loadbufferx) (lua_State *L, const char *buff, size_t sz,
const char *name, const char *mode);
LUALIB_API void luaL_traceback (lua_State *L, lua_State *L1, const char *msg,
int level);


/*
** ===============================================================
** some useful macros
** ===============================================================
*/

#define luaL_argcheck(L, cond,numarg,extramsg) \
((void)((cond) || luaL_argerror(L, (numarg), (extramsg))))
#define luaL_checkstring(L,n) (luaL_checklstring(L, (n), NULL))
#define luaL_optstring(L,n,d) (luaL_optlstring(L, (n), (d), NULL))
#define luaL_checkint(L,n) ((int)luaL_checkinteger(L, (n)))
#define luaL_optint(L,n,d) ((int)luaL_optinteger(L, (n), (d)))
#define luaL_checklong(L,n) ((long)luaL_checkinteger(L, (n)))
#define luaL_optlong(L,n,d) ((long)luaL_optinteger(L, (n), (d)))

#define luaL_typename(L,i) lua_typename(L, lua_type(L,(i)))

#define luaL_dofile(L, fn) \
(luaL_loadfile(L, fn) || lua_pcall(L, 0, LUA_MULTRET, 0))

#define luaL_dostring(L, s) \
(luaL_loadstring(L, s) || lua_pcall(L, 0, LUA_MULTRET, 0))

#define luaL_getmetatable(L,n) (lua_getfield(L, LUA_REGISTRYINDEX, (n)))

#define luaL_opt(L,f,n,d) (lua_isnoneornil(L,(n)) ? (d) : f(L,(n)))

/*
** {======================================================
** Generic Buffer manipulation
** =======================================================
*/



typedef struct luaL_Buffer {
char *p; /* current position in buffer */
int lvl; /* number of strings in the stack (level) */
lua_State *L;
char buffer[LUAL_BUFFERSIZE];
} luaL_Buffer;

#define luaL_addchar(B,c) \
((void)((B)->p < ((B)->buffer+LUAL_BUFFERSIZE) || luaL_prepbuffer(B)), \
(*(B)->p++ = (char)(c)))

/* compatibility only */
#define luaL_putchar(B,c) luaL_addchar(B,c)

#define luaL_addsize(B,n) ((B)->p += (n))

LUALIB_API void (luaL_buffinit) (lua_State *L, luaL_Buffer *B);
LUALIB_API char *(luaL_prepbuffer) (luaL_Buffer *B);
LUALIB_API void (luaL_addlstring) (luaL_Buffer *B, const char *s, size_t l);
LUALIB_API void (luaL_addstring) (luaL_Buffer *B, const char *s);
LUALIB_API void (luaL_addvalue) (luaL_Buffer *B);
LUALIB_API void (luaL_pushresult) (luaL_Buffer *B);


/* }====================================================== */


/* compatibility with ref system */

/* pre-defined references */
#define LUA_NOREF (-2)
#define LUA_REFNIL (-1)

#define lua_ref(L,lock) ((lock) ? luaL_ref(L, LUA_REGISTRYINDEX) : \
(lua_pushstring(L, "unlocked references are obsolete"), lua_error(L), 0))

#define lua_unref(L,ref) luaL_unref(L, LUA_REGISTRYINDEX, (ref))

#define lua_getref(L,ref) lua_rawgeti(L, LUA_REGISTRYINDEX, (ref))


#define luaL_reg luaL_Reg

#endif
@@ -0,0 +1,356 @@
/*
** Auxiliary library for the Lua/C API.
** Copyright (C) 2005-2013 Mike Pall. See Copyright Notice in luajit.h
**
** Major parts taken verbatim or adapted from the Lua interpreter.
** Copyright (C) 1994-2008 Lua.org, PUC-Rio. See Copyright Notice in lua.h
*/

#include <errno.h>
#include <stdarg.h>
#include <stdio.h>

#define lib_aux_c
#define LUA_LIB

#include "lua.h"
#include "lauxlib.h"

#include "lj_obj.h"
#include "lj_err.h"
#include "lj_state.h"
#include "lj_trace.h"
#include "lj_lib.h"

#if LJ_TARGET_POSIX
#include <sys/wait.h>
#endif

/* -- I/O error handling -------------------------------------------------- */

LUALIB_API int luaL_fileresult(lua_State *L, int stat, const char *fname)
{
if (stat) {
setboolV(L->top++, 1);
return 1;
} else {
int en = errno; /* Lua API calls may change this value. */
setnilV(L->top++);
if (fname)
lua_pushfstring(L, "%s: %s", fname, strerror(en));
else
lua_pushfstring(L, "%s", strerror(en));
setintV(L->top++, en);
lj_trace_abort(G(L));
return 3;
}
}

LUALIB_API int luaL_execresult(lua_State *L, int stat)
{
if (stat != -1) {
#if LJ_TARGET_POSIX
if (WIFSIGNALED(stat)) {
stat = WTERMSIG(stat);
setnilV(L->top++);
lua_pushliteral(L, "signal");
} else {
if (WIFEXITED(stat))
stat = WEXITSTATUS(stat);
if (stat == 0)
setboolV(L->top++, 1);
else
setnilV(L->top++);
lua_pushliteral(L, "exit");
}
#else
if (stat == 0)
setboolV(L->top++, 1);
else
setnilV(L->top++);
lua_pushliteral(L, "exit");
#endif
setintV(L->top++, stat);
return 3;
}
return luaL_fileresult(L, 0, NULL);
}

/* -- Module registration ------------------------------------------------- */

LUALIB_API const char *luaL_findtable(lua_State *L, int idx,
const char *fname, int szhint)
{
const char *e;
lua_pushvalue(L, idx);
do {
e = strchr(fname, '.');
if (e == NULL) e = fname + strlen(fname);
lua_pushlstring(L, fname, (size_t)(e - fname));
lua_rawget(L, -2);
if (lua_isnil(L, -1)) { /* no such field? */
lua_pop(L, 1); /* remove this nil */
lua_createtable(L, 0, (*e == '.' ? 1 : szhint)); /* new table for field */
lua_pushlstring(L, fname, (size_t)(e - fname));
lua_pushvalue(L, -2);
lua_settable(L, -4); /* set new table into field */
} else if (!lua_istable(L, -1)) { /* field has a non-table value? */
lua_pop(L, 2); /* remove table and value */
return fname; /* return problematic part of the name */
}
lua_remove(L, -2); /* remove previous table */
fname = e + 1;
} while (*e == '.');
return NULL;
}

static int libsize(const luaL_Reg *l)
{
int size = 0;
for (; l->name; l++) size++;
return size;
}

LUALIB_API void luaL_openlib(lua_State *L, const char *libname,
const luaL_Reg *l, int nup)
{
lj_lib_checkfpu(L);
if (libname) {
int size = libsize(l);
/* check whether lib already exists */
luaL_findtable(L, LUA_REGISTRYINDEX, "_LOADED", 16);
lua_getfield(L, -1, libname); /* get _LOADED[libname] */
if (!lua_istable(L, -1)) { /* not found? */
lua_pop(L, 1); /* remove previous result */
/* try global variable (and create one if it does not exist) */
if (luaL_findtable(L, LUA_GLOBALSINDEX, libname, size) != NULL)
lj_err_callerv(L, LJ_ERR_BADMODN, libname);
lua_pushvalue(L, -1);
lua_setfield(L, -3, libname); /* _LOADED[libname] = new table */
}
lua_remove(L, -2); /* remove _LOADED table */
lua_insert(L, -(nup+1)); /* move library table to below upvalues */
}
for (; l->name; l++) {
int i;
for (i = 0; i < nup; i++) /* copy upvalues to the top */
lua_pushvalue(L, -nup);
lua_pushcclosure(L, l->func, nup);
lua_setfield(L, -(nup+2), l->name);
}
lua_pop(L, nup); /* remove upvalues */
}

LUALIB_API void luaL_register(lua_State *L, const char *libname,
const luaL_Reg *l)
{
luaL_openlib(L, libname, l, 0);
}

LUALIB_API const char *luaL_gsub(lua_State *L, const char *s,
const char *p, const char *r)
{
const char *wild;
size_t l = strlen(p);
luaL_Buffer b;
luaL_buffinit(L, &b);
while ((wild = strstr(s, p)) != NULL) {
luaL_addlstring(&b, s, (size_t)(wild - s)); /* push prefix */
luaL_addstring(&b, r); /* push replacement in place of pattern */
s = wild + l; /* continue after `p' */
}
luaL_addstring(&b, s); /* push last suffix */
luaL_pushresult(&b);
return lua_tostring(L, -1);
}

/* -- Buffer handling ----------------------------------------------------- */

#define bufflen(B) ((size_t)((B)->p - (B)->buffer))
#define bufffree(B) ((size_t)(LUAL_BUFFERSIZE - bufflen(B)))

static int emptybuffer(luaL_Buffer *B)
{
size_t l = bufflen(B);
if (l == 0)
return 0; /* put nothing on stack */
lua_pushlstring(B->L, B->buffer, l);
B->p = B->buffer;
B->lvl++;
return 1;
}

static void adjuststack(luaL_Buffer *B)
{
if (B->lvl > 1) {
lua_State *L = B->L;
int toget = 1; /* number of levels to concat */
size_t toplen = lua_strlen(L, -1);
do {
size_t l = lua_strlen(L, -(toget+1));
if (!(B->lvl - toget + 1 >= LUA_MINSTACK/2 || toplen > l))
break;
toplen += l;
toget++;
} while (toget < B->lvl);
lua_concat(L, toget);
B->lvl = B->lvl - toget + 1;
}
}

LUALIB_API char *luaL_prepbuffer(luaL_Buffer *B)
{
if (emptybuffer(B))
adjuststack(B);
return B->buffer;
}

LUALIB_API void luaL_addlstring(luaL_Buffer *B, const char *s, size_t l)
{
while (l--)
luaL_addchar(B, *s++);
}

LUALIB_API void luaL_addstring(luaL_Buffer *B, const char *s)
{
luaL_addlstring(B, s, strlen(s));
}

LUALIB_API void luaL_pushresult(luaL_Buffer *B)
{
emptybuffer(B);
lua_concat(B->L, B->lvl);
B->lvl = 1;
}

LUALIB_API void luaL_addvalue(luaL_Buffer *B)
{
lua_State *L = B->L;
size_t vl;
const char *s = lua_tolstring(L, -1, &vl);
if (vl <= bufffree(B)) { /* fit into buffer? */
memcpy(B->p, s, vl); /* put it there */
B->p += vl;
lua_pop(L, 1); /* remove from stack */
} else {
if (emptybuffer(B))
lua_insert(L, -2); /* put buffer before new value */
B->lvl++; /* add new value into B stack */
adjuststack(B);
}
}

LUALIB_API void luaL_buffinit(lua_State *L, luaL_Buffer *B)
{
B->L = L;
B->p = B->buffer;
B->lvl = 0;
}

/* -- Reference management ------------------------------------------------ */

#define FREELIST_REF 0

/* Convert a stack index to an absolute index. */
#define abs_index(L, i) \
((i) > 0 || (i) <= LUA_REGISTRYINDEX ? (i) : lua_gettop(L) + (i) + 1)

LUALIB_API int luaL_ref(lua_State *L, int t)
{
int ref;
t = abs_index(L, t);
if (lua_isnil(L, -1)) {
lua_pop(L, 1); /* remove from stack */
return LUA_REFNIL; /* `nil' has a unique fixed reference */
}
lua_rawgeti(L, t, FREELIST_REF); /* get first free element */
ref = (int)lua_tointeger(L, -1); /* ref = t[FREELIST_REF] */
lua_pop(L, 1); /* remove it from stack */
if (ref != 0) { /* any free element? */
lua_rawgeti(L, t, ref); /* remove it from list */
lua_rawseti(L, t, FREELIST_REF); /* (t[FREELIST_REF] = t[ref]) */
} else { /* no free elements */
ref = (int)lua_objlen(L, t);
ref++; /* create new reference */
}
lua_rawseti(L, t, ref);
return ref;
}

LUALIB_API void luaL_unref(lua_State *L, int t, int ref)
{
if (ref >= 0) {
t = abs_index(L, t);
lua_rawgeti(L, t, FREELIST_REF);
lua_rawseti(L, t, ref); /* t[ref] = t[FREELIST_REF] */
lua_pushinteger(L, ref);
lua_rawseti(L, t, FREELIST_REF); /* t[FREELIST_REF] = ref */
}
}

/* -- Default allocator and panic function -------------------------------- */

static int panic(lua_State *L)
{
const char *s = lua_tostring(L, -1);
fputs("PANIC: unprotected error in call to Lua API (", stderr);
fputs(s ? s : "?", stderr);
fputc(')', stderr); fputc('\n', stderr);
fflush(stderr);
return 0;
}

#ifdef LUAJIT_USE_SYSMALLOC

#if LJ_64
#error "Must use builtin allocator for 64 bit target"
#endif

static void *mem_alloc(void *ud, void *ptr, size_t osize, size_t nsize)
{
(void)ud;
(void)osize;
if (nsize == 0) {
free(ptr);
return NULL;
} else {
return realloc(ptr, nsize);
}
}

LUALIB_API lua_State *luaL_newstate(void)
{
lua_State *L = lua_newstate(mem_alloc, NULL);
if (L) G(L)->panic = panic;
return L;
}

#else

#include "lj_alloc.h"

LUALIB_API lua_State *luaL_newstate(void)
{
lua_State *L;
void *ud = lj_alloc_create();
if (ud == NULL) return NULL;
#if LJ_64
L = lj_state_newstate(lj_alloc_f, ud);
#else
L = lua_newstate(lj_alloc_f, ud);
#endif
if (L) G(L)->panic = panic;
return L;
}

#if LJ_64
LUA_API lua_State *lua_newstate(lua_Alloc f, void *ud)
{
UNUSED(f); UNUSED(ud);
fputs("Must use luaL_newstate() for 64 bit target\n", stderr);
return NULL;
}
#endif

#endif