Upgrade LuaJIT to 2.1.0-beta3
This commit is contained in:
parent
186c98308e
commit
6b41659178
229 changed files with 43994 additions and 12090 deletions
|
@ -7,7 +7,7 @@ set(CMAKE_MODULE_PATH ${PROJECT_SOURCE_DIR}/cmake)
|
|||
|
||||
include_directories("build")
|
||||
include_directories("libaegisub/include")
|
||||
include_directories("vendor/luajit/include")
|
||||
include_directories("vendor/luajit/src")
|
||||
|
||||
add_library(libaegisub STATIC
|
||||
libaegisub/common/parser.cpp
|
||||
|
@ -202,11 +202,23 @@ add_custom_command(
|
|||
)
|
||||
|
||||
add_library(luajit STATIC
|
||||
vendor/luajit/src/lib_base.c
|
||||
vendor/luajit/src/lib_math.c
|
||||
vendor/luajit/src/lib_bit.c
|
||||
vendor/luajit/src/lib_string.c
|
||||
vendor/luajit/src/lib_table.c
|
||||
vendor/luajit/src/lib_io.c
|
||||
vendor/luajit/src/lib_os.c
|
||||
vendor/luajit/src/lib_package.c
|
||||
vendor/luajit/src/lib_debug.c
|
||||
vendor/luajit/src/lib_jit.c
|
||||
vendor/luajit/src/lib_ffi.c
|
||||
vendor/luajit/src/lj_gc.c
|
||||
vendor/luajit/src/lj_err.c
|
||||
vendor/luajit/src/lj_char.c
|
||||
vendor/luajit/src/lj_bc.c
|
||||
vendor/luajit/src/lj_obj.c
|
||||
vendor/luajit/src/lj_buf.c
|
||||
vendor/luajit/src/lj_str.c
|
||||
vendor/luajit/src/lj_tab.c
|
||||
vendor/luajit/src/lj_func.c
|
||||
|
@ -218,7 +230,10 @@ add_library(luajit STATIC
|
|||
vendor/luajit/src/lj_vmevent.c
|
||||
vendor/luajit/src/lj_vmmath.c
|
||||
vendor/luajit/src/lj_strscan.c
|
||||
vendor/luajit/src/lj_strfmt.c
|
||||
vendor/luajit/src/lj_strfmt_num.c
|
||||
vendor/luajit/src/lj_api.c
|
||||
vendor/luajit/src/lj_profile.c
|
||||
vendor/luajit/src/lj_lex.c
|
||||
vendor/luajit/src/lj_parse.c
|
||||
vendor/luajit/src/lj_bcread.c
|
||||
|
@ -251,17 +266,6 @@ add_library(luajit STATIC
|
|||
vendor/luajit/src/lj_lib.c
|
||||
vendor/luajit/src/lj_alloc.c
|
||||
vendor/luajit/src/lib_aux.c
|
||||
vendor/luajit/src/lib_base.c
|
||||
vendor/luajit/src/lib_math.c
|
||||
vendor/luajit/src/lib_bit.c
|
||||
vendor/luajit/src/lib_string.c
|
||||
vendor/luajit/src/lib_table.c
|
||||
vendor/luajit/src/lib_io.c
|
||||
vendor/luajit/src/lib_os.c
|
||||
vendor/luajit/src/lib_package.c
|
||||
vendor/luajit/src/lib_debug.c
|
||||
vendor/luajit/src/lib_jit.c
|
||||
vendor/luajit/src/lib_ffi.c
|
||||
vendor/luajit/src/lib_init.c
|
||||
|
||||
vendor/luajit/src/gen/lj_ffdef.h
|
||||
|
|
|
@ -53,7 +53,7 @@ int main(int argc, char **argv) {
|
|||
agi::log::log = new agi::log::LogSink;
|
||||
|
||||
// Init lua state
|
||||
lua_State *L = lua_open();
|
||||
lua_State *L = luaL_newstate();
|
||||
if (!L) {
|
||||
fprintf(stderr, "Failed to create Lua state\n");
|
||||
return 1;
|
||||
|
|
|
@ -431,7 +431,7 @@ AS_IF([test x$with_system_luajit != xno], [
|
|||
])
|
||||
|
||||
AS_IF([test $with_system_luajit = no],
|
||||
[AC_SUBST([LUAJIT_CFLAGS], ['-I$(TOP)vendor/luajit/include'])
|
||||
[AC_SUBST([LUAJIT_CFLAGS], ['-I$(TOP)vendor/luajit/src'])
|
||||
AC_SUBST([LUAJIT_LIBS], ['$(TOP)vendor/luajit/src/libluajit.a'])])
|
||||
|
||||
# We also need a Lua binary to run part of the build system
|
||||
|
|
2
vendor/luabins/src/luabins.c
vendored
2
vendor/luabins/src/luabins.c
vendored
|
@ -54,7 +54,7 @@ static int l_load(lua_State * L)
|
|||
}
|
||||
|
||||
/* luabins Lua module API */
|
||||
static const struct luaL_reg R[] =
|
||||
static const struct luaL_Reg R[] =
|
||||
{
|
||||
{ "save", l_save },
|
||||
{ "load", l_load },
|
||||
|
|
11
vendor/luajit/.gitignore
vendored
Normal file
11
vendor/luajit/.gitignore
vendored
Normal file
|
@ -0,0 +1,11 @@
|
|||
*.[oa]
|
||||
*.so
|
||||
*.obj
|
||||
*.lib
|
||||
*.exp
|
||||
*.dll
|
||||
*.exe
|
||||
*.manifest
|
||||
*.dmp
|
||||
*.swp
|
||||
.tags
|
2
vendor/luajit/COPYRIGHT
vendored
2
vendor/luajit/COPYRIGHT
vendored
|
@ -1,7 +1,7 @@
|
|||
===============================================================================
|
||||
LuaJIT -- a Just-In-Time Compiler for Lua. http://luajit.org/
|
||||
|
||||
Copyright (C) 2005-2015 Mike Pall. All rights reserved.
|
||||
Copyright (C) 2005-2017 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
|
||||
|
|
6
vendor/luajit/README
vendored
6
vendor/luajit/README
vendored
|
@ -1,11 +1,11 @@
|
|||
README for LuaJIT 2.0.4
|
||||
-----------------------
|
||||
README for LuaJIT 2.1.0-beta3
|
||||
-----------------------------
|
||||
|
||||
LuaJIT is a Just-In-Time (JIT) compiler for the Lua programming language.
|
||||
|
||||
Project Homepage: http://luajit.org/
|
||||
|
||||
LuaJIT is Copyright (C) 2005-2015 Mike Pall.
|
||||
LuaJIT is Copyright (C) 2005-2017 Mike Pall.
|
||||
LuaJIT is free software, released under the MIT license.
|
||||
See full Copyright Notice in the COPYRIGHT file or in luajit.h.
|
||||
|
||||
|
|
166
vendor/luajit/doc/bluequad-print.css
vendored
Normal file
166
vendor/luajit/doc/bluequad-print.css
vendored
Normal file
|
@ -0,0 +1,166 @@
|
|||
/* Copyright (C) 2004-2017 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;
|
||||
}
|
325
vendor/luajit/doc/bluequad.css
vendored
Normal file
325
vendor/luajit/doc/bluequad.css
vendored
Normal file
|
@ -0,0 +1,325 @@
|
|||
/* Copyright (C) 2004-2017 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;
|
||||
}
|
||||
b {
|
||||
color: #404040;
|
||||
}
|
||||
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;
|
||||
line-height: 1.2;
|
||||
font-size: 110%;
|
||||
}
|
||||
kbd {
|
||||
font-weight: bolder;
|
||||
}
|
||||
blockquote, pre {
|
||||
max-width: 600px;
|
||||
margin: 1em 2em;
|
||||
padding: 0;
|
||||
}
|
||||
pre {
|
||||
line-height: 1.1;
|
||||
}
|
||||
pre.code {
|
||||
line-height: 1.4;
|
||||
margin: 0.5em 0 1em 0.5em;
|
||||
padding: 0.5em 1em;
|
||||
border: 1px solid #bfcfff;
|
||||
background: #f0f4ff;
|
||||
}
|
||||
pre.mark {
|
||||
padding-left: 2em;
|
||||
}
|
||||
span.codemark {
|
||||
position:absolute;
|
||||
left: 16em;
|
||||
color: #4040c0;
|
||||
}
|
||||
span.mark {
|
||||
color: #4040c0;
|
||||
font-family: Courier New, Courier, monospace;
|
||||
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;
|
||||
}
|
||||
.new {
|
||||
font-size: 6pt;
|
||||
vertical-align: middle;
|
||||
background: #ff8000;
|
||||
color: #ffffff;
|
||||
}
|
||||
#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 1.7em;
|
||||
}
|
||||
#nav ul ul ul a {
|
||||
padding: 0 0.5em 0 2.4em;
|
||||
}
|
||||
#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;
|
||||
}
|
883
vendor/luajit/doc/changes.html
vendored
Normal file
883
vendor/luajit/doc/changes.html
vendored
Normal file
|
@ -0,0 +1,883 @@
|
|||
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
|
||||
<html>
|
||||
<head>
|
||||
<title>LuaJIT Change History</title>
|
||||
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
|
||||
<meta name="Author" content="Mike Pall">
|
||||
<meta name="Copyright" content="Copyright (C) 2005-2017, Mike Pall">
|
||||
<meta name="Language" content="en">
|
||||
<link rel="stylesheet" type="text/css" href="bluequad.css" media="screen">
|
||||
<link rel="stylesheet" type="text/css" href="bluequad-print.css" media="print">
|
||||
<style type="text/css">
|
||||
div.major { max-width: 600px; padding: 1em; margin: 1em 0 1em 0; }
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<div id="site">
|
||||
<a href="http://luajit.org"><span>Lua<span id="logo">JIT</span></span></a>
|
||||
</div>
|
||||
<div id="head">
|
||||
<h1>LuaJIT Change History</h1>
|
||||
</div>
|
||||
<div id="nav">
|
||||
<ul><li>
|
||||
<a href="luajit.html">LuaJIT</a>
|
||||
<ul><li>
|
||||
<a href="http://luajit.org/download.html">Download <span class="ext">»</span></a>
|
||||
</li><li>
|
||||
<a href="install.html">Installation</a>
|
||||
</li><li>
|
||||
<a href="running.html">Running</a>
|
||||
</li></ul>
|
||||
</li><li>
|
||||
<a href="extensions.html">Extensions</a>
|
||||
<ul><li>
|
||||
<a href="ext_ffi.html">FFI Library</a>
|
||||
<ul><li>
|
||||
<a href="ext_ffi_tutorial.html">FFI Tutorial</a>
|
||||
</li><li>
|
||||
<a href="ext_ffi_api.html">ffi.* API</a>
|
||||
</li><li>
|
||||
<a href="ext_ffi_semantics.html">FFI Semantics</a>
|
||||
</li></ul>
|
||||
</li><li>
|
||||
<a href="ext_jit.html">jit.* Library</a>
|
||||
</li><li>
|
||||
<a href="ext_c_api.html">Lua/C API</a>
|
||||
</li><li>
|
||||
<a href="ext_profiler.html">Profiler</a>
|
||||
</li></ul>
|
||||
</li><li>
|
||||
<a href="status.html">Status</a>
|
||||
<ul><li>
|
||||
<a class="current" href="changes.html">Changes</a>
|
||||
</li></ul>
|
||||
</li><li>
|
||||
<a href="faq.html">FAQ</a>
|
||||
</li><li>
|
||||
<a href="http://luajit.org/performance.html">Performance <span class="ext">»</span></a>
|
||||
</li><li>
|
||||
<a href="http://wiki.luajit.org/">Wiki <span class="ext">»</span></a>
|
||||
</li><li>
|
||||
<a href="http://luajit.org/list.html">Mailing List <span class="ext">»</span></a>
|
||||
</li></ul>
|
||||
</div>
|
||||
<div id="main">
|
||||
<p>
|
||||
This is a list of changes between the released versions of LuaJIT.<br>
|
||||
The current <span style="color: #0000c0;">stable version</span> is <strong>LuaJIT 2.0.5</strong>.<br>
|
||||
</p>
|
||||
<p>
|
||||
Please check the
|
||||
<a href="http://luajit.org/changes.html"><span class="ext">»</span> Online Change History</a>
|
||||
to see whether newer versions are available.
|
||||
</p>
|
||||
|
||||
<div class="major" style="background: #d0d0ff;">
|
||||
<h2 id="LuaJIT-2.1.0-beta3">LuaJIT 2.1.0-beta3 — 2017-05-01</h2>
|
||||
<ul>
|
||||
<li>Rewrite memory block allocator.</li>
|
||||
<li>Add various extension from Lua 5.2/5.3.</li>
|
||||
<li>Remove old Lua 5.0 compatibility defines.</li>
|
||||
<li>Set arg table before evaluating <tt>LUA_INIT</tt> and <tt>-e</tt> chunks.</li>
|
||||
<li>Fix FOLD rules for <tt>math.abs()</tt> and FP negation.</li>
|
||||
<li>Fix soft-float <tt>math.abs()</tt> and negation.</li>
|
||||
<li>Fix formatting of some small denormals at low precision.</li>
|
||||
<li>LJ_GC64: Add JIT compiler support.</li>
|
||||
<li>x64/LJ_GC64: Add JIT compiler backend.</li>
|
||||
<li>x86/x64: Generate BMI2 shifts and rotates, if available.</li>
|
||||
<li>Windows/x86: Add full exception interoperability.</li>
|
||||
<li>ARM64: Add big-endian support.</li>
|
||||
<li>ARM64: Add JIT compiler backend.</li>
|
||||
<li>MIPS: Fix <tt>TSETR</tt> barrier.</li>
|
||||
<li>MIPS: Support MIPS16 interlinking.</li>
|
||||
<li>MIPS soft-float: Fix code generation for <tt>HREF</tt>.</li>
|
||||
<li>MIPS64: Add MIPS64 hard-float JIT compiler backend.</li>
|
||||
<li>MIPS64: Add MIPS64 hard-float/soft-float support to interpreter.</li>
|
||||
<li>FFI: Compile bitfield loads/stores.</li>
|
||||
<li>Various fixes common with the 2.0 branch.</li>
|
||||
</ul>
|
||||
|
||||
<h2 id="LuaJIT-2.1.0-beta2">LuaJIT 2.1.0-beta2 — 2016-03-03</h2>
|
||||
<ul>
|
||||
<li>Enable trace stitching.</li>
|
||||
<li>Use internal implementation for converting FP numbers to strings.</li>
|
||||
<li>Parse Unicode escape <tt>'\u{XX...}'</tt> in string literals.</li>
|
||||
<li>Add MIPS soft-float support.</li>
|
||||
<li>Switch MIPS port to dual-number mode.</li>
|
||||
<li>x86/x64: Add support for AES-NI, AVX and AVX2 to DynASM.</li>
|
||||
<li>FFI: Add <tt>ssize_t</tt> declaration.</li>
|
||||
<li>FFI: Parse <tt>#line NN</tt> and <tt>#NN</tt>.</li>
|
||||
<li>Various minor fixes.</li>
|
||||
</ul>
|
||||
|
||||
<h2 id="LuaJIT-2.1.0-beta1">LuaJIT 2.1.0-beta1 — 2015-08-25</h2>
|
||||
<p>
|
||||
This is a brief summary of the major changes in LuaJIT 2.1 compared to 2.0.
|
||||
Please take a look at the commit history for more details.
|
||||
</p>
|
||||
<ul>
|
||||
<li>Changes to the VM core:
|
||||
<ul>
|
||||
<li>Add low-overhead profiler (<tt>-jp</tt>).</li>
|
||||
<li>Add <tt>LJ_GC64</tt> mode: 64 bit GC object references (really: 47 bit). Interpreter-only for now.</li>
|
||||
<li>Add <tt>LJ_FR2</tt> mode: Two-slot frame info. Required by <tt>LJ_GC64</tt> mode.</li>
|
||||
<li>Add <tt>table.new()</tt> and <tt>table.clear()</tt>.</li>
|
||||
<li>Parse binary number literals (<tt>0bxxx</tt>).</li>
|
||||
</ul></li>
|
||||
<li>Improvements to the JIT compiler:
|
||||
<ul>
|
||||
<li>Add trace stitching (disabled for now).</li>
|
||||
<li>Compile various builtins: <tt>string.char()</tt>, <tt>string.reverse()</tt>, <tt>string.lower()</tt>, <tt>string.upper()</tt>, <tt>string.rep()</tt>, <tt>string.format()</tt>, <tt>table.concat()</tt>, <tt>bit.tohex()</tt>, <tt>getfenv(0)</tt>, <tt>debug.getmetatable()</tt>.</li>
|
||||
<li>Compile <tt>string.find()</tt> for fixed string searches (no patterns).</li>
|
||||
<li>Compile <tt>BC_TSETM</tt>, e.g. <tt>{1,2,3,f()}</tt>.</li>
|
||||
<li>Compile string concatenations (<tt>BC_CAT</tt>).</li>
|
||||
<li>Compile <tt>__concat</tt> metamethod.</li>
|
||||
<li>Various minor optimizations.</li>
|
||||
</ul></li>
|
||||
<li>Internal Changes:
|
||||
<ul>
|
||||
<li>Add support for embedding LuaJIT bytecode for builtins.</li>
|
||||
<li>Replace various builtins with embedded bytecode.</li>
|
||||
<li>Refactor string buffers and string formatting.</li>
|
||||
<li>Remove obsolete non-truncating number to integer conversions.</li>
|
||||
</ul></li>
|
||||
<li>Ports:
|
||||
<ul>
|
||||
<li>Add Xbox One port (<tt>LJ_GC64</tt> mode).</li>
|
||||
<li>ARM64: Add port of the interpreter (<tt>LJ_GC64</tt> mode).</li>
|
||||
<li>x64: Add separate port of the interpreter to <tt>LJ_GC64</tt> mode.</li>
|
||||
<li>x86/x64: Drop internal x87 math functions. Use libm functions.</li>
|
||||
<li>x86: Remove x87 support from interpreter. SSE2 is mandatory now.</li>
|
||||
<li>PPC/e500: Drop support for this architecture.</li>
|
||||
</ul></li>
|
||||
<li>FFI library:
|
||||
<ul>
|
||||
<li>FFI: Add 64 bit bitwise operations.</li>
|
||||
<li>FFI: Compile VLA/VLS and large cdata allocations with default initialization.</li>
|
||||
<li>FFI: Compile conversions from functions to function pointers.</li>
|
||||
<li>FFI: Compile lightuserdata to <tt>void *</tt> conversion.</li>
|
||||
<li>FFI: Compile <tt>ffi.gc(cdata, nil)</tt>, too.</li>
|
||||
<li>FFI: Add <tt>ffi.typeinfo()</tt>.</li>
|
||||
</ul></li>
|
||||
</ul>
|
||||
</div>
|
||||
|
||||
<div class="major" style="background: #ffffd0;">
|
||||
<h2 id="LuaJIT-2.0.5">LuaJIT 2.0.5 — 2017-05-01</h2>
|
||||
<ul>
|
||||
<li>Add workaround for MSVC 2015 stdio changes.</li>
|
||||
<li>Limit mcode alloc probing, depending on the available pool size.</li>
|
||||
<li>Fix overly restrictive range calculation in mcode allocation.</li>
|
||||
<li>Fix out-of-scope goto handling in parser.</li>
|
||||
<li>Remove internal <tt>__mode = "K"</tt> and replace with safe check.</li>
|
||||
<li>Add "proto" field to <tt>jit.util.funcinfo()</tt>.</li>
|
||||
<li>Fix GC step size calculation.</li>
|
||||
<li>Initialize <tt>uv->immutable</tt> for upvalues of loaded chunks.</li>
|
||||
<li>Fix for cdata vs. non-cdata arithmetics/comparisons.</li>
|
||||
<li>Drop leftover regs in 'for' iterator assignment, too.</li>
|
||||
<li>Fix PHI remarking in SINK pass.</li>
|
||||
<li>Don't try to record outermost <tt>pcall()</tt> return to lower frame.</li>
|
||||
<li>Add guard for obscure aliasing between open upvalues and SSA slots.</li>
|
||||
<li>Remove assumption that <tt>lj_math_random_step()</tt> doesn't clobber FPRs.</li>
|
||||
<li>Fix handling of non-numeric strings in arithmetic coercions.</li>
|
||||
<li>Fix recording of <tt>select(n, ...)</tt> with off-trace varargs</li>
|
||||
<li>Fix install for cross-builds.</li>
|
||||
<li>Don't allocate unused 2nd result register in JIT compiler backend.</li>
|
||||
<li>Drop marks from replayed instructions when sinking.</li>
|
||||
<li>Fix unsinking check.</li>
|
||||
<li>Properly handle OOM in <tt>trace_save()</tt>.</li>
|
||||
<li>Limit number of arguments given to <tt>io.lines()</tt> and <tt>fp:lines()</tt>.</li>
|
||||
<li>Fix narrowing of <tt>TOBIT</tt>.</li>
|
||||
<li>OSX: Fix build with recent XCode.</li>
|
||||
<li>x86/x64: Don't spill an explicit <tt>REF_BASE</tt> in the IR.</li>
|
||||
<li>x86/x64: Fix instruction length decoder.</li>
|
||||
<li>x86/x64: Search for exit jumps with instruction length decoder.</li>
|
||||
<li>ARM: Fix <tt>BLX</tt> encoding for Thumb interworking calls.</li>
|
||||
<li>MIPS: Don't use <tt>RID_GP</tt> as a scratch register.</li>
|
||||
<li>MIPS: Fix emitted code for U32 to float conversion.</li>
|
||||
<li>MIPS: Backport workaround for compact unwind tables.</li>
|
||||
<li>MIPS: Fix cross-endian jit.bcsave.</li>
|
||||
<li>MIPS: Fix <tt>BC_ISNEXT</tt> fallback path.</li>
|
||||
<li>MIPS: Fix use of ffgccheck delay slots in interpreter.</li>
|
||||
<li>FFI: Fix FOLD rules for <tt>int64_t</tt> comparisons.</li>
|
||||
<li>FFI: Fix SPLIT pass for <tt>CONV i64.u64</tt>.</li>
|
||||
<li>FFI: Fix <tt>ipairs()</tt> recording.</li>
|
||||
<li>FFI: Don't propagate qualifiers into subtypes of complex.</li>
|
||||
</ul>
|
||||
|
||||
<h2 id="LuaJIT-2.0.4">LuaJIT 2.0.4 — 2015-05-14</h2>
|
||||
<ul>
|
||||
<li>Fix stack check in narrowing optimization.</li>
|
||||
<li>Fix Lua/C API typecheck error for special indexes.</li>
|
||||
<li>Fix string to number conversion.</li>
|
||||
<li>Fix lexer error for chunks without tokens.</li>
|
||||
<li>Don't compile <tt>IR_RETF</tt> after <tt>CALLT</tt> to ff with-side effects.</li>
|
||||
<li>Fix <tt>BC_UCLO</tt>/<tt>BC_JMP</tt> join optimization in Lua parser.</li>
|
||||
<li>Fix corner case in string to number conversion.</li>
|
||||
<li>Gracefully handle <tt>lua_error()</tt> for a suspended coroutine.</li>
|
||||
<li>Avoid error messages when building with Clang.</li>
|
||||
<li>Fix snapshot #0 handling for traces with a stack check on entry.</li>
|
||||
<li>Fix fused constant loads under high register pressure.</li>
|
||||
<li>Invalidate backpropagation cache after DCE.</li>
|
||||
<li>Fix ABC elimination.</li>
|
||||
<li>Fix debug info for main chunk of stripped bytecode.</li>
|
||||
<li>Fix FOLD rule for <tt>string.sub(s, ...) == k</tt>.</li>
|
||||
<li>Fix FOLD rule for <tt>STRREF</tt> of <tt>SNEW</tt>.</li>
|
||||
<li>Fix frame traversal while searching for error function.</li>
|
||||
<li>Prevent GC estimate miscalculation due to buffer growth.</li>
|
||||
<li>Prevent adding side traces for stack checks.</li>
|
||||
<li>Fix top slot calculation for snapshots with continuations.</li>
|
||||
<li>Fix check for reuse of SCEV results in <tt>FORL</tt>.</li>
|
||||
<li>Add PS Vita port.</li>
|
||||
<li>Fix compatibility issues with Illumos.</li>
|
||||
<li>Fix DragonFly build (unsupported).</li>
|
||||
<li>OpenBSD/x86: Better executable memory allocation for W^X mode.</li>
|
||||
<li>x86: Fix argument checks for <tt>ipairs()</tt> iterator.</li>
|
||||
<li>x86: <tt>lj_math_random_step()</tt> clobbers XMM regs on OSX Clang.</li>
|
||||
<li>x86: Fix code generation for unused result of <tt>math.random()</tt>.</li>
|
||||
<li>x64: Allow building with <tt>LUAJIT_USE_SYSMALLOC</tt> and <tt>LUAJIT_USE_VALGRIND</tt>.</li>
|
||||
<li>x86/x64: Fix argument check for bit shifts.</li>
|
||||
<li>x86/x64: Fix code generation for fused test/arith ops.</li>
|
||||
<li>ARM: Fix write barrier check in <tt>BC_USETS</tt>.</li>
|
||||
<li>PPC: Fix red zone overflow in machine code generation.</li>
|
||||
<li>PPC: Don't use <tt>mcrxr</tt> on PPE.</li>
|
||||
<li>Various archs: Fix excess stack growth in interpreter.</li>
|
||||
<li>FFI: Fix FOLD rule for <tt>TOBIT</tt> + <tt>CONV num.u32</tt>.</li>
|
||||
<li>FFI: Prevent DSE across <tt>ffi.string()</tt>.</li>
|
||||
<li>FFI: No meta fallback when indexing pointer to incomplete struct.</li>
|
||||
<li>FFI: Fix initialization of unions of subtypes.</li>
|
||||
<li>FFI: Fix cdata vs. non-cdata arithmetic and comparisons.</li>
|
||||
<li>FFI: Fix <tt>__index</tt>/<tt>__newindex</tt> metamethod resolution for ctypes.</li>
|
||||
<li>FFI: Fix compilation of reference field access.</li>
|
||||
<li>FFI: Fix frame traversal for backtraces with FFI callbacks.</li>
|
||||
<li>FFI: Fix recording of indexing a struct pointer ctype object itself.</li>
|
||||
<li>FFI: Allow non-scalar cdata to be compared for equality by address.</li>
|
||||
<li>FFI: Fix pseudo type conversions for type punning.</li>
|
||||
</ul>
|
||||
|
||||
<h2 id="LuaJIT-2.0.3">LuaJIT 2.0.3 — 2014-03-12</h2>
|
||||
<ul>
|
||||
<li>Add PS4 port.</li>
|
||||
<li>Add support for multilib distro builds.</li>
|
||||
<li>Fix OSX build.</li>
|
||||
<li>Fix MinGW build.</li>
|
||||
<li>Fix Xbox 360 build.</li>
|
||||
<li>Improve ULOAD forwarding for open upvalues.</li>
|
||||
<li>Fix GC steps threshold handling when called by JIT-compiled code.</li>
|
||||
<li>Fix argument checks for <tt>math.deg()</tt> and <tt>math.rad()</tt>.</li>
|
||||
<li>Fix <tt>jit.flush(func|true)</tt>.</li>
|
||||
<li>Respect <tt>jit.off(func)</tt> when returning to a function, too.</li>
|
||||
<li>Fix compilation of <tt>string.byte(s, nil, n)</tt>.</li>
|
||||
<li>Fix line number for relocated bytecode after closure fixup</li>
|
||||
<li>Fix frame traversal for backtraces.</li>
|
||||
<li>Fix ABC elimination.</li>
|
||||
<li>Fix handling of redundant PHIs.</li>
|
||||
<li>Fix snapshot restore for exit to function header.</li>
|
||||
<li>Fix type punning alias analysis for constified pointers</li>
|
||||
<li>Fix call unroll checks in the presence of metamethod frames.</li>
|
||||
<li>Fix initial maxslot for down-recursive traces.</li>
|
||||
<li>Prevent BASE register coalescing if parent uses <tt>IR_RETF</tt>.</li>
|
||||
<li>Don't purge modified function from stack slots in <tt>BC_RET</tt>.</li>
|
||||
<li>Fix recording of <tt>BC_VARG</tt>.</li>
|
||||
<li>Don't access dangling reference to reallocated IR.</li>
|
||||
<li>Fix frame depth display for bytecode dump in <tt>-jdump</tt>.</li>
|
||||
<li>ARM: Fix register allocation when rematerializing FPRs.</li>
|
||||
<li>x64: Fix store to upvalue for lightuserdata values.</li>
|
||||
<li>FFI: Add missing GC steps for callback argument conversions.</li>
|
||||
<li>FFI: Properly unload loaded DLLs.</li>
|
||||
<li>FFI: Fix argument checks for <tt>ffi.string()</tt>.</li>
|
||||
<li>FFI/x64: Fix passing of vector arguments to calls.</li>
|
||||
<li>FFI: Rehash finalizer table after GC cycle, if needed.</li>
|
||||
<li>FFI: Fix <tt>cts->L</tt> for cdata unsinking in snapshot restore.</li>
|
||||
</ul>
|
||||
|
||||
<h2 id="LuaJIT-2.0.2">LuaJIT 2.0.2 — 2013-06-03</h2>
|
||||
<ul>
|
||||
<li>Fix memory access check for fast string interning.</li>
|
||||
<li>Fix MSVC intrinsics for older versions.</li>
|
||||
<li>Add missing GC steps for <tt>io.*</tt> functions.</li>
|
||||
<li>Fix spurious red zone overflows in machine code generation.</li>
|
||||
<li>Fix jump-range constrained mcode allocation.</li>
|
||||
<li>Inhibit DSE for implicit loads via calls.</li>
|
||||
<li>Fix builtin string to number conversion for overflow digits.</li>
|
||||
<li>Fix optional argument handling while recording builtins.</li>
|
||||
<li>Fix optional argument handling in <tt>table.concat()</tt>.</li>
|
||||
<li>Add partial support for building with MingW64 GCC 4.8-SEH.</li>
|
||||
<li>Add missing PHI barrier to <tt>string.sub(str, a, b) == kstr</tt> FOLD rule.</li>
|
||||
<li>Fix compatibility issues with Illumos.</li>
|
||||
<li>ARM: Fix cache flush/sync for exit stubs of JIT-compiled code.</li>
|
||||
<li>MIPS: Fix cache flush/sync for JIT-compiled code jump area.</li>
|
||||
<li>PPC: Add <tt>plt</tt> suffix for external calls from assembler code.</li>
|
||||
<li>FFI: Fix snapshot substitution in SPLIT pass.</li>
|
||||
<li>FFI/x86: Fix register allocation for 64 bit comparisons.</li>
|
||||
<li>FFI: Fix tailcall in lowest frame to C function with bool result.</li>
|
||||
<li>FFI: Ignore <tt>long</tt> type specifier in <tt>ffi.istype()</tt>.</li>
|
||||
<li>FFI: Fix calling conventions for 32 bit OSX and iOS simulator (struct returns).</li>
|
||||
<li>FFI: Fix calling conventions for ARM hard-float EABI (nested structs).</li>
|
||||
<li>FFI: Improve error messages for arithmetic and comparison operators.</li>
|
||||
<li>FFI: Insert no-op type conversion for pointer to integer cast.</li>
|
||||
<li>FFI: Fix unroll limit for <tt>ffi.fill()</tt>.</li>
|
||||
<li>FFI: Must sink <tt>XBAR</tt> together with <tt>XSTORE</tt>s.</li>
|
||||
<li>FFI: Preserve intermediate string for <tt>const char *</tt> conversion.</li>
|
||||
</ul>
|
||||
|
||||
<h2 id="LuaJIT-2.0.1">LuaJIT 2.0.1 — 2013-02-19</h2>
|
||||
<ul>
|
||||
<li>Don't clear frame for out-of-memory error.</li>
|
||||
<li>Leave hook when resume catches error thrown from hook.</li>
|
||||
<li>Add missing GC steps for template table creation.</li>
|
||||
<li>Fix discharge order of comparisons in Lua parser.</li>
|
||||
<li>Improve buffer handling for <tt>io.read()</tt>.</li>
|
||||
<li>OSX: Add support for Mach-O object files to <tt>-b</tt> option.</li>
|
||||
<li>Fix PS3 port.</li>
|
||||
<li>Fix/enable Xbox 360 port.</li>
|
||||
<li>x86/x64: Always mark ref for shift count as non-weak.</li>
|
||||
<li>x64: Don't fuse implicitly 32-to-64 extended operands.</li>
|
||||
<li>ARM: Fix armhf call argument handling.</li>
|
||||
<li>ARM: Fix code generation for integer math.min/math.max.</li>
|
||||
<li>PPC/e500: Fix <tt>lj_vm_floor()</tt> for Inf/NaN.</li>
|
||||
<li>FFI: Change priority of table initializer variants for structs.</li>
|
||||
<li>FFI: Fix code generation for bool call result check on x86/x64.</li>
|
||||
<li>FFI: Load FFI library on-demand for bytecode with cdata literals.</li>
|
||||
<li>FFI: Fix handling of qualified transparent structs/unions.</li>
|
||||
</ul>
|
||||
|
||||
<h2 id="LuaJIT-2.0.0">LuaJIT 2.0.0 — 2012-11-08</h2>
|
||||
<ul>
|
||||
<li>Correctness and completeness:
|
||||
<ul>
|
||||
<li>Fix Android/x86 build.</li>
|
||||
<li>Fix recording of equality comparisons with <tt>__eq</tt> metamethods.</li>
|
||||
<li>Fix detection of immutable upvalues.</li>
|
||||
<li>Replace error with PANIC for callbacks from JIT-compiled code.</li>
|
||||
<li>Fix builtin string to number conversion for <tt>INT_MIN</tt>.</li>
|
||||
<li>Don't create unneeded array part for template tables.</li>
|
||||
<li>Fix <tt>CONV.num.int</tt> sinking.</li>
|
||||
<li>Don't propagate implicitly widened number to index metamethods.</li>
|
||||
<li>ARM: Fix ordered comparisons of number vs. non-number.</li>
|
||||
<li>FFI: Fix code generation for replay of sunk float fields.</li>
|
||||
<li>FFI: Fix signedness of bool.</li>
|
||||
<li>FFI: Fix recording of bool call result check on x86/x64.</li>
|
||||
<li>FFI: Fix stack-adjustment for <tt>__thiscall</tt> callbacks.</li>
|
||||
</ul></li>
|
||||
</ul>
|
||||
|
||||
<h2 id="LuaJIT-2.0.0-beta11">LuaJIT 2.0.0-beta11 — 2012-10-16</h2>
|
||||
<ul>
|
||||
<li>New features:
|
||||
<ul>
|
||||
<li>Use ARM VFP instructions, if available (build-time detection).</li>
|
||||
<li>Add support for ARM hard-float EABI (<tt>armhf</tt>).</li>
|
||||
<li>Add PS3 port.</li>
|
||||
<li>Add many features from Lua 5.2, e.g. <tt>goto</tt>/labels.
|
||||
Refer to <a href="extensions.html#lua52">this list</a>.</li>
|
||||
<li>FFI: Add parameterized C types.</li>
|
||||
<li>FFI: Add support for copy constructors.</li>
|
||||
<li>FFI: Equality comparisons never raise an error (treat as unequal instead).</li>
|
||||
<li>FFI: Box all accessed or returned enums.</li>
|
||||
<li>FFI: Check for <tt>__new</tt> metamethod when calling a constructor.</li>
|
||||
<li>FFI: Handle <tt>__pairs</tt>/<tt>__ipairs</tt> metamethods for cdata objects.</li>
|
||||
<li>FFI: Convert <tt>io.*</tt> file handle to <tt>FILE *</tt> pointer (but as a <tt>void *</tt>).</li>
|
||||
<li>FFI: Detect and support type punning through unions.</li>
|
||||
<li>FFI: Improve various error messages.</li>
|
||||
</ul></li>
|
||||
<li>Build-system reorganization:
|
||||
<ul>
|
||||
<li>Reorganize directory layout:<br>
|
||||
<tt>lib/*</tt> → <tt>src/jit/*</tt><br>
|
||||
<tt>src/buildvm_*.dasc</tt> → <tt>src/vm_*.dasc</tt><br>
|
||||
<tt>src/buildvm_*.h</tt> → removed<br>
|
||||
<tt>src/buildvm*</tt> → <tt>src/host/*</tt></li>
|
||||
<li>Add minified Lua interpreter plus Lua BitOp (<tt>minilua</tt>) to run DynASM.</li>
|
||||
<li>Change DynASM bit operations to use Lua BitOp</li>
|
||||
<li>Translate only <tt>vm_*.dasc</tt> for detected target architecture.</li>
|
||||
<li>Improve target detection for <tt>msvcbuild.bat</tt>.</li>
|
||||
<li>Fix build issues on Cygwin and MinGW with optional MSys.</li>
|
||||
<li>Handle cross-compiles with FPU/no-FPU or hard-fp/soft-fp ABI mismatch.</li>
|
||||
<li>Remove some library functions for no-JIT/no-FFI builds.</li>
|
||||
<li>Add uninstall target to top-level Makefile.</li>
|
||||
</ul></li>
|
||||
<li>Correctness and completeness:
|
||||
<ul>
|
||||
<li>Preserve snapshot #0 PC for all traces.</li>
|
||||
<li>Fix argument checks for <tt>coroutine.create()</tt>.</li>
|
||||
<li>Command line prints version and JIT status to <tt>stdout</tt>, not <tt>stderr</tt>.</li>
|
||||
<li>Fix userdata <tt>__gc</tt> separations at Lua state close.</li>
|
||||
<li>Fix <tt>TDUP</tt> to <tt>HLOAD</tt> forwarding for <tt>LJ_DUALNUM</tt> builds.</li>
|
||||
<li>Fix buffer check in bytecode writer.</li>
|
||||
<li>Make <tt>os.date()</tt> thread-safe.</li>
|
||||
<li>Add missing declarations for MSVC intrinsics.</li>
|
||||
<li>Fix dispatch table modifications for return hooks.</li>
|
||||
<li>Workaround for MSVC conversion bug (<tt>double</tt> → <tt>uint32_t</tt> → <tt>int32_t</tt>).</li>
|
||||
<li>Fix FOLD rule <tt>(i-j)-i => 0-j</tt>.</li>
|
||||
<li>Never use DWARF unwinder on Windows.</li>
|
||||
<li>Fix shrinking of direct mapped blocks in builtin allocator.</li>
|
||||
<li>Limit recursion depth in <tt>string.match()</tt> et al.</li>
|
||||
<li>Fix late despecialization of <tt>ITERN</tt> after loop has been entered.</li>
|
||||
<li>Fix <tt>'f'</tt> and <tt>'L'</tt> options for <tt>debug.getinfo()</tt> and <tt>lua_getinfo()</tt>.</li>
|
||||
<li>Fix <tt>package.searchpath()</tt>.</li>
|
||||
<li>OSX: Change dylib names to be consistent with other platforms.</li>
|
||||
<li>Android: Workaround for broken <tt>sprintf("%g", -0.0)</tt>.</li>
|
||||
<li>x86: Remove support for ancient CPUs without <tt>CMOV</tt> (before Pentium Pro).</li>
|
||||
<li>x86: Fix register allocation for calls returning register pair.</li>
|
||||
<li>x86/x64: Fix fusion of unsigned byte comparisons with swapped operands.</li>
|
||||
<li>ARM: Fix <tt>tonumber()</tt> argument check.</li>
|
||||
<li>ARM: Fix modulo operator and <tt>math.floor()</tt>/<tt>math.ceil()</tt> for <tt>inf</tt>/<tt>nan</tt>.</li>
|
||||
<li>ARM: Invoke SPLIT pass for leftover <tt>IR_TOBIT</tt>.</li>
|
||||
<li>ARM: Fix BASE register coalescing.</li>
|
||||
<li>PPC: Fix interpreter state setup in callbacks.</li>
|
||||
<li>PPC: Fix <tt>string.sub()</tt> range check.</li>
|
||||
<li>MIPS: Support generation of MIPS/MIPSEL bytecode object files.</li>
|
||||
<li>MIPS: Fix calls to <tt>floor()</tt>/<tt>ceil()</tt><tt>/trunc()</tt>.</li>
|
||||
<li>ARM/PPC: Detect more target architecture variants.</li>
|
||||
<li>ARM/PPC/e500/MIPS: Fix tailcalls from fast functions, esp. <tt>tostring()</tt>.</li>
|
||||
<li>ARM/PPC/MIPS: Fix rematerialization of FP constants.</li>
|
||||
<li>FFI: Don't call <tt>FreeLibrary()</tt> on our own EXE/DLL.</li>
|
||||
<li>FFI: Resolve metamethods for constructors, too.</li>
|
||||
<li>FFI: Properly disable callbacks on iOS (would require executable memory).</li>
|
||||
<li>FFI: Fix cdecl string parsing during recording.</li>
|
||||
<li>FFI: Show address pointed to for <tt>tostring(ref)</tt>, too.</li>
|
||||
<li>FFI: Fix alignment of C call argument/return structure.</li>
|
||||
<li>FFI: Initialize all fields of standard types.</li>
|
||||
<li>FFI: Fix callback handling when new C types are declared in callback.</li>
|
||||
<li>FFI: Fix recording of constructors for pointers.</li>
|
||||
<li>FFI: Always resolve metamethods for pointers to structs.</li>
|
||||
<li>FFI: Correctly propagate alignment when interning nested types.</li>
|
||||
</ul></li>
|
||||
<li>Structural and performance enhancements:
|
||||
<ul>
|
||||
<li>Add allocation sinking and store sinking optimization.</li>
|
||||
<li>Constify immutable upvalues.</li>
|
||||
<li>Add builtin string to integer or FP number conversion. Improves cross-platform consistency and correctness.</li>
|
||||
<li>Create string hash slots in template tables for non-const values, too. Avoids later table resizes.</li>
|
||||
<li>Eliminate <tt>HREFK</tt> guard for template table references.</li>
|
||||
<li>Add various new FOLD rules.</li>
|
||||
<li>Don't use stack unwinding for <tt>lua_yield()</tt> (slow on x64).</li>
|
||||
<li>ARM, PPC, MIPS: Improve <tt>XLOAD</tt> operand fusion and register hinting.</li>
|
||||
<li>PPC, MIPS: Compile <tt>math.sqrt()</tt> to sqrt instruction, if available.</li>
|
||||
<li>FFI: Fold <tt>KPTR</tt> + constant offset in SPLIT pass.</li>
|
||||
<li>FFI: Optimize/inline <tt>ffi.copy()</tt> and <tt>ffi.fill()</tt>.</li>
|
||||
<li>FFI: Compile and optimize array/struct copies.</li>
|
||||
<li>FFI: Compile <tt>ffi.typeof(cdata|ctype)</tt>, <tt>ffi.sizeof()</tt>, <tt>ffi.alignof()</tt>, <tt>ffi.offsetof()</tt> and <tt>ffi.gc()</tt>.</li>
|
||||
</ul></li>
|
||||
</ul>
|
||||
|
||||
<h2 id="LuaJIT-2.0.0-beta10">LuaJIT 2.0.0-beta10 — 2012-05-09</h2>
|
||||
<ul>
|
||||
<li>New features:
|
||||
<ul>
|
||||
<li>The MIPS of LuaJIT is complete. It requires a CPU conforming to the
|
||||
MIPS32 R1 architecture with hardware FPU. O32 hard-fp ABI,
|
||||
little-endian or big-endian.</li>
|
||||
<li>Auto-detect target arch via cross-compiler. No need for
|
||||
<tt>TARGET=arch</tt> anymore.</li>
|
||||
<li>Make DynASM compatible with Lua 5.2.</li>
|
||||
<li>From Lua 5.2: Try <tt>__tostring</tt> metamethod on non-string error
|
||||
messages..</li>
|
||||
</ul></li>
|
||||
<li>Correctness and completeness:
|
||||
<ul>
|
||||
<li>Fix parsing of hex literals with exponents.</li>
|
||||
<li>Fix bytecode dump for certain number constants.</li>
|
||||
<li>Fix argument type in error message for relative arguments.</li>
|
||||
<li>Fix argument error handling on Lua stacks without a frame.</li>
|
||||
<li>Add missing mcode limit check in assembler backend.</li>
|
||||
<li>Fix compilation on OpenBSD.</li>
|
||||
<li>Avoid recursive GC steps after GC-triggered trace exit.</li>
|
||||
<li>Replace <tt><unwind.h></tt> definitions with our own.</li>
|
||||
<li>Fix OSX build issues. Bump minimum required OSX version to 10.4.</li>
|
||||
<li>Fix discharge order of comparisons in Lua parser.</li>
|
||||
<li>Ensure running <tt>__gc</tt> of userdata created in <tt>__gc</tt>
|
||||
at state close.</li>
|
||||
<li>Limit number of userdata <tt>__gc</tt> separations at state close.</li>
|
||||
<li>Fix bytecode <tt>JMP</tt> slot range when optimizing
|
||||
<tt>and</tt>/<tt>or</tt> with constant LHS.</li>
|
||||
<li>Fix DSE of <tt>USTORE</tt>.</li>
|
||||
<li>Make <tt>lua_concat()</tt> work from C hook with partial frame.</li>
|
||||
<li>Add required PHIs for implicit conversions, e.g. via <tt>XREF</tt>
|
||||
forwarding.</li>
|
||||
<li>Add more comparison variants to Valgrind suppressions file.</li>
|
||||
<li>Disable loading bytecode with an extra header (BOM or <tt>#!</tt>).</li>
|
||||
<li>Fix PHI stack slot syncing.</li>
|
||||
<li>ARM: Reorder type/value tests to silence Valgrind.</li>
|
||||
<li>ARM: Fix register allocation for <tt>ldrd</tt>-optimized
|
||||
<tt>HREFK</tt>.</li>
|
||||
<li>ARM: Fix conditional branch fixup for <tt>OBAR</tt>.</li>
|
||||
<li>ARM: Invoke SPLIT pass for <tt>double</tt> args in FFI call.</li>
|
||||
<li>ARM: Handle all <tt>CALL*</tt> ops with <tt>double</tt> results in
|
||||
SPLIT pass.</li>
|
||||
<li>ARM: Fix rejoin of <tt>POW</tt> in SPLIT pass.</li>
|
||||
<li>ARM: Fix compilation of <tt>math.sinh</tt>, <tt>math.cosh</tt>,
|
||||
<tt>math.tanh</tt>.</li>
|
||||
<li>ARM, PPC: Avoid pointless arg clearing in <tt>BC_IFUNCF</tt>.</li>
|
||||
<li>PPC: Fix resume after yield from hook.</li>
|
||||
<li>PPC: Fix argument checking for <tt>rawget()</tt>.</li>
|
||||
<li>PPC: Fix fusion of floating-point <tt>XLOAD</tt>/<tt>XSTORE</tt>.</li>
|
||||
<li>PPC: Fix <tt>HREFK</tt> code generation for huge tables.</li>
|
||||
<li>PPC: Use builtin D-Cache/I-Cache sync code.</li>
|
||||
</ul></li>
|
||||
<li>FFI library:
|
||||
<ul>
|
||||
<li>Ignore empty statements in <tt>ffi.cdef()</tt>.</li>
|
||||
<li>Ignore number parsing errors while skipping definitions.</li>
|
||||
<li>Don't touch frame in callbacks with tailcalls to fast functions.</li>
|
||||
<li>Fix library unloading on POSIX systems.</li>
|
||||
<li>Finalize cdata before userdata when closing the state.</li>
|
||||
<li>Change <tt>ffi.load()</tt> library name resolution for Cygwin.</li>
|
||||
<li>Fix resolving of function name redirects on Windows/x86.</li>
|
||||
<li>Fix symbol resolving error messages on Windows.</li>
|
||||
<li>Fix blacklisting of C functions calling callbacks.</li>
|
||||
<li>Fix result type of pointer difference.</li>
|
||||
<li>Use correct PC in FFI metamethod error message.</li>
|
||||
<li>Allow <tt>'typedef _Bool int BOOL;'</tt> for the Windows API.</li>
|
||||
<li>Don't record test for bool result of call, if ignored.</li>
|
||||
</ul></li>
|
||||
</ul>
|
||||
|
||||
<h2 id="LuaJIT-2.0.0-beta9">LuaJIT 2.0.0-beta9 — 2011-12-14</h2>
|
||||
<ul>
|
||||
<li>New features:
|
||||
<ul>
|
||||
<li>PPC port of LuaJIT is complete. Default is the dual-number port
|
||||
(usually faster). Single-number port selectable via <tt>src/Makefile</tt>
|
||||
at build time.</li>
|
||||
<li>Add FFI callback support.</li>
|
||||
<li>Extend <tt>-b</tt> to generate <tt>.c</tt>, <tt>.h</tt> or <tt>.obj/.o</tt>
|
||||
files with embedded bytecode.</li>
|
||||
<li>Allow loading embedded bytecode with <tt>require()</tt>.</li>
|
||||
<li>From Lua 5.2: Change to <tt>'\z'</tt> escape. Reject undefined escape
|
||||
sequences.</li>
|
||||
</ul></li>
|
||||
<li>Correctness and completeness:
|
||||
<ul>
|
||||
<li>Fix OSX 10.7 build. Fix <tt>install_name</tt> and versioning on OSX.</li>
|
||||
<li>Fix iOS build.</li>
|
||||
<li>Install <tt>dis_arm.lua</tt>, too.</li>
|
||||
<li>Mark installed shared library as executable.</li>
|
||||
<li>Add debug option to <tt>msvcbuild.bat</tt> and improve error handling.</li>
|
||||
<li>Fix data-flow analysis for iterators.</li>
|
||||
<li>Fix forced unwinding triggered by external unwinder.</li>
|
||||
<li>Record missing <tt>for</tt> loop slot loads (return to lower frame).</li>
|
||||
<li>Always use ANSI variants of Windows system functions.</li>
|
||||
<li>Fix GC barrier for multi-result table constructor (<tt>TSETM</tt>).</li>
|
||||
<li>Fix/add various FOLD rules.</li>
|
||||
<li>Add potential PHI for number conversions due to type instability.</li>
|
||||
<li>Do not eliminate PHIs only referenced from other PHIs.</li>
|
||||
<li>Correctly anchor implicit number to string conversions in Lua/C API.</li>
|
||||
<li>Fix various stack limit checks.</li>
|
||||
<li>x64: Use thread-safe exceptions for external unwinding (GCC platforms).</li>
|
||||
<li>x64: Fix result type of cdata index conversions.</li>
|
||||
<li>x64: Fix <tt>math.random()</tt> and <tt>bit.bswap()</tt> code generation.</li>
|
||||
<li>x64: Fix <tt>lightuserdata</tt> comparisons.</li>
|
||||
<li>x64: Always extend stack-passed arguments to pointer size.</li>
|
||||
<li>ARM: Many fixes to code generation backend.</li>
|
||||
<li>PPC/e500: Fix dispatch for binop metamethods.</li>
|
||||
<li>PPC/e500: Save/restore condition registers when entering/leaving the VM.</li>
|
||||
<li>PPC/e500: Fix write barrier in stores of strings to upvalues.</li>
|
||||
</ul></li>
|
||||
<li>FFI library:
|
||||
<ul>
|
||||
<li>Fix C comment parsing.</li>
|
||||
<li>Fix snapshot optimization for cdata comparisons.</li>
|
||||
<li>Fix recording of const/enum lookups in namespaces.</li>
|
||||
<li>Fix call argument and return handling for <tt>I8/U8/I16/U16</tt> types.</li>
|
||||
<li>Fix unfused loads of float fields.</li>
|
||||
<li>Fix <tt>ffi.string()</tt> recording.</li>
|
||||
<li>Save <tt>GetLastError()</tt> around <tt>ffi.load()</tt> and symbol
|
||||
resolving, too.</li>
|
||||
<li>Improve ld script detection in <tt>ffi.load()</tt>.</li>
|
||||
<li>Record loads/stores to external variables in namespaces.</li>
|
||||
<li>Compile calls to stdcall, fastcall and vararg functions.</li>
|
||||
<li>Treat function ctypes like pointers in comparisons.</li>
|
||||
<li>Resolve <tt>__call</tt> metamethod for pointers, too.</li>
|
||||
<li>Record C function calls with bool return values.</li>
|
||||
<li>Record <tt>ffi.errno()</tt>.</li>
|
||||
<li>x86: Fix number to <tt>uint32_t</tt> conversion rounding.</li>
|
||||
<li>x86: Fix 64 bit arithmetic in assembler backend.</li>
|
||||
<li>x64: Fix struct-by-value calling conventions.</li>
|
||||
<li>ARM: Ensure invocation of SPLIT pass for float conversions.</li>
|
||||
</ul></li>
|
||||
<li>Structural and performance enhancements:
|
||||
<ul>
|
||||
<li>Display trace types with <tt>-jv</tt> and <tt>-jdump</tt>.</li>
|
||||
<li>Record isolated calls. But prefer recording loops over calls.</li>
|
||||
<li>Specialize to prototype for non-monomorphic functions. Solves the
|
||||
trace-explosion problem for closure-heavy programming styles.</li>
|
||||
<li>Always generate a portable <tt>vmdef.lua</tt>. Easier for distros.</li>
|
||||
</ul></li>
|
||||
</ul>
|
||||
|
||||
<h2 id="LuaJIT-2.0.0-beta8">LuaJIT 2.0.0-beta8 — 2011-06-23</h2>
|
||||
<ul>
|
||||
<li>New features:
|
||||
<ul>
|
||||
<li>Soft-float ARM port of LuaJIT is complete.</li>
|
||||
<li>Add support for bytecode loading/saving and <tt>-b</tt> command line
|
||||
option.</li>
|
||||
<li>From Lua 5.2: <tt>__len</tt> metamethod for tables
|
||||
(disabled by default).</li>
|
||||
</ul></li>
|
||||
<li>Correctness and completeness:
|
||||
<ul>
|
||||
<li>ARM: Misc. fixes for interpreter.</li>
|
||||
<li>x86/x64: Fix <tt>bit.*</tt> argument checking in interpreter.</li>
|
||||
<li>Catch early out-of-memory in memory allocator initialization.</li>
|
||||
<li>Fix data-flow analysis for paths leading to an upvalue close.</li>
|
||||
<li>Fix check for missing arguments in <tt>string.format()</tt>.</li>
|
||||
<li>Fix Solaris/x86 build (note: not a supported target).</li>
|
||||
<li>Fix recording of loops with instable directions in side traces.</li>
|
||||
<li>x86/x64: Fix fusion of comparisons with <tt>u8</tt>/<tt>u16</tt>
|
||||
<tt>XLOAD</tt>.</li>
|
||||
<li>x86/x64: Fix register allocation for variable shifts.</li>
|
||||
</ul></li>
|
||||
<li>FFI library:
|
||||
<ul>
|
||||
<li>Add <tt>ffi.errno()</tt>. Save <tt>errno</tt>/<tt>GetLastError()</tt>
|
||||
around allocations etc.</li>
|
||||
<li>Fix <tt>__gc</tt> for VLA/VLS cdata objects.</li>
|
||||
<li>Fix recording of casts from 32 bit cdata pointers to integers.</li>
|
||||
<li><tt>tonumber(cdata)</tt> returns <tt>nil</tt> for non-numbers.</li>
|
||||
<li>Show address pointed to for <tt>tostring(pointer)</tt>.</li>
|
||||
<li>Print <tt>NULL</tt> pointers as <tt>"cdata<... *>: NULL"</tt>.</li>
|
||||
<li>Support <tt>__tostring</tt> metamethod for pointers to structs, too.</li>
|
||||
</ul></li>
|
||||
<li>Structural and performance enhancements:
|
||||
<ul>
|
||||
<li>More tuning for loop unrolling heuristics.</li>
|
||||
<li>Flatten and compress in-memory debug info (saves ~70%).</li>
|
||||
</ul></li>
|
||||
</ul>
|
||||
|
||||
<h2 id="LuaJIT-2.0.0-beta7">LuaJIT 2.0.0-beta7 — 2011-05-05</h2>
|
||||
<ul>
|
||||
<li>New features:
|
||||
<ul>
|
||||
<li>ARM port of the LuaJIT interpreter is complete.</li>
|
||||
<li>FFI library: Add <tt>ffi.gc()</tt>, <tt>ffi.metatype()</tt>,
|
||||
<tt>ffi.istype()</tt>.</li>
|
||||
<li>FFI library: Resolve ld script redirection in <tt>ffi.load()</tt>.</li>
|
||||
<li>From Lua 5.2: <tt>package.searchpath()</tt>, <tt>fp:read("*L")</tt>,
|
||||
<tt>load(string)</tt>.</li>
|
||||
<li>From Lua 5.2, disabled by default: empty statement,
|
||||
<tt>table.unpack()</tt>, modified <tt>coroutine.running()</tt>.</li>
|
||||
</ul></li>
|
||||
<li>Correctness and completeness:
|
||||
<ul>
|
||||
<li>FFI library: numerous fixes.</li>
|
||||
<li>Fix type mismatches in store-to-load forwarding.</li>
|
||||
<li>Fix error handling within metamethods.</li>
|
||||
<li>Fix <tt>table.maxn()</tt>.</li>
|
||||
<li>Improve accuracy of <tt>x^-k</tt> on x64.</li>
|
||||
<li>Fix code generation for Intel Atom in x64 mode.</li>
|
||||
<li>Fix narrowing of POW.</li>
|
||||
<li>Fix recording of retried fast functions.</li>
|
||||
<li>Fix code generation for <tt>bit.bnot()</tt> and multiplies.</li>
|
||||
<li>Fix error location within cpcall frames.</li>
|
||||
<li>Add workaround for old libgcc unwind bug.</li>
|
||||
<li>Fix <tt>lua_yield()</tt> and <tt>getmetatable(lightuserdata)</tt> on x64.</li>
|
||||
<li>Misc. fixes for PPC/e500 interpreter.</li>
|
||||
<li>Fix stack slot updates for down-recursion.</li>
|
||||
</ul></li>
|
||||
<li>Structural and performance enhancements:
|
||||
<ul>
|
||||
<li>Add dual-number mode (int/double) for the VM. Enabled for ARM.</li>
|
||||
<li>Improve narrowing of arithmetic operators and <tt>for</tt> loops.</li>
|
||||
<li>Tune loop unrolling heuristics and increase trace recorder limits.</li>
|
||||
<li>Eliminate dead slots in snapshots using bytecode data-flow analysis.</li>
|
||||
<li>Avoid phantom stores to proxy tables.</li>
|
||||
<li>Optimize lookups in empty proxy tables.</li>
|
||||
<li>Improve bytecode optimization of <tt>and</tt>/<tt>or</tt> operators.</li>
|
||||
</ul></li>
|
||||
</ul>
|
||||
|
||||
<h2 id="LuaJIT-2.0.0-beta6">LuaJIT 2.0.0-beta6 — 2011-02-11</h2>
|
||||
<ul>
|
||||
<li>New features:
|
||||
<ul>
|
||||
<li>PowerPC/e500v2 port of the LuaJIT interpreter is complete.</li>
|
||||
<li>Various minor features from Lua 5.2: Hex escapes in literals,
|
||||
<tt>'\*'</tt> escape, reversible <tt>string.format("%q",s)</tt>,
|
||||
<tt>"%g"</tt> pattern, <tt>table.sort</tt> checks callbacks,
|
||||
<tt>os.exit(status|true|false[,close])</tt>.</li>
|
||||
<li>Lua 5.2 <tt>__pairs</tt> and <tt>__ipairs</tt> metamethods
|
||||
(disabled by default).</li>
|
||||
<li>Initial release of the FFI library.</li>
|
||||
</ul></li>
|
||||
<li>Correctness and completeness:
|
||||
<ul>
|
||||
<li>Fix <tt>string.format()</tt> for non-finite numbers.</li>
|
||||
<li>Fix memory leak when compiled to use the built-in allocator.</li>
|
||||
<li>x86/x64: Fix unnecessary resize in <tt>TSETM</tt> bytecode.</li>
|
||||
<li>Fix various GC issues with traces and <tt>jit.flush()</tt>.</li>
|
||||
<li>x64: Fix fusion of indexes for array references.</li>
|
||||
<li>x86/x64: Fix stack overflow handling for coroutine results.</li>
|
||||
<li>Enable low-2GB memory allocation on FreeBSD/x64.</li>
|
||||
<li>Fix <tt>collectgarbage("count")</tt> result if more than 2GB is in use.</li>
|
||||
<li>Fix parsing of hex floats.</li>
|
||||
<li>x86/x64: Fix loop branch inversion with trailing
|
||||
<tt>HREF+NE/EQ</tt>.</li>
|
||||
<li>Add <tt>jit.os</tt> string.</li>
|
||||
<li><tt>coroutine.create()</tt> permits running C functions, too.</li>
|
||||
<li>Fix OSX build to work with newer ld64 versions.</li>
|
||||
<li>Fix bytecode optimization of <tt>and</tt>/<tt>or</tt> operators.</li>
|
||||
</ul></li>
|
||||
<li>Structural and performance enhancements:
|
||||
<ul>
|
||||
<li>Emit specialized bytecode for <tt>pairs()</tt>/<tt>next()</tt>.</li>
|
||||
<li>Improve bytecode coalescing of <tt>nil</tt> constants.</li>
|
||||
<li>Compile calls to vararg functions.</li>
|
||||
<li>Compile <tt>select()</tt>.</li>
|
||||
<li>Improve alias analysis, esp. for loads from allocations.</li>
|
||||
<li>Tuning of various compiler heuristics.</li>
|
||||
<li>Refactor and extend IR conversion instructions.</li>
|
||||
<li>x86/x64: Various backend enhancements related to the FFI.</li>
|
||||
<li>Add SPLIT pass to split 64 bit IR instructions for 32 bit CPUs.</li>
|
||||
</ul></li>
|
||||
</ul>
|
||||
|
||||
<h2 id="LuaJIT-2.0.0-beta5">LuaJIT 2.0.0-beta5 — 2010-08-24</h2>
|
||||
<ul>
|
||||
<li>Correctness and completeness:
|
||||
<ul>
|
||||
<li>Fix trace exit dispatch to function headers.</li>
|
||||
<li>Fix Windows and OSX builds with LUAJIT_DISABLE_JIT.</li>
|
||||
<li>Reorganize and fix placement of generated machine code on x64.</li>
|
||||
<li>Fix TNEW in x64 interpreter.</li>
|
||||
<li>Do not eliminate PHIs for values only referenced from side exits.</li>
|
||||
<li>OS-independent canonicalization of strings for non-finite numbers.</li>
|
||||
<li>Fix <tt>string.char()</tt> range check on x64.</li>
|
||||
<li>Fix <tt>tostring()</tt> resolving within <tt>print()</tt>.</li>
|
||||
<li>Fix error handling for <tt>next()</tt>.</li>
|
||||
<li>Fix passing of constant arguments to external calls on x64.</li>
|
||||
<li>Fix interpreter argument check for two-argument SSE math functions.</li>
|
||||
<li>Fix C frame chain corruption caused by <tt>lua_cpcall()</tt>.</li>
|
||||
<li>Fix return from <tt>pcall()</tt> within active hook.</li>
|
||||
</ul></li>
|
||||
<li>Structural and performance enhancements:
|
||||
<ul>
|
||||
<li>Replace on-trace GC frame syncing with interpreter exit.</li>
|
||||
<li>Improve hash lookup specialization by not removing dead keys during GC.</li>
|
||||
<li>Turn traces into true GC objects.</li>
|
||||
<li>Avoid starting a GC cycle immediately after library init.</li>
|
||||
<li>Add weak guards to improve dead-code elimination.</li>
|
||||
<li>Speed up string interning.</li>
|
||||
</ul></li>
|
||||
</ul>
|
||||
|
||||
<h2 id="LuaJIT-2.0.0-beta4">LuaJIT 2.0.0-beta4 — 2010-03-28</h2>
|
||||
<ul>
|
||||
<li>Correctness and completeness:
|
||||
<ul>
|
||||
<li>Fix precondition for on-trace creation of table keys.</li>
|
||||
<li>Fix <tt>{f()}</tt> on x64 when table is resized.</li>
|
||||
<li>Fix folding of ordered comparisons with same references.</li>
|
||||
<li>Fix snapshot restores for multi-result bytecodes.</li>
|
||||
<li>Fix potential hang when recording bytecode with nested closures.</li>
|
||||
<li>Fix recording of <tt>getmetatable()</tt>, <tt>tonumber()</tt> and bad argument types.</li>
|
||||
<li>Fix SLOAD fusion across returns to lower frames.</li>
|
||||
</ul></li>
|
||||
<li>Structural and performance enhancements:
|
||||
<ul>
|
||||
<li>Add array bounds check elimination. <tt>-Oabc</tt> is enabled by default.</li>
|
||||
<li>More tuning for x64, e.g. smaller table objects.</li>
|
||||
</ul></li>
|
||||
</ul>
|
||||
|
||||
<h2 id="LuaJIT-2.0.0-beta3">LuaJIT 2.0.0-beta3 — 2010-03-07</h2>
|
||||
<ul>
|
||||
<li>LuaJIT x64 port:
|
||||
<ul>
|
||||
<li>Port integrated memory allocator to Linux/x64, Windows/x64 and OSX/x64.</li>
|
||||
<li>Port interpreter and JIT compiler to x64.</li>
|
||||
<li>Port DynASM to x64.</li>
|
||||
<li>Many 32/64 bit cleanups in the VM.</li>
|
||||
<li>Allow building the interpreter with either x87 or SSE2 arithmetics.</li>
|
||||
<li>Add external unwinding and C++ exception interop (default on x64).</li>
|
||||
</ul></li>
|
||||
<li>Correctness and completeness:
|
||||
<ul>
|
||||
<li>Fix constructor bytecode generation for certain conditional values.</li>
|
||||
<li>Fix some cases of ordered string comparisons.</li>
|
||||
<li>Fix <tt>lua_tocfunction()</tt>.</li>
|
||||
<li>Fix cutoff register in JMP bytecode for some conditional expressions.</li>
|
||||
<li>Fix PHI marking algorithm for references from variant slots.</li>
|
||||
<li>Fix <tt>package.cpath</tt> for non-default PREFIX.</li>
|
||||
<li>Fix DWARF2 frame unwind information for interpreter on OSX.</li>
|
||||
<li>Drive the GC forward on string allocations in the parser.</li>
|
||||
<li>Implement call/return hooks (zero-cost if disabled).</li>
|
||||
<li>Implement yield from C hooks.</li>
|
||||
<li>Disable JIT compiler on older non-SSE2 CPUs instead of aborting.</li>
|
||||
</ul></li>
|
||||
<li>Structural and performance enhancements:
|
||||
<ul>
|
||||
<li>Compile recursive code (tail-, up- and down-recursion).</li>
|
||||
<li>Improve heuristics for bytecode penalties and blacklisting.</li>
|
||||
<li>Split CALL/FUNC recording and clean up fast function call semantics.</li>
|
||||
<li>Major redesign of internal function call handling.</li>
|
||||
<li>Improve FOR loop const specialization and integerness checks.</li>
|
||||
<li>Switch to pre-initialized stacks. Avoid frame-clearing.</li>
|
||||
<li>Colocation of prototypes and related data: bytecode, constants, debug info.</li>
|
||||
<li>Cleanup parser and streamline bytecode generation.</li>
|
||||
<li>Add support for weak IR references to register allocator.</li>
|
||||
<li>Switch to compressed, extensible snapshots.</li>
|
||||
<li>Compile returns to frames below the start frame.</li>
|
||||
<li>Improve alias analysis of upvalues using a disambiguation hash value.</li>
|
||||
<li>Compile floor/ceil/trunc to SSE2 helper calls or SSE4.1 instructions.</li>
|
||||
<li>Add generic C call handling to IR and backend.</li>
|
||||
<li>Improve KNUM fuse vs. load heuristics.</li>
|
||||
<li>Compile various <tt>io.*()</tt> functions.</li>
|
||||
<li>Compile <tt>math.sinh()</tt>, <tt>math.cosh()</tt>, <tt>math.tanh()</tt>
|
||||
and <tt>math.random()</tt>.</li>
|
||||
</ul></li>
|
||||
</ul>
|
||||
|
||||
<h2 id="LuaJIT-2.0.0-beta2">LuaJIT 2.0.0-beta2 — 2009-11-09</h2>
|
||||
<ul>
|
||||
<li>Reorganize build system. Build static+shared library on POSIX.</li>
|
||||
<li>Allow C++ exception conversion on all platforms
|
||||
using a wrapper function.</li>
|
||||
<li>Automatically catch C++ exceptions and rethrow Lua error
|
||||
(DWARF2 only).</li>
|
||||
<li>Check for the correct x87 FPU precision at strategic points.</li>
|
||||
<li>Always use wrappers for libm functions.</li>
|
||||
<li>Resurrect metamethod name strings before copying them.</li>
|
||||
<li>Mark current trace, even if compiler is idle.</li>
|
||||
<li>Ensure FILE metatable is created only once.</li>
|
||||
<li>Fix type comparisons when different integer types are involved.</li>
|
||||
<li>Fix <tt>getmetatable()</tt> recording.</li>
|
||||
<li>Fix TDUP with dead keys in template table.</li>
|
||||
<li><tt>jit.flush(tr)</tt> returns status.
|
||||
Prevent manual flush of a trace that's still linked.</li>
|
||||
<li>Improve register allocation heuristics for invariant references.</li>
|
||||
<li>Compile the push/pop variants of <tt>table.insert()</tt> and
|
||||
<tt>table.remove()</tt>.</li>
|
||||
<li>Compatibility with MSVC <tt>link /debug</tt>.</li>
|
||||
<li>Fix <tt>lua_iscfunction()</tt>.</li>
|
||||
<li>Fix <tt>math.random()</tt> when compiled with <tt>-fpic</tt> (OSX).</li>
|
||||
<li>Fix <tt>table.maxn()</tt>.</li>
|
||||
<li>Bump <tt>MACOSX_DEPLOYMENT_TARGET</tt> to <tt>10.4</tt></li>
|
||||
<li><tt>luaL_check*()</tt> and <tt>luaL_opt*()</tt> now support
|
||||
negative arguments, too.<br>
|
||||
This matches the behavior of Lua 5.1, but not the specification.</li>
|
||||
</ul>
|
||||
|
||||
<h2 id="LuaJIT-2.0.0-beta1">LuaJIT 2.0.0-beta1 — 2009-10-31</h2>
|
||||
<ul>
|
||||
<li>This is the first public release of LuaJIT 2.0.</li>
|
||||
<li>The whole VM has been rewritten from the ground up, so there's
|
||||
no point in listing differences over earlier versions.</li>
|
||||
</ul>
|
||||
</div>
|
||||
<br class="flush">
|
||||
</div>
|
||||
<div id="foot">
|
||||
<hr class="hide">
|
||||
Copyright © 2005-2017 Mike Pall
|
||||
<span class="noprint">
|
||||
·
|
||||
<a href="contact.html">Contact</a>
|
||||
</span>
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
111
vendor/luajit/doc/contact.html
vendored
Normal file
111
vendor/luajit/doc/contact.html
vendored
Normal file
|
@ -0,0 +1,111 @@
|
|||
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
|
||||
<html>
|
||||
<head>
|
||||
<title>Contact</title>
|
||||
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
|
||||
<meta name="Author" content="Mike Pall">
|
||||
<meta name="Copyright" content="Copyright (C) 2005-2017, Mike Pall">
|
||||
<meta name="Language" content="en">
|
||||
<link rel="stylesheet" type="text/css" href="bluequad.css" media="screen">
|
||||
<link rel="stylesheet" type="text/css" href="bluequad-print.css" media="print">
|
||||
</head>
|
||||
<body>
|
||||
<div id="site">
|
||||
<a href="http://luajit.org"><span>Lua<span id="logo">JIT</span></span></a>
|
||||
</div>
|
||||
<div id="head">
|
||||
<h1>Contact</h1>
|
||||
</div>
|
||||
<div id="nav">
|
||||
<ul><li>
|
||||
<a href="luajit.html">LuaJIT</a>
|
||||
<ul><li>
|
||||
<a href="http://luajit.org/download.html">Download <span class="ext">»</span></a>
|
||||
</li><li>
|
||||
<a href="install.html">Installation</a>
|
||||
</li><li>
|
||||
<a href="running.html">Running</a>
|
||||
</li></ul>
|
||||
</li><li>
|
||||
<a href="extensions.html">Extensions</a>
|
||||
<ul><li>
|
||||
<a href="ext_ffi.html">FFI Library</a>
|
||||
<ul><li>
|
||||
<a href="ext_ffi_tutorial.html">FFI Tutorial</a>
|
||||
</li><li>
|
||||
<a href="ext_ffi_api.html">ffi.* API</a>
|
||||
</li><li>
|
||||
<a href="ext_ffi_semantics.html">FFI Semantics</a>
|
||||
</li></ul>
|
||||
</li><li>
|
||||
<a href="ext_jit.html">jit.* Library</a>
|
||||
</li><li>
|
||||
<a href="ext_c_api.html">Lua/C API</a>
|
||||
</li><li>
|
||||
<a href="ext_profiler.html">Profiler</a>
|
||||
</li></ul>
|
||||
</li><li>
|
||||
<a href="status.html">Status</a>
|
||||
<ul><li>
|
||||
<a href="changes.html">Changes</a>
|
||||
</li></ul>
|
||||
</li><li>
|
||||
<a href="faq.html">FAQ</a>
|
||||
</li><li>
|
||||
<a href="http://luajit.org/performance.html">Performance <span class="ext">»</span></a>
|
||||
</li><li>
|
||||
<a href="http://wiki.luajit.org/">Wiki <span class="ext">»</span></a>
|
||||
</li><li>
|
||||
<a href="http://luajit.org/list.html">Mailing List <span class="ext">»</span></a>
|
||||
</li></ul>
|
||||
</div>
|
||||
<div id="main">
|
||||
<p>
|
||||
If you want to report bugs, propose fixes or suggest enhancements,
|
||||
please use the
|
||||
<a href="https://github.com/LuaJIT/LuaJIT/issues">GitHub issue tracker</a>.
|
||||
</p>
|
||||
<p>
|
||||
Please send general questions to the
|
||||
<a href="http://luajit.org/list.html"><span class="ext">»</span> LuaJIT mailing list</a>.
|
||||
</p>
|
||||
<p>
|
||||
You can also send any questions you have directly to me:
|
||||
</p>
|
||||
|
||||
<script type="text/javascript">
|
||||
<!--
|
||||
var xS="@-:\" .0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ<abc>defghijklmnopqrstuvwxyz";function xD(s)
|
||||
{var len=s.length;var r="";for(var i=0;i<len;i++)
|
||||
{var c=s.charAt(i);var n=xS.indexOf(c);if(n!=-1)c=xS.charAt(69-n);r+=c;}
|
||||
document.write("<"+"p>"+r+"<"+"/p>\n");}
|
||||
//-->
|
||||
</script>
|
||||
<script type="text/javascript">
|
||||
<!--
|
||||
xD("fyZKB8xv\"FJytmz8.KAB0u52D")
|
||||
//--></script>
|
||||
<noscript>
|
||||
<p><img src="img/contact.png" alt="Contact info in image" width="170" height="13">
|
||||
</p>
|
||||
</noscript>
|
||||
|
||||
<h2>Copyright</h2>
|
||||
<p>
|
||||
All documentation is
|
||||
Copyright © 2005-2017 Mike Pall.
|
||||
</p>
|
||||
|
||||
|
||||
<br class="flush">
|
||||
</div>
|
||||
<div id="foot">
|
||||
<hr class="hide">
|
||||
Copyright © 2005-2017 Mike Pall
|
||||
<span class="noprint">
|
||||
·
|
||||
<a href="contact.html">Contact</a>
|
||||
</span>
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
189
vendor/luajit/doc/ext_c_api.html
vendored
Normal file
189
vendor/luajit/doc/ext_c_api.html
vendored
Normal file
|
@ -0,0 +1,189 @@
|
|||
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
|
||||
<html>
|
||||
<head>
|
||||
<title>Lua/C API Extensions</title>
|
||||
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
|
||||
<meta name="Author" content="Mike Pall">
|
||||
<meta name="Copyright" content="Copyright (C) 2005-2017, Mike Pall">
|
||||
<meta name="Language" content="en">
|
||||
<link rel="stylesheet" type="text/css" href="bluequad.css" media="screen">
|
||||
<link rel="stylesheet" type="text/css" href="bluequad-print.css" media="print">
|
||||
</head>
|
||||
<body>
|
||||
<div id="site">
|
||||
<a href="http://luajit.org"><span>Lua<span id="logo">JIT</span></span></a>
|
||||
</div>
|
||||
<div id="head">
|
||||
<h1>Lua/C API Extensions</h1>
|
||||
</div>
|
||||
<div id="nav">
|
||||
<ul><li>
|
||||
<a href="luajit.html">LuaJIT</a>
|
||||
<ul><li>
|
||||
<a href="http://luajit.org/download.html">Download <span class="ext">»</span></a>
|
||||
</li><li>
|
||||
<a href="install.html">Installation</a>
|
||||
</li><li>
|
||||
<a href="running.html">Running</a>
|
||||
</li></ul>
|
||||
</li><li>
|
||||
<a href="extensions.html">Extensions</a>
|
||||
<ul><li>
|
||||
<a href="ext_ffi.html">FFI Library</a>
|
||||
<ul><li>
|
||||
<a href="ext_ffi_tutorial.html">FFI Tutorial</a>
|
||||
</li><li>
|
||||
<a href="ext_ffi_api.html">ffi.* API</a>
|
||||
</li><li>
|
||||
<a href="ext_ffi_semantics.html">FFI Semantics</a>
|
||||
</li></ul>
|
||||
</li><li>
|
||||
<a href="ext_jit.html">jit.* Library</a>
|
||||
</li><li>
|
||||
<a class="current" href="ext_c_api.html">Lua/C API</a>
|
||||
</li><li>
|
||||
<a href="ext_profiler.html">Profiler</a>
|
||||
</li></ul>
|
||||
</li><li>
|
||||
<a href="status.html">Status</a>
|
||||
<ul><li>
|
||||
<a href="changes.html">Changes</a>
|
||||
</li></ul>
|
||||
</li><li>
|
||||
<a href="faq.html">FAQ</a>
|
||||
</li><li>
|
||||
<a href="http://luajit.org/performance.html">Performance <span class="ext">»</span></a>
|
||||
</li><li>
|
||||
<a href="http://wiki.luajit.org/">Wiki <span class="ext">»</span></a>
|
||||
</li><li>
|
||||
<a href="http://luajit.org/list.html">Mailing List <span class="ext">»</span></a>
|
||||
</li></ul>
|
||||
</div>
|
||||
<div id="main">
|
||||
<p>
|
||||
LuaJIT adds some extensions to the standard Lua/C API. The LuaJIT include
|
||||
directory must be in the compiler search path (<tt>-I<i>path</i></tt>)
|
||||
to be able to include the required header for C code:
|
||||
</p>
|
||||
<pre class="code">
|
||||
#include "luajit.h"
|
||||
</pre>
|
||||
<p>
|
||||
Or for C++ code:
|
||||
</p>
|
||||
<pre class="code">
|
||||
#include "lua.hpp"
|
||||
</pre>
|
||||
|
||||
<h2 id="luaJIT_setmode"><tt>luaJIT_setmode(L, idx, mode)</tt>
|
||||
— Control VM</h2>
|
||||
<p>
|
||||
This is a C API extension to allow control of the VM from C code. The
|
||||
full prototype of <tt>LuaJIT_setmode</tt> is:
|
||||
</p>
|
||||
<pre class="code">
|
||||
LUA_API int luaJIT_setmode(lua_State *L, int idx, int mode);
|
||||
</pre>
|
||||
<p>
|
||||
The returned status is either success (<tt>1</tt>) or failure (<tt>0</tt>).
|
||||
The second argument is either <tt>0</tt> or a stack index (similar to the
|
||||
other Lua/C API functions).
|
||||
</p>
|
||||
<p>
|
||||
The third argument specifies the mode, which is 'or'ed with a flag.
|
||||
The flag can be <tt>LUAJIT_MODE_OFF</tt> to turn a feature on,
|
||||
<tt>LUAJIT_MODE_ON</tt> to turn a feature off, or
|
||||
<tt>LUAJIT_MODE_FLUSH</tt> to flush cached code.
|
||||
</p>
|
||||
<p>
|
||||
The following modes are defined:
|
||||
</p>
|
||||
|
||||
<h3 id="mode_engine"><tt>luaJIT_setmode(L, 0, LUAJIT_MODE_ENGINE|flag)</tt></h3>
|
||||
<p>
|
||||
Turn the whole JIT compiler on or off or flush the whole cache of compiled code.
|
||||
</p>
|
||||
|
||||
<h3 id="mode_func"><tt>luaJIT_setmode(L, idx, LUAJIT_MODE_FUNC|flag)</tt><br>
|
||||
<tt>luaJIT_setmode(L, idx, LUAJIT_MODE_ALLFUNC|flag)</tt><br>
|
||||
<tt>luaJIT_setmode(L, idx, LUAJIT_MODE_ALLSUBFUNC|flag)</tt></h3>
|
||||
<p>
|
||||
This sets the mode for the function at the stack index <tt>idx</tt> or
|
||||
the parent of the calling function (<tt>idx = 0</tt>). It either
|
||||
enables JIT compilation for a function, disables it and flushes any
|
||||
already compiled code or only flushes already compiled code. This
|
||||
applies recursively to all sub-functions of the function with
|
||||
<tt>LUAJIT_MODE_ALLFUNC</tt> or only to the sub-functions with
|
||||
<tt>LUAJIT_MODE_ALLSUBFUNC</tt>.
|
||||
</p>
|
||||
|
||||
<h3 id="mode_trace"><tt>luaJIT_setmode(L, trace,<br>
|
||||
LUAJIT_MODE_TRACE|LUAJIT_MODE_FLUSH)</tt></h3>
|
||||
<p>
|
||||
Flushes the specified root trace and all of its side traces from the cache.
|
||||
The code for the trace will be retained as long as there are any other
|
||||
traces which link to it.
|
||||
</p>
|
||||
|
||||
<h3 id="mode_wrapcfunc"><tt>luaJIT_setmode(L, idx, LUAJIT_MODE_WRAPCFUNC|flag)</tt></h3>
|
||||
<p>
|
||||
This mode defines a wrapper function for calls to C functions. If
|
||||
called with <tt>LUAJIT_MODE_ON</tt>, the stack index at <tt>idx</tt>
|
||||
must be a <tt>lightuserdata</tt> object holding a pointer to the wrapper
|
||||
function. From now on all C functions are called through the wrapper
|
||||
function. If called with <tt>LUAJIT_MODE_OFF</tt> this mode is turned
|
||||
off and all C functions are directly called.
|
||||
</p>
|
||||
<p>
|
||||
The wrapper function can be used for debugging purposes or to catch
|
||||
and convert foreign exceptions. But please read the section on
|
||||
<a href="extensions.html#exceptions">C++ exception interoperability</a>
|
||||
first. Recommended usage can be seen in this C++ code excerpt:
|
||||
</p>
|
||||
<pre class="code">
|
||||
#include <exception>
|
||||
#include "lua.hpp"
|
||||
|
||||
// Catch C++ exceptions and convert them to Lua error messages.
|
||||
// Customize as needed for your own exception classes.
|
||||
static int wrap_exceptions(lua_State *L, lua_CFunction f)
|
||||
{
|
||||
try {
|
||||
return f(L); // Call wrapped function and return result.
|
||||
} catch (const char *s) { // Catch and convert exceptions.
|
||||
lua_pushstring(L, s);
|
||||
} catch (std::exception& e) {
|
||||
lua_pushstring(L, e.what());
|
||||
} catch (...) {
|
||||
lua_pushliteral(L, "caught (...)");
|
||||
}
|
||||
return lua_error(L); // Rethrow as a Lua error.
|
||||
}
|
||||
|
||||
static int myinit(lua_State *L)
|
||||
{
|
||||
...
|
||||
// Define wrapper function and enable it.
|
||||
lua_pushlightuserdata(L, (void *)wrap_exceptions);
|
||||
luaJIT_setmode(L, -1, LUAJIT_MODE_WRAPCFUNC|LUAJIT_MODE_ON);
|
||||
lua_pop(L, 1);
|
||||
...
|
||||
}
|
||||
</pre>
|
||||
<p>
|
||||
Note that you can only define <b>a single global wrapper function</b>,
|
||||
so be careful when using this mechanism from multiple C++ modules.
|
||||
Also note that this mechanism is not without overhead.
|
||||
</p>
|
||||
<br class="flush">
|
||||
</div>
|
||||
<div id="foot">
|
||||
<hr class="hide">
|
||||
Copyright © 2005-2017 Mike Pall
|
||||
<span class="noprint">
|
||||
·
|
||||
<a href="contact.html">Contact</a>
|
||||
</span>
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
332
vendor/luajit/doc/ext_ffi.html
vendored
Normal file
332
vendor/luajit/doc/ext_ffi.html
vendored
Normal file
|
@ -0,0 +1,332 @@
|
|||
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
|
||||
<html>
|
||||
<head>
|
||||
<title>FFI Library</title>
|
||||
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
|
||||
<meta name="Author" content="Mike Pall">
|
||||
<meta name="Copyright" content="Copyright (C) 2005-2017, Mike Pall">
|
||||
<meta name="Language" content="en">
|
||||
<link rel="stylesheet" type="text/css" href="bluequad.css" media="screen">
|
||||
<link rel="stylesheet" type="text/css" href="bluequad-print.css" media="print">
|
||||
</head>
|
||||
<body>
|
||||
<div id="site">
|
||||
<a href="http://luajit.org"><span>Lua<span id="logo">JIT</span></span></a>
|
||||
</div>
|
||||
<div id="head">
|
||||
<h1>FFI Library</h1>
|
||||
</div>
|
||||
<div id="nav">
|
||||
<ul><li>
|
||||
<a href="luajit.html">LuaJIT</a>
|
||||
<ul><li>
|
||||
<a href="http://luajit.org/download.html">Download <span class="ext">»</span></a>
|
||||
</li><li>
|
||||
<a href="install.html">Installation</a>
|
||||
</li><li>
|
||||
<a href="running.html">Running</a>
|
||||
</li></ul>
|
||||
</li><li>
|
||||
<a href="extensions.html">Extensions</a>
|
||||
<ul><li>
|
||||
<a class="current" href="ext_ffi.html">FFI Library</a>
|
||||
<ul><li>
|
||||
<a href="ext_ffi_tutorial.html">FFI Tutorial</a>
|
||||
</li><li>
|
||||
<a href="ext_ffi_api.html">ffi.* API</a>
|
||||
</li><li>
|
||||
<a href="ext_ffi_semantics.html">FFI Semantics</a>
|
||||
</li></ul>
|
||||
</li><li>
|
||||
<a href="ext_jit.html">jit.* Library</a>
|
||||
</li><li>
|
||||
<a href="ext_c_api.html">Lua/C API</a>
|
||||
</li><li>
|
||||
<a href="ext_profiler.html">Profiler</a>
|
||||
</li></ul>
|
||||
</li><li>
|
||||
<a href="status.html">Status</a>
|
||||
<ul><li>
|
||||
<a href="changes.html">Changes</a>
|
||||
</li></ul>
|
||||
</li><li>
|
||||
<a href="faq.html">FAQ</a>
|
||||
</li><li>
|
||||
<a href="http://luajit.org/performance.html">Performance <span class="ext">»</span></a>
|
||||
</li><li>
|
||||
<a href="http://wiki.luajit.org/">Wiki <span class="ext">»</span></a>
|
||||
</li><li>
|
||||
<a href="http://luajit.org/list.html">Mailing List <span class="ext">»</span></a>
|
||||
</li></ul>
|
||||
</div>
|
||||
<div id="main">
|
||||
<p>
|
||||
|
||||
The FFI library allows <b>calling external C functions</b> and
|
||||
<b>using C data structures</b> from pure Lua code.
|
||||
|
||||
</p>
|
||||
<p>
|
||||
|
||||
The FFI library largely obviates the need to write tedious manual
|
||||
Lua/C bindings in C. No need to learn a separate binding language
|
||||
— <b>it parses plain C declarations!</b> These can be
|
||||
cut-n-pasted from C header files or reference manuals. It's up to
|
||||
the task of binding large libraries without the need for dealing with
|
||||
fragile binding generators.
|
||||
|
||||
</p>
|
||||
<p>
|
||||
The FFI library is tightly integrated into LuaJIT (it's not available
|
||||
as a separate module). The code generated by the JIT-compiler for
|
||||
accesses to C data structures from Lua code is on par with the
|
||||
code a C compiler would generate. Calls to C functions can
|
||||
be inlined in JIT-compiled code, unlike calls to functions bound via
|
||||
the classic Lua/C API.
|
||||
</p>
|
||||
<p>
|
||||
This page gives a short introduction to the usage of the FFI library.
|
||||
<em>Please use the FFI sub-topics in the navigation bar to learn more.</em>
|
||||
</p>
|
||||
|
||||
<h2 id="call">Motivating Example: Calling External C Functions</h2>
|
||||
<p>
|
||||
It's really easy to call an external C library function:
|
||||
</p>
|
||||
<pre class="code mark">
|
||||
<span class="codemark">①
|
||||
②
|
||||
|
||||
|
||||
③</span>local ffi = require("ffi")
|
||||
ffi.cdef[[
|
||||
<span style="color:#00a000;">int printf(const char *fmt, ...);</span>
|
||||
]]
|
||||
ffi.C.printf("Hello %s!", "world")
|
||||
</pre>
|
||||
<p>
|
||||
So, let's pick that apart:
|
||||
</p>
|
||||
<p>
|
||||
<span class="mark">①</span> Load the FFI library.
|
||||
</p>
|
||||
<p>
|
||||
<span class="mark">②</span> Add a C declaration
|
||||
for the function. The part inside the double-brackets (in green) is
|
||||
just standard C syntax.
|
||||
</p>
|
||||
<p>
|
||||
<span class="mark">③</span> Call the named
|
||||
C function — Yes, it's that simple!
|
||||
</p>
|
||||
<p style="font-size: 8pt;">
|
||||
Actually, what goes on behind the scenes is far from simple: <span
|
||||
style="color:#4040c0;">③</span> makes use of the standard
|
||||
C library namespace <tt>ffi.C</tt>. Indexing this namespace with
|
||||
a symbol name (<tt>"printf"</tt>) automatically binds it to the
|
||||
standard C library. The result is a special kind of object which,
|
||||
when called, runs the <tt>printf</tt> function. The arguments passed
|
||||
to this function are automatically converted from Lua objects to the
|
||||
corresponding C types.
|
||||
</p>
|
||||
<p>
|
||||
Ok, so maybe the use of <tt>printf()</tt> wasn't such a spectacular
|
||||
example. You could have done that with <tt>io.write()</tt> and
|
||||
<tt>string.format()</tt>, too. But you get the idea ...
|
||||
</p>
|
||||
<p>
|
||||
So here's something to pop up a message box on Windows:
|
||||
</p>
|
||||
<pre class="code">
|
||||
local ffi = require("ffi")
|
||||
ffi.cdef[[
|
||||
<span style="color:#00a000;">int MessageBoxA(void *w, const char *txt, const char *cap, int type);</span>
|
||||
]]
|
||||
ffi.C.MessageBoxA(nil, "Hello world!", "Test", 0)
|
||||
</pre>
|
||||
<p>
|
||||
Bing! Again, that was far too easy, no?
|
||||
</p>
|
||||
<p style="font-size: 8pt;">
|
||||
Compare this with the effort required to bind that function using the
|
||||
classic Lua/C API: create an extra C file, add a C function
|
||||
that retrieves and checks the argument types passed from Lua and calls
|
||||
the actual C function, add a list of module functions and their
|
||||
names, add a <tt>luaopen_*</tt> function and register all module
|
||||
functions, compile and link it into a shared library (DLL), move it to
|
||||
the proper path, add Lua code that loads the module aaaand ... finally
|
||||
call the binding function. Phew!
|
||||
</p>
|
||||
|
||||
<h2 id="cdata">Motivating Example: Using C Data Structures</h2>
|
||||
<p>
|
||||
The FFI library allows you to create and access C data
|
||||
structures. Of course the main use for this is for interfacing with
|
||||
C functions. But they can be used stand-alone, too.
|
||||
</p>
|
||||
<p>
|
||||
Lua is built upon high-level data types. They are flexible, extensible
|
||||
and dynamic. That's why we all love Lua so much. Alas, this can be
|
||||
inefficient for certain tasks, where you'd really want a low-level
|
||||
data type. E.g. a large array of a fixed structure needs to be
|
||||
implemented with a big table holding lots of tiny tables. This imposes
|
||||
both a substantial memory overhead as well as a performance overhead.
|
||||
</p>
|
||||
<p>
|
||||
Here's a sketch of a library that operates on color images plus a
|
||||
simple benchmark. First, the plain Lua version:
|
||||
</p>
|
||||
<pre class="code">
|
||||
local floor = math.floor
|
||||
|
||||
local function image_ramp_green(n)
|
||||
local img = {}
|
||||
local f = 255/(n-1)
|
||||
for i=1,n do
|
||||
img[i] = { red = 0, green = floor((i-1)*f), blue = 0, alpha = 255 }
|
||||
end
|
||||
return img
|
||||
end
|
||||
|
||||
local function image_to_grey(img, n)
|
||||
for i=1,n do
|
||||
local y = floor(0.3*img[i].red + 0.59*img[i].green + 0.11*img[i].blue)
|
||||
img[i].red = y; img[i].green = y; img[i].blue = y
|
||||
end
|
||||
end
|
||||
|
||||
local N = 400*400
|
||||
local img = image_ramp_green(N)
|
||||
for i=1,1000 do
|
||||
image_to_grey(img, N)
|
||||
end
|
||||
</pre>
|
||||
<p>
|
||||
This creates a table with 160.000 pixels, each of which is a table
|
||||
holding four number values in the range of 0-255. First an image with
|
||||
a green ramp is created (1D for simplicity), then the image is
|
||||
converted to greyscale 1000 times. Yes, that's silly, but I was in
|
||||
need of a simple example ...
|
||||
</p>
|
||||
<p>
|
||||
And here's the FFI version. The modified parts have been marked in
|
||||
bold:
|
||||
</p>
|
||||
<pre class="code mark">
|
||||
<span class="codemark">①
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
②
|
||||
|
||||
③
|
||||
④
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
③
|
||||
⑤</span><b>local ffi = require("ffi")
|
||||
ffi.cdef[[
|
||||
</b><span style="color:#00a000;">typedef struct { uint8_t red, green, blue, alpha; } rgba_pixel;</span><b>
|
||||
]]</b>
|
||||
|
||||
local function image_ramp_green(n)
|
||||
<b>local img = ffi.new("rgba_pixel[?]", n)</b>
|
||||
local f = 255/(n-1)
|
||||
for i=<b>0,n-1</b> do
|
||||
<b>img[i].green = i*f</b>
|
||||
<b>img[i].alpha = 255</b>
|
||||
end
|
||||
return img
|
||||
end
|
||||
|
||||
local function image_to_grey(img, n)
|
||||
for i=<b>0,n-1</b> do
|
||||
local y = <b>0.3*img[i].red + 0.59*img[i].green + 0.11*img[i].blue</b>
|
||||
img[i].red = y; img[i].green = y; img[i].blue = y
|
||||
end
|
||||
end
|
||||
|
||||
local N = 400*400
|
||||
local img = image_ramp_green(N)
|
||||
for i=1,1000 do
|
||||
image_to_grey(img, N)
|
||||
end
|
||||
</pre>
|
||||
<p>
|
||||
Ok, so that wasn't too difficult:
|
||||
</p>
|
||||
<p>
|
||||
<span class="mark">①</span> First, load the FFI
|
||||
library and declare the low-level data type. Here we choose a
|
||||
<tt>struct</tt> which holds four byte fields, one for each component
|
||||
of a 4x8 bit RGBA pixel.
|
||||
</p>
|
||||
<p>
|
||||
<span class="mark">②</span> Creating the data
|
||||
structure with <tt>ffi.new()</tt> is straightforward — the
|
||||
<tt>'?'</tt> is a placeholder for the number of elements of a
|
||||
variable-length array.
|
||||
</p>
|
||||
<p>
|
||||
<span class="mark">③</span> C arrays are
|
||||
zero-based, so the indexes have to run from <tt>0</tt> to
|
||||
<tt>n-1</tt>. One might want to allocate one more element instead to
|
||||
simplify converting legacy code.
|
||||
</p>
|
||||
<p>
|
||||
<span class="mark">④</span> Since <tt>ffi.new()</tt>
|
||||
zero-fills the array by default, we only need to set the green and the
|
||||
alpha fields.
|
||||
</p>
|
||||
<p>
|
||||
<span class="mark">⑤</span> The calls to
|
||||
<tt>math.floor()</tt> can be omitted here, because floating-point
|
||||
numbers are already truncated towards zero when converting them to an
|
||||
integer. This happens implicitly when the number is stored in the
|
||||
fields of each pixel.
|
||||
</p>
|
||||
<p>
|
||||
Now let's have a look at the impact of the changes: first, memory
|
||||
consumption for the image is down from 22 Megabytes to
|
||||
640 Kilobytes (400*400*4 bytes). That's a factor of 35x less! So,
|
||||
yes, tables do have a noticeable overhead. BTW: The original program
|
||||
would consume 40 Megabytes in plain Lua (on x64).
|
||||
</p>
|
||||
<p>
|
||||
Next, performance: the pure Lua version runs in 9.57 seconds (52.9
|
||||
seconds with the Lua interpreter) and the FFI version runs in 0.48
|
||||
seconds on my machine (YMMV). That's a factor of 20x faster (110x
|
||||
faster than the Lua interpreter).
|
||||
</p>
|
||||
<p style="font-size: 8pt;">
|
||||
The avid reader may notice that converting the pure Lua version over
|
||||
to use array indexes for the colors (<tt>[1]</tt> instead of
|
||||
<tt>.red</tt>, <tt>[2]</tt> instead of <tt>.green</tt> etc.) ought to
|
||||
be more compact and faster. This is certainly true (by a factor of
|
||||
~1.7x). Switching to a struct-of-arrays would help, too.
|
||||
</p>
|
||||
<p style="font-size: 8pt;">
|
||||
However the resulting code would be less idiomatic and rather
|
||||
error-prone. And it still doesn't get even close to the performance of
|
||||
the FFI version of the code. Also, high-level data structures cannot
|
||||
be easily passed to other C functions, especially I/O functions,
|
||||
without undue conversion penalties.
|
||||
</p>
|
||||
<br class="flush">
|
||||
</div>
|
||||
<div id="foot">
|
||||
<hr class="hide">
|
||||
Copyright © 2005-2017 Mike Pall
|
||||
<span class="noprint">
|
||||
·
|
||||
<a href="contact.html">Contact</a>
|
||||
</span>
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
570
vendor/luajit/doc/ext_ffi_api.html
vendored
Normal file
570
vendor/luajit/doc/ext_ffi_api.html
vendored
Normal file
|
@ -0,0 +1,570 @@
|
|||
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
|
||||
<html>
|
||||
<head>
|
||||
<title>ffi.* API Functions</title>
|
||||
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
|
||||
<meta name="Author" content="Mike Pall">
|
||||
<meta name="Copyright" content="Copyright (C) 2005-2017, Mike Pall">
|
||||
<meta name="Language" content="en">
|
||||
<link rel="stylesheet" type="text/css" href="bluequad.css" media="screen">
|
||||
<link rel="stylesheet" type="text/css" href="bluequad-print.css" media="print">
|
||||
<style type="text/css">
|
||||
table.abitable { width: 30em; line-height: 1.2; }
|
||||
tr.abihead td { font-weight: bold; }
|
||||
td.abiparam { font-weight: bold; width: 6em; }
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<div id="site">
|
||||
<a href="http://luajit.org"><span>Lua<span id="logo">JIT</span></span></a>
|
||||
</div>
|
||||
<div id="head">
|
||||
<h1><tt>ffi.*</tt> API Functions</h1>
|
||||
</div>
|
||||
<div id="nav">
|
||||
<ul><li>
|
||||
<a href="luajit.html">LuaJIT</a>
|
||||
<ul><li>
|
||||
<a href="http://luajit.org/download.html">Download <span class="ext">»</span></a>
|
||||
</li><li>
|
||||
<a href="install.html">Installation</a>
|
||||
</li><li>
|
||||
<a href="running.html">Running</a>
|
||||
</li></ul>
|
||||
</li><li>
|
||||
<a href="extensions.html">Extensions</a>
|
||||
<ul><li>
|
||||
<a href="ext_ffi.html">FFI Library</a>
|
||||
<ul><li>
|
||||
<a href="ext_ffi_tutorial.html">FFI Tutorial</a>
|
||||
</li><li>
|
||||
<a class="current" href="ext_ffi_api.html">ffi.* API</a>
|
||||
</li><li>
|
||||
<a href="ext_ffi_semantics.html">FFI Semantics</a>
|
||||
</li></ul>
|
||||
</li><li>
|
||||
<a href="ext_jit.html">jit.* Library</a>
|
||||
</li><li>
|
||||
<a href="ext_c_api.html">Lua/C API</a>
|
||||
</li><li>
|
||||
<a href="ext_profiler.html">Profiler</a>
|
||||
</li></ul>
|
||||
</li><li>
|
||||
<a href="status.html">Status</a>
|
||||
<ul><li>
|
||||
<a href="changes.html">Changes</a>
|
||||
</li></ul>
|
||||
</li><li>
|
||||
<a href="faq.html">FAQ</a>
|
||||
</li><li>
|
||||
<a href="http://luajit.org/performance.html">Performance <span class="ext">»</span></a>
|
||||
</li><li>
|
||||
<a href="http://wiki.luajit.org/">Wiki <span class="ext">»</span></a>
|
||||
</li><li>
|
||||
<a href="http://luajit.org/list.html">Mailing List <span class="ext">»</span></a>
|
||||
</li></ul>
|
||||
</div>
|
||||
<div id="main">
|
||||
<p>
|
||||
This page describes the API functions provided by the FFI library in
|
||||
detail. It's recommended to read through the
|
||||
<a href="ext_ffi.html">introduction</a> and the
|
||||
<a href="ext_ffi_tutorial.html">FFI tutorial</a> first.
|
||||
</p>
|
||||
|
||||
<h2 id="glossary">Glossary</h2>
|
||||
<ul>
|
||||
<li><b>cdecl</b> — An abstract C type declaration (a Lua
|
||||
string).</li>
|
||||
<li><b>ctype</b> — A C type object. This is a special kind of
|
||||
<b>cdata</b> returned by <tt>ffi.typeof()</tt>. It serves as a
|
||||
<b>cdata</b> <a href="#ffi_new">constructor</a> when called.</li>
|
||||
<li><b>cdata</b> — A C data object. It holds a value of the
|
||||
corresponding <b>ctype</b>.</li>
|
||||
<li><b>ct</b> — A C type specification which can be used for
|
||||
most of the API functions. Either a <b>cdecl</b>, a <b>ctype</b> or a
|
||||
<b>cdata</b> serving as a template type.</li>
|
||||
<li><b>cb</b> — A callback object. This is a C data object
|
||||
holding a special function pointer. Calling this function from
|
||||
C code runs an associated Lua function.</li>
|
||||
<li><b>VLA</b> — A variable-length array is declared with a
|
||||
<tt>?</tt> instead of the number of elements, e.g. <tt>"int[?]"</tt>.
|
||||
The number of elements (<tt>nelem</tt>) must be given when it's
|
||||
<a href="#ffi_new">created</a>.</li>
|
||||
<li><b>VLS</b> — A variable-length struct is a <tt>struct</tt> C
|
||||
type where the last element is a <b>VLA</b>. The same rules for
|
||||
declaration and creation apply.</li>
|
||||
</ul>
|
||||
|
||||
<h2 id="decl">Declaring and Accessing External Symbols</h2>
|
||||
<p>
|
||||
External symbols must be declared first and can then be accessed by
|
||||
indexing a <a href="ext_ffi_semantics.html#clib">C library
|
||||
namespace</a>, which automatically binds the symbol to a specific
|
||||
library.
|
||||
</p>
|
||||
|
||||
<h3 id="ffi_cdef"><tt>ffi.cdef(def)</tt></h3>
|
||||
<p>
|
||||
Adds multiple C declarations for types or external symbols (named
|
||||
variables or functions). <tt>def</tt> must be a Lua string. It's
|
||||
recommended to use the syntactic sugar for string arguments as
|
||||
follows:
|
||||
</p>
|
||||
<pre class="code">
|
||||
ffi.cdef[[
|
||||
<span style="color:#00a000;">typedef struct foo { int a, b; } foo_t; // Declare a struct and typedef.
|
||||
int dofoo(foo_t *f, int n); /* Declare an external C function. */</span>
|
||||
]]
|
||||
</pre>
|
||||
<p>
|
||||
The contents of the string (the part in green above) must be a
|
||||
sequence of
|
||||
<a href="ext_ffi_semantics.html#clang">C declarations</a>,
|
||||
separated by semicolons. The trailing semicolon for a single
|
||||
declaration may be omitted.
|
||||
</p>
|
||||
<p>
|
||||
Please note that external symbols are only <em>declared</em>, but they
|
||||
are <em>not bound</em> to any specific address, yet. Binding is
|
||||
achieved with C library namespaces (see below).
|
||||
</p>
|
||||
<p style="color: #c00000;">
|
||||
C declarations are not passed through a C pre-processor,
|
||||
yet. No pre-processor tokens are allowed, except for
|
||||
<tt>#pragma pack</tt>. Replace <tt>#define</tt> in existing
|
||||
C header files with <tt>enum</tt>, <tt>static const</tt>
|
||||
or <tt>typedef</tt> and/or pass the files through an external
|
||||
C pre-processor (once). Be careful not to include unneeded or
|
||||
redundant declarations from unrelated header files.
|
||||
</p>
|
||||
|
||||
<h3 id="ffi_C"><tt>ffi.C</tt></h3>
|
||||
<p>
|
||||
This is the default C library namespace — note the
|
||||
uppercase <tt>'C'</tt>. It binds to the default set of symbols or
|
||||
libraries on the target system. These are more or less the same as a
|
||||
C compiler would offer by default, without specifying extra link
|
||||
libraries.
|
||||
</p>
|
||||
<p>
|
||||
On POSIX systems, this binds to symbols in the default or global
|
||||
namespace. This includes all exported symbols from the executable and
|
||||
any libraries loaded into the global namespace. This includes at least
|
||||
<tt>libc</tt>, <tt>libm</tt>, <tt>libdl</tt> (on Linux),
|
||||
<tt>libgcc</tt> (if compiled with GCC), as well as any exported
|
||||
symbols from the Lua/C API provided by LuaJIT itself.
|
||||
</p>
|
||||
<p>
|
||||
On Windows systems, this binds to symbols exported from the
|
||||
<tt>*.exe</tt>, the <tt>lua51.dll</tt> (i.e. the Lua/C API
|
||||
provided by LuaJIT itself), the C runtime library LuaJIT was linked
|
||||
with (<tt>msvcrt*.dll</tt>), <tt>kernel32.dll</tt>,
|
||||
<tt>user32.dll</tt> and <tt>gdi32.dll</tt>.
|
||||
</p>
|
||||
|
||||
<h3 id="ffi_load"><tt>clib = ffi.load(name [,global])</tt></h3>
|
||||
<p>
|
||||
This loads the dynamic library given by <tt>name</tt> and returns
|
||||
a new C library namespace which binds to its symbols. On POSIX
|
||||
systems, if <tt>global</tt> is <tt>true</tt>, the library symbols are
|
||||
loaded into the global namespace, too.
|
||||
</p>
|
||||
<p>
|
||||
If <tt>name</tt> is a path, the library is loaded from this path.
|
||||
Otherwise <tt>name</tt> is canonicalized in a system-dependent way and
|
||||
searched in the default search path for dynamic libraries:
|
||||
</p>
|
||||
<p>
|
||||
On POSIX systems, if the name contains no dot, the extension
|
||||
<tt>.so</tt> is appended. Also, the <tt>lib</tt> prefix is prepended
|
||||
if necessary. So <tt>ffi.load("z")</tt> looks for <tt>"libz.so"</tt>
|
||||
in the default shared library search path.
|
||||
</p>
|
||||
<p>
|
||||
On Windows systems, if the name contains no dot, the extension
|
||||
<tt>.dll</tt> is appended. So <tt>ffi.load("ws2_32")</tt> looks for
|
||||
<tt>"ws2_32.dll"</tt> in the default DLL search path.
|
||||
</p>
|
||||
|
||||
<h2 id="create">Creating cdata Objects</h2>
|
||||
<p>
|
||||
The following API functions create cdata objects (<tt>type()</tt>
|
||||
returns <tt>"cdata"</tt>). All created cdata objects are
|
||||
<a href="ext_ffi_semantics.html#gc">garbage collected</a>.
|
||||
</p>
|
||||
|
||||
<h3 id="ffi_new"><tt>cdata = ffi.new(ct [,nelem] [,init...])<br>
|
||||
cdata = <em>ctype</em>([nelem,] [init...])</tt></h3>
|
||||
<p>
|
||||
Creates a cdata object for the given <tt>ct</tt>. VLA/VLS types
|
||||
require the <tt>nelem</tt> argument. The second syntax uses a ctype as
|
||||
a constructor and is otherwise fully equivalent.
|
||||
</p>
|
||||
<p>
|
||||
The cdata object is initialized according to the
|
||||
<a href="ext_ffi_semantics.html#init">rules for initializers</a>,
|
||||
using the optional <tt>init</tt> arguments. Excess initializers cause
|
||||
an error.
|
||||
</p>
|
||||
<p>
|
||||
Performance notice: if you want to create many objects of one kind,
|
||||
parse the cdecl only once and get its ctype with
|
||||
<tt>ffi.typeof()</tt>. Then use the ctype as a constructor repeatedly.
|
||||
</p>
|
||||
<p style="font-size: 8pt;">
|
||||
Please note that an anonymous <tt>struct</tt> declaration implicitly
|
||||
creates a new and distinguished ctype every time you use it for
|
||||
<tt>ffi.new()</tt>. This is probably <b>not</b> what you want,
|
||||
especially if you create more than one cdata object. Different anonymous
|
||||
<tt>structs</tt> are not considered assignment-compatible by the
|
||||
C standard, even though they may have the same fields! Also, they
|
||||
are considered different types by the JIT-compiler, which may cause an
|
||||
excessive number of traces. It's strongly suggested to either declare
|
||||
a named <tt>struct</tt> or <tt>typedef</tt> with <tt>ffi.cdef()</tt>
|
||||
or to create a single ctype object for an anonymous <tt>struct</tt>
|
||||
with <tt>ffi.typeof()</tt>.
|
||||
</p>
|
||||
|
||||
<h3 id="ffi_typeof"><tt>ctype = ffi.typeof(ct)</tt></h3>
|
||||
<p>
|
||||
Creates a ctype object for the given <tt>ct</tt>.
|
||||
</p>
|
||||
<p>
|
||||
This function is especially useful to parse a cdecl only once and then
|
||||
use the resulting ctype object as a <a href="#ffi_new">constructor</a>.
|
||||
</p>
|
||||
|
||||
<h3 id="ffi_cast"><tt>cdata = ffi.cast(ct, init)</tt></h3>
|
||||
<p>
|
||||
Creates a scalar cdata object for the given <tt>ct</tt>. The cdata
|
||||
object is initialized with <tt>init</tt> using the "cast" variant of
|
||||
the <a href="ext_ffi_semantics.html#convert">C type conversion
|
||||
rules</a>.
|
||||
</p>
|
||||
<p>
|
||||
This functions is mainly useful to override the pointer compatibility
|
||||
checks or to convert pointers to addresses or vice versa.
|
||||
</p>
|
||||
|
||||
<h3 id="ffi_metatype"><tt>ctype = ffi.metatype(ct, metatable)</tt></h3>
|
||||
<p>
|
||||
Creates a ctype object for the given <tt>ct</tt> and associates it with
|
||||
a metatable. Only <tt>struct</tt>/<tt>union</tt> types, complex numbers
|
||||
and vectors are allowed. Other types may be wrapped in a
|
||||
<tt>struct</tt>, if needed.
|
||||
</p>
|
||||
<p>
|
||||
The association with a metatable is permanent and cannot be changed
|
||||
afterwards. Neither the contents of the <tt>metatable</tt> nor the
|
||||
contents of an <tt>__index</tt> table (if any) may be modified
|
||||
afterwards. The associated metatable automatically applies to all uses
|
||||
of this type, no matter how the objects are created or where they
|
||||
originate from. Note that pre-defined operations on types have
|
||||
precedence (e.g. declared field names cannot be overriden).
|
||||
</p>
|
||||
<p>
|
||||
All standard Lua metamethods are implemented. These are called directly,
|
||||
without shortcuts and on any mix of types. For binary operations, the
|
||||
left operand is checked first for a valid ctype metamethod. The
|
||||
<tt>__gc</tt> metamethod only applies to <tt>struct</tt>/<tt>union</tt>
|
||||
types and performs an implicit <a href="#ffi_gc"><tt>ffi.gc()</tt></a>
|
||||
call during creation of an instance.
|
||||
</p>
|
||||
|
||||
<h3 id="ffi_gc"><tt>cdata = ffi.gc(cdata, finalizer)</tt></h3>
|
||||
<p>
|
||||
Associates a finalizer with a pointer or aggregate cdata object. The
|
||||
cdata object is returned unchanged.
|
||||
</p>
|
||||
<p>
|
||||
This function allows safe integration of unmanaged resources into the
|
||||
automatic memory management of the LuaJIT garbage collector. Typical
|
||||
usage:
|
||||
</p>
|
||||
<pre class="code">
|
||||
local p = ffi.gc(ffi.C.malloc(n), ffi.C.free)
|
||||
...
|
||||
p = nil -- Last reference to p is gone.
|
||||
-- GC will eventually run finalizer: ffi.C.free(p)
|
||||
</pre>
|
||||
<p>
|
||||
A cdata finalizer works like the <tt>__gc</tt> metamethod for userdata
|
||||
objects: when the last reference to a cdata object is gone, the
|
||||
associated finalizer is called with the cdata object as an argument. The
|
||||
finalizer can be a Lua function or a cdata function or cdata function
|
||||
pointer. An existing finalizer can be removed by setting a <tt>nil</tt>
|
||||
finalizer, e.g. right before explicitly deleting a resource:
|
||||
</p>
|
||||
<pre class="code">
|
||||
ffi.C.free(ffi.gc(p, nil)) -- Manually free the memory.
|
||||
</pre>
|
||||
|
||||
<h2 id="info">C Type Information</h2>
|
||||
<p>
|
||||
The following API functions return information about C types.
|
||||
They are most useful for inspecting cdata objects.
|
||||
</p>
|
||||
|
||||
<h3 id="ffi_sizeof"><tt>size = ffi.sizeof(ct [,nelem])</tt></h3>
|
||||
<p>
|
||||
Returns the size of <tt>ct</tt> in bytes. Returns <tt>nil</tt> if
|
||||
the size is not known (e.g. for <tt>"void"</tt> or function types).
|
||||
Requires <tt>nelem</tt> for VLA/VLS types, except for cdata objects.
|
||||
</p>
|
||||
|
||||
<h3 id="ffi_alignof"><tt>align = ffi.alignof(ct)</tt></h3>
|
||||
<p>
|
||||
Returns the minimum required alignment for <tt>ct</tt> in bytes.
|
||||
</p>
|
||||
|
||||
<h3 id="ffi_offsetof"><tt>ofs [,bpos,bsize] = ffi.offsetof(ct, field)</tt></h3>
|
||||
<p>
|
||||
Returns the offset (in bytes) of <tt>field</tt> relative to the start
|
||||
of <tt>ct</tt>, which must be a <tt>struct</tt>. Additionally returns
|
||||
the position and the field size (in bits) for bit fields.
|
||||
</p>
|
||||
|
||||
<h3 id="ffi_istype"><tt>status = ffi.istype(ct, obj)</tt></h3>
|
||||
<p>
|
||||
Returns <tt>true</tt> if <tt>obj</tt> has the C type given by
|
||||
<tt>ct</tt>. Returns <tt>false</tt> otherwise.
|
||||
</p>
|
||||
<p>
|
||||
C type qualifiers (<tt>const</tt> etc.) are ignored. Pointers are
|
||||
checked with the standard pointer compatibility rules, but without any
|
||||
special treatment for <tt>void *</tt>. If <tt>ct</tt> specifies a
|
||||
<tt>struct</tt>/<tt>union</tt>, then a pointer to this type is accepted,
|
||||
too. Otherwise the types must match exactly.
|
||||
</p>
|
||||
<p>
|
||||
Note: this function accepts all kinds of Lua objects for the
|
||||
<tt>obj</tt> argument, but always returns <tt>false</tt> for non-cdata
|
||||
objects.
|
||||
</p>
|
||||
|
||||
<h2 id="util">Utility Functions</h2>
|
||||
|
||||
<h3 id="ffi_errno"><tt>err = ffi.errno([newerr])</tt></h3>
|
||||
<p>
|
||||
Returns the error number set by the last C function call which
|
||||
indicated an error condition. If the optional <tt>newerr</tt> argument
|
||||
is present, the error number is set to the new value and the previous
|
||||
value is returned.
|
||||
</p>
|
||||
<p>
|
||||
This function offers a portable and OS-independent way to get and set the
|
||||
error number. Note that only <em>some</em> C functions set the error
|
||||
number. And it's only significant if the function actually indicated an
|
||||
error condition (e.g. with a return value of <tt>-1</tt> or
|
||||
<tt>NULL</tt>). Otherwise, it may or may not contain any previously set
|
||||
value.
|
||||
</p>
|
||||
<p>
|
||||
You're advised to call this function only when needed and as close as
|
||||
possible after the return of the related C function. The
|
||||
<tt>errno</tt> value is preserved across hooks, memory allocations,
|
||||
invocations of the JIT compiler and other internal VM activity. The same
|
||||
applies to the value returned by <tt>GetLastError()</tt> on Windows, but
|
||||
you need to declare and call it yourself.
|
||||
</p>
|
||||
|
||||
<h3 id="ffi_string"><tt>str = ffi.string(ptr [,len])</tt></h3>
|
||||
<p>
|
||||
Creates an interned Lua string from the data pointed to by
|
||||
<tt>ptr</tt>.
|
||||
</p>
|
||||
<p>
|
||||
If the optional argument <tt>len</tt> is missing, <tt>ptr</tt> is
|
||||
converted to a <tt>"char *"</tt> and the data is assumed to be
|
||||
zero-terminated. The length of the string is computed with
|
||||
<tt>strlen()</tt>.
|
||||
</p>
|
||||
<p>
|
||||
Otherwise <tt>ptr</tt> is converted to a <tt>"void *"</tt> and
|
||||
<tt>len</tt> gives the length of the data. The data may contain
|
||||
embedded zeros and need not be byte-oriented (though this may cause
|
||||
endianess issues).
|
||||
</p>
|
||||
<p>
|
||||
This function is mainly useful to convert (temporary)
|
||||
<tt>"const char *"</tt> pointers returned by
|
||||
C functions to Lua strings and store them or pass them to other
|
||||
functions expecting a Lua string. The Lua string is an (interned) copy
|
||||
of the data and bears no relation to the original data area anymore.
|
||||
Lua strings are 8 bit clean and may be used to hold arbitrary,
|
||||
non-character data.
|
||||
</p>
|
||||
<p>
|
||||
Performance notice: it's faster to pass the length of the string, if
|
||||
it's known. E.g. when the length is returned by a C call like
|
||||
<tt>sprintf()</tt>.
|
||||
</p>
|
||||
|
||||
<h3 id="ffi_copy"><tt>ffi.copy(dst, src, len)<br>
|
||||
ffi.copy(dst, str)</tt></h3>
|
||||
<p>
|
||||
Copies the data pointed to by <tt>src</tt> to <tt>dst</tt>.
|
||||
<tt>dst</tt> is converted to a <tt>"void *"</tt> and <tt>src</tt>
|
||||
is converted to a <tt>"const void *"</tt>.
|
||||
</p>
|
||||
<p>
|
||||
In the first syntax, <tt>len</tt> gives the number of bytes to copy.
|
||||
Caveat: if <tt>src</tt> is a Lua string, then <tt>len</tt> must not
|
||||
exceed <tt>#src+1</tt>.
|
||||
</p>
|
||||
<p>
|
||||
In the second syntax, the source of the copy must be a Lua string. All
|
||||
bytes of the string <em>plus a zero-terminator</em> are copied to
|
||||
<tt>dst</tt> (i.e. <tt>#src+1</tt> bytes).
|
||||
</p>
|
||||
<p>
|
||||
Performance notice: <tt>ffi.copy()</tt> may be used as a faster
|
||||
(inlinable) replacement for the C library functions
|
||||
<tt>memcpy()</tt>, <tt>strcpy()</tt> and <tt>strncpy()</tt>.
|
||||
</p>
|
||||
|
||||
<h3 id="ffi_fill"><tt>ffi.fill(dst, len [,c])</tt></h3>
|
||||
<p>
|
||||
Fills the data pointed to by <tt>dst</tt> with <tt>len</tt> constant
|
||||
bytes, given by <tt>c</tt>. If <tt>c</tt> is omitted, the data is
|
||||
zero-filled.
|
||||
</p>
|
||||
<p>
|
||||
Performance notice: <tt>ffi.fill()</tt> may be used as a faster
|
||||
(inlinable) replacement for the C library function
|
||||
<tt>memset(dst, c, len)</tt>. Please note the different
|
||||
order of arguments!
|
||||
</p>
|
||||
|
||||
<h2 id="target">Target-specific Information</h2>
|
||||
|
||||
<h3 id="ffi_abi"><tt>status = ffi.abi(param)</tt></h3>
|
||||
<p>
|
||||
Returns <tt>true</tt> if <tt>param</tt> (a Lua string) applies for the
|
||||
target ABI (Application Binary Interface). Returns <tt>false</tt>
|
||||
otherwise. The following parameters are currently defined:
|
||||
</p>
|
||||
<table class="abitable">
|
||||
<tr class="abihead">
|
||||
<td class="abiparam">Parameter</td>
|
||||
<td class="abidesc">Description</td>
|
||||
</tr>
|
||||
<tr class="odd separate">
|
||||
<td class="abiparam">32bit</td><td class="abidesc">32 bit architecture</td></tr>
|
||||
<tr class="even">
|
||||
<td class="abiparam">64bit</td><td class="abidesc">64 bit architecture</td></tr>
|
||||
<tr class="odd separate">
|
||||
<td class="abiparam">le</td><td class="abidesc">Little-endian architecture</td></tr>
|
||||
<tr class="even">
|
||||
<td class="abiparam">be</td><td class="abidesc">Big-endian architecture</td></tr>
|
||||
<tr class="odd separate">
|
||||
<td class="abiparam">fpu</td><td class="abidesc">Target has a hardware FPU</td></tr>
|
||||
<tr class="even">
|
||||
<td class="abiparam">softfp</td><td class="abidesc">softfp calling conventions</td></tr>
|
||||
<tr class="odd">
|
||||
<td class="abiparam">hardfp</td><td class="abidesc">hardfp calling conventions</td></tr>
|
||||
<tr class="even separate">
|
||||
<td class="abiparam">eabi</td><td class="abidesc">EABI variant of the standard ABI</td></tr>
|
||||
<tr class="odd">
|
||||
<td class="abiparam">win</td><td class="abidesc">Windows variant of the standard ABI</td></tr>
|
||||
<tr class="even">
|
||||
<td class="abiparam">gc64</td><td class="abidesc">64 bit GC references</td></tr>
|
||||
</table>
|
||||
|
||||
<h3 id="ffi_os"><tt>ffi.os</tt></h3>
|
||||
<p>
|
||||
Contains the target OS name. Same contents as
|
||||
<a href="ext_jit.html#jit_os"><tt>jit.os</tt></a>.
|
||||
</p>
|
||||
|
||||
<h3 id="ffi_arch"><tt>ffi.arch</tt></h3>
|
||||
<p>
|
||||
Contains the target architecture name. Same contents as
|
||||
<a href="ext_jit.html#jit_arch"><tt>jit.arch</tt></a>.
|
||||
</p>
|
||||
|
||||
<h2 id="callback">Methods for Callbacks</h2>
|
||||
<p>
|
||||
The C types for <a href="ext_ffi_semantics.html#callback">callbacks</a>
|
||||
have some extra methods:
|
||||
</p>
|
||||
|
||||
<h3 id="callback_free"><tt>cb:free()</tt></h3>
|
||||
<p>
|
||||
Free the resources associated with a callback. The associated Lua
|
||||
function is unanchored and may be garbage collected. The callback
|
||||
function pointer is no longer valid and must not be called anymore
|
||||
(it may be reused by a subsequently created callback).
|
||||
</p>
|
||||
|
||||
<h3 id="callback_set"><tt>cb:set(func)</tt></h3>
|
||||
<p>
|
||||
Associate a new Lua function with a callback. The C type of the
|
||||
callback and the callback function pointer are unchanged.
|
||||
</p>
|
||||
<p>
|
||||
This method is useful to dynamically switch the receiver of callbacks
|
||||
without creating a new callback each time and registering it again (e.g.
|
||||
with a GUI library).
|
||||
</p>
|
||||
|
||||
<h2 id="extended">Extended Standard Library Functions</h2>
|
||||
<p>
|
||||
The following standard library functions have been extended to work
|
||||
with cdata objects:
|
||||
</p>
|
||||
|
||||
<h3 id="tonumber"><tt>n = tonumber(cdata)</tt></h3>
|
||||
<p>
|
||||
Converts a number cdata object to a <tt>double</tt> and returns it as
|
||||
a Lua number. This is particularly useful for boxed 64 bit
|
||||
integer values. Caveat: this conversion may incur a precision loss.
|
||||
</p>
|
||||
|
||||
<h3 id="tostring"><tt>s = tostring(cdata)</tt></h3>
|
||||
<p>
|
||||
Returns a string representation of the value of 64 bit integers
|
||||
(<tt><b>"</b>nnn<b>LL"</b></tt> or <tt><b>"</b>nnn<b>ULL"</b></tt>) or
|
||||
complex numbers (<tt><b>"</b>re±im<b>i"</b></tt>). Otherwise
|
||||
returns a string representation of the C type of a ctype object
|
||||
(<tt><b>"ctype<</b>type<b>>"</b></tt>) or a cdata object
|
||||
(<tt><b>"cdata<</b>type<b>>: </b>address"</tt>), unless you
|
||||
override it with a <tt>__tostring</tt> metamethod (see
|
||||
<a href="#ffi_metatype"><tt>ffi.metatype()</tt></a>).
|
||||
</p>
|
||||
|
||||
<h3 id="pairs"><tt>iter, obj, start = pairs(cdata)<br>
|
||||
iter, obj, start = ipairs(cdata)<br></tt></h3>
|
||||
<p>
|
||||
Calls the <tt>__pairs</tt> or <tt>__ipairs</tt> metamethod of the
|
||||
corresponding ctype.
|
||||
</p>
|
||||
|
||||
<h2 id="literals">Extensions to the Lua Parser</h2>
|
||||
<p>
|
||||
The parser for Lua source code treats numeric literals with the
|
||||
suffixes <tt>LL</tt> or <tt>ULL</tt> as signed or unsigned 64 bit
|
||||
integers. Case doesn't matter, but uppercase is recommended for
|
||||
readability. It handles decimal (<tt>42LL</tt>), hexadecimal
|
||||
(<tt>0x2aLL</tt>) and binary (<tt>0b101010LL</tt>) literals.
|
||||
</p>
|
||||
<p>
|
||||
The imaginary part of complex numbers can be specified by suffixing
|
||||
number literals with <tt>i</tt> or <tt>I</tt>, e.g. <tt>12.5i</tt>.
|
||||
Caveat: you'll need to use <tt>1i</tt> to get an imaginary part with
|
||||
the value one, since <tt>i</tt> itself still refers to a variable
|
||||
named <tt>i</tt>.
|
||||
</p>
|
||||
<br class="flush">
|
||||
</div>
|
||||
<div id="foot">
|
||||
<hr class="hide">
|
||||
Copyright © 2005-2017 Mike Pall
|
||||
<span class="noprint">
|
||||
·
|
||||
<a href="contact.html">Contact</a>
|
||||
</span>
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
1262
vendor/luajit/doc/ext_ffi_semantics.html
vendored
Normal file
1262
vendor/luajit/doc/ext_ffi_semantics.html
vendored
Normal file
File diff suppressed because it is too large
Load diff
603
vendor/luajit/doc/ext_ffi_tutorial.html
vendored
Normal file
603
vendor/luajit/doc/ext_ffi_tutorial.html
vendored
Normal file
|
@ -0,0 +1,603 @@
|
|||
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
|
||||
<html>
|
||||
<head>
|
||||
<title>FFI Tutorial</title>
|
||||
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
|
||||
<meta name="Author" content="Mike Pall">
|
||||
<meta name="Copyright" content="Copyright (C) 2005-2017, Mike Pall">
|
||||
<meta name="Language" content="en">
|
||||
<link rel="stylesheet" type="text/css" href="bluequad.css" media="screen">
|
||||
<link rel="stylesheet" type="text/css" href="bluequad-print.css" media="print">
|
||||
<style type="text/css">
|
||||
table.idiomtable { font-size: 90%; line-height: 1.2; }
|
||||
table.idiomtable tt { font-size: 100%; }
|
||||
table.idiomtable td { vertical-align: top; }
|
||||
tr.idiomhead td { font-weight: bold; }
|
||||
td.idiomlua b { font-weight: normal; color: #2142bf; }
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<div id="site">
|
||||
<a href="http://luajit.org"><span>Lua<span id="logo">JIT</span></span></a>
|
||||
</div>
|
||||
<div id="head">
|
||||
<h1>FFI Tutorial</h1>
|
||||
</div>
|
||||
<div id="nav">
|
||||
<ul><li>
|
||||
<a href="luajit.html">LuaJIT</a>
|
||||
<ul><li>
|
||||
<a href="http://luajit.org/download.html">Download <span class="ext">»</span></a>
|
||||
</li><li>
|
||||
<a href="install.html">Installation</a>
|
||||
</li><li>
|
||||
<a href="running.html">Running</a>
|
||||
</li></ul>
|
||||
</li><li>
|
||||
<a href="extensions.html">Extensions</a>
|
||||
<ul><li>
|
||||
<a href="ext_ffi.html">FFI Library</a>
|
||||
<ul><li>
|
||||
<a class="current" href="ext_ffi_tutorial.html">FFI Tutorial</a>
|
||||
</li><li>
|
||||
<a href="ext_ffi_api.html">ffi.* API</a>
|
||||
</li><li>
|
||||
<a href="ext_ffi_semantics.html">FFI Semantics</a>
|
||||
</li></ul>
|
||||
</li><li>
|
||||
<a href="ext_jit.html">jit.* Library</a>
|
||||
</li><li>
|
||||
<a href="ext_c_api.html">Lua/C API</a>
|
||||
</li><li>
|
||||
<a href="ext_profiler.html">Profiler</a>
|
||||
</li></ul>
|
||||
</li><li>
|
||||
<a href="status.html">Status</a>
|
||||
<ul><li>
|
||||
<a href="changes.html">Changes</a>
|
||||
</li></ul>
|
||||
</li><li>
|
||||
<a href="faq.html">FAQ</a>
|
||||
</li><li>
|
||||
<a href="http://luajit.org/performance.html">Performance <span class="ext">»</span></a>
|
||||
</li><li>
|
||||
<a href="http://wiki.luajit.org/">Wiki <span class="ext">»</span></a>
|
||||
</li><li>
|
||||
<a href="http://luajit.org/list.html">Mailing List <span class="ext">»</span></a>
|
||||
</li></ul>
|
||||
</div>
|
||||
<div id="main">
|
||||
<p>
|
||||
This page is intended to give you an overview of the features of the FFI
|
||||
library by presenting a few use cases and guidelines.
|
||||
</p>
|
||||
<p>
|
||||
This page makes no attempt to explain all of the FFI library, though.
|
||||
You'll want to have a look at the <a href="ext_ffi_api.html">ffi.* API
|
||||
function reference</a> and the <a href="ext_ffi_semantics.html">FFI
|
||||
semantics</a> to learn more.
|
||||
</p>
|
||||
|
||||
<h2 id="load">Loading the FFI Library</h2>
|
||||
<p>
|
||||
The FFI library is built into LuaJIT by default, but it's not loaded
|
||||
and initialized by default. The suggested way to use the FFI library
|
||||
is to add the following to the start of every Lua file that needs one
|
||||
of its functions:
|
||||
</p>
|
||||
<pre class="code">
|
||||
local ffi = require("ffi")
|
||||
</pre>
|
||||
<p>
|
||||
Please note this doesn't define an <tt>ffi</tt> variable in the table
|
||||
of globals — you really need to use the local variable. The
|
||||
<tt>require</tt> function ensures the library is only loaded once.
|
||||
</p>
|
||||
<p style="font-size: 8pt;">
|
||||
Note: If you want to experiment with the FFI from the interactive prompt
|
||||
of the command line executable, omit the <tt>local</tt>, as it doesn't
|
||||
preserve local variables across lines.
|
||||
</p>
|
||||
|
||||
<h2 id="sleep">Accessing Standard System Functions</h2>
|
||||
<p>
|
||||
The following code explains how to access standard system functions.
|
||||
We slowly print two lines of dots by sleeping for 10 milliseconds
|
||||
after each dot:
|
||||
</p>
|
||||
<pre class="code mark">
|
||||
<span class="codemark">
|
||||
①
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
②
|
||||
③
|
||||
④
|
||||
|
||||
|
||||
|
||||
⑤
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
⑥</span>local ffi = require("ffi")
|
||||
ffi.cdef[[
|
||||
<span style="color:#00a000;">void Sleep(int ms);
|
||||
int poll(struct pollfd *fds, unsigned long nfds, int timeout);</span>
|
||||
]]
|
||||
|
||||
local sleep
|
||||
if ffi.os == "Windows" then
|
||||
function sleep(s)
|
||||
ffi.C.Sleep(s*1000)
|
||||
end
|
||||
else
|
||||
function sleep(s)
|
||||
ffi.C.poll(nil, 0, s*1000)
|
||||
end
|
||||
end
|
||||
|
||||
for i=1,160 do
|
||||
io.write("."); io.flush()
|
||||
sleep(0.01)
|
||||
end
|
||||
io.write("\n")
|
||||
</pre>
|
||||
<p>
|
||||
Here's the step-by-step explanation:
|
||||
</p>
|
||||
<p>
|
||||
<span class="mark">①</span> This defines the
|
||||
C library functions we're going to use. The part inside the
|
||||
double-brackets (in green) is just standard C syntax. You can
|
||||
usually get this info from the C header files or the
|
||||
documentation provided by each C library or C compiler.
|
||||
</p>
|
||||
<p>
|
||||
<span class="mark">②</span> The difficulty we're
|
||||
facing here, is that there are different standards to choose from.
|
||||
Windows has a simple <tt>Sleep()</tt> function. On other systems there
|
||||
are a variety of functions available to achieve sub-second sleeps, but
|
||||
with no clear consensus. Thankfully <tt>poll()</tt> can be used for
|
||||
this task, too, and it's present on most non-Windows systems. The
|
||||
check for <tt>ffi.os</tt> makes sure we use the Windows-specific
|
||||
function only on Windows systems.
|
||||
</p>
|
||||
<p>
|
||||
<span class="mark">③</span> Here we're wrapping the
|
||||
call to the C function in a Lua function. This isn't strictly
|
||||
necessary, but it's helpful to deal with system-specific issues only
|
||||
in one part of the code. The way we're wrapping it ensures the check
|
||||
for the OS is only done during initialization and not for every call.
|
||||
</p>
|
||||
<p>
|
||||
<span class="mark">④</span> A more subtle point is
|
||||
that we defined our <tt>sleep()</tt> function (for the sake of this
|
||||
example) as taking the number of seconds, but accepting fractional
|
||||
seconds. Multiplying this by 1000 gets us milliseconds, but that still
|
||||
leaves it a Lua number, which is a floating-point value. Alas, the
|
||||
<tt>Sleep()</tt> function only accepts an integer value. Luckily for
|
||||
us, the FFI library automatically performs the conversion when calling
|
||||
the function (truncating the FP value towards zero, like in C).
|
||||
</p>
|
||||
<p style="font-size: 8pt;">
|
||||
Some readers will notice that <tt>Sleep()</tt> is part of
|
||||
<tt>KERNEL32.DLL</tt> and is also a <tt>stdcall</tt> function. So how
|
||||
can this possibly work? The FFI library provides the <tt>ffi.C</tt>
|
||||
default C library namespace, which allows calling functions from
|
||||
the default set of libraries, like a C compiler would. Also, the
|
||||
FFI library automatically detects <tt>stdcall</tt> functions, so you
|
||||
don't need to declare them as such.
|
||||
</p>
|
||||
<p>
|
||||
<span class="mark">⑤</span> The <tt>poll()</tt>
|
||||
function takes a couple more arguments we're not going to use. You can
|
||||
simply use <tt>nil</tt> to pass a <tt>NULL</tt> pointer and <tt>0</tt>
|
||||
for the <tt>nfds</tt> parameter. Please note that the
|
||||
number <tt>0</tt> <em>does not convert to a pointer value</em>,
|
||||
unlike in C++. You really have to pass pointers to pointer arguments
|
||||
and numbers to number arguments.
|
||||
</p>
|
||||
<p style="font-size: 8pt;">
|
||||
The page on <a href="ext_ffi_semantics.html">FFI semantics</a> has all
|
||||
of the gory details about
|
||||
<a href="ext_ffi_semantics.html#convert">conversions between Lua
|
||||
objects and C types</a>. For the most part you don't have to deal
|
||||
with this, as it's performed automatically and it's carefully designed
|
||||
to bridge the semantic differences between Lua and C.
|
||||
</p>
|
||||
<p>
|
||||
<span class="mark">⑥</span> Now that we have defined
|
||||
our own <tt>sleep()</tt> function, we can just call it from plain Lua
|
||||
code. That wasn't so bad, huh? Turning these boring animated dots into
|
||||
a fascinating best-selling game is left as an exercise for the reader.
|
||||
:-)
|
||||
</p>
|
||||
|
||||
<h2 id="zlib">Accessing the zlib Compression Library</h2>
|
||||
<p>
|
||||
The following code shows how to access the <a
|
||||
href="http://zlib.net/">zlib</a> compression library from Lua code.
|
||||
We'll define two convenience wrapper functions that take a string and
|
||||
compress or uncompress it to another string:
|
||||
</p>
|
||||
<pre class="code mark">
|
||||
<span class="codemark">
|
||||
①
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
②
|
||||
|
||||
|
||||
③
|
||||
|
||||
④
|
||||
|
||||
|
||||
⑤
|
||||
|
||||
|
||||
⑥
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
⑦</span>local ffi = require("ffi")
|
||||
ffi.cdef[[
|
||||
<span style="color:#00a000;">unsigned long compressBound(unsigned long sourceLen);
|
||||
int compress2(uint8_t *dest, unsigned long *destLen,
|
||||
const uint8_t *source, unsigned long sourceLen, int level);
|
||||
int uncompress(uint8_t *dest, unsigned long *destLen,
|
||||
const uint8_t *source, unsigned long sourceLen);</span>
|
||||
]]
|
||||
local zlib = ffi.load(ffi.os == "Windows" and "zlib1" or "z")
|
||||
|
||||
local function compress(txt)
|
||||
local n = zlib.compressBound(#txt)
|
||||
local buf = ffi.new("uint8_t[?]", n)
|
||||
local buflen = ffi.new("unsigned long[1]", n)
|
||||
local res = zlib.compress2(buf, buflen, txt, #txt, 9)
|
||||
assert(res == 0)
|
||||
return ffi.string(buf, buflen[0])
|
||||
end
|
||||
|
||||
local function uncompress(comp, n)
|
||||
local buf = ffi.new("uint8_t[?]", n)
|
||||
local buflen = ffi.new("unsigned long[1]", n)
|
||||
local res = zlib.uncompress(buf, buflen, comp, #comp)
|
||||
assert(res == 0)
|
||||
return ffi.string(buf, buflen[0])
|
||||
end
|
||||
|
||||
-- Simple test code.
|
||||
local txt = string.rep("abcd", 1000)
|
||||
print("Uncompressed size: ", #txt)
|
||||
local c = compress(txt)
|
||||
print("Compressed size: ", #c)
|
||||
local txt2 = uncompress(c, #txt)
|
||||
assert(txt2 == txt)
|
||||
</pre>
|
||||
<p>
|
||||
Here's the step-by-step explanation:
|
||||
</p>
|
||||
<p>
|
||||
<span class="mark">①</span> This defines some of the
|
||||
C functions provided by zlib. For the sake of this example, some
|
||||
type indirections have been reduced and it uses the pre-defined
|
||||
fixed-size integer types, while still adhering to the zlib API/ABI.
|
||||
</p>
|
||||
<p>
|
||||
<span class="mark">②</span> This loads the zlib shared
|
||||
library. On POSIX systems it's named <tt>libz.so</tt> and usually
|
||||
comes pre-installed. Since <tt>ffi.load()</tt> automatically adds any
|
||||
missing standard prefixes/suffixes, we can simply load the
|
||||
<tt>"z"</tt> library. On Windows it's named <tt>zlib1.dll</tt> and
|
||||
you'll have to download it first from the
|
||||
<a href="http://zlib.net/"><span class="ext">»</span> zlib site</a>. The check for
|
||||
<tt>ffi.os</tt> makes sure we pass the right name to
|
||||
<tt>ffi.load()</tt>.
|
||||
</p>
|
||||
<p>
|
||||
<span class="mark">③</span> First, the maximum size of
|
||||
the compression buffer is obtained by calling the
|
||||
<tt>zlib.compressBound</tt> function with the length of the
|
||||
uncompressed string. The next line allocates a byte buffer of this
|
||||
size. The <tt>[?]</tt> in the type specification indicates a
|
||||
variable-length array (VLA). The actual number of elements of this
|
||||
array is given as the 2nd argument to <tt>ffi.new()</tt>.
|
||||
</p>
|
||||
<p>
|
||||
<span class="mark">④</span> This may look strange at
|
||||
first, but have a look at the declaration of the <tt>compress2</tt>
|
||||
function from zlib: the destination length is defined as a pointer!
|
||||
This is because you pass in the maximum buffer size and get back the
|
||||
actual length that was used.
|
||||
</p>
|
||||
<p>
|
||||
In C you'd pass in the address of a local variable
|
||||
(<tt>&buflen</tt>). But since there's no address-of operator in
|
||||
Lua, we'll just pass in a one-element array. Conveniently it can be
|
||||
initialized with the maximum buffer size in one step. Calling the
|
||||
actual <tt>zlib.compress2</tt> function is then straightforward.
|
||||
</p>
|
||||
<p>
|
||||
<span class="mark">⑤</span> We want to return the
|
||||
compressed data as a Lua string, so we'll use <tt>ffi.string()</tt>.
|
||||
It needs a pointer to the start of the data and the actual length. The
|
||||
length has been returned in the <tt>buflen</tt> array, so we'll just
|
||||
get it from there.
|
||||
</p>
|
||||
<p style="font-size: 8pt;">
|
||||
Note that since the function returns now, the <tt>buf</tt> and
|
||||
<tt>buflen</tt> variables will eventually be garbage collected. This
|
||||
is fine, because <tt>ffi.string()</tt> has copied the contents to a
|
||||
newly created (interned) Lua string. If you plan to call this function
|
||||
lots of times, consider reusing the buffers and/or handing back the
|
||||
results in buffers instead of strings. This will reduce the overhead
|
||||
for garbage collection and string interning.
|
||||
</p>
|
||||
<p>
|
||||
<span class="mark">⑥</span> The <tt>uncompress</tt>
|
||||
functions does the exact opposite of the <tt>compress</tt> function.
|
||||
The compressed data doesn't include the size of the original string,
|
||||
so this needs to be passed in. Otherwise no surprises here.
|
||||
</p>
|
||||
<p>
|
||||
<span class="mark">⑦</span> The code, that makes use
|
||||
of the functions we just defined, is just plain Lua code. It doesn't
|
||||
need to know anything about the LuaJIT FFI — the convenience
|
||||
wrapper functions completely hide it.
|
||||
</p>
|
||||
<p>
|
||||
One major advantage of the LuaJIT FFI is that you are now able to
|
||||
write those wrappers <em>in Lua</em>. And at a fraction of the time it
|
||||
would cost you to create an extra C module using the Lua/C API.
|
||||
Many of the simpler C functions can probably be used directly
|
||||
from your Lua code, without any wrappers.
|
||||
</p>
|
||||
<p style="font-size: 8pt;">
|
||||
Side note: the zlib API uses the <tt>long</tt> type for passing
|
||||
lengths and sizes around. But all those zlib functions actually only
|
||||
deal with 32 bit values. This is an unfortunate choice for a
|
||||
public API, but may be explained by zlib's history — we'll just
|
||||
have to deal with it.
|
||||
</p>
|
||||
<p style="font-size: 8pt;">
|
||||
First, you should know that a <tt>long</tt> is a 64 bit type e.g.
|
||||
on POSIX/x64 systems, but a 32 bit type on Windows/x64 and on
|
||||
32 bit systems. Thus a <tt>long</tt> result can be either a plain
|
||||
Lua number or a boxed 64 bit integer cdata object, depending on
|
||||
the target system.
|
||||
</p>
|
||||
<p style="font-size: 8pt;">
|
||||
Ok, so the <tt>ffi.*</tt> functions generally accept cdata objects
|
||||
wherever you'd want to use a number. That's why we get a away with
|
||||
passing <tt>n</tt> to <tt>ffi.string()</tt> above. But other Lua
|
||||
library functions or modules don't know how to deal with this. So for
|
||||
maximum portability one needs to use <tt>tonumber()</tt> on returned
|
||||
<tt>long</tt> results before passing them on. Otherwise the
|
||||
application might work on some systems, but would fail in a POSIX/x64
|
||||
environment.
|
||||
</p>
|
||||
|
||||
<h2 id="metatype">Defining Metamethods for a C Type</h2>
|
||||
<p>
|
||||
The following code explains how to define metamethods for a C type.
|
||||
We define a simple point type and add some operations to it:
|
||||
</p>
|
||||
<pre class="code mark">
|
||||
<span class="codemark">
|
||||
①
|
||||
|
||||
|
||||
|
||||
②
|
||||
|
||||
③
|
||||
|
||||
④
|
||||
|
||||
|
||||
|
||||
⑤
|
||||
|
||||
⑥</span>local ffi = require("ffi")
|
||||
ffi.cdef[[
|
||||
<span style="color:#00a000;">typedef struct { double x, y; } point_t;</span>
|
||||
]]
|
||||
|
||||
local point
|
||||
local mt = {
|
||||
__add = function(a, b) return point(a.x+b.x, a.y+b.y) end,
|
||||
__len = function(a) return math.sqrt(a.x*a.x + a.y*a.y) end,
|
||||
__index = {
|
||||
area = function(a) return a.x*a.x + a.y*a.y end,
|
||||
},
|
||||
}
|
||||
point = ffi.metatype("point_t", mt)
|
||||
|
||||
local a = point(3, 4)
|
||||
print(a.x, a.y) --> 3 4
|
||||
print(#a) --> 5
|
||||
print(a:area()) --> 25
|
||||
local b = a + point(0.5, 8)
|
||||
print(#b) --> 12.5
|
||||
</pre>
|
||||
<p>
|
||||
Here's the step-by-step explanation:
|
||||
</p>
|
||||
<p>
|
||||
<span class="mark">①</span> This defines the C type for a
|
||||
two-dimensional point object.
|
||||
</p>
|
||||
<p>
|
||||
<span class="mark">②</span> We have to declare the variable
|
||||
holding the point constructor first, because it's used inside of a
|
||||
metamethod.
|
||||
</p>
|
||||
<p>
|
||||
<span class="mark">③</span> Let's define an <tt>__add</tt>
|
||||
metamethod which adds the coordinates of two points and creates a new
|
||||
point object. For simplicity, this function assumes that both arguments
|
||||
are points. But it could be any mix of objects, if at least one operand
|
||||
is of the required type (e.g. adding a point plus a number or vice
|
||||
versa). Our <tt>__len</tt> metamethod returns the distance of a point to
|
||||
the origin.
|
||||
</p>
|
||||
<p>
|
||||
<span class="mark">④</span> If we run out of operators, we can
|
||||
define named methods, too. Here the <tt>__index</tt> table defines an
|
||||
<tt>area</tt> function. For custom indexing needs, one might want to
|
||||
define <tt>__index</tt> and <tt>__newindex</tt> <em>functions</em> instead.
|
||||
</p>
|
||||
<p>
|
||||
<span class="mark">⑤</span> This associates the metamethods with
|
||||
our C type. This only needs to be done once. For convenience, a
|
||||
constructor is returned by
|
||||
<a href="ext_ffi_api.html#ffi_metatype"><tt>ffi.metatype()</tt></a>.
|
||||
We're not required to use it, though. The original C type can still
|
||||
be used e.g. to create an array of points. The metamethods automatically
|
||||
apply to any and all uses of this type.
|
||||
</p>
|
||||
<p>
|
||||
Please note that the association with a metatable is permanent and
|
||||
<b>the metatable must not be modified afterwards!</b> Ditto for the
|
||||
<tt>__index</tt> table.
|
||||
</p>
|
||||
<p>
|
||||
<span class="mark">⑥</span> Here are some simple usage examples
|
||||
for the point type and their expected results. The pre-defined
|
||||
operations (such as <tt>a.x</tt>) can be freely mixed with the newly
|
||||
defined metamethods. Note that <tt>area</tt> is a method and must be
|
||||
called with the Lua syntax for methods: <tt>a:area()</tt>, not
|
||||
<tt>a.area()</tt>.
|
||||
</p>
|
||||
<p>
|
||||
The C type metamethod mechanism is most useful when used in
|
||||
conjunction with C libraries that are written in an object-oriented
|
||||
style. Creators return a pointer to a new instance and methods take an
|
||||
instance pointer as the first argument. Sometimes you can just point
|
||||
<tt>__index</tt> to the library namespace and <tt>__gc</tt> to the
|
||||
destructor and you're done. But often enough you'll want to add
|
||||
convenience wrappers, e.g. to return actual Lua strings or when
|
||||
returning multiple values.
|
||||
</p>
|
||||
<p>
|
||||
Some C libraries only declare instance pointers as an opaque
|
||||
<tt>void *</tt> type. In this case you can use a fake type for all
|
||||
declarations, e.g. a pointer to a named (incomplete) struct will do:
|
||||
<tt>typedef struct foo_type *foo_handle</tt>. The C side doesn't
|
||||
know what you declare with the LuaJIT FFI, but as long as the underlying
|
||||
types are compatible, everything still works.
|
||||
</p>
|
||||
|
||||
<h2 id="idioms">Translating C Idioms</h2>
|
||||
<p>
|
||||
Here's a list of common C idioms and their translation to the
|
||||
LuaJIT FFI:
|
||||
</p>
|
||||
<table class="idiomtable">
|
||||
<tr class="idiomhead">
|
||||
<td class="idiomdesc">Idiom</td>
|
||||
<td class="idiomc">C code</td>
|
||||
<td class="idiomlua">Lua code</td>
|
||||
</tr>
|
||||
<tr class="odd separate">
|
||||
<td class="idiomdesc">Pointer dereference<br><tt>int *p;</tt></td><td class="idiomc"><tt>x = *p;<br>*p = y;</tt></td><td class="idiomlua"><tt>x = <b>p[0]</b><br><b>p[0]</b> = y</tt></td></tr>
|
||||
<tr class="even">
|
||||
<td class="idiomdesc">Pointer indexing<br><tt>int i, *p;</tt></td><td class="idiomc"><tt>x = p[i];<br>p[i+1] = y;</tt></td><td class="idiomlua"><tt>x = p[i]<br>p[i+1] = y</tt></td></tr>
|
||||
<tr class="odd">
|
||||
<td class="idiomdesc">Array indexing<br><tt>int i, a[];</tt></td><td class="idiomc"><tt>x = a[i];<br>a[i+1] = y;</tt></td><td class="idiomlua"><tt>x = a[i]<br>a[i+1] = y</tt></td></tr>
|
||||
<tr class="even separate">
|
||||
<td class="idiomdesc"><tt>struct</tt>/<tt>union</tt> dereference<br><tt>struct foo s;</tt></td><td class="idiomc"><tt>x = s.field;<br>s.field = y;</tt></td><td class="idiomlua"><tt>x = s.field<br>s.field = y</tt></td></tr>
|
||||
<tr class="odd">
|
||||
<td class="idiomdesc"><tt>struct</tt>/<tt>union</tt> pointer deref.<br><tt>struct foo *sp;</tt></td><td class="idiomc"><tt>x = sp->field;<br>sp->field = y;</tt></td><td class="idiomlua"><tt>x = <b>s.field</b><br><b>s.field</b> = y</tt></td></tr>
|
||||
<tr class="even separate">
|
||||
<td class="idiomdesc">Pointer arithmetic<br><tt>int i, *p;</tt></td><td class="idiomc"><tt>x = p + i;<br>y = p - i;</tt></td><td class="idiomlua"><tt>x = p + i<br>y = p - i</tt></td></tr>
|
||||
<tr class="odd">
|
||||
<td class="idiomdesc">Pointer difference<br><tt>int *p1, *p2;</tt></td><td class="idiomc"><tt>x = p1 - p2;</tt></td><td class="idiomlua"><tt>x = p1 - p2</tt></td></tr>
|
||||
<tr class="even">
|
||||
<td class="idiomdesc">Array element pointer<br><tt>int i, a[];</tt></td><td class="idiomc"><tt>x = &a[i];</tt></td><td class="idiomlua"><tt>x = <b>a+i</b></tt></td></tr>
|
||||
<tr class="odd">
|
||||
<td class="idiomdesc">Cast pointer to address<br><tt>int *p;</tt></td><td class="idiomc"><tt>x = (intptr_t)p;</tt></td><td class="idiomlua"><tt>x = <b>tonumber(<br> ffi.cast("intptr_t",<br> p))</b></tt></td></tr>
|
||||
<tr class="even separate">
|
||||
<td class="idiomdesc">Functions with outargs<br><tt>void foo(int *inoutlen);</tt></td><td class="idiomc"><tt>int len = x;<br>foo(&len);<br>y = len;</tt></td><td class="idiomlua"><tt><b>local len =<br> ffi.new("int[1]", x)<br>foo(len)<br>y = len[0]</b></tt></td></tr>
|
||||
<tr class="odd">
|
||||
<td class="idiomdesc"><a href="ext_ffi_semantics.html#convert_vararg">Vararg conversions</a><br><tt>int printf(char *fmt, ...);</tt></td><td class="idiomc"><tt>printf("%g", 1.0);<br>printf("%d", 1);<br> </tt></td><td class="idiomlua"><tt>printf("%g", 1);<br>printf("%d",<br> <b>ffi.new("int", 1)</b>)</tt></td></tr>
|
||||
</table>
|
||||
|
||||
<h2 id="cache">To Cache or Not to Cache</h2>
|
||||
<p>
|
||||
It's a common Lua idiom to cache library functions in local variables
|
||||
or upvalues, e.g.:
|
||||
</p>
|
||||
<pre class="code">
|
||||
local byte, char = string.byte, string.char
|
||||
local function foo(x)
|
||||
return char(byte(x)+1)
|
||||
end
|
||||
</pre>
|
||||
<p>
|
||||
This replaces several hash-table lookups with a (faster) direct use of
|
||||
a local or an upvalue. This is less important with LuaJIT, since the
|
||||
JIT compiler optimizes hash-table lookups a lot and is even able to
|
||||
hoist most of them out of the inner loops. It can't eliminate
|
||||
<em>all</em> of them, though, and it saves some typing for often-used
|
||||
functions. So there's still a place for this, even with LuaJIT.
|
||||
</p>
|
||||
<p>
|
||||
The situation is a bit different with C function calls via the
|
||||
FFI library. The JIT compiler has special logic to eliminate <em>all
|
||||
of the lookup overhead</em> for functions resolved from a
|
||||
<a href="ext_ffi_semantics.html#clib">C library namespace</a>!
|
||||
Thus it's not helpful and actually counter-productive to cache
|
||||
individual C functions like this:
|
||||
</p>
|
||||
<pre class="code">
|
||||
local <b>funca</b>, <b>funcb</b> = ffi.C.funca, ffi.C.funcb -- <span style="color:#c00000;">Not helpful!</span>
|
||||
local function foo(x, n)
|
||||
for i=1,n do <b>funcb</b>(<b>funca</b>(x, i), 1) end
|
||||
end
|
||||
</pre>
|
||||
<p>
|
||||
This turns them into indirect calls and generates bigger and slower
|
||||
machine code. Instead you'll want to cache the namespace itself and
|
||||
rely on the JIT compiler to eliminate the lookups:
|
||||
</p>
|
||||
<pre class="code">
|
||||
local <b>C</b> = ffi.C -- <span style="color:#00a000;">Instead use this!</span>
|
||||
local function foo(x, n)
|
||||
for i=1,n do <b>C.funcb</b>(<b>C.funca</b>(x, i), 1) end
|
||||
end
|
||||
</pre>
|
||||
<p>
|
||||
This generates both shorter and faster code. So <b>don't cache
|
||||
C functions</b>, but <b>do</b> cache namespaces! Most often the
|
||||
namespace is already in a local variable at an outer scope, e.g. from
|
||||
<tt>local lib = ffi.load(...)</tt>. Note that copying
|
||||
it to a local variable in the function scope is unnecessary.
|
||||
</p>
|
||||
<br class="flush">
|
||||
</div>
|
||||
<div id="foot">
|
||||
<hr class="hide">
|
||||
Copyright © 2005-2017 Mike Pall
|
||||
<span class="noprint">
|
||||
·
|
||||
<a href="contact.html">Contact</a>
|
||||
</span>
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
201
vendor/luajit/doc/ext_jit.html
vendored
Normal file
201
vendor/luajit/doc/ext_jit.html
vendored
Normal file
|
@ -0,0 +1,201 @@
|
|||
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
|
||||
<html>
|
||||
<head>
|
||||
<title>jit.* Library</title>
|
||||
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
|
||||
<meta name="Author" content="Mike Pall">
|
||||
<meta name="Copyright" content="Copyright (C) 2005-2017, Mike Pall">
|
||||
<meta name="Language" content="en">
|
||||
<link rel="stylesheet" type="text/css" href="bluequad.css" media="screen">
|
||||
<link rel="stylesheet" type="text/css" href="bluequad-print.css" media="print">
|
||||
</head>
|
||||
<body>
|
||||
<div id="site">
|
||||
<a href="http://luajit.org"><span>Lua<span id="logo">JIT</span></span></a>
|
||||
</div>
|
||||
<div id="head">
|
||||
<h1><tt>jit.*</tt> Library</h1>
|
||||
</div>
|
||||
<div id="nav">
|
||||
<ul><li>
|
||||
<a href="luajit.html">LuaJIT</a>
|
||||
<ul><li>
|
||||
<a href="http://luajit.org/download.html">Download <span class="ext">»</span></a>
|
||||
</li><li>
|
||||
<a href="install.html">Installation</a>
|
||||
</li><li>
|
||||
<a href="running.html">Running</a>
|
||||
</li></ul>
|
||||
</li><li>
|
||||
<a href="extensions.html">Extensions</a>
|
||||
<ul><li>
|
||||
<a href="ext_ffi.html">FFI Library</a>
|
||||
<ul><li>
|
||||
<a href="ext_ffi_tutorial.html">FFI Tutorial</a>
|
||||
</li><li>
|
||||
<a href="ext_ffi_api.html">ffi.* API</a>
|
||||
</li><li>
|
||||
<a href="ext_ffi_semantics.html">FFI Semantics</a>
|
||||
</li></ul>
|
||||
</li><li>
|
||||
<a class="current" href="ext_jit.html">jit.* Library</a>
|
||||
</li><li>
|
||||
<a href="ext_c_api.html">Lua/C API</a>
|
||||
</li><li>
|
||||
<a href="ext_profiler.html">Profiler</a>
|
||||
</li></ul>
|
||||
</li><li>
|
||||
<a href="status.html">Status</a>
|
||||
<ul><li>
|
||||
<a href="changes.html">Changes</a>
|
||||
</li></ul>
|
||||
</li><li>
|
||||
<a href="faq.html">FAQ</a>
|
||||
</li><li>
|
||||
<a href="http://luajit.org/performance.html">Performance <span class="ext">»</span></a>
|
||||
</li><li>
|
||||
<a href="http://wiki.luajit.org/">Wiki <span class="ext">»</span></a>
|
||||
</li><li>
|
||||
<a href="http://luajit.org/list.html">Mailing List <span class="ext">»</span></a>
|
||||
</li></ul>
|
||||
</div>
|
||||
<div id="main">
|
||||
<p>
|
||||
The functions in this built-in module control the behavior of the JIT
|
||||
compiler engine. Note that JIT-compilation is fully automatic —
|
||||
you probably won't need to use any of the following functions unless
|
||||
you have special needs.
|
||||
</p>
|
||||
|
||||
<h3 id="jit_onoff"><tt>jit.on()<br>
|
||||
jit.off()</tt></h3>
|
||||
<p>
|
||||
Turns the whole JIT compiler on (default) or off.
|
||||
</p>
|
||||
<p>
|
||||
These functions are typically used with the command line options
|
||||
<tt>-j on</tt> or <tt>-j off</tt>.
|
||||
</p>
|
||||
|
||||
<h3 id="jit_flush"><tt>jit.flush()</tt></h3>
|
||||
<p>
|
||||
Flushes the whole cache of compiled code.
|
||||
</p>
|
||||
|
||||
<h3 id="jit_onoff_func"><tt>jit.on(func|true [,true|false])<br>
|
||||
jit.off(func|true [,true|false])<br>
|
||||
jit.flush(func|true [,true|false])</tt></h3>
|
||||
<p>
|
||||
<tt>jit.on</tt> enables JIT compilation for a Lua function (this is
|
||||
the default).
|
||||
</p>
|
||||
<p>
|
||||
<tt>jit.off</tt> disables JIT compilation for a Lua function and
|
||||
flushes any already compiled code from the code cache.
|
||||
</p>
|
||||
<p>
|
||||
<tt>jit.flush</tt> flushes the code, but doesn't affect the
|
||||
enable/disable status.
|
||||
</p>
|
||||
<p>
|
||||
The current function, i.e. the Lua function calling this library
|
||||
function, can also be specified by passing <tt>true</tt> as the first
|
||||
argument.
|
||||
</p>
|
||||
<p>
|
||||
If the second argument is <tt>true</tt>, JIT compilation is also
|
||||
enabled, disabled or flushed recursively for all sub-functions of a
|
||||
function. With <tt>false</tt> only the sub-functions are affected.
|
||||
</p>
|
||||
<p>
|
||||
The <tt>jit.on</tt> and <tt>jit.off</tt> functions only set a flag
|
||||
which is checked when the function is about to be compiled. They do
|
||||
not trigger immediate compilation.
|
||||
</p>
|
||||
<p>
|
||||
Typical usage is <tt>jit.off(true, true)</tt> in the main chunk
|
||||
of a module to turn off JIT compilation for the whole module for
|
||||
debugging purposes.
|
||||
</p>
|
||||
|
||||
<h3 id="jit_flush_tr"><tt>jit.flush(tr)</tt></h3>
|
||||
<p>
|
||||
Flushes the root trace, specified by its number, and all of its side
|
||||
traces from the cache. The code for the trace will be retained as long
|
||||
as there are any other traces which link to it.
|
||||
</p>
|
||||
|
||||
<h3 id="jit_status"><tt>status, ... = jit.status()</tt></h3>
|
||||
<p>
|
||||
Returns the current status of the JIT compiler. The first result is
|
||||
either <tt>true</tt> or <tt>false</tt> if the JIT compiler is turned
|
||||
on or off. The remaining results are strings for CPU-specific features
|
||||
and enabled optimizations.
|
||||
</p>
|
||||
|
||||
<h3 id="jit_version"><tt>jit.version</tt></h3>
|
||||
<p>
|
||||
Contains the LuaJIT version string.
|
||||
</p>
|
||||
|
||||
<h3 id="jit_version_num"><tt>jit.version_num</tt></h3>
|
||||
<p>
|
||||
Contains the version number of the LuaJIT core. Version xx.yy.zz
|
||||
is represented by the decimal number xxyyzz.
|
||||
</p>
|
||||
|
||||
<h3 id="jit_os"><tt>jit.os</tt></h3>
|
||||
<p>
|
||||
Contains the target OS name:
|
||||
"Windows", "Linux", "OSX", "BSD", "POSIX" or "Other".
|
||||
</p>
|
||||
|
||||
<h3 id="jit_arch"><tt>jit.arch</tt></h3>
|
||||
<p>
|
||||
Contains the target architecture name:
|
||||
"x86", "x64", "arm", "arm64", "ppc", "mips" or "mips64".
|
||||
</p>
|
||||
|
||||
<h2 id="jit_opt"><tt>jit.opt.*</tt> — JIT compiler optimization control</h2>
|
||||
<p>
|
||||
This sub-module provides the backend for the <tt>-O</tt> command line
|
||||
option.
|
||||
</p>
|
||||
<p>
|
||||
You can also use it programmatically, e.g.:
|
||||
</p>
|
||||
<pre class="code">
|
||||
jit.opt.start(2) -- same as -O2
|
||||
jit.opt.start("-dce")
|
||||
jit.opt.start("hotloop=10", "hotexit=2")
|
||||
</pre>
|
||||
<p>
|
||||
Unlike in LuaJIT 1.x, the module is built-in and
|
||||
<b>optimization is turned on by default!</b>
|
||||
It's no longer necessary to run <tt>require("jit.opt").start()</tt>,
|
||||
which was one of the ways to enable optimization.
|
||||
</p>
|
||||
|
||||
<h2 id="jit_util"><tt>jit.util.*</tt> — JIT compiler introspection</h2>
|
||||
<p>
|
||||
This sub-module holds functions to introspect the bytecode, generated
|
||||
traces, the IR and the generated machine code. The functionality
|
||||
provided by this module is still in flux and therefore undocumented.
|
||||
</p>
|
||||
<p>
|
||||
The debug modules <tt>-jbc</tt>, <tt>-jv</tt> and <tt>-jdump</tt> make
|
||||
extensive use of these functions. Please check out their source code,
|
||||
if you want to know more.
|
||||
</p>
|
||||
<br class="flush">
|
||||
</div>
|
||||
<div id="foot">
|
||||
<hr class="hide">
|
||||
Copyright © 2005-2017 Mike Pall
|
||||
<span class="noprint">
|
||||
·
|
||||
<a href="contact.html">Contact</a>
|
||||
</span>
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
365
vendor/luajit/doc/ext_profiler.html
vendored
Normal file
365
vendor/luajit/doc/ext_profiler.html
vendored
Normal file
|
@ -0,0 +1,365 @@
|
|||
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
|
||||
<html>
|
||||
<head>
|
||||
<title>Profiler</title>
|
||||
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
|
||||
<meta name="Author" content="Mike Pall">
|
||||
<meta name="Copyright" content="Copyright (C) 2005-2017, Mike Pall">
|
||||
<meta name="Language" content="en">
|
||||
<link rel="stylesheet" type="text/css" href="bluequad.css" media="screen">
|
||||
<link rel="stylesheet" type="text/css" href="bluequad-print.css" media="print">
|
||||
</head>
|
||||
<body>
|
||||
<div id="site">
|
||||
<a href="http://luajit.org"><span>Lua<span id="logo">JIT</span></span></a>
|
||||
</div>
|
||||
<div id="head">
|
||||
<h1>Profiler</h1>
|
||||
</div>
|
||||
<div id="nav">
|
||||
<ul><li>
|
||||
<a href="luajit.html">LuaJIT</a>
|
||||
<ul><li>
|
||||
<a href="http://luajit.org/download.html">Download <span class="ext">»</span></a>
|
||||
</li><li>
|
||||
<a href="install.html">Installation</a>
|
||||
</li><li>
|
||||
<a href="running.html">Running</a>
|
||||
</li></ul>
|
||||
</li><li>
|
||||
<a href="extensions.html">Extensions</a>
|
||||
<ul><li>
|
||||
<a href="ext_ffi.html">FFI Library</a>
|
||||
<ul><li>
|
||||
<a href="ext_ffi_tutorial.html">FFI Tutorial</a>
|
||||
</li><li>
|
||||
<a href="ext_ffi_api.html">ffi.* API</a>
|
||||
</li><li>
|
||||
<a href="ext_ffi_semantics.html">FFI Semantics</a>
|
||||
</li></ul>
|
||||
</li><li>
|
||||
<a href="ext_jit.html">jit.* Library</a>
|
||||
</li><li>
|
||||
<a href="ext_c_api.html">Lua/C API</a>
|
||||
</li><li>
|
||||
<a class="current" href="ext_profiler.html">Profiler</a>
|
||||
</li></ul>
|
||||
</li><li>
|
||||
<a href="status.html">Status</a>
|
||||
<ul><li>
|
||||
<a href="changes.html">Changes</a>
|
||||
</li></ul>
|
||||
</li><li>
|
||||
<a href="faq.html">FAQ</a>
|
||||
</li><li>
|
||||
<a href="http://luajit.org/performance.html">Performance <span class="ext">»</span></a>
|
||||
</li><li>
|
||||
<a href="http://wiki.luajit.org/">Wiki <span class="ext">»</span></a>
|
||||
</li><li>
|
||||
<a href="http://luajit.org/list.html">Mailing List <span class="ext">»</span></a>
|
||||
</li></ul>
|
||||
</div>
|
||||
<div id="main">
|
||||
<p>
|
||||
LuaJIT has an integrated statistical profiler with very low overhead. It
|
||||
allows sampling the currently executing stack and other parameters in
|
||||
regular intervals.
|
||||
</p>
|
||||
<p>
|
||||
The integrated profiler can be accessed from three levels:
|
||||
</p>
|
||||
<ul>
|
||||
<li>The <a href="#hl_profiler">bundled high-level profiler</a>, invoked by the
|
||||
<a href="#j_p"><tt>-jp</tt></a> command line option.</li>
|
||||
<li>A <a href="#ll_lua_api">low-level Lua API</a> to control the profiler.</li>
|
||||
<li>A <a href="#ll_c_api">low-level C API</a> to control the profiler.</li>
|
||||
</ul>
|
||||
|
||||
<h2 id="hl_profiler">High-Level Profiler</h2>
|
||||
<p>
|
||||
The bundled high-level profiler offers basic profiling functionality. It
|
||||
generates simple textual summaries or source code annotations. It can be
|
||||
accessed with the <a href="#j_p"><tt>-jp</tt></a> command line option
|
||||
or from Lua code by loading the underlying <tt>jit.p</tt> module.
|
||||
</p>
|
||||
<p>
|
||||
To cut to the chase — run this to get a CPU usage profile by
|
||||
function name:
|
||||
</p>
|
||||
<pre class="code">
|
||||
luajit -jp myapp.lua
|
||||
</pre>
|
||||
<p>
|
||||
It's <em>not</em> a stated goal of the bundled profiler to add every
|
||||
possible option or to cater for special profiling needs. The low-level
|
||||
profiler APIs are documented below. They may be used by third-party
|
||||
authors to implement advanced functionality, e.g. IDE integration or
|
||||
graphical profilers.
|
||||
</p>
|
||||
<p>
|
||||
Note: Sampling works for both interpreted and JIT-compiled code. The
|
||||
results for JIT-compiled code may sometimes be surprising. LuaJIT
|
||||
heavily optimizes and inlines Lua code — there's no simple
|
||||
one-to-one correspondence between source code lines and the sampled
|
||||
machine code.
|
||||
</p>
|
||||
|
||||
<h3 id="j_p"><tt>-jp=[options[,output]]</tt></h3>
|
||||
<p>
|
||||
The <tt>-jp</tt> command line option starts the high-level profiler.
|
||||
When the application run by the command line terminates, the profiler
|
||||
stops and writes the results to <tt>stdout</tt> or to the specified
|
||||
<tt>output</tt> file.
|
||||
</p>
|
||||
<p>
|
||||
The <tt>options</tt> argument specifies how the profiling is to be
|
||||
performed:
|
||||
</p>
|
||||
<ul>
|
||||
<li><tt>f</tt> — Stack dump: function name, otherwise module:line.
|
||||
This is the default mode.</li>
|
||||
<li><tt>F</tt> — Stack dump: ditto, but dump module:name.</li>
|
||||
<li><tt>l</tt> — Stack dump: module:line.</li>
|
||||
<li><tt><number></tt> — stack dump depth (callee ←
|
||||
caller). Default: 1.</li>
|
||||
<li><tt>-<number></tt> — Inverse stack dump depth (caller
|
||||
→ callee).</li>
|
||||
<li><tt>s</tt> — Split stack dump after first stack level. Implies
|
||||
depth ≥ 2 or depth ≤ -2.</li>
|
||||
<li><tt>p</tt> — Show full path for module names.</li>
|
||||
<li><tt>v</tt> — Show VM states.</li>
|
||||
<li><tt>z</tt> — Show <a href="#jit_zone">zones</a>.</li>
|
||||
<li><tt>r</tt> — Show raw sample counts. Default: show percentages.</li>
|
||||
<li><tt>a</tt> — Annotate excerpts from source code files.</li>
|
||||
<li><tt>A</tt> — Annotate complete source code files.</li>
|
||||
<li><tt>G</tt> — Produce raw output suitable for graphical tools.</li>
|
||||
<li><tt>m<number></tt> — Minimum sample percentage to be shown.
|
||||
Default: 3%.</li>
|
||||
<li><tt>i<number></tt> — Sampling interval in milliseconds.
|
||||
Default: 10ms.<br>
|
||||
Note: The actual sampling precision is OS-dependent.</li>
|
||||
</ul>
|
||||
<p>
|
||||
The default output for <tt>-jp</tt> is a list of the most CPU consuming
|
||||
spots in the application. Increasing the stack dump depth with (say)
|
||||
<tt>-jp=2</tt> may help to point out the main callers or callees of
|
||||
hotspots. But sample aggregation is still flat per unique stack dump.
|
||||
</p>
|
||||
<p>
|
||||
To get a two-level view (split view) of callers/callees, use
|
||||
<tt>-jp=s</tt> or <tt>-jp=-s</tt>. The percentages shown for the second
|
||||
level are relative to the first level.
|
||||
</p>
|
||||
<p>
|
||||
To see how much time is spent in each line relative to a function, use
|
||||
<tt>-jp=fl</tt>.
|
||||
</p>
|
||||
<p>
|
||||
To see how much time is spent in different VM states or
|
||||
<a href="#jit_zone">zones</a>, use <tt>-jp=v</tt> or <tt>-jp=z</tt>.
|
||||
</p>
|
||||
<p>
|
||||
Combinations of <tt>v/z</tt> with <tt>f/F/l</tt> produce two-level
|
||||
views, e.g. <tt>-jp=vf</tt> or <tt>-jp=fv</tt>. This shows the time
|
||||
spent in a VM state or zone vs. hotspots. This can be used to answer
|
||||
questions like "Which time consuming functions are only interpreted?" or
|
||||
"What's the garbage collector overhead for a specific function?".
|
||||
</p>
|
||||
<p>
|
||||
Multiple options can be combined — but not all combinations make
|
||||
sense, see above. E.g. <tt>-jp=3si4m1</tt> samples three stack levels
|
||||
deep in 4ms intervals and shows a split view of the CPU consuming
|
||||
functions and their callers with a 1% threshold.
|
||||
</p>
|
||||
<p>
|
||||
Source code annotations produced by <tt>-jp=a</tt> or <tt>-jp=A</tt> are
|
||||
always flat and at the line level. Obviously, the source code files need
|
||||
to be readable by the profiler script.
|
||||
</p>
|
||||
<p>
|
||||
The high-level profiler can also be started and stopped from Lua code with:
|
||||
</p>
|
||||
<pre class="code">
|
||||
require("jit.p").start(options, output)
|
||||
...
|
||||
require("jit.p").stop()
|
||||
</pre>
|
||||
|
||||
<h3 id="jit_zone"><tt>jit.zone</tt> — Zones</h3>
|
||||
<p>
|
||||
Zones can be used to provide information about different parts of an
|
||||
application to the high-level profiler. E.g. a game could make use of an
|
||||
<tt>"AI"</tt> zone, a <tt>"PHYS"</tt> zone, etc. Zones are hierarchical,
|
||||
organized as a stack.
|
||||
</p>
|
||||
<p>
|
||||
The <tt>jit.zone</tt> module needs to be loaded explicitly:
|
||||
</p>
|
||||
<pre class="code">
|
||||
local zone = require("jit.zone")
|
||||
</pre>
|
||||
<ul>
|
||||
<li><tt>zone("name")</tt> pushes a named zone to the zone stack.</li>
|
||||
<li><tt>zone()</tt> pops the current zone from the zone stack and
|
||||
returns its name.</li>
|
||||
<li><tt>zone:get()</tt> returns the current zone name or <tt>nil</tt>.</li>
|
||||
<li><tt>zone:flush()</tt> flushes the zone stack.</li>
|
||||
</ul>
|
||||
<p>
|
||||
To show the time spent in each zone use <tt>-jp=z</tt>. To show the time
|
||||
spent relative to hotspots use e.g. <tt>-jp=zf</tt> or <tt>-jp=fz</tt>.
|
||||
</p>
|
||||
|
||||
<h2 id="ll_lua_api">Low-level Lua API</h2>
|
||||
<p>
|
||||
The <tt>jit.profile</tt> module gives access to the low-level API of the
|
||||
profiler from Lua code. This module needs to be loaded explicitly:
|
||||
<pre class="code">
|
||||
local profile = require("jit.profile")
|
||||
</pre>
|
||||
<p>
|
||||
This module can be used to implement your own higher-level profiler.
|
||||
A typical profiling run starts the profiler, captures stack dumps in
|
||||
the profiler callback, adds them to a hash table to aggregate the number
|
||||
of samples, stops the profiler and then analyzes all of the captured
|
||||
stack dumps. Other parameters can be sampled in the profiler callback,
|
||||
too. But it's important not to spend too much time in the callback,
|
||||
since this may skew the statistics.
|
||||
</p>
|
||||
|
||||
<h3 id="profile_start"><tt>profile.start(mode, cb)</tt>
|
||||
— Start profiler</h3>
|
||||
<p>
|
||||
This function starts the profiler. The <tt>mode</tt> argument is a
|
||||
string holding options:
|
||||
</p>
|
||||
<ul>
|
||||
<li><tt>f</tt> — Profile with precision down to the function level.</li>
|
||||
<li><tt>l</tt> — Profile with precision down to the line level.</li>
|
||||
<li><tt>i<number></tt> — Sampling interval in milliseconds (default
|
||||
10ms).</br>
|
||||
Note: The actual sampling precision is OS-dependent.
|
||||
</li>
|
||||
</ul>
|
||||
<p>
|
||||
The <tt>cb</tt> argument is a callback function which is called with
|
||||
three arguments: <tt>(thread, samples, vmstate)</tt>. The callback is
|
||||
called on a separate coroutine, the <tt>thread</tt> argument is the
|
||||
state that holds the stack to sample for profiling. Note: do
|
||||
<em>not</em> modify the stack of that state or call functions on it.
|
||||
</p>
|
||||
<p>
|
||||
<tt>samples</tt> gives the number of accumulated samples since the last
|
||||
callback (usually 1).
|
||||
</p>
|
||||
<p>
|
||||
<tt>vmstate</tt> holds the VM state at the time the profiling timer
|
||||
triggered. This may or may not correspond to the state of the VM when
|
||||
the profiling callback is called. The state is either <tt>'N'</tt>
|
||||
native (compiled) code, <tt>'I'</tt> interpreted code, <tt>'C'</tt>
|
||||
C code, <tt>'G'</tt> the garbage collector, or <tt>'J'</tt> the JIT
|
||||
compiler.
|
||||
</p>
|
||||
|
||||
<h3 id="profile_stop"><tt>profile.stop()</tt>
|
||||
— Stop profiler</h3>
|
||||
<p>
|
||||
This function stops the profiler.
|
||||
</p>
|
||||
|
||||
<h3 id="profile_dump"><tt>dump = profile.dumpstack([thread,] fmt, depth)</tt>
|
||||
— Dump stack </h3>
|
||||
<p>
|
||||
This function allows taking stack dumps in an efficient manner. It
|
||||
returns a string with a stack dump for the <tt>thread</tt> (coroutine),
|
||||
formatted according to the <tt>fmt</tt> argument:
|
||||
</p>
|
||||
<ul>
|
||||
<li><tt>p</tt> — Preserve the full path for module names. Otherwise
|
||||
only the file name is used.</li>
|
||||
<li><tt>f</tt> — Dump the function name if it can be derived. Otherwise
|
||||
use module:line.</li>
|
||||
<li><tt>F</tt> — Ditto, but dump module:name.</li>
|
||||
<li><tt>l</tt> — Dump module:line.</li>
|
||||
<li><tt>Z</tt> — Zap the following characters for the last dumped
|
||||
frame.</li>
|
||||
<li>All other characters are added verbatim to the output string.</li>
|
||||
</ul>
|
||||
<p>
|
||||
The <tt>depth</tt> argument gives the number of frames to dump, starting
|
||||
at the topmost frame of the thread. A negative number dumps the frames in
|
||||
inverse order.
|
||||
</p>
|
||||
<p>
|
||||
The first example prints a list of the current module names and line
|
||||
numbers of up to 10 frames in separate lines. The second example prints
|
||||
semicolon-separated function names for all frames (up to 100) in inverse
|
||||
order:
|
||||
</p>
|
||||
<pre class="code">
|
||||
print(profile.dumpstack(thread, "l\n", 10))
|
||||
print(profile.dumpstack(thread, "lZ;", -100))
|
||||
</pre>
|
||||
|
||||
<h2 id="ll_c_api">Low-level C API</h2>
|
||||
<p>
|
||||
The profiler can be controlled directly from C code, e.g. for
|
||||
use by IDEs. The declarations are in <tt>"luajit.h"</tt> (see
|
||||
<a href="ext_c_api.html">Lua/C API</a> extensions).
|
||||
</p>
|
||||
|
||||
<h3 id="luaJIT_profile_start"><tt>luaJIT_profile_start(L, mode, cb, data)</tt>
|
||||
— Start profiler</h3>
|
||||
<p>
|
||||
This function starts the profiler. <a href="#profile_start">See
|
||||
above</a> for a description of the <tt>mode</tt> argument.
|
||||
</p>
|
||||
<p>
|
||||
The <tt>cb</tt> argument is a callback function with the following
|
||||
declaration:
|
||||
</p>
|
||||
<pre class="code">
|
||||
typedef void (*luaJIT_profile_callback)(void *data, lua_State *L,
|
||||
int samples, int vmstate);
|
||||
</pre>
|
||||
<p>
|
||||
<tt>data</tt> is available for use by the callback. <tt>L</tt> is the
|
||||
state that holds the stack to sample for profiling. Note: do
|
||||
<em>not</em> modify this stack or call functions on this stack —
|
||||
use a separate coroutine for this purpose. <a href="#profile_start">See
|
||||
above</a> for a description of <tt>samples</tt> and <tt>vmstate</tt>.
|
||||
</p>
|
||||
|
||||
<h3 id="luaJIT_profile_stop"><tt>luaJIT_profile_stop(L)</tt>
|
||||
— Stop profiler</h3>
|
||||
<p>
|
||||
This function stops the profiler.
|
||||
</p>
|
||||
|
||||
<h3 id="luaJIT_profile_dumpstack"><tt>p = luaJIT_profile_dumpstack(L, fmt, depth, len)</tt>
|
||||
— Dump stack </h3>
|
||||
<p>
|
||||
This function allows taking stack dumps in an efficient manner.
|
||||
<a href="#profile_dump">See above</a> for a description of <tt>fmt</tt>
|
||||
and <tt>depth</tt>.
|
||||
</p>
|
||||
<p>
|
||||
This function returns a <tt>const char *</tt> pointing to a
|
||||
private string buffer of the profiler. The <tt>int *len</tt>
|
||||
argument returns the length of the output string. The buffer is
|
||||
overwritten on the next call and deallocated when the profiler stops.
|
||||
You either need to consume the content immediately or copy it for later
|
||||
use.
|
||||
</p>
|
||||
<br class="flush">
|
||||
</div>
|
||||
<div id="foot">
|
||||
<hr class="hide">
|
||||
Copyright © 2005-2017 Mike Pall
|
||||
<span class="noprint">
|
||||
·
|
||||
<a href="contact.html">Contact</a>
|
||||
</span>
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
482
vendor/luajit/doc/extensions.html
vendored
Normal file
482
vendor/luajit/doc/extensions.html
vendored
Normal file
|
@ -0,0 +1,482 @@
|
|||
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
|
||||
<html>
|
||||
<head>
|
||||
<title>Extensions</title>
|
||||
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
|
||||
<meta name="Author" content="Mike Pall">
|
||||
<meta name="Copyright" content="Copyright (C) 2005-2017, Mike Pall">
|
||||
<meta name="Language" content="en">
|
||||
<link rel="stylesheet" type="text/css" href="bluequad.css" media="screen">
|
||||
<link rel="stylesheet" type="text/css" href="bluequad-print.css" media="print">
|
||||
<style type="text/css">
|
||||
table.exc {
|
||||
line-height: 1.2;
|
||||
}
|
||||
tr.exchead td {
|
||||
font-weight: bold;
|
||||
}
|
||||
td.excplatform {
|
||||
width: 48%;
|
||||
}
|
||||
td.exccompiler {
|
||||
width: 29%;
|
||||
}
|
||||
td.excinterop {
|
||||
width: 23%;
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<div id="site">
|
||||
<a href="http://luajit.org"><span>Lua<span id="logo">JIT</span></span></a>
|
||||
</div>
|
||||
<div id="head">
|
||||
<h1>Extensions</h1>
|
||||
</div>
|
||||
<div id="nav">
|
||||
<ul><li>
|
||||
<a href="luajit.html">LuaJIT</a>
|
||||
<ul><li>
|
||||
<a href="http://luajit.org/download.html">Download <span class="ext">»</span></a>
|
||||
</li><li>
|
||||
<a href="install.html">Installation</a>
|
||||
</li><li>
|
||||
<a href="running.html">Running</a>
|
||||
</li></ul>
|
||||
</li><li>
|
||||
<a class="current" href="extensions.html">Extensions</a>
|
||||
<ul><li>
|
||||
<a href="ext_ffi.html">FFI Library</a>
|
||||
<ul><li>
|
||||
<a href="ext_ffi_tutorial.html">FFI Tutorial</a>
|
||||
</li><li>
|
||||
<a href="ext_ffi_api.html">ffi.* API</a>
|
||||
</li><li>
|
||||
<a href="ext_ffi_semantics.html">FFI Semantics</a>
|
||||
</li></ul>
|
||||
</li><li>
|
||||
<a href="ext_jit.html">jit.* Library</a>
|
||||
</li><li>
|
||||
<a href="ext_c_api.html">Lua/C API</a>
|
||||
</li><li>
|
||||
<a href="ext_profiler.html">Profiler</a>
|
||||
</li></ul>
|
||||
</li><li>
|
||||
<a href="status.html">Status</a>
|
||||
<ul><li>
|
||||
<a href="changes.html">Changes</a>
|
||||
</li></ul>
|
||||
</li><li>
|
||||
<a href="faq.html">FAQ</a>
|
||||
</li><li>
|
||||
<a href="http://luajit.org/performance.html">Performance <span class="ext">»</span></a>
|
||||
</li><li>
|
||||
<a href="http://wiki.luajit.org/">Wiki <span class="ext">»</span></a>
|
||||
</li><li>
|
||||
<a href="http://luajit.org/list.html">Mailing List <span class="ext">»</span></a>
|
||||
</li></ul>
|
||||
</div>
|
||||
<div id="main">
|
||||
<p>
|
||||
LuaJIT is fully upwards-compatible with Lua 5.1. It supports all
|
||||
<a href="http://www.lua.org/manual/5.1/manual.html#5"><span class="ext">»</span> standard Lua
|
||||
library functions</a> and the full set of
|
||||
<a href="http://www.lua.org/manual/5.1/manual.html#3"><span class="ext">»</span> Lua/C API
|
||||
functions</a>.
|
||||
</p>
|
||||
<p>
|
||||
LuaJIT is also fully ABI-compatible to Lua 5.1 at the linker/dynamic
|
||||
loader level. This means you can compile a C module against the
|
||||
standard Lua headers and load the same shared library from either Lua
|
||||
or LuaJIT.
|
||||
</p>
|
||||
<p>
|
||||
LuaJIT extends the standard Lua VM with new functionality and adds
|
||||
several extension modules. Please note this page is only about
|
||||
<em>functional</em> enhancements and not about performance enhancements,
|
||||
such as the optimized VM, the faster interpreter or the JIT compiler.
|
||||
</p>
|
||||
|
||||
<h2 id="modules">Extensions Modules</h2>
|
||||
<p>
|
||||
LuaJIT comes with several built-in extension modules:
|
||||
</p>
|
||||
|
||||
<h3 id="bit"><tt>bit.*</tt> — Bitwise operations</h3>
|
||||
<p>
|
||||
LuaJIT supports all bitwise operations as defined by
|
||||
<a href="http://bitop.luajit.org"><span class="ext">»</span> Lua BitOp</a>:
|
||||
</p>
|
||||
<pre class="code">
|
||||
bit.tobit bit.tohex bit.bnot bit.band bit.bor bit.bxor
|
||||
bit.lshift bit.rshift bit.arshift bit.rol bit.ror bit.bswap
|
||||
</pre>
|
||||
<p>
|
||||
This module is a LuaJIT built-in — you don't need to download or
|
||||
install Lua BitOp. The Lua BitOp site has full documentation for all
|
||||
<a href="http://bitop.luajit.org/api.html"><span class="ext">»</span> Lua BitOp API functions</a>.
|
||||
The FFI adds support for
|
||||
<a href="ext_ffi_semantics.html#cdata_arith">64 bit bitwise operations</a>,
|
||||
using the same API functions.
|
||||
</p>
|
||||
<p>
|
||||
Please make sure to <tt>require</tt> the module before using any of
|
||||
its functions:
|
||||
</p>
|
||||
<pre class="code">
|
||||
local bit = require("bit")
|
||||
</pre>
|
||||
<p>
|
||||
An already installed Lua BitOp module is ignored by LuaJIT.
|
||||
This way you can use bit operations from both Lua and LuaJIT on a
|
||||
shared installation.
|
||||
</p>
|
||||
|
||||
<h3 id="ffi"><tt>ffi.*</tt> — FFI library</h3>
|
||||
<p>
|
||||
The <a href="ext_ffi.html">FFI library</a> allows calling external
|
||||
C functions and the use of C data structures from pure Lua
|
||||
code.
|
||||
</p>
|
||||
|
||||
<h3 id="jit"><tt>jit.*</tt> — JIT compiler control</h3>
|
||||
<p>
|
||||
The functions in this module
|
||||
<a href="ext_jit.html">control the behavior of the JIT compiler engine</a>.
|
||||
</p>
|
||||
|
||||
<h3 id="c_api">C API extensions</h3>
|
||||
<p>
|
||||
LuaJIT adds some
|
||||
<a href="ext_c_api.html">extra functions to the Lua/C API</a>.
|
||||
</p>
|
||||
|
||||
<h3 id="profiler">Profiler</h3>
|
||||
<p>
|
||||
LuaJIT has an <a href="ext_profiler.html">integrated profiler</a>.
|
||||
</p>
|
||||
|
||||
<h2 id="library">Enhanced Standard Library Functions</h2>
|
||||
|
||||
<h3 id="xpcall"><tt>xpcall(f, err [,args...])</tt> passes arguments</h3>
|
||||
<p>
|
||||
Unlike the standard implementation in Lua 5.1, <tt>xpcall()</tt>
|
||||
passes any arguments after the error function to the function
|
||||
which is called in a protected context.
|
||||
</p>
|
||||
|
||||
<h3 id="load"><tt>loadfile()</tt> etc. handle UTF-8 source code</h3>
|
||||
<p>
|
||||
Non-ASCII characters are handled transparently by the Lua source code parser.
|
||||
This allows the use of UTF-8 characters in identifiers and strings.
|
||||
A UTF-8 BOM is skipped at the start of the source code.
|
||||
</p>
|
||||
|
||||
<h3 id="tostring"><tt>tostring()</tt> etc. canonicalize NaN and ±Inf</h3>
|
||||
<p>
|
||||
All number-to-string conversions consistently convert non-finite numbers
|
||||
to the same strings on all platforms. NaN results in <tt>"nan"</tt>,
|
||||
positive infinity results in <tt>"inf"</tt> and negative infinity results
|
||||
in <tt>"-inf"</tt>.
|
||||
</p>
|
||||
|
||||
<h3 id="tonumber"><tt>tonumber()</tt> etc. use builtin string to number conversion</h3>
|
||||
<p>
|
||||
All string-to-number conversions consistently convert integer and
|
||||
floating-point inputs in decimal, hexadecimal and binary on all platforms.
|
||||
<tt>strtod()</tt> is <em>not</em> used anymore, which avoids numerous
|
||||
problems with poor C library implementations. The builtin conversion
|
||||
function provides full precision according to the IEEE-754 standard, it
|
||||
works independently of the current locale and it supports hex floating-point
|
||||
numbers (e.g. <tt>0x1.5p-3</tt>).
|
||||
</p>
|
||||
|
||||
<h3 id="string_dump"><tt>string.dump(f [,strip])</tt> generates portable bytecode</h3>
|
||||
<p>
|
||||
An extra argument has been added to <tt>string.dump()</tt>. If set to
|
||||
<tt>true</tt>, 'stripped' bytecode without debug information is
|
||||
generated. This speeds up later bytecode loading and reduces memory
|
||||
usage. See also the
|
||||
<a href="running.html#opt_b"><tt>-b</tt> command line option</a>.
|
||||
</p>
|
||||
<p>
|
||||
The generated bytecode is portable and can be loaded on any architecture
|
||||
that LuaJIT supports, independent of word size or endianess. However the
|
||||
bytecode compatibility versions must match. Bytecode stays compatible
|
||||
for dot releases (x.y.0 → x.y.1), but may change with major or
|
||||
minor releases (2.0 → 2.1) or between any beta release. Foreign
|
||||
bytecode (e.g. from Lua 5.1) is incompatible and cannot be loaded.
|
||||
</p>
|
||||
<p>
|
||||
Note: <tt>LJ_GC64</tt> mode requires a different frame layout, which implies
|
||||
a different, incompatible bytecode format for ports that use this mode (e.g.
|
||||
ARM64 or MIPS64) or when explicitly enabled for x64. This may be rectified
|
||||
in the future.
|
||||
</p>
|
||||
|
||||
<h3 id="table_new"><tt>table.new(narray, nhash)</tt> allocates a pre-sized table</h3>
|
||||
<p>
|
||||
An extra library function <tt>table.new()</tt> can be made available via
|
||||
<tt>require("table.new")</tt>. This creates a pre-sized table, just like
|
||||
the C API equivalent <tt>lua_createtable()</tt>. This is useful for big
|
||||
tables if the final table size is known and automatic table resizing is
|
||||
too expensive.
|
||||
</p>
|
||||
|
||||
<h3 id="table_clear"><tt>table.clear(tab)</tt> clears a table</h3>
|
||||
<p>
|
||||
An extra library function <tt>table.clear()</tt> can be made available
|
||||
via <tt>require("table.clear")</tt>. This clears all keys and values
|
||||
from a table, but preserves the allocated array/hash sizes. This is
|
||||
useful when a table, which is linked from multiple places, needs to be
|
||||
cleared and/or when recycling a table for use by the same context. This
|
||||
avoids managing backlinks, saves an allocation and the overhead of
|
||||
incremental array/hash part growth.
|
||||
</p>
|
||||
<p>
|
||||
Please note this function is meant for very specific situations. In most
|
||||
cases it's better to replace the (usually single) link with a new table
|
||||
and let the GC do its work.
|
||||
</p>
|
||||
|
||||
<h3 id="math_random">Enhanced PRNG for <tt>math.random()</tt></h3>
|
||||
<p>
|
||||
LuaJIT uses a Tausworthe PRNG with period 2^223 to implement
|
||||
<tt>math.random()</tt> and <tt>math.randomseed()</tt>. The quality of
|
||||
the PRNG results is much superior compared to the standard Lua
|
||||
implementation which uses the platform-specific ANSI rand().
|
||||
</p>
|
||||
<p>
|
||||
The PRNG generates the same sequences from the same seeds on all
|
||||
platforms and makes use of all bits in the seed argument.
|
||||
<tt>math.random()</tt> without arguments generates 52 pseudo-random bits
|
||||
for every call. The result is uniformly distributed between 0.0 and 1.0.
|
||||
It's correctly scaled up and rounded for <tt>math.random(n [,m])</tt> to
|
||||
preserve uniformity.
|
||||
</p>
|
||||
|
||||
<h3 id="io"><tt>io.*</tt> functions handle 64 bit file offsets</h3>
|
||||
<p>
|
||||
The file I/O functions in the standard <tt>io.*</tt> library handle
|
||||
64 bit file offsets. In particular this means it's possible
|
||||
to open files larger than 2 Gigabytes and to reposition or obtain
|
||||
the current file position for offsets beyond 2 GB
|
||||
(<tt>fp:seek()</tt> method).
|
||||
</p>
|
||||
|
||||
<h3 id="debug_meta"><tt>debug.*</tt> functions identify metamethods</h3>
|
||||
<p>
|
||||
<tt>debug.getinfo()</tt> and <tt>lua_getinfo()</tt> also return information
|
||||
about invoked metamethods. The <tt>namewhat</tt> field is set to
|
||||
<tt>"metamethod"</tt> and the <tt>name</tt> field has the name of
|
||||
the corresponding metamethod (e.g. <tt>"__index"</tt>).
|
||||
</p>
|
||||
|
||||
<h2 id="resumable">Fully Resumable VM</h2>
|
||||
<p>
|
||||
The LuaJIT VM is fully resumable. This means you can yield from a
|
||||
coroutine even across contexts, where this would not possible with
|
||||
the standard Lua 5.1 VM: e.g. you can yield across <tt>pcall()</tt>
|
||||
and <tt>xpcall()</tt>, across iterators and across metamethods.
|
||||
</p>
|
||||
|
||||
<h2 id="lua52">Extensions from Lua 5.2</h2>
|
||||
<p>
|
||||
LuaJIT supports some language and library extensions from Lua 5.2.
|
||||
Features that are unlikely to break existing code are unconditionally
|
||||
enabled:
|
||||
</p>
|
||||
<ul>
|
||||
<li><tt>goto</tt> and <tt>::labels::</tt>.</li>
|
||||
<li>Hex escapes <tt>'\x3F'</tt> and <tt>'\*'</tt> escape in strings.</li>
|
||||
<li><tt>load(string|reader [, chunkname [,mode [,env]]])</tt>.</li>
|
||||
<li><tt>loadstring()</tt> is an alias for <tt>load()</tt>.</li>
|
||||
<li><tt>loadfile(filename [,mode [,env]])</tt>.</li>
|
||||
<li><tt>math.log(x [,base])</tt>.</li>
|
||||
<li><tt>string.rep(s, n [,sep])</tt>.</li>
|
||||
<li><tt>string.format()</tt>: <tt>%q</tt> reversible.
|
||||
<tt>%s</tt> checks <tt>__tostring</tt>.
|
||||
<tt>%a</tt> and <tt>"%A</tt> added.</li>
|
||||
<li>String matching pattern <tt>%g</tt> added.</li>
|
||||
<li><tt>io.read("*L")</tt>.</li>
|
||||
<li><tt>io.lines()</tt> and <tt>file:lines()</tt> process
|
||||
<tt>io.read()</tt> options.</li>
|
||||
<li><tt>os.exit(status|true|false [,close])</tt>.</li>
|
||||
<li><tt>package.searchpath(name, path [, sep [, rep]])</tt>.</li>
|
||||
<li><tt>package.loadlib(name, "*")</tt>.</li>
|
||||
<li><tt>debug.getinfo()</tt> returns <tt>nparams</tt> and <tt>isvararg</tt>
|
||||
for option <tt>"u"</tt>.</li>
|
||||
<li><tt>debug.getlocal()</tt> accepts function instead of level.</li>
|
||||
<li><tt>debug.getlocal()</tt> and <tt>debug.setlocal()</tt> accept negative
|
||||
indexes for varargs.</li>
|
||||
<li><tt>debug.getupvalue()</tt> and <tt>debug.setupvalue()</tt> handle
|
||||
C functions.</li>
|
||||
<li><tt>debug.upvalueid()</tt> and <tt>debug.upvaluejoin()</tt>.</li>
|
||||
<li>Lua/C API extensions:
|
||||
<tt>lua_version()</tt>
|
||||
<tt>lua_upvalueid()</tt>
|
||||
<tt>lua_upvaluejoin()</tt>
|
||||
<tt>lua_loadx()</tt>
|
||||
<tt>lua_copy()</tt>
|
||||
<tt>lua_tonumberx()</tt>
|
||||
<tt>lua_tointegerx()</tt>
|
||||
<tt>luaL_fileresult()</tt>
|
||||
<tt>luaL_execresult()</tt>
|
||||
<tt>luaL_loadfilex()</tt>
|
||||
<tt>luaL_loadbufferx()</tt>
|
||||
<tt>luaL_traceback()</tt>
|
||||
<tt>luaL_setfuncs()</tt>
|
||||
<tt>luaL_pushmodule()</tt>
|
||||
<tt>luaL_newlibtable()</tt>
|
||||
<tt>luaL_newlib()</tt>
|
||||
<tt>luaL_testudata()</tt>
|
||||
<tt>luaL_setmetatable()</tt>
|
||||
</li>
|
||||
<li>Command line option <tt>-E</tt>.</li>
|
||||
<li>Command line checks <tt>__tostring</tt> for errors.</li>
|
||||
</ul>
|
||||
<p>
|
||||
Other features are only enabled, if LuaJIT is built with
|
||||
<tt>-DLUAJIT_ENABLE_LUA52COMPAT</tt>:
|
||||
</p>
|
||||
<ul>
|
||||
<li><tt>goto</tt> is a keyword and not a valid variable name anymore.</li>
|
||||
<li><tt>break</tt> can be placed anywhere. Empty statements (<tt>;;</tt>)
|
||||
are allowed.</li>
|
||||
<li><tt>__lt</tt>, <tt>__le</tt> are invoked for mixed types.</li>
|
||||
<li><tt>__len</tt> for tables. <tt>rawlen()</tt> library function.</li>
|
||||
<li><tt>pairs()</tt> and <tt>ipairs()</tt> check for <tt>__pairs</tt> and
|
||||
<tt>__ipairs</tt>.</li>
|
||||
<li><tt>coroutine.running()</tt> returns two results.</li>
|
||||
<li><tt>table.pack()</tt> and <tt>table.unpack()</tt>
|
||||
(same as <tt>unpack()</tt>).</li>
|
||||
<li><tt>io.write()</tt> and <tt>file:write()</tt> return file handle
|
||||
instead of <tt>true</tt>.</li>
|
||||
<li><tt>os.execute()</tt> and <tt>pipe:close()</tt> return detailed
|
||||
exit status.</li>
|
||||
<li><tt>debug.setmetatable()</tt> returns object.</li>
|
||||
<li><tt>debug.getuservalue()</tt> and <tt>debug.setuservalue()</tt>.</li>
|
||||
<li>Remove <tt>math.mod()</tt>, <tt>string.gfind()</tt>.</li>
|
||||
<li><tt>package.searchers</tt>.</li>
|
||||
<li><tt>module()</tt> returns the module table.</li>
|
||||
</ul>
|
||||
<p>
|
||||
Note: this provides only partial compatibility with Lua 5.2 at the
|
||||
language and Lua library level. LuaJIT is API+ABI-compatible with
|
||||
Lua 5.1, which prevents implementing features that would otherwise
|
||||
break the Lua/C API and ABI (e.g. <tt>_ENV</tt>).
|
||||
</p>
|
||||
|
||||
<h2 id="lua53">Extensions from Lua 5.3</h2>
|
||||
<p>
|
||||
LuaJIT supports some extensions from Lua 5.3:
|
||||
<ul>
|
||||
<li>Unicode escape <tt>'\u{XX...}'</tt> embeds the UTF-8 encoding in string literals.</li>
|
||||
<li>The argument table <tt>arg</tt> can be read (and modified) by <tt>LUA_INIT</tt> and <tt>-e</tt> chunks.</li>
|
||||
<li><tt>io.read()</tt> and <tt>file:read()</tt> accept formats with or without a leading <tt>*</tt>.</li>
|
||||
<li><tt>table.move(a1, f, e, t [,a2])</tt>.</li>
|
||||
<li><tt>coroutine.isyieldable()</tt>.</li>
|
||||
<li>Lua/C API extensions:
|
||||
<tt>lua_isyieldable()</tt>
|
||||
</li>
|
||||
</ul>
|
||||
|
||||
<h2 id="exceptions">C++ Exception Interoperability</h2>
|
||||
<p>
|
||||
LuaJIT has built-in support for interoperating with C++ exceptions.
|
||||
The available range of features depends on the target platform and
|
||||
the toolchain used to compile LuaJIT:
|
||||
</p>
|
||||
<table class="exc">
|
||||
<tr class="exchead">
|
||||
<td class="excplatform">Platform</td>
|
||||
<td class="exccompiler">Compiler</td>
|
||||
<td class="excinterop">Interoperability</td>
|
||||
</tr>
|
||||
<tr class="odd separate">
|
||||
<td class="excplatform">POSIX/x64, DWARF2 unwinding</td>
|
||||
<td class="exccompiler">GCC 4.3+, Clang</td>
|
||||
<td class="excinterop"><b style="color: #00a000;">Full</b></td>
|
||||
</tr>
|
||||
<tr class="even">
|
||||
<td class="excplatform">ARM <tt>-DLUAJIT_UNWIND_EXTERNAL</tt></td>
|
||||
<td class="exccompiler">GCC, Clang</td>
|
||||
<td class="excinterop"><b style="color: #00a000;">Full</b></td>
|
||||
</tr>
|
||||
<tr class="odd">
|
||||
<td class="excplatform">Other platforms, DWARF2 unwinding</td>
|
||||
<td class="exccompiler">GCC, Clang</td>
|
||||
<td class="excinterop"><b style="color: #c06000;">Limited</b></td>
|
||||
</tr>
|
||||
<tr class="even">
|
||||
<td class="excplatform">Windows/x64</td>
|
||||
<td class="exccompiler">MSVC or WinSDK</td>
|
||||
<td class="excinterop"><b style="color: #00a000;">Full</b></td>
|
||||
</tr>
|
||||
<tr class="odd">
|
||||
<td class="excplatform">Windows/x86</td>
|
||||
<td class="exccompiler">Any</td>
|
||||
<td class="excinterop"><b style="color: #00a000;">Full</b></td>
|
||||
</tr>
|
||||
<tr class="even">
|
||||
<td class="excplatform">Other platforms</td>
|
||||
<td class="exccompiler">Other compilers</td>
|
||||
<td class="excinterop"><b style="color: #a00000;">No</b></td>
|
||||
</tr>
|
||||
</table>
|
||||
<p>
|
||||
<b style="color: #00a000;">Full interoperability</b> means:
|
||||
</p>
|
||||
<ul>
|
||||
<li>C++ exceptions can be caught on the Lua side with <tt>pcall()</tt>,
|
||||
<tt>lua_pcall()</tt> etc.</li>
|
||||
<li>C++ exceptions will be converted to the generic Lua error
|
||||
<tt>"C++ exception"</tt>, unless you use the
|
||||
<a href="ext_c_api.html#mode_wrapcfunc">C call wrapper</a> feature.</li>
|
||||
<li>It's safe to throw C++ exceptions across non-protected Lua frames
|
||||
on the C stack. The contents of the C++ exception object
|
||||
pass through unmodified.</li>
|
||||
<li>Lua errors can be caught on the C++ side with <tt>catch(...)</tt>.
|
||||
The corresponding Lua error message can be retrieved from the Lua stack.</li>
|
||||
<li>Throwing Lua errors across C++ frames is safe. C++ destructors
|
||||
will be called.</li>
|
||||
</ul>
|
||||
<p>
|
||||
<b style="color: #c06000;">Limited interoperability</b> means:
|
||||
</p>
|
||||
<ul>
|
||||
<li>C++ exceptions can be caught on the Lua side with <tt>pcall()</tt>,
|
||||
<tt>lua_pcall()</tt> etc.</li>
|
||||
<li>C++ exceptions will be converted to the generic Lua error
|
||||
<tt>"C++ exception"</tt>, unless you use the
|
||||
<a href="ext_c_api.html#mode_wrapcfunc">C call wrapper</a> feature.</li>
|
||||
<li>C++ exceptions will be caught by non-protected Lua frames and
|
||||
are rethrown as a generic Lua error. The C++ exception object will
|
||||
be destroyed.</li>
|
||||
<li>Lua errors <b>cannot</b> be caught on the C++ side.</li>
|
||||
<li>Throwing Lua errors across C++ frames will <b>not</b> call
|
||||
C++ destructors.</li>
|
||||
</ul>
|
||||
|
||||
<p>
|
||||
<b style="color: #a00000;">No interoperability</b> means:
|
||||
</p>
|
||||
<ul>
|
||||
<li>It's <b>not</b> safe to throw C++ exceptions across Lua frames.</li>
|
||||
<li>C++ exceptions <b>cannot</b> be caught on the Lua side.</li>
|
||||
<li>Lua errors <b>cannot</b> be caught on the C++ side.</li>
|
||||
<li>Throwing Lua errors across C++ frames will <b>not</b> call
|
||||
C++ destructors.</li>
|
||||
</ul>
|
||||
<br class="flush">
|
||||
</div>
|
||||
<div id="foot">
|
||||
<hr class="hide">
|
||||
Copyright © 2005-2017 Mike Pall
|
||||
<span class="noprint">
|
||||
·
|
||||
<a href="contact.html">Contact</a>
|
||||
</span>
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
186
vendor/luajit/doc/faq.html
vendored
Normal file
186
vendor/luajit/doc/faq.html
vendored
Normal file
|
@ -0,0 +1,186 @@
|
|||
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
|
||||
<html>
|
||||
<head>
|
||||
<title>Frequently Asked Questions (FAQ)</title>
|
||||
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
|
||||
<meta name="Author" content="Mike Pall">
|
||||
<meta name="Copyright" content="Copyright (C) 2005-2017, Mike Pall">
|
||||
<meta name="Language" content="en">
|
||||
<link rel="stylesheet" type="text/css" href="bluequad.css" media="screen">
|
||||
<link rel="stylesheet" type="text/css" href="bluequad-print.css" media="print">
|
||||
<style type="text/css">
|
||||
dd { margin-left: 1.5em; }
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<div id="site">
|
||||
<a href="http://luajit.org"><span>Lua<span id="logo">JIT</span></span></a>
|
||||
</div>
|
||||
<div id="head">
|
||||
<h1>Frequently Asked Questions (FAQ)</h1>
|
||||
</div>
|
||||
<div id="nav">
|
||||
<ul><li>
|
||||
<a href="luajit.html">LuaJIT</a>
|
||||
<ul><li>
|
||||
<a href="http://luajit.org/download.html">Download <span class="ext">»</span></a>
|
||||
</li><li>
|
||||
<a href="install.html">Installation</a>
|
||||
</li><li>
|
||||
<a href="running.html">Running</a>
|
||||
</li></ul>
|
||||
</li><li>
|
||||
<a href="extensions.html">Extensions</a>
|
||||
<ul><li>
|
||||
<a href="ext_ffi.html">FFI Library</a>
|
||||
<ul><li>
|
||||
<a href="ext_ffi_tutorial.html">FFI Tutorial</a>
|
||||
</li><li>
|
||||
<a href="ext_ffi_api.html">ffi.* API</a>
|
||||
</li><li>
|
||||
<a href="ext_ffi_semantics.html">FFI Semantics</a>
|
||||
</li></ul>
|
||||
</li><li>
|
||||
<a href="ext_jit.html">jit.* Library</a>
|
||||
</li><li>
|
||||
<a href="ext_c_api.html">Lua/C API</a>
|
||||
</li><li>
|
||||
<a href="ext_profiler.html">Profiler</a>
|
||||
</li></ul>
|
||||
</li><li>
|
||||
<a href="status.html">Status</a>
|
||||
<ul><li>
|
||||
<a href="changes.html">Changes</a>
|
||||
</li></ul>
|
||||
</li><li>
|
||||
<a class="current" href="faq.html">FAQ</a>
|
||||
</li><li>
|
||||
<a href="http://luajit.org/performance.html">Performance <span class="ext">»</span></a>
|
||||
</li><li>
|
||||
<a href="http://wiki.luajit.org/">Wiki <span class="ext">»</span></a>
|
||||
</li><li>
|
||||
<a href="http://luajit.org/list.html">Mailing List <span class="ext">»</span></a>
|
||||
</li></ul>
|
||||
</div>
|
||||
<div id="main">
|
||||
<dl>
|
||||
<dt>Q: Where can I learn more about LuaJIT and Lua?</dt>
|
||||
<dd>
|
||||
<ul style="padding: 0;">
|
||||
<li>The <a href="http://luajit.org/list.html"><span class="ext">»</span> LuaJIT mailing list</a> focuses on topics
|
||||
related to LuaJIT.</li>
|
||||
<li>The <a href="http://wiki.luajit.org/"><span class="ext">»</span> LuaJIT wiki</a> gathers community
|
||||
resources about LuaJIT.</li>
|
||||
<li>News about Lua itself can be found at the
|
||||
<a href="http://www.lua.org/lua-l.html"><span class="ext">»</span> Lua mailing list</a>.
|
||||
The mailing list archives are worth checking out for older postings
|
||||
about LuaJIT.</li>
|
||||
<li>The <a href="http://lua.org"><span class="ext">»</span> main Lua.org site</a> has complete
|
||||
<a href="http://www.lua.org/docs.html"><span class="ext">»</span> documentation</a> of the language
|
||||
and links to books and papers about Lua.</li>
|
||||
<li>The community-managed <a href="http://lua-users.org/wiki/"><span class="ext">»</span> Lua Wiki</a>
|
||||
has information about diverse topics.</li>
|
||||
</ul>
|
||||
</dl>
|
||||
|
||||
<dl>
|
||||
<dt>Q: Where can I learn more about the compiler technology used by LuaJIT?</dt>
|
||||
<dd>
|
||||
I'm planning to write more documentation about the internals of LuaJIT.
|
||||
In the meantime, please use the following Google Scholar searches
|
||||
to find relevant papers:<br>
|
||||
Search for: <a href="http://scholar.google.com/scholar?q=Trace+Compiler"><span class="ext">»</span> Trace Compiler</a><br>
|
||||
Search for: <a href="http://scholar.google.com/scholar?q=JIT+Compiler"><span class="ext">»</span> JIT Compiler</a><br>
|
||||
Search for: <a href="http://scholar.google.com/scholar?q=Dynamic+Language+Optimizations"><span class="ext">»</span> Dynamic Language Optimizations</a><br>
|
||||
Search for: <a href="http://scholar.google.com/scholar?q=SSA+Form"><span class="ext">»</span> SSA Form</a><br>
|
||||
Search for: <a href="http://scholar.google.com/scholar?q=Linear+Scan+Register+Allocation"><span class="ext">»</span> Linear Scan Register Allocation</a><br>
|
||||
Here is a list of the <a href="http://article.gmane.org/gmane.comp.lang.lua.general/58908"><span class="ext">»</span> innovative features in LuaJIT</a>.<br>
|
||||
And, you know, reading the source is of course the only way to enlightenment. :-)
|
||||
</dd>
|
||||
</dl>
|
||||
|
||||
<dl>
|
||||
<dt>Q: Why do I get this error: "attempt to index global 'arg' (a nil value)"?<br>
|
||||
Q: My vararg functions fail after switching to LuaJIT!</dt>
|
||||
<dd>LuaJIT is compatible to the Lua 5.1 language standard. It doesn't
|
||||
support the implicit <tt>arg</tt> parameter for old-style vararg
|
||||
functions from Lua 5.0.<br>Please convert your code to the
|
||||
<a href="http://www.lua.org/manual/5.1/manual.html#2.5.9"><span class="ext">»</span> Lua 5.1
|
||||
vararg syntax</a>.</dd>
|
||||
</dl>
|
||||
|
||||
<dl>
|
||||
<dt>Q: Why do I get this error: "bad FPU precision"?<br>
|
||||
<dt>Q: I get weird behavior after initializing Direct3D.<br>
|
||||
<dt>Q: Some FPU operations crash after I load a Delphi DLL.<br>
|
||||
</dt>
|
||||
<dd>
|
||||
|
||||
DirectX/Direct3D (up to version 9) sets the x87 FPU to single-precision
|
||||
mode by default. This violates the Windows ABI and interferes with the
|
||||
operation of many programs — LuaJIT is affected, too. Please make
|
||||
sure you always use the <tt>D3DCREATE_FPU_PRESERVE</tt> flag when
|
||||
initializing Direct3D.<br>
|
||||
|
||||
Direct3D version 10 or higher do not show this behavior anymore.
|
||||
Consider testing your application with older versions, too.<br>
|
||||
|
||||
Similarly, the Borland/Delphi runtime modifies the FPU control word and
|
||||
enables FP exceptions. Of course this violates the Windows ABI, too.
|
||||
Please check the Delphi docs for the Set8087CW method.
|
||||
|
||||
</dl>
|
||||
|
||||
<dl>
|
||||
<dt>Q: Sometimes Ctrl-C fails to stop my Lua program. Why?</dt>
|
||||
<dd>The interrupt signal handler sets a Lua debug hook. But this is
|
||||
currently ignored by compiled code (this will eventually be fixed). If
|
||||
your program is running in a tight loop and never falls back to the
|
||||
interpreter, the debug hook never runs and can't throw the
|
||||
"interrupted!" error.<br> In the meantime you have to press Ctrl-C
|
||||
twice to get stop your program. That's similar to when it's stuck
|
||||
running inside a C function under the Lua interpreter.</dd>
|
||||
</dl>
|
||||
|
||||
<dl>
|
||||
<dt>Q: Why doesn't my favorite power-patch for Lua apply against LuaJIT?</dt>
|
||||
<dd>Because it's a completely redesigned VM and has very little code
|
||||
in common with Lua anymore. Also, if the patch introduces changes to
|
||||
the Lua semantics, these would need to be reflected everywhere in the
|
||||
VM, from the interpreter up to all stages of the compiler.<br> Please
|
||||
use only standard Lua language constructs. For many common needs you
|
||||
can use source transformations or use wrapper or proxy functions.
|
||||
The compiler will happily optimize away such indirections.</dd>
|
||||
</dl>
|
||||
|
||||
<dl>
|
||||
<dt>Q: Lua runs everywhere. Why doesn't LuaJIT support my CPU?</dt>
|
||||
<dd>Because it's a compiler — it needs to generate native
|
||||
machine code. This means the code generator must be ported to each
|
||||
architecture. And the fast interpreter is written in assembler and
|
||||
must be ported, too. This is quite an undertaking.<br>
|
||||
The <a href="install.html">install documentation</a> shows the supported
|
||||
architectures. Other architectures will follow based on sufficient user
|
||||
demand and/or sponsoring.</dd>
|
||||
</dl>
|
||||
|
||||
<dl>
|
||||
<dt>Q: When will feature X be added? When will the next version be released?</dt>
|
||||
<dd>When it's ready.<br>
|
||||
C'mon, it's open source — I'm doing it on my own time and you're
|
||||
getting it for free. You can either contribute a patch or sponsor
|
||||
the development of certain features, if they are important to you.
|
||||
</dd>
|
||||
</dl>
|
||||
<br class="flush">
|
||||
</div>
|
||||
<div id="foot">
|
||||
<hr class="hide">
|
||||
Copyright © 2005-2017 Mike Pall
|
||||
<span class="noprint">
|
||||
·
|
||||
<a href="contact.html">Contact</a>
|
||||
</span>
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
BIN
vendor/luajit/doc/img/contact.png
vendored
Normal file
BIN
vendor/luajit/doc/img/contact.png
vendored
Normal file
Binary file not shown.
After Width: | Height: | Size: 1.3 KiB |
692
vendor/luajit/doc/install.html
vendored
Normal file
692
vendor/luajit/doc/install.html
vendored
Normal file
|
@ -0,0 +1,692 @@
|
|||
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
|
||||
<html>
|
||||
<head>
|
||||
<title>Installation</title>
|
||||
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
|
||||
<meta name="Author" content="Mike Pall">
|
||||
<meta name="Copyright" content="Copyright (C) 2005-2017, Mike Pall">
|
||||
<meta name="Language" content="en">
|
||||
<link rel="stylesheet" type="text/css" href="bluequad.css" media="screen">
|
||||
<link rel="stylesheet" type="text/css" href="bluequad-print.css" media="print">
|
||||
<style type="text/css">
|
||||
table.compat {
|
||||
line-height: 1.2;
|
||||
font-size: 80%;
|
||||
}
|
||||
table.compat td {
|
||||
border: 1px solid #bfcfff;
|
||||
height: 2.5em;
|
||||
}
|
||||
table.compat tr.compathead td {
|
||||
font-weight: bold;
|
||||
border-bottom: 2px solid #bfcfff;
|
||||
}
|
||||
tr.compathead td.compatos {
|
||||
vertical-align: top;
|
||||
}
|
||||
table.compat td.compatcpu {
|
||||
width: 18%;
|
||||
border-right: 2px solid #bfcfff;
|
||||
}
|
||||
td.compatos {
|
||||
width: 21%;
|
||||
vertical-align: middle;
|
||||
}
|
||||
td.compatno {
|
||||
background-color: #d0d0d0;
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<div id="site">
|
||||
<a href="http://luajit.org"><span>Lua<span id="logo">JIT</span></span></a>
|
||||
</div>
|
||||
<div id="head">
|
||||
<h1>Installation</h1>
|
||||
</div>
|
||||
<div id="nav">
|
||||
<ul><li>
|
||||
<a href="luajit.html">LuaJIT</a>
|
||||
<ul><li>
|
||||
<a href="http://luajit.org/download.html">Download <span class="ext">»</span></a>
|
||||
</li><li>
|
||||
<a class="current" href="install.html">Installation</a>
|
||||
</li><li>
|
||||
<a href="running.html">Running</a>
|
||||
</li></ul>
|
||||
</li><li>
|
||||
<a href="extensions.html">Extensions</a>
|
||||
<ul><li>
|
||||
<a href="ext_ffi.html">FFI Library</a>
|
||||
<ul><li>
|
||||
<a href="ext_ffi_tutorial.html">FFI Tutorial</a>
|
||||
</li><li>
|
||||
<a href="ext_ffi_api.html">ffi.* API</a>
|
||||
</li><li>
|
||||
<a href="ext_ffi_semantics.html">FFI Semantics</a>
|
||||
</li></ul>
|
||||
</li><li>
|
||||
<a href="ext_jit.html">jit.* Library</a>
|
||||
</li><li>
|
||||
<a href="ext_c_api.html">Lua/C API</a>
|
||||
</li><li>
|
||||
<a href="ext_profiler.html">Profiler</a>
|
||||
</li></ul>
|
||||
</li><li>
|
||||
<a href="status.html">Status</a>
|
||||
<ul><li>
|
||||
<a href="changes.html">Changes</a>
|
||||
</li></ul>
|
||||
</li><li>
|
||||
<a href="faq.html">FAQ</a>
|
||||
</li><li>
|
||||
<a href="http://luajit.org/performance.html">Performance <span class="ext">»</span></a>
|
||||
</li><li>
|
||||
<a href="http://wiki.luajit.org/">Wiki <span class="ext">»</span></a>
|
||||
</li><li>
|
||||
<a href="http://luajit.org/list.html">Mailing List <span class="ext">»</span></a>
|
||||
</li></ul>
|
||||
</div>
|
||||
<div id="main">
|
||||
<p>
|
||||
LuaJIT is only distributed as a source package. This page explains
|
||||
how to build and install LuaJIT with different operating systems
|
||||
and C compilers.
|
||||
</p>
|
||||
<p>
|
||||
For the impatient (on POSIX systems):
|
||||
</p>
|
||||
<pre class="code">
|
||||
make && sudo make install
|
||||
</pre>
|
||||
<p>
|
||||
LuaJIT currently builds out-of-the box on most systems.
|
||||
Here's the compatibility matrix for the supported combinations of
|
||||
operating systems, CPUs and compilers:
|
||||
</p>
|
||||
<table class="compat">
|
||||
<tr class="compathead">
|
||||
<td class="compatcpu">CPU / OS</td>
|
||||
<td class="compatos"><a href="#posix">Linux</a> or<br><a href="#android">Android</a></td>
|
||||
<td class="compatos"><a href="#posix">*BSD, Other</a></td>
|
||||
<td class="compatos"><a href="#posix">OSX 10.4+</a> or<br><a href="#ios">iOS 3.0+</a></td>
|
||||
<td class="compatos"><a href="#windows">Windows<br>XP/Vista/7</a></td>
|
||||
</tr>
|
||||
<tr class="odd separate">
|
||||
<td class="compatcpu">x86 (32 bit)</td>
|
||||
<td class="compatos">GCC 4.2+</td>
|
||||
<td class="compatos">GCC 4.2+</td>
|
||||
<td class="compatos">XCode 5.0+<br>Clang</td>
|
||||
<td class="compatos">MSVC, MSVC/EE<br>WinSDK<br>MinGW, Cygwin</td>
|
||||
</tr>
|
||||
<tr class="even">
|
||||
<td class="compatcpu">x64 (64 bit)</td>
|
||||
<td class="compatos">GCC 4.2+</td>
|
||||
<td class="compatos">GCC 4.2+<br>ORBIS (<a href="#ps4">PS4</a>)</td>
|
||||
<td class="compatos">XCode 5.0+<br>Clang</td>
|
||||
<td class="compatos">MSVC + SDK v7.0<br>WinSDK v7.0<br>Durango (<a href="#xboxone">Xbox One</a>)</td>
|
||||
</tr>
|
||||
<tr class="odd">
|
||||
<td class="compatcpu"><a href="#cross2">ARMv5+<br>ARM9E+</a></td>
|
||||
<td class="compatos">GCC 4.2+</td>
|
||||
<td class="compatos">GCC 4.2+<br>PSP2 (<a href="#psvita">PS VITA</a>)</td>
|
||||
<td class="compatos">XCode 5.0+<br>Clang</td>
|
||||
<td class="compatos compatno"> </td>
|
||||
</tr>
|
||||
<tr class="even">
|
||||
<td class="compatcpu"><a href="#cross2">ARM64</a></td>
|
||||
<td class="compatos">GCC 4.8+</td>
|
||||
<td class="compatos compatno"> </td>
|
||||
<td class="compatos">XCode 6.0+<br>Clang 3.5+</td>
|
||||
<td class="compatos compatno"> </td>
|
||||
</tr>
|
||||
<tr class="odd">
|
||||
<td class="compatcpu"><a href="#cross2">PPC</a></td>
|
||||
<td class="compatos">GCC 4.3+</td>
|
||||
<td class="compatos">GCC 4.3+<br>GCC 4.1 (<a href="#ps3">PS3</a>)</td>
|
||||
<td class="compatos compatno"> </td>
|
||||
<td class="compatos">XEDK (<a href="#xbox360">Xbox 360</a>)</td>
|
||||
</tr>
|
||||
<tr class="even">
|
||||
<td class="compatcpu"><a href="#cross2">MIPS32<br>MIPS64</a></td>
|
||||
<td class="compatos">GCC 4.3+</td>
|
||||
<td class="compatos">GCC 4.3+</td>
|
||||
<td class="compatos compatno"> </td>
|
||||
<td class="compatos compatno"> </td>
|
||||
</tr>
|
||||
</table>
|
||||
|
||||
<h2>Configuring LuaJIT</h2>
|
||||
<p>
|
||||
The standard configuration should work fine for most installations.
|
||||
Usually there is no need to tweak the settings. The following files
|
||||
hold all user-configurable settings:
|
||||
</p>
|
||||
<ul>
|
||||
<li><tt>src/luaconf.h</tt> sets some configuration variables.</li>
|
||||
<li><tt>Makefile</tt> has settings for <b>installing</b> LuaJIT (POSIX
|
||||
only).</li>
|
||||
<li><tt>src/Makefile</tt> has settings for <b>compiling</b> LuaJIT
|
||||
under POSIX, MinGW or Cygwin.</li>
|
||||
<li><tt>src/msvcbuild.bat</tt> has settings for compiling LuaJIT with
|
||||
MSVC or WinSDK.</li>
|
||||
</ul>
|
||||
<p>
|
||||
Please read the instructions given in these files, before changing
|
||||
any settings.
|
||||
</p>
|
||||
<p>
|
||||
LuaJIT on x64 currently uses 32 bit GC objects by default.
|
||||
<tt>LJ_GC64</tt> mode may be explicitly enabled:
|
||||
add <tt>XCFLAGS=-DLUAJIT_ENABLE_GC64</tt> to the make command or run
|
||||
<tt>msvcbuild gc64</tt> for MSVC/WinSDK. Please check the note
|
||||
about the <a href="extensions.html#string_dump">bytecode format</a>
|
||||
differences, too.
|
||||
</p>
|
||||
|
||||
<h2 id="posix">POSIX Systems (Linux, OSX, *BSD etc.)</h2>
|
||||
<h3>Prerequisites</h3>
|
||||
<p>
|
||||
Depending on your distribution, you may need to install a package for
|
||||
GCC, the development headers and/or a complete SDK. E.g. on a current
|
||||
Debian/Ubuntu, install <tt>libc6-dev</tt> with the package manager.
|
||||
</p>
|
||||
<p>
|
||||
Download the current source package of LuaJIT (pick the .tar.gz),
|
||||
if you haven't already done so. Move it to a directory of your choice,
|
||||
open a terminal window and change to this directory. Now unpack the archive
|
||||
and change to the newly created directory:
|
||||
</p>
|
||||
<pre class="code">
|
||||
tar zxf LuaJIT-2.0.5.tar.gz
|
||||
cd LuaJIT-2.0.5</pre>
|
||||
<h3>Building LuaJIT</h3>
|
||||
<p>
|
||||
The supplied Makefiles try to auto-detect the settings needed for your
|
||||
operating system and your compiler. They need to be run with GNU Make,
|
||||
which is probably the default on your system, anyway. Simply run:
|
||||
</p>
|
||||
<pre class="code">
|
||||
make
|
||||
</pre>
|
||||
<p>
|
||||
This always builds a native binary, depending on the host OS
|
||||
you're running this command on. Check the section on
|
||||
<a href="#cross">cross-compilation</a> for more options.
|
||||
</p>
|
||||
<p>
|
||||
By default, modules are only searched under the prefix <tt>/usr/local</tt>.
|
||||
You can add an extra prefix to the search paths by appending the
|
||||
<tt>PREFIX</tt> option, e.g.:
|
||||
</p>
|
||||
<pre class="code">
|
||||
make PREFIX=/home/myself/lj2
|
||||
</pre>
|
||||
<p>
|
||||
Note for OSX: if the <tt>MACOSX_DEPLOYMENT_TARGET</tt> environment
|
||||
variable is not set, then it's forced to <tt>10.4</tt>.
|
||||
</p>
|
||||
<h3>Installing LuaJIT</h3>
|
||||
<p>
|
||||
The top-level Makefile installs LuaJIT by default under
|
||||
<tt>/usr/local</tt>, i.e. the executable ends up in
|
||||
<tt>/usr/local/bin</tt> and so on. You need root privileges
|
||||
to write to this path. So, assuming sudo is installed on your system,
|
||||
run the following command and enter your sudo password:
|
||||
</p>
|
||||
<pre class="code">
|
||||
sudo make install
|
||||
</pre>
|
||||
<p>
|
||||
Otherwise specify the directory prefix as an absolute path, e.g.:
|
||||
</p>
|
||||
<pre class="code">
|
||||
make install PREFIX=/home/myself/lj2
|
||||
</pre>
|
||||
<p>
|
||||
Obviously the prefixes given during build and installation need to be the same.
|
||||
</p>
|
||||
|
||||
<h2 id="windows">Windows Systems</h2>
|
||||
<h3>Prerequisites</h3>
|
||||
<p>
|
||||
Either install one of the open source SDKs
|
||||
(<a href="http://mingw.org/"><span class="ext">»</span> MinGW</a> or
|
||||
<a href="http://www.cygwin.com/"><span class="ext">»</span> Cygwin</a>), which come with a modified
|
||||
GCC plus the required development headers.
|
||||
</p>
|
||||
<p>
|
||||
Or install Microsoft's Visual C++ (MSVC). The freely downloadable
|
||||
<a href="http://www.microsoft.com/Express/VC/"><span class="ext">»</span> Express Edition</a>
|
||||
works just fine, but only contains an x86 compiler.
|
||||
</p>
|
||||
<p>
|
||||
The freely downloadable
|
||||
<a href="http://msdn.microsoft.com/en-us/windowsserver/bb980924.aspx"><span class="ext">»</span> Windows SDK</a>
|
||||
only comes with command line tools, but this is all you need to build LuaJIT.
|
||||
It contains x86 and x64 compilers.
|
||||
</p>
|
||||
<p>
|
||||
Next, download the source package and unpack it using an archive manager
|
||||
(e.g. the Windows Explorer) to a directory of your choice.
|
||||
</p>
|
||||
<h3>Building with MSVC</h3>
|
||||
<p>
|
||||
Open a "Visual Studio .NET Command Prompt", <tt>cd</tt> to the
|
||||
directory where you've unpacked the sources and run these commands:
|
||||
</p>
|
||||
<pre class="code">
|
||||
cd src
|
||||
msvcbuild
|
||||
</pre>
|
||||
<p>
|
||||
Then follow the installation instructions below.
|
||||
</p>
|
||||
<h3>Building with the Windows SDK</h3>
|
||||
<p>
|
||||
Open a "Windows SDK Command Shell" and select the x86 compiler:
|
||||
</p>
|
||||
<pre class="code">
|
||||
setenv /release /x86
|
||||
</pre>
|
||||
<p>
|
||||
Or select the x64 compiler:
|
||||
</p>
|
||||
<pre class="code">
|
||||
setenv /release /x64
|
||||
</pre>
|
||||
<p>
|
||||
Then <tt>cd</tt> to the directory where you've unpacked the sources
|
||||
and run these commands:
|
||||
</p>
|
||||
<pre class="code">
|
||||
cd src
|
||||
msvcbuild
|
||||
</pre>
|
||||
<p>
|
||||
Then follow the installation instructions below.
|
||||
</p>
|
||||
<h3>Building with MinGW or Cygwin</h3>
|
||||
<p>
|
||||
Open a command prompt window and make sure the MinGW or Cygwin programs
|
||||
are in your path. Then <tt>cd</tt> to the directory where
|
||||
you've unpacked the sources and run this command for MinGW:
|
||||
</p>
|
||||
<pre class="code">
|
||||
mingw32-make
|
||||
</pre>
|
||||
<p>
|
||||
Or this command for Cygwin:
|
||||
</p>
|
||||
<pre class="code">
|
||||
make
|
||||
</pre>
|
||||
<p>
|
||||
Then follow the installation instructions below.
|
||||
</p>
|
||||
<h3>Installing LuaJIT</h3>
|
||||
<p>
|
||||
Copy <tt>luajit.exe</tt> and <tt>lua51.dll</tt> (built in the <tt>src</tt>
|
||||
directory) to a newly created directory (any location is ok).
|
||||
Add <tt>lua</tt> and <tt>lua\jit</tt> directories below it and copy
|
||||
all Lua files from the <tt>src\jit</tt> directory of the distribution
|
||||
to the latter directory.
|
||||
</p>
|
||||
<p>
|
||||
There are no hardcoded
|
||||
absolute path names — all modules are loaded relative to the
|
||||
directory where <tt>luajit.exe</tt> is installed
|
||||
(see <tt>src/luaconf.h</tt>).
|
||||
</p>
|
||||
|
||||
<h2 id="cross">Cross-compiling LuaJIT</h2>
|
||||
<p>
|
||||
First, let's clear up some terminology:
|
||||
</p>
|
||||
<ul>
|
||||
<li>Host: This is your development system, usually based on a x64 or x86 CPU.</li>
|
||||
<li>Target: This is the target system you want LuaJIT to run on, e.g. Android/ARM.</li>
|
||||
<li>Toolchain: This comprises a C compiler, linker, assembler and a matching C library.</li>
|
||||
<li>Host (or system) toolchain: This is the toolchain used to build native binaries for your host system.</li>
|
||||
<li>Cross-compile toolchain: This is the toolchain used to build binaries for the target system. They can only be run on the target system.</li>
|
||||
</ul>
|
||||
<p>
|
||||
The GNU Makefile-based build system allows cross-compiling on any host
|
||||
for any supported target:
|
||||
</p>
|
||||
<ul>
|
||||
<li>Yes, you need a toolchain for both your host <em>and</em> your target!</li>
|
||||
<li>Both host and target architectures must have the same pointer size.</li>
|
||||
<li>E.g. if you want to cross-compile to a 32 bit target on a 64 bit host, you need to install the multilib development package (e.g. <tt>libc6-dev-i386</tt> on Debian/Ubuntu) and build a 32 bit host part (<tt>HOST_CC="gcc -m32"</tt>).</li>
|
||||
<li>64 bit targets always require compilation on a 64 bit host.</li>
|
||||
</ul>
|
||||
<p>
|
||||
You need to specify <tt>TARGET_SYS</tt> whenever the host OS and the
|
||||
target OS differ, or you'll get assembler or linker errors:
|
||||
</p>
|
||||
<ul>
|
||||
<li>E.g. if you're compiling on a Windows or OSX host for embedded Linux or Android, you need to add <tt>TARGET_SYS=Linux</tt> to the examples below.</li>
|
||||
<li>For a minimal target OS, you may need to disable the built-in allocator in <tt>src/Makefile</tt> and use <tt>TARGET_SYS=Other</tt>.</li>
|
||||
<li>Don't forget to specify the same <tt>TARGET_SYS</tt> for the install step, too.</li>
|
||||
</ul>
|
||||
<p>
|
||||
Here are some examples where host and target have the same CPU:
|
||||
</p>
|
||||
<pre class="code">
|
||||
# Cross-compile to a 32 bit binary on a multilib x64 OS
|
||||
make CC="gcc -m32"
|
||||
|
||||
# Cross-compile on Debian/Ubuntu for Windows (mingw32 package)
|
||||
make HOST_CC="gcc -m32" CROSS=i586-mingw32msvc- TARGET_SYS=Windows
|
||||
</pre>
|
||||
<p id="cross2">
|
||||
The <tt>CROSS</tt> prefix allows specifying a standard GNU cross-compile
|
||||
toolchain (Binutils, GCC and a matching libc). The prefix may vary
|
||||
depending on the <tt>--target</tt> the toolchain was built for (note the
|
||||
<tt>CROSS</tt> prefix has a trailing <tt>"-"</tt>). The examples below
|
||||
use the canonical toolchain triplets for Linux.
|
||||
</p>
|
||||
<p>
|
||||
Since there's often no easy way to detect CPU features at runtime, it's
|
||||
important to compile with the proper CPU or architecture settings:
|
||||
</o>
|
||||
<ul>
|
||||
<li>The best way to get consistent results is to specify the correct settings when building the toolchain yourself.</li>
|
||||
<li>For a pre-built, generic toolchain add <tt>-mcpu=...</tt> or <tt>-march=...</tt> and other necessary flags to <tt>TARGET_CFLAGS</tt>.</li>
|
||||
<li>For ARM it's important to have the correct <tt>-mfloat-abi=...</tt> setting, too. Otherwise LuaJIT may not run at the full performance of your target CPU.</li>
|
||||
<li>For MIPS it's important to select a supported ABI (o32 on MIPS32, n64 on MIPS64) and consistently compile your project either with hard-float or soft-float compiler settings.</li>
|
||||
</ul>
|
||||
<p>
|
||||
Here are some examples for targets with a different CPU than the host:
|
||||
</p>
|
||||
<pre class="code">
|
||||
# ARM soft-float
|
||||
make HOST_CC="gcc -m32" CROSS=arm-linux-gnueabi- \
|
||||
TARGET_CFLAGS="-mfloat-abi=soft"
|
||||
|
||||
# ARM soft-float ABI with VFP (example for Cortex-A9)
|
||||
make HOST_CC="gcc -m32" CROSS=arm-linux-gnueabi- \
|
||||
TARGET_CFLAGS="-mcpu=cortex-a9 -mfloat-abi=softfp"
|
||||
|
||||
# ARM hard-float ABI with VFP (armhf, most modern toolchains)
|
||||
make HOST_CC="gcc -m32" CROSS=arm-linux-gnueabihf-
|
||||
|
||||
# ARM64
|
||||
make CROSS=aarch64-linux-
|
||||
|
||||
# PPC
|
||||
make HOST_CC="gcc -m32" CROSS=powerpc-linux-gnu-
|
||||
|
||||
# MIPS32 big-endian
|
||||
make HOST_CC="gcc -m32" CROSS=mips-linux-
|
||||
# MIPS32 little-endian
|
||||
make HOST_CC="gcc -m32" CROSS=mipsel-linux-
|
||||
|
||||
# MIPS64 big-endian
|
||||
make CROSS=mips-linux- TARGET_CFLAGS="-mips64r2 -mabi=64"
|
||||
# MIPS64 little-endian
|
||||
make CROSS=mipsel-linux- TARGET_CFLAGS="-mips64r2 -mabi=64"
|
||||
</pre>
|
||||
<p>
|
||||
You can cross-compile for <b id="android">Android</b> using the <a href="https://developer.android.com/ndk/index.html">Android NDK</a>.
|
||||
The environment variables need to match the install locations and the
|
||||
desired target platform. E.g. Android 4.0 corresponds to ABI level 14.
|
||||
For details check the folder <tt>docs</tt> in the NDK directory.
|
||||
</p>
|
||||
<p>
|
||||
Only a few common variations for the different CPUs, ABIs and platforms
|
||||
are listed. Please use your own judgement for which combination you want
|
||||
to build/deploy or which lowest common denominator you want to pick:
|
||||
</p>
|
||||
<pre class="code">
|
||||
# Android/ARM, armeabi (ARMv5TE soft-float), Android 2.2+ (Froyo)
|
||||
NDK=/opt/android/ndk
|
||||
NDKABI=8
|
||||
NDKVER=$NDK/toolchains/arm-linux-androideabi-4.9
|
||||
NDKP=$NDKVER/prebuilt/linux-x86/bin/arm-linux-androideabi-
|
||||
NDKF="--sysroot $NDK/platforms/android-$NDKABI/arch-arm"
|
||||
make HOST_CC="gcc -m32" CROSS=$NDKP TARGET_FLAGS="$NDKF"
|
||||
|
||||
# Android/ARM, armeabi-v7a (ARMv7 VFP), Android 4.0+ (ICS)
|
||||
NDK=/opt/android/ndk
|
||||
NDKABI=14
|
||||
NDKVER=$NDK/toolchains/arm-linux-androideabi-4.9
|
||||
NDKP=$NDKVER/prebuilt/linux-x86/bin/arm-linux-androideabi-
|
||||
NDKF="--sysroot $NDK/platforms/android-$NDKABI/arch-arm"
|
||||
NDKARCH="-march=armv7-a -mfloat-abi=softfp -Wl,--fix-cortex-a8"
|
||||
make HOST_CC="gcc -m32" CROSS=$NDKP TARGET_FLAGS="$NDKF $NDKARCH"
|
||||
|
||||
# Android/MIPS, mipsel (MIPS32R1 hard-float), Android 4.0+ (ICS)
|
||||
NDK=/opt/android/ndk
|
||||
NDKABI=14
|
||||
NDKVER=$NDK/toolchains/mipsel-linux-android-4.9
|
||||
NDKP=$NDKVER/prebuilt/linux-x86/bin/mipsel-linux-android-
|
||||
NDKF="--sysroot $NDK/platforms/android-$NDKABI/arch-mips"
|
||||
make HOST_CC="gcc -m32" CROSS=$NDKP TARGET_FLAGS="$NDKF"
|
||||
|
||||
# Android/x86, x86 (i686 SSE3), Android 4.0+ (ICS)
|
||||
NDK=/opt/android/ndk
|
||||
NDKABI=14
|
||||
NDKVER=$NDK/toolchains/x86-4.9
|
||||
NDKP=$NDKVER/prebuilt/linux-x86/bin/i686-linux-android-
|
||||
NDKF="--sysroot $NDK/platforms/android-$NDKABI/arch-x86"
|
||||
make HOST_CC="gcc -m32" CROSS=$NDKP TARGET_FLAGS="$NDKF"
|
||||
</pre>
|
||||
<p>
|
||||
You can cross-compile for <b id="ios">iOS 3.0+</b> (iPhone/iPad) using the <a href="http://developer.apple.com/devcenter/ios/index.action"><span class="ext">»</span> iOS SDK</a>:
|
||||
</p>
|
||||
<p style="font-size: 8pt;">
|
||||
Note: <b>the JIT compiler is disabled for iOS</b>, because regular iOS Apps
|
||||
are not allowed to generate code at runtime. You'll only get the performance
|
||||
of the LuaJIT interpreter on iOS. This is still faster than plain Lua, but
|
||||
much slower than the JIT compiler. Please complain to Apple, not me.
|
||||
Or use Android. :-p
|
||||
</p>
|
||||
<pre class="code">
|
||||
# iOS/ARM (32 bit)
|
||||
ISDKP=$(xcrun --sdk iphoneos --show-sdk-path)
|
||||
ICC=$(xcrun --sdk iphoneos --find clang)
|
||||
ISDKF="-arch armv7 -isysroot $ISDKP"
|
||||
make DEFAULT_CC=clang HOST_CC="clang -m32 -arch i386" \
|
||||
CROSS="$(dirname $ICC)/" TARGET_FLAGS="$ISDKF" TARGET_SYS=iOS
|
||||
|
||||
# iOS/ARM64
|
||||
ISDKP=$(xcrun --sdk iphoneos --show-sdk-path)
|
||||
ICC=$(xcrun --sdk iphoneos --find clang)
|
||||
ISDKF="-arch arm64 -isysroot $ISDKP"
|
||||
make DEFAULT_CC=clang CROSS="$(dirname $ICC)/" \
|
||||
TARGET_FLAGS="$ISDKF" TARGET_SYS=iOS
|
||||
</pre>
|
||||
|
||||
<h3 id="consoles">Cross-compiling for consoles</h3>
|
||||
<p>
|
||||
Building LuaJIT for consoles requires both a supported host compiler
|
||||
(x86 or x64) and a cross-compiler (to PPC or ARM) from the official
|
||||
console SDK.
|
||||
</p>
|
||||
<p>
|
||||
Due to restrictions on consoles, the JIT compiler is disabled and only
|
||||
the fast interpreter is built. This is still faster than plain Lua,
|
||||
but much slower than the JIT compiler. The FFI is disabled, too, since
|
||||
it's not very useful in such an environment.
|
||||
</p>
|
||||
<p>
|
||||
The following commands build a static library <tt>libluajit.a</tt>,
|
||||
which can be linked against your game, just like the Lua library.
|
||||
</p>
|
||||
<p>
|
||||
To cross-compile for <b id="ps3">PS3</b> from a Linux host (requires
|
||||
32 bit GCC, i.e. multilib Linux/x64) or a Windows host (requires
|
||||
32 bit MinGW), run this command:
|
||||
</p>
|
||||
<pre class="code">
|
||||
make HOST_CC="gcc -m32" CROSS=ppu-lv2-
|
||||
</pre>
|
||||
<p>
|
||||
To cross-compile for <b id="ps4">PS4</b> from a Windows host,
|
||||
open a "Visual Studio .NET Command Prompt" (64 bit host compiler),
|
||||
<tt>cd</tt> to the directory where you've unpacked the sources and
|
||||
run the following commands:
|
||||
</p>
|
||||
<pre class="code">
|
||||
cd src
|
||||
ps4build
|
||||
</pre>
|
||||
<p>
|
||||
To cross-compile for <b id="psvita">PS Vita</b> from a Windows host,
|
||||
open a "Visual Studio .NET Command Prompt" (32 bit host compiler),
|
||||
<tt>cd</tt> to the directory where you've unpacked the sources and
|
||||
run the following commands:
|
||||
</p>
|
||||
<pre class="code">
|
||||
cd src
|
||||
psvitabuild
|
||||
</pre>
|
||||
<p>
|
||||
To cross-compile for <b id="xbox360">Xbox 360</b> from a Windows host,
|
||||
open a "Visual Studio .NET Command Prompt" (32 bit host compiler),
|
||||
<tt>cd</tt> to the directory where you've unpacked the sources and run
|
||||
the following commands:
|
||||
</p>
|
||||
<pre class="code">
|
||||
cd src
|
||||
xedkbuild
|
||||
</pre>
|
||||
<p>
|
||||
To cross-compile for <b id="xboxone">Xbox One</b> from a Windows host,
|
||||
open a "Visual Studio .NET Command Prompt" (64 bit host compiler),
|
||||
<tt>cd</tt> to the directory where you've unpacked the sources and run
|
||||
the following commands:
|
||||
</p>
|
||||
<pre class="code">
|
||||
cd src
|
||||
xb1build
|
||||
</pre>
|
||||
|
||||
<h2 id="embed">Embedding LuaJIT</h2>
|
||||
<p>
|
||||
LuaJIT is API-compatible with Lua 5.1. If you've already embedded Lua
|
||||
into your application, you probably don't need to do anything to switch
|
||||
to LuaJIT, except link with a different library:
|
||||
</p>
|
||||
<ul>
|
||||
<li>It's strongly suggested to build LuaJIT separately using the supplied
|
||||
build system. Please do <em>not</em> attempt to integrate the individual
|
||||
source files into your build tree. You'll most likely get the internal build
|
||||
dependencies wrong or mess up the compiler flags. Treat LuaJIT like any
|
||||
other external library and link your application with either the dynamic
|
||||
or static library, depending on your needs.</li>
|
||||
<li>If you want to load C modules compiled for plain Lua
|
||||
with <tt>require()</tt>, you need to make sure the public symbols
|
||||
(e.g. <tt>lua_pushnumber</tt>) are exported, too:
|
||||
<ul><li>On POSIX systems you can either link to the shared library
|
||||
or link the static library into your application. In the latter case
|
||||
you'll need to export all public symbols from your main executable
|
||||
(e.g. <tt>-Wl,-E</tt> on Linux) and add the external dependencies
|
||||
(e.g. <tt>-lm -ldl</tt> on Linux).</li>
|
||||
<li>Since Windows symbols are bound to a specific DLL name, you need to
|
||||
link to the <tt>lua51.dll</tt> created by the LuaJIT build (do not rename
|
||||
the DLL). You may link LuaJIT statically on Windows only if you don't
|
||||
intend to load Lua/C modules at runtime.
|
||||
</li></ul>
|
||||
</li>
|
||||
<li>
|
||||
If you're building a 64 bit application on OSX which links directly or
|
||||
indirectly against LuaJIT which is not built for <tt>LJ_GC64</tt> mode,
|
||||
you need to link your main executable with these flags:
|
||||
<pre class="code">
|
||||
-pagezero_size 10000 -image_base 100000000
|
||||
</pre>
|
||||
</li>
|
||||
</ul>
|
||||
<p>Additional hints for initializing LuaJIT using the C API functions:</p>
|
||||
<ul>
|
||||
<li>Here's a
|
||||
<a href="http://lua-users.org/wiki/SimpleLuaApiExample"><span class="ext">»</span> simple example</a>
|
||||
for embedding Lua or LuaJIT into your application.</li>
|
||||
<li>Make sure you use <tt>luaL_newstate</tt>. Avoid using
|
||||
<tt>lua_newstate</tt>, since this uses the (slower) default memory
|
||||
allocator from your system (no support for this on x64).</li>
|
||||
<li>Make sure you use <tt>luaL_openlibs</tt> and not the old Lua 5.0 style
|
||||
of calling <tt>luaopen_base</tt> etc. directly.</li>
|
||||
<li>To change or extend the list of standard libraries to load, copy
|
||||
<tt>src/lib_init.c</tt> to your project and modify it accordingly.
|
||||
Make sure the <tt>jit</tt> library is loaded or the JIT compiler
|
||||
will not be activated.</li>
|
||||
<li>The <tt>bit.*</tt> module for bitwise operations
|
||||
is already built-in. There's no need to statically link
|
||||
<a href="http://bitop.luajit.org/"><span class="ext">»</span> Lua BitOp</a> to your application.</li>
|
||||
</ul>
|
||||
|
||||
<h2 id="distro">Hints for Distribution Maintainers</h2>
|
||||
<p>
|
||||
The LuaJIT build system has extra provisions for the needs of most
|
||||
POSIX-based distributions. If you're a package maintainer for
|
||||
a distribution, <em>please</em> make use of these features and
|
||||
avoid patching, subverting, autotoolizing or messing up the build system
|
||||
in unspeakable ways.
|
||||
</p>
|
||||
<p>
|
||||
There should be absolutely no need to patch <tt>luaconf.h</tt> or any
|
||||
of the Makefiles. And please do not hand-pick files for your packages —
|
||||
simply use whatever <tt>make install</tt> creates. There's a reason
|
||||
for all of the files <em>and</em> directories it creates.
|
||||
</p>
|
||||
<p>
|
||||
The build system uses GNU make and auto-detects most settings based on
|
||||
the host you're building it on. This should work fine for native builds,
|
||||
even when sandboxed. You may need to pass some of the following flags to
|
||||
<em>both</em> the <tt>make</tt> and the <tt>make install</tt> command lines
|
||||
for a regular distribution build:
|
||||
</p>
|
||||
<ul>
|
||||
<li><tt>PREFIX</tt> overrides the installation path and should usually
|
||||
be set to <tt>/usr</tt>. Setting this also changes the module paths and
|
||||
the paths needed to locate the shared library.</li>
|
||||
<li><tt>DESTDIR</tt> is an absolute path which allows you to install
|
||||
to a shadow tree instead of the root tree of the build system.</li>
|
||||
<li><tt>MULTILIB</tt> sets the architecture-specific library path component
|
||||
for multilib systems. The default is <tt>lib</tt>.</li>
|
||||
<li>Have a look at the top-level <tt>Makefile</tt> and <tt>src/Makefile</tt>
|
||||
for additional variables to tweak. The following variables <em>may</em> be
|
||||
overridden, but it's <em>not</em> recommended, except for special needs
|
||||
like cross-builds:
|
||||
<tt>BUILDMODE, CC, HOST_CC, STATIC_CC, DYNAMIC_CC, CFLAGS, HOST_CFLAGS,
|
||||
TARGET_CFLAGS, LDFLAGS, HOST_LDFLAGS, TARGET_LDFLAGS, TARGET_SHLDFLAGS,
|
||||
TARGET_FLAGS, LIBS, HOST_LIBS, TARGET_LIBS, CROSS, HOST_SYS, TARGET_SYS
|
||||
</tt></li>
|
||||
</ul>
|
||||
<p>
|
||||
The build system has a special target for an amalgamated build, i.e.
|
||||
<tt>make amalg</tt>. This compiles the LuaJIT core as one huge C file
|
||||
and allows GCC to generate faster and shorter code. Alas, this requires
|
||||
lots of memory during the build. This may be a problem for some users,
|
||||
that's why it's not enabled by default. But it shouldn't be a problem for
|
||||
most build farms. It's recommended that binary distributions use this
|
||||
target for their LuaJIT builds.
|
||||
</p>
|
||||
<p>
|
||||
The tl;dr version of the above:
|
||||
</p>
|
||||
<pre class="code">
|
||||
make amalg PREFIX=/usr && \
|
||||
make install PREFIX=/usr DESTDIR=/tmp/buildroot
|
||||
</pre>
|
||||
<p>
|
||||
Finally, if you encounter any difficulties, please
|
||||
<a href="contact.html">contact me</a> first, instead of releasing a broken
|
||||
package onto unsuspecting users. Because they'll usually gonna complain
|
||||
to me (the upstream) and not you (the package maintainer), anyway.
|
||||
</p>
|
||||
<br class="flush">
|
||||
</div>
|
||||
<div id="foot">
|
||||
<hr class="hide">
|
||||
Copyright © 2005-2017 Mike Pall
|
||||
<span class="noprint">
|
||||
·
|
||||
<a href="contact.html">Contact</a>
|
||||
</span>
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
236
vendor/luajit/doc/luajit.html
vendored
Normal file
236
vendor/luajit/doc/luajit.html
vendored
Normal file
|
@ -0,0 +1,236 @@
|
|||
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
|
||||
<html>
|
||||
<head>
|
||||
<title>LuaJIT</title>
|
||||
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
|
||||
<meta name="Author" content="Mike Pall">
|
||||
<meta name="Copyright" content="Copyright (C) 2005-2017, Mike Pall">
|
||||
<meta name="Language" content="en">
|
||||
<link rel="stylesheet" type="text/css" href="bluequad.css" media="screen">
|
||||
<link rel="stylesheet" type="text/css" href="bluequad-print.css" media="print">
|
||||
<meta name="description" content="LuaJIT is a Just-In-Time (JIT) compiler for the Lua language.">
|
||||
<style type="text/css">
|
||||
table.feature {
|
||||
width: inherit;
|
||||
line-height: 1.2;
|
||||
margin: 0;
|
||||
}
|
||||
table.feature td {
|
||||
width: 80px;
|
||||
height: 40px;
|
||||
vertical-align: middle;
|
||||
text-align: center;
|
||||
font-weight: bold;
|
||||
border: 4px solid #e6ecff;
|
||||
border-radius: 12px;
|
||||
}
|
||||
table.os td {
|
||||
background: #7080d0;
|
||||
background-image: linear-gradient(#4060c0 10%, #b0b0ff 95%);
|
||||
background-image: -moz-linear-gradient(#4060c0 10%, #b0b0ff 95%);
|
||||
background-image: -webkit-linear-gradient(#4060c0 10%, #b0b0ff 95%);
|
||||
background-image: -o-linear-gradient(#4060c0 10%, #b0b0ff 95%);
|
||||
background-image: -ms-linear-gradient(#4060c0 10%, #b0b0ff 95%);
|
||||
}
|
||||
table.os1 td {
|
||||
color: #ffff80;
|
||||
}
|
||||
table.os2 td {
|
||||
color: #ffa040;
|
||||
}
|
||||
table.os3 td {
|
||||
color: #40ffff;
|
||||
}
|
||||
table.compiler td {
|
||||
color: #2080ff;
|
||||
background: #62bf41;
|
||||
background-image: linear-gradient(#62bf41 10%, #b0ffb0 95%);
|
||||
background-image: -moz-linear-gradient(#62bf41 10%, #b0ffb0 95%);
|
||||
background-image: -webkit-linear-gradient(#62bf41 10%, #b0ffb0 95%);
|
||||
background-image: -o-linear-gradient(#62bf41 10%, #b0ffb0 95%);
|
||||
background-image: -ms-linear-gradient(#62bf41 10%, #b0ffb0 95%);
|
||||
}
|
||||
table.cpu td {
|
||||
color: #ffff00;
|
||||
background: #cf7251;
|
||||
background-image: linear-gradient(#bf6241 10%, #ffb0b0 95%);
|
||||
background-image: -moz-linear-gradient(#bf6241 10%, #ffb0b0 95%);
|
||||
background-image: -webkit-linear-gradient(#bf6241 10%, #ffb0b0 95%);
|
||||
background-image: -o-linear-gradient(#bf6241 10%, #ffb0b0 95%);
|
||||
background-image: -ms-linear-gradient(#bf6241 10%, #ffb0b0 95%);
|
||||
}
|
||||
table.fcompat td {
|
||||
color: #2060e0;
|
||||
background: #61cfcf;
|
||||
background-image: linear-gradient(#41bfbf 10%, #b0ffff 95%);
|
||||
background-image: -moz-linear-gradient(#41bfbf 10%, #b0ffff 95%);
|
||||
background-image: -webkit-linear-gradient(#41bfbf 10%, #b0ffff 95%);
|
||||
background-image: -o-linear-gradient(#41bfbf 10%, #b0ffff 95%);
|
||||
background-image: -ms-linear-gradient(#41bfbf 10%, #b0ffff 95%);
|
||||
}
|
||||
table.stats td {
|
||||
color: #ffffff;
|
||||
background: #a0a0a0;
|
||||
background-image: linear-gradient(#808080 10%, #d0d0d0 95%);
|
||||
background-image: -moz-linear-gradient(#808080 10%, #d0d0d0 95%);
|
||||
background-image: -webkit-linear-gradient(#808080 10%, #d0d0d0 95%);
|
||||
background-image: -o-linear-gradient(#808080 10%, #d0d0d0 95%);
|
||||
background-image: -ms-linear-gradient(#808080 10%, #d0d0d0 95%);
|
||||
}
|
||||
table.stats td.speed {
|
||||
color: #ff4020;
|
||||
}
|
||||
table.stats td.kb {
|
||||
color: #ffff80;
|
||||
background: #808080;
|
||||
background-image: linear-gradient(#606060 10%, #c0c0c0 95%);
|
||||
background-image: -moz-linear-gradient(#606060 10%, #c0c0c0 95%);
|
||||
background-image: -webkit-linear-gradient(#606060 10%, #c0c0c0 95%);
|
||||
background-image: -o-linear-gradient(#606060 10%, #c0c0c0 95%);
|
||||
background-image: -ms-linear-gradient(#606060 10%, #c0c0c0 95%);
|
||||
}
|
||||
table.feature small {
|
||||
font-size: 50%;
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<div id="site">
|
||||
<a href="http://luajit.org"><span>Lua<span id="logo">JIT</span></span></a>
|
||||
</div>
|
||||
<div id="head">
|
||||
<h1>LuaJIT</h1>
|
||||
</div>
|
||||
<div id="nav">
|
||||
<ul><li>
|
||||
<a class="current" href="luajit.html">LuaJIT</a>
|
||||
<ul><li>
|
||||
<a href="http://luajit.org/download.html">Download <span class="ext">»</span></a>
|
||||
</li><li>
|
||||
<a href="install.html">Installation</a>
|
||||
</li><li>
|
||||
<a href="running.html">Running</a>
|
||||
</li></ul>
|
||||
</li><li>
|
||||
<a href="extensions.html">Extensions</a>
|
||||
<ul><li>
|
||||
<a href="ext_ffi.html">FFI Library</a>
|
||||
<ul><li>
|
||||
<a href="ext_ffi_tutorial.html">FFI Tutorial</a>
|
||||
</li><li>
|
||||
<a href="ext_ffi_api.html">ffi.* API</a>
|
||||
</li><li>
|
||||
<a href="ext_ffi_semantics.html">FFI Semantics</a>
|
||||
</li></ul>
|
||||
</li><li>
|
||||
<a href="ext_jit.html">jit.* Library</a>
|
||||
</li><li>
|
||||
<a href="ext_c_api.html">Lua/C API</a>
|
||||
</li><li>
|
||||
<a href="ext_profiler.html">Profiler</a>
|
||||
</li></ul>
|
||||
</li><li>
|
||||
<a href="status.html">Status</a>
|
||||
<ul><li>
|
||||
<a href="changes.html">Changes</a>
|
||||
</li></ul>
|
||||
</li><li>
|
||||
<a href="faq.html">FAQ</a>
|
||||
</li><li>
|
||||
<a href="http://luajit.org/performance.html">Performance <span class="ext">»</span></a>
|
||||
</li><li>
|
||||
<a href="http://wiki.luajit.org/">Wiki <span class="ext">»</span></a>
|
||||
</li><li>
|
||||
<a href="http://luajit.org/list.html">Mailing List <span class="ext">»</span></a>
|
||||
</li></ul>
|
||||
</div>
|
||||
<div id="main">
|
||||
<p>
|
||||
LuaJIT is a <b>Just-In-Time Compiler</b> (JIT) for the
|
||||
<a href="http://www.lua.org/"><span class="ext">»</span> Lua</a> programming language.
|
||||
Lua is a powerful, dynamic and light-weight programming language.
|
||||
It may be embedded or used as a general-purpose, stand-alone language.
|
||||
</p>
|
||||
<p>
|
||||
LuaJIT is Copyright © 2005-2017 Mike Pall, released under the
|
||||
<a href="http://www.opensource.org/licenses/mit-license.php"><span class="ext">»</span> MIT open source license</a>.
|
||||
</p>
|
||||
<p>
|
||||
</p>
|
||||
|
||||
<h2>Compatibility</h2>
|
||||
<table class="feature os os1">
|
||||
<tr><td>Windows</td><td>Linux</td><td>BSD</td><td>OSX</td><td>POSIX</td></tr>
|
||||
</table>
|
||||
<table class="feature os os2">
|
||||
<tr><td><span style="font-size:90%;">Embedded</span></td><td>Android</td><td>iOS</td></tr>
|
||||
</table>
|
||||
<table class="feature os os3">
|
||||
<tr><td>PS3</td><td>PS4</td><td>PS Vita</td><td>Xbox 360</td><td>Xbox One</td></tr>
|
||||
</table>
|
||||
<table class="feature compiler">
|
||||
<tr><td>GCC</td><td>Clang<br>LLVM</td><td>MSVC</td></tr>
|
||||
</table>
|
||||
<table class="feature cpu">
|
||||
<tr><td>x86<br>x64</td><td>ARM<br>ARM64</td><td>PPC</td><td>MIPS32<br>MIPS64</td></tr>
|
||||
</table>
|
||||
<table class="feature fcompat">
|
||||
<tr><td>Lua 5.1<br>API+ABI</td><td>+ JIT</td><td>+ BitOp</td><td>+ FFI</td><td>Drop-in<br>DLL/.so</td></tr>
|
||||
</table>
|
||||
|
||||
<h2>Overview</h2>
|
||||
<table class="feature stats">
|
||||
<tr>
|
||||
<td class="speed">3x<br>- 100x</td>
|
||||
<td class="kb">115 <small>KB</small><br>VM</td>
|
||||
<td class="kb">90 <small>KB</small><br>JIT</td>
|
||||
<td class="kloc">63 <small>KLOC</small><br>C</td>
|
||||
<td class="kloc">24 <small>KLOC</small><br>ASM</td>
|
||||
<td class="kloc">11 <small>KLOC</small><br>Lua</td>
|
||||
</tr>
|
||||
</table>
|
||||
<p style="margin-top: 1em;">
|
||||
LuaJIT has been successfully used as a <b>scripting middleware</b> in
|
||||
games, appliances, network and graphics apps, numerical simulations,
|
||||
trading platforms and many other specialty applications. It scales from
|
||||
embedded devices, smartphones, desktops up to server farms. It combines
|
||||
high flexibility with <a href="http://luajit.org/performance.html"><span class="ext">»</span> high performance</a>
|
||||
and an unmatched <b>low memory footprint</b>.
|
||||
</p>
|
||||
<p>
|
||||
LuaJIT has been in continuous development since 2005. It's widely
|
||||
considered to be <b>one of the fastest dynamic language
|
||||
implementations</b>. It has outperformed other dynamic languages on many
|
||||
cross-language benchmarks since its first release — often by a
|
||||
substantial margin.
|
||||
</p>
|
||||
<p>
|
||||
For <b>LuaJIT 2.0</b>, the whole VM has been rewritten from the ground up
|
||||
and relentlessly optimized for performance. It combines a <b>high-speed
|
||||
interpreter</b>, written in assembler, with a <b>state-of-the-art JIT
|
||||
compiler</b>.
|
||||
</p>
|
||||
<p>
|
||||
An innovative <b>trace compiler</b> is integrated with advanced,
|
||||
SSA-based optimizations and highly tuned code generation backends.
|
||||
A substantial reduction of the overhead associated with dynamic languages
|
||||
allows it to break into the performance range traditionally reserved for
|
||||
offline, static language compilers.
|
||||
</p>
|
||||
|
||||
<h2>More ...</h2>
|
||||
<p>
|
||||
Please select a sub-topic in the navigation bar to learn more about LuaJIT.
|
||||
</p>
|
||||
<br class="flush">
|
||||
</div>
|
||||
<div id="foot">
|
||||
<hr class="hide">
|
||||
Copyright © 2005-2017 Mike Pall
|
||||
<span class="noprint">
|
||||
·
|
||||
<a href="contact.html">Contact</a>
|
||||
</span>
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
309
vendor/luajit/doc/running.html
vendored
Normal file
309
vendor/luajit/doc/running.html
vendored
Normal file
|
@ -0,0 +1,309 @@
|
|||
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
|
||||
<html>
|
||||
<head>
|
||||
<title>Running LuaJIT</title>
|
||||
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
|
||||
<meta name="Author" content="Mike Pall">
|
||||
<meta name="Copyright" content="Copyright (C) 2005-2017, Mike Pall">
|
||||
<meta name="Language" content="en">
|
||||
<link rel="stylesheet" type="text/css" href="bluequad.css" media="screen">
|
||||
<link rel="stylesheet" type="text/css" href="bluequad-print.css" media="print">
|
||||
<style type="text/css">
|
||||
table.opt {
|
||||
line-height: 1.2;
|
||||
}
|
||||
tr.opthead td {
|
||||
font-weight: bold;
|
||||
}
|
||||
td.flag_name {
|
||||
width: 4em;
|
||||
}
|
||||
td.flag_level {
|
||||
width: 2em;
|
||||
text-align: center;
|
||||
}
|
||||
td.param_name {
|
||||
width: 6em;
|
||||
}
|
||||
td.param_default {
|
||||
width: 4em;
|
||||
text-align: right;
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<div id="site">
|
||||
<a href="http://luajit.org"><span>Lua<span id="logo">JIT</span></span></a>
|
||||
</div>
|
||||
<div id="head">
|
||||
<h1>Running LuaJIT</h1>
|
||||
</div>
|
||||
<div id="nav">
|
||||
<ul><li>
|
||||
<a href="luajit.html">LuaJIT</a>
|
||||
<ul><li>
|
||||
<a href="http://luajit.org/download.html">Download <span class="ext">»</span></a>
|
||||
</li><li>
|
||||
<a href="install.html">Installation</a>
|
||||
</li><li>
|
||||
<a class="current" href="running.html">Running</a>
|
||||
</li></ul>
|
||||
</li><li>
|
||||
<a href="extensions.html">Extensions</a>
|
||||
<ul><li>
|
||||
<a href="ext_ffi.html">FFI Library</a>
|
||||
<ul><li>
|
||||
<a href="ext_ffi_tutorial.html">FFI Tutorial</a>
|
||||
</li><li>
|
||||
<a href="ext_ffi_api.html">ffi.* API</a>
|
||||
</li><li>
|
||||
<a href="ext_ffi_semantics.html">FFI Semantics</a>
|
||||
</li></ul>
|
||||
</li><li>
|
||||
<a href="ext_jit.html">jit.* Library</a>
|
||||
</li><li>
|
||||
<a href="ext_c_api.html">Lua/C API</a>
|
||||
</li><li>
|
||||
<a href="ext_profiler.html">Profiler</a>
|
||||
</li></ul>
|
||||
</li><li>
|
||||
<a href="status.html">Status</a>
|
||||
<ul><li>
|
||||
<a href="changes.html">Changes</a>
|
||||
</li></ul>
|
||||
</li><li>
|
||||
<a href="faq.html">FAQ</a>
|
||||
</li><li>
|
||||
<a href="http://luajit.org/performance.html">Performance <span class="ext">»</span></a>
|
||||
</li><li>
|
||||
<a href="http://wiki.luajit.org/">Wiki <span class="ext">»</span></a>
|
||||
</li><li>
|
||||
<a href="http://luajit.org/list.html">Mailing List <span class="ext">»</span></a>
|
||||
</li></ul>
|
||||
</div>
|
||||
<div id="main">
|
||||
<p>
|
||||
LuaJIT has only a single stand-alone executable, called <tt>luajit</tt> on
|
||||
POSIX systems or <tt>luajit.exe</tt> on Windows. It can be used to run simple
|
||||
Lua statements or whole Lua applications from the command line. It has an
|
||||
interactive mode, too.
|
||||
</p>
|
||||
|
||||
<h2 id="options">Command Line Options</h2>
|
||||
<p>
|
||||
The <tt>luajit</tt> stand-alone executable is just a slightly modified
|
||||
version of the regular <tt>lua</tt> stand-alone executable.
|
||||
It supports the same basic options, too. <tt>luajit -h</tt>
|
||||
prints a short list of the available options. Please have a look at the
|
||||
<a href="http://www.lua.org/manual/5.1/manual.html#6"><span class="ext">»</span> Lua manual</a>
|
||||
for details.
|
||||
</p>
|
||||
<p>
|
||||
LuaJIT has some additional options:
|
||||
</p>
|
||||
|
||||
<h3 id="opt_b"><tt>-b[options] input output</tt></h3>
|
||||
<p>
|
||||
This option saves or lists bytecode. The following additional options
|
||||
are accepted:
|
||||
</p>
|
||||
<ul>
|
||||
<li><tt>-l</tt> — Only list bytecode.</li>
|
||||
<li><tt>-s</tt> — Strip debug info (this is the default).</li>
|
||||
<li><tt>-g</tt> — Keep debug info.</li>
|
||||
<li><tt>-n name</tt> — Set module name (default: auto-detect from input name)</li>
|
||||
<li><tt>-t type</tt> — Set output file type (default: auto-detect from output name).</li>
|
||||
<li><tt>-a arch</tt> — Override architecture for object files (default: native).</li>
|
||||
<li><tt>-o os</tt> — Override OS for object files (default: native).</li>
|
||||
<li><tt>-e chunk</tt> — Use chunk string as input.</li>
|
||||
<li><tt>-</tt> (a single minus sign) — Use stdin as input and/or stdout as output.</li>
|
||||
</ul>
|
||||
<p>
|
||||
The output file type is auto-detected from the extension of the output
|
||||
file name:
|
||||
</p>
|
||||
<ul>
|
||||
<li><tt>c</tt> — C source file, exported bytecode data.</li>
|
||||
<li><tt>h</tt> — C header file, static bytecode data.</li>
|
||||
<li><tt>obj</tt> or <tt>o</tt> — Object file, exported bytecode data
|
||||
(OS- and architecture-specific).</li>
|
||||
<li><tt>raw</tt> or any other extension — Raw bytecode file (portable).
|
||||
</ul>
|
||||
<p>
|
||||
Notes:
|
||||
</p>
|
||||
<ul>
|
||||
<li>See also <a href="extensions.html#string_dump">string.dump()</a>
|
||||
for information on bytecode portability and compatibility.</li>
|
||||
<li>A file in raw bytecode format is auto-detected and can be loaded like
|
||||
any Lua source file. E.g. directly from the command line or with
|
||||
<tt>loadfile()</tt>, <tt>dofile()</tt> etc.</li>
|
||||
<li>To statically embed the bytecode of a module in your application,
|
||||
generate an object file and just link it with your application.</li>
|
||||
<li>On most ELF-based systems (e.g. Linux) you need to explicitly export the
|
||||
global symbols when linking your application, e.g. with: <tt>-Wl,-E</tt></li>
|
||||
<li><tt>require()</tt> tries to load embedded bytecode data from exported
|
||||
symbols (in <tt>*.exe</tt> or <tt>lua51.dll</tt> on Windows) and from
|
||||
shared libraries in <tt>package.cpath</tt>.</li>
|
||||
</ul>
|
||||
<p>
|
||||
Typical usage examples:
|
||||
</p>
|
||||
<pre class="code">
|
||||
luajit -b test.lua test.out # Save bytecode to test.out
|
||||
luajit -bg test.lua test.out # Keep debug info
|
||||
luajit -be "print('hello world')" test.out # Save cmdline script
|
||||
|
||||
luajit -bl test.lua # List to stdout
|
||||
luajit -bl test.lua test.txt # List to test.txt
|
||||
luajit -ble "print('hello world')" # List cmdline script
|
||||
|
||||
luajit -b test.lua test.obj # Generate object file
|
||||
# Link test.obj with your application and load it with require("test")
|
||||
</pre>
|
||||
|
||||
<h3 id="opt_j"><tt>-j cmd[=arg[,arg...]]</tt></h3>
|
||||
<p>
|
||||
This option performs a LuaJIT control command or activates one of the
|
||||
loadable extension modules. The command is first looked up in the
|
||||
<tt>jit.*</tt> library. If no matching function is found, a module
|
||||
named <tt>jit.<cmd></tt> is loaded and the <tt>start()</tt>
|
||||
function of the module is called with the specified arguments (if
|
||||
any). The space between <tt>-j</tt> and <tt>cmd</tt> is optional.
|
||||
</p>
|
||||
<p>
|
||||
Here are the available LuaJIT control commands:
|
||||
</p>
|
||||
<ul>
|
||||
<li id="j_on"><tt>-jon</tt> — Turns the JIT compiler on (default).</li>
|
||||
<li id="j_off"><tt>-joff</tt> — Turns the JIT compiler off (only use the interpreter).</li>
|
||||
<li id="j_flush"><tt>-jflush</tt> — Flushes the whole cache of compiled code.</li>
|
||||
<li id="j_v"><tt>-jv</tt> — Shows verbose information about the progress of the JIT compiler.</li>
|
||||
<li id="j_dump"><tt>-jdump</tt> — Dumps the code and structures used in various compiler stages.</li>
|
||||
<li id="j_p"><tt>-jp</tt> — Start the <a href="ext_profiler.html">integrated profiler</a>.</li>
|
||||
</ul>
|
||||
<p>
|
||||
The <tt>-jv</tt> and <tt>-jdump</tt> commands are extension modules
|
||||
written in Lua. They are mainly used for debugging the JIT compiler
|
||||
itself. For a description of their options and output format, please
|
||||
read the comment block at the start of their source.
|
||||
They can be found in the <tt>lib</tt> directory of the source
|
||||
distribution or installed under the <tt>jit</tt> directory. By default
|
||||
this is <tt>/usr/local/share/luajit-2.0.5/jit</tt> on POSIX
|
||||
systems.
|
||||
</p>
|
||||
|
||||
<h3 id="opt_O"><tt>-O[level]</tt><br>
|
||||
<tt>-O[+]flag</tt> <tt>-O-flag</tt><br>
|
||||
<tt>-Oparam=value</tt></h3>
|
||||
<p>
|
||||
This options allows fine-tuned control of the optimizations used by
|
||||
the JIT compiler. This is mainly intended for debugging LuaJIT itself.
|
||||
Please note that the JIT compiler is extremely fast (we are talking
|
||||
about the microsecond to millisecond range). Disabling optimizations
|
||||
doesn't have any visible impact on its overhead, but usually generates
|
||||
code that runs slower.
|
||||
</p>
|
||||
<p>
|
||||
The first form sets an optimization level — this enables a
|
||||
specific mix of optimization flags. <tt>-O0</tt> turns off all
|
||||
optimizations and higher numbers enable more optimizations. Omitting
|
||||
the level (i.e. just <tt>-O</tt>) sets the default optimization level,
|
||||
which is <tt>-O3</tt> in the current version.
|
||||
</p>
|
||||
<p>
|
||||
The second form adds or removes individual optimization flags.
|
||||
The third form sets a parameter for the VM or the JIT compiler
|
||||
to a specific value.
|
||||
</p>
|
||||
<p>
|
||||
You can either use this option multiple times (like <tt>-Ocse
|
||||
-O-dce -Ohotloop=10</tt>) or separate several settings with a comma
|
||||
(like <tt>-O+cse,-dce,hotloop=10</tt>). The settings are applied from
|
||||
left to right and later settings override earlier ones. You can freely
|
||||
mix the three forms, but note that setting an optimization level
|
||||
overrides all earlier flags.
|
||||
</p>
|
||||
<p>
|
||||
Here are the available flags and at what optimization levels they
|
||||
are enabled:
|
||||
</p>
|
||||
<table class="opt">
|
||||
<tr class="opthead">
|
||||
<td class="flag_name">Flag</td>
|
||||
<td class="flag_level">-O1</td>
|
||||
<td class="flag_level">-O2</td>
|
||||
<td class="flag_level">-O3</td>
|
||||
<td class="flag_desc"> </td>
|
||||
</tr>
|
||||
<tr class="odd separate">
|
||||
<td class="flag_name">fold</td><td class="flag_level">•</td><td class="flag_level">•</td><td class="flag_level">•</td><td class="flag_desc">Constant Folding, Simplifications and Reassociation</td></tr>
|
||||
<tr class="even">
|
||||
<td class="flag_name">cse</td><td class="flag_level">•</td><td class="flag_level">•</td><td class="flag_level">•</td><td class="flag_desc">Common-Subexpression Elimination</td></tr>
|
||||
<tr class="odd">
|
||||
<td class="flag_name">dce</td><td class="flag_level">•</td><td class="flag_level">•</td><td class="flag_level">•</td><td class="flag_desc">Dead-Code Elimination</td></tr>
|
||||
<tr class="even">
|
||||
<td class="flag_name">narrow</td><td class="flag_level"> </td><td class="flag_level">•</td><td class="flag_level">•</td><td class="flag_desc">Narrowing of numbers to integers</td></tr>
|
||||
<tr class="odd">
|
||||
<td class="flag_name">loop</td><td class="flag_level"> </td><td class="flag_level">•</td><td class="flag_level">•</td><td class="flag_desc">Loop Optimizations (code hoisting)</td></tr>
|
||||
<tr class="even">
|
||||
<td class="flag_name">fwd</td><td class="flag_level"> </td><td class="flag_level"> </td><td class="flag_level">•</td><td class="flag_desc">Load Forwarding (L2L) and Store Forwarding (S2L)</td></tr>
|
||||
<tr class="odd">
|
||||
<td class="flag_name">dse</td><td class="flag_level"> </td><td class="flag_level"> </td><td class="flag_level">•</td><td class="flag_desc">Dead-Store Elimination</td></tr>
|
||||
<tr class="even">
|
||||
<td class="flag_name">abc</td><td class="flag_level"> </td><td class="flag_level"> </td><td class="flag_level">•</td><td class="flag_desc">Array Bounds Check Elimination</td></tr>
|
||||
<tr class="odd">
|
||||
<td class="flag_name">sink</td><td class="flag_level"> </td><td class="flag_level"> </td><td class="flag_level">•</td><td class="flag_desc">Allocation/Store Sinking</td></tr>
|
||||
<tr class="even">
|
||||
<td class="flag_name">fuse</td><td class="flag_level"> </td><td class="flag_level"> </td><td class="flag_level">•</td><td class="flag_desc">Fusion of operands into instructions</td></tr>
|
||||
</table>
|
||||
<p>
|
||||
Here are the parameters and their default settings:
|
||||
</p>
|
||||
<table class="opt">
|
||||
<tr class="opthead">
|
||||
<td class="param_name">Parameter</td>
|
||||
<td class="param_default">Default</td>
|
||||
<td class="param_desc"> </td>
|
||||
</tr>
|
||||
<tr class="odd separate">
|
||||
<td class="param_name">maxtrace</td><td class="param_default">1000</td><td class="param_desc">Max. number of traces in the cache</td></tr>
|
||||
<tr class="even">
|
||||
<td class="param_name">maxrecord</td><td class="param_default">4000</td><td class="param_desc">Max. number of recorded IR instructions</td></tr>
|
||||
<tr class="odd">
|
||||
<td class="param_name">maxirconst</td><td class="param_default">500</td><td class="param_desc">Max. number of IR constants of a trace</td></tr>
|
||||
<tr class="even">
|
||||
<td class="param_name">maxside</td><td class="param_default">100</td><td class="param_desc">Max. number of side traces of a root trace</td></tr>
|
||||
<tr class="odd">
|
||||
<td class="param_name">maxsnap</td><td class="param_default">500</td><td class="param_desc">Max. number of snapshots for a trace</td></tr>
|
||||
<tr class="even separate">
|
||||
<td class="param_name">hotloop</td><td class="param_default">56</td><td class="param_desc">Number of iterations to detect a hot loop or hot call</td></tr>
|
||||
<tr class="odd">
|
||||
<td class="param_name">hotexit</td><td class="param_default">10</td><td class="param_desc">Number of taken exits to start a side trace</td></tr>
|
||||
<tr class="even">
|
||||
<td class="param_name">tryside</td><td class="param_default">4</td><td class="param_desc">Number of attempts to compile a side trace</td></tr>
|
||||
<tr class="odd separate">
|
||||
<td class="param_name">instunroll</td><td class="param_default">4</td><td class="param_desc">Max. unroll factor for instable loops</td></tr>
|
||||
<tr class="even">
|
||||
<td class="param_name">loopunroll</td><td class="param_default">15</td><td class="param_desc">Max. unroll factor for loop ops in side traces</td></tr>
|
||||
<tr class="odd">
|
||||
<td class="param_name">callunroll</td><td class="param_default">3</td><td class="param_desc">Max. unroll factor for pseudo-recursive calls</td></tr>
|
||||
<tr class="even">
|
||||
<td class="param_name">recunroll</td><td class="param_default">2</td><td class="param_desc">Min. unroll factor for true recursion</td></tr>
|
||||
<tr class="odd separate">
|
||||
<td class="param_name">sizemcode</td><td class="param_default">32</td><td class="param_desc">Size of each machine code area in KBytes (Windows: 64K)</td></tr>
|
||||
<tr class="even">
|
||||
<td class="param_name">maxmcode</td><td class="param_default">512</td><td class="param_desc">Max. total size of all machine code areas in KBytes</td></tr>
|
||||
</table>
|
||||
<br class="flush">
|
||||
</div>
|
||||
<div id="foot">
|
||||
<hr class="hide">
|
||||
Copyright © 2005-2017 Mike Pall
|
||||
<span class="noprint">
|
||||
·
|
||||
<a href="contact.html">Contact</a>
|
||||
</span>
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
123
vendor/luajit/doc/status.html
vendored
Normal file
123
vendor/luajit/doc/status.html
vendored
Normal file
|
@ -0,0 +1,123 @@
|
|||
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
|
||||
<html>
|
||||
<head>
|
||||
<title>Status</title>
|
||||
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
|
||||
<meta name="Author" content="Mike Pall">
|
||||
<meta name="Copyright" content="Copyright (C) 2005-2017, Mike Pall">
|
||||
<meta name="Language" content="en">
|
||||
<link rel="stylesheet" type="text/css" href="bluequad.css" media="screen">
|
||||
<link rel="stylesheet" type="text/css" href="bluequad-print.css" media="print">
|
||||
<style type="text/css">
|
||||
ul li { padding-bottom: 0.3em; }
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<div id="site">
|
||||
<a href="http://luajit.org"><span>Lua<span id="logo">JIT</span></span></a>
|
||||
</div>
|
||||
<div id="head">
|
||||
<h1>Status</h1>
|
||||
</div>
|
||||
<div id="nav">
|
||||
<ul><li>
|
||||
<a href="luajit.html">LuaJIT</a>
|
||||
<ul><li>
|
||||
<a href="http://luajit.org/download.html">Download <span class="ext">»</span></a>
|
||||
</li><li>
|
||||
<a href="install.html">Installation</a>
|
||||
</li><li>
|
||||
<a href="running.html">Running</a>
|
||||
</li></ul>
|
||||
</li><li>
|
||||
<a href="extensions.html">Extensions</a>
|
||||
<ul><li>
|
||||
<a href="ext_ffi.html">FFI Library</a>
|
||||
<ul><li>
|
||||
<a href="ext_ffi_tutorial.html">FFI Tutorial</a>
|
||||
</li><li>
|
||||
<a href="ext_ffi_api.html">ffi.* API</a>
|
||||
</li><li>
|
||||
<a href="ext_ffi_semantics.html">FFI Semantics</a>
|
||||
</li></ul>
|
||||
</li><li>
|
||||
<a href="ext_jit.html">jit.* Library</a>
|
||||
</li><li>
|
||||
<a href="ext_c_api.html">Lua/C API</a>
|
||||
</li><li>
|
||||
<a href="ext_profiler.html">Profiler</a>
|
||||
</li></ul>
|
||||
</li><li>
|
||||
<a class="current" href="status.html">Status</a>
|
||||
<ul><li>
|
||||
<a href="changes.html">Changes</a>
|
||||
</li></ul>
|
||||
</li><li>
|
||||
<a href="faq.html">FAQ</a>
|
||||
</li><li>
|
||||
<a href="http://luajit.org/performance.html">Performance <span class="ext">»</span></a>
|
||||
</li><li>
|
||||
<a href="http://wiki.luajit.org/">Wiki <span class="ext">»</span></a>
|
||||
</li><li>
|
||||
<a href="http://luajit.org/list.html">Mailing List <span class="ext">»</span></a>
|
||||
</li></ul>
|
||||
</div>
|
||||
<div id="main">
|
||||
<p>
|
||||
<span style="color: #0000c0;">LuaJIT 2.0</span> is the current
|
||||
<span style="color: #0000c0;">stable branch</span>. This branch is in
|
||||
feature-freeze — new features will only be added to LuaJIT 2.1.
|
||||
</p>
|
||||
|
||||
<h2>Current Status</h2>
|
||||
<p>
|
||||
LuaJIT ought to run all Lua 5.1-compatible source code just fine.
|
||||
It's considered a serious bug if the VM crashes or produces unexpected
|
||||
results — please report this.
|
||||
</p>
|
||||
<p>
|
||||
Known incompatibilities and issues in LuaJIT 2.0:
|
||||
</p>
|
||||
<ul>
|
||||
<li>
|
||||
There are some differences in <b>implementation-defined</b> behavior.
|
||||
These either have a good reason, are arbitrary design choices
|
||||
or are due to quirks in the VM. The latter cases may get fixed if a
|
||||
demonstrable need is shown.
|
||||
</li>
|
||||
<li>
|
||||
The Lua <b>debug API</b> is missing a couple of features (return
|
||||
hooks for non-Lua functions) and shows slightly different behavior
|
||||
in LuaJIT (no per-coroutine hooks, no tail call counting).
|
||||
</li>
|
||||
<li>
|
||||
Currently some <b>out-of-memory</b> errors from <b>on-trace code</b> are not
|
||||
handled correctly. The error may fall through an on-trace
|
||||
<tt>pcall</tt> or it may be passed on to the function set with
|
||||
<tt>lua_atpanic</tt> on x64. This issue will be fixed with the new
|
||||
garbage collector.
|
||||
</li>
|
||||
<li>
|
||||
LuaJIT on 64 bit systems provides a <b>limited range</b> of 47 bits for the
|
||||
<b>legacy <tt>lightuserdata</tt></b> data type.
|
||||
This is only relevant on x64 systems which use the negative part of the
|
||||
virtual address space in user mode, e.g. Solaris/x64, and on ARM64 systems
|
||||
configured with a 48 bit or 52 bit VA.
|
||||
Avoid using <tt>lightuserdata</tt> to hold pointers that may point outside
|
||||
of that range, e.g. variables on the stack. In general, avoid this data
|
||||
type for new code and replace it with (much more performant) FFI bindings.
|
||||
FFI cdata pointers can address the full 64 bit range.
|
||||
</li>
|
||||
</ul>
|
||||
<br class="flush">
|
||||
</div>
|
||||
<div id="foot">
|
||||
<hr class="hide">
|
||||
Copyright © 2005-2017 Mike Pall
|
||||
<span class="noprint">
|
||||
·
|
||||
<a href="contact.html">Contact</a>
|
||||
</span>
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
2
vendor/luajit/dynasm/dasm_arm.h
vendored
2
vendor/luajit/dynasm/dasm_arm.h
vendored
|
@ -1,6 +1,6 @@
|
|||
/*
|
||||
** DynASM ARM encoding engine.
|
||||
** Copyright (C) 2005-2015 Mike Pall. All rights reserved.
|
||||
** Copyright (C) 2005-2017 Mike Pall. All rights reserved.
|
||||
** Released under the MIT license. See dynasm.lua for full copyright notice.
|
||||
*/
|
||||
|
||||
|
|
8
vendor/luajit/dynasm/dasm_arm.lua
vendored
8
vendor/luajit/dynasm/dasm_arm.lua
vendored
|
@ -1,7 +1,7 @@
|
|||
------------------------------------------------------------------------------
|
||||
-- DynASM ARM module.
|
||||
--
|
||||
-- Copyright (C) 2005-2015 Mike Pall. All rights reserved.
|
||||
-- Copyright (C) 2005-2017 Mike Pall. All rights reserved.
|
||||
-- See dynasm.lua for full copyright notice.
|
||||
------------------------------------------------------------------------------
|
||||
|
||||
|
@ -9,9 +9,9 @@
|
|||
local _info = {
|
||||
arch = "arm",
|
||||
description = "DynASM ARM module",
|
||||
version = "1.3.0",
|
||||
vernum = 10300,
|
||||
release = "2011-05-05",
|
||||
version = "1.4.0",
|
||||
vernum = 10400,
|
||||
release = "2015-10-18",
|
||||
author = "Mike Pall",
|
||||
license = "MIT",
|
||||
}
|
||||
|
|
518
vendor/luajit/dynasm/dasm_arm64.h
vendored
Normal file
518
vendor/luajit/dynasm/dasm_arm64.h
vendored
Normal file
|
@ -0,0 +1,518 @@
|
|||
/*
|
||||
** DynASM ARM64 encoding engine.
|
||||
** Copyright (C) 2005-2017 Mike Pall. All rights reserved.
|
||||
** Released under the MIT license. See dynasm.lua for full copyright notice.
|
||||
*/
|
||||
|
||||
#include <stddef.h>
|
||||
#include <stdarg.h>
|
||||
#include <string.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
#define DASM_ARCH "arm64"
|
||||
|
||||
#ifndef DASM_EXTERN
|
||||
#define DASM_EXTERN(a,b,c,d) 0
|
||||
#endif
|
||||
|
||||
/* Action definitions. */
|
||||
enum {
|
||||
DASM_STOP, DASM_SECTION, DASM_ESC, DASM_REL_EXT,
|
||||
/* The following actions need a buffer position. */
|
||||
DASM_ALIGN, DASM_REL_LG, DASM_LABEL_LG,
|
||||
/* The following actions also have an argument. */
|
||||
DASM_REL_PC, DASM_LABEL_PC,
|
||||
DASM_IMM, DASM_IMM6, DASM_IMM12, DASM_IMM13W, DASM_IMM13X, DASM_IMML,
|
||||
DASM__MAX
|
||||
};
|
||||
|
||||
/* 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_RANGE_REL 0x15000000
|
||||
#define DASM_S_UNDEF_LG 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))
|
||||
|
||||
/* Action list type. */
|
||||
typedef const unsigned int *dasm_ActList;
|
||||
|
||||
/* 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, const void *actionlist)
|
||||
{
|
||||
dasm_State *D = Dst_REF;
|
||||
int i;
|
||||
D->actionlist = (dasm_ActList)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
|
||||
|
||||
static int dasm_imm12(unsigned int n)
|
||||
{
|
||||
if ((n >> 12) == 0)
|
||||
return n;
|
||||
else if ((n & 0xff000fff) == 0)
|
||||
return (n >> 12) | 0x1000;
|
||||
else
|
||||
return -1;
|
||||
}
|
||||
|
||||
static int dasm_ffs(unsigned long long x)
|
||||
{
|
||||
int n = -1;
|
||||
while (x) { x >>= 1; n++; }
|
||||
return n;
|
||||
}
|
||||
|
||||
static int dasm_imm13(int lo, int hi)
|
||||
{
|
||||
int inv = 0, w = 64, s = 0xfff, xa, xb;
|
||||
unsigned long long n = (((unsigned long long)hi) << 32) | (unsigned int)lo;
|
||||
unsigned long long m = 1ULL, a, b, c;
|
||||
if (n & 1) { n = ~n; inv = 1; }
|
||||
a = n & -n; b = (n+a)&-(n+a); c = (n+a-b)&-(n+a-b);
|
||||
xa = dasm_ffs(a); xb = dasm_ffs(b);
|
||||
if (c) {
|
||||
w = dasm_ffs(c) - xa;
|
||||
if (w == 32) m = 0x0000000100000001UL;
|
||||
else if (w == 16) m = 0x0001000100010001UL;
|
||||
else if (w == 8) m = 0x0101010101010101UL;
|
||||
else if (w == 4) m = 0x1111111111111111UL;
|
||||
else if (w == 2) m = 0x5555555555555555UL;
|
||||
else return -1;
|
||||
s = (-2*w & 0x3f) - 1;
|
||||
} else if (!a) {
|
||||
return -1;
|
||||
} else if (xb == -1) {
|
||||
xb = 64;
|
||||
}
|
||||
if ((b-a) * m != n) return -1;
|
||||
if (inv) {
|
||||
return ((w - xb) << 6) | (s+w+xa-xb);
|
||||
} else {
|
||||
return ((w - xa) << 6) | (s+xb-xa);
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* 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;
|
||||
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 = (int)sec->bsize/sizeof(int) - DASM_MAXSECPOS+DASM_POS2BIAS(pos);
|
||||
}
|
||||
|
||||
b = sec->rbuf;
|
||||
b[pos++] = start;
|
||||
|
||||
va_start(ap, start);
|
||||
while (1) {
|
||||
unsigned int ins = *p++;
|
||||
unsigned int action = (ins >> 16);
|
||||
if (action >= DASM__MAX) {
|
||||
ofs += 4;
|
||||
} else {
|
||||
int *pl, n = action >= DASM_REL_PC ? va_arg(ap, int) : 0;
|
||||
switch (action) {
|
||||
case DASM_STOP: goto stop;
|
||||
case DASM_SECTION:
|
||||
n = (ins & 255); CK(n < D->maxsection, RANGE_SEC);
|
||||
D->section = &D->sections[n]; goto stop;
|
||||
case DASM_ESC: p++; ofs += 4; break;
|
||||
case DASM_REL_EXT: break;
|
||||
case DASM_ALIGN: ofs += (ins & 255); b[pos++] = ofs; break;
|
||||
case DASM_REL_LG:
|
||||
n = (ins & 2047) - 10; pl = D->lglabels + n;
|
||||
/* Bkwd rel or global. */
|
||||
if (n >= 0) { CK(n>=10||*pl<0, RANGE_LG); CKPL(lg, LG); goto putrel; }
|
||||
pl += 10; n = *pl;
|
||||
if (n < 0) n = 0; /* Start new chain for fwd rel if label exists. */
|
||||
goto linkrel;
|
||||
case DASM_REL_PC:
|
||||
pl = D->pclabels + n; 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++;
|
||||
break;
|
||||
case DASM_LABEL_LG:
|
||||
pl = D->lglabels + (ins & 2047) - 10; CKPL(lg, LG); goto putlabel;
|
||||
case DASM_LABEL_PC:
|
||||
pl = D->pclabels + n; 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_IMM:
|
||||
CK((n & ((1<<((ins>>10)&31))-1)) == 0, RANGE_I);
|
||||
n >>= ((ins>>10)&31);
|
||||
#ifdef DASM_CHECKS
|
||||
if ((ins & 0x8000))
|
||||
CK(((n + (1<<(((ins>>5)&31)-1)))>>((ins>>5)&31)) == 0, RANGE_I);
|
||||
else
|
||||
CK((n>>((ins>>5)&31)) == 0, RANGE_I);
|
||||
#endif
|
||||
b[pos++] = n;
|
||||
break;
|
||||
case DASM_IMM6:
|
||||
CK((n >> 6) == 0, RANGE_I);
|
||||
b[pos++] = n;
|
||||
break;
|
||||
case DASM_IMM12:
|
||||
CK(dasm_imm12((unsigned int)n) != -1, RANGE_I);
|
||||
b[pos++] = n;
|
||||
break;
|
||||
case DASM_IMM13W:
|
||||
CK(dasm_imm13(n, n) != -1, RANGE_I);
|
||||
b[pos++] = n;
|
||||
break;
|
||||
case DASM_IMM13X: {
|
||||
int m = va_arg(ap, int);
|
||||
CK(dasm_imm13(n, m) != -1, RANGE_I);
|
||||
b[pos++] = n;
|
||||
b[pos++] = m;
|
||||
break;
|
||||
}
|
||||
case DASM_IMML: {
|
||||
#ifdef DASM_CHECKS
|
||||
int scale = (p[-2] >> 30);
|
||||
CK((!(n & ((1<<scale)-1)) && (unsigned int)(n>>scale) < 4096) ||
|
||||
(unsigned int)(n+256) < 512, RANGE_I);
|
||||
#endif
|
||||
b[pos++] = n;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
stop:
|
||||
va_end(ap);
|
||||
sec->pos = pos;
|
||||
sec->ofs = ofs;
|
||||
}
|
||||
#undef CK
|
||||
|
||||
/* Pass 2: Link sections, shrink 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 = 20; 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) {
|
||||
unsigned int ins = *p++;
|
||||
unsigned int action = (ins >> 16);
|
||||
switch (action) {
|
||||
case DASM_STOP: case DASM_SECTION: goto stop;
|
||||
case DASM_ESC: p++; break;
|
||||
case DASM_REL_EXT: break;
|
||||
case DASM_ALIGN: ofs -= (b[pos++] + ofs) & (ins & 255); break;
|
||||
case DASM_REL_LG: case DASM_REL_PC: pos++; break;
|
||||
case DASM_LABEL_LG: case DASM_LABEL_PC: b[pos++] += ofs; break;
|
||||
case DASM_IMM: case DASM_IMM6: case DASM_IMM12: case DASM_IMM13W:
|
||||
case DASM_IMML: pos++; break;
|
||||
case DASM_IMM13X: pos += 2; break;
|
||||
}
|
||||
}
|
||||
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;
|
||||
}
|
||||
|
||||
#ifdef DASM_CHECKS
|
||||
#define CK(x, st) \
|
||||
do { if (!(x)) return DASM_S_##st|(p-D->actionlist-1); } while (0)
|
||||
#else
|
||||
#define CK(x, st) ((void)0)
|
||||
#endif
|
||||
|
||||
/* Pass 3: Encode sections. */
|
||||
int dasm_encode(Dst_DECL, void *buffer)
|
||||
{
|
||||
dasm_State *D = Dst_REF;
|
||||
char *base = (char *)buffer;
|
||||
unsigned int *cp = (unsigned int *)buffer;
|
||||
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++;
|
||||
while (1) {
|
||||
unsigned int ins = *p++;
|
||||
unsigned int action = (ins >> 16);
|
||||
int n = (action >= DASM_ALIGN && action < DASM__MAX) ? *b++ : 0;
|
||||
switch (action) {
|
||||
case DASM_STOP: case DASM_SECTION: goto stop;
|
||||
case DASM_ESC: *cp++ = *p++; break;
|
||||
case DASM_REL_EXT:
|
||||
n = DASM_EXTERN(Dst, (unsigned char *)cp, (ins&2047), !(ins&2048));
|
||||
goto patchrel;
|
||||
case DASM_ALIGN:
|
||||
ins &= 255; while ((((char *)cp - base) & ins)) *cp++ = 0xe1a00000;
|
||||
break;
|
||||
case DASM_REL_LG:
|
||||
CK(n >= 0, UNDEF_LG);
|
||||
case DASM_REL_PC:
|
||||
CK(n >= 0, UNDEF_PC);
|
||||
n = *DASM_POS2PTR(D, n) - (int)((char *)cp - base) + 4;
|
||||
patchrel:
|
||||
if (!(ins & 0xf800)) { /* B, BL */
|
||||
CK((n & 3) == 0 && ((n+0x08000000) >> 28) == 0, RANGE_REL);
|
||||
cp[-1] |= ((n >> 2) & 0x03ffffff);
|
||||
} else if ((ins & 0x800)) { /* B.cond, CBZ, CBNZ, LDR* literal */
|
||||
CK((n & 3) == 0 && ((n+0x00100000) >> 21) == 0, RANGE_REL);
|
||||
cp[-1] |= ((n << 3) & 0x00ffffe0);
|
||||
} else if ((ins & 0x3000) == 0x2000) { /* ADR */
|
||||
CK(((n+0x00100000) >> 21) == 0, RANGE_REL);
|
||||
cp[-1] |= ((n << 3) & 0x00ffffe0) | ((n & 3) << 29);
|
||||
} else if ((ins & 0x3000) == 0x3000) { /* ADRP */
|
||||
cp[-1] |= ((n >> 9) & 0x00ffffe0) | (((n >> 12) & 3) << 29);
|
||||
} else if ((ins & 0x1000)) { /* TBZ, TBNZ */
|
||||
CK((n & 3) == 0 && ((n+0x00008000) >> 16) == 0, RANGE_REL);
|
||||
cp[-1] |= ((n << 3) & 0x0007ffe0);
|
||||
}
|
||||
break;
|
||||
case DASM_LABEL_LG:
|
||||
ins &= 2047; if (ins >= 20) D->globals[ins-10] = (void *)(base + n);
|
||||
break;
|
||||
case DASM_LABEL_PC: break;
|
||||
case DASM_IMM:
|
||||
cp[-1] |= (n & ((1<<((ins>>5)&31))-1)) << (ins&31);
|
||||
break;
|
||||
case DASM_IMM6:
|
||||
cp[-1] |= ((n&31) << 19) | ((n&32) << 26);
|
||||
break;
|
||||
case DASM_IMM12:
|
||||
cp[-1] |= (dasm_imm12((unsigned int)n) << 10);
|
||||
break;
|
||||
case DASM_IMM13W:
|
||||
cp[-1] |= (dasm_imm13(n, n) << 10);
|
||||
break;
|
||||
case DASM_IMM13X:
|
||||
cp[-1] |= (dasm_imm13(n, *b++) << 10);
|
||||
break;
|
||||
case DASM_IMML: {
|
||||
int scale = (p[-2] >> 30);
|
||||
cp[-1] |= (!(n & ((1<<scale)-1)) && (unsigned int)(n>>scale) < 4096) ?
|
||||
((n << (10-scale)) | 0x01000000) : ((n & 511) << 12);
|
||||
break;
|
||||
}
|
||||
default: *cp++ = ins; break;
|
||||
}
|
||||
}
|
||||
stop: (void)0;
|
||||
}
|
||||
}
|
||||
|
||||
if (base + D->codesize != (char *)cp) /* Check for phase errors. */
|
||||
return DASM_S_PHASE;
|
||||
return DASM_S_OK;
|
||||
}
|
||||
#undef CK
|
||||
|
||||
/* 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_LG|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
|
||||
|
1166
vendor/luajit/dynasm/dasm_arm64.lua
vendored
Normal file
1166
vendor/luajit/dynasm/dasm_arm64.lua
vendored
Normal file
File diff suppressed because it is too large
Load diff
13
vendor/luajit/dynasm/dasm_mips.h
vendored
13
vendor/luajit/dynasm/dasm_mips.h
vendored
|
@ -1,6 +1,6 @@
|
|||
/*
|
||||
** DynASM MIPS encoding engine.
|
||||
** Copyright (C) 2005-2015 Mike Pall. All rights reserved.
|
||||
** Copyright (C) 2005-2017 Mike Pall. All rights reserved.
|
||||
** Released under the MIT license. See dynasm.lua for full copyright notice.
|
||||
*/
|
||||
|
||||
|
@ -21,7 +21,7 @@ enum {
|
|||
/* The following actions need a buffer position. */
|
||||
DASM_ALIGN, DASM_REL_LG, DASM_LABEL_LG,
|
||||
/* The following actions also have an argument. */
|
||||
DASM_REL_PC, DASM_LABEL_PC, DASM_IMM,
|
||||
DASM_REL_PC, DASM_LABEL_PC, DASM_IMM, DASM_IMMS,
|
||||
DASM__MAX
|
||||
};
|
||||
|
||||
|
@ -231,7 +231,7 @@ void dasm_put(Dst_DECL, int start, ...)
|
|||
*pl = -pos; /* Label exists now. */
|
||||
b[pos++] = ofs; /* Store pass1 offset estimate. */
|
||||
break;
|
||||
case DASM_IMM:
|
||||
case DASM_IMM: case DASM_IMMS:
|
||||
#ifdef DASM_CHECKS
|
||||
CK((n & ((1<<((ins>>10)&31))-1)) == 0, RANGE_I);
|
||||
#endif
|
||||
|
@ -299,7 +299,7 @@ int dasm_link(Dst_DECL, size_t *szp)
|
|||
case DASM_ALIGN: ofs -= (b[pos++] + ofs) & (ins & 255); break;
|
||||
case DASM_REL_LG: case DASM_REL_PC: pos++; break;
|
||||
case DASM_LABEL_LG: case DASM_LABEL_PC: b[pos++] += ofs; break;
|
||||
case DASM_IMM: pos++; break;
|
||||
case DASM_IMM: case DASM_IMMS: pos++; break;
|
||||
}
|
||||
}
|
||||
stop: (void)0;
|
||||
|
@ -356,7 +356,7 @@ int dasm_encode(Dst_DECL, void *buffer)
|
|||
if (ins & 2048)
|
||||
n = n - (int)((char *)cp - base);
|
||||
else
|
||||
n = (n + (int)base) & 0x0fffffff;
|
||||
n = (n + (int)(size_t)base) & 0x0fffffff;
|
||||
patchrel:
|
||||
CK((n & 3) == 0 &&
|
||||
((n + ((ins & 2048) ? 0x00020000 : 0)) >>
|
||||
|
@ -367,6 +367,9 @@ int dasm_encode(Dst_DECL, void *buffer)
|
|||
ins &= 2047; if (ins >= 20) D->globals[ins-10] = (void *)(base + n);
|
||||
break;
|
||||
case DASM_LABEL_PC: break;
|
||||
case DASM_IMMS:
|
||||
cp[-1] |= ((n>>3) & 4); n &= 0x1f;
|
||||
/* fallthrough */
|
||||
case DASM_IMM:
|
||||
cp[-1] |= (n & ((1<<((ins>>5)&31))-1)) << (ins&31);
|
||||
break;
|
||||
|
|
81
vendor/luajit/dynasm/dasm_mips.lua
vendored
81
vendor/luajit/dynasm/dasm_mips.lua
vendored
|
@ -1,17 +1,19 @@
|
|||
------------------------------------------------------------------------------
|
||||
-- DynASM MIPS module.
|
||||
-- DynASM MIPS32/MIPS64 module.
|
||||
--
|
||||
-- Copyright (C) 2005-2015 Mike Pall. All rights reserved.
|
||||
-- Copyright (C) 2005-2017 Mike Pall. All rights reserved.
|
||||
-- See dynasm.lua for full copyright notice.
|
||||
------------------------------------------------------------------------------
|
||||
|
||||
local mips64 = mips64
|
||||
|
||||
-- Module information:
|
||||
local _info = {
|
||||
arch = "mips",
|
||||
description = "DynASM MIPS module",
|
||||
version = "1.3.0",
|
||||
vernum = 10300,
|
||||
release = "2012-01-23",
|
||||
arch = mips64 and "mips64" or "mips",
|
||||
description = "DynASM MIPS32/MIPS64 module",
|
||||
version = "1.4.0",
|
||||
vernum = 10400,
|
||||
release = "2016-05-24",
|
||||
author = "Mike Pall",
|
||||
license = "MIT",
|
||||
}
|
||||
|
@ -27,7 +29,8 @@ local sub, format, byte, char = _s.sub, _s.format, _s.byte, _s.char
|
|||
local match, gmatch = _s.match, _s.gmatch
|
||||
local concat, sort = table.concat, table.sort
|
||||
local bit = bit or require("bit")
|
||||
local band, shl, sar, tohex = bit.band, bit.lshift, bit.arshift, bit.tohex
|
||||
local band, shl, shr, sar = bit.band, bit.lshift, bit.rshift, bit.arshift
|
||||
local tohex = bit.tohex
|
||||
|
||||
-- Inherited tables and callbacks.
|
||||
local g_opt, g_arch
|
||||
|
@ -38,7 +41,7 @@ local wline, werror, wfatal, wwarn
|
|||
local action_names = {
|
||||
"STOP", "SECTION", "ESC", "REL_EXT",
|
||||
"ALIGN", "REL_LG", "LABEL_LG",
|
||||
"REL_PC", "LABEL_PC", "IMM",
|
||||
"REL_PC", "LABEL_PC", "IMM", "IMMS",
|
||||
}
|
||||
|
||||
-- Maximum number of section buffer positions for dasm_put().
|
||||
|
@ -251,6 +254,10 @@ local map_op = {
|
|||
bnel_3 = "54000000STB",
|
||||
blezl_2 = "58000000SB",
|
||||
bgtzl_2 = "5c000000SB",
|
||||
daddi_3 = mips64 and "60000000TSI",
|
||||
daddiu_3 = mips64 and "64000000TSI",
|
||||
ldl_2 = mips64 and "68000000TO",
|
||||
ldr_2 = mips64 and "6c000000TO",
|
||||
lb_2 = "80000000TO",
|
||||
lh_2 = "84000000TO",
|
||||
lwl_2 = "88000000TO",
|
||||
|
@ -258,23 +265,30 @@ local map_op = {
|
|||
lbu_2 = "90000000TO",
|
||||
lhu_2 = "94000000TO",
|
||||
lwr_2 = "98000000TO",
|
||||
lwu_2 = mips64 and "9c000000TO",
|
||||
sb_2 = "a0000000TO",
|
||||
sh_2 = "a4000000TO",
|
||||
swl_2 = "a8000000TO",
|
||||
sw_2 = "ac000000TO",
|
||||
sdl_2 = mips64 and "b0000000TO",
|
||||
sdr_2 = mips64 and "b1000000TO",
|
||||
swr_2 = "b8000000TO",
|
||||
cache_2 = "bc000000NO",
|
||||
ll_2 = "c0000000TO",
|
||||
lwc1_2 = "c4000000HO",
|
||||
pref_2 = "cc000000NO",
|
||||
ldc1_2 = "d4000000HO",
|
||||
ld_2 = mips64 and "dc000000TO",
|
||||
sc_2 = "e0000000TO",
|
||||
swc1_2 = "e4000000HO",
|
||||
scd_2 = mips64 and "f0000000TO",
|
||||
sdc1_2 = "f4000000HO",
|
||||
sd_2 = mips64 and "fc000000TO",
|
||||
|
||||
-- Opcode SPECIAL.
|
||||
nop_0 = "00000000",
|
||||
sll_3 = "00000000DTA",
|
||||
sextw_2 = "00000000DT",
|
||||
movf_2 = "00000001DS",
|
||||
movf_3 = "00000001DSC",
|
||||
movt_2 = "00010001DS",
|
||||
|
@ -285,6 +299,7 @@ local map_op = {
|
|||
sllv_3 = "00000004DTS",
|
||||
srlv_3 = "00000006DTS",
|
||||
rotrv_3 = "00000046DTS",
|
||||
drotrv_3 = mips64 and "00000056DTS",
|
||||
srav_3 = "00000007DTS",
|
||||
jr_1 = "00000008S",
|
||||
jalr_1 = "0000f809S",
|
||||
|
@ -300,15 +315,22 @@ local map_op = {
|
|||
mthi_1 = "00000011S",
|
||||
mflo_1 = "00000012D",
|
||||
mtlo_1 = "00000013S",
|
||||
dsllv_3 = mips64 and "00000014DTS",
|
||||
dsrlv_3 = mips64 and "00000016DTS",
|
||||
dsrav_3 = mips64 and "00000017DTS",
|
||||
mult_2 = "00000018ST",
|
||||
multu_2 = "00000019ST",
|
||||
div_2 = "0000001aST",
|
||||
divu_2 = "0000001bST",
|
||||
dmult_2 = mips64 and "0000001cST",
|
||||
dmultu_2 = mips64 and "0000001dST",
|
||||
ddiv_2 = mips64 and "0000001eST",
|
||||
ddivu_2 = mips64 and "0000001fST",
|
||||
add_3 = "00000020DST",
|
||||
move_2 = "00000021DS",
|
||||
move_2 = mips64 and "00000025DS" or "00000021DS",
|
||||
addu_3 = "00000021DST",
|
||||
sub_3 = "00000022DST",
|
||||
negu_2 = "00000023DT",
|
||||
negu_2 = mips64 and "0000002fDT" or "00000023DT",
|
||||
subu_3 = "00000023DST",
|
||||
and_3 = "00000024DST",
|
||||
or_3 = "00000025DST",
|
||||
|
@ -317,6 +339,10 @@ local map_op = {
|
|||
nor_3 = "00000027DST",
|
||||
slt_3 = "0000002aDST",
|
||||
sltu_3 = "0000002bDST",
|
||||
dadd_3 = mips64 and "0000002cDST",
|
||||
daddu_3 = mips64 and "0000002dDST",
|
||||
dsub_3 = mips64 and "0000002eDST",
|
||||
dsubu_3 = mips64 and "0000002fDST",
|
||||
tge_2 = "00000030ST",
|
||||
tge_3 = "00000030STZ",
|
||||
tgeu_2 = "00000031ST",
|
||||
|
@ -329,6 +355,14 @@ local map_op = {
|
|||
teq_3 = "00000034STZ",
|
||||
tne_2 = "00000036ST",
|
||||
tne_3 = "00000036STZ",
|
||||
dsll_3 = mips64 and "00000038DTa",
|
||||
dsrl_3 = mips64 and "0000003aDTa",
|
||||
drotr_3 = mips64 and "0020003aDTa",
|
||||
dsra_3 = mips64 and "0000003bDTa",
|
||||
dsll32_3 = mips64 and "0000003cDTA",
|
||||
dsrl32_3 = mips64 and "0000003eDTA",
|
||||
drotr32_3 = mips64 and "0020003eDTA",
|
||||
dsra32_3 = mips64 and "0000003fDTA",
|
||||
|
||||
-- Opcode REGIMM.
|
||||
bltz_2 = "04000000SB",
|
||||
|
@ -356,13 +390,24 @@ local map_op = {
|
|||
msubu_2 = "70000005ST",
|
||||
clz_2 = "70000020DS=",
|
||||
clo_2 = "70000021DS=",
|
||||
dclz_2 = mips64 and "70000024DS=",
|
||||
dclo_2 = mips64 and "70000025DS=",
|
||||
sdbbp_0 = "7000003f",
|
||||
sdbbp_1 = "7000003fY",
|
||||
|
||||
-- Opcode SPECIAL3.
|
||||
ext_4 = "7c000000TSAM", -- Note: last arg is msbd = size-1
|
||||
dextm_4 = mips64 and "7c000001TSAM", -- Args: pos | size-1-32
|
||||
dextu_4 = mips64 and "7c000002TSAM", -- Args: pos-32 | size-1
|
||||
dext_4 = mips64 and "7c000003TSAM", -- Args: pos | size-1
|
||||
zextw_2 = mips64 and "7c00f803TS",
|
||||
ins_4 = "7c000004TSAM", -- Note: last arg is msb = pos+size-1
|
||||
dinsm_4 = mips64 and "7c000005TSAM", -- Args: pos | pos+size-33
|
||||
dinsu_4 = mips64 and "7c000006TSAM", -- Args: pos-32 | pos+size-33
|
||||
dins_4 = mips64 and "7c000007TSAM", -- Args: pos | pos+size-1
|
||||
wsbh_2 = "7c0000a0DT",
|
||||
dsbh_2 = mips64 and "7c0000a4DT",
|
||||
dshd_2 = mips64 and "7c000164DT",
|
||||
seb_2 = "7c000420DT",
|
||||
seh_2 = "7c000620DT",
|
||||
rdhwr_2 = "7c00003bTD",
|
||||
|
@ -370,8 +415,12 @@ local map_op = {
|
|||
-- Opcode COP0.
|
||||
mfc0_2 = "40000000TD",
|
||||
mfc0_3 = "40000000TDW",
|
||||
dmfc0_2 = mips64 and "40200000TD",
|
||||
dmfc0_3 = mips64 and "40200000TDW",
|
||||
mtc0_2 = "40800000TD",
|
||||
mtc0_3 = "40800000TDW",
|
||||
dmtc0_2 = mips64 and "40a00000TD",
|
||||
dmtc0_3 = mips64 and "40a00000TDW",
|
||||
rdpgpr_2 = "41400000DT",
|
||||
di_0 = "41606000",
|
||||
di_1 = "41606000T",
|
||||
|
@ -388,9 +437,11 @@ local map_op = {
|
|||
|
||||
-- Opcode COP1.
|
||||
mfc1_2 = "44000000TG",
|
||||
dmfc1_2 = mips64 and "44200000TG",
|
||||
cfc1_2 = "44400000TG",
|
||||
mfhc1_2 = "44600000TG",
|
||||
mtc1_2 = "44800000TG",
|
||||
dmtc1_2 = mips64 and "44a00000TG",
|
||||
ctc1_2 = "44c00000TG",
|
||||
mthc1_2 = "44e00000TG",
|
||||
|
||||
|
@ -633,7 +684,7 @@ local function parse_fpr(expr)
|
|||
werror("bad register name `"..expr.."'")
|
||||
end
|
||||
|
||||
local function parse_imm(imm, bits, shift, scale, signed)
|
||||
local function parse_imm(imm, bits, shift, scale, signed, action)
|
||||
local n = tonumber(imm)
|
||||
if n then
|
||||
local m = sar(n, scale)
|
||||
|
@ -651,7 +702,8 @@ local function parse_imm(imm, bits, shift, scale, signed)
|
|||
match(imm, "^([%w_]+):([rf][1-3]?[0-9])$") then
|
||||
werror("expected immediate operand, got register")
|
||||
else
|
||||
waction("IMM", (signed and 32768 or 0)+scale*1024+bits*32+shift, imm)
|
||||
waction(action or "IMM",
|
||||
(signed and 32768 or 0)+shl(scale, 10)+shl(bits, 5)+shift, imm)
|
||||
return 0
|
||||
end
|
||||
end
|
||||
|
@ -763,6 +815,9 @@ map_op[".template__"] = function(params, template, nparams)
|
|||
n = n + 1
|
||||
elseif p == "A" then
|
||||
op = op + parse_imm(params[n], 5, 6, 0, false); n = n + 1
|
||||
elseif p == "a" then
|
||||
local m = parse_imm(params[n], 6, 6, 0, false, "IMMS"); n = n + 1
|
||||
op = op + band(m, 0x7c0) + band(shr(m, 9), 4)
|
||||
elseif p == "M" then
|
||||
op = op + parse_imm(params[n], 5, 11, 0, false); n = n + 1
|
||||
elseif p == "N" then
|
||||
|
|
12
vendor/luajit/dynasm/dasm_mips64.lua
vendored
Normal file
12
vendor/luajit/dynasm/dasm_mips64.lua
vendored
Normal file
|
@ -0,0 +1,12 @@
|
|||
------------------------------------------------------------------------------
|
||||
-- DynASM MIPS64 module.
|
||||
--
|
||||
-- Copyright (C) 2005-2017 Mike Pall. All rights reserved.
|
||||
-- See dynasm.lua for full copyright notice.
|
||||
------------------------------------------------------------------------------
|
||||
-- This module just sets 64 bit mode for the combined MIPS/MIPS64 module.
|
||||
-- All the interesting stuff is there.
|
||||
------------------------------------------------------------------------------
|
||||
|
||||
mips64 = true -- Using a global is an ugly, but effective solution.
|
||||
return require("dasm_mips")
|
15
vendor/luajit/dynasm/dasm_ppc.h
vendored
15
vendor/luajit/dynasm/dasm_ppc.h
vendored
|
@ -1,6 +1,6 @@
|
|||
/*
|
||||
** DynASM PPC encoding engine.
|
||||
** Copyright (C) 2005-2015 Mike Pall. All rights reserved.
|
||||
** DynASM PPC/PPC64 encoding engine.
|
||||
** Copyright (C) 2005-2017 Mike Pall. All rights reserved.
|
||||
** Released under the MIT license. See dynasm.lua for full copyright notice.
|
||||
*/
|
||||
|
||||
|
@ -21,7 +21,7 @@ enum {
|
|||
/* The following actions need a buffer position. */
|
||||
DASM_ALIGN, DASM_REL_LG, DASM_LABEL_LG,
|
||||
/* The following actions also have an argument. */
|
||||
DASM_REL_PC, DASM_LABEL_PC, DASM_IMM,
|
||||
DASM_REL_PC, DASM_LABEL_PC, DASM_IMM, DASM_IMMSH,
|
||||
DASM__MAX
|
||||
};
|
||||
|
||||
|
@ -244,6 +244,10 @@ void dasm_put(Dst_DECL, int start, ...)
|
|||
#endif
|
||||
b[pos++] = n;
|
||||
break;
|
||||
case DASM_IMMSH:
|
||||
CK((n >> 6) == 0, RANGE_I);
|
||||
b[pos++] = n;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -299,7 +303,7 @@ int dasm_link(Dst_DECL, size_t *szp)
|
|||
case DASM_ALIGN: ofs -= (b[pos++] + ofs) & (ins & 255); break;
|
||||
case DASM_REL_LG: case DASM_REL_PC: pos++; break;
|
||||
case DASM_LABEL_LG: case DASM_LABEL_PC: b[pos++] += ofs; break;
|
||||
case DASM_IMM: pos++; break;
|
||||
case DASM_IMM: case DASM_IMMSH: pos++; break;
|
||||
}
|
||||
}
|
||||
stop: (void)0;
|
||||
|
@ -366,6 +370,9 @@ int dasm_encode(Dst_DECL, void *buffer)
|
|||
case DASM_IMM:
|
||||
cp[-1] |= (n & ((1<<((ins>>5)&31))-1)) << (ins&31);
|
||||
break;
|
||||
case DASM_IMMSH:
|
||||
cp[-1] |= (ins & 1) ? ((n&31)<<11)|((n&32)>>4) : ((n&31)<<6)|(n&32);
|
||||
break;
|
||||
default: *cp++ = ins; break;
|
||||
}
|
||||
}
|
||||
|
|
704
vendor/luajit/dynasm/dasm_ppc.lua
vendored
704
vendor/luajit/dynasm/dasm_ppc.lua
vendored
|
@ -1,17 +1,19 @@
|
|||
------------------------------------------------------------------------------
|
||||
-- DynASM PPC module.
|
||||
-- DynASM PPC/PPC64 module.
|
||||
--
|
||||
-- Copyright (C) 2005-2015 Mike Pall. All rights reserved.
|
||||
-- Copyright (C) 2005-2017 Mike Pall. All rights reserved.
|
||||
-- See dynasm.lua for full copyright notice.
|
||||
--
|
||||
-- Support for various extensions contributed by Caio Souza Oliveira.
|
||||
------------------------------------------------------------------------------
|
||||
|
||||
-- Module information:
|
||||
local _info = {
|
||||
arch = "ppc",
|
||||
description = "DynASM PPC module",
|
||||
version = "1.3.0",
|
||||
vernum = 10300,
|
||||
release = "2011-05-05",
|
||||
version = "1.4.0",
|
||||
vernum = 10400,
|
||||
release = "2015-10-18",
|
||||
author = "Mike Pall",
|
||||
license = "MIT",
|
||||
}
|
||||
|
@ -39,7 +41,7 @@ local wline, werror, wfatal, wwarn
|
|||
local action_names = {
|
||||
"STOP", "SECTION", "ESC", "REL_EXT",
|
||||
"ALIGN", "REL_LG", "LABEL_LG",
|
||||
"REL_PC", "LABEL_PC", "IMM",
|
||||
"REL_PC", "LABEL_PC", "IMM", "IMMSH"
|
||||
}
|
||||
|
||||
-- Maximum number of section buffer positions for dasm_put().
|
||||
|
@ -228,8 +230,18 @@ local map_cond = {
|
|||
|
||||
------------------------------------------------------------------------------
|
||||
|
||||
local map_op, op_template
|
||||
|
||||
local function op_alias(opname, f)
|
||||
return function(params, nparams)
|
||||
if not params then return "-> "..opname:sub(1, -3) end
|
||||
f(params, nparams)
|
||||
op_template(params, map_op[opname], nparams)
|
||||
end
|
||||
end
|
||||
|
||||
-- Template strings for PPC instructions.
|
||||
local map_op = {
|
||||
map_op = {
|
||||
tdi_3 = "08000000ARI",
|
||||
twi_3 = "0c000000ARI",
|
||||
mulli_3 = "1c000000RRI",
|
||||
|
@ -297,6 +309,250 @@ local map_op = {
|
|||
std_2 = "f8000000RD",
|
||||
stdu_2 = "f8000001RD",
|
||||
|
||||
subi_3 = op_alias("addi_3", function(p) p[3] = "-("..p[3]..")" end),
|
||||
subis_3 = op_alias("addis_3", function(p) p[3] = "-("..p[3]..")" end),
|
||||
subic_3 = op_alias("addic_3", function(p) p[3] = "-("..p[3]..")" end),
|
||||
["subic._3"] = op_alias("addic._3", function(p) p[3] = "-("..p[3]..")" end),
|
||||
|
||||
rotlwi_3 = op_alias("rlwinm_5", function(p)
|
||||
p[4] = "0"; p[5] = "31"
|
||||
end),
|
||||
rotrwi_3 = op_alias("rlwinm_5", function(p)
|
||||
p[3] = "32-("..p[3]..")"; p[4] = "0"; p[5] = "31"
|
||||
end),
|
||||
rotlw_3 = op_alias("rlwnm_5", function(p)
|
||||
p[4] = "0"; p[5] = "31"
|
||||
end),
|
||||
slwi_3 = op_alias("rlwinm_5", function(p)
|
||||
p[5] = "31-("..p[3]..")"; p[4] = "0"
|
||||
end),
|
||||
srwi_3 = op_alias("rlwinm_5", function(p)
|
||||
p[4] = p[3]; p[3] = "32-("..p[3]..")"; p[5] = "31"
|
||||
end),
|
||||
clrlwi_3 = op_alias("rlwinm_5", function(p)
|
||||
p[4] = p[3]; p[3] = "0"; p[5] = "31"
|
||||
end),
|
||||
clrrwi_3 = op_alias("rlwinm_5", function(p)
|
||||
p[5] = "31-("..p[3]..")"; p[3] = "0"; p[4] = "0"
|
||||
end),
|
||||
|
||||
-- Primary opcode 4:
|
||||
mulhhwu_3 = "10000010RRR.",
|
||||
machhwu_3 = "10000018RRR.",
|
||||
mulhhw_3 = "10000050RRR.",
|
||||
nmachhw_3 = "1000005cRRR.",
|
||||
machhwsu_3 = "10000098RRR.",
|
||||
machhws_3 = "100000d8RRR.",
|
||||
nmachhws_3 = "100000dcRRR.",
|
||||
mulchwu_3 = "10000110RRR.",
|
||||
macchwu_3 = "10000118RRR.",
|
||||
mulchw_3 = "10000150RRR.",
|
||||
macchw_3 = "10000158RRR.",
|
||||
nmacchw_3 = "1000015cRRR.",
|
||||
macchwsu_3 = "10000198RRR.",
|
||||
macchws_3 = "100001d8RRR.",
|
||||
nmacchws_3 = "100001dcRRR.",
|
||||
mullhw_3 = "10000350RRR.",
|
||||
maclhw_3 = "10000358RRR.",
|
||||
nmaclhw_3 = "1000035cRRR.",
|
||||
maclhwsu_3 = "10000398RRR.",
|
||||
maclhws_3 = "100003d8RRR.",
|
||||
nmaclhws_3 = "100003dcRRR.",
|
||||
machhwuo_3 = "10000418RRR.",
|
||||
nmachhwo_3 = "1000045cRRR.",
|
||||
machhwsuo_3 = "10000498RRR.",
|
||||
machhwso_3 = "100004d8RRR.",
|
||||
nmachhwso_3 = "100004dcRRR.",
|
||||
macchwuo_3 = "10000518RRR.",
|
||||
macchwo_3 = "10000558RRR.",
|
||||
nmacchwo_3 = "1000055cRRR.",
|
||||
macchwsuo_3 = "10000598RRR.",
|
||||
macchwso_3 = "100005d8RRR.",
|
||||
nmacchwso_3 = "100005dcRRR.",
|
||||
maclhwo_3 = "10000758RRR.",
|
||||
nmaclhwo_3 = "1000075cRRR.",
|
||||
maclhwsuo_3 = "10000798RRR.",
|
||||
maclhwso_3 = "100007d8RRR.",
|
||||
nmaclhwso_3 = "100007dcRRR.",
|
||||
|
||||
vaddubm_3 = "10000000VVV",
|
||||
vmaxub_3 = "10000002VVV",
|
||||
vrlb_3 = "10000004VVV",
|
||||
vcmpequb_3 = "10000006VVV",
|
||||
vmuloub_3 = "10000008VVV",
|
||||
vaddfp_3 = "1000000aVVV",
|
||||
vmrghb_3 = "1000000cVVV",
|
||||
vpkuhum_3 = "1000000eVVV",
|
||||
vmhaddshs_4 = "10000020VVVV",
|
||||
vmhraddshs_4 = "10000021VVVV",
|
||||
vmladduhm_4 = "10000022VVVV",
|
||||
vmsumubm_4 = "10000024VVVV",
|
||||
vmsummbm_4 = "10000025VVVV",
|
||||
vmsumuhm_4 = "10000026VVVV",
|
||||
vmsumuhs_4 = "10000027VVVV",
|
||||
vmsumshm_4 = "10000028VVVV",
|
||||
vmsumshs_4 = "10000029VVVV",
|
||||
vsel_4 = "1000002aVVVV",
|
||||
vperm_4 = "1000002bVVVV",
|
||||
vsldoi_4 = "1000002cVVVP",
|
||||
vpermxor_4 = "1000002dVVVV",
|
||||
vmaddfp_4 = "1000002eVVVV~",
|
||||
vnmsubfp_4 = "1000002fVVVV~",
|
||||
vaddeuqm_4 = "1000003cVVVV",
|
||||
vaddecuq_4 = "1000003dVVVV",
|
||||
vsubeuqm_4 = "1000003eVVVV",
|
||||
vsubecuq_4 = "1000003fVVVV",
|
||||
vadduhm_3 = "10000040VVV",
|
||||
vmaxuh_3 = "10000042VVV",
|
||||
vrlh_3 = "10000044VVV",
|
||||
vcmpequh_3 = "10000046VVV",
|
||||
vmulouh_3 = "10000048VVV",
|
||||
vsubfp_3 = "1000004aVVV",
|
||||
vmrghh_3 = "1000004cVVV",
|
||||
vpkuwum_3 = "1000004eVVV",
|
||||
vadduwm_3 = "10000080VVV",
|
||||
vmaxuw_3 = "10000082VVV",
|
||||
vrlw_3 = "10000084VVV",
|
||||
vcmpequw_3 = "10000086VVV",
|
||||
vmulouw_3 = "10000088VVV",
|
||||
vmuluwm_3 = "10000089VVV",
|
||||
vmrghw_3 = "1000008cVVV",
|
||||
vpkuhus_3 = "1000008eVVV",
|
||||
vaddudm_3 = "100000c0VVV",
|
||||
vmaxud_3 = "100000c2VVV",
|
||||
vrld_3 = "100000c4VVV",
|
||||
vcmpeqfp_3 = "100000c6VVV",
|
||||
vcmpequd_3 = "100000c7VVV",
|
||||
vpkuwus_3 = "100000ceVVV",
|
||||
vadduqm_3 = "10000100VVV",
|
||||
vmaxsb_3 = "10000102VVV",
|
||||
vslb_3 = "10000104VVV",
|
||||
vmulosb_3 = "10000108VVV",
|
||||
vrefp_2 = "1000010aV-V",
|
||||
vmrglb_3 = "1000010cVVV",
|
||||
vpkshus_3 = "1000010eVVV",
|
||||
vaddcuq_3 = "10000140VVV",
|
||||
vmaxsh_3 = "10000142VVV",
|
||||
vslh_3 = "10000144VVV",
|
||||
vmulosh_3 = "10000148VVV",
|
||||
vrsqrtefp_2 = "1000014aV-V",
|
||||
vmrglh_3 = "1000014cVVV",
|
||||
vpkswus_3 = "1000014eVVV",
|
||||
vaddcuw_3 = "10000180VVV",
|
||||
vmaxsw_3 = "10000182VVV",
|
||||
vslw_3 = "10000184VVV",
|
||||
vmulosw_3 = "10000188VVV",
|
||||
vexptefp_2 = "1000018aV-V",
|
||||
vmrglw_3 = "1000018cVVV",
|
||||
vpkshss_3 = "1000018eVVV",
|
||||
vmaxsd_3 = "100001c2VVV",
|
||||
vsl_3 = "100001c4VVV",
|
||||
vcmpgefp_3 = "100001c6VVV",
|
||||
vlogefp_2 = "100001caV-V",
|
||||
vpkswss_3 = "100001ceVVV",
|
||||
vadduhs_3 = "10000240VVV",
|
||||
vminuh_3 = "10000242VVV",
|
||||
vsrh_3 = "10000244VVV",
|
||||
vcmpgtuh_3 = "10000246VVV",
|
||||
vmuleuh_3 = "10000248VVV",
|
||||
vrfiz_2 = "1000024aV-V",
|
||||
vsplth_3 = "1000024cVV3",
|
||||
vupkhsh_2 = "1000024eV-V",
|
||||
vminuw_3 = "10000282VVV",
|
||||
vminud_3 = "100002c2VVV",
|
||||
vcmpgtud_3 = "100002c7VVV",
|
||||
vrfim_2 = "100002caV-V",
|
||||
vcmpgtsb_3 = "10000306VVV",
|
||||
vcfux_3 = "1000030aVVA~",
|
||||
vaddshs_3 = "10000340VVV",
|
||||
vminsh_3 = "10000342VVV",
|
||||
vsrah_3 = "10000344VVV",
|
||||
vcmpgtsh_3 = "10000346VVV",
|
||||
vmulesh_3 = "10000348VVV",
|
||||
vcfsx_3 = "1000034aVVA~",
|
||||
vspltish_2 = "1000034cVS",
|
||||
vupkhpx_2 = "1000034eV-V",
|
||||
vaddsws_3 = "10000380VVV",
|
||||
vminsw_3 = "10000382VVV",
|
||||
vsraw_3 = "10000384VVV",
|
||||
vcmpgtsw_3 = "10000386VVV",
|
||||
vmulesw_3 = "10000388VVV",
|
||||
vctuxs_3 = "1000038aVVA~",
|
||||
vspltisw_2 = "1000038cVS",
|
||||
vminsd_3 = "100003c2VVV",
|
||||
vsrad_3 = "100003c4VVV",
|
||||
vcmpbfp_3 = "100003c6VVV",
|
||||
vcmpgtsd_3 = "100003c7VVV",
|
||||
vctsxs_3 = "100003caVVA~",
|
||||
vupklpx_2 = "100003ceV-V",
|
||||
vsububm_3 = "10000400VVV",
|
||||
["bcdadd._4"] = "10000401VVVy.",
|
||||
vavgub_3 = "10000402VVV",
|
||||
vand_3 = "10000404VVV",
|
||||
["vcmpequb._3"] = "10000406VVV",
|
||||
vmaxfp_3 = "1000040aVVV",
|
||||
vsubuhm_3 = "10000440VVV",
|
||||
["bcdsub._4"] = "10000441VVVy.",
|
||||
vavguh_3 = "10000442VVV",
|
||||
vandc_3 = "10000444VVV",
|
||||
["vcmpequh._3"] = "10000446VVV",
|
||||
vminfp_3 = "1000044aVVV",
|
||||
vpkudum_3 = "1000044eVVV",
|
||||
vsubuwm_3 = "10000480VVV",
|
||||
vavguw_3 = "10000482VVV",
|
||||
vor_3 = "10000484VVV",
|
||||
["vcmpequw._3"] = "10000486VVV",
|
||||
vpmsumw_3 = "10000488VVV",
|
||||
["vcmpeqfp._3"] = "100004c6VVV",
|
||||
["vcmpequd._3"] = "100004c7VVV",
|
||||
vpkudus_3 = "100004ceVVV",
|
||||
vavgsb_3 = "10000502VVV",
|
||||
vavgsh_3 = "10000542VVV",
|
||||
vorc_3 = "10000544VVV",
|
||||
vbpermq_3 = "1000054cVVV",
|
||||
vpksdus_3 = "1000054eVVV",
|
||||
vavgsw_3 = "10000582VVV",
|
||||
vsld_3 = "100005c4VVV",
|
||||
["vcmpgefp._3"] = "100005c6VVV",
|
||||
vpksdss_3 = "100005ceVVV",
|
||||
vsububs_3 = "10000600VVV",
|
||||
mfvscr_1 = "10000604V--",
|
||||
vsum4ubs_3 = "10000608VVV",
|
||||
vsubuhs_3 = "10000640VVV",
|
||||
mtvscr_1 = "10000644--V",
|
||||
["vcmpgtuh._3"] = "10000646VVV",
|
||||
vsum4shs_3 = "10000648VVV",
|
||||
vupkhsw_2 = "1000064eV-V",
|
||||
vsubuws_3 = "10000680VVV",
|
||||
vshasigmaw_4 = "10000682VVYp",
|
||||
veqv_3 = "10000684VVV",
|
||||
vsum2sws_3 = "10000688VVV",
|
||||
vmrgow_3 = "1000068cVVV",
|
||||
vshasigmad_4 = "100006c2VVYp",
|
||||
vsrd_3 = "100006c4VVV",
|
||||
["vcmpgtud._3"] = "100006c7VVV",
|
||||
vupklsw_2 = "100006ceV-V",
|
||||
vupkslw_2 = "100006ceV-V",
|
||||
vsubsbs_3 = "10000700VVV",
|
||||
vclzb_2 = "10000702V-V",
|
||||
vpopcntb_2 = "10000703V-V",
|
||||
["vcmpgtsb._3"] = "10000706VVV",
|
||||
vsum4sbs_3 = "10000708VVV",
|
||||
vsubshs_3 = "10000740VVV",
|
||||
vclzh_2 = "10000742V-V",
|
||||
vpopcnth_2 = "10000743V-V",
|
||||
["vcmpgtsh._3"] = "10000746VVV",
|
||||
vsubsws_3 = "10000780VVV",
|
||||
vclzw_2 = "10000782V-V",
|
||||
vpopcntw_2 = "10000783V-V",
|
||||
["vcmpgtsw._3"] = "10000786VVV",
|
||||
vsumsws_3 = "10000788VVV",
|
||||
vmrgew_3 = "1000078cVVV",
|
||||
vclzd_2 = "100007c2V-V",
|
||||
vpopcntd_2 = "100007c3V-V",
|
||||
["vcmpbfp._3"] = "100007c6VVV",
|
||||
["vcmpgtsd._3"] = "100007c7VVV",
|
||||
|
||||
-- Primary opcode 19:
|
||||
mcrf_2 = "4c000000XX",
|
||||
isync_0 = "4c00012c",
|
||||
|
@ -316,6 +572,8 @@ local map_op = {
|
|||
bclrl_2 = "4c000021AA",
|
||||
bcctr_2 = "4c000420AA",
|
||||
bcctrl_2 = "4c000421AA",
|
||||
bctar_2 = "4c000460AA",
|
||||
bctarl_2 = "4c000461AA",
|
||||
blr_0 = "4e800020",
|
||||
blrl_0 = "4e800021",
|
||||
bctr_0 = "4e800420",
|
||||
|
@ -327,6 +585,7 @@ local map_op = {
|
|||
cmpd_3 = "7c200000XRR",
|
||||
cmpd_2 = "7c200000-RR",
|
||||
tw_3 = "7c000008ARR",
|
||||
lvsl_3 = "7c00000cVRR",
|
||||
subfc_3 = "7c000010RRR.",
|
||||
subc_3 = "7c000010RRR~.",
|
||||
mulhdu_3 = "7c000012RRR.",
|
||||
|
@ -351,50 +610,68 @@ local map_op = {
|
|||
cmplw_2 = "7c000040-RR",
|
||||
cmpld_3 = "7c200040XRR",
|
||||
cmpld_2 = "7c200040-RR",
|
||||
lvsr_3 = "7c00004cVRR",
|
||||
subf_3 = "7c000050RRR.",
|
||||
sub_3 = "7c000050RRR~.",
|
||||
lbarx_3 = "7c000068RR0R",
|
||||
ldux_3 = "7c00006aRR0R",
|
||||
dcbst_2 = "7c00006c-RR",
|
||||
lwzux_3 = "7c00006eRR0R",
|
||||
cntlzd_2 = "7c000074RR~",
|
||||
andc_3 = "7c000078RR~R.",
|
||||
td_3 = "7c000088ARR",
|
||||
lvewx_3 = "7c00008eVRR",
|
||||
mulhd_3 = "7c000092RRR.",
|
||||
addg6s_3 = "7c000094RRR",
|
||||
mulhw_3 = "7c000096RRR.",
|
||||
dlmzb_3 = "7c00009cRR~R.",
|
||||
ldarx_3 = "7c0000a8RR0R",
|
||||
dcbf_2 = "7c0000ac-RR",
|
||||
lbzx_3 = "7c0000aeRR0R",
|
||||
lvx_3 = "7c0000ceVRR",
|
||||
neg_2 = "7c0000d0RR.",
|
||||
lharx_3 = "7c0000e8RR0R",
|
||||
lbzux_3 = "7c0000eeRR0R",
|
||||
popcntb_2 = "7c0000f4RR~",
|
||||
not_2 = "7c0000f8RR~%.",
|
||||
nor_3 = "7c0000f8RR~R.",
|
||||
stvebx_3 = "7c00010eVRR",
|
||||
subfe_3 = "7c000110RRR.",
|
||||
sube_3 = "7c000110RRR~.",
|
||||
adde_3 = "7c000114RRR.",
|
||||
stdx_3 = "7c00012aRR0R",
|
||||
stwcx_3 = "7c00012cRR0R.",
|
||||
["stwcx._3"] = "7c00012dRR0R.",
|
||||
stwx_3 = "7c00012eRR0R",
|
||||
prtyw_2 = "7c000134RR~",
|
||||
stvehx_3 = "7c00014eVRR",
|
||||
stdux_3 = "7c00016aRR0R",
|
||||
["stqcx._3"] = "7c00016dR:R0R.",
|
||||
stwux_3 = "7c00016eRR0R",
|
||||
prtyd_2 = "7c000174RR~",
|
||||
stvewx_3 = "7c00018eVRR",
|
||||
subfze_2 = "7c000190RR.",
|
||||
addze_2 = "7c000194RR.",
|
||||
stdcx_3 = "7c0001acRR0R.",
|
||||
["stdcx._3"] = "7c0001adRR0R.",
|
||||
stbx_3 = "7c0001aeRR0R",
|
||||
stvx_3 = "7c0001ceVRR",
|
||||
subfme_2 = "7c0001d0RR.",
|
||||
mulld_3 = "7c0001d2RRR.",
|
||||
addme_2 = "7c0001d4RR.",
|
||||
mullw_3 = "7c0001d6RRR.",
|
||||
dcbtst_2 = "7c0001ec-RR",
|
||||
stbux_3 = "7c0001eeRR0R",
|
||||
bpermd_3 = "7c0001f8RR~R",
|
||||
lvepxl_3 = "7c00020eVRR",
|
||||
add_3 = "7c000214RRR.",
|
||||
lqarx_3 = "7c000228R:R0R",
|
||||
dcbt_2 = "7c00022c-RR",
|
||||
lhzx_3 = "7c00022eRR0R",
|
||||
cdtbcd_2 = "7c000234RR~",
|
||||
eqv_3 = "7c000238RR~R.",
|
||||
lvepx_3 = "7c00024eVRR",
|
||||
eciwx_3 = "7c00026cRR0R",
|
||||
lhzux_3 = "7c00026eRR0R",
|
||||
cbcdtd_2 = "7c000274RR~",
|
||||
xor_3 = "7c000278RR~R.",
|
||||
mfspefscr_1 = "7c0082a6R",
|
||||
mfxer_1 = "7c0102a6R",
|
||||
|
@ -404,8 +681,12 @@ local map_op = {
|
|||
lhax_3 = "7c0002aeRR0R",
|
||||
mftb_1 = "7c0c42e6R",
|
||||
mftbu_1 = "7c0d42e6R",
|
||||
lvxl_3 = "7c0002ceVRR",
|
||||
lwaux_3 = "7c0002eaRR0R",
|
||||
lhaux_3 = "7c0002eeRR0R",
|
||||
popcntw_2 = "7c0002f4RR~",
|
||||
divdeu_3 = "7c000312RRR.",
|
||||
divweu_3 = "7c000316RRR.",
|
||||
sthx_3 = "7c00032eRR0R",
|
||||
orc_3 = "7c000338RR~R.",
|
||||
ecowx_3 = "7c00036cRR0R",
|
||||
|
@ -420,10 +701,14 @@ local map_op = {
|
|||
mtctr_1 = "7c0903a6R",
|
||||
dcbi_2 = "7c0003ac-RR",
|
||||
nand_3 = "7c0003b8RR~R.",
|
||||
dsn_2 = "7c0003c6-RR",
|
||||
stvxl_3 = "7c0003ceVRR",
|
||||
divd_3 = "7c0003d2RRR.",
|
||||
divw_3 = "7c0003d6RRR.",
|
||||
popcntd_2 = "7c0003f4RR~",
|
||||
cmpb_3 = "7c0003f8RR~R.",
|
||||
mcrxr_1 = "7c000400X",
|
||||
lbdx_3 = "7c000406RRR",
|
||||
subfco_3 = "7c000410RRR.",
|
||||
subco_3 = "7c000410RRR~.",
|
||||
addco_3 = "7c000414RRR.",
|
||||
|
@ -433,16 +718,20 @@ local map_op = {
|
|||
lfsx_3 = "7c00042eFR0R",
|
||||
srw_3 = "7c000430RR~R.",
|
||||
srd_3 = "7c000436RR~R.",
|
||||
lhdx_3 = "7c000446RRR",
|
||||
subfo_3 = "7c000450RRR.",
|
||||
subo_3 = "7c000450RRR~.",
|
||||
lfsux_3 = "7c00046eFR0R",
|
||||
lwdx_3 = "7c000486RRR",
|
||||
lswi_3 = "7c0004aaRR0A",
|
||||
sync_0 = "7c0004ac",
|
||||
lwsync_0 = "7c2004ac",
|
||||
ptesync_0 = "7c4004ac",
|
||||
lfdx_3 = "7c0004aeFR0R",
|
||||
lddx_3 = "7c0004c6RRR",
|
||||
nego_2 = "7c0004d0RR.",
|
||||
lfdux_3 = "7c0004eeFR0R",
|
||||
stbdx_3 = "7c000506RRR",
|
||||
subfeo_3 = "7c000510RRR.",
|
||||
subeo_3 = "7c000510RRR~.",
|
||||
addeo_3 = "7c000514RRR.",
|
||||
|
@ -450,27 +739,42 @@ local map_op = {
|
|||
stswx_3 = "7c00052aRR0R",
|
||||
stwbrx_3 = "7c00052cRR0R",
|
||||
stfsx_3 = "7c00052eFR0R",
|
||||
sthdx_3 = "7c000546RRR",
|
||||
["stbcx._3"] = "7c00056dRRR",
|
||||
stfsux_3 = "7c00056eFR0R",
|
||||
stwdx_3 = "7c000586RRR",
|
||||
subfzeo_2 = "7c000590RR.",
|
||||
addzeo_2 = "7c000594RR.",
|
||||
stswi_3 = "7c0005aaRR0A",
|
||||
["sthcx._3"] = "7c0005adRRR",
|
||||
stfdx_3 = "7c0005aeFR0R",
|
||||
stddx_3 = "7c0005c6RRR",
|
||||
subfmeo_2 = "7c0005d0RR.",
|
||||
mulldo_3 = "7c0005d2RRR.",
|
||||
addmeo_2 = "7c0005d4RR.",
|
||||
mullwo_3 = "7c0005d6RRR.",
|
||||
dcba_2 = "7c0005ec-RR",
|
||||
stfdux_3 = "7c0005eeFR0R",
|
||||
stvepxl_3 = "7c00060eVRR",
|
||||
addo_3 = "7c000614RRR.",
|
||||
lhbrx_3 = "7c00062cRR0R",
|
||||
lfdpx_3 = "7c00062eF:RR",
|
||||
sraw_3 = "7c000630RR~R.",
|
||||
srad_3 = "7c000634RR~R.",
|
||||
lfddx_3 = "7c000646FRR",
|
||||
stvepx_3 = "7c00064eVRR",
|
||||
srawi_3 = "7c000670RR~A.",
|
||||
sradi_3 = "7c000674RR~H.",
|
||||
eieio_0 = "7c0006ac",
|
||||
lfiwax_3 = "7c0006aeFR0R",
|
||||
divdeuo_3 = "7c000712RRR.",
|
||||
divweuo_3 = "7c000716RRR.",
|
||||
sthbrx_3 = "7c00072cRR0R",
|
||||
stfdpx_3 = "7c00072eF:RR",
|
||||
extsh_2 = "7c000734RR~.",
|
||||
stfddx_3 = "7c000746FRR",
|
||||
divdeo_3 = "7c000752RRR.",
|
||||
divweo_3 = "7c000756RRR.",
|
||||
extsb_2 = "7c000774RR~.",
|
||||
divduo_3 = "7c000792RRR.",
|
||||
divwou_3 = "7c000796RRR.",
|
||||
|
@ -481,6 +785,40 @@ local map_op = {
|
|||
divwo_3 = "7c0007d6RRR.",
|
||||
dcbz_2 = "7c0007ec-RR",
|
||||
|
||||
["tbegin._1"] = "7c00051d1",
|
||||
["tbegin._0"] = "7c00051d",
|
||||
["tend._1"] = "7c00055dY",
|
||||
["tend._0"] = "7c00055d",
|
||||
["tendall._0"] = "7e00055d",
|
||||
tcheck_1 = "7c00059cX",
|
||||
["tsr._1"] = "7c0005dd1",
|
||||
["tsuspend._0"] = "7c0005dd",
|
||||
["tresume._0"] = "7c2005dd",
|
||||
["tabortwc._3"] = "7c00061dARR",
|
||||
["tabortdc._3"] = "7c00065dARR",
|
||||
["tabortwci._3"] = "7c00069dARS",
|
||||
["tabortdci._3"] = "7c0006ddARS",
|
||||
["tabort._1"] = "7c00071d-R-",
|
||||
["treclaim._1"] = "7c00075d-R",
|
||||
["trechkpt._0"] = "7c0007dd",
|
||||
|
||||
lxsiwzx_3 = "7c000018QRR",
|
||||
lxsiwax_3 = "7c000098QRR",
|
||||
mfvsrd_2 = "7c000066-Rq",
|
||||
mfvsrwz_2 = "7c0000e6-Rq",
|
||||
stxsiwx_3 = "7c000118QRR",
|
||||
mtvsrd_2 = "7c000166QR",
|
||||
mtvsrwa_2 = "7c0001a6QR",
|
||||
lxvdsx_3 = "7c000298QRR",
|
||||
lxsspx_3 = "7c000418QRR",
|
||||
lxsdx_3 = "7c000498QRR",
|
||||
stxsspx_3 = "7c000518QRR",
|
||||
stxsdx_3 = "7c000598QRR",
|
||||
lxvw4x_3 = "7c000618QRR",
|
||||
lxvd2x_3 = "7c000698QRR",
|
||||
stxvw4x_3 = "7c000718QRR",
|
||||
stxvd2x_3 = "7c000798QRR",
|
||||
|
||||
-- Primary opcode 30:
|
||||
rldicl_4 = "78000000RR~HM.",
|
||||
rldicr_4 = "78000004RR~HM.",
|
||||
|
@ -489,6 +827,34 @@ local map_op = {
|
|||
rldcl_4 = "78000010RR~RM.",
|
||||
rldcr_4 = "78000012RR~RM.",
|
||||
|
||||
rotldi_3 = op_alias("rldicl_4", function(p)
|
||||
p[4] = "0"
|
||||
end),
|
||||
rotrdi_3 = op_alias("rldicl_4", function(p)
|
||||
p[3] = "64-("..p[3]..")"; p[4] = "0"
|
||||
end),
|
||||
rotld_3 = op_alias("rldcl_4", function(p)
|
||||
p[4] = "0"
|
||||
end),
|
||||
sldi_3 = op_alias("rldicr_4", function(p)
|
||||
p[4] = "63-("..p[3]..")"
|
||||
end),
|
||||
srdi_3 = op_alias("rldicl_4", function(p)
|
||||
p[4] = p[3]; p[3] = "64-("..p[3]..")"
|
||||
end),
|
||||
clrldi_3 = op_alias("rldicl_4", function(p)
|
||||
p[4] = p[3]; p[3] = "0"
|
||||
end),
|
||||
clrrdi_3 = op_alias("rldicr_4", function(p)
|
||||
p[4] = "63-("..p[3]..")"; p[3] = "0"
|
||||
end),
|
||||
|
||||
-- Primary opcode 56:
|
||||
lq_2 = "e0000000R:D", -- NYI: displacement must be divisible by 8.
|
||||
|
||||
-- Primary opcode 57:
|
||||
lfdp_2 = "e4000000F:D", -- NYI: displacement must be divisible by 4.
|
||||
|
||||
-- Primary opcode 59:
|
||||
fdivs_3 = "ec000024FFF.",
|
||||
fsubs_3 = "ec000028FFF.",
|
||||
|
@ -501,6 +867,200 @@ local map_op = {
|
|||
fmadds_4 = "ec00003aFFFF~.",
|
||||
fnmsubs_4 = "ec00003cFFFF~.",
|
||||
fnmadds_4 = "ec00003eFFFF~.",
|
||||
fcfids_2 = "ec00069cF-F.",
|
||||
fcfidus_2 = "ec00079cF-F.",
|
||||
|
||||
dadd_3 = "ec000004FFF.",
|
||||
dqua_4 = "ec000006FFFZ.",
|
||||
dmul_3 = "ec000044FFF.",
|
||||
drrnd_4 = "ec000046FFFZ.",
|
||||
dscli_3 = "ec000084FF6.",
|
||||
dquai_4 = "ec000086SF~FZ.",
|
||||
dscri_3 = "ec0000c4FF6.",
|
||||
drintx_4 = "ec0000c61F~FZ.",
|
||||
dcmpo_3 = "ec000104XFF",
|
||||
dtstex_3 = "ec000144XFF",
|
||||
dtstdc_3 = "ec000184XF6",
|
||||
dtstdg_3 = "ec0001c4XF6",
|
||||
drintn_4 = "ec0001c61F~FZ.",
|
||||
dctdp_2 = "ec000204F-F.",
|
||||
dctfix_2 = "ec000244F-F.",
|
||||
ddedpd_3 = "ec000284ZF~F.",
|
||||
dxex_2 = "ec0002c4F-F.",
|
||||
dsub_3 = "ec000404FFF.",
|
||||
ddiv_3 = "ec000444FFF.",
|
||||
dcmpu_3 = "ec000504XFF",
|
||||
dtstsf_3 = "ec000544XFF",
|
||||
drsp_2 = "ec000604F-F.",
|
||||
dcffix_2 = "ec000644F-F.",
|
||||
denbcd_3 = "ec000684YF~F.",
|
||||
diex_3 = "ec0006c4FFF.",
|
||||
|
||||
-- Primary opcode 60:
|
||||
xsaddsp_3 = "f0000000QQQ",
|
||||
xsmaddasp_3 = "f0000008QQQ",
|
||||
xxsldwi_4 = "f0000010QQQz",
|
||||
xsrsqrtesp_2 = "f0000028Q-Q",
|
||||
xssqrtsp_2 = "f000002cQ-Q",
|
||||
xxsel_4 = "f0000030QQQQ",
|
||||
xssubsp_3 = "f0000040QQQ",
|
||||
xsmaddmsp_3 = "f0000048QQQ",
|
||||
xxpermdi_4 = "f0000050QQQz",
|
||||
xsresp_2 = "f0000068Q-Q",
|
||||
xsmulsp_3 = "f0000080QQQ",
|
||||
xsmsubasp_3 = "f0000088QQQ",
|
||||
xxmrghw_3 = "f0000090QQQ",
|
||||
xsdivsp_3 = "f00000c0QQQ",
|
||||
xsmsubmsp_3 = "f00000c8QQQ",
|
||||
xsadddp_3 = "f0000100QQQ",
|
||||
xsmaddadp_3 = "f0000108QQQ",
|
||||
xscmpudp_3 = "f0000118XQQ",
|
||||
xscvdpuxws_2 = "f0000120Q-Q",
|
||||
xsrdpi_2 = "f0000124Q-Q",
|
||||
xsrsqrtedp_2 = "f0000128Q-Q",
|
||||
xssqrtdp_2 = "f000012cQ-Q",
|
||||
xssubdp_3 = "f0000140QQQ",
|
||||
xsmaddmdp_3 = "f0000148QQQ",
|
||||
xscmpodp_3 = "f0000158XQQ",
|
||||
xscvdpsxws_2 = "f0000160Q-Q",
|
||||
xsrdpiz_2 = "f0000164Q-Q",
|
||||
xsredp_2 = "f0000168Q-Q",
|
||||
xsmuldp_3 = "f0000180QQQ",
|
||||
xsmsubadp_3 = "f0000188QQQ",
|
||||
xxmrglw_3 = "f0000190QQQ",
|
||||
xsrdpip_2 = "f00001a4Q-Q",
|
||||
xstsqrtdp_2 = "f00001a8X-Q",
|
||||
xsrdpic_2 = "f00001acQ-Q",
|
||||
xsdivdp_3 = "f00001c0QQQ",
|
||||
xsmsubmdp_3 = "f00001c8QQQ",
|
||||
xsrdpim_2 = "f00001e4Q-Q",
|
||||
xstdivdp_3 = "f00001e8XQQ",
|
||||
xvaddsp_3 = "f0000200QQQ",
|
||||
xvmaddasp_3 = "f0000208QQQ",
|
||||
xvcmpeqsp_3 = "f0000218QQQ",
|
||||
xvcvspuxws_2 = "f0000220Q-Q",
|
||||
xvrspi_2 = "f0000224Q-Q",
|
||||
xvrsqrtesp_2 = "f0000228Q-Q",
|
||||
xvsqrtsp_2 = "f000022cQ-Q",
|
||||
xvsubsp_3 = "f0000240QQQ",
|
||||
xvmaddmsp_3 = "f0000248QQQ",
|
||||
xvcmpgtsp_3 = "f0000258QQQ",
|
||||
xvcvspsxws_2 = "f0000260Q-Q",
|
||||
xvrspiz_2 = "f0000264Q-Q",
|
||||
xvresp_2 = "f0000268Q-Q",
|
||||
xvmulsp_3 = "f0000280QQQ",
|
||||
xvmsubasp_3 = "f0000288QQQ",
|
||||
xxspltw_3 = "f0000290QQg~",
|
||||
xvcmpgesp_3 = "f0000298QQQ",
|
||||
xvcvuxwsp_2 = "f00002a0Q-Q",
|
||||
xvrspip_2 = "f00002a4Q-Q",
|
||||
xvtsqrtsp_2 = "f00002a8X-Q",
|
||||
xvrspic_2 = "f00002acQ-Q",
|
||||
xvdivsp_3 = "f00002c0QQQ",
|
||||
xvmsubmsp_3 = "f00002c8QQQ",
|
||||
xvcvsxwsp_2 = "f00002e0Q-Q",
|
||||
xvrspim_2 = "f00002e4Q-Q",
|
||||
xvtdivsp_3 = "f00002e8XQQ",
|
||||
xvadddp_3 = "f0000300QQQ",
|
||||
xvmaddadp_3 = "f0000308QQQ",
|
||||
xvcmpeqdp_3 = "f0000318QQQ",
|
||||
xvcvdpuxws_2 = "f0000320Q-Q",
|
||||
xvrdpi_2 = "f0000324Q-Q",
|
||||
xvrsqrtedp_2 = "f0000328Q-Q",
|
||||
xvsqrtdp_2 = "f000032cQ-Q",
|
||||
xvsubdp_3 = "f0000340QQQ",
|
||||
xvmaddmdp_3 = "f0000348QQQ",
|
||||
xvcmpgtdp_3 = "f0000358QQQ",
|
||||
xvcvdpsxws_2 = "f0000360Q-Q",
|
||||
xvrdpiz_2 = "f0000364Q-Q",
|
||||
xvredp_2 = "f0000368Q-Q",
|
||||
xvmuldp_3 = "f0000380QQQ",
|
||||
xvmsubadp_3 = "f0000388QQQ",
|
||||
xvcmpgedp_3 = "f0000398QQQ",
|
||||
xvcvuxwdp_2 = "f00003a0Q-Q",
|
||||
xvrdpip_2 = "f00003a4Q-Q",
|
||||
xvtsqrtdp_2 = "f00003a8X-Q",
|
||||
xvrdpic_2 = "f00003acQ-Q",
|
||||
xvdivdp_3 = "f00003c0QQQ",
|
||||
xvmsubmdp_3 = "f00003c8QQQ",
|
||||
xvcvsxwdp_2 = "f00003e0Q-Q",
|
||||
xvrdpim_2 = "f00003e4Q-Q",
|
||||
xvtdivdp_3 = "f00003e8XQQ",
|
||||
xsnmaddasp_3 = "f0000408QQQ",
|
||||
xxland_3 = "f0000410QQQ",
|
||||
xscvdpsp_2 = "f0000424Q-Q",
|
||||
xscvdpspn_2 = "f000042cQ-Q",
|
||||
xsnmaddmsp_3 = "f0000448QQQ",
|
||||
xxlandc_3 = "f0000450QQQ",
|
||||
xsrsp_2 = "f0000464Q-Q",
|
||||
xsnmsubasp_3 = "f0000488QQQ",
|
||||
xxlor_3 = "f0000490QQQ",
|
||||
xscvuxdsp_2 = "f00004a0Q-Q",
|
||||
xsnmsubmsp_3 = "f00004c8QQQ",
|
||||
xxlxor_3 = "f00004d0QQQ",
|
||||
xscvsxdsp_2 = "f00004e0Q-Q",
|
||||
xsmaxdp_3 = "f0000500QQQ",
|
||||
xsnmaddadp_3 = "f0000508QQQ",
|
||||
xxlnor_3 = "f0000510QQQ",
|
||||
xscvdpuxds_2 = "f0000520Q-Q",
|
||||
xscvspdp_2 = "f0000524Q-Q",
|
||||
xscvspdpn_2 = "f000052cQ-Q",
|
||||
xsmindp_3 = "f0000540QQQ",
|
||||
xsnmaddmdp_3 = "f0000548QQQ",
|
||||
xxlorc_3 = "f0000550QQQ",
|
||||
xscvdpsxds_2 = "f0000560Q-Q",
|
||||
xsabsdp_2 = "f0000564Q-Q",
|
||||
xscpsgndp_3 = "f0000580QQQ",
|
||||
xsnmsubadp_3 = "f0000588QQQ",
|
||||
xxlnand_3 = "f0000590QQQ",
|
||||
xscvuxddp_2 = "f00005a0Q-Q",
|
||||
xsnabsdp_2 = "f00005a4Q-Q",
|
||||
xsnmsubmdp_3 = "f00005c8QQQ",
|
||||
xxleqv_3 = "f00005d0QQQ",
|
||||
xscvsxddp_2 = "f00005e0Q-Q",
|
||||
xsnegdp_2 = "f00005e4Q-Q",
|
||||
xvmaxsp_3 = "f0000600QQQ",
|
||||
xvnmaddasp_3 = "f0000608QQQ",
|
||||
["xvcmpeqsp._3"] = "f0000618QQQ",
|
||||
xvcvspuxds_2 = "f0000620Q-Q",
|
||||
xvcvdpsp_2 = "f0000624Q-Q",
|
||||
xvminsp_3 = "f0000640QQQ",
|
||||
xvnmaddmsp_3 = "f0000648QQQ",
|
||||
["xvcmpgtsp._3"] = "f0000658QQQ",
|
||||
xvcvspsxds_2 = "f0000660Q-Q",
|
||||
xvabssp_2 = "f0000664Q-Q",
|
||||
xvcpsgnsp_3 = "f0000680QQQ",
|
||||
xvnmsubasp_3 = "f0000688QQQ",
|
||||
["xvcmpgesp._3"] = "f0000698QQQ",
|
||||
xvcvuxdsp_2 = "f00006a0Q-Q",
|
||||
xvnabssp_2 = "f00006a4Q-Q",
|
||||
xvnmsubmsp_3 = "f00006c8QQQ",
|
||||
xvcvsxdsp_2 = "f00006e0Q-Q",
|
||||
xvnegsp_2 = "f00006e4Q-Q",
|
||||
xvmaxdp_3 = "f0000700QQQ",
|
||||
xvnmaddadp_3 = "f0000708QQQ",
|
||||
["xvcmpeqdp._3"] = "f0000718QQQ",
|
||||
xvcvdpuxds_2 = "f0000720Q-Q",
|
||||
xvcvspdp_2 = "f0000724Q-Q",
|
||||
xvmindp_3 = "f0000740QQQ",
|
||||
xvnmaddmdp_3 = "f0000748QQQ",
|
||||
["xvcmpgtdp._3"] = "f0000758QQQ",
|
||||
xvcvdpsxds_2 = "f0000760Q-Q",
|
||||
xvabsdp_2 = "f0000764Q-Q",
|
||||
xvcpsgndp_3 = "f0000780QQQ",
|
||||
xvnmsubadp_3 = "f0000788QQQ",
|
||||
["xvcmpgedp._3"] = "f0000798QQQ",
|
||||
xvcvuxddp_2 = "f00007a0Q-Q",
|
||||
xvnabsdp_2 = "f00007a4Q-Q",
|
||||
xvnmsubmdp_3 = "f00007c8QQQ",
|
||||
xvcvsxddp_2 = "f00007e0Q-Q",
|
||||
xvnegdp_2 = "f00007e4Q-Q",
|
||||
|
||||
-- Primary opcode 61:
|
||||
stfdp_2 = "f4000000F:D", -- NYI: displacement must be divisible by 4.
|
||||
|
||||
-- Primary opcode 62:
|
||||
stq_2 = "f8000002R:D", -- NYI: displacement must be divisible by 8.
|
||||
|
||||
-- Primary opcode 63:
|
||||
fdiv_3 = "fc000024FFF.",
|
||||
|
@ -526,8 +1086,12 @@ local map_op = {
|
|||
frsp_2 = "fc000018F-F.",
|
||||
fctiw_2 = "fc00001cF-F.",
|
||||
fctiwz_2 = "fc00001eF-F.",
|
||||
ftdiv_2 = "fc000100X-F.",
|
||||
fctiwu_2 = "fc00011cF-F.",
|
||||
fctiwuz_2 = "fc00011eF-F.",
|
||||
mtfsfi_2 = "fc00010cAA", -- NYI: upshift.
|
||||
fnabs_2 = "fc000110F-F.",
|
||||
ftsqrt_2 = "fc000140X-F.",
|
||||
fabs_2 = "fc000210F-F.",
|
||||
frin_2 = "fc000310F-F.",
|
||||
friz_2 = "fc000350F-F.",
|
||||
|
@ -537,7 +1101,38 @@ local map_op = {
|
|||
-- NYI: mtfsf, mtfsb0, mtfsb1.
|
||||
fctid_2 = "fc00065cF-F.",
|
||||
fctidz_2 = "fc00065eF-F.",
|
||||
fmrgow_3 = "fc00068cFFF",
|
||||
fcfid_2 = "fc00069cF-F.",
|
||||
fctidu_2 = "fc00075cF-F.",
|
||||
fctiduz_2 = "fc00075eF-F.",
|
||||
fmrgew_3 = "fc00078cFFF",
|
||||
fcfidu_2 = "fc00079cF-F.",
|
||||
|
||||
daddq_3 = "fc000004F:F:F:.",
|
||||
dquaq_4 = "fc000006F:F:F:Z.",
|
||||
dmulq_3 = "fc000044F:F:F:.",
|
||||
drrndq_4 = "fc000046F:F:F:Z.",
|
||||
dscliq_3 = "fc000084F:F:6.",
|
||||
dquaiq_4 = "fc000086SF:~F:Z.",
|
||||
dscriq_3 = "fc0000c4F:F:6.",
|
||||
drintxq_4 = "fc0000c61F:~F:Z.",
|
||||
dcmpoq_3 = "fc000104XF:F:",
|
||||
dtstexq_3 = "fc000144XF:F:",
|
||||
dtstdcq_3 = "fc000184XF:6",
|
||||
dtstdgq_3 = "fc0001c4XF:6",
|
||||
drintnq_4 = "fc0001c61F:~F:Z.",
|
||||
dctqpq_2 = "fc000204F:-F:.",
|
||||
dctfixq_2 = "fc000244F:-F:.",
|
||||
ddedpdq_3 = "fc000284ZF:~F:.",
|
||||
dxexq_2 = "fc0002c4F:-F:.",
|
||||
dsubq_3 = "fc000404F:F:F:.",
|
||||
ddivq_3 = "fc000444F:F:F:.",
|
||||
dcmpuq_3 = "fc000504XF:F:",
|
||||
dtstsfq_3 = "fc000544XF:F:",
|
||||
drdpq_2 = "fc000604F:-F:.",
|
||||
dcffixq_2 = "fc000644F:-F:.",
|
||||
denbcdq_3 = "fc000684YF:~F:.",
|
||||
diexq_3 = "fc0006c4F:FF:.",
|
||||
|
||||
-- Primary opcode 4, SPE APU extension:
|
||||
evaddw_3 = "10000200RRR",
|
||||
|
@ -822,7 +1417,7 @@ local map_op = {
|
|||
do
|
||||
local t = {}
|
||||
for k,v in pairs(map_op) do
|
||||
if sub(v, -1) == "." then
|
||||
if type(v) == "string" and sub(v, -1) == "." then
|
||||
local v2 = sub(v, 1, 7)..char(byte(v, 8)+1)..sub(v, 9, -2)
|
||||
t[sub(k, 1, -3).."."..sub(k, -2)] = v2
|
||||
end
|
||||
|
@ -884,6 +1479,24 @@ local function parse_fpr(expr)
|
|||
werror("bad register name `"..expr.."'")
|
||||
end
|
||||
|
||||
local function parse_vr(expr)
|
||||
local r = match(expr, "^v([1-3]?[0-9])$")
|
||||
if r then
|
||||
r = tonumber(r)
|
||||
if r <= 31 then return r end
|
||||
end
|
||||
werror("bad register name `"..expr.."'")
|
||||
end
|
||||
|
||||
local function parse_vs(expr)
|
||||
local r = match(expr, "^vs([1-6]?[0-9])$")
|
||||
if r then
|
||||
r = tonumber(r)
|
||||
if r <= 63 then return r end
|
||||
end
|
||||
werror("bad register name `"..expr.."'")
|
||||
end
|
||||
|
||||
local function parse_cr(expr)
|
||||
local r = match(expr, "^cr([0-7])$")
|
||||
if r then return tonumber(r) end
|
||||
|
@ -900,8 +1513,30 @@ local function parse_cond(expr)
|
|||
werror("bad condition bit name `"..expr.."'")
|
||||
end
|
||||
|
||||
local parse_ctx = {}
|
||||
|
||||
local loadenv = setfenv and function(s)
|
||||
local code = loadstring(s, "")
|
||||
if code then setfenv(code, parse_ctx) end
|
||||
return code
|
||||
end or function(s)
|
||||
return load(s, "", nil, parse_ctx)
|
||||
end
|
||||
|
||||
-- Try to parse simple arithmetic, too, since some basic ops are aliases.
|
||||
local function parse_number(n)
|
||||
local x = tonumber(n)
|
||||
if x then return x end
|
||||
local code = loadenv("return "..n)
|
||||
if code then
|
||||
local ok, y = pcall(code)
|
||||
if ok then return y end
|
||||
end
|
||||
return nil
|
||||
end
|
||||
|
||||
local function parse_imm(imm, bits, shift, scale, signed)
|
||||
local n = tonumber(imm)
|
||||
local n = parse_number(imm)
|
||||
if n then
|
||||
local m = sar(n, scale)
|
||||
if shl(m, scale) == n then
|
||||
|
@ -914,7 +1549,8 @@ local function parse_imm(imm, bits, shift, scale, signed)
|
|||
end
|
||||
end
|
||||
werror("out of range immediate `"..imm.."'")
|
||||
elseif match(imm, "^r([1-3]?[0-9])$") or
|
||||
elseif match(imm, "^[rfv]([1-3]?[0-9])$") or
|
||||
match(imm, "^vs([1-6]?[0-9])$") or
|
||||
match(imm, "^([%w_]+):(r[1-3]?[0-9])$") then
|
||||
werror("expected immediate operand, got register")
|
||||
else
|
||||
|
@ -924,11 +1560,11 @@ local function parse_imm(imm, bits, shift, scale, signed)
|
|||
end
|
||||
|
||||
local function parse_shiftmask(imm, isshift)
|
||||
local n = tonumber(imm)
|
||||
local n = parse_number(imm)
|
||||
if n then
|
||||
if shr(n, 6) == 0 then
|
||||
local lsb = band(imm, 31)
|
||||
local msb = imm - lsb
|
||||
local lsb = band(n, 31)
|
||||
local msb = n - lsb
|
||||
return isshift and (shl(lsb, 11)+shr(msb, 4)) or (shl(lsb, 6)+msb)
|
||||
end
|
||||
werror("out of range immediate `"..imm.."'")
|
||||
|
@ -936,7 +1572,8 @@ local function parse_shiftmask(imm, isshift)
|
|||
match(imm, "^([%w_]+):(r[1-3]?[0-9])$") then
|
||||
werror("expected immediate operand, got register")
|
||||
else
|
||||
werror("NYI: parameterized 64 bit shift/mask")
|
||||
waction("IMMSH", isshift and 1 or 0, imm)
|
||||
return 0;
|
||||
end
|
||||
end
|
||||
|
||||
|
@ -1011,7 +1648,7 @@ end
|
|||
------------------------------------------------------------------------------
|
||||
|
||||
-- Handle opcodes defined with template strings.
|
||||
map_op[".template__"] = function(params, template, nparams)
|
||||
op_template = function(params, template, nparams)
|
||||
if not params then return sub(template, 9) end
|
||||
local op = tonumber(sub(template, 1, 8), 16)
|
||||
local n, rs = 1, 26
|
||||
|
@ -1027,6 +1664,15 @@ map_op[".template__"] = function(params, template, nparams)
|
|||
rs = rs - 5; op = op + shl(parse_gpr(params[n]), rs); n = n + 1
|
||||
elseif p == "F" then
|
||||
rs = rs - 5; op = op + shl(parse_fpr(params[n]), rs); n = n + 1
|
||||
elseif p == "V" then
|
||||
rs = rs - 5; op = op + shl(parse_vr(params[n]), rs); n = n + 1
|
||||
elseif p == "Q" then
|
||||
local vs = parse_vs(params[n]); n = n + 1; rs = rs - 5
|
||||
local sh = rs == 6 and 2 or 3 + band(shr(rs, 1), 3)
|
||||
op = op + shl(band(vs, 31), rs) + shr(band(vs, 32), sh)
|
||||
elseif p == "q" then
|
||||
local vs = parse_vs(params[n]); n = n + 1
|
||||
op = op + shl(band(vs, 31), 21) + shr(band(vs, 32), 5)
|
||||
elseif p == "A" then
|
||||
rs = rs - 5; op = op + parse_imm(params[n], 5, rs, 0, false); n = n + 1
|
||||
elseif p == "S" then
|
||||
|
@ -1047,6 +1693,26 @@ map_op[".template__"] = function(params, template, nparams)
|
|||
rs = rs - 5; op = op + shl(parse_cond(params[n]), rs); n = n + 1
|
||||
elseif p == "X" then
|
||||
rs = rs - 5; op = op + shl(parse_cr(params[n]), rs+2); n = n + 1
|
||||
elseif p == "1" then
|
||||
rs = rs - 5; op = op + parse_imm(params[n], 1, rs, 0, false); n = n + 1
|
||||
elseif p == "g" then
|
||||
rs = rs - 5; op = op + parse_imm(params[n], 2, rs, 0, false); n = n + 1
|
||||
elseif p == "3" then
|
||||
rs = rs - 5; op = op + parse_imm(params[n], 3, rs, 0, false); n = n + 1
|
||||
elseif p == "P" then
|
||||
rs = rs - 5; op = op + parse_imm(params[n], 4, rs, 0, false); n = n + 1
|
||||
elseif p == "p" then
|
||||
op = op + parse_imm(params[n], 4, rs, 0, false); n = n + 1
|
||||
elseif p == "6" then
|
||||
rs = rs - 6; op = op + parse_imm(params[n], 6, rs, 0, false); n = n + 1
|
||||
elseif p == "Y" then
|
||||
rs = rs - 5; op = op + parse_imm(params[n], 1, rs+4, 0, false); n = n + 1
|
||||
elseif p == "y" then
|
||||
rs = rs - 5; op = op + parse_imm(params[n], 1, rs+3, 0, false); n = n + 1
|
||||
elseif p == "Z" then
|
||||
rs = rs - 5; op = op + parse_imm(params[n], 2, rs+3, 0, false); n = n + 1
|
||||
elseif p == "z" then
|
||||
rs = rs - 5; op = op + parse_imm(params[n], 2, rs+2, 0, false); n = n + 1
|
||||
elseif p == "W" then
|
||||
op = op + parse_cr(params[n]); n = n + 1
|
||||
elseif p == "G" then
|
||||
|
@ -1071,6 +1737,8 @@ map_op[".template__"] = function(params, template, nparams)
|
|||
local lo = band(op, mm)
|
||||
local hi = band(op, shl(mm, 5))
|
||||
op = op - lo - hi + shl(lo, 5) + shr(hi, 5)
|
||||
elseif p == ":" then
|
||||
if band(shr(op, rs), 1) ~= 0 then werror("register pair expected") end
|
||||
elseif p == "-" then
|
||||
rs = rs - 5
|
||||
elseif p == "." then
|
||||
|
@ -1082,6 +1750,8 @@ map_op[".template__"] = function(params, template, nparams)
|
|||
wputpos(pos, op)
|
||||
end
|
||||
|
||||
map_op[".template__"] = op_template
|
||||
|
||||
------------------------------------------------------------------------------
|
||||
|
||||
-- Pseudo-opcode to mark the position where the action list is to be emitted.
|
||||
|
|
6
vendor/luajit/dynasm/dasm_proto.h
vendored
6
vendor/luajit/dynasm/dasm_proto.h
vendored
|
@ -1,6 +1,6 @@
|
|||
/*
|
||||
** DynASM encoding engine prototypes.
|
||||
** Copyright (C) 2005-2015 Mike Pall. All rights reserved.
|
||||
** Copyright (C) 2005-2017 Mike Pall. All rights reserved.
|
||||
** Released under the MIT license. See dynasm.lua for full copyright notice.
|
||||
*/
|
||||
|
||||
|
@ -10,8 +10,8 @@
|
|||
#include <stddef.h>
|
||||
#include <stdarg.h>
|
||||
|
||||
#define DASM_IDENT "DynASM 1.3.0"
|
||||
#define DASM_VERSION 10300 /* 1.3.0 */
|
||||
#define DASM_IDENT "DynASM 1.4.0"
|
||||
#define DASM_VERSION 10400 /* 1.4.0 */
|
||||
|
||||
#ifndef Dst_DECL
|
||||
#define Dst_DECL dasm_State **Dst
|
||||
|
|
2
vendor/luajit/dynasm/dasm_x64.lua
vendored
2
vendor/luajit/dynasm/dasm_x64.lua
vendored
|
@ -1,7 +1,7 @@
|
|||
------------------------------------------------------------------------------
|
||||
-- DynASM x64 module.
|
||||
--
|
||||
-- Copyright (C) 2005-2015 Mike Pall. All rights reserved.
|
||||
-- Copyright (C) 2005-2017 Mike Pall. All rights reserved.
|
||||
-- See dynasm.lua for full copyright notice.
|
||||
------------------------------------------------------------------------------
|
||||
-- This module just sets 64 bit mode for the combined x86/x64 module.
|
||||
|
|
41
vendor/luajit/dynasm/dasm_x86.h
vendored
41
vendor/luajit/dynasm/dasm_x86.h
vendored
|
@ -1,6 +1,6 @@
|
|||
/*
|
||||
** DynASM x86 encoding engine.
|
||||
** Copyright (C) 2005-2015 Mike Pall. All rights reserved.
|
||||
** Copyright (C) 2005-2017 Mike Pall. All rights reserved.
|
||||
** Released under the MIT license. See dynasm.lua for full copyright notice.
|
||||
*/
|
||||
|
||||
|
@ -170,7 +170,7 @@ void dasm_put(Dst_DECL, int start, ...)
|
|||
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 pos = sec->pos, ofs = sec->ofs, mrm = -1;
|
||||
int *b;
|
||||
|
||||
if (pos >= sec->epos) {
|
||||
|
@ -193,7 +193,7 @@ void dasm_put(Dst_DECL, int start, ...)
|
|||
b[pos++] = n;
|
||||
switch (action) {
|
||||
case DASM_DISP:
|
||||
if (n == 0) { if ((mrm&7) == 4) mrm = p[-2]; if ((mrm&7) != 5) break; }
|
||||
if (n == 0) { if (mrm < 0) 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;
|
||||
|
@ -203,10 +203,17 @@ void dasm_put(Dst_DECL, int start, ...)
|
|||
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. */
|
||||
case DASM_VREG: CK((n&-8) == 0 && (n != 4 || (*p&1) == 0), RANGE_VREG);
|
||||
if (*p++ == 1 && *p == DASM_DISP) mrm = n; continue;
|
||||
case DASM_VREG: CK((n&-16) == 0 && (n != 4 || (*p>>5) != 2), RANGE_VREG);
|
||||
if (*p < 0x40 && p[1] == DASM_DISP) mrm = n;
|
||||
if (*p < 0x20 && (n&7) == 4) ofs++;
|
||||
switch ((*p++ >> 3) & 3) {
|
||||
case 3: n |= b[pos-3];
|
||||
case 2: n |= b[pos-2];
|
||||
case 1: if (n <= 7) { b[pos-1] |= 0x10; ofs--; }
|
||||
}
|
||||
continue;
|
||||
}
|
||||
mrm = 4;
|
||||
mrm = -1;
|
||||
} else {
|
||||
int *pl, n;
|
||||
switch (action) {
|
||||
|
@ -391,7 +398,27 @@ int dasm_encode(Dst_DECL, void *buffer)
|
|||
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_VREG: { int t = *p++; if (t >= 2) n<<=3; cp[-1] |= n; break; }
|
||||
case DASM_VREG: {
|
||||
int t = *p++;
|
||||
unsigned char *ex = cp - (t&7);
|
||||
if ((n & 8) && t < 0xa0) {
|
||||
if (*ex & 0x80) ex[1] ^= 0x20 << (t>>6); else *ex ^= 1 << (t>>6);
|
||||
n &= 7;
|
||||
} else if (n & 0x10) {
|
||||
if (*ex & 0x80) {
|
||||
*ex = 0xc5; ex[1] = (ex[1] & 0x80) | ex[2]; ex += 2;
|
||||
}
|
||||
while (++ex < cp) ex[-1] = *ex;
|
||||
if (mark) mark--;
|
||||
cp--;
|
||||
n &= 7;
|
||||
}
|
||||
if (t >= 0xc0) n <<= 4;
|
||||
else if (t >= 0x40) n <<= 3;
|
||||
else if (n == 4 && t < 0x20) { cp[-1] ^= n; *cp++ = 0x20; }
|
||||
cp[-1] ^= n;
|
||||
break;
|
||||
}
|
||||
case DASM_REL_LG: p++; if (n >= 0) goto rel_pc;
|
||||
b++; n = (int)(ptrdiff_t)D->globals[-n];
|
||||
case DASM_REL_A: rel_a: n -= (int)(ptrdiff_t)(cp+4); goto wd; /* !x64 */
|
||||
|
|
533
vendor/luajit/dynasm/dasm_x86.lua
vendored
533
vendor/luajit/dynasm/dasm_x86.lua
vendored
|
@ -1,7 +1,7 @@
|
|||
------------------------------------------------------------------------------
|
||||
-- DynASM x86/x64 module.
|
||||
--
|
||||
-- Copyright (C) 2005-2015 Mike Pall. All rights reserved.
|
||||
-- Copyright (C) 2005-2017 Mike Pall. All rights reserved.
|
||||
-- See dynasm.lua for full copyright notice.
|
||||
------------------------------------------------------------------------------
|
||||
|
||||
|
@ -11,9 +11,9 @@ local x64 = x64
|
|||
local _info = {
|
||||
arch = x64 and "x64" or "x86",
|
||||
description = "DynASM x86/x64 module",
|
||||
version = "1.3.0",
|
||||
vernum = 10300,
|
||||
release = "2011-05-05",
|
||||
version = "1.4.0",
|
||||
vernum = 10400,
|
||||
release = "2015-10-18",
|
||||
author = "Mike Pall",
|
||||
license = "MIT",
|
||||
}
|
||||
|
@ -27,9 +27,9 @@ local assert, unpack, setmetatable = assert, unpack or table.unpack, setmetatabl
|
|||
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 concat, sort, remove = table.concat, table.sort, table.remove
|
||||
local bit = bit or require("bit")
|
||||
local band, shl, shr = bit.band, bit.lshift, bit.rshift
|
||||
local band, bxor, shl, shr = bit.band, bit.bxor, bit.lshift, bit.rshift
|
||||
|
||||
-- Inherited tables and callbacks.
|
||||
local g_opt, g_arch
|
||||
|
@ -41,7 +41,7 @@ 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 (reg/num):
|
||||
"VREG", "SPACE", -- !x64: VREG support NYI.
|
||||
"VREG", "SPACE",
|
||||
-- ptrdiff_t arg, 1 buffer pos (address): !x64
|
||||
"SETLABEL", "REL_A",
|
||||
-- action arg (1 byte) or int arg, 2 buffer pos (link, offset):
|
||||
|
@ -83,6 +83,21 @@ local actargs = { 0 }
|
|||
-- Current number of section buffer positions for dasm_put().
|
||||
local secpos = 1
|
||||
|
||||
-- VREG kind encodings, pre-shifted by 5 bits.
|
||||
local map_vreg = {
|
||||
["modrm.rm.m"] = 0x00,
|
||||
["modrm.rm.r"] = 0x20,
|
||||
["opcode"] = 0x20,
|
||||
["sib.base"] = 0x20,
|
||||
["sib.index"] = 0x40,
|
||||
["modrm.reg"] = 0x80,
|
||||
["vex.v"] = 0xa0,
|
||||
["imm.hi"] = 0xc0,
|
||||
}
|
||||
|
||||
-- Current number of VREG actions contributing to REX/VEX shrinkage.
|
||||
local vreg_shrink_count = 0
|
||||
|
||||
------------------------------------------------------------------------------
|
||||
|
||||
-- Compute action numbers for action names.
|
||||
|
@ -134,6 +149,21 @@ local function waction(action, a, num)
|
|||
if a or num then secpos = secpos + (num or 1) end
|
||||
end
|
||||
|
||||
-- Optionally add a VREG action.
|
||||
local function wvreg(kind, vreg, psz, sk, defer)
|
||||
if not vreg then return end
|
||||
waction("VREG", vreg)
|
||||
local b = assert(map_vreg[kind], "bad vreg kind `"..vreg.."'")
|
||||
if b < (sk or 0) then
|
||||
vreg_shrink_count = vreg_shrink_count + 1
|
||||
end
|
||||
if not defer then
|
||||
b = b + vreg_shrink_count * 8
|
||||
vreg_shrink_count = 0
|
||||
end
|
||||
wputxb(b + (psz or 0))
|
||||
end
|
||||
|
||||
-- Add call to embedded DynASM C code.
|
||||
local function wcall(func, args)
|
||||
wline(format("dasm_%s(Dst, %s);", func, concat(args, ", ")), true)
|
||||
|
@ -299,7 +329,7 @@ local function mkrmap(sz, cl, names)
|
|||
local iname = format("@%s%x%s", sz, i, needrex and "R" or "")
|
||||
if needrex then map_reg_needrex[iname] = true end
|
||||
local name
|
||||
if sz == "o" then name = format("xmm%d", i)
|
||||
if sz == "o" or sz == "y" then name = format("%s%d", cl, i)
|
||||
elseif sz == "f" then name = format("st%d", i)
|
||||
else name = format("r%d%s", i, sz == addrsize and "" or sz) end
|
||||
map_archdef[name] = iname
|
||||
|
@ -326,6 +356,7 @@ mkrmap("w", "Rw", {"ax", "cx", "dx", "bx", "sp", "bp", "si", "di"})
|
|||
mkrmap("b", "Rb", {"al", "cl", "dl", "bl", "ah", "ch", "dh", "bh"})
|
||||
map_reg_valid_index[map_archdef.esp] = false
|
||||
if x64 then map_reg_valid_index[map_archdef.rsp] = false end
|
||||
if x64 then map_reg_needrex[map_archdef.Rb] = true end
|
||||
map_archdef["Ra"] = "@"..addrsize
|
||||
|
||||
-- FP registers (internally tword sized, but use "f" as operand size).
|
||||
|
@ -334,21 +365,24 @@ mkrmap("f", "Rf")
|
|||
-- SSE registers (oword sized, but qword and dword accessible).
|
||||
mkrmap("o", "xmm")
|
||||
|
||||
-- AVX registers (yword sized, but oword, qword and dword accessible).
|
||||
mkrmap("y", "ymm")
|
||||
|
||||
-- Operand size prefixes to codes.
|
||||
local map_opsize = {
|
||||
byte = "b", word = "w", dword = "d", qword = "q", oword = "o", tword = "t",
|
||||
aword = addrsize,
|
||||
byte = "b", word = "w", dword = "d", qword = "q", oword = "o", yword = "y",
|
||||
tword = "t", aword = addrsize,
|
||||
}
|
||||
|
||||
-- Operand size code to number.
|
||||
local map_opsizenum = {
|
||||
b = 1, w = 2, d = 4, q = 8, o = 16, t = 10,
|
||||
b = 1, w = 2, d = 4, q = 8, o = 16, y = 32, t = 10,
|
||||
}
|
||||
|
||||
-- Operand size code to name.
|
||||
local map_opsizename = {
|
||||
b = "byte", w = "word", d = "dword", q = "qword", o = "oword", t = "tword",
|
||||
f = "fpword",
|
||||
b = "byte", w = "word", d = "dword", q = "qword", o = "oword", y = "yword",
|
||||
t = "tword", f = "fpword",
|
||||
}
|
||||
|
||||
-- Valid index register scale factors.
|
||||
|
@ -460,9 +494,45 @@ local function wputszarg(sz, n)
|
|||
end
|
||||
|
||||
-- Put multi-byte opcode with operand-size dependent modifications.
|
||||
local function wputop(sz, op, rex)
|
||||
local function wputop(sz, op, rex, vex, vregr, vregxb)
|
||||
local psz, sk = 0, nil
|
||||
if vex then
|
||||
local tail
|
||||
if vex.m == 1 and band(rex, 11) == 0 then
|
||||
if x64 and vregxb then
|
||||
sk = map_vreg["modrm.reg"]
|
||||
else
|
||||
wputb(0xc5)
|
||||
tail = shl(bxor(band(rex, 4), 4), 5)
|
||||
psz = 3
|
||||
end
|
||||
end
|
||||
if not tail then
|
||||
wputb(0xc4)
|
||||
wputb(shl(bxor(band(rex, 7), 7), 5) + vex.m)
|
||||
tail = shl(band(rex, 8), 4)
|
||||
psz = 4
|
||||
end
|
||||
local reg, vreg = 0, nil
|
||||
if vex.v then
|
||||
reg = vex.v.reg
|
||||
if not reg then werror("bad vex operand") end
|
||||
if reg < 0 then reg = 0; vreg = vex.v.vreg end
|
||||
end
|
||||
if sz == "y" or vex.l then tail = tail + 4 end
|
||||
wputb(tail + shl(bxor(reg, 15), 3) + vex.p)
|
||||
wvreg("vex.v", vreg)
|
||||
rex = 0
|
||||
if op >= 256 then werror("bad vex opcode") end
|
||||
else
|
||||
if rex ~= 0 then
|
||||
if not x64 then werror("bad operand size") end
|
||||
elseif (vregr or vregxb) and x64 then
|
||||
rex = 0x10
|
||||
sk = map_vreg["vex.v"]
|
||||
end
|
||||
end
|
||||
local r
|
||||
if rex ~= 0 and not x64 then werror("bad operand size") end
|
||||
if sz == "w" then wputb(102) end
|
||||
-- Needs >32 bit numbers, but only for crc32 eax, word [ebx]
|
||||
if op >= 4294967296 then r = op%4294967296 wputb((op-r)/4294967296) op = r end
|
||||
|
@ -471,20 +541,20 @@ local function wputop(sz, op, rex)
|
|||
if rex ~= 0 then
|
||||
local opc3 = band(op, 0xffff00)
|
||||
if opc3 == 0x0f3a00 or opc3 == 0x0f3800 then
|
||||
wputb(64 + band(rex, 15)); rex = 0
|
||||
wputb(64 + band(rex, 15)); rex = 0; psz = 2
|
||||
end
|
||||
end
|
||||
wputb(shr(op, 16)); op = band(op, 0xffff)
|
||||
wputb(shr(op, 16)); op = band(op, 0xffff); psz = psz + 1
|
||||
end
|
||||
if op >= 256 then
|
||||
local b = shr(op, 8)
|
||||
if b == 15 and rex ~= 0 then wputb(64 + band(rex, 15)); rex = 0 end
|
||||
wputb(b)
|
||||
op = band(op, 255)
|
||||
if b == 15 and rex ~= 0 then wputb(64 + band(rex, 15)); rex = 0; psz = 2 end
|
||||
wputb(b); op = band(op, 255); psz = psz + 1
|
||||
end
|
||||
if rex ~= 0 then wputb(64 + band(rex, 15)) end
|
||||
if rex ~= 0 then wputb(64 + band(rex, 15)); psz = 2 end
|
||||
if sz == "b" then op = op - 1 end
|
||||
wputb(op)
|
||||
return psz, sk
|
||||
end
|
||||
|
||||
-- Put ModRM or SIB formatted byte.
|
||||
|
@ -494,7 +564,7 @@ local function wputmodrm(m, s, rm, vs, vrm)
|
|||
end
|
||||
|
||||
-- Put ModRM/SIB plus optional displacement.
|
||||
local function wputmrmsib(t, imark, s, vsreg)
|
||||
local function wputmrmsib(t, imark, s, vsreg, psz, sk)
|
||||
local vreg, vxreg
|
||||
local reg, xreg = t.reg, t.xreg
|
||||
if reg and reg < 0 then reg = 0; vreg = t.vreg end
|
||||
|
@ -504,8 +574,8 @@ local function wputmrmsib(t, imark, s, vsreg)
|
|||
-- Register mode.
|
||||
if sub(t.mode, 1, 1) == "r" then
|
||||
wputmodrm(3, s, reg)
|
||||
if vsreg then waction("VREG", vsreg); wputxb(2) end
|
||||
if vreg then waction("VREG", vreg); wputxb(0) end
|
||||
wvreg("modrm.reg", vsreg, psz+1, sk, vreg)
|
||||
wvreg("modrm.rm.r", vreg, psz+1, sk)
|
||||
return
|
||||
end
|
||||
|
||||
|
@ -519,21 +589,22 @@ local function wputmrmsib(t, imark, s, vsreg)
|
|||
-- [xreg*xsc+disp] -> (0, s, esp) (xsc, xreg, ebp)
|
||||
wputmodrm(0, s, 4)
|
||||
if imark == "I" then waction("MARK") end
|
||||
if vsreg then waction("VREG", vsreg); wputxb(2) end
|
||||
wvreg("modrm.reg", vsreg, psz+1, sk, vxreg)
|
||||
wputmodrm(t.xsc, xreg, 5)
|
||||
if vxreg then waction("VREG", vxreg); wputxb(3) end
|
||||
wvreg("sib.index", vxreg, psz+2, sk)
|
||||
else
|
||||
-- Pure 32 bit displacement.
|
||||
if x64 and tdisp ~= "table" then
|
||||
wputmodrm(0, s, 4) -- [disp] -> (0, s, esp) (0, esp, ebp)
|
||||
wvreg("modrm.reg", vsreg, psz+1, sk)
|
||||
if imark == "I" then waction("MARK") end
|
||||
wputmodrm(0, 4, 5)
|
||||
else
|
||||
riprel = x64
|
||||
wputmodrm(0, s, 5) -- [disp|rip-label] -> (0, s, ebp)
|
||||
wvreg("modrm.reg", vsreg, psz+1, sk)
|
||||
if imark == "I" then waction("MARK") end
|
||||
end
|
||||
if vsreg then waction("VREG", vsreg); wputxb(2) end
|
||||
end
|
||||
if riprel then -- Emit rip-relative displacement.
|
||||
if match("UWSiI", imark) then
|
||||
|
@ -561,16 +632,16 @@ local function wputmrmsib(t, imark, s, vsreg)
|
|||
if xreg or band(reg, 7) == 4 then
|
||||
wputmodrm(m or 2, s, 4) -- ModRM.
|
||||
if m == nil or imark == "I" then waction("MARK") end
|
||||
if vsreg then waction("VREG", vsreg); wputxb(2) end
|
||||
wvreg("modrm.reg", vsreg, psz+1, sk, vxreg or vreg)
|
||||
wputmodrm(t.xsc or 0, xreg or 4, reg) -- SIB.
|
||||
if vxreg then waction("VREG", vxreg); wputxb(3) end
|
||||
if vreg then waction("VREG", vreg); wputxb(1) end
|
||||
wvreg("sib.index", vxreg, psz+2, sk, vreg)
|
||||
wvreg("sib.base", vreg, psz+2, sk)
|
||||
else
|
||||
wputmodrm(m or 2, s, reg) -- ModRM.
|
||||
if (imark == "I" and (m == 1 or m == 2)) or
|
||||
(m == nil and (vsreg or vreg)) then waction("MARK") end
|
||||
if vsreg then waction("VREG", vsreg); wputxb(2) end
|
||||
if vreg then waction("VREG", vreg); wputxb(1) end
|
||||
wvreg("modrm.reg", vsreg, psz+1, sk, vreg)
|
||||
wvreg("modrm.rm.m", vreg, psz+1, sk)
|
||||
end
|
||||
|
||||
-- Put displacement.
|
||||
|
@ -881,9 +952,15 @@ end
|
|||
-- "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.
|
||||
-- "u" Use VEX encoding, vvvv unused.
|
||||
-- "v"/"V" Use VEX encoding, vvvv from 1st/2nd operand (the operand is
|
||||
-- removed from the list used by future characters).
|
||||
-- "L" Force VEX.L
|
||||
--
|
||||
-- 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 4 bit immediate from the last register operand,
|
||||
-- followed by 4 zero bits.
|
||||
-- "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.
|
||||
|
@ -1081,10 +1158,11 @@ local map_op = {
|
|||
btr_2 = "mrqdw:0FB3Rm|miqdw:0FBA6mU",
|
||||
bts_2 = "mrqdw:0FABRm|miqdw:0FBA5mU",
|
||||
|
||||
shld_3 = "mriqdw:0FA4RmU|mrCqdw:0FA5Rm",
|
||||
shrd_3 = "mriqdw:0FACRmU|mrCqdw:0FADRm",
|
||||
shld_3 = "mriqdw:0FA4RmU|mrC/qq:0FA5Rm|mrC/dd:|mrC/ww:",
|
||||
shrd_3 = "mriqdw:0FACRmU|mrC/qq:0FADRm|mrC/dd:|mrC/ww:",
|
||||
|
||||
rdtsc_0 = "0F31", -- P1+
|
||||
rdpmc_0 = "0F33", -- P6+
|
||||
cpuid_0 = "0FA2", -- P1+
|
||||
|
||||
-- floating point ops
|
||||
|
@ -1190,7 +1268,7 @@ local map_op = {
|
|||
cvtsi2sd_2 = "rm/od:F20F2ArM|rm/oq:F20F2ArXM",
|
||||
cvtsi2ss_2 = "rm/od:F30F2ArM|rm/oq:F30F2ArXM",
|
||||
cvtss2sd_2 = "rro:F30F5ArM|rx/od:",
|
||||
cvtss2si_2 = "rr/do:F20F2CrM|rr/qo:|rxd:|rx/qd:",
|
||||
cvtss2si_2 = "rr/do:F30F2DrM|rr/qo:|rxd:|rx/qd:",
|
||||
cvttpd2dq_2 = "rmo:660FE6rM",
|
||||
cvttps2dq_2 = "rmo:F30F5BrM",
|
||||
cvttsd2si_2 = "rr/do:F20F2CrM|rr/qo:|rx/dq:|rxq:",
|
||||
|
@ -1225,46 +1303,14 @@ local map_op = {
|
|||
movups_2 = "rmo:0F10rM|mro:0F11Rm",
|
||||
orpd_2 = "rmo:660F56rM",
|
||||
orps_2 = "rmo:0F56rM",
|
||||
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",
|
||||
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|xri/wo:660F3A15nrMU", -- Mem op: SSE4.1 only.
|
||||
pextrw_3 = "rri/do:660FC5rMU|xri/wo:660F3A15nRmU", -- Mem op: SSE4.1 only.
|
||||
pinsrw_3 = "rri/od:660FC4rMU|rxi/ow:",
|
||||
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",
|
||||
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",
|
||||
pshufd_3 = "rmio:660F70rMU",
|
||||
pshufhw_3 = "rmio:F30F70rMU",
|
||||
pshuflw_3 = "rmio:F20F70rMU",
|
||||
|
@ -1278,23 +1324,6 @@ local map_op = {
|
|||
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 = "rro:F30F53rM|rx/od:",
|
||||
rsqrtps_2 = "rmo:0F52rM",
|
||||
|
@ -1352,7 +1381,7 @@ local map_op = {
|
|||
dpps_3 = "rmio:660F3A40rMU",
|
||||
extractps_3 = "mri/do:660F3A17RmU|rri/qo:660F3A17RXmU",
|
||||
insertps_3 = "rrio:660F3A41rMU|rxi/od:",
|
||||
movntdqa_2 = "rmo:660F382ArM",
|
||||
movntdqa_2 = "rxo:660F382ArM",
|
||||
mpsadbw_3 = "rmio:660F3A42rMU",
|
||||
packusdw_2 = "rmo:660F382BrM",
|
||||
pblendvb_3 = "rmRo:660F3810rM",
|
||||
|
@ -1412,6 +1441,242 @@ local map_op = {
|
|||
movntsd_2 = "xr/qo:nF20F2BRm",
|
||||
movntss_2 = "xr/do:F30F2BRm",
|
||||
-- popcnt is also in SSE4.2
|
||||
|
||||
-- AES-NI
|
||||
aesdec_2 = "rmo:660F38DErM",
|
||||
aesdeclast_2 = "rmo:660F38DFrM",
|
||||
aesenc_2 = "rmo:660F38DCrM",
|
||||
aesenclast_2 = "rmo:660F38DDrM",
|
||||
aesimc_2 = "rmo:660F38DBrM",
|
||||
aeskeygenassist_3 = "rmio:660F3ADFrMU",
|
||||
pclmulqdq_3 = "rmio:660F3A44rMU",
|
||||
|
||||
-- AVX FP ops
|
||||
vaddsubpd_3 = "rrmoy:660FVD0rM",
|
||||
vaddsubps_3 = "rrmoy:F20FVD0rM",
|
||||
vandpd_3 = "rrmoy:660FV54rM",
|
||||
vandps_3 = "rrmoy:0FV54rM",
|
||||
vandnpd_3 = "rrmoy:660FV55rM",
|
||||
vandnps_3 = "rrmoy:0FV55rM",
|
||||
vblendpd_4 = "rrmioy:660F3AV0DrMU",
|
||||
vblendps_4 = "rrmioy:660F3AV0CrMU",
|
||||
vblendvpd_4 = "rrmroy:660F3AV4BrMs",
|
||||
vblendvps_4 = "rrmroy:660F3AV4ArMs",
|
||||
vbroadcastf128_2 = "rx/yo:660F38u1ArM",
|
||||
vcmppd_4 = "rrmioy:660FVC2rMU",
|
||||
vcmpps_4 = "rrmioy:0FVC2rMU",
|
||||
vcmpsd_4 = "rrrio:F20FVC2rMU|rrxi/ooq:",
|
||||
vcmpss_4 = "rrrio:F30FVC2rMU|rrxi/ood:",
|
||||
vcomisd_2 = "rro:660Fu2FrM|rx/oq:",
|
||||
vcomiss_2 = "rro:0Fu2FrM|rx/od:",
|
||||
vcvtdq2pd_2 = "rro:F30FuE6rM|rx/oq:|rm/yo:",
|
||||
vcvtdq2ps_2 = "rmoy:0Fu5BrM",
|
||||
vcvtpd2dq_2 = "rmoy:F20FuE6rM",
|
||||
vcvtpd2ps_2 = "rmoy:660Fu5ArM",
|
||||
vcvtps2dq_2 = "rmoy:660Fu5BrM",
|
||||
vcvtps2pd_2 = "rro:0Fu5ArM|rx/oq:|rm/yo:",
|
||||
vcvtsd2si_2 = "rr/do:F20Fu2DrM|rx/dq:|rr/qo:|rxq:",
|
||||
vcvtsd2ss_3 = "rrro:F20FV5ArM|rrx/ooq:",
|
||||
vcvtsi2sd_3 = "rrm/ood:F20FV2ArM|rrm/ooq:F20FVX2ArM",
|
||||
vcvtsi2ss_3 = "rrm/ood:F30FV2ArM|rrm/ooq:F30FVX2ArM",
|
||||
vcvtss2sd_3 = "rrro:F30FV5ArM|rrx/ood:",
|
||||
vcvtss2si_2 = "rr/do:F30Fu2DrM|rxd:|rr/qo:|rx/qd:",
|
||||
vcvttpd2dq_2 = "rmo:660FuE6rM|rm/oy:660FuLE6rM",
|
||||
vcvttps2dq_2 = "rmoy:F30Fu5BrM",
|
||||
vcvttsd2si_2 = "rr/do:F20Fu2CrM|rx/dq:|rr/qo:|rxq:",
|
||||
vcvttss2si_2 = "rr/do:F30Fu2CrM|rxd:|rr/qo:|rx/qd:",
|
||||
vdppd_4 = "rrmio:660F3AV41rMU",
|
||||
vdpps_4 = "rrmioy:660F3AV40rMU",
|
||||
vextractf128_3 = "mri/oy:660F3AuL19RmU",
|
||||
vextractps_3 = "mri/do:660F3Au17RmU",
|
||||
vhaddpd_3 = "rrmoy:660FV7CrM",
|
||||
vhaddps_3 = "rrmoy:F20FV7CrM",
|
||||
vhsubpd_3 = "rrmoy:660FV7DrM",
|
||||
vhsubps_3 = "rrmoy:F20FV7DrM",
|
||||
vinsertf128_4 = "rrmi/yyo:660F3AV18rMU",
|
||||
vinsertps_4 = "rrrio:660F3AV21rMU|rrxi/ood:",
|
||||
vldmxcsr_1 = "xd:0FuAE2m",
|
||||
vmaskmovps_3 = "rrxoy:660F38V2CrM|xrroy:660F38V2ERm",
|
||||
vmaskmovpd_3 = "rrxoy:660F38V2DrM|xrroy:660F38V2FRm",
|
||||
vmovapd_2 = "rmoy:660Fu28rM|mroy:660Fu29Rm",
|
||||
vmovaps_2 = "rmoy:0Fu28rM|mroy:0Fu29Rm",
|
||||
vmovd_2 = "rm/od:660Fu6ErM|rm/oq:660FuX6ErM|mr/do:660Fu7ERm|mr/qo:",
|
||||
vmovq_2 = "rro:F30Fu7ErM|rx/oq:|xr/qo:660FuD6Rm",
|
||||
vmovddup_2 = "rmy:F20Fu12rM|rro:|rx/oq:",
|
||||
vmovhlps_3 = "rrro:0FV12rM",
|
||||
vmovhpd_2 = "xr/qo:660Fu17Rm",
|
||||
vmovhpd_3 = "rrx/ooq:660FV16rM",
|
||||
vmovhps_2 = "xr/qo:0Fu17Rm",
|
||||
vmovhps_3 = "rrx/ooq:0FV16rM",
|
||||
vmovlhps_3 = "rrro:0FV16rM",
|
||||
vmovlpd_2 = "xr/qo:660Fu13Rm",
|
||||
vmovlpd_3 = "rrx/ooq:660FV12rM",
|
||||
vmovlps_2 = "xr/qo:0Fu13Rm",
|
||||
vmovlps_3 = "rrx/ooq:0FV12rM",
|
||||
vmovmskpd_2 = "rr/do:660Fu50rM|rr/dy:660FuL50rM",
|
||||
vmovmskps_2 = "rr/do:0Fu50rM|rr/dy:0FuL50rM",
|
||||
vmovntpd_2 = "xroy:660Fu2BRm",
|
||||
vmovntps_2 = "xroy:0Fu2BRm",
|
||||
vmovsd_2 = "rx/oq:F20Fu10rM|xr/qo:F20Fu11Rm",
|
||||
vmovsd_3 = "rrro:F20FV10rM",
|
||||
vmovshdup_2 = "rmoy:F30Fu16rM",
|
||||
vmovsldup_2 = "rmoy:F30Fu12rM",
|
||||
vmovss_2 = "rx/od:F30Fu10rM|xr/do:F30Fu11Rm",
|
||||
vmovss_3 = "rrro:F30FV10rM",
|
||||
vmovupd_2 = "rmoy:660Fu10rM|mroy:660Fu11Rm",
|
||||
vmovups_2 = "rmoy:0Fu10rM|mroy:0Fu11Rm",
|
||||
vorpd_3 = "rrmoy:660FV56rM",
|
||||
vorps_3 = "rrmoy:0FV56rM",
|
||||
vpermilpd_3 = "rrmoy:660F38V0DrM|rmioy:660F3Au05rMU",
|
||||
vpermilps_3 = "rrmoy:660F38V0CrM|rmioy:660F3Au04rMU",
|
||||
vperm2f128_4 = "rrmiy:660F3AV06rMU",
|
||||
vptestpd_2 = "rmoy:660F38u0FrM",
|
||||
vptestps_2 = "rmoy:660F38u0ErM",
|
||||
vrcpps_2 = "rmoy:0Fu53rM",
|
||||
vrcpss_3 = "rrro:F30FV53rM|rrx/ood:",
|
||||
vrsqrtps_2 = "rmoy:0Fu52rM",
|
||||
vrsqrtss_3 = "rrro:F30FV52rM|rrx/ood:",
|
||||
vroundpd_3 = "rmioy:660F3AV09rMU",
|
||||
vroundps_3 = "rmioy:660F3AV08rMU",
|
||||
vroundsd_4 = "rrrio:660F3AV0BrMU|rrxi/ooq:",
|
||||
vroundss_4 = "rrrio:660F3AV0ArMU|rrxi/ood:",
|
||||
vshufpd_4 = "rrmioy:660FVC6rMU",
|
||||
vshufps_4 = "rrmioy:0FVC6rMU",
|
||||
vsqrtps_2 = "rmoy:0Fu51rM",
|
||||
vsqrtss_2 = "rro:F30Fu51rM|rx/od:",
|
||||
vsqrtpd_2 = "rmoy:660Fu51rM",
|
||||
vsqrtsd_2 = "rro:F20Fu51rM|rx/oq:",
|
||||
vstmxcsr_1 = "xd:0FuAE3m",
|
||||
vucomisd_2 = "rro:660Fu2ErM|rx/oq:",
|
||||
vucomiss_2 = "rro:0Fu2ErM|rx/od:",
|
||||
vunpckhpd_3 = "rrmoy:660FV15rM",
|
||||
vunpckhps_3 = "rrmoy:0FV15rM",
|
||||
vunpcklpd_3 = "rrmoy:660FV14rM",
|
||||
vunpcklps_3 = "rrmoy:0FV14rM",
|
||||
vxorpd_3 = "rrmoy:660FV57rM",
|
||||
vxorps_3 = "rrmoy:0FV57rM",
|
||||
vzeroall_0 = "0FuL77",
|
||||
vzeroupper_0 = "0Fu77",
|
||||
|
||||
-- AVX2 FP ops
|
||||
vbroadcastss_2 = "rx/od:660F38u18rM|rx/yd:|rro:|rr/yo:",
|
||||
vbroadcastsd_2 = "rx/yq:660F38u19rM|rr/yo:",
|
||||
-- *vgather* (!vsib)
|
||||
vpermpd_3 = "rmiy:660F3AuX01rMU",
|
||||
vpermps_3 = "rrmy:660F38V16rM",
|
||||
|
||||
-- AVX, AVX2 integer ops
|
||||
-- In general, xmm requires AVX, ymm requires AVX2.
|
||||
vaesdec_3 = "rrmo:660F38VDErM",
|
||||
vaesdeclast_3 = "rrmo:660F38VDFrM",
|
||||
vaesenc_3 = "rrmo:660F38VDCrM",
|
||||
vaesenclast_3 = "rrmo:660F38VDDrM",
|
||||
vaesimc_2 = "rmo:660F38uDBrM",
|
||||
vaeskeygenassist_3 = "rmio:660F3AuDFrMU",
|
||||
vlddqu_2 = "rxoy:F20FuF0rM",
|
||||
vmaskmovdqu_2 = "rro:660FuF7rM",
|
||||
vmovdqa_2 = "rmoy:660Fu6FrM|mroy:660Fu7FRm",
|
||||
vmovdqu_2 = "rmoy:F30Fu6FrM|mroy:F30Fu7FRm",
|
||||
vmovntdq_2 = "xroy:660FuE7Rm",
|
||||
vmovntdqa_2 = "rxoy:660F38u2ArM",
|
||||
vmpsadbw_4 = "rrmioy:660F3AV42rMU",
|
||||
vpabsb_2 = "rmoy:660F38u1CrM",
|
||||
vpabsd_2 = "rmoy:660F38u1ErM",
|
||||
vpabsw_2 = "rmoy:660F38u1DrM",
|
||||
vpackusdw_3 = "rrmoy:660F38V2BrM",
|
||||
vpalignr_4 = "rrmioy:660F3AV0FrMU",
|
||||
vpblendvb_4 = "rrmroy:660F3AV4CrMs",
|
||||
vpblendw_4 = "rrmioy:660F3AV0ErMU",
|
||||
vpclmulqdq_4 = "rrmio:660F3AV44rMU",
|
||||
vpcmpeqq_3 = "rrmoy:660F38V29rM",
|
||||
vpcmpestri_3 = "rmio:660F3Au61rMU",
|
||||
vpcmpestrm_3 = "rmio:660F3Au60rMU",
|
||||
vpcmpgtq_3 = "rrmoy:660F38V37rM",
|
||||
vpcmpistri_3 = "rmio:660F3Au63rMU",
|
||||
vpcmpistrm_3 = "rmio:660F3Au62rMU",
|
||||
vpextrb_3 = "rri/do:660F3Au14nRmU|rri/qo:|xri/bo:",
|
||||
vpextrw_3 = "rri/do:660FuC5rMU|xri/wo:660F3Au15nRmU",
|
||||
vpextrd_3 = "mri/do:660F3Au16RmU",
|
||||
vpextrq_3 = "mri/qo:660F3Au16RmU",
|
||||
vphaddw_3 = "rrmoy:660F38V01rM",
|
||||
vphaddd_3 = "rrmoy:660F38V02rM",
|
||||
vphaddsw_3 = "rrmoy:660F38V03rM",
|
||||
vphminposuw_2 = "rmo:660F38u41rM",
|
||||
vphsubw_3 = "rrmoy:660F38V05rM",
|
||||
vphsubd_3 = "rrmoy:660F38V06rM",
|
||||
vphsubsw_3 = "rrmoy:660F38V07rM",
|
||||
vpinsrb_4 = "rrri/ood:660F3AV20rMU|rrxi/oob:",
|
||||
vpinsrw_4 = "rrri/ood:660FVC4rMU|rrxi/oow:",
|
||||
vpinsrd_4 = "rrmi/ood:660F3AV22rMU",
|
||||
vpinsrq_4 = "rrmi/ooq:660F3AVX22rMU",
|
||||
vpmaddubsw_3 = "rrmoy:660F38V04rM",
|
||||
vpmaxsb_3 = "rrmoy:660F38V3CrM",
|
||||
vpmaxsd_3 = "rrmoy:660F38V3DrM",
|
||||
vpmaxuw_3 = "rrmoy:660F38V3ErM",
|
||||
vpmaxud_3 = "rrmoy:660F38V3FrM",
|
||||
vpminsb_3 = "rrmoy:660F38V38rM",
|
||||
vpminsd_3 = "rrmoy:660F38V39rM",
|
||||
vpminuw_3 = "rrmoy:660F38V3ArM",
|
||||
vpminud_3 = "rrmoy:660F38V3BrM",
|
||||
vpmovmskb_2 = "rr/do:660FuD7rM|rr/dy:660FuLD7rM",
|
||||
vpmovsxbw_2 = "rroy:660F38u20rM|rx/oq:|rx/yo:",
|
||||
vpmovsxbd_2 = "rroy:660F38u21rM|rx/od:|rx/yq:",
|
||||
vpmovsxbq_2 = "rroy:660F38u22rM|rx/ow:|rx/yd:",
|
||||
vpmovsxwd_2 = "rroy:660F38u23rM|rx/oq:|rx/yo:",
|
||||
vpmovsxwq_2 = "rroy:660F38u24rM|rx/od:|rx/yq:",
|
||||
vpmovsxdq_2 = "rroy:660F38u25rM|rx/oq:|rx/yo:",
|
||||
vpmovzxbw_2 = "rroy:660F38u30rM|rx/oq:|rx/yo:",
|
||||
vpmovzxbd_2 = "rroy:660F38u31rM|rx/od:|rx/yq:",
|
||||
vpmovzxbq_2 = "rroy:660F38u32rM|rx/ow:|rx/yd:",
|
||||
vpmovzxwd_2 = "rroy:660F38u33rM|rx/oq:|rx/yo:",
|
||||
vpmovzxwq_2 = "rroy:660F38u34rM|rx/od:|rx/yq:",
|
||||
vpmovzxdq_2 = "rroy:660F38u35rM|rx/oq:|rx/yo:",
|
||||
vpmuldq_3 = "rrmoy:660F38V28rM",
|
||||
vpmulhrsw_3 = "rrmoy:660F38V0BrM",
|
||||
vpmulld_3 = "rrmoy:660F38V40rM",
|
||||
vpshufb_3 = "rrmoy:660F38V00rM",
|
||||
vpshufd_3 = "rmioy:660Fu70rMU",
|
||||
vpshufhw_3 = "rmioy:F30Fu70rMU",
|
||||
vpshuflw_3 = "rmioy:F20Fu70rMU",
|
||||
vpsignb_3 = "rrmoy:660F38V08rM",
|
||||
vpsignw_3 = "rrmoy:660F38V09rM",
|
||||
vpsignd_3 = "rrmoy:660F38V0ArM",
|
||||
vpslldq_3 = "rrioy:660Fv737mU",
|
||||
vpsllw_3 = "rrmoy:660FVF1rM|rrioy:660Fv716mU",
|
||||
vpslld_3 = "rrmoy:660FVF2rM|rrioy:660Fv726mU",
|
||||
vpsllq_3 = "rrmoy:660FVF3rM|rrioy:660Fv736mU",
|
||||
vpsraw_3 = "rrmoy:660FVE1rM|rrioy:660Fv714mU",
|
||||
vpsrad_3 = "rrmoy:660FVE2rM|rrioy:660Fv724mU",
|
||||
vpsrldq_3 = "rrioy:660Fv733mU",
|
||||
vpsrlw_3 = "rrmoy:660FVD1rM|rrioy:660Fv712mU",
|
||||
vpsrld_3 = "rrmoy:660FVD2rM|rrioy:660Fv722mU",
|
||||
vpsrlq_3 = "rrmoy:660FVD3rM|rrioy:660Fv732mU",
|
||||
vptest_2 = "rmoy:660F38u17rM",
|
||||
|
||||
-- AVX2 integer ops
|
||||
vbroadcasti128_2 = "rx/yo:660F38u5ArM",
|
||||
vinserti128_4 = "rrmi/yyo:660F3AV38rMU",
|
||||
vextracti128_3 = "mri/oy:660F3AuL39RmU",
|
||||
vpblendd_4 = "rrmioy:660F3AV02rMU",
|
||||
vpbroadcastb_2 = "rro:660F38u78rM|rx/ob:|rr/yo:|rx/yb:",
|
||||
vpbroadcastw_2 = "rro:660F38u79rM|rx/ow:|rr/yo:|rx/yw:",
|
||||
vpbroadcastd_2 = "rro:660F38u58rM|rx/od:|rr/yo:|rx/yd:",
|
||||
vpbroadcastq_2 = "rro:660F38u59rM|rx/oq:|rr/yo:|rx/yq:",
|
||||
vpermd_3 = "rrmy:660F38V36rM",
|
||||
vpermq_3 = "rmiy:660F3AuX00rMU",
|
||||
-- *vpgather* (!vsib)
|
||||
vperm2i128_4 = "rrmiy:660F3AV46rMU",
|
||||
vpmaskmovd_3 = "rrxoy:660F38V8CrM|xrroy:660F38V8ERm",
|
||||
vpmaskmovq_3 = "rrxoy:660F38VX8CrM|xrroy:660F38VX8ERm",
|
||||
vpsllvd_3 = "rrmoy:660F38V47rM",
|
||||
vpsllvq_3 = "rrmoy:660F38VX47rM",
|
||||
vpsravd_3 = "rrmoy:660F38V46rM",
|
||||
vpsrlvd_3 = "rrmoy:660F38V45rM",
|
||||
vpsrlvq_3 = "rrmoy:660F38VX45rM",
|
||||
|
||||
-- Intel ADX
|
||||
adcx_2 = "rmqd:660F38F6rM",
|
||||
adox_2 = "rmqd:F30F38F6rM",
|
||||
}
|
||||
|
||||
------------------------------------------------------------------------------
|
||||
|
@ -1462,28 +1727,58 @@ for cc,n in pairs{ b=0, e=1, be=2, u=3, nb=4, ne=5, nbe=6, nu=7 } do
|
|||
map_op["fcmov"..cc.."_2"] = format("Fff:%04XR", nc) -- P6+
|
||||
end
|
||||
|
||||
-- SSE FP arithmetic ops.
|
||||
-- SSE / AVX 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)
|
||||
if n ~= 1 then
|
||||
map_op["v"..name.."ps_3"] = format("rrmoy:0FV5%XrM", n)
|
||||
map_op["v"..name.."ss_3"] = format("rrro:F30FV5%XrM|rrx/ood:", n)
|
||||
map_op["v"..name.."pd_3"] = format("rrmoy:660FV5%XrM", n)
|
||||
map_op["v"..name.."sd_3"] = format("rrro:F20FV5%XrM|rrx/ooq:", n)
|
||||
end
|
||||
end
|
||||
|
||||
-- SSE2 / AVX / AVX2 integer arithmetic ops (66 0F leaf).
|
||||
for name,n in pairs{
|
||||
paddb = 0xFC, paddw = 0xFD, paddd = 0xFE, paddq = 0xD4,
|
||||
paddsb = 0xEC, paddsw = 0xED, packssdw = 0x6B,
|
||||
packsswb = 0x63, packuswb = 0x67, paddusb = 0xDC,
|
||||
paddusw = 0xDD, pand = 0xDB, pandn = 0xDF, pavgb = 0xE0,
|
||||
pavgw = 0xE3, pcmpeqb = 0x74, pcmpeqd = 0x76,
|
||||
pcmpeqw = 0x75, pcmpgtb = 0x64, pcmpgtd = 0x66,
|
||||
pcmpgtw = 0x65, pmaddwd = 0xF5, pmaxsw = 0xEE,
|
||||
pmaxub = 0xDE, pminsw = 0xEA, pminub = 0xDA,
|
||||
pmulhuw = 0xE4, pmulhw = 0xE5, pmullw = 0xD5,
|
||||
pmuludq = 0xF4, por = 0xEB, psadbw = 0xF6, psubb = 0xF8,
|
||||
psubw = 0xF9, psubd = 0xFA, psubq = 0xFB, psubsb = 0xE8,
|
||||
psubsw = 0xE9, psubusb = 0xD8, psubusw = 0xD9,
|
||||
punpckhbw = 0x68, punpckhwd = 0x69, punpckhdq = 0x6A,
|
||||
punpckhqdq = 0x6D, punpcklbw = 0x60, punpcklwd = 0x61,
|
||||
punpckldq = 0x62, punpcklqdq = 0x6C, pxor = 0xEF
|
||||
} do
|
||||
map_op[name.."_2"] = format("rmo:660F%02XrM", n)
|
||||
map_op["v"..name.."_3"] = format("rrmoy:660FV%02XrM", n)
|
||||
end
|
||||
|
||||
------------------------------------------------------------------------------
|
||||
|
||||
local map_vexarg = { u = false, v = 1, V = 2 }
|
||||
|
||||
-- Process pattern string.
|
||||
local function dopattern(pat, args, sz, op, needrex)
|
||||
local digit, addin
|
||||
local digit, addin, vex
|
||||
local opcode = 0
|
||||
local szov = sz
|
||||
local narg = 1
|
||||
local rex = 0
|
||||
|
||||
-- Limit number of section buffer positions used by a single dasm_put().
|
||||
-- A single opcode needs a maximum of 5 positions.
|
||||
if secpos+5 > maxsecpos then wflush() end
|
||||
-- A single opcode needs a maximum of 6 positions.
|
||||
if secpos+6 > maxsecpos then wflush() end
|
||||
|
||||
-- Process each character.
|
||||
for c in gmatch(pat.."|", ".") do
|
||||
|
@ -1497,6 +1792,8 @@ local function dopattern(pat, args, sz, op, needrex)
|
|||
szov = nil
|
||||
elseif c == "X" then -- Force REX.W.
|
||||
rex = 8
|
||||
elseif c == "L" then -- Force VEX.L.
|
||||
vex.l = true
|
||||
elseif c == "r" then -- Merge 1st operand regno. into opcode.
|
||||
addin = args[1]; opcode = opcode + (addin.reg % 8)
|
||||
if narg < 2 then narg = 2 end
|
||||
|
@ -1520,21 +1817,42 @@ local function dopattern(pat, args, sz, op, needrex)
|
|||
if t.xreg and t.xreg > 7 then rex = rex + 2 end
|
||||
if s > 7 then rex = rex + 4 end
|
||||
if needrex then rex = rex + 16 end
|
||||
wputop(szov, opcode, rex); opcode = nil
|
||||
local psz, sk = wputop(szov, opcode, rex, vex, s < 0, t.vreg or t.vxreg)
|
||||
opcode = nil
|
||||
local imark = sub(pat, -1) -- Force a mark (ugly).
|
||||
-- Put ModRM/SIB with regno/last digit as spare.
|
||||
wputmrmsib(t, imark, s, addin and addin.vreg)
|
||||
wputmrmsib(t, imark, s, addin and addin.vreg, psz, sk)
|
||||
addin = nil
|
||||
elseif map_vexarg[c] ~= nil then -- Encode using VEX prefix
|
||||
local b = band(opcode, 255); opcode = shr(opcode, 8)
|
||||
local m = 1
|
||||
if b == 0x38 then m = 2
|
||||
elseif b == 0x3a then m = 3 end
|
||||
if m ~= 1 then b = band(opcode, 255); opcode = shr(opcode, 8) end
|
||||
if b ~= 0x0f then
|
||||
werror("expected `0F', `0F38', or `0F3A' to precede `"..c..
|
||||
"' in pattern `"..pat.."' for `"..op.."'")
|
||||
end
|
||||
local v = map_vexarg[c]
|
||||
if v then v = remove(args, v) end
|
||||
b = band(opcode, 255)
|
||||
local p = 0
|
||||
if b == 0x66 then p = 1
|
||||
elseif b == 0xf3 then p = 2
|
||||
elseif b == 0xf2 then p = 3 end
|
||||
if p ~= 0 then opcode = shr(opcode, 8) end
|
||||
if opcode ~= 0 then wputop(nil, opcode, 0); opcode = 0 end
|
||||
vex = { m = m, p = p, v = v }
|
||||
else
|
||||
if opcode then -- Flush opcode.
|
||||
if szov == "q" and rex == 0 then rex = rex + 8 end
|
||||
if needrex then rex = rex + 16 end
|
||||
if addin and addin.reg == -1 then
|
||||
wputop(szov, opcode - 7, rex)
|
||||
waction("VREG", addin.vreg); wputxb(0)
|
||||
local psz, sk = wputop(szov, opcode - 7, rex, vex, true)
|
||||
wvreg("opcode", addin.vreg, psz, sk)
|
||||
else
|
||||
if addin and addin.reg > 7 then rex = rex + 1 end
|
||||
wputop(szov, opcode, rex)
|
||||
wputop(szov, opcode, rex, vex)
|
||||
end
|
||||
opcode = nil
|
||||
end
|
||||
|
@ -1571,6 +1889,14 @@ local function dopattern(pat, args, sz, op, needrex)
|
|||
else
|
||||
wputlabel("REL_", imm, 2)
|
||||
end
|
||||
elseif c == "s" then
|
||||
local reg = a.reg
|
||||
if reg < 0 then
|
||||
wputb(0)
|
||||
wvreg("imm.hi", a.vreg)
|
||||
else
|
||||
wputb(shl(reg, 4))
|
||||
end
|
||||
else
|
||||
werror("bad char `"..c.."' in pattern `"..pat.."' for `"..op.."'")
|
||||
end
|
||||
|
@ -1647,11 +1973,14 @@ map_op[".template__"] = function(params, template, nparams)
|
|||
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, needrex) -- Process pattern.
|
||||
return
|
||||
if prefix == "/" then -- Exactly match leading operand sizes.
|
||||
for i = #szm,1,-1 do
|
||||
if i == 1 then
|
||||
dopattern(pat, args, sz, params.op, needrex) -- Process pattern.
|
||||
return
|
||||
elseif args[i-1].opsize ~= sub(szm, i, i) then
|
||||
break
|
||||
end
|
||||
end
|
||||
else -- Match common operand size.
|
||||
local szp = sz
|
||||
|
@ -1716,8 +2045,8 @@ if x64 then
|
|||
rex = a.reg > 7 and 9 or 8
|
||||
end
|
||||
end
|
||||
wputop(sz, opcode, rex)
|
||||
if vreg then waction("VREG", vreg); wputxb(0) end
|
||||
local psz, sk = wputop(sz, opcode, rex, nil, vreg)
|
||||
wvreg("opcode", vreg, psz, sk)
|
||||
waction("IMM_D", format("(unsigned int)(%s)", op64))
|
||||
waction("IMM_D", format("(unsigned int)((%s)>>32)", op64))
|
||||
end
|
||||
|
|
10
vendor/luajit/dynasm/dynasm.lua
vendored
10
vendor/luajit/dynasm/dynasm.lua
vendored
|
@ -2,7 +2,7 @@
|
|||
-- DynASM. A dynamic assembler for code generation engines.
|
||||
-- Originally designed and implemented for LuaJIT.
|
||||
--
|
||||
-- Copyright (C) 2005-2015 Mike Pall. All rights reserved.
|
||||
-- Copyright (C) 2005-2017 Mike Pall. All rights reserved.
|
||||
-- See below for full copyright notice.
|
||||
------------------------------------------------------------------------------
|
||||
|
||||
|
@ -10,14 +10,14 @@
|
|||
local _info = {
|
||||
name = "DynASM",
|
||||
description = "A dynamic assembler for code generation engines",
|
||||
version = "1.3.0",
|
||||
vernum = 10300,
|
||||
release = "2011-05-05",
|
||||
version = "1.4.0",
|
||||
vernum = 10400,
|
||||
release = "2015-10-18",
|
||||
author = "Mike Pall",
|
||||
url = "http://luajit.org/dynasm.html",
|
||||
license = "MIT",
|
||||
copyright = [[
|
||||
Copyright (C) 2005-2015 Mike Pall. All rights reserved.
|
||||
Copyright (C) 2005-2017 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
|
||||
|
|
88
vendor/luajit/etc/luajit.1
vendored
Normal file
88
vendor/luajit/etc/luajit.1
vendored
Normal file
|
@ -0,0 +1,88 @@
|
|||
.TH luajit 1 "" "" "LuaJIT documentation"
|
||||
.SH NAME
|
||||
luajit \- Just-In-Time Compiler for the Lua Language
|
||||
\fB
|
||||
.SH SYNOPSIS
|
||||
.B luajit
|
||||
[\fIoptions\fR]... [\fIscript\fR [\fIargs\fR]...]
|
||||
.SH "WEB SITE"
|
||||
.IR http://luajit.org
|
||||
.SH DESCRIPTION
|
||||
.PP
|
||||
This is the command-line program to run Lua programs with \fBLuaJIT\fR.
|
||||
.PP
|
||||
\fBLuaJIT\fR is a just-in-time (JIT) compiler for the Lua language.
|
||||
The virtual machine (VM) is based on a fast interpreter combined with
|
||||
a trace compiler. It can significantly improve the performance of Lua programs.
|
||||
.PP
|
||||
\fBLuaJIT\fR is API\- and ABI-compatible with the VM of the standard
|
||||
Lua\ 5.1 interpreter. When embedding the VM into an application,
|
||||
the built library can be used as a drop-in replacement.
|
||||
.SH OPTIONS
|
||||
.TP
|
||||
.BI "\-e " chunk
|
||||
Run the given chunk of Lua code.
|
||||
.TP
|
||||
.BI "\-l " library
|
||||
Load the named library, just like \fBrequire("\fR\fIlibrary\fR\fB")\fR.
|
||||
.TP
|
||||
.BI "\-b " ...
|
||||
Save or list bytecode. Run without arguments to get help on options.
|
||||
.TP
|
||||
.BI "\-j " command
|
||||
Perform LuaJIT control command (optional space after \fB\-j\fR).
|
||||
.TP
|
||||
.BI "\-O" [opt]
|
||||
Control LuaJIT optimizations.
|
||||
.TP
|
||||
.B "\-i"
|
||||
Run in interactive mode.
|
||||
.TP
|
||||
.B "\-v"
|
||||
Show \fBLuaJIT\fR version.
|
||||
.TP
|
||||
.B "\-E"
|
||||
Ignore environment variables.
|
||||
.TP
|
||||
.B "\-\-"
|
||||
Stop processing options.
|
||||
.TP
|
||||
.B "\-"
|
||||
Read script from stdin instead.
|
||||
.PP
|
||||
After all options are processed, the given \fIscript\fR is run.
|
||||
The arguments are passed in the global \fIarg\fR table.
|
||||
.PP
|
||||
Interactive mode is only entered, if no \fIscript\fR and no \fB\-e\fR
|
||||
option is given. Interactive mode can be left with EOF (\fICtrl\-Z\fB).
|
||||
.SH EXAMPLES
|
||||
.TP
|
||||
luajit hello.lua world
|
||||
|
||||
Prints "Hello world", assuming \fIhello.lua\fR contains:
|
||||
.br
|
||||
print("Hello", arg[1])
|
||||
.TP
|
||||
luajit \-e "local x=0; for i=1,1e9 do x=x+i end; print(x)"
|
||||
|
||||
Calculates the sum of the numbers from 1 to 1000000000.
|
||||
.br
|
||||
And finishes in a reasonable amount of time, too.
|
||||
.TP
|
||||
luajit \-jv \-e "for i=1,10 do for j=1,10 do for k=1,100 do end end end"
|
||||
|
||||
Runs some nested loops and shows the resulting traces.
|
||||
.SH COPYRIGHT
|
||||
.PP
|
||||
\fBLuaJIT\fR is Copyright \(co 2005-2017 Mike Pall.
|
||||
.br
|
||||
\fBLuaJIT\fR is open source software, released under the MIT license.
|
||||
.SH SEE ALSO
|
||||
.PP
|
||||
More details in the provided HTML docs or at:
|
||||
.IR http://luajit.org
|
||||
.br
|
||||
More about the Lua language can be found at:
|
||||
.IR http://lua.org/docs.html
|
||||
.PP
|
||||
lua(1)
|
25
vendor/luajit/etc/luajit.pc
vendored
Normal file
25
vendor/luajit/etc/luajit.pc
vendored
Normal file
|
@ -0,0 +1,25 @@
|
|||
# Package information for LuaJIT to be used by pkg-config.
|
||||
majver=2
|
||||
minver=1
|
||||
relver=0
|
||||
version=${majver}.${minver}.${relver}-beta3
|
||||
abiver=5.1
|
||||
|
||||
prefix=/usr/local
|
||||
multilib=lib
|
||||
exec_prefix=${prefix}
|
||||
libdir=${exec_prefix}/${multilib}
|
||||
libname=luajit-${abiver}
|
||||
includedir=${prefix}/include/luajit-${majver}.${minver}
|
||||
|
||||
INSTALL_LMOD=${prefix}/share/lua/${abiver}
|
||||
INSTALL_CMOD=${prefix}/${multilib}/lua/${abiver}
|
||||
|
||||
Name: LuaJIT
|
||||
Description: Just-in-time compiler for Lua
|
||||
URL: http://luajit.org
|
||||
Version: ${version}
|
||||
Requires:
|
||||
Libs: -L${libdir} -l${libname}
|
||||
Libs.private: -Wl,-E -lm -ldl
|
||||
Cflags: -I${includedir}
|
167
vendor/luajit/include/lauxlib.h
vendored
167
vendor/luajit/include/lauxlib.h
vendored
|
@ -1,167 +0,0 @@
|
|||
/*
|
||||
** $Id: lauxlib.h,v 1.88.1.1 2007/12/27 13:02:25 roberto Exp $
|
||||
** Auxiliary functions for building Lua libraries
|
||||
** See Copyright Notice in lua.h
|
||||
*/
|
||||
|
||||
|
||||
#ifndef lauxlib_h
|
||||
#define lauxlib_h
|
||||
|
||||
|
||||
#include <stddef.h>
|
||||
#include <stdio.h>
|
||||
|
||||
#include "lua.h"
|
||||
|
||||
|
||||
#define luaL_getn(L,i) ((int)lua_objlen(L, i))
|
||||
#define luaL_setn(L,i,j) ((void)0) /* no op! */
|
||||
|
||||
/* extra error code for `luaL_load' */
|
||||
#define LUA_ERRFILE (LUA_ERRERR+1)
|
||||
|
||||
typedef struct luaL_Reg {
|
||||
const char *name;
|
||||
lua_CFunction func;
|
||||
} luaL_Reg;
|
||||
|
||||
LUALIB_API void (luaL_openlib) (lua_State *L, const char *libname,
|
||||
const luaL_Reg *l, int nup);
|
||||
LUALIB_API void (luaL_register) (lua_State *L, const char *libname,
|
||||
const luaL_Reg *l);
|
||||
LUALIB_API int (luaL_getmetafield) (lua_State *L, int obj, const char *e);
|
||||
LUALIB_API int (luaL_callmeta) (lua_State *L, int obj, const char *e);
|
||||
LUALIB_API int (luaL_typerror) (lua_State *L, int narg, const char *tname);
|
||||
LUALIB_API int (luaL_argerror) (lua_State *L, int numarg, const char *extramsg);
|
||||
LUALIB_API const char *(luaL_checklstring) (lua_State *L, int numArg,
|
||||
size_t *l);
|
||||
LUALIB_API const char *(luaL_optlstring) (lua_State *L, int numArg,
|
||||
const char *def, size_t *l);
|
||||
LUALIB_API lua_Number (luaL_checknumber) (lua_State *L, int numArg);
|
||||
LUALIB_API lua_Number (luaL_optnumber) (lua_State *L, int nArg, lua_Number def);
|
||||
|
||||
LUALIB_API lua_Integer (luaL_checkinteger) (lua_State *L, int numArg);
|
||||
LUALIB_API lua_Integer (luaL_optinteger) (lua_State *L, int nArg,
|
||||
lua_Integer def);
|
||||
|
||||
LUALIB_API void (luaL_checkstack) (lua_State *L, int sz, const char *msg);
|
||||
LUALIB_API void (luaL_checktype) (lua_State *L, int narg, int t);
|
||||
LUALIB_API void (luaL_checkany) (lua_State *L, int narg);
|
||||
|
||||
LUALIB_API int (luaL_newmetatable) (lua_State *L, const char *tname);
|
||||
LUALIB_API void *(luaL_checkudata) (lua_State *L, int ud, const char *tname);
|
||||
|
||||
LUALIB_API void (luaL_where) (lua_State *L, int lvl);
|
||||
LUALIB_API int (luaL_error) (lua_State *L, const char *fmt, ...);
|
||||
|
||||
LUALIB_API int (luaL_checkoption) (lua_State *L, int narg, const char *def,
|
||||
const char *const lst[]);
|
||||
|
||||
LUALIB_API int (luaL_ref) (lua_State *L, int t);
|
||||
LUALIB_API void (luaL_unref) (lua_State *L, int t, int ref);
|
||||
|
||||
LUALIB_API int (luaL_loadfile) (lua_State *L, const char *filename);
|
||||
LUALIB_API int (luaL_loadbuffer) (lua_State *L, const char *buff, size_t sz,
|
||||
const char *name);
|
||||
LUALIB_API int (luaL_loadstring) (lua_State *L, const char *s);
|
||||
|
||||
LUALIB_API lua_State *(luaL_newstate) (void);
|
||||
|
||||
|
||||
LUALIB_API const char *(luaL_gsub) (lua_State *L, const char *s, const char *p,
|
||||
const char *r);
|
||||
|
||||
LUALIB_API const char *(luaL_findtable) (lua_State *L, int idx,
|
||||
const char *fname, int szhint);
|
||||
|
||||
/* From Lua 5.2. */
|
||||
LUALIB_API int luaL_fileresult(lua_State *L, int stat, const char *fname);
|
||||
LUALIB_API int luaL_execresult(lua_State *L, int stat);
|
||||
LUALIB_API int (luaL_loadfilex) (lua_State *L, const char *filename,
|
||||
const char *mode);
|
||||
LUALIB_API int (luaL_loadbufferx) (lua_State *L, const char *buff, size_t sz,
|
||||
const char *name, const char *mode);
|
||||
LUALIB_API void luaL_traceback (lua_State *L, lua_State *L1, const char *msg,
|
||||
int level);
|
||||
|
||||
|
||||
/*
|
||||
** ===============================================================
|
||||
** some useful macros
|
||||
** ===============================================================
|
||||
*/
|
||||
|
||||
#define luaL_argcheck(L, cond,numarg,extramsg) \
|
||||
((void)((cond) || luaL_argerror(L, (numarg), (extramsg))))
|
||||
#define luaL_checkstring(L,n) (luaL_checklstring(L, (n), NULL))
|
||||
#define luaL_optstring(L,n,d) (luaL_optlstring(L, (n), (d), NULL))
|
||||
#define luaL_checkint(L,n) ((int)luaL_checkinteger(L, (n)))
|
||||
#define luaL_optint(L,n,d) ((int)luaL_optinteger(L, (n), (d)))
|
||||
#define luaL_checklong(L,n) ((long)luaL_checkinteger(L, (n)))
|
||||
#define luaL_optlong(L,n,d) ((long)luaL_optinteger(L, (n), (d)))
|
||||
|
||||
#define luaL_typename(L,i) lua_typename(L, lua_type(L,(i)))
|
||||
|
||||
#define luaL_dofile(L, fn) \
|
||||
(luaL_loadfile(L, fn) || lua_pcall(L, 0, LUA_MULTRET, 0))
|
||||
|
||||
#define luaL_dostring(L, s) \
|
||||
(luaL_loadstring(L, s) || lua_pcall(L, 0, LUA_MULTRET, 0))
|
||||
|
||||
#define luaL_getmetatable(L,n) (lua_getfield(L, LUA_REGISTRYINDEX, (n)))
|
||||
|
||||
#define luaL_opt(L,f,n,d) (lua_isnoneornil(L,(n)) ? (d) : f(L,(n)))
|
||||
|
||||
/*
|
||||
** {======================================================
|
||||
** Generic Buffer manipulation
|
||||
** =======================================================
|
||||
*/
|
||||
|
||||
|
||||
|
||||
typedef struct luaL_Buffer {
|
||||
char *p; /* current position in buffer */
|
||||
int lvl; /* number of strings in the stack (level) */
|
||||
lua_State *L;
|
||||
char buffer[LUAL_BUFFERSIZE];
|
||||
} luaL_Buffer;
|
||||
|
||||
#define luaL_addchar(B,c) \
|
||||
((void)((B)->p < ((B)->buffer+LUAL_BUFFERSIZE) || luaL_prepbuffer(B)), \
|
||||
(*(B)->p++ = (char)(c)))
|
||||
|
||||
/* compatibility only */
|
||||
#define luaL_putchar(B,c) luaL_addchar(B,c)
|
||||
|
||||
#define luaL_addsize(B,n) ((B)->p += (n))
|
||||
|
||||
LUALIB_API void (luaL_buffinit) (lua_State *L, luaL_Buffer *B);
|
||||
LUALIB_API char *(luaL_prepbuffer) (luaL_Buffer *B);
|
||||
LUALIB_API void (luaL_addlstring) (luaL_Buffer *B, const char *s, size_t l);
|
||||
LUALIB_API void (luaL_addstring) (luaL_Buffer *B, const char *s);
|
||||
LUALIB_API void (luaL_addvalue) (luaL_Buffer *B);
|
||||
LUALIB_API void (luaL_pushresult) (luaL_Buffer *B);
|
||||
|
||||
|
||||
/* }====================================================== */
|
||||
|
||||
|
||||
/* compatibility with ref system */
|
||||
|
||||
/* pre-defined references */
|
||||
#define LUA_NOREF (-2)
|
||||
#define LUA_REFNIL (-1)
|
||||
|
||||
#define lua_ref(L,lock) ((lock) ? luaL_ref(L, LUA_REGISTRYINDEX) : \
|
||||
(lua_pushstring(L, "unlocked references are obsolete"), lua_error(L), 0))
|
||||
|
||||
#define lua_unref(L,ref) luaL_unref(L, LUA_REGISTRYINDEX, (ref))
|
||||
|
||||
#define lua_getref(L,ref) lua_rawgeti(L, LUA_REGISTRYINDEX, (ref))
|
||||
|
||||
|
||||
#define luaL_reg luaL_Reg
|
||||
|
||||
#endif
|
393
vendor/luajit/include/lua.h
vendored
393
vendor/luajit/include/lua.h
vendored
|
@ -1,393 +0,0 @@
|
|||
/*
|
||||
** $Id: lua.h,v 1.218.1.5 2008/08/06 13:30:12 roberto Exp $
|
||||
** Lua - An Extensible Extension Language
|
||||
** Lua.org, PUC-Rio, Brazil (http://www.lua.org)
|
||||
** See Copyright Notice at the end of this file
|
||||
*/
|
||||
|
||||
|
||||
#ifndef lua_h
|
||||
#define lua_h
|
||||
|
||||
#include <stdarg.h>
|
||||
#include <stddef.h>
|
||||
|
||||
|
||||
#include "luaconf.h"
|
||||
|
||||
|
||||
#define LUA_VERSION "Lua 5.1"
|
||||
#define LUA_RELEASE "Lua 5.1.4"
|
||||
#define LUA_VERSION_NUM 501
|
||||
#define LUA_COPYRIGHT "Copyright (C) 1994-2008 Lua.org, PUC-Rio"
|
||||
#define LUA_AUTHORS "R. Ierusalimschy, L. H. de Figueiredo & W. Celes"
|
||||
|
||||
|
||||
/* mark for precompiled code (`<esc>Lua') */
|
||||
#define LUA_SIGNATURE "\033Lua"
|
||||
|
||||
/* option for multiple returns in `lua_pcall' and `lua_call' */
|
||||
#define LUA_MULTRET (-1)
|
||||
|
||||
|
||||
/*
|
||||
** pseudo-indices
|
||||
*/
|
||||
#define LUA_REGISTRYINDEX (-10000)
|
||||
#define LUA_ENVIRONINDEX (-10001)
|
||||
#define LUA_GLOBALSINDEX (-10002)
|
||||
#define lua_upvalueindex(i) (LUA_GLOBALSINDEX-(i))
|
||||
|
||||
|
||||
/* thread status; 0 is OK */
|
||||
#define LUA_YIELD 1
|
||||
#define LUA_ERRRUN 2
|
||||
#define LUA_ERRSYNTAX 3
|
||||
#define LUA_ERRMEM 4
|
||||
#define LUA_ERRERR 5
|
||||
|
||||
|
||||
typedef struct lua_State lua_State;
|
||||
|
||||
typedef int (*lua_CFunction) (lua_State *L);
|
||||
|
||||
|
||||
/*
|
||||
** functions that read/write blocks when loading/dumping Lua chunks
|
||||
*/
|
||||
typedef const char * (*lua_Reader) (lua_State *L, void *ud, size_t *sz);
|
||||
|
||||
typedef int (*lua_Writer) (lua_State *L, const void* p, size_t sz, void* ud);
|
||||
|
||||
|
||||
/*
|
||||
** prototype for memory-allocation functions
|
||||
*/
|
||||
typedef void * (*lua_Alloc) (void *ud, void *ptr, size_t osize, size_t nsize);
|
||||
|
||||
|
||||
/*
|
||||
** basic types
|
||||
*/
|
||||
#define LUA_TNONE (-1)
|
||||
|
||||
#define LUA_TNIL 0
|
||||
#define LUA_TBOOLEAN 1
|
||||
#define LUA_TLIGHTUSERDATA 2
|
||||
#define LUA_TNUMBER 3
|
||||
#define LUA_TSTRING 4
|
||||
#define LUA_TTABLE 5
|
||||
#define LUA_TFUNCTION 6
|
||||
#define LUA_TUSERDATA 7
|
||||
#define LUA_TTHREAD 8
|
||||
|
||||
|
||||
|
||||
/* minimum Lua stack available to a C function */
|
||||
#define LUA_MINSTACK 20
|
||||
|
||||
|
||||
/*
|
||||
** generic extra include file
|
||||
*/
|
||||
#if defined(LUA_USER_H)
|
||||
#include LUA_USER_H
|
||||
#endif
|
||||
|
||||
|
||||
/* type of numbers in Lua */
|
||||
typedef LUA_NUMBER lua_Number;
|
||||
|
||||
|
||||
/* type for integer functions */
|
||||
typedef LUA_INTEGER lua_Integer;
|
||||
|
||||
|
||||
|
||||
/*
|
||||
** state manipulation
|
||||
*/
|
||||
LUA_API lua_State *(lua_newstate) (lua_Alloc f, void *ud);
|
||||
LUA_API void (lua_close) (lua_State *L);
|
||||
LUA_API lua_State *(lua_newthread) (lua_State *L);
|
||||
|
||||
LUA_API lua_CFunction (lua_atpanic) (lua_State *L, lua_CFunction panicf);
|
||||
|
||||
|
||||
/*
|
||||
** basic stack manipulation
|
||||
*/
|
||||
LUA_API int (lua_gettop) (lua_State *L);
|
||||
LUA_API void (lua_settop) (lua_State *L, int idx);
|
||||
LUA_API void (lua_pushvalue) (lua_State *L, int idx);
|
||||
LUA_API void (lua_remove) (lua_State *L, int idx);
|
||||
LUA_API void (lua_insert) (lua_State *L, int idx);
|
||||
LUA_API void (lua_replace) (lua_State *L, int idx);
|
||||
LUA_API int (lua_checkstack) (lua_State *L, int sz);
|
||||
|
||||
LUA_API void (lua_xmove) (lua_State *from, lua_State *to, int n);
|
||||
|
||||
|
||||
/*
|
||||
** access functions (stack -> C)
|
||||
*/
|
||||
|
||||
LUA_API int (lua_isnumber) (lua_State *L, int idx);
|
||||
LUA_API int (lua_isstring) (lua_State *L, int idx);
|
||||
LUA_API int (lua_iscfunction) (lua_State *L, int idx);
|
||||
LUA_API int (lua_isuserdata) (lua_State *L, int idx);
|
||||
LUA_API int (lua_type) (lua_State *L, int idx);
|
||||
LUA_API const char *(lua_typename) (lua_State *L, int tp);
|
||||
|
||||
LUA_API int (lua_equal) (lua_State *L, int idx1, int idx2);
|
||||
LUA_API int (lua_rawequal) (lua_State *L, int idx1, int idx2);
|
||||
LUA_API int (lua_lessthan) (lua_State *L, int idx1, int idx2);
|
||||
|
||||
LUA_API lua_Number (lua_tonumber) (lua_State *L, int idx);
|
||||
LUA_API lua_Integer (lua_tointeger) (lua_State *L, int idx);
|
||||
LUA_API int (lua_toboolean) (lua_State *L, int idx);
|
||||
LUA_API const char *(lua_tolstring) (lua_State *L, int idx, size_t *len);
|
||||
LUA_API size_t (lua_objlen) (lua_State *L, int idx);
|
||||
LUA_API lua_CFunction (lua_tocfunction) (lua_State *L, int idx);
|
||||
LUA_API void *(lua_touserdata) (lua_State *L, int idx);
|
||||
LUA_API lua_State *(lua_tothread) (lua_State *L, int idx);
|
||||
LUA_API const void *(lua_topointer) (lua_State *L, int idx);
|
||||
|
||||
|
||||
/*
|
||||
** push functions (C -> stack)
|
||||
*/
|
||||
LUA_API void (lua_pushnil) (lua_State *L);
|
||||
LUA_API void (lua_pushnumber) (lua_State *L, lua_Number n);
|
||||
LUA_API void (lua_pushinteger) (lua_State *L, lua_Integer n);
|
||||
LUA_API void (lua_pushlstring) (lua_State *L, const char *s, size_t l);
|
||||
LUA_API void (lua_pushstring) (lua_State *L, const char *s);
|
||||
LUA_API const char *(lua_pushvfstring) (lua_State *L, const char *fmt,
|
||||
va_list argp);
|
||||
LUA_API const char *(lua_pushfstring) (lua_State *L, const char *fmt, ...);
|
||||
LUA_API void (lua_pushcclosure) (lua_State *L, lua_CFunction fn, int n);
|
||||
LUA_API void (lua_pushboolean) (lua_State *L, int b);
|
||||
LUA_API void (lua_pushlightuserdata) (lua_State *L, void *p);
|
||||
LUA_API int (lua_pushthread) (lua_State *L);
|
||||
|
||||
|
||||
/*
|
||||
** get functions (Lua -> stack)
|
||||
*/
|
||||
LUA_API void (lua_gettable) (lua_State *L, int idx);
|
||||
LUA_API void (lua_getfield) (lua_State *L, int idx, const char *k);
|
||||
LUA_API void (lua_rawget) (lua_State *L, int idx);
|
||||
LUA_API void (lua_rawgeti) (lua_State *L, int idx, int n);
|
||||
LUA_API void (lua_createtable) (lua_State *L, int narr, int nrec);
|
||||
LUA_API void *(lua_newuserdata) (lua_State *L, size_t sz);
|
||||
LUA_API int (lua_getmetatable) (lua_State *L, int objindex);
|
||||
LUA_API void (lua_getfenv) (lua_State *L, int idx);
|
||||
|
||||
|
||||
/*
|
||||
** set functions (stack -> Lua)
|
||||
*/
|
||||
LUA_API void (lua_settable) (lua_State *L, int idx);
|
||||
LUA_API void (lua_setfield) (lua_State *L, int idx, const char *k);
|
||||
LUA_API void (lua_rawset) (lua_State *L, int idx);
|
||||
LUA_API void (lua_rawseti) (lua_State *L, int idx, int n);
|
||||
LUA_API int (lua_setmetatable) (lua_State *L, int objindex);
|
||||
LUA_API int (lua_setfenv) (lua_State *L, int idx);
|
||||
|
||||
|
||||
/*
|
||||
** `load' and `call' functions (load and run Lua code)
|
||||
*/
|
||||
LUA_API void (lua_call) (lua_State *L, int nargs, int nresults);
|
||||
LUA_API int (lua_pcall) (lua_State *L, int nargs, int nresults, int errfunc);
|
||||
LUA_API int (lua_cpcall) (lua_State *L, lua_CFunction func, void *ud);
|
||||
LUA_API int (lua_load) (lua_State *L, lua_Reader reader, void *dt,
|
||||
const char *chunkname);
|
||||
|
||||
LUA_API int (lua_dump) (lua_State *L, lua_Writer writer, void *data);
|
||||
|
||||
|
||||
/*
|
||||
** coroutine functions
|
||||
*/
|
||||
LUA_API int (lua_yield) (lua_State *L, int nresults);
|
||||
LUA_API int (lua_resume) (lua_State *L, int narg);
|
||||
LUA_API int (lua_status) (lua_State *L);
|
||||
|
||||
/*
|
||||
** garbage-collection function and options
|
||||
*/
|
||||
|
||||
#define LUA_GCSTOP 0
|
||||
#define LUA_GCRESTART 1
|
||||
#define LUA_GCCOLLECT 2
|
||||
#define LUA_GCCOUNT 3
|
||||
#define LUA_GCCOUNTB 4
|
||||
#define LUA_GCSTEP 5
|
||||
#define LUA_GCSETPAUSE 6
|
||||
#define LUA_GCSETSTEPMUL 7
|
||||
|
||||
LUA_API int (lua_gc) (lua_State *L, int what, int data);
|
||||
|
||||
|
||||
/*
|
||||
** miscellaneous functions
|
||||
*/
|
||||
|
||||
LUA_API int (lua_error) (lua_State *L);
|
||||
|
||||
LUA_API int (lua_next) (lua_State *L, int idx);
|
||||
|
||||
LUA_API void (lua_concat) (lua_State *L, int n);
|
||||
|
||||
LUA_API lua_Alloc (lua_getallocf) (lua_State *L, void **ud);
|
||||
LUA_API void lua_setallocf (lua_State *L, lua_Alloc f, void *ud);
|
||||
|
||||
|
||||
|
||||
/*
|
||||
** ===============================================================
|
||||
** some useful macros
|
||||
** ===============================================================
|
||||
*/
|
||||
|
||||
#define lua_pop(L,n) lua_settop(L, -(n)-1)
|
||||
|
||||
#define lua_newtable(L) lua_createtable(L, 0, 0)
|
||||
|
||||
#define lua_register(L,n,f) (lua_pushcfunction(L, (f)), lua_setglobal(L, (n)))
|
||||
|
||||
#define lua_pushcfunction(L,f) lua_pushcclosure(L, (f), 0)
|
||||
|
||||
#define lua_strlen(L,i) lua_objlen(L, (i))
|
||||
|
||||
#define lua_isfunction(L,n) (lua_type(L, (n)) == LUA_TFUNCTION)
|
||||
#define lua_istable(L,n) (lua_type(L, (n)) == LUA_TTABLE)
|
||||
#define lua_islightuserdata(L,n) (lua_type(L, (n)) == LUA_TLIGHTUSERDATA)
|
||||
#define lua_isnil(L,n) (lua_type(L, (n)) == LUA_TNIL)
|
||||
#define lua_isboolean(L,n) (lua_type(L, (n)) == LUA_TBOOLEAN)
|
||||
#define lua_isthread(L,n) (lua_type(L, (n)) == LUA_TTHREAD)
|
||||
#define lua_isnone(L,n) (lua_type(L, (n)) == LUA_TNONE)
|
||||
#define lua_isnoneornil(L, n) (lua_type(L, (n)) <= 0)
|
||||
|
||||
#define lua_pushliteral(L, s) \
|
||||
lua_pushlstring(L, "" s, (sizeof(s)/sizeof(char))-1)
|
||||
|
||||
#define lua_setglobal(L,s) lua_setfield(L, LUA_GLOBALSINDEX, (s))
|
||||
#define lua_getglobal(L,s) lua_getfield(L, LUA_GLOBALSINDEX, (s))
|
||||
|
||||
#define lua_tostring(L,i) lua_tolstring(L, (i), NULL)
|
||||
|
||||
|
||||
|
||||
/*
|
||||
** compatibility macros and functions
|
||||
*/
|
||||
|
||||
#define lua_open() luaL_newstate()
|
||||
|
||||
#define lua_getregistry(L) lua_pushvalue(L, LUA_REGISTRYINDEX)
|
||||
|
||||
#define lua_getgccount(L) lua_gc(L, LUA_GCCOUNT, 0)
|
||||
|
||||
#define lua_Chunkreader lua_Reader
|
||||
#define lua_Chunkwriter lua_Writer
|
||||
|
||||
|
||||
/* hack */
|
||||
LUA_API void lua_setlevel (lua_State *from, lua_State *to);
|
||||
|
||||
|
||||
/*
|
||||
** {======================================================================
|
||||
** Debug API
|
||||
** =======================================================================
|
||||
*/
|
||||
|
||||
|
||||
/*
|
||||
** Event codes
|
||||
*/
|
||||
#define LUA_HOOKCALL 0
|
||||
#define LUA_HOOKRET 1
|
||||
#define LUA_HOOKLINE 2
|
||||
#define LUA_HOOKCOUNT 3
|
||||
#define LUA_HOOKTAILRET 4
|
||||
|
||||
|
||||
/*
|
||||
** Event masks
|
||||
*/
|
||||
#define LUA_MASKCALL (1 << LUA_HOOKCALL)
|
||||
#define LUA_MASKRET (1 << LUA_HOOKRET)
|
||||
#define LUA_MASKLINE (1 << LUA_HOOKLINE)
|
||||
#define LUA_MASKCOUNT (1 << LUA_HOOKCOUNT)
|
||||
|
||||
typedef struct lua_Debug lua_Debug; /* activation record */
|
||||
|
||||
|
||||
/* Functions to be called by the debuger in specific events */
|
||||
typedef void (*lua_Hook) (lua_State *L, lua_Debug *ar);
|
||||
|
||||
|
||||
LUA_API int lua_getstack (lua_State *L, int level, lua_Debug *ar);
|
||||
LUA_API int lua_getinfo (lua_State *L, const char *what, lua_Debug *ar);
|
||||
LUA_API const char *lua_getlocal (lua_State *L, const lua_Debug *ar, int n);
|
||||
LUA_API const char *lua_setlocal (lua_State *L, const lua_Debug *ar, int n);
|
||||
LUA_API const char *lua_getupvalue (lua_State *L, int funcindex, int n);
|
||||
LUA_API const char *lua_setupvalue (lua_State *L, int funcindex, int n);
|
||||
LUA_API int lua_sethook (lua_State *L, lua_Hook func, int mask, int count);
|
||||
LUA_API lua_Hook lua_gethook (lua_State *L);
|
||||
LUA_API int lua_gethookmask (lua_State *L);
|
||||
LUA_API int lua_gethookcount (lua_State *L);
|
||||
|
||||
/* From Lua 5.2. */
|
||||
LUA_API void *lua_upvalueid (lua_State *L, int idx, int n);
|
||||
LUA_API void lua_upvaluejoin (lua_State *L, int idx1, int n1, int idx2, int n2);
|
||||
LUA_API int lua_loadx (lua_State *L, lua_Reader reader, void *dt,
|
||||
const char *chunkname, const char *mode);
|
||||
|
||||
|
||||
struct lua_Debug {
|
||||
int event;
|
||||
const char *name; /* (n) */
|
||||
const char *namewhat; /* (n) `global', `local', `field', `method' */
|
||||
const char *what; /* (S) `Lua', `C', `main', `tail' */
|
||||
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 */
|
||||
int i_ci; /* active function */
|
||||
};
|
||||
|
||||
/* }====================================================================== */
|
||||
|
||||
|
||||
/******************************************************************************
|
||||
* Copyright (C) 1994-2008 Lua.org, PUC-Rio. 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.
|
||||
******************************************************************************/
|
||||
|
||||
|
||||
#endif
|
9
vendor/luajit/include/lua.hpp
vendored
9
vendor/luajit/include/lua.hpp
vendored
|
@ -1,9 +0,0 @@
|
|||
// C++ wrapper for LuaJIT header files.
|
||||
|
||||
extern "C" {
|
||||
#include "lua.h"
|
||||
#include "lauxlib.h"
|
||||
#include "lualib.h"
|
||||
#include "luajit.h"
|
||||
}
|
||||
|
156
vendor/luajit/include/luaconf.h
vendored
156
vendor/luajit/include/luaconf.h
vendored
|
@ -1,156 +0,0 @@
|
|||
/*
|
||||
** Configuration header.
|
||||
** Copyright (C) 2005-2015 Mike Pall. See Copyright Notice in luajit.h
|
||||
*/
|
||||
|
||||
#ifndef luaconf_h
|
||||
#define luaconf_h
|
||||
|
||||
#ifndef WINVER
|
||||
#define WINVER 0x0501
|
||||
#endif
|
||||
#include <limits.h>
|
||||
#include <stddef.h>
|
||||
|
||||
/* Default path for loading Lua and C modules with require(). */
|
||||
#if defined(_WIN32)
|
||||
/*
|
||||
** In Windows, any exclamation mark ('!') in the path is replaced by the
|
||||
** path of the directory of the executable file of the current process.
|
||||
*/
|
||||
#define LUA_LDIR "!\\lua\\"
|
||||
#define LUA_CDIR "!\\"
|
||||
#define LUA_PATH_DEFAULT \
|
||||
".\\?.lua;" LUA_LDIR"?.lua;" LUA_LDIR"?\\init.lua;"
|
||||
#define LUA_CPATH_DEFAULT \
|
||||
".\\?.dll;" LUA_CDIR"?.dll;" LUA_CDIR"loadall.dll"
|
||||
#else
|
||||
/*
|
||||
** Note to distribution maintainers: do NOT patch the following lines!
|
||||
** Please read ../doc/install.html#distro and pass PREFIX=/usr instead.
|
||||
*/
|
||||
#ifndef LUA_MULTILIB
|
||||
#define LUA_MULTILIB "lib"
|
||||
#endif
|
||||
#ifndef LUA_LMULTILIB
|
||||
#define LUA_LMULTILIB "lib"
|
||||
#endif
|
||||
#define LUA_LROOT "/usr/local"
|
||||
#define LUA_LUADIR "/lua/5.1/"
|
||||
#define LUA_LJDIR "/luajit-2.0.4/"
|
||||
|
||||
#ifdef LUA_ROOT
|
||||
#define LUA_JROOT LUA_ROOT
|
||||
#define LUA_RLDIR LUA_ROOT "/share" LUA_LUADIR
|
||||
#define LUA_RCDIR LUA_ROOT "/" LUA_MULTILIB LUA_LUADIR
|
||||
#define LUA_RLPATH ";" LUA_RLDIR "?.lua;" LUA_RLDIR "?/init.lua"
|
||||
#define LUA_RCPATH ";" LUA_RCDIR "?.so"
|
||||
#else
|
||||
#define LUA_JROOT LUA_LROOT
|
||||
#define LUA_RLPATH
|
||||
#define LUA_RCPATH
|
||||
#endif
|
||||
|
||||
#define LUA_JPATH ";" LUA_JROOT "/share" LUA_LJDIR "?.lua"
|
||||
#define LUA_LLDIR LUA_LROOT "/share" LUA_LUADIR
|
||||
#define LUA_LCDIR LUA_LROOT "/" LUA_LMULTILIB LUA_LUADIR
|
||||
#define LUA_LLPATH ";" LUA_LLDIR "?.lua;" LUA_LLDIR "?/init.lua"
|
||||
#define LUA_LCPATH1 ";" LUA_LCDIR "?.so"
|
||||
#define LUA_LCPATH2 ";" LUA_LCDIR "loadall.so"
|
||||
|
||||
#define LUA_PATH_DEFAULT "./?.lua" LUA_JPATH LUA_LLPATH LUA_RLPATH
|
||||
#define LUA_CPATH_DEFAULT "./?.so" LUA_LCPATH1 LUA_RCPATH LUA_LCPATH2
|
||||
#endif
|
||||
|
||||
/* Environment variable names for path overrides and initialization code. */
|
||||
#define LUA_PATH "LUA_PATH"
|
||||
#define LUA_CPATH "LUA_CPATH"
|
||||
#define LUA_INIT "LUA_INIT"
|
||||
|
||||
/* Special file system characters. */
|
||||
#if defined(_WIN32)
|
||||
#define LUA_DIRSEP "\\"
|
||||
#else
|
||||
#define LUA_DIRSEP "/"
|
||||
#endif
|
||||
#define LUA_PATHSEP ";"
|
||||
#define LUA_PATH_MARK "?"
|
||||
#define LUA_EXECDIR "!"
|
||||
#define LUA_IGMARK "-"
|
||||
#define LUA_PATH_CONFIG \
|
||||
LUA_DIRSEP "\n" LUA_PATHSEP "\n" LUA_PATH_MARK "\n" \
|
||||
LUA_EXECDIR "\n" LUA_IGMARK
|
||||
|
||||
/* Quoting in error messages. */
|
||||
#define LUA_QL(x) "'" x "'"
|
||||
#define LUA_QS LUA_QL("%s")
|
||||
|
||||
/* Various tunables. */
|
||||
#define LUAI_MAXSTACK 65500 /* Max. # of stack slots for a thread (<64K). */
|
||||
#define LUAI_MAXCSTACK 8000 /* Max. # of stack slots for a C func (<10K). */
|
||||
#define LUAI_GCPAUSE 200 /* Pause GC until memory is at 200%. */
|
||||
#define LUAI_GCMUL 200 /* Run GC at 200% of allocation speed. */
|
||||
#define LUA_MAXCAPTURES 32 /* Max. pattern captures. */
|
||||
|
||||
/* Compatibility with older library function names. */
|
||||
#define LUA_COMPAT_MOD /* OLD: math.mod, NEW: math.fmod */
|
||||
#define LUA_COMPAT_GFIND /* OLD: string.gfind, NEW: string.gmatch */
|
||||
|
||||
/* Configuration for the frontend (the luajit executable). */
|
||||
#if defined(luajit_c)
|
||||
#define LUA_PROGNAME "luajit" /* Fallback frontend name. */
|
||||
#define LUA_PROMPT "> " /* Interactive prompt. */
|
||||
#define LUA_PROMPT2 ">> " /* Continuation prompt. */
|
||||
#define LUA_MAXINPUT 512 /* Max. input line length. */
|
||||
#endif
|
||||
|
||||
/* Note: changing the following defines breaks the Lua 5.1 ABI. */
|
||||
#define LUA_INTEGER ptrdiff_t
|
||||
#define LUA_IDSIZE 60 /* Size of lua_Debug.short_src. */
|
||||
/*
|
||||
** Size of lauxlib and io.* on-stack buffers. Weird workaround to avoid using
|
||||
** unreasonable amounts of stack space, but still retain ABI compatibility.
|
||||
** Blame Lua for depending on BUFSIZ in the ABI, blame **** for wrecking it.
|
||||
*/
|
||||
#define LUAL_BUFFERSIZE (BUFSIZ > 16384 ? 8192 : BUFSIZ)
|
||||
|
||||
/* The following defines are here only for compatibility with luaconf.h
|
||||
** from the standard Lua distribution. They must not be changed for LuaJIT.
|
||||
*/
|
||||
#define LUA_NUMBER_DOUBLE
|
||||
#define LUA_NUMBER double
|
||||
#define LUAI_UACNUMBER double
|
||||
#define LUA_NUMBER_SCAN "%lf"
|
||||
#define LUA_NUMBER_FMT "%.14g"
|
||||
#define lua_number2str(s, n) sprintf((s), LUA_NUMBER_FMT, (n))
|
||||
#define LUAI_MAXNUMBER2STR 32
|
||||
#define LUA_INTFRMLEN "l"
|
||||
#define LUA_INTFRM_T long
|
||||
|
||||
/* Linkage of public API functions. */
|
||||
#if defined(LUA_BUILD_AS_DLL)
|
||||
#if defined(LUA_CORE) || defined(LUA_LIB)
|
||||
#define LUA_API __declspec(dllexport)
|
||||
#else
|
||||
#define LUA_API __declspec(dllimport)
|
||||
#endif
|
||||
#else
|
||||
#define LUA_API extern
|
||||
#endif
|
||||
|
||||
#define LUALIB_API LUA_API
|
||||
|
||||
/* Support for internal assertions. */
|
||||
#if defined(LUA_USE_ASSERT) || defined(LUA_USE_APICHECK)
|
||||
#include <assert.h>
|
||||
#endif
|
||||
#ifdef LUA_USE_ASSERT
|
||||
#define lua_assert(x) assert(x)
|
||||
#endif
|
||||
#ifdef LUA_USE_APICHECK
|
||||
#define luai_apicheck(L, o) { (void)L; assert(o); }
|
||||
#else
|
||||
#define luai_apicheck(L, o) { (void)L; }
|
||||
#endif
|
||||
|
||||
#endif
|
70
vendor/luajit/include/luajit.h
vendored
70
vendor/luajit/include/luajit.h
vendored
|
@ -1,70 +0,0 @@
|
|||
/*
|
||||
** LuaJIT -- a Just-In-Time Compiler for Lua. http://luajit.org/
|
||||
**
|
||||
** Copyright (C) 2005-2015 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 ]
|
||||
*/
|
||||
|
||||
#ifndef _LUAJIT_H
|
||||
#define _LUAJIT_H
|
||||
|
||||
#include "lua.h"
|
||||
|
||||
#define LUAJIT_VERSION "LuaJIT 2.0.4"
|
||||
#define LUAJIT_VERSION_NUM 20004 /* Version 2.0.4 = 02.00.04. */
|
||||
#define LUAJIT_VERSION_SYM luaJIT_version_2_0_4
|
||||
#define LUAJIT_COPYRIGHT "Copyright (C) 2005-2015 Mike Pall"
|
||||
#define LUAJIT_URL "http://luajit.org/"
|
||||
|
||||
/* Modes for luaJIT_setmode. */
|
||||
#define LUAJIT_MODE_MASK 0x00ff
|
||||
|
||||
enum {
|
||||
LUAJIT_MODE_ENGINE, /* Set mode for whole JIT engine. */
|
||||
LUAJIT_MODE_DEBUG, /* Set debug mode (idx = level). */
|
||||
|
||||
LUAJIT_MODE_FUNC, /* Change mode for a function. */
|
||||
LUAJIT_MODE_ALLFUNC, /* Recurse into subroutine protos. */
|
||||
LUAJIT_MODE_ALLSUBFUNC, /* Change only the subroutines. */
|
||||
|
||||
LUAJIT_MODE_TRACE, /* Flush a compiled trace. */
|
||||
|
||||
LUAJIT_MODE_WRAPCFUNC = 0x10, /* Set wrapper mode for C function calls. */
|
||||
|
||||
LUAJIT_MODE_MAX
|
||||
};
|
||||
|
||||
/* Flags or'ed in to the mode. */
|
||||
#define LUAJIT_MODE_OFF 0x0000 /* Turn feature off. */
|
||||
#define LUAJIT_MODE_ON 0x0100 /* Turn feature on. */
|
||||
#define LUAJIT_MODE_FLUSH 0x0200 /* Flush JIT-compiled code. */
|
||||
|
||||
/* LuaJIT public C API. */
|
||||
|
||||
/* Control the JIT engine. */
|
||||
LUA_API int luaJIT_setmode(lua_State *L, int idx, int mode);
|
||||
|
||||
/* Enforce (dynamic) linker error for version mismatches. Call from main. */
|
||||
LUA_API void LUAJIT_VERSION_SYM(void);
|
||||
|
||||
#endif
|
43
vendor/luajit/include/lualib.h
vendored
43
vendor/luajit/include/lualib.h
vendored
|
@ -1,43 +0,0 @@
|
|||
/*
|
||||
** Standard library header.
|
||||
** Copyright (C) 2005-2015 Mike Pall. See Copyright Notice in luajit.h
|
||||
*/
|
||||
|
||||
#ifndef _LUALIB_H
|
||||
#define _LUALIB_H
|
||||
|
||||
#include "lua.h"
|
||||
|
||||
#define LUA_FILEHANDLE "FILE*"
|
||||
|
||||
#define LUA_COLIBNAME "coroutine"
|
||||
#define LUA_MATHLIBNAME "math"
|
||||
#define LUA_STRLIBNAME "string"
|
||||
#define LUA_TABLIBNAME "table"
|
||||
#define LUA_IOLIBNAME "io"
|
||||
#define LUA_OSLIBNAME "os"
|
||||
#define LUA_LOADLIBNAME "package"
|
||||
#define LUA_DBLIBNAME "debug"
|
||||
#define LUA_BITLIBNAME "bit"
|
||||
#define LUA_JITLIBNAME "jit"
|
||||
#define LUA_FFILIBNAME "ffi"
|
||||
|
||||
LUALIB_API int luaopen_base(lua_State *L);
|
||||
LUALIB_API int luaopen_math(lua_State *L);
|
||||
LUALIB_API int luaopen_string(lua_State *L);
|
||||
LUALIB_API int luaopen_table(lua_State *L);
|
||||
LUALIB_API int luaopen_io(lua_State *L);
|
||||
LUALIB_API int luaopen_os(lua_State *L);
|
||||
LUALIB_API int luaopen_package(lua_State *L);
|
||||
LUALIB_API int luaopen_debug(lua_State *L);
|
||||
LUALIB_API int luaopen_bit(lua_State *L);
|
||||
LUALIB_API int luaopen_jit(lua_State *L);
|
||||
LUALIB_API int luaopen_ffi(lua_State *L);
|
||||
|
||||
LUALIB_API void luaL_openlibs(lua_State *L);
|
||||
|
||||
#ifndef lua_assert
|
||||
#define lua_assert(x) ((void)0)
|
||||
#endif
|
||||
|
||||
#endif
|
7
vendor/luajit/src/.gitignore
vendored
Normal file
7
vendor/luajit/src/.gitignore
vendored
Normal file
|
@ -0,0 +1,7 @@
|
|||
luajit
|
||||
lj_bcdef.h
|
||||
lj_ffdef.h
|
||||
lj_libdef.h
|
||||
lj_recdef.h
|
||||
lj_folddef.h
|
||||
lj_vm.[sS]
|
178
vendor/luajit/src/Makefile
vendored
178
vendor/luajit/src/Makefile
vendored
|
@ -7,12 +7,12 @@
|
|||
# Also works with MinGW and Cygwin on Windows.
|
||||
# Please check msvcbuild.bat for building with MSVC on Windows.
|
||||
#
|
||||
# Copyright (C) 2005-2015 Mike Pall. See Copyright Notice in luajit.h
|
||||
# Copyright (C) 2005-2017 Mike Pall. See Copyright Notice in luajit.h
|
||||
##############################################################################
|
||||
|
||||
MAJVER= 2
|
||||
MINVER= 0
|
||||
RELVER= 4
|
||||
MINVER= 1
|
||||
RELVER= 0
|
||||
ABIVER= 5.1
|
||||
NODOTABIVER= 51
|
||||
|
||||
|
@ -24,11 +24,13 @@ NODOTABIVER= 51
|
|||
# removing the '#' in front of them. Make sure you force a full recompile
|
||||
# with "make clean", followed by "make" if you change any options.
|
||||
#
|
||||
DEFAULT_CC = gcc
|
||||
#
|
||||
# LuaJIT builds as a native 32 or 64 bit binary by default.
|
||||
CC= gcc
|
||||
CC= $(DEFAULT_CC)
|
||||
#
|
||||
# Use this if you want to force a 32 bit build on a 64 bit multilib OS.
|
||||
#CC= gcc -m32
|
||||
#CC= $(DEFAULT_CC) -m32
|
||||
#
|
||||
# Since the assembler part does NOT maintain a frame pointer, it's pointless
|
||||
# to slow down the C part by not omitting it. Debugging, tracebacks and
|
||||
|
@ -42,17 +44,14 @@ CCOPT= -O2 -fomit-frame-pointer
|
|||
#
|
||||
# Target-specific compiler options:
|
||||
#
|
||||
# x86 only: it's recommended to compile at least for i686. Better yet,
|
||||
# compile for an architecture that has SSE2, too (-msse -msse2).
|
||||
#
|
||||
# x86/x64 only: For GCC 4.2 or higher and if you don't intend to distribute
|
||||
# the binaries to a different machine you could also use: -march=native
|
||||
#
|
||||
CCOPT_x86= -march=i686
|
||||
CCOPT_x86= -march=i686 -msse -msse2 -mfpmath=sse
|
||||
CCOPT_x64=
|
||||
CCOPT_arm=
|
||||
CCOPT_arm64=
|
||||
CCOPT_ppc=
|
||||
CCOPT_ppcspe=
|
||||
CCOPT_mips=
|
||||
#
|
||||
#CCDEBUG=
|
||||
|
@ -88,7 +87,7 @@ BUILDMODE= static
|
|||
##############################################################################
|
||||
# Enable/disable these features as needed, but make sure you force a full
|
||||
# recompile with "make clean", followed by "make".
|
||||
XCFLAGS=-Igen
|
||||
XCFLAGS=
|
||||
#
|
||||
# Permanently disable the FFI extension to reduce the size of the LuaJIT
|
||||
# executable. But please consider that the FFI library is compiled-in,
|
||||
|
@ -111,6 +110,9 @@ XCFLAGS+= -DLUAJIT_ENABLE_LUA52COMPAT
|
|||
#XCFLAGS+= -DLUAJIT_NUMMODE=1
|
||||
#XCFLAGS+= -DLUAJIT_NUMMODE=2
|
||||
#
|
||||
# Enable GC64 mode for x64.
|
||||
#XCFLAGS+= -DLUAJIT_ENABLE_GC64
|
||||
#
|
||||
##############################################################################
|
||||
|
||||
##############################################################################
|
||||
|
@ -122,8 +124,8 @@ XCFLAGS+= -DLUAJIT_ENABLE_LUA52COMPAT
|
|||
#
|
||||
# Use the system provided memory allocator (realloc) instead of the
|
||||
# bundled memory allocator. This is slower, but sometimes helpful for
|
||||
# debugging. This option cannot be enabled on x64, since realloc usually
|
||||
# doesn't return addresses in the right address range.
|
||||
# debugging. This option cannot be enabled on x64 without GC64, since
|
||||
# realloc usually doesn't return addresses in the right address range.
|
||||
# OTOH this option is mandatory for Valgrind's memcheck tool on x64 and
|
||||
# the only way to get useful results from it for all other architectures.
|
||||
#XCFLAGS+= -DLUAJIT_USE_SYSMALLOC
|
||||
|
@ -150,6 +152,25 @@ XCFLAGS+= -DLUAJIT_ENABLE_LUA52COMPAT
|
|||
# You probably don't need to change anything below this line!
|
||||
##############################################################################
|
||||
|
||||
##############################################################################
|
||||
# Host system detection.
|
||||
##############################################################################
|
||||
|
||||
ifeq (Windows,$(findstring Windows,$(OS))$(MSYSTEM)$(TERM))
|
||||
HOST_SYS= Windows
|
||||
HOST_RM= del
|
||||
else
|
||||
HOST_SYS:= $(shell uname -s)
|
||||
ifneq (,$(findstring MINGW,$(HOST_SYS)))
|
||||
HOST_SYS= Windows
|
||||
HOST_MSYS= mingw
|
||||
endif
|
||||
ifneq (,$(findstring CYGWIN,$(HOST_SYS)))
|
||||
HOST_SYS= Windows
|
||||
HOST_MSYS= cygwin
|
||||
endif
|
||||
endif
|
||||
|
||||
##############################################################################
|
||||
# Flags and options for host and target.
|
||||
##############################################################################
|
||||
|
@ -165,7 +186,8 @@ XCFLAGS+= -DLUAJIT_ENABLE_LUA52COMPAT
|
|||
# make HOST_CC="gcc -m32" CROSS=i586-mingw32msvc- TARGET_SYS=Windows
|
||||
# make HOST_CC="gcc -m32" CROSS=powerpc-linux-gnu-
|
||||
|
||||
CCOPTIONS= $(CCDEBUG) $(CCOPT) $(CCWARN) $(XCFLAGS) $(CFLAGS)
|
||||
ASOPTIONS= $(CCOPT) $(CCWARN) $(XCFLAGS) $(CFLAGS)
|
||||
CCOPTIONS= $(CCDEBUG) $(ASOPTIONS)
|
||||
LDOPTIONS= $(CCDEBUG) $(LDFLAGS)
|
||||
|
||||
HOST_CC= $(CC)
|
||||
|
@ -187,14 +209,14 @@ TARGET_CC= $(STATIC_CC)
|
|||
TARGET_STCC= $(STATIC_CC)
|
||||
TARGET_DYNCC= $(DYNAMIC_CC)
|
||||
TARGET_LD= $(CROSS)$(CC)
|
||||
TARGET_AR= $(CROSS)ar rcus
|
||||
TARGET_AR= $(CROSS)ar rcus 2>/dev/null
|
||||
TARGET_STRIP= $(CROSS)strip
|
||||
|
||||
TARGET_LIBPATH= $(CURDIR)
|
||||
#TARGET_LIBPATH= $(or $(PREFIX),/usr/local)/$(or $(MULTILIB),lib)
|
||||
TARGET_LIBPATH= $(CURDIR)
|
||||
TARGET_SONAME= libluajit-$(ABIVER).so.$(MAJVER)
|
||||
TARGET_DYLIBNAME= libluajit-aegisub.so
|
||||
#TARGET_DYLIBNAME= libluajit-$(ABIVER).$(MAJVER).dylib
|
||||
TARGET_DYLIBNAME= libluajit-aegisub.so
|
||||
TARGET_DYLIBPATH= $(TARGET_LIBPATH)/$(TARGET_DYLIBNAME)
|
||||
TARGET_DLLNAME= lua$(NODOTABIVER).dll
|
||||
TARGET_XSHLDFLAGS= -shared -fPIC -Wl,-soname,$(TARGET_SONAME)
|
||||
|
@ -206,6 +228,7 @@ TARGET_XLDFLAGS=
|
|||
TARGET_XLIBS= -lm
|
||||
TARGET_TCFLAGS= $(CCOPTIONS) $(TARGET_XCFLAGS) $(TARGET_FLAGS) $(TARGET_CFLAGS)
|
||||
TARGET_ACFLAGS= $(CCOPTIONS) $(TARGET_XCFLAGS) $(TARGET_FLAGS) $(TARGET_CFLAGS)
|
||||
TARGET_ASFLAGS= $(ASOPTIONS) $(TARGET_XCFLAGS) $(TARGET_FLAGS) $(TARGET_CFLAGS)
|
||||
TARGET_ALDFLAGS= $(LDOPTIONS) $(TARGET_XLDFLAGS) $(TARGET_FLAGS) $(TARGET_LDFLAGS)
|
||||
TARGET_ASHLDFLAGS= $(LDOPTIONS) $(TARGET_XSHLDFLAGS) $(TARGET_FLAGS) $(TARGET_SHLDFLAGS)
|
||||
TARGET_ALIBS= $(TARGET_XLIBS) $(LIBS) $(TARGET_LIBS)
|
||||
|
@ -220,17 +243,29 @@ else
|
|||
ifneq (,$(findstring LJ_TARGET_ARM ,$(TARGET_TESTARCH)))
|
||||
TARGET_LJARCH= arm
|
||||
else
|
||||
ifneq (,$(findstring LJ_TARGET_PPC ,$(TARGET_TESTARCH)))
|
||||
TARGET_LJARCH= ppc
|
||||
ifneq (,$(findstring LJ_TARGET_ARM64 ,$(TARGET_TESTARCH)))
|
||||
ifneq (,$(findstring __AARCH64EB__ ,$(TARGET_TESTARCH)))
|
||||
TARGET_ARCH= -D__AARCH64EB__=1
|
||||
endif
|
||||
TARGET_LJARCH= arm64
|
||||
else
|
||||
ifneq (,$(findstring LJ_TARGET_PPCSPE ,$(TARGET_TESTARCH)))
|
||||
TARGET_LJARCH= ppcspe
|
||||
ifneq (,$(findstring LJ_TARGET_PPC ,$(TARGET_TESTARCH)))
|
||||
ifneq (,$(findstring LJ_LE 1,$(TARGET_TESTARCH)))
|
||||
TARGET_ARCH= -DLJ_ARCH_ENDIAN=LUAJIT_LE
|
||||
else
|
||||
TARGET_ARCH= -DLJ_ARCH_ENDIAN=LUAJIT_BE
|
||||
endif
|
||||
TARGET_LJARCH= ppc
|
||||
else
|
||||
ifneq (,$(findstring LJ_TARGET_MIPS ,$(TARGET_TESTARCH)))
|
||||
ifneq (,$(findstring MIPSEL ,$(TARGET_TESTARCH)))
|
||||
TARGET_ARCH= -D__MIPSEL__=1
|
||||
endif
|
||||
TARGET_LJARCH= mips
|
||||
ifneq (,$(findstring LJ_TARGET_MIPS64 ,$(TARGET_TESTARCH)))
|
||||
TARGET_LJARCH= mips64
|
||||
else
|
||||
TARGET_LJARCH= mips
|
||||
endif
|
||||
else
|
||||
$(error Unsupported target architecture)
|
||||
endif
|
||||
|
@ -244,9 +279,7 @@ ifneq (,$(findstring LJ_TARGET_PS3 1,$(TARGET_TESTARCH)))
|
|||
TARGET_SYS= PS3
|
||||
TARGET_ARCH+= -D__CELLOS_LV2__
|
||||
TARGET_XCFLAGS+= -DLUAJIT_USE_SYSMALLOC
|
||||
endif
|
||||
ifneq (,$(findstring LJ_NO_UNWIND 1,$(TARGET_TESTARCH)))
|
||||
TARGET_ARCH+= -DLUAJIT_NO_UNWIND
|
||||
TARGET_XLIBS+= -lpthread
|
||||
endif
|
||||
|
||||
TARGET_XCFLAGS+= $(CCOPT_$(TARGET_LJARCH))
|
||||
|
@ -268,24 +301,9 @@ ifneq (,$(LMULTILIB))
|
|||
endif
|
||||
|
||||
##############################################################################
|
||||
# System detection.
|
||||
# Target system detection.
|
||||
##############################################################################
|
||||
|
||||
ifeq (Windows,$(findstring Windows,$(OS))$(MSYSTEM)$(TERM))
|
||||
HOST_SYS= Windows
|
||||
HOST_RM= del
|
||||
else
|
||||
HOST_SYS:= $(shell uname -s)
|
||||
ifneq (,$(findstring MINGW,$(HOST_SYS)))
|
||||
HOST_SYS= Windows
|
||||
HOST_MSYS= mingw
|
||||
endif
|
||||
ifneq (,$(findstring CYGWIN,$(HOST_SYS)))
|
||||
HOST_SYS= Windows
|
||||
HOST_MSYS= cygwin
|
||||
endif
|
||||
endif
|
||||
|
||||
TARGET_SYS?= $(HOST_SYS)
|
||||
ifeq (Windows,$(TARGET_SYS))
|
||||
TARGET_STRIP+= --strip-unneeded
|
||||
|
@ -300,7 +318,6 @@ ifeq (Darwin,$(TARGET_SYS))
|
|||
export MACOSX_DEPLOYMENT_TARGET=10.4
|
||||
endif
|
||||
TARGET_STRIP+= -x
|
||||
TARGET_AR+= 2>/dev/null
|
||||
TARGET_XSHLDFLAGS= -dynamiclib -single_module -undefined dynamic_lookup -fPIC
|
||||
TARGET_DYNXLDOPTS=
|
||||
TARGET_XSHLDFLAGS+= -install_name $(TARGET_DYLIBPATH) -compatibility_version $(MAJVER).$(MINVER) -current_version $(MAJVER).$(MINVER).$(RELVER)
|
||||
|
@ -311,10 +328,12 @@ ifeq (Darwin,$(TARGET_SYS))
|
|||
else
|
||||
ifeq (iOS,$(TARGET_SYS))
|
||||
TARGET_STRIP+= -x
|
||||
TARGET_AR+= 2>/dev/null
|
||||
TARGET_XSHLDFLAGS= -dynamiclib -single_module -undefined dynamic_lookup -fPIC
|
||||
TARGET_DYNXLDOPTS=
|
||||
TARGET_XSHLDFLAGS+= -install_name $(TARGET_DYLIBPATH) -compatibility_version $(MAJVER).$(MINVER) -current_version $(MAJVER).$(MINVER).$(RELVER)
|
||||
ifeq (arm64,$(TARGET_LJARCH))
|
||||
TARGET_XCFLAGS+= -fno-omit-frame-pointer
|
||||
endif
|
||||
else
|
||||
ifneq (SunOS,$(TARGET_SYS))
|
||||
ifneq (PS3,$(TARGET_SYS))
|
||||
|
@ -375,6 +394,11 @@ DASM_XFLAGS=
|
|||
DASM_AFLAGS=
|
||||
DASM_ARCH= $(TARGET_LJARCH)
|
||||
|
||||
ifneq (,$(findstring LJ_LE 1,$(TARGET_TESTARCH)))
|
||||
DASM_AFLAGS+= -D ENDIAN_LE
|
||||
else
|
||||
DASM_AFLAGS+= -D ENDIAN_BE
|
||||
endif
|
||||
ifneq (,$(findstring LJ_ARCH_BITS 64,$(TARGET_TESTARCH)))
|
||||
DASM_AFLAGS+= -D P64
|
||||
endif
|
||||
|
@ -399,17 +423,18 @@ ifeq (,$(findstring LJ_ABI_SOFTFP 1,$(TARGET_TESTARCH)))
|
|||
else
|
||||
TARGET_ARCH+= -DLJ_ABI_SOFTFP=1
|
||||
endif
|
||||
ifneq (,$(findstring LJ_NO_UNWIND 1,$(TARGET_TESTARCH)))
|
||||
DASM_AFLAGS+= -D NO_UNWIND
|
||||
TARGET_ARCH+= -DLUAJIT_NO_UNWIND
|
||||
endif
|
||||
DASM_AFLAGS+= -D VER=$(subst LJ_ARCH_VERSION_,,$(filter LJ_ARCH_VERSION_%,$(subst LJ_ARCH_VERSION ,LJ_ARCH_VERSION_,$(TARGET_TESTARCH))))
|
||||
ifeq (Windows,$(TARGET_SYS))
|
||||
DASM_AFLAGS+= -D WIN
|
||||
endif
|
||||
ifeq (x86,$(TARGET_LJARCH))
|
||||
ifneq (,$(findstring __SSE2__ 1,$(TARGET_TESTARCH)))
|
||||
DASM_AFLAGS+= -D SSE
|
||||
endif
|
||||
else
|
||||
ifeq (x64,$(TARGET_LJARCH))
|
||||
DASM_ARCH= x86
|
||||
ifeq (,$(findstring LJ_FR2 1,$(TARGET_TESTARCH)))
|
||||
DASM_ARCH= x86
|
||||
endif
|
||||
else
|
||||
ifeq (arm,$(TARGET_LJARCH))
|
||||
ifeq (iOS,$(TARGET_SYS))
|
||||
|
@ -423,13 +448,15 @@ ifeq (ppc,$(TARGET_LJARCH))
|
|||
ifneq (,$(findstring LJ_ARCH_ROUND 1,$(TARGET_TESTARCH)))
|
||||
DASM_AFLAGS+= -D ROUND
|
||||
endif
|
||||
ifneq (,$(findstring LJ_ARCH_PPC64 1,$(TARGET_TESTARCH)))
|
||||
ifneq (,$(findstring LJ_ARCH_PPC32ON64 1,$(TARGET_TESTARCH)))
|
||||
DASM_AFLAGS+= -D GPR64
|
||||
endif
|
||||
ifeq (PS3,$(TARGET_SYS))
|
||||
DASM_AFLAGS+= -D PPE -D TOC
|
||||
endif
|
||||
endif
|
||||
ifneq (,$(findstring LJ_ARCH_PPC64 ,$(TARGET_TESTARCH)))
|
||||
DASM_ARCH= ppc64
|
||||
endif
|
||||
endif
|
||||
endif
|
||||
endif
|
||||
|
@ -445,7 +472,7 @@ BUILDVM_X= $(BUILDVM_T)
|
|||
HOST_O= $(MINILUA_O) $(BUILDVM_O)
|
||||
HOST_T= $(MINILUA_T) $(BUILDVM_T)
|
||||
|
||||
LJVM_S= lj_vm.s
|
||||
LJVM_S= lj_vm.S
|
||||
LJVM_O= lj_vm.o
|
||||
LJVM_BOUT= $(LJVM_S)
|
||||
LJVM_MODE= elfasm
|
||||
|
@ -454,10 +481,11 @@ LJLIB_O= lib_base.o lib_math.o lib_bit.o lib_string.o lib_table.o \
|
|||
lib_io.o lib_os.o lib_package.o lib_debug.o lib_jit.o lib_ffi.o
|
||||
LJLIB_C= $(LJLIB_O:.o=.c)
|
||||
|
||||
LJCORE_O= lj_gc.o lj_err.o lj_char.o lj_bc.o lj_obj.o \
|
||||
LJCORE_O= lj_gc.o lj_err.o lj_char.o lj_bc.o lj_obj.o lj_buf.o \
|
||||
lj_str.o lj_tab.o lj_func.o lj_udata.o lj_meta.o lj_debug.o \
|
||||
lj_state.o lj_dispatch.o lj_vmevent.o lj_vmmath.o lj_strscan.o \
|
||||
lj_api.o lj_lex.o lj_parse.o lj_bcread.o lj_bcwrite.o lj_load.o \
|
||||
lj_strfmt.o lj_strfmt_num.o lj_api.o lj_profile.o \
|
||||
lj_lex.o lj_parse.o lj_bcread.o lj_bcwrite.o lj_load.o \
|
||||
lj_ir.o lj_opt_mem.o lj_opt_fold.o lj_opt_narrow.o \
|
||||
lj_opt_dce.o lj_opt_loop.o lj_opt_split.o lj_opt_sink.o \
|
||||
lj_mcode.o lj_snap.o lj_record.o lj_crecord.o lj_ffrecord.o \
|
||||
|
@ -479,8 +507,8 @@ LUAJIT_SO= libluajit-aegisub.so
|
|||
LUAJIT_T= luajit
|
||||
|
||||
ALL_T= $(LUAJIT_T) $(LUAJIT_A) $(LUAJIT_SO) $(HOST_T)
|
||||
ALL_HDRGEN= gen/lj_bcdef.h gen/lj_ffdef.h gen/lj_libdef.h gen/lj_recdef.h gen/lj_folddef.h \
|
||||
gen/buildvm_arch.h
|
||||
ALL_HDRGEN= lj_bcdef.h lj_ffdef.h lj_libdef.h lj_recdef.h lj_folddef.h \
|
||||
host/buildvm_arch.h
|
||||
ALL_GEN= $(LJVM_S) $(ALL_HDRGEN) $(LIB_VMDEFP)
|
||||
WIN_RM= *.obj *.lib *.exp *.dll *.exe *.manifest *.pdb *.ilk
|
||||
ALL_RM= $(ALL_T) $(ALL_GEN) *.o host/*.o $(WIN_RM)
|
||||
|
@ -513,9 +541,6 @@ ifeq (Windows,$(TARGET_SYS))
|
|||
endif
|
||||
ifeq (Darwin,$(TARGET_SYS))
|
||||
LJVM_MODE= machasm
|
||||
# -dead_strip breaks LuaJIT, but we really want it for everything else, so we
|
||||
# have to dynamically link it
|
||||
BUILDMODE= dynamic
|
||||
endif
|
||||
ifeq (iOS,$(TARGET_SYS))
|
||||
LJVM_MODE= machasm
|
||||
|
@ -562,13 +587,10 @@ endif
|
|||
endif
|
||||
endif
|
||||
|
||||
ifeq ($(V),1)
|
||||
Q=
|
||||
E= @:
|
||||
else
|
||||
Q= @
|
||||
E= @echo
|
||||
endif
|
||||
#Q=
|
||||
#E= @:
|
||||
|
||||
##############################################################################
|
||||
# Make targets.
|
||||
|
@ -577,11 +599,16 @@ endif
|
|||
default all: $(TARGET_T)
|
||||
|
||||
amalg:
|
||||
@grep "^[+|]" ljamalg.c
|
||||
$(MAKE) all "LJCORE_O=ljamalg.o"
|
||||
|
||||
clean:
|
||||
$(HOST_RM) $(ALL_RM)
|
||||
|
||||
libbc:
|
||||
./$(LUAJIT_T) host/genlibbc.lua -o host/buildvm_libbc.h $(LJLIB_C)
|
||||
$(MAKE) all
|
||||
|
||||
depend:
|
||||
@for file in $(ALL_HDRGEN); do \
|
||||
test -f $$file || touch $$file; \
|
||||
|
@ -596,7 +623,7 @@ depend:
|
|||
test -s $$file || $(HOST_RM) $$file; \
|
||||
done
|
||||
|
||||
.PHONY: default all amalg clean depend
|
||||
.PHONY: default all amalg clean libbc depend
|
||||
|
||||
##############################################################################
|
||||
# Rules for generated files.
|
||||
|
@ -606,10 +633,7 @@ $(MINILUA_T): $(MINILUA_O)
|
|||
$(E) "HOSTLINK $@"
|
||||
$(Q)$(HOST_CC) $(HOST_ALDFLAGS) -o $@ $(MINILUA_O) $(MINILUA_LIBS) $(HOST_ALIBS)
|
||||
|
||||
gen:
|
||||
mkdir -p gen
|
||||
|
||||
gen/buildvm_arch.h: $(DASM_DASC) $(DASM_DEP) gen
|
||||
host/buildvm_arch.h: $(DASM_DASC) $(DASM_DEP) $(DASM_DIR)/*.lua
|
||||
$(E) "DYNASM $@"
|
||||
$(Q)$(DASM) $(DASM_FLAGS) -o $@ $(DASM_DASC)
|
||||
|
||||
|
@ -623,19 +647,19 @@ $(LJVM_BOUT): $(BUILDVM_T)
|
|||
$(E) "BUILDVM $@"
|
||||
$(Q)$(BUILDVM_X) -m $(LJVM_MODE) -o $@
|
||||
|
||||
gen/lj_bcdef.h: $(BUILDVM_T) $(LJLIB_C)
|
||||
lj_bcdef.h: $(BUILDVM_T) $(LJLIB_C)
|
||||
$(E) "BUILDVM $@"
|
||||
$(Q)$(BUILDVM_X) -m bcdef -o $@ $(LJLIB_C)
|
||||
|
||||
gen/lj_ffdef.h: $(BUILDVM_T) $(LJLIB_C)
|
||||
lj_ffdef.h: $(BUILDVM_T) $(LJLIB_C)
|
||||
$(E) "BUILDVM $@"
|
||||
$(Q)$(BUILDVM_X) -m ffdef -o $@ $(LJLIB_C)
|
||||
|
||||
gen/lj_libdef.h: $(BUILDVM_T) $(LJLIB_C)
|
||||
lj_libdef.h: $(BUILDVM_T) $(LJLIB_C)
|
||||
$(E) "BUILDVM $@"
|
||||
$(Q)$(BUILDVM_X) -m libdef -o $@ $(LJLIB_C)
|
||||
|
||||
gen/lj_recdef.h: $(BUILDVM_T) $(LJLIB_C)
|
||||
lj_recdef.h: $(BUILDVM_T) $(LJLIB_C)
|
||||
$(E) "BUILDVM $@"
|
||||
$(Q)$(BUILDVM_X) -m recdef -o $@ $(LJLIB_C)
|
||||
|
||||
|
@ -643,7 +667,7 @@ $(LIB_VMDEF): $(BUILDVM_T) $(LJLIB_C)
|
|||
$(E) "BUILDVM $@"
|
||||
$(Q)$(BUILDVM_X) -m vmdef -o $(LIB_VMDEFP) $(LJLIB_C)
|
||||
|
||||
gen/lj_folddef.h: $(BUILDVM_T) lj_opt_fold.c
|
||||
lj_folddef.h: $(BUILDVM_T) lj_opt_fold.c
|
||||
$(E) "BUILDVM $@"
|
||||
$(Q)$(BUILDVM_X) -m folddef -o $@ lj_opt_fold.c
|
||||
|
||||
|
@ -656,10 +680,10 @@ gen/lj_folddef.h: $(BUILDVM_T) lj_opt_fold.c
|
|||
$(Q)$(TARGET_DYNCC) $(TARGET_ACFLAGS) -c -o $(@:.o=_dyn.o) $<
|
||||
$(Q)$(TARGET_CC) $(TARGET_ACFLAGS) -c -o $@ $<
|
||||
|
||||
%.o: %.s
|
||||
%.o: %.S
|
||||
$(E) "ASM $@"
|
||||
$(Q)$(TARGET_DYNCC) $(TARGET_ACFLAGS) -c -o $(@:.o=_dyn.o) $<
|
||||
$(Q)$(TARGET_CC) $(TARGET_ACFLAGS) -c -o $@ $<
|
||||
$(Q)$(TARGET_DYNCC) $(TARGET_ASFLAGS) -c -o $(@:.o=_dyn.o) $<
|
||||
$(Q)$(TARGET_CC) $(TARGET_ASFLAGS) -c -o $@ $<
|
||||
|
||||
$(LUAJIT_O):
|
||||
$(E) "CC $@"
|
||||
|
|
228
vendor/luajit/src/Makefile.dep
vendored
228
vendor/luajit/src/Makefile.dep
vendored
|
@ -3,64 +3,71 @@ lib_aux.o: lib_aux.c lua.h luaconf.h lauxlib.h lj_obj.h lj_def.h \
|
|||
lj_dispatch.h lj_bc.h lj_traceerr.h lj_lib.h lj_alloc.h
|
||||
lib_base.o: lib_base.c lua.h luaconf.h lauxlib.h lualib.h lj_obj.h \
|
||||
lj_def.h lj_arch.h lj_gc.h lj_err.h lj_errmsg.h lj_debug.h lj_str.h \
|
||||
lj_tab.h lj_meta.h lj_state.h lj_ctype.h lj_cconv.h lj_bc.h lj_ff.h \
|
||||
gen/lj_ffdef.h lj_dispatch.h lj_jit.h lj_ir.h lj_char.h lj_strscan.h \
|
||||
lj_lib.h gen/lj_libdef.h
|
||||
lj_tab.h lj_meta.h lj_state.h lj_frame.h lj_bc.h lj_ctype.h lj_cconv.h \
|
||||
lj_ff.h lj_ffdef.h lj_dispatch.h lj_jit.h lj_ir.h lj_char.h lj_strscan.h \
|
||||
lj_strfmt.h lj_lib.h lj_libdef.h
|
||||
lib_bit.o: lib_bit.c lua.h luaconf.h lauxlib.h lualib.h lj_obj.h lj_def.h \
|
||||
lj_arch.h lj_err.h lj_errmsg.h lj_str.h lj_lib.h gen/lj_libdef.h
|
||||
lj_arch.h lj_err.h lj_errmsg.h lj_buf.h lj_gc.h lj_str.h lj_strscan.h \
|
||||
lj_strfmt.h lj_ctype.h lj_cdata.h lj_cconv.h lj_carith.h lj_ff.h \
|
||||
lj_ffdef.h lj_lib.h lj_libdef.h
|
||||
lib_debug.o: lib_debug.c lua.h luaconf.h lauxlib.h lualib.h lj_obj.h \
|
||||
lj_def.h lj_arch.h lj_gc.h lj_err.h lj_errmsg.h lj_debug.h lj_lib.h \
|
||||
gen/lj_libdef.h
|
||||
lj_libdef.h
|
||||
lib_ffi.o: lib_ffi.c lua.h luaconf.h lauxlib.h lualib.h lj_obj.h lj_def.h \
|
||||
lj_arch.h lj_gc.h lj_err.h lj_errmsg.h lj_str.h lj_tab.h lj_meta.h \
|
||||
lj_ctype.h lj_cparse.h lj_cdata.h lj_cconv.h lj_carith.h lj_ccall.h \
|
||||
lj_ccallback.h lj_clib.h lj_ff.h gen/lj_ffdef.h lj_lib.h gen/lj_libdef.h
|
||||
lj_ccallback.h lj_clib.h lj_strfmt.h lj_ff.h lj_ffdef.h lj_lib.h \
|
||||
lj_libdef.h
|
||||
lib_init.o: lib_init.c lua.h luaconf.h lauxlib.h lualib.h lj_arch.h
|
||||
lib_io.o: lib_io.c lua.h luaconf.h lauxlib.h lualib.h lj_obj.h lj_def.h \
|
||||
lj_arch.h lj_gc.h lj_err.h lj_errmsg.h lj_str.h lj_state.h lj_ff.h \
|
||||
gen/lj_ffdef.h lj_lib.h gen/lj_libdef.h
|
||||
lib_jit.o: lib_jit.c lua.h luaconf.h lauxlib.h lualib.h lj_arch.h \
|
||||
lj_obj.h lj_def.h lj_err.h lj_errmsg.h lj_debug.h lj_str.h lj_tab.h \
|
||||
lj_bc.h lj_ir.h lj_jit.h lj_ircall.h lj_iropt.h lj_target.h \
|
||||
lj_target_*.h lj_dispatch.h lj_vm.h lj_vmevent.h lj_lib.h luajit.h \
|
||||
gen/lj_libdef.h
|
||||
lj_arch.h lj_gc.h lj_err.h lj_errmsg.h lj_buf.h lj_str.h lj_state.h \
|
||||
lj_strfmt.h lj_ff.h lj_ffdef.h lj_lib.h lj_libdef.h
|
||||
lib_jit.o: lib_jit.c lua.h luaconf.h lauxlib.h lualib.h lj_obj.h lj_def.h \
|
||||
lj_arch.h lj_gc.h lj_err.h lj_errmsg.h lj_debug.h lj_str.h lj_tab.h \
|
||||
lj_state.h lj_bc.h lj_ctype.h lj_ir.h lj_jit.h lj_ircall.h lj_iropt.h \
|
||||
lj_target.h lj_target_*.h lj_trace.h lj_dispatch.h lj_traceerr.h \
|
||||
lj_vm.h lj_vmevent.h lj_lib.h luajit.h lj_libdef.h
|
||||
lib_math.o: lib_math.c lua.h luaconf.h lauxlib.h lualib.h lj_obj.h \
|
||||
lj_def.h lj_arch.h lj_lib.h lj_vm.h gen/lj_libdef.h
|
||||
lj_def.h lj_arch.h lj_lib.h lj_vm.h lj_libdef.h
|
||||
lib_os.o: lib_os.c lua.h luaconf.h lauxlib.h lualib.h lj_obj.h lj_def.h \
|
||||
lj_arch.h lj_err.h lj_errmsg.h lj_lib.h gen/lj_libdef.h
|
||||
lj_arch.h lj_gc.h lj_err.h lj_errmsg.h lj_buf.h lj_str.h lj_lib.h \
|
||||
lj_libdef.h
|
||||
lib_package.o: lib_package.c lua.h luaconf.h lauxlib.h lualib.h lj_obj.h \
|
||||
lj_def.h lj_arch.h lj_err.h lj_errmsg.h lj_lib.h
|
||||
lib_string.o: lib_string.c lua.h luaconf.h lauxlib.h lualib.h lj_obj.h \
|
||||
lj_def.h lj_arch.h lj_gc.h lj_err.h lj_errmsg.h lj_str.h lj_tab.h \
|
||||
lj_meta.h lj_state.h lj_ff.h gen/lj_ffdef.h lj_bcdump.h lj_lex.h lj_char.h \
|
||||
lj_lib.h gen/lj_libdef.h
|
||||
lj_def.h lj_arch.h lj_gc.h lj_err.h lj_errmsg.h lj_buf.h lj_str.h \
|
||||
lj_tab.h lj_meta.h lj_state.h lj_ff.h lj_ffdef.h lj_bcdump.h lj_lex.h \
|
||||
lj_char.h lj_strfmt.h lj_lib.h lj_libdef.h
|
||||
lib_table.o: lib_table.c lua.h luaconf.h lauxlib.h lualib.h lj_obj.h \
|
||||
lj_def.h lj_arch.h lj_gc.h lj_err.h lj_errmsg.h lj_tab.h lj_lib.h \
|
||||
gen/lj_libdef.h
|
||||
lj_def.h lj_arch.h lj_gc.h lj_err.h lj_errmsg.h lj_buf.h lj_str.h \
|
||||
lj_tab.h lj_ff.h lj_ffdef.h lj_lib.h lj_libdef.h
|
||||
lj_alloc.o: lj_alloc.c lj_def.h lua.h luaconf.h lj_arch.h lj_alloc.h
|
||||
lj_api.o: lj_api.c lj_obj.h lua.h luaconf.h lj_def.h lj_arch.h lj_gc.h \
|
||||
lj_err.h lj_errmsg.h lj_debug.h lj_str.h lj_tab.h lj_func.h lj_udata.h \
|
||||
lj_meta.h lj_state.h lj_bc.h lj_frame.h lj_trace.h lj_jit.h lj_ir.h \
|
||||
lj_dispatch.h lj_traceerr.h lj_vm.h lj_strscan.h
|
||||
lj_dispatch.h lj_traceerr.h lj_vm.h lj_strscan.h lj_strfmt.h
|
||||
lj_asm.o: lj_asm.c lj_obj.h lua.h luaconf.h lj_def.h lj_arch.h lj_gc.h \
|
||||
lj_str.h lj_tab.h lj_frame.h lj_bc.h lj_ctype.h lj_ir.h lj_jit.h \
|
||||
lj_ircall.h lj_iropt.h lj_mcode.h lj_trace.h lj_dispatch.h lj_traceerr.h \
|
||||
lj_snap.h lj_asm.h lj_vm.h lj_target.h lj_target_*.h lj_emit_*.h \
|
||||
lj_asm_*.h
|
||||
lj_bc.o: lj_bc.c lj_obj.h lua.h luaconf.h lj_def.h lj_arch.h lj_bc.h \
|
||||
gen/lj_bcdef.h
|
||||
lj_bcdef.h
|
||||
lj_bcread.o: lj_bcread.c lj_obj.h lua.h luaconf.h lj_def.h lj_arch.h \
|
||||
lj_gc.h lj_err.h lj_errmsg.h lj_str.h lj_tab.h lj_bc.h lj_ctype.h \
|
||||
lj_cdata.h lualib.h lj_lex.h lj_bcdump.h lj_state.h
|
||||
lj_gc.h lj_err.h lj_errmsg.h lj_buf.h lj_str.h lj_tab.h lj_bc.h \
|
||||
lj_ctype.h lj_cdata.h lualib.h lj_lex.h lj_bcdump.h lj_state.h \
|
||||
lj_strfmt.h
|
||||
lj_bcwrite.o: lj_bcwrite.c lj_obj.h lua.h luaconf.h lj_def.h lj_arch.h \
|
||||
lj_gc.h lj_str.h lj_bc.h lj_ctype.h lj_dispatch.h lj_jit.h lj_ir.h \
|
||||
lj_bcdump.h lj_lex.h lj_err.h lj_errmsg.h lj_vm.h
|
||||
lj_gc.h lj_buf.h lj_str.h lj_bc.h lj_ctype.h lj_dispatch.h lj_jit.h \
|
||||
lj_ir.h lj_strfmt.h lj_bcdump.h lj_lex.h lj_err.h lj_errmsg.h lj_vm.h
|
||||
lj_buf.o: lj_buf.c lj_obj.h lua.h luaconf.h lj_def.h lj_arch.h lj_gc.h \
|
||||
lj_err.h lj_errmsg.h lj_buf.h lj_str.h lj_tab.h lj_strfmt.h
|
||||
lj_carith.o: lj_carith.c lj_obj.h lua.h luaconf.h lj_def.h lj_arch.h \
|
||||
lj_gc.h lj_err.h lj_errmsg.h lj_tab.h lj_meta.h lj_ctype.h lj_cconv.h \
|
||||
lj_cdata.h lj_carith.h
|
||||
lj_gc.h lj_err.h lj_errmsg.h lj_tab.h lj_meta.h lj_ir.h lj_ctype.h \
|
||||
lj_cconv.h lj_cdata.h lj_carith.h lj_strscan.h
|
||||
lj_ccall.o: lj_ccall.c lj_obj.h lua.h luaconf.h lj_def.h lj_arch.h \
|
||||
lj_gc.h lj_err.h lj_errmsg.h lj_str.h lj_tab.h lj_ctype.h lj_cconv.h \
|
||||
lj_cdata.h lj_ccall.h lj_trace.h lj_jit.h lj_ir.h lj_dispatch.h lj_bc.h \
|
||||
lj_gc.h lj_err.h lj_errmsg.h lj_tab.h lj_ctype.h lj_cconv.h lj_cdata.h \
|
||||
lj_ccall.h lj_trace.h lj_jit.h lj_ir.h lj_dispatch.h lj_bc.h \
|
||||
lj_traceerr.h
|
||||
lj_ccallback.o: lj_ccallback.c lj_obj.h lua.h luaconf.h lj_def.h \
|
||||
lj_arch.h lj_gc.h lj_err.h lj_errmsg.h lj_tab.h lj_state.h lj_frame.h \
|
||||
|
@ -71,107 +78,118 @@ lj_cconv.o: lj_cconv.c lj_obj.h lua.h luaconf.h lj_def.h lj_arch.h \
|
|||
lj_err.h lj_errmsg.h lj_tab.h lj_ctype.h lj_gc.h lj_cdata.h lj_cconv.h \
|
||||
lj_ccallback.h
|
||||
lj_cdata.o: lj_cdata.c lj_obj.h lua.h luaconf.h lj_def.h lj_arch.h \
|
||||
lj_gc.h lj_err.h lj_errmsg.h lj_str.h lj_tab.h lj_ctype.h lj_cconv.h \
|
||||
lj_cdata.h
|
||||
lj_gc.h lj_err.h lj_errmsg.h lj_tab.h lj_ctype.h lj_cconv.h lj_cdata.h
|
||||
lj_char.o: lj_char.c lj_char.h lj_def.h lua.h luaconf.h
|
||||
lj_clib.o: lj_clib.c lj_obj.h lua.h luaconf.h lj_def.h lj_arch.h lj_gc.h \
|
||||
lj_err.h lj_errmsg.h lj_tab.h lj_str.h lj_udata.h lj_ctype.h lj_cconv.h \
|
||||
lj_cdata.h lj_clib.h
|
||||
lj_cdata.h lj_clib.h lj_strfmt.h
|
||||
lj_cparse.o: lj_cparse.c lj_obj.h lua.h luaconf.h lj_def.h lj_arch.h \
|
||||
lj_gc.h lj_err.h lj_errmsg.h lj_str.h lj_ctype.h lj_cparse.h lj_frame.h \
|
||||
lj_bc.h lj_vm.h lj_char.h lj_strscan.h
|
||||
lj_gc.h lj_err.h lj_errmsg.h lj_buf.h lj_str.h lj_ctype.h lj_cparse.h \
|
||||
lj_frame.h lj_bc.h lj_vm.h lj_char.h lj_strscan.h lj_strfmt.h
|
||||
lj_crecord.o: lj_crecord.c lj_obj.h lua.h luaconf.h lj_def.h lj_arch.h \
|
||||
lj_err.h lj_errmsg.h lj_str.h lj_tab.h lj_frame.h lj_bc.h lj_ctype.h \
|
||||
lj_gc.h lj_cdata.h lj_cparse.h lj_cconv.h lj_clib.h lj_ccall.h lj_ff.h \
|
||||
gen/lj_ffdef.h lj_ir.h lj_jit.h lj_ircall.h lj_iropt.h lj_trace.h \
|
||||
lj_err.h lj_errmsg.h lj_tab.h lj_frame.h lj_bc.h lj_ctype.h lj_gc.h \
|
||||
lj_cdata.h lj_cparse.h lj_cconv.h lj_carith.h lj_clib.h lj_ccall.h \
|
||||
lj_ff.h lj_ffdef.h lj_ir.h lj_jit.h lj_ircall.h lj_iropt.h lj_trace.h \
|
||||
lj_dispatch.h lj_traceerr.h lj_record.h lj_ffrecord.h lj_snap.h \
|
||||
lj_crecord.h
|
||||
lj_crecord.h lj_strfmt.h
|
||||
lj_ctype.o: lj_ctype.c lj_obj.h lua.h luaconf.h lj_def.h lj_arch.h \
|
||||
lj_gc.h lj_err.h lj_errmsg.h lj_str.h lj_tab.h lj_ctype.h lj_ccallback.h
|
||||
lj_gc.h lj_err.h lj_errmsg.h lj_str.h lj_tab.h lj_strfmt.h lj_ctype.h \
|
||||
lj_ccallback.h lj_buf.h
|
||||
lj_debug.o: lj_debug.c lj_obj.h lua.h luaconf.h lj_def.h lj_arch.h \
|
||||
lj_err.h lj_errmsg.h lj_debug.h lj_str.h lj_tab.h lj_state.h lj_frame.h \
|
||||
lj_bc.h lj_jit.h lj_ir.h
|
||||
lj_err.h lj_errmsg.h lj_debug.h lj_buf.h lj_gc.h lj_str.h lj_tab.h \
|
||||
lj_state.h lj_frame.h lj_bc.h lj_strfmt.h lj_jit.h lj_ir.h
|
||||
lj_dispatch.o: lj_dispatch.c lj_obj.h lua.h luaconf.h lj_def.h lj_arch.h \
|
||||
lj_err.h lj_errmsg.h lj_func.h lj_str.h lj_tab.h lj_meta.h lj_debug.h \
|
||||
lj_state.h lj_frame.h lj_bc.h lj_ff.h gen/lj_ffdef.h lj_jit.h lj_ir.h \
|
||||
lj_ccallback.h lj_ctype.h lj_gc.h lj_trace.h lj_dispatch.h lj_traceerr.h \
|
||||
lj_vm.h luajit.h
|
||||
lj_err.h lj_errmsg.h lj_buf.h lj_gc.h lj_str.h lj_func.h lj_tab.h \
|
||||
lj_meta.h lj_debug.h lj_state.h lj_frame.h lj_bc.h lj_ff.h lj_ffdef.h \
|
||||
lj_strfmt.h lj_jit.h lj_ir.h lj_ccallback.h lj_ctype.h lj_trace.h \
|
||||
lj_dispatch.h lj_traceerr.h lj_profile.h lj_vm.h luajit.h
|
||||
lj_err.o: lj_err.c lj_obj.h lua.h luaconf.h lj_def.h lj_arch.h lj_err.h \
|
||||
lj_errmsg.h lj_debug.h lj_str.h lj_func.h lj_state.h lj_frame.h lj_bc.h \
|
||||
lj_ff.h gen/lj_ffdef.h lj_trace.h lj_jit.h lj_ir.h lj_dispatch.h \
|
||||
lj_traceerr.h lj_vm.h
|
||||
lj_ff.h lj_ffdef.h lj_trace.h lj_jit.h lj_ir.h lj_dispatch.h \
|
||||
lj_traceerr.h lj_vm.h lj_strfmt.h
|
||||
lj_ffrecord.o: lj_ffrecord.c lj_obj.h lua.h luaconf.h lj_def.h lj_arch.h \
|
||||
lj_err.h lj_errmsg.h lj_str.h lj_tab.h lj_frame.h lj_bc.h lj_ff.h \
|
||||
gen/lj_ffdef.h lj_ir.h lj_jit.h lj_ircall.h lj_iropt.h lj_trace.h \
|
||||
lj_ffdef.h lj_ir.h lj_jit.h lj_ircall.h lj_iropt.h lj_trace.h \
|
||||
lj_dispatch.h lj_traceerr.h lj_record.h lj_ffrecord.h lj_crecord.h \
|
||||
lj_vm.h lj_strscan.h gen/lj_recdef.h
|
||||
lj_vm.h lj_strscan.h lj_strfmt.h lj_recdef.h
|
||||
lj_func.o: lj_func.c lj_obj.h lua.h luaconf.h lj_def.h lj_arch.h lj_gc.h \
|
||||
lj_func.h lj_trace.h lj_jit.h lj_ir.h lj_dispatch.h lj_bc.h \
|
||||
lj_traceerr.h lj_vm.h
|
||||
lj_gc.o: lj_gc.c lj_obj.h lua.h luaconf.h lj_def.h lj_arch.h lj_gc.h \
|
||||
lj_err.h lj_errmsg.h lj_str.h lj_tab.h lj_func.h lj_udata.h lj_meta.h \
|
||||
lj_state.h lj_frame.h lj_bc.h lj_ctype.h lj_cdata.h lj_trace.h lj_jit.h \
|
||||
lj_ir.h lj_dispatch.h lj_traceerr.h lj_vm.h
|
||||
lj_err.h lj_errmsg.h lj_buf.h lj_str.h lj_tab.h lj_func.h lj_udata.h \
|
||||
lj_meta.h lj_state.h lj_frame.h lj_bc.h lj_ctype.h lj_cdata.h lj_trace.h \
|
||||
lj_jit.h lj_ir.h lj_dispatch.h lj_traceerr.h lj_vm.h
|
||||
lj_gdbjit.o: lj_gdbjit.c lj_obj.h lua.h luaconf.h lj_def.h lj_arch.h \
|
||||
lj_gc.h lj_err.h lj_errmsg.h lj_debug.h lj_frame.h lj_bc.h lj_jit.h \
|
||||
lj_ir.h lj_dispatch.h
|
||||
lj_gc.h lj_err.h lj_errmsg.h lj_debug.h lj_frame.h lj_bc.h lj_buf.h \
|
||||
lj_str.h lj_strfmt.h lj_jit.h lj_ir.h lj_dispatch.h
|
||||
lj_ir.o: lj_ir.c lj_obj.h lua.h luaconf.h lj_def.h lj_arch.h lj_gc.h \
|
||||
lj_str.h lj_tab.h lj_ir.h lj_jit.h lj_ircall.h lj_iropt.h lj_trace.h \
|
||||
lj_dispatch.h lj_bc.h lj_traceerr.h lj_ctype.h lj_cdata.h lj_carith.h \
|
||||
lj_vm.h lj_strscan.h lj_lib.h
|
||||
lj_buf.h lj_str.h lj_tab.h lj_ir.h lj_jit.h lj_ircall.h lj_iropt.h \
|
||||
lj_trace.h lj_dispatch.h lj_bc.h lj_traceerr.h lj_ctype.h lj_cdata.h \
|
||||
lj_carith.h lj_vm.h lj_strscan.h lj_strfmt.h lj_lib.h
|
||||
lj_lex.o: lj_lex.c lj_obj.h lua.h luaconf.h lj_def.h lj_arch.h lj_gc.h \
|
||||
lj_err.h lj_errmsg.h lj_str.h lj_tab.h lj_ctype.h lj_cdata.h lualib.h \
|
||||
lj_state.h lj_lex.h lj_parse.h lj_char.h lj_strscan.h
|
||||
lj_err.h lj_errmsg.h lj_buf.h lj_str.h lj_tab.h lj_ctype.h lj_cdata.h \
|
||||
lualib.h lj_state.h lj_lex.h lj_parse.h lj_char.h lj_strscan.h \
|
||||
lj_strfmt.h
|
||||
lj_lib.o: lj_lib.c lauxlib.h lua.h luaconf.h lj_obj.h lj_def.h lj_arch.h \
|
||||
lj_gc.h lj_err.h lj_errmsg.h lj_str.h lj_tab.h lj_func.h lj_bc.h \
|
||||
lj_dispatch.h lj_jit.h lj_ir.h lj_vm.h lj_strscan.h lj_lib.h
|
||||
lj_dispatch.h lj_jit.h lj_ir.h lj_vm.h lj_strscan.h lj_strfmt.h lj_lex.h \
|
||||
lj_bcdump.h lj_lib.h
|
||||
lj_load.o: lj_load.c lua.h luaconf.h lauxlib.h lj_obj.h lj_def.h \
|
||||
lj_arch.h lj_gc.h lj_err.h lj_errmsg.h lj_str.h lj_func.h lj_frame.h \
|
||||
lj_bc.h lj_vm.h lj_lex.h lj_bcdump.h lj_parse.h
|
||||
lj_arch.h lj_gc.h lj_err.h lj_errmsg.h lj_buf.h lj_str.h lj_func.h \
|
||||
lj_frame.h lj_bc.h lj_vm.h lj_lex.h lj_bcdump.h lj_parse.h
|
||||
lj_mcode.o: lj_mcode.c lj_obj.h lua.h luaconf.h lj_def.h lj_arch.h \
|
||||
lj_gc.h lj_err.h lj_errmsg.h lj_jit.h lj_ir.h lj_mcode.h lj_trace.h \
|
||||
lj_dispatch.h lj_bc.h lj_traceerr.h lj_vm.h
|
||||
lj_meta.o: lj_meta.c lj_obj.h lua.h luaconf.h lj_def.h lj_arch.h lj_gc.h \
|
||||
lj_err.h lj_errmsg.h lj_str.h lj_tab.h lj_meta.h lj_frame.h lj_bc.h \
|
||||
lj_vm.h lj_strscan.h
|
||||
lj_err.h lj_errmsg.h lj_buf.h lj_str.h lj_tab.h lj_meta.h lj_frame.h \
|
||||
lj_bc.h lj_vm.h lj_strscan.h lj_strfmt.h lj_lib.h
|
||||
lj_obj.o: lj_obj.c lj_obj.h lua.h luaconf.h lj_def.h lj_arch.h
|
||||
lj_opt_dce.o: lj_opt_dce.c lj_obj.h lua.h luaconf.h lj_def.h lj_arch.h \
|
||||
lj_ir.h lj_jit.h lj_iropt.h
|
||||
lj_opt_fold.o: lj_opt_fold.c lj_obj.h lua.h luaconf.h lj_def.h lj_arch.h \
|
||||
lj_str.h lj_tab.h lj_ir.h lj_jit.h lj_iropt.h lj_trace.h lj_dispatch.h \
|
||||
lj_bc.h lj_traceerr.h lj_ctype.h lj_gc.h lj_carith.h lj_vm.h \
|
||||
lj_strscan.h gen/lj_folddef.h
|
||||
lj_buf.h lj_gc.h lj_str.h lj_tab.h lj_ir.h lj_jit.h lj_ircall.h \
|
||||
lj_iropt.h lj_trace.h lj_dispatch.h lj_bc.h lj_traceerr.h lj_ctype.h \
|
||||
lj_carith.h lj_vm.h lj_strscan.h lj_strfmt.h lj_folddef.h
|
||||
lj_opt_loop.o: lj_opt_loop.c lj_obj.h lua.h luaconf.h lj_def.h lj_arch.h \
|
||||
lj_err.h lj_errmsg.h lj_str.h lj_ir.h lj_jit.h lj_iropt.h lj_trace.h \
|
||||
lj_dispatch.h lj_bc.h lj_traceerr.h lj_snap.h lj_vm.h
|
||||
lj_err.h lj_errmsg.h lj_buf.h lj_gc.h lj_str.h lj_ir.h lj_jit.h \
|
||||
lj_iropt.h lj_trace.h lj_dispatch.h lj_bc.h lj_traceerr.h lj_snap.h \
|
||||
lj_vm.h
|
||||
lj_opt_mem.o: lj_opt_mem.c lj_obj.h lua.h luaconf.h lj_def.h lj_arch.h \
|
||||
lj_tab.h lj_ir.h lj_jit.h lj_iropt.h
|
||||
lj_tab.h lj_ir.h lj_jit.h lj_iropt.h lj_ircall.h
|
||||
lj_opt_narrow.o: lj_opt_narrow.c lj_obj.h lua.h luaconf.h lj_def.h \
|
||||
lj_arch.h lj_bc.h lj_ir.h lj_jit.h lj_iropt.h lj_trace.h lj_dispatch.h \
|
||||
lj_traceerr.h lj_vm.h lj_strscan.h
|
||||
lj_opt_sink.o: lj_opt_sink.c lj_obj.h lua.h luaconf.h lj_def.h lj_arch.h \
|
||||
lj_ir.h lj_jit.h lj_iropt.h lj_target.h lj_target_*.h
|
||||
lj_opt_split.o: lj_opt_split.c lj_obj.h lua.h luaconf.h lj_def.h \
|
||||
lj_arch.h lj_err.h lj_errmsg.h lj_str.h lj_ir.h lj_jit.h lj_ircall.h \
|
||||
lj_iropt.h lj_vm.h
|
||||
lj_arch.h lj_err.h lj_errmsg.h lj_buf.h lj_gc.h lj_str.h lj_ir.h \
|
||||
lj_jit.h lj_ircall.h lj_iropt.h lj_dispatch.h lj_bc.h lj_vm.h
|
||||
lj_parse.o: lj_parse.c lj_obj.h lua.h luaconf.h lj_def.h lj_arch.h \
|
||||
lj_gc.h lj_err.h lj_errmsg.h lj_debug.h lj_str.h lj_tab.h lj_func.h \
|
||||
lj_state.h lj_bc.h lj_ctype.h lj_lex.h lj_parse.h lj_vm.h lj_vmevent.h
|
||||
lj_gc.h lj_err.h lj_errmsg.h lj_debug.h lj_buf.h lj_str.h lj_tab.h \
|
||||
lj_func.h lj_state.h lj_bc.h lj_ctype.h lj_strfmt.h lj_lex.h lj_parse.h \
|
||||
lj_vm.h lj_vmevent.h
|
||||
lj_profile.o: lj_profile.c lj_obj.h lua.h luaconf.h lj_def.h lj_arch.h \
|
||||
lj_buf.h lj_gc.h lj_str.h lj_frame.h lj_bc.h lj_debug.h lj_dispatch.h \
|
||||
lj_jit.h lj_ir.h lj_trace.h lj_traceerr.h lj_profile.h luajit.h
|
||||
lj_record.o: lj_record.c lj_obj.h lua.h luaconf.h lj_def.h lj_arch.h \
|
||||
lj_err.h lj_errmsg.h lj_str.h lj_tab.h lj_meta.h lj_frame.h lj_bc.h \
|
||||
lj_ctype.h lj_gc.h lj_ff.h gen/lj_ffdef.h lj_ir.h lj_jit.h lj_ircall.h \
|
||||
lj_iropt.h lj_trace.h lj_dispatch.h lj_traceerr.h lj_record.h \
|
||||
lj_ffrecord.h lj_snap.h lj_vm.h
|
||||
lj_ctype.h lj_gc.h lj_ff.h lj_ffdef.h lj_debug.h lj_ir.h lj_jit.h \
|
||||
lj_ircall.h lj_iropt.h lj_trace.h lj_dispatch.h lj_traceerr.h \
|
||||
lj_record.h lj_ffrecord.h lj_snap.h lj_vm.h
|
||||
lj_snap.o: lj_snap.c lj_obj.h lua.h luaconf.h lj_def.h lj_arch.h lj_gc.h \
|
||||
lj_tab.h lj_state.h lj_frame.h lj_bc.h lj_ir.h lj_jit.h lj_iropt.h \
|
||||
lj_trace.h lj_dispatch.h lj_traceerr.h lj_snap.h lj_target.h \
|
||||
lj_target_*.h lj_ctype.h lj_cdata.h
|
||||
lj_state.o: lj_state.c lj_obj.h lua.h luaconf.h lj_def.h lj_arch.h \
|
||||
lj_gc.h lj_err.h lj_errmsg.h lj_str.h lj_tab.h lj_func.h lj_meta.h \
|
||||
lj_state.h lj_frame.h lj_bc.h lj_ctype.h lj_trace.h lj_jit.h lj_ir.h \
|
||||
lj_dispatch.h lj_traceerr.h lj_vm.h lj_lex.h lj_alloc.h
|
||||
lj_gc.h lj_err.h lj_errmsg.h lj_buf.h lj_str.h lj_tab.h lj_func.h \
|
||||
lj_meta.h lj_state.h lj_frame.h lj_bc.h lj_ctype.h lj_trace.h lj_jit.h \
|
||||
lj_ir.h lj_dispatch.h lj_traceerr.h lj_vm.h lj_lex.h lj_alloc.h luajit.h
|
||||
lj_str.o: lj_str.c lj_obj.h lua.h luaconf.h lj_def.h lj_arch.h lj_gc.h \
|
||||
lj_err.h lj_errmsg.h lj_str.h lj_state.h lj_char.h
|
||||
lj_err.h lj_errmsg.h lj_str.h lj_char.h
|
||||
lj_strfmt.o: lj_strfmt.c lj_obj.h lua.h luaconf.h lj_def.h lj_arch.h \
|
||||
lj_buf.h lj_gc.h lj_str.h lj_state.h lj_char.h lj_strfmt.h
|
||||
lj_strfmt_num.o: lj_strfmt_num.c lj_obj.h lua.h luaconf.h lj_def.h \
|
||||
lj_arch.h lj_buf.h lj_gc.h lj_str.h lj_strfmt.h
|
||||
lj_strscan.o: lj_strscan.c lj_obj.h lua.h luaconf.h lj_def.h lj_arch.h \
|
||||
lj_char.h lj_strscan.h
|
||||
lj_tab.o: lj_tab.c lj_obj.h lua.h luaconf.h lj_def.h lj_arch.h lj_gc.h \
|
||||
|
@ -189,38 +207,40 @@ lj_vmevent.o: lj_vmevent.c lj_obj.h lua.h luaconf.h lj_def.h lj_arch.h \
|
|||
lj_vmmath.o: lj_vmmath.c lj_obj.h lua.h luaconf.h lj_def.h lj_arch.h \
|
||||
lj_ir.h lj_vm.h
|
||||
ljamalg.o: ljamalg.c lua.h luaconf.h lauxlib.h lj_gc.c lj_obj.h lj_def.h \
|
||||
lj_arch.h lj_gc.h lj_err.h lj_errmsg.h lj_str.h lj_tab.h lj_func.h \
|
||||
lj_udata.h lj_meta.h lj_state.h lj_frame.h lj_bc.h lj_ctype.h lj_cdata.h \
|
||||
lj_trace.h lj_jit.h lj_ir.h lj_dispatch.h lj_traceerr.h lj_vm.h lj_err.c \
|
||||
lj_debug.h lj_ff.h gen/lj_ffdef.h lj_char.c lj_char.h lj_bc.c gen/lj_bcdef.h \
|
||||
lj_obj.c lj_str.c lj_tab.c lj_func.c lj_udata.c lj_meta.c lj_strscan.h \
|
||||
lj_debug.c lj_state.c lj_lex.h lj_alloc.h lj_dispatch.c lj_ccallback.h \
|
||||
luajit.h lj_vmevent.c lj_vmevent.h lj_vmmath.c lj_strscan.c lj_api.c \
|
||||
lj_lex.c lualib.h lj_parse.h lj_parse.c lj_bcread.c lj_bcdump.h \
|
||||
lj_bcwrite.c lj_load.c lj_ctype.c lj_cdata.c lj_cconv.h lj_cconv.c \
|
||||
lj_ccall.c lj_ccall.h lj_ccallback.c lj_target.h lj_target_*.h \
|
||||
lj_mcode.h lj_carith.c lj_carith.h lj_clib.c lj_clib.h lj_cparse.c \
|
||||
lj_cparse.h lj_lib.c lj_lib.h lj_ir.c lj_ircall.h lj_iropt.h \
|
||||
lj_opt_mem.c lj_opt_fold.c gen/lj_folddef.h lj_opt_narrow.c lj_opt_dce.c \
|
||||
lj_opt_loop.c lj_snap.h lj_opt_split.c lj_opt_sink.c lj_mcode.c \
|
||||
lj_snap.c lj_record.c lj_record.h lj_ffrecord.h lj_crecord.c \
|
||||
lj_crecord.h lj_ffrecord.c gen/lj_recdef.h lj_asm.c lj_asm.h lj_emit_*.h \
|
||||
lj_asm_*.h lj_trace.c lj_gdbjit.h lj_gdbjit.c lj_alloc.c lib_aux.c \
|
||||
lib_base.c gen/lj_libdef.h lib_math.c lib_string.c lib_table.c lib_io.c \
|
||||
lib_os.c lib_package.c lib_debug.c lib_bit.c lib_jit.c lib_ffi.c \
|
||||
lib_init.c
|
||||
lj_arch.h lj_gc.h lj_err.h lj_errmsg.h lj_buf.h lj_str.h lj_tab.h \
|
||||
lj_func.h lj_udata.h lj_meta.h lj_state.h lj_frame.h lj_bc.h lj_ctype.h \
|
||||
lj_cdata.h lj_trace.h lj_jit.h lj_ir.h lj_dispatch.h lj_traceerr.h \
|
||||
lj_vm.h lj_err.c lj_debug.h lj_ff.h lj_ffdef.h lj_strfmt.h lj_char.c \
|
||||
lj_char.h lj_bc.c lj_bcdef.h lj_obj.c lj_buf.c lj_str.c lj_tab.c \
|
||||
lj_func.c lj_udata.c lj_meta.c lj_strscan.h lj_lib.h lj_debug.c \
|
||||
lj_state.c lj_lex.h lj_alloc.h luajit.h lj_dispatch.c lj_ccallback.h \
|
||||
lj_profile.h lj_vmevent.c lj_vmevent.h lj_vmmath.c lj_strscan.c \
|
||||
lj_strfmt.c lj_strfmt_num.c lj_api.c lj_profile.c lj_lex.c lualib.h \
|
||||
lj_parse.h lj_parse.c lj_bcread.c lj_bcdump.h lj_bcwrite.c lj_load.c \
|
||||
lj_ctype.c lj_cdata.c lj_cconv.h lj_cconv.c lj_ccall.c lj_ccall.h \
|
||||
lj_ccallback.c lj_target.h lj_target_*.h lj_mcode.h lj_carith.c \
|
||||
lj_carith.h lj_clib.c lj_clib.h lj_cparse.c lj_cparse.h lj_lib.c lj_ir.c \
|
||||
lj_ircall.h lj_iropt.h lj_opt_mem.c lj_opt_fold.c lj_folddef.h \
|
||||
lj_opt_narrow.c lj_opt_dce.c lj_opt_loop.c lj_snap.h lj_opt_split.c \
|
||||
lj_opt_sink.c lj_mcode.c lj_snap.c lj_record.c lj_record.h lj_ffrecord.h \
|
||||
lj_crecord.c lj_crecord.h lj_ffrecord.c lj_recdef.h lj_asm.c lj_asm.h \
|
||||
lj_emit_*.h lj_asm_*.h lj_trace.c lj_gdbjit.h lj_gdbjit.c lj_alloc.c \
|
||||
lib_aux.c lib_base.c lj_libdef.h lib_math.c lib_string.c lib_table.c \
|
||||
lib_io.c lib_os.c lib_package.c lib_debug.c lib_bit.c lib_jit.c \
|
||||
lib_ffi.c lib_init.c
|
||||
luajit.o: luajit.c lua.h luaconf.h lauxlib.h lualib.h luajit.h lj_arch.h
|
||||
host/buildvm.o: host/buildvm.c host/buildvm.h lj_def.h lua.h luaconf.h \
|
||||
lj_arch.h lj_obj.h lj_def.h lj_arch.h lj_gc.h lj_obj.h lj_bc.h lj_ir.h \
|
||||
lj_ircall.h lj_ir.h lj_jit.h lj_frame.h lj_bc.h lj_dispatch.h lj_ctype.h \
|
||||
lj_gc.h lj_ccall.h lj_ctype.h luajit.h \
|
||||
gen/buildvm_arch.h lj_traceerr.h
|
||||
host/buildvm_arch.h lj_traceerr.h
|
||||
host/buildvm_asm.o: host/buildvm_asm.c host/buildvm.h lj_def.h lua.h luaconf.h \
|
||||
lj_arch.h lj_bc.h lj_def.h lj_arch.h
|
||||
host/buildvm_fold.o: host/buildvm_fold.c host/buildvm.h lj_def.h lua.h \
|
||||
luaconf.h lj_arch.h lj_obj.h lj_def.h lj_arch.h lj_ir.h lj_obj.h
|
||||
host/buildvm_lib.o: host/buildvm_lib.c host/buildvm.h lj_def.h lua.h luaconf.h \
|
||||
lj_arch.h lj_obj.h lj_def.h lj_arch.h lj_lib.h lj_obj.h
|
||||
lj_arch.h lj_obj.h lj_def.h lj_arch.h lj_bc.h lj_lib.h lj_obj.h \
|
||||
host/buildvm_libbc.h
|
||||
host/buildvm_peobj.o: host/buildvm_peobj.c host/buildvm.h lj_def.h lua.h \
|
||||
luaconf.h lj_arch.h lj_bc.h lj_def.h lj_arch.h
|
||||
host/minilua.o: host/minilua.c
|
||||
|
|
3
vendor/luajit/src/host/.gitignore
vendored
Normal file
3
vendor/luajit/src/host/.gitignore
vendored
Normal file
|
@ -0,0 +1,3 @@
|
|||
minilua
|
||||
buildvm
|
||||
buildvm_arch.h
|
28
vendor/luajit/src/host/buildvm.c
vendored
28
vendor/luajit/src/host/buildvm.c
vendored
|
@ -1,6 +1,6 @@
|
|||
/*
|
||||
** LuaJIT VM builder.
|
||||
** Copyright (C) 2005-2015 Mike Pall. See Copyright Notice in luajit.h
|
||||
** Copyright (C) 2005-2017 Mike Pall. See Copyright Notice in luajit.h
|
||||
**
|
||||
** This is a tool to build the hand-tuned assembler code required for
|
||||
** LuaJIT's bytecode interpreter. It supports a variety of output formats
|
||||
|
@ -59,10 +59,10 @@ static int collect_reloc(BuildCtx *ctx, uint8_t *addr, int idx, int type);
|
|||
#include "../dynasm/dasm_x86.h"
|
||||
#elif LJ_TARGET_ARM
|
||||
#include "../dynasm/dasm_arm.h"
|
||||
#elif LJ_TARGET_ARM64
|
||||
#include "../dynasm/dasm_arm64.h"
|
||||
#elif LJ_TARGET_PPC
|
||||
#include "../dynasm/dasm_ppc.h"
|
||||
#elif LJ_TARGET_PPCSPE
|
||||
#include "../dynasm/dasm_ppc.h"
|
||||
#elif LJ_TARGET_MIPS
|
||||
#include "../dynasm/dasm_mips.h"
|
||||
#else
|
||||
|
@ -110,11 +110,11 @@ static const char *sym_decorate(BuildCtx *ctx,
|
|||
if (p) {
|
||||
#if LJ_TARGET_X86ORX64
|
||||
if (!LJ_64 && (ctx->mode == BUILD_coffasm || ctx->mode == BUILD_peobj))
|
||||
name[0] = '@';
|
||||
name[0] = name[1] == 'R' ? '_' : '@'; /* Just for _RtlUnwind@16. */
|
||||
else
|
||||
*p = '\0';
|
||||
#elif (LJ_TARGET_PPC || LJ_TARGET_PPCSPE) && !LJ_TARGET_CONSOLE
|
||||
/* Keep @plt. */
|
||||
#elif LJ_TARGET_PPC && !LJ_TARGET_CONSOLE
|
||||
/* Keep @plt etc. */
|
||||
#else
|
||||
*p = '\0';
|
||||
#endif
|
||||
|
@ -179,6 +179,7 @@ static int build_code(BuildCtx *ctx)
|
|||
ctx->nreloc = 0;
|
||||
|
||||
ctx->globnames = globnames;
|
||||
ctx->extnames = extnames;
|
||||
ctx->relocsym = (const char **)malloc(NRELOCSYM*sizeof(const char *));
|
||||
ctx->nrelocsym = 0;
|
||||
for (i = 0; i < (int)NRELOCSYM; i++) relocmap[i] = -1;
|
||||
|
@ -320,20 +321,20 @@ static void emit_vmdef(BuildCtx *ctx)
|
|||
char buf[80];
|
||||
int i;
|
||||
fprintf(ctx->fp, "-- This is a generated file. DO NOT EDIT!\n\n");
|
||||
fprintf(ctx->fp, "module(...)\n\n");
|
||||
fprintf(ctx->fp, "return {\n\n");
|
||||
|
||||
fprintf(ctx->fp, "bcnames = \"");
|
||||
for (i = 0; bc_names[i]; i++) fprintf(ctx->fp, "%-6s", bc_names[i]);
|
||||
fprintf(ctx->fp, "\"\n\n");
|
||||
fprintf(ctx->fp, "\",\n\n");
|
||||
|
||||
fprintf(ctx->fp, "irnames = \"");
|
||||
for (i = 0; ir_names[i]; i++) fprintf(ctx->fp, "%-6s", ir_names[i]);
|
||||
fprintf(ctx->fp, "\"\n\n");
|
||||
fprintf(ctx->fp, "\",\n\n");
|
||||
|
||||
fprintf(ctx->fp, "irfpm = { [0]=");
|
||||
for (i = 0; irfpm_names[i]; i++)
|
||||
fprintf(ctx->fp, "\"%s\", ", lower(buf, irfpm_names[i]));
|
||||
fprintf(ctx->fp, "}\n\n");
|
||||
fprintf(ctx->fp, "},\n\n");
|
||||
|
||||
fprintf(ctx->fp, "irfield = { [0]=");
|
||||
for (i = 0; irfield_names[i]; i++) {
|
||||
|
@ -343,17 +344,17 @@ static void emit_vmdef(BuildCtx *ctx)
|
|||
if (p) *p = '.';
|
||||
fprintf(ctx->fp, "\"%s\", ", buf);
|
||||
}
|
||||
fprintf(ctx->fp, "}\n\n");
|
||||
fprintf(ctx->fp, "},\n\n");
|
||||
|
||||
fprintf(ctx->fp, "ircall = {\n[0]=");
|
||||
for (i = 0; ircall_names[i]; i++)
|
||||
fprintf(ctx->fp, "\"%s\",\n", ircall_names[i]);
|
||||
fprintf(ctx->fp, "}\n\n");
|
||||
fprintf(ctx->fp, "},\n\n");
|
||||
|
||||
fprintf(ctx->fp, "traceerr = {\n[0]=");
|
||||
for (i = 0; trace_errors[i]; i++)
|
||||
fprintf(ctx->fp, "\"%s\",\n", trace_errors[i]);
|
||||
fprintf(ctx->fp, "}\n\n");
|
||||
fprintf(ctx->fp, "},\n\n");
|
||||
}
|
||||
|
||||
/* -- Argument parsing ---------------------------------------------------- */
|
||||
|
@ -490,6 +491,7 @@ int main(int argc, char **argv)
|
|||
case BUILD_vmdef:
|
||||
emit_vmdef(ctx);
|
||||
emit_lib(ctx);
|
||||
fprintf(ctx->fp, "}\n\n");
|
||||
break;
|
||||
case BUILD_ffdef:
|
||||
case BUILD_libdef:
|
||||
|
|
3
vendor/luajit/src/host/buildvm.h
vendored
3
vendor/luajit/src/host/buildvm.h
vendored
|
@ -1,6 +1,6 @@
|
|||
/*
|
||||
** LuaJIT VM builder.
|
||||
** Copyright (C) 2005-2015 Mike Pall. See Copyright Notice in luajit.h
|
||||
** Copyright (C) 2005-2017 Mike Pall. See Copyright Notice in luajit.h
|
||||
*/
|
||||
|
||||
#ifndef _BUILDVM_H
|
||||
|
@ -82,6 +82,7 @@ typedef struct BuildCtx {
|
|||
const char *beginsym;
|
||||
/* Strings generated by DynASM. */
|
||||
const char *const *globnames;
|
||||
const char *const *extnames;
|
||||
const char *dasm_ident;
|
||||
const char *dasm_arch;
|
||||
/* Relocations. */
|
||||
|
|
72
vendor/luajit/src/host/buildvm_asm.c
vendored
72
vendor/luajit/src/host/buildvm_asm.c
vendored
|
@ -1,6 +1,6 @@
|
|||
/*
|
||||
** LuaJIT VM builder: Assembler source code emitter.
|
||||
** Copyright (C) 2005-2015 Mike Pall. See Copyright Notice in luajit.h
|
||||
** Copyright (C) 2005-2017 Mike Pall. See Copyright Notice in luajit.h
|
||||
*/
|
||||
|
||||
#include "buildvm.h"
|
||||
|
@ -51,8 +51,8 @@ static const char *const jccnames[] = {
|
|||
"js", "jns", "jpe", "jpo", "jl", "jge", "jle", "jg"
|
||||
};
|
||||
|
||||
/* Emit relocation for the incredibly stupid OSX assembler. */
|
||||
static void emit_asm_reloc_mach(BuildCtx *ctx, uint8_t *cp, int n,
|
||||
/* Emit x86/x64 text relocations. */
|
||||
static void emit_asm_reloc_text(BuildCtx *ctx, uint8_t *cp, int n,
|
||||
const char *sym)
|
||||
{
|
||||
const char *opname = NULL;
|
||||
|
@ -71,6 +71,20 @@ err:
|
|||
exit(1);
|
||||
}
|
||||
emit_asm_bytes(ctx, cp, n);
|
||||
if (strncmp(sym+(*sym == '_'), LABEL_PREFIX, sizeof(LABEL_PREFIX)-1)) {
|
||||
/* Various fixups for external symbols outside of our binary. */
|
||||
if (ctx->mode == BUILD_elfasm) {
|
||||
if (LJ_32)
|
||||
fprintf(ctx->fp, "#if __PIC__\n\t%s lj_wrap_%s\n#else\n", opname, sym);
|
||||
fprintf(ctx->fp, "\t%s %s@PLT\n", opname, sym);
|
||||
if (LJ_32)
|
||||
fprintf(ctx->fp, "#endif\n");
|
||||
return;
|
||||
} else if (LJ_32 && ctx->mode == BUILD_machasm) {
|
||||
fprintf(ctx->fp, "\t%s L%s$stub\n", opname, sym);
|
||||
return;
|
||||
}
|
||||
}
|
||||
fprintf(ctx->fp, "\t%s %s\n", opname, sym);
|
||||
}
|
||||
#else
|
||||
|
@ -79,10 +93,14 @@ static void emit_asm_words(BuildCtx *ctx, uint8_t *p, int n)
|
|||
{
|
||||
int i;
|
||||
for (i = 0; i < n; i += 4) {
|
||||
uint32_t ins = *(uint32_t *)(p+i);
|
||||
#if LJ_TARGET_ARM64 && LJ_BE
|
||||
ins = lj_bswap(ins); /* ARM64 instructions are always little-endian. */
|
||||
#endif
|
||||
if ((i & 15) == 0)
|
||||
fprintf(ctx->fp, "\t.long 0x%08x", *(uint32_t *)(p+i));
|
||||
fprintf(ctx->fp, "\t.long 0x%08x", ins);
|
||||
else
|
||||
fprintf(ctx->fp, ",0x%08x", *(uint32_t *)(p+i));
|
||||
fprintf(ctx->fp, ",0x%08x", ins);
|
||||
if ((i & 15) == 12) putc('\n', ctx->fp);
|
||||
}
|
||||
if ((n & 15) != 0) putc('\n', ctx->fp);
|
||||
|
@ -107,7 +125,16 @@ static void emit_asm_wordreloc(BuildCtx *ctx, uint8_t *p, int n,
|
|||
ins, sym);
|
||||
exit(1);
|
||||
}
|
||||
#elif LJ_TARGET_PPC || LJ_TARGET_PPCSPE
|
||||
#elif LJ_TARGET_ARM64
|
||||
if ((ins >> 26) == 0x25u) {
|
||||
fprintf(ctx->fp, "\tbl %s\n", sym);
|
||||
} else {
|
||||
fprintf(stderr,
|
||||
"Error: unsupported opcode %08x for %s symbol relocation.\n",
|
||||
ins, sym);
|
||||
exit(1);
|
||||
}
|
||||
#elif LJ_TARGET_PPC
|
||||
#if LJ_TARGET_PS3
|
||||
#define TOCPREFIX "."
|
||||
#else
|
||||
|
@ -117,6 +144,14 @@ static void emit_asm_wordreloc(BuildCtx *ctx, uint8_t *p, int n,
|
|||
fprintf(ctx->fp, "\t%s %d, %d, " TOCPREFIX "%s\n",
|
||||
(ins & 1) ? "bcl" : "bc", (ins >> 21) & 31, (ins >> 16) & 31, sym);
|
||||
} else if ((ins >> 26) == 18) {
|
||||
#if LJ_ARCH_PPC64
|
||||
const char *suffix = strchr(sym, '@');
|
||||
if (suffix && suffix[1] == 'h') {
|
||||
fprintf(ctx->fp, "\taddis 11, 2, %s\n", sym);
|
||||
} else if (suffix && suffix[1] == 'l') {
|
||||
fprintf(ctx->fp, "\tld 12, %s\n", sym);
|
||||
} else
|
||||
#endif
|
||||
fprintf(ctx->fp, "\t%s " TOCPREFIX "%s\n", (ins & 1) ? "bl" : "b", sym);
|
||||
} else {
|
||||
fprintf(stderr,
|
||||
|
@ -183,7 +218,8 @@ static void emit_asm_label(BuildCtx *ctx, const char *name, int size, int isfunc
|
|||
case BUILD_machasm:
|
||||
fprintf(ctx->fp,
|
||||
"\n\t.private_extern %s\n"
|
||||
"%s:\n", name, name);
|
||||
"\t.no_dead_strip %s\n"
|
||||
"%s:\n", name, name, name);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
|
@ -214,6 +250,9 @@ void emit_asm(BuildCtx *ctx)
|
|||
int i, rel;
|
||||
|
||||
fprintf(ctx->fp, "\t.file \"buildvm_%s.dasc\"\n", ctx->dasm_arch);
|
||||
#if LJ_ARCH_PPC64
|
||||
fprintf(ctx->fp, "\t.abiversion 2\n");
|
||||
#endif
|
||||
fprintf(ctx->fp, "\t.text\n");
|
||||
emit_asm_align(ctx, 4);
|
||||
|
||||
|
@ -227,11 +266,20 @@ void emit_asm(BuildCtx *ctx)
|
|||
|
||||
#if LJ_TARGET_ARM && defined(__GNUC__) && !LJ_NO_UNWIND
|
||||
/* This should really be moved into buildvm_arm.dasc. */
|
||||
#if LJ_ARCH_HASFPU
|
||||
fprintf(ctx->fp,
|
||||
".fnstart\n"
|
||||
".save {r5, r6, r7, r8, r9, r10, r11, lr}\n"
|
||||
".vsave {d8-d15}\n"
|
||||
".save {r4}\n"
|
||||
".pad #28\n");
|
||||
#else
|
||||
fprintf(ctx->fp,
|
||||
".fnstart\n"
|
||||
".save {r4, r5, r6, r7, r8, r9, r10, r11, lr}\n"
|
||||
".pad #28\n");
|
||||
#endif
|
||||
#endif
|
||||
#if LJ_TARGET_MIPS
|
||||
fprintf(ctx->fp, ".set nomips16\n.abicalls\n.set noreorder\n.set nomacro\n");
|
||||
#endif
|
||||
|
@ -254,8 +302,9 @@ void emit_asm(BuildCtx *ctx)
|
|||
BuildReloc *r = &ctx->reloc[rel];
|
||||
int n = r->ofs - ofs;
|
||||
#if LJ_TARGET_X86ORX64
|
||||
if (ctx->mode == BUILD_machasm && r->type != 0) {
|
||||
emit_asm_reloc_mach(ctx, ctx->code+ofs, n, ctx->relocsym[r->sym]);
|
||||
if (r->type != 0 &&
|
||||
(ctx->mode == BUILD_elfasm || ctx->mode == BUILD_machasm)) {
|
||||
emit_asm_reloc_text(ctx, ctx->code+ofs, n, ctx->relocsym[r->sym]);
|
||||
} else {
|
||||
emit_asm_bytes(ctx, ctx->code+ofs, n);
|
||||
emit_asm_reloc(ctx, r->type, ctx->relocsym[r->sym]);
|
||||
|
@ -289,10 +338,7 @@ void emit_asm(BuildCtx *ctx)
|
|||
#if !(LJ_TARGET_PS3 || LJ_TARGET_PSVITA)
|
||||
fprintf(ctx->fp, "\t.section .note.GNU-stack,\"\"," ELFASM_PX "progbits\n");
|
||||
#endif
|
||||
#if LJ_TARGET_PPCSPE
|
||||
/* Soft-float ABI + SPE. */
|
||||
fprintf(ctx->fp, "\t.gnu_attribute 4, 2\n\t.gnu_attribute 8, 3\n");
|
||||
#elif LJ_TARGET_PPC && !LJ_TARGET_PS3
|
||||
#if LJ_TARGET_PPC && !LJ_TARGET_PS3
|
||||
/* Hard-float ABI. */
|
||||
fprintf(ctx->fp, "\t.gnu_attribute 4, 1\n");
|
||||
#endif
|
||||
|
|
4
vendor/luajit/src/host/buildvm_fold.c
vendored
4
vendor/luajit/src/host/buildvm_fold.c
vendored
|
@ -1,6 +1,6 @@
|
|||
/*
|
||||
** LuaJIT VM builder: IR folding hash table generator.
|
||||
** Copyright (C) 2005-2015 Mike Pall. See Copyright Notice in luajit.h
|
||||
** Copyright (C) 2005-2017 Mike Pall. See Copyright Notice in luajit.h
|
||||
*/
|
||||
|
||||
#include "buildvm.h"
|
||||
|
@ -9,7 +9,7 @@
|
|||
|
||||
/* Context for the folding hash table generator. */
|
||||
static int lineno;
|
||||
static int funcidx;
|
||||
static uint32_t funcidx;
|
||||
static uint32_t foldkeys[BUILD_MAX_FOLD];
|
||||
static uint32_t nkeys;
|
||||
|
||||
|
|
63
vendor/luajit/src/host/buildvm_lib.c
vendored
63
vendor/luajit/src/host/buildvm_lib.c
vendored
|
@ -1,11 +1,13 @@
|
|||
/*
|
||||
** LuaJIT VM builder: library definition compiler.
|
||||
** Copyright (C) 2005-2015 Mike Pall. See Copyright Notice in luajit.h
|
||||
** Copyright (C) 2005-2017 Mike Pall. See Copyright Notice in luajit.h
|
||||
*/
|
||||
|
||||
#include "buildvm.h"
|
||||
#include "lj_obj.h"
|
||||
#include "lj_bc.h"
|
||||
#include "lj_lib.h"
|
||||
#include "buildvm_libbc.h"
|
||||
|
||||
/* Context for library definitions. */
|
||||
static uint8_t obuf[8192];
|
||||
|
@ -151,6 +153,62 @@ static void libdef_func(BuildCtx *ctx, char *p, int arg)
|
|||
regfunc = REGFUNC_OK;
|
||||
}
|
||||
|
||||
static uint8_t *libdef_uleb128(uint8_t *p, uint32_t *vv)
|
||||
{
|
||||
uint32_t v = *p++;
|
||||
if (v >= 0x80) {
|
||||
int sh = 0; v &= 0x7f;
|
||||
do { v |= ((*p & 0x7f) << (sh += 7)); } while (*p++ >= 0x80);
|
||||
}
|
||||
*vv = v;
|
||||
return p;
|
||||
}
|
||||
|
||||
static void libdef_fixupbc(uint8_t *p)
|
||||
{
|
||||
uint32_t i, sizebc;
|
||||
p += 4;
|
||||
p = libdef_uleb128(p, &sizebc);
|
||||
p = libdef_uleb128(p, &sizebc);
|
||||
p = libdef_uleb128(p, &sizebc);
|
||||
for (i = 0; i < sizebc; i++, p += 4) {
|
||||
uint8_t op = p[libbc_endian ? 3 : 0];
|
||||
uint8_t ra = p[libbc_endian ? 2 : 1];
|
||||
uint8_t rc = p[libbc_endian ? 1 : 2];
|
||||
uint8_t rb = p[libbc_endian ? 0 : 3];
|
||||
if (!LJ_DUALNUM && op == BC_ISTYPE && rc == ~LJ_TNUMX+1) {
|
||||
op = BC_ISNUM; rc++;
|
||||
}
|
||||
p[LJ_ENDIAN_SELECT(0, 3)] = op;
|
||||
p[LJ_ENDIAN_SELECT(1, 2)] = ra;
|
||||
p[LJ_ENDIAN_SELECT(2, 1)] = rc;
|
||||
p[LJ_ENDIAN_SELECT(3, 0)] = rb;
|
||||
}
|
||||
}
|
||||
|
||||
static void libdef_lua(BuildCtx *ctx, char *p, int arg)
|
||||
{
|
||||
UNUSED(arg);
|
||||
if (ctx->mode == BUILD_libdef) {
|
||||
int i;
|
||||
for (i = 0; libbc_map[i].name != NULL; i++) {
|
||||
if (!strcmp(libbc_map[i].name, p)) {
|
||||
int ofs = libbc_map[i].ofs;
|
||||
int len = libbc_map[i+1].ofs - ofs;
|
||||
obuf[2]++; /* Bump hash table size. */
|
||||
*optr++ = LIBINIT_LUA;
|
||||
libdef_name(p, 0);
|
||||
memcpy(optr, libbc_code + ofs, len);
|
||||
libdef_fixupbc(optr);
|
||||
optr += len;
|
||||
return;
|
||||
}
|
||||
}
|
||||
fprintf(stderr, "Error: missing libbc definition for %s\n", p);
|
||||
exit(1);
|
||||
}
|
||||
}
|
||||
|
||||
static uint32_t find_rec(char *name)
|
||||
{
|
||||
char *p = (char *)obuf;
|
||||
|
@ -277,6 +335,7 @@ static const LibDefHandler libdef_handlers[] = {
|
|||
{ "CF(", ")", libdef_func, LIBINIT_CF },
|
||||
{ "ASM(", ")", libdef_func, LIBINIT_ASM },
|
||||
{ "ASM_(", ")", libdef_func, LIBINIT_ASM_ },
|
||||
{ "LUA(", ")", libdef_lua, 0 },
|
||||
{ "REC(", ")", libdef_rec, 0 },
|
||||
{ "PUSH(", ")", libdef_push, 0 },
|
||||
{ "SET(", ")", libdef_set, 0 },
|
||||
|
@ -373,7 +432,7 @@ void emit_lib(BuildCtx *ctx)
|
|||
"#ifndef FF_NUM_ASMFUNC\n#define FF_NUM_ASMFUNC %d\n#endif\n\n",
|
||||
ffasmfunc);
|
||||
} else if (ctx->mode == BUILD_vmdef) {
|
||||
fprintf(ctx->fp, "}\n\n");
|
||||
fprintf(ctx->fp, "},\n\n");
|
||||
} else if (ctx->mode == BUILD_bcdef) {
|
||||
int i;
|
||||
fprintf(ctx->fp, "\n};\n\n");
|
||||
|
|
56
vendor/luajit/src/host/buildvm_libbc.h
vendored
Normal file
56
vendor/luajit/src/host/buildvm_libbc.h
vendored
Normal file
|
@ -0,0 +1,56 @@
|
|||
/* This is a generated file. DO NOT EDIT! */
|
||||
|
||||
static const int libbc_endian = 0;
|
||||
|
||||
static const uint8_t libbc_code[] = {
|
||||
#if LJ_FR2
|
||||
0,1,2,0,0,1,2,24,1,0,0,76,1,2,0,241,135,158,166,3,220,203,178,130,4,0,1,2,0,
|
||||
0,1,2,24,1,0,0,76,1,2,0,243,244,148,165,20,198,190,199,252,3,0,1,2,0,0,0,3,
|
||||
16,0,5,0,21,1,0,0,76,1,2,0,0,2,10,0,0,0,15,16,0,12,0,16,1,9,0,41,2,1,0,21,3,
|
||||
0,0,41,4,1,0,77,2,8,128,18,6,1,0,18,8,5,0,59,9,5,0,66,6,3,2,10,6,0,0,88,7,1,
|
||||
128,76,6,2,0,79,2,248,127,75,0,1,0,0,2,11,0,0,0,16,16,0,12,0,16,1,9,0,43,2,
|
||||
0,0,18,3,0,0,41,4,0,0,88,5,7,128,18,7,1,0,18,9,5,0,18,10,6,0,66,7,3,2,10,7,
|
||||
0,0,88,8,1,128,76,7,2,0,70,5,3,3,82,5,247,127,75,0,1,0,0,1,2,0,0,0,3,16,0,12,
|
||||
0,21,1,0,0,76,1,2,0,0,2,10,0,0,2,30,16,0,12,0,21,2,0,0,11,1,0,0,88,3,7,128,
|
||||
8,2,0,0,88,3,23,128,59,3,2,0,43,4,0,0,64,4,2,0,76,3,2,0,88,3,18,128,16,1,14,
|
||||
0,41,3,1,0,3,3,1,0,88,3,14,128,3,1,2,0,88,3,12,128,59,3,1,0,22,4,1,1,18,5,2,
|
||||
0,41,6,1,0,77,4,4,128,23,8,1,7,59,9,7,0,64,9,8,0,79,4,252,127,43,4,0,0,64,4,
|
||||
2,0,76,3,2,0,75,0,1,0,0,2,0,5,12,0,0,0,35,16,0,12,0,16,1,14,0,16,2,14,0,16,
|
||||
3,14,0,11,4,0,0,88,5,1,128,18,4,0,0,16,4,12,0,3,1,2,0,88,5,24,128,33,5,1,3,
|
||||
0,2,3,0,88,6,4,128,2,3,1,0,88,6,2,128,4,4,0,0,88,6,9,128,18,6,1,0,18,7,2,0,
|
||||
41,8,1,0,77,6,4,128,32,10,5,9,59,11,9,0,64,11,10,4,79,6,252,127,88,6,8,128,
|
||||
18,6,2,0,18,7,1,0,41,8,255,255,77,6,4,128,32,10,5,9,59,11,9,0,64,11,10,4,79,
|
||||
6,252,127,76,4,2,0,0
|
||||
#else
|
||||
0,1,2,0,0,1,2,24,1,0,0,76,1,2,0,241,135,158,166,3,220,203,178,130,4,0,1,2,0,
|
||||
0,1,2,24,1,0,0,76,1,2,0,243,244,148,165,20,198,190,199,252,3,0,1,2,0,0,0,3,
|
||||
16,0,5,0,21,1,0,0,76,1,2,0,0,2,9,0,0,0,15,16,0,12,0,16,1,9,0,41,2,1,0,21,3,
|
||||
0,0,41,4,1,0,77,2,8,128,18,6,1,0,18,7,5,0,59,8,5,0,66,6,3,2,10,6,0,0,88,7,1,
|
||||
128,76,6,2,0,79,2,248,127,75,0,1,0,0,2,10,0,0,0,16,16,0,12,0,16,1,9,0,43,2,
|
||||
0,0,18,3,0,0,41,4,0,0,88,5,7,128,18,7,1,0,18,8,5,0,18,9,6,0,66,7,3,2,10,7,0,
|
||||
0,88,8,1,128,76,7,2,0,70,5,3,3,82,5,247,127,75,0,1,0,0,1,2,0,0,0,3,16,0,12,
|
||||
0,21,1,0,0,76,1,2,0,0,2,10,0,0,2,30,16,0,12,0,21,2,0,0,11,1,0,0,88,3,7,128,
|
||||
8,2,0,0,88,3,23,128,59,3,2,0,43,4,0,0,64,4,2,0,76,3,2,0,88,3,18,128,16,1,14,
|
||||
0,41,3,1,0,3,3,1,0,88,3,14,128,3,1,2,0,88,3,12,128,59,3,1,0,22,4,1,1,18,5,2,
|
||||
0,41,6,1,0,77,4,4,128,23,8,1,7,59,9,7,0,64,9,8,0,79,4,252,127,43,4,0,0,64,4,
|
||||
2,0,76,3,2,0,75,0,1,0,0,2,0,5,12,0,0,0,35,16,0,12,0,16,1,14,0,16,2,14,0,16,
|
||||
3,14,0,11,4,0,0,88,5,1,128,18,4,0,0,16,4,12,0,3,1,2,0,88,5,24,128,33,5,1,3,
|
||||
0,2,3,0,88,6,4,128,2,3,1,0,88,6,2,128,4,4,0,0,88,6,9,128,18,6,1,0,18,7,2,0,
|
||||
41,8,1,0,77,6,4,128,32,10,5,9,59,11,9,0,64,11,10,4,79,6,252,127,88,6,8,128,
|
||||
18,6,2,0,18,7,1,0,41,8,255,255,77,6,4,128,32,10,5,9,59,11,9,0,64,11,10,4,79,
|
||||
6,252,127,76,4,2,0,0
|
||||
#endif
|
||||
};
|
||||
|
||||
static const struct { const char *name; int ofs; } libbc_map[] = {
|
||||
{"math_deg",0},
|
||||
{"math_rad",25},
|
||||
{"string_len",50},
|
||||
{"table_foreachi",69},
|
||||
{"table_foreach",136},
|
||||
{"table_getn",207},
|
||||
{"table_remove",226},
|
||||
{"table_move",355},
|
||||
{NULL,502}
|
||||
};
|
||||
|
30
vendor/luajit/src/host/buildvm_peobj.c
vendored
30
vendor/luajit/src/host/buildvm_peobj.c
vendored
|
@ -1,6 +1,6 @@
|
|||
/*
|
||||
** LuaJIT VM builder: PE object emitter.
|
||||
** Copyright (C) 2005-2015 Mike Pall. See Copyright Notice in luajit.h
|
||||
** Copyright (C) 2005-2017 Mike Pall. See Copyright Notice in luajit.h
|
||||
**
|
||||
** Only used for building on Windows, since we cannot assume the presence
|
||||
** of a suitable assembler. The host and target byte order must match.
|
||||
|
@ -109,6 +109,8 @@ enum {
|
|||
#if LJ_TARGET_X64
|
||||
PEOBJ_SECT_PDATA,
|
||||
PEOBJ_SECT_XDATA,
|
||||
#elif LJ_TARGET_X86
|
||||
PEOBJ_SECT_SXDATA,
|
||||
#endif
|
||||
PEOBJ_SECT_RDATA_Z,
|
||||
PEOBJ_NSECTIONS
|
||||
|
@ -208,6 +210,13 @@ void emit_peobj(BuildCtx *ctx)
|
|||
sofs += (pesect[PEOBJ_SECT_XDATA].nreloc = 1) * PEOBJ_RELOC_SIZE;
|
||||
/* Flags: 40 = read, 30 = align4, 40 = initialized data. */
|
||||
pesect[PEOBJ_SECT_XDATA].flags = 0x40300040;
|
||||
#elif LJ_TARGET_X86
|
||||
memcpy(pesect[PEOBJ_SECT_SXDATA].name, ".sxdata", sizeof(".sxdata")-1);
|
||||
pesect[PEOBJ_SECT_SXDATA].ofs = sofs;
|
||||
sofs += (pesect[PEOBJ_SECT_SXDATA].size = 4);
|
||||
pesect[PEOBJ_SECT_SXDATA].relocofs = sofs;
|
||||
/* Flags: 40 = read, 30 = align4, 02 = lnk_info, 40 = initialized data. */
|
||||
pesect[PEOBJ_SECT_SXDATA].flags = 0x40300240;
|
||||
#endif
|
||||
|
||||
memcpy(pesect[PEOBJ_SECT_RDATA_Z].name, ".rdata$Z", sizeof(".rdata$Z")-1);
|
||||
|
@ -232,7 +241,7 @@ void emit_peobj(BuildCtx *ctx)
|
|||
nrsym = ctx->nrelocsym;
|
||||
pehdr.nsyms = 1+PEOBJ_NSECTIONS*2 + 1+ctx->nsym + nrsym;
|
||||
#if LJ_TARGET_X64
|
||||
pehdr.nsyms += 1; /* Symbol for lj_err_unwind_win64. */
|
||||
pehdr.nsyms += 1; /* Symbol for lj_err_unwind_win. */
|
||||
#endif
|
||||
|
||||
/* Write PE object header and all sections. */
|
||||
|
@ -312,6 +321,19 @@ void emit_peobj(BuildCtx *ctx)
|
|||
reloc.type = PEOBJ_RELOC_ADDR32NB;
|
||||
owrite(ctx, &reloc, PEOBJ_RELOC_SIZE);
|
||||
}
|
||||
#elif LJ_TARGET_X86
|
||||
/* Write .sxdata section. */
|
||||
for (i = 0; i < nrsym; i++) {
|
||||
if (!strcmp(ctx->relocsym[i], "_lj_err_unwind_win")) {
|
||||
uint32_t symidx = 1+2+i;
|
||||
owrite(ctx, &symidx, 4);
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (i == nrsym) {
|
||||
fprintf(stderr, "Error: extern lj_err_unwind_win not used\n");
|
||||
exit(1);
|
||||
}
|
||||
#endif
|
||||
|
||||
/* Write .rdata$Z section. */
|
||||
|
@ -333,8 +355,10 @@ void emit_peobj(BuildCtx *ctx)
|
|||
#if LJ_TARGET_X64
|
||||
emit_peobj_sym_sect(ctx, pesect, PEOBJ_SECT_PDATA);
|
||||
emit_peobj_sym_sect(ctx, pesect, PEOBJ_SECT_XDATA);
|
||||
emit_peobj_sym(ctx, "lj_err_unwind_win64", 0,
|
||||
emit_peobj_sym(ctx, "lj_err_unwind_win", 0,
|
||||
PEOBJ_SECT_UNDEF, PEOBJ_TYPE_FUNC, PEOBJ_SCL_EXTERN);
|
||||
#elif LJ_TARGET_X86
|
||||
emit_peobj_sym_sect(ctx, pesect, PEOBJ_SECT_SXDATA);
|
||||
#endif
|
||||
|
||||
emit_peobj_sym(ctx, ctx->beginsym, 0,
|
||||
|
|
197
vendor/luajit/src/host/genlibbc.lua
vendored
Normal file
197
vendor/luajit/src/host/genlibbc.lua
vendored
Normal file
|
@ -0,0 +1,197 @@
|
|||
----------------------------------------------------------------------------
|
||||
-- Lua script to dump the bytecode of the library functions written in Lua.
|
||||
-- The resulting 'buildvm_libbc.h' is used for the build process of LuaJIT.
|
||||
----------------------------------------------------------------------------
|
||||
-- Copyright (C) 2005-2017 Mike Pall. All rights reserved.
|
||||
-- Released under the MIT license. See Copyright Notice in luajit.h
|
||||
----------------------------------------------------------------------------
|
||||
|
||||
local ffi = require("ffi")
|
||||
local bit = require("bit")
|
||||
local vmdef = require("jit.vmdef")
|
||||
local bcnames = vmdef.bcnames
|
||||
|
||||
local format = string.format
|
||||
|
||||
local isbe = (string.byte(string.dump(function() end), 5) % 2 == 1)
|
||||
|
||||
local function usage(arg)
|
||||
io.stderr:write("Usage: ", arg and arg[0] or "genlibbc",
|
||||
" [-o buildvm_libbc.h] lib_*.c\n")
|
||||
os.exit(1)
|
||||
end
|
||||
|
||||
local function parse_arg(arg)
|
||||
local outfile = "-"
|
||||
if not (arg and arg[1]) then
|
||||
usage(arg)
|
||||
end
|
||||
if arg[1] == "-o" then
|
||||
outfile = arg[2]
|
||||
if not outfile then usage(arg) end
|
||||
table.remove(arg, 1)
|
||||
table.remove(arg, 1)
|
||||
end
|
||||
return outfile
|
||||
end
|
||||
|
||||
local function read_files(names)
|
||||
local src = ""
|
||||
for _,name in ipairs(names) do
|
||||
local fp = assert(io.open(name))
|
||||
src = src .. fp:read("*a")
|
||||
fp:close()
|
||||
end
|
||||
return src
|
||||
end
|
||||
|
||||
local function transform_lua(code)
|
||||
local fixup = {}
|
||||
local n = -30000
|
||||
code = string.gsub(code, "CHECK_(%w*)%((.-)%)", function(tp, var)
|
||||
n = n + 1
|
||||
fixup[n] = { "CHECK", tp }
|
||||
return format("%s=%d", var, n)
|
||||
end)
|
||||
code = string.gsub(code, "PAIRS%((.-)%)", function(var)
|
||||
fixup.PAIRS = true
|
||||
return format("nil, %s, 0", var)
|
||||
end)
|
||||
return "return "..code, fixup
|
||||
end
|
||||
|
||||
local function read_uleb128(p)
|
||||
local v = p[0]; p = p + 1
|
||||
if v >= 128 then
|
||||
local sh = 7; v = v - 128
|
||||
repeat
|
||||
local r = p[0]
|
||||
v = v + bit.lshift(bit.band(r, 127), sh)
|
||||
sh = sh + 7
|
||||
p = p + 1
|
||||
until r < 128
|
||||
end
|
||||
return p, v
|
||||
end
|
||||
|
||||
-- ORDER LJ_T
|
||||
local name2itype = {
|
||||
str = 5, func = 9, tab = 12, int = 14, num = 15
|
||||
}
|
||||
|
||||
local BC = {}
|
||||
for i=0,#bcnames/6-1 do
|
||||
BC[string.gsub(string.sub(bcnames, i*6+1, i*6+6), " ", "")] = i
|
||||
end
|
||||
local xop, xra = isbe and 3 or 0, isbe and 2 or 1
|
||||
local xrc, xrb = isbe and 1 or 2, isbe and 0 or 3
|
||||
|
||||
local function fixup_dump(dump, fixup)
|
||||
local buf = ffi.new("uint8_t[?]", #dump+1, dump)
|
||||
local p = buf+5
|
||||
local n, sizebc
|
||||
p, n = read_uleb128(p)
|
||||
local start = p
|
||||
p = p + 4
|
||||
p = read_uleb128(p)
|
||||
p = read_uleb128(p)
|
||||
p, sizebc = read_uleb128(p)
|
||||
local rawtab = {}
|
||||
for i=0,sizebc-1 do
|
||||
local op = p[xop]
|
||||
if op == BC.KSHORT then
|
||||
local rd = p[xrc] + 256*p[xrb]
|
||||
rd = bit.arshift(bit.lshift(rd, 16), 16)
|
||||
local f = fixup[rd]
|
||||
if f then
|
||||
if f[1] == "CHECK" then
|
||||
local tp = f[2]
|
||||
if tp == "tab" then rawtab[p[xra]] = true end
|
||||
p[xop] = tp == "num" and BC.ISNUM or BC.ISTYPE
|
||||
p[xrb] = 0
|
||||
p[xrc] = name2itype[tp]
|
||||
else
|
||||
error("unhandled fixup type: "..f[1])
|
||||
end
|
||||
end
|
||||
elseif op == BC.TGETV then
|
||||
if rawtab[p[xrb]] then
|
||||
p[xop] = BC.TGETR
|
||||
end
|
||||
elseif op == BC.TSETV then
|
||||
if rawtab[p[xrb]] then
|
||||
p[xop] = BC.TSETR
|
||||
end
|
||||
elseif op == BC.ITERC then
|
||||
if fixup.PAIRS then
|
||||
p[xop] = BC.ITERN
|
||||
end
|
||||
end
|
||||
p = p + 4
|
||||
end
|
||||
return ffi.string(start, n)
|
||||
end
|
||||
|
||||
local function find_defs(src)
|
||||
local defs = {}
|
||||
for name, code in string.gmatch(src, "LJLIB_LUA%(([^)]*)%)%s*/%*(.-)%*/") do
|
||||
local env = {}
|
||||
local tcode, fixup = transform_lua(code)
|
||||
local func = assert(load(tcode, "", nil, env))()
|
||||
defs[name] = fixup_dump(string.dump(func, true), fixup)
|
||||
defs[#defs+1] = name
|
||||
end
|
||||
return defs
|
||||
end
|
||||
|
||||
local function gen_header(defs)
|
||||
local t = {}
|
||||
local function w(x) t[#t+1] = x end
|
||||
w("/* This is a generated file. DO NOT EDIT! */\n\n")
|
||||
w("static const int libbc_endian = ") w(isbe and 1 or 0) w(";\n\n")
|
||||
local s = ""
|
||||
for _,name in ipairs(defs) do
|
||||
s = s .. defs[name]
|
||||
end
|
||||
w("static const uint8_t libbc_code[] = {\n")
|
||||
local n = 0
|
||||
for i=1,#s do
|
||||
local x = string.byte(s, i)
|
||||
w(x); w(",")
|
||||
n = n + (x < 10 and 2 or (x < 100 and 3 or 4))
|
||||
if n >= 75 then n = 0; w("\n") end
|
||||
end
|
||||
w("0\n};\n\n")
|
||||
w("static const struct { const char *name; int ofs; } libbc_map[] = {\n")
|
||||
local m = 0
|
||||
for _,name in ipairs(defs) do
|
||||
w('{"'); w(name); w('",'); w(m) w('},\n')
|
||||
m = m + #defs[name]
|
||||
end
|
||||
w("{NULL,"); w(m); w("}\n};\n\n")
|
||||
return table.concat(t)
|
||||
end
|
||||
|
||||
local function write_file(name, data)
|
||||
if name == "-" then
|
||||
assert(io.write(data))
|
||||
assert(io.flush())
|
||||
else
|
||||
local fp = io.open(name)
|
||||
if fp then
|
||||
local old = fp:read("*a")
|
||||
fp:close()
|
||||
if data == old then return end
|
||||
end
|
||||
fp = assert(io.open(name, "w"))
|
||||
assert(fp:write(data))
|
||||
assert(fp:close())
|
||||
end
|
||||
end
|
||||
|
||||
local outfile = parse_arg(arg)
|
||||
local src = read_files(arg)
|
||||
local defs = find_defs(src)
|
||||
local hdr = gen_header(defs)
|
||||
write_file(outfile, hdr)
|
||||
|
11
vendor/luajit/src/host/genminilua.lua
vendored
11
vendor/luajit/src/host/genminilua.lua
vendored
|
@ -2,7 +2,7 @@
|
|||
-- Lua script to generate a customized, minified version of Lua.
|
||||
-- The resulting 'minilua' is used for the build process of LuaJIT.
|
||||
----------------------------------------------------------------------------
|
||||
-- Copyright (C) 2005-2015 Mike Pall. All rights reserved.
|
||||
-- Copyright (C) 2005-2017 Mike Pall. All rights reserved.
|
||||
-- Released under the MIT license. See Copyright Notice in luajit.h
|
||||
----------------------------------------------------------------------------
|
||||
|
||||
|
@ -157,11 +157,11 @@ local function merge_includes(src)
|
|||
if includes[name] then return "" end
|
||||
includes[name] = true
|
||||
local fp = assert(io.open(LUA_SOURCE..name, "r"))
|
||||
local src = fp:read("*a")
|
||||
local inc = fp:read("*a")
|
||||
assert(fp:close())
|
||||
src = gsub(src, "#ifndef%s+%w+_h\n#define%s+%w+_h\n", "")
|
||||
src = gsub(src, "#endif%s*$", "")
|
||||
return merge_includes(src)
|
||||
inc = gsub(inc, "#ifndef%s+%w+_h\n#define%s+%w+_h\n", "")
|
||||
inc = gsub(inc, "#endif%s*$", "")
|
||||
return merge_includes(inc)
|
||||
end)
|
||||
end
|
||||
|
||||
|
@ -300,6 +300,7 @@ local function strip_unused3(src)
|
|||
src = gsub(src, "if%([^\n]*hookmask[^\n]*&&\n[^\n]*%b{}\n", "")
|
||||
src = gsub(src, "(twoto%b()%()", "%1(size_t)")
|
||||
src = gsub(src, "i<sizenode", "i<(int)sizenode")
|
||||
src = gsub(src, "cast%(unsigned int,key%-1%)", "cast(unsigned int,key)-1")
|
||||
return gsub(src, "\n\n+", "\n")
|
||||
end
|
||||
|
||||
|
|
2
vendor/luajit/src/host/minilua.c
vendored
2
vendor/luajit/src/host/minilua.c
vendored
|
@ -1606,7 +1606,7 @@ luaC_barriert(L,t,key);
|
|||
return gval(mp);
|
||||
}
|
||||
static const TValue*luaH_getnum(Table*t,int key){
|
||||
if(cast(unsigned int,key-1)<cast(unsigned int,t->sizearray))
|
||||
if(cast(unsigned int,key)-1<cast(unsigned int,t->sizearray))
|
||||
return&t->array[key-1];
|
||||
else{
|
||||
lua_Number nk=cast_num(key);
|
||||
|
|
1
vendor/luajit/src/jit/.gitignore
vendored
Normal file
1
vendor/luajit/src/jit/.gitignore
vendored
Normal file
|
@ -0,0 +1 @@
|
|||
vmdef.lua
|
21
vendor/luajit/src/jit/bc.lua
vendored
21
vendor/luajit/src/jit/bc.lua
vendored
|
@ -1,7 +1,7 @@
|
|||
----------------------------------------------------------------------------
|
||||
-- LuaJIT bytecode listing module.
|
||||
--
|
||||
-- Copyright (C) 2005-2015 Mike Pall. All rights reserved.
|
||||
-- Copyright (C) 2005-2017 Mike Pall. All rights reserved.
|
||||
-- Released under the MIT license. See Copyright Notice in luajit.h
|
||||
----------------------------------------------------------------------------
|
||||
--
|
||||
|
@ -41,7 +41,7 @@
|
|||
|
||||
-- Cache some library functions and objects.
|
||||
local jit = require("jit")
|
||||
assert(jit.version_num == 20004, "LuaJIT core/library version mismatch")
|
||||
assert(jit.version_num == 20100, "LuaJIT core/library version mismatch")
|
||||
local jutil = require("jit.util")
|
||||
local vmdef = require("jit.vmdef")
|
||||
local bit = require("bit")
|
||||
|
@ -179,13 +179,12 @@ local function bcliston(outfile)
|
|||
end
|
||||
|
||||
-- Public module functions.
|
||||
module(...)
|
||||
|
||||
line = bcline
|
||||
dump = bcdump
|
||||
targets = bctargets
|
||||
|
||||
on = bcliston
|
||||
off = bclistoff
|
||||
start = bcliston -- For -j command line option.
|
||||
return {
|
||||
line = bcline,
|
||||
dump = bcdump,
|
||||
targets = bctargets,
|
||||
on = bcliston,
|
||||
off = bclistoff,
|
||||
start = bcliston -- For -j command line option.
|
||||
}
|
||||
|
||||
|
|
36
vendor/luajit/src/jit/bcsave.lua
vendored
36
vendor/luajit/src/jit/bcsave.lua
vendored
|
@ -1,7 +1,7 @@
|
|||
----------------------------------------------------------------------------
|
||||
-- LuaJIT module to save/list bytecode.
|
||||
--
|
||||
-- Copyright (C) 2005-2015 Mike Pall. All rights reserved.
|
||||
-- Copyright (C) 2005-2017 Mike Pall. All rights reserved.
|
||||
-- Released under the MIT license. See Copyright Notice in luajit.h
|
||||
----------------------------------------------------------------------------
|
||||
--
|
||||
|
@ -11,7 +11,7 @@
|
|||
------------------------------------------------------------------------------
|
||||
|
||||
local jit = require("jit")
|
||||
assert(jit.version_num == 20004, "LuaJIT core/library version mismatch")
|
||||
assert(jit.version_num == 20100, "LuaJIT core/library version mismatch")
|
||||
local bit = require("bit")
|
||||
|
||||
-- Symbol name prefix for LuaJIT bytecode.
|
||||
|
@ -63,8 +63,8 @@ local map_type = {
|
|||
}
|
||||
|
||||
local map_arch = {
|
||||
x86 = true, x64 = true, arm = true, ppc = true, ppcspe = true,
|
||||
mips = true, mipsel = true,
|
||||
x86 = true, x64 = true, arm = true, arm64 = true, arm64be = true,
|
||||
ppc = true, mips = true, mipsel = true,
|
||||
}
|
||||
|
||||
local map_os = {
|
||||
|
@ -125,12 +125,12 @@ extern "C"
|
|||
#ifdef _WIN32
|
||||
__declspec(dllexport)
|
||||
#endif
|
||||
const char %s%s[] = {
|
||||
const unsigned char %s%s[] = {
|
||||
]], LJBC_PREFIX, ctx.modname))
|
||||
else
|
||||
fp:write(string.format([[
|
||||
#define %s%s_SIZE %d
|
||||
static const char %s%s[] = {
|
||||
static const unsigned char %s%s[] = {
|
||||
]], LJBC_PREFIX, ctx.modname, #s, LJBC_PREFIX, ctx.modname))
|
||||
end
|
||||
local t, n, m = {}, 0, 0
|
||||
|
@ -200,9 +200,9 @@ typedef struct {
|
|||
]]
|
||||
local symname = LJBC_PREFIX..ctx.modname
|
||||
local is64, isbe = false, false
|
||||
if ctx.arch == "x64" then
|
||||
if ctx.arch == "x64" or ctx.arch == "arm64" or ctx.arch == "arm64be" then
|
||||
is64 = true
|
||||
elseif ctx.arch == "ppc" or ctx.arch == "ppcspe" or ctx.arch == "mips" then
|
||||
elseif ctx.arch == "ppc" or ctx.arch == "mips" then
|
||||
isbe = true
|
||||
end
|
||||
|
||||
|
@ -237,9 +237,9 @@ typedef struct {
|
|||
hdr.eendian = isbe and 2 or 1
|
||||
hdr.eversion = 1
|
||||
hdr.type = f16(1)
|
||||
hdr.machine = f16(({ x86=3, x64=62, arm=40, ppc=20, ppcspe=20, mips=8, mipsel=8 })[ctx.arch])
|
||||
hdr.machine = f16(({ x86=3, x64=62, arm=40, arm64=183, arm64be=183, ppc=20, mips=8, mipsel=8 })[ctx.arch])
|
||||
if ctx.arch == "mips" or ctx.arch == "mipsel" then
|
||||
hdr.flags = 0x50001006
|
||||
hdr.flags = f32(0x50001006)
|
||||
end
|
||||
hdr.version = f32(1)
|
||||
hdr.shofs = fofs(ffi.offsetof(o, "sect"))
|
||||
|
@ -477,13 +477,13 @@ typedef struct {
|
|||
} mach_obj_64;
|
||||
typedef struct {
|
||||
mach_fat_header fat;
|
||||
mach_fat_arch fat_arch[4];
|
||||
mach_fat_arch fat_arch[2];
|
||||
struct {
|
||||
mach_header hdr;
|
||||
mach_segment_command seg;
|
||||
mach_section sec;
|
||||
mach_symtab_command sym;
|
||||
} arch[4];
|
||||
} arch[2];
|
||||
mach_nlist sym_entry;
|
||||
uint8_t space[4096];
|
||||
} mach_fat_obj;
|
||||
|
@ -494,6 +494,8 @@ typedef struct {
|
|||
is64, align, mobj = true, 8, "mach_obj_64"
|
||||
elseif ctx.arch == "arm" then
|
||||
isfat, mobj = true, "mach_fat_obj"
|
||||
elseif ctx.arch == "arm64" then
|
||||
is64, align, isfat, mobj = true, 8, true, "mach_fat_obj"
|
||||
else
|
||||
check(ctx.arch == "x86", "unsupported architecture for OSX")
|
||||
end
|
||||
|
@ -503,8 +505,8 @@ typedef struct {
|
|||
-- Create Mach-O object and fill in header.
|
||||
local o = ffi.new(mobj)
|
||||
local mach_size = aligned(ffi.offsetof(o, "space")+#symname+2, align)
|
||||
local cputype = ({ x86={7}, x64={0x01000007}, arm={7,12,12,12} })[ctx.arch]
|
||||
local cpusubtype = ({ x86={3}, x64={3}, arm={3,6,9,11} })[ctx.arch]
|
||||
local cputype = ({ x86={7}, x64={0x01000007}, arm={7,12}, arm64={0x01000007,0x0100000c} })[ctx.arch]
|
||||
local cpusubtype = ({ x86={3}, x64={3}, arm={3,9}, arm64={3,0} })[ctx.arch]
|
||||
if isfat then
|
||||
o.fat.magic = be32(0xcafebabe)
|
||||
o.fat.nfat_arch = be32(#cpusubtype)
|
||||
|
@ -653,7 +655,7 @@ end
|
|||
------------------------------------------------------------------------------
|
||||
|
||||
-- Public module functions.
|
||||
module(...)
|
||||
|
||||
start = docmd -- Process -b command line option.
|
||||
return {
|
||||
start = docmd -- Process -b command line option.
|
||||
}
|
||||
|
||||
|
|
22
vendor/luajit/src/jit/dis_arm.lua
vendored
22
vendor/luajit/src/jit/dis_arm.lua
vendored
|
@ -1,7 +1,7 @@
|
|||
----------------------------------------------------------------------------
|
||||
-- LuaJIT ARM disassembler module.
|
||||
--
|
||||
-- Copyright (C) 2005-2015 Mike Pall. All rights reserved.
|
||||
-- Copyright (C) 2005-2017 Mike Pall. All rights reserved.
|
||||
-- Released under the MIT license. See Copyright Notice in luajit.h
|
||||
----------------------------------------------------------------------------
|
||||
-- This is a helper module used by the LuaJIT machine code dumper module.
|
||||
|
@ -12,7 +12,7 @@
|
|||
|
||||
local type = type
|
||||
local sub, byte, format = string.sub, string.byte, string.format
|
||||
local match, gmatch, gsub = string.match, string.gmatch, string.gsub
|
||||
local match, gmatch = string.match, string.gmatch
|
||||
local concat = table.concat
|
||||
local bit = require("bit")
|
||||
local band, bor, ror, tohex = bit.band, bit.bor, bit.ror, bit.tohex
|
||||
|
@ -658,7 +658,7 @@ local function disass_block(ctx, ofs, len)
|
|||
end
|
||||
|
||||
-- Extended API: create a disassembler context. Then call ctx:disass(ofs, len).
|
||||
local function create_(code, addr, out)
|
||||
local function create(code, addr, out)
|
||||
local ctx = {}
|
||||
ctx.code = code
|
||||
ctx.addr = addr or 0
|
||||
|
@ -670,20 +670,20 @@ local function create_(code, addr, out)
|
|||
end
|
||||
|
||||
-- Simple API: disassemble code (a string) at address and output via out.
|
||||
local function disass_(code, addr, out)
|
||||
create_(code, addr, out):disass()
|
||||
local function disass(code, addr, out)
|
||||
create(code, addr, out):disass()
|
||||
end
|
||||
|
||||
-- Return register name for RID.
|
||||
local function regname_(r)
|
||||
local function regname(r)
|
||||
if r < 16 then return map_gpr[r] end
|
||||
return "d"..(r-16)
|
||||
end
|
||||
|
||||
-- Public module functions.
|
||||
module(...)
|
||||
|
||||
create = create_
|
||||
disass = disass_
|
||||
regname = regname_
|
||||
return {
|
||||
create = create,
|
||||
disass = disass,
|
||||
regname = regname
|
||||
}
|
||||
|
||||
|
|
1216
vendor/luajit/src/jit/dis_arm64.lua
vendored
Normal file
1216
vendor/luajit/src/jit/dis_arm64.lua
vendored
Normal file
File diff suppressed because it is too large
Load diff
12
vendor/luajit/src/jit/dis_arm64be.lua
vendored
Normal file
12
vendor/luajit/src/jit/dis_arm64be.lua
vendored
Normal file
|
@ -0,0 +1,12 @@
|
|||
----------------------------------------------------------------------------
|
||||
-- LuaJIT ARM64BE disassembler wrapper module.
|
||||
--
|
||||
-- Copyright (C) 2005-2017 Mike Pall. All rights reserved.
|
||||
-- Released under the MIT license. See Copyright Notice in luajit.h
|
||||
----------------------------------------------------------------------------
|
||||
-- ARM64 instructions are always little-endian. So just forward to the
|
||||
-- common ARM64 disassembler module. All the interesting stuff is there.
|
||||
------------------------------------------------------------------------------
|
||||
|
||||
return require((string.match(..., ".*%.") or "").."dis_arm64")
|
||||
|
85
vendor/luajit/src/jit/dis_mips.lua
vendored
85
vendor/luajit/src/jit/dis_mips.lua
vendored
|
@ -1,7 +1,7 @@
|
|||
----------------------------------------------------------------------------
|
||||
-- LuaJIT MIPS disassembler module.
|
||||
--
|
||||
-- Copyright (C) 2005-2015 Mike Pall. All rights reserved.
|
||||
-- Copyright (C) 2005-2017 Mike Pall. All rights reserved.
|
||||
-- Released under the MIT/X license. See Copyright Notice in luajit.h
|
||||
----------------------------------------------------------------------------
|
||||
-- This is a helper module used by the LuaJIT machine code dumper module.
|
||||
|
@ -11,8 +11,8 @@
|
|||
------------------------------------------------------------------------------
|
||||
|
||||
local type = type
|
||||
local sub, byte, format = string.sub, string.byte, string.format
|
||||
local match, gmatch, gsub = string.match, string.gmatch, string.gsub
|
||||
local byte, format = string.byte, string.format
|
||||
local match, gmatch = string.match, string.gmatch
|
||||
local concat = table.concat
|
||||
local bit = require("bit")
|
||||
local band, bor, tohex = bit.band, bit.bor, bit.tohex
|
||||
|
@ -34,15 +34,17 @@ local map_special = {
|
|||
"jrS", "jalrD1S", "movzDST", "movnDST",
|
||||
"syscallY", "breakY", false, "sync",
|
||||
"mfhiD", "mthiS", "mfloD", "mtloS",
|
||||
false, false, false, false,
|
||||
"dsllvDST", false, "dsrlvDST", "dsravDST",
|
||||
"multST", "multuST", "divST", "divuST",
|
||||
false, false, false, false,
|
||||
"dmultST", "dmultuST", "ddivST", "ddivuST",
|
||||
"addDST", "addu|moveDST0", "subDST", "subu|neguDS0T",
|
||||
"andDST", "orDST", "xorDST", "nor|notDST0",
|
||||
"andDST", "or|moveDST0", "xorDST", "nor|notDST0",
|
||||
false, false, "sltDST", "sltuDST",
|
||||
false, false, false, false,
|
||||
"daddDST", "dadduDST", "dsubDST", "dsubuDST",
|
||||
"tgeSTZ", "tgeuSTZ", "tltSTZ", "tltuSTZ",
|
||||
"teqSTZ", false, "tneSTZ",
|
||||
"teqSTZ", false, "tneSTZ", false,
|
||||
"dsllDTA", false, "dsrlDTA", "dsraDTA",
|
||||
"dsll32DTA", false, "dsrl32DTA", "dsra32DTA",
|
||||
}
|
||||
|
||||
local map_special2 = {
|
||||
|
@ -60,11 +62,17 @@ local map_bshfl = {
|
|||
[24] = "sehDT",
|
||||
}
|
||||
|
||||
local map_dbshfl = {
|
||||
shift = 6, mask = 31,
|
||||
[2] = "dsbhDT",
|
||||
[5] = "dshdDT",
|
||||
}
|
||||
|
||||
local map_special3 = {
|
||||
shift = 0, mask = 63,
|
||||
[0] = "extTSAK", [4] = "insTSAL",
|
||||
[32] = map_bshfl,
|
||||
[59] = "rdhwrTD",
|
||||
[0] = "extTSAK", [1] = "dextmTSAP", [3] = "dextTSAK",
|
||||
[4] = "insTSAL", [6] = "dinsuTSEQ", [7] = "dinsTSAL",
|
||||
[32] = map_bshfl, [36] = map_dbshfl, [59] = "rdhwrTD",
|
||||
}
|
||||
|
||||
local map_regimm = {
|
||||
|
@ -178,8 +186,8 @@ local map_cop1bc = {
|
|||
|
||||
local map_cop1 = {
|
||||
shift = 21, mask = 31,
|
||||
[0] = "mfc1TG", false, "cfc1TG", "mfhc1TG",
|
||||
"mtc1TG", false, "ctc1TG", "mthc1TG",
|
||||
[0] = "mfc1TG", "dmfc1TG", "cfc1TG", "mfhc1TG",
|
||||
"mtc1TG", "dmtc1TG", "ctc1TG", "mthc1TG",
|
||||
map_cop1bc, false, false, false,
|
||||
false, false, false, false,
|
||||
map_cop1s, map_cop1d, false, false,
|
||||
|
@ -213,16 +221,16 @@ local map_pri = {
|
|||
"andiTSU", "ori|liTS0U", "xoriTSU", "luiTU",
|
||||
map_cop0, map_cop1, false, map_cop1x,
|
||||
"beql|beqzlST0B", "bnel|bnezlST0B", "blezlSB", "bgtzlSB",
|
||||
false, false, false, false,
|
||||
map_special2, false, false, map_special3,
|
||||
"daddiTSI", "daddiuTSI", false, false,
|
||||
map_special2, "jalxJ", false, map_special3,
|
||||
"lbTSO", "lhTSO", "lwlTSO", "lwTSO",
|
||||
"lbuTSO", "lhuTSO", "lwrTSO", false,
|
||||
"sbTSO", "shTSO", "swlTSO", "swTSO",
|
||||
false, false, "swrTSO", "cacheNSO",
|
||||
"llTSO", "lwc1HSO", "lwc2TSO", "prefNSO",
|
||||
false, "ldc1HSO", "ldc2TSO", false,
|
||||
false, "ldc1HSO", "ldc2TSO", "ldTSO",
|
||||
"scTSO", "swc1HSO", "swc2TSO", false,
|
||||
false, "sdc1HSO", "sdc2TSO", false,
|
||||
false, "sdc1HSO", "sdc2TSO", "sdTSO",
|
||||
}
|
||||
|
||||
------------------------------------------------------------------------------
|
||||
|
@ -306,6 +314,8 @@ local function disass_ins(ctx)
|
|||
x = "f"..band(rshift(op, 21), 31)
|
||||
elseif p == "A" then
|
||||
x = band(rshift(op, 6), 31)
|
||||
elseif p == "E" then
|
||||
x = band(rshift(op, 6), 31) + 32
|
||||
elseif p == "M" then
|
||||
x = band(rshift(op, 11), 31)
|
||||
elseif p == "N" then
|
||||
|
@ -315,8 +325,12 @@ local function disass_ins(ctx)
|
|||
if x == 0 then x = nil end
|
||||
elseif p == "K" then
|
||||
x = band(rshift(op, 11), 31) + 1
|
||||
elseif p == "P" then
|
||||
x = band(rshift(op, 11), 31) + 33
|
||||
elseif p == "L" then
|
||||
x = band(rshift(op, 11), 31) - last + 1
|
||||
elseif p == "Q" then
|
||||
x = band(rshift(op, 11), 31) - last + 33
|
||||
elseif p == "I" then
|
||||
x = arshift(lshift(op, 16), 16)
|
||||
elseif p == "U" then
|
||||
|
@ -330,11 +344,12 @@ local function disass_ins(ctx)
|
|||
elseif p == "B" then
|
||||
x = ctx.addr + ctx.pos + arshift(lshift(op, 16), 16)*4 + 4
|
||||
ctx.rel = x
|
||||
x = "0x"..tohex(x)
|
||||
x = format("0x%08x", x)
|
||||
elseif p == "J" then
|
||||
x = band(ctx.addr + ctx.pos, 0xf0000000) + band(op, 0x03ffffff)*4
|
||||
local a = ctx.addr + ctx.pos
|
||||
x = a - band(a, 0x0fffffff) + band(op, 0x03ffffff)*4
|
||||
ctx.rel = x
|
||||
x = "0x"..tohex(x)
|
||||
x = format("0x%08x", x)
|
||||
elseif p == "V" then
|
||||
x = band(rshift(op, 8), 7)
|
||||
if x == 0 then x = nil end
|
||||
|
@ -384,7 +399,7 @@ local function disass_block(ctx, ofs, len)
|
|||
end
|
||||
|
||||
-- Extended API: create a disassembler context. Then call ctx:disass(ofs, len).
|
||||
local function create_(code, addr, out)
|
||||
local function create(code, addr, out)
|
||||
local ctx = {}
|
||||
ctx.code = code
|
||||
ctx.addr = addr or 0
|
||||
|
@ -396,33 +411,33 @@ local function create_(code, addr, out)
|
|||
return ctx
|
||||
end
|
||||
|
||||
local function create_el_(code, addr, out)
|
||||
local ctx = create_(code, addr, out)
|
||||
local function create_el(code, addr, out)
|
||||
local ctx = create(code, addr, out)
|
||||
ctx.get = get_le
|
||||
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()
|
||||
local function disass(code, addr, out)
|
||||
create(code, addr, out):disass()
|
||||
end
|
||||
|
||||
local function disass_el_(code, addr, out)
|
||||
create_el_(code, addr, out):disass()
|
||||
local function disass_el(code, addr, out)
|
||||
create_el(code, addr, out):disass()
|
||||
end
|
||||
|
||||
-- Return register name for RID.
|
||||
local function regname_(r)
|
||||
local function regname(r)
|
||||
if r < 32 then return map_gpr[r] end
|
||||
return "f"..(r-32)
|
||||
end
|
||||
|
||||
-- Public module functions.
|
||||
module(...)
|
||||
|
||||
create = create_
|
||||
create_el = create_el_
|
||||
disass = disass_
|
||||
disass_el = disass_el_
|
||||
regname = regname_
|
||||
return {
|
||||
create = create,
|
||||
create_el = create_el,
|
||||
disass = disass,
|
||||
disass_el = disass_el,
|
||||
regname = regname
|
||||
}
|
||||
|
||||
|
|
17
vendor/luajit/src/jit/dis_mips64.lua
vendored
Normal file
17
vendor/luajit/src/jit/dis_mips64.lua
vendored
Normal file
|
@ -0,0 +1,17 @@
|
|||
----------------------------------------------------------------------------
|
||||
-- LuaJIT MIPS64 disassembler wrapper module.
|
||||
--
|
||||
-- Copyright (C) 2005-2017 Mike Pall. All rights reserved.
|
||||
-- Released under the MIT license. See Copyright Notice in luajit.h
|
||||
----------------------------------------------------------------------------
|
||||
-- This module just exports the big-endian functions from the
|
||||
-- MIPS disassembler module. All the interesting stuff is there.
|
||||
------------------------------------------------------------------------------
|
||||
|
||||
local dis_mips = require((string.match(..., ".*%.") or "").."dis_mips")
|
||||
return {
|
||||
create = dis_mips.create,
|
||||
disass = dis_mips.disass,
|
||||
regname = dis_mips.regname
|
||||
}
|
||||
|
17
vendor/luajit/src/jit/dis_mips64el.lua
vendored
Normal file
17
vendor/luajit/src/jit/dis_mips64el.lua
vendored
Normal file
|
@ -0,0 +1,17 @@
|
|||
----------------------------------------------------------------------------
|
||||
-- LuaJIT MIPS64EL disassembler wrapper module.
|
||||
--
|
||||
-- Copyright (C) 2005-2017 Mike Pall. All rights reserved.
|
||||
-- Released under the MIT license. See Copyright Notice in luajit.h
|
||||
----------------------------------------------------------------------------
|
||||
-- This module just exports the little-endian functions from the
|
||||
-- MIPS disassembler module. All the interesting stuff is there.
|
||||
------------------------------------------------------------------------------
|
||||
|
||||
local dis_mips = require((string.match(..., ".*%.") or "").."dis_mips")
|
||||
return {
|
||||
create = dis_mips.create_el,
|
||||
disass = dis_mips.disass_el,
|
||||
regname = dis_mips.regname
|
||||
}
|
||||
|
17
vendor/luajit/src/jit/dis_mipsel.lua
vendored
17
vendor/luajit/src/jit/dis_mipsel.lua
vendored
|
@ -1,20 +1,17 @@
|
|||
----------------------------------------------------------------------------
|
||||
-- LuaJIT MIPSEL disassembler wrapper module.
|
||||
--
|
||||
-- Copyright (C) 2005-2015 Mike Pall. All rights reserved.
|
||||
-- Copyright (C) 2005-2017 Mike Pall. All rights reserved.
|
||||
-- Released under the MIT license. See Copyright Notice in luajit.h
|
||||
----------------------------------------------------------------------------
|
||||
-- This module just exports the little-endian functions from the
|
||||
-- MIPS disassembler module. All the interesting stuff is there.
|
||||
------------------------------------------------------------------------------
|
||||
|
||||
local require = require
|
||||
|
||||
module(...)
|
||||
|
||||
local dis_mips = require(_PACKAGE.."dis_mips")
|
||||
|
||||
create = dis_mips.create_el
|
||||
disass = dis_mips.disass_el
|
||||
regname = dis_mips.regname
|
||||
local dis_mips = require((string.match(..., ".*%.") or "").."dis_mips")
|
||||
return {
|
||||
create = dis_mips.create_el,
|
||||
disass = dis_mips.disass_el,
|
||||
regname = dis_mips.regname
|
||||
}
|
||||
|
||||
|
|
22
vendor/luajit/src/jit/dis_ppc.lua
vendored
22
vendor/luajit/src/jit/dis_ppc.lua
vendored
|
@ -1,7 +1,7 @@
|
|||
----------------------------------------------------------------------------
|
||||
-- LuaJIT PPC disassembler module.
|
||||
--
|
||||
-- Copyright (C) 2005-2015 Mike Pall. All rights reserved.
|
||||
-- Copyright (C) 2005-2017 Mike Pall. All rights reserved.
|
||||
-- Released under the MIT/X license. See Copyright Notice in luajit.h
|
||||
----------------------------------------------------------------------------
|
||||
-- This is a helper module used by the LuaJIT machine code dumper module.
|
||||
|
@ -13,7 +13,7 @@
|
|||
------------------------------------------------------------------------------
|
||||
|
||||
local type = type
|
||||
local sub, byte, format = string.sub, string.byte, string.format
|
||||
local byte, format = string.byte, string.format
|
||||
local match, gmatch, gsub = string.match, string.gmatch, string.gsub
|
||||
local concat = table.concat
|
||||
local bit = require("bit")
|
||||
|
@ -560,7 +560,7 @@ local function disass_block(ctx, ofs, len)
|
|||
end
|
||||
|
||||
-- Extended API: create a disassembler context. Then call ctx:disass(ofs, len).
|
||||
local function create_(code, addr, out)
|
||||
local function create(code, addr, out)
|
||||
local ctx = {}
|
||||
ctx.code = code
|
||||
ctx.addr = addr or 0
|
||||
|
@ -572,20 +572,20 @@ local function create_(code, addr, out)
|
|||
end
|
||||
|
||||
-- Simple API: disassemble code (a string) at address and output via out.
|
||||
local function disass_(code, addr, out)
|
||||
create_(code, addr, out):disass()
|
||||
local function disass(code, addr, out)
|
||||
create(code, addr, out):disass()
|
||||
end
|
||||
|
||||
-- Return register name for RID.
|
||||
local function regname_(r)
|
||||
local function regname(r)
|
||||
if r < 32 then return map_gpr[r] end
|
||||
return "f"..(r-32)
|
||||
end
|
||||
|
||||
-- Public module functions.
|
||||
module(...)
|
||||
|
||||
create = create_
|
||||
disass = disass_
|
||||
regname = regname_
|
||||
return {
|
||||
create = create,
|
||||
disass = disass,
|
||||
regname = regname
|
||||
}
|
||||
|
||||
|
|
17
vendor/luajit/src/jit/dis_x64.lua
vendored
17
vendor/luajit/src/jit/dis_x64.lua
vendored
|
@ -1,20 +1,17 @@
|
|||
----------------------------------------------------------------------------
|
||||
-- LuaJIT x64 disassembler wrapper module.
|
||||
--
|
||||
-- Copyright (C) 2005-2015 Mike Pall. All rights reserved.
|
||||
-- Copyright (C) 2005-2017 Mike Pall. All rights reserved.
|
||||
-- Released under the MIT license. See Copyright Notice in luajit.h
|
||||
----------------------------------------------------------------------------
|
||||
-- This module just exports the 64 bit functions from the combined
|
||||
-- x86/x64 disassembler module. All the interesting stuff is there.
|
||||
------------------------------------------------------------------------------
|
||||
|
||||
local require = require
|
||||
|
||||
module(...)
|
||||
|
||||
local dis_x86 = require(_PACKAGE.."dis_x86")
|
||||
|
||||
create = dis_x86.create64
|
||||
disass = dis_x86.disass64
|
||||
regname = dis_x86.regname64
|
||||
local dis_x86 = require((string.match(..., ".*%.") or "").."dis_x86")
|
||||
return {
|
||||
create = dis_x86.create64,
|
||||
disass = dis_x86.disass64,
|
||||
regname = dis_x86.regname64
|
||||
}
|
||||
|
||||
|
|
277
vendor/luajit/src/jit/dis_x86.lua
vendored
277
vendor/luajit/src/jit/dis_x86.lua
vendored
|
@ -1,7 +1,7 @@
|
|||
----------------------------------------------------------------------------
|
||||
-- LuaJIT x86/x64 disassembler module.
|
||||
--
|
||||
-- Copyright (C) 2005-2015 Mike Pall. All rights reserved.
|
||||
-- Copyright (C) 2005-2017 Mike Pall. All rights reserved.
|
||||
-- Released under the MIT license. See Copyright Notice in luajit.h
|
||||
----------------------------------------------------------------------------
|
||||
-- This is a helper module used by the LuaJIT machine code dumper module.
|
||||
|
@ -15,19 +15,20 @@
|
|||
-- Intel and AMD manuals. The supported instruction set is quite extensive
|
||||
-- and reflects what a current generation Intel or AMD CPU implements in
|
||||
-- 32 bit and 64 bit mode. Yes, this includes MMX, SSE, SSE2, SSE3, SSSE3,
|
||||
-- SSE4.1, SSE4.2, SSE4a and even privileged and hypervisor (VMX/SVM)
|
||||
-- instructions.
|
||||
-- SSE4.1, SSE4.2, SSE4a, AVX, AVX2 and even privileged and hypervisor
|
||||
-- (VMX/SVM) 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.
|
||||
------------------------------------------------------------------------------
|
||||
|
||||
local type = type
|
||||
local sub, byte, format = string.sub, string.byte, string.format
|
||||
local match, gmatch, gsub = string.match, string.gmatch, string.gsub
|
||||
local lower, rep = string.lower, string.rep
|
||||
local bit = require("bit")
|
||||
local tohex = bit.tohex
|
||||
|
||||
-- Map for 1st opcode byte in 32 bit mode. Ugly? Well ... read on.
|
||||
local map_opc1_32 = {
|
||||
|
@ -76,7 +77,7 @@ local map_opc1_32 = {
|
|||
"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",
|
||||
"shift!Bmu","shift!Vmu","retBw","ret","vex*3$lesVrm","vex*2$ldsVrm","movBmi","movVmi",
|
||||
"enterBwu","leave","retfBw","retf","int3","intBu","into","iretVS",
|
||||
--Dx
|
||||
"shift!Bm1","shift!Vm1","shift!Bmc","shift!Vmc","aamBu","aadBu","salc","xlatb",
|
||||
|
@ -101,7 +102,7 @@ local map_opc1_64 = setmetatable({
|
|||
[0x44]="rex*r", [0x45]="rex*rb", [0x46]="rex*rx", [0x47]="rex*rxb",
|
||||
[0x48]="rex*w", [0x49]="rex*wb", [0x4a]="rex*wx", [0x4b]="rex*wxb",
|
||||
[0x4c]="rex*wr", [0x4d]="rex*wrb", [0x4e]="rex*wrx", [0x4f]="rex*wrxb",
|
||||
[0x82]=false, [0x9a]=false, [0xc4]=false, [0xc5]=false, [0xce]=false,
|
||||
[0x82]=false, [0x9a]=false, [0xc4]="vex*3", [0xc5]="vex*2", [0xce]=false,
|
||||
[0xd4]=false, [0xd5]=false, [0xd6]=false, [0xea]=false,
|
||||
}, { __index = map_opc1_32 })
|
||||
|
||||
|
@ -112,12 +113,12 @@ local map_opc2 = {
|
|||
[0]="sldt!Dmp","sgdt!Ump","larVrm","lslVrm",nil,"syscall","clts","sysret",
|
||||
"invd","wbinvd",nil,"ud1",nil,"$prefetch!Bm","femms","3dnowMrmu",
|
||||
--1x
|
||||
"movupsXrm|movssXrm|movupdXrm|movsdXrm",
|
||||
"movupsXmr|movssXmr|movupdXmr|movsdXmr",
|
||||
"movupsXrm|movssXrvm|movupdXrm|movsdXrvm",
|
||||
"movupsXmr|movssXmvr|movupdXmr|movsdXmvr",
|
||||
"movhlpsXrm$movlpsXrm|movsldupXrm|movlpdXrm|movddupXrm",
|
||||
"movlpsXmr||movlpdXmr",
|
||||
"unpcklpsXrm||unpcklpdXrm",
|
||||
"unpckhpsXrm||unpckhpdXrm",
|
||||
"unpcklpsXrvm||unpcklpdXrvm",
|
||||
"unpckhpsXrvm||unpckhpdXrvm",
|
||||
"movlhpsXrm$movhpsXrm|movshdupXrm|movhpdXrm",
|
||||
"movhpsXmr||movhpdXmr",
|
||||
"$prefetcht!Bm","hintnopVm","hintnopVm","hintnopVm",
|
||||
|
@ -126,7 +127,7 @@ local map_opc2 = {
|
|||
"movUmx$","movUmy$","movUxm$","movUym$","movUmz$",nil,"movUzm$",nil,
|
||||
"movapsXrm||movapdXrm",
|
||||
"movapsXmr||movapdXmr",
|
||||
"cvtpi2psXrMm|cvtsi2ssXrVmt|cvtpi2pdXrMm|cvtsi2sdXrVmt",
|
||||
"cvtpi2psXrMm|cvtsi2ssXrvVmt|cvtpi2pdXrMm|cvtsi2sdXrvVmt",
|
||||
"movntpsXmr|movntssXmr|movntpdXmr|movntsdXmr",
|
||||
"cvttps2piMrXm|cvttss2siVrXm|cvttpd2piMrXm|cvttsd2siVrXm",
|
||||
"cvtps2piMrXm|cvtss2siVrXm|cvtpd2piMrXm|cvtsd2siVrXm",
|
||||
|
@ -142,27 +143,27 @@ local map_opc2 = {
|
|||
"cmovlVrm","cmovgeVrm","cmovleVrm","cmovgVrm",
|
||||
--5x
|
||||
"movmskpsVrXm$||movmskpdVrXm$","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",
|
||||
"rsqrtpsXrm|rsqrtssXrvm","rcppsXrm|rcpssXrvm",
|
||||
"andpsXrvm||andpdXrvm","andnpsXrvm||andnpdXrvm",
|
||||
"orpsXrvm||orpdXrvm","xorpsXrvm||xorpdXrvm",
|
||||
"addpsXrvm|addssXrvm|addpdXrvm|addsdXrvm","mulpsXrvm|mulssXrvm|mulpdXrvm|mulsdXrvm",
|
||||
"cvtps2pdXrm|cvtss2sdXrvm|cvtpd2psXrm|cvtsd2ssXrvm",
|
||||
"cvtdq2psXrm|cvttps2dqXrm|cvtps2dqXrm",
|
||||
"subpsXrm|subssXrm|subpdXrm|subsdXrm","minpsXrm|minssXrm|minpdXrm|minsdXrm",
|
||||
"divpsXrm|divssXrm|divpdXrm|divsdXrm","maxpsXrm|maxssXrm|maxpdXrm|maxsdXrm",
|
||||
"subpsXrvm|subssXrvm|subpdXrvm|subsdXrvm","minpsXrvm|minssXrvm|minpdXrvm|minsdXrvm",
|
||||
"divpsXrvm|divssXrvm|divpdXrvm|divsdXrvm","maxpsXrvm|maxssXrvm|maxpdXrvm|maxsdXrvm",
|
||||
--6x
|
||||
"punpcklbwPrm","punpcklwdPrm","punpckldqPrm","packsswbPrm",
|
||||
"pcmpgtbPrm","pcmpgtwPrm","pcmpgtdPrm","packuswbPrm",
|
||||
"punpckhbwPrm","punpckhwdPrm","punpckhdqPrm","packssdwPrm",
|
||||
"||punpcklqdqXrm","||punpckhqdqXrm",
|
||||
"punpcklbwPrvm","punpcklwdPrvm","punpckldqPrvm","packsswbPrvm",
|
||||
"pcmpgtbPrvm","pcmpgtwPrvm","pcmpgtdPrvm","packuswbPrvm",
|
||||
"punpckhbwPrvm","punpckhwdPrvm","punpckhdqPrvm","packssdwPrvm",
|
||||
"||punpcklqdqXrvm","||punpckhqdqXrvm",
|
||||
"movPrVSm","movqMrm|movdquXrm|movdqaXrm",
|
||||
--7x
|
||||
"pshufwMrmu|pshufhwXrmu|pshufdXrmu|pshuflwXrmu","pshiftw!Pmu",
|
||||
"pshiftd!Pmu","pshiftq!Mmu||pshiftdq!Xmu",
|
||||
"pcmpeqbPrm","pcmpeqwPrm","pcmpeqdPrm","emms|",
|
||||
"pshufwMrmu|pshufhwXrmu|pshufdXrmu|pshuflwXrmu","pshiftw!Pvmu",
|
||||
"pshiftd!Pvmu","pshiftq!Mvmu||pshiftdq!Xvmu",
|
||||
"pcmpeqbPrvm","pcmpeqwPrvm","pcmpeqdPrvm","emms*|",
|
||||
"vmreadUmr||extrqXmuu$|insertqXrmuu$","vmwriteUrm||extrqXrm$|insertqXrm$",
|
||||
nil,nil,
|
||||
"||haddpdXrm|haddpsXrm","||hsubpdXrm|hsubpsXrm",
|
||||
"||haddpdXrvm|haddpsXrvm","||hsubpdXrvm|hsubpsXrvm",
|
||||
"movVSmMr|movqXrm|movVSmXr","movqMmr|movdquXmr|movdqaXmr",
|
||||
--8x
|
||||
"joVj","jnoVj","jbVj","jnbVj","jzVj","jnzVj","jbeVj","jaVj",
|
||||
|
@ -180,27 +181,27 @@ nil,nil,
|
|||
"bsfVrm","bsrVrm|lzcntVrm|bsrWrm","movsxVrBmt","movsxVrWmt",
|
||||
--Cx
|
||||
"xaddBmr","xaddVmr",
|
||||
"cmppsXrmu|cmpssXrmu|cmppdXrmu|cmpsdXrmu","$movntiVmr|",
|
||||
"pinsrwPrWmu","pextrwDrPmu",
|
||||
"shufpsXrmu||shufpdXrmu","$cmpxchg!Qmp",
|
||||
"cmppsXrvmu|cmpssXrvmu|cmppdXrvmu|cmpsdXrvmu","$movntiVmr|",
|
||||
"pinsrwPrvWmu","pextrwDrPmu",
|
||||
"shufpsXrvmu||shufpdXrvmu","$cmpxchg!Qmp",
|
||||
"bswapVR","bswapVR","bswapVR","bswapVR","bswapVR","bswapVR","bswapVR","bswapVR",
|
||||
--Dx
|
||||
"||addsubpdXrm|addsubpsXrm","psrlwPrm","psrldPrm","psrlqPrm",
|
||||
"paddqPrm","pmullwPrm",
|
||||
"||addsubpdXrvm|addsubpsXrvm","psrlwPrvm","psrldPrvm","psrlqPrvm",
|
||||
"paddqPrvm","pmullwPrvm",
|
||||
"|movq2dqXrMm|movqXmr|movdq2qMrXm$","pmovmskbVrMm||pmovmskbVrXm",
|
||||
"psubusbPrm","psubuswPrm","pminubPrm","pandPrm",
|
||||
"paddusbPrm","padduswPrm","pmaxubPrm","pandnPrm",
|
||||
"psubusbPrvm","psubuswPrvm","pminubPrvm","pandPrvm",
|
||||
"paddusbPrvm","padduswPrvm","pmaxubPrvm","pandnPrvm",
|
||||
--Ex
|
||||
"pavgbPrm","psrawPrm","psradPrm","pavgwPrm",
|
||||
"pmulhuwPrm","pmulhwPrm",
|
||||
"pavgbPrvm","psrawPrvm","psradPrvm","pavgwPrvm",
|
||||
"pmulhuwPrvm","pmulhwPrvm",
|
||||
"|cvtdq2pdXrm|cvttpd2dqXrm|cvtpd2dqXrm","$movntqMmr||$movntdqXmr",
|
||||
"psubsbPrm","psubswPrm","pminswPrm","porPrm",
|
||||
"paddsbPrm","paddswPrm","pmaxswPrm","pxorPrm",
|
||||
"psubsbPrvm","psubswPrvm","pminswPrvm","porPrvm",
|
||||
"paddsbPrvm","paddswPrvm","pmaxswPrvm","pxorPrvm",
|
||||
--Fx
|
||||
"|||lddquXrm","psllwPrm","pslldPrm","psllqPrm",
|
||||
"pmuludqPrm","pmaddwdPrm","psadbwPrm","maskmovqMrm||maskmovdquXrm$",
|
||||
"psubbPrm","psubwPrm","psubdPrm","psubqPrm",
|
||||
"paddbPrm","paddwPrm","padddPrm","ud",
|
||||
"|||lddquXrm","psllwPrvm","pslldPrvm","psllqPrvm",
|
||||
"pmuludqPrvm","pmaddwdPrvm","psadbwPrvm","maskmovqMrm||maskmovdquXrm$",
|
||||
"psubbPrvm","psubwPrvm","psubdPrvm","psubqPrvm",
|
||||
"paddbPrvm","paddwPrvm","padddPrvm","ud",
|
||||
}
|
||||
assert(map_opc2[255] == "ud")
|
||||
|
||||
|
@ -208,49 +209,73 @@ assert(map_opc2[255] == "ud")
|
|||
local map_opc3 = {
|
||||
["38"] = { -- [66] 0f 38 xx
|
||||
--0x
|
||||
[0]="pshufbPrm","phaddwPrm","phadddPrm","phaddswPrm",
|
||||
"pmaddubswPrm","phsubwPrm","phsubdPrm","phsubswPrm",
|
||||
"psignbPrm","psignwPrm","psigndPrm","pmulhrswPrm",
|
||||
nil,nil,nil,nil,
|
||||
[0]="pshufbPrvm","phaddwPrvm","phadddPrvm","phaddswPrvm",
|
||||
"pmaddubswPrvm","phsubwPrvm","phsubdPrvm","phsubswPrvm",
|
||||
"psignbPrvm","psignwPrvm","psigndPrvm","pmulhrswPrvm",
|
||||
"||permilpsXrvm","||permilpdXrvm",nil,nil,
|
||||
--1x
|
||||
"||pblendvbXrma",nil,nil,nil,
|
||||
"||blendvpsXrma","||blendvpdXrma",nil,"||ptestXrm",
|
||||
nil,nil,nil,nil,
|
||||
"||blendvpsXrma","||blendvpdXrma","||permpsXrvm","||ptestXrm",
|
||||
"||broadcastssXrm","||broadcastsdXrm","||broadcastf128XrlXm",nil,
|
||||
"pabsbPrm","pabswPrm","pabsdPrm",nil,
|
||||
--2x
|
||||
"||pmovsxbwXrm","||pmovsxbdXrm","||pmovsxbqXrm","||pmovsxwdXrm",
|
||||
"||pmovsxwqXrm","||pmovsxdqXrm",nil,nil,
|
||||
"||pmuldqXrm","||pcmpeqqXrm","||$movntdqaXrm","||packusdwXrm",
|
||||
nil,nil,nil,nil,
|
||||
"||pmuldqXrvm","||pcmpeqqXrvm","||$movntdqaXrm","||packusdwXrvm",
|
||||
"||maskmovpsXrvm","||maskmovpdXrvm","||maskmovpsXmvr","||maskmovpdXmvr",
|
||||
--3x
|
||||
"||pmovzxbwXrm","||pmovzxbdXrm","||pmovzxbqXrm","||pmovzxwdXrm",
|
||||
"||pmovzxwqXrm","||pmovzxdqXrm",nil,"||pcmpgtqXrm",
|
||||
"||pminsbXrm","||pminsdXrm","||pminuwXrm","||pminudXrm",
|
||||
"||pmaxsbXrm","||pmaxsdXrm","||pmaxuwXrm","||pmaxudXrm",
|
||||
"||pmovzxwqXrm","||pmovzxdqXrm","||permdXrvm","||pcmpgtqXrvm",
|
||||
"||pminsbXrvm","||pminsdXrvm","||pminuwXrvm","||pminudXrvm",
|
||||
"||pmaxsbXrvm","||pmaxsdXrvm","||pmaxuwXrvm","||pmaxudXrvm",
|
||||
--4x
|
||||
"||pmulddXrm","||phminposuwXrm",
|
||||
"||pmulddXrvm","||phminposuwXrm",nil,nil,
|
||||
nil,"||psrlvVSXrvm","||psravdXrvm","||psllvVSXrvm",
|
||||
--5x
|
||||
[0x58] = "||pbroadcastdXrlXm",[0x59] = "||pbroadcastqXrlXm",
|
||||
[0x5a] = "||broadcasti128XrlXm",
|
||||
--7x
|
||||
[0x78] = "||pbroadcastbXrlXm",[0x79] = "||pbroadcastwXrlXm",
|
||||
--8x
|
||||
[0x8c] = "||pmaskmovXrvVSm",
|
||||
[0x8e] = "||pmaskmovVSmXvr",
|
||||
--Dx
|
||||
[0xdc] = "||aesencXrvm", [0xdd] = "||aesenclastXrvm",
|
||||
[0xde] = "||aesdecXrvm", [0xdf] = "||aesdeclastXrvm",
|
||||
--Fx
|
||||
[0xf0] = "|||crc32TrBmt",[0xf1] = "|||crc32TrVmt",
|
||||
[0xf7] = "| sarxVrmv| shlxVrmv| shrxVrmv",
|
||||
},
|
||||
|
||||
["3a"] = { -- [66] 0f 3a xx
|
||||
--0x
|
||||
[0x00]=nil,nil,nil,nil,nil,nil,nil,nil,
|
||||
"||roundpsXrmu","||roundpdXrmu","||roundssXrmu","||roundsdXrmu",
|
||||
"||blendpsXrmu","||blendpdXrmu","||pblendwXrmu","palignrPrmu",
|
||||
[0x00]="||permqXrmu","||permpdXrmu","||pblenddXrvmu",nil,
|
||||
"||permilpsXrmu","||permilpdXrmu","||perm2f128Xrvmu",nil,
|
||||
"||roundpsXrmu","||roundpdXrmu","||roundssXrvmu","||roundsdXrvmu",
|
||||
"||blendpsXrvmu","||blendpdXrvmu","||pblendwXrvmu","palignrPrvmu",
|
||||
--1x
|
||||
nil,nil,nil,nil,
|
||||
"||pextrbVmXru","||pextrwVmXru","||pextrVmSXru","||extractpsVmXru",
|
||||
nil,nil,nil,nil,nil,nil,nil,nil,
|
||||
"||insertf128XrvlXmu","||extractf128XlXmYru",nil,nil,
|
||||
nil,nil,nil,nil,
|
||||
--2x
|
||||
"||pinsrbXrVmu","||insertpsXrmu","||pinsrXrVmuS",nil,
|
||||
"||pinsrbXrvVmu","||insertpsXrvmu","||pinsrXrvVmuS",nil,
|
||||
--3x
|
||||
[0x38] = "||inserti128Xrvmu",[0x39] = "||extracti128XlXmYru",
|
||||
--4x
|
||||
[0x40] = "||dppsXrmu",
|
||||
[0x41] = "||dppdXrmu",
|
||||
[0x42] = "||mpsadbwXrmu",
|
||||
[0x40] = "||dppsXrvmu",
|
||||
[0x41] = "||dppdXrvmu",
|
||||
[0x42] = "||mpsadbwXrvmu",
|
||||
[0x44] = "||pclmulqdqXrvmu",
|
||||
[0x46] = "||perm2i128Xrvmu",
|
||||
[0x4a] = "||blendvpsXrvmb",[0x4b] = "||blendvpdXrvmb",
|
||||
[0x4c] = "||pblendvbXrvmb",
|
||||
--6x
|
||||
[0x60] = "||pcmpestrmXrmu",[0x61] = "||pcmpestriXrmu",
|
||||
[0x62] = "||pcmpistrmXrmu",[0x63] = "||pcmpistriXrmu",
|
||||
[0xdf] = "||aeskeygenassistXrmu",
|
||||
--Fx
|
||||
[0xf0] = "||| rorxVrmu",
|
||||
},
|
||||
}
|
||||
|
||||
|
@ -354,17 +379,19 @@ local map_regs = {
|
|||
"mm0", "mm1", "mm2", "mm3", "mm4", "mm5", "mm6", "mm7" }, -- No x64 ext!
|
||||
X = { "xmm0", "xmm1", "xmm2", "xmm3", "xmm4", "xmm5", "xmm6", "xmm7",
|
||||
"xmm8", "xmm9", "xmm10", "xmm11", "xmm12", "xmm13", "xmm14", "xmm15" },
|
||||
Y = { "ymm0", "ymm1", "ymm2", "ymm3", "ymm4", "ymm5", "ymm6", "ymm7",
|
||||
"ymm8", "ymm9", "ymm10", "ymm11", "ymm12", "ymm13", "ymm14", "ymm15" },
|
||||
}
|
||||
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,
|
||||
B = 1, W = 2, D = 4, Q = 8, M = 8, X = 16, Y = 32,
|
||||
}
|
||||
local map_sz2prefix = {
|
||||
B = "byte", W = "word", D = "dword",
|
||||
Q = "qword",
|
||||
M = "qword", X = "xword",
|
||||
M = "qword", X = "xword", Y = "yword",
|
||||
F = "dword", G = "qword", -- No need for sizes/register names for these two.
|
||||
}
|
||||
|
||||
|
@ -387,10 +414,13 @@ local function putop(ctx, text, operands)
|
|||
if ctx.rep then text = ctx.rep.." "..text; ctx.rep = false end
|
||||
if ctx.rex then
|
||||
local t = (ctx.rexw and "w" or "")..(ctx.rexr and "r" or "")..
|
||||
(ctx.rexx and "x" or "")..(ctx.rexb and "b" or "")
|
||||
if t ~= "" then text = "rex."..t.." "..text end
|
||||
(ctx.rexx and "x" or "")..(ctx.rexb and "b" or "")..
|
||||
(ctx.vexl and "l" or "")
|
||||
if ctx.vexv and ctx.vexv ~= 0 then t = t.."v"..ctx.vexv end
|
||||
if t ~= "" then text = ctx.rex.."."..t.." "..gsub(text, "^ ", "")
|
||||
elseif ctx.rex == "vex" then text = gsub("v"..text, "^v ", "") end
|
||||
ctx.rexw = false; ctx.rexr = false; ctx.rexx = false; ctx.rexb = false
|
||||
ctx.rex = false
|
||||
ctx.rex = false; ctx.vexl = false; ctx.vexv = false
|
||||
end
|
||||
if ctx.seg then
|
||||
local text2, n = gsub(text, "%[", "["..ctx.seg..":")
|
||||
|
@ -405,6 +435,7 @@ local function putop(ctx, text, operands)
|
|||
end
|
||||
ctx.out(format("%08x %s%s\n", ctx.addr+ctx.start, hex, text))
|
||||
ctx.mrm = false
|
||||
ctx.vexv = false
|
||||
ctx.start = pos
|
||||
ctx.imm = nil
|
||||
end
|
||||
|
@ -413,7 +444,7 @@ end
|
|||
local function clearprefixes(ctx)
|
||||
ctx.o16 = false; ctx.seg = false; ctx.lock = false; ctx.rep = false
|
||||
ctx.rexw = false; ctx.rexr = false; ctx.rexx = false; ctx.rexb = false
|
||||
ctx.rex = false; ctx.a32 = false
|
||||
ctx.rex = false; ctx.a32 = false; ctx.vexl = false
|
||||
end
|
||||
|
||||
-- Fallback for incomplete opcodes at the end.
|
||||
|
@ -450,9 +481,9 @@ end
|
|||
-- Process pattern string and generate the operands.
|
||||
local function putpat(ctx, name, pat)
|
||||
local operands, regs, sz, mode, sp, rm, sc, rx, sdisp
|
||||
local code, pos, stop = ctx.code, ctx.pos, ctx.stop
|
||||
local code, pos, stop, vexl = ctx.code, ctx.pos, ctx.stop, ctx.vexl
|
||||
|
||||
-- Chars used: 1DFGIMPQRSTUVWXacdfgijmoprstuwxyz
|
||||
-- Chars used: 1DFGIMPQRSTUVWXYabcdfgijlmoprstuvwxyz
|
||||
for p in gmatch(pat, ".") do
|
||||
local x = nil
|
||||
if p == "V" or p == "U" then
|
||||
|
@ -467,11 +498,13 @@ local function putpat(ctx, name, pat)
|
|||
elseif p == "B" then
|
||||
sz = "B"
|
||||
regs = ctx.rex and map_regs.B64 or map_regs.B
|
||||
elseif match(p, "[WDQMXFG]") then
|
||||
elseif match(p, "[WDQMXYFG]") then
|
||||
sz = p
|
||||
if sz == "X" and vexl then sz = "Y"; ctx.vexl = false end
|
||||
regs = map_regs[sz]
|
||||
elseif p == "P" then
|
||||
sz = ctx.o16 and "X" or "M"; ctx.o16 = false
|
||||
if sz == "X" and vexl then sz = "Y"; ctx.vexl = false end
|
||||
regs = map_regs[sz]
|
||||
elseif p == "S" then
|
||||
name = name..lower(sz)
|
||||
|
@ -484,6 +517,10 @@ local function putpat(ctx, name, pat)
|
|||
local imm = getimm(ctx, pos, 1); if not imm then return end
|
||||
x = format("0x%02x", imm)
|
||||
pos = pos+1
|
||||
elseif p == "b" then
|
||||
local imm = getimm(ctx, pos, 1); if not imm then return end
|
||||
x = regs[imm/16+1]
|
||||
pos = pos+1
|
||||
elseif p == "w" then
|
||||
local imm = getimm(ctx, pos, 2); if not imm then return end
|
||||
x = format("0x%x", imm)
|
||||
|
@ -532,7 +569,7 @@ local function putpat(ctx, name, pat)
|
|||
local lo = imm % 0x1000000
|
||||
x = format("0x%02x%06x", (imm-lo) / 0x1000000, lo)
|
||||
else
|
||||
x = format("0x%08x", imm)
|
||||
x = "0x"..tohex(imm)
|
||||
end
|
||||
elseif p == "R" then
|
||||
local r = byte(code, pos-1, pos-1)%8
|
||||
|
@ -616,8 +653,13 @@ local function putpat(ctx, name, pat)
|
|||
else
|
||||
x = "CR"..sp
|
||||
end
|
||||
elseif p == "v" then
|
||||
if ctx.vexv then
|
||||
x = regs[ctx.vexv+1]; ctx.vexv = false
|
||||
end
|
||||
elseif p == "y" then x = "DR"..sp
|
||||
elseif p == "z" then x = "TR"..sp
|
||||
elseif p == "l" then vexl = false
|
||||
elseif p == "t" then
|
||||
else
|
||||
error("bad pattern `"..pat.."'")
|
||||
|
@ -692,7 +734,7 @@ map_act = {
|
|||
B = putpat, W = putpat, D = putpat, Q = putpat,
|
||||
V = putpat, U = putpat, T = putpat,
|
||||
M = putpat, X = putpat, P = putpat,
|
||||
F = putpat, G = putpat,
|
||||
F = putpat, G = putpat, Y = putpat,
|
||||
|
||||
-- Collect prefixes.
|
||||
[":"] = function(ctx, name, pat)
|
||||
|
@ -753,15 +795,68 @@ map_act = {
|
|||
|
||||
-- REX prefix.
|
||||
rex = function(ctx, name, pat)
|
||||
if ctx.rex then return unknown(ctx) end -- Only 1 REX prefix allowed.
|
||||
if ctx.rex then return unknown(ctx) end -- Only 1 REX or VEX prefix allowed.
|
||||
for p in gmatch(pat, ".") do ctx["rex"..p] = true end
|
||||
ctx.rex = true
|
||||
ctx.rex = "rex"
|
||||
end,
|
||||
|
||||
-- VEX prefix.
|
||||
vex = function(ctx, name, pat)
|
||||
if ctx.rex then return unknown(ctx) end -- Only 1 REX or VEX prefix allowed.
|
||||
ctx.rex = "vex"
|
||||
local pos = ctx.pos
|
||||
if ctx.mrm then
|
||||
ctx.mrm = nil
|
||||
pos = pos-1
|
||||
end
|
||||
local b = byte(ctx.code, pos, pos)
|
||||
if not b then return incomplete(ctx) end
|
||||
pos = pos+1
|
||||
if b < 128 then ctx.rexr = true end
|
||||
local m = 1
|
||||
if pat == "3" then
|
||||
m = b%32; b = (b-m)/32
|
||||
local nb = b%2; b = (b-nb)/2
|
||||
if nb == 0 then ctx.rexb = true end
|
||||
local nx = b%2
|
||||
if nx == 0 then ctx.rexx = true end
|
||||
b = byte(ctx.code, pos, pos)
|
||||
if not b then return incomplete(ctx) end
|
||||
pos = pos+1
|
||||
if b >= 128 then ctx.rexw = true end
|
||||
end
|
||||
ctx.pos = pos
|
||||
local map
|
||||
if m == 1 then map = map_opc2
|
||||
elseif m == 2 then map = map_opc3["38"]
|
||||
elseif m == 3 then map = map_opc3["3a"]
|
||||
else return unknown(ctx) end
|
||||
local p = b%4; b = (b-p)/4
|
||||
if p == 1 then ctx.o16 = "o16"
|
||||
elseif p == 2 then ctx.rep = "rep"
|
||||
elseif p == 3 then ctx.rep = "repne" end
|
||||
local l = b%2; b = (b-l)/2
|
||||
if l ~= 0 then ctx.vexl = true end
|
||||
ctx.vexv = (-1-b)%16
|
||||
return dispatchmap(ctx, map)
|
||||
end,
|
||||
|
||||
-- Special case for nop with REX prefix.
|
||||
nop = function(ctx, name, pat)
|
||||
return dispatch(ctx, ctx.rex and pat or "nop")
|
||||
end,
|
||||
|
||||
-- Special case for 0F 77.
|
||||
emms = function(ctx, name, pat)
|
||||
if ctx.rex ~= "vex" then
|
||||
return putop(ctx, "emms")
|
||||
elseif ctx.vexl then
|
||||
ctx.vexl = false
|
||||
return putop(ctx, "zeroall")
|
||||
else
|
||||
return putop(ctx, "zeroupper")
|
||||
end
|
||||
end,
|
||||
}
|
||||
|
||||
------------------------------------------------------------------------------
|
||||
|
@ -782,7 +877,7 @@ local function disass_block(ctx, ofs, len)
|
|||
end
|
||||
|
||||
-- Extended API: create a disassembler context. Then call ctx:disass(ofs, len).
|
||||
local function create_(code, addr, out)
|
||||
local function create(code, addr, out)
|
||||
local ctx = {}
|
||||
ctx.code = code
|
||||
ctx.addr = (addr or 0) - 1
|
||||
|
@ -796,8 +891,8 @@ local function create_(code, addr, out)
|
|||
return ctx
|
||||
end
|
||||
|
||||
local function create64_(code, addr, out)
|
||||
local ctx = create_(code, addr, out)
|
||||
local function create64(code, addr, out)
|
||||
local ctx = create(code, addr, out)
|
||||
ctx.x64 = true
|
||||
ctx.map1 = map_opc1_64
|
||||
ctx.aregs = map_regs.Q
|
||||
|
@ -805,32 +900,32 @@ local function create64_(code, addr, out)
|
|||
end
|
||||
|
||||
-- Simple API: disassemble code (a string) at address and output via out.
|
||||
local function disass_(code, addr, out)
|
||||
create_(code, addr, out):disass()
|
||||
local function disass(code, addr, out)
|
||||
create(code, addr, out):disass()
|
||||
end
|
||||
|
||||
local function disass64_(code, addr, out)
|
||||
create64_(code, addr, out):disass()
|
||||
local function disass64(code, addr, out)
|
||||
create64(code, addr, out):disass()
|
||||
end
|
||||
|
||||
-- Return register name for RID.
|
||||
local function regname_(r)
|
||||
local function regname(r)
|
||||
if r < 8 then return map_regs.D[r+1] end
|
||||
return map_regs.X[r-7]
|
||||
end
|
||||
|
||||
local function regname64_(r)
|
||||
local function regname64(r)
|
||||
if r < 16 then return map_regs.Q[r+1] end
|
||||
return map_regs.X[r-15]
|
||||
end
|
||||
|
||||
-- Public module functions.
|
||||
module(...)
|
||||
|
||||
create = create_
|
||||
create64 = create64_
|
||||
disass = disass_
|
||||
disass64 = disass64_
|
||||
regname = regname_
|
||||
regname64 = regname64_
|
||||
return {
|
||||
create = create,
|
||||
create64 = create64,
|
||||
disass = disass,
|
||||
disass64 = disass64,
|
||||
regname = regname,
|
||||
regname64 = regname64
|
||||
}
|
||||
|
||||
|
|
57
vendor/luajit/src/jit/dump.lua
vendored
57
vendor/luajit/src/jit/dump.lua
vendored
|
@ -1,7 +1,7 @@
|
|||
----------------------------------------------------------------------------
|
||||
-- LuaJIT compiler dump module.
|
||||
--
|
||||
-- Copyright (C) 2005-2015 Mike Pall. All rights reserved.
|
||||
-- Copyright (C) 2005-2017 Mike Pall. All rights reserved.
|
||||
-- Released under the MIT license. See Copyright Notice in luajit.h
|
||||
----------------------------------------------------------------------------
|
||||
--
|
||||
|
@ -55,7 +55,7 @@
|
|||
|
||||
-- Cache some library functions and objects.
|
||||
local jit = require("jit")
|
||||
assert(jit.version_num == 20004, "LuaJIT core/library version mismatch")
|
||||
assert(jit.version_num == 20100, "LuaJIT core/library version mismatch")
|
||||
local jutil = require("jit.util")
|
||||
local vmdef = require("jit.vmdef")
|
||||
local funcinfo, funcbc = jutil.funcinfo, jutil.funcbc
|
||||
|
@ -63,9 +63,9 @@ local traceinfo, traceir, tracek = jutil.traceinfo, jutil.traceir, jutil.tracek
|
|||
local tracemc, tracesnap = jutil.tracemc, jutil.tracesnap
|
||||
local traceexitstub, ircalladdr = jutil.traceexitstub, jutil.ircalladdr
|
||||
local bit = require("bit")
|
||||
local band, shl, shr = bit.band, bit.lshift, bit.rshift
|
||||
local band, shr, tohex = bit.band, bit.rshift, bit.tohex
|
||||
local sub, gsub, format = string.sub, string.gsub, string.format
|
||||
local byte, char, rep = string.byte, string.char, string.rep
|
||||
local byte, rep = string.byte, string.rep
|
||||
local type, tostring = type, tostring
|
||||
local stdout, stderr = io.stdout, io.stderr
|
||||
|
||||
|
@ -85,12 +85,13 @@ local nexitsym = 0
|
|||
local function fillsymtab_tr(tr, nexit)
|
||||
local t = {}
|
||||
symtabmt.__index = t
|
||||
if jit.arch == "mips" or jit.arch == "mipsel" then
|
||||
if jit.arch:sub(1, 4) == "mips" then
|
||||
t[traceexitstub(tr, 0)] = "exit"
|
||||
return
|
||||
end
|
||||
for i=0,nexit-1 do
|
||||
local addr = traceexitstub(tr, i)
|
||||
if addr < 0 then addr = addr + 2^32 end
|
||||
t[addr] = tostring(i)
|
||||
end
|
||||
local addr = traceexitstub(tr, nexit)
|
||||
|
@ -104,7 +105,10 @@ local function fillsymtab(tr, nexit)
|
|||
local ircall = vmdef.ircall
|
||||
for i=0,#ircall do
|
||||
local addr = ircalladdr(i)
|
||||
if addr ~= 0 then t[addr] = ircall[i] end
|
||||
if addr ~= 0 then
|
||||
if addr < 0 then addr = addr + 2^32 end
|
||||
t[addr] = ircall[i]
|
||||
end
|
||||
end
|
||||
end
|
||||
if nexitsym == 1000000 then -- Per-trace exit stubs.
|
||||
|
@ -118,6 +122,7 @@ local function fillsymtab(tr, nexit)
|
|||
nexit = 1000000
|
||||
break
|
||||
end
|
||||
if addr < 0 then addr = addr + 2^32 end
|
||||
t[addr] = tostring(i)
|
||||
end
|
||||
nexitsym = nexit
|
||||
|
@ -136,6 +141,7 @@ local function dump_mcode(tr)
|
|||
local mcode, addr, loop = tracemc(tr)
|
||||
if not mcode then return end
|
||||
if not disass then disass = require("jit.dis_"..jit.arch) end
|
||||
if addr < 0 then addr = addr + 2^32 end
|
||||
out:write("---- TRACE ", tr, " mcode ", #mcode, "\n")
|
||||
local ctx = disass.create(mcode, addr, dumpwrite)
|
||||
ctx.hexdump = 0
|
||||
|
@ -207,7 +213,7 @@ local colortype_ansi = {
|
|||
"\027[35m%s\027[m",
|
||||
}
|
||||
|
||||
local function colorize_text(s, t)
|
||||
local function colorize_text(s)
|
||||
return s
|
||||
end
|
||||
|
||||
|
@ -270,8 +276,7 @@ local litname = {
|
|||
["CONV "] = setmetatable({}, { __index = function(t, mode)
|
||||
local s = irtype[band(mode, 31)]
|
||||
s = irtype[band(shr(mode, 5), 31)].."."..s
|
||||
if band(mode, 0x400) ~= 0 then s = s.." trunc"
|
||||
elseif band(mode, 0x800) ~= 0 then s = s.." sext" end
|
||||
if band(mode, 0x800) ~= 0 then s = s.." sext" end
|
||||
local c = shr(mode, 14)
|
||||
if c == 2 then s = s.." index" elseif c == 3 then s = s.." check" end
|
||||
t[mode] = s
|
||||
|
@ -280,6 +285,8 @@ local litname = {
|
|||
["FLOAD "] = vmdef.irfield,
|
||||
["FREF "] = vmdef.irfield,
|
||||
["FPMATH"] = vmdef.irfpm,
|
||||
["BUFHDR"] = { [0] = "RESET", "APPEND" },
|
||||
["TOSTR "] = { [0] = "INT", "NUM", "CHAR" },
|
||||
}
|
||||
|
||||
local function ctlsub(c)
|
||||
|
@ -303,15 +310,17 @@ local function fmtfunc(func, pc)
|
|||
end
|
||||
end
|
||||
|
||||
local function formatk(tr, idx)
|
||||
local function formatk(tr, idx, sn)
|
||||
local k, t, slot = tracek(tr, idx)
|
||||
local tn = type(k)
|
||||
local s
|
||||
if tn == "number" then
|
||||
if k == 2^52+2^51 then
|
||||
if band(sn or 0, 0x30000) ~= 0 then
|
||||
s = band(sn, 0x20000) ~= 0 and "contpc" or "ftsz"
|
||||
elseif k == 2^52+2^51 then
|
||||
s = "bias"
|
||||
else
|
||||
s = format("%+.14g", k)
|
||||
s = format(0 < k and k < 0x1p-1026 and "%+a" or "%+.14g", k)
|
||||
end
|
||||
elseif tn == "string" then
|
||||
s = format(#k > 20 and '"%.20s"~' or '"%s"', gsub(k, "%c", ctlsub))
|
||||
|
@ -324,11 +333,13 @@ local function formatk(tr, idx)
|
|||
s = format("userdata:%p", k)
|
||||
else
|
||||
s = format("[%p]", k)
|
||||
if s == "[0x00000000]" then s = "NULL" end
|
||||
if s == "[NULL]" then s = "NULL" end
|
||||
end
|
||||
elseif t == 21 then -- int64_t
|
||||
s = sub(tostring(k), 1, -3)
|
||||
if sub(s, 1, 1) ~= "-" then s = "+"..s end
|
||||
elseif sn == 0x1057fff then -- SNAP(1, SNAP_FRAME | SNAP_NORESTORE, REF_NIL)
|
||||
return "----" -- Special case for LJ_FR2 slot 1.
|
||||
else
|
||||
s = tostring(k) -- For primitives.
|
||||
end
|
||||
|
@ -347,7 +358,7 @@ local function printsnap(tr, snap)
|
|||
n = n + 1
|
||||
local ref = band(sn, 0xffff) - 0x8000 -- REF_BIAS
|
||||
if ref < 0 then
|
||||
out:write(formatk(tr, ref))
|
||||
out:write(formatk(tr, ref, sn))
|
||||
elseif band(sn, 0x80000) ~= 0 then -- SNAP_SOFTFPNUM
|
||||
out:write(colorize(format("%04d/%04d", ref, ref+1), 14))
|
||||
else
|
||||
|
@ -545,7 +556,7 @@ local function dump_trace(what, tr, func, pc, otr, oex)
|
|||
if what == "start" then
|
||||
if dumpmode.H then out:write('<pre class="ljdump">\n') end
|
||||
out:write("---- TRACE ", tr, " ", what)
|
||||
if otr then out:write(" ", otr, "/", oex) end
|
||||
if otr then out:write(" ", otr, "/", oex == -1 and "stitch" or oex) end
|
||||
out:write(" ", fmtfunc(func, pc), "\n")
|
||||
elseif what == "stop" or what == "abort" then
|
||||
out:write("---- TRACE ", tr, " ", what)
|
||||
|
@ -564,6 +575,7 @@ local function dump_trace(what, tr, func, pc, otr, oex)
|
|||
end
|
||||
if dumpmode.H then out:write("</pre>\n\n") else out:write("\n") end
|
||||
else
|
||||
if what == "flush" then symtab, nexitsym = {}, 0 end
|
||||
out:write("---- TRACE ", what, "\n\n")
|
||||
end
|
||||
out:flush()
|
||||
|
@ -607,7 +619,7 @@ local function dump_texit(tr, ex, ngpr, nfpr, ...)
|
|||
end
|
||||
else
|
||||
for i=1,ngpr do
|
||||
out:write(format(" %08x", regs[i]))
|
||||
out:write(" ", tohex(regs[i]))
|
||||
if i % 8 == 0 then out:write("\n") end
|
||||
end
|
||||
end
|
||||
|
@ -643,7 +655,8 @@ end
|
|||
local function dumpon(opt, outfile)
|
||||
if active then dumpoff() end
|
||||
|
||||
local colormode = os.getenv("COLORTERM") and "A" or "T"
|
||||
local term = os.getenv("TERM")
|
||||
local colormode = (term and term:match("color") or os.getenv("COLORTERM")) and "A" or "T"
|
||||
if opt then
|
||||
opt = gsub(opt, "[TAH]", function(mode) colormode = mode; return ""; end)
|
||||
end
|
||||
|
@ -691,9 +704,9 @@ local function dumpon(opt, outfile)
|
|||
end
|
||||
|
||||
-- Public module functions.
|
||||
module(...)
|
||||
|
||||
on = dumpon
|
||||
off = dumpoff
|
||||
start = dumpon -- For -j command line option.
|
||||
return {
|
||||
on = dumpon,
|
||||
off = dumpoff,
|
||||
start = dumpon -- For -j command line option.
|
||||
}
|
||||
|
||||
|
|
311
vendor/luajit/src/jit/p.lua
vendored
Normal file
311
vendor/luajit/src/jit/p.lua
vendored
Normal file
|
@ -0,0 +1,311 @@
|
|||
----------------------------------------------------------------------------
|
||||
-- LuaJIT profiler.
|
||||
--
|
||||
-- Copyright (C) 2005-2017 Mike Pall. All rights reserved.
|
||||
-- Released under the MIT license. See Copyright Notice in luajit.h
|
||||
----------------------------------------------------------------------------
|
||||
--
|
||||
-- This module is a simple command line interface to the built-in
|
||||
-- low-overhead profiler of LuaJIT.
|
||||
--
|
||||
-- The lower-level API of the profiler is accessible via the "jit.profile"
|
||||
-- module or the luaJIT_profile_* C API.
|
||||
--
|
||||
-- Example usage:
|
||||
--
|
||||
-- luajit -jp myapp.lua
|
||||
-- luajit -jp=s myapp.lua
|
||||
-- luajit -jp=-s myapp.lua
|
||||
-- luajit -jp=vl myapp.lua
|
||||
-- luajit -jp=G,profile.txt myapp.lua
|
||||
--
|
||||
-- The following dump features are available:
|
||||
--
|
||||
-- f Stack dump: function name, otherwise module:line. Default mode.
|
||||
-- F Stack dump: ditto, but always prepend module.
|
||||
-- l Stack dump: module:line.
|
||||
-- <number> stack dump depth (callee < caller). Default: 1.
|
||||
-- -<number> Inverse stack dump depth (caller > callee).
|
||||
-- s Split stack dump after first stack level. Implies abs(depth) >= 2.
|
||||
-- p Show full path for module names.
|
||||
-- v Show VM states. Can be combined with stack dumps, e.g. vf or fv.
|
||||
-- z Show zones. Can be combined with stack dumps, e.g. zf or fz.
|
||||
-- r Show raw sample counts. Default: show percentages.
|
||||
-- a Annotate excerpts from source code files.
|
||||
-- A Annotate complete source code files.
|
||||
-- G Produce raw output suitable for graphical tools (e.g. flame graphs).
|
||||
-- m<number> Minimum sample percentage to be shown. Default: 3.
|
||||
-- i<number> Sampling interval in milliseconds. Default: 10.
|
||||
--
|
||||
----------------------------------------------------------------------------
|
||||
|
||||
-- Cache some library functions and objects.
|
||||
local jit = require("jit")
|
||||
assert(jit.version_num == 20100, "LuaJIT core/library version mismatch")
|
||||
local profile = require("jit.profile")
|
||||
local vmdef = require("jit.vmdef")
|
||||
local math = math
|
||||
local pairs, ipairs, tonumber, floor = pairs, ipairs, tonumber, math.floor
|
||||
local sort, format = table.sort, string.format
|
||||
local stdout = io.stdout
|
||||
local zone -- Load jit.zone module on demand.
|
||||
|
||||
-- Output file handle.
|
||||
local out
|
||||
|
||||
------------------------------------------------------------------------------
|
||||
|
||||
local prof_ud
|
||||
local prof_states, prof_split, prof_min, prof_raw, prof_fmt, prof_depth
|
||||
local prof_ann, prof_count1, prof_count2, prof_samples
|
||||
|
||||
local map_vmmode = {
|
||||
N = "Compiled",
|
||||
I = "Interpreted",
|
||||
C = "C code",
|
||||
G = "Garbage Collector",
|
||||
J = "JIT Compiler",
|
||||
}
|
||||
|
||||
-- Profiler callback.
|
||||
local function prof_cb(th, samples, vmmode)
|
||||
prof_samples = prof_samples + samples
|
||||
local key_stack, key_stack2, key_state
|
||||
-- Collect keys for sample.
|
||||
if prof_states then
|
||||
if prof_states == "v" then
|
||||
key_state = map_vmmode[vmmode] or vmmode
|
||||
else
|
||||
key_state = zone:get() or "(none)"
|
||||
end
|
||||
end
|
||||
if prof_fmt then
|
||||
key_stack = profile.dumpstack(th, prof_fmt, prof_depth)
|
||||
key_stack = key_stack:gsub("%[builtin#(%d+)%]", function(x)
|
||||
return vmdef.ffnames[tonumber(x)]
|
||||
end)
|
||||
if prof_split == 2 then
|
||||
local k1, k2 = key_stack:match("(.-) [<>] (.*)")
|
||||
if k2 then key_stack, key_stack2 = k1, k2 end
|
||||
elseif prof_split == 3 then
|
||||
key_stack2 = profile.dumpstack(th, "l", 1)
|
||||
end
|
||||
end
|
||||
-- Order keys.
|
||||
local k1, k2
|
||||
if prof_split == 1 then
|
||||
if key_state then
|
||||
k1 = key_state
|
||||
if key_stack then k2 = key_stack end
|
||||
end
|
||||
elseif key_stack then
|
||||
k1 = key_stack
|
||||
if key_stack2 then k2 = key_stack2 elseif key_state then k2 = key_state end
|
||||
end
|
||||
-- Coalesce samples in one or two levels.
|
||||
if k1 then
|
||||
local t1 = prof_count1
|
||||
t1[k1] = (t1[k1] or 0) + samples
|
||||
if k2 then
|
||||
local t2 = prof_count2
|
||||
local t3 = t2[k1]
|
||||
if not t3 then t3 = {}; t2[k1] = t3 end
|
||||
t3[k2] = (t3[k2] or 0) + samples
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
------------------------------------------------------------------------------
|
||||
|
||||
-- Show top N list.
|
||||
local function prof_top(count1, count2, samples, indent)
|
||||
local t, n = {}, 0
|
||||
for k in pairs(count1) do
|
||||
n = n + 1
|
||||
t[n] = k
|
||||
end
|
||||
sort(t, function(a, b) return count1[a] > count1[b] end)
|
||||
for i=1,n do
|
||||
local k = t[i]
|
||||
local v = count1[k]
|
||||
local pct = floor(v*100/samples + 0.5)
|
||||
if pct < prof_min then break end
|
||||
if not prof_raw then
|
||||
out:write(format("%s%2d%% %s\n", indent, pct, k))
|
||||
elseif prof_raw == "r" then
|
||||
out:write(format("%s%5d %s\n", indent, v, k))
|
||||
else
|
||||
out:write(format("%s %d\n", k, v))
|
||||
end
|
||||
if count2 then
|
||||
local r = count2[k]
|
||||
if r then
|
||||
prof_top(r, nil, v, (prof_split == 3 or prof_split == 1) and " -- " or
|
||||
(prof_depth < 0 and " -> " or " <- "))
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
-- Annotate source code
|
||||
local function prof_annotate(count1, samples)
|
||||
local files = {}
|
||||
local ms = 0
|
||||
for k, v in pairs(count1) do
|
||||
local pct = floor(v*100/samples + 0.5)
|
||||
ms = math.max(ms, v)
|
||||
if pct >= prof_min then
|
||||
local file, line = k:match("^(.*):(%d+)$")
|
||||
if not file then file = k; line = 0 end
|
||||
local fl = files[file]
|
||||
if not fl then fl = {}; files[file] = fl; files[#files+1] = file end
|
||||
line = tonumber(line)
|
||||
fl[line] = prof_raw and v or pct
|
||||
end
|
||||
end
|
||||
sort(files)
|
||||
local fmtv, fmtn = " %3d%% | %s\n", " | %s\n"
|
||||
if prof_raw then
|
||||
local n = math.max(5, math.ceil(math.log10(ms)))
|
||||
fmtv = "%"..n.."d | %s\n"
|
||||
fmtn = (" "):rep(n).." | %s\n"
|
||||
end
|
||||
local ann = prof_ann
|
||||
for _, file in ipairs(files) do
|
||||
local f0 = file:byte()
|
||||
if f0 == 40 or f0 == 91 then
|
||||
out:write(format("\n====== %s ======\n[Cannot annotate non-file]\n", file))
|
||||
break
|
||||
end
|
||||
local fp, err = io.open(file)
|
||||
if not fp then
|
||||
out:write(format("====== ERROR: %s: %s\n", file, err))
|
||||
break
|
||||
end
|
||||
out:write(format("\n====== %s ======\n", file))
|
||||
local fl = files[file]
|
||||
local n, show = 1, false
|
||||
if ann ~= 0 then
|
||||
for i=1,ann do
|
||||
if fl[i] then show = true; out:write("@@ 1 @@\n"); break end
|
||||
end
|
||||
end
|
||||
for line in fp:lines() do
|
||||
if line:byte() == 27 then
|
||||
out:write("[Cannot annotate bytecode file]\n")
|
||||
break
|
||||
end
|
||||
local v = fl[n]
|
||||
if ann ~= 0 then
|
||||
local v2 = fl[n+ann]
|
||||
if show then
|
||||
if v2 then show = n+ann elseif v then show = n
|
||||
elseif show+ann < n then show = false end
|
||||
elseif v2 then
|
||||
show = n+ann
|
||||
out:write(format("@@ %d @@\n", n))
|
||||
end
|
||||
if not show then goto next end
|
||||
end
|
||||
if v then
|
||||
out:write(format(fmtv, v, line))
|
||||
else
|
||||
out:write(format(fmtn, line))
|
||||
end
|
||||
::next::
|
||||
n = n + 1
|
||||
end
|
||||
fp:close()
|
||||
end
|
||||
end
|
||||
|
||||
------------------------------------------------------------------------------
|
||||
|
||||
-- Finish profiling and dump result.
|
||||
local function prof_finish()
|
||||
if prof_ud then
|
||||
profile.stop()
|
||||
local samples = prof_samples
|
||||
if samples == 0 then
|
||||
if prof_raw ~= true then out:write("[No samples collected]\n") end
|
||||
return
|
||||
end
|
||||
if prof_ann then
|
||||
prof_annotate(prof_count1, samples)
|
||||
else
|
||||
prof_top(prof_count1, prof_count2, samples, "")
|
||||
end
|
||||
prof_count1 = nil
|
||||
prof_count2 = nil
|
||||
prof_ud = nil
|
||||
end
|
||||
end
|
||||
|
||||
-- Start profiling.
|
||||
local function prof_start(mode)
|
||||
local interval = ""
|
||||
mode = mode:gsub("i%d*", function(s) interval = s; return "" end)
|
||||
prof_min = 3
|
||||
mode = mode:gsub("m(%d+)", function(s) prof_min = tonumber(s); return "" end)
|
||||
prof_depth = 1
|
||||
mode = mode:gsub("%-?%d+", function(s) prof_depth = tonumber(s); return "" end)
|
||||
local m = {}
|
||||
for c in mode:gmatch(".") do m[c] = c end
|
||||
prof_states = m.z or m.v
|
||||
if prof_states == "z" then zone = require("jit.zone") end
|
||||
local scope = m.l or m.f or m.F or (prof_states and "" or "f")
|
||||
local flags = (m.p or "")
|
||||
prof_raw = m.r
|
||||
if m.s then
|
||||
prof_split = 2
|
||||
if prof_depth == -1 or m["-"] then prof_depth = -2
|
||||
elseif prof_depth == 1 then prof_depth = 2 end
|
||||
elseif mode:find("[fF].*l") then
|
||||
scope = "l"
|
||||
prof_split = 3
|
||||
else
|
||||
prof_split = (scope == "" or mode:find("[zv].*[lfF]")) and 1 or 0
|
||||
end
|
||||
prof_ann = m.A and 0 or (m.a and 3)
|
||||
if prof_ann then
|
||||
scope = "l"
|
||||
prof_fmt = "pl"
|
||||
prof_split = 0
|
||||
prof_depth = 1
|
||||
elseif m.G and scope ~= "" then
|
||||
prof_fmt = flags..scope.."Z;"
|
||||
prof_depth = -100
|
||||
prof_raw = true
|
||||
prof_min = 0
|
||||
elseif scope == "" then
|
||||
prof_fmt = false
|
||||
else
|
||||
local sc = prof_split == 3 and m.f or m.F or scope
|
||||
prof_fmt = flags..sc..(prof_depth >= 0 and "Z < " or "Z > ")
|
||||
end
|
||||
prof_count1 = {}
|
||||
prof_count2 = {}
|
||||
prof_samples = 0
|
||||
profile.start(scope:lower()..interval, prof_cb)
|
||||
prof_ud = newproxy(true)
|
||||
getmetatable(prof_ud).__gc = prof_finish
|
||||
end
|
||||
|
||||
------------------------------------------------------------------------------
|
||||
|
||||
local function start(mode, outfile)
|
||||
if not outfile then outfile = os.getenv("LUAJIT_PROFILEFILE") end
|
||||
if outfile then
|
||||
out = outfile == "-" and stdout or assert(io.open(outfile, "w"))
|
||||
else
|
||||
out = stdout
|
||||
end
|
||||
prof_start(mode or "f")
|
||||
end
|
||||
|
||||
-- Public module functions.
|
||||
return {
|
||||
start = start, -- For -j command line option.
|
||||
stop = prof_finish
|
||||
}
|
||||
|
19
vendor/luajit/src/jit/v.lua
vendored
19
vendor/luajit/src/jit/v.lua
vendored
|
@ -1,7 +1,7 @@
|
|||
----------------------------------------------------------------------------
|
||||
-- Verbose mode of the LuaJIT compiler.
|
||||
--
|
||||
-- Copyright (C) 2005-2015 Mike Pall. All rights reserved.
|
||||
-- Copyright (C) 2005-2017 Mike Pall. All rights reserved.
|
||||
-- Released under the MIT license. See Copyright Notice in luajit.h
|
||||
----------------------------------------------------------------------------
|
||||
--
|
||||
|
@ -59,7 +59,7 @@
|
|||
|
||||
-- Cache some library functions and objects.
|
||||
local jit = require("jit")
|
||||
assert(jit.version_num == 20004, "LuaJIT core/library version mismatch")
|
||||
assert(jit.version_num == 20100, "LuaJIT core/library version mismatch")
|
||||
local jutil = require("jit.util")
|
||||
local vmdef = require("jit.vmdef")
|
||||
local funcinfo, traceinfo = jutil.funcinfo, jutil.traceinfo
|
||||
|
@ -99,7 +99,7 @@ end
|
|||
local function dump_trace(what, tr, func, pc, otr, oex)
|
||||
if what == "start" then
|
||||
startloc = fmtfunc(func, pc)
|
||||
startex = otr and "("..otr.."/"..oex..") " or ""
|
||||
startex = otr and "("..otr.."/"..(oex == -1 and "stitch" or oex)..") " or ""
|
||||
else
|
||||
if what == "abort" then
|
||||
local loc = fmtfunc(func, pc)
|
||||
|
@ -116,6 +116,9 @@ local function dump_trace(what, tr, func, pc, otr, oex)
|
|||
if ltype == "interpreter" then
|
||||
out:write(format("[TRACE %3s %s%s -- fallback to interpreter]\n",
|
||||
tr, startex, startloc))
|
||||
elseif ltype == "stitch" then
|
||||
out:write(format("[TRACE %3s %s%s %s %s]\n",
|
||||
tr, startex, startloc, ltype, fmtfunc(func, pc)))
|
||||
elseif link == tr or link == 0 then
|
||||
out:write(format("[TRACE %3s %s%s %s]\n",
|
||||
tr, startex, startloc, ltype))
|
||||
|
@ -159,9 +162,9 @@ local function dumpon(outfile)
|
|||
end
|
||||
|
||||
-- Public module functions.
|
||||
module(...)
|
||||
|
||||
on = dumpon
|
||||
off = dumpoff
|
||||
start = dumpon -- For -j command line option.
|
||||
return {
|
||||
on = dumpon,
|
||||
off = dumpoff,
|
||||
start = dumpon -- For -j command line option.
|
||||
}
|
||||
|
||||
|
|
45
vendor/luajit/src/jit/zone.lua
vendored
Normal file
45
vendor/luajit/src/jit/zone.lua
vendored
Normal file
|
@ -0,0 +1,45 @@
|
|||
----------------------------------------------------------------------------
|
||||
-- LuaJIT profiler zones.
|
||||
--
|
||||
-- Copyright (C) 2005-2017 Mike Pall. All rights reserved.
|
||||
-- Released under the MIT license. See Copyright Notice in luajit.h
|
||||
----------------------------------------------------------------------------
|
||||
--
|
||||
-- This module implements a simple hierarchical zone model.
|
||||
--
|
||||
-- Example usage:
|
||||
--
|
||||
-- local zone = require("jit.zone")
|
||||
-- zone("AI")
|
||||
-- ...
|
||||
-- zone("A*")
|
||||
-- ...
|
||||
-- print(zone:get()) --> "A*"
|
||||
-- ...
|
||||
-- zone()
|
||||
-- ...
|
||||
-- print(zone:get()) --> "AI"
|
||||
-- ...
|
||||
-- zone()
|
||||
--
|
||||
----------------------------------------------------------------------------
|
||||
|
||||
local remove = table.remove
|
||||
|
||||
return setmetatable({
|
||||
flush = function(t)
|
||||
for i=#t,1,-1 do t[i] = nil end
|
||||
end,
|
||||
get = function(t)
|
||||
return t[#t]
|
||||
end
|
||||
}, {
|
||||
__call = function(t, zone)
|
||||
if zone then
|
||||
t[#t+1] = zone
|
||||
else
|
||||
return (assert(remove(t), "empty zone stack"))
|
||||
end
|
||||
end
|
||||
})
|
||||
|
34
vendor/luajit/src/lauxlib.h
vendored
34
vendor/luajit/src/lauxlib.h
vendored
|
@ -15,9 +15,6 @@
|
|||
#include "lua.h"
|
||||
|
||||
|
||||
#define luaL_getn(L,i) ((int)lua_objlen(L, i))
|
||||
#define luaL_setn(L,i,j) ((void)0) /* no op! */
|
||||
|
||||
/* extra error code for `luaL_load' */
|
||||
#define LUA_ERRFILE (LUA_ERRERR+1)
|
||||
|
||||
|
@ -58,6 +55,10 @@ LUALIB_API int (luaL_error) (lua_State *L, const char *fmt, ...);
|
|||
LUALIB_API int (luaL_checkoption) (lua_State *L, int narg, const char *def,
|
||||
const char *const lst[]);
|
||||
|
||||
/* pre-defined references */
|
||||
#define LUA_NOREF (-2)
|
||||
#define LUA_REFNIL (-1)
|
||||
|
||||
LUALIB_API int (luaL_ref) (lua_State *L, int t);
|
||||
LUALIB_API void (luaL_unref) (lua_State *L, int t, int ref);
|
||||
|
||||
|
@ -84,6 +85,11 @@ LUALIB_API int (luaL_loadbufferx) (lua_State *L, const char *buff, size_t sz,
|
|||
const char *name, const char *mode);
|
||||
LUALIB_API void luaL_traceback (lua_State *L, lua_State *L1, const char *msg,
|
||||
int level);
|
||||
LUALIB_API void (luaL_setfuncs) (lua_State *L, const luaL_Reg *l, int nup);
|
||||
LUALIB_API void (luaL_pushmodule) (lua_State *L, const char *modname,
|
||||
int sizehint);
|
||||
LUALIB_API void *(luaL_testudata) (lua_State *L, int ud, const char *tname);
|
||||
LUALIB_API void (luaL_setmetatable) (lua_State *L, const char *tname);
|
||||
|
||||
|
||||
/*
|
||||
|
@ -113,6 +119,11 @@ LUALIB_API void luaL_traceback (lua_State *L, lua_State *L1, const char *msg,
|
|||
|
||||
#define luaL_opt(L,f,n,d) (lua_isnoneornil(L,(n)) ? (d) : f(L,(n)))
|
||||
|
||||
/* From Lua 5.2. */
|
||||
#define luaL_newlibtable(L, l) \
|
||||
lua_createtable(L, 0, sizeof(l)/sizeof((l)[0]) - 1)
|
||||
#define luaL_newlib(L, l) (luaL_newlibtable(L, l), luaL_setfuncs(L, l, 0))
|
||||
|
||||
/*
|
||||
** {======================================================
|
||||
** Generic Buffer manipulation
|
||||
|
@ -147,21 +158,4 @@ LUALIB_API void (luaL_pushresult) (luaL_Buffer *B);
|
|||
|
||||
/* }====================================================== */
|
||||
|
||||
|
||||
/* compatibility with ref system */
|
||||
|
||||
/* pre-defined references */
|
||||
#define LUA_NOREF (-2)
|
||||
#define LUA_REFNIL (-1)
|
||||
|
||||
#define lua_ref(L,lock) ((lock) ? luaL_ref(L, LUA_REGISTRYINDEX) : \
|
||||
(lua_pushstring(L, "unlocked references are obsolete"), lua_error(L), 0))
|
||||
|
||||
#define lua_unref(L,ref) luaL_unref(L, LUA_REGISTRYINDEX, (ref))
|
||||
|
||||
#define lua_getref(L,ref) lua_rawgeti(L, LUA_REGISTRYINDEX, (ref))
|
||||
|
||||
|
||||
#define luaL_reg luaL_Reg
|
||||
|
||||
#endif
|
||||
|
|
65
vendor/luajit/src/lib_aux.c
vendored
65
vendor/luajit/src/lib_aux.c
vendored
|
@ -1,6 +1,6 @@
|
|||
/*
|
||||
** Auxiliary library for the Lua/C API.
|
||||
** Copyright (C) 2005-2015 Mike Pall. See Copyright Notice in luajit.h
|
||||
** Copyright (C) 2005-2017 Mike Pall. See Copyright Notice in luajit.h
|
||||
**
|
||||
** Major parts taken verbatim or adapted from the Lua interpreter.
|
||||
** Copyright (C) 1994-2008 Lua.org, PUC-Rio. See Copyright Notice in lua.h
|
||||
|
@ -107,38 +107,36 @@ LUALIB_API const char *luaL_findtable(lua_State *L, int idx,
|
|||
static int libsize(const luaL_Reg *l)
|
||||
{
|
||||
int size = 0;
|
||||
for (; l->name; l++) size++;
|
||||
for (; l && l->name; l++) size++;
|
||||
return size;
|
||||
}
|
||||
|
||||
LUALIB_API void luaL_pushmodule(lua_State *L, const char *modname, int sizehint)
|
||||
{
|
||||
luaL_findtable(L, LUA_REGISTRYINDEX, "_LOADED", 16);
|
||||
lua_getfield(L, -1, modname);
|
||||
if (!lua_istable(L, -1)) {
|
||||
lua_pop(L, 1);
|
||||
if (luaL_findtable(L, LUA_GLOBALSINDEX, modname, sizehint) != NULL)
|
||||
lj_err_callerv(L, LJ_ERR_BADMODN, modname);
|
||||
lua_pushvalue(L, -1);
|
||||
lua_setfield(L, -3, modname); /* _LOADED[modname] = new table. */
|
||||
}
|
||||
lua_remove(L, -2); /* Remove _LOADED table. */
|
||||
}
|
||||
|
||||
LUALIB_API void luaL_openlib(lua_State *L, const char *libname,
|
||||
const luaL_Reg *l, int nup)
|
||||
{
|
||||
lj_lib_checkfpu(L);
|
||||
if (libname) {
|
||||
int size = libsize(l);
|
||||
/* check whether lib already exists */
|
||||
luaL_findtable(L, LUA_REGISTRYINDEX, "_LOADED", 16);
|
||||
lua_getfield(L, -1, libname); /* get _LOADED[libname] */
|
||||
if (!lua_istable(L, -1)) { /* not found? */
|
||||
lua_pop(L, 1); /* remove previous result */
|
||||
/* try global variable (and create one if it does not exist) */
|
||||
if (luaL_findtable(L, LUA_GLOBALSINDEX, libname, size) != NULL)
|
||||
lj_err_callerv(L, LJ_ERR_BADMODN, libname);
|
||||
lua_pushvalue(L, -1);
|
||||
lua_setfield(L, -3, libname); /* _LOADED[libname] = new table */
|
||||
}
|
||||
lua_remove(L, -2); /* remove _LOADED table */
|
||||
lua_insert(L, -(nup+1)); /* move library table to below upvalues */
|
||||
luaL_pushmodule(L, libname, libsize(l));
|
||||
lua_insert(L, -(nup + 1)); /* Move module table below upvalues. */
|
||||
}
|
||||
for (; l->name; l++) {
|
||||
int i;
|
||||
for (i = 0; i < nup; i++) /* copy upvalues to the top */
|
||||
lua_pushvalue(L, -nup);
|
||||
lua_pushcclosure(L, l->func, nup);
|
||||
lua_setfield(L, -(nup+2), l->name);
|
||||
}
|
||||
lua_pop(L, nup); /* remove upvalues */
|
||||
if (l)
|
||||
luaL_setfuncs(L, l, nup);
|
||||
else
|
||||
lua_pop(L, nup); /* Remove upvalues. */
|
||||
}
|
||||
|
||||
LUALIB_API void luaL_register(lua_State *L, const char *libname,
|
||||
|
@ -147,6 +145,19 @@ LUALIB_API void luaL_register(lua_State *L, const char *libname,
|
|||
luaL_openlib(L, libname, l, 0);
|
||||
}
|
||||
|
||||
LUALIB_API void luaL_setfuncs(lua_State *L, const luaL_Reg *l, int nup)
|
||||
{
|
||||
luaL_checkstack(L, nup, "too many upvalues");
|
||||
for (; l->name; l++) {
|
||||
int i;
|
||||
for (i = 0; i < nup; i++) /* Copy upvalues to the top. */
|
||||
lua_pushvalue(L, -nup);
|
||||
lua_pushcclosure(L, l->func, nup);
|
||||
lua_setfield(L, -(nup + 2), l->name);
|
||||
}
|
||||
lua_pop(L, nup); /* Remove upvalues. */
|
||||
}
|
||||
|
||||
LUALIB_API const char *luaL_gsub(lua_State *L, const char *s,
|
||||
const char *p, const char *r)
|
||||
{
|
||||
|
@ -302,7 +313,7 @@ static int panic(lua_State *L)
|
|||
|
||||
#ifdef LUAJIT_USE_SYSMALLOC
|
||||
|
||||
#if LJ_64 && !defined(LUAJIT_USE_VALGRIND)
|
||||
#if LJ_64 && !LJ_GC64 && !defined(LUAJIT_USE_VALGRIND)
|
||||
#error "Must use builtin allocator for 64 bit target"
|
||||
#endif
|
||||
|
||||
|
@ -334,7 +345,7 @@ LUALIB_API lua_State *luaL_newstate(void)
|
|||
lua_State *L;
|
||||
void *ud = lj_alloc_create();
|
||||
if (ud == NULL) return NULL;
|
||||
#if LJ_64
|
||||
#if LJ_64 && !LJ_GC64
|
||||
L = lj_state_newstate(lj_alloc_f, ud);
|
||||
#else
|
||||
L = lua_newstate(lj_alloc_f, ud);
|
||||
|
@ -343,7 +354,7 @@ LUALIB_API lua_State *luaL_newstate(void)
|
|||
return L;
|
||||
}
|
||||
|
||||
#if LJ_64
|
||||
#if LJ_64 && !LJ_GC64
|
||||
LUA_API lua_State *lua_newstate(lua_Alloc f, void *ud)
|
||||
{
|
||||
UNUSED(f); UNUSED(ud);
|
||||
|
|
101
vendor/luajit/src/lib_base.c
vendored
101
vendor/luajit/src/lib_base.c
vendored
|
@ -1,6 +1,6 @@
|
|||
/*
|
||||
** Base and coroutine library.
|
||||
** Copyright (C) 2005-2015 Mike Pall. See Copyright Notice in luajit.h
|
||||
** Copyright (C) 2005-2017 Mike Pall. See Copyright Notice in luajit.h
|
||||
**
|
||||
** Major portions taken verbatim or adapted from the Lua interpreter.
|
||||
** Copyright (C) 1994-2011 Lua.org, PUC-Rio. See Copyright Notice in lua.h
|
||||
|
@ -23,6 +23,7 @@
|
|||
#include "lj_tab.h"
|
||||
#include "lj_meta.h"
|
||||
#include "lj_state.h"
|
||||
#include "lj_frame.h"
|
||||
#if LJ_HASFFI
|
||||
#include "lj_ctype.h"
|
||||
#include "lj_cconv.h"
|
||||
|
@ -32,6 +33,7 @@
|
|||
#include "lj_dispatch.h"
|
||||
#include "lj_char.h"
|
||||
#include "lj_strscan.h"
|
||||
#include "lj_strfmt.h"
|
||||
#include "lj_lib.h"
|
||||
|
||||
/* -- Base library: checks ------------------------------------------------ */
|
||||
|
@ -86,10 +88,11 @@ static int ffh_pairs(lua_State *L, MMS mm)
|
|||
cTValue *mo = lj_meta_lookup(L, o, mm);
|
||||
if ((LJ_52 || tviscdata(o)) && !tvisnil(mo)) {
|
||||
L->top = o+1; /* Only keep one argument. */
|
||||
copyTV(L, L->base-1, mo); /* Replace callable. */
|
||||
copyTV(L, L->base-1-LJ_FR2, mo); /* Replace callable. */
|
||||
return FFH_TAILCALL;
|
||||
} else {
|
||||
if (!tvistab(o)) lj_err_argt(L, 1, LUA_TTABLE);
|
||||
if (LJ_FR2) { copyTV(L, o-1, o); o--; }
|
||||
setfuncV(L, o-1, funcV(lj_lib_upvalue(L, 1)));
|
||||
if (mm == MM_pairs) setnilV(o+1); else setintV(o+1, 0);
|
||||
return FFH_RES(3);
|
||||
|
@ -100,7 +103,7 @@ static int ffh_pairs(lua_State *L, MMS mm)
|
|||
#endif
|
||||
|
||||
LJLIB_PUSH(lastcl)
|
||||
LJLIB_ASM(pairs)
|
||||
LJLIB_ASM(pairs) LJLIB_REC(xpairs 0)
|
||||
{
|
||||
return ffh_pairs(L, MM_pairs);
|
||||
}
|
||||
|
@ -113,7 +116,7 @@ LJLIB_NOREGUV LJLIB_ASM(ipairs_aux) LJLIB_REC(.)
|
|||
}
|
||||
|
||||
LJLIB_PUSH(lastcl)
|
||||
LJLIB_ASM(ipairs) LJLIB_REC(.)
|
||||
LJLIB_ASM(ipairs) LJLIB_REC(xpairs 1)
|
||||
{
|
||||
return ffh_pairs(L, MM_ipairs);
|
||||
}
|
||||
|
@ -131,11 +134,11 @@ LJLIB_ASM(setmetatable) LJLIB_REC(.)
|
|||
lj_err_caller(L, LJ_ERR_PROTMT);
|
||||
setgcref(t->metatable, obj2gco(mt));
|
||||
if (mt) { lj_gc_objbarriert(L, t, mt); }
|
||||
settabV(L, L->base-1, t);
|
||||
settabV(L, L->base-1-LJ_FR2, t);
|
||||
return FFH_RES(1);
|
||||
}
|
||||
|
||||
LJLIB_CF(getfenv)
|
||||
LJLIB_CF(getfenv) LJLIB_REC(.)
|
||||
{
|
||||
GCfunc *fn;
|
||||
cTValue *o = L->base;
|
||||
|
@ -144,6 +147,7 @@ LJLIB_CF(getfenv)
|
|||
o = lj_debug_frame(L, level, &level);
|
||||
if (o == NULL)
|
||||
lj_err_arg(L, 1, LJ_ERR_INVLVL);
|
||||
if (LJ_FR2) o--;
|
||||
}
|
||||
fn = &gcval(o)->fn;
|
||||
settabV(L, L->top++, isluafunc(fn) ? tabref(fn->l.env) : tabref(L->env));
|
||||
|
@ -165,6 +169,7 @@ LJLIB_CF(setfenv)
|
|||
o = lj_debug_frame(L, level, &level);
|
||||
if (o == NULL)
|
||||
lj_err_arg(L, 1, LJ_ERR_INVLVL);
|
||||
if (LJ_FR2) o--;
|
||||
}
|
||||
fn = &gcval(o)->fn;
|
||||
if (!isluafunc(fn))
|
||||
|
@ -257,7 +262,7 @@ LJLIB_ASM(tonumber) LJLIB_REC(.)
|
|||
if (base == 10) {
|
||||
TValue *o = lj_lib_checkany(L, 1);
|
||||
if (lj_strscan_numberobj(o)) {
|
||||
copyTV(L, L->base-1, o);
|
||||
copyTV(L, L->base-1-LJ_FR2, o);
|
||||
return FFH_RES(1);
|
||||
}
|
||||
#if LJ_HASFFI
|
||||
|
@ -270,11 +275,11 @@ LJLIB_ASM(tonumber) LJLIB_REC(.)
|
|||
ct->size <= 4 && !(ct->size == 4 && (ct->info & CTF_UNSIGNED))) {
|
||||
int32_t i;
|
||||
lj_cconv_ct_tv(cts, ctype_get(cts, CTID_INT32), (uint8_t *)&i, o, 0);
|
||||
setintV(L->base-1, i);
|
||||
setintV(L->base-1-LJ_FR2, i);
|
||||
return FFH_RES(1);
|
||||
}
|
||||
lj_cconv_ct_tv(cts, ctype_get(cts, CTID_DOUBLE),
|
||||
(uint8_t *)&(L->base-1)->n, o, 0);
|
||||
(uint8_t *)&(L->base-1-LJ_FR2)->n, o, 0);
|
||||
return FFH_RES(1);
|
||||
}
|
||||
}
|
||||
|
@ -290,45 +295,29 @@ LJLIB_ASM(tonumber) LJLIB_REC(.)
|
|||
while (lj_char_isspace((unsigned char)(*ep))) ep++;
|
||||
if (*ep == '\0') {
|
||||
if (LJ_DUALNUM && LJ_LIKELY(ul < 0x80000000u))
|
||||
setintV(L->base-1, (int32_t)ul);
|
||||
setintV(L->base-1-LJ_FR2, (int32_t)ul);
|
||||
else
|
||||
setnumV(L->base-1, (lua_Number)ul);
|
||||
setnumV(L->base-1-LJ_FR2, (lua_Number)ul);
|
||||
return FFH_RES(1);
|
||||
}
|
||||
}
|
||||
}
|
||||
setnilV(L->base-1);
|
||||
setnilV(L->base-1-LJ_FR2);
|
||||
return FFH_RES(1);
|
||||
}
|
||||
|
||||
LJLIB_PUSH("nil")
|
||||
LJLIB_PUSH("false")
|
||||
LJLIB_PUSH("true")
|
||||
LJLIB_ASM(tostring) LJLIB_REC(.)
|
||||
{
|
||||
TValue *o = lj_lib_checkany(L, 1);
|
||||
cTValue *mo;
|
||||
L->top = o+1; /* Only keep one argument. */
|
||||
if (!tvisnil(mo = lj_meta_lookup(L, o, MM_tostring))) {
|
||||
copyTV(L, L->base-1, mo); /* Replace callable. */
|
||||
copyTV(L, L->base-1-LJ_FR2, mo); /* Replace callable. */
|
||||
return FFH_TAILCALL;
|
||||
} else {
|
||||
GCstr *s;
|
||||
if (tvisnumber(o)) {
|
||||
s = lj_str_fromnumber(L, o);
|
||||
} else if (tvispri(o)) {
|
||||
s = strV(lj_lib_upvalue(L, -(int32_t)itype(o)));
|
||||
} else {
|
||||
if (tvisfunc(o) && isffunc(funcV(o)))
|
||||
lua_pushfstring(L, "function: builtin#%d", funcV(o)->c.ffid);
|
||||
else
|
||||
lua_pushfstring(L, "%s: %p", lj_typename(o), lua_topointer(L, 1));
|
||||
/* Note: lua_pushfstring calls the GC which may invalidate o. */
|
||||
s = strV(L->top-1);
|
||||
}
|
||||
setstrV(L, L->base-1, s);
|
||||
return FFH_RES(1);
|
||||
}
|
||||
lj_gc_check(L);
|
||||
setstrV(L, L->base-1-LJ_FR2, lj_strfmt_obj(L, L->base));
|
||||
return FFH_RES(1);
|
||||
}
|
||||
|
||||
/* -- Base library: throw and catch errors -------------------------------- */
|
||||
|
@ -357,7 +346,7 @@ LJLIB_ASM_(xpcall) LJLIB_REC(.)
|
|||
|
||||
static int load_aux(lua_State *L, int status, int envarg)
|
||||
{
|
||||
if (status == 0) {
|
||||
if (status == LUA_OK) {
|
||||
if (tvistab(L->base+envarg-1)) {
|
||||
GCfunc *fn = funcV(L->top-1);
|
||||
GCtab *t = tabV(L->base+envarg-1);
|
||||
|
@ -430,7 +419,7 @@ LJLIB_CF(dofile)
|
|||
GCstr *fname = lj_lib_optstr(L, 1);
|
||||
setnilV(L->top);
|
||||
L->top = L->base+1;
|
||||
if (luaL_loadfile(L, fname ? strdata(fname) : NULL) != 0)
|
||||
if (luaL_loadfile(L, fname ? strdata(fname) : NULL) != LUA_OK)
|
||||
lua_error(L);
|
||||
lua_call(L, 0, LUA_MULTRET);
|
||||
return (int)(L->top - L->base) - 1;
|
||||
|
@ -440,20 +429,20 @@ LJLIB_CF(dofile)
|
|||
|
||||
LJLIB_CF(gcinfo)
|
||||
{
|
||||
setintV(L->top++, (G(L)->gc.total >> 10));
|
||||
setintV(L->top++, (int32_t)(G(L)->gc.total >> 10));
|
||||
return 1;
|
||||
}
|
||||
|
||||
LJLIB_CF(collectgarbage)
|
||||
{
|
||||
int opt = lj_lib_checkopt(L, 1, LUA_GCCOLLECT, /* ORDER LUA_GC* */
|
||||
"\4stop\7restart\7collect\5count\1\377\4step\10setpause\12setstepmul");
|
||||
"\4stop\7restart\7collect\5count\1\377\4step\10setpause\12setstepmul\1\377\11isrunning");
|
||||
int32_t data = lj_lib_optint(L, 2, 0);
|
||||
if (opt == LUA_GCCOUNT) {
|
||||
setnumV(L->top, (lua_Number)G(L)->gc.total/1024.0);
|
||||
} else {
|
||||
int res = lua_gc(L, opt, data);
|
||||
if (opt == LUA_GCSTEP)
|
||||
if (opt == LUA_GCSTEP || opt == LUA_GCISRUNNING)
|
||||
setboolV(L->top, res);
|
||||
else
|
||||
setintV(L->top, res);
|
||||
|
@ -506,21 +495,12 @@ LJLIB_CF(print)
|
|||
}
|
||||
shortcut = (tvisfunc(tv) && funcV(tv)->c.ffid == FF_tostring);
|
||||
for (i = 0; i < nargs; i++) {
|
||||
cTValue *o = &L->base[i];
|
||||
const char *str;
|
||||
size_t size;
|
||||
cTValue *o = &L->base[i];
|
||||
if (shortcut && tvisstr(o)) {
|
||||
str = strVdata(o);
|
||||
size = strV(o)->len;
|
||||
} else if (shortcut && tvisint(o)) {
|
||||
char buf[LJ_STR_INTBUF];
|
||||
char *p = lj_str_bufint(buf, intV(o));
|
||||
size = (size_t)(buf+LJ_STR_INTBUF-p);
|
||||
str = p;
|
||||
} else if (shortcut && tvisnum(o)) {
|
||||
char buf[LJ_STR_NUMBUF];
|
||||
size = lj_str_bufnum(buf, o);
|
||||
str = buf;
|
||||
MSize len;
|
||||
if (shortcut && (str = lj_strfmt_wstrnum(L, o, &len)) != NULL) {
|
||||
size = len;
|
||||
} else {
|
||||
copyTV(L, L->top+1, o);
|
||||
copyTV(L, L->top, L->top-1);
|
||||
|
@ -557,8 +537,8 @@ LJLIB_CF(coroutine_status)
|
|||
co = threadV(L->base);
|
||||
if (co == L) s = "running";
|
||||
else if (co->status == LUA_YIELD) s = "suspended";
|
||||
else if (co->status != 0) s = "dead";
|
||||
else if (co->base > tvref(co->stack)+1) s = "normal";
|
||||
else if (co->status != LUA_OK) s = "dead";
|
||||
else if (co->base > tvref(co->stack)+1+LJ_FR2) s = "normal";
|
||||
else if (co->top == co->base) s = "dead";
|
||||
else s = "suspended";
|
||||
lua_pushstring(L, s);
|
||||
|
@ -578,6 +558,12 @@ LJLIB_CF(coroutine_running)
|
|||
#endif
|
||||
}
|
||||
|
||||
LJLIB_CF(coroutine_isyieldable)
|
||||
{
|
||||
setboolV(L->top++, cframe_canyield(L->cframe));
|
||||
return 1;
|
||||
}
|
||||
|
||||
LJLIB_CF(coroutine_create)
|
||||
{
|
||||
lua_State *L1;
|
||||
|
@ -597,11 +583,11 @@ LJLIB_ASM(coroutine_yield)
|
|||
static int ffh_resume(lua_State *L, lua_State *co, int wrap)
|
||||
{
|
||||
if (co->cframe != NULL || co->status > LUA_YIELD ||
|
||||
(co->status == 0 && co->top == co->base)) {
|
||||
(co->status == LUA_OK && co->top == co->base)) {
|
||||
ErrMsg em = co->cframe ? LJ_ERR_CORUN : LJ_ERR_CODEAD;
|
||||
if (wrap) lj_err_caller(L, em);
|
||||
setboolV(L->base-1, 0);
|
||||
setstrV(L, L->base, lj_err_str(L, em));
|
||||
setboolV(L->base-1-LJ_FR2, 0);
|
||||
setstrV(L, L->base-LJ_FR2, lj_err_str(L, em));
|
||||
return FFH_RES(2);
|
||||
}
|
||||
lj_state_growstack(co, (MSize)(L->top - L->base));
|
||||
|
@ -642,9 +628,10 @@ static void setpc_wrap_aux(lua_State *L, GCfunc *fn);
|
|||
|
||||
LJLIB_CF(coroutine_wrap)
|
||||
{
|
||||
GCfunc *fn;
|
||||
lj_cf_coroutine_create(L);
|
||||
lj_lib_pushcc(L, lj_ffh_coroutine_wrap_aux, FF_coroutine_wrap_aux, 1);
|
||||
setpc_wrap_aux(L, funcV(L->top-1));
|
||||
fn = lj_lib_pushcc(L, lj_ffh_coroutine_wrap_aux, FF_coroutine_wrap_aux, 1);
|
||||
setpc_wrap_aux(L, fn);
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
|
138
vendor/luajit/src/lib_bit.c
vendored
138
vendor/luajit/src/lib_bit.c
vendored
|
@ -1,6 +1,6 @@
|
|||
/*
|
||||
** Bit manipulation library.
|
||||
** Copyright (C) 2005-2015 Mike Pall. See Copyright Notice in luajit.h
|
||||
** Copyright (C) 2005-2017 Mike Pall. See Copyright Notice in luajit.h
|
||||
*/
|
||||
|
||||
#define lib_bit_c
|
||||
|
@ -12,26 +12,99 @@
|
|||
|
||||
#include "lj_obj.h"
|
||||
#include "lj_err.h"
|
||||
#include "lj_str.h"
|
||||
#include "lj_buf.h"
|
||||
#include "lj_strscan.h"
|
||||
#include "lj_strfmt.h"
|
||||
#if LJ_HASFFI
|
||||
#include "lj_ctype.h"
|
||||
#include "lj_cdata.h"
|
||||
#include "lj_cconv.h"
|
||||
#include "lj_carith.h"
|
||||
#endif
|
||||
#include "lj_ff.h"
|
||||
#include "lj_lib.h"
|
||||
|
||||
/* ------------------------------------------------------------------------ */
|
||||
|
||||
#define LJLIB_MODULE_bit
|
||||
|
||||
LJLIB_ASM(bit_tobit) LJLIB_REC(bit_unary IR_TOBIT)
|
||||
#if LJ_HASFFI
|
||||
static int bit_result64(lua_State *L, CTypeID id, uint64_t x)
|
||||
{
|
||||
GCcdata *cd = lj_cdata_new_(L, id, 8);
|
||||
*(uint64_t *)cdataptr(cd) = x;
|
||||
setcdataV(L, L->base-1-LJ_FR2, cd);
|
||||
return FFH_RES(1);
|
||||
}
|
||||
#else
|
||||
static int32_t bit_checkbit(lua_State *L, int narg)
|
||||
{
|
||||
TValue *o = L->base + narg-1;
|
||||
if (!(o < L->top && lj_strscan_numberobj(o)))
|
||||
lj_err_argt(L, narg, LUA_TNUMBER);
|
||||
if (LJ_LIKELY(tvisint(o))) {
|
||||
return intV(o);
|
||||
} else {
|
||||
int32_t i = lj_num2bit(numV(o));
|
||||
if (LJ_DUALNUM) setintV(o, i);
|
||||
return i;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
LJLIB_ASM(bit_tobit) LJLIB_REC(bit_tobit)
|
||||
{
|
||||
#if LJ_HASFFI
|
||||
CTypeID id = 0;
|
||||
setintV(L->base-1-LJ_FR2, (int32_t)lj_carith_check64(L, 1, &id));
|
||||
return FFH_RES(1);
|
||||
#else
|
||||
lj_lib_checknumber(L, 1);
|
||||
return FFH_RETRY;
|
||||
#endif
|
||||
}
|
||||
|
||||
LJLIB_ASM(bit_bnot) LJLIB_REC(bit_unary IR_BNOT)
|
||||
{
|
||||
#if LJ_HASFFI
|
||||
CTypeID id = 0;
|
||||
uint64_t x = lj_carith_check64(L, 1, &id);
|
||||
return id ? bit_result64(L, id, ~x) : FFH_RETRY;
|
||||
#else
|
||||
lj_lib_checknumber(L, 1);
|
||||
return FFH_RETRY;
|
||||
#endif
|
||||
}
|
||||
|
||||
LJLIB_ASM(bit_bswap) LJLIB_REC(bit_unary IR_BSWAP)
|
||||
{
|
||||
#if LJ_HASFFI
|
||||
CTypeID id = 0;
|
||||
uint64_t x = lj_carith_check64(L, 1, &id);
|
||||
return id ? bit_result64(L, id, lj_bswap64(x)) : FFH_RETRY;
|
||||
#else
|
||||
lj_lib_checknumber(L, 1);
|
||||
return FFH_RETRY;
|
||||
#endif
|
||||
}
|
||||
LJLIB_ASM_(bit_bnot) LJLIB_REC(bit_unary IR_BNOT)
|
||||
LJLIB_ASM_(bit_bswap) LJLIB_REC(bit_unary IR_BSWAP)
|
||||
|
||||
LJLIB_ASM(bit_lshift) LJLIB_REC(bit_shift IR_BSHL)
|
||||
{
|
||||
lj_lib_checknumber(L, 1);
|
||||
lj_lib_checkbit(L, 2);
|
||||
#if LJ_HASFFI
|
||||
CTypeID id = 0, id2 = 0;
|
||||
uint64_t x = lj_carith_check64(L, 1, &id);
|
||||
int32_t sh = (int32_t)lj_carith_check64(L, 2, &id2);
|
||||
if (id) {
|
||||
x = lj_carith_shift64(x, sh, curr_func(L)->c.ffid - (int)FF_bit_lshift);
|
||||
return bit_result64(L, id, x);
|
||||
}
|
||||
if (id2) setintV(L->base+1, sh);
|
||||
return FFH_RETRY;
|
||||
#else
|
||||
lj_lib_checknumber(L, 1);
|
||||
bit_checkbit(L, 2);
|
||||
return FFH_RETRY;
|
||||
#endif
|
||||
}
|
||||
LJLIB_ASM_(bit_rshift) LJLIB_REC(bit_shift IR_BSHR)
|
||||
LJLIB_ASM_(bit_arshift) LJLIB_REC(bit_shift IR_BSAR)
|
||||
|
@ -40,25 +113,58 @@ LJLIB_ASM_(bit_ror) LJLIB_REC(bit_shift IR_BROR)
|
|||
|
||||
LJLIB_ASM(bit_band) LJLIB_REC(bit_nary IR_BAND)
|
||||
{
|
||||
#if LJ_HASFFI
|
||||
CTypeID id = 0;
|
||||
TValue *o = L->base, *top = L->top;
|
||||
int i = 0;
|
||||
do { lj_carith_check64(L, ++i, &id); } while (++o < top);
|
||||
if (id) {
|
||||
CTState *cts = ctype_cts(L);
|
||||
CType *ct = ctype_get(cts, id);
|
||||
int op = curr_func(L)->c.ffid - (int)FF_bit_bor;
|
||||
uint64_t x, y = op >= 0 ? 0 : ~(uint64_t)0;
|
||||
o = L->base;
|
||||
do {
|
||||
lj_cconv_ct_tv(cts, ct, (uint8_t *)&x, o, 0);
|
||||
if (op < 0) y &= x; else if (op == 0) y |= x; else y ^= x;
|
||||
} while (++o < top);
|
||||
return bit_result64(L, id, y);
|
||||
}
|
||||
return FFH_RETRY;
|
||||
#else
|
||||
int i = 0;
|
||||
do { lj_lib_checknumber(L, ++i); } while (L->base+i < L->top);
|
||||
return FFH_RETRY;
|
||||
#endif
|
||||
}
|
||||
LJLIB_ASM_(bit_bor) LJLIB_REC(bit_nary IR_BOR)
|
||||
LJLIB_ASM_(bit_bxor) LJLIB_REC(bit_nary IR_BXOR)
|
||||
|
||||
/* ------------------------------------------------------------------------ */
|
||||
|
||||
LJLIB_CF(bit_tohex)
|
||||
LJLIB_CF(bit_tohex) LJLIB_REC(.)
|
||||
{
|
||||
uint32_t b = (uint32_t)lj_lib_checkbit(L, 1);
|
||||
int32_t i, n = L->base+1 >= L->top ? 8 : lj_lib_checkbit(L, 2);
|
||||
const char *hexdigits = "0123456789abcdef";
|
||||
char buf[8];
|
||||
if (n < 0) { n = -n; hexdigits = "0123456789ABCDEF"; }
|
||||
if (n > 8) n = 8;
|
||||
for (i = n; --i >= 0; ) { buf[i] = hexdigits[b & 15]; b >>= 4; }
|
||||
lua_pushlstring(L, buf, (size_t)n);
|
||||
#if LJ_HASFFI
|
||||
CTypeID id = 0, id2 = 0;
|
||||
uint64_t b = lj_carith_check64(L, 1, &id);
|
||||
int32_t n = L->base+1>=L->top ? (id ? 16 : 8) :
|
||||
(int32_t)lj_carith_check64(L, 2, &id2);
|
||||
#else
|
||||
uint32_t b = (uint32_t)bit_checkbit(L, 1);
|
||||
int32_t n = L->base+1>=L->top ? 8 : bit_checkbit(L, 2);
|
||||
#endif
|
||||
SBuf *sb = lj_buf_tmp_(L);
|
||||
SFormat sf = (STRFMT_UINT|STRFMT_T_HEX);
|
||||
if (n < 0) { n = -n; sf |= STRFMT_F_UPPER; }
|
||||
sf |= ((SFormat)((n+1)&255) << STRFMT_SH_PREC);
|
||||
#if LJ_HASFFI
|
||||
if (n < 16) b &= ((uint64_t)1 << 4*n)-1;
|
||||
#else
|
||||
if (n < 8) b &= (1u << 4*n)-1;
|
||||
#endif
|
||||
sb = lj_strfmt_putfxint(sb, sf, b);
|
||||
setstrV(L, L->top-1, lj_buf_str(L, sb));
|
||||
lj_gc_check(L);
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
|
12
vendor/luajit/src/lib_debug.c
vendored
12
vendor/luajit/src/lib_debug.c
vendored
|
@ -1,6 +1,6 @@
|
|||
/*
|
||||
** Debug library.
|
||||
** Copyright (C) 2005-2015 Mike Pall. See Copyright Notice in luajit.h
|
||||
** Copyright (C) 2005-2017 Mike Pall. See Copyright Notice in luajit.h
|
||||
**
|
||||
** Major portions taken verbatim or adapted from the Lua interpreter.
|
||||
** Copyright (C) 1994-2008 Lua.org, PUC-Rio. See Copyright Notice in lua.h
|
||||
|
@ -29,7 +29,7 @@ LJLIB_CF(debug_getregistry)
|
|||
return 1;
|
||||
}
|
||||
|
||||
LJLIB_CF(debug_getmetatable)
|
||||
LJLIB_CF(debug_getmetatable) LJLIB_REC(.)
|
||||
{
|
||||
lj_lib_checkany(L, 1);
|
||||
if (!lua_getmetatable(L, 1)) {
|
||||
|
@ -283,13 +283,13 @@ LJLIB_CF(debug_setuservalue)
|
|||
|
||||
/* ------------------------------------------------------------------------ */
|
||||
|
||||
static const char KEY_HOOK = 'h';
|
||||
#define KEY_HOOK ((void *)0x3004)
|
||||
|
||||
static void hookf(lua_State *L, lua_Debug *ar)
|
||||
{
|
||||
static const char *const hooknames[] =
|
||||
{"call", "return", "line", "count", "tail return"};
|
||||
lua_pushlightuserdata(L, (void *)&KEY_HOOK);
|
||||
lua_pushlightuserdata(L, KEY_HOOK);
|
||||
lua_rawget(L, LUA_REGISTRYINDEX);
|
||||
if (lua_isfunction(L, -1)) {
|
||||
lua_pushstring(L, hooknames[(int)ar->event]);
|
||||
|
@ -334,7 +334,7 @@ LJLIB_CF(debug_sethook)
|
|||
count = luaL_optint(L, arg+3, 0);
|
||||
func = hookf; mask = makemask(smask, count);
|
||||
}
|
||||
lua_pushlightuserdata(L, (void *)&KEY_HOOK);
|
||||
lua_pushlightuserdata(L, KEY_HOOK);
|
||||
lua_pushvalue(L, arg+1);
|
||||
lua_rawset(L, LUA_REGISTRYINDEX);
|
||||
lua_sethook(L, func, mask, count);
|
||||
|
@ -349,7 +349,7 @@ LJLIB_CF(debug_gethook)
|
|||
if (hook != NULL && hook != hookf) { /* external hook? */
|
||||
lua_pushliteral(L, "external hook");
|
||||
} else {
|
||||
lua_pushlightuserdata(L, (void *)&KEY_HOOK);
|
||||
lua_pushlightuserdata(L, KEY_HOOK);
|
||||
lua_rawget(L, LUA_REGISTRYINDEX); /* get hook */
|
||||
}
|
||||
lua_pushstring(L, unmakemask(mask, buff));
|
||||
|
|
52
vendor/luajit/src/lib_ffi.c
vendored
52
vendor/luajit/src/lib_ffi.c
vendored
|
@ -1,6 +1,6 @@
|
|||
/*
|
||||
** FFI library.
|
||||
** Copyright (C) 2005-2015 Mike Pall. See Copyright Notice in luajit.h
|
||||
** Copyright (C) 2005-2017 Mike Pall. See Copyright Notice in luajit.h
|
||||
*/
|
||||
|
||||
#define lib_ffi_c
|
||||
|
@ -29,6 +29,7 @@
|
|||
#include "lj_ccall.h"
|
||||
#include "lj_ccallback.h"
|
||||
#include "lj_clib.h"
|
||||
#include "lj_strfmt.h"
|
||||
#include "lj_ff.h"
|
||||
#include "lj_lib.h"
|
||||
|
||||
|
@ -137,7 +138,7 @@ static int ffi_index_meta(lua_State *L, CTState *cts, CType *ct, MMS mm)
|
|||
}
|
||||
}
|
||||
copyTV(L, base, L->top);
|
||||
tv = L->top-1;
|
||||
tv = L->top-1-LJ_FR2;
|
||||
}
|
||||
return lj_meta_tailcall(L, tv);
|
||||
}
|
||||
|
@ -318,7 +319,7 @@ LJLIB_CF(ffi_meta___tostring)
|
|||
}
|
||||
}
|
||||
}
|
||||
lj_str_pushf(L, msg, strdata(lj_ctype_repr(L, id, NULL)), p);
|
||||
lj_strfmt_pushf(L, msg, strdata(lj_ctype_repr(L, id, NULL)), p);
|
||||
checkgc:
|
||||
lj_gc_check(L);
|
||||
return 1;
|
||||
|
@ -504,10 +505,7 @@ LJLIB_CF(ffi_new) LJLIB_REC(.)
|
|||
}
|
||||
if (sz == CTSIZE_INVALID)
|
||||
lj_err_arg(L, 1, LJ_ERR_FFI_INVSIZE);
|
||||
if (!(info & CTF_VLA) && ctype_align(info) <= CT_MEMALIGN)
|
||||
cd = lj_cdata_new(cts, id, sz);
|
||||
else
|
||||
cd = lj_cdata_newv(cts, id, sz, ctype_align(info));
|
||||
cd = lj_cdata_newx(cts, id, sz, info);
|
||||
setcdataV(L, o-1, cd); /* Anchor the uninitialized cdata. */
|
||||
lj_cconv_ct_init(cts, ct, sz, cdataptr(cd),
|
||||
o, (MSize)(L->top - o)); /* Initialize cdata. */
|
||||
|
@ -558,6 +556,31 @@ LJLIB_CF(ffi_typeof) LJLIB_REC(.)
|
|||
return 1;
|
||||
}
|
||||
|
||||
/* Internal and unsupported API. */
|
||||
LJLIB_CF(ffi_typeinfo)
|
||||
{
|
||||
CTState *cts = ctype_cts(L);
|
||||
CTypeID id = (CTypeID)ffi_checkint(L, 1);
|
||||
if (id > 0 && id < cts->top) {
|
||||
CType *ct = ctype_get(cts, id);
|
||||
GCtab *t;
|
||||
lua_createtable(L, 0, 4); /* Increment hash size if fields are added. */
|
||||
t = tabV(L->top-1);
|
||||
setintV(lj_tab_setstr(L, t, lj_str_newlit(L, "info")), (int32_t)ct->info);
|
||||
if (ct->size != CTSIZE_INVALID)
|
||||
setintV(lj_tab_setstr(L, t, lj_str_newlit(L, "size")), (int32_t)ct->size);
|
||||
if (ct->sib)
|
||||
setintV(lj_tab_setstr(L, t, lj_str_newlit(L, "sib")), (int32_t)ct->sib);
|
||||
if (gcref(ct->name)) {
|
||||
GCstr *s = gco2str(gcref(ct->name));
|
||||
setstrV(L, lj_tab_setstr(L, t, lj_str_newlit(L, "name")), s);
|
||||
}
|
||||
lj_gc_check(L);
|
||||
return 1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
LJLIB_CF(ffi_istype) LJLIB_REC(.)
|
||||
{
|
||||
CTState *cts = ctype_cts(L);
|
||||
|
@ -725,6 +748,9 @@ LJLIB_CF(ffi_abi) LJLIB_REC(.)
|
|||
case H_(4ab624a8,4ab624a8): b = 1; break; /* win */
|
||||
#endif
|
||||
case H_(3af93066,1f001464): b = 1; break; /* le/be */
|
||||
#if LJ_GC64
|
||||
case H_(9e89d2c9,13c83c92): b = 1; break; /* gc64 */
|
||||
#endif
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
@ -768,19 +794,11 @@ LJLIB_CF(ffi_gc) LJLIB_REC(.)
|
|||
GCcdata *cd = ffi_checkcdata(L, 1);
|
||||
TValue *fin = lj_lib_checkany(L, 2);
|
||||
CTState *cts = ctype_cts(L);
|
||||
GCtab *t = cts->finalizer;
|
||||
CType *ct = ctype_raw(cts, cd->ctypeid);
|
||||
if (!(ctype_isptr(ct->info) || ctype_isstruct(ct->info) ||
|
||||
ctype_isrefarray(ct->info)))
|
||||
lj_err_arg(L, 1, LJ_ERR_FFI_INVTYPE);
|
||||
if (gcref(t->metatable)) { /* Update finalizer table, if still enabled. */
|
||||
copyTV(L, lj_tab_set(L, t, L->base), fin);
|
||||
lj_gc_anybarriert(L, t);
|
||||
if (!tvisnil(fin))
|
||||
cd->marked |= LJ_GC_CDATA_FIN;
|
||||
else
|
||||
cd->marked &= ~LJ_GC_CDATA_FIN;
|
||||
}
|
||||
lj_cdata_setfin(L, cd, gcval(fin), itype(fin));
|
||||
L->top = L->base+1; /* Pass through the cdata object. */
|
||||
return 1;
|
||||
}
|
||||
|
@ -811,7 +829,7 @@ static GCtab *ffi_finalizer(lua_State *L)
|
|||
settabV(L, L->top++, t);
|
||||
setgcref(t->metatable, obj2gco(t));
|
||||
setstrV(L, lj_tab_setstr(L, t, lj_str_newlit(L, "__mode")),
|
||||
lj_str_newlit(L, "K"));
|
||||
lj_str_newlit(L, "k"));
|
||||
t->nomm = (uint8_t)(~(1u<<MM_mode));
|
||||
return t;
|
||||
}
|
||||
|
|
2
vendor/luajit/src/lib_init.c
vendored
2
vendor/luajit/src/lib_init.c
vendored
|
@ -1,6 +1,6 @@
|
|||
/*
|
||||
** Library initialization.
|
||||
** Copyright (C) 2005-2015 Mike Pall. See Copyright Notice in luajit.h
|
||||
** Copyright (C) 2005-2017 Mike Pall. See Copyright Notice in luajit.h
|
||||
**
|
||||
** Major parts taken verbatim from the Lua interpreter.
|
||||
** Copyright (C) 1994-2008 Lua.org, PUC-Rio. See Copyright Notice in lua.h
|
||||
|
|
60
vendor/luajit/src/lib_io.c
vendored
60
vendor/luajit/src/lib_io.c
vendored
|
@ -1,6 +1,6 @@
|
|||
/*
|
||||
** I/O library.
|
||||
** Copyright (C) 2005-2015 Mike Pall. See Copyright Notice in luajit.h
|
||||
** Copyright (C) 2005-2017 Mike Pall. See Copyright Notice in luajit.h
|
||||
**
|
||||
** Major portions taken verbatim or adapted from the Lua interpreter.
|
||||
** Copyright (C) 1994-2011 Lua.org, PUC-Rio. See Copyright Notice in lua.h
|
||||
|
@ -19,8 +19,10 @@
|
|||
#include "lj_obj.h"
|
||||
#include "lj_gc.h"
|
||||
#include "lj_err.h"
|
||||
#include "lj_buf.h"
|
||||
#include "lj_str.h"
|
||||
#include "lj_state.h"
|
||||
#include "lj_strfmt.h"
|
||||
#include "lj_ff.h"
|
||||
#include "lj_lib.h"
|
||||
|
||||
|
@ -96,13 +98,13 @@ static IOFileUD *io_file_open(lua_State *L, const char *mode)
|
|||
wchar_t wfname[MAX_PATH];
|
||||
wchar_t wmode[MAX_PATH];
|
||||
if (!widen(fname, wfname) || !widen(mode, wmode))
|
||||
luaL_argerror(L, 1, lj_str_pushf(L, "%s: failed to convert path to utf-16", fname));
|
||||
luaL_argerror(L, 1, lj_strfmt_pushf(L, "%s: failed to convert path to utf-16", fname));
|
||||
iof->fp = _wfopen(wfname, wmode);
|
||||
#else
|
||||
iof->fp = fopen(fname, mode);
|
||||
#endif
|
||||
if (iof->fp == NULL)
|
||||
luaL_argerror(L, 1, lj_str_pushf(L, "%s: %s", fname, strerror(errno)));
|
||||
luaL_argerror(L, 1, lj_strfmt_pushf(L, "%s: %s", fname, strerror(errno)));
|
||||
return iof;
|
||||
}
|
||||
|
||||
|
@ -115,7 +117,7 @@ static int io_file_close(lua_State *L, IOFileUD *iof)
|
|||
int stat = -1;
|
||||
#if LJ_TARGET_POSIX
|
||||
stat = pclose(iof->fp);
|
||||
#elif LJ_TARGET_WINDOWS
|
||||
#elif LJ_TARGET_WINDOWS && !LJ_TARGET_XBOXONE
|
||||
stat = _pclose(iof->fp);
|
||||
#else
|
||||
lua_assert(0);
|
||||
|
@ -163,7 +165,7 @@ static int io_file_readline(lua_State *L, FILE *fp, MSize chop)
|
|||
MSize m = LUAL_BUFFERSIZE, n = 0, ok = 0;
|
||||
char *buf;
|
||||
for (;;) {
|
||||
buf = lj_str_needbuf(L, &G(L)->tmpbuf, m);
|
||||
buf = lj_buf_tmp(L, m);
|
||||
if (fgets(buf+n, m-n, fp) == NULL) break;
|
||||
n += (MSize)strlen(buf+n);
|
||||
ok |= n;
|
||||
|
@ -179,7 +181,7 @@ static void io_file_readall(lua_State *L, FILE *fp)
|
|||
{
|
||||
MSize m, n;
|
||||
for (m = LUAL_BUFFERSIZE, n = 0; ; m += m) {
|
||||
char *buf = lj_str_needbuf(L, &G(L)->tmpbuf, m);
|
||||
char *buf = lj_buf_tmp(L, m);
|
||||
n += (MSize)fread(buf+n, 1, m-n, fp);
|
||||
if (n != m) {
|
||||
setstrV(L, L->top++, lj_str_new(L, buf, (size_t)n));
|
||||
|
@ -192,7 +194,7 @@ static void io_file_readall(lua_State *L, FILE *fp)
|
|||
static int io_file_readlen(lua_State *L, FILE *fp, MSize m)
|
||||
{
|
||||
if (m) {
|
||||
char *buf = lj_str_needbuf(L, &G(L)->tmpbuf, m);
|
||||
char *buf = lj_buf_tmp(L, m);
|
||||
MSize n = (MSize)fread(buf, 1, m, fp);
|
||||
setstrV(L, L->top++, lj_str_new(L, buf, (size_t)n));
|
||||
lj_gc_check(L);
|
||||
|
@ -219,13 +221,12 @@ static int io_file_read(lua_State *L, FILE *fp, int start)
|
|||
for (n = start; nargs-- && ok; n++) {
|
||||
if (tvisstr(L->base+n)) {
|
||||
const char *p = strVdata(L->base+n);
|
||||
if (p[0] != '*')
|
||||
lj_err_arg(L, n+1, LJ_ERR_INVOPT);
|
||||
if (p[1] == 'n')
|
||||
if (p[0] == '*') p++;
|
||||
if (p[0] == 'n')
|
||||
ok = io_file_readnum(L, fp);
|
||||
else if ((p[1] & ~0x20) == 'L')
|
||||
ok = io_file_readline(L, fp, (p[1] == 'l'));
|
||||
else if (p[1] == 'a')
|
||||
else if ((p[0] & ~0x20) == 'L')
|
||||
ok = io_file_readline(L, fp, (p[0] == 'l'));
|
||||
else if (p[0] == 'a')
|
||||
io_file_readall(L, fp);
|
||||
else
|
||||
lj_err_arg(L, n+1, LJ_ERR_INVFMT);
|
||||
|
@ -248,19 +249,11 @@ static int io_file_write(lua_State *L, FILE *fp, int start)
|
|||
cTValue *tv;
|
||||
int status = 1;
|
||||
for (tv = L->base+start; tv < L->top; tv++) {
|
||||
if (tvisstr(tv)) {
|
||||
MSize len = strV(tv)->len;
|
||||
status = status && (fwrite(strVdata(tv), 1, len, fp) == len);
|
||||
} else if (tvisint(tv)) {
|
||||
char buf[LJ_STR_INTBUF];
|
||||
char *p = lj_str_bufint(buf, intV(tv));
|
||||
size_t len = (size_t)(buf+LJ_STR_INTBUF-p);
|
||||
status = status && (fwrite(p, 1, len, fp) == len);
|
||||
} else if (tvisnum(tv)) {
|
||||
status = status && (fprintf(fp, LUA_NUMBER_FMT, numV(tv)) > 0);
|
||||
} else {
|
||||
MSize len;
|
||||
const char *p = lj_strfmt_wstrnum(L, tv, &len);
|
||||
if (!p)
|
||||
lj_err_argt(L, (int)(tv - L->base) + 1, LUA_TSTRING);
|
||||
}
|
||||
status = status && (fwrite(p, 1, len, fp) == len);
|
||||
}
|
||||
if (LJ_52 && status) {
|
||||
L->top = L->base+1;
|
||||
|
@ -296,6 +289,15 @@ static int io_file_iter(lua_State *L)
|
|||
return n;
|
||||
}
|
||||
|
||||
static int io_file_lines(lua_State *L)
|
||||
{
|
||||
int n = (int)(L->top - L->base);
|
||||
if (n > LJ_MAX_UPVAL)
|
||||
lj_err_caller(L, LJ_ERR_UNPACK);
|
||||
lua_pushcclosure(L, io_file_iter, n);
|
||||
return 1;
|
||||
}
|
||||
|
||||
/* -- I/O file methods ---------------------------------------------------- */
|
||||
|
||||
#define LJLIB_MODULE_io_method
|
||||
|
@ -379,8 +381,7 @@ LJLIB_CF(io_method_setvbuf)
|
|||
LJLIB_CF(io_method_lines)
|
||||
{
|
||||
io_tofile(L);
|
||||
lua_pushcclosure(L, io_file_iter, (int)(L->top - L->base));
|
||||
return 1;
|
||||
return io_file_lines(L);
|
||||
}
|
||||
|
||||
LJLIB_CF(io_method___gc)
|
||||
|
@ -430,7 +431,7 @@ LJLIB_CF(io_open)
|
|||
|
||||
LJLIB_CF(io_popen)
|
||||
{
|
||||
#if LJ_TARGET_POSIX || LJ_TARGET_WINDOWS
|
||||
#if LJ_TARGET_POSIX || (LJ_TARGET_WINDOWS && !LJ_TARGET_XBOXONE)
|
||||
const char *fname = strdata(lj_lib_checkstr(L, 1));
|
||||
GCstr *s = lj_lib_optstr(L, 2);
|
||||
const char *mode = s ? strdata(s) : "r";
|
||||
|
@ -520,8 +521,7 @@ LJLIB_CF(io_lines)
|
|||
} else { /* io.lines() iterates over stdin. */
|
||||
setudataV(L, L->base, IOSTDF_UD(L, GCROOT_IO_INPUT));
|
||||
}
|
||||
lua_pushcclosure(L, io_file_iter, (int)(L->top - L->base));
|
||||
return 1;
|
||||
return io_file_lines(L);
|
||||
}
|
||||
|
||||
LJLIB_CF(io_type)
|
||||
|
|
172
vendor/luajit/src/lib_jit.c
vendored
172
vendor/luajit/src/lib_jit.c
vendored
|
@ -1,6 +1,6 @@
|
|||
/*
|
||||
** JIT library.
|
||||
** Copyright (C) 2005-2015 Mike Pall. See Copyright Notice in luajit.h
|
||||
** Copyright (C) 2005-2017 Mike Pall. See Copyright Notice in luajit.h
|
||||
*/
|
||||
|
||||
#define lib_jit_c
|
||||
|
@ -10,13 +10,17 @@
|
|||
#include "lauxlib.h"
|
||||
#include "lualib.h"
|
||||
|
||||
#include "lj_arch.h"
|
||||
#include "lj_obj.h"
|
||||
#include "lj_gc.h"
|
||||
#include "lj_err.h"
|
||||
#include "lj_debug.h"
|
||||
#include "lj_str.h"
|
||||
#include "lj_tab.h"
|
||||
#include "lj_state.h"
|
||||
#include "lj_bc.h"
|
||||
#if LJ_HASFFI
|
||||
#include "lj_ctype.h"
|
||||
#endif
|
||||
#if LJ_HASJIT
|
||||
#include "lj_ir.h"
|
||||
#include "lj_jit.h"
|
||||
|
@ -24,6 +28,7 @@
|
|||
#include "lj_iropt.h"
|
||||
#include "lj_target.h"
|
||||
#endif
|
||||
#include "lj_trace.h"
|
||||
#include "lj_dispatch.h"
|
||||
#include "lj_vm.h"
|
||||
#include "lj_vmevent.h"
|
||||
|
@ -199,6 +204,7 @@ LJLIB_CF(jit_util_funcinfo)
|
|||
lua_setfield(L, -2, "source");
|
||||
lj_debug_pushloc(L, pt, pc);
|
||||
lua_setfield(L, -2, "loc");
|
||||
setprotoV(L, lj_tab_setstr(L, t, lj_str_newlit(L, "proto")), pt);
|
||||
} else {
|
||||
GCfunc *fn = funcV(L->base);
|
||||
GCtab *t;
|
||||
|
@ -279,7 +285,7 @@ static GCtrace *jit_checktrace(lua_State *L)
|
|||
/* Names of link types. ORDER LJ_TRLINK */
|
||||
static const char *const jit_trlinkname[] = {
|
||||
"none", "root", "loop", "tail-recursion", "up-recursion", "down-recursion",
|
||||
"interpreter", "return"
|
||||
"interpreter", "return", "stitch"
|
||||
};
|
||||
|
||||
/* local info = jit.util.traceinfo(tr) */
|
||||
|
@ -332,6 +338,13 @@ LJLIB_CF(jit_util_tracek)
|
|||
slot = ir->op2;
|
||||
ir = &T->ir[ir->op1];
|
||||
}
|
||||
#if LJ_HASFFI
|
||||
if (ir->o == IR_KINT64 && !ctype_ctsG(G(L))) {
|
||||
ptrdiff_t oldtop = savestack(L, L->top);
|
||||
luaopen_ffi(L); /* Load FFI library on-demand. */
|
||||
L->top = restorestack(L, oldtop);
|
||||
}
|
||||
#endif
|
||||
lj_ir_kvalue(L, L->top-2, ir);
|
||||
setintV(L->top-1, (int32_t)irt_type(ir->t));
|
||||
if (slot == -1)
|
||||
|
@ -416,6 +429,12 @@ LJLIB_CF(jit_util_ircalladdr)
|
|||
|
||||
#include "lj_libdef.h"
|
||||
|
||||
static int luaopen_jit_util(lua_State *L)
|
||||
{
|
||||
LJ_LIB_REG(L, NULL, jit_util);
|
||||
return 1;
|
||||
}
|
||||
|
||||
/* -- jit.opt module ------------------------------------------------------ */
|
||||
|
||||
#if LJ_HASJIT
|
||||
|
@ -513,6 +532,104 @@ LJLIB_CF(jit_opt_start)
|
|||
|
||||
#endif
|
||||
|
||||
/* -- jit.profile module -------------------------------------------------- */
|
||||
|
||||
#if LJ_HASPROFILE
|
||||
|
||||
#define LJLIB_MODULE_jit_profile
|
||||
|
||||
/* Not loaded by default, use: local profile = require("jit.profile") */
|
||||
|
||||
static const char KEY_PROFILE_THREAD = 't';
|
||||
static const char KEY_PROFILE_FUNC = 'f';
|
||||
|
||||
static void jit_profile_callback(lua_State *L2, lua_State *L, int samples,
|
||||
int vmstate)
|
||||
{
|
||||
TValue key;
|
||||
cTValue *tv;
|
||||
setlightudV(&key, (void *)&KEY_PROFILE_FUNC);
|
||||
tv = lj_tab_get(L, tabV(registry(L)), &key);
|
||||
if (tvisfunc(tv)) {
|
||||
char vmst = (char)vmstate;
|
||||
int status;
|
||||
setfuncV(L2, L2->top++, funcV(tv));
|
||||
setthreadV(L2, L2->top++, L);
|
||||
setintV(L2->top++, samples);
|
||||
setstrV(L2, L2->top++, lj_str_new(L2, &vmst, 1));
|
||||
status = lua_pcall(L2, 3, 0, 0); /* callback(thread, samples, vmstate) */
|
||||
if (status) {
|
||||
if (G(L2)->panic) G(L2)->panic(L2);
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
lj_trace_abort(G(L2));
|
||||
}
|
||||
}
|
||||
|
||||
/* profile.start(mode, cb) */
|
||||
LJLIB_CF(jit_profile_start)
|
||||
{
|
||||
GCtab *registry = tabV(registry(L));
|
||||
GCstr *mode = lj_lib_optstr(L, 1);
|
||||
GCfunc *func = lj_lib_checkfunc(L, 2);
|
||||
lua_State *L2 = lua_newthread(L); /* Thread that runs profiler callback. */
|
||||
TValue key;
|
||||
/* Anchor thread and function in registry. */
|
||||
setlightudV(&key, (void *)&KEY_PROFILE_THREAD);
|
||||
setthreadV(L, lj_tab_set(L, registry, &key), L2);
|
||||
setlightudV(&key, (void *)&KEY_PROFILE_FUNC);
|
||||
setfuncV(L, lj_tab_set(L, registry, &key), func);
|
||||
lj_gc_anybarriert(L, registry);
|
||||
luaJIT_profile_start(L, mode ? strdata(mode) : "",
|
||||
(luaJIT_profile_callback)jit_profile_callback, L2);
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* profile.stop() */
|
||||
LJLIB_CF(jit_profile_stop)
|
||||
{
|
||||
GCtab *registry;
|
||||
TValue key;
|
||||
luaJIT_profile_stop(L);
|
||||
registry = tabV(registry(L));
|
||||
setlightudV(&key, (void *)&KEY_PROFILE_THREAD);
|
||||
setnilV(lj_tab_set(L, registry, &key));
|
||||
setlightudV(&key, (void *)&KEY_PROFILE_FUNC);
|
||||
setnilV(lj_tab_set(L, registry, &key));
|
||||
lj_gc_anybarriert(L, registry);
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* dump = profile.dumpstack([thread,] fmt, depth) */
|
||||
LJLIB_CF(jit_profile_dumpstack)
|
||||
{
|
||||
lua_State *L2 = L;
|
||||
int arg = 0;
|
||||
size_t len;
|
||||
int depth;
|
||||
GCstr *fmt;
|
||||
const char *p;
|
||||
if (L->top > L->base && tvisthread(L->base)) {
|
||||
L2 = threadV(L->base);
|
||||
arg = 1;
|
||||
}
|
||||
fmt = lj_lib_checkstr(L, arg+1);
|
||||
depth = lj_lib_checkint(L, arg+2);
|
||||
p = luaJIT_profile_dumpstack(L2, strdata(fmt), depth, &len);
|
||||
lua_pushlstring(L, p, len);
|
||||
return 1;
|
||||
}
|
||||
|
||||
#include "lj_libdef.h"
|
||||
|
||||
static int luaopen_jit_profile(lua_State *L)
|
||||
{
|
||||
LJ_LIB_REG(L, NULL, jit_profile);
|
||||
return 1;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
/* -- JIT compiler initialization ----------------------------------------- */
|
||||
|
||||
#if LJ_HASJIT
|
||||
|
@ -538,38 +655,31 @@ static uint32_t jit_cpudetect(lua_State *L)
|
|||
uint32_t features[4];
|
||||
if (lj_vm_cpuid(0, vendor) && lj_vm_cpuid(1, features)) {
|
||||
#if !LJ_HASJIT
|
||||
#define JIT_F_CMOV 1
|
||||
#define JIT_F_SSE2 2
|
||||
#endif
|
||||
flags |= ((features[3] >> 15)&1) * JIT_F_CMOV;
|
||||
flags |= ((features[3] >> 26)&1) * JIT_F_SSE2;
|
||||
#if LJ_HASJIT
|
||||
flags |= ((features[2] >> 0)&1) * JIT_F_SSE3;
|
||||
flags |= ((features[2] >> 19)&1) * JIT_F_SSE4_1;
|
||||
if (vendor[2] == 0x6c65746e) { /* Intel. */
|
||||
if ((features[0] & 0x0ff00f00) == 0x00000f00) /* P4. */
|
||||
flags |= JIT_F_P4; /* Currently unused. */
|
||||
else if ((features[0] & 0x0fff0ff0) == 0x000106c0) /* Atom. */
|
||||
if ((features[0] & 0x0fff0ff0) == 0x000106c0) /* Atom. */
|
||||
flags |= JIT_F_LEA_AGU;
|
||||
} else if (vendor[2] == 0x444d4163) { /* AMD. */
|
||||
uint32_t fam = (features[0] & 0x0ff00f00);
|
||||
if (fam == 0x00000f00) /* K8. */
|
||||
flags |= JIT_F_SPLIT_XMM;
|
||||
if (fam >= 0x00000f00) /* K8, K10. */
|
||||
flags |= JIT_F_PREFER_IMUL;
|
||||
}
|
||||
if (vendor[0] >= 7) {
|
||||
uint32_t xfeatures[4];
|
||||
lj_vm_cpuid(7, xfeatures);
|
||||
flags |= ((xfeatures[1] >> 8)&1) * JIT_F_BMI2;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
/* Check for required instruction set support on x86 (unnecessary on x64). */
|
||||
#if LJ_TARGET_X86
|
||||
#if !defined(LUAJIT_CPU_NOCMOV)
|
||||
if (!(flags & JIT_F_CMOV))
|
||||
luaL_error(L, "CPU not supported");
|
||||
#endif
|
||||
#if defined(LUAJIT_CPU_SSE2)
|
||||
if (!(flags & JIT_F_SSE2))
|
||||
luaL_error(L, "CPU does not support SSE2 (recompile without -DLUAJIT_CPU_SSE2)");
|
||||
#endif
|
||||
luaL_error(L, "CPU with SSE2 required");
|
||||
#endif
|
||||
#elif LJ_TARGET_ARM
|
||||
#if LJ_HASJIT
|
||||
|
@ -591,6 +701,8 @@ static uint32_t jit_cpudetect(lua_State *L)
|
|||
ver >= 60 ? JIT_F_ARMV6_ : 0;
|
||||
flags |= LJ_ARCH_HASFPU == 0 ? 0 : ver >= 70 ? JIT_F_VFPV3 : JIT_F_VFPV2;
|
||||
#endif
|
||||
#elif LJ_TARGET_ARM64
|
||||
/* No optional CPU features to detect (for now). */
|
||||
#elif LJ_TARGET_PPC
|
||||
#if LJ_HASJIT
|
||||
#if LJ_ARCH_SQRT
|
||||
|
@ -600,21 +712,23 @@ static uint32_t jit_cpudetect(lua_State *L)
|
|||
flags |= JIT_F_ROUND;
|
||||
#endif
|
||||
#endif
|
||||
#elif LJ_TARGET_PPCSPE
|
||||
/* Nothing to do. */
|
||||
#elif LJ_TARGET_MIPS
|
||||
#if LJ_HASJIT
|
||||
/* Compile-time MIPS CPU detection. */
|
||||
#if LJ_ARCH_VERSION >= 20
|
||||
flags |= JIT_F_MIPS32R2;
|
||||
flags |= JIT_F_MIPSXXR2;
|
||||
#endif
|
||||
/* Runtime MIPS CPU detection. */
|
||||
#if defined(__GNUC__)
|
||||
if (!(flags & JIT_F_MIPS32R2)) {
|
||||
if (!(flags & JIT_F_MIPSXXR2)) {
|
||||
int x;
|
||||
#ifdef __mips16
|
||||
x = 0; /* Runtime detection is difficult. Ensure optimal -march flags. */
|
||||
#else
|
||||
/* On MIPS32R1 rotr is treated as srl. rotr r2,r2,1 -> srl r2,r2,1. */
|
||||
__asm__("li $2, 1\n\t.long 0x00221042\n\tmove %0, $2" : "=r"(x) : : "$2");
|
||||
if (x) flags |= JIT_F_MIPS32R2; /* Either 0x80000000 (R2) or 0 (R1). */
|
||||
#endif
|
||||
if (x) flags |= JIT_F_MIPSXXR2; /* Either 0x80000000 (R2) or 0 (R1). */
|
||||
}
|
||||
#endif
|
||||
#endif
|
||||
|
@ -631,11 +745,7 @@ static void jit_init(lua_State *L)
|
|||
uint32_t flags = jit_cpudetect(L);
|
||||
#if LJ_HASJIT
|
||||
jit_State *J = L2J(L);
|
||||
#if LJ_TARGET_X86
|
||||
/* Silently turn off the JIT compiler on CPUs without SSE2. */
|
||||
if ((flags & JIT_F_SSE2))
|
||||
#endif
|
||||
J->flags = flags | JIT_F_ON | JIT_F_OPT_DEFAULT;
|
||||
J->flags = flags | JIT_F_ON | JIT_F_OPT_DEFAULT;
|
||||
memcpy(J->param, jit_param_default, sizeof(J->param));
|
||||
lj_dispatch_update(G(L));
|
||||
#else
|
||||
|
@ -645,19 +755,23 @@ static void jit_init(lua_State *L)
|
|||
|
||||
LUALIB_API int luaopen_jit(lua_State *L)
|
||||
{
|
||||
jit_init(L);
|
||||
lua_pushliteral(L, LJ_OS_NAME);
|
||||
lua_pushliteral(L, LJ_ARCH_NAME);
|
||||
lua_pushinteger(L, LUAJIT_VERSION_NUM);
|
||||
lua_pushliteral(L, LUAJIT_VERSION);
|
||||
LJ_LIB_REG(L, LUA_JITLIBNAME, jit);
|
||||
#if LJ_HASPROFILE
|
||||
lj_lib_prereg(L, LUA_JITLIBNAME ".profile", luaopen_jit_profile,
|
||||
tabref(L->env));
|
||||
#endif
|
||||
#ifndef LUAJIT_DISABLE_JITUTIL
|
||||
LJ_LIB_REG(L, "jit.util", jit_util);
|
||||
lj_lib_prereg(L, LUA_JITLIBNAME ".util", luaopen_jit_util, tabref(L->env));
|
||||
#endif
|
||||
#if LJ_HASJIT
|
||||
LJ_LIB_REG(L, "jit.opt", jit_opt);
|
||||
#endif
|
||||
L->top -= 2;
|
||||
jit_init(L);
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
|
17
vendor/luajit/src/lib_math.c
vendored
17
vendor/luajit/src/lib_math.c
vendored
|
@ -1,6 +1,6 @@
|
|||
/*
|
||||
** Math library.
|
||||
** Copyright (C) 2005-2015 Mike Pall. See Copyright Notice in luajit.h
|
||||
** Copyright (C) 2005-2017 Mike Pall. See Copyright Notice in luajit.h
|
||||
*/
|
||||
|
||||
#include <math.h>
|
||||
|
@ -47,12 +47,6 @@ LJLIB_ASM_(math_tanh) LJLIB_REC(math_htrig IRCALL_tanh)
|
|||
LJLIB_ASM_(math_frexp)
|
||||
LJLIB_ASM_(math_modf) LJLIB_REC(.)
|
||||
|
||||
LJLIB_PUSH(57.29577951308232)
|
||||
LJLIB_ASM_(math_deg) LJLIB_REC(math_degrad)
|
||||
|
||||
LJLIB_PUSH(0.017453292519943295)
|
||||
LJLIB_ASM_(math_rad) LJLIB_REC(math_degrad)
|
||||
|
||||
LJLIB_ASM(math_log) LJLIB_REC(math_log)
|
||||
{
|
||||
double x = lj_lib_checknum(L, 1);
|
||||
|
@ -63,12 +57,15 @@ LJLIB_ASM(math_log) LJLIB_REC(math_log)
|
|||
#else
|
||||
x = lj_vm_log2(x); y = 1.0 / lj_vm_log2(y);
|
||||
#endif
|
||||
setnumV(L->base-1, x*y); /* Do NOT join the expression to x / y. */
|
||||
setnumV(L->base-1-LJ_FR2, x*y); /* Do NOT join the expression to x / y. */
|
||||
return FFH_RES(1);
|
||||
}
|
||||
return FFH_RETRY;
|
||||
}
|
||||
|
||||
LJLIB_LUA(math_deg) /* function(x) return x * 57.29577951308232 end */
|
||||
LJLIB_LUA(math_rad) /* function(x) return x * 0.017453292519943295 end */
|
||||
|
||||
LJLIB_ASM(math_atan2) LJLIB_REC(.)
|
||||
{
|
||||
lj_lib_checknum(L, 1);
|
||||
|
@ -224,10 +221,6 @@ LUALIB_API int luaopen_math(lua_State *L)
|
|||
rs = (RandomState *)lua_newuserdata(L, sizeof(RandomState));
|
||||
rs->valid = 0; /* Use lazy initialization to save some time on startup. */
|
||||
LJ_LIB_REG(L, LUA_MATHLIBNAME, math);
|
||||
#if defined(LUA_COMPAT_MOD) && !LJ_52
|
||||
lua_getfield(L, -1, "fmod");
|
||||
lua_setfield(L, -2, "mod");
|
||||
#endif
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
|
41
vendor/luajit/src/lib_os.c
vendored
41
vendor/luajit/src/lib_os.c
vendored
|
@ -1,6 +1,6 @@
|
|||
/*
|
||||
** OS library.
|
||||
** Copyright (C) 2005-2015 Mike Pall. See Copyright Notice in luajit.h
|
||||
** Copyright (C) 2005-2017 Mike Pall. See Copyright Notice in luajit.h
|
||||
**
|
||||
** Major portions taken verbatim or adapted from the Lua interpreter.
|
||||
** Copyright (C) 1994-2008 Lua.org, PUC-Rio. See Copyright Notice in lua.h
|
||||
|
@ -17,7 +17,10 @@
|
|||
#include "lualib.h"
|
||||
|
||||
#include "lj_obj.h"
|
||||
#include "lj_gc.h"
|
||||
#include "lj_err.h"
|
||||
#include "lj_buf.h"
|
||||
#include "lj_str.h"
|
||||
#include "lj_lib.h"
|
||||
|
||||
#if LJ_TARGET_POSIX
|
||||
|
@ -53,7 +56,7 @@ static wchar_t *widen_static(const char *narrow, int idx)
|
|||
|
||||
LJLIB_CF(os_execute)
|
||||
{
|
||||
#if LJ_TARGET_CONSOLE
|
||||
#if LJ_NO_SYSTEM
|
||||
#if LJ_52
|
||||
errno = ENOSYS;
|
||||
return luaL_fileresult(L, 0, NULL);
|
||||
|
@ -205,7 +208,7 @@ LJLIB_CF(os_date)
|
|||
#endif
|
||||
}
|
||||
if (stm == NULL) { /* Invalid date? */
|
||||
setnilV(L->top-1);
|
||||
setnilV(L->top++);
|
||||
} else if (strcmp(s, "*t") == 0) {
|
||||
lua_createtable(L, 0, 9); /* 9 = number of fields */
|
||||
setfield(L, "sec", stm->tm_sec);
|
||||
|
@ -217,23 +220,25 @@ LJLIB_CF(os_date)
|
|||
setfield(L, "wday", stm->tm_wday+1);
|
||||
setfield(L, "yday", stm->tm_yday+1);
|
||||
setboolfield(L, "isdst", stm->tm_isdst);
|
||||
} else {
|
||||
char cc[3];
|
||||
luaL_Buffer b;
|
||||
cc[0] = '%'; cc[2] = '\0';
|
||||
luaL_buffinit(L, &b);
|
||||
for (; *s; s++) {
|
||||
if (*s != '%' || *(s + 1) == '\0') { /* No conversion specifier? */
|
||||
luaL_addchar(&b, *s);
|
||||
} else {
|
||||
size_t reslen;
|
||||
char buff[200]; /* Should be big enough for any conversion result. */
|
||||
cc[1] = *(++s);
|
||||
reslen = strftime(buff, sizeof(buff), cc, stm);
|
||||
luaL_addlstring(&b, buff, reslen);
|
||||
} else if (*s) {
|
||||
SBuf *sb = &G(L)->tmpbuf;
|
||||
MSize sz = 0;
|
||||
const char *q;
|
||||
for (q = s; *q; q++)
|
||||
sz += (*q == '%') ? 30 : 1; /* Overflow doesn't matter. */
|
||||
setsbufL(sb, L);
|
||||
for (;;) {
|
||||
char *buf = lj_buf_need(sb, sz);
|
||||
size_t len = strftime(buf, sbufsz(sb), s, stm);
|
||||
if (len) {
|
||||
setstrV(L, L->top++, lj_str_new(L, buf, len));
|
||||
lj_gc_check(L);
|
||||
break;
|
||||
}
|
||||
sz += (sz|1);
|
||||
}
|
||||
luaL_pushresult(&b);
|
||||
} else {
|
||||
setstrV(L, L->top++, &G(L)->strempty);
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
|
51
vendor/luajit/src/lib_package.c
vendored
51
vendor/luajit/src/lib_package.c
vendored
|
@ -1,6 +1,6 @@
|
|||
/*
|
||||
** Package library.
|
||||
** Copyright (C) 2005-2015 Mike Pall. See Copyright Notice in luajit.h
|
||||
** Copyright (C) 2005-2017 Mike Pall. See Copyright Notice in luajit.h
|
||||
**
|
||||
** Major portions taken verbatim or adapted from the Lua interpreter.
|
||||
** Copyright (C) 1994-2012 Lua.org, PUC-Rio. See Copyright Notice in lua.h
|
||||
|
@ -96,9 +96,17 @@ static void setprogdir(lua_State *L)
|
|||
static void pusherror(lua_State *L)
|
||||
{
|
||||
DWORD error = GetLastError();
|
||||
#if LJ_TARGET_XBOXONE
|
||||
wchar_t wbuffer[128];
|
||||
char buffer[128*2];
|
||||
if (FormatMessageW(FORMAT_MESSAGE_IGNORE_INSERTS | FORMAT_MESSAGE_FROM_SYSTEM,
|
||||
NULL, error, 0, wbuffer, sizeof(wbuffer)/sizeof(wchar_t), NULL) &&
|
||||
WideCharToMultiByte(CP_ACP, 0, wbuffer, 128, buffer, 128*2, NULL, NULL))
|
||||
#else
|
||||
char buffer[128];
|
||||
if (FormatMessageA(FORMAT_MESSAGE_IGNORE_INSERTS | FORMAT_MESSAGE_FROM_SYSTEM,
|
||||
NULL, error, 0, buffer, sizeof(buffer), NULL))
|
||||
#endif
|
||||
lua_pushstring(L, buffer);
|
||||
else
|
||||
lua_pushfstring(L, "system error %d\n", error);
|
||||
|
@ -111,7 +119,7 @@ static void ll_unloadlib(void *lib)
|
|||
|
||||
static void *ll_load(lua_State *L, const char *path, int gl)
|
||||
{
|
||||
HINSTANCE lib = LoadLibraryA(path);
|
||||
HINSTANCE lib = LoadLibraryExA(path, NULL, 0);
|
||||
if (lib == NULL) pusherror(L);
|
||||
UNUSED(gl);
|
||||
return lib;
|
||||
|
@ -185,8 +193,7 @@ static void **ll_register(lua_State *L, const char *path)
|
|||
lua_pop(L, 1);
|
||||
plib = (void **)lua_newuserdata(L, sizeof(void *));
|
||||
*plib = NULL;
|
||||
luaL_getmetatable(L, "_LOADLIB");
|
||||
lua_setmetatable(L, -2);
|
||||
luaL_setmetatable(L, "_LOADLIB");
|
||||
lua_pushfstring(L, "LOADLIB: %s", path);
|
||||
lua_pushvalue(L, -2);
|
||||
lua_settable(L, LUA_REGISTRYINDEX);
|
||||
|
@ -226,7 +233,7 @@ static int ll_loadfunc(lua_State *L, const char *path, const char *name, int r)
|
|||
const char *bcdata = ll_bcsym(*reg, mksymname(L, name, SYMPREFIX_BC));
|
||||
lua_pop(L, 1);
|
||||
if (bcdata) {
|
||||
if (luaL_loadbuffer(L, bcdata, ~(size_t)0, name) != 0)
|
||||
if (luaL_loadbuffer(L, bcdata, LJ_MAX_BUF, name) != 0)
|
||||
return PACKAGE_ERR_LOAD;
|
||||
return 0;
|
||||
}
|
||||
|
@ -383,7 +390,7 @@ static int lj_cf_package_loader_preload(lua_State *L)
|
|||
if (lua_isnil(L, -1)) { /* Not found? */
|
||||
const char *bcname = mksymname(L, name, SYMPREFIX_BC);
|
||||
const char *bcdata = ll_bcsym(NULL, bcname);
|
||||
if (bcdata == NULL || luaL_loadbuffer(L, bcdata, ~(size_t)0, name) != 0)
|
||||
if (bcdata == NULL || luaL_loadbuffer(L, bcdata, LJ_MAX_BUF, name) != 0)
|
||||
lua_pushfstring(L, "\n\tno field package.preload['%s']", name);
|
||||
}
|
||||
return 1;
|
||||
|
@ -391,8 +398,7 @@ static int lj_cf_package_loader_preload(lua_State *L)
|
|||
|
||||
/* ------------------------------------------------------------------------ */
|
||||
|
||||
static const int sentinel_ = 0;
|
||||
#define sentinel ((void *)&sentinel_)
|
||||
#define sentinel ((void *)0x4004)
|
||||
|
||||
static int lj_cf_package_require(lua_State *L)
|
||||
{
|
||||
|
@ -482,29 +488,19 @@ static void modinit(lua_State *L, const char *modname)
|
|||
static int lj_cf_package_module(lua_State *L)
|
||||
{
|
||||
const char *modname = luaL_checkstring(L, 1);
|
||||
int loaded = lua_gettop(L) + 1; /* index of _LOADED table */
|
||||
lua_getfield(L, LUA_REGISTRYINDEX, "_LOADED");
|
||||
lua_getfield(L, loaded, modname); /* get _LOADED[modname] */
|
||||
if (!lua_istable(L, -1)) { /* not found? */
|
||||
lua_pop(L, 1); /* remove previous result */
|
||||
/* try global variable (and create one if it does not exist) */
|
||||
if (luaL_findtable(L, LUA_GLOBALSINDEX, modname, 1) != NULL)
|
||||
lj_err_callerv(L, LJ_ERR_BADMODN, modname);
|
||||
lua_pushvalue(L, -1);
|
||||
lua_setfield(L, loaded, modname); /* _LOADED[modname] = new table */
|
||||
}
|
||||
/* check whether table already has a _NAME field */
|
||||
int lastarg = (int)(L->top - L->base);
|
||||
luaL_pushmodule(L, modname, 1);
|
||||
lua_getfield(L, -1, "_NAME");
|
||||
if (!lua_isnil(L, -1)) { /* is table an initialized module? */
|
||||
if (!lua_isnil(L, -1)) { /* Module already initialized? */
|
||||
lua_pop(L, 1);
|
||||
} else { /* no; initialize it */
|
||||
} else {
|
||||
lua_pop(L, 1);
|
||||
modinit(L, modname);
|
||||
}
|
||||
lua_pushvalue(L, -1);
|
||||
setfenv(L);
|
||||
dooptions(L, loaded - 1);
|
||||
return 0;
|
||||
dooptions(L, lastarg);
|
||||
return LJ_52;
|
||||
}
|
||||
|
||||
static int lj_cf_package_seeall(lua_State *L)
|
||||
|
@ -575,13 +571,16 @@ LUALIB_API int luaopen_package(lua_State *L)
|
|||
lj_lib_pushcf(L, lj_cf_package_unloadlib, 1);
|
||||
lua_setfield(L, -2, "__gc");
|
||||
luaL_register(L, LUA_LOADLIBNAME, package_lib);
|
||||
lua_pushvalue(L, -1);
|
||||
lua_replace(L, LUA_ENVIRONINDEX);
|
||||
lua_copy(L, -1, LUA_ENVIRONINDEX);
|
||||
lua_createtable(L, sizeof(package_loaders)/sizeof(package_loaders[0])-1, 0);
|
||||
for (i = 0; package_loaders[i] != NULL; i++) {
|
||||
lj_lib_pushcf(L, package_loaders[i], 1);
|
||||
lua_rawseti(L, -2, i+1);
|
||||
}
|
||||
#if LJ_52
|
||||
lua_pushvalue(L, -1);
|
||||
lua_setfield(L, -3, "searchers");
|
||||
#endif
|
||||
lua_setfield(L, -2, "loaders");
|
||||
lua_getfield(L, LUA_REGISTRYINDEX, "LUA_NOENV");
|
||||
noenv = lua_toboolean(L, -1);
|
||||
|
|
452
vendor/luajit/src/lib_string.c
vendored
452
vendor/luajit/src/lib_string.c
vendored
|
@ -1,13 +1,11 @@
|
|||
/*
|
||||
** String library.
|
||||
** Copyright (C) 2005-2015 Mike Pall. See Copyright Notice in luajit.h
|
||||
** Copyright (C) 2005-2017 Mike Pall. See Copyright Notice in luajit.h
|
||||
**
|
||||
** Major portions taken verbatim or adapted from the Lua interpreter.
|
||||
** Copyright (C) 1994-2008 Lua.org, PUC-Rio. See Copyright Notice in lua.h
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
|
||||
#define lib_string_c
|
||||
#define LUA_LIB
|
||||
|
||||
|
@ -18,6 +16,7 @@
|
|||
#include "lj_obj.h"
|
||||
#include "lj_gc.h"
|
||||
#include "lj_err.h"
|
||||
#include "lj_buf.h"
|
||||
#include "lj_str.h"
|
||||
#include "lj_tab.h"
|
||||
#include "lj_meta.h"
|
||||
|
@ -25,17 +24,19 @@
|
|||
#include "lj_ff.h"
|
||||
#include "lj_bcdump.h"
|
||||
#include "lj_char.h"
|
||||
#include "lj_strfmt.h"
|
||||
#include "lj_lib.h"
|
||||
|
||||
/* ------------------------------------------------------------------------ */
|
||||
|
||||
#define LJLIB_MODULE_string
|
||||
|
||||
LJLIB_ASM(string_len) LJLIB_REC(.)
|
||||
{
|
||||
lj_lib_checkstr(L, 1);
|
||||
return FFH_RETRY;
|
||||
}
|
||||
LJLIB_LUA(string_len) /*
|
||||
function(s)
|
||||
CHECK_str(s)
|
||||
return #s
|
||||
end
|
||||
*/
|
||||
|
||||
LJLIB_ASM(string_byte) LJLIB_REC(string_range 0)
|
||||
{
|
||||
|
@ -57,21 +58,21 @@ LJLIB_ASM(string_byte) LJLIB_REC(string_range 0)
|
|||
lj_state_checkstack(L, (MSize)n);
|
||||
p = (const unsigned char *)strdata(s) + start;
|
||||
for (i = 0; i < n; i++)
|
||||
setintV(L->base + i-1, p[i]);
|
||||
setintV(L->base + i-1-LJ_FR2, p[i]);
|
||||
return FFH_RES(n);
|
||||
}
|
||||
|
||||
LJLIB_ASM(string_char)
|
||||
LJLIB_ASM(string_char) LJLIB_REC(.)
|
||||
{
|
||||
int i, nargs = (int)(L->top - L->base);
|
||||
char *buf = lj_str_needbuf(L, &G(L)->tmpbuf, (MSize)nargs);
|
||||
char *buf = lj_buf_tmp(L, (MSize)nargs);
|
||||
for (i = 1; i <= nargs; i++) {
|
||||
int32_t k = lj_lib_checkint(L, i);
|
||||
if (!checku8(k))
|
||||
lj_err_arg(L, i, LJ_ERR_BADVAL);
|
||||
buf[i-1] = (char)k;
|
||||
}
|
||||
setstrV(L, L->base-1, lj_str_new(L, buf, (size_t)nargs));
|
||||
setstrV(L, L->base-1-LJ_FR2, lj_str_new(L, buf, (size_t)nargs));
|
||||
return FFH_RES(1);
|
||||
}
|
||||
|
||||
|
@ -83,68 +84,38 @@ LJLIB_ASM(string_sub) LJLIB_REC(string_range 1)
|
|||
return FFH_RETRY;
|
||||
}
|
||||
|
||||
LJLIB_ASM(string_rep)
|
||||
LJLIB_CF(string_rep) LJLIB_REC(.)
|
||||
{
|
||||
GCstr *s = lj_lib_checkstr(L, 1);
|
||||
int32_t k = lj_lib_checkint(L, 2);
|
||||
int32_t rep = lj_lib_checkint(L, 2);
|
||||
GCstr *sep = lj_lib_optstr(L, 3);
|
||||
int32_t len = (int32_t)s->len;
|
||||
global_State *g = G(L);
|
||||
int64_t tlen;
|
||||
const char *src;
|
||||
char *buf;
|
||||
if (k <= 0) {
|
||||
empty:
|
||||
setstrV(L, L->base-1, &g->strempty);
|
||||
return FFH_RES(1);
|
||||
SBuf *sb = lj_buf_tmp_(L);
|
||||
if (sep && rep > 1) {
|
||||
GCstr *s2 = lj_buf_cat2str(L, sep, s);
|
||||
lj_buf_reset(sb);
|
||||
lj_buf_putstr(sb, s);
|
||||
s = s2;
|
||||
rep--;
|
||||
}
|
||||
if (sep) {
|
||||
tlen = (int64_t)len + sep->len;
|
||||
if (tlen > LJ_MAX_STR)
|
||||
lj_err_caller(L, LJ_ERR_STROV);
|
||||
tlen *= k;
|
||||
if (tlen > LJ_MAX_STR)
|
||||
lj_err_caller(L, LJ_ERR_STROV);
|
||||
} else {
|
||||
tlen = (int64_t)k * len;
|
||||
if (tlen > LJ_MAX_STR)
|
||||
lj_err_caller(L, LJ_ERR_STROV);
|
||||
}
|
||||
if (tlen == 0) goto empty;
|
||||
buf = lj_str_needbuf(L, &g->tmpbuf, (MSize)tlen);
|
||||
src = strdata(s);
|
||||
if (sep) {
|
||||
tlen -= sep->len; /* Ignore trailing separator. */
|
||||
if (k > 1) { /* Paste one string and one separator. */
|
||||
int32_t i;
|
||||
i = 0; while (i < len) *buf++ = src[i++];
|
||||
src = strdata(sep); len = sep->len;
|
||||
i = 0; while (i < len) *buf++ = src[i++];
|
||||
src = g->tmpbuf.buf; len += s->len; k--; /* Now copy that k-1 times. */
|
||||
}
|
||||
}
|
||||
do {
|
||||
int32_t i = 0;
|
||||
do { *buf++ = src[i++]; } while (i < len);
|
||||
} while (--k > 0);
|
||||
setstrV(L, L->base-1, lj_str_new(L, g->tmpbuf.buf, (size_t)tlen));
|
||||
return FFH_RES(1);
|
||||
sb = lj_buf_putstr_rep(sb, s, rep);
|
||||
setstrV(L, L->top-1, lj_buf_str(L, sb));
|
||||
lj_gc_check(L);
|
||||
return 1;
|
||||
}
|
||||
|
||||
LJLIB_ASM(string_reverse)
|
||||
LJLIB_ASM(string_reverse) LJLIB_REC(string_op IRCALL_lj_buf_putstr_reverse)
|
||||
{
|
||||
GCstr *s = lj_lib_checkstr(L, 1);
|
||||
lj_str_needbuf(L, &G(L)->tmpbuf, s->len);
|
||||
lj_lib_checkstr(L, 1);
|
||||
return FFH_RETRY;
|
||||
}
|
||||
LJLIB_ASM_(string_lower)
|
||||
LJLIB_ASM_(string_upper)
|
||||
LJLIB_ASM_(string_lower) LJLIB_REC(string_op IRCALL_lj_buf_putstr_lower)
|
||||
LJLIB_ASM_(string_upper) LJLIB_REC(string_op IRCALL_lj_buf_putstr_upper)
|
||||
|
||||
/* ------------------------------------------------------------------------ */
|
||||
|
||||
static int writer_buf(lua_State *L, const void *p, size_t size, void *b)
|
||||
static int writer_buf(lua_State *L, const void *p, size_t size, void *sb)
|
||||
{
|
||||
luaL_addlstring((luaL_Buffer *)b, (const char *)p, size);
|
||||
lj_buf_putmem((SBuf *)sb, p, (MSize)size);
|
||||
UNUSED(L);
|
||||
return 0;
|
||||
}
|
||||
|
@ -153,12 +124,12 @@ LJLIB_CF(string_dump)
|
|||
{
|
||||
GCfunc *fn = lj_lib_checkfunc(L, 1);
|
||||
int strip = L->base+1 < L->top && tvistruecond(L->base+1);
|
||||
luaL_Buffer b;
|
||||
SBuf *sb = lj_buf_tmp_(L); /* Assumes lj_bcwrite() doesn't use tmpbuf. */
|
||||
L->top = L->base+1;
|
||||
luaL_buffinit(L, &b);
|
||||
if (!isluafunc(fn) || lj_bcwrite(L, funcproto(fn), writer_buf, &b, strip))
|
||||
if (!isluafunc(fn) || lj_bcwrite(L, funcproto(fn), writer_buf, sb, strip))
|
||||
lj_err_caller(L, LJ_ERR_STRDUMP);
|
||||
luaL_pushresult(&b);
|
||||
setstrV(L, L->top-1, lj_buf_str(L, sb));
|
||||
lj_gc_check(L);
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
@ -183,7 +154,6 @@ typedef struct MatchState {
|
|||
} MatchState;
|
||||
|
||||
#define L_ESC '%'
|
||||
#define SPECIALS "^$*+?.([%-"
|
||||
|
||||
static int check_capture(MatchState *ms, int l)
|
||||
{
|
||||
|
@ -450,30 +420,6 @@ static const char *match(MatchState *ms, const char *s, const char *p)
|
|||
return s;
|
||||
}
|
||||
|
||||
static const char *lmemfind(const char *s1, size_t l1,
|
||||
const char *s2, size_t l2)
|
||||
{
|
||||
if (l2 == 0) {
|
||||
return s1; /* empty strings are everywhere */
|
||||
} else if (l2 > l1) {
|
||||
return NULL; /* avoids a negative `l1' */
|
||||
} else {
|
||||
const char *init; /* to search for a `*s2' inside `s1' */
|
||||
l2--; /* 1st char will be checked by `memchr' */
|
||||
l1 = l1-l2; /* `s2' cannot be found after that */
|
||||
while (l1 > 0 && (init = (const char *)memchr(s1, *s2, l1)) != NULL) {
|
||||
init++; /* 1st char is already checked */
|
||||
if (memcmp(init, s2+1, l2) == 0) {
|
||||
return init-1;
|
||||
} else { /* correct `l1' and `s1' to try again */
|
||||
l1 -= (size_t)(init-s1);
|
||||
s1 = init;
|
||||
}
|
||||
}
|
||||
return NULL; /* not found */
|
||||
}
|
||||
}
|
||||
|
||||
static void push_onecapture(MatchState *ms, int i, const char *s, const char *e)
|
||||
{
|
||||
if (i >= ms->level) {
|
||||
|
@ -501,64 +447,60 @@ static int push_captures(MatchState *ms, const char *s, const char *e)
|
|||
return nlevels; /* number of strings pushed */
|
||||
}
|
||||
|
||||
static ptrdiff_t posrelat(ptrdiff_t pos, size_t len)
|
||||
{
|
||||
/* relative string position: negative means back from end */
|
||||
if (pos < 0) pos += (ptrdiff_t)len + 1;
|
||||
return (pos >= 0) ? pos : 0;
|
||||
}
|
||||
|
||||
static int str_find_aux(lua_State *L, int find)
|
||||
{
|
||||
size_t l1, l2;
|
||||
const char *s = luaL_checklstring(L, 1, &l1);
|
||||
const char *p = luaL_checklstring(L, 2, &l2);
|
||||
ptrdiff_t init = posrelat(luaL_optinteger(L, 3, 1), l1) - 1;
|
||||
if (init < 0) {
|
||||
init = 0;
|
||||
} else if ((size_t)(init) > l1) {
|
||||
GCstr *s = lj_lib_checkstr(L, 1);
|
||||
GCstr *p = lj_lib_checkstr(L, 2);
|
||||
int32_t start = lj_lib_optint(L, 3, 1);
|
||||
MSize st;
|
||||
if (start < 0) start += (int32_t)s->len; else start--;
|
||||
if (start < 0) start = 0;
|
||||
st = (MSize)start;
|
||||
if (st > s->len) {
|
||||
#if LJ_52
|
||||
setnilV(L->top-1);
|
||||
return 1;
|
||||
#else
|
||||
init = (ptrdiff_t)l1;
|
||||
st = s->len;
|
||||
#endif
|
||||
}
|
||||
if (find && (lua_toboolean(L, 4) || /* explicit request? */
|
||||
strpbrk(p, SPECIALS) == NULL)) { /* or no special characters? */
|
||||
/* do a plain search */
|
||||
const char *s2 = lmemfind(s+init, l1-(size_t)init, p, l2);
|
||||
if (s2) {
|
||||
lua_pushinteger(L, s2-s+1);
|
||||
lua_pushinteger(L, s2-s+(ptrdiff_t)l2);
|
||||
if (find && ((L->base+3 < L->top && tvistruecond(L->base+3)) ||
|
||||
!lj_str_haspattern(p))) { /* Search for fixed string. */
|
||||
const char *q = lj_str_find(strdata(s)+st, strdata(p), s->len-st, p->len);
|
||||
if (q) {
|
||||
setintV(L->top-2, (int32_t)(q-strdata(s)) + 1);
|
||||
setintV(L->top-1, (int32_t)(q-strdata(s)) + (int32_t)p->len);
|
||||
return 2;
|
||||
}
|
||||
} else {
|
||||
} else { /* Search for pattern. */
|
||||
MatchState ms;
|
||||
int anchor = (*p == '^') ? (p++, 1) : 0;
|
||||
const char *s1=s+init;
|
||||
const char *pstr = strdata(p);
|
||||
const char *sstr = strdata(s) + st;
|
||||
int anchor = 0;
|
||||
if (*pstr == '^') { pstr++; anchor = 1; }
|
||||
ms.L = L;
|
||||
ms.src_init = s;
|
||||
ms.src_end = s+l1;
|
||||
do {
|
||||
const char *res;
|
||||
ms.src_init = strdata(s);
|
||||
ms.src_end = strdata(s) + s->len;
|
||||
do { /* Loop through string and try to match the pattern. */
|
||||
const char *q;
|
||||
ms.level = ms.depth = 0;
|
||||
if ((res=match(&ms, s1, p)) != NULL) {
|
||||
q = match(&ms, sstr, pstr);
|
||||
if (q) {
|
||||
if (find) {
|
||||
lua_pushinteger(L, s1-s+1); /* start */
|
||||
lua_pushinteger(L, res-s); /* end */
|
||||
return push_captures(&ms, NULL, 0) + 2;
|
||||
setintV(L->top++, (int32_t)(sstr-(strdata(s)-1)));
|
||||
setintV(L->top++, (int32_t)(q-strdata(s)));
|
||||
return push_captures(&ms, NULL, NULL) + 2;
|
||||
} else {
|
||||
return push_captures(&ms, s1, res);
|
||||
return push_captures(&ms, sstr, q);
|
||||
}
|
||||
}
|
||||
} while (s1++ < ms.src_end && !anchor);
|
||||
} while (sstr++ < ms.src_end && !anchor);
|
||||
}
|
||||
lua_pushnil(L); /* not found */
|
||||
setnilV(L->top-1); /* Not found. */
|
||||
return 1;
|
||||
}
|
||||
|
||||
LJLIB_CF(string_find)
|
||||
LJLIB_CF(string_find) LJLIB_REC(.)
|
||||
{
|
||||
return str_find_aux(L, 1);
|
||||
}
|
||||
|
@ -698,221 +640,91 @@ LJLIB_CF(string_gsub)
|
|||
|
||||
/* ------------------------------------------------------------------------ */
|
||||
|
||||
/* maximum size of each formatted item (> len(format('%99.99f', -1e308))) */
|
||||
#define MAX_FMTITEM 512
|
||||
/* valid flags in a format specification */
|
||||
#define FMT_FLAGS "-+ #0"
|
||||
/*
|
||||
** maximum size of each format specification (such as '%-099.99d')
|
||||
** (+10 accounts for %99.99x plus margin of error)
|
||||
*/
|
||||
#define MAX_FMTSPEC (sizeof(FMT_FLAGS) + sizeof(LUA_INTFRMLEN) + 10)
|
||||
|
||||
static void addquoted(lua_State *L, luaL_Buffer *b, int arg)
|
||||
{
|
||||
GCstr *str = lj_lib_checkstr(L, arg);
|
||||
int32_t len = (int32_t)str->len;
|
||||
const char *s = strdata(str);
|
||||
luaL_addchar(b, '"');
|
||||
while (len--) {
|
||||
uint32_t c = uchar(*s);
|
||||
if (c == '"' || c == '\\' || c == '\n') {
|
||||
luaL_addchar(b, '\\');
|
||||
} else if (lj_char_iscntrl(c)) { /* This can only be 0-31 or 127. */
|
||||
uint32_t d;
|
||||
luaL_addchar(b, '\\');
|
||||
if (c >= 100 || lj_char_isdigit(uchar(s[1]))) {
|
||||
luaL_addchar(b, '0'+(c >= 100)); if (c >= 100) c -= 100;
|
||||
goto tens;
|
||||
} else if (c >= 10) {
|
||||
tens:
|
||||
d = (c * 205) >> 11; c -= d * 10; luaL_addchar(b, '0'+d);
|
||||
}
|
||||
c += '0';
|
||||
}
|
||||
luaL_addchar(b, c);
|
||||
s++;
|
||||
}
|
||||
luaL_addchar(b, '"');
|
||||
}
|
||||
|
||||
static const char *scanformat(lua_State *L, const char *strfrmt, char *form)
|
||||
{
|
||||
const char *p = strfrmt;
|
||||
while (*p != '\0' && strchr(FMT_FLAGS, *p) != NULL) p++; /* skip flags */
|
||||
if ((size_t)(p - strfrmt) >= sizeof(FMT_FLAGS))
|
||||
lj_err_caller(L, LJ_ERR_STRFMTR);
|
||||
if (lj_char_isdigit(uchar(*p))) p++; /* skip width */
|
||||
if (lj_char_isdigit(uchar(*p))) p++; /* (2 digits at most) */
|
||||
if (*p == '.') {
|
||||
p++;
|
||||
if (lj_char_isdigit(uchar(*p))) p++; /* skip precision */
|
||||
if (lj_char_isdigit(uchar(*p))) p++; /* (2 digits at most) */
|
||||
}
|
||||
if (lj_char_isdigit(uchar(*p)))
|
||||
lj_err_caller(L, LJ_ERR_STRFMTW);
|
||||
*(form++) = '%';
|
||||
strncpy(form, strfrmt, (size_t)(p - strfrmt + 1));
|
||||
form += p - strfrmt + 1;
|
||||
*form = '\0';
|
||||
return p;
|
||||
}
|
||||
|
||||
static void addintlen(char *form)
|
||||
{
|
||||
size_t l = strlen(form);
|
||||
char spec = form[l - 1];
|
||||
strcpy(form + l - 1, LUA_INTFRMLEN);
|
||||
form[l + sizeof(LUA_INTFRMLEN) - 2] = spec;
|
||||
form[l + sizeof(LUA_INTFRMLEN) - 1] = '\0';
|
||||
}
|
||||
|
||||
static unsigned LUA_INTFRM_T num2intfrm(lua_State *L, int arg)
|
||||
{
|
||||
if (sizeof(LUA_INTFRM_T) == 4) {
|
||||
return (LUA_INTFRM_T)lj_lib_checkbit(L, arg);
|
||||
} else {
|
||||
cTValue *o;
|
||||
lj_lib_checknumber(L, arg);
|
||||
o = L->base+arg-1;
|
||||
if (tvisint(o))
|
||||
return (LUA_INTFRM_T)intV(o);
|
||||
else
|
||||
return (LUA_INTFRM_T)numV(o);
|
||||
}
|
||||
}
|
||||
|
||||
static unsigned LUA_INTFRM_T num2uintfrm(lua_State *L, int arg)
|
||||
{
|
||||
if (sizeof(LUA_INTFRM_T) == 4) {
|
||||
return (unsigned LUA_INTFRM_T)lj_lib_checkbit(L, arg);
|
||||
} else {
|
||||
cTValue *o;
|
||||
lj_lib_checknumber(L, arg);
|
||||
o = L->base+arg-1;
|
||||
if (tvisint(o))
|
||||
return (unsigned LUA_INTFRM_T)intV(o);
|
||||
else if ((int32_t)o->u32.hi < 0)
|
||||
return (unsigned LUA_INTFRM_T)(LUA_INTFRM_T)numV(o);
|
||||
else
|
||||
return (unsigned LUA_INTFRM_T)numV(o);
|
||||
}
|
||||
}
|
||||
|
||||
static GCstr *meta_tostring(lua_State *L, int arg)
|
||||
/* Emulate tostring() inline. */
|
||||
static GCstr *string_fmt_tostring(lua_State *L, int arg, int retry)
|
||||
{
|
||||
TValue *o = L->base+arg-1;
|
||||
cTValue *mo;
|
||||
lua_assert(o < L->top); /* Caller already checks for existence. */
|
||||
if (LJ_LIKELY(tvisstr(o)))
|
||||
return strV(o);
|
||||
if (!tvisnil(mo = lj_meta_lookup(L, o, MM_tostring))) {
|
||||
if (retry != 2 && !tvisnil(mo = lj_meta_lookup(L, o, MM_tostring))) {
|
||||
copyTV(L, L->top++, mo);
|
||||
copyTV(L, L->top++, o);
|
||||
lua_call(L, 1, 1);
|
||||
L->top--;
|
||||
if (tvisstr(L->top))
|
||||
return strV(L->top);
|
||||
o = L->base+arg-1;
|
||||
copyTV(L, o, L->top);
|
||||
}
|
||||
if (tvisnumber(o)) {
|
||||
return lj_str_fromnumber(L, o);
|
||||
} else if (tvisnil(o)) {
|
||||
return lj_str_newlit(L, "nil");
|
||||
} else if (tvisfalse(o)) {
|
||||
return lj_str_newlit(L, "false");
|
||||
} else if (tvistrue(o)) {
|
||||
return lj_str_newlit(L, "true");
|
||||
} else {
|
||||
if (tvisfunc(o) && isffunc(funcV(o)))
|
||||
lj_str_pushf(L, "function: builtin#%d", funcV(o)->c.ffid);
|
||||
else
|
||||
lj_str_pushf(L, "%s: %p", lj_typename(o), lua_topointer(L, arg));
|
||||
L->top--;
|
||||
return strV(L->top);
|
||||
copyTV(L, L->base+arg-1, --L->top);
|
||||
return NULL; /* Buffer may be overwritten, retry. */
|
||||
}
|
||||
return lj_strfmt_obj(L, o);
|
||||
}
|
||||
|
||||
LJLIB_CF(string_format)
|
||||
LJLIB_CF(string_format) LJLIB_REC(.)
|
||||
{
|
||||
int arg = 1, top = (int)(L->top - L->base);
|
||||
GCstr *fmt = lj_lib_checkstr(L, arg);
|
||||
const char *strfrmt = strdata(fmt);
|
||||
const char *strfrmt_end = strfrmt + fmt->len;
|
||||
luaL_Buffer b;
|
||||
luaL_buffinit(L, &b);
|
||||
while (strfrmt < strfrmt_end) {
|
||||
if (*strfrmt != L_ESC) {
|
||||
luaL_addchar(&b, *strfrmt++);
|
||||
} else if (*++strfrmt == L_ESC) {
|
||||
luaL_addchar(&b, *strfrmt++); /* %% */
|
||||
} else { /* format item */
|
||||
char form[MAX_FMTSPEC]; /* to store the format (`%...') */
|
||||
char buff[MAX_FMTITEM]; /* to store the formatted item */
|
||||
int arg, top = (int)(L->top - L->base);
|
||||
GCstr *fmt;
|
||||
SBuf *sb;
|
||||
FormatState fs;
|
||||
SFormat sf;
|
||||
int retry = 0;
|
||||
again:
|
||||
arg = 1;
|
||||
sb = lj_buf_tmp_(L);
|
||||
fmt = lj_lib_checkstr(L, arg);
|
||||
lj_strfmt_init(&fs, strdata(fmt), fmt->len);
|
||||
while ((sf = lj_strfmt_parse(&fs)) != STRFMT_EOF) {
|
||||
if (sf == STRFMT_LIT) {
|
||||
lj_buf_putmem(sb, fs.str, fs.len);
|
||||
} else if (sf == STRFMT_ERR) {
|
||||
lj_err_callerv(L, LJ_ERR_STRFMT, strdata(lj_str_new(L, fs.str, fs.len)));
|
||||
} else {
|
||||
if (++arg > top)
|
||||
luaL_argerror(L, arg, lj_obj_typename[0]);
|
||||
strfrmt = scanformat(L, strfrmt, form);
|
||||
switch (*strfrmt++) {
|
||||
case 'c':
|
||||
sprintf(buff, form, lj_lib_checkint(L, arg));
|
||||
break;
|
||||
case 'd': case 'i':
|
||||
addintlen(form);
|
||||
sprintf(buff, form, num2intfrm(L, arg));
|
||||
break;
|
||||
case 'o': case 'u': case 'x': case 'X':
|
||||
addintlen(form);
|
||||
sprintf(buff, form, num2uintfrm(L, arg));
|
||||
break;
|
||||
case 'e': case 'E': case 'f': case 'g': case 'G': case 'a': case 'A': {
|
||||
TValue tv;
|
||||
tv.n = lj_lib_checknum(L, arg);
|
||||
if (LJ_UNLIKELY((tv.u32.hi << 1) >= 0xffe00000)) {
|
||||
/* Canonicalize output of non-finite values. */
|
||||
char *p, nbuf[LJ_STR_NUMBUF];
|
||||
size_t len = lj_str_bufnum(nbuf, &tv);
|
||||
if (strfrmt[-1] < 'a') {
|
||||
nbuf[len-3] = nbuf[len-3] - 0x20;
|
||||
nbuf[len-2] = nbuf[len-2] - 0x20;
|
||||
nbuf[len-1] = nbuf[len-1] - 0x20;
|
||||
}
|
||||
nbuf[len] = '\0';
|
||||
for (p = form; *p < 'A' && *p != '.'; p++) ;
|
||||
*p++ = 's'; *p = '\0';
|
||||
sprintf(buff, form, nbuf);
|
||||
break;
|
||||
switch (STRFMT_TYPE(sf)) {
|
||||
case STRFMT_INT:
|
||||
if (tvisint(L->base+arg-1)) {
|
||||
int32_t k = intV(L->base+arg-1);
|
||||
if (sf == STRFMT_INT)
|
||||
lj_strfmt_putint(sb, k); /* Shortcut for plain %d. */
|
||||
else
|
||||
lj_strfmt_putfxint(sb, sf, k);
|
||||
} else {
|
||||
lj_strfmt_putfnum_int(sb, sf, lj_lib_checknum(L, arg));
|
||||
}
|
||||
sprintf(buff, form, (double)tv.n);
|
||||
break;
|
||||
case STRFMT_UINT:
|
||||
if (tvisint(L->base+arg-1))
|
||||
lj_strfmt_putfxint(sb, sf, intV(L->base+arg-1));
|
||||
else
|
||||
lj_strfmt_putfnum_uint(sb, sf, lj_lib_checknum(L, arg));
|
||||
break;
|
||||
case STRFMT_NUM:
|
||||
lj_strfmt_putfnum(sb, sf, lj_lib_checknum(L, arg));
|
||||
break;
|
||||
case STRFMT_STR: {
|
||||
GCstr *str = string_fmt_tostring(L, arg, retry);
|
||||
if (str == NULL)
|
||||
retry = 1;
|
||||
else if ((sf & STRFMT_T_QUOTED))
|
||||
lj_strfmt_putquoted(sb, str); /* No formatting. */
|
||||
else
|
||||
lj_strfmt_putfstr(sb, sf, str);
|
||||
break;
|
||||
}
|
||||
case 'q':
|
||||
addquoted(L, &b, arg);
|
||||
continue;
|
||||
case 'p':
|
||||
lj_str_pushf(L, "%p", lua_topointer(L, arg));
|
||||
luaL_addvalue(&b);
|
||||
continue;
|
||||
case 's': {
|
||||
GCstr *str = meta_tostring(L, arg);
|
||||
if (!strchr(form, '.') && str->len >= 100) {
|
||||
/* no precision and string is too long to be formatted;
|
||||
keep original string */
|
||||
setstrV(L, L->top++, str);
|
||||
luaL_addvalue(&b);
|
||||
continue;
|
||||
}
|
||||
sprintf(buff, form, strdata(str));
|
||||
case STRFMT_CHAR:
|
||||
lj_strfmt_putfchar(sb, sf, lj_lib_checkint(L, arg));
|
||||
break;
|
||||
case STRFMT_PTR: /* No formatting. */
|
||||
lj_strfmt_putptr(sb, lj_obj_ptr(L->base+arg-1));
|
||||
break;
|
||||
}
|
||||
default:
|
||||
lj_err_callerv(L, LJ_ERR_STRFMTO, *(strfrmt -1));
|
||||
lua_assert(0);
|
||||
break;
|
||||
}
|
||||
luaL_addlstring(&b, buff, strlen(buff));
|
||||
}
|
||||
}
|
||||
luaL_pushresult(&b);
|
||||
if (retry++ == 1) goto again;
|
||||
setstrV(L, L->top-1, lj_buf_str(L, sb));
|
||||
lj_gc_check(L);
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
@ -925,10 +737,6 @@ LUALIB_API int luaopen_string(lua_State *L)
|
|||
GCtab *mt;
|
||||
global_State *g;
|
||||
LJ_LIB_REG(L, LUA_STRLIBNAME, string);
|
||||
#if defined(LUA_COMPAT_GFIND) && !LJ_52
|
||||
lua_getfield(L, -1, "gmatch");
|
||||
lua_setfield(L, -2, "gfind");
|
||||
#endif
|
||||
mt = lj_tab_new(L, 0, 1);
|
||||
/* NOBARRIER: basemt is a GC root. */
|
||||
g = G(L);
|
||||
|
|
189
vendor/luajit/src/lib_table.c
vendored
189
vendor/luajit/src/lib_table.c
vendored
|
@ -1,6 +1,6 @@
|
|||
/*
|
||||
** Table library.
|
||||
** Copyright (C) 2005-2015 Mike Pall. See Copyright Notice in luajit.h
|
||||
** Copyright (C) 2005-2017 Mike Pall. See Copyright Notice in luajit.h
|
||||
**
|
||||
** Major portions taken verbatim or adapted from the Lua interpreter.
|
||||
** Copyright (C) 1994-2008 Lua.org, PUC-Rio. See Copyright Notice in lua.h
|
||||
|
@ -16,57 +16,43 @@
|
|||
#include "lj_obj.h"
|
||||
#include "lj_gc.h"
|
||||
#include "lj_err.h"
|
||||
#include "lj_buf.h"
|
||||
#include "lj_tab.h"
|
||||
#include "lj_ff.h"
|
||||
#include "lj_lib.h"
|
||||
|
||||
/* ------------------------------------------------------------------------ */
|
||||
|
||||
#define LJLIB_MODULE_table
|
||||
|
||||
LJLIB_CF(table_foreachi)
|
||||
{
|
||||
GCtab *t = lj_lib_checktab(L, 1);
|
||||
GCfunc *func = lj_lib_checkfunc(L, 2);
|
||||
MSize i, n = lj_tab_len(t);
|
||||
for (i = 1; i <= n; i++) {
|
||||
cTValue *val;
|
||||
setfuncV(L, L->top, func);
|
||||
setintV(L->top+1, i);
|
||||
val = lj_tab_getint(t, (int32_t)i);
|
||||
if (val) { copyTV(L, L->top+2, val); } else { setnilV(L->top+2); }
|
||||
L->top += 3;
|
||||
lua_call(L, 2, 1);
|
||||
if (!tvisnil(L->top-1))
|
||||
return 1;
|
||||
L->top--;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
LJLIB_LUA(table_foreachi) /*
|
||||
function(t, f)
|
||||
CHECK_tab(t)
|
||||
CHECK_func(f)
|
||||
for i=1,#t do
|
||||
local r = f(i, t[i])
|
||||
if r ~= nil then return r end
|
||||
end
|
||||
end
|
||||
*/
|
||||
|
||||
LJLIB_CF(table_foreach)
|
||||
{
|
||||
GCtab *t = lj_lib_checktab(L, 1);
|
||||
GCfunc *func = lj_lib_checkfunc(L, 2);
|
||||
L->top = L->base+3;
|
||||
setnilV(L->top-1);
|
||||
while (lj_tab_next(L, t, L->top-1)) {
|
||||
copyTV(L, L->top+2, L->top);
|
||||
copyTV(L, L->top+1, L->top-1);
|
||||
setfuncV(L, L->top, func);
|
||||
L->top += 3;
|
||||
lua_call(L, 2, 1);
|
||||
if (!tvisnil(L->top-1))
|
||||
return 1;
|
||||
L->top--;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
LJLIB_LUA(table_foreach) /*
|
||||
function(t, f)
|
||||
CHECK_tab(t)
|
||||
CHECK_func(f)
|
||||
for k, v in PAIRS(t) do
|
||||
local r = f(k, v)
|
||||
if r ~= nil then return r end
|
||||
end
|
||||
end
|
||||
*/
|
||||
|
||||
LJLIB_ASM(table_getn) LJLIB_REC(.)
|
||||
{
|
||||
lj_lib_checktab(L, 1);
|
||||
return FFH_UNREACHABLE;
|
||||
}
|
||||
LJLIB_LUA(table_getn) /*
|
||||
function(t)
|
||||
CHECK_tab(t)
|
||||
return #t
|
||||
end
|
||||
*/
|
||||
|
||||
LJLIB_CF(table_maxn)
|
||||
{
|
||||
|
@ -119,52 +105,67 @@ LJLIB_CF(table_insert) LJLIB_REC(.)
|
|||
return 0;
|
||||
}
|
||||
|
||||
LJLIB_CF(table_remove) LJLIB_REC(.)
|
||||
{
|
||||
GCtab *t = lj_lib_checktab(L, 1);
|
||||
int32_t e = (int32_t)lj_tab_len(t);
|
||||
int32_t pos = lj_lib_optint(L, 2, e);
|
||||
if (!(1 <= pos && pos <= e)) /* Nothing to remove? */
|
||||
return 0;
|
||||
lua_rawgeti(L, 1, pos); /* Get previous value. */
|
||||
/* NOBARRIER: This just moves existing elements around. */
|
||||
for (; pos < e; pos++) {
|
||||
cTValue *src = lj_tab_getint(t, pos+1);
|
||||
TValue *dst = lj_tab_setint(L, t, pos);
|
||||
if (src) {
|
||||
copyTV(L, dst, src);
|
||||
} else {
|
||||
setnilV(dst);
|
||||
}
|
||||
}
|
||||
setnilV(lj_tab_setint(L, t, e)); /* Remove (last) value. */
|
||||
return 1; /* Return previous value. */
|
||||
}
|
||||
LJLIB_LUA(table_remove) /*
|
||||
function(t, pos)
|
||||
CHECK_tab(t)
|
||||
local len = #t
|
||||
if pos == nil then
|
||||
if len ~= 0 then
|
||||
local old = t[len]
|
||||
t[len] = nil
|
||||
return old
|
||||
end
|
||||
else
|
||||
CHECK_int(pos)
|
||||
if pos >= 1 and pos <= len then
|
||||
local old = t[pos]
|
||||
for i=pos+1,len do
|
||||
t[i-1] = t[i]
|
||||
end
|
||||
t[len] = nil
|
||||
return old
|
||||
end
|
||||
end
|
||||
end
|
||||
*/
|
||||
|
||||
LJLIB_CF(table_concat)
|
||||
LJLIB_LUA(table_move) /*
|
||||
function(a1, f, e, t, a2)
|
||||
CHECK_tab(a1)
|
||||
CHECK_int(f)
|
||||
CHECK_int(e)
|
||||
CHECK_int(t)
|
||||
if a2 == nil then a2 = a1 end
|
||||
CHECK_tab(a2)
|
||||
if e >= f then
|
||||
local d = t - f
|
||||
if t > e or t <= f or a2 ~= a1 then
|
||||
for i=f,e do a2[i+d] = a1[i] end
|
||||
else
|
||||
for i=e,f,-1 do a2[i+d] = a1[i] end
|
||||
end
|
||||
end
|
||||
return a2
|
||||
end
|
||||
*/
|
||||
|
||||
LJLIB_CF(table_concat) LJLIB_REC(.)
|
||||
{
|
||||
luaL_Buffer b;
|
||||
GCtab *t = lj_lib_checktab(L, 1);
|
||||
GCstr *sep = lj_lib_optstr(L, 2);
|
||||
MSize seplen = sep ? sep->len : 0;
|
||||
int32_t i = lj_lib_optint(L, 3, 1);
|
||||
int32_t e = (L->base+3 < L->top && !tvisnil(L->base+3)) ?
|
||||
lj_lib_checkint(L, 4) : (int32_t)lj_tab_len(t);
|
||||
luaL_buffinit(L, &b);
|
||||
if (i <= e) {
|
||||
for (;;) {
|
||||
cTValue *o;
|
||||
lua_rawgeti(L, 1, i);
|
||||
o = L->top-1;
|
||||
if (!(tvisstr(o) || tvisnumber(o)))
|
||||
lj_err_callerv(L, LJ_ERR_TABCAT, lj_typename(o), i);
|
||||
luaL_addvalue(&b);
|
||||
if (i++ == e) break;
|
||||
if (seplen)
|
||||
luaL_addlstring(&b, strdata(sep), seplen);
|
||||
}
|
||||
SBuf *sb = lj_buf_tmp_(L);
|
||||
SBuf *sbx = lj_buf_puttab(sb, t, sep, i, e);
|
||||
if (LJ_UNLIKELY(!sbx)) { /* Error: bad element type. */
|
||||
int32_t idx = (int32_t)(intptr_t)sbufP(sb);
|
||||
cTValue *o = lj_tab_getint(t, idx);
|
||||
lj_err_callerv(L, LJ_ERR_TABCAT,
|
||||
lj_obj_itypename[o ? itypemap(o) : ~LJ_TNIL], idx);
|
||||
}
|
||||
luaL_pushresult(&b);
|
||||
setstrV(L, L->top-1, lj_buf_str(L, sbx));
|
||||
lj_gc_check(L);
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
@ -284,6 +285,30 @@ LJLIB_CF(table_pack)
|
|||
}
|
||||
#endif
|
||||
|
||||
LJLIB_NOREG LJLIB_CF(table_new) LJLIB_REC(.)
|
||||
{
|
||||
int32_t a = lj_lib_checkint(L, 1);
|
||||
int32_t h = lj_lib_checkint(L, 2);
|
||||
lua_createtable(L, a, h);
|
||||
return 1;
|
||||
}
|
||||
|
||||
LJLIB_NOREG LJLIB_CF(table_clear) LJLIB_REC(.)
|
||||
{
|
||||
lj_tab_clear(lj_lib_checktab(L, 1));
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int luaopen_table_new(lua_State *L)
|
||||
{
|
||||
return lj_lib_postreg(L, lj_cf_table_new, FF_table_new, "new");
|
||||
}
|
||||
|
||||
static int luaopen_table_clear(lua_State *L)
|
||||
{
|
||||
return lj_lib_postreg(L, lj_cf_table_clear, FF_table_clear, "clear");
|
||||
}
|
||||
|
||||
/* ------------------------------------------------------------------------ */
|
||||
|
||||
#include "lj_libdef.h"
|
||||
|
@ -295,6 +320,8 @@ LUALIB_API int luaopen_table(lua_State *L)
|
|||
lua_getglobal(L, "unpack");
|
||||
lua_setfield(L, -2, "unpack");
|
||||
#endif
|
||||
lj_lib_prereg(L, LUA_TABLIBNAME ".new", luaopen_table_new, tabV(L->top-1));
|
||||
lj_lib_prereg(L, LUA_TABLIBNAME ".clear", luaopen_table_clear, tabV(L->top-1));
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
|
15
vendor/luajit/src/lj.supp
vendored
15
vendor/luajit/src/lj.supp
vendored
|
@ -24,3 +24,18 @@
|
|||
Memcheck:Cond
|
||||
fun:lj_str_new
|
||||
}
|
||||
{
|
||||
Optimized string compare
|
||||
Memcheck:Addr4
|
||||
fun:str_fastcmp
|
||||
}
|
||||
{
|
||||
Optimized string compare
|
||||
Memcheck:Addr1
|
||||
fun:str_fastcmp
|
||||
}
|
||||
{
|
||||
Optimized string compare
|
||||
Memcheck:Cond
|
||||
fun:str_fastcmp
|
||||
}
|
||||
|
|
267
vendor/luajit/src/lj_alloc.c
vendored
267
vendor/luajit/src/lj_alloc.c
vendored
|
@ -72,13 +72,56 @@
|
|||
|
||||
#define IS_DIRECT_BIT (SIZE_T_ONE)
|
||||
|
||||
|
||||
/* Determine system-specific block allocation method. */
|
||||
#if LJ_TARGET_WINDOWS
|
||||
|
||||
#define WIN32_LEAN_AND_MEAN
|
||||
#include <windows.h>
|
||||
|
||||
#define LJ_ALLOC_VIRTUALALLOC 1
|
||||
|
||||
#if LJ_64 && !LJ_GC64
|
||||
#define LJ_ALLOC_NTAVM 1
|
||||
#endif
|
||||
|
||||
#else
|
||||
|
||||
#include <errno.h>
|
||||
/* If this include fails, then rebuild with: -DLUAJIT_USE_SYSMALLOC */
|
||||
#include <sys/mman.h>
|
||||
|
||||
#define LJ_ALLOC_MMAP 1
|
||||
|
||||
#if LJ_64
|
||||
|
||||
#define LJ_ALLOC_MMAP_PROBE 1
|
||||
|
||||
#if LJ_GC64
|
||||
#define LJ_ALLOC_MBITS 47 /* 128 TB in LJ_GC64 mode. */
|
||||
#elif LJ_TARGET_X64 && LJ_HASJIT
|
||||
/* Due to limitations in the x64 compiler backend. */
|
||||
#define LJ_ALLOC_MBITS 31 /* 2 GB on x64 with !LJ_GC64. */
|
||||
#else
|
||||
#define LJ_ALLOC_MBITS 32 /* 4 GB on other archs with !LJ_GC64. */
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
||||
#if LJ_64 && !LJ_GC64 && defined(MAP_32BIT)
|
||||
#define LJ_ALLOC_MMAP32 1
|
||||
#endif
|
||||
|
||||
#if LJ_TARGET_LINUX
|
||||
#define LJ_ALLOC_MREMAP 1
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
#if LJ_ALLOC_VIRTUALALLOC
|
||||
|
||||
#if LJ_ALLOC_NTAVM
|
||||
/* Undocumented, but hey, that's what we all love so much about Windows. */
|
||||
typedef long (*PNTAVM)(HANDLE handle, void **addr, ULONG zbits,
|
||||
size_t *size, ULONG alloctype, ULONG prot);
|
||||
|
@ -89,14 +132,15 @@ static PNTAVM ntavm;
|
|||
*/
|
||||
#define NTAVM_ZEROBITS 1
|
||||
|
||||
static void INIT_MMAP(void)
|
||||
static void init_mmap(void)
|
||||
{
|
||||
ntavm = (PNTAVM)GetProcAddress(GetModuleHandleA("ntdll.dll"),
|
||||
"NtAllocateVirtualMemory");
|
||||
}
|
||||
#define INIT_MMAP() init_mmap()
|
||||
|
||||
/* Win64 32 bit MMAP via NtAllocateVirtualMemory. */
|
||||
static LJ_AINLINE void *CALL_MMAP(size_t size)
|
||||
static void *CALL_MMAP(size_t size)
|
||||
{
|
||||
DWORD olderr = GetLastError();
|
||||
void *ptr = NULL;
|
||||
|
@ -107,7 +151,7 @@ static LJ_AINLINE void *CALL_MMAP(size_t size)
|
|||
}
|
||||
|
||||
/* For direct MMAP, use MEM_TOP_DOWN to minimize interference */
|
||||
static LJ_AINLINE void *DIRECT_MMAP(size_t size)
|
||||
static void *DIRECT_MMAP(size_t size)
|
||||
{
|
||||
DWORD olderr = GetLastError();
|
||||
void *ptr = NULL;
|
||||
|
@ -119,10 +163,8 @@ static LJ_AINLINE void *DIRECT_MMAP(size_t size)
|
|||
|
||||
#else
|
||||
|
||||
#define INIT_MMAP() ((void)0)
|
||||
|
||||
/* Win32 MMAP via VirtualAlloc */
|
||||
static LJ_AINLINE void *CALL_MMAP(size_t size)
|
||||
static void *CALL_MMAP(size_t size)
|
||||
{
|
||||
DWORD olderr = GetLastError();
|
||||
void *ptr = VirtualAlloc(0, size, MEM_RESERVE|MEM_COMMIT, PAGE_READWRITE);
|
||||
|
@ -131,7 +173,7 @@ static LJ_AINLINE void *CALL_MMAP(size_t size)
|
|||
}
|
||||
|
||||
/* For direct MMAP, use MEM_TOP_DOWN to minimize interference */
|
||||
static LJ_AINLINE void *DIRECT_MMAP(size_t size)
|
||||
static void *DIRECT_MMAP(size_t size)
|
||||
{
|
||||
DWORD olderr = GetLastError();
|
||||
void *ptr = VirtualAlloc(0, size, MEM_RESERVE|MEM_COMMIT|MEM_TOP_DOWN,
|
||||
|
@ -143,7 +185,7 @@ static LJ_AINLINE void *DIRECT_MMAP(size_t size)
|
|||
#endif
|
||||
|
||||
/* This function supports releasing coalesed segments */
|
||||
static LJ_AINLINE int CALL_MUNMAP(void *ptr, size_t size)
|
||||
static int CALL_MUNMAP(void *ptr, size_t size)
|
||||
{
|
||||
DWORD olderr = GetLastError();
|
||||
MEMORY_BASIC_INFORMATION minfo;
|
||||
|
@ -163,10 +205,7 @@ static LJ_AINLINE int CALL_MUNMAP(void *ptr, size_t size)
|
|||
return 0;
|
||||
}
|
||||
|
||||
#else
|
||||
|
||||
#include <errno.h>
|
||||
#include <sys/mman.h>
|
||||
#elif LJ_ALLOC_MMAP
|
||||
|
||||
#define MMAP_PROT (PROT_READ|PROT_WRITE)
|
||||
#if !defined(MAP_ANONYMOUS) && defined(MAP_ANON)
|
||||
|
@ -174,105 +213,151 @@ static LJ_AINLINE int CALL_MUNMAP(void *ptr, size_t size)
|
|||
#endif
|
||||
#define MMAP_FLAGS (MAP_PRIVATE|MAP_ANONYMOUS)
|
||||
|
||||
#if LJ_64
|
||||
/* 64 bit mode needs special support for allocating memory in the lower 2GB. */
|
||||
#if LJ_ALLOC_MMAP_PROBE
|
||||
|
||||
#if defined(MAP_32BIT)
|
||||
|
||||
#if defined(__sun__)
|
||||
#define MMAP_REGION_START ((uintptr_t)0x1000)
|
||||
#ifdef MAP_TRYFIXED
|
||||
#define MMAP_FLAGS_PROBE (MMAP_FLAGS|MAP_TRYFIXED)
|
||||
#else
|
||||
/* Actually this only gives us max. 1GB in current Linux kernels. */
|
||||
#define MMAP_REGION_START ((uintptr_t)0)
|
||||
#define MMAP_FLAGS_PROBE MMAP_FLAGS
|
||||
#endif
|
||||
|
||||
static LJ_AINLINE void *CALL_MMAP(size_t size)
|
||||
#define LJ_ALLOC_MMAP_PROBE_MAX 30
|
||||
#define LJ_ALLOC_MMAP_PROBE_LINEAR 5
|
||||
|
||||
#define LJ_ALLOC_MMAP_PROBE_LOWER ((uintptr_t)0x4000)
|
||||
|
||||
/* No point in a giant ifdef mess. Just try to open /dev/urandom.
|
||||
** It doesn't really matter if this fails, since we get some ASLR bits from
|
||||
** every unsuitable allocation, too. And we prefer linear allocation, anyway.
|
||||
*/
|
||||
#include <fcntl.h>
|
||||
#include <unistd.h>
|
||||
|
||||
static uintptr_t mmap_probe_seed(void)
|
||||
{
|
||||
int olderr = errno;
|
||||
void *ptr = mmap((void *)MMAP_REGION_START, size, MMAP_PROT, MAP_32BIT|MMAP_FLAGS, -1, 0);
|
||||
errno = olderr;
|
||||
return ptr;
|
||||
uintptr_t val;
|
||||
int fd = open("/dev/urandom", O_RDONLY);
|
||||
if (fd != -1) {
|
||||
int ok = ((size_t)read(fd, &val, sizeof(val)) == sizeof(val));
|
||||
(void)close(fd);
|
||||
if (ok) return val;
|
||||
}
|
||||
return 1; /* Punt. */
|
||||
}
|
||||
|
||||
#elif LJ_TARGET_OSX || LJ_TARGET_PS4 || defined(__FreeBSD__) || defined(__FreeBSD_kernel__) || defined(__NetBSD__) || defined(__OpenBSD__) || defined(__DragonFly__) || defined(__sun__)
|
||||
|
||||
/* OSX and FreeBSD mmap() use a naive first-fit linear search.
|
||||
** That's perfect for us. Except that -pagezero_size must be set for OSX,
|
||||
** otherwise the lower 4GB are blocked. And the 32GB RLIMIT_DATA needs
|
||||
** to be reduced to 250MB on FreeBSD.
|
||||
*/
|
||||
#if LJ_TARGET_OSX || defined(__DragonFly__)
|
||||
#define MMAP_REGION_START ((uintptr_t)0x10000)
|
||||
#elif LJ_TARGET_PS4
|
||||
#define MMAP_REGION_START ((uintptr_t)0x4000)
|
||||
#else
|
||||
#define MMAP_REGION_START ((uintptr_t)0x10000000)
|
||||
#endif
|
||||
#define MMAP_REGION_END ((uintptr_t)0x80000000)
|
||||
|
||||
#if (defined(__FreeBSD__) || defined(__FreeBSD_kernel__)) && !LJ_TARGET_PS4
|
||||
#include <sys/resource.h>
|
||||
#endif
|
||||
|
||||
static LJ_AINLINE void *CALL_MMAP(size_t size)
|
||||
static void *mmap_probe(size_t size)
|
||||
{
|
||||
int olderr = errno;
|
||||
/* Hint for next allocation. Doesn't need to be thread-safe. */
|
||||
static uintptr_t alloc_hint = MMAP_REGION_START;
|
||||
int retry = 0;
|
||||
#if (defined(__FreeBSD__) || defined(__FreeBSD_kernel__)) && !LJ_TARGET_PS4
|
||||
static int rlimit_modified = 0;
|
||||
if (LJ_UNLIKELY(rlimit_modified == 0)) {
|
||||
struct rlimit rlim;
|
||||
rlim.rlim_cur = rlim.rlim_max = MMAP_REGION_START;
|
||||
setrlimit(RLIMIT_DATA, &rlim); /* Ignore result. May fail below. */
|
||||
rlimit_modified = 1;
|
||||
}
|
||||
#endif
|
||||
for (;;) {
|
||||
void *p = mmap((void *)alloc_hint, size, MMAP_PROT, MMAP_FLAGS, -1, 0);
|
||||
if ((uintptr_t)p >= MMAP_REGION_START &&
|
||||
(uintptr_t)p + size < MMAP_REGION_END) {
|
||||
alloc_hint = (uintptr_t)p + size;
|
||||
static uintptr_t hint_addr = 0;
|
||||
static uintptr_t hint_prng = 0;
|
||||
int olderr = errno;
|
||||
int retry;
|
||||
for (retry = 0; retry < LJ_ALLOC_MMAP_PROBE_MAX; retry++) {
|
||||
void *p = mmap((void *)hint_addr, size, MMAP_PROT, MMAP_FLAGS_PROBE, -1, 0);
|
||||
uintptr_t addr = (uintptr_t)p;
|
||||
if ((addr >> LJ_ALLOC_MBITS) == 0 && addr >= LJ_ALLOC_MMAP_PROBE_LOWER) {
|
||||
/* We got a suitable address. Bump the hint address. */
|
||||
hint_addr = addr + size;
|
||||
errno = olderr;
|
||||
return p;
|
||||
}
|
||||
if (p != CMFAIL) munmap(p, size);
|
||||
#if defined(__sun__) || defined(__DragonFly__)
|
||||
alloc_hint += 0x1000000; /* Need near-exhaustive linear scan. */
|
||||
if (alloc_hint + size < MMAP_REGION_END) continue;
|
||||
#endif
|
||||
if (retry) break;
|
||||
retry = 1;
|
||||
alloc_hint = MMAP_REGION_START;
|
||||
if (p != MFAIL) {
|
||||
munmap(p, size);
|
||||
} else if (errno == ENOMEM) {
|
||||
return MFAIL;
|
||||
}
|
||||
if (hint_addr) {
|
||||
/* First, try linear probing. */
|
||||
if (retry < LJ_ALLOC_MMAP_PROBE_LINEAR) {
|
||||
hint_addr += 0x1000000;
|
||||
if (((hint_addr + size) >> LJ_ALLOC_MBITS) != 0)
|
||||
hint_addr = 0;
|
||||
continue;
|
||||
} else if (retry == LJ_ALLOC_MMAP_PROBE_LINEAR) {
|
||||
/* Next, try a no-hint probe to get back an ASLR address. */
|
||||
hint_addr = 0;
|
||||
continue;
|
||||
}
|
||||
}
|
||||
/* Finally, try pseudo-random probing. */
|
||||
if (LJ_UNLIKELY(hint_prng == 0)) {
|
||||
hint_prng = mmap_probe_seed();
|
||||
}
|
||||
/* The unsuitable address we got has some ASLR PRNG bits. */
|
||||
hint_addr ^= addr & ~((uintptr_t)(LJ_PAGESIZE-1));
|
||||
do { /* The PRNG itself is very weak, but see above. */
|
||||
hint_prng = hint_prng * 1103515245 + 12345;
|
||||
hint_addr ^= hint_prng * (uintptr_t)LJ_PAGESIZE;
|
||||
hint_addr &= (((uintptr_t)1 << LJ_ALLOC_MBITS)-1);
|
||||
} while (hint_addr < LJ_ALLOC_MMAP_PROBE_LOWER);
|
||||
}
|
||||
errno = olderr;
|
||||
return CMFAIL;
|
||||
return MFAIL;
|
||||
}
|
||||
|
||||
#else
|
||||
|
||||
#error "NYI: need an equivalent of MAP_32BIT for this 64 bit OS"
|
||||
|
||||
#endif
|
||||
|
||||
#else
|
||||
#if LJ_ALLOC_MMAP32
|
||||
|
||||
/* 32 bit mode is easy. */
|
||||
static LJ_AINLINE void *CALL_MMAP(size_t size)
|
||||
#if defined(__sun__)
|
||||
#define LJ_ALLOC_MMAP32_START ((uintptr_t)0x1000)
|
||||
#else
|
||||
#define LJ_ALLOC_MMAP32_START ((uintptr_t)0)
|
||||
#endif
|
||||
|
||||
static void *mmap_map32(size_t size)
|
||||
{
|
||||
#if LJ_ALLOC_MMAP_PROBE
|
||||
static int fallback = 0;
|
||||
if (fallback)
|
||||
return mmap_probe(size);
|
||||
#endif
|
||||
{
|
||||
int olderr = errno;
|
||||
void *ptr = mmap((void *)LJ_ALLOC_MMAP32_START, size, MMAP_PROT, MAP_32BIT|MMAP_FLAGS, -1, 0);
|
||||
errno = olderr;
|
||||
/* This only allows 1GB on Linux. So fallback to probing to get 2GB. */
|
||||
#if LJ_ALLOC_MMAP_PROBE
|
||||
if (ptr == MFAIL) {
|
||||
fallback = 1;
|
||||
return mmap_probe(size);
|
||||
}
|
||||
#endif
|
||||
return ptr;
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
#if LJ_ALLOC_MMAP32
|
||||
#define CALL_MMAP(size) mmap_map32(size)
|
||||
#elif LJ_ALLOC_MMAP_PROBE
|
||||
#define CALL_MMAP(size) mmap_probe(size)
|
||||
#else
|
||||
static void *CALL_MMAP(size_t size)
|
||||
{
|
||||
int olderr = errno;
|
||||
void *ptr = mmap(NULL, size, MMAP_PROT, MMAP_FLAGS, -1, 0);
|
||||
errno = olderr;
|
||||
return ptr;
|
||||
}
|
||||
#endif
|
||||
|
||||
#if (defined(__FreeBSD__) || defined(__FreeBSD_kernel__)) && !LJ_TARGET_PS4
|
||||
|
||||
#include <sys/resource.h>
|
||||
|
||||
static void init_mmap(void)
|
||||
{
|
||||
struct rlimit rlim;
|
||||
rlim.rlim_cur = rlim.rlim_max = 0x10000;
|
||||
setrlimit(RLIMIT_DATA, &rlim); /* Ignore result. May fail later. */
|
||||
}
|
||||
#define INIT_MMAP() init_mmap()
|
||||
|
||||
#endif
|
||||
|
||||
#define INIT_MMAP() ((void)0)
|
||||
#define DIRECT_MMAP(s) CALL_MMAP(s)
|
||||
|
||||
static LJ_AINLINE int CALL_MUNMAP(void *ptr, size_t size)
|
||||
static int CALL_MUNMAP(void *ptr, size_t size)
|
||||
{
|
||||
int olderr = errno;
|
||||
int ret = munmap(ptr, size);
|
||||
|
@ -280,10 +365,9 @@ static LJ_AINLINE int CALL_MUNMAP(void *ptr, size_t size)
|
|||
return ret;
|
||||
}
|
||||
|
||||
#if LJ_TARGET_LINUX
|
||||
#if LJ_ALLOC_MREMAP
|
||||
/* Need to define _GNU_SOURCE to get the mremap prototype. */
|
||||
static LJ_AINLINE void *CALL_MREMAP_(void *ptr, size_t osz, size_t nsz,
|
||||
int flags)
|
||||
static void *CALL_MREMAP_(void *ptr, size_t osz, size_t nsz, int flags)
|
||||
{
|
||||
int olderr = errno;
|
||||
ptr = mremap(ptr, osz, nsz, flags);
|
||||
|
@ -294,7 +378,7 @@ static LJ_AINLINE void *CALL_MREMAP_(void *ptr, size_t osz, size_t nsz,
|
|||
#define CALL_MREMAP(addr, osz, nsz, mv) CALL_MREMAP_((addr), (osz), (nsz), (mv))
|
||||
#define CALL_MREMAP_NOMOVE 0
|
||||
#define CALL_MREMAP_MAYMOVE 1
|
||||
#if LJ_64
|
||||
#if LJ_64 && !LJ_GC64
|
||||
#define CALL_MREMAP_MV CALL_MREMAP_NOMOVE
|
||||
#else
|
||||
#define CALL_MREMAP_MV CALL_MREMAP_MAYMOVE
|
||||
|
@ -303,6 +387,15 @@ static LJ_AINLINE void *CALL_MREMAP_(void *ptr, size_t osz, size_t nsz,
|
|||
|
||||
#endif
|
||||
|
||||
|
||||
#ifndef INIT_MMAP
|
||||
#define INIT_MMAP() ((void)0)
|
||||
#endif
|
||||
|
||||
#ifndef DIRECT_MMAP
|
||||
#define DIRECT_MMAP(s) CALL_MMAP(s)
|
||||
#endif
|
||||
|
||||
#ifndef CALL_MREMAP
|
||||
#define CALL_MREMAP(addr, osz, nsz, mv) ((void)osz, MFAIL)
|
||||
#endif
|
||||
|
|
248
vendor/luajit/src/lj_api.c
vendored
248
vendor/luajit/src/lj_api.c
vendored
|
@ -1,6 +1,6 @@
|
|||
/*
|
||||
** Public Lua/C API.
|
||||
** Copyright (C) 2005-2015 Mike Pall. See Copyright Notice in luajit.h
|
||||
** Copyright (C) 2005-2017 Mike Pall. See Copyright Notice in luajit.h
|
||||
**
|
||||
** Major portions taken verbatim or adapted from the Lua interpreter.
|
||||
** Copyright (C) 1994-2008 Lua.org, PUC-Rio. See Copyright Notice in lua.h
|
||||
|
@ -24,6 +24,7 @@
|
|||
#include "lj_trace.h"
|
||||
#include "lj_vm.h"
|
||||
#include "lj_strscan.h"
|
||||
#include "lj_strfmt.h"
|
||||
|
||||
/* -- Common helper functions --------------------------------------------- */
|
||||
|
||||
|
@ -111,6 +112,13 @@ LUA_API void lua_xmove(lua_State *from, lua_State *to, int n)
|
|||
from->top = f;
|
||||
}
|
||||
|
||||
LUA_API const lua_Number *lua_version(lua_State *L)
|
||||
{
|
||||
static const lua_Number version = LUA_VERSION_NUM;
|
||||
UNUSED(L);
|
||||
return &version;
|
||||
}
|
||||
|
||||
/* -- Stack manipulation -------------------------------------------------- */
|
||||
|
||||
LUA_API int lua_gettop(lua_State *L)
|
||||
|
@ -151,30 +159,40 @@ LUA_API void lua_insert(lua_State *L, int idx)
|
|||
copyTV(L, p, L->top);
|
||||
}
|
||||
|
||||
LUA_API void lua_replace(lua_State *L, int idx)
|
||||
static void copy_slot(lua_State *L, TValue *f, int idx)
|
||||
{
|
||||
api_checknelems(L, 1);
|
||||
if (idx == LUA_GLOBALSINDEX) {
|
||||
api_check(L, tvistab(L->top-1));
|
||||
api_check(L, tvistab(f));
|
||||
/* NOBARRIER: A thread (i.e. L) is never black. */
|
||||
setgcref(L->env, obj2gco(tabV(L->top-1)));
|
||||
setgcref(L->env, obj2gco(tabV(f)));
|
||||
} else if (idx == LUA_ENVIRONINDEX) {
|
||||
GCfunc *fn = curr_func(L);
|
||||
if (fn->c.gct != ~LJ_TFUNC)
|
||||
lj_err_msg(L, LJ_ERR_NOENV);
|
||||
api_check(L, tvistab(L->top-1));
|
||||
setgcref(fn->c.env, obj2gco(tabV(L->top-1)));
|
||||
lj_gc_barrier(L, fn, L->top-1);
|
||||
api_check(L, tvistab(f));
|
||||
setgcref(fn->c.env, obj2gco(tabV(f)));
|
||||
lj_gc_barrier(L, fn, f);
|
||||
} else {
|
||||
TValue *o = index2adr(L, idx);
|
||||
api_checkvalidindex(L, o);
|
||||
copyTV(L, o, L->top-1);
|
||||
copyTV(L, o, f);
|
||||
if (idx < LUA_GLOBALSINDEX) /* Need a barrier for upvalues. */
|
||||
lj_gc_barrier(L, curr_func(L), L->top-1);
|
||||
lj_gc_barrier(L, curr_func(L), f);
|
||||
}
|
||||
}
|
||||
|
||||
LUA_API void lua_replace(lua_State *L, int idx)
|
||||
{
|
||||
api_checknelems(L, 1);
|
||||
copy_slot(L, L->top - 1, idx);
|
||||
L->top--;
|
||||
}
|
||||
|
||||
LUA_API void lua_copy(lua_State *L, int fromidx, int toidx)
|
||||
{
|
||||
copy_slot(L, index2adr(L, fromidx), toidx);
|
||||
}
|
||||
|
||||
LUA_API void lua_pushvalue(lua_State *L, int idx)
|
||||
{
|
||||
copyTV(L, L->top, index2adr(L, idx));
|
||||
|
@ -188,7 +206,7 @@ LUA_API int lua_type(lua_State *L, int idx)
|
|||
cTValue *o = index2adr(L, idx);
|
||||
if (tvisnumber(o)) {
|
||||
return LUA_TNUMBER;
|
||||
#if LJ_64
|
||||
#if LJ_64 && !LJ_GC64
|
||||
} else if (tvislightud(o)) {
|
||||
return LUA_TLIGHTUSERDATA;
|
||||
#endif
|
||||
|
@ -268,7 +286,7 @@ LUA_API int lua_equal(lua_State *L, int idx1, int idx2)
|
|||
return 0;
|
||||
} else if (tvispri(o1)) {
|
||||
return o1 != niltv(L) && o2 != niltv(L);
|
||||
#if LJ_64
|
||||
#if LJ_64 && !LJ_GC64
|
||||
} else if (tvislightud(o1)) {
|
||||
return o1->u64 == o2->u64;
|
||||
#endif
|
||||
|
@ -283,8 +301,8 @@ LUA_API int lua_equal(lua_State *L, int idx1, int idx2)
|
|||
} else {
|
||||
L->top = base+2;
|
||||
lj_vm_call(L, base, 1+1);
|
||||
L->top -= 2;
|
||||
return tvistruecond(L->top+1);
|
||||
L->top -= 2+LJ_FR2;
|
||||
return tvistruecond(L->top+1+LJ_FR2);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -306,8 +324,8 @@ LUA_API int lua_lessthan(lua_State *L, int idx1, int idx2)
|
|||
} else {
|
||||
L->top = base+2;
|
||||
lj_vm_call(L, base, 1+1);
|
||||
L->top -= 2;
|
||||
return tvistruecond(L->top+1);
|
||||
L->top -= 2+LJ_FR2;
|
||||
return tvistruecond(L->top+1+LJ_FR2);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -324,6 +342,22 @@ LUA_API lua_Number lua_tonumber(lua_State *L, int idx)
|
|||
return 0;
|
||||
}
|
||||
|
||||
LUA_API lua_Number lua_tonumberx(lua_State *L, int idx, int *ok)
|
||||
{
|
||||
cTValue *o = index2adr(L, idx);
|
||||
TValue tmp;
|
||||
if (LJ_LIKELY(tvisnumber(o))) {
|
||||
if (ok) *ok = 1;
|
||||
return numberVnum(o);
|
||||
} else if (tvisstr(o) && lj_strscan_num(strV(o), &tmp)) {
|
||||
if (ok) *ok = 1;
|
||||
return numV(&tmp);
|
||||
} else {
|
||||
if (ok) *ok = 0;
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
LUALIB_API lua_Number luaL_checknumber(lua_State *L, int idx)
|
||||
{
|
||||
cTValue *o = index2adr(L, idx);
|
||||
|
@ -361,7 +395,7 @@ LUA_API lua_Integer lua_tointeger(lua_State *L, int idx)
|
|||
if (!(tvisstr(o) && lj_strscan_number(strV(o), &tmp)))
|
||||
return 0;
|
||||
if (tvisint(&tmp))
|
||||
return (lua_Integer)intV(&tmp);
|
||||
return intV(&tmp);
|
||||
n = numV(&tmp);
|
||||
}
|
||||
#if LJ_64
|
||||
|
@ -371,6 +405,35 @@ LUA_API lua_Integer lua_tointeger(lua_State *L, int idx)
|
|||
#endif
|
||||
}
|
||||
|
||||
LUA_API lua_Integer lua_tointegerx(lua_State *L, int idx, int *ok)
|
||||
{
|
||||
cTValue *o = index2adr(L, idx);
|
||||
TValue tmp;
|
||||
lua_Number n;
|
||||
if (LJ_LIKELY(tvisint(o))) {
|
||||
if (ok) *ok = 1;
|
||||
return intV(o);
|
||||
} else if (LJ_LIKELY(tvisnum(o))) {
|
||||
n = numV(o);
|
||||
} else {
|
||||
if (!(tvisstr(o) && lj_strscan_number(strV(o), &tmp))) {
|
||||
if (ok) *ok = 0;
|
||||
return 0;
|
||||
}
|
||||
if (tvisint(&tmp)) {
|
||||
if (ok) *ok = 1;
|
||||
return intV(&tmp);
|
||||
}
|
||||
n = numV(&tmp);
|
||||
}
|
||||
if (ok) *ok = 1;
|
||||
#if LJ_64
|
||||
return (lua_Integer)n;
|
||||
#else
|
||||
return lj_num2int(n);
|
||||
#endif
|
||||
}
|
||||
|
||||
LUALIB_API lua_Integer luaL_checkinteger(lua_State *L, int idx)
|
||||
{
|
||||
cTValue *o = index2adr(L, idx);
|
||||
|
@ -434,7 +497,7 @@ LUA_API const char *lua_tolstring(lua_State *L, int idx, size_t *len)
|
|||
} else if (tvisnumber(o)) {
|
||||
lj_gc_check(L);
|
||||
o = index2adr(L, idx); /* GC may move the stack. */
|
||||
s = lj_str_fromnumber(L, o);
|
||||
s = lj_strfmt_number(L, o);
|
||||
setstrV(L, o, s);
|
||||
} else {
|
||||
if (len != NULL) *len = 0;
|
||||
|
@ -453,7 +516,7 @@ LUALIB_API const char *luaL_checklstring(lua_State *L, int idx, size_t *len)
|
|||
} else if (tvisnumber(o)) {
|
||||
lj_gc_check(L);
|
||||
o = index2adr(L, idx); /* GC may move the stack. */
|
||||
s = lj_str_fromnumber(L, o);
|
||||
s = lj_strfmt_number(L, o);
|
||||
setstrV(L, o, s);
|
||||
} else {
|
||||
lj_err_argt(L, idx, LUA_TSTRING);
|
||||
|
@ -475,7 +538,7 @@ LUALIB_API const char *luaL_optlstring(lua_State *L, int idx,
|
|||
} else if (tvisnumber(o)) {
|
||||
lj_gc_check(L);
|
||||
o = index2adr(L, idx); /* GC may move the stack. */
|
||||
s = lj_str_fromnumber(L, o);
|
||||
s = lj_strfmt_number(L, o);
|
||||
setstrV(L, o, s);
|
||||
} else {
|
||||
lj_err_argt(L, idx, LUA_TSTRING);
|
||||
|
@ -507,7 +570,7 @@ LUA_API size_t lua_objlen(lua_State *L, int idx)
|
|||
} else if (tvisudata(o)) {
|
||||
return udataV(o)->len;
|
||||
} else if (tvisnumber(o)) {
|
||||
GCstr *s = lj_str_fromnumber(L, o);
|
||||
GCstr *s = lj_strfmt_number(L, o);
|
||||
setstrV(L, o, s);
|
||||
return s->len;
|
||||
} else {
|
||||
|
@ -545,17 +608,7 @@ LUA_API lua_State *lua_tothread(lua_State *L, int idx)
|
|||
|
||||
LUA_API const void *lua_topointer(lua_State *L, int idx)
|
||||
{
|
||||
cTValue *o = index2adr(L, idx);
|
||||
if (tvisudata(o))
|
||||
return uddata(udataV(o));
|
||||
else if (tvislightud(o))
|
||||
return lightudV(o);
|
||||
else if (tviscdata(o))
|
||||
return cdataptr(cdataV(o));
|
||||
else if (tvisgcv(o))
|
||||
return gcV(o);
|
||||
else
|
||||
return NULL;
|
||||
return lj_obj_ptr(index2adr(L, idx));
|
||||
}
|
||||
|
||||
/* -- Stack setters (object creation) ------------------------------------- */
|
||||
|
@ -606,7 +659,7 @@ LUA_API const char *lua_pushvfstring(lua_State *L, const char *fmt,
|
|||
va_list argp)
|
||||
{
|
||||
lj_gc_check(L);
|
||||
return lj_str_pushvf(L, fmt, argp);
|
||||
return lj_strfmt_pushvf(L, fmt, argp);
|
||||
}
|
||||
|
||||
LUA_API const char *lua_pushfstring(lua_State *L, const char *fmt, ...)
|
||||
|
@ -615,7 +668,7 @@ LUA_API const char *lua_pushfstring(lua_State *L, const char *fmt, ...)
|
|||
va_list argp;
|
||||
lj_gc_check(L);
|
||||
va_start(argp, fmt);
|
||||
ret = lj_str_pushvf(L, fmt, argp);
|
||||
ret = lj_strfmt_pushvf(L, fmt, argp);
|
||||
va_end(argp);
|
||||
return ret;
|
||||
}
|
||||
|
@ -649,10 +702,8 @@ LUA_API void lua_pushlightuserdata(lua_State *L, void *p)
|
|||
|
||||
LUA_API void lua_createtable(lua_State *L, int narray, int nrec)
|
||||
{
|
||||
GCtab *t;
|
||||
lj_gc_check(L);
|
||||
t = lj_tab_new(L, (uint32_t)(narray > 0 ? narray+1 : 0), hsize2hbits(nrec));
|
||||
settabV(L, L->top, t);
|
||||
settabV(L, L->top, lj_tab_new_ah(L, narray, nrec));
|
||||
incr_top(L);
|
||||
}
|
||||
|
||||
|
@ -715,8 +766,8 @@ LUA_API void lua_concat(lua_State *L, int n)
|
|||
n -= (int)(L->top - top);
|
||||
L->top = top+2;
|
||||
lj_vm_call(L, top, 1+1);
|
||||
L->top--;
|
||||
copyTV(L, L->top-1, L->top);
|
||||
L->top -= 1+LJ_FR2;
|
||||
copyTV(L, L->top-1, L->top+LJ_FR2);
|
||||
} while (--n > 0);
|
||||
} else if (n == 0) { /* Push empty string. */
|
||||
setstrV(L, L->top, &G(L)->strempty);
|
||||
|
@ -735,8 +786,8 @@ LUA_API void lua_gettable(lua_State *L, int idx)
|
|||
if (v == NULL) {
|
||||
L->top += 2;
|
||||
lj_vm_call(L, L->top-2, 1+1);
|
||||
L->top -= 2;
|
||||
v = L->top+1;
|
||||
L->top -= 2+LJ_FR2;
|
||||
v = L->top+1+LJ_FR2;
|
||||
}
|
||||
copyTV(L, L->top-1, v);
|
||||
}
|
||||
|
@ -751,8 +802,8 @@ LUA_API void lua_getfield(lua_State *L, int idx, const char *k)
|
|||
if (v == NULL) {
|
||||
L->top += 2;
|
||||
lj_vm_call(L, L->top-2, 1+1);
|
||||
L->top -= 2;
|
||||
v = L->top+1;
|
||||
L->top -= 2+LJ_FR2;
|
||||
v = L->top+1+LJ_FR2;
|
||||
}
|
||||
copyTV(L, L->top, v);
|
||||
incr_top(L);
|
||||
|
@ -869,7 +920,7 @@ LUA_API void lua_upvaluejoin(lua_State *L, int idx1, int n1, int idx2, int n2)
|
|||
lj_gc_objbarrier(L, fn1, gcref(fn1->l.uvptr[n1]));
|
||||
}
|
||||
|
||||
LUALIB_API void *luaL_checkudata(lua_State *L, int idx, const char *tname)
|
||||
LUALIB_API void *luaL_testudata(lua_State *L, int idx, const char *tname)
|
||||
{
|
||||
cTValue *o = index2adr(L, idx);
|
||||
if (tvisudata(o)) {
|
||||
|
@ -878,8 +929,14 @@ LUALIB_API void *luaL_checkudata(lua_State *L, int idx, const char *tname)
|
|||
if (tv && tvistab(tv) && tabV(tv) == tabref(ud->metatable))
|
||||
return uddata(ud);
|
||||
}
|
||||
lj_err_argtype(L, idx, tname);
|
||||
return NULL; /* unreachable */
|
||||
return NULL; /* value is not a userdata with a metatable */
|
||||
}
|
||||
|
||||
LUALIB_API void *luaL_checkudata(lua_State *L, int idx, const char *tname)
|
||||
{
|
||||
void *p = luaL_testudata(L, idx, tname);
|
||||
if (!p) lj_err_argtype(L, idx, tname);
|
||||
return p;
|
||||
}
|
||||
|
||||
/* -- Object setters ------------------------------------------------------ */
|
||||
|
@ -893,13 +950,14 @@ LUA_API void lua_settable(lua_State *L, int idx)
|
|||
o = lj_meta_tset(L, t, L->top-2);
|
||||
if (o) {
|
||||
/* NOBARRIER: lj_meta_tset ensures the table is not black. */
|
||||
copyTV(L, o, L->top-1);
|
||||
L->top -= 2;
|
||||
copyTV(L, o, L->top+1);
|
||||
} else {
|
||||
L->top += 3;
|
||||
copyTV(L, L->top-1, L->top-6);
|
||||
lj_vm_call(L, L->top-3, 0+1);
|
||||
L->top -= 3;
|
||||
TValue *base = L->top;
|
||||
copyTV(L, base+2, base-3-2*LJ_FR2);
|
||||
L->top = base+3;
|
||||
lj_vm_call(L, base, 0+1);
|
||||
L->top -= 3+LJ_FR2;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -913,14 +971,14 @@ LUA_API void lua_setfield(lua_State *L, int idx, const char *k)
|
|||
setstrV(L, &key, lj_str_newz(L, k));
|
||||
o = lj_meta_tset(L, t, &key);
|
||||
if (o) {
|
||||
L->top--;
|
||||
/* NOBARRIER: lj_meta_tset ensures the table is not black. */
|
||||
copyTV(L, o, L->top);
|
||||
copyTV(L, o, --L->top);
|
||||
} else {
|
||||
L->top += 3;
|
||||
copyTV(L, L->top-1, L->top-6);
|
||||
lj_vm_call(L, L->top-3, 0+1);
|
||||
L->top -= 2;
|
||||
TValue *base = L->top;
|
||||
copyTV(L, base+2, base-3-2*LJ_FR2);
|
||||
L->top = base+3;
|
||||
lj_vm_call(L, base, 0+1);
|
||||
L->top -= 2+LJ_FR2;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -987,6 +1045,12 @@ LUA_API int lua_setmetatable(lua_State *L, int idx)
|
|||
return 1;
|
||||
}
|
||||
|
||||
LUALIB_API void luaL_setmetatable(lua_State *L, const char *tname)
|
||||
{
|
||||
lua_getfield(L, LUA_REGISTRYINDEX, tname);
|
||||
lua_setmetatable(L, -2);
|
||||
}
|
||||
|
||||
LUA_API int lua_setfenv(lua_State *L, int idx)
|
||||
{
|
||||
cTValue *o = index2adr(L, idx);
|
||||
|
@ -1027,11 +1091,24 @@ LUA_API const char *lua_setupvalue(lua_State *L, int idx, int n)
|
|||
|
||||
/* -- Calls --------------------------------------------------------------- */
|
||||
|
||||
#if LJ_FR2
|
||||
static TValue *api_call_base(lua_State *L, int nargs)
|
||||
{
|
||||
TValue *o = L->top, *base = o - nargs;
|
||||
L->top = o+1;
|
||||
for (; o > base; o--) copyTV(L, o, o-1);
|
||||
setnilV(o);
|
||||
return o+1;
|
||||
}
|
||||
#else
|
||||
#define api_call_base(L, nargs) (L->top - (nargs))
|
||||
#endif
|
||||
|
||||
LUA_API void lua_call(lua_State *L, int nargs, int nresults)
|
||||
{
|
||||
api_check(L, L->status == 0 || L->status == LUA_ERRERR);
|
||||
api_check(L, L->status == LUA_OK || L->status == LUA_ERRERR);
|
||||
api_checknelems(L, nargs+1);
|
||||
lj_vm_call(L, L->top - nargs, nresults+1);
|
||||
lj_vm_call(L, api_call_base(L, nargs), nresults+1);
|
||||
}
|
||||
|
||||
LUA_API int lua_pcall(lua_State *L, int nargs, int nresults, int errfunc)
|
||||
|
@ -1040,7 +1117,7 @@ LUA_API int lua_pcall(lua_State *L, int nargs, int nresults, int errfunc)
|
|||
uint8_t oldh = hook_save(g);
|
||||
ptrdiff_t ef;
|
||||
int status;
|
||||
api_check(L, L->status == 0 || L->status == LUA_ERRERR);
|
||||
api_check(L, L->status == LUA_OK || L->status == LUA_ERRERR);
|
||||
api_checknelems(L, nargs+1);
|
||||
if (errfunc == 0) {
|
||||
ef = 0;
|
||||
|
@ -1049,7 +1126,7 @@ LUA_API int lua_pcall(lua_State *L, int nargs, int nresults, int errfunc)
|
|||
api_checkvalidindex(L, o);
|
||||
ef = savestack(L, o);
|
||||
}
|
||||
status = lj_vm_pcall(L, L->top - nargs, nresults+1, ef);
|
||||
status = lj_vm_pcall(L, api_call_base(L, nargs), nresults+1, ef);
|
||||
if (status) hook_restore(g, oldh);
|
||||
return status;
|
||||
}
|
||||
|
@ -1057,12 +1134,14 @@ LUA_API int lua_pcall(lua_State *L, int nargs, int nresults, int errfunc)
|
|||
static TValue *cpcall(lua_State *L, lua_CFunction func, void *ud)
|
||||
{
|
||||
GCfunc *fn = lj_func_newC(L, 0, getcurrenv(L));
|
||||
TValue *top = L->top;
|
||||
fn->c.f = func;
|
||||
setfuncV(L, L->top, fn);
|
||||
setlightudV(L->top+1, checklightudptr(L, ud));
|
||||
setfuncV(L, top++, fn);
|
||||
if (LJ_FR2) setnilV(top++);
|
||||
setlightudV(top++, checklightudptr(L, ud));
|
||||
cframe_nres(L->cframe) = 1+0; /* Zero results. */
|
||||
L->top += 2;
|
||||
return L->top-1; /* Now call the newly allocated C function. */
|
||||
L->top = top;
|
||||
return top-1; /* Now call the newly allocated C function. */
|
||||
}
|
||||
|
||||
LUA_API int lua_cpcall(lua_State *L, lua_CFunction func, void *ud)
|
||||
|
@ -1070,7 +1149,7 @@ LUA_API int lua_cpcall(lua_State *L, lua_CFunction func, void *ud)
|
|||
global_State *g = G(L);
|
||||
uint8_t oldh = hook_save(g);
|
||||
int status;
|
||||
api_check(L, L->status == 0 || L->status == LUA_ERRERR);
|
||||
api_check(L, L->status == LUA_OK || L->status == LUA_ERRERR);
|
||||
status = lj_vm_cpcall(L, func, ud, cpcall);
|
||||
if (status) hook_restore(g, oldh);
|
||||
return status;
|
||||
|
@ -1079,10 +1158,11 @@ LUA_API int lua_cpcall(lua_State *L, lua_CFunction func, void *ud)
|
|||
LUALIB_API int luaL_callmeta(lua_State *L, int idx, const char *field)
|
||||
{
|
||||
if (luaL_getmetafield(L, idx, field)) {
|
||||
TValue *base = L->top--;
|
||||
copyTV(L, base, index2adr(L, idx));
|
||||
L->top = base+1;
|
||||
lj_vm_call(L, base, 1+1);
|
||||
TValue *top = L->top--;
|
||||
if (LJ_FR2) setnilV(top++);
|
||||
copyTV(L, top++, index2adr(L, idx));
|
||||
L->top = top;
|
||||
lj_vm_call(L, top-1, 1+1);
|
||||
return 1;
|
||||
}
|
||||
return 0;
|
||||
|
@ -1090,6 +1170,11 @@ LUALIB_API int luaL_callmeta(lua_State *L, int idx, const char *field)
|
|||
|
||||
/* -- Coroutine yield and resume ------------------------------------------ */
|
||||
|
||||
LUA_API int lua_isyieldable(lua_State *L)
|
||||
{
|
||||
return cframe_canyield(L->cframe);
|
||||
}
|
||||
|
||||
LUA_API int lua_yield(lua_State *L, int nresults)
|
||||
{
|
||||
void *cf = L->cframe;
|
||||
|
@ -1109,12 +1194,14 @@ LUA_API int lua_yield(lua_State *L, int nresults)
|
|||
} else { /* Yield from hook: add a pseudo-frame. */
|
||||
TValue *top = L->top;
|
||||
hook_leave(g);
|
||||
top->u64 = cframe_multres(cf);
|
||||
setcont(top+1, lj_cont_hook);
|
||||
setframe_pc(top+1, cframe_pc(cf)-1);
|
||||
setframe_gc(top+2, obj2gco(L));
|
||||
setframe_ftsz(top+2, (int)((char *)(top+3)-(char *)L->base)+FRAME_CONT);
|
||||
L->top = L->base = top+3;
|
||||
(top++)->u64 = cframe_multres(cf);
|
||||
setcont(top, lj_cont_hook);
|
||||
if (LJ_FR2) top++;
|
||||
setframe_pc(top, cframe_pc(cf)-1);
|
||||
if (LJ_FR2) top++;
|
||||
setframe_gc(top, obj2gco(L), LJ_TTHREAD);
|
||||
setframe_ftsz(top, ((char *)(top+1)-(char *)L->base)+FRAME_CONT);
|
||||
L->top = L->base = top+1;
|
||||
#if LJ_TARGET_X64
|
||||
lj_err_throw(L, LUA_YIELD);
|
||||
#else
|
||||
|
@ -1131,7 +1218,9 @@ LUA_API int lua_yield(lua_State *L, int nresults)
|
|||
LUA_API int lua_resume(lua_State *L, int nargs)
|
||||
{
|
||||
if (L->cframe == NULL && L->status <= LUA_YIELD)
|
||||
return lj_vm_resume(L, L->top - nargs, 0, 0);
|
||||
return lj_vm_resume(L,
|
||||
L->status == LUA_OK ? api_call_base(L, nargs) : L->top - nargs,
|
||||
0, 0);
|
||||
L->top = L->base;
|
||||
setstrV(L, L->top, lj_err_str(L, LJ_ERR_COSUSP));
|
||||
incr_top(L);
|
||||
|
@ -1161,7 +1250,7 @@ LUA_API int lua_gc(lua_State *L, int what, int data)
|
|||
res = (int)(g->gc.total & 0x3ff);
|
||||
break;
|
||||
case LUA_GCSTEP: {
|
||||
MSize a = (MSize)data << 10;
|
||||
GCSize a = (GCSize)data << 10;
|
||||
g->gc.threshold = (a <= g->gc.total) ? (g->gc.total - a) : 0;
|
||||
while (g->gc.total >= g->gc.threshold)
|
||||
if (lj_gc_step(L) > 0) {
|
||||
|
@ -1178,6 +1267,9 @@ LUA_API int lua_gc(lua_State *L, int what, int data)
|
|||
res = (int)(g->gc.stepmul);
|
||||
g->gc.stepmul = (MSize)data;
|
||||
break;
|
||||
case LUA_GCISRUNNING:
|
||||
res = (g->gc.threshold != LJ_MAX_MEM);
|
||||
break;
|
||||
default:
|
||||
res = -1; /* Invalid option. */
|
||||
}
|
||||
|
|
242
vendor/luajit/src/lj_arch.h
vendored
242
vendor/luajit/src/lj_arch.h
vendored
|
@ -1,6 +1,6 @@
|
|||
/*
|
||||
** Target architecture selection.
|
||||
** Copyright (C) 2005-2015 Mike Pall. See Copyright Notice in luajit.h
|
||||
** Copyright (C) 2005-2017 Mike Pall. See Copyright Notice in luajit.h
|
||||
*/
|
||||
|
||||
#ifndef _LJ_ARCH_H
|
||||
|
@ -19,12 +19,16 @@
|
|||
#define LUAJIT_ARCH_x64 2
|
||||
#define LUAJIT_ARCH_ARM 3
|
||||
#define LUAJIT_ARCH_arm 3
|
||||
#define LUAJIT_ARCH_PPC 4
|
||||
#define LUAJIT_ARCH_ppc 4
|
||||
#define LUAJIT_ARCH_PPCSPE 5
|
||||
#define LUAJIT_ARCH_ppcspe 5
|
||||
#define LUAJIT_ARCH_ARM64 4
|
||||
#define LUAJIT_ARCH_arm64 4
|
||||
#define LUAJIT_ARCH_PPC 5
|
||||
#define LUAJIT_ARCH_ppc 5
|
||||
#define LUAJIT_ARCH_MIPS 6
|
||||
#define LUAJIT_ARCH_mips 6
|
||||
#define LUAJIT_ARCH_MIPS32 6
|
||||
#define LUAJIT_ARCH_mips32 6
|
||||
#define LUAJIT_ARCH_MIPS64 7
|
||||
#define LUAJIT_ARCH_mips64 7
|
||||
|
||||
/* Target OS. */
|
||||
#define LUAJIT_OS_OTHER 0
|
||||
|
@ -43,14 +47,14 @@
|
|||
#define LUAJIT_TARGET LUAJIT_ARCH_X64
|
||||
#elif defined(__arm__) || defined(__arm) || defined(__ARM__) || defined(__ARM)
|
||||
#define LUAJIT_TARGET LUAJIT_ARCH_ARM
|
||||
#elif defined(__aarch64__)
|
||||
#define LUAJIT_TARGET LUAJIT_ARCH_ARM64
|
||||
#elif defined(__ppc__) || defined(__ppc) || defined(__PPC__) || defined(__PPC) || defined(__powerpc__) || defined(__powerpc) || defined(__POWERPC__) || defined(__POWERPC) || defined(_M_PPC)
|
||||
#ifdef __NO_FPRS__
|
||||
#define LUAJIT_TARGET LUAJIT_ARCH_PPCSPE
|
||||
#else
|
||||
#define LUAJIT_TARGET LUAJIT_ARCH_PPC
|
||||
#endif
|
||||
#elif defined(__mips64__) || defined(__mips64) || defined(__MIPS64__) || defined(__MIPS64)
|
||||
#define LUAJIT_TARGET LUAJIT_ARCH_MIPS64
|
||||
#elif defined(__mips__) || defined(__mips) || defined(__MIPS__) || defined(__MIPS)
|
||||
#define LUAJIT_TARGET LUAJIT_ARCH_MIPS
|
||||
#define LUAJIT_TARGET LUAJIT_ARCH_MIPS32
|
||||
#else
|
||||
#error "No support for this architecture (yet)"
|
||||
#endif
|
||||
|
@ -70,7 +74,10 @@
|
|||
defined(__NetBSD__) || defined(__OpenBSD__) || \
|
||||
defined(__DragonFly__)) && !defined(__ORBIS__)
|
||||
#define LUAJIT_OS LUAJIT_OS_BSD
|
||||
#elif (defined(__sun__) && defined(__svr4__)) || defined(__CYGWIN__)
|
||||
#elif (defined(__sun__) && defined(__svr4__)) || defined(__HAIKU__)
|
||||
#define LUAJIT_OS LUAJIT_OS_POSIX
|
||||
#elif defined(__CYGWIN__)
|
||||
#define LJ_TARGET_CYGWIN 1
|
||||
#define LUAJIT_OS LUAJIT_OS_POSIX
|
||||
#else
|
||||
#define LUAJIT_OS LUAJIT_OS_OTHER
|
||||
|
@ -96,7 +103,7 @@
|
|||
#define LJ_TARGET_WINDOWS (LUAJIT_OS == LUAJIT_OS_WINDOWS)
|
||||
#define LJ_TARGET_LINUX (LUAJIT_OS == LUAJIT_OS_LINUX)
|
||||
#define LJ_TARGET_OSX (LUAJIT_OS == LUAJIT_OS_OSX)
|
||||
#define LJ_TARGET_IOS (LJ_TARGET_OSX && LUAJIT_TARGET == LUAJIT_ARCH_ARM)
|
||||
#define LJ_TARGET_IOS (LJ_TARGET_OSX && (LUAJIT_TARGET == LUAJIT_ARCH_ARM || LUAJIT_TARGET == LUAJIT_ARCH_ARM64))
|
||||
#define LJ_TARGET_POSIX (LUAJIT_OS > LUAJIT_OS_WINDOWS)
|
||||
#define LJ_TARGET_DLOPEN LJ_TARGET_POSIX
|
||||
|
||||
|
@ -122,6 +129,12 @@
|
|||
#define LJ_TARGET_CONSOLE 1
|
||||
#endif
|
||||
|
||||
#ifdef _DURANGO
|
||||
#define LJ_TARGET_XBOXONE 1
|
||||
#define LJ_TARGET_CONSOLE 1
|
||||
#define LJ_TARGET_GC64 1
|
||||
#endif
|
||||
|
||||
#define LJ_NUMMODE_SINGLE 0 /* Single-number mode only. */
|
||||
#define LJ_NUMMODE_SINGLE_DUAL 1 /* Default to single-number mode. */
|
||||
#define LJ_NUMMODE_DUAL 2 /* Dual-number mode only. */
|
||||
|
@ -133,7 +146,7 @@
|
|||
#define LJ_ARCH_NAME "x86"
|
||||
#define LJ_ARCH_BITS 32
|
||||
#define LJ_ARCH_ENDIAN LUAJIT_LE
|
||||
#if LJ_TARGET_WINDOWS || __CYGWIN__
|
||||
#if LJ_TARGET_WINDOWS || LJ_TARGET_CYGWIN
|
||||
#define LJ_ABI_WIN 1
|
||||
#else
|
||||
#define LJ_ABI_WIN 0
|
||||
|
@ -151,7 +164,11 @@
|
|||
#define LJ_ARCH_NAME "x64"
|
||||
#define LJ_ARCH_BITS 64
|
||||
#define LJ_ARCH_ENDIAN LUAJIT_LE
|
||||
#define LJ_ABI_WIN LJ_TARGET_WINDOWS
|
||||
#if LJ_TARGET_WINDOWS || LJ_TARGET_CYGWIN
|
||||
#define LJ_ABI_WIN 1
|
||||
#else
|
||||
#define LJ_ABI_WIN 0
|
||||
#endif
|
||||
#define LJ_TARGET_X64 1
|
||||
#define LJ_TARGET_X86ORX64 1
|
||||
#define LJ_TARGET_EHRETREG 0
|
||||
|
@ -160,6 +177,9 @@
|
|||
#define LJ_TARGET_MASKROT 1
|
||||
#define LJ_TARGET_UNALIGNED 1
|
||||
#define LJ_ARCH_NUMMODE LJ_NUMMODE_SINGLE_DUAL
|
||||
#ifdef LUAJIT_ENABLE_GC64
|
||||
#define LJ_TARGET_GC64 1
|
||||
#endif
|
||||
|
||||
#elif LUAJIT_TARGET == LUAJIT_ARCH_ARM
|
||||
|
||||
|
@ -193,15 +213,49 @@
|
|||
#define LJ_ARCH_VERSION 50
|
||||
#endif
|
||||
|
||||
#elif LUAJIT_TARGET == LUAJIT_ARCH_ARM64
|
||||
|
||||
#define LJ_ARCH_BITS 64
|
||||
#if defined(__AARCH64EB__)
|
||||
#define LJ_ARCH_NAME "arm64be"
|
||||
#define LJ_ARCH_ENDIAN LUAJIT_BE
|
||||
#else
|
||||
#define LJ_ARCH_NAME "arm64"
|
||||
#define LJ_ARCH_ENDIAN LUAJIT_LE
|
||||
#endif
|
||||
#define LJ_TARGET_ARM64 1
|
||||
#define LJ_TARGET_EHRETREG 0
|
||||
#define LJ_TARGET_JUMPRANGE 27 /* +-2^27 = +-128MB */
|
||||
#define LJ_TARGET_MASKSHIFT 1
|
||||
#define LJ_TARGET_MASKROT 1
|
||||
#define LJ_TARGET_UNIFYROT 2 /* Want only IR_BROR. */
|
||||
#define LJ_TARGET_GC64 1
|
||||
#define LJ_ARCH_NUMMODE LJ_NUMMODE_DUAL
|
||||
|
||||
#define LJ_ARCH_VERSION 80
|
||||
|
||||
#elif LUAJIT_TARGET == LUAJIT_ARCH_PPC
|
||||
|
||||
#define LJ_ARCH_NAME "ppc"
|
||||
#ifndef LJ_ARCH_ENDIAN
|
||||
#if __BYTE_ORDER__ != __ORDER_BIG_ENDIAN__
|
||||
#define LJ_ARCH_ENDIAN LUAJIT_LE
|
||||
#else
|
||||
#define LJ_ARCH_ENDIAN LUAJIT_BE
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#if _LP64
|
||||
#define LJ_ARCH_BITS 64
|
||||
#if LJ_ARCH_ENDIAN == LUAJIT_LE
|
||||
#define LJ_ARCH_NAME "ppc64le"
|
||||
#else
|
||||
#define LJ_ARCH_NAME "ppc64"
|
||||
#endif
|
||||
#else
|
||||
#define LJ_ARCH_BITS 32
|
||||
#define LJ_ARCH_NAME "ppc"
|
||||
#endif
|
||||
#define LJ_ARCH_ENDIAN LUAJIT_BE
|
||||
|
||||
#define LJ_TARGET_PPC 1
|
||||
#define LJ_TARGET_EHRETREG 3
|
||||
#define LJ_TARGET_JUMPRANGE 25 /* +-2^25 = +-32MB */
|
||||
|
@ -210,6 +264,15 @@
|
|||
#define LJ_TARGET_UNIFYROT 1 /* Want only IR_BROL. */
|
||||
#define LJ_ARCH_NUMMODE LJ_NUMMODE_DUAL_SINGLE
|
||||
|
||||
#if LJ_TARGET_CONSOLE
|
||||
#define LJ_ARCH_PPC32ON64 1
|
||||
#define LJ_ARCH_NOFFI 1
|
||||
#elif LJ_ARCH_BITS == 64
|
||||
#define LJ_ARCH_PPC64 1
|
||||
#define LJ_TARGET_GC64 1
|
||||
#define LJ_ARCH_NOJIT 1 /* NYI */
|
||||
#endif
|
||||
|
||||
#if _ARCH_PWR7
|
||||
#define LJ_ARCH_VERSION 70
|
||||
#elif _ARCH_PWR6
|
||||
|
@ -223,10 +286,6 @@
|
|||
#else
|
||||
#define LJ_ARCH_VERSION 0
|
||||
#endif
|
||||
#if __PPC64__ || __powerpc64__ || LJ_TARGET_CONSOLE
|
||||
#define LJ_ARCH_PPC64 1
|
||||
#define LJ_ARCH_NOFFI 1
|
||||
#endif
|
||||
#if _ARCH_PPCSQ
|
||||
#define LJ_ARCH_SQRT 1
|
||||
#endif
|
||||
|
@ -240,44 +299,60 @@
|
|||
#define LJ_ARCH_XENON 1
|
||||
#endif
|
||||
|
||||
#elif LUAJIT_TARGET == LUAJIT_ARCH_PPCSPE
|
||||
|
||||
#define LJ_ARCH_NAME "ppcspe"
|
||||
#define LJ_ARCH_BITS 32
|
||||
#define LJ_ARCH_ENDIAN LUAJIT_BE
|
||||
#ifndef LJ_ABI_SOFTFP
|
||||
#define LJ_ABI_SOFTFP 1
|
||||
#endif
|
||||
#define LJ_ABI_EABI 1
|
||||
#define LJ_TARGET_PPCSPE 1
|
||||
#define LJ_TARGET_EHRETREG 3
|
||||
#define LJ_TARGET_JUMPRANGE 25 /* +-2^25 = +-32MB */
|
||||
#define LJ_TARGET_MASKSHIFT 0
|
||||
#define LJ_TARGET_MASKROT 1
|
||||
#define LJ_TARGET_UNIFYROT 1 /* Want only IR_BROL. */
|
||||
#define LJ_ARCH_NUMMODE LJ_NUMMODE_SINGLE
|
||||
#define LJ_ARCH_NOFFI 1 /* NYI: comparisons, calls. */
|
||||
#define LJ_ARCH_NOJIT 1
|
||||
|
||||
#elif LUAJIT_TARGET == LUAJIT_ARCH_MIPS
|
||||
#elif LUAJIT_TARGET == LUAJIT_ARCH_MIPS32 || LUAJIT_TARGET == LUAJIT_ARCH_MIPS64
|
||||
|
||||
#if defined(__MIPSEL__) || defined(__MIPSEL) || defined(_MIPSEL)
|
||||
#if LUAJIT_TARGET == LUAJIT_ARCH_MIPS32
|
||||
#define LJ_ARCH_NAME "mipsel"
|
||||
#else
|
||||
#define LJ_ARCH_NAME "mips64el"
|
||||
#endif
|
||||
#define LJ_ARCH_ENDIAN LUAJIT_LE
|
||||
#else
|
||||
#if LUAJIT_TARGET == LUAJIT_ARCH_MIPS32
|
||||
#define LJ_ARCH_NAME "mips"
|
||||
#else
|
||||
#define LJ_ARCH_NAME "mips64"
|
||||
#endif
|
||||
#define LJ_ARCH_ENDIAN LUAJIT_BE
|
||||
#endif
|
||||
|
||||
#if !defined(LJ_ARCH_HASFPU)
|
||||
#ifdef __mips_soft_float
|
||||
#define LJ_ARCH_HASFPU 0
|
||||
#else
|
||||
#define LJ_ARCH_HASFPU 1
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#if !defined(LJ_ABI_SOFTFP)
|
||||
#ifdef __mips_soft_float
|
||||
#define LJ_ABI_SOFTFP 1
|
||||
#else
|
||||
#define LJ_ABI_SOFTFP 0
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#if LUAJIT_TARGET == LUAJIT_ARCH_MIPS32
|
||||
#define LJ_ARCH_BITS 32
|
||||
#define LJ_TARGET_MIPS32 1
|
||||
#else
|
||||
#if LJ_ABI_SOFTFP || !LJ_ARCH_HASFPU
|
||||
#define LJ_ARCH_NOJIT 1 /* NYI */
|
||||
#endif
|
||||
#define LJ_ARCH_BITS 64
|
||||
#define LJ_TARGET_MIPS64 1
|
||||
#define LJ_TARGET_GC64 1
|
||||
#endif
|
||||
#define LJ_TARGET_MIPS 1
|
||||
#define LJ_TARGET_EHRETREG 4
|
||||
#define LJ_TARGET_JUMPRANGE 27 /* 2*2^27 = 256MB-aligned region */
|
||||
#define LJ_TARGET_MASKSHIFT 1
|
||||
#define LJ_TARGET_MASKROT 1
|
||||
#define LJ_TARGET_UNIFYROT 2 /* Want only IR_BROR. */
|
||||
#define LJ_ARCH_NUMMODE LJ_NUMMODE_SINGLE
|
||||
#define LJ_ARCH_NUMMODE LJ_NUMMODE_DUAL
|
||||
|
||||
#if _MIPS_ARCH_MIPS32R2
|
||||
#if _MIPS_ARCH_MIPS32R2 || _MIPS_ARCH_MIPS64R2
|
||||
#define LJ_ARCH_VERSION 20
|
||||
#else
|
||||
#define LJ_ARCH_VERSION 10
|
||||
|
@ -305,6 +380,16 @@
|
|||
#if (__GNUC__ < 4) || ((__GNUC__ == 4) && __GNUC_MINOR__ < 2)
|
||||
#error "Need at least GCC 4.2 or newer"
|
||||
#endif
|
||||
#elif LJ_TARGET_ARM64
|
||||
#if __clang__
|
||||
#if ((__clang_major__ < 3) || ((__clang_major__ == 3) && __clang_minor__ < 5)) && !defined(__NX_TOOLCHAIN_MAJOR__)
|
||||
#error "Need at least Clang 3.5 or newer"
|
||||
#endif
|
||||
#else
|
||||
#if (__GNUC__ < 4) || ((__GNUC__ == 4) && __GNUC_MINOR__ < 8)
|
||||
#error "Need at least GCC 4.8 or newer"
|
||||
#endif
|
||||
#endif
|
||||
#elif !LJ_TARGET_PS3
|
||||
#if (__GNUC__ < 4) || ((__GNUC__ == 4) && __GNUC_MINOR__ < 3)
|
||||
#error "Need at least GCC 4.3 or newer"
|
||||
|
@ -328,22 +413,30 @@
|
|||
#if !(__ARM_EABI__ || LJ_TARGET_IOS)
|
||||
#error "Only ARM EABI or iOS 3.0+ ABI is supported"
|
||||
#endif
|
||||
#elif LJ_TARGET_PPC || LJ_TARGET_PPCSPE
|
||||
#elif LJ_TARGET_ARM64
|
||||
#if defined(_ILP32)
|
||||
#error "No support for ILP32 model on ARM64"
|
||||
#endif
|
||||
#elif LJ_TARGET_PPC
|
||||
#if defined(_SOFT_FLOAT) || defined(_SOFT_DOUBLE)
|
||||
#error "No support for PowerPC CPUs without double-precision FPU"
|
||||
#endif
|
||||
#if defined(_LITTLE_ENDIAN)
|
||||
#error "No support for little-endian PowerPC"
|
||||
#if !LJ_ARCH_PPC64 && LJ_ARCH_ENDIAN == LUAJIT_LE
|
||||
#error "No support for little-endian PPC32"
|
||||
#endif
|
||||
#if defined(_LP64)
|
||||
#error "No support for PowerPC 64 bit mode"
|
||||
#if LJ_ARCH_PPC64
|
||||
#error "No support for PowerPC 64 bit mode (yet)"
|
||||
#endif
|
||||
#elif LJ_TARGET_MIPS
|
||||
#if defined(__mips_soft_float)
|
||||
#error "No support for MIPS CPUs without FPU"
|
||||
#ifdef __NO_FPRS__
|
||||
#error "No support for PPC/e500 anymore (use LuaJIT 2.0)"
|
||||
#endif
|
||||
#if defined(_LP64)
|
||||
#error "No support for MIPS64"
|
||||
#elif LJ_TARGET_MIPS32
|
||||
#if !((defined(_MIPS_SIM_ABI32) && _MIPS_SIM == _MIPS_SIM_ABI32) || (defined(_ABIO32) && _MIPS_SIM == _ABIO32))
|
||||
#error "Only o32 ABI supported for MIPS32"
|
||||
#endif
|
||||
#elif LJ_TARGET_MIPS64
|
||||
#if !((defined(_MIPS_SIM_ABI64) && _MIPS_SIM == _MIPS_SIM_ABI64) || (defined(_ABI64) && _MIPS_SIM == _ABI64))
|
||||
#error "Only n64 ABI supported for MIPS64"
|
||||
#endif
|
||||
#endif
|
||||
#endif
|
||||
|
@ -369,6 +462,20 @@
|
|||
#endif
|
||||
#endif
|
||||
|
||||
/* 64 bit GC references. */
|
||||
#if LJ_TARGET_GC64
|
||||
#define LJ_GC64 1
|
||||
#else
|
||||
#define LJ_GC64 0
|
||||
#endif
|
||||
|
||||
/* 2-slot frame info. */
|
||||
#if LJ_GC64
|
||||
#define LJ_FR2 1
|
||||
#else
|
||||
#define LJ_FR2 0
|
||||
#endif
|
||||
|
||||
/* Disable or enable the JIT compiler. */
|
||||
#if defined(LUAJIT_DISABLE_JIT) || defined(LJ_ARCH_NOJIT) || defined(LJ_OS_NOJIT)
|
||||
#define LJ_HASJIT 0
|
||||
|
@ -383,6 +490,21 @@
|
|||
#define LJ_HASFFI 1
|
||||
#endif
|
||||
|
||||
#if defined(LUAJIT_DISABLE_PROFILE)
|
||||
#define LJ_HASPROFILE 0
|
||||
#elif LJ_TARGET_POSIX
|
||||
#define LJ_HASPROFILE 1
|
||||
#define LJ_PROFILE_SIGPROF 1
|
||||
#elif LJ_TARGET_PS3
|
||||
#define LJ_HASPROFILE 1
|
||||
#define LJ_PROFILE_PTHREAD 1
|
||||
#elif LJ_TARGET_WINDOWS || LJ_TARGET_XBOX360
|
||||
#define LJ_HASPROFILE 1
|
||||
#define LJ_PROFILE_WTHREAD 1
|
||||
#else
|
||||
#define LJ_HASPROFILE 0
|
||||
#endif
|
||||
|
||||
#ifndef LJ_ARCH_HASFPU
|
||||
#define LJ_ARCH_HASFPU 1
|
||||
#endif
|
||||
|
@ -415,15 +537,23 @@
|
|||
#define LJ_TARGET_UNALIGNED 0
|
||||
#endif
|
||||
|
||||
/* Various workarounds for embedded operating systems. */
|
||||
#if (defined(__ANDROID__) && !defined(LJ_TARGET_X86ORX64)) || defined(__symbian__) || LJ_TARGET_XBOX360
|
||||
/* Various workarounds for embedded operating systems or weak C runtimes. */
|
||||
#if defined(__ANDROID__) || defined(__symbian__) || LJ_TARGET_XBOX360 || LJ_TARGET_WINDOWS
|
||||
#define LUAJIT_NO_LOG2
|
||||
#endif
|
||||
#if defined(__symbian__)
|
||||
#if defined(__symbian__) || LJ_TARGET_WINDOWS
|
||||
#define LUAJIT_NO_EXP2
|
||||
#endif
|
||||
#if LJ_TARGET_CONSOLE || (LJ_TARGET_IOS && __IPHONE_OS_VERSION_MIN_REQUIRED >= __IPHONE_8_0)
|
||||
#define LJ_NO_SYSTEM 1
|
||||
#endif
|
||||
|
||||
#if defined(LUAJIT_NO_UNWIND) || defined(__symbian__) || LJ_TARGET_IOS || LJ_TARGET_PS3
|
||||
#if !defined(LUAJIT_NO_UNWIND) && __GNU_COMPACT_EH__
|
||||
/* NYI: no support for compact unwind specification, yet. */
|
||||
#define LUAJIT_NO_UNWIND 1
|
||||
#endif
|
||||
|
||||
#if defined(LUAJIT_NO_UNWIND) || defined(__symbian__) || LJ_TARGET_IOS || LJ_TARGET_PS3 || LJ_TARGET_PS4
|
||||
#define LJ_NO_UNWIND 1
|
||||
#endif
|
||||
|
||||
|
|
724
vendor/luajit/src/lj_asm.c
vendored
724
vendor/luajit/src/lj_asm.c
vendored
|
@ -1,6 +1,6 @@
|
|||
/*
|
||||
** IR assembler (SSA IR -> machine code).
|
||||
** Copyright (C) 2005-2015 Mike Pall. See Copyright Notice in luajit.h
|
||||
** Copyright (C) 2005-2017 Mike Pall. See Copyright Notice in luajit.h
|
||||
*/
|
||||
|
||||
#define lj_asm_c
|
||||
|
@ -91,7 +91,7 @@ typedef struct ASMState {
|
|||
MCode *realign; /* Realign loop if not NULL. */
|
||||
|
||||
#ifdef RID_NUM_KREF
|
||||
int32_t krefk[RID_NUM_KREF];
|
||||
intptr_t krefk[RID_NUM_KREF];
|
||||
#endif
|
||||
IRRef1 phireg[RID_MAX]; /* PHI register references. */
|
||||
uint16_t parentmap[LJ_MAX_JSLOTS]; /* Parent instruction to RegSP map. */
|
||||
|
@ -144,7 +144,7 @@ static LJ_AINLINE void checkmclim(ASMState *as)
|
|||
#define ra_krefreg(ref) ((Reg)(RID_MIN_KREF + (Reg)(ref)))
|
||||
#define ra_krefk(as, ref) (as->krefk[(ref)])
|
||||
|
||||
static LJ_AINLINE void ra_setkref(ASMState *as, Reg r, int32_t k)
|
||||
static LJ_AINLINE void ra_setkref(ASMState *as, Reg r, intptr_t k)
|
||||
{
|
||||
IRRef ref = (IRRef)(r - RID_MIN_KREF);
|
||||
as->krefk[ref] = k;
|
||||
|
@ -171,6 +171,8 @@ IRFLDEF(FLOFS)
|
|||
#include "lj_emit_x86.h"
|
||||
#elif LJ_TARGET_ARM
|
||||
#include "lj_emit_arm.h"
|
||||
#elif LJ_TARGET_ARM64
|
||||
#include "lj_emit_arm64.h"
|
||||
#elif LJ_TARGET_PPC
|
||||
#include "lj_emit_ppc.h"
|
||||
#elif LJ_TARGET_MIPS
|
||||
|
@ -179,6 +181,12 @@ IRFLDEF(FLOFS)
|
|||
#error "Missing instruction emitter for target CPU"
|
||||
#endif
|
||||
|
||||
/* Generic load/store of register from/to stack slot. */
|
||||
#define emit_spload(as, ir, r, ofs) \
|
||||
emit_loadofs(as, ir, (r), RID_SP, (ofs))
|
||||
#define emit_spstore(as, ir, r, ofs) \
|
||||
emit_storeofs(as, ir, (r), RID_SP, (ofs))
|
||||
|
||||
/* -- Register allocator debugging ---------------------------------------- */
|
||||
|
||||
/* #define LUAJIT_DEBUG_RA */
|
||||
|
@ -316,7 +324,11 @@ static Reg ra_rematk(ASMState *as, IRRef ref)
|
|||
lua_assert(!rset_test(as->freeset, r));
|
||||
ra_free(as, r);
|
||||
ra_modified(as, r);
|
||||
#if LJ_64
|
||||
emit_loadu64(as, r, ra_krefk(as, ref));
|
||||
#else
|
||||
emit_loadi(as, r, ra_krefk(as, ref));
|
||||
#endif
|
||||
return r;
|
||||
}
|
||||
ir = IR(ref);
|
||||
|
@ -328,7 +340,7 @@ static Reg ra_rematk(ASMState *as, IRRef ref)
|
|||
RA_DBGX((as, "remat $i $r", ir, r));
|
||||
#if !LJ_SOFTFP
|
||||
if (ir->o == IR_KNUM) {
|
||||
emit_loadn(as, r, ir_knum(ir));
|
||||
emit_loadk64(as, r, ir);
|
||||
} else
|
||||
#endif
|
||||
if (emit_canremat(REF_BASE) && ir->o == IR_BASE) {
|
||||
|
@ -336,10 +348,16 @@ static Reg ra_rematk(ASMState *as, IRRef ref)
|
|||
emit_getgl(as, r, jit_base);
|
||||
} else if (emit_canremat(ASMREF_L) && ir->o == IR_KPRI) {
|
||||
lua_assert(irt_isnil(ir->t)); /* REF_NIL stores ASMREF_L register. */
|
||||
emit_getgl(as, r, jit_L);
|
||||
emit_getgl(as, r, cur_L);
|
||||
#if LJ_64
|
||||
} else if (ir->o == IR_KINT64) {
|
||||
emit_loadu64(as, r, ir_kint64(ir)->u64);
|
||||
#if LJ_GC64
|
||||
} else if (ir->o == IR_KGC) {
|
||||
emit_loadu64(as, r, (uintptr_t)ir_kgc(ir));
|
||||
} else if (ir->o == IR_KPTR || ir->o == IR_KKPTR) {
|
||||
emit_loadu64(as, r, (uintptr_t)ir_kptr(ir));
|
||||
#endif
|
||||
#endif
|
||||
} else {
|
||||
lua_assert(ir->o == IR_KINT || ir->o == IR_KGC ||
|
||||
|
@ -512,7 +530,7 @@ static void ra_evictk(ASMState *as)
|
|||
|
||||
#ifdef RID_NUM_KREF
|
||||
/* Allocate a register for a constant. */
|
||||
static Reg ra_allock(ASMState *as, int32_t k, RegSet allow)
|
||||
static Reg ra_allock(ASMState *as, intptr_t k, RegSet allow)
|
||||
{
|
||||
/* First try to find a register which already holds the same constant. */
|
||||
RegSet pick, work = ~as->freeset & RSET_GPR;
|
||||
|
@ -521,9 +539,31 @@ static Reg ra_allock(ASMState *as, int32_t k, RegSet allow)
|
|||
IRRef ref;
|
||||
r = rset_pickbot(work);
|
||||
ref = regcost_ref(as->cost[r]);
|
||||
#if LJ_64
|
||||
if (ref < ASMREF_L) {
|
||||
if (ra_iskref(ref)) {
|
||||
if (k == ra_krefk(as, ref))
|
||||
return r;
|
||||
} else {
|
||||
IRIns *ir = IR(ref);
|
||||
if ((ir->o == IR_KINT64 && k == (int64_t)ir_kint64(ir)->u64) ||
|
||||
#if LJ_GC64
|
||||
(ir->o == IR_KINT && k == ir->i) ||
|
||||
(ir->o == IR_KGC && k == (intptr_t)ir_kgc(ir)) ||
|
||||
((ir->o == IR_KPTR || ir->o == IR_KKPTR) &&
|
||||
k == (intptr_t)ir_kptr(ir))
|
||||
#else
|
||||
(ir->o != IR_KINT64 && k == ir->i)
|
||||
#endif
|
||||
)
|
||||
return r;
|
||||
}
|
||||
}
|
||||
#else
|
||||
if (ref < ASMREF_L &&
|
||||
k == (ra_iskref(ref) ? ra_krefk(as, ref) : IR(ref)->i))
|
||||
return r;
|
||||
#endif
|
||||
rset_clear(work, r);
|
||||
}
|
||||
pick = as->freeset & allow;
|
||||
|
@ -543,7 +583,7 @@ static Reg ra_allock(ASMState *as, int32_t k, RegSet allow)
|
|||
}
|
||||
|
||||
/* Allocate a specific register for a constant. */
|
||||
static void ra_allockreg(ASMState *as, int32_t k, Reg r)
|
||||
static void ra_allockreg(ASMState *as, intptr_t k, Reg r)
|
||||
{
|
||||
Reg kr = ra_allock(as, k, RID2RSET(r));
|
||||
if (kr != r) {
|
||||
|
@ -613,10 +653,20 @@ static Reg ra_alloc1(ASMState *as, IRRef ref, RegSet allow)
|
|||
return r;
|
||||
}
|
||||
|
||||
/* Add a register rename to the IR. */
|
||||
static void ra_addrename(ASMState *as, Reg down, IRRef ref, SnapNo snapno)
|
||||
{
|
||||
IRRef ren;
|
||||
lj_ir_set(as->J, IRT(IR_RENAME, IRT_NIL), ref, snapno);
|
||||
ren = tref_ref(lj_ir_emit(as->J));
|
||||
as->J->cur.ir[ren].r = (uint8_t)down;
|
||||
as->J->cur.ir[ren].s = SPS_NONE;
|
||||
}
|
||||
|
||||
/* Rename register allocation and emit move. */
|
||||
static void ra_rename(ASMState *as, Reg down, Reg up)
|
||||
{
|
||||
IRRef ren, ref = regcost_ref(as->cost[up] = as->cost[down]);
|
||||
IRRef ref = regcost_ref(as->cost[up] = as->cost[down]);
|
||||
IRIns *ir = IR(ref);
|
||||
ir->r = (uint8_t)up;
|
||||
as->cost[down] = 0;
|
||||
|
@ -629,11 +679,7 @@ static void ra_rename(ASMState *as, Reg down, Reg up)
|
|||
RA_DBGX((as, "rename $f $r $r", regcost_ref(as->cost[up]), down, up));
|
||||
emit_movrr(as, ir, down, up); /* Backwards codegen needs inverse move. */
|
||||
if (!ra_hasspill(IR(ref)->s)) { /* Add the rename to the IR. */
|
||||
lj_ir_set(as->J, IRT(IR_RENAME, IRT_NIL), ref, as->snapno);
|
||||
ren = tref_ref(lj_ir_emit(as->J));
|
||||
as->ir = as->T->ir; /* The IR may have been reallocated. */
|
||||
IR(ren)->r = (uint8_t)down;
|
||||
IR(ren)->s = SPS_NONE;
|
||||
ra_addrename(as, down, ref, as->snapno);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -683,18 +729,22 @@ static void ra_left(ASMState *as, Reg dest, IRRef lref)
|
|||
if (ra_noreg(left)) {
|
||||
if (irref_isk(lref)) {
|
||||
if (ir->o == IR_KNUM) {
|
||||
cTValue *tv = ir_knum(ir);
|
||||
/* FP remat needs a load except for +0. Still better than eviction. */
|
||||
if (tvispzero(tv) || !(as->freeset & RSET_FPR)) {
|
||||
emit_loadn(as, dest, tv);
|
||||
if (tvispzero(ir_knum(ir)) || !(as->freeset & RSET_FPR)) {
|
||||
emit_loadk64(as, dest, ir);
|
||||
return;
|
||||
}
|
||||
#if LJ_64
|
||||
} else if (ir->o == IR_KINT64) {
|
||||
emit_loadu64(as, dest, ir_kint64(ir)->u64);
|
||||
emit_loadk64(as, dest, ir);
|
||||
return;
|
||||
#if LJ_GC64
|
||||
} else if (ir->o == IR_KGC || ir->o == IR_KPTR || ir->o == IR_KKPTR) {
|
||||
emit_loadk64(as, dest, ir);
|
||||
return;
|
||||
#endif
|
||||
} else {
|
||||
#endif
|
||||
} else if (ir->o != IR_KPRI) {
|
||||
lua_assert(ir->o == IR_KINT || ir->o == IR_KGC ||
|
||||
ir->o == IR_KPTR || ir->o == IR_KKPTR || ir->o == IR_KNULL);
|
||||
emit_loadi(as, dest, ir->i);
|
||||
|
@ -935,7 +985,7 @@ static void asm_snap_prep(ASMState *as)
|
|||
} else {
|
||||
/* Process any renames above the highwater mark. */
|
||||
for (; as->snaprename < as->T->nins; as->snaprename++) {
|
||||
IRIns *ir = IR(as->snaprename);
|
||||
IRIns *ir = &as->T->ir[as->snaprename];
|
||||
if (asm_snap_checkrename(as, ir->op1))
|
||||
ir->op2 = REF_BIAS-1; /* Kill rename. */
|
||||
}
|
||||
|
@ -944,44 +994,6 @@ static void asm_snap_prep(ASMState *as)
|
|||
|
||||
/* -- Miscellaneous helpers ----------------------------------------------- */
|
||||
|
||||
/* Collect arguments from CALL* and CARG instructions. */
|
||||
static void asm_collectargs(ASMState *as, IRIns *ir,
|
||||
const CCallInfo *ci, IRRef *args)
|
||||
{
|
||||
uint32_t n = CCI_NARGS(ci);
|
||||
lua_assert(n <= CCI_NARGS_MAX*2); /* Account for split args. */
|
||||
if ((ci->flags & CCI_L)) { *args++ = ASMREF_L; n--; }
|
||||
while (n-- > 1) {
|
||||
ir = IR(ir->op1);
|
||||
lua_assert(ir->o == IR_CARG);
|
||||
args[n] = ir->op2 == REF_NIL ? 0 : ir->op2;
|
||||
}
|
||||
args[0] = ir->op1 == REF_NIL ? 0 : ir->op1;
|
||||
lua_assert(IR(ir->op1)->o != IR_CARG);
|
||||
}
|
||||
|
||||
/* Reconstruct CCallInfo flags for CALLX*. */
|
||||
static uint32_t asm_callx_flags(ASMState *as, IRIns *ir)
|
||||
{
|
||||
uint32_t nargs = 0;
|
||||
if (ir->op1 != REF_NIL) { /* Count number of arguments first. */
|
||||
IRIns *ira = IR(ir->op1);
|
||||
nargs++;
|
||||
while (ira->o == IR_CARG) { nargs++; ira = IR(ira->op1); }
|
||||
}
|
||||
#if LJ_HASFFI
|
||||
if (IR(ir->op2)->o == IR_CARG) { /* Copy calling convention info. */
|
||||
CTypeID id = (CTypeID)IR(IR(ir->op2)->op2)->i;
|
||||
CType *ct = ctype_get(ctype_ctsG(J2G(as->J)), id);
|
||||
nargs |= ((ct->info & CTF_VARARG) ? CCI_VARARG : 0);
|
||||
#if LJ_TARGET_X86
|
||||
nargs |= (ctype_cconv(ct->info) << CCI_CC_SHIFT);
|
||||
#endif
|
||||
}
|
||||
#endif
|
||||
return (nargs | (ir->t.irt << CCI_OTSHIFT));
|
||||
}
|
||||
|
||||
/* Calculate stack adjustment. */
|
||||
static int32_t asm_stack_adjust(ASMState *as)
|
||||
{
|
||||
|
@ -1066,6 +1078,259 @@ static void asm_gcstep(ASMState *as, IRIns *ir)
|
|||
as->gcsteps = 0x80000000; /* Prevent implicit GC check further up. */
|
||||
}
|
||||
|
||||
/* -- Buffer operations --------------------------------------------------- */
|
||||
|
||||
static void asm_tvptr(ASMState *as, Reg dest, IRRef ref);
|
||||
|
||||
static void asm_bufhdr(ASMState *as, IRIns *ir)
|
||||
{
|
||||
Reg sb = ra_dest(as, ir, RSET_GPR);
|
||||
if ((ir->op2 & IRBUFHDR_APPEND)) {
|
||||
/* Rematerialize const buffer pointer instead of likely spill. */
|
||||
IRIns *irp = IR(ir->op1);
|
||||
if (!(ra_hasreg(irp->r) || irp == ir-1 ||
|
||||
(irp == ir-2 && !ra_used(ir-1)))) {
|
||||
while (!(irp->o == IR_BUFHDR && !(irp->op2 & IRBUFHDR_APPEND)))
|
||||
irp = IR(irp->op1);
|
||||
if (irref_isk(irp->op1)) {
|
||||
ra_weak(as, ra_allocref(as, ir->op1, RSET_GPR));
|
||||
ir = irp;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
Reg tmp = ra_scratch(as, rset_exclude(RSET_GPR, sb));
|
||||
/* Passing ir isn't strictly correct, but it's an IRT_PGC, too. */
|
||||
emit_storeofs(as, ir, tmp, sb, offsetof(SBuf, p));
|
||||
emit_loadofs(as, ir, tmp, sb, offsetof(SBuf, b));
|
||||
}
|
||||
#if LJ_TARGET_X86ORX64
|
||||
ra_left(as, sb, ir->op1);
|
||||
#else
|
||||
ra_leftov(as, sb, ir->op1);
|
||||
#endif
|
||||
}
|
||||
|
||||
static void asm_bufput(ASMState *as, IRIns *ir)
|
||||
{
|
||||
const CCallInfo *ci = &lj_ir_callinfo[IRCALL_lj_buf_putstr];
|
||||
IRRef args[3];
|
||||
IRIns *irs;
|
||||
int kchar = -1;
|
||||
args[0] = ir->op1; /* SBuf * */
|
||||
args[1] = ir->op2; /* GCstr * */
|
||||
irs = IR(ir->op2);
|
||||
lua_assert(irt_isstr(irs->t));
|
||||
if (irs->o == IR_KGC) {
|
||||
GCstr *s = ir_kstr(irs);
|
||||
if (s->len == 1) { /* Optimize put of single-char string constant. */
|
||||
kchar = strdata(s)[0];
|
||||
args[1] = ASMREF_TMP1; /* int, truncated to char */
|
||||
ci = &lj_ir_callinfo[IRCALL_lj_buf_putchar];
|
||||
}
|
||||
} else if (mayfuse(as, ir->op2) && ra_noreg(irs->r)) {
|
||||
if (irs->o == IR_TOSTR) { /* Fuse number to string conversions. */
|
||||
if (irs->op2 == IRTOSTR_NUM) {
|
||||
args[1] = ASMREF_TMP1; /* TValue * */
|
||||
ci = &lj_ir_callinfo[IRCALL_lj_strfmt_putnum];
|
||||
} else {
|
||||
lua_assert(irt_isinteger(IR(irs->op1)->t));
|
||||
args[1] = irs->op1; /* int */
|
||||
if (irs->op2 == IRTOSTR_INT)
|
||||
ci = &lj_ir_callinfo[IRCALL_lj_strfmt_putint];
|
||||
else
|
||||
ci = &lj_ir_callinfo[IRCALL_lj_buf_putchar];
|
||||
}
|
||||
} else if (irs->o == IR_SNEW) { /* Fuse string allocation. */
|
||||
args[1] = irs->op1; /* const void * */
|
||||
args[2] = irs->op2; /* MSize */
|
||||
ci = &lj_ir_callinfo[IRCALL_lj_buf_putmem];
|
||||
}
|
||||
}
|
||||
asm_setupresult(as, ir, ci); /* SBuf * */
|
||||
asm_gencall(as, ci, args);
|
||||
if (args[1] == ASMREF_TMP1) {
|
||||
Reg tmp = ra_releasetmp(as, ASMREF_TMP1);
|
||||
if (kchar == -1)
|
||||
asm_tvptr(as, tmp, irs->op1);
|
||||
else
|
||||
ra_allockreg(as, kchar, tmp);
|
||||
}
|
||||
}
|
||||
|
||||
static void asm_bufstr(ASMState *as, IRIns *ir)
|
||||
{
|
||||
const CCallInfo *ci = &lj_ir_callinfo[IRCALL_lj_buf_tostr];
|
||||
IRRef args[1];
|
||||
args[0] = ir->op1; /* SBuf *sb */
|
||||
as->gcsteps++;
|
||||
asm_setupresult(as, ir, ci); /* GCstr * */
|
||||
asm_gencall(as, ci, args);
|
||||
}
|
||||
|
||||
/* -- Type conversions ---------------------------------------------------- */
|
||||
|
||||
static void asm_tostr(ASMState *as, IRIns *ir)
|
||||
{
|
||||
const CCallInfo *ci;
|
||||
IRRef args[2];
|
||||
args[0] = ASMREF_L;
|
||||
as->gcsteps++;
|
||||
if (ir->op2 == IRTOSTR_NUM) {
|
||||
args[1] = ASMREF_TMP1; /* cTValue * */
|
||||
ci = &lj_ir_callinfo[IRCALL_lj_strfmt_num];
|
||||
} else {
|
||||
args[1] = ir->op1; /* int32_t k */
|
||||
if (ir->op2 == IRTOSTR_INT)
|
||||
ci = &lj_ir_callinfo[IRCALL_lj_strfmt_int];
|
||||
else
|
||||
ci = &lj_ir_callinfo[IRCALL_lj_strfmt_char];
|
||||
}
|
||||
asm_setupresult(as, ir, ci); /* GCstr * */
|
||||
asm_gencall(as, ci, args);
|
||||
if (ir->op2 == IRTOSTR_NUM)
|
||||
asm_tvptr(as, ra_releasetmp(as, ASMREF_TMP1), ir->op1);
|
||||
}
|
||||
|
||||
#if LJ_32 && LJ_HASFFI && !LJ_SOFTFP && !LJ_TARGET_X86
|
||||
static void asm_conv64(ASMState *as, IRIns *ir)
|
||||
{
|
||||
IRType st = (IRType)((ir-1)->op2 & IRCONV_SRCMASK);
|
||||
IRType dt = (((ir-1)->op2 & IRCONV_DSTMASK) >> IRCONV_DSH);
|
||||
IRCallID id;
|
||||
IRRef args[2];
|
||||
lua_assert((ir-1)->o == IR_CONV && ir->o == IR_HIOP);
|
||||
args[LJ_BE] = (ir-1)->op1;
|
||||
args[LJ_LE] = ir->op1;
|
||||
if (st == IRT_NUM || st == IRT_FLOAT) {
|
||||
id = IRCALL_fp64_d2l + ((st == IRT_FLOAT) ? 2 : 0) + (dt - IRT_I64);
|
||||
ir--;
|
||||
} else {
|
||||
id = IRCALL_fp64_l2d + ((dt == IRT_FLOAT) ? 2 : 0) + (st - IRT_I64);
|
||||
}
|
||||
{
|
||||
#if LJ_TARGET_ARM && !LJ_ABI_SOFTFP
|
||||
CCallInfo cim = lj_ir_callinfo[id], *ci = &cim;
|
||||
cim.flags |= CCI_VARARG; /* These calls don't use the hard-float ABI! */
|
||||
#else
|
||||
const CCallInfo *ci = &lj_ir_callinfo[id];
|
||||
#endif
|
||||
asm_setupresult(as, ir, ci);
|
||||
asm_gencall(as, ci, args);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
/* -- Memory references --------------------------------------------------- */
|
||||
|
||||
static void asm_newref(ASMState *as, IRIns *ir)
|
||||
{
|
||||
const CCallInfo *ci = &lj_ir_callinfo[IRCALL_lj_tab_newkey];
|
||||
IRRef args[3];
|
||||
if (ir->r == RID_SINK)
|
||||
return;
|
||||
args[0] = ASMREF_L; /* lua_State *L */
|
||||
args[1] = ir->op1; /* GCtab *t */
|
||||
args[2] = ASMREF_TMP1; /* cTValue *key */
|
||||
asm_setupresult(as, ir, ci); /* TValue * */
|
||||
asm_gencall(as, ci, args);
|
||||
asm_tvptr(as, ra_releasetmp(as, ASMREF_TMP1), ir->op2);
|
||||
}
|
||||
|
||||
static void asm_lref(ASMState *as, IRIns *ir)
|
||||
{
|
||||
Reg r = ra_dest(as, ir, RSET_GPR);
|
||||
#if LJ_TARGET_X86ORX64
|
||||
ra_left(as, r, ASMREF_L);
|
||||
#else
|
||||
ra_leftov(as, r, ASMREF_L);
|
||||
#endif
|
||||
}
|
||||
|
||||
/* -- Calls --------------------------------------------------------------- */
|
||||
|
||||
/* Collect arguments from CALL* and CARG instructions. */
|
||||
static void asm_collectargs(ASMState *as, IRIns *ir,
|
||||
const CCallInfo *ci, IRRef *args)
|
||||
{
|
||||
uint32_t n = CCI_XNARGS(ci);
|
||||
lua_assert(n <= CCI_NARGS_MAX*2); /* Account for split args. */
|
||||
if ((ci->flags & CCI_L)) { *args++ = ASMREF_L; n--; }
|
||||
while (n-- > 1) {
|
||||
ir = IR(ir->op1);
|
||||
lua_assert(ir->o == IR_CARG);
|
||||
args[n] = ir->op2 == REF_NIL ? 0 : ir->op2;
|
||||
}
|
||||
args[0] = ir->op1 == REF_NIL ? 0 : ir->op1;
|
||||
lua_assert(IR(ir->op1)->o != IR_CARG);
|
||||
}
|
||||
|
||||
/* Reconstruct CCallInfo flags for CALLX*. */
|
||||
static uint32_t asm_callx_flags(ASMState *as, IRIns *ir)
|
||||
{
|
||||
uint32_t nargs = 0;
|
||||
if (ir->op1 != REF_NIL) { /* Count number of arguments first. */
|
||||
IRIns *ira = IR(ir->op1);
|
||||
nargs++;
|
||||
while (ira->o == IR_CARG) { nargs++; ira = IR(ira->op1); }
|
||||
}
|
||||
#if LJ_HASFFI
|
||||
if (IR(ir->op2)->o == IR_CARG) { /* Copy calling convention info. */
|
||||
CTypeID id = (CTypeID)IR(IR(ir->op2)->op2)->i;
|
||||
CType *ct = ctype_get(ctype_ctsG(J2G(as->J)), id);
|
||||
nargs |= ((ct->info & CTF_VARARG) ? CCI_VARARG : 0);
|
||||
#if LJ_TARGET_X86
|
||||
nargs |= (ctype_cconv(ct->info) << CCI_CC_SHIFT);
|
||||
#endif
|
||||
}
|
||||
#endif
|
||||
return (nargs | (ir->t.irt << CCI_OTSHIFT));
|
||||
}
|
||||
|
||||
static void asm_callid(ASMState *as, IRIns *ir, IRCallID id)
|
||||
{
|
||||
const CCallInfo *ci = &lj_ir_callinfo[id];
|
||||
IRRef args[2];
|
||||
args[0] = ir->op1;
|
||||
args[1] = ir->op2;
|
||||
asm_setupresult(as, ir, ci);
|
||||
asm_gencall(as, ci, args);
|
||||
}
|
||||
|
||||
static void asm_call(ASMState *as, IRIns *ir)
|
||||
{
|
||||
IRRef args[CCI_NARGS_MAX];
|
||||
const CCallInfo *ci = &lj_ir_callinfo[ir->op2];
|
||||
asm_collectargs(as, ir, ci, args);
|
||||
asm_setupresult(as, ir, ci);
|
||||
asm_gencall(as, ci, args);
|
||||
}
|
||||
|
||||
#if !LJ_SOFTFP
|
||||
static void asm_fppow(ASMState *as, IRIns *ir, IRRef lref, IRRef rref)
|
||||
{
|
||||
const CCallInfo *ci = &lj_ir_callinfo[IRCALL_pow];
|
||||
IRRef args[2];
|
||||
args[0] = lref;
|
||||
args[1] = rref;
|
||||
asm_setupresult(as, ir, ci);
|
||||
asm_gencall(as, ci, args);
|
||||
}
|
||||
|
||||
static int asm_fpjoin_pow(ASMState *as, IRIns *ir)
|
||||
{
|
||||
IRIns *irp = IR(ir->op1);
|
||||
if (irp == ir-1 && irp->o == IR_MUL && !ra_used(irp)) {
|
||||
IRIns *irpp = IR(irp->op1);
|
||||
if (irpp == ir-2 && irpp->o == IR_FPMATH &&
|
||||
irpp->op2 == IRFPM_LOG2 && !ra_used(irpp)) {
|
||||
asm_fppow(as, ir, irpp->op1, irp->op2);
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
|
||||
/* -- PHI and loop handling ----------------------------------------------- */
|
||||
|
||||
/* Break a PHI cycle by renaming to a free register (evict if needed). */
|
||||
|
@ -1251,12 +1516,7 @@ static void asm_phi_fixup(ASMState *as)
|
|||
irt_clearmark(ir->t);
|
||||
/* Left PHI gained a spill slot before the loop? */
|
||||
if (ra_hasspill(ir->s)) {
|
||||
IRRef ren;
|
||||
lj_ir_set(as->J, IRT(IR_RENAME, IRT_NIL), lref, as->loopsnapno);
|
||||
ren = tref_ref(lj_ir_emit(as->J));
|
||||
as->ir = as->T->ir; /* The IR may have been reallocated. */
|
||||
IR(ren)->r = (uint8_t)r;
|
||||
IR(ren)->s = SPS_NONE;
|
||||
ra_addrename(as, r, lref, as->loopsnapno);
|
||||
}
|
||||
}
|
||||
rset_clear(work, r);
|
||||
|
@ -1331,6 +1591,8 @@ static void asm_loop(ASMState *as)
|
|||
#include "lj_asm_x86.h"
|
||||
#elif LJ_TARGET_ARM
|
||||
#include "lj_asm_arm.h"
|
||||
#elif LJ_TARGET_ARM64
|
||||
#include "lj_asm_arm64.h"
|
||||
#elif LJ_TARGET_PPC
|
||||
#include "lj_asm_ppc.h"
|
||||
#elif LJ_TARGET_MIPS
|
||||
|
@ -1339,6 +1601,136 @@ static void asm_loop(ASMState *as)
|
|||
#error "Missing assembler for target CPU"
|
||||
#endif
|
||||
|
||||
/* -- Instruction dispatch ------------------------------------------------ */
|
||||
|
||||
/* Assemble a single instruction. */
|
||||
static void asm_ir(ASMState *as, IRIns *ir)
|
||||
{
|
||||
switch ((IROp)ir->o) {
|
||||
/* Miscellaneous ops. */
|
||||
case IR_LOOP: asm_loop(as); break;
|
||||
case IR_NOP: case IR_XBAR: lua_assert(!ra_used(ir)); break;
|
||||
case IR_USE:
|
||||
ra_alloc1(as, ir->op1, irt_isfp(ir->t) ? RSET_FPR : RSET_GPR); break;
|
||||
case IR_PHI: asm_phi(as, ir); break;
|
||||
case IR_HIOP: asm_hiop(as, ir); break;
|
||||
case IR_GCSTEP: asm_gcstep(as, ir); break;
|
||||
case IR_PROF: asm_prof(as, ir); break;
|
||||
|
||||
/* Guarded assertions. */
|
||||
case IR_LT: case IR_GE: case IR_LE: case IR_GT:
|
||||
case IR_ULT: case IR_UGE: case IR_ULE: case IR_UGT:
|
||||
case IR_ABC:
|
||||
asm_comp(as, ir);
|
||||
break;
|
||||
case IR_EQ: case IR_NE:
|
||||
if ((ir-1)->o == IR_HREF && ir->op1 == as->curins-1) {
|
||||
as->curins--;
|
||||
asm_href(as, ir-1, (IROp)ir->o);
|
||||
} else {
|
||||
asm_equal(as, ir);
|
||||
}
|
||||
break;
|
||||
|
||||
case IR_RETF: asm_retf(as, ir); break;
|
||||
|
||||
/* Bit ops. */
|
||||
case IR_BNOT: asm_bnot(as, ir); break;
|
||||
case IR_BSWAP: asm_bswap(as, ir); break;
|
||||
case IR_BAND: asm_band(as, ir); break;
|
||||
case IR_BOR: asm_bor(as, ir); break;
|
||||
case IR_BXOR: asm_bxor(as, ir); break;
|
||||
case IR_BSHL: asm_bshl(as, ir); break;
|
||||
case IR_BSHR: asm_bshr(as, ir); break;
|
||||
case IR_BSAR: asm_bsar(as, ir); break;
|
||||
case IR_BROL: asm_brol(as, ir); break;
|
||||
case IR_BROR: asm_bror(as, ir); break;
|
||||
|
||||
/* Arithmetic ops. */
|
||||
case IR_ADD: asm_add(as, ir); break;
|
||||
case IR_SUB: asm_sub(as, ir); break;
|
||||
case IR_MUL: asm_mul(as, ir); break;
|
||||
case IR_MOD: asm_mod(as, ir); break;
|
||||
case IR_NEG: asm_neg(as, ir); break;
|
||||
#if LJ_SOFTFP
|
||||
case IR_DIV: case IR_POW: case IR_ABS:
|
||||
case IR_ATAN2: case IR_LDEXP: case IR_FPMATH: case IR_TOBIT:
|
||||
lua_assert(0); /* Unused for LJ_SOFTFP. */
|
||||
break;
|
||||
#else
|
||||
case IR_DIV: asm_div(as, ir); break;
|
||||
case IR_POW: asm_pow(as, ir); break;
|
||||
case IR_ABS: asm_abs(as, ir); break;
|
||||
case IR_ATAN2: asm_atan2(as, ir); break;
|
||||
case IR_LDEXP: asm_ldexp(as, ir); break;
|
||||
case IR_FPMATH: asm_fpmath(as, ir); break;
|
||||
case IR_TOBIT: asm_tobit(as, ir); break;
|
||||
#endif
|
||||
case IR_MIN: asm_min(as, ir); break;
|
||||
case IR_MAX: asm_max(as, ir); break;
|
||||
|
||||
/* Overflow-checking arithmetic ops. */
|
||||
case IR_ADDOV: asm_addov(as, ir); break;
|
||||
case IR_SUBOV: asm_subov(as, ir); break;
|
||||
case IR_MULOV: asm_mulov(as, ir); break;
|
||||
|
||||
/* Memory references. */
|
||||
case IR_AREF: asm_aref(as, ir); break;
|
||||
case IR_HREF: asm_href(as, ir, 0); break;
|
||||
case IR_HREFK: asm_hrefk(as, ir); break;
|
||||
case IR_NEWREF: asm_newref(as, ir); break;
|
||||
case IR_UREFO: case IR_UREFC: asm_uref(as, ir); break;
|
||||
case IR_FREF: asm_fref(as, ir); break;
|
||||
case IR_STRREF: asm_strref(as, ir); break;
|
||||
case IR_LREF: asm_lref(as, ir); break;
|
||||
|
||||
/* Loads and stores. */
|
||||
case IR_ALOAD: case IR_HLOAD: case IR_ULOAD: case IR_VLOAD:
|
||||
asm_ahuvload(as, ir);
|
||||
break;
|
||||
case IR_FLOAD: asm_fload(as, ir); break;
|
||||
case IR_XLOAD: asm_xload(as, ir); break;
|
||||
case IR_SLOAD: asm_sload(as, ir); break;
|
||||
|
||||
case IR_ASTORE: case IR_HSTORE: case IR_USTORE: asm_ahustore(as, ir); break;
|
||||
case IR_FSTORE: asm_fstore(as, ir); break;
|
||||
case IR_XSTORE: asm_xstore(as, ir); break;
|
||||
|
||||
/* Allocations. */
|
||||
case IR_SNEW: case IR_XSNEW: asm_snew(as, ir); break;
|
||||
case IR_TNEW: asm_tnew(as, ir); break;
|
||||
case IR_TDUP: asm_tdup(as, ir); break;
|
||||
case IR_CNEW: case IR_CNEWI: asm_cnew(as, ir); break;
|
||||
|
||||
/* Buffer operations. */
|
||||
case IR_BUFHDR: asm_bufhdr(as, ir); break;
|
||||
case IR_BUFPUT: asm_bufput(as, ir); break;
|
||||
case IR_BUFSTR: asm_bufstr(as, ir); break;
|
||||
|
||||
/* Write barriers. */
|
||||
case IR_TBAR: asm_tbar(as, ir); break;
|
||||
case IR_OBAR: asm_obar(as, ir); break;
|
||||
|
||||
/* Type conversions. */
|
||||
case IR_CONV: asm_conv(as, ir); break;
|
||||
case IR_TOSTR: asm_tostr(as, ir); break;
|
||||
case IR_STRTO: asm_strto(as, ir); break;
|
||||
|
||||
/* Calls. */
|
||||
case IR_CALLA:
|
||||
as->gcsteps++;
|
||||
/* fallthrough */
|
||||
case IR_CALLN: case IR_CALLL: case IR_CALLS: asm_call(as, ir); break;
|
||||
case IR_CALLXS: asm_callx(as, ir); break;
|
||||
case IR_CARG: break;
|
||||
|
||||
default:
|
||||
setintV(&as->J->errinfo, ir->o);
|
||||
lj_trace_err_info(as->J, LJ_TRERR_NYIIR);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/* -- Head of trace ------------------------------------------------------- */
|
||||
|
||||
/* Head of a root trace. */
|
||||
|
@ -1537,7 +1929,7 @@ static BCReg asm_baseslot(ASMState *as, SnapShot *snap, int *gotframe)
|
|||
SnapEntry sn = map[n-1];
|
||||
if ((sn & SNAP_FRAME)) {
|
||||
*gotframe = 1;
|
||||
return snap_slot(sn);
|
||||
return snap_slot(sn) - LJ_FR2;
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
|
@ -1557,19 +1949,23 @@ static void asm_tail_link(ASMState *as)
|
|||
|
||||
if (as->T->link == 0) {
|
||||
/* Setup fixed registers for exit to interpreter. */
|
||||
const BCIns *pc = snap_pc(as->T->snapmap[snap->mapofs + snap->nent]);
|
||||
const BCIns *pc = snap_pc(&as->T->snapmap[snap->mapofs + snap->nent]);
|
||||
int32_t mres;
|
||||
if (bc_op(*pc) == BC_JLOOP) { /* NYI: find a better way to do this. */
|
||||
BCIns *retpc = &traceref(as->J, bc_d(*pc))->startins;
|
||||
if (bc_isret(bc_op(*retpc)))
|
||||
pc = retpc;
|
||||
}
|
||||
#if LJ_GC64
|
||||
emit_loadu64(as, RID_LPC, u64ptr(pc));
|
||||
#else
|
||||
ra_allockreg(as, i32ptr(J2GG(as->J)->dispatch), RID_DISPATCH);
|
||||
ra_allockreg(as, i32ptr(pc), RID_LPC);
|
||||
mres = (int32_t)(snap->nslots - baseslot);
|
||||
#endif
|
||||
mres = (int32_t)(snap->nslots - baseslot - LJ_FR2);
|
||||
switch (bc_op(*pc)) {
|
||||
case BC_CALLM: case BC_CALLMT:
|
||||
mres -= (int32_t)(1 + bc_a(*pc) + bc_c(*pc)); break;
|
||||
mres -= (int32_t)(1 + LJ_FR2 + bc_a(*pc) + bc_c(*pc)); break;
|
||||
case BC_RETM: mres -= (int32_t)(bc_a(*pc) + bc_d(*pc)); break;
|
||||
case BC_TSETM: mres -= (int32_t)bc_a(*pc); break;
|
||||
default: if (bc_op(*pc) < BC_FUNCF) mres = 0; break;
|
||||
|
@ -1581,6 +1977,11 @@ static void asm_tail_link(ASMState *as)
|
|||
}
|
||||
emit_addptr(as, RID_BASE, 8*(int32_t)baseslot);
|
||||
|
||||
if (as->J->ktrace) { /* Patch ktrace slot with the final GCtrace pointer. */
|
||||
setgcref(IR(as->J->ktrace)[LJ_GC64].gcr, obj2gco(as->J->curfinal));
|
||||
IR(as->J->ktrace)->o = IR_KGC;
|
||||
}
|
||||
|
||||
/* Sync the interpreter state with the on-trace state. */
|
||||
asm_stack_restore(as, snap);
|
||||
|
||||
|
@ -1606,17 +2007,22 @@ static void asm_setup_regsp(ASMState *as)
|
|||
ra_setup(as);
|
||||
|
||||
/* Clear reg/sp for constants. */
|
||||
for (ir = IR(T->nk), lastir = IR(REF_BASE); ir < lastir; ir++)
|
||||
for (ir = IR(T->nk), lastir = IR(REF_BASE); ir < lastir; ir++) {
|
||||
ir->prev = REGSP_INIT;
|
||||
if (irt_is64(ir->t) && ir->o != IR_KNULL) {
|
||||
#if LJ_GC64
|
||||
ir->i = 0; /* Will become non-zero only for RIP-relative addresses. */
|
||||
#else
|
||||
/* Make life easier for backends by putting address of constant in i. */
|
||||
ir->i = (int32_t)(intptr_t)(ir+1);
|
||||
#endif
|
||||
ir++;
|
||||
}
|
||||
}
|
||||
|
||||
/* REF_BASE is used for implicit references to the BASE register. */
|
||||
lastir->prev = REGSP_HINT(RID_BASE);
|
||||
|
||||
ir = IR(nins-1);
|
||||
if (ir->o == IR_RENAME) {
|
||||
do { ir--; nins--; } while (ir->o == IR_RENAME);
|
||||
T->nins = nins; /* Remove any renames left over from ASM restart. */
|
||||
}
|
||||
as->snaprename = nins;
|
||||
as->snapref = nins;
|
||||
as->snapno = T->nsnap;
|
||||
|
@ -1677,7 +2083,7 @@ static void asm_setup_regsp(ASMState *as)
|
|||
as->modset |= RSET_SCRATCH;
|
||||
continue;
|
||||
}
|
||||
case IR_CALLN: case IR_CALLL: case IR_CALLS: {
|
||||
case IR_CALLN: case IR_CALLA: case IR_CALLL: case IR_CALLS: {
|
||||
const CCallInfo *ci = &lj_ir_callinfo[ir->op2];
|
||||
ir->prev = asm_setup_call_slots(as, ir, ci);
|
||||
if (inloop)
|
||||
|
@ -1722,10 +2128,20 @@ static void asm_setup_regsp(ASMState *as)
|
|||
/* fallthrough */
|
||||
#endif
|
||||
/* C calls evict all scratch regs and return results in RID_RET. */
|
||||
case IR_SNEW: case IR_XSNEW: case IR_NEWREF:
|
||||
case IR_SNEW: case IR_XSNEW: case IR_NEWREF: case IR_BUFPUT:
|
||||
if (REGARG_NUMGPR < 3 && as->evenspill < 3)
|
||||
as->evenspill = 3; /* lj_str_new and lj_tab_newkey need 3 args. */
|
||||
case IR_TNEW: case IR_TDUP: case IR_CNEW: case IR_CNEWI: case IR_TOSTR:
|
||||
#if LJ_TARGET_X86 && LJ_HASFFI
|
||||
if (0) {
|
||||
case IR_CNEW:
|
||||
if (ir->op2 != REF_NIL && as->evenspill < 4)
|
||||
as->evenspill = 4; /* lj_cdata_newv needs 4 args. */
|
||||
}
|
||||
#else
|
||||
case IR_CNEW:
|
||||
#endif
|
||||
case IR_TNEW: case IR_TDUP: case IR_CNEWI: case IR_TOSTR:
|
||||
case IR_BUFSTR:
|
||||
ir->prev = REGSP_HINT(RID_RET);
|
||||
if (inloop)
|
||||
as->modset = RSET_SCRATCH;
|
||||
|
@ -1734,21 +2150,26 @@ static void asm_setup_regsp(ASMState *as)
|
|||
if (inloop)
|
||||
as->modset = RSET_SCRATCH;
|
||||
break;
|
||||
#if !LJ_TARGET_X86ORX64 && !LJ_SOFTFP
|
||||
case IR_ATAN2: case IR_LDEXP:
|
||||
#if !LJ_SOFTFP
|
||||
case IR_ATAN2:
|
||||
#if LJ_TARGET_X86
|
||||
if (as->evenspill < 4) /* Leave room to call atan2(). */
|
||||
as->evenspill = 4;
|
||||
#endif
|
||||
#if !LJ_TARGET_X86ORX64
|
||||
case IR_LDEXP:
|
||||
#endif
|
||||
#endif
|
||||
case IR_POW:
|
||||
if (!LJ_SOFTFP && irt_isnum(ir->t)) {
|
||||
#if LJ_TARGET_X86ORX64
|
||||
ir->prev = REGSP_HINT(RID_XMM0);
|
||||
if (inloop)
|
||||
as->modset |= RSET_RANGE(RID_XMM0, RID_XMM1+1)|RID2RSET(RID_EAX);
|
||||
#else
|
||||
ir->prev = REGSP_HINT(RID_FPRET);
|
||||
if (inloop)
|
||||
as->modset |= RSET_SCRATCH;
|
||||
#endif
|
||||
#if LJ_TARGET_X86
|
||||
break;
|
||||
#else
|
||||
ir->prev = REGSP_HINT(RID_FPRET);
|
||||
continue;
|
||||
#endif
|
||||
}
|
||||
/* fallthrough for integer POW */
|
||||
case IR_DIV: case IR_MOD:
|
||||
|
@ -1761,31 +2182,33 @@ static void asm_setup_regsp(ASMState *as)
|
|||
break;
|
||||
case IR_FPMATH:
|
||||
#if LJ_TARGET_X86ORX64
|
||||
if (ir->op2 == IRFPM_EXP2) { /* May be joined to lj_vm_pow_sse. */
|
||||
ir->prev = REGSP_HINT(RID_XMM0);
|
||||
#if !LJ_64
|
||||
if (as->evenspill < 4) /* Leave room for 16 byte scratch area. */
|
||||
if (ir->op2 <= IRFPM_TRUNC) {
|
||||
if (!(as->flags & JIT_F_SSE4_1)) {
|
||||
ir->prev = REGSP_HINT(RID_XMM0);
|
||||
if (inloop)
|
||||
as->modset |= RSET_RANGE(RID_XMM0, RID_XMM3+1)|RID2RSET(RID_EAX);
|
||||
continue;
|
||||
}
|
||||
break;
|
||||
} else if (ir->op2 == IRFPM_EXP2 && !LJ_64) {
|
||||
if (as->evenspill < 4) /* Leave room to call pow(). */
|
||||
as->evenspill = 4;
|
||||
#endif
|
||||
if (inloop)
|
||||
as->modset |= RSET_RANGE(RID_XMM0, RID_XMM2+1)|RID2RSET(RID_EAX);
|
||||
continue;
|
||||
} else if (ir->op2 <= IRFPM_TRUNC && !(as->flags & JIT_F_SSE4_1)) {
|
||||
ir->prev = REGSP_HINT(RID_XMM0);
|
||||
if (inloop)
|
||||
as->modset |= RSET_RANGE(RID_XMM0, RID_XMM3+1)|RID2RSET(RID_EAX);
|
||||
continue;
|
||||
}
|
||||
#endif
|
||||
if (inloop)
|
||||
as->modset |= RSET_SCRATCH;
|
||||
#if LJ_TARGET_X86
|
||||
break;
|
||||
#else
|
||||
ir->prev = REGSP_HINT(RID_FPRET);
|
||||
if (inloop)
|
||||
as->modset |= RSET_SCRATCH;
|
||||
continue;
|
||||
#endif
|
||||
#if LJ_TARGET_X86ORX64
|
||||
/* Non-constant shift counts need to be in RID_ECX on x86/x64. */
|
||||
case IR_BSHL: case IR_BSHR: case IR_BSAR: case IR_BROL: case IR_BROR:
|
||||
case IR_BSHL: case IR_BSHR: case IR_BSAR:
|
||||
if ((as->flags & JIT_F_BMI2)) /* Except if BMI2 is available. */
|
||||
break;
|
||||
case IR_BROL: case IR_BROR:
|
||||
if (!irref_isk(ir->op2) && !ra_hashint(IR(ir->op2)->r)) {
|
||||
IR(ir->op2)->r = REGSP_HINT(RID_ECX);
|
||||
if (inloop)
|
||||
|
@ -1831,14 +2254,25 @@ void lj_asm_trace(jit_State *J, GCtrace *T)
|
|||
ASMState *as = &as_;
|
||||
MCode *origtop;
|
||||
|
||||
/* Remove nops/renames left over from ASM restart due to LJ_TRERR_MCODELM. */
|
||||
{
|
||||
IRRef nins = T->nins;
|
||||
IRIns *ir = &T->ir[nins-1];
|
||||
if (ir->o == IR_NOP || ir->o == IR_RENAME) {
|
||||
do { ir--; nins--; } while (ir->o == IR_NOP || ir->o == IR_RENAME);
|
||||
T->nins = nins;
|
||||
}
|
||||
}
|
||||
|
||||
/* Ensure an initialized instruction beyond the last one for HIOP checks. */
|
||||
J->cur.nins = lj_ir_nextins(J);
|
||||
J->cur.ir[J->cur.nins].o = IR_NOP;
|
||||
/* This also allows one RENAME to be added without reallocating curfinal. */
|
||||
as->orignins = lj_ir_nextins(J);
|
||||
J->cur.ir[as->orignins].o = IR_NOP;
|
||||
|
||||
/* Setup initial state. Copy some fields to reduce indirections. */
|
||||
as->J = J;
|
||||
as->T = T;
|
||||
as->ir = T->ir;
|
||||
J->curfinal = lj_trace_alloc(J->L, T); /* This copies the IR, too. */
|
||||
as->flags = J->flags;
|
||||
as->loopref = J->loopref;
|
||||
as->realign = NULL;
|
||||
|
@ -1851,12 +2285,41 @@ void lj_asm_trace(jit_State *J, GCtrace *T)
|
|||
as->mclim = as->mcbot + MCLIM_REDZONE;
|
||||
asm_setup_target(as);
|
||||
|
||||
do {
|
||||
/*
|
||||
** This is a loop, because the MCode may have to be (re-)assembled
|
||||
** multiple times:
|
||||
**
|
||||
** 1. as->realign is set (and the assembly aborted), if the arch-specific
|
||||
** backend wants the MCode to be aligned differently.
|
||||
**
|
||||
** This is currently only the case on x86/x64, where small loops get
|
||||
** an aligned loop body plus a short branch. Not much effort is wasted,
|
||||
** because the abort happens very quickly and only once.
|
||||
**
|
||||
** 2. The IR is immovable, since the MCode embeds pointers to various
|
||||
** constants inside the IR. But RENAMEs may need to be added to the IR
|
||||
** during assembly, which might grow and reallocate the IR. We check
|
||||
** at the end if the IR (in J->cur.ir) has actually grown, resize the
|
||||
** copy (in J->curfinal.ir) and try again.
|
||||
**
|
||||
** 95% of all traces have zero RENAMEs, 3% have one RENAME, 1.5% have
|
||||
** 2 RENAMEs and only 0.5% have more than that. That's why we opt to
|
||||
** always have one spare slot in the IR (see above), which means we
|
||||
** have to redo the assembly for only ~2% of all traces.
|
||||
**
|
||||
** Very, very rarely, this needs to be done repeatedly, since the
|
||||
** location of constants inside the IR (actually, reachability from
|
||||
** a global pointer) may affect register allocation and thus the
|
||||
** number of RENAMEs.
|
||||
*/
|
||||
for (;;) {
|
||||
as->mcp = as->mctop;
|
||||
#ifdef LUA_USE_ASSERT
|
||||
as->mcp_prev = as->mcp;
|
||||
#endif
|
||||
as->curins = T->nins;
|
||||
as->ir = J->curfinal->ir; /* Use the copied IR. */
|
||||
as->curins = J->cur.nins = as->orignins;
|
||||
|
||||
RA_DBG_START();
|
||||
RA_DBGX((as, "===== STOP ====="));
|
||||
|
||||
|
@ -1884,22 +2347,40 @@ void lj_asm_trace(jit_State *J, GCtrace *T)
|
|||
checkmclim(as);
|
||||
asm_ir(as, ir);
|
||||
}
|
||||
} while (as->realign); /* Retry in case the MCode needs to be realigned. */
|
||||
|
||||
/* Emit head of trace. */
|
||||
RA_DBG_REF();
|
||||
checkmclim(as);
|
||||
if (as->gcsteps > 0) {
|
||||
as->curins = as->T->snap[0].ref;
|
||||
asm_snap_prep(as); /* The GC check is a guard. */
|
||||
asm_gc_check(as);
|
||||
if (as->realign && J->curfinal->nins >= T->nins)
|
||||
continue; /* Retry in case only the MCode needs to be realigned. */
|
||||
|
||||
/* Emit head of trace. */
|
||||
RA_DBG_REF();
|
||||
checkmclim(as);
|
||||
if (as->gcsteps > 0) {
|
||||
as->curins = as->T->snap[0].ref;
|
||||
asm_snap_prep(as); /* The GC check is a guard. */
|
||||
asm_gc_check(as);
|
||||
as->curins = as->stopins;
|
||||
}
|
||||
ra_evictk(as);
|
||||
if (as->parent)
|
||||
asm_head_side(as);
|
||||
else
|
||||
asm_head_root(as);
|
||||
asm_phi_fixup(as);
|
||||
|
||||
if (J->curfinal->nins >= T->nins) { /* IR didn't grow? */
|
||||
lua_assert(J->curfinal->nk == T->nk);
|
||||
memcpy(J->curfinal->ir + as->orignins, T->ir + as->orignins,
|
||||
(T->nins - as->orignins) * sizeof(IRIns)); /* Copy RENAMEs. */
|
||||
T->nins = J->curfinal->nins;
|
||||
break; /* Done. */
|
||||
}
|
||||
|
||||
/* Otherwise try again with a bigger IR. */
|
||||
lj_trace_free(J2G(J), J->curfinal);
|
||||
J->curfinal = NULL; /* In case lj_trace_alloc() OOMs. */
|
||||
J->curfinal = lj_trace_alloc(J->L, T);
|
||||
as->realign = NULL;
|
||||
}
|
||||
ra_evictk(as);
|
||||
if (as->parent)
|
||||
asm_head_side(as);
|
||||
else
|
||||
asm_head_root(as);
|
||||
asm_phi_fixup(as);
|
||||
|
||||
RA_DBGX((as, "===== START ===="));
|
||||
RA_DBG_FLUSH();
|
||||
|
@ -1912,6 +2393,9 @@ void lj_asm_trace(jit_State *J, GCtrace *T)
|
|||
if (!as->loopref)
|
||||
asm_tail_fixup(as, T->link); /* Note: this may change as->mctop! */
|
||||
T->szmcode = (MSize)((char *)as->mctop - (char *)as->mcp);
|
||||
#if LJ_TARGET_MCODE_FIXUP
|
||||
asm_mcode_fixup(T->mcode, T->szmcode);
|
||||
#endif
|
||||
lj_mcode_sync(T->mcode, origtop);
|
||||
}
|
||||
|
||||
|
|
2
vendor/luajit/src/lj_asm.h
vendored
2
vendor/luajit/src/lj_asm.h
vendored
|
@ -1,6 +1,6 @@
|
|||
/*
|
||||
** IR assembler (SSA IR -> machine code).
|
||||
** Copyright (C) 2005-2015 Mike Pall. See Copyright Notice in luajit.h
|
||||
** Copyright (C) 2005-2017 Mike Pall. See Copyright Notice in luajit.h
|
||||
*/
|
||||
|
||||
#ifndef _LJ_ASM_H
|
||||
|
|
467
vendor/luajit/src/lj_asm_arm.h
vendored
467
vendor/luajit/src/lj_asm_arm.h
vendored
|
@ -1,6 +1,6 @@
|
|||
/*
|
||||
** ARM IR assembler (SSA IR -> machine code).
|
||||
** Copyright (C) 2005-2015 Mike Pall. See Copyright Notice in luajit.h
|
||||
** Copyright (C) 2005-2017 Mike Pall. See Copyright Notice in luajit.h
|
||||
*/
|
||||
|
||||
/* -- Register allocator extensions --------------------------------------- */
|
||||
|
@ -338,7 +338,7 @@ static int asm_fusemadd(ASMState *as, IRIns *ir, ARMIns ai, ARMIns air)
|
|||
/* Generate a call to a C function. */
|
||||
static void asm_gencall(ASMState *as, const CCallInfo *ci, IRRef *args)
|
||||
{
|
||||
uint32_t n, nargs = CCI_NARGS(ci);
|
||||
uint32_t n, nargs = CCI_XNARGS(ci);
|
||||
int32_t ofs = 0;
|
||||
#if LJ_SOFTFP
|
||||
Reg gpr = REGARG_FIRSTGPR;
|
||||
|
@ -426,7 +426,7 @@ static void asm_gencall(ASMState *as, const CCallInfo *ci, IRRef *args)
|
|||
static void asm_setupresult(ASMState *as, IRIns *ir, const CCallInfo *ci)
|
||||
{
|
||||
RegSet drop = RSET_SCRATCH;
|
||||
int hiop = ((ir+1)->o == IR_HIOP);
|
||||
int hiop = ((ir+1)->o == IR_HIOP && !irt_isnil((ir+1)->t));
|
||||
if (ra_hasreg(ir->r))
|
||||
rset_clear(drop, ir->r); /* Dest reg handled below. */
|
||||
if (hiop && ra_hasreg((ir+1)->r))
|
||||
|
@ -453,15 +453,6 @@ static void asm_setupresult(ASMState *as, IRIns *ir, const CCallInfo *ci)
|
|||
UNUSED(ci);
|
||||
}
|
||||
|
||||
static void asm_call(ASMState *as, IRIns *ir)
|
||||
{
|
||||
IRRef args[CCI_NARGS_MAX];
|
||||
const CCallInfo *ci = &lj_ir_callinfo[ir->op2];
|
||||
asm_collectargs(as, ir, ci, args);
|
||||
asm_setupresult(as, ir, ci);
|
||||
asm_gencall(as, ci, args);
|
||||
}
|
||||
|
||||
static void asm_callx(ASMState *as, IRIns *ir)
|
||||
{
|
||||
IRRef args[CCI_NARGS_MAX*2];
|
||||
|
@ -490,7 +481,7 @@ static void asm_retf(ASMState *as, IRIns *ir)
|
|||
{
|
||||
Reg base = ra_alloc1(as, REF_BASE, RSET_GPR);
|
||||
void *pc = ir_kptr(IR(ir->op2));
|
||||
int32_t delta = 1+bc_a(*((const BCIns *)pc - 1));
|
||||
int32_t delta = 1+LJ_FR2+bc_a(*((const BCIns *)pc - 1));
|
||||
as->topslot -= (BCReg)delta;
|
||||
if ((int32_t)as->topslot < 0) as->topslot = 0;
|
||||
irt_setmark(IR(REF_BASE)->t); /* Children must not coalesce with BASE reg. */
|
||||
|
@ -601,31 +592,6 @@ static void asm_conv(ASMState *as, IRIns *ir)
|
|||
}
|
||||
}
|
||||
|
||||
#if !LJ_SOFTFP && LJ_HASFFI
|
||||
static void asm_conv64(ASMState *as, IRIns *ir)
|
||||
{
|
||||
IRType st = (IRType)((ir-1)->op2 & IRCONV_SRCMASK);
|
||||
IRType dt = (((ir-1)->op2 & IRCONV_DSTMASK) >> IRCONV_DSH);
|
||||
IRCallID id;
|
||||
CCallInfo ci;
|
||||
IRRef args[2];
|
||||
args[0] = (ir-1)->op1;
|
||||
args[1] = ir->op1;
|
||||
if (st == IRT_NUM || st == IRT_FLOAT) {
|
||||
id = IRCALL_fp64_d2l + ((st == IRT_FLOAT) ? 2 : 0) + (dt - IRT_I64);
|
||||
ir--;
|
||||
} else {
|
||||
id = IRCALL_fp64_l2d + ((dt == IRT_FLOAT) ? 2 : 0) + (st - IRT_I64);
|
||||
}
|
||||
ci = lj_ir_callinfo[id];
|
||||
#if !LJ_ABI_SOFTFP
|
||||
ci.flags |= CCI_VARARG; /* These calls don't use the hard-float ABI! */
|
||||
#endif
|
||||
asm_setupresult(as, ir, &ci);
|
||||
asm_gencall(as, &ci, args);
|
||||
}
|
||||
#endif
|
||||
|
||||
static void asm_strto(ASMState *as, IRIns *ir)
|
||||
{
|
||||
const CCallInfo *ci = &lj_ir_callinfo[IRCALL_lj_strscan_num];
|
||||
|
@ -689,6 +655,8 @@ static void asm_strto(ASMState *as, IRIns *ir)
|
|||
emit_opk(as, ARMI_ADD, tmp, RID_SP, ofs, RSET_GPR);
|
||||
}
|
||||
|
||||
/* -- Memory references --------------------------------------------------- */
|
||||
|
||||
/* Get pointer to TValue. */
|
||||
static void asm_tvptr(ASMState *as, Reg dest, IRRef ref)
|
||||
{
|
||||
|
@ -714,7 +682,7 @@ static void asm_tvptr(ASMState *as, Reg dest, IRRef ref)
|
|||
Reg src = ra_alloc1(as, ref, allow);
|
||||
emit_lso(as, ARMI_STR, src, RID_SP, 0);
|
||||
}
|
||||
if ((ir+1)->o == IR_HIOP)
|
||||
if (LJ_SOFTFP && (ir+1)->o == IR_HIOP)
|
||||
type = ra_alloc1(as, ref+1, allow);
|
||||
else
|
||||
type = ra_allock(as, irt_toitype(ir->t), allow);
|
||||
|
@ -722,27 +690,6 @@ static void asm_tvptr(ASMState *as, Reg dest, IRRef ref)
|
|||
}
|
||||
}
|
||||
|
||||
static void asm_tostr(ASMState *as, IRIns *ir)
|
||||
{
|
||||
IRRef args[2];
|
||||
args[0] = ASMREF_L;
|
||||
as->gcsteps++;
|
||||
if (irt_isnum(IR(ir->op1)->t) || (ir+1)->o == IR_HIOP) {
|
||||
const CCallInfo *ci = &lj_ir_callinfo[IRCALL_lj_str_fromnum];
|
||||
args[1] = ASMREF_TMP1; /* const lua_Number * */
|
||||
asm_setupresult(as, ir, ci); /* GCstr * */
|
||||
asm_gencall(as, ci, args);
|
||||
asm_tvptr(as, ra_releasetmp(as, ASMREF_TMP1), ir->op1);
|
||||
} else {
|
||||
const CCallInfo *ci = &lj_ir_callinfo[IRCALL_lj_str_fromint];
|
||||
args[1] = ir->op1; /* int32_t k */
|
||||
asm_setupresult(as, ir, ci); /* GCstr * */
|
||||
asm_gencall(as, ci, args);
|
||||
}
|
||||
}
|
||||
|
||||
/* -- Memory references --------------------------------------------------- */
|
||||
|
||||
static void asm_aref(ASMState *as, IRIns *ir)
|
||||
{
|
||||
Reg dest = ra_dest(as, ir, RSET_GPR);
|
||||
|
@ -960,23 +907,8 @@ static void asm_hrefk(ASMState *as, IRIns *ir)
|
|||
emit_opk(as, ARMI_ADD, dest, node, ofs, RSET_GPR);
|
||||
}
|
||||
|
||||
static void asm_newref(ASMState *as, IRIns *ir)
|
||||
{
|
||||
const CCallInfo *ci = &lj_ir_callinfo[IRCALL_lj_tab_newkey];
|
||||
IRRef args[3];
|
||||
if (ir->r == RID_SINK)
|
||||
return;
|
||||
args[0] = ASMREF_L; /* lua_State *L */
|
||||
args[1] = ir->op1; /* GCtab *t */
|
||||
args[2] = ASMREF_TMP1; /* cTValue *key */
|
||||
asm_setupresult(as, ir, ci); /* TValue * */
|
||||
asm_gencall(as, ci, args);
|
||||
asm_tvptr(as, ra_releasetmp(as, ASMREF_TMP1), ir->op2);
|
||||
}
|
||||
|
||||
static void asm_uref(ASMState *as, IRIns *ir)
|
||||
{
|
||||
/* NYI: Check that UREFO is still open and not aliasing a slot. */
|
||||
Reg dest = ra_dest(as, ir, RSET_GPR);
|
||||
if (irref_isk(ir->op1)) {
|
||||
GCfunc *fn = ir_kfunc(IR(ir->op1));
|
||||
|
@ -1065,22 +997,26 @@ static ARMIns asm_fxstoreins(IRIns *ir)
|
|||
|
||||
static void asm_fload(ASMState *as, IRIns *ir)
|
||||
{
|
||||
Reg dest = ra_dest(as, ir, RSET_GPR);
|
||||
Reg idx = ra_alloc1(as, ir->op1, RSET_GPR);
|
||||
ARMIns ai = asm_fxloadins(ir);
|
||||
int32_t ofs;
|
||||
if (ir->op2 == IRFL_TAB_ARRAY) {
|
||||
ofs = asm_fuseabase(as, ir->op1);
|
||||
if (ofs) { /* Turn the t->array load into an add for colocated arrays. */
|
||||
emit_dn(as, ARMI_ADD|ARMI_K12|ofs, dest, idx);
|
||||
return;
|
||||
if (ir->op1 == REF_NIL) {
|
||||
lua_assert(!ra_used(ir)); /* We can end up here if DCE is turned off. */
|
||||
} else {
|
||||
Reg dest = ra_dest(as, ir, RSET_GPR);
|
||||
Reg idx = ra_alloc1(as, ir->op1, RSET_GPR);
|
||||
ARMIns ai = asm_fxloadins(ir);
|
||||
int32_t ofs;
|
||||
if (ir->op2 == IRFL_TAB_ARRAY) {
|
||||
ofs = asm_fuseabase(as, ir->op1);
|
||||
if (ofs) { /* Turn the t->array load into an add for colocated arrays. */
|
||||
emit_dn(as, ARMI_ADD|ARMI_K12|ofs, dest, idx);
|
||||
return;
|
||||
}
|
||||
}
|
||||
ofs = field_ofs[ir->op2];
|
||||
if ((ai & 0x04000000))
|
||||
emit_lso(as, ai, dest, idx, ofs);
|
||||
else
|
||||
emit_lsox(as, ai, dest, idx, ofs);
|
||||
}
|
||||
ofs = field_ofs[ir->op2];
|
||||
if ((ai & 0x04000000))
|
||||
emit_lso(as, ai, dest, idx, ofs);
|
||||
else
|
||||
emit_lsox(as, ai, dest, idx, ofs);
|
||||
}
|
||||
|
||||
static void asm_fstore(ASMState *as, IRIns *ir)
|
||||
|
@ -1106,7 +1042,7 @@ static void asm_xload(ASMState *as, IRIns *ir)
|
|||
asm_fusexref(as, asm_fxloadins(ir), dest, ir->op1, RSET_GPR, 0);
|
||||
}
|
||||
|
||||
static void asm_xstore(ASMState *as, IRIns *ir, int32_t ofs)
|
||||
static void asm_xstore_(ASMState *as, IRIns *ir, int32_t ofs)
|
||||
{
|
||||
if (ir->r != RID_SINK) {
|
||||
Reg src = ra_alloc1(as, ir->op2,
|
||||
|
@ -1116,6 +1052,8 @@ static void asm_xstore(ASMState *as, IRIns *ir, int32_t ofs)
|
|||
}
|
||||
}
|
||||
|
||||
#define asm_xstore(as, ir) asm_xstore_(as, ir, 0)
|
||||
|
||||
static void asm_ahuvload(ASMState *as, IRIns *ir)
|
||||
{
|
||||
int hiop = (LJ_SOFTFP && (ir+1)->o == IR_HIOP);
|
||||
|
@ -1273,19 +1211,16 @@ dotypecheck:
|
|||
static void asm_cnew(ASMState *as, IRIns *ir)
|
||||
{
|
||||
CTState *cts = ctype_ctsG(J2G(as->J));
|
||||
CTypeID ctypeid = (CTypeID)IR(ir->op1)->i;
|
||||
CTSize sz = (ir->o == IR_CNEWI || ir->op2 == REF_NIL) ?
|
||||
lj_ctype_size(cts, ctypeid) : (CTSize)IR(ir->op2)->i;
|
||||
CTypeID id = (CTypeID)IR(ir->op1)->i;
|
||||
CTSize sz;
|
||||
CTInfo info = lj_ctype_info(cts, id, &sz);
|
||||
const CCallInfo *ci = &lj_ir_callinfo[IRCALL_lj_mem_newgco];
|
||||
IRRef args[2];
|
||||
IRRef args[4];
|
||||
RegSet allow = (RSET_GPR & ~RSET_SCRATCH);
|
||||
RegSet drop = RSET_SCRATCH;
|
||||
lua_assert(sz != CTSIZE_INVALID);
|
||||
lua_assert(sz != CTSIZE_INVALID || (ir->o == IR_CNEW && ir->op2 != REF_NIL));
|
||||
|
||||
args[0] = ASMREF_L; /* lua_State *L */
|
||||
args[1] = ASMREF_TMP1; /* MSize size */
|
||||
as->gcsteps++;
|
||||
|
||||
if (ra_hasreg(ir->r))
|
||||
rset_clear(drop, ir->r); /* Dest reg handled below. */
|
||||
ra_evictset(as, drop);
|
||||
|
@ -1307,16 +1242,28 @@ static void asm_cnew(ASMState *as, IRIns *ir)
|
|||
if (ofs == sizeof(GCcdata)) break;
|
||||
ofs -= 4; ir--;
|
||||
}
|
||||
} else if (ir->op2 != REF_NIL) { /* Create VLA/VLS/aligned cdata. */
|
||||
ci = &lj_ir_callinfo[IRCALL_lj_cdata_newv];
|
||||
args[0] = ASMREF_L; /* lua_State *L */
|
||||
args[1] = ir->op1; /* CTypeID id */
|
||||
args[2] = ir->op2; /* CTSize sz */
|
||||
args[3] = ASMREF_TMP1; /* CTSize align */
|
||||
asm_gencall(as, ci, args);
|
||||
emit_loadi(as, ra_releasetmp(as, ASMREF_TMP1), (int32_t)ctype_align(info));
|
||||
return;
|
||||
}
|
||||
|
||||
/* Initialize gct and ctypeid. lj_mem_newgco() already sets marked. */
|
||||
{
|
||||
uint32_t k = emit_isk12(ARMI_MOV, ctypeid);
|
||||
Reg r = k ? RID_R1 : ra_allock(as, ctypeid, allow);
|
||||
uint32_t k = emit_isk12(ARMI_MOV, id);
|
||||
Reg r = k ? RID_R1 : ra_allock(as, id, allow);
|
||||
emit_lso(as, ARMI_STRB, RID_TMP, RID_RET, offsetof(GCcdata, gct));
|
||||
emit_lsox(as, ARMI_STRH, r, RID_RET, offsetof(GCcdata, ctypeid));
|
||||
emit_d(as, ARMI_MOV|ARMI_K12|~LJ_TCDATA, RID_TMP);
|
||||
if (k) emit_d(as, ARMI_MOV^k, RID_R1);
|
||||
}
|
||||
args[0] = ASMREF_L; /* lua_State *L */
|
||||
args[1] = ASMREF_TMP1; /* MSize size */
|
||||
asm_gencall(as, ci, args);
|
||||
ra_allockreg(as, (int32_t)(sz+sizeof(GCcdata)),
|
||||
ra_releasetmp(as, ASMREF_TMP1));
|
||||
|
@ -1393,23 +1340,38 @@ static void asm_fpunary(ASMState *as, IRIns *ir, ARMIns ai)
|
|||
emit_dm(as, ai, (dest & 15), (left & 15));
|
||||
}
|
||||
|
||||
static int asm_fpjoin_pow(ASMState *as, IRIns *ir)
|
||||
static void asm_callround(ASMState *as, IRIns *ir, int id)
|
||||
{
|
||||
IRIns *irp = IR(ir->op1);
|
||||
if (irp == ir-1 && irp->o == IR_MUL && !ra_used(irp)) {
|
||||
IRIns *irpp = IR(irp->op1);
|
||||
if (irpp == ir-2 && irpp->o == IR_FPMATH &&
|
||||
irpp->op2 == IRFPM_LOG2 && !ra_used(irpp)) {
|
||||
const CCallInfo *ci = &lj_ir_callinfo[IRCALL_pow];
|
||||
IRRef args[2];
|
||||
args[0] = irpp->op1;
|
||||
args[1] = irp->op2;
|
||||
asm_setupresult(as, ir, ci);
|
||||
asm_gencall(as, ci, args);
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
/* The modified regs must match with the *.dasc implementation. */
|
||||
RegSet drop = RID2RSET(RID_R0)|RID2RSET(RID_R1)|RID2RSET(RID_R2)|
|
||||
RID2RSET(RID_R3)|RID2RSET(RID_R12);
|
||||
RegSet of;
|
||||
Reg dest, src;
|
||||
ra_evictset(as, drop);
|
||||
dest = ra_dest(as, ir, RSET_FPR);
|
||||
emit_dnm(as, ARMI_VMOV_D_RR, RID_RETLO, RID_RETHI, (dest & 15));
|
||||
emit_call(as, id == IRFPM_FLOOR ? (void *)lj_vm_floor_sf :
|
||||
id == IRFPM_CEIL ? (void *)lj_vm_ceil_sf :
|
||||
(void *)lj_vm_trunc_sf);
|
||||
/* Workaround to protect argument GPRs from being used for remat. */
|
||||
of = as->freeset;
|
||||
as->freeset &= ~RSET_RANGE(RID_R0, RID_R1+1);
|
||||
as->cost[RID_R0] = as->cost[RID_R1] = REGCOST(~0u, ASMREF_L);
|
||||
src = ra_alloc1(as, ir->op1, RSET_FPR); /* May alloc GPR to remat FPR. */
|
||||
as->freeset |= (of & RSET_RANGE(RID_R0, RID_R1+1));
|
||||
emit_dnm(as, ARMI_VMOV_RR_D, RID_R0, RID_R1, (src & 15));
|
||||
}
|
||||
|
||||
static void asm_fpmath(ASMState *as, IRIns *ir)
|
||||
{
|
||||
if (ir->op2 == IRFPM_EXP2 && asm_fpjoin_pow(as, ir))
|
||||
return;
|
||||
if (ir->op2 <= IRFPM_TRUNC)
|
||||
asm_callround(as, ir, ir->op2);
|
||||
else if (ir->op2 == IRFPM_SQRT)
|
||||
asm_fpunary(as, ir, ARMI_VSQRT_D);
|
||||
else
|
||||
asm_callid(as, ir, IRCALL_lj_vm_floor + ir->op2);
|
||||
}
|
||||
#endif
|
||||
|
||||
|
@ -1460,32 +1422,6 @@ static void asm_intop_s(ASMState *as, IRIns *ir, ARMIns ai)
|
|||
asm_intop(as, ir, ai);
|
||||
}
|
||||
|
||||
static void asm_bitop(ASMState *as, IRIns *ir, ARMIns ai)
|
||||
{
|
||||
if (as->flagmcp == as->mcp) { /* Try to drop cmp r, #0. */
|
||||
uint32_t cc = (as->mcp[1] >> 28);
|
||||
as->flagmcp = NULL;
|
||||
if (cc <= CC_NE) {
|
||||
as->mcp++;
|
||||
ai |= ARMI_S;
|
||||
} else if (cc == CC_GE) {
|
||||
*++as->mcp ^= ((CC_GE^CC_PL) << 28);
|
||||
ai |= ARMI_S;
|
||||
} else if (cc == CC_LT) {
|
||||
*++as->mcp ^= ((CC_LT^CC_MI) << 28);
|
||||
ai |= ARMI_S;
|
||||
} /* else: other conds don't work with bit ops. */
|
||||
}
|
||||
if (ir->op2 == 0) {
|
||||
Reg dest = ra_dest(as, ir, RSET_GPR);
|
||||
uint32_t m = asm_fuseopm(as, ai, ir->op1, RSET_GPR);
|
||||
emit_d(as, ai^m, dest);
|
||||
} else {
|
||||
/* NYI: Turn BAND !k12 into uxtb, uxth or bfc or shl+shr. */
|
||||
asm_intop(as, ir, ai);
|
||||
}
|
||||
}
|
||||
|
||||
static void asm_intneg(ASMState *as, IRIns *ir, ARMIns ai)
|
||||
{
|
||||
Reg dest = ra_dest(as, ir, RSET_GPR);
|
||||
|
@ -1551,6 +1487,20 @@ static void asm_mul(ASMState *as, IRIns *ir)
|
|||
asm_intmul(as, ir);
|
||||
}
|
||||
|
||||
#define asm_addov(as, ir) asm_add(as, ir)
|
||||
#define asm_subov(as, ir) asm_sub(as, ir)
|
||||
#define asm_mulov(as, ir) asm_mul(as, ir)
|
||||
|
||||
#if !LJ_SOFTFP
|
||||
#define asm_div(as, ir) asm_fparith(as, ir, ARMI_VDIV_D)
|
||||
#define asm_pow(as, ir) asm_callid(as, ir, IRCALL_lj_vm_powi)
|
||||
#define asm_abs(as, ir) asm_fpunary(as, ir, ARMI_VABS_D)
|
||||
#define asm_atan2(as, ir) asm_callid(as, ir, IRCALL_atan2)
|
||||
#define asm_ldexp(as, ir) asm_callid(as, ir, IRCALL_ldexp)
|
||||
#endif
|
||||
|
||||
#define asm_mod(as, ir) asm_callid(as, ir, IRCALL_lj_vm_modi)
|
||||
|
||||
static void asm_neg(ASMState *as, IRIns *ir)
|
||||
{
|
||||
#if !LJ_SOFTFP
|
||||
|
@ -1562,41 +1512,35 @@ static void asm_neg(ASMState *as, IRIns *ir)
|
|||
asm_intneg(as, ir, ARMI_RSB);
|
||||
}
|
||||
|
||||
static void asm_callid(ASMState *as, IRIns *ir, IRCallID id)
|
||||
static void asm_bitop(ASMState *as, IRIns *ir, ARMIns ai)
|
||||
{
|
||||
const CCallInfo *ci = &lj_ir_callinfo[id];
|
||||
IRRef args[2];
|
||||
args[0] = ir->op1;
|
||||
args[1] = ir->op2;
|
||||
asm_setupresult(as, ir, ci);
|
||||
asm_gencall(as, ci, args);
|
||||
if (as->flagmcp == as->mcp) { /* Try to drop cmp r, #0. */
|
||||
uint32_t cc = (as->mcp[1] >> 28);
|
||||
as->flagmcp = NULL;
|
||||
if (cc <= CC_NE) {
|
||||
as->mcp++;
|
||||
ai |= ARMI_S;
|
||||
} else if (cc == CC_GE) {
|
||||
*++as->mcp ^= ((CC_GE^CC_PL) << 28);
|
||||
ai |= ARMI_S;
|
||||
} else if (cc == CC_LT) {
|
||||
*++as->mcp ^= ((CC_LT^CC_MI) << 28);
|
||||
ai |= ARMI_S;
|
||||
} /* else: other conds don't work with bit ops. */
|
||||
}
|
||||
if (ir->op2 == 0) {
|
||||
Reg dest = ra_dest(as, ir, RSET_GPR);
|
||||
uint32_t m = asm_fuseopm(as, ai, ir->op1, RSET_GPR);
|
||||
emit_d(as, ai^m, dest);
|
||||
} else {
|
||||
/* NYI: Turn BAND !k12 into uxtb, uxth or bfc or shl+shr. */
|
||||
asm_intop(as, ir, ai);
|
||||
}
|
||||
}
|
||||
|
||||
#if !LJ_SOFTFP
|
||||
static void asm_callround(ASMState *as, IRIns *ir, int id)
|
||||
{
|
||||
/* The modified regs must match with the *.dasc implementation. */
|
||||
RegSet drop = RID2RSET(RID_R0)|RID2RSET(RID_R1)|RID2RSET(RID_R2)|
|
||||
RID2RSET(RID_R3)|RID2RSET(RID_R12);
|
||||
RegSet of;
|
||||
Reg dest, src;
|
||||
ra_evictset(as, drop);
|
||||
dest = ra_dest(as, ir, RSET_FPR);
|
||||
emit_dnm(as, ARMI_VMOV_D_RR, RID_RETLO, RID_RETHI, (dest & 15));
|
||||
emit_call(as, id == IRFPM_FLOOR ? (void *)lj_vm_floor_sf :
|
||||
id == IRFPM_CEIL ? (void *)lj_vm_ceil_sf :
|
||||
(void *)lj_vm_trunc_sf);
|
||||
/* Workaround to protect argument GPRs from being used for remat. */
|
||||
of = as->freeset;
|
||||
as->freeset &= ~RSET_RANGE(RID_R0, RID_R1+1);
|
||||
as->cost[RID_R0] = as->cost[RID_R1] = REGCOST(~0u, ASMREF_L);
|
||||
src = ra_alloc1(as, ir->op1, RSET_FPR); /* May alloc GPR to remat FPR. */
|
||||
as->freeset |= (of & RSET_RANGE(RID_R0, RID_R1+1));
|
||||
emit_dnm(as, ARMI_VMOV_RR_D, RID_R0, RID_R1, (src & 15));
|
||||
}
|
||||
#endif
|
||||
#define asm_bnot(as, ir) asm_bitop(as, ir, ARMI_MVN)
|
||||
|
||||
static void asm_bitswap(ASMState *as, IRIns *ir)
|
||||
static void asm_bswap(ASMState *as, IRIns *ir)
|
||||
{
|
||||
Reg dest = ra_dest(as, ir, RSET_GPR);
|
||||
Reg left = ra_alloc1(as, ir->op1, RSET_GPR);
|
||||
|
@ -1613,6 +1557,10 @@ static void asm_bitswap(ASMState *as, IRIns *ir)
|
|||
}
|
||||
}
|
||||
|
||||
#define asm_band(as, ir) asm_bitop(as, ir, ARMI_AND)
|
||||
#define asm_bor(as, ir) asm_bitop(as, ir, ARMI_ORR)
|
||||
#define asm_bxor(as, ir) asm_bitop(as, ir, ARMI_EOR)
|
||||
|
||||
static void asm_bitshift(ASMState *as, IRIns *ir, ARMShift sh)
|
||||
{
|
||||
if (irref_isk(ir->op2)) { /* Constant shifts. */
|
||||
|
@ -1630,6 +1578,12 @@ static void asm_bitshift(ASMState *as, IRIns *ir, ARMShift sh)
|
|||
}
|
||||
}
|
||||
|
||||
#define asm_bshl(as, ir) asm_bitshift(as, ir, ARMSH_LSL)
|
||||
#define asm_bshr(as, ir) asm_bitshift(as, ir, ARMSH_LSR)
|
||||
#define asm_bsar(as, ir) asm_bitshift(as, ir, ARMSH_ASR)
|
||||
#define asm_bror(as, ir) asm_bitshift(as, ir, ARMSH_ROR)
|
||||
#define asm_brol(as, ir) lua_assert(0)
|
||||
|
||||
static void asm_intmin_max(ASMState *as, IRIns *ir, int cc)
|
||||
{
|
||||
uint32_t kcmp = 0, kmov = 0;
|
||||
|
@ -1703,6 +1657,9 @@ static void asm_min_max(ASMState *as, IRIns *ir, int cc, int fcc)
|
|||
asm_intmin_max(as, ir, cc);
|
||||
}
|
||||
|
||||
#define asm_min(as, ir) asm_min_max(as, ir, CC_GT, CC_HI)
|
||||
#define asm_max(as, ir) asm_min_max(as, ir, CC_LT, CC_LO)
|
||||
|
||||
/* -- Comparisons --------------------------------------------------------- */
|
||||
|
||||
/* Map of comparisons to flags. ORDER IR. */
|
||||
|
@ -1818,6 +1775,18 @@ notst:
|
|||
as->flagmcp = as->mcp; /* Allow elimination of the compare. */
|
||||
}
|
||||
|
||||
static void asm_comp(ASMState *as, IRIns *ir)
|
||||
{
|
||||
#if !LJ_SOFTFP
|
||||
if (irt_isnum(ir->t))
|
||||
asm_fpcomp(as, ir);
|
||||
else
|
||||
#endif
|
||||
asm_intcomp(as, ir);
|
||||
}
|
||||
|
||||
#define asm_equal(as, ir) asm_comp(as, ir)
|
||||
|
||||
#if LJ_HASFFI
|
||||
/* 64 bit integer comparisons. */
|
||||
static void asm_int64comp(ASMState *as, IRIns *ir)
|
||||
|
@ -1892,7 +1861,7 @@ static void asm_hiop(ASMState *as, IRIns *ir)
|
|||
#endif
|
||||
} else if ((ir-1)->o == IR_XSTORE) {
|
||||
if ((ir-1)->r != RID_SINK)
|
||||
asm_xstore(as, ir, 4);
|
||||
asm_xstore_(as, ir, 4);
|
||||
return;
|
||||
}
|
||||
if (!usehi) return; /* Skip unused hiword op for all remaining ops. */
|
||||
|
@ -1940,6 +1909,16 @@ static void asm_hiop(ASMState *as, IRIns *ir)
|
|||
#endif
|
||||
}
|
||||
|
||||
/* -- Profiling ----------------------------------------------------------- */
|
||||
|
||||
static void asm_prof(ASMState *as, IRIns *ir)
|
||||
{
|
||||
UNUSED(ir);
|
||||
asm_guardcc(as, CC_NE);
|
||||
emit_n(as, ARMI_TST|ARMI_K12|HOOK_PROFILE, RID_TMP);
|
||||
emit_lsptr(as, ARMI_LDRB, RID_TMP, (void *)&J2G(as->J)->hookmask);
|
||||
}
|
||||
|
||||
/* -- Stack handling ------------------------------------------------------ */
|
||||
|
||||
/* Check Lua stack size for overflow. Use exit handler as fallback. */
|
||||
|
@ -1969,7 +1948,7 @@ static void asm_stack_check(ASMState *as, BCReg topslot,
|
|||
emit_lso(as, ARMI_LDR, RID_TMP, RID_TMP,
|
||||
(int32_t)offsetof(lua_State, maxstack));
|
||||
if (irp) { /* Must not spill arbitrary registers in head of side trace. */
|
||||
int32_t i = i32ptr(&J2G(as->J)->jit_L);
|
||||
int32_t i = i32ptr(&J2G(as->J)->cur_L);
|
||||
if (ra_hasspill(irp->s))
|
||||
emit_lso(as, ARMI_LDR, pbase, RID_SP, sps_scale(irp->s));
|
||||
emit_lso(as, ARMI_LDR, RID_TMP, RID_TMP, (i & 4095));
|
||||
|
@ -1977,7 +1956,7 @@ static void asm_stack_check(ASMState *as, BCReg topslot,
|
|||
emit_lso(as, ARMI_STR, RID_RET, RID_SP, 0); /* Save temp. register. */
|
||||
emit_loadi(as, RID_TMP, (i & ~4095));
|
||||
} else {
|
||||
emit_getgl(as, RID_TMP, jit_L);
|
||||
emit_getgl(as, RID_TMP, cur_L);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -2086,13 +2065,13 @@ static void asm_loop_fixup(ASMState *as)
|
|||
|
||||
/* -- Head of trace ------------------------------------------------------- */
|
||||
|
||||
/* Reload L register from g->jit_L. */
|
||||
/* Reload L register from g->cur_L. */
|
||||
static void asm_head_lreg(ASMState *as)
|
||||
{
|
||||
IRIns *ir = IR(ASMREF_L);
|
||||
if (ra_used(ir)) {
|
||||
Reg r = ra_dest(as, ir, RSET_GPR);
|
||||
emit_getgl(as, r, jit_L);
|
||||
emit_getgl(as, r, cur_L);
|
||||
ra_evictk(as);
|
||||
}
|
||||
}
|
||||
|
@ -2163,143 +2142,13 @@ static void asm_tail_prep(ASMState *as)
|
|||
*p = 0; /* Prevent load/store merging. */
|
||||
}
|
||||
|
||||
/* -- Instruction dispatch ------------------------------------------------ */
|
||||
|
||||
/* Assemble a single instruction. */
|
||||
static void asm_ir(ASMState *as, IRIns *ir)
|
||||
{
|
||||
switch ((IROp)ir->o) {
|
||||
/* Miscellaneous ops. */
|
||||
case IR_LOOP: asm_loop(as); break;
|
||||
case IR_NOP: case IR_XBAR: lua_assert(!ra_used(ir)); break;
|
||||
case IR_USE:
|
||||
ra_alloc1(as, ir->op1, irt_isfp(ir->t) ? RSET_FPR : RSET_GPR); break;
|
||||
case IR_PHI: asm_phi(as, ir); break;
|
||||
case IR_HIOP: asm_hiop(as, ir); break;
|
||||
case IR_GCSTEP: asm_gcstep(as, ir); break;
|
||||
|
||||
/* Guarded assertions. */
|
||||
case IR_EQ: case IR_NE:
|
||||
if ((ir-1)->o == IR_HREF && ir->op1 == as->curins-1) {
|
||||
as->curins--;
|
||||
asm_href(as, ir-1, (IROp)ir->o);
|
||||
break;
|
||||
}
|
||||
/* fallthrough */
|
||||
case IR_LT: case IR_GE: case IR_LE: case IR_GT:
|
||||
case IR_ULT: case IR_UGE: case IR_ULE: case IR_UGT:
|
||||
case IR_ABC:
|
||||
#if !LJ_SOFTFP
|
||||
if (irt_isnum(ir->t)) { asm_fpcomp(as, ir); break; }
|
||||
#endif
|
||||
asm_intcomp(as, ir);
|
||||
break;
|
||||
|
||||
case IR_RETF: asm_retf(as, ir); break;
|
||||
|
||||
/* Bit ops. */
|
||||
case IR_BNOT: asm_bitop(as, ir, ARMI_MVN); break;
|
||||
case IR_BSWAP: asm_bitswap(as, ir); break;
|
||||
|
||||
case IR_BAND: asm_bitop(as, ir, ARMI_AND); break;
|
||||
case IR_BOR: asm_bitop(as, ir, ARMI_ORR); break;
|
||||
case IR_BXOR: asm_bitop(as, ir, ARMI_EOR); break;
|
||||
|
||||
case IR_BSHL: asm_bitshift(as, ir, ARMSH_LSL); break;
|
||||
case IR_BSHR: asm_bitshift(as, ir, ARMSH_LSR); break;
|
||||
case IR_BSAR: asm_bitshift(as, ir, ARMSH_ASR); break;
|
||||
case IR_BROR: asm_bitshift(as, ir, ARMSH_ROR); break;
|
||||
case IR_BROL: lua_assert(0); break;
|
||||
|
||||
/* Arithmetic ops. */
|
||||
case IR_ADD: case IR_ADDOV: asm_add(as, ir); break;
|
||||
case IR_SUB: case IR_SUBOV: asm_sub(as, ir); break;
|
||||
case IR_MUL: case IR_MULOV: asm_mul(as, ir); break;
|
||||
case IR_MOD: asm_callid(as, ir, IRCALL_lj_vm_modi); break;
|
||||
case IR_NEG: asm_neg(as, ir); break;
|
||||
|
||||
#if LJ_SOFTFP
|
||||
case IR_DIV: case IR_POW: case IR_ABS:
|
||||
case IR_ATAN2: case IR_LDEXP: case IR_FPMATH: case IR_TOBIT:
|
||||
lua_assert(0); /* Unused for LJ_SOFTFP. */
|
||||
break;
|
||||
#else
|
||||
case IR_DIV: asm_fparith(as, ir, ARMI_VDIV_D); break;
|
||||
case IR_POW: asm_callid(as, ir, IRCALL_lj_vm_powi); break;
|
||||
case IR_ABS: asm_fpunary(as, ir, ARMI_VABS_D); break;
|
||||
case IR_ATAN2: asm_callid(as, ir, IRCALL_atan2); break;
|
||||
case IR_LDEXP: asm_callid(as, ir, IRCALL_ldexp); break;
|
||||
case IR_FPMATH:
|
||||
if (ir->op2 == IRFPM_EXP2 && asm_fpjoin_pow(as, ir))
|
||||
break;
|
||||
if (ir->op2 <= IRFPM_TRUNC)
|
||||
asm_callround(as, ir, ir->op2);
|
||||
else if (ir->op2 == IRFPM_SQRT)
|
||||
asm_fpunary(as, ir, ARMI_VSQRT_D);
|
||||
else
|
||||
asm_callid(as, ir, IRCALL_lj_vm_floor + ir->op2);
|
||||
break;
|
||||
case IR_TOBIT: asm_tobit(as, ir); break;
|
||||
#endif
|
||||
|
||||
case IR_MIN: asm_min_max(as, ir, CC_GT, CC_HI); break;
|
||||
case IR_MAX: asm_min_max(as, ir, CC_LT, CC_LO); break;
|
||||
|
||||
/* Memory references. */
|
||||
case IR_AREF: asm_aref(as, ir); break;
|
||||
case IR_HREF: asm_href(as, ir, 0); break;
|
||||
case IR_HREFK: asm_hrefk(as, ir); break;
|
||||
case IR_NEWREF: asm_newref(as, ir); break;
|
||||
case IR_UREFO: case IR_UREFC: asm_uref(as, ir); break;
|
||||
case IR_FREF: asm_fref(as, ir); break;
|
||||
case IR_STRREF: asm_strref(as, ir); break;
|
||||
|
||||
/* Loads and stores. */
|
||||
case IR_ALOAD: case IR_HLOAD: case IR_ULOAD: case IR_VLOAD:
|
||||
asm_ahuvload(as, ir);
|
||||
break;
|
||||
case IR_FLOAD: asm_fload(as, ir); break;
|
||||
case IR_XLOAD: asm_xload(as, ir); break;
|
||||
case IR_SLOAD: asm_sload(as, ir); break;
|
||||
|
||||
case IR_ASTORE: case IR_HSTORE: case IR_USTORE: asm_ahustore(as, ir); break;
|
||||
case IR_FSTORE: asm_fstore(as, ir); break;
|
||||
case IR_XSTORE: asm_xstore(as, ir, 0); break;
|
||||
|
||||
/* Allocations. */
|
||||
case IR_SNEW: case IR_XSNEW: asm_snew(as, ir); break;
|
||||
case IR_TNEW: asm_tnew(as, ir); break;
|
||||
case IR_TDUP: asm_tdup(as, ir); break;
|
||||
case IR_CNEW: case IR_CNEWI: asm_cnew(as, ir); break;
|
||||
|
||||
/* Write barriers. */
|
||||
case IR_TBAR: asm_tbar(as, ir); break;
|
||||
case IR_OBAR: asm_obar(as, ir); break;
|
||||
|
||||
/* Type conversions. */
|
||||
case IR_CONV: asm_conv(as, ir); break;
|
||||
case IR_TOSTR: asm_tostr(as, ir); break;
|
||||
case IR_STRTO: asm_strto(as, ir); break;
|
||||
|
||||
/* Calls. */
|
||||
case IR_CALLN: case IR_CALLL: case IR_CALLS: asm_call(as, ir); break;
|
||||
case IR_CALLXS: asm_callx(as, ir); break;
|
||||
case IR_CARG: break;
|
||||
|
||||
default:
|
||||
setintV(&as->J->errinfo, ir->o);
|
||||
lj_trace_err_info(as->J, LJ_TRERR_NYIIR);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/* -- Trace setup --------------------------------------------------------- */
|
||||
|
||||
/* Ensure there are enough stack slots for call arguments. */
|
||||
static Reg asm_setup_call_slots(ASMState *as, IRIns *ir, const CCallInfo *ci)
|
||||
{
|
||||
IRRef args[CCI_NARGS_MAX*2];
|
||||
uint32_t i, nargs = (int)CCI_NARGS(ci);
|
||||
uint32_t i, nargs = CCI_XNARGS(ci);
|
||||
int nslots = 0, ngpr = REGARG_NUMGPR, nfpr = REGARG_NUMFPR, fprodd = 0;
|
||||
asm_collectargs(as, ir, ci, args);
|
||||
for (i = 0; i < nargs; i++) {
|
||||
|
|
2022
vendor/luajit/src/lj_asm_arm64.h
vendored
Normal file
2022
vendor/luajit/src/lj_asm_arm64.h
vendored
Normal file
File diff suppressed because it is too large
Load diff
Some files were not shown because too many files have changed in this diff Show more
Loading…
Reference in a new issue