+
+
+
+Lua 5.1 Reference Manual
+ by R. Ierusalimschy, L. H. de Figueiredo, W. Celes
+ Lua.org, August 2006
+ ISBN 85-903798-3-3
+
+
+
+
+
+
+Buy a copy of this book and
+help to support
+the Lua project.
+
+
+The reference manual is the official definition of the Lua language.
+For a complete introduction to Lua programming, see the book
+Programming in Lua.
+
+
+Last update:
+Sat Jan 19 13:24:29 BRST 2008
+
+
+
+
+
diff --git a/libraries/LuaJIT-1.1.7/doc/cover.png b/libraries/LuaJIT-1.1.7/doc/cover.png
new file mode 100644
index 0000000..2dbb198
Binary files /dev/null and b/libraries/LuaJIT-1.1.7/doc/cover.png differ
diff --git a/libraries/LuaJIT-1.1.7/doc/logo.gif b/libraries/LuaJIT-1.1.7/doc/logo.gif
new file mode 100644
index 0000000..2f5e4ac
Binary files /dev/null and b/libraries/LuaJIT-1.1.7/doc/logo.gif differ
diff --git a/libraries/LuaJIT-1.1.7/doc/lua.1 b/libraries/LuaJIT-1.1.7/doc/lua.1
new file mode 100644
index 0000000..24809cc
--- /dev/null
+++ b/libraries/LuaJIT-1.1.7/doc/lua.1
@@ -0,0 +1,163 @@
+.\" $Id: lua.man,v 1.11 2006/01/06 16:03:34 lhf Exp $
+.TH LUA 1 "$Date: 2006/01/06 16:03:34 $"
+.SH NAME
+lua \- Lua interpreter
+.SH SYNOPSIS
+.B lua
+[
+.I options
+]
+[
+.I script
+[
+.I args
+]
+]
+.SH DESCRIPTION
+.B lua
+is the stand-alone Lua interpreter.
+It loads and executes Lua programs,
+either in textual source form or
+in precompiled binary form.
+(Precompiled binaries are output by
+.BR luac ,
+the Lua compiler.)
+.B lua
+can be used as a batch interpreter and also interactively.
+.LP
+The given
+.I options
+(see below)
+are executed and then
+the Lua program in file
+.I script
+is loaded and executed.
+The given
+.I args
+are available to
+.I script
+as strings in a global table named
+.BR arg .
+If these arguments contain spaces or other characters special to the shell,
+then they should be quoted
+(but note that the quotes will be removed by the shell).
+The arguments in
+.B arg
+start at 0,
+which contains the string
+.RI ' script '.
+The index of the last argument is stored in
+.BR arg.n .
+The arguments given in the command line before
+.IR script ,
+including the name of the interpreter,
+are available in negative indices in
+.BR arg .
+.LP
+At the very start,
+before even handling the command line,
+.B lua
+executes the contents of the environment variable
+.BR LUA_INIT ,
+if it is defined.
+If the value of
+.B LUA_INIT
+is of the form
+.RI '@ filename ',
+then
+.I filename
+is executed.
+Otherwise, the string is assumed to be a Lua statement and is executed.
+.LP
+Options start with
+.B '\-'
+and are described below.
+You can use
+.B "'\--'"
+to signal the end of options.
+.LP
+If no arguments are given,
+then
+.B "\-v \-i"
+is assumed when the standard input is a terminal;
+otherwise,
+.B "\-"
+is assumed.
+.LP
+In interactive mode,
+.B lua
+prompts the user,
+reads lines from the standard input,
+and executes them as they are read.
+If a line does not contain a complete statement,
+then a secondary prompt is displayed and
+lines are read until a complete statement is formed or
+a syntax error is found.
+So, one way to interrupt the reading of an incomplete statement is
+to force a syntax error:
+adding a
+.B ';'
+in the middle of a statement is a sure way of forcing a syntax error
+(except inside multiline strings and comments; these must be closed explicitly).
+If a line starts with
+.BR '=' ,
+then
+.B lua
+displays the values of all the expressions in the remainder of the
+line. The expressions must be separated by commas.
+The primary prompt is the value of the global variable
+.BR _PROMPT ,
+if this value is a string;
+otherwise, the default prompt is used.
+Similarly, the secondary prompt is the value of the global variable
+.BR _PROMPT2 .
+So,
+to change the prompts,
+set the corresponding variable to a string of your choice.
+You can do that after calling the interpreter
+or on the command line
+(but in this case you have to be careful with quotes
+if the prompt string contains a space; otherwise you may confuse the shell.)
+The default prompts are "> " and ">> ".
+.SH OPTIONS
+.TP
+.B \-
+load and execute the standard input as a file,
+that is,
+not interactively,
+even when the standard input is a terminal.
+.TP
+.BI \-e " stat"
+execute statement
+.IR stat .
+You need to quote
+.I stat
+if it contains spaces, quotes,
+or other characters special to the shell.
+.TP
+.B \-i
+enter interactive mode after
+.I script
+is executed.
+.TP
+.BI \-l " name"
+call
+.BI require(' name ')
+before executing
+.IR script .
+Typically used to load libraries.
+.TP
+.B \-v
+show version information.
+.SH "SEE ALSO"
+.BR luac (1)
+.br
+http://www.lua.org/
+.SH DIAGNOSTICS
+Error messages should be self explanatory.
+.SH AUTHORS
+R. Ierusalimschy,
+L. H. de Figueiredo,
+and
+W. Celes
+.\" EOF
diff --git a/libraries/LuaJIT-1.1.7/doc/lua.css b/libraries/LuaJIT-1.1.7/doc/lua.css
new file mode 100644
index 0000000..039cf11
--- /dev/null
+++ b/libraries/LuaJIT-1.1.7/doc/lua.css
@@ -0,0 +1,41 @@
+body {
+ color: #000000 ;
+ background-color: #FFFFFF ;
+ font-family: sans-serif ;
+ text-align: justify ;
+ margin-right: 20px ;
+ margin-left: 20px ;
+}
+
+h1, h2, h3, h4 {
+ font-weight: normal ;
+ font-style: italic ;
+}
+
+a:link {
+ color: #000080 ;
+ background-color: inherit ;
+ text-decoration: none ;
+}
+
+a:visited {
+ background-color: inherit ;
+ text-decoration: none ;
+}
+
+a:link:hover, a:visited:hover {
+ color: #000080 ;
+ background-color: #E0E0FF ;
+}
+
+a:link:active, a:visited:active {
+ color: #FF0000 ;
+}
+
+hr {
+ border: 0 ;
+ height: 1px ;
+ color: #a0a0a0 ;
+ background-color: #a0a0a0 ;
+}
+
diff --git a/libraries/LuaJIT-1.1.7/doc/lua.html b/libraries/LuaJIT-1.1.7/doc/lua.html
new file mode 100644
index 0000000..1d435ab
--- /dev/null
+++ b/libraries/LuaJIT-1.1.7/doc/lua.html
@@ -0,0 +1,172 @@
+
+
+
+LUA man page
+
+
+
+
+
+
NAME
+lua - Lua interpreter
+
SYNOPSIS
+lua
+[
+options
+]
+[
+script
+[
+args
+]
+]
+
DESCRIPTION
+lua
+is the stand-alone Lua interpreter.
+It loads and executes Lua programs,
+either in textual source form or
+in precompiled binary form.
+(Precompiled binaries are output by
+luac,
+the Lua compiler.)
+lua
+can be used as a batch interpreter and also interactively.
+
+The given
+options
+(see below)
+are executed and then
+the Lua program in file
+script
+is loaded and executed.
+The given
+args
+are available to
+script
+as strings in a global table named
+arg.
+If these arguments contain spaces or other characters special to the shell,
+then they should be quoted
+(but note that the quotes will be removed by the shell).
+The arguments in
+arg
+start at 0,
+which contains the string
+'script'.
+The index of the last argument is stored in
+arg.n.
+The arguments given in the command line before
+script,
+including the name of the interpreter,
+are available in negative indices in
+arg.
+
+At the very start,
+before even handling the command line,
+lua
+executes the contents of the environment variable
+LUA_INIT,
+if it is defined.
+If the value of
+LUA_INIT
+is of the form
+'@filename',
+then
+filename
+is executed.
+Otherwise, the string is assumed to be a Lua statement and is executed.
+
+Options start with
+'-'
+and are described below.
+You can use
+'--'
+to signal the end of options.
+
+If no arguments are given,
+then
+"-v -i"
+is assumed when the standard input is a terminal;
+otherwise,
+"-"
+is assumed.
+
+In interactive mode,
+lua
+prompts the user,
+reads lines from the standard input,
+and executes them as they are read.
+If a line does not contain a complete statement,
+then a secondary prompt is displayed and
+lines are read until a complete statement is formed or
+a syntax error is found.
+So, one way to interrupt the reading of an incomplete statement is
+to force a syntax error:
+adding a
+';'
+in the middle of a statement is a sure way of forcing a syntax error
+(except inside multiline strings and comments; these must be closed explicitly).
+If a line starts with
+'=',
+then
+lua
+displays the values of all the expressions in the remainder of the
+line. The expressions must be separated by commas.
+The primary prompt is the value of the global variable
+_PROMPT,
+if this value is a string;
+otherwise, the default prompt is used.
+Similarly, the secondary prompt is the value of the global variable
+_PROMPT2.
+So,
+to change the prompts,
+set the corresponding variable to a string of your choice.
+You can do that after calling the interpreter
+or on the command line
+(but in this case you have to be careful with quotes
+if the prompt string contains a space; otherwise you may confuse the shell.)
+The default prompts are "> " and ">> ".
+
OPTIONS
+
+-
+load and execute the standard input as a file,
+that is,
+not interactively,
+even when the standard input is a terminal.
+
+-e stat
+execute statement
+stat.
+You need to quote
+stat
+if it contains spaces, quotes,
+or other characters special to the shell.
+
+-i
+enter interactive mode after
+script
+is executed.
+
+-l name
+call
+require('name')
+before executing
+script.
+Typically used to load libraries.
+
+R. Ierusalimschy,
+L. H. de Figueiredo,
+and
+W. Celes
+
+
+
diff --git a/libraries/LuaJIT-1.1.7/doc/luac.1 b/libraries/LuaJIT-1.1.7/doc/luac.1
new file mode 100644
index 0000000..d814678
--- /dev/null
+++ b/libraries/LuaJIT-1.1.7/doc/luac.1
@@ -0,0 +1,136 @@
+.\" $Id: luac.man,v 1.28 2006/01/06 16:03:34 lhf Exp $
+.TH LUAC 1 "$Date: 2006/01/06 16:03:34 $"
+.SH NAME
+luac \- Lua compiler
+.SH SYNOPSIS
+.B luac
+[
+.I options
+] [
+.I filenames
+]
+.SH DESCRIPTION
+.B luac
+is the Lua compiler.
+It translates programs written in the Lua programming language
+into binary files that can be later loaded and executed.
+.LP
+The main advantages of precompiling chunks are:
+faster loading,
+protecting source code from accidental user changes,
+and
+off-line syntax checking.
+.LP
+Pre-compiling does not imply faster execution
+because in Lua chunks are always compiled into bytecodes before being executed.
+.B luac
+simply allows those bytecodes to be saved in a file for later execution.
+.LP
+Pre-compiled chunks are not necessarily smaller than the corresponding source.
+The main goal in pre-compiling is faster loading.
+.LP
+The binary files created by
+.B luac
+are portable only among architectures with the same word size and byte order.
+.LP
+.B luac
+produces a single output file containing the bytecodes
+for all source files given.
+By default,
+the output file is named
+.BR luac.out ,
+but you can change this with the
+.B \-o
+option.
+.LP
+In the command line,
+you can mix
+text files containing Lua source and
+binary files containing precompiled chunks.
+This is useful to combine several precompiled chunks,
+even from different (but compatible) platforms,
+into a single precompiled chunk.
+.LP
+You can use
+.B "'\-'"
+to indicate the standard input as a source file
+and
+.B "'\--'"
+to signal the end of options
+(that is,
+all remaining arguments will be treated as files even if they start with
+.BR "'\-'" ).
+.LP
+The internal format of the binary files produced by
+.B luac
+is likely to change when a new version of Lua is released.
+So,
+save the source files of all Lua programs that you precompile.
+.LP
+.SH OPTIONS
+Options must be separate.
+.TP
+.B \-l
+produce a listing of the compiled bytecode for Lua's virtual machine.
+Listing bytecodes is useful to learn about Lua's virtual machine.
+If no files are given, then
+.B luac
+loads
+.B luac.out
+and lists its contents.
+.TP
+.BI \-o " file"
+output to
+.IR file ,
+instead of the default
+.BR luac.out .
+(You can use
+.B "'\-'"
+for standard output,
+but not on platforms that open standard output in text mode.)
+The output file may be a source file because
+all files are loaded before the output file is written.
+Be careful not to overwrite precious files.
+.TP
+.B \-p
+load files but do not generate any output file.
+Used mainly for syntax checking and for testing precompiled chunks:
+corrupted files will probably generate errors when loaded.
+Lua always performs a thorough integrity test on precompiled chunks.
+Bytecode that passes this test is completely safe,
+in the sense that it will not break the interpreter.
+However,
+there is no guarantee that such code does anything sensible.
+(None can be given, because the halting problem is unsolvable.)
+If no files are given, then
+.B luac
+loads
+.B luac.out
+and tests its contents.
+No messages are displayed if the file passes the integrity test.
+.TP
+.B \-s
+strip debug information before writing the output file.
+This saves some space in very large chunks,
+but if errors occur when running a stripped chunk,
+then the error messages may not contain the full information they usually do.
+For instance,
+line numbers and names of local variables are lost.
+.TP
+.B \-v
+show version information.
+.SH FILES
+.TP 15
+.B luac.out
+default output file
+.SH "SEE ALSO"
+.BR lua (1)
+.br
+http://www.lua.org/
+.SH DIAGNOSTICS
+Error messages should be self explanatory.
+.SH AUTHORS
+L. H. de Figueiredo,
+R. Ierusalimschy and
+W. Celes
+.\" EOF
diff --git a/libraries/LuaJIT-1.1.7/doc/luac.html b/libraries/LuaJIT-1.1.7/doc/luac.html
new file mode 100644
index 0000000..179ffe8
--- /dev/null
+++ b/libraries/LuaJIT-1.1.7/doc/luac.html
@@ -0,0 +1,145 @@
+
+
+
+LUAC man page
+
+
+
+
+
+
NAME
+luac - Lua compiler
+
SYNOPSIS
+luac
+[
+options
+] [
+filenames
+]
+
DESCRIPTION
+luac
+is the Lua compiler.
+It translates programs written in the Lua programming language
+into binary files that can be later loaded and executed.
+
+The main advantages of precompiling chunks are:
+faster loading,
+protecting source code from accidental user changes,
+and
+off-line syntax checking.
+
+Precompiling does not imply faster execution
+because in Lua chunks are always compiled into bytecodes before being executed.
+luac
+simply allows those bytecodes to be saved in a file for later execution.
+
+Precompiled chunks are not necessarily smaller than the corresponding source.
+The main goal in precompiling is faster loading.
+
+The binary files created by
+luac
+are portable only among architectures with the same word size and byte order.
+
+luac
+produces a single output file containing the bytecodes
+for all source files given.
+By default,
+the output file is named
+luac.out,
+but you can change this with the
+-o
+option.
+
+In the command line,
+you can mix
+text files containing Lua source and
+binary files containing precompiled chunks.
+This is useful because several precompiled chunks,
+even from different (but compatible) platforms,
+can be combined into a single precompiled chunk.
+
+You can use
+'-'
+to indicate the standard input as a source file
+and
+'--'
+to signal the end of options
+(that is,
+all remaining arguments will be treated as files even if they start with
+'-').
+
+The internal format of the binary files produced by
+luac
+is likely to change when a new version of Lua is released.
+So,
+save the source files of all Lua programs that you precompile.
+
+
OPTIONS
+Options must be separate.
+
+-l
+produce a listing of the compiled bytecode for Lua's virtual machine.
+Listing bytecodes is useful to learn about Lua's virtual machine.
+If no files are given, then
+luac
+loads
+luac.out
+and lists its contents.
+
+-o file
+output to
+file,
+instead of the default
+luac.out.
+(You can use
+'-'
+for standard output,
+but not on platforms that open standard output in text mode.)
+The output file may be a source file because
+all files are loaded before the output file is written.
+Be careful not to overwrite precious files.
+
+-p
+load files but do not generate any output file.
+Used mainly for syntax checking and for testing precompiled chunks:
+corrupted files will probably generate errors when loaded.
+Lua always performs a thorough integrity test on precompiled chunks.
+Bytecode that passes this test is completely safe,
+in the sense that it will not break the interpreter.
+However,
+there is no guarantee that such code does anything sensible.
+(None can be given, because the halting problem is unsolvable.)
+If no files are given, then
+luac
+loads
+luac.out
+and tests its contents.
+No messages are displayed if the file passes the integrity test.
+
+-s
+strip debug information before writing the output file.
+This saves some space in very large chunks,
+but if errors occur when running a stripped chunk,
+then the error messages may not contain the full information they usually do.
+For instance,
+line numbers and names of local variables are lost.
+
+Lua is an extension programming language designed to support
+general procedural programming with data description
+facilities.
+It also offers good support for object-oriented programming,
+functional programming, and data-driven programming.
+Lua is intended to be used as a powerful, light-weight
+scripting language for any program that needs one.
+Lua is implemented as a library, written in clean C
+(that is, in the common subset of ANSI C and C++).
+
+
+
+Being an extension language, Lua has no notion of a "main" program:
+it only works embedded in a host client,
+called the embedding program or simply the host.
+This host program can invoke functions to execute a piece of Lua code,
+can write and read Lua variables,
+and can register C functions to be called by Lua code.
+Through the use of C functions, Lua can be augmented to cope with
+a wide range of different domains,
+thus creating customized programming languages sharing a syntactical framework.
+The Lua distribution includes a sample host program called lua,
+which uses the Lua library to offer a complete, stand-alone Lua interpreter.
+
+
+
+Lua is free software,
+and is provided as usual with no guarantees,
+as stated in its license.
+The implementation described in this manual is available
+at Lua's official web site, www.lua.org.
+
+
+
+Like any other reference manual,
+this document is dry in places.
+For a discussion of the decisions behind the design of Lua,
+see the technical papers available at Lua's web site.
+For a detailed introduction to programming in Lua,
+see Roberto's book, Programming in Lua (Second Edition).
+
+
+
+
+This section describes the lexis, the syntax, and the semantics of Lua.
+In other words,
+this section describes
+which tokens are valid,
+how they can be combined,
+and what their combinations mean.
+
+
+
+The language constructs will be explained using the usual extended BNF notation,
+in which
+{a} means 0 or more a's, and
+[a] means an optional a.
+Non-terminals are shown like non-terminal,
+keywords are shown like kword,
+and other terminal symbols are shown like `=´.
+The complete syntax of Lua can be found in §8
+at the end of this manual.
+
+
+
+
+Names
+(also called identifiers)
+in Lua can be any string of letters,
+digits, and underscores,
+not beginning with a digit.
+This coincides with the definition of names in most languages.
+(The definition of letter depends on the current locale:
+any character considered alphabetic by the current locale
+can be used in an identifier.)
+Identifiers are used to name variables and table fields.
+
+
+
+The following keywords are reserved
+and cannot be used as names:
+
+
+
+ and break do else elseif
+ end false for function if
+ in local nil not or
+ repeat return then true until while
+
+
+
+Lua is a case-sensitive language:
+and is a reserved word, but And and AND
+are two different, valid names.
+As a convention, names starting with an underscore followed by
+uppercase letters (such as _VERSION)
+are reserved for internal global variables used by Lua.
+
+
+
+Literal strings
+can be delimited by matching single or double quotes,
+and can contain the following C-like escape sequences:
+'\a' (bell),
+'\b' (backspace),
+'\f' (form feed),
+'\n' (newline),
+'\r' (carriage return),
+'\t' (horizontal tab),
+'\v' (vertical tab),
+'\\' (backslash),
+'\"' (quotation mark [double quote]),
+and '\'' (apostrophe [single quote]).
+Moreover, a backslash followed by a real newline
+results in a newline in the string.
+A character in a string can also be specified by its numerical value
+using the escape sequence \ddd,
+where ddd is a sequence of up to three decimal digits.
+(Note that if a numerical escape is to be followed by a digit,
+it must be expressed using exactly three digits.)
+Strings in Lua can contain any 8-bit value, including embedded zeros,
+which can be specified as '\0'.
+
+
+
+Literal strings can also be defined using a long format
+enclosed by long brackets.
+We define an opening long bracket of level n as an opening
+square bracket followed by n equal signs followed by another
+opening square bracket.
+So, an opening long bracket of level 0 is written as [[,
+an opening long bracket of level 1 is written as [=[,
+and so on.
+A closing long bracket is defined similarly;
+for instance, a closing long bracket of level 4 is written as ]====].
+A long string starts with an opening long bracket of any level and
+ends at the first closing long bracket of the same level.
+Literals in this bracketed form can run for several lines,
+do not interpret any escape sequences,
+and ignore long brackets of any other level.
+They can contain anything except a closing bracket of the proper level.
+
+
+
+For convenience,
+when the opening long bracket is immediately followed by a newline,
+the newline is not included in the string.
+As an example, in a system using ASCII
+(in which 'a' is coded as 97,
+newline is coded as 10, and '1' is coded as 49),
+the five literal strings below denote the same string:
+
+
+ a = 'alo\n123"'
+ a = "alo\n123\""
+ a = '\97lo\10\04923"'
+ a = [[alo
+ 123"]]
+ a = [==[
+ alo
+ 123"]==]
+
+
+
+A numerical constant can be written with an optional decimal part
+and an optional decimal exponent.
+Lua also accepts integer hexadecimal constants,
+by prefixing them with 0x.
+Examples of valid numerical constants are
+
+
+ 3 3.0 3.1416 314.16e-2 0.31416E1 0xff 0x56
+
+
+
+A comment starts with a double hyphen (--)
+anywhere outside a string.
+If the text immediately after -- is not an opening long bracket,
+the comment is a short comment,
+which runs until the end of the line.
+Otherwise, it is a long comment,
+which runs until the corresponding closing long bracket.
+Long comments are frequently used to disable code temporarily.
+
+
+
+
+
+
+Lua is a dynamically typed language.
+This means that
+variables do not have types; only values do.
+There are no type definitions in the language.
+All values carry their own type.
+
+
+
+All values in Lua are first-class values.
+This means that all values can be stored in variables,
+passed as arguments to other functions, and returned as results.
+
+
+
+There are eight basic types in Lua:
+nil, boolean, number,
+string, function, userdata,
+thread, and table.
+Nil is the type of the value nil,
+whose main property is to be different from any other value;
+it usually represents the absence of a useful value.
+Boolean is the type of the values false and true.
+Both nil and false make a condition false;
+any other value makes it true.
+Number represents real (double-precision floating-point) numbers.
+(It is easy to build Lua interpreters that use other
+internal representations for numbers,
+such as single-precision float or long integers;
+see file luaconf.h.)
+String represents arrays of characters.
+
+Lua is 8-bit clean:
+strings can contain any 8-bit character,
+including embedded zeros ('\0') (see §2.1).
+
+
+
+Lua can call (and manipulate) functions written in Lua and
+functions written in C
+(see §2.5.8).
+
+
+
+The type userdata is provided to allow arbitrary C data to
+be stored in Lua variables.
+This type corresponds to a block of raw memory
+and has no pre-defined operations in Lua,
+except assignment and identity test.
+However, by using metatables,
+the programmer can define operations for userdata values
+(see §2.8).
+Userdata values cannot be created or modified in Lua,
+only through the C API.
+This guarantees the integrity of data owned by the host program.
+
+
+
+The type thread represents independent threads of execution
+and it is used to implement coroutines (see §2.11).
+Do not confuse Lua threads with operating-system threads.
+Lua supports coroutines on all systems,
+even those that do not support threads.
+
+
+
+The type table implements associative arrays,
+that is, arrays that can be indexed not only with numbers,
+but with any value (except nil).
+Tables can be heterogeneous;
+that is, they can contain values of all types (except nil).
+Tables are the sole data structuring mechanism in Lua;
+they can be used to represent ordinary arrays,
+symbol tables, sets, records, graphs, trees, etc.
+To represent records, Lua uses the field name as an index.
+The language supports this representation by
+providing a.name as syntactic sugar for a["name"].
+There are several convenient ways to create tables in Lua
+(see §2.5.7).
+
+
+
+Like indices,
+the value of a table field can be of any type (except nil).
+In particular,
+because functions are first-class values,
+table fields can contain functions.
+Thus tables can also carry methods (see §2.5.9).
+
+
+
+Tables, functions, threads, and (full) userdata values are objects:
+variables do not actually contain these values,
+only references to them.
+Assignment, parameter passing, and function returns
+always manipulate references to such values;
+these operations do not imply any kind of copy.
+
+
+
+The library function type returns a string describing the type
+of a given value.
+
+
+
+
+Lua provides automatic conversion between
+string and number values at run time.
+Any arithmetic operation applied to a string tries to convert
+this string to a number, following the usual conversion rules.
+Conversely, whenever a number is used where a string is expected,
+the number is converted to a string, in a reasonable format.
+For complete control over how numbers are converted to strings,
+use the format function from the string library
+(see string.format).
+
+
+
+
+
+
+
+
+Variables are places that store values.
+
+There are three kinds of variables in Lua:
+global variables, local variables, and table fields.
+
+
+
+A single name can denote a global variable or a local variable
+(or a function's formal parameter,
+which is a particular kind of local variable):
+
+
+ var ::= Name
+
+Name denotes identifiers, as defined in §2.1.
+
+
+
+Any variable is assumed to be global unless explicitly declared
+as a local (see §2.4.7).
+Local variables are lexically scoped:
+local variables can be freely accessed by functions
+defined inside their scope (see §2.6).
+
+
+
+Before the first assignment to a variable, its value is nil.
+
+
+
+Square brackets are used to index a table:
+
+
+ var ::= prefixexp `[´ exp `]´
+
+The meaning of accesses to global variables
+and table fields can be changed via metatables.
+An access to an indexed variable t[i] is equivalent to
+a call gettable_event(t,i).
+(See §2.8 for a complete description of the
+gettable_event function.
+This function is not defined or callable in Lua.
+We use it here only for explanatory purposes.)
+
+
+
+The syntax var.Name is just syntactic sugar for
+var["Name"]:
+
+
+ var ::= prefixexp `.´ Name
+
+
+
+All global variables live as fields in ordinary Lua tables,
+called environment tables or simply
+environments (see §2.9).
+Each function has its own reference to an environment,
+so that all global variables in this function
+will refer to this environment table.
+When a function is created,
+it inherits the environment from the function that created it.
+To get the environment table of a Lua function,
+you call getfenv.
+To replace it,
+you call setfenv.
+(You can only manipulate the environment of C functions
+through the debug library; (see §5.9).)
+
+
+
+An access to a global variable x
+is equivalent to _env.x,
+which in turn is equivalent to
+
+
+ gettable_event(_env, "x")
+
+where _env is the environment of the running function.
+(See §2.8 for a complete description of the
+gettable_event function.
+This function is not defined or callable in Lua.
+Similarly, the _env variable is not defined in Lua.
+We use them here only for explanatory purposes.)
+
+
+
+
+
+
+Lua supports an almost conventional set of statements,
+similar to those in Pascal or C.
+This set includes
+assignments, control structures, function calls,
+and variable declarations.
+
+
+
+
+The unit of execution of Lua is called a chunk.
+A chunk is simply a sequence of statements,
+which are executed sequentially.
+Each statement can be optionally followed by a semicolon:
+
+
+ chunk ::= {stat [`;´]}
+
+There are no empty statements and thus ';;' is not legal.
+
+
+
+Lua handles a chunk as the body of an anonymous function
+with a variable number of arguments
+(see §2.5.9).
+As such, chunks can define local variables,
+receive arguments, and return values.
+
+
+
+A chunk can be stored in a file or in a string inside the host program.
+To execute a chunk,
+Lua first pre-compiles the chunk into instructions for a virtual machine,
+and then it executes the compiled code
+with an interpreter for the virtual machine.
+
+
+
+Chunks can also be pre-compiled into binary form;
+see program luac for details.
+Programs in source and compiled forms are interchangeable;
+Lua automatically detects the file type and acts accordingly.
+
+
+
+
+
+
+
+A block is a list of statements;
+syntactically, a block is the same as a chunk:
+
+
+ block ::= chunk
+
+
+
+A block can be explicitly delimited to produce a single statement:
+
+
+ stat ::= do block end
+
+Explicit blocks are useful
+to control the scope of variable declarations.
+Explicit blocks are also sometimes used to
+add a return or break statement in the middle
+of another block (see §2.4.4).
+
+
+
+
+
+
+Lua allows multiple assignments.
+Therefore, the syntax for assignment
+defines a list of variables on the left side
+and a list of expressions on the right side.
+The elements in both lists are separated by commas:
+
+
+ stat ::= varlist `=´ explist
+ varlist ::= var {`,´ var}
+ explist ::= exp {`,´ exp}
+
+Before the assignment,
+the list of values is adjusted to the length of
+the list of variables.
+If there are more values than needed,
+the excess values are thrown away.
+If there are fewer values than needed,
+the list is extended with as many nil's as needed.
+If the list of expressions ends with a function call,
+then all values returned by that call enter the list of values,
+before the adjustment
+(except when the call is enclosed in parentheses; see §2.5).
+
+
+
+The assignment statement first evaluates all its expressions
+and only then are the assignments performed.
+Thus the code
+
+
+ i = 3
+ i, a[i] = i+1, 20
+
+sets a[3] to 20, without affecting a[4]
+because the i in a[i] is evaluated (to 3)
+before it is assigned 4.
+Similarly, the line
+
+
+ x, y = y, x
+
+exchanges the values of x and y,
+and
+
+
+ x, y, z = y, z, x
+
+cyclically permutes the values of x, y, and z.
+
+
+
+The meaning of assignments to global variables
+and table fields can be changed via metatables.
+An assignment to an indexed variable t[i] = val is equivalent to
+settable_event(t,i,val).
+(See §2.8 for a complete description of the
+settable_event function.
+This function is not defined or callable in Lua.
+We use it here only for explanatory purposes.)
+
+
+
+An assignment to a global variable x = val
+is equivalent to the assignment
+_env.x = val,
+which in turn is equivalent to
+
+
+ settable_event(_env, "x", val)
+
+where _env is the environment of the running function.
+(The _env variable is not defined in Lua.
+We use it here only for explanatory purposes.)
+
+
+
+
+
+
+The control structures
+if, while, and repeat have the usual meaning and
+familiar syntax:
+
+
+
+
+
+ stat ::= while exp do block end
+ stat ::= repeat block until exp
+ stat ::= if exp then block {elseif exp then block} [else block] end
+
+Lua also has a for statement, in two flavors (see §2.4.5).
+
+
+
+The condition expression of a
+control structure can return any value.
+Both false and nil are considered false.
+All values different from nil and false are considered true
+(in particular, the number 0 and the empty string are also true).
+
+
+
+In the repeat–until loop,
+the inner block does not end at the until keyword,
+but only after the condition.
+So, the condition can refer to local variables
+declared inside the loop block.
+
+
+
+The return statement is used to return values
+from a function or a chunk (which is just a function).
+
+Functions and chunks can return more than one value,
+and so the syntax for the return statement is
+
+
+ stat ::= return [explist]
+
+
+
+The break statement is used to terminate the execution of a
+while, repeat, or for loop,
+skipping to the next statement after the loop:
+
+
+
+ stat ::= break
+
+A break ends the innermost enclosing loop.
+
+
+
+The return and break
+statements can only be written as the last statement of a block.
+If it is really necessary to return or break in the
+middle of a block,
+then an explicit inner block can be used,
+as in the idioms
+do return end and do break end,
+because now return and break are the last statements in
+their (inner) blocks.
+
+
+
+
+
+
+
+The for statement has two forms:
+one numeric and one generic.
+
+
+
+The numeric for loop repeats a block of code while a
+control variable runs through an arithmetic progression.
+It has the following syntax:
+
+
+ stat ::= for Name `=´ exp `,´ exp [`,´ exp] do block end
+
+The block is repeated for name starting at the value of
+the first exp, until it passes the second exp by steps of the
+third exp.
+More precisely, a for statement like
+
+
+ for v = e1, e2, e3 do block end
+
+is equivalent to the code:
+
+
+ do
+ local var, limit, step = tonumber(e1), tonumber(e2), tonumber(e3)
+ if not (var and limit and step) then error() end
+ while (step > 0 and var <= limit) or (step <= 0 and var >= limit) do
+ local v = var
+ block
+ var = var + step
+ end
+ end
+
+Note the following:
+
+
+
+
+All three control expressions are evaluated only once,
+before the loop starts.
+They must all result in numbers.
+
+
+
+var, limit, and step are invisible variables.
+The names shown here are for explanatory purposes only.
+
+
+
+If the third expression (the step) is absent,
+then a step of 1 is used.
+
+
+
+You can use break to exit a for loop.
+
+
+
+The loop variable v is local to the loop;
+you cannot use its value after the for ends or is broken.
+If you need this value,
+assign it to another variable before breaking or exiting the loop.
+
+
+
+
+
+The generic for statement works over functions,
+called iterators.
+On each iteration, the iterator function is called to produce a new value,
+stopping when this new value is nil.
+The generic for loop has the following syntax:
+
+
+ stat ::= for namelist in explist do block end
+ namelist ::= Name {`,´ Name}
+
+A for statement like
+
+
+ for var_1, ···, var_n in explist do block end
+
+is equivalent to the code:
+
+
+ do
+ local f, s, var = explist
+ while true do
+ local var_1, ···, var_n = f(s, var)
+ var = var_1
+ if var == nil then break end
+ block
+ end
+ end
+
+Note the following:
+
+
+
+
+explist is evaluated only once.
+Its results are an iterator function,
+a state,
+and an initial value for the first iterator variable.
+
+
+
+f, s, and var are invisible variables.
+The names are here for explanatory purposes only.
+
+
+
+You can use break to exit a for loop.
+
+
+
+The loop variables var_i are local to the loop;
+you cannot use their values after the for ends.
+If you need these values,
+then assign them to other variables before breaking or exiting the loop.
+
+Local variables can be declared anywhere inside a block.
+The declaration can include an initial assignment:
+
+
+ stat ::= local namelist [`=´ explist]
+
+If present, an initial assignment has the same semantics
+of a multiple assignment (see §2.4.3).
+Otherwise, all variables are initialized with nil.
+
+
+
+A chunk is also a block (see §2.4.1),
+and so local variables can be declared in a chunk outside any explicit block.
+The scope of such local variables extends until the end of the chunk.
+
+
+
+The visibility rules for local variables are explained in §2.6.
+
+
+
+
+
+
+
+
+Numbers and literal strings are explained in §2.1;
+variables are explained in §2.3;
+function definitions are explained in §2.5.9;
+function calls are explained in §2.5.8;
+table constructors are explained in §2.5.7.
+Vararg expressions,
+denoted by three dots ('...'), can only be used when
+directly inside a vararg function;
+they are explained in §2.5.9.
+
+
+
+Binary operators comprise arithmetic operators (see §2.5.1),
+relational operators (see §2.5.2), logical operators (see §2.5.3),
+and the concatenation operator (see §2.5.4).
+Unary operators comprise the unary minus (see §2.5.1),
+the unary not (see §2.5.3),
+and the unary length operator (see §2.5.5).
+
+
+
+Both function calls and vararg expressions can result in multiple values.
+If an expression is used as a statement
+(only possible for function calls (see §2.4.6)),
+then its return list is adjusted to zero elements,
+thus discarding all returned values.
+If an expression is used as the last (or the only) element
+of a list of expressions,
+then no adjustment is made
+(unless the call is enclosed in parentheses).
+In all other contexts,
+Lua adjusts the result list to one element,
+discarding all values except the first one.
+
+
+
+Here are some examples:
+
+
+ f() -- adjusted to 0 results
+ g(f(), x) -- f() is adjusted to 1 result
+ g(x, f()) -- g gets x plus all results from f()
+ a,b,c = f(), x -- f() is adjusted to 1 result (c gets nil)
+ a,b = ... -- a gets the first vararg parameter, b gets
+ -- the second (both a and b can get nil if there
+ -- is no corresponding vararg parameter)
+
+ a,b,c = x, f() -- f() is adjusted to 2 results
+ a,b,c = f() -- f() is adjusted to 3 results
+ return f() -- returns all results from f()
+ return ... -- returns all received vararg parameters
+ return x,y,f() -- returns x, y, and all results from f()
+ {f()} -- creates a list with all results from f()
+ {...} -- creates a list with all vararg parameters
+ {f(), nil} -- f() is adjusted to 1 result
+
+
+
+Any expression enclosed in parentheses always results in only one value.
+Thus,
+(f(x,y,z)) is always a single value,
+even if f returns several values.
+(The value of (f(x,y,z)) is the first value returned by f
+or nil if f does not return any values.)
+
+
+
+
+Lua supports the usual arithmetic operators:
+the binary + (addition),
+- (subtraction), * (multiplication),
+/ (division), % (modulo), and ^ (exponentiation);
+and unary - (negation).
+If the operands are numbers, or strings that can be converted to
+numbers (see §2.2.1),
+then all operations have the usual meaning.
+Exponentiation works for any exponent.
+For instance, x^(-0.5) computes the inverse of the square root of x.
+Modulo is defined as
+
+
+ a % b == a - math.floor(a/b)*b
+
+That is, it is the remainder of a division that rounds
+the quotient towards minus infinity.
+
+
+
+
+
+
+These operators always result in false or true.
+
+
+
+Equality (==) first compares the type of its operands.
+If the types are different, then the result is false.
+Otherwise, the values of the operands are compared.
+Numbers and strings are compared in the usual way.
+Objects (tables, userdata, threads, and functions)
+are compared by reference:
+two objects are considered equal only if they are the same object.
+Every time you create a new object
+(a table, userdata, thread, or function),
+this new object is different from any previously existing object.
+
+
+
+You can change the way that Lua compares tables and userdata
+by using the "eq" metamethod (see §2.8).
+
+
+
+The conversion rules of §2.2.1
+do not apply to equality comparisons.
+Thus, "0"==0 evaluates to false,
+and t[0] and t["0"] denote different
+entries in a table.
+
+
+
+The operator ~= is exactly the negation of equality (==).
+
+
+
+The order operators work as follows.
+If both arguments are numbers, then they are compared as such.
+Otherwise, if both arguments are strings,
+then their values are compared according to the current locale.
+Otherwise, Lua tries to call the "lt" or the "le"
+metamethod (see §2.8).
+A comparison a > b is translated to b < a
+and a >= b is translated to b <= a.
+
+
+
+
+
+
+The logical operators in Lua are
+and, or, and not.
+Like the control structures (see §2.4.4),
+all logical operators consider both false and nil as false
+and anything else as true.
+
+
+
+The negation operator not always returns false or true.
+The conjunction operator and returns its first argument
+if this value is false or nil;
+otherwise, and returns its second argument.
+The disjunction operator or returns its first argument
+if this value is different from nil and false;
+otherwise, or returns its second argument.
+Both and and or use short-cut evaluation;
+that is,
+the second operand is evaluated only if necessary.
+Here are some examples:
+
+
+ 10 or 20 --> 10
+ 10 or error() --> 10
+ nil or "a" --> "a"
+ nil and 10 --> nil
+ false and error() --> false
+ false and nil --> false
+ false or nil --> nil
+ 10 and 20 --> 20
+
+(In this manual,
+--> indicates the result of the preceding expression.)
+
+
+
+
+
+
+The string concatenation operator in Lua is
+denoted by two dots ('..').
+If both operands are strings or numbers, then they are converted to
+strings according to the rules mentioned in §2.2.1.
+Otherwise, the "concat" metamethod is called (see §2.8).
+
+
+
+
+
+
+The length operator is denoted by the unary operator #.
+The length of a string is its number of bytes
+(that is, the usual meaning of string length when each
+character is one byte).
+
+
+
+The length of a table t is defined to be any
+integer index n
+such that t[n] is not nil and t[n+1] is nil;
+moreover, if t[1] is nil, n can be zero.
+For a regular array, with non-nil values from 1 to a given n,
+its length is exactly that n,
+the index of its last value.
+If the array has "holes"
+(that is, nil values between other non-nil values),
+then #t can be any of the indices that
+directly precedes a nil value
+(that is, it may consider any such nil value as the end of
+the array).
+
+
+
+
+
+
+Operator precedence in Lua follows the table below,
+from lower to higher priority:
+
+
+ or
+ and
+ < > <= >= ~= ==
+ ..
+ + -
+ * / %
+ not # - (unary)
+ ^
+
+As usual,
+you can use parentheses to change the precedences of an expression.
+The concatenation ('..') and exponentiation ('^')
+operators are right associative.
+All other binary operators are left associative.
+
+
+
+
+
+
+Table constructors are expressions that create tables.
+Every time a constructor is evaluated, a new table is created.
+A constructor can be used to create an empty table
+or to create a table and initialize some of its fields.
+The general syntax for constructors is
+
+
+Each field of the form [exp1] = exp2 adds to the new table an entry
+with key exp1 and value exp2.
+A field of the form name = exp is equivalent to
+["name"] = exp.
+Finally, fields of the form exp are equivalent to
+[i] = exp, where i are consecutive numerical integers,
+starting with 1.
+Fields in the other formats do not affect this counting.
+For example,
+
+
+ a = { [f(1)] = g; "x", "y"; x = 1, f(x), [30] = 23; 45 }
+
+is equivalent to
+
+
+ do
+ local t = {}
+ t[f(1)] = g
+ t[1] = "x" -- 1st exp
+ t[2] = "y" -- 2nd exp
+ t.x = 1 -- t["x"] = 1
+ t[3] = f(x) -- 3rd exp
+ t[30] = 23
+ t[4] = 45 -- 4th exp
+ a = t
+ end
+
+
+
+If the last field in the list has the form exp
+and the expression is a function call or a vararg expression,
+then all values returned by this expression enter the list consecutively
+(see §2.5.8).
+To avoid this,
+enclose the function call or the vararg expression
+in parentheses (see §2.5).
+
+
+
+The field list can have an optional trailing separator,
+as a convenience for machine-generated code.
+
+
+
+
+
+
+A function call in Lua has the following syntax:
+
+
+ functioncall ::= prefixexp args
+
+In a function call,
+first prefixexp and args are evaluated.
+If the value of prefixexp has type function,
+then this function is called
+with the given arguments.
+Otherwise, the prefixexp "call" metamethod is called,
+having as first parameter the value of prefixexp,
+followed by the original call arguments
+(see §2.8).
+
+
+
+The form
+
+
+ functioncall ::= prefixexp `:´ Name args
+
+can be used to call "methods".
+A call v:name(args)
+is syntactic sugar for v.name(v,args),
+except that v is evaluated only once.
+
+
+
+All argument expressions are evaluated before the call.
+A call of the form f{fields} is
+syntactic sugar for f({fields});
+that is, the argument list is a single new table.
+A call of the form f'string'
+(or f"string" or f[[string]])
+is syntactic sugar for f('string');
+that is, the argument list is a single literal string.
+
+
+
+As an exception to the free-format syntax of Lua,
+you cannot put a line break before the '(' in a function call.
+This restriction avoids some ambiguities in the language.
+If you write
+
+
+ a = f
+ (g).x(a)
+
+Lua would see that as a single statement, a = f(g).x(a).
+So, if you want two statements, you must add a semi-colon between them.
+If you actually want to call f,
+you must remove the line break before (g).
+
+
+
+A call of the form returnfunctioncall is called
+a tail call.
+Lua implements proper tail calls
+(or proper tail recursion):
+in a tail call,
+the called function reuses the stack entry of the calling function.
+Therefore, there is no limit on the number of nested tail calls that
+a program can execute.
+However, a tail call erases any debug information about the
+calling function.
+Note that a tail call only happens with a particular syntax,
+where the return has one single function call as argument;
+this syntax makes the calling function return exactly
+the returns of the called function.
+So, none of the following examples are tail calls:
+
+
+ return (f(x)) -- results adjusted to 1
+ return 2 * f(x)
+ return x, f(x) -- additional results
+ f(x); return -- results discarded
+ return x or f(x) -- results adjusted to 1
+
+ function ::= function funcbody
+ funcbody ::= `(´ [parlist] `)´ block end
+
+
+
+The following syntactic sugar simplifies function definitions:
+
+
+ stat ::= function funcname funcbody
+ stat ::= localfunction Name funcbody
+ funcname ::= Name {`.´ Name} [`:´ Name]
+
+The statement
+
+
+ function f () body end
+
+translates to
+
+
+ f = function () body end
+
+The statement
+
+
+ function t.a.b.c.f () body end
+
+translates to
+
+
+ t.a.b.c.f = function () body end
+
+The statement
+
+
+ local function f () body end
+
+translates to
+
+
+ local f; f = function () body end
+
+not to
+
+
+ local f = function () body end
+
+(This only makes a difference when the body of the function
+contains references to f.)
+
+
+
+A function definition is an executable expression,
+whose value has type function.
+When Lua pre-compiles a chunk,
+all its function bodies are pre-compiled too.
+Then, whenever Lua executes the function definition,
+the function is instantiated (or closed).
+This function instance (or closure)
+is the final value of the expression.
+Different instances of the same function
+can refer to different external local variables
+and can have different environment tables.
+
+
+
+Parameters act as local variables that are
+initialized with the argument values:
+
+
+ parlist ::= namelist [`,´ `...´] | `...´
+
+When a function is called,
+the list of arguments is adjusted to
+the length of the list of parameters,
+unless the function is a variadic or vararg function,
+which is
+indicated by three dots ('...') at the end of its parameter list.
+A vararg function does not adjust its argument list;
+instead, it collects all extra arguments and supplies them
+to the function through a vararg expression,
+which is also written as three dots.
+The value of this expression is a list of all actual extra arguments,
+similar to a function with multiple results.
+If a vararg expression is used inside another expression
+or in the middle of a list of expressions,
+then its return list is adjusted to one element.
+If the expression is used as the last element of a list of expressions,
+then no adjustment is made
+(unless that last expression is enclosed in parentheses).
+
+
+
+As an example, consider the following definitions:
+
+
+ function f(a, b) end
+ function g(a, b, ...) end
+ function r() return 1,2,3 end
+
+Then, we have the following mapping from arguments to parameters and
+to the vararg expression:
+
+
+Results are returned using the return statement (see §2.4.4).
+If control reaches the end of a function
+without encountering a return statement,
+then the function returns with no results.
+
+
+
+The colon syntax
+is used for defining methods,
+that is, functions that have an implicit extra parameter self.
+Thus, the statement
+
+
+
+Lua is a lexically scoped language.
+The scope of variables begins at the first statement after
+their declaration and lasts until the end of the innermost block that
+includes the declaration.
+Consider the following example:
+
+
+ x = 10 -- global variable
+ do -- new block
+ local x = x -- new 'x', with value 10
+ print(x) --> 10
+ x = x+1
+ do -- another block
+ local x = x+1 -- another 'x'
+ print(x) --> 12
+ end
+ print(x) --> 11
+ end
+ print(x) --> 10 (the global one)
+
+
+
+Notice that, in a declaration like local x = x,
+the new x being declared is not in scope yet,
+and so the second x refers to the outside variable.
+
+
+
+Because of the lexical scoping rules,
+local variables can be freely accessed by functions
+defined inside their scope.
+A local variable used by an inner function is called
+an upvalue, or external local variable,
+inside the inner function.
+
+
+
+Notice that each execution of a local statement
+defines new local variables.
+Consider the following example:
+
+
+ a = {}
+ local x = 20
+ for i=1,10 do
+ local y = 0
+ a[i] = function () y=y+1; return x+y end
+ end
+
+The loop creates ten closures
+(that is, ten instances of the anonymous function).
+Each of these closures uses a different y variable,
+while all of them share the same x.
+
+
+
+
+
+
+Because Lua is an embedded extension language,
+all Lua actions start from C code in the host program
+calling a function from the Lua library (see lua_pcall).
+Whenever an error occurs during Lua compilation or execution,
+control returns to C,
+which can take appropriate measures
+(such as printing an error message).
+
+
+
+Lua code can explicitly generate an error by calling the
+error function.
+If you need to catch errors in Lua,
+you can use the pcall function.
+
+
+
+
+
+
+Every value in Lua can have a metatable.
+This metatable is an ordinary Lua table
+that defines the behavior of the original value
+under certain special operations.
+You can change several aspects of the behavior
+of operations over a value by setting specific fields in its metatable.
+For instance, when a non-numeric value is the operand of an addition,
+Lua checks for a function in the field "__add" in its metatable.
+If it finds one,
+Lua calls this function to perform the addition.
+
+
+
+We call the keys in a metatable events
+and the values metamethods.
+In the previous example, the event is "add"
+and the metamethod is the function that performs the addition.
+
+
+
+You can query the metatable of any value
+through the getmetatable function.
+
+
+
+You can replace the metatable of tables
+through the setmetatable
+function.
+You cannot change the metatable of other types from Lua
+(except by using the debug library);
+you must use the C API for that.
+
+
+
+Tables and full userdata have individual metatables
+(although multiple tables and userdata can share their metatables).
+Values of all other types share one single metatable per type;
+that is, there is one single metatable for all numbers,
+one for all strings, etc.
+
+
+
+A metatable controls how an object behaves in arithmetic operations,
+order comparisons, concatenation, length operation, and indexing.
+A metatable also can define a function to be called when a userdata
+is garbage collected.
+For each of these operations Lua associates a specific key
+called an event.
+When Lua performs one of these operations over a value,
+it checks whether this value has a metatable with the corresponding event.
+If so, the value associated with that key (the metamethod)
+controls how Lua will perform the operation.
+
+
+
+Metatables control the operations listed next.
+Each operation is identified by its corresponding name.
+The key for each operation is a string with its name prefixed by
+two underscores, '__';
+for instance, the key for operation "add" is the
+string "__add".
+The semantics of these operations is better explained by a Lua function
+describing how the interpreter executes the operation.
+
+
+
+The code shown here in Lua is only illustrative;
+the real behavior is hard coded in the interpreter
+and it is much more efficient than this simulation.
+All functions used in these descriptions
+(rawget, tonumber, etc.)
+are described in §5.1.
+In particular, to retrieve the metamethod of a given object,
+we use the expression
+
+
+ metatable(obj)[event]
+
+This should be read as
+
+
+ rawget(getmetatable(obj) or {}, event)
+
+
+That is, the access to a metamethod does not invoke other metamethods,
+and the access to objects with no metatables does not fail
+(it simply results in nil).
+
+
+
+
+
+
"add":
+the + operation.
+
+
+
+
+The function getbinhandler below defines how Lua chooses a handler
+for a binary operation.
+First, Lua tries the first operand.
+If its type does not define a handler for the operation,
+then Lua tries the second operand.
+
+
+ function getbinhandler (op1, op2, event)
+ return metatable(op1)[event] or metatable(op2)[event]
+ end
+
+By using this function,
+the behavior of the op1 + op2 is
+
+
+ function add_event (op1, op2)
+ local o1, o2 = tonumber(op1), tonumber(op2)
+ if o1 and o2 then -- both operands are numeric?
+ return o1 + o2 -- '+' here is the primitive 'add'
+ else -- at least one of the operands is not numeric
+ local h = getbinhandler(op1, op2, "__add")
+ if h then
+ -- call the handler with both operands
+ return (h(op1, op2))
+ else -- no handler available: default behavior
+ error(···)
+ end
+ end
+ end
+
+
+
+
"sub":
+the - operation.
+
+Behavior similar to the "add" operation.
+
+
+
"mul":
+the * operation.
+
+Behavior similar to the "add" operation.
+
+
+
"div":
+the / operation.
+
+Behavior similar to the "add" operation.
+
+
+
"mod":
+the % operation.
+
+Behavior similar to the "add" operation,
+with the operation
+o1 - floor(o1/o2)*o2 as the primitive operation.
+
+
+
"pow":
+the ^ (exponentiation) operation.
+
+Behavior similar to the "add" operation,
+with the function pow (from the C math library)
+as the primitive operation.
+
+
+
"unm":
+the unary - operation.
+
+
+
+ function unm_event (op)
+ local o = tonumber(op)
+ if o then -- operand is numeric?
+ return -o -- '-' here is the primitive 'unm'
+ else -- the operand is not numeric.
+ -- Try to get a handler from the operand
+ local h = metatable(op).__unm
+ if h then
+ -- call the handler with the operand
+ return (h(op))
+ else -- no handler available: default behavior
+ error(···)
+ end
+ end
+ end
+
+ function concat_event (op1, op2)
+ if (type(op1) == "string" or type(op1) == "number") and
+ (type(op2) == "string" or type(op2) == "number") then
+ return op1 .. op2 -- primitive string concatenation
+ else
+ local h = getbinhandler(op1, op2, "__concat")
+ if h then
+ return (h(op1, op2))
+ else
+ error(···)
+ end
+ end
+ end
+
+
+
+
"len":
+the # operation.
+
+
+
+ function len_event (op)
+ if type(op) == "string" then
+ return strlen(op) -- primitive string length
+ elseif type(op) == "table" then
+ return #op -- primitive table length
+ else
+ local h = metatable(op).__len
+ if h then
+ -- call the handler with the operand
+ return (h(op))
+ else -- no handler available: default behavior
+ error(···)
+ end
+ end
+ end
+
+See §2.5.5 for a description of the length of a table.
+
+
+
"eq":
+the == operation.
+
+The function getcomphandler defines how Lua chooses a metamethod
+for comparison operators.
+A metamethod only is selected when both objects
+being compared have the same type
+and the same metamethod for the selected operation.
+
+
+ function getcomphandler (op1, op2, event)
+ if type(op1) ~= type(op2) then return nil end
+ local mm1 = metatable(op1)[event]
+ local mm2 = metatable(op2)[event]
+ if mm1 == mm2 then return mm1 else return nil end
+ end
+
+The "eq" event is defined as follows:
+
+
+ function eq_event (op1, op2)
+ if type(op1) ~= type(op2) then -- different types?
+ return false -- different objects
+ end
+ if op1 == op2 then -- primitive equal?
+ return true -- objects are equal
+ end
+ -- try metamethod
+ local h = getcomphandler(op1, op2, "__eq")
+ if h then
+ return (h(op1, op2))
+ else
+ return false
+ end
+ end
+
+a ~= b is equivalent to not (a == b).
+
+
+
"lt":
+the < operation.
+
+
+
+ function lt_event (op1, op2)
+ if type(op1) == "number" and type(op2) == "number" then
+ return op1 < op2 -- numeric comparison
+ elseif type(op1) == "string" and type(op2) == "string" then
+ return op1 < op2 -- lexicographic comparison
+ else
+ local h = getcomphandler(op1, op2, "__lt")
+ if h then
+ return (h(op1, op2))
+ else
+ error(···)
+ end
+ end
+ end
+
+a > b is equivalent to b < a.
+
+
+
"le":
+the <= operation.
+
+
+
+ function le_event (op1, op2)
+ if type(op1) == "number" and type(op2) == "number" then
+ return op1 <= op2 -- numeric comparison
+ elseif type(op1) == "string" and type(op2) == "string" then
+ return op1 <= op2 -- lexicographic comparison
+ else
+ local h = getcomphandler(op1, op2, "__le")
+ if h then
+ return (h(op1, op2))
+ else
+ h = getcomphandler(op1, op2, "__lt")
+ if h then
+ return not h(op2, op1)
+ else
+ error(···)
+ end
+ end
+ end
+ end
+
+a >= b is equivalent to b <= a.
+Note that, in the absence of a "le" metamethod,
+Lua tries the "lt", assuming that a <= b is
+equivalent to not (b < a).
+
+
+
"index":
+The indexing access table[key].
+
+
+
+ function gettable_event (table, key)
+ local h
+ if type(table) == "table" then
+ local v = rawget(table, key)
+ if v ~= nil then return v end
+ h = metatable(table).__index
+ if h == nil then return nil end
+ else
+ h = metatable(table).__index
+ if h == nil then
+ error(···)
+ end
+ end
+ if type(h) == "function" then
+ return (h(table, key)) -- call the handler
+ else return h[key] -- or repeat operation on it
+ end
+ end
+
+ function settable_event (table, key, value)
+ local h
+ if type(table) == "table" then
+ local v = rawget(table, key)
+ if v ~= nil then rawset(table, key, value); return end
+ h = metatable(table).__newindex
+ if h == nil then rawset(table, key, value); return end
+ else
+ h = metatable(table).__newindex
+ if h == nil then
+ error(···)
+ end
+ end
+ if type(h) == "function" then
+ h(table, key,value) -- call the handler
+ else h[key] = value -- or repeat operation on it
+ end
+ end
+
+
+
+
"call":
+called when Lua calls a value.
+
+
+
+ function function_event (func, ...)
+ if type(func) == "function" then
+ return func(...) -- primitive call
+ else
+ local h = metatable(func).__call
+ if h then
+ return h(func, ...)
+ else
+ error(···)
+ end
+ end
+ end
+
+Besides metatables,
+objects of types thread, function, and userdata
+have another table associated with them,
+called their environment.
+Like metatables, environments are regular tables and
+multiple objects can share the same environment.
+
+
+
+Threads are created sharing the environment of the creating thread.
+Userdata and C functions are created sharing the environment
+of the creating C function.
+Non-nested Lua functions
+(created by loadfile, loadstring or load)
+are created sharing the environment of the creating thread.
+Nested Lua functions are created sharing the environment of
+the creating Lua function.
+
+
+
+Environments associated with userdata have no meaning for Lua.
+It is only a convenience feature for programmers to associate a table to
+a userdata.
+
+
+
+Environments associated with threads are called
+global environments.
+They are used as the default environment for threads and
+non-nested Lua functions created by the thread
+and can be directly accessed by C code (see §3.3).
+
+
+
+The environment associated with a C function can be directly
+accessed by C code (see §3.3).
+It is used as the default environment for other C functions
+and userdata created by the function.
+
+
+
+Environments associated with Lua functions are used to resolve
+all accesses to global variables within the function (see §2.3).
+They are used as the default environment for nested Lua functions
+created by the function.
+
+
+
+You can change the environment of a Lua function or the
+running thread by calling setfenv.
+You can get the environment of a Lua function or the running thread
+by calling getfenv.
+To manipulate the environment of other objects
+(userdata, C functions, other threads) you must
+use the C API.
+
+
+
+
+
+
+Lua performs automatic memory management.
+This means that
+you have to worry neither about allocating memory for new objects
+nor about freeing it when the objects are no longer needed.
+Lua manages memory automatically by running
+a garbage collector from time to time
+to collect all dead objects
+(that is, objects that are no longer accessible from Lua).
+All memory used by Lua is subject to automatic management:
+tables, userdata, functions, threads, strings, etc.
+
+
+
+Lua implements an incremental mark-and-sweep collector.
+It uses two numbers to control its garbage-collection cycles:
+the garbage-collector pause and
+the garbage-collector step multiplier.
+Both use percentage points as units
+(so that a value of 100 means an internal value of 1).
+
+
+
+The garbage-collector pause
+controls how long the collector waits before starting a new cycle.
+Larger values make the collector less aggressive.
+Values smaller than 100 mean the collector will not wait to
+start a new cycle.
+A value of 200 means that the collector waits for the total memory in use
+to double before starting a new cycle.
+
+
+
+The step multiplier
+controls the relative speed of the collector relative to
+memory allocation.
+Larger values make the collector more aggressive but also increase
+the size of each incremental step.
+Values smaller than 100 make the collector too slow and
+can result in the collector never finishing a cycle.
+The default, 200, means that the collector runs at "twice"
+the speed of memory allocation.
+
+
+
+You can change these numbers by calling lua_gc in C
+or collectgarbage in Lua.
+With these functions you can also control
+the collector directly (e.g., stop and restart it).
+
+
+
+
+Using the C API,
+you can set garbage-collector metamethods for userdata (see §2.8).
+These metamethods are also called finalizers.
+Finalizers allow you to coordinate Lua's garbage collection
+with external resource management
+(such as closing files, network or database connections,
+or freeing your own memory).
+
+
+
+Garbage userdata with a field __gc in their metatables are not
+collected immediately by the garbage collector.
+Instead, Lua puts them in a list.
+After the collection,
+Lua does the equivalent of the following function
+for each userdata in that list:
+
+
+ function gc_event (udata)
+ local h = metatable(udata).__gc
+ if h then
+ h(udata)
+ end
+ end
+
+
+
+At the end of each garbage-collection cycle,
+the finalizers for userdata are called in reverse
+order of their creation,
+among those collected in that cycle.
+That is, the first finalizer to be called is the one associated
+with the userdata created last in the program.
+The userdata itself is freed only in the next garbage-collection cycle.
+
+
+
+
+
+
+A weak table is a table whose elements are
+weak references.
+A weak reference is ignored by the garbage collector.
+In other words,
+if the only references to an object are weak references,
+then the garbage collector will collect this object.
+
+
+
+A weak table can have weak keys, weak values, or both.
+A table with weak keys allows the collection of its keys,
+but prevents the collection of its values.
+A table with both weak keys and weak values allows the collection of
+both keys and values.
+In any case, if either the key or the value is collected,
+the whole pair is removed from the table.
+The weakness of a table is controlled by the
+__mode field of its metatable.
+If the __mode field is a string containing the character 'k',
+the keys in the table are weak.
+If __mode contains 'v',
+the values in the table are weak.
+
+
+
+After you use a table as a metatable,
+you should not change the value of its __mode field.
+Otherwise, the weak behavior of the tables controlled by this
+metatable is undefined.
+
+
+
+
+
+
+
+
+Lua supports coroutines,
+also called collaborative multithreading.
+A coroutine in Lua represents an independent thread of execution.
+Unlike threads in multithread systems, however,
+a coroutine only suspends its execution by explicitly calling
+a yield function.
+
+
+
+You create a coroutine with a call to coroutine.create.
+Its sole argument is a function
+that is the main function of the coroutine.
+The create function only creates a new coroutine and
+returns a handle to it (an object of type thread);
+it does not start the coroutine execution.
+
+
+
+When you first call coroutine.resume,
+passing as its first argument
+a thread returned by coroutine.create,
+the coroutine starts its execution,
+at the first line of its main function.
+Extra arguments passed to coroutine.resume are passed on
+to the coroutine main function.
+After the coroutine starts running,
+it runs until it terminates or yields.
+
+
+
+A coroutine can terminate its execution in two ways:
+normally, when its main function returns
+(explicitly or implicitly, after the last instruction);
+and abnormally, if there is an unprotected error.
+In the first case, coroutine.resume returns true,
+plus any values returned by the coroutine main function.
+In case of errors, coroutine.resume returns false
+plus an error message.
+
+
+
+A coroutine yields by calling coroutine.yield.
+When a coroutine yields,
+the corresponding coroutine.resume returns immediately,
+even if the yield happens inside nested function calls
+(that is, not in the main function,
+but in a function directly or indirectly called by the main function).
+In the case of a yield, coroutine.resume also returns true,
+plus any values passed to coroutine.yield.
+The next time you resume the same coroutine,
+it continues its execution from the point where it yielded,
+with the call to coroutine.yield returning any extra
+arguments passed to coroutine.resume.
+
+
+
+Like coroutine.create,
+the coroutine.wrap function also creates a coroutine,
+but instead of returning the coroutine itself,
+it returns a function that, when called, resumes the coroutine.
+Any arguments passed to this function
+go as extra arguments to coroutine.resume.
+coroutine.wrap returns all the values returned by coroutine.resume,
+except the first one (the boolean error code).
+Unlike coroutine.resume,
+coroutine.wrap does not catch errors;
+any error is propagated to the caller.
+
+
+
+As an example,
+consider the following code:
+
+
+ function foo (a)
+ print("foo", a)
+ return coroutine.yield(2*a)
+ end
+
+ co = coroutine.create(function (a,b)
+ print("co-body", a, b)
+ local r = foo(a+1)
+ print("co-body", r)
+ local r, s = coroutine.yield(a+b, a-b)
+ print("co-body", r, s)
+ return b, "end"
+ end)
+
+ print("main", coroutine.resume(co, 1, 10))
+ print("main", coroutine.resume(co, "r"))
+ print("main", coroutine.resume(co, "x", "y"))
+ print("main", coroutine.resume(co, "x", "y"))
+
+When you run it, it produces the following output:
+
+
+ co-body 1 10
+ foo 2
+
+ main true 4
+ co-body r
+ main true 11 -9
+ co-body x y
+ main true 10 end
+ main false cannot resume dead coroutine
+
+
+This section describes the C API for Lua, that is,
+the set of C functions available to the host program to communicate
+with Lua.
+All API functions and related types and constants
+are declared in the header file lua.h.
+
+
+
+Even when we use the term "function",
+any facility in the API may be provided as a macro instead.
+All such macros use each of their arguments exactly once
+(except for the first argument, which is always a Lua state),
+and so do not generate any hidden side-effects.
+
+
+
+As in most C libraries,
+the Lua API functions do not check their arguments for validity or consistency.
+However, you can change this behavior by compiling Lua
+with a proper definition for the macro luai_apicheck,
+in file luaconf.h.
+
+
+
+
+Lua uses a virtual stack to pass values to and from C.
+Each element in this stack represents a Lua value
+(nil, number, string, etc.).
+
+
+
+Whenever Lua calls C, the called function gets a new stack,
+which is independent of previous stacks and of stacks of
+C functions that are still active.
+This stack initially contains any arguments to the C function
+and it is where the C function pushes its results
+to be returned to the caller (see lua_CFunction).
+
+
+
+For convenience,
+most query operations in the API do not follow a strict stack discipline.
+Instead, they can refer to any element in the stack
+by using an index:
+A positive index represents an absolute stack position
+(starting at 1);
+a negative index represents an offset relative to the top of the stack.
+More specifically, if the stack has n elements,
+then index 1 represents the first element
+(that is, the element that was pushed onto the stack first)
+and
+index n represents the last element;
+index -1 also represents the last element
+(that is, the element at the top)
+and index -n represents the first element.
+We say that an index is valid
+if it lies between 1 and the stack top
+(that is, if 1 ≤ abs(index) ≤ top).
+
+
+
+
+
+
+
+When you interact with Lua API,
+you are responsible for ensuring consistency.
+In particular,
+you are responsible for controlling stack overflow.
+You can use the function lua_checkstack
+to grow the stack size.
+
+
+
+Whenever Lua calls C,
+it ensures that at least LUA_MINSTACK stack positions are available.
+LUA_MINSTACK is defined as 20,
+so that usually you do not have to worry about stack space
+unless your code has loops pushing elements onto the stack.
+
+
+
+Most query functions accept as indices any value inside the
+available stack space, that is, indices up to the maximum stack size
+you have set through lua_checkstack.
+Such indices are called acceptable indices.
+More formally, we define an acceptable index
+as follows:
+
+
+Unless otherwise noted,
+any function that accepts valid indices can also be called with
+pseudo-indices,
+which represent some Lua values that are accessible to C code
+but which are not in the stack.
+Pseudo-indices are used to access the thread environment,
+the function environment,
+the registry,
+and the upvalues of a C function (see §3.4).
+
+
+
+The thread environment (where global variables live) is
+always at pseudo-index LUA_GLOBALSINDEX.
+The environment of the running C function is always
+at pseudo-index LUA_ENVIRONINDEX.
+
+
+
+To access and change the value of global variables,
+you can use regular table operations over an environment table.
+For instance, to access the value of a global variable, do
+
+
+When a C function is created,
+it is possible to associate some values with it,
+thus creating a C closure;
+these values are called upvalues and are
+accessible to the function whenever it is called
+(see lua_pushcclosure).
+
+
+
+Whenever a C function is called,
+its upvalues are located at specific pseudo-indices.
+These pseudo-indices are produced by the macro
+lua_upvalueindex.
+The first value associated with a function is at position
+lua_upvalueindex(1), and so on.
+Any access to lua_upvalueindex(n),
+where n is greater than the number of upvalues of the
+current function (but not greater than 256),
+produces an acceptable (but invalid) index.
+
+
+
+
+
+
+Lua provides a registry,
+a pre-defined table that can be used by any C code to
+store whatever Lua value it needs to store.
+This table is always located at pseudo-index
+LUA_REGISTRYINDEX.
+Any C library can store data into this table,
+but it should take care to choose keys different from those used
+by other libraries, to avoid collisions.
+Typically, you should use as key a string containing your library name
+or a light userdata with the address of a C object in your code.
+
+
+
+The integer keys in the registry are used by the reference mechanism,
+implemented by the auxiliary library,
+and therefore should not be used for other purposes.
+
+
+
+
+
+
+Internally, Lua uses the C longjmp facility to handle errors.
+(You can also choose to use exceptions if you use C++;
+see file luaconf.h.)
+When Lua faces any error
+(such as memory allocation errors, type errors, syntax errors,
+and runtime errors)
+it raises an error;
+that is, it does a long jump.
+A protected environment uses setjmp
+to set a recover point;
+any error jumps to the most recent active recover point.
+
+
+
+Most functions in the API can throw an error,
+for instance due to a memory allocation error.
+The documentation for each function indicates whether
+it can throw errors.
+
+
+
+Inside a C function you can throw an error by calling lua_error.
+
+
+
+
+
+
+Here we list all functions and types from the C API in
+alphabetical order.
+Each function has an indicator like this:
+[-o, +p, x]
+
+
+
+The first field, o,
+is how many elements the function pops from the stack.
+The second field, p,
+is how many elements the function pushes onto the stack.
+(Any function always pushes its results after popping its arguments.)
+A field in the form x|y means the function can push (or pop)
+x or y elements,
+depending on the situation;
+an interrogation mark '?' means that
+we cannot know how many elements the function pops/pushes
+by looking only at its arguments
+(e.g., they may depend on what is on the stack).
+The third field, x,
+tells whether the function may throw errors:
+'-' means the function never throws any error;
+'m' means the function may throw an error
+only due to not enough memory;
+'e' means the function may throw other kinds of errors;
+'v' means the function may throw an error on purpose.
+
+
+
+
+The type of the memory-allocation function used by Lua states.
+The allocator function must provide a
+functionality similar to realloc,
+but not exactly the same.
+Its arguments are
+ud, an opaque pointer passed to lua_newstate;
+ptr, a pointer to the block being allocated/reallocated/freed;
+osize, the original size of the block;
+nsize, the new size of the block.
+ptr is NULL if and only if osize is zero.
+When nsize is zero, the allocator must return NULL;
+if osize is not zero,
+it should free the block pointed to by ptr.
+When nsize is not zero, the allocator returns NULL
+if and only if it cannot fill the request.
+When nsize is not zero and osize is zero,
+the allocator should behave like malloc.
+When nsize and osize are not zero,
+the allocator behaves like realloc.
+Lua assumes that the allocator never fails when
+osize >= nsize.
+
+
+
+Here is a simple implementation for the allocator function.
+It is used in the auxiliary library by luaL_newstate.
+
+
+This code assumes
+that free(NULL) has no effect and that
+realloc(NULL, size) is equivalent to malloc(size).
+ANSI C ensures both behaviors.
+
+
+
+
+
+
+Sets a new panic function and returns the old one.
+
+
+
+If an error happens outside any protected environment,
+Lua calls a panic function
+and then calls exit(EXIT_FAILURE),
+thus exiting the host application.
+Your panic function can avoid this exit by
+never returning (e.g., doing a long jump).
+
+
+
+The panic function can access the error message at the top of the stack.
+
+
+
+
+
+
void lua_call (lua_State *L, int nargs, int nresults);
+
+
+Calls a function.
+
+
+
+To call a function you must use the following protocol:
+first, the function to be called is pushed onto the stack;
+then, the arguments to the function are pushed
+in direct order;
+that is, the first argument is pushed first.
+Finally you call lua_call;
+nargs is the number of arguments that you pushed onto the stack.
+All arguments and the function value are popped from the stack
+when the function is called.
+The function results are pushed onto the stack when the function returns.
+The number of results is adjusted to nresults,
+unless nresults is LUA_MULTRET.
+In this case, all results from the function are pushed.
+Lua takes care that the returned values fit into the stack space.
+The function results are pushed onto the stack in direct order
+(the first result is pushed first),
+so that after the call the last result is on the top of the stack.
+
+
+
+Any error inside the called function is propagated upwards
+(with a longjmp).
+
+
+
+The following example shows how the host program can do the
+equivalent to this Lua code:
+
+
+ a = f("how", t.x, 14)
+
+Here it is in C:
+
+
+ lua_getfield(L, LUA_GLOBALSINDEX, "f"); /* function to be called */
+ lua_pushstring(L, "how"); /* 1st argument */
+ lua_getfield(L, LUA_GLOBALSINDEX, "t"); /* table to be indexed */
+ lua_getfield(L, -1, "x"); /* push result of t.x (2nd arg) */
+ lua_remove(L, -2); /* remove 't' from the stack */
+ lua_pushinteger(L, 14); /* 3rd argument */
+ lua_call(L, 3, 1); /* call 'f' with 3 arguments and 1 result */
+ lua_setfield(L, LUA_GLOBALSINDEX, "a"); /* set global 'a' */
+
+Note that the code above is "balanced":
+at its end, the stack is back to its original configuration.
+This is considered good programming practice.
+
+
+
+
+
+
+In order to communicate properly with Lua,
+a C function must use the following protocol,
+which defines the way parameters and results are passed:
+a C function receives its arguments from Lua in its stack
+in direct order (the first argument is pushed first).
+So, when the function starts,
+lua_gettop(L) returns the number of arguments received by the function.
+The first argument (if any) is at index 1
+and its last argument is at index lua_gettop(L).
+To return values to Lua, a C function just pushes them onto the stack,
+in direct order (the first result is pushed first),
+and returns the number of results.
+Any other value in the stack below the results will be properly
+discarded by Lua.
+Like a Lua function, a C function called by Lua can also return
+many results.
+
+
+
+As an example, the following function receives a variable number
+of numerical arguments and returns their average and sum:
+
+
+ static int foo (lua_State *L) {
+ int n = lua_gettop(L); /* number of arguments */
+ lua_Number sum = 0;
+ int i;
+ for (i = 1; i <= n; i++) {
+ if (!lua_isnumber(L, i)) {
+ lua_pushstring(L, "incorrect argument");
+ lua_error(L);
+ }
+ sum += lua_tonumber(L, i);
+ }
+ lua_pushnumber(L, sum/n); /* first result */
+ lua_pushnumber(L, sum); /* second result */
+ return 2; /* number of results */
+ }
+
+Ensures that there are at least extra free stack slots in the stack.
+It returns false if it cannot grow the stack to that size.
+This function never shrinks the stack;
+if the stack is already larger than the new size,
+it is left unchanged.
+
+
+
+
+
+
+Destroys all objects in the given Lua state
+(calling the corresponding garbage-collection metamethods, if any)
+and frees all dynamic memory used by this state.
+On several platforms, you may not need to call this function,
+because all resources are naturally released when the host program ends.
+On the other hand, long-running programs,
+such as a daemon or a web server,
+might need to release states as soon as they are not needed,
+to avoid growing too large.
+
+
+
+
+
+
+Concatenates the n values at the top of the stack,
+pops them, and leaves the result at the top.
+If n is 1, the result is the single value on the stack
+(that is, the function does nothing);
+if n is 0, the result is the empty string.
+Concatenation is performed following the usual semantics of Lua
+(see §2.5.4).
+
+
+
+
+
+
int lua_cpcall (lua_State *L, lua_CFunction func, void *ud);
+
+
+Calls the C function func in protected mode.
+func starts with only one element in its stack,
+a light userdata containing ud.
+In case of errors,
+lua_cpcall returns the same error codes as lua_pcall,
+plus the error object on the top of the stack;
+otherwise, it returns zero, and does not change the stack.
+All values returned by func are discarded.
+
+
+
+
+
+
void lua_createtable (lua_State *L, int narr, int nrec);
+
+
+Creates a new empty table and pushes it onto the stack.
+The new table has space pre-allocated
+for narr array elements and nrec non-array elements.
+This pre-allocation is useful when you know exactly how many elements
+the table will have.
+Otherwise you can use the function lua_newtable.
+
+
+
+
+
+
int lua_dump (lua_State *L, lua_Writer writer, void *data);
+
+
+Dumps a function as a binary chunk.
+Receives a Lua function on the top of the stack
+and produces a binary chunk that,
+if loaded again,
+results in a function equivalent to the one dumped.
+As it produces parts of the chunk,
+lua_dump calls function writer (see lua_Writer)
+with the given data
+to write them.
+
+
+
+The value returned is the error code returned by the last
+call to the writer;
+0 means no errors.
+
+
+
+This function does not pop the Lua function from the stack.
+
+
+
+
+
+
int lua_equal (lua_State *L, int index1, int index2);
+
+
+Returns 1 if the two values in acceptable indices index1 and
+index2 are equal,
+following the semantics of the Lua == operator
+(that is, may call metamethods).
+Otherwise returns 0.
+Also returns 0 if any of the indices is non valid.
+
+
+
+
+
+
+Generates a Lua error.
+The error message (which can actually be a Lua value of any type)
+must be on the stack top.
+This function does a long jump,
+and therefore never returns.
+(see luaL_error).
+
+
+
+
+
+
+This function performs several tasks,
+according to the value of the parameter what:
+
+
+
+
LUA_GCSTOP:
+stops the garbage collector.
+
+
+
LUA_GCRESTART:
+restarts the garbage collector.
+
+
+
LUA_GCCOLLECT:
+performs a full garbage-collection cycle.
+
+
+
LUA_GCCOUNT:
+returns the current amount of memory (in Kbytes) in use by Lua.
+
+
+
LUA_GCCOUNTB:
+returns the remainder of dividing the current amount of bytes of
+memory in use by Lua by 1024.
+
+
+
LUA_GCSTEP:
+performs an incremental step of garbage collection.
+The step "size" is controlled by data
+(larger values mean more steps) in a non-specified way.
+If you want to control the step size
+you must experimentally tune the value of data.
+The function returns 1 if the step finished a
+garbage-collection cycle.
+
+
+
LUA_GCSETPAUSE:
+sets data as the new value
+for the pause of the collector (see §2.10).
+The function returns the previous value of the pause.
+
+
+
LUA_GCSETSTEPMUL:
+sets data as the new value for the step multiplier of
+the collector (see §2.10).
+The function returns the previous value of the step multiplier.
+
+Returns the memory-allocation function of a given state.
+If ud is not NULL, Lua stores in *ud the
+opaque pointer passed to lua_newstate.
+
+
+
+
+
+
void lua_getfield (lua_State *L, int index, const char *k);
+
+
+Pushes onto the stack the value t[k],
+where t is the value at the given valid index.
+As in Lua, this function may trigger a metamethod
+for the "index" event (see §2.8).
+
+
+
+
+
+
+Pushes onto the stack the metatable of the value at the given
+acceptable index.
+If the index is not valid,
+or if the value does not have a metatable,
+the function returns 0 and pushes nothing on the stack.
+
+
+
+
+
+
+Pushes onto the stack the value t[k],
+where t is the value at the given valid index
+and k is the value at the top of the stack.
+
+
+
+This function pops the key from the stack
+(putting the resulting value in its place).
+As in Lua, this function may trigger a metamethod
+for the "index" event (see §2.8).
+
+
+
+
+
+
+Returns the index of the top element in the stack.
+Because indices start at 1,
+this result is equal to the number of elements in the stack
+(and so 0 means an empty stack).
+
+
+
+
+
+
+Moves the top element into the given valid index,
+shifting up the elements above this index to open space.
+Cannot be called with a pseudo-index,
+because a pseudo-index is not an actual stack position.
+
+
+
+
+
+
+Returns 1 if the given acceptable index is not valid
+(that is, it refers to an element outside the current stack)
+or if the value at this index is nil,
+and 0 otherwise.
+
+
+
+
+
+
+Returns 1 if the value at the given acceptable index is a string
+or a number (which is always convertible to a string),
+and 0 otherwise.
+
+
+
+
+
+
int lua_lessthan (lua_State *L, int index1, int index2);
+
+
+Returns 1 if the value at acceptable index index1 is smaller
+than the value at acceptable index index2,
+following the semantics of the Lua < operator
+(that is, may call metamethods).
+Otherwise returns 0.
+Also returns 0 if any of the indices is non valid.
+
+
+
+
+
+
+Loads a Lua chunk.
+If there are no errors,
+lua_load pushes the compiled chunk as a Lua
+function on top of the stack.
+Otherwise, it pushes an error message.
+The return values of lua_load are:
+
+
+
+
0: no errors;
+
+
LUA_ERRSYNTAX:
+syntax error during pre-compilation;
+This function only loads a chunk;
+it does not run it.
+
+
+
+lua_load automatically detects whether the chunk is text or binary,
+and loads it accordingly (see program luac).
+
+
+
+The lua_load function uses a user-supplied reader function
+to read the chunk (see lua_Reader).
+The data argument is an opaque value passed to the reader function.
+
+
+
+The chunkname argument gives a name to the chunk,
+which is used for error messages and in debug information (see §3.8).
+
+
+
+
+
+
+Creates a new, independent state.
+Returns NULL if cannot create the state
+(due to lack of memory).
+The argument f is the allocator function;
+Lua does all memory allocation for this state through this function.
+The second argument, ud, is an opaque pointer that Lua
+simply passes to the allocator in every call.
+
+
+
+
+
+
+Creates a new thread, pushes it on the stack,
+and returns a pointer to a lua_State that represents this new thread.
+The new state returned by this function shares with the original state
+all global objects (such as tables),
+but has an independent execution stack.
+
+
+
+There is no explicit function to close or to destroy a thread.
+Threads are subject to garbage collection,
+like any Lua object.
+
+
+
+
+
+
+This function allocates a new block of memory with the given size,
+pushes onto the stack a new full userdata with the block address,
+and returns this address.
+
+
+
+Userdata represent C values in Lua.
+A full userdata represents a block of memory.
+It is an object (like a table):
+you must create it, it can have its own metatable,
+and you can detect when it is being collected.
+A full userdata is only equal to itself (under raw equality).
+
+
+
+When Lua collects a full userdata with a gc metamethod,
+Lua calls the metamethod and marks the userdata as finalized.
+When this userdata is collected again then
+Lua frees its corresponding memory.
+
+
+
+
+
+
+Pops a key from the stack,
+and pushes a key-value pair from the table at the given index
+(the "next" pair after the given key).
+If there are no more elements in the table,
+then lua_next returns 0 (and pushes nothing).
+
+
+
+A typical traversal looks like this:
+
+
+ /* table is in the stack at index 't' */
+ lua_pushnil(L); /* first key */
+ while (lua_next(L, t) != 0) {
+ /* uses 'key' (at index -2) and 'value' (at index -1) */
+ printf("%s - %s\n",
+ lua_typename(L, lua_type(L, -2)),
+ lua_typename(L, lua_type(L, -1)));
+ /* removes 'value'; keeps 'key' for next iteration */
+ lua_pop(L, 1);
+ }
+
+
+
+While traversing a table,
+do not call lua_tolstring directly on a key,
+unless you know that the key is actually a string.
+Recall that lua_tolstringchanges
+the value at the given index;
+this confuses the next call to lua_next.
+
+
+
+
+
+
+Returns the "length" of the value at the given acceptable index:
+for strings, this is the string length;
+for tables, this is the result of the length operator ('#');
+for userdata, this is the size of the block of memory allocated
+for the userdata;
+for other values, it is 0.
+
+
+
+
+
+
int lua_pcall (lua_State *L, int nargs, int nresults, int errfunc);
+
+
+Calls a function in protected mode.
+
+
+
+Both nargs and nresults have the same meaning as
+in lua_call.
+If there are no errors during the call,
+lua_pcall behaves exactly like lua_call.
+However, if there is any error,
+lua_pcall catches it,
+pushes a single value on the stack (the error message),
+and returns an error code.
+Like lua_call,
+lua_pcall always removes the function
+and its arguments from the stack.
+
+
+
+If errfunc is 0,
+then the error message returned on the stack
+is exactly the original error message.
+Otherwise, errfunc is the stack index of an
+error handler function.
+(In the current implementation, this index cannot be a pseudo-index.)
+In case of runtime errors,
+this function will be called with the error message
+and its return value will be the message returned on the stack by lua_pcall.
+
+
+
+Typically, the error handler function is used to add more debug
+information to the error message, such as a stack traceback.
+Such information cannot be gathered after the return of lua_pcall,
+since by then the stack has unwound.
+
+
+
+The lua_pcall function returns 0 in case of success
+or one of the following error codes
+(defined in lua.h):
+
+
void lua_pushcclosure (lua_State *L, lua_CFunction fn, int n);
+
+
+Pushes a new C closure onto the stack.
+
+
+
+When a C function is created,
+it is possible to associate some values with it,
+thus creating a C closure (see §3.4);
+these values are then accessible to the function whenever it is called.
+To associate values with a C function,
+first these values should be pushed onto the stack
+(when there are multiple values, the first value is pushed first).
+Then lua_pushcclosure
+is called to create and push the C function onto the stack,
+with the argument n telling how many values should be
+associated with the function.
+lua_pushcclosure also pops these values from the stack.
+
+
+
+Pushes a C function onto the stack.
+This function receives a pointer to a C function
+and pushes onto the stack a Lua value of type function that,
+when called, invokes the corresponding C function.
+
+
+
+Any function to be registered in Lua must
+follow the correct protocol to receive its parameters
+and return its results (see lua_CFunction).
+
+
+
+Pushes onto the stack a formatted string
+and returns a pointer to this string.
+It is similar to the C function sprintf,
+but has some important differences:
+
+
+
+
+You do not have to allocate space for the result:
+the result is a Lua string and Lua takes care of memory allocation
+(and deallocation, through garbage collection).
+
+
+
+The conversion specifiers are quite restricted.
+There are no flags, widths, or precisions.
+The conversion specifiers can only be
+'%%' (inserts a '%' in the string),
+'%s' (inserts a zero-terminated string, with no size restrictions),
+'%f' (inserts a lua_Number),
+'%p' (inserts a pointer as a hexadecimal numeral),
+'%d' (inserts an int), and
+'%c' (inserts an int as a character).
+
+Userdata represent C values in Lua.
+A light userdata represents a pointer.
+It is a value (like a number):
+you do not create it, it has no individual metatable,
+and it is not collected (as it was never created).
+A light userdata is equal to "any"
+light userdata with the same C address.
+
+
+
+
+
+
+This macro is equivalent to lua_pushlstring,
+but can be used only when s is a literal string.
+In these cases, it automatically provides the string length.
+
+
+
+
+
+
+Pushes the string pointed to by s with size len
+onto the stack.
+Lua makes (or reuses) an internal copy of the given string,
+so the memory at s can be freed or reused immediately after
+the function returns.
+The string can contain embedded zeros.
+
+
+
+
+
+
+Pushes the zero-terminated string pointed to by s
+onto the stack.
+Lua makes (or reuses) an internal copy of the given string,
+so the memory at s can be freed or reused immediately after
+the function returns.
+The string cannot contain embedded zeros;
+it is assumed to end at the first zero.
+
+
+
+
+
+
int lua_rawequal (lua_State *L, int index1, int index2);
+
+
+Returns 1 if the two values in acceptable indices index1 and
+index2 are primitively equal
+(that is, without calling metamethods).
+Otherwise returns 0.
+Also returns 0 if any of the indices are non valid.
+
+
+
+
+
+
void lua_rawgeti (lua_State *L, int index, int n);
+
+
+Pushes onto the stack the value t[n],
+where t is the value at the given valid index.
+The access is raw;
+that is, it does not invoke metamethods.
+
+
+
+
+
+
+The reader function used by lua_load.
+Every time it needs another piece of the chunk,
+lua_load calls the reader,
+passing along its data parameter.
+The reader must return a pointer to a block of memory
+with a new piece of the chunk
+and set size to the block size.
+The block must exist until the reader function is called again.
+To signal the end of the chunk,
+the reader must return NULL or set size to zero.
+The reader function may return pieces of any size greater than zero.
+
+
+
+
+
+
+Removes the element at the given valid index,
+shifting down the elements above this index to fill the gap.
+Cannot be called with a pseudo-index,
+because a pseudo-index is not an actual stack position.
+
+
+
+
+
+
+Moves the top element into the given position (and pops it),
+without shifting any element
+(therefore replacing the value at the given position).
+
+
+
+
+
+
+Starts and resumes a coroutine in a given thread.
+
+
+
+To start a coroutine, you first create a new thread
+(see lua_newthread);
+then you push onto its stack the main function plus any arguments;
+then you call lua_resume,
+with narg being the number of arguments.
+This call returns when the coroutine suspends or finishes its execution.
+When it returns, the stack contains all values passed to lua_yield,
+or all values returned by the body function.
+lua_resume returns
+LUA_YIELD if the coroutine yields,
+0 if the coroutine finishes its execution
+without errors,
+or an error code in case of errors (see lua_pcall).
+In case of errors,
+the stack is not unwound,
+so you can use the debug API over it.
+The error message is on the top of the stack.
+To restart a coroutine, you put on its stack only the values to
+be passed as results from yield,
+and then call lua_resume.
+
+
+
+
+
+
+Pops a table from the stack and sets it as
+the new environment for the value at the given index.
+If the value at the given index is
+neither a function nor a thread nor a userdata,
+lua_setfenv returns 0.
+Otherwise it returns 1.
+
+
+
+
+
+
+Does the equivalent to t[k] = v,
+where t is the value at the given valid index,
+v is the value at the top of the stack,
+and k is the value just below the top.
+
+
+
+This function pops both the key and the value from the stack.
+As in Lua, this function may trigger a metamethod
+for the "newindex" event (see §2.8).
+
+
+
+
+
+
+Accepts any acceptable index, or 0,
+and sets the stack top to this index.
+If the new top is larger than the old one,
+then the new elements are filled with nil.
+If index is 0, then all stack elements are removed.
+
+
+
+
+
+
+Opaque structure that keeps the whole state of a Lua interpreter.
+The Lua library is fully reentrant:
+it has no global variables.
+All information about a state is kept in this structure.
+
+
+
+A pointer to this state must be passed as the first argument to
+every function in the library, except to lua_newstate,
+which creates a Lua state from scratch.
+
+
+
+
+
+
+The status can be 0 for a normal thread,
+an error code if the thread finished its execution with an error,
+or LUA_YIELD if the thread is suspended.
+
+
+
+
+
+
+Converts the Lua value at the given acceptable index to a C boolean
+value (0 or 1).
+Like all tests in Lua,
+lua_toboolean returns 1 for any Lua value
+different from false and nil;
+otherwise it returns 0.
+It also returns 0 when called with a non-valid index.
+(If you want to accept only actual boolean values,
+use lua_isboolean to test the value's type.)
+
+
+
+
+
+
lua_Integer lua_tointeger (lua_State *L, int index);
+
+
+Converts the Lua value at the given acceptable index
+to the signed integral type lua_Integer.
+The Lua value must be a number or a string convertible to a number
+(see §2.2.1);
+otherwise, lua_tointeger returns 0.
+
+
+
+If the number is not an integer,
+it is truncated in some non-specified way.
+
+
+
+
+
+
const char *lua_tolstring (lua_State *L, int index, size_t *len);
+
+
+Converts the Lua value at the given acceptable index to a C string.
+If len is not NULL,
+it also sets *len with the string length.
+The Lua value must be a string or a number;
+otherwise, the function returns NULL.
+If the value is a number,
+then lua_tolstring also
+changes the actual value in the stack to a string.
+(This change confuses lua_next
+when lua_tolstring is applied to keys during a table traversal.)
+
+
+
+lua_tolstring returns a fully aligned pointer
+to a string inside the Lua state.
+This string always has a zero ('\0')
+after its last character (as in C),
+but can contain other zeros in its body.
+Because Lua has garbage collection,
+there is no guarantee that the pointer returned by lua_tolstring
+will be valid after the corresponding value is removed from the stack.
+
+
+
+
+
+
lua_Number lua_tonumber (lua_State *L, int index);
+
+
+Converts the Lua value at the given acceptable index
+to the C type lua_Number (see lua_Number).
+The Lua value must be a number or a string convertible to a number
+(see §2.2.1);
+otherwise, lua_tonumber returns 0.
+
+
+
+
+
+
const void *lua_topointer (lua_State *L, int index);
+
+
+Converts the value at the given acceptable index to a generic
+C pointer (void*).
+The value can be a userdata, a table, a thread, or a function;
+otherwise, lua_topointer returns NULL.
+Different objects will give different pointers.
+There is no way to convert the pointer back to its original value.
+
+
+
+Typically this function is used only for debug information.
+
+
+
+
+
+
lua_State *lua_tothread (lua_State *L, int index);
+
+
+Converts the value at the given acceptable index to a Lua thread
+(represented as lua_State*).
+This value must be a thread;
+otherwise, the function returns NULL.
+
+
+
+
+
+
+If the value at the given acceptable index is a full userdata,
+returns its block address.
+If the value is a light userdata,
+returns its pointer.
+Otherwise, returns NULL.
+
+
+
+
+
+
+Returns the type of the value in the given acceptable index,
+or LUA_TNONE for a non-valid index
+(that is, an index to an "empty" stack position).
+The types returned by lua_type are coded by the following constants
+defined in lua.h:
+LUA_TNIL,
+LUA_TNUMBER,
+LUA_TBOOLEAN,
+LUA_TSTRING,
+LUA_TTABLE,
+LUA_TFUNCTION,
+LUA_TUSERDATA,
+LUA_TTHREAD,
+and
+LUA_TLIGHTUSERDATA.
+
+
+
+
+
+
+The type of the writer function used by lua_dump.
+Every time it produces another piece of chunk,
+lua_dump calls the writer,
+passing along the buffer to be written (p),
+its size (sz),
+and the data parameter supplied to lua_dump.
+
+
+
+The writer returns an error code:
+0 means no errors;
+any other value means an error and stops lua_dump from
+calling the writer again.
+
+
+
+
+
+
+This function should only be called as the
+return expression of a C function, as follows:
+
+
+ return lua_yield (L, nresults);
+
+When a C function calls lua_yield in that way,
+the running coroutine suspends its execution,
+and the call to lua_resume that started this coroutine returns.
+The parameter nresults is the number of values from the stack
+that are passed as results to lua_resume.
+
+
+
+
+
+
+
+
+Lua has no built-in debugging facilities.
+Instead, it offers a special interface
+by means of functions and hooks.
+This interface allows the construction of different
+kinds of debuggers, profilers, and other tools
+that need "inside information" from the interpreter.
+
+
+
+
typedef struct lua_Debug {
+ int event;
+ const char *name; /* (n) */
+ const char *namewhat; /* (n) */
+ const char *what; /* (S) */
+ const char *source; /* (S) */
+ int currentline; /* (l) */
+ int nups; /* (u) number of upvalues */
+ int linedefined; /* (S) */
+ int lastlinedefined; /* (S) */
+ char short_src[LUA_IDSIZE]; /* (S) */
+ /* private part */
+ other fields
+} lua_Debug;
+
+
+A structure used to carry different pieces of
+information about an active function.
+lua_getstack fills only the private part
+of this structure, for later use.
+To fill the other fields of lua_Debug with useful information,
+call lua_getinfo.
+
+
+
+The fields of lua_Debug have the following meaning:
+
+
+
+
source:
+If the function was defined in a string,
+then source is that string.
+If the function was defined in a file,
+then source starts with a '@' followed by the file name.
+
+
+
short_src:
+a "printable" version of source, to be used in error messages.
+
+
+
linedefined:
+the line number where the definition of the function starts.
+
+
+
lastlinedefined:
+the line number where the definition of the function ends.
+
+
+
what:
+the string "Lua" if the function is a Lua function,
+"C" if it is a C function,
+"main" if it is the main part of a chunk,
+and "tail" if it was a function that did a tail call.
+In the latter case,
+Lua has no other information about the function.
+
+
+
currentline:
+the current line where the given function is executing.
+When no line information is available,
+currentline is set to -1.
+
+
+
name:
+a reasonable name for the given function.
+Because functions in Lua are first-class values,
+they do not have a fixed name:
+some functions can be the value of multiple global variables,
+while others can be stored only in a table field.
+The lua_getinfo function checks how the function was
+called to find a suitable name.
+If it cannot find a name,
+then name is set to NULL.
+
+
+
namewhat:
+explains the name field.
+The value of namewhat can be
+"global", "local", "method",
+"field", "upvalue", or "" (the empty string),
+according to how the function was called.
+(Lua uses the empty string when no other option seems to apply.)
+
int lua_getinfo (lua_State *L, const char *what, lua_Debug *ar);
+
+
+Returns information about a specific function or function invocation.
+
+
+
+To get information about a function invocation,
+the parameter ar must be a valid activation record that was
+filled by a previous call to lua_getstack or
+given as argument to a hook (see lua_Hook).
+
+
+
+To get information about a function you push it onto the stack
+and start the what string with the character '>'.
+(In that case,
+lua_getinfo pops the function in the top of the stack.)
+For instance, to know in which line a function f was defined,
+you can write the following code:
+
+
+ lua_Debug ar;
+ lua_getfield(L, LUA_GLOBALSINDEX, "f"); /* get global 'f' */
+ lua_getinfo(L, ">S", &ar);
+ printf("%d\n", ar.linedefined);
+
+
+
+Each character in the string what
+selects some fields of the structure ar to be filled or
+a value to be pushed on the stack:
+
+
+
+
'n': fills in the field name and namewhat;
+
+
+
'S':
+fills in the fields source, short_src,
+linedefined, lastlinedefined, and what;
+
+
+
'l': fills in the field currentline;
+
+
+
'u': fills in the field nups;
+
+
+
'f':
+pushes onto the stack the function that is
+running at the given level;
+
+
+
'L':
+pushes onto the stack a table whose indices are the
+numbers of the lines that are valid on the function.
+(A valid line is a line with some associated code,
+that is, a line where you can put a break point.
+Non-valid lines include empty lines and comments.)
+
+
+
+
+
+This function returns 0 on error
+(for instance, an invalid option in what).
+
+
+
+
+
+
const char *lua_getlocal (lua_State *L, lua_Debug *ar, int n);
+
+
+Gets information about a local variable of a given activation record.
+The parameter ar must be a valid activation record that was
+filled by a previous call to lua_getstack or
+given as argument to a hook (see lua_Hook).
+The index n selects which local variable to inspect
+(1 is the first parameter or active local variable, and so on,
+until the last active local variable).
+lua_getlocal pushes the variable's value onto the stack
+and returns its name.
+
+
+
+Variable names starting with '(' (open parentheses)
+represent internal variables
+(loop control variables, temporaries, and C function locals).
+
+
+
+Returns NULL (and pushes nothing)
+when the index is greater than
+the number of active local variables.
+
+
+
+
+
+
int lua_getstack (lua_State *L, int level, lua_Debug *ar);
+
+
+Get information about the interpreter runtime stack.
+
+
+
+This function fills parts of a lua_Debug structure with
+an identification of the activation record
+of the function executing at a given level.
+Level 0 is the current running function,
+whereas level n+1 is the function that has called level n.
+When there are no errors, lua_getstack returns 1;
+when called with a level greater than the stack depth,
+it returns 0.
+
+
+
+
+
+
const char *lua_getupvalue (lua_State *L, int funcindex, int n);
+
+
+Gets information about a closure's upvalue.
+(For Lua functions,
+upvalues are the external local variables that the function uses,
+and that are consequently included in its closure.)
+lua_getupvalue gets the index n of an upvalue,
+pushes the upvalue's value onto the stack,
+and returns its name.
+funcindex points to the closure in the stack.
+(Upvalues have no particular order,
+as they are active through the whole function.
+So, they are numbered in an arbitrary order.)
+
+
+
+Returns NULL (and pushes nothing)
+when the index is greater than the number of upvalues.
+For C functions, this function uses the empty string ""
+as a name for all upvalues.
+
+
+
+
+
+
+Whenever a hook is called, its ar argument has its field
+event set to the specific event that triggered the hook.
+Lua identifies these events with the following constants:
+LUA_HOOKCALL, LUA_HOOKRET,
+LUA_HOOKTAILRET, LUA_HOOKLINE,
+and LUA_HOOKCOUNT.
+Moreover, for line events, the field currentline is also set.
+To get the value of any other field in ar,
+the hook must call lua_getinfo.
+For return events, event can be LUA_HOOKRET,
+the normal value, or LUA_HOOKTAILRET.
+In the latter case, Lua is simulating a return from
+a function that did a tail call;
+in this case, it is useless to call lua_getinfo.
+
+
+
+While Lua is running a hook, it disables other calls to hooks.
+Therefore, if a hook calls back Lua to execute a function or a chunk,
+this execution occurs without any calls to hooks.
+
+
+
+
+
+
int lua_sethook (lua_State *L, lua_Hook f, int mask, int count);
+
+
+Sets the debugging hook function.
+
+
+
+Argument f is the hook function.
+mask specifies on which events the hook will be called:
+it is formed by a bitwise or of the constants
+LUA_MASKCALL,
+LUA_MASKRET,
+LUA_MASKLINE,
+and LUA_MASKCOUNT.
+The count argument is only meaningful when the mask
+includes LUA_MASKCOUNT.
+For each event, the hook is called as explained below:
+
+
+
+
The call hook: is called when the interpreter calls a function.
+The hook is called just after Lua enters the new function,
+before the function gets its arguments.
+
+
+
The return hook: is called when the interpreter returns from a function.
+The hook is called just before Lua leaves the function.
+You have no access to the values to be returned by the function.
+
+
+
The line hook: is called when the interpreter is about to
+start the execution of a new line of code,
+or when it jumps back in the code (even to the same line).
+(This event only happens while Lua is executing a Lua function.)
+
+
+
The count hook: is called after the interpreter executes every
+count instructions.
+(This event only happens while Lua is executing a Lua function.)
+
+
+
+
+
+A hook is disabled by setting mask to zero.
+
+
+
+
+
+
const char *lua_setlocal (lua_State *L, lua_Debug *ar, int n);
+
+
+Sets the value of a local variable of a given activation record.
+Parameters ar and n are as in lua_getlocal
+(see lua_getlocal).
+lua_setlocal assigns the value at the top of the stack
+to the variable and returns its name.
+It also pops the value from the stack.
+
+
+
+Returns NULL (and pops nothing)
+when the index is greater than
+the number of active local variables.
+
+
+
+
+
+
const char *lua_setupvalue (lua_State *L, int funcindex, int n);
+
+
+Sets the value of a closure's upvalue.
+It assigns the value at the top of the stack
+to the upvalue and returns its name.
+It also pops the value from the stack.
+Parameters funcindex and n are as in the lua_getupvalue
+(see lua_getupvalue).
+
+
+
+Returns NULL (and pops nothing)
+when the index is greater than the number of upvalues.
+
+
+
+
+
+
+
+
+
+The auxiliary library provides several convenient functions
+to interface C with Lua.
+While the basic API provides the primitive functions for all
+interactions between C and Lua,
+the auxiliary library provides higher-level functions for some
+common tasks.
+
+
+
+All functions from the auxiliary library
+are defined in header file lauxlib.h and
+have a prefix luaL_.
+
+
+
+All functions in the auxiliary library are built on
+top of the basic API,
+and so they provide nothing that cannot be done with this API.
+
+
+
+Several functions in the auxiliary library are used to
+check C function arguments.
+Their names are always luaL_check* or luaL_opt*.
+All of these functions throw an error if the check is not satisfied.
+Because the error message is formatted for arguments
+(e.g., "bad argument #1"),
+you should not use these functions for other stack values.
+
+
+
+
+Adds the value at the top of the stack
+to the buffer B
+(see luaL_Buffer).
+Pops the value.
+
+
+
+This is the only function on string buffers that can (and must)
+be called with an extra element on the stack,
+which is the value to be added to the buffer.
+
+
+
+
+
+
+A string buffer allows C code to build Lua strings piecemeal.
+Its pattern of use is as follows:
+
+
+
+
First you declare a variable b of type luaL_Buffer.
+
+
Then you initialize it with a call luaL_buffinit(L, &b).
+
+
+Then you add string pieces to the buffer calling any of
+the luaL_add* functions.
+
+
+
+You finish by calling luaL_pushresult(&b).
+This call leaves the final string on the top of the stack.
+
+
+
+
+
+During its normal operation,
+a string buffer uses a variable number of stack slots.
+So, while using a buffer, you cannot assume that you know where
+the top of the stack is.
+You can use the stack between successive calls to buffer operations
+as long as that use is balanced;
+that is,
+when you call a buffer operation,
+the stack is at the same level
+it was immediately after the previous buffer operation.
+(The only exception to this rule is luaL_addvalue.)
+After calling luaL_pushresult the stack is back to its
+level when the buffer was initialized,
+plus the final string on its top.
+
+
+
+
+
+
int luaL_callmeta (lua_State *L, int obj, const char *e);
+
+
+Calls a metamethod.
+
+
+
+If the object at index obj has a metatable and this
+metatable has a field e,
+this function calls this field and passes the object as its only argument.
+In this case this function returns 1 and pushes onto the
+stack the value returned by the call.
+If there is no metatable or no metamethod,
+this function returns 0 (without pushing any value on the stack).
+
+
+
+
+
+
int luaL_checkoption (lua_State *L,
+ int narg,
+ const char *def,
+ const char *const lst[]);
+
+
+Checks whether the function argument narg is a string and
+searches for this string in the array lst
+(which must be NULL-terminated).
+Returns the index in the array where the string was found.
+Raises an error if the argument is not a string or
+if the string cannot be found.
+
+
+
+If def is not NULL,
+the function uses def as a default value when
+there is no argument narg or if this argument is nil.
+
+
+
+This is a useful function for mapping strings to C enums.
+(The usual convention in Lua libraries is
+to use strings instead of numbers to select options.)
+
+
+
+
+
+
void luaL_checkstack (lua_State *L, int sz, const char *msg);
+
+
+Grows the stack size to top + sz elements,
+raising an error if the stack cannot grow to that size.
+msg is an additional text to go into the error message.
+
+
+
+
+
+
int luaL_error (lua_State *L, const char *fmt, ...);
+
+
+Raises an error.
+The error message format is given by fmt
+plus any extra arguments,
+following the same rules of lua_pushfstring.
+It also adds at the beginning of the message the file name and
+the line number where the error occurred,
+if this information is available.
+
+
+
+This function never returns,
+but it is an idiom to use it in C functions
+as return luaL_error(args).
+
+
+
+
+
+
int luaL_getmetafield (lua_State *L, int obj, const char *e);
+
+
+Pushes onto the stack the field e from the metatable
+of the object at index obj.
+If the object does not have a metatable,
+or if the metatable does not have this field,
+returns 0 and pushes nothing.
+
+
+
+
+
+
+Creates a copy of string s by replacing
+any occurrence of the string p
+with the string r.
+Pushes the resulting string on the stack and returns it.
+
+
+
+
+
+
int luaL_loadfile (lua_State *L, const char *filename);
+
+
+Loads a file as a Lua chunk.
+This function uses lua_load to load the chunk in the file
+named filename.
+If filename is NULL,
+then it loads from the standard input.
+The first line in the file is ignored if it starts with a #.
+
+
+
+This function returns the same results as lua_load,
+but it has an extra error code LUA_ERRFILE
+if it cannot open/read the file.
+
+
+
+As lua_load, this function only loads the chunk;
+it does not run it.
+
+
+
+
+
+
int luaL_newmetatable (lua_State *L, const char *tname);
+
+
+If the registry already has the key tname,
+returns 0.
+Otherwise,
+creates a new table to be used as a metatable for userdata,
+adds it to the registry with key tname,
+and returns 1.
+
+
+
+In both cases pushes onto the stack the final value associated
+with tname in the registry.
+
+
+
+
+
+
+Creates a new Lua state.
+It calls lua_newstate with an
+allocator based on the standard C realloc function
+and then sets a panic function (see lua_atpanic) that prints
+an error message to the standard error output in case of fatal
+errors.
+
+
+
+Returns the new state,
+or NULL if there is a memory allocation error.
+
+
+
+
+
+
+If the function argument narg is a number,
+returns this number cast to an int.
+If this argument is absent or is nil,
+returns d.
+Otherwise, raises an error.
+
+
+
+
+
+
lua_Integer luaL_optinteger (lua_State *L,
+ int narg,
+ lua_Integer d);
+
+
+If the function argument narg is a number,
+returns this number cast to a lua_Integer.
+If this argument is absent or is nil,
+returns d.
+Otherwise, raises an error.
+
+
+
+
+
+
long luaL_optlong (lua_State *L, int narg, long d);
+
+
+If the function argument narg is a number,
+returns this number cast to a long.
+If this argument is absent or is nil,
+returns d.
+Otherwise, raises an error.
+
+
+
+
+
+
+If the function argument narg is a string,
+returns this string.
+If this argument is absent or is nil,
+returns d.
+Otherwise, raises an error.
+
+
+
+If l is not NULL,
+fills the position *l with the results's length.
+
+
+
+
+
+
lua_Number luaL_optnumber (lua_State *L, int narg, lua_Number d);
+
+
+If the function argument narg is a number,
+returns this number.
+If this argument is absent or is nil,
+returns d.
+Otherwise, raises an error.
+
+
+
+
+
+
+If the function argument narg is a string,
+returns this string.
+If this argument is absent or is nil,
+returns d.
+Otherwise, raises an error.
+
+
+
+
+
+
+Returns an address to a space of size LUAL_BUFFERSIZE
+where you can copy a string to be added to buffer B
+(see luaL_Buffer).
+After copying the string into this space you must call
+luaL_addsize with the size of the string to actually add
+it to the buffer.
+
+
+
+
+
+
+Creates and returns a reference,
+in the table at index t,
+for the object at the top of the stack (and pops the object).
+
+
+
+A reference is a unique integer key.
+As long as you do not manually add integer keys into table t,
+luaL_ref ensures the uniqueness of the key it returns.
+You can retrieve an object referred by reference r
+by calling lua_rawgeti(L, t, r).
+Function luaL_unref frees a reference and its associated object.
+
+
+
+If the object at the top of the stack is nil,
+luaL_ref returns the constant LUA_REFNIL.
+The constant LUA_NOREF is guaranteed to be different
+from any reference returned by luaL_ref.
+
+
+
+
+
+
+Type for arrays of functions to be registered by
+luaL_register.
+name is the function name and func is a pointer to
+the function.
+Any array of luaL_Reg must end with an sentinel entry
+in which both name and func are NULL.
+
+
+
+
+
+
+When called with libname equal to NULL,
+it simply registers all functions in the list l
+(see luaL_Reg) into the table on the top of the stack.
+
+
+
+When called with a non-null libname,
+luaL_register creates a new table t,
+sets it as the value of the global variable libname,
+sets it as the value of package.loaded[libname],
+and registers on it all functions in the list l.
+If there is a table in package.loaded[libname] or in
+variable libname,
+reuses this table instead of creating a new one.
+
+
+
+In any case the function leaves the table
+on the top of the stack.
+
+
+
+
+
+
+Releases reference ref from the table at index t
+(see luaL_ref).
+The entry is removed from the table,
+so that the referred object can be collected.
+The reference ref is also freed to be used again.
+
+
+
+Pushes onto the stack a string identifying the current position
+of the control at level lvl in the call stack.
+Typically this string has the following format:
+
+
+ chunkname:currentline:
+
+Level 0 is the running function,
+level 1 is the function that called the running function,
+etc.
+
+
+
+This function is used to build a prefix for error messages.
+
+
+
+
+
+
+
+
+The standard Lua libraries provide useful functions
+that are implemented directly through the C API.
+Some of these functions provide essential services to the language
+(e.g., type and getmetatable);
+others provide access to "outside" services (e.g., I/O);
+and others could be implemented in Lua itself,
+but are quite useful or have critical performance requirements that
+deserve an implementation in C (e.g., table.sort).
+
+
+
+All libraries are implemented through the official C API
+and are provided as separate C modules.
+Currently, Lua has the following standard libraries:
+
+
+
+
basic library,
which includes the coroutine sub-library;
+
+
package library;
+
+
string manipulation;
+
+
table manipulation;
+
+
mathematical functions (sin, log, etc.);
+
+
input and output;
+
+
operating system facilities;
+
+
debug facilities.
+
+
+Except for the basic and package libraries,
+each library provides all its functions as fields of a global table
+or as methods of its objects.
+
+
+
+To have access to these libraries,
+the C host program should call the luaL_openlibs function,
+which opens all standard libraries.
+Alternatively,
+it can open them individually by calling
+luaopen_base (for the basic library),
+luaopen_package (for the package library),
+luaopen_string (for the string library),
+luaopen_table (for the table library),
+luaopen_math (for the mathematical library),
+luaopen_io (for the I/O library),
+luaopen_os (for the Operating System library),
+and luaopen_debug (for the debug library).
+These functions are declared in lualib.h
+and should not be called directly:
+you must call them like any other Lua C function,
+e.g., by using lua_call.
+
+
+
+
+The basic library provides some core functions to Lua.
+If you do not include this library in your application,
+you should check carefully whether you need to provide
+implementations for some of its facilities.
+
+
+
+Issues an error when
+the value of its argument v is false (i.e., nil or false);
+otherwise, returns all its arguments.
+message is an error message;
+when absent, it defaults to "assertion failed!"
+
+
+
+
+
+This function is a generic interface to the garbage collector.
+It performs different functions according to its first argument, opt:
+
+
+
+
"stop":
+stops the garbage collector.
+
+
+
"restart":
+restarts the garbage collector.
+
+
+
"collect":
+performs a full garbage-collection cycle.
+
+
+
"count":
+returns the total memory in use by Lua (in Kbytes).
+
+
+
"step":
+performs a garbage-collection step.
+The step "size" is controlled by arg
+(larger values mean more steps) in a non-specified way.
+If you want to control the step size
+you must experimentally tune the value of arg.
+Returns true if the step finished a collection cycle.
+
+
+
"setpause":
+sets arg as the new value for the pause of
+the collector (see §2.10).
+Returns the previous value for pause.
+
+
+
"setstepmul":
+sets arg as the new value for the step multiplier of
+the collector (see §2.10).
+Returns the previous value for step.
+
+Opens the named file and executes its contents as a Lua chunk.
+When called without arguments,
+dofile executes the contents of the standard input (stdin).
+Returns all values returned by the chunk.
+In case of errors, dofile propagates the error
+to its caller (that is, dofile does not run in protected mode).
+
+
+
+
+
+Terminates the last protected function called
+and returns message as the error message.
+Function error never returns.
+
+
+
+Usually, error adds some information about the error position
+at the beginning of the message.
+The level argument specifies how to get the error position.
+With level 1 (the default), the error position is where the
+error function was called.
+Level 2 points the error to where the function
+that called error was called; and so on.
+Passing a level 0 avoids the addition of error position information
+to the message.
+
+
+
+
+
+A global variable (not a function) that
+holds the global environment (that is, _G._G = _G).
+Lua itself does not use this variable;
+changing its value does not affect any environment,
+nor vice-versa.
+(Use setfenv to change environments.)
+
+
+
+
+
+Returns the current environment in use by the function.
+f can be a Lua function or a number
+that specifies the function at that stack level:
+Level 1 is the function calling getfenv.
+If the given function is not a Lua function,
+or if f is 0,
+getfenv returns the global environment.
+The default for f is 1.
+
+
+
+
+
+If object does not have a metatable, returns nil.
+Otherwise,
+if the object's metatable has a "__metatable" field,
+returns the associated value.
+Otherwise, returns the metatable of the given object.
+
+
+
+
+
+Loads a chunk using function func to get its pieces.
+Each call to func must return a string that concatenates
+with previous results.
+A return of an empty string, nil, or no value signals the end of the chunk.
+
+
+
+If there are no errors,
+returns the compiled chunk as a function;
+otherwise, returns nil plus the error message.
+The environment of the returned function is the global environment.
+
+
+
+chunkname is used as the chunk name for error messages
+and debug information.
+When absent,
+it defaults to "=(load)".
+
+
+
+
+
+Allows a program to traverse all fields of a table.
+Its first argument is a table and its second argument
+is an index in this table.
+next returns the next index of the table
+and its associated value.
+When called with nil as its second argument,
+next returns an initial index
+and its associated value.
+When called with the last index,
+or with nil in an empty table,
+next returns nil.
+If the second argument is absent, then it is interpreted as nil.
+In particular,
+you can use next(t) to check whether a table is empty.
+
+
+
+The order in which the indices are enumerated is not specified,
+even for numeric indices.
+(To traverse a table in numeric order,
+use a numerical for or the ipairs function.)
+
+
+
+The behavior of next is undefined if,
+during the traversal,
+you assign any value to a non-existent field in the table.
+You may however modify existing fields.
+In particular, you may clear existing fields.
+
+
+
+
+
+Calls function f with
+the given arguments in protected mode.
+This means that any error inside f is not propagated;
+instead, pcall catches the error
+and returns a status code.
+Its first result is the status code (a boolean),
+which is true if the call succeeds without errors.
+In such case, pcall also returns all results from the call,
+after this first result.
+In case of any error, pcall returns false plus the error message.
+
+
+
+
+
+Receives any number of arguments,
+and prints their values to stdout,
+using the tostring function to convert them to strings.
+print is not intended for formatted output,
+but only as a quick way to show a value,
+typically for debugging.
+For formatted output, use string.format.
+
+
+
+
+
+Sets the real value of table[index] to value,
+without invoking any metamethod.
+table must be a table,
+index any value different from nil,
+and value any Lua value.
+
+
+
+If index is a number,
+returns all arguments after argument number index.
+Otherwise, index must be the string "#",
+and select returns the total number of extra arguments it received.
+
+
+
+
+
+Sets the environment to be used by the given function.
+f can be a Lua function or a number
+that specifies the function at that stack level:
+Level 1 is the function calling setfenv.
+setfenv returns the given function.
+
+
+
+As a special case, when f is 0 setfenv changes
+the environment of the running thread.
+In this case, setfenv returns no values.
+
+
+
+
+
+Sets the metatable for the given table.
+(You cannot change the metatable of other types from Lua, only from C.)
+If metatable is nil,
+removes the metatable of the given table.
+If the original metatable has a "__metatable" field,
+raises an error.
+
+
+
+Tries to convert its argument to a number.
+If the argument is already a number or a string convertible
+to a number, then tonumber returns this number;
+otherwise, it returns nil.
+
+
+
+An optional argument specifies the base to interpret the numeral.
+The base may be any integer between 2 and 36, inclusive.
+In bases above 10, the letter 'A' (in either upper or lower case)
+represents 10, 'B' represents 11, and so forth,
+with 'Z' representing 35.
+In base 10 (the default), the number can have a decimal part,
+as well as an optional exponent part (see §2.1).
+In other bases, only unsigned integers are accepted.
+
+
+
+
+
+Receives an argument of any type and
+converts it to a string in a reasonable format.
+For complete control of how numbers are converted,
+use string.format.
+
+
+
+If the metatable of e has a "__tostring" field,
+then tostring calls the corresponding value
+with e as argument,
+and uses the result of the call as its result.
+
+
+
+
+
+Returns the type of its only argument, coded as a string.
+The possible results of this function are
+"nil" (a string, not the value nil),
+"number",
+"string",
+"boolean",
+"table",
+"function",
+"thread",
+and "userdata".
+
+
+
+
+
+Returns the elements from the given table.
+This function is equivalent to
+
+
+ return list[i], list[i+1], ···, list[j]
+
+except that the above code can be written only for a fixed number
+of elements.
+By default, i is 1 and j is the length of the list,
+as defined by the length operator (see §2.5.5).
+
+
+
+
+
+A global variable (not a function) that
+holds a string containing the current interpreter version.
+The current contents of this variable is "Lua 5.1".
+
+
+
+
+
+This function is similar to pcall,
+except that you can set a new error handler.
+
+
+
+xpcall calls function f in protected mode,
+using err as the error handler.
+Any error inside f is not propagated;
+instead, xpcall catches the error,
+calls the err function with the original error object,
+and returns a status code.
+Its first result is the status code (a boolean),
+which is true if the call succeeds without errors.
+In this case, xpcall also returns all results from the call,
+after this first result.
+In case of any error,
+xpcall returns false plus the result from err.
+
+
+
+
+
+
+
+
+The operations related to coroutines comprise a sub-library of
+the basic library and come inside the table coroutine.
+See §2.11 for a general description of coroutines.
+
+
+
+Starts or continues the execution of coroutine co.
+The first time you resume a coroutine,
+it starts running its body.
+The values val1, ··· are passed
+as the arguments to the body function.
+If the coroutine has yielded,
+resume restarts it;
+the values val1, ··· are passed
+as the results from the yield.
+
+
+
+If the coroutine runs without any errors,
+resume returns true plus any values passed to yield
+(if the coroutine yields) or any values returned by the body function
+(if the coroutine terminates).
+If there is any error,
+resume returns false plus the error message.
+
+
+
+
+
+Returns the status of coroutine co, as a string:
+"running",
+if the coroutine is running (that is, it called status);
+"suspended", if the coroutine is suspended in a call to yield,
+or if it has not started running yet;
+"normal" if the coroutine is active but not running
+(that is, it has resumed another coroutine);
+and "dead" if the coroutine has finished its body function,
+or if it has stopped with an error.
+
+
+
+
+
+Creates a new coroutine, with body f.
+f must be a Lua function.
+Returns a function that resumes the coroutine each time it is called.
+Any arguments passed to the function behave as the
+extra arguments to resume.
+Returns the same values returned by resume,
+except the first boolean.
+In case of error, propagates the error.
+
+
+
+
+
+Suspends the execution of the calling coroutine.
+The coroutine cannot be running a C function,
+a metamethod, or an iterator.
+Any arguments to yield are passed as extra results to resume.
+
+
+
+
+
+
+
+
+The package library provides basic
+facilities for loading and building modules in Lua.
+It exports two of its functions directly in the global environment:
+require and module.
+Everything else is exported in a table package.
+
+
+
+Creates a module.
+If there is a table in package.loaded[name],
+this table is the module.
+Otherwise, if there is a global table t with the given name,
+this table is the module.
+Otherwise creates a new table t and
+sets it as the value of the global name and
+the value of package.loaded[name].
+This function also initializes t._NAME with the given name,
+t._M with the module (t itself),
+and t._PACKAGE with the package name
+(the full module name minus last component; see below).
+Finally, module sets t as the new environment
+of the current function and the new value of package.loaded[name],
+so that require returns t.
+
+
+
+If name is a compound name
+(that is, one with components separated by dots),
+module creates (or reuses, if they already exist)
+tables for each component.
+For instance, if name is a.b.c,
+then module stores the module table in field c of
+field b of global a.
+
+
+
+This function can receive optional options after
+the module name,
+where each option is a function to be applied over the module.
+
+
+
+
+
+Loads the given module.
+The function starts by looking into the package.loaded table
+to determine whether modname is already loaded.
+If it is, then require returns the value stored
+at package.loaded[modname].
+Otherwise, it tries to find a loader for the module.
+
+
+
+To find a loader,
+require is guided by the package.loaders array.
+By changing this array,
+we can change how require looks for a module.
+The following explanation is based on the default configuration
+for package.loaders.
+
+
+
+First require queries package.preload[modname].
+If it has a value,
+this value (which should be a function) is the loader.
+Otherwise require searches for a Lua loader using the
+path stored in package.path.
+If that also fails, it searches for a C loader using the
+path stored in package.cpath.
+If that also fails,
+it tries an all-in-one loader (see package.loaders).
+
+
+
+Once a loader is found,
+require calls the loader with a single argument, modname.
+If the loader returns any value,
+require assigns the returned value to package.loaded[modname].
+If the loader returns no value and
+has not assigned any value to package.loaded[modname],
+then require assigns true to this entry.
+In any case, require returns the
+final value of package.loaded[modname].
+
+
+
+If there is any error loading or running the module,
+or if it cannot find any loader for the module,
+then require signals an error.
+
+
+
+
+
+The path used by require to search for a C loader.
+
+
+
+Lua initializes the C path package.cpath in the same way
+it initializes the Lua path package.path,
+using the environment variable LUA_CPATH
+or a default path defined in luaconf.h.
+
+
+
+
+
+A table used by require to control which
+modules are already loaded.
+When you require a module modname and
+package.loaded[modname] is not false,
+require simply returns the value stored there.
+
+
+
+
+
+A table used by require to control how to load modules.
+
+
+
+Each entry in this table is a searcher function.
+When looking for a module,
+require calls each of these searchers in ascending order,
+with the module name (the argument given to require) as its
+sole parameter.
+The function can return another function (the module loader)
+or a string explaining why it did not find that module
+(or nil if it has nothing to say).
+Lua initializes this table with four functions.
+
+
+
+The first searcher simply looks for a loader in the
+package.preload table.
+
+
+
+The second searcher looks for a loader as a Lua library,
+using the path stored at package.path.
+A path is a sequence of templates separated by semicolons.
+For each template,
+the searcher will change each interrogation
+mark in the template by filename,
+which is the module name with each dot replaced by a
+"directory separator" (such as "/" in Unix);
+then it will try to open the resulting file name.
+So, for instance, if the Lua path is the string
+
+
+ "./?.lua;./?.lc;/usr/local/?/init.lua"
+
+the search for a Lua file for module foo
+will try to open the files
+./foo.lua, ./foo.lc, and
+/usr/local/foo/init.lua, in that order.
+
+
+
+The third searcher looks for a loader as a C library,
+using the path given by the variable package.cpath.
+For instance,
+if the C path is the string
+
+
+ "./?.so;./?.dll;/usr/local/?/init.so"
+
+the searcher for module foo
+will try to open the files ./foo.so, ./foo.dll,
+and /usr/local/foo/init.so, in that order.
+Once it finds a C library,
+this searcher first uses a dynamic link facility to link the
+application with the library.
+Then it tries to find a C function inside the library to
+be used as the loader.
+The name of this C function is the string "luaopen_"
+concatenated with a copy of the module name where each dot
+is replaced by an underscore.
+Moreover, if the module name has a hyphen,
+its prefix up to (and including) the first hyphen is removed.
+For instance, if the module name is a.v1-b.c,
+the function name will be luaopen_b_c.
+
+
+
+The fourth searcher tries an all-in-one loader.
+It searches the C path for a library for
+the root name of the given module.
+For instance, when requiring a.b.c,
+it will search for a C library for a.
+If found, it looks into it for an open function for
+the submodule;
+in our example, that would be luaopen_a_b_c.
+With this facility, a package can pack several C submodules
+into one single library,
+with each submodule keeping its original open function.
+
+
+
+
+
+Dynamically links the host program with the C library libname.
+Inside this library, looks for a function funcname
+and returns this function as a C function.
+(So, funcname must follow the protocol (see lua_CFunction)).
+
+
+
+This is a low-level function.
+It completely bypasses the package and module system.
+Unlike require,
+it does not perform any path searching and
+does not automatically adds extensions.
+libname must be the complete file name of the C library,
+including if necessary a path and extension.
+funcname must be the exact name exported by the C library
+(which may depend on the C compiler and linker used).
+
+
+
+This function is not supported by ANSI C.
+As such, it is only available on some platforms
+(Windows, Linux, Mac OS X, Solaris, BSD,
+plus other Unix systems that support the dlfcn standard).
+
+
+
+
+
+The path used by require to search for a Lua loader.
+
+
+
+At start-up, Lua initializes this variable with
+the value of the environment variable LUA_PATH or
+with a default path defined in luaconf.h,
+if the environment variable is not defined.
+Any ";;" in the value of the environment variable
+is replaced by the default path.
+
+
+
+
+
+Sets a metatable for module with
+its __index field referring to the global environment,
+so that this module inherits values
+from the global environment.
+To be used as an option to function module.
+
+
+
+
+
+
+
+
+This library provides generic functions for string manipulation,
+such as finding and extracting substrings, and pattern matching.
+When indexing a string in Lua, the first character is at position 1
+(not at 0, as in C).
+Indices are allowed to be negative and are interpreted as indexing backwards,
+from the end of the string.
+Thus, the last character is at position -1, and so on.
+
+
+
+The string library provides all its functions inside the table
+string.
+It also sets a metatable for strings
+where the __index field points to the string table.
+Therefore, you can use the string functions in object-oriented style.
+For instance, string.byte(s, i)
+can be written as s:byte(i).
+
+
+
+The string library assumes one-byte character encodings.
+
+
+
+Receives zero or more integers.
+Returns a string with length equal to the number of arguments,
+in which each character has the internal numerical code equal
+to its corresponding argument.
+
+
+
+Note that numerical codes are not necessarily portable across platforms.
+
+
+
+
+
+Returns a string containing a binary representation of the given function,
+so that a later loadstring on this string returns
+a copy of the function.
+function must be a Lua function without upvalues.
+
+
+
+
+
+Looks for the first match of
+pattern in the string s.
+If it finds a match, then find returns the indices of s
+where this occurrence starts and ends;
+otherwise, it returns nil.
+A third, optional numerical argument init specifies
+where to start the search;
+its default value is 1 and can be negative.
+A value of true as a fourth, optional argument plain
+turns off the pattern matching facilities,
+so the function does a plain "find substring" operation,
+with no characters in pattern being considered "magic".
+Note that if plain is given, then init must be given as well.
+
+
+
+If the pattern has captures,
+then in a successful match
+the captured values are also returned,
+after the two indices.
+
+
+
+
+
+Returns a formatted version of its variable number of arguments
+following the description given in its first argument (which must be a string).
+The format string follows the same rules as the printf family of
+standard C functions.
+The only differences are that the options/modifiers
+*, l, L, n, p,
+and h are not supported
+and that there is an extra option, q.
+The q option formats a string in a form suitable to be safely read
+back by the Lua interpreter:
+the string is written between double quotes,
+and all double quotes, newlines, embedded zeros,
+and backslashes in the string
+are correctly escaped when written.
+For instance, the call
+
+
+ string.format('%q', 'a string with "quotes" and \n new line')
+
+will produce the string:
+
+
+ "a string with \"quotes\" and \
+ new line"
+
+
+
+The options c, d, E, e, f,
+g, G, i, o, u, X, and x all
+expect a number as argument,
+whereas q and s expect a string.
+
+
+
+This function does not accept string values
+containing embedded zeros,
+except as arguments to the q option.
+
+
+
+
+
+Returns an iterator function that,
+each time it is called,
+returns the next captures from pattern over string s.
+If pattern specifies no captures,
+then the whole match is produced in each call.
+
+
+
+As an example, the following loop
+
+
+ s = "hello world from Lua"
+ for w in string.gmatch(s, "%a+") do
+ print(w)
+ end
+
+will iterate over all the words from string s,
+printing one per line.
+The next example collects all pairs key=value from the
+given string into a table:
+
+
+ t = {}
+ s = "from=world, to=Lua"
+ for k, v in string.gmatch(s, "(%w+)=(%w+)") do
+ t[k] = v
+ end
+
+
+
+For this function, a '^' at the start of a pattern does not
+work as an anchor, as this would prevent the iteration.
+
+
+
+
+
+Returns a copy of s
+in which all (or the first n, if given)
+occurrences of the pattern have been
+replaced by a replacement string specified by repl,
+which can be a string, a table, or a function.
+gsub also returns, as its second value,
+the total number of matches that occurred.
+
+
+
+If repl is a string, then its value is used for replacement.
+The character % works as an escape character:
+any sequence in repl of the form %n,
+with n between 1 and 9,
+stands for the value of the n-th captured substring (see below).
+The sequence %0 stands for the whole match.
+The sequence %% stands for a single %.
+
+
+
+If repl is a table, then the table is queried for every match,
+using the first capture as the key;
+if the pattern specifies no captures,
+then the whole match is used as the key.
+
+
+
+If repl is a function, then this function is called every time a
+match occurs, with all captured substrings passed as arguments,
+in order;
+if the pattern specifies no captures,
+then the whole match is passed as a sole argument.
+
+
+
+If the value returned by the table query or by the function call
+is a string or a number,
+then it is used as the replacement string;
+otherwise, if it is false or nil,
+then there is no replacement
+(that is, the original match is kept in the string).
+
+
+
+Here are some examples:
+
+
+ x = string.gsub("hello world", "(%w+)", "%1 %1")
+ --> x="hello hello world world"
+
+ x = string.gsub("hello world", "%w+", "%0 %0", 1)
+ --> x="hello hello world"
+
+ x = string.gsub("hello world from Lua", "(%w+)%s*(%w+)", "%2 %1")
+ --> x="world hello Lua from"
+
+ x = string.gsub("home = $HOME, user = $USER", "%$(%w+)", os.getenv)
+ --> x="home = /home/roberto, user = roberto"
+
+ x = string.gsub("4+5 = $return 4+5$", "%$(.-)%$", function (s)
+ return loadstring(s)()
+ end)
+ --> x="4+5 = 9"
+
+ local t = {name="lua", version="5.1"}
+ x = string.gsub("$name-$version.tar.gz", "%$(%w+)", t)
+ --> x="lua-5.1.tar.gz"
+
+Receives a string and returns a copy of this string with all
+uppercase letters changed to lowercase.
+All other characters are left unchanged.
+The definition of what an uppercase letter is depends on the current locale.
+
+
+
+
+
+Looks for the first match of
+pattern in the string s.
+If it finds one, then match returns
+the captures from the pattern;
+otherwise it returns nil.
+If pattern specifies no captures,
+then the whole match is returned.
+A third, optional numerical argument init specifies
+where to start the search;
+its default value is 1 and can be negative.
+
+
+
+
+
+Returns the substring of s that
+starts at i and continues until j;
+i and j can be negative.
+If j is absent, then it is assumed to be equal to -1
+(which is the same as the string length).
+In particular,
+the call string.sub(s,1,j) returns a prefix of s
+with length j,
+and string.sub(s, -i) returns a suffix of s
+with length i.
+
+
+
+
+
+Receives a string and returns a copy of this string with all
+lowercase letters changed to uppercase.
+All other characters are left unchanged.
+The definition of what a lowercase letter is depends on the current locale.
+
+
+
+
+A character class is used to represent a set of characters.
+The following combinations are allowed in describing a character class:
+
+
+
+
x:
+(where x is not one of the magic characters
+^$()%.[]*+-?)
+represents the character x itself.
+
+
+
.: (a dot) represents all characters.
+
+
%a: represents all letters.
+
+
%c: represents all control characters.
+
+
%d: represents all digits.
+
+
%l: represents all lowercase letters.
+
+
%p: represents all punctuation characters.
+
+
%s: represents all space characters.
+
+
%u: represents all uppercase letters.
+
+
%w: represents all alphanumeric characters.
+
+
%x: represents all hexadecimal digits.
+
+
%z: represents the character with representation 0.
+
+
%x: (where x is any non-alphanumeric character)
+represents the character x.
+This is the standard way to escape the magic characters.
+Any punctuation character (even the non magic)
+can be preceded by a '%'
+when used to represent itself in a pattern.
+
+
+
[set]:
+represents the class which is the union of all
+characters in set.
+A range of characters can be specified by
+separating the end characters of the range with a '-'.
+All classes %x described above can also be used as
+components in set.
+All other characters in set represent themselves.
+For example, [%w_] (or [_%w])
+represents all alphanumeric characters plus the underscore,
+[0-7] represents the octal digits,
+and [0-7%l%-] represents the octal digits plus
+the lowercase letters plus the '-' character.
+
+
+
+The interaction between ranges and classes is not defined.
+Therefore, patterns like [%a-z] or [a-%%]
+have no meaning.
+
+
+
[^set]:
+represents the complement of set,
+where set is interpreted as above.
+
+
+
+For all classes represented by single letters (%a, %c, etc.),
+the corresponding uppercase letter represents the complement of the class.
+For instance, %S represents all non-space characters.
+
+
+
+The definitions of letter, space, and other character groups
+depend on the current locale.
+In particular, the class [a-z] may not be equivalent to %l.
+
+
+
+
+
+
Pattern Item:
+A pattern item can be
+
+
+
+
+a single character class,
+which matches any single character in the class;
+
+
+
+a single character class followed by '*',
+which matches 0 or more repetitions of characters in the class.
+These repetition items will always match the longest possible sequence;
+
+
+
+a single character class followed by '+',
+which matches 1 or more repetitions of characters in the class.
+These repetition items will always match the longest possible sequence;
+
+
+
+a single character class followed by '-',
+which also matches 0 or more repetitions of characters in the class.
+Unlike '*',
+these repetition items will always match the shortest possible sequence;
+
+
+
+a single character class followed by '?',
+which matches 0 or 1 occurrence of a character in the class;
+
+
+
+%n, for n between 1 and 9;
+such item matches a substring equal to the n-th captured string
+(see below);
+
+
+
+%bxy, where x and y are two distinct characters;
+such item matches strings that start with x, end with y,
+and where the x and y are balanced.
+This means that, if one reads the string from left to right,
+counting +1 for an x and -1 for a y,
+the ending y is the first y where the count reaches 0.
+For instance, the item %b() matches expressions with
+balanced parentheses.
+
+
+
+
+
+
+
+
Pattern:
+A pattern is a sequence of pattern items.
+A '^' at the beginning of a pattern anchors the match at the
+beginning of the subject string.
+A '$' at the end of a pattern anchors the match at the
+end of the subject string.
+At other positions,
+'^' and '$' have no special meaning and represent themselves.
+
+
+
+
+
+
Captures:
+A pattern can contain sub-patterns enclosed in parentheses;
+they describe captures.
+When a match succeeds, the substrings of the subject string
+that match captures are stored (captured) for future use.
+Captures are numbered according to their left parentheses.
+For instance, in the pattern "(a*(.)%w(%s*))",
+the part of the string matching "a*(.)%w(%s*)" is
+stored as the first capture (and therefore has number 1);
+the character matching "." is captured with number 2,
+and the part matching "%s*" has number 3.
+
+
+
+As a special case, the empty capture () captures
+the current string position (a number).
+For instance, if we apply the pattern "()aa()" on the
+string "flaaap", there will be two captures: 3 and 5.
+
+
+
+This library provides generic functions for table manipulation.
+It provides all its functions inside the table table.
+
+
+
+Most functions in the table library assume that the table
+represents an array or a list.
+For these functions, when we talk about the "length" of a table
+we mean the result of the length operator.
+
+
+
+Given an array where all elements are strings or numbers,
+returns table[i]..sep..table[i+1] ··· sep..table[j].
+The default value for sep is the empty string,
+the default for i is 1,
+and the default for j is the length of the table.
+If i is greater than j, returns the empty string.
+
+
+
+
+
+Inserts element value at position pos in table,
+shifting up other elements to open space, if necessary.
+The default value for pos is n+1,
+where n is the length of the table (see §2.5.5),
+so that a call table.insert(t,x) inserts x at the end
+of table t.
+
+
+
+
+
+Returns the largest positive numerical index of the given table,
+or zero if the table has no positive numerical indices.
+(To do its job this function does a linear traversal of
+the whole table.)
+
+
+
+
+
+Removes from table the element at position pos,
+shifting down other elements to close the space, if necessary.
+Returns the value of the removed element.
+The default value for pos is n,
+where n is the length of the table,
+so that a call table.remove(t) removes the last element
+of table t.
+
+
+
+
+
+Sorts table elements in a given order, in-place,
+from table[1] to table[n],
+where n is the length of the table.
+If comp is given,
+then it must be a function that receives two table elements,
+and returns true
+when the first is less than the second
+(so that not comp(a[i+1],a[i]) will be true after the sort).
+If comp is not given,
+then the standard Lua operator < is used instead.
+
+
+
+The sort algorithm is not stable;
+that is, elements considered equal by the given order
+may have their relative positions changed by the sort.
+
+
+
+
+
+
+
+
+Returns the arc tangent of y/x (in radians),
+but uses the signs of both parameters to find the
+quadrant of the result.
+(It also handles correctly the case of x being zero.)
+
+
+
+
+
+This function is an interface to the simple
+pseudo-random generator function rand provided by ANSI C.
+(No guarantees can be given for its statistical properties.)
+
+
+
+When called without arguments,
+returns a uniform pseudo-random real number
+in the range [0,1).
+When called with an integer number m,
+math.random returns
+a uniform pseudo-random integer in the range [1, m].
+When called with two integer numbers m and n,
+math.random returns a uniform pseudo-random
+integer in the range [m, n].
+
+
+
+
+
+The I/O library provides two different styles for file manipulation.
+The first one uses implicit file descriptors;
+that is, there are operations to set a default input file and a
+default output file,
+and all input/output operations are over these default files.
+The second style uses explicit file descriptors.
+
+
+
+When using implicit file descriptors,
+all operations are supplied by table io.
+When using explicit file descriptors,
+the operation io.open returns a file descriptor
+and then all operations are supplied as methods of the file descriptor.
+
+
+
+The table io also provides
+three predefined file descriptors with their usual meanings from C:
+io.stdin, io.stdout, and io.stderr.
+The I/O library never closes these files.
+
+
+
+Unless otherwise stated,
+all I/O functions return nil on failure
+(plus an error message as a second result and
+a system-dependent error code as a third result)
+and some value different from nil on success.
+
+
+
+When called with a file name, it opens the named file (in text mode),
+and sets its handle as the default input file.
+When called with a file handle,
+it simply sets this file handle as the default input file.
+When called without parameters,
+it returns the current default input file.
+
+
+
+In case of errors this function raises the error,
+instead of returning an error code.
+
+
+
+
+
+Opens the given file name in read mode
+and returns an iterator function that,
+each time it is called,
+returns a new line from the file.
+Therefore, the construction
+
+
+ for line in io.lines(filename) do body end
+
+will iterate over all lines of the file.
+When the iterator function detects the end of file,
+it returns nil (to finish the loop) and automatically closes the file.
+
+
+
+The call io.lines() (with no file name) is equivalent
+to io.input():lines();
+that is, it iterates over the lines of the default input file.
+In this case it does not close the file when the loop ends.
+
+
+
+
+
+This function opens a file,
+in the mode specified in the string mode.
+It returns a new file handle,
+or, in case of errors, nil plus an error message.
+
+
+
+The mode string can be any of the following:
+
+
+
"r": read mode (the default);
+
"w": write mode;
+
"a": append mode;
+
"r+": update mode, all previous data is preserved;
+
"w+": update mode, all previous data is erased;
+
"a+": append update mode, previous data is preserved,
+ writing is only allowed at the end of file.
+
+The mode string can also have a 'b' at the end,
+which is needed in some systems to open the file in binary mode.
+This string is exactly what is used in the
+standard C function fopen.
+
+
+
+
+
+Starts program prog in a separated process and returns
+a file handle that you can use to read data from this program
+(if mode is "r", the default)
+or to write data to this program
+(if mode is "w").
+
+
+
+This function is system dependent and is not available
+on all platforms.
+
+
+
+
+
+Checks whether obj is a valid file handle.
+Returns the string "file" if obj is an open file handle,
+"closed file" if obj is a closed file handle,
+or nil if obj is not a file handle.
+
+
+
+
+
+Closes file.
+Note that files are automatically closed when
+their handles are garbage collected,
+but that takes an unpredictable amount of time to happen.
+
+
+
+
+
+Reads the file file,
+according to the given formats, which specify what to read.
+For each format,
+the function returns a string (or a number) with the characters read,
+or nil if it cannot read data with the specified format.
+When called without formats,
+it uses a default format that reads the entire next line
+(see below).
+
+
+
+The available formats are
+
+
+
+
"*n":
+reads a number;
+this is the only format that returns a number instead of a string.
+
+
+
"*a":
+reads the whole file, starting at the current position.
+On end of file, it returns the empty string.
+
+
+
"*l":
+reads the next line (skipping the end of line),
+returning nil on end of file.
+This is the default format.
+
+
+
number:
+reads a string with up to this number of characters,
+returning nil on end of file.
+If number is zero,
+it reads nothing and returns an empty string,
+or nil on end of file.
+
+Sets and gets the file position,
+measured from the beginning of the file,
+to the position given by offset plus a base
+specified by the string whence, as follows:
+
+
+
"set": base is position 0 (beginning of the file);
+
"cur": base is current position;
+
"end": base is end of file;
+
+In case of success, function seek returns the final file position,
+measured in bytes from the beginning of the file.
+If this function fails, it returns nil,
+plus a string describing the error.
+
+
+
+The default value for whence is "cur",
+and for offset is 0.
+Therefore, the call file:seek() returns the current
+file position, without changing it;
+the call file:seek("set") sets the position to the
+beginning of the file (and returns 0);
+and the call file:seek("end") sets the position to the
+end of the file, and returns its size.
+
+
+
+
+
+Writes the value of each of its arguments to
+the file.
+The arguments must be strings or numbers.
+To write other values,
+use tostring or string.format before write.
+
+
+
+
+
+
+
+
+Returns a string or a table containing date and time,
+formatted according to the given string format.
+
+
+
+If the time argument is present,
+this is the time to be formatted
+(see the os.time function for a description of this value).
+Otherwise, date formats the current time.
+
+
+
+If format starts with '!',
+then the date is formatted in Coordinated Universal Time.
+After this optional character,
+if format is the string "*t",
+then date returns a table with the following fields:
+year (four digits), month (1--12), day (1--31),
+hour (0--23), min (0--59), sec (0--61),
+wday (weekday, Sunday is 1),
+yday (day of the year),
+and isdst (daylight saving flag, a boolean).
+
+
+
+If format is not "*t",
+then date returns the date as a string,
+formatted according to the same rules as the C function strftime.
+
+
+
+When called without arguments,
+date returns a reasonable date and time representation that depends on
+the host system and on the current locale
+(that is, os.date() is equivalent to os.date("%c")).
+
+
+
+
+
+This function is equivalent to the C function system.
+It passes command to be executed by an operating system shell.
+It returns a status code, which is system-dependent.
+If command is absent, then it returns nonzero if a shell is available
+and zero otherwise.
+
+
+
+
+
+Deletes the file or directory with the given name.
+Directories must be empty to be removed.
+If this function fails, it returns nil,
+plus a string describing the error.
+
+
+
+
+
+Sets the current locale of the program.
+locale is a string specifying a locale;
+category is an optional string describing which category to change:
+"all", "collate", "ctype",
+"monetary", "numeric", or "time";
+the default category is "all".
+The function returns the name of the new locale,
+or nil if the request cannot be honored.
+
+
+
+If locale is the empty string,
+the current locale is set to an implementation-defined native locale.
+If locale is the string "C",
+the current locale is set to the standard C locale.
+
+
+
+When called with nil as the first argument,
+this function only returns the name of the current locale
+for the given category.
+
+
+
+
+
+Returns the current time when called without arguments,
+or a time representing the date and time specified by the given table.
+This table must have fields year, month, and day,
+and may have fields hour, min, sec, and isdst
+(for a description of these fields, see the os.date function).
+
+
+
+The returned value is a number, whose meaning depends on your system.
+In POSIX, Windows, and some other systems, this number counts the number
+of seconds since some given start time (the "epoch").
+In other systems, the meaning is not specified,
+and the number returned by time can be used only as an argument to
+date and difftime.
+
+
+
+
+
+Returns a string with a file name that can
+be used for a temporary file.
+The file must be explicitly opened before its use
+and explicitly removed when no longer needed.
+
+
+
+On some systems (POSIX),
+this function also creates a file with that name,
+to avoid security risks.
+(Someone else might create the file with wrong permissions
+in the time between getting the name and creating the file.)
+You still have to open the file to use it
+and to remove it (even if you do not use it).
+
+
+
+When possible,
+you may prefer to use io.tmpfile,
+which automatically removes the file when the program ends.
+
+
+
+
+
+
+
+
+This library provides
+the functionality of the debug interface to Lua programs.
+You should exert care when using this library.
+The functions provided here should be used exclusively for debugging
+and similar tasks, such as profiling.
+Please resist the temptation to use them as a
+usual programming tool:
+they can be very slow.
+Moreover, several of these functions
+violate some assumptions about Lua code
+(e.g., that variables local to a function
+cannot be accessed from outside or
+that userdata metatables cannot be changed by Lua code)
+and therefore can compromise otherwise secure code.
+
+
+
+All functions in this library are provided
+inside the debug table.
+All functions that operate over a thread
+have an optional first argument which is the
+thread to operate over.
+The default is always the current thread.
+
+
+
+Enters an interactive mode with the user,
+running each string that the user enters.
+Using simple commands and other debug facilities,
+the user can inspect global and local variables,
+change their values, evaluate expressions, and so on.
+A line containing only the word cont finishes this function,
+so that the caller continues its execution.
+
+
+
+Note that commands for debug.debug are not lexically nested
+within any function, and so have no direct access to local variables.
+
+
+
+
+
+Returns the current hook settings of the thread, as three values:
+the current hook function, the current hook mask,
+and the current hook count
+(as set by the debug.sethook function).
+
+
+
+
+
+Returns a table with information about a function.
+You can give the function directly,
+or you can give a number as the value of function,
+which means the function running at level function of the call stack
+of the given thread:
+level 0 is the current function (getinfo itself);
+level 1 is the function that called getinfo;
+and so on.
+If function is a number larger than the number of active functions,
+then getinfo returns nil.
+
+
+
+The returned table can contain all the fields returned by lua_getinfo,
+with the string what describing which fields to fill in.
+The default for what is to get all information available,
+except the table of valid lines.
+If present,
+the option 'f'
+adds a field named func with the function itself.
+If present,
+the option 'L'
+adds a field named activelines with the table of
+valid lines.
+
+
+
+For instance, the expression debug.getinfo(1,"n").name returns
+a table with a name for the current function,
+if a reasonable name can be found,
+and the expression debug.getinfo(print)
+returns a table with all available information
+about the print function.
+
+
+
+
+
+This function returns the name and the value of the local variable
+with index local of the function at level level of the stack.
+(The first parameter or local variable has index 1, and so on,
+until the last active local variable.)
+The function returns nil if there is no local
+variable with the given index,
+and raises an error when called with a level out of range.
+(You can call debug.getinfo to check whether the level is valid.)
+
+
+
+Variable names starting with '(' (open parentheses)
+represent internal variables
+(loop control variables, temporaries, and C function locals).
+
+
+
+
+
+This function returns the name and the value of the upvalue
+with index up of the function func.
+The function returns nil if there is no upvalue with the given index.
+
+
+
+
+
+Sets the given function as a hook.
+The string mask and the number count describe
+when the hook will be called.
+The string mask may have the following characters,
+with the given meaning:
+
+
+
"c": the hook is called every time Lua calls a function;
+
"r": the hook is called every time Lua returns from a function;
+
"l": the hook is called every time Lua enters a new line of code.
+
+With a count different from zero,
+the hook is called after every count instructions.
+
+
+
+When called without arguments,
+debug.sethook turns off the hook.
+
+
+
+When the hook is called, its first parameter is a string
+describing the event that has triggered its call:
+"call", "return" (or "tail return",
+when simulating a return from a tail call),
+"line", and "count".
+For line events,
+the hook also gets the new line number as its second parameter.
+Inside a hook,
+you can call getinfo with level 2 to get more information about
+the running function
+(level 0 is the getinfo function,
+and level 1 is the hook function),
+unless the event is "tail return".
+In this case, Lua is only simulating the return,
+and a call to getinfo will return invalid data.
+
+
+
+
+
+This function assigns the value value to the local variable
+with index local of the function at level level of the stack.
+The function returns nil if there is no local
+variable with the given index,
+and raises an error when called with a level out of range.
+(You can call getinfo to check whether the level is valid.)
+Otherwise, it returns the name of the local variable.
+
+
+
+
+
+This function assigns the value value to the upvalue
+with index up of the function func.
+The function returns nil if there is no upvalue
+with the given index.
+Otherwise, it returns the name of the upvalue.
+
+
+
+
+
+Returns a string with a traceback of the call stack.
+An optional message string is appended
+at the beginning of the traceback.
+An optional level number tells at which level
+to start the traceback
+(default is 1, the function calling traceback).
+
+
+
+
+
+
+
+
+Although Lua has been designed as an extension language,
+to be embedded in a host C program,
+it is also frequently used as a stand-alone language.
+An interpreter for Lua as a stand-alone language,
+called simply lua,
+is provided with the standard distribution.
+The stand-alone interpreter includes
+all standard libraries, including the debug library.
+Its usage is:
+
+
+ lua [options] [script [args]]
+
+The options are:
+
+
+
-e stat: executes string stat;
+
-l mod: "requires" mod;
+
-i: enters interactive mode after running script;
+
-v: prints version information;
+
--: stops handling options;
+
-: executes stdin as a file and stops handling options.
+
+After handling its options, lua runs the given script,
+passing to it the given args as string arguments.
+When called without arguments,
+lua behaves as lua -v -i
+when the standard input (stdin) is a terminal,
+and as lua - otherwise.
+
+
+
+Before running any argument,
+the interpreter checks for an environment variable LUA_INIT.
+If its format is @filename,
+then lua executes the file.
+Otherwise, lua executes the string itself.
+
+
+
+All options are handled in order, except -i.
+For instance, an invocation like
+
+
+ $ lua -e'a=1' -e 'print(a)' script.lua
+
+will first set a to 1, then print the value of a (which is '1'),
+and finally run the file script.lua with no arguments.
+(Here $ is the shell prompt. Your prompt may be different.)
+
+
+
+Before starting to run the script,
+lua collects all arguments in the command line
+in a global table called arg.
+The script name is stored at index 0,
+the first argument after the script name goes to index 1,
+and so on.
+Any arguments before the script name
+(that is, the interpreter name plus the options)
+go to negative indices.
+For instance, in the call
+
+
+ $ lua -la b.lua t1 t2
+
+the interpreter first runs the file a.lua,
+then creates a table
+
+
+and finally runs the file b.lua.
+The script is called with arg[1], arg[2], ···
+as arguments;
+it can also access these arguments with the vararg expression '...'.
+
+
+
+In interactive mode,
+if you write an incomplete statement,
+the interpreter waits for its completion
+by issuing a different prompt.
+
+
+
+If the global variable _PROMPT contains a string,
+then its value is used as the prompt.
+Similarly, if the global variable _PROMPT2 contains a string,
+its value is used as the secondary prompt
+(issued during incomplete statements).
+Therefore, both prompts can be changed directly on the command line
+or in any Lua programs by assigning to _PROMPT.
+See the next example:
+
+
+ $ lua -e"_PROMPT='myprompt> '" -i
+
+(The outer pair of quotes is for the shell,
+the inner pair is for Lua.)
+Note the use of -i to enter interactive mode;
+otherwise,
+the program would just end silently
+right after the assignment to _PROMPT.
+
+
+
+To allow the use of Lua as a
+script interpreter in Unix systems,
+the stand-alone interpreter skips
+the first line of a chunk if it starts with #.
+Therefore, Lua scripts can be made into executable programs
+by using chmod +x and the #! form,
+as in
+
+
+ #!/usr/local/bin/lua
+
+(Of course,
+the location of the Lua interpreter may be different in your machine.
+If lua is in your PATH,
+then
+
+
+Here we list the incompatibilities that you may find when moving a program
+from Lua 5.0 to Lua 5.1.
+You can avoid most of the incompatibilities compiling Lua with
+appropriate options (see file luaconf.h).
+However,
+all these compatibility options will be removed in the next version of Lua.
+
+
+
+
+The vararg system changed from the pseudo-argument arg with a
+table with the extra arguments to the vararg expression.
+(See compile-time option LUA_COMPAT_VARARG in luaconf.h.)
+
+
+
+There was a subtle change in the scope of the implicit
+variables of the for statement and for the repeat statement.
+
+
+
+The long string/long comment syntax ([[string]])
+does not allow nesting.
+You can use the new syntax ([=[string]=]) in these cases.
+(See compile-time option LUA_COMPAT_LSTR in luaconf.h.)
+
+Function string.gfind was renamed string.gmatch.
+(See compile-time option LUA_COMPAT_GFIND in luaconf.h.)
+
+
+
+When string.gsub is called with a function as its
+third argument,
+whenever this function returns nil or false the
+replacement string is the whole match,
+instead of the empty string.
+
+
+
+Function table.setn was deprecated.
+Function table.getn corresponds
+to the new length operator (#);
+use the operator instead of the function.
+(See compile-time option LUA_COMPAT_GETN in luaconf.h.)
+
+
+
+Function loadlib was renamed package.loadlib.
+(See compile-time option LUA_COMPAT_LOADLIB in luaconf.h.)
+
+
+
+Function math.mod was renamed math.fmod.
+(See compile-time option LUA_COMPAT_MOD in luaconf.h.)
+
+
+
+Functions table.foreach and table.foreachi are deprecated.
+You can use a for loop with pairs or ipairs instead.
+
+
+
+There were substantial changes in function require due to
+the new module system.
+However, the new behavior is mostly compatible with the old,
+but require gets the path from package.path instead
+of from LUA_PATH.
+
+
+
+Function collectgarbage has different arguments.
+Function gcinfo is deprecated;
+use collectgarbage("count") instead.
+
+The luaopen_* functions (to open libraries)
+cannot be called directly,
+like a regular C function.
+They must be called through Lua,
+like a Lua function.
+
+
+
+Function lua_open was replaced by lua_newstate to
+allow the user to set a memory-allocation function.
+You can use luaL_newstate from the standard library to
+create a state with a standard allocation function
+(based on realloc).
+
+
+
+Functions luaL_getn and luaL_setn
+(from the auxiliary library) are deprecated.
+Use lua_objlen instead of luaL_getn
+and nothing instead of luaL_setn.
+
+
+
+Function luaL_openlib was replaced by luaL_register.
+
+
+
+Function luaL_checkudata now throws an error when the given value
+is not a userdata of the expected type.
+(In Lua 5.0 it returned NULL.)
+
+
+Last update:
+Tue Aug 12 14:46:07 BRT 2008
+
+
+
+
diff --git a/libraries/LuaJIT-1.1.7/dynasm/dasm_proto.h b/libraries/LuaJIT-1.1.7/dynasm/dasm_proto.h
new file mode 100644
index 0000000..c194cba
--- /dev/null
+++ b/libraries/LuaJIT-1.1.7/dynasm/dasm_proto.h
@@ -0,0 +1,68 @@
+/*
+** DynASM encoding engine prototypes.
+** Copyright (C) 2005-2008 Mike Pall. All rights reserved.
+** Released under the MIT/X license. See dynasm.lua for full copyright notice.
+*/
+
+#ifndef _DASM_PROTO_H
+#define _DASM_PROTO_H
+
+#include
+#include
+
+#define DASM_VERSION 10104 /* 1.1.4 */
+
+#ifndef Dst_DECL
+#define Dst_DECL dasm_State *Dst
+#endif
+
+#ifndef Dst_GET
+#define Dst_GET (Dst)
+#endif
+
+#ifndef DASM_FDEF
+#define DASM_FDEF extern
+#endif
+
+
+/* Internal DynASM encoder state. */
+typedef struct dasm_State dasm_State;
+
+/* Action list type. */
+typedef const unsigned char *dasm_ActList;
+
+
+/* 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, dasm_ActList 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 */
diff --git a/libraries/LuaJIT-1.1.7/dynasm/dasm_x86.h b/libraries/LuaJIT-1.1.7/dynasm/dasm_x86.h
new file mode 100644
index 0000000..2d4fb26
--- /dev/null
+++ b/libraries/LuaJIT-1.1.7/dynasm/dasm_x86.h
@@ -0,0 +1,455 @@
+/*
+** DynASM x86 encoding engine.
+** Copyright (C) 2005-2008 Mike Pall. All rights reserved.
+** Released under the MIT/X license. See dynasm.lua for full copyright notice.
+*/
+
+#include
+#include
+#include
+#include
+
+#define DASM_ARCH "x86"
+
+/* Action definitions. DASM_STOP must be 255. */
+enum {
+ DASM_DISP = 235,
+ DASM_IMM_S, DASM_IMM_B, DASM_IMM_W, DASM_IMM_D, DASM_IMM_WB, DASM_IMM_DB,
+ DASM_SPACE, DASM_SETLABEL, DASM_REL_A, DASM_REL_LG, DASM_REL_PC, DASM_IMM_LG,
+ DASM_IMM_PC, DASM_LABEL_LG, DASM_LABEL_PC, DASM_ALIGN, DASM_ESC, DASM_MARK,
+ DASM_SECTION, DASM_STOP
+};
+
+/* Maximum number of section buffer positions for a single dasm_put() call. */
+#define DASM_MAXSECPOS 25
+
+/* DynASM encoder status codes. Action list offset or number are or'ed in. */
+#define DASM_S_OK 0x00000000
+#define DASM_S_NOMEM 0x01000000
+#define DASM_S_PHASE 0x02000000
+#define DASM_S_MATCH_SEC 0x03000000
+#define DASM_S_RANGE_I 0x11000000
+#define DASM_S_RANGE_SEC 0x12000000
+#define DASM_S_RANGE_LG 0x13000000
+#define DASM_S_RANGE_PC 0x14000000
+#define DASM_S_UNDEF_L 0x21000000
+#define DASM_S_UNDEF_PC 0x22000000
+
+/* Macros to convert positions (8 bit section + 24 bit index). */
+#define DASM_POS2IDX(pos) ((pos)&0x00ffffff)
+#define DASM_POS2BIAS(pos) ((pos)&0xff000000)
+#define DASM_SEC2POS(sec) ((sec)<<24)
+#define DASM_POS2SEC(pos) ((pos)>>24)
+#define DASM_POS2PTR(D, pos) (D->sections[DASM_POS2SEC(pos)].rbuf + (pos))
+
+/* Per-section structure. */
+typedef struct dasm_Section {
+ int *rbuf; /* Biased buffer pointer (negative section bias). */
+ int *buf; /* True buffer pointer. */
+ size_t bsize; /* Buffer size in bytes. */
+ int pos; /* Biased buffer position. */
+ int epos; /* End of biased buffer position - max single put. */
+ int ofs; /* Byte offset into section. */
+} dasm_Section;
+
+/* Core structure holding the DynASM encoding state. */
+struct dasm_State {
+ size_t psize; /* Allocated size of this structure. */
+ dasm_ActList actionlist; /* Current actionlist pointer. */
+ int *lglabels; /* Local/global chain/pos ptrs. */
+ size_t lgsize;
+ int *pclabels; /* PC label chains/pos ptrs. */
+ size_t pcsize;
+ void **globals; /* Array of globals (bias -10). */
+ dasm_Section *section; /* Pointer to active section. */
+ size_t codesize; /* Total size of all code sections. */
+ int maxsection; /* 0 <= sectionidx < maxsection. */
+ int status; /* Status code. */
+ dasm_Section sections[1]; /* All sections. Alloc-extended. */
+};
+
+/* The size of the core structure depends on the max. number of sections. */
+#define DASM_PSZ(ms) (sizeof(dasm_State)+(ms-1)*sizeof(dasm_Section))
+
+
+/* Initialize DynASM state. */
+void dasm_init(Dst_DECL, int maxsection)
+{
+ dasm_State *D;
+ size_t psz = 0;
+ int i;
+ Dst_REF = NULL;
+ DASM_M_GROW(Dst, struct dasm_State, Dst_REF, psz, DASM_PSZ(maxsection));
+ D = Dst_REF;
+ D->psize = psz;
+ D->lglabels = NULL;
+ D->lgsize = 0;
+ D->pclabels = NULL;
+ D->pcsize = 0;
+ D->globals = NULL;
+ D->maxsection = maxsection;
+ for (i = 0; i < maxsection; i++) {
+ D->sections[i].buf = NULL; /* Need this for pass3. */
+ D->sections[i].rbuf = D->sections[i].buf - DASM_SEC2POS(i);
+ D->sections[i].bsize = 0;
+ D->sections[i].epos = 0; /* Wrong, but is recalculated after resize. */
+ }
+}
+
+/* Free DynASM state. */
+void dasm_free(Dst_DECL)
+{
+ dasm_State *D = Dst_REF;
+ int i;
+ for (i = 0; i < D->maxsection; i++)
+ if (D->sections[i].buf)
+ DASM_M_FREE(Dst, D->sections[i].buf, D->sections[i].bsize);
+ if (D->pclabels) DASM_M_FREE(Dst, D->pclabels, D->pcsize);
+ if (D->lglabels) DASM_M_FREE(Dst, D->lglabels, D->lgsize);
+ DASM_M_FREE(Dst, D, D->psize);
+}
+
+/* Setup global label array. Must be called before dasm_setup(). */
+void dasm_setupglobal(Dst_DECL, void **gl, unsigned int maxgl)
+{
+ dasm_State *D = Dst_REF;
+ D->globals = gl - 10; /* Negative bias to compensate for locals. */
+ DASM_M_GROW(Dst, int, D->lglabels, D->lgsize, (10+maxgl)*sizeof(int));
+}
+
+/* Grow PC label array. Can be called after dasm_setup(), too. */
+void dasm_growpc(Dst_DECL, unsigned int maxpc)
+{
+ dasm_State *D = Dst_REF;
+ size_t osz = D->pcsize;
+ DASM_M_GROW(Dst, int, D->pclabels, D->pcsize, maxpc*sizeof(int));
+ memset((void *)(((unsigned char *)D->pclabels)+osz), 0, D->pcsize-osz);
+}
+
+/* Setup encoder. */
+void dasm_setup(Dst_DECL, dasm_ActList actionlist)
+{
+ dasm_State *D = Dst_REF;
+ int i;
+ D->actionlist = actionlist;
+ D->status = DASM_S_OK;
+ D->section = &D->sections[0];
+ memset((void *)D->lglabels, 0, D->lgsize);
+ if (D->pclabels) memset((void *)D->pclabels, 0, D->pcsize);
+ for (i = 0; i < D->maxsection; i++) {
+ D->sections[i].pos = DASM_SEC2POS(i);
+ D->sections[i].ofs = 0;
+ }
+}
+
+
+#ifdef DASM_CHECKS
+#define CK(x, st) \
+ do { if (!(x)) { \
+ D->status = DASM_S_##st|(p-D->actionlist-1); return; } } while (0)
+#define CKPL(kind, st) \
+ do { if ((size_t)((char *)pl-(char *)D->kind##labels) >= D->kind##size) { \
+ D->status = DASM_S_RANGE_##st|(p-D->actionlist-1); return; } } while (0)
+#else
+#define CK(x, st) ((void)0)
+#define CKPL(kind, st) ((void)0)
+#endif
+
+/* Pass 1: Store actions and args, link branches/labels, estimate offsets. */
+void dasm_put(Dst_DECL, int start, ...)
+{
+ va_list ap;
+ dasm_State *D = Dst_REF;
+ dasm_ActList p = D->actionlist + start;
+ dasm_Section *sec = D->section;
+ int pos = sec->pos, ofs = sec->ofs, mrm = 4;
+ int *b;
+
+ if (pos >= sec->epos) {
+ DASM_M_GROW(Dst, int, sec->buf, sec->bsize,
+ sec->bsize + 2*DASM_MAXSECPOS*sizeof(int));
+ sec->rbuf = sec->buf - DASM_POS2BIAS(pos);
+ sec->epos = sec->bsize/sizeof(int) - DASM_MAXSECPOS + DASM_POS2BIAS(pos);
+ }
+
+ b = sec->rbuf;
+ b[pos++] = start;
+
+ va_start(ap, start);
+ while (1) {
+ int action = *p++;
+ if (action < DASM_DISP) {
+ ofs++;
+ } else if (action <= DASM_REL_A) {
+ int n = va_arg(ap, int);
+ b[pos++] = n;
+ switch (action) {
+ case DASM_DISP:
+ if (n == 0) { if ((mrm&7) == 4) mrm = p[-2]; if ((mrm&7) != 5) break; }
+ case DASM_IMM_DB: if (((n+128)&-256) == 0) goto ob;
+ case DASM_REL_A: /* Assumes ptrdiff_t is int. !x64 */
+ case DASM_IMM_D: ofs += 4; break;
+ case DASM_IMM_S: CK(((n+128)&-256) == 0, RANGE_I); goto ob;
+ case DASM_IMM_B: CK((n&-256) == 0, RANGE_I); ob: ofs++; break;
+ case DASM_IMM_WB: if (((n+128)&-256) == 0) goto ob;
+ case DASM_IMM_W: CK((n&-65536) == 0, RANGE_I); ofs += 2; break;
+ case DASM_SPACE: p++; ofs += n; break;
+ case DASM_SETLABEL: b[pos-2] = -0x40000000; break; /* Neg. label ofs. */
+ }
+ mrm = 4;
+ } else {
+ int *pl, n;
+ switch (action) {
+ case DASM_REL_LG:
+ case DASM_IMM_LG:
+ n = *p++; pl = D->lglabels + n;
+ if (n <= 246) { CKPL(lg, LG); goto putrel; } /* Bkwd rel or global. */
+ pl -= 246; n = *pl;
+ if (n < 0) n = 0; /* Start new chain for fwd rel if label exists. */
+ goto linkrel;
+ case DASM_REL_PC:
+ case DASM_IMM_PC: pl = D->pclabels + va_arg(ap, int); CKPL(pc, PC);
+ putrel:
+ n = *pl;
+ if (n < 0) { /* Label exists. Get label pos and store it. */
+ b[pos] = -n;
+ } else {
+ linkrel:
+ b[pos] = n; /* Else link to rel chain, anchored at label. */
+ *pl = pos;
+ }
+ pos++;
+ ofs += 4; /* Maximum offset needed. */
+ if (action == DASM_REL_LG || action == DASM_REL_PC)
+ b[pos++] = ofs; /* Store pass1 offset estimate. */
+ break;
+ case DASM_LABEL_LG: pl = D->lglabels + *p++; CKPL(lg, LG); goto putlabel;
+ case DASM_LABEL_PC: pl = D->pclabels + va_arg(ap, int); CKPL(pc, PC);
+ putlabel:
+ n = *pl; /* n > 0: Collapse rel chain and replace with label pos. */
+ while (n > 0) { int *pb = DASM_POS2PTR(D, n); n = *pb; *pb = pos; }
+ *pl = -pos; /* Label exists now. */
+ b[pos++] = ofs; /* Store pass1 offset estimate. */
+ break;
+ case DASM_ALIGN:
+ ofs += *p++; /* Maximum alignment needed (arg is 2**n-1). */
+ b[pos++] = ofs; /* Store pass1 offset estimate. */
+ break;
+ case DASM_ESC: p++; ofs++; break;
+ case DASM_MARK: mrm = p[-2]; break;
+ case DASM_SECTION:
+ n = *p; CK(n < D->maxsection, RANGE_SEC); D->section = &D->sections[n];
+ case DASM_STOP: goto stop;
+ }
+ }
+ }
+stop:
+ va_end(ap);
+ sec->pos = pos;
+ sec->ofs = ofs;
+}
+#undef CK
+
+/* Pass 2: Link sections, shrink branches/aligns, fix label offsets. */
+int dasm_link(Dst_DECL, size_t *szp)
+{
+ dasm_State *D = Dst_REF;
+ int secnum;
+ int ofs = 0;
+
+#ifdef DASM_CHECKS
+ *szp = 0;
+ if (D->status != DASM_S_OK) return D->status;
+ {
+ int pc;
+ for (pc = 0; pc*sizeof(int) < D->pcsize; pc++)
+ if (D->pclabels[pc] > 0) return DASM_S_UNDEF_PC|pc;
+ }
+#endif
+
+ { /* Handle globals not defined in this translation unit. */
+ int idx;
+ for (idx = 10; idx*sizeof(int) < D->lgsize; idx++) {
+ int n = D->lglabels[idx];
+ /* Undefined label: Collapse rel chain and replace with marker (< 0). */
+ while (n > 0) { int *pb = DASM_POS2PTR(D, n); n = *pb; *pb = -idx; }
+ }
+ }
+
+ /* Combine all code sections. No support for data sections (yet). */
+ for (secnum = 0; secnum < D->maxsection; secnum++) {
+ dasm_Section *sec = D->sections + secnum;
+ int *b = sec->rbuf;
+ int pos = DASM_SEC2POS(secnum);
+ int lastpos = sec->pos;
+
+ while (pos != lastpos) {
+ dasm_ActList p = D->actionlist + b[pos++];
+ while (1) {
+ int op, action = *p++;
+ switch (action) {
+ case DASM_REL_LG: p++; op = p[-3]; goto rel_pc;
+ case DASM_REL_PC: op = p[-2]; rel_pc: {
+ int shrink = op == 0xe9 ? 3 : ((op&0xf0) == 0x80 ? 4 : 0);
+ if (shrink) { /* Shrinkable branch opcode? */
+ int lofs, lpos = b[pos];
+ if (lpos < 0) goto noshrink; /* Ext global? */
+ lofs = *DASM_POS2PTR(D, lpos);
+ if (lpos > pos) { /* Fwd label: add cumulative section offsets. */
+ int i;
+ for (i = secnum; i < DASM_POS2SEC(lpos); i++)
+ lofs += D->sections[i].ofs;
+ } else {
+ lofs -= ofs; /* Bkwd label: unfix offset. */
+ }
+ lofs -= b[pos+1]; /* Short branch ok? */
+ if (lofs >= -128-shrink && lofs <= 127) ofs -= shrink; /* Yes. */
+ else { noshrink: shrink = 0; } /* No, cannot shrink op. */
+ }
+ b[pos+1] = shrink;
+ pos += 2;
+ break;
+ }
+ case DASM_SPACE: case DASM_IMM_LG: p++;
+ case DASM_DISP: case DASM_IMM_S: case DASM_IMM_B: case DASM_IMM_W:
+ case DASM_IMM_D: case DASM_IMM_WB: case DASM_IMM_DB:
+ case DASM_SETLABEL: case DASM_REL_A: case DASM_IMM_PC: pos++; break;
+ case DASM_LABEL_LG: p++;
+ case DASM_LABEL_PC: b[pos++] += ofs; break; /* Fix label offset. */
+ case DASM_ALIGN: ofs -= (b[pos++]+ofs)&*p++; break; /* Adjust ofs. */
+ case DASM_ESC: p++;
+ case DASM_MARK: break;
+ case DASM_SECTION: case DASM_STOP: goto stop;
+ }
+ }
+ stop: (void)0;
+ }
+ ofs += sec->ofs; /* Next section starts right after current section. */
+ }
+
+ D->codesize = ofs; /* Total size of all code sections */
+ *szp = ofs;
+ return DASM_S_OK;
+}
+
+#define dasmb(x) *cp++ = (unsigned char)(x)
+#ifndef DASM_ALIGNED_WRITES
+#define dasmw(x) \
+ do { *((unsigned short *)cp) = (unsigned short)(x); cp+=2; } while (0)
+#define dasmd(x) \
+ do { *((unsigned int *)cp) = (unsigned int)(x); cp+=4; } while (0)
+#else
+#define dasmw(x) do { dasmb(x); dasmb((x)>>8); } while (0)
+#define dasmd(x) do { dasmw(x); dasmw((x)>>16); } while (0)
+#endif
+
+/* Pass 3: Encode sections. */
+int dasm_encode(Dst_DECL, void *buffer)
+{
+ dasm_State *D = Dst_REF;
+ unsigned char *base = (unsigned char *)buffer;
+ unsigned char *cp = base;
+ int secnum;
+
+ /* Encode all code sections. No support for data sections (yet). */
+ for (secnum = 0; secnum < D->maxsection; secnum++) {
+ dasm_Section *sec = D->sections + secnum;
+ int *b = sec->buf;
+ int *endb = sec->rbuf + sec->pos;
+
+ while (b != endb) {
+ dasm_ActList p = D->actionlist + *b++;
+ unsigned char *mark = NULL;
+ while (1) {
+ int action = *p++;
+ int n = (action >= DASM_DISP && action <= DASM_ALIGN) ? *b++ : 0;
+ switch (action) {
+ case DASM_DISP: if (!mark) mark = cp; {
+ unsigned char *mm = mark;
+ if (*p != DASM_IMM_DB && *p != DASM_IMM_WB) mark = NULL;
+ if (n == 0) { int mrm = mm[-1]&7; if (mrm == 4) mrm = mm[0]&7;
+ if (mrm != 5) { mm[-1] -= 0x80; break; } }
+ if (((n+128) & -256) != 0) goto wd; else mm[-1] -= 0x40;
+ }
+ case DASM_IMM_S: case DASM_IMM_B: wb: dasmb(n); break;
+ case DASM_IMM_DB: if (((n+128)&-256) == 0) {
+ db: if (!mark) mark = cp; mark[-2] += 2; mark = NULL; goto wb;
+ } else mark = NULL;
+ case DASM_IMM_D: wd: dasmd(n); break;
+ case DASM_IMM_WB: if (((n+128)&-256) == 0) goto db; else mark = NULL;
+ case DASM_IMM_W: dasmw(n); break;
+ case DASM_REL_LG: p++; if (n >= 0) goto rel_pc;
+ b++; n = (int)D->globals[-n];
+ case DASM_REL_A: rel_a: n -= (int)(cp+4); goto wd; /* !x64 */
+ case DASM_REL_PC: rel_pc: {
+ int shrink = *b++;
+ int *pb = DASM_POS2PTR(D, n); if (*pb < 0) { n = pb[1]; goto rel_a; }
+ n = *pb - ((cp-base) + 4-shrink);
+ if (shrink == 0) goto wd;
+ if (shrink == 4) { cp--; cp[-1] = *cp-0x10; } else cp[-1] = 0xeb;
+ goto wb;
+ }
+ case DASM_IMM_LG: p++; if (n < 0) { n = (int)D->globals[-n]; goto wd; }
+ case DASM_IMM_PC: {
+ int *pb = DASM_POS2PTR(D, n);
+ n = *pb < 0 ? pb[1] : (*pb + (ptrdiff_t)base);
+ goto wd;
+ }
+ case DASM_LABEL_LG: {
+ int idx = *p++;
+ if (idx >= 10)
+ D->globals[idx] = (void *)(base + (*p == DASM_SETLABEL ? *b : n));
+ break;
+ }
+ case DASM_LABEL_PC: case DASM_SETLABEL: break;
+ case DASM_SPACE: { int fill = *p++; while (n--) *cp++ = fill; break; }
+ case DASM_ALIGN:
+ n = *p++;
+ while (((cp-base) & n)) *cp++ = 0x90; /* nop */
+ break;
+ case DASM_MARK: mark = cp; break;
+ case DASM_ESC: action = *p++;
+ default: *cp++ = action; break;
+ case DASM_SECTION: case DASM_STOP: goto stop;
+ }
+ }
+ stop: (void)0;
+ }
+ }
+
+ if (base + D->codesize != cp) /* Check for phase errors. */
+ return DASM_S_PHASE;
+ return DASM_S_OK;
+}
+
+/* Get PC label offset. */
+int dasm_getpclabel(Dst_DECL, unsigned int pc)
+{
+ dasm_State *D = Dst_REF;
+ if (pc*sizeof(int) < D->pcsize) {
+ int pos = D->pclabels[pc];
+ if (pos < 0) return *DASM_POS2PTR(D, -pos);
+ if (pos > 0) return -1; /* Undefined. */
+ }
+ return -2; /* Unused or out of range. */
+}
+
+#ifdef DASM_CHECKS
+/* Optional sanity checker to call between isolated encoding steps. */
+int dasm_checkstep(Dst_DECL, int secmatch)
+{
+ dasm_State *D = Dst_REF;
+ if (D->status == DASM_S_OK) {
+ int i;
+ for (i = 1; i <= 9; i++) {
+ if (D->lglabels[i] > 0) { D->status = DASM_S_UNDEF_L|i; break; }
+ D->lglabels[i] = 0;
+ }
+ }
+ if (D->status == DASM_S_OK && secmatch >= 0 &&
+ D->section != &D->sections[secmatch])
+ D->status = DASM_S_MATCH_SEC|(D->section-D->sections);
+ return D->status;
+}
+#endif
+
diff --git a/libraries/LuaJIT-1.1.7/dynasm/dasm_x86.lua b/libraries/LuaJIT-1.1.7/dynasm/dasm_x86.lua
new file mode 100644
index 0000000..026c3b0
--- /dev/null
+++ b/libraries/LuaJIT-1.1.7/dynasm/dasm_x86.lua
@@ -0,0 +1,1581 @@
+------------------------------------------------------------------------------
+-- DynASM x86 module.
+--
+-- Copyright (C) 2005-2008 Mike Pall. All rights reserved.
+-- See dynasm.lua for full copyright notice.
+------------------------------------------------------------------------------
+
+-- Module information:
+local _info = {
+ arch = "x86",
+ description = "DynASM x86 (i386) module",
+ version = "1.1.4",
+ vernum = 10104,
+ release = "2008-01-29",
+ author = "Mike Pall",
+ license = "MIT",
+}
+
+-- Exported glue functions for the arch-specific module.
+local _M = { _info = _info }
+
+-- Cache library functions.
+local type, tonumber, pairs, ipairs = type, tonumber, pairs, ipairs
+local assert, unpack = assert, unpack
+local _s = string
+local sub, format, byte, char = _s.sub, _s.format, _s.byte, _s.char
+local find, match, gmatch, gsub = _s.find, _s.match, _s.gmatch, _s.gsub
+local concat, sort = table.concat, table.sort
+local char, unpack = string.char, unpack
+
+-- Inherited tables and callbacks.
+local g_opt, g_arch
+local wline, werror, wfatal, wwarn
+
+-- Action name list.
+-- CHECK: Keep this in sync with the C code!
+local action_names = {
+ -- int arg, 1 buffer pos:
+ "DISP", "IMM_S", "IMM_B", "IMM_W", "IMM_D", "IMM_WB", "IMM_DB",
+ -- action arg (1 byte), int arg, 1 buffer pos (num):
+ "SPACE",
+ -- ptrdiff_t arg, 1 buffer pos (address): !x64
+ "SETLABEL", "REL_A",
+ -- action arg (1 byte) or int arg, 2 buffer pos (link, offset):
+ "REL_LG", "REL_PC",
+ -- action arg (1 byte) or int arg, 1 buffer pos (link):
+ "IMM_LG", "IMM_PC",
+ -- action arg (1 byte) or int arg, 1 buffer pos (offset):
+ "LABEL_LG", "LABEL_PC",
+ -- action arg (1 byte), 1 buffer pos (offset):
+ "ALIGN",
+ -- action arg (1 byte), no buffer pos.
+ "ESC",
+ -- no action arg, no buffer pos.
+ "MARK",
+ -- action arg (1 byte), no buffer pos, terminal action:
+ "SECTION",
+ -- no args, no buffer pos, terminal action:
+ "STOP"
+}
+
+-- Maximum number of section buffer positions for dasm_put().
+-- CHECK: Keep this in sync with the C code!
+local maxsecpos = 25 -- Keep this low, to avoid excessively long C lines.
+
+-- Action name -> action number (dynamically generated below).
+local map_action = {}
+-- First action number. Everything below does not need to be escaped.
+local actfirst = 256-#action_names
+
+-- Action list buffer and string (only used to remove dupes).
+local actlist = {}
+local actstr = ""
+
+-- Argument list for next dasm_put(). Start with offset 0 into action list.
+local actargs = { 0 }
+
+-- Current number of section buffer positions for dasm_put().
+local secpos = 1
+
+------------------------------------------------------------------------------
+
+-- Compute action numbers for action names.
+for n,name in ipairs(action_names) do
+ local num = actfirst + n - 1
+ map_action[name] = num
+end
+
+-- Dump action names and numbers.
+local function dumpactions(out)
+ out:write("DynASM encoding engine action codes:\n")
+ for n,name in ipairs(action_names) do
+ local num = map_action[name]
+ out:write(format(" %-10s %02X %d\n", name, num, num))
+ end
+ out:write("\n")
+end
+
+-- Write action list buffer as a huge static C array.
+local function writeactions(out, name)
+ local nn = #actlist
+ local last = actlist[nn] or 255
+ actlist[nn] = nil -- Remove last byte.
+ if nn == 0 then nn = 1 end
+ out:write("static const unsigned char ", name, "[", nn, "] = {\n")
+ local s = " "
+ for n,b in ipairs(actlist) do
+ s = s..b..","
+ if #s >= 75 then
+ assert(out:write(s, "\n"))
+ s = " "
+ end
+ end
+ out:write(s, last, "\n};\n\n") -- Add last byte back.
+end
+
+------------------------------------------------------------------------------
+
+-- Add byte to action list.
+local function wputxb(n)
+ assert(n >= 0 and n <= 255 and n % 1 == 0, "byte out of range")
+ actlist[#actlist+1] = n
+end
+
+-- Add action to list with optional arg. Advance buffer pos, too.
+local function waction(action, a, num)
+ wputxb(assert(map_action[action], "bad action name `"..action.."'"))
+ if a then actargs[#actargs+1] = a end
+ if a or num then secpos = secpos + (num or 1) end
+end
+
+-- Add call to embedded DynASM C code.
+local function wcall(func, args)
+ wline(format("dasm_%s(Dst, %s);", func, concat(args, ", ")), true)
+end
+
+-- Delete duplicate action list chunks. A tad slow, but so what.
+local function dedupechunk(offset)
+ local al, as = actlist, actstr
+ local chunk = char(unpack(al, offset+1, #al))
+ local orig = find(as, chunk, 1, true)
+ if orig then
+ actargs[1] = orig-1 -- Replace with original offset.
+ for i=offset+1,#al do al[i] = nil end -- Kill dupe.
+ else
+ actstr = as..chunk
+ end
+end
+
+-- Flush action list (intervening C code or buffer pos overflow).
+local function wflush(term)
+ local offset = actargs[1]
+ if #actlist == offset then return end -- Nothing to flush.
+ if not term then waction("STOP") end -- Terminate action list.
+ dedupechunk(offset)
+ wcall("put", actargs) -- Add call to dasm_put().
+ actargs = { #actlist } -- Actionlist offset is 1st arg to next dasm_put().
+ secpos = 1 -- The actionlist offset occupies a buffer position, too.
+end
+
+-- Put escaped byte.
+local function wputb(n)
+ if n >= actfirst then waction("ESC") end -- Need to escape byte.
+ wputxb(n)
+end
+
+------------------------------------------------------------------------------
+
+-- Global label name -> global label number. With auto assignment on 1st use.
+local next_global = 10
+local map_global = setmetatable({}, { __index = function(t, name)
+ if not match(name, "^[%a_][%w_]*$") then werror("bad global label") end
+ local n = next_global
+ if n > 246 then werror("too many global labels") end
+ next_global = n + 1
+ t[name] = n
+ return n
+end})
+
+-- Dump global labels.
+local function dumpglobals(out, lvl)
+ local t = {}
+ for name, n in pairs(map_global) do t[n] = name end
+ out:write("Global labels:\n")
+ for i=10,next_global-1 do
+ out:write(format(" %s\n", t[i]))
+ end
+ out:write("\n")
+end
+
+-- Write global label enum.
+local function writeglobals(out, prefix)
+ local t = {}
+ for name, n in pairs(map_global) do t[n] = name end
+ out:write("enum {\n")
+ for i=10,next_global-1 do
+ out:write(" ", prefix, t[i], ",\n")
+ end
+ out:write(" ", prefix, "_MAX\n};\n")
+end
+
+------------------------------------------------------------------------------
+
+-- Arch-specific maps.
+local map_archdef = {} -- Ext. register name -> int. name.
+local map_reg_rev = {} -- Int. register name -> ext. name.
+local map_reg_num = {} -- Int. register name -> register number.
+local map_reg_opsize = {} -- Int. register name -> operand size.
+local map_reg_valid_base = {} -- Int. register name -> valid base register?
+local map_reg_valid_index = {} -- Int. register name -> valid index register?
+local reg_list = {} -- Canonical list of int. register names.
+
+local map_type = {} -- Type name -> { ctype, reg }
+local ctypenum = 0 -- Type number (for _PTx macros).
+
+local addrsize = "d" -- Size for address operands. !x64
+
+-- Helper function to fill register maps.
+local function mkrmap(sz, names)
+ for n,name in ipairs(names) do
+ local iname = format("@%s%x", sz, n-1)
+ reg_list[#reg_list+1] = iname
+ map_archdef[name] = iname
+ map_reg_rev[iname] = name
+ map_reg_num[iname] = n-1
+ map_reg_opsize[iname] = sz
+ if sz == addrsize then
+ map_reg_valid_base[iname] = true
+ map_reg_valid_index[iname] = true
+ end
+ end
+ reg_list[#reg_list+1] = ""
+end
+
+-- Integer registers (dword, word and byte sized).
+mkrmap("d", {"eax", "ecx", "edx", "ebx", "esp", "ebp", "esi", "edi"})
+map_reg_valid_index[map_archdef.esp] = nil
+mkrmap("w", {"ax", "cx", "dx", "bx", "sp", "bp", "si", "di"})
+mkrmap("b", {"al", "cl", "dl", "bl", "ah", "ch", "dh", "bh"})
+
+-- FP registers (internally tword sized, but use "f" as operand size).
+mkrmap("f", {"st0", "st1", "st2", "st3", "st4", "st5", "st6", "st7"})
+
+-- SSE registers (oword sized, but qword and dword accessible).
+mkrmap("o", {"xmm0", "xmm1", "xmm2", "xmm3", "xmm4", "xmm5", "xmm6", "xmm7"})
+
+-- Operand size prefixes to codes.
+local map_opsize = {
+ byte = "b", word = "w", dword = "d", qword = "q", oword = "o", tword = "t",
+ aword = addrsize,
+}
+
+-- Operand size code to number.
+local map_opsizenum = {
+ b = 1, w = 2, d = 4, q = 8, o = 16, t = 10,
+}
+
+-- Operand size code to name.
+local map_opsizename = {
+ b = "byte", w = "word", d = "dword", q = "qword", o = "oword", t = "tword",
+ f = "fpword",
+}
+
+-- Valid index register scale factors.
+local map_xsc = {
+ ["1"] = 0, ["2"] = 1, ["4"] = 2, ["8"] = 3,
+}
+
+-- Condition codes.
+local map_cc = {
+ o = 0, no = 1, b = 2, nb = 3, e = 4, ne = 5, be = 6, nbe = 7,
+ s = 8, ns = 9, p = 10, np = 11, l = 12, nl = 13, le = 14, nle = 15,
+ c = 2, nae = 2, nc = 3, ae = 3, z = 4, nz = 5, na = 6, a = 7,
+ nge = 12, ge = 13, ng = 14, g = 15,
+}
+
+
+-- Reverse defines for registers.
+function _M.revdef(s)
+ return gsub(s, "@%w+", map_reg_rev)
+end
+
+-- Dump register names and numbers
+local function dumpregs(out)
+ out:write("Register names, sizes and internal numbers:\n")
+ for _,reg in ipairs(reg_list) do
+ if reg == "" then
+ out:write("\n")
+ else
+ local name = map_reg_rev[reg]
+ local num = map_reg_num[reg]
+ local opsize = map_opsizename[map_reg_opsize[reg]]
+ out:write(format(" %-5s %-8s %d\n", name, opsize, num))
+ end
+ end
+end
+
+------------------------------------------------------------------------------
+
+-- Put action for label arg (IMM_LG, IMM_PC, REL_LG, REL_PC).
+local function wputlabel(aprefix, imm, num)
+ if type(imm) == "number" then
+ waction(aprefix.."LG", nil, num);
+ wputxb(imm)
+ else
+ waction(aprefix.."PC", imm, num)
+ end
+end
+
+-- Put signed byte or arg.
+local function wputsbarg(n)
+ if type(n) == "number" then
+ if n < -128 or n > 127 then
+ werror("signed immediate byte out of range")
+ end
+ if n < 0 then n = n + 256 end
+ wputb(n)
+ else waction("IMM_S", n) end
+end
+
+-- Put unsigned byte or arg.
+local function wputbarg(n)
+ if type(n) == "number" then
+ if n < 0 or n > 255 then
+ werror("unsigned immediate byte out of range")
+ end
+ wputb(n)
+ else waction("IMM_B", n) end
+end
+
+-- Put unsigned word or arg.
+local function wputwarg(n)
+ if type(n) == "number" then
+ if n < 0 or n > 65535 then
+ werror("unsigned immediate word out of range")
+ end
+ local r = n%256; n = (n-r)/256; wputb(r); wputb(n);
+ else waction("IMM_W", n) end
+end
+
+-- Put signed or unsigned dword or arg.
+local function wputdarg(n)
+ local tn = type(n)
+ if tn == "number" then
+ if n < 0 then n = n + 4294967296 end
+ local r = n%256; n = (n-r)/256; wputb(r);
+ r = n%256; n = (n-r)/256; wputb(r);
+ r = n%256; n = (n-r)/256; wputb(r); wputb(n);
+ elseif tn == "table" then
+ wputlabel("IMM_", n[1], 1)
+ else
+ waction("IMM_D", n)
+ end
+end
+
+-- Put operand-size dependent number or arg (defaults to dword).
+local function wputszarg(sz, n)
+ if not sz or sz == "d" then wputdarg(n)
+ elseif sz == "w" then wputwarg(n)
+ elseif sz == "b" then wputbarg(n)
+ elseif sz == "s" then wputsbarg(n)
+ else werror("bad operand size") end
+end
+
+-- Put multi-byte opcode with operand-size dependent modifications.
+local function wputop(sz, op)
+ local r
+ if sz == "w" then wputb(102) end
+ if op >= 16777216 then r = op % 16777216 wputb((op-r) / 16777216) op = r end
+ if op >= 65536 then r = op % 65536 wputb((op-r) / 65536) op = r end
+ if op >= 256 then r = op % 256 wputb((op-r) / 256) op = r end
+ if sz == "b" then op = op - 1 end
+ wputb(op)
+end
+
+-- Put ModRM or SIB formatted byte.
+local function wputmodrm(m, s, rm)
+ assert(m < 4 and s < 8 and rm < 8, "bad modrm operands")
+ wputb(64*m + 8*s + rm)
+end
+
+-- Put ModRM/SIB plus optional displacement.
+local function wputmrmsib(t, s, imark)
+ -- Register mode.
+ if sub(t.mode, 1, 1) == "r" then
+ wputmodrm(3, s, t.reg)
+ return
+ end
+
+ local disp = t.disp
+ local tdisp = type(disp)
+ -- No base register?
+ if not t.reg then
+ if t.xreg then
+ -- Indexed mode with index register only.
+ wputmodrm(0, s, 4) -- [xreg*xsc+disp] -> (0, s, esp) (xsc, xreg, ebp)
+ wputmodrm(t.xsc, t.xreg, 5)
+ else
+ -- Pure displacement.
+ wputmodrm(0, s, 5) -- [disp] -> (0, s, ebp)
+ end
+ wputdarg(disp)
+ return
+ end
+
+ local m
+ if tdisp == "number" then -- Check displacement size at assembly time.
+ if disp == 0 and t.reg ~= 5 then m = 0 -- [ebp] -> [ebp+0] (in SIB, too)
+ elseif disp >= -128 and disp <= 127 then m = 1
+ else m = 2 end
+ elseif tdisp == "table" then
+ m = 2
+ end
+
+ -- Index register present or esp as base register: need SIB encoding.
+ if t.xreg or t.reg == 4 then
+ wputmodrm(m or 2, s, 4) -- ModRM.
+ if (m == nil or imark) and tdisp ~= "table" then waction("MARK") end
+ wputmodrm(t.xsc or 0, t.xreg or 4, t.reg) -- SIB.
+ else
+ wputmodrm(m or 2, s, t.reg) -- ModRM.
+ if imark and (m == 1 or m == 2) then waction("MARK") end
+ end
+
+ -- Put displacement.
+ if m == 1 then wputsbarg(disp)
+ elseif m == 2 then wputdarg(disp)
+ elseif not m then waction("DISP", disp) end
+end
+
+------------------------------------------------------------------------------
+
+-- Return human-readable operand mode string.
+local function opmodestr(op, args)
+ local m = {}
+ for i=1,#args do
+ local a = args[i]
+ m[#m+1] = sub(a.mode, 1, 1)..(a.opsize or "?")
+ end
+ return op.." "..concat(m, ",")
+end
+
+-- Convert number to valid integer or nil.
+local function toint(expr)
+ local n = tonumber(expr)
+ if n then
+ if n % 1 ~= 0 or n < -2147483648 or n > 4294967295 then
+ werror("bad integer number `"..expr.."'")
+ end
+ return n
+ end
+end
+
+-- Parse immediate expression.
+local function immexpr(expr)
+ -- &expr (pointer)
+ if sub(expr, 1, 1) == "&" then
+ return "iPJ", format("(ptrdiff_t)(%s)", sub(expr,2))
+ end
+
+ local prefix = sub(expr, 1, 2)
+ -- =>expr (pc label reference)
+ if prefix == "=>" then
+ return "iJ", sub(expr, 3)
+ end
+ -- ->name (global label reference)
+ if prefix == "->" then
+ return "iJ", map_global[sub(expr, 3)]
+ end
+
+ -- [<>][1-9] (local label reference)
+ local dir, lnum = match(expr, "^([<>])([1-9])$")
+ if dir then -- Fwd: 247-255, Bkwd: 1-9.
+ return "iJ", lnum + (dir == ">" and 246 or 0)
+ end
+
+ -- expr (interpreted as immediate)
+ return "iI", expr
+end
+
+-- Parse displacement expression: +-num, +-expr, +-opsize*num
+local function dispexpr(expr)
+ local disp = expr == "" and 0 or toint(expr)
+ if disp then return disp end
+ local c, dispt = match(expr, "^([+-])%s*(.+)$")
+ if c == "+" then
+ expr = dispt
+ elseif not c then
+ werror("bad displacement expression `"..expr.."'")
+ end
+ local opsize, tailops = match(dispt, "^(%w+)%s*%*%s*(.+)$")
+ local ops, imm = map_opsize[opsize], toint(tailops)
+ if ops and imm then
+ if c == "-" then imm = -imm end
+ return imm*map_opsizenum[ops]
+ end
+ local mode, iexpr = immexpr(dispt)
+ if mode == "iJ" then
+ if c == "-" then werror("cannot invert label reference") end
+ return { iexpr }
+ end
+ return expr -- Need to return original signed expression.
+end
+
+-- Parse register or type expression.
+local function rtexpr(expr)
+ if not expr then return end
+ local tname, ovreg = match(expr, "^([%w_]+):(@[%w_]+)$")
+ local tp = map_type[tname or expr]
+ if tp then
+ local reg = ovreg or tp.reg
+ local rnum = map_reg_num[reg]
+ if not rnum then
+ werror("type `"..(tname or expr).."' needs a register override")
+ end
+ if not map_reg_valid_base[reg] then
+ werror("bad base register override `"..(map_reg_rev[reg] or reg).."'")
+ end
+ return reg, rnum, tp
+ end
+ return expr, map_reg_num[expr]
+end
+
+-- Parse operand and return { mode, opsize, reg, xreg, xsc, disp, imm }.
+local function parseoperand(param)
+ local t = {}
+
+ local expr = param
+ local opsize, tailops = match(param, "^(%w+)%s*(.+)$")
+ if opsize then
+ t.opsize = map_opsize[opsize]
+ if t.opsize then expr = tailops end
+ end
+
+ local br = match(expr, "^%[%s*(.-)%s*%]$")
+ repeat
+ if br then
+ t.mode = "xm"
+
+ -- [disp]
+ t.disp = toint(br)
+ if t.disp then
+ t.mode = "xmO"
+ break
+ end
+
+ -- [reg...]
+ local tp
+ local reg, tailr = match(br, "^([@%w_:]+)%s*(.*)$")
+ reg, t.reg, tp = rtexpr(reg)
+ if not t.reg then
+ -- [expr]
+ t.mode = "xmO"
+ t.disp = dispexpr("+"..br)
+ break
+ end
+
+ -- [xreg*xsc] or [xreg*xsc+-disp] or [xreg*xsc+-expr]
+ local xsc, tailsc = match(tailr, "^%*%s*([1248])%s*(.*)$")
+ if xsc then
+ if not map_reg_valid_index[reg] then
+ werror("bad index register `"..map_reg_rev[reg].."'")
+ end
+ t.xsc = map_xsc[xsc]
+ t.xreg = t.reg
+ t.reg = nil
+ t.disp = dispexpr(tailsc)
+ break
+ end
+ if not map_reg_valid_base[reg] then
+ werror("bad base register `"..map_reg_rev[reg].."'")
+ end
+
+ -- [reg] or [reg+-disp]
+ t.disp = toint(tailr) or (tailr == "" and 0)
+ if t.disp then break end
+
+ -- [reg+xreg...]
+ local xreg, tailx = match(tailr, "^+%s*([@%w_:]+)%s*(.*)$")
+ xreg, t.xreg, tp = rtexpr(xreg)
+ if not t.xreg then
+ -- [reg+-expr]
+ t.disp = dispexpr(tailr)
+ break
+ end
+ if not map_reg_valid_index[xreg] then
+ werror("bad index register `"..map_reg_rev[xreg].."'")
+ end
+
+ -- [reg+xreg*xsc...]
+ local xsc, tailsc = match(tailx, "^%*%s*([1248])%s*(.*)$")
+ if xsc then
+ t.xsc = map_xsc[xsc]
+ tailx = tailsc
+ end
+
+ -- [...] or [...+-disp] or [...+-expr]
+ t.disp = dispexpr(tailx)
+ else
+ -- imm or opsize*imm
+ local imm = toint(expr)
+ if not imm and sub(expr, 1, 1) == "*" and t.opsize then
+ imm = toint(sub(expr, 2))
+ if imm then
+ imm = imm * map_opsizenum[t.opsize]
+ t.opsize = nil
+ end
+ end
+ if imm then
+ if t.opsize then werror("bad operand size override") end
+ local m = "i"
+ if imm == 1 then m = m.."1" end
+ if imm >= 4294967168 and imm <= 4294967295 then imm = imm-4294967296 end
+ if imm >= -128 and imm <= 127 then m = m.."S" end
+ t.imm = imm
+ t.mode = m
+ break
+ end
+
+ local tp
+ local reg, tailr = match(expr, "^([@%w_:]+)%s*(.*)$")
+ reg, t.reg, tp = rtexpr(reg)
+ if t.reg then
+ -- reg
+ if tailr == "" then
+ if t.opsize then werror("bad operand size override") end
+ t.opsize = map_reg_opsize[reg]
+ if t.opsize == "f" then
+ t.mode = t.reg == 0 and "fF" or "f"
+ else
+ if reg == "@w4" then wwarn("bad idea, try again with `esp'") end
+ t.mode = t.reg == 0 and "rmR" or (reg == "@b1" and "rmC" or "rm")
+ end
+ break
+ end
+
+ -- type[idx], type[idx].field, type->field -> [reg+offset_expr]
+ if not tp then werror("bad operand `"..param.."'") end
+ t.mode = "xm"
+ t.disp = format(tp.ctypefmt, tailr)
+ else
+ t.mode, t.imm = immexpr(expr)
+ if sub(t.mode, -1) == "J" then
+ if t.opsize and t.opsize ~= addrsize then
+ werror("bad operand size override")
+ end
+ t.opsize = addrsize
+ end
+ end
+ end
+ until true
+ return t
+end
+
+------------------------------------------------------------------------------
+-- x86 Template String Description
+-- ===============================
+--
+-- Each template string is a list of [match:]pattern pairs,
+-- separated by "|". The first match wins. No match means a
+-- bad or unsupported combination of operand modes or sizes.
+--
+-- The match part and the ":" is omitted if the operation has
+-- no operands. Otherwise the first N characters are matched
+-- against the mode strings of each of the N operands.
+--
+-- The mode string for each operand type is (see parseoperand()):
+-- Integer register: "rm", +"R" for eax, ax, al, +"C" for cl
+-- FP register: "f", +"F" for st0
+-- Index operand: "xm", +"O" for [disp] (pure offset)
+-- Immediate: "i", +"S" for signed 8 bit, +"1" for 1,
+-- +"I" for arg, +"P" for pointer
+-- Any: +"J" for valid jump targets
+--
+-- So a match character "m" (mixed) matches both an integer register
+-- and an index operand (to be encoded with the ModRM/SIB scheme).
+-- But "r" matches only a register and "x" only an index operand
+-- (e.g. for FP memory access operations).
+--
+-- The operand size match string starts right after the mode match
+-- characters and ends before the ":". "dwb" is assumed, if empty.
+-- The effective data size of the operation is matched against this list.
+--
+-- If only the regular "b", "w", "d", "q", "t" operand sizes are
+-- present, then all operands must be the same size. Unspecified sizes
+-- are ignored, but at least one operand must have a size or the pattern
+-- won't match (use the "byte", "word", "dword", "qword", "tword"
+-- operand size overrides. E.g.: mov dword [eax], 1).
+--
+-- If the list has a "1" or "2" prefix, the operand size is taken
+-- from the respective operand and any other operand sizes are ignored.
+-- If the list contains only ".", all operand sizes are ignored.
+-- If the list has a "/" prefix, the concatenated (mixed) operand sizes
+-- are compared to the match.
+--
+-- E.g. "rrdw" matches for either two dword registers or two word
+-- registers. "Fx2dq" matches an st0 operand plus an index operand
+-- pointing to a dword (float) or qword (double).
+--
+-- Every character after the ":" is part of the pattern string:
+-- Hex chars are accumulated to form the opcode (left to right).
+-- "n" disables the standard opcode mods
+-- (otherwise: -1 for "b", o16 prefix for "w")
+-- "r"/"R" adds the reg. number from the 1st/2nd operand to the opcode.
+-- "m"/"M" generates ModRM/SIB from the 1st/2nd operand.
+-- The spare 3 bits are either filled with the last hex digit or
+-- the result from a previous "r"/"R". The opcode is restored.
+--
+-- All of the following characters force a flush of the opcode:
+-- "o"/"O" stores a pure 32 bit disp (offset) from the 1st/2nd operand.
+-- "S" stores a signed 8 bit immediate from the last operand.
+-- "U" stores an unsigned 8 bit immediate from the last operand.
+-- "W" stores an unsigned 16 bit immediate from the last operand.
+-- "i" stores an operand sized immediate from the last operand.
+-- "I" dito, but generates an action code to optionally modify
+-- the opcode (+2) for a signed 8 bit immediate.
+-- "J" generates one of the REL action codes from the last operand.
+--
+------------------------------------------------------------------------------
+
+-- Template strings for x86 instructions. Ordered by first opcode byte.
+-- Unimplemented opcodes (deliberate omissions) are marked with *.
+local map_op = {
+ -- 00-05: add...
+ -- 06: *push es
+ -- 07: *pop es
+ -- 08-0D: or...
+ -- 0E: *push cs
+ -- 0F: two byte opcode prefix
+ -- 10-15: adc...
+ -- 16: *push ss
+ -- 17: *pop ss
+ -- 18-1D: sbb...
+ -- 1E: *push ds
+ -- 1F: *pop ds
+ -- 20-25: and...
+ es_0 = "26",
+ -- 27: *daa
+ -- 28-2D: sub...
+ cs_0 = "2E",
+ -- 2F: *das
+ -- 30-35: xor...
+ ss_0 = "36",
+ -- 37: *aaa
+ -- 38-3D: cmp...
+ ds_0 = "3E",
+ -- 3F: *aas
+ inc_1 = "rdw:40r|m:FF0m",
+ dec_1 = "rdw:48r|m:FF1m",
+ push_1 = "rdw:50r|mdw:FF6m|S.:6AS|ib:n6Ai|i.:68i",
+ pop_1 = "rdw:58r|mdw:8F0m",
+ -- 60: *pusha, *pushad, *pushaw
+ -- 61: *popa, *popad, *popaw
+ -- 62: *bound rdw,x
+ -- 63: *arpl mw,rw
+ fs_0 = "64",
+ gs_0 = "65",
+ o16_0 = "66",
+ a16_0 = "67",
+ -- 68: push idw
+ -- 69: imul rdw,mdw,idw
+ -- 6A: push ib
+ -- 6B: imul rdw,mdw,S
+ -- 6C: *insb
+ -- 6D: *insd, *insw
+ -- 6E: *outsb
+ -- 6F: *outsd, *outsw
+ -- 70-7F: jcc lb
+ -- 80: add... mb,i
+ -- 81: add... mdw,i
+ -- 82: *undefined
+ -- 83: add... mdw,S
+ test_2 = "mr:85Rm|rm:85rM|Ri:A9i|mi:F70mi",
+ -- 86: xchg rb,mb
+ -- 87: xchg rdw,mdw
+ -- 88: mov mb,r
+ -- 89: mov mdw,r
+ -- 8A: mov r,mb
+ -- 8B: mov r,mdw
+ -- 8C: *mov mdw,seg
+ lea_2 = "rxd:8DrM",
+ -- 8E: *mov seg,mdw
+ -- 8F: pop mdw
+ nop_0 = "90",
+ xchg_2 = "Rrdw:90R|rRdw:90r|rm:87rM|mr:87Rm",
+ cbw_0 = "6698",
+ cwde_0 = "98",
+ cwd_0 = "6699",
+ cdq_0 = "99",
+ -- 9A: *call iw:idw
+ wait_0 = "9B",
+ fwait_0 = "9B",
+ pushf_0 = "9C",
+ pushfw_0 = "669C",
+ pushfd_0 = "9C",
+ popf_0 = "9D",
+ popfw_0 = "669D",
+ popfd_0 = "9D",
+ sahf_0 = "9E",
+ lahf_0 = "9F",
+ mov_2 = "OR:A3o|RO:A1O|mr:89Rm|rm:8BrM|rib:nB0ri|ridw:B8ri|mi:C70mi",
+ movsb_0 = "A4",
+ movsw_0 = "66A5",
+ movsd_0 = "A5",
+ cmpsb_0 = "A6",
+ cmpsw_0 = "66A7",
+ cmpsd_0 = "A7",
+ -- A8: test Rb,i
+ -- A9: test Rdw,i
+ stosb_0 = "AA",
+ stosw_0 = "66AB",
+ stosd_0 = "AB",
+ lodsb_0 = "AC",
+ lodsw_0 = "66AD",
+ lodsd_0 = "AD",
+ scasb_0 = "AE",
+ scasw_0 = "66AF",
+ scasd_0 = "AF",
+ -- B0-B7: mov rb,i
+ -- B8-BF: mov rdw,i
+ -- C0: rol... mb,i
+ -- C1: rol... mdw,i
+ ret_1 = "i.:nC2W",
+ ret_0 = "C3",
+ -- C4: *les rdw,mq
+ -- C5: *lds rdw,mq
+ -- C6: mov mb,i
+ -- C7: mov mdw,i
+ -- C8: *enter iw,ib
+ leave_0 = "C9",
+ -- CA: *retf iw
+ -- CB: *retf
+ int3_0 = "CC",
+ int_1 = "i.:nCDU",
+ into_0 = "CE",
+ -- CF: *iret
+ -- D0: rol... mb,1
+ -- D1: rol... mdw,1
+ -- D2: rol... mb,cl
+ -- D3: rol... mb,cl
+ -- D4: *aam ib
+ -- D5: *aad ib
+ -- D6: *salc
+ -- D7: *xlat
+ -- D8-DF: floating point ops
+ -- E0: *loopne
+ -- E1: *loope
+ -- E2: *loop
+ -- E3: *jcxz, *jecxz
+ -- E4: *in Rb,ib
+ -- E5: *in Rdw,ib
+ -- E6: *out ib,Rb
+ -- E7: *out ib,Rdw
+ call_1 = "md:FF2m|J.:E8J",
+ jmp_1 = "md:FF4m|J.:E9J", -- short: EB
+ -- EA: *jmp iw:idw
+ -- EB: jmp ib
+ -- EC: *in Rb,dx
+ -- ED: *in Rdw,dx
+ -- EE: *out dx,Rb
+ -- EF: *out dx,Rdw
+ -- F0: *lock
+ int1_0 = "F1",
+ repne_0 = "F2",
+ repnz_0 = "F2",
+ rep_0 = "F3",
+ repe_0 = "F3",
+ repz_0 = "F3",
+ -- F4: *hlt
+ cmc_0 = "F5",
+ -- F6: test... mb,i; div... mb
+ -- F7: test... mdw,i; div... mdw
+ clc_0 = "F8",
+ stc_0 = "F9",
+ -- FA: *cli
+ cld_0 = "FC",
+ std_0 = "FD",
+ -- FE: inc... mb
+ -- FF: inc... mdw
+
+ -- misc ops
+ not_1 = "m:F72m",
+ neg_1 = "m:F73m",
+ mul_1 = "m:F74m",
+ imul_1 = "m:F75m",
+ div_1 = "m:F76m",
+ idiv_1 = "m:F77m",
+
+ imul_2 = "rmdw:0FAFrM|rIdw:69rmI|rSdw:6BrmS|ridw:69rmi",
+ imul_3 = "rmIdw:69rMI|rmSdw:6BrMS|rmidw:69rMi",
+
+ movzx_2 = "rm/db:0FB6rM|rm/wb:0FB6rM|rm/dw:0FB7rM",
+ movsx_2 = "rm/db:0FBErM|rm/wb:0FBErM|rm/dw:0FBFrM",
+
+ bswap_1 = "rd:0FC8r",
+ bsf_2 = "rmdw:0FBCrM",
+ bsr_2 = "rmdw:0FBDrM",
+ bt_2 = "mrdw:0FA3Rm|midw:0FBA4mU",
+ btc_2 = "mrdw:0FBBRm|midw:0FBA7mU",
+ btr_2 = "mrdw:0FB3Rm|midw:0FBA6mU",
+ bts_2 = "mrdw:0FABRm|midw:0FBA5mU",
+
+ rdtsc_0 = "0F31", -- P1+
+ cpuid_0 = "0FA2", -- P1+
+
+ -- floating point ops
+ fst_1 = "ff:DDD0r|xd:D92m|xq:DD2m",
+ fstp_1 = "ff:DDD8r|xd:D93m|xq:DD3m|xt:DB7m",
+ fld_1 = "ff:D9C0r|xd:D90m|xq:DD0m|xt:DB5m",
+
+ fpop_0 = "DDD8", -- Alias for fstp st0.
+
+ fist_1 = "xw:nDF2m|xd:DB2m",
+ fistp_1 = "xw:nDF3m|xd:DB3m|xq:DF7m",
+ fisttp_1 = "xw:nDF1m|xd:DB1m|xq:DD1m", -- SSE3
+ fild_1 = "xw:nDF0m|xd:DB0m|xq:DF5m",
+
+ fxch_0 = "D9C9",
+ fxch_1 = "ff:D9C8r",
+ fxch_2 = "fFf:D9C8r|Fff:D9C8R",
+
+ fucom_1 = "ff:DDE0r",
+ fucom_2 = "Fff:DDE0R",
+ fucomp_1 = "ff:DDE8r",
+ fucomp_2 = "Fff:DDE8R",
+ fucomi_1 = "ff:DBE8r", -- P6+
+ fucomi_2 = "Fff:DBE8R", -- P6+
+ fucomip_1 = "ff:DFE8r", -- P6+
+ fucomip_2 = "Fff:DFE8R", -- P6+
+ fcomi_1 = "ff:DBF0r", -- P6+
+ fcomi_2 = "Fff:DBF0R", -- P6+
+ fcomip_1 = "ff:DFF0r", -- P6+
+ fcomip_2 = "Fff:DFF0R", -- P6+
+ fucompp_0 = "DAE9",
+ fcompp_0 = "DED9",
+
+ fldcw_1 = "xw:nD95m",
+ fstcw_1 = "xw:n9BD97m",
+ fnstcw_1 = "xw:nD97m",
+ fstsw_1 = "Rw:n9BDFE0|xw:n9BDD7m",
+ fnstsw_1 = "Rw:nDFE0|xw:nDD7m",
+ fclex_0 = "9BDBE2",
+ fnclex_0 = "DBE2",
+
+ fnop_0 = "D9D0",
+ -- D9D1-D9DF: unassigned
+
+ fchs_0 = "D9E0",
+ fabs_0 = "D9E1",
+ -- D9E2: unassigned
+ -- D9E3: unassigned
+ ftst_0 = "D9E4",
+ fxam_0 = "D9E5",
+ -- D9E6: unassigned
+ -- D9E7: unassigned
+ fld1_0 = "D9E8",
+ fldl2t_0 = "D9E9",
+ fldl2e_0 = "D9EA",
+ fldpi_0 = "D9EB",
+ fldlg2_0 = "D9EC",
+ fldln2_0 = "D9ED",
+ fldz_0 = "D9EE",
+ -- D9EF: unassigned
+
+ f2xm1_0 = "D9F0",
+ fyl2x_0 = "D9F1",
+ fptan_0 = "D9F2",
+ fpatan_0 = "D9F3",
+ fxtract_0 = "D9F4",
+ fprem1_0 = "D9F5",
+ fdecstp_0 = "D9F6",
+ fincstp_0 = "D9F7",
+ fprem_0 = "D9F8",
+ fyl2xp1_0 = "D9F9",
+ fsqrt_0 = "D9FA",
+ fsincos_0 = "D9FB",
+ frndint_0 = "D9FC",
+ fscale_0 = "D9FD",
+ fsin_0 = "D9FE",
+ fcos_0 = "D9FF",
+
+ -- SSE, SSE2, SSE3, SSSE3 ops
+ addsubpd_2 = "rmo:660FD0rM",
+ addsubps_2 = "rmo:F20FD0rM",
+ andnpd_2 = "rmo:660F55rM",
+ andnps_2 = "rmo:0F55rM",
+ andpd_2 = "rmo:660F54rM",
+ andps_2 = "rmo:0F54rM",
+ clflush_1 = "x.:0FAE7m",
+ cmppd_3 = "rmio:660FC2rMU",
+ cmpps_3 = "rmio:0FC2rMU",
+ cmpsd_3 = "rmio:F20FC2rMU",
+ cmpss_3 = "rmio:F30FC2rMU",
+ comisd_2 = "rmo:660F2FrM",
+ comiss_2 = "rmo:0F2FrM",
+ cvtdq2pd_2 = "rro:F30FE6rM|rx/oq:",
+ cvtdq2ps_2 = "rmo:0F5BrM",
+ cvtpd2dq_2 = "rmo:F20FE6rM",
+ cvtpd2ps_2 = "rmo:660F5ArM",
+ cvtpi2pd_2 = "rx/oq:660F2ArM",
+ cvtpi2ps_2 = "rx/oq:0F2ArM",
+ cvtps2dq_2 = "rmo:660F5BrM",
+ cvtps2pd_2 = "rro:0F5ArM|rx/oq:",
+ cvtsd2si_2 = "rr/do:F20F2DrM|rx/dq:",
+ cvtsd2ss_2 = "rro:F20F5ArM|rx/oq:",
+ cvtsi2sd_2 = "rm/od:F20F2ArM",
+ cvtsi2ss_2 = "rm/od:F30F2ArM",
+ cvtss2sd_2 = "rro:F30F5ArM|rx/od:",
+ cvtss2si_2 = "rr/do:F20F2CrM|rx/dd:",
+ cvttpd2dq_2 = "rmo:660FE6rM",
+ cvttps2dq_2 = "rmo:F30F5BrM",
+ cvttsd2si_2 = "rr/do:F20F2CrM|rx/dq:",
+ cvttss2si_2 = "rr/do:F30F2CrM|rx/dd:",
+ haddpd_2 = "rmo:660F7CrM",
+ haddps_2 = "rmo:F20F7CrM",
+ hsubpd_2 = "rmo:660F7DrM",
+ hsubps_2 = "rmo:F20F7DrM",
+ lddqu_2 = "rxo:F20FF0rM",
+ ldmxcsr_1 = "xd:0FAE2m",
+ lfence_0 = "0FAEE8",
+ maskmovdqu_2 = "rro:660FF7rM",
+ mfence_0 = "0FAEF0",
+ movapd_2 = "rmo:660F28rM|mro:660F29Rm",
+ movaps_2 = "rmo:0F28rM|mro:0F29Rm",
+ movd_2 = "rm/od:660F6ErM|mr/do:660F7ERm",
+ movddup_2 = "rmo:F20F12rM",
+ movdqa_2 = "rmo:660F6FrM|mro:660F7FRm",
+ movdqu_2 = "rmo:F30F6FrM|mro:F30F7FRm",
+ movhlps_2 = "rro:0F12rM",
+ movhpd_2 = "rx/oq:660F16rM|xr/qo:660F17Rm",
+ movhps_2 = "rx/oq:0F16rM|xr/qo:0F17Rm",
+ movlhps_2 = "rro:0F16rM",
+ movlpd_2 = "rx/oq:660F12rM|xr/qo:660F13Rm",
+ movlps_2 = "rx/oq:0F12rM|xr/qo:0F13Rm",
+ movmskpd_2 = "rr/do:660F50rM",
+ movmskps_2 = "rr/do:0F50rM",
+ movntdq_2 = "xro:660FE7Rm",
+ movnti_2 = "xrd:0FC3Rm",
+ movntpd_2 = "xro:660F2BRm",
+ movntps_2 = "xro:0F2BRm",
+ movq_2 = "rro:F30F7ErM|rx/oq:|xr/qo:660FD6Rm",
+ movsd_2 = "rro:F20F10rM|rx/oq:|xr/qo:F20F11Rm",
+ movshdup_2 = "rmo:F30F16rM",
+ movsldup_2 = "rmo:F30F12rM",
+ movss_2 = "rro:F30F10rM|rx/od:|xr/do:F30F11Rm",
+ movupd_2 = "rmo:660F10rM|mro:660F11Rm",
+ movups_2 = "rmo:0F10rM|mro:0F11Rm",
+ orpd_2 = "rmo:660F56rM",
+ orps_2 = "rmo:0F56rM",
+ pabsb_2 = "rmo:660F381CrM",
+ pabsd_2 = "rmo:660F381ErM",
+ pabsw_2 = "rmo:660F381DrM",
+ packssdw_2 = "rmo:660F6BrM",
+ packsswb_2 = "rmo:660F63rM",
+ packuswb_2 = "rmo:660F67rM",
+ paddb_2 = "rmo:660FFCrM",
+ paddd_2 = "rmo:660FFErM",
+ paddq_2 = "rmo:660FD4rM",
+ paddsb_2 = "rmo:660FECrM",
+ paddsw_2 = "rmo:660FEDrM",
+ paddusb_2 = "rmo:660FDCrM",
+ paddusw_2 = "rmo:660FDDrM",
+ paddw_2 = "rmo:660FFDrM",
+ palignr_3 = "rmio:660F3A0FrMU",
+ pand_2 = "rmo:660FDBrM",
+ pandn_2 = "rmo:660FDFrM",
+ pause_0 = "F390",
+ pavgb_2 = "rmo:660FE0rM",
+ pavgw_2 = "rmo:660FE3rM",
+ pcmpeqb_2 = "rmo:660F74rM",
+ pcmpeqd_2 = "rmo:660F76rM",
+ pcmpeqw_2 = "rmo:660F75rM",
+ pcmpgtb_2 = "rmo:660F64rM",
+ pcmpgtd_2 = "rmo:660F66rM",
+ pcmpgtw_2 = "rmo:660F65rM",
+ pextrw_3 = "rri/do:660FC5rMU",
+ phaddd_2 = "rmo:660F3802rM",
+ phaddsw_2 = "rmo:660F3803rM",
+ phaddw_2 = "rmo:660F3801rM",
+ phsubd_2 = "rmo:660F3806rM",
+ phsubsw_2 = "rmo:660F3807rM",
+ phsubw_2 = "rmo:660F3805rM",
+ pinsrw_3 = "rri/od:660FC4rMU|rmi/ow:",
+ pmaddubsw_2 = "rmo:660F3804rM",
+ pmaddwd_2 = "rmo:660FF5rM",
+ pmaxsw_2 = "rmo:660FEErM",
+ pmaxub_2 = "rmo:660FDErM",
+ pminsw_2 = "rmo:660FEArM",
+ pminub_2 = "rmo:660FDArM",
+ pmovmskb_2 = "rr/do:660FD7rM",
+ pmulhrsw_2 = "rmo:660F380BrM",
+ pmulhuw_2 = "rmo:660FE4rM",
+ pmulhw_2 = "rmo:660FE5rM",
+ pmullw_2 = "rmo:660FD5rM",
+ pmuludq_2 = "rmo:660FF4rM",
+ por_2 = "rmo:660FEBrM",
+ prefetchnta_1 = "xb:n0F180m",
+ prefetcht0_1 = "xb:n0F181m",
+ prefetcht1_1 = "xb:n0F182m",
+ prefetcht2_1 = "xb:n0F183m",
+ psadbw_2 = "rmo:660FF6rM",
+ pshufb_2 = "rmo:660F3800rM",
+ pshufd_3 = "rmio:660F70rMU",
+ pshufhw_3 = "rmio:F30F70rMU",
+ pshuflw_3 = "rmio:F20F70rMU",
+ psignb_2 = "rmo:660F3808rM",
+ psignd_2 = "rmo:660F380ArM",
+ psignw_2 = "rmo:660F3809rM",
+ pslld_2 = "rmo:660FF2rM|rio:660F726mU",
+ pslldq_2 = "rio:660F737mU",
+ psllq_2 = "rmo:660FF3rM|rio:660F736mU",
+ psllw_2 = "rmo:660FF1rM|rio:660F716mU",
+ psrad_2 = "rmo:660FE2rM|rio:660F724mU",
+ psraw_2 = "rmo:660FE1rM|rio:660F714mU",
+ psrld_2 = "rmo:660FD2rM|rio:660F722mU",
+ psrldq_2 = "rio:660F733mU",
+ psrlq_2 = "rmo:660FD3rM|rio:660F732mU",
+ psrlw_2 = "rmo:660FD1rM|rio:660F712mU",
+ psubb_2 = "rmo:660FF8rM",
+ psubd_2 = "rmo:660FFArM",
+ psubq_2 = "rmo:660FFBrM",
+ psubsb_2 = "rmo:660FE8rM",
+ psubsw_2 = "rmo:660FE9rM",
+ psubusb_2 = "rmo:660FD8rM",
+ psubusw_2 = "rmo:660FD9rM",
+ psubw_2 = "rmo:660FF9rM",
+ punpckhbw_2 = "rmo:660F68rM",
+ punpckhdq_2 = "rmo:660F6ArM",
+ punpckhqdq_2 = "rmo:660F6DrM",
+ punpckhwd_2 = "rmo:660F69rM",
+ punpcklbw_2 = "rmo:660F60rM",
+ punpckldq_2 = "rmo:660F62rM",
+ punpcklqdq_2 = "rmo:660F6CrM",
+ punpcklwd_2 = "rmo:660F61rM",
+ pxor_2 = "rmo:660FEFrM",
+ rcpps_2 = "rmo:0F53rM",
+ rcpss_2 = "rmo:F30F53rM",
+ rsqrtps_2 = "rmo:0F52rM",
+ rsqrtss_2 = "rmo:F30F52rM",
+ sfence_0 = "0FAEF8",
+ shufpd_3 = "rmio:660FC6rMU",
+ shufps_3 = "rmio:0FC6rMU",
+ stmxcsr_1 = "xd:0FAE3m",
+ ucomisd_2 = "rmo:660F2ErM",
+ ucomiss_2 = "rmo:0F2ErM",
+ unpckhpd_2 = "rmo:660F15rM",
+ unpckhps_2 = "rmo:0F15rM",
+ unpcklpd_2 = "rmo:660F14rM",
+ unpcklps_2 = "rmo:0F14rM",
+ xorpd_2 = "rmo:660F57rM",
+ xorps_2 = "rmo:0F57rM",
+}
+
+------------------------------------------------------------------------------
+
+-- Arithmetic ops.
+for name,n in pairs{ add = 0, ["or"] = 1, adc = 2, sbb = 3,
+ ["and"] = 4, sub = 5, xor = 6, cmp = 7 } do
+ local n8 = n * 8
+ map_op[name.."_2"] = format(
+ "mr:%02XRm|rm:%02XrM|mI1dw:81%XmI|mS1dw:83%XmS|Ri1dwb:%02Xi|mi1dwb:81%Xmi",
+ 1+n8, 3+n8, n, n, 5+n8, n)
+end
+
+-- Shift ops.
+for name,n in pairs{ rol = 0, ror = 1, rcl = 2, rcr = 3,
+ shl = 4, shr = 5, sar = 7, sal = 4 } do
+ map_op[name.."_2"] = format("m1:D1%Xm|mC1dwb:D3%Xm|mi:C1%XmU", n, n, n)
+end
+
+-- Conditional ops.
+for cc,n in pairs(map_cc) do
+ map_op["j"..cc.."_1"] = format("J.:0F8%XJ", n) -- short: 7%X
+ map_op["set"..cc.."_1"] = format("mb:n0F9%X2m", n)
+ map_op["cmov"..cc.."_2"] = format("rmdw:0F4%XrM", n) -- P6+
+end
+
+-- FP arithmetic ops.
+for name,n in pairs{ add = 0, mul = 1, com = 2, comp = 3,
+ sub = 4, subr = 5, div = 6, divr = 7 } do
+ local nc = 192 + n * 8
+ local nr = nc + (n < 4 and 0 or (n % 2 == 0 and 8 or -8))
+ local fn = "f"..name
+ map_op[fn.."_1"] = format("ff:D8%02Xr|xd:D8%Xm|xq:DC%Xm", nc, n, n)
+ if n == 2 or n == 3 then
+ map_op[fn.."_2"] = format("Fff:D8%02XR|Fx2d:D8%XM|Fx2q:DC%XM", nc, n, n)
+ else
+ map_op[fn.."_2"] = format("Fff:D8%02XR|fFf:DC%02Xr|Fx2d:D8%XM|Fx2q:DC%XM", nc, nr, n, n)
+ map_op[fn.."p_1"] = format("ff:DE%02Xr", nr)
+ map_op[fn.."p_2"] = format("fFf:DE%02Xr", nr)
+ end
+ map_op["fi"..name.."_1"] = format("xd:DA%Xm|xw:nDE%Xm", n, n)
+end
+
+-- FP conditional moves.
+for cc,n in pairs{ b=0, e=1, be=2, u=3, nb=4, ne=5, nbe=6, nu=7 } do
+ local n4 = n % 4
+ local nc = 56000 + n4 * 8 + (n-n4) * 64
+ map_op["fcmov"..cc.."_1"] = format("ff:%04Xr", nc) -- P6+
+ map_op["fcmov"..cc.."_2"] = format("Fff:%04XR", nc) -- P6+
+end
+
+-- SSE FP arithmetic ops.
+for name,n in pairs{ sqrt = 1, add = 8, mul = 9,
+ sub = 12, min = 13, div = 14, max = 15 } do
+ map_op[name.."ps_2"] = format("rmo:0F5%XrM", n)
+ map_op[name.."ss_2"] = format("rro:F30F5%XrM|rx/od:", n)
+ map_op[name.."pd_2"] = format("rmo:660F5%XrM", n)
+ map_op[name.."sd_2"] = format("rro:F20F5%XrM|rx/oq:", n)
+end
+
+------------------------------------------------------------------------------
+
+-- Process pattern string.
+local function dopattern(pat, args, sz, op)
+ local digit, addin
+ local opcode = 0
+ local szov = sz
+
+ -- Limit number of section buffer positions used by a single dasm_put().
+ -- A single opcode needs a maximum of 2 positions. !x64
+ if secpos+2 > maxsecpos then wflush() end
+
+ -- Process each character.
+ for c in gmatch(pat, ".") do
+ if match(c, "%x") then -- Hex digit.
+ digit = byte(c) - 48
+ if digit > 48 then digit = digit - 39
+ elseif digit > 16 then digit = digit - 7 end
+ opcode = opcode*16 + digit
+ addin = nil
+ elseif c == "n" then -- Disable operand size mods for opcode.
+ szov = nil
+ elseif c == "r" then -- Merge 1st operand regno. into opcode.
+ addin = args[1].reg; opcode = opcode + addin
+ elseif c == "R" then -- Merge 2nd operand regno. into opcode.
+ addin = args[2].reg; opcode = opcode + addin
+ elseif c == "m" or c == "M" then -- Encode ModRM/SIB.
+ if addin then
+ opcode = opcode - addin -- Undo regno opcode merge.
+ else
+ addin = opcode % 16 -- Undo last digit.
+ opcode = (opcode - addin) / 16
+ end
+ wputop(szov, opcode); opcode = nil
+ local imark = (sub(pat, -1) == "I") -- Force a mark (ugly).
+ -- Put ModRM/SIB with regno/last digit as spare.
+ wputmrmsib(args[c == "m" and 1 or 2], addin, imark)
+ else
+ if opcode then wputop(szov, opcode); opcode = nil end -- Flush opcode.
+ if c == "o" or c == "O" then -- Offset (pure 32 bit displacement).
+ wputdarg(args[c == "o" and 1 or 2].disp)
+ else
+ -- Anything else is an immediate operand.
+ local a = args[#args]
+ local mode, imm = a.mode, a.imm
+ if mode == "iJ" and not match("iIJ", c) then
+ werror("bad operand size for label")
+ end
+ if c == "S" then
+ wputsbarg(imm)
+ elseif c == "U" then
+ wputbarg(imm)
+ elseif c == "W" then
+ wputwarg(imm)
+ elseif c == "i" or c == "I" then
+ if mode == "iJ" then
+ wputlabel("IMM_", imm, 1)
+ elseif mode == "iI" and c == "I" then
+ waction(sz == "w" and "IMM_WB" or "IMM_DB", imm)
+ else
+ wputszarg(sz, imm)
+ end
+ elseif c == "J" then
+ if mode == "iPJ" then
+ waction("REL_A", imm) -- !x64 (secpos)
+ else
+ wputlabel("REL_", imm, 2)
+ end
+ else
+ werror("bad char `"..c.."' in pattern `"..pat.."' for `"..op.."'")
+ end
+ end
+ end
+ end
+ if opcode then wputop(szov, opcode) end
+end
+
+------------------------------------------------------------------------------
+
+-- Mapping of operand modes to short names. Suppress output with '#'.
+local map_modename = {
+ r = "reg", R = "eax", C = "cl", x = "mem", m = "mrm", i = "imm",
+ f = "stx", F = "st0", J = "lbl", ["1"] = "1",
+ I = "#", S = "#", O = "#",
+}
+
+-- Return a table/string showing all possible operand modes.
+local function templatehelp(template, nparams)
+ if nparams == 0 then return "" end
+ local t = {}
+ for tm in gmatch(template, "[^%|]+") do
+ local s = map_modename[sub(tm, 1, 1)]
+ s = s..gsub(sub(tm, 2, nparams), ".", function(c)
+ return ", "..map_modename[c]
+ end)
+ if not match(s, "#") then t[#t+1] = s end
+ end
+ return t
+end
+
+-- Match operand modes against mode match part of template.
+local function matchtm(tm, args)
+ for i=1,#args do
+ if not match(args[i].mode, sub(tm, i, i)) then return end
+ end
+ return true
+end
+
+-- Handle opcodes defined with template strings.
+map_op[".template__"] = function(params, template, nparams)
+ if not params then return templatehelp(template, nparams) end
+ local args = {}
+
+ -- Zero-operand opcodes have no match part.
+ if #params == 0 then
+ dopattern(template, args, "d", params.op)
+ return
+ end
+
+ -- Determine common operand size (coerce undefined size) or flag as mixed.
+ local sz, szmix
+ for i,p in ipairs(params) do
+ args[i] = parseoperand(p)
+ local nsz = args[i].opsize
+ if nsz then
+ if sz and sz ~= nsz then szmix = true else sz = nsz end
+ end
+ end
+
+ -- Try all match:pattern pairs (separated by '|').
+ local gotmatch, lastpat
+ for tm in gmatch(template, "[^%|]+") do
+ -- Split off size match (starts after mode match) and pattern string.
+ local szm, pat = match(tm, "^(.-):(.*)$", #args+1)
+ if pat == "" then pat = lastpat else lastpat = pat end
+ if matchtm(tm, args) then
+ local prefix = sub(szm, 1, 1)
+ if prefix == "/" then -- Match both operand sizes.
+ if args[1].opsize == sub(szm, 2, 2) and
+ args[2].opsize == sub(szm, 3, 3) then
+ dopattern(pat, args, sz, params.op) -- Process pattern string.
+ return
+ end
+ else -- Match common operand size.
+ local szp = sz
+ if szm == "" then szm = "dwb" end -- Default size match.
+ if prefix == "1" then szp = args[1].opsize; szmix = nil
+ elseif prefix == "2" then szp = args[2].opsize; szmix = nil end
+ if not szmix and (prefix == "." or match(szm, szp or "#")) then
+ dopattern(pat, args, szp, params.op) -- Process pattern string.
+ return
+ end
+ end
+ gotmatch = true
+ end
+ end
+
+ local msg = "bad operand mode"
+ if gotmatch then
+ if szmix then
+ msg = "mixed operand size"
+ else
+ msg = sz and "bad operand size" or "missing operand size"
+ end
+ end
+
+ werror(msg.." in `"..opmodestr(params.op, args).."'")
+end
+
+------------------------------------------------------------------------------
+
+-- Pseudo-opcodes for data storage.
+local function op_data(params)
+ if not params then return "imm..." end
+ local sz = sub(params.op, 2, 2)
+ if sz == "a" then sz = addrsize end
+ for _,p in ipairs(params) do
+ local a = parseoperand(p)
+ if sub(a.mode, 1, 1) ~= "i" or (a.opsize and a.opsize ~= sz) then
+ werror("bad mode or size in `"..p.."'")
+ end
+ if a.mode == "iJ" then
+ wputlabel("IMM_", a.imm, 1)
+ else
+ wputszarg(sz, a.imm)
+ end
+ end
+end
+
+map_op[".byte_*"] = op_data
+map_op[".sbyte_*"] = op_data
+map_op[".word_*"] = op_data
+map_op[".dword_*"] = op_data
+map_op[".aword_*"] = op_data
+
+------------------------------------------------------------------------------
+
+-- Pseudo-opcode to mark the position where the action list is to be emitted.
+map_op[".actionlist_1"] = function(params)
+ if not params then return "cvar" end
+ local name = params[1] -- No syntax check. You get to keep the pieces.
+ wline(function(out) writeactions(out, name) end)
+end
+
+-- Pseudo-opcode to mark the position where the global enum is to be emitted.
+map_op[".globals_1"] = function(params)
+ if not params then return "prefix" end
+ local prefix = params[1] -- No syntax check. You get to keep the pieces.
+ wline(function(out) writeglobals(out, prefix) end)
+end
+
+------------------------------------------------------------------------------
+
+-- Label pseudo-opcode (converted from trailing colon form).
+map_op[".label_2"] = function(params)
+ if not params then return "[1-9] | ->global | =>pcexpr [, addr]" end
+ local a = parseoperand(params[1])
+ local mode, imm = a.mode, a.imm
+ if type(imm) == "number" and (mode == "iJ" or (imm >= 1 and imm <= 9)) then
+ -- Local label (1: ... 9:) or global label (->global:).
+ waction("LABEL_LG", nil, 1)
+ wputxb(imm)
+ elseif mode == "iJ" then
+ -- PC label (=>pcexpr:).
+ waction("LABEL_PC", imm)
+ else
+ werror("bad label definition")
+ end
+ -- SETLABEL must immediately follow LABEL_LG/LABEL_PC.
+ local addr = params[2]
+ if addr then
+ local a = parseoperand(params[2])
+ if a.mode == "iPJ" then
+ waction("SETLABEL", a.imm) -- !x64 (secpos)
+ else
+ werror("bad label assignment")
+ end
+ end
+end
+map_op[".label_1"] = map_op[".label_2"]
+
+------------------------------------------------------------------------------
+
+-- Alignment pseudo-opcode.
+map_op[".align_1"] = function(params)
+ if not params then return "numpow2" end
+ local align = tonumber(params[1]) or map_opsizenum[map_opsize[params[1]]]
+ if align then
+ local x = align
+ -- Must be a power of 2 in the range (2 ... 256).
+ for i=1,8 do
+ x = x / 2
+ if x == 1 then
+ waction("ALIGN", nil, 1)
+ wputxb(align-1) -- Action byte is 2**n-1.
+ return
+ end
+ end
+ end
+ werror("bad alignment")
+end
+
+-- Spacing pseudo-opcode.
+map_op[".space_2"] = function(params)
+ if not params then return "num [, filler]" end
+ waction("SPACE", params[1])
+ local fill = params[2]
+ if fill then
+ fill = tonumber(fill)
+ if not fill or fill < 0 or fill > 255 then werror("bad filler") end
+ end
+ wputxb(fill or 0)
+end
+map_op[".space_1"] = map_op[".space_2"]
+
+------------------------------------------------------------------------------
+
+-- Pseudo-opcode for (primitive) type definitions (map to C types).
+map_op[".type_3"] = function(params, nparams)
+ if not params then
+ return nparams == 2 and "name, ctype" or "name, ctype, reg"
+ end
+ local name, ctype, reg = params[1], params[2], params[3]
+ if not match(name, "^[%a_][%w_]*$") then
+ werror("bad type name `"..name.."'")
+ end
+ local tp = map_type[name]
+ if tp then
+ werror("duplicate type `"..name.."'")
+ end
+ if reg and not map_reg_valid_base[reg] then
+ werror("bad base register `"..(map_reg_rev[reg] or reg).."'")
+ end
+ -- Add #type to defines. A bit unclean to put it in map_archdef.
+ map_archdef["#"..name] = "sizeof("..ctype..")"
+ -- Add new type and emit shortcut define.
+ local num = ctypenum + 1
+ map_type[name] = {
+ ctype = ctype,
+ ctypefmt = format("Dt%X(%%s)", num),
+ reg = reg,
+ }
+ wline(format("#define Dt%X(_V) (int)&(((%s *)0)_V)", num, ctype))
+ ctypenum = num
+end
+map_op[".type_2"] = map_op[".type_3"]
+
+-- Dump type definitions.
+local function dumptypes(out, lvl)
+ local t = {}
+ for name in pairs(map_type) do t[#t+1] = name end
+ sort(t)
+ out:write("Type definitions:\n")
+ for _,name in ipairs(t) do
+ local tp = map_type[name]
+ local reg = tp.reg and map_reg_rev[tp.reg] or ""
+ out:write(format(" %-20s %-20s %s\n", name, tp.ctype, reg))
+ end
+ out:write("\n")
+end
+
+------------------------------------------------------------------------------
+
+-- Set the current section.
+function _M.section(num)
+ waction("SECTION")
+ wputxb(num)
+ wflush(true) -- SECTION is a terminal action.
+end
+
+------------------------------------------------------------------------------
+
+-- Dump architecture description.
+function _M.dumparch(out)
+ out:write(format("DynASM %s version %s, released %s\n\n",
+ _info.arch, _info.version, _info.release))
+ dumpregs(out)
+ dumpactions(out)
+end
+
+-- Dump all user defined elements.
+function _M.dumpdef(out, lvl)
+ dumptypes(out, lvl)
+ dumpglobals(out, lvl)
+end
+
+------------------------------------------------------------------------------
+
+-- Pass callbacks from/to the DynASM core.
+function _M.passcb(wl, we, wf, ww)
+ wline, werror, wfatal, wwarn = wl, we, wf, ww
+ return wflush
+end
+
+-- Setup the arch-specific module.
+function _M.setup(arch, opt)
+ g_arch, g_opt = arch, opt
+end
+
+-- Merge the core maps and the arch-specific maps.
+function _M.mergemaps(map_coreop, map_def)
+ setmetatable(map_op, { __index = map_coreop })
+ setmetatable(map_def, { __index = map_archdef })
+ return map_op, map_def
+end
+
+return _M
+
+------------------------------------------------------------------------------
+
diff --git a/libraries/LuaJIT-1.1.7/dynasm/dynasm.lua b/libraries/LuaJIT-1.1.7/dynasm/dynasm.lua
new file mode 100644
index 0000000..264a4bb
--- /dev/null
+++ b/libraries/LuaJIT-1.1.7/dynasm/dynasm.lua
@@ -0,0 +1,1070 @@
+------------------------------------------------------------------------------
+-- DynASM. A dynamic assembler for code generation engines.
+-- Originally designed and implemented for LuaJIT.
+--
+-- Copyright (C) 2005-2008 Mike Pall. All rights reserved.
+-- See below for full copyright notice.
+------------------------------------------------------------------------------
+
+-- Application information.
+local _info = {
+ name = "DynASM",
+ description = "A dynamic assembler for code generation engines",
+ version = "1.1.4",
+ vernum = 10104,
+ release = "2008-01-29",
+ author = "Mike Pall",
+ url = "http://luajit.org/dynasm.html",
+ license = "MIT",
+ copyright = [[
+Copyright (C) 2005-2008 Mike Pall. All rights reserved.
+
+Permission is hereby granted, free of charge, to any person obtaining
+a copy of this software and associated documentation files (the
+"Software"), to deal in the Software without restriction, including
+without limitation the rights to use, copy, modify, merge, publish,
+distribute, sublicense, and/or sell copies of the Software, and to
+permit persons to whom the Software is furnished to do so, subject to
+the following conditions:
+
+The above copyright notice and this permission notice shall be
+included in all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
+CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
+SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+
+[ MIT license: http://www.opensource.org/licenses/mit-license.php ]
+]],
+}
+
+-- Cache library functions.
+local type, pairs, ipairs = type, pairs, ipairs
+local pcall, error, assert = pcall, error, assert
+local _s = string
+local sub, match, gmatch, gsub = _s.sub, _s.match, _s.gmatch, _s.gsub
+local format, rep, upper = _s.format, _s.rep, _s.upper
+local _t = table
+local insert, remove, concat, sort = _t.insert, _t.remove, _t.concat, _t.sort
+local exit = os.exit
+local io = io
+local stdin, stdout, stderr = io.stdin, io.stdout, io.stderr
+
+------------------------------------------------------------------------------
+
+-- Program options.
+local g_opt = {}
+
+-- Global state for current file.
+local g_fname, g_curline, g_indent, g_lineno, g_synclineno, g_arch
+local g_errcount = 0
+
+-- Write buffer for output file.
+local g_wbuffer, g_capbuffer
+
+------------------------------------------------------------------------------
+
+-- Write an output line (or callback function) to the buffer.
+local function wline(line, needindent)
+ local buf = g_capbuffer or g_wbuffer
+ buf[#buf+1] = needindent and g_indent..line or line
+ g_synclineno = g_synclineno + 1
+end
+
+-- Write assembler line as a comment, if requestd.
+local function wcomment(aline)
+ if g_opt.comment then
+ wline(g_opt.comment..aline..g_opt.endcomment, true)
+ end
+end
+
+-- Resync CPP line numbers.
+local function wsync()
+ if g_synclineno ~= g_lineno and g_opt.cpp then
+ wline("# "..g_lineno..' "'..g_fname..'"')
+ g_synclineno = g_lineno
+ end
+end
+
+-- Dummy action flush function. Replaced with arch-specific function later.
+local function wflush(term)
+end
+
+-- Dump all buffered output lines.
+local function wdumplines(out, buf)
+ for _,line in ipairs(buf) do
+ if type(line) == "string" then
+ assert(out:write(line, "\n"))
+ else
+ -- Special callback to dynamically insert lines after end of processing.
+ line(out)
+ end
+ end
+end
+
+------------------------------------------------------------------------------
+
+-- Emit an error. Processing continues with next statement.
+local function werror(msg)
+ error(format("%s:%s: error: %s:\n%s", g_fname, g_lineno, msg, g_curline), 0)
+end
+
+-- Emit a fatal error. Processing stops.
+local function wfatal(msg)
+ g_errcount = "fatal"
+ werror(msg)
+end
+
+-- Print a warning. Processing continues.
+local function wwarn(msg)
+ stderr:write(format("%s:%s: warning: %s:\n%s\n",
+ g_fname, g_lineno, msg, g_curline))
+end
+
+-- Print caught error message. But suppress excessive errors.
+local function wprinterr(...)
+ if type(g_errcount) == "number" then
+ -- Regular error.
+ g_errcount = g_errcount + 1
+ if g_errcount < 21 then -- Seems to be a reasonable limit.
+ stderr:write(...)
+ elseif g_errcount == 21 then
+ stderr:write(g_fname,
+ ":*: warning: too many errors (suppressed further messages).\n")
+ end
+ else
+ -- Fatal error.
+ stderr:write(...)
+ return true -- Stop processing.
+ end
+end
+
+------------------------------------------------------------------------------
+
+-- Map holding all option handlers.
+local opt_map = {}
+local opt_current
+
+-- Print error and exit with error status.
+local function opterror(...)
+ stderr:write("dynasm.lua: ERROR: ", ...)
+ stderr:write("\n")
+ exit(1)
+end
+
+-- Get option parameter.
+local function optparam(args)
+ local argn = args.argn
+ local p = args[argn]
+ if not p then
+ opterror("missing parameter for option `", opt_current, "'.")
+ end
+ args.argn = argn + 1
+ return p
+end
+
+------------------------------------------------------------------------------
+
+-- Core pseudo-opcodes.
+local map_coreop = {}
+-- Dummy opcode map. Replaced by arch-specific map.
+local map_op = {}
+
+-- Forward declarations.
+local dostmt
+local readfile
+
+------------------------------------------------------------------------------
+
+-- Map for defines (initially empty, chains to arch-specific map).
+local map_def = {}
+
+-- Pseudo-opcode to define a substitution.
+map_coreop[".define_2"] = function(params, nparams)
+ if not params then return nparams == 1 and "name" or "name, subst" end
+ local name, def = params[1], params[2] or "1"
+ if not match(name, "^[%a_][%w_]*$") then werror("bad or duplicate define") end
+ map_def[name] = def
+end
+map_coreop[".define_1"] = map_coreop[".define_2"]
+
+-- Define a substitution on the command line.
+function opt_map.D(args)
+ local namesubst = optparam(args)
+ local name, subst = match(namesubst, "^([%a_][%w_]*)=(.*)$")
+ if name then
+ map_def[name] = subst
+ elseif match(namesubst, "^[%a_][%w_]*$") then
+ map_def[namesubst] = "1"
+ else
+ opterror("bad define")
+ end
+end
+
+-- Undefine a substitution on the command line.
+function opt_map.U(args)
+ local name = optparam(args)
+ if match(name, "^[%a_][%w_]*$") then
+ map_def[name] = nil
+ else
+ opterror("bad define")
+ end
+end
+
+-- Helper for definesubst.
+local gotsubst
+
+local function definesubst_one(word)
+ local subst = map_def[word]
+ if subst then gotsubst = word; return subst else return word end
+end
+
+-- Iteratively substitute defines.
+local function definesubst(stmt)
+ -- Limit number of iterations.
+ for i=1,100 do
+ gotsubst = false
+ stmt = gsub(stmt, "#?[%w_]+", definesubst_one)
+ if not gotsubst then break end
+ end
+ if gotsubst then wfatal("recursive define involving `"..gotsubst.."'") end
+ return stmt
+end
+
+-- Dump all defines.
+local function dumpdefines(out, lvl)
+ local t = {}
+ for name in pairs(map_def) do
+ t[#t+1] = name
+ end
+ sort(t)
+ out:write("Defines:\n")
+ for _,name in ipairs(t) do
+ local subst = map_def[name]
+ if g_arch then subst = g_arch.revdef(subst) end
+ out:write(format(" %-20s %s\n", name, subst))
+ end
+ out:write("\n")
+end
+
+------------------------------------------------------------------------------
+
+-- Support variables for conditional assembly.
+local condlevel = 0
+local condstack = {}
+
+-- Evaluate condition with a Lua expression. Substitutions already performed.
+local function cond_eval(cond)
+ local func, err = loadstring("return "..cond)
+ if func then
+ setfenv(func, {}) -- No globals. All unknown identifiers evaluate to nil.
+ local ok, res = pcall(func)
+ if ok then
+ if res == 0 then return false end -- Oh well.
+ return not not res
+ end
+ err = res
+ end
+ wfatal("bad condition: "..err)
+end
+
+-- Skip statements until next conditional pseudo-opcode at the same level.
+local function stmtskip()
+ local dostmt_save = dostmt
+ local lvl = 0
+ dostmt = function(stmt)
+ local op = match(stmt, "^%s*(%S+)")
+ if op == ".if" then
+ lvl = lvl + 1
+ elseif lvl ~= 0 then
+ if op == ".endif" then lvl = lvl - 1 end
+ elseif op == ".elif" or op == ".else" or op == ".endif" then
+ dostmt = dostmt_save
+ dostmt(stmt)
+ end
+ end
+end
+
+-- Pseudo-opcodes for conditional assembly.
+map_coreop[".if_1"] = function(params)
+ if not params then return "condition" end
+ local lvl = condlevel + 1
+ local res = cond_eval(params[1])
+ condlevel = lvl
+ condstack[lvl] = res
+ if not res then stmtskip() end
+end
+
+map_coreop[".elif_1"] = function(params)
+ if not params then return "condition" end
+ if condlevel == 0 then wfatal(".elif without .if") end
+ local lvl = condlevel
+ local res = condstack[lvl]
+ if res then
+ if res == "else" then wfatal(".elif after .else") end
+ else
+ res = cond_eval(params[1])
+ if res then
+ condstack[lvl] = res
+ return
+ end
+ end
+ stmtskip()
+end
+
+map_coreop[".else_0"] = function(params)
+ if condlevel == 0 then wfatal(".else without .if") end
+ local lvl = condlevel
+ local res = condstack[lvl]
+ condstack[lvl] = "else"
+ if res then
+ if res == "else" then wfatal(".else after .else") end
+ stmtskip()
+ end
+end
+
+map_coreop[".endif_0"] = function(params)
+ local lvl = condlevel
+ if lvl == 0 then wfatal(".endif without .if") end
+ condlevel = lvl - 1
+end
+
+-- Check for unfinished conditionals.
+local function checkconds()
+ if g_errcount ~= "fatal" and condlevel ~= 0 then
+ wprinterr(g_fname, ":*: error: unbalanced conditional\n")
+ end
+end
+
+------------------------------------------------------------------------------
+
+-- Search for a file in the given path and open it for reading.
+local function pathopen(path, name)
+ local dirsep = match(package.path, "\\") and "\\" or "/"
+ for _,p in ipairs(path) do
+ local fullname = p == "" and name or p..dirsep..name
+ local fin = io.open(fullname, "r")
+ if fin then
+ g_fname = fullname
+ return fin
+ end
+ end
+end
+
+-- Include a file.
+map_coreop[".include_1"] = function(params)
+ if not params then return "filename" end
+ local name = params[1]
+ -- Save state. Ugly, I know. but upvalues are fast.
+ local gf, gl, gcl, gi = g_fname, g_lineno, g_curline, g_indent
+ -- Read the included file.
+ local fatal = readfile(pathopen(g_opt.include, name) or
+ wfatal("include file `"..name.."' not found"))
+ -- Restore state.
+ g_synclineno = -1
+ g_fname, g_lineno, g_curline, g_indent = gf, gl, gcl, gi
+ if fatal then wfatal("in include file") end
+end
+
+-- Make .include initially available, too.
+map_op[".include_1"] = map_coreop[".include_1"]
+
+------------------------------------------------------------------------------
+
+-- Support variables for macros.
+local mac_capture, mac_lineno, mac_name
+local mac_active = {}
+local mac_list = {}
+
+-- Pseudo-opcode to define a macro.
+map_coreop[".macro_*"] = function(mparams)
+ if not mparams then return "name [, params...]" end
+ -- Split off and validate macro name.
+ local name = remove(mparams, 1)
+ if not name then werror("missing macro name") end
+ if not (match(name, "^[%a_][%w_%.]*$") or match(name, "^%.[%w_%.]+$")) then
+ wfatal("bad macro name `"..name.."'")
+ end
+ -- Validate macro parameter names.
+ local mdup = {}
+ for _,mp in ipairs(mparams) do
+ if not match(mp, "^[%a_][%w_]*$") then
+ wfatal("bad macro parameter name `"..mp.."'")
+ end
+ if mdup[mp] then wfatal("duplicate macro parameter name `"..mp.."'") end
+ mdup[mp] = true
+ end
+ -- Check for duplicate or recursive macro definitions.
+ local opname = name.."_"..#mparams
+ if map_op[opname] or map_op[name.."_*"] then
+ wfatal("duplicate macro `"..name.."' ("..#mparams.." parameters)")
+ end
+ if mac_capture then wfatal("recursive macro definition") end
+
+ -- Enable statement capture.
+ local lines = {}
+ mac_lineno = g_lineno
+ mac_name = name
+ mac_capture = function(stmt) -- Statement capture function.
+ -- Stop macro definition with .endmacro pseudo-opcode.
+ if not match(stmt, "^%s*.endmacro%s*$") then
+ lines[#lines+1] = stmt
+ return
+ end
+ mac_capture = nil
+ mac_lineno = nil
+ mac_name = nil
+ mac_list[#mac_list+1] = opname
+ -- Add macro-op definition.
+ map_op[opname] = function(params)
+ if not params then return mparams, lines end
+ -- Protect against recursive macro invocation.
+ if mac_active[opname] then wfatal("recursive macro invocation") end
+ mac_active[opname] = true
+ -- Setup substitution map.
+ local subst = {}
+ for i,mp in ipairs(mparams) do subst[mp] = params[i] end
+ local mcom
+ if g_opt.maccomment and g_opt.comment then
+ mcom = " MACRO "..name.." ("..#mparams..")"
+ wcomment("{"..mcom)
+ end
+ -- Loop through all captured statements
+ for _,stmt in ipairs(lines) do
+ -- Substitute macro parameters.
+ local st = gsub(stmt, "[%w_]+", subst)
+ st = definesubst(st)
+ st = gsub(st, "%s*%.%.%s*", "") -- Token paste a..b.
+ if mcom and sub(st, 1, 1) ~= "|" then wcomment(st) end
+ -- Emit statement. Use a protected call for better diagnostics.
+ local ok, err = pcall(dostmt, st)
+ if not ok then
+ -- Add the captured statement to the error.
+ wprinterr(err, "\n", g_indent, "| ", stmt,
+ "\t[MACRO ", name, " (", #mparams, ")]\n")
+ end
+ end
+ if mcom then wcomment("}"..mcom) end
+ mac_active[opname] = nil
+ end
+ end
+end
+
+-- An .endmacro pseudo-opcode outside of a macro definition is an error.
+map_coreop[".endmacro_0"] = function(params)
+ wfatal(".endmacro without .macro")
+end
+
+-- Dump all macros and their contents (with -PP only).
+local function dumpmacros(out, lvl)
+ sort(mac_list)
+ out:write("Macros:\n")
+ for _,opname in ipairs(mac_list) do
+ local name = sub(opname, 1, -3)
+ local params, lines = map_op[opname]()
+ out:write(format(" %-20s %s\n", name, concat(params, ", ")))
+ if lvl > 1 then
+ for _,line in ipairs(lines) do
+ out:write(" |", line, "\n")
+ end
+ out:write("\n")
+ end
+ end
+ out:write("\n")
+end
+
+-- Check for unfinished macro definitions.
+local function checkmacros()
+ if mac_capture then
+ wprinterr(g_fname, ":", mac_lineno,
+ ": error: unfinished .macro `", mac_name ,"'\n")
+ end
+end
+
+------------------------------------------------------------------------------
+
+-- Support variables for captures.
+local cap_lineno, cap_name
+local cap_buffers = {}
+local cap_used = {}
+
+-- Start a capture.
+map_coreop[".capture_1"] = function(params)
+ if not params then return "name" end
+ wflush()
+ local name = params[1]
+ if not match(name, "^[%a_][%w_]*$") then
+ wfatal("bad capture name `"..name.."'")
+ end
+ if cap_name then
+ wfatal("already capturing to `"..cap_name.."' since line "..cap_lineno)
+ end
+ cap_name = name
+ cap_lineno = g_lineno
+ -- Create or continue a capture buffer and start the output line capture.
+ local buf = cap_buffers[name]
+ if not buf then buf = {}; cap_buffers[name] = buf end
+ g_capbuffer = buf
+ g_synclineno = 0
+end
+
+-- Stop a capture.
+map_coreop[".endcapture_0"] = function(params)
+ wflush()
+ if not cap_name then wfatal(".endcapture without a valid .capture") end
+ cap_name = nil
+ cap_lineno = nil
+ g_capbuffer = nil
+ g_synclineno = 0
+end
+
+-- Dump a capture buffer.
+map_coreop[".dumpcapture_1"] = function(params)
+ if not params then return "name" end
+ wflush()
+ local name = params[1]
+ if not match(name, "^[%a_][%w_]*$") then
+ wfatal("bad capture name `"..name.."'")
+ end
+ cap_used[name] = true
+ wline(function(out)
+ local buf = cap_buffers[name]
+ if buf then wdumplines(out, buf) end
+ end)
+ g_synclineno = 0
+end
+
+-- Dump all captures and their buffers (with -PP only).
+local function dumpcaptures(out, lvl)
+ out:write("Captures:\n")
+ for name,buf in pairs(cap_buffers) do
+ out:write(format(" %-20s %4s)\n", name, "("..#buf))
+ if lvl > 1 then
+ local bar = rep("=", 76)
+ out:write(" ", bar, "\n")
+ for _,line in ipairs(buf) do
+ out:write(" ", line, "\n")
+ end
+ out:write(" ", bar, "\n\n")
+ end
+ end
+ out:write("\n")
+end
+
+-- Check for unfinished or unused captures.
+local function checkcaptures()
+ if cap_name then
+ wprinterr(g_fname, ":", cap_lineno,
+ ": error: unfinished .capture `", cap_name,"'\n")
+ return
+ end
+ for name in pairs(cap_buffers) do
+ if not cap_used[name] then
+ wprinterr(g_fname, ":*: error: missing .dumpcapture ", name ,"\n")
+ end
+ end
+end
+
+------------------------------------------------------------------------------
+
+-- Sections names.
+local map_sections = {}
+
+-- Pseudo-opcode to define code sections.
+-- TODO: Data sections, BSS sections. Needs extra C code and API.
+map_coreop[".section_*"] = function(params)
+ if not params then return "name..." end
+ if #map_sections > 0 then werror("duplicate section definition") end
+ wflush()
+ for sn,name in ipairs(params) do
+ local opname = "."..name.."_0"
+ if not match(name, "^[%a][%w_]*$") or
+ map_op[opname] or map_op["."..name.."_*"] then
+ werror("bad section name `"..name.."'")
+ end
+ map_sections[#map_sections+1] = name
+ wline(format("#define DASM_SECTION_%s\t%d", upper(name), sn-1))
+ map_op[opname] = function(params) g_arch.section(sn-1) end
+ end
+ wline(format("#define DASM_MAXSECTION\t\t%d", #map_sections))
+end
+
+-- Dump all sections.
+local function dumpsections(out, lvl)
+ out:write("Sections:\n")
+ for _,name in ipairs(map_sections) do
+ out:write(format(" %s\n", name))
+ end
+ out:write("\n")
+end
+
+------------------------------------------------------------------------------
+
+-- Load architecture-specific module.
+local function loadarch(arch)
+ if not match(arch, "^[%w_]+$") then return "bad arch name" end
+ local ok, m_arch = pcall(require, "dasm_"..arch)
+ if not ok then return "cannot load module: "..m_arch end
+ g_arch = m_arch
+ wflush = m_arch.passcb(wline, werror, wfatal, wwarn)
+ m_arch.setup(arch, g_opt)
+ map_op, map_def = m_arch.mergemaps(map_coreop, map_def)
+end
+
+-- Dump architecture description.
+function opt_map.dumparch(args)
+ local name = optparam(args)
+ if not g_arch then
+ local err = loadarch(name)
+ if err then opterror(err) end
+ end
+
+ local t = {}
+ for name in pairs(map_coreop) do t[#t+1] = name end
+ for name in pairs(map_op) do t[#t+1] = name end
+ sort(t)
+
+ local out = stdout
+ local _arch = g_arch._info
+ out:write(format("%s version %s, released %s, %s\n",
+ _info.name, _info.version, _info.release, _info.url))
+ g_arch.dumparch(out)
+
+ local pseudo = true
+ out:write("Pseudo-Opcodes:\n")
+ for _,sname in ipairs(t) do
+ local name, nparam = match(sname, "^(.+)_([0-9%*])$")
+ if name then
+ if pseudo and sub(name, 1, 1) ~= "." then
+ out:write("\nOpcodes:\n")
+ pseudo = false
+ end
+ local f = map_op[sname]
+ local s
+ if nparam ~= "*" then nparam = nparam + 0 end
+ if nparam == 0 then
+ s = ""
+ elseif type(f) == "string" then
+ s = map_op[".template__"](nil, f, nparam)
+ else
+ s = f(nil, nparam)
+ end
+ if type(s) == "table" then
+ for _,s2 in ipairs(s) do
+ out:write(format(" %-12s %s\n", name, s2))
+ end
+ else
+ out:write(format(" %-12s %s\n", name, s))
+ end
+ end
+ end
+ out:write("\n")
+ exit(0)
+end
+
+-- Pseudo-opcode to set the architecture.
+-- Only initially available (map_op is replaced when called).
+map_op[".arch_1"] = function(params)
+ if not params then return "name" end
+ local err = loadarch(params[1])
+ if err then wfatal(err) end
+end
+
+-- Dummy .arch pseudo-opcode to improve the error report.
+map_coreop[".arch_1"] = function(params)
+ if not params then return "name" end
+ wfatal("duplicate .arch statement")
+end
+
+------------------------------------------------------------------------------
+
+-- Dummy pseudo-opcode. Don't confuse '.nop' with 'nop'.
+map_coreop[".nop_*"] = function(params)
+ if not params then return "[ignored...]" end
+end
+
+-- Pseudo-opcodes to raise errors.
+map_coreop[".error_1"] = function(params)
+ if not params then return "message" end
+ werror(params[1])
+end
+
+map_coreop[".fatal_1"] = function(params)
+ if not params then return "message" end
+ wfatal(params[1])
+end
+
+-- Dump all user defined elements.
+local function dumpdef(out)
+ local lvl = g_opt.dumpdef
+ if lvl == 0 then return end
+ dumpsections(out, lvl)
+ dumpdefines(out, lvl)
+ if g_arch then g_arch.dumpdef(out, lvl) end
+ dumpmacros(out, lvl)
+ dumpcaptures(out, lvl)
+end
+
+------------------------------------------------------------------------------
+
+-- Helper for splitstmt.
+local splitlvl
+
+local function splitstmt_one(c)
+ if c == "(" then
+ splitlvl = ")"..splitlvl
+ elseif c == "[" then
+ splitlvl = "]"..splitlvl
+ elseif c == ")" or c == "]" then
+ if sub(splitlvl, 1, 1) ~= c then werror("unbalanced () or []") end
+ splitlvl = sub(splitlvl, 2)
+ elseif splitlvl == "" then
+ return " \0 "
+ end
+ return c
+end
+
+-- Split statement into (pseudo-)opcode and params.
+local function splitstmt(stmt)
+ -- Convert label with trailing-colon into .label statement.
+ local label = match(stmt, "^%s*(.+):%s*$")
+ if label then return ".label", {label} end
+
+ -- Split at commas and equal signs, but obey parentheses and brackets.
+ splitlvl = ""
+ stmt = gsub(stmt, "[,%(%)%[%]]", splitstmt_one)
+ if splitlvl ~= "" then werror("unbalanced () or []") end
+
+ -- Split off opcode.
+ local op, other = match(stmt, "^%s*([^%s%z]+)%s*(.*)$")
+ if not op then werror("bad statement syntax") end
+
+ -- Split parameters.
+ local params = {}
+ for p in gmatch(other, "%s*(%Z+)%z?") do
+ params[#params+1] = gsub(p, "%s+$", "")
+ end
+ if #params > 16 then werror("too many parameters") end
+
+ params.op = op
+ return op, params
+end
+
+-- Process a single statement.
+dostmt = function(stmt)
+ -- Ignore empty statements.
+ if match(stmt, "^%s*$") then return end
+
+ -- Capture macro defs before substitution.
+ if mac_capture then return mac_capture(stmt) end
+ stmt = definesubst(stmt)
+
+ -- Emit C code without parsing the line.
+ if sub(stmt, 1, 1) == "|" then
+ local tail = sub(stmt, 2)
+ wflush()
+ if sub(tail, 1, 2) == "//" then wcomment(tail) else wline(tail, true) end
+ return
+ end
+
+ -- Split into (pseudo-)opcode and params.
+ local op, params = splitstmt(stmt)
+
+ -- Get opcode handler (matching # of parameters or generic handler).
+ local f = map_op[op.."_"..#params] or map_op[op.."_*"]
+ if not f then
+ if not g_arch then wfatal("first statement must be .arch") end
+ -- Improve error report.
+ for i=0,16 do
+ if map_op[op.."_"..i] then
+ werror("wrong number of parameters for `"..op.."'")
+ end
+ end
+ werror("unknown statement `"..op.."'")
+ end
+
+ -- Call opcode handler or special handler for template strings.
+ if type(f) == "string" then
+ map_op[".template__"](params, f)
+ else
+ f(params)
+ end
+end
+
+-- Process a single line.
+local function doline(line)
+ if g_opt.flushline then wflush() end
+
+ -- Assembler line?
+ local indent, aline = match(line, "^(%s*)%|(.*)$")
+ if not aline then
+ -- No, plain C code line, need to flush first.
+ wflush()
+ wsync()
+ wline(line, false)
+ return
+ end
+
+ g_indent = indent -- Remember current line indentation.
+
+ -- Emit C code (even from macros). Avoids echo and line parsing.
+ if sub(aline, 1, 1) == "|" then
+ if not mac_capture then
+ wsync()
+ elseif g_opt.comment then
+ wsync()
+ wcomment(aline)
+ end
+ dostmt(aline)
+ return
+ end
+
+ -- Echo assembler line as a comment.
+ if g_opt.comment then
+ wsync()
+ wcomment(aline)
+ end
+
+ -- Strip assembler comments.
+ aline = gsub(aline, "//.*$", "")
+
+ -- Split line into statements at semicolons.
+ if match(aline, ";") then
+ for stmt in gmatch(aline, "[^;]+") do dostmt(stmt) end
+ else
+ dostmt(aline)
+ end
+end
+
+------------------------------------------------------------------------------
+
+-- Write DynASM header.
+local function dasmhead(out)
+ out:write(format([[
+/*
+** This file has been pre-processed with DynASM.
+** %s
+** DynASM version %s, DynASM %s version %s
+** DO NOT EDIT! The original file is in "%s".
+*/
+
+#if DASM_VERSION != %d
+#error "Version mismatch between DynASM and included encoding engine"
+#endif
+
+]], _info.url,
+ _info.version, g_arch._info.arch, g_arch._info.version,
+ g_fname, _info.vernum))
+end
+
+-- Read input file.
+readfile = function(fin)
+ g_indent = ""
+ g_lineno = 0
+ g_synclineno = -1
+
+ -- Process all lines.
+ for line in fin:lines() do
+ g_lineno = g_lineno + 1
+ g_curline = line
+ local ok, err = pcall(doline, line)
+ if not ok and wprinterr(err, "\n") then return true end
+ end
+ wflush()
+
+ -- Close input file.
+ assert(fin == stdin or fin:close())
+end
+
+-- Write output file.
+local function writefile(outfile)
+ local fout
+
+ -- Open output file.
+ if outfile == nil or outfile == "-" then
+ fout = stdout
+ else
+ fout = assert(io.open(outfile, "w"))
+ end
+
+ -- Write all buffered lines
+ wdumplines(fout, g_wbuffer)
+
+ -- Close output file.
+ assert(fout == stdout or fout:close())
+
+ -- Optionally dump definitions.
+ dumpdef(fout == stdout and stderr or stdout)
+end
+
+-- Translate an input file to an output file.
+local function translate(infile, outfile)
+ g_wbuffer = {}
+ g_indent = ""
+ g_lineno = 0
+ g_synclineno = -1
+
+ -- Put header.
+ wline(dasmhead)
+
+ -- Read input file.
+ local fin
+ if infile == "-" then
+ g_fname = "(stdin)"
+ fin = stdin
+ else
+ g_fname = infile
+ fin = assert(io.open(infile, "r"))
+ end
+ readfile(fin)
+
+ -- Check for errors.
+ if not g_arch then
+ wprinterr(g_fname, ":*: error: missing .arch directive\n")
+ end
+ checkconds()
+ checkmacros()
+ checkcaptures()
+
+ if g_errcount ~= 0 then
+ stderr:write(g_fname, ":*: info: ", g_errcount, " error",
+ (type(g_errcount) == "number" and g_errcount > 1) and "s" or "",
+ " in input file -- no output file generated.\n")
+ dumpdef(stderr)
+ exit(1)
+ end
+
+ -- Write output file.
+ writefile(outfile)
+end
+
+------------------------------------------------------------------------------
+
+-- Print help text.
+function opt_map.help()
+ stdout:write("DynASM -- ", _info.description, ".\n")
+ stdout:write("DynASM ", _info.version, " ", _info.release, " ", _info.url, "\n")
+ stdout:write[[
+
+Usage: dynasm [OPTION]... INFILE.dasc|-
+
+ -h, --help Display this help text.
+ -V, --version Display version and copyright information.
+
+ -o, --outfile FILE Output file name (default is stdout).
+ -I, --include DIR Add directory to the include search path.
+
+ -c, --ccomment Use /* */ comments for assembler lines.
+ -C, --cppcomment Use // comments for assembler lines (default).
+ -N, --nocomment Suppress assembler lines in output.
+ -M, --maccomment Show macro expansions as comments (default off).
+
+ -L, --nolineno Suppress CPP line number information in output.
+ -F, --flushline Flush action list for every line.
+
+ -D NAME[=SUBST] Define a substitution.
+ -U NAME Undefine a substitution.
+
+ -P, --dumpdef Dump defines, macros, etc. Repeat for more output.
+ -A, --dumparch ARCH Load architecture ARCH and dump description.
+]]
+ exit(0)
+end
+
+-- Print version information.
+function opt_map.version()
+ stdout:write(format("%s version %s, released %s\n%s\n\n%s",
+ _info.name, _info.version, _info.release, _info.url, _info.copyright))
+ exit(0)
+end
+
+-- Misc. options.
+function opt_map.outfile(args) g_opt.outfile = optparam(args) end
+function opt_map.include(args) insert(g_opt.include, 1, optparam(args)) end
+function opt_map.ccomment() g_opt.comment = "/*|"; g_opt.endcomment = " */" end
+function opt_map.cppcomment() g_opt.comment = "//|"; g_opt.endcomment = "" end
+function opt_map.nocomment() g_opt.comment = false end
+function opt_map.maccomment() g_opt.maccomment = true end
+function opt_map.nolineno() g_opt.cpp = false end
+function opt_map.flushline() g_opt.flushline = true end
+function opt_map.dumpdef() g_opt.dumpdef = g_opt.dumpdef + 1 end
+
+------------------------------------------------------------------------------
+
+-- Short aliases for long options.
+local opt_alias = {
+ h = "help", ["?"] = "help", V = "version",
+ o = "outfile", I = "include",
+ c = "ccomment", C = "cppcomment", N = "nocomment", M = "maccomment",
+ L = "nolineno", F = "flushline",
+ P = "dumpdef", A = "dumparch",
+}
+
+-- Parse single option.
+local function parseopt(opt, args)
+ opt_current = #opt == 1 and "-"..opt or "--"..opt
+ local f = opt_map[opt] or opt_map[opt_alias[opt]]
+ if not f then
+ opterror("unrecognized option `", opt_current, "'. Try `--help'.\n")
+ end
+ f(args)
+end
+
+-- Parse arguments.
+local function parseargs(args)
+ -- Default options.
+ g_opt.comment = "//|"
+ g_opt.endcomment = ""
+ g_opt.cpp = true
+ g_opt.dumpdef = 0
+ g_opt.include = { "" }
+
+ -- Process all option arguments.
+ args.argn = 1
+ repeat
+ local a = args[args.argn]
+ if not a then break end
+ local lopt, opt = match(a, "^%-(%-?)(.+)")
+ if not opt then break end
+ args.argn = args.argn + 1
+ if lopt == "" then
+ -- Loop through short options.
+ for o in gmatch(opt, ".") do parseopt(o, args) end
+ else
+ -- Long option.
+ parseopt(opt, args)
+ end
+ until false
+
+ -- Check for proper number of arguments.
+ local nargs = #args - args.argn + 1
+ if nargs ~= 1 then
+ if nargs == 0 then
+ if g_opt.dumpdef > 0 then return dumpdef(stdout) end
+ end
+ opt_map.help()
+ end
+
+ -- Translate a single input file to a single output file
+ -- TODO: Handle multiple files?
+ translate(args[args.argn], g_opt.outfile)
+end
+
+------------------------------------------------------------------------------
+
+-- Add the directory dynasm.lua resides in to the Lua module search path.
+local arg = arg
+if arg and arg[0] then
+ local prefix = match(arg[0], "^(.*/)")
+ if prefix then package.path = prefix.."?.lua;"..package.path end
+end
+
+-- Start DynASM.
+parseargs{...}
+
+------------------------------------------------------------------------------
+
diff --git a/libraries/LuaJIT-1.1.7/etc/README b/libraries/LuaJIT-1.1.7/etc/README
new file mode 100644
index 0000000..98117d0
--- /dev/null
+++ b/libraries/LuaJIT-1.1.7/etc/README
@@ -0,0 +1,20 @@
+This directory contains some useful files and code.
+Unlike the code in ../src, everything here is in the public domain.
+
+lua.hpp
+ Lua header files for C++ using 'extern "C"'.
+
+luajit.ico
+ A LuaJIT icon for Windows (and web sites: save as favicon.ico).
+ Lua icon drawn by hand by Markus Gritsch. Modified for LuaJIT.
+
+luajit.pc
+ pkg-config data for LuaJIT
+
+luavs.bat
+ Script to build LuaJIT under "Visual Studio .NET Command Prompt".
+ Run it from the toplevel as etc\luavs.bat.
+
+strict.lua
+ Traps uses of undeclared global variables.
+
diff --git a/libraries/LuaJIT-1.1.7/etc/lua.hpp b/libraries/LuaJIT-1.1.7/etc/lua.hpp
new file mode 100644
index 0000000..ec417f5
--- /dev/null
+++ b/libraries/LuaJIT-1.1.7/etc/lua.hpp
@@ -0,0 +1,9 @@
+// lua.hpp
+// Lua header files for C++
+// <> not supplied automatically because Lua also compiles as C++
+
+extern "C" {
+#include "lua.h"
+#include "lualib.h"
+#include "lauxlib.h"
+}
diff --git a/libraries/LuaJIT-1.1.7/etc/luajit.ico b/libraries/LuaJIT-1.1.7/etc/luajit.ico
new file mode 100644
index 0000000..bdd7a90
Binary files /dev/null and b/libraries/LuaJIT-1.1.7/etc/luajit.ico differ
diff --git a/libraries/LuaJIT-1.1.7/etc/luajit.pc b/libraries/LuaJIT-1.1.7/etc/luajit.pc
new file mode 100644
index 0000000..1444076
--- /dev/null
+++ b/libraries/LuaJIT-1.1.7/etc/luajit.pc
@@ -0,0 +1,28 @@
+# luajit.pc -- pkg-config data for LuaJIT
+
+# vars from install Makefile
+
+# grep '^J*V=' ../Makefile
+V= 5.1
+JV= 1.1.7
+
+# grep '^INSTALL_.*=' ../Makefile | sed 's/INSTALL_TOP/prefix/'
+prefix= /usr/local
+INSTALL_BIN= ${prefix}/bin
+INSTALL_INC= ${prefix}/include
+INSTALL_LIB= ${prefix}/lib
+INSTALL_MAN= ${prefix}/man/man1
+INSTALL_LMOD= ${prefix}/share/lua/${V}
+INSTALL_CMOD= ${prefix}/lib/lua/${V}
+
+exec_prefix=${prefix}
+libdir=${exec_prefix}/lib
+includedir=${prefix}/include
+
+Name: LuaJIT
+Description: An Extensible Extension Language (JIT compiled for speed)
+Version: ${JV}
+Requires:
+Libs: -L${libdir} -llua -lm
+Cflags: -I${includedir}
+
diff --git a/libraries/LuaJIT-1.1.7/etc/luavs.bat b/libraries/LuaJIT-1.1.7/etc/luavs.bat
new file mode 100755
index 0000000..4f311e2
--- /dev/null
+++ b/libraries/LuaJIT-1.1.7/etc/luavs.bat
@@ -0,0 +1,22 @@
+@rem Script to build LuaJIT under "Visual Studio .NET Command Prompt".
+@rem Do not run from this directory; run it from the toplevel: etc\luavs.bat .
+@rem It creates lua51.dll, lua51.lib and luajit.exe in src.
+@rem (contributed by David Manura and Mike Pall)
+
+@setlocal
+@set MYCOMPILE=cl /nologo /MD /O2 /W3 /c /D_CRT_SECURE_NO_DEPRECATE /I . /I ..\dynasm
+@set MYLINK=link /nologo
+@set MYMT=mt /nologo
+
+cd src
+%MYCOMPILE% /DLUA_BUILD_AS_DLL l*.c
+del lua.obj luac.obj
+%MYLINK% /DLL /out:lua51.dll l*.obj
+if exist lua51.dll.manifest^
+ %MYMT% -manifest lua51.dll.manifest -outputresource:lua51.dll;2
+%MYCOMPILE% /DLUA_BUILD_AS_DLL lua.c
+%MYLINK% /out:luajit.exe lua.obj lua51.lib
+if exist luajit.exe.manifest^
+ %MYMT% -manifest luajit.exe.manifest -outputresource:luajit.exe
+del *.obj *.manifest
+cd ..
diff --git a/libraries/LuaJIT-1.1.7/etc/strict.lua b/libraries/LuaJIT-1.1.7/etc/strict.lua
new file mode 100644
index 0000000..604619d
--- /dev/null
+++ b/libraries/LuaJIT-1.1.7/etc/strict.lua
@@ -0,0 +1,41 @@
+--
+-- strict.lua
+-- checks uses of undeclared global variables
+-- All global variables must be 'declared' through a regular assignment
+-- (even assigning nil will do) in a main chunk before being used
+-- anywhere or assigned to inside a function.
+--
+
+local getinfo, error, rawset, rawget = debug.getinfo, error, rawset, rawget
+
+local mt = getmetatable(_G)
+if mt == nil then
+ mt = {}
+ setmetatable(_G, mt)
+end
+
+mt.__declared = {}
+
+local function what ()
+ local d = getinfo(3, "S")
+ return d and d.what or "C"
+end
+
+mt.__newindex = function (t, n, v)
+ if not mt.__declared[n] then
+ local w = what()
+ if w ~= "main" and w ~= "C" then
+ error("assign to undeclared variable '"..n.."'", 2)
+ end
+ mt.__declared[n] = true
+ end
+ rawset(t, n, v)
+end
+
+mt.__index = function (t, n)
+ if not mt.__declared[n] and what() ~= "C" then
+ error("variable '"..n.."' is not declared", 2)
+ end
+ return rawget(t, n)
+end
+
diff --git a/libraries/LuaJIT-1.1.7/jit/dis_x86.lua b/libraries/LuaJIT-1.1.7/jit/dis_x86.lua
new file mode 100644
index 0000000..b9ca150
--- /dev/null
+++ b/libraries/LuaJIT-1.1.7/jit/dis_x86.lua
@@ -0,0 +1,622 @@
+----------------------------------------------------------------------------
+-- LuaJIT x86 disassembler module.
+--
+-- Copyright (C) 2005-2011 Mike Pall. All rights reserved.
+-- Released under the MIT/X license. See luajit.h for full copyright notice.
+----------------------------------------------------------------------------
+-- This is a helper module used by the LuaJIT machine code dumper module.
+--
+-- Sending small code snippets to an external disassembler and mixing the
+-- output with our own stuff was too fragile. So I had to bite the bullet
+-- and write yet another x86 disassembler. Oh well ...
+--
+-- The output format is very similar to what ndisasm generates. But it has
+-- been developed independently by looking at the opcode tables from the
+-- Intel and AMD manuals. The supported instruction set is quite extensive
+-- and reflects what a current generation P4 or K8 implements in 32 bit
+-- mode. Yes, this includes MMX, SSE, SSE2, SSE3, SSSE3 and even privileged
+-- instructions.
+--
+-- Notes:
+-- * The (useless) a16 prefix, 3DNow and pre-586 opcodes are unsupported.
+-- * No attempt at optimization has been made -- it's fast enough for my needs.
+-- * The public API may change when more architectures are added.
+--
+-- TODO:
+-- * More testing with arbitrary x86 code (not just LuaJIT generated code).
+-- * The output for a few MMX/SSE opcodes could be improved.
+-- * Adding x64 support would be straightforward.
+-- * Better input API (iterator) and output API (structured access to instr).
+------------------------------------------------------------------------------
+
+local type = type
+local sub, byte, format = string.sub, string.byte, string.format
+local match, gmatch, gsub = string.match, string.gmatch, string.gsub
+
+-- Map for 1st opcode byte. Ugly? Well ... read on.
+local map_opc1 = {
+--0x
+[0]="addBmr","addVmr","addBrm","addVrm","addBai","addVai","push es","pop es",
+"orBmr","orVmr","orBrm","orVrm","orBai","orVai","push cs","opc2*",
+--1x
+"adcBmr","adcVmr","adcBrm","adcVrm","adcBai","adcVai","push ss","pop ss",
+"sbbBmr","sbbVmr","sbbBrm","sbbVrm","sbbBai","sbbVai","push ds","pop ds",
+--2x
+"andBmr","andVmr","andBrm","andVrm","andBai","andVai","es:seg","daa",
+"subBmr","subVmr","subBrm","subVrm","subBai","subVai","cs:seg","das",
+--3x
+"xorBmr","xorVmr","xorBrm","xorVrm","xorBai","xorVai","ss:seg","aaa",
+"cmpBmr","cmpVmr","cmpBrm","cmpVrm","cmpBai","cmpVai","ds:seg","aas",
+--4x
+"incVR","incVR","incVR","incVR","incVR","incVR","incVR","incVR",
+"decVR","decVR","decVR","decVR","decVR","decVR","decVR","decVR",
+--5x
+"pushVR","pushVR","pushVR","pushVR","pushVR","pushVR","pushVR","pushVR",
+"popVR","popVR","popVR","popVR","popVR","popVR","popVR","popVR",
+--6x
+"pusha/pushaw","popa/popaw","boundVrm","arplWmr",
+"fs:seg","gs:seg","o16:","a16",
+"pushVi","imulVrmi","pushBs","imulVrms",
+"insb","insd/insw","outsb","outsd/outsw",
+--7x
+"joBj","jnoBj","jbBj","jnbBj","jzBj","jnzBj","jbeBj","jaBj",
+"jsBj","jnsBj","jpeBj","jpoBj","jlBj","jgeBj","jleBj","jgBj",
+--8x
+"arith!Bmi","arith!Vmi","arith!Bmi","arith!Vms",
+"testBmr","testVmr","xchgBrm","xchgVrm",
+"movBmr","movVmr","movBrm","movVrm",
+"movVmg","leaVrm","movWgm","popVm",
+--9x
+"nop|pause|xchgWaR|repne nop","xchgVaR","xchgVaR","xchgVaR",
+"xchgVaR","xchgVaR","xchgVaR","xchgVaR",
+"cwde/cbw","cdq/cwd","call farViw","wait",
+"pushf/pushfw","popf/popfw","sahf","lahf",
+--Ax
+"movBao","movVao","movBoa","movVoa",
+"movsb","movsd/movsb","cmpsb","cmpsd/cmpsw",
+"testBai","testVai","stosb","stosd/stosw",
+"lodsb","lodsd/lodsw","scasb","scasd/scasw",
+--Bx
+"movBRi","movBRi","movBRi","movBRi","movBRi","movBRi","movBRi","movBRi",
+"movVRi","movVRi","movVRi","movVRi","movVRi","movVRi","movVRi","movVRi",
+--Cx
+"shift!Bmu","shift!Vmu","retBw","ret","lesVrm","ldsVrm","movBmi","movVmi",
+"enterBwu","leave","retfBw","retf","int3","intBu","into","iret/iretw",
+--Dx
+"shift!Bm1","shift!Vm1","shift!Bmc","shift!Vmc","aamBu","aadBu","salc","xlatb",
+"fp*0","fp*1","fp*2","fp*3","fp*4","fp*5","fp*6","fp*7",
+--Ex
+"loopneBj","loopeBj","loopBj","jecxz/jcxzBj","inBau","inVau","outBua","outVua",
+"callDj","jmpDj","jmp farViw","jmpBj","inBad","inVad","outBda","outVda",
+--Fx
+"lock:","int1","repne:rep","rep:","hlt","cmc","testb!Bm","testv!Vm",
+"clc","stc","cli","sti","cld","std","inc!Bm","inc!Vm",
+}
+assert(#map_opc1 == 255)
+
+-- Map for 2nd opcode byte (0f xx). True CISC hell. Hey, I told you.
+-- Prefix dependent MMX/SSE opcodes: (none)|rep|o16|repne
+local map_opc2 = {
+--0x
+[0]="sldt!Dmp","sgdt!Dmp","larVrm","lslVrm",nil,"syscall","clts","sysret",
+"invd","wbinvd",nil,"ud1",nil,"prefetch!Bm","femms","3dnowMrmu",
+--1x
+"movupsXrm|movssXrm|movupdXrm|movsdXrm",
+"movupsXmr|movssXmr|movupdXmr|movsdXmr",
+"movhlpsXrm|movsldupXrm|movlpdXrm|movddupXrm", -- TODO: movlpsXrMm (mem case).
+"movlpsXmr||movlpdXmr",
+"unpcklpsXrm||unpcklpdXrm",
+"unpckhpsXrm||unpckhpdXrm",
+"movlhpsXrm|movshdupXrm|movhpdXrm", -- TODO: movhpsXrMm (mem case).
+"movhpsXmr||movhpdXmr",
+"prefetcht!Bm","hintnopBm","hintnopBm","hintnopBm",
+"hintnopBm","hintnopBm","hintnopBm","hintnopBm",
+--2x
+"movDmx","movDmy","movDxm","movDym","movDmz",nil,"movDzm",nil,
+"movapsXrm||movapdXrm",
+"movapsXmr||movapdXmr",
+"cvtpi2psXrMm|cvtsi2ssXrDm|cvtpi2pdXrMm|cvtsi2sdXrDm",
+"movntpsXmr||movntpdXmr",
+"cvttps2piMrXm|cvttss2siDrXm|cvttpd2piMrXm|cvttsd2siDrXm",
+"cvtps2piMrXm|cvtss2siDrXm|cvtpd2piMrXm|cvtsd2siDrXm",
+"ucomissXrm||ucomisdXrm",
+"comissXrm||comisdXrm",
+--3x
+"wrmsr","rdtsc","rdmsr","rdpmc","sysenter","sysexit",nil,nil,
+"ssse3*38",nil,"ssse3*3a",nil,nil,nil,nil,nil,
+--4x
+"cmovoVrm","cmovnoVrm","cmovbVrm","cmovnbVrm",
+"cmovzVrm","cmovnzVrm","cmovbeVrm","cmovaVrm",
+"cmovsVrm","cmovnsVrm","cmovpeVrm","cmovpoVrm",
+"cmovlVrm","cmovgeVrm","cmovleVrm","cmovgVrm",
+--5x
+"movmskpsDrXm||movmskpdDrXm","sqrtpsXrm|sqrtssXrm|sqrtpdXrm|sqrtsdXrm",
+"rsqrtpsXrm|rsqrtssXrm","rcppsXrm|rcpssXrm",
+"andpsXrm||andpdXrm","andnpsXrm||andnpdXrm",
+"orpsXrm||orpdXrm","xorpsXrm||xorpdXrm",
+"addpsXrm|addssXrm|addpdXrm|addsdXrm","mulpsXrm|mulssXrm|mulpdXrm|mulsdXrm",
+"cvtps2pdXrm|cvtss2sdXrm|cvtpd2psXrm|cvtsd2ssXrm",
+"cvtdq2psXrm|cvttps2dqXrm|cvtps2dqXrm",
+"subpsXrm|subssXrm|subpdXrm|subsdXrm","minpsXrm|minssXrm|minpdXrm|minsdXrm",
+"divpsXrm|divssXrm|divpdXrm|divsdXrm","maxpsXrm|maxssXrm|maxpdXrm|maxsdXrm",
+--6x
+"punpcklbwMrm||punpcklbqXrm","punpcklwdPrm","punpckldqPrm","packsswbPrm",
+"pcmpgtbPrm","pcmpgtwPrm","pcmpgtdPrm","packuswbPrm",
+"punpckhbwPrm","punpckhwdPrm","punpckhdqPrm","packssdwPrm",
+"||punpcklqdqXrm","||punpckhqdqXrm",
+"movdPrDm","movqMrm|movdquXrm|movdqaXrm",
+--7x
+"pshufwPrmu","pshiftw!Pmu","pshiftd!Pmu","pshiftq!Mmu||pshiftdq!Xmu",
+"pcmpeqbPrm","pcmpeqwPrm","pcmpeqdPrm","emms|",
+nil,nil,nil,nil,
+"||haddpdXrm|haddpsXrm","||hsubpdXrm|hsubpsXrm",
+"movdDmMr|movqXrm|movdDmXr","movqMmr|movdquXmr|movdqaXmr",
+--8x
+"joVj","jnoVj","jbVj","jnbVj","jzVj","jnzVj","jbeVj","jaVj",
+"jsVj","jnsVj","jpeVj","jpoVj","jlVj","jgeVj","jleVj","jgVj",
+--9x
+"setoBm","setnoBm","setbBm","setnbBm","setzBm","setnzBm","setbeBm","setaBm",
+"setsBm","setnsBm","setpeBm","setpoBm","setlBm","setgeBm","setleBm","setgBm",
+--Ax
+"push fs","pop fs","cpuid","btVmr","shldVmru","shldVmrc",nil,nil,
+"push gs","pop gs","rsm","btsVmr","shrdVmru","shrdVmrc","fxsave!Dmp","imulVrm",
+--Bx
+"cmpxchgBmr","cmpxchgVmr","lssVrm","btrVmr",
+"lfsVrm","lgsVrm","movzxVrBm","movzxDrWm",
+nil,"ud2","bt!Vmu","btcVmr",
+"bsfVrm","bsrVrm","movsxVrBm","movsxDrWm",
+--Cx
+"xaddBmr","xaddVmr",
+"cmppsXrmu|cmpssXrmu|cmppdXrmu|cmpsdXrmu","movntiDmr|",
+"pinsrwPrWmu","pextrwDrPmu",
+"shufpsXrmu||shufpdXrmu","cmpxchg!Dmp",
+"bswapDR","bswapDR","bswapDR","bswapDR","bswapDR","bswapDR","bswapDR","bswapDR",
+--Dx
+"||addsubpdXrm|addsubpsXrm","psrlwPrm","psrldPrm","psrlqPrm",
+"paddqPrm","pmullwPrm",
+"|movq2dqXrMm|movqXmr|movdq2qMrXm","pmovmskbDrPm",
+"psubusbPrm","psubuswPrm","pminubPrm","pandPrm",
+"paddusbPrm","padduswPrm","pmaxubPrm","pandnPrm",
+--Ex
+"pavgbPrm","psrawPrm","psradPrm","pavgwPrm",
+"pmulhuwPrm","pmulhwPrm",
+"|cvtdq2pdXrm|cvttpd2dqXrm|cvtpd2dqXrm","movntqMmr||movntdqXmr",
+"psubsbPrm","psubswPrm","pminswPrm","porPrm",
+"paddsbPrm","paddswPrm","pmaxswPrm","pxorPrm",
+--Fx
+"|||lddquXrm","psllwPrm","pslldPrm","psllqPrm",
+"pmuludqPrm","pmaddwdPrm","psadbwPrm","maskmovqMrm||maskmovdquXrm",
+"psubbPrm","psubwPrm","psubdPrm","psubqPrm",
+"paddbPrm","paddwPrm","padddPrm","ud",
+}
+assert(map_opc2[255] == "ud")
+
+-- Map for SSSE3 opcodes.
+local map_ssse3 = {
+["38"] = { -- [66] 0f 38 xx
+--0x
+[0]="pshufbPrm","phaddwPrm","phadddPrm","phaddswPrm",
+"pmaddubswPrm","phsubwPrm","phsubdPrm","phsubswPrm",
+"psignbPrm","psignwPrm","psigndPrm","pmulhrswPrm",
+nil,nil,nil,nil,
+--1x
+nil,nil,nil,nil,nil,nil,nil,nil,
+nil,nil,nil,nil,"pabsbPrm","pabswPrm","pabsdPrm",nil,
+},
+["3a"] = { -- [66] 0f 3a xx
+[0x0f] = "palignrPrmu",
+},
+}
+
+-- Map for FP opcodes. And you thought stack machines are simple?
+local map_opcfp = {
+-- D8-DF 00-BF: opcodes with a memory operand.
+-- D8
+[0]="faddFm","fmulFm","fcomFm","fcompFm","fsubFm","fsubrFm","fdivFm","fdivrFm",
+"fldFm",nil,"fstFm","fstpFm","fldenvDmp","fldcwWm","fnstenvDmp","fnstcwWm",
+-- DA
+"fiaddDm","fimulDm","ficomDm","ficompDm",
+"fisubDm","fisubrDm","fidivDm","fidivrDm",
+-- DB
+"fildDm","fisttpDm","fistDm","fistpDm",nil,"fld twordFmp",nil,"fstp twordFmp",
+-- DC
+"faddGm","fmulGm","fcomGm","fcompGm","fsubGm","fsubrGm","fdivGm","fdivrGm",
+-- DD
+"fldGm","fisttpQm","fstGm","fstpGm","frstorDmp",nil,"fnsaveDmp","fnstswWm",
+-- DE
+"fiaddWm","fimulWm","ficomWm","ficompWm",
+"fisubWm","fisubrWm","fidivWm","fidivrWm",
+-- DF
+"fildWm","fisttpWm","fistWm","fistpWm",
+"fbld twordFmp","fildQm","fbstp twordFmp","fistpQm",
+-- xx C0-FF: opcodes with a pseudo-register operand.
+-- D8
+"faddFf","fmulFf","fcomFf","fcompFf","fsubFf","fsubrFf","fdivFf","fdivrFf",
+-- D9
+"fldFf","fxchFf",{"fnop"},nil,
+{"fchs","fabs",nil,nil,"ftst","fxam"},
+{"fld1","fldl2t","fldl2e","fldpi","fldlg2","fldln2","fldz"},
+{"f2xm1","fyl2x","fptan","fpatan","fxtract","fprem1","fdecstp","fincstp"},
+{"fprem","fyl2xp1","fsqrt","fsincos","frndint","fscale","fsin","fcos"},
+-- DA
+"fcmovbFf","fcmoveFf","fcmovbeFf","fcmovuFf",nil,{nil,"fucompp"},nil,nil,
+-- DB
+"fcmovnbFf","fcmovneFf","fcmovnbeFf","fcmovnuFf",
+{nil,nil,"fnclex","fninit"},"fucomiFf","fcomiFf",nil,
+-- DC
+"fadd toFf","fmul toFf",nil,nil,
+"fsub toFf","fsubr toFf","fdivr toFf","fdiv toFf",
+-- DD
+"ffreeFf",nil,"fstFf","fstpFf","fucomFf","fucompFf",nil,nil,
+-- DE
+"faddpFf","fmulpFf",nil,{nil,"fcompp"},
+"fsubrpFf","fsubpFf","fdivrpFf","fdivpFf",
+-- DF
+nil,nil,nil,nil,{"fnstsw ax"},"fucomipFf","fcomipFf",nil,
+}
+assert(map_opcfp[126] == "fcomipFf")
+
+-- Map for opcode groups. The subkey is sp from the ModRM byte.
+local map_opcgroup = {
+ arith = { "add", "or", "adc", "sbb", "and", "sub", "xor", "cmp" },
+ shift = { "rol", "ror", "rcl", "rcr", "shl", "shr", "sal", "sar" },
+ testb = { "testBmi", "testBmi", "not", "neg", "mul", "imul", "div", "idiv" },
+ testv = { "testVmi", "testVmi", "not", "neg", "mul", "imul", "div", "idiv" },
+ inc = { "inc", "dec", "callDmp", "call farDmp",
+ "jmpDmp", "jmp farDmp", "push" },
+ sldt = { "sldt", "str", "lldt", "ltr", "verr", "verw" },
+ sgdt = { "sgdt", "sidt", "lgdt", "lidt", "smsw", nil, "lmsw", "invlpg" },
+ bt = { nil, nil, nil, nil, "bt", "bts", "btr", "btc" },
+ cmpxchg = { nil, "cmpxchg8b" },
+ pshiftw = { nil, nil, "psrlw", nil, "psraw", nil, "psllw" },
+ pshiftd = { nil, nil, "psrld", nil, "psrad", nil, "pslld" },
+ pshiftq = { nil, nil, "psrlq", nil, nil, nil, "psllq" },
+ pshiftdq = { nil, nil, "psrlq", "psrldq", nil, nil, "psllq", "pslldq" },
+ fxsave = { "fxsave", "fxrstor", "ldmxcsr", "stmxcsr",
+ nil, "lfenceDp", "mfenceDp", "sfenceDp" }, -- TODO: clflush.
+ prefetch = { "prefetch", "prefetchw" },
+ prefetcht = { "prefetchnta", "prefetcht0", "prefetcht1", "prefetcht2" },
+}
+
+------------------------------------------------------------------------------
+
+-- Maps for register names.
+local map_aregs = { "eax", "ecx", "edx", "ebx", "esp", "ebp", "esi", "edi" }
+local map_regs = {
+ B = { "al", "cl", "dl", "bl", "ah", "ch", "dh", "bh" },
+ W = { "ax", "cx", "dx", "bx", "sp", "bp", "si", "di" },
+ D = map_aregs,
+ M = { "mm0", "mm1", "mm2", "mm3", "mm4", "mm5", "mm6", "mm7" },
+ X = { "xmm0", "xmm1", "xmm2", "xmm3", "xmm4", "xmm5", "xmm6", "xmm7" },
+}
+local map_segregs = { "es", "cs", "ss", "ds", "fs", "gs", "segr6", "segr7" }
+
+-- Maps for size names.
+local map_sz2n = {
+ B = 1, W = 2, D = 4, Q = 8, M = 8, X = 16,
+}
+local map_sz2prefix = {
+ B = "byte", W = "word", D = "dword",
+ Q = "qword", -- No associated reg in 32 bit mode.
+ F = "dword", G = "qword", -- No need for sizes/register names for these two.
+ M = "qword", X = "xword",
+}
+
+------------------------------------------------------------------------------
+
+-- Output a nicely formatted line with an opcode and operands.
+local function putop(ctx, text, operands)
+ local code, pos, hex = ctx.code, ctx.pos, ""
+ for i=ctx.start,pos-1 do
+ hex = hex..format("%02X", byte(code, i, i))
+ end
+ if #hex > 16 then hex = sub(hex, 1, 16).."." end
+ if operands then text = text.." "..operands end
+ if ctx.o16 then text = "o16 "..text; ctx.o16 = false end
+ if ctx.rep then text = ctx.rep.." "..text; ctx.rep = false end
+ if ctx.seg then
+ local text2, n = gsub(text, "%[", "["..ctx.seg..":")
+ if n == 0 then text = ctx.seg.." "..text else text = text2 end
+ ctx.seg = false
+ end
+ if ctx.lock then text = "lock "..text; ctx.lock = false end
+ local imm = ctx.imm
+ if imm then
+ local sym = ctx.symtab[imm]
+ if sym then text = text.."\t->"..sym end
+ end
+ ctx.out(format("%08x %-18s%s\n", ctx.addr+ctx.start, hex, text))
+ ctx.mrm = false
+ ctx.start = pos
+ ctx.imm = nil
+end
+
+-- Fallback for incomplete opcodes at the end.
+local function incomplete(ctx)
+ ctx.pos = ctx.stop+1
+ ctx.o16 = false; ctx.seg = false; ctx.lock = false; ctx.rep = false
+ return putop(ctx, "(incomplete)")
+end
+
+-- Fallback for unknown opcodes.
+local function unknown(ctx)
+ ctx.o16 = false; ctx.seg = false; ctx.lock = false; ctx.rep = false
+ return putop(ctx, "(unknown)")
+end
+
+-- Return an immediate of the specified size.
+local function getimm(ctx, pos, n)
+ if pos+n-1 > ctx.stop then return incomplete(ctx) end
+ local code = ctx.code
+ if n == 1 then
+ local b1 = byte(code, pos, pos)
+ return b1
+ elseif n == 2 then
+ local b1, b2 = byte(code, pos, pos+1)
+ return b1+b2*256
+ else
+ local b1, b2, b3, b4 = byte(code, pos, pos+3)
+ local imm = b1+b2*256+b3*65536+b4*16777216
+ ctx.imm = imm
+ return imm
+ end
+end
+
+-- Process pattern string and generate the operands.
+local function putpat(ctx, name, pat)
+ local operands, regs, sz, mode, sp, rm, sc, rx, disp, sdisp
+ local code, pos, stop = ctx.code, ctx.pos, ctx.stop
+
+ -- Chars used: 1DFGMPQRVWXacdfgijmoprsuwxyz
+ for p in gmatch(pat, ".") do
+ local x = nil
+ if p == "V" then
+ sz = ctx.o16 and "W" or "D"; ctx.o16 = false
+ regs = map_regs[sz]
+ elseif match(p, "[BWDQFGMX]") then
+ sz = p
+ regs = map_regs[sz]
+ elseif p == "P" then
+ sz = ctx.o16 and "X" or "M"; ctx.o16 = false
+ regs = map_regs[sz]
+ elseif p == "s" then
+ local imm = getimm(ctx, pos, 1); if not imm then return end
+ x = imm <= 127 and format("byte +0x%02x", imm)
+ or format("byte -0x%02x", 256-imm)
+ pos = pos+1
+ elseif p == "u" then
+ local imm = getimm(ctx, pos, 1); if not imm then return end
+ x = format("0x%02x", imm)
+ pos = pos+1
+ elseif p == "w" then
+ local imm = getimm(ctx, pos, 2); if not imm then return end
+ x = format("0x%x", imm)
+ pos = pos+2
+ elseif p == "o" then -- [offset]
+ local imm = getimm(ctx, pos, 4); if not imm then return end
+ x = format("[0x%08x]", imm)
+ pos = pos+4
+ elseif p == "i" then
+ local n = map_sz2n[sz]
+ local imm = getimm(ctx, pos, n); if not imm then return end
+ x = format(imm > 65535 and "0x%08x" or "0x%x", imm)
+ pos = pos+n
+ elseif p == "j" then
+ local n = map_sz2n[sz]
+ local imm = getimm(ctx, pos, n); if not imm then return end
+ if sz == "B" and imm > 127 then imm = imm-256
+ elseif imm > 2147483647 then imm = imm-4294967296 end
+ pos = pos+n
+ imm = imm + pos + ctx.addr
+ ctx.imm = imm
+ x = sz == "W" and format("word 0x%04x", imm%65536)
+ or format("0x%08x", imm)
+ elseif p == "R" then x = regs[byte(code, pos-1, pos-1)%8+1]
+ elseif p == "a" then x = regs[1]
+ elseif p == "c" then x = "cl"
+ elseif p == "d" then x = "dx"
+ elseif p == "1" then x = "1"
+ else
+ if not mode then
+ mode = ctx.mrm
+ if not mode then
+ if pos > stop then return incomplete(ctx) end
+ mode = byte(code, pos, pos)
+ pos = pos+1
+ end
+ rm = mode%8; mode = (mode-rm)/8
+ sp = mode%8; mode = (mode-sp)/8
+ sdisp = ""
+ if mode < 3 then
+ if rm == 4 then
+ if pos > stop then return incomplete(ctx) end
+ sc = byte(code, pos, pos)
+ pos = pos+1
+ rm = sc%8; sc = (sc-rm)/8
+ rx = sc%8; sc = (sc-rx)/8
+ if rx == 4 then rx = nil end
+ end
+ if mode > 0 or rm == 5 then
+ local dsz = mode
+ if dsz ~= 1 then dsz = 4 end
+ disp = getimm(ctx, pos, dsz); if not disp then return end
+ sdisp = (dsz == 4 or disp <= 127) and
+ format(disp > 65535 and "+0x%08x" or "+0x%x", disp) or
+ format("-0x%x", 256-disp)
+ pos = pos+dsz
+ end
+ end
+ end
+ if p == "m" then
+ if mode == 3 then x = regs[rm+1]
+ else
+ local srm, srx = map_aregs[rm+1], ""
+ if rx then
+ srm = srm.."+"
+ srx = map_aregs[rx+1]
+ if sc > 0 then srx = srx.."*"..(2^sc) end
+ end
+ if mode == 0 and rm == 5 then
+ srm = ""
+ sdisp = format("%s0x%08x", rx and "+" or "", disp)
+ end
+ x = format("[%s%s%s]", srm, srx, sdisp)
+ end
+ if mode < 3 and
+ (not match(pat, "[aRrgp]") or
+ name == "movzx" or name == "movsx") then -- Yuck.
+ x = map_sz2prefix[sz].." "..x
+ end
+ elseif p == "r" then x = regs[sp+1]
+ elseif p == "g" then x = map_segregs[sp+1]
+ elseif p == "p" then -- Suppress prefix.
+ elseif p == "f" then x = "st"..rm
+ elseif p == "x" then x = "CR"..sp
+ elseif p == "y" then x = "DR"..sp
+ elseif p == "z" then x = "TR"..sp
+ else
+ error("bad pattern `"..pat.."'")
+ end
+ end
+ if x then operands = operands and operands..","..x or x end
+ end
+ ctx.pos = pos
+ return putop(ctx, name, operands)
+end
+
+-- Forward declaration.
+local map_act
+
+-- Get a pattern from an opcode map and dispatch to handler.
+local function opcdispatch(ctx, opcmap)
+ local pos = ctx.pos
+ local opat = opcmap[byte(ctx.code, pos, pos)]
+ if not opat then return unknown(ctx) end
+ if match(opat, "%|") then -- MMX/SSE variants depending on prefix.
+ local p
+ if ctx.rep then p = ctx.rep=="rep" and "%|([^%|]*)" or "%|.-%|.-%|([^%|]*)"
+ elseif ctx.o16 then p = "%|.-%|([^%|]*)"
+ else p = "^[^%|]*" end
+ opat = match(opat, p)
+ if not opat or opat == "" then return unknown(ctx) end
+ ctx.rep = false; ctx.o16 = false
+ end
+ local name, pat, act = match(opat, "^([a-z0-9 ]*)((.?).*)")
+ ctx.pos = pos + 1
+ return map_act[act](ctx, name, pat)
+end
+
+-- Map for action codes. The key is the first char after the name.
+map_act = {
+ -- Simple opcodes without operands.
+ [""] = function(ctx, name, pat)
+ return putop(ctx, name)
+ end,
+
+ -- Operand size chars fall right through.
+ B = putpat, W = putpat, D = putpat, V = putpat,
+ F = putpat, G = putpat,
+ M = putpat, X = putpat, P = putpat,
+
+ -- Collect prefixes.
+ [":"] = function(ctx, name, pat)
+ ctx[pat == ":" and name or sub(pat, 2)] = name
+ end,
+
+ -- Select alternate opcode name when prefixed with o16.
+ ["/"] = function(ctx, name, pat)
+ local wname, rpat = match(pat, "^/([a-z0-9 ]+)(.*)")
+ if ctx.o16 then name = wname; ctx.o16 = false end
+ return putpat(ctx, name, rpat)
+ end,
+
+ -- Chain to special handler specified by name.
+ ["*"] = function(ctx, name, pat)
+ return map_act[name](ctx, name, sub(pat, 2))
+ end,
+
+ -- Use named subtable for opcode group.
+ ["!"] = function(ctx, name, pat)
+
+ local pos = ctx.pos
+ if pos > ctx.stop then return incomplete(ctx) end
+ local mrm = byte(ctx.code, pos, pos)
+ ctx.pos = pos+1
+ ctx.mrm = mrm
+
+ local opat = map_opcgroup[name][((mrm-(mrm%8))/8)%8+1]
+ if not opat then return unknown(ctx) end
+ local name, pat2 = match(opat, "^([a-z0-9 ]*)(.*)")
+ return putpat(ctx, name, pat2 ~= "" and pat2 or sub(pat, 2))
+ end,
+
+ -- Two-byte opcode dispatch.
+ opc2 = function(ctx, name, pat)
+ return opcdispatch(ctx, map_opc2)
+ end,
+
+ -- SSSE3 dispatch.
+ ssse3 = function(ctx, name, pat)
+ return opcdispatch(ctx, map_ssse3[pat])
+ end,
+
+ -- Floating point opcode dispatch.
+ fp = function(ctx, name, pat)
+
+ local pos = ctx.pos
+ if pos > ctx.stop then return incomplete(ctx) end
+ local mrm = byte(ctx.code, pos, pos)
+ ctx.pos = pos+1
+ ctx.mrm = mrm
+
+ local rm = mrm%8
+ local idx = pat*8 + ((mrm-rm)/8)%8
+ if mrm >= 192 then idx = idx + 64 end
+ local opat = map_opcfp[idx]
+ if type(opat) == "table" then opat = opat[rm+1] end
+ if not opat then return unknown(ctx) end
+ local name, pat2 = match(opat, "^([a-z0-9 ]*)(.*)")
+ return putpat(ctx, name, pat2)
+ end,
+}
+
+------------------------------------------------------------------------------
+
+-- Disassemble a block of code.
+local function disass_block(ctx, ofs, len)
+ if not ofs then ofs = 0 end
+ local stop = len and ofs+len or #ctx.code
+ ofs = ofs + 1
+ ctx.start = ofs
+ ctx.pos = ofs
+ ctx.stop = stop
+ ctx.imm = nil
+ ctx.mrm = false
+ ctx.o16 = false; ctx.seg = false; ctx.lock = false; ctx.rep = false
+ while ctx.pos <= stop do opcdispatch(ctx, map_opc1) end
+ if ctx.pos ~= ctx.start then incomplete(ctx) end
+end
+
+-- Extended API: create a disassembler context. Then call ctx:disass(ofs, len).
+local function create_(code, addr, out)
+ local ctx = {}
+ ctx.code = code
+ ctx.addr = (addr or 0) - 1
+ ctx.out = out or io.write
+ ctx.symtab = {}
+ ctx.disass = disass_block
+ return ctx
+end
+
+-- Simple API: disassemble code (a string) at address and output via out.
+local function disass_(code, addr, out)
+ create_(code, addr, out):disass()
+end
+
+
+-- Public module functions.
+module(...)
+
+create = create_
+disass = disass_
+
diff --git a/libraries/LuaJIT-1.1.7/jit/dump.lua b/libraries/LuaJIT-1.1.7/jit/dump.lua
new file mode 100644
index 0000000..2287c23
--- /dev/null
+++ b/libraries/LuaJIT-1.1.7/jit/dump.lua
@@ -0,0 +1,265 @@
+----------------------------------------------------------------------------
+-- LuaJIT machine code dumper module.
+--
+-- Copyright (C) 2005-2011 Mike Pall. All rights reserved.
+-- Released under the MIT/X license. See luajit.h for full copyright notice.
+----------------------------------------------------------------------------
+-- Activate this module to dump the machine code for all functions
+-- immediately after they have been compiled. The disassembler
+-- output is mixed with the bytecode listing.
+--
+-- Try: luajit -j dump -e 'print "foo"'
+-- luajit -j dump=foo.dump foo.lua
+-- luajit -j off -j dump -e 'jit.compile(assert(loadfile"foo.lua")))'
+--
+-- Default output is to stderr. To redirect output to a file,
+-- pass a filename as an argument or set the environment variable
+-- "LUAJIT_DUMPFILE".
+-- Note: The file is overwritten each time you run luajit.
+--
+-- TODO: Find a way to be more selective on what to dump.
+------------------------------------------------------------------------------
+
+-- Priority for compiler pipeline. Must run after backend (negative)
+-- and should be even because we only catch successful compiles.
+local PRIORITY = -98
+
+-- Cache some library functions and objects.
+local jit = require("jit")
+assert(jit.version_num == 10107, "LuaJIT core/library version mismatch")
+local jutil = require("jit.util")
+local type, format, gsub = type, string.format, string.gsub
+local bytecode, const = jutil.bytecode, jutil.const
+local getinfo = debug.getinfo
+local stdout, stderr = io.stdout, io.stderr
+
+-- Load the right disassembler.
+local dis = require("jit.dis_"..jit.arch)
+local discreate, disass_ = dis.create, dis.disass
+
+-- Turn compilation off for the whole module. LuaJIT would do that anyway.
+jit.off(true, true)
+
+-- Separator line.
+local sepline = "-------------------------------"
+
+-- Map JSUB indices to names.
+-- CHECK: must match the order in ljit_x86.h. Regenerate with:
+-- grep '^ *JSUB_[^_].*,' ljit_x86.h | sed -e 's/^ *JSUB_/ "/' -e 's/,.*/",/'
+local jsubnames = {
+ "STACKPTR",
+ "GATE_LJ",
+ "GATE_JL",
+ "GATE_JC",
+ "GROW_STACK",
+ "GROW_CI",
+ "GATE_JC_PATCH",
+ "GATE_JC_DEBUG",
+ "DEOPTIMIZE_CALLER",
+ "DEOPTIMIZE",
+ "DEOPTIMIZE_OPEN",
+ "HOOKINS",
+ "GCSTEP",
+ "STRING_SUB3",
+ "STRING_SUB2",
+ "HOOKCALL",
+ "HOOKRET",
+ "METACALL",
+ "METATAILCALL",
+ "BARRIERF",
+ "GETGLOBAL",
+ "GETTABLE_KSTR",
+ "GETTABLE_STR",
+ "BARRIERBACK",
+ "SETGLOBAL",
+ "SETTABLE_KSTR",
+ "SETTABLE_STR",
+ "GETTABLE_KNUM",
+ "GETTABLE_NUM",
+ "SETTABLE_KNUM",
+ "SETTABLE_NUM",
+ "LOG2_TWORD",
+ "CONCAT_STR2",
+}
+
+-- Generate map from JSUB addresses to JSUB names.
+local jsubmap = {}
+do
+ local jsubmcode = jutil.jsubmcode
+ for pc=0,100000 do
+ local addr = jsubmcode(pc)
+ if not addr then break end
+ jsubmap[addr] = jsubnames[pc+1] or "JSUB#"..pc
+ end
+end
+
+-- Pretty-print a constant.
+local function conststr(func, idx)
+ local k = const(func, idx)
+ if k == nil then return "nil"
+ elseif k == true then return "true"
+ elseif k == false then return "false"
+ elseif type(k) == "string" then
+ if #k > 10 then return format('"%.10s"~', k)
+ else return '"'..k..'"' end
+ else return k.."" end
+end
+
+-- Pretty-print a bytecode instruction (one or two lines).
+local function bytecodeout(out, func, pc)
+ local op, a, b, c = bytecode(func, pc)
+ if not op then
+ return true
+ elseif op == "JMP" then
+ out:write(format("\n--%04d-- JMP => %04d", pc, pc+1+b))
+ elseif op == "FORLOOP" or op == "FORPREP" then
+ out:write(format("\n--%04d-- %-9s %3d => %04d", pc, op, a, pc+1+b))
+ else
+ out:write(format("\n--%04d-- %-9s %3d %4s %4s",
+ pc, op, a, b or "", c or ""))
+ if b and b < 0 then out:write(" ; ", conststr(func, b)) end
+ if c and c < 0 then out:write(" ; ", conststr(func, c)) end
+ end
+end
+
+-- Dump machine code and mix it with the bytecode listing.
+local function dumpfunc(func, out, deopt)
+ if not out then out = stderr end
+ local info = getinfo(func, "S")
+
+ -- Don't bother checking for the right blocks to dump.
+ -- Dump the main block (if not deopt) and always all deopt blocks.
+ for block=deopt and 2 or 1,1000000 do
+ local addr, code, mfmiter = jutil.mcode(func, block)
+ if not addr then
+ if code then return code end -- Not compiled: return status.
+ break -- No more blocks to dump.
+ end
+
+ -- Print header.
+ out:write(sepline, " ", info.source, ":", info.linedefined)
+ if block ~= 1 then out:write(" DEOPT block ", block) end
+
+ -- Create disassembler context.
+ local ctx = discreate(code, addr, function(s) out:write(s) end)
+ ctx.symtab = jsubmap
+
+ -- Dump an mcode block.
+ local pc, ofs = 1, 0
+ local len, isdeopt = mfmiter()
+ if isdeopt then pc = len; len = 0
+ elseif block ~= 1 then break end -- Stop before next main block.
+ for t, m in mfmiter do
+ if t == "COMBINE" then
+ bytecodeout(out, func, pc)
+ else
+ if len ~= 0 then
+ out:write("\n")
+ if len > 0 then
+ ctx:disass(ofs, len)
+ ofs = ofs + len
+ else
+ out:write(format("%08x ** deoptimized\n", addr+ofs))
+ ofs = ofs - len
+ end
+ len = 0
+ end
+ if type(t) == "number" then
+ if m then
+ if isdeopt then
+ pc = t - 1
+ else
+ bytecodeout(out, func, pc)
+ len = -t
+ end
+ else
+ len = t
+ if bytecodeout(out, func, pc) then break end
+ end
+ end
+ end
+ pc = pc + 1
+ end
+ if len and len ~= 0 then
+ out:write(sepline, " tail code\n")
+ ctx:disass(ofs, len)
+ end
+ end
+
+ -- Print footer.
+ out:write(sepline, "\n")
+ out:flush()
+end
+
+-- Dump the internal JIT subroutines.
+local function dumpjsub_(out)
+ if not out then out = stderr end
+ local addr, code = jutil.jsubmcode()
+
+ -- Create disassembler context.
+ local ctx = discreate(code, addr, function(s) out:write(s) end)
+ ctx.symtab = jsubmap
+
+ -- Collect addresses and sort them.
+ local t = {}
+ for addr in pairs(jsubmap) do t[#t+1] = addr end
+ t[#t+1] = addr + #code
+ table.sort(t)
+
+ -- Go through the addresses in ascending order.
+ local ofs = addr
+ for i=2,#t do
+ local next = t[i]
+ out:write("\n->", jsubmap[ofs], ":\n") -- Output label for JSUB.
+ ctx:disass(ofs-addr, next-ofs) -- Disassemble corresponding code block.
+ ofs = next
+ end
+ out:flush()
+end
+
+
+-- Active flag and output file handle.
+local active, out
+
+-- Dump handler for compiler pipeline.
+local function h_dump(st)
+ local ok, err = pcall(dumpfunc, st.func, out, st.deopt)
+ if not ok then
+ stderr:write("\nERROR: jit.dump disabled: ", err, "\n")
+ jit.attach(h_dump) -- Better turn ourselves off after a failure.
+ if out and out ~= stdout then out:close() end
+ out = nil
+ active = nil
+ end
+end
+
+-- Detach dump handler from compiler pipeline.
+local function dumpoff()
+ if active then
+ active = false
+ jit.attach(h_dump)
+ if out and out ~= stdout then out:close() end
+ out = nil
+ end
+end
+
+-- Open the output file and attach dump handler to compiler pipeline.
+local function dumpon(filename)
+ if active then dumpoff() end
+ local outfile = filename or os.getenv("LUAJIT_DUMPFILE")
+ out = outfile and (outfile == "-" and stdout or assert(io.open(outfile, "w")))
+ jit.attach(h_dump, PRIORITY)
+ active = true
+end
+
+
+-- Public module functions.
+module(...)
+
+disass = disass_
+dump = dumpfunc
+dumpjsub = dumpjsub_
+on = dumpon
+off = dumpoff
+start = dumpon -- For -j command line option.
+
diff --git a/libraries/LuaJIT-1.1.7/jit/dumphints.lua b/libraries/LuaJIT-1.1.7/jit/dumphints.lua
new file mode 100644
index 0000000..4a64676
--- /dev/null
+++ b/libraries/LuaJIT-1.1.7/jit/dumphints.lua
@@ -0,0 +1,239 @@
+----------------------------------------------------------------------------
+-- LuaJIT hints dumper module.
+--
+-- Copyright (C) 2005-2011 Mike Pall. All rights reserved.
+-- Released under the MIT/X license. See luajit.h for full copyright notice.
+----------------------------------------------------------------------------
+-- Activate this module to dump the bytecode and the hints from
+-- the optimizer for all functions to be compiled.
+--
+-- Try: luajit -O -j dumphints -e 'return 1'
+--
+-- Default output is to stderr. To redirect output to a file,
+-- pass a filename as an argument or set the environment variable
+-- "LUAJIT_DUMPHINTSFILE".
+-- Note: The file is overwritten each time you run luajit.
+--
+-- TODO: Find a way to be more selective on what to dump.
+------------------------------------------------------------------------------
+
+-- Priority for compiler pipeline. Should run before backend (positive)
+-- and should be even because we only catch successful compiles.
+local PRIORITY = 10
+
+-- Cache some library functions and objects.
+local jit = require("jit")
+assert(jit.version_num == 10107, "LuaJIT core/library version mismatch")
+local jutil = require("jit.util")
+local type, pairs, format = type, pairs, string.format
+local bytecode, const = jutil.bytecode, jutil.const
+local hints, fhints = jutil.hints, jutil.fhints
+local stdout, stderr = io.stdout, io.stderr
+
+-- Turn compilation off for the whole module. LuaJIT would do that anyway.
+jit.off(true, true)
+
+-- Separator line.
+local sepline = "-------------------------------"
+
+
+-- Pretty-print a constant.
+local function conststr(func, idx)
+ local k = const(func, idx)
+ if k == nil then return "nil"
+ elseif k == true then return "true"
+ elseif k == false then return "false"
+ elseif type(k) == "string" then
+ if #k > 10 then return format('"%.10s"~', k)
+ else return '"'..k..'"' end
+ else return k.."" end
+end
+
+-- Pretty-print a bytecode instruction.
+local function bytecodeline(func, pc, flag)
+ local op, a, b, c = bytecode(func, pc)
+ if not op then return end
+ if op == "JMP" then
+ return format("\n%04d %s JMP => %04d", pc, flag, pc+1+b)
+ end
+ if op == "FORLOOP" or op == "FORPREP" then
+ return format("\n%04d %s %-9s %3d => %04d", pc, flag, op, a, pc+1+b)
+ end
+ local s = format("\n%04d %s %-9s %3d %4s %4s",
+ pc, flag, op, a, b or "", c or "")
+ if b and b < 0 then s = s.." ; "..conststr(func, b) end
+ if c and c < 0 then s = s.." ; "..conststr(func, c) end
+ return s
+end
+
+-- Precompute inverse hints table.
+local invhints = {}
+for k,v in pairs(hints) do invhints[v] = k end
+
+-- The inverse resolver for inline functions is loaded on demand.
+local getname
+
+-- Helper functions to pretty-print hints.
+local function typehint(h, v, st, pc)
+ if st[pc+hints.INLINE] then return "" end
+ local tp = type(v)
+ if tp == "function" then
+ tp = debug.getinfo(v, "S").what
+ elseif tp == "number" and v % 1 == 0 then
+ tp = "integer"
+ elseif v == false then
+ tp = "mixed"
+ end
+ return " #"..h.."("..tp..")"
+end
+
+local hintprint = {
+ COMBINE = function(h, v, st, pc)
+ if v == false then return "" end -- Dead instructions are already marked.
+ end,
+ TYPE = typehint,
+ TYPEKEY = typehint,
+ INLINE = function(h, v, st, pc)
+ if not getname then getname = require("jit.opt_inline").getname end
+ return " #INLINE("..getname(st[pc+hints.TYPE], v)..")"
+ end,
+}
+
+-- Generate range string from table: pc[-pc] [,...]
+local function rangestring(t)
+ local s = ""
+ for i,range in ipairs(t) do
+ if i ~= 1 then s = s.."," end
+ local pc = range % 65536
+ range = (range - pc) / 65536
+ s = s..pc
+ if range ~= 0 then s = s..(-(pc+range)) end
+ end
+ return s
+end
+
+-- Dump instructions and hints for a (to be compiled) function.
+local function dumphints(st, out)
+ if not out then out = stderr end
+ local func = st.func
+ local COMBINE = hints.COMBINE
+
+ -- Need to recompute branch targets (not part of hints).
+ local target = {}
+ for pc=1,1e6 do
+ local op, a, b, c = bytecode(func, pc)
+ if not op then break end
+ if op == "JMP" or op == "FORLOOP" then
+ local t = pc+1+b
+ if st[pc+COMBINE] ~= false then target[t] = true end
+ elseif op == "LOADBOOL" and c ~= 0 then
+ target[pc+2] = true
+ end
+ end
+
+ -- Map hints to bytecode instructions.
+ local hintstr = {}
+ for k,v in pairs(st) do
+ -- CHECK: must match hint shift in ljit_hints.h:JIT_H2NUM().
+ if type(k) == "number" and k >= 65536 then
+ local pc = k % 65536
+ if pc > 0 then
+ k = k - pc
+ local h = invhints[k] or (k/65536)
+ local hp = hintprint[h]
+ local s = hp and hp(h, v, st, pc) or (" #"..h)
+ local hs = hintstr[pc]
+ hintstr[pc] = hs and (hs..s) or s
+ end
+ end
+ end
+
+ -- Write header.
+ local info = debug.getinfo(func, "S")
+ out:write(sepline, " ", info.source, ":", info.linedefined)
+
+ -- Write function hints.
+ for k,v in pairs(fhints) do
+ if st[v] then out:write("\n#", k) end
+ end
+
+ -- Write instruction hints and bytecode.
+ local function dumprange(firstpc, lastpc)
+ for pc=firstpc,lastpc do
+ local prefix = " "
+ if st[pc+COMBINE] == false then prefix = "**"
+ elseif target[pc] then prefix = "=>" end
+ local line = bytecodeline(func, pc, prefix)
+ if not line then break end
+ local h = hintstr[pc]
+ if h then
+ out:write(format("%-40s %s", line, h))
+ else
+ out:write(line)
+ end
+ end
+ end
+
+ -- Handle deoptimization range table.
+ local t = st.deopt
+ if t then
+ out:write(" DEOPT=", rangestring(t))
+ for i,range in ipairs(t) do
+ if i ~= 1 then out:write("\n----") end
+ local pc = range % 65536
+ range = (range - pc) / 65536
+ dumprange(pc, pc+range)
+ end
+ else
+ dumprange(1, 1000000)
+ end
+
+ -- Write footer.
+ out:write("\n", sepline, "\n")
+ out:flush()
+end
+
+
+-- Active flag and output file handle.
+local active, out
+
+-- Dump hints handler for compiler pipeline.
+local function h_dumphints(st)
+ local ok, err = pcall(dumphints, st, out)
+ if not ok then
+ stderr:write("\nERROR: jit.dumphints disabled: ", err, "\n")
+ jit.attach(h_dumphints) -- Better turn ourselves off after a failure.
+ if out and out ~= stdout then out:close() end
+ out = nil
+ active = nil
+ end
+end
+
+-- Detach dump handler from compiler pipeline.
+local function dumphintsoff()
+ if active then
+ active = false
+ jit.attach(h_dumphints)
+ if out and out ~= stdout then out:close() end
+ out = nil
+ end
+end
+
+-- Open the output file and attach dump handler to compiler pipeline.
+local function dumphintson(filename)
+ if active then dumphintsoff() end
+ local outfile = filename or os.getenv("LUAJIT_DUMPHINTSFILE")
+ out = outfile and (outfile == "-" and stdout or assert(io.open(outfile, "w")))
+ jit.attach(h_dumphints, PRIORITY)
+ active = true
+end
+
+
+-- Public module functions.
+module(...)
+
+dump = dumphints
+on = dumphintson
+off = dumphintsoff
+start = dumphintson -- For -j command line option.
+
diff --git a/libraries/LuaJIT-1.1.7/jit/opt.lua b/libraries/LuaJIT-1.1.7/jit/opt.lua
new file mode 100644
index 0000000..5fe0f34
--- /dev/null
+++ b/libraries/LuaJIT-1.1.7/jit/opt.lua
@@ -0,0 +1,508 @@
+----------------------------------------------------------------------------
+-- LuaJIT optimizer.
+--
+-- Copyright (C) 2005-2011 Mike Pall. All rights reserved.
+-- Released under the MIT/X license. See luajit.h for full copyright notice.
+----------------------------------------------------------------------------
+-- This module contains a simple optimizer that generates some hints for
+-- the compiler backend.
+--
+-- Compare: luajit -j dump -e 'return 1'
+-- with: luajit -O -j dumphints -j dump -e 'return 1'
+--
+-- This module uses a very simplistic (but fast) abstract interpretation
+-- algorithm. It mostly ignores control flow and/or basic block boundaries.
+-- Thus the results of the analysis are really only predictions (e.g. about
+-- monomorphic use of operators). The backend _must_ check all contracts
+-- (e.g. verify the object type) and use a (polymorphic) fallback or
+-- deoptimization in case a contract is broken.
+--
+-- Although simplistic, the generated hints are pretty accurate. Note that
+-- some hints are really definitive and don't need to be checked (like
+-- COMBINE or FOR_STEP_K).
+--
+-- TODO: Try MFP with an extended lattice. But it's unclear whether the
+-- added complexity really pays off with the current backend.
+------------------------------------------------------------------------------
+
+-- Priority for compiler pipeline. Right in the middle before the backend.
+local PRIORITY = 50
+
+-- Default optimizer level, i.e. what you get with -O.
+-- Caveat: this may change in the future when more optimizations are added.
+local OPTLEVEL = 2
+
+-- Heuristic limits for what the compiler should reasonably handle.
+-- Functions outside these limits are unlikely to be run more than once.
+-- Maybe a bit on the generous side. Check ljit.h for backend limits, too.
+-- TODO: make it depend on the bytecode distribution, too.
+local LIMITS = {
+ bytecodes = 4000,
+ stackslots = 150,
+ params = 20,
+ consts = 200,
+ subs = 30,
+}
+
+-- Cache some library functions and objects.
+local jit = require("jit")
+assert(jit.version_num == 10107, "LuaJIT core/library version mismatch")
+local jutil = require("jit.util")
+local type, rawget, next, pcall = type, rawget, next, pcall
+local bytecode, const = jutil.bytecode, jutil.const
+local hints, fhints = jutil.hints, jutil.fhints
+local getmetatable = getmetatable
+
+-- Turn compilation off for the whole module. LuaJIT would do that anyway.
+jit.off(true, true)
+
+-- Default optimizer level after loading. But -O runs setlevel(), too.
+local optlevel = -1
+
+
+-- Use iterative path marking to mark live instructions and branch targets.
+local function marklive(func)
+ local live, work, workn, pc = {}, {}, 0, 1
+ repeat
+ repeat
+ local op, a, b, c, test = bytecode(func, pc)
+ live[pc] = true
+ pc = pc + 1
+ if op == "JMP" then
+ pc = pc + b
+ live[-pc] = true
+ elseif op == "FORLOOP" then
+ local mpc = -pc
+ live[mpc - b] = true
+ live[mpc] = true
+ elseif op == "RETURN" then
+ break
+ elseif test then
+ local fpc = pc + 1
+ -- No need for fallthrough target mark live[-fpc] in our analysis.
+ if not live[fpc] then -- Add fallthrough path to work list.
+ workn = workn + 1
+ work[workn] = fpc
+ end
+ elseif op == "CLOSURE" then
+ pc = pc + jutil.closurenup(func, b) -- Do not mark pseudo-ins live.
+ elseif op == "LOADBOOL" and c ~= 0 then
+ pc = pc + 1
+ live[-pc] = true
+ elseif op == "SETLIST" and c == 0 then
+ pc = pc + 1 -- Do not mark pseudo-ins live.
+ end
+ until live[pc]
+ if workn == 0 then return live end -- Return if work list is empty.
+ pc = work[workn] -- Else fetch next path to mark from work list.
+ workn = workn - 1
+ until false
+end
+
+
+-- Empty objects.
+local function empty() end
+
+-- Dummy function to set call hints. Replaced when jit.opt_inline is loaded.
+local function callhint(st, slot, pc, base, narg, nres)
+ st[pc+hints.TYPE] = slot[base]
+ for i=base,base+nres-1 do slot[i] = nil end
+end
+
+-- Set TYPE hint, but only for numbers, strings or tables.
+local function typehint(st, pc, o)
+ local tp = type(o)
+ if tp == "number" or tp == "string" or tp == "table" then
+ st[pc+hints.TYPE] = o
+ end
+end
+
+-- Set TYPE and TYPEKEY hints for table operations.
+local function tablehint(st, slot, pc, t, kslot)
+ local tp = type(t)
+ if tp == "table" or tp == "userdata" then st[pc+hints.TYPE] = t end
+ if kslot >= 0 then -- Don't need this hint for constants.
+ local key = slot[kslot]
+ local tp = type(key)
+ if tp == "number" or tp == "string" then st[pc+hints.TYPEKEY] = key end
+ end
+end
+
+-- Try to lookup a value. Guess the value or at least the value type.
+local function trylookup(st, t, k)
+ if k == nil then return nil end
+ if type(t) == "table" then
+ local v = rawget(t, k)
+ if v ~= nil then return v end
+ end
+ local mt = getmetatable(t)
+ if type(mt) == "table" then
+ -- One __index level is enough for our purposes.
+ local it = rawget(mt, "__index")
+ if type(it) == "table" then
+ local v = rawget(it, k)
+ if v ~= nil then return v end
+ end
+ end
+ local v = st.tableval[t] -- Resort to a generic guess.
+ if v == nil and type(t) == "table" then v = next(t) end -- Getting desperate.
+ return v
+end
+
+-- Check whether the previous instruction sets a const.
+local function prevconst(st, slot, pc, reg)
+ if st.live[-pc] == nil then -- Current instruction must not be a target.
+ local op, ka, kb = bytecode(st.func, pc-1)
+ if ka == reg and (op == "LOADK" or op == "LOADBOOL" or
+ (op == "LOADNIL" and kb == reg)) then
+ return true, slot[reg]
+ end
+ end
+end
+
+-- Common handler for arithmetic and comparison opcodes.
+local function arithop(st, slot, pc, a, b, c, op)
+ local sb, sc = slot[b], slot[c]
+ if sb == nil then sb = sc elseif sc == nil then sc = sb end
+ local tb, tc = type(sb), type(sc)
+ if tb == tc then
+ if tb == "number" then -- Improve the guess for numbers.
+ if op == "DIV" or sb % 1 ~= 0 or sc % 1 ~= 0 then
+ sb = 0.5 -- Probably a non-integral number.
+ else
+ sb = 1 -- Optimistic guess.
+ end
+ end
+ if sb ~= nil then st[pc+hints.TYPE] = sb end
+ else
+ st[pc+hints.TYPE] = false -- Marker for mixed types.
+ end
+ if op ~= "LT" and op ~= "LE" then
+ slot[a] = sb -- Assume coercion to 1st type if different.
+ end
+end
+
+-- Common handler for TEST and TESTSET.
+local function testop(st, slot, pc, a, b, c)
+ -- Optimize the 'expr and k1 or k2' idiom.
+ local ok, k = prevconst(st, slot, pc, b)
+ if k and a == b then
+ st[pc+hints.COMBINE] = false -- Kill the TEST/TESTSET.
+ if c == 0 then st.live[pc+1] = nil end -- Kill the JMP.
+ end
+ slot[a] = slot[b]
+end
+
+-- Dispatch table for opcode handlers.
+local handler = {
+ MOVE = function(st, slot, pc, a, b, c)
+ slot[a] = slot[b]
+ end,
+
+ LOADK = function(st, slot, pc, a, b, c)
+ slot[a] = const(st.func, b)
+ end,
+
+ LOADBOOL = function(st, slot, pc, a, b, c)
+ slot[a] = (b == 1)
+ end,
+
+ LOADNIL = function(st, slot, pc, a, b, c)
+ for i=a,b do slot[i] = nil end
+ end,
+
+ GETUPVAL = function(st, slot, pc, a, b, c)
+ slot[a] = jutil.upvalue(st.func, b)
+ end,
+
+ GETGLOBAL = function(st, slot, pc, a, b, c)
+ slot[a] = trylookup(st, st.stats.env, const(st.func, b))
+ end,
+
+ GETTABLE = function(st, slot, pc, a, b, c)
+ local t = slot[b]
+ tablehint(st, slot, pc, t, c)
+ slot[a] = trylookup(st, t, slot[c])
+ end,
+
+ SETGLOBAL = empty,
+
+ SETUPVAL = empty, -- TODO: shortcut -- but this is rare?
+
+ SETTABLE = function(st, slot, pc, a, b, c)
+ local t = slot[a]
+ tablehint(st, slot, pc, t, b)
+ if type(t) == "table" or type(t) == "userdata" then -- Must validate setkey.
+ local val = slot[c]
+ if val ~= nil then st.tableval[t] = val end
+ end
+ end,
+
+ NEWTABLE = function(st, slot, pc, a, b, c)
+ slot[a] = {} -- Need unique tables for indexing st.tableval.
+ end,
+
+ SELF = function(st, slot, pc, a, b, c)
+ local t = slot[b]
+ tablehint(st, slot, pc, t, c)
+ slot[a+1] = t
+ slot[a] = trylookup(st, t, slot[c])
+ end,
+
+ ADD = arithop, SUB = arithop, MUL = arithop, DIV = arithop,
+ MOD = arithop, POW = arithop, LT = arithop, LE = arithop,
+
+ UNM = function(st, slot, pc, a, b, c)
+ return arithop(st, slot, pc, a, b, b, "UNM")
+ end,
+
+ NOT = function(st, slot, pc, a, b, c)
+ slot[a] = true
+ end,
+
+ LEN = function(st, slot, pc, a, b, c)
+ typehint(st, pc, slot[b])
+ slot[a] = 1
+ end,
+
+ CONCAT = function(st, slot, pc, a, b, c)
+ local mixed
+ local sb = slot[b]
+ for i=b+1,c do
+ local si = slot[i]
+ if sb == nil then
+ sb = si
+ elseif si ~= nil and type(sb) ~= type(si) then
+ mixed = true
+ break
+ end
+ end
+ if sb == nil then
+ sb = ""
+ else
+ st[pc+hints.TYPE] = not mixed and sb or false
+ if type(sb) == "number" then sb = "" end
+ end
+ slot[a] = sb -- Assume coercion to 1st type (if different) or string.
+ end,
+
+ JMP = function(st, slot, pc, a, b, c)
+ if b >= 0 then -- Kill JMPs across dead code.
+ local tpc = pc + b
+ while not st.live[tpc] do tpc = tpc - 1 end
+ if tpc == pc then st[pc+hints.COMBINE] = false end
+ end
+ end,
+
+ EQ = function(st, slot, pc, a, b, c)
+ if b >= 0 and c >= 0 then typehint(st, pc, slot[b] or slot[c]) end
+ end,
+
+ TEST = function(st, slot, pc, a, b, c)
+ return testop(st, slot, pc, a, a, c)
+ end,
+
+ TESTSET = testop,
+
+ CALL = function(st, slot, pc, a, b, c)
+ callhint(st, slot, pc, a, b-1, c-1)
+ end,
+
+ TAILCALL = function(st, slot, pc, a, b, c)
+ callhint(st, slot, pc, a, b-1, -1)
+ end,
+
+ RETURN = function(st, slot, pc, a, b, c)
+ if b == 2 and prevconst(st, slot, pc, a) then
+ st[pc-1+hints.COMBINE] = true -- Set COMBINE hint for prev. instruction.
+ end
+ end,
+
+ FORLOOP = empty,
+
+ FORPREP = function(st, slot, pc, a, b, c)
+ local ok, step = prevconst(st, slot, pc, a+2)
+ if type(step) == "number" then
+ st[pc+hints.FOR_STEP_K] = step
+ end
+ local nstart, nstep = slot[a], slot[a+2]
+ local tnstart, tnstep = type(nstart), type(nstep)
+ local ntype = ((tnstart == "number" and nstart % 1 ~= 0) or
+ (tnstep == "number" and nstep % 1 ~= 0)) and 0.5 or 1
+ slot[a+3] = ntype
+ if tnstart == "number" and tnstep == "number" and
+ type(slot[a+1]) == "number" then
+ st[pc+hints.TYPE] = ntype
+ end
+ end,
+
+ -- TFORLOOP is at the end of the loop. Setting slots would be pointless.
+ -- Inlining is handled by the corresponding iterator constructor (CALL).
+ TFORLOOP = function(st, slot, pc, a, b, c)
+ st[pc+hints.TYPE] = slot[a]
+ end,
+
+ SETLIST = function(st, slot, pc, a, b, c)
+ -- TODO: if only (numeric) const: shortcut (+ nobarrier).
+ local t = slot[a]
+ -- Very imprecise. But better than nothing.
+ if type(t) == "table" then st.tableval[t] = slot[a+1] end
+ end,
+
+ CLOSE = empty,
+
+ CLOSURE = function(st, slot, pc, a, b, c)
+ slot[a] = empty
+ if st.noclose then
+ local nup = jutil.closurenup(st.func, b)
+ for i=pc+1,pc+nup do
+ local op = bytecode(st.func, i)
+ if op == "MOVE" then
+ st.noclose = false
+ return
+ end
+ end
+ end
+ end,
+
+ VARARG = function(st, slot, pc, a, b, c)
+ local params = st.stats.params
+ for i=1,b do slot[a+i-1] = st[params+i] end
+ end,
+}
+
+-- Generate some hints for the compiler backend.
+local function optimize(st)
+ -- Deoptimization is simple: just don't generate any hints. :-)
+ if st.deopt then return end
+
+ local func = st.func
+ local stats = jutil.stats(func)
+ if not stats then return jutil.status.COMPILER_ERROR end -- Eh?
+
+ -- Check limits.
+ if stats.bytecodes > LIMITS.bytecodes or
+ stats.stackslots > LIMITS.stackslots or
+ stats.params > LIMITS.params or
+ stats.consts > LIMITS.consts or
+ stats.subs > LIMITS.subs then
+ return jutil.status.TOOLARGE
+ end
+
+ -- Mark live instructions (live[pc]) and branch targets (live[-pc]).
+ local live = marklive(func)
+
+ -- Handlers need access to some temporary state fields.
+ st.noclose = true
+ st.stats = stats
+ st.live = live
+ st.tableval = { [stats.env] = empty } -- Guess: unknown globals are functions.
+
+ -- Initialize slots with argument hints and constants.
+ local slot = {}
+ for i=1,stats.params do slot[i-1] = st[i] end
+ for i=-1,-256,-1 do -- No need to copy non-RK-able consts.
+ local k, ok = const(func, i)
+ if not ok then break end
+ slot[i] = k
+ end
+
+ -- Step through all live instructions, update slots and add hints.
+ for pc=1,stats.bytecodes do
+ if live[pc] then
+ local op, a, b, c, test = bytecode(func, pc)
+ handler[op](st, slot, pc, a, b, c, op)
+ else
+ st[pc+hints.COMBINE] = false -- Dead instruction hint.
+ end
+ end
+
+ -- Update function hints.
+ if st.noclose then st[fhints.NOCLOSE] = true end
+
+ -- Clear temporary state fields.
+ st.noclose = nil
+ st.stats = nil
+ st.live = nil
+ st.tableval = nil
+end
+
+
+-- Active flags.
+local active, active_opt_inline
+
+-- Handler for compiler pipeline.
+local function h_opt(st)
+ if optlevel <= 0 then return end
+ local ok, err = pcall(optimize, st)
+ if not ok then
+ io.stderr:write("\nERROR: jit.opt disabled: ", err, "\n")
+ jit.attach(h_opt) -- Better turn ourselves off after a failure.
+ active = nil
+ else
+ if err then return err end
+ end
+end
+
+-- Load add-on module.
+local function loadaddon(opt)
+ local name, val = string.match(opt, "^(.-)=(.*)$") -- Strip value.
+ if not name then name = opt end
+ name = "jit.opt_"..name
+ local ok, mod = pcall(require, name)
+ if not ok then
+ -- Return error if not installed, but propagate other errors.
+ if string.sub(mod, 1, 7) ~= "module " then error(mod, 0) end
+ return "optimizer add-on module "..name.." not found"
+ end
+ mod.start(val)
+end
+
+-- Attach optimizer and set optimizer level or load add-on module.
+local function setlevel_(opt)
+ -- Easier to always attach the optimizer (even for -O0).
+ if not active then
+ jit.attach(h_opt, PRIORITY)
+ active = true
+ end
+
+ -- Parse -O or -O.
+ if opt == nil or opt == "" then
+ optlevel = OPTLEVEL
+ else
+ local level = tonumber(opt) -- Numeric level?
+ if level then
+ if level < 0 or level % 1 ~= 0 then
+ error("bad optimizer level", 0)
+ end
+ optlevel = level
+ else
+ if optlevel == -1 then optlevel = OPTLEVEL end
+ local err = loadaddon(opt)
+ if err then error(err, 0) end
+ end
+ end
+
+ -- Load add-on module for inlining functions for -O2 and above.
+ if not active_opt_inline and optlevel >= 2 then
+ loadaddon("inline") -- Be silent if not installed.
+ active_opt_inline = true -- Try this only once.
+ end
+end
+
+
+-- Public module functions.
+module(...)
+
+-- Callback to allow attaching a call hinter. Used by jit.opt_inline.
+function attach_callhint(f)
+ callhint = f
+end
+
+function getlevel()
+ return optlevel
+end
+
+setlevel = setlevel_
+start = setlevel_ -- For -O command line option.
+
diff --git a/libraries/LuaJIT-1.1.7/jit/opt_inline.lua b/libraries/LuaJIT-1.1.7/jit/opt_inline.lua
new file mode 100644
index 0000000..cc19bf4
--- /dev/null
+++ b/libraries/LuaJIT-1.1.7/jit/opt_inline.lua
@@ -0,0 +1,397 @@
+----------------------------------------------------------------------------
+-- LuaJIT optimizer add-on module for function inlining.
+--
+-- Copyright (C) 2005-2011 Mike Pall. All rights reserved.
+-- Released under the MIT/X license. See luajit.h for full copyright notice.
+----------------------------------------------------------------------------
+-- This is a simple framework for C function signature maps.
+-- It helps with type propagation and C function inlining.
+--
+-- This module is automatically loaded with -O2 and above.
+-- By default most standard library functions are added.
+--
+-- TODO: generalize it, e.g. for back propagation (i.e. arg types).
+-- TODO: extend it for Lua functions (but need to analyze them before use).
+------------------------------------------------------------------------------
+
+-- Cache some library functions and objects.
+local jit = require("jit")
+assert(jit.version_num == 10107, "LuaJIT core/library version mismatch")
+local jutil = require("jit.util")
+local type, rawget, next = type, rawget, next
+local hints, fhints = jutil.hints, jutil.fhints
+local sub, match, gsub = string.sub, string.match, string.gsub
+
+-- Turn compilation off for the whole module. LuaJIT would do that anyway.
+jit.off(true, true)
+
+-- Prototypical objects used for type hints.
+local TABLE = {}
+local CFUNC = collectgarbage -- Pretty sure this is never inlined.
+
+
+-- Map from C closures to signatures. Cannot use a weak table.
+-- Closures must be kept alive because inlining checks against their addrs.
+local map_sign = {}
+
+-- For jit.dumphints: get printable name for TYPE hint: "#INLINE(foo.bar)".
+local function getname_(f, idx)
+ local sign = map_sign[f]
+ if sign then
+ local libname, name = sign.libname, sign.name
+ if libname then
+ return libname.."."..name
+ else
+ return name
+ end
+ elseif idx == 0 then
+ return "recursive"
+ else
+ return "?"
+ end
+end
+
+-- Name, base table and running index for convenience functions.
+-- CHECK: the library index and the order below must match with ljit_hints.h
+local flibname, flib, fidx
+
+local function fadd(name, results, args, handler)
+ local f = rawget(flib, name)
+ if f then
+ map_sign[f] = {
+ libname = flibname, name = name, idx = fidx,
+ results = results, args = args, handler = handler,
+ }
+ end
+ if fidx then fidx = fidx + 1 end
+end
+
+local function faddf(name, f, results, args, handler)
+ map_sign[f] = {
+ libname = flibname, name = name, idx = fidx,
+ results = results, args = args, handler = handler,
+ }
+ if fidx then fidx = fidx + 1 end
+end
+
+
+-- Signature handler: copy first argument to first result.
+local function copyfirst(st, slot, pc, base, narg, nres)
+ slot[base] = slot[base+1]
+end
+
+-- Helper for iterators: check if the function is an iterator constructor.
+--
+-- 'for ivars in func(args) do body end'
+--
+-- ...load func+args...
+-- CALL func <-- pc
+-- JMP fwd ---+
+-- back: | <--+
+-- ...body... | |
+-- fwd: <--+ |
+-- TFORLOOP ivars | <-- tforpc
+-- JMP back ---+
+--
+local function itercheck(st, slot, pc, base, idx)
+ if idx then
+ local bytecode, func = jutil.bytecode, st.func
+ local op, _, fwd = bytecode(func, pc+1)
+ if op == "JMP" then
+ local tforpc = pc+2+fwd
+ local op, tfbase, _, tfnres = bytecode(func, tforpc)
+ if op == "TFORLOOP" and tfbase == base and tfnres <= 2 then
+ local op, _, back = bytecode(func, tforpc+1)
+ if op == "JMP" and fwd+back == -2 then
+ -- Must set inlining hint for TFORLOOP instruction here.
+ st[tforpc+hints.INLINE] = idx -- Serves as iterator index, too.
+ return -- Inline it.
+ end
+ end
+ end
+ end
+ slot[base] = CFUNC -- Better make it different from pairs.
+ return true -- Better not inline it, if not used in a for statement.
+end
+
+-- Helper for pairs/next: guess result types for standard table iterator.
+local function guessnext(st, slot, base, dest)
+ local t, k, v = slot[base+1]
+ if type(t) == "table" then
+ k, v = next(t)
+ if v == nil then v = st.tableval[t] end
+ end
+ slot[dest] = k or "" -- Strings are a good guess for the key type.
+ slot[dest+1] = v -- But better not guess any fixed value type.
+end
+
+
+-- Signatures for base library functions.
+-- Note: Only add functions where result type hints or inlining makes sense.
+flibname, flib, fidx = nil, _G, 65536*1
+fadd("pairs", "..0", "T",
+ function(st, slot, pc, base, narg, nres, idx)
+ -- Table in slot[base+1] is kept (2nd result = 1st arg).
+ -- Fill result slots for the iterator here (TFORLOOP is at the end).
+ guessnext(st, slot, base, base+3)
+ return itercheck(st, slot, pc, base, idx)
+ end)
+
+fadd("ipairs", "..I", "T",
+ function(st, slot, pc, base, narg, nres, idx)
+ -- Table in slot[base+1] is kept (2nd result = 1st arg).
+ -- Fill result slots for the iterator here (TFORLOOP is at the end).
+ local t = slot[base+1]
+ slot[base+3] = 1 -- Integer key.
+ local v
+ if type(t) == "table" then
+ v = rawget(t, 1)
+ if v == nil then v = st.tableval[t] end
+ end
+ slot[base+4] = v
+ return itercheck(st, slot, pc, base, idx)
+ end)
+
+fidx = nil -- Pure result type signatures follow:
+fadd("next", "..", "T.?",
+ function(st, slot, pc, base, narg, nres)
+ guessnext(st, slot, base, base)
+ end)
+fadd("type", "S", ".")
+fadd("getmetatable", "T", ".")
+fadd("setmetatable", ".", "TT?", copyfirst)
+fadd("rawequal", "B", "..")
+fadd("rawget", ".", "T.",
+ function(st, slot, pc, base, narg, nres)
+ local t = slot[base+1]
+ slot[base] = type(t) == "table" and rawget(t, slot[base+2]) or ""
+ end)
+fadd("rawset", ".", "T..", copyfirst)
+fadd("assert", "*", "..*",
+ function(st, slot, pc, base, narg, nres)
+ for i=1,nres do slot[base+i-1] = i <= narg and slot[base+i] or nil end
+ end)
+fadd("tonumber", "I", ".I?")
+fadd("tostring", "S", ".")
+fadd("require", "T", "S")
+
+-- Signatures for coroutine library functions.
+flibname, flib, fidx = "coroutine", coroutine, 65536*2
+if flib then
+ fadd("yield", "*", ".*")
+ fadd("resume", "*", "R.*",
+ function(st, slot, pc, base, narg, nres)
+ slot[base] = true
+ for i=1,nres-1 do slot[base+i] = nil end -- No guess.
+ end)
+
+ fidx = nil -- Pure result type signatures follow:
+ fadd("wrap", "C", "F")
+end
+
+-- Signatures for string library functions.
+flibname, flib, fidx = "string", string, 65536*3
+if flib then
+ fadd("len", "I", "S")
+ fadd("sub", "S", "SII?")
+ fadd("char", "S", "I*")
+
+ fidx = nil -- Pure result type signatures follow:
+ fadd("byte", "I", "S",
+ function(st, slot, pc, base, narg, nres)
+ for i=0,nres-1 do slot[base+i] = 1 end -- Set all result hints.
+ end)
+ fadd("rep", "S", "SI")
+ fadd("reverse", "S", "S")
+ fadd("upper", "S", "S")
+ fadd("lower", "S", "S")
+
+ fadd("format", "S", "S.*")
+ fadd("find", "*", "SSI?.?",
+ function(st, slot, pc, base, narg, nres)
+ slot[base] = 1
+ slot[base+1] = 1
+ for i=2,nres-1 do slot[base+i] = "" end -- Hints for matches.
+ end)
+ fadd("match", "*", "SSI?",
+ function(st, slot, pc, base, narg, nres)
+ for i=0,nres-1 do slot[base+i] = "" end -- Hints for matches.
+ end)
+ fadd("gsub", "SI", "SSGI?")
+ fadd("gmatch", "C00", "SS",
+ function(st, slot, pc, base, narg, nres)
+ -- Fill result slots for gmatch_iter here (TFORLOOP is at the end).
+ for i=base+3,st.stats.stackslots-1 do slot[i] = "" end
+ end)
+ -- The gmatch iterator itself is never inlined. No point in adding it.
+end
+
+-- Signatures for table library functions.
+flibname, flib, fidx = "table", table, 65536*4
+if flib then
+ fadd("insert", "", "TI?.")
+ fadd("remove", ".", "T",
+ function(st, slot, pc, base, narg, nres)
+ if nres >= 1 then
+ local t = slot[base+1]
+ slot[base] = type(t) == "table" and rawget(t, 1) or ""
+ end
+ end)
+ fadd("getn", "I", "T")
+
+ fidx = nil -- Pure result type signatures follow:
+ fadd("concat", "S", "TS?I?I?")
+end
+
+-- Signatures for math library functions.
+flibname, flib, fidx = "math", math, 65536*5
+if flib then
+ -- 1 arg, 1 result.
+ fadd("log", "N", "N")
+ fadd("log10", "N", "N")
+ fadd("exp", "N", "N")
+ fadd("sinh", "N", "N")
+ fadd("cosh", "N", "N")
+ fadd("tanh", "N", "N")
+ fadd("asin", "N", "N")
+ fadd("acos", "N", "N")
+ fadd("atan", "N", "N")
+ fadd("sin", "N", "N")
+ fadd("cos", "N", "N")
+ fadd("tan", "N", "N")
+ fadd("ceil", "I", "N")
+ fadd("floor", "I", "N")
+ fadd("abs", ".", "N", copyfirst)
+ fadd("sqrt", "N", "N")
+ -- 2 args, 1 result.
+ -- math.fmod is aliased to math.mod for compatibility.
+ fadd("fmod", ".", "NN",
+ function(st, slot, pc, base, narg, nres)
+ slot[base] = slot[base+2] or 1 -- Copy integer or number hint.
+ end)
+ fadd("atan2", "N", "NN")
+
+ fidx = nil -- Pure result type signatures follow:
+ -- 1-n args, 1 result.
+ fadd("min", ".", "NN*", copyfirst) -- Really depends on all args.
+ fadd("max", ".", "NN*", copyfirst) -- Really depends on all args.
+ -- 1 arg, 1 result.
+ fadd("deg", "N", "N")
+ fadd("rad", "N", "N")
+ -- 1 arg, 2 results.
+ fadd("modf", "IN", "N")
+ fadd("frexp", "NI", "N")
+ -- 2 args, 1 result.
+ fadd("pow", "N", "NN")
+ fadd("ldexp", ".", "NI", copyfirst)
+ -- 1 arg, 0 results.
+ fadd("randomseed", "", "I")
+ -- 0-2 args, 1 result.
+ fadd("random", "N", "I?I?",
+ function(st, slot, pc, base, narg, nres)
+ if narg > 0 then slot[base] = 1 end
+ end)
+end
+
+-- Signatures for I/O library functions.
+-- Not inlined anytime soon. Used for result types only.
+flibname, flib, fidx = "io", io, nil
+if flib then
+ fadd("lines", "C00S", "S?")
+ fadd("read", "S", "") -- Simplified (a lot).
+ -- Adding io methods doesn't work, because we don't deal with userdata (yet).
+end
+
+
+-- Type names to argument type shorthands.
+-- TODO: make the matches more exact? Need to differentiate nil/unknown.
+local map_argtype = {
+ ["nil"] = "0", boolean = "b", number = "n", string = "s",
+ table = "t", ["function"] = "f", userdata = "u", thread = "r",
+}
+
+-- Complex argument match patterns to regexp fragments.
+local map_argmatch = {
+ B = "[b0]", S = "[s0]", T = "[t0]", F = "[f0]", U = "[u0]", R = "[r0]",
+ N = "[n0]", I = "[n0]", -- Number/int args are the same for now.
+ G = "[stf0]", -- For string.gsub.
+}
+
+-- Result type shorthands to sample types.
+local map_restype = {
+ -- ["0"] = nil,
+ B = true, S = "", T = {},
+ N = 0.5, I = 1,
+ L = function() end, C = collectgarbage, -- Pretty sure this is never inlined.
+}
+
+-- Create argument match regexp and cache it.
+local function getargmatch(sign)
+ local argmatch = "^"..gsub(sign.args, ".", map_argmatch).."0*$"
+ sign.argmatch = argmatch
+ return argmatch
+end
+
+-- Set INLINE hints and result types for known C functions.
+local function inlinehint(sign, st, slot, pc, base, narg, nres)
+ local idx = sign.idx
+ if idx then
+ if narg ~= -1 then
+ local argpat = ""
+ for i=1,narg do argpat = argpat..map_argtype[type(slot[base+i])] end
+ if not match(argpat, sign.argmatch or getargmatch(sign)) then
+ idx = nil
+ end
+ end
+ end
+
+ local results = sign.results
+ if results ~= "*" and nres ~= -1 then
+ if nres > #results then idx = nil end
+ for i=1,#results do
+ local c = sub(results, i, i)
+ if c ~= "." then slot[base+i-1] = map_restype[c] end
+ end
+ end
+
+ local handler = sign.handler
+ if handler and handler(st, slot, pc, base, narg, nres, idx) then idx = nil end
+
+ if idx then st[pc+hints.INLINE] = idx end
+end
+
+-- Set call hints and result types during forward propagation.
+local function fwdcallhint(st, slot, pc, base, narg, nres)
+ local f = slot[base]
+ st[pc+hints.TYPE] = f
+ if type(f) == "function" then
+ local sign = map_sign[f]
+ if sign then
+ inlinehint(sign, st, slot, pc, base, narg, nres)
+ return
+ end
+ if f == st.func and not st.stats.isvararg and
+ (narg == -1 or narg == st.stats.params) then
+ st[pc+hints.INLINE] = 0 -- Recursive call.
+ end
+ end
+ -- Clear result types for unknown functions.
+ for i=base,base+nres-1 do slot[i] = nil end
+end
+
+
+-- Attach call hinter to optimizer.
+local function start_()
+ local jopt = require "jit.opt"
+ jopt.attach_callhint(fwdcallhint)
+ -- Note that just loading the optimizer does not start it, yet.
+end
+
+
+-- Public module functions.
+module(...)
+
+-- TODO: Public API to add signatures. Alas, the API is still in flux.
+getname = getname_
+start = start_
+
diff --git a/libraries/LuaJIT-1.1.7/jit/trace.lua b/libraries/LuaJIT-1.1.7/jit/trace.lua
new file mode 100644
index 0000000..42367c6
--- /dev/null
+++ b/libraries/LuaJIT-1.1.7/jit/trace.lua
@@ -0,0 +1,111 @@
+----------------------------------------------------------------------------
+-- LuaJIT compiler tracing module.
+--
+-- Copyright (C) 2005-2011 Mike Pall. All rights reserved.
+-- Released under the MIT/X license. See luajit.h for full copyright notice.
+----------------------------------------------------------------------------
+-- Activate this module to trace the progress of the JIT compiler.
+--
+-- Try: luajit -j trace -e 'print "foo"'
+-- luajit -j trace=foo.trace foo.lua
+--
+-- Default output is to stderr. To redirect output to a file,
+-- pass a filename as an argument or set the environment variable
+-- "LUAJIT_TRACEFILE".
+-- Note: the file is overwritten each time you run luajit.
+------------------------------------------------------------------------------
+
+-- Priority for compiler pipeline. Must run after backend (negative)
+-- and should be odd to catch compiler errors, too.
+local PRIORITY = -99
+
+-- Cache some library functions and objects.
+local jit = require("jit")
+assert(jit.version_num == 10107, "LuaJIT core/library version mismatch")
+local jutil = require("jit.util")
+local type, tostring, sub, format = type, tostring, string.sub, string.format
+local getinfo, justats = debug.getinfo, jutil.stats
+local stdout, stderr = io.stdout, io.stderr
+
+-- Turn compilation off for the whole module. LuaJIT would do that anyway.
+jit.off(true, true)
+
+-- Active flag and output file handle.
+local active, out
+
+-- Generate range string from table: pc[-pc] [,...]
+local function rangestring(t)
+ local s = ""
+ for i,range in ipairs(t) do
+ if i ~= 1 then s = s.."," end
+ local pc = range % 65536
+ range = (range - pc) / 65536
+ s = s..pc
+ if range ~= 0 then s = s..(-(pc+range)) end
+ end
+ return s
+end
+
+-- Trace handler for compiler pipeline.
+local function h_trace(st, status)
+ local o = out or stderr
+ local func = st.func
+ if type(func) ~= "function" then return end
+ local info = getinfo(func, "S")
+ local src, line = info.source, info.linedefined or 0
+ if src then
+ if sub(src, 1, 1) == "@" or sub(src, 1, 2) == "=(" then
+ src = sub(src, 2)
+ else
+ src = "**"..string.gsub(sub(src, 1, 40), "%c", " ").."**"
+ end
+ else
+ src = "?"
+ end
+ local aux = st.deopt and " DEOPT="..rangestring(st.deopt) or ""
+ if status == nil then
+ local stats = justats(func)
+ if not stats then return end
+ o:write(format("[LuaJIT: OK %4d %6d %s:%d%s]\n",
+ stats.bytecodes, stats.mcodesize or -1, src, line, aux))
+ return
+ else
+ local stname = jit.util.status[status] or status
+ local pc, err = st.dasm_pc, st.dasm_err
+ if type(pc) == "number" and type(err) == "number" then
+ local op = jutil.bytecode(func, pc) or "END"
+ o:write(format("[LuaJIT: %s %s@%d %08x %s:%d%s]\n",
+ stname, op, pc, err, src, line, aux))
+ else
+ o:write(format("[LuaJIT: %s %s:%d%s]\n", stname, src, line, aux))
+ end
+ end
+end
+
+-- Detach trace handler from compiler pipeline.
+local function traceoff()
+ if active then
+ active = false
+ jit.attach(h_trace)
+ if out and out ~= stdout then out:close() end
+ out = nil
+ end
+end
+
+-- Open the output file and attach trace handler to compiler pipeline.
+local function traceon(filename)
+ if active then traceoff() end
+ local outfile = filename or os.getenv("LUAJIT_TRACEFILE")
+ out = outfile and (outfile == "-" and stdout or assert(io.open(outfile, "w")))
+ jit.attach(h_trace, PRIORITY)
+ active = true
+end
+
+
+-- Public module functions.
+module(...)
+
+on = traceon
+off = traceoff
+start = traceon -- For -j command line option.
+
diff --git a/libraries/LuaJIT-1.1.7/jitdoc/bluequad-print.css b/libraries/LuaJIT-1.1.7/jitdoc/bluequad-print.css
new file mode 100644
index 0000000..69c07d6
--- /dev/null
+++ b/libraries/LuaJIT-1.1.7/jitdoc/bluequad-print.css
@@ -0,0 +1,166 @@
+/* Copyright (C) 2004-2011 Mike Pall.
+ *
+ * You are welcome to use the general ideas of this design for your own sites.
+ * But please do not steal the stylesheet, the layout or the color scheme.
+ */
+body {
+ font-family: serif;
+ font-size: 11pt;
+ margin: 0 3em;
+ padding: 0;
+ border: none;
+}
+a:link, a:visited, a:hover, a:active {
+ text-decoration: none;
+ background: transparent;
+ color: #0000ff;
+}
+h1, h2, h3 {
+ font-family: sans-serif;
+ font-weight: bold;
+ text-align: left;
+ margin: 0.5em 0;
+ padding: 0;
+}
+h1 {
+ font-size: 200%;
+}
+h2 {
+ font-size: 150%;
+}
+h3 {
+ font-size: 125%;
+}
+p {
+ margin: 0 0 0.5em 0;
+ padding: 0;
+}
+ul, ol {
+ margin: 0.5em 0;
+ padding: 0 0 0 2em;
+}
+ul {
+ list-style: outside square;
+}
+ol {
+ list-style: outside decimal;
+}
+li {
+ margin: 0;
+ padding: 0;
+}
+dl {
+ margin: 1em 0;
+ padding: 1em;
+ border: 1px solid black;
+}
+dt {
+ font-weight: bold;
+ margin: 0;
+ padding: 0;
+}
+dt sup {
+ float: right;
+ margin-left: 1em;
+}
+dd {
+ margin: 0.5em 0 0 2em;
+ padding: 0;
+}
+table {
+ table-layout: fixed;
+ width: 100%;
+ margin: 1em 0;
+ padding: 0;
+ border: 1px solid black;
+ border-spacing: 0;
+ border-collapse: collapse;
+}
+tr {
+ margin: 0;
+ padding: 0;
+ border: none;
+}
+td {
+ text-align: left;
+ margin: 0;
+ padding: 0.2em 0.5em;
+ border-top: 1px solid black;
+ border-bottom: 1px solid black;
+}
+tr.separate td {
+ border-top: double;
+}
+tt, pre, code, kbd, samp {
+ font-family: monospace;
+ font-size: 75%;
+}
+kbd {
+ font-weight: bolder;
+}
+blockquote, pre {
+ margin: 1em 2em;
+ padding: 0;
+}
+img {
+ border: none;
+ vertical-align: baseline;
+ margin: 0;
+ padding: 0;
+}
+img.left {
+ float: left;
+ margin: 0.5em 1em 0.5em 0;
+}
+img.right {
+ float: right;
+ margin: 0.5em 0 0.5em 1em;
+}
+.flush {
+ clear: both;
+ visibility: hidden;
+}
+.hide, .noprint, #nav {
+ display: none !important;
+}
+.pagebreak {
+ page-break-before: always;
+}
+#site {
+ text-align: right;
+ font-family: sans-serif;
+ font-weight: bold;
+ margin: 0 1em;
+ border-bottom: 1pt solid black;
+}
+#site a {
+ font-size: 1.2em;
+}
+#site a:link, #site a:visited {
+ text-decoration: none;
+ font-weight: bold;
+ background: transparent;
+ color: #ffffff;
+}
+#logo {
+ color: #ff8000;
+}
+#head {
+ clear: both;
+ margin: 0 1em;
+}
+#main {
+ line-height: 1.3;
+ text-align: justify;
+ margin: 1em;
+}
+#foot {
+ clear: both;
+ font-size: 80%;
+ text-align: center;
+ margin: 0 1.25em;
+ padding: 0.5em 0 0 0;
+ border-top: 1pt solid black;
+ page-break-before: avoid;
+ page-break-after: avoid;
+}
diff --git a/libraries/LuaJIT-1.1.7/jitdoc/bluequad.css b/libraries/LuaJIT-1.1.7/jitdoc/bluequad.css
new file mode 100644
index 0000000..8d72de9
--- /dev/null
+++ b/libraries/LuaJIT-1.1.7/jitdoc/bluequad.css
@@ -0,0 +1,292 @@
+/* Copyright (C) 2004-2011 Mike Pall.
+ *
+ * You are welcome to use the general ideas of this design for your own sites.
+ * But please do not steal the stylesheet, the layout or the color scheme.
+ */
+/* colorscheme:
+ *
+ * site | head #4162bf/white | #6078bf/#e6ecff
+ * ------+------ ----------------+-------------------
+ * nav | main #bfcfff | #e6ecff/black
+ *
+ * nav: hiback loback #c5d5ff #b9c9f9
+ * hiborder loborder #e6ecff #97a7d7
+ * link hover #2142bf #ff0000
+ *
+ * link: link visited hover #2142bf #8122bf #ff0000
+ *
+ * main: boxback boxborder #f0f4ff #bfcfff
+ */
+body {
+ font-family: Verdana, Arial, Helvetica, sans-serif;
+ font-size: 10pt;
+ margin: 0;
+ padding: 0;
+ border: none;
+ background: #e0e0e0;
+ color: #000000;
+}
+a:link {
+ text-decoration: none;
+ background: transparent;
+ color: #2142bf;
+}
+a:visited {
+ text-decoration: none;
+ background: transparent;
+ color: #8122bf;
+}
+a:hover, a:active {
+ text-decoration: underline;
+ background: transparent;
+ color: #ff0000;
+}
+h1, h2, h3 {
+ font-weight: bold;
+ text-align: left;
+ margin: 0.5em 0;
+ padding: 0;
+ background: transparent;
+}
+h1 {
+ font-size: 200%;
+ line-height: 3em; /* really 6em relative to body, match #site span */
+ margin: 0;
+}
+h2 {
+ font-size: 150%;
+ color: #606060;
+}
+h3 {
+ font-size: 125%;
+ color: #404040;
+}
+p {
+ max-width: 600px;
+ margin: 0 0 0.5em 0;
+ padding: 0;
+}
+ul, ol {
+ max-width: 600px;
+ margin: 0.5em 0;
+ padding: 0 0 0 2em;
+}
+ul {
+ list-style: outside square;
+}
+ol {
+ list-style: outside decimal;
+}
+li {
+ margin: 0;
+ padding: 0;
+}
+dl {
+ max-width: 600px;
+ margin: 1em 0;
+ padding: 1em;
+ border: 1px solid #bfcfff;
+ background: #f0f4ff;
+}
+dt {
+ font-weight: bold;
+ margin: 0;
+ padding: 0;
+}
+dt sup {
+ float: right;
+ margin-left: 1em;
+ color: #808080;
+}
+dt a:visited {
+ text-decoration: none;
+ color: #2142bf;
+}
+dt a:hover, dt a:active {
+ text-decoration: none;
+ color: #ff0000;
+}
+dd {
+ margin: 0.5em 0 0 2em;
+ padding: 0;
+}
+div.tablewrap { /* for IE *sigh* */
+ max-width: 600px;
+}
+table {
+ table-layout: fixed;
+ border-spacing: 0;
+ border-collapse: collapse;
+ max-width: 600px;
+ width: 100%;
+ margin: 1em 0;
+ padding: 0;
+ border: 1px solid #bfcfff;
+}
+tr {
+ margin: 0;
+ padding: 0;
+ border: none;
+}
+tr.odd {
+ background: #f0f4ff;
+}
+tr.separate td {
+ border-top: 1px solid #bfcfff;
+}
+td {
+ text-align: left;
+ margin: 0;
+ padding: 0.2em 0.5em;
+ border: none;
+}
+tt, code, kbd, samp {
+ font-family: Courier New, Courier, monospace;
+ font-size: 110%;
+}
+kbd {
+ font-weight: bolder;
+}
+blockquote, pre {
+ max-width: 600px;
+ margin: 1em 2em;
+ padding: 0;
+}
+pre {
+ line-height: 1.1;
+}
+img {
+ border: none;
+ vertical-align: baseline;
+ margin: 0;
+ padding: 0;
+}
+img.left {
+ float: left;
+ margin: 0.5em 1em 0.5em 0;
+}
+img.right {
+ float: right;
+ margin: 0.5em 0 0.5em 1em;
+}
+.indent {
+ padding-left: 1em;
+}
+.flush {
+ clear: both;
+ visibility: hidden;
+}
+.hide, .noscreen {
+ display: none !important;
+}
+.ext {
+ color: #ff8000;
+}
+#site {
+ clear: both;
+ float: left;
+ width: 13em;
+ text-align: center;
+ font-weight: bold;
+ margin: 0;
+ padding: 0;
+ background: transparent;
+ color: #ffffff;
+}
+#site a {
+ font-size: 200%;
+}
+#site a:link, #site a:visited {
+ text-decoration: none;
+ font-weight: bold;
+ background: transparent;
+ color: #ffffff;
+}
+#site span {
+ line-height: 3em; /* really 6em relative to body, match h1 */
+}
+#logo {
+ color: #ffb380;
+}
+#head {
+ margin: 0;
+ padding: 0 0 0 2em;
+ border-left: solid 13em #4162bf;
+ border-right: solid 3em #6078bf;
+ background: #6078bf;
+ color: #e6ecff;
+}
+#nav {
+ clear: both;
+ float: left;
+ overflow: hidden;
+ text-align: left;
+ line-height: 1.5;
+ width: 13em;
+ padding-top: 1em;
+ background: transparent;
+}
+#nav ul {
+ list-style: none outside;
+ margin: 0;
+ padding: 0;
+}
+#nav li {
+ margin: 0;
+ padding: 0;
+}
+#nav a {
+ display: block;
+ text-decoration: none;
+ font-weight: bold;
+ margin: 0;
+ padding: 2px 1em;
+ border-top: 1px solid transparent;
+ border-bottom: 1px solid transparent;
+ background: transparent;
+ color: #2142bf;
+}
+#nav a:hover, #nav a:active {
+ text-decoration: none;
+ border-top: 1px solid #97a7d7;
+ border-bottom: 1px solid #e6ecff;
+ background: #b9c9f9;
+ color: #ff0000;
+}
+#nav a.current, #nav a.current:hover, #nav a.current:active {
+ border-top: 1px solid #e6ecff;
+ border-bottom: 1px solid #97a7d7;
+ background: #c5d5ff;
+ color: #2142bf;
+}
+#nav ul ul a {
+ padding: 0 1em 0 2em;
+}
+#main {
+ line-height: 1.5;
+ text-align: left;
+ margin: 0;
+ padding: 1em 2em;
+ border-left: solid 13em #bfcfff;
+ border-right: solid 3em #e6ecff;
+ background: #e6ecff;
+}
+#foot {
+ clear: both;
+ font-size: 80%;
+ text-align: center;
+ margin: 0;
+ padding: 0.5em;
+ background: #6078bf;
+ color: #ffffff;
+}
+#foot a:link, #foot a:visited {
+ text-decoration: underline;
+ background: transparent;
+ color: #ffffff;
+}
+#foot a:hover, #foot a:active {
+ text-decoration: underline;
+ background: transparent;
+ color: #bfcfff;
+}
diff --git a/libraries/LuaJIT-1.1.7/jitdoc/coco.html b/libraries/LuaJIT-1.1.7/jitdoc/coco.html
new file mode 100644
index 0000000..0ef43f1
--- /dev/null
+++ b/libraries/LuaJIT-1.1.7/jitdoc/coco.html
@@ -0,0 +1,132 @@
+
+
+
+Coco
+
+
+
+
+
+
+
+
+
+Coco is a small extension to get True C Coroutine
+semantics for Lua 5.1.
+
+
+Coco is both available as a stand-alone release and integrated
+into LuaJIT 1.x.
+
+
+The stand-alone release is a patchset against the
+» standard Lua 5.1.4
+distribution. There are no dependencies on LuaJIT. However LuaJIT 1.x
+depends on Coco to allow yielding for JIT compiled functions.
+
+True C coroutine semantics mean you can yield from a coroutine
+across a C call boundary and resume back to it.
+
+
+Coco allows you to use a dedicated C stack for each coroutine.
+Resuming a coroutine and yielding from a coroutine automatically switches
+C stacks, too.
+
+
+In particular you can now:
+
+
+
Yield across all metamethods (not advised for __gc).
+
Yield across iterator functions (for x in func do).
+
Yield across callbacks (table.foreach(), dofile(), ...).
+
Yield across protected callbacks (pcall(), xpcall(), ...).
+
Yield from C functions and resume back to them.
+
+
+Best of all, you don't need to change your Lua or C sources
+and still get the benefits. It's fully integrated into the
+Lua core, but tries to minimize the required changes.
+
+
+
More ...
+
+Please visit the » Download page
+to fetch the current version of the stand-alone package.
+
+
+Coco needs some machine-specific features — please have a look
+at the Portability Requirements.
+
+
+Coco also provides some upwards-compatible
+API Extensions for Lua.
+
+The optional argument cstacksize specifies the size of the
+C stack to allocate for the coroutine:
+
+
+
A default stack size is used if cstacksize is not given
+or is nil or zero.
+
No C stack is allocated if cstacksize is -1.
+
Any other value is rounded up to the minimum size
+(i.e. use 1 to get the minimum size).
+
+
+Important notice for LuaJIT: JIT compiled functions cannot
+yield if a coroutine does not have a dedicated C stack.
+
+
+
olddefault = coroutine.cstacksize([newdefault])
+
+Returns the current default C stack size (may be 0 if the
+underlying context switch method has its own default).
+Sets a new default C stack size if newdefault is present.
+Use 0 to reset it to the default C stack size. Any other
+value is rounded up to the minimum size.
+
+
+
C API extensions
+
+All C API functions are either unchanged or upwards compatible.
+
+
+
int lua_yield(lua_State *L, int nresults)
+
+The semantics for lua_yield() have changed slightly.
+Existing programs should work fine as long as they follow
+the usage conventions from the Lua manual:
+
+
+return lua_yield(L, nresults);
+
+
+Previously lua_yield() returned a 'magic' value (-1) that
+indicated a yield. Your C function had to pass this value
+on to the Lua core and was not called again.
+
+
+Now, if the current coroutine has an associated C stack,
+lua_yield() returns the number of arguments passed back from
+the resume. This just happens to be the right convention for
+returning them as a result from a C function. I.e. if you
+used the above convention, you'll never notice the change.
+
+
+But the results are on the Lua stack when lua_yield()
+returns. So the C function can just continue and process them
+or retry an I/O operation etc. And your whole C stack frame
+(local variables etc.) is still there, too. You can yield from
+anywhere in your C program, even several call levels deeper.
+
+
+Of course all of this only works with Lua+Coco and not with standard Lua.
+
+
+
lua_State *lua_newcthread(lua_State *L, int cstacksize)
+
+This is an (optional) new function that allows you to create
+a coroutine with an associated C stack directly from the C API.
+Other than that it works the same as lua_newthread(L).
+
+
+You have to declare this function as extern
+yourself, since it's not part of the official Lua API.
+This means that a C module that uses this call cannot
+be loaded with standard Lua. This may be intentional.
+
+
+If you want your C module to work with both standard Lua
+and Lua+Coco you can check whether Coco is available with:
+
Fix compilation of the GCC inline assembler code on x64.
+Now works when compiled as C++ code (reported by Jonathan Sauer)
+or with -fPIC (reported by Jim Pryor).
+
Added GCC inline assembler for faster context switching on Sparc.
+Thanks to Takayuki Usui.
+
+
+
Coco 1.1.5 — 2008-10-25
+
+
Upgraded to patch cleanly into Lua 5.1.4.
+
Added GCC inline assembler for faster context switching on x64.
+Thanks to Robert G. Jakabosky.
+
+
+
Coco 1.1.4 — 2008-02-05
+
+
Upgraded to patch cleanly into Lua 5.1.3.
+
Fixed setjmp method for ARM with recent glibc versions.
+Thanks to the LuaTeX developers.
+
Fixed setjmp method for x86 on Mac OS X (rarely used,
+default is GCC inline assembler). Thanks to Jason Toffaletti.
+
+
+
Coco 1.1.3 — 2007-05-24
+
+
Upgraded to patch cleanly into Lua 5.1.2.
+
Merged patch from Zachary P. Landau for a Linux/ARM setjmp method (uClibc and glibc).
+
+
+
Coco 1.1.1 — 2006-06-20
+
+
Upgraded to patch cleanly into Lua 5.1.1.
+
C stacks are deallocated early: when a coroutine ends, and not when
+the coroutine object is collected. This mainly benefits Windows Fibers.
+
Windows threads get the required Fiber context when resuming
+a coroutine and not just on creation.
+
+
+
Coco 1.1.0 — 2006-02-18
+
+
Upgraded to patch cleanly into Lua 5.1 (final).
+
Added GCC inline assembler for context switching on x86 and MIPS32
+[up to 3x faster].
+
New targets for setjmp method:
+Mac OS X/x86, Solaris/x86 and x64 and Linux/MIPS32.
+
Workaround for WinXP problem with GetCurrentFiber().
+
The minimum C stack size has been increased to 32K+4K.
+
Removed lcocolib.c and integrated the (much smaller) changes
+into lbaselib.c.
+Note for embedders: this means you no longer need to call
+luaopen_coco().
+
Optional Valgrind support requires version 3.x.
+Renamed define to USE_VALGRIND.
+
C stacks are now registered with Valgrind.
+
+
+
Coco pre-release 51w6 — 2005-08-09
+
+This is the first pre-release of Coco. It targets Lua 5.1-work6 only
+and is no longer available for download.
+
+Coco needs some machine-specific features which are
+inherently non-portable. Although the coverage is pretty good,
+this means that Coco will probably never be a standard part
+of the Lua core (which is pure ANSI C).
+
+
+
Context Switching Methods
+
+Coco relies on four different machine-specific methods
+for allocating a C stack and switching context.
+The appropriate method is automatically selected at compile time.
+
+
+
GCC Inline Assembler
+
+This method is only available when GCC 3.x/4.x is used
+to compile the source.
+This is the fastest method for context switching, but only available
+for a few CPUs (see below).
+
+
+
Modified setjmp Buffer
+
+This method changes a few fields in the setjmp buffer to
+redirect the next longjmp to a new function with a new stack
+frame. It needs a bit of guesswork and lots of #ifdef's to
+handle the supported CPU/OS combinations, but this is quite
+manageable.
+
+
+This is the fallback method if inline assembler is not available.
+It's pretty fast because it doesn't have to save or restore signals
+(which is slow and generally undesirable for Lua coroutines).
+
+
+
POSIX ucontext
+
+The POSIX calls getcontext, makecontext and switchcontext
+are used to set up and switch between different C stacks.
+Although highly portable and even available for some
+esoteric platforms, it's slower than the setjmp method
+because it saves and restores signals, too (using at least one
+syscall for each context switch).
+
+
+You can force the use of ucontext (instead of setjmp) by enabling
+-DCOCO_USE_UCONTEXT in src/Makefile.
+
+
+
Windows Fibers
+
+This is the standard method to set up and switch between
+different C stacks on Windows. It's available on Windows 98
+and later.
+
+
+None of the other methods work for Windows because OS specific code
+is required to switch exception handling contexts.
+
+
+
Supported Platforms
+
+Coco has support for the following platforms:
+
+
+
+
CPU
+
System
+
Method
+
+
+
x86
(any OS)
gccasm
+
+
x86
Linux
setjmp
+
+
x86
FreeBSD
setjmp
+
+
x86
NetBSD
setjmp
+
+
x86
OpenBSD
setjmp
+
+
x86
Solaris
setjmp
+
+
x86
Mac OS X
setjmp
+
+
x64
(any OS)
gccasm
+
+
x64
Solaris
setjmp
+
+
MIPS32
(any OS)
gccasm
+
+
MIPS32
Linux
setjmp
+
+
ARM
Linux
setjmp
+
+
PPC32
Mac OS X
setjmp
+
+
(any CPU)
POSIX
ucontext
+
+
(any CPU)
Windows
fibers
+
+
+
+
+It should work pretty much anywhere where a correct
+POSIX ucontext implementation is available. It has been tested
+on every systems I could get hold of (e.g. Sparc, PPC32/PPC64,
+IA64, Alpha, HPPA with various operating systems).
+
+
+
Caveats
+
+
+Some older operating systems may have defective ucontext
+implementations because this feature is not widely used. E.g. some
+implementations don't mix well with other C library functions
+like malloc() or with native threads.
+This is really not the fault of Coco — please upgrade your OS.
+
+
+Note for Windows: Please read the explanation for the default
+» Thread Stack Size
+in case you want to create large numbers of Fiber-based coroutines.
+
+
+Note for MinGW/Cygwin: Older releases of GCC (before 4.0) generate
+wrong unwind information when -fomit-frame-pointer is used
+with stdcalls. This may lead to crashes when exceptions are thrown.
+The workaround is to always use two flags:
+-fomit-frame-pointer -maccumulate-outgoing-args.
+
+
+Note for MIPS CPUs without FPU: It's recommended to compile
+all sources with -msoft-float, even if you don't use
+any floating point ops anywhere. Otherwise context switching must
+save and restore FPU registers (which needs to go through
+the slow kernel emulation).
+
+
+To run Coco with » Valgrind
+(a memory debugger) you must add -DUSE_VALGRIND
+to MYCFLAGS and recompile. You will get random errors
+if you don't! Valgrind 3.x or later is required. Earlier versions
+do not work well with newly allocated C stacks.
+
+DynASM is a Dynamic Assembler for code generation
+engines.
+
+
+DynASM has been developed primarily as a tool for
+LuaJIT, but might be useful for other
+projects, too.
+
+
+If you are writing a just-in-time compiler or need to generate
+code on the fly (e.g. for high-performance graphics or other
+CPU-intensive computations), DynASM might be just what you
+are looking for.
+
+
+Please have a look at the list of Features
+to find out whether DynASM could be useful for your project.
+
+Sorry, right now there is no proper documentation available other
+than some Examples and of course
+the source code. The source is well documented, though (IMHO).
+
+
+I may add more docs in case someone actually finds DynASM to be
+useful outside of LuaJIT. If you do, I'd like to
+hear from you, please. Thank you!
+
+
+If you want to check it out please visit the
+» Download page and fetch the most recent
+version of LuaJIT. All you need is in the dynasm directory.
+For some complex examples take a peek at the
+*.dasc and *.dash files in LuaJIT, too.
+
+Note: yes, you usually get the assembler code as comments and proper
+CPP directives to match them up with the source. I've omitted
+them here for clarity. Oh and BTW: the pipe symbols probably
+line up much more nicely in your editor than in a browser.
+
+
+Here 123 is an offset into the action list buffer that
+holds the partially specified machine code. Without going
+into too much detail, the embedded C library implements a
+tiny bytecode engine that takes the action list as input and
+outputs machine code. It basically copies machine code snippets
+from the action list and merges them with the arguments
+passed in by dasm_put().
+
+
+The arguments can be any kind of C expressions. In practical
+use most of them evaluate to constants (e.g. structure offsets).
+Your C compiler should generate very compact code out of it.
+
+
+The embedded C library knows only what's absolutely needed to
+generate proper machine code for the target CPU (e.g. variable
+displacement sizes, variable branch offset sizes and so on).
+It doesn't have a clue about other atrocities like x86 opcode
+encodings — and it doesn't need to. This dramatically
+reduces the minimum required code size to around 2K [sic!].
+
+
+The action list buffer itself has a pretty compact encoding, too.
+E.g. the whole action list buffer for an early version of LuaJIT
+needs only around 3K.
+
+
+
Advanced Features
+
+Here's a real-life example taken from LuaJIT that shows some
+advanced features like type maps, macros and how to access
+C structures:
+
The toolchain is split into a portable subset and
+CPU-specific modules.
+
DynASM itself (the pre-processor) is written in Lua.
+
There is no machine-dependency for the pre-processor itself.
+It should work everywhere you can get Lua 5.1 up and running
+(i.e. Linux, *BSD, Solaris, Windows, ... you name it).
+
+
+
DynASM Assembler Features
+
+
C code and assembler code can be freely mixed.
+Readable, too.
+
All the usual syntax for instructions and operand modes
+you come to expect from a standard assembler.
+
Access to C variables and CPP defines in assembler statements.
+
Access to C structures and unions via type mapping.
+
Convenient shortcuts for accessing C structures.
+
Local and global labels.
+
Numbered labels (e.g. for mapping bytecode instruction numbers).
+
Multiple code sections (e.g. for tailcode).
+
Defines/substitutions (inline and from command line).
+
Conditionals (translation time) with proper nesting.
+
Macros with parameters.
+
Macros can mix assembler statements and C code.
+
Captures (output diversion for code reordering).
+
Simple and extensible template system for instruction definitions.
+
+
+
Restrictions
+
+Currently only a subset of x86 (i386+) instructions is supported.
+Unsupported instructions are either not usable in user-mode or
+are slow on modern CPUs (i.e. not suited for a code generator).
+SSE, SSE2, SSE3 and SSSE3 are fully supported. MMX is not supported.
+
+
+The whole toolchain has been designed to support multiple CPU
+architectures. As LuaJIT gets support for more architectures,
+DynASM will be extended with new CPU-specific modules.
+
+
+The assembler itself will be extended with more features on an
+as-needed basis. E.g. I'm thinking about vararg macros.
+
+
+Note that runtime conditionals are not really needed, since you can
+just use plain C code for that (and LuaJIT does this a lot).
+It's not going to be more (time-) efficient if conditionals are done
+by the embedded C library (maybe a bit more space-efficient).
+
+DynASM —
+a Dynamic Assembler for code generation engines.
+
+
+
+
+
+
More ...
+
+Please click on one of the links in the navigation bar to your left
+to learn more.
+
+
+Click on the Logo in the upper left corner to visit
+the LuaJIT project page on the web. All other links to online
+resources are marked with a '»'.
+
+LuaJIT is a Just-In-Time Compiler for the Lua
+programming language.
+
+
+Lua is a powerful, light-weight programming language designed
+for extending applications. Lua is also frequently used as a
+general-purpose, stand-alone language. More information about
+Lua can be found at: » http://www.lua.org/
+
+
+LuaJIT 1.x is based on the Lua 5.1.x virtual machine and bytecode interpreter
+from lua.org. It compiles bytecode to native x86 (i386+) machine code
+to speed up the execution of Lua programs.
+
+
+LuaJIT depends on Coco to allow yielding
+from coroutines for JIT compiled functions. Coco is part of the
+LuaJIT distribution.
+
+All standard library functions have the same behaviour as
+in the Lua distribution LuaJIT is based on.
+
+
+The Lua loader used by the standard require() library
+function has been modified to turn off compilation of the main
+chunk of a module. The main chunk is only run once when the module
+is loaded for the first time. There is no point in compiling it.
+
+
+You might want to adapt this behaviour if you use your own utility
+functions (and not require()) to load modules.
+
+
+Note that the subfunctions defined in a loaded module are
+of course compiled. See below if you want to override this.
+
+
+
The jit.* Library
+
+This library holds several functions to control the behaviour
+of the JIT engine.
+
+
+
jit.on()
+jit.off()
+
+Turns the JIT engine on (default) or off.
+
+
+These functions are typically used with the command line options
+-j on or -j off.
+
+Enable (with jit.on, default) or disable (with jit.off)
+JIT compilation for a Lua function. The current function (the Lua function
+calling this library function) can be specified with true.
+
+
+If the second argument is true, JIT compilation is also
+enabled/disabled recursively for all subfunctions of a function.
+With false only the subfunctions are affected.
+
+
+Both library functions only set a flag which is checked when
+the function is executed for the first/next time. They do not
+trigger immediate compilation.
+
+
+Typical usage is jit.off(true, true) in the main chunk
+of a module to turn off JIT compilation for the whole module.
+Note that require() already turns off compilation for
+the main chunk itself.
+
+
+
status = jit.compile(func [,args...])
+
+Compiles a Lua function and returns the compilation status.
+Successful compilation is indicated with a nil status.
+Failure is indicated with a numeric status (see jit.util.status).
+
+
+The optimizer pass of the compiler tries to derive hints from the
+passed arguments. Not passing any arguments or passing untypical
+arguments (esp. the wrong types) reduces the efficiency of the
+optimizer. The compiled function will still run, but probably not
+with maximum speed.
+
+
+This library function is typically used for Ahead-Of-Time (AOT)
+compilation of time-critical functions or for testing/debugging.
+
+
+
status = jit.compilesub(func|true [,true])
+
+Recursively compile all subfunctions of a Lua function.
+The current function (the Lua function calling this library function)
+can be specified with true. Note that the function
+itself is not compiled (use jit.compile()).
+
+
+If the second argument is true, compilation will stop
+when the first error is encountered. Otherwise compilation will
+continue with the next subfunction.
+
+
+The returned status is nil, if all subfunctions have been
+compiled successfully. A numeric status (see jit.util.status)
+indicates that at least one compilation failed and gives the status
+of the last failure (this is only helpful when stop on error
+is true).
+
+
+
jit.debug([level])
+
+Set the debug level for JIT compilation. If no level is given,
+the maximum debug level is set.
+
+
+
Level 0 disables debugging: no checks for hooks are compiled
+into the code. This is the default when LuaJIT is started and
+provides the maximum performance.
+
Level 1 enables function call debugging: call hooks and
+return hooks are checked in the function prologue and epilogue.
+This slows down function calls somewhat (by up to 10%).
+
Level 2 enables full debugging: all hooks are checked.
+This slows down execution quite a bit, even when the hooks
+are not active.
+
+
+Note that some compiler optimizations are turned off when
+debugging is enabled.
+
+
+This function is typically used with the command line options
+-j debug or -j debug=level.
+
+
+
jit.attach(handler [, priority])
+
+Attach a handler to the compiler pipeline with the given priority.
+The handler is detached if no priority is given.
+
+
+The inner workings of the compiler pipeline and the API for handlers
+are still in flux. Please see the source code for more details.
+
+
+
jit.version
+
+Contains the LuaJIT version string.
+
+
+
jit.version_num
+
+Contains the version number of the LuaJIT core. Version xx.yy.zz
+is represented by the decimal number xxyyzz.
+
+
+
jit.arch
+
+Contains the target architecture name (CPU and optional ABI).
+
+
+
+
The jit.util.* Library
+
+This library holds many utility functions used by the provided
+extension modules for LuaJIT (e.g. the optimizer). The API may
+change in future versions.
+
+
+
stats = jit.util.stats(func)
+
+Retrieves information about a function. Returns nil
+for C functions. Returns a table with the following fields for
+Lua functions:
+
+
+
status: numeric compilation status (see jit.util.status).
+
stackslots: number of stack slots.
+
params: number of fixed parameters (arguments).
+
consts: number of constants.
+
upvalues: number of upvalues.
+
subs: number of subfunctions (sub prototypes).
+
bytecodes: number of bytecode instructions.
+
isvararg: fixarg (false) or vararg (true) function.
+
env: function environment table.
+
mcodesize: size of the compiled machine code.
+
mcodeaddr: start address of the compiled machine code.
+
+
+mcodesize and mcodeaddr are not set if the
+function has not been compiled (yet).
+
+
+
op, a, b, c, test = jit.util.bytecode(func, pc)
+
+Returns the fields of the bytecode instruction at the given pc
+for a Lua function. The first instruction is at pc = 1.
+Nothing is returned if pc is out of range.
+
+
+The opcode name is returned as an uppercase string in op.
+The opcode arguments are returned as a, b and
+optionally c. Arguments that indicate an index into the
+array of constants are translated to negative numbers (the first
+constant is referred to with -1). Branch targets are signed numbers
+relative to the next instruction.
+
+
+test is true if the instruction is a test (i.e. followed
+by a JMP).
+
+
+
const, ok = jit.util.const(func, idx)
+
+Returns a constant from the array of constants for a Lua function.
+ok is true if idx is in range. Otherwise nothing
+is returned.
+
+
+Constants are numbered starting with 1. A negative idx
+is mapped to a positive index.
+
+
+
upvalue, ok = jit.util.upvalue(func, idx)
+
+Returns an upvalue from the array of upvalues for a Lua function.
+ok is true if idx is in range. Otherwise nothing
+is returned. Upvalues are numbered starting with 0.
+
+
+
nup = jit.util.closurenup(func, idx)
+
+Returns the number of upvalues for the subfunction prototype with
+the given index idx for a Lua function. Nothing is returned
+if idx is out of range. Subfunctions are numbered starting
+with 0.
+
+Returns the numeric start address, the compiled machine code
+(converted to a string) and an iterator for the machine code fragment map
+for the specified machine code block associated with a Lua function.
+
+
+Returns nil and a numeric status code (see jit.util.status)
+if the function has not been compiled yet or compilation has failed
+or compilation is disabled. Returns nothing if the selected
+machine code block does not exist.
+
+
+The machine code fragment map is used for debugging and error handling.
+The format may change between versions and is an internal implementation
+detail of LuaJIT.
+
+
+
addr [, mcode] = jit.util.jsubmcode([idx])
+
+If idx is omitted or nil:
+Returns the numeric start address and the compiled machine code
+(converted to a string) for internal subroutines used by the
+compiled machine code.
+
+
+If idx is given:
+Returns the numeric start address of the machine code for a specific
+internal subroutine (0 based). Nothing is returned if idx is
+out of range.
+
+
+
jit.util.status
+
+This is a table that bidirectionally maps status numbers and
+status names (strings):
+
+
+
+
Status Name
Description
+
OK
Ok, code has been compiled.
+
NONE
Nothing analyzed or compiled, yet (default).
+
OFF
Compilation disabled for this function.
+
ENGINE_OFF
JIT engine is turned off.
+
DELAYED
Compilation delayed (recursive invocation).
+
TOOLARGE
Bytecode or machine code is too large.
+
COMPILER_ERROR
Error from compiler frontend.
+
DASM_ERROR
Error from DynASM engine.
+
+
+
+
jit.util.hints
+jit.util.fhints
+
+These two tables map compiler hint names to internal hint numbers.
+
+
+The hint system is an internal implementation detail of LuaJIT.
+Please see the source code for more info.
+
Remove a (sometimes) wrong assertion in luaJIT_findpc().
+
DynASM now allows labels for displacements and .aword.
+
Fix some compiler warnings for DynASM glue (internal API change).
+
Correct naming for SSSE3 (temporarily known as SSE4) in DynASM and x86 disassembler.
+
The loadable debug modules now handle redirection to stdout
+(e.g. -j trace=-).
+
+
+
LuaJIT 1.1.2 — 2006-06-24
+
+
Fix MSVC inline assembly: use only local variables with
+lua_number2int().
+
Fix "attempt to call a thread value" bug on Mac OS X:
+make values of consts used as lightuserdata keys unique
+to avoid joining by the compiler/linker.
The C stack is kept 16 byte aligned (faster).
+Mandatory for Mac OS X on Intel, too.
+
Faster calling conventions for internal C helper functions.
+
Better instruction scheduling for function prologue, OP_CALL and
+OP_RETURN.
+
+
+
Miscellaneous optimizations:
+
+
Faster loads of FP constants. Remove narrow-to-wide store-to-load
+forwarding stalls.
+
Use (scalar) SSE2 ops (if the CPU supports it) to speed up slot moves
+and FP to integer conversions.
+
Optimized the two-argument form of OP_CONCAT (a..b).
+
Inlined OP_MOD (a%b).
+With better accuracy than the C variant, too.
+
Inlined OP_POW (a^b). Unroll x^k or
+use k^x = 2^(log2(k)*x) or call pow().
+
+
+
Changes in the optimizer:
+
+
Improved hinting for table keys derived from table values
+(t1[t2[x]]).
+
Lookup hinting now works with arbitrary object types and
+supports index chains, too.
+
Generate type hints for arithmetic and comparison operators,
+OP_LEN, OP_CONCAT and OP_FORPREP.
+
Remove several hint definitions in favour of a generic COMBINE hint.
+
Complete rewrite of jit.opt_inline module
+(ex jit.opt_lib).
+
+
+
Use adaptive deoptimization:
+
+
If runtime verification of a contract fails, the affected
+instruction is recompiled and patched on-the-fly.
+Regular programs will trigger deoptimization only occasionally.
+
This avoids generating code for uncommon fallback cases
+most of the time. Generated code is up to 30% smaller compared to
+LuaJIT 1.0.3.
+
Deoptimization is used for many opcodes and contracts:
+
+
OP_CALL, OP_TAILCALL: type mismatch for callable.
+
Inlined calls: closure mismatch, parameter number and type mismatches.
+
OP_GETTABLE, OP_SETTABLE: table or key type and range mismatches.
+
All arithmetic and comparison operators, OP_LEN, OP_CONCAT,
+OP_FORPREP: operand type and range mismatches.
+
+
Complete redesign of the debug and traceback info
+(bytecode ↔ mcode) to support deoptimization.
+Much more flexible and needs only 50% of the space.
+
The modules jit.trace, jit.dumphints and
+jit.dump handle deoptimization.
+
+
+
Inlined many popular library functions
+(for commonly used arguments only):
+
+
Most math.* functions (the 18 most used ones)
+[2x-10x faster].
+
string.len, string.sub and string.char
+[2x-10x faster].
+
table.insert, table.remove and table.getn
+[3x-5x faster].
+
coroutine.yield and coroutine.resume
+[3x-5x faster].
+
pairs, ipairs and the corresponding iterators
+[8x-15x faster].
+
+
+
Changes in the core and loadable modules and the stand-alone executable:
+
+
Added jit.version, jit.version_num
+and jit.arch.
+
Reorganized some internal API functions (jit.util.*mcode*).
+
The -j dump output now shows JSUB names, too.
+
New x86 disassembler module written in pure Lua. No dependency
+on ndisasm anymore. Flexible API, very compact (500 lines)
+and complete (x87, MMX, SSE, SSE2, SSE3, SSSE3, privileged instructions).
+
luajit -v prints the LuaJIT version and copyright
+on a separate line.
+
+
+
Added SSE, SSE2, SSE3 and SSSE3 support to DynASM.
+
Miscellaneous doc changes. Added a section about
+embedding LuaJIT.
+LuaJIT is a rather complex application. There will undoubtedly
+be bugs lurking in there. You have been warned. :-)
+
+
+If you came here looking for information on how to debug
+your application (and not LuaJIT itself) then please
+check out jit.debug()
+and the -j debug
+command line option.
+
+
+But if you suspect a problem with LuaJIT itself, then try
+any of the following suggestions (in order).
+
+
+
Is LuaJIT the Problem?
+
+Try to run your application in several different ways:
+
+
+
luajit app.lua
+
luajit -O1 app.lua
+
luajit -O app.lua
+
luajit -j off app.lua
+
lua app.lua (i.e. with standard Lua)
+
+
+If the behaviour is the same as with standard Lua then ...
+well ... that's what LuaJIT is about: doing the same things,
+just faster. Even bugs fly faster. :-)
+
+
+So this is most likely a bug in your application then. It may be easier
+to debug this with plain Lua — the remainder of this page
+is probably not helpful for you.
+
+
+But if the behaviour is different, there is some likelihood
+that you caught a bug in LuaJIT. Oh dear ...
+
+
+Ok, so don't just give up. Please read on and help the community
+by finding the bug. Thank you!
+
+Please check if a newer version is available. Maybe the bug
+you have encountered has been fixed already. Always download the
+latest version and try it with your application before continuing.
+
+
+
Reproduce the Bug
+
+First try to make the bug reproducible. Try to isolate the module
+and the function the bug occurs in:
+
+
+Either selectively turn off compilation for some modules with
+ jit.off(true, true)
+until the bug disappears ...
+
+
+And/or turn the whole JIT engine off and selectively compile
+functions with
+ jit.compile(func)
+until it reappears.
+
+
+If you have isolated the point where it happens, it's most helpful
+to reduce the affected Lua code to a short code snippet that
+still shows the problem. You may need to print() some
+variables until you can pinpoint the exact spot where it happens.
+
+
+If you've got a reproducible and short test
+you can either send it directly to me or the mailing list
+(see the Contact Information)
+or you can try to debug this a bit further.
+
+
+Well — if you are brave enough. :-)
+
+
+
Look at the Generated Code
+
+You may want to have a look at the output of -j dumphints
+first. Try to change things around until you can see which hint
+or which instruction is the cause of the bug. If you suspect
+an optimizer bug then have a look at the backend (*.das[ch])
+and check how the hint is encoded.
+
+
+Otherwise have a look at -j dump and see whether
+you can spot the problem around the affected instruction.
+It's helpful to have a good knowledge of assembler, though
+(sorry).
+
+
+
Locate a Crash
+
+If you get a crash, you should compile LuaJIT with debugging
+turned on:
+
+
+Add -g to CFLAGS and MYLDFLAGS
+or whatever is needed to turn on debugging. For Windows you
+need both an executable and a DLL built with debugging.
+
+
+Then start LuaJIT with your debugger. Run it with
+-j dump=test.dump.
+
+
+Have a look at the backtrace and compare it with the generated
+dump file to find out exactly where it crashes. I'm sorry, but
+symbols or instructions for JIT compiled functions are not
+displayed in your debugger (this is really hard to solve).
+
+
+
Turn on Assertions
+
+Another way to debug LuaJIT is to turn on assertions.
+They can be turned on only for the JIT engine by adding
+-DLUAJIT_ASSERT to JITCFLAGS in src/Makefile.
+Then recompile with make clean and make.
+
+
+Add these two lines to src/luaconf.h to turn on all assertions in the Lua core:
+ #include <assert.h>
+ #define lua_assert(x) assert(x)
+This turns on the JIT engine assertions, too.
+Recompile and see whether any assertions trigger.
+Don't forget to turn off the (slow) assertions when you're done!
+
+
+
Use Valgrind
+
+A tremendously useful (and free) tool for runtime code analysis
+is » Valgrind. Regularly
+run your applications with valgrind --memcheck and
+your life will be better.
+
+
+To run LuaJIT under Valgrind you must add
+-DUSE_VALGRIND to MYCFLAGS
+and recompile LuaJIT. You will get random errors if you don't!
+Valgrind 3.x or later is required. Earlier versions
+do not work well with newly allocated C stacks.
+
+
+An executable built with this option runs fine without Valgrind
+and without a performance loss. But it needs the Valgrind header
+files for compilation (which is why it's not enabled by default).
+
+
+It's helpful to compile LuaJIT with debugging turned on, too
+(see above).
+
+
+If Valgrind spots many invalid memory accesses that involve
+memory allocation/free functions you've probably found a bug
+related to garbage collection. Some object reference must have
+gone astray.
+
+
+Try to find out which object is disappearing. You can force
+eager garbage collection with repeated calls to
+collectgarbage() or by setting a very low threshold
+with collectgarbage("setpause", 1).
+
+
+
Don't Despair
+
+If all of this doesn't help to find the bug, please send
+a summary of your findings to the mailing list. Describe as much
+of the circumstances you think are relevant.
+
+
+Please don't send your whole application to me
+(without asking first) and especially not to the mailing list.
+Code snippets should preferrably be less than 50 lines and
+up to the point.
+
+
+All bug reports are helpful, even if no immediate solution
+is available. Often enough someone else finds the same bug
+in a different setting and together with your bug report
+this may help to track it down.
+
+
+Finally I have to say a BIG THANK YOU
+to everyone who has helped to make LuaJIT better by finding
+and fixing bugs!
+
Adaptive deoptimization is used to recompile individual bytecode
+instructions with broken contracts. This avoids generating code for the
+generic fallback cases most of the time (faster compilation, reduced
+I-cache contention).
+
Special CPU features (such as conditional moves or SSE2)
+are automatically used when detected.
+
+
+The JIT compiler is very fast:
+
+
+
Compilation times vary a great deal (depending on the nature of
+the function to be compiled) but are generally in the
+microsecond range.
+
Even compiling large functions (hundreds of lines) with the
+maximum optimization level takes only a few milliseconds in the
+worst case.
+
+
+LuaJIT is very small:
+
+
+
The whole JIT compiler engine adds only around 32K
+of code to the Lua core (if compiled with -Os).
+
The optimizer is split into several optional modules that
+can be loaded at runtime if requested.
+
LuaJIT adds around 6.000 lines of C and assembler code and
+2.000 lines of Lua code to the Lua 5.1 core (17.000 lines of C).
+
Required build tools (DynASM)
+take another 2.500 lines of Lua code.
+
+
+
Compatibility
+
+LuaJIT is designed to be fully compatible with Lua 5.1.
+It accepts the same source code and/or precompiled bytecode.
+It supports all standard language semantics. In particular:
+
+
+
All standard types, operators and metamethods are supported.
+
Implicit type coercions (number/string) work as expected.
+
Full IEEE-754 semantics for floating point arithmetics
+(NaN, +-Inf, +-0, ...).
+
Full support for lexical closures.
+Proper tail calls do not consume a call frame.
No changes to the Lua 5.1 incremental garbage collector.
+
No changes to the standard Lua/C API.
+
Dynamically loaded C modules are link compatible with Lua 5.1
+(same ABI).
+
LuaJIT can be embedded
+into an application just like Lua.
+
+
+Some minor differences are related to debugging:
+
+
+
Debug hooks are only called if debug code generation is enabled.
+
There is no support for tailcall counting in JIT compiled code.
+HOOKTAILRET is not called, too. Note: this won't affect you unless
+you are writing a Lua debugger. *
+
+
+* There is not much I can do to improve this situation without undue
+complications. A suggestion to modify the behaviour of standard Lua
+has been made on the mailing list (it would be beneficial there, too).
+
+
+
Restrictions
+
+
Only x86 (i386+) CPUs are supported right now (but see below).
+
Only the default type for lua_Number is supported
+(double).
+
The interrupt signal (Ctrl-C) is ignored unless you enable
+debug hooks (with -j debug). But this will seriously
+slow down your application. I'm looking for better ways to handle
+this. In the meantime you have to press Ctrl-C twice to interrupt
+a currently running JIT compiled function (just like C functions).
+
GDB, Valgrind and other debugging tools can't report symbols
+or stack frames for JIT compiled code. This is rather difficult to solve.
+Have a look at Debugging LuaJIT, too.
+
+
+
Caveats
+
+
LuaJIT allocates executable memory for the generated machine code
+if your OS has support for it: either HeapCreate() for Windows or
+mmap() on POSIX systems.
+The fallback is the standard Lua allocator (i.e. malloc()).
+But this usually means the allocated memory is not marked executable.
+Running compiled code will trap on CPUs/OS with the NX (No eXecute)
+extension if you can only use the fallback.
+
DynASM is needed to regenerate the
+ljit_x86.h file. But only in case you want to modify
+the *.dasc/*.dash files. A pre-processed *.h
+file is supplied with LuaJIT.
+DynASM is written in Lua and needs a plain copy of Lua 5.1
+(installed as lua). Or you can run it with LuaJIT built from
+the *.h file supplied with the distribution (modify
+DASM= in src/Makefile). It's a good idea to install
+a known good copy of LuaJIT under a different name for this.
+
LuaJIT ships with LUA_COMPAT_VARARG turned off.
+I.e. the implicit arg parameter is not created anymore.
+Please have a look at the comments in luaconf.h for
+this configuration option. You can turn it on, if you really need it.
+Or better yet, convert your code to the new Lua 5.1 vararg syntax.
+LuaJIT is not much more difficult to install than Lua itself.
+Just unpack the distribution file, change into the newly created
+directory and follow the instructions below.
+
+
+For the impatient: make linux && sudo make install
+Replace linux with e.g. bsd or macosx depending on your OS.
+
+
+In case you've missed this in Features:
+LuaJIT only works on x86 (i386+) systems right now. Support for
+other architectures may be added in future versions.
+
+
+
Configuring LuaJIT
+
+LuaJIT is (deliberately) not autoconfigured — the
+defaults should work fine on most systems. But please check the
+system-specific instructions below.
+
+
+The following three files hold all configuration information:
+
+
+
Makefile holds settings for installing LuaJIT.
+
src/Makefile holds settings for compiling LuaJIT.
+
src/luaconf.h sets a multitude of configuration
+variables.
+
+
+If this is your first build then it's better not to give into
+the temptation to tweak every little setting. The standard
+configuration provides sensible defaults (IMHO).
+
+
+One particular setting you might want to change is the installation
+path. Note that you need to modify both the top-level Makefile
+and src/luaconf.h (right at the start) to take
+effect.
+
+
+If you have trouble getting Coco to work, you can disable it by
+uncommenting the COCOFLAGS= -DCOCO_DISABLE line in
+src/Makefile. But note that this effectively disables
+yielding from coroutines for JIT compiled functions.
+
+
+A few more settings need to be changed if you want to
+Debug LuaJITitself.
+Application debugging can be turned on/off at runtime.
+
+
+
Upgrading From Previous Versions
+
+It's important to keep the LuaJIT core and the add-on modules in sync.
+Be sure to delete any old versions of LuaJIT modules from the
+Lua module search path (check the current directory, too!).
+
+
+Lua files compiled to bytecode may be incompatible if the underlying
+Lua core has changed (like from Lua 5.1 alpha to Lua 5.1
+final between LuaJIT 1.0.3 and LuaJIT 1.1.0). The same
+applies to any
+» loadable C modules
+(shared libraries, DLLs) which need to be recompiled with the new
+Lua header files.
+
+
+Compiled bytecode and loadable C modules are fully compatible and
+can be freely exchanged between LuaJIT and the same
+version of Lua it is based on. Please verify that LUA_RELEASE
+in src/lua.h is the same in both distributions.
+
+
+
Building LuaJIT
+
+
Makefile Targets
+
+The Makefiles have a number of targets for various operating systems:
+
+You may want to enable interactive line editing for the stand-alone
+executable. There are extra targets for Linux, BSD and Mac OS X:
+make linux_rl, make bsd_rl
+and make macosx_rl.
+
+
+
MSVC (Win32)
+
+First check out etc\luavs.bat if it suits your needs. Then try
+running it from the MSVC command prompt (start it from the toplevel directory).
+
+
+Another option is to set up your own MSVC project:
+
+
+Change to the src directory
+and create a new DLL project for lua51.dll.
+Add all C files to it except for lua.c, luac.c
+and print.c. Add the ..\dynasm directory
+to the include path and build the DLL.
+
+
+Next create a new EXE project for luajit.exe.
+Add lua.c to it and link with the import library
+lua51.lib created for lua51.dll. Build
+the executable.
+
+
+
Installation
+
+
POSIX systems
+
+Run make install from the top-level directory.
+You probably need to be the root user before doing so, i.e. use
+sudo make install or su - root
+before the make install.
+
+
+By default this installs only:
+ /usr/local/bin/luajit — The stand-alone executable.
+ /usr/local/lib/lua/5.1 — C module directory.
+ /usr/local/share/lua/5.1 — Lua module directory.
+ /usr/local/share/lua/5.1/jit/*.lua —
+jit.* modules.
+
+
+The Lua docs and includes are not installed to avoid overwriting
+an existing Lua installation. In any case these are identical
+to the version of Lua that LuaJIT is based on. If you want
+to install them, edit the top-level makefile (look for ###).
+
+
+The stand-alone Lua bytecode compiler luac is neither
+built nor installed, for the same reason. If you really need it,
+you may be better off with luac built from the original Lua
+distribution (use the same version your copy of LuaJIT
+is based on). This avoids dragging in most of LuaJIT which is not
+needed for the pure bytecode compiler. You can also use the bare-bones
+Lua to bytecode translator luac.lua (look in the test
+directory of the original Lua distribution).
+
+
+
Windows
+
+Copy luajit.exe and lua51.dll
+to a newly created directory (any location is ok). Add lua
+and lua\jit directories below it and copy all Lua files
+from the jit directory of the distribution to the latter directory.
+
+
+There are no hardcoded
+absolute path names — all modules are loaded relative to the
+directory where luajit.exe is installed
+(see src/luaconf.h).
+
+
+
Embedding LuaJIT
+
+It's strongly recommended that you build the stand-alone executable
+with your toolchain and verify that it works before starting
+to embed LuaJIT into an application. The stand-alone executable is
+also useful later on, when you want to experiment with code snippets
+or try out some Lua files.
+
+
+Please consult the Lua docs for general information about how to
+embed Lua into your application. The following list only shows
+the additional steps needed for embedding LuaJIT:
+
+
+
You need to add the LuaJIT library functions by running
+luaopen_jit() after all the other standard library functions.
+The modified src/linit.c used by the stand-alone executable
+already does this for you.
+
Caveat: LuaJIT is based on Lua 5.1 which
+means the luaopen_*() functions must not
+be called directly. See src/linit.c for the proper way to
+run them. You'll get an error initializing the io library
+if you don't follow these instructions.
+
To use the optimizer (strongly recommended) you need to:
+
+
Install the optimizer modules jit.opt and
+jit.opt_inline relative to the Lua module path
+(you've probably modified it — see src/luaconf.h):
+jit/opt.lua
+jit/opt_inline.lua
+
If you want to ship a single executable then you may want to
+embed the optimizer modules into your application (but don't loose
+time with this during the early development phase). This involves:
+
+
Compile the two modules to bytecode
+(using luac -s from a plain Lua installation).
+
Convert them to C include files (search for "Lua bin2c").
+
On Windows you can also put the compiled bytecode into a resource
+(search for "Lua bin2res").
+
Load the bytecode with luaL_loadbuffer (but don't run it).
+
Put the resulting functions into package.preload["jit.opt"]
+and package.preload["jit.opt_inline"].
+
+
Activate the LuaJIT optimizer from Lua code to be run at startup:
+ require("jit.opt").start()
+Or use equivalent C code. See dojitopt() in src/lua.c.
+
+
All other LuaJIT specific modules (jit.*) are for debugging only.
+They do not need to be shipped with an application. But they may be quite
+useful, anyway (especially jit.trace).
+
DynASM is only needed while building LuaJIT. It's not
+needed while running LuaJIT and there is no point in shipping or
+installing it together with an application.
+
In case you want to strip some of the standard libraries from
+your application: The optimizer modules need several functions from
+the base library and the string library (and of course the LuaJIT
+core libraries). The io library is only used to print a fatal error
+message (you may want to replace it). The optional modules
+for debugging depend on a few more library functions —
+please check the source.
+
+
+Although the very liberal LuaJIT
+» license
+does not require any acknowledgment whatsoever, it would be appreciated
+if you give some credit in the docs (or the "About" box) of your application.
+A simple line like:
+ This product includes LuaJIT, http://luajit.org/
+would be nice. Please do not include any E-Mail addresses. Thank you!
+
+
+I'm always interested where LuaJIT can be put to good use in applications.
+Please tell me
+or better yet write a few lines about your project to the
+» Lua mailing list.
+Thank you!
+
+This is a little essay that tries to answer the question:
+'So, how does LuaJIT really work?'.
+
+
+I tried to avoid going into all the gory details, but at the
+same time provide a deep enough explanation, to let you find
+your way around LuaJIT's inner workings.
+
+
+The learning curve is maybe a little bit steep for newbies and
+compiler gurus will certainly fall asleep after two paragraphs.
+It's difficult to strike a balance here.
+
+
+
Acronym Soup
+
+As the name says LuaJIT is a Just-In-Time (JIT) compiler.
+This means that functions are compiled on demand, i.e. when they
+are run first. This ensures both a quick application startup
+and helps to avoid useless work, too. E.g. unused functions
+are not compiled at all.
+
+
+The other alternative is known as Ahead-Of-Time (AOT)
+compilation. Here everything is compiled before running any function.
+This is the classic way for many languages, such as C or C++.
+
+
+In fact plain Lua allows you to pre-compile Lua source code into
+Lua bytecode and store it in a binary file that can be run
+later on. This is used only in specific settings (e.g. memory limited
+embedded systems), because the Lua bytecode compiler is really fast.
+The ability to run source files right away is part of what makes
+a dynamic language (aka scripting language) so powerful.
+
+
+JIT compilation has a few other advantages for dynamic languages
+that AOT compilation can only provide with a massive amount
+of code analysis. More can be found in the literature.
+One particular advantage is explained later.
+
+
+
Quick, JIT — Run!
+
+JIT compilation happens mostly invisible. You'll probably never
+notice that a compilation is going on. Part of the secret is
+that everything happens in little pieces intermixed with running
+the application itself inbetween. The other part of the secret
+is that JIT compilation can be made pretty fast.
+
+
+Most applications quickly converge to a stable state where
+everything that really needs to be compiled is compiled
+right away. Only occasional isolated compiles happen later on.
+
+
+Even though the name doesn't suggest it, LuaJIT can operate
+in AOT mode, too. But this is completely under user control
+(see jit.compile())
+and doesn't happen automatically.
+
+
+Unless you have good reason to suspect that AOT compilation
+might help for a specific application, I wouldn't bother though.
+Compilation speed is usually a non-argument, because LuaJIT
+is extremely fast. Compilation times are typically in the
+microsecond range for individual Lua functions.
+
+
+
Starting Up
+
+The next few paragraphs may not be exactly breaking news to you,
+if you are familiar with JIT compilers. Still, please read on,
+because some terms are introduced that are used later on.
+
+
+When you start LuaJIT everything proceeds like in standard Lua:
+the Lua core is initialized, the standard libraries are loaded and
+the command line is analyzed. Then usually the first Lua source
+code file is loaded and is translated to Lua bytecode. And finally
+the function for the initial main chunk is run ...
+
+
+
Kicking the Compiler
+
+This is where LuaJIT kicks in:
+
+
+All Lua functions carry an additional status code for LuaJIT.
+Initially this is set to 'NONE', i.e. the function has not been
+looked at (yet). If a function is run with this setting,
+the LuaJIT compiler pipeline is started up.
+
+
+If you haven't loaded any special LuaJIT modules and optimization
+is not turned on, the compiler pipeline only consists of the
+compiler backend.
+
+
+The compiler backend is the low-level encoding engine that translates
+bytecode instructions to machine code instructions. Without any
+further hints from other modules, the backend more or less does a
+1:1 translation. I.e. a single variant of a bytecode instruction
+corresponds to a single piece of machine code.
+
+
+If all goes well, these little code pieces are put together,
+a function prologue is slapped on and voila: your Lua function
+has been translated to machine code. Of course things are not
+that simple when you look closer, but hey — this is
+the theory.
+
+
+Anyway, the status code for the function is set to 'OK' and the
+machine code is run. If this function runs another Lua function
+which has not been compiled, that one is compiled, too. And so on.
+
+
+
Call Gates
+
+Ok, so what happens when a function is called repeatedly? After all
+this is the most common case.
+
+
+Simple: The status code is checked again. This time it's set to 'OK',
+so the machine code can be run directly. Well — that's not the
+whole truth: for calls that originate in a JIT compiled function
+a better mechanism, tentatively named call gates is used.
+
+
+Every function has a call gate field (a function pointer). By default
+it's set to a function that does the above checks and runs the
+compiler. But as soon as a function is compiled, the call gate
+is modified to point to the just compiled machine code.
+
+
+Calling a function is then as easy as calling the code that the
+call gate points to. But due to special (faster) calling conventions
+this function pointer cannot be used directly from C. So calls from
+a non-compiled function or from a C function use an extra entry
+call gate which in turn calls the real call gate. But this is
+really a non-issue since most calls in typical applications
+are intra-JIT calls.
+
+
+
The Compiler Pipeline
+
+The compiler pipeline has already been mentioned. This sounds
+more complicated than it is. Basically this is a coroutine that
+runs a frontend function which in turn calls all functions
+from the pipeline table.
+
+
+The pipeline table is sorted by priorities. The standard
+backend has priority 0. Positive priorities are run before the
+backend and negative priorities are run after the backend. Modules
+can dynamically attach or detach themselves to the pipeline with
+the library function jit.attach().
+
+
+So a typical optimizer pass better have a positive priority,
+because it needs to be run before the backend is run. E.g. the
+LuaJIT optimizer module registers itself with priority 50.
+
+
+On the other hand a typical helper module for debugging —
+a machine code disassembler — needs to be run after the
+backend and is attached with a negative priority.
+
+
+One special case occurs when compilation fails. This can be due to
+an internal error (ouch) or on purpose. E.g. the optimizer module
+checks some characteristics of the function to be compiled and
+may decide that it's just not worth it. In this case a status
+other than OK is passed back to the pipeline frontend.
+
+
+The easiest thing would be to abort pipeline processing and just
+give up. But this would remove the ability to trace the progress
+of the compiler (which better include failed compilations, too).
+So there is a special rule that odd priorities are still run,
+but even priorities are not. That's why e.g. -j trace
+registers itself with priority -99.
+
+
+
The Optimizer
+
+Maybe it hasn't become clear from the above description,
+but a module can attach any Lua or C function to the compiler
+pipeline. In fact all of the loadable modules are Lua modules.
+Only the backend itself is written in C.
+
+
+So, yes — the LuaJIT optimizer is written in pure Lua!
+
+
+And no, don't worry, it's quite fast. One reason for this is
+that a very simple abstract interpretation algorithm
+is used. It mostly ignores control flow and/or basic block
+boundaries.
+
+
+Thus the results of the analysis are really only hints.
+The backend must check the preconditions (the contracts)
+for these hints (e.g. the object type). Still, the generated
+hints are pretty accurate and quite useful to speed up the
+compiled code (see below).
+
+
+Explaining how abstract interpretation works is not within the
+scope for this short essay. You may want to have a look at the
+optimizer source code and/or read some articles or books on
+this topic. The canonical reference is
+» Principles of Program Analysis.
+Ok, so this one is a bit more on the theoretical side (a gross
+understatement). Try a search engine with the keywords "abstract
+interpretation", too.
+
+
+Suffice to say the optimizer generates hints and passes these
+on to the backend. The backend then decides to encode different
+forms for the same bytecode instruction, to combine several
+instructions or to inline code for C functions. If the hints
+from the optimizer are good, the resulting code will perform
+better because shorter code paths are used for the typical cases.
+
+
+
The JIT Advantage
+
+One important feature of the optimizer is that it takes 'live'
+function arguments into account. Since the JIT compiler is
+called just before the function is run, the arguments for this
+first invocation are already present. This can be used to great
+advantage in a dynamically typed language, such as Lua.
+
+
+Here's a trivial example:
+
+
+function foo(t, k)
+ return t[k]
+end
+
+
+Without knowing the most likely arguments for the function
+there's not much to optimize.
+
+
+Ok, so 't' is most likely a table. But it could be userdata, too.
+In fact it could be any type since the introduction of generic
+metatables for types.
+
+
+And more importantly 'k' can be a number, a string
+or any other type. Oh and let's not forget about metamethods ...
+
+
+If you know a bit about Lua internals, it should be clear by now
+that the code for this function could potentially branch to half
+of the Lua core. And it's of course impossible to inline all
+these cases.
+
+
+On the other hand if it's known (or there's a good hint)
+that 't' is a table and that 'k' is a positive integer, then there
+is a high likeliness that the key 'k' is in the array part
+of the table. This lookup can be done with just a few machine code
+instructions.
+
+
+Of course the preconditions for this fast path have to be checked
+(unless there are definitive hints). But if the hints are right,
+the code runs a lot faster (about a factor of 3 in this case
+for the pure table lookup).
+
+
+
Optimizing the Optimizer
+
+A question that surely popped up in your mind while reading
+the above section: does the optimizer optimize itself? I.e.
+is the optimizer module compiled?
+
+
+The current answer is no. Mainly because the compiler pipeline
+is single-threaded only. It's locked during compilation and
+any parallel attempt to JIT compile a function results in
+a 'DELAYED' status code. In fact all modules that attach to
+the compiler pipeline disable compilation for the entire
+module (because LuaJIT would do that anyway). The main chunk
+of modules loaded with require() is never compiled,
+so there is no chicken-and-egg problem here.
+
+
+Of course you could do an AOT compilation in the main chunk of
+the optimizer module. But then only with the plain backend.
+Recompiling it later on with the optimizer attached doesn't work,
+because a function cannot be compiled twice (I plan to lift
+this restriction).
+
+
+The other question is whether it pays off to compile the optimizer
+at all? Honestly, I haven't tried, because the current optimizer
+is really simple. It runs very quickly, even under the bytecode
+interpreter.
+
+
+
That's All Folks
+
+Ok, that's all for now. I'll extend this text later on with
+new topics that come up in questions. Keep on asking these
+on the mailing list if you are interested.
+
+As is always the case with benchmarks, care must be taken to
+interpret the results:
+
+
+First, the standard Lua interpreter is already very fast.
+It's commonly the fastest of it's class (interpreters) in the
+» Great Computer Language Shootout.
+Only true machine code compilers get a better overall score.
+
+
+Any performance improvements due to LuaJIT can only be incremental.
+You can't expect a speedup of 50x if the fastest compiled language
+is only 5x faster than interpreted Lua in a particular benchmark.
+LuaJIT can't do miracles.
+
+
+Also please note that most of the benchmarks below are not
+trivial micro-benchmarks, which are often cited with marvelous numbers.
+Micro-benchmarks do not realistically model the performance gains you
+can expect in your own programs.
+
+
+It's easy to make up a few one-liners like:
+ local function f(...) end; for i=1,1e7 do f() end
+This is more than 30x faster with LuaJIT. But you won't find
+this in a real-world program.
+
+
+
Measurement Methods
+
+All measurements have been taken on a Pentium III 1.139 GHz
+running Linux 2.6. Both Lua and LuaJIT have been compiled with
+GCC 3.3.6 with -O3 -fomit-frame-pointer.
+You'll definitely get different results on different machines or
+with different C compiler options. *
+
+
+The base for the comparison are the user CPU times as reported by
+/usr/bin/time. The runtime of each benchmark is parametrized
+and has been adjusted to minimize the variation between several runs.
+The ratio between the times for LuaJIT and Lua gives the speedup.
+Only this number is shown because it's less dependent on a specific system.
+
+
+E.g. a speedup of 6.74 means the same benchmark runs almost 7 times
+faster with luajit -O than with standard Lua (or with
+-j off). Your mileage may vary.
+
+
+* Yes, LuaJIT relies on quite a bit of the Lua core infrastructure
+like table and string handling. All of this is written in C and
+should be compiled with full optimization turned on, or performance
+will suffer.
+
+Note that many of these benchmarks have changed over time (both spec
+and code). Benchmark results shown in previous versions of LuaJIT
+are not directly comparable. The next section compares different
+versions with the current set of benchmarks.
+
+
+
Comparing LuaJIT Versions
+
+This shows the improvements between the following versions:
+
+
+
LuaJIT 1.0.x
+
LuaJIT 1.1.x
+
+
+
+
+
+
Benchmark
+
Speedup
+
+
+
+
+
+
fannkuch
+
3.96 → 5.37
+
+
+
+
chameneos
+
2.25 → 5.08
+
+
+
+
nsievebits
+
2.90 → 5.05
+
+
+
+
pidigits
+
3.58 → 4.94
+
+
+
+
nbody
+
4.16 → 4.63
+
+
+
+
cheapconcr
+
1.46 → 4.46
+
+
+
+
partialsums
+
1.71 → 3.73
+
+
+
+
fasta
+
2.37 → 2.68
+
+
+
+
cheapconcw
+
1.27 → 2.52
+
+
+
+
revcomp
+
1.45 → 1.92
+
+
+
+
knucleotide
+
1.32 → 1.59
+
+
+
+
+
+All other benchmarks show only minor performance differences.
+
+
+
Summary
+
+These results should give you an idea about what speedup
+you can expect depending on the nature of your Lua code:
+
+
+
+LuaJIT is really good at (floating-point) math and loops
+(mandelbrot, pidigits, spectralnorm, partialsums).
+
+
+Function calls (recursive), vararg calls, table lookups (nbody),
+table iteration and coroutine switching (chameneos, cheapconc)
+are a lot faster than with plain Lua.
+
+
+It's still pretty good for indexed table access (fannkuch, nsieve)
+and string processing (fasta, revcomp, knucleotide).
+But there is room for improvement in a future version.
+
+
+If your application spends most of the time in C code
+you won't see much of a difference (regexdna, sumfile).
+Ok, so write more code in pure Lua. :-)
+
+
+The real speedup may be shadowed by other dominant factors in a benchmark:
+
+
Common parts of the Lua core: e.g. memory allocation
+and GC (binarytrees).
+
Language characteristics: e.g. lack of bit operations (nsievebits).
+
System characteristics: e.g. CPU cache size and memory speed (nsieve).
+
+
+
+
+The best idea is of course to benchmark your own applications.
+Please report any interesting results you may find. Thank you!
+
+LuaJIT has only a single stand-alone executable, called luajit.
+It can be used to run simple Lua statements or whole Lua applications
+from the command line. It has an interactive mode, too.
+
+
+Note: The optimizer is not activated by default because it resides
+in an external module
+(see Installing LuaJIT).
+It's recommended to always use the optimizer, i.e.:luajit -O
+
+
+
Command Line Options
+
+The luajit stand-alone executable is just a slightly modified
+version of the regular lua stand-alone executable.
+It supports the same basic options, too. Please have a look at the
+Manual Page
+for the regular lua stand-alone executable.
+
+
+Two additional options control LuaJIT behaviour:
+
+
+
-j cmd[=value]
+
+This option performs a LuaJIT control command. LuaJIT has a small
+but extensible set of control commands. It's easy to add your own.
+
+
+The command is first searched for in the jit.* library.
+If no matching function is found, a module named jit.<cmd>
+is loaded. The module table must provide a start() function.
+
+
+For the -j cmd form the function is called without an argument.
+Otherwise the value is passed as the first argument (a string).
+
+
+Here are the built-in LuaJIT control commands:
+
+
+
-j on — Turns the JIT engine on (default).
+
-j off — Turns the JIT engine off.
+
-j debug[=level] — Set debug level. See
+jit.debug().
+
+
+The following control commands are loaded from add-on modules:
+
+
+
-j trace[=file] — Trace the progress of the JIT compiler.
+
-j dumphints[=file] — Dump bytecode + hints before compilation.
+
-j dump[=file] — Dump machine code after compilation.
+
+
+
+
-O[level]
+
+This option loads and runs the optimizer module jit.opt.
+The optimizer generates hints for the compiler backend to improve
+the performance of the compiled code. The optimizer slows down
+compilation slightly, but the end result should make up for it
+in almost every case.
+
+
+The -O form sets the default optimizer level, which is
+currently 2 (this may change in future versions
+of LuaJIT).
+
+
+The -Olevel form explicitly sets the optimizer level:
+
+
+
-O0 — disable the optimizer but leave it attached.
+
-O1 — perform standard optimizations (like hints for table lookups).
+
-O2 — like -O1 but also loads jit.opt_inline to enable result hints and inlining for standard library functions.
+This is a list of changes between the released versions of LuaJIT.
+The current development version is LuaJIT 2.0.0-beta9.
+The current stable version is LuaJIT 1.1.7.
+
FFI library: Resolve ld script redirection in ffi.load().
+
From Lua 5.2: package.searchpath(), fp:read("*L"),
+load(string).
+
From Lua 5.2, disabled by default: empty statement,
+table.unpack(), modified coroutine.running().
+
+
Correctness and completeness:
+
+
FFI library: numerous fixes.
+
Fix type mismatches in store-to-load forwarding.
+
Fix error handling within metamethods.
+
Fix table.maxn().
+
Improve accuracy of x^-k on x64.
+
Fix code generation for Intel Atom in x64 mode.
+
Fix narrowing of POW.
+
Fix recording of retried fast functions.
+
Fix code generation for bit.bnot() and multiplies.
+
Fix error location within cpcall frames.
+
Add workaround for old libgcc unwind bug.
+
Fix lua_yield() and getmetatable(lightuserdata) on x64.
+
Misc. fixes for PPC/e500 interpreter.
+
Fix stack slot updates for down-recursion.
+
+
Structural and performance enhancements:
+
+
Add dual-number mode (int/double) for the VM. Enabled for ARM.
+
Improve narrowing of arithmetic operators and for loops.
+
Tune loop unrolling heuristics and increase trace recorder limits.
+
Eliminate dead slots in snapshots using bytecode data-flow analysis.
+
Avoid phantom stores to proxy tables.
+
Optimize lookups in empty proxy tables.
+
Improve bytecode optimization of and/or operators.
+
+
+
+
LuaJIT 2.0.0-beta6 — 2011-02-11
+
+
New features:
+
+
PowerPC/e500v2 port of the LuaJIT interpreter is complete.
+
Various minor features from Lua 5.2: Hex escapes in literals,
+'\*' escape, reversible string.format("%q",s),
+"%g" pattern, table.sort checks callbacks,
+os.exit(status|true|false[,close]).
+
Lua 5.2 __pairs and __ipairs metamethods
+(disabled by default).
+
Initial release of the FFI library.
+
+
Correctness and completeness:
+
+
Fix string.format() for non-finite numbers.
+
Fix memory leak when compiled to use the built-in allocator.
+
x86/x64: Fix unnecessary resize in TSETM bytecode.
+
Fix various GC issues with traces and jit.flush().
+
x64: Fix fusion of indexes for array references.
+
x86/x64: Fix stack overflow handling for coroutine results.
+
Enable low-2GB memory allocation on FreeBSD/x64.
+
Fix collectgarbage("count") result if more than 2GB is in use.
+
Fix parsing of hex floats.
+
x86/x64: Fix loop branch inversion with trailing
+HREF+NE/EQ.
+
Add jit.os string.
+
coroutine.create() permits running C functions, too.
+
Fix OSX build to work with newer ld64 versions.
+
Fix bytecode optimization of and/or operators.
+
+
Structural and performance enhancements:
+
+
Emit specialized bytecode for pairs()/next().
+
Improve bytecode coalescing of nil constants.
+
Compile calls to vararg functions.
+
Compile select().
+
Improve alias analysis, esp. for loads from allocations.
+
Tuning of various compiler heuristics.
+
Refactor and extend IR conversion instructions.
+
x86/x64: Various backend enhancements related to the FFI.
+
Add SPLIT pass to split 64 bit IR instructions for 32 bit CPUs.
+
+
+
+
LuaJIT 2.0.0-beta5 — 2010-08-24
+
+
Correctness and completeness:
+
+
Fix trace exit dispatch to function headers.
+
Fix Windows and OSX builds with LUAJIT_DISABLE_JIT.
+
Reorganize and fix placement of generated machine code on x64.
+
Fix TNEW in x64 interpreter.
+
Do not eliminate PHIs for values only referenced from side exits.
+
OS-independent canonicalization of strings for non-finite numbers.
+
Fix string.char() range check on x64.
+
Fix tostring() resolving within print().
+
Fix error handling for next().
+
Fix passing of constant arguments to external calls on x64.
+
Fix interpreter argument check for two-argument SSE math functions.
+
Fix C frame chain corruption caused by lua_cpcall().
+
Fix return from pcall() within active hook.
+
+
Structural and performance enhancements:
+
+
Replace on-trace GC frame syncing with interpreter exit.
+
Improve hash lookup specialization by not removing dead keys during GC.
+
Turn traces into true GC objects.
+
Avoid starting a GC cycle immediately after library init.
+
Add weak guards to improve dead-code elimination.
+
Speed up string interning.
+
+
+
+
LuaJIT 2.0.0-beta4 — 2010-03-28
+
+
Correctness and completeness:
+
+
Fix precondition for on-trace creation of table keys.
+
Fix {f()} on x64 when table is resized.
+
Fix folding of ordered comparisons with same references.
+
Fix snapshot restores for multi-result bytecodes.
+
Fix potential hang when recording bytecode with nested closures.
+
Fix recording of getmetatable(), tonumber() and bad argument types.
+
Fix SLOAD fusion across returns to lower frames.
+
+
Structural and performance enhancements:
+
+
Add array bounds check elimination. -Oabc is enabled by default.
+
More tuning for x64, e.g. smaller table objects.
+
+
+
+
LuaJIT 2.0.0-beta3 — 2010-03-07
+
+
LuaJIT x64 port:
+
+
Port integrated memory allocator to Linux/x64, Windows/x64 and OSX/x64.
+
Port interpreter and JIT compiler to x64.
+
Port DynASM to x64.
+
Many 32/64 bit cleanups in the VM.
+
Allow building the interpreter with either x87 or SSE2 arithmetics.
+
Add external unwinding and C++ exception interop (default on x64).
+
+
Correctness and completeness:
+
+
Fix constructor bytecode generation for certain conditional values.
+
Fix some cases of ordered string comparisons.
+
Fix lua_tocfunction().
+
Fix cutoff register in JMP bytecode for some conditional expressions.
+
Fix PHI marking algorithm for references from variant slots.
+
Fix package.cpath for non-default PREFIX.
+
Fix DWARF2 frame unwind information for interpreter on OSX.
+
Drive the GC forward on string allocations in the parser.
+
Implement call/return hooks (zero-cost if disabled).
+
Implement yield from C hooks.
+
Disable JIT compiler on older non-SSE2 CPUs instead of aborting.
+
+
Structural and performance enhancements:
+
+
Compile recursive code (tail-, up- and down-recursion).
+
Improve heuristics for bytecode penalties and blacklisting.
+
Split CALL/FUNC recording and clean up fast function call semantics.
+
Major redesign of internal function call handling.
+
Improve FOR loop const specialization and integerness checks.
+
Switch to pre-initialized stacks. Avoid frame-clearing.
+
Colocation of prototypes and related data: bytecode, constants, debug info.
+
Cleanup parser and streamline bytecode generation.
+
Add support for weak IR references to register allocator.
+
Switch to compressed, extensible snapshots.
+
Compile returns to frames below the start frame.
+
Improve alias analysis of upvalues using a disambiguation hash value.
+
Compile floor/ceil/trunc to SSE2 helper calls or SSE4.1 instructions.
Remove a (sometimes) wrong assertion in luaJIT_findpc().
+
DynASM now allows labels for displacements and .aword.
+
Fix some compiler warnings for DynASM glue (internal API change).
+
Correct naming for SSSE3 (temporarily known as SSE4) in DynASM and x86 disassembler.
+
The loadable debug modules now handle redirection to stdout
+(e.g. -j trace=-).
+
+
+
LuaJIT 1.1.2 — 2006-06-24
+
+
Fix MSVC inline assembly: use only local variables with
+lua_number2int().
+
Fix "attempt to call a thread value" bug on Mac OS X:
+make values of consts used as lightuserdata keys unique
+to avoid joining by the compiler/linker.
The C stack is kept 16 byte aligned (faster).
+Mandatory for Mac OS X on Intel, too.
+
Faster calling conventions for internal C helper functions.
+
Better instruction scheduling for function prologue, OP_CALL and
+OP_RETURN.
+
+
+
Miscellaneous optimizations:
+
+
Faster loads of FP constants. Remove narrow-to-wide store-to-load
+forwarding stalls.
+
Use (scalar) SSE2 ops (if the CPU supports it) to speed up slot moves
+and FP to integer conversions.
+
Optimized the two-argument form of OP_CONCAT (a..b).
+
Inlined OP_MOD (a%b).
+With better accuracy than the C variant, too.
+
Inlined OP_POW (a^b). Unroll x^k or
+use k^x = 2^(log2(k)*x) or call pow().
+
+
+
Changes in the optimizer:
+
+
Improved hinting for table keys derived from table values
+(t1[t2[x]]).
+
Lookup hinting now works with arbitrary object types and
+supports index chains, too.
+
Generate type hints for arithmetic and comparison operators,
+OP_LEN, OP_CONCAT and OP_FORPREP.
+
Remove several hint definitions in favour of a generic COMBINE hint.
+
Complete rewrite of jit.opt_inline module
+(ex jit.opt_lib).
+
+
+
Use adaptive deoptimization:
+
+
If runtime verification of a contract fails, the affected
+instruction is recompiled and patched on-the-fly.
+Regular programs will trigger deoptimization only occasionally.
+
This avoids generating code for uncommon fallback cases
+most of the time. Generated code is up to 30% smaller compared to
+LuaJIT 1.0.3.
+
Deoptimization is used for many opcodes and contracts:
+
+
OP_CALL, OP_TAILCALL: type mismatch for callable.
+
Inlined calls: closure mismatch, parameter number and type mismatches.
+
OP_GETTABLE, OP_SETTABLE: table or key type and range mismatches.
+
All arithmetic and comparison operators, OP_LEN, OP_CONCAT,
+OP_FORPREP: operand type and range mismatches.
+
+
Complete redesign of the debug and traceback info
+(bytecode ↔ mcode) to support deoptimization.
+Much more flexible and needs only 50% of the space.
+
The modules jit.trace, jit.dumphints and
+jit.dump handle deoptimization.
+
+
+
Inlined many popular library functions
+(for commonly used arguments only):
+
+
Most math.* functions (the 18 most used ones)
+[2x-10x faster].
+
string.len, string.sub and string.char
+[2x-10x faster].
+
table.insert, table.remove and table.getn
+[3x-5x faster].
+
coroutine.yield and coroutine.resume
+[3x-5x faster].
+
pairs, ipairs and the corresponding iterators
+[8x-15x faster].
+
+
+
Changes in the core and loadable modules and the stand-alone executable:
+
+
Added jit.version, jit.version_num
+and jit.arch.
+
Reorganized some internal API functions (jit.util.*mcode*).
+
The -j dump output now shows JSUB names, too.
+
New x86 disassembler module written in pure Lua. No dependency
+on ndisasm anymore. Flexible API, very compact (500 lines)
+and complete (x87, MMX, SSE, SSE2, SSE3, SSSE3, privileged instructions).
+
luajit -v prints the LuaJIT version and copyright
+on a separate line.
+
+
+
Added SSE, SSE2, SSE3 and SSSE3 support to DynASM.
+
Miscellaneous doc changes. Added a section about
+embedding LuaJIT.
+LuaJIT adds some extensions to the standard Lua/C API. The LuaJIT include
+directory must be in the compiler search path (-Ipath)
+to be able to include the required header for C code:
+
+
+#include "luajit.h"
+
+
+Or for C++ code:
+
+
+#include "lua.hpp"
+
+
+
luaJIT_setmode(L, idx, mode)
+— Control VM
+
+This is a C API extension to allow control of the VM from C code. The
+full prototype of LuaJIT_setmode is:
+
+
+LUA_API int luaJIT_setmode(lua_State *L, int idx, int mode);
+
+
+The returned status is either success (1) or failure (0).
+The second argument is either 0 or a stack index (similar to the
+other Lua/C API functions).
+
+
+The third argument specifies the mode, which is 'or'ed with a flag.
+The flag can be LUAJIT_MODE_OFF to turn a feature on,
+LUAJIT_MODE_ON to turn a feature off, or
+LUAJIT_MODE_FLUSH to flush cached code.
+
+
+The following modes are defined:
+
+
+
luaJIT_setmode(L, 0, LUAJIT_MODE_ENGINE|flag)
+
+Turn the whole JIT compiler on or off or flush the whole cache of compiled code.
+
+This sets the mode for the function at the stack index idx or
+the parent of the calling function (idx = 0). It either
+enables JIT compilation for a function, disables it and flushes any
+already compiled code or only flushes already compiled code. This
+applies recursively to all sub-functions of the function with
+LUAJIT_MODE_ALLFUNC or only to the sub-functions with
+LUAJIT_MODE_ALLSUBFUNC.
+
+Flushes the specified root trace and all of its side traces from the cache.
+The code for the trace will be retained as long as there are any other
+traces which link to it.
+
+This mode defines a wrapper function for calls to C functions. If
+called with LUAJIT_MODE_ON, the stack index at idx
+must be a lightuserdata object holding a pointer to the wrapper
+function. From now on all C functions are called through the wrapper
+function. If called with LUAJIT_MODE_OFF this mode is turned
+off and all C functions are directly called.
+
+
+The wrapper function can be used for debugging purposes or to catch
+and convert foreign exceptions. But please read the section on
+C++ exception interoperability
+first. Recommended usage can be seen in this C++ code excerpt:
+
+
+#include <exception>
+#include "lua.hpp"
+
+// Catch C++ exceptions and convert them to Lua error messages.
+// Customize as needed for your own exception classes.
+static int wrap_exceptions(lua_State *L, lua_CFunction f)
+{
+ try {
+ return f(L); // Call wrapped function and return result.
+ } catch (const char *s) { // Catch and convert exceptions.
+ lua_pushstring(L, s);
+ } catch (std::exception& e) {
+ lua_pushstring(L, e.what());
+ } catch (...) {
+ lua_pushliteral(L, "caught (...)");
+ }
+ return lua_error(L); // Rethrow as a Lua error.
+}
+
+static int myinit(lua_State *L)
+{
+ ...
+ // Define wrapper function and enable it.
+ lua_pushlightuserdata(L, (void *)wrap_exceptions);
+ luaJIT_setmode(L, -1, LUAJIT_MODE_WRAPCFUNC|LUAJIT_MODE_ON);
+ lua_pop(L, 1);
+ ...
+}
+
+
+Note that you can only define a single global wrapper function,
+so be careful when using this mechanism from multiple C++ modules.
+Also note that this mechanism is not without overhead.
+
+
+The FFI library allows calling external C functions and
+using C data structures from pure Lua code.
+
+
+
+
+The FFI library largely obviates the need to write tedious manual
+Lua/C bindings in C. No need to learn a separate binding language
+— it parses plain C declarations! These can be
+cut-n-pasted from C header files or reference manuals. It's up to
+the task of binding large libraries without the need for dealing with
+fragile binding generators.
+
+
+
+The FFI library is tightly integrated into LuaJIT (it's not available
+as a separate module). The code generated by the JIT-compiler for
+accesses to C data structures from Lua code is on par with the
+code a C compiler would generate. Calls to C functions can
+be inlined in JIT-compiled code, unlike calls to functions bound via
+the classic Lua/C API.
+
+
+This page gives a short introduction to the usage of the FFI library.
+Please use the FFI sub-topics in the navigation bar to learn more.
+
+
+
Motivating Example: Calling External C Functions
+
+It's really easy to call an external C library function:
+
+② Add a C declaration
+for the function. The part inside the double-brackets (in green) is
+just standard C syntax.
+
+
+③ Call the named
+C function — Yes, it's that simple!
+
+
+Actually, what goes on behind the scenes is far from simple: ③ makes use of the standard
+C library namespace ffi.C. Indexing this namespace with
+a symbol name ("printf") automatically binds it to the the
+standard C library. The result is a special kind of object which,
+when called, runs the printf function. The arguments passed
+to this function are automatically converted from Lua objects to the
+corresponding C types.
+
+
+Ok, so maybe the use of printf() wasn't such a spectacular
+example. You could have done that with io.write() and
+string.format(), too. But you get the idea ...
+
+
+So here's something to pop up a message box on Windows:
+
+Compare this with the effort required to bind that function using the
+classic Lua/C API: create an extra C file, add a C function
+that retrieves and checks the argument types passed from Lua and calls
+the actual C function, add a list of module functions and their
+names, add a luaopen_* function and register all module
+functions, compile and link it into a shared library (DLL), move it to
+the proper path, add Lua code that loads the module aaaand ... finally
+call the binding function. Phew!
+
+
+
Motivating Example: Using C Data Structures
+
+The FFI library allows you to create and access C data
+structures. Of course the main use for this is for interfacing with
+C functions. But they can be used stand-alone, too.
+
+
+Lua is built upon high-level data types. They are flexible, extensible
+and dynamic. That's why we all love Lua so much. Alas, this can be
+inefficient for certain tasks, where you'd really want a low-level
+data type. E.g. a large array of a fixed structure needs to be
+implemented with a big table holding lots of tiny tables. This imposes
+both a substantial memory overhead as well as a performance overhead.
+
+
+Here's a sketch of a library that operates on color images plus a
+simple benchmark. First, the plain Lua version:
+
+
+local floor = math.floor
+
+local function image_ramp_green(n)
+ local img = {}
+ local f = 255/(n-1)
+ for i=1,n do
+ img[i] = { red = 0, green = floor((i-1)*f), blue = 0, alpha = 255 }
+ end
+ return img
+end
+
+local function image_to_grey(img, n)
+ for i=1,n do
+ local y = floor(0.3*img[i].red + 0.59*img[i].green + 0.11*img[i].blue)
+ img[i].red = y; img[i].green = y; img[i].blue = y
+ end
+end
+
+local N = 400*400
+local img = image_ramp_green(N)
+for i=1,1000 do
+ image_to_grey(img, N)
+end
+
+
+This creates a table with 160.000 pixels, each of which is a table
+holding four number values in the range of 0-255. First an image with
+a green ramp is created (1D for simplicity), then the image is
+converted to greyscale 1000 times. Yes, that's silly, but I was in
+need of a simple example ...
+
+
+And here's the FFI version. The modified parts have been marked in
+bold:
+
+
+①
+
+
+
+
+
+②
+
+③
+④
+
+
+
+
+
+
+③
+⑤local ffi = require("ffi")
+ffi.cdef[[
+typedef struct { uint8_t red, green, blue, alpha; } rgba_pixel;
+]]
+
+local function image_ramp_green(n)
+ local img = ffi.new("rgba_pixel[?]", n)
+ local f = 255/(n-1)
+ for i=0,n-1 do
+ img[i].green = i*f
+ img[i].alpha = 255
+ end
+ return img
+end
+
+local function image_to_grey(img, n)
+ for i=0,n-1 do
+ local y = 0.3*img[i].red + 0.59*img[i].green + 0.11*img[i].blue
+ img[i].red = y; img[i].green = y; img[i].blue = y
+ end
+end
+
+local N = 400*400
+local img = image_ramp_green(N)
+for i=1,1000 do
+ image_to_grey(img, N)
+end
+
+
+Ok, so that wasn't too difficult:
+
+
+① First, load the FFI
+library and declare the low-level data type. Here we choose a
+struct which holds four byte fields, one for each component
+of a 4x8 bit RGBA pixel.
+
+
+② Creating the data
+structure with ffi.new() is straightforward — the
+'?' is a placeholder for the number of elements of a
+variable-length array.
+
+
+③ C arrays are
+zero-based, so the indexes have to run from 0 to
+n-1. One might want to allocate one more element instead to
+simplify converting legacy code.
+
+
+④ Since ffi.new()
+zero-fills the array by default, we only need to set the green and the
+alpha fields.
+
+
+⑤ The calls to
+math.floor() can be omitted here, because floating-point
+numbers are already truncated towards zero when converting them to an
+integer. This happens implicitly when the number is stored in the
+fields of each pixel.
+
+
+Now let's have a look at the impact of the changes: first, memory
+consumption for the image is down from 22 Megabytes to
+640 Kilobytes (400*400*4 bytes). That's a factor of 35x less! So,
+yes, tables do have a noticeable overhead. BTW: The original program
+would consume 40 Megabytes in plain Lua (on x64).
+
+
+Next, performance: the pure Lua version runs in 9.57 seconds (52.9
+seconds with the Lua interpreter) and the FFI version runs in 0.48
+seconds on my machine (YMMV). That's a factor of 20x faster (110x
+faster than the Lua interpreter).
+
+
+The avid reader may notice that converting the pure Lua version over
+to use array indexes for the colors ([1] instead of
+.red, [2] instead of .green etc.) ought to
+be more compact and faster. This is certainly true (by a factor of
+~1.7x). Switching to a struct-of-arrays would help, too.
+
+
+However the resulting code would be less idiomatic and rather
+error-prone. And it still doesn't get even close to the performance of
+the FFI version of the code. Also, high-level data structures cannot
+be easily passed to other C functions, especially I/O functions,
+without undue conversion penalties.
+
+This page describes the API functions provided by the FFI library in
+detail. It's recommended to read through the
+introduction and the
+FFI tutorial first.
+
+
+
Glossary
+
+
cdecl — An abstract C type declaration (a Lua
+string).
+
ctype — A C type object. This is a special kind of
+cdata returned by ffi.typeof(). It serves as a
+cdataconstructor when called.
+
cdata — A C data object. It holds a value of the
+corresponding ctype.
+
ct — A C type specification which can be used for
+most of the API functions. Either a cdecl, a ctype or a
+cdata serving as a template type.
+
cb — A callback object. This is a C data object
+holding a special function pointer. Calling this function from
+C code runs an associated Lua function.
+
VLA — A variable-length array is declared with a
+? instead of the number of elements, e.g. "int[?]".
+The number of elements (nelem) must be given when it's
+created.
+
VLS — A variable-length struct is a struct C
+type where the last element is a VLA. The same rules for
+declaration and creation apply.
+
+
+
Declaring and Accessing External Symbols
+
+External symbols must be declared first and can then be accessed by
+indexing a C library
+namespace, which automatically binds the symbol to a specific
+library.
+
+
+
ffi.cdef(def)
+
+Adds multiple C declarations for types or external symbols (named
+variables or functions). def must be a Lua string. It's
+recommended to use the syntactic sugar for string arguments as
+follows:
+
+
+ffi.cdef[[
+typedef struct foo { int a, b; } foo_t; // Declare a struct and typedef.
+int dofoo(foo_t *f, int n); /* Declare an external C function. */
+]]
+
+
+The contents of the string (the part in green above) must be a
+sequence of
+C declarations,
+separated by semicolons. The trailing semicolon for a single
+declaration may be omitted.
+
+
+Please note that external symbols are only declared, but they
+are not bound to any specific address, yet. Binding is
+achieved with C library namespaces (see below).
+
+
+C declarations are not passed through a C pre-processor,
+yet. No pre-processor tokens are allowed, except for
+#pragma pack. Replace #define in existing
+C header files with enum, static const
+or typedef and/or pass the files through an external
+C pre-processor (once). Be careful not to include unneeded or
+redundant declarations from unrelated header files.
+
+
+
ffi.C
+
+This is the default C library namespace — note the
+uppercase 'C'. It binds to the default set of symbols or
+libraries on the target system. These are more or less the same as a
+C compiler would offer by default, without specifying extra link
+libraries.
+
+
+On POSIX systems, this binds to symbols in the default or global
+namespace. This includes all exported symbols from the executable and
+any libraries loaded into the global namespace. This includes at least
+libc, libm, libdl (on Linux),
+libgcc (if compiled with GCC), as well as any exported
+symbols from the Lua/C API provided by LuaJIT itself.
+
+
+On Windows systems, this binds to symbols exported from the
+*.exe, the lua51.dll (i.e. the Lua/C API
+provided by LuaJIT itself), the C runtime library LuaJIT was linked
+with (msvcrt*.dll), kernel32.dll,
+user32.dll and gdi32.dll.
+
+
+
clib = ffi.load(name [,global])
+
+This loads the dynamic library given by name and returns
+a new C library namespace which binds to its symbols. On POSIX
+systems, if global is true, the library symbols are
+loaded into the global namespace, too.
+
+
+If name is a path, the library is loaded from this path.
+Otherwise name is canonicalized in a system-dependent way and
+searched in the default search path for dynamic libraries:
+
+
+On POSIX systems, if the name contains no dot, the extension
+.so is appended. Also, the lib prefix is prepended
+if necessary. So ffi.load("z") looks for "libz.so"
+in the default shared library search path.
+
+
+On Windows systems, if the name contains no dot, the extension
+.dll is appended. So ffi.load("ws2_32") looks for
+"ws2_32.dll" in the default DLL search path.
+
+
+
Creating cdata Objects
+
+The following API functions create cdata objects (type()
+returns "cdata"). All created cdata objects are
+garbage collected.
+
+Creates a cdata object for the given ct. VLA/VLS types
+require the nelem argument. The second syntax uses a ctype as
+a constructor and is otherwise fully equivalent.
+
+
+The cdata object is initialized according to the
+rules for initializers,
+using the optional init arguments. Excess initializers cause
+an error.
+
+
+Performance notice: if you want to create many objects of one kind,
+parse the cdecl only once and get its ctype with
+ffi.typeof(). Then use the ctype as a constructor repeatedly.
+
+
+Please note that an anonymous struct declaration implicitly
+creates a new and distinguished ctype every time you use it for
+ffi.new(). This is probably not what you want,
+especially if you create more than one cdata object. Different anonymous
+structs are not considered assignment-compatible by the
+C standard, even though they may have the same fields! Also, they
+are considered different types by the JIT-compiler, which may cause an
+excessive number of traces. It's strongly suggested to either declare
+a named struct or typedef with ffi.cdef()
+or to create a single ctype object for an anonymous struct
+with ffi.typeof().
+
+
+
ctype = ffi.typeof(ct)
+
+Creates a ctype object for the given ct.
+
+
+This function is especially useful to parse a cdecl only once and then
+use the resulting ctype object as a constructor.
+
+
+
cdata = ffi.cast(ct, init)
+
+Creates a scalar cdata object for the given ct. The cdata
+object is initialized with init using the "cast" variant of
+the C type conversion
+rules.
+
+
+This functions is mainly useful to override the pointer compatibility
+checks or to convert pointers to addresses or vice versa.
+
+
+
ctype = ffi.metatype(ct, metatable)
+
+Creates a ctype object for the given ct and associates it with
+a metatable. Only struct/union types, complex numbers
+and vectors are allowed. Other types may be wrapped in a
+struct, if needed.
+
+
+The association with a metatable is permanent and cannot be changed
+afterwards. Neither the contents of the metatable nor the
+contents of an __index table (if any) may be modified
+afterwards. The associated metatable automatically applies to all uses
+of this type, no matter how the objects are created or where they
+originate from. Note that pre-defined operations on types have
+precedence (e.g. declared field names cannot be overriden).
+
+
+All standard Lua metamethods are implemented. These are called directly,
+without shortcuts and on any mix of types. For binary operations, the
+left operand is checked first for a valid ctype metamethod. The
+__gc metamethod only applies to struct/union
+types and performs an implicit ffi.gc()
+call during creation of an instance.
+
+
+
cdata = ffi.gc(cdata, finalizer)
+
+Associates a finalizer with a pointer or aggregate cdata object. The
+cdata object is returned unchanged.
+
+
+This function allows safe integration of unmanaged resources into the
+automatic memory management of the LuaJIT garbage collector. Typical
+usage:
+
+
+local p = ffi.gc(ffi.C.malloc(n), ffi.C.free)
+...
+p = nil -- Last reference to p is gone.
+-- GC will eventually run finalizer: ffi.C.free(p)
+
+
+A cdata finalizer works like the __gc metamethod for userdata
+objects: when the last reference to a cdata object is gone, the
+associated finalizer is called with the cdata object as an argument. The
+finalizer can be a Lua function or a cdata function or cdata function
+pointer. An existing finalizer can be removed by setting a nil
+finalizer, e.g. right before explicitly deleting a resource:
+
+
+ffi.C.free(ffi.gc(p, nil)) -- Manually free the memory.
+
+
+
C Type Information
+
+The following API functions return information about C types.
+They are most useful for inspecting cdata objects.
+
+
+
size = ffi.sizeof(ct [,nelem])
+
+Returns the size of ct in bytes. Returns nil if
+the size is not known (e.g. for "void" or function types).
+Requires nelem for VLA/VLS types, except for cdata objects.
+
+
+
align = ffi.alignof(ct)
+
+Returns the minimum required alignment for ct in bytes.
+
+
+
ofs [,bpos,bsize] = ffi.offsetof(ct, field)
+
+Returns the offset (in bytes) of field relative to the start
+of ct, which must be a struct. Additionally returns
+the position and the field size (in bits) for bit fields.
+
+
+
status = ffi.istype(ct, obj)
+
+Returns true if obj has the C type given by
+ct. Returns false otherwise.
+
+
+C type qualifiers (const etc.) are ignored. Pointers are
+checked with the standard pointer compatibility rules, but without any
+special treatment for void *. If ct specifies a
+struct/union, then a pointer to this type is accepted,
+too. Otherwise the types must match exactly.
+
+
+Note: this function accepts all kinds of Lua objects for the
+obj argument, but always returns false for non-cdata
+objects.
+
+
+
Utility Functions
+
+
err = ffi.errno([newerr])
+
+Returns the error number set by the last C function call which
+indicated an error condition. If the optional newerr argument
+is present, the error number is set to the new value and the previous
+value is returned.
+
+
+This function offers a portable and OS-independent way to get and set the
+error number. Note that only some C functions set the error
+number. And it's only significant if the function actually indicated an
+error condition (e.g. with a return value of -1 or
+NULL). Otherwise, it may or may not contain any previously set
+value.
+
+
+You're advised to call this function only when needed and as close as
+possible after the return of the related C function. The
+errno value is preserved across hooks, memory allocations,
+invocations of the JIT compiler and other internal VM activity. The same
+applies to the value returned by GetLastError() on Windows, but
+you need to declare and call it yourself.
+
+
+
str = ffi.string(ptr [,len])
+
+Creates an interned Lua string from the data pointed to by
+ptr.
+
+
+If the optional argument len is missing, ptr is
+converted to a "char *" and the data is assumed to be
+zero-terminated. The length of the string is computed with
+strlen().
+
+
+Otherwise ptr is converted to a "void *" and
+len gives the length of the data. The data may contain
+embedded zeros and need not be byte-oriented (though this may cause
+endianess issues).
+
+
+This function is mainly useful to convert (temporary)
+"const char *" pointers returned by
+C functions to Lua strings and store them or pass them to other
+functions expecting a Lua string. The Lua string is an (interned) copy
+of the data and bears no relation to the original data area anymore.
+Lua strings are 8 bit clean and may be used to hold arbitrary,
+non-character data.
+
+
+Performance notice: it's faster to pass the length of the string, if
+it's known. E.g. when the length is returned by a C call like
+sprintf().
+
+
+
ffi.copy(dst, src, len)
+ffi.copy(dst, str)
+
+Copies the data pointed to by src to dst.
+dst is converted to a "void *" and src
+is converted to a "const void *".
+
+
+In the first syntax, len gives the number of bytes to copy.
+Caveat: if src is a Lua string, then len must not
+exceed #src+1.
+
+
+In the second syntax, the source of the copy must be a Lua string. All
+bytes of the string plus a zero-terminator are copied to
+dst (i.e. #src+1 bytes).
+
+
+Performance notice: ffi.copy() may be used as a faster
+(inlinable) replacement for the C library functions
+memcpy(), strcpy() and strncpy().
+
+
+
ffi.fill(dst, len [,c])
+
+Fills the data pointed to by dst with len constant
+bytes, given by c. If c is omitted, the data is
+zero-filled.
+
+
+Performance notice: ffi.fill() may be used as a faster
+(inlinable) replacement for the C library function
+memset(dst, c, len). Please note the different
+order of arguments!
+
+
+
Target-specific Information
+
+
status = ffi.abi(param)
+
+Returns true if param (a Lua string) applies for the
+target ABI (Application Binary Interface). Returns false
+otherwise. The following parameters are currently defined:
+
+
+
+
Parameter
+
Description
+
+
+
32bit
32 bit architecture
+
+
64bit
64 bit architecture
+
+
le
Little-endian architecture
+
+
be
Big-endian architecture
+
+
fpu
Target has a hardware FPU
+
+
softfp
softfp calling conventions
+
+
hardfp
hardfp calling conventions
+
+
eabi
EABI variant of the standard ABI
+
+
win
Windows variant of the standard ABI
+
+
+
ffi.os
+
+Contains the target OS name. Same contents as
+jit.os.
+
+
+
ffi.arch
+
+Contains the target architecture name. Same contents as
+jit.arch.
+
+
+
Methods for Callbacks
+
+The C types for callbacks
+have some extra methods:
+
+
+
cb:free()
+
+Free the resources associated with a callback. The associated Lua
+function is unanchored and may be garbage collected. The callback
+function pointer is no longer valid and must not be called anymore
+(it may be reused by a subsequently created callback).
+
+
+
cb:set(func)
+
+Associate a new Lua function with a callback. The C type of the
+callback and the callback function pointer are unchanged.
+
+
+This method is useful to dynamically switch the receiver of callbacks
+without creating a new callback each time and registering it again (e.g.
+with a GUI library).
+
+
+
Extended Standard Library Functions
+
+The following standard library functions have been extended to work
+with cdata objects:
+
+
+
n = tonumber(cdata)
+
+Converts a number cdata object to a double and returns it as
+a Lua number. This is particularly useful for boxed 64 bit
+integer values. Caveat: this conversion may incur a precision loss.
+
+
+
s = tostring(cdata)
+
+Returns a string representation of the value of 64 bit integers
+("nnnLL" or "nnnULL") or
+complex numbers ("re±imi"). Otherwise
+returns a string representation of the C type of a ctype object
+("ctype<type>") or a cdata object
+("cdata<type>: address").
+
+
+
Extensions to the Lua Parser
+
+The parser for Lua source code treats numeric literals with the
+suffixes LL or ULL as signed or unsigned 64 bit
+integers. Case doesn't matter, but uppercase is recommended for
+readability. It handles both decimal (42LL) and hexadecimal
+(0x2aLL) literals.
+
+
+The imaginary part of complex numbers can be specified by suffixing
+number literals with i or I, e.g. 12.5i.
+Caveat: you'll need to use 1i to get an imaginary part with
+the value one, since i itself still refers to a variable
+named i.
+
+This page describes the detailed semantics underlying the FFI library
+and its interaction with both Lua and C code.
+
+
+Given that the FFI library is designed to interface with C code
+and that declarations can be written in plain C syntax, it
+closely follows the C language semantics, wherever possible.
+Some minor concessions are needed for smoother interoperation with Lua
+language semantics.
+
+
+Please don't be overwhelmed by the contents of this page — this
+is a reference and you may need to consult it, if in doubt. It doesn't
+hurt to skim this page, but most of the semantics "just work" as you'd
+expect them to work. It should be straightforward to write
+applications using the LuaJIT FFI for developers with a C or C++
+background.
+
+
+Please note: this doesn't comprise the final specification for the FFI
+semantics, yet. Some semantics may need to be changed, based on your
+feedback. Please report any problems you may
+encounter or any improvements you'd like to see — thank you!
+
+
+
C Language Support
+
+The FFI library has a built-in C parser with a minimal memory
+footprint. It's used by the ffi.* library
+functions to declare C types or external symbols.
+
+
+It's only purpose is to parse C declarations, as found e.g. in
+C header files. Although it does evaluate constant expressions,
+it's not a C compiler. The body of inline
+C function definitions is simply ignored.
+
+
+Also, this is not a validating C parser. It expects and
+accepts correctly formed C declarations, but it may choose to
+ignore bad declarations or show rather generic error messages. If in
+doubt, please check the input against your favorite C compiler.
+
+
+The C parser complies to the C99 language standard plus
+the following extensions:
+
+
+
+
The '\e' escape in character and string literals.
+
+
The C99/C++ boolean type, declared with the keywords bool
+or _Bool.
+
+
Complex numbers, declared with the keywords complex or
+_Complex.
+
+
Two complex number types: complex (aka
+complex double) and complex float.
+
+
Vector types, declared with the GCC mode or
+vector_size attribute.
+
+
Unnamed ('transparent') struct/union fields
+inside a struct/union.
+
+
Incomplete enum declarations, handled like incomplete
+struct declarations.
+
+
Unnamed enum fields inside a
+struct/union. This is similar to a scoped C++
+enum, except that declared constants are visible in the
+global namespace, too.
+
+
Scoped static const declarations inside a
+struct/union (from C++).
+
+
Zero-length arrays ([0]), empty
+struct/union, variable-length arrays (VLA,
+[?]) and variable-length structs (VLS, with a trailing
+VLA).
+
+
C++ reference types (int &x).
+
+
Alternate GCC keywords with '__', e.g.
+__const__.
+
+
GCC __attribute__ with the following attributes:
+aligned, packed, mode,
+vector_size, cdecl, fastcall,
+stdcall.
+
+
The GCC __extension__ keyword and the GCC
+__alignof__ operator.
+
+
GCC __asm__("symname") symbol name redirection for
+function declarations.
+
+
MSVC keywords for fixed-length types: __int8,
+__int16, __int32 and __int64.
+You're encouraged to use these types in preference to the
+compiler-specific extensions or the target-dependent standard types.
+E.g. char differs in signedness and long differs in
+size, depending on the target architecture and platform ABI.
+
+
+The following C features are not supported:
+
+
+
+
A declaration must always have a type specifier; it doesn't
+default to an int type.
+
+
Old-style empty function declarations (K&R) are not allowed.
+All C functions must have a proper prototype declaration. A
+function declared without parameters (int foo();) is
+treated as a function taking zero arguments, like in C++.
+
+
The long double C type is parsed correctly, but
+there's no support for the related conversions, accesses or arithmetic
+operations.
+
+
Wide character strings and character literals are not
+supported.
+
+
See below for features that are currently
+not implemented.
+
+
+
+
C Type Conversion Rules
+
+
Conversions from C types to Lua objects
+
+These conversion rules apply for read accesses to
+C types: indexing pointers, arrays or
+struct/union types; reading external variables or
+constant values; retrieving return values from C calls:
+
+
+
+
Input
+
Conversion
+
Output
+
+
+
int8_t, int16_t
→sign-extint32_t → double
number
+
+
uint8_t, uint16_t
→zero-extint32_t → double
number
+
+
int32_t, uint32_t
→ double
number
+
+
int64_t, uint64_t
boxed value
64 bit int cdata
+
+
double, float
→ double
number
+
+
bool
0 → false, otherwise true
boolean
+
+
Complex number
boxed value
complex cdata
+
+
Vector
boxed value
vector cdata
+
+
Pointer
boxed value
pointer cdata
+
+
Array
boxed reference
reference cdata
+
+
struct/union
boxed reference
reference cdata
+
+
+Bitfields or enum types are treated like their underlying
+type.
+
+
+Reference types are dereferenced before a conversion can take
+place — the conversion is applied to the C type pointed to
+by the reference.
+
+
+
Conversions from Lua objects to C types
+
+These conversion rules apply for write accesses to
+C types: indexing pointers, arrays or
+struct/union types; initializing cdata objects;
+casts to C types; writing to external variables; passing
+arguments to C calls:
+
+If the result type of this conversion doesn't match the
+C type of the destination, the
+conversion rules between C types
+are applied.
+
+
+Reference types are immutable after initialization ("no re-seating of
+references"). For initialization purposes or when passing values to
+reference parameters, they are treated like pointers. Note that unlike
+in C++, there's no way to implement automatic reference generation of
+variables under the Lua language semantics. If you want to call a
+function with a reference parameter, you need to explicitly pass a
+one-element array.
+
+
+
Conversions between C types
+
+These conversion rules are more or less the same as the standard
+C conversion rules. Some rules only apply to casts, or require
+pointer or type compatibility:
+
+
+
+
Input
+
Conversion
+
Output
+
+
+
Signed integer
→narrow or sign-extend
Integer
+
+
Unsigned integer
→narrow or zero-extend
Integer
+
+
Integer
→round
double, float
+
+
double, float
→truncint32_t →narrow
(u)int8_t, (u)int16_t
+
+
double, float
→trunc
(u)int32_t, (u)int64_t
+
+
double, float
→round
float, double
+
+
Number
n == 0 → 0, otherwise 1
bool
+
+
bool
false → 0, true → 1
Number
+
+
Complex number
convert real part
Number
+
+
Number
convert real part, imag = 0
Complex number
+
+
Complex number
convert real and imag part
Complex number
+
+
Number
convert scalar and replicate
Vector
+
+
Vector
copy (same size)
Vector
+
+
struct/union
take base address (compat)
Pointer
+
+
Array
take base address (compat)
Pointer
+
+
Function
take function address
Function pointer
+
+
Number
convert via uintptr_t (cast)
Pointer
+
+
Pointer
convert address (compat/cast)
Pointer
+
+
Pointer
convert address (cast)
Integer
+
+
Array
convert base address (cast)
Integer
+
+
Array
copy (compat)
Array
+
+
struct/union
copy (identical type)
struct/union
+
+
+Bitfields or enum types are treated like their underlying
+type.
+
+
+Conversions not listed above will raise an error. E.g. it's not
+possible to convert a pointer to a complex number or vice versa.
+
+
+
Conversions for vararg C function arguments
+
+The following default conversion rules apply when passing Lua objects
+to the variable argument part of vararg C functions:
+
+
+
+
Input
+
Conversion
+
Output
+
+
+
number
→
double
+
+
boolean
false → 0, true → 1
bool
+
+
nil
NULL →
(void *)
+
+
userdata
userdata payload →
(void *)
+
+
lightuserdata
lightuserdata address →
(void *)
+
+
string
string data →
const char *
+
+
float cdata
→
double
+
+
Array cdata
take base address
Element pointer
+
+
struct/union cdata
take base address
struct/union pointer
+
+
Function cdata
take function address
Function pointer
+
+
Any other cdata
no conversion
C type
+
+
+To pass a Lua object, other than a cdata object, as a specific type,
+you need to override the conversion rules: create a temporary cdata
+object with a constructor or a cast and initialize it with the value
+to pass:
+
+
+Assuming x is a Lua number, here's how to pass it as an
+integer to a vararg function:
+
+If you don't do this, the default Lua number → double
+conversion rule applies. A vararg C function expecting an integer
+will see a garbled or uninitialized value.
+
+
+
Initializers
+
+Creating a cdata object with
+ffi.new() or the
+equivalent constructor syntax always initializes its contents, too.
+Different rules apply, depending on the number of optional
+initializers and the C types involved:
+
+
+
If no initializers are given, the object is filled with zero bytes.
Valarrays (complex numbers and vectors) are treated like scalars
+when a single initializer is given. Otherwise they are treated like
+regular arrays.
+
+
Aggregate types (arrays and structs) accept either a single
+table initializer or a flat list of
+initializers.
+
+
The elements of an array are initialized, starting at index zero.
+If a single initializer is given for an array, it's repeated for all
+remaining elements. This doesn't happen if two or more initializers
+are given: all remaining uninitialized elements are filled with zero
+bytes.
+
+
Byte arrays may also be initialized with a Lua string. This copies
+the whole string plus a terminating zero-byte. The copy stops early only
+if the array has a known, fixed size.
+
+
The fields of a struct are initialized in the order of
+their declaration. Uninitialized fields are filled with zero
+bytes.
+
+
Only the first field of a union can be initialized with a
+flat initializer.
+
+
Elements or fields which are aggregates themselves are initialized
+with a single initializer, but this may be a table
+initializer or a compatible aggregate.
+
+
Excess initializers cause an error.
+
+
+
+
Table Initializers
+
+The following rules apply if a Lua table is used to initialize an
+Array or a struct/union:
+
+
+
+
If the table index [0] is non-nil, then the
+table is assumed to be zero-based. Otherwise it's assumed to be
+one-based.
+
+
Array elements, starting at index zero, are initialized one-by-one
+with the consecutive table elements, starting at either index
+[0] or [1]. This process stops at the first
+nil table element.
+
+
If exactly one array element was initialized, it's repeated for
+all the remaining elements. Otherwise all remaining uninitialized
+elements are filled with zero bytes.
+
+
The above logic only applies to arrays with a known fixed size.
+A VLA is only initialized with the element(s) given in the table.
+Depending on the use case, you may need to explicitly add a
+NULL or 0 terminator to a VLA.
+
+
If the table has a non-empty hash part, a
+struct/union is initialized by looking up each field
+name (as a string key) in the table. Each non-nil value is
+used to initialize the corresponding field.
+
+
Otherwise a struct/union is initialized in the
+order of the declaration of its fields. Each field is initialized with
+the consecutive table elements, starting at either index [0]
+or [1]. This process stops at the first nil table
+element.
+
+
Uninitialized fields of a struct are filled with zero
+bytes, except for the trailing VLA of a VLS.
+
+
Initialization of a union stops after one field has been
+initialized. If no field has been initialized, the union is
+filled with zero bytes.
+
+
Elements or fields which are aggregates themselves are initialized
+with a single initializer, but this may be a nested table
+initializer (or a compatible aggregate).
+
+
Excess initializers for an array cause an error. Excess
+initializers for a struct/union are ignored.
+Unrelated table entries are ignored, too.
+
+
+
+Example:
+
+
+local ffi = require("ffi")
+
+ffi.cdef[[
+struct foo { int a, b; };
+union bar { int i; double d; };
+struct nested { int x; struct foo y; };
+]]
+
+ffi.new("int[3]", {}) --> 0, 0, 0
+ffi.new("int[3]", {1}) --> 1, 1, 1
+ffi.new("int[3]", {1,2}) --> 1, 2, 0
+ffi.new("int[3]", {1,2,3}) --> 1, 2, 3
+ffi.new("int[3]", {[0]=1}) --> 1, 1, 1
+ffi.new("int[3]", {[0]=1,2}) --> 1, 2, 0
+ffi.new("int[3]", {[0]=1,2,3}) --> 1, 2, 3
+ffi.new("int[3]", {[0]=1,2,3,4}) --> error: too many initializers
+
+ffi.new("struct foo", {}) --> a = 0, b = 0
+ffi.new("struct foo", {1}) --> a = 1, b = 0
+ffi.new("struct foo", {1,2}) --> a = 1, b = 2
+ffi.new("struct foo", {[0]=1,2}) --> a = 1, b = 2
+ffi.new("struct foo", {b=2}) --> a = 0, b = 2
+ffi.new("struct foo", {a=1,b=2,c=3}) --> a = 1, b = 2 'c' is ignored
+
+ffi.new("union bar", {}) --> i = 0, d = 0.0
+ffi.new("union bar", {1}) --> i = 1, d = ?
+ffi.new("union bar", {[0]=1,2}) --> i = 1, d = ? '2' is ignored
+ffi.new("union bar", {d=2}) --> i = ?, d = 2.0
+
+ffi.new("struct nested", {1,{2,3}}) --> x = 1, y.a = 2, y.b = 3
+ffi.new("struct nested", {x=1,y={2,3}}) --> x = 1, y.a = 2, y.b = 3
+
+
+
Operations on cdata Objects
+
+All of the standard Lua operators can be applied to cdata objects or a
+mix of a cdata object and another Lua object. The following list shows
+the valid combinations. All other combinations currently raise an
+error.
+
+
+Reference types are dereferenced before performing each of
+the operations below — the operation is applied to the
+C type pointed to by the reference.
+
+
+The pre-defined operations are always tried first before deferring to a
+metamethod for a ctype (if defined).
+
+
+
Indexing a cdata object
+
+
+
Indexing a pointer/array: a cdata pointer/array can be
+indexed by a cdata number or a Lua number. The element address is
+computed as the base address plus the number value multiplied by the
+element size in bytes. A read access loads the element value and
+converts it to a Lua object. A write
+access converts a Lua object to the element
+type and stores the converted value to the element. An error is
+raised if the element size is undefined or a write access to a
+constant element is attempted.
+
+
Dereferencing a struct/union field: a
+cdata struct/union or a pointer to a
+struct/union can be dereferenced by a string key,
+giving the field name. The field address is computed as the base
+address plus the relative offset of the field. A read access loads the
+field value and converts it to a Lua
+object. A write access converts a Lua
+object to the field type and stores the converted value to the
+field. An error is raised if a write access to a constant
+struct/union or a constant field is attempted.
+
+
Indexing a complex number: a complex number can be indexed
+either by a cdata number or a Lua number with the values 0 or 1, or by
+the strings "re" or "im". A read access loads the
+real part ([0], .re) or the imaginary part
+([1], .im) part of a complex number and
+converts it to a Lua number. The
+sub-parts of a complex number are immutable — assigning to an
+index of a complex number raises an error. Accessing out-of-bound
+indexes returns unspecified results, but is guaranteed not to trigger
+memory access violations.
+
+
Indexing a vector: a vector is treated like an array for
+indexing purposes, except the vector elements are immutable —
+assigning to an index of a vector raises an error.
+
+
+
+Note: since there's (deliberately) no address-of operator, a cdata
+object holding a value type is effectively immutable after
+initialization. The JIT compiler benefits from this fact when applying
+certain optimizations.
+
+
+As a consequence of this, the elements of complex numbers and
+vectors are immutable. But the elements of an aggregate holding these
+types may be modified of course. I.e. you cannot assign to
+foo.c.im, but you can assign a (newly created) complex number
+to foo.c.
+
+
+
Calling a cdata object
+
+
+
Constructor: a ctype object can be called and used as a
+constructor.
+
+
C function call: a cdata function or cdata function
+pointer can be called. The passed arguments are
+converted to the C types of the
+parameters given by the function declaration. Arguments passed to the
+variable argument part of vararg C function use
+special conversion rules. This
+C function is called and the return value (if any) is
+converted to a Lua object.
+On Windows/x86 systems, __stdcall functions are automatically
+detected and a function declared as __cdecl (the default) is
+silently fixed up after the first call.
+
+
+
+
Arithmetic on cdata objects
+
+
+
Pointer arithmetic: a cdata pointer/array and a cdata
+number or a Lua number can be added or subtracted. The number must be
+on the right hand side for a subtraction. The result is a pointer of
+the same type with an address plus or minus the number value
+multiplied by the element size in bytes. An error is raised if the
+element size is undefined.
+
+
Pointer difference: two compatible cdata pointers/arrays
+can be subtracted. The result is the difference between their
+addresses, divided by the element size in bytes. An error is raised if
+the element size is undefined or zero.
+
+
64 bit integer arithmetic: the standard arithmetic
+operators (+ - * / % ^ and unary
+minus) can be applied to two cdata numbers, or a cdata number and a
+Lua number. If one of them is an uint64_t, the other side is
+converted to an uint64_t and an unsigned arithmetic operation
+is performed. Otherwise both sides are converted to an
+int64_t and a signed arithmetic operation is performed. The
+result is a boxed 64 bit cdata object.
+
+These rules ensure that 64 bit integers are "sticky". Any
+expression involving at least one 64 bit integer operand results
+in another one. The undefined cases for the division, modulo and power
+operators return 2LL ^ 63 or
+2ULL ^ 63.
+
+You'll have to explicitly convert a 64 bit integer to a Lua
+number (e.g. for regular floating-point calculations) with
+tonumber(). But note this may incur a precision loss.
+
+
+
+
Comparisons of cdata objects
+
+
+
Pointer comparison: two compatible cdata pointers/arrays
+can be compared. The result is the same as an unsigned comparison of
+their addresses. nil is treated like a NULL pointer,
+which is compatible with any other pointer type.
+
+
64 bit integer comparison: two cdata numbers, or a
+cdata number and a Lua number can be compared with each other. If one
+of them is an uint64_t, the other side is converted to an
+uint64_t and an unsigned comparison is performed. Otherwise
+both sides are converted to an int64_t and a signed
+comparison is performed.
+
+
+
+
cdata objects as table keys
+
+Lua tables may be indexed by cdata objects, but this doesn't provide
+any useful semantics — cdata objects are unsuitable as table
+keys!
+
+
+A cdata object is treated like any other garbage-collected object and
+is hashed and compared by its address for table indexing. Since
+there's no interning for cdata value types, the same value may be
+boxed in different cdata objects with different addresses. Thus
+t[1LL+1LL] and t[2LL] usually do not point to
+the same hash slot and they certainly do not point to the same
+hash slot as t[2].
+
+
+It would seriously drive up implementation complexity and slow down
+the common case, if one were to add extra handling for by-value
+hashing and comparisons to Lua tables. Given the ubiquity of their use
+inside the VM, this is not acceptable.
+
+
+There are three viable alternatives, if you really need to use cdata
+objects as keys:
+
+
+
+
If you can get by with the precision of Lua numbers
+(52 bits), then use tonumber() on a cdata number or
+combine multiple fields of a cdata aggregate to a Lua number. Then use
+the resulting Lua number as a key when indexing tables.
+One obvious benefit: t[tonumber(2LL)]does point to
+the same slot as t[2].
+
+
Otherwise use either tostring() on 64 bit integers
+or complex numbers or combine multiple fields of a cdata aggregate to
+a Lua string (e.g. with
+ffi.string()). Then
+use the resulting Lua string as a key when indexing tables.
+
+
Create your own specialized hash table implementation using the
+C types provided by the FFI library, just like you would in
+C code. Ultimately this may give much better performance than the
+other alternatives or what a generic by-value hash table could
+possibly provide.
+
+
+
+
Garbage Collection of cdata Objects
+
+All explicitly (ffi.new(), ffi.cast() etc.) or
+implicitly (accessors) created cdata objects are garbage collected.
+You need to ensure to retain valid references to cdata objects
+somewhere on a Lua stack, an upvalue or in a Lua table while they are
+still in use. Once the last reference to a cdata object is gone, the
+garbage collector will automatically free the memory used by it (at
+the end of the next GC cycle).
+
+
+Please note that pointers themselves are cdata objects, however they
+are not followed by the garbage collector. So e.g. if you
+assign a cdata array to a pointer, you must keep the cdata object
+holding the array alive as long as the pointer is still in use:
+
+
+ffi.cdef[[
+typedef struct { int *a; } foo_t;
+]]
+
+local s = ffi.new("foo_t", ffi.new("int[10]")) -- WRONG!
+
+local a = ffi.new("int[10]") -- OK
+local s = ffi.new("foo_t", a)
+-- Now do something with 's', but keep 'a' alive until you're done.
+
+
+Similar rules apply for Lua strings which are implicitly converted to
+"const char *": the string object itself must be
+referenced somewhere or it'll be garbage collected eventually. The
+pointer will then point to stale data, which may have already been
+overwritten. Note that string literals are automatically kept
+alive as long as the function containing it (actually its prototype)
+is not garbage collected.
+
+
+Objects which are passed as an argument to an external C function
+are kept alive until the call returns. So it's generally safe to
+create temporary cdata objects in argument lists. This is a common
+idiom for passing specific C types to
+vararg functions.
+
+
+Memory areas returned by C functions (e.g. from malloc())
+must be manually managed, of course (or use
+ffi.gc()). Pointers to
+cdata objects are indistinguishable from pointers returned by C
+functions (which is one of the reasons why the GC cannot follow them).
+
+
+
Callbacks
+
+The LuaJIT FFI automatically generates special callback functions
+whenever a Lua function is converted to a C function pointer. This
+associates the generated callback function pointer with the C type
+of the function pointer and the Lua function object (closure).
+
+
+This can happen implicitly due to the usual conversions, e.g. when
+passing a Lua function to a function pointer argument. Or you can use
+ffi.cast() to explicitly cast a Lua function to a
+C function pointer.
+
+
+Currently only certain C function types can be used as callback
+functions. Neither C vararg functions nor functions with
+pass-by-value aggregate argument or result types are supported. There
+are no restrictions for the kind of Lua functions that can be called
+from the callback — no checks for the proper number of arguments
+are made. The return value of the Lua function will be converted to the
+result type and an error will be thrown for invalid conversions.
+
+
+It's allowed to throw errors across a callback invocation, but it's not
+advisable in general. Do this only if you know the C function, that
+called the callback, copes with the forced stack unwinding and doesn't
+leak resources.
+
+
+
Callback resource handling
+
+Callbacks take up resources — you can only have a limited number
+of them at the same time (500 - 1000, depending on the
+architecture). The associated Lua functions are anchored to prevent
+garbage collection, too.
+
+
+Callbacks due to implicit conversions are permanent! There is no
+way to guess their lifetime, since the C side might store the
+function pointer for later use (typical for GUI toolkits). The associated
+resources cannot be reclaimed until termination:
+
+
+ffi.cdef[[
+typedef int (__stdcall *WNDENUMPROC)(void *hwnd, intptr_t l);
+int EnumWindows(WNDENUMPROC func, intptr_t l);
+]]
+
+-- Implicit conversion to a callback via function pointer argument.
+local count = 0
+ffi.C.EnumWindows(function(hwnd, l)
+ count = count + 1
+ return true
+end, 0)
+-- The callback is permanent and its resources cannot be reclaimed!
+-- Ok, so this may not be a problem, if you do this only once.
+
+
+Note: this example shows that you must properly declare
+__stdcall callbacks on Windows/x86 systems. The calling
+convention cannot be automatically detected, unlike for
+__stdcall calls to Windows functions.
+
+
+For some use cases it's necessary to free up the resources or to
+dynamically redirect callbacks. Use an explicit cast to a
+C function pointer and keep the resulting cdata object. Then use
+the cb:free()
+or cb:set() methods
+on the cdata object:
+
+
+-- Explicitly convert to a callback via cast.
+local count = 0
+local cb = ffi.cast("WNDENUMPROC", function(hwnd, l)
+ count = count + 1
+ return true
+end)
+
+-- Pass it to a C function.
+ffi.C.EnumWindows(cb, 0)
+-- EnumWindows doesn't need the callback after it returns, so free it.
+
+cb:free()
+-- The callback function pointer is no longer valid and its resources
+-- will be reclaimed. The created Lua closure will be garbage collected.
+
+
+
Callback performance
+
+Callbacks are slow! First, the C to Lua transition itself
+has an unavoidable cost, similar to a lua_call() or
+lua_pcall(). Argument and result marshalling add to that cost.
+And finally, neither the C compiler nor LuaJIT can inline or
+optimize across the language barrier and hoist repeated computations out
+of a callback function.
+
+
+Do not use callbacks for performance-sensitive work: e.g. consider a
+numerical integration routine which takes a user-defined function to
+integrate over. It's a bad idea to call a user-defined Lua function from
+C code millions of times. The callback overhead will be absolutely
+detrimental for performance.
+
+
+It's considerably faster to write the numerical integration routine
+itself in Lua — the JIT compiler will be able to inline the
+user-defined function and optimize it together with its calling context,
+with very competitive performance.
+
+
+As a general guideline: use callbacks only when you must, because
+of existing C APIs. E.g. callback performance is irrelevant for a
+GUI application, which waits for user input most of the time, anyway.
+
+
+For new designs avoid push-style APIs (C function repeatedly
+calling a callback for each result). Instead use pull-style APIs
+(call a C function repeatedly to get a new result). Calls from Lua
+to C via the FFI are much faster than the other way round. Most well-designed
+libraries already use pull-style APIs (read/write, get/put).
+
+
+
C Library Namespaces
+
+A C library namespace is a special kind of object which allows
+access to the symbols contained in shared libraries or the default
+symbol namespace. The default
+ffi.C namespace is
+automatically created when the FFI library is loaded. C library
+namespaces for specific shared libraries may be created with the
+ffi.load() API
+function.
+
+
+Indexing a C library namespace object with a symbol name (a Lua
+string) automatically binds it to the library. First the symbol type
+is resolved — it must have been declared with
+ffi.cdef. Then the
+symbol address is resolved by searching for the symbol name in the
+associated shared libraries or the default symbol namespace. Finally,
+the resulting binding between the symbol name, the symbol type and its
+address is cached. Missing symbol declarations or nonexistent symbol
+names cause an error.
+
+
+This is what happens on a read access for the different kinds of
+symbols:
+
+
+
+
External functions: a cdata object with the type of the function
+and its address is returned.
+
+
External variables: the symbol address is dereferenced and the
+loaded value is converted to a Lua object
+and returned.
+
+
Constant values (static const or enum
+constants): the constant is converted to a
+Lua object and returned.
+
+
+
+This is what happens on a write access:
+
+
+
+
External variables: the value to be written is
+converted to the C type of the
+variable and then stored at the symbol address.
+
+
Writing to constant variables or to any other symbol type causes
+an error, like any other attempted write to a constant location.
+
+
+
+C library namespaces themselves are garbage collected objects. If
+the last reference to the namespace object is gone, the garbage
+collector will eventually release the shared library reference and
+remove all memory associated with the namespace. Since this may
+trigger the removal of the shared library from the memory of the
+running process, it's generally not safe to use function
+cdata objects obtained from a library if the namespace object may be
+unreferenced.
+
+
+Performance notice: the JIT compiler specializes to the identity of
+namespace objects and to the strings used to index it. This
+effectively turns function cdata objects into constants. It's not
+useful and actually counter-productive to explicitly cache these
+function objects, e.g. local strlen = ffi.C.strlen. OTOH it
+is useful to cache the namespace itself, e.g. local C =
+ffi.C.
+
+
+
No Hand-holding!
+
+The FFI library has been designed as a low-level library. The
+goal is to interface with C code and C data types with a
+minimum of overhead. This means you can do anything you can do
+from C: access all memory, overwrite anything in memory, call
+machine code at any memory address and so on.
+
+
+The FFI library provides no memory safety, unlike regular Lua
+code. It will happily allow you to dereference a NULL
+pointer, to access arrays out of bounds or to misdeclare
+C functions. If you make a mistake, your application might crash,
+just like equivalent C code would.
+
+
+This behavior is inevitable, since the goal is to provide full
+interoperability with C code. Adding extra safety measures, like
+bounds checks, would be futile. There's no way to detect
+misdeclarations of C functions, since shared libraries only
+provide symbol names, but no type information. Likewise there's no way
+to infer the valid range of indexes for a returned pointer.
+
+
+Again: the FFI library is a low-level library. This implies it needs
+to be used with care, but it's flexibility and performance often
+outweigh this concern. If you're a C or C++ developer, it'll be easy
+to apply your existing knowledge. OTOH writing code for the FFI
+library is not for the faint of heart and probably shouldn't be the
+first exercise for someone with little experience in Lua, C or C++.
+
+
+As a corollary of the above, the FFI library is not safe for use by
+untrusted Lua code. If you're sandboxing untrusted Lua code, you
+definitely don't want to give this code access to the FFI library or
+to any cdata object (except 64 bit integers or complex
+numbers). Any properly engineered Lua sandbox needs to provide safety
+wrappers for many of the standard Lua library functions —
+similar wrappers need to be written for high-level operations on FFI
+data types, too.
+
+
+
Current Status
+
+The initial release of the FFI library has some limitations and is
+missing some features. Most of these will be fixed in future releases.
+
C declarations are not passed through a C pre-processor,
+yet.
+
The C parser is able to evaluate most constant expressions
+commonly found in C header files. However it doesn't handle the
+full range of C expression semantics and may fail for some
+obscure constructs.
+
static const declarations only work for integer types
+up to 32 bits. Neither declaring string constants nor
+floating-point constants is supported.
+
Packed struct bitfields that cross container boundaries
+are not implemented.
+
Native vector types may be defined with the GCC mode or
+vector_size attribute. But no operations other than loading,
+storing and initializing them are supported, yet.
+
The volatile type qualifier is currently ignored by
+compiled code.
+The JIT compiler already handles a large subset of all FFI operations.
+It automatically falls back to the interpreter for unimplemented
+operations (you can check for this with the
+-jv command line option).
+The following operations are currently not compiled and may exhibit
+suboptimal performance, especially when used in inner loops:
+
+
+
Array/struct copies and bulk initializations.
+
Bitfield accesses and initializations.
+
Vector operations.
+
Table initializers.
+
Initialization of nested struct/union types.
+
Allocations of variable-length arrays or structs.
+
Allocations of C types with a size > 64 bytes or an
+alignment > 8 bytes.
+
Conversions from lightuserdata to void *.
+
Pointer differences for element sizes that are not a power of
+two.
+
Calls to C functions with aggregates passed or returned by
+value.
+
Calls to ctype metamethods which are not plain functions.
+
ctype __newindex tables and non-string lookups in ctype
+__index tables.
+
tostring() for cdata types.
+
Calls to the following ffi.* API
+functions: cdef, load, typeof,
+metatype, gc, sizeof, alignof,
+offsetof.
+This page is intended to give you an overview of the features of the FFI
+library by presenting a few use cases and guidelines.
+
+
+This page makes no attempt to explain all of the FFI library, though.
+You'll want to have a look at the ffi.* API
+function reference and the FFI
+semantics to learn more.
+
+
+
Loading the FFI Library
+
+The FFI library is built into LuaJIT by default, but it's not loaded
+and initialized by default. The suggested way to use the FFI library
+is to add the following to the start of every Lua file that needs one
+of its functions:
+
+
+local ffi = require("ffi")
+
+
+Please note this doesn't define an ffi variable in the table
+of globals — you really need to use the local variable. The
+require function ensures the library is only loaded once.
+
+
+
Accessing Standard System Functions
+
+The following code explains how to access standard system functions.
+We slowly print two lines of dots by sleeping for 10 milliseconds
+after each dot:
+
+
+
+①
+
+
+
+
+
+②
+③
+④
+
+
+
+⑤
+
+
+
+
+
+⑥local ffi = require("ffi")
+ffi.cdef[[
+void Sleep(int ms);
+int poll(struct pollfd *fds, unsigned long nfds, int timeout);
+]]
+
+local sleep
+if ffi.os == "Windows" then
+ function sleep(s)
+ ffi.C.Sleep(s*1000)
+ end
+else
+ function sleep(s)
+ ffi.C.poll(nil, 0, s*1000)
+ end
+end
+
+for i=1,160 do
+ io.write("."); io.flush()
+ sleep(0.01)
+end
+io.write("\n")
+
+
+Here's the step-by-step explanation:
+
+
+① This defines the
+C library functions we're going to use. The part inside the
+double-brackets (in green) is just standard C syntax. You can
+usually get this info from the C header files or the
+documentation provided by each C library or C compiler.
+
+
+② The difficulty we're
+facing here, is that there are different standards to choose from.
+Windows has a simple Sleep() function. On other systems there
+are a variety of functions available to achieve sub-second sleeps, but
+with no clear consensus. Thankfully poll() can be used for
+this task, too, and it's present on most non-Windows systems. The
+check for ffi.os makes sure we use the Windows-specific
+function only on Windows systems.
+
+
+③ Here we're wrapping the
+call to the C function in a Lua function. This isn't strictly
+necessary, but it's helpful to deal with system-specific issues only
+in one part of the code. The way we're wrapping it ensures the check
+for the OS is only done during initialization and not for every call.
+
+
+④ A more subtle point is
+that we defined our sleep() function (for the sake of this
+example) as taking the number of seconds, but accepting fractional
+seconds. Multiplying this by 1000 gets us milliseconds, but that still
+leaves it a Lua number, which is a floating-point value. Alas, the
+Sleep() function only accepts an integer value. Luckily for
+us, the FFI library automatically performs the conversion when calling
+the function (truncating the FP value towards zero, like in C).
+
+
+Some readers will notice that Sleep() is part of
+KERNEL32.DLL and is also a stdcall function. So how
+can this possibly work? The FFI library provides the ffi.C
+default C library namespace, which allows calling functions from
+the default set of libraries, like a C compiler would. Also, the
+FFI library automatically detects stdcall functions, so you
+don't need to declare them as such.
+
+
+⑤ The poll()
+function takes a couple more arguments we're not going to use. You can
+simply use nil to pass a NULL pointer and 0
+for the nfds parameter. Please note that the
+number 0does not convert to a pointer value,
+unlike in C++. You really have to pass pointers to pointer arguments
+and numbers to number arguments.
+
+
+The page on FFI semantics has all
+of the gory details about
+conversions between Lua
+objects and C types. For the most part you don't have to deal
+with this, as it's performed automatically and it's carefully designed
+to bridge the semantic differences between Lua and C.
+
+
+⑥ Now that we have defined
+our own sleep() function, we can just call it from plain Lua
+code. That wasn't so bad, huh? Turning these boring animated dots into
+a fascinating best-selling game is left as an exercise for the reader.
+:-)
+
+
+
Accessing the zlib Compression Library
+
+The following code shows how to access the zlib compression library from Lua code.
+We'll define two convenience wrapper functions that take a string and
+compress or uncompress it to another string:
+
+
+
+①
+
+
+
+
+
+
+②
+
+
+③
+
+④
+
+
+⑤
+
+
+⑥
+
+
+
+
+
+
+
+⑦local ffi = require("ffi")
+ffi.cdef[[
+unsigned long compressBound(unsigned long sourceLen);
+int compress2(uint8_t *dest, unsigned long *destLen,
+ const uint8_t *source, unsigned long sourceLen, int level);
+int uncompress(uint8_t *dest, unsigned long *destLen,
+ const uint8_t *source, unsigned long sourceLen);
+]]
+local zlib = ffi.load(ffi.os == "Windows" and "zlib1" or "z")
+
+local function compress(txt)
+ local n = zlib.compressBound(#txt)
+ local buf = ffi.new("uint8_t[?]", n)
+ local buflen = ffi.new("unsigned long[1]", n)
+ local res = zlib.compress2(buf, buflen, txt, #txt, 9)
+ assert(res == 0)
+ return ffi.string(buf, buflen[0])
+end
+
+local function uncompress(comp, n)
+ local buf = ffi.new("uint8_t[?]", n)
+ local buflen = ffi.new("unsigned long[1]", n)
+ local res = zlib.uncompress(buf, buflen, comp, #comp)
+ assert(res == 0)
+ return ffi.string(buf, buflen[0])
+end
+
+-- Simple test code.
+local txt = string.rep("abcd", 1000)
+print("Uncompressed size: ", #txt)
+local c = compress(txt)
+print("Compressed size: ", #c)
+local txt2 = uncompress(c, #txt)
+assert(txt2 == txt)
+
+
+Here's the step-by-step explanation:
+
+
+① This defines some of the
+C functions provided by zlib. For the sake of this example, some
+type indirections have been reduced and it uses the pre-defined
+fixed-size integer types, while still adhering to the zlib API/ABI.
+
+
+② This loads the zlib shared
+library. On POSIX systems it's named libz.so and usually
+comes pre-installed. Since ffi.load() automatically adds any
+missing standard prefixes/suffixes, we can simply load the
+"z" library. On Windows it's named zlib1.dll and
+you'll have to download it first from the
+» zlib site. The check for
+ffi.os makes sure we pass the right name to
+ffi.load().
+
+
+③ First, the maximum size of
+the compression buffer is obtained by calling the
+zlib.compressBound function with the length of the
+uncompressed string. The next line allocates a byte buffer of this
+size. The [?] in the type specification indicates a
+variable-length array (VLA). The actual number of elements of this
+array is given as the 2nd argument to ffi.new().
+
+
+④ This may look strange at
+first, but have a look at the declaration of the compress2
+function from zlib: the destination length is defined as a pointer!
+This is because you pass in the maximum buffer size and get back the
+actual length that was used.
+
+
+In C you'd pass in the address of a local variable
+(&buflen). But since there's no address-of operator in
+Lua, we'll just pass in a one-element array. Conveniently it can be
+initialized with the maximum buffer size in one step. Calling the
+actual zlib.compress2 function is then straightforward.
+
+
+⑤ We want to return the
+compressed data as a Lua string, so we'll use ffi.string().
+It needs a pointer to the start of the data and the actual length. The
+length has been returned in the buflen array, so we'll just
+get it from there.
+
+
+Note that since the function returns now, the buf and
+buflen variables will eventually be garbage collected. This
+is fine, because ffi.string() has copied the contents to a
+newly created (interned) Lua string. If you plan to call this function
+lots of times, consider reusing the buffers and/or handing back the
+results in buffers instead of strings. This will reduce the overhead
+for garbage collection and string interning.
+
+
+⑥ The uncompress
+functions does the exact opposite of the compress function.
+The compressed data doesn't include the size of the original string,
+so this needs to be passed in. Otherwise no surprises here.
+
+
+⑦ The code, that makes use
+of the functions we just defined, is just plain Lua code. It doesn't
+need to know anything about the LuaJIT FFI — the convenience
+wrapper functions completely hide it.
+
+
+One major advantage of the LuaJIT FFI is that you are now able to
+write those wrappers in Lua. And at a fraction of the time it
+would cost you to create an extra C module using the Lua/C API.
+Many of the simpler C functions can probably be used directly
+from your Lua code, without any wrappers.
+
+
+Side note: the zlib API uses the long type for passing
+lengths and sizes around. But all those zlib functions actually only
+deal with 32 bit values. This is an unfortunate choice for a
+public API, but may be explained by zlib's history — we'll just
+have to deal with it.
+
+
+First, you should know that a long is a 64 bit type e.g.
+on POSIX/x64 systems, but a 32 bit type on Windows/x64 and on
+32 bit systems. Thus a long result can be either a plain
+Lua number or a boxed 64 bit integer cdata object, depending on
+the target system.
+
+
+Ok, so the ffi.* functions generally accept cdata objects
+wherever you'd want to use a number. That's why we get a away with
+passing n to ffi.string() above. But other Lua
+library functions or modules don't know how to deal with this. So for
+maximum portability one needs to use tonumber() on returned
+long results before passing them on. Otherwise the
+application might work on some systems, but would fail in a POSIX/x64
+environment.
+
+
+
Defining Metamethods for a C Type
+
+The following code explains how to define metamethods for a C type.
+We define a simple point type and add some operations to it:
+
+① This defines the C type for a
+two-dimensional point object.
+
+
+② We have to declare the variable
+holding the point constructor first, because it's used inside of a
+metamethod.
+
+
+③ Let's define an __add
+metamethod which adds the coordinates of two points and creates a new
+point object. For simplicity, this function assumes that both arguments
+are points. But it could be any mix of objects, if at least one operand
+is of the required type (e.g. adding a point plus a number or vice
+versa). Our __len metamethod returns the distance of a point to
+the origin.
+
+
+④ If we run out of operators, we can
+define named methods, too. Here the __index table defines an
+area function. For custom indexing needs, one might want to
+define __index and __newindexfunctions instead.
+
+
+⑤ This associates the metamethods with
+our C type. This only needs to be done once. For convenience, a
+constructor is returned by
+ffi.metatype().
+We're not required to use it, though. The original C type can still
+be used e.g. to create an array of points. The metamethods automatically
+apply to any and all uses of this type.
+
+
+Please note that the association with a metatable is permanent and
+the metatable must not be modified afterwards! Ditto for the
+__index table.
+
+
+⑥ Here are some simple usage examples
+for the point type and their expected results. The pre-defined
+operations (such as a.x) can be freely mixed with the newly
+defined metamethods. Note that area is a method and must be
+called with the Lua syntax for methods: a:area(), not
+a.area().
+
+
+The C type metamethod mechanism is most useful when used in
+conjunction with C libraries that are written in an object-oriented
+style. Creators return a pointer to a new instance and methods take an
+instance pointer as the first argument. Sometimes you can just point
+__index to the library namespace and __gc to the
+destructor and you're done. But often enough you'll want to add
+convenience wrappers, e.g. to return actual Lua strings or when
+returning multiple values.
+
+
+Some C libraries only declare instance pointers as an opaque
+void * type. In this case you can use a fake type for all
+declarations, e.g. a pointer to a named (incomplete) struct will do:
+typedef struct foo_type *foo_handle. The C side doesn't
+know what you declare with the LuaJIT FFI, but as long as the underlying
+types are compatible, everything still works.
+
+
+
Translating C Idioms
+
+Here's a list of common C idioms and their translation to the
+LuaJIT FFI:
+
+
+
+
Idiom
+
C code
+
Lua code
+
+
+
Pointer dereference int *p;
x = *p; *p = y;
x = p[0] p[0] = y
+
+
Pointer indexing int i, *p;
x = p[i]; p[i+1] = y;
x = p[i] p[i+1] = y
+
+
Array indexing int i, a[];
x = a[i]; a[i+1] = y;
x = a[i] a[i+1] = y
+
+
struct/union dereference struct foo s;
x = s.field; s.field = y;
x = s.field s.field = y
+
+
struct/union pointer deref. struct foo *sp;
x = sp->field; sp->field = y;
x = s.field s.field = y
+
+
Pointer arithmetic int i, *p;
x = p + i; y = p - i;
x = p + i y = p - i
+
+
Pointer difference int *p1, *p2;
x = p1 - p2;
x = p1 - p2
+
+
Array element pointer int i, a[];
x = &a[i];
x = a+i
+
+
Cast pointer to address int *p;
x = (intptr_t)p;
x = tonumber( ffi.cast("intptr_t", p))
+
+
Functions with outargs void foo(int *inoutlen);
int len = x; foo(&len); y = len;
local len = ffi.new("int[1]", x) foo(len) y = len[0]
+This replaces several hash-table lookups with a (faster) direct use of
+a local or an upvalue. This is less important with LuaJIT, since the
+JIT compiler optimizes hash-table lookups a lot and is even able to
+hoist most of them out of the inner loops. It can't eliminate
+all of them, though, and it saves some typing for often-used
+functions. So there's still a place for this, even with LuaJIT.
+
+
+The situation is a bit different with C function calls via the
+FFI library. The JIT compiler has special logic to eliminate all
+of the lookup overhead for functions resolved from a
+C library namespace!
+Thus it's not helpful and actually counter-productive to cache
+individual C functions like this:
+
+
+local funca, funcb = ffi.C.funcb, ffi.C.funcb -- Not helpful!
+local function foo(x, n)
+ for i=1,n do funcb(funca(x, i), 1) end
+end
+
+
+This turns them into indirect calls and generates bigger and slower
+machine code. Instead you'll want to cache the namespace itself and
+rely on the JIT compiler to eliminate the lookups:
+
+
+local C = ffi.C -- Instead use this!
+local function foo(x, n)
+ for i=1,n do C.funcb(C.funca(x, i), 1) end
+end
+
+
+This generates both shorter and faster code. So don't cache
+C functions, but do cache namespaces! Most often the
+namespace is already in a local variable at an outer scope, e.g. from
+local lib = ffi.load(...). Note that copying
+it to a local variable in the function scope is unnecessary.
+
+The functions in this built-in module control the behavior of the JIT
+compiler engine. Note that JIT-compilation is fully automatic —
+you probably won't need to use any of the following functions unless
+you have special needs.
+
+
+
jit.on()
+jit.off()
+
+Turns the whole JIT compiler on (default) or off.
+
+
+These functions are typically used with the command line options
+-j on or -j off.
+
+jit.on enables JIT compilation for a Lua function (this is
+the default).
+
+
+jit.off disables JIT compilation for a Lua function and
+flushes any already compiled code from the code cache.
+
+
+jit.flush flushes the code, but doesn't affect the
+enable/disable status.
+
+
+The current function, i.e. the Lua function calling this library
+function, can also be specified by passing true as the first
+argument.
+
+
+If the second argument is true, JIT compilation is also
+enabled, disabled or flushed recursively for all sub-functions of a
+function. With false only the sub-functions are affected.
+
+
+The jit.on and jit.off functions only set a flag
+which is checked when the function is about to be compiled. They do
+not trigger immediate compilation.
+
+
+Typical usage is jit.off(true, true) in the main chunk
+of a module to turn off JIT compilation for the whole module for
+debugging purposes.
+
+
+
jit.flush(tr)
+
+Flushes the root trace, specified by its number, and all of its side
+traces from the cache. The code for the trace will be retained as long
+as there are any other traces which link to it.
+
+
+
status, ... = jit.status()
+
+Returns the current status of the JIT compiler. The first result is
+either true or false if the JIT compiler is turned
+on or off. The remaining results are strings for CPU-specific features
+and enabled optimizations.
+
+
+
jit.version
+
+Contains the LuaJIT version string.
+
+
+
jit.version_num
+
+Contains the version number of the LuaJIT core. Version xx.yy.zz
+is represented by the decimal number xxyyzz.
+
+
+
jit.os
+
+Contains the target OS name:
+"Windows", "Linux", "OSX", "BSD", "POSIX" or "Other".
+
+
+
jit.arch
+
+Contains the target architecture name:
+"x86", "x64" or "ppcspe".
+
+
+
jit.opt.* — JIT compiler optimization control
+
+This sub-module provides the backend for the -O command line
+option.
+
+
+You can also use it programmatically, e.g.:
+
+
+jit.opt.start(2) -- same as -O2
+jit.opt.start("-dce")
+jit.opt.start("hotloop=10", "hotexit=2")
+
+
+Unlike in LuaJIT 1.x, the module is built-in and
+optimization is turned on by default!
+It's no longer necessary to run require("jit.opt").start(),
+which was one of the ways to enable optimization.
+
+
+
jit.util.* — JIT compiler introspection
+
+This sub-module holds functions to introspect the bytecode, generated
+traces, the IR and the generated machine code. The functionality
+provided by this module is still in flux and therefore undocumented.
+
+
+The debug modules -jbc, -jv and -jdump make
+extensive use of these functions. Please check out their source code,
+if you want to know more.
+
+LuaJIT is also fully ABI-compatible to Lua 5.1 at the linker/dynamic
+loader level. This means you can compile a C module against the
+standard Lua headers and load the same shared library from either Lua
+or LuaJIT.
+
+
+LuaJIT extends the standard Lua VM with new functionality and adds
+several extension modules. Please note that this page is only about
+functional enhancements and not about performance enhancements,
+such as the optimized VM, the faster interpreter or the JIT compiler.
+
+
+
Extensions Modules
+
+LuaJIT comes with several built-in extension modules:
+
+
+
bit.* — Bitwise operations
+
+LuaJIT supports all bitwise operations as defined by
+» Lua BitOp:
+
+This module is a LuaJIT built-in — you don't need to download or
+install Lua BitOp. The Lua BitOp site has full documentation for all
+» Lua BitOp API functions.
+
+
+Please make sure to require the module before using any of
+its functions:
+
+
+local bit = require("bit")
+
+
+An already installed Lua BitOp module is ignored by LuaJIT.
+This way you can use bit operations from both Lua and LuaJIT on a
+shared installation.
+
+
+
ffi.* — FFI library
+
+The FFI library allows calling external
+C functions and the use of C data structures from pure Lua
+code.
+
+Unlike the standard implementation in Lua 5.1, xpcall()
+passes any arguments after the error function to the function
+which is called in a protected context.
+
+
+
loadfile() etc. handle UTF-8 source code
+
+Non-ASCII characters are handled transparently by the Lua source code parser.
+This allows the use of UTF-8 characters in identifiers and strings.
+A UTF-8 BOM is skipped at the start of the source code.
+
+
+
tostring() etc. canonicalize NaN and ±Inf
+
+All number-to-string conversions consistently convert non-finite numbers
+to the same strings on all platforms. NaN results in "nan",
+positive infinity results in "inf" and negative infinity results
+in "-inf".
+
+An extra argument has been added to string.dump(). If set to
+true, 'stripped' bytecode without debug information is
+generated. This speeds up later bytecode loading and reduces memory
+usage. See also the
+-b command line option.
+
+
+The generated bytecode is portable and can be loaded on any architecture
+that LuaJIT supports, independent of word size or endianess. However the
+bytecode compatibility versions must match. Bytecode stays compatible
+for dot releases (x.y.0 → x.y.1), but may change with major or
+minor releases (2.0 → 2.1) or between any beta release. Foreign
+bytecode (e.g. from Lua 5.1) is incompatible and cannot be loaded.
+
+
+
Enhanced PRNG for math.random()
+
+LuaJIT uses a Tausworthe PRNG with period 2^223 to implement
+math.random() and math.randomseed(). The quality of
+the PRNG results is much superior compared to the standard Lua
+implementation which uses the platform-specific ANSI rand().
+
+
+The PRNG generates the same sequences from the same seeds on all
+platforms and makes use of all bits in the seed argument.
+math.random() without arguments generates 52 pseudo-random bits
+for every call. The result is uniformly distributed between 0 and 1.
+It's correctly scaled up and rounded for math.random(n [,m]) to
+preserve uniformity.
+
+
+
io.* functions handle 64 bit file offsets
+
+The file I/O functions in the standard io.* library handle
+64 bit file offsets. In particular this means it's possible
+to open files larger than 2 Gigabytes and to reposition or obtain
+the current file position for offsets beyond 2 GB
+(fp:seek() method).
+
+
+
debug.* functions identify metamethods
+
+debug.getinfo() and lua_getinfo() also return information
+about invoked metamethods. The namewhat field is set to
+"metamethod" and the name field has the name of
+the corresponding metamethod (e.g. "__index").
+
+
+
Fully Resumable VM
+
+The LuaJIT 2.x VM is fully resumable. This means you can yield from a
+coroutine even across contexts, where this would not possible with
+the standard Lua 5.1 VM: e.g. you can yield across pcall()
+and xpcall(), across iterators and across metamethods.
+
+
+Note however that LuaJIT 2.x doesn't use
+» Coco anymore. This means the
+overhead for creating coroutines is much smaller and no extra
+C stacks need to be allocated. OTOH you can no longer yield
+across arbitrary C functions. Keep this in mind when
+upgrading from LuaJIT 1.x.
+
+
+
C++ Exception Interoperability
+
+LuaJIT has built-in support for interoperating with C++ exceptions.
+The available range of features depends on the target platform and
+the toolchain used to compile LuaJIT:
+
+
+
+
Platform
+
Compiler
+
Interoperability
+
+
+
POSIX/x64, DWARF2 unwinding
+
GCC 4.3+
+
Full
+
+
+
Other platforms, DWARF2 unwinding
+
GCC
+
Limited
+
+
+
Windows/x64
+
MSVC or WinSDK
+
Full
+
+
+
Windows/x86
+
Any
+
No
+
+
+
Other platforms
+
Other compilers
+
No
+
+
+
+Full interoperability means:
+
+
+
C++ exceptions can be caught on the Lua side with pcall(),
+lua_pcall() etc.
+
C++ exceptions will be converted to the generic Lua error
+"C++ exception", unless you use the
+C call wrapper feature.
+
It's safe to throw C++ exceptions across non-protected Lua frames
+on the C stack. The contents of the C++ exception object
+pass through unmodified.
+
Lua errors can be caught on the C++ side with catch(...).
+The corresponding Lua error message can be retrieved from the Lua stack.
+
Throwing Lua errors across C++ frames is safe. C++ destructors
+will be called.
+
+
+Limited interoperability means:
+
+
+
C++ exceptions can be caught on the Lua side with pcall(),
+lua_pcall() etc.
+
C++ exceptions will be converted to the generic Lua error
+"C++ exception", unless you use the
+C call wrapper feature.
+
C++ exceptions will be caught by non-protected Lua frames and
+are rethrown as a generic Lua error. The C++ exception object will
+be destroyed.
+
Lua errors cannot be caught on the C++ side.
+
Throwing Lua errors across C++ frames will not call
+C++ destructors.
+
+
+
+No interoperability means:
+
+
+
It's not safe to throw C++ exceptions across Lua frames.
+
C++ exceptions cannot be caught on the Lua side.
+
Lua errors cannot be caught on the C++ side.
+
Throwing Lua errors across C++ frames will not call
+C++ destructors.
+
Additionally, on Windows/x86 with SEH-based C++ exceptions:
+it's not safe to throw a Lua error across any frames containing
+a C++ function with any try/catch construct or using variables with
+(implicit) destructors. This also applies to any functions which may be
+inlined in such a function. It doesn't matter whether lua_error()
+is called inside or outside of a try/catch or whether any object actually
+needs to be destroyed: the SEH chain is corrupted and this will eventually
+lead to the termination of the process.
The community-managed » Lua Wiki
+has information about diverse topics.
+
The primary source of information for the latest developments surrounding
+Lua is the » Lua mailing list.
+You can check out the » mailing
+list archive or
+» subscribe
+to the list (you need to be subscribed before posting).
+This is also the place where announcements and discussions about LuaJIT
+take place.
+
+
+
+
+
Q: Where can I learn more about the compiler technology used by LuaJIT?
Q: Why do I get this error: "attempt to index global 'arg' (a nil value)"?
+Q: My vararg functions fail after switching to LuaJIT!
+
LuaJIT is compatible to the Lua 5.1 language standard. It doesn't
+support the implicit arg parameter for old-style vararg
+functions from Lua 5.0. Please convert your code to the
+» Lua 5.1
+vararg syntax.
+
+
+
+
Q: Why do I get this error: "bad FPU precision"?
+
Q: I get weird behavior after initializing Direct3D.
+
Q: Some FPU operations crash after I load a Delphi DLL.
+
+
+
+DirectX/Direct3D (up to version 9) sets the x87 FPU to single-precision
+mode by default. This violates the Windows ABI and interferes with the
+operation of many programs — LuaJIT is affected, too. Please make
+sure you always use the D3DCREATE_FPU_PRESERVE flag when
+initializing Direct3D.
+
+Direct3D version 10 or higher do not show this behavior anymore.
+Consider testing your application with older versions, too.
+
+Similarly, the Borland/Delphi runtime modifies the FPU control word and
+enables FP exceptions. Of course this violates the Windows ABI, too.
+Please check the Delphi docs for the Set8087CW method.
+
+
+
+
+
Q: Sometimes Ctrl-C fails to stop my Lua program. Why?
+
The interrupt signal handler sets a Lua debug hook. But this is
+currently ignored by compiled code (this will eventually be fixed). If
+your program is running in a tight loop and never falls back to the
+interpreter, the debug hook never runs and can't throw the
+"interrupted!" error. In the meantime you have to press Ctrl-C
+twice to get stop your program. That's similar to when it's stuck
+running inside a C function under the Lua interpreter.
+
+
+
+
Q: Why doesn't my favorite power-patch for Lua apply against LuaJIT?
+
Because it's a completely redesigned VM and has very little code
+in common with Lua anymore. Also, if the patch introduces changes to
+the Lua semantics, these would need to be reflected everywhere in the
+VM, from the interpreter up to all stages of the compiler. Please
+use only standard Lua language constructs. For many common needs you
+can use source transformations or use wrapper or proxy functions.
+The compiler will happily optimize away such indirections.
+
+
+
+
Q: Lua runs everywhere. Why doesn't LuaJIT support my CPU?
+
Because it's a compiler — it needs to generate native
+machine code. This means the code generator must be ported to each
+architecture. And the fast interpreter is written in assembler and
+must be ported, too. This is quite an undertaking.
+The install documentation shows the supported
+architectures. Other architectures will follow based on sufficient user
+demand and/or sponsoring.
+
+
+
+
Q: When will feature X be added? When will the next version be released?
+
When it's ready.
+C'mon, it's open source — I'm doing it on my own time and you're
+getting it for free. You can either contribute a patch or sponsor
+the development of certain features, if they are important to you.
+
+LuaJIT is only distributed as a source package. This page explains
+how to build and install LuaJIT with different operating systems
+and C compilers.
+
+
+For the impatient (on POSIX systems):
+
+
+make && sudo make install
+
+
+LuaJIT currently builds out-of-the box on most systems.
+Here's the compatibility matrix for the supported combinations of
+operating systems, CPUs and compilers:
+
+The standard configuration should work fine for most installations.
+Usually there is no need to tweak the settings. The following files
+hold all user-configurable settings:
+
+
+
src/luaconf.h sets some configuration variables.
+
Makefile has settings for installing LuaJIT (POSIX
+only).
+
src/Makefile has settings for compiling LuaJIT
+under POSIX, MinGW or Cygwin.
+
src/msvcbuild.bat has settings for compiling LuaJIT with
+MSVC or WinSDK.
+
+
+Please read the instructions given in these files, before changing
+any settings.
+
+
+
POSIX Systems (Linux, OSX, *BSD etc.)
+
Prerequisites
+
+Depending on your distribution, you may need to install a package for
+GCC, the development headers and/or a complete SDK. E.g. on a current
+Debian/Ubuntu, install libc6-dev with the package manager.
+
+
+Download the current source package of LuaJIT (pick the .tar.gz),
+if you haven't already done so. Move it to a directory of your choice,
+open a terminal window and change to this directory. Now unpack the archive
+and change to the newly created directory:
+
+The supplied Makefiles try to auto-detect the settings needed for your
+operating system and your compiler. They need to be run with GNU Make,
+which is probably the default on your system, anyway. Simply run:
+
+
+make
+
+
+This always builds a native x86, x64 or PPC binary, depending on the host OS
+you're running this command on. Check the section on
+cross-compilation for more options.
+
+
+By default, modules are only searched under the prefix /usr/local.
+You can add an extra prefix to the search paths by appending the
+PREFIX option, e.g.:
+
+
+make PREFIX=/home/myself/lj2
+
+
+Note for OSX: MACOSX_DEPLOYMENT_TARGET is set to 10.4
+in src/Makefile. Change it, if you want to build on an older version.
+
+
Installing LuaJIT
+
+The top-level Makefile installs LuaJIT by default under
+/usr/local, i.e. the executable ends up in
+/usr/local/bin and so on. You need root privileges
+to write to this path. So, assuming sudo is installed on your system,
+run the following command and enter your sudo password:
+
+
+sudo make install
+
+
+Otherwise specify the directory prefix as an absolute path, e.g.:
+
+
+make install PREFIX=/home/myself/lj2
+
+
+Obviously the prefixes given during build and installation need to be the same.
+
+
+Note: to avoid overwriting a previous version, the beta test releases
+only install the LuaJIT executable under the versioned name (i.e.
+luajit-2.0.0-beta9). You probably want to create a symlink
+for convenience, with a command like this:
+
+Either install one of the open source SDKs
+(» MinGW or
+» Cygwin), which come with a modified
+GCC plus the required development headers.
+
+
+Or install Microsoft's Visual C++ (MSVC). The freely downloadable
+» Express Edition
+works just fine, but only contains an x86 compiler.
+
+
+The freely downloadable
+» Windows SDK
+only comes with command line tools, but this is all you need to build LuaJIT.
+It contains x86 and x64 compilers.
+
+
+Next, download the source package and unpack it using an archive manager
+(e.g. the Windows Explorer) to a directory of your choice.
+
+
Building with MSVC
+
+Open a "Visual Studio .NET Command Prompt", cd to the
+directory where you've unpacked the sources and run these commands:
+
+
+cd src
+msvcbuild
+
+
+Then follow the installation instructions below.
+
+
Building with the Windows SDK
+
+Open a "Windows SDK Command Shell" and select the x86 compiler:
+
+
+setenv /release /x86
+
+
+Or select the x64 compiler:
+
+
+setenv /release /x64
+
+
+Then cd to the directory where you've unpacked the sources
+and run these commands:
+
+
+cd src
+msvcbuild
+
+
+Then follow the installation instructions below.
+
+
Building with MinGW or Cygwin
+
+Open a command prompt window and make sure the MinGW or Cygwin programs
+are in your path. Then cd to the directory where
+you've unpacked the sources and run this command for MinGW:
+
+
+mingw32-make
+
+
+Or this command for Cygwin:
+
+
+make
+
+
+Then follow the installation instructions below.
+
+
Installing LuaJIT
+
+Copy luajit.exe and lua51.dll (built in the src
+directory) to a newly created directory (any location is ok).
+Add lua and lua\jit directories below it and copy
+all Lua files from the lib directory of the distribution
+to the latter directory.
+
+
+There are no hardcoded
+absolute path names — all modules are loaded relative to the
+directory where luajit.exe is installed
+(see src/luaconf.h).
+
+
+
Cross-compiling LuaJIT
+
+The build system has limited support for cross-compilation. For details
+check the comments in src/Makefile. Here are some popular examples:
+
+
+You can cross-compile to a 32 bit binary on a multilib x64 OS by
+installing the multilib development packages (e.g. libc6-dev-i386
+on Debian/Ubuntu) and running:
+
+
+make CC="gcc -m32"
+
+
+You can cross-compile for a Windows target on Debian/Ubuntu by
+installing the mingw32 package and running:
+
+You can cross-compile for an ARM target on an x86 or x64 host
+system using a standard GNU cross-compile toolchain (Binutils, GCC,
+EGLIBC). The CROSS prefix may vary depending on the
+--target of the toolchain:
+
+You can cross-compile for Android (ARM) using the » Android NDK.
+The environment variables need to match the install locations and the
+desired target platform. E.g. Android 2.2 corresponds to ABI level 8:
+
+You can cross-compile for iOS 3.0+ (iPhone/iPad) using the » iOS SDK.
+The environment variables need to match the iOS SDK version:
+
+
+Note: the JIT compiler is disabled for iOS, because regular iOS Apps
+are not allowed to generate code at runtime. You'll only get the performance
+of the LuaJIT interpreter on iOS. This is still faster than plain Lua, but
+much slower than the JIT compiler. Please complain to Apple, not me.
+Or use Android. :-p
+
+You can cross-compile for a PPC target or a
+PPC/e500v2 target on x86 or x64 host systems using a standard
+GNU cross-compile toolchain (Binutils, GCC, EGLIBC).
+The CROSS prefix may vary depending on the --target
+of the toolchain:
+
+Whenever the host OS and the target OS differ, you need to specify
+TARGET_SYS or you'll get assembler or linker errors. E.g. if
+you're compiling on a Windows or OSX host for embedded Linux or Android,
+you need to add TARGET_SYS=Linux to the examples above. For a
+minimal target OS, you may need to disable the built-in allocator in
+src/Makefile and use TARGET_SYS=Other.
+
+
+
Embedding LuaJIT
+
+LuaJIT is API-compatible with Lua 5.1. If you've already embedded Lua
+into your application, you probably don't need to do anything to switch
+to LuaJIT, except link with a different library:
+
+
+
It's strongly suggested to build LuaJIT separately using the supplied
+build system. Please do not attempt to integrate the individual
+source files into your build tree. You'll most likely get the internal build
+dependencies wrong or mess up the compiler flags. Treat LuaJIT like any
+other external library and link your application with either the dynamic
+or static library, depending on your needs.
+
If you want to load C modules compiled for plain Lua
+with require(), you need to make sure the public symbols
+(e.g. lua_pushnumber) are exported, too:
+
On POSIX systems you can either link to the shared library
+or link the static library into your application. In the latter case
+you'll need to export all public symbols from your main executable
+(e.g. -Wl,-E on Linux) and add the external dependencies
+(e.g. -lm -ldl on Linux).
+
Since Windows symbols are bound to a specific DLL name, you need to
+link to the lua51.dll created by the LuaJIT build (do not rename
+the DLL). You may link LuaJIT statically on Windows only if you don't
+intend to load Lua/C modules at runtime.
+
+
+
+If you're building a 64 bit application on OSX which links directly or
+indirectly against LuaJIT, you need to link your main executable
+with these flags:
+
+-pagezero_size 10000 -image_base 100000000
+
+Also, it's recommended to rebase all (self-compiled) shared libraries
+which are loaded at runtime on OSX/x64 (e.g. C extension modules for Lua).
+See: man rebase
+
+
+
Additional hints for initializing LuaJIT using the C API functions:
+
+
Here's a
+» simple example
+for embedding Lua or LuaJIT into your application.
+
Make sure you use luaL_newstate. Avoid using
+lua_newstate, since this uses the (slower) default memory
+allocator from your system (no support for this on x64).
+
Make sure you use luaL_openlibs and not the old Lua 5.0 style
+of calling luaopen_base etc. directly.
+
To change or extend the list of standard libraries to load, copy
+src/lib_init.c to your project and modify it accordingly.
+Make sure the jit library is loaded or the JIT compiler
+will not be activated.
+
The bit.* module for bitwise operations
+is already built-in. There's no need to statically link
+» Lua BitOp to your application.
+
+
+
Hints for Distribution Maintainers
+
+The LuaJIT build system has extra provisions for the needs of most
+POSIX-based distributions. If you're a package maintainer for
+a distribution, please make use of these features and
+avoid patching, subverting, autotoolizing or messing up the build system
+in unspeakable ways.
+
+
+There should be absolutely no need to patch luaconf.h or any
+of the Makefiles. And please do not hand-pick files for your packages —
+simply use whatever make install creates. There's a reason
+for all of the files and directories it creates.
+
+
+The build system uses GNU make and auto-detects most settings based on
+the host you're building it on. This should work fine for native builds,
+even when sandboxed. You may need to pass some of the following flags to
+both the make and the make install command lines
+for a regular distribution build:
+
+
+
PREFIX overrides the installation path and should usually
+be set to /usr. Setting this also changes the module paths and
+the -rpath of the shared library.
+
DESTDIR is an absolute path which allows you to install
+to a shadow tree instead of the root tree of the build system.
+
Have a look at the top-level Makefile and src/Makefile
+for additional variables to tweak. The following variables may be
+overridden, but it's not recommended, except for special needs
+like cross-builds:
+BUILDMODE, CC, HOST_CC, STATIC_CC, DYNAMIC_CC, CFLAGS, HOST_CFLAGS,
+TARGET_CFLAGS, LDFLAGS, HOST_LDFLAGS, TARGET_LDFLAGS, TARGET_SHLDFLAGS,
+TARGET_FLAGS, LIBS, HOST_LIBS, TARGET_LIBS, CROSS, HOST_SYS, TARGET_SYS
+
+
+
+The build system has a special target for an amalgamated build, i.e.
+make amalg. This compiles the LuaJIT core as one huge C file
+and allows GCC to generate faster and shorter code. Alas, this requires
+lots of memory during the build. This may be a problem for some users,
+that's why it's not enabled by default. But it shouldn't be a problem for
+most build farms. It's recommended that binary distributions use this
+target for their LuaJIT builds.
+
+Finally, if you encounter any difficulties, please
+contact me first, instead of releasing a broken
+package onto unsuspecting users. Because they'll usually gonna complain
+to me (the upstream) and not you (the package maintainer), anyway.
+
+* Lua is a powerful, dynamic and light-weight programming language
+designed for extending applications. Lua is also frequently used as a
+general-purpose, stand-alone language. More information about
+Lua can be found at: » http://www.lua.org/
+
+
Compatibility
+
+LuaJIT implements the full set of language features defined by Lua 5.1.
+The virtual machine (VM) is API- and ABI-compatible to the
+standard Lua interpreter and can be deployed as a drop-in replacement.
+
+
+LuaJIT offers more performance, at the expense of portability. It
+currently runs on all popular operating systems based on
+x86 or x64 CPUs (Linux, Windows, OSX etc.) or embedded
+systems based on ARM (Android, iOS) or PPC CPUs.
+Other platforms will be supported in the future, based on user demand
+and sponsoring.
+
+
+
Overview
+
+LuaJIT has been successfully used as a scripting middleware in
+games, 3D modellers, numerical simulations, trading platforms and many
+other specialty applications. It combines high flexibility with high
+performance and an unmatched low memory footprint: less than
+125K for the VM plus less than 85K for the JIT compiler (on x86).
+
+
+LuaJIT has been in continuous development since 2005. It's widely
+considered to be one of the fastest dynamic language
+implementations. It has outperformed other dynamic languages on many
+cross-language benchmarks since its first release — often by a
+substantial margin. In 2009 other dynamic language VMs started to catch up
+with the performance of LuaJIT 1.x. Well, I couldn't let that slide. ;-)
+
+
+2009 also marks the first release of the long-awaited LuaJIT 2.0.
+The whole VM has been rewritten from the ground up and relentlessly
+optimized for performance. It combines a high-speed interpreter,
+written in assembler, with a state-of-the-art JIT compiler.
+
+
+An innovative trace compiler is integrated with advanced,
+SSA-based optimizations and a highly tuned code generation backend. This
+allows a substantial reduction of the overhead associated with dynamic
+language features.
+
+
+It's destined to break into the » performance
+range traditionally reserved for offline, static language compilers.
+
+
+
More ...
+
+Click on the LuaJIT sub-topics in the navigation bar to learn more
+about LuaJIT.
+
+
+Click on the Logo in the upper left corner to visit
+the LuaJIT project page on the web. All other links to online
+resources are marked with a '»'.
+
+LuaJIT has only a single stand-alone executable, called luajit on
+POSIX systems or luajit.exe on Windows. It can be used to run simple
+Lua statements or whole Lua applications from the command line. It has an
+interactive mode, too.
+
+
+Note: the beta test releases only install under the versioned name on
+POSIX systems (to avoid overwriting a previous version). You either need
+to type luajit-2.0.0-beta9 to start it or create a symlink
+with a command like this:
+
+Unlike previous versions optimization is turned on by default in
+LuaJIT 2.0! It's no longer necessary to use luajit -O.
+
+
+
Command Line Options
+
+The luajit stand-alone executable is just a slightly modified
+version of the regular lua stand-alone executable.
+It supports the same basic options, too. luajit -h
+prints a short list of the available options. Please have a look at the
+» Lua manual
+for details.
+
+
+LuaJIT has some additional options:
+
+
+
-b[options] input output
+
+This option saves or lists bytecode. The following additional options
+are accepted:
+
+
+
-l — Only list bytecode.
+
-s — Strip debug info (this is the default).
+
-g — Keep debug info.
+
-n name — Set module name (default: auto-detect from input name)
+
-t type — Set output file type (default: auto-detect from output name).
+
-a arch — Override architecture for object files (default: native).
+
-o os — Override OS for object files (default: native).
+
-e chunk — Use chunk string as input.
+
- (a single minus sign) — Use stdin as input and/or stdout as output.
+
+
+The output file type is auto-detected from the extension of the output
+file name:
+
+
+
c — C source file, exported bytecode data.
+
h — C header file, static bytecode data.
+
obj or o — Object file, exported bytecode data
+(OS- and architecture-specific).
+
raw or any other extension — Raw bytecode file (portable).
+
+
+Notes:
+
+
+
See also string.dump()
+for information on bytecode portability and compatibility.
+
A file in raw bytecode format is auto-detected and can be loaded like
+any Lua source file. E.g. directly from the command line or with
+loadfile(), dofile() etc.
+
To statically embed the bytecode of a module in your application,
+generate an object file and just link it with your application.
+
On most ELF-based systems (e.g. Linux) you need to explicitly export the
+global symbols when linking your application, e.g. with: -Wl,-E
+
require() tries to load embedded bytecode data from exported
+symbols (in *.exe or lua51.dll on Windows) and from
+shared libraries in package.cpath.
+
+
+Typical usage examples:
+
+
+luajit -b test.lua test.out # Save bytecode to test.out
+luajit -bg test.lua test.out # Keep debug info
+luajit -be "print('hello world')" test.out # Save cmdline script
+
+luajit -bl test.lua # List to stdout
+luajit -bl test.lua test.txt # List to test.txt
+luajit -ble "print('hello world')" # List cmdline script
+
+luajit -b test.lua test.obj # Generate object file
+# Link test.obj with your application and load it with require("test")
+
+
+
-j cmd[=arg[,arg...]]
+
+This option performs a LuaJIT control command or activates one of the
+loadable extension modules. The command is first looked up in the
+jit.* library. If no matching function is found, a module
+named jit.<cmd> is loaded and the start()
+function of the module is called with the specified arguments (if
+any). The space between -j and cmd is optional.
+
+
+Here are the available LuaJIT control commands:
+
+
+
-jon — Turns the JIT compiler on (default).
+
-joff — Turns the JIT compiler off (only use the interpreter).
+
-jflush — Flushes the whole cache of compiled code.
+
-jv — Shows verbose information about the progress of the JIT compiler.
+
-jdump — Dumps the code and structures used in various compiler stages.
+
+
+The -jv and -jdump commands are extension modules
+written in Lua. They are mainly used for debugging the JIT compiler
+itself. For a description of their options and output format, please
+read the comment block at the start of their source.
+They can be found in the lib directory of the source
+distribution or installed under the jit directory. By default
+this is /usr/local/share/luajit-2.0.0-beta9/jit on POSIX
+systems.
+
+
+
-O[level]
+-O[+]flag-O-flag
+-Oparam=value
+
+This options allows fine-tuned control of the optimizations used by
+the JIT compiler. This is mainly intended for debugging LuaJIT itself.
+Please note that the JIT compiler is extremely fast (we are talking
+about the microsecond to millisecond range). Disabling optimizations
+doesn't have any visible impact on its overhead, but usually generates
+code that runs slower.
+
+
+The first form sets an optimization level — this enables a
+specific mix of optimization flags. -O0 turns off all
+optimizations and higher numbers enable more optimizations. Omitting
+the level (i.e. just -O) sets the default optimization level,
+which is -O3 in the current version.
+
+
+The second form adds or removes individual optimization flags.
+The third form sets a parameter for the VM or the JIT compiler
+to a specific value.
+
+
+You can either use this option multiple times (like -Ocse
+-O-dce -Ohotloop=10) or separate several settings with a comma
+(like -O+cse,-dce,hotloop=10). The settings are applied from
+left to right and later settings override earlier ones. You can freely
+mix the three forms, but note that setting an optimization level
+overrides all earlier flags.
+
+
+Here are the available flags and at what optimization levels they
+are enabled:
+
+
+
+
Flag
+
-O1
+
-O2
+
-O3
+
+
+
+
fold
•
•
•
Constant Folding, Simplifications and Reassociation
+
+
cse
•
•
•
Common-Subexpression Elimination
+
+
dce
•
•
•
Dead-Code Elimination
+
+
narrow
•
•
Narrowing of numbers to integers
+
+
loop
•
•
Loop Optimizations (code hoisting)
+
+
fwd
•
Load Forwarding (L2L) and Store Forwarding (S2L)
+
+
dse
•
Dead-Store Elimination
+
+
abc
•
Array Bounds Check Elimination
+
+
fuse
•
Fusion of operands into instructions
+
+
+Here are the parameters and their default settings:
+
+
+
+
Parameter
+
Default
+
+
+
+
maxtrace
1000
Max. number of traces in the cache
+
+
maxrecord
4000
Max. number of recorded IR instructions
+
+
maxirconst
500
Max. number of IR constants of a trace
+
+
maxside
100
Max. number of side traces of a root trace
+
+
maxsnap
500
Max. number of snapshots for a trace
+
+
hotloop
56
Number of iterations to detect a hot loop or hot call
+
+
hotexit
10
Number of taken exits to start a side trace
+
+
tryside
4
Number of attempts to compile a side trace
+
+
instunroll
4
Max. unroll factor for instable loops
+
+
loopunroll
15
Max. unroll factor for loop ops in side traces
+
+
callunroll
3
Max. unroll factor for pseudo-recursive calls
+
+
recunroll
2
Min. unroll factor for true recursion
+
+
sizemcode
32
Size of each machine code area in KBytes (Windows: 64K)
+
+
maxmcode
512
Max. total size of all machine code areas in KBytes
+The LuaJIT 1.x series represents
+the current stable branch.
+Only a single bug has been discovered in the last two years. So, if
+you need a rock-solid VM, you are encouraged to fetch the latest
+release of LuaJIT 1.x from the » Download
+page.
+
+
+LuaJIT 2.0 is the currently active
+development branch.
+It has Beta Test status and is still undergoing
+substantial changes.
+It has » much better performance than LuaJIT 1.x.
+It's maturing quickly, so you should definitely
+start to evaluate it for new projects right now.
+
+
+
Current Status
+
+This is a list of the things you should know about the LuaJIT 2.0 beta test:
+
+
+
+Obviously there will be some bugs in a VM which has been
+rewritten from the ground up. Please report your findings together with
+the circumstances needed to reproduce the bug. If possible, reduce the
+problem down to a simple test case.
+There is no formal bug tracker at the moment. The best place for
+discussion is the
+» Lua mailing list. Of course
+you may also send your bug reports directly to me,
+especially when they contain lengthy debug output or if you require
+confidentiality.
+
+
+The x86 JIT compiler only generates code for CPUs with support for
+SSE2 instructions. I.e. you need at least a P4, Core 2/i3/i5/i7,
+Atom or K8/K10 to get the full benefit.
+If you run LuaJIT on older CPUs without SSE2 support, the JIT compiler
+is disabled and the VM falls back to the LuaJIT interpreter. This is faster
+than the Lua interpreter, but not nearly as fast as the JIT compiler of course.
+Run the command line executable without arguments to show the current status
+(JIT: ON or JIT: OFF).
+
+
+The VM is complete in the sense that it should run all Lua code
+just fine. It's considered a serious bug if the VM crashes or produces
+unexpected results — please report this. There are only very few
+known incompatibilities with standard Lua:
+
+
+The Lua debug API is missing a couple of features (return
+hooks for non-Lua functions) and shows slightly different behavior
+(no per-coroutine hooks, no tail call counting).
+
+
+Some of the configuration options of Lua 5.1 are not supported:
+
+
The number type cannot be changed (it's always a double).
+
The stand-alone executable cannot be linked with readline
+to enable line editing. It's planned to add support for loading it
+on-demand.
+
+
+
+Most other issues you're likely to find (e.g. with the existing test
+suites) are differences in the implementation-defined behavior.
+These either have a good reason (like early tail call resolving which
+may cause differences in error reporting), are arbitrary design choices
+or are due to quirks in the VM. The latter cases may get fixed if a
+demonstrable need is shown.
+
+
+
+
+The JIT compiler falls back to the
+interpreter in some cases. All of this works transparently, so unless
+you use -jv, you'll probably never notice (the interpreter is
+» quite fast, too). Here are the known issues:
+
+
+Most known issues cause a NYI (not yet implemented) trace abort
+message. E.g. for calls to some internal library
+functions. Reporting these is only mildly useful, except if you have good
+example code that shows the problem. Obviously, reports accompanied with
+a patch to fix the issue are more than welcome. But please check back
+with me, before writing major improvements, to avoid duplication of
+effort.
+
+
+Some checks are missing in the JIT-compiled code for obscure situations
+with open upvalues aliasing one of the SSA slots later on (or
+vice versa). Bonus points, if you can find a real world test case for
+this.
+
+
+Currently some out-of-memory errors from on-trace code are not
+handled correctly. The error may fall through an on-trace
+pcall (x86) or it may be passed on to the function set with
+lua_atpanic (x64).
+
+
+
+
+
+
Roadmap
+
+Please refer to the
+» LuaJIT
+Roadmap 2011 for the latest release plan. Here's the general
+project plan for LuaJIT 2.0:
+
+
+
+The main goal right now is to stabilize LuaJIT 2.0 and get it out of
+beta test. Correctness has priority over completeness. This
+implies the first stable release will certainly NOT compile every
+library function call and will fall back to the interpreter from time
+to time. This is perfectly ok, since it still executes all Lua code,
+just not at the highest possible speed.
+
+
+The next step is to get it to compile more library functions and handle
+more cases where the compiler currently bails out. This doesn't mean it
+will compile every corner case. It's much more important that it
+performs well in a majority of use cases. Every compiler has to make
+these trade-offs — completeness just cannot be the
+overriding goal for a low-footprint, low-overhead JIT compiler.
+
+
+More optimizations will be added in parallel to the last step on
+an as-needed basis. Sinking of stores
+to aggregates and sinking of allocations are high on the list.
+More complex optimizations with less pay-off, such as value-range-propagation
+(VRP) will have to wait.
+
+
+LuaJIT 2.0 has been designed with portability in mind.
+Nonetheless, it compiles to native code and needs to be adapted to each
+architecture. The two major work items are porting the the fast interpreter,
+which is written in assembler, and porting the compiler backend.
+Most other portability issues like endianess or 32 vs. 64 bit CPUs
+have already been taken care of.
+Several ports are already available, thanks to the
+» LuaJIT sponsorship program.
+More ports will follow in the future — companies which are
+interested in sponsoring a port to a particular architecture, please
+use the given contact address.
+
+
+Documentation about the internals of LuaJIT is still sorely
+missing. Although the source code is included and is IMHO well
+commented, many basic design decisions are in need of an explanation.
+The rather un-traditional compiler architecture and the many highly
+optimized data structures are a barrier for outside participation in
+the development. Alas, as I've repeatedly stated, I'm better at
+writing code than papers and I'm not in need of any academic merits.
+Someday I will find the time for it. :-)
+
+
+Producing good code for unbiased branches is a key problem for trace
+compilers. This is the main cause for "trace explosion".
+Hyperblock scheduling promises to solve this nicely at the
+price of a major redesign of the compiler. This would also pave the
+way for emitting predicated instructions, which is a prerequisite
+for efficient vectorization.
+