-
-
-
-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
deleted file mode 100644
index 2dbb198..0000000
Binary files a/libraries/LuaJIT-1.1.7/doc/cover.png and /dev/null differ
diff --git a/libraries/LuaJIT-1.1.7/doc/logo.gif b/libraries/LuaJIT-1.1.7/doc/logo.gif
deleted file mode 100644
index 2f5e4ac..0000000
Binary files a/libraries/LuaJIT-1.1.7/doc/logo.gif and /dev/null differ
diff --git a/libraries/LuaJIT-1.1.7/doc/lua.1 b/libraries/LuaJIT-1.1.7/doc/lua.1
deleted file mode 100644
index 24809cc..0000000
--- a/libraries/LuaJIT-1.1.7/doc/lua.1
+++ /dev/null
@@ -1,163 +0,0 @@
-.\" $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
deleted file mode 100644
index 039cf11..0000000
--- a/libraries/LuaJIT-1.1.7/doc/lua.css
+++ /dev/null
@@ -1,41 +0,0 @@
-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
deleted file mode 100644
index 1d435ab..0000000
--- a/libraries/LuaJIT-1.1.7/doc/lua.html
+++ /dev/null
@@ -1,172 +0,0 @@
-
-
-
-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
deleted file mode 100644
index d814678..0000000
--- a/libraries/LuaJIT-1.1.7/doc/luac.1
+++ /dev/null
@@ -1,136 +0,0 @@
-.\" $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
deleted file mode 100644
index 179ffe8..0000000
--- a/libraries/LuaJIT-1.1.7/doc/luac.html
+++ /dev/null
@@ -1,145 +0,0 @@
-
-
-
-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
deleted file mode 100644
index c194cba..0000000
--- a/libraries/LuaJIT-1.1.7/dynasm/dasm_proto.h
+++ /dev/null
@@ -1,68 +0,0 @@
-/*
-** 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
deleted file mode 100644
index 2d4fb26..0000000
--- a/libraries/LuaJIT-1.1.7/dynasm/dasm_x86.h
+++ /dev/null
@@ -1,455 +0,0 @@
-/*
-** 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
deleted file mode 100644
index 026c3b0..0000000
--- a/libraries/LuaJIT-1.1.7/dynasm/dasm_x86.lua
+++ /dev/null
@@ -1,1581 +0,0 @@
-------------------------------------------------------------------------------
--- 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
deleted file mode 100644
index 264a4bb..0000000
--- a/libraries/LuaJIT-1.1.7/dynasm/dynasm.lua
+++ /dev/null
@@ -1,1070 +0,0 @@
-------------------------------------------------------------------------------
--- 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
deleted file mode 100644
index 98117d0..0000000
--- a/libraries/LuaJIT-1.1.7/etc/README
+++ /dev/null
@@ -1,20 +0,0 @@
-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
deleted file mode 100644
index ec417f5..0000000
--- a/libraries/LuaJIT-1.1.7/etc/lua.hpp
+++ /dev/null
@@ -1,9 +0,0 @@
-// 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
deleted file mode 100644
index bdd7a90..0000000
Binary files a/libraries/LuaJIT-1.1.7/etc/luajit.ico and /dev/null differ
diff --git a/libraries/LuaJIT-1.1.7/etc/luajit.pc b/libraries/LuaJIT-1.1.7/etc/luajit.pc
deleted file mode 100644
index 1444076..0000000
--- a/libraries/LuaJIT-1.1.7/etc/luajit.pc
+++ /dev/null
@@ -1,28 +0,0 @@
-# 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
deleted file mode 100755
index 4f311e2..0000000
--- a/libraries/LuaJIT-1.1.7/etc/luavs.bat
+++ /dev/null
@@ -1,22 +0,0 @@
-@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
deleted file mode 100644
index 604619d..0000000
--- a/libraries/LuaJIT-1.1.7/etc/strict.lua
+++ /dev/null
@@ -1,41 +0,0 @@
---
--- 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
deleted file mode 100644
index b9ca150..0000000
--- a/libraries/LuaJIT-1.1.7/jit/dis_x86.lua
+++ /dev/null
@@ -1,622 +0,0 @@
-----------------------------------------------------------------------------
--- 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
deleted file mode 100644
index 2287c23..0000000
--- a/libraries/LuaJIT-1.1.7/jit/dump.lua
+++ /dev/null
@@ -1,265 +0,0 @@
-----------------------------------------------------------------------------
--- 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
deleted file mode 100644
index 4a64676..0000000
--- a/libraries/LuaJIT-1.1.7/jit/dumphints.lua
+++ /dev/null
@@ -1,239 +0,0 @@
-----------------------------------------------------------------------------
--- 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
deleted file mode 100644
index 5fe0f34..0000000
--- a/libraries/LuaJIT-1.1.7/jit/opt.lua
+++ /dev/null
@@ -1,508 +0,0 @@
-----------------------------------------------------------------------------
--- 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
deleted file mode 100644
index cc19bf4..0000000
--- a/libraries/LuaJIT-1.1.7/jit/opt_inline.lua
+++ /dev/null
@@ -1,397 +0,0 @@
-----------------------------------------------------------------------------
--- 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
deleted file mode 100644
index 42367c6..0000000
--- a/libraries/LuaJIT-1.1.7/jit/trace.lua
+++ /dev/null
@@ -1,111 +0,0 @@
-----------------------------------------------------------------------------
--- 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
deleted file mode 100644
index 69c07d6..0000000
--- a/libraries/LuaJIT-1.1.7/jitdoc/bluequad-print.css
+++ /dev/null
@@ -1,166 +0,0 @@
-/* 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
deleted file mode 100644
index 8d72de9..0000000
--- a/libraries/LuaJIT-1.1.7/jitdoc/bluequad.css
+++ /dev/null
@@ -1,292 +0,0 @@
-/* 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
deleted file mode 100644
index 0ef43f1..0000000
--- a/libraries/LuaJIT-1.1.7/jitdoc/coco.html
+++ /dev/null
@@ -1,132 +0,0 @@
-
-
-
-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.