diff options
author | Akira Kakuto <kakuto@fuk.kindai.ac.jp> | 2016-03-09 22:32:00 +0000 |
---|---|---|
committer | Akira Kakuto <kakuto@fuk.kindai.ac.jp> | 2016-03-09 22:32:00 +0000 |
commit | 1f16f479df5678daa28b623d9d747b84b3bd0e30 (patch) | |
tree | db4533086788267005152e0c17043ddf5823a181 /Build/source/libs/luajit/LuaJIT-src | |
parent | 337d391352594f8970e748077c3c43985f9e8655 (diff) |
libs/luajit: sync with the upstream
git-svn-id: svn://tug.org/texlive/trunk@39980 c570f23f-e606-0410-a88d-b1316a301751
Diffstat (limited to 'Build/source/libs/luajit/LuaJIT-src')
199 files changed, 11174 insertions, 8707 deletions
diff --git a/Build/source/libs/luajit/LuaJIT-src/COPYRIGHT b/Build/source/libs/luajit/LuaJIT-src/COPYRIGHT index 1ef7df62446..b614d3eb4b7 100644 --- a/Build/source/libs/luajit/LuaJIT-src/COPYRIGHT +++ b/Build/source/libs/luajit/LuaJIT-src/COPYRIGHT @@ -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-2016 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 diff --git a/Build/source/libs/luajit/LuaJIT-src/Makefile b/Build/source/libs/luajit/LuaJIT-src/Makefile index 8ce773e3936..f6446ba4d3f 100644 --- a/Build/source/libs/luajit/LuaJIT-src/Makefile +++ b/Build/source/libs/luajit/LuaJIT-src/Makefile @@ -10,13 +10,13 @@ # For MSVC, please follow the instructions given in src/msvcbuild.bat. # For MinGW and Cygwin, cd to src and run make with the Makefile there. # -# Copyright (C) 2005-2015 Mike Pall. See Copyright Notice in luajit.h +# Copyright (C) 2005-2016 Mike Pall. See Copyright Notice in luajit.h ############################################################################## MAJVER= 2 MINVER= 1 RELVER= 0 -PREREL= -beta1 +PREREL= -beta2 VERSION= $(MAJVER).$(MINVER).$(RELVER)$(PREREL) ABIVER= 5.1 diff --git a/Build/source/libs/luajit/LuaJIT-src/README b/Build/source/libs/luajit/LuaJIT-src/README index 951ddbf9c7f..01fd4a0c937 100644 --- a/Build/source/libs/luajit/LuaJIT-src/README +++ b/Build/source/libs/luajit/LuaJIT-src/README @@ -1,16 +1,16 @@ -README for LuaJIT 2.1.0-beta1
------------------------------
-
-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 free software, released under the MIT license.
-See full Copyright Notice in the COPYRIGHT file or in luajit.h.
-
-Documentation for LuaJIT is available in HTML format.
-Please point your favorite browser to:
-
- doc/luajit.html
-
+README for LuaJIT 2.1.0-beta2 +----------------------------- + +LuaJIT is a Just-In-Time (JIT) compiler for the Lua programming language. + +Project Homepage: http://luajit.org/ + +LuaJIT is Copyright (C) 2005-2016 Mike Pall. +LuaJIT is free software, released under the MIT license. +See full Copyright Notice in the COPYRIGHT file or in luajit.h. + +Documentation for LuaJIT is available in HTML format. +Please point your favorite browser to: + + doc/luajit.html + diff --git a/Build/source/libs/luajit/LuaJIT-src/doc/bluequad-print.css b/Build/source/libs/luajit/LuaJIT-src/doc/bluequad-print.css index dc62ce5c4ca..975a55bfa31 100644 --- a/Build/source/libs/luajit/LuaJIT-src/doc/bluequad-print.css +++ b/Build/source/libs/luajit/LuaJIT-src/doc/bluequad-print.css @@ -1,166 +1,166 @@ -/* Copyright (C) 2004-2015 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;
-}
+/* Copyright (C) 2004-2016 Mike Pall. + * + * You are welcome to use the general ideas of this design for your own sites. + * But please do not steal the stylesheet, the layout or the color scheme. + */ +body { + font-family: serif; + font-size: 11pt; + margin: 0 3em; + padding: 0; + border: none; +} +a:link, a:visited, a:hover, a:active { + text-decoration: none; + background: transparent; + color: #0000ff; +} +h1, h2, h3 { + font-family: sans-serif; + font-weight: bold; + text-align: left; + margin: 0.5em 0; + padding: 0; +} +h1 { + font-size: 200%; +} +h2 { + font-size: 150%; +} +h3 { + font-size: 125%; +} +p { + margin: 0 0 0.5em 0; + padding: 0; +} +ul, ol { + margin: 0.5em 0; + padding: 0 0 0 2em; +} +ul { + list-style: outside square; +} +ol { + list-style: outside decimal; +} +li { + margin: 0; + padding: 0; +} +dl { + margin: 1em 0; + padding: 1em; + border: 1px solid black; +} +dt { + font-weight: bold; + margin: 0; + padding: 0; +} +dt sup { + float: right; + margin-left: 1em; +} +dd { + margin: 0.5em 0 0 2em; + padding: 0; +} +table { + table-layout: fixed; + width: 100%; + margin: 1em 0; + padding: 0; + border: 1px solid black; + border-spacing: 0; + border-collapse: collapse; +} +tr { + margin: 0; + padding: 0; + border: none; +} +td { + text-align: left; + margin: 0; + padding: 0.2em 0.5em; + border-top: 1px solid black; + border-bottom: 1px solid black; +} +tr.separate td { + border-top: double; +} +tt, pre, code, kbd, samp { + font-family: monospace; + font-size: 75%; +} +kbd { + font-weight: bolder; +} +blockquote, pre { + margin: 1em 2em; + padding: 0; +} +img { + border: none; + vertical-align: baseline; + margin: 0; + padding: 0; +} +img.left { + float: left; + margin: 0.5em 1em 0.5em 0; +} +img.right { + float: right; + margin: 0.5em 0 0.5em 1em; +} +.flush { + clear: both; + visibility: hidden; +} +.hide, .noprint, #nav { + display: none !important; +} +.pagebreak { + page-break-before: always; +} +#site { + text-align: right; + font-family: sans-serif; + font-weight: bold; + margin: 0 1em; + border-bottom: 1pt solid black; +} +#site a { + font-size: 1.2em; +} +#site a:link, #site a:visited { + text-decoration: none; + font-weight: bold; + background: transparent; + color: #ffffff; +} +#logo { + color: #ff8000; +} +#head { + clear: both; + margin: 0 1em; +} +#main { + line-height: 1.3; + text-align: justify; + margin: 1em; +} +#foot { + clear: both; + font-size: 80%; + text-align: center; + margin: 0 1.25em; + padding: 0.5em 0 0 0; + border-top: 1pt solid black; + page-break-before: avoid; + page-break-after: avoid; +} diff --git a/Build/source/libs/luajit/LuaJIT-src/doc/bluequad.css b/Build/source/libs/luajit/LuaJIT-src/doc/bluequad.css index 6839e0a76b4..5dca9064e82 100644 --- a/Build/source/libs/luajit/LuaJIT-src/doc/bluequad.css +++ b/Build/source/libs/luajit/LuaJIT-src/doc/bluequad.css @@ -1,325 +1,325 @@ -/* Copyright (C) 2004-2015 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;
-}
+/* Copyright (C) 2004-2016 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; +} diff --git a/Build/source/libs/luajit/LuaJIT-src/doc/changes.html b/Build/source/libs/luajit/LuaJIT-src/doc/changes.html index dcf60b68ddd..9684d7c0a19 100644 --- a/Build/source/libs/luajit/LuaJIT-src/doc/changes.html +++ b/Build/source/libs/luajit/LuaJIT-src/doc/changes.html @@ -1,804 +1,817 @@ -<!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-2015, 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.4</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-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.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-2015 Mike Pall
-<span class="noprint">
-·
-<a href="contact.html">Contact</a>
-</span>
-</div>
-</body>
-</html>
+<!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-2016, 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.4</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-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.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-2016 Mike Pall +<span class="noprint"> +· +<a href="contact.html">Contact</a> +</span> +</div> +</body> +</html> diff --git a/Build/source/libs/luajit/LuaJIT-src/doc/contact.html b/Build/source/libs/luajit/LuaJIT-src/doc/contact.html index 4bba550f9cd..5262376464c 100644 --- a/Build/source/libs/luajit/LuaJIT-src/doc/contact.html +++ b/Build/source/libs/luajit/LuaJIT-src/doc/contact.html @@ -1,104 +1,104 @@ -<!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-2015, 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>
-Please send general questions to the
-<a href="http://luajit.org/list.html"><span class="ext">»</span> LuaJIT mailing list</a>.
-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-2015 Mike Pall.
-</p>
-
-
-<br class="flush">
-</div>
-<div id="foot">
-<hr class="hide">
-Copyright © 2005-2015 Mike Pall
-<span class="noprint">
-·
-<a href="contact.html">Contact</a>
-</span>
-</div>
-</body>
-</html>
+<!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-2016, 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> +Please send general questions to the +<a href="http://luajit.org/list.html"><span class="ext">»</span> LuaJIT mailing list</a>. +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-2016 Mike Pall. +</p> + + +<br class="flush"> +</div> +<div id="foot"> +<hr class="hide"> +Copyright © 2005-2016 Mike Pall +<span class="noprint"> +· +<a href="contact.html">Contact</a> +</span> +</div> +</body> +</html> diff --git a/Build/source/libs/luajit/LuaJIT-src/doc/ext_c_api.html b/Build/source/libs/luajit/LuaJIT-src/doc/ext_c_api.html index 650032c29b1..e1af3ed004d 100644 --- a/Build/source/libs/luajit/LuaJIT-src/doc/ext_c_api.html +++ b/Build/source/libs/luajit/LuaJIT-src/doc/ext_c_api.html @@ -1,189 +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-2015, 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-2015 Mike Pall
-<span class="noprint">
-·
-<a href="contact.html">Contact</a>
-</span>
-</div>
-</body>
-</html>
+<!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-2016, 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-2016 Mike Pall +<span class="noprint"> +· +<a href="contact.html">Contact</a> +</span> +</div> +</body> +</html> diff --git a/Build/source/libs/luajit/LuaJIT-src/doc/ext_ffi.html b/Build/source/libs/luajit/LuaJIT-src/doc/ext_ffi.html index 652df6cbaf0..d814f4d04a3 100644 --- a/Build/source/libs/luajit/LuaJIT-src/doc/ext_ffi.html +++ b/Build/source/libs/luajit/LuaJIT-src/doc/ext_ffi.html @@ -1,332 +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-2015, 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-2015 Mike Pall
-<span class="noprint">
-·
-<a href="contact.html">Contact</a>
-</span>
-</div>
-</body>
-</html>
+<!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-2016, 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-2016 Mike Pall +<span class="noprint"> +· +<a href="contact.html">Contact</a> +</span> +</div> +</body> +</html> diff --git a/Build/source/libs/luajit/LuaJIT-src/doc/ext_ffi_api.html b/Build/source/libs/luajit/LuaJIT-src/doc/ext_ffi_api.html index b27e4675f96..6d405960092 100644 --- a/Build/source/libs/luajit/LuaJIT-src/doc/ext_ffi_api.html +++ b/Build/source/libs/luajit/LuaJIT-src/doc/ext_ffi_api.html @@ -1,570 +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-2015, 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-2015 Mike Pall
-<span class="noprint">
-·
-<a href="contact.html">Contact</a>
-</span>
-</div>
-</body>
-</html>
+<!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-2016, 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-2016 Mike Pall +<span class="noprint"> +· +<a href="contact.html">Contact</a> +</span> +</div> +</body> +</html> diff --git a/Build/source/libs/luajit/LuaJIT-src/doc/ext_ffi_semantics.html b/Build/source/libs/luajit/LuaJIT-src/doc/ext_ffi_semantics.html index b231ac289d5..15843d7cc57 100644 --- a/Build/source/libs/luajit/LuaJIT-src/doc/ext_ffi_semantics.html +++ b/Build/source/libs/luajit/LuaJIT-src/doc/ext_ffi_semantics.html @@ -1,1261 +1,1263 @@ -<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
-<html>
-<head>
-<title>FFI Semantics</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-2015, 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.convtable { line-height: 1.2; }
-tr.convhead td { font-weight: bold; }
-td.convop { font-style: italic; width: 40%; }
-</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 Semantics</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 class="current" 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 detailed semantics underlying the FFI library
-and its interaction with both Lua and C code.
-</p>
-<p>
-Given that the FFI library is designed to interface with C code
-and that declarations can be written in plain C syntax, <b>it
-closely follows the C language semantics</b>, wherever possible.
-Some minor concessions are needed for smoother interoperation with Lua
-language semantics.
-</p>
-<p>
-Please don't be overwhelmed by the contents of this page — this
-is a reference and you may need to consult it, if in doubt. It doesn't
-hurt to skim this page, but most of the semantics "just work" as you'd
-expect them to work. It should be straightforward to write
-applications using the LuaJIT FFI for developers with a C or C++
-background.
-</p>
-
-<h2 id="clang">C Language Support</h2>
-<p>
-The FFI library has a built-in C parser with a minimal memory
-footprint. It's used by the <a href="ext_ffi_api.html">ffi.* library
-functions</a> to declare C types or external symbols.
-</p>
-<p>
-It's only purpose is to parse C declarations, as found e.g. in
-C header files. Although it does evaluate constant expressions,
-it's <em>not</em> a C compiler. The body of <tt>inline</tt>
-C function definitions is simply ignored.
-</p>
-<p>
-Also, this is <em>not</em> a validating C parser. It expects and
-accepts correctly formed C declarations, but it may choose to
-ignore bad declarations or show rather generic error messages. If in
-doubt, please check the input against your favorite C compiler.
-</p>
-<p>
-The C parser complies to the <b>C99 language standard</b> plus
-the following extensions:
-</p>
-<ul>
-
-<li>The <tt>'\e'</tt> escape in character and string literals.</li>
-
-<li>The C99/C++ boolean type, declared with the keywords <tt>bool</tt>
-or <tt>_Bool</tt>.</li>
-
-<li>Complex numbers, declared with the keywords <tt>complex</tt> or
-<tt>_Complex</tt>.</li>
-
-<li>Two complex number types: <tt>complex</tt> (aka
-<tt>complex double</tt>) and <tt>complex float</tt>.</li>
-
-<li>Vector types, declared with the GCC <tt>mode</tt> or
-<tt>vector_size</tt> attribute.</li>
-
-<li>Unnamed ('transparent') <tt>struct</tt>/<tt>union</tt> fields
-inside a <tt>struct</tt>/<tt>union</tt>.</li>
-
-<li>Incomplete <tt>enum</tt> declarations, handled like incomplete
-<tt>struct</tt> declarations.</li>
-
-<li>Unnamed <tt>enum</tt> fields inside a
-<tt>struct</tt>/<tt>union</tt>. This is similar to a scoped C++
-<tt>enum</tt>, except that declared constants are visible in the
-global namespace, too.</li>
-
-<li>Scoped <tt>static const</tt> declarations inside a
-<tt>struct</tt>/<tt>union</tt> (from C++).</li>
-
-<li>Zero-length arrays (<tt>[0]</tt>), empty
-<tt>struct</tt>/<tt>union</tt>, variable-length arrays (VLA,
-<tt>[?]</tt>) and variable-length structs (VLS, with a trailing
-VLA).</li>
-
-<li>C++ reference types (<tt>int &x</tt>).</li>
-
-<li>Alternate GCC keywords with '<tt>__</tt>', e.g.
-<tt>__const__</tt>.</li>
-
-<li>GCC <tt>__attribute__</tt> with the following attributes:
-<tt>aligned</tt>, <tt>packed</tt>, <tt>mode</tt>,
-<tt>vector_size</tt>, <tt>cdecl</tt>, <tt>fastcall</tt>,
-<tt>stdcall</tt>, <tt>thiscall</tt>.</li>
-
-<li>The GCC <tt>__extension__</tt> keyword and the GCC
-<tt>__alignof__</tt> operator.</li>
-
-<li>GCC <tt>__asm__("symname")</tt> symbol name redirection for
-function declarations.</li>
-
-<li>MSVC keywords for fixed-length types: <tt>__int8</tt>,
-<tt>__int16</tt>, <tt>__int32</tt> and <tt>__int64</tt>.</li>
-
-<li>MSVC <tt>__cdecl</tt>, <tt>__fastcall</tt>, <tt>__stdcall</tt>,
-<tt>__thiscall</tt>, <tt>__ptr32</tt>, <tt>__ptr64</tt>,
-<tt>__declspec(align(n))</tt> and <tt>#pragma pack</tt>.</li>
-
-<li>All other GCC/MSVC-specific attributes are ignored.</li>
-
-</ul>
-<p>
-The following C types are pre-defined by the C parser (like
-a <tt>typedef</tt>, except re-declarations will be ignored):
-</p>
-<ul>
-
-<li>Vararg handling: <tt>va_list</tt>, <tt>__builtin_va_list</tt>,
-<tt>__gnuc_va_list</tt>.</li>
-
-<li>From <tt><stddef.h></tt>: <tt>ptrdiff_t</tt>,
-<tt>size_t</tt>, <tt>wchar_t</tt>.</li>
-
-<li>From <tt><stdint.h></tt>: <tt>int8_t</tt>, <tt>int16_t</tt>,
-<tt>int32_t</tt>, <tt>int64_t</tt>, <tt>uint8_t</tt>,
-<tt>uint16_t</tt>, <tt>uint32_t</tt>, <tt>uint64_t</tt>,
-<tt>intptr_t</tt>, <tt>uintptr_t</tt>.</li>
-
-</ul>
-<p>
-You're encouraged to use these types in preference to
-compiler-specific extensions or target-dependent standard types.
-E.g. <tt>char</tt> differs in signedness and <tt>long</tt> differs in
-size, depending on the target architecture and platform ABI.
-</p>
-<p>
-The following C features are <b>not</b> supported:
-</p>
-<ul>
-
-<li>A declaration must always have a type specifier; it doesn't
-default to an <tt>int</tt> type.</li>
-
-<li>Old-style empty function declarations (K&R) are not allowed.
-All C functions must have a proper prototype declaration. A
-function declared without parameters (<tt>int foo();</tt>) is
-treated as a function taking zero arguments, like in C++.</li>
-
-<li>The <tt>long double</tt> C type is parsed correctly, but
-there's no support for the related conversions, accesses or arithmetic
-operations.</li>
-
-<li>Wide character strings and character literals are not
-supported.</li>
-
-<li><a href="#status">See below</a> for features that are currently
-not implemented.</li>
-
-</ul>
-
-<h2 id="convert">C Type Conversion Rules</h2>
-
-<h3 id="convert_tolua">Conversions from C types to Lua objects</h3>
-<p>
-These conversion rules apply for <em>read accesses</em> to
-C types: indexing pointers, arrays or
-<tt>struct</tt>/<tt>union</tt> types; reading external variables or
-constant values; retrieving return values from C calls:
-</p>
-<table class="convtable">
-<tr class="convhead">
-<td class="convin">Input</td>
-<td class="convop">Conversion</td>
-<td class="convout">Output</td>
-</tr>
-<tr class="odd separate">
-<td class="convin"><tt>int8_t</tt>, <tt>int16_t</tt></td><td class="convop">→<sup>sign-ext</sup> <tt>int32_t</tt> → <tt>double</tt></td><td class="convout">number</td></tr>
-<tr class="even">
-<td class="convin"><tt>uint8_t</tt>, <tt>uint16_t</tt></td><td class="convop">→<sup>zero-ext</sup> <tt>int32_t</tt> → <tt>double</tt></td><td class="convout">number</td></tr>
-<tr class="odd">
-<td class="convin"><tt>int32_t</tt>, <tt>uint32_t</tt></td><td class="convop">→ <tt>double</tt></td><td class="convout">number</td></tr>
-<tr class="even">
-<td class="convin"><tt>int64_t</tt>, <tt>uint64_t</tt></td><td class="convop">boxed value</td><td class="convout">64 bit int cdata</td></tr>
-<tr class="odd separate">
-<td class="convin"><tt>double</tt>, <tt>float</tt></td><td class="convop">→ <tt>double</tt></td><td class="convout">number</td></tr>
-<tr class="even separate">
-<td class="convin"><tt>bool</tt></td><td class="convop">0 → <tt>false</tt>, otherwise <tt>true</tt></td><td class="convout">boolean</td></tr>
-<tr class="odd separate">
-<td class="convin"><tt>enum</tt></td><td class="convop">boxed value</td><td class="convout">enum cdata</td></tr>
-<tr class="even">
-<td class="convin">Complex number</td><td class="convop">boxed value</td><td class="convout">complex cdata</td></tr>
-<tr class="odd">
-<td class="convin">Vector</td><td class="convop">boxed value</td><td class="convout">vector cdata</td></tr>
-<tr class="even">
-<td class="convin">Pointer</td><td class="convop">boxed value</td><td class="convout">pointer cdata</td></tr>
-<tr class="odd separate">
-<td class="convin">Array</td><td class="convop">boxed reference</td><td class="convout">reference cdata</td></tr>
-<tr class="even">
-<td class="convin"><tt>struct</tt>/<tt>union</tt></td><td class="convop">boxed reference</td><td class="convout">reference cdata</td></tr>
-</table>
-<p>
-Bitfields are treated like their underlying type.
-</p>
-<p>
-Reference types are dereferenced <em>before</em> a conversion can take
-place — the conversion is applied to the C type pointed to
-by the reference.
-</p>
-
-<h3 id="convert_fromlua">Conversions from Lua objects to C types</h3>
-<p>
-These conversion rules apply for <em>write accesses</em> to
-C types: indexing pointers, arrays or
-<tt>struct</tt>/<tt>union</tt> types; initializing cdata objects;
-casts to C types; writing to external variables; passing
-arguments to C calls:
-</p>
-<table class="convtable">
-<tr class="convhead">
-<td class="convin">Input</td>
-<td class="convop">Conversion</td>
-<td class="convout">Output</td>
-</tr>
-<tr class="odd separate">
-<td class="convin">number</td><td class="convop">→</td><td class="convout"><tt>double</tt></td></tr>
-<tr class="even">
-<td class="convin">boolean</td><td class="convop"><tt>false</tt> → 0, <tt>true</tt> → 1</td><td class="convout"><tt>bool</tt></td></tr>
-<tr class="odd separate">
-<td class="convin">nil</td><td class="convop"><tt>NULL</tt> →</td><td class="convout"><tt>(void *)</tt></td></tr>
-<tr class="even">
-<td class="convin">lightuserdata</td><td class="convop">lightuserdata address →</td><td class="convout"><tt>(void *)</tt></td></tr>
-<tr class="odd">
-<td class="convin">userdata</td><td class="convop">userdata payload →</td><td class="convout"><tt>(void *)</tt></td></tr>
-<tr class="even">
-<td class="convin">io.* file</td><td class="convop">get FILE * handle →</td><td class="convout"><tt>(void *)</tt></td></tr>
-<tr class="odd separate">
-<td class="convin">string</td><td class="convop">match against <tt>enum</tt> constant</td><td class="convout"><tt>enum</tt></td></tr>
-<tr class="even">
-<td class="convin">string</td><td class="convop">copy string data + zero-byte</td><td class="convout"><tt>int8_t[]</tt>, <tt>uint8_t[]</tt></td></tr>
-<tr class="odd">
-<td class="convin">string</td><td class="convop">string data →</td><td class="convout"><tt>const char[]</tt></td></tr>
-<tr class="even separate">
-<td class="convin">function</td><td class="convop"><a href="#callback">create callback</a> →</td><td class="convout">C function type</td></tr>
-<tr class="odd separate">
-<td class="convin">table</td><td class="convop"><a href="#init_table">table initializer</a></td><td class="convout">Array</td></tr>
-<tr class="even">
-<td class="convin">table</td><td class="convop"><a href="#init_table">table initializer</a></td><td class="convout"><tt>struct</tt>/<tt>union</tt></td></tr>
-<tr class="odd separate">
-<td class="convin">cdata</td><td class="convop">cdata payload →</td><td class="convout">C type</td></tr>
-</table>
-<p>
-If the result type of this conversion doesn't match the
-C type of the destination, the
-<a href="#convert_between">conversion rules between C types</a>
-are applied.
-</p>
-<p>
-Reference types are immutable after initialization ("no re-seating of
-references"). For initialization purposes or when passing values to
-reference parameters, they are treated like pointers. Note that unlike
-in C++, there's no way to implement automatic reference generation of
-variables under the Lua language semantics. If you want to call a
-function with a reference parameter, you need to explicitly pass a
-one-element array.
-</p>
-
-<h3 id="convert_between">Conversions between C types</h3>
-<p>
-These conversion rules are more or less the same as the standard
-C conversion rules. Some rules only apply to casts, or require
-pointer or type compatibility:
-</p>
-<table class="convtable">
-<tr class="convhead">
-<td class="convin">Input</td>
-<td class="convop">Conversion</td>
-<td class="convout">Output</td>
-</tr>
-<tr class="odd separate">
-<td class="convin">Signed integer</td><td class="convop">→<sup>narrow or sign-extend</sup></td><td class="convout">Integer</td></tr>
-<tr class="even">
-<td class="convin">Unsigned integer</td><td class="convop">→<sup>narrow or zero-extend</sup></td><td class="convout">Integer</td></tr>
-<tr class="odd">
-<td class="convin">Integer</td><td class="convop">→<sup>round</sup></td><td class="convout"><tt>double</tt>, <tt>float</tt></td></tr>
-<tr class="even">
-<td class="convin"><tt>double</tt>, <tt>float</tt></td><td class="convop">→<sup>trunc</sup> <tt>int32_t</tt> →<sup>narrow</sup></td><td class="convout"><tt>(u)int8_t</tt>, <tt>(u)int16_t</tt></td></tr>
-<tr class="odd">
-<td class="convin"><tt>double</tt>, <tt>float</tt></td><td class="convop">→<sup>trunc</sup></td><td class="convout"><tt>(u)int32_t</tt>, <tt>(u)int64_t</tt></td></tr>
-<tr class="even">
-<td class="convin"><tt>double</tt>, <tt>float</tt></td><td class="convop">→<sup>round</sup></td><td class="convout"><tt>float</tt>, <tt>double</tt></td></tr>
-<tr class="odd separate">
-<td class="convin">Number</td><td class="convop">n == 0 → 0, otherwise 1</td><td class="convout"><tt>bool</tt></td></tr>
-<tr class="even">
-<td class="convin"><tt>bool</tt></td><td class="convop"><tt>false</tt> → 0, <tt>true</tt> → 1</td><td class="convout">Number</td></tr>
-<tr class="odd separate">
-<td class="convin">Complex number</td><td class="convop">convert real part</td><td class="convout">Number</td></tr>
-<tr class="even">
-<td class="convin">Number</td><td class="convop">convert real part, imag = 0</td><td class="convout">Complex number</td></tr>
-<tr class="odd">
-<td class="convin">Complex number</td><td class="convop">convert real and imag part</td><td class="convout">Complex number</td></tr>
-<tr class="even separate">
-<td class="convin">Number</td><td class="convop">convert scalar and replicate</td><td class="convout">Vector</td></tr>
-<tr class="odd">
-<td class="convin">Vector</td><td class="convop">copy (same size)</td><td class="convout">Vector</td></tr>
-<tr class="even separate">
-<td class="convin"><tt>struct</tt>/<tt>union</tt></td><td class="convop">take base address (compat)</td><td class="convout">Pointer</td></tr>
-<tr class="odd">
-<td class="convin">Array</td><td class="convop">take base address (compat)</td><td class="convout">Pointer</td></tr>
-<tr class="even">
-<td class="convin">Function</td><td class="convop">take function address</td><td class="convout">Function pointer</td></tr>
-<tr class="odd separate">
-<td class="convin">Number</td><td class="convop">convert via <tt>uintptr_t</tt> (cast)</td><td class="convout">Pointer</td></tr>
-<tr class="even">
-<td class="convin">Pointer</td><td class="convop">convert address (compat/cast)</td><td class="convout">Pointer</td></tr>
-<tr class="odd">
-<td class="convin">Pointer</td><td class="convop">convert address (cast)</td><td class="convout">Integer</td></tr>
-<tr class="even">
-<td class="convin">Array</td><td class="convop">convert base address (cast)</td><td class="convout">Integer</td></tr>
-<tr class="odd separate">
-<td class="convin">Array</td><td class="convop">copy (compat)</td><td class="convout">Array</td></tr>
-<tr class="even">
-<td class="convin"><tt>struct</tt>/<tt>union</tt></td><td class="convop">copy (identical type)</td><td class="convout"><tt>struct</tt>/<tt>union</tt></td></tr>
-</table>
-<p>
-Bitfields or <tt>enum</tt> types are treated like their underlying
-type.
-</p>
-<p>
-Conversions not listed above will raise an error. E.g. it's not
-possible to convert a pointer to a complex number or vice versa.
-</p>
-
-<h3 id="convert_vararg">Conversions for vararg C function arguments</h3>
-<p>
-The following default conversion rules apply when passing Lua objects
-to the variable argument part of vararg C functions:
-</p>
-<table class="convtable">
-<tr class="convhead">
-<td class="convin">Input</td>
-<td class="convop">Conversion</td>
-<td class="convout">Output</td>
-</tr>
-<tr class="odd separate">
-<td class="convin">number</td><td class="convop">→</td><td class="convout"><tt>double</tt></td></tr>
-<tr class="even">
-<td class="convin">boolean</td><td class="convop"><tt>false</tt> → 0, <tt>true</tt> → 1</td><td class="convout"><tt>bool</tt></td></tr>
-<tr class="odd separate">
-<td class="convin">nil</td><td class="convop"><tt>NULL</tt> →</td><td class="convout"><tt>(void *)</tt></td></tr>
-<tr class="even">
-<td class="convin">userdata</td><td class="convop">userdata payload →</td><td class="convout"><tt>(void *)</tt></td></tr>
-<tr class="odd">
-<td class="convin">lightuserdata</td><td class="convop">lightuserdata address →</td><td class="convout"><tt>(void *)</tt></td></tr>
-<tr class="even separate">
-<td class="convin">string</td><td class="convop">string data →</td><td class="convout"><tt>const char *</tt></td></tr>
-<tr class="odd separate">
-<td class="convin"><tt>float</tt> cdata</td><td class="convop">→</td><td class="convout"><tt>double</tt></td></tr>
-<tr class="even">
-<td class="convin">Array cdata</td><td class="convop">take base address</td><td class="convout">Element pointer</td></tr>
-<tr class="odd">
-<td class="convin"><tt>struct</tt>/<tt>union</tt> cdata</td><td class="convop">take base address</td><td class="convout"><tt>struct</tt>/<tt>union</tt> pointer</td></tr>
-<tr class="even">
-<td class="convin">Function cdata</td><td class="convop">take function address</td><td class="convout">Function pointer</td></tr>
-<tr class="odd">
-<td class="convin">Any other cdata</td><td class="convop">no conversion</td><td class="convout">C type</td></tr>
-</table>
-<p>
-To pass a Lua object, other than a cdata object, as a specific type,
-you need to override the conversion rules: create a temporary cdata
-object with a constructor or a cast and initialize it with the value
-to pass:
-</p>
-<p>
-Assuming <tt>x</tt> is a Lua number, here's how to pass it as an
-integer to a vararg function:
-</p>
-<pre class="code">
-ffi.cdef[[
-int printf(const char *fmt, ...);
-]]
-ffi.C.printf("integer value: %d\n", ffi.new("int", x))
-</pre>
-<p>
-If you don't do this, the default Lua number → <tt>double</tt>
-conversion rule applies. A vararg C function expecting an integer
-will see a garbled or uninitialized value.
-</p>
-
-<h2 id="init">Initializers</h2>
-<p>
-Creating a cdata object with
-<a href="ext_ffi_api.html#ffi_new"><tt>ffi.new()</tt></a> or the
-equivalent constructor syntax always initializes its contents, too.
-Different rules apply, depending on the number of optional
-initializers and the C types involved:
-</p>
-<ul>
-<li>If no initializers are given, the object is filled with zero bytes.</li>
-
-<li>Scalar types (numbers and pointers) accept a single initializer.
-The Lua object is <a href="#convert_fromlua">converted to the scalar
-C type</a>.</li>
-
-<li>Valarrays (complex numbers and vectors) are treated like scalars
-when a single initializer is given. Otherwise they are treated like
-regular arrays.</li>
-
-<li>Aggregate types (arrays and structs) accept either a single cdata
-initializer of the same type (copy constructor), a single
-<a href="#init_table">table initializer</a>, or a flat list of
-initializers.</li>
-
-<li>The elements of an array are initialized, starting at index zero.
-If a single initializer is given for an array, it's repeated for all
-remaining elements. This doesn't happen if two or more initializers
-are given: all remaining uninitialized elements are filled with zero
-bytes.</li>
-
-<li>Byte arrays may also be initialized with a Lua string. This copies
-the whole string plus a terminating zero-byte. The copy stops early only
-if the array has a known, fixed size.</li>
-
-<li>The fields of a <tt>struct</tt> are initialized in the order of
-their declaration. Uninitialized fields are filled with zero
-bytes.</li>
-
-<li>Only the first field of a <tt>union</tt> can be initialized with a
-flat initializer.</li>
-
-<li>Elements or fields which are aggregates themselves are initialized
-with a <em>single</em> initializer, but this may be a table
-initializer or a compatible aggregate.</li>
-
-<li>Excess initializers cause an error.</li>
-
-</ul>
-
-<h2 id="init_table">Table Initializers</h2>
-<p>
-The following rules apply if a Lua table is used to initialize an
-Array or a <tt>struct</tt>/<tt>union</tt>:
-</p>
-<ul>
-
-<li>If the table index <tt>[0]</tt> is non-<tt>nil</tt>, then the
-table is assumed to be zero-based. Otherwise it's assumed to be
-one-based.</li>
-
-<li>Array elements, starting at index zero, are initialized one-by-one
-with the consecutive table elements, starting at either index
-<tt>[0]</tt> or <tt>[1]</tt>. This process stops at the first
-<tt>nil</tt> table element.</li>
-
-<li>If exactly one array element was initialized, it's repeated for
-all the remaining elements. Otherwise all remaining uninitialized
-elements are filled with zero bytes.</li>
-
-<li>The above logic only applies to arrays with a known fixed size.
-A VLA is only initialized with the element(s) given in the table.
-Depending on the use case, you may need to explicitly add a
-<tt>NULL</tt> or <tt>0</tt> terminator to a VLA.</li>
-
-<li>A <tt>struct</tt>/<tt>union</tt> can be initialized in the
-order of the declaration of its fields. Each field is initialized with
-consecutive table elements, starting at either index <tt>[0]</tt>
-or <tt>[1]</tt>. This process stops at the first <tt>nil</tt> table
-element.</li>
-
-<li>Otherwise, if neither index <tt>[0]</tt> nor <tt>[1]</tt> is present,
-a <tt>struct</tt>/<tt>union</tt> is initialized by looking up each field
-name (as a string key) in the table. Each non-<tt>nil</tt> value is
-used to initialize the corresponding field.</li>
-
-<li>Uninitialized fields of a <tt>struct</tt> are filled with zero
-bytes, except for the trailing VLA of a VLS.</li>
-
-<li>Initialization of a <tt>union</tt> stops after one field has been
-initialized. If no field has been initialized, the <tt>union</tt> is
-filled with zero bytes.</li>
-
-<li>Elements or fields which are aggregates themselves are initialized
-with a <em>single</em> initializer, but this may be a nested table
-initializer (or a compatible aggregate).</li>
-
-<li>Excess initializers for an array cause an error. Excess
-initializers for a <tt>struct</tt>/<tt>union</tt> are ignored.
-Unrelated table entries are ignored, too.</li>
-
-</ul>
-<p>
-Example:
-</p>
-<pre class="code">
-local ffi = require("ffi")
-
-ffi.cdef[[
-struct foo { int a, b; };
-union bar { int i; double d; };
-struct nested { int x; struct foo y; };
-]]
-
-ffi.new("int[3]", {}) --> 0, 0, 0
-ffi.new("int[3]", {1}) --> 1, 1, 1
-ffi.new("int[3]", {1,2}) --> 1, 2, 0
-ffi.new("int[3]", {1,2,3}) --> 1, 2, 3
-ffi.new("int[3]", {[0]=1}) --> 1, 1, 1
-ffi.new("int[3]", {[0]=1,2}) --> 1, 2, 0
-ffi.new("int[3]", {[0]=1,2,3}) --> 1, 2, 3
-ffi.new("int[3]", {[0]=1,2,3,4}) --> error: too many initializers
-
-ffi.new("struct foo", {}) --> a = 0, b = 0
-ffi.new("struct foo", {1}) --> a = 1, b = 0
-ffi.new("struct foo", {1,2}) --> a = 1, b = 2
-ffi.new("struct foo", {[0]=1,2}) --> a = 1, b = 2
-ffi.new("struct foo", {b=2}) --> a = 0, b = 2
-ffi.new("struct foo", {a=1,b=2,c=3}) --> a = 1, b = 2 'c' is ignored
-
-ffi.new("union bar", {}) --> i = 0, d = 0.0
-ffi.new("union bar", {1}) --> i = 1, d = ?
-ffi.new("union bar", {[0]=1,2}) --> i = 1, d = ? '2' is ignored
-ffi.new("union bar", {d=2}) --> i = ?, d = 2.0
-
-ffi.new("struct nested", {1,{2,3}}) --> x = 1, y.a = 2, y.b = 3
-ffi.new("struct nested", {x=1,y={2,3}}) --> x = 1, y.a = 2, y.b = 3
-</pre>
-
-<h2 id="cdata_ops">Operations on cdata Objects</h2>
-<p>
-All of the standard Lua operators can be applied to cdata objects or a
-mix of a cdata object and another Lua object. The following list shows
-the pre-defined operations.
-</p>
-<p>
-Reference types are dereferenced <em>before</em> performing each of
-the operations below — the operation is applied to the
-C type pointed to by the reference.
-</p>
-<p>
-The pre-defined operations are always tried first before deferring to a
-metamethod or index table (if any) for the corresponding ctype (except
-for <tt>__new</tt>). An error is raised if the metamethod lookup or
-index table lookup fails.
-</p>
-
-<h3 id="cdata_array">Indexing a cdata object</h3>
-<ul>
-
-<li><b>Indexing a pointer/array</b>: a cdata pointer/array can be
-indexed by a cdata number or a Lua number. The element address is
-computed as the base address plus the number value multiplied by the
-element size in bytes. A read access loads the element value and
-<a href="#convert_tolua">converts it to a Lua object</a>. A write
-access <a href="#convert_fromlua">converts a Lua object to the element
-type</a> and stores the converted value to the element. An error is
-raised if the element size is undefined or a write access to a
-constant element is attempted.</li>
-
-<li><b>Dereferencing a <tt>struct</tt>/<tt>union</tt> field</b>: a
-cdata <tt>struct</tt>/<tt>union</tt> or a pointer to a
-<tt>struct</tt>/<tt>union</tt> can be dereferenced by a string key,
-giving the field name. The field address is computed as the base
-address plus the relative offset of the field. A read access loads the
-field value and <a href="#convert_tolua">converts it to a Lua
-object</a>. A write access <a href="#convert_fromlua">converts a Lua
-object to the field type</a> and stores the converted value to the
-field. An error is raised if a write access to a constant
-<tt>struct</tt>/<tt>union</tt> or a constant field is attempted.
-Scoped enum constants or static constants are treated like a constant
-field.</li>
-
-<li><b>Indexing a complex number</b>: a complex number can be indexed
-either by a cdata number or a Lua number with the values 0 or 1, or by
-the strings <tt>"re"</tt> or <tt>"im"</tt>. A read access loads the
-real part (<tt>[0]</tt>, <tt>.re</tt>) or the imaginary part
-(<tt>[1]</tt>, <tt>.im</tt>) part of a complex number and
-<a href="#convert_tolua">converts it to a Lua number</a>. The
-sub-parts of a complex number are immutable — assigning to an
-index of a complex number raises an error. Accessing out-of-bound
-indexes returns unspecified results, but is guaranteed not to trigger
-memory access violations.</li>
-
-<li><b>Indexing a vector</b>: a vector is treated like an array for
-indexing purposes, except the vector elements are immutable —
-assigning to an index of a vector raises an error.</li>
-
-</ul>
-<p>
-A ctype object can be indexed with a string key, too. The only
-pre-defined operation is reading scoped constants of
-<tt>struct</tt>/<tt>union</tt> types. All other accesses defer
-to the corresponding metamethods or index tables (if any).
-</p>
-<p>
-Note: since there's (deliberately) no address-of operator, a cdata
-object holding a value type is effectively immutable after
-initialization. The JIT compiler benefits from this fact when applying
-certain optimizations.
-</p>
-<p>
-As a consequence, the <em>elements</em> of complex numbers and
-vectors are immutable. But the elements of an aggregate holding these
-types <em>may</em> be modified of course. I.e. you cannot assign to
-<tt>foo.c.im</tt>, but you can assign a (newly created) complex number
-to <tt>foo.c</tt>.
-</p>
-<p>
-The JIT compiler implements strict aliasing rules: accesses to different
-types do <b>not</b> alias, except for differences in signedness (this
-applies even to <tt>char</tt> pointers, unlike C99). Type punning
-through unions is explicitly detected and allowed.
-</p>
-
-<h3 id="cdata_call">Calling a cdata object</h3>
-<ul>
-
-<li><b>Constructor</b>: a ctype object can be called and used as a
-<a href="ext_ffi_api.html#ffi_new">constructor</a>. This is equivalent
-to <tt>ffi.new(ct, ...)</tt>, unless a <tt>__new</tt> metamethod is
-defined. The <tt>__new</tt> metamethod is called with the ctype object
-plus any other arguments passed to the contructor. Note that you have to
-use <tt>ffi.new</tt> inside of it, since calling <tt>ct(...)</tt> would
-cause infinite recursion.</li>
-
-<li><b>C function call</b>: a cdata function or cdata function
-pointer can be called. The passed arguments are
-<a href="#convert_fromlua">converted to the C types</a> of the
-parameters given by the function declaration. Arguments passed to the
-variable argument part of vararg C function use
-<a href="#convert_vararg">special conversion rules</a>. This
-C function is called and the return value (if any) is
-<a href="#convert_tolua">converted to a Lua object</a>.<br>
-On Windows/x86 systems, <tt>__stdcall</tt> functions are automatically
-detected and a function declared as <tt>__cdecl</tt> (the default) is
-silently fixed up after the first call.</li>
-
-</ul>
-
-<h3 id="cdata_arith">Arithmetic on cdata objects</h3>
-<ul>
-
-<li><b>Pointer arithmetic</b>: a cdata pointer/array and a cdata
-number or a Lua number can be added or subtracted. The number must be
-on the right hand side for a subtraction. The result is a pointer of
-the same type with an address plus or minus the number value
-multiplied by the element size in bytes. An error is raised if the
-element size is undefined.</li>
-
-<li><b>Pointer difference</b>: two compatible cdata pointers/arrays
-can be subtracted. The result is the difference between their
-addresses, divided by the element size in bytes. An error is raised if
-the element size is undefined or zero.</li>
-
-<li><b>64 bit integer arithmetic</b>: the standard arithmetic
-operators (<tt>+ - * / % ^</tt> and unary
-minus) can be applied to two cdata numbers, or a cdata number and a
-Lua number. If one of them is an <tt>uint64_t</tt>, the other side is
-converted to an <tt>uint64_t</tt> and an unsigned arithmetic operation
-is performed. Otherwise both sides are converted to an
-<tt>int64_t</tt> and a signed arithmetic operation is performed. The
-result is a boxed 64 bit cdata object.<br>
-
-If one of the operands is an <tt>enum</tt> and the other operand is a
-string, the string is converted to the value of a matching <tt>enum</tt>
-constant before the above conversion.<br>
-
-These rules ensure that 64 bit integers are "sticky". Any
-expression involving at least one 64 bit integer operand results
-in another one. The undefined cases for the division, modulo and power
-operators return <tt>2LL ^ 63</tt> or
-<tt>2ULL ^ 63</tt>.<br>
-
-You'll have to explicitly convert a 64 bit integer to a Lua
-number (e.g. for regular floating-point calculations) with
-<tt>tonumber()</tt>. But note this may incur a precision loss.</li>
-
-<li><b>64 bit bitwise operations</b>: the rules for 64 bit
-arithmetic operators apply analogously.<br>
-
-Unlike the other <tt>bit.*</tt> operations, <tt>bit.tobit()</tt>
-converts a cdata number via <tt>int64_t</tt> to <tt>int32_t</tt> and
-returns a Lua number.<br>
-
-For <tt>bit.band()</tt>, <tt>bit.bor()</tt> and <tt>bit.bxor()</tt>, the
-conversion to <tt>int64_t</tt> or <tt>uint64_t</tt> applies to
-<em>all</em> arguments, if <em>any</em> argument is a cdata number.<br>
-
-For all other operations, only the first argument is used to determine
-the output type. This implies that a cdata number as a shift count for
-shifts and rotates is accepted, but that alone does <em>not</em> cause
-a cdata number output.
-
-</ul>
-
-<h3 id="cdata_comp">Comparisons of cdata objects</h3>
-<ul>
-
-<li><b>Pointer comparison</b>: two compatible cdata pointers/arrays
-can be compared. The result is the same as an unsigned comparison of
-their addresses. <tt>nil</tt> is treated like a <tt>NULL</tt> pointer,
-which is compatible with any other pointer type.</li>
-
-<li><b>64 bit integer comparison</b>: two cdata numbers, or a
-cdata number and a Lua number can be compared with each other. If one
-of them is an <tt>uint64_t</tt>, the other side is converted to an
-<tt>uint64_t</tt> and an unsigned comparison is performed. Otherwise
-both sides are converted to an <tt>int64_t</tt> and a signed
-comparison is performed.<br>
-
-If one of the operands is an <tt>enum</tt> and the other operand is a
-string, the string is converted to the value of a matching <tt>enum</tt>
-constant before the above conversion.<br>
-
-<li><b>Comparisons for equality/inequality</b> never raise an error.
-Even incompatible pointers can be compared for equality by address. Any
-other incompatible comparison (also with non-cdata objects) treats the
-two sides as unequal.</li>
-
-</ul>
-
-<h3 id="cdata_key">cdata objects as table keys</h3>
-<p>
-Lua tables may be indexed by cdata objects, but this doesn't provide
-any useful semantics — <b>cdata objects are unsuitable as table
-keys!</b>
-</p>
-<p>
-A cdata object is treated like any other garbage-collected object and
-is hashed and compared by its address for table indexing. Since
-there's no interning for cdata value types, the same value may be
-boxed in different cdata objects with different addresses. Thus
-<tt>t[1LL+1LL]</tt> and <tt>t[2LL]</tt> usually <b>do not</b> point to
-the same hash slot and they certainly <b>do not</b> point to the same
-hash slot as <tt>t[2]</tt>.
-</p>
-<p>
-It would seriously drive up implementation complexity and slow down
-the common case, if one were to add extra handling for by-value
-hashing and comparisons to Lua tables. Given the ubiquity of their use
-inside the VM, this is not acceptable.
-</p>
-<p>
-There are three viable alternatives, if you really need to use cdata
-objects as keys:
-</p>
-<ul>
-
-<li>If you can get by with the precision of Lua numbers
-(52 bits), then use <tt>tonumber()</tt> on a cdata number or
-combine multiple fields of a cdata aggregate to a Lua number. Then use
-the resulting Lua number as a key when indexing tables.<br>
-One obvious benefit: <tt>t[tonumber(2LL)]</tt> <b>does</b> point to
-the same slot as <tt>t[2]</tt>.</li>
-
-<li>Otherwise use either <tt>tostring()</tt> on 64 bit integers
-or complex numbers or combine multiple fields of a cdata aggregate to
-a Lua string (e.g. with
-<a href="ext_ffi_api.html#ffi_string"><tt>ffi.string()</tt></a>). Then
-use the resulting Lua string as a key when indexing tables.</li>
-
-<li>Create your own specialized hash table implementation using the
-C types provided by the FFI library, just like you would in
-C code. Ultimately this may give much better performance than the
-other alternatives or what a generic by-value hash table could
-possibly provide.</li>
-
-</ul>
-
-<h2 id="param">Parameterized Types</h2>
-<p>
-To facilitate some abstractions, the two functions
-<a href="ext_ffi_api.html#ffi_typeof"><tt>ffi.typeof</tt></a> and
-<a href="ext_ffi_api.html#ffi_cdef"><tt>ffi.cdef</tt></a> support
-parameterized types in C declarations. Note: none of the other API
-functions taking a cdecl allow this.
-</p>
-<p>
-Any place you can write a <b><tt>typedef</tt> name</b>, an
-<b>identifier</b> or a <b>number</b> in a declaration, you can write
-<tt>$</tt> (the dollar sign) instead. These placeholders are replaced in
-order of appearance with the arguments following the cdecl string:
-</p>
-<pre class="code">
--- Declare a struct with a parameterized field type and name:
-ffi.cdef([[
-typedef struct { $ $; } foo_t;
-]], type1, name1)
-
--- Anonymous struct with dynamic names:
-local bar_t = ffi.typeof("struct { int $, $; }", name1, name2)
--- Derived pointer type:
-local bar_ptr_t = ffi.typeof("$ *", bar_t)
-
--- Parameterized dimensions work even where a VLA won't work:
-local matrix_t = ffi.typeof("uint8_t[$][$]", width, height)
-</pre>
-<p>
-Caveat: this is <em>not</em> simple text substitution! A passed ctype or
-cdata object is treated like the underlying type, a passed string is
-considered an identifier and a number is considered a number. You must
-not mix this up: e.g. passing <tt>"int"</tt> as a string doesn't work in
-place of a type, you'd need to use <tt>ffi.typeof("int")</tt> instead.
-</p>
-<p>
-The main use for parameterized types are libraries implementing abstract
-data types
-(<a href="http://www.freelists.org/post/luajit/ffi-type-of-pointer-to,8"><span class="ext">»</span> example</a>),
-similar to what can be achieved with C++ template metaprogramming.
-Another use case are derived types of anonymous structs, which avoids
-pollution of the global struct namespace.
-</p>
-<p>
-Please note that parameterized types are a nice tool and indispensable
-for certain use cases. But you'll want to use them sparingly in regular
-code, e.g. when all types are actually fixed.
-</p>
-
-<h2 id="gc">Garbage Collection of cdata Objects</h2>
-<p>
-All explicitly (<tt>ffi.new()</tt>, <tt>ffi.cast()</tt> etc.) or
-implicitly (accessors) created cdata objects are garbage collected.
-You need to ensure to retain valid references to cdata objects
-somewhere on a Lua stack, an upvalue or in a Lua table while they are
-still in use. Once the last reference to a cdata object is gone, the
-garbage collector will automatically free the memory used by it (at
-the end of the next GC cycle).
-</p>
-<p>
-Please note that pointers themselves are cdata objects, however they
-are <b>not</b> followed by the garbage collector. So e.g. if you
-assign a cdata array to a pointer, you must keep the cdata object
-holding the array alive as long as the pointer is still in use:
-</p>
-<pre class="code">
-ffi.cdef[[
-typedef struct { int *a; } foo_t;
-]]
-
-local s = ffi.new("foo_t", ffi.new("int[10]")) -- <span style="color:#c00000;">WRONG!</span>
-
-local a = ffi.new("int[10]") -- <span style="color:#00a000;">OK</span>
-local s = ffi.new("foo_t", a)
--- Now do something with 's', but keep 'a' alive until you're done.
-</pre>
-<p>
-Similar rules apply for Lua strings which are implicitly converted to
-<tt>"const char *"</tt>: the string object itself must be
-referenced somewhere or it'll be garbage collected eventually. The
-pointer will then point to stale data, which may have already been
-overwritten. Note that <em>string literals</em> are automatically kept
-alive as long as the function containing it (actually its prototype)
-is not garbage collected.
-</p>
-<p>
-Objects which are passed as an argument to an external C function
-are kept alive until the call returns. So it's generally safe to
-create temporary cdata objects in argument lists. This is a common
-idiom for <a href="#convert_vararg">passing specific C types to
-vararg functions</a>.
-</p>
-<p>
-Memory areas returned by C functions (e.g. from <tt>malloc()</tt>)
-must be manually managed, of course (or use
-<a href="ext_ffi_api.html#ffi_gc"><tt>ffi.gc()</tt></a>). Pointers to
-cdata objects are indistinguishable from pointers returned by C
-functions (which is one of the reasons why the GC cannot follow them).
-</p>
-
-<h2 id="callback">Callbacks</h2>
-<p>
-The LuaJIT FFI automatically generates special callback functions
-whenever a Lua function is converted to a C function pointer. This
-associates the generated callback function pointer with the C type
-of the function pointer and the Lua function object (closure).
-</p>
-<p>
-This can happen implicitly due to the usual conversions, e.g. when
-passing a Lua function to a function pointer argument. Or you can use
-<tt>ffi.cast()</tt> to explicitly cast a Lua function to a
-C function pointer.
-</p>
-<p>
-Currently only certain C function types can be used as callback
-functions. Neither C vararg functions nor functions with
-pass-by-value aggregate argument or result types are supported. There
-are no restrictions for the kind of Lua functions that can be called
-from the callback — no checks for the proper number of arguments
-are made. The return value of the Lua function will be converted to the
-result type and an error will be thrown for invalid conversions.
-</p>
-<p>
-It's allowed to throw errors across a callback invocation, but it's not
-advisable in general. Do this only if you know the C function, that
-called the callback, copes with the forced stack unwinding and doesn't
-leak resources.
-</p>
-<p>
-One thing that's not allowed, is to let an FFI call into a C function
-get JIT-compiled, which in turn calls a callback, calling into Lua again.
-Usually this attempt is caught by the interpreter first and the
-C function is blacklisted for compilation.
-</p>
-<p>
-However, this heuristic may fail under specific circumstances: e.g. a
-message polling function might not run Lua callbacks right away and the call
-gets JIT-compiled. If it later happens to call back into Lua (e.g. a rarely
-invoked error callback), you'll get a VM PANIC with the message
-<tt>"bad callback"</tt>. Then you'll need to manually turn off
-JIT-compilation with
-<a href="ext_jit.html#jit_onoff_func"><tt>jit.off()</tt></a> for the
-surrounding Lua function that invokes such a message polling function (or
-similar).
-</p>
-
-<h3 id="callback_resources">Callback resource handling</h3>
-<p>
-Callbacks take up resources — you can only have a limited number
-of them at the same time (500 - 1000, depending on the
-architecture). The associated Lua functions are anchored to prevent
-garbage collection, too.
-</p>
-<p>
-<b>Callbacks due to implicit conversions are permanent!</b> There is no
-way to guess their lifetime, since the C side might store the
-function pointer for later use (typical for GUI toolkits). The associated
-resources cannot be reclaimed until termination:
-</p>
-<pre class="code">
-ffi.cdef[[
-typedef int (__stdcall *WNDENUMPROC)(void *hwnd, intptr_t l);
-int EnumWindows(WNDENUMPROC func, intptr_t l);
-]]
-
--- Implicit conversion to a callback via function pointer argument.
-local count = 0
-ffi.C.EnumWindows(function(hwnd, l)
- count = count + 1
- return true
-end, 0)
--- The callback is permanent and its resources cannot be reclaimed!
--- Ok, so this may not be a problem, if you do this only once.
-</pre>
-<p>
-Note: this example shows that you <em>must</em> properly declare
-<tt>__stdcall</tt> callbacks on Windows/x86 systems. The calling
-convention cannot be automatically detected, unlike for
-<tt>__stdcall</tt> calls <em>to</em> Windows functions.
-</p>
-<p>
-For some use cases it's necessary to free up the resources or to
-dynamically redirect callbacks. Use an explicit cast to a
-C function pointer and keep the resulting cdata object. Then use
-the <a href="ext_ffi_api.html#callback_free"><tt>cb:free()</tt></a>
-or <a href="ext_ffi_api.html#callback_set"><tt>cb:set()</tt></a> methods
-on the cdata object:
-</p>
-<pre class="code">
--- Explicitly convert to a callback via cast.
-local count = 0
-local cb = ffi.cast("WNDENUMPROC", function(hwnd, l)
- count = count + 1
- return true
-end)
-
--- Pass it to a C function.
-ffi.C.EnumWindows(cb, 0)
--- EnumWindows doesn't need the callback after it returns, so free it.
-
-cb:free()
--- The callback function pointer is no longer valid and its resources
--- will be reclaimed. The created Lua closure will be garbage collected.
-</pre>
-
-<h3 id="callback_performance">Callback performance</h3>
-<p>
-<b>Callbacks are slow!</b> First, the C to Lua transition itself
-has an unavoidable cost, similar to a <tt>lua_call()</tt> or
-<tt>lua_pcall()</tt>. Argument and result marshalling add to that cost.
-And finally, neither the C compiler nor LuaJIT can inline or
-optimize across the language barrier and hoist repeated computations out
-of a callback function.
-</p>
-<p>
-Do not use callbacks for performance-sensitive work: e.g. consider a
-numerical integration routine which takes a user-defined function to
-integrate over. It's a bad idea to call a user-defined Lua function from
-C code millions of times. The callback overhead will be absolutely
-detrimental for performance.
-</p>
-<p>
-It's considerably faster to write the numerical integration routine
-itself in Lua — the JIT compiler will be able to inline the
-user-defined function and optimize it together with its calling context,
-with very competitive performance.
-</p>
-<p>
-As a general guideline: <b>use callbacks only when you must</b>, because
-of existing C APIs. E.g. callback performance is irrelevant for a
-GUI application, which waits for user input most of the time, anyway.
-</p>
-<p>
-For new designs <b>avoid push-style APIs</b>: a C function repeatedly
-calling a callback for each result. Instead <b>use pull-style APIs</b>:
-call a C function repeatedly to get a new result. Calls from Lua
-to C via the FFI are much faster than the other way round. Most well-designed
-libraries already use pull-style APIs (read/write, get/put).
-</p>
-
-<h2 id="clib">C Library Namespaces</h2>
-<p>
-A C library namespace is a special kind of object which allows
-access to the symbols contained in shared libraries or the default
-symbol namespace. The default
-<a href="ext_ffi_api.html#ffi_C"><tt>ffi.C</tt></a> namespace is
-automatically created when the FFI library is loaded. C library
-namespaces for specific shared libraries may be created with the
-<a href="ext_ffi_api.html#ffi_load"><tt>ffi.load()</tt></a> API
-function.
-</p>
-<p>
-Indexing a C library namespace object with a symbol name (a Lua
-string) automatically binds it to the library. First the symbol type
-is resolved — it must have been declared with
-<a href="ext_ffi_api.html#ffi_cdef"><tt>ffi.cdef</tt></a>. Then the
-symbol address is resolved by searching for the symbol name in the
-associated shared libraries or the default symbol namespace. Finally,
-the resulting binding between the symbol name, the symbol type and its
-address is cached. Missing symbol declarations or nonexistent symbol
-names cause an error.
-</p>
-<p>
-This is what happens on a <b>read access</b> for the different kinds of
-symbols:
-</p>
-<ul>
-
-<li>External functions: a cdata object with the type of the function
-and its address is returned.</li>
-
-<li>External variables: the symbol address is dereferenced and the
-loaded value is <a href="#convert_tolua">converted to a Lua object</a>
-and returned.</li>
-
-<li>Constant values (<tt>static const</tt> or <tt>enum</tt>
-constants): the constant is <a href="#convert_tolua">converted to a
-Lua object</a> and returned.</li>
-
-</ul>
-<p>
-This is what happens on a <b>write access</b>:
-</p>
-<ul>
-
-<li>External variables: the value to be written is
-<a href="#convert_fromlua">converted to the C type</a> of the
-variable and then stored at the symbol address.</li>
-
-<li>Writing to constant variables or to any other symbol type causes
-an error, like any other attempted write to a constant location.</li>
-
-</ul>
-<p>
-C library namespaces themselves are garbage collected objects. If
-the last reference to the namespace object is gone, the garbage
-collector will eventually release the shared library reference and
-remove all memory associated with the namespace. Since this may
-trigger the removal of the shared library from the memory of the
-running process, it's generally <em>not safe</em> to use function
-cdata objects obtained from a library if the namespace object may be
-unreferenced.
-</p>
-<p>
-Performance notice: the JIT compiler specializes to the identity of
-namespace objects and to the strings used to index it. This
-effectively turns function cdata objects into constants. It's not
-useful and actually counter-productive to explicitly cache these
-function objects, e.g. <tt>local strlen = ffi.C.strlen</tt>. OTOH it
-<em>is</em> useful to cache the namespace itself, e.g. <tt>local C =
-ffi.C</tt>.
-</p>
-
-<h2 id="policy">No Hand-holding!</h2>
-<p>
-The FFI library has been designed as <b>a low-level library</b>. The
-goal is to interface with C code and C data types with a
-minimum of overhead. This means <b>you can do anything you can do
-from C</b>: access all memory, overwrite anything in memory, call
-machine code at any memory address and so on.
-</p>
-<p>
-The FFI library provides <b>no memory safety</b>, unlike regular Lua
-code. It will happily allow you to dereference a <tt>NULL</tt>
-pointer, to access arrays out of bounds or to misdeclare
-C functions. If you make a mistake, your application might crash,
-just like equivalent C code would.
-</p>
-<p>
-This behavior is inevitable, since the goal is to provide full
-interoperability with C code. Adding extra safety measures, like
-bounds checks, would be futile. There's no way to detect
-misdeclarations of C functions, since shared libraries only
-provide symbol names, but no type information. Likewise there's no way
-to infer the valid range of indexes for a returned pointer.
-</p>
-<p>
-Again: the FFI library is a low-level library. This implies it needs
-to be used with care, but it's flexibility and performance often
-outweigh this concern. If you're a C or C++ developer, it'll be easy
-to apply your existing knowledge. OTOH writing code for the FFI
-library is not for the faint of heart and probably shouldn't be the
-first exercise for someone with little experience in Lua, C or C++.
-</p>
-<p>
-As a corollary of the above, the FFI library is <b>not safe for use by
-untrusted Lua code</b>. If you're sandboxing untrusted Lua code, you
-definitely don't want to give this code access to the FFI library or
-to <em>any</em> cdata object (except 64 bit integers or complex
-numbers). Any properly engineered Lua sandbox needs to provide safety
-wrappers for many of the standard Lua library functions —
-similar wrappers need to be written for high-level operations on FFI
-data types, too.
-</p>
-
-<h2 id="status">Current Status</h2>
-<p>
-The initial release of the FFI library has some limitations and is
-missing some features. Most of these will be fixed in future releases.
-</p>
-<p>
-<a href="#clang">C language support</a> is
-currently incomplete:
-</p>
-<ul>
-<li>C declarations are not passed through a C pre-processor,
-yet.</li>
-<li>The C parser is able to evaluate most constant expressions
-commonly found in C header files. However it doesn't handle the
-full range of C expression semantics and may fail for some
-obscure constructs.</li>
-<li><tt>static const</tt> declarations only work for integer types
-up to 32 bits. Neither declaring string constants nor
-floating-point constants is supported.</li>
-<li>Packed <tt>struct</tt> bitfields that cross container boundaries
-are not implemented.</li>
-<li>Native vector types may be defined with the GCC <tt>mode</tt> or
-<tt>vector_size</tt> attribute. But no operations other than loading,
-storing and initializing them are supported, yet.</li>
-<li>The <tt>volatile</tt> type qualifier is currently ignored by
-compiled code.</li>
-<li><a href="ext_ffi_api.html#ffi_cdef"><tt>ffi.cdef</tt></a> silently
-ignores most re-declarations. Note: avoid re-declarations which do not
-conform to C99. The implementation will eventually be changed to
-perform strict checks.</li>
-</ul>
-<p>
-The JIT compiler already handles a large subset of all FFI operations.
-It automatically falls back to the interpreter for unimplemented
-operations (you can check for this with the
-<a href="running.html#opt_j"><tt>-jv</tt></a> command line option).
-The following operations are currently not compiled and may exhibit
-suboptimal performance, especially when used in inner loops:
-</p>
-<ul>
-<li>Bitfield accesses and initializations.</li>
-<li>Vector operations.</li>
-<li>Table initializers.</li>
-<li>Initialization of nested <tt>struct</tt>/<tt>union</tt> types.</li>
-<li>Non-default initialization of VLA/VLS or large C types
-(> 128 bytes or > 16 array elements.</li>
-<li>Conversions from lightuserdata to <tt>void *</tt>.</li>
-<li>Pointer differences for element sizes that are not a power of
-two.</li>
-<li>Calls to C functions with aggregates passed or returned by
-value.</li>
-<li>Calls to ctype metamethods which are not plain functions.</li>
-<li>ctype <tt>__newindex</tt> tables and non-string lookups in ctype
-<tt>__index</tt> tables.</li>
-<li><tt>tostring()</tt> for cdata types.</li>
-<li>Calls to <tt>ffi.cdef()</tt>, <tt>ffi.load()</tt> and
-<tt>ffi.metatype()</tt>.</li>
-</ul>
-<p>
-Other missing features:
-</p>
-<ul>
-<li>Arithmetic for <tt>complex</tt> numbers.</li>
-<li>Passing structs by value to vararg C functions.</li>
-<li><a href="extensions.html#exceptions">C++ exception interoperability</a>
-does not extend to C functions called via the FFI, if the call is
-compiled.</li>
-</ul>
-<br class="flush">
-</div>
-<div id="foot">
-<hr class="hide">
-Copyright © 2005-2015 Mike Pall
-<span class="noprint">
-·
-<a href="contact.html">Contact</a>
-</span>
-</div>
-</body>
-</html>
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd"> +<html> +<head> +<title>FFI Semantics</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-2016, 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.convtable { line-height: 1.2; } +tr.convhead td { font-weight: bold; } +td.convop { font-style: italic; width: 40%; } +</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 Semantics</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 class="current" 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 detailed semantics underlying the FFI library +and its interaction with both Lua and C code. +</p> +<p> +Given that the FFI library is designed to interface with C code +and that declarations can be written in plain C syntax, <b>it +closely follows the C language semantics</b>, wherever possible. +Some minor concessions are needed for smoother interoperation with Lua +language semantics. +</p> +<p> +Please don't be overwhelmed by the contents of this page — this +is a reference and you may need to consult it, if in doubt. It doesn't +hurt to skim this page, but most of the semantics "just work" as you'd +expect them to work. It should be straightforward to write +applications using the LuaJIT FFI for developers with a C or C++ +background. +</p> + +<h2 id="clang">C Language Support</h2> +<p> +The FFI library has a built-in C parser with a minimal memory +footprint. It's used by the <a href="ext_ffi_api.html">ffi.* library +functions</a> to declare C types or external symbols. +</p> +<p> +It's only purpose is to parse C declarations, as found e.g. in +C header files. Although it does evaluate constant expressions, +it's <em>not</em> a C compiler. The body of <tt>inline</tt> +C function definitions is simply ignored. +</p> +<p> +Also, this is <em>not</em> a validating C parser. It expects and +accepts correctly formed C declarations, but it may choose to +ignore bad declarations or show rather generic error messages. If in +doubt, please check the input against your favorite C compiler. +</p> +<p> +The C parser complies to the <b>C99 language standard</b> plus +the following extensions: +</p> +<ul> + +<li>The <tt>'\e'</tt> escape in character and string literals.</li> + +<li>The C99/C++ boolean type, declared with the keywords <tt>bool</tt> +or <tt>_Bool</tt>.</li> + +<li>Complex numbers, declared with the keywords <tt>complex</tt> or +<tt>_Complex</tt>.</li> + +<li>Two complex number types: <tt>complex</tt> (aka +<tt>complex double</tt>) and <tt>complex float</tt>.</li> + +<li>Vector types, declared with the GCC <tt>mode</tt> or +<tt>vector_size</tt> attribute.</li> + +<li>Unnamed ('transparent') <tt>struct</tt>/<tt>union</tt> fields +inside a <tt>struct</tt>/<tt>union</tt>.</li> + +<li>Incomplete <tt>enum</tt> declarations, handled like incomplete +<tt>struct</tt> declarations.</li> + +<li>Unnamed <tt>enum</tt> fields inside a +<tt>struct</tt>/<tt>union</tt>. This is similar to a scoped C++ +<tt>enum</tt>, except that declared constants are visible in the +global namespace, too.</li> + +<li>Scoped <tt>static const</tt> declarations inside a +<tt>struct</tt>/<tt>union</tt> (from C++).</li> + +<li>Zero-length arrays (<tt>[0]</tt>), empty +<tt>struct</tt>/<tt>union</tt>, variable-length arrays (VLA, +<tt>[?]</tt>) and variable-length structs (VLS, with a trailing +VLA).</li> + +<li>C++ reference types (<tt>int &x</tt>).</li> + +<li>Alternate GCC keywords with '<tt>__</tt>', e.g. +<tt>__const__</tt>.</li> + +<li>GCC <tt>__attribute__</tt> with the following attributes: +<tt>aligned</tt>, <tt>packed</tt>, <tt>mode</tt>, +<tt>vector_size</tt>, <tt>cdecl</tt>, <tt>fastcall</tt>, +<tt>stdcall</tt>, <tt>thiscall</tt>.</li> + +<li>The GCC <tt>__extension__</tt> keyword and the GCC +<tt>__alignof__</tt> operator.</li> + +<li>GCC <tt>__asm__("symname")</tt> symbol name redirection for +function declarations.</li> + +<li>MSVC keywords for fixed-length types: <tt>__int8</tt>, +<tt>__int16</tt>, <tt>__int32</tt> and <tt>__int64</tt>.</li> + +<li>MSVC <tt>__cdecl</tt>, <tt>__fastcall</tt>, <tt>__stdcall</tt>, +<tt>__thiscall</tt>, <tt>__ptr32</tt>, <tt>__ptr64</tt>, +<tt>__declspec(align(n))</tt> and <tt>#pragma pack</tt>.</li> + +<li>All other GCC/MSVC-specific attributes are ignored.</li> + +</ul> +<p> +The following C types are pre-defined by the C parser (like +a <tt>typedef</tt>, except re-declarations will be ignored): +</p> +<ul> + +<li>Vararg handling: <tt>va_list</tt>, <tt>__builtin_va_list</tt>, +<tt>__gnuc_va_list</tt>.</li> + +<li>From <tt><stddef.h></tt>: <tt>ptrdiff_t</tt>, +<tt>size_t</tt>, <tt>wchar_t</tt>.</li> + +<li>From <tt><stdint.h></tt>: <tt>int8_t</tt>, <tt>int16_t</tt>, +<tt>int32_t</tt>, <tt>int64_t</tt>, <tt>uint8_t</tt>, +<tt>uint16_t</tt>, <tt>uint32_t</tt>, <tt>uint64_t</tt>, +<tt>intptr_t</tt>, <tt>uintptr_t</tt>.</li> + +<li>From <tt><unistd.h></tt> (POSIX): <tt>ssize_t</tt>.</li> + +</ul> +<p> +You're encouraged to use these types in preference to +compiler-specific extensions or target-dependent standard types. +E.g. <tt>char</tt> differs in signedness and <tt>long</tt> differs in +size, depending on the target architecture and platform ABI. +</p> +<p> +The following C features are <b>not</b> supported: +</p> +<ul> + +<li>A declaration must always have a type specifier; it doesn't +default to an <tt>int</tt> type.</li> + +<li>Old-style empty function declarations (K&R) are not allowed. +All C functions must have a proper prototype declaration. A +function declared without parameters (<tt>int foo();</tt>) is +treated as a function taking zero arguments, like in C++.</li> + +<li>The <tt>long double</tt> C type is parsed correctly, but +there's no support for the related conversions, accesses or arithmetic +operations.</li> + +<li>Wide character strings and character literals are not +supported.</li> + +<li><a href="#status">See below</a> for features that are currently +not implemented.</li> + +</ul> + +<h2 id="convert">C Type Conversion Rules</h2> + +<h3 id="convert_tolua">Conversions from C types to Lua objects</h3> +<p> +These conversion rules apply for <em>read accesses</em> to +C types: indexing pointers, arrays or +<tt>struct</tt>/<tt>union</tt> types; reading external variables or +constant values; retrieving return values from C calls: +</p> +<table class="convtable"> +<tr class="convhead"> +<td class="convin">Input</td> +<td class="convop">Conversion</td> +<td class="convout">Output</td> +</tr> +<tr class="odd separate"> +<td class="convin"><tt>int8_t</tt>, <tt>int16_t</tt></td><td class="convop">→<sup>sign-ext</sup> <tt>int32_t</tt> → <tt>double</tt></td><td class="convout">number</td></tr> +<tr class="even"> +<td class="convin"><tt>uint8_t</tt>, <tt>uint16_t</tt></td><td class="convop">→<sup>zero-ext</sup> <tt>int32_t</tt> → <tt>double</tt></td><td class="convout">number</td></tr> +<tr class="odd"> +<td class="convin"><tt>int32_t</tt>, <tt>uint32_t</tt></td><td class="convop">→ <tt>double</tt></td><td class="convout">number</td></tr> +<tr class="even"> +<td class="convin"><tt>int64_t</tt>, <tt>uint64_t</tt></td><td class="convop">boxed value</td><td class="convout">64 bit int cdata</td></tr> +<tr class="odd separate"> +<td class="convin"><tt>double</tt>, <tt>float</tt></td><td class="convop">→ <tt>double</tt></td><td class="convout">number</td></tr> +<tr class="even separate"> +<td class="convin"><tt>bool</tt></td><td class="convop">0 → <tt>false</tt>, otherwise <tt>true</tt></td><td class="convout">boolean</td></tr> +<tr class="odd separate"> +<td class="convin"><tt>enum</tt></td><td class="convop">boxed value</td><td class="convout">enum cdata</td></tr> +<tr class="even"> +<td class="convin">Complex number</td><td class="convop">boxed value</td><td class="convout">complex cdata</td></tr> +<tr class="odd"> +<td class="convin">Vector</td><td class="convop">boxed value</td><td class="convout">vector cdata</td></tr> +<tr class="even"> +<td class="convin">Pointer</td><td class="convop">boxed value</td><td class="convout">pointer cdata</td></tr> +<tr class="odd separate"> +<td class="convin">Array</td><td class="convop">boxed reference</td><td class="convout">reference cdata</td></tr> +<tr class="even"> +<td class="convin"><tt>struct</tt>/<tt>union</tt></td><td class="convop">boxed reference</td><td class="convout">reference cdata</td></tr> +</table> +<p> +Bitfields are treated like their underlying type. +</p> +<p> +Reference types are dereferenced <em>before</em> a conversion can take +place — the conversion is applied to the C type pointed to +by the reference. +</p> + +<h3 id="convert_fromlua">Conversions from Lua objects to C types</h3> +<p> +These conversion rules apply for <em>write accesses</em> to +C types: indexing pointers, arrays or +<tt>struct</tt>/<tt>union</tt> types; initializing cdata objects; +casts to C types; writing to external variables; passing +arguments to C calls: +</p> +<table class="convtable"> +<tr class="convhead"> +<td class="convin">Input</td> +<td class="convop">Conversion</td> +<td class="convout">Output</td> +</tr> +<tr class="odd separate"> +<td class="convin">number</td><td class="convop">→</td><td class="convout"><tt>double</tt></td></tr> +<tr class="even"> +<td class="convin">boolean</td><td class="convop"><tt>false</tt> → 0, <tt>true</tt> → 1</td><td class="convout"><tt>bool</tt></td></tr> +<tr class="odd separate"> +<td class="convin">nil</td><td class="convop"><tt>NULL</tt> →</td><td class="convout"><tt>(void *)</tt></td></tr> +<tr class="even"> +<td class="convin">lightuserdata</td><td class="convop">lightuserdata address →</td><td class="convout"><tt>(void *)</tt></td></tr> +<tr class="odd"> +<td class="convin">userdata</td><td class="convop">userdata payload →</td><td class="convout"><tt>(void *)</tt></td></tr> +<tr class="even"> +<td class="convin">io.* file</td><td class="convop">get FILE * handle →</td><td class="convout"><tt>(void *)</tt></td></tr> +<tr class="odd separate"> +<td class="convin">string</td><td class="convop">match against <tt>enum</tt> constant</td><td class="convout"><tt>enum</tt></td></tr> +<tr class="even"> +<td class="convin">string</td><td class="convop">copy string data + zero-byte</td><td class="convout"><tt>int8_t[]</tt>, <tt>uint8_t[]</tt></td></tr> +<tr class="odd"> +<td class="convin">string</td><td class="convop">string data →</td><td class="convout"><tt>const char[]</tt></td></tr> +<tr class="even separate"> +<td class="convin">function</td><td class="convop"><a href="#callback">create callback</a> →</td><td class="convout">C function type</td></tr> +<tr class="odd separate"> +<td class="convin">table</td><td class="convop"><a href="#init_table">table initializer</a></td><td class="convout">Array</td></tr> +<tr class="even"> +<td class="convin">table</td><td class="convop"><a href="#init_table">table initializer</a></td><td class="convout"><tt>struct</tt>/<tt>union</tt></td></tr> +<tr class="odd separate"> +<td class="convin">cdata</td><td class="convop">cdata payload →</td><td class="convout">C type</td></tr> +</table> +<p> +If the result type of this conversion doesn't match the +C type of the destination, the +<a href="#convert_between">conversion rules between C types</a> +are applied. +</p> +<p> +Reference types are immutable after initialization ("no re-seating of +references"). For initialization purposes or when passing values to +reference parameters, they are treated like pointers. Note that unlike +in C++, there's no way to implement automatic reference generation of +variables under the Lua language semantics. If you want to call a +function with a reference parameter, you need to explicitly pass a +one-element array. +</p> + +<h3 id="convert_between">Conversions between C types</h3> +<p> +These conversion rules are more or less the same as the standard +C conversion rules. Some rules only apply to casts, or require +pointer or type compatibility: +</p> +<table class="convtable"> +<tr class="convhead"> +<td class="convin">Input</td> +<td class="convop">Conversion</td> +<td class="convout">Output</td> +</tr> +<tr class="odd separate"> +<td class="convin">Signed integer</td><td class="convop">→<sup>narrow or sign-extend</sup></td><td class="convout">Integer</td></tr> +<tr class="even"> +<td class="convin">Unsigned integer</td><td class="convop">→<sup>narrow or zero-extend</sup></td><td class="convout">Integer</td></tr> +<tr class="odd"> +<td class="convin">Integer</td><td class="convop">→<sup>round</sup></td><td class="convout"><tt>double</tt>, <tt>float</tt></td></tr> +<tr class="even"> +<td class="convin"><tt>double</tt>, <tt>float</tt></td><td class="convop">→<sup>trunc</sup> <tt>int32_t</tt> →<sup>narrow</sup></td><td class="convout"><tt>(u)int8_t</tt>, <tt>(u)int16_t</tt></td></tr> +<tr class="odd"> +<td class="convin"><tt>double</tt>, <tt>float</tt></td><td class="convop">→<sup>trunc</sup></td><td class="convout"><tt>(u)int32_t</tt>, <tt>(u)int64_t</tt></td></tr> +<tr class="even"> +<td class="convin"><tt>double</tt>, <tt>float</tt></td><td class="convop">→<sup>round</sup></td><td class="convout"><tt>float</tt>, <tt>double</tt></td></tr> +<tr class="odd separate"> +<td class="convin">Number</td><td class="convop">n == 0 → 0, otherwise 1</td><td class="convout"><tt>bool</tt></td></tr> +<tr class="even"> +<td class="convin"><tt>bool</tt></td><td class="convop"><tt>false</tt> → 0, <tt>true</tt> → 1</td><td class="convout">Number</td></tr> +<tr class="odd separate"> +<td class="convin">Complex number</td><td class="convop">convert real part</td><td class="convout">Number</td></tr> +<tr class="even"> +<td class="convin">Number</td><td class="convop">convert real part, imag = 0</td><td class="convout">Complex number</td></tr> +<tr class="odd"> +<td class="convin">Complex number</td><td class="convop">convert real and imag part</td><td class="convout">Complex number</td></tr> +<tr class="even separate"> +<td class="convin">Number</td><td class="convop">convert scalar and replicate</td><td class="convout">Vector</td></tr> +<tr class="odd"> +<td class="convin">Vector</td><td class="convop">copy (same size)</td><td class="convout">Vector</td></tr> +<tr class="even separate"> +<td class="convin"><tt>struct</tt>/<tt>union</tt></td><td class="convop">take base address (compat)</td><td class="convout">Pointer</td></tr> +<tr class="odd"> +<td class="convin">Array</td><td class="convop">take base address (compat)</td><td class="convout">Pointer</td></tr> +<tr class="even"> +<td class="convin">Function</td><td class="convop">take function address</td><td class="convout">Function pointer</td></tr> +<tr class="odd separate"> +<td class="convin">Number</td><td class="convop">convert via <tt>uintptr_t</tt> (cast)</td><td class="convout">Pointer</td></tr> +<tr class="even"> +<td class="convin">Pointer</td><td class="convop">convert address (compat/cast)</td><td class="convout">Pointer</td></tr> +<tr class="odd"> +<td class="convin">Pointer</td><td class="convop">convert address (cast)</td><td class="convout">Integer</td></tr> +<tr class="even"> +<td class="convin">Array</td><td class="convop">convert base address (cast)</td><td class="convout">Integer</td></tr> +<tr class="odd separate"> +<td class="convin">Array</td><td class="convop">copy (compat)</td><td class="convout">Array</td></tr> +<tr class="even"> +<td class="convin"><tt>struct</tt>/<tt>union</tt></td><td class="convop">copy (identical type)</td><td class="convout"><tt>struct</tt>/<tt>union</tt></td></tr> +</table> +<p> +Bitfields or <tt>enum</tt> types are treated like their underlying +type. +</p> +<p> +Conversions not listed above will raise an error. E.g. it's not +possible to convert a pointer to a complex number or vice versa. +</p> + +<h3 id="convert_vararg">Conversions for vararg C function arguments</h3> +<p> +The following default conversion rules apply when passing Lua objects +to the variable argument part of vararg C functions: +</p> +<table class="convtable"> +<tr class="convhead"> +<td class="convin">Input</td> +<td class="convop">Conversion</td> +<td class="convout">Output</td> +</tr> +<tr class="odd separate"> +<td class="convin">number</td><td class="convop">→</td><td class="convout"><tt>double</tt></td></tr> +<tr class="even"> +<td class="convin">boolean</td><td class="convop"><tt>false</tt> → 0, <tt>true</tt> → 1</td><td class="convout"><tt>bool</tt></td></tr> +<tr class="odd separate"> +<td class="convin">nil</td><td class="convop"><tt>NULL</tt> →</td><td class="convout"><tt>(void *)</tt></td></tr> +<tr class="even"> +<td class="convin">userdata</td><td class="convop">userdata payload →</td><td class="convout"><tt>(void *)</tt></td></tr> +<tr class="odd"> +<td class="convin">lightuserdata</td><td class="convop">lightuserdata address →</td><td class="convout"><tt>(void *)</tt></td></tr> +<tr class="even separate"> +<td class="convin">string</td><td class="convop">string data →</td><td class="convout"><tt>const char *</tt></td></tr> +<tr class="odd separate"> +<td class="convin"><tt>float</tt> cdata</td><td class="convop">→</td><td class="convout"><tt>double</tt></td></tr> +<tr class="even"> +<td class="convin">Array cdata</td><td class="convop">take base address</td><td class="convout">Element pointer</td></tr> +<tr class="odd"> +<td class="convin"><tt>struct</tt>/<tt>union</tt> cdata</td><td class="convop">take base address</td><td class="convout"><tt>struct</tt>/<tt>union</tt> pointer</td></tr> +<tr class="even"> +<td class="convin">Function cdata</td><td class="convop">take function address</td><td class="convout">Function pointer</td></tr> +<tr class="odd"> +<td class="convin">Any other cdata</td><td class="convop">no conversion</td><td class="convout">C type</td></tr> +</table> +<p> +To pass a Lua object, other than a cdata object, as a specific type, +you need to override the conversion rules: create a temporary cdata +object with a constructor or a cast and initialize it with the value +to pass: +</p> +<p> +Assuming <tt>x</tt> is a Lua number, here's how to pass it as an +integer to a vararg function: +</p> +<pre class="code"> +ffi.cdef[[ +int printf(const char *fmt, ...); +]] +ffi.C.printf("integer value: %d\n", ffi.new("int", x)) +</pre> +<p> +If you don't do this, the default Lua number → <tt>double</tt> +conversion rule applies. A vararg C function expecting an integer +will see a garbled or uninitialized value. +</p> + +<h2 id="init">Initializers</h2> +<p> +Creating a cdata object with +<a href="ext_ffi_api.html#ffi_new"><tt>ffi.new()</tt></a> or the +equivalent constructor syntax always initializes its contents, too. +Different rules apply, depending on the number of optional +initializers and the C types involved: +</p> +<ul> +<li>If no initializers are given, the object is filled with zero bytes.</li> + +<li>Scalar types (numbers and pointers) accept a single initializer. +The Lua object is <a href="#convert_fromlua">converted to the scalar +C type</a>.</li> + +<li>Valarrays (complex numbers and vectors) are treated like scalars +when a single initializer is given. Otherwise they are treated like +regular arrays.</li> + +<li>Aggregate types (arrays and structs) accept either a single cdata +initializer of the same type (copy constructor), a single +<a href="#init_table">table initializer</a>, or a flat list of +initializers.</li> + +<li>The elements of an array are initialized, starting at index zero. +If a single initializer is given for an array, it's repeated for all +remaining elements. This doesn't happen if two or more initializers +are given: all remaining uninitialized elements are filled with zero +bytes.</li> + +<li>Byte arrays may also be initialized with a Lua string. This copies +the whole string plus a terminating zero-byte. The copy stops early only +if the array has a known, fixed size.</li> + +<li>The fields of a <tt>struct</tt> are initialized in the order of +their declaration. Uninitialized fields are filled with zero +bytes.</li> + +<li>Only the first field of a <tt>union</tt> can be initialized with a +flat initializer.</li> + +<li>Elements or fields which are aggregates themselves are initialized +with a <em>single</em> initializer, but this may be a table +initializer or a compatible aggregate.</li> + +<li>Excess initializers cause an error.</li> + +</ul> + +<h2 id="init_table">Table Initializers</h2> +<p> +The following rules apply if a Lua table is used to initialize an +Array or a <tt>struct</tt>/<tt>union</tt>: +</p> +<ul> + +<li>If the table index <tt>[0]</tt> is non-<tt>nil</tt>, then the +table is assumed to be zero-based. Otherwise it's assumed to be +one-based.</li> + +<li>Array elements, starting at index zero, are initialized one-by-one +with the consecutive table elements, starting at either index +<tt>[0]</tt> or <tt>[1]</tt>. This process stops at the first +<tt>nil</tt> table element.</li> + +<li>If exactly one array element was initialized, it's repeated for +all the remaining elements. Otherwise all remaining uninitialized +elements are filled with zero bytes.</li> + +<li>The above logic only applies to arrays with a known fixed size. +A VLA is only initialized with the element(s) given in the table. +Depending on the use case, you may need to explicitly add a +<tt>NULL</tt> or <tt>0</tt> terminator to a VLA.</li> + +<li>A <tt>struct</tt>/<tt>union</tt> can be initialized in the +order of the declaration of its fields. Each field is initialized with +consecutive table elements, starting at either index <tt>[0]</tt> +or <tt>[1]</tt>. This process stops at the first <tt>nil</tt> table +element.</li> + +<li>Otherwise, if neither index <tt>[0]</tt> nor <tt>[1]</tt> is present, +a <tt>struct</tt>/<tt>union</tt> is initialized by looking up each field +name (as a string key) in the table. Each non-<tt>nil</tt> value is +used to initialize the corresponding field.</li> + +<li>Uninitialized fields of a <tt>struct</tt> are filled with zero +bytes, except for the trailing VLA of a VLS.</li> + +<li>Initialization of a <tt>union</tt> stops after one field has been +initialized. If no field has been initialized, the <tt>union</tt> is +filled with zero bytes.</li> + +<li>Elements or fields which are aggregates themselves are initialized +with a <em>single</em> initializer, but this may be a nested table +initializer (or a compatible aggregate).</li> + +<li>Excess initializers for an array cause an error. Excess +initializers for a <tt>struct</tt>/<tt>union</tt> are ignored. +Unrelated table entries are ignored, too.</li> + +</ul> +<p> +Example: +</p> +<pre class="code"> +local ffi = require("ffi") + +ffi.cdef[[ +struct foo { int a, b; }; +union bar { int i; double d; }; +struct nested { int x; struct foo y; }; +]] + +ffi.new("int[3]", {}) --> 0, 0, 0 +ffi.new("int[3]", {1}) --> 1, 1, 1 +ffi.new("int[3]", {1,2}) --> 1, 2, 0 +ffi.new("int[3]", {1,2,3}) --> 1, 2, 3 +ffi.new("int[3]", {[0]=1}) --> 1, 1, 1 +ffi.new("int[3]", {[0]=1,2}) --> 1, 2, 0 +ffi.new("int[3]", {[0]=1,2,3}) --> 1, 2, 3 +ffi.new("int[3]", {[0]=1,2,3,4}) --> error: too many initializers + +ffi.new("struct foo", {}) --> a = 0, b = 0 +ffi.new("struct foo", {1}) --> a = 1, b = 0 +ffi.new("struct foo", {1,2}) --> a = 1, b = 2 +ffi.new("struct foo", {[0]=1,2}) --> a = 1, b = 2 +ffi.new("struct foo", {b=2}) --> a = 0, b = 2 +ffi.new("struct foo", {a=1,b=2,c=3}) --> a = 1, b = 2 'c' is ignored + +ffi.new("union bar", {}) --> i = 0, d = 0.0 +ffi.new("union bar", {1}) --> i = 1, d = ? +ffi.new("union bar", {[0]=1,2}) --> i = 1, d = ? '2' is ignored +ffi.new("union bar", {d=2}) --> i = ?, d = 2.0 + +ffi.new("struct nested", {1,{2,3}}) --> x = 1, y.a = 2, y.b = 3 +ffi.new("struct nested", {x=1,y={2,3}}) --> x = 1, y.a = 2, y.b = 3 +</pre> + +<h2 id="cdata_ops">Operations on cdata Objects</h2> +<p> +All of the standard Lua operators can be applied to cdata objects or a +mix of a cdata object and another Lua object. The following list shows +the pre-defined operations. +</p> +<p> +Reference types are dereferenced <em>before</em> performing each of +the operations below — the operation is applied to the +C type pointed to by the reference. +</p> +<p> +The pre-defined operations are always tried first before deferring to a +metamethod or index table (if any) for the corresponding ctype (except +for <tt>__new</tt>). An error is raised if the metamethod lookup or +index table lookup fails. +</p> + +<h3 id="cdata_array">Indexing a cdata object</h3> +<ul> + +<li><b>Indexing a pointer/array</b>: a cdata pointer/array can be +indexed by a cdata number or a Lua number. The element address is +computed as the base address plus the number value multiplied by the +element size in bytes. A read access loads the element value and +<a href="#convert_tolua">converts it to a Lua object</a>. A write +access <a href="#convert_fromlua">converts a Lua object to the element +type</a> and stores the converted value to the element. An error is +raised if the element size is undefined or a write access to a +constant element is attempted.</li> + +<li><b>Dereferencing a <tt>struct</tt>/<tt>union</tt> field</b>: a +cdata <tt>struct</tt>/<tt>union</tt> or a pointer to a +<tt>struct</tt>/<tt>union</tt> can be dereferenced by a string key, +giving the field name. The field address is computed as the base +address plus the relative offset of the field. A read access loads the +field value and <a href="#convert_tolua">converts it to a Lua +object</a>. A write access <a href="#convert_fromlua">converts a Lua +object to the field type</a> and stores the converted value to the +field. An error is raised if a write access to a constant +<tt>struct</tt>/<tt>union</tt> or a constant field is attempted. +Scoped enum constants or static constants are treated like a constant +field.</li> + +<li><b>Indexing a complex number</b>: a complex number can be indexed +either by a cdata number or a Lua number with the values 0 or 1, or by +the strings <tt>"re"</tt> or <tt>"im"</tt>. A read access loads the +real part (<tt>[0]</tt>, <tt>.re</tt>) or the imaginary part +(<tt>[1]</tt>, <tt>.im</tt>) part of a complex number and +<a href="#convert_tolua">converts it to a Lua number</a>. The +sub-parts of a complex number are immutable — assigning to an +index of a complex number raises an error. Accessing out-of-bound +indexes returns unspecified results, but is guaranteed not to trigger +memory access violations.</li> + +<li><b>Indexing a vector</b>: a vector is treated like an array for +indexing purposes, except the vector elements are immutable — +assigning to an index of a vector raises an error.</li> + +</ul> +<p> +A ctype object can be indexed with a string key, too. The only +pre-defined operation is reading scoped constants of +<tt>struct</tt>/<tt>union</tt> types. All other accesses defer +to the corresponding metamethods or index tables (if any). +</p> +<p> +Note: since there's (deliberately) no address-of operator, a cdata +object holding a value type is effectively immutable after +initialization. The JIT compiler benefits from this fact when applying +certain optimizations. +</p> +<p> +As a consequence, the <em>elements</em> of complex numbers and +vectors are immutable. But the elements of an aggregate holding these +types <em>may</em> be modified of course. I.e. you cannot assign to +<tt>foo.c.im</tt>, but you can assign a (newly created) complex number +to <tt>foo.c</tt>. +</p> +<p> +The JIT compiler implements strict aliasing rules: accesses to different +types do <b>not</b> alias, except for differences in signedness (this +applies even to <tt>char</tt> pointers, unlike C99). Type punning +through unions is explicitly detected and allowed. +</p> + +<h3 id="cdata_call">Calling a cdata object</h3> +<ul> + +<li><b>Constructor</b>: a ctype object can be called and used as a +<a href="ext_ffi_api.html#ffi_new">constructor</a>. This is equivalent +to <tt>ffi.new(ct, ...)</tt>, unless a <tt>__new</tt> metamethod is +defined. The <tt>__new</tt> metamethod is called with the ctype object +plus any other arguments passed to the contructor. Note that you have to +use <tt>ffi.new</tt> inside of it, since calling <tt>ct(...)</tt> would +cause infinite recursion.</li> + +<li><b>C function call</b>: a cdata function or cdata function +pointer can be called. The passed arguments are +<a href="#convert_fromlua">converted to the C types</a> of the +parameters given by the function declaration. Arguments passed to the +variable argument part of vararg C function use +<a href="#convert_vararg">special conversion rules</a>. This +C function is called and the return value (if any) is +<a href="#convert_tolua">converted to a Lua object</a>.<br> +On Windows/x86 systems, <tt>__stdcall</tt> functions are automatically +detected and a function declared as <tt>__cdecl</tt> (the default) is +silently fixed up after the first call.</li> + +</ul> + +<h3 id="cdata_arith">Arithmetic on cdata objects</h3> +<ul> + +<li><b>Pointer arithmetic</b>: a cdata pointer/array and a cdata +number or a Lua number can be added or subtracted. The number must be +on the right hand side for a subtraction. The result is a pointer of +the same type with an address plus or minus the number value +multiplied by the element size in bytes. An error is raised if the +element size is undefined.</li> + +<li><b>Pointer difference</b>: two compatible cdata pointers/arrays +can be subtracted. The result is the difference between their +addresses, divided by the element size in bytes. An error is raised if +the element size is undefined or zero.</li> + +<li><b>64 bit integer arithmetic</b>: the standard arithmetic +operators (<tt>+ - * / % ^</tt> and unary +minus) can be applied to two cdata numbers, or a cdata number and a +Lua number. If one of them is an <tt>uint64_t</tt>, the other side is +converted to an <tt>uint64_t</tt> and an unsigned arithmetic operation +is performed. Otherwise both sides are converted to an +<tt>int64_t</tt> and a signed arithmetic operation is performed. The +result is a boxed 64 bit cdata object.<br> + +If one of the operands is an <tt>enum</tt> and the other operand is a +string, the string is converted to the value of a matching <tt>enum</tt> +constant before the above conversion.<br> + +These rules ensure that 64 bit integers are "sticky". Any +expression involving at least one 64 bit integer operand results +in another one. The undefined cases for the division, modulo and power +operators return <tt>2LL ^ 63</tt> or +<tt>2ULL ^ 63</tt>.<br> + +You'll have to explicitly convert a 64 bit integer to a Lua +number (e.g. for regular floating-point calculations) with +<tt>tonumber()</tt>. But note this may incur a precision loss.</li> + +<li><b>64 bit bitwise operations</b>: the rules for 64 bit +arithmetic operators apply analogously.<br> + +Unlike the other <tt>bit.*</tt> operations, <tt>bit.tobit()</tt> +converts a cdata number via <tt>int64_t</tt> to <tt>int32_t</tt> and +returns a Lua number.<br> + +For <tt>bit.band()</tt>, <tt>bit.bor()</tt> and <tt>bit.bxor()</tt>, the +conversion to <tt>int64_t</tt> or <tt>uint64_t</tt> applies to +<em>all</em> arguments, if <em>any</em> argument is a cdata number.<br> + +For all other operations, only the first argument is used to determine +the output type. This implies that a cdata number as a shift count for +shifts and rotates is accepted, but that alone does <em>not</em> cause +a cdata number output. + +</ul> + +<h3 id="cdata_comp">Comparisons of cdata objects</h3> +<ul> + +<li><b>Pointer comparison</b>: two compatible cdata pointers/arrays +can be compared. The result is the same as an unsigned comparison of +their addresses. <tt>nil</tt> is treated like a <tt>NULL</tt> pointer, +which is compatible with any other pointer type.</li> + +<li><b>64 bit integer comparison</b>: two cdata numbers, or a +cdata number and a Lua number can be compared with each other. If one +of them is an <tt>uint64_t</tt>, the other side is converted to an +<tt>uint64_t</tt> and an unsigned comparison is performed. Otherwise +both sides are converted to an <tt>int64_t</tt> and a signed +comparison is performed.<br> + +If one of the operands is an <tt>enum</tt> and the other operand is a +string, the string is converted to the value of a matching <tt>enum</tt> +constant before the above conversion.<br> + +<li><b>Comparisons for equality/inequality</b> never raise an error. +Even incompatible pointers can be compared for equality by address. Any +other incompatible comparison (also with non-cdata objects) treats the +two sides as unequal.</li> + +</ul> + +<h3 id="cdata_key">cdata objects as table keys</h3> +<p> +Lua tables may be indexed by cdata objects, but this doesn't provide +any useful semantics — <b>cdata objects are unsuitable as table +keys!</b> +</p> +<p> +A cdata object is treated like any other garbage-collected object and +is hashed and compared by its address for table indexing. Since +there's no interning for cdata value types, the same value may be +boxed in different cdata objects with different addresses. Thus +<tt>t[1LL+1LL]</tt> and <tt>t[2LL]</tt> usually <b>do not</b> point to +the same hash slot and they certainly <b>do not</b> point to the same +hash slot as <tt>t[2]</tt>. +</p> +<p> +It would seriously drive up implementation complexity and slow down +the common case, if one were to add extra handling for by-value +hashing and comparisons to Lua tables. Given the ubiquity of their use +inside the VM, this is not acceptable. +</p> +<p> +There are three viable alternatives, if you really need to use cdata +objects as keys: +</p> +<ul> + +<li>If you can get by with the precision of Lua numbers +(52 bits), then use <tt>tonumber()</tt> on a cdata number or +combine multiple fields of a cdata aggregate to a Lua number. Then use +the resulting Lua number as a key when indexing tables.<br> +One obvious benefit: <tt>t[tonumber(2LL)]</tt> <b>does</b> point to +the same slot as <tt>t[2]</tt>.</li> + +<li>Otherwise use either <tt>tostring()</tt> on 64 bit integers +or complex numbers or combine multiple fields of a cdata aggregate to +a Lua string (e.g. with +<a href="ext_ffi_api.html#ffi_string"><tt>ffi.string()</tt></a>). Then +use the resulting Lua string as a key when indexing tables.</li> + +<li>Create your own specialized hash table implementation using the +C types provided by the FFI library, just like you would in +C code. Ultimately this may give much better performance than the +other alternatives or what a generic by-value hash table could +possibly provide.</li> + +</ul> + +<h2 id="param">Parameterized Types</h2> +<p> +To facilitate some abstractions, the two functions +<a href="ext_ffi_api.html#ffi_typeof"><tt>ffi.typeof</tt></a> and +<a href="ext_ffi_api.html#ffi_cdef"><tt>ffi.cdef</tt></a> support +parameterized types in C declarations. Note: none of the other API +functions taking a cdecl allow this. +</p> +<p> +Any place you can write a <b><tt>typedef</tt> name</b>, an +<b>identifier</b> or a <b>number</b> in a declaration, you can write +<tt>$</tt> (the dollar sign) instead. These placeholders are replaced in +order of appearance with the arguments following the cdecl string: +</p> +<pre class="code"> +-- Declare a struct with a parameterized field type and name: +ffi.cdef([[ +typedef struct { $ $; } foo_t; +]], type1, name1) + +-- Anonymous struct with dynamic names: +local bar_t = ffi.typeof("struct { int $, $; }", name1, name2) +-- Derived pointer type: +local bar_ptr_t = ffi.typeof("$ *", bar_t) + +-- Parameterized dimensions work even where a VLA won't work: +local matrix_t = ffi.typeof("uint8_t[$][$]", width, height) +</pre> +<p> +Caveat: this is <em>not</em> simple text substitution! A passed ctype or +cdata object is treated like the underlying type, a passed string is +considered an identifier and a number is considered a number. You must +not mix this up: e.g. passing <tt>"int"</tt> as a string doesn't work in +place of a type, you'd need to use <tt>ffi.typeof("int")</tt> instead. +</p> +<p> +The main use for parameterized types are libraries implementing abstract +data types +(<a href="http://www.freelists.org/post/luajit/ffi-type-of-pointer-to,8"><span class="ext">»</span> example</a>), +similar to what can be achieved with C++ template metaprogramming. +Another use case are derived types of anonymous structs, which avoids +pollution of the global struct namespace. +</p> +<p> +Please note that parameterized types are a nice tool and indispensable +for certain use cases. But you'll want to use them sparingly in regular +code, e.g. when all types are actually fixed. +</p> + +<h2 id="gc">Garbage Collection of cdata Objects</h2> +<p> +All explicitly (<tt>ffi.new()</tt>, <tt>ffi.cast()</tt> etc.) or +implicitly (accessors) created cdata objects are garbage collected. +You need to ensure to retain valid references to cdata objects +somewhere on a Lua stack, an upvalue or in a Lua table while they are +still in use. Once the last reference to a cdata object is gone, the +garbage collector will automatically free the memory used by it (at +the end of the next GC cycle). +</p> +<p> +Please note that pointers themselves are cdata objects, however they +are <b>not</b> followed by the garbage collector. So e.g. if you +assign a cdata array to a pointer, you must keep the cdata object +holding the array alive as long as the pointer is still in use: +</p> +<pre class="code"> +ffi.cdef[[ +typedef struct { int *a; } foo_t; +]] + +local s = ffi.new("foo_t", ffi.new("int[10]")) -- <span style="color:#c00000;">WRONG!</span> + +local a = ffi.new("int[10]") -- <span style="color:#00a000;">OK</span> +local s = ffi.new("foo_t", a) +-- Now do something with 's', but keep 'a' alive until you're done. +</pre> +<p> +Similar rules apply for Lua strings which are implicitly converted to +<tt>"const char *"</tt>: the string object itself must be +referenced somewhere or it'll be garbage collected eventually. The +pointer will then point to stale data, which may have already been +overwritten. Note that <em>string literals</em> are automatically kept +alive as long as the function containing it (actually its prototype) +is not garbage collected. +</p> +<p> +Objects which are passed as an argument to an external C function +are kept alive until the call returns. So it's generally safe to +create temporary cdata objects in argument lists. This is a common +idiom for <a href="#convert_vararg">passing specific C types to +vararg functions</a>. +</p> +<p> +Memory areas returned by C functions (e.g. from <tt>malloc()</tt>) +must be manually managed, of course (or use +<a href="ext_ffi_api.html#ffi_gc"><tt>ffi.gc()</tt></a>). Pointers to +cdata objects are indistinguishable from pointers returned by C +functions (which is one of the reasons why the GC cannot follow them). +</p> + +<h2 id="callback">Callbacks</h2> +<p> +The LuaJIT FFI automatically generates special callback functions +whenever a Lua function is converted to a C function pointer. This +associates the generated callback function pointer with the C type +of the function pointer and the Lua function object (closure). +</p> +<p> +This can happen implicitly due to the usual conversions, e.g. when +passing a Lua function to a function pointer argument. Or you can use +<tt>ffi.cast()</tt> to explicitly cast a Lua function to a +C function pointer. +</p> +<p> +Currently only certain C function types can be used as callback +functions. Neither C vararg functions nor functions with +pass-by-value aggregate argument or result types are supported. There +are no restrictions for the kind of Lua functions that can be called +from the callback — no checks for the proper number of arguments +are made. The return value of the Lua function will be converted to the +result type and an error will be thrown for invalid conversions. +</p> +<p> +It's allowed to throw errors across a callback invocation, but it's not +advisable in general. Do this only if you know the C function, that +called the callback, copes with the forced stack unwinding and doesn't +leak resources. +</p> +<p> +One thing that's not allowed, is to let an FFI call into a C function +get JIT-compiled, which in turn calls a callback, calling into Lua again. +Usually this attempt is caught by the interpreter first and the +C function is blacklisted for compilation. +</p> +<p> +However, this heuristic may fail under specific circumstances: e.g. a +message polling function might not run Lua callbacks right away and the call +gets JIT-compiled. If it later happens to call back into Lua (e.g. a rarely +invoked error callback), you'll get a VM PANIC with the message +<tt>"bad callback"</tt>. Then you'll need to manually turn off +JIT-compilation with +<a href="ext_jit.html#jit_onoff_func"><tt>jit.off()</tt></a> for the +surrounding Lua function that invokes such a message polling function (or +similar). +</p> + +<h3 id="callback_resources">Callback resource handling</h3> +<p> +Callbacks take up resources — you can only have a limited number +of them at the same time (500 - 1000, depending on the +architecture). The associated Lua functions are anchored to prevent +garbage collection, too. +</p> +<p> +<b>Callbacks due to implicit conversions are permanent!</b> There is no +way to guess their lifetime, since the C side might store the +function pointer for later use (typical for GUI toolkits). The associated +resources cannot be reclaimed until termination: +</p> +<pre class="code"> +ffi.cdef[[ +typedef int (__stdcall *WNDENUMPROC)(void *hwnd, intptr_t l); +int EnumWindows(WNDENUMPROC func, intptr_t l); +]] + +-- Implicit conversion to a callback via function pointer argument. +local count = 0 +ffi.C.EnumWindows(function(hwnd, l) + count = count + 1 + return true +end, 0) +-- The callback is permanent and its resources cannot be reclaimed! +-- Ok, so this may not be a problem, if you do this only once. +</pre> +<p> +Note: this example shows that you <em>must</em> properly declare +<tt>__stdcall</tt> callbacks on Windows/x86 systems. The calling +convention cannot be automatically detected, unlike for +<tt>__stdcall</tt> calls <em>to</em> Windows functions. +</p> +<p> +For some use cases it's necessary to free up the resources or to +dynamically redirect callbacks. Use an explicit cast to a +C function pointer and keep the resulting cdata object. Then use +the <a href="ext_ffi_api.html#callback_free"><tt>cb:free()</tt></a> +or <a href="ext_ffi_api.html#callback_set"><tt>cb:set()</tt></a> methods +on the cdata object: +</p> +<pre class="code"> +-- Explicitly convert to a callback via cast. +local count = 0 +local cb = ffi.cast("WNDENUMPROC", function(hwnd, l) + count = count + 1 + return true +end) + +-- Pass it to a C function. +ffi.C.EnumWindows(cb, 0) +-- EnumWindows doesn't need the callback after it returns, so free it. + +cb:free() +-- The callback function pointer is no longer valid and its resources +-- will be reclaimed. The created Lua closure will be garbage collected. +</pre> + +<h3 id="callback_performance">Callback performance</h3> +<p> +<b>Callbacks are slow!</b> First, the C to Lua transition itself +has an unavoidable cost, similar to a <tt>lua_call()</tt> or +<tt>lua_pcall()</tt>. Argument and result marshalling add to that cost. +And finally, neither the C compiler nor LuaJIT can inline or +optimize across the language barrier and hoist repeated computations out +of a callback function. +</p> +<p> +Do not use callbacks for performance-sensitive work: e.g. consider a +numerical integration routine which takes a user-defined function to +integrate over. It's a bad idea to call a user-defined Lua function from +C code millions of times. The callback overhead will be absolutely +detrimental for performance. +</p> +<p> +It's considerably faster to write the numerical integration routine +itself in Lua — the JIT compiler will be able to inline the +user-defined function and optimize it together with its calling context, +with very competitive performance. +</p> +<p> +As a general guideline: <b>use callbacks only when you must</b>, because +of existing C APIs. E.g. callback performance is irrelevant for a +GUI application, which waits for user input most of the time, anyway. +</p> +<p> +For new designs <b>avoid push-style APIs</b>: a C function repeatedly +calling a callback for each result. Instead <b>use pull-style APIs</b>: +call a C function repeatedly to get a new result. Calls from Lua +to C via the FFI are much faster than the other way round. Most well-designed +libraries already use pull-style APIs (read/write, get/put). +</p> + +<h2 id="clib">C Library Namespaces</h2> +<p> +A C library namespace is a special kind of object which allows +access to the symbols contained in shared libraries or the default +symbol namespace. The default +<a href="ext_ffi_api.html#ffi_C"><tt>ffi.C</tt></a> namespace is +automatically created when the FFI library is loaded. C library +namespaces for specific shared libraries may be created with the +<a href="ext_ffi_api.html#ffi_load"><tt>ffi.load()</tt></a> API +function. +</p> +<p> +Indexing a C library namespace object with a symbol name (a Lua +string) automatically binds it to the library. First the symbol type +is resolved — it must have been declared with +<a href="ext_ffi_api.html#ffi_cdef"><tt>ffi.cdef</tt></a>. Then the +symbol address is resolved by searching for the symbol name in the +associated shared libraries or the default symbol namespace. Finally, +the resulting binding between the symbol name, the symbol type and its +address is cached. Missing symbol declarations or nonexistent symbol +names cause an error. +</p> +<p> +This is what happens on a <b>read access</b> for the different kinds of +symbols: +</p> +<ul> + +<li>External functions: a cdata object with the type of the function +and its address is returned.</li> + +<li>External variables: the symbol address is dereferenced and the +loaded value is <a href="#convert_tolua">converted to a Lua object</a> +and returned.</li> + +<li>Constant values (<tt>static const</tt> or <tt>enum</tt> +constants): the constant is <a href="#convert_tolua">converted to a +Lua object</a> and returned.</li> + +</ul> +<p> +This is what happens on a <b>write access</b>: +</p> +<ul> + +<li>External variables: the value to be written is +<a href="#convert_fromlua">converted to the C type</a> of the +variable and then stored at the symbol address.</li> + +<li>Writing to constant variables or to any other symbol type causes +an error, like any other attempted write to a constant location.</li> + +</ul> +<p> +C library namespaces themselves are garbage collected objects. If +the last reference to the namespace object is gone, the garbage +collector will eventually release the shared library reference and +remove all memory associated with the namespace. Since this may +trigger the removal of the shared library from the memory of the +running process, it's generally <em>not safe</em> to use function +cdata objects obtained from a library if the namespace object may be +unreferenced. +</p> +<p> +Performance notice: the JIT compiler specializes to the identity of +namespace objects and to the strings used to index it. This +effectively turns function cdata objects into constants. It's not +useful and actually counter-productive to explicitly cache these +function objects, e.g. <tt>local strlen = ffi.C.strlen</tt>. OTOH it +<em>is</em> useful to cache the namespace itself, e.g. <tt>local C = +ffi.C</tt>. +</p> + +<h2 id="policy">No Hand-holding!</h2> +<p> +The FFI library has been designed as <b>a low-level library</b>. The +goal is to interface with C code and C data types with a +minimum of overhead. This means <b>you can do anything you can do +from C</b>: access all memory, overwrite anything in memory, call +machine code at any memory address and so on. +</p> +<p> +The FFI library provides <b>no memory safety</b>, unlike regular Lua +code. It will happily allow you to dereference a <tt>NULL</tt> +pointer, to access arrays out of bounds or to misdeclare +C functions. If you make a mistake, your application might crash, +just like equivalent C code would. +</p> +<p> +This behavior is inevitable, since the goal is to provide full +interoperability with C code. Adding extra safety measures, like +bounds checks, would be futile. There's no way to detect +misdeclarations of C functions, since shared libraries only +provide symbol names, but no type information. Likewise there's no way +to infer the valid range of indexes for a returned pointer. +</p> +<p> +Again: the FFI library is a low-level library. This implies it needs +to be used with care, but it's flexibility and performance often +outweigh this concern. If you're a C or C++ developer, it'll be easy +to apply your existing knowledge. OTOH writing code for the FFI +library is not for the faint of heart and probably shouldn't be the +first exercise for someone with little experience in Lua, C or C++. +</p> +<p> +As a corollary of the above, the FFI library is <b>not safe for use by +untrusted Lua code</b>. If you're sandboxing untrusted Lua code, you +definitely don't want to give this code access to the FFI library or +to <em>any</em> cdata object (except 64 bit integers or complex +numbers). Any properly engineered Lua sandbox needs to provide safety +wrappers for many of the standard Lua library functions — +similar wrappers need to be written for high-level operations on FFI +data types, too. +</p> + +<h2 id="status">Current Status</h2> +<p> +The initial release of the FFI library has some limitations and is +missing some features. Most of these will be fixed in future releases. +</p> +<p> +<a href="#clang">C language support</a> is +currently incomplete: +</p> +<ul> +<li>C declarations are not passed through a C pre-processor, +yet.</li> +<li>The C parser is able to evaluate most constant expressions +commonly found in C header files. However it doesn't handle the +full range of C expression semantics and may fail for some +obscure constructs.</li> +<li><tt>static const</tt> declarations only work for integer types +up to 32 bits. Neither declaring string constants nor +floating-point constants is supported.</li> +<li>Packed <tt>struct</tt> bitfields that cross container boundaries +are not implemented.</li> +<li>Native vector types may be defined with the GCC <tt>mode</tt> or +<tt>vector_size</tt> attribute. But no operations other than loading, +storing and initializing them are supported, yet.</li> +<li>The <tt>volatile</tt> type qualifier is currently ignored by +compiled code.</li> +<li><a href="ext_ffi_api.html#ffi_cdef"><tt>ffi.cdef</tt></a> silently +ignores most re-declarations. Note: avoid re-declarations which do not +conform to C99. The implementation will eventually be changed to +perform strict checks.</li> +</ul> +<p> +The JIT compiler already handles a large subset of all FFI operations. +It automatically falls back to the interpreter for unimplemented +operations (you can check for this with the +<a href="running.html#opt_j"><tt>-jv</tt></a> command line option). +The following operations are currently not compiled and may exhibit +suboptimal performance, especially when used in inner loops: +</p> +<ul> +<li>Bitfield accesses and initializations.</li> +<li>Vector operations.</li> +<li>Table initializers.</li> +<li>Initialization of nested <tt>struct</tt>/<tt>union</tt> types.</li> +<li>Non-default initialization of VLA/VLS or large C types +(> 128 bytes or > 16 array elements.</li> +<li>Conversions from lightuserdata to <tt>void *</tt>.</li> +<li>Pointer differences for element sizes that are not a power of +two.</li> +<li>Calls to C functions with aggregates passed or returned by +value.</li> +<li>Calls to ctype metamethods which are not plain functions.</li> +<li>ctype <tt>__newindex</tt> tables and non-string lookups in ctype +<tt>__index</tt> tables.</li> +<li><tt>tostring()</tt> for cdata types.</li> +<li>Calls to <tt>ffi.cdef()</tt>, <tt>ffi.load()</tt> and +<tt>ffi.metatype()</tt>.</li> +</ul> +<p> +Other missing features: +</p> +<ul> +<li>Arithmetic for <tt>complex</tt> numbers.</li> +<li>Passing structs by value to vararg C functions.</li> +<li><a href="extensions.html#exceptions">C++ exception interoperability</a> +does not extend to C functions called via the FFI, if the call is +compiled.</li> +</ul> +<br class="flush"> +</div> +<div id="foot"> +<hr class="hide"> +Copyright © 2005-2016 Mike Pall +<span class="noprint"> +· +<a href="contact.html">Contact</a> +</span> +</div> +</body> +</html> diff --git a/Build/source/libs/luajit/LuaJIT-src/doc/ext_ffi_tutorial.html b/Build/source/libs/luajit/LuaJIT-src/doc/ext_ffi_tutorial.html index a624e6fd6e6..01200c45c11 100644 --- a/Build/source/libs/luajit/LuaJIT-src/doc/ext_ffi_tutorial.html +++ b/Build/source/libs/luajit/LuaJIT-src/doc/ext_ffi_tutorial.html @@ -1,603 +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-2015, 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-2015 Mike Pall
-<span class="noprint">
-·
-<a href="contact.html">Contact</a>
-</span>
-</div>
-</body>
-</html>
+<!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-2016, 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-2016 Mike Pall +<span class="noprint"> +· +<a href="contact.html">Contact</a> +</span> +</div> +</body> +</html> diff --git a/Build/source/libs/luajit/LuaJIT-src/doc/ext_jit.html b/Build/source/libs/luajit/LuaJIT-src/doc/ext_jit.html index 79c9f1f0085..9489c6f5cfb 100644 --- a/Build/source/libs/luajit/LuaJIT-src/doc/ext_jit.html +++ b/Build/source/libs/luajit/LuaJIT-src/doc/ext_jit.html @@ -1,201 +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-2015, 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", "ppc", or "mips".
-</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-2015 Mike Pall
-<span class="noprint">
-·
-<a href="contact.html">Contact</a>
-</span>
-</div>
-</body>
-</html>
+<!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-2016, 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", "ppc", or "mips". +</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-2016 Mike Pall +<span class="noprint"> +· +<a href="contact.html">Contact</a> +</span> +</div> +</body> +</html> diff --git a/Build/source/libs/luajit/LuaJIT-src/doc/ext_profiler.html b/Build/source/libs/luajit/LuaJIT-src/doc/ext_profiler.html index c435bb3090a..69ea25dbeba 100644 --- a/Build/source/libs/luajit/LuaJIT-src/doc/ext_profiler.html +++ b/Build/source/libs/luajit/LuaJIT-src/doc/ext_profiler.html @@ -1,365 +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-2015, 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-2015 Mike Pall
-<span class="noprint">
-·
-<a href="contact.html">Contact</a>
-</span>
-</div>
-</body>
-</html>
+<!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-2016, 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-2016 Mike Pall +<span class="noprint"> +· +<a href="contact.html">Contact</a> +</span> +</div> +</body> +</html> diff --git a/Build/source/libs/luajit/LuaJIT-src/doc/extensions.html b/Build/source/libs/luajit/LuaJIT-src/doc/extensions.html index 51d02fca89f..7f712a62144 100644 --- a/Build/source/libs/luajit/LuaJIT-src/doc/extensions.html +++ b/Build/source/libs/luajit/LuaJIT-src/doc/extensions.html @@ -1,448 +1,455 @@ -<!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-2015, 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). 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><tt>string.rep(s, n [,sep])</tt>.
-<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>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>.
-</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="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+</td>
-<td class="excinterop"><b style="color: #00a000;">Full</b></td>
-</tr>
-<tr class="even">
-<td class="excplatform">Other platforms, DWARF2 unwinding</td>
-<td class="exccompiler">GCC</td>
-<td class="excinterop"><b style="color: #c06000;">Limited</b></td>
-</tr>
-<tr class="odd">
-<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="even">
-<td class="excplatform">Windows/x86</td>
-<td class="exccompiler">Any</td>
-<td class="excinterop"><b style="color: #a00000;">No</b></td>
-</tr>
-<tr class="odd">
-<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>
-<li>Additionally, on Windows/x86 with SEH-based C++ exceptions:
-it's <b>not</b> safe to throw a Lua error across any frames containing
-a C++ function with any try/catch construct or using variables with
-(implicit) destructors. This also applies to any functions which may be
-inlined in such a function. It doesn't matter whether <tt>lua_error()</tt>
-is called inside or outside of a try/catch or whether any object actually
-needs to be destroyed: the SEH chain is corrupted and this will eventually
-lead to the termination of the process.</li>
-</ul>
-<br class="flush">
-</div>
-<div id="foot">
-<hr class="hide">
-Copyright © 2005-2015 Mike Pall
-<span class="noprint">
-·
-<a href="contact.html">Contact</a>
-</span>
-</div>
-</body>
-</html>
+<!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-2016, 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). 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><tt>string.rep(s, n [,sep])</tt>. +<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>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>. +</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> +</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+</td> +<td class="excinterop"><b style="color: #00a000;">Full</b></td> +</tr> +<tr class="even"> +<td class="excplatform">Other platforms, DWARF2 unwinding</td> +<td class="exccompiler">GCC</td> +<td class="excinterop"><b style="color: #c06000;">Limited</b></td> +</tr> +<tr class="odd"> +<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="even"> +<td class="excplatform">Windows/x86</td> +<td class="exccompiler">Any</td> +<td class="excinterop"><b style="color: #a00000;">No</b></td> +</tr> +<tr class="odd"> +<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> +<li>Additionally, on Windows/x86 with SEH-based C++ exceptions: +it's <b>not</b> safe to throw a Lua error across any frames containing +a C++ function with any try/catch construct or using variables with +(implicit) destructors. This also applies to any functions which may be +inlined in such a function. It doesn't matter whether <tt>lua_error()</tt> +is called inside or outside of a try/catch or whether any object actually +needs to be destroyed: the SEH chain is corrupted and this will eventually +lead to the termination of the process.</li> +</ul> +<br class="flush"> +</div> +<div id="foot"> +<hr class="hide"> +Copyright © 2005-2016 Mike Pall +<span class="noprint"> +· +<a href="contact.html">Contact</a> +</span> +</div> +</body> +</html> diff --git a/Build/source/libs/luajit/LuaJIT-src/doc/faq.html b/Build/source/libs/luajit/LuaJIT-src/doc/faq.html index 106dbd03727..605fdd0a2ce 100644 --- a/Build/source/libs/luajit/LuaJIT-src/doc/faq.html +++ b/Build/source/libs/luajit/LuaJIT-src/doc/faq.html @@ -1,186 +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-2015, 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-2015 Mike Pall
-<span class="noprint">
-·
-<a href="contact.html">Contact</a>
-</span>
-</div>
-</body>
-</html>
+<!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-2016, 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-2016 Mike Pall +<span class="noprint"> +· +<a href="contact.html">Contact</a> +</span> +</div> +</body> +</html> diff --git a/Build/source/libs/luajit/LuaJIT-src/doc/install.html b/Build/source/libs/luajit/LuaJIT-src/doc/install.html index 39539e4607d..dba63fd868d 100644 --- a/Build/source/libs/luajit/LuaJIT-src/doc/install.html +++ b/Build/source/libs/luajit/LuaJIT-src/doc/install.html @@ -1,659 +1,663 @@ -<!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-2015, 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.x<br>GCC 3.4</td>
-<td class="compatos">GCC 4.x<br>GCC 3.4</td>
-<td class="compatos">GCC 4.x<br>GCC 3.4</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.x</td>
-<td class="compatos">ORBIS (<a href="#ps4">PS4</a>)</td>
-<td class="compatos">GCC 4.x</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">GCC 4.2+</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">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">MIPS</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>
-
-<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.4.tar.gz
-cd LuaJIT-2.0.4</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 x86, x64 or PPC 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>
-The GNU Makefile-based build system allows cross-compiling on any host
-for any supported target, as long as both architectures have the same
-pointer size. If you want to cross-compile to any 32 bit target on an
-x64 OS, 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>).
-</p>
-<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. 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. 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>. The examples
-below only show some popular targets — please check the comments
-in <tt>src/Makefile</tt> for more details.
-</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. You
-can specify these when building the toolchain yourself. Or add
-<tt>-mcpu=...</tt> or <tt>-march=...</tt> to <tt>TARGET_CFLAGS</tt>. 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.
-</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-A8)
-make HOST_CC="gcc -m32" CROSS=arm-linux-gnueabi- \
- TARGET_CFLAGS="-mcpu=cortex-a8 -mfloat-abi=softfp"
-
-# ARM hard-float ABI with VFP (armhf, requires recent toolchain)
-make HOST_CC="gcc -m32" CROSS=arm-linux-gnueabihf-
-
-# ARM64 (requires x64 host)
-make CROSS=aarch64-linux-
-
-# PPC
-make HOST_CC="gcc -m32" CROSS=powerpc-linux-gnu-
-
-# MIPS big-endian
-make HOST_CC="gcc -m32" CROSS=mips-linux-
-# MIPS little-endian
-make HOST_CC="gcc -m32" CROSS=mipsel-linux-
-</pre>
-<p>
-You can cross-compile for <b id="android">Android</b> using the <a href="http://developer.android.com/sdk/ndk/index.html"><span class="ext">»</span> 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.6
-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.6
-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, mips (MIPS32R1 hard-float), Android 4.0+ (ICS)
-NDK=/opt/android/ndk
-NDKABI=14
-NDKVER=$NDK/toolchains/mipsel-linux-android-4.6
-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.6
-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>.
-The environment variables need to match the iOS SDK version:
-</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">
-IXCODE=`xcode-select -print-path`
-ISDK=$IXCODE/Platforms/iPhoneOS.platform/Developer
-ISDKVER=iPhoneOS6.0.sdk
-ISDKP=$ISDK/usr/bin/
-ISDKF="-arch armv7 -isysroot $ISDK/SDKs/$ISDKVER"
-make HOST_CC="gcc -m32 -arch i386" CROSS=$ISDKP 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, you need to link your main executable
-with these flags:
-<pre class="code">
--pagezero_size 10000 -image_base 100000000
-</pre>
-Also, it's recommended to <tt>rebase</tt> all (self-compiled) shared libraries
-which are loaded at runtime on OSX/x64 (e.g. C extension modules for Lua).
-See: <tt>man rebase</tt>
-</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-2015 Mike Pall
-<span class="noprint">
-·
-<a href="contact.html">Contact</a>
-</span>
-</div>
-</body>
-</html>
+<!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-2016, 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">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">MIPS</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> + +<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.4.tar.gz +cd LuaJIT-2.0.4</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 x86, x64 or PPC 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> +The GNU Makefile-based build system allows cross-compiling on any host +for any supported target, as long as both architectures have the same +pointer size. If you want to cross-compile to any 32 bit target on an +x64 OS, 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>). +</p> +<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. 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. 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>. The examples +below only show some popular targets — please check the comments +in <tt>src/Makefile</tt> for more details. +</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. You +can specify these when building the toolchain yourself. Or add +<tt>-mcpu=...</tt> or <tt>-march=...</tt> to <tt>TARGET_CFLAGS</tt>. 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. +</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-A8) +make HOST_CC="gcc -m32" CROSS=arm-linux-gnueabi- \ + TARGET_CFLAGS="-mcpu=cortex-a8 -mfloat-abi=softfp" + +# ARM hard-float ABI with VFP (armhf, requires recent toolchain) +make HOST_CC="gcc -m32" CROSS=arm-linux-gnueabihf- + +# ARM64 (requires x64 host) +make CROSS=aarch64-linux- + +# PPC +make HOST_CC="gcc -m32" CROSS=powerpc-linux-gnu- + +# MIPS big-endian +make HOST_CC="gcc -m32" CROSS=mips-linux- +# MIPS little-endian +make HOST_CC="gcc -m32" CROSS=mipsel-linux- +</pre> +<p> +You can cross-compile for <b id="android">Android</b> using the <a href="http://developer.android.com/sdk/ndk/index.html"><span class="ext">»</span> 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.6 +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.6 +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, mips (MIPS32R1 hard-float), Android 4.0+ (ICS) +NDK=/opt/android/ndk +NDKABI=14 +NDKVER=$NDK/toolchains/mipsel-linux-android-4.6 +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.6 +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 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 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, you need to link your main executable +with these flags: +<pre class="code"> +-pagezero_size 10000 -image_base 100000000 +</pre> +Also, it's recommended to <tt>rebase</tt> all (self-compiled) shared libraries +which are loaded at runtime on OSX/x64 (e.g. C extension modules for Lua). +See: <tt>man rebase</tt> +</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-2016 Mike Pall +<span class="noprint"> +· +<a href="contact.html">Contact</a> +</span> +</div> +</body> +</html> diff --git a/Build/source/libs/luajit/LuaJIT-src/doc/luajit.html b/Build/source/libs/luajit/LuaJIT-src/doc/luajit.html index bee0f62a1d0..c7a92b86cdc 100644 --- a/Build/source/libs/luajit/LuaJIT-src/doc/luajit.html +++ b/Build/source/libs/luajit/LuaJIT-src/doc/luajit.html @@ -1,236 +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-2015, 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-2015 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</td><td>x64</td><td>ARM</td><td>ARM64</td><td>PPC</td><td>MIPS</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-2015 Mike Pall
-<span class="noprint">
-·
-<a href="contact.html">Contact</a>
-</span>
-</div>
-</body>
-</html>
+<!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-2016, 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-2016 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</td><td>x64</td><td>ARM</td><td>ARM64</td><td>PPC</td><td>MIPS</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-2016 Mike Pall +<span class="noprint"> +· +<a href="contact.html">Contact</a> +</span> +</div> +</body> +</html> diff --git a/Build/source/libs/luajit/LuaJIT-src/doc/running.html b/Build/source/libs/luajit/LuaJIT-src/doc/running.html index 353b542b6c2..28a732641b8 100644 --- a/Build/source/libs/luajit/LuaJIT-src/doc/running.html +++ b/Build/source/libs/luajit/LuaJIT-src/doc/running.html @@ -1,309 +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-2015, 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.4/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-2015 Mike Pall
-<span class="noprint">
-·
-<a href="contact.html">Contact</a>
-</span>
-</div>
-</body>
-</html>
+<!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-2016, 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.4/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-2016 Mike Pall +<span class="noprint"> +· +<a href="contact.html">Contact</a> +</span> +</div> +</body> +</html> diff --git a/Build/source/libs/luajit/LuaJIT-src/doc/status.html b/Build/source/libs/luajit/LuaJIT-src/doc/status.html index 9ffa65fefad..6f57db1bb97 100644 --- a/Build/source/libs/luajit/LuaJIT-src/doc/status.html +++ b/Build/source/libs/luajit/LuaJIT-src/doc/status.html @@ -1,118 +1,118 @@ -<!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-2015, 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>
-Some checks are missing in the JIT-compiled code for obscure situations
-with <b>open upvalues aliasing</b> one of the SSA slots later on (or
-vice versa). Bonus points, if you can find a real world test case for
-this.
-</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>
-</ul>
-<br class="flush">
-</div>
-<div id="foot">
-<hr class="hide">
-Copyright © 2005-2015 Mike Pall
-<span class="noprint">
-·
-<a href="contact.html">Contact</a>
-</span>
-</div>
-</body>
-</html>
+<!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-2016, 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> +Some checks are missing in the JIT-compiled code for obscure situations +with <b>open upvalues aliasing</b> one of the SSA slots later on (or +vice versa). Bonus points, if you can find a real world test case for +this. +</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> +</ul> +<br class="flush"> +</div> +<div id="foot"> +<hr class="hide"> +Copyright © 2005-2016 Mike Pall +<span class="noprint"> +· +<a href="contact.html">Contact</a> +</span> +</div> +</body> +</html> diff --git a/Build/source/libs/luajit/LuaJIT-src/dynasm/dasm_arm.h b/Build/source/libs/luajit/LuaJIT-src/dynasm/dasm_arm.h index 57e0116f5ac..0fa69ac06f9 100644 --- a/Build/source/libs/luajit/LuaJIT-src/dynasm/dasm_arm.h +++ b/Build/source/libs/luajit/LuaJIT-src/dynasm/dasm_arm.h @@ -1,6 +1,6 @@ /* ** DynASM ARM encoding engine. -** Copyright (C) 2005-2015 Mike Pall. All rights reserved. +** Copyright (C) 2005-2016 Mike Pall. All rights reserved. ** Released under the MIT license. See dynasm.lua for full copyright notice. */ diff --git a/Build/source/libs/luajit/LuaJIT-src/dynasm/dasm_arm.lua b/Build/source/libs/luajit/LuaJIT-src/dynasm/dasm_arm.lua index 90a259c5c33..e2ed922a3c6 100644 --- a/Build/source/libs/luajit/LuaJIT-src/dynasm/dasm_arm.lua +++ b/Build/source/libs/luajit/LuaJIT-src/dynasm/dasm_arm.lua @@ -1,7 +1,7 @@ ------------------------------------------------------------------------------ -- DynASM ARM module. -- --- Copyright (C) 2005-2015 Mike Pall. All rights reserved. +-- Copyright (C) 2005-2016 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", } diff --git a/Build/source/libs/luajit/LuaJIT-src/dynasm/dasm_arm64.h b/Build/source/libs/luajit/LuaJIT-src/dynasm/dasm_arm64.h index d912e61dda7..d64e60a3e6e 100644 --- a/Build/source/libs/luajit/LuaJIT-src/dynasm/dasm_arm64.h +++ b/Build/source/libs/luajit/LuaJIT-src/dynasm/dasm_arm64.h @@ -1,6 +1,6 @@ /* ** DynASM ARM64 encoding engine. -** Copyright (C) 2005-2015 Mike Pall. All rights reserved. +** Copyright (C) 2005-2016 Mike Pall. All rights reserved. ** Released under the MIT license. See dynasm.lua for full copyright notice. */ diff --git a/Build/source/libs/luajit/LuaJIT-src/dynasm/dasm_arm64.lua b/Build/source/libs/luajit/LuaJIT-src/dynasm/dasm_arm64.lua index 9766e475b0f..4a7d8dfeeb5 100644 --- a/Build/source/libs/luajit/LuaJIT-src/dynasm/dasm_arm64.lua +++ b/Build/source/libs/luajit/LuaJIT-src/dynasm/dasm_arm64.lua @@ -1,7 +1,7 @@ ------------------------------------------------------------------------------ -- DynASM ARM64 module. -- --- Copyright (C) 2005-2015 Mike Pall. All rights reserved. +-- Copyright (C) 2005-2016 Mike Pall. All rights reserved. -- See dynasm.lua for full copyright notice. ------------------------------------------------------------------------------ @@ -9,9 +9,9 @@ local _info = { arch = "arm", description = "DynASM ARM64 module", - version = "1.3.0", - vernum = 10300, - release = "2014-12-03", + version = "1.4.0", + vernum = 10400, + release = "2015-10-18", author = "Mike Pall", license = "MIT", } diff --git a/Build/source/libs/luajit/LuaJIT-src/dynasm/dasm_mips.h b/Build/source/libs/luajit/LuaJIT-src/dynasm/dasm_mips.h index 2f4c2d2220a..c10528fab98 100644 --- a/Build/source/libs/luajit/LuaJIT-src/dynasm/dasm_mips.h +++ b/Build/source/libs/luajit/LuaJIT-src/dynasm/dasm_mips.h @@ -1,6 +1,6 @@ /* ** DynASM MIPS encoding engine. -** Copyright (C) 2005-2015 Mike Pall. All rights reserved. +** Copyright (C) 2005-2016 Mike Pall. All rights reserved. ** Released under the MIT license. See dynasm.lua for full copyright notice. */ diff --git a/Build/source/libs/luajit/LuaJIT-src/dynasm/dasm_mips.lua b/Build/source/libs/luajit/LuaJIT-src/dynasm/dasm_mips.lua index ae0dbd7a9bc..c5a5595c1aa 100644 --- a/Build/source/libs/luajit/LuaJIT-src/dynasm/dasm_mips.lua +++ b/Build/source/libs/luajit/LuaJIT-src/dynasm/dasm_mips.lua @@ -1,7 +1,7 @@ ------------------------------------------------------------------------------ -- DynASM MIPS module. -- --- Copyright (C) 2005-2015 Mike Pall. All rights reserved. +-- Copyright (C) 2005-2016 Mike Pall. All rights reserved. -- See dynasm.lua for full copyright notice. ------------------------------------------------------------------------------ @@ -9,9 +9,9 @@ local _info = { arch = "mips", description = "DynASM MIPS module", - version = "1.3.0", - vernum = 10300, - release = "2012-01-23", + version = "1.4.0", + vernum = 10400, + release = "2015-10-18", author = "Mike Pall", license = "MIT", } diff --git a/Build/source/libs/luajit/LuaJIT-src/dynasm/dasm_ppc.h b/Build/source/libs/luajit/LuaJIT-src/dynasm/dasm_ppc.h index 332c64dc68a..3f267fb8240 100644 --- a/Build/source/libs/luajit/LuaJIT-src/dynasm/dasm_ppc.h +++ b/Build/source/libs/luajit/LuaJIT-src/dynasm/dasm_ppc.h @@ -1,6 +1,6 @@ /* ** DynASM PPC/PPC64 encoding engine. -** Copyright (C) 2005-2015 Mike Pall. All rights reserved. +** Copyright (C) 2005-2016 Mike Pall. All rights reserved. ** Released under the MIT license. See dynasm.lua for full copyright notice. */ diff --git a/Build/source/libs/luajit/LuaJIT-src/dynasm/dasm_ppc.lua b/Build/source/libs/luajit/LuaJIT-src/dynasm/dasm_ppc.lua index 278f09526dd..e2f704ec18a 100644 --- a/Build/source/libs/luajit/LuaJIT-src/dynasm/dasm_ppc.lua +++ b/Build/source/libs/luajit/LuaJIT-src/dynasm/dasm_ppc.lua @@ -1,7 +1,7 @@ ------------------------------------------------------------------------------ -- DynASM PPC/PPC64 module. -- --- Copyright (C) 2005-2015 Mike Pall. All rights reserved. +-- Copyright (C) 2005-2016 Mike Pall. All rights reserved. -- See dynasm.lua for full copyright notice. -- -- Support for various extensions contributed by Caio Souza Oliveira. @@ -11,9 +11,9 @@ local _info = { arch = "ppc", description = "DynASM PPC module", - version = "1.3.0", - vernum = 10300, - release = "2015-01-14", + version = "1.4.0", + vernum = 10400, + release = "2015-10-18", author = "Mike Pall", license = "MIT", } diff --git a/Build/source/libs/luajit/LuaJIT-src/dynasm/dasm_proto.h b/Build/source/libs/luajit/LuaJIT-src/dynasm/dasm_proto.h index a8bc6fd285d..22a654cbfd9 100644 --- a/Build/source/libs/luajit/LuaJIT-src/dynasm/dasm_proto.h +++ b/Build/source/libs/luajit/LuaJIT-src/dynasm/dasm_proto.h @@ -1,6 +1,6 @@ /* ** DynASM encoding engine prototypes. -** Copyright (C) 2005-2015 Mike Pall. All rights reserved. +** Copyright (C) 2005-2016 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 diff --git a/Build/source/libs/luajit/LuaJIT-src/dynasm/dasm_x64.lua b/Build/source/libs/luajit/LuaJIT-src/dynasm/dasm_x64.lua index b1b62022f3c..2133355644f 100644 --- a/Build/source/libs/luajit/LuaJIT-src/dynasm/dasm_x64.lua +++ b/Build/source/libs/luajit/LuaJIT-src/dynasm/dasm_x64.lua @@ -1,7 +1,7 @@ ------------------------------------------------------------------------------ -- DynASM x64 module. -- --- Copyright (C) 2005-2015 Mike Pall. All rights reserved. +-- Copyright (C) 2005-2016 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. diff --git a/Build/source/libs/luajit/LuaJIT-src/dynasm/dasm_x86.h b/Build/source/libs/luajit/LuaJIT-src/dynasm/dasm_x86.h index 652e8c99b08..bf5b729633b 100644 --- a/Build/source/libs/luajit/LuaJIT-src/dynasm/dasm_x86.h +++ b/Build/source/libs/luajit/LuaJIT-src/dynasm/dasm_x86.h @@ -1,6 +1,6 @@ /* ** DynASM x86 encoding engine. -** Copyright (C) 2005-2015 Mike Pall. All rights reserved. +** Copyright (C) 2005-2016 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 */ diff --git a/Build/source/libs/luajit/LuaJIT-src/dynasm/dasm_x86.lua b/Build/source/libs/luajit/LuaJIT-src/dynasm/dasm_x86.lua index 7ca061d22f6..1f21a2673cc 100644 --- a/Build/source/libs/luajit/LuaJIT-src/dynasm/dasm_x86.lua +++ b/Build/source/libs/luajit/LuaJIT-src/dynasm/dasm_x86.lua @@ -1,7 +1,7 @@ ------------------------------------------------------------------------------ -- DynASM x86/x64 module. -- --- Copyright (C) 2005-2015 Mike Pall. All rights reserved. +-- Copyright (C) 2005-2016 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,238 @@ 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", } ------------------------------------------------------------------------------ @@ -1462,28 +1723,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 +1788,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 +1813,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 +1885,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 +1969,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 +2041,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 diff --git a/Build/source/libs/luajit/LuaJIT-src/dynasm/dynasm.lua b/Build/source/libs/luajit/LuaJIT-src/dynasm/dynasm.lua index fffda7513c8..1e5899a4bf0 100644 --- a/Build/source/libs/luajit/LuaJIT-src/dynasm/dynasm.lua +++ b/Build/source/libs/luajit/LuaJIT-src/dynasm/dynasm.lua @@ -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-2016 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-2016 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 diff --git a/Build/source/libs/luajit/LuaJIT-src/etc/luajit.1 b/Build/source/libs/luajit/LuaJIT-src/etc/luajit.1 index 223a0283755..11e88c04481 100644 --- a/Build/source/libs/luajit/LuaJIT-src/etc/luajit.1 +++ b/Build/source/libs/luajit/LuaJIT-src/etc/luajit.1 @@ -1,88 +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-2015 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)
+.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-2016 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) diff --git a/Build/source/libs/luajit/LuaJIT-src/etc/luajit.pc b/Build/source/libs/luajit/LuaJIT-src/etc/luajit.pc index b9ccdf59ea0..0fdd1efd9b0 100644 --- a/Build/source/libs/luajit/LuaJIT-src/etc/luajit.pc +++ b/Build/source/libs/luajit/LuaJIT-src/etc/luajit.pc @@ -1,25 +1,25 @@ -# Package information for LuaJIT to be used by pkg-config.
-majver=2
-minver=1
-relver=0
-version=${majver}.${minver}.${relver}-beta1
-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}
+# Package information for LuaJIT to be used by pkg-config. +majver=2 +minver=1 +relver=0 +version=${majver}.${minver}.${relver}-beta2 +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} diff --git a/Build/source/libs/luajit/LuaJIT-src/src/Makefile b/Build/source/libs/luajit/LuaJIT-src/src/Makefile index 7f86e98ec03..5139ccd2774 100644 --- a/Build/source/libs/luajit/LuaJIT-src/src/Makefile +++ b/Build/source/libs/luajit/LuaJIT-src/src/Makefile @@ -7,7 +7,7 @@ # 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-2016 Mike Pall. See Copyright Notice in luajit.h ############################################################################## MAJVER= 2 @@ -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 @@ -148,6 +150,29 @@ XCFLAGS+= -DLUAJIT_ENABLE_LUA52COMPAT ############################################################################## ############################################################################## +# 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 + # Use Clang for OSX host. + ifeq (Darwin,$(HOST_SYS)) + DEFAULT_CC= clang + endif +endif + +############################################################################## # Flags and options for host and target. ############################################################################## @@ -268,24 +293,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 @@ -378,6 +388,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 @@ -463,7 +478,7 @@ LJLIB_C= $(LJLIB_O:.o=.c) 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_strfmt.o lj_api.o lj_profile.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 \ @@ -612,7 +627,7 @@ $(MINILUA_T): $(MINILUA_O) $(E) "HOSTLINK $@" $(Q)$(HOST_CC) $(HOST_ALDFLAGS) -o $@ $(MINILUA_O) $(MINILUA_LIBS) $(HOST_ALIBS) -host/buildvm_arch.h: $(DASM_DASC) $(DASM_DEP) +host/buildvm_arch.h: $(DASM_DASC) $(DASM_DEP) $(DASM_DIR)/*.lua $(E) "DYNASM $@" $(Q)$(DASM) $(DASM_FLAGS) -o $@ $(DASM_DASC) diff --git a/Build/source/libs/luajit/LuaJIT-src/src/Makefile.dep b/Build/source/libs/luajit/LuaJIT-src/src/Makefile.dep index 34cb53be2ed..7fc5ade4e18 100644 --- a/Build/source/libs/luajit/LuaJIT-src/src/Makefile.dep +++ b/Build/source/libs/luajit/LuaJIT-src/src/Makefile.dep @@ -1,245 +1,247 @@ -lib_aux.o: lib_aux.c lua.h luaconf.h lauxlib.h lj_obj.h lj_def.h \
- lj_arch.h lj_err.h lj_errmsg.h lj_state.h lj_trace.h lj_jit.h lj_ir.h \
- lj_dispatch.h lj_bc.h lj_traceerr.h lj_lib.h lj_alloc.h
-lib_base.o: lib_base.c lua.h luaconf.h lauxlib.h lualib.h lj_obj.h \
- lj_def.h lj_arch.h lj_gc.h lj_err.h lj_errmsg.h lj_debug.h lj_str.h \
- lj_tab.h lj_meta.h lj_state.h lj_ctype.h lj_cconv.h lj_bc.h lj_ff.h \
- lj_ffdef.h lj_dispatch.h lj_jit.h lj_ir.h lj_char.h lj_strscan.h \
- lj_strfmt.h lj_lib.h lj_libdef.h
-lbitlib.o: lbitlib.c lua.h luaconf.h lauxlib.h lualib.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_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 \
- 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_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_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 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_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_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_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_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 \
- 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_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_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_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_tab.h lj_ctype.h lj_cconv.h lj_cdata.h \
- lj_ccall.h lj_trace.h lj_jit.h lj_ir.h lj_dispatch.h lj_bc.h \
- lj_traceerr.h
-lj_ccallback.o: lj_ccallback.c lj_obj.h lua.h luaconf.h lj_def.h \
- lj_arch.h lj_gc.h lj_err.h lj_errmsg.h lj_tab.h lj_state.h lj_frame.h \
- lj_bc.h lj_ctype.h lj_cconv.h lj_ccall.h lj_ccallback.h lj_target.h \
- lj_target_*.h lj_mcode.h lj_jit.h lj_ir.h lj_trace.h lj_dispatch.h \
- lj_traceerr.h lj_vm.h
-lj_cconv.o: lj_cconv.c lj_obj.h lua.h luaconf.h lj_def.h lj_arch.h \
- lj_err.h lj_errmsg.h lj_tab.h lj_ctype.h lj_gc.h lj_cdata.h lj_cconv.h \
- lj_ccallback.h
-lj_cdata.o: lj_cdata.c lj_obj.h lua.h luaconf.h lj_def.h lj_arch.h \
- lj_gc.h lj_err.h lj_errmsg.h lj_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_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_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_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_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_strfmt.h lj_ctype.h \
- lj_ccallback.h
-lj_debug.o: lj_debug.c lj_obj.h lua.h luaconf.h lj_def.h lj_arch.h \
- lj_err.h lj_errmsg.h lj_debug.h lj_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_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 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 \
- lj_ffdef.h lj_ir.h lj_jit.h lj_ircall.h lj_iropt.h lj_trace.h \
- lj_dispatch.h lj_traceerr.h lj_record.h lj_ffrecord.h lj_crecord.h \
- lj_vm.h lj_strscan.h lj_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_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_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_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_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_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_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_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_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_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_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_buf.h lj_gc.h lj_str.h lj_ir.h \
- lj_jit.h lj_ircall.h lj_iropt.h lj_vm.h
-lj_parse.o: lj_parse.c lj_obj.h lua.h luaconf.h lj_def.h lj_arch.h \
- lj_gc.h lj_err.h lj_errmsg.h lj_debug.h lj_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 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_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_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_strscan.o: lj_strscan.c lj_obj.h lua.h luaconf.h lj_def.h lj_arch.h \
- lj_char.h lj_strscan.h
-lj_tab.o: lj_tab.c lj_obj.h lua.h luaconf.h lj_def.h lj_arch.h lj_gc.h \
- lj_err.h lj_errmsg.h lj_tab.h
-lj_trace.o: lj_trace.c lj_obj.h lua.h luaconf.h lj_def.h lj_arch.h \
- lj_gc.h lj_err.h lj_errmsg.h lj_debug.h lj_str.h lj_frame.h lj_bc.h \
- lj_state.h lj_ir.h lj_jit.h lj_iropt.h lj_mcode.h lj_trace.h \
- lj_dispatch.h lj_traceerr.h lj_snap.h lj_gdbjit.h lj_record.h lj_asm.h \
- lj_vm.h lj_vmevent.h lj_target.h lj_target_*.h
-lj_udata.o: lj_udata.c lj_obj.h lua.h luaconf.h lj_def.h lj_arch.h \
- lj_gc.h lj_udata.h
-lj_vmevent.o: lj_vmevent.c lj_obj.h lua.h luaconf.h lj_def.h lj_arch.h \
- lj_str.h lj_tab.h lj_state.h lj_dispatch.h lj_bc.h lj_jit.h lj_ir.h \
- lj_vm.h lj_vmevent.h
-lj_vmmath.o: lj_vmmath.c lj_obj.h lua.h luaconf.h lj_def.h lj_arch.h \
- lj_ir.h lj_vm.h
-ljamalg.o: ljamalg.c lua.h luaconf.h lauxlib.h lj_gc.c lj_obj.h lj_def.h \
- lj_arch.h lj_gc.h lj_err.h lj_errmsg.h lj_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_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 \
- 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_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
+lib_aux.o: lib_aux.c lua.h luaconf.h lauxlib.h lj_obj.h lj_def.h \ + lj_arch.h lj_err.h lj_errmsg.h lj_state.h lj_trace.h lj_jit.h lj_ir.h \ + lj_dispatch.h lj_bc.h lj_traceerr.h lj_lib.h lj_alloc.h +lib_base.o: lib_base.c lua.h luaconf.h lauxlib.h lualib.h lj_obj.h \ + lj_def.h lj_arch.h lj_gc.h lj_err.h lj_errmsg.h lj_debug.h lj_str.h \ + lj_tab.h lj_meta.h lj_state.h lj_ctype.h lj_cconv.h lj_bc.h lj_ff.h \ + lj_ffdef.h lj_dispatch.h lj_jit.h lj_ir.h lj_char.h lj_strscan.h \ + lj_strfmt.h lj_lib.h lj_libdef.h +lbitlib.o: lbitlib.c lua.h luaconf.h lauxlib.h lualib.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_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 \ + 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_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_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 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_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_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_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_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 \ + 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_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_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_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_tab.h lj_ctype.h lj_cconv.h lj_cdata.h \ + lj_ccall.h lj_trace.h lj_jit.h lj_ir.h lj_dispatch.h lj_bc.h \ + lj_traceerr.h +lj_ccallback.o: lj_ccallback.c lj_obj.h lua.h luaconf.h lj_def.h \ + lj_arch.h lj_gc.h lj_err.h lj_errmsg.h lj_tab.h lj_state.h lj_frame.h \ + lj_bc.h lj_ctype.h lj_cconv.h lj_ccall.h lj_ccallback.h lj_target.h \ + lj_target_*.h lj_mcode.h lj_jit.h lj_ir.h lj_trace.h lj_dispatch.h \ + lj_traceerr.h lj_vm.h +lj_cconv.o: lj_cconv.c lj_obj.h lua.h luaconf.h lj_def.h lj_arch.h \ + lj_err.h lj_errmsg.h lj_tab.h lj_ctype.h lj_gc.h lj_cdata.h lj_cconv.h \ + lj_ccallback.h +lj_cdata.o: lj_cdata.c lj_obj.h lua.h luaconf.h lj_def.h lj_arch.h \ + lj_gc.h lj_err.h lj_errmsg.h lj_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_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_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_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_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_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_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_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 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 \ + lj_ffdef.h lj_ir.h lj_jit.h lj_ircall.h lj_iropt.h lj_trace.h \ + lj_dispatch.h lj_traceerr.h lj_record.h lj_ffrecord.h lj_crecord.h \ + lj_vm.h lj_strscan.h lj_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_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_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_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_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_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_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_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_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_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_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_buf.h lj_gc.h lj_str.h lj_ir.h \ + lj_jit.h lj_ircall.h lj_iropt.h lj_vm.h +lj_parse.o: lj_parse.c lj_obj.h lua.h luaconf.h lj_def.h lj_arch.h \ + lj_gc.h lj_err.h lj_errmsg.h lj_debug.h lj_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 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_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_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 \ + lj_err.h lj_errmsg.h lj_tab.h +lj_trace.o: lj_trace.c lj_obj.h lua.h luaconf.h lj_def.h lj_arch.h \ + lj_gc.h lj_err.h lj_errmsg.h lj_debug.h lj_str.h lj_frame.h lj_bc.h \ + lj_state.h lj_ir.h lj_jit.h lj_iropt.h lj_mcode.h lj_trace.h \ + lj_dispatch.h lj_traceerr.h lj_snap.h lj_gdbjit.h lj_record.h lj_asm.h \ + lj_vm.h lj_vmevent.h lj_target.h lj_target_*.h +lj_udata.o: lj_udata.c lj_obj.h lua.h luaconf.h lj_def.h lj_arch.h \ + lj_gc.h lj_udata.h +lj_vmevent.o: lj_vmevent.c lj_obj.h lua.h luaconf.h lj_def.h lj_arch.h \ + lj_str.h lj_tab.h lj_state.h lj_dispatch.h lj_bc.h lj_jit.h lj_ir.h \ + lj_vm.h lj_vmevent.h +lj_vmmath.o: lj_vmmath.c lj_obj.h lua.h luaconf.h lj_def.h lj_arch.h \ + lj_ir.h lj_vm.h +ljamalg.o: ljamalg.c lua.h luaconf.h lauxlib.h lj_gc.c lj_obj.h lj_def.h \ + lj_arch.h lj_gc.h lj_err.h lj_errmsg.h lj_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_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 \ + 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_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 diff --git a/Build/source/libs/luajit/LuaJIT-src/src/host/README b/Build/source/libs/luajit/LuaJIT-src/src/host/README index 78f51a57051..abfcdaa76e9 100644 --- a/Build/source/libs/luajit/LuaJIT-src/src/host/README +++ b/Build/source/libs/luajit/LuaJIT-src/src/host/README @@ -1,4 +1,4 @@ -The files in this directory are only used during the build process of LuaJIT.
-For cross-compilation, they must be executed on the host, not on the target.
-
-These files should NOT be installed!
+The files in this directory are only used during the build process of LuaJIT. +For cross-compilation, they must be executed on the host, not on the target. + +These files should NOT be installed! diff --git a/Build/source/libs/luajit/LuaJIT-src/src/host/buildvm.c b/Build/source/libs/luajit/LuaJIT-src/src/host/buildvm.c index 8584e614d09..3feae49f6fd 100644 --- a/Build/source/libs/luajit/LuaJIT-src/src/host/buildvm.c +++ b/Build/source/libs/luajit/LuaJIT-src/src/host/buildvm.c @@ -1,6 +1,6 @@ /* ** LuaJIT VM builder. -** Copyright (C) 2005-2015 Mike Pall. See Copyright Notice in luajit.h +** Copyright (C) 2005-2016 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 diff --git a/Build/source/libs/luajit/LuaJIT-src/src/host/buildvm.h b/Build/source/libs/luajit/LuaJIT-src/src/host/buildvm.h index 5588555307e..90d21b15f65 100644 --- a/Build/source/libs/luajit/LuaJIT-src/src/host/buildvm.h +++ b/Build/source/libs/luajit/LuaJIT-src/src/host/buildvm.h @@ -1,6 +1,6 @@ /* ** LuaJIT VM builder. -** Copyright (C) 2005-2015 Mike Pall. See Copyright Notice in luajit.h +** Copyright (C) 2005-2016 Mike Pall. See Copyright Notice in luajit.h */ #ifndef _BUILDVM_H diff --git a/Build/source/libs/luajit/LuaJIT-src/src/host/buildvm_asm.c b/Build/source/libs/luajit/LuaJIT-src/src/host/buildvm_asm.c index 9b7ae53a26a..28419c077a4 100644 --- a/Build/source/libs/luajit/LuaJIT-src/src/host/buildvm_asm.c +++ b/Build/source/libs/luajit/LuaJIT-src/src/host/buildvm_asm.c @@ -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-2016 Mike Pall. See Copyright Notice in luajit.h */ #include "buildvm.h" @@ -261,11 +261,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 diff --git a/Build/source/libs/luajit/LuaJIT-src/src/host/buildvm_fold.c b/Build/source/libs/luajit/LuaJIT-src/src/host/buildvm_fold.c index daed7eccb22..eec1af1cbac 100644 --- a/Build/source/libs/luajit/LuaJIT-src/src/host/buildvm_fold.c +++ b/Build/source/libs/luajit/LuaJIT-src/src/host/buildvm_fold.c @@ -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-2016 Mike Pall. See Copyright Notice in luajit.h */ #include "buildvm.h" diff --git a/Build/source/libs/luajit/LuaJIT-src/src/host/buildvm_lib.c b/Build/source/libs/luajit/LuaJIT-src/src/host/buildvm_lib.c index e928673d4e0..1adc3cbd60a 100644 --- a/Build/source/libs/luajit/LuaJIT-src/src/host/buildvm_lib.c +++ b/Build/source/libs/luajit/LuaJIT-src/src/host/buildvm_lib.c @@ -1,6 +1,6 @@ /* ** LuaJIT VM builder: library definition compiler. -** Copyright (C) 2005-2015 Mike Pall. See Copyright Notice in luajit.h +** Copyright (C) 2005-2016 Mike Pall. See Copyright Notice in luajit.h */ #include "buildvm.h" diff --git a/Build/source/libs/luajit/LuaJIT-src/src/host/buildvm_peobj.c b/Build/source/libs/luajit/LuaJIT-src/src/host/buildvm_peobj.c index 4279f50050b..e8c927d8bf9 100644 --- a/Build/source/libs/luajit/LuaJIT-src/src/host/buildvm_peobj.c +++ b/Build/source/libs/luajit/LuaJIT-src/src/host/buildvm_peobj.c @@ -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-2016 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. diff --git a/Build/source/libs/luajit/LuaJIT-src/src/host/genlibbc.lua b/Build/source/libs/luajit/LuaJIT-src/src/host/genlibbc.lua index 4398d8e74d9..7a17a3d06b8 100644 --- a/Build/source/libs/luajit/LuaJIT-src/src/host/genlibbc.lua +++ b/Build/source/libs/luajit/LuaJIT-src/src/host/genlibbc.lua @@ -2,7 +2,7 @@ -- 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-2015 Mike Pall. All rights reserved. +-- Copyright (C) 2005-2016 Mike Pall. All rights reserved. -- Released under the MIT license. See Copyright Notice in luajit.h ---------------------------------------------------------------------------- diff --git a/Build/source/libs/luajit/LuaJIT-src/src/host/genminilua.lua b/Build/source/libs/luajit/LuaJIT-src/src/host/genminilua.lua index cd0d946628c..0a4690c1d2f 100644 --- a/Build/source/libs/luajit/LuaJIT-src/src/host/genminilua.lua +++ b/Build/source/libs/luajit/LuaJIT-src/src/host/genminilua.lua @@ -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-2016 Mike Pall. All rights reserved. -- Released under the MIT license. See Copyright Notice in luajit.h ---------------------------------------------------------------------------- diff --git a/Build/source/libs/luajit/LuaJIT-src/src/jit/bc.lua b/Build/source/libs/luajit/LuaJIT-src/src/jit/bc.lua index 320039ff353..a8cb8496e43 100644 --- a/Build/source/libs/luajit/LuaJIT-src/src/jit/bc.lua +++ b/Build/source/libs/luajit/LuaJIT-src/src/jit/bc.lua @@ -1,7 +1,7 @@ ---------------------------------------------------------------------------- -- LuaJIT bytecode listing module. -- --- Copyright (C) 2005-2015 Mike Pall. All rights reserved. +-- Copyright (C) 2005-2016 Mike Pall. All rights reserved. -- Released under the MIT license. See Copyright Notice in luajit.h ---------------------------------------------------------------------------- -- diff --git a/Build/source/libs/luajit/LuaJIT-src/src/jit/bcsave.lua b/Build/source/libs/luajit/LuaJIT-src/src/jit/bcsave.lua index 1fe9d389697..d0968b18760 100644 --- a/Build/source/libs/luajit/LuaJIT-src/src/jit/bcsave.lua +++ b/Build/source/libs/luajit/LuaJIT-src/src/jit/bcsave.lua @@ -1,7 +1,7 @@ ---------------------------------------------------------------------------- -- LuaJIT module to save/list bytecode. -- --- Copyright (C) 2005-2015 Mike Pall. All rights reserved. +-- Copyright (C) 2005-2016 Mike Pall. All rights reserved. -- Released under the MIT license. See Copyright Notice in luajit.h ---------------------------------------------------------------------------- -- @@ -200,7 +200,7 @@ 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" then is64 = true elseif ctx.arch == "ppc" or ctx.arch == "mips" then isbe = true diff --git a/Build/source/libs/luajit/LuaJIT-src/src/jit/dis_arm.lua b/Build/source/libs/luajit/LuaJIT-src/src/jit/dis_arm.lua index dfcbeeecf14..1296d816be0 100644 --- a/Build/source/libs/luajit/LuaJIT-src/src/jit/dis_arm.lua +++ b/Build/source/libs/luajit/LuaJIT-src/src/jit/dis_arm.lua @@ -1,7 +1,7 @@ ---------------------------------------------------------------------------- -- LuaJIT ARM disassembler module. -- --- Copyright (C) 2005-2015 Mike Pall. All rights reserved. +-- Copyright (C) 2005-2016 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. diff --git a/Build/source/libs/luajit/LuaJIT-src/src/jit/dis_mips.lua b/Build/source/libs/luajit/LuaJIT-src/src/jit/dis_mips.lua index 9466f45c2c2..2bf8b389c36 100644 --- a/Build/source/libs/luajit/LuaJIT-src/src/jit/dis_mips.lua +++ b/Build/source/libs/luajit/LuaJIT-src/src/jit/dis_mips.lua @@ -1,7 +1,7 @@ ---------------------------------------------------------------------------- -- LuaJIT MIPS disassembler module. -- --- Copyright (C) 2005-2015 Mike Pall. All rights reserved. +-- Copyright (C) 2005-2016 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. diff --git a/Build/source/libs/luajit/LuaJIT-src/src/jit/dis_mipsel.lua b/Build/source/libs/luajit/LuaJIT-src/src/jit/dis_mipsel.lua index f06ffe855e3..3f2f6efc98f 100644 --- a/Build/source/libs/luajit/LuaJIT-src/src/jit/dis_mipsel.lua +++ b/Build/source/libs/luajit/LuaJIT-src/src/jit/dis_mipsel.lua @@ -1,7 +1,7 @@ ---------------------------------------------------------------------------- -- LuaJIT MIPSEL disassembler wrapper module. -- --- Copyright (C) 2005-2015 Mike Pall. All rights reserved. +-- Copyright (C) 2005-2016 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 diff --git a/Build/source/libs/luajit/LuaJIT-src/src/jit/dis_ppc.lua b/Build/source/libs/luajit/LuaJIT-src/src/jit/dis_ppc.lua index e077d7acdd9..30f51ecdc14 100644 --- a/Build/source/libs/luajit/LuaJIT-src/src/jit/dis_ppc.lua +++ b/Build/source/libs/luajit/LuaJIT-src/src/jit/dis_ppc.lua @@ -1,7 +1,7 @@ ---------------------------------------------------------------------------- -- LuaJIT PPC disassembler module. -- --- Copyright (C) 2005-2015 Mike Pall. All rights reserved. +-- Copyright (C) 2005-2016 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. diff --git a/Build/source/libs/luajit/LuaJIT-src/src/jit/dis_x64.lua b/Build/source/libs/luajit/LuaJIT-src/src/jit/dis_x64.lua index 15d55243a85..077b1b127ca 100644 --- a/Build/source/libs/luajit/LuaJIT-src/src/jit/dis_x64.lua +++ b/Build/source/libs/luajit/LuaJIT-src/src/jit/dis_x64.lua @@ -1,7 +1,7 @@ ---------------------------------------------------------------------------- -- LuaJIT x64 disassembler wrapper module. -- --- Copyright (C) 2005-2015 Mike Pall. All rights reserved. +-- Copyright (C) 2005-2016 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 diff --git a/Build/source/libs/luajit/LuaJIT-src/src/jit/dis_x86.lua b/Build/source/libs/luajit/LuaJIT-src/src/jit/dis_x86.lua index 6bc38066fe3..f8a21ff30ec 100644 --- a/Build/source/libs/luajit/LuaJIT-src/src/jit/dis_x86.lua +++ b/Build/source/libs/luajit/LuaJIT-src/src/jit/dis_x86.lua @@ -1,7 +1,7 @@ ---------------------------------------------------------------------------- -- LuaJIT x86/x64 disassembler module. -- --- Copyright (C) 2005-2015 Mike Pall. All rights reserved. +-- Copyright (C) 2005-2016 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,13 +15,12 @@ -- 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 @@ -78,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", @@ -103,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 }) @@ -114,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", @@ -128,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", @@ -144,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", @@ -182,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") @@ -210,49 +209,70 @@ 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", }, ["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", }, } @@ -356,17 +376,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. } @@ -389,10 +411,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.." "..text + elseif ctx.rex == "vex" then text = "v"..text 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..":") @@ -407,6 +432,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 @@ -415,7 +441,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. @@ -452,9 +478,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 @@ -469,11 +495,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) @@ -486,6 +514,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) @@ -618,8 +650,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.."'") @@ -694,7 +731,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) @@ -755,15 +792,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; b = (b-nx)/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, } ------------------------------------------------------------------------------ diff --git a/Build/source/libs/luajit/LuaJIT-src/src/jit/dump.lua b/Build/source/libs/luajit/LuaJIT-src/src/jit/dump.lua index 5f858492bc4..9d8330e1838 100644 --- a/Build/source/libs/luajit/LuaJIT-src/src/jit/dump.lua +++ b/Build/source/libs/luajit/LuaJIT-src/src/jit/dump.lua @@ -1,7 +1,7 @@ ---------------------------------------------------------------------------- -- LuaJIT compiler dump module. -- --- Copyright (C) 2005-2015 Mike Pall. All rights reserved. +-- Copyright (C) 2005-2016 Mike Pall. All rights reserved. -- Released under the MIT license. See Copyright Notice in luajit.h ---------------------------------------------------------------------------- -- @@ -571,6 +571,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() diff --git a/Build/source/libs/luajit/LuaJIT-src/src/jit/p.lua b/Build/source/libs/luajit/LuaJIT-src/src/jit/p.lua index 97d4ccdf87c..5323728b1df 100644 --- a/Build/source/libs/luajit/LuaJIT-src/src/jit/p.lua +++ b/Build/source/libs/luajit/LuaJIT-src/src/jit/p.lua @@ -1,7 +1,7 @@ ---------------------------------------------------------------------------- -- LuaJIT profiler. -- --- Copyright (C) 2005-2015 Mike Pall. All rights reserved. +-- Copyright (C) 2005-2016 Mike Pall. All rights reserved. -- Released under the MIT license. See Copyright Notice in luajit.h ---------------------------------------------------------------------------- -- diff --git a/Build/source/libs/luajit/LuaJIT-src/src/jit/v.lua b/Build/source/libs/luajit/LuaJIT-src/src/jit/v.lua index 157c34bc643..60c8b05aa4e 100644 --- a/Build/source/libs/luajit/LuaJIT-src/src/jit/v.lua +++ b/Build/source/libs/luajit/LuaJIT-src/src/jit/v.lua @@ -1,7 +1,7 @@ ---------------------------------------------------------------------------- -- Verbose mode of the LuaJIT compiler. -- --- Copyright (C) 2005-2015 Mike Pall. All rights reserved. +-- Copyright (C) 2005-2016 Mike Pall. All rights reserved. -- Released under the MIT license. See Copyright Notice in luajit.h ---------------------------------------------------------------------------- -- diff --git a/Build/source/libs/luajit/LuaJIT-src/src/jit/zone.lua b/Build/source/libs/luajit/LuaJIT-src/src/jit/zone.lua index 69f0f169147..f5f9656af63 100644 --- a/Build/source/libs/luajit/LuaJIT-src/src/jit/zone.lua +++ b/Build/source/libs/luajit/LuaJIT-src/src/jit/zone.lua @@ -1,7 +1,7 @@ ---------------------------------------------------------------------------- -- LuaJIT profiler zones. -- --- Copyright (C) 2005-2015 Mike Pall. All rights reserved. +-- Copyright (C) 2005-2016 Mike Pall. All rights reserved. -- Released under the MIT license. See Copyright Notice in luajit.h ---------------------------------------------------------------------------- -- diff --git a/Build/source/libs/luajit/LuaJIT-src/src/lauxlib.h b/Build/source/libs/luajit/LuaJIT-src/src/lauxlib.h index b6ed1a7d04a..ef0fd54dacc 100644 --- a/Build/source/libs/luajit/LuaJIT-src/src/lauxlib.h +++ b/Build/source/libs/luajit/LuaJIT-src/src/lauxlib.h @@ -170,6 +170,8 @@ 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); +/* Luajittex needs this one because it overloads loadfile */ +LUALIB_API int (RESERVED_load_aux_JIT) (lua_State *L, int status, int envarg); /* }====================================================== */ diff --git a/Build/source/libs/luajit/LuaJIT-src/src/lib_aux.c b/Build/source/libs/luajit/LuaJIT-src/src/lib_aux.c index 4a1b70ddc09..0e61d951a24 100644 --- a/Build/source/libs/luajit/LuaJIT-src/src/lib_aux.c +++ b/Build/source/libs/luajit/LuaJIT-src/src/lib_aux.c @@ -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-2016 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 diff --git a/Build/source/libs/luajit/LuaJIT-src/src/lib_base.c b/Build/source/libs/luajit/LuaJIT-src/src/lib_base.c index 887fea7a58a..6107bde0066 100644 --- a/Build/source/libs/luajit/LuaJIT-src/src/lib_base.c +++ b/Build/source/libs/luajit/LuaJIT-src/src/lib_base.c @@ -1,6 +1,6 @@ /* ** Base and coroutine library. -** Copyright (C) 2005-2015 Mike Pall. See Copyright Notice in luajit.h +** Copyright (C) 2005-2016 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 @@ -435,13 +435,13 @@ LJLIB_CF(gcinfo) 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); @@ -495,11 +495,10 @@ LJLIB_CF(print) shortcut = (tvisfunc(tv) && funcV(tv)->c.ffid == FF_tostring); for (i = 0; i < nargs; i++) { cTValue *o = &L->base[i]; - char buf[STRFMT_MAXBUF_NUM]; const char *str; size_t size; MSize len; - if (shortcut && (str = lj_strfmt_wstrnum(buf, o, &len)) != NULL) { + if (shortcut && (str = lj_strfmt_wstrnum(L, o, &len)) != NULL) { size = len; } else { copyTV(L, L->top+1, o); diff --git a/Build/source/libs/luajit/LuaJIT-src/src/lib_bit.c b/Build/source/libs/luajit/LuaJIT-src/src/lib_bit.c index 55cb2a845a8..1344d24d9fa 100644 --- a/Build/source/libs/luajit/LuaJIT-src/src/lib_bit.c +++ b/Build/source/libs/luajit/LuaJIT-src/src/lib_bit.c @@ -1,6 +1,6 @@ /* ** Bit manipulation library. -** Copyright (C) 2005-2015 Mike Pall. See Copyright Notice in luajit.h +** Copyright (C) 2005-2016 Mike Pall. See Copyright Notice in luajit.h */ #define lib_bit_c diff --git a/Build/source/libs/luajit/LuaJIT-src/src/lib_debug.c b/Build/source/libs/luajit/LuaJIT-src/src/lib_debug.c index b610fb4dcdd..cda7137efc0 100644 --- a/Build/source/libs/luajit/LuaJIT-src/src/lib_debug.c +++ b/Build/source/libs/luajit/LuaJIT-src/src/lib_debug.c @@ -1,6 +1,6 @@ /* ** Debug library. -** Copyright (C) 2005-2015 Mike Pall. See Copyright Notice in luajit.h +** Copyright (C) 2005-2016 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 diff --git a/Build/source/libs/luajit/LuaJIT-src/src/lib_ffi.c b/Build/source/libs/luajit/LuaJIT-src/src/lib_ffi.c index b2b2d37ff7b..1feee2157f9 100644 --- a/Build/source/libs/luajit/LuaJIT-src/src/lib_ffi.c +++ b/Build/source/libs/luajit/LuaJIT-src/src/lib_ffi.c @@ -1,6 +1,6 @@ /* ** FFI library. -** Copyright (C) 2005-2015 Mike Pall. See Copyright Notice in luajit.h +** Copyright (C) 2005-2016 Mike Pall. See Copyright Notice in luajit.h */ #define lib_ffi_c @@ -505,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(L, 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. */ diff --git a/Build/source/libs/luajit/LuaJIT-src/src/lib_init.c b/Build/source/libs/luajit/LuaJIT-src/src/lib_init.c index 8e0d4428fd3..bbb99ec0efd 100644 --- a/Build/source/libs/luajit/LuaJIT-src/src/lib_init.c +++ b/Build/source/libs/luajit/LuaJIT-src/src/lib_init.c @@ -1,6 +1,6 @@ /* ** Library initialization. -** Copyright (C) 2005-2015 Mike Pall. See Copyright Notice in luajit.h +** Copyright (C) 2005-2016 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 diff --git a/Build/source/libs/luajit/LuaJIT-src/src/lib_io.c b/Build/source/libs/luajit/LuaJIT-src/src/lib_io.c index 2aa834746e1..31f0ea97521 100644 --- a/Build/source/libs/luajit/LuaJIT-src/src/lib_io.c +++ b/Build/source/libs/luajit/LuaJIT-src/src/lib_io.c @@ -1,6 +1,6 @@ /* ** I/O library. -** Copyright (C) 2005-2015 Mike Pall. See Copyright Notice in luajit.h +** Copyright (C) 2005-2016 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 @@ -232,9 +232,8 @@ 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++) { - char buf[STRFMT_MAXBUF_NUM]; MSize len; - const char *p = lj_strfmt_wstrnum(buf, tv, &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); diff --git a/Build/source/libs/luajit/LuaJIT-src/src/lib_jit.c b/Build/source/libs/luajit/LuaJIT-src/src/lib_jit.c index 178ef249df3..402ca35c7eb 100644 --- a/Build/source/libs/luajit/LuaJIT-src/src/lib_jit.c +++ b/Build/source/libs/luajit/LuaJIT-src/src/lib_jit.c @@ -1,6 +1,6 @@ /* ** JIT library. -** Copyright (C) 2005-2015 Mike Pall. See Copyright Notice in luajit.h +** Copyright (C) 2005-2016 Mike Pall. See Copyright Notice in luajit.h */ #define lib_jit_c diff --git a/Build/source/libs/luajit/LuaJIT-src/src/lib_math.c b/Build/source/libs/luajit/LuaJIT-src/src/lib_math.c index 78838fcd6c0..f90dd331c44 100644 --- a/Build/source/libs/luajit/LuaJIT-src/src/lib_math.c +++ b/Build/source/libs/luajit/LuaJIT-src/src/lib_math.c @@ -1,6 +1,6 @@ /* ** Math library. -** Copyright (C) 2005-2015 Mike Pall. See Copyright Notice in luajit.h +** Copyright (C) 2005-2016 Mike Pall. See Copyright Notice in luajit.h */ #include <math.h> diff --git a/Build/source/libs/luajit/LuaJIT-src/src/lib_os.c b/Build/source/libs/luajit/LuaJIT-src/src/lib_os.c index 7b5873a518a..941c2a5db0b 100644 --- a/Build/source/libs/luajit/LuaJIT-src/src/lib_os.c +++ b/Build/source/libs/luajit/LuaJIT-src/src/lib_os.c @@ -1,6 +1,6 @@ /* ** OS library. -** Copyright (C) 2005-2015 Mike Pall. See Copyright Notice in luajit.h +** Copyright (C) 2005-2016 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 @@ -39,7 +39,7 @@ LJLIB_CF(os_execute) { -#if LJ_TARGET_CONSOLE +#if LJ_NO_SYSTEM #if LJ_52 errno = ENOSYS; return luaL_fileresult(L, 0, NULL); diff --git a/Build/source/libs/luajit/LuaJIT-src/src/lib_package.c b/Build/source/libs/luajit/LuaJIT-src/src/lib_package.c index f8d69bfea82..ed56156e583 100644 --- a/Build/source/libs/luajit/LuaJIT-src/src/lib_package.c +++ b/Build/source/libs/luajit/LuaJIT-src/src/lib_package.c @@ -1,6 +1,6 @@ /* ** Package library. -** Copyright (C) 2005-2015 Mike Pall. See Copyright Notice in luajit.h +** Copyright (C) 2005-2016 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 diff --git a/Build/source/libs/luajit/LuaJIT-src/src/lib_string.c b/Build/source/libs/luajit/LuaJIT-src/src/lib_string.c index a6d9986ac63..46b54a5e584 100644 --- a/Build/source/libs/luajit/LuaJIT-src/src/lib_string.c +++ b/Build/source/libs/luajit/LuaJIT-src/src/lib_string.c @@ -1,6 +1,6 @@ /* ** String library. -** Copyright (C) 2005-2015 Mike Pall. See Copyright Notice in luajit.h +** Copyright (C) 2005-2016 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 diff --git a/Build/source/libs/luajit/LuaJIT-src/src/lib_table.c b/Build/source/libs/luajit/LuaJIT-src/src/lib_table.c index 56612aba983..f9a3693dfcb 100644 --- a/Build/source/libs/luajit/LuaJIT-src/src/lib_table.c +++ b/Build/source/libs/luajit/LuaJIT-src/src/lib_table.c @@ -1,6 +1,6 @@ /* ** Table library. -** Copyright (C) 2005-2015 Mike Pall. See Copyright Notice in luajit.h +** Copyright (C) 2005-2016 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 diff --git a/Build/source/libs/luajit/LuaJIT-src/src/lj.supp b/Build/source/libs/luajit/LuaJIT-src/src/lj.supp index 411f2617001..acb9e789d08 100644 --- a/Build/source/libs/luajit/LuaJIT-src/src/lj.supp +++ b/Build/source/libs/luajit/LuaJIT-src/src/lj.supp @@ -24,3 +24,18 @@ Memcheck:Cond fun:lj_str_new } +{ + Optimized string compare + Memcheck:Addr4 + fun:lj_str_fastcmp +} +{ + Optimized string compare + Memcheck:Addr1 + fun:lj_str_fastcmp +} +{ + Optimized string compare + Memcheck:Cond + fun:lj_str_fastcmp +} diff --git a/Build/source/libs/luajit/LuaJIT-src/src/lj_api.c b/Build/source/libs/luajit/LuaJIT-src/src/lj_api.c index 1f09284f991..0fbb9256343 100644 --- a/Build/source/libs/luajit/LuaJIT-src/src/lj_api.c +++ b/Build/source/libs/luajit/LuaJIT-src/src/lj_api.c @@ -1,6 +1,6 @@ /* ** Public Lua/C API. -** Copyright (C) 2005-2015 Mike Pall. See Copyright Notice in luajit.h +** Copyright (C) 2005-2016 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 @@ -1188,6 +1188,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. */ } diff --git a/Build/source/libs/luajit/LuaJIT-src/src/lj_arch.h b/Build/source/libs/luajit/LuaJIT-src/src/lj_arch.h index 6760111ef5e..d95848fe5cf 100644 --- a/Build/source/libs/luajit/LuaJIT-src/src/lj_arch.h +++ b/Build/source/libs/luajit/LuaJIT-src/src/lj_arch.h @@ -1,6 +1,6 @@ /* ** Target architecture selection. -** Copyright (C) 2005-2015 Mike Pall. See Copyright Notice in luajit.h +** Copyright (C) 2005-2016 Mike Pall. See Copyright Notice in luajit.h */ #ifndef _LJ_ARCH_H @@ -295,6 +295,28 @@ #define LJ_ARCH_NAME "mips" #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 + +/* Temporarily disable features until the code has been merged. */ +#if !defined(LUAJIT_NO_UNWIND) && __GNU_COMPACT_EH__ +#define LUAJIT_NO_UNWIND 1 +#endif + +#if !defined(LJ_ABI_SOFTFP) +#ifdef __mips_soft_float +#define LJ_ABI_SOFTFP 1 +#else +#define LJ_ABI_SOFTFP 0 +#endif +#endif + #define LJ_ARCH_BITS 32 #define LJ_TARGET_MIPS 1 #define LJ_TARGET_EHRETREG 4 @@ -302,7 +324,7 @@ #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 #define LJ_ARCH_VERSION 20 @@ -386,9 +408,6 @@ #error "No support for PPC/e500 anymore (use LuaJIT 2.0)" #endif #elif LJ_TARGET_MIPS -#if defined(__mips_soft_float) -#error "No support for MIPS CPUs without FPU" -#endif #if defined(_LP64) #error "No support for MIPS64" #endif @@ -492,12 +511,15 @@ #endif /* Various workarounds for embedded operating systems or weak C runtimes. */ -#if (defined(__ANDROID__) && !defined(LJ_TARGET_X86ORX64)) || defined(__symbian__) || LJ_TARGET_XBOX360 || LJ_TARGET_WINDOWS +#if defined(__ANDROID__) || defined(__symbian__) || LJ_TARGET_XBOX360 || LJ_TARGET_WINDOWS #define LUAJIT_NO_LOG2 #endif #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 || LJ_TARGET_PS4 #define LJ_NO_UNWIND 1 diff --git a/Build/source/libs/luajit/LuaJIT-src/src/lj_asm.c b/Build/source/libs/luajit/LuaJIT-src/src/lj_asm.c index 9db950a2bd1..93f6bcd6c96 100644 --- a/Build/source/libs/luajit/LuaJIT-src/src/lj_asm.c +++ b/Build/source/libs/luajit/LuaJIT-src/src/lj_asm.c @@ -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-2016 Mike Pall. See Copyright Notice in luajit.h */ #define lj_asm_c @@ -1609,16 +1609,24 @@ static void asm_ir(ASMState *as, IRIns *ir) 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_DIV: asm_div(as, ir); break; case IR_MOD: asm_mod(as, ir); break; - case IR_POW: asm_pow(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; - case IR_FPMATH: asm_fpmath(as, ir); break; /* Overflow-checking arithmetic ops. */ case IR_ADDOV: asm_addov(as, ir); break; @@ -1663,7 +1671,6 @@ static void asm_ir(ASMState *as, IRIns *ir) case IR_OBAR: asm_obar(as, ir); break; /* Type conversions. */ - case IR_TOBIT: asm_tobit(as, ir); break; case IR_CONV: asm_conv(as, ir); break; case IR_TOSTR: asm_tostr(as, ir); break; case IR_STRTO: asm_strto(as, ir); break; diff --git a/Build/source/libs/luajit/LuaJIT-src/src/lj_asm.h b/Build/source/libs/luajit/LuaJIT-src/src/lj_asm.h index 85f29763220..9f4654ec0a8 100644 --- a/Build/source/libs/luajit/LuaJIT-src/src/lj_asm.h +++ b/Build/source/libs/luajit/LuaJIT-src/src/lj_asm.h @@ -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-2016 Mike Pall. See Copyright Notice in luajit.h */ #ifndef _LJ_ASM_H diff --git a/Build/source/libs/luajit/LuaJIT-src/src/lj_asm_arm.h b/Build/source/libs/luajit/LuaJIT-src/src/lj_asm_arm.h index 81843caf96a..ff4068a37fa 100644 --- a/Build/source/libs/luajit/LuaJIT-src/src/lj_asm_arm.h +++ b/Build/source/libs/luajit/LuaJIT-src/src/lj_asm_arm.h @@ -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-2016 Mike Pall. See Copyright Notice in luajit.h */ /* -- Register allocator extensions --------------------------------------- */ @@ -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)) @@ -520,8 +520,6 @@ static void asm_tobit(ASMState *as, IRIns *ir) emit_dn(as, ARMI_VMOV_R_S, dest, (tmp & 15)); emit_dnm(as, ARMI_VADD_D, (tmp & 15), (left & 15), (right & 15)); } -#else -#define asm_tobit(as, ir) lua_assert(0) #endif static void asm_conv(ASMState *as, IRIns *ir) @@ -1372,8 +1370,6 @@ static void asm_fpmath(ASMState *as, IRIns *ir) else asm_callid(as, ir, IRCALL_lj_vm_floor + ir->op2); } -#else -#define asm_fpmath(as, ir) lua_assert(0) #endif static int asm_swapops(ASMState *as, IRRef lref, IRRef rref) @@ -1492,13 +1488,7 @@ static void asm_mul(ASMState *as, IRIns *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) lua_assert(0) -#define asm_pow(as, ir) lua_assert(0) -#define asm_abs(as, ir) lua_assert(0) -#define asm_atan2(as, ir) lua_assert(0) -#define asm_ldexp(as, ir) lua_assert(0) -#else +#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) diff --git a/Build/source/libs/luajit/LuaJIT-src/src/lj_asm_mips.h b/Build/source/libs/luajit/LuaJIT-src/src/lj_asm_mips.h index adea0e32367..9b7f89b096a 100644 --- a/Build/source/libs/luajit/LuaJIT-src/src/lj_asm_mips.h +++ b/Build/source/libs/luajit/LuaJIT-src/src/lj_asm_mips.h @@ -1,6 +1,6 @@ /* ** MIPS IR assembler (SSA IR -> machine code). -** Copyright (C) 2005-2015 Mike Pall. See Copyright Notice in luajit.h +** Copyright (C) 2005-2016 Mike Pall. See Copyright Notice in luajit.h */ /* -- Register allocator extensions --------------------------------------- */ @@ -228,27 +228,39 @@ static void asm_gencall(ASMState *as, const CCallInfo *ci, IRRef *args) { uint32_t n, nargs = CCI_XNARGS(ci); int32_t ofs = 16; +#if LJ_SOFTFP + Reg gpr = REGARG_FIRSTGPR; +#else Reg gpr, fpr = REGARG_FIRSTFPR; +#endif if ((void *)ci->func) - emit_call(as, (void *)ci->func); + emit_call(as, (void *)ci->func, 1); +#if !LJ_SOFTFP for (gpr = REGARG_FIRSTGPR; gpr <= REGARG_LASTGPR; gpr++) as->cost[gpr] = REGCOST(~0u, ASMREF_L); gpr = REGARG_FIRSTGPR; +#endif for (n = 0; n < nargs; n++) { /* Setup args. */ IRRef ref = args[n]; if (ref) { IRIns *ir = IR(ref); +#if !LJ_SOFTFP if (irt_isfp(ir->t) && fpr <= REGARG_LASTFPR && !(ci->flags & CCI_VARARG)) { lua_assert(rset_test(as->freeset, fpr)); /* Already evicted. */ ra_leftov(as, fpr, ref); fpr += 2; gpr += irt_isnum(ir->t) ? 2 : 1; - } else { + } else +#endif + { +#if !LJ_SOFTFP fpr = REGARG_LASTFPR+1; +#endif if (irt_isnum(ir->t)) gpr = (gpr+1) & ~1; if (gpr <= REGARG_LASTGPR) { lua_assert(rset_test(as->freeset, gpr)); /* Already evicted. */ +#if !LJ_SOFTFP if (irt_isfp(ir->t)) { RegSet of = as->freeset; Reg r; @@ -265,19 +277,23 @@ static void asm_gencall(ASMState *as, const CCallInfo *ci, IRRef *args) emit_tg(as, MIPSI_MFC1, gpr, r); gpr++; } - } else { + } else +#endif + { ra_leftov(as, gpr, ref); gpr++; } } else { - Reg r = ra_alloc1z(as, ref, irt_isfp(ir->t) ? RSET_FPR : RSET_GPR); + Reg r = ra_alloc1z(as, ref, !LJ_SOFTFP && irt_isfp(ir->t) ? RSET_FPR : RSET_GPR); if (irt_isnum(ir->t)) ofs = (ofs + 4) & ~4; emit_spstore(as, ir, r, ofs); ofs += irt_isnum(ir->t) ? 8 : 4; } } } else { +#if !LJ_SOFTFP fpr = REGARG_LASTFPR+1; +#endif if (gpr <= REGARG_LASTGPR) gpr++; else @@ -291,9 +307,11 @@ 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 !LJ_SOFTFP if ((ci->flags & CCI_NOFPRCLOBBER)) drop &= ~RSET_FPR; +#endif if (ra_hasreg(ir->r)) rset_clear(drop, ir->r); /* Dest reg handled below. */ if (hiop && ra_hasreg((ir+1)->r)) @@ -301,7 +319,7 @@ static void asm_setupresult(ASMState *as, IRIns *ir, const CCallInfo *ci) ra_evictset(as, drop); /* Evictions must be performed first. */ if (ra_used(ir)) { lua_assert(!irt_ispri(ir->t)); - if (irt_isfp(ir->t)) { + if (!LJ_SOFTFP && irt_isfp(ir->t)) { if ((ci->flags & CCI_CASTU64)) { int32_t ofs = sps_scale(ir->s); Reg dest = ir->r; @@ -353,6 +371,7 @@ static void asm_callx(ASMState *as, IRIns *ir) asm_gencall(as, &ci, args); } +#if !LJ_SOFTFP static void asm_callround(ASMState *as, IRIns *ir, IRCallID id) { /* The modified regs must match with the *.dasc implementation. */ @@ -361,9 +380,10 @@ static void asm_callround(ASMState *as, IRIns *ir, IRCallID id) if (ra_hasreg(ir->r)) rset_clear(drop, ir->r); ra_evictset(as, drop); ra_destreg(as, ir, RID_FPRET); - emit_call(as, (void *)lj_ir_callinfo[id].func); + emit_call(as, (void *)lj_ir_callinfo[id].func, 0); ra_leftov(as, REGARG_FIRSTFPR, ir->op1); } +#endif /* -- Returns ------------------------------------------------------------- */ @@ -385,6 +405,7 @@ static void asm_retf(ASMState *as, IRIns *ir) /* -- Type conversions ---------------------------------------------------- */ +#if !LJ_SOFTFP static void asm_tointg(ASMState *as, IRIns *ir, Reg left) { Reg tmp = ra_scratch(as, rset_exclude(RSET_FPR, left)); @@ -406,15 +427,23 @@ static void asm_tobit(ASMState *as, IRIns *ir) emit_tg(as, MIPSI_MFC1, dest, tmp); emit_fgh(as, MIPSI_ADD_D, tmp, left, right); } +#endif static void asm_conv(ASMState *as, IRIns *ir) { IRType st = (IRType)(ir->op2 & IRCONV_SRCMASK); +#if !LJ_SOFTFP int stfp = (st == IRT_NUM || st == IRT_FLOAT); +#endif IRRef lref = ir->op1; - lua_assert(irt_type(ir->t) != st); lua_assert(!(irt_isint64(ir->t) || (st == IRT_I64 || st == IRT_U64))); /* Handled by SPLIT. */ +#if LJ_SOFTFP + /* FP conversions are handled by SPLIT. */ + lua_assert(!irt_isfp(ir->t) && !(st == IRT_NUM || st == IRT_FLOAT)); + /* Can't check for same types: SPLIT uses CONV int.int + BXOR for sfp NEG. */ +#else + lua_assert(irt_type(ir->t) != st); if (irt_isfp(ir->t)) { Reg dest = ra_dest(as, ir, RSET_FPR); if (stfp) { /* FP to FP conversion. */ @@ -477,7 +506,9 @@ static void asm_conv(ASMState *as, IRIns *ir) tmp, left); } } - } else { + } else +#endif + { Reg dest = ra_dest(as, ir, RSET_GPR); if (st >= IRT_I8 && st <= IRT_U16) { /* Extend to 32 bit integer. */ Reg left = ra_alloc1(as, ir->op1, RSET_GPR); @@ -505,16 +536,42 @@ static void asm_strto(ASMState *as, IRIns *ir) { const CCallInfo *ci = &lj_ir_callinfo[IRCALL_lj_strscan_num]; IRRef args[2]; + int32_t ofs = 0; +#if LJ_SOFTFP + ra_evictset(as, RSET_SCRATCH); + if (ra_used(ir)) { + if (ra_hasspill(ir->s) && ra_hasspill((ir+1)->s) && + (ir->s & 1) == LJ_BE && (ir->s ^ 1) == (ir+1)->s) { + int i; + for (i = 0; i < 2; i++) { + Reg r = (ir+i)->r; + if (ra_hasreg(r)) { + ra_free(as, r); + ra_modified(as, r); + emit_spload(as, ir+i, r, sps_scale((ir+i)->s)); + } + } + ofs = sps_scale(ir->s & ~1); + } else { + Reg rhi = ra_dest(as, ir+1, RSET_GPR); + Reg rlo = ra_dest(as, ir, rset_exclude(RSET_GPR, rhi)); + emit_tsi(as, MIPSI_LW, rhi, RID_SP, ofs+(LJ_BE?0:4)); + emit_tsi(as, MIPSI_LW, rlo, RID_SP, ofs+(LJ_BE?4:0)); + } + } +#else RegSet drop = RSET_SCRATCH; if (ra_hasreg(ir->r)) rset_set(drop, ir->r); /* Spill dest reg (if any). */ ra_evictset(as, drop); + ofs = sps_scale(ir->s); +#endif asm_guard(as, MIPSI_BEQ, RID_RET, RID_ZERO); /* Test return status. */ args[0] = ir->op1; /* GCstr *str */ args[1] = ASMREF_TMP1; /* TValue *n */ asm_gencall(as, ci, args); /* Store the result to the spill slot or temp slots. */ emit_tsi(as, MIPSI_ADDIU, ra_releasetmp(as, ASMREF_TMP1), - RID_SP, sps_scale(ir->s)); + RID_SP, ofs); } /* -- Memory references --------------------------------------------------- */ @@ -532,12 +589,15 @@ static void asm_tvptr(ASMState *as, Reg dest, IRRef ref) /* Otherwise use g->tmptv to hold the TValue. */ RegSet allow = rset_exclude(RSET_GPR, dest); Reg type; - emit_tsi(as, MIPSI_ADDIU, dest, RID_JGL, offsetof(global_State, tmptv)-32768); + emit_tsi(as, MIPSI_ADDIU, dest, RID_JGL, (int32_t)(offsetof(global_State, tmptv)-32768)); if (!irt_ispri(ir->t)) { Reg src = ra_alloc1(as, ref, allow); emit_setgl(as, src, tmptv.gcr); } - type = ra_allock(as, irt_toitype(ir->t), allow); + if (LJ_SOFTFP && (ir+1)->o == IR_HIOP) + type = ra_alloc1(as, ref+1, allow); + else + type = ra_allock(as, (int32_t)irt_toitype(ir->t), allow); emit_setgl(as, type, tmptv.it); } } @@ -585,15 +645,37 @@ static void asm_href(ASMState *as, IRIns *ir, IROp merge) MCLabel l_end, l_loop, l_next; rset_clear(allow, tab); +#if LJ_SOFTFP + if (!irref_isk(refkey)) { + key = ra_alloc1(as, refkey, allow); + rset_clear(allow, key); + if (irkey[1].o == IR_HIOP) { + if (ra_hasreg((irkey+1)->r)) { + tmpnum = (irkey+1)->r; + type = RID_TMP; + tmp1 = ra_scratch(as, allow); + rset_clear(allow, tmp1); + ra_noweak(as, tmpnum); + } else { + type = tmpnum = ra_allocref(as, refkey+1, allow); + } + rset_clear(allow, tmpnum); + } else { + type = ra_allock(as, (int32_t)irt_toitype(irkey->t), allow); + rset_clear(allow, type); + } + } +#else if (irt_isnum(kt)) { key = ra_alloc1(as, refkey, RSET_FPR); tmpnum = ra_scratch(as, rset_exclude(RSET_FPR, key)); } else if (!irt_ispri(kt)) { key = ra_alloc1(as, refkey, allow); rset_clear(allow, key); - type = ra_allock(as, irt_toitype(irkey->t), allow); + type = ra_allock(as, (int32_t)irt_toitype(irkey->t), allow); rset_clear(allow, type); } +#endif tmp2 = ra_scratch(as, allow); rset_clear(allow, tmp2); @@ -615,7 +697,7 @@ static void asm_href(ASMState *as, IRIns *ir, IROp merge) emit_ti(as, MIPSI_LI, RID_TMP, as->snapno); l_end = asm_exitstub_addr(as); } - if (irt_isnum(kt)) { + if (!LJ_SOFTFP && irt_isnum(kt)) { emit_branch(as, MIPSI_BC1T, 0, 0, l_end); emit_fgh(as, MIPSI_C_EQ_D, 0, tmpnum, key); *--as->mcp = MIPSI_NOP; /* Avoid NaN comparison overhead. */ @@ -660,7 +742,7 @@ static void asm_href(ASMState *as, IRIns *ir, IROp merge) emit_dst(as, MIPSI_XOR, tmp1, tmp1, tmp2); emit_rotr(as, tmp1, tmp1, dest, (-HASH_ROT2-HASH_ROT1)&31); emit_dst(as, MIPSI_SUBU, tmp2, tmp2, dest); - if (irt_isnum(kt)) { + if (LJ_SOFTFP ? (irkey[1].o == IR_HIOP) : irt_isnum(kt)) { emit_dst(as, MIPSI_XOR, tmp2, tmp2, tmp1); if ((as->flags & JIT_F_MIPS32R2)) { emit_dta(as, MIPSI_ROTR, dest, tmp1, (-HASH_ROT1)&31); @@ -670,8 +752,13 @@ static void asm_href(ASMState *as, IRIns *ir, IROp merge) emit_dta(as, MIPSI_SRL, dest, tmp1, (-HASH_ROT1)&31); } emit_dst(as, MIPSI_ADDU, tmp1, tmp1, tmp1); +#if LJ_SOFTFP + emit_ds(as, MIPSI_MOVE, tmp1, type); + emit_ds(as, MIPSI_MOVE, tmp2, key); +#else emit_tg(as, MIPSI_MFC1, tmp2, key); emit_tg(as, MIPSI_MFC1, tmp1, key+1); +#endif } else { emit_dst(as, MIPSI_XOR, tmp2, key, tmp1); emit_rotr(as, dest, tmp1, tmp2, (-HASH_ROT1)&31); @@ -795,8 +882,8 @@ static MIPSIns asm_fxloadins(IRIns *ir) case IRT_U8: return MIPSI_LBU; case IRT_I16: return MIPSI_LH; case IRT_U16: return MIPSI_LHU; - case IRT_NUM: return MIPSI_LDC1; - case IRT_FLOAT: return MIPSI_LWC1; + case IRT_NUM: lua_assert(!LJ_SOFTFP); return MIPSI_LDC1; + case IRT_FLOAT: if (!LJ_SOFTFP) return MIPSI_LWC1; default: return MIPSI_LW; } } @@ -806,8 +893,8 @@ static MIPSIns asm_fxstoreins(IRIns *ir) switch (irt_type(ir->t)) { case IRT_I8: case IRT_U8: return MIPSI_SB; case IRT_I16: case IRT_U16: return MIPSI_SH; - case IRT_NUM: return MIPSI_SDC1; - case IRT_FLOAT: return MIPSI_SWC1; + case IRT_NUM: lua_assert(!LJ_SOFTFP); return MIPSI_SDC1; + case IRT_FLOAT: if (!LJ_SOFTFP) return MIPSI_SWC1; default: return MIPSI_SW; } } @@ -845,7 +932,8 @@ static void asm_fstore(ASMState *as, IRIns *ir) static void asm_xload(ASMState *as, IRIns *ir) { - Reg dest = ra_dest(as, ir, irt_isfp(ir->t) ? RSET_FPR : RSET_GPR); + Reg dest = ra_dest(as, ir, + (!LJ_SOFTFP && irt_isfp(ir->t)) ? RSET_FPR : RSET_GPR); lua_assert(!(ir->op2 & IRXLOAD_UNALIGNED)); asm_fusexref(as, asm_fxloadins(ir), dest, ir->op1, RSET_GPR, 0); } @@ -853,7 +941,8 @@ static void asm_xload(ASMState *as, IRIns *ir) static void asm_xstore_(ASMState *as, IRIns *ir, int32_t ofs) { if (ir->r != RID_SINK) { - Reg src = ra_alloc1z(as, ir->op2, irt_isfp(ir->t) ? RSET_FPR : RSET_GPR); + Reg src = ra_alloc1z(as, ir->op2, + (!LJ_SOFTFP && irt_isfp(ir->t)) ? RSET_FPR : RSET_GPR); asm_fusexref(as, asm_fxstoreins(ir), src, ir->op1, rset_exclude(RSET_GPR, src), ofs); } @@ -863,25 +952,34 @@ static void asm_xstore_(ASMState *as, IRIns *ir, int32_t ofs) static void asm_ahuvload(ASMState *as, IRIns *ir) { - IRType1 t = ir->t; + int hiop = (LJ_SOFTFP && (ir+1)->o == IR_HIOP); + IRType t = hiop ? IRT_NUM : irt_type(ir->t); Reg dest = RID_NONE, type = RID_TMP, idx; RegSet allow = RSET_GPR; int32_t ofs = 0; + if (hiop && ra_used(ir+1)) { + type = ra_dest(as, ir+1, allow); + rset_clear(allow, type); + } if (ra_used(ir)) { - lua_assert(irt_isnum(t) || irt_isint(t) || irt_isaddr(t)); - dest = ra_dest(as, ir, irt_isnum(t) ? RSET_FPR : RSET_GPR); + lua_assert((LJ_SOFTFP ? 0 : irt_isnum(ir->t)) || + irt_isint(ir->t) || irt_isaddr(ir->t)); + dest = ra_dest(as, ir, (!LJ_SOFTFP && t == IRT_NUM) ? RSET_FPR : allow); rset_clear(allow, dest); } idx = asm_fuseahuref(as, ir->op1, &ofs, allow); rset_clear(allow, idx); - if (irt_isnum(t)) { - asm_guard(as, MIPSI_BEQ, type, RID_ZERO); - emit_tsi(as, MIPSI_SLTIU, type, type, (int32_t)LJ_TISNUM); - if (ra_hasreg(dest)) - emit_hsi(as, MIPSI_LDC1, dest, idx, ofs); + if (t == IRT_NUM) { + asm_guard(as, MIPSI_BEQ, RID_TMP, RID_ZERO); + emit_tsi(as, MIPSI_SLTIU, RID_TMP, type, (int32_t)LJ_TISNUM); } else { - asm_guard(as, MIPSI_BNE, type, ra_allock(as, irt_toitype(t), allow)); - if (ra_hasreg(dest)) emit_tsi(as, MIPSI_LW, dest, idx, ofs+(LJ_BE?4:0)); + asm_guard(as, MIPSI_BNE, type, ra_allock(as, irt_toitype_(t), allow)); + } + if (ra_hasreg(dest)) { + if (!LJ_SOFTFP && t == IRT_NUM) + emit_hsi(as, MIPSI_LDC1, dest, idx, ofs); + else + emit_tsi(as, MIPSI_LW, dest, idx, ofs+(LJ_BE?4:0)); } emit_tsi(as, MIPSI_LW, type, idx, ofs+(LJ_BE?0:4)); } @@ -893,18 +991,22 @@ static void asm_ahustore(ASMState *as, IRIns *ir) int32_t ofs = 0; if (ir->r == RID_SINK) return; - if (irt_isnum(ir->t)) { + if (!LJ_SOFTFP && irt_isnum(ir->t)) { src = ra_alloc1(as, ir->op2, RSET_FPR); } else { + int hiop = (LJ_SOFTFP && (ir+1)->o == IR_HIOP); if (!irt_ispri(ir->t)) { src = ra_alloc1(as, ir->op2, allow); rset_clear(allow, src); } - type = ra_allock(as, (int32_t)irt_toitype(ir->t), allow); + if (hiop) + type = ra_alloc1(as, (ir+1)->op2, allow); + else + type = ra_allock(as, (int32_t)irt_toitype(ir->t), allow); rset_clear(allow, type); } idx = asm_fuseahuref(as, ir->op1, &ofs, allow); - if (irt_isnum(ir->t)) { + if (!LJ_SOFTFP && irt_isnum(ir->t)) { emit_hsi(as, MIPSI_SDC1, src, idx, ofs); } else { if (ra_hasreg(src)) @@ -916,35 +1018,45 @@ static void asm_ahustore(ASMState *as, IRIns *ir) static void asm_sload(ASMState *as, IRIns *ir) { int32_t ofs = 8*((int32_t)ir->op1-1) + ((ir->op2 & IRSLOAD_FRAME) ? 4 : 0); - IRType1 t = ir->t; + int hiop = (LJ_SOFTFP && (ir+1)->o == IR_HIOP); + IRType t = hiop ? IRT_NUM : irt_type(ir->t); Reg dest = RID_NONE, type = RID_NONE, base; RegSet allow = RSET_GPR; lua_assert(!(ir->op2 & IRSLOAD_PARENT)); /* Handled by asm_head_side(). */ - lua_assert(irt_isguard(t) || !(ir->op2 & IRSLOAD_TYPECHECK)); - lua_assert(!irt_isint(t) || (ir->op2 & (IRSLOAD_CONVERT|IRSLOAD_FRAME))); - if ((ir->op2 & IRSLOAD_CONVERT) && irt_isguard(t) && irt_isint(t)) { + lua_assert(irt_isguard(ir->t) || !(ir->op2 & IRSLOAD_TYPECHECK)); +#if LJ_SOFTFP + lua_assert(!(ir->op2 & IRSLOAD_CONVERT)); /* Handled by LJ_SOFTFP SPLIT. */ + if (hiop && ra_used(ir+1)) { + type = ra_dest(as, ir+1, allow); + rset_clear(allow, type); + } +#else + if ((ir->op2 & IRSLOAD_CONVERT) && irt_isguard(ir->t) && t == IRT_INT) { dest = ra_scratch(as, RSET_FPR); asm_tointg(as, ir, dest); - t.irt = IRT_NUM; /* Continue with a regular number type check. */ - } else if (ra_used(ir)) { - lua_assert(irt_isnum(t) || irt_isint(t) || irt_isaddr(t)); - dest = ra_dest(as, ir, irt_isnum(t) ? RSET_FPR : RSET_GPR); + t = IRT_NUM; /* Continue with a regular number type check. */ + } else +#endif + if (ra_used(ir)) { + lua_assert((LJ_SOFTFP ? 0 : irt_isnum(ir->t)) || + irt_isint(ir->t) || irt_isaddr(ir->t)); + dest = ra_dest(as, ir, (!LJ_SOFTFP && t == IRT_NUM) ? RSET_FPR : allow); rset_clear(allow, dest); base = ra_alloc1(as, REF_BASE, allow); rset_clear(allow, base); - if ((ir->op2 & IRSLOAD_CONVERT)) { - if (irt_isint(t)) { + if (!LJ_SOFTFP && (ir->op2 & IRSLOAD_CONVERT)) { + if (t == IRT_INT) { Reg tmp = ra_scratch(as, RSET_FPR); emit_tg(as, MIPSI_MFC1, dest, tmp); emit_fg(as, MIPSI_TRUNC_W_D, tmp, tmp); dest = tmp; - t.irt = IRT_NUM; /* Check for original type. */ + t = IRT_NUM; /* Check for original type. */ } else { Reg tmp = ra_scratch(as, RSET_GPR); emit_fg(as, MIPSI_CVT_D_W, dest, dest); emit_tg(as, MIPSI_MTC1, tmp, dest); dest = tmp; - t.irt = IRT_INT; /* Check for original type. */ + t = IRT_INT; /* Check for original type. */ } } goto dotypecheck; @@ -952,22 +1064,32 @@ static void asm_sload(ASMState *as, IRIns *ir) base = ra_alloc1(as, REF_BASE, allow); rset_clear(allow, base); dotypecheck: - if (irt_isnum(t)) { - if ((ir->op2 & IRSLOAD_TYPECHECK)) { - asm_guard(as, MIPSI_BEQ, RID_TMP, RID_ZERO); - emit_tsi(as, MIPSI_SLTIU, RID_TMP, RID_TMP, (int32_t)LJ_TISNUM); - type = RID_TMP; + if ((ir->op2 & IRSLOAD_TYPECHECK)) { + if (ra_noreg(type)) { + if (ofs < 256 && ra_hasreg(dest) && (dest & 1) == 0 && + rset_test((as->freeset & allow), dest+1)) { + type = dest+1; + ra_modified(as, type); + } else { + type = RID_TMP; + } } - if (ra_hasreg(dest)) emit_hsi(as, MIPSI_LDC1, dest, base, ofs); - } else { - if ((ir->op2 & IRSLOAD_TYPECHECK)) { - Reg ktype = ra_allock(as, irt_toitype(t), allow); - asm_guard(as, MIPSI_BNE, RID_TMP, ktype); - type = RID_TMP; + if (t == IRT_NUM) { + asm_guard(as, MIPSI_BEQ, RID_TMP, RID_ZERO); + emit_tsi(as, MIPSI_SLTIU, RID_TMP, type, (int32_t)LJ_TISNUM); + } else { + Reg ktype = ra_allock(as, irt_toitype_(t), allow); + asm_guard(as, MIPSI_BNE, type, ktype); } - if (ra_hasreg(dest)) emit_tsi(as, MIPSI_LW, dest, base, ofs ^ (LJ_BE?4:0)); } - if (ra_hasreg(type)) emit_tsi(as, MIPSI_LW, type, base, ofs ^ (LJ_BE?0:4)); + if (ra_hasreg(dest)) { + if (!LJ_SOFTFP && t == IRT_NUM) + emit_hsi(as, MIPSI_LDC1, dest, base, ofs); + else + emit_tsi(as, MIPSI_LW, dest, base, ofs ^ (LJ_BE?4:0)); + } + if (ra_hasreg(type)) + emit_tsi(as, MIPSI_LW, type, base, ofs ^ (LJ_BE?0:4)); } /* -- Allocations --------------------------------------------------------- */ @@ -1080,6 +1202,7 @@ static void asm_obar(ASMState *as, IRIns *ir) /* -- Arithmetic and logic operations ------------------------------------- */ +#if !LJ_SOFTFP static void asm_fparith(ASMState *as, IRIns *ir, MIPSIns mi) { Reg dest = ra_dest(as, ir, RSET_FPR); @@ -1106,12 +1229,16 @@ static void asm_fpmath(ASMState *as, IRIns *ir) else asm_callid(as, ir, IRCALL_lj_vm_floor + ir->op2); } +#endif static void asm_add(ASMState *as, IRIns *ir) { +#if !LJ_SOFTFP if (irt_isnum(ir->t)) { asm_fparith(as, ir, MIPSI_ADD_D); - } else { + } else +#endif + { Reg dest = ra_dest(as, ir, RSET_GPR); Reg right, left = ra_hintalloc(as, ir->op1, dest, RSET_GPR); if (irref_isk(ir->op2)) { @@ -1128,9 +1255,12 @@ static void asm_add(ASMState *as, IRIns *ir) static void asm_sub(ASMState *as, IRIns *ir) { +#if !LJ_SOFTFP if (irt_isnum(ir->t)) { asm_fparith(as, ir, MIPSI_SUB_D); - } else { + } else +#endif + { Reg dest = ra_dest(as, ir, RSET_GPR); Reg right, left = ra_alloc2(as, ir, RSET_GPR); right = (left >> 8); left &= 255; @@ -1140,9 +1270,12 @@ static void asm_sub(ASMState *as, IRIns *ir) static void asm_mul(ASMState *as, IRIns *ir) { +#if !LJ_SOFTFP if (irt_isnum(ir->t)) { asm_fparith(as, ir, MIPSI_MUL_D); - } else { + } else +#endif + { Reg dest = ra_dest(as, ir, RSET_GPR); Reg right, left = ra_alloc2(as, ir, RSET_GPR); right = (left >> 8); left &= 255; @@ -1156,9 +1289,12 @@ static void asm_mul(ASMState *as, IRIns *ir) static void asm_neg(ASMState *as, IRIns *ir) { +#if !LJ_SOFTFP if (irt_isnum(ir->t)) { asm_fpunary(as, ir, MIPSI_NEG_D); - } else { + } else +#endif + { Reg dest = ra_dest(as, ir, RSET_GPR); Reg left = ra_hintalloc(as, ir->op1, dest, RSET_GPR); emit_dst(as, MIPSI_SUBU, dest, RID_ZERO, left); @@ -1396,9 +1532,25 @@ static void asm_bror(ASMState *as, IRIns *ir) } } +#if LJ_SOFTFP +static void asm_sfpmin_max(ASMState *as, IRIns *ir) +{ + CCallInfo ci = lj_ir_callinfo[(IROp)ir->o == IR_MIN ? IRCALL_lj_vm_sfmin : IRCALL_lj_vm_sfmax]; + IRRef args[4]; + args[0^LJ_BE] = ir->op1; + args[1^LJ_BE] = (ir+1)->op1; + args[2^LJ_BE] = ir->op2; + args[3^LJ_BE] = (ir+1)->op2; + asm_setupresult(as, ir, &ci); + emit_call(as, (void *)ci.func, 0); + ci.func = NULL; + asm_gencall(as, &ci, args); +} +#endif + static void asm_min_max(ASMState *as, IRIns *ir, int ismax) { - if (irt_isnum(ir->t)) { + if (!LJ_SOFTFP && irt_isnum(ir->t)) { Reg dest = ra_dest(as, ir, RSET_FPR); Reg right, left = ra_alloc2(as, ir, RSET_FPR); right = (left >> 8); left &= 255; @@ -1429,11 +1581,72 @@ static void asm_min_max(ASMState *as, IRIns *ir, int ismax) /* -- Comparisons --------------------------------------------------------- */ +#if LJ_SOFTFP +/* SFP comparisons. */ +static void asm_sfpcomp(ASMState *as, IRIns *ir) +{ + const CCallInfo *ci = &lj_ir_callinfo[IRCALL_softfp_cmp]; + RegSet drop = RSET_SCRATCH; + Reg r; + IRRef args[4]; + args[LJ_LE ? 0 : 1] = ir->op1; args[LJ_LE ? 1 : 0] = (ir+1)->op1; + args[LJ_LE ? 2 : 3] = ir->op2; args[LJ_LE ? 3 : 2] = (ir+1)->op2; + + for (r = REGARG_FIRSTGPR; r <= REGARG_FIRSTGPR+3; r++) { + if (!rset_test(as->freeset, r) && + regcost_ref(as->cost[r]) == args[r-REGARG_FIRSTGPR]) + rset_clear(drop, r); + } + ra_evictset(as, drop); + + asm_setupresult(as, ir, ci); + + switch ((IROp)ir->o) { + case IR_LT: + asm_guard(as, MIPSI_BGEZ, RID_RET, 0); + break; + case IR_ULT: + asm_guard(as, MIPSI_BEQ, RID_RET, RID_TMP); + emit_loadi(as, RID_TMP, 1); + asm_guard(as, MIPSI_BEQ, RID_RET, RID_ZERO); + break; + case IR_GE: + asm_guard(as, MIPSI_BEQ, RID_RET, RID_TMP); + emit_loadi(as, RID_TMP, 2); + asm_guard(as, MIPSI_BLTZ, RID_RET, 0); + break; + case IR_LE: + asm_guard(as, MIPSI_BGTZ, RID_RET, 0); + break; + case IR_GT: + asm_guard(as, MIPSI_BEQ, RID_RET, RID_TMP); + emit_loadi(as, RID_TMP, 2); + asm_guard(as, MIPSI_BLEZ, RID_RET, 0); + break; + case IR_UGE: + asm_guard(as, MIPSI_BLTZ, RID_RET, 0); + break; + case IR_ULE: + asm_guard(as, MIPSI_BEQ, RID_RET, RID_TMP); + emit_loadi(as, RID_TMP, 1); + break; + case IR_UGT: case IR_ABC: + asm_guard(as, MIPSI_BLEZ, RID_RET, 0); + break; + case IR_EQ: case IR_NE: + asm_guard(as, (ir->o & 1) ? MIPSI_BEQ : MIPSI_BNE, RID_RET, RID_ZERO); + default: + break; + } + asm_gencall(as, ci, args); +} +#endif + static void asm_comp(ASMState *as, IRIns *ir) { /* ORDER IR: LT GE LE GT ULT UGE ULE UGT. */ IROp op = ir->o; - if (irt_isnum(ir->t)) { + if (!LJ_SOFTFP && irt_isnum(ir->t)) { Reg right, left = ra_alloc2(as, ir, RSET_FPR); right = (left >> 8); left &= 255; asm_guard(as, (op&1) ? MIPSI_BC1T : MIPSI_BC1F, 0, 0); @@ -1466,9 +1679,9 @@ static void asm_comp(ASMState *as, IRIns *ir) static void asm_equal(ASMState *as, IRIns *ir) { - Reg right, left = ra_alloc2(as, ir, irt_isnum(ir->t) ? RSET_FPR : RSET_GPR); + Reg right, left = ra_alloc2(as, ir, (!LJ_SOFTFP && irt_isnum(ir->t)) ? RSET_FPR : RSET_GPR); right = (left >> 8); left &= 255; - if (irt_isnum(ir->t)) { + if (!LJ_SOFTFP && irt_isnum(ir->t)) { asm_guard(as, (ir->o & 1) ? MIPSI_BC1T : MIPSI_BC1F, 0, 0); emit_fgh(as, MIPSI_C_EQ_D, 0, left, right); } else { @@ -1518,23 +1731,48 @@ static void asm_comp64eq(ASMState *as, IRIns *ir) /* Hiword op of a split 64 bit op. Previous op must be the loword op. */ static void asm_hiop(ASMState *as, IRIns *ir) { -#if LJ_HASFFI +#if LJ_HASFFI || LJ_SOFTFP /* HIOP is marked as a store because it needs its own DCE logic. */ int uselo = ra_used(ir-1), usehi = ra_used(ir); /* Loword/hiword used? */ if (LJ_UNLIKELY(!(as->flags & JIT_F_OPT_DCE))) uselo = usehi = 1; if ((ir-1)->o == IR_CONV) { /* Conversions to/from 64 bit. */ as->curins--; /* Always skip the CONV. */ +#if LJ_HASFFI && !LJ_SOFTFP if (usehi || uselo) asm_conv64(as, ir); return; +#endif } else if ((ir-1)->o < IR_EQ) { /* 64 bit integer comparisons. ORDER IR. */ as->curins--; /* Always skip the loword comparison. */ +#if LJ_SOFTFP + if (!irt_isint(ir->t)) { + asm_sfpcomp(as, ir-1); + return; + } +#endif +#if LJ_HASFFI asm_comp64(as, ir); +#endif return; } else if ((ir-1)->o <= IR_NE) { /* 64 bit integer comparisons. ORDER IR. */ as->curins--; /* Always skip the loword comparison. */ +#if LJ_SOFTFP + if (!irt_isint(ir->t)) { + asm_sfpcomp(as, ir-1); + return; + } +#endif +#if LJ_HASFFI asm_comp64eq(as, ir); +#endif return; +#if LJ_SOFTFP + } else if ((ir-1)->o == IR_MIN || (ir-1)->o == IR_MAX) { + as->curins--; /* Always skip the loword min/max. */ + if (uselo || usehi) + asm_sfpmin_max(as, ir-1); + return; +#endif } else if ((ir-1)->o == IR_XSTORE) { as->curins--; /* Handle both stores here. */ if ((ir-1)->r != RID_SINK) { @@ -1545,14 +1783,27 @@ static void asm_hiop(ASMState *as, IRIns *ir) } if (!usehi) return; /* Skip unused hiword op for all remaining ops. */ switch ((ir-1)->o) { +#if LJ_HASFFI case IR_ADD: as->curins--; asm_add64(as, ir); break; case IR_SUB: as->curins--; asm_sub64(as, ir); break; case IR_NEG: as->curins--; asm_neg64(as, ir); break; +#endif +#if LJ_SOFTFP + case IR_SLOAD: case IR_ALOAD: case IR_HLOAD: case IR_ULOAD: case IR_VLOAD: + case IR_STRTO: + if (!uselo) + ra_allocref(as, ir->op1, RSET_GPR); /* Mark lo op as used. */ + break; +#endif case IR_CALLN: + case IR_CALLS: case IR_CALLXS: if (!uselo) ra_allocref(as, ir->op1, RID2RSET(RID_RETLO)); /* Mark lo op as used. */ break; +#if LJ_SOFTFP + case IR_ASTORE: case IR_HSTORE: case IR_USTORE: case IR_TOSTR: +#endif case IR_CNEWI: /* Nothing to do here. Handled by lo op itself. */ break; @@ -1619,8 +1870,19 @@ static void asm_stack_restore(ASMState *as, SnapShot *snap) if ((sn & SNAP_NORESTORE)) continue; if (irt_isnum(ir->t)) { +#if LJ_SOFTFP + Reg tmp; + RegSet allow = rset_exclude(RSET_GPR, RID_BASE); + lua_assert(irref_isk(ref)); /* LJ_SOFTFP: must be a number constant. */ + tmp = ra_allock(as, (int32_t)ir_knum(ir)->u32.lo, allow); + emit_tsi(as, MIPSI_SW, tmp, RID_BASE, ofs+(LJ_BE?4:0)); + if (rset_test(as->freeset, tmp+1)) allow = RID2RSET(tmp+1); + tmp = ra_allock(as, (int32_t)ir_knum(ir)->u32.hi, allow); + emit_tsi(as, MIPSI_SW, tmp, RID_BASE, ofs+(LJ_BE?0:4)); +#else Reg src = ra_alloc1(as, ref, RSET_FPR); emit_hsi(as, MIPSI_SDC1, src, RID_BASE, ofs); +#endif } else { Reg type; RegSet allow = rset_exclude(RSET_GPR, RID_BASE); @@ -1633,6 +1895,10 @@ static void asm_stack_restore(ASMState *as, SnapShot *snap) if ((sn & (SNAP_CONT|SNAP_FRAME))) { if (s == 0) continue; /* Do not overwrite link to previous frame. */ type = ra_allock(as, (int32_t)(*flinks--), allow); +#if LJ_SOFTFP + } else if ((sn & SNAP_SOFTFPNUM)) { + type = ra_alloc1(as, ref+1, rset_exclude(RSET_GPR, RID_BASE)); +#endif } else { type = ra_allock(as, (int32_t)irt_toitype(ir->t), allow); } @@ -1756,11 +2022,11 @@ static Reg asm_setup_call_slots(ASMState *as, IRIns *ir, const CCallInfo *ci) int nslots = 4, ngpr = REGARG_NUMGPR, nfpr = REGARG_NUMFPR; asm_collectargs(as, ir, ci, args); for (i = 0; i < nargs; i++) { - if (args[i] && irt_isfp(IR(args[i])->t) && + if (!LJ_SOFTFP && args[i] && irt_isfp(IR(args[i])->t) && nfpr > 0 && !(ci->flags & CCI_VARARG)) { nfpr--; ngpr -= irt_isnum(IR(args[i])->t) ? 2 : 1; - } else if (args[i] && irt_isnum(IR(args[i])->t)) { + } else if (!LJ_SOFTFP && args[i] && irt_isnum(IR(args[i])->t)) { nfpr = 0; ngpr = ngpr & ~1; if (ngpr > 0) ngpr -= 2; else nslots = (nslots+3) & ~1; diff --git a/Build/source/libs/luajit/LuaJIT-src/src/lj_asm_ppc.h b/Build/source/libs/luajit/LuaJIT-src/src/lj_asm_ppc.h index 7deeb66e51f..0ebed40fdaa 100644 --- a/Build/source/libs/luajit/LuaJIT-src/src/lj_asm_ppc.h +++ b/Build/source/libs/luajit/LuaJIT-src/src/lj_asm_ppc.h @@ -1,6 +1,6 @@ /* ** PPC IR assembler (SSA IR -> machine code). -** Copyright (C) 2005-2015 Mike Pall. See Copyright Notice in luajit.h +** Copyright (C) 2005-2016 Mike Pall. See Copyright Notice in luajit.h */ /* -- Register allocator extensions --------------------------------------- */ @@ -298,7 +298,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 ((ci->flags & CCI_NOFPRCLOBBER)) drop &= ~RSET_FPR; if (ra_hasreg(ir->r)) diff --git a/Build/source/libs/luajit/LuaJIT-src/src/lj_asm_x86.h b/Build/source/libs/luajit/LuaJIT-src/src/lj_asm_x86.h index 941d09192c2..512e05346e6 100644 --- a/Build/source/libs/luajit/LuaJIT-src/src/lj_asm_x86.h +++ b/Build/source/libs/luajit/LuaJIT-src/src/lj_asm_x86.h @@ -1,6 +1,6 @@ /* ** x86/x64 IR assembler (SSA IR -> machine code). -** Copyright (C) 2005-2015 Mike Pall. See Copyright Notice in luajit.h +** Copyright (C) 2005-2016 Mike Pall. See Copyright Notice in luajit.h */ /* -- Guard handling ------------------------------------------------------ */ @@ -531,7 +531,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 = (LJ_32 && (ir+1)->o == IR_HIOP); + int hiop = (LJ_32 && (ir+1)->o == IR_HIOP && !irt_isnil((ir+1)->t)); if ((ci->flags & CCI_NOFPRCLOBBER)) drop &= ~RSET_FPR; if (ra_hasreg(ir->r)) diff --git a/Build/source/libs/luajit/LuaJIT-src/src/lj_bc.c b/Build/source/libs/luajit/LuaJIT-src/src/lj_bc.c index a8f444c26e1..f038769c220 100644 --- a/Build/source/libs/luajit/LuaJIT-src/src/lj_bc.c +++ b/Build/source/libs/luajit/LuaJIT-src/src/lj_bc.c @@ -1,6 +1,6 @@ /* ** Bytecode instruction modes. -** Copyright (C) 2005-2015 Mike Pall. See Copyright Notice in luajit.h +** Copyright (C) 2005-2016 Mike Pall. See Copyright Notice in luajit.h */ #define lj_bc_c diff --git a/Build/source/libs/luajit/LuaJIT-src/src/lj_bc.h b/Build/source/libs/luajit/LuaJIT-src/src/lj_bc.h index 64c1bcda35a..78826068693 100644 --- a/Build/source/libs/luajit/LuaJIT-src/src/lj_bc.h +++ b/Build/source/libs/luajit/LuaJIT-src/src/lj_bc.h @@ -1,6 +1,6 @@ /* ** Bytecode instruction format. -** Copyright (C) 2005-2015 Mike Pall. See Copyright Notice in luajit.h +** Copyright (C) 2005-2016 Mike Pall. See Copyright Notice in luajit.h */ #ifndef _LJ_BC_H diff --git a/Build/source/libs/luajit/LuaJIT-src/src/lj_bcdump.h b/Build/source/libs/luajit/LuaJIT-src/src/lj_bcdump.h index c38983146bb..3752f151249 100644 --- a/Build/source/libs/luajit/LuaJIT-src/src/lj_bcdump.h +++ b/Build/source/libs/luajit/LuaJIT-src/src/lj_bcdump.h @@ -1,6 +1,6 @@ /* ** Bytecode dump definitions. -** Copyright (C) 2005-2015 Mike Pall. See Copyright Notice in luajit.h +** Copyright (C) 2005-2016 Mike Pall. See Copyright Notice in luajit.h */ #ifndef _LJ_BCDUMP_H diff --git a/Build/source/libs/luajit/LuaJIT-src/src/lj_bcread.c b/Build/source/libs/luajit/LuaJIT-src/src/lj_bcread.c index 5e5021773d7..455c9d8242d 100644 --- a/Build/source/libs/luajit/LuaJIT-src/src/lj_bcread.c +++ b/Build/source/libs/luajit/LuaJIT-src/src/lj_bcread.c @@ -1,6 +1,6 @@ /* ** Bytecode reader. -** Copyright (C) 2005-2015 Mike Pall. See Copyright Notice in luajit.h +** Copyright (C) 2005-2016 Mike Pall. See Copyright Notice in luajit.h */ #define lj_bcread_c diff --git a/Build/source/libs/luajit/LuaJIT-src/src/lj_bcwrite.c b/Build/source/libs/luajit/LuaJIT-src/src/lj_bcwrite.c index b2c09738387..4728305932a 100644 --- a/Build/source/libs/luajit/LuaJIT-src/src/lj_bcwrite.c +++ b/Build/source/libs/luajit/LuaJIT-src/src/lj_bcwrite.c @@ -1,6 +1,6 @@ /* ** Bytecode writer. -** Copyright (C) 2005-2015 Mike Pall. See Copyright Notice in luajit.h +** Copyright (C) 2005-2016 Mike Pall. See Copyright Notice in luajit.h */ #define lj_bcwrite_c diff --git a/Build/source/libs/luajit/LuaJIT-src/src/lj_buf.c b/Build/source/libs/luajit/LuaJIT-src/src/lj_buf.c index 023bb9aac8f..6251b075af2 100644 --- a/Build/source/libs/luajit/LuaJIT-src/src/lj_buf.c +++ b/Build/source/libs/luajit/LuaJIT-src/src/lj_buf.c @@ -1,6 +1,6 @@ /* ** Buffer handling. -** Copyright (C) 2005-2015 Mike Pall. See Copyright Notice in luajit.h +** Copyright (C) 2005-2016 Mike Pall. See Copyright Notice in luajit.h */ #define lj_buf_c @@ -77,7 +77,6 @@ SBuf *lj_buf_putmem(SBuf *sb, const void *q, MSize len) return sb; } -#if LJ_HASJIT SBuf * LJ_FASTCALL lj_buf_putchar(SBuf *sb, int c) { char *p = lj_buf_more(sb, 1); @@ -85,7 +84,6 @@ SBuf * LJ_FASTCALL lj_buf_putchar(SBuf *sb, int c) setsbufP(sb, p); return sb; } -#endif SBuf * LJ_FASTCALL lj_buf_putstr(SBuf *sb, GCstr *s) { @@ -186,7 +184,7 @@ SBuf *lj_buf_puttab(SBuf *sb, GCtab *t, GCstr *sep, int32_t i, int32_t e) } else if (tvisint(o)) { p = lj_strfmt_wint(lj_buf_more(sb, STRFMT_MAXBUF_INT+seplen), intV(o)); } else if (tvisnum(o)) { - p = lj_strfmt_wnum(lj_buf_more(sb, STRFMT_MAXBUF_NUM+seplen), o); + p = lj_buf_more(lj_strfmt_putfnum(sb, STRFMT_G14, numV(o)), seplen); } else { goto badtype; } diff --git a/Build/source/libs/luajit/LuaJIT-src/src/lj_buf.h b/Build/source/libs/luajit/LuaJIT-src/src/lj_buf.h index 1cf1780b020..fb632ee231c 100644 --- a/Build/source/libs/luajit/LuaJIT-src/src/lj_buf.h +++ b/Build/source/libs/luajit/LuaJIT-src/src/lj_buf.h @@ -1,6 +1,6 @@ /* ** Buffer handling. -** Copyright (C) 2005-2015 Mike Pall. See Copyright Notice in luajit.h +** Copyright (C) 2005-2016 Mike Pall. See Copyright Notice in luajit.h */ #ifndef _LJ_BUF_H @@ -67,9 +67,7 @@ static LJ_AINLINE char *lj_buf_more(SBuf *sb, MSize sz) /* Low-level buffer put operations */ LJ_FUNC SBuf *lj_buf_putmem(SBuf *sb, const void *q, MSize len); -#if LJ_HASJIT LJ_FUNC SBuf * LJ_FASTCALL lj_buf_putchar(SBuf *sb, int c); -#endif LJ_FUNC SBuf * LJ_FASTCALL lj_buf_putstr(SBuf *sb, GCstr *s); static LJ_AINLINE char *lj_buf_wmem(char *p, const void *q, MSize len) diff --git a/Build/source/libs/luajit/LuaJIT-src/src/lj_carith.c b/Build/source/libs/luajit/LuaJIT-src/src/lj_carith.c index 9032ea32410..6102dcaa776 100644 --- a/Build/source/libs/luajit/LuaJIT-src/src/lj_carith.c +++ b/Build/source/libs/luajit/LuaJIT-src/src/lj_carith.c @@ -1,6 +1,6 @@ /* ** C data arithmetic. -** Copyright (C) 2005-2015 Mike Pall. See Copyright Notice in luajit.h +** Copyright (C) 2005-2016 Mike Pall. See Copyright Notice in luajit.h */ #include "lj_obj.h" diff --git a/Build/source/libs/luajit/LuaJIT-src/src/lj_carith.h b/Build/source/libs/luajit/LuaJIT-src/src/lj_carith.h index da8320f3066..b3bdff8a761 100644 --- a/Build/source/libs/luajit/LuaJIT-src/src/lj_carith.h +++ b/Build/source/libs/luajit/LuaJIT-src/src/lj_carith.h @@ -1,6 +1,6 @@ /* ** C data arithmetic. -** Copyright (C) 2005-2015 Mike Pall. See Copyright Notice in luajit.h +** Copyright (C) 2005-2016 Mike Pall. See Copyright Notice in luajit.h */ #ifndef _LJ_CARITH_H diff --git a/Build/source/libs/luajit/LuaJIT-src/src/lj_ccall.c b/Build/source/libs/luajit/LuaJIT-src/src/lj_ccall.c index 5ab5b60daab..eb7c1ee0d58 100644 --- a/Build/source/libs/luajit/LuaJIT-src/src/lj_ccall.c +++ b/Build/source/libs/luajit/LuaJIT-src/src/lj_ccall.c @@ -1,6 +1,6 @@ /* ** FFI C call handling. -** Copyright (C) 2005-2015 Mike Pall. See Copyright Notice in luajit.h +** Copyright (C) 2005-2016 Mike Pall. See Copyright Notice in luajit.h */ #include "lj_obj.h" @@ -418,6 +418,18 @@ /* Complex values are returned in 1 or 2 FPRs. */ \ cc->retref = 0; +#if LJ_ABI_SOFTFP +#define CCALL_HANDLE_COMPLEXRET2 \ + if (ctr->size == 2*sizeof(float)) { /* Copy complex float from GPRs. */ \ + ((intptr_t *)dp)[0] = cc->gpr[0]; \ + ((intptr_t *)dp)[1] = cc->gpr[1]; \ + } else { /* Copy complex double from GPRs. */ \ + ((intptr_t *)dp)[0] = cc->gpr[0]; \ + ((intptr_t *)dp)[1] = cc->gpr[1]; \ + ((intptr_t *)dp)[2] = cc->gpr[2]; \ + ((intptr_t *)dp)[3] = cc->gpr[3]; \ + } +#else #define CCALL_HANDLE_COMPLEXRET2 \ if (ctr->size == 2*sizeof(float)) { /* Copy complex float from FPRs. */ \ ((float *)dp)[0] = cc->fpr[0].f; \ @@ -426,6 +438,7 @@ ((double *)dp)[0] = cc->fpr[0].d; \ ((double *)dp)[1] = cc->fpr[1].d; \ } +#endif #define CCALL_HANDLE_STRUCTARG \ /* Pass all structs by value in registers and/or on the stack. */ @@ -433,6 +446,22 @@ #define CCALL_HANDLE_COMPLEXARG \ /* Pass complex by value in 2 or 4 GPRs. */ +#define CCALL_HANDLE_GPR \ + if ((d->info & CTF_ALIGN) > CTALIGN_PTR) \ + ngpr = (ngpr + 1u) & ~1u; /* Align to regpair. */ \ + if (ngpr < maxgpr) { \ + dp = &cc->gpr[ngpr]; \ + if (ngpr + n > maxgpr) { \ + nsp += ngpr + n - maxgpr; /* Assumes contiguous gpr/stack fields. */ \ + if (nsp > CCALL_MAXSTACK) goto err_nyi; /* Too many arguments. */ \ + ngpr = maxgpr; \ + } else { \ + ngpr += n; \ + } \ + goto done; \ + } + +#if !LJ_ABI_SOFTFP /* MIPS32 hard-float */ #define CCALL_HANDLE_REGARG \ if (isfp && nfpr < CCALL_NARG_FPR && !(ct->info & CTF_VARARG)) { \ /* Try to pass argument in FPRs. */ \ @@ -441,24 +470,18 @@ goto done; \ } else { /* Try to pass argument in GPRs. */ \ nfpr = CCALL_NARG_FPR; \ - if ((d->info & CTF_ALIGN) > CTALIGN_PTR) \ - ngpr = (ngpr + 1u) & ~1u; /* Align to regpair. */ \ - if (ngpr < maxgpr) { \ - dp = &cc->gpr[ngpr]; \ - if (ngpr + n > maxgpr) { \ - nsp += ngpr + n - maxgpr; /* Assumes contiguous gpr/stack fields. */ \ - if (nsp > CCALL_MAXSTACK) goto err_nyi; /* Too many arguments. */ \ - ngpr = maxgpr; \ - } else { \ - ngpr += n; \ - } \ - goto done; \ - } \ + CCALL_HANDLE_GPR \ } +#else /* MIPS32 soft-float */ +#define CCALL_HANDLE_REGARG CCALL_HANDLE_GPR +#endif +#if !LJ_ABI_SOFTFP +/* On MIPS64 soft-float, position of float return values is endian-dependant. */ #define CCALL_HANDLE_RET \ if (ctype_isfp(ctr->info) && ctr->size == sizeof(float)) \ sp = (uint8_t *)&cc->fpr[0].f; +#endif #else #error "Missing calling convention definitions for this architecture" diff --git a/Build/source/libs/luajit/LuaJIT-src/src/lj_ccall.h b/Build/source/libs/luajit/LuaJIT-src/src/lj_ccall.h index 91983feebd7..a77afae3f87 100644 --- a/Build/source/libs/luajit/LuaJIT-src/src/lj_ccall.h +++ b/Build/source/libs/luajit/LuaJIT-src/src/lj_ccall.h @@ -1,6 +1,6 @@ /* ** FFI C call handling. -** Copyright (C) 2005-2015 Mike Pall. See Copyright Notice in luajit.h +** Copyright (C) 2005-2016 Mike Pall. See Copyright Notice in luajit.h */ #ifndef _LJ_CCALL_H @@ -98,9 +98,9 @@ typedef double FPRArg; #elif LJ_TARGET_MIPS #define CCALL_NARG_GPR 4 -#define CCALL_NARG_FPR 2 +#define CCALL_NARG_FPR (LJ_ABI_SOFTFP ? 0 : 2) #define CCALL_NRET_GPR 2 -#define CCALL_NRET_FPR 2 +#define CCALL_NRET_FPR (LJ_ABI_SOFTFP ? 0 : 2) #define CCALL_SPS_EXTRA 7 #define CCALL_SPS_FREE 1 diff --git a/Build/source/libs/luajit/LuaJIT-src/src/lj_ccallback.c b/Build/source/libs/luajit/LuaJIT-src/src/lj_ccallback.c index 065c329fa7e..43c29e41265 100644 --- a/Build/source/libs/luajit/LuaJIT-src/src/lj_ccallback.c +++ b/Build/source/libs/luajit/LuaJIT-src/src/lj_ccallback.c @@ -1,6 +1,6 @@ /* ** FFI C callback handling. -** Copyright (C) 2005-2015 Mike Pall. See Copyright Notice in luajit.h +** Copyright (C) 2005-2016 Mike Pall. See Copyright Notice in luajit.h */ #include "lj_obj.h" @@ -427,6 +427,15 @@ void lj_ccallback_mcode_free(CTState *cts) #elif LJ_TARGET_MIPS +#define CALLBACK_HANDLE_GPR \ + if (n > 1) ngpr = (ngpr + 1u) & ~1u; /* Align to regpair. */ \ + if (ngpr + n <= maxgpr) { \ + sp = &cts->cb.gpr[ngpr]; \ + ngpr += n; \ + goto done; \ + } + +#if !LJ_ABI_SOFTFP /* MIPS32 hard-float */ #define CALLBACK_HANDLE_REGARG \ if (isfp && nfpr < CCALL_NARG_FPR) { /* Try to pass argument in FPRs. */ \ sp = (void *)((uint8_t *)&cts->cb.fpr[nfpr] + ((LJ_BE && n==1) ? 4 : 0)); \ @@ -434,13 +443,13 @@ void lj_ccallback_mcode_free(CTState *cts) goto done; \ } else { /* Try to pass argument in GPRs. */ \ nfpr = CCALL_NARG_FPR; \ - if (n > 1) ngpr = (ngpr + 1u) & ~1u; /* Align to regpair. */ \ - if (ngpr + n <= maxgpr) { \ - sp = &cts->cb.gpr[ngpr]; \ - ngpr += n; \ - goto done; \ - } \ + CALLBACK_HANDLE_GPR \ } +#else /* MIPS32 soft-float */ +#define CALLBACK_HANDLE_REGARG \ + CALLBACK_HANDLE_GPR \ + UNUSED(isfp); +#endif #define CALLBACK_HANDLE_RET \ if (ctype_isfp(ctr->info) && ctr->size == sizeof(float)) \ diff --git a/Build/source/libs/luajit/LuaJIT-src/src/lj_ccallback.h b/Build/source/libs/luajit/LuaJIT-src/src/lj_ccallback.h index 83dbe048b5b..99c778d1a50 100644 --- a/Build/source/libs/luajit/LuaJIT-src/src/lj_ccallback.h +++ b/Build/source/libs/luajit/LuaJIT-src/src/lj_ccallback.h @@ -1,6 +1,6 @@ /* ** FFI C callback handling. -** Copyright (C) 2005-2015 Mike Pall. See Copyright Notice in luajit.h +** Copyright (C) 2005-2016 Mike Pall. See Copyright Notice in luajit.h */ #ifndef _LJ_CCALLBACK_H diff --git a/Build/source/libs/luajit/LuaJIT-src/src/lj_cconv.c b/Build/source/libs/luajit/LuaJIT-src/src/lj_cconv.c index 8a270766fb9..81f3c871c57 100644 --- a/Build/source/libs/luajit/LuaJIT-src/src/lj_cconv.c +++ b/Build/source/libs/luajit/LuaJIT-src/src/lj_cconv.c @@ -1,6 +1,6 @@ /* ** C type conversions. -** Copyright (C) 2005-2015 Mike Pall. See Copyright Notice in luajit.h +** Copyright (C) 2005-2016 Mike Pall. See Copyright Notice in luajit.h */ #include "lj_obj.h" diff --git a/Build/source/libs/luajit/LuaJIT-src/src/lj_cconv.h b/Build/source/libs/luajit/LuaJIT-src/src/lj_cconv.h index 2bd50ff46e9..35e72cbb00a 100644 --- a/Build/source/libs/luajit/LuaJIT-src/src/lj_cconv.h +++ b/Build/source/libs/luajit/LuaJIT-src/src/lj_cconv.h @@ -1,6 +1,6 @@ /* ** C type conversions. -** Copyright (C) 2005-2015 Mike Pall. See Copyright Notice in luajit.h +** Copyright (C) 2005-2016 Mike Pall. See Copyright Notice in luajit.h */ #ifndef _LJ_CCONV_H diff --git a/Build/source/libs/luajit/LuaJIT-src/src/lj_cdata.c b/Build/source/libs/luajit/LuaJIT-src/src/lj_cdata.c index 5cd2c1140ef..05e27dad1ab 100644 --- a/Build/source/libs/luajit/LuaJIT-src/src/lj_cdata.c +++ b/Build/source/libs/luajit/LuaJIT-src/src/lj_cdata.c @@ -1,6 +1,6 @@ /* ** C data management. -** Copyright (C) 2005-2015 Mike Pall. See Copyright Notice in luajit.h +** Copyright (C) 2005-2016 Mike Pall. See Copyright Notice in luajit.h */ #include "lj_obj.h" @@ -49,6 +49,15 @@ GCcdata *lj_cdata_newv(lua_State *L, CTypeID id, CTSize sz, CTSize align) return cd; } +/* Allocate arbitrary C data object. */ +GCcdata *lj_cdata_newx(CTState *cts, CTypeID id, CTSize sz, CTInfo info) +{ + if (!(info & CTF_VLA) && ctype_align(info) <= CT_MEMALIGN) + return lj_cdata_new(cts, id, sz); + else + return lj_cdata_newv(cts->L, id, sz, ctype_align(info)); +} + /* Free a C data object. */ void LJ_FASTCALL lj_cdata_free(global_State *g, GCcdata *cd) { diff --git a/Build/source/libs/luajit/LuaJIT-src/src/lj_cdata.h b/Build/source/libs/luajit/LuaJIT-src/src/lj_cdata.h index c8975be1c9f..ee5b740dbd7 100644 --- a/Build/source/libs/luajit/LuaJIT-src/src/lj_cdata.h +++ b/Build/source/libs/luajit/LuaJIT-src/src/lj_cdata.h @@ -1,6 +1,6 @@ /* ** C data management. -** Copyright (C) 2005-2015 Mike Pall. See Copyright Notice in luajit.h +** Copyright (C) 2005-2016 Mike Pall. See Copyright Notice in luajit.h */ #ifndef _LJ_CDATA_H @@ -60,6 +60,8 @@ static LJ_AINLINE GCcdata *lj_cdata_new_(lua_State *L, CTypeID id, CTSize sz) LJ_FUNC GCcdata *lj_cdata_newref(CTState *cts, const void *pp, CTypeID id); LJ_FUNC GCcdata *lj_cdata_newv(lua_State *L, CTypeID id, CTSize sz, CTSize align); +LJ_FUNC GCcdata *lj_cdata_newx(CTState *cts, CTypeID id, CTSize sz, + CTInfo info); LJ_FUNC void LJ_FASTCALL lj_cdata_free(global_State *g, GCcdata *cd); LJ_FUNC void lj_cdata_setfin(lua_State *L, GCcdata *cd, GCobj *obj, diff --git a/Build/source/libs/luajit/LuaJIT-src/src/lj_clib.c b/Build/source/libs/luajit/LuaJIT-src/src/lj_clib.c index 1e927ebe99e..922dbfaec8c 100644 --- a/Build/source/libs/luajit/LuaJIT-src/src/lj_clib.c +++ b/Build/source/libs/luajit/LuaJIT-src/src/lj_clib.c @@ -1,6 +1,6 @@ /* ** FFI C library loader. -** Copyright (C) 2005-2015 Mike Pall. See Copyright Notice in luajit.h +** Copyright (C) 2005-2016 Mike Pall. See Copyright Notice in luajit.h */ #include "lj_obj.h" diff --git a/Build/source/libs/luajit/LuaJIT-src/src/lj_clib.h b/Build/source/libs/luajit/LuaJIT-src/src/lj_clib.h index e5dc98e1cd7..ce3ab85a8bb 100644 --- a/Build/source/libs/luajit/LuaJIT-src/src/lj_clib.h +++ b/Build/source/libs/luajit/LuaJIT-src/src/lj_clib.h @@ -1,6 +1,6 @@ /* ** FFI C library loader. -** Copyright (C) 2005-2015 Mike Pall. See Copyright Notice in luajit.h +** Copyright (C) 2005-2016 Mike Pall. See Copyright Notice in luajit.h */ #ifndef _LJ_CLIB_H diff --git a/Build/source/libs/luajit/LuaJIT-src/src/lj_cparse.c b/Build/source/libs/luajit/LuaJIT-src/src/lj_cparse.c index f212bd36820..7ec4a5eebfa 100644 --- a/Build/source/libs/luajit/LuaJIT-src/src/lj_cparse.c +++ b/Build/source/libs/luajit/LuaJIT-src/src/lj_cparse.c @@ -1,6 +1,6 @@ /* ** C declaration parser. -** Copyright (C) 2005-2015 Mike Pall. See Copyright Notice in luajit.h +** Copyright (C) 2005-2016 Mike Pall. See Copyright Notice in luajit.h */ #include "lj_obj.h" @@ -1744,6 +1744,16 @@ static void cp_pragma(CPState *cp, BCLine pragmaline) } } +/* Handle line number. */ +static void cp_line(CPState *cp, BCLine hashline) +{ + BCLine newline = cp->val.u32; + /* TODO: Handle file name and include it in error messages. */ + while (cp->tok != CTOK_EOF && cp->linenumber == hashline) + cp_next(cp); + cp->linenumber = newline; +} + /* Parse multiple C declarations of types or extern identifiers. */ static void cp_decl_multi(CPState *cp) { @@ -1756,12 +1766,23 @@ static void cp_decl_multi(CPState *cp) continue; } if (cp->tok == '#') { /* Workaround, since we have no preprocessor, yet. */ - BCLine pragmaline = cp->linenumber; - if (!(cp_next(cp) == CTOK_IDENT && - cp->str->hash == H_(f5e6b4f8,1d509107))) /* pragma */ + BCLine hashline = cp->linenumber; + CPToken tok = cp_next(cp); + if (tok == CTOK_INTEGER) { + cp_line(cp, hashline); + continue; + } else if (tok == CTOK_IDENT && + cp->str->hash == H_(187aab88,fcb60b42)) { /* line */ + if (cp_next(cp) != CTOK_INTEGER) cp_err_token(cp, tok); + cp_line(cp, hashline); + continue; + } else if (tok == CTOK_IDENT && + cp->str->hash == H_(f5e6b4f8,1d509107)) { /* pragma */ + cp_pragma(cp, hashline); + continue; + } else { cp_errmsg(cp, cp->tok, LJ_ERR_XSYMBOL); - cp_pragma(cp, pragmaline); - continue; + } } scl = cp_decl_spec(cp, &decl, CDF_TYPEDEF|CDF_EXTERN|CDF_STATIC); if ((cp->tok == ';' || cp->tok == CTOK_EOF) && diff --git a/Build/source/libs/luajit/LuaJIT-src/src/lj_cparse.h b/Build/source/libs/luajit/LuaJIT-src/src/lj_cparse.h index 441580de6fe..bfd1a9bb4d0 100644 --- a/Build/source/libs/luajit/LuaJIT-src/src/lj_cparse.h +++ b/Build/source/libs/luajit/LuaJIT-src/src/lj_cparse.h @@ -1,6 +1,6 @@ /* ** C declaration parser. -** Copyright (C) 2005-2015 Mike Pall. See Copyright Notice in luajit.h +** Copyright (C) 2005-2016 Mike Pall. See Copyright Notice in luajit.h */ #ifndef _LJ_CPARSE_H diff --git a/Build/source/libs/luajit/LuaJIT-src/src/lj_crecord.c b/Build/source/libs/luajit/LuaJIT-src/src/lj_crecord.c index e200cc99423..c0f7e3d7957 100644 --- a/Build/source/libs/luajit/LuaJIT-src/src/lj_crecord.c +++ b/Build/source/libs/luajit/LuaJIT-src/src/lj_crecord.c @@ -1,6 +1,6 @@ /* ** Trace recorder for C data operations. -** Copyright (C) 2005-2015 Mike Pall. See Copyright Notice in luajit.h +** Copyright (C) 2005-2016 Mike Pall. See Copyright Notice in luajit.h */ #define lj_ffrecord_c diff --git a/Build/source/libs/luajit/LuaJIT-src/src/lj_crecord.h b/Build/source/libs/luajit/LuaJIT-src/src/lj_crecord.h index 59f342a1d9a..7a058813191 100644 --- a/Build/source/libs/luajit/LuaJIT-src/src/lj_crecord.h +++ b/Build/source/libs/luajit/LuaJIT-src/src/lj_crecord.h @@ -1,6 +1,6 @@ /* ** Trace recorder for C data operations. -** Copyright (C) 2005-2015 Mike Pall. See Copyright Notice in luajit.h +** Copyright (C) 2005-2016 Mike Pall. See Copyright Notice in luajit.h */ #ifndef _LJ_CRECORD_H diff --git a/Build/source/libs/luajit/LuaJIT-src/src/lj_ctype.c b/Build/source/libs/luajit/LuaJIT-src/src/lj_ctype.c index 2e23c994bb0..bc47cc5b927 100644 --- a/Build/source/libs/luajit/LuaJIT-src/src/lj_ctype.c +++ b/Build/source/libs/luajit/LuaJIT-src/src/lj_ctype.c @@ -1,6 +1,6 @@ /* ** C type management. -** Copyright (C) 2005-2015 Mike Pall. See Copyright Notice in luajit.h +** Copyright (C) 2005-2016 Mike Pall. See Copyright Notice in luajit.h */ #include "lj_obj.h" @@ -14,6 +14,7 @@ #include "lj_strfmt.h" #include "lj_ctype.h" #include "lj_ccallback.h" +#include "lj_buf.h" /* -- C type definitions -------------------------------------------------- */ @@ -38,6 +39,8 @@ _("uint64_t", UINT64) \ _("intptr_t", INT_PSZ) \ _("uintptr_t", UINT_PSZ) \ + /* From POSIX. */ \ + _("ssize_t", INT_PSZ) \ /* End of typedef list. */ /* Keywords (only the ones we actually care for). */ @@ -569,19 +572,18 @@ GCstr *lj_ctype_repr_int64(lua_State *L, uint64_t n, int isunsigned) /* Convert complex to string with 'i' or 'I' suffix. */ GCstr *lj_ctype_repr_complex(lua_State *L, void *sp, CTSize size) { - char buf[2*STRFMT_MAXBUF_NUM+2+1], *p = buf; + SBuf *sb = lj_buf_tmp_(L); TValue re, im; if (size == 2*sizeof(double)) { re.n = *(double *)sp; im.n = ((double *)sp)[1]; } else { re.n = (double)*(float *)sp; im.n = (double)((float *)sp)[1]; } - p = lj_strfmt_wnum(p, &re); - if (!(im.u32.hi & 0x80000000u) || im.n != im.n) *p++ = '+'; - p = lj_strfmt_wnum(p, &im); - *p = *(p-1) >= 'a' ? 'I' : 'i'; - p++; - return lj_str_new(L, buf, p-buf); + lj_strfmt_putfnum(sb, STRFMT_G14, re.n); + if (!(im.u32.hi & 0x80000000u) || im.n != im.n) lj_buf_putchar(sb, '+'); + lj_strfmt_putfnum(sb, STRFMT_G14, im.n); + lj_buf_putchar(sb, sbufP(sb)[-1] >= 'a' ? 'I' : 'i'); + return lj_buf_str(L, sb); } /* -- C type state -------------------------------------------------------- */ diff --git a/Build/source/libs/luajit/LuaJIT-src/src/lj_ctype.h b/Build/source/libs/luajit/LuaJIT-src/src/lj_ctype.h index 6639547a431..e9b426f0dc9 100644 --- a/Build/source/libs/luajit/LuaJIT-src/src/lj_ctype.h +++ b/Build/source/libs/luajit/LuaJIT-src/src/lj_ctype.h @@ -1,6 +1,6 @@ /* ** C type management. -** Copyright (C) 2005-2015 Mike Pall. See Copyright Notice in luajit.h +** Copyright (C) 2005-2016 Mike Pall. See Copyright Notice in luajit.h */ #ifndef _LJ_CTYPE_H diff --git a/Build/source/libs/luajit/LuaJIT-src/src/lj_debug.c b/Build/source/libs/luajit/LuaJIT-src/src/lj_debug.c index 3226d03b9e1..153035a90b2 100644 --- a/Build/source/libs/luajit/LuaJIT-src/src/lj_debug.c +++ b/Build/source/libs/luajit/LuaJIT-src/src/lj_debug.c @@ -1,6 +1,6 @@ /* ** Debugging and introspection. -** Copyright (C) 2005-2015 Mike Pall. See Copyright Notice in luajit.h +** Copyright (C) 2005-2016 Mike Pall. See Copyright Notice in luajit.h */ #define lj_debug_c diff --git a/Build/source/libs/luajit/LuaJIT-src/src/lj_debug.h b/Build/source/libs/luajit/LuaJIT-src/src/lj_debug.h index 11d308a41b3..1028688d145 100644 --- a/Build/source/libs/luajit/LuaJIT-src/src/lj_debug.h +++ b/Build/source/libs/luajit/LuaJIT-src/src/lj_debug.h @@ -1,6 +1,6 @@ /* ** Debugging and introspection. -** Copyright (C) 2005-2015 Mike Pall. See Copyright Notice in luajit.h +** Copyright (C) 2005-2016 Mike Pall. See Copyright Notice in luajit.h */ #ifndef _LJ_DEBUG_H diff --git a/Build/source/libs/luajit/LuaJIT-src/src/lj_def.h b/Build/source/libs/luajit/LuaJIT-src/src/lj_def.h index 04bf00c89be..6b898838ef2 100644 --- a/Build/source/libs/luajit/LuaJIT-src/src/lj_def.h +++ b/Build/source/libs/luajit/LuaJIT-src/src/lj_def.h @@ -1,6 +1,6 @@ /* ** LuaJIT common internal definitions. -** Copyright (C) 2005-2015 Mike Pall. See Copyright Notice in luajit.h +** Copyright (C) 2005-2016 Mike Pall. See Copyright Notice in luajit.h */ #ifndef _LJ_DEF_H diff --git a/Build/source/libs/luajit/LuaJIT-src/src/lj_dispatch.c b/Build/source/libs/luajit/LuaJIT-src/src/lj_dispatch.c index 1a07371cacf..36b920add7f 100644 --- a/Build/source/libs/luajit/LuaJIT-src/src/lj_dispatch.c +++ b/Build/source/libs/luajit/LuaJIT-src/src/lj_dispatch.c @@ -1,6 +1,6 @@ /* ** Instruction dispatch handling. -** Copyright (C) 2005-2015 Mike Pall. See Copyright Notice in luajit.h +** Copyright (C) 2005-2016 Mike Pall. See Copyright Notice in luajit.h */ #define lj_dispatch_c diff --git a/Build/source/libs/luajit/LuaJIT-src/src/lj_dispatch.h b/Build/source/libs/luajit/LuaJIT-src/src/lj_dispatch.h index 1e247e38286..827080770da 100644 --- a/Build/source/libs/luajit/LuaJIT-src/src/lj_dispatch.h +++ b/Build/source/libs/luajit/LuaJIT-src/src/lj_dispatch.h @@ -1,6 +1,6 @@ /* ** Instruction dispatch handling. -** Copyright (C) 2005-2015 Mike Pall. See Copyright Notice in luajit.h +** Copyright (C) 2005-2016 Mike Pall. See Copyright Notice in luajit.h */ #ifndef _LJ_DISPATCH_H @@ -14,6 +14,22 @@ #if LJ_TARGET_MIPS /* Need our own global offset table for the dreaded MIPS calling conventions. */ + +#ifndef _LJ_VM_H +LJ_ASMF int32_t LJ_FASTCALL lj_vm_modi(int32_t a, int32_t b); +#endif + +#if LJ_SOFTFP +#ifndef _LJ_IRCALL_H +extern double __adddf3(double a, double b); +extern double __subdf3(double a, double b); +extern double __muldf3(double a, double b); +extern double __divdf3(double a, double b); +#endif +#define SFGOTDEF(_) _(sqrt) _(__adddf3) _(__subdf3) _(__muldf3) _(__divdf3) +#else +#define SFGOTDEF(_) +#endif #if LJ_HASJIT #define JITGOTDEF(_) _(lj_trace_exit) _(lj_trace_hot) #else @@ -28,18 +44,19 @@ #define GOTDEF(_) \ _(floor) _(ceil) _(trunc) _(log) _(log10) _(exp) _(sin) _(cos) _(tan) \ _(asin) _(acos) _(atan) _(sinh) _(cosh) _(tanh) _(frexp) _(modf) _(atan2) \ - _(pow) _(fmod) _(ldexp) \ + _(pow) _(fmod) _(ldexp) _(lj_vm_modi) \ _(lj_dispatch_call) _(lj_dispatch_ins) _(lj_dispatch_stitch) \ _(lj_dispatch_profile) _(lj_err_throw) \ _(lj_ffh_coroutine_wrap_err) _(lj_func_closeuv) _(lj_func_newL_gc) \ _(lj_gc_barrieruv) _(lj_gc_step) _(lj_gc_step_fixtop) _(lj_meta_arith) \ _(lj_meta_call) _(lj_meta_cat) _(lj_meta_comp) _(lj_meta_equal) \ _(lj_meta_for) _(lj_meta_istype) _(lj_meta_len) _(lj_meta_tget) \ - _(lj_meta_tset) _(lj_state_growstack) _(lj_strfmt_num) \ + _(lj_meta_tset) _(lj_state_growstack) _(lj_strfmt_number) \ _(lj_str_new) _(lj_tab_dup) _(lj_tab_get) _(lj_tab_getinth) _(lj_tab_len) \ _(lj_tab_new) _(lj_tab_newkey) _(lj_tab_next) _(lj_tab_reasize) \ _(lj_tab_setinth) _(lj_buf_putstr_reverse) _(lj_buf_putstr_lower) \ - _(lj_buf_putstr_upper) _(lj_buf_tostr) JITGOTDEF(_) FFIGOTDEF(_) + _(lj_buf_putstr_upper) _(lj_buf_tostr) \ + JITGOTDEF(_) FFIGOTDEF(_) SFGOTDEF(_) enum { #define GOTENUM(name) LJ_GOT_##name, diff --git a/Build/source/libs/luajit/LuaJIT-src/src/lj_emit_arm.h b/Build/source/libs/luajit/LuaJIT-src/src/lj_emit_arm.h index 45ce519ef6b..47fee5fcd85 100644 --- a/Build/source/libs/luajit/LuaJIT-src/src/lj_emit_arm.h +++ b/Build/source/libs/luajit/LuaJIT-src/src/lj_emit_arm.h @@ -1,6 +1,6 @@ /* ** ARM instruction emitter. -** Copyright (C) 2005-2015 Mike Pall. See Copyright Notice in luajit.h +** Copyright (C) 2005-2016 Mike Pall. See Copyright Notice in luajit.h */ /* -- Constant encoding --------------------------------------------------- */ diff --git a/Build/source/libs/luajit/LuaJIT-src/src/lj_emit_mips.h b/Build/source/libs/luajit/LuaJIT-src/src/lj_emit_mips.h index 8e7ee66fb1a..fdebe94b49b 100644 --- a/Build/source/libs/luajit/LuaJIT-src/src/lj_emit_mips.h +++ b/Build/source/libs/luajit/LuaJIT-src/src/lj_emit_mips.h @@ -1,6 +1,6 @@ /* ** MIPS instruction emitter. -** Copyright (C) 2005-2015 Mike Pall. See Copyright Notice in luajit.h +** Copyright (C) 2005-2016 Mike Pall. See Copyright Notice in luajit.h */ /* -- Emit basic instructions --------------------------------------------- */ @@ -152,16 +152,18 @@ static void emit_jmp(ASMState *as, MCode *target) emit_branch(as, MIPSI_B, RID_ZERO, RID_ZERO, (target)); } -static void emit_call(ASMState *as, void *target) +static void emit_call(ASMState *as, void *target, int needcfa) { MCode *p = as->mcp; *--p = MIPSI_NOP; - if ((((uintptr_t)target ^ (uintptr_t)p) >> 28) == 0) + if ((((uintptr_t)target ^ (uintptr_t)p) >> 28) == 0) { *--p = MIPSI_JAL | (((uintptr_t)target >>2) & 0x03ffffffu); - else /* Target out of range: need indirect call. */ + } else { /* Target out of range: need indirect call. */ *--p = MIPSI_JALR | MIPSF_S(RID_CFUNCADDR); + needcfa = 1; + } as->mcp = p; - ra_allockreg(as, i32ptr(target), RID_CFUNCADDR); + if (needcfa) ra_allockreg(as, i32ptr(target), RID_CFUNCADDR); } /* -- Emit generic operations --------------------------------------------- */ diff --git a/Build/source/libs/luajit/LuaJIT-src/src/lj_emit_ppc.h b/Build/source/libs/luajit/LuaJIT-src/src/lj_emit_ppc.h index 087860ed382..4eb933ea549 100644 --- a/Build/source/libs/luajit/LuaJIT-src/src/lj_emit_ppc.h +++ b/Build/source/libs/luajit/LuaJIT-src/src/lj_emit_ppc.h @@ -1,6 +1,6 @@ /* ** PPC instruction emitter. -** Copyright (C) 2005-2015 Mike Pall. See Copyright Notice in luajit.h +** Copyright (C) 2005-2016 Mike Pall. See Copyright Notice in luajit.h */ /* -- Emit basic instructions --------------------------------------------- */ diff --git a/Build/source/libs/luajit/LuaJIT-src/src/lj_emit_x86.h b/Build/source/libs/luajit/LuaJIT-src/src/lj_emit_x86.h index ac42db3e20f..caf30859ace 100644 --- a/Build/source/libs/luajit/LuaJIT-src/src/lj_emit_x86.h +++ b/Build/source/libs/luajit/LuaJIT-src/src/lj_emit_x86.h @@ -1,6 +1,6 @@ /* ** x86/x64 instruction emitter. -** Copyright (C) 2005-2015 Mike Pall. See Copyright Notice in luajit.h +** Copyright (C) 2005-2016 Mike Pall. See Copyright Notice in luajit.h */ /* -- Emit basic instructions --------------------------------------------- */ diff --git a/Build/source/libs/luajit/LuaJIT-src/src/lj_err.c b/Build/source/libs/luajit/LuaJIT-src/src/lj_err.c index 9ac0c988fc9..01b86d1129d 100644 --- a/Build/source/libs/luajit/LuaJIT-src/src/lj_err.c +++ b/Build/source/libs/luajit/LuaJIT-src/src/lj_err.c @@ -1,6 +1,6 @@ /* ** Error handling. -** Copyright (C) 2005-2015 Mike Pall. See Copyright Notice in luajit.h +** Copyright (C) 2005-2016 Mike Pall. See Copyright Notice in luajit.h */ #define lj_err_c @@ -190,13 +190,6 @@ static void *err_unwind(lua_State *L, void *stopcf, int errcode) ** since various OS, distros and compilers mess up the header installation. */ -typedef struct _Unwind_Exception -{ - uint64_t exclass; - void (*excleanup)(int, struct _Unwind_Exception *); - uintptr_t p1, p2; -} __attribute__((__aligned__)) _Unwind_Exception; - typedef struct _Unwind_Context _Unwind_Context; #define _URC_OK 0 @@ -206,8 +199,20 @@ typedef struct _Unwind_Context _Unwind_Context; #define _URC_CONTINUE_UNWIND 8 #define _URC_FAILURE 9 +#define LJ_UEXCLASS 0x4c55414a49543200ULL /* LUAJIT2\0 */ +#define LJ_UEXCLASS_MAKE(c) (LJ_UEXCLASS | (uint64_t)(c)) +#define LJ_UEXCLASS_CHECK(cl) (((cl) ^ LJ_UEXCLASS) <= 0xff) +#define LJ_UEXCLASS_ERRCODE(cl) ((int)((cl) & 0xff)) + #if !LJ_TARGET_ARM +typedef struct _Unwind_Exception +{ + uint64_t exclass; + void (*excleanup)(int, struct _Unwind_Exception *); + uintptr_t p1, p2; +} __attribute__((__aligned__)) _Unwind_Exception; + extern uintptr_t _Unwind_GetCFA(_Unwind_Context *); extern void _Unwind_SetGR(_Unwind_Context *, int, uintptr_t); extern void _Unwind_SetIP(_Unwind_Context *, uintptr_t); @@ -219,11 +224,6 @@ extern int _Unwind_RaiseException(_Unwind_Exception *); #define _UA_HANDLER_FRAME 4 #define _UA_FORCE_UNWIND 8 -#define LJ_UEXCLASS 0x4c55414a49543200ULL /* LUAJIT2\0 */ -#define LJ_UEXCLASS_MAKE(c) (LJ_UEXCLASS | (uint64_t)(c)) -#define LJ_UEXCLASS_CHECK(cl) (((cl) ^ LJ_UEXCLASS) <= 0xff) -#define LJ_UEXCLASS_ERRCODE(cl) ((int)((cl) & 0xff)) - /* DWARF2 personality handler referenced from interpreter .eh_frame. */ LJ_FUNCA int lj_err_unwind_dwarf(int version, int actions, uint64_t uexclass, _Unwind_Exception *uex, _Unwind_Context *ctx) @@ -302,10 +302,23 @@ static void err_raise_ext(int errcode) } #endif -#else +#else /* LJ_TARGET_ARM */ + +#define _US_VIRTUAL_UNWIND_FRAME 0 +#define _US_UNWIND_FRAME_STARTING 1 +#define _US_ACTION_MASK 3 +#define _US_FORCE_UNWIND 8 + +typedef struct _Unwind_Control_Block _Unwind_Control_Block; +typedef struct _Unwind_Context _Unwind_Context; + +struct _Unwind_Control_Block { + uint64_t exclass; + uint32_t misc[20]; +}; -extern void _Unwind_DeleteException(void *); -extern int __gnu_unwind_frame (void *, _Unwind_Context *); +extern int _Unwind_RaiseException(_Unwind_Control_Block *); +extern int __gnu_unwind_frame(_Unwind_Control_Block *, _Unwind_Context *); extern int _Unwind_VRS_Set(_Unwind_Context *, int, uint32_t, int, void *); extern int _Unwind_VRS_Get(_Unwind_Context *, int, uint32_t, int, void *); @@ -321,34 +334,57 @@ static inline void _Unwind_SetGR(_Unwind_Context *ctx, int r, uint32_t v) _Unwind_VRS_Set(ctx, 0, r, 0, &v); } -#define _US_VIRTUAL_UNWIND_FRAME 0 -#define _US_UNWIND_FRAME_STARTING 1 -#define _US_ACTION_MASK 3 -#define _US_FORCE_UNWIND 8 +extern void lj_vm_unwind_ext(void); /* ARM unwinder personality handler referenced from interpreter .ARM.extab. */ -LJ_FUNCA int lj_err_unwind_arm(int state, void *ucb, _Unwind_Context *ctx) +LJ_FUNCA int lj_err_unwind_arm(int state, _Unwind_Control_Block *ucb, + _Unwind_Context *ctx) { void *cf = (void *)_Unwind_GetGR(ctx, 13); lua_State *L = cframe_L(cf); - if ((state & _US_ACTION_MASK) == _US_VIRTUAL_UNWIND_FRAME) { - setstrV(L, L->top++, lj_err_str(L, LJ_ERR_ERRCPP)); + int errcode; + + switch ((state & _US_ACTION_MASK)) { + case _US_VIRTUAL_UNWIND_FRAME: + if ((state & _US_FORCE_UNWIND)) break; return _URC_HANDLER_FOUND; - } - if ((state&(_US_ACTION_MASK|_US_FORCE_UNWIND)) == _US_UNWIND_FRAME_STARTING) { - _Unwind_DeleteException(ucb); - _Unwind_SetGR(ctx, 15, (uint32_t)(void *)lj_err_throw); - _Unwind_SetGR(ctx, 0, (uint32_t)L); - _Unwind_SetGR(ctx, 1, (uint32_t)LUA_ERRRUN); + case _US_UNWIND_FRAME_STARTING: + if (LJ_UEXCLASS_CHECK(ucb->exclass)) { + errcode = LJ_UEXCLASS_ERRCODE(ucb->exclass); + } else { + errcode = LUA_ERRRUN; + setstrV(L, L->top++, lj_err_str(L, LJ_ERR_ERRCPP)); + } + cf = err_unwind(L, cf, errcode); + if ((state & _US_FORCE_UNWIND) || cf == NULL) break; + _Unwind_SetGR(ctx, 15, (uint32_t)lj_vm_unwind_ext); + _Unwind_SetGR(ctx, 0, (uint32_t)ucb); + _Unwind_SetGR(ctx, 1, (uint32_t)errcode); + _Unwind_SetGR(ctx, 2, cframe_unwind_ff(cf) ? + (uint32_t)lj_vm_unwind_ff_eh : + (uint32_t)lj_vm_unwind_c_eh); return _URC_INSTALL_CONTEXT; + default: + return _URC_FAILURE; } if (__gnu_unwind_frame(ucb, ctx) != _URC_OK) return _URC_FAILURE; return _URC_CONTINUE_UNWIND; } +#if LJ_UNWIND_EXT +static __thread _Unwind_Control_Block static_uex; + +static void err_raise_ext(int errcode) +{ + memset(&static_uex, 0, sizeof(static_uex)); + static_uex.exclass = LJ_UEXCLASS_MAKE(errcode); + _Unwind_RaiseException(&static_uex); +} #endif +#endif /* LJ_TARGET_ARM */ + #elif LJ_TARGET_X64 && LJ_ABI_WIN /* diff --git a/Build/source/libs/luajit/LuaJIT-src/src/lj_err.h b/Build/source/libs/luajit/LuaJIT-src/src/lj_err.h index 03a56f0362c..6c7576137b5 100644 --- a/Build/source/libs/luajit/LuaJIT-src/src/lj_err.h +++ b/Build/source/libs/luajit/LuaJIT-src/src/lj_err.h @@ -1,6 +1,6 @@ /* ** Error handling. -** Copyright (C) 2005-2015 Mike Pall. See Copyright Notice in luajit.h +** Copyright (C) 2005-2016 Mike Pall. See Copyright Notice in luajit.h */ #ifndef _LJ_ERR_H diff --git a/Build/source/libs/luajit/LuaJIT-src/src/lj_errmsg.h b/Build/source/libs/luajit/LuaJIT-src/src/lj_errmsg.h index 7717665b038..0ed8f4e7398 100644 --- a/Build/source/libs/luajit/LuaJIT-src/src/lj_errmsg.h +++ b/Build/source/libs/luajit/LuaJIT-src/src/lj_errmsg.h @@ -1,6 +1,6 @@ /* ** VM error messages. -** Copyright (C) 2005-2015 Mike Pall. See Copyright Notice in luajit.h +** Copyright (C) 2005-2016 Mike Pall. See Copyright Notice in luajit.h */ /* This file may be included multiple times with different ERRDEF macros. */ diff --git a/Build/source/libs/luajit/LuaJIT-src/src/lj_ff.h b/Build/source/libs/luajit/LuaJIT-src/src/lj_ff.h index 73dad9695a6..9af3b12d265 100644 --- a/Build/source/libs/luajit/LuaJIT-src/src/lj_ff.h +++ b/Build/source/libs/luajit/LuaJIT-src/src/lj_ff.h @@ -1,6 +1,6 @@ /* ** Fast function IDs. -** Copyright (C) 2005-2015 Mike Pall. See Copyright Notice in luajit.h +** Copyright (C) 2005-2016 Mike Pall. See Copyright Notice in luajit.h */ #ifndef _LJ_FF_H diff --git a/Build/source/libs/luajit/LuaJIT-src/src/lj_ffrecord.c b/Build/source/libs/luajit/LuaJIT-src/src/lj_ffrecord.c index a08113ca386..d05dc5d710d 100644 --- a/Build/source/libs/luajit/LuaJIT-src/src/lj_ffrecord.c +++ b/Build/source/libs/luajit/LuaJIT-src/src/lj_ffrecord.c @@ -1,6 +1,6 @@ /* ** Fast function call recorder. -** Copyright (C) 2005-2015 Mike Pall. See Copyright Notice in luajit.h +** Copyright (C) 2005-2016 Mike Pall. See Copyright Notice in luajit.h */ #define lj_ffrecord_c @@ -96,18 +96,10 @@ static ptrdiff_t results_wanted(jit_State *J) return -1; } -#ifdef LUAJIT_TRACE_STITCHING -/* This feature is disabled for now due to a design mistake. Sorry. -** -** It causes unpredictable behavior and crashes when a full trace flush -** happens with a stitching continuation still in the stack somewhere. -*/ - /* Trace stitching: add continuation below frame to start a new trace. */ static void recff_stitch(jit_State *J) { ASMFunction cont = lj_cont_stitch; - TraceNo traceno = J->cur.traceno; lua_State *L = J->L; TValue *base = L->base; const BCIns *pc = frame_pc(base-1); @@ -120,7 +112,7 @@ static void recff_stitch(jit_State *J) setframe_ftsz(base+1, ((char *)(base+1) - (char *)pframe) + FRAME_CONT); setcont(base, cont); setframe_pc(base, pc); - if (LJ_DUALNUM) setintV(base-1, traceno); else base[-1].u64 = traceno; + setnilV(base-1); /* Incorrect, but rec_check_slots() won't run anymore. */ L->base += 2; L->top += 2; @@ -132,7 +124,9 @@ static void recff_stitch(jit_State *J) trcont = lj_ir_kptr(J, (void *)cont); #endif J->base[0] = trcont | TREF_CONT; - J->base[-1] = LJ_DUALNUM ? lj_ir_kint(J,traceno) : lj_ir_knum_u64(J,traceno); + J->ktracep = lj_ir_k64_reserve(J); + lua_assert(irt_toitype_(IRT_P64) == LJ_TTRACE); + J->base[-1] = emitir(IRT(IR_XLOAD, IRT_P64), lj_ir_kptr(J, &J->ktracep->gcr), 0); J->base += 2; J->baseslot += 2; J->framedepth++; @@ -181,31 +175,6 @@ static void LJ_FASTCALL recff_nyi(jit_State *J, RecordFFData *rd) /* Must stop the trace for classic C functions with arbitrary side-effects. */ #define recff_c recff_nyi -#else -/* Fallback handler for fast functions that are not recorded (yet). */ -static void LJ_FASTCALL recff_nyi(jit_State *J, RecordFFData *rd) -{ - setfuncV(J->L, &J->errinfo, J->fn); - lj_trace_err_info(J, LJ_TRERR_NYIFF); - UNUSED(rd); -} - -/* Throw error for unsupported variant of fast function. */ -LJ_NORET static void recff_nyiu(jit_State *J, RecordFFData *rd) -{ - setfuncV(J->L, &J->errinfo, J->fn); - lj_trace_err_info(J, LJ_TRERR_NYIFFU); - UNUSED(rd); -} - -/* Must abort the trace for classic C functions with arbitrary side-effects. */ -static void LJ_FASTCALL recff_c(jit_State *J, RecordFFData *rd) -{ - setfuncV(J->L, &J->errinfo, J->fn); - lj_trace_err_info(J, LJ_TRERR_NYICF); - UNUSED(rd); -} -#endif /* Emit BUFHDR for the global temporary buffer. */ static TRef recff_bufhdr(jit_State *J) @@ -466,11 +435,12 @@ static void LJ_FASTCALL recff_ipairs_aux(jit_State *J, RecordFFData *rd) static void LJ_FASTCALL recff_xpairs(jit_State *J, RecordFFData *rd) { - if (!(LJ_52 && recff_metacall(J, rd, MM_ipairs))) { - TRef tab = J->base[0]; - if (tref_istab(tab)) { + TRef tr = J->base[0]; + if (!((LJ_52 || (LJ_HASFFI && tref_iscdata(tr))) && + recff_metacall(J, rd, MM_pairs + rd->data))) { + if (tref_istab(tr)) { J->base[0] = lj_ir_kfunc(J, funcV(&J->fn->c.upvalue[0])); - J->base[1] = tab; + J->base[1] = tr; J->base[2] = rd->data ? lj_ir_kint(J, 0) : TREF_NIL; rd->nres = 3; } /* else: Interpreter will throw. */ diff --git a/Build/source/libs/luajit/LuaJIT-src/src/lj_ffrecord.h b/Build/source/libs/luajit/LuaJIT-src/src/lj_ffrecord.h index f858ca29cfc..7a188beb298 100644 --- a/Build/source/libs/luajit/LuaJIT-src/src/lj_ffrecord.h +++ b/Build/source/libs/luajit/LuaJIT-src/src/lj_ffrecord.h @@ -1,6 +1,6 @@ /* ** Fast function call recorder. -** Copyright (C) 2005-2015 Mike Pall. See Copyright Notice in luajit.h +** Copyright (C) 2005-2016 Mike Pall. See Copyright Notice in luajit.h */ #ifndef _LJ_FFRECORD_H diff --git a/Build/source/libs/luajit/LuaJIT-src/src/lj_frame.h b/Build/source/libs/luajit/LuaJIT-src/src/lj_frame.h index a86c36be7e5..fc0e281c2e0 100644 --- a/Build/source/libs/luajit/LuaJIT-src/src/lj_frame.h +++ b/Build/source/libs/luajit/LuaJIT-src/src/lj_frame.h @@ -1,6 +1,6 @@ /* ** Stack frames. -** Copyright (C) 2005-2015 Mike Pall. See Copyright Notice in luajit.h +** Copyright (C) 2005-2016 Mike Pall. See Copyright Notice in luajit.h */ #ifndef _LJ_FRAME_H @@ -218,6 +218,7 @@ enum { LJ_CONT_TAILCALL, LJ_CONT_FFI_CALLBACK }; /* Special continuations. */ #define CFRAME_SHIFT_MULTRES 3 #endif #elif LJ_TARGET_MIPS +#if LJ_ARCH_HASFPU #define CFRAME_OFS_ERRF 124 #define CFRAME_OFS_NRES 120 #define CFRAME_OFS_PREV 116 @@ -227,6 +228,16 @@ enum { LJ_CONT_TAILCALL, LJ_CONT_FFI_CALLBACK }; /* Special continuations. */ #define CFRAME_SIZE 112 #define CFRAME_SHIFT_MULTRES 3 #else +#define CFRAME_OFS_ERRF 76 +#define CFRAME_OFS_NRES 72 +#define CFRAME_OFS_PREV 68 +#define CFRAME_OFS_L 64 +#define CFRAME_OFS_PC 20 +#define CFRAME_OFS_MULTRES 16 +#define CFRAME_SIZE 64 +#define CFRAME_SHIFT_MULTRES 3 +#endif +#else #error "Missing CFRAME_* definitions for this architecture" #endif diff --git a/Build/source/libs/luajit/LuaJIT-src/src/lj_func.c b/Build/source/libs/luajit/LuaJIT-src/src/lj_func.c index eb8a9dbbfd8..431a56d76df 100644 --- a/Build/source/libs/luajit/LuaJIT-src/src/lj_func.c +++ b/Build/source/libs/luajit/LuaJIT-src/src/lj_func.c @@ -1,6 +1,6 @@ /* ** Function handling (prototypes, functions and upvalues). -** Copyright (C) 2005-2015 Mike Pall. See Copyright Notice in luajit.h +** Copyright (C) 2005-2016 Mike Pall. See Copyright Notice in luajit.h ** ** Portions taken verbatim or adapted from the Lua interpreter. ** Copyright (C) 1994-2008 Lua.org, PUC-Rio. See Copyright Notice in lua.h diff --git a/Build/source/libs/luajit/LuaJIT-src/src/lj_func.h b/Build/source/libs/luajit/LuaJIT-src/src/lj_func.h index a6e534e7739..e0c3c555ed3 100644 --- a/Build/source/libs/luajit/LuaJIT-src/src/lj_func.h +++ b/Build/source/libs/luajit/LuaJIT-src/src/lj_func.h @@ -1,6 +1,6 @@ /* ** Function handling (prototypes, functions and upvalues). -** Copyright (C) 2005-2015 Mike Pall. See Copyright Notice in luajit.h +** Copyright (C) 2005-2016 Mike Pall. See Copyright Notice in luajit.h */ #ifndef _LJ_FUNC_H diff --git a/Build/source/libs/luajit/LuaJIT-src/src/lj_gc.c b/Build/source/libs/luajit/LuaJIT-src/src/lj_gc.c index 99d664aa2a1..53f1d974cf3 100644 --- a/Build/source/libs/luajit/LuaJIT-src/src/lj_gc.c +++ b/Build/source/libs/luajit/LuaJIT-src/src/lj_gc.c @@ -1,6 +1,6 @@ /* ** Garbage collector. -** Copyright (C) 2005-2015 Mike Pall. See Copyright Notice in luajit.h +** Copyright (C) 2005-2016 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 @@ -69,7 +69,7 @@ static void gc_mark(global_State *g, GCobj *o) gray2black(o); /* Closed upvalues are never gray. */ } else if (gct != ~LJ_TSTR && gct != ~LJ_TCDATA) { lua_assert(gct == ~LJ_TFUNC || gct == ~LJ_TTAB || - gct == ~LJ_TTHREAD || gct == ~LJ_TPROTO); + gct == ~LJ_TTHREAD || gct == ~LJ_TPROTO || gct == ~LJ_TTRACE); setgcrefr(o->gch.gclist, g->gc.gray); setgcref(g->gc.gray, o); } diff --git a/Build/source/libs/luajit/LuaJIT-src/src/lj_gc.h b/Build/source/libs/luajit/LuaJIT-src/src/lj_gc.h index 847eb7835d9..eee09afb5a5 100644 --- a/Build/source/libs/luajit/LuaJIT-src/src/lj_gc.h +++ b/Build/source/libs/luajit/LuaJIT-src/src/lj_gc.h @@ -1,6 +1,6 @@ /* ** Garbage collector. -** Copyright (C) 2005-2015 Mike Pall. See Copyright Notice in luajit.h +** Copyright (C) 2005-2016 Mike Pall. See Copyright Notice in luajit.h */ #ifndef _LJ_GC_H diff --git a/Build/source/libs/luajit/LuaJIT-src/src/lj_gdbjit.c b/Build/source/libs/luajit/LuaJIT-src/src/lj_gdbjit.c index 9b95e525840..f2bd865e600 100644 --- a/Build/source/libs/luajit/LuaJIT-src/src/lj_gdbjit.c +++ b/Build/source/libs/luajit/LuaJIT-src/src/lj_gdbjit.c @@ -1,6 +1,6 @@ /* ** Client for the GDB JIT API. -** Copyright (C) 2005-2015 Mike Pall. See Copyright Notice in luajit.h +** Copyright (C) 2005-2016 Mike Pall. See Copyright Notice in luajit.h */ #define lj_gdbjit_c diff --git a/Build/source/libs/luajit/LuaJIT-src/src/lj_gdbjit.h b/Build/source/libs/luajit/LuaJIT-src/src/lj_gdbjit.h index 49c586301a8..1043bc69862 100644 --- a/Build/source/libs/luajit/LuaJIT-src/src/lj_gdbjit.h +++ b/Build/source/libs/luajit/LuaJIT-src/src/lj_gdbjit.h @@ -1,6 +1,6 @@ /* ** Client for the GDB JIT API. -** Copyright (C) 2005-2015 Mike Pall. See Copyright Notice in luajit.h +** Copyright (C) 2005-2016 Mike Pall. See Copyright Notice in luajit.h */ #ifndef _LJ_GDBJIT_H diff --git a/Build/source/libs/luajit/LuaJIT-src/src/lj_ir.c b/Build/source/libs/luajit/LuaJIT-src/src/lj_ir.c index 9682e05e577..63c9825475f 100644 --- a/Build/source/libs/luajit/LuaJIT-src/src/lj_ir.c +++ b/Build/source/libs/luajit/LuaJIT-src/src/lj_ir.c @@ -1,6 +1,6 @@ /* ** SSA IR (Intermediate Representation) emitter. -** Copyright (C) 2005-2015 Mike Pall. See Copyright Notice in luajit.h +** Copyright (C) 2005-2016 Mike Pall. See Copyright Notice in luajit.h */ #define lj_ir_c @@ -209,24 +209,13 @@ void lj_ir_k64_freeall(jit_State *J) lj_mem_free(J2G(J), k, sizeof(K64Array)); k = next; } + setmref(J->k64, NULL); } -/* Find 64 bit constant in chained array or add it. */ -cTValue *lj_ir_k64_find(jit_State *J, uint64_t u64) +/* Get new 64 bit constant slot. */ +static TValue *ir_k64_add(jit_State *J, K64Array *kp, uint64_t u64) { - K64Array *k, *kp = NULL; TValue *ntv; - MSize idx; - /* Search for the constant in the whole chain of arrays. */ - for (k = mref(J->k64, K64Array); k; k = mref(k->next, K64Array)) { - kp = k; /* Remember previous element in list. */ - for (idx = 0; idx < k->numk; idx++) { /* Search one array. */ - TValue *tv = &k->k[idx]; - if (tv->u64 == u64) /* Needed for +-0/NaN/absmask. */ - return tv; - } - } - /* Constant was not found, need to add it. */ if (!(kp && kp->numk < LJ_MIN_K64SZ)) { /* Allocate a new array. */ K64Array *kn = lj_mem_newt(J->L, sizeof(K64Array), K64Array); setmref(kn->next, NULL); @@ -242,6 +231,33 @@ cTValue *lj_ir_k64_find(jit_State *J, uint64_t u64) return ntv; } +/* Find 64 bit constant in chained array or add it. */ +cTValue *lj_ir_k64_find(jit_State *J, uint64_t u64) +{ + K64Array *k, *kp = NULL; + MSize idx; + /* Search for the constant in the whole chain of arrays. */ + for (k = mref(J->k64, K64Array); k; k = mref(k->next, K64Array)) { + kp = k; /* Remember previous element in list. */ + for (idx = 0; idx < k->numk; idx++) { /* Search one array. */ + TValue *tv = &k->k[idx]; + if (tv->u64 == u64) /* Needed for +-0/NaN/absmask. */ + return tv; + } + } + /* Otherwise add a new constant. */ + return ir_k64_add(J, kp, u64); +} + +TValue *lj_ir_k64_reserve(jit_State *J) +{ + K64Array *k, *kp = NULL; + lj_ir_k64_find(J, 0); /* Intern dummy 0 to protect the reserved slot. */ + /* Find last K64Array, if any. */ + for (k = mref(J->k64, K64Array); k; k = mref(k->next, K64Array)) kp = k; + return ir_k64_add(J, kp, 0); /* Set to 0. Final value is set later. */ +} + /* Intern 64 bit constant, given by its address. */ TRef lj_ir_k64(jit_State *J, IROp op, cTValue *tv) { diff --git a/Build/source/libs/luajit/LuaJIT-src/src/lj_ir.h b/Build/source/libs/luajit/LuaJIT-src/src/lj_ir.h index 56e19774c97..cd8df59d39d 100644 --- a/Build/source/libs/luajit/LuaJIT-src/src/lj_ir.h +++ b/Build/source/libs/luajit/LuaJIT-src/src/lj_ir.h @@ -1,6 +1,6 @@ /* ** SSA IR (Intermediate Representation) format. -** Copyright (C) 2005-2015 Mike Pall. See Copyright Notice in luajit.h +** Copyright (C) 2005-2016 Mike Pall. See Copyright Notice in luajit.h */ #ifndef _LJ_IR_H diff --git a/Build/source/libs/luajit/LuaJIT-src/src/lj_ircall.h b/Build/source/libs/luajit/LuaJIT-src/src/lj_ircall.h index 84e41ecfccb..144135a4a7f 100644 --- a/Build/source/libs/luajit/LuaJIT-src/src/lj_ircall.h +++ b/Build/source/libs/luajit/LuaJIT-src/src/lj_ircall.h @@ -1,6 +1,6 @@ /* ** IR CALL* instruction definitions. -** Copyright (C) 2005-2015 Mike Pall. See Copyright Notice in luajit.h +** Copyright (C) 2005-2016 Mike Pall. See Copyright Notice in luajit.h */ #ifndef _LJ_IRCALL_H @@ -78,6 +78,12 @@ typedef struct CCallInfo { #define IRCALLCOND_SOFTFP_FFI(x) NULL #endif +#if LJ_SOFTFP && LJ_TARGET_MIPS +#define IRCALLCOND_SOFTFP_MIPS(x) x +#else +#define IRCALLCOND_SOFTFP_MIPS(x) NULL +#endif + #define LJ_NEED_FP64 (LJ_TARGET_ARM || LJ_TARGET_PPC || LJ_TARGET_MIPS) #if LJ_HASFFI && (LJ_SOFTFP || LJ_NEED_FP64) @@ -189,6 +195,8 @@ typedef struct CCallInfo { _(SOFTFP, softfp_cmp, 4, N, NIL, 0) \ _(SOFTFP, softfp_i2d, 1, N, NUM, 0) \ _(SOFTFP, softfp_d2i, 2, N, INT, 0) \ + _(SOFTFP_MIPS, lj_vm_sfmin, 4, N, NUM, 0) \ + _(SOFTFP_MIPS, lj_vm_sfmax, 4, N, NUM, 0) \ _(SOFTFP_FFI, softfp_ui2d, 1, N, NUM, 0) \ _(SOFTFP_FFI, softfp_f2d, 1, N, NUM, 0) \ _(SOFTFP_FFI, softfp_d2ui, 2, N, INT, 0) \ @@ -270,6 +278,22 @@ LJ_DATA const CCallInfo lj_ir_callinfo[IRCALL__MAX+1]; #define fp64_f2l __aeabi_f2lz #define fp64_f2ul __aeabi_f2ulz #endif +#elif LJ_TARGET_MIPS +#define softfp_add __adddf3 +#define softfp_sub __subdf3 +#define softfp_mul __muldf3 +#define softfp_div __divdf3 +#define softfp_cmp __ledf2 +#define softfp_i2d __floatsidf +#define softfp_d2i __fixdfsi +#define softfp_ui2d __floatunsidf +#define softfp_f2d __extendsfdf2 +#define softfp_d2ui __fixunsdfsi +#define softfp_d2f __truncdfsf2 +#define softfp_i2f __floatsisf +#define softfp_ui2f __floatunsisf +#define softfp_f2i __fixsfsi +#define softfp_f2ui __fixunssfsi #else #error "Missing soft-float definitions for target architecture" #endif @@ -290,6 +314,10 @@ extern float softfp_ui2f(uint32_t a); extern int32_t softfp_f2i(float a); extern uint32_t softfp_f2ui(float a); #endif +#if LJ_TARGET_MIPS +extern double lj_vm_sfmin(double a, double b); +extern double lj_vm_sfmax(double a, double b); +#endif #endif #if LJ_HASFFI && LJ_NEED_FP64 && !(LJ_TARGET_ARM && LJ_SOFTFP) diff --git a/Build/source/libs/luajit/LuaJIT-src/src/lj_iropt.h b/Build/source/libs/luajit/LuaJIT-src/src/lj_iropt.h index 4e424e70045..953740443cd 100644 --- a/Build/source/libs/luajit/LuaJIT-src/src/lj_iropt.h +++ b/Build/source/libs/luajit/LuaJIT-src/src/lj_iropt.h @@ -1,6 +1,6 @@ /* ** Common header for IR emitter and optimizations. -** Copyright (C) 2005-2015 Mike Pall. See Copyright Notice in luajit.h +** Copyright (C) 2005-2016 Mike Pall. See Copyright Notice in luajit.h */ #ifndef _LJ_IROPT_H @@ -40,6 +40,7 @@ static LJ_AINLINE IRRef lj_ir_nextins(jit_State *J) LJ_FUNC TRef LJ_FASTCALL lj_ir_kint(jit_State *J, int32_t k); LJ_FUNC void lj_ir_k64_freeall(jit_State *J); LJ_FUNC TRef lj_ir_k64(jit_State *J, IROp op, cTValue *tv); +LJ_FUNC TValue *lj_ir_k64_reserve(jit_State *J); LJ_FUNC cTValue *lj_ir_k64_find(jit_State *J, uint64_t u64); LJ_FUNC TRef lj_ir_knum_u64(jit_State *J, uint64_t u64); LJ_FUNC TRef lj_ir_knumint(jit_State *J, lua_Number n); diff --git a/Build/source/libs/luajit/LuaJIT-src/src/lj_jit.h b/Build/source/libs/luajit/LuaJIT-src/src/lj_jit.h index 1df56cae55e..5a51357e077 100644 --- a/Build/source/libs/luajit/LuaJIT-src/src/lj_jit.h +++ b/Build/source/libs/luajit/LuaJIT-src/src/lj_jit.h @@ -1,6 +1,6 @@ /* ** Common definitions for the JIT compiler. -** Copyright (C) 2005-2015 Mike Pall. See Copyright Notice in luajit.h +** Copyright (C) 2005-2016 Mike Pall. See Copyright Notice in luajit.h */ #ifndef _LJ_JIT_H @@ -381,6 +381,7 @@ typedef struct jit_State { GCRef *trace; /* Array of traces. */ TraceNo freetrace; /* Start of scan for next free trace. */ MSize sizetrace; /* Size of trace array. */ + TValue *ktracep; /* Pointer to K64Array slot with GCtrace pointer. */ IRRef1 chain[IR__MAX]; /* IR instruction skip-list chain anchors. */ TRef slot[LJ_MAX_JSLOTS+LJ_STACK_EXTRA]; /* Stack slot map. */ diff --git a/Build/source/libs/luajit/LuaJIT-src/src/lj_lex.c b/Build/source/libs/luajit/LuaJIT-src/src/lj_lex.c index 8409cd78a71..0187c4267a2 100644 --- a/Build/source/libs/luajit/LuaJIT-src/src/lj_lex.c +++ b/Build/source/libs/luajit/LuaJIT-src/src/lj_lex.c @@ -1,6 +1,6 @@ /* ** Lexical analyzer. -** Copyright (C) 2005-2015 Mike Pall. See Copyright Notice in luajit.h +** Copyright (C) 2005-2016 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 @@ -214,6 +214,33 @@ static void lex_string(LexState *ls, TValue *tv) c += 9; } break; + case 'u': /* Unicode escape '\u{XX...}'. */ + if (lex_next(ls) != '{') goto err_xesc; + lex_next(ls); + c = 0; + do { + c = (c << 4) | (ls->c & 15u); + if (!lj_char_isdigit(ls->c)) { + if (!lj_char_isxdigit(ls->c)) goto err_xesc; + c += 9; + } + if (c >= 0x110000) goto err_xesc; /* Out of Unicode range. */ + } while (lex_next(ls) != '}'); + if (c < 0x800) { + if (c < 0x80) break; + lex_save(ls, 0xc0 | (c >> 6)); + } else { + if (c >= 0x10000) { + lex_save(ls, 0xf0 | (c >> 18)); + lex_save(ls, 0x80 | ((c >> 12) & 0x3f)); + } else { + if (c >= 0xd800 && c < 0xe000) goto err_xesc; /* No surrogates. */ + lex_save(ls, 0xe0 | (c >> 12)); + } + lex_save(ls, 0x80 | ((c >> 6) & 0x3f)); + } + c = 0x80 | (c & 0x3f); + break; case 'z': /* Skip whitespace. */ lex_next(ls); while (lj_char_isspace(ls->c)) diff --git a/Build/source/libs/luajit/LuaJIT-src/src/lj_lex.h b/Build/source/libs/luajit/LuaJIT-src/src/lj_lex.h index acd2285d789..7fed1fd6137 100644 --- a/Build/source/libs/luajit/LuaJIT-src/src/lj_lex.h +++ b/Build/source/libs/luajit/LuaJIT-src/src/lj_lex.h @@ -1,6 +1,6 @@ /* ** Lexical analyzer. -** Copyright (C) 2005-2015 Mike Pall. See Copyright Notice in luajit.h +** Copyright (C) 2005-2016 Mike Pall. See Copyright Notice in luajit.h */ #ifndef _LJ_LEX_H diff --git a/Build/source/libs/luajit/LuaJIT-src/src/lj_lib.c b/Build/source/libs/luajit/LuaJIT-src/src/lj_lib.c index b16d0564fa7..8bdf6912a8d 100644 --- a/Build/source/libs/luajit/LuaJIT-src/src/lj_lib.c +++ b/Build/source/libs/luajit/LuaJIT-src/src/lj_lib.c @@ -1,6 +1,6 @@ /* ** Library function support. -** Copyright (C) 2005-2015 Mike Pall. See Copyright Notice in luajit.h +** Copyright (C) 2005-2016 Mike Pall. See Copyright Notice in luajit.h */ #define lj_lib_c diff --git a/Build/source/libs/luajit/LuaJIT-src/src/lj_lib.h b/Build/source/libs/luajit/LuaJIT-src/src/lj_lib.h index 3fa7aa17eff..dbc04055b44 100644 --- a/Build/source/libs/luajit/LuaJIT-src/src/lj_lib.h +++ b/Build/source/libs/luajit/LuaJIT-src/src/lj_lib.h @@ -1,6 +1,6 @@ /* ** Library function support. -** Copyright (C) 2005-2015 Mike Pall. See Copyright Notice in luajit.h +** Copyright (C) 2005-2016 Mike Pall. See Copyright Notice in luajit.h */ #ifndef _LJ_LIB_H diff --git a/Build/source/libs/luajit/LuaJIT-src/src/lj_load.c b/Build/source/libs/luajit/LuaJIT-src/src/lj_load.c index 95a6ab0d4de..7783eee0504 100644 --- a/Build/source/libs/luajit/LuaJIT-src/src/lj_load.c +++ b/Build/source/libs/luajit/LuaJIT-src/src/lj_load.c @@ -1,6 +1,6 @@ /* ** Load and dump code. -** Copyright (C) 2005-2015 Mike Pall. See Copyright Notice in luajit.h +** Copyright (C) 2005-2016 Mike Pall. See Copyright Notice in luajit.h */ #include <errno.h> @@ -166,3 +166,19 @@ LUA_API int lua_dump(lua_State *L, lua_Writer writer, void *data) return 1; } +/* -- Luajittex needs this one because it overloads loadfile -- */ +LUALIB_API int RESERVED_load_aux_JIT(lua_State *L, int status, int envarg) +{ + if (status == 0) { + if (tvistab(L->base+envarg-1)) { + GCfunc *fn = funcV(L->top-1); + GCtab *t = tabV(L->base+envarg-1); + setgcref(fn->c.env, obj2gco(t)); + lj_gc_objbarrier(L, fn, t); + } + return 1; + } else { + setnilV(L->top-2); + return 2; + } +} diff --git a/Build/source/libs/luajit/LuaJIT-src/src/lj_mcode.c b/Build/source/libs/luajit/LuaJIT-src/src/lj_mcode.c index d95ebeb1fe7..3eaee0546e7 100644 --- a/Build/source/libs/luajit/LuaJIT-src/src/lj_mcode.c +++ b/Build/source/libs/luajit/LuaJIT-src/src/lj_mcode.c @@ -1,6 +1,6 @@ /* ** Machine code management. -** Copyright (C) 2005-2015 Mike Pall. See Copyright Notice in luajit.h +** Copyright (C) 2005-2016 Mike Pall. See Copyright Notice in luajit.h */ #define lj_mcode_c diff --git a/Build/source/libs/luajit/LuaJIT-src/src/lj_mcode.h b/Build/source/libs/luajit/LuaJIT-src/src/lj_mcode.h index ee604523496..503e001974f 100644 --- a/Build/source/libs/luajit/LuaJIT-src/src/lj_mcode.h +++ b/Build/source/libs/luajit/LuaJIT-src/src/lj_mcode.h @@ -1,6 +1,6 @@ /* ** Machine code management. -** Copyright (C) 2005-2015 Mike Pall. See Copyright Notice in luajit.h +** Copyright (C) 2005-2016 Mike Pall. See Copyright Notice in luajit.h */ #ifndef _LJ_MCODE_H diff --git a/Build/source/libs/luajit/LuaJIT-src/src/lj_meta.c b/Build/source/libs/luajit/LuaJIT-src/src/lj_meta.c index 104ecf07c3d..c7993ad6264 100644 --- a/Build/source/libs/luajit/LuaJIT-src/src/lj_meta.c +++ b/Build/source/libs/luajit/LuaJIT-src/src/lj_meta.c @@ -1,6 +1,6 @@ /* ** Metamethod handling. -** Copyright (C) 2005-2015 Mike Pall. See Copyright Notice in luajit.h +** Copyright (C) 2005-2016 Mike Pall. See Copyright Notice in luajit.h ** ** Portions taken verbatim or adapted from the Lua interpreter. ** Copyright (C) 1994-2008 Lua.org, PUC-Rio. See Copyright Notice in lua.h @@ -278,25 +278,25 @@ TValue *lj_meta_cat(lua_State *L, TValue *top, int left) */ TValue *e, *o = top; uint64_t tlen = tvisstr(o) ? strV(o)->len : STRFMT_MAXBUF_NUM; - char *p, *buf; + SBuf *sb; do { o--; tlen += tvisstr(o) ? strV(o)->len : STRFMT_MAXBUF_NUM; } while (--left > 0 && (tvisstr(o-1) || tvisnumber(o-1))); if (tlen >= LJ_MAX_STR) lj_err_msg(L, LJ_ERR_STROV); - p = buf = lj_buf_tmp(L, (MSize)tlen); + sb = lj_buf_tmp_(L); + lj_buf_more(sb, (MSize)tlen); for (e = top, top = o; o <= e; o++) { if (tvisstr(o)) { GCstr *s = strV(o); MSize len = s->len; - p = lj_buf_wmem(p, strdata(s), len); + lj_buf_putmem(sb, strdata(s), len); } else if (tvisint(o)) { - p = lj_strfmt_wint(p, intV(o)); + lj_strfmt_putint(sb, intV(o)); } else { - lua_assert(tvisnum(o)); - p = lj_strfmt_wnum(p, o); + lj_strfmt_putfnum(sb, STRFMT_G14, numV(o)); } } - setstrV(L, top, lj_str_new(L, buf, (size_t)(p-buf))); + setstrV(L, top, lj_buf_str(L, sb)); } } while (left >= 1); if (LJ_UNLIKELY(G(L)->gc.total >= G(L)->gc.threshold)) { diff --git a/Build/source/libs/luajit/LuaJIT-src/src/lj_meta.h b/Build/source/libs/luajit/LuaJIT-src/src/lj_meta.h index 7f71633362b..52e85cba2d1 100644 --- a/Build/source/libs/luajit/LuaJIT-src/src/lj_meta.h +++ b/Build/source/libs/luajit/LuaJIT-src/src/lj_meta.h @@ -1,6 +1,6 @@ /* ** Metamethod handling. -** Copyright (C) 2005-2015 Mike Pall. See Copyright Notice in luajit.h +** Copyright (C) 2005-2016 Mike Pall. See Copyright Notice in luajit.h */ #ifndef _LJ_META_H diff --git a/Build/source/libs/luajit/LuaJIT-src/src/lj_obj.c b/Build/source/libs/luajit/LuaJIT-src/src/lj_obj.c index b78d2c8d835..1daea817ace 100644 --- a/Build/source/libs/luajit/LuaJIT-src/src/lj_obj.c +++ b/Build/source/libs/luajit/LuaJIT-src/src/lj_obj.c @@ -1,6 +1,6 @@ /* ** Miscellaneous object handling. -** Copyright (C) 2005-2015 Mike Pall. See Copyright Notice in luajit.h +** Copyright (C) 2005-2016 Mike Pall. See Copyright Notice in luajit.h */ #define lj_obj_c diff --git a/Build/source/libs/luajit/LuaJIT-src/src/lj_obj.h b/Build/source/libs/luajit/LuaJIT-src/src/lj_obj.h index 74ed59bc726..059eb13250a 100644 --- a/Build/source/libs/luajit/LuaJIT-src/src/lj_obj.h +++ b/Build/source/libs/luajit/LuaJIT-src/src/lj_obj.h @@ -1,6 +1,6 @@ /* ** LuaJIT VM tags, values and objects. -** Copyright (C) 2005-2015 Mike Pall. See Copyright Notice in luajit.h +** Copyright (C) 2005-2016 Mike Pall. See Copyright Notice in luajit.h ** ** Portions taken verbatim or adapted from the Lua interpreter. ** Copyright (C) 1994-2008 Lua.org, PUC-Rio. See Copyright Notice in lua.h diff --git a/Build/source/libs/luajit/LuaJIT-src/src/lj_opt_dce.c b/Build/source/libs/luajit/LuaJIT-src/src/lj_opt_dce.c index 7f1faafe647..e5a096af561 100644 --- a/Build/source/libs/luajit/LuaJIT-src/src/lj_opt_dce.c +++ b/Build/source/libs/luajit/LuaJIT-src/src/lj_opt_dce.c @@ -1,6 +1,6 @@ /* ** DCE: Dead Code Elimination. Pre-LOOP only -- ASM already performs DCE. -** Copyright (C) 2005-2015 Mike Pall. See Copyright Notice in luajit.h +** Copyright (C) 2005-2016 Mike Pall. See Copyright Notice in luajit.h */ #define lj_opt_dce_c diff --git a/Build/source/libs/luajit/LuaJIT-src/src/lj_opt_fold.c b/Build/source/libs/luajit/LuaJIT-src/src/lj_opt_fold.c index f809a991a73..e1d136915cb 100644 --- a/Build/source/libs/luajit/LuaJIT-src/src/lj_opt_fold.c +++ b/Build/source/libs/luajit/LuaJIT-src/src/lj_opt_fold.c @@ -2,7 +2,7 @@ ** FOLD: Constant Folding, Algebraic Simplifications and Reassociation. ** ABCelim: Array Bounds Check Elimination. ** CSE: Common-Subexpression Elimination. -** Copyright (C) 2005-2015 Mike Pall. See Copyright Notice in luajit.h +** Copyright (C) 2005-2016 Mike Pall. See Copyright Notice in luajit.h */ #define lj_opt_fold_c diff --git a/Build/source/libs/luajit/LuaJIT-src/src/lj_opt_loop.c b/Build/source/libs/luajit/LuaJIT-src/src/lj_opt_loop.c index 4b4ab7dc3a3..7978f3eeafc 100644 --- a/Build/source/libs/luajit/LuaJIT-src/src/lj_opt_loop.c +++ b/Build/source/libs/luajit/LuaJIT-src/src/lj_opt_loop.c @@ -1,6 +1,6 @@ /* ** LOOP: Loop Optimizations. -** Copyright (C) 2005-2015 Mike Pall. See Copyright Notice in luajit.h +** Copyright (C) 2005-2016 Mike Pall. See Copyright Notice in luajit.h */ #define lj_opt_loop_c diff --git a/Build/source/libs/luajit/LuaJIT-src/src/lj_opt_mem.c b/Build/source/libs/luajit/LuaJIT-src/src/lj_opt_mem.c index e04a6228f4b..5549b0d02dd 100644 --- a/Build/source/libs/luajit/LuaJIT-src/src/lj_opt_mem.c +++ b/Build/source/libs/luajit/LuaJIT-src/src/lj_opt_mem.c @@ -3,7 +3,7 @@ ** AA: Alias Analysis using high-level semantic disambiguation. ** FWD: Load Forwarding (L2L) + Store Forwarding (S2L). ** DSE: Dead-Store Elimination. -** Copyright (C) 2005-2015 Mike Pall. See Copyright Notice in luajit.h +** Copyright (C) 2005-2016 Mike Pall. See Copyright Notice in luajit.h */ #define lj_opt_mem_c diff --git a/Build/source/libs/luajit/LuaJIT-src/src/lj_opt_narrow.c b/Build/source/libs/luajit/LuaJIT-src/src/lj_opt_narrow.c index d1993452a6a..b1ab5ba8eeb 100644 --- a/Build/source/libs/luajit/LuaJIT-src/src/lj_opt_narrow.c +++ b/Build/source/libs/luajit/LuaJIT-src/src/lj_opt_narrow.c @@ -1,7 +1,7 @@ /* ** NARROW: Narrowing of numbers to integers (double to int32_t). ** STRIPOV: Stripping of overflow checks. -** Copyright (C) 2005-2015 Mike Pall. See Copyright Notice in luajit.h +** Copyright (C) 2005-2016 Mike Pall. See Copyright Notice in luajit.h */ #define lj_opt_narrow_c diff --git a/Build/source/libs/luajit/LuaJIT-src/src/lj_opt_sink.c b/Build/source/libs/luajit/LuaJIT-src/src/lj_opt_sink.c index a98e9dfe3b4..975ee831d91 100644 --- a/Build/source/libs/luajit/LuaJIT-src/src/lj_opt_sink.c +++ b/Build/source/libs/luajit/LuaJIT-src/src/lj_opt_sink.c @@ -1,6 +1,6 @@ /* ** SINK: Allocation Sinking and Store Sinking. -** Copyright (C) 2005-2015 Mike Pall. See Copyright Notice in luajit.h +** Copyright (C) 2005-2016 Mike Pall. See Copyright Notice in luajit.h */ #define lj_opt_sink_c diff --git a/Build/source/libs/luajit/LuaJIT-src/src/lj_opt_split.c b/Build/source/libs/luajit/LuaJIT-src/src/lj_opt_split.c index 81ded6c0a01..6def4161aa3 100644 --- a/Build/source/libs/luajit/LuaJIT-src/src/lj_opt_split.c +++ b/Build/source/libs/luajit/LuaJIT-src/src/lj_opt_split.c @@ -1,6 +1,6 @@ /* ** SPLIT: Split 64 bit IR instructions into 32 bit IR instructions. -** Copyright (C) 2005-2015 Mike Pall. See Copyright Notice in luajit.h +** Copyright (C) 2005-2016 Mike Pall. See Copyright Notice in luajit.h */ #define lj_opt_split_c @@ -192,7 +192,7 @@ static IRRef split_ptr(jit_State *J, IRIns *oir, IRRef ref) nref = ir->op1; if (ofs == 0) return nref; } - return split_emit(J, IRTI(IR_ADD), nref, lj_ir_kint(J, ofs)); + return split_emit(J, IRT(IR_ADD, IRT_PTR), nref, lj_ir_kint(J, ofs)); } #if LJ_HASFFI @@ -452,11 +452,15 @@ static void split_ir(jit_State *J) IRIns inslo = *nir; /* Save/undo the emit of the lo XLOAD. */ J->cur.nins--; hi = split_ptr(J, oir, ir->op1); /* Insert the hiref ADD. */ +#if LJ_BE + hi = split_emit(J, IRT(IR_XLOAD, IRT_INT), hi, ir->op2); + inslo.t.irt = IRT_SOFTFP | (inslo.t.irt & IRT_GUARD); +#endif nref = lj_ir_nextins(J); nir = IR(nref); - *nir = inslo; /* Re-emit lo XLOAD immediately before hi XLOAD. */ - hi = split_emit(J, IRT(IR_XLOAD, IRT_SOFTFP), hi, ir->op2); + *nir = inslo; /* Re-emit lo XLOAD. */ #if LJ_LE + hi = split_emit(J, IRT(IR_XLOAD, IRT_SOFTFP), hi, ir->op2); ir->prev = nref; #else ir->prev = hi; hi = nref; @@ -596,7 +600,8 @@ static void split_ir(jit_State *J) } #endif else if (st == IRT_I64 || st == IRT_U64) { /* 64/64 bit cast. */ - /* Drop cast, since assembler doesn't care. */ + /* Drop cast, since assembler doesn't care. But fwd both parts. */ + hi = hiref; goto fwdlo; } else if ((ir->op2 & IRCONV_SEXT)) { /* Sign-extend to 64 bit. */ IRRef k31 = lj_ir_kint(J, 31); diff --git a/Build/source/libs/luajit/LuaJIT-src/src/lj_parse.c b/Build/source/libs/luajit/LuaJIT-src/src/lj_parse.c index 9891897ed6f..610c861480e 100644 --- a/Build/source/libs/luajit/LuaJIT-src/src/lj_parse.c +++ b/Build/source/libs/luajit/LuaJIT-src/src/lj_parse.c @@ -1,6 +1,6 @@ /* ** Lua parser (source code -> bytecode). -** Copyright (C) 2005-2015 Mike Pall. See Copyright Notice in luajit.h +** Copyright (C) 2005-2016 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 diff --git a/Build/source/libs/luajit/LuaJIT-src/src/lj_parse.h b/Build/source/libs/luajit/LuaJIT-src/src/lj_parse.h index dc4fd405d18..b383c8971b1 100644 --- a/Build/source/libs/luajit/LuaJIT-src/src/lj_parse.h +++ b/Build/source/libs/luajit/LuaJIT-src/src/lj_parse.h @@ -1,6 +1,6 @@ /* ** Lua parser (source code -> bytecode). -** Copyright (C) 2005-2015 Mike Pall. See Copyright Notice in luajit.h +** Copyright (C) 2005-2016 Mike Pall. See Copyright Notice in luajit.h */ #ifndef _LJ_PARSE_H diff --git a/Build/source/libs/luajit/LuaJIT-src/src/lj_profile.c b/Build/source/libs/luajit/LuaJIT-src/src/lj_profile.c index c7e53963b5b..95b0a621e84 100644 --- a/Build/source/libs/luajit/LuaJIT-src/src/lj_profile.c +++ b/Build/source/libs/luajit/LuaJIT-src/src/lj_profile.c @@ -1,6 +1,6 @@ /* ** Low-overhead profiling. -** Copyright (C) 2005-2015 Mike Pall. See Copyright Notice in luajit.h +** Copyright (C) 2005-2016 Mike Pall. See Copyright Notice in luajit.h */ #define lj_profile_c diff --git a/Build/source/libs/luajit/LuaJIT-src/src/lj_profile.h b/Build/source/libs/luajit/LuaJIT-src/src/lj_profile.h index 26cb9db380c..14c3fc0881f 100644 --- a/Build/source/libs/luajit/LuaJIT-src/src/lj_profile.h +++ b/Build/source/libs/luajit/LuaJIT-src/src/lj_profile.h @@ -1,6 +1,6 @@ /* ** Low-overhead profiling. -** Copyright (C) 2005-2015 Mike Pall. See Copyright Notice in luajit.h +** Copyright (C) 2005-2016 Mike Pall. See Copyright Notice in luajit.h */ #ifndef _LJ_PROFILE_H diff --git a/Build/source/libs/luajit/LuaJIT-src/src/lj_record.c b/Build/source/libs/luajit/LuaJIT-src/src/lj_record.c index dc5f2d547ae..90f53af3e6b 100644 --- a/Build/source/libs/luajit/LuaJIT-src/src/lj_record.c +++ b/Build/source/libs/luajit/LuaJIT-src/src/lj_record.c @@ -1,6 +1,6 @@ /* ** Trace recorder (bytecode -> SSA IR). -** Copyright (C) 2005-2015 Mike Pall. See Copyright Notice in luajit.h +** Copyright (C) 2005-2016 Mike Pall. See Copyright Notice in luajit.h */ #define lj_record_c @@ -1236,12 +1236,14 @@ static void rec_idx_abc(jit_State *J, TRef asizeref, TRef ikey, uint32_t asize) } /* Record indexed key lookup. */ -static TRef rec_idx_key(jit_State *J, RecordIndex *ix, IRRef *rbref) +static TRef rec_idx_key(jit_State *J, RecordIndex *ix, IRRef *rbref, + IRType1 *rbguard) { TRef key; GCtab *t = tabV(&ix->tabv); ix->oldv = lj_tab_get(J->L, t, &ix->keyv); /* Lookup previous value. */ *rbref = 0; + rbguard->irt = 0; /* Integer keys are looked up in the array part first. */ key = ix->key; @@ -1293,6 +1295,7 @@ static TRef rec_idx_key(jit_State *J, RecordIndex *ix, IRRef *rbref) hslot <= 65535*(MSize)sizeof(Node)) { TRef node, kslot, hm; *rbref = J->cur.nins; /* Mark possible rollback point. */ + *rbguard = J->guardemit; hm = emitir(IRTI(IR_FLOAD), ix->tab, IRFL_TAB_HMASK); emitir(IRTGI(IR_EQ), hm, lj_ir_kint(J, (int32_t)t->hmask)); node = emitir(IRT(IR_FLOAD, IRT_P32), ix->tab, IRFL_TAB_NODE); @@ -1327,6 +1330,7 @@ TRef lj_record_idx(jit_State *J, RecordIndex *ix) TRef xref; IROp xrefop, loadop; IRRef rbref; + IRType1 rbguard; cTValue *oldv; while (!tref_istab(ix->tab)) { /* Handle non-table lookup. */ @@ -1373,7 +1377,7 @@ TRef lj_record_idx(jit_State *J, RecordIndex *ix) } /* Record the key lookup. */ - xref = rec_idx_key(J, ix, &rbref); + xref = rec_idx_key(J, ix, &rbref, &rbguard); xrefop = IR(tref_ref(xref))->o; loadop = xrefop == IR_AREF ? IR_ALOAD : IR_HLOAD; /* The lj_meta_tset() inconsistency is gone, but better play safe. */ @@ -1388,8 +1392,10 @@ TRef lj_record_idx(jit_State *J, RecordIndex *ix) } else { res = emitir(IRTG(loadop, t), xref, 0); } - if (tref_ref(res) < rbref) /* HREFK + load forwarded? */ + if (tref_ref(res) < rbref) { /* HREFK + load forwarded? */ lj_ir_rollback(J, rbref); /* Rollback to eliminate hmask guard. */ + J->guardemit = rbguard; + } if (t == IRT_NIL && ix->idxchain && lj_record_mm_lookup(J, ix, MM_index)) goto handlemm; if (irtype_ispri(t)) res = TREF_PRI(t); /* Canonicalize primitives. */ @@ -1397,8 +1403,10 @@ TRef lj_record_idx(jit_State *J, RecordIndex *ix) } else { /* Indexed store. */ GCtab *mt = tabref(tabV(&ix->tabv)->metatable); int keybarrier = tref_isgcv(ix->key) && !tref_isnil(ix->val); - if (tref_ref(xref) < rbref) /* HREFK forwarded? */ + if (tref_ref(xref) < rbref) { /* HREFK forwarded? */ lj_ir_rollback(J, rbref); /* Rollback to eliminate hmask guard. */ + J->guardemit = rbguard; + } if (tvisnil(oldv)) { /* Previous value was nil? */ /* Need to duplicate the hasmm check for the early guards. */ int hasmm = 0; diff --git a/Build/source/libs/luajit/LuaJIT-src/src/lj_record.h b/Build/source/libs/luajit/LuaJIT-src/src/lj_record.h index 732adb47ce2..cb184e8f6b9 100644 --- a/Build/source/libs/luajit/LuaJIT-src/src/lj_record.h +++ b/Build/source/libs/luajit/LuaJIT-src/src/lj_record.h @@ -1,6 +1,6 @@ /* ** Trace recorder (bytecode -> SSA IR). -** Copyright (C) 2005-2015 Mike Pall. See Copyright Notice in luajit.h +** Copyright (C) 2005-2016 Mike Pall. See Copyright Notice in luajit.h */ #ifndef _LJ_RECORD_H diff --git a/Build/source/libs/luajit/LuaJIT-src/src/lj_snap.c b/Build/source/libs/luajit/LuaJIT-src/src/lj_snap.c index d8e7987c5c2..8638d9edbfd 100644 --- a/Build/source/libs/luajit/LuaJIT-src/src/lj_snap.c +++ b/Build/source/libs/luajit/LuaJIT-src/src/lj_snap.c @@ -1,6 +1,6 @@ /* ** Snapshot handling. -** Copyright (C) 2005-2015 Mike Pall. See Copyright Notice in luajit.h +** Copyright (C) 2005-2016 Mike Pall. See Copyright Notice in luajit.h */ #define lj_snap_c @@ -26,9 +26,6 @@ #include "lj_cdata.h" #endif -/* Some local macros to save typing. Undef'd at the end. */ -#define IR(ref) (&J->cur.ir[(ref)]) - /* Pass IR on to next optimization in chain (FOLD). */ #define emitir(ot, a, b) (lj_ir_set(J, (ot), (a), (b)), lj_opt_fold(J)) @@ -73,7 +70,7 @@ static MSize snapshot_slots(jit_State *J, SnapEntry *map, BCReg nslots) IRRef ref = tref_ref(tr); if (ref) { SnapEntry sn = SNAP_TR(s, tr); - IRIns *ir = IR(ref); + IRIns *ir = &J->cur.ir[ref]; if (!(sn & (SNAP_CONT|SNAP_FRAME)) && ir->o == IR_SLOAD && ir->op1 == s && ref > retf) { /* No need to snapshot unmodified non-inherited slots. */ @@ -148,8 +145,8 @@ void lj_snap_add(jit_State *J) MSize nsnap = J->cur.nsnap; MSize nsnapmap = J->cur.nsnapmap; /* Merge if no ins. inbetween or if requested and no guard inbetween. */ - if (J->mergesnap ? !irt_isguard(J->guardemit) : - (nsnap > 0 && J->cur.snap[nsnap-1].ref == J->cur.nins)) { + if ((nsnap > 0 && J->cur.snap[nsnap-1].ref == J->cur.nins) || + (J->mergesnap && !irt_isguard(J->guardemit))) { if (nsnap == 1) { /* But preserve snap #0 PC. */ emitir_raw(IRT(IR_NOP, IRT_NIL), 0, 0); goto nomerge; @@ -407,24 +404,24 @@ static TRef snap_pref(jit_State *J, GCtrace *T, SnapEntry *map, MSize nmax, } /* Check whether a sunk store corresponds to an allocation. Slow path. */ -static int snap_sunk_store2(jit_State *J, IRIns *ira, IRIns *irs) +static int snap_sunk_store2(GCtrace *T, IRIns *ira, IRIns *irs) { if (irs->o == IR_ASTORE || irs->o == IR_HSTORE || irs->o == IR_FSTORE || irs->o == IR_XSTORE) { - IRIns *irk = IR(irs->op1); + IRIns *irk = &T->ir[irs->op1]; if (irk->o == IR_AREF || irk->o == IR_HREFK) - irk = IR(irk->op1); - return (IR(irk->op1) == ira); + irk = &T->ir[irk->op1]; + return (&T->ir[irk->op1] == ira); } return 0; } /* Check whether a sunk store corresponds to an allocation. Fast path. */ -static LJ_AINLINE int snap_sunk_store(jit_State *J, IRIns *ira, IRIns *irs) +static LJ_AINLINE int snap_sunk_store(GCtrace *T, IRIns *ira, IRIns *irs) { if (irs->s != 255) return (ira + irs->s == irs); /* Fast check. */ - return snap_sunk_store2(J, ira, irs); + return snap_sunk_store2(T, ira, irs); } /* Replay snapshot state to setup side trace. */ @@ -487,7 +484,7 @@ void lj_snap_replay(jit_State *J, GCtrace *T) } else { IRIns *irs; for (irs = ir+1; irs < irlast; irs++) - if (irs->r == RID_SINK && snap_sunk_store(J, ir, irs)) { + if (irs->r == RID_SINK && snap_sunk_store(T, ir, irs)) { if (snap_pref(J, T, map, nent, seen, irs->op2) == 0) snap_pref(J, T, map, nent, seen, T->ir[irs->op2].op1); else if ((LJ_SOFTFP || (LJ_32 && LJ_HASFFI)) && @@ -521,13 +518,13 @@ void lj_snap_replay(jit_State *J, GCtrace *T) op2 = emitir_raw(IRT(IR_HIOP, IRT_I64), op2, snap_pref(J, T, map, nent, seen, (ir+1)->op2)); } - J->slot[snap_slot(sn)] = emitir(ir->ot, op1, op2); + J->slot[snap_slot(sn)] = emitir(ir->ot & ~(IRT_MARK|IRT_ISPHI), op1, op2); } else { IRIns *irs; TRef tr = emitir(ir->ot, op1, op2); J->slot[snap_slot(sn)] = tr; for (irs = ir+1; irs < irlast; irs++) - if (irs->r == RID_SINK && snap_sunk_store(J, ir, irs)) { + if (irs->r == RID_SINK && snap_sunk_store(T, ir, irs)) { IRIns *irr = &T->ir[irs->op1]; TRef val, key = irr->op2, tmp = tr; if (irr->o != IR_FREF) { @@ -631,8 +628,8 @@ static void snap_restoreval(jit_State *J, GCtrace *T, ExitState *ex, } else if (irt_isnum(t)) { setnumV(o, ex->fpr[r-RID_MIN_FPR]); #endif - } else if (LJ_64 && irt_islightud(t)) { - /* 64 bit lightuserdata which may escape already has the tag bits. */ + } else if (LJ_64 && irt_is64(t)) { + /* 64 bit values that already have the tag bits. */ o->u64 = ex->gpr[r-RID_MIN_GPR]; } else if (irt_ispri(t)) { setpriV(o, irt_toitype(t)); @@ -714,8 +711,9 @@ static void snap_unsink(jit_State *J, GCtrace *T, ExitState *ex, if (ir->o == IR_CNEW || ir->o == IR_CNEWI) { CTState *cts = ctype_cts(J->L); CTypeID id = (CTypeID)T->ir[ir->op1].i; - CTSize sz = lj_ctype_size(cts, id); - GCcdata *cd = lj_cdata_new(cts, id, sz); + CTSize sz; + CTInfo info = lj_ctype_info(cts, id, &sz); + GCcdata *cd = lj_cdata_newx(cts, id, sz, info); setcdataV(J->L, o, cd); if (ir->o == IR_CNEWI) { uint8_t *p = (uint8_t *)cdataptr(cd); @@ -729,7 +727,7 @@ static void snap_unsink(jit_State *J, GCtrace *T, ExitState *ex, } else { IRIns *irs, *irlast = &T->ir[T->snap[snapno].ref]; for (irs = ir+1; irs < irlast; irs++) - if (irs->r == RID_SINK && snap_sunk_store(J, ir, irs)) { + if (irs->r == RID_SINK && snap_sunk_store(T, ir, irs)) { IRIns *iro = &T->ir[T->ir[irs->op1].op2]; uint8_t *p = (uint8_t *)cd; CTSize szs; @@ -762,7 +760,7 @@ static void snap_unsink(jit_State *J, GCtrace *T, ExitState *ex, settabV(J->L, o, t); irlast = &T->ir[T->snap[snapno].ref]; for (irs = ir+1; irs < irlast; irs++) - if (irs->r == RID_SINK && snap_sunk_store(J, ir, irs)) { + if (irs->r == RID_SINK && snap_sunk_store(T, ir, irs)) { IRIns *irk = &T->ir[irs->op1]; TValue tmp, *val; lua_assert(irs->o == IR_ASTORE || irs->o == IR_HSTORE || @@ -863,7 +861,6 @@ const BCIns *lj_snap_restore(jit_State *J, void *exptr) return pc; } -#undef IR #undef emitir_raw #undef emitir diff --git a/Build/source/libs/luajit/LuaJIT-src/src/lj_snap.h b/Build/source/libs/luajit/LuaJIT-src/src/lj_snap.h index 9a125be7fb9..1d3379bc6f4 100644 --- a/Build/source/libs/luajit/LuaJIT-src/src/lj_snap.h +++ b/Build/source/libs/luajit/LuaJIT-src/src/lj_snap.h @@ -1,6 +1,6 @@ /* ** Snapshot handling. -** Copyright (C) 2005-2015 Mike Pall. See Copyright Notice in luajit.h +** Copyright (C) 2005-2016 Mike Pall. See Copyright Notice in luajit.h */ #ifndef _LJ_SNAP_H diff --git a/Build/source/libs/luajit/LuaJIT-src/src/lj_state.c b/Build/source/libs/luajit/LuaJIT-src/src/lj_state.c index 84b4d113a2b..66bf439f822 100644 --- a/Build/source/libs/luajit/LuaJIT-src/src/lj_state.c +++ b/Build/source/libs/luajit/LuaJIT-src/src/lj_state.c @@ -1,6 +1,6 @@ /* ** State and stack handling. -** Copyright (C) 2005-2015 Mike Pall. See Copyright Notice in luajit.h +** Copyright (C) 2005-2016 Mike Pall. See Copyright Notice in luajit.h ** ** Portions taken verbatim or adapted from the Lua interpreter. ** Copyright (C) 1994-2008 Lua.org, PUC-Rio. See Copyright Notice in lua.h diff --git a/Build/source/libs/luajit/LuaJIT-src/src/lj_state.h b/Build/source/libs/luajit/LuaJIT-src/src/lj_state.h index 687889a2613..e128d3211b3 100644 --- a/Build/source/libs/luajit/LuaJIT-src/src/lj_state.h +++ b/Build/source/libs/luajit/LuaJIT-src/src/lj_state.h @@ -1,6 +1,6 @@ /* ** State and stack handling. -** Copyright (C) 2005-2015 Mike Pall. See Copyright Notice in luajit.h +** Copyright (C) 2005-2016 Mike Pall. See Copyright Notice in luajit.h */ #ifndef _LJ_STATE_H diff --git a/Build/source/libs/luajit/LuaJIT-src/src/lj_str.c b/Build/source/libs/luajit/LuaJIT-src/src/lj_str.c index 3bc8079f37c..086072c3807 100644 --- a/Build/source/libs/luajit/LuaJIT-src/src/lj_str.c +++ b/Build/source/libs/luajit/LuaJIT-src/src/lj_str.c @@ -1,6 +1,6 @@ /* ** String handling. -** Copyright (C) 2005-2015 Mike Pall. See Copyright Notice in luajit.h +** Copyright (C) 2005-2016 Mike Pall. See Copyright Notice in luajit.h */ #define lj_str_c diff --git a/Build/source/libs/luajit/LuaJIT-src/src/lj_str.h b/Build/source/libs/luajit/LuaJIT-src/src/lj_str.h index d8465de663b..bb306c142ba 100644 --- a/Build/source/libs/luajit/LuaJIT-src/src/lj_str.h +++ b/Build/source/libs/luajit/LuaJIT-src/src/lj_str.h @@ -1,6 +1,6 @@ /* ** String handling. -** Copyright (C) 2005-2015 Mike Pall. See Copyright Notice in luajit.h +** Copyright (C) 2005-2016 Mike Pall. See Copyright Notice in luajit.h */ #ifndef _LJ_STR_H diff --git a/Build/source/libs/luajit/LuaJIT-src/src/lj_strfmt.c b/Build/source/libs/luajit/LuaJIT-src/src/lj_strfmt.c index d54e796ae2a..7c7d81d360f 100644 --- a/Build/source/libs/luajit/LuaJIT-src/src/lj_strfmt.c +++ b/Build/source/libs/luajit/LuaJIT-src/src/lj_strfmt.c @@ -1,6 +1,6 @@ /* ** String formatting. -** Copyright (C) 2005-2015 Mike Pall. See Copyright Notice in luajit.h +** Copyright (C) 2005-2016 Mike Pall. See Copyright Notice in luajit.h */ #include <stdio.h> @@ -18,7 +18,7 @@ /* -- Format parser ------------------------------------------------------- */ static const uint8_t strfmt_map[('x'-'A')+1] = { - STRFMT_A,0,0,0,STRFMT_E,0,STRFMT_G,0,0,0,0,0,0, + STRFMT_A,0,0,0,STRFMT_E,STRFMT_F,STRFMT_G,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,STRFMT_X,0,0, 0,0,0,0,0,0, STRFMT_A,0,STRFMT_C,STRFMT_D,STRFMT_E,STRFMT_F,STRFMT_G,0,STRFMT_I,0,0,0,0, @@ -89,24 +89,6 @@ retlit: /* -- Raw conversions ----------------------------------------------------- */ -/* Write number to bufer. */ -char * LJ_FASTCALL lj_strfmt_wnum(char *p, cTValue *o) -{ - if (LJ_LIKELY((o->u32.hi << 1) < 0xffe00000)) { /* Finite? */ -#if __BIONIC__ - if (tvismzero(o)) { *p++ = '-'; *p++ = '0'; return p; } -#endif - return p + lua_number2str(p, o->n); - } else if (((o->u32.hi & 0x000fffff) | o->u32.lo) != 0) { - *p++ = 'n'; *p++ = 'a'; *p++ = 'n'; - } else if ((o->u32.hi & 0x80000000) == 0) { - *p++ = 'i'; *p++ = 'n'; *p++ = 'f'; - } else { - *p++ = '-'; *p++ = 'i'; *p++ = 'n'; *p++ = 'f'; - } - return p; -} - #define WINT_R(x, sh, sc) \ { uint32_t d = (x*(((1<<sh)+sc-1)/sc))>>sh; x -= d*sc; *p++ = (char)('0'+d); } @@ -168,21 +150,22 @@ char * LJ_FASTCALL lj_strfmt_wuleb128(char *p, uint32_t v) return p; } -/* Return string or write number to buffer and return pointer to start. */ -const char *lj_strfmt_wstrnum(char *buf, cTValue *o, MSize *lenp) +/* Return string or write number to tmp buffer and return pointer to start. */ +const char *lj_strfmt_wstrnum(lua_State *L, cTValue *o, MSize *lenp) { + SBuf *sb; if (tvisstr(o)) { *lenp = strV(o)->len; return strVdata(o); } else if (tvisint(o)) { - *lenp = (MSize)(lj_strfmt_wint(buf, intV(o)) - buf); - return buf; + sb = lj_strfmt_putint(lj_buf_tmp_(L), intV(o)); } else if (tvisnum(o)) { - *lenp = (MSize)(lj_strfmt_wnum(buf, o) - buf); - return buf; + sb = lj_strfmt_putfnum(lj_buf_tmp_(L), STRFMT_G14, o->n); } else { return NULL; } + *lenp = sbuflen(sb); + return sbufB(sb); } /* -- Unformatted conversions to buffer ----------------------------------- */ @@ -198,8 +181,7 @@ SBuf * LJ_FASTCALL lj_strfmt_putint(SBuf *sb, int32_t k) /* Add number to buffer. */ SBuf * LJ_FASTCALL lj_strfmt_putnum(SBuf *sb, cTValue *o) { - setsbufP(sb, lj_strfmt_wnum(lj_buf_more(sb, STRFMT_MAXBUF_NUM), o)); - return sb; + return lj_strfmt_putfnum(sb, STRFMT_G14, o->n); } #endif @@ -360,63 +342,6 @@ SBuf *lj_strfmt_putfnum_uint(SBuf *sb, SFormat sf, lua_Number n) return lj_strfmt_putfxint(sb, sf, (uint64_t)k); } -/* Max. sprintf buffer size needed. At least #string.format("%.99f", -1e308). */ -#define STRFMT_FMTNUMBUF 512 - -/* Add formatted floating-point number to buffer. */ -SBuf *lj_strfmt_putfnum(SBuf *sb, SFormat sf, lua_Number n) -{ - TValue tv; - tv.n = n; - if (LJ_UNLIKELY((tv.u32.hi << 1) >= 0xffe00000)) { - /* Canonicalize output of non-finite values. */ - MSize width = STRFMT_WIDTH(sf), len = 3; - int prefix = 0, ch = (sf & STRFMT_F_UPPER) ? 0x202020 : 0; - char *p; - if (((tv.u32.hi & 0x000fffff) | tv.u32.lo) != 0) { - ch ^= ('n' << 16) | ('a' << 8) | 'n'; - if ((sf & STRFMT_F_SPACE)) prefix = ' '; - } else { - ch ^= ('i' << 16) | ('n' << 8) | 'f'; - if ((tv.u32.hi & 0x80000000)) prefix = '-'; - else if ((sf & STRFMT_F_PLUS)) prefix = '+'; - else if ((sf & STRFMT_F_SPACE)) prefix = ' '; - } - if (prefix) len = 4; - p = lj_buf_more(sb, width > len ? width : len); - if (!(sf & STRFMT_F_LEFT)) while (width-- > len) *p++ = ' '; - if (prefix) *p++ = prefix; - *p++ = (char)(ch >> 16); *p++ = (char)(ch >> 8); *p++ = (char)ch; - if ((sf & STRFMT_F_LEFT)) while (width-- > len) *p++ = ' '; - setsbufP(sb, p); - } else { /* Delegate to sprintf() for now. */ - uint8_t width = (uint8_t)STRFMT_WIDTH(sf), prec = (uint8_t)STRFMT_PREC(sf); - char fmt[1+5+2+3+1+1], *p = fmt; - *p++ = '%'; - if ((sf & STRFMT_F_LEFT)) *p++ = '-'; - if ((sf & STRFMT_F_PLUS)) *p++ = '+'; - if ((sf & STRFMT_F_ZERO)) *p++ = '0'; - if ((sf & STRFMT_F_SPACE)) *p++ = ' '; - if ((sf & STRFMT_F_ALT)) *p++ = '#'; - if (width) { - uint8_t x = width / 10, y = width % 10; - if (x) *p++ = '0' + x; - *p++ = '0' + y; - } - if (prec != 255) { - uint8_t x = prec / 10, y = prec % 10; - *p++ = '.'; - if (x) *p++ = '0' + x; - *p++ = '0' + y; - } - *p++ = (0x67666561 >> (STRFMT_FP(sf)<<3)) ^ ((sf & STRFMT_F_UPPER)?0x20:0); - *p = '\0'; - p = lj_buf_more(sb, STRFMT_FMTNUMBUF); - setsbufP(sb, p + sprintf(p, fmt, n)); - } - return sb; -} - /* -- Conversions to strings ---------------------------------------------- */ /* Convert integer to string. */ @@ -427,14 +352,6 @@ GCstr * LJ_FASTCALL lj_strfmt_int(lua_State *L, int32_t k) return lj_str_new(L, buf, len); } -/* Convert number to string. */ -GCstr * LJ_FASTCALL lj_strfmt_num(lua_State *L, cTValue *o) -{ - char buf[STRFMT_MAXBUF_NUM]; - MSize len = (MSize)(lj_strfmt_wnum(buf, o) - buf); - return lj_str_new(L, buf, len); -} - /* Convert integer or number to string. */ GCstr * LJ_FASTCALL lj_strfmt_number(lua_State *L, cTValue *o) { @@ -510,12 +427,9 @@ const char *lj_strfmt_pushvf(lua_State *L, const char *fmt, va_list argp) case STRFMT_UINT: lj_strfmt_putfxint(sb, sf, va_arg(argp, uint32_t)); break; - case STRFMT_NUM: { - TValue tv; - tv.n = va_arg(argp, lua_Number); - setsbufP(sb, lj_strfmt_wnum(lj_buf_more(sb, STRFMT_MAXBUF_NUM), &tv)); + case STRFMT_NUM: + lj_strfmt_putfnum(sb, STRFMT_G14, va_arg(argp, lua_Number)); break; - } case STRFMT_STR: { const char *s = va_arg(argp, char *); if (s == NULL) s = "(null)"; diff --git a/Build/source/libs/luajit/LuaJIT-src/src/lj_strfmt.h b/Build/source/libs/luajit/LuaJIT-src/src/lj_strfmt.h index dcfaf2e393b..a38bc7c38e1 100644 --- a/Build/source/libs/luajit/LuaJIT-src/src/lj_strfmt.h +++ b/Build/source/libs/luajit/LuaJIT-src/src/lj_strfmt.h @@ -1,6 +1,6 @@ /* ** String formatting. -** Copyright (C) 2005-2015 Mike Pall. See Copyright Notice in luajit.h +** Copyright (C) 2005-2016 Mike Pall. See Copyright Notice in luajit.h */ #ifndef _LJ_STRFMT_H @@ -64,11 +64,12 @@ typedef enum FormatType { #define STRFMT_S (STRFMT_STR) #define STRFMT_U (STRFMT_UINT) #define STRFMT_X (STRFMT_UINT|STRFMT_T_HEX) +#define STRFMT_G14 (STRFMT_G | ((14+1) << STRFMT_SH_PREC)) /* Maximum buffer sizes for conversions. */ #define STRFMT_MAXBUF_XINT (1+22) /* '0' prefix + uint64_t in octal. */ #define STRFMT_MAXBUF_INT (1+10) /* Sign + int32_t in decimal. */ -#define STRFMT_MAXBUF_NUM LUAI_MAXNUMBER2STR +#define STRFMT_MAXBUF_NUM 32 /* Must correspond with STRFMT_G14. */ #define STRFMT_MAXBUF_PTR (2+2*sizeof(ptrdiff_t)) /* "0x" + hex ptr. */ /* Format parser. */ @@ -83,10 +84,9 @@ static LJ_AINLINE void lj_strfmt_init(FormatState *fs, const char *p, MSize len) /* Raw conversions. */ LJ_FUNC char * LJ_FASTCALL lj_strfmt_wint(char *p, int32_t k); -LJ_FUNC char * LJ_FASTCALL lj_strfmt_wnum(char *p, cTValue *o); LJ_FUNC char * LJ_FASTCALL lj_strfmt_wptr(char *p, const void *v); LJ_FUNC char * LJ_FASTCALL lj_strfmt_wuleb128(char *p, uint32_t v); -LJ_FUNC const char *lj_strfmt_wstrnum(char *buf, cTValue *o, MSize *lenp); +LJ_FUNC const char *lj_strfmt_wstrnum(lua_State *L, cTValue *o, MSize *lenp); /* Unformatted conversions to buffer. */ LJ_FUNC SBuf * LJ_FASTCALL lj_strfmt_putint(SBuf *sb, int32_t k); diff --git a/Build/source/libs/luajit/LuaJIT-src/src/lj_strfmt_num.c b/Build/source/libs/luajit/LuaJIT-src/src/lj_strfmt_num.c new file mode 100644 index 00000000000..ab84fda76d2 --- /dev/null +++ b/Build/source/libs/luajit/LuaJIT-src/src/lj_strfmt_num.c @@ -0,0 +1,591 @@ +/* +** String formatting for floating-point numbers. +** Copyright (C) 2005-2016 Mike Pall. See Copyright Notice in luajit.h +** Contributed by Peter Cawley. +*/ + +#include <stdio.h> + +#define lj_strfmt_num_c +#define LUA_CORE + +#include "lj_obj.h" +#include "lj_buf.h" +#include "lj_str.h" +#include "lj_strfmt.h" + +/* -- Precomputed tables -------------------------------------------------- */ + +/* Rescale factors to push the exponent of a number towards zero. */ +#define RESCALE_EXPONENTS(P, N) \ + P(308), P(289), P(270), P(250), P(231), P(212), P(193), P(173), P(154), \ + P(135), P(115), P(96), P(77), P(58), P(38), P(0), P(0), P(0), N(39), N(58), \ + N(77), N(96), N(116), N(135), N(154), N(174), N(193), N(212), N(231), \ + N(251), N(270), N(289) + +#define ONE_E_P(X) 1e+0 ## X +#define ONE_E_N(X) 1e-0 ## X +static const int16_t rescale_e[] = { RESCALE_EXPONENTS(-, +) }; +static const double rescale_n[] = { RESCALE_EXPONENTS(ONE_E_P, ONE_E_N) }; +#undef ONE_E_N +#undef ONE_E_P + +/* +** For p in range -70 through 57, this table encodes pairs (m, e) such that +** 4*2^p <= (uint8_t)m*10^e, and is the smallest value for which this holds. +*/ +static const int8_t four_ulp_m_e[] = { + 34, -21, 68, -21, 14, -20, 28, -20, 55, -20, 2, -19, 3, -19, 5, -19, 9, -19, + -82, -18, 35, -18, 7, -17, -117, -17, 28, -17, 56, -17, 112, -16, -33, -16, + 45, -16, 89, -16, -78, -15, 36, -15, 72, -15, -113, -14, 29, -14, 57, -14, + 114, -13, -28, -13, 46, -13, 91, -12, -74, -12, 37, -12, 73, -12, 15, -11, 3, + -11, 59, -11, 2, -10, 3, -10, 5, -10, 1, -9, -69, -9, 38, -9, 75, -9, 15, -7, + 3, -7, 6, -7, 12, -6, -17, -7, 48, -7, 96, -7, -65, -6, 39, -6, 77, -6, -103, + -5, 31, -5, 62, -5, 123, -4, -11, -4, 49, -4, 98, -4, -60, -3, 4, -2, 79, -3, + 16, -2, 32, -2, 63, -2, 2, -1, 25, 0, 5, 1, 1, 2, 2, 2, 4, 2, 8, 2, 16, 2, + 32, 2, 64, 2, -128, 2, 26, 2, 52, 2, 103, 3, -51, 3, 41, 4, 82, 4, -92, 4, + 33, 4, 66, 4, -124, 5, 27, 5, 53, 5, 105, 6, 21, 6, 42, 6, 84, 6, 17, 7, 34, + 7, 68, 7, 2, 8, 3, 8, 6, 8, 108, 9, -41, 9, 43, 10, 86, 9, -84, 10, 35, 10, + 69, 10, -118, 11, 28, 11, 55, 12, 11, 13, 22, 13, 44, 13, 88, 13, -80, 13, + 36, 13, 71, 13, -115, 14, 29, 14, 57, 14, 113, 15, -30, 15, 46, 15, 91, 15, + 19, 16, 37, 16, 73, 16, 2, 17, 3, 17, 6, 17 +}; + +/* min(2^32-1, 10^e-1) for e in range 0 through 10 */ +static uint32_t ndigits_dec_threshold[] = { + 0, 9U, 99U, 999U, 9999U, 99999U, 999999U, + 9999999U, 99999999U, 999999999U, 0xffffffffU +}; + +/* -- Helper functions ---------------------------------------------------- */ + +/* Compute the number of digits in the decimal representation of x. */ +static MSize ndigits_dec(uint32_t x) +{ + MSize t = ((lj_fls(x | 1) * 77) >> 8) + 1; /* 2^8/77 is roughly log2(10) */ + return t + (x > ndigits_dec_threshold[t]); +} + +#define WINT_R(x, sh, sc) \ + { uint32_t d = (x*(((1<<sh)+sc-1)/sc))>>sh; x -= d*sc; *p++ = (char)('0'+d); } + +/* Write 9-digit unsigned integer to buffer. */ +static char *lj_strfmt_wuint9(char *p, uint32_t u) +{ + uint32_t v = u / 10000, w; + u -= v * 10000; + w = v / 10000; + v -= w * 10000; + *p++ = (char)('0'+w); + WINT_R(v, 23, 1000) + WINT_R(v, 12, 100) + WINT_R(v, 10, 10) + *p++ = (char)('0'+v); + WINT_R(u, 23, 1000) + WINT_R(u, 12, 100) + WINT_R(u, 10, 10) + *p++ = (char)('0'+u); + return p; +} +#undef WINT_R + +/* -- Extended precision arithmetic --------------------------------------- */ + +/* +** The "nd" format is a fixed-precision decimal representation for numbers. It +** consists of up to 64 uint32_t values, with each uint32_t storing a value +** in the range [0, 1e9). A number in "nd" format consists of three variables: +** +** uint32_t nd[64]; +** uint32_t ndlo; +** uint32_t ndhi; +** +** The integral part of the number is stored in nd[0 ... ndhi], the value of +** which is sum{i in [0, ndhi] | nd[i] * 10^(9*i)}. If the fractional part of +** the number is zero, ndlo is zero. Otherwise, the fractional part is stored +** in nd[ndlo ... 63], the value of which is taken to be +** sum{i in [ndlo, 63] | nd[i] * 10^(9*(i-64))}. +** +** If the array part had 128 elements rather than 64, then every double would +** have an exact representation in "nd" format. With 64 elements, all integral +** doubles have an exact representation, and all non-integral doubles have +** enough digits to make both %.99e and %.99f do the right thing. +*/ + +#if LJ_64 +#define ND_MUL2K_MAX_SHIFT 29 +#define ND_MUL2K_DIV1E9(val) ((uint32_t)((val) / 1000000000)) +#else +#define ND_MUL2K_MAX_SHIFT 11 +#define ND_MUL2K_DIV1E9(val) ((uint32_t)((val) >> 9) / 1953125) +#endif + +/* Multiply nd by 2^k and add carry_in (ndlo is assumed to be zero). */ +static uint32_t nd_mul2k(uint32_t* nd, uint32_t ndhi, uint32_t k, + uint32_t carry_in, SFormat sf) +{ + uint32_t i, ndlo = 0, start = 1; + /* Performance hacks. */ + if (k > ND_MUL2K_MAX_SHIFT*2 && STRFMT_FP(sf) != STRFMT_FP(STRFMT_T_FP_F)) { + start = ndhi - (STRFMT_PREC(sf) + 17) / 8; + } + /* Real logic. */ + while (k >= ND_MUL2K_MAX_SHIFT) { + for (i = ndlo; i <= ndhi; i++) { + uint64_t val = ((uint64_t)nd[i] << ND_MUL2K_MAX_SHIFT) | carry_in; + carry_in = ND_MUL2K_DIV1E9(val); + nd[i] = (uint32_t)val - carry_in * 1000000000; + } + if (carry_in) { + nd[++ndhi] = carry_in; carry_in = 0; + if(start++ == ndlo) ++ndlo; + } + k -= ND_MUL2K_MAX_SHIFT; + } + if (k) { + for (i = ndlo; i <= ndhi; i++) { + uint64_t val = ((uint64_t)nd[i] << k) | carry_in; + carry_in = ND_MUL2K_DIV1E9(val); + nd[i] = (uint32_t)val - carry_in * 1000000000; + } + if (carry_in) nd[++ndhi] = carry_in; + } + return ndhi; +} + +/* Divide nd by 2^k (ndlo is assumed to be zero). */ +static uint32_t nd_div2k(uint32_t* nd, uint32_t ndhi, uint32_t k, SFormat sf) +{ + uint32_t ndlo = 0, stop1 = ~0, stop2 = ~0; + /* Performance hacks. */ + if (!ndhi) { + if (!nd[0]) { + return 0; + } else { + uint32_t s = lj_ffs(nd[0]); + if (s >= k) { nd[0] >>= k; return 0; } + nd[0] >>= s; k -= s; + } + } + if (k > 18) { + if (STRFMT_FP(sf) == STRFMT_FP(STRFMT_T_FP_F)) { + stop1 = 63 - (int32_t)STRFMT_PREC(sf) / 9; + } else { + int32_t floorlog2 = ndhi * 29 + lj_fls(nd[ndhi]) - k; + int32_t floorlog10 = (int32_t)(floorlog2 * 0.30102999566398114); + stop1 = 62 + (floorlog10 - (int32_t)STRFMT_PREC(sf)) / 9; + stop2 = 61 + ndhi - (int32_t)STRFMT_PREC(sf) / 8; + } + } + /* Real logic. */ + while (k >= 9) { + uint32_t i = ndhi, carry = 0; + for (;;) { + uint32_t val = nd[i]; + nd[i] = (val >> 9) + carry; + carry = (val & 0x1ff) * 1953125; + if (i == ndlo) break; + i = (i - 1) & 0x3f; + } + if (ndlo != stop1 && ndlo != stop2) { + if (carry) { ndlo = (ndlo - 1) & 0x3f; nd[ndlo] = carry; } + if (!nd[ndhi]) { ndhi = (ndhi - 1) & 0x3f; stop2--; } + } else if (!nd[ndhi]) { + if (ndhi != ndlo) { ndhi = (ndhi - 1) & 0x3f; stop2--; } + else return ndlo; + } + k -= 9; + } + if (k) { + uint32_t mask = (1U << k) - 1, mul = 1000000000 >> k, i = ndhi, carry = 0; + for (;;) { + uint32_t val = nd[i]; + nd[i] = (val >> k) + carry; + carry = (val & mask) * mul; + if (i == ndlo) break; + i = (i - 1) & 0x3f; + } + if (carry) { ndlo = (ndlo - 1) & 0x3f; nd[ndlo] = carry; } + } + return ndlo; +} + +/* Add m*10^e to nd (assumes ndlo <= e/9 <= ndhi and 0 <= m <= 9). */ +static uint32_t nd_add_m10e(uint32_t* nd, uint32_t ndhi, uint8_t m, int32_t e) +{ + uint32_t i, carry; + if (e >= 0) { + i = (uint32_t)e/9; + carry = m * (ndigits_dec_threshold[e - (int32_t)i*9] + 1); + } else { + int32_t f = (e-8)/9; + i = (uint32_t)(64 + f); + carry = m * (ndigits_dec_threshold[e - f*9] + 1); + } + for (;;) { + uint32_t val = nd[i] + carry; + if (LJ_UNLIKELY(val >= 1000000000)) { + val -= 1000000000; + nd[i] = val; + if (LJ_UNLIKELY(i == ndhi)) { + ndhi = (ndhi + 1) & 0x3f; + nd[ndhi] = 1; + break; + } + carry = 1; + i = (i + 1) & 0x3f; + } else { + nd[i] = val; + break; + } + } + return ndhi; +} + +/* Test whether two "nd" values are equal in their most significant digits. */ +static int nd_similar(uint32_t* nd, uint32_t ndhi, uint32_t* ref, MSize hilen, + MSize prec) +{ + char nd9[9], ref9[9]; + if (hilen <= prec) { + if (LJ_UNLIKELY(nd[ndhi] != *ref)) return 0; + prec -= hilen; ref--; ndhi = (ndhi - 1) & 0x3f; + if (prec >= 9) { + if (LJ_UNLIKELY(nd[ndhi] != *ref)) return 0; + prec -= 9; ref--; ndhi = (ndhi - 1) & 0x3f; + } + } else { + prec -= hilen - 9; + } + lua_assert(prec < 9); + lj_strfmt_wuint9(nd9, nd[ndhi]); + lj_strfmt_wuint9(ref9, *ref); + return !memcmp(nd9, ref9, prec) && (nd9[prec] < '5') == (ref9[prec] < '5'); +} + +/* -- Formatted conversions to buffer ------------------------------------- */ + +/* Write formatted floating-point number to either sb or p. */ +static char *lj_strfmt_wfnum(SBuf *sb, SFormat sf, lua_Number n, char *p) +{ + MSize width = STRFMT_WIDTH(sf), prec = STRFMT_PREC(sf), len; + TValue t; + t.n = n; + if (LJ_UNLIKELY((t.u32.hi << 1) >= 0xffe00000)) { + /* Handle non-finite values uniformly for %a, %e, %f, %g. */ + int prefix = 0, ch = (sf & STRFMT_F_UPPER) ? 0x202020 : 0; + if (((t.u32.hi & 0x000fffff) | t.u32.lo) != 0) { + ch ^= ('n' << 16) | ('a' << 8) | 'n'; + if ((sf & STRFMT_F_SPACE)) prefix = ' '; + } else { + ch ^= ('i' << 16) | ('n' << 8) | 'f'; + if ((t.u32.hi & 0x80000000)) prefix = '-'; + else if ((sf & STRFMT_F_PLUS)) prefix = '+'; + else if ((sf & STRFMT_F_SPACE)) prefix = ' '; + } + len = 3 + (prefix != 0); + if (!p) p = lj_buf_more(sb, width > len ? width : len); + if (!(sf & STRFMT_F_LEFT)) while (width-- > len) *p++ = ' '; + if (prefix) *p++ = prefix; + *p++ = (char)(ch >> 16); *p++ = (char)(ch >> 8); *p++ = (char)ch; + } else if (STRFMT_FP(sf) == STRFMT_FP(STRFMT_T_FP_A)) { + /* %a */ + const char *hexdig = (sf & STRFMT_F_UPPER) ? "0123456789ABCDEFPX" + : "0123456789abcdefpx"; + int32_t e = (t.u32.hi >> 20) & 0x7ff; + char prefix = 0, eprefix = '+'; + if (t.u32.hi & 0x80000000) prefix = '-'; + else if ((sf & STRFMT_F_PLUS)) prefix = '+'; + else if ((sf & STRFMT_F_SPACE)) prefix = ' '; + t.u32.hi &= 0xfffff; + if (e) { + t.u32.hi |= 0x100000; + e -= 1023; + } else if (t.u32.lo | t.u32.hi) { + /* Non-zero denormal - normalise it. */ + uint32_t shift = t.u32.hi ? 20-lj_fls(t.u32.hi) : 52-lj_fls(t.u32.lo); + e = -1022 - shift; + t.u64 <<= shift; + } + /* abs(n) == t.u64 * 2^(e - 52) */ + /* If n != 0, bit 52 of t.u64 is set, and is the highest set bit. */ + if ((int32_t)prec < 0) { + /* Default precision: use smallest precision giving exact result. */ + prec = t.u32.lo ? 13-lj_ffs(t.u32.lo)/4 : 5-lj_ffs(t.u32.hi|0x100000)/4; + } else if (prec < 13) { + /* Precision is sufficiently low as to maybe require rounding. */ + t.u64 += (((uint64_t)1) << (51 - prec*4)); + } + if (e < 0) { + eprefix = '-'; + e = -e; + } + len = 5 + ndigits_dec((uint32_t)e) + prec + (prefix != 0) + + ((prec | (sf & STRFMT_F_ALT)) != 0); + if (!p) p = lj_buf_more(sb, width > len ? width : len); + if (!(sf & (STRFMT_F_LEFT | STRFMT_F_ZERO))) { + while (width-- > len) *p++ = ' '; + } + if (prefix) *p++ = prefix; + *p++ = '0'; + *p++ = hexdig[17]; /* x or X */ + if ((sf & (STRFMT_F_LEFT | STRFMT_F_ZERO)) == STRFMT_F_ZERO) { + while (width-- > len) *p++ = '0'; + } + *p++ = '0' + (t.u32.hi >> 20); /* Usually '1', sometimes '0' or '2'. */ + if ((prec | (sf & STRFMT_F_ALT))) { + /* Emit fractional part. */ + char *q = p + 1 + prec; + *p = '.'; + if (prec < 13) t.u64 >>= (52 - prec*4); + else while (prec > 13) p[prec--] = '0'; + while (prec) { p[prec--] = hexdig[t.u64 & 15]; t.u64 >>= 4; } + p = q; + } + *p++ = hexdig[16]; /* p or P */ + *p++ = eprefix; /* + or - */ + p = lj_strfmt_wint(p, e); + } else { + /* %e or %f or %g - begin by converting n to "nd" format. */ + uint32_t nd[64]; + uint32_t ndhi = 0, ndlo, i; + int32_t e = (t.u32.hi >> 20) & 0x7ff, ndebias = 0; + char prefix = 0, *q; + if (t.u32.hi & 0x80000000) prefix = '-'; + else if ((sf & STRFMT_F_PLUS)) prefix = '+'; + else if ((sf & STRFMT_F_SPACE)) prefix = ' '; + prec += ((int32_t)prec >> 31) & 7; /* Default precision is 6. */ + if (STRFMT_FP(sf) == STRFMT_FP(STRFMT_T_FP_G)) { + /* %g - decrement precision if non-zero (to make it like %e). */ + prec--; + prec ^= (uint32_t)((int32_t)prec >> 31); + } + if ((sf & STRFMT_T_FP_E) && prec < 14 && n != 0) { + /* Precision is sufficiently low that rescaling will probably work. */ + if ((ndebias = rescale_e[e >> 6])) { + t.n = n * rescale_n[e >> 6]; + t.u64 -= 2; /* Convert 2ulp below (later we convert 2ulp above). */ + nd[0] = 0x100000 | (t.u32.hi & 0xfffff); + e = ((t.u32.hi >> 20) & 0x7ff) - 1075 - (ND_MUL2K_MAX_SHIFT < 29); + goto load_t_lo; rescale_failed: + t.n = n; + e = (t.u32.hi >> 20) & 0x7ff; + ndebias = ndhi = 0; + } + } + nd[0] = t.u32.hi & 0xfffff; + if (e == 0) e++; else nd[0] |= 0x100000; + e -= 1043; + if (t.u32.lo) { + e -= 32 + (ND_MUL2K_MAX_SHIFT < 29); load_t_lo: +#if ND_MUL2K_MAX_SHIFT >= 29 + nd[0] = (nd[0] << 3) | (t.u32.lo >> 29); + ndhi = nd_mul2k(nd, ndhi, 29, t.u32.lo & 0x1fffffff, sf); +#elif ND_MUL2K_MAX_SHIFT >= 11 + ndhi = nd_mul2k(nd, ndhi, 11, t.u32.lo >> 21, sf); + ndhi = nd_mul2k(nd, ndhi, 11, (t.u32.lo >> 10) & 0x7ff, sf); + ndhi = nd_mul2k(nd, ndhi, 11, (t.u32.lo << 1) & 0x7ff, sf); +#else +#error "ND_MUL2K_MAX_SHIFT too small" +#endif + } + if (e >= 0) { + ndhi = nd_mul2k(nd, ndhi, (uint32_t)e, 0, sf); + ndlo = 0; + } else { + ndlo = nd_div2k(nd, ndhi, (uint32_t)-e, sf); + if (ndhi && !nd[ndhi]) ndhi--; + } + /* abs(n) == nd * 10^ndebias (for slightly loose interpretation of ==) */ + if ((sf & STRFMT_T_FP_E)) { + /* %e or %g - assume %e and start by calculating nd's exponent (nde). */ + char eprefix = '+'; + int32_t nde = -1; + MSize hilen; + if (ndlo && !nd[ndhi]) { + ndhi = 64; do {} while (!nd[--ndhi]); + nde -= 64 * 9; + } + hilen = ndigits_dec(nd[ndhi]); + nde += ndhi * 9 + hilen; + if (ndebias) { + /* + ** Rescaling was performed, but this introduced some error, and might + ** have pushed us across a rounding boundary. We check whether this + ** error affected the result by introducing even more error (2ulp in + ** either direction), and seeing whether a roundary boundary was + ** crossed. Having already converted the -2ulp case, we save off its + ** most significant digits, convert the +2ulp case, and compare them. + */ + int32_t eidx = e + 70 + (ND_MUL2K_MAX_SHIFT < 29) + + (t.u32.lo >= 0xfffffffe && !(~t.u32.hi << 12)); + const int8_t *m_e = four_ulp_m_e + eidx * 2; + lua_assert(0 <= eidx && eidx < 128); + nd[33] = nd[ndhi]; + nd[32] = nd[(ndhi - 1) & 0x3f]; + nd[31] = nd[(ndhi - 2) & 0x3f]; + nd_add_m10e(nd, ndhi, (uint8_t)*m_e, m_e[1]); + if (LJ_UNLIKELY(!nd_similar(nd, ndhi, nd + 33, hilen, prec + 1))) { + goto rescale_failed; + } + } + if ((int32_t)(prec - nde) < (0x3f & -(int32_t)ndlo) * 9) { + /* Precision is sufficiently low as to maybe require rounding. */ + ndhi = nd_add_m10e(nd, ndhi, 5, nde - prec - 1); + nde += (hilen != ndigits_dec(nd[ndhi])); + } + nde += ndebias; + if ((sf & STRFMT_T_FP_F)) { + /* %g */ + if ((int32_t)prec >= nde && nde >= -4) { + if (nde < 0) ndhi = 0; + prec -= nde; + goto g_format_like_f; + } else if (!(sf & STRFMT_F_ALT) && prec && width > 5) { + /* Decrease precision in order to strip trailing zeroes. */ + char tail[9]; + uint32_t maxprec = hilen - 1 + ((ndhi - ndlo) & 0x3f) * 9; + if (prec >= maxprec) prec = maxprec; + else ndlo = (ndhi - (((int32_t)(prec - hilen) + 9) / 9)) & 0x3f; + i = prec - hilen - (((ndhi - ndlo) & 0x3f) * 9) + 10; + lj_strfmt_wuint9(tail, nd[ndlo]); + while (prec && tail[--i] == '0') { + prec--; + if (!i) { + if (ndlo == ndhi) { prec = 0; break; } + lj_strfmt_wuint9(tail, nd[++ndlo]); + i = 9; + } + } + } + } + if (nde < 0) { + /* Make nde non-negative. */ + eprefix = '-'; + nde = -nde; + } + len = 3 + prec + (prefix != 0) + ndigits_dec((uint32_t)nde) + (nde < 10) + + ((prec | (sf & STRFMT_F_ALT)) != 0); + if (!p) p = lj_buf_more(sb, (width > len ? width : len) + 5); + if (!(sf & (STRFMT_F_LEFT | STRFMT_F_ZERO))) { + while (width-- > len) *p++ = ' '; + } + if (prefix) *p++ = prefix; + if ((sf & (STRFMT_F_LEFT | STRFMT_F_ZERO)) == STRFMT_F_ZERO) { + while (width-- > len) *p++ = '0'; + } + q = lj_strfmt_wint(p + 1, nd[ndhi]); + p[0] = p[1]; /* Put leading digit in the correct place. */ + if ((prec | (sf & STRFMT_F_ALT))) { + /* Emit fractional part. */ + p[1] = '.'; p += 2; + prec -= (q - p); p = q; /* Account for the digits already emitted. */ + /* Then emit chunks of 9 digits (this may emit 8 digits too many). */ + for (i = ndhi; (int32_t)prec > 0 && i != ndlo; prec -= 9) { + i = (i - 1) & 0x3f; + p = lj_strfmt_wuint9(p, nd[i]); + } + if ((sf & STRFMT_T_FP_F) && !(sf & STRFMT_F_ALT)) { + /* %g (and not %#g) - strip trailing zeroes. */ + p += (int32_t)prec & ((int32_t)prec >> 31); + while (p[-1] == '0') p--; + if (p[-1] == '.') p--; + } else { + /* %e (or %#g) - emit trailing zeroes. */ + while ((int32_t)prec > 0) { *p++ = '0'; prec--; } + p += (int32_t)prec; + } + } else { + p++; + } + *p++ = (sf & STRFMT_F_UPPER) ? 'E' : 'e'; + *p++ = eprefix; /* + or - */ + if (nde < 10) *p++ = '0'; /* Always at least two digits of exponent. */ + p = lj_strfmt_wint(p, nde); + } else { + /* %f (or, shortly, %g in %f style) */ + if (prec < (MSize)(0x3f & -(int32_t)ndlo) * 9) { + /* Precision is sufficiently low as to maybe require rounding. */ + ndhi = nd_add_m10e(nd, ndhi, 5, 0 - prec - 1); + } + g_format_like_f: + if ((sf & STRFMT_T_FP_E) && !(sf & STRFMT_F_ALT) && prec && width) { + /* Decrease precision in order to strip trailing zeroes. */ + if (ndlo) { + /* nd has a fractional part; we need to look at its digits. */ + char tail[9]; + uint32_t maxprec = (64 - ndlo) * 9; + if (prec >= maxprec) prec = maxprec; + else ndlo = 64 - (prec + 8) / 9; + i = prec - ((63 - ndlo) * 9); + lj_strfmt_wuint9(tail, nd[ndlo]); + while (prec && tail[--i] == '0') { + prec--; + if (!i) { + if (ndlo == 63) { prec = 0; break; } + lj_strfmt_wuint9(tail, nd[++ndlo]); + i = 9; + } + } + } else { + /* nd has no fractional part, so precision goes straight to zero. */ + prec = 0; + } + } + len = ndhi * 9 + ndigits_dec(nd[ndhi]) + prec + (prefix != 0) + + ((prec | (sf & STRFMT_F_ALT)) != 0); + if (!p) p = lj_buf_more(sb, (width > len ? width : len) + 8); + if (!(sf & (STRFMT_F_LEFT | STRFMT_F_ZERO))) { + while (width-- > len) *p++ = ' '; + } + if (prefix) *p++ = prefix; + if ((sf & (STRFMT_F_LEFT | STRFMT_F_ZERO)) == STRFMT_F_ZERO) { + while (width-- > len) *p++ = '0'; + } + /* Emit integer part. */ + p = lj_strfmt_wint(p, nd[ndhi]); + i = ndhi; + while (i) p = lj_strfmt_wuint9(p, nd[--i]); + if ((prec | (sf & STRFMT_F_ALT))) { + /* Emit fractional part. */ + *p++ = '.'; + /* Emit chunks of 9 digits (this may emit 8 digits too many). */ + while ((int32_t)prec > 0 && i != ndlo) { + i = (i - 1) & 0x3f; + p = lj_strfmt_wuint9(p, nd[i]); + prec -= 9; + } + if ((sf & STRFMT_T_FP_E) && !(sf & STRFMT_F_ALT)) { + /* %g (and not %#g) - strip trailing zeroes. */ + p += (int32_t)prec & ((int32_t)prec >> 31); + while (p[-1] == '0') p--; + if (p[-1] == '.') p--; + } else { + /* %f (or %#g) - emit trailing zeroes. */ + while ((int32_t)prec > 0) { *p++ = '0'; prec--; } + p += (int32_t)prec; + } + } + } + } + if ((sf & STRFMT_F_LEFT)) while (width-- > len) *p++ = ' '; + return p; +} + +/* Add formatted floating-point number to buffer. */ +SBuf *lj_strfmt_putfnum(SBuf *sb, SFormat sf, lua_Number n) +{ + setsbufP(sb, lj_strfmt_wfnum(sb, sf, n, NULL)); + return sb; +} + +/* -- Conversions to strings ---------------------------------------------- */ + +/* Convert number to string. */ +GCstr * LJ_FASTCALL lj_strfmt_num(lua_State *L, cTValue *o) +{ + char buf[STRFMT_MAXBUF_NUM]; + MSize len = (MSize)(lj_strfmt_wfnum(NULL, STRFMT_G14, o->n, buf) - buf); + return lj_str_new(L, buf, len); +} + diff --git a/Build/source/libs/luajit/LuaJIT-src/src/lj_strscan.c b/Build/source/libs/luajit/LuaJIT-src/src/lj_strscan.c index d3c5ba9124f..7c5171328e8 100644 --- a/Build/source/libs/luajit/LuaJIT-src/src/lj_strscan.c +++ b/Build/source/libs/luajit/LuaJIT-src/src/lj_strscan.c @@ -1,6 +1,6 @@ /* ** String scanning. -** Copyright (C) 2005-2015 Mike Pall. See Copyright Notice in luajit.h +** Copyright (C) 2005-2016 Mike Pall. See Copyright Notice in luajit.h */ #include <math.h> diff --git a/Build/source/libs/luajit/LuaJIT-src/src/lj_strscan.h b/Build/source/libs/luajit/LuaJIT-src/src/lj_strscan.h index 77606893640..b3ee9e528df 100644 --- a/Build/source/libs/luajit/LuaJIT-src/src/lj_strscan.h +++ b/Build/source/libs/luajit/LuaJIT-src/src/lj_strscan.h @@ -1,6 +1,6 @@ /* ** String scanning. -** Copyright (C) 2005-2015 Mike Pall. See Copyright Notice in luajit.h +** Copyright (C) 2005-2016 Mike Pall. See Copyright Notice in luajit.h */ #ifndef _LJ_STRSCAN_H diff --git a/Build/source/libs/luajit/LuaJIT-src/src/lj_tab.c b/Build/source/libs/luajit/LuaJIT-src/src/lj_tab.c index 88bf1089b5b..8011212f1b1 100644 --- a/Build/source/libs/luajit/LuaJIT-src/src/lj_tab.c +++ b/Build/source/libs/luajit/LuaJIT-src/src/lj_tab.c @@ -1,6 +1,6 @@ /* ** Table handling. -** Copyright (C) 2005-2015 Mike Pall. See Copyright Notice in luajit.h +** Copyright (C) 2005-2016 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 diff --git a/Build/source/libs/luajit/LuaJIT-src/src/lj_tab.h b/Build/source/libs/luajit/LuaJIT-src/src/lj_tab.h index 7cf031be9af..f06fcf611ad 100644 --- a/Build/source/libs/luajit/LuaJIT-src/src/lj_tab.h +++ b/Build/source/libs/luajit/LuaJIT-src/src/lj_tab.h @@ -1,6 +1,6 @@ /* ** Table handling. -** Copyright (C) 2005-2015 Mike Pall. See Copyright Notice in luajit.h +** Copyright (C) 2005-2016 Mike Pall. See Copyright Notice in luajit.h */ #ifndef _LJ_TAB_H diff --git a/Build/source/libs/luajit/LuaJIT-src/src/lj_target.h b/Build/source/libs/luajit/LuaJIT-src/src/lj_target.h index 0daecb11c86..abea8d5b216 100644 --- a/Build/source/libs/luajit/LuaJIT-src/src/lj_target.h +++ b/Build/source/libs/luajit/LuaJIT-src/src/lj_target.h @@ -1,6 +1,6 @@ /* ** Definitions for target CPU. -** Copyright (C) 2005-2015 Mike Pall. See Copyright Notice in luajit.h +** Copyright (C) 2005-2016 Mike Pall. See Copyright Notice in luajit.h */ #ifndef _LJ_TARGET_H diff --git a/Build/source/libs/luajit/LuaJIT-src/src/lj_target_arm.h b/Build/source/libs/luajit/LuaJIT-src/src/lj_target_arm.h index 0a243b3740b..36959dbcc4e 100644 --- a/Build/source/libs/luajit/LuaJIT-src/src/lj_target_arm.h +++ b/Build/source/libs/luajit/LuaJIT-src/src/lj_target_arm.h @@ -1,6 +1,6 @@ /* ** Definitions for ARM CPUs. -** Copyright (C) 2005-2015 Mike Pall. See Copyright Notice in luajit.h +** Copyright (C) 2005-2016 Mike Pall. See Copyright Notice in luajit.h */ #ifndef _LJ_TARGET_ARM_H diff --git a/Build/source/libs/luajit/LuaJIT-src/src/lj_target_arm64.h b/Build/source/libs/luajit/LuaJIT-src/src/lj_target_arm64.h index 99e0adc9d66..57ab134f98e 100644 --- a/Build/source/libs/luajit/LuaJIT-src/src/lj_target_arm64.h +++ b/Build/source/libs/luajit/LuaJIT-src/src/lj_target_arm64.h @@ -1,6 +1,6 @@ /* ** Definitions for ARM64 CPUs. -** Copyright (C) 2005-2015 Mike Pall. See Copyright Notice in luajit.h +** Copyright (C) 2005-2016 Mike Pall. See Copyright Notice in luajit.h */ #ifndef _LJ_TARGET_ARM64_H diff --git a/Build/source/libs/luajit/LuaJIT-src/src/lj_target_mips.h b/Build/source/libs/luajit/LuaJIT-src/src/lj_target_mips.h index 76645bcac5e..bafa817a38a 100644 --- a/Build/source/libs/luajit/LuaJIT-src/src/lj_target_mips.h +++ b/Build/source/libs/luajit/LuaJIT-src/src/lj_target_mips.h @@ -1,6 +1,6 @@ /* ** Definitions for MIPS CPUs. -** Copyright (C) 2005-2015 Mike Pall. See Copyright Notice in luajit.h +** Copyright (C) 2005-2016 Mike Pall. See Copyright Notice in luajit.h */ #ifndef _LJ_TARGET_MIPS_H @@ -13,11 +13,15 @@ _(R8) _(R9) _(R10) _(R11) _(R12) _(R13) _(R14) _(R15) \ _(R16) _(R17) _(R18) _(R19) _(R20) _(R21) _(R22) _(R23) \ _(R24) _(R25) _(SYS1) _(SYS2) _(R28) _(SP) _(R30) _(RA) +#if LJ_SOFTFP +#define FPRDEF(_) +#else #define FPRDEF(_) \ _(F0) _(F1) _(F2) _(F3) _(F4) _(F5) _(F6) _(F7) \ _(F8) _(F9) _(F10) _(F11) _(F12) _(F13) _(F14) _(F15) \ _(F16) _(F17) _(F18) _(F19) _(F20) _(F21) _(F22) _(F23) \ _(F24) _(F25) _(F26) _(F27) _(F28) _(F29) _(F30) _(F31) +#endif #define VRIDDEF(_) #define RIDENUM(name) RID_##name, @@ -38,7 +42,11 @@ enum { RID_RETHI = RID_R2, RID_RETLO = RID_R3, #endif +#if LJ_SOFTFP + RID_FPRET = RID_R2, +#else RID_FPRET = RID_F0, +#endif RID_CFUNCADDR = RID_R25, /* These definitions must match with the *.dasc file(s): */ @@ -51,8 +59,12 @@ enum { /* Register ranges [min, max) and number of registers. */ RID_MIN_GPR = RID_R0, RID_MAX_GPR = RID_RA+1, - RID_MIN_FPR = RID_F0, + RID_MIN_FPR = RID_MAX_GPR, +#if LJ_SOFTFP + RID_MAX_FPR = RID_MIN_FPR, +#else RID_MAX_FPR = RID_F31+1, +#endif RID_NUM_GPR = RID_MAX_GPR - RID_MIN_GPR, RID_NUM_FPR = RID_MAX_FPR - RID_MIN_FPR /* Only even regs are used. */ }; @@ -67,28 +79,42 @@ enum { (RID2RSET(RID_ZERO)|RID2RSET(RID_TMP)|RID2RSET(RID_SP)|\ RID2RSET(RID_SYS1)|RID2RSET(RID_SYS2)|RID2RSET(RID_JGL)) #define RSET_GPR (RSET_RANGE(RID_MIN_GPR, RID_MAX_GPR) - RSET_FIXED) +#if LJ_SOFTFP +#define RSET_FPR 0 +#else #define RSET_FPR \ (RID2RSET(RID_F0)|RID2RSET(RID_F2)|RID2RSET(RID_F4)|RID2RSET(RID_F6)|\ RID2RSET(RID_F8)|RID2RSET(RID_F10)|RID2RSET(RID_F12)|RID2RSET(RID_F14)|\ RID2RSET(RID_F16)|RID2RSET(RID_F18)|RID2RSET(RID_F20)|RID2RSET(RID_F22)|\ RID2RSET(RID_F24)|RID2RSET(RID_F26)|RID2RSET(RID_F28)|RID2RSET(RID_F30)) +#endif #define RSET_ALL (RSET_GPR|RSET_FPR) #define RSET_INIT RSET_ALL #define RSET_SCRATCH_GPR \ (RSET_RANGE(RID_R1, RID_R15+1)|\ RID2RSET(RID_R24)|RID2RSET(RID_R25)|RID2RSET(RID_R28)) +#if LJ_SOFTFP +#define RSET_SCRATCH_FPR 0 +#else #define RSET_SCRATCH_FPR \ (RID2RSET(RID_F0)|RID2RSET(RID_F2)|RID2RSET(RID_F4)|RID2RSET(RID_F6)|\ RID2RSET(RID_F8)|RID2RSET(RID_F10)|RID2RSET(RID_F12)|RID2RSET(RID_F14)|\ RID2RSET(RID_F16)|RID2RSET(RID_F18)) +#endif #define RSET_SCRATCH (RSET_SCRATCH_GPR|RSET_SCRATCH_FPR) #define REGARG_FIRSTGPR RID_R4 #define REGARG_LASTGPR RID_R7 #define REGARG_NUMGPR 4 +#if LJ_ABI_SOFTFP +#define REGARG_FIRSTFPR 0 +#define REGARG_LASTFPR 0 +#define REGARG_NUMFPR 0 +#else #define REGARG_FIRSTFPR RID_F12 #define REGARG_LASTFPR RID_F14 #define REGARG_NUMFPR 2 +#endif /* -- Spill slots --------------------------------------------------------- */ @@ -111,7 +137,9 @@ enum { /* This definition must match with the *.dasc file(s). */ typedef struct { +#if !LJ_SOFTFP lua_Number fpr[RID_NUM_FPR]; /* Floating-point registers. */ +#endif int32_t gpr[RID_NUM_GPR]; /* General-purpose registers. */ int32_t spill[256]; /* Spill slots. */ } ExitState; diff --git a/Build/source/libs/luajit/LuaJIT-src/src/lj_target_ppc.h b/Build/source/libs/luajit/LuaJIT-src/src/lj_target_ppc.h index 99867688b7d..bbf22390c46 100644 --- a/Build/source/libs/luajit/LuaJIT-src/src/lj_target_ppc.h +++ b/Build/source/libs/luajit/LuaJIT-src/src/lj_target_ppc.h @@ -1,6 +1,6 @@ /* ** Definitions for PPC CPUs. -** Copyright (C) 2005-2015 Mike Pall. See Copyright Notice in luajit.h +** Copyright (C) 2005-2016 Mike Pall. See Copyright Notice in luajit.h */ #ifndef _LJ_TARGET_PPC_H diff --git a/Build/source/libs/luajit/LuaJIT-src/src/lj_target_x86.h b/Build/source/libs/luajit/LuaJIT-src/src/lj_target_x86.h index fc9d37024b0..289f83e1c8b 100644 --- a/Build/source/libs/luajit/LuaJIT-src/src/lj_target_x86.h +++ b/Build/source/libs/luajit/LuaJIT-src/src/lj_target_x86.h @@ -1,6 +1,6 @@ /* ** Definitions for x86 and x64 CPUs. -** Copyright (C) 2005-2015 Mike Pall. See Copyright Notice in luajit.h +** Copyright (C) 2005-2016 Mike Pall. See Copyright Notice in luajit.h */ #ifndef _LJ_TARGET_X86_H diff --git a/Build/source/libs/luajit/LuaJIT-src/src/lj_trace.c b/Build/source/libs/luajit/LuaJIT-src/src/lj_trace.c index 42f4321d5d2..7970aba6ae0 100644 --- a/Build/source/libs/luajit/LuaJIT-src/src/lj_trace.c +++ b/Build/source/libs/luajit/LuaJIT-src/src/lj_trace.c @@ -1,6 +1,6 @@ /* ** Trace management. -** Copyright (C) 2005-2015 Mike Pall. See Copyright Notice in luajit.h +** Copyright (C) 2005-2016 Mike Pall. See Copyright Notice in luajit.h */ #define lj_trace_c @@ -274,7 +274,7 @@ int lj_trace_flushall(lua_State *L) if (T->root == 0) trace_flushroot(J, T); lj_gdbjit_deltrace(J, T); - T->traceno = 0; + T->traceno = T->link = 0; /* Blacklist the link for cont_stitch. */ setgcrefnull(J->trace[i]); } } @@ -284,6 +284,7 @@ int lj_trace_flushall(lua_State *L) memset(J->penalty, 0, sizeof(J->penalty)); /* Free the whole machine code and invalidate all exit stub groups. */ lj_mcode_free(J); + lj_ir_k64_freeall(J); memset(J->exitstubgroup, 0, sizeof(J->exitstubgroup)); lj_vmevent_send(L, TRACE, setstrV(L, L->top++, lj_str_newlit(L, "flush")); @@ -402,6 +403,7 @@ static void trace_start(jit_State *J) J->postproc = LJ_POST_NONE; lj_resetsplit(J); J->retryrec = 0; + J->ktracep = NULL; setgcref(J->cur.startpt, obj2gco(J->pt)); L = J->L; @@ -477,6 +479,9 @@ static void trace_stop(jit_State *J) lj_mcode_commit(J, J->cur.mcode); J->postproc = LJ_POST_NONE; trace_save(J, T); + if (J->ktracep) { /* Patch K64Array slot with the final GCtrace pointer. */ + setgcV(J->L, J->ktracep, obj2gco(T), LJ_TTRACE); + } L = J->L; lj_vmevent_send(L, TRACE, diff --git a/Build/source/libs/luajit/LuaJIT-src/src/lj_trace.h b/Build/source/libs/luajit/LuaJIT-src/src/lj_trace.h index 9eaf91b0e33..6faa1aa3cde 100644 --- a/Build/source/libs/luajit/LuaJIT-src/src/lj_trace.h +++ b/Build/source/libs/luajit/LuaJIT-src/src/lj_trace.h @@ -1,6 +1,6 @@ /* ** Trace management. -** Copyright (C) 2005-2015 Mike Pall. See Copyright Notice in luajit.h +** Copyright (C) 2005-2016 Mike Pall. See Copyright Notice in luajit.h */ #ifndef _LJ_TRACE_H diff --git a/Build/source/libs/luajit/LuaJIT-src/src/lj_traceerr.h b/Build/source/libs/luajit/LuaJIT-src/src/lj_traceerr.h index 12e90d0395c..9c01ffb7ac5 100644 --- a/Build/source/libs/luajit/LuaJIT-src/src/lj_traceerr.h +++ b/Build/source/libs/luajit/LuaJIT-src/src/lj_traceerr.h @@ -1,6 +1,6 @@ /* ** Trace compiler error messages. -** Copyright (C) 2005-2015 Mike Pall. See Copyright Notice in luajit.h +** Copyright (C) 2005-2016 Mike Pall. See Copyright Notice in luajit.h */ /* This file may be included multiple times with different TREDEF macros. */ @@ -25,8 +25,6 @@ TREDEF(BADTYPE, "bad argument type") TREDEF(CJITOFF, "JIT compilation disabled for function") TREDEF(CUNROLL, "call unroll limit reached") TREDEF(DOWNREC, "down-recursion, restarting") -TREDEF(NYICF, "NYI: C function %s") -TREDEF(NYIFF, "NYI: FastFunc %s") TREDEF(NYIFFU, "NYI: unsupported variant of FastFunc %s") TREDEF(NYIRETL, "NYI: return to lower frame") diff --git a/Build/source/libs/luajit/LuaJIT-src/src/lj_udata.c b/Build/source/libs/luajit/LuaJIT-src/src/lj_udata.c index d401a3d8e85..71697a42fb9 100644 --- a/Build/source/libs/luajit/LuaJIT-src/src/lj_udata.c +++ b/Build/source/libs/luajit/LuaJIT-src/src/lj_udata.c @@ -1,6 +1,6 @@ /* ** Userdata handling. -** Copyright (C) 2005-2015 Mike Pall. See Copyright Notice in luajit.h +** Copyright (C) 2005-2016 Mike Pall. See Copyright Notice in luajit.h */ #define lj_udata_c diff --git a/Build/source/libs/luajit/LuaJIT-src/src/lj_udata.h b/Build/source/libs/luajit/LuaJIT-src/src/lj_udata.h index 676e970f488..81c15816da5 100644 --- a/Build/source/libs/luajit/LuaJIT-src/src/lj_udata.h +++ b/Build/source/libs/luajit/LuaJIT-src/src/lj_udata.h @@ -1,6 +1,6 @@ /* ** Userdata handling. -** Copyright (C) 2005-2015 Mike Pall. See Copyright Notice in luajit.h +** Copyright (C) 2005-2016 Mike Pall. See Copyright Notice in luajit.h */ #ifndef _LJ_UDATA_H diff --git a/Build/source/libs/luajit/LuaJIT-src/src/lj_vm.h b/Build/source/libs/luajit/LuaJIT-src/src/lj_vm.h index b31e22f70f7..be35295d261 100644 --- a/Build/source/libs/luajit/LuaJIT-src/src/lj_vm.h +++ b/Build/source/libs/luajit/LuaJIT-src/src/lj_vm.h @@ -1,6 +1,6 @@ /* ** Assembler VM interface definitions. -** Copyright (C) 2005-2015 Mike Pall. See Copyright Notice in luajit.h +** Copyright (C) 2005-2016 Mike Pall. See Copyright Notice in luajit.h */ #ifndef _LJ_VM_H @@ -50,7 +50,7 @@ LJ_ASMF void lj_vm_exit_handler(void); LJ_ASMF void lj_vm_exit_interp(void); /* Internal math helper functions. */ -#if LJ_TARGET_PPC || LJ_TARGET_ARM64 +#if LJ_TARGET_PPC || LJ_TARGET_ARM64 || (LJ_TARGET_MIPS && LJ_ABI_SOFTFP) #define lj_vm_floor floor #define lj_vm_ceil ceil #else @@ -66,6 +66,9 @@ LJ_ASMF double lj_vm_log2(double); #else #define lj_vm_log2 log2 #endif +#if !(defined(_LJ_DISPATCH_H) && LJ_TARGET_MIPS) +LJ_ASMF int32_t LJ_FASTCALL lj_vm_modi(int32_t, int32_t); +#endif #if LJ_HASJIT #if LJ_TARGET_X86ORX64 @@ -90,7 +93,6 @@ LJ_ASMF double lj_vm_exp2(double); #else #define lj_vm_exp2 exp2 #endif -LJ_ASMF int32_t LJ_FASTCALL lj_vm_modi(int32_t, int32_t); #if LJ_HASFFI LJ_ASMF int lj_vm_errno(void); #endif diff --git a/Build/source/libs/luajit/LuaJIT-src/src/lj_vmevent.c b/Build/source/libs/luajit/LuaJIT-src/src/lj_vmevent.c index 87ebcfbd286..3acdd2534e6 100644 --- a/Build/source/libs/luajit/LuaJIT-src/src/lj_vmevent.c +++ b/Build/source/libs/luajit/LuaJIT-src/src/lj_vmevent.c @@ -1,6 +1,6 @@ /* ** VM event handling. -** Copyright (C) 2005-2015 Mike Pall. See Copyright Notice in luajit.h +** Copyright (C) 2005-2016 Mike Pall. See Copyright Notice in luajit.h */ #include <stdio.h> diff --git a/Build/source/libs/luajit/LuaJIT-src/src/lj_vmevent.h b/Build/source/libs/luajit/LuaJIT-src/src/lj_vmevent.h index 231e00ecdf9..b9495b4f9ec 100644 --- a/Build/source/libs/luajit/LuaJIT-src/src/lj_vmevent.h +++ b/Build/source/libs/luajit/LuaJIT-src/src/lj_vmevent.h @@ -1,6 +1,6 @@ /* ** VM event handling. -** Copyright (C) 2005-2015 Mike Pall. See Copyright Notice in luajit.h +** Copyright (C) 2005-2016 Mike Pall. See Copyright Notice in luajit.h */ #ifndef _LJ_VMEVENT_H diff --git a/Build/source/libs/luajit/LuaJIT-src/src/lj_vmmath.c b/Build/source/libs/luajit/LuaJIT-src/src/lj_vmmath.c index ecad2950d93..e6622650503 100644 --- a/Build/source/libs/luajit/LuaJIT-src/src/lj_vmmath.c +++ b/Build/source/libs/luajit/LuaJIT-src/src/lj_vmmath.c @@ -1,6 +1,6 @@ /* ** Math helper functions for assembler VM. -** Copyright (C) 2005-2015 Mike Pall. See Copyright Notice in luajit.h +** Copyright (C) 2005-2016 Mike Pall. See Copyright Notice in luajit.h */ #define lj_vmmath_c @@ -57,6 +57,20 @@ double lj_vm_foldarith(double x, double y, int op) } } +#if (LJ_HASJIT && !(LJ_TARGET_ARM || LJ_TARGET_ARM64 || LJ_TARGET_PPC)) || LJ_TARGET_MIPS +int32_t LJ_FASTCALL lj_vm_modi(int32_t a, int32_t b) +{ + uint32_t y, ua, ub; + lua_assert(b != 0); /* This must be checked before using this function. */ + ua = a < 0 ? (uint32_t)-a : (uint32_t)a; + ub = b < 0 ? (uint32_t)-b : (uint32_t)b; + y = ua % ub; + if (y != 0 && (a^b) < 0) y = y - ub; + if (((int32_t)y^b) < 0) y = (uint32_t)-(int32_t)y; + return (int32_t)y; +} +#endif + #if LJ_HASJIT #ifdef LUAJIT_NO_LOG2 @@ -73,20 +87,6 @@ double lj_vm_exp2(double a) } #endif -#if !(LJ_TARGET_ARM || LJ_TARGET_ARM64 || LJ_TARGET_PPC) -int32_t LJ_FASTCALL lj_vm_modi(int32_t a, int32_t b) -{ - uint32_t y, ua, ub; - lua_assert(b != 0); /* This must be checked before using this function. */ - ua = a < 0 ? (uint32_t)-a : (uint32_t)a; - ub = b < 0 ? (uint32_t)-b : (uint32_t)b; - y = ua % ub; - if (y != 0 && (a^b) < 0) y = y - ub; - if (((int32_t)y^b) < 0) y = (uint32_t)-(int32_t)y; - return (int32_t)y; -} -#endif - #if !LJ_TARGET_X86ORX64 /* Unsigned x^k. */ static double lj_vm_powui(double x, uint32_t k) diff --git a/Build/source/libs/luajit/LuaJIT-src/src/ljamalg.c b/Build/source/libs/luajit/LuaJIT-src/src/ljamalg.c index be0c52d743e..4c44de27ad8 100644 --- a/Build/source/libs/luajit/LuaJIT-src/src/ljamalg.c +++ b/Build/source/libs/luajit/LuaJIT-src/src/ljamalg.c @@ -1,6 +1,6 @@ /* ** LuaJIT core and libraries amalgamation. -** Copyright (C) 2005-2015 Mike Pall. See Copyright Notice in luajit.h +** Copyright (C) 2005-2016 Mike Pall. See Copyright Notice in luajit.h */ /* @@ -46,6 +46,7 @@ #include "lj_vmmath.c" #include "lj_strscan.c" #include "lj_strfmt.c" +#include "lj_strfmt_num.c" #include "lj_api.c" #include "lj_profile.c" #include "lj_lex.c" diff --git a/Build/source/libs/luajit/LuaJIT-src/src/lua.h b/Build/source/libs/luajit/LuaJIT-src/src/lua.h index 64a930e3e38..fb4e69f4076 100644 --- a/Build/source/libs/luajit/LuaJIT-src/src/lua.h +++ b/Build/source/libs/luajit/LuaJIT-src/src/lua.h @@ -229,6 +229,7 @@ LUA_API int (lua_status) (lua_State *L); #define LUA_GCSTEP 5 #define LUA_GCSETPAUSE 6 #define LUA_GCSETSTEPMUL 7 +#define LUA_GCISRUNNING 9 LUA_API int (lua_gc) (lua_State *L, int what, int data); diff --git a/Build/source/libs/luajit/LuaJIT-src/src/luaconf.h b/Build/source/libs/luajit/LuaJIT-src/src/luaconf.h index 79f514825f8..4c24bb1a0e2 100644 --- a/Build/source/libs/luajit/LuaJIT-src/src/luaconf.h +++ b/Build/source/libs/luajit/LuaJIT-src/src/luaconf.h @@ -1,6 +1,6 @@ /* ** Configuration header. -** Copyright (C) 2005-2015 Mike Pall. See Copyright Notice in luajit.h +** Copyright (C) 2005-2016 Mike Pall. See Copyright Notice in luajit.h */ #ifndef luaconf_h @@ -37,7 +37,7 @@ #endif #define LUA_LROOT "/usr/local" #define LUA_LUADIR "/lua/5.1/" -#define LUA_LJDIR "/luajit-2.1.0-beta1/" +#define LUA_LJDIR "/luajit-2.1.0-beta2/" #ifdef LUA_ROOT #define LUA_JROOT LUA_ROOT diff --git a/Build/source/libs/luajit/LuaJIT-src/src/luajit.c b/Build/source/libs/luajit/LuaJIT-src/src/luajit.c index 0ebc73005f8..00e12bd32e3 100644 --- a/Build/source/libs/luajit/LuaJIT-src/src/luajit.c +++ b/Build/source/libs/luajit/LuaJIT-src/src/luajit.c @@ -1,6 +1,6 @@ /* ** LuaJIT frontend. Runs commands, scripts, read-eval-print (REPL) etc. -** Copyright (C) 2005-2015 Mike Pall. See Copyright Notice in luajit.h +** Copyright (C) 2005-2016 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 diff --git a/Build/source/libs/luajit/LuaJIT-src/src/luajit.h b/Build/source/libs/luajit/LuaJIT-src/src/luajit.h index 960418519ee..1d0a558cabc 100644 --- a/Build/source/libs/luajit/LuaJIT-src/src/luajit.h +++ b/Build/source/libs/luajit/LuaJIT-src/src/luajit.h @@ -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-2016 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 @@ -30,10 +30,10 @@ #include "lua.h" -#define LUAJIT_VERSION "LuaJIT 2.1.0-beta1" +#define LUAJIT_VERSION "LuaJIT 2.1.0-beta2" #define LUAJIT_VERSION_NUM 20100 /* Version 2.1.0 = 02.01.00. */ -#define LUAJIT_VERSION_SYM luaJIT_version_2_1_0_beta1 -#define LUAJIT_COPYRIGHT "Copyright (C) 2005-2015 Mike Pall" +#define LUAJIT_VERSION_SYM luaJIT_version_2_1_0_beta2 +#define LUAJIT_COPYRIGHT "Copyright (C) 2005-2016 Mike Pall" #define LUAJIT_URL "http://luajit.org/" /* Modes for luaJIT_setmode. */ diff --git a/Build/source/libs/luajit/LuaJIT-src/src/lualib.h b/Build/source/libs/luajit/LuaJIT-src/src/lualib.h index 58dd3349aa9..f2d9b486e6f 100644 --- a/Build/source/libs/luajit/LuaJIT-src/src/lualib.h +++ b/Build/source/libs/luajit/LuaJIT-src/src/lualib.h @@ -1,6 +1,6 @@ /* ** Standard library header. -** Copyright (C) 2005-2015 Mike Pall. See Copyright Notice in luajit.h +** Copyright (C) 2005-2016 Mike Pall. See Copyright Notice in luajit.h */ #ifndef _LUALIB_H diff --git a/Build/source/libs/luajit/LuaJIT-src/src/msvcbuild.bat b/Build/source/libs/luajit/LuaJIT-src/src/msvcbuild.bat index 0360d7e33b8..9c6b5320ae7 100644 --- a/Build/source/libs/luajit/LuaJIT-src/src/msvcbuild.bat +++ b/Build/source/libs/luajit/LuaJIT-src/src/msvcbuild.bat @@ -1,5 +1,5 @@ @rem Script to build LuaJIT with MSVC.
-@rem Copyright (C) 2005-2015 Mike Pall. See Copyright Notice in luajit.h
+@rem Copyright (C) 2005-2016 Mike Pall. See Copyright Notice in luajit.h
@rem
@rem Either open a "Visual Studio .NET Command Prompt"
@rem (Note that the Express Edition does not contain an x64 compiler)
diff --git a/Build/source/libs/luajit/LuaJIT-src/src/ps4build.bat b/Build/source/libs/luajit/LuaJIT-src/src/ps4build.bat index 337a44fa72d..e4a7defe7af 100644 --- a/Build/source/libs/luajit/LuaJIT-src/src/ps4build.bat +++ b/Build/source/libs/luajit/LuaJIT-src/src/ps4build.bat @@ -2,7 +2,19 @@ @rem Donated to the public domain.
@rem
@rem Open a "Visual Studio .NET Command Prompt" (64 bit host compiler)
+@rem or "VS2015 x64 Native Tools Command Prompt".
+@rem
@rem Then cd to this directory and run this script.
+@rem
+@rem Recommended invocation:
+@rem
+@rem ps4build release build, amalgamated, 64-bit GC
+@rem ps4build debug debug build, amalgamated, 64-bit GC
+@rem
+@rem Additional command-line options (not generally recommended):
+@rem
+@rem gc32 (before debug) 32-bit GC
+@rem noamalg (after debug) non-amalgamated build
@if not defined INCLUDE goto :FAIL
@if not defined SCE_ORBIS_SDK_DIR goto :FAIL
@@ -15,6 +27,14 @@ @set DASMDIR=..\dynasm
@set DASM=%DASMDIR%\dynasm.lua
@set ALL_LIB=lib_base.c lib_math.c lib_bit.c lib_string.c lib_table.c lib_io.c lib_os.c lib_package.c lib_debug.c lib_jit.c lib_ffi.c
+@set GC64=-DLUAJIT_ENABLE_GC64
+@set DASC=vm_x64.dasc
+
+@if "%1" neq "gc32" goto :NOGC32
+@shift
+@set GC64=
+@set DASC=vm_x86.dasc
+:NOGC32
%LJCOMPILE% host\minilua.c
@if errorlevel 1 goto :BAD
@@ -28,10 +48,10 @@ if exist minilua.exe.manifest^ @if not errorlevel 8 goto :FAIL
@set DASMFLAGS=-D P64 -D NO_UNWIND
-minilua %DASM% -LN %DASMFLAGS% -o host\buildvm_arch.h vm_x86.dasc
+minilua %DASM% -LN %DASMFLAGS% -o host\buildvm_arch.h %DASC%
@if errorlevel 1 goto :BAD
-%LJCOMPILE% /I "." /I %DASMDIR% -DLUAJIT_TARGET=LUAJIT_ARCH_X64 -DLUAJIT_OS=LUAJIT_OS_OTHER -DLUAJIT_DISABLE_JIT -DLUAJIT_DISABLE_FFI -DLUAJIT_NO_UNWIND host\buildvm*.c
+%LJCOMPILE% /I "." /I %DASMDIR% %GC64% -DLUAJIT_TARGET=LUAJIT_ARCH_X64 -DLUAJIT_OS=LUAJIT_OS_OTHER -DLUAJIT_DISABLE_JIT -DLUAJIT_DISABLE_FFI -DLUAJIT_NO_UNWIND host\buildvm*.c
@if errorlevel 1 goto :BAD
%LJLINK% /out:buildvm.exe buildvm*.obj
@if errorlevel 1 goto :BAD
@@ -54,7 +74,7 @@ buildvm -m folddef -o lj_folddef.h lj_opt_fold.c @if errorlevel 1 goto :BAD
@rem ---- Cross compiler ----
-@set LJCOMPILE="%SCE_ORBIS_SDK_DIR%\host_tools\bin\orbis-clang" -c -Wall -DLUAJIT_DISABLE_FFI
+@set LJCOMPILE="%SCE_ORBIS_SDK_DIR%\host_tools\bin\orbis-clang" -c -Wall -DLUAJIT_DISABLE_FFI %GC64%
@set LJLIB="%SCE_ORBIS_SDK_DIR%\host_tools\bin\orbis-ar" rcus
@set INCLUDE=""
@@ -63,14 +83,14 @@ orbis-as -o lj_vm.o lj_vm.s @if "%1" neq "debug" goto :NODEBUG
@shift
@set LJCOMPILE=%LJCOMPILE% -g -O0
-@set TARGETLIB=libluajitD.a
+@set TARGETLIB=libluajitD_ps4.a
goto :BUILD
:NODEBUG
@set LJCOMPILE=%LJCOMPILE% -O2
-@set TARGETLIB=libluajit.a
+@set TARGETLIB=libluajit_ps4.a
:BUILD
del %TARGETLIB%
-@if "%1"=="amalg" goto :AMALG
+@if "%1" neq "noamalg" goto :AMALG
for %%f in (lj_*.c lib_*.c) do (
%LJCOMPILE% %%f
@if errorlevel 1 goto :BAD
diff --git a/Build/source/libs/luajit/LuaJIT-src/src/vm_arm.dasc b/Build/source/libs/luajit/LuaJIT-src/src/vm_arm.dasc index 0bd9b147ad3..882884cdf76 100644 --- a/Build/source/libs/luajit/LuaJIT-src/src/vm_arm.dasc +++ b/Build/source/libs/luajit/LuaJIT-src/src/vm_arm.dasc @@ -1,6 +1,6 @@ |// Low-level VM code for ARM CPUs. |// Bytecode interpreter, fast functions and helper functions. -|// Copyright (C) 2005-2015 Mike Pall. See Copyright Notice in luajit.h +|// Copyright (C) 2005-2016 Mike Pall. See Copyright Notice in luajit.h | |.arch arm |.section code_op, code_sub @@ -373,6 +373,17 @@ static void build_subroutines(BuildCtx *ctx) | st_vmstate CARG2 | b ->vm_returnc | + |->vm_unwind_ext: // Complete external unwind. +#if !LJ_NO_UNWIND + | push {r0, r1, r2, lr} + | bl extern _Unwind_Complete + | ldr r0, [sp] + | bl extern _Unwind_DeleteException + | pop {r0, r1, r2, lr} + | mov r0, r1 + | bx r2 +#endif + | |//----------------------------------------------------------------------- |//-- Grow stack for calls ----------------------------------------------- |//----------------------------------------------------------------------- @@ -2086,7 +2097,7 @@ static void build_subroutines(BuildCtx *ctx) | // RA = resultptr, CARG4 = meta base | ldr RB, SAVE_MULTRES | ldr INS, [PC, #-4] - | ldr CARG3, [CARG4, #-24] // Save previous trace number. + | ldr TRACE:CARG3, [CARG4, #-24] // Save previous trace. | subs RB, RB, #8 | decode_RA8 RC, INS // Call base. | beq >2 @@ -2101,23 +2112,20 @@ static void build_subroutines(BuildCtx *ctx) | decode_RA8 RA, INS | decode_RB8 RB, INS | add RA, RA, RB - | ldr CARG1, [DISPATCH, #DISPATCH_J(trace)] |3: | cmp RA, RC | mvn CARG2, #~LJ_TNIL | bhi >9 // More results wanted? | - | ldr TRACE:RA, [CARG1, CARG3, lsl #2] - | cmp TRACE:RA, #0 - | beq ->cont_nop - | ldrh RC, TRACE:RA->link - | cmp RC, CARG3 + | ldrh RA, TRACE:CARG3->traceno + | ldrh RC, TRACE:CARG3->link + | cmp RC, RA | beq ->cont_nop // Blacklisted. | cmp RC, #0 | bne =>BC_JLOOP // Jump to stitched trace. | | // Stitch a new trace to the previous trace. - | str CARG3, [DISPATCH, #DISPATCH_J(exitno)] + | str RA, [DISPATCH, #DISPATCH_J(exitno)] | str L, [DISPATCH, #DISPATCH_J(L)] | str BASE, L->base | sub CARG1, DISPATCH, #-GG_DISP2J diff --git a/Build/source/libs/luajit/LuaJIT-src/src/vm_arm64.dasc b/Build/source/libs/luajit/LuaJIT-src/src/vm_arm64.dasc index f1251f2c48a..7a881bdd34c 100644 --- a/Build/source/libs/luajit/LuaJIT-src/src/vm_arm64.dasc +++ b/Build/source/libs/luajit/LuaJIT-src/src/vm_arm64.dasc @@ -1,6 +1,6 @@ |// Low-level VM code for ARM64 CPUs. |// Bytecode interpreter, fast functions and helper functions. -|// Copyright (C) 2005-2015 Mike Pall. See Copyright Notice in luajit.h +|// Copyright (C) 2005-2016 Mike Pall. See Copyright Notice in luajit.h | |.arch arm64 |.section code_op, code_sub diff --git a/Build/source/libs/luajit/LuaJIT-src/src/vm_mips.dasc b/Build/source/libs/luajit/LuaJIT-src/src/vm_mips.dasc index 7cfdf4b18b5..03b3084e88a 100644 --- a/Build/source/libs/luajit/LuaJIT-src/src/vm_mips.dasc +++ b/Build/source/libs/luajit/LuaJIT-src/src/vm_mips.dasc @@ -1,6 +1,9 @@ |// Low-level VM code for MIPS CPUs. |// Bytecode interpreter, fast functions and helper functions. -|// Copyright (C) 2005-2015 Mike Pall. See Copyright Notice in luajit.h +|// Copyright (C) 2005-2016 Mike Pall. See Copyright Notice in luajit.h +|// +|// MIPS soft-float support contributed by Djordje Kovacevic and +|// Stefan Pejic from RT-RK.com, sponsored by Cisco Systems, Inc. | |.arch mips |.section code_op, code_sub @@ -18,6 +21,12 @@ |// Fixed register assignments for the interpreter. |// Don't use: r0 = 0, r26/r27 = reserved, r28 = gp, r29 = sp, r31 = ra | +|.macro .FPU, a, b +|.if FPU +| a, b +|.endif +|.endmacro +| |// The following must be C callee-save (but BASE is often refetched). |.define BASE, r16 // Base of current Lua stack frame. |.define KBASE, r17 // Constants of current Lua function. @@ -25,13 +34,15 @@ |.define DISPATCH, r19 // Opcode dispatch table. |.define LREG, r20 // Register holding lua_State (also in SAVE_L). |.define MULTRES, r21 // Size of multi-result: (nresults+1)*8. -|// NYI: r22 currently unused. | |.define JGL, r30 // On-trace: global_State + 32768. | |// Constants for type-comparisons, stores and conversions. C callee-save. +|.define TISNUM, r22 |.define TISNIL, r30 +|.if FPU |.define TOBIT, f30 // 2^52 + 2^51. +|.endif | |// The following temporaries are not saved across C calls, except for RA. |.define RA, r23 // Callee-save. @@ -56,13 +67,33 @@ |.define CRET1, r2 |.define CRET2, r3 | +|.if ENDIAN_LE +|.define SFRETLO, CRET1 +|.define SFRETHI, CRET2 +|.define SFARG1LO, CARG1 +|.define SFARG1HI, CARG2 +|.define SFARG2LO, CARG3 +|.define SFARG2HI, CARG4 +|.else +|.define SFRETLO, CRET2 +|.define SFRETHI, CRET1 +|.define SFARG1LO, CARG2 +|.define SFARG1HI, CARG1 +|.define SFARG2LO, CARG4 +|.define SFARG2HI, CARG3 +|.endif +| +|.if FPU |.define FARG1, f12 |.define FARG2, f14 | |.define FRET1, f0 |.define FRET2, f2 +|.endif | |// Stack layout while in interpreter. Must match with lj_frame.h. +|.if FPU // MIPS32 hard-float. +| |.define CFRAME_SPACE, 112 // Delta for sp. | |.define SAVE_ERRF, 124(sp) // 32 bit C frame info. @@ -72,6 +103,20 @@ |//----- 8 byte aligned, ^^^^ 16 byte register save area, owned by interpreter. |.define SAVE_GPR_, 72 // .. 72+10*4: 32 bit GPR saves. |.define SAVE_FPR_, 24 // .. 24+6*8: 64 bit FPR saves. +| +|.else // MIPS32 soft-float +| +|.define CFRAME_SPACE, 64 // Delta for sp. +| +|.define SAVE_ERRF, 76(sp) // 32 bit C frame info. +|.define SAVE_NRES, 72(sp) +|.define SAVE_CFRAME, 68(sp) +|.define SAVE_L, 64(sp) +|//----- 8 byte aligned, ^^^^ 16 byte register save area, owned by interpreter. +|.define SAVE_GPR_, 24 // .. 24+10*4: 32 bit GPR saves. +| +|.endif +| |.define SAVE_PC, 20(sp) |.define ARG5, 16(sp) |.define CSAVE_4, 12(sp) @@ -83,43 +128,45 @@ |.define ARG5_OFS, 16 |.define SAVE_MULTRES, ARG5 | +|//----------------------------------------------------------------------- +| |.macro saveregs | addiu sp, sp, -CFRAME_SPACE | sw ra, SAVE_GPR_+9*4(sp) | sw r30, SAVE_GPR_+8*4(sp) -| sdc1 f30, SAVE_FPR_+5*8(sp) +| .FPU sdc1 f30, SAVE_FPR_+5*8(sp) | sw r23, SAVE_GPR_+7*4(sp) | sw r22, SAVE_GPR_+6*4(sp) -| sdc1 f28, SAVE_FPR_+4*8(sp) +| .FPU sdc1 f28, SAVE_FPR_+4*8(sp) | sw r21, SAVE_GPR_+5*4(sp) | sw r20, SAVE_GPR_+4*4(sp) -| sdc1 f26, SAVE_FPR_+3*8(sp) +| .FPU sdc1 f26, SAVE_FPR_+3*8(sp) | sw r19, SAVE_GPR_+3*4(sp) | sw r18, SAVE_GPR_+2*4(sp) -| sdc1 f24, SAVE_FPR_+2*8(sp) +| .FPU sdc1 f24, SAVE_FPR_+2*8(sp) | sw r17, SAVE_GPR_+1*4(sp) | sw r16, SAVE_GPR_+0*4(sp) -| sdc1 f22, SAVE_FPR_+1*8(sp) -| sdc1 f20, SAVE_FPR_+0*8(sp) +| .FPU sdc1 f22, SAVE_FPR_+1*8(sp) +| .FPU sdc1 f20, SAVE_FPR_+0*8(sp) |.endmacro | |.macro restoreregs_ret | lw ra, SAVE_GPR_+9*4(sp) | lw r30, SAVE_GPR_+8*4(sp) -| ldc1 f30, SAVE_FPR_+5*8(sp) +| .FPU ldc1 f30, SAVE_FPR_+5*8(sp) | lw r23, SAVE_GPR_+7*4(sp) | lw r22, SAVE_GPR_+6*4(sp) -| ldc1 f28, SAVE_FPR_+4*8(sp) +| .FPU ldc1 f28, SAVE_FPR_+4*8(sp) | lw r21, SAVE_GPR_+5*4(sp) | lw r20, SAVE_GPR_+4*4(sp) -| ldc1 f26, SAVE_FPR_+3*8(sp) +| .FPU ldc1 f26, SAVE_FPR_+3*8(sp) | lw r19, SAVE_GPR_+3*4(sp) | lw r18, SAVE_GPR_+2*4(sp) -| ldc1 f24, SAVE_FPR_+2*8(sp) +| .FPU ldc1 f24, SAVE_FPR_+2*8(sp) | lw r17, SAVE_GPR_+1*4(sp) | lw r16, SAVE_GPR_+0*4(sp) -| ldc1 f22, SAVE_FPR_+1*8(sp) -| ldc1 f20, SAVE_FPR_+0*8(sp) +| .FPU ldc1 f22, SAVE_FPR_+1*8(sp) +| .FPU ldc1 f20, SAVE_FPR_+0*8(sp) | jr ra | addiu sp, sp, CFRAME_SPACE |.endmacro @@ -153,13 +200,23 @@ |//----------------------------------------------------------------------- | |// Endian-specific defines. -|.define FRAME_PC, LJ_ENDIAN_SELECT(-4,-8) -|.define FRAME_FUNC, LJ_ENDIAN_SELECT(-8,-4) -|.define HI, LJ_ENDIAN_SELECT(4,0) -|.define LO, LJ_ENDIAN_SELECT(0,4) -|.define OFS_RD, LJ_ENDIAN_SELECT(2,0) -|.define OFS_RA, LJ_ENDIAN_SELECT(1,2) -|.define OFS_OP, LJ_ENDIAN_SELECT(0,3) +|.if ENDIAN_LE +|.define FRAME_PC, -4 +|.define FRAME_FUNC, -8 +|.define HI, 4 +|.define LO, 0 +|.define OFS_RD, 2 +|.define OFS_RA, 1 +|.define OFS_OP, 0 +|.else +|.define FRAME_PC, -8 +|.define FRAME_FUNC, -4 +|.define HI, 0 +|.define LO, 4 +|.define OFS_RD, 0 +|.define OFS_RA, 2 +|.define OFS_OP, 3 +|.endif | |// Instruction decode. |.macro decode_OP1, dst, ins; andi dst, ins, 0xff; .endmacro @@ -354,9 +411,11 @@ static void build_subroutines(BuildCtx *ctx) |. sll TMP2, TMP2, 3 |1: | addiu TMP1, TMP1, -8 - | ldc1 f0, 0(RA) + | lw SFRETHI, HI(RA) + | lw SFRETLO, LO(RA) | addiu RA, RA, 8 - | sdc1 f0, 0(BASE) + | sw SFRETHI, HI(BASE) + | sw SFRETLO, LO(BASE) | bnez TMP1, <1 |. addiu BASE, BASE, 8 | @@ -425,15 +484,16 @@ static void build_subroutines(BuildCtx *ctx) | and sp, CARG1, AT |->vm_unwind_ff_eh: // Landing pad for external unwinder. | lw L, SAVE_L - | lui TMP3, 0x59c0 // TOBIT = 2^52 + 2^51 (float). + | .FPU lui TMP3, 0x59c0 // TOBIT = 2^52 + 2^51 (float). + | li TISNUM, LJ_TISNUM // Setup type comparison constants. | li TISNIL, LJ_TNIL | lw BASE, L->base | lw DISPATCH, L->glref // Setup pointer to dispatch table. - | mtc1 TMP3, TOBIT + | .FPU mtc1 TMP3, TOBIT | li TMP1, LJ_TFALSE | li_vmstate INTERP | lw PC, FRAME_PC(BASE) // Fetch PC of previous frame. - | cvt.d.s TOBIT, TOBIT + | .FPU cvt.d.s TOBIT, TOBIT | addiu RA, BASE, -8 // Results start at BASE-8. | addiu DISPATCH, DISPATCH, GG_G2DISP | sw TMP1, HI(RA) // Prepend false to error message. @@ -496,13 +556,14 @@ static void build_subroutines(BuildCtx *ctx) | sw L, DISPATCH_GL(cur_L)(DISPATCH) | move RA, BASE | lw BASE, L->base + | li TISNUM, LJ_TISNUM // Setup type comparison constants. | lw TMP1, L->top | lw PC, FRAME_PC(BASE) - | lui TMP3, 0x59c0 // TOBIT = 2^52 + 2^51 (float). + | .FPU lui TMP3, 0x59c0 // TOBIT = 2^52 + 2^51 (float). | subu RD, TMP1, BASE - | mtc1 TMP3, TOBIT + | .FPU mtc1 TMP3, TOBIT | sb r0, L->status - | cvt.d.s TOBIT, TOBIT + | .FPU cvt.d.s TOBIT, TOBIT | li_vmstate INTERP | addiu RD, RD, 8 | st_vmstate @@ -540,13 +601,14 @@ static void build_subroutines(BuildCtx *ctx) |3: // Entry point for vm_cpcall/vm_resume (BASE = base, PC = ftype). | sw L, DISPATCH_GL(cur_L)(DISPATCH) | lw TMP2, L->base // TMP2 = old base (used in vmeta_call). - | lui TMP3, 0x59c0 // TOBIT = 2^52 + 2^51 (float). + | li TISNUM, LJ_TISNUM // Setup type comparison constants. + | .FPU lui TMP3, 0x59c0 // TOBIT = 2^52 + 2^51 (float). | lw TMP1, L->top - | mtc1 TMP3, TOBIT + | .FPU mtc1 TMP3, TOBIT | addu PC, PC, BASE | subu NARGS8:RC, TMP1, BASE | subu PC, PC, TMP2 // PC = frame delta + frame type - | cvt.d.s TOBIT, TOBIT + | .FPU cvt.d.s TOBIT, TOBIT | li_vmstate INTERP | li TISNIL, LJ_TNIL | st_vmstate @@ -628,7 +690,8 @@ static void build_subroutines(BuildCtx *ctx) |->cont_cat: // RA = resultptr, RB = meta base | lw INS, -4(PC) | addiu CARG2, RB, -16 - | ldc1 f0, 0(RA) + | lw SFRETHI, HI(RA) + | lw SFRETLO, LO(RA) | decode_RB8a MULTRES, INS | decode_RA8a RA, INS | decode_RB8b MULTRES @@ -636,11 +699,13 @@ static void build_subroutines(BuildCtx *ctx) | addu TMP1, BASE, MULTRES | sw BASE, L->base | subu CARG3, CARG2, TMP1 + | sw SFRETHI, HI(CARG2) | bne TMP1, CARG2, ->BC_CAT_Z - |. sdc1 f0, 0(CARG2) + |. sw SFRETLO, LO(CARG2) | addu RA, BASE, RA + | sw SFRETHI, HI(RA) | b ->cont_nop - |. sdc1 f0, 0(RA) + |. sw SFRETLO, LO(RA) | |//-- Table indexing metamethods ----------------------------------------- | @@ -663,10 +728,9 @@ static void build_subroutines(BuildCtx *ctx) |. sw TMP1, HI(CARG3) | |->vmeta_tgetb: // TMP0 = index - | mtc1 TMP0, f0 - | cvt.d.w f0, f0 | addiu CARG3, DISPATCH, DISPATCH_GL(tmptv) - | sdc1 f0, 0(CARG3) + | sw TMP0, LO(CARG3) + | sw TISNUM, HI(CARG3) | |->vmeta_tgetv: |1: @@ -678,9 +742,11 @@ static void build_subroutines(BuildCtx *ctx) | // Returns TValue * (finished) or NULL (metamethod). | beqz CRET1, >3 |. addiu TMP1, BASE, -FRAME_CONT - | ldc1 f0, 0(CRET1) + | lw SFARG1HI, HI(CRET1) + | lw SFARG2HI, LO(CRET1) | ins_next1 - | sdc1 f0, 0(RA) + | sw SFARG1HI, HI(RA) + | sw SFARG2HI, LO(RA) | ins_next2 | |3: // Call __index metamethod. @@ -697,10 +763,11 @@ static void build_subroutines(BuildCtx *ctx) | call_intern lj_tab_getinth // (GCtab *t, int32_t key) |. nop | // Returns cTValue * or NULL. - | beqz CRET1, >1 - |. nop + | beqz CRET1, ->BC_TGETR_Z + |. move SFARG2HI, TISNIL + | lw SFARG2HI, HI(CRET1) | b ->BC_TGETR_Z - |. ldc1 f0, 0(CRET1) + |. lw SFARG2LO, LO(CRET1) | |//----------------------------------------------------------------------- | @@ -723,10 +790,9 @@ static void build_subroutines(BuildCtx *ctx) |. sw TMP1, HI(CARG3) | |->vmeta_tsetb: // TMP0 = index - | mtc1 TMP0, f0 - | cvt.d.w f0, f0 | addiu CARG3, DISPATCH, DISPATCH_GL(tmptv) - | sdc1 f0, 0(CARG3) + | sw TMP0, LO(CARG3) + | sw TISNUM, HI(CARG3) | |->vmeta_tsetv: |1: @@ -736,11 +802,13 @@ static void build_subroutines(BuildCtx *ctx) | call_intern lj_meta_tset // (lua_State *L, TValue *o, TValue *k) |. move CARG1, L | // Returns TValue * (finished) or NULL (metamethod). + | lw SFARG1HI, HI(RA) | beqz CRET1, >3 - |. ldc1 f0, 0(RA) + |. lw SFARG1LO, LO(RA) | // NOBARRIER: lj_meta_tset ensures the table is not black. | ins_next1 - | sdc1 f0, 0(CRET1) + | sw SFARG1HI, HI(CRET1) + | sw SFARG1LO, LO(CRET1) | ins_next2 | |3: // Call __newindex metamethod. @@ -750,7 +818,8 @@ static void build_subroutines(BuildCtx *ctx) | sw PC, -16+HI(BASE) // [cont|PC] | subu PC, BASE, TMP1 | lw LFUNC:RB, FRAME_FUNC(BASE) // Guaranteed to be a function here. - | sdc1 f0, 16(BASE) // Copy value to third argument. + | sw SFARG1HI, 16+HI(BASE) // Copy value to third argument. + | sw SFARG1LO, 16+LO(BASE) | b ->vm_call_dispatch_f |. li NARGS8:RC, 24 // 3 args for func(t, k, v) | @@ -767,7 +836,9 @@ static void build_subroutines(BuildCtx *ctx) |//-- Comparison metamethods --------------------------------------------- | |->vmeta_comp: - | // CARG2, CARG3 are already set by BC_ISLT/BC_ISGE/BC_ISLE/BC_ISGT. + | // RA/RD point to o1/o2. + | move CARG2, RA + | move CARG3, RD | load_got lj_meta_comp | addiu PC, PC, -4 | sw BASE, L->base @@ -793,11 +864,13 @@ static void build_subroutines(BuildCtx *ctx) | |->cont_ra: // RA = resultptr | lbu TMP1, -4+OFS_RA(PC) - | ldc1 f0, 0(RA) + | lw SFRETHI, HI(RA) + | lw SFRETLO, LO(RA) | sll TMP1, TMP1, 3 | addu TMP1, BASE, TMP1 + | sw SFRETHI, HI(TMP1) | b ->cont_nop - |. sdc1 f0, 0(TMP1) + |. sw SFRETLO, LO(TMP1) | |->cont_condt: // RA = resultptr | lw TMP0, HI(RA) @@ -812,8 +885,11 @@ static void build_subroutines(BuildCtx *ctx) |. addiu TMP2, AT, -1 // Branch if result is false. | |->vmeta_equal: - | // CARG2, CARG3, CARG4 are already set by BC_ISEQV/BC_ISNEV. + | // SFARG1LO/SFARG2LO point to o1/o2. TMP0 is set to 0/1. | load_got lj_meta_equal + | move CARG2, SFARG1LO + | move CARG3, SFARG2LO + | move CARG4, TMP0 | addiu PC, PC, -4 | sw BASE, L->base | sw PC, SAVE_PC @@ -852,14 +928,16 @@ static void build_subroutines(BuildCtx *ctx) |//-- Arithmetic metamethods --------------------------------------------- | |->vmeta_unm: - | move CARG4, CARG3 + | move RC, RB | |->vmeta_arith: | load_got lj_meta_arith | decode_OP1 TMP0, INS | sw BASE, L->base - | sw PC, SAVE_PC | move CARG2, RA + | sw PC, SAVE_PC + | move CARG3, RB + | move CARG4, RC | sw TMP0, ARG5 | call_intern lj_meta_arith // (lua_State *L, TValue *ra,*rb,*rc, BCReg op) |. move CARG1, L @@ -967,40 +1045,52 @@ static void build_subroutines(BuildCtx *ctx) | |.macro .ffunc_1, name |->ff_ .. name: + | lw SFARG1HI, HI(BASE) | beqz NARGS8:RC, ->fff_fallback - |. lw CARG3, HI(BASE) - | lw CARG1, LO(BASE) + |. lw SFARG1LO, LO(BASE) |.endmacro | |.macro .ffunc_2, name |->ff_ .. name: | sltiu AT, NARGS8:RC, 16 - | lw CARG3, HI(BASE) + | lw SFARG1HI, HI(BASE) | bnez AT, ->fff_fallback - |. lw CARG4, 8+HI(BASE) - | lw CARG1, LO(BASE) - | lw CARG2, 8+LO(BASE) + |. lw SFARG2HI, 8+HI(BASE) + | lw SFARG1LO, LO(BASE) + | lw SFARG2LO, 8+LO(BASE) |.endmacro | |.macro .ffunc_n, name // Caveat: has delay slot! |->ff_ .. name: - | lw CARG3, HI(BASE) + | lw SFARG1HI, HI(BASE) + |.if FPU + | ldc1 FARG1, 0(BASE) + |.else + | lw SFARG1LO, LO(BASE) + |.endif | beqz NARGS8:RC, ->fff_fallback - |. ldc1 FARG1, 0(BASE) - | sltiu AT, CARG3, LJ_TISNUM + |. sltiu AT, SFARG1HI, LJ_TISNUM | beqz AT, ->fff_fallback |.endmacro | |.macro .ffunc_nn, name // Caveat: has delay slot! |->ff_ .. name: | sltiu AT, NARGS8:RC, 16 - | lw CARG3, HI(BASE) + | lw SFARG1HI, HI(BASE) | bnez AT, ->fff_fallback - |. lw CARG4, 8+HI(BASE) - | ldc1 FARG1, 0(BASE) - | ldc1 FARG2, 8(BASE) - | sltiu TMP0, CARG3, LJ_TISNUM - | sltiu TMP1, CARG4, LJ_TISNUM + |. lw SFARG2HI, 8+HI(BASE) + | sltiu TMP0, SFARG1HI, LJ_TISNUM + |.if FPU + | ldc1 FARG1, 0(BASE) + |.else + | lw SFARG1LO, LO(BASE) + |.endif + | sltiu TMP1, SFARG2HI, LJ_TISNUM + |.if FPU + | ldc1 FARG2, 8(BASE) + |.else + | lw SFARG2LO, 8+LO(BASE) + |.endif | and TMP0, TMP0, TMP1 | beqz TMP0, ->fff_fallback |.endmacro @@ -1016,52 +1106,54 @@ static void build_subroutines(BuildCtx *ctx) |//-- Base library: checks ----------------------------------------------- | |.ffunc_1 assert - | sltiu AT, CARG3, LJ_TISTRUECOND + | sltiu AT, SFARG1HI, LJ_TISTRUECOND | beqz AT, ->fff_fallback |. addiu RA, BASE, -8 | lw PC, FRAME_PC(BASE) | addiu RD, NARGS8:RC, 8 // Compute (nresults+1)*8. | addu TMP2, RA, NARGS8:RC - | sw CARG3, HI(RA) + | sw SFARG1HI, HI(RA) | addiu TMP1, BASE, 8 | beq BASE, TMP2, ->fff_res // Done if exactly 1 argument. - |. sw CARG1, LO(RA) + |. sw SFARG1LO, LO(RA) |1: - | ldc1 f0, 0(TMP1) - | sdc1 f0, -8(TMP1) + | lw SFRETHI, HI(TMP1) + | lw SFRETLO, LO(TMP1) + | sw SFRETHI, -8+HI(TMP1) + | sw SFRETLO, -8+LO(TMP1) | bne TMP1, TMP2, <1 |. addiu TMP1, TMP1, 8 | b ->fff_res |. nop | |.ffunc type - | lw CARG3, HI(BASE) - | li TMP1, LJ_TISNUM + | lw SFARG1HI, HI(BASE) | beqz NARGS8:RC, ->fff_fallback - |. sltiu TMP0, CARG3, LJ_TISNUM - | movz TMP1, CARG3, TMP0 - | not TMP1, TMP1 + |. sltiu TMP0, SFARG1HI, LJ_TISNUM + | movn SFARG1HI, TISNUM, TMP0 + | not TMP1, SFARG1HI | sll TMP1, TMP1, 3 | addu TMP1, CFUNC:RB, TMP1 - | b ->fff_resn - |. ldc1 FRET1, CFUNC:TMP1->upvalue + | lw SFARG1HI, CFUNC:TMP1->upvalue[0].u32.hi + | b ->fff_restv + |. lw SFARG1LO, CFUNC:TMP1->upvalue[0].u32.lo | |//-- Base library: getters and setters --------------------------------- | |.ffunc_1 getmetatable | li AT, LJ_TTAB - | bne CARG3, AT, >6 + | bne SFARG1HI, AT, >6 |. li AT, LJ_TUDATA |1: // Field metatable must be at same offset for GCtab and GCudata! - | lw TAB:CARG1, TAB:CARG1->metatable + | lw TAB:SFARG1LO, TAB:SFARG1LO->metatable |2: | lw STR:RC, DISPATCH_GL(gcroot[GCROOT_MMNAME+MM_metatable])(DISPATCH) - | beqz TAB:CARG1, ->fff_restv - |. li CARG3, LJ_TNIL - | lw TMP0, TAB:CARG1->hmask - | li CARG3, LJ_TTAB // Use metatable as default result. + | beqz TAB:SFARG1LO, ->fff_restv + |. li SFARG1HI, LJ_TNIL + | lw TMP0, TAB:SFARG1LO->hmask + | li SFARG1HI, LJ_TTAB // Use metatable as default result. | lw TMP1, STR:RC->hash - | lw NODE:TMP2, TAB:CARG1->node + | lw NODE:TMP2, TAB:SFARG1LO->node | and TMP1, TMP1, TMP0 // idx = str->hash & tab->hmask | sll TMP0, TMP1, 5 | sll TMP1, TMP1, 3 @@ -1073,7 +1165,7 @@ static void build_subroutines(BuildCtx *ctx) | lw TMP0, offsetof(Node, key)+LO(NODE:TMP2) | lw NODE:TMP3, NODE:TMP2->next | bne CARG4, AT, >4 - |. lw CARG2, offsetof(Node, val)+HI(NODE:TMP2) + |. lw CARG3, offsetof(Node, val)+HI(NODE:TMP2) | beq TMP0, STR:RC, >5 |. lw TMP1, offsetof(Node, val)+LO(NODE:TMP2) |4: @@ -1082,36 +1174,35 @@ static void build_subroutines(BuildCtx *ctx) | b <3 |. nop |5: - | beq CARG2, TISNIL, ->fff_restv // Ditto for nil value. + | beq CARG3, TISNIL, ->fff_restv // Ditto for nil value. |. nop - | move CARG3, CARG2 // Return value of mt.__metatable. + | move SFARG1HI, CARG3 // Return value of mt.__metatable. | b ->fff_restv - |. move CARG1, TMP1 + |. move SFARG1LO, TMP1 | |6: - | beq CARG3, AT, <1 - |. sltiu TMP0, CARG3, LJ_TISNUM - | li TMP1, LJ_TISNUM - | movz TMP1, CARG3, TMP0 - | not TMP1, TMP1 + | beq SFARG1HI, AT, <1 + |. sltu AT, TISNUM, SFARG1HI + | movz SFARG1HI, TISNUM, AT + | not TMP1, SFARG1HI | sll TMP1, TMP1, 2 | addu TMP1, DISPATCH, TMP1 | b <2 - |. lw TAB:CARG1, DISPATCH_GL(gcroot[GCROOT_BASEMT])(TMP1) + |. lw TAB:SFARG1LO, DISPATCH_GL(gcroot[GCROOT_BASEMT])(TMP1) | |.ffunc_2 setmetatable | // Fast path: no mt for table yet and not clearing the mt. | li AT, LJ_TTAB - | bne CARG3, AT, ->fff_fallback - |. addiu CARG4, CARG4, -LJ_TTAB - | lw TAB:TMP1, TAB:CARG1->metatable - | lbu TMP3, TAB:CARG1->marked - | or AT, CARG4, TAB:TMP1 + | bne SFARG1HI, AT, ->fff_fallback + |. addiu SFARG2HI, SFARG2HI, -LJ_TTAB + | lw TAB:TMP1, TAB:SFARG1LO->metatable + | lbu TMP3, TAB:SFARG1LO->marked + | or AT, SFARG2HI, TAB:TMP1 | bnez AT, ->fff_fallback |. andi AT, TMP3, LJ_GC_BLACK // isblack(table) | beqz AT, ->fff_restv - |. sw TAB:CARG2, TAB:CARG1->metatable - | barrierback TAB:CARG1, TMP3, TMP0, ->fff_restv + |. sw TAB:SFARG2LO, TAB:SFARG1LO->metatable + | barrierback TAB:SFARG1LO, TMP3, TMP0, ->fff_restv | |.ffunc rawget | lw CARG4, HI(BASE) @@ -1125,44 +1216,44 @@ static void build_subroutines(BuildCtx *ctx) | call_intern lj_tab_get // (lua_State *L, GCtab *t, cTValue *key) |. move CARG1, L | // Returns cTValue *. - | b ->fff_resn - |. ldc1 FRET1, 0(CRET1) + | lw SFARG1HI, HI(CRET1) + | b ->fff_restv + |. lw SFARG1LO, LO(CRET1) | |//-- Base library: conversions ------------------------------------------ | |.ffunc tonumber | // Only handles the number case inline (without a base argument). | lw CARG1, HI(BASE) - | xori AT, NARGS8:RC, 8 - | sltiu CARG1, CARG1, LJ_TISNUM - | movn CARG1, r0, AT - | beqz CARG1, ->fff_fallback // Exactly one number argument. - |. ldc1 FRET1, 0(BASE) - | b ->fff_resn - |. nop + | xori AT, NARGS8:RC, 8 // Exactly one number argument. + | sltu TMP0, TISNUM, CARG1 + | or AT, AT, TMP0 + | bnez AT, ->fff_fallback + |. lw SFARG1HI, HI(BASE) + | b ->fff_restv + |. lw SFARG1LO, LO(BASE) | |.ffunc_1 tostring | // Only handles the string or number case inline. | li AT, LJ_TSTR | // A __tostring method in the string base metatable is ignored. - | beq CARG3, AT, ->fff_restv // String key? + | beq SFARG1HI, AT, ->fff_restv // String key? | // Handle numbers inline, unless a number base metatable is present. |. lw TMP1, DISPATCH_GL(gcroot[GCROOT_BASEMT_NUM])(DISPATCH) - | sltiu TMP0, CARG3, LJ_TISNUM - | sltiu TMP1, TMP1, 1 - | and TMP0, TMP0, TMP1 - | beqz TMP0, ->fff_fallback + | sltu TMP0, TISNUM, SFARG1HI + | or TMP0, TMP0, TMP1 + | bnez TMP0, ->fff_fallback |. sw BASE, L->base // Add frame since C call can throw. | ffgccheck |. sw PC, SAVE_PC // Redundant (but a defined value). - | load_got lj_strfmt_num + | load_got lj_strfmt_number | move CARG1, L - | call_intern lj_strfmt_num // (lua_State *L, lua_Number *np) + | call_intern lj_strfmt_number // (lua_State *L, cTValue *o) |. move CARG2, BASE | // Returns GCstr *. - | li CARG3, LJ_TSTR + | li SFARG1HI, LJ_TSTR | b ->fff_restv - |. move CARG1, CRET1 + |. move SFARG1LO, CRET1 | |//-- Base library: iterators ------------------------------------------- | @@ -1184,31 +1275,38 @@ static void build_subroutines(BuildCtx *ctx) |. move CARG1, L | // Returns 0 at end of traversal. | beqz CRET1, ->fff_restv // End of traversal: return nil. - |. li CARG3, LJ_TNIL - | ldc1 f0, 8(BASE) // Copy key and value to results. + |. li SFARG1HI, LJ_TNIL + | lw TMP0, 8+HI(BASE) + | lw TMP1, 8+LO(BASE) | addiu RA, BASE, -8 - | ldc1 f2, 16(BASE) - | li RD, (2+1)*8 - | sdc1 f0, 0(RA) + | lw TMP2, 16+HI(BASE) + | lw TMP3, 16+LO(BASE) + | sw TMP0, HI(RA) + | sw TMP1, LO(RA) + | sw TMP2, 8+HI(RA) + | sw TMP3, 8+LO(RA) | b ->fff_res - |. sdc1 f2, 8(RA) + |. li RD, (2+1)*8 | |.ffunc_1 pairs | li AT, LJ_TTAB - | bne CARG3, AT, ->fff_fallback + | bne SFARG1HI, AT, ->fff_fallback |. lw PC, FRAME_PC(BASE) #if LJ_52 - | lw TAB:TMP2, TAB:CARG1->metatable - | ldc1 f0, CFUNC:RB->upvalue[0] + | lw TAB:TMP2, TAB:SFARG1LO->metatable + | lw TMP0, CFUNC:RB->upvalue[0].u32.hi + | lw TMP1, CFUNC:RB->upvalue[0].u32.lo | bnez TAB:TMP2, ->fff_fallback #else - | ldc1 f0, CFUNC:RB->upvalue[0] + | lw TMP0, CFUNC:RB->upvalue[0].u32.hi + | lw TMP1, CFUNC:RB->upvalue[0].u32.lo #endif |. addiu RA, BASE, -8 | sw TISNIL, 8+HI(BASE) - | li RD, (3+1)*8 + | sw TMP0, HI(RA) + | sw TMP1, LO(RA) | b ->fff_res - |. sdc1 f0, 0(RA) + |. li RD, (3+1)*8 | |.ffunc ipairs_aux | sltiu AT, NARGS8:RC, 16 @@ -1216,35 +1314,32 @@ static void build_subroutines(BuildCtx *ctx) | lw TAB:CARG1, LO(BASE) | lw CARG4, 8+HI(BASE) | bnez AT, ->fff_fallback - |. ldc1 FARG2, 8(BASE) - | addiu CARG3, CARG3, -LJ_TTAB - | sltiu AT, CARG4, LJ_TISNUM - | li TMP0, 1 - | movn AT, r0, CARG3 - | mtc1 TMP0, FARG1 - | beqz AT, ->fff_fallback + |. addiu CARG3, CARG3, -LJ_TTAB + | xor CARG4, CARG4, TISNUM + | and AT, CARG3, CARG4 + | bnez AT, ->fff_fallback |. lw PC, FRAME_PC(BASE) - | trunc.w.d FRET1, FARG2 - | cvt.d.w FARG1, FARG1 + | lw TMP2, 8+LO(BASE) | lw TMP0, TAB:CARG1->asize | lw TMP1, TAB:CARG1->array - | mfc1 TMP2, FRET1 - | addiu RA, BASE, -8 - | add.d FARG2, FARG2, FARG1 | addiu TMP2, TMP2, 1 + | sw TISNUM, -8+HI(BASE) | sltu AT, TMP2, TMP0 + | sw TMP2, -8+LO(BASE) + | beqz AT, >2 // Not in array part? + |. addiu RA, BASE, -8 | sll TMP3, TMP2, 3 | addu TMP3, TMP1, TMP3 - | beqz AT, >2 // Not in array part? - |. sdc1 FARG2, 0(RA) - | lw TMP2, HI(TMP3) - | ldc1 f0, 0(TMP3) + | lw TMP1, HI(TMP3) + | lw TMP2, LO(TMP3) |1: - | beq TMP2, TISNIL, ->fff_res // End of iteration, return 0 results. + | beq TMP1, TISNIL, ->fff_res // End of iteration, return 0 results. |. li RD, (0+1)*8 - | li RD, (2+1)*8 + | sw TMP1, 8+HI(RA) + | sw TMP2, 8+LO(RA) | b ->fff_res - |. sdc1 f0, 8(RA) + |. li RD, (2+1)*8 + | |2: // Check for empty hash part first. Otherwise call C function. | lw TMP0, TAB:CARG1->hmask | load_got lj_tab_getinth @@ -1255,27 +1350,30 @@ static void build_subroutines(BuildCtx *ctx) | // Returns cTValue * or NULL. | beqz CRET1, ->fff_res |. li RD, (0+1)*8 - | lw TMP2, HI(CRET1) + | lw TMP1, HI(CRET1) | b <1 - |. ldc1 f0, 0(CRET1) + |. lw TMP2, LO(CRET1) | |.ffunc_1 ipairs | li AT, LJ_TTAB - | bne CARG3, AT, ->fff_fallback + | bne SFARG1HI, AT, ->fff_fallback |. lw PC, FRAME_PC(BASE) #if LJ_52 - | lw TAB:TMP2, TAB:CARG1->metatable - | ldc1 f0, CFUNC:RB->upvalue[0] + | lw TAB:TMP2, TAB:SFARG1LO->metatable + | lw TMP0, CFUNC:RB->upvalue[0].u32.hi + | lw TMP1, CFUNC:RB->upvalue[0].u32.lo | bnez TAB:TMP2, ->fff_fallback #else - | ldc1 f0, CFUNC:RB->upvalue[0] + | lw TMP0, CFUNC:RB->upvalue[0].u32.hi + | lw TMP1, CFUNC:RB->upvalue[0].u32.lo #endif |. addiu RA, BASE, -8 - | sw r0, 8+HI(BASE) + | sw TISNUM, 8+HI(BASE) | sw r0, 8+LO(BASE) - | li RD, (3+1)*8 + | sw TMP0, HI(RA) + | sw TMP1, LO(RA) | b ->fff_res - |. sdc1 f0, 0(RA) + |. li RD, (3+1)*8 | |//-- Base library: catch errors ---------------------------------------- | @@ -1295,8 +1393,9 @@ static void build_subroutines(BuildCtx *ctx) | sltiu AT, NARGS8:RC, 16 | lw CARG4, 8+HI(BASE) | bnez AT, ->fff_fallback - |. ldc1 FARG2, 8(BASE) - | ldc1 FARG1, 0(BASE) + |. lw CARG3, 8+LO(BASE) + | lw CARG1, LO(BASE) + | lw CARG2, HI(BASE) | lbu TMP1, DISPATCH_GL(hookmask)(DISPATCH) | li AT, LJ_TFUNC | move TMP2, BASE @@ -1304,9 +1403,11 @@ static void build_subroutines(BuildCtx *ctx) | addiu BASE, BASE, 16 | // Remember active hook before pcall. | srl TMP3, TMP3, HOOK_ACTIVE_SHIFT - | sdc1 FARG2, 0(TMP2) // Swap function and traceback. + | sw CARG3, LO(TMP2) // Swap function and traceback. + | sw CARG4, HI(TMP2) | andi TMP3, TMP3, 1 - | sdc1 FARG1, 8(TMP2) + | sw CARG1, 8+LO(TMP2) + | sw CARG2, 8+HI(TMP2) | addiu PC, TMP3, 16+FRAME_PCALL | b ->vm_call_dispatch |. addiu NARGS8:RC, NARGS8:RC, -16 @@ -1315,7 +1416,10 @@ static void build_subroutines(BuildCtx *ctx) | |.macro coroutine_resume_wrap, resume |.if resume - |.ffunc_1 coroutine_resume + |.ffunc coroutine_resume + | lw CARG3, HI(BASE) + | beqz NARGS8:RC, ->fff_fallback + |. lw CARG1, LO(BASE) | li AT, LJ_TTHREAD | bne CARG3, AT, ->fff_fallback |.else @@ -1350,11 +1454,13 @@ static void build_subroutines(BuildCtx *ctx) | move CARG3, CARG2 | sw BASE, L->top |2: // Move args to coroutine. - | ldc1 f0, 0(BASE) + | lw SFRETHI, HI(BASE) + | lw SFRETLO, LO(BASE) | sltu AT, BASE, TMP1 | beqz AT, >3 |. addiu BASE, BASE, 8 - | sdc1 f0, 0(CARG3) + | sw SFRETHI, HI(CARG3) + | sw SFRETLO, LO(CARG3) | b <2 |. addiu CARG3, CARG3, 8 |3: @@ -1380,10 +1486,12 @@ static void build_subroutines(BuildCtx *ctx) | sw TMP2, L:RA->top // Clear coroutine stack. | move TMP1, BASE |5: // Move results from coroutine. - | ldc1 f0, 0(TMP2) + | lw SFRETHI, HI(TMP2) + | lw SFRETLO, LO(TMP2) | addiu TMP2, TMP2, 8 | sltu AT, TMP2, TMP3 - | sdc1 f0, 0(TMP1) + | sw SFRETHI, HI(TMP1) + | sw SFRETLO, LO(TMP1) | bnez AT, <5 |. addiu TMP1, TMP1, 8 |6: @@ -1408,12 +1516,14 @@ static void build_subroutines(BuildCtx *ctx) |.if resume | addiu TMP3, TMP3, -8 | li TMP1, LJ_TFALSE - | ldc1 f0, 0(TMP3) + | lw SFRETHI, HI(TMP3) + | lw SFRETLO, LO(TMP3) | sw TMP3, L:RA->top // Remove error from coroutine stack. | li RD, (2+1)*8 | sw TMP1, -8+HI(BASE) // Prepend false to results. | addiu RA, BASE, -8 - | sdc1 f0, 0(BASE) // Copy error message. + | sw SFRETHI, HI(BASE) // Copy error message. + | sw SFRETLO, LO(BASE) | b <7 |. andi TMP0, PC, FRAME_TYPE |.else @@ -1449,20 +1559,29 @@ static void build_subroutines(BuildCtx *ctx) | |//-- Math library ------------------------------------------------------- | - |.ffunc_n math_abs - |. abs.d FRET1, FARG1 - |->fff_resn: - | lw PC, FRAME_PC(BASE) - | addiu RA, BASE, -8 - | b ->fff_res1 - |. sdc1 FRET1, -8(BASE) + |.ffunc_1 math_abs + | bne SFARG1HI, TISNUM, >1 + |. sra TMP0, SFARG1LO, 31 + | xor TMP1, SFARG1LO, TMP0 + | subu SFARG1LO, TMP1, TMP0 + | bgez SFARG1LO, ->fff_restv + |. nop + | lui SFARG1HI, 0x41e0 // 2^31 as a double. + | b ->fff_restv + |. li SFARG1LO, 0 + |1: + | sltiu AT, SFARG1HI, LJ_TISNUM + | beqz AT, ->fff_fallback + |. sll SFARG1HI, SFARG1HI, 1 + | srl SFARG1HI, SFARG1HI, 1 + |// fallthrough | |->fff_restv: - | // CARG3/CARG1 = TValue result. + | // SFARG1LO/SFARG1HI = TValue result. | lw PC, FRAME_PC(BASE) - | sw CARG3, -8+HI(BASE) + | sw SFARG1HI, -8+HI(BASE) | addiu RA, BASE, -8 - | sw CARG1, -8+LO(BASE) + | sw SFARG1LO, -8+LO(BASE) |->fff_res1: | // RA = results, PC = return. | li RD, (1+1)*8 @@ -1491,15 +1610,19 @@ static void build_subroutines(BuildCtx *ctx) |. sw TISNIL, -8+HI(TMP1) | |.macro math_extern, func - |->ff_math_ .. func: - | lw CARG3, HI(BASE) + | .ffunc math_ .. func + | lw SFARG1HI, HI(BASE) | beqz NARGS8:RC, ->fff_fallback |. load_got func - | sltiu AT, CARG3, LJ_TISNUM + | sltiu AT, SFARG1HI, LJ_TISNUM | beqz AT, ->fff_fallback - |. nop - | call_extern + |.if FPU |. ldc1 FARG1, 0(BASE) + |.else + |. lw SFARG1LO, LO(BASE) + |.endif + | call_extern + |. nop | b ->fff_resn |. nop |.endmacro @@ -1513,10 +1636,22 @@ static void build_subroutines(BuildCtx *ctx) |. nop |.endmacro | + |// TODO: Return integer type if result is integer (own sf implementation). |.macro math_round, func - | .ffunc_n math_ .. func - |. nop + |->ff_math_ .. func: + | lw SFARG1HI, HI(BASE) + | beqz NARGS8:RC, ->fff_fallback + |. lw SFARG1LO, LO(BASE) + | beq SFARG1HI, TISNUM, ->fff_restv + |. sltu AT, SFARG1HI, TISNUM + | beqz AT, ->fff_fallback + |.if FPU + |. ldc1 FARG1, 0(BASE) | bal ->vm_ .. func + |.else + |. load_got func + | call_extern + |.endif |. nop | b ->fff_resn |. nop @@ -1526,15 +1661,19 @@ static void build_subroutines(BuildCtx *ctx) | math_round ceil | |.ffunc math_log - | lw CARG3, HI(BASE) | li AT, 8 | bne NARGS8:RC, AT, ->fff_fallback // Exactly 1 argument. - |. load_got log - | sltiu AT, CARG3, LJ_TISNUM + |. lw SFARG1HI, HI(BASE) + | sltiu AT, SFARG1HI, LJ_TISNUM | beqz AT, ->fff_fallback - |. nop + |. load_got log + |.if FPU | call_extern |. ldc1 FARG1, 0(BASE) + |.else + | call_extern + |. lw SFARG1LO, LO(BASE) + |.endif | b ->fff_resn |. nop | @@ -1553,17 +1692,43 @@ static void build_subroutines(BuildCtx *ctx) | math_extern2 atan2 | math_extern2 fmod | + |.if FPU |.ffunc_n math_sqrt |. sqrt.d FRET1, FARG1 - | b ->fff_resn - |. nop + |// fallthrough to ->fff_resn + |.else + | math_extern sqrt + |.endif + | + |->fff_resn: + | lw PC, FRAME_PC(BASE) + | addiu RA, BASE, -8 + |.if FPU + | b ->fff_res1 + |. sdc1 FRET1, -8(BASE) + |.else + | sw SFRETHI, -8+HI(BASE) + | b ->fff_res1 + |. sw SFRETLO, -8+LO(BASE) + |.endif | - |.ffunc_nn math_ldexp - | trunc.w.d FARG2, FARG2 + | + |.ffunc math_ldexp + | sltiu AT, NARGS8:RC, 16 + | lw SFARG1HI, HI(BASE) + | bnez AT, ->fff_fallback + |. lw CARG4, 8+HI(BASE) + | bne CARG4, TISNUM, ->fff_fallback | load_got ldexp - | mfc1 CARG3, FARG2 + |. sltu AT, SFARG1HI, TISNUM + | beqz AT, ->fff_fallback + |.if FPU + |. ldc1 FARG1, 0(BASE) + |.else + |. lw SFARG1LO, LO(BASE) + |.endif | call_extern - |. nop + |. lw CARG3, 8+LO(BASE) | b ->fff_resn |. nop | @@ -1574,10 +1739,17 @@ static void build_subroutines(BuildCtx *ctx) |. addiu CARG3, DISPATCH, DISPATCH_GL(tmptv) | lw TMP1, DISPATCH_GL(tmptv)(DISPATCH) | addiu RA, BASE, -8 + |.if FPU | mtc1 TMP1, FARG2 | sdc1 FRET1, 0(RA) | cvt.d.w FARG2, FARG2 | sdc1 FARG2, 8(RA) + |.else + | sw SFRETLO, LO(RA) + | sw SFRETHI, HI(RA) + | sw TMP1, 8+LO(RA) + | sw TISNUM, 8+HI(RA) + |.endif | b ->fff_res |. li RD, (2+1)*8 | @@ -1587,39 +1759,98 @@ static void build_subroutines(BuildCtx *ctx) | call_extern |. addiu CARG3, BASE, -8 | addiu RA, BASE, -8 + |.if FPU | sdc1 FRET1, 0(BASE) + |.else + | sw SFRETLO, LO(BASE) + | sw SFRETHI, HI(BASE) + |.endif | b ->fff_res |. li RD, (2+1)*8 | - |.macro math_minmax, name, ismax - |->ff_ .. name: - | lw CARG3, HI(BASE) - | beqz NARGS8:RC, ->fff_fallback - |. ldc1 FRET1, 0(BASE) - | sltiu AT, CARG3, LJ_TISNUM + |.macro math_minmax, name, intins, fpins + | .ffunc_1 name + | addu TMP3, BASE, NARGS8:RC + | bne SFARG1HI, TISNUM, >5 + |. addiu TMP2, BASE, 8 + |1: // Handle integers. + |. lw SFARG2HI, HI(TMP2) + | beq TMP2, TMP3, ->fff_restv + |. lw SFARG2LO, LO(TMP2) + | bne SFARG2HI, TISNUM, >3 + |. slt AT, SFARG1LO, SFARG2LO + | intins SFARG1LO, SFARG2LO, AT + | b <1 + |. addiu TMP2, TMP2, 8 + | + |3: // Convert intermediate result to number and continue with number loop. + | sltiu AT, SFARG2HI, LJ_TISNUM | beqz AT, ->fff_fallback - |. addu TMP2, BASE, NARGS8:RC - | addiu TMP1, BASE, 8 - | beq TMP1, TMP2, ->fff_resn - |1: - |. lw CARG3, HI(TMP1) - | ldc1 FARG1, 0(TMP1) - | addiu TMP1, TMP1, 8 - | sltiu AT, CARG3, LJ_TISNUM + |.if FPU + |. mtc1 SFARG1LO, FRET1 + | cvt.d.w FRET1, FRET1 + | b >7 + |. ldc1 FARG1, 0(TMP2) + |.else + |. nop + | bal ->vm_sfi2d_1 + |. nop + | b >7 + |. nop + |.endif + | + |5: + |. sltiu AT, SFARG1HI, LJ_TISNUM | beqz AT, ->fff_fallback - |.if ismax - |. c.olt.d FARG1, FRET1 + |.if FPU + |. ldc1 FRET1, 0(BASE) + |.endif + | + |6: // Handle numbers. + |. lw SFARG2HI, HI(TMP2) + |.if FPU + | beq TMP2, TMP3, ->fff_resn |.else - |. c.olt.d FRET1, FARG1 + | beq TMP2, TMP3, ->fff_restv |.endif - | bne TMP1, TMP2, <1 - |. movf.d FRET1, FARG1 - | b ->fff_resn + |. sltiu AT, SFARG2HI, LJ_TISNUM + | beqz AT, >8 + |.if FPU + |. ldc1 FARG1, 0(TMP2) + |.else + |. lw SFARG2LO, LO(TMP2) + |.endif + |7: + |.if FPU + | c.olt.d FRET1, FARG1 + | fpins FRET1, FARG1 + |.else + | bal ->vm_sfcmpolt |. nop + | intins SFARG1LO, SFARG2LO, CRET1 + | intins SFARG1HI, SFARG2HI, CRET1 + |.endif + | b <6 + |. addiu TMP2, TMP2, 8 + | + |8: // Convert integer to number and continue with number loop. + | bne SFARG2HI, TISNUM, ->fff_fallback + |.if FPU + |. lwc1 FARG1, LO(TMP2) + | b <7 + |. cvt.d.w FARG1, FARG1 + |.else + |. nop + | bal ->vm_sfi2d_2 + |. nop + | b <7 + |. nop + |.endif + | |.endmacro | - | math_minmax math_min, 0 - | math_minmax math_max, 1 + | math_minmax math_min, movz, movf.d + | math_minmax math_max, movn, movt.d | |//-- String library ----------------------------------------------------- | @@ -1632,32 +1863,30 @@ static void build_subroutines(BuildCtx *ctx) | bnez AT, ->fff_fallback // Need exactly 1 string argument. |. nop | lw TMP0, STR:CARG1->len - | lbu TMP1, STR:CARG1[1] // Access is always ok (NUL at end). | addiu RA, BASE, -8 + | lw PC, FRAME_PC(BASE) | sltu RD, r0, TMP0 - | mtc1 TMP1, f0 + | lbu TMP1, STR:CARG1[1] // Access is always ok (NUL at end). | addiu RD, RD, 1 - | cvt.d.w f0, f0 - | lw PC, FRAME_PC(BASE) | sll RD, RD, 3 // RD = ((str->len != 0)+1)*8 + | sw TISNUM, HI(RA) | b ->fff_res - |. sdc1 f0, 0(RA) + |. sw TMP1, LO(RA) | |.ffunc string_char // Only handle the 1-arg case here. | ffgccheck - | lw CARG3, HI(BASE) - | ldc1 FARG1, 0(BASE) - | li AT, 8 - | bne NARGS8:RC, AT, ->fff_fallback // Exactly 1 argument. - |. sltiu AT, CARG3, LJ_TISNUM - | beqz AT, ->fff_fallback + |. lw CARG3, HI(BASE) + | lw CARG1, LO(BASE) + | li TMP1, 255 + | xori AT, NARGS8:RC, 8 // Exactly 1 argument. + | xor TMP0, CARG3, TISNUM // Integer. + | sltu TMP1, TMP1, CARG1 // !(255 < n). + | or AT, AT, TMP0 + | or AT, AT, TMP1 + | bnez AT, ->fff_fallback |. li CARG3, 1 - | trunc.w.d FARG1, FARG1 | addiu CARG2, sp, ARG5_OFS - | sltiu AT, TMP0, 256 - | mfc1 TMP0, FARG1 - | beqz AT, ->fff_fallback - |. sw TMP0, ARG5 + | sb CARG1, ARG5 |->fff_newstr: | load_got lj_str_new | sw BASE, L->base @@ -1667,34 +1896,28 @@ static void build_subroutines(BuildCtx *ctx) | // Returns GCstr *. | lw BASE, L->base |->fff_resstr: - | move CARG1, CRET1 + | move SFARG1LO, CRET1 | b ->fff_restv - |. li CARG3, LJ_TSTR + |. li SFARG1HI, LJ_TSTR | |.ffunc string_sub | ffgccheck - | addiu AT, NARGS8:RC, -16 + |. addiu AT, NARGS8:RC, -16 | lw CARG3, 16+HI(BASE) - | ldc1 f0, 16(BASE) | lw TMP0, HI(BASE) | lw STR:CARG1, LO(BASE) | bltz AT, ->fff_fallback - | lw CARG2, 8+HI(BASE) - | ldc1 f2, 8(BASE) + |. lw CARG2, 8+HI(BASE) | beqz AT, >1 |. li CARG4, -1 - | trunc.w.d f0, f0 - | sltiu AT, CARG3, LJ_TISNUM - | beqz AT, ->fff_fallback - |. mfc1 CARG4, f0 + | bne CARG3, TISNUM, ->fff_fallback + |. lw CARG4, 16+LO(BASE) |1: - | sltiu AT, CARG2, LJ_TISNUM - | beqz AT, ->fff_fallback + | bne CARG2, TISNUM, ->fff_fallback |. li AT, LJ_TSTR - | trunc.w.d f2, f2 | bne TMP0, AT, ->fff_fallback - |. lw CARG2, STR:CARG1->len - | mfc1 CARG3, f2 + |. lw CARG3, 8+LO(BASE) + | lw CARG2, STR:CARG1->len | // STR:CARG1 = str, CARG2 = str->len, CARG3 = start, CARG4 = end | slt AT, CARG4, r0 | addiu TMP0, CARG2, 1 @@ -1716,14 +1939,14 @@ static void build_subroutines(BuildCtx *ctx) | bgez CARG3, ->fff_newstr |. addiu CARG3, CARG3, 1 // len++ |->fff_emptystr: // Return empty string. - | addiu STR:CARG1, DISPATCH, DISPATCH_GL(strempty) + | addiu STR:SFARG1LO, DISPATCH, DISPATCH_GL(strempty) | b ->fff_restv - |. li CARG3, LJ_TSTR + |. li SFARG1HI, LJ_TSTR | |.macro ffstring_op, name | .ffunc string_ .. name | ffgccheck - | lw CARG3, HI(BASE) + |. lw CARG3, HI(BASE) | lw STR:CARG2, LO(BASE) | beqz NARGS8:RC, ->fff_fallback |. li AT, LJ_TSTR @@ -1749,27 +1972,96 @@ static void build_subroutines(BuildCtx *ctx) | |//-- Bit library -------------------------------------------------------- | + |->vm_tobit_fb: + | beqz TMP1, ->fff_fallback + |.if FPU + |. ldc1 FARG1, 0(BASE) + | add.d FARG1, FARG1, TOBIT + | jr ra + |. mfc1 CRET1, FARG1 + |.else + |// FP number to bit conversion for soft-float. + |->vm_tobit: + | sll TMP0, SFARG1HI, 1 + | lui AT, 0x0020 + | addu TMP0, TMP0, AT + | slt AT, TMP0, r0 + | movz SFARG1LO, r0, AT + | beqz AT, >2 + |. li TMP1, 0x3e0 + | not TMP1, TMP1 + | sra TMP0, TMP0, 21 + | subu TMP0, TMP1, TMP0 + | slt AT, TMP0, r0 + | bnez AT, >1 + |. sll TMP1, SFARG1HI, 11 + | lui AT, 0x8000 + | or TMP1, TMP1, AT + | srl AT, SFARG1LO, 21 + | or TMP1, TMP1, AT + | slt AT, SFARG1HI, r0 + | beqz AT, >2 + |. srlv SFARG1LO, TMP1, TMP0 + | subu SFARG1LO, r0, SFARG1LO + |2: + | jr ra + |. move CRET1, SFARG1LO + |1: + | addiu TMP0, TMP0, 21 + | srlv TMP1, SFARG1LO, TMP0 + | li AT, 20 + | subu TMP0, AT, TMP0 + | sll SFARG1LO, SFARG1HI, 12 + | sllv AT, SFARG1LO, TMP0 + | or SFARG1LO, TMP1, AT + | slt AT, SFARG1HI, r0 + | beqz AT, <2 + |. nop + | jr ra + |. subu CRET1, r0, SFARG1LO + |.endif + | |.macro .ffunc_bit, name - | .ffunc_n bit_..name - |. add.d FARG1, FARG1, TOBIT - | mfc1 CRET1, FARG1 + | .ffunc_1 bit_..name + | beq SFARG1HI, TISNUM, >6 + |. move CRET1, SFARG1LO + | bal ->vm_tobit_fb + |. sltu TMP1, SFARG1HI, TISNUM + |6: |.endmacro | |.macro .ffunc_bit_op, name, ins | .ffunc_bit name - | addiu TMP1, BASE, 8 - | addu TMP2, BASE, NARGS8:RC + | addiu TMP2, BASE, 8 + | addu TMP3, BASE, NARGS8:RC |1: - | lw CARG4, HI(TMP1) - | beq TMP1, TMP2, ->fff_resi - |. ldc1 FARG1, 0(TMP1) - | sltiu AT, CARG4, LJ_TISNUM - | beqz AT, ->fff_fallback - | add.d FARG1, FARG1, TOBIT - | mfc1 CARG2, FARG1 - | ins CRET1, CRET1, CARG2 + | lw SFARG1HI, HI(TMP2) + | beq TMP2, TMP3, ->fff_resi + |. lw SFARG1LO, LO(TMP2) + |.if FPU + | bne SFARG1HI, TISNUM, >2 + |. addiu TMP2, TMP2, 8 | b <1 - |. addiu TMP1, TMP1, 8 + |. ins CRET1, CRET1, SFARG1LO + |2: + | ldc1 FARG1, -8(TMP2) + | sltu TMP1, SFARG1HI, TISNUM + | beqz TMP1, ->fff_fallback + |. add.d FARG1, FARG1, TOBIT + | mfc1 SFARG1LO, FARG1 + | b <1 + |. ins CRET1, CRET1, SFARG1LO + |.else + | beq SFARG1HI, TISNUM, >2 + |. move CRET2, CRET1 + | bal ->vm_tobit_fb + |. sltu TMP1, SFARG1HI, TISNUM + | move SFARG1LO, CRET2 + |2: + | ins CRET1, CRET1, SFARG1LO + | b <1 + |. addiu TMP2, TMP2, 8 + |.endif |.endmacro | |.ffunc_bit_op band, and @@ -1793,24 +2085,28 @@ static void build_subroutines(BuildCtx *ctx) |. not CRET1, CRET1 | |.macro .ffunc_bit_sh, name, ins, shmod - | .ffunc_nn bit_..name - |. add.d FARG1, FARG1, TOBIT - | add.d FARG2, FARG2, TOBIT - | mfc1 CARG1, FARG1 - | mfc1 CARG2, FARG2 + | .ffunc_2 bit_..name + | beq SFARG1HI, TISNUM, >1 + |. nop + | bal ->vm_tobit_fb + |. sltu TMP1, SFARG1HI, TISNUM + | move SFARG1LO, CRET1 + |1: + | bne SFARG2HI, TISNUM, ->fff_fallback + |. nop |.if shmod == 1 | li AT, 32 - | subu TMP0, AT, CARG2 - | sllv CARG2, CARG1, CARG2 - | srlv CARG1, CARG1, TMP0 + | subu TMP0, AT, SFARG2LO + | sllv SFARG2LO, SFARG1LO, SFARG2LO + | srlv SFARG1LO, SFARG1LO, TMP0 |.elif shmod == 2 | li AT, 32 - | subu TMP0, AT, CARG2 - | srlv CARG2, CARG1, CARG2 - | sllv CARG1, CARG1, TMP0 + | subu TMP0, AT, SFARG2LO + | srlv SFARG2LO, SFARG1LO, SFARG2LO + | sllv SFARG1LO, SFARG1LO, TMP0 |.endif | b ->fff_resi - |. ins CRET1, CARG1, CARG2 + |. ins CRET1, SFARG1LO, SFARG2LO |.endmacro | |.ffunc_bit_sh lshift, sllv, 0 @@ -1822,9 +2118,11 @@ static void build_subroutines(BuildCtx *ctx) | |.ffunc_bit tobit |->fff_resi: - | mtc1 CRET1, FRET1 - | b ->fff_resn - |. cvt.d.w FRET1, FRET1 + | lw PC, FRAME_PC(BASE) + | addiu RA, BASE, -8 + | sw TISNUM, -8+HI(BASE) + | b ->fff_res1 + |. sw CRET1, -8+LO(BASE) | |//----------------------------------------------------------------------- | @@ -2015,17 +2313,19 @@ static void build_subroutines(BuildCtx *ctx) |.if JIT | // RA = resultptr, RB = meta base | lw INS, -4(PC) - | lw TMP3, -24+LO(RB) // Save previous trace number. + | lw TMP2, -24+LO(RB) // Save previous trace. | decode_RA8a RC, INS | addiu AT, MULTRES, -8 | decode_RA8b RC | beqz AT, >2 |. addu RC, BASE, RC // Call base. |1: // Move results down. - | ldc1 f0, 0(RA) + | lw SFRETHI, HI(RA) + | lw SFRETLO, LO(RA) | addiu AT, AT, -8 | addiu RA, RA, 8 - | sdc1 f0, 0(RC) + | sw SFRETHI, HI(RC) + | sw SFRETLO, LO(RC) | bnez AT, <1 |. addiu RC, RC, 8 |2: @@ -2034,17 +2334,13 @@ static void build_subroutines(BuildCtx *ctx) | decode_RA8b RA | decode_RB8b RB | addu RA, RA, RB - | lw TMP1, DISPATCH_J(trace)(DISPATCH) | addu RA, BASE, RA |3: | sltu AT, RC, RA | bnez AT, >9 // More results wanted? - |. sll TMP2, TMP3, 2 + |. nop | - | addu TMP2, TMP1, TMP2 - | lw TRACE:TMP2, 0(TMP2) - | beqz TRACE:TMP2, ->cont_nop - |. nop + | lhu TMP3, TRACE:TMP2->traceno | lhu RD, TRACE:TMP2->link | beq RD, TMP3, ->cont_nop // Blacklisted. |. load_got lj_dispatch_stitch @@ -2086,14 +2382,23 @@ static void build_subroutines(BuildCtx *ctx) |//----------------------------------------------------------------------- | |.macro savex_, a, b + |.if FPU | sdc1 f..a, 16+a*8(sp) | sw r..a, 16+32*8+a*4(sp) | sw r..b, 16+32*8+b*4(sp) + |.else + | sw r..a, 16+a*4(sp) + | sw r..b, 16+b*4(sp) + |.endif |.endmacro | |->vm_exit_handler: |.if JIT + |.if FPU | addiu sp, sp, -(16+32*8+32*4) + |.else + | addiu sp, sp, -(16+32*4) + |.endif | savex_ 0, 1 | savex_ 2, 3 | savex_ 4, 5 @@ -2108,17 +2413,25 @@ static void build_subroutines(BuildCtx *ctx) | savex_ 22, 23 | savex_ 24, 25 | savex_ 26, 27 + |.if FPU | sdc1 f28, 16+28*8(sp) - | sw r28, 16+32*8+28*4(sp) | sdc1 f30, 16+30*8(sp) + | sw r28, 16+32*8+28*4(sp) | sw r30, 16+32*8+30*4(sp) | sw r0, 16+32*8+31*4(sp) // Clear RID_TMP. + | addiu TMP2, sp, 16+32*8+32*4 // Recompute original value of sp. + | sw TMP2, 16+32*8+29*4(sp) // Store sp in RID_SP + |.else + | sw r28, 16+28*4(sp) + | sw r30, 16+30*4(sp) + | sw r0, 16+31*4(sp) // Clear RID_TMP. + | addiu TMP2, sp, 16+32*4 // Recompute original value of sp. + | sw TMP2, 16+29*4(sp) // Store sp in RID_SP + |.endif | li_vmstate EXIT - | addiu TMP2, sp, 16+32*8+32*4 // Recompute original value of sp. | addiu DISPATCH, JGL, -GG_DISP2G-32768 | lw TMP1, 0(TMP2) // Load exit number. | st_vmstate - | sw TMP2, 16+32*8+29*4(sp) // Store sp in RID_SP. | lw L, DISPATCH_GL(cur_L)(DISPATCH) | lw BASE, DISPATCH_GL(jit_base)(DISPATCH) | load_got lj_trace_exit @@ -2148,15 +2461,16 @@ static void build_subroutines(BuildCtx *ctx) |1: | bltz CRET1, >9 // Check for error from exit. |. lw LFUNC:RB, FRAME_FUNC(BASE) - | lui TMP3, 0x59c0 // TOBIT = 2^52 + 2^51 (float). + | .FPU lui TMP3, 0x59c0 // TOBIT = 2^52 + 2^51 (float). | sll MULTRES, CRET1, 3 | li TISNIL, LJ_TNIL + | li TISNUM, LJ_TISNUM // Setup type comparison constants. | sw MULTRES, SAVE_MULTRES - | mtc1 TMP3, TOBIT + | .FPU mtc1 TMP3, TOBIT | lw TMP1, LFUNC:RB->pc | sw r0, DISPATCH_GL(jit_base)(DISPATCH) | lw KBASE, PC2PROTO(k)(TMP1) - | cvt.d.s TOBIT, TOBIT + | .FPU cvt.d.s TOBIT, TOBIT | // Modified copy of ins_next which handles function header dispatch, too. | lw INS, 0(PC) | addiu PC, PC, 4 @@ -2164,7 +2478,7 @@ static void build_subroutines(BuildCtx *ctx) | sw TISNIL, DISPATCH_GL(vmstate)(DISPATCH) | decode_OP4a TMP1, INS | decode_OP4b TMP1 - | sltiu TMP2, TMP1, BC_FUNCF*4 // Function header? + | sltiu TMP2, TMP1, BC_FUNCF*4 | addu TMP0, DISPATCH, TMP1 | decode_RD8a RD, INS | lw AT, 0(TMP0) @@ -2205,8 +2519,9 @@ static void build_subroutines(BuildCtx *ctx) |//-- Math helper functions ---------------------------------------------- |//----------------------------------------------------------------------- | + |// Hard-float round to integer. |// Modifies AT, TMP0, FRET1, FRET2, f4. Keeps all others incl. FARG1. - |.macro vm_round, func + |.macro vm_round_hf, func | lui TMP0, 0x4330 // Hiword of 2^52 (double). | mtc1 r0, f4 | mtc1 TMP0, f5 @@ -2248,6 +2563,12 @@ static void build_subroutines(BuildCtx *ctx) |. mov.d FRET1, FARG1 |.endmacro | + |.macro vm_round, func + |.if FPU + | vm_round_hf, func + |.endif + |.endmacro + | |->vm_floor: | vm_round floor |->vm_ceil: @@ -2257,6 +2578,178 @@ static void build_subroutines(BuildCtx *ctx) | vm_round trunc |.endif | + |// Soft-float integer to number conversion. + |.macro sfi2d, AHI, ALO + |.if not FPU + | beqz ALO, >9 // Handle zero first. + |. sra TMP0, ALO, 31 + | xor TMP1, ALO, TMP0 + | subu TMP1, TMP1, TMP0 // Absolute value in TMP1. + | clz AHI, TMP1 + | andi TMP0, TMP0, 0x800 // Mask sign bit. + | li AT, 0x3ff+31-1 + | sllv TMP1, TMP1, AHI // Align mantissa left with leading 1. + | subu AHI, AT, AHI // Exponent - 1 in AHI. + | sll ALO, TMP1, 21 + | or AHI, AHI, TMP0 // Sign | Exponent. + | srl TMP1, TMP1, 11 + | sll AHI, AHI, 20 // Align left. + | jr ra + |. addu AHI, AHI, TMP1 // Add mantissa, increment exponent. + |9: + | jr ra + |. li AHI, 0 + |.endif + |.endmacro + | + |// Input SFARG1LO. Output: SFARG1*. Temporaries: AT, TMP0, TMP1. + |->vm_sfi2d_1: + | sfi2d SFARG1HI, SFARG1LO + | + |// Input SFARG2LO. Output: SFARG2*. Temporaries: AT, TMP0, TMP1. + |->vm_sfi2d_2: + | sfi2d SFARG2HI, SFARG2LO + | + |// Soft-float comparison. Equivalent to c.eq.d. + |// Input: SFARG*. Output: CRET1. Temporaries: AT, TMP0, TMP1. + |->vm_sfcmpeq: + |.if not FPU + | sll AT, SFARG1HI, 1 + | sll TMP0, SFARG2HI, 1 + | or CRET1, SFARG1LO, SFARG2LO + | or TMP1, AT, TMP0 + | or TMP1, TMP1, CRET1 + | beqz TMP1, >8 // Both args +-0: return 1. + |. sltu CRET1, r0, SFARG1LO + | lui TMP1, 0xffe0 + | addu AT, AT, CRET1 + | sltu CRET1, r0, SFARG2LO + | sltu AT, TMP1, AT + | addu TMP0, TMP0, CRET1 + | sltu TMP0, TMP1, TMP0 + | or TMP1, AT, TMP0 + | bnez TMP1, >9 // Either arg is NaN: return 0; + |. xor TMP0, SFARG1HI, SFARG2HI + | xor TMP1, SFARG1LO, SFARG2LO + | or AT, TMP0, TMP1 + | jr ra + |. sltiu CRET1, AT, 1 // Same values: return 1. + |8: + | jr ra + |. li CRET1, 1 + |9: + | jr ra + |. li CRET1, 0 + |.endif + | + |// Soft-float comparison. Equivalent to c.ult.d and c.olt.d. + |// Input: SFARG*. Output: CRET1. Temporaries: AT, TMP0, TMP1, CRET2. + |->vm_sfcmpult: + |.if not FPU + | b >1 + |. li CRET2, 1 + |.endif + | + |->vm_sfcmpolt: + |.if not FPU + | li CRET2, 0 + |1: + | sll AT, SFARG1HI, 1 + | sll TMP0, SFARG2HI, 1 + | or CRET1, SFARG1LO, SFARG2LO + | or TMP1, AT, TMP0 + | or TMP1, TMP1, CRET1 + | beqz TMP1, >8 // Both args +-0: return 0. + |. sltu CRET1, r0, SFARG1LO + | lui TMP1, 0xffe0 + | addu AT, AT, CRET1 + | sltu CRET1, r0, SFARG2LO + | sltu AT, TMP1, AT + | addu TMP0, TMP0, CRET1 + | sltu TMP0, TMP1, TMP0 + | or TMP1, AT, TMP0 + | bnez TMP1, >9 // Either arg is NaN: return 0 or 1; + |. and AT, SFARG1HI, SFARG2HI + | bltz AT, >5 // Both args negative? + |. nop + | beq SFARG1HI, SFARG2HI, >8 + |. sltu CRET1, SFARG1LO, SFARG2LO + | jr ra + |. slt CRET1, SFARG1HI, SFARG2HI + |5: // Swap conditions if both operands are negative. + | beq SFARG1HI, SFARG2HI, >8 + |. sltu CRET1, SFARG2LO, SFARG1LO + | jr ra + |. slt CRET1, SFARG2HI, SFARG1HI + |8: + | jr ra + |. nop + |9: + | jr ra + |. move CRET1, CRET2 + |.endif + | + |// Soft-float comparison. Equivalent to c.ole.d a, b or c.ole.d b, a. + |// Input: SFARG*, TMP3. Output: CRET1. Temporaries: AT, TMP0, TMP1. + |->vm_sfcmpolex: + |.if not FPU + | sll AT, SFARG1HI, 1 + | sll TMP0, SFARG2HI, 1 + | or CRET1, SFARG1LO, SFARG2LO + | or TMP1, AT, TMP0 + | or TMP1, TMP1, CRET1 + | beqz TMP1, >8 // Both args +-0: return 1. + |. sltu CRET1, r0, SFARG1LO + | lui TMP1, 0xffe0 + | addu AT, AT, CRET1 + | sltu CRET1, r0, SFARG2LO + | sltu AT, TMP1, AT + | addu TMP0, TMP0, CRET1 + | sltu TMP0, TMP1, TMP0 + | or TMP1, AT, TMP0 + | bnez TMP1, >9 // Either arg is NaN: return 0; + |. and AT, SFARG1HI, SFARG2HI + | xor AT, AT, TMP3 + | bltz AT, >5 // Both args negative? + |. nop + | beq SFARG1HI, SFARG2HI, >6 + |. sltu CRET1, SFARG2LO, SFARG1LO + | jr ra + |. slt CRET1, SFARG2HI, SFARG1HI + |5: // Swap conditions if both operands are negative. + | beq SFARG1HI, SFARG2HI, >6 + |. sltu CRET1, SFARG1LO, SFARG2LO + | slt CRET1, SFARG1HI, SFARG2HI + |6: + | jr ra + |. nop + |8: + | jr ra + |. li CRET1, 1 + |9: + | jr ra + |. li CRET1, 0 + |.endif + | + |.macro sfmin_max, name, intins + |->vm_sf .. name: + |.if JIT and not FPU + | move TMP2, ra + | bal ->vm_sfcmpolt + |. nop + | move TMP0, CRET1 + | move SFRETHI, SFARG1HI + | move SFRETLO, SFARG1LO + | move ra, TMP2 + | intins SFRETHI, SFARG2HI, TMP0 + | jr ra + |. intins SFRETLO, SFARG2LO, TMP0 + |.endif + |.endmacro + | + | sfmin_max min, movz + | sfmin_max max, movn + | |//----------------------------------------------------------------------- |//-- Miscellaneous functions -------------------------------------------- |//----------------------------------------------------------------------- @@ -2276,10 +2769,10 @@ static void build_subroutines(BuildCtx *ctx) | sw r1, CTSTATE->cb.slot | sw CARG1, CTSTATE->cb.gpr[0] | sw CARG2, CTSTATE->cb.gpr[1] - | sdc1 FARG1, CTSTATE->cb.fpr[0] + | .FPU sdc1 FARG1, CTSTATE->cb.fpr[0] | sw CARG3, CTSTATE->cb.gpr[2] | sw CARG4, CTSTATE->cb.gpr[3] - | sdc1 FARG2, CTSTATE->cb.fpr[1] + | .FPU sdc1 FARG2, CTSTATE->cb.fpr[1] | addiu TMP0, sp, CFRAME_SPACE+16 | sw TMP0, CTSTATE->cb.stack | sw r0, SAVE_PC // Any value outside of bytecode is ok. @@ -2289,15 +2782,16 @@ static void build_subroutines(BuildCtx *ctx) | // Returns lua_State *. | lw BASE, L:CRET1->base | lw RC, L:CRET1->top + | li TISNUM, LJ_TISNUM // Setup type comparison constants. | move L, CRET1 - | lui TMP3, 0x59c0 // TOBIT = 2^52 + 2^51 (float). + | .FPU lui TMP3, 0x59c0 // TOBIT = 2^52 + 2^51 (float). | lw LFUNC:RB, FRAME_FUNC(BASE) - | mtc1 TMP3, TOBIT + | .FPU mtc1 TMP3, TOBIT | li_vmstate INTERP | li TISNIL, LJ_TNIL | subu RC, RC, BASE | st_vmstate - | cvt.d.s TOBIT, TOBIT + | .FPU cvt.d.s TOBIT, TOBIT | ins_callt |.endif | @@ -2311,11 +2805,11 @@ static void build_subroutines(BuildCtx *ctx) | move CARG2, RA | call_intern lj_ccallback_leave // (CTState *cts, TValue *o) |. move CARG1, CTSTATE + | .FPU ldc1 FRET1, CTSTATE->cb.fpr[0] | lw CRET1, CTSTATE->cb.gpr[0] - | ldc1 FRET1, CTSTATE->cb.fpr[0] - | lw CRET2, CTSTATE->cb.gpr[1] + | .FPU ldc1 FRET2, CTSTATE->cb.fpr[1] | b ->vm_leave_unw - |. ldc1 FRET2, CTSTATE->cb.fpr[1] + |. lw CRET2, CTSTATE->cb.gpr[1] |.endif | |->vm_ffi_call: // Call C function via FFI. @@ -2347,8 +2841,8 @@ static void build_subroutines(BuildCtx *ctx) | lw CARG2, CCSTATE->gpr[1] | lw CARG3, CCSTATE->gpr[2] | lw CARG4, CCSTATE->gpr[3] - | ldc1 FARG1, CCSTATE->fpr[0] - | ldc1 FARG2, CCSTATE->fpr[1] + | .FPU ldc1 FARG1, CCSTATE->fpr[0] + | .FPU ldc1 FARG2, CCSTATE->fpr[1] | jalr CFUNCADDR |. lw CARG1, CCSTATE->gpr[0] // Do this last, since CCSTATE is CARG1. | lw CCSTATE:TMP1, -12(r16) @@ -2356,8 +2850,13 @@ static void build_subroutines(BuildCtx *ctx) | lw ra, -4(r16) | sw CRET1, CCSTATE:TMP1->gpr[0] | sw CRET2, CCSTATE:TMP1->gpr[1] + |.if FPU | sdc1 FRET1, CCSTATE:TMP1->fpr[0] | sdc1 FRET2, CCSTATE:TMP1->fpr[1] + |.else + | sw CARG1, CCSTATE:TMP1->gpr[2] // Soft-float: complex double .im part. + | sw CARG2, CCSTATE:TMP1->gpr[3] + |.endif | move sp, r16 | jr ra |. move r16, TMP2 @@ -2381,82 +2880,143 @@ static void build_ins(BuildCtx *ctx, BCOp op, int defop) case BC_ISLT: case BC_ISGE: case BC_ISLE: case BC_ISGT: | // RA = src1*8, RD = src2*8, JMP with RD = target - | addu CARG2, BASE, RA - | addu CARG3, BASE, RD - | lw TMP0, HI(CARG2) - | lw TMP1, HI(CARG3) - | ldc1 f0, 0(CARG2) - | ldc1 f2, 0(CARG3) - | sltiu TMP0, TMP0, LJ_TISNUM - | sltiu TMP1, TMP1, LJ_TISNUM + |.macro bc_comp, FRA, FRD, RAHI, RALO, RDHI, RDLO, movop, fmovop, fcomp, sfcomp + | addu RA, BASE, RA + | addu RD, BASE, RD + | lw RAHI, HI(RA) + | lw RDHI, HI(RD) | lhu TMP2, OFS_RD(PC) - | and TMP0, TMP0, TMP1 | addiu PC, PC, 4 - | beqz TMP0, ->vmeta_comp - |. lui TMP1, (-(BCBIAS_J*4 >> 16) & 65535) - | decode_RD4b TMP2 - | addu TMP2, TMP2, TMP1 - if (op == BC_ISLT || op == BC_ISGE) { - | c.olt.d f0, f2 - } else { - | c.ole.d f0, f2 - } - if (op == BC_ISLT || op == BC_ISLE) { - | movf TMP2, r0 - } else { - | movt TMP2, r0 - } - | addu PC, PC, TMP2 + | bne RAHI, TISNUM, >2 + |. lw RALO, LO(RA) + | lui TMP3, (-(BCBIAS_J*4 >> 16) & 65535) + | lw RDLO, LO(RD) + | bne RDHI, TISNUM, >5 + |. decode_RD4b TMP2 + | slt AT, SFARG1LO, SFARG2LO + | addu TMP2, TMP2, TMP3 + | movop TMP2, r0, AT |1: + | addu PC, PC, TMP2 | ins_next + | + |2: // RA is not an integer. + | sltiu AT, RAHI, LJ_TISNUM + | beqz AT, ->vmeta_comp + |. lui TMP3, (-(BCBIAS_J*4 >> 16) & 65535) + | sltiu AT, RDHI, LJ_TISNUM + |.if FPU + | ldc1 FRA, 0(RA) + | ldc1 FRD, 0(RD) + |.else + | lw RDLO, LO(RD) + |.endif + | beqz AT, >4 + |. decode_RD4b TMP2 + |3: // RA and RD are both numbers. + |.if FPU + | fcomp f20, f22 + | addu TMP2, TMP2, TMP3 + | b <1 + |. fmovop TMP2, r0 + |.else + | bal sfcomp + |. addu TMP2, TMP2, TMP3 + | b <1 + |. movop TMP2, r0, CRET1 + |.endif + | + |4: // RA is a number, RD is not a number. + | bne RDHI, TISNUM, ->vmeta_comp + | // RA is a number, RD is an integer. Convert RD to a number. + |.if FPU + |. lwc1 FRD, LO(RD) + | b <3 + |. cvt.d.w FRD, FRD + |.else + |. nop + |.if "RDHI" == "SFARG1HI" + | bal ->vm_sfi2d_1 + |.else + | bal ->vm_sfi2d_2 + |.endif + |. nop + | b <3 + |. nop + |.endif + | + |5: // RA is an integer, RD is not an integer + | sltiu AT, RDHI, LJ_TISNUM + | beqz AT, ->vmeta_comp + | // RA is an integer, RD is a number. Convert RA to a number. + |.if FPU + |. mtc1 RALO, FRA + | ldc1 FRD, 0(RD) + | b <3 + | cvt.d.w FRA, FRA + |.else + |. nop + |.if "RAHI" == "SFARG1HI" + | bal ->vm_sfi2d_1 + |.else + | bal ->vm_sfi2d_2 + |.endif + |. nop + | b <3 + |. nop + |.endif + |.endmacro + | + if (op == BC_ISLT) { + | bc_comp f20, f22, SFARG1HI, SFARG1LO, SFARG2HI, SFARG2LO, movz, movf, c.olt.d, ->vm_sfcmpolt + } else if (op == BC_ISGE) { + | bc_comp f20, f22, SFARG1HI, SFARG1LO, SFARG2HI, SFARG2LO, movn, movt, c.olt.d, ->vm_sfcmpolt + } else if (op == BC_ISLE) { + | bc_comp f22, f20, SFARG2HI, SFARG2LO, SFARG1HI, SFARG1LO, movn, movt, c.ult.d, ->vm_sfcmpult + } else { + | bc_comp f22, f20, SFARG2HI, SFARG2LO, SFARG1HI, SFARG1LO, movz, movf, c.ult.d, ->vm_sfcmpult + } break; case BC_ISEQV: case BC_ISNEV: vk = op == BC_ISEQV; | // RA = src1*8, RD = src2*8, JMP with RD = target | addu RA, BASE, RA - | addiu PC, PC, 4 - | lw TMP0, HI(RA) - | ldc1 f0, 0(RA) + | addiu PC, PC, 4 | addu RD, BASE, RD + | lw SFARG1HI, HI(RA) | lhu TMP2, -4+OFS_RD(PC) - | lw TMP1, HI(RD) - | ldc1 f2, 0(RD) + | lw SFARG2HI, HI(RD) | lui TMP3, (-(BCBIAS_J*4 >> 16) & 65535) - | sltiu AT, TMP0, LJ_TISNUM - | sltiu CARG1, TMP1, LJ_TISNUM - | decode_RD4b TMP2 - | and AT, AT, CARG1 - | beqz AT, >5 - |. addu TMP2, TMP2, TMP3 - | c.eq.d f0, f2 + | sltu AT, TISNUM, SFARG1HI + | sltu TMP0, TISNUM, SFARG2HI + | or AT, AT, TMP0 if (vk) { - | movf TMP2, r0 + | beqz AT, ->BC_ISEQN_Z } else { - | movt TMP2, r0 + | beqz AT, ->BC_ISNEN_Z } - |1: - | addu PC, PC, TMP2 - | ins_next - |5: // Either or both types are not numbers. - | lw CARG2, LO(RA) - | lw CARG3, LO(RD) + |. decode_RD4b TMP2 + | // Either or both types are not numbers. + | lw SFARG1LO, LO(RA) + | lw SFARG2LO, LO(RD) + | addu TMP2, TMP2, TMP3 |.if FFI | li TMP3, LJ_TCDATA - | beq TMP0, TMP3, ->vmeta_equal_cd + | beq SFARG1HI, TMP3, ->vmeta_equal_cd |.endif - |. sltiu AT, TMP0, LJ_TISPRI // Not a primitive? + |. sltiu AT, SFARG1HI, LJ_TISPRI // Not a primitive? |.if FFI - | beq TMP1, TMP3, ->vmeta_equal_cd + | beq SFARG2HI, TMP3, ->vmeta_equal_cd |.endif - |. xor TMP3, CARG2, CARG3 // Same tv? - | xor TMP1, TMP1, TMP0 // Same type? - | sltiu CARG1, TMP0, LJ_TISTABUD+1 // Table or userdata? + |. xor TMP3, SFARG1LO, SFARG2LO // Same tv? + | xor SFARG2HI, SFARG2HI, SFARG1HI // Same type? + | sltiu TMP0, SFARG1HI, LJ_TISTABUD+1 // Table or userdata? | movz TMP3, r0, AT // Ignore tv if primitive. - | movn CARG1, r0, TMP1 // Tab/ud and same type? - | or AT, TMP1, TMP3 // Same type && (pri||same tv). - | movz CARG1, r0, AT - | beqz CARG1, <1 // Done if not tab/ud or not same type or same tv. + | movn TMP0, r0, SFARG2HI // Tab/ud and same type? + | or AT, SFARG2HI, TMP3 // Same type && (pri||same tv). + | movz TMP0, r0, AT + | beqz TMP0, >1 // Done if not tab/ud or not same type or same tv. if (vk) { |. movn TMP2, r0, AT } else { @@ -2464,15 +3024,18 @@ static void build_ins(BuildCtx *ctx, BCOp op, int defop) } | // Different tables or userdatas. Need to check __eq metamethod. | // Field metatable must be at same offset for GCtab and GCudata! - | lw TAB:TMP1, TAB:CARG2->metatable - | beqz TAB:TMP1, <1 // No metatable? + | lw TAB:TMP1, TAB:SFARG1LO->metatable + | beqz TAB:TMP1, >1 // No metatable? |. nop | lbu TMP1, TAB:TMP1->nomm | andi TMP1, TMP1, 1<<MM_eq - | bnez TMP1, <1 // Or 'no __eq' flag set? + | bnez TMP1, >1 // Or 'no __eq' flag set? |. nop | b ->vmeta_equal // Handle __eq metamethod. - |. li CARG4, 1-vk // ne = 0 or 1. + |. li TMP0, 1-vk // ne = 0 or 1. + |1: + | addu PC, PC, TMP2 + | ins_next break; case BC_ISEQS: case BC_ISNES: @@ -2509,38 +3072,124 @@ static void build_ins(BuildCtx *ctx, BCOp op, int defop) vk = op == BC_ISEQN; | // RA = src*8, RD = num_const*8, JMP with RD = target | addu RA, BASE, RA - | addiu PC, PC, 4 - | lw TMP0, HI(RA) - | ldc1 f0, 0(RA) - | addu RD, KBASE, RD - | lhu TMP2, -4+OFS_RD(PC) - | ldc1 f2, 0(RD) + | addu RD, KBASE, RD + | lw SFARG1HI, HI(RA) + | lw SFARG2HI, HI(RD) + | lhu TMP2, OFS_RD(PC) + | addiu PC, PC, 4 | lui TMP3, (-(BCBIAS_J*4 >> 16) & 65535) - | sltiu AT, TMP0, LJ_TISNUM | decode_RD4b TMP2 - |.if FFI - | beqz AT, >5 - |.else - | beqz AT, >1 - |.endif - |. addu TMP2, TMP2, TMP3 - | c.eq.d f0, f2 if (vk) { - | movf TMP2, r0 - | addu PC, PC, TMP2 + |->BC_ISEQN_Z: + } else { + |->BC_ISNEN_Z: + } + | bne SFARG1HI, TISNUM, >3 + |. lw SFARG1LO, LO(RA) + | lw SFARG2LO, LO(RD) + | addu TMP2, TMP2, TMP3 + | bne SFARG2HI, TISNUM, >6 + |. xor AT, SFARG1LO, SFARG2LO + if (vk) { + | movn TMP2, r0, AT |1: + | addu PC, PC, TMP2 + |2: } else { - | movt TMP2, r0 + | movz TMP2, r0, AT |1: + |2: | addu PC, PC, TMP2 } | ins_next + | + |3: // RA is not an integer. + | sltiu AT, SFARG1HI, LJ_TISNUM |.if FFI - |5: - | li AT, LJ_TCDATA - | beq TMP0, AT, ->vmeta_equal_cd + | beqz AT, >8 + |.else + | beqz AT, <2 + |.endif + |. addu TMP2, TMP2, TMP3 + | sltiu AT, SFARG2HI, LJ_TISNUM + |.if FPU + | ldc1 f20, 0(RA) + | ldc1 f22, 0(RD) + |.endif + | beqz AT, >5 + |. lw SFARG2LO, LO(RD) + |4: // RA and RD are both numbers. + |.if FPU + | c.eq.d f20, f22 + | b <1 + if (vk) { + |. movf TMP2, r0 + } else { + |. movt TMP2, r0 + } + |.else + | bal ->vm_sfcmpeq |. nop | b <1 + if (vk) { + |. movz TMP2, r0, CRET1 + } else { + |. movn TMP2, r0, CRET1 + } + |.endif + | + |5: // RA is a number, RD is not a number. + |.if FFI + | bne SFARG2HI, TISNUM, >9 + |.else + | bne SFARG2HI, TISNUM, <2 + |.endif + | // RA is a number, RD is an integer. Convert RD to a number. + |.if FPU + |. lwc1 f22, LO(RD) + | b <4 + |. cvt.d.w f22, f22 + |.else + |. nop + | bal ->vm_sfi2d_2 + |. nop + | b <4 + |. nop + |.endif + | + |6: // RA is an integer, RD is not an integer + | sltiu AT, SFARG2HI, LJ_TISNUM + |.if FFI + | beqz AT, >9 + |.else + | beqz AT, <2 + |.endif + | // RA is an integer, RD is a number. Convert RA to a number. + |.if FPU + |. mtc1 SFARG1LO, f20 + | ldc1 f22, 0(RD) + | b <4 + | cvt.d.w f20, f20 + |.else + |. nop + | bal ->vm_sfi2d_1 + |. nop + | b <4 + |. nop + |.endif + | + |.if FFI + |8: + | li AT, LJ_TCDATA + | bne SFARG1HI, AT, <2 + |. nop + | b ->vmeta_equal_cd + |. nop + |9: + | li AT, LJ_TCDATA + | bne SFARG2HI, AT, <2 + |. nop + | b ->vmeta_equal_cd |. nop |.endif break; @@ -2592,7 +3241,8 @@ static void build_ins(BuildCtx *ctx, BCOp op, int defop) | addu PC, PC, TMP2 } else { | sltiu TMP0, TMP0, LJ_TISTRUECOND - | ldc1 f0, 0(RD) + | lw SFRETHI, HI(RD) + | lw SFRETLO, LO(RD) if (op == BC_ISTC) { | beqz TMP0, >1 } else { @@ -2602,7 +3252,8 @@ static void build_ins(BuildCtx *ctx, BCOp op, int defop) | decode_RD4b TMP2 | lui TMP3, (-(BCBIAS_J*4 >> 16) & 65535) | addu TMP2, TMP2, TMP3 - | sdc1 f0, 0(RA) + | sw SFRETHI, HI(RA) + | sw SFRETLO, LO(RA) | addu PC, PC, TMP2 |1: } @@ -2634,10 +3285,12 @@ static void build_ins(BuildCtx *ctx, BCOp op, int defop) case BC_MOV: | // RA = dst*8, RD = src*8 | addu RD, BASE, RD - | addu RA, BASE, RA - | ldc1 f0, 0(RD) + | addu RA, BASE, RA + | lw SFRETHI, HI(RD) + | lw SFRETLO, LO(RD) | ins_next1 - | sdc1 f0, 0(RA) + | sw SFRETHI, HI(RA) + | sw SFRETLO, LO(RA) | ins_next2 break; case BC_NOT: @@ -2654,16 +3307,25 @@ static void build_ins(BuildCtx *ctx, BCOp op, int defop) break; case BC_UNM: | // RA = dst*8, RD = src*8 - | addu CARG3, BASE, RD + | addu RB, BASE, RD + | lw SFARG1HI, HI(RB) | addu RA, BASE, RA - | lw TMP0, HI(CARG3) - | ldc1 f0, 0(CARG3) - | sltiu AT, TMP0, LJ_TISNUM - | beqz AT, ->vmeta_unm - |. neg.d f0, f0 + | bne SFARG1HI, TISNUM, >2 + |. lw SFARG1LO, LO(RB) + | lui TMP1, 0x8000 + | beq SFARG1LO, TMP1, ->vmeta_unm // Meta handler deals with -2^31. + |. negu SFARG1LO, SFARG1LO + |1: | ins_next1 - | sdc1 f0, 0(RA) + | sw SFARG1HI, HI(RA) + | sw SFARG1LO, LO(RA) | ins_next2 + |2: + | sltiu AT, SFARG1HI, LJ_TISNUM + | beqz AT, ->vmeta_unm + |. lui TMP1, 0x8000 + | b <1 + |. xor SFARG1HI, SFARG1HI, TMP1 break; case BC_LEN: | // RA = dst*8, RD = src*8 @@ -2674,12 +3336,11 @@ static void build_ins(BuildCtx *ctx, BCOp op, int defop) | li AT, LJ_TSTR | bne TMP0, AT, >2 |. li AT, LJ_TTAB - | lw CRET1, STR:CARG1->len + | lw CRET1, STR:CARG1->len |1: - | mtc1 CRET1, f0 - | cvt.d.w f0, f0 | ins_next1 - | sdc1 f0, 0(RA) + | sw TISNUM, HI(RA) + | sw CRET1, LO(RA) | ins_next2 |2: | bne TMP0, AT, ->vmeta_len @@ -2710,104 +3371,232 @@ static void build_ins(BuildCtx *ctx, BCOp op, int defop) /* -- Binary ops -------------------------------------------------------- */ - |.macro ins_arithpre + |.macro fpmod, a, b, c + | bal ->vm_floor // floor(b/c) + |. div.d FARG1, b, c + | mul.d a, FRET1, c + | sub.d a, b, a // b - floor(b/c)*c + |.endmacro + + |.macro sfpmod + | addiu sp, sp, -16 + | + | load_got __divdf3 + | sw SFARG1HI, HI(sp) + | sw SFARG1LO, LO(sp) + | sw SFARG2HI, 8+HI(sp) + | call_extern + |. sw SFARG2LO, 8+LO(sp) + | + | load_got floor + | move SFARG1HI, SFRETHI + | call_extern + |. move SFARG1LO, SFRETLO + | + | load_got __muldf3 + | move SFARG1HI, SFRETHI + | move SFARG1LO, SFRETLO + | lw SFARG2HI, 8+HI(sp) + | call_extern + |. lw SFARG2LO, 8+LO(sp) + | + | load_got __subdf3 + | lw SFARG1HI, HI(sp) + | lw SFARG1LO, LO(sp) + | move SFARG2HI, SFRETHI + | call_extern + |. move SFARG2LO, SFRETLO + | + | addiu sp, sp, 16 + |.endmacro + + |.macro ins_arithpre, label ||vk = ((int)op - BC_ADDVN) / (BC_ADDNV-BC_ADDVN); - | decode_RB8a RB, INS - | decode_RB8b RB - | decode_RDtoRC8 RC, RD | // RA = dst*8, RB = src1*8, RC = src2*8 | num_const*8 ||switch (vk) { ||case 0: - | addu CARG3, BASE, RB - | addu CARG4, KBASE, RC - | lw TMP1, HI(CARG3) - | ldc1 f20, 0(CARG3) - | ldc1 f22, 0(CARG4) - | sltiu AT, TMP1, LJ_TISNUM + | decode_RB8a RB, INS + | decode_RB8b RB + | decode_RDtoRC8 RC, RD + | // RA = dst*8, RB = src1*8, RC = num_const*8 + | addu RB, BASE, RB + |.if "label" ~= "none" + | b label + |.endif + |. addu RC, KBASE, RC || break; ||case 1: - | addu CARG4, BASE, RB - | addu CARG3, KBASE, RC - | lw TMP1, HI(CARG4) - | ldc1 f22, 0(CARG4) - | ldc1 f20, 0(CARG3) - | sltiu AT, TMP1, LJ_TISNUM + | decode_RB8a RC, INS + | decode_RB8b RC + | decode_RDtoRC8 RB, RD + | // RA = dst*8, RB = num_const*8, RC = src1*8 + | addu RC, BASE, RC + |.if "label" ~= "none" + | b label + |.endif + |. addu RB, KBASE, RB || break; ||default: - | addu CARG3, BASE, RB - | addu CARG4, BASE, RC - | lw TMP1, HI(CARG3) - | lw TMP2, HI(CARG4) - | ldc1 f20, 0(CARG3) - | ldc1 f22, 0(CARG4) - | sltiu AT, TMP1, LJ_TISNUM - | sltiu TMP0, TMP2, LJ_TISNUM - | and AT, AT, TMP0 + | decode_RB8a RB, INS + | decode_RB8b RB + | decode_RDtoRC8 RC, RD + | // RA = dst*8, RB = src1*8, RC = src2*8 + | addu RB, BASE, RB + |.if "label" ~= "none" + | b label + |.endif + |. addu RC, BASE, RC || break; ||} - | beqz AT, ->vmeta_arith - |. addu RA, BASE, RA |.endmacro | - |.macro fpmod, a, b, c - |->BC_MODVN_Z: - | bal ->vm_floor // floor(b/c) - |. div.d FARG1, b, c - | mul.d a, FRET1, c - | sub.d a, b, a // b - floor(b/c)*c - |.endmacro + |.macro ins_arith, intins, fpins, fpcall, label + | ins_arithpre none | - |.macro ins_arith, ins - | ins_arithpre - |.if "ins" == "fpmod_" - | b ->BC_MODVN_Z // Avoid 3 copies. It's slow anyway. - |. nop + |.if "label" ~= "none" + |label: + |.endif + | + | lw SFARG1HI, HI(RB) + | lw SFARG2HI, HI(RC) + | + |.if "intins" ~= "div" + | + | // Check for two integers. + | lw SFARG1LO, LO(RB) + | bne SFARG1HI, TISNUM, >5 + |. lw SFARG2LO, LO(RC) + | bne SFARG2HI, TISNUM, >5 + | + |.if "intins" == "addu" + |. intins CRET1, SFARG1LO, SFARG2LO + | xor TMP1, CRET1, SFARG1LO // ((y^a) & (y^b)) < 0: overflow. + | xor TMP2, CRET1, SFARG2LO + | and TMP1, TMP1, TMP2 + | bltz TMP1, ->vmeta_arith + |. addu RA, BASE, RA + |.elif "intins" == "subu" + |. intins CRET1, SFARG1LO, SFARG2LO + | xor TMP1, CRET1, SFARG1LO // ((y^a) & (a^b)) < 0: overflow. + | xor TMP2, SFARG1LO, SFARG2LO + | and TMP1, TMP1, TMP2 + | bltz TMP1, ->vmeta_arith + |. addu RA, BASE, RA + |.elif "intins" == "mult" + |. intins SFARG1LO, SFARG2LO + | mflo CRET1 + | mfhi TMP2 + | sra TMP1, CRET1, 31 + | bne TMP1, TMP2, ->vmeta_arith + |. addu RA, BASE, RA + |.else + |. load_got lj_vm_modi + | beqz SFARG2LO, ->vmeta_arith + |. addu RA, BASE, RA + |.if ENDIAN_BE + | move CARG1, SFARG1LO + |.endif + | call_extern + |. move CARG2, SFARG2LO + |.endif + | + | ins_next1 + | sw TISNUM, HI(RA) + | sw CRET1, LO(RA) + |3: + | ins_next2 + | + |.elif not FPU + | + | lw SFARG1LO, LO(RB) + | lw SFARG2LO, LO(RC) + | + |.endif + | + |5: // Check for two numbers. + | .FPU ldc1 f20, 0(RB) + | sltiu AT, SFARG1HI, LJ_TISNUM + | sltiu TMP0, SFARG2HI, LJ_TISNUM + | .FPU ldc1 f22, 0(RC) + | and AT, AT, TMP0 + | beqz AT, ->vmeta_arith + |. addu RA, BASE, RA + | + |.if FPU + | fpins FRET1, f20, f22 + |.elif "fpcall" == "sfpmod" + | sfpmod |.else - | ins f0, f20, f22 + | load_got fpcall + | call_extern + |. nop + |.endif + | | ins_next1 - | sdc1 f0, 0(RA) + |.if not FPU + | sw SFRETHI, HI(RA) + |.endif + |.if "intins" ~= "div" + | b <3 + |.endif + |.if FPU + |. sdc1 FRET1, 0(RA) + |.else + |. sw SFRETLO, LO(RA) + |.endif + |.if "intins" == "div" | ins_next2 |.endif + | |.endmacro case BC_ADDVN: case BC_ADDNV: case BC_ADDVV: - | ins_arith add.d + | ins_arith addu, add.d, __adddf3, none break; case BC_SUBVN: case BC_SUBNV: case BC_SUBVV: - | ins_arith sub.d + | ins_arith subu, sub.d, __subdf3, none break; case BC_MULVN: case BC_MULNV: case BC_MULVV: - | ins_arith mul.d + | ins_arith mult, mul.d, __muldf3, none break; - case BC_DIVVN: case BC_DIVNV: case BC_DIVVV: - | ins_arith div.d + case BC_DIVVN: + | ins_arith div, div.d, __divdf3, ->BC_DIVVN_Z + break; + case BC_DIVNV: case BC_DIVVV: + | ins_arithpre ->BC_DIVVN_Z break; case BC_MODVN: - | ins_arith fpmod + | ins_arith modi, fpmod, sfpmod, ->BC_MODVN_Z break; case BC_MODNV: case BC_MODVV: - | ins_arith fpmod_ + | ins_arithpre ->BC_MODVN_Z break; case BC_POW: - | decode_RB8a RB, INS - | decode_RB8b RB - | decode_RDtoRC8 RC, RD - | addu CARG3, BASE, RB - | addu CARG4, BASE, RC - | lw TMP1, HI(CARG3) - | lw TMP2, HI(CARG4) - | ldc1 FARG1, 0(CARG3) - | ldc1 FARG2, 0(CARG4) - | sltiu AT, TMP1, LJ_TISNUM - | sltiu TMP0, TMP2, LJ_TISNUM + | ins_arithpre none + | lw SFARG1HI, HI(RB) + | lw SFARG2HI, HI(RC) + | sltiu AT, SFARG1HI, LJ_TISNUM + | sltiu TMP0, SFARG2HI, LJ_TISNUM | and AT, AT, TMP0 | load_got pow | beqz AT, ->vmeta_arith |. addu RA, BASE, RA + |.if FPU + | ldc1 FARG1, 0(RB) + | ldc1 FARG2, 0(RC) + |.else + | lw SFARG1LO, LO(RB) + | lw SFARG2LO, LO(RC) + |.endif | call_extern |. nop | ins_next1 + |.if FPU | sdc1 FRET1, 0(RA) + |.else + | sw SFRETHI, HI(RA) + | sw SFRETLO, LO(RA) + |.endif | ins_next2 break; @@ -2830,10 +3619,12 @@ static void build_ins(BuildCtx *ctx, BCOp op, int defop) | bnez CRET1, ->vmeta_binop |. lw BASE, L->base | addu RB, BASE, MULTRES - | ldc1 f0, 0(RB) + | lw SFRETHI, HI(RB) + | lw SFRETLO, LO(RB) | addu RA, BASE, RA | ins_next1 - | sdc1 f0, 0(RA) // Copy result from RB to RA. + | sw SFRETHI, HI(RA) + | sw SFRETLO, LO(RA) | ins_next2 break; @@ -2868,20 +3659,21 @@ static void build_ins(BuildCtx *ctx, BCOp op, int defop) case BC_KSHORT: | // RA = dst*8, RD = int16_literal*8 | sra RD, INS, 16 - | mtc1 RD, f0 | addu RA, BASE, RA - | cvt.d.w f0, f0 | ins_next1 - | sdc1 f0, 0(RA) + | sw TISNUM, HI(RA) + | sw RD, LO(RA) | ins_next2 break; case BC_KNUM: | // RA = dst*8, RD = num_const*8 | addu RD, KBASE, RD | addu RA, BASE, RA - | ldc1 f0, 0(RD) + | lw SFRETHI, HI(RD) + | lw SFRETLO, LO(RD) | ins_next1 - | sdc1 f0, 0(RA) + | sw SFRETHI, HI(RA) + | sw SFRETLO, LO(RA) | ins_next2 break; case BC_KPRI: @@ -2917,9 +3709,11 @@ static void build_ins(BuildCtx *ctx, BCOp op, int defop) | lw UPVAL:RB, LFUNC:RD->uvptr | ins_next1 | lw TMP1, UPVAL:RB->v - | ldc1 f0, 0(TMP1) + | lw SFRETHI, HI(TMP1) + | lw SFRETLO, LO(TMP1) | addu RA, BASE, RA - | sdc1 f0, 0(RA) + | sw SFRETHI, HI(RA) + | sw SFRETLO, LO(RA) | ins_next2 break; case BC_USETV: @@ -2928,26 +3722,27 @@ static void build_ins(BuildCtx *ctx, BCOp op, int defop) | srl RA, RA, 1 | addu RD, BASE, RD | addu RA, RA, LFUNC:RB - | ldc1 f0, 0(RD) | lw UPVAL:RB, LFUNC:RA->uvptr + | lw SFRETHI, HI(RD) + | lw SFRETLO, LO(RD) | lbu TMP3, UPVAL:RB->marked | lw CARG2, UPVAL:RB->v | andi TMP3, TMP3, LJ_GC_BLACK // isblack(uv) | lbu TMP0, UPVAL:RB->closed - | lw TMP2, HI(RD) - | sdc1 f0, 0(CARG2) + | sw SFRETHI, HI(CARG2) + | sw SFRETLO, LO(CARG2) | li AT, LJ_GC_BLACK|1 | or TMP3, TMP3, TMP0 | beq TMP3, AT, >2 // Upvalue is closed and black? - |. addiu TMP2, TMP2, -(LJ_TNUMX+1) + |. addiu TMP2, SFRETHI, -(LJ_TNUMX+1) |1: | ins_next | |2: // Check if new value is collectable. | sltiu AT, TMP2, LJ_TISGCV - (LJ_TNUMX+1) | beqz AT, <1 // tvisgcv(v) - |. lw TMP1, LO(RD) - | lbu TMP3, GCOBJ:TMP1->gch.marked + |. nop + | lbu TMP3, GCOBJ:SFRETLO->gch.marked | andi TMP3, TMP3, LJ_GC_WHITES // iswhite(v) | beqz TMP3, <1 |. load_got lj_gc_barrieruv @@ -2995,11 +3790,13 @@ static void build_ins(BuildCtx *ctx, BCOp op, int defop) | srl RA, RA, 1 | addu RD, KBASE, RD | addu RA, RA, LFUNC:RB - | ldc1 f0, 0(RD) - | lw UPVAL:RB, LFUNC:RA->uvptr + | lw UPVAL:RB, LFUNC:RA->uvptr + | lw SFRETHI, HI(RD) + | lw SFRETLO, LO(RD) + | lw TMP1, UPVAL:RB->v | ins_next1 - | lw TMP1, UPVAL:RB->v - | sdc1 f0, 0(TMP1) + | sw SFRETHI, HI(TMP1) + | sw SFRETLO, LO(TMP1) | ins_next2 break; case BC_USETP: @@ -3009,10 +3806,10 @@ static void build_ins(BuildCtx *ctx, BCOp op, int defop) | srl TMP0, RD, 3 | addu RA, RA, LFUNC:RB | not TMP0, TMP0 - | lw UPVAL:RB, LFUNC:RA->uvptr + | lw UPVAL:RB, LFUNC:RA->uvptr | ins_next1 - | lw TMP1, UPVAL:RB->v - | sw TMP0, HI(TMP1) + | lw TMP1, UPVAL:RB->v + | sw TMP0, HI(TMP1) | ins_next2 break; @@ -3048,8 +3845,8 @@ static void build_ins(BuildCtx *ctx, BCOp op, int defop) | li TMP0, LJ_TFUNC | ins_next1 | addu RA, BASE, RA - | sw TMP0, HI(RA) | sw LFUNC:CRET1, LO(RA) + | sw TMP0, HI(RA) | ins_next2 break; @@ -3130,31 +3927,23 @@ static void build_ins(BuildCtx *ctx, BCOp op, int defop) | lw TMP2, HI(CARG3) | lw TAB:RB, LO(CARG2) | li AT, LJ_TTAB - | ldc1 f0, 0(CARG3) | bne TMP1, AT, ->vmeta_tgetv |. addu RA, BASE, RA - | sltiu AT, TMP2, LJ_TISNUM - | beqz AT, >5 - |. li AT, LJ_TSTR - | - | // Convert number key to integer, check for integerness and range. - | cvt.w.d f2, f0 - | lw TMP0, TAB:RB->asize - | mfc1 TMP2, f2 - | cvt.d.w f4, f2 + | bne TMP2, TISNUM, >5 + |. lw RC, LO(CARG3) + | lw TMP0, TAB:RB->asize | lw TMP1, TAB:RB->array - | c.eq.d f0, f4 - | sltu AT, TMP2, TMP0 - | movf AT, r0 - | sll TMP2, TMP2, 3 + | sltu AT, RC, TMP0 + | sll TMP2, RC, 3 | beqz AT, ->vmeta_tgetv // Integer key and in array part? |. addu TMP2, TMP1, TMP2 - | lw TMP0, HI(TMP2) - | beq TMP0, TISNIL, >2 - |. ldc1 f0, 0(TMP2) + | lw SFRETHI, HI(TMP2) + | beq SFRETHI, TISNIL, >2 + |. lw SFRETLO, LO(TMP2) |1: | ins_next1 - | sdc1 f0, 0(RA) + | sw SFRETHI, HI(RA) + | sw SFRETLO, LO(RA) | ins_next2 | |2: // Check for __index if table value is nil. @@ -3169,8 +3958,9 @@ static void build_ins(BuildCtx *ctx, BCOp op, int defop) |. nop | |5: + | li AT, LJ_TSTR | bne TMP2, AT, ->vmeta_tgetv - |. lw STR:RC, LO(CARG3) + |. nop | b ->BC_TGETS_Z // String key? |. nop break; @@ -3202,18 +3992,18 @@ static void build_ins(BuildCtx *ctx, BCOp op, int defop) | lw CARG1, offsetof(Node, key)+HI(NODE:TMP2) | lw TMP0, offsetof(Node, key)+LO(NODE:TMP2) | lw NODE:TMP1, NODE:TMP2->next - | lw CARG2, offsetof(Node, val)+HI(NODE:TMP2) + | lw SFRETHI, offsetof(Node, val)+HI(NODE:TMP2) | addiu CARG1, CARG1, -LJ_TSTR | xor TMP0, TMP0, STR:RC | or AT, CARG1, TMP0 | bnez AT, >4 |. lw TAB:TMP3, TAB:RB->metatable - | beq CARG2, TISNIL, >5 // Key found, but nil value? - |. lw CARG1, offsetof(Node, val)+LO(NODE:TMP2) + | beq SFRETHI, TISNIL, >5 // Key found, but nil value? + |. lw SFRETLO, offsetof(Node, val)+LO(NODE:TMP2) |3: | ins_next1 - | sw CARG2, HI(RA) - | sw CARG1, LO(RA) + | sw SFRETHI, HI(RA) + | sw SFRETLO, LO(RA) | ins_next2 | |4: // Follow hash chain. @@ -3223,7 +4013,7 @@ static void build_ins(BuildCtx *ctx, BCOp op, int defop) | |5: // Check for __index if table value is nil. | beqz TAB:TMP3, <3 // No metatable: done. - |. li CARG2, LJ_TNIL + |. li SFRETHI, LJ_TNIL | lbu TMP0, TAB:TMP3->nomm | andi TMP0, TMP0, 1<<MM_index | bnez TMP0, <3 // 'no __index' flag set: done. @@ -3248,12 +4038,13 @@ static void build_ins(BuildCtx *ctx, BCOp op, int defop) | sltu AT, TMP0, TMP1 | beqz AT, ->vmeta_tgetb |. addu RC, TMP2, RC - | lw TMP1, HI(RC) - | beq TMP1, TISNIL, >5 - |. ldc1 f0, 0(RC) + | lw SFRETHI, HI(RC) + | beq SFRETHI, TISNIL, >5 + |. lw SFRETLO, LO(RC) |1: | ins_next1 - | sdc1 f0, 0(RA) + | sw SFRETHI, HI(RA) + | sw SFRETLO, LO(RA) | ins_next2 | |5: // Check for __index if table value is nil. @@ -3264,7 +4055,7 @@ static void build_ins(BuildCtx *ctx, BCOp op, int defop) | andi TMP1, TMP1, 1<<MM_index | bnez TMP1, <1 // 'no __index' flag set: done. |. nop - | b ->vmeta_tgetb // Caveat: preserve TMP0! + | b ->vmeta_tgetb // Caveat: preserve TMP0 and CARG2! |. nop break; case BC_TGETR: @@ -3272,23 +4063,23 @@ static void build_ins(BuildCtx *ctx, BCOp op, int defop) | decode_RB8a RB, INS | decode_RB8b RB | decode_RDtoRC8 RC, RD - | addu CARG2, BASE, RB - | addu CARG3, BASE, RC - | lw TAB:CARG1, LO(CARG2) - | ldc1 f0, 0(CARG3) - | trunc.w.d f2, f0 - | lw TMP0, TAB:CARG1->asize - | mfc1 CARG2, f2 + | addu RB, BASE, RB + | addu RC, BASE, RC + | lw TAB:CARG1, LO(RB) + | lw CARG2, LO(RC) + | addu RA, BASE, RA + | lw TMP0, TAB:CARG1->asize | lw TMP1, TAB:CARG1->array | sltu AT, CARG2, TMP0 | sll TMP2, CARG2, 3 | beqz AT, ->vmeta_tgetr // In array part? - |. addu TMP2, TMP1, TMP2 - | ldc1 f0, 0(TMP2) + |. addu CRET1, TMP1, TMP2 + | lw SFARG2HI, HI(CRET1) + | lw SFARG2LO, LO(CRET1) |->BC_TGETR_Z: - | addu RA, BASE, RA | ins_next1 - | sdc1 f0, 0(RA) + | sw SFARG2HI, HI(RA) + | sw SFARG2LO, LO(RA) | ins_next2 break; @@ -3303,33 +4094,26 @@ static void build_ins(BuildCtx *ctx, BCOp op, int defop) | lw TMP2, HI(CARG3) | lw TAB:RB, LO(CARG2) | li AT, LJ_TTAB - | ldc1 f0, 0(CARG3) | bne TMP1, AT, ->vmeta_tsetv |. addu RA, BASE, RA - | sltiu AT, TMP2, LJ_TISNUM - | beqz AT, >5 - |. li AT, LJ_TSTR - | - | // Convert number key to integer, check for integerness and range. - | cvt.w.d f2, f0 - | lw TMP0, TAB:RB->asize - | mfc1 TMP2, f2 - | cvt.d.w f4, f2 + | bne TMP2, TISNUM, >5 + |. lw RC, LO(CARG3) + | lw TMP0, TAB:RB->asize | lw TMP1, TAB:RB->array - | c.eq.d f0, f4 - | sltu AT, TMP2, TMP0 - | movf AT, r0 - | sll TMP2, TMP2, 3 + | sltu AT, RC, TMP0 + | sll TMP2, RC, 3 | beqz AT, ->vmeta_tsetv // Integer key and in array part? |. addu TMP1, TMP1, TMP2 - | lbu TMP3, TAB:RB->marked | lw TMP0, HI(TMP1) + | lbu TMP3, TAB:RB->marked + | lw SFRETHI, HI(RA) | beq TMP0, TISNIL, >3 - |. ldc1 f0, 0(RA) + |. lw SFRETLO, LO(RA) |1: - | andi AT, TMP3, LJ_GC_BLACK // isblack(table) - | bnez AT, >7 - |. sdc1 f0, 0(TMP1) + | andi AT, TMP3, LJ_GC_BLACK // isblack(table) + | sw SFRETHI, HI(TMP1) + | bnez AT, >7 + |. sw SFRETLO, LO(TMP1) |2: | ins_next | @@ -3345,8 +4129,9 @@ static void build_ins(BuildCtx *ctx, BCOp op, int defop) |. nop | |5: + | li AT, LJ_TSTR | bne TMP2, AT, ->vmeta_tsetv - |. lw STR:RC, LO(CARG3) + |. nop | b ->BC_TSETS_Z // String key? |. nop | @@ -3378,7 +4163,12 @@ static void build_ins(BuildCtx *ctx, BCOp op, int defop) | sll TMP1, TMP1, 3 | subu TMP1, TMP0, TMP1 | addu NODE:TMP2, NODE:TMP2, TMP1 // node = tab->node + (idx*32-idx*8) + |.if FPU | ldc1 f20, 0(RA) + |.else + | lw SFRETHI, HI(RA) + | lw SFRETLO, LO(RA) + |.endif |1: | lw CARG1, offsetof(Node, key)+HI(NODE:TMP2) | lw TMP0, offsetof(Node, key)+LO(NODE:TMP2) @@ -3392,8 +4182,14 @@ static void build_ins(BuildCtx *ctx, BCOp op, int defop) |. lw TAB:TMP0, TAB:RB->metatable |2: | andi AT, TMP3, LJ_GC_BLACK // isblack(table) + |.if FPU | bnez AT, >7 |. sdc1 f20, NODE:TMP2->val + |.else + | sw SFRETHI, NODE:TMP2->val.u32.hi + | bnez AT, >7 + |. sw SFRETLO, NODE:TMP2->val.u32.lo + |.endif |3: | ins_next | @@ -3431,8 +4227,16 @@ static void build_ins(BuildCtx *ctx, BCOp op, int defop) |. move CARG1, L | // Returns TValue *. | lw BASE, L->base + |.if FPU | b <3 // No 2nd write barrier needed. |. sdc1 f20, 0(CRET1) + |.else + | lw SFARG1HI, HI(RA) + | lw SFARG1LO, LO(RA) + | sw SFARG1HI, HI(CRET1) + | b <3 // No 2nd write barrier needed. + |. sw SFARG1LO, LO(CRET1) + |.endif | |7: // Possible table write barrier for the value. Skip valiswhite check. | barrierback TAB:RB, TMP3, TMP0, <3 @@ -3457,11 +4261,13 @@ static void build_ins(BuildCtx *ctx, BCOp op, int defop) | lw TMP1, HI(RC) | lbu TMP3, TAB:RB->marked | beq TMP1, TISNIL, >5 - |. ldc1 f0, 0(RA) |1: + |. lw SFRETHI, HI(RA) + | lw SFRETLO, LO(RA) | andi AT, TMP3, LJ_GC_BLACK // isblack(table) + | sw SFRETHI, HI(RC) | bnez AT, >7 - |. sdc1 f0, 0(RC) + |. sw SFRETLO, LO(RC) |2: | ins_next | @@ -3473,7 +4279,7 @@ static void build_ins(BuildCtx *ctx, BCOp op, int defop) | andi TMP1, TMP1, 1<<MM_newindex | bnez TMP1, <1 // 'no __newindex' flag set: done. |. nop - | b ->vmeta_tsetb // Caveat: preserve TMP0! + | b ->vmeta_tsetb // Caveat: preserve TMP0 and CARG2! |. nop | |7: // Possible table write barrier for the value. Skip valiswhite check. @@ -3486,13 +4292,11 @@ static void build_ins(BuildCtx *ctx, BCOp op, int defop) | decode_RDtoRC8 RC, RD | addu CARG1, BASE, RB | addu CARG3, BASE, RC - | lw TAB:CARG2, LO(CARG1) - | ldc1 f0, 0(CARG3) - | trunc.w.d f2, f0 - | lbu TMP3, TAB:CARG2->marked + | lw TAB:CARG2, LO(CARG1) + | lw CARG3, LO(CARG3) + | lbu TMP3, TAB:CARG2->marked | lw TMP0, TAB:CARG2->asize - | mfc1 CARG3, f2 - | lw TMP1, TAB:CARG2->array + | lw TMP1, TAB:CARG2->array | andi AT, TMP3, LJ_GC_BLACK // isblack(table) | bnez AT, >7 |. addu RA, BASE, RA @@ -3500,18 +4304,19 @@ static void build_ins(BuildCtx *ctx, BCOp op, int defop) | sltu AT, CARG3, TMP0 | sll TMP2, CARG3, 3 | beqz AT, ->vmeta_tsetr // In array part? - |. ldc1 f20, 0(RA) - | addu CRET1, TMP1, TMP2 + |. addu CRET1, TMP1, TMP2 |->BC_TSETR_Z: + | lw SFARG1HI, HI(RA) + | lw SFARG1LO, LO(RA) | ins_next1 - | sdc1 f20, 0(CRET1) + | sw SFARG1HI, HI(CRET1) + | sw SFARG1LO, LO(CRET1) | ins_next2 | |7: // Possible table write barrier for the value. Skip valiswhite check. | barrierback TAB:RB, TMP3, TMP0, <2 break; - case BC_TSETM: | // RA = base*8 (table at base-1), RD = num_const*8 (start index) | addu RA, BASE, RA @@ -3533,10 +4338,12 @@ static void build_ins(BuildCtx *ctx, BCOp op, int defop) | addu TMP1, TMP1, CARG1 | andi TMP0, TMP3, LJ_GC_BLACK // isblack(table) |3: // Copy result slots to table. - | ldc1 f0, 0(RA) + | lw SFRETHI, HI(RA) + | lw SFRETLO, LO(RA) | addiu RA, RA, 8 | sltu AT, RA, TMP2 - | sdc1 f0, 0(TMP1) + | sw SFRETHI, HI(TMP1) + | sw SFRETLO, LO(TMP1) | bnez AT, <3 |. addiu TMP1, TMP1, 8 | bnez TMP0, >7 @@ -3611,10 +4418,12 @@ static void build_ins(BuildCtx *ctx, BCOp op, int defop) | beqz NARGS8:RC, >3 |. move TMP3, NARGS8:RC |2: - | ldc1 f0, 0(RA) + | lw SFRETHI, HI(RA) + | lw SFRETLO, LO(RA) | addiu RA, RA, 8 | addiu TMP3, TMP3, -8 - | sdc1 f0, 0(TMP2) + | sw SFRETHI, HI(TMP2) + | sw SFRETLO, LO(TMP2) | bnez TMP3, <2 |. addiu TMP2, TMP2, 8 |3: @@ -3651,12 +4460,16 @@ static void build_ins(BuildCtx *ctx, BCOp op, int defop) | li AT, LJ_TFUNC | lw TMP1, -24+HI(BASE) | lw LFUNC:RB, -24+LO(BASE) - | ldc1 f2, -8(BASE) - | ldc1 f0, -16(BASE) + | lw SFARG1HI, -16+HI(BASE) + | lw SFARG1LO, -16+LO(BASE) + | lw SFARG2HI, -8+HI(BASE) + | lw SFARG2LO, -8+LO(BASE) | sw TMP1, HI(BASE) // Copy callable. | sw LFUNC:RB, LO(BASE) - | sdc1 f2, 16(BASE) // Copy control var. - | sdc1 f0, 8(BASE) // Copy state. + | sw SFARG1HI, 8+HI(BASE) // Copy state. + | sw SFARG1LO, 8+LO(BASE) + | sw SFARG2HI, 16+HI(BASE) // Copy control var. + | sw SFARG2LO, 16+LO(BASE) | addiu BASE, BASE, 8 | bne TMP1, AT, ->vmeta_call |. li NARGS8:RC, 16 // Iterators get 2 arguments. @@ -3679,20 +4492,20 @@ static void build_ins(BuildCtx *ctx, BCOp op, int defop) | beqz AT, >5 // Index points after array part? |. sll TMP3, RC, 3 | addu TMP3, TMP1, TMP3 - | lw TMP2, HI(TMP3) - | ldc1 f0, 0(TMP3) - | mtc1 RC, f2 + | lw SFARG1HI, HI(TMP3) + | lw SFARG1LO, LO(TMP3) | lhu RD, -4+OFS_RD(PC) - | beq TMP2, TISNIL, <1 // Skip holes in array part. + | sw TISNUM, HI(RA) + | sw RC, LO(RA) + | beq SFARG1HI, TISNIL, <1 // Skip holes in array part. |. addiu RC, RC, 1 - | cvt.d.w f2, f2 + | sw SFARG1HI, 8+HI(RA) + | sw SFARG1LO, 8+LO(RA) | lui TMP3, (-(BCBIAS_J*4 >> 16) & 65535) - | sdc1 f0, 8(RA) | decode_RD4b RD | addu RD, RD, TMP3 | sw RC, -8+LO(RA) // Update control var. | addu PC, PC, RD - | sdc1 f2, 0(RA) |3: | ins_next | @@ -3707,18 +4520,21 @@ static void build_ins(BuildCtx *ctx, BCOp op, int defop) | sll RB, RC, 3 | subu TMP3, TMP3, RB | addu NODE:TMP3, TMP3, TMP2 - | lw RB, HI(NODE:TMP3) - | ldc1 f0, 0(NODE:TMP3) + | lw SFARG1HI, NODE:TMP3->val.u32.hi + | lw SFARG1LO, NODE:TMP3->val.u32.lo | lhu RD, -4+OFS_RD(PC) - | beq RB, TISNIL, <6 // Skip holes in hash part. + | beq SFARG1HI, TISNIL, <6 // Skip holes in hash part. |. addiu RC, RC, 1 - | ldc1 f2, NODE:TMP3->key + | lw SFARG2HI, NODE:TMP3->key.u32.hi + | lw SFARG2LO, NODE:TMP3->key.u32.lo | lui TMP3, (-(BCBIAS_J*4 >> 16) & 65535) - | sdc1 f0, 8(RA) + | sw SFARG1HI, 8+HI(RA) + | sw SFARG1LO, 8+LO(RA) | addu RC, RC, TMP0 | decode_RD4b RD | addu RD, RD, TMP3 - | sdc1 f2, 0(RA) + | sw SFARG2HI, HI(RA) + | sw SFARG2LO, LO(RA) | addu PC, PC, RD | b <3 |. sw RC, -8+LO(RA) // Update control var. @@ -3798,9 +4614,11 @@ static void build_ins(BuildCtx *ctx, BCOp op, int defop) | bnez AT, >7 |. addiu MULTRES, TMP1, 8 |6: - | ldc1 f0, 0(RC) + | lw SFRETHI, HI(RC) + | lw SFRETLO, LO(RC) | addiu RC, RC, 8 - | sdc1 f0, 0(RA) + | sw SFRETHI, HI(RA) + | sw SFRETLO, LO(RA) | sltu AT, RC, TMP3 | bnez AT, <6 // More vararg slots? |. addiu RA, RA, 8 @@ -3856,10 +4674,12 @@ static void build_ins(BuildCtx *ctx, BCOp op, int defop) | beqz RC, >3 |. subu BASE, TMP2, TMP0 |2: - | ldc1 f0, 0(RA) + | lw SFRETHI, HI(RA) + | lw SFRETLO, LO(RA) | addiu RA, RA, 8 | addiu RC, RC, -8 - | sdc1 f0, 0(TMP2) + | sw SFRETHI, HI(TMP2) + | sw SFRETLO, LO(TMP2) | bnez RC, <2 |. addiu TMP2, TMP2, 8 |3: @@ -3900,14 +4720,16 @@ static void build_ins(BuildCtx *ctx, BCOp op, int defop) | lw INS, -4(PC) | addiu TMP2, BASE, -8 if (op == BC_RET1) { - | ldc1 f0, 0(RA) + | lw SFRETHI, HI(RA) + | lw SFRETLO, LO(RA) } | decode_RB8a RB, INS | decode_RA8a RA, INS | decode_RB8b RB | decode_RA8b RA if (op == BC_RET1) { - | sdc1 f0, 0(TMP2) + | sw SFRETHI, HI(TMP2) + | sw SFRETLO, LO(TMP2) } | subu BASE, TMP2, RA |5: @@ -3949,69 +4771,147 @@ static void build_ins(BuildCtx *ctx, BCOp op, int defop) | // RA = base*8, RD = target (after end of loop or start of loop) vk = (op == BC_IFORL || op == BC_JFORL); | addu RA, BASE, RA - if (vk) { - | ldc1 f0, FORL_IDX*8(RA) - | ldc1 f4, FORL_STEP*8(RA) - | ldc1 f2, FORL_STOP*8(RA) - | lw TMP3, FORL_STEP*8+HI(RA) - | add.d f0, f0, f4 - | sdc1 f0, FORL_IDX*8(RA) - } else { - | lw TMP1, FORL_IDX*8+HI(RA) - | lw TMP3, FORL_STEP*8+HI(RA) - | lw TMP2, FORL_STOP*8+HI(RA) - | sltiu TMP1, TMP1, LJ_TISNUM - | sltiu TMP0, TMP3, LJ_TISNUM - | sltiu TMP2, TMP2, LJ_TISNUM - | and TMP1, TMP1, TMP0 - | and TMP1, TMP1, TMP2 - | ldc1 f0, FORL_IDX*8(RA) - | beqz TMP1, ->vmeta_for - |. ldc1 f2, FORL_STOP*8(RA) - } + | lw SFARG1HI, FORL_IDX*8+HI(RA) + | lw SFARG1LO, FORL_IDX*8+LO(RA) if (op != BC_JFORL) { | srl RD, RD, 1 - | lui TMP0, (-(BCBIAS_J*4 >> 16) & 65535) + | lui TMP2, (-(BCBIAS_J*4 >> 16) & 65535) + | addu TMP2, RD, TMP2 + } + if (!vk) { + | lw SFARG2HI, FORL_STOP*8+HI(RA) + | lw SFARG2LO, FORL_STOP*8+LO(RA) + | bne SFARG1HI, TISNUM, >5 + |. lw SFRETHI, FORL_STEP*8+HI(RA) + | xor AT, SFARG2HI, TISNUM + | lw SFRETLO, FORL_STEP*8+LO(RA) + | xor TMP0, SFRETHI, TISNUM + | or AT, AT, TMP0 + | bnez AT, ->vmeta_for + |. slt AT, SFRETLO, r0 + | slt CRET1, SFARG2LO, SFARG1LO + | slt TMP1, SFARG1LO, SFARG2LO + | movn CRET1, TMP1, AT + } else { + | bne SFARG1HI, TISNUM, >5 + |. lw SFARG2LO, FORL_STEP*8+LO(RA) + | lw SFRETLO, FORL_STOP*8+LO(RA) + | move TMP3, SFARG1LO + | addu SFARG1LO, SFARG1LO, SFARG2LO + | xor TMP0, SFARG1LO, TMP3 + | xor TMP1, SFARG1LO, SFARG2LO + | and TMP0, TMP0, TMP1 + | slt TMP1, SFARG1LO, SFRETLO + | slt CRET1, SFRETLO, SFARG1LO + | slt AT, SFARG2LO, r0 + | slt TMP0, TMP0, r0 // ((y^a) & (y^b)) < 0: overflow. + | movn CRET1, TMP1, AT + | or CRET1, CRET1, TMP0 + } + |1: + if (op == BC_FORI) { + | movz TMP2, r0, CRET1 + | addu PC, PC, TMP2 + } else if (op == BC_JFORI) { + | addu PC, PC, TMP2 + | lhu RD, -4+OFS_RD(PC) + } else if (op == BC_IFORL) { + | movn TMP2, r0, CRET1 + | addu PC, PC, TMP2 } - | c.le.d 0, f0, f2 - | c.le.d 1, f2, f0 - | sdc1 f0, FORL_EXT*8(RA) + if (vk) { + | sw SFARG1HI, FORL_IDX*8+HI(RA) + | sw SFARG1LO, FORL_IDX*8+LO(RA) + } + | ins_next1 + | sw SFARG1HI, FORL_EXT*8+HI(RA) + | sw SFARG1LO, FORL_EXT*8+LO(RA) + |2: if (op == BC_JFORI) { - | li TMP1, 1 - | li TMP2, 1 - | addu TMP0, RD, TMP0 - | slt TMP3, TMP3, r0 - | movf TMP1, r0, 0 - | addu PC, PC, TMP0 - | movf TMP2, r0, 1 - | lhu RD, -4+OFS_RD(PC) - | movn TMP1, TMP2, TMP3 - | bnez TMP1, =>BC_JLOOP + | beqz CRET1, =>BC_JLOOP |. decode_RD8b RD } else if (op == BC_JFORL) { - | li TMP1, 1 - | li TMP2, 1 - | slt TMP3, TMP3, r0 - | movf TMP1, r0, 0 - | movf TMP2, r0, 1 - | movn TMP1, TMP2, TMP3 - | bnez TMP1, =>BC_JLOOP + | beqz CRET1, =>BC_JLOOP + } + | ins_next2 + | + |5: // FP loop. + |.if FPU + if (!vk) { + | ldc1 f0, FORL_IDX*8(RA) + | ldc1 f2, FORL_STOP*8(RA) + | sltiu TMP0, SFARG1HI, LJ_TISNUM + | sltiu TMP1, SFARG2HI, LJ_TISNUM + | sltiu AT, SFRETHI, LJ_TISNUM + | and TMP0, TMP0, TMP1 + | and AT, AT, TMP0 + | beqz AT, ->vmeta_for + |. slt TMP3, SFRETHI, r0 + | c.ole.d 0, f0, f2 + | c.ole.d 1, f2, f0 + | li CRET1, 1 + | movt CRET1, r0, 0 + | movt AT, r0, 1 + | b <1 + |. movn CRET1, AT, TMP3 + } else { + | ldc1 f0, FORL_IDX*8(RA) + | ldc1 f4, FORL_STEP*8(RA) + | ldc1 f2, FORL_STOP*8(RA) + | lw SFARG2HI, FORL_STEP*8+HI(RA) + | add.d f0, f0, f4 + | c.ole.d 0, f0, f2 + | c.ole.d 1, f2, f0 + | slt TMP3, SFARG2HI, r0 + | li CRET1, 1 + | li AT, 1 + | movt CRET1, r0, 0 + | movt AT, r0, 1 + | movn CRET1, AT, TMP3 + if (op == BC_IFORL) { + | movn TMP2, r0, CRET1 + | addu PC, PC, TMP2 + } + | sdc1 f0, FORL_IDX*8(RA) + | ins_next1 + | b <2 + |. sdc1 f0, FORL_EXT*8(RA) + } + |.else + if (!vk) { + | sltiu TMP0, SFARG1HI, LJ_TISNUM + | sltiu TMP1, SFARG2HI, LJ_TISNUM + | sltiu AT, SFRETHI, LJ_TISNUM + | and TMP0, TMP0, TMP1 + | and AT, AT, TMP0 + | beqz AT, ->vmeta_for + |. nop + | bal ->vm_sfcmpolex + |. move TMP3, SFRETHI + | b <1 |. nop } else { - | addu TMP1, RD, TMP0 - | slt TMP3, TMP3, r0 - | move TMP2, TMP1 - if (op == BC_FORI) { - | movt TMP1, r0, 0 - | movt TMP2, r0, 1 + | lw SFARG2HI, FORL_STEP*8+HI(RA) + | load_got __adddf3 + | call_extern + |. sw TMP2, ARG5 + | lw SFARG2HI, FORL_STOP*8+HI(RA) + | lw SFARG2LO, FORL_STOP*8+LO(RA) + | move SFARG1HI, SFRETHI + | move SFARG1LO, SFRETLO + | bal ->vm_sfcmpolex + |. lw TMP3, FORL_STEP*8+HI(RA) + if ( op == BC_JFORL ) { + | lhu RD, -4+OFS_RD(PC) + | lw TMP2, ARG5 + | b <1 + |. decode_RD8b RD } else { - | movf TMP1, r0, 0 - | movf TMP2, r0, 1 + | b <1 + |. lw TMP2, ARG5 } - | movn TMP1, TMP2, TMP3 - | addu PC, PC, TMP1 } - | ins_next + |.endif break; case BC_ITERL: @@ -4260,8 +5160,10 @@ static void emit_asm_debug(BuildCtx *ctx) fcofs, CFRAME_SIZE); for (i = 23; i >= 16; i--) fprintf(ctx->fp, "\t.byte %d\n\t.uleb128 %d\n", 0x80+i, 26-i); +#if !LJ_SOFTFP for (i = 30; i >= 20; i -= 2) fprintf(ctx->fp, "\t.byte %d\n\t.uleb128 %d\n", 0x80+32+i, 42-i); +#endif fprintf(ctx->fp, "\t.align 2\n" ".LEFDE0:\n\n"); @@ -4279,6 +5181,7 @@ static void emit_asm_debug(BuildCtx *ctx) "\t.align 2\n" ".LEFDE1:\n\n", (int)ctx->codesz - fcofs); #endif +#if !LJ_NO_UNWIND fprintf(ctx->fp, "\t.section .eh_frame,\"aw\",@progbits\n"); fprintf(ctx->fp, "\t.globl lj_err_unwind_dwarf\n" @@ -4312,8 +5215,10 @@ static void emit_asm_debug(BuildCtx *ctx) fcofs, CFRAME_SIZE); for (i = 23; i >= 16; i--) fprintf(ctx->fp, "\t.byte %d\n\t.uleb128 %d\n", 0x80+i, 26-i); +#if !LJ_SOFTFP for (i = 30; i >= 20; i -= 2) fprintf(ctx->fp, "\t.byte %d\n\t.uleb128 %d\n", 0x80+32+i, 42-i); +#endif fprintf(ctx->fp, "\t.align 2\n" ".LEFDE2:\n\n"); @@ -4347,6 +5252,7 @@ static void emit_asm_debug(BuildCtx *ctx) "\t.align 2\n" ".LEFDE3:\n\n", (int)ctx->codesz - fcofs); #endif +#endif break; default: break; diff --git a/Build/source/libs/luajit/LuaJIT-src/src/vm_ppc.dasc b/Build/source/libs/luajit/LuaJIT-src/src/vm_ppc.dasc index 9299c554e2b..be4356e7480 100644 --- a/Build/source/libs/luajit/LuaJIT-src/src/vm_ppc.dasc +++ b/Build/source/libs/luajit/LuaJIT-src/src/vm_ppc.dasc @@ -1,6 +1,6 @@ |// Low-level VM code for PowerPC 32 bit or 32on64 bit mode. |// Bytecode interpreter, fast functions and helper functions. -|// Copyright (C) 2005-2015 Mike Pall. See Copyright Notice in luajit.h +|// Copyright (C) 2005-2016 Mike Pall. See Copyright Notice in luajit.h | |.arch ppc |.section code_op, code_sub @@ -2525,7 +2525,7 @@ static void build_subroutines(BuildCtx *ctx) |.if JIT | // RA = resultptr, RB = meta base | lwz INS, -4(PC) - | lwz TMP3, -20(RB) // Save previous trace number. + | lwz TRACE:TMP2, -20(RB) // Save previous trace. | addic. TMP1, MULTRES, -8 | decode_RA8 RC, INS // Call base. | beq >2 @@ -2540,15 +2540,11 @@ static void build_subroutines(BuildCtx *ctx) | decode_RA8 RA, INS | decode_RB8 RB, INS | add RA, RA, RB - | lwz TMP1, DISPATCH_J(trace)(DISPATCH) |3: | cmplw RA, RC | bgt >9 // More results wanted? | - | slwi TMP2, TMP3, 2 - | lwzx TRACE:TMP2, TMP1, TMP2 - | cmpwi TRACE:TMP2, 0 - | beq ->cont_nop + | lhz TMP3, TRACE:TMP2->traceno | lhz RD, TRACE:TMP2->link | cmpw RD, TMP3 | cmpwi cr1, RD, 0 diff --git a/Build/source/libs/luajit/LuaJIT-src/src/vm_x64.dasc b/Build/source/libs/luajit/LuaJIT-src/src/vm_x64.dasc index e7e990ae27f..a6b6853e1e9 100644 --- a/Build/source/libs/luajit/LuaJIT-src/src/vm_x64.dasc +++ b/Build/source/libs/luajit/LuaJIT-src/src/vm_x64.dasc @@ -1,6 +1,6 @@ |// Low-level VM code for x64 CPUs in LJ_GC64 mode. |// Bytecode interpreter, fast functions and helper functions. -|// Copyright (C) 2005-2015 Mike Pall. See Copyright Notice in luajit.h +|// Copyright (C) 2005-2016 Mike Pall. See Copyright Notice in luajit.h | |.arch x64 |.section code_op, code_sub @@ -531,7 +531,7 @@ static void build_subroutines(BuildCtx *ctx) | jmp >2 | |->vm_growstack_v: // Grow stack for vararg Lua function. - | sub RD, 8 + | sub RD, 16 // LJ_FR2 | jmp >1 | |->vm_growstack_f: // Grow stack for fixarg Lua function. @@ -1804,7 +1804,11 @@ static void build_subroutines(BuildCtx *ctx) | jmp ->fff_res1 | |.ffunc_n math_frexp + |.if X64WIN + | lea CARG2, TMP1 + |.else | lea CARG1, TMP1 + |.endif | mov RB, BASE | call extern frexp | mov BASE, RB @@ -1822,7 +1826,11 @@ static void build_subroutines(BuildCtx *ctx) | jmp ->fff_res | |.ffunc_n math_modf + |.if X64WIN + | lea CARG2, [BASE-16] + |.else | lea CARG1, [BASE-16] + |.endif | mov PC, [BASE-8] | mov RB, BASE | call extern modf diff --git a/Build/source/libs/luajit/LuaJIT-src/src/vm_x86.dasc b/Build/source/libs/luajit/LuaJIT-src/src/vm_x86.dasc index f31e595b3f4..fcef660c420 100644 --- a/Build/source/libs/luajit/LuaJIT-src/src/vm_x86.dasc +++ b/Build/source/libs/luajit/LuaJIT-src/src/vm_x86.dasc @@ -1,6 +1,6 @@ |// Low-level VM code for x86 CPUs. |// Bytecode interpreter, fast functions and helper functions. -|// Copyright (C) 2005-2015 Mike Pall. See Copyright Notice in luajit.h +|// Copyright (C) 2005-2016 Mike Pall. See Copyright Notice in luajit.h | |.if P64 |.arch x64 @@ -2667,8 +2667,8 @@ static void build_subroutines(BuildCtx *ctx) |->cont_stitch: // Trace stitching. |.if JIT | // BASE = base, RC = result, RB = mbase - | mov RA, [RB-24] // Save previous trace number. - | mov TMP1, RA + | mov TRACE:RA, [RB-24] // Save previous trace. + | mov TMP1, TRACE:RA | mov TMP3, DISPATCH // Need one more register. | mov DISPATCH, MULTRES | movzx RA, PC_RA @@ -2699,11 +2699,8 @@ static void build_subroutines(BuildCtx *ctx) | ja >9 // More results wanted? | | mov DISPATCH, TMP3 - | mov RB, TMP1 // Get previous trace number. - | mov RA, [DISPATCH+DISPATCH_J(trace)] - | mov TRACE:RD, [RA+RB*4] - | test TRACE:RD, TRACE:RD - | jz ->cont_nop + | mov TRACE:RD, TMP1 // Get previous trace. + | movzx RB, word TRACE:RD->traceno | movzx RD, word TRACE:RD->link | cmp RD, RB | je ->cont_nop // Blacklisted. |