diff --git a/.gitmodules b/.gitmodules
new file mode 100644
index 0000000..5294912
--- /dev/null
+++ b/.gitmodules
@@ -0,0 +1,3 @@
+[submodule "3rd/kcp"]
+ path = 3rd/kcp
+ url = https://github.com/skywind3000/kcp
diff --git a/3rd/kcp b/3rd/kcp
new file mode 160000
index 0000000..b8100f9
--- /dev/null
+++ b/3rd/kcp
@@ -0,0 +1 @@
+Subproject commit b8100f9de986a94d5eef8ec90d1d039f09538b87
diff --git a/3rd/kcp/LICENSE b/3rd/kcp/LICENSE
deleted file mode 100644
index d6a9326..0000000
--- a/3rd/kcp/LICENSE
+++ /dev/null
@@ -1,340 +0,0 @@
-GNU GENERAL PUBLIC LICENSE
- Version 2, June 1991
-
- Copyright (C) 1989, 1991 Free Software Foundation, Inc.,
- 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
- Everyone is permitted to copy and distribute verbatim copies
- of this license document, but changing it is not allowed.
-
- Preamble
-
- The licenses for most software are designed to take away your
-freedom to share and change it. By contrast, the GNU General Public
-License is intended to guarantee your freedom to share and change free
-software--to make sure the software is free for all its users. This
-General Public License applies to most of the Free Software
-Foundation's software and to any other program whose authors commit to
-using it. (Some other Free Software Foundation software is covered by
-the GNU Lesser General Public License instead.) You can apply it to
-your programs, too.
-
- When we speak of free software, we are referring to freedom, not
-price. Our General Public Licenses are designed to make sure that you
-have the freedom to distribute copies of free software (and charge for
-this service if you wish), that you receive source code or can get it
-if you want it, that you can change the software or use pieces of it
-in new free programs; and that you know you can do these things.
-
- To protect your rights, we need to make restrictions that forbid
-anyone to deny you these rights or to ask you to surrender the rights.
-These restrictions translate to certain responsibilities for you if you
-distribute copies of the software, or if you modify it.
-
- For example, if you distribute copies of such a program, whether
-gratis or for a fee, you must give the recipients all the rights that
-you have. You must make sure that they, too, receive or can get the
-source code. And you must show them these terms so they know their
-rights.
-
- We protect your rights with two steps: (1) copyright the software, and
-(2) offer you this license which gives you legal permission to copy,
-distribute and/or modify the software.
-
- Also, for each author's protection and ours, we want to make certain
-that everyone understands that there is no warranty for this free
-software. If the software is modified by someone else and passed on, we
-want its recipients to know that what they have is not the original, so
-that any problems introduced by others will not reflect on the original
-authors' reputations.
-
- Finally, any free program is threatened constantly by software
-patents. We wish to avoid the danger that redistributors of a free
-program will individually obtain patent licenses, in effect making the
-program proprietary. To prevent this, we have made it clear that any
-patent must be licensed for everyone's free use or not licensed at all.
-
- The precise terms and conditions for copying, distribution and
-modification follow.
-
- GNU GENERAL PUBLIC LICENSE
- TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
-
- 0. This License applies to any program or other work which contains
-a notice placed by the copyright holder saying it may be distributed
-under the terms of this General Public License. The "Program", below,
-refers to any such program or work, and a "work based on the Program"
-means either the Program or any derivative work under copyright law:
-that is to say, a work containing the Program or a portion of it,
-either verbatim or with modifications and/or translated into another
-language. (Hereinafter, translation is included without limitation in
-the term "modification".) Each licensee is addressed as "you".
-
-Activities other than copying, distribution and modification are not
-covered by this License; they are outside its scope. The act of
-running the Program is not restricted, and the output from the Program
-is covered only if its contents constitute a work based on the
-Program (independent of having been made by running the Program).
-Whether that is true depends on what the Program does.
-
- 1. You may copy and distribute verbatim copies of the Program's
-source code as you receive it, in any medium, provided that you
-conspicuously and appropriately publish on each copy an appropriate
-copyright notice and disclaimer of warranty; keep intact all the
-notices that refer to this License and to the absence of any warranty;
-and give any other recipients of the Program a copy of this License
-along with the Program.
-
-You may charge a fee for the physical act of transferring a copy, and
-you may at your option offer warranty protection in exchange for a fee.
-
- 2. You may modify your copy or copies of the Program or any portion
-of it, thus forming a work based on the Program, and copy and
-distribute such modifications or work under the terms of Section 1
-above, provided that you also meet all of these conditions:
-
- a) You must cause the modified files to carry prominent notices
- stating that you changed the files and the date of any change.
-
- b) You must cause any work that you distribute or publish, that in
- whole or in part contains or is derived from the Program or any
- part thereof, to be licensed as a whole at no charge to all third
- parties under the terms of this License.
-
- c) If the modified program normally reads commands interactively
- when run, you must cause it, when started running for such
- interactive use in the most ordinary way, to print or display an
- announcement including an appropriate copyright notice and a
- notice that there is no warranty (or else, saying that you provide
- a warranty) and that users may redistribute the program under
- these conditions, and telling the user how to view a copy of this
- License. (Exception: if the Program itself is interactive but
- does not normally print such an announcement, your work based on
- the Program is not required to print an announcement.)
-
-These requirements apply to the modified work as a whole. If
-identifiable sections of that work are not derived from the Program,
-and can be reasonably considered independent and separate works in
-themselves, then this License, and its terms, do not apply to those
-sections when you distribute them as separate works. But when you
-distribute the same sections as part of a whole which is a work based
-on the Program, the distribution of the whole must be on the terms of
-this License, whose permissions for other licensees extend to the
-entire whole, and thus to each and every part regardless of who wrote it.
-
-Thus, it is not the intent of this section to claim rights or contest
-your rights to work written entirely by you; rather, the intent is to
-exercise the right to control the distribution of derivative or
-collective works based on the Program.
-
-In addition, mere aggregation of another work not based on the Program
-with the Program (or with a work based on the Program) on a volume of
-a storage or distribution medium does not bring the other work under
-the scope of this License.
-
- 3. You may copy and distribute the Program (or a work based on it,
-under Section 2) in object code or executable form under the terms of
-Sections 1 and 2 above provided that you also do one of the following:
-
- a) Accompany it with the complete corresponding machine-readable
- source code, which must be distributed under the terms of Sections
- 1 and 2 above on a medium customarily used for software interchange; or,
-
- b) Accompany it with a written offer, valid for at least three
- years, to give any third party, for a charge no more than your
- cost of physically performing source distribution, a complete
- machine-readable copy of the corresponding source code, to be
- distributed under the terms of Sections 1 and 2 above on a medium
- customarily used for software interchange; or,
-
- c) Accompany it with the information you received as to the offer
- to distribute corresponding source code. (This alternative is
- allowed only for noncommercial distribution and only if you
- received the program in object code or executable form with such
- an offer, in accord with Subsection b above.)
-
-The source code for a work means the preferred form of the work for
-making modifications to it. For an executable work, complete source
-code means all the source code for all modules it contains, plus any
-associated interface definition files, plus the scripts used to
-control compilation and installation of the executable. However, as a
-special exception, the source code distributed need not include
-anything that is normally distributed (in either source or binary
-form) with the major components (compiler, kernel, and so on) of the
-operating system on which the executable runs, unless that component
-itself accompanies the executable.
-
-If distribution of executable or object code is made by offering
-access to copy from a designated place, then offering equivalent
-access to copy the source code from the same place counts as
-distribution of the source code, even though third parties are not
-compelled to copy the source along with the object code.
-
- 4. You may not copy, modify, sublicense, or distribute the Program
-except as expressly provided under this License. Any attempt
-otherwise to copy, modify, sublicense or distribute the Program is
-void, and will automatically terminate your rights under this License.
-However, parties who have received copies, or rights, from you under
-this License will not have their licenses terminated so long as such
-parties remain in full compliance.
-
- 5. You are not required to accept this License, since you have not
-signed it. However, nothing else grants you permission to modify or
-distribute the Program or its derivative works. These actions are
-prohibited by law if you do not accept this License. Therefore, by
-modifying or distributing the Program (or any work based on the
-Program), you indicate your acceptance of this License to do so, and
-all its terms and conditions for copying, distributing or modifying
-the Program or works based on it.
-
- 6. Each time you redistribute the Program (or any work based on the
-Program), the recipient automatically receives a license from the
-original licensor to copy, distribute or modify the Program subject to
-these terms and conditions. You may not impose any further
-restrictions on the recipients' exercise of the rights granted herein.
-You are not responsible for enforcing compliance by third parties to
-this License.
-
- 7. If, as a consequence of a court judgment or allegation of patent
-infringement or for any other reason (not limited to patent issues),
-conditions are imposed on you (whether by court order, agreement or
-otherwise) that contradict the conditions of this License, they do not
-excuse you from the conditions of this License. If you cannot
-distribute so as to satisfy simultaneously your obligations under this
-License and any other pertinent obligations, then as a consequence you
-may not distribute the Program at all. For example, if a patent
-license would not permit royalty-free redistribution of the Program by
-all those who receive copies directly or indirectly through you, then
-the only way you could satisfy both it and this License would be to
-refrain entirely from distribution of the Program.
-
-If any portion of this section is held invalid or unenforceable under
-any particular circumstance, the balance of the section is intended to
-apply and the section as a whole is intended to apply in other
-circumstances.
-
-It is not the purpose of this section to induce you to infringe any
-patents or other property right claims or to contest validity of any
-such claims; this section has the sole purpose of protecting the
-integrity of the free software distribution system, which is
-implemented by public license practices. Many people have made
-generous contributions to the wide range of software distributed
-through that system in reliance on consistent application of that
-system; it is up to the author/donor to decide if he or she is willing
-to distribute software through any other system and a licensee cannot
-impose that choice.
-
-This section is intended to make thoroughly clear what is believed to
-be a consequence of the rest of this License.
-
- 8. If the distribution and/or use of the Program is restricted in
-certain countries either by patents or by copyrighted interfaces, the
-original copyright holder who places the Program under this License
-may add an explicit geographical distribution limitation excluding
-those countries, so that distribution is permitted only in or among
-countries not thus excluded. In such case, this License incorporates
-the limitation as if written in the body of this License.
-
- 9. The Free Software Foundation may publish revised and/or new versions
-of the General Public License from time to time. Such new versions will
-be similar in spirit to the present version, but may differ in detail to
-address new problems or concerns.
-
-Each version is given a distinguishing version number. If the Program
-specifies a version number of this License which applies to it and "any
-later version", you have the option of following the terms and conditions
-either of that version or of any later version published by the Free
-Software Foundation. If the Program does not specify a version number of
-this License, you may choose any version ever published by the Free Software
-Foundation.
-
- 10. If you wish to incorporate parts of the Program into other free
-programs whose distribution conditions are different, write to the author
-to ask for permission. For software which is copyrighted by the Free
-Software Foundation, write to the Free Software Foundation; we sometimes
-make exceptions for this. Our decision will be guided by the two goals
-of preserving the free status of all derivatives of our free software and
-of promoting the sharing and reuse of software generally.
-
- NO WARRANTY
-
- 11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY
-FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN
-OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES
-PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED
-OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
-MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS
-TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE
-PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING,
-REPAIR OR CORRECTION.
-
- 12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
-WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR
-REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES,
-INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING
-OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED
-TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY
-YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER
-PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE
-POSSIBILITY OF SUCH DAMAGES.
-
- END OF TERMS AND CONDITIONS
-
- How to Apply These Terms to Your New Programs
-
- If you develop a new program, and you want it to be of the greatest
-possible use to the public, the best way to achieve this is to make it
-free software which everyone can redistribute and change under these terms.
-
- To do so, attach the following notices to the program. It is safest
-to attach them to the start of each source file to most effectively
-convey the exclusion of warranty; and each file should have at least
-the "copyright" line and a pointer to where the full notice is found.
-
- {description}
- Copyright (C) {year} {fullname}
-
- This program is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation; either version 2 of the License, or
- (at your option) any later version.
-
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License along
- with this program; if not, write to the Free Software Foundation, Inc.,
- 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
-
-Also add information on how to contact you by electronic and paper mail.
-
-If the program is interactive, make it output a short notice like this
-when it starts in an interactive mode:
-
- Gnomovision version 69, Copyright (C) year name of author
- Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
- This is free software, and you are welcome to redistribute it
- under certain conditions; type `show c' for details.
-
-The hypothetical commands `show w' and `show c' should show the appropriate
-parts of the General Public License. Of course, the commands you use may
-be called something other than `show w' and `show c'; they could even be
-mouse-clicks or menu items--whatever suits your program.
-
-You should also get your employer (if you work as a programmer) or your
-school, if any, to sign a "copyright disclaimer" for the program, if
-necessary. Here is a sample; alter the names:
-
- Yoyodyne, Inc., hereby disclaims all copyright interest in the program
- `Gnomovision' (which makes passes at compilers) written by James Hacker.
-
- {signature of Ty Coon}, 1 April 1989
- Ty Coon, President of Vice
-
-This General Public License does not permit incorporating your program into
-proprietary programs. If your program is a subroutine library, you may
-consider it more useful to permit linking proprietary applications with the
-library. If this is what you want to do, use the GNU Lesser General
-Public License instead of this License.
-
diff --git a/3rd/kcp/README.md b/3rd/kcp/README.md
deleted file mode 100644
index 9a4ce84..0000000
--- a/3rd/kcp/README.md
+++ /dev/null
@@ -1,187 +0,0 @@
-KCP - A Fast and Reliable ARQ Protocol
-======================================
-
-# 简介
-
-KCP是一个快速可靠协议,能以比 TCP浪费10%-20%的带宽的代价,换取平均延迟降低
-30%-40%,且最大延迟降低三倍的传输效果。纯算法实现,并不负责底层协议(如UDP)
-的收发,需要使用者自己定义下层数据包的发送方式,以 callback的方式提供给 KCP。
-连时钟都需要外部传递进来,内部不会有任何一次系统调用。
-
-整个协议只有 ikcp.h, ikcp.c两个源文件,可以方便的集成到用户自己的协议栈中。
-也许你实现了一个P2P,或者某个基于 UDP的协议,而缺乏一套完善的ARQ可靠协议实现,
-那么简单的拷贝这两个文件到现有项目中,稍微编写两行代码,即可使用。
-
-
-# 技术特性
-
-TCP是为流量设计的(每秒内可以传输多少KB的数据),讲究的是充分利用带宽。而KCP
-是为流速设计的(单个数据包从一端发送到一端需要多少时间),以10%-20%带宽浪费
-的代价换取了比 TCP快30%-40%的传输速度。TCP信道是一条流速很慢,但每秒流量很大
-的大运河,而KCP是水流湍急的小激流。KCP有正常模式和快速模式两种,通过以下策略
-达到提高流速的结果:
-
-#### RTO翻倍vs不翻倍:
-
- TCP超时计算是RTOx2,这样连续丢三次包就变成RTOx8了,十分恐怖,而KCP启动快速
- 模式后不x2,只是x1.5(实验证明1.5这个值相对比较好),提高了传输速度。
-
-#### 选择性重传 vs 全部重传:
-
- TCP丢包时会全部重传从丢的那个包开始以后的数据,KCP是选择性重传,只重传真正
- 丢失的数据包。
-
-#### 快速重传:
-
- 发送端发送了1,2,3,4,5几个包,然后收到远端的ACK: 1, 3, 4, 5,当收到ACK3时,
- KCP知道2被跳过1次,收到ACK4时,知道2被跳过了2次,此时可以认为2号丢失,不用
- 等超时,直接重传2号包,大大改善了丢包时的传输速度。
-
-#### 延迟ACK vs 非延迟ACK:
-
- TCP为了充分利用带宽,延迟发送ACK(NODELAY都没用),这样超时计算会算出较大
- RTT时间,延长了丢包时的判断过程。KCP的ACK是否延迟发送可以调节。
-
-#### UNA vs ACK+UNA:
-
- ARQ模型响应有两种,UNA(此编号前所有包已收到,如TCP)和ACK(该编号包已收到
- ),光用UNA将导致全部重传,光用ACK则丢失成本太高,以往协议都是二选其一,而
- KCP协议中,除去单独的 ACK包外,所有包都有UNA信息。
-
-#### 非退让流控:
-
- KCP正常模式同TCP一样使用公平退让法则,即发送窗口大小由:发送缓存大小、接收
- 端剩余接收缓存大小、丢包退让及慢启动这四要素决定。但传送及时性要求很高的小
- 数据时,可选择通过配置跳过后两步,仅用前两项来控制发送频率。以牺牲部分公平
- 性及带宽利用率之代价,换取了开着BT都能流畅传输的效果。
-
-
-# 基本使用
-
-1. 创建 KCP对象:
-
- ```cpp
- // 初始化 kcp对象,conv为一个表示会话编号的整数,和tcp的 conv一样,通信双
- // 方需保证 conv相同,相互的数据包才能够被认可,user是一个给回调函数的指针
- ikcpcb *kcp = ikcp_create(conv, user);
- ```
-
-2. 设置回调函数:
-
- ```cpp
- // KCP的下层协议输出函数,KCP需要发送数据时会调用它
- // buf/len 表示缓存和长度
- // user指针为 kcp对象创建时传入的值,用于区别多个 KCP对象
- int udp_output(const char *buf, int len, ikcpcb *kcp, void *user)
- {
- ....
- }
- // 设置回调函数
- kcp->output = udp_output;
- ```
-
-3. 循环调用 update:
-
- ```cpp
- // 以一定频率调用 ikcp_update来更新 kcp状态,并且传入当前时钟(毫秒单位)
- // 如 10ms调用一次,或用 ikcp_check确定下次调用 update的时间不必每次调用
- ikcp_update(kcp, millisec);
- ```
-
-4. 输入一个下层数据包:
-
- ```cpp
- // 收到一个下层数据包(比如UDP包)时需要调用:
- ikcp_input(kcp, received_udp_packet, received_udp_size);
- ```
- 处理了下层协议的输出/输入后 KCP协议就可以正常工作了,使用 ikcp_send 来向
- 远端发送数据。而另一端使用 ikcp_recv(kcp, ptr, size)来接收数据。
-
-
-# 协议配置
-
-协议默认模式是一个标准的 ARQ,需要通过配置打开各项加速开关:
-
-1. 工作模式:
- ```cpp
- int ikcp_nodelay(ikcpcb *kcp, int nodelay, int interval, int resend, int nc)
- ```
-
- > nodelay :是否启用 nodelay模式,0不启用;1启用。
- > interval :协议内部工作的 interval,单位毫秒,比如 10ms或者 20ms
- > resend :快速重传模式,默认0关闭,可以设置2(2次ACK跨越将会直接重传)
- > nc :是否关闭流控,默认是0代表不关闭,1代表关闭。
- > 普通模式:`ikcp_nodelay(kcp, 0, 40, 0, 0);
- > 极速模式: ikcp_nodelay(kcp, 1, 10, 2, 1);
-
-2. 最大窗口:
- ```cpp
- int ikcp_wndsize(ikcpcb *kcp, int sndwnd, int rcvwnd);
- ```
- 该调用将会设置协议的最大发送窗口和最大接收窗口大小,默认为32.
-
-3. 最大传输单元:
-
- 纯算法协议并不负责探测 MTU,默认 mtu是1400字节,可以使用ikcp_setmtu来设置
- 该值。该值将会影响数据包归并及分片时候的最大传输单元。
-
-4. 最小RTO:
-
- 不管是 TCP还是 KCP计算 RTO时都有最小 RTO的限制,即便计算出来RTO为40ms,由
- 于默认的 RTO是100ms,协议只有在100ms后才能检测到丢包,快速模式下为30ms,可
- 以手动更改该值:
- ```cpp
- kcp->rx_minrto = 10;
- ```
-
-# 最佳实践
-#### 内存分配器
-
- 默认KCP协议使用 malloc/free进行内存分配释放,如果应用层接管了内存分配,可以
- 用ikcp_allocator来设置新的内存分配器,注意要在一开始设置:
-
- > ikcp_allocator(my_new_malloc, my_new_free);
-
-
-#### 前向纠错注意
-
-为了进一步提高传输速度,下层协议也许会使用前向纠错技术。需要注意,前向纠错会根
-据冗余信息解出原始数据包。相同的原始数据包不要两次input到KCP,否则将会导致kcp
-以为对方重发了,这样会产生更多的ack占用额外带宽。
-
-比如下层协议使用最简单的冗余包:单个数据包除了自己外,还会重复存储一次上一个数
-据包,以及上上一个数据包的内容:
-
-```cpp
-Fn = (Pn, Pn-1, Pn-2)
-
-P0 = (0, X, X)
-P1 = (1, 0, X)
-P2 = (2, 1, 0)
-P3 = (3, 2, 1)
-```
-
-这样几个包发送出去,接收方对于单个原始包都可能被解出3次来(后面两个包任然会重
-复该包内容),那么这里需要记录一下,一个下层数据包只会input给kcp一次,避免过
-多重复ack带来的浪费。
-
-#### 管理大规模连接
-
-如果需要同时管理大规模的 KCP连接(比如大于3000个),比如你正在实现一套类 epoll
-的机制,那么为了避免每秒钟对每个连接调用大量的调用 ikcp_update,我们可以使用
-ikcp_check来大大减少 ikcp_update调用的次数。 ikcp_check返回值会告诉你需要
-在什么时间点再次调用 ikcp_update(如果中途没有 ikcp_send, ikcp_input的话,
-否则中途调用了 ikcp_send, ikcp_input的话,需要在下一次interval时调用 update)
-
-标准顺序是每次调用了 ikcp_update后,使用 ikcp_check决定下次什么时间点再次调用
-ikcp_update,而如果中途发生了 ikcp_send, ikcp_input的话,在下一轮 interval
-立马调用 ikcp_update和 ikcp_check。 使用该方法,原来在处理2000个 kcp连接且每
-个连接每10ms调用一次update,改为 check机制后,cpu从 60%降低到 15%。
-
-
-# 欢迎捐赠
-
-
-
-欢迎使用支付宝手扫描上面的二维码,对该项目进行捐赠。捐赠款项将用于改进 KCP性能以及
-后续持续优化。
diff --git a/3rd/kcp/donation.png b/3rd/kcp/donation.png
deleted file mode 100644
index 2324ca2..0000000
Binary files a/3rd/kcp/donation.png and /dev/null differ
diff --git a/3rd/kcp/ikcp.c b/3rd/kcp/ikcp.c
deleted file mode 100644
index 4ec38b0..0000000
--- a/3rd/kcp/ikcp.c
+++ /dev/null
@@ -1,1193 +0,0 @@
-//=====================================================================
-//
-// KCP - A Better ARQ Protocol Implementation
-// skywind3000 (at) gmail.com, 2010-2011
-//
-// Features:
-// + Average RTT reduce 30% - 40% vs traditional ARQ like tcp.
-// + Maximum RTT reduce three times vs tcp.
-// + Lightweight, distributed as a single source file.
-//
-//=====================================================================
-#include "ikcp.h"
-
-#include
-#include
-#include
-#include
-
-
-
-//=====================================================================
-// KCP BASIC
-//=====================================================================
-const IUINT32 IKCP_RTO_NDL = 30; // no delay min rto
-const IUINT32 IKCP_RTO_MIN = 100; // normal min rto
-const IUINT32 IKCP_RTO_DEF = 200;
-const IUINT32 IKCP_RTO_MAX = 60000;
-const IUINT32 IKCP_CMD_PUSH = 81; // cmd: push data
-const IUINT32 IKCP_CMD_ACK = 82; // cmd: ack
-const IUINT32 IKCP_CMD_WASK = 83; // cmd: window probe (ask)
-const IUINT32 IKCP_CMD_WINS = 84; // cmd: window size (tell)
-const IUINT32 IKCP_ASK_SEND = 1; // need to send IKCP_CMD_WASK
-const IUINT32 IKCP_ASK_TELL = 2; // need to send IKCP_CMD_WINS
-const IUINT32 IKCP_WND_SND = 32;
-const IUINT32 IKCP_WND_RCV = 32;
-const IUINT32 IKCP_MTU_DEF = 1400;
-const IUINT32 IKCP_ACK_FAST = 3;
-const IUINT32 IKCP_INTERVAL = 100;
-const IUINT32 IKCP_OVERHEAD = 24;
-const IUINT32 IKCP_DEADLINK = 10;
-const IUINT32 IKCP_THRESH_INIT = 2;
-const IUINT32 IKCP_THRESH_MIN = 2;
-const IUINT32 IKCP_PROBE_INIT = 7000; // 7 secs to probe window size
-const IUINT32 IKCP_PROBE_LIMIT = 120000; // up to 120 secs to probe window
-
-
-//---------------------------------------------------------------------
-// encode / decode
-//---------------------------------------------------------------------
-
-/* encode 8 bits unsigned int */
-static inline char *ikcp_encode8u(char *p, unsigned char c)
-{
- *(unsigned char*)p++ = c;
- return p;
-}
-
-/* decode 8 bits unsigned int */
-static inline const char *ikcp_decode8u(const char *p, unsigned char *c)
-{
- *c = *(unsigned char*)p++;
- return p;
-}
-
-/* encode 16 bits unsigned int (lsb) */
-static inline char *ikcp_encode16u(char *p, unsigned short w)
-{
-#if IWORDS_BIG_ENDIAN
- *(unsigned char*)(p + 0) = (w & 255);
- *(unsigned char*)(p + 1) = (w >> 8);
-#else
- *(unsigned short*)(p) = w;
-#endif
- p += 2;
- return p;
-}
-
-/* decode 16 bits unsigned int (lsb) */
-static inline const char *ikcp_decode16u(const char *p, unsigned short *w)
-{
-#if IWORDS_BIG_ENDIAN
- *w = *(const unsigned char*)(p + 1);
- *w = *(const unsigned char*)(p + 0) + (*w << 8);
-#else
- *w = *(const unsigned short*)p;
-#endif
- p += 2;
- return p;
-}
-
-/* encode 32 bits unsigned int (lsb) */
-static inline char *ikcp_encode32u(char *p, IUINT32 l)
-{
-#if IWORDS_BIG_ENDIAN
- *(unsigned char*)(p + 0) = (unsigned char)((l >> 0) & 0xff);
- *(unsigned char*)(p + 1) = (unsigned char)((l >> 8) & 0xff);
- *(unsigned char*)(p + 2) = (unsigned char)((l >> 16) & 0xff);
- *(unsigned char*)(p + 3) = (unsigned char)((l >> 24) & 0xff);
-#else
- *(IUINT32*)p = l;
-#endif
- p += 4;
- return p;
-}
-
-/* decode 32 bits unsigned int (lsb) */
-static inline const char *ikcp_decode32u(const char *p, IUINT32 *l)
-{
-#if IWORDS_BIG_ENDIAN
- *l = *(const unsigned char*)(p + 3);
- *l = *(const unsigned char*)(p + 2) + (*l << 8);
- *l = *(const unsigned char*)(p + 1) + (*l << 8);
- *l = *(const unsigned char*)(p + 0) + (*l << 8);
-#else
- *l = *(const IUINT32*)p;
-#endif
- p += 4;
- return p;
-}
-
-static inline IUINT32 _imin_(IUINT32 a, IUINT32 b) {
- return a <= b ? a : b;
-}
-
-static inline IUINT32 _imax_(IUINT32 a, IUINT32 b) {
- return a >= b ? a : b;
-}
-
-static inline IUINT32 _ibound_(IUINT32 lower, IUINT32 middle, IUINT32 upper)
-{
- return _imin_(_imax_(lower, middle), upper);
-}
-
-static inline long _itimediff(IUINT32 later, IUINT32 earlier)
-{
- return ((IINT32)(later - earlier));
-}
-
-//---------------------------------------------------------------------
-// manage segment
-//---------------------------------------------------------------------
-typedef struct IKCPSEG IKCPSEG;
-
-static void* (*ikcp_malloc_hook)(size_t) = NULL;
-static void (*ikcp_free_hook)(void *) = NULL;
-
-// internal malloc
-static void* ikcp_malloc(size_t size) {
- if (ikcp_malloc_hook)
- return ikcp_malloc_hook(size);
- return malloc(size);
-}
-
-// internal free
-static void ikcp_free(void *ptr) {
- if (ikcp_free_hook) {
- ikcp_free_hook(ptr);
- } else {
- free(ptr);
- }
-}
-
-// redefine allocator
-void ikcp_allocator(void* (*new_malloc)(size_t), void (*new_free)(void*))
-{
- ikcp_malloc_hook = new_malloc;
- ikcp_free_hook = new_free;
-}
-
-// allocate a new kcp segment
-static IKCPSEG* ikcp_segment_new(ikcpcb *kcp, int size)
-{
- return (IKCPSEG*)ikcp_malloc(sizeof(IKCPSEG) + size);
-}
-
-// delete a segment
-static void ikcp_segment_delete(ikcpcb *kcp, IKCPSEG *seg)
-{
- ikcp_free(seg);
-}
-
-// write log
-void ikcp_log(ikcpcb *kcp, int mask, const char *fmt, ...)
-{
- char buffer[1024];
- va_list argptr;
- if ((mask & kcp->logmask) == 0 || kcp->writelog == 0) return;
- va_start(argptr, fmt);
- vsprintf(buffer, fmt, argptr);
- va_end(argptr);
- kcp->writelog(buffer, kcp, kcp->user);
-}
-
-// check log mask
-static int ikcp_canlog(const ikcpcb *kcp, int mask)
-{
- if ((mask & kcp->logmask) == 0 || kcp->writelog == NULL) return 0;
- return 1;
-}
-
-// output segment
-static int ikcp_output(ikcpcb *kcp, const void *data, int size)
-{
- assert(kcp);
- assert(kcp->output);
- if (ikcp_canlog(kcp, IKCP_LOG_OUTPUT)) {
- ikcp_log(kcp, IKCP_LOG_OUTPUT, "[RO] %ld bytes", (long)size);
- }
- if (size == 0) return 0;
- return kcp->output((const char*)data, size, kcp, kcp->user);
-}
-
-// output queue
-void ikcp_qprint(const char *name, const struct IQUEUEHEAD *head)
-{
-#if 0
- const struct IQUEUEHEAD *p;
- printf("<%s>: [", name);
- for (p = head->next; p != head; p = p->next) {
- const IKCPSEG *seg = iqueue_entry(p, const IKCPSEG, node);
- printf("(%lu %d)", (unsigned long)seg->sn, (int)(seg->ts % 10000));
- if (p->next != head) printf(",");
- }
- printf("]\n");
-#endif
-}
-
-
-//---------------------------------------------------------------------
-// create a new kcpcb
-//---------------------------------------------------------------------
-ikcpcb* ikcp_create(IUINT32 conv, void *user)
-{
- ikcpcb *kcp = (ikcpcb*)ikcp_malloc(sizeof(struct IKCPCB));
- if (kcp == NULL) return NULL;
- kcp->conv = conv;
- kcp->user = user;
- kcp->snd_una = 0;
- kcp->snd_nxt = 0;
- kcp->rcv_nxt = 0;
- kcp->ts_recent = 0;
- kcp->ts_lastack = 0;
- kcp->ts_probe = 0;
- kcp->probe_wait = 0;
- kcp->snd_wnd = IKCP_WND_SND;
- kcp->rcv_wnd = IKCP_WND_RCV;
- kcp->rmt_wnd = IKCP_WND_RCV;
- kcp->cwnd = 0;
- kcp->incr = 0;
- kcp->probe = 0;
- kcp->mtu = IKCP_MTU_DEF;
- kcp->mss = kcp->mtu - IKCP_OVERHEAD;
-
- kcp->buffer = (char*)ikcp_malloc((kcp->mtu + IKCP_OVERHEAD) * 3);
- if (kcp->buffer == NULL) {
- ikcp_free(kcp);
- return NULL;
- }
-
- iqueue_init(&kcp->snd_queue);
- iqueue_init(&kcp->rcv_queue);
- iqueue_init(&kcp->snd_buf);
- iqueue_init(&kcp->rcv_buf);
- kcp->nrcv_buf = 0;
- kcp->nsnd_buf = 0;
- kcp->nrcv_que = 0;
- kcp->nsnd_que = 0;
- kcp->state = 0;
- kcp->acklist = NULL;
- kcp->ackblock = 0;
- kcp->ackcount = 0;
- kcp->rx_srtt = 0;
- kcp->rx_rttval = 0;
- kcp->rx_rto = IKCP_RTO_DEF;
- kcp->rx_minrto = IKCP_RTO_MIN;
- kcp->current = 0;
- kcp->interval = IKCP_INTERVAL;
- kcp->ts_flush = IKCP_INTERVAL;
- kcp->nodelay = 0;
- kcp->updated = 0;
- kcp->logmask = 0;
- kcp->ssthresh = IKCP_THRESH_INIT;
- kcp->fastresend = 0;
- kcp->nocwnd = 0;
- kcp->xmit = 0;
- kcp->dead_link = IKCP_DEADLINK;
- kcp->output = NULL;
- kcp->writelog = NULL;
-
- return kcp;
-}
-
-
-//---------------------------------------------------------------------
-// release a new kcpcb
-//---------------------------------------------------------------------
-void ikcp_release(ikcpcb *kcp)
-{
- assert(kcp);
- if (kcp) {
- IKCPSEG *seg;
- while (!iqueue_is_empty(&kcp->snd_buf)) {
- seg = iqueue_entry(kcp->snd_buf.next, IKCPSEG, node);
- iqueue_del(&seg->node);
- ikcp_segment_delete(kcp, seg);
- }
- while (!iqueue_is_empty(&kcp->rcv_buf)) {
- seg = iqueue_entry(kcp->rcv_buf.next, IKCPSEG, node);
- iqueue_del(&seg->node);
- ikcp_segment_delete(kcp, seg);
- }
- while (!iqueue_is_empty(&kcp->snd_queue)) {
- seg = iqueue_entry(kcp->snd_queue.next, IKCPSEG, node);
- iqueue_del(&seg->node);
- ikcp_segment_delete(kcp, seg);
- }
- while (!iqueue_is_empty(&kcp->rcv_queue)) {
- seg = iqueue_entry(kcp->rcv_queue.next, IKCPSEG, node);
- iqueue_del(&seg->node);
- ikcp_segment_delete(kcp, seg);
- }
- if (kcp->buffer) {
- ikcp_free(kcp->buffer);
- }
- if (kcp->acklist) {
- ikcp_free(kcp->acklist);
- }
-
- kcp->nrcv_buf = 0;
- kcp->nsnd_buf = 0;
- kcp->nrcv_que = 0;
- kcp->nsnd_que = 0;
- kcp->ackcount = 0;
- kcp->buffer = NULL;
- kcp->acklist = NULL;
- ikcp_free(kcp);
- }
-}
-
-
-
-//---------------------------------------------------------------------
-// user/upper level recv: returns size, returns below zero for EAGAIN
-//---------------------------------------------------------------------
-int ikcp_recv(ikcpcb *kcp, char *buffer, int len)
-{
- struct IQUEUEHEAD *p;
- int ispeek = (len < 0)? 1 : 0;
- int peeksize;
- int recover = 0;
- IKCPSEG *seg;
- assert(kcp);
-
- if (iqueue_is_empty(&kcp->rcv_queue))
- return -1;
-
- if (len < 0) len = -len;
-
- peeksize = ikcp_peeksize(kcp);
-
- if (peeksize < 0)
- return -2;
-
- if (peeksize > len)
- return -3;
-
- if (kcp->nrcv_que >= kcp->rcv_wnd)
- recover = 1;
-
- // merge fragment
- for (len = 0, p = kcp->rcv_queue.next; p != &kcp->rcv_queue; ) {
- int fragment;
- seg = iqueue_entry(p, IKCPSEG, node);
- p = p->next;
-
- if (buffer) {
- memcpy(buffer, seg->data, seg->len);
- buffer += seg->len;
- }
-
- len += seg->len;
- fragment = seg->frg;
-
- if (ikcp_canlog(kcp, IKCP_LOG_RECV)) {
- ikcp_log(kcp, IKCP_LOG_RECV, "recv sn=%lu", seg->sn);
- }
-
- if (ispeek == 0) {
- iqueue_del(&seg->node);
- ikcp_segment_delete(kcp, seg);
- kcp->nrcv_que--;
- }
-
- if (fragment == 0)
- break;
- }
-
- assert(len == peeksize);
-
- // move available data from rcv_buf -> rcv_queue
- while (! iqueue_is_empty(&kcp->rcv_buf)) {
- IKCPSEG *seg = iqueue_entry(kcp->rcv_buf.next, IKCPSEG, node);
- if (seg->sn == kcp->rcv_nxt && kcp->nrcv_que < kcp->rcv_wnd) {
- iqueue_del(&seg->node);
- kcp->nrcv_buf--;
- iqueue_add_tail(&seg->node, &kcp->rcv_queue);
- kcp->nrcv_que++;
- kcp->rcv_nxt++;
- } else {
- break;
- }
- }
-
- // fast recover
- if (kcp->nrcv_que < kcp->rcv_wnd && recover) {
- // ready to send back IKCP_CMD_WINS in ikcp_flush
- // tell remote my window size
- kcp->probe |= IKCP_ASK_TELL;
- }
-
- return len;
-}
-
-
-//---------------------------------------------------------------------
-// peek data size
-//---------------------------------------------------------------------
-int ikcp_peeksize(const ikcpcb *kcp)
-{
- struct IQUEUEHEAD *p;
- IKCPSEG *seg;
- int length = 0;
-
- assert(kcp);
-
- if (iqueue_is_empty(&kcp->rcv_queue)) return -1;
-
- seg = iqueue_entry(kcp->rcv_queue.next, IKCPSEG, node);
- if (seg->frg == 0) return seg->len;
-
- if (kcp->nrcv_que < seg->frg + 1) return -1;
-
- for (p = kcp->rcv_queue.next; p != &kcp->rcv_queue; p = p->next) {
- seg = iqueue_entry(p, IKCPSEG, node);
- length += seg->len;
- if (seg->frg == 0) break;
- }
-
- return length;
-}
-
-
-//---------------------------------------------------------------------
-// user/upper level send, returns below zero for error
-//---------------------------------------------------------------------
-int ikcp_send(ikcpcb *kcp, const char *buffer, int len)
-{
- IKCPSEG *seg;
- int count, i;
-
- assert(kcp->mss > 0);
- if (len < 0) return -1;
-
- if (len <= (int)kcp->mss) count = 1;
- else count = (len + kcp->mss - 1) / kcp->mss;
-
- if (count > 255) return -2;
-
- if (count == 0) count = 1;
-
- // fragment
- for (i = 0; i < count; i++) {
- int size = len > (int)kcp->mss ? (int)kcp->mss : len;
- seg = ikcp_segment_new(kcp, size);
- assert(seg);
- if (seg == NULL) {
- return -2;
- }
- if (buffer && len > 0) {
- memcpy(seg->data, buffer, size);
- }
- seg->len = size;
- seg->frg = count - i - 1;
- iqueue_init(&seg->node);
- iqueue_add_tail(&seg->node, &kcp->snd_queue);
- kcp->nsnd_que++;
- if (buffer) {
- buffer += size;
- }
- len -= size;
- }
-
- return 0;
-}
-
-
-//---------------------------------------------------------------------
-// parse ack
-//---------------------------------------------------------------------
-static void ikcp_update_ack(ikcpcb *kcp, IINT32 rtt)
-{
- IINT32 rto = 0;
- if (kcp->rx_srtt == 0) {
- kcp->rx_srtt = rtt;
- kcp->rx_rttval = rtt / 2;
- } else {
- long delta = rtt - kcp->rx_srtt;
- if (delta < 0) delta = -delta;
- kcp->rx_rttval = (3 * kcp->rx_rttval + delta) / 4;
- kcp->rx_srtt = (7 * kcp->rx_srtt + rtt) / 8;
- if (kcp->rx_srtt < 1) kcp->rx_srtt = 1;
- }
- rto = kcp->rx_srtt + _imax_(1, 4 * kcp->rx_rttval);
- kcp->rx_rto = _ibound_(kcp->rx_minrto, rto, IKCP_RTO_MAX);
-}
-
-static void ikcp_shrink_buf(ikcpcb *kcp)
-{
- struct IQUEUEHEAD *p = kcp->snd_buf.next;
- if (p != &kcp->snd_buf) {
- IKCPSEG *seg = iqueue_entry(p, IKCPSEG, node);
- kcp->snd_una = seg->sn;
- } else {
- kcp->snd_una = kcp->snd_nxt;
- }
-}
-
-static void ikcp_parse_ack(ikcpcb *kcp, IUINT32 sn)
-{
- struct IQUEUEHEAD *p, *next;
-
- if (_itimediff(sn, kcp->snd_una) < 0 || _itimediff(sn, kcp->snd_nxt) >= 0)
- return;
-
- for (p = kcp->snd_buf.next; p != &kcp->snd_buf; p = next) {
- IKCPSEG *seg = iqueue_entry(p, IKCPSEG, node);
- next = p->next;
- if (sn == seg->sn) {
- iqueue_del(p);
- ikcp_segment_delete(kcp, seg);
- kcp->nsnd_buf--;
- break;
- }
- else {
- seg->fastack++;
- }
- }
-}
-
-static void ikcp_parse_una(ikcpcb *kcp, IUINT32 una)
-{
-#if 1
- struct IQUEUEHEAD *p, *next;
- for (p = kcp->snd_buf.next; p != &kcp->snd_buf; p = next) {
- IKCPSEG *seg = iqueue_entry(p, IKCPSEG, node);
- next = p->next;
- if (_itimediff(una, seg->sn) > 0) {
- iqueue_del(p);
- ikcp_segment_delete(kcp, seg);
- kcp->nsnd_buf--;
- } else {
- break;
- }
- }
-#endif
-}
-
-
-//---------------------------------------------------------------------
-// ack append
-//---------------------------------------------------------------------
-static void ikcp_ack_push(ikcpcb *kcp, IUINT32 sn, IUINT32 ts)
-{
- size_t newsize = kcp->ackcount + 1;
- IUINT32 *ptr;
-
- if (newsize > kcp->ackblock) {
- IUINT32 *acklist;
- size_t newblock;
-
- for (newblock = 8; newblock < newsize; newblock <<= 1);
- acklist = (IUINT32*)ikcp_malloc(newblock * sizeof(IUINT32) * 2);
-
- if (acklist == NULL) {
- assert(acklist != NULL);
- abort();
- }
-
- if (kcp->acklist != NULL) {
- size_t x;
- for (x = 0; x < kcp->ackcount; x++) {
- acklist[x * 2 + 0] = kcp->acklist[x * 2 + 0];
- acklist[x * 2 + 1] = kcp->acklist[x * 2 + 1];
- }
- ikcp_free(kcp->acklist);
- }
-
- kcp->acklist = acklist;
- kcp->ackblock = newblock;
- }
-
- ptr = &kcp->acklist[kcp->ackcount * 2];
- ptr[0] = sn;
- ptr[1] = ts;
- kcp->ackcount++;
-}
-
-static void ikcp_ack_get(const ikcpcb *kcp, int p, IUINT32 *sn, IUINT32 *ts)
-{
- if (sn) sn[0] = kcp->acklist[p * 2 + 0];
- if (ts) ts[0] = kcp->acklist[p * 2 + 1];
-}
-
-
-//---------------------------------------------------------------------
-// parse data
-//---------------------------------------------------------------------
-void ikcp_parse_data(ikcpcb *kcp, IKCPSEG *newseg)
-{
- struct IQUEUEHEAD *p, *prev;
- IUINT32 sn = newseg->sn;
- int repeat = 0;
-
- if (_itimediff(sn, kcp->rcv_nxt + kcp->rcv_wnd) >= 0 ||
- _itimediff(sn, kcp->rcv_nxt) < 0) {
- ikcp_segment_delete(kcp, newseg);
- return;
- }
-
- for (p = kcp->rcv_buf.prev; p != &kcp->rcv_buf; p = prev) {
- IKCPSEG *seg = iqueue_entry(p, IKCPSEG, node);
- prev = p->prev;
- if (seg->sn == sn) {
- repeat = 1;
- break;
- }
- if (_itimediff(sn, seg->sn) > 0) {
- break;
- }
- }
-
- if (repeat == 0) {
- iqueue_init(&newseg->node);
- iqueue_add(&newseg->node, p);
- kcp->nrcv_buf++;
- } else {
- ikcp_segment_delete(kcp, newseg);
- }
-
-#if 0
- ikcp_qprint("rcvbuf", &kcp->rcv_buf);
- printf("rcv_nxt=%lu\n", kcp->rcv_nxt);
-#endif
-
- // move available data from rcv_buf -> rcv_queue
- while (! iqueue_is_empty(&kcp->rcv_buf)) {
- IKCPSEG *seg = iqueue_entry(kcp->rcv_buf.next, IKCPSEG, node);
- if (seg->sn == kcp->rcv_nxt && kcp->nrcv_que < kcp->rcv_wnd) {
- iqueue_del(&seg->node);
- kcp->nrcv_buf--;
- iqueue_add_tail(&seg->node, &kcp->rcv_queue);
- kcp->nrcv_que++;
- kcp->rcv_nxt++;
- } else {
- break;
- }
- }
-
-#if 0
- ikcp_qprint("queue", &kcp->rcv_queue);
- printf("rcv_nxt=%lu\n", kcp->rcv_nxt);
-#endif
-
-#if 1
-// printf("snd(buf=%d, queue=%d)\n", kcp->nsnd_buf, kcp->nsnd_que);
-// printf("rcv(buf=%d, queue=%d)\n", kcp->nrcv_buf, kcp->nrcv_que);
-#endif
-}
-
-
-//---------------------------------------------------------------------
-// input data
-//---------------------------------------------------------------------
-int ikcp_input(ikcpcb *kcp, const char *data, long size)
-{
- IUINT32 una = kcp->snd_una;
-
- if (ikcp_canlog(kcp, IKCP_LOG_INPUT)) {
- ikcp_log(kcp, IKCP_LOG_INPUT, "[RI] %d bytes", size);
- }
-
- if (data == NULL || size < 24) return 0;
-
- while (1) {
- IUINT32 ts, sn, len, una, conv;
- IUINT16 wnd;
- IUINT8 cmd, frg;
- IKCPSEG *seg;
-
- if (size < (int)IKCP_OVERHEAD) break;
-
- data = ikcp_decode32u(data, &conv);
- if (conv != kcp->conv) return -1;
-
- data = ikcp_decode8u(data, &cmd);
- data = ikcp_decode8u(data, &frg);
- data = ikcp_decode16u(data, &wnd);
- data = ikcp_decode32u(data, &ts);
- data = ikcp_decode32u(data, &sn);
- data = ikcp_decode32u(data, &una);
- data = ikcp_decode32u(data, &len);
-
- size -= IKCP_OVERHEAD;
-
- if ((long)size < (long)len) return -2;
-
- if (cmd != IKCP_CMD_PUSH && cmd != IKCP_CMD_ACK &&
- cmd != IKCP_CMD_WASK && cmd != IKCP_CMD_WINS)
- return -3;
-
- kcp->rmt_wnd = wnd;
- ikcp_parse_una(kcp, una);
- ikcp_shrink_buf(kcp);
-
- if (cmd == IKCP_CMD_ACK) {
- if (_itimediff(kcp->current, ts) >= 0) {
- ikcp_update_ack(kcp, _itimediff(kcp->current, ts));
- }
- ikcp_parse_ack(kcp, sn);
- ikcp_shrink_buf(kcp);
- if (ikcp_canlog(kcp, IKCP_LOG_IN_ACK)) {
- ikcp_log(kcp, IKCP_LOG_IN_DATA,
- "input ack: sn=%lu rtt=%ld rto=%ld", sn,
- (long)_itimediff(kcp->current, ts),
- (long)kcp->rx_rto);
- }
- }
- else if (cmd == IKCP_CMD_PUSH) {
- if (ikcp_canlog(kcp, IKCP_LOG_IN_DATA)) {
- ikcp_log(kcp, IKCP_LOG_IN_DATA,
- "input psh: sn=%lu ts=%lu", sn, ts);
- }
- if (_itimediff(sn, kcp->rcv_nxt + kcp->rcv_wnd) < 0) {
- ikcp_ack_push(kcp, sn, ts);
- if (_itimediff(sn, kcp->rcv_nxt) >= 0) {
- seg = ikcp_segment_new(kcp, len);
- seg->conv = conv;
- seg->cmd = cmd;
- seg->frg = frg;
- seg->wnd = wnd;
- seg->ts = ts;
- seg->sn = sn;
- seg->una = una;
- seg->len = len;
-
- if (len > 0) {
- memcpy(seg->data, data, len);
- }
-
- ikcp_parse_data(kcp, seg);
- }
- }
- }
- else if (cmd == IKCP_CMD_WASK) {
- // ready to send back IKCP_CMD_WINS in ikcp_flush
- // tell remote my window size
- kcp->probe |= IKCP_ASK_TELL;
- if (ikcp_canlog(kcp, IKCP_LOG_IN_PROBE)) {
- ikcp_log(kcp, IKCP_LOG_IN_PROBE, "input probe");
- }
- }
- else if (cmd == IKCP_CMD_WINS) {
- // do nothing
- if (ikcp_canlog(kcp, IKCP_LOG_IN_WINS)) {
- ikcp_log(kcp, IKCP_LOG_IN_WINS,
- "input wins: %lu", (IUINT32)(wnd));
- }
- }
- else {
- return -3;
- }
-
- data += len;
- size -= len;
- }
-
- if (_itimediff(kcp->snd_una, una) > 0) {
- if (kcp->cwnd < kcp->rmt_wnd) {
- IUINT32 mss = kcp->mss;
- if (kcp->cwnd < kcp->ssthresh) {
- kcp->cwnd++;
- kcp->incr += mss;
- } else {
- if (kcp->incr < mss) kcp->incr = mss;
- kcp->incr += (mss * mss) / kcp->incr + (mss / 16);
- if ((kcp->cwnd + 1) * mss >= kcp->incr) {
- kcp->cwnd++;
- }
- }
- if (kcp->cwnd > kcp->rmt_wnd) {
- kcp->cwnd = kcp->rmt_wnd;
- kcp->incr = kcp->rmt_wnd * mss;
- }
- }
- }
-
- return 0;
-}
-
-
-//---------------------------------------------------------------------
-// ikcp_encode_seg
-//---------------------------------------------------------------------
-static char *ikcp_encode_seg(char *ptr, const IKCPSEG *seg)
-{
- ptr = ikcp_encode32u(ptr, seg->conv);
- ptr = ikcp_encode8u(ptr, (IUINT8)seg->cmd);
- ptr = ikcp_encode8u(ptr, (IUINT8)seg->frg);
- ptr = ikcp_encode16u(ptr, (IUINT16)seg->wnd);
- ptr = ikcp_encode32u(ptr, seg->ts);
- ptr = ikcp_encode32u(ptr, seg->sn);
- ptr = ikcp_encode32u(ptr, seg->una);
- ptr = ikcp_encode32u(ptr, seg->len);
- return ptr;
-}
-
-static int ikcp_wnd_unused(const ikcpcb *kcp)
-{
- if (kcp->nrcv_que < kcp->rcv_wnd) {
- return kcp->rcv_wnd - kcp->nrcv_que;
- }
- return 0;
-}
-
-
-//---------------------------------------------------------------------
-// ikcp_flush
-//---------------------------------------------------------------------
-void ikcp_flush(ikcpcb *kcp)
-{
- IUINT32 current = kcp->current;
- char *buffer = kcp->buffer;
- char *ptr = buffer;
- int count, size, i;
- IUINT32 resent, cwnd;
- IUINT32 rtomin;
- struct IQUEUEHEAD *p;
- int change = 0;
- int lost = 0;
- IKCPSEG seg;
-
- // 'ikcp_update' haven't been called.
- if (kcp->updated == 0) return;
-
- seg.conv = kcp->conv;
- seg.cmd = IKCP_CMD_ACK;
- seg.frg = 0;
- seg.wnd = ikcp_wnd_unused(kcp);
- seg.una = kcp->rcv_nxt;
- seg.len = 0;
- seg.sn = 0;
- seg.ts = 0;
-
- // flush acknowledges
- count = kcp->ackcount;
- for (i = 0; i < count; i++) {
- size = (int)(ptr - buffer);
- if (size + IKCP_OVERHEAD > (int)kcp->mtu) {
- ikcp_output(kcp, buffer, size);
- ptr = buffer;
- }
- ikcp_ack_get(kcp, i, &seg.sn, &seg.ts);
- ptr = ikcp_encode_seg(ptr, &seg);
- }
-
- kcp->ackcount = 0;
-
- // probe window size (if remote window size equals zero)
- if (kcp->rmt_wnd == 0) {
- if (kcp->probe_wait == 0) {
- kcp->probe_wait = IKCP_PROBE_INIT;
- kcp->ts_probe = kcp->current + kcp->probe_wait;
- }
- else {
- if (_itimediff(kcp->current, kcp->ts_probe) >= 0) {
- if (kcp->probe_wait < IKCP_PROBE_INIT)
- kcp->probe_wait = IKCP_PROBE_INIT;
- kcp->probe_wait += kcp->probe_wait / 2;
- if (kcp->probe_wait > IKCP_PROBE_LIMIT)
- kcp->probe_wait = IKCP_PROBE_LIMIT;
- kcp->ts_probe = kcp->current + kcp->probe_wait;
- kcp->probe |= IKCP_ASK_SEND;
- }
- }
- } else {
- kcp->ts_probe = 0;
- kcp->probe_wait = 0;
- }
-
- // flush window probing commands
- if (kcp->probe & IKCP_ASK_SEND) {
- seg.cmd = IKCP_CMD_WASK;
- size = (int)(ptr - buffer);
- if (size + IKCP_OVERHEAD > (int)kcp->mtu) {
- ikcp_output(kcp, buffer, size);
- ptr = buffer;
- }
- ptr = ikcp_encode_seg(ptr, &seg);
- }
-
- // flush window probing commands
- if (kcp->probe & IKCP_ASK_TELL) {
- seg.cmd = IKCP_CMD_WINS;
- size = (int)(ptr - buffer);
- if (size + IKCP_OVERHEAD > (int)kcp->mtu) {
- ikcp_output(kcp, buffer, size);
- ptr = buffer;
- }
- ptr = ikcp_encode_seg(ptr, &seg);
- }
-
- kcp->probe = 0;
-
- // calculate window size
- cwnd = _imin_(kcp->snd_wnd, kcp->rmt_wnd);
- if (kcp->nocwnd == 0) cwnd = _imin_(kcp->cwnd, cwnd);
-
- // move data from snd_queue to snd_buf
- while (_itimediff(kcp->snd_nxt, kcp->snd_una + cwnd) < 0) {
- IKCPSEG *newseg;
- if (iqueue_is_empty(&kcp->snd_queue)) break;
-
- newseg = iqueue_entry(kcp->snd_queue.next, IKCPSEG, node);
-
- iqueue_del(&newseg->node);
- iqueue_add_tail(&newseg->node, &kcp->snd_buf);
- kcp->nsnd_que--;
- kcp->nsnd_buf++;
-
- newseg->conv = kcp->conv;
- newseg->cmd = IKCP_CMD_PUSH;
- newseg->wnd = seg.wnd;
- newseg->ts = current;
- newseg->sn = kcp->snd_nxt++;
- newseg->una = kcp->rcv_nxt;
- newseg->resendts = current;
- newseg->rto = kcp->rx_rto;
- newseg->fastack = 0;
- newseg->xmit = 0;
- }
-
- // calculate resent
- resent = (kcp->fastresend > 0)? (IUINT32)kcp->fastresend : 0xffffffff;
- rtomin = (kcp->nodelay == 0)? (kcp->rx_rto >> 3) : 0;
-
- // flush data segments
- for (p = kcp->snd_buf.next; p != &kcp->snd_buf; p = p->next) {
- IKCPSEG *segment = iqueue_entry(p, IKCPSEG, node);
- int needsend = 0;
- if (segment->xmit == 0) {
- needsend = 1;
- segment->xmit++;
- segment->rto = kcp->rx_rto;
- segment->resendts = current + segment->rto + rtomin;
- }
- else if (_itimediff(current, segment->resendts) >= 0) {
- needsend = 1;
- segment->xmit++;
- kcp->xmit++;
- if (kcp->nodelay == 0) {
- segment->rto += kcp->rx_rto;
- } else {
- segment->rto += kcp->rx_rto / 2;
- }
- segment->resendts = current + segment->rto;
- lost = 1;
- }
- else if (segment->fastack >= resent) {
- needsend = 1;
- segment->xmit++;
- segment->fastack = 0;
- segment->resendts = current + segment->rto;
- change++;
- }
-
- if (needsend) {
- int size, need;
- segment->ts = current;
- segment->wnd = seg.wnd;
- segment->una = kcp->rcv_nxt;
-
- size = (int)(ptr - buffer);
- need = IKCP_OVERHEAD + segment->len;
-
- if (size + need > (int)kcp->mtu) {
- ikcp_output(kcp, buffer, size);
- ptr = buffer;
- }
-
- ptr = ikcp_encode_seg(ptr, segment);
-
- if (segment->len > 0) {
- memcpy(ptr, segment->data, segment->len);
- ptr += segment->len;
- }
-
- if (segment->xmit >= kcp->dead_link) {
- kcp->state = -1;
- }
- }
- }
-
- // flash remain segments
- size = (int)(ptr - buffer);
- if (size > 0) {
- ikcp_output(kcp, buffer, size);
- }
-
- // update ssthresh
- if (change) {
- IUINT32 inflight = kcp->snd_nxt - kcp->snd_una;
- kcp->ssthresh = inflight / 2;
- if (kcp->ssthresh < IKCP_THRESH_MIN)
- kcp->ssthresh = IKCP_THRESH_MIN;
- kcp->cwnd = kcp->ssthresh + resent;
- kcp->incr = kcp->cwnd * kcp->mss;
- }
-
- if (lost) {
- kcp->ssthresh = cwnd / 2;
- if (kcp->ssthresh < IKCP_THRESH_MIN)
- kcp->ssthresh = IKCP_THRESH_MIN;
- kcp->cwnd = 1;
- kcp->incr = kcp->mss;
- }
-
- if (kcp->cwnd < 1) {
- kcp->cwnd = 1;
- kcp->incr = kcp->mss;
- }
-}
-
-
-//---------------------------------------------------------------------
-// update state (call it repeatedly, every 10ms-100ms), or you can ask
-// ikcp_check when to call it again (without ikcp_input/_send calling).
-// 'current' - current timestamp in millisec.
-//---------------------------------------------------------------------
-void ikcp_update(ikcpcb *kcp, IUINT32 current)
-{
- IINT32 slap;
-
- kcp->current = current;
-
- if (kcp->updated == 0) {
- kcp->updated = 1;
- kcp->ts_flush = kcp->current;
- }
-
- slap = _itimediff(kcp->current, kcp->ts_flush);
-
- if (slap >= 10000 || slap < -10000) {
- kcp->ts_flush = kcp->current;
- slap = 0;
- }
-
- if (slap >= 0) {
- kcp->ts_flush += kcp->interval;
- if (_itimediff(kcp->current, kcp->ts_flush) >= 0) {
- kcp->ts_flush = kcp->current + kcp->interval;
- }
- ikcp_flush(kcp);
- }
-}
-
-
-//---------------------------------------------------------------------
-// Determine when should you invoke ikcp_update:
-// returns when you should invoke ikcp_update in millisec, if there
-// is no ikcp_input/_send calling. you can call ikcp_update in that
-// time, instead of call update repeatly.
-// Important to reduce unnacessary ikcp_update invoking. use it to
-// schedule ikcp_update (eg. implementing an epoll-like mechanism,
-// or optimize ikcp_update when handling massive kcp connections)
-//---------------------------------------------------------------------
-IUINT32 ikcp_check(const ikcpcb *kcp, IUINT32 current)
-{
- IUINT32 ts_flush = kcp->ts_flush;
- IINT32 tm_flush = 0x7fffffff;
- IINT32 tm_packet = 0x7fffffff;
- IUINT32 minimal = 0;
- struct IQUEUEHEAD *p;
-
- if (kcp->updated == 0) {
- return current;
- }
-
- if (_itimediff(current, ts_flush) >= 10000 ||
- _itimediff(current, ts_flush) < -10000) {
- ts_flush = current;
- }
-
- if (_itimediff(current, ts_flush) >= 0) {
- return current;
- }
-
- tm_flush = _itimediff(ts_flush, current);
-
- for (p = kcp->snd_buf.next; p != &kcp->snd_buf; p = p->next) {
- const IKCPSEG *seg = iqueue_entry(p, const IKCPSEG, node);
- IINT32 diff = _itimediff(seg->resendts, current);
- if (diff <= 0) {
- return current;
- }
- if (diff < tm_packet) tm_packet = diff;
- }
-
- minimal = (IUINT32)(tm_packet < tm_flush ? tm_packet : tm_flush);
- if (minimal >= kcp->interval) minimal = kcp->interval;
-
- return current + minimal;
-}
-
-
-
-int ikcp_setmtu(ikcpcb *kcp, int mtu)
-{
- char *buffer;
- if (mtu < 50 || mtu < (int)IKCP_OVERHEAD)
- return -1;
- buffer = (char*)ikcp_malloc((mtu + IKCP_OVERHEAD) * 3);
- if (buffer == NULL)
- return -2;
- kcp->mtu = mtu;
- kcp->mss = kcp->mtu - IKCP_OVERHEAD;
- ikcp_free(kcp->buffer);
- kcp->buffer = buffer;
- return 0;
-}
-
-int ikcp_interval(ikcpcb *kcp, int interval)
-{
- if (interval > 5000) interval = 5000;
- else if (interval < 10) interval = 10;
- kcp->interval = interval;
- return 0;
-}
-
-int ikcp_nodelay(ikcpcb *kcp, int nodelay, int interval, int resend, int nc)
-{
- if (nodelay >= 0) {
- kcp->nodelay = nodelay;
- if (nodelay) {
- kcp->rx_minrto = IKCP_RTO_NDL;
- }
- else {
- kcp->rx_minrto = IKCP_RTO_MIN;
- }
- }
- if (interval >= 0) {
- if (interval > 5000) interval = 5000;
- else if (interval < 10) interval = 10;
- kcp->interval = interval;
- }
- if (resend >= 0) {
- kcp->fastresend = resend;
- }
- if (nc >= 0) {
- kcp->nocwnd = nc;
- }
- return 0;
-}
-
-
-int ikcp_wndsize(ikcpcb *kcp, int sndwnd, int rcvwnd)
-{
- if (kcp) {
- if (sndwnd > 0) {
- kcp->snd_wnd = sndwnd;
- }
- if (rcvwnd > 0) {
- kcp->rcv_wnd = rcvwnd;
- }
- }
- return 0;
-}
-
-int ikcp_waitsnd(const ikcpcb *kcp)
-{
- return kcp->nsnd_buf + kcp->nsnd_que;
-}
-
-
diff --git a/3rd/kcp/ikcp.h b/3rd/kcp/ikcp.h
deleted file mode 100644
index 5626693..0000000
--- a/3rd/kcp/ikcp.h
+++ /dev/null
@@ -1,399 +0,0 @@
-//=====================================================================
-//
-// KCP - A Better ARQ Protocol Implementation
-// skywind3000 (at) gmail.com, 2010-2011
-//
-// Features:
-// + Average RTT reduce 30% - 40% vs traditional ARQ like tcp.
-// + Maximum RTT reduce three times vs tcp.
-// + Lightweight, distributed as a single source file.
-//
-//=====================================================================
-#ifndef __IKCP_H__
-#define __IKCP_H__
-
-#include
-#include
-#include
-
-
-//=====================================================================
-// 32BIT INTEGER DEFINITION
-//=====================================================================
-#ifndef __INTEGER_32_BITS__
-#define __INTEGER_32_BITS__
-#if defined(_WIN64) || defined(WIN64) || defined(__amd64__) || \
- defined(__x86_64) || defined(__x86_64__) || defined(_M_IA64) || \
- defined(_M_AMD64)
- typedef unsigned int ISTDUINT32;
- typedef int ISTDINT32;
-#elif defined(_WIN32) || defined(WIN32) || defined(__i386__) || \
- defined(__i386) || defined(_M_X86)
- typedef unsigned long ISTDUINT32;
- typedef long ISTDINT32;
-#elif defined(__MACOS__)
- typedef UInt32 ISTDUINT32;
- typedef SInt32 ISTDINT32;
-#elif defined(__APPLE__) && defined(__MACH__)
- #include
- typedef u_int32_t ISTDUINT32;
- typedef int32_t ISTDINT32;
-#elif defined(__BEOS__)
- #include
- typedef u_int32_t ISTDUINT32;
- typedef int32_t ISTDINT32;
-#elif (defined(_MSC_VER) || defined(__BORLANDC__)) && (!defined(__MSDOS__))
- typedef unsigned __int32 ISTDUINT32;
- typedef __int32 ISTDINT32;
-#elif defined(__GNUC__)
- #include
- typedef uint32_t ISTDUINT32;
- typedef int32_t ISTDINT32;
-#else
- typedef unsigned long ISTDUINT32;
- typedef long ISTDINT32;
-#endif
-#endif
-
-
-//=====================================================================
-// Integer Definition
-//=====================================================================
-#ifndef __IINT8_DEFINED
-#define __IINT8_DEFINED
-typedef char IINT8;
-#endif
-
-#ifndef __IUINT8_DEFINED
-#define __IUINT8_DEFINED
-typedef unsigned char IUINT8;
-#endif
-
-#ifndef __IUINT16_DEFINED
-#define __IUINT16_DEFINED
-typedef unsigned short IUINT16;
-#endif
-
-#ifndef __IINT16_DEFINED
-#define __IINT16_DEFINED
-typedef short IINT16;
-#endif
-
-#ifndef __IINT32_DEFINED
-#define __IINT32_DEFINED
-typedef ISTDINT32 IINT32;
-#endif
-
-#ifndef __IUINT32_DEFINED
-#define __IUINT32_DEFINED
-typedef ISTDUINT32 IUINT32;
-#endif
-
-#ifndef __IINT64_DEFINED
-#define __IINT64_DEFINED
-#if defined(_MSC_VER) || defined(__BORLANDC__)
-typedef __int64 IINT64;
-#else
-typedef long long IINT64;
-#endif
-#endif
-
-#ifndef __IUINT64_DEFINED
-#define __IUINT64_DEFINED
-#if defined(_MSC_VER) || defined(__BORLANDC__)
-typedef unsigned __int64 IUINT64;
-#else
-typedef unsigned long long IUINT64;
-#endif
-#endif
-
-#ifndef INLINE
-#if defined(__GNUC__)
-
-#if (__GNUC__ > 3) || ((__GNUC__ == 3) && (__GNUC_MINOR__ >= 1))
-#define INLINE __inline__ __attribute__((always_inline))
-#else
-#define INLINE __inline__
-#endif
-
-#elif (defined(_MSC_VER) || defined(__BORLANDC__) || defined(__WATCOMC__))
-#define INLINE __inline
-#else
-#define INLINE
-#endif
-#endif
-
-#ifndef inline
-#define inline INLINE
-#endif
-
-
-//=====================================================================
-// QUEUE DEFINITION
-//=====================================================================
-#ifndef __IQUEUE_DEF__
-#define __IQUEUE_DEF__
-
-struct IQUEUEHEAD {
- struct IQUEUEHEAD *next, *prev;
-};
-
-typedef struct IQUEUEHEAD iqueue_head;
-
-
-//---------------------------------------------------------------------
-// queue init
-//---------------------------------------------------------------------
-#define IQUEUE_HEAD_INIT(name) { &(name), &(name) }
-#define IQUEUE_HEAD(name) \
- struct IQUEUEHEAD name = IQUEUE_HEAD_INIT(name)
-
-#define IQUEUE_INIT(ptr) ( \
- (ptr)->next = (ptr), (ptr)->prev = (ptr))
-
-#define IOFFSETOF(TYPE, MEMBER) ((size_t) &((TYPE *)0)->MEMBER)
-
-#define ICONTAINEROF(ptr, type, member) ( \
- (type*)( ((char*)((type*)ptr)) - IOFFSETOF(type, member)) )
-
-#define IQUEUE_ENTRY(ptr, type, member) ICONTAINEROF(ptr, type, member)
-
-
-//---------------------------------------------------------------------
-// queue operation
-//---------------------------------------------------------------------
-#define IQUEUE_ADD(node, head) ( \
- (node)->prev = (head), (node)->next = (head)->next, \
- (head)->next->prev = (node), (head)->next = (node))
-
-#define IQUEUE_ADD_TAIL(node, head) ( \
- (node)->prev = (head)->prev, (node)->next = (head), \
- (head)->prev->next = (node), (head)->prev = (node))
-
-#define IQUEUE_DEL_BETWEEN(p, n) ((n)->prev = (p), (p)->next = (n))
-
-#define IQUEUE_DEL(entry) (\
- (entry)->next->prev = (entry)->prev, \
- (entry)->prev->next = (entry)->next, \
- (entry)->next = 0, (entry)->prev = 0)
-
-#define IQUEUE_DEL_INIT(entry) do { \
- IQUEUE_DEL(entry); IQUEUE_INIT(entry); } while (0)
-
-#define IQUEUE_IS_EMPTY(entry) ((entry) == (entry)->next)
-
-#define iqueue_init IQUEUE_INIT
-#define iqueue_entry IQUEUE_ENTRY
-#define iqueue_add IQUEUE_ADD
-#define iqueue_add_tail IQUEUE_ADD_TAIL
-#define iqueue_del IQUEUE_DEL
-#define iqueue_del_init IQUEUE_DEL_INIT
-#define iqueue_is_empty IQUEUE_IS_EMPTY
-
-#define IQUEUE_FOREACH(iterator, head, TYPE, MEMBER) \
- for ((iterator) = iqueue_entry((head)->next, TYPE, MEMBER); \
- &((iterator)->MEMBER) != (head); \
- (iterator) = iqueue_entry((iterator)->MEMBER.next, TYPE, MEMBER))
-
-#define iqueue_foreach(iterator, head, TYPE, MEMBER) \
- IQUEUE_FOREACH(iterator, head, TYPE, MEMBER)
-
-#define iqueue_foreach_entry(pos, head) \
- for( (pos) = (head)->next; (pos) != (head) ; (pos) = (pos)->next )
-
-
-#define __iqueue_splice(list, head) do { \
- iqueue_head *first = (list)->next, *last = (list)->prev; \
- iqueue_head *at = (head)->next; \
- (first)->prev = (head), (head)->next = (first); \
- (last)->next = (at), (at)->prev = (last); } while (0)
-
-#define iqueue_splice(list, head) do { \
- if (!iqueue_is_empty(list)) __iqueue_splice(list, head); } while (0)
-
-#define iqueue_splice_init(list, head) do { \
- iqueue_splice(list, head); iqueue_init(list); } while (0)
-
-
-#ifdef _MSC_VER
-#pragma warning(disable:4311)
-#pragma warning(disable:4312)
-#pragma warning(disable:4996)
-#endif
-
-#endif
-
-
-//---------------------------------------------------------------------
-// WORD ORDER
-//---------------------------------------------------------------------
-#ifndef IWORDS_BIG_ENDIAN
- #ifdef _BIG_ENDIAN_
- #if _BIG_ENDIAN_
- #define IWORDS_BIG_ENDIAN 1
- #endif
- #endif
- #ifndef IWORDS_BIG_ENDIAN
- #if defined(__hppa__) || \
- defined(__m68k__) || defined(mc68000) || defined(_M_M68K) || \
- (defined(__MIPS__) && defined(__MISPEB__)) || \
- defined(__ppc__) || defined(__POWERPC__) || defined(_M_PPC) || \
- defined(__sparc__) || defined(__powerpc__) || \
- defined(__mc68000__) || defined(__s390x__) || defined(__s390__)
- #define IWORDS_BIG_ENDIAN 1
- #endif
- #endif
- #ifndef IWORDS_BIG_ENDIAN
- #define IWORDS_BIG_ENDIAN 0
- #endif
-#endif
-
-
-
-//=====================================================================
-// SEGMENT
-//=====================================================================
-struct IKCPSEG
-{
- struct IQUEUEHEAD node;
- IUINT32 conv;
- IUINT32 cmd;
- IUINT32 frg;
- IUINT32 wnd;
- IUINT32 ts;
- IUINT32 sn;
- IUINT32 una;
- IUINT32 len;
- IUINT32 resendts;
- IUINT32 rto;
- IUINT32 fastack;
- IUINT32 xmit;
- char data[1];
-};
-
-
-//---------------------------------------------------------------------
-// IKCPCB
-//---------------------------------------------------------------------
-struct IKCPCB
-{
- IUINT32 conv, mtu, mss, state;
- IUINT32 snd_una, snd_nxt, rcv_nxt;
- IUINT32 ts_recent, ts_lastack, ssthresh;
- IINT32 rx_rttval, rx_srtt, rx_rto, rx_minrto;
- IUINT32 snd_wnd, rcv_wnd, rmt_wnd, cwnd, probe;
- IUINT32 current, interval, ts_flush, xmit;
- IUINT32 nrcv_buf, nsnd_buf;
- IUINT32 nrcv_que, nsnd_que;
- IUINT32 nodelay, updated;
- IUINT32 ts_probe, probe_wait;
- IUINT32 dead_link, incr;
- struct IQUEUEHEAD snd_queue;
- struct IQUEUEHEAD rcv_queue;
- struct IQUEUEHEAD snd_buf;
- struct IQUEUEHEAD rcv_buf;
- IUINT32 *acklist;
- IUINT32 ackcount;
- IUINT32 ackblock;
- void *user;
- char *buffer;
- int fastresend;
- int nocwnd;
- int logmask;
- int (*output)(const char *buf, int len, struct IKCPCB *kcp, void *user);
- void (*writelog)(const char *log, struct IKCPCB *kcp, void *user);
-};
-
-
-typedef struct IKCPCB ikcpcb;
-
-#define IKCP_LOG_OUTPUT 1
-#define IKCP_LOG_INPUT 2
-#define IKCP_LOG_SEND 4
-#define IKCP_LOG_RECV 8
-#define IKCP_LOG_IN_DATA 16
-#define IKCP_LOG_IN_ACK 32
-#define IKCP_LOG_IN_PROBE 64
-#define IKCP_LOG_IN_WINS 128
-#define IKCP_LOG_OUT_DATA 256
-#define IKCP_LOG_OUT_ACK 512
-#define IKCP_LOG_OUT_PROBE 1024
-#define IKCP_LOG_OUT_WINS 2048
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-//---------------------------------------------------------------------
-// interface
-//---------------------------------------------------------------------
-
-// create a new kcp control object, 'conv' must equal in two endpoint
-// from the same connection. 'user' will be passed to the output callback
-// output callback can be setup like this: 'kcp->output = my_udp_output'
-ikcpcb* ikcp_create(IUINT32 conv, void *user);
-
-// release kcp control object
-void ikcp_release(ikcpcb *kcp);
-
-// user/upper level recv: returns size, returns below zero for EAGAIN
-int ikcp_recv(ikcpcb *kcp, char *buffer, int len);
-
-// user/upper level send, returns below zero for error
-int ikcp_send(ikcpcb *kcp, const char *buffer, int len);
-
-// update state (call it repeatedly, every 10ms-100ms), or you can ask
-// ikcp_check when to call it again (without ikcp_input/_send calling).
-// 'current' - current timestamp in millisec.
-void ikcp_update(ikcpcb *kcp, IUINT32 current);
-
-// Determine when should you invoke ikcp_update:
-// returns when you should invoke ikcp_update in millisec, if there
-// is no ikcp_input/_send calling. you can call ikcp_update in that
-// time, instead of call update repeatly.
-// Important to reduce unnacessary ikcp_update invoking. use it to
-// schedule ikcp_update (eg. implementing an epoll-like mechanism,
-// or optimize ikcp_update when handling massive kcp connections)
-IUINT32 ikcp_check(const ikcpcb *kcp, IUINT32 current);
-
-// when you received a low level packet (eg. UDP packet), call it
-int ikcp_input(ikcpcb *kcp, const char *data, long size);
-
-// flush pending data
-void ikcp_flush(ikcpcb *kcp);
-
-// check the size of next message in the recv queue
-int ikcp_peeksize(const ikcpcb *kcp);
-
-// change MTU size, default is 1400
-int ikcp_setmtu(ikcpcb *kcp, int mtu);
-
-// set maximum window size: sndwnd=32, rcvwnd=32 by default
-int ikcp_wndsize(ikcpcb *kcp, int sndwnd, int rcvwnd);
-
-// get how many packet is waiting to be sent
-int ikcp_waitsnd(const ikcpcb *kcp);
-
-// fastest: ikcp_nodelay(kcp, 1, 20, 2, 1)
-// nodelay: 0:disable(default), 1:enable
-// interval: internal update timer interval in millisec, default is 100ms
-// resend: 0:disable fast resend(default), 1:enable fast resend
-// nc: 0:normal congestion control(default), 1:disable congestion control
-int ikcp_nodelay(ikcpcb *kcp, int nodelay, int interval, int resend, int nc);
-
-int ikcp_rcvbuf_count(const ikcpcb *kcp);
-int ikcp_sndbuf_count(const ikcpcb *kcp);
-
-void ikcp_log(ikcpcb *kcp, int mask, const char *fmt, ...);
-
-// setup allocator
-void ikcp_allocator(void* (*new_malloc)(size_t), void (*new_free)(void*));
-
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif
-
-
diff --git a/3rd/kcp/test.cpp b/3rd/kcp/test.cpp
deleted file mode 100644
index 260ad84..0000000
--- a/3rd/kcp/test.cpp
+++ /dev/null
@@ -1,177 +0,0 @@
-//=====================================================================
-//
-// test.cpp - kcp 测试用例
-//
-// 说明:
-// gcc test.cpp -o test -lstdc++
-//
-//=====================================================================
-
-#include
-#include
-
-#include "test.h"
-#include "ikcp.c"
-
-
-// 模拟网络
-LatencySimulator *vnet;
-
-// 模拟网络:模拟发送一个 udp包
-int udp_output(const char *buf, int len, ikcpcb *kcp, void *user)
-{
- int id = (int)user;
- vnet->send(id, buf, len);
- return 0;
-}
-
-// 测试用例
-void test(int mode)
-{
- // 创建模拟网络:丢包率10%,Rtt 60ms~125ms
- vnet = new LatencySimulator(10, 60, 125);
-
- // 创建两个端点的 kcp对象,第一个参数 conv是会话编号,同一个会话需要相同
- // 最后一个是 user参数,用来传递标识
- ikcpcb *kcp1 = ikcp_create(0x11223344, (void*)0);
- ikcpcb *kcp2 = ikcp_create(0x11223344, (void*)1);
-
- // 设置kcp的下层输出,这里为 udp_output,模拟udp网络输出函数
- kcp1->output = udp_output;
- kcp2->output = udp_output;
-
- IUINT32 current = iclock();
- IUINT32 slap = current + 20;
- IUINT32 index = 0;
- IUINT32 next = 0;
- IINT64 sumrtt = 0;
- int count = 0;
- int maxrtt = 0;
-
- // 配置窗口大小:平均延迟200ms,每20ms发送一个包,
- // 而考虑到丢包重发,设置最大收发窗口为128
- ikcp_wndsize(kcp1, 128, 128);
- ikcp_wndsize(kcp2, 128, 128);
-
- // 判断测试用例的模式
- if (mode == 0) {
- // 默认模式
- ikcp_nodelay(kcp1, 0, 10, 0, 0);
- ikcp_nodelay(kcp2, 0, 10, 0, 0);
- }
- else if (mode == 1) {
- // 普通模式,关闭流控等
- ikcp_nodelay(kcp1, 0, 10, 0, 1);
- ikcp_nodelay(kcp2, 0, 10, 0, 1);
- } else {
- // 启动快速模式
- // 第二个参数 nodelay-启用以后若干常规加速将启动
- // 第三个参数 interval为内部处理时钟,默认设置为 10ms
- // 第四个参数 resend为快速重传指标,设置为2
- // 第五个参数 为是否禁用常规流控,这里禁止
- ikcp_nodelay(kcp1, 1, 10, 2, 1);
- ikcp_nodelay(kcp2, 1, 10, 2, 1);
- }
-
-
- char buffer[2000];
- int hr;
-
- IUINT32 ts1 = iclock();
-
- while (1) {
- isleep(1);
- current = iclock();
- ikcp_update(kcp1, iclock());
- ikcp_update(kcp2, iclock());
-
- // 每隔 20ms,kcp1发送数据
- for (; current >= slap; slap += 20) {
- *(IUINT32*)(buffer + 0) = index++;
- *(IUINT32*)(buffer + 4) = current;
-
- // 发送上层协议包
- ikcp_send(kcp1, buffer, 8);
- }
-
- // 处理虚拟网络:检测是否有udp包从p1->p2
- while (1) {
- hr = vnet->recv(1, buffer, 2000);
- if (hr < 0) break;
- // 如果 p2收到udp,则作为下层协议输入到kcp2
- ikcp_input(kcp2, buffer, hr);
- }
-
- // 处理虚拟网络:检测是否有udp包从p2->p1
- while (1) {
- hr = vnet->recv(0, buffer, 2000);
- if (hr < 0) break;
- // 如果 p1收到udp,则作为下层协议输入到kcp1
- ikcp_input(kcp1, buffer, hr);
- }
-
- // kcp2接收到任何包都返回回去
- while (1) {
- hr = ikcp_recv(kcp2, buffer, 10);
- // 没有收到包就退出
- if (hr < 0) break;
- // 如果收到包就回射
- ikcp_send(kcp2, buffer, hr);
- }
-
- // kcp1收到kcp2的回射数据
- while (1) {
- hr = ikcp_recv(kcp1, buffer, 10);
- // 没有收到包就退出
- if (hr < 0) break;
- IUINT32 sn = *(IUINT32*)(buffer + 0);
- IUINT32 ts = *(IUINT32*)(buffer + 4);
- IUINT32 rtt = current - ts;
-
- if (sn != next) {
- // 如果收到的包不连续
- printf("ERROR sn %d<->%d\n", (int)count, (int)next);
- return;
- }
-
- next++;
- sumrtt += rtt;
- count++;
- if (rtt > (IUINT32)maxrtt) maxrtt = rtt;
-
- printf("[RECV] mode=%d sn=%d rtt=%d\n", mode, (int)sn, (int)rtt);
- }
- if (next > 1000) break;
- }
-
- ts1 = iclock() - ts1;
-
- ikcp_release(kcp1);
- ikcp_release(kcp2);
-
- const char *names[3] = { "default", "normal", "fast" };
- printf("%s mode result (%dms):\n", names[mode], (int)ts1);
- printf("avgrtt=%d maxrtt=%d\n", (int)(sumrtt / count), maxrtt);
- printf("press enter to next ...\n");
- char ch; scanf("%c", &ch);
-}
-
-int main()
-{
- test(0); // 默认模式,类似 TCP:正常模式,无快速重传,常规流控
- test(1); // 普通模式,关闭流控等
- test(2); // 快速模式,所有开关都打开,且关闭流控
- return 0;
-}
-
-/*
-default mode result (20917ms):
-avgrtt=740 maxrtt=1507
-
-normal mode result (20131ms):
-avgrtt=156 maxrtt=571
-
-fast mode result (20207ms):
-avgrtt=138 maxrtt=392
-*/
-
diff --git a/3rd/kcp/test.h b/3rd/kcp/test.h
deleted file mode 100644
index f60a8a4..0000000
--- a/3rd/kcp/test.h
+++ /dev/null
@@ -1,242 +0,0 @@
-#ifndef __TEST_H__
-#define __TEST_H__
-
-#include
-#include
-#include
-#include
-#include
-
-#include "ikcp.h"
-
-#if defined(WIN32) || defined(_WIN32) || defined(WIN64) || defined(_WIN64)
-#include
-#elif !defined(__unix)
-#define __unix
-#endif
-
-#ifdef __unix
-#include
-#include
-#include
-#include
-#endif
-
-/* get system time */
-static inline void itimeofday(long *sec, long *usec)
-{
- #if defined(__unix)
- struct timeval time;
- gettimeofday(&time, NULL);
- if (sec) *sec = time.tv_sec;
- if (usec) *usec = time.tv_usec;
- #else
- static long mode = 0, addsec = 0;
- BOOL retval;
- static IINT64 freq = 1;
- IINT64 qpc;
- if (mode == 0) {
- retval = QueryPerformanceFrequency((LARGE_INTEGER*)&freq);
- freq = (freq == 0)? 1 : freq;
- retval = QueryPerformanceCounter((LARGE_INTEGER*)&qpc);
- addsec = (long)time(NULL);
- addsec = addsec - (long)((qpc / freq) & 0x7fffffff);
- mode = 1;
- }
- retval = QueryPerformanceCounter((LARGE_INTEGER*)&qpc);
- retval = retval * 2;
- if (sec) *sec = (long)(qpc / freq) + addsec;
- if (usec) *usec = (long)((qpc % freq) * 1000000 / freq);
- #endif
-}
-
-/* get clock in millisecond 64 */
-static inline IINT64 iclock64(void)
-{
- long s, u;
- IINT64 value;
- itimeofday(&s, &u);
- value = ((IINT64)s) * 1000 + (u / 1000);
- return value;
-}
-
-static inline IUINT32 iclock()
-{
- return (IUINT32)(iclock64() & 0xfffffffful);
-}
-
-/* sleep in millisecond */
-static inline void isleep(unsigned long millisecond)
-{
- #ifdef __unix /* usleep( time * 1000 ); */
- struct timespec ts;
- ts.tv_sec = (time_t)(millisecond / 1000);
- ts.tv_nsec = (long)((millisecond % 1000) * 1000000);
- /*nanosleep(&ts, NULL);*/
- usleep((millisecond << 10) - (millisecond << 4) - (millisecond << 3));
- #elif defined(_WIN32)
- Sleep(millisecond);
- #endif
-}
-
-#ifdef __cplusplus
-#include
-#include
-
-// 带延迟的数据包
-class DelayPacket
-{
-public:
- virtual ~DelayPacket() {
- if (_ptr) delete _ptr;
- _ptr = NULL;
- }
-
- DelayPacket(int size, const void *src = NULL) {
- _ptr = new unsigned char[size];
- _size = size;
- if (src) {
- memcpy(_ptr, src, size);
- }
- }
-
- unsigned char* ptr() { return _ptr; }
- const unsigned char* ptr() const { return _ptr; }
-
- int size() const { return _size; }
- IUINT32 ts() const { return _ts; }
- void setts(IUINT32 ts) { _ts = ts; }
-
-protected:
- unsigned char *_ptr;
- int _size;
- IUINT32 _ts;
-};
-
-// 均匀分布的随机数
-class Random
-{
-public:
- Random(int size) {
- this->size = 0;
- seeds.resize(size);
- }
-
- int random() {
- int x, i;
- if (seeds.size() == 0) return 0;
- if (size == 0) {
- for (i = 0; i < (int)seeds.size(); i++) {
- seeds[i] = i;
- }
- size = (int)seeds.size();
- }
- i = rand() % size;
- x = seeds[i];
- seeds[i] = seeds[--size];
- return x;
- }
-
-protected:
- int size;
- std::vector seeds;
-};
-
-// 网络延迟模拟器
-class LatencySimulator
-{
-public:
- virtual ~LatencySimulator() {
- clear();
- }
-
- // lostrate: 往返一周丢包率的百分比,默认 10%
- // rttmin:rtt最小值,默认 60
- // rttmax:rtt最大值,默认 125
- LatencySimulator(int lostrate = 10, int rttmin = 60, int rttmax = 125, int nmax = 1000):
- r12(100), r21(100) {
- current = iclock();
- this->lostrate = lostrate / 2; // 上面数据是往返丢包率,单程除以2
- this->rttmin = rttmin / 2;
- this->rttmax = rttmax / 2;
- this->nmax = nmax;
- }
-
- // 清除数据
- void clear() {
- DelayTunnel::iterator it;
- for (it = p12.begin(); it != p12.end(); it++) {
- delete *it;
- }
- for (it = p21.begin(); it != p21.end(); it++) {
- delete *it;
- }
- p12.clear();
- p21.clear();
- }
-
- // 发送数据
- // peer - 端点0/1,从0发送,从1接收;从1发送从0接收
- void send(int peer, const void *data, int size) {
- if (peer == 0) {
- if (r12.random() < lostrate) return;
- if ((int)p12.size() >= nmax) return;
- } else {
- if (r21.random() < lostrate) return;
- if ((int)p21.size() >= nmax) return;
- }
- DelayPacket *pkt = new DelayPacket(size, data);
- current = iclock();
- IUINT32 delay = rttmin;
- if (rttmax > rttmin) delay += rand() % (rttmax - rttmin);
- pkt->setts(current + delay);
- if (peer == 0) {
- p12.push_back(pkt);
- } else {
- p21.push_back(pkt);
- }
- }
-
- // 接收数据
- int recv(int peer, void *data, int maxsize) {
- DelayTunnel::iterator it;
- if (peer == 0) {
- it = p21.begin();
- if (p21.size() == 0) return -1;
- } else {
- it = p12.begin();
- if (p12.size() == 0) return -1;
- }
- DelayPacket *pkt = *it;
- current = iclock();
- if (current < pkt->ts()) return -2;
- if (maxsize < pkt->size()) return -3;
- if (peer == 0) {
- p21.erase(it);
- } else {
- p12.erase(it);
- }
- maxsize = pkt->size();
- memcpy(data, pkt->ptr(), maxsize);
- delete pkt;
- return maxsize;
- }
-
-protected:
- IUINT32 current;
- int lostrate;
- int rttmin;
- int rttmax;
- int nmax;
- typedef std::list DelayTunnel;
- DelayTunnel p12;
- DelayTunnel p21;
- Random r12;
- Random r21;
-};
-
-#endif
-
-#endif
-
-
diff --git a/3rd/lua/Makefile b/3rd/lua/Makefile
deleted file mode 100644
index 7fa91c8..0000000
--- a/3rd/lua/Makefile
+++ /dev/null
@@ -1,114 +0,0 @@
-# Makefile for installing Lua
-# See doc/readme.html for installation and customization instructions.
-
-# == CHANGE THE SETTINGS BELOW TO SUIT YOUR ENVIRONMENT =======================
-
-# Your platform. See PLATS for possible values.
-PLAT= none
-
-# Where to install. The installation starts in the src and doc directories,
-# so take care if INSTALL_TOP is not an absolute path. See the local target.
-# You may want to make INSTALL_LMOD and INSTALL_CMOD consistent with
-# LUA_ROOT, LUA_LDIR, and LUA_CDIR in luaconf.h.
-INSTALL_TOP= /usr/local
-INSTALL_BIN= $(INSTALL_TOP)/bin
-INSTALL_INC= $(INSTALL_TOP)/include
-INSTALL_LIB= $(INSTALL_TOP)/lib
-INSTALL_MAN= $(INSTALL_TOP)/man/man1
-INSTALL_LMOD= $(INSTALL_TOP)/share/lua/$V
-INSTALL_CMOD= $(INSTALL_TOP)/lib/lua/$V
-
-# How to install. If your install program does not support "-p", then
-# you may have to run ranlib on the installed liblua.a.
-INSTALL= install -p
-INSTALL_EXEC= $(INSTALL) -m 0755
-INSTALL_DATA= $(INSTALL) -m 0644
-#
-# If you don't have "install" you can use "cp" instead.
-# INSTALL= cp -p
-# INSTALL_EXEC= $(INSTALL)
-# INSTALL_DATA= $(INSTALL)
-
-# Other utilities.
-MKDIR= mkdir -p
-RM= rm -f
-
-# == END OF USER SETTINGS -- NO NEED TO CHANGE ANYTHING BELOW THIS LINE =======
-
-# Convenience platforms targets.
-PLATS= aix bsd c89 freebsd generic linux macosx mingw posix solaris
-
-# What to install.
-TO_BIN= lua luac
-TO_INC= lua.h luaconf.h lualib.h lauxlib.h lua.hpp
-TO_LIB= liblua.a
-TO_MAN= lua.1 luac.1
-
-# Lua version and release.
-V= 5.3
-R= $V.0
-
-# Targets start here.
-all: $(PLAT)
-
-$(PLATS) clean:
- cd src && $(MAKE) $@
-
-test: dummy
- src/lua -v
-
-install: dummy
- cd src && $(MKDIR) $(INSTALL_BIN) $(INSTALL_INC) $(INSTALL_LIB) $(INSTALL_MAN) $(INSTALL_LMOD) $(INSTALL_CMOD)
- cd src && $(INSTALL_EXEC) $(TO_BIN) $(INSTALL_BIN)
- cd src && $(INSTALL_DATA) $(TO_INC) $(INSTALL_INC)
- cd src && $(INSTALL_DATA) $(TO_LIB) $(INSTALL_LIB)
- cd doc && $(INSTALL_DATA) $(TO_MAN) $(INSTALL_MAN)
-
-uninstall:
- cd src && cd $(INSTALL_BIN) && $(RM) $(TO_BIN)
- cd src && cd $(INSTALL_INC) && $(RM) $(TO_INC)
- cd src && cd $(INSTALL_LIB) && $(RM) $(TO_LIB)
- cd doc && cd $(INSTALL_MAN) && $(RM) $(TO_MAN)
-
-local:
- $(MAKE) install INSTALL_TOP=../install
-
-none:
- @echo "Please do 'make PLATFORM' where PLATFORM is one of these:"
- @echo " $(PLATS)"
- @echo "See doc/readme.html for complete instructions."
-
-# make may get confused with test/ and install/
-dummy:
-
-# echo config parameters
-echo:
- @cd src && $(MAKE) -s echo
- @echo "PLAT= $(PLAT)"
- @echo "V= $V"
- @echo "R= $R"
- @echo "TO_BIN= $(TO_BIN)"
- @echo "TO_INC= $(TO_INC)"
- @echo "TO_LIB= $(TO_LIB)"
- @echo "TO_MAN= $(TO_MAN)"
- @echo "INSTALL_TOP= $(INSTALL_TOP)"
- @echo "INSTALL_BIN= $(INSTALL_BIN)"
- @echo "INSTALL_INC= $(INSTALL_INC)"
- @echo "INSTALL_LIB= $(INSTALL_LIB)"
- @echo "INSTALL_MAN= $(INSTALL_MAN)"
- @echo "INSTALL_LMOD= $(INSTALL_LMOD)"
- @echo "INSTALL_CMOD= $(INSTALL_CMOD)"
- @echo "INSTALL_EXEC= $(INSTALL_EXEC)"
- @echo "INSTALL_DATA= $(INSTALL_DATA)"
-
-# echo pkg-config data
-pc:
- @echo "version=$R"
- @echo "prefix=$(INSTALL_TOP)"
- @echo "libdir=$(INSTALL_LIB)"
- @echo "includedir=$(INSTALL_INC)"
-
-# list targets that do not create files (but not all makes understand .PHONY)
-.PHONY: all $(PLATS) clean test install local none dummy echo pecho lecho
-
-# (end of Makefile)
diff --git a/3rd/lua/README b/3rd/lua/README
deleted file mode 100644
index 32fb68e..0000000
--- a/3rd/lua/README
+++ /dev/null
@@ -1,6 +0,0 @@
-
-This is Lua 5.3.0, released on 06 Jan 2015.
-
-For installation instructions, license details, and
-further information about Lua, see doc/readme.html.
-
diff --git a/3rd/lua/doc/contents.html b/3rd/lua/doc/contents.html
deleted file mode 100644
index e59e421..0000000
--- a/3rd/lua/doc/contents.html
+++ /dev/null
@@ -1,619 +0,0 @@
-
-
-
-Lua 5.3 Reference Manual - contents
-
-
-
-
-
-
-
-
-
-
-Lua 5.3 Reference Manual
-
-
-
-The reference manual is the official definition of the Lua language.
-For a complete introduction to Lua programming, see the book
-Programming in Lua.
-
-
-
-
-
-Last update:
-Tue Dec 9 21:26:07 BRST 2014
-
-
-
-
-
diff --git a/3rd/lua/doc/logo.gif b/3rd/lua/doc/logo.gif
deleted file mode 100644
index 2f5e4ac..0000000
Binary files a/3rd/lua/doc/logo.gif and /dev/null differ
diff --git a/3rd/lua/doc/lua.1 b/3rd/lua/doc/lua.1
deleted file mode 100644
index 411531b..0000000
--- a/3rd/lua/doc/lua.1
+++ /dev/null
@@ -1,111 +0,0 @@
-.TH LUA 1 "$Date: 2014/12/10 15:55:45 $"
-.SH NAME
-lua \- Lua interpreter
-.SH SYNOPSIS
-.B lua
-[
-.I options
-]
-[
-.I script
-[
-.I args
-]
-]
-.SH DESCRIPTION
-.B lua
-is the standalone Lua interpreter.
-It loads and executes Lua programs,
-either in textual source form or
-in precompiled binary form.
-(Precompiled binaries are output by
-.BR luac ,
-the Lua compiler.)
-.B lua
-can be used as a batch interpreter and also interactively.
-.LP
-The given
-.I options
-are handled in order and then
-the Lua program in file
-.I script
-is loaded and executed.
-The given
-.I args
-are available to
-.I script
-as strings in a global table named
-.BR arg .
-If no options or arguments are given,
-then
-.B "\-v \-i"
-is assumed when the standard input is a terminal;
-otherwise,
-.B "\-"
-is assumed.
-.LP
-In interactive mode,
-.B lua
-prompts the user,
-reads lines from the standard input,
-and executes them as they are read.
-If the line contains an expression or list of expressions,
-then the line is evaluated and the results are printed.
-If a line does not contain a complete statement,
-then a secondary prompt is displayed and
-lines are read until a complete statement is formed or
-a syntax error is found.
-.LP
-At the very start,
-before even handling the command line,
-.B lua
-checks the contents of the environment variables
-.B LUA_INIT_5_3
-or
-.BR LUA_INIT ,
-in that order.
-If the contents is of the form
-.RI '@ filename ',
-then
-.I filename
-is executed.
-Otherwise, the string is assumed to be a Lua statement and is executed.
-.SH OPTIONS
-.TP
-.BI \-e " stat"
-execute statement
-.IR stat .
-.TP
-.B \-i
-enter interactive mode after executing
-.IR script .
-.TP
-.BI \-l " name"
-execute the equivalent of
-.IB name =require(' name ')
-before executing
-.IR script .
-.TP
-.B \-v
-show version information.
-.TP
-.B \-E
-ignore environment variables.
-.TP
-.B \-\-
-stop handling options.
-.TP
-.B \-
-stop handling options and execute the standard input as a file.
-.SH "SEE ALSO"
-.BR luac (1)
-.br
-The documentation at lua.org,
-especially section 7 of the reference manual.
-.SH DIAGNOSTICS
-Error messages should be self explanatory.
-.SH AUTHORS
-R. Ierusalimschy,
-L. H. de Figueiredo,
-W. Celes
-.\" EOF
diff --git a/3rd/lua/doc/lua.css b/3rd/lua/doc/lua.css
deleted file mode 100644
index 3199a2b..0000000
--- a/3rd/lua/doc/lua.css
+++ /dev/null
@@ -1,105 +0,0 @@
-html {
- background-color: #F8F8F8 ;
-}
-
-body {
- border: solid #a0a0a0 1px ;
- border-radius: 20px ;
- padding: 26px ;
- margin: 16px ;
- color: #000000 ;
- background-color: #FFFFFF ;
- font-family: Helvetica, Arial, sans-serif ;
- text-align: justify ;
-}
-
-h1, h2, h3, h4 {
- font-family: Verdana, Geneva, sans-serif ;
- font-weight: normal ;
- font-style: normal ;
-}
-
-h2 {
- padding-top: 0.4em ;
- padding-bottom: 0.4em ;
- padding-left: 0.8em ;
- padding-right: 0.8em ;
- background-color: #D0D0FF ;
- border-radius: 8px ;
- border: solid #a0a0a0 1px ;
-}
-
-h3 {
- padding-left: 0.5em ;
- border-left: solid #D0D0FF 1em ;
-}
-
-table h3 {
- padding-left: 0px ;
- border-left: none ;
-}
-
-a:link {
- color: #000080 ;
- background-color: inherit ;
- text-decoration: none ;
-}
-
-a:visited {
- background-color: inherit ;
- text-decoration: none ;
-}
-
-a:link:hover, a:visited:hover {
- color: #000080 ;
- background-color: #D0D0FF ;
- border-radius: 4px;
-}
-
-a:link:active, a:visited:active {
- color: #FF0000 ;
-}
-
-h1 a img {
- vertical-align: text-bottom ;
-}
-
-hr {
- border: 0 ;
- height: 1px ;
- color: #a0a0a0 ;
- background-color: #a0a0a0 ;
- display: none ;
-}
-
-table hr {
- display: block ;
-}
-
-:target {
- background-color: #F8F8F8 ;
- padding: 8px ;
- border: solid #a0a0a0 2px ;
- border-radius: 8px ;
-}
-
-.footer {
- color: gray ;
- font-size: x-small ;
-}
-
-input[type=text] {
- border: solid #a0a0a0 2px ;
- border-radius: 2em ;
- background-image: url('images/search.png') ;
- background-repeat: no-repeat ;
- background-position: 4px center ;
- padding-left: 20px ;
- height: 2em ;
-}
-
-pre.session {
- background-color: #F8F8F8 ;
- padding: 1em ;
- border-radius: 8px ;
-}
diff --git a/3rd/lua/doc/luac.1 b/3rd/lua/doc/luac.1
deleted file mode 100644
index 33a4ed0..0000000
--- a/3rd/lua/doc/luac.1
+++ /dev/null
@@ -1,118 +0,0 @@
-.\" $Id: luac.man,v 1.29 2011/11/16 13:53:40 lhf Exp $
-.TH LUAC 1 "$Date: 2011/11/16 13:53:40 $"
-.SH NAME
-luac \- Lua compiler
-.SH SYNOPSIS
-.B luac
-[
-.I options
-] [
-.I filenames
-]
-.SH DESCRIPTION
-.B luac
-is the Lua compiler.
-It translates programs written in the Lua programming language
-into binary files containing precompiled chunks
-that can be later loaded and executed.
-.LP
-The main advantages of precompiling chunks are:
-faster loading,
-protecting source code from accidental user changes,
-and
-off-line syntax checking.
-Precompiling does not imply faster execution
-because in Lua chunks are always compiled into bytecodes before being executed.
-.B luac
-simply allows those bytecodes to be saved in a file for later execution.
-Precompiled chunks are not necessarily smaller than the corresponding source.
-The main goal in precompiling is faster loading.
-.LP
-In the command line,
-you can mix
-text files containing Lua source and
-binary files containing precompiled chunks.
-.B luac
-produces a single output file containing the combined bytecodes
-for all files given.
-Executing the combined file is equivalent to executing the given files.
-By default,
-the output file is named
-.BR luac.out ,
-but you can change this with the
-.B \-o
-option.
-.LP
-Precompiled chunks are
-.I not
-portable across different architectures.
-Moreover,
-the internal format of precompiled chunks
-is likely to change when a new version of Lua is released.
-Make sure you save the source files of all Lua programs that you precompile.
-.LP
-.SH OPTIONS
-.TP
-.B \-l
-produce a listing of the compiled bytecode for Lua's virtual machine.
-Listing bytecodes is useful to learn about Lua's virtual machine.
-If no files are given, then
-.B luac
-loads
-.B luac.out
-and lists its contents.
-Use
-.B \-l \-l
-for a full listing.
-.TP
-.BI \-o " file"
-output to
-.IR file ,
-instead of the default
-.BR luac.out .
-(You can use
-.B "'\-'"
-for standard output,
-but not on platforms that open standard output in text mode.)
-The output file may be one of the given files because
-all files are loaded before the output file is written.
-Be careful not to overwrite precious files.
-.TP
-.B \-p
-load files but do not generate any output file.
-Used mainly for syntax checking and for testing precompiled chunks:
-corrupted files will probably generate errors when loaded.
-If no files are given, then
-.B luac
-loads
-.B luac.out
-and tests its contents.
-No messages are displayed if the file loads without errors.
-.TP
-.B \-s
-strip debug information before writing the output file.
-This saves some space in very large chunks,
-but if errors occur when running a stripped chunk,
-then the error messages may not contain the full information they usually do.
-In particular,
-line numbers and names of local variables are lost.
-.TP
-.B \-v
-show version information.
-.TP
-.B \-\-
-stop handling options.
-.TP
-.B \-
-stop handling options and process standard input.
-.SH "SEE ALSO"
-.BR lua (1)
-.br
-The documentation at lua.org.
-.SH DIAGNOSTICS
-Error messages should be self explanatory.
-.SH AUTHORS
-R. Ierusalimschy,
-L. H. de Figueiredo,
-W. Celes
-.\" EOF
diff --git a/3rd/lua/doc/manual.css b/3rd/lua/doc/manual.css
deleted file mode 100644
index ca613cd..0000000
--- a/3rd/lua/doc/manual.css
+++ /dev/null
@@ -1,27 +0,0 @@
-h3 code {
- font-family: inherit ;
- font-size: inherit ;
-}
-
-pre, code {
- font-size: 12pt ;
-}
-
-span.apii {
- float: right ;
- font-family: inherit ;
- font-style: normal ;
- font-size: small ;
- color: gray ;
-}
-
-p+h1, ul+h1 {
- font-style: normal ;
- padding-top: 0.4em ;
- padding-bottom: 0.4em ;
- padding-left: 16px ;
- margin-left: -16px ;
- background-color: #D0D0FF ;
- border-radius: 8px ;
- border: solid #000080 1px ;
-}
diff --git a/3rd/lua/doc/manual.html b/3rd/lua/doc/manual.html
deleted file mode 100644
index 5ed8f06..0000000
--- a/3rd/lua/doc/manual.html
+++ /dev/null
@@ -1,10789 +0,0 @@
-
-
-
-
-Lua 5.3 Reference Manual
-
-
-
-
-
-
-
-
-
-Lua is an extension programming language designed to support
-general procedural programming with data description
-facilities.
-Lua also offers good support for object-oriented programming,
-functional programming, and data-driven programming.
-Lua is intended to be used as a powerful, lightweight,
-embeddable scripting language for any program that needs one.
-Lua is implemented as a library, written in clean C,
-the common subset of Standard C and C++.
-
-
-
-As an extension language, Lua has no notion of a "main" program:
-it only works embedded in a host client,
-called the embedding program or simply the host.
-The host program can invoke functions to execute a piece of Lua code,
-can write and read Lua variables,
-and can register C functions to be called by Lua code.
-Through the use of C functions, Lua can be augmented to cope with
-a wide range of different domains,
-thus creating customized programming languages sharing a syntactical framework.
-The Lua distribution includes a sample host program called lua,
-which uses the Lua library to offer a complete, standalone Lua interpreter,
-for interactive or batch use.
-
-
-
-Lua is free software,
-and is provided as usual with no guarantees,
-as stated in its license.
-The implementation described in this manual is available
-at Lua's official web site, www.lua.org.
-
-
-
-Like any other reference manual,
-this document is dry in places.
-For a discussion of the decisions behind the design of Lua,
-see the technical papers available at Lua's web site.
-For a detailed introduction to programming in Lua,
-see Roberto's book, Programming in Lua.
-
-
-
-
-Lua is a dynamically typed language.
-This means that
-variables do not have types; only values do.
-There are no type definitions in the language.
-All values carry their own type.
-
-
-
-All values in Lua are first-class values.
-This means that all values can be stored in variables,
-passed as arguments to other functions, and returned as results.
-
-
-
-There are eight basic types in Lua:
-nil, boolean, number,
-string, function, userdata,
-thread, and table.
-Nil is the type of the value nil,
-whose main property is to be different from any other value;
-it usually represents the absence of a useful value.
-Boolean is the type of the values false and true.
-Both nil and false make a condition false;
-any other value makes it true.
-Number represents both
-integer numbers and real (floating-point) numbers.
-String represents immutable sequences of bytes.
-
-Lua is 8-bit clean:
-strings can contain any 8-bit value,
-including embedded zeros ('\0').
-Lua is also encoding-agnostic;
-it makes no assumptions about the contents of a string.
-
-
-
-The type number uses two internal representations,
-one called integer and the other called float.
-Lua has explicit rules about when each representation is used,
-but it also converts between them automatically as needed (see §3.4.3).
-Therefore,
-the programmer may choose to mostly ignore the difference
-between integers and floats
-or to assume complete control over the representation of each number.
-Standard Lua uses 64-bit integers and double-precision (64-bit) floats,
-but you can also compile Lua so that it
-uses 32-bit integers and/or single-precision (32-bit) floats.
-The option with 32 bits for both integers and floats
-is particularly attractive
-for small machines and embedded systems.
-(See macro LUA_32BITS in file luaconf.h.)
-
-
-
-Lua can call (and manipulate) functions written in Lua and
-functions written in C (see §3.4.10).
-Both are represented by the type function.
-
-
-
-The type userdata is provided to allow arbitrary C data to
-be stored in Lua variables.
-A userdata value represents a block of raw memory.
-There are two kinds of userdata:
-full userdata,
-which is an object with a block of memory managed by Lua,
-and light userdata,
-which is simply a C pointer value.
-Userdata has no predefined operations in Lua,
-except assignment and identity test.
-By using metatables,
-the programmer can define operations for full userdata values
-(see §2.4).
-Userdata values cannot be created or modified in Lua,
-only through the C API.
-This guarantees the integrity of data owned by the host program.
-
-
-
-The type thread represents independent threads of execution
-and it is used to implement coroutines (see §2.6).
-Lua threads are not related to operating-system threads.
-Lua supports coroutines on all systems,
-even those that do not support threads natively.
-
-
-
-The type table implements associative arrays,
-that is, arrays that can be indexed not only with numbers,
-but with any Lua value except nil and NaN.
-(Not a Number is a special numeric value used to represent
-undefined or unrepresentable results, such as 0/0.)
-Tables can be heterogeneous;
-that is, they can contain values of all types (except nil).
-Any key with value nil is not considered part of the table.
-Conversely, any key that is not part of a table has
-an associated value nil.
-
-
-
-Tables are the sole data-structuring mechanism in Lua;
-they can be used to represent ordinary arrays, sequences,
-symbol tables, sets, records, graphs, trees, etc.
-To represent records, Lua uses the field name as an index.
-The language supports this representation by
-providing a.name as syntactic sugar for a["name"].
-There are several convenient ways to create tables in Lua
-(see §3.4.9).
-
-
-
-We use the term sequence to denote a table where
-the set of all positive numeric keys is equal to {1..n}
-for some non-negative integer n,
-which is called the length of the sequence (see §3.4.7).
-
-
-
-Like indices,
-the values of table fields can be of any type.
-In particular,
-because functions are first-class values,
-table fields can contain functions.
-Thus tables can also carry methods (see §3.4.11).
-
-
-
-The indexing of tables follows
-the definition of raw equality in the language.
-The expressions a[i] and a[j]
-denote the same table element
-if and only if i and j are raw equal
-(that is, equal without metamethods).
-In particular, floats with integral values
-are equal to their respective integers
-(e.g., 1.0 == 1).
-To avoid ambiguities,
-any float with integral value used as a key
-is converted to its respective integer.
-For instance, if you write a[2.0] = true,
-the actual key inserted into the table will be the
-integer 2.
-(On the other hand,
-2 and "2" are different Lua values and therefore
-denote different table entries.)
-
-
-
-Tables, functions, threads, and (full) userdata values are objects:
-variables do not actually contain these values,
-only references to them.
-Assignment, parameter passing, and function returns
-always manipulate references to such values;
-these operations do not imply any kind of copy.
-
-
-
-The library function type returns a string describing the type
-of a given value (see §6.1).
-
-
-
-
-
-
-As will be discussed in §3.2 and §3.3.3,
-any reference to a free name
-(that is, a name not bound to any declaration) var
-is syntactically translated to _ENV.var.
-Moreover, every chunk is compiled in the scope of
-an external local variable named _ENV (see §3.3.2),
-so _ENV itself is never a free name in a chunk.
-
-
-
-Despite the existence of this external _ENV variable and
-the translation of free names,
-_ENV is a completely regular name.
-In particular,
-you can define new variables and parameters with that name.
-Each reference to a free name uses the _ENV that is
-visible at that point in the program,
-following the usual visibility rules of Lua (see §3.5).
-
-
-
-Any table used as the value of _ENV is called an environment.
-
-
-
-Lua keeps a distinguished environment called the global environment.
-This value is kept at a special index in the C registry (see §4.5).
-In Lua, the global variable _G is initialized with this same value.
-(_G is never used internally.)
-
-
-
-When Lua loads a chunk,
-the default value for its _ENV upvalue
-is the global environment (see load).
-Therefore, by default,
-free names in Lua code refer to entries in the global environment
-(and, therefore, they are also called global variables).
-Moreover, all standard libraries are loaded in the global environment
-and some functions there operate on that environment.
-You can use load (or loadfile)
-to load a chunk with a different environment.
-(In C, you have to load the chunk and then change the value
-of its first upvalue.)
-
-
-
-
-
-
-Because Lua is an embedded extension language,
-all Lua actions start from C code in the host program
-calling a function from the Lua library.
-(When you use Lua standalone,
-the lua application is the host program.)
-Whenever an error occurs during
-the compilation or execution of a Lua chunk,
-control returns to the host,
-which can take appropriate measures
-(such as printing an error message).
-
-
-
-Lua code can explicitly generate an error by calling the
-error function.
-If you need to catch errors in Lua,
-you can use pcall or xpcall
-to call a given function in protected mode.
-
-
-
-Whenever there is an error,
-an error object (also called an error message)
-is propagated with information about the error.
-Lua itself only generates errors whose error object is a string,
-but programs may generate errors with
-any value as the error object.
-It is up to the Lua program or its host to handle such error objects.
-
-
-
-When you use xpcall or lua_pcall,
-you may give a message handler
-to be called in case of errors.
-This function is called with the original error message
-and returns a new error message.
-It is called before the error unwinds the stack,
-so that it can gather more information about the error,
-for instance by inspecting the stack and creating a stack traceback.
-This message handler is still protected by the protected call;
-so, an error inside the message handler
-will call the message handler again.
-If this loop goes on for too long,
-Lua breaks it and returns an appropriate message.
-
-
-
-
-
-
-Every value in Lua can have a metatable.
-This metatable is an ordinary Lua table
-that defines the behavior of the original value
-under certain special operations.
-You can change several aspects of the behavior
-of operations over a value by setting specific fields in its metatable.
-For instance, when a non-numeric value is the operand of an addition,
-Lua checks for a function in the field "__add" of the value's metatable.
-If it finds one,
-Lua calls this function to perform the addition.
-
-
-
-The keys in a metatable are derived from the event names;
-the corresponding values are called metamethods.
-In the previous example, the event is "add"
-and the metamethod is the function that performs the addition.
-
-
-
-You can query the metatable of any value
-using the getmetatable function.
-
-
-
-You can replace the metatable of tables
-using the setmetatable function.
-You cannot change the metatable of other types from Lua
-(except by using the debug library (§6.10));
-you must use the C API for that.
-
-
-
-Tables and full userdata have individual metatables
-(although multiple tables and userdata can share their metatables).
-Values of all other types share one single metatable per type;
-that is, there is one single metatable for all numbers,
-one for all strings, etc.
-By default, a value has no metatable,
-but the string library sets a metatable for the string type (see §6.4).
-
-
-
-A metatable controls how an object behaves in
-arithmetic operations, bitwise operations,
-order comparisons, concatenation, length operation, calls, and indexing.
-A metatable also can define a function to be called
-when a userdata or a table is garbage collected (§2.5).
-
-
-
-A detailed list of events controlled by metatables is given next.
-Each operation is identified by its corresponding event name.
-The key for each event is a string with its name prefixed by
-two underscores, '__';
-for instance, the key for operation "add" is the
-string "__add".
-Note that queries for metamethods are always raw;
-the access to a metamethod does not invoke other metamethods.
-You can emulate how Lua queries a metamethod for an object obj
-with the following code:
-
-
- rawget(getmetatable(obj) or {}, "__" .. event_name)
-
-
-
-For the unary operators (negation, length, and bitwise not),
-the metamethod is computed and called with a dummy second operand,
-equal to the first one.
-This extra operand is only to simplify Lua's internals
-(by making these operators behave like a binary operation)
-and may be removed in future versions.
-(For most uses this extra operand is irrelevant.)
-
-
-
-
-
-
"add":
-the + operation.
-
-If any operand for an addition is not a number
-(nor a string coercible to a number),
-Lua will try to call a metamethod.
-First, Lua will check the first operand (even if it is valid).
-If that operand does not define a metamethod for the "__add" event,
-then Lua will check the second operand.
-If Lua can find a metamethod,
-it calls the metamethod with the two operands as arguments,
-and the result of the call
-(adjusted to one value)
-is the result of the operation.
-Otherwise,
-it raises an error.
-
-
-
"sub":
-the - operation.
-
-Behavior similar to the "add" operation.
-
-
-
"mul":
-the * operation.
-
-Behavior similar to the "add" operation.
-
-
-
"div":
-the / operation.
-
-Behavior similar to the "add" operation.
-
-
-
"mod":
-the % operation.
-
-Behavior similar to the "add" operation.
-
-
-
"pow":
-the ^ (exponentiation) operation.
-
-Behavior similar to the "add" operation.
-
-
-
"unm":
-the - (unary minus) operation.
-
-Behavior similar to the "add" operation.
-
-
-
"idiv":
-the // (floor division) operation.
-
-Behavior similar to the "add" operation.
-
-
-
"band":
-the & (bitwise and) operation.
-
-Behavior similar to the "add" operation,
-except that Lua will try a metamethod
-if any operator is neither an integer
-nor a value coercible to an integer (see §3.4.3).
-
-
-
"bor":
-the | (bitwise or) operation.
-
-Behavior similar to the "band" operation.
-
-
-
"bxor":
-the ~ (bitwise exclusive or) operation.
-
-Behavior similar to the "band" operation.
-
-
-
"bnot":
-the ~ (bitwise unary not) operation.
-
-Behavior similar to the "band" operation.
-
-
-
"shl":
-the << (bitwise left shift) operation.
-
-Behavior similar to the "band" operation.
-
-
-
"shr":
-the >> (bitwise right shift) operation.
-
-Behavior similar to the "band" operation.
-
-
-
"concat":
-the .. (concatenation) operation.
-
-Behavior similar to the "add" operation,
-except that Lua will try a metamethod
-if any operator is neither a string nor a number
-(which is always coercible to a string).
-
-
-
"len":
-the # (length) operation.
-
-If the object is not a string,
-Lua will try its metamethod.
-If there is a metamethod,
-Lua calls it with the object as argument,
-and the result of the call
-(always adjusted to one value)
-is the result of the operation.
-If there is no metamethod but the object is a table,
-then Lua uses the table length operation (see §3.4.7).
-Otherwise, Lua raises an error.
-
-
-
"eq":
-the == (equal) operation.
-
-Behavior similar to the "add" operation,
-except that Lua will try a metamethod only when the values
-being compared are either both tables or both full userdata
-and they are not primitively equal.
-The result of the call is always converted to a boolean.
-
-
-
"lt":
-the < (less than) operation.
-
-Behavior similar to the "add" operation,
-except that Lua will try a metamethod only when the values
-being compared are neither both numbers nor both strings.
-The result of the call is always converted to a boolean.
-
-
-
"le":
-the <= (less equal) operation.
-
-Unlike other operations,
-The less-equal operation can use two different events.
-First, Lua looks for the "__le" metamethod in both operands,
-like in the "lt" operation.
-If it cannot find such a metamethod,
-then it will try the "__lt" event,
-assuming that a <= b is equivalent to not (b < a).
-As with the other comparison operators,
-the result is always a boolean.
-
-
-
"index":
-The indexing access table[key].
-
-This event happens when table is not a table or
-when key is not present in table.
-The metamethod is looked up in table.
-
-
-
-Despite the name,
-the metamethod for this event can be either a function or a table.
-If it is a function,
-it is called with table and key as arguments.
-If it is a table,
-the final result is the result of indexing this table with key.
-(This indexing is regular, not raw,
-and therefore can trigger another metamethod.)
-
-
-
"newindex":
-The indexing assignment table[key] = value.
-
-Like the index event,
-this event happens when table is not a table or
-when key is not present in table.
-The metamethod is looked up in table.
-
-
-
-Like with indexing,
-the metamethod for this event can be either a function or a table.
-If it is a function,
-it is called with table, key, and value as arguments.
-If it is a table,
-Lua does an indexing assignment to this table with the same key and value.
-(This assignment is regular, not raw,
-and therefore can trigger another metamethod.)
-
-
-
-Whenever there is a "newindex" metamethod,
-Lua does not perform the primitive assignment.
-(If necessary,
-the metamethod itself can call rawset
-to do the assignment.)
-
-
-
"call":
-The call operation func(args).
-
-This event happens when Lua tries to call a non-function value
-(that is, func is not a function).
-The metamethod is looked up in func.
-If present,
-the metamethod is called with func as its first argument,
-followed by the arguments of the original call (args).
-
-Lua performs automatic memory management.
-This means that
-you do not have to worry about allocating memory for new objects
-or freeing it when the objects are no longer needed.
-Lua manages memory automatically by running
-a garbage collector to collect all dead objects
-(that is, objects that are no longer accessible from Lua).
-All memory used by Lua is subject to automatic management:
-strings, tables, userdata, functions, threads, internal structures, etc.
-
-
-
-Lua implements an incremental mark-and-sweep collector.
-It uses two numbers to control its garbage-collection cycles:
-the garbage-collector pause and
-the garbage-collector step multiplier.
-Both use percentage points as units
-(e.g., a value of 100 means an internal value of 1).
-
-
-
-The garbage-collector pause
-controls how long the collector waits before starting a new cycle.
-Larger values make the collector less aggressive.
-Values smaller than 100 mean the collector will not wait to
-start a new cycle.
-A value of 200 means that the collector waits for the total memory in use
-to double before starting a new cycle.
-
-
-
-The garbage-collector step multiplier
-controls the relative speed of the collector relative to
-memory allocation.
-Larger values make the collector more aggressive but also increase
-the size of each incremental step.
-You should not use values smaller than 100,
-because they make the collector too slow and
-can result in the collector never finishing a cycle.
-The default is 200,
-which means that the collector runs at "twice"
-the speed of memory allocation.
-
-
-
-If you set the step multiplier to a very large number
-(larger than 10% of the maximum number of
-bytes that the program may use),
-the collector behaves like a stop-the-world collector.
-If you then set the pause to 200,
-the collector behaves as in old Lua versions,
-doing a complete collection every time Lua doubles its
-memory usage.
-
-
-
-You can change these numbers by calling lua_gc in C
-or collectgarbage in Lua.
-You can also use these functions to control
-the collector directly (e.g., stop and restart it).
-
-
-
-
-You can set garbage-collector metamethods for tables
-and, using the C API,
-for full userdata (see §2.4).
-These metamethods are also called finalizers.
-Finalizers allow you to coordinate Lua's garbage collection
-with external resource management
-(such as closing files, network or database connections,
-or freeing your own memory).
-
-
-
-For an object (table or userdata) to be finalized when collected,
-you must mark it for finalization.
-
-You mark an object for finalization when you set its metatable
-and the metatable has a field indexed by the string "__gc".
-Note that if you set a metatable without a __gc field
-and later create that field in the metatable,
-the object will not be marked for finalization.
-However, after an object has been marked,
-you can freely change the __gc field of its metatable.
-
-
-
-When a marked object becomes garbage,
-it is not collected immediately by the garbage collector.
-Instead, Lua puts it in a list.
-After the collection,
-Lua goes through that list.
-For each object in the list,
-it checks the object's __gc metamethod:
-If it is a function,
-Lua calls it with the object as its single argument;
-if the metamethod is not a function,
-Lua simply ignores it.
-
-
-
-At the end of each garbage-collection cycle,
-the finalizers for objects are called in
-the reverse order that the objects were marked for finalization,
-among those collected in that cycle;
-that is, the first finalizer to be called is the one associated
-with the object marked last in the program.
-The execution of each finalizer may occur at any point during
-the execution of the regular code.
-
-
-
-Because the object being collected must still be used by the finalizer,
-that object (and other objects accessible only through it)
-must be resurrected by Lua.
-Usually, this resurrection is transient,
-and the object memory is freed in the next garbage-collection cycle.
-However, if the finalizer stores the object in some global place
-(e.g., a global variable),
-then the resurrection is permanent.
-Moreover, if the finalizer marks a finalizing object for finalization again,
-its finalizer will be called again in the next cycle where the
-object is unreachable.
-In any case,
-the object memory is freed only in the GC cycle where
-the object is unreachable and not marked for finalization.
-
-
-
-When you close a state (see lua_close),
-Lua calls the finalizers of all objects marked for finalization,
-following the reverse order that they were marked.
-If any finalizer marks objects for collection during that phase,
-these marks have no effect.
-
-
-
-
-
-
-A weak table is a table whose elements are
-weak references.
-A weak reference is ignored by the garbage collector.
-In other words,
-if the only references to an object are weak references,
-then the garbage collector will collect that object.
-
-
-
-A weak table can have weak keys, weak values, or both.
-A table with weak keys allows the collection of its keys,
-but prevents the collection of its values.
-A table with both weak keys and weak values allows the collection of
-both keys and values.
-In any case, if either the key or the value is collected,
-the whole pair is removed from the table.
-The weakness of a table is controlled by the
-__mode field of its metatable.
-If the __mode field is a string containing the character 'k',
-the keys in the table are weak.
-If __mode contains 'v',
-the values in the table are weak.
-
-
-
-A table with weak keys and strong values
-is also called an ephemeron table.
-In an ephemeron table,
-a value is considered reachable only if its key is reachable.
-In particular,
-if the only reference to a key comes through its value,
-the pair is removed.
-
-
-
-Any change in the weakness of a table may take effect only
-at the next collect cycle.
-In particular, if you change the weakness to a stronger mode,
-Lua may still collect some items from that table
-before the change takes effect.
-
-
-
-Only objects that have an explicit construction
-are removed from weak tables.
-Values, such as numbers and light C functions,
-are not subject to garbage collection,
-and therefore are not removed from weak tables
-(unless their associated values are collected).
-Although strings are subject to garbage collection,
-they do not have an explicit construction,
-and therefore are not removed from weak tables.
-
-
-
-Resurrected objects
-(that is, objects being finalized
-and objects accessible only through objects being finalized)
-have a special behavior in weak tables.
-They are removed from weak values before running their finalizers,
-but are removed from weak keys only in the next collection
-after running their finalizers, when such objects are actually freed.
-This behavior allows the finalizer to access properties
-associated with the object through weak tables.
-
-
-
-If a weak table is among the resurrected objects in a collection cycle,
-it may not be properly cleared until the next cycle.
-
-
-
-
-
-
-
-
-Lua supports coroutines,
-also called collaborative multithreading.
-A coroutine in Lua represents an independent thread of execution.
-Unlike threads in multithread systems, however,
-a coroutine only suspends its execution by explicitly calling
-a yield function.
-
-
-
-You create a coroutine by calling coroutine.create.
-Its sole argument is a function
-that is the main function of the coroutine.
-The create function only creates a new coroutine and
-returns a handle to it (an object of type thread);
-it does not start the coroutine.
-
-
-
-You execute a coroutine by calling coroutine.resume.
-When you first call coroutine.resume,
-passing as its first argument
-a thread returned by coroutine.create,
-the coroutine starts its execution,
-at the first line of its main function.
-Extra arguments passed to coroutine.resume are passed
-as arguments to the coroutine's main function.
-After the coroutine starts running,
-it runs until it terminates or yields.
-
-
-
-A coroutine can terminate its execution in two ways:
-normally, when its main function returns
-(explicitly or implicitly, after the last instruction);
-and abnormally, if there is an unprotected error.
-In case of normal termination,
-coroutine.resume returns true,
-plus any values returned by the coroutine main function.
-In case of errors, coroutine.resume returns false
-plus an error message.
-
-
-
-A coroutine yields by calling coroutine.yield.
-When a coroutine yields,
-the corresponding coroutine.resume returns immediately,
-even if the yield happens inside nested function calls
-(that is, not in the main function,
-but in a function directly or indirectly called by the main function).
-In the case of a yield, coroutine.resume also returns true,
-plus any values passed to coroutine.yield.
-The next time you resume the same coroutine,
-it continues its execution from the point where it yielded,
-with the call to coroutine.yield returning any extra
-arguments passed to coroutine.resume.
-
-
-
-Like coroutine.create,
-the coroutine.wrap function also creates a coroutine,
-but instead of returning the coroutine itself,
-it returns a function that, when called, resumes the coroutine.
-Any arguments passed to this function
-go as extra arguments to coroutine.resume.
-coroutine.wrap returns all the values returned by coroutine.resume,
-except the first one (the boolean error code).
-Unlike coroutine.resume,
-coroutine.wrap does not catch errors;
-any error is propagated to the caller.
-
-
-
-As an example of how coroutines work,
-consider the following code:
-
-
- function foo (a)
- print("foo", a)
- return coroutine.yield(2*a)
- end
-
- co = coroutine.create(function (a,b)
- print("co-body", a, b)
- local r = foo(a+1)
- print("co-body", r)
- local r, s = coroutine.yield(a+b, a-b)
- print("co-body", r, s)
- return b, "end"
- end)
-
- print("main", coroutine.resume(co, 1, 10))
- print("main", coroutine.resume(co, "r"))
- print("main", coroutine.resume(co, "x", "y"))
- print("main", coroutine.resume(co, "x", "y"))
-
-When you run it, it produces the following output:
-
-
- co-body 1 10
- foo 2
- main true 4
- co-body r
- main true 11 -9
- co-body x y
- main true 10 end
- main false cannot resume dead coroutine
-
-
-
-You can also create and manipulate coroutines through the C API:
-see functions lua_newthread, lua_resume,
-and lua_yield.
-
-
-
-
-
-
-This section describes the lexis, the syntax, and the semantics of Lua.
-In other words,
-this section describes
-which tokens are valid,
-how they can be combined,
-and what their combinations mean.
-
-
-
-Language constructs will be explained using the usual extended BNF notation,
-in which
-{a} means 0 or more a's, and
-[a] means an optional a.
-Non-terminals are shown like non-terminal,
-keywords are shown like kword,
-and other terminal symbols are shown like ‘=’.
-The complete syntax of Lua can be found in §9
-at the end of this manual.
-
-
-
-
-Lua is a free-form language.
-It ignores spaces (including new lines) and comments
-between lexical elements (tokens),
-except as delimiters between names and keywords.
-
-
-
-Names
-(also called identifiers)
-in Lua can be any string of letters,
-digits, and underscores,
-not beginning with a digit.
-Identifiers are used to name variables, table fields, and labels.
-
-
-
-The following keywords are reserved
-and cannot be used as names:
-
-
-
- and break do else elseif end
- false for function goto if in
- local nil not or repeat return
- then true until while
-
-
-
-Lua is a case-sensitive language:
-and is a reserved word, but And and AND
-are two different, valid names.
-As a convention,
-programs should avoid creating
-names that start with an underscore followed by
-one or more uppercase letters (such as _VERSION).
-
-
-
-Literal strings
-can be delimited by matching single or double quotes,
-and can contain the following C-like escape sequences:
-'\a' (bell),
-'\b' (backspace),
-'\f' (form feed),
-'\n' (newline),
-'\r' (carriage return),
-'\t' (horizontal tab),
-'\v' (vertical tab),
-'\\' (backslash),
-'\"' (quotation mark [double quote]),
-and '\'' (apostrophe [single quote]).
-A backslash followed by a real newline
-results in a newline in the string.
-The escape sequence '\z' skips the following span
-of white-space characters,
-including line breaks;
-it is particularly useful to break and indent a long literal string
-into multiple lines without adding the newlines and spaces
-into the string contents.
-
-
-
-Strings in Lua can contain any 8-bit value, including embedded zeros,
-which can be specified as '\0'.
-More generally,
-we can specify any byte in a literal string by its numerical value.
-This can be done
-with the escape sequence \xXX,
-where XX is a sequence of exactly two hexadecimal digits,
-or with the escape sequence \ddd,
-where ddd is a sequence of up to three decimal digits.
-(Note that if a decimal escape sequence is to be followed by a digit,
-it must be expressed using exactly three digits.)
-
-
-
-The UTF-8 encoding of a Unicode character
-can be inserted in a literal string with
-the escape sequence \u{XXX}
-(note the mandatory enclosing brackets),
-where XXX is a sequence of one or more hexadecimal digits
-representing the character code point.
-
-
-
-Literal strings can also be defined using a long format
-enclosed by long brackets.
-We define an opening long bracket of level n as an opening
-square bracket followed by n equal signs followed by another
-opening square bracket.
-So, an opening long bracket of level 0 is written as [[,
-an opening long bracket of level 1 is written as [=[,
-and so on.
-A closing long bracket is defined similarly;
-for instance,
-a closing long bracket of level 4 is written as ]====].
-A long literal starts with an opening long bracket of any level and
-ends at the first closing long bracket of the same level.
-It can contain any text except a closing bracket of the same level.
-Literals in this bracketed form can run for several lines,
-do not interpret any escape sequences,
-and ignore long brackets of any other level.
-Any kind of end-of-line sequence
-(carriage return, newline, carriage return followed by newline,
-or newline followed by carriage return)
-is converted to a simple newline.
-
-
-
-Any byte in a literal string not
-explicitly affected by the previous rules represents itself.
-However, Lua opens files for parsing in text mode,
-and the system file functions may have problems with
-some control characters.
-So, it is safer to represent
-non-text data as a quoted literal with
-explicit escape sequences for non-text characters.
-
-
-
-For convenience,
-when the opening long bracket is immediately followed by a newline,
-the newline is not included in the string.
-As an example, in a system using ASCII
-(in which 'a' is coded as 97,
-newline is coded as 10, and '1' is coded as 49),
-the five literal strings below denote the same string:
-
-
- a = 'alo\n123"'
- a = "alo\n123\""
- a = '\97lo\10\04923"'
- a = [[alo
- 123"]]
- a = [==[
- alo
- 123"]==]
-
-
-
-A numerical constant (or numeral)
-can be written with an optional fractional part
-and an optional decimal exponent,
-marked by a letter 'e' or 'E'.
-Lua also accepts hexadecimal constants,
-which start with 0x or 0X.
-Hexadecimal constants also accept an optional fractional part
-plus an optional binary exponent,
-marked by a letter 'p' or 'P'.
-A numeric constant with a fractional dot or an exponent
-denotes a float;
-otherwise it denotes an integer.
-Examples of valid integer constants are
-
-
-A comment starts with a double hyphen (--)
-anywhere outside a string.
-If the text immediately after -- is not an opening long bracket,
-the comment is a short comment,
-which runs until the end of the line.
-Otherwise, it is a long comment,
-which runs until the corresponding closing long bracket.
-Long comments are frequently used to disable code temporarily.
-
-
-
-
-
-
-Variables are places that store values.
-There are three kinds of variables in Lua:
-global variables, local variables, and table fields.
-
-
-
-A single name can denote a global variable or a local variable
-(or a function's formal parameter,
-which is a particular kind of local variable):
-
-
- var ::= Name
-
-Name denotes identifiers, as defined in §3.1.
-
-
-
-Any variable name is assumed to be global unless explicitly declared
-as a local (see §3.3.7).
-Local variables are lexically scoped:
-local variables can be freely accessed by functions
-defined inside their scope (see §3.5).
-
-
-
-Before the first assignment to a variable, its value is nil.
-
-
-
-Square brackets are used to index a table:
-
-
- var ::= prefixexp ‘[’ exp ‘]’
-
-The meaning of accesses to table fields can be changed via metatables.
-An access to an indexed variable t[i] is equivalent to
-a call gettable_event(t,i).
-(See §2.4 for a complete description of the
-gettable_event function.
-This function is not defined or callable in Lua.
-We use it here only for explanatory purposes.)
-
-
-
-The syntax var.Name is just syntactic sugar for
-var["Name"]:
-
-
- var ::= prefixexp ‘.’ Name
-
-
-
-An access to a global variable x
-is equivalent to _ENV.x.
-Due to the way that chunks are compiled,
-_ENV is never a global name (see §2.2).
-
-
-
-
-
-
-Lua supports an almost conventional set of statements,
-similar to those in Pascal or C.
-This set includes
-assignments, control structures, function calls,
-and variable declarations.
-
-
-
-
-A block is a list of statements,
-which are executed sequentially:
-
-
- block ::= {stat}
-
-Lua has empty statements
-that allow you to separate statements with semicolons,
-start a block with a semicolon
-or write two semicolons in sequence:
-
-
- stat ::= ‘;’
-
-
-
-Function calls and assignments
-can start with an open parenthesis.
-This possibility leads to an ambiguity in Lua's grammar.
-Consider the following fragment:
-
-
- a = b + c
- (print or io.write)('done')
-
-The grammar could see it in two ways:
-
-
- a = b + c(print or io.write)('done')
-
- a = b + c; (print or io.write)('done')
-
-The current parser always sees such constructions
-in the first way,
-interpreting the open parenthesis
-as the start of the arguments to a call.
-To avoid this ambiguity,
-it is a good practice to always precede with a semicolon
-statements that start with a parenthesis:
-
-
- ;(print or io.write)('done')
-
-
-
-A block can be explicitly delimited to produce a single statement:
-
-
- stat ::= do block end
-
-Explicit blocks are useful
-to control the scope of variable declarations.
-Explicit blocks are also sometimes used to
-add a return statement in the middle
-of another block (see §3.3.4).
-
-
-
-
-
-
-The unit of compilation of Lua is called a chunk.
-Syntactically,
-a chunk is simply a block:
-
-
- chunk ::= block
-
-
-
-Lua handles a chunk as the body of an anonymous function
-with a variable number of arguments
-(see §3.4.11).
-As such, chunks can define local variables,
-receive arguments, and return values.
-Moreover, such anonymous function is compiled as in the
-scope of an external local variable called _ENV (see §2.2).
-The resulting function always has _ENV as its only upvalue,
-even if it does not use that variable.
-
-
-
-A chunk can be stored in a file or in a string inside the host program.
-To execute a chunk,
-Lua first loads it,
-precompiling the chunk's code into instructions for a virtual machine,
-and then Lua executes the compiled code
-with an interpreter for the virtual machine.
-
-
-
-Chunks can also be precompiled into binary form;
-see program luac and function string.dump for details.
-Programs in source and compiled forms are interchangeable;
-Lua automatically detects the file type and acts accordingly (see load).
-
-
-
-
-
-
-Lua allows multiple assignments.
-Therefore, the syntax for assignment
-defines a list of variables on the left side
-and a list of expressions on the right side.
-The elements in both lists are separated by commas:
-
-
- stat ::= varlist ‘=’ explist
- varlist ::= var {‘,’ var}
- explist ::= exp {‘,’ exp}
-
-Before the assignment,
-the list of values is adjusted to the length of
-the list of variables.
-If there are more values than needed,
-the excess values are thrown away.
-If there are fewer values than needed,
-the list is extended with as many nil's as needed.
-If the list of expressions ends with a function call,
-then all values returned by that call enter the list of values,
-before the adjustment
-(except when the call is enclosed in parentheses; see §3.4).
-
-
-
-The assignment statement first evaluates all its expressions
-and only then the assignments are performed.
-Thus the code
-
-
- i = 3
- i, a[i] = i+1, 20
-
-sets a[3] to 20, without affecting a[4]
-because the i in a[i] is evaluated (to 3)
-before it is assigned 4.
-Similarly, the line
-
-
- x, y = y, x
-
-exchanges the values of x and y,
-and
-
-
- x, y, z = y, z, x
-
-cyclically permutes the values of x, y, and z.
-
-
-
-The meaning of assignments to global variables
-and table fields can be changed via metatables.
-An assignment to an indexed variable t[i] = val is equivalent to
-settable_event(t,i,val).
-(See §2.4 for a complete description of the
-settable_event function.
-This function is not defined or callable in Lua.
-We use it here only for explanatory purposes.)
-
-
-
-An assignment to a global name x = val
-is equivalent to the assignment
-_ENV.x = val (see §2.2).
-
-
-
-
-
-
-The control structures
-if, while, and repeat have the usual meaning and
-familiar syntax:
-
-
-
-
-
- stat ::= while exp do block end
- stat ::= repeat block until exp
- stat ::= if exp then block {elseif exp then block} [else block] end
-
-Lua also has a for statement, in two flavors (see §3.3.5).
-
-
-
-The condition expression of a
-control structure can return any value.
-Both false and nil are considered false.
-All values different from nil and false are considered true
-(in particular, the number 0 and the empty string are also true).
-
-
-
-In the repeat–until loop,
-the inner block does not end at the until keyword,
-but only after the condition.
-So, the condition can refer to local variables
-declared inside the loop block.
-
-
-
-The goto statement transfers the program control to a label.
-For syntactical reasons,
-labels in Lua are considered statements too:
-
-
-
-
- stat ::= goto Name
- stat ::= label
- label ::= ‘::’ Name ‘::’
-
-
-
-A label is visible in the entire block where it is defined,
-except
-inside nested blocks where a label with the same name is defined and
-inside nested functions.
-A goto may jump to any visible label as long as it does not
-enter into the scope of a local variable.
-
-
-
-Labels and empty statements are called void statements,
-as they perform no actions.
-
-
-
-The break statement terminates the execution of a
-while, repeat, or for loop,
-skipping to the next statement after the loop:
-
-
-
- stat ::= break
-
-A break ends the innermost enclosing loop.
-
-
-
-The return statement is used to return values
-from a function or a chunk
-(which is an anonymous function).
-
-Functions can return more than one value,
-so the syntax for the return statement is
-
-
- stat ::= return [explist] [‘;’]
-
-
-
-The return statement can only be written
-as the last statement of a block.
-If it is really necessary to return in the middle of a block,
-then an explicit inner block can be used,
-as in the idiom do return end,
-because now return is the last statement in its (inner) block.
-
-
-
-
-
-
-
-The for statement has two forms:
-one numeric and one generic.
-
-
-
-The numeric for loop repeats a block of code while a
-control variable runs through an arithmetic progression.
-It has the following syntax:
-
-
- stat ::= for Name ‘=’ exp ‘,’ exp [‘,’ exp] do block end
-
-The block is repeated for name starting at the value of
-the first exp, until it passes the second exp by steps of the
-third exp.
-More precisely, a for statement like
-
-
- for v = e1, e2, e3 do block end
-
-is equivalent to the code:
-
-
- do
- local var, limit, step = tonumber(e1), tonumber(e2), tonumber(e3)
- if not (var and limit and step) then error() end
- var = var - step
- while true do
- var = var + step
- if (step >= 0 and var > limit) or (step < 0 and var < limit) then
- break
- end
- local v = var
- block
- end
- end
-
-
-
-Note the following:
-
-
-
-
-All three control expressions are evaluated only once,
-before the loop starts.
-They must all result in numbers.
-
-
-
-var, limit, and step are invisible variables.
-The names shown here are for explanatory purposes only.
-
-
-
-If the third expression (the step) is absent,
-then a step of 1 is used.
-
-
-
-You can use break and goto to exit a for loop.
-
-
-
-The loop variable v is local to the loop body.
-If you need its value after the loop,
-assign it to another variable before exiting the loop.
-
-
-
-
-
-The generic for statement works over functions,
-called iterators.
-On each iteration, the iterator function is called to produce a new value,
-stopping when this new value is nil.
-The generic for loop has the following syntax:
-
-
- stat ::= for namelist in explist do block end
- namelist ::= Name {‘,’ Name}
-
-A for statement like
-
-
- for var_1, ···, var_n in explist do block end
-
-is equivalent to the code:
-
-
- do
- local f, s, var = explist
- while true do
- local var_1, ···, var_n = f(s, var)
- if var_1 == nil then break end
- var = var_1
- block
- end
- end
-
-Note the following:
-
-
-
-
-explist is evaluated only once.
-Its results are an iterator function,
-a state,
-and an initial value for the first iterator variable.
-
-
-
-f, s, and var are invisible variables.
-The names are here for explanatory purposes only.
-
-
-
-You can use break to exit a for loop.
-
-
-
-The loop variables var_i are local to the loop;
-you cannot use their values after the for ends.
-If you need these values,
-then assign them to other variables before breaking or exiting the loop.
-
-Local variables can be declared anywhere inside a block.
-The declaration can include an initial assignment:
-
-
- stat ::= local namelist [‘=’ explist]
-
-If present, an initial assignment has the same semantics
-of a multiple assignment (see §3.3.3).
-Otherwise, all variables are initialized with nil.
-
-
-
-A chunk is also a block (see §3.3.2),
-and so local variables can be declared in a chunk outside any explicit block.
-
-
-
-The visibility rules for local variables are explained in §3.5.
-
-
-
-
-
-
-
-
-Numerals and literal strings are explained in §3.1;
-variables are explained in §3.2;
-function definitions are explained in §3.4.11;
-function calls are explained in §3.4.10;
-table constructors are explained in §3.4.9.
-Vararg expressions,
-denoted by three dots ('...'), can only be used when
-directly inside a vararg function;
-they are explained in §3.4.11.
-
-
-
-Binary operators comprise arithmetic operators (see §3.4.1),
-bitwise operators (see §3.4.2),
-relational operators (see §3.4.4), logical operators (see §3.4.5),
-and the concatenation operator (see §3.4.6).
-Unary operators comprise the unary minus (see §3.4.1),
-the unary bitwise not (see §3.4.2),
-the unary logical not (see §3.4.5),
-and the unary length operator (see §3.4.7).
-
-
-
-Both function calls and vararg expressions can result in multiple values.
-If a function call is used as a statement (see §3.3.6),
-then its return list is adjusted to zero elements,
-thus discarding all returned values.
-If an expression is used as the last (or the only) element
-of a list of expressions,
-then no adjustment is made
-(unless the expression is enclosed in parentheses).
-In all other contexts,
-Lua adjusts the result list to one element,
-either discarding all values except the first one
-or adding a single nil if there are no values.
-
-
-
-Here are some examples:
-
-
- f() -- adjusted to 0 results
- g(f(), x) -- f() is adjusted to 1 result
- g(x, f()) -- g gets x plus all results from f()
- a,b,c = f(), x -- f() is adjusted to 1 result (c gets nil)
- a,b = ... -- a gets the first vararg parameter, b gets
- -- the second (both a and b can get nil if there
- -- is no corresponding vararg parameter)
-
- a,b,c = x, f() -- f() is adjusted to 2 results
- a,b,c = f() -- f() is adjusted to 3 results
- return f() -- returns all results from f()
- return ... -- returns all received vararg parameters
- return x,y,f() -- returns x, y, and all results from f()
- {f()} -- creates a list with all results from f()
- {...} -- creates a list with all vararg parameters
- {f(), nil} -- f() is adjusted to 1 result
-
-
-
-Any expression enclosed in parentheses always results in only one value.
-Thus,
-(f(x,y,z)) is always a single value,
-even if f returns several values.
-(The value of (f(x,y,z)) is the first value returned by f
-or nil if f does not return any values.)
-
-
-
-
-Lua supports the following arithmetic operators:
-
-
-
+: addition
-
-: subtraction
-
*: multiplication
-
/: float division
-
//: floor division
-
%: modulo
-
^: exponentiation
-
-: unary minus
-
-
-
-With the exception of exponentiation and float division,
-the arithmetic operators work as follows:
-If both operands are integers,
-the operation is performed over integers and the result is an integer.
-Otherwise, if both operands are numbers
-or strings that can be converted to
-numbers (see §3.4.3),
-then they are converted to floats,
-the operation is performed following the usual rules
-for floating-point arithmetic
-(usually the IEEE 754 standard),
-and the result is a float.
-
-
-
-Exponentiation and float division (/)
-always convert their operands to floats
-and the result is always a float.
-Exponentiation uses the ISO C function pow,
-so that it works for non-integer exponents too.
-
-
-
-Floor division (//) is a division
-that rounds the quotient towards minus infinite,
-that is, the floor of the division of its operands.
-
-
-
-Modulo is defined as the remainder of a division
-that rounds the quotient towards minus infinite (floor division).
-
-
-
-In case of overflows in integer arithmetic,
-all operations wrap around,
-according to the usual rules of two-complement arithmetic.
-(In other words,
-they return the unique representable integer
-that is equal modulo 264 to the mathematical result.)
-
-
-
-
-Lua supports the following bitwise operators:
-
-
-
&: bitwise and
-
|: bitwise or
-
~: bitwise exclusive or
-
>>: right shift
-
<<: left shift
-
~: unary bitwise not
-
-
-
-All bitwise operations convert its operands to integers
-(see §3.4.3),
-operate on all bits of those integers,
-and result in an integer.
-
-
-
-Both right and left shifts fill the vacant bits with zeros.
-Negative displacements shift to the other direction;
-displacements with absolute values equal to or higher than
-the number of bits in an integer
-result in zero (as all bits are shifted out).
-
-
-
-
-
-
-Lua provides some automatic conversions between some
-types and representations at run time.
-Bitwise operators always convert float operands to integers.
-Exponentiation and float division
-always convert integer operands to floats.
-All other arithmetic operations applied to mixed numbers
-(integers and floats) convert the integer operand to a float;
-this is called the usual rule.
-The C API also converts both integers to floats and
-floats to integers, as needed.
-Moreover, string concatenation accepts numbers as arguments,
-besides strings.
-
-
-
-Lua also converts strings to numbers,
-whenever a number is expected.
-
-
-
-In a conversion from integer to float,
-if the integer value has an exact representation as a float,
-that is the result.
-Otherwise,
-the conversion gets the nearest higher or
-the nearest lower representable value.
-This kind of conversion never fails.
-
-
-
-The conversion from float to integer
-checks whether the float has an exact representation as an integer
-(that is, the float has an integral value and
-it is in the range of integer representation).
-If it does, that representation is the result.
-Otherwise, the conversion fails.
-
-
-
-The conversion from strings to numbers goes as follows:
-First, the string is converted to an integer or a float,
-following its syntax and the rules of the Lua lexer.
-(The string may have also leading and trailing spaces and a sign.)
-Then, the resulting number is converted to the required type
-(float or integer) according to the previous rules.
-
-
-
-The conversion from numbers to strings uses a
-non-specified human-readable format.
-For complete control over how numbers are converted to strings,
-use the format function from the string library
-(see string.format).
-
-
-
-
-
-
-Lua supports the following relational operators:
-
-
-
==: equality
-
~=: inequality
-
<: less than
-
>: greater than
-
<=: less or equal
-
>=: greater or equal
-
-These operators always result in false or true.
-
-
-
-Equality (==) first compares the type of its operands.
-If the types are different, then the result is false.
-Otherwise, the values of the operands are compared.
-Strings are compared in the obvious way.
-Numbers follow the usual rule for binary operations:
-if both operands are integers,
-they are compared as integers;
-otherwise, they are converted to floats
-and compared as such.
-
-
-
-Tables, userdata, and threads
-are compared by reference:
-two objects are considered equal only if they are the same object.
-Every time you create a new object
-(a table, userdata, or thread),
-this new object is different from any previously existing object.
-Closures with the same reference are always equal.
-Closures with any detectable difference
-(different behavior, different definition) are always different.
-
-
-
-You can change the way that Lua compares tables and userdata
-by using the "eq" metamethod (see §2.4).
-
-
-
-Equality comparisons do not convert strings to numbers
-or vice versa.
-Thus, "0"==0 evaluates to false,
-and t[0] and t["0"] denote different
-entries in a table.
-
-
-
-The operator ~= is exactly the negation of equality (==).
-
-
-
-The order operators work as follows.
-If both arguments are numbers,
-then they are compared following
-the usual rule for binary operations.
-Otherwise, if both arguments are strings,
-then their values are compared according to the current locale.
-Otherwise, Lua tries to call the "lt" or the "le"
-metamethod (see §2.4).
-A comparison a > b is translated to b < a
-and a >= b is translated to b <= a.
-
-
-
-
-
-
-The logical operators in Lua are
-and, or, and not.
-Like the control structures (see §3.3.4),
-all logical operators consider both false and nil as false
-and anything else as true.
-
-
-
-The negation operator not always returns false or true.
-The conjunction operator and returns its first argument
-if this value is false or nil;
-otherwise, and returns its second argument.
-The disjunction operator or returns its first argument
-if this value is different from nil and false;
-otherwise, or returns its second argument.
-Both and and or use short-circuit evaluation;
-that is,
-the second operand is evaluated only if necessary.
-Here are some examples:
-
-
- 10 or 20 --> 10
- 10 or error() --> 10
- nil or "a" --> "a"
- nil and 10 --> nil
- false and error() --> false
- false and nil --> false
- false or nil --> nil
- 10 and 20 --> 20
-
-(In this manual,
---> indicates the result of the preceding expression.)
-
-
-
-
-
-
-The string concatenation operator in Lua is
-denoted by two dots ('..').
-If both operands are strings or numbers, then they are converted to
-strings according to the rules described in §3.4.3.
-Otherwise, the __concat metamethod is called (see §2.4).
-
-
-
-
-
-
-The length operator is denoted by the unary prefix operator #.
-The length of a string is its number of bytes
-(that is, the usual meaning of string length when each
-character is one byte).
-
-
-
-A program can modify the behavior of the length operator for
-any value but strings through the __len metamethod (see §2.4).
-
-
-
-Unless a __len metamethod is given,
-the length of a table t is only defined if the
-table is a sequence,
-that is,
-the set of its positive numeric keys is equal to {1..n}
-for some non-negative integer n.
-In that case, n is its length.
-Note that a table like
-
-
- {10, 20, nil, 40}
-
-is not a sequence, because it has the key 4
-but does not have the key 3.
-(So, there is no n such that the set {1..n} is equal
-to the set of positive numeric keys of that table.)
-Note, however, that non-numeric keys do not interfere
-with whether a table is a sequence.
-
-
-
-
-
-
-As usual,
-you can use parentheses to change the precedences of an expression.
-The concatenation ('..') and exponentiation ('^')
-operators are right associative.
-All other binary operators are left associative.
-
-
-
-
-
-
-Table constructors are expressions that create tables.
-Every time a constructor is evaluated, a new table is created.
-A constructor can be used to create an empty table
-or to create a table and initialize some of its fields.
-The general syntax for constructors is
-
-
-Each field of the form [exp1] = exp2 adds to the new table an entry
-with key exp1 and value exp2.
-A field of the form name = exp is equivalent to
-["name"] = exp.
-Finally, fields of the form exp are equivalent to
-[i] = exp, where i are consecutive integers
-starting with 1.
-Fields in the other formats do not affect this counting.
-For example,
-
-
- a = { [f(1)] = g; "x", "y"; x = 1, f(x), [30] = 23; 45 }
-
-is equivalent to
-
-
- do
- local t = {}
- t[f(1)] = g
- t[1] = "x" -- 1st exp
- t[2] = "y" -- 2nd exp
- t.x = 1 -- t["x"] = 1
- t[3] = f(x) -- 3rd exp
- t[30] = 23
- t[4] = 45 -- 4th exp
- a = t
- end
-
-
-
-The order of the assignments in a constructor is undefined.
-(This order would be relevant only when there are repeated keys.)
-
-
-
-If the last field in the list has the form exp
-and the expression is a function call or a vararg expression,
-then all values returned by this expression enter the list consecutively
-(see §3.4.10).
-
-
-
-The field list can have an optional trailing separator,
-as a convenience for machine-generated code.
-
-
-
-
-
-
-A function call in Lua has the following syntax:
-
-
- functioncall ::= prefixexp args
-
-In a function call,
-first prefixexp and args are evaluated.
-If the value of prefixexp has type function,
-then this function is called
-with the given arguments.
-Otherwise, the prefixexp "call" metamethod is called,
-having as first parameter the value of prefixexp,
-followed by the original call arguments
-(see §2.4).
-
-
-
-The form
-
-
- functioncall ::= prefixexp ‘:’ Name args
-
-can be used to call "methods".
-A call v:name(args)
-is syntactic sugar for v.name(v,args),
-except that v is evaluated only once.
-
-
-
-All argument expressions are evaluated before the call.
-A call of the form f{fields} is
-syntactic sugar for f({fields});
-that is, the argument list is a single new table.
-A call of the form f'string'
-(or f"string" or f[[string]])
-is syntactic sugar for f('string');
-that is, the argument list is a single literal string.
-
-
-
-A call of the form return functioncall is called
-a tail call.
-Lua implements proper tail calls
-(or proper tail recursion):
-in a tail call,
-the called function reuses the stack entry of the calling function.
-Therefore, there is no limit on the number of nested tail calls that
-a program can execute.
-However, a tail call erases any debug information about the
-calling function.
-Note that a tail call only happens with a particular syntax,
-where the return has one single function call as argument;
-this syntax makes the calling function return exactly
-the returns of the called function.
-So, none of the following examples are tail calls:
-
-
- return (f(x)) -- results adjusted to 1
- return 2 * f(x)
- return x, f(x) -- additional results
- f(x); return -- results discarded
- return x or f(x) -- results adjusted to 1
-
- functiondef ::= function funcbody
- funcbody ::= ‘(’ [parlist] ‘)’ block end
-
-
-
-The following syntactic sugar simplifies function definitions:
-
-
- stat ::= function funcname funcbody
- stat ::= localfunction Name funcbody
- funcname ::= Name {‘.’ Name} [‘:’ Name]
-
-The statement
-
-
- function f () body end
-
-translates to
-
-
- f = function () body end
-
-The statement
-
-
- function t.a.b.c.f () body end
-
-translates to
-
-
- t.a.b.c.f = function () body end
-
-The statement
-
-
- local function f () body end
-
-translates to
-
-
- local f; f = function () body end
-
-not to
-
-
- local f = function () body end
-
-(This only makes a difference when the body of the function
-contains references to f.)
-
-
-
-A function definition is an executable expression,
-whose value has type function.
-When Lua precompiles a chunk,
-all its function bodies are precompiled too.
-Then, whenever Lua executes the function definition,
-the function is instantiated (or closed).
-This function instance (or closure)
-is the final value of the expression.
-
-
-
-Parameters act as local variables that are
-initialized with the argument values:
-
-
- parlist ::= namelist [‘,’ ‘...’] | ‘...’
-
-When a function is called,
-the list of arguments is adjusted to
-the length of the list of parameters,
-unless the function is a vararg function,
-which is indicated by three dots ('...')
-at the end of its parameter list.
-A vararg function does not adjust its argument list;
-instead, it collects all extra arguments and supplies them
-to the function through a vararg expression,
-which is also written as three dots.
-The value of this expression is a list of all actual extra arguments,
-similar to a function with multiple results.
-If a vararg expression is used inside another expression
-or in the middle of a list of expressions,
-then its return list is adjusted to one element.
-If the expression is used as the last element of a list of expressions,
-then no adjustment is made
-(unless that last expression is enclosed in parentheses).
-
-
-
-As an example, consider the following definitions:
-
-
- function f(a, b) end
- function g(a, b, ...) end
- function r() return 1,2,3 end
-
-Then, we have the following mapping from arguments to parameters and
-to the vararg expression:
-
-
-Results are returned using the return statement (see §3.3.4).
-If control reaches the end of a function
-without encountering a return statement,
-then the function returns with no results.
-
-
-
-
-There is a system-dependent limit on the number of values
-that a function may return.
-This limit is guaranteed to be larger than 1000.
-
-
-
-The colon syntax
-is used for defining methods,
-that is, functions that have an implicit extra parameter self.
-Thus, the statement
-
-
-
-Lua is a lexically scoped language.
-The scope of a local variable begins at the first statement after
-its declaration and lasts until the last non-void statement
-of the innermost block that includes the declaration.
-Consider the following example:
-
-
- x = 10 -- global variable
- do -- new block
- local x = x -- new 'x', with value 10
- print(x) --> 10
- x = x+1
- do -- another block
- local x = x+1 -- another 'x'
- print(x) --> 12
- end
- print(x) --> 11
- end
- print(x) --> 10 (the global one)
-
-
-
-Notice that, in a declaration like local x = x,
-the new x being declared is not in scope yet,
-and so the second x refers to the outside variable.
-
-
-
-Because of the lexical scoping rules,
-local variables can be freely accessed by functions
-defined inside their scope.
-A local variable used by an inner function is called
-an upvalue, or external local variable,
-inside the inner function.
-
-
-
-Notice that each execution of a local statement
-defines new local variables.
-Consider the following example:
-
-
- a = {}
- local x = 20
- for i=1,10 do
- local y = 0
- a[i] = function () y=y+1; return x+y end
- end
-
-The loop creates ten closures
-(that is, ten instances of the anonymous function).
-Each of these closures uses a different y variable,
-while all of them share the same x.
-
-
-
-
-
-
-
-This section describes the C API for Lua, that is,
-the set of C functions available to the host program to communicate
-with Lua.
-All API functions and related types and constants
-are declared in the header file lua.h.
-
-
-
-Even when we use the term "function",
-any facility in the API may be provided as a macro instead.
-Except where stated otherwise,
-all such macros use each of their arguments exactly once
-(except for the first argument, which is always a Lua state),
-and so do not generate any hidden side-effects.
-
-
-
-As in most C libraries,
-the Lua API functions do not check their arguments for validity or consistency.
-However, you can change this behavior by compiling Lua
-with the macro LUA_USE_APICHECK defined.
-
-
-
-
-Lua uses a virtual stack to pass values to and from C.
-Each element in this stack represents a Lua value
-(nil, number, string, etc.).
-
-
-
-Whenever Lua calls C, the called function gets a new stack,
-which is independent of previous stacks and of stacks of
-C functions that are still active.
-This stack initially contains any arguments to the C function
-and it is where the C function pushes its results
-to be returned to the caller (see lua_CFunction).
-
-
-
-For convenience,
-most query operations in the API do not follow a strict stack discipline.
-Instead, they can refer to any element in the stack
-by using an index:
-A positive index represents an absolute stack position
-(starting at 1);
-a negative index represents an offset relative to the top of the stack.
-More specifically, if the stack has n elements,
-then index 1 represents the first element
-(that is, the element that was pushed onto the stack first)
-and
-index n represents the last element;
-index -1 also represents the last element
-(that is, the element at the top)
-and index -n represents the first element.
-
-
-
-
-
-
-When you interact with the Lua API,
-you are responsible for ensuring consistency.
-In particular,
-you are responsible for controlling stack overflow.
-You can use the function lua_checkstack
-to ensure that the stack has enough space for pushing new elements.
-
-
-
-Whenever Lua calls C,
-it ensures that the stack has space for
-at least LUA_MINSTACK extra slots.
-LUA_MINSTACK is defined as 20,
-so that usually you do not have to worry about stack space
-unless your code has loops pushing elements onto the stack.
-
-
-
-When you call a Lua function
-without a fixed number of results (see lua_call),
-Lua ensures that the stack has enough space for all results,
-but it does not ensure any extra space.
-So, before pushing anything in the stack after such a call
-you should use lua_checkstack.
-
-
-
-
-
-
-Any function in the API that receives stack indices
-works only with valid indices or acceptable indices.
-
-
-
-A valid index is an index that refers to a
-real position within the stack, that is,
-its position lies between 1 and the stack top
-(1 ≤ abs(index) ≤ top).
-
-Usually, functions that can modify the value at an index
-require valid indices.
-
-
-
-Unless otherwise noted,
-any function that accepts valid indices also accepts pseudo-indices,
-which represent some Lua values that are accessible to C code
-but which are not in the stack.
-Pseudo-indices are used to access the registry
-and the upvalues of a C function (see §4.4).
-
-
-
-Functions that do not need a specific stack position,
-but only a value in the stack (e.g., query functions),
-can be called with acceptable indices.
-An acceptable index can be any valid index,
-including the pseudo-indices,
-but it also can be any positive index after the stack top
-within the space allocated for the stack,
-that is, indices up to the stack size.
-(Note that 0 is never an acceptable index.)
-Except when noted otherwise,
-functions in the API work with acceptable indices.
-
-
-
-Acceptable indices serve to avoid extra tests
-against the stack top when querying the stack.
-For instance, a C function can query its third argument
-without the need to first check whether there is a third argument,
-that is, without the need to check whether 3 is a valid index.
-
-
-
-For functions that can be called with acceptable indices,
-any non-valid index is treated as if it
-contains a value of a virtual type LUA_TNONE,
-which behaves like a nil value.
-
-
-
-
-
-
-When a C function is created,
-it is possible to associate some values with it,
-thus creating a C closure
-(see lua_pushcclosure);
-these values are called upvalues and are
-accessible to the function whenever it is called.
-
-
-
-Whenever a C function is called,
-its upvalues are located at specific pseudo-indices.
-These pseudo-indices are produced by the macro
-lua_upvalueindex.
-The first value associated with a function is at position
-lua_upvalueindex(1), and so on.
-Any access to lua_upvalueindex(n),
-where n is greater than the number of upvalues of the
-current function (but not greater than 256),
-produces an acceptable but invalid index.
-
-
-
-
-
-
-Lua provides a registry,
-a predefined table that can be used by any C code to
-store whatever Lua values it needs to store.
-The registry table is always located at pseudo-index
-LUA_REGISTRYINDEX,
-which is a valid index.
-Any C library can store data into this table,
-but it must take care to choose keys
-that are different from those used
-by other libraries, to avoid collisions.
-Typically, you should use as key a string containing your library name,
-or a light userdata with the address of a C object in your code,
-or any Lua object created by your code.
-As with variable names,
-string keys starting with an underscore followed by
-uppercase letters are reserved for Lua.
-
-
-
-The integer keys in the registry are used
-by the reference mechanism (see luaL_ref)
-and by some predefined values.
-Therefore, integer keys must not be used for other purposes.
-
-
-
-When you create a new Lua state,
-its registry comes with some predefined values.
-These predefined values are indexed with integer keys
-defined as constants in lua.h.
-The following constants are defined:
-
-
-
LUA_RIDX_MAINTHREAD: At this index the registry has
-the main thread of the state.
-(The main thread is the one created together with the state.)
-
-
-
LUA_RIDX_GLOBALS: At this index the registry has
-the global environment.
-
-Internally, Lua uses the C longjmp facility to handle errors.
-(Lua will use exceptions if you compile it as C++;
-search for LUAI_THROW in the source code for details.)
-When Lua faces any error
-(such as a memory allocation error, type errors, syntax errors,
-and runtime errors)
-it raises an error;
-that is, it does a long jump.
-A protected environment uses setjmp
-to set a recovery point;
-any error jumps to the most recent active recovery point.
-
-
-
-If an error happens outside any protected environment,
-Lua calls a panic function (see lua_atpanic)
-and then calls abort,
-thus exiting the host application.
-Your panic function can avoid this exit by
-never returning
-(e.g., doing a long jump to your own recovery point outside Lua).
-
-
-
-The panic function runs as if it were a message handler (see §2.3);
-in particular, the error message is at the top of the stack.
-However, there is no guarantee about stack space.
-To push anything on the stack,
-the panic function must first check the available space (see §4.2).
-
-
-
-Most functions in the API can raise an error,
-for instance due to a memory allocation error.
-The documentation for each function indicates whether
-it can raise errors.
-
-
-
-Inside a C function you can raise an error by calling lua_error.
-
-
-
-
-
-
-Internally, Lua uses the C longjmp facility to yield a coroutine.
-Therefore, if a C function foo calls an API function
-and this API function yields
-(directly or indirectly by calling another function that yields),
-Lua cannot return to foo any more,
-because the longjmp removes its frame from the C stack.
-
-
-
-To avoid this kind of problem,
-Lua raises an error whenever it tries to yield across an API call,
-except for three functions:
-lua_yieldk, lua_callk, and lua_pcallk.
-All those functions receive a continuation function
-(as a parameter named k) to continue execution after a yield.
-
-
-
-We need to set some terminology to explain continuations.
-We have a C function called from Lua which we will call
-the original function.
-This original function then calls one of those three functions in the C API,
-which we will call the callee function,
-that then yields the current thread.
-(This can happen when the callee function is lua_yieldk,
-or when the callee function is either lua_callk or lua_pcallk
-and the function called by them yields.)
-
-
-
-Suppose the running thread yields while executing the callee function.
-After the thread resumes,
-it eventually will finish running the callee function.
-However,
-the callee function cannot return to the original function,
-because its frame in the C stack was destroyed by the yield.
-Instead, Lua calls a continuation function,
-which was given as an argument to the callee function.
-As the name implies,
-the continuation function should continue the task
-of the original function.
-
-
-
-As an illustration, consider the following function:
-
-
- int original_function (lua_State *L) {
- ... /* code 1 */
- status = lua_pcall(L, n, m, h); /* calls Lua */
- ... /* code 2 */
- }
-
-Now we want to allow
-the Lua code being run by lua_pcall to yield.
-First, we can rewrite our function like here:
-
-
- int k (lua_State *L, int status, lua_KContext ctx) {
- ... /* code 2 */
- }
-
- int original_function (lua_State *L) {
- ... /* code 1 */
- return k(L, lua_pcall(L, n, m, h), ctx);
- }
-
-In the above code,
-the new function k is a
-continuation function (with type lua_KFunction),
-which should do all the work that the original function
-was doing after calling lua_pcall.
-Now, we must inform Lua that it must call k if the Lua code
-being executed by lua_pcall gets interrupted in some way
-(errors or yielding),
-so we rewrite the code as here,
-replacing lua_pcall by lua_pcallk:
-
-
- int original_function (lua_State *L) {
- ... /* code 1 */
- return k(L, lua_pcallk(L, n, m, h, ctx2, k), ctx1);
- }
-
-Note the external, explicit call to the continuation:
-Lua will call the continuation only if needed, that is,
-in case of errors or resuming after a yield.
-If the called function returns normally without ever yielding,
-lua_pcallk (and lua_callk) will also return normally.
-(Of course, instead of calling the continuation in that case,
-you can do the equivalent work directly inside the original function.)
-
-
-
-Besides the Lua state,
-the continuation function has two other parameters:
-the final status of the call plus the context value (ctx) that
-was passed originally to lua_pcallk.
-(Lua does not use this context value;
-it only passes this value from the original function to the
-continuation function.)
-For lua_pcallk,
-the status is the same value that would be returned by lua_pcallk,
-except that it is LUA_YIELD when being executed after a yield
-(instead of LUA_OK).
-For lua_yieldk and lua_callk,
-the status is always LUA_YIELD when Lua calls the continuation.
-(For these two functions,
-Lua will not call the continuation in case of errors,
-because they do not handle errors.)
-Similarly, when using lua_callk,
-you should call the continuation function
-with LUA_OK as the status.
-(For lua_yieldk, there is not much point in calling
-directly the continuation function,
-because lua_yieldk usually does not return.)
-
-
-
-Lua treats the continuation function as if it were the original function.
-The continuation function receives the same Lua stack
-from the original function,
-in the same state it would be if the callee function had returned.
-(For instance,
-after a lua_callk the function and its arguments are
-removed from the stack and replaced by the results from the call.)
-It also has the same upvalues.
-Whatever it returns is handled by Lua as if it were the return
-of the original function.
-
-
-
-
-
-
-Here we list all functions and types from the C API in
-alphabetical order.
-Each function has an indicator like this:
-[-o, +p, x]
-
-
-
-The first field, o,
-is how many elements the function pops from the stack.
-The second field, p,
-is how many elements the function pushes onto the stack.
-(Any function always pushes its results after popping its arguments.)
-A field in the form x|y means the function can push (or pop)
-x or y elements,
-depending on the situation;
-an interrogation mark '?' means that
-we cannot know how many elements the function pops/pushes
-by looking only at its arguments
-(e.g., they may depend on what is on the stack).
-The third field, x,
-tells whether the function may raise errors:
-'-' means the function never raises any error;
-'e' means the function may raise errors;
-'v' means the function may raise an error on purpose.
-
-
-
-
-The type of the memory-allocation function used by Lua states.
-The allocator function must provide a
-functionality similar to realloc,
-but not exactly the same.
-Its arguments are
-ud, an opaque pointer passed to lua_newstate;
-ptr, a pointer to the block being allocated/reallocated/freed;
-osize, the original size of the block or some code about what
-is being allocated;
-and nsize, the new size of the block.
-
-
-
-When ptr is not NULL,
-osize is the size of the block pointed by ptr,
-that is, the size given when it was allocated or reallocated.
-
-
-
-When ptr is NULL,
-osize encodes the kind of object that Lua is allocating.
-osize is any of
-LUA_TSTRING, LUA_TTABLE, LUA_TFUNCTION,
-LUA_TUSERDATA, or LUA_TTHREAD when (and only when)
-Lua is creating a new object of that type.
-When osize is some other value,
-Lua is allocating memory for something else.
-
-
-
-Lua assumes the following behavior from the allocator function:
-
-
-
-When nsize is zero,
-the allocator must behave like free
-and return NULL.
-
-
-
-When nsize is not zero,
-the allocator must behave like realloc.
-The allocator returns NULL
-if and only if it cannot fulfill the request.
-Lua assumes that the allocator never fails when
-osize >= nsize.
-
-
-
-Here is a simple implementation for the allocator function.
-It is used in the auxiliary library by luaL_newstate.
-
-
-Note that Standard C ensures
-that free(NULL) has no effect and that
-realloc(NULL,size) is equivalent to malloc(size).
-This code assumes that realloc does not fail when shrinking a block.
-(Although Standard C does not ensure this behavior,
-it seems to be a safe assumption.)
-
-
-
-
-
-
-Performs an arithmetic or bitwise operation over the two values
-(or one, in the case of negations)
-at the top of the stack,
-with the value at the top being the second operand,
-pops these values, and pushes the result of the operation.
-The function follows the semantics of the corresponding Lua operator
-(that is, it may call metamethods).
-
-
-
-The value of op must be one of the following constants:
-
-
void lua_call (lua_State *L, int nargs, int nresults);
-
-
-Calls a function.
-
-
-
-To call a function you must use the following protocol:
-first, the function to be called is pushed onto the stack;
-then, the arguments to the function are pushed
-in direct order;
-that is, the first argument is pushed first.
-Finally you call lua_call;
-nargs is the number of arguments that you pushed onto the stack.
-All arguments and the function value are popped from the stack
-when the function is called.
-The function results are pushed onto the stack when the function returns.
-The number of results is adjusted to nresults,
-unless nresults is LUA_MULTRET.
-In this case, all results from the function are pushed.
-Lua takes care that the returned values fit into the stack space.
-The function results are pushed onto the stack in direct order
-(the first result is pushed first),
-so that after the call the last result is on the top of the stack.
-
-
-
-Any error inside the called function is propagated upwards
-(with a longjmp).
-
-
-
-The following example shows how the host program can do the
-equivalent to this Lua code:
-
-
- a = f("how", t.x, 14)
-
-Here it is in C:
-
-
- lua_getglobal(L, "f"); /* function to be called */
- lua_pushliteral(L, "how"); /* 1st argument */
- lua_getglobal(L, "t"); /* table to be indexed */
- lua_getfield(L, -1, "x"); /* push result of t.x (2nd arg) */
- lua_remove(L, -2); /* remove 't' from the stack */
- lua_pushinteger(L, 14); /* 3rd argument */
- lua_call(L, 3, 1); /* call 'f' with 3 arguments and 1 result */
- lua_setglobal(L, "a"); /* set global 'a' */
-
-Note that the code above is balanced:
-at its end, the stack is back to its original configuration.
-This is considered good programming practice.
-
-
-
-
-
-
-In order to communicate properly with Lua,
-a C function must use the following protocol,
-which defines the way parameters and results are passed:
-a C function receives its arguments from Lua in its stack
-in direct order (the first argument is pushed first).
-So, when the function starts,
-lua_gettop(L) returns the number of arguments received by the function.
-The first argument (if any) is at index 1
-and its last argument is at index lua_gettop(L).
-To return values to Lua, a C function just pushes them onto the stack,
-in direct order (the first result is pushed first),
-and returns the number of results.
-Any other value in the stack below the results will be properly
-discarded by Lua.
-Like a Lua function, a C function called by Lua can also return
-many results.
-
-
-
-As an example, the following function receives a variable number
-of numerical arguments and returns their average and their sum:
-
-
- static int foo (lua_State *L) {
- int n = lua_gettop(L); /* number of arguments */
- lua_Number sum = 0.0;
- int i;
- for (i = 1; i <= n; i++) {
- if (!lua_isnumber(L, i)) {
- lua_pushliteral(L, "incorrect argument");
- lua_error(L);
- }
- sum += lua_tonumber(L, i);
- }
- lua_pushnumber(L, sum/n); /* first result */
- lua_pushnumber(L, sum); /* second result */
- return 2; /* number of results */
- }
-
-Ensures that the stack has space for at least n extra slots.
-It returns false if it cannot fulfill the request,
-either because it would cause the stack
-to be larger than a fixed maximum size
-(typically at least several thousand elements) or
-because it cannot allocate memory for the extra space.
-This function never shrinks the stack;
-if the stack is already larger than the new size,
-it is left unchanged.
-
-
-
-
-
-
-Destroys all objects in the given Lua state
-(calling the corresponding garbage-collection metamethods, if any)
-and frees all dynamic memory used by this state.
-On several platforms, you may not need to call this function,
-because all resources are naturally released when the host program ends.
-On the other hand, long-running programs that create multiple states,
-such as daemons or web servers,
-will probably need to close states as soon as they are not needed.
-
-
-
-
-
-
int lua_compare (lua_State *L, int index1, int index2, int op);
-
-
-Compares two Lua values.
-Returns 1 if the value at index index1 satisfies op
-when compared with the value at index index2,
-following the semantics of the corresponding Lua operator
-(that is, it may call metamethods).
-Otherwise returns 0.
-Also returns 0 if any of the indices is not valid.
-
-
-
-The value of op must be one of the following constants:
-
-
-Concatenates the n values at the top of the stack,
-pops them, and leaves the result at the top.
-If n is 1, the result is the single value on the stack
-(that is, the function does nothing);
-if n is 0, the result is the empty string.
-Concatenation is performed following the usual semantics of Lua
-(see §3.4.6).
-
-
-
-
-
-
void lua_copy (lua_State *L, int fromidx, int toidx);
-
-
-Copies the element at index fromidx
-into the valid index toidx,
-replacing the value at that position.
-Values at other positions are not affected.
-
-
-
-
-
-
void lua_createtable (lua_State *L, int narr, int nrec);
-
-
-Creates a new empty table and pushes it onto the stack.
-Parameter narr is a hint for how many elements the table
-will have as a sequence;
-parameter nrec is a hint for how many other elements
-the table will have.
-Lua may use these hints to preallocate memory for the new table.
-This pre-allocation is useful for performance when you know in advance
-how many elements the table will have.
-Otherwise you can use the function lua_newtable.
-
-
-
-
-
-
int lua_dump (lua_State *L,
- lua_Writer writer,
- void *data,
- int strip);
-
-
-Dumps a function as a binary chunk.
-Receives a Lua function on the top of the stack
-and produces a binary chunk that,
-if loaded again,
-results in a function equivalent to the one dumped.
-As it produces parts of the chunk,
-lua_dump calls function writer (see lua_Writer)
-with the given data
-to write them.
-
-
-
-If strip is true,
-the binary representation is created without debug information
-about the function.
-
-
-
-The value returned is the error code returned by the last
-call to the writer;
-0 means no errors.
-
-
-
-This function does not pop the Lua function from the stack.
-
-
-
-
-
-
-Generates a Lua error,
-using the value at the top of the stack as the error object.
-This function does a long jump,
-and therefore never returns
-(see luaL_error).
-
-
-
-
-
-
-This function performs several tasks,
-according to the value of the parameter what:
-
-
-
-
LUA_GCSTOP:
-stops the garbage collector.
-
-
-
LUA_GCRESTART:
-restarts the garbage collector.
-
-
-
LUA_GCCOLLECT:
-performs a full garbage-collection cycle.
-
-
-
LUA_GCCOUNT:
-returns the current amount of memory (in Kbytes) in use by Lua.
-
-
-
LUA_GCCOUNTB:
-returns the remainder of dividing the current amount of bytes of
-memory in use by Lua by 1024.
-
-
-
LUA_GCSTEP:
-performs an incremental step of garbage collection.
-
-
-
LUA_GCSETPAUSE:
-sets data as the new value
-for the pause of the collector (see §2.5)
-and returns the previous value of the pause.
-
-
-
LUA_GCSETSTEPMUL:
-sets data as the new value for the step multiplier of
-the collector (see §2.5)
-and returns the previous value of the step multiplier.
-
-
-
LUA_GCISRUNNING:
-returns a boolean that tells whether the collector is running
-(i.e., not stopped).
-
-
-
-
-
-For more details about these options,
-see collectgarbage.
-
-
-
-
-
-
-Returns the memory-allocation function of a given state.
-If ud is not NULL, Lua stores in *ud the
-opaque pointer given when the memory-allocator function was set.
-
-
-
-
-
-
int lua_getfield (lua_State *L, int index, const char *k);
-
-
-Pushes onto the stack the value t[k],
-where t is the value at the given index.
-As in Lua, this function may trigger a metamethod
-for the "index" event (see §2.4).
-
-
-
-Returns the type of the pushed value.
-
-
-
-
-
-
-Returns a pointer to a raw memory area associated with the
-given Lua state.
-The application can use this area for any purpose;
-Lua does not use it for anything.
-
-
-
-Each new thread has this area initialized with a copy
-of the area of the main thread.
-
-
-
-By default, this area has the size of a pointer to void,
-but you can recompile Lua with a different size for this area.
-(See LUA_EXTRASPACE in luaconf.h.)
-
-
-
-
-
-
int lua_geti (lua_State *L, int index, lua_Integer i);
-
-
-Pushes onto the stack the value t[i],
-where t is the value at the given index.
-As in Lua, this function may trigger a metamethod
-for the "index" event (see §2.4).
-
-
-
-Returns the type of the pushed value.
-
-
-
-
-
-
-If the value at the given index has a metatable,
-the function pushes that metatable onto the stack and returns 1.
-Otherwise,
-the function returns 0 and pushes nothing on the stack.
-
-
-
-
-
-
-Pushes onto the stack the value t[k],
-where t is the value at the given index
-and k is the value at the top of the stack.
-
-
-
-This function pops the key from the stack,
-pushing the resulting value in its place.
-As in Lua, this function may trigger a metamethod
-for the "index" event (see §2.4).
-
-
-
-Returns the type of the pushed value.
-
-
-
-
-
-
-Returns the index of the top element in the stack.
-Because indices start at 1,
-this result is equal to the number of elements in the stack;
-in particular, 0 means an empty stack.
-
-
-
-
-
-
-Moves the top element into the given valid index,
-shifting up the elements above this index to open space.
-This function cannot be called with a pseudo-index,
-because a pseudo-index is not an actual stack position.
-
-
-
-
-
-
-By default this type is long long,
-(usually a 64-bit two-complement integer),
-but that can be changed to long or int
-(usually a 32-bit two-complement integer).
-(See LUA_INT in luaconf.h.)
-
-
-
-Lua also defines the constants
-LUA_MININTEGER and LUA_MAXINTEGER,
-with the minimum and the maximum values that fit in this type.
-
-
-
-
-
-
-Returns 1 if the value at the given index is an integer
-(that is, the value is a number and is represented as an integer),
-and 0 otherwise.
-
-
-
-
-
-
-The type for continuation-function contexts.
-It must be a numerical type.
-This type is defined as intptr_t
-when intptr_t is available,
-so that it can store pointers too.
-Otherwise, it is defined as ptrdiff_t.
-
-
-
-
-
-
-Returns the length of the value at the given index.
-It is equivalent to the '#' operator in Lua (see §3.4.7) and
-may trigger a metamethod for the "length" event (see §2.4).
-The result is pushed on the stack.
-
-
-
-
-
-
-Loads a Lua chunk without running it.
-If there are no errors,
-lua_load pushes the compiled chunk as a Lua
-function on top of the stack.
-Otherwise, it pushes an error message.
-
-
-
LUA_ERRGCMM:
-error while running a __gc metamethod.
-(This error has no relation with the chunk being loaded.
-It is generated by the garbage collector.)
-
-
-
-
-
-The lua_load function uses a user-supplied reader function
-to read the chunk (see lua_Reader).
-The data argument is an opaque value passed to the reader function.
-
-
-
-The chunkname argument gives a name to the chunk,
-which is used for error messages and in debug information (see §4.9).
-
-
-
-lua_load automatically detects whether the chunk is text or binary
-and loads it accordingly (see program luac).
-The string mode works as in function load,
-with the addition that
-a NULL value is equivalent to the string "bt".
-
-
-
-lua_load uses the stack internally,
-so the reader function must always leave the stack
-unmodified when returning.
-
-
-
-If the resulting function has upvalues,
-its first upvalue is set to the value of the global environment
-stored at index LUA_RIDX_GLOBALS in the registry (see §4.5).
-When loading main chunks,
-this upvalue will be the _ENV variable (see §2.2).
-Other upvalues are initialized with nil.
-
-
-
-
-
-
-Creates a new thread running in a new, independent state.
-Returns NULL if it cannot create the thread or the state
-(due to lack of memory).
-The argument f is the allocator function;
-Lua does all memory allocation for this state through this function.
-The second argument, ud, is an opaque pointer that Lua
-passes to the allocator in every call.
-
-
-
-
-
-
-Creates a new thread, pushes it on the stack,
-and returns a pointer to a lua_State that represents this new thread.
-The new thread returned by this function shares with the original thread
-its global environment,
-but has an independent execution stack.
-
-
-
-There is no explicit function to close or to destroy a thread.
-Threads are subject to garbage collection,
-like any Lua object.
-
-
-
-
-
-
-This function allocates a new block of memory with the given size,
-pushes onto the stack a new full userdata with the block address,
-and returns this address.
-The host program can freely use this memory.
-
-
-
-
-
-
-Pops a key from the stack,
-and pushes a key–value pair from the table at the given index
-(the "next" pair after the given key).
-If there are no more elements in the table,
-then lua_next returns 0 (and pushes nothing).
-
-
-
-A typical traversal looks like this:
-
-
- /* table is in the stack at index 't' */
- lua_pushnil(L); /* first key */
- while (lua_next(L, t) != 0) {
- /* uses 'key' (at index -2) and 'value' (at index -1) */
- printf("%s - %s\n",
- lua_typename(L, lua_type(L, -2)),
- lua_typename(L, lua_type(L, -1)));
- /* removes 'value'; keeps 'key' for next iteration */
- lua_pop(L, 1);
- }
-
-
-
-While traversing a table,
-do not call lua_tolstring directly on a key,
-unless you know that the key is actually a string.
-Recall that lua_tolstring may change
-the value at the given index;
-this confuses the next call to lua_next.
-
-
-
-See function next for the caveats of modifying
-the table during its traversal.
-
-
-
-
-
-
int lua_numbertointeger (lua_Number n, lua_Integer *p);
-
-
-Converts a Lua float to a Lua integer.
-This macro assumes that n has an integral value.
-If that value is within the range of Lua integers,
-it is converted to an integer and assigned to *p.
-The macro results in a boolean indicating whether the
-conversion was successful.
-(Note that this range test can be tricky to do
-correctly without this macro,
-due to roundings.)
-
-
-
-This macro may evaluate its arguments more than once.
-
-
-
-
-
-
int lua_pcall (lua_State *L, int nargs, int nresults, int msgh);
-
-
-Calls a function in protected mode.
-
-
-
-Both nargs and nresults have the same meaning as
-in lua_call.
-If there are no errors during the call,
-lua_pcall behaves exactly like lua_call.
-However, if there is any error,
-lua_pcall catches it,
-pushes a single value on the stack (the error message),
-and returns an error code.
-Like lua_call,
-lua_pcall always removes the function
-and its arguments from the stack.
-
-
-
-If msgh is 0,
-then the error message returned on the stack
-is exactly the original error message.
-Otherwise, msgh is the stack index of a
-message handler.
-(In the current implementation, this index cannot be a pseudo-index.)
-In case of runtime errors,
-this function will be called with the error message
-and its return value will be the message
-returned on the stack by lua_pcall.
-
-
-
-Typically, the message handler is used to add more debug
-information to the error message, such as a stack traceback.
-Such information cannot be gathered after the return of lua_pcall,
-since by then the stack has unwound.
-
-
-
-The lua_pcall function returns one of the following constants
-(defined in lua.h):
-
-
void lua_pushcclosure (lua_State *L, lua_CFunction fn, int n);
-
-
-Pushes a new C closure onto the stack.
-
-
-
-When a C function is created,
-it is possible to associate some values with it,
-thus creating a C closure (see §4.4);
-these values are then accessible to the function whenever it is called.
-To associate values with a C function,
-first these values must be pushed onto the stack
-(when there are multiple values, the first value is pushed first).
-Then lua_pushcclosure
-is called to create and push the C function onto the stack,
-with the argument n telling how many values will be
-associated with the function.
-lua_pushcclosure also pops these values from the stack.
-
-
-
-The maximum value for n is 255.
-
-
-
-When n is zero,
-this function creates a light C function,
-which is just a pointer to the C function.
-In that case, it never raises a memory error.
-
-
-
-
-
-
-Pushes a C function onto the stack.
-This function receives a pointer to a C function
-and pushes onto the stack a Lua value of type function that,
-when called, invokes the corresponding C function.
-
-
-
-Any function to be registered in Lua must
-follow the correct protocol to receive its parameters
-and return its results (see lua_CFunction).
-
-
-
-Pushes onto the stack a formatted string
-and returns a pointer to this string.
-It is similar to the ISO C function sprintf,
-but has some important differences:
-
-
-
-
-You do not have to allocate space for the result:
-the result is a Lua string and Lua takes care of memory allocation
-(and deallocation, through garbage collection).
-
-
-
-The conversion specifiers are quite restricted.
-There are no flags, widths, or precisions.
-The conversion specifiers can only be
-'%%' (inserts the character '%'),
-'%s' (inserts a zero-terminated string, with no size restrictions),
-'%f' (inserts a lua_Number),
-'%L' (inserts a lua_Integer),
-'%p' (inserts a pointer as a hexadecimal numeral),
-'%d' (inserts an int),
-'%c' (inserts an int as a one-byte character), and
-'%U' (inserts a long int as a UTF-8 byte sequence).
-
-Userdata represent C values in Lua.
-A light userdata represents a pointer, a void*.
-It is a value (like a number):
-you do not create it, it has no individual metatable,
-and it is not collected (as it was never created).
-A light userdata is equal to "any"
-light userdata with the same C address.
-
-
-
-
-
-
-This macro is equivalent to lua_pushlstring,
-but can be used only when s is a literal string.
-It automatically provides the string length.
-
-
-
-
-
-
-Pushes the string pointed to by s with size len
-onto the stack.
-Lua makes (or reuses) an internal copy of the given string,
-so the memory at s can be freed or reused immediately after
-the function returns.
-The string can contain any binary data,
-including embedded zeros.
-
-
-
-Returns a pointer to the internal copy of the string.
-
-
-
-
-
-
-Pushes the zero-terminated string pointed to by s
-onto the stack.
-Lua makes (or reuses) an internal copy of the given string,
-so the memory at s can be freed or reused immediately after
-the function returns.
-
-
-
-Returns a pointer to the internal copy of the string.
-
-
-
-If s is NULL, pushes nil and returns NULL.
-
-
-
-
-
-
int lua_rawequal (lua_State *L, int index1, int index2);
-
-
-Returns 1 if the two values in indices index1 and
-index2 are primitively equal
-(that is, without calling metamethods).
-Otherwise returns 0.
-Also returns 0 if any of the indices are not valid.
-
-
-
-
-
-
int lua_rawgetp (lua_State *L, int index, const void *p);
-
-
-Pushes onto the stack the value t[k],
-where t is the table at the given index and
-k is the pointer p represented as a light userdata.
-The access is raw;
-that is, it does not invoke metamethods.
-
-
-
-Returns the type of the pushed value.
-
-
-
-
-
-
-Returns the raw "length" of the value at the given index:
-for strings, this is the string length;
-for tables, this is the result of the length operator ('#')
-with no metamethods;
-for userdata, this is the size of the block of memory allocated
-for the userdata;
-for other values, it is 0.
-
-
-
-
-
-
void lua_rawsetp (lua_State *L, int index, const void *p);
-
-
-Does the equivalent of t[k] = v,
-where t is the table at the given index,
-k is the pointer p represented as a light userdata,
-and v is the value at the top of the stack.
-
-
-
-This function pops the value from the stack.
-The assignment is raw;
-that is, it does not invoke metamethods.
-
-
-
-
-
-
-The reader function used by lua_load.
-Every time it needs another piece of the chunk,
-lua_load calls the reader,
-passing along its data parameter.
-The reader must return a pointer to a block of memory
-with a new piece of the chunk
-and set size to the block size.
-The block must exist until the reader function is called again.
-To signal the end of the chunk,
-the reader must return NULL or set size to zero.
-The reader function may return pieces of any size greater than zero.
-
-
-
-
-
-
-Removes the element at the given valid index,
-shifting down the elements above this index to fill the gap.
-This function cannot be called with a pseudo-index,
-because a pseudo-index is not an actual stack position.
-
-
-
-
-
-
-Moves the top element into the given valid index
-without shifting any element
-(therefore replacing the value at the given index),
-and then pops the top element.
-
-
-
-
-
-
int lua_resume (lua_State *L, lua_State *from, int nargs);
-
-
-Starts and resumes a coroutine in a given thread.
-
-
-
-To start a coroutine,
-you push onto the thread stack the main function plus any arguments;
-then you call lua_resume,
-with nargs being the number of arguments.
-This call returns when the coroutine suspends or finishes its execution.
-When it returns, the stack contains all values passed to lua_yield,
-or all values returned by the body function.
-lua_resume returns
-LUA_YIELD if the coroutine yields,
-LUA_OK if the coroutine finishes its execution
-without errors,
-or an error code in case of errors (see lua_pcall).
-
-
-
-In case of errors,
-the stack is not unwound,
-so you can use the debug API over it.
-The error message is on the top of the stack.
-
-
-
-To resume a coroutine,
-you remove any results from the last lua_yield,
-put on its stack only the values to
-be passed as results from yield,
-and then call lua_resume.
-
-
-
-The parameter from represents the coroutine that is resuming L.
-If there is no such coroutine,
-this parameter can be NULL.
-
-
-
-
-
-
-Rotates the stack elements from idx to the top n positions
-in the direction of the top, for a positive n,
-or -n positions in the direction of the bottom,
-for a negative n.
-The absolute value of n must not be greater than the size
-of the slice being rotated.
-
-
-
-
-
-
-Does the equivalent to t[k] = v,
-where t is the value at the given index,
-v is the value at the top of the stack,
-and k is the value just below the top.
-
-
-
-This function pops both the key and the value from the stack.
-As in Lua, this function may trigger a metamethod
-for the "newindex" event (see §2.4).
-
-
-
-
-
-
-Accepts any index, or 0,
-and sets the stack top to this index.
-If the new top is larger than the old one,
-then the new elements are filled with nil.
-If index is 0, then all stack elements are removed.
-
-
-
-
-
-
-An opaque structure that points to a thread and indirectly
-(through the thread) to the whole state of a Lua interpreter.
-The Lua library is fully reentrant:
-it has no global variables.
-All information about a state is accessible through this structure.
-
-
-
-A pointer to this structure must be passed as the first argument to
-every function in the library, except to lua_newstate,
-which creates a Lua state from scratch.
-
-
-
-
-
-
-The status can be 0 (LUA_OK) for a normal thread,
-an error code if the thread finished the execution
-of a lua_resume with an error,
-or LUA_YIELD if the thread is suspended.
-
-
-
-You can only call functions in threads with status LUA_OK.
-You can resume threads with status LUA_OK
-(to start a new coroutine) or LUA_YIELD
-(to resume a coroutine).
-
-
-
-
-
-
-Converts the zero-terminated string s to a number,
-pushes that number into the stack,
-and returns the total size of the string,
-that is, its length plus one.
-The conversion can result in an integer or a float,
-according to the lexical conventions of Lua (see §3.1).
-The string may have leading and trailing spaces and a sign.
-If the string is not a valid numeral,
-returns 0 and pushes nothing.
-(Note that the result can be used as a boolean,
-true if the conversion succeeds.)
-
-
-
-
-
-
-Converts the Lua value at the given index to a C boolean
-value (0 or 1).
-Like all tests in Lua,
-lua_toboolean returns true for any Lua value
-different from false and nil;
-otherwise it returns false.
-(If you want to accept only actual boolean values,
-use lua_isboolean to test the value's type.)
-
-
-
-
-
-
lua_Integer lua_tointegerx (lua_State *L, int index, int *isnum);
-
-
-Converts the Lua value at the given index
-to the signed integral type lua_Integer.
-The Lua value must be an integer,
-or a number or string convertible to an integer (see §3.4.3);
-otherwise, lua_tointegerx returns 0.
-
-
-
-If isnum is not NULL,
-its referent is assigned a boolean value that
-indicates whether the operation succeeded.
-
-
-
-
-
-
const char *lua_tolstring (lua_State *L, int index, size_t *len);
-
-
-Converts the Lua value at the given index to a C string.
-If len is not NULL,
-it also sets *len with the string length.
-The Lua value must be a string or a number;
-otherwise, the function returns NULL.
-If the value is a number,
-then lua_tolstring also
-changes the actual value in the stack to a string.
-(This change confuses lua_next
-when lua_tolstring is applied to keys during a table traversal.)
-
-
-
-lua_tolstring returns a fully aligned pointer
-to a string inside the Lua state.
-This string always has a zero ('\0')
-after its last character (as in C),
-but can contain other zeros in its body.
-
-
-
-Because Lua has garbage collection,
-there is no guarantee that the pointer returned by lua_tolstring
-will be valid after the corresponding Lua value is removed from the stack.
-
-
-
-
-
-
lua_Number lua_tonumberx (lua_State *L, int index, int *isnum);
-
-
-Converts the Lua value at the given index
-to the C type lua_Number (see lua_Number).
-The Lua value must be a number or a string convertible to a number
-(see §3.4.3);
-otherwise, lua_tonumberx returns 0.
-
-
-
-If isnum is not NULL,
-its referent is assigned a boolean value that
-indicates whether the operation succeeded.
-
-
-
-
-
-
const void *lua_topointer (lua_State *L, int index);
-
-
-Converts the value at the given index to a generic
-C pointer (void*).
-The value can be a userdata, a table, a thread, or a function;
-otherwise, lua_topointer returns NULL.
-Different objects will give different pointers.
-There is no way to convert the pointer back to its original value.
-
-
-
-Typically this function is used only for debug information.
-
-
-
-
-
-
lua_State *lua_tothread (lua_State *L, int index);
-
-
-Converts the value at the given index to a Lua thread
-(represented as lua_State*).
-This value must be a thread;
-otherwise, the function returns NULL.
-
-
-
-
-
-
-If the value at the given index is a full userdata,
-returns its block address.
-If the value is a light userdata,
-returns its pointer.
-Otherwise, returns NULL.
-
-
-
-
-
-
-Returns the address of the version number stored in the Lua core.
-When called with a valid lua_State,
-returns the address of the version used to create that state.
-When called with NULL,
-returns the address of the version running the call.
-
-
-
-
-
-
-The type of the writer function used by lua_dump.
-Every time it produces another piece of chunk,
-lua_dump calls the writer,
-passing along the buffer to be written (p),
-its size (sz),
-and the data parameter supplied to lua_dump.
-
-
-
-The writer returns an error code:
-0 means no errors;
-any other value means an error and stops lua_dump from
-calling the writer again.
-
-
-
-
-
-
-This function is equivalent to lua_yieldk,
-but it has no continuation (see §4.7).
-Therefore, when the thread resumes,
-it continues the function that called
-the function calling lua_yield.
-
-
-
-
-
-
int lua_yieldk (lua_State *L,
- int nresults,
- lua_KContext ctx,
- lua_KFunction k);
-
-
-Yields a coroutine (thread).
-
-
-
-When a C function calls lua_yieldk,
-the running coroutine suspends its execution,
-and the call to lua_resume that started this coroutine returns.
-The parameter nresults is the number of values from the stack
-that will be passed as results to lua_resume.
-
-
-
-When the coroutine is resumed again,
-Lua calls the given continuation function k to continue
-the execution of the C function that yielded (see §4.7).
-This continuation function receives the same stack
-from the previous function,
-with the n results removed and
-replaced by the arguments passed to lua_resume.
-Moreover,
-the continuation function receives the value ctx
-that was passed to lua_yieldk.
-
-
-
-Usually, this function does not return;
-when the coroutine eventually resumes,
-it continues executing the continuation function.
-However, there is one special case,
-which is when this function is called
-from inside a line hook (see §4.9).
-In that case, lua_yieldk should be called with no continuation
-(probably in the form of lua_yield),
-and the hook should return immediately after the call.
-Lua will yield and,
-when the coroutine resumes again,
-it will continue the normal execution
-of the (Lua) function that triggered the hook.
-
-
-
-This function can raise an error if it is called from a thread
-with a pending C call with no continuation function,
-or it is called from a thread that is not running inside a resume
-(e.g., the main thread).
-
-
-
-
-
-
-
-
-Lua has no built-in debugging facilities.
-Instead, it offers a special interface
-by means of functions and hooks.
-This interface allows the construction of different
-kinds of debuggers, profilers, and other tools
-that need "inside information" from the interpreter.
-
-
-
-
typedef struct lua_Debug {
- int event;
- const char *name; /* (n) */
- const char *namewhat; /* (n) */
- const char *what; /* (S) */
- const char *source; /* (S) */
- int currentline; /* (l) */
- int linedefined; /* (S) */
- int lastlinedefined; /* (S) */
- unsigned char nups; /* (u) number of upvalues */
- unsigned char nparams; /* (u) number of parameters */
- char isvararg; /* (u) */
- char istailcall; /* (t) */
- char short_src[LUA_IDSIZE]; /* (S) */
- /* private part */
- other fields
-} lua_Debug;
-
-
-A structure used to carry different pieces of
-information about a function or an activation record.
-lua_getstack fills only the private part
-of this structure, for later use.
-To fill the other fields of lua_Debug with useful information,
-call lua_getinfo.
-
-
-
-The fields of lua_Debug have the following meaning:
-
-
-
-
source:
-the name of the chunk that created the function.
-If source starts with a '@',
-it means that the function was defined in a file where
-the file name follows the '@'.
-If source starts with a '=',
-the remainder of its contents describe the source in a user-dependent manner.
-Otherwise,
-the function was defined in a string where
-source is that string.
-
-
-
short_src:
-a "printable" version of source, to be used in error messages.
-
-
-
linedefined:
-the line number where the definition of the function starts.
-
-
-
lastlinedefined:
-the line number where the definition of the function ends.
-
-
-
what:
-the string "Lua" if the function is a Lua function,
-"C" if it is a C function,
-"main" if it is the main part of a chunk.
-
-
-
currentline:
-the current line where the given function is executing.
-When no line information is available,
-currentline is set to -1.
-
-
-
name:
-a reasonable name for the given function.
-Because functions in Lua are first-class values,
-they do not have a fixed name:
-some functions can be the value of multiple global variables,
-while others can be stored only in a table field.
-The lua_getinfo function checks how the function was
-called to find a suitable name.
-If it cannot find a name,
-then name is set to NULL.
-
-
-
namewhat:
-explains the name field.
-The value of namewhat can be
-"global", "local", "method",
-"field", "upvalue", or "" (the empty string),
-according to how the function was called.
-(Lua uses the empty string when no other option seems to apply.)
-
-
-
istailcall:
-true if this function invocation was called by a tail call.
-In this case, the caller of this level is not in the stack.
-
-
-
nups:
-the number of upvalues of the function.
-
-
-
nparams:
-the number of fixed parameters of the function
-(always 0 for C functions).
-
-
-
isvararg:
-true if the function is a vararg function
-(always true for C functions).
-
int lua_getinfo (lua_State *L, const char *what, lua_Debug *ar);
-
-
-Gets information about a specific function or function invocation.
-
-
-
-To get information about a function invocation,
-the parameter ar must be a valid activation record that was
-filled by a previous call to lua_getstack or
-given as argument to a hook (see lua_Hook).
-
-
-
-To get information about a function you push it onto the stack
-and start the what string with the character '>'.
-(In that case,
-lua_getinfo pops the function from the top of the stack.)
-For instance, to know in which line a function f was defined,
-you can write the following code:
-
-
- lua_Debug ar;
- lua_getglobal(L, "f"); /* get global 'f' */
- lua_getinfo(L, ">S", &ar);
- printf("%d\n", ar.linedefined);
-
-
-
-Each character in the string what
-selects some fields of the structure ar to be filled or
-a value to be pushed on the stack:
-
-
-
-
'n': fills in the field name and namewhat;
-
-
-
'S':
-fills in the fields source, short_src,
-linedefined, lastlinedefined, and what;
-
-
-
'l': fills in the field currentline;
-
-
-
't': fills in the field istailcall;
-
-
-
'u': fills in the fields
-nups, nparams, and isvararg;
-
-
-
'f':
-pushes onto the stack the function that is
-running at the given level;
-
-
-
'L':
-pushes onto the stack a table whose indices are the
-numbers of the lines that are valid on the function.
-(A valid line is a line with some associated code,
-that is, a line where you can put a break point.
-Non-valid lines include empty lines and comments.)
-
-
-
-If this option is given together with option 'f',
-its table is pushed after the function.
-
-
-
-
-
-This function returns 0 on error
-(for instance, an invalid option in what).
-
-
-
-
-
-
const char *lua_getlocal (lua_State *L, const lua_Debug *ar, int n);
-
-
-Gets information about a local variable of
-a given activation record or a given function.
-
-
-
-In the first case,
-the parameter ar must be a valid activation record that was
-filled by a previous call to lua_getstack or
-given as argument to a hook (see lua_Hook).
-The index n selects which local variable to inspect;
-see debug.getlocal for details about variable indices
-and names.
-
-
-
-lua_getlocal pushes the variable's value onto the stack
-and returns its name.
-
-
-
-In the second case, ar must be NULL and the function
-to be inspected must be at the top of the stack.
-In this case, only parameters of Lua functions are visible
-(as there is no information about what variables are active)
-and no values are pushed onto the stack.
-
-
-
-Returns NULL (and pushes nothing)
-when the index is greater than
-the number of active local variables.
-
-
-
-
-
-
int lua_getstack (lua_State *L, int level, lua_Debug *ar);
-
-
-Gets information about the interpreter runtime stack.
-
-
-
-This function fills parts of a lua_Debug structure with
-an identification of the activation record
-of the function executing at a given level.
-Level 0 is the current running function,
-whereas level n+1 is the function that has called level n
-(except for tail calls, which do not count on the stack).
-When there are no errors, lua_getstack returns 1;
-when called with a level greater than the stack depth,
-it returns 0.
-
-
-
-
-
-
const char *lua_getupvalue (lua_State *L, int funcindex, int n);
-
-
-Gets information about a closure's upvalue.
-(For Lua functions,
-upvalues are the external local variables that the function uses,
-and that are consequently included in its closure.)
-lua_getupvalue gets the index n of an upvalue,
-pushes the upvalue's value onto the stack,
-and returns its name.
-funcindex points to the closure in the stack.
-(Upvalues have no particular order,
-as they are active through the whole function.
-So, they are numbered in an arbitrary order.)
-
-
-
-Returns NULL (and pushes nothing)
-when the index is greater than the number of upvalues.
-For C functions, this function uses the empty string ""
-as a name for all upvalues.
-
-
-
-
-
-
-Whenever a hook is called, its ar argument has its field
-event set to the specific event that triggered the hook.
-Lua identifies these events with the following constants:
-LUA_HOOKCALL, LUA_HOOKRET,
-LUA_HOOKTAILCALL, LUA_HOOKLINE,
-and LUA_HOOKCOUNT.
-Moreover, for line events, the field currentline is also set.
-To get the value of any other field in ar,
-the hook must call lua_getinfo.
-
-
-
-For call events, event can be LUA_HOOKCALL,
-the normal value, or LUA_HOOKTAILCALL, for a tail call;
-in this case, there will be no corresponding return event.
-
-
-
-While Lua is running a hook, it disables other calls to hooks.
-Therefore, if a hook calls back Lua to execute a function or a chunk,
-this execution occurs without any calls to hooks.
-
-
-
-Hook functions cannot have continuations,
-that is, they cannot call lua_yieldk,
-lua_pcallk, or lua_callk with a non-null k.
-
-
-
-Hook functions can yield under the following conditions:
-Only count and line events can yield
-and they cannot yield any value;
-to yield a hook function must finish its execution
-calling lua_yield with nresults equal to zero.
-
-
-
-
-
-
void lua_sethook (lua_State *L, lua_Hook f, int mask, int count);
-
-
-Sets the debugging hook function.
-
-
-
-Argument f is the hook function.
-mask specifies on which events the hook will be called:
-it is formed by a bitwise or of the constants
-LUA_MASKCALL,
-LUA_MASKRET,
-LUA_MASKLINE,
-and LUA_MASKCOUNT.
-The count argument is only meaningful when the mask
-includes LUA_MASKCOUNT.
-For each event, the hook is called as explained below:
-
-
-
-
The call hook: is called when the interpreter calls a function.
-The hook is called just after Lua enters the new function,
-before the function gets its arguments.
-
-
-
The return hook: is called when the interpreter returns from a function.
-The hook is called just before Lua leaves the function.
-There is no standard way to access the values
-to be returned by the function.
-
-
-
The line hook: is called when the interpreter is about to
-start the execution of a new line of code,
-or when it jumps back in the code (even to the same line).
-(This event only happens while Lua is executing a Lua function.)
-
-
-
The count hook: is called after the interpreter executes every
-count instructions.
-(This event only happens while Lua is executing a Lua function.)
-
-
-
-
-
-A hook is disabled by setting mask to zero.
-
-
-
-
-
-
const char *lua_setlocal (lua_State *L, const lua_Debug *ar, int n);
-
-
-Sets the value of a local variable of a given activation record.
-Parameters ar and n are as in lua_getlocal
-(see lua_getlocal).
-lua_setlocal assigns the value at the top of the stack
-to the variable and returns its name.
-It also pops the value from the stack.
-
-
-
-Returns NULL (and pops nothing)
-when the index is greater than
-the number of active local variables.
-
-
-
-
-
-
const char *lua_setupvalue (lua_State *L, int funcindex, int n);
-
-
-Sets the value of a closure's upvalue.
-It assigns the value at the top of the stack
-to the upvalue and returns its name.
-It also pops the value from the stack.
-Parameters funcindex and n are as in the lua_getupvalue
-(see lua_getupvalue).
-
-
-
-Returns NULL (and pops nothing)
-when the index is greater than the number of upvalues.
-
-
-
-
-
-
void *lua_upvalueid (lua_State *L, int funcindex, int n);
-
-
-Returns a unique identifier for the upvalue numbered n
-from the closure at index funcindex.
-Parameters funcindex and n are as in the lua_getupvalue
-(see lua_getupvalue)
-(but n cannot be greater than the number of upvalues).
-
-
-
-These unique identifiers allow a program to check whether different
-closures share upvalues.
-Lua closures that share an upvalue
-(that is, that access a same external local variable)
-will return identical ids for those upvalue indices.
-
-
-
-
-
-
-
-The auxiliary library provides several convenient functions
-to interface C with Lua.
-While the basic API provides the primitive functions for all
-interactions between C and Lua,
-the auxiliary library provides higher-level functions for some
-common tasks.
-
-
-
-All functions and types from the auxiliary library
-are defined in header file lauxlib.h and
-have a prefix luaL_.
-
-
-
-All functions in the auxiliary library are built on
-top of the basic API,
-and so they provide nothing that cannot be done with that API.
-Nevertheless, the use of the auxiliary library ensures
-more consistency to your code.
-
-
-
-Several functions in the auxiliary library use internally some
-extra stack slots.
-When a function in the auxiliary library uses less than five slots,
-it does not check the stack size;
-it simply assumes that there are enough slots.
-
-
-
-Several functions in the auxiliary library are used to
-check C function arguments.
-Because the error message is formatted for arguments
-(e.g., "bad argument #1"),
-you should not use these functions for other stack values.
-
-
-
-Functions called luaL_check*
-always raise an error if the check is not satisfied.
-
-
-
-
-Adds the value at the top of the stack
-to the buffer B
-(see luaL_Buffer).
-Pops the value.
-
-
-
-This is the only function on string buffers that can (and must)
-be called with an extra element on the stack,
-which is the value to be added to the buffer.
-
-
-
-
-
-
int luaL_argerror (lua_State *L, int arg, const char *extramsg);
-
-
-Raises an error reporting a problem with argument arg
-of the C function that called it,
-using a standard message
-that includes extramsg as a comment:
-
-
Then initialize it and preallocate a space of
-size sz with a call luaL_buffinitsize(L, &b, sz).
-
-
Then copy the string into that space.
-
-
-Finish by calling luaL_pushresultsize(&b, sz),
-where sz is the total size of the resulting string
-copied into that space.
-
-
-
-
-
-During its normal operation,
-a string buffer uses a variable number of stack slots.
-So, while using a buffer, you cannot assume that you know where
-the top of the stack is.
-You can use the stack between successive calls to buffer operations
-as long as that use is balanced;
-that is,
-when you call a buffer operation,
-the stack is at the same level
-it was immediately after the previous buffer operation.
-(The only exception to this rule is luaL_addvalue.)
-After calling luaL_pushresult the stack is back to its
-level when the buffer was initialized,
-plus the final string on its top.
-
-
-
-
-
-
int luaL_callmeta (lua_State *L, int obj, const char *e);
-
-
-Calls a metamethod.
-
-
-
-If the object at index obj has a metatable and this
-metatable has a field e,
-this function calls this field passing the object as its only argument.
-In this case this function returns true and pushes onto the
-stack the value returned by the call.
-If there is no metatable or no metamethod,
-this function returns false (without pushing any value on the stack).
-
-
-
-
-
-
lua_Integer luaL_checkinteger (lua_State *L, int arg);
-
-
-Checks whether the function argument arg is an integer
-(or can be converted to an integer)
-and returns this integer cast to a lua_Integer.
-
-
-
-
-
-
int luaL_checkoption (lua_State *L,
- int arg,
- const char *def,
- const char *const lst[]);
-
-
-Checks whether the function argument arg is a string and
-searches for this string in the array lst
-(which must be NULL-terminated).
-Returns the index in the array where the string was found.
-Raises an error if the argument is not a string or
-if the string cannot be found.
-
-
-
-If def is not NULL,
-the function uses def as a default value when
-there is no argument arg or when this argument is nil.
-
-
-
-This is a useful function for mapping strings to C enums.
-(The usual convention in Lua libraries is
-to use strings instead of numbers to select options.)
-
-
-
-
-
-
void luaL_checkstack (lua_State *L, int sz, const char *msg);
-
-
-Grows the stack size to top + sz elements,
-raising an error if the stack cannot grow to that size.
-msg is an additional text to go into the error message
-(or NULL for no additional text).
-
-
-
-
-
-
void *luaL_checkudata (lua_State *L, int arg, const char *tname);
-
-
-Checks whether the function argument arg is a userdata
-of the type tname (see luaL_newmetatable) and
-returns the userdata address (see lua_touserdata).
-
-
-
-
-
-
-Checks whether the core running the call,
-the core that created the Lua state,
-and the code making the call are all using the same version of Lua.
-Also checks whether the core running the call
-and the core that created the Lua state
-are using the same address space.
-
-
-
-
-
-
int luaL_error (lua_State *L, const char *fmt, ...);
-
-
-Raises an error.
-The error message format is given by fmt
-plus any extra arguments,
-following the same rules of lua_pushfstring.
-It also adds at the beginning of the message the file name and
-the line number where the error occurred,
-if this information is available.
-
-
-
-This function never returns,
-but it is an idiom to use it in C functions
-as return luaL_error(args).
-
-
-
-
-
-
int luaL_getmetafield (lua_State *L, int obj, const char *e);
-
-
-Pushes onto the stack the field e from the metatable
-of the object at index obj and returns the type of pushed value.
-If the object does not have a metatable,
-or if the metatable does not have this field,
-pushes nothing and returns LUA_TNIL.
-
-
-
-
-
-
int luaL_getmetatable (lua_State *L, const char *tname);
-
-
-Pushes onto the stack the metatable associated with name tname
-in the registry (see luaL_newmetatable).
-If there is no metatable associated with tname,
-returns false and pushes nil.
-
-
-
-
-
-
int luaL_getsubtable (lua_State *L, int idx, const char *fname);
-
-
-Ensures that the value t[fname],
-where t is the value at index idx,
-is a table,
-and pushes that table onto the stack.
-Returns true if it finds a previous table there
-and false if it creates a new table.
-
-
-
-
-
-
-Creates a copy of string s by replacing
-any occurrence of the string p
-with the string r.
-Pushes the resulting string on the stack and returns it.
-
-
-
-
-
-
-Returns the "length" of the value at the given index
-as a number;
-it is equivalent to the '#' operator in Lua (see §3.4.7).
-Raises an error if the result of the operation is not an integer.
-(This case only can happen through metamethods.)
-
-
-
-
-
-
-Loads a buffer as a Lua chunk.
-This function uses lua_load to load the chunk in the
-buffer pointed to by buff with size sz.
-
-
-
-This function returns the same results as lua_load.
-name is the chunk name,
-used for debug information and error messages.
-The string mode works as in function lua_load.
-
-
-
-
-
-
-Loads a file as a Lua chunk.
-This function uses lua_load to load the chunk in the file
-named filename.
-If filename is NULL,
-then it loads from the standard input.
-The first line in the file is ignored if it starts with a #.
-
-
-
-The string mode works as in function lua_load.
-
-
-
-This function returns the same results as lua_load,
-but it has an extra error code LUA_ERRFILE
-if it cannot open/read the file or the file has a wrong mode.
-
-
-
-As lua_load, this function only loads the chunk;
-it does not run it.
-
-
-
-
-
-
-Creates a new table with a size optimized
-to store all entries in the array l
-(but does not actually store them).
-It is intended to be used in conjunction with luaL_setfuncs
-(see luaL_newlib).
-
-
-
-It is implemented as a macro.
-The array l must be the actual array,
-not a pointer to it.
-
-
-
-
-
-
int luaL_newmetatable (lua_State *L, const char *tname);
-
-
-If the registry already has the key tname,
-returns 0.
-Otherwise,
-creates a new table to be used as a metatable for userdata,
-adds to this new table the pair __name = tname,
-adds to the registry the pair [tname] = new table,
-and returns 1.
-(The entry __name is used by some error-reporting functions.)
-
-
-
-In both cases pushes onto the stack the final value associated
-with tname in the registry.
-
-
-
-
-
-
-Creates a new Lua state.
-It calls lua_newstate with an
-allocator based on the standard C realloc function
-and then sets a panic function (see §4.6) that prints
-an error message to the standard error output in case of fatal
-errors.
-
-
-
-Returns the new state,
-or NULL if there is a memory allocation error.
-
-
-
-
-
-
lua_Integer luaL_optinteger (lua_State *L,
- int arg,
- lua_Integer d);
-
-
-If the function argument arg is an integer
-(or convertible to an integer),
-returns this integer.
-If this argument is absent or is nil,
-returns d.
-Otherwise, raises an error.
-
-
-
-
-
-
lua_Number luaL_optnumber (lua_State *L, int arg, lua_Number d);
-
-
-If the function argument arg is a number,
-returns this number.
-If this argument is absent or is nil,
-returns d.
-Otherwise, raises an error.
-
-
-
-
-
-
-If the function argument arg is a string,
-returns this string.
-If this argument is absent or is nil,
-returns d.
-Otherwise, raises an error.
-
-
-
-
-
-
-Returns an address to a space of size sz
-where you can copy a string to be added to buffer B
-(see luaL_Buffer).
-After copying the string into this space you must call
-luaL_addsize with the size of the string to actually add
-it to the buffer.
-
-
-
-
-
-
-Creates and returns a reference,
-in the table at index t,
-for the object at the top of the stack (and pops the object).
-
-
-
-A reference is a unique integer key.
-As long as you do not manually add integer keys into table t,
-luaL_ref ensures the uniqueness of the key it returns.
-You can retrieve an object referred by reference r
-by calling lua_rawgeti(L, t, r).
-Function luaL_unref frees a reference and its associated object.
-
-
-
-If the object at the top of the stack is nil,
-luaL_ref returns the constant LUA_REFNIL.
-The constant LUA_NOREF is guaranteed to be different
-from any reference returned by luaL_ref.
-
-
-
-
-
-
-Type for arrays of functions to be registered by
-luaL_setfuncs.
-name is the function name and func is a pointer to
-the function.
-Any array of luaL_Reg must end with a sentinel entry
-in which both name and func are NULL.
-
-
-
-
-
-
-If modname is not already present in package.loaded,
-calls function openf with string modname as an argument
-and sets the call result in package.loaded[modname],
-as if that function has been called through require.
-
-
-
-If glb is true,
-also stores the module into global modname.
-
-
-
-Leaves a copy of the module on the stack.
-
-
-
-
-
-
void luaL_setfuncs (lua_State *L, const luaL_Reg *l, int nup);
-
-
-Registers all functions in the array l
-(see luaL_Reg) into the table on the top of the stack
-(below optional upvalues, see next).
-
-
-
-When nup is not zero,
-all functions are created sharing nup upvalues,
-which must be previously pushed on the stack
-on top of the library table.
-These values are popped from the stack after the registration.
-
-
-
-
-
-
-Sets the metatable of the object at the top of the stack
-as the metatable associated with name tname
-in the registry (see luaL_newmetatable).
-
-
-
-
-
-
-The standard representation for file handles,
-which is used by the standard I/O library.
-
-
-
-A file handle is implemented as a full userdata,
-with a metatable called LUA_FILEHANDLE
-(where LUA_FILEHANDLE is a macro with the actual metatable's name).
-The metatable is created by the I/O library
-(see luaL_newmetatable).
-
-
-
-This userdata must start with the structure luaL_Stream;
-it can contain other data after this initial structure.
-Field f points to the corresponding C stream
-(or it can be NULL to indicate an incompletely created handle).
-Field closef points to a Lua function
-that will be called to close the stream
-when the handle is closed or collected;
-this function receives the file handle as its sole argument and
-must return either true (in case of success)
-or nil plus an error message (in case of error).
-Once Lua calls this field,
-the field value is changed to NULL
-to signal that the handle is closed.
-
-
-
-
-
-
const char *luaL_tolstring (lua_State *L, int idx, size_t *len);
-
-
-Converts any Lua value at the given index to a C string
-in a reasonable format.
-The resulting string is pushed onto the stack and also
-returned by the function.
-If len is not NULL,
-the function also sets *len with the string length.
-
-
-
-If the value has a metatable with a "__tostring" field,
-then luaL_tolstring calls the corresponding metamethod
-with the value as argument,
-and uses the result of the call as its result.
-
-
-
-
-
-
-Creates and pushes a traceback of the stack L1.
-If msg is not NULL it is appended
-at the beginning of the traceback.
-The level parameter tells at which level
-to start the traceback.
-
-
-
-
-
-
-Releases reference ref from the table at index t
-(see luaL_ref).
-The entry is removed from the table,
-so that the referred object can be collected.
-The reference ref is also freed to be used again.
-
-
-
-Pushes onto the stack a string identifying the current position
-of the control at level lvl in the call stack.
-Typically this string has the following format:
-
-
- chunkname:currentline:
-
-Level 0 is the running function,
-level 1 is the function that called the running function,
-etc.
-
-
-
-This function is used to build a prefix for error messages.
-
-
-
-
-
-
-
-
-The standard Lua libraries provide useful functions
-that are implemented directly through the C API.
-Some of these functions provide essential services to the language
-(e.g., type and getmetatable);
-others provide access to "outside" services (e.g., I/O);
-and others could be implemented in Lua itself,
-but are quite useful or have critical performance requirements that
-deserve an implementation in C (e.g., table.sort).
-
-
-
-All libraries are implemented through the official C API
-and are provided as separate C modules.
-Currently, Lua has the following standard libraries:
-
-
-Except for the basic and the package libraries,
-each library provides all its functions as fields of a global table
-or as methods of its objects.
-
-
-
-To have access to these libraries,
-the C host program should call the luaL_openlibs function,
-which opens all standard libraries.
-Alternatively,
-the host program can open them individually by using
-luaL_requiref to call
-luaopen_base (for the basic library),
-luaopen_package (for the package library),
-luaopen_coroutine (for the coroutine library),
-luaopen_string (for the string library),
-luaopen_utf8 (for the UTF8 library),
-luaopen_table (for the table library),
-luaopen_math (for the mathematical library),
-luaopen_io (for the I/O library),
-luaopen_os (for the operating system library),
-and luaopen_debug (for the debug library).
-These functions are declared in lualib.h.
-
-
-
-
-The basic library provides core functions to Lua.
-If you do not include this library in your application,
-you should check carefully whether you need to provide
-implementations for some of its facilities.
-
-
-
-Calls error if
-the value of its argument v is false (i.e., nil or false);
-otherwise, returns all its arguments.
-In case of error,
-message is the error object;
-when absent, it defaults to "assertion failed!"
-
-
-
-
-
-This function is a generic interface to the garbage collector.
-It performs different functions according to its first argument, opt:
-
-
-
-
"collect":
-performs a full garbage-collection cycle.
-This is the default option.
-
-
-
"stop":
-stops automatic execution of the garbage collector.
-The collector will run only when explicitly invoked,
-until a call to restart it.
-
-
-
"restart":
-restarts automatic execution of the garbage collector.
-
-
-
"count":
-returns the total memory in use by Lua in Kbytes.
-The value has a fractional part,
-so that it multiplied by 1024
-gives the exact number of bytes in use by Lua
-(except for overflows).
-
-
-
"step":
-performs a garbage-collection step.
-The step "size" is controlled by arg.
-With a zero value,
-the collector will perform one basic (indivisible) step.
-For non-zero values,
-the collector will perform as if that amount of memory
-(in KBytes) had been allocated by Lua.
-Returns true if the step finished a collection cycle.
-
-
-
"setpause":
-sets arg as the new value for the pause of
-the collector (see §2.5).
-Returns the previous value for pause.
-
-
-
"setstepmul":
-sets arg as the new value for the step multiplier of
-the collector (see §2.5).
-Returns the previous value for step.
-
-
-
"isrunning":
-returns a boolean that tells whether the collector is running
-(i.e., not stopped).
-
-Opens the named file and executes its contents as a Lua chunk.
-When called without arguments,
-dofile executes the contents of the standard input (stdin).
-Returns all values returned by the chunk.
-In case of errors, dofile propagates the error
-to its caller (that is, dofile does not run in protected mode).
-
-
-
-
-
-Terminates the last protected function called
-and returns message as the error object.
-Function error never returns.
-
-
-
-Usually, error adds some information about the error position
-at the beginning of the message, if the message is a string.
-The level argument specifies how to get the error position.
-With level 1 (the default), the error position is where the
-error function was called.
-Level 2 points the error to where the function
-that called error was called; and so on.
-Passing a level 0 avoids the addition of error position information
-to the message.
-
-
-
-
-
-A global variable (not a function) that
-holds the global environment (see §2.2).
-Lua itself does not use this variable;
-changing its value does not affect any environment,
-nor vice versa.
-
-
-
-
-
-If object does not have a metatable, returns nil.
-Otherwise,
-if the object's metatable has a "__metatable" field,
-returns the associated value.
-Otherwise, returns the metatable of the given object.
-
-
-
-
-
-If chunk is a string, the chunk is this string.
-If chunk is a function,
-load calls it repeatedly to get the chunk pieces.
-Each call to chunk must return a string that concatenates
-with previous results.
-A return of an empty string, nil, or no value signals the end of the chunk.
-
-
-
-If there are no syntactic errors,
-returns the compiled chunk as a function;
-otherwise, returns nil plus the error message.
-
-
-
-If the resulting function has upvalues,
-the first upvalue is set to the value of env,
-if that parameter is given,
-or to the value of the global environment.
-Other upvalues are initialized with nil.
-(When you load a main chunk,
-the resulting function will always have exactly one upvalue,
-the _ENV variable (see §2.2).
-However,
-when you load a binary chunk created from a function (see string.dump),
-the resulting function can have an arbitrary number of upvalues.)
-All upvalues are fresh, that is,
-they are not shared with any other function.
-
-
-
-chunkname is used as the name of the chunk for error messages
-and debug information (see §4.9).
-When absent,
-it defaults to chunk, if chunk is a string,
-or to "=(load)" otherwise.
-
-
-
-The string mode controls whether the chunk can be text or binary
-(that is, a precompiled chunk).
-It may be the string "b" (only binary chunks),
-"t" (only text chunks),
-or "bt" (both binary and text).
-The default is "bt".
-
-
-
-Lua does not check the consistency of binary chunks.
-Maliciously crafted binary chunks can crash
-the interpreter.
-
-
-
-
-
-Allows a program to traverse all fields of a table.
-Its first argument is a table and its second argument
-is an index in this table.
-next returns the next index of the table
-and its associated value.
-When called with nil as its second argument,
-next returns an initial index
-and its associated value.
-When called with the last index,
-or with nil in an empty table,
-next returns nil.
-If the second argument is absent, then it is interpreted as nil.
-In particular,
-you can use next(t) to check whether a table is empty.
-
-
-
-The order in which the indices are enumerated is not specified,
-even for numeric indices.
-(To traverse a table in numeric order,
-use a numerical for.)
-
-
-
-The behavior of next is undefined if,
-during the traversal,
-you assign any value to a non-existent field in the table.
-You may however modify existing fields.
-In particular, you may clear existing fields.
-
-
-
-
-
-Calls function f with
-the given arguments in protected mode.
-This means that any error inside f is not propagated;
-instead, pcall catches the error
-and returns a status code.
-Its first result is the status code (a boolean),
-which is true if the call succeeds without errors.
-In such case, pcall also returns all results from the call,
-after this first result.
-In case of any error, pcall returns false plus the error message.
-
-
-
-
-
-Receives any number of arguments
-and prints their values to stdout,
-using the tostring function to convert each argument to a string.
-print is not intended for formatted output,
-but only as a quick way to show a value,
-for instance for debugging.
-For complete control over the output,
-use string.format and io.write.
-
-
-
-
-
-Sets the real value of table[index] to value,
-without invoking any metamethod.
-table must be a table,
-index any value different from nil and NaN,
-and value any Lua value.
-
-
-
-If index is a number,
-returns all arguments after argument number index;
-a negative number indexes from the end (-1 is the last argument).
-Otherwise, index must be the string "#",
-and select returns the total number of extra arguments it received.
-
-
-
-
-
-Sets the metatable for the given table.
-(You cannot change the metatable of other types from Lua, only from C.)
-If metatable is nil,
-removes the metatable of the given table.
-If the original metatable has a "__metatable" field,
-raises an error.
-
-
-
-When called with no base,
-tonumber tries to convert its argument to a number.
-If the argument is already a number or
-a string convertible to a number,
-then tonumber returns this number;
-otherwise, it returns nil.
-
-
-
-The conversion of strings can result in integers or floats,
-according to the lexical conventions of Lua (see §3.1).
-(The string may have leading and trailing spaces and a sign.)
-
-
-
-When called with base,
-then e must be a string to be interpreted as
-an integer numeral in that base.
-The base may be any integer between 2 and 36, inclusive.
-In bases above 10, the letter 'A' (in either upper or lower case)
-represents 10, 'B' represents 11, and so forth,
-with 'Z' representing 35.
-If the string e is not a valid numeral in the given base,
-the function returns nil.
-
-
-
-
-
-Receives a value of any type and
-converts it to a string in a human-readable format.
-Floats always produce strings with some
-floating-point indication (either a decimal dot or an exponent).
-(For complete control of how numbers are converted,
-use string.format.)
-
-
-
-If the metatable of v has a "__tostring" field,
-then tostring calls the corresponding value
-with v as argument,
-and uses the result of the call as its result.
-
-
-
-
-
-Returns the type of its only argument, coded as a string.
-The possible results of this function are
-"nil" (a string, not the value nil),
-"number",
-"string",
-"boolean",
-"table",
-"function",
-"thread",
-and "userdata".
-
-
-
-
-
-A global variable (not a function) that
-holds a string containing the current interpreter version.
-The current value of this variable is "Lua 5.3".
-
-
-
-
-
-The operations related to coroutines comprise a sub-library of
-the basic library and come inside the table coroutine.
-See §2.6 for a general description of coroutines.
-
-
-
-Starts or continues the execution of coroutine co.
-The first time you resume a coroutine,
-it starts running its body.
-The values val1, ... are passed
-as the arguments to the body function.
-If the coroutine has yielded,
-resume restarts it;
-the values val1, ... are passed
-as the results from the yield.
-
-
-
-If the coroutine runs without any errors,
-resume returns true plus any values passed to yield
-(when the coroutine yields) or any values returned by the body function
-(when the coroutine terminates).
-If there is any error,
-resume returns false plus the error message.
-
-
-
-
-
-Returns the status of coroutine co, as a string:
-"running",
-if the coroutine is running (that is, it called status);
-"suspended", if the coroutine is suspended in a call to yield,
-or if it has not started running yet;
-"normal" if the coroutine is active but not running
-(that is, it has resumed another coroutine);
-and "dead" if the coroutine has finished its body function,
-or if it has stopped with an error.
-
-
-
-
-
-Creates a new coroutine, with body f.
-f must be a Lua function.
-Returns a function that resumes the coroutine each time it is called.
-Any arguments passed to the function behave as the
-extra arguments to resume.
-Returns the same values returned by resume,
-except the first boolean.
-In case of error, propagates the error.
-
-
-
-
-
-The package library provides basic
-facilities for loading modules in Lua.
-It exports one function directly in the global environment:
-require.
-Everything else is exported in a table package.
-
-
-
-Loads the given module.
-The function starts by looking into the package.loaded table
-to determine whether modname is already loaded.
-If it is, then require returns the value stored
-at package.loaded[modname].
-Otherwise, it tries to find a loader for the module.
-
-
-
-To find a loader,
-require is guided by the package.searchers sequence.
-By changing this sequence,
-we can change how require looks for a module.
-The following explanation is based on the default configuration
-for package.searchers.
-
-
-
-First require queries package.preload[modname].
-If it has a value,
-this value (which must be a function) is the loader.
-Otherwise require searches for a Lua loader using the
-path stored in package.path.
-If that also fails, it searches for a C loader using the
-path stored in package.cpath.
-If that also fails,
-it tries an all-in-one loader (see package.searchers).
-
-
-
-Once a loader is found,
-require calls the loader with two arguments:
-modname and an extra value dependent on how it got the loader.
-(If the loader came from a file,
-this extra value is the file name.)
-If the loader returns any non-nil value,
-require assigns the returned value to package.loaded[modname].
-If the loader does not return a non-nil value and
-has not assigned any value to package.loaded[modname],
-then require assigns true to this entry.
-In any case, require returns the
-final value of package.loaded[modname].
-
-
-
-If there is any error loading or running the module,
-or if it cannot find any loader for the module,
-then require raises an error.
-
-
-
-
-
-The path used by require to search for a C loader.
-
-
-
-Lua initializes the C path package.cpath in the same way
-it initializes the Lua path package.path,
-using the environment variable LUA_CPATH_5_3
-or the environment variable LUA_CPATH
-or a default path defined in luaconf.h.
-
-
-
-
-
-A table used by require to control which
-modules are already loaded.
-When you require a module modname and
-package.loaded[modname] is not false,
-require simply returns the value stored there.
-
-
-
-This variable is only a reference to the real table;
-assignments to this variable do not change the
-table used by require.
-
-
-
-
-
-Dynamically links the host program with the C library libname.
-
-
-
-If funcname is "*",
-then it only links with the library,
-making the symbols exported by the library
-available to other dynamically linked libraries.
-Otherwise,
-it looks for a function funcname inside the library
-and returns this function as a C function.
-So, funcname must follow the lua_CFunction prototype
-(see lua_CFunction).
-
-
-
-This is a low-level function.
-It completely bypasses the package and module system.
-Unlike require,
-it does not perform any path searching and
-does not automatically adds extensions.
-libname must be the complete file name of the C library,
-including if necessary a path and an extension.
-funcname must be the exact name exported by the C library
-(which may depend on the C compiler and linker used).
-
-
-
-This function is not supported by Standard C.
-As such, it is only available on some platforms
-(Windows, Linux, Mac OS X, Solaris, BSD,
-plus other Unix systems that support the dlfcn standard).
-
-
-
-
-
-The path used by require to search for a Lua loader.
-
-
-
-At start-up, Lua initializes this variable with
-the value of the environment variable LUA_PATH_5_3 or
-the environment variable LUA_PATH or
-with a default path defined in luaconf.h,
-if those environment variables are not defined.
-Any ";;" in the value of the environment variable
-is replaced by the default path.
-
-
-
-
-
-A table used by require to control how to load modules.
-
-
-
-Each entry in this table is a searcher function.
-When looking for a module,
-require calls each of these searchers in ascending order,
-with the module name (the argument given to require) as its
-sole parameter.
-The function can return another function (the module loader)
-plus an extra value that will be passed to that loader,
-or a string explaining why it did not find that module
-(or nil if it has nothing to say).
-
-
-
-Lua initializes this table with four searcher functions.
-
-
-
-The first searcher simply looks for a loader in the
-package.preload table.
-
-
-
-The second searcher looks for a loader as a Lua library,
-using the path stored at package.path.
-The search is done as described in function package.searchpath.
-
-
-
-The third searcher looks for a loader as a C library,
-using the path given by the variable package.cpath.
-Again,
-the search is done as described in function package.searchpath.
-For instance,
-if the C path is the string
-
-
- "./?.so;./?.dll;/usr/local/?/init.so"
-
-the searcher for module foo
-will try to open the files ./foo.so, ./foo.dll,
-and /usr/local/foo/init.so, in that order.
-Once it finds a C library,
-this searcher first uses a dynamic link facility to link the
-application with the library.
-Then it tries to find a C function inside the library to
-be used as the loader.
-The name of this C function is the string "luaopen_"
-concatenated with a copy of the module name where each dot
-is replaced by an underscore.
-Moreover, if the module name has a hyphen,
-its suffix after (and including) the first hyphen is removed.
-For instance, if the module name is a.b.c-v2.1,
-the function name will be luaopen_a_b_c.
-
-
-
-The fourth searcher tries an all-in-one loader.
-It searches the C path for a library for
-the root name of the given module.
-For instance, when requiring a.b.c,
-it will search for a C library for a.
-If found, it looks into it for an open function for
-the submodule;
-in our example, that would be luaopen_a_b_c.
-With this facility, a package can pack several C submodules
-into one single library,
-with each submodule keeping its original open function.
-
-
-
-All searchers except the first one (preload) return as the extra value
-the file name where the module was found,
-as returned by package.searchpath.
-The first searcher returns no extra value.
-
-
-
-
-
-Searches for the given name in the given path.
-
-
-
-A path is a string containing a sequence of
-templates separated by semicolons.
-For each template,
-the function replaces each interrogation mark (if any)
-in the template with a copy of name
-wherein all occurrences of sep
-(a dot, by default)
-were replaced by rep
-(the system's directory separator, by default),
-and then tries to open the resulting file name.
-
-
-
-For instance, if the path is the string
-
-
- "./?.lua;./?.lc;/usr/local/?/init.lua"
-
-the search for the name foo.a
-will try to open the files
-./foo/a.lua, ./foo/a.lc, and
-/usr/local/foo/a/init.lua, in that order.
-
-
-
-Returns the resulting name of the first file that it can
-open in read mode (after closing the file),
-or nil plus an error message if none succeeds.
-(This error message lists all file names it tried to open.)
-
-
-
-
-
-
-
-
-This library provides generic functions for string manipulation,
-such as finding and extracting substrings, and pattern matching.
-When indexing a string in Lua, the first character is at position 1
-(not at 0, as in C).
-Indices are allowed to be negative and are interpreted as indexing backwards,
-from the end of the string.
-Thus, the last character is at position -1, and so on.
-
-
-
-The string library provides all its functions inside the table
-string.
-It also sets a metatable for strings
-where the __index field points to the string table.
-Therefore, you can use the string functions in object-oriented style.
-For instance, string.byte(s,i)
-can be written as s:byte(i).
-
-
-
-The string library assumes one-byte character encodings.
-
-
-
-Returns the internal numerical codes of the characters s[i],
-s[i+1], ..., s[j].
-The default value for i is 1;
-the default value for j is i.
-These indices are corrected
-following the same rules of function string.sub.
-
-
-
-Numerical codes are not necessarily portable across platforms.
-
-
-
-
-
-Receives zero or more integers.
-Returns a string with length equal to the number of arguments,
-in which each character has the internal numerical code equal
-to its corresponding argument.
-
-
-
-Numerical codes are not necessarily portable across platforms.
-
-
-
-
-
-Returns a string containing a binary representation
-(a binary chunk)
-of the given function,
-so that a later load on this string returns
-a copy of the function (but with new upvalues).
-If strip is a true value,
-the binary representation is created without debug information
-about the function
-(local variable names, lines, etc.).
-
-
-
-Functions with upvalues have only their number of upvalues saved.
-When (re)loaded,
-those upvalues receive fresh instances containing nil.
-(You can use the debug library to serialize
-and reload the upvalues of a function
-in a way adequate to your needs.)
-
-
-
-
-
-Looks for the first match of
-pattern (see §6.4.1) in the string s.
-If it finds a match, then find returns the indices of s
-where this occurrence starts and ends;
-otherwise, it returns nil.
-A third, optional numerical argument init specifies
-where to start the search;
-its default value is 1 and can be negative.
-A value of true as a fourth, optional argument plain
-turns off the pattern matching facilities,
-so the function does a plain "find substring" operation,
-with no characters in pattern being considered magic.
-Note that if plain is given, then init must be given as well.
-
-
-
-If the pattern has captures,
-then in a successful match
-the captured values are also returned,
-after the two indices.
-
-
-
-
-
-Returns a formatted version of its variable number of arguments
-following the description given in its first argument (which must be a string).
-The format string follows the same rules as the ISO C function sprintf.
-The only differences are that the options/modifiers
-*, h, L, l, n,
-and p are not supported
-and that there is an extra option, q.
-The q option formats a string between double quotes,
-using escape sequences when necessary to ensure that
-it can safely be read back by the Lua interpreter.
-For instance, the call
-
-
- string.format('%q', 'a string with "quotes" and \n new line')
-
-may produce the string:
-
-
- "a string with \"quotes\" and \
- new line"
-
-
-
-Options
-A and a (when available),
-E, e, f,
-G, and g all expect a number as argument.
-Options c, d,
-i, o, u, X, and x
-expect an integer.
-Option q expects a string;
-option s expects a string without embedded zeros.
-If the argument to option s is not a string,
-it is converted to one following the same rules of tostring.
-
-
-
-
-
-Returns an iterator function that,
-each time it is called,
-returns the next captures from pattern (see §6.4.1)
-over the string s.
-If pattern specifies no captures,
-then the whole match is produced in each call.
-
-
-
-As an example, the following loop
-will iterate over all the words from string s,
-printing one per line:
-
-
- s = "hello world from Lua"
- for w in string.gmatch(s, "%a+") do
- print(w)
- end
-
-The next example collects all pairs key=value from the
-given string into a table:
-
-
- t = {}
- s = "from=world, to=Lua"
- for k, v in string.gmatch(s, "(%w+)=(%w+)") do
- t[k] = v
- end
-
-
-
-For this function, a caret '^' at the start of a pattern does not
-work as an anchor, as this would prevent the iteration.
-
-
-
-
-
-Returns a copy of s
-in which all (or the first n, if given)
-occurrences of the pattern (see §6.4.1) have been
-replaced by a replacement string specified by repl,
-which can be a string, a table, or a function.
-gsub also returns, as its second value,
-the total number of matches that occurred.
-The name gsub comes from Global SUBstitution.
-
-
-
-If repl is a string, then its value is used for replacement.
-The character % works as an escape character:
-any sequence in repl of the form %d,
-with d between 1 and 9,
-stands for the value of the d-th captured substring.
-The sequence %0 stands for the whole match.
-The sequence %% stands for a single %.
-
-
-
-If repl is a table, then the table is queried for every match,
-using the first capture as the key.
-
-
-
-If repl is a function, then this function is called every time a
-match occurs, with all captured substrings passed as arguments,
-in order.
-
-
-
-In any case,
-if the pattern specifies no captures,
-then it behaves as if the whole pattern was inside a capture.
-
-
-
-If the value returned by the table query or by the function call
-is a string or a number,
-then it is used as the replacement string;
-otherwise, if it is false or nil,
-then there is no replacement
-(that is, the original match is kept in the string).
-
-
-
-Here are some examples:
-
-
- x = string.gsub("hello world", "(%w+)", "%1 %1")
- --> x="hello hello world world"
-
- x = string.gsub("hello world", "%w+", "%0 %0", 1)
- --> x="hello hello world"
-
- x = string.gsub("hello world from Lua", "(%w+)%s*(%w+)", "%2 %1")
- --> x="world hello Lua from"
-
- x = string.gsub("home = $HOME, user = $USER", "%$(%w+)", os.getenv)
- --> x="home = /home/roberto, user = roberto"
-
- x = string.gsub("4+5 = $return 4+5$", "%$(.-)%$", function (s)
- return load(s)()
- end)
- --> x="4+5 = 9"
-
- local t = {name="lua", version="5.3"}
- x = string.gsub("$name-$version.tar.gz", "%$(%w+)", t)
- --> x="lua-5.3.tar.gz"
-
-Receives a string and returns a copy of this string with all
-uppercase letters changed to lowercase.
-All other characters are left unchanged.
-The definition of what an uppercase letter is depends on the current locale.
-
-
-
-
-
-Looks for the first match of
-pattern (see §6.4.1) in the string s.
-If it finds one, then match returns
-the captures from the pattern;
-otherwise it returns nil.
-If pattern specifies no captures,
-then the whole match is returned.
-A third, optional numerical argument init specifies
-where to start the search;
-its default value is 1 and can be negative.
-
-
-
-
-
-Returns a binary string containing the values v1, v2, etc.
-packed (that is, serialized in binary form)
-according to the format string fmt (see §6.4.2).
-
-
-
-
-
-Returns the size of a string resulting from string.pack
-with the given format.
-The format string cannot have the variable-length options
-'s' or 'z' (see §6.4.2).
-
-
-
-
-
-Returns a string that is the concatenation of n copies of
-the string s separated by the string sep.
-The default value for sep is the empty string
-(that is, no separator).
-Returns the empty string if n is not positive.
-
-
-
-
-
-Returns the substring of s that
-starts at i and continues until j;
-i and j can be negative.
-If j is absent, then it is assumed to be equal to -1
-(which is the same as the string length).
-In particular,
-the call string.sub(s,1,j) returns a prefix of s
-with length j,
-and string.sub(s, -i) returns a suffix of s
-with length i.
-
-
-
-If, after the translation of negative indices,
-i is less than 1,
-it is corrected to 1.
-If j is greater than the string length,
-it is corrected to that length.
-If, after these corrections,
-i is greater than j,
-the function returns the empty string.
-
-
-
-
-
-Returns the values packed in string s (see string.pack)
-according to the format string fmt (see §6.4.2).
-An optional pos marks where
-to start reading in s (default is 1).
-After the read values,
-this function also returns the index of the first unread byte in s.
-
-
-
-
-
-Receives a string and returns a copy of this string with all
-lowercase letters changed to uppercase.
-All other characters are left unchanged.
-The definition of what a lowercase letter is depends on the current locale.
-
-
-
-
-
-
-Patterns in Lua are described by regular strings,
-which are interpreted as patterns by the pattern-matching functions
-string.find,
-string.gmatch,
-string.gsub,
-and string.match.
-This section describes the syntax and the meaning
-(that is, what they match) of these strings.
-
-
-
-
Character Class:
-A character class is used to represent a set of characters.
-The following combinations are allowed in describing a character class:
-
-
-
-
x:
-(where x is not one of the magic characters
-^$()%.[]*+-?)
-represents the character x itself.
-
-
-
.: (a dot) represents all characters.
-
-
%a: represents all letters.
-
-
%c: represents all control characters.
-
-
%d: represents all digits.
-
-
%g: represents all printable characters except space.
-
-
%l: represents all lowercase letters.
-
-
%p: represents all punctuation characters.
-
-
%s: represents all space characters.
-
-
%u: represents all uppercase letters.
-
-
%w: represents all alphanumeric characters.
-
-
%x: represents all hexadecimal digits.
-
-
%x: (where x is any non-alphanumeric character)
-represents the character x.
-This is the standard way to escape the magic characters.
-Any non-alphanumeric character
-(including all punctuations, even the non-magical)
-can be preceded by a '%'
-when used to represent itself in a pattern.
-
-
-
[set]:
-represents the class which is the union of all
-characters in set.
-A range of characters can be specified by
-separating the end characters of the range,
-in ascending order, with a '-'.
-All classes %x described above can also be used as
-components in set.
-All other characters in set represent themselves.
-For example, [%w_] (or [_%w])
-represents all alphanumeric characters plus the underscore,
-[0-7] represents the octal digits,
-and [0-7%l%-] represents the octal digits plus
-the lowercase letters plus the '-' character.
-
-
-
-The interaction between ranges and classes is not defined.
-Therefore, patterns like [%a-z] or [a-%%]
-have no meaning.
-
-
-
[^set]:
-represents the complement of set,
-where set is interpreted as above.
-
-
-
-For all classes represented by single letters (%a, %c, etc.),
-the corresponding uppercase letter represents the complement of the class.
-For instance, %S represents all non-space characters.
-
-
-
-The definitions of letter, space, and other character groups
-depend on the current locale.
-In particular, the class [a-z] may not be equivalent to %l.
-
-
-
-
-
-
Pattern Item:
-A pattern item can be
-
-
-
-
-a single character class,
-which matches any single character in the class;
-
-
-
-a single character class followed by '*',
-which matches zero or more repetitions of characters in the class.
-These repetition items will always match the longest possible sequence;
-
-
-
-a single character class followed by '+',
-which matches one or more repetitions of characters in the class.
-These repetition items will always match the longest possible sequence;
-
-
-
-a single character class followed by '-',
-which also matches zero or more repetitions of characters in the class.
-Unlike '*',
-these repetition items will always match the shortest possible sequence;
-
-
-
-a single character class followed by '?',
-which matches zero or one occurrence of a character in the class.
-It always matches one occurrence if possible;
-
-
-
-%n, for n between 1 and 9;
-such item matches a substring equal to the n-th captured string
-(see below);
-
-
-
-%bxy, where x and y are two distinct characters;
-such item matches strings that start with x, end with y,
-and where the x and y are balanced.
-This means that, if one reads the string from left to right,
-counting +1 for an x and -1 for a y,
-the ending y is the first y where the count reaches 0.
-For instance, the item %b() matches expressions with
-balanced parentheses.
-
-
-
-%f[set], a frontier pattern;
-such item matches an empty string at any position such that
-the next character belongs to set
-and the previous character does not belong to set.
-The set set is interpreted as previously described.
-The beginning and the end of the subject are handled as if
-they were the character '\0'.
-
-
-
-
-
-
-
-
Pattern:
-A pattern is a sequence of pattern items.
-A caret '^' at the beginning of a pattern anchors the match at the
-beginning of the subject string.
-A '$' at the end of a pattern anchors the match at the
-end of the subject string.
-At other positions,
-'^' and '$' have no special meaning and represent themselves.
-
-
-
-
-
-
Captures:
-A pattern can contain sub-patterns enclosed in parentheses;
-they describe captures.
-When a match succeeds, the substrings of the subject string
-that match captures are stored (captured) for future use.
-Captures are numbered according to their left parentheses.
-For instance, in the pattern "(a*(.)%w(%s*))",
-the part of the string matching "a*(.)%w(%s*)" is
-stored as the first capture (and therefore has number 1);
-the character matching "." is captured with number 2,
-and the part matching "%s*" has number 3.
-
-
-
-As a special case, the empty capture () captures
-the current string position (a number).
-For instance, if we apply the pattern "()aa()" on the
-string "flaaap", there will be two captures: 3 and 5.
-
-
-
-
-
-
-
-
-The first argument to string.pack,
-string.packsize, and string.unpack
-is a format string,
-which describes the layout of the structure being created or read.
-
-
-
-A format string is a sequence of conversion options.
-The conversion options are as follows:
-
-
-
<: sets little endian
-
>: sets big endian
-
=: sets native endian
-
![n]: sets maximum alignment to n
-(default is native alignment)
-
b: a signed byte (char)
-
B: an unsigned byte (char)
-
h: a signed short (native size)
-
H: an unsigned short (native size)
-
l: a signed long (native size)
-
L: an unsigned long (native size)
-
j: a lua_Integer
-
J: a lua_Unsigned
-
T: a size_t (native size)
-
i[n]: a signed int with n bytes
-(default is native size)
-
I[n]: an unsigned int with n bytes
-(default is native size)
-
f: a float (native size)
-
d: a double (native size)
-
n: a lua_Number
-
cn: a fixed-sized string with n bytes
-
z: a zero-terminated string
-
s[n]: a string preceded by its length
-coded as an unsigned integer with n bytes
-(default is a size_t)
-
x: one byte of padding
-
Xop: an empty item that aligns
-according to option op
-(which is otherwise ignored)
-
'': (empty space) ignored
-
-(A "[n]" means an optional integral numeral.)
-Except for padding, spaces, and configurations
-(options "xX <=>!"),
-each option corresponds to an argument (in string.pack)
-or a result (in string.unpack).
-
-
-
-For options "!n", "sn", "in", and "In",
-n can be any integer between 1 and 16.
-All integral options check overflows;
-string.pack checks whether the given value fits in the given size;
-string.unpack checks whether the read value fits in a Lua integer.
-
-
-
-Any format string starts as if prefixed by "!1=",
-that is,
-with maximum alignment of 1 (no alignment)
-and native endianness.
-
-
-
-Alignment works as follows:
-For each option,
-the format gets extra padding until the data starts
-at an offset that is a multiple of the minimum between the
-option size and the maximum alignment;
-this minimum must be a power of 2.
-Options "c" and "z" are not aligned;
-option "s" follows the alignment of its starting integer.
-
-
-
-All padding is filled with zeros by string.pack
-(and ignored by string.unpack).
-
-
-
-
-
-
-
-
-This library provides basic support for UTF-8 encoding.
-It provides all its functions inside the table utf8.
-This library does not provide any support for Unicode other
-than the handling of the encoding.
-Any operation that needs the meaning of a character,
-such as character classification, is outside its scope.
-
-
-
-Unless stated otherwise,
-all functions that expect a byte position as a parameter
-assume that the given position is either the start of a byte sequence
-or one plus the length of the subject string.
-As in the string library,
-negative indices count from the end of the string.
-
-
-
-Receives zero or more integers,
-converts each one to its corresponding UTF-8 byte sequence
-and returns a string with the concatenation of all these sequences.
-
-
-
-
-
-The pattern (a string, not a function) "[\0-\x7F\xC2-\xF4][\x80-\xBF]*"
-(see §6.4.1),
-which matches exactly one UTF-8 byte sequence,
-assuming that the subject is a valid UTF-8 string.
-
-
-
-
-
-will iterate over all characters in string s,
-with p being the position (in bytes) and c the code point
-of each character.
-It raises an error if it meets any invalid byte sequence.
-
-
-
-
-
-Returns the codepoints (as integers) from all characters in s
-that start between byte position i and j (both included).
-The default for i is 1 and for j is i.
-It raises an error if it meets any invalid byte sequence.
-
-
-
-
-
-Returns the number of UTF-8 characters in string s
-that start between positions i and j (both inclusive).
-The default for i is 1 and for j is -1.
-If it finds any invalid byte sequence,
-returns a false value plus the position of the first invalid byte.
-
-
-
-
-
-Returns the position (in bytes) where the encoding of the
-n-th character of s
-(counting from position i) starts.
-A negative n gets characters before position i.
-The default for i is 1 when n is non-negative
-and #s + 1 otherwise,
-so that utf8.offset(s, -n) gets the offset of the
-n-th character from the end of the string.
-If the specified character is neither in the subject
-nor right after its end,
-the function returns nil.
-
-
-
-As a special case,
-when n is 0 the function returns the start of the encoding
-of the character that contains the i-th byte of s.
-
-
-
-This function assumes that s is a valid UTF-8 string.
-
-
-
-
-
-
-
-
-This library provides generic functions for table manipulation.
-It provides all its functions inside the table table.
-
-
-
-Remember that, whenever an operation needs the length of a table,
-the table must be a proper sequence
-or have a __len metamethod (see §3.4.7).
-All functions ignore non-numeric keys
-in the tables given as arguments.
-
-
-
-Given a list where all elements are strings or numbers,
-returns the string list[i]..sep..list[i+1] ··· sep..list[j].
-The default value for sep is the empty string,
-the default for i is 1,
-and the default for j is #list.
-If i is greater than j, returns the empty string.
-
-
-
-
-
-Inserts element value at position pos in list,
-shifting up the elements
-list[pos], list[pos+1], ···, list[#list].
-The default value for pos is #list+1,
-so that a call table.insert(t,x) inserts x at the end
-of list t.
-
-
-
-
-
-Moves elements from table a1 to table a2.
-This function performs the equivalent to the following
-multiple assignment:
-a2[t],··· = a1[f],···,a1[e].
-The default for a2 is a1.
-The destination range can overlap with the source range.
-Index f must be positive.
-
-
-
-
-
-Returns a new table with all parameters stored into keys 1, 2, etc.
-and with a field "n" with the total number of parameters.
-Note that the resulting table may not be a sequence.
-
-
-
-
-
-Removes from list the element at position pos,
-returning the value of the removed element.
-When pos is an integer between 1 and #list,
-it shifts down the elements
-list[pos+1], list[pos+2], ···, list[#list]
-and erases element list[#list];
-The index pos can also be 0 when #list is 0,
-or #list + 1;
-in those cases, the function erases the element list[pos].
-
-
-
-The default value for pos is #list,
-so that a call table.remove(l) removes the last element
-of list l.
-
-
-
-
-
-Sorts list elements in a given order, in-place,
-from list[1] to list[#list].
-If comp is given,
-then it must be a function that receives two list elements
-and returns true when the first element must come
-before the second in the final order
-(so that not comp(list[i+1],list[i]) will be true after the sort).
-If comp is not given,
-then the standard Lua operator < is used instead.
-
-
-
-The sort algorithm is not stable;
-that is, elements considered equal by the given order
-may have their relative positions changed by the sort.
-
-
-
-
-
-This library provides basic mathematical functions.
-It provides all its functions and constants inside the table math.
-Functions with the annotation "integer/float" give
-integer results for integer arguments
-and float results for float (or mixed) arguments.
-Rounding functions
-(math.ceil, math.floor, and math.modf)
-return an integer when the result fits in the range of an integer,
-or a float otherwise.
-
-
-
-
-Returns the arc tangent of y/x (in radians),
-but uses the signs of both parameters to find the
-quadrant of the result.
-(It also handles correctly the case of x being zero.)
-
-
-
-The default value for x is 1,
-so that the call math.atan(y)
-returns the arc tangent of y.
-
-
-
-
-
-When called without arguments,
-returns a pseudo-random float with uniform distribution
-in the range [0,1).
-When called with two integers m and n,
-math.random returns a pseudo-random integer
-with uniform distribution in the range [m, n].
-(The value m-n cannot be negative and must fit in a Lua integer.)
-The call math.random(n) is equivalent to math.random(1,n).
-
-
-
-This function is an interface to the underling
-pseudo-random generator function provided by C.
-No guarantees can be given for its statistical properties.
-
-
-
-
-
-The I/O library provides two different styles for file manipulation.
-The first one uses implicit file handles;
-that is, there are operations to set a default input file and a
-default output file,
-and all input/output operations are over these default files.
-The second style uses explicit file handles.
-
-
-
-When using implicit file handles,
-all operations are supplied by table io.
-When using explicit file handles,
-the operation io.open returns a file handle
-and then all operations are supplied as methods of the file handle.
-
-
-
-The table io also provides
-three predefined file handles with their usual meanings from C:
-io.stdin, io.stdout, and io.stderr.
-The I/O library never closes these files.
-
-
-
-Unless otherwise stated,
-all I/O functions return nil on failure
-(plus an error message as a second result and
-a system-dependent error code as a third result)
-and some value different from nil on success.
-On non-POSIX systems,
-the computation of the error message and error code
-in case of errors
-may be not thread safe,
-because they rely on the global C variable errno.
-
-
-
-When called with a file name, it opens the named file (in text mode),
-and sets its handle as the default input file.
-When called with a file handle,
-it simply sets this file handle as the default input file.
-When called without parameters,
-it returns the current default input file.
-
-
-
-In case of errors this function raises the error,
-instead of returning an error code.
-
-
-
-
-
-Opens the given file name in read mode
-and returns an iterator function that
-works like file:lines(···) over the opened file.
-When the iterator function detects the end of file,
-it returns no values (to finish the loop) and automatically closes the file.
-
-
-
-The call io.lines() (with no file name) is equivalent
-to io.input():lines("*l");
-that is, it iterates over the lines of the default input file.
-In this case it does not close the file when the loop ends.
-
-
-
-In case of errors this function raises the error,
-instead of returning an error code.
-
-
-
-
-
-This function opens a file,
-in the mode specified in the string mode.
-It returns a new file handle,
-or, in case of errors, nil plus an error message.
-
-
-
-The mode string can be any of the following:
-
-
-
"r": read mode (the default);
-
"w": write mode;
-
"a": append mode;
-
"r+": update mode, all previous data is preserved;
-
"w+": update mode, all previous data is erased;
-
"a+": append update mode, previous data is preserved,
- writing is only allowed at the end of file.
-
-The mode string can also have a 'b' at the end,
-which is needed in some systems to open the file in binary mode.
-
-
-
-
-
-This function is system dependent and is not available
-on all platforms.
-
-
-
-Starts program prog in a separated process and returns
-a file handle that you can use to read data from this program
-(if mode is "r", the default)
-or to write data to this program
-(if mode is "w").
-
-
-
-
-
-Checks whether obj is a valid file handle.
-Returns the string "file" if obj is an open file handle,
-"closed file" if obj is a closed file handle,
-or nil if obj is not a file handle.
-
-
-
-
-
-Closes file.
-Note that files are automatically closed when
-their handles are garbage collected,
-but that takes an unpredictable amount of time to happen.
-
-
-
-When closing a file handle created with io.popen,
-file:close returns the same values
-returned by os.execute.
-
-
-
-
-
-Returns an iterator function that,
-each time it is called,
-reads the file according to the given formats.
-When no format is given,
-uses "l" as a default.
-As an example, the construction
-
-
- for c in file:lines(1) do body end
-
-will iterate over all characters of the file,
-starting at the current position.
-Unlike io.lines, this function does not close the file
-when the loop ends.
-
-
-
-In case of errors this function raises the error,
-instead of returning an error code.
-
-
-
-
-
-Reads the file file,
-according to the given formats, which specify what to read.
-For each format,
-the function returns a string or a number with the characters read,
-or nil if it cannot read data with the specified format.
-(In this latter case,
-the function does not read subsequent formats.)
-When called without formats,
-it uses a default format that reads the next line
-(see below).
-
-
-
-The available formats are
-
-
-
-
"n":
-reads a numeral and returns it as a float or an integer,
-following the lexical conventions of Lua.
-(The numeral may have leading spaces and a sign.)
-This format always reads the longest input sequence that
-is a valid prefix for a number;
-if that prefix does not form a valid number
-(e.g., an empty string, "0x", or "3.4e-"),
-it is discarded and the function returns nil.
-
-
-
"i":
-reads an integral number and returns it as an integer.
-
-
-
"a":
-reads the whole file, starting at the current position.
-On end of file, it returns the empty string.
-
-
-
"l":
-reads the next line skipping the end of line,
-returning nil on end of file.
-This is the default format.
-
-
-
"L":
-reads the next line keeping the end-of-line character (if present),
-returning nil on end of file.
-
-
-
number:
-reads a string with up to this number of bytes,
-returning nil on end of file.
-If number is zero,
-it reads nothing and returns an empty string,
-or nil on end of file.
-
-
-
-The formats "l" and "L" should be used only for text files.
-
-
-
-
-
-Sets and gets the file position,
-measured from the beginning of the file,
-to the position given by offset plus a base
-specified by the string whence, as follows:
-
-
-
"set": base is position 0 (beginning of the file);
-
"cur": base is current position;
-
"end": base is end of file;
-
-In case of success, seek returns the final file position,
-measured in bytes from the beginning of the file.
-If seek fails, it returns nil,
-plus a string describing the error.
-
-
-
-The default value for whence is "cur",
-and for offset is 0.
-Therefore, the call file:seek() returns the current
-file position, without changing it;
-the call file:seek("set") sets the position to the
-beginning of the file (and returns 0);
-and the call file:seek("end") sets the position to the
-end of the file, and returns its size.
-
-
-
-
-
-Returns a string or a table containing date and time,
-formatted according to the given string format.
-
-
-
-If the time argument is present,
-this is the time to be formatted
-(see the os.time function for a description of this value).
-Otherwise, date formats the current time.
-
-
-
-If format starts with '!',
-then the date is formatted in Coordinated Universal Time.
-After this optional character,
-if format is the string "*t",
-then date returns a table with the following fields:
-year (four digits), month (1–12), day (1–31),
-hour (0–23), min (0–59), sec (0–61),
-wday (weekday, Sunday is 1),
-yday (day of the year),
-and isdst (daylight saving flag, a boolean).
-This last field may be absent
-if the information is not available.
-
-
-
-If format is not "*t",
-then date returns the date as a string,
-formatted according to the same rules as the ISO C function strftime.
-
-
-
-When called without arguments,
-date returns a reasonable date and time representation that depends on
-the host system and on the current locale
-(that is, os.date() is equivalent to os.date("%c")).
-
-
-
-On non-POSIX systems,
-this function may be not thread safe
-because of its reliance on C function gmtime and C function localtime.
-
-
-
-
-
-Returns the difference, in seconds,
-from time t1 to time t2
-(where the times are values returned by os.time).
-In POSIX, Windows, and some other systems,
-this value is exactly t2-t1.
-
-
-
-
-
-This function is equivalent to the ISO C function system.
-It passes command to be executed by an operating system shell.
-Its first result is true
-if the command terminated successfully,
-or nil otherwise.
-After this first result
-the function returns a string plus a number,
-as follows:
-
-
-
-
"exit":
-the command terminated normally;
-the following number is the exit status of the command.
-
-
-
"signal":
-the command was terminated by a signal;
-the following number is the signal that terminated the command.
-
-
-
-
-
-When called without a command,
-os.execute returns a boolean that is true if a shell is available.
-
-
-
-
-
-Calls the ISO C function exit to terminate the host program.
-If code is true,
-the returned status is EXIT_SUCCESS;
-if code is false,
-the returned status is EXIT_FAILURE;
-if code is a number,
-the returned status is this number.
-The default value for code is true.
-
-
-
-If the optional second argument close is true,
-closes the Lua state before exiting.
-
-
-
-
-
-Deletes the file (or empty directory, on POSIX systems)
-with the given name.
-If this function fails, it returns nil,
-plus a string describing the error and the error code.
-
-
-
-
-
-Renames file or directory named oldname to newname.
-If this function fails, it returns nil,
-plus a string describing the error and the error code.
-
-
-
-
-
-Sets the current locale of the program.
-locale is a system-dependent string specifying a locale;
-category is an optional string describing which category to change:
-"all", "collate", "ctype",
-"monetary", "numeric", or "time";
-the default category is "all".
-The function returns the name of the new locale,
-or nil if the request cannot be honored.
-
-
-
-If locale is the empty string,
-the current locale is set to an implementation-defined native locale.
-If locale is the string "C",
-the current locale is set to the standard C locale.
-
-
-
-When called with nil as the first argument,
-this function only returns the name of the current locale
-for the given category.
-
-
-
-This function may be not thread safe
-because of its reliance on C function setlocale.
-
-
-
-
-
-Returns the current time when called without arguments,
-or a time representing the date and time specified by the given table.
-This table must have fields year, month, and day,
-and may have fields
-hour (default is 12),
-min (default is 0),
-sec (default is 0),
-and isdst (default is nil).
-For a description of these fields, see the os.date function.
-
-
-
-The returned value is a number, whose meaning depends on your system.
-In POSIX, Windows, and some other systems,
-this number counts the number
-of seconds since some given start time (the "epoch").
-In other systems, the meaning is not specified,
-and the number returned by time can be used only as an argument to
-os.date and os.difftime.
-
-
-
-
-
-Returns a string with a file name that can
-be used for a temporary file.
-The file must be explicitly opened before its use
-and explicitly removed when no longer needed.
-
-
-
-On POSIX systems,
-this function also creates a file with that name,
-to avoid security risks.
-(Someone else might create the file with wrong permissions
-in the time between getting the name and creating the file.)
-You still have to open the file to use it
-and to remove it (even if you do not use it).
-
-
-
-When possible,
-you may prefer to use io.tmpfile,
-which automatically removes the file when the program ends.
-
-
-
-
-
-
-
-
-This library provides
-the functionality of the debug interface (§4.9) to Lua programs.
-You should exert care when using this library.
-Several of its functions
-violate basic assumptions about Lua code
-(e.g., that variables local to a function
-cannot be accessed from outside;
-that userdata metatables cannot be changed by Lua code;
-that Lua programs do not crash)
-and therefore can compromise otherwise secure code.
-Moreover, some functions in this library may be slow.
-
-
-
-All functions in this library are provided
-inside the debug table.
-All functions that operate over a thread
-have an optional first argument which is the
-thread to operate over.
-The default is always the current thread.
-
-
-
-Enters an interactive mode with the user,
-running each string that the user enters.
-Using simple commands and other debug facilities,
-the user can inspect global and local variables,
-change their values, evaluate expressions, and so on.
-A line containing only the word cont finishes this function,
-so that the caller continues its execution.
-
-
-
-Note that commands for debug.debug are not lexically nested
-within any function and so have no direct access to local variables.
-
-
-
-
-
-Returns the current hook settings of the thread, as three values:
-the current hook function, the current hook mask,
-and the current hook count
-(as set by the debug.sethook function).
-
-
-
-
-
-Returns a table with information about a function.
-You can give the function directly
-or you can give a number as the value of f,
-which means the function running at level f of the call stack
-of the given thread:
-level 0 is the current function (getinfo itself);
-level 1 is the function that called getinfo
-(except for tail calls, which do not count on the stack);
-and so on.
-If f is a number larger than the number of active functions,
-then getinfo returns nil.
-
-
-
-The returned table can contain all the fields returned by lua_getinfo,
-with the string what describing which fields to fill in.
-The default for what is to get all information available,
-except the table of valid lines.
-If present,
-the option 'f'
-adds a field named func with the function itself.
-If present,
-the option 'L'
-adds a field named activelines with the table of
-valid lines.
-
-
-
-For instance, the expression debug.getinfo(1,"n").name returns
-a table with a name for the current function,
-if a reasonable name can be found,
-and the expression debug.getinfo(print)
-returns a table with all available information
-about the print function.
-
-
-
-
-
-This function returns the name and the value of the local variable
-with index local of the function at level f of the stack.
-This function accesses not only explicit local variables,
-but also parameters, temporaries, etc.
-
-
-
-The first parameter or local variable has index 1, and so on,
-following the order that they are declared in the code,
-counting only the variables that are active
-in the current scope of the function.
-Negative indices refer to vararg parameters;
--1 is the first vararg parameter.
-The function returns nil if there is no variable with the given index,
-and raises an error when called with a level out of range.
-(You can call debug.getinfo to check whether the level is valid.)
-
-
-
-Variable names starting with '(' (open parenthesis)
-represent variables with no known names
-(internal variables such as loop control variables,
-and variables from chunks saved without debug information).
-
-
-
-The parameter f may also be a function.
-In that case, getlocal returns only the name of function parameters.
-
-
-
-
-
-This function returns the name and the value of the upvalue
-with index up of the function f.
-The function returns nil if there is no upvalue with the given index.
-
-
-
-Variable names starting with '(' (open parenthesis)
-represent variables with no known names
-(variables from chunks saved without debug information).
-
-
-
-
-
-Sets the given function as a hook.
-The string mask and the number count describe
-when the hook will be called.
-The string mask may have any combination of the following characters,
-with the given meaning:
-
-
-
'c': the hook is called every time Lua calls a function;
-
'r': the hook is called every time Lua returns from a function;
-
'l': the hook is called every time Lua enters a new line of code.
-
-Moreover,
-with a count different from zero,
-the hook is called also after every count instructions.
-
-
-
-When called without arguments,
-debug.sethook turns off the hook.
-
-
-
-When the hook is called, its first parameter is a string
-describing the event that has triggered its call:
-"call" (or "tail call"),
-"return",
-"line", and "count".
-For line events,
-the hook also gets the new line number as its second parameter.
-Inside a hook,
-you can call getinfo with level 2 to get more information about
-the running function
-(level 0 is the getinfo function,
-and level 1 is the hook function).
-
-
-
-
-
-This function assigns the value value to the local variable
-with index local of the function at level level of the stack.
-The function returns nil if there is no local
-variable with the given index,
-and raises an error when called with a level out of range.
-(You can call getinfo to check whether the level is valid.)
-Otherwise, it returns the name of the local variable.
-
-
-
-See debug.getlocal for more information about
-variable indices and names.
-
-
-
-
-
-This function assigns the value value to the upvalue
-with index up of the function f.
-The function returns nil if there is no upvalue
-with the given index.
-Otherwise, it returns the name of the upvalue.
-
-
-
-
-
-If message is present but is neither a string nor nil,
-this function returns message without further processing.
-Otherwise,
-it returns a string with a traceback of the call stack.
-The optional message string is appended
-at the beginning of the traceback.
-An optional level number tells at which level
-to start the traceback
-(default is 1, the function calling traceback).
-
-
-
-
-
-Returns a unique identifier (as a light userdata)
-for the upvalue numbered n
-from the given function.
-
-
-
-These unique identifiers allow a program to check whether different
-closures share upvalues.
-Lua closures that share an upvalue
-(that is, that access a same external local variable)
-will return identical ids for those upvalue indices.
-
-
-
-
-
-Although Lua has been designed as an extension language,
-to be embedded in a host C program,
-it is also frequently used as a standalone language.
-An interpreter for Lua as a standalone language,
-called simply lua,
-is provided with the standard distribution.
-The standalone interpreter includes
-all standard libraries, including the debug library.
-Its usage is:
-
-
- lua [options] [script [args]]
-
-The options are:
-
-
-
-e stat: executes string stat;
-
-l mod: "requires" mod;
-
-i: enters interactive mode after running script;
-
-v: prints version information;
-
-E: ignores environment variables;
-
--: stops handling options;
-
-: executes stdin as a file and stops handling options.
-
-After handling its options, lua runs the given script.
-When called without arguments,
-lua behaves as lua -v -i
-when the standard input (stdin) is a terminal,
-and as lua - otherwise.
-
-
-
-When called without option -E,
-the interpreter checks for an environment variable LUA_INIT_5_3
-(or LUA_INIT if the versioned name is not defined)
-before running any argument.
-If the variable content has the format @filename,
-then lua executes the file.
-Otherwise, lua executes the string itself.
-
-
-
-When called with option -E,
-besides ignoring LUA_INIT,
-Lua also ignores
-the values of LUA_PATH and LUA_CPATH,
-setting the values of
-package.path and package.cpath
-with the default paths defined in luaconf.h.
-
-
-
-All options are handled in order, except -i and -E.
-For instance, an invocation like
-
-
- $ lua -e'a=1' -e 'print(a)' script.lua
-
-will first set a to 1, then print the value of a,
-and finally run the file script.lua with no arguments.
-(Here $ is the shell prompt. Your prompt may be different.)
-
-
-
-Before running any code,
-lua collects all command-line arguments
-in a global table called arg.
-The script name goes to index 0,
-the first argument after the script name goes to index 1,
-and so on.
-Any arguments before the script name
-(that is, the interpreter name plus its options)
-go to negative indices.
-For instance, in the call
-
-
-If there is no script in the call,
-the interpreter name goes to index 0,
-followed by the other arguments.
-For instance, the call
-
-
- $ lua -e "print(arg[1])"
-
-will print "-e".
-If there is a script,
-the script is called with parameters
-arg[1], ···, arg[#arg].
-(Like all chunks in Lua,
-the script is compiled as a vararg function.)
-
-
-
-In interactive mode,
-Lua repeatedly prompts and waits for a line.
-After reading a line,
-Lua first try to interpret the line as an expression.
-If it succeeds, it prints its value.
-Otherwise, it interprets the line as a statement.
-If you write an incomplete statement,
-the interpreter waits for its completion
-by issuing a different prompt.
-
-
-
-In case of unprotected errors in the script,
-the interpreter reports the error to the standard error stream.
-If the error object is not a string but
-has a metamethod __tostring,
-the interpreter calls this metamethod to produce the final message.
-Otherwise, the interpreter converts the error object to a string
-and adds a stack traceback to it.
-
-
-
-When finishing normally,
-the interpreter closes its main Lua state
-(see lua_close).
-The script can avoid this step by
-calling os.exit to terminate.
-
-
-
-To allow the use of Lua as a
-script interpreter in Unix systems,
-the standalone interpreter skips
-the first line of a chunk if it starts with #.
-Therefore, Lua scripts can be made into executable programs
-by using chmod +x and the #! form,
-as in
-
-
- #!/usr/local/bin/lua
-
-(Of course,
-the location of the Lua interpreter may be different in your machine.
-If lua is in your PATH,
-then
-
-
-Here we list the incompatibilities that you may find when moving a program
-from Lua 5.2 to Lua 5.3.
-You can avoid some incompatibilities by compiling Lua with
-appropriate options (see file luaconf.h).
-However,
-all these compatibility options will be removed in the future.
-
-
-
-Lua versions can always change the C API in ways that
-do not imply source-code changes in a program,
-such as the numeric values for constants
-or the implementation of functions as macros.
-Therefore,
-you should not assume that binaries are compatible between
-different Lua versions.
-Always recompile clients of the Lua API when
-using a new version.
-
-
-
-Similarly, Lua versions can always change the internal representation
-of precompiled chunks;
-precompiled chunks are not compatible between different Lua versions.
-
-
-
-The standard paths in the official distribution may
-change between versions.
-
-
-
-
-The main difference between Lua 5.2 and Lua 5.3 is the
-introduction of an integer subtype for numbers.
-Although this change should not affect "normal" computations,
-some computations
-(mainly those that involve some kind of overflow)
-can give different results.
-
-
-
-You can fix these differences by forcing a number to be a float
-(in Lua 5.2 all numbers were float),
-in particular writing constants with an ending .0
-or using x = x + 0.0 to convert a variable.
-(This recommendation is only for a quick fix
-for an occasional incompatibility;
-it is not a general guideline for good programming.
-For good programming,
-use floats where you need floats
-and integers where you need integers.)
-
-
-
-The conversion of a float to a string now adds a .0 suffix
-to the result if it looks like an integer.
-(For instance, the float 2.0 will be printed as 2.0,
-not as 2.)
-You should always use an explicit format
-when you need a specific format for numbers.
-
-
-
-(Formally this is not an incompatibility,
-because Lua does not specify how numbers are formatted as strings,
-but some programs assumed a specific format.)
-
-
-
-The generational mode for the garbage collector was removed.
-(It was an experimental feature in Lua 5.2.)
-
-The bit32 library has been deprecated.
-It is easy to require a compatible external library or,
-better yet, to replace its functions with appropriate bitwise operations.
-(Keep in mind that bit32 operates on 32-bit integers,
-while the bitwise operators in standard Lua operate on 64-bit integers.)
-
-
-
-The Table library now respects metamethods
-for setting and getting elements.
-
-
-
-The ipairs iterator now respects metamethods and
-its __ipairs metamethod has been deprecated.
-
-
-
-Option names in io.read do not have a starting '*' anymore.
-For compatibility, Lua will continue to ignore this character.
-
-
-
-The following functions were deprecated in the mathematical library:
-atan2, cosh, sinh, tanh, pow,
-frexp, and ldexp.
-You can replace math.pow(x,y) with x^y;
-you can replace math.atan2 with math.atan,
-which now accepts one or two parameters;
-you can replace math.ldexp(x,exp) with x * 2.0^exp.
-For the other operations,
-you can either use an external library or
-implement them in Lua.
-
-
-
-The searcher for C loaders used by require
-changed the way it handles versioned names.
-Now, the version should come after the module name
-(as is usual in most other tools).
-For compatibility, that searcher still tries the old format
-if it cannot find an open function according to the new style.
-(Lua 5.2 already worked that way,
-but it did not document the change.)
-
-Continuation functions now receive as parameters what they needed
-to get through lua_getctx,
-so lua_getctx has been removed.
-Adapt your code accordingly.
-
-
-
-Function lua_dump has an extra parameter, strip.
-Use 0 as the value of this parameter to get the old behavior.
-
-
-
-Functions to inject/project unsigned integers
-(lua_pushunsigned, lua_tounsigned, lua_tounsignedx,
-luaL_checkunsigned, luaL_optunsigned)
-were deprecated.
-Use their signed equivalents with a type cast.
-
-
-
-Macros to project non-default integer types
-(luaL_checkint, luaL_optint, luaL_checklong, luaL_optlong)
-were deprecated.
-Use their equivalent over lua_Integer with a type cast
-(or, when possible, use lua_Integer in your code).
-
-Here is the complete syntax of Lua in extended BNF.
-As usual in extended BNF,
-{A} means 0 or more As,
-and [A] means an optional A.
-(For operator precedences, see §3.4.8;
-for a description of the terminals
-Name, Numeral,
-and LiteralString, see §3.1.)
-
-
-
-
-
-
- chunk ::= block
-
- block ::= {stat} [retstat]
-
- stat ::= ‘;’ |
- varlist ‘=’ explist |
- functioncall |
- label |
- break |
- goto Name |
- do block end |
- while exp do block end |
- repeat block until exp |
- if exp then block {elseif exp then block} [else block] end |
- for Name ‘=’ exp ‘,’ exp [‘,’ exp] do block end |
- for namelist in explist do block end |
- function funcname funcbody |
- localfunction Name funcbody |
- local namelist [‘=’ explist]
-
- retstat ::= return [explist] [‘;’]
-
- label ::= ‘::’ Name ‘::’
-
- funcname ::= Name {‘.’ Name} [‘:’ Name]
-
- varlist ::= var {‘,’ var}
-
- var ::= Name | prefixexp ‘[’ exp ‘]’ | prefixexp ‘.’ Name
-
- namelist ::= Name {‘,’ Name}
-
- explist ::= exp {‘,’ exp}
-
- exp ::= nil | false | true | Numeral | LiteralString | ‘...’ | functiondef |
- prefixexp | tableconstructor | exp binop exp | unop exp
-
- prefixexp ::= var | functioncall | ‘(’ exp ‘)’
-
- functioncall ::= prefixexp args | prefixexp ‘:’ Name args
-
- args ::= ‘(’ [explist] ‘)’ | tableconstructor | LiteralString
-
- functiondef ::= function funcbody
-
- funcbody ::= ‘(’ [parlist] ‘)’ block end
-
- parlist ::= namelist [‘,’ ‘...’] | ‘...’
-
- tableconstructor ::= ‘{’ [fieldlist] ‘}’
-
- fieldlist ::= field {fieldsep field} [fieldsep]
-
- field ::= ‘[’ exp ‘]’ ‘=’ exp | Name ‘=’ exp | exp
-
- fieldsep ::= ‘,’ | ‘;’
-
- binop ::= ‘+’ | ‘-’ | ‘*’ | ‘/’ | ‘//’ | ‘^’ | ‘%’ |
- ‘&’ | ‘~’ | ‘|’ | ‘>>’ | ‘<<’ | ‘..’ |
- ‘<’ | ‘<=’ | ‘>’ | ‘>=’ | ‘==’ | ‘~=’ |
- and | or
-
- unop ::= ‘-’ | not | ‘#’ | ‘~’
-
-
-Lua is a powerful, fast, lightweight, embeddable scripting language
-developed by a
-team
-at
-PUC-Rio,
-the Pontifical Catholic University of Rio de Janeiro in Brazil.
-Lua is
-free software
-used in many products and projects around the world.
-
-
-Lua is distributed in
-source
-form.
-You need to build it before using it.
-Building Lua should be straightforward
-because
-Lua is implemented in pure ANSI C and compiles unmodified in all known
-platforms that have an ANSI C compiler.
-Lua also compiles unmodified as C++.
-The instructions given below for building Lua are for Unix-like platforms.
-See also
-instructions for other systems
-and
-customization options.
-
-
-If you don't have the time or the inclination to compile Lua yourself,
-get a binary from
-LuaBinaries.
-Try also
-LuaDist,
-a multi-platform distribution of Lua that includes batteries.
-
-
Building Lua
-
-
-In most Unix-like platforms, simply do "make" with a suitable target.
-Here are the details.
-
-
-
-Open a terminal window and move to
-the top-level directory, which is named lua-5.3.0.
-The Makefile there controls both the build process and the installation process.
-
-
- Do "make" and see if your platform is listed.
- The platforms currently supported are:
-
-
- aix bsd c89 freebsd generic linux macosx mingw posix solaris
-
-
- If your platform is listed, just do "make xxx", where xxx
- is your platform name.
-
- If your platform is not listed, try the closest one or posix, generic,
- c89, in this order.
-
-
-The compilation takes only a few moments
-and produces three files in the src directory:
-lua (the interpreter),
-luac (the compiler),
-and liblua.a (the library).
-
-
- To check that Lua has been built correctly, do "make test"
- after building Lua. This will run the interpreter and print its version.
-
-
-If you're running Linux and get compilation errors,
-make sure you have installed the readline development package.
-If you get link errors after that,
-then try "make linux MYLIBS=-ltermcap".
-
-
Installing Lua
-
- Once you have built Lua, you may want to install it in an official
- place in your system. In this case, do "make install". The official
- place and the way to install files are defined in the Makefile. You'll
- probably need the right permissions to install files.
-
-
- To build and install Lua in one step, do "make xxx install",
- where xxx is your platform name.
-
-
- To install Lua locally, do "make local".
- This will create a directory install with subdirectories
- bin, include, lib, man, share,
- and install Lua as listed below.
-
- To install Lua locally, but in some other directory, do
- "make install INSTALL_TOP=xxx", where xxx is your chosen directory.
- The installation starts in the src and doc directories,
- so take care if INSTALL_TOP is not an absolute path.
-
-
-
- bin:
-
- lua luac
-
- include:
-
- lauxlib.h lua.h lua.hpp luaconf.h lualib.h
-
- lib:
-
- liblua.a
-
- man/man1:
-
- lua.1 luac.1
-
-
-
- These are the only directories you need for development.
- If you only want to run Lua programs,
- you only need the files in bin and man.
- The files in include and lib are needed for
- embedding Lua in C or C++ programs.
-
-
- Three kinds of things can be customized by editing a file:
-
-
Where and how to install Lua — edit Makefile.
-
How to build Lua — edit src/Makefile.
-
Lua features — edit src/luaconf.h.
-
-
-
- You don't actually need to edit the Makefiles because you may set the
- relevant variables in the command line when invoking make.
- Nevertheless, it's probably best to edit and save the Makefiles to
- record the changes you've made.
-
-
- On the other hand, if you need to customize some Lua features, you'll need
- to edit src/luaconf.h before building and installing Lua.
- The edited file will be the one installed, and
- it will be used by any Lua clients that you build, to ensure consistency.
- Further customization is available to experts by editing the Lua sources.
-
-
- If you're not using the usual Unix tools, then the instructions for
- building Lua depend on the compiler you use. You'll need to create
- projects (or whatever your compiler uses) for building the library,
- the interpreter, and the compiler, as follows:
-
-
- To use Lua as a library in your own programs you'll need to know how to
- create and use libraries with your compiler. Moreover, to dynamically load
- C libraries for Lua you'll need to know how to create dynamic libraries
- and you'll need to make sure that the Lua API functions are accessible to
- those dynamic libraries — but don't link the Lua library
- into each dynamic library. For Unix, we recommend that the Lua library
- be linked statically into the host program and its symbols exported for
- dynamic linking; src/Makefile does this for the Lua interpreter.
- For Windows, we recommend that the Lua library be a DLL.
- In all cases, the compiler luac should be linked statically.
-
-
- As mentioned above, you may edit src/luaconf.h to customize
- some features before building Lua.
-
-
-Lua is free software distributed under the terms of the
-MIT license
-reproduced below;
-it may be used for any purpose, including commercial purposes,
-at absolutely no cost without having to ask us.
-
-The only requirement is that if you do use Lua,
-then you should give us credit by including the appropriate copyright notice somewhere in your product or its documentation.
-
-For details, see
-this.
-
-
-Permission is hereby granted, free of charge, to any person obtaining a copy
-of this software and associated documentation files (the "Software"), to deal
-in the Software without restriction, including without limitation the rights
-to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
-copies of the Software, and to permit persons to whom the Software is
-furnished to do so, subject to the following conditions:
-
-
-The above copyright notice and this permission notice shall be included in
-all copies or substantial portions of the Software.
-
-
-THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
-AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
-LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
-OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
-THE SOFTWARE.
-
-
-
-
-
-Last update:
-Fri Dec 12 09:58:42 BRST 2014
-
-
-
-
-
diff --git a/3rd/lua/src/Makefile b/3rd/lua/src/Makefile
deleted file mode 100644
index 2e7a412..0000000
--- a/3rd/lua/src/Makefile
+++ /dev/null
@@ -1,197 +0,0 @@
-# Makefile for building Lua
-# See ../doc/readme.html for installation and customization instructions.
-
-# == CHANGE THE SETTINGS BELOW TO SUIT YOUR ENVIRONMENT =======================
-
-# Your platform. See PLATS for possible values.
-PLAT= none
-
-CC= gcc -std=gnu99
-CFLAGS= -O2 -Wall -Wextra -DLUA_COMPAT_5_2 $(SYSCFLAGS) $(MYCFLAGS)
-LDFLAGS= $(SYSLDFLAGS) $(MYLDFLAGS)
-LIBS= -lm $(SYSLIBS) $(MYLIBS)
-
-AR= ar rcu
-RANLIB= ranlib
-RM= rm -f
-
-SYSCFLAGS=
-SYSLDFLAGS=
-SYSLIBS=
-
-MYCFLAGS=
-MYLDFLAGS=
-MYLIBS=
-MYOBJS=
-
-# == END OF USER SETTINGS -- NO NEED TO CHANGE ANYTHING BELOW THIS LINE =======
-
-PLATS= aix bsd c89 freebsd generic linux macosx mingw posix solaris
-
-LUA_A= liblua.a
-CORE_O= lapi.o lcode.o lctype.o ldebug.o ldo.o ldump.o lfunc.o lgc.o llex.o \
- lmem.o lobject.o lopcodes.o lparser.o lstate.o lstring.o ltable.o \
- ltm.o lundump.o lvm.o lzio.o
-LIB_O= lauxlib.o lbaselib.o lbitlib.o lcorolib.o ldblib.o liolib.o \
- lmathlib.o loslib.o lstrlib.o ltablib.o lutf8lib.o loadlib.o linit.o
-BASE_O= $(CORE_O) $(LIB_O) $(MYOBJS)
-
-LUA_T= lua
-LUA_O= lua.o
-
-LUAC_T= luac
-LUAC_O= luac.o
-
-ALL_O= $(BASE_O) $(LUA_O) $(LUAC_O)
-ALL_T= $(LUA_A) $(LUA_T) $(LUAC_T)
-ALL_A= $(LUA_A)
-
-# Targets start here.
-default: $(PLAT)
-
-all: $(ALL_T)
-
-o: $(ALL_O)
-
-a: $(ALL_A)
-
-$(LUA_A): $(BASE_O)
- $(AR) $@ $(BASE_O)
- $(RANLIB) $@
-
-$(LUA_T): $(LUA_O) $(LUA_A)
- $(CC) -o $@ $(LDFLAGS) $(LUA_O) $(LUA_A) $(LIBS)
-
-$(LUAC_T): $(LUAC_O) $(LUA_A)
- $(CC) -o $@ $(LDFLAGS) $(LUAC_O) $(LUA_A) $(LIBS)
-
-clean:
- $(RM) $(ALL_T) $(ALL_O)
-
-depend:
- @$(CC) $(CFLAGS) -MM l*.c
-
-echo:
- @echo "PLAT= $(PLAT)"
- @echo "CC= $(CC)"
- @echo "CFLAGS= $(CFLAGS)"
- @echo "LDFLAGS= $(SYSLDFLAGS)"
- @echo "LIBS= $(LIBS)"
- @echo "AR= $(AR)"
- @echo "RANLIB= $(RANLIB)"
- @echo "RM= $(RM)"
-
-# Convenience targets for popular platforms
-ALL= all
-
-none:
- @echo "Please do 'make PLATFORM' where PLATFORM is one of these:"
- @echo " $(PLATS)"
-
-aix:
- $(MAKE) $(ALL) CC="xlc" CFLAGS="-O2 -DLUA_USE_POSIX -DLUA_USE_DLOPEN" SYSLIBS="-ldl" SYSLDFLAGS="-brtl -bexpall"
-
-bsd:
- $(MAKE) $(ALL) SYSCFLAGS="-DLUA_USE_POSIX -DLUA_USE_DLOPEN" SYSLIBS="-Wl,-E"
-
-c89:
- $(MAKE) $(ALL) SYSCFLAGS="-DLUA_USE_C89" CC="gcc -std=c89"
- @echo ''
- @echo '*** C89 does not guarantee 64-bit integers for Lua.'
- @echo ''
-
-
-freebsd:
- $(MAKE) $(ALL) SYSCFLAGS="-DLUA_USE_LINUX" SYSLIBS="-Wl,-E -lreadline"
-
-generic: $(ALL)
-
-linux:
- $(MAKE) $(ALL) SYSCFLAGS="-DLUA_USE_LINUX" SYSLIBS="-Wl,-E -ldl -lreadline"
-
-macosx:
- $(MAKE) $(ALL) SYSCFLAGS="-DLUA_USE_MACOSX" SYSLIBS="-lreadline" CC=cc
-
-mingw:
- $(MAKE) "LUA_A=lua53.dll" "LUA_T=lua.exe" \
- "AR=$(CC) -shared -o" "RANLIB=strip --strip-unneeded" \
- "SYSCFLAGS=-DLUA_BUILD_AS_DLL" "SYSLIBS=" "SYSLDFLAGS=-s" lua.exe
- $(MAKE) "LUAC_T=luac.exe" luac.exe
-
-posix:
- $(MAKE) $(ALL) SYSCFLAGS="-DLUA_USE_POSIX"
-
-solaris:
- $(MAKE) $(ALL) SYSCFLAGS="-DLUA_USE_POSIX -DLUA_USE_DLOPEN -D_REENTRANT" SYSLIBS="-ldl"
-
-# list targets that do not create files (but not all makes understand .PHONY)
-.PHONY: all $(PLATS) default o a clean depend echo none
-
-# DO NOT DELETE
-
-lapi.o: lapi.c lprefix.h lua.h luaconf.h lapi.h llimits.h lstate.h \
- lobject.h ltm.h lzio.h lmem.h ldebug.h ldo.h lfunc.h lgc.h lstring.h \
- ltable.h lundump.h lvm.h
-lauxlib.o: lauxlib.c lprefix.h lua.h luaconf.h lauxlib.h
-lbaselib.o: lbaselib.c lprefix.h lua.h luaconf.h lauxlib.h lualib.h
-lbitlib.o: lbitlib.c lprefix.h lua.h luaconf.h lauxlib.h lualib.h
-lcode.o: lcode.c lprefix.h lua.h luaconf.h lcode.h llex.h lobject.h \
- llimits.h lzio.h lmem.h lopcodes.h lparser.h ldebug.h lstate.h ltm.h \
- ldo.h lgc.h lstring.h ltable.h lvm.h
-lcorolib.o: lcorolib.c lprefix.h lua.h luaconf.h lauxlib.h lualib.h
-lctype.o: lctype.c lprefix.h lctype.h lua.h luaconf.h llimits.h
-ldblib.o: ldblib.c lprefix.h lua.h luaconf.h lauxlib.h lualib.h
-ldebug.o: ldebug.c lprefix.h lua.h luaconf.h lapi.h llimits.h lstate.h \
- lobject.h ltm.h lzio.h lmem.h lcode.h llex.h lopcodes.h lparser.h \
- ldebug.h ldo.h lfunc.h lstring.h lgc.h ltable.h lvm.h
-ldo.o: ldo.c lprefix.h lua.h luaconf.h lapi.h llimits.h lstate.h \
- lobject.h ltm.h lzio.h lmem.h ldebug.h ldo.h lfunc.h lgc.h lopcodes.h \
- lparser.h lstring.h ltable.h lundump.h lvm.h
-ldump.o: ldump.c lprefix.h lua.h luaconf.h lobject.h llimits.h lstate.h \
- ltm.h lzio.h lmem.h lundump.h
-lfunc.o: lfunc.c lprefix.h lua.h luaconf.h lfunc.h lobject.h llimits.h \
- lgc.h lstate.h ltm.h lzio.h lmem.h
-lgc.o: lgc.c lprefix.h lua.h luaconf.h ldebug.h lstate.h lobject.h \
- llimits.h ltm.h lzio.h lmem.h ldo.h lfunc.h lgc.h lstring.h ltable.h
-linit.o: linit.c lprefix.h lua.h luaconf.h lualib.h lauxlib.h
-liolib.o: liolib.c lprefix.h lua.h luaconf.h lauxlib.h lualib.h
-llex.o: llex.c lprefix.h lua.h luaconf.h lctype.h llimits.h ldo.h \
- lobject.h lstate.h ltm.h lzio.h lmem.h lgc.h llex.h lparser.h lstring.h \
- ltable.h
-lmathlib.o: lmathlib.c lprefix.h lua.h luaconf.h lauxlib.h lualib.h
-lmem.o: lmem.c lprefix.h lua.h luaconf.h ldebug.h lstate.h lobject.h \
- llimits.h ltm.h lzio.h lmem.h ldo.h lgc.h
-loadlib.o: loadlib.c lprefix.h lua.h luaconf.h lauxlib.h lualib.h
-lobject.o: lobject.c lprefix.h lua.h luaconf.h lctype.h llimits.h \
- ldebug.h lstate.h lobject.h ltm.h lzio.h lmem.h ldo.h lstring.h lgc.h \
- lvm.h
-lopcodes.o: lopcodes.c lprefix.h lopcodes.h llimits.h lua.h luaconf.h
-loslib.o: loslib.c lprefix.h lua.h luaconf.h lauxlib.h lualib.h
-lparser.o: lparser.c lprefix.h lua.h luaconf.h lcode.h llex.h lobject.h \
- llimits.h lzio.h lmem.h lopcodes.h lparser.h ldebug.h lstate.h ltm.h \
- ldo.h lfunc.h lstring.h lgc.h ltable.h
-lstate.o: lstate.c lprefix.h lua.h luaconf.h lapi.h llimits.h lstate.h \
- lobject.h ltm.h lzio.h lmem.h ldebug.h ldo.h lfunc.h lgc.h llex.h \
- lstring.h ltable.h
-lstring.o: lstring.c lprefix.h lua.h luaconf.h ldebug.h lstate.h \
- lobject.h llimits.h ltm.h lzio.h lmem.h ldo.h lstring.h lgc.h
-lstrlib.o: lstrlib.c lprefix.h lua.h luaconf.h lauxlib.h lualib.h
-ltable.o: ltable.c lprefix.h lua.h luaconf.h ldebug.h lstate.h lobject.h \
- llimits.h ltm.h lzio.h lmem.h ldo.h lgc.h lstring.h ltable.h lvm.h
-ltablib.o: ltablib.c lprefix.h lua.h luaconf.h lauxlib.h lualib.h
-ltm.o: ltm.c lprefix.h lua.h luaconf.h ldebug.h lstate.h lobject.h \
- llimits.h ltm.h lzio.h lmem.h ldo.h lstring.h lgc.h ltable.h lvm.h
-lua.o: lua.c lprefix.h lua.h luaconf.h lauxlib.h lualib.h
-luac.o: luac.c lprefix.h lua.h luaconf.h lauxlib.h lobject.h llimits.h \
- lstate.h ltm.h lzio.h lmem.h lundump.h ldebug.h lopcodes.h
-lundump.o: lundump.c lprefix.h lua.h luaconf.h ldebug.h lstate.h \
- lobject.h llimits.h ltm.h lzio.h lmem.h ldo.h lfunc.h lstring.h lgc.h \
- lundump.h
-lutf8lib.o: lutf8lib.c lprefix.h lua.h luaconf.h lauxlib.h lualib.h
-lvm.o: lvm.c lprefix.h lua.h luaconf.h ldebug.h lstate.h lobject.h \
- llimits.h ltm.h lzio.h lmem.h ldo.h lfunc.h lgc.h lopcodes.h lstring.h \
- ltable.h lvm.h
-lzio.o: lzio.c lprefix.h lua.h luaconf.h llimits.h lmem.h lstate.h \
- lobject.h ltm.h lzio.h
-
-# (end of Makefile)
diff --git a/3rd/lua/src/lapi.c b/3rd/lua/src/lapi.c
deleted file mode 100644
index fbfafa3..0000000
--- a/3rd/lua/src/lapi.c
+++ /dev/null
@@ -1,1270 +0,0 @@
-/*
-** $Id: lapi.c,v 2.244 2014/12/26 14:43:45 roberto Exp $
-** Lua API
-** See Copyright Notice in lua.h
-*/
-
-#define lapi_c
-#define LUA_CORE
-
-#include "lprefix.h"
-
-
-#include
-#include
-
-#include "lua.h"
-
-#include "lapi.h"
-#include "ldebug.h"
-#include "ldo.h"
-#include "lfunc.h"
-#include "lgc.h"
-#include "lmem.h"
-#include "lobject.h"
-#include "lstate.h"
-#include "lstring.h"
-#include "ltable.h"
-#include "ltm.h"
-#include "lundump.h"
-#include "lvm.h"
-
-
-
-const char lua_ident[] =
- "$LuaVersion: " LUA_COPYRIGHT " $"
- "$LuaAuthors: " LUA_AUTHORS " $";
-
-
-/* value at a non-valid index */
-#define NONVALIDVALUE cast(TValue *, luaO_nilobject)
-
-/* corresponding test */
-#define isvalid(o) ((o) != luaO_nilobject)
-
-/* test for pseudo index */
-#define ispseudo(i) ((i) <= LUA_REGISTRYINDEX)
-
-/* test for upvalue */
-#define isupvalue(i) ((i) < LUA_REGISTRYINDEX)
-
-/* test for valid but not pseudo index */
-#define isstackindex(i, o) (isvalid(o) && !ispseudo(i))
-
-#define api_checkvalidindex(o) api_check(isvalid(o), "invalid index")
-
-#define api_checkstackindex(i, o) \
- api_check(isstackindex(i, o), "index not in the stack")
-
-
-static TValue *index2addr (lua_State *L, int idx) {
- CallInfo *ci = L->ci;
- if (idx > 0) {
- TValue *o = ci->func + idx;
- api_check(idx <= ci->top - (ci->func + 1), "unacceptable index");
- if (o >= L->top) return NONVALIDVALUE;
- else return o;
- }
- else if (!ispseudo(idx)) { /* negative index */
- api_check(idx != 0 && -idx <= L->top - (ci->func + 1), "invalid index");
- return L->top + idx;
- }
- else if (idx == LUA_REGISTRYINDEX)
- return &G(L)->l_registry;
- else { /* upvalues */
- idx = LUA_REGISTRYINDEX - idx;
- api_check(idx <= MAXUPVAL + 1, "upvalue index too large");
- if (ttislcf(ci->func)) /* light C function? */
- return NONVALIDVALUE; /* it has no upvalues */
- else {
- CClosure *func = clCvalue(ci->func);
- return (idx <= func->nupvalues) ? &func->upvalue[idx-1] : NONVALIDVALUE;
- }
- }
-}
-
-
-/*
-** to be called by 'lua_checkstack' in protected mode, to grow stack
-** capturing memory errors
-*/
-static void growstack (lua_State *L, void *ud) {
- int size = *(int *)ud;
- luaD_growstack(L, size);
-}
-
-
-LUA_API int lua_checkstack (lua_State *L, int n) {
- int res;
- CallInfo *ci = L->ci;
- lua_lock(L);
- api_check(n >= 0, "negative 'n'");
- if (L->stack_last - L->top > n) /* stack large enough? */
- res = 1; /* yes; check is OK */
- else { /* no; need to grow stack */
- int inuse = cast_int(L->top - L->stack) + EXTRA_STACK;
- if (inuse > LUAI_MAXSTACK - n) /* can grow without overflow? */
- res = 0; /* no */
- else /* try to grow stack */
- res = (luaD_rawrunprotected(L, &growstack, &n) == LUA_OK);
- }
- if (res && ci->top < L->top + n)
- ci->top = L->top + n; /* adjust frame top */
- lua_unlock(L);
- return res;
-}
-
-
-LUA_API void lua_xmove (lua_State *from, lua_State *to, int n) {
- int i;
- if (from == to) return;
- lua_lock(to);
- api_checknelems(from, n);
- api_check(G(from) == G(to), "moving among independent states");
- api_check(to->ci->top - to->top >= n, "not enough elements to move");
- from->top -= n;
- for (i = 0; i < n; i++) {
- setobj2s(to, to->top++, from->top + i);
- }
- lua_unlock(to);
-}
-
-
-LUA_API lua_CFunction lua_atpanic (lua_State *L, lua_CFunction panicf) {
- lua_CFunction old;
- lua_lock(L);
- old = G(L)->panic;
- G(L)->panic = panicf;
- lua_unlock(L);
- return old;
-}
-
-
-LUA_API const lua_Number *lua_version (lua_State *L) {
- static const lua_Number version = LUA_VERSION_NUM;
- if (L == NULL) return &version;
- else return G(L)->version;
-}
-
-
-
-/*
-** basic stack manipulation
-*/
-
-
-/*
-** convert an acceptable stack index into an absolute index
-*/
-LUA_API int lua_absindex (lua_State *L, int idx) {
- return (idx > 0 || ispseudo(idx))
- ? idx
- : cast_int(L->top - L->ci->func + idx);
-}
-
-
-LUA_API int lua_gettop (lua_State *L) {
- return cast_int(L->top - (L->ci->func + 1));
-}
-
-
-LUA_API void lua_settop (lua_State *L, int idx) {
- StkId func = L->ci->func;
- lua_lock(L);
- if (idx >= 0) {
- api_check(idx <= L->stack_last - (func + 1), "new top too large");
- while (L->top < (func + 1) + idx)
- setnilvalue(L->top++);
- L->top = (func + 1) + idx;
- }
- else {
- api_check(-(idx+1) <= (L->top - (func + 1)), "invalid new top");
- L->top += idx+1; /* 'subtract' index (index is negative) */
- }
- lua_unlock(L);
-}
-
-
-/*
-** Reverse the stack segment from 'from' to 'to'
-** (auxiliary to 'lua_rotate')
-*/
-static void reverse (lua_State *L, StkId from, StkId to) {
- for (; from < to; from++, to--) {
- TValue temp;
- setobj(L, &temp, from);
- setobjs2s(L, from, to);
- setobj2s(L, to, &temp);
- }
-}
-
-
-/*
-** Let x = AB, where A is a prefix of length 'n'. Then,
-** rotate x n == BA. But BA == (A^r . B^r)^r.
-*/
-LUA_API void lua_rotate (lua_State *L, int idx, int n) {
- StkId p, t, m;
- lua_lock(L);
- t = L->top - 1; /* end of stack segment being rotated */
- p = index2addr(L, idx); /* start of segment */
- api_checkstackindex(idx, p);
- api_check((n >= 0 ? n : -n) <= (t - p + 1), "invalid 'n'");
- m = (n >= 0 ? t - n : p - n - 1); /* end of prefix */
- reverse(L, p, m); /* reverse the prefix with length 'n' */
- reverse(L, m + 1, t); /* reverse the suffix */
- reverse(L, p, t); /* reverse the entire segment */
- lua_unlock(L);
-}
-
-
-LUA_API void lua_copy (lua_State *L, int fromidx, int toidx) {
- TValue *fr, *to;
- lua_lock(L);
- fr = index2addr(L, fromidx);
- to = index2addr(L, toidx);
- api_checkvalidindex(to);
- setobj(L, to, fr);
- if (isupvalue(toidx)) /* function upvalue? */
- luaC_barrier(L, clCvalue(L->ci->func), fr);
- /* LUA_REGISTRYINDEX does not need gc barrier
- (collector revisits it before finishing collection) */
- lua_unlock(L);
-}
-
-
-LUA_API void lua_pushvalue (lua_State *L, int idx) {
- lua_lock(L);
- setobj2s(L, L->top, index2addr(L, idx));
- api_incr_top(L);
- lua_unlock(L);
-}
-
-
-
-/*
-** access functions (stack -> C)
-*/
-
-
-LUA_API int lua_type (lua_State *L, int idx) {
- StkId o = index2addr(L, idx);
- return (isvalid(o) ? ttnov(o) : LUA_TNONE);
-}
-
-
-LUA_API const char *lua_typename (lua_State *L, int t) {
- UNUSED(L);
- api_check(LUA_TNONE <= t && t < LUA_NUMTAGS, "invalid tag");
- return ttypename(t);
-}
-
-
-LUA_API int lua_iscfunction (lua_State *L, int idx) {
- StkId o = index2addr(L, idx);
- return (ttislcf(o) || (ttisCclosure(o)));
-}
-
-
-LUA_API int lua_isinteger (lua_State *L, int idx) {
- StkId o = index2addr(L, idx);
- return ttisinteger(o);
-}
-
-
-LUA_API int lua_isnumber (lua_State *L, int idx) {
- lua_Number n;
- const TValue *o = index2addr(L, idx);
- return tonumber(o, &n);
-}
-
-
-LUA_API int lua_isstring (lua_State *L, int idx) {
- const TValue *o = index2addr(L, idx);
- return (ttisstring(o) || cvt2str(o));
-}
-
-
-LUA_API int lua_isuserdata (lua_State *L, int idx) {
- const TValue *o = index2addr(L, idx);
- return (ttisfulluserdata(o) || ttislightuserdata(o));
-}
-
-
-LUA_API int lua_rawequal (lua_State *L, int index1, int index2) {
- StkId o1 = index2addr(L, index1);
- StkId o2 = index2addr(L, index2);
- return (isvalid(o1) && isvalid(o2)) ? luaV_rawequalobj(o1, o2) : 0;
-}
-
-
-LUA_API void lua_arith (lua_State *L, int op) {
- lua_lock(L);
- if (op != LUA_OPUNM && op != LUA_OPBNOT)
- api_checknelems(L, 2); /* all other operations expect two operands */
- else { /* for unary operations, add fake 2nd operand */
- api_checknelems(L, 1);
- setobjs2s(L, L->top, L->top - 1);
- L->top++;
- }
- /* first operand at top - 2, second at top - 1; result go to top - 2 */
- luaO_arith(L, op, L->top - 2, L->top - 1, L->top - 2);
- L->top--; /* remove second operand */
- lua_unlock(L);
-}
-
-
-LUA_API int lua_compare (lua_State *L, int index1, int index2, int op) {
- StkId o1, o2;
- int i = 0;
- lua_lock(L); /* may call tag method */
- o1 = index2addr(L, index1);
- o2 = index2addr(L, index2);
- if (isvalid(o1) && isvalid(o2)) {
- switch (op) {
- case LUA_OPEQ: i = luaV_equalobj(L, o1, o2); break;
- case LUA_OPLT: i = luaV_lessthan(L, o1, o2); break;
- case LUA_OPLE: i = luaV_lessequal(L, o1, o2); break;
- default: api_check(0, "invalid option");
- }
- }
- lua_unlock(L);
- return i;
-}
-
-
-LUA_API size_t lua_stringtonumber (lua_State *L, const char *s) {
- size_t sz = luaO_str2num(s, L->top);
- if (sz != 0)
- api_incr_top(L);
- return sz;
-}
-
-
-LUA_API lua_Number lua_tonumberx (lua_State *L, int idx, int *pisnum) {
- lua_Number n;
- const TValue *o = index2addr(L, idx);
- int isnum = tonumber(o, &n);
- if (!isnum)
- n = 0; /* call to 'tonumber' may change 'n' even if it fails */
- if (pisnum) *pisnum = isnum;
- return n;
-}
-
-
-LUA_API lua_Integer lua_tointegerx (lua_State *L, int idx, int *pisnum) {
- lua_Integer res;
- const TValue *o = index2addr(L, idx);
- int isnum = tointeger(o, &res);
- if (!isnum)
- res = 0; /* call to 'tointeger' may change 'n' even if it fails */
- if (pisnum) *pisnum = isnum;
- return res;
-}
-
-
-LUA_API int lua_toboolean (lua_State *L, int idx) {
- const TValue *o = index2addr(L, idx);
- return !l_isfalse(o);
-}
-
-
-LUA_API const char *lua_tolstring (lua_State *L, int idx, size_t *len) {
- StkId o = index2addr(L, idx);
- if (!ttisstring(o)) {
- if (!cvt2str(o)) { /* not convertible? */
- if (len != NULL) *len = 0;
- return NULL;
- }
- lua_lock(L); /* 'luaO_tostring' may create a new string */
- luaC_checkGC(L);
- o = index2addr(L, idx); /* previous call may reallocate the stack */
- luaO_tostring(L, o);
- lua_unlock(L);
- }
- if (len != NULL) *len = tsvalue(o)->len;
- return svalue(o);
-}
-
-
-LUA_API size_t lua_rawlen (lua_State *L, int idx) {
- StkId o = index2addr(L, idx);
- switch (ttnov(o)) {
- case LUA_TSTRING: return tsvalue(o)->len;
- case LUA_TUSERDATA: return uvalue(o)->len;
- case LUA_TTABLE: return luaH_getn(hvalue(o));
- default: return 0;
- }
-}
-
-
-LUA_API lua_CFunction lua_tocfunction (lua_State *L, int idx) {
- StkId o = index2addr(L, idx);
- if (ttislcf(o)) return fvalue(o);
- else if (ttisCclosure(o))
- return clCvalue(o)->f;
- else return NULL; /* not a C function */
-}
-
-
-LUA_API void *lua_touserdata (lua_State *L, int idx) {
- StkId o = index2addr(L, idx);
- switch (ttnov(o)) {
- case LUA_TUSERDATA: return getudatamem(uvalue(o));
- case LUA_TLIGHTUSERDATA: return pvalue(o);
- default: return NULL;
- }
-}
-
-
-LUA_API lua_State *lua_tothread (lua_State *L, int idx) {
- StkId o = index2addr(L, idx);
- return (!ttisthread(o)) ? NULL : thvalue(o);
-}
-
-
-LUA_API const void *lua_topointer (lua_State *L, int idx) {
- StkId o = index2addr(L, idx);
- switch (ttype(o)) {
- case LUA_TTABLE: return hvalue(o);
- case LUA_TLCL: return clLvalue(o);
- case LUA_TCCL: return clCvalue(o);
- case LUA_TLCF: return cast(void *, cast(size_t, fvalue(o)));
- case LUA_TTHREAD: return thvalue(o);
- case LUA_TUSERDATA:
- case LUA_TLIGHTUSERDATA:
- return lua_touserdata(L, idx);
- default: return NULL;
- }
-}
-
-
-
-/*
-** push functions (C -> stack)
-*/
-
-
-LUA_API void lua_pushnil (lua_State *L) {
- lua_lock(L);
- setnilvalue(L->top);
- api_incr_top(L);
- lua_unlock(L);
-}
-
-
-LUA_API void lua_pushnumber (lua_State *L, lua_Number n) {
- lua_lock(L);
- setfltvalue(L->top, n);
- api_incr_top(L);
- lua_unlock(L);
-}
-
-
-LUA_API void lua_pushinteger (lua_State *L, lua_Integer n) {
- lua_lock(L);
- setivalue(L->top, n);
- api_incr_top(L);
- lua_unlock(L);
-}
-
-
-LUA_API const char *lua_pushlstring (lua_State *L, const char *s, size_t len) {
- TString *ts;
- lua_lock(L);
- luaC_checkGC(L);
- ts = luaS_newlstr(L, s, len);
- setsvalue2s(L, L->top, ts);
- api_incr_top(L);
- lua_unlock(L);
- return getstr(ts);
-}
-
-
-LUA_API const char *lua_pushstring (lua_State *L, const char *s) {
- if (s == NULL) {
- lua_pushnil(L);
- return NULL;
- }
- else {
- TString *ts;
- lua_lock(L);
- luaC_checkGC(L);
- ts = luaS_new(L, s);
- setsvalue2s(L, L->top, ts);
- api_incr_top(L);
- lua_unlock(L);
- return getstr(ts);
- }
-}
-
-
-LUA_API const char *lua_pushvfstring (lua_State *L, const char *fmt,
- va_list argp) {
- const char *ret;
- lua_lock(L);
- luaC_checkGC(L);
- ret = luaO_pushvfstring(L, fmt, argp);
- lua_unlock(L);
- return ret;
-}
-
-
-LUA_API const char *lua_pushfstring (lua_State *L, const char *fmt, ...) {
- const char *ret;
- va_list argp;
- lua_lock(L);
- luaC_checkGC(L);
- va_start(argp, fmt);
- ret = luaO_pushvfstring(L, fmt, argp);
- va_end(argp);
- lua_unlock(L);
- return ret;
-}
-
-
-LUA_API void lua_pushcclosure (lua_State *L, lua_CFunction fn, int n) {
- lua_lock(L);
- if (n == 0) {
- setfvalue(L->top, fn);
- }
- else {
- CClosure *cl;
- api_checknelems(L, n);
- api_check(n <= MAXUPVAL, "upvalue index too large");
- luaC_checkGC(L);
- cl = luaF_newCclosure(L, n);
- cl->f = fn;
- L->top -= n;
- while (n--) {
- setobj2n(L, &cl->upvalue[n], L->top + n);
- /* does not need barrier because closure is white */
- }
- setclCvalue(L, L->top, cl);
- }
- api_incr_top(L);
- lua_unlock(L);
-}
-
-
-LUA_API void lua_pushboolean (lua_State *L, int b) {
- lua_lock(L);
- setbvalue(L->top, (b != 0)); /* ensure that true is 1 */
- api_incr_top(L);
- lua_unlock(L);
-}
-
-
-LUA_API void lua_pushlightuserdata (lua_State *L, void *p) {
- lua_lock(L);
- setpvalue(L->top, p);
- api_incr_top(L);
- lua_unlock(L);
-}
-
-
-LUA_API int lua_pushthread (lua_State *L) {
- lua_lock(L);
- setthvalue(L, L->top, L);
- api_incr_top(L);
- lua_unlock(L);
- return (G(L)->mainthread == L);
-}
-
-
-
-/*
-** get functions (Lua -> stack)
-*/
-
-
-LUA_API int lua_getglobal (lua_State *L, const char *name) {
- Table *reg = hvalue(&G(L)->l_registry);
- const TValue *gt; /* global table */
- lua_lock(L);
- gt = luaH_getint(reg, LUA_RIDX_GLOBALS);
- setsvalue2s(L, L->top++, luaS_new(L, name));
- luaV_gettable(L, gt, L->top - 1, L->top - 1);
- lua_unlock(L);
- return ttnov(L->top - 1);
-}
-
-
-LUA_API int lua_gettable (lua_State *L, int idx) {
- StkId t;
- lua_lock(L);
- t = index2addr(L, idx);
- luaV_gettable(L, t, L->top - 1, L->top - 1);
- lua_unlock(L);
- return ttnov(L->top - 1);
-}
-
-
-LUA_API int lua_getfield (lua_State *L, int idx, const char *k) {
- StkId t;
- lua_lock(L);
- t = index2addr(L, idx);
- setsvalue2s(L, L->top, luaS_new(L, k));
- api_incr_top(L);
- luaV_gettable(L, t, L->top - 1, L->top - 1);
- lua_unlock(L);
- return ttnov(L->top - 1);
-}
-
-
-LUA_API int lua_geti (lua_State *L, int idx, lua_Integer n) {
- StkId t;
- lua_lock(L);
- t = index2addr(L, idx);
- setivalue(L->top, n);
- api_incr_top(L);
- luaV_gettable(L, t, L->top - 1, L->top - 1);
- lua_unlock(L);
- return ttnov(L->top - 1);
-}
-
-
-LUA_API int lua_rawget (lua_State *L, int idx) {
- StkId t;
- lua_lock(L);
- t = index2addr(L, idx);
- api_check(ttistable(t), "table expected");
- setobj2s(L, L->top - 1, luaH_get(hvalue(t), L->top - 1));
- lua_unlock(L);
- return ttnov(L->top - 1);
-}
-
-
-LUA_API int lua_rawgeti (lua_State *L, int idx, lua_Integer n) {
- StkId t;
- lua_lock(L);
- t = index2addr(L, idx);
- api_check(ttistable(t), "table expected");
- setobj2s(L, L->top, luaH_getint(hvalue(t), n));
- api_incr_top(L);
- lua_unlock(L);
- return ttnov(L->top - 1);
-}
-
-
-LUA_API int lua_rawgetp (lua_State *L, int idx, const void *p) {
- StkId t;
- TValue k;
- lua_lock(L);
- t = index2addr(L, idx);
- api_check(ttistable(t), "table expected");
- setpvalue(&k, cast(void *, p));
- setobj2s(L, L->top, luaH_get(hvalue(t), &k));
- api_incr_top(L);
- lua_unlock(L);
- return ttnov(L->top - 1);
-}
-
-
-LUA_API void lua_createtable (lua_State *L, int narray, int nrec) {
- Table *t;
- lua_lock(L);
- luaC_checkGC(L);
- t = luaH_new(L);
- sethvalue(L, L->top, t);
- api_incr_top(L);
- if (narray > 0 || nrec > 0)
- luaH_resize(L, t, narray, nrec);
- lua_unlock(L);
-}
-
-
-LUA_API int lua_getmetatable (lua_State *L, int objindex) {
- const TValue *obj;
- Table *mt;
- int res = 0;
- lua_lock(L);
- obj = index2addr(L, objindex);
- switch (ttnov(obj)) {
- case LUA_TTABLE:
- mt = hvalue(obj)->metatable;
- break;
- case LUA_TUSERDATA:
- mt = uvalue(obj)->metatable;
- break;
- default:
- mt = G(L)->mt[ttnov(obj)];
- break;
- }
- if (mt != NULL) {
- sethvalue(L, L->top, mt);
- api_incr_top(L);
- res = 1;
- }
- lua_unlock(L);
- return res;
-}
-
-
-LUA_API int lua_getuservalue (lua_State *L, int idx) {
- StkId o;
- lua_lock(L);
- o = index2addr(L, idx);
- api_check(ttisfulluserdata(o), "full userdata expected");
- getuservalue(L, uvalue(o), L->top);
- api_incr_top(L);
- lua_unlock(L);
- return ttnov(L->top - 1);
-}
-
-
-/*
-** set functions (stack -> Lua)
-*/
-
-
-LUA_API void lua_setglobal (lua_State *L, const char *name) {
- Table *reg = hvalue(&G(L)->l_registry);
- const TValue *gt; /* global table */
- lua_lock(L);
- api_checknelems(L, 1);
- gt = luaH_getint(reg, LUA_RIDX_GLOBALS);
- setsvalue2s(L, L->top++, luaS_new(L, name));
- luaV_settable(L, gt, L->top - 1, L->top - 2);
- L->top -= 2; /* pop value and key */
- lua_unlock(L);
-}
-
-
-LUA_API void lua_settable (lua_State *L, int idx) {
- StkId t;
- lua_lock(L);
- api_checknelems(L, 2);
- t = index2addr(L, idx);
- luaV_settable(L, t, L->top - 2, L->top - 1);
- L->top -= 2; /* pop index and value */
- lua_unlock(L);
-}
-
-
-LUA_API void lua_setfield (lua_State *L, int idx, const char *k) {
- StkId t;
- lua_lock(L);
- api_checknelems(L, 1);
- t = index2addr(L, idx);
- setsvalue2s(L, L->top++, luaS_new(L, k));
- luaV_settable(L, t, L->top - 1, L->top - 2);
- L->top -= 2; /* pop value and key */
- lua_unlock(L);
-}
-
-
-LUA_API void lua_seti (lua_State *L, int idx, lua_Integer n) {
- StkId t;
- lua_lock(L);
- api_checknelems(L, 1);
- t = index2addr(L, idx);
- setivalue(L->top++, n);
- luaV_settable(L, t, L->top - 1, L->top - 2);
- L->top -= 2; /* pop value and key */
- lua_unlock(L);
-}
-
-
-LUA_API void lua_rawset (lua_State *L, int idx) {
- StkId o;
- Table *t;
- lua_lock(L);
- api_checknelems(L, 2);
- o = index2addr(L, idx);
- api_check(ttistable(o), "table expected");
- t = hvalue(o);
- setobj2t(L, luaH_set(L, t, L->top-2), L->top-1);
- invalidateTMcache(t);
- luaC_barrierback(L, t, L->top-1);
- L->top -= 2;
- lua_unlock(L);
-}
-
-
-LUA_API void lua_rawseti (lua_State *L, int idx, lua_Integer n) {
- StkId o;
- Table *t;
- lua_lock(L);
- api_checknelems(L, 1);
- o = index2addr(L, idx);
- api_check(ttistable(o), "table expected");
- t = hvalue(o);
- luaH_setint(L, t, n, L->top - 1);
- luaC_barrierback(L, t, L->top-1);
- L->top--;
- lua_unlock(L);
-}
-
-
-LUA_API void lua_rawsetp (lua_State *L, int idx, const void *p) {
- StkId o;
- Table *t;
- TValue k;
- lua_lock(L);
- api_checknelems(L, 1);
- o = index2addr(L, idx);
- api_check(ttistable(o), "table expected");
- t = hvalue(o);
- setpvalue(&k, cast(void *, p));
- setobj2t(L, luaH_set(L, t, &k), L->top - 1);
- luaC_barrierback(L, t, L->top - 1);
- L->top--;
- lua_unlock(L);
-}
-
-
-LUA_API int lua_setmetatable (lua_State *L, int objindex) {
- TValue *obj;
- Table *mt;
- lua_lock(L);
- api_checknelems(L, 1);
- obj = index2addr(L, objindex);
- if (ttisnil(L->top - 1))
- mt = NULL;
- else {
- api_check(ttistable(L->top - 1), "table expected");
- mt = hvalue(L->top - 1);
- }
- switch (ttnov(obj)) {
- case LUA_TTABLE: {
- hvalue(obj)->metatable = mt;
- if (mt) {
- luaC_objbarrier(L, gcvalue(obj), mt);
- luaC_checkfinalizer(L, gcvalue(obj), mt);
- }
- break;
- }
- case LUA_TUSERDATA: {
- uvalue(obj)->metatable = mt;
- if (mt) {
- luaC_objbarrier(L, uvalue(obj), mt);
- luaC_checkfinalizer(L, gcvalue(obj), mt);
- }
- break;
- }
- default: {
- G(L)->mt[ttnov(obj)] = mt;
- break;
- }
- }
- L->top--;
- lua_unlock(L);
- return 1;
-}
-
-
-LUA_API void lua_setuservalue (lua_State *L, int idx) {
- StkId o;
- lua_lock(L);
- api_checknelems(L, 1);
- o = index2addr(L, idx);
- api_check(ttisfulluserdata(o), "full userdata expected");
- setuservalue(L, uvalue(o), L->top - 1);
- luaC_barrier(L, gcvalue(o), L->top - 1);
- L->top--;
- lua_unlock(L);
-}
-
-
-/*
-** 'load' and 'call' functions (run Lua code)
-*/
-
-
-#define checkresults(L,na,nr) \
- api_check((nr) == LUA_MULTRET || (L->ci->top - L->top >= (nr) - (na)), \
- "results from function overflow current stack size")
-
-
-LUA_API void lua_callk (lua_State *L, int nargs, int nresults,
- lua_KContext ctx, lua_KFunction k) {
- StkId func;
- lua_lock(L);
- api_check(k == NULL || !isLua(L->ci),
- "cannot use continuations inside hooks");
- api_checknelems(L, nargs+1);
- api_check(L->status == LUA_OK, "cannot do calls on non-normal thread");
- checkresults(L, nargs, nresults);
- func = L->top - (nargs+1);
- if (k != NULL && L->nny == 0) { /* need to prepare continuation? */
- L->ci->u.c.k = k; /* save continuation */
- L->ci->u.c.ctx = ctx; /* save context */
- luaD_call(L, func, nresults, 1); /* do the call */
- }
- else /* no continuation or no yieldable */
- luaD_call(L, func, nresults, 0); /* just do the call */
- adjustresults(L, nresults);
- lua_unlock(L);
-}
-
-
-
-/*
-** Execute a protected call.
-*/
-struct CallS { /* data to 'f_call' */
- StkId func;
- int nresults;
-};
-
-
-static void f_call (lua_State *L, void *ud) {
- struct CallS *c = cast(struct CallS *, ud);
- luaD_call(L, c->func, c->nresults, 0);
-}
-
-
-
-LUA_API int lua_pcallk (lua_State *L, int nargs, int nresults, int errfunc,
- lua_KContext ctx, lua_KFunction k) {
- struct CallS c;
- int status;
- ptrdiff_t func;
- lua_lock(L);
- api_check(k == NULL || !isLua(L->ci),
- "cannot use continuations inside hooks");
- api_checknelems(L, nargs+1);
- api_check(L->status == LUA_OK, "cannot do calls on non-normal thread");
- checkresults(L, nargs, nresults);
- if (errfunc == 0)
- func = 0;
- else {
- StkId o = index2addr(L, errfunc);
- api_checkstackindex(errfunc, o);
- func = savestack(L, o);
- }
- c.func = L->top - (nargs+1); /* function to be called */
- if (k == NULL || L->nny > 0) { /* no continuation or no yieldable? */
- c.nresults = nresults; /* do a 'conventional' protected call */
- status = luaD_pcall(L, f_call, &c, savestack(L, c.func), func);
- }
- else { /* prepare continuation (call is already protected by 'resume') */
- CallInfo *ci = L->ci;
- ci->u.c.k = k; /* save continuation */
- ci->u.c.ctx = ctx; /* save context */
- /* save information for error recovery */
- ci->extra = savestack(L, c.func);
- ci->u.c.old_errfunc = L->errfunc;
- L->errfunc = func;
- setoah(ci->callstatus, L->allowhook); /* save value of 'allowhook' */
- ci->callstatus |= CIST_YPCALL; /* function can do error recovery */
- luaD_call(L, c.func, nresults, 1); /* do the call */
- ci->callstatus &= ~CIST_YPCALL;
- L->errfunc = ci->u.c.old_errfunc;
- status = LUA_OK; /* if it is here, there were no errors */
- }
- adjustresults(L, nresults);
- lua_unlock(L);
- return status;
-}
-
-
-LUA_API int lua_load (lua_State *L, lua_Reader reader, void *data,
- const char *chunkname, const char *mode) {
- ZIO z;
- int status;
- lua_lock(L);
- if (!chunkname) chunkname = "?";
- luaZ_init(L, &z, reader, data);
- status = luaD_protectedparser(L, &z, chunkname, mode);
- if (status == LUA_OK) { /* no errors? */
- LClosure *f = clLvalue(L->top - 1); /* get newly created function */
- if (f->nupvalues >= 1) { /* does it have an upvalue? */
- /* get global table from registry */
- Table *reg = hvalue(&G(L)->l_registry);
- const TValue *gt = luaH_getint(reg, LUA_RIDX_GLOBALS);
- /* set global table as 1st upvalue of 'f' (may be LUA_ENV) */
- setobj(L, f->upvals[0]->v, gt);
- luaC_upvalbarrier(L, f->upvals[0]);
- }
- }
- lua_unlock(L);
- return status;
-}
-
-
-LUA_API int lua_dump (lua_State *L, lua_Writer writer, void *data, int strip) {
- int status;
- TValue *o;
- lua_lock(L);
- api_checknelems(L, 1);
- o = L->top - 1;
- if (isLfunction(o))
- status = luaU_dump(L, getproto(o), writer, data, strip);
- else
- status = 1;
- lua_unlock(L);
- return status;
-}
-
-
-LUA_API int lua_status (lua_State *L) {
- return L->status;
-}
-
-
-/*
-** Garbage-collection function
-*/
-
-LUA_API int lua_gc (lua_State *L, int what, int data) {
- int res = 0;
- global_State *g;
- lua_lock(L);
- g = G(L);
- switch (what) {
- case LUA_GCSTOP: {
- g->gcrunning = 0;
- break;
- }
- case LUA_GCRESTART: {
- luaE_setdebt(g, 0);
- g->gcrunning = 1;
- break;
- }
- case LUA_GCCOLLECT: {
- luaC_fullgc(L, 0);
- break;
- }
- case LUA_GCCOUNT: {
- /* GC values are expressed in Kbytes: #bytes/2^10 */
- res = cast_int(gettotalbytes(g) >> 10);
- break;
- }
- case LUA_GCCOUNTB: {
- res = cast_int(gettotalbytes(g) & 0x3ff);
- break;
- }
- case LUA_GCSTEP: {
- l_mem debt = 1; /* =1 to signal that it did an actual step */
- int oldrunning = g->gcrunning;
- g->gcrunning = 1; /* allow GC to run */
- if (data == 0) {
- luaE_setdebt(g, -GCSTEPSIZE); /* to do a "small" step */
- luaC_step(L);
- }
- else { /* add 'data' to total debt */
- debt = cast(l_mem, data) * 1024 + g->GCdebt;
- luaE_setdebt(g, debt);
- luaC_checkGC(L);
- }
- g->gcrunning = oldrunning; /* restore previous state */
- if (debt > 0 && g->gcstate == GCSpause) /* end of cycle? */
- res = 1; /* signal it */
- break;
- }
- case LUA_GCSETPAUSE: {
- res = g->gcpause;
- g->gcpause = data;
- break;
- }
- case LUA_GCSETSTEPMUL: {
- res = g->gcstepmul;
- if (data < 40) data = 40; /* avoid ridiculous low values (and 0) */
- g->gcstepmul = data;
- break;
- }
- case LUA_GCISRUNNING: {
- res = g->gcrunning;
- break;
- }
- default: res = -1; /* invalid option */
- }
- lua_unlock(L);
- return res;
-}
-
-
-
-/*
-** miscellaneous functions
-*/
-
-
-LUA_API int lua_error (lua_State *L) {
- lua_lock(L);
- api_checknelems(L, 1);
- luaG_errormsg(L);
- /* code unreachable; will unlock when control actually leaves the kernel */
- return 0; /* to avoid warnings */
-}
-
-
-LUA_API int lua_next (lua_State *L, int idx) {
- StkId t;
- int more;
- lua_lock(L);
- t = index2addr(L, idx);
- api_check(ttistable(t), "table expected");
- more = luaH_next(L, hvalue(t), L->top - 1);
- if (more) {
- api_incr_top(L);
- }
- else /* no more elements */
- L->top -= 1; /* remove key */
- lua_unlock(L);
- return more;
-}
-
-
-LUA_API void lua_concat (lua_State *L, int n) {
- lua_lock(L);
- api_checknelems(L, n);
- if (n >= 2) {
- luaC_checkGC(L);
- luaV_concat(L, n);
- }
- else if (n == 0) { /* push empty string */
- setsvalue2s(L, L->top, luaS_newlstr(L, "", 0));
- api_incr_top(L);
- }
- /* else n == 1; nothing to do */
- lua_unlock(L);
-}
-
-
-LUA_API void lua_len (lua_State *L, int idx) {
- StkId t;
- lua_lock(L);
- t = index2addr(L, idx);
- luaV_objlen(L, L->top, t);
- api_incr_top(L);
- lua_unlock(L);
-}
-
-
-LUA_API lua_Alloc lua_getallocf (lua_State *L, void **ud) {
- lua_Alloc f;
- lua_lock(L);
- if (ud) *ud = G(L)->ud;
- f = G(L)->frealloc;
- lua_unlock(L);
- return f;
-}
-
-
-LUA_API void lua_setallocf (lua_State *L, lua_Alloc f, void *ud) {
- lua_lock(L);
- G(L)->ud = ud;
- G(L)->frealloc = f;
- lua_unlock(L);
-}
-
-
-LUA_API void *lua_newuserdata (lua_State *L, size_t size) {
- Udata *u;
- lua_lock(L);
- luaC_checkGC(L);
- u = luaS_newudata(L, size);
- setuvalue(L, L->top, u);
- api_incr_top(L);
- lua_unlock(L);
- return getudatamem(u);
-}
-
-
-
-static const char *aux_upvalue (StkId fi, int n, TValue **val,
- CClosure **owner, UpVal **uv) {
- switch (ttype(fi)) {
- case LUA_TCCL: { /* C closure */
- CClosure *f = clCvalue(fi);
- if (!(1 <= n && n <= f->nupvalues)) return NULL;
- *val = &f->upvalue[n-1];
- if (owner) *owner = f;
- return "";
- }
- case LUA_TLCL: { /* Lua closure */
- LClosure *f = clLvalue(fi);
- TString *name;
- Proto *p = f->p;
- if (!(1 <= n && n <= p->sizeupvalues)) return NULL;
- *val = f->upvals[n-1]->v;
- if (uv) *uv = f->upvals[n - 1];
- name = p->upvalues[n-1].name;
- return (name == NULL) ? "(*no name)" : getstr(name);
- }
- default: return NULL; /* not a closure */
- }
-}
-
-
-LUA_API const char *lua_getupvalue (lua_State *L, int funcindex, int n) {
- const char *name;
- TValue *val = NULL; /* to avoid warnings */
- lua_lock(L);
- name = aux_upvalue(index2addr(L, funcindex), n, &val, NULL, NULL);
- if (name) {
- setobj2s(L, L->top, val);
- api_incr_top(L);
- }
- lua_unlock(L);
- return name;
-}
-
-
-LUA_API const char *lua_setupvalue (lua_State *L, int funcindex, int n) {
- const char *name;
- TValue *val = NULL; /* to avoid warnings */
- CClosure *owner = NULL;
- UpVal *uv = NULL;
- StkId fi;
- lua_lock(L);
- fi = index2addr(L, funcindex);
- api_checknelems(L, 1);
- name = aux_upvalue(fi, n, &val, &owner, &uv);
- if (name) {
- L->top--;
- setobj(L, val, L->top);
- if (owner) { luaC_barrier(L, owner, L->top); }
- else if (uv) { luaC_upvalbarrier(L, uv); }
- }
- lua_unlock(L);
- return name;
-}
-
-
-static UpVal **getupvalref (lua_State *L, int fidx, int n, LClosure **pf) {
- LClosure *f;
- StkId fi = index2addr(L, fidx);
- api_check(ttisLclosure(fi), "Lua function expected");
- f = clLvalue(fi);
- api_check((1 <= n && n <= f->p->sizeupvalues), "invalid upvalue index");
- if (pf) *pf = f;
- return &f->upvals[n - 1]; /* get its upvalue pointer */
-}
-
-
-LUA_API void *lua_upvalueid (lua_State *L, int fidx, int n) {
- StkId fi = index2addr(L, fidx);
- switch (ttype(fi)) {
- case LUA_TLCL: { /* lua closure */
- return *getupvalref(L, fidx, n, NULL);
- }
- case LUA_TCCL: { /* C closure */
- CClosure *f = clCvalue(fi);
- api_check(1 <= n && n <= f->nupvalues, "invalid upvalue index");
- return &f->upvalue[n - 1];
- }
- default: {
- api_check(0, "closure expected");
- return NULL;
- }
- }
-}
-
-
-LUA_API void lua_upvaluejoin (lua_State *L, int fidx1, int n1,
- int fidx2, int n2) {
- LClosure *f1;
- UpVal **up1 = getupvalref(L, fidx1, n1, &f1);
- UpVal **up2 = getupvalref(L, fidx2, n2, NULL);
- luaC_upvdeccount(L, *up1);
- *up1 = *up2;
- (*up1)->refcount++;
- if (upisopen(*up1)) (*up1)->u.open.touched = 1;
- luaC_upvalbarrier(L, *up1);
-}
-
-
diff --git a/3rd/lua/src/lapi.h b/3rd/lua/src/lapi.h
deleted file mode 100644
index 092f5e9..0000000
--- a/3rd/lua/src/lapi.h
+++ /dev/null
@@ -1,24 +0,0 @@
-/*
-** $Id: lapi.h,v 2.8 2014/07/15 21:26:50 roberto Exp $
-** Auxiliary functions from Lua API
-** See Copyright Notice in lua.h
-*/
-
-#ifndef lapi_h
-#define lapi_h
-
-
-#include "llimits.h"
-#include "lstate.h"
-
-#define api_incr_top(L) {L->top++; api_check(L->top <= L->ci->top, \
- "stack overflow");}
-
-#define adjustresults(L,nres) \
- { if ((nres) == LUA_MULTRET && L->ci->top < L->top) L->ci->top = L->top; }
-
-#define api_checknelems(L,n) api_check((n) < (L->top - L->ci->func), \
- "not enough elements in the stack")
-
-
-#endif
diff --git a/3rd/lua/src/lauxlib.c b/3rd/lua/src/lauxlib.c
deleted file mode 100644
index 1c41d6a..0000000
--- a/3rd/lua/src/lauxlib.c
+++ /dev/null
@@ -1,972 +0,0 @@
-/*
-** $Id: lauxlib.c,v 1.279 2014/12/14 18:32:26 roberto Exp $
-** Auxiliary functions for building Lua libraries
-** See Copyright Notice in lua.h
-*/
-
-#define lauxlib_c
-#define LUA_LIB
-
-#include "lprefix.h"
-
-
-#include
-#include
-#include
-#include
-#include
-
-
-/* This file uses only the official API of Lua.
-** Any function declared here could be written as an application function.
-*/
-
-#include "lua.h"
-
-#include "lauxlib.h"
-
-
-/*
-** {======================================================
-** Traceback
-** =======================================================
-*/
-
-
-#define LEVELS1 12 /* size of the first part of the stack */
-#define LEVELS2 10 /* size of the second part of the stack */
-
-
-
-/*
-** search for 'objidx' in table at index -1.
-** return 1 + string at top if find a good name.
-*/
-static int findfield (lua_State *L, int objidx, int level) {
- if (level == 0 || !lua_istable(L, -1))
- return 0; /* not found */
- lua_pushnil(L); /* start 'next' loop */
- while (lua_next(L, -2)) { /* for each pair in table */
- if (lua_type(L, -2) == LUA_TSTRING) { /* ignore non-string keys */
- if (lua_rawequal(L, objidx, -1)) { /* found object? */
- lua_pop(L, 1); /* remove value (but keep name) */
- return 1;
- }
- else if (findfield(L, objidx, level - 1)) { /* try recursively */
- lua_remove(L, -2); /* remove table (but keep name) */
- lua_pushliteral(L, ".");
- lua_insert(L, -2); /* place '.' between the two names */
- lua_concat(L, 3);
- return 1;
- }
- }
- lua_pop(L, 1); /* remove value */
- }
- return 0; /* not found */
-}
-
-
-/*
-** Search for a name for a function in all loaded modules
-** (registry._LOADED).
-*/
-static int pushglobalfuncname (lua_State *L, lua_Debug *ar) {
- int top = lua_gettop(L);
- lua_getinfo(L, "f", ar); /* push function */
- lua_getfield(L, LUA_REGISTRYINDEX, "_LOADED");
- if (findfield(L, top + 1, 2)) {
- const char *name = lua_tostring(L, -1);
- if (strncmp(name, "_G.", 3) == 0) { /* name start with '_G.'? */
- lua_pushstring(L, name + 3); /* push name without prefix */
- lua_remove(L, -2); /* remove original name */
- }
- lua_copy(L, -1, top + 1); /* move name to proper place */
- lua_pop(L, 2); /* remove pushed values */
- return 1;
- }
- else {
- lua_settop(L, top); /* remove function and global table */
- return 0;
- }
-}
-
-
-static void pushfuncname (lua_State *L, lua_Debug *ar) {
- if (pushglobalfuncname(L, ar)) { /* try first a global name */
- lua_pushfstring(L, "function '%s'", lua_tostring(L, -1));
- lua_remove(L, -2); /* remove name */
- }
- else if (*ar->namewhat != '\0') /* is there a name from code? */
- lua_pushfstring(L, "%s '%s'", ar->namewhat, ar->name); /* use it */
- else if (*ar->what == 'm') /* main? */
- lua_pushliteral(L, "main chunk");
- else if (*ar->what != 'C') /* for Lua functions, use */
- lua_pushfstring(L, "function <%s:%d>", ar->short_src, ar->linedefined);
- else /* nothing left... */
- lua_pushliteral(L, "?");
-}
-
-
-static int countlevels (lua_State *L) {
- lua_Debug ar;
- int li = 1, le = 1;
- /* find an upper bound */
- while (lua_getstack(L, le, &ar)) { li = le; le *= 2; }
- /* do a binary search */
- while (li < le) {
- int m = (li + le)/2;
- if (lua_getstack(L, m, &ar)) li = m + 1;
- else le = m;
- }
- return le - 1;
-}
-
-
-LUALIB_API void luaL_traceback (lua_State *L, lua_State *L1,
- const char *msg, int level) {
- lua_Debug ar;
- int top = lua_gettop(L);
- int numlevels = countlevels(L1);
- int mark = (numlevels > LEVELS1 + LEVELS2) ? LEVELS1 : 0;
- if (msg) lua_pushfstring(L, "%s\n", msg);
- lua_pushliteral(L, "stack traceback:");
- while (lua_getstack(L1, level++, &ar)) {
- if (level == mark) { /* too many levels? */
- lua_pushliteral(L, "\n\t..."); /* add a '...' */
- level = numlevels - LEVELS2; /* and skip to last ones */
- }
- else {
- lua_getinfo(L1, "Slnt", &ar);
- lua_pushfstring(L, "\n\t%s:", ar.short_src);
- if (ar.currentline > 0)
- lua_pushfstring(L, "%d:", ar.currentline);
- lua_pushliteral(L, " in ");
- pushfuncname(L, &ar);
- if (ar.istailcall)
- lua_pushliteral(L, "\n\t(...tail calls...)");
- lua_concat(L, lua_gettop(L) - top);
- }
- }
- lua_concat(L, lua_gettop(L) - top);
-}
-
-/* }====================================================== */
-
-
-/*
-** {======================================================
-** Error-report functions
-** =======================================================
-*/
-
-LUALIB_API int luaL_argerror (lua_State *L, int arg, const char *extramsg) {
- lua_Debug ar;
- if (!lua_getstack(L, 0, &ar)) /* no stack frame? */
- return luaL_error(L, "bad argument #%d (%s)", arg, extramsg);
- lua_getinfo(L, "n", &ar);
- if (strcmp(ar.namewhat, "method") == 0) {
- arg--; /* do not count 'self' */
- if (arg == 0) /* error is in the self argument itself? */
- return luaL_error(L, "calling '%s' on bad self (%s)",
- ar.name, extramsg);
- }
- if (ar.name == NULL)
- ar.name = (pushglobalfuncname(L, &ar)) ? lua_tostring(L, -1) : "?";
- return luaL_error(L, "bad argument #%d to '%s' (%s)",
- arg, ar.name, extramsg);
-}
-
-
-static int typeerror (lua_State *L, int arg, const char *tname) {
- const char *msg;
- const char *typearg; /* name for the type of the actual argument */
- if (luaL_getmetafield(L, arg, "__name") == LUA_TSTRING)
- typearg = lua_tostring(L, -1); /* use the given type name */
- else if (lua_type(L, arg) == LUA_TLIGHTUSERDATA)
- typearg = "light userdata"; /* special name for messages */
- else
- typearg = luaL_typename(L, arg); /* standard name */
- msg = lua_pushfstring(L, "%s expected, got %s", tname, typearg);
- return luaL_argerror(L, arg, msg);
-}
-
-
-static void tag_error (lua_State *L, int arg, int tag) {
- typeerror(L, arg, lua_typename(L, tag));
-}
-
-
-LUALIB_API void luaL_where (lua_State *L, int level) {
- lua_Debug ar;
- if (lua_getstack(L, level, &ar)) { /* check function at level */
- lua_getinfo(L, "Sl", &ar); /* get info about it */
- if (ar.currentline > 0) { /* is there info? */
- lua_pushfstring(L, "%s:%d: ", ar.short_src, ar.currentline);
- return;
- }
- }
- lua_pushliteral(L, ""); /* else, no information available... */
-}
-
-
-LUALIB_API int luaL_error (lua_State *L, const char *fmt, ...) {
- va_list argp;
- va_start(argp, fmt);
- luaL_where(L, 1);
- lua_pushvfstring(L, fmt, argp);
- va_end(argp);
- lua_concat(L, 2);
- return lua_error(L);
-}
-
-
-LUALIB_API int luaL_fileresult (lua_State *L, int stat, const char *fname) {
- int en = errno; /* calls to Lua API may change this value */
- if (stat) {
- lua_pushboolean(L, 1);
- return 1;
- }
- else {
- lua_pushnil(L);
- if (fname)
- lua_pushfstring(L, "%s: %s", fname, strerror(en));
- else
- lua_pushstring(L, strerror(en));
- lua_pushinteger(L, en);
- return 3;
- }
-}
-
-
-#if !defined(l_inspectstat) /* { */
-
-#if defined(LUA_USE_POSIX)
-
-#include
-
-/*
-** use appropriate macros to interpret 'pclose' return status
-*/
-#define l_inspectstat(stat,what) \
- if (WIFEXITED(stat)) { stat = WEXITSTATUS(stat); } \
- else if (WIFSIGNALED(stat)) { stat = WTERMSIG(stat); what = "signal"; }
-
-#else
-
-#define l_inspectstat(stat,what) /* no op */
-
-#endif
-
-#endif /* } */
-
-
-LUALIB_API int luaL_execresult (lua_State *L, int stat) {
- const char *what = "exit"; /* type of termination */
- if (stat == -1) /* error? */
- return luaL_fileresult(L, 0, NULL);
- else {
- l_inspectstat(stat, what); /* interpret result */
- if (*what == 'e' && stat == 0) /* successful termination? */
- lua_pushboolean(L, 1);
- else
- lua_pushnil(L);
- lua_pushstring(L, what);
- lua_pushinteger(L, stat);
- return 3; /* return true/nil,what,code */
- }
-}
-
-/* }====================================================== */
-
-
-/*
-** {======================================================
-** Userdata's metatable manipulation
-** =======================================================
-*/
-
-LUALIB_API int luaL_newmetatable (lua_State *L, const char *tname) {
- if (luaL_getmetatable(L, tname)) /* name already in use? */
- return 0; /* leave previous value on top, but return 0 */
- lua_pop(L, 1);
- lua_newtable(L); /* create metatable */
- lua_pushstring(L, tname);
- lua_setfield(L, -2, "__name"); /* metatable.__name = tname */
- lua_pushvalue(L, -1);
- lua_setfield(L, LUA_REGISTRYINDEX, tname); /* registry.name = metatable */
- return 1;
-}
-
-
-LUALIB_API void luaL_setmetatable (lua_State *L, const char *tname) {
- luaL_getmetatable(L, tname);
- lua_setmetatable(L, -2);
-}
-
-
-LUALIB_API void *luaL_testudata (lua_State *L, int ud, const char *tname) {
- void *p = lua_touserdata(L, ud);
- if (p != NULL) { /* value is a userdata? */
- if (lua_getmetatable(L, ud)) { /* does it have a metatable? */
- luaL_getmetatable(L, tname); /* get correct metatable */
- if (!lua_rawequal(L, -1, -2)) /* not the same? */
- p = NULL; /* value is a userdata with wrong metatable */
- lua_pop(L, 2); /* remove both metatables */
- return p;
- }
- }
- return NULL; /* value is not a userdata with a metatable */
-}
-
-
-LUALIB_API void *luaL_checkudata (lua_State *L, int ud, const char *tname) {
- void *p = luaL_testudata(L, ud, tname);
- if (p == NULL) typeerror(L, ud, tname);
- return p;
-}
-
-/* }====================================================== */
-
-
-/*
-** {======================================================
-** Argument check functions
-** =======================================================
-*/
-
-LUALIB_API int luaL_checkoption (lua_State *L, int arg, const char *def,
- const char *const lst[]) {
- const char *name = (def) ? luaL_optstring(L, arg, def) :
- luaL_checkstring(L, arg);
- int i;
- for (i=0; lst[i]; i++)
- if (strcmp(lst[i], name) == 0)
- return i;
- return luaL_argerror(L, arg,
- lua_pushfstring(L, "invalid option '%s'", name));
-}
-
-
-LUALIB_API void luaL_checkstack (lua_State *L, int space, const char *msg) {
- /* keep some extra space to run error routines, if needed */
- const int extra = LUA_MINSTACK;
- if (!lua_checkstack(L, space + extra)) {
- if (msg)
- luaL_error(L, "stack overflow (%s)", msg);
- else
- luaL_error(L, "stack overflow");
- }
-}
-
-
-LUALIB_API void luaL_checktype (lua_State *L, int arg, int t) {
- if (lua_type(L, arg) != t)
- tag_error(L, arg, t);
-}
-
-
-LUALIB_API void luaL_checkany (lua_State *L, int arg) {
- if (lua_type(L, arg) == LUA_TNONE)
- luaL_argerror(L, arg, "value expected");
-}
-
-
-LUALIB_API const char *luaL_checklstring (lua_State *L, int arg, size_t *len) {
- const char *s = lua_tolstring(L, arg, len);
- if (!s) tag_error(L, arg, LUA_TSTRING);
- return s;
-}
-
-
-LUALIB_API const char *luaL_optlstring (lua_State *L, int arg,
- const char *def, size_t *len) {
- if (lua_isnoneornil(L, arg)) {
- if (len)
- *len = (def ? strlen(def) : 0);
- return def;
- }
- else return luaL_checklstring(L, arg, len);
-}
-
-
-LUALIB_API lua_Number luaL_checknumber (lua_State *L, int arg) {
- int isnum;
- lua_Number d = lua_tonumberx(L, arg, &isnum);
- if (!isnum)
- tag_error(L, arg, LUA_TNUMBER);
- return d;
-}
-
-
-LUALIB_API lua_Number luaL_optnumber (lua_State *L, int arg, lua_Number def) {
- return luaL_opt(L, luaL_checknumber, arg, def);
-}
-
-
-static void interror (lua_State *L, int arg) {
- if (lua_isnumber(L, arg))
- luaL_argerror(L, arg, "number has no integer representation");
- else
- tag_error(L, arg, LUA_TNUMBER);
-}
-
-
-LUALIB_API lua_Integer luaL_checkinteger (lua_State *L, int arg) {
- int isnum;
- lua_Integer d = lua_tointegerx(L, arg, &isnum);
- if (!isnum) {
- interror(L, arg);
- }
- return d;
-}
-
-
-LUALIB_API lua_Integer luaL_optinteger (lua_State *L, int arg,
- lua_Integer def) {
- return luaL_opt(L, luaL_checkinteger, arg, def);
-}
-
-/* }====================================================== */
-
-
-/*
-** {======================================================
-** Generic Buffer manipulation
-** =======================================================
-*/
-
-/*
-** check whether buffer is using a userdata on the stack as a temporary
-** buffer
-*/
-#define buffonstack(B) ((B)->b != (B)->initb)
-
-
-/*
-** returns a pointer to a free area with at least 'sz' bytes
-*/
-LUALIB_API char *luaL_prepbuffsize (luaL_Buffer *B, size_t sz) {
- lua_State *L = B->L;
- if (B->size - B->n < sz) { /* not enough space? */
- char *newbuff;
- size_t newsize = B->size * 2; /* double buffer size */
- if (newsize - B->n < sz) /* not big enough? */
- newsize = B->n + sz;
- if (newsize < B->n || newsize - B->n < sz)
- luaL_error(L, "buffer too large");
- /* create larger buffer */
- newbuff = (char *)lua_newuserdata(L, newsize * sizeof(char));
- /* move content to new buffer */
- memcpy(newbuff, B->b, B->n * sizeof(char));
- if (buffonstack(B))
- lua_remove(L, -2); /* remove old buffer */
- B->b = newbuff;
- B->size = newsize;
- }
- return &B->b[B->n];
-}
-
-
-LUALIB_API void luaL_addlstring (luaL_Buffer *B, const char *s, size_t l) {
- char *b = luaL_prepbuffsize(B, l);
- memcpy(b, s, l * sizeof(char));
- luaL_addsize(B, l);
-}
-
-
-LUALIB_API void luaL_addstring (luaL_Buffer *B, const char *s) {
- luaL_addlstring(B, s, strlen(s));
-}
-
-
-LUALIB_API void luaL_pushresult (luaL_Buffer *B) {
- lua_State *L = B->L;
- lua_pushlstring(L, B->b, B->n);
- if (buffonstack(B))
- lua_remove(L, -2); /* remove old buffer */
-}
-
-
-LUALIB_API void luaL_pushresultsize (luaL_Buffer *B, size_t sz) {
- luaL_addsize(B, sz);
- luaL_pushresult(B);
-}
-
-
-LUALIB_API void luaL_addvalue (luaL_Buffer *B) {
- lua_State *L = B->L;
- size_t l;
- const char *s = lua_tolstring(L, -1, &l);
- if (buffonstack(B))
- lua_insert(L, -2); /* put value below buffer */
- luaL_addlstring(B, s, l);
- lua_remove(L, (buffonstack(B)) ? -2 : -1); /* remove value */
-}
-
-
-LUALIB_API void luaL_buffinit (lua_State *L, luaL_Buffer *B) {
- B->L = L;
- B->b = B->initb;
- B->n = 0;
- B->size = LUAL_BUFFERSIZE;
-}
-
-
-LUALIB_API char *luaL_buffinitsize (lua_State *L, luaL_Buffer *B, size_t sz) {
- luaL_buffinit(L, B);
- return luaL_prepbuffsize(B, sz);
-}
-
-/* }====================================================== */
-
-
-/*
-** {======================================================
-** Reference system
-** =======================================================
-*/
-
-/* index of free-list header */
-#define freelist 0
-
-
-LUALIB_API int luaL_ref (lua_State *L, int t) {
- int ref;
- if (lua_isnil(L, -1)) {
- lua_pop(L, 1); /* remove from stack */
- return LUA_REFNIL; /* 'nil' has a unique fixed reference */
- }
- t = lua_absindex(L, t);
- lua_rawgeti(L, t, freelist); /* get first free element */
- ref = (int)lua_tointeger(L, -1); /* ref = t[freelist] */
- lua_pop(L, 1); /* remove it from stack */
- if (ref != 0) { /* any free element? */
- lua_rawgeti(L, t, ref); /* remove it from list */
- lua_rawseti(L, t, freelist); /* (t[freelist] = t[ref]) */
- }
- else /* no free elements */
- ref = (int)lua_rawlen(L, t) + 1; /* get a new reference */
- lua_rawseti(L, t, ref);
- return ref;
-}
-
-
-LUALIB_API void luaL_unref (lua_State *L, int t, int ref) {
- if (ref >= 0) {
- t = lua_absindex(L, t);
- lua_rawgeti(L, t, freelist);
- lua_rawseti(L, t, ref); /* t[ref] = t[freelist] */
- lua_pushinteger(L, ref);
- lua_rawseti(L, t, freelist); /* t[freelist] = ref */
- }
-}
-
-/* }====================================================== */
-
-
-/*
-** {======================================================
-** Load functions
-** =======================================================
-*/
-
-typedef struct LoadF {
- int n; /* number of pre-read characters */
- FILE *f; /* file being read */
- char buff[BUFSIZ]; /* area for reading file */
-} LoadF;
-
-
-static const char *getF (lua_State *L, void *ud, size_t *size) {
- LoadF *lf = (LoadF *)ud;
- (void)L; /* not used */
- if (lf->n > 0) { /* are there pre-read characters to be read? */
- *size = lf->n; /* return them (chars already in buffer) */
- lf->n = 0; /* no more pre-read characters */
- }
- else { /* read a block from file */
- /* 'fread' can return > 0 *and* set the EOF flag. If next call to
- 'getF' called 'fread', it might still wait for user input.
- The next check avoids this problem. */
- if (feof(lf->f)) return NULL;
- *size = fread(lf->buff, 1, sizeof(lf->buff), lf->f); /* read block */
- }
- return lf->buff;
-}
-
-
-static int errfile (lua_State *L, const char *what, int fnameindex) {
- const char *serr = strerror(errno);
- const char *filename = lua_tostring(L, fnameindex) + 1;
- lua_pushfstring(L, "cannot %s %s: %s", what, filename, serr);
- lua_remove(L, fnameindex);
- return LUA_ERRFILE;
-}
-
-
-static int skipBOM (LoadF *lf) {
- const char *p = "\xEF\xBB\xBF"; /* Utf8 BOM mark */
- int c;
- lf->n = 0;
- do {
- c = getc(lf->f);
- if (c == EOF || c != *(const unsigned char *)p++) return c;
- lf->buff[lf->n++] = c; /* to be read by the parser */
- } while (*p != '\0');
- lf->n = 0; /* prefix matched; discard it */
- return getc(lf->f); /* return next character */
-}
-
-
-/*
-** reads the first character of file 'f' and skips an optional BOM mark
-** in its beginning plus its first line if it starts with '#'. Returns
-** true if it skipped the first line. In any case, '*cp' has the
-** first "valid" character of the file (after the optional BOM and
-** a first-line comment).
-*/
-static int skipcomment (LoadF *lf, int *cp) {
- int c = *cp = skipBOM(lf);
- if (c == '#') { /* first line is a comment (Unix exec. file)? */
- do { /* skip first line */
- c = getc(lf->f);
- } while (c != EOF && c != '\n') ;
- *cp = getc(lf->f); /* skip end-of-line, if present */
- return 1; /* there was a comment */
- }
- else return 0; /* no comment */
-}
-
-
-LUALIB_API int luaL_loadfilex (lua_State *L, const char *filename,
- const char *mode) {
- LoadF lf;
- int status, readstatus;
- int c;
- int fnameindex = lua_gettop(L) + 1; /* index of filename on the stack */
- if (filename == NULL) {
- lua_pushliteral(L, "=stdin");
- lf.f = stdin;
- }
- else {
- lua_pushfstring(L, "@%s", filename);
- lf.f = fopen(filename, "r");
- if (lf.f == NULL) return errfile(L, "open", fnameindex);
- }
- if (skipcomment(&lf, &c)) /* read initial portion */
- lf.buff[lf.n++] = '\n'; /* add line to correct line numbers */
- if (c == LUA_SIGNATURE[0] && filename) { /* binary file? */
- lf.f = freopen(filename, "rb", lf.f); /* reopen in binary mode */
- if (lf.f == NULL) return errfile(L, "reopen", fnameindex);
- skipcomment(&lf, &c); /* re-read initial portion */
- }
- if (c != EOF)
- lf.buff[lf.n++] = c; /* 'c' is the first character of the stream */
- status = lua_load(L, getF, &lf, lua_tostring(L, -1), mode);
- readstatus = ferror(lf.f);
- if (filename) fclose(lf.f); /* close file (even in case of errors) */
- if (readstatus) {
- lua_settop(L, fnameindex); /* ignore results from 'lua_load' */
- return errfile(L, "read", fnameindex);
- }
- lua_remove(L, fnameindex);
- return status;
-}
-
-
-typedef struct LoadS {
- const char *s;
- size_t size;
-} LoadS;
-
-
-static const char *getS (lua_State *L, void *ud, size_t *size) {
- LoadS *ls = (LoadS *)ud;
- (void)L; /* not used */
- if (ls->size == 0) return NULL;
- *size = ls->size;
- ls->size = 0;
- return ls->s;
-}
-
-
-LUALIB_API int luaL_loadbufferx (lua_State *L, const char *buff, size_t size,
- const char *name, const char *mode) {
- LoadS ls;
- ls.s = buff;
- ls.size = size;
- return lua_load(L, getS, &ls, name, mode);
-}
-
-
-LUALIB_API int luaL_loadstring (lua_State *L, const char *s) {
- return luaL_loadbuffer(L, s, strlen(s), s);
-}
-
-/* }====================================================== */
-
-
-
-LUALIB_API int luaL_getmetafield (lua_State *L, int obj, const char *event) {
- if (!lua_getmetatable(L, obj)) /* no metatable? */
- return LUA_TNIL;
- else {
- int tt;
- lua_pushstring(L, event);
- tt = lua_rawget(L, -2);
- if (tt == LUA_TNIL) /* is metafield nil? */
- lua_pop(L, 2); /* remove metatable and metafield */
- else
- lua_remove(L, -2); /* remove only metatable */
- return tt; /* return metafield type */
- }
-}
-
-
-LUALIB_API int luaL_callmeta (lua_State *L, int obj, const char *event) {
- obj = lua_absindex(L, obj);
- if (luaL_getmetafield(L, obj, event) == LUA_TNIL) /* no metafield? */
- return 0;
- lua_pushvalue(L, obj);
- lua_call(L, 1, 1);
- return 1;
-}
-
-
-LUALIB_API lua_Integer luaL_len (lua_State *L, int idx) {
- lua_Integer l;
- int isnum;
- lua_len(L, idx);
- l = lua_tointegerx(L, -1, &isnum);
- if (!isnum)
- luaL_error(L, "object length is not an integer");
- lua_pop(L, 1); /* remove object */
- return l;
-}
-
-
-LUALIB_API const char *luaL_tolstring (lua_State *L, int idx, size_t *len) {
- if (!luaL_callmeta(L, idx, "__tostring")) { /* no metafield? */
- switch (lua_type(L, idx)) {
- case LUA_TNUMBER: {
- if (lua_isinteger(L, idx))
- lua_pushfstring(L, "%I", lua_tointeger(L, idx));
- else
- lua_pushfstring(L, "%f", lua_tonumber(L, idx));
- break;
- }
- case LUA_TSTRING:
- lua_pushvalue(L, idx);
- break;
- case LUA_TBOOLEAN:
- lua_pushstring(L, (lua_toboolean(L, idx) ? "true" : "false"));
- break;
- case LUA_TNIL:
- lua_pushliteral(L, "nil");
- break;
- default:
- lua_pushfstring(L, "%s: %p", luaL_typename(L, idx),
- lua_topointer(L, idx));
- break;
- }
- }
- return lua_tolstring(L, -1, len);
-}
-
-
-/*
-** {======================================================
-** Compatibility with 5.1 module functions
-** =======================================================
-*/
-#if defined(LUA_COMPAT_MODULE)
-
-static const char *luaL_findtable (lua_State *L, int idx,
- const char *fname, int szhint) {
- const char *e;
- if (idx) lua_pushvalue(L, idx);
- do {
- e = strchr(fname, '.');
- if (e == NULL) e = fname + strlen(fname);
- lua_pushlstring(L, fname, e - fname);
- if (lua_rawget(L, -2) == LUA_TNIL) { /* no such field? */
- lua_pop(L, 1); /* remove this nil */
- lua_createtable(L, 0, (*e == '.' ? 1 : szhint)); /* new table for field */
- lua_pushlstring(L, fname, e - fname);
- lua_pushvalue(L, -2);
- lua_settable(L, -4); /* set new table into field */
- }
- else if (!lua_istable(L, -1)) { /* field has a non-table value? */
- lua_pop(L, 2); /* remove table and value */
- return fname; /* return problematic part of the name */
- }
- lua_remove(L, -2); /* remove previous table */
- fname = e + 1;
- } while (*e == '.');
- return NULL;
-}
-
-
-/*
-** Count number of elements in a luaL_Reg list.
-*/
-static int libsize (const luaL_Reg *l) {
- int size = 0;
- for (; l && l->name; l++) size++;
- return size;
-}
-
-
-/*
-** Find or create a module table with a given name. The function
-** first looks at the _LOADED table and, if that fails, try a
-** global variable with that name. In any case, leaves on the stack
-** the module table.
-*/
-LUALIB_API void luaL_pushmodule (lua_State *L, const char *modname,
- int sizehint) {
- luaL_findtable(L, LUA_REGISTRYINDEX, "_LOADED", 1); /* get _LOADED table */
- if (lua_getfield(L, -1, modname) != LUA_TTABLE) { /* no _LOADED[modname]? */
- lua_pop(L, 1); /* remove previous result */
- /* try global variable (and create one if it does not exist) */
- lua_pushglobaltable(L);
- if (luaL_findtable(L, 0, modname, sizehint) != NULL)
- luaL_error(L, "name conflict for module '%s'", modname);
- lua_pushvalue(L, -1);
- lua_setfield(L, -3, modname); /* _LOADED[modname] = new table */
- }
- lua_remove(L, -2); /* remove _LOADED table */
-}
-
-
-LUALIB_API void luaL_openlib (lua_State *L, const char *libname,
- const luaL_Reg *l, int nup) {
- luaL_checkversion(L);
- if (libname) {
- luaL_pushmodule(L, libname, libsize(l)); /* get/create library table */
- lua_insert(L, -(nup + 1)); /* move library table to below upvalues */
- }
- if (l)
- luaL_setfuncs(L, l, nup);
- else
- lua_pop(L, nup); /* remove upvalues */
-}
-
-#endif
-/* }====================================================== */
-
-/*
-** set functions from list 'l' into table at top - 'nup'; each
-** function gets the 'nup' elements at the top as upvalues.
-** Returns with only the table at the stack.
-*/
-LUALIB_API void luaL_setfuncs (lua_State *L, const luaL_Reg *l, int nup) {
- luaL_checkstack(L, nup, "too many upvalues");
- for (; l->name != NULL; l++) { /* fill the table with given functions */
- int i;
- for (i = 0; i < nup; i++) /* copy upvalues to the top */
- lua_pushvalue(L, -nup);
- lua_pushcclosure(L, l->func, nup); /* closure with those upvalues */
- lua_setfield(L, -(nup + 2), l->name);
- }
- lua_pop(L, nup); /* remove upvalues */
-}
-
-
-/*
-** ensure that stack[idx][fname] has a table and push that table
-** into the stack
-*/
-LUALIB_API int luaL_getsubtable (lua_State *L, int idx, const char *fname) {
- if (lua_getfield(L, idx, fname) == LUA_TTABLE)
- return 1; /* table already there */
- else {
- lua_pop(L, 1); /* remove previous result */
- idx = lua_absindex(L, idx);
- lua_newtable(L);
- lua_pushvalue(L, -1); /* copy to be left at top */
- lua_setfield(L, idx, fname); /* assign new table to field */
- return 0; /* false, because did not find table there */
- }
-}
-
-
-/*
-** Stripped-down 'require': After checking "loaded" table, calls 'openf'
-** to open a module, registers the result in 'package.loaded' table and,
-** if 'glb' is true, also registers the result in the global table.
-** Leaves resulting module on the top.
-*/
-LUALIB_API void luaL_requiref (lua_State *L, const char *modname,
- lua_CFunction openf, int glb) {
- luaL_getsubtable(L, LUA_REGISTRYINDEX, "_LOADED");
- lua_getfield(L, -1, modname); /* _LOADED[modname] */
- if (!lua_toboolean(L, -1)) { /* package not already loaded? */
- lua_pop(L, 1); /* remove field */
- lua_pushcfunction(L, openf);
- lua_pushstring(L, modname); /* argument to open function */
- lua_call(L, 1, 1); /* call 'openf' to open module */
- lua_pushvalue(L, -1); /* make copy of module (call result) */
- lua_setfield(L, -3, modname); /* _LOADED[modname] = module */
- }
- lua_remove(L, -2); /* remove _LOADED table */
- if (glb) {
- lua_pushvalue(L, -1); /* copy of module */
- lua_setglobal(L, modname); /* _G[modname] = module */
- }
-}
-
-
-LUALIB_API const char *luaL_gsub (lua_State *L, const char *s, const char *p,
- const char *r) {
- const char *wild;
- size_t l = strlen(p);
- luaL_Buffer b;
- luaL_buffinit(L, &b);
- while ((wild = strstr(s, p)) != NULL) {
- luaL_addlstring(&b, s, wild - s); /* push prefix */
- luaL_addstring(&b, r); /* push replacement in place of pattern */
- s = wild + l; /* continue after 'p' */
- }
- luaL_addstring(&b, s); /* push last suffix */
- luaL_pushresult(&b);
- return lua_tostring(L, -1);
-}
-
-
-static void *l_alloc (void *ud, void *ptr, size_t osize, size_t nsize) {
- (void)ud; (void)osize; /* not used */
- if (nsize == 0) {
- free(ptr);
- return NULL;
- }
- else
- return realloc(ptr, nsize);
-}
-
-
-static int panic (lua_State *L) {
- lua_writestringerror("PANIC: unprotected error in call to Lua API (%s)\n",
- lua_tostring(L, -1));
- return 0; /* return to Lua to abort */
-}
-
-
-LUALIB_API lua_State *luaL_newstate (void) {
- lua_State *L = lua_newstate(l_alloc, NULL);
- if (L) lua_atpanic(L, &panic);
- return L;
-}
-
-
-LUALIB_API void luaL_checkversion_ (lua_State *L, lua_Number ver, size_t sz) {
- const lua_Number *v = lua_version(L);
- if (sz != LUAL_NUMSIZES) /* check numeric types */
- luaL_error(L, "core and library have incompatible numeric types");
- if (v != lua_version(NULL))
- luaL_error(L, "multiple Lua VMs detected");
- else if (*v != ver)
- luaL_error(L, "version mismatch: app. needs %f, Lua core provides %f",
- ver, *v);
-}
-
diff --git a/3rd/lua/src/lauxlib.h b/3rd/lua/src/lauxlib.h
deleted file mode 100644
index 0bac246..0000000
--- a/3rd/lua/src/lauxlib.h
+++ /dev/null
@@ -1,256 +0,0 @@
-/*
-** $Id: lauxlib.h,v 1.128 2014/10/29 16:11:17 roberto Exp $
-** Auxiliary functions for building Lua libraries
-** See Copyright Notice in lua.h
-*/
-
-
-#ifndef lauxlib_h
-#define lauxlib_h
-
-
-#include
-#include
-
-#include "lua.h"
-
-
-
-/* extra error code for 'luaL_load' */
-#define LUA_ERRFILE (LUA_ERRERR+1)
-
-
-typedef struct luaL_Reg {
- const char *name;
- lua_CFunction func;
-} luaL_Reg;
-
-
-#define LUAL_NUMSIZES (sizeof(lua_Integer)*16 + sizeof(lua_Number))
-
-LUALIB_API void (luaL_checkversion_) (lua_State *L, lua_Number ver, size_t sz);
-#define luaL_checkversion(L) \
- luaL_checkversion_(L, LUA_VERSION_NUM, LUAL_NUMSIZES)
-
-LUALIB_API int (luaL_getmetafield) (lua_State *L, int obj, const char *e);
-LUALIB_API int (luaL_callmeta) (lua_State *L, int obj, const char *e);
-LUALIB_API const char *(luaL_tolstring) (lua_State *L, int idx, size_t *len);
-LUALIB_API int (luaL_argerror) (lua_State *L, int arg, const char *extramsg);
-LUALIB_API const char *(luaL_checklstring) (lua_State *L, int arg,
- size_t *l);
-LUALIB_API const char *(luaL_optlstring) (lua_State *L, int arg,
- const char *def, size_t *l);
-LUALIB_API lua_Number (luaL_checknumber) (lua_State *L, int arg);
-LUALIB_API lua_Number (luaL_optnumber) (lua_State *L, int arg, lua_Number def);
-
-LUALIB_API lua_Integer (luaL_checkinteger) (lua_State *L, int arg);
-LUALIB_API lua_Integer (luaL_optinteger) (lua_State *L, int arg,
- lua_Integer def);
-
-LUALIB_API void (luaL_checkstack) (lua_State *L, int sz, const char *msg);
-LUALIB_API void (luaL_checktype) (lua_State *L, int arg, int t);
-LUALIB_API void (luaL_checkany) (lua_State *L, int arg);
-
-LUALIB_API int (luaL_newmetatable) (lua_State *L, const char *tname);
-LUALIB_API void (luaL_setmetatable) (lua_State *L, const char *tname);
-LUALIB_API void *(luaL_testudata) (lua_State *L, int ud, const char *tname);
-LUALIB_API void *(luaL_checkudata) (lua_State *L, int ud, const char *tname);
-
-LUALIB_API void (luaL_where) (lua_State *L, int lvl);
-LUALIB_API int (luaL_error) (lua_State *L, const char *fmt, ...);
-
-LUALIB_API int (luaL_checkoption) (lua_State *L, int arg, const char *def,
- const char *const lst[]);
-
-LUALIB_API int (luaL_fileresult) (lua_State *L, int stat, const char *fname);
-LUALIB_API int (luaL_execresult) (lua_State *L, int stat);
-
-/* pre-defined references */
-#define LUA_NOREF (-2)
-#define LUA_REFNIL (-1)
-
-LUALIB_API int (luaL_ref) (lua_State *L, int t);
-LUALIB_API void (luaL_unref) (lua_State *L, int t, int ref);
-
-LUALIB_API int (luaL_loadfilex) (lua_State *L, const char *filename,
- const char *mode);
-
-#define luaL_loadfile(L,f) luaL_loadfilex(L,f,NULL)
-
-LUALIB_API int (luaL_loadbufferx) (lua_State *L, const char *buff, size_t sz,
- const char *name, const char *mode);
-LUALIB_API int (luaL_loadstring) (lua_State *L, const char *s);
-
-LUALIB_API lua_State *(luaL_newstate) (void);
-
-LUALIB_API lua_Integer (luaL_len) (lua_State *L, int idx);
-
-LUALIB_API const char *(luaL_gsub) (lua_State *L, const char *s, const char *p,
- const char *r);
-
-LUALIB_API void (luaL_setfuncs) (lua_State *L, const luaL_Reg *l, int nup);
-
-LUALIB_API int (luaL_getsubtable) (lua_State *L, int idx, const char *fname);
-
-LUALIB_API void (luaL_traceback) (lua_State *L, lua_State *L1,
- const char *msg, int level);
-
-LUALIB_API void (luaL_requiref) (lua_State *L, const char *modname,
- lua_CFunction openf, int glb);
-
-/*
-** ===============================================================
-** some useful macros
-** ===============================================================
-*/
-
-
-#define luaL_newlibtable(L,l) \
- lua_createtable(L, 0, sizeof(l)/sizeof((l)[0]) - 1)
-
-#define luaL_newlib(L,l) \
- (luaL_checkversion(L), luaL_newlibtable(L,l), luaL_setfuncs(L,l,0))
-
-#define luaL_argcheck(L, cond,arg,extramsg) \
- ((void)((cond) || luaL_argerror(L, (arg), (extramsg))))
-#define luaL_checkstring(L,n) (luaL_checklstring(L, (n), NULL))
-#define luaL_optstring(L,n,d) (luaL_optlstring(L, (n), (d), NULL))
-
-#define luaL_typename(L,i) lua_typename(L, lua_type(L,(i)))
-
-#define luaL_dofile(L, fn) \
- (luaL_loadfile(L, fn) || lua_pcall(L, 0, LUA_MULTRET, 0))
-
-#define luaL_dostring(L, s) \
- (luaL_loadstring(L, s) || lua_pcall(L, 0, LUA_MULTRET, 0))
-
-#define luaL_getmetatable(L,n) (lua_getfield(L, LUA_REGISTRYINDEX, (n)))
-
-#define luaL_opt(L,f,n,d) (lua_isnoneornil(L,(n)) ? (d) : f(L,(n)))
-
-#define luaL_loadbuffer(L,s,sz,n) luaL_loadbufferx(L,s,sz,n,NULL)
-
-
-/*
-** {======================================================
-** Generic Buffer manipulation
-** =======================================================
-*/
-
-typedef struct luaL_Buffer {
- char *b; /* buffer address */
- size_t size; /* buffer size */
- size_t n; /* number of characters in buffer */
- lua_State *L;
- char initb[LUAL_BUFFERSIZE]; /* initial buffer */
-} luaL_Buffer;
-
-
-#define luaL_addchar(B,c) \
- ((void)((B)->n < (B)->size || luaL_prepbuffsize((B), 1)), \
- ((B)->b[(B)->n++] = (c)))
-
-#define luaL_addsize(B,s) ((B)->n += (s))
-
-LUALIB_API void (luaL_buffinit) (lua_State *L, luaL_Buffer *B);
-LUALIB_API char *(luaL_prepbuffsize) (luaL_Buffer *B, size_t sz);
-LUALIB_API void (luaL_addlstring) (luaL_Buffer *B, const char *s, size_t l);
-LUALIB_API void (luaL_addstring) (luaL_Buffer *B, const char *s);
-LUALIB_API void (luaL_addvalue) (luaL_Buffer *B);
-LUALIB_API void (luaL_pushresult) (luaL_Buffer *B);
-LUALIB_API void (luaL_pushresultsize) (luaL_Buffer *B, size_t sz);
-LUALIB_API char *(luaL_buffinitsize) (lua_State *L, luaL_Buffer *B, size_t sz);
-
-#define luaL_prepbuffer(B) luaL_prepbuffsize(B, LUAL_BUFFERSIZE)
-
-/* }====================================================== */
-
-
-
-/*
-** {======================================================
-** File handles for IO library
-** =======================================================
-*/
-
-/*
-** A file handle is a userdata with metatable 'LUA_FILEHANDLE' and
-** initial structure 'luaL_Stream' (it may contain other fields
-** after that initial structure).
-*/
-
-#define LUA_FILEHANDLE "FILE*"
-
-
-typedef struct luaL_Stream {
- FILE *f; /* stream (NULL for incompletely created streams) */
- lua_CFunction closef; /* to close stream (NULL for closed streams) */
-} luaL_Stream;
-
-/* }====================================================== */
-
-
-
-/* compatibility with old module system */
-#if defined(LUA_COMPAT_MODULE)
-
-LUALIB_API void (luaL_pushmodule) (lua_State *L, const char *modname,
- int sizehint);
-LUALIB_API void (luaL_openlib) (lua_State *L, const char *libname,
- const luaL_Reg *l, int nup);
-
-#define luaL_register(L,n,l) (luaL_openlib(L,(n),(l),0))
-
-#endif
-
-
-/*
-** {==================================================================
-** "Abstraction Layer" for basic report of messages and errors
-** ===================================================================
-*/
-
-/* print a string */
-#if !defined(lua_writestring)
-#define lua_writestring(s,l) fwrite((s), sizeof(char), (l), stdout)
-#endif
-
-/* print a newline and flush the output */
-#if !defined(lua_writeline)
-#define lua_writeline() (lua_writestring("\n", 1), fflush(stdout))
-#endif
-
-/* print an error message */
-#if !defined(lua_writestringerror)
-#define lua_writestringerror(s,p) \
- (fprintf(stderr, (s), (p)), fflush(stderr))
-#endif
-
-/* }================================================================== */
-
-
-/*
-** {============================================================
-** Compatibility with deprecated conversions
-** =============================================================
-*/
-#if defined(LUA_COMPAT_APIINTCASTS)
-
-#define luaL_checkunsigned(L,a) ((lua_Unsigned)luaL_checkinteger(L,a))
-#define luaL_optunsigned(L,a,d) \
- ((lua_Unsigned)luaL_optinteger(L,a,(lua_Integer)(d)))
-
-#define luaL_checkint(L,n) ((int)luaL_checkinteger(L, (n)))
-#define luaL_optint(L,n,d) ((int)luaL_optinteger(L, (n), (d)))
-
-#define luaL_checklong(L,n) ((long)luaL_checkinteger(L, (n)))
-#define luaL_optlong(L,n,d) ((long)luaL_optinteger(L, (n), (d)))
-
-#endif
-/* }============================================================ */
-
-
-
-#endif
-
-
diff --git a/3rd/lua/src/lbaselib.c b/3rd/lua/src/lbaselib.c
deleted file mode 100644
index a240395..0000000
--- a/3rd/lua/src/lbaselib.c
+++ /dev/null
@@ -1,520 +0,0 @@
-/*
-** $Id: lbaselib.c,v 1.309 2014/12/10 12:26:42 roberto Exp $
-** Basic library
-** See Copyright Notice in lua.h
-*/
-
-#define lbaselib_c
-#define LUA_LIB
-
-#include "lprefix.h"
-
-
-#include
-#include
-#include
-#include
-
-#include "lua.h"
-
-#include "lauxlib.h"
-#include "lualib.h"
-
-
-static int luaB_print (lua_State *L) {
- int n = lua_gettop(L); /* number of arguments */
- int i;
- lua_getglobal(L, "tostring");
- for (i=1; i<=n; i++) {
- const char *s;
- size_t l;
- lua_pushvalue(L, -1); /* function to be called */
- lua_pushvalue(L, i); /* value to print */
- lua_call(L, 1, 1);
- s = lua_tolstring(L, -1, &l); /* get result */
- if (s == NULL)
- return luaL_error(L, "'tostring' must return a string to 'print'");
- if (i>1) lua_writestring("\t", 1);
- lua_writestring(s, l);
- lua_pop(L, 1); /* pop result */
- }
- lua_writeline();
- return 0;
-}
-
-
-#define SPACECHARS " \f\n\r\t\v"
-
-static const char *b_str2int (const char *s, int base, lua_Integer *pn) {
- lua_Unsigned n = 0;
- int neg = 0;
- s += strspn(s, SPACECHARS); /* skip initial spaces */
- if (*s == '-') { s++; neg = 1; } /* handle signal */
- else if (*s == '+') s++;
- if (!isalnum((unsigned char)*s)) /* no digit? */
- return NULL;
- do {
- int digit = (isdigit((unsigned char)*s)) ? *s - '0'
- : toupper((unsigned char)*s) - 'A' + 10;
- if (digit >= base) return NULL; /* invalid numeral */
- n = n * base + digit;
- s++;
- } while (isalnum((unsigned char)*s));
- s += strspn(s, SPACECHARS); /* skip trailing spaces */
- *pn = (lua_Integer)((neg) ? (0u - n) : n);
- return s;
-}
-
-
-static int luaB_tonumber (lua_State *L) {
- if (lua_isnoneornil(L, 2)) { /* standard conversion? */
- luaL_checkany(L, 1);
- if (lua_type(L, 1) == LUA_TNUMBER) { /* already a number? */
- lua_settop(L, 1); /* yes; return it */
- return 1;
- }
- else {
- size_t l;
- const char *s = lua_tolstring(L, 1, &l);
- if (s != NULL && lua_stringtonumber(L, s) == l + 1)
- return 1; /* successful conversion to number */
- /* else not a number */
- }
- }
- else {
- size_t l;
- const char *s;
- lua_Integer n = 0; /* to avoid warnings */
- lua_Integer base = luaL_checkinteger(L, 2);
- luaL_checktype(L, 1, LUA_TSTRING); /* before 'luaL_checklstring'! */
- s = luaL_checklstring(L, 1, &l);
- luaL_argcheck(L, 2 <= base && base <= 36, 2, "base out of range");
- if (b_str2int(s, (int)base, &n) == s + l) {
- lua_pushinteger(L, n);
- return 1;
- } /* else not a number */
- } /* else not a number */
- lua_pushnil(L); /* not a number */
- return 1;
-}
-
-
-static int luaB_error (lua_State *L) {
- int level = (int)luaL_optinteger(L, 2, 1);
- lua_settop(L, 1);
- if (lua_isstring(L, 1) && level > 0) { /* add extra information? */
- luaL_where(L, level);
- lua_pushvalue(L, 1);
- lua_concat(L, 2);
- }
- return lua_error(L);
-}
-
-
-static int luaB_getmetatable (lua_State *L) {
- luaL_checkany(L, 1);
- if (!lua_getmetatable(L, 1)) {
- lua_pushnil(L);
- return 1; /* no metatable */
- }
- luaL_getmetafield(L, 1, "__metatable");
- return 1; /* returns either __metatable field (if present) or metatable */
-}
-
-
-static int luaB_setmetatable (lua_State *L) {
- int t = lua_type(L, 2);
- luaL_checktype(L, 1, LUA_TTABLE);
- luaL_argcheck(L, t == LUA_TNIL || t == LUA_TTABLE, 2,
- "nil or table expected");
- if (luaL_getmetafield(L, 1, "__metatable") != LUA_TNIL)
- return luaL_error(L, "cannot change a protected metatable");
- lua_settop(L, 2);
- lua_setmetatable(L, 1);
- return 1;
-}
-
-
-static int luaB_rawequal (lua_State *L) {
- luaL_checkany(L, 1);
- luaL_checkany(L, 2);
- lua_pushboolean(L, lua_rawequal(L, 1, 2));
- return 1;
-}
-
-
-static int luaB_rawlen (lua_State *L) {
- int t = lua_type(L, 1);
- luaL_argcheck(L, t == LUA_TTABLE || t == LUA_TSTRING, 1,
- "table or string expected");
- lua_pushinteger(L, lua_rawlen(L, 1));
- return 1;
-}
-
-
-static int luaB_rawget (lua_State *L) {
- luaL_checktype(L, 1, LUA_TTABLE);
- luaL_checkany(L, 2);
- lua_settop(L, 2);
- lua_rawget(L, 1);
- return 1;
-}
-
-static int luaB_rawset (lua_State *L) {
- luaL_checktype(L, 1, LUA_TTABLE);
- luaL_checkany(L, 2);
- luaL_checkany(L, 3);
- lua_settop(L, 3);
- lua_rawset(L, 1);
- return 1;
-}
-
-
-static int luaB_collectgarbage (lua_State *L) {
- static const char *const opts[] = {"stop", "restart", "collect",
- "count", "step", "setpause", "setstepmul",
- "isrunning", NULL};
- static const int optsnum[] = {LUA_GCSTOP, LUA_GCRESTART, LUA_GCCOLLECT,
- LUA_GCCOUNT, LUA_GCSTEP, LUA_GCSETPAUSE, LUA_GCSETSTEPMUL,
- LUA_GCISRUNNING};
- int o = optsnum[luaL_checkoption(L, 1, "collect", opts)];
- int ex = (int)luaL_optinteger(L, 2, 0);
- int res = lua_gc(L, o, ex);
- switch (o) {
- case LUA_GCCOUNT: {
- int b = lua_gc(L, LUA_GCCOUNTB, 0);
- lua_pushnumber(L, (lua_Number)res + ((lua_Number)b/1024));
- return 1;
- }
- case LUA_GCSTEP: case LUA_GCISRUNNING: {
- lua_pushboolean(L, res);
- return 1;
- }
- default: {
- lua_pushinteger(L, res);
- return 1;
- }
- }
-}
-
-
-/*
-** This function has all type names as upvalues, to maximize performance.
-*/
-static int luaB_type (lua_State *L) {
- luaL_checkany(L, 1);
- lua_pushvalue(L, lua_upvalueindex(lua_type(L, 1) + 1));
- return 1;
-}
-
-
-static int pairsmeta (lua_State *L, const char *method, int iszero,
- lua_CFunction iter) {
- if (luaL_getmetafield(L, 1, method) == LUA_TNIL) { /* no metamethod? */
- luaL_checktype(L, 1, LUA_TTABLE); /* argument must be a table */
- lua_pushcfunction(L, iter); /* will return generator, */
- lua_pushvalue(L, 1); /* state, */
- if (iszero) lua_pushinteger(L, 0); /* and initial value */
- else lua_pushnil(L);
- }
- else {
- lua_pushvalue(L, 1); /* argument 'self' to metamethod */
- lua_call(L, 1, 3); /* get 3 values from metamethod */
- }
- return 3;
-}
-
-
-static int luaB_next (lua_State *L) {
- luaL_checktype(L, 1, LUA_TTABLE);
- lua_settop(L, 2); /* create a 2nd argument if there isn't one */
- if (lua_next(L, 1))
- return 2;
- else {
- lua_pushnil(L);
- return 1;
- }
-}
-
-
-static int luaB_pairs (lua_State *L) {
- return pairsmeta(L, "__pairs", 0, luaB_next);
-}
-
-
-/*
-** Traversal function for 'ipairs' for raw tables
-*/
-static int ipairsaux_raw (lua_State *L) {
- lua_Integer i = luaL_checkinteger(L, 2) + 1;
- luaL_checktype(L, 1, LUA_TTABLE);
- lua_pushinteger(L, i);
- return (lua_rawgeti(L, 1, i) == LUA_TNIL) ? 1 : 2;
-}
-
-
-/*
-** Traversal function for 'ipairs' for tables with metamethods
-*/
-static int ipairsaux (lua_State *L) {
- lua_Integer i = luaL_checkinteger(L, 2) + 1;
- lua_pushinteger(L, i);
- return (lua_geti(L, 1, i) == LUA_TNIL) ? 1 : 2;
-}
-
-
-/*
-** This function will use either 'ipairsaux' or 'ipairsaux_raw' to
-** traverse a table, depending on whether the table has metamethods
-** that can affect the traversal.
-*/
-static int luaB_ipairs (lua_State *L) {
- lua_CFunction iter = (luaL_getmetafield(L, 1, "__index") != LUA_TNIL)
- ? ipairsaux : ipairsaux_raw;
-#if defined(LUA_COMPAT_IPAIRS)
- return pairsmeta(L, "__ipairs", 1, iter);
-#else
- luaL_checkany(L, 1);
- lua_pushcfunction(L, iter); /* iteration function */
- lua_pushvalue(L, 1); /* state */
- lua_pushinteger(L, 0); /* initial value */
- return 3;
-#endif
-}
-
-
-static int load_aux (lua_State *L, int status, int envidx) {
- if (status == LUA_OK) {
- if (envidx != 0) { /* 'env' parameter? */
- lua_pushvalue(L, envidx); /* environment for loaded function */
- if (!lua_setupvalue(L, -2, 1)) /* set it as 1st upvalue */
- lua_pop(L, 1); /* remove 'env' if not used by previous call */
- }
- return 1;
- }
- else { /* error (message is on top of the stack) */
- lua_pushnil(L);
- lua_insert(L, -2); /* put before error message */
- return 2; /* return nil plus error message */
- }
-}
-
-
-static int luaB_loadfile (lua_State *L) {
- const char *fname = luaL_optstring(L, 1, NULL);
- const char *mode = luaL_optstring(L, 2, NULL);
- int env = (!lua_isnone(L, 3) ? 3 : 0); /* 'env' index or 0 if no 'env' */
- int status = luaL_loadfilex(L, fname, mode);
- return load_aux(L, status, env);
-}
-
-
-/*
-** {======================================================
-** Generic Read function
-** =======================================================
-*/
-
-
-/*
-** reserved slot, above all arguments, to hold a copy of the returned
-** string to avoid it being collected while parsed. 'load' has four
-** optional arguments (chunk, source name, mode, and environment).
-*/
-#define RESERVEDSLOT 5
-
-
-/*
-** Reader for generic 'load' function: 'lua_load' uses the
-** stack for internal stuff, so the reader cannot change the
-** stack top. Instead, it keeps its resulting string in a
-** reserved slot inside the stack.
-*/
-static const char *generic_reader (lua_State *L, void *ud, size_t *size) {
- (void)(ud); /* not used */
- luaL_checkstack(L, 2, "too many nested functions");
- lua_pushvalue(L, 1); /* get function */
- lua_call(L, 0, 1); /* call it */
- if (lua_isnil(L, -1)) {
- lua_pop(L, 1); /* pop result */
- *size = 0;
- return NULL;
- }
- else if (!lua_isstring(L, -1))
- luaL_error(L, "reader function must return a string");
- lua_replace(L, RESERVEDSLOT); /* save string in reserved slot */
- return lua_tolstring(L, RESERVEDSLOT, size);
-}
-
-
-static int luaB_load (lua_State *L) {
- int status;
- size_t l;
- const char *s = lua_tolstring(L, 1, &l);
- const char *mode = luaL_optstring(L, 3, "bt");
- int env = (!lua_isnone(L, 4) ? 4 : 0); /* 'env' index or 0 if no 'env' */
- if (s != NULL) { /* loading a string? */
- const char *chunkname = luaL_optstring(L, 2, s);
- status = luaL_loadbufferx(L, s, l, chunkname, mode);
- }
- else { /* loading from a reader function */
- const char *chunkname = luaL_optstring(L, 2, "=(load)");
- luaL_checktype(L, 1, LUA_TFUNCTION);
- lua_settop(L, RESERVEDSLOT); /* create reserved slot */
- status = lua_load(L, generic_reader, NULL, chunkname, mode);
- }
- return load_aux(L, status, env);
-}
-
-/* }====================================================== */
-
-
-static int dofilecont (lua_State *L, int d1, lua_KContext d2) {
- (void)d1; (void)d2; /* only to match 'lua_Kfunction' prototype */
- return lua_gettop(L) - 1;
-}
-
-
-static int luaB_dofile (lua_State *L) {
- const char *fname = luaL_optstring(L, 1, NULL);
- lua_settop(L, 1);
- if (luaL_loadfile(L, fname) != LUA_OK)
- return lua_error(L);
- lua_callk(L, 0, LUA_MULTRET, 0, dofilecont);
- return dofilecont(L, 0, 0);
-}
-
-
-static int luaB_assert (lua_State *L) {
- if (lua_toboolean(L, 1)) /* condition is true? */
- return lua_gettop(L); /* return all arguments */
- else { /* error */
- luaL_checkany(L, 1); /* there must be a condition */
- lua_remove(L, 1); /* remove it */
- lua_pushliteral(L, "assertion failed!"); /* default message */
- lua_settop(L, 1); /* leave only message (default if no other one) */
- return luaB_error(L); /* call 'error' */
- }
-}
-
-
-static int luaB_select (lua_State *L) {
- int n = lua_gettop(L);
- if (lua_type(L, 1) == LUA_TSTRING && *lua_tostring(L, 1) == '#') {
- lua_pushinteger(L, n-1);
- return 1;
- }
- else {
- lua_Integer i = luaL_checkinteger(L, 1);
- if (i < 0) i = n + i;
- else if (i > n) i = n;
- luaL_argcheck(L, 1 <= i, 1, "index out of range");
- return n - (int)i;
- }
-}
-
-
-/*
-** Continuation function for 'pcall' and 'xpcall'. Both functions
-** already pushed a 'true' before doing the call, so in case of success
-** 'finishpcall' only has to return everything in the stack minus
-** 'extra' values (where 'extra' is exactly the number of items to be
-** ignored).
-*/
-static int finishpcall (lua_State *L, int status, lua_KContext extra) {
- if (status != LUA_OK && status != LUA_YIELD) { /* error? */
- lua_pushboolean(L, 0); /* first result (false) */
- lua_pushvalue(L, -2); /* error message */
- return 2; /* return false, msg */
- }
- else
- return lua_gettop(L) - (int)extra; /* return all results */
-}
-
-
-static int luaB_pcall (lua_State *L) {
- int status;
- luaL_checkany(L, 1);
- lua_pushboolean(L, 1); /* first result if no errors */
- lua_insert(L, 1); /* put it in place */
- status = lua_pcallk(L, lua_gettop(L) - 2, LUA_MULTRET, 0, 0, finishpcall);
- return finishpcall(L, status, 0);
-}
-
-
-/*
-** Do a protected call with error handling. After 'lua_rotate', the
-** stack will have ; so, the function passes
-** 2 to 'finishpcall' to skip the 2 first values when returning results.
-*/
-static int luaB_xpcall (lua_State *L) {
- int status;
- int n = lua_gettop(L);
- luaL_checktype(L, 2, LUA_TFUNCTION); /* check error function */
- lua_pushboolean(L, 1); /* first result */
- lua_pushvalue(L, 1); /* function */
- lua_rotate(L, 3, 2); /* move them below function's arguments */
- status = lua_pcallk(L, n - 2, LUA_MULTRET, 2, 2, finishpcall);
- return finishpcall(L, status, 2);
-}
-
-
-static int luaB_tostring (lua_State *L) {
- luaL_checkany(L, 1);
- luaL_tolstring(L, 1, NULL);
- return 1;
-}
-
-
-static const luaL_Reg base_funcs[] = {
- {"assert", luaB_assert},
- {"collectgarbage", luaB_collectgarbage},
- {"dofile", luaB_dofile},
- {"error", luaB_error},
- {"getmetatable", luaB_getmetatable},
- {"ipairs", luaB_ipairs},
- {"loadfile", luaB_loadfile},
- {"load", luaB_load},
-#if defined(LUA_COMPAT_LOADSTRING)
- {"loadstring", luaB_load},
-#endif
- {"next", luaB_next},
- {"pairs", luaB_pairs},
- {"pcall", luaB_pcall},
- {"print", luaB_print},
- {"rawequal", luaB_rawequal},
- {"rawlen", luaB_rawlen},
- {"rawget", luaB_rawget},
- {"rawset", luaB_rawset},
- {"select", luaB_select},
- {"setmetatable", luaB_setmetatable},
- {"tonumber", luaB_tonumber},
- {"tostring", luaB_tostring},
- {"xpcall", luaB_xpcall},
- /* placeholders */
- {"type", NULL},
- {"_G", NULL},
- {"_VERSION", NULL},
- {NULL, NULL}
-};
-
-
-LUAMOD_API int luaopen_base (lua_State *L) {
- int i;
- /* open lib into global table */
- lua_pushglobaltable(L);
- luaL_setfuncs(L, base_funcs, 0);
- /* set global _G */
- lua_pushvalue(L, -1);
- lua_setfield(L, -2, "_G");
- /* set global _VERSION */
- lua_pushliteral(L, LUA_VERSION);
- lua_setfield(L, -2, "_VERSION");
- /* set function 'type' with proper upvalues */
- for (i = 0; i < LUA_NUMTAGS; i++) /* push all type names as upvalues */
- lua_pushstring(L, lua_typename(L, i));
- lua_pushcclosure(L, luaB_type, LUA_NUMTAGS);
- lua_setfield(L, -2, "type");
- return 1;
-}
-
diff --git a/3rd/lua/src/lbitlib.c b/3rd/lua/src/lbitlib.c
deleted file mode 100644
index 15d5f0c..0000000
--- a/3rd/lua/src/lbitlib.c
+++ /dev/null
@@ -1,230 +0,0 @@
-/*
-** $Id: lbitlib.c,v 1.28 2014/11/02 19:19:04 roberto Exp $
-** Standard library for bitwise operations
-** See Copyright Notice in lua.h
-*/
-
-#define lbitlib_c
-#define LUA_LIB
-
-#include "lprefix.h"
-
-
-#include "lua.h"
-
-#include "lauxlib.h"
-#include "lualib.h"
-
-
-#if defined(LUA_COMPAT_BITLIB) /* { */
-
-
-/* number of bits to consider in a number */
-#if !defined(LUA_NBITS)
-#define LUA_NBITS 32
-#endif
-
-
-/*
-** a lua_Unsigned with its first LUA_NBITS bits equal to 1. (Shift must
-** be made in two parts to avoid problems when LUA_NBITS is equal to the
-** number of bits in a lua_Unsigned.)
-*/
-#define ALLONES (~(((~(lua_Unsigned)0) << (LUA_NBITS - 1)) << 1))
-
-
-/* macro to trim extra bits */
-#define trim(x) ((x) & ALLONES)
-
-
-/* builds a number with 'n' ones (1 <= n <= LUA_NBITS) */
-#define mask(n) (~((ALLONES << 1) << ((n) - 1)))
-
-
-
-static lua_Unsigned andaux (lua_State *L) {
- int i, n = lua_gettop(L);
- lua_Unsigned r = ~(lua_Unsigned)0;
- for (i = 1; i <= n; i++)
- r &= luaL_checkunsigned(L, i);
- return trim(r);
-}
-
-
-static int b_and (lua_State *L) {
- lua_Unsigned r = andaux(L);
- lua_pushunsigned(L, r);
- return 1;
-}
-
-
-static int b_test (lua_State *L) {
- lua_Unsigned r = andaux(L);
- lua_pushboolean(L, r != 0);
- return 1;
-}
-
-
-static int b_or (lua_State *L) {
- int i, n = lua_gettop(L);
- lua_Unsigned r = 0;
- for (i = 1; i <= n; i++)
- r |= luaL_checkunsigned(L, i);
- lua_pushunsigned(L, trim(r));
- return 1;
-}
-
-
-static int b_xor (lua_State *L) {
- int i, n = lua_gettop(L);
- lua_Unsigned r = 0;
- for (i = 1; i <= n; i++)
- r ^= luaL_checkunsigned(L, i);
- lua_pushunsigned(L, trim(r));
- return 1;
-}
-
-
-static int b_not (lua_State *L) {
- lua_Unsigned r = ~luaL_checkunsigned(L, 1);
- lua_pushunsigned(L, trim(r));
- return 1;
-}
-
-
-static int b_shift (lua_State *L, lua_Unsigned r, lua_Integer i) {
- if (i < 0) { /* shift right? */
- i = -i;
- r = trim(r);
- if (i >= LUA_NBITS) r = 0;
- else r >>= i;
- }
- else { /* shift left */
- if (i >= LUA_NBITS) r = 0;
- else r <<= i;
- r = trim(r);
- }
- lua_pushunsigned(L, r);
- return 1;
-}
-
-
-static int b_lshift (lua_State *L) {
- return b_shift(L, luaL_checkunsigned(L, 1), luaL_checkinteger(L, 2));
-}
-
-
-static int b_rshift (lua_State *L) {
- return b_shift(L, luaL_checkunsigned(L, 1), -luaL_checkinteger(L, 2));
-}
-
-
-static int b_arshift (lua_State *L) {
- lua_Unsigned r = luaL_checkunsigned(L, 1);
- lua_Integer i = luaL_checkinteger(L, 2);
- if (i < 0 || !(r & ((lua_Unsigned)1 << (LUA_NBITS - 1))))
- return b_shift(L, r, -i);
- else { /* arithmetic shift for 'negative' number */
- if (i >= LUA_NBITS) r = ALLONES;
- else
- r = trim((r >> i) | ~(trim(~(lua_Unsigned)0) >> i)); /* add signal bit */
- lua_pushunsigned(L, r);
- return 1;
- }
-}
-
-
-static int b_rot (lua_State *L, lua_Integer d) {
- lua_Unsigned r = luaL_checkunsigned(L, 1);
- int i = d & (LUA_NBITS - 1); /* i = d % NBITS */
- r = trim(r);
- if (i != 0) /* avoid undefined shift of LUA_NBITS when i == 0 */
- r = (r << i) | (r >> (LUA_NBITS - i));
- lua_pushunsigned(L, trim(r));
- return 1;
-}
-
-
-static int b_lrot (lua_State *L) {
- return b_rot(L, luaL_checkinteger(L, 2));
-}
-
-
-static int b_rrot (lua_State *L) {
- return b_rot(L, -luaL_checkinteger(L, 2));
-}
-
-
-/*
-** get field and width arguments for field-manipulation functions,
-** checking whether they are valid.
-** ('luaL_error' called without 'return' to avoid later warnings about
-** 'width' being used uninitialized.)
-*/
-static int fieldargs (lua_State *L, int farg, int *width) {
- lua_Integer f = luaL_checkinteger(L, farg);
- lua_Integer w = luaL_optinteger(L, farg + 1, 1);
- luaL_argcheck(L, 0 <= f, farg, "field cannot be negative");
- luaL_argcheck(L, 0 < w, farg + 1, "width must be positive");
- if (f + w > LUA_NBITS)
- luaL_error(L, "trying to access non-existent bits");
- *width = (int)w;
- return (int)f;
-}
-
-
-static int b_extract (lua_State *L) {
- int w;
- lua_Unsigned r = trim(luaL_checkunsigned(L, 1));
- int f = fieldargs(L, 2, &w);
- r = (r >> f) & mask(w);
- lua_pushunsigned(L, r);
- return 1;
-}
-
-
-static int b_replace (lua_State *L) {
- int w;
- lua_Unsigned r = trim(luaL_checkunsigned(L, 1));
- lua_Unsigned v = luaL_checkunsigned(L, 2);
- int f = fieldargs(L, 3, &w);
- int m = mask(w);
- v &= m; /* erase bits outside given width */
- r = (r & ~(m << f)) | (v << f);
- lua_pushunsigned(L, r);
- return 1;
-}
-
-
-static const luaL_Reg bitlib[] = {
- {"arshift", b_arshift},
- {"band", b_and},
- {"bnot", b_not},
- {"bor", b_or},
- {"bxor", b_xor},
- {"btest", b_test},
- {"extract", b_extract},
- {"lrotate", b_lrot},
- {"lshift", b_lshift},
- {"replace", b_replace},
- {"rrotate", b_rrot},
- {"rshift", b_rshift},
- {NULL, NULL}
-};
-
-
-
-LUAMOD_API int luaopen_bit32 (lua_State *L) {
- luaL_newlib(L, bitlib);
- return 1;
-}
-
-
-#else /* }{ */
-
-
-LUAMOD_API int luaopen_bit32 (lua_State *L) {
- return luaL_error(L, "library 'bit32' has been deprecated");
-}
-
-#endif /* } */
diff --git a/3rd/lua/src/lcode.c b/3rd/lua/src/lcode.c
deleted file mode 100644
index 5e34624..0000000
--- a/3rd/lua/src/lcode.c
+++ /dev/null
@@ -1,954 +0,0 @@
-/*
-** $Id: lcode.c,v 2.99 2014/12/29 16:49:25 roberto Exp $
-** Code generator for Lua
-** See Copyright Notice in lua.h
-*/
-
-#define lcode_c
-#define LUA_CORE
-
-#include "lprefix.h"
-
-
-#include
-#include
-
-#include "lua.h"
-
-#include "lcode.h"
-#include "ldebug.h"
-#include "ldo.h"
-#include "lgc.h"
-#include "llex.h"
-#include "lmem.h"
-#include "lobject.h"
-#include "lopcodes.h"
-#include "lparser.h"
-#include "lstring.h"
-#include "ltable.h"
-#include "lvm.h"
-
-
-/* Maximum number of registers in a Lua function */
-#define MAXREGS 250
-
-
-#define hasjumps(e) ((e)->t != (e)->f)
-
-
-static int tonumeral(expdesc *e, TValue *v) {
- if (e->t != NO_JUMP || e->f != NO_JUMP)
- return 0; /* not a numeral */
- switch (e->k) {
- case VKINT:
- if (v) setivalue(v, e->u.ival);
- return 1;
- case VKFLT:
- if (v) setfltvalue(v, e->u.nval);
- return 1;
- default: return 0;
- }
-}
-
-
-void luaK_nil (FuncState *fs, int from, int n) {
- Instruction *previous;
- int l = from + n - 1; /* last register to set nil */
- if (fs->pc > fs->lasttarget) { /* no jumps to current position? */
- previous = &fs->f->code[fs->pc-1];
- if (GET_OPCODE(*previous) == OP_LOADNIL) {
- int pfrom = GETARG_A(*previous);
- int pl = pfrom + GETARG_B(*previous);
- if ((pfrom <= from && from <= pl + 1) ||
- (from <= pfrom && pfrom <= l + 1)) { /* can connect both? */
- if (pfrom < from) from = pfrom; /* from = min(from, pfrom) */
- if (pl > l) l = pl; /* l = max(l, pl) */
- SETARG_A(*previous, from);
- SETARG_B(*previous, l - from);
- return;
- }
- } /* else go through */
- }
- luaK_codeABC(fs, OP_LOADNIL, from, n - 1, 0); /* else no optimization */
-}
-
-
-int luaK_jump (FuncState *fs) {
- int jpc = fs->jpc; /* save list of jumps to here */
- int j;
- fs->jpc = NO_JUMP;
- j = luaK_codeAsBx(fs, OP_JMP, 0, NO_JUMP);
- luaK_concat(fs, &j, jpc); /* keep them on hold */
- return j;
-}
-
-
-void luaK_ret (FuncState *fs, int first, int nret) {
- luaK_codeABC(fs, OP_RETURN, first, nret+1, 0);
-}
-
-
-static int condjump (FuncState *fs, OpCode op, int A, int B, int C) {
- luaK_codeABC(fs, op, A, B, C);
- return luaK_jump(fs);
-}
-
-
-static void fixjump (FuncState *fs, int pc, int dest) {
- Instruction *jmp = &fs->f->code[pc];
- int offset = dest-(pc+1);
- lua_assert(dest != NO_JUMP);
- if (abs(offset) > MAXARG_sBx)
- luaX_syntaxerror(fs->ls, "control structure too long");
- SETARG_sBx(*jmp, offset);
-}
-
-
-/*
-** returns current 'pc' and marks it as a jump target (to avoid wrong
-** optimizations with consecutive instructions not in the same basic block).
-*/
-int luaK_getlabel (FuncState *fs) {
- fs->lasttarget = fs->pc;
- return fs->pc;
-}
-
-
-static int getjump (FuncState *fs, int pc) {
- int offset = GETARG_sBx(fs->f->code[pc]);
- if (offset == NO_JUMP) /* point to itself represents end of list */
- return NO_JUMP; /* end of list */
- else
- return (pc+1)+offset; /* turn offset into absolute position */
-}
-
-
-static Instruction *getjumpcontrol (FuncState *fs, int pc) {
- Instruction *pi = &fs->f->code[pc];
- if (pc >= 1 && testTMode(GET_OPCODE(*(pi-1))))
- return pi-1;
- else
- return pi;
-}
-
-
-/*
-** check whether list has any jump that do not produce a value
-** (or produce an inverted value)
-*/
-static int need_value (FuncState *fs, int list) {
- for (; list != NO_JUMP; list = getjump(fs, list)) {
- Instruction i = *getjumpcontrol(fs, list);
- if (GET_OPCODE(i) != OP_TESTSET) return 1;
- }
- return 0; /* not found */
-}
-
-
-static int patchtestreg (FuncState *fs, int node, int reg) {
- Instruction *i = getjumpcontrol(fs, node);
- if (GET_OPCODE(*i) != OP_TESTSET)
- return 0; /* cannot patch other instructions */
- if (reg != NO_REG && reg != GETARG_B(*i))
- SETARG_A(*i, reg);
- else /* no register to put value or register already has the value */
- *i = CREATE_ABC(OP_TEST, GETARG_B(*i), 0, GETARG_C(*i));
-
- return 1;
-}
-
-
-static void removevalues (FuncState *fs, int list) {
- for (; list != NO_JUMP; list = getjump(fs, list))
- patchtestreg(fs, list, NO_REG);
-}
-
-
-static void patchlistaux (FuncState *fs, int list, int vtarget, int reg,
- int dtarget) {
- while (list != NO_JUMP) {
- int next = getjump(fs, list);
- if (patchtestreg(fs, list, reg))
- fixjump(fs, list, vtarget);
- else
- fixjump(fs, list, dtarget); /* jump to default target */
- list = next;
- }
-}
-
-
-static void dischargejpc (FuncState *fs) {
- patchlistaux(fs, fs->jpc, fs->pc, NO_REG, fs->pc);
- fs->jpc = NO_JUMP;
-}
-
-
-void luaK_patchlist (FuncState *fs, int list, int target) {
- if (target == fs->pc)
- luaK_patchtohere(fs, list);
- else {
- lua_assert(target < fs->pc);
- patchlistaux(fs, list, target, NO_REG, target);
- }
-}
-
-
-void luaK_patchclose (FuncState *fs, int list, int level) {
- level++; /* argument is +1 to reserve 0 as non-op */
- while (list != NO_JUMP) {
- int next = getjump(fs, list);
- lua_assert(GET_OPCODE(fs->f->code[list]) == OP_JMP &&
- (GETARG_A(fs->f->code[list]) == 0 ||
- GETARG_A(fs->f->code[list]) >= level));
- SETARG_A(fs->f->code[list], level);
- list = next;
- }
-}
-
-
-void luaK_patchtohere (FuncState *fs, int list) {
- luaK_getlabel(fs);
- luaK_concat(fs, &fs->jpc, list);
-}
-
-
-void luaK_concat (FuncState *fs, int *l1, int l2) {
- if (l2 == NO_JUMP) return;
- else if (*l1 == NO_JUMP)
- *l1 = l2;
- else {
- int list = *l1;
- int next;
- while ((next = getjump(fs, list)) != NO_JUMP) /* find last element */
- list = next;
- fixjump(fs, list, l2);
- }
-}
-
-
-static int luaK_code (FuncState *fs, Instruction i) {
- Proto *f = fs->f;
- dischargejpc(fs); /* 'pc' will change */
- /* put new instruction in code array */
- luaM_growvector(fs->ls->L, f->code, fs->pc, f->sizecode, Instruction,
- MAX_INT, "opcodes");
- f->code[fs->pc] = i;
- /* save corresponding line information */
- luaM_growvector(fs->ls->L, f->lineinfo, fs->pc, f->sizelineinfo, int,
- MAX_INT, "opcodes");
- f->lineinfo[fs->pc] = fs->ls->lastline;
- return fs->pc++;
-}
-
-
-int luaK_codeABC (FuncState *fs, OpCode o, int a, int b, int c) {
- lua_assert(getOpMode(o) == iABC);
- lua_assert(getBMode(o) != OpArgN || b == 0);
- lua_assert(getCMode(o) != OpArgN || c == 0);
- lua_assert(a <= MAXARG_A && b <= MAXARG_B && c <= MAXARG_C);
- return luaK_code(fs, CREATE_ABC(o, a, b, c));
-}
-
-
-int luaK_codeABx (FuncState *fs, OpCode o, int a, unsigned int bc) {
- lua_assert(getOpMode(o) == iABx || getOpMode(o) == iAsBx);
- lua_assert(getCMode(o) == OpArgN);
- lua_assert(a <= MAXARG_A && bc <= MAXARG_Bx);
- return luaK_code(fs, CREATE_ABx(o, a, bc));
-}
-
-
-static int codeextraarg (FuncState *fs, int a) {
- lua_assert(a <= MAXARG_Ax);
- return luaK_code(fs, CREATE_Ax(OP_EXTRAARG, a));
-}
-
-
-int luaK_codek (FuncState *fs, int reg, int k) {
- if (k <= MAXARG_Bx)
- return luaK_codeABx(fs, OP_LOADK, reg, k);
- else {
- int p = luaK_codeABx(fs, OP_LOADKX, reg, 0);
- codeextraarg(fs, k);
- return p;
- }
-}
-
-
-void luaK_checkstack (FuncState *fs, int n) {
- int newstack = fs->freereg + n;
- if (newstack > fs->f->maxstacksize) {
- if (newstack >= MAXREGS)
- luaX_syntaxerror(fs->ls, "function or expression too complex");
- fs->f->maxstacksize = cast_byte(newstack);
- }
-}
-
-
-void luaK_reserveregs (FuncState *fs, int n) {
- luaK_checkstack(fs, n);
- fs->freereg += n;
-}
-
-
-static void freereg (FuncState *fs, int reg) {
- if (!ISK(reg) && reg >= fs->nactvar) {
- fs->freereg--;
- lua_assert(reg == fs->freereg);
- }
-}
-
-
-static void freeexp (FuncState *fs, expdesc *e) {
- if (e->k == VNONRELOC)
- freereg(fs, e->u.info);
-}
-
-
-/*
-** Use scanner's table to cache position of constants in constant list
-** and try to reuse constants
-*/
-static int addk (FuncState *fs, TValue *key, TValue *v) {
- lua_State *L = fs->ls->L;
- Proto *f = fs->f;
- TValue *idx = luaH_set(L, fs->ls->h, key); /* index scanner table */
- int k, oldsize;
- if (ttisinteger(idx)) { /* is there an index there? */
- k = cast_int(ivalue(idx));
- /* correct value? (warning: must distinguish floats from integers!) */
- if (k < fs->nk && ttype(&f->k[k]) == ttype(v) &&
- luaV_rawequalobj(&f->k[k], v))
- return k; /* reuse index */
- }
- /* constant not found; create a new entry */
- oldsize = f->sizek;
- k = fs->nk;
- /* numerical value does not need GC barrier;
- table has no metatable, so it does not need to invalidate cache */
- setivalue(idx, k);
- luaM_growvector(L, f->k, k, f->sizek, TValue, MAXARG_Ax, "constants");
- while (oldsize < f->sizek) setnilvalue(&f->k[oldsize++]);
- setobj(L, &f->k[k], v);
- fs->nk++;
- luaC_barrier(L, f, v);
- return k;
-}
-
-
-int luaK_stringK (FuncState *fs, TString *s) {
- TValue o;
- setsvalue(fs->ls->L, &o, s);
- return addk(fs, &o, &o);
-}
-
-
-/*
-** Integers use userdata as keys to avoid collision with floats with same
-** value; conversion to 'void*' used only for hashing, no "precision"
-** problems
-*/
-int luaK_intK (FuncState *fs, lua_Integer n) {
- TValue k, o;
- setpvalue(&k, cast(void*, cast(size_t, n)));
- setivalue(&o, n);
- return addk(fs, &k, &o);
-}
-
-
-static int luaK_numberK (FuncState *fs, lua_Number r) {
- TValue o;
- setfltvalue(&o, r);
- return addk(fs, &o, &o);
-}
-
-
-static int boolK (FuncState *fs, int b) {
- TValue o;
- setbvalue(&o, b);
- return addk(fs, &o, &o);
-}
-
-
-static int nilK (FuncState *fs) {
- TValue k, v;
- setnilvalue(&v);
- /* cannot use nil as key; instead use table itself to represent nil */
- sethvalue(fs->ls->L, &k, fs->ls->h);
- return addk(fs, &k, &v);
-}
-
-
-void luaK_setreturns (FuncState *fs, expdesc *e, int nresults) {
- if (e->k == VCALL) { /* expression is an open function call? */
- SETARG_C(getcode(fs, e), nresults+1);
- }
- else if (e->k == VVARARG) {
- SETARG_B(getcode(fs, e), nresults+1);
- SETARG_A(getcode(fs, e), fs->freereg);
- luaK_reserveregs(fs, 1);
- }
-}
-
-
-void luaK_setoneret (FuncState *fs, expdesc *e) {
- if (e->k == VCALL) { /* expression is an open function call? */
- e->k = VNONRELOC;
- e->u.info = GETARG_A(getcode(fs, e));
- }
- else if (e->k == VVARARG) {
- SETARG_B(getcode(fs, e), 2);
- e->k = VRELOCABLE; /* can relocate its simple result */
- }
-}
-
-
-void luaK_dischargevars (FuncState *fs, expdesc *e) {
- switch (e->k) {
- case VLOCAL: {
- e->k = VNONRELOC;
- break;
- }
- case VUPVAL: {
- e->u.info = luaK_codeABC(fs, OP_GETUPVAL, 0, e->u.info, 0);
- e->k = VRELOCABLE;
- break;
- }
- case VINDEXED: {
- OpCode op = OP_GETTABUP; /* assume 't' is in an upvalue */
- freereg(fs, e->u.ind.idx);
- if (e->u.ind.vt == VLOCAL) { /* 't' is in a register? */
- freereg(fs, e->u.ind.t);
- op = OP_GETTABLE;
- }
- e->u.info = luaK_codeABC(fs, op, 0, e->u.ind.t, e->u.ind.idx);
- e->k = VRELOCABLE;
- break;
- }
- case VVARARG:
- case VCALL: {
- luaK_setoneret(fs, e);
- break;
- }
- default: break; /* there is one value available (somewhere) */
- }
-}
-
-
-static int code_label (FuncState *fs, int A, int b, int jump) {
- luaK_getlabel(fs); /* those instructions may be jump targets */
- return luaK_codeABC(fs, OP_LOADBOOL, A, b, jump);
-}
-
-
-static void discharge2reg (FuncState *fs, expdesc *e, int reg) {
- luaK_dischargevars(fs, e);
- switch (e->k) {
- case VNIL: {
- luaK_nil(fs, reg, 1);
- break;
- }
- case VFALSE: case VTRUE: {
- luaK_codeABC(fs, OP_LOADBOOL, reg, e->k == VTRUE, 0);
- break;
- }
- case VK: {
- luaK_codek(fs, reg, e->u.info);
- break;
- }
- case VKFLT: {
- luaK_codek(fs, reg, luaK_numberK(fs, e->u.nval));
- break;
- }
- case VKINT: {
- luaK_codek(fs, reg, luaK_intK(fs, e->u.ival));
- break;
- }
- case VRELOCABLE: {
- Instruction *pc = &getcode(fs, e);
- SETARG_A(*pc, reg);
- break;
- }
- case VNONRELOC: {
- if (reg != e->u.info)
- luaK_codeABC(fs, OP_MOVE, reg, e->u.info, 0);
- break;
- }
- default: {
- lua_assert(e->k == VVOID || e->k == VJMP);
- return; /* nothing to do... */
- }
- }
- e->u.info = reg;
- e->k = VNONRELOC;
-}
-
-
-static void discharge2anyreg (FuncState *fs, expdesc *e) {
- if (e->k != VNONRELOC) {
- luaK_reserveregs(fs, 1);
- discharge2reg(fs, e, fs->freereg-1);
- }
-}
-
-
-static void exp2reg (FuncState *fs, expdesc *e, int reg) {
- discharge2reg(fs, e, reg);
- if (e->k == VJMP)
- luaK_concat(fs, &e->t, e->u.info); /* put this jump in 't' list */
- if (hasjumps(e)) {
- int final; /* position after whole expression */
- int p_f = NO_JUMP; /* position of an eventual LOAD false */
- int p_t = NO_JUMP; /* position of an eventual LOAD true */
- if (need_value(fs, e->t) || need_value(fs, e->f)) {
- int fj = (e->k == VJMP) ? NO_JUMP : luaK_jump(fs);
- p_f = code_label(fs, reg, 0, 1);
- p_t = code_label(fs, reg, 1, 0);
- luaK_patchtohere(fs, fj);
- }
- final = luaK_getlabel(fs);
- patchlistaux(fs, e->f, final, reg, p_f);
- patchlistaux(fs, e->t, final, reg, p_t);
- }
- e->f = e->t = NO_JUMP;
- e->u.info = reg;
- e->k = VNONRELOC;
-}
-
-
-void luaK_exp2nextreg (FuncState *fs, expdesc *e) {
- luaK_dischargevars(fs, e);
- freeexp(fs, e);
- luaK_reserveregs(fs, 1);
- exp2reg(fs, e, fs->freereg - 1);
-}
-
-
-int luaK_exp2anyreg (FuncState *fs, expdesc *e) {
- luaK_dischargevars(fs, e);
- if (e->k == VNONRELOC) {
- if (!hasjumps(e)) return e->u.info; /* exp is already in a register */
- if (e->u.info >= fs->nactvar) { /* reg. is not a local? */
- exp2reg(fs, e, e->u.info); /* put value on it */
- return e->u.info;
- }
- }
- luaK_exp2nextreg(fs, e); /* default */
- return e->u.info;
-}
-
-
-void luaK_exp2anyregup (FuncState *fs, expdesc *e) {
- if (e->k != VUPVAL || hasjumps(e))
- luaK_exp2anyreg(fs, e);
-}
-
-
-void luaK_exp2val (FuncState *fs, expdesc *e) {
- if (hasjumps(e))
- luaK_exp2anyreg(fs, e);
- else
- luaK_dischargevars(fs, e);
-}
-
-
-int luaK_exp2RK (FuncState *fs, expdesc *e) {
- luaK_exp2val(fs, e);
- switch (e->k) {
- case VTRUE:
- case VFALSE:
- case VNIL: {
- if (fs->nk <= MAXINDEXRK) { /* constant fits in RK operand? */
- e->u.info = (e->k == VNIL) ? nilK(fs) : boolK(fs, (e->k == VTRUE));
- e->k = VK;
- return RKASK(e->u.info);
- }
- else break;
- }
- case VKINT: {
- e->u.info = luaK_intK(fs, e->u.ival);
- e->k = VK;
- goto vk;
- }
- case VKFLT: {
- e->u.info = luaK_numberK(fs, e->u.nval);
- e->k = VK;
- /* go through */
- }
- case VK: {
- vk:
- if (e->u.info <= MAXINDEXRK) /* constant fits in 'argC'? */
- return RKASK(e->u.info);
- else break;
- }
- default: break;
- }
- /* not a constant in the right range: put it in a register */
- return luaK_exp2anyreg(fs, e);
-}
-
-
-void luaK_storevar (FuncState *fs, expdesc *var, expdesc *ex) {
- switch (var->k) {
- case VLOCAL: {
- freeexp(fs, ex);
- exp2reg(fs, ex, var->u.info);
- return;
- }
- case VUPVAL: {
- int e = luaK_exp2anyreg(fs, ex);
- luaK_codeABC(fs, OP_SETUPVAL, e, var->u.info, 0);
- break;
- }
- case VINDEXED: {
- OpCode op = (var->u.ind.vt == VLOCAL) ? OP_SETTABLE : OP_SETTABUP;
- int e = luaK_exp2RK(fs, ex);
- luaK_codeABC(fs, op, var->u.ind.t, var->u.ind.idx, e);
- break;
- }
- default: {
- lua_assert(0); /* invalid var kind to store */
- break;
- }
- }
- freeexp(fs, ex);
-}
-
-
-void luaK_self (FuncState *fs, expdesc *e, expdesc *key) {
- int ereg;
- luaK_exp2anyreg(fs, e);
- ereg = e->u.info; /* register where 'e' was placed */
- freeexp(fs, e);
- e->u.info = fs->freereg; /* base register for op_self */
- e->k = VNONRELOC;
- luaK_reserveregs(fs, 2); /* function and 'self' produced by op_self */
- luaK_codeABC(fs, OP_SELF, e->u.info, ereg, luaK_exp2RK(fs, key));
- freeexp(fs, key);
-}
-
-
-static void invertjump (FuncState *fs, expdesc *e) {
- Instruction *pc = getjumpcontrol(fs, e->u.info);
- lua_assert(testTMode(GET_OPCODE(*pc)) && GET_OPCODE(*pc) != OP_TESTSET &&
- GET_OPCODE(*pc) != OP_TEST);
- SETARG_A(*pc, !(GETARG_A(*pc)));
-}
-
-
-static int jumponcond (FuncState *fs, expdesc *e, int cond) {
- if (e->k == VRELOCABLE) {
- Instruction ie = getcode(fs, e);
- if (GET_OPCODE(ie) == OP_NOT) {
- fs->pc--; /* remove previous OP_NOT */
- return condjump(fs, OP_TEST, GETARG_B(ie), 0, !cond);
- }
- /* else go through */
- }
- discharge2anyreg(fs, e);
- freeexp(fs, e);
- return condjump(fs, OP_TESTSET, NO_REG, e->u.info, cond);
-}
-
-
-void luaK_goiftrue (FuncState *fs, expdesc *e) {
- int pc; /* pc of last jump */
- luaK_dischargevars(fs, e);
- switch (e->k) {
- case VJMP: {
- invertjump(fs, e);
- pc = e->u.info;
- break;
- }
- case VK: case VKFLT: case VKINT: case VTRUE: {
- pc = NO_JUMP; /* always true; do nothing */
- break;
- }
- default: {
- pc = jumponcond(fs, e, 0);
- break;
- }
- }
- luaK_concat(fs, &e->f, pc); /* insert last jump in 'f' list */
- luaK_patchtohere(fs, e->t);
- e->t = NO_JUMP;
-}
-
-
-void luaK_goiffalse (FuncState *fs, expdesc *e) {
- int pc; /* pc of last jump */
- luaK_dischargevars(fs, e);
- switch (e->k) {
- case VJMP: {
- pc = e->u.info;
- break;
- }
- case VNIL: case VFALSE: {
- pc = NO_JUMP; /* always false; do nothing */
- break;
- }
- default: {
- pc = jumponcond(fs, e, 1);
- break;
- }
- }
- luaK_concat(fs, &e->t, pc); /* insert last jump in 't' list */
- luaK_patchtohere(fs, e->f);
- e->f = NO_JUMP;
-}
-
-
-static void codenot (FuncState *fs, expdesc *e) {
- luaK_dischargevars(fs, e);
- switch (e->k) {
- case VNIL: case VFALSE: {
- e->k = VTRUE;
- break;
- }
- case VK: case VKFLT: case VKINT: case VTRUE: {
- e->k = VFALSE;
- break;
- }
- case VJMP: {
- invertjump(fs, e);
- break;
- }
- case VRELOCABLE:
- case VNONRELOC: {
- discharge2anyreg(fs, e);
- freeexp(fs, e);
- e->u.info = luaK_codeABC(fs, OP_NOT, 0, e->u.info, 0);
- e->k = VRELOCABLE;
- break;
- }
- default: {
- lua_assert(0); /* cannot happen */
- break;
- }
- }
- /* interchange true and false lists */
- { int temp = e->f; e->f = e->t; e->t = temp; }
- removevalues(fs, e->f);
- removevalues(fs, e->t);
-}
-
-
-void luaK_indexed (FuncState *fs, expdesc *t, expdesc *k) {
- lua_assert(!hasjumps(t));
- t->u.ind.t = t->u.info;
- t->u.ind.idx = luaK_exp2RK(fs, k);
- t->u.ind.vt = (t->k == VUPVAL) ? VUPVAL
- : check_exp(vkisinreg(t->k), VLOCAL);
- t->k = VINDEXED;
-}
-
-
-/*
-** return false if folding can raise an error
-*/
-static int validop (int op, TValue *v1, TValue *v2) {
- switch (op) {
- case LUA_OPBAND: case LUA_OPBOR: case LUA_OPBXOR:
- case LUA_OPSHL: case LUA_OPSHR: case LUA_OPBNOT: { /* conversion errors */
- lua_Integer i;
- return (tointeger(v1, &i) && tointeger(v2, &i));
- }
- case LUA_OPDIV: case LUA_OPIDIV: case LUA_OPMOD: /* division by 0 */
- return (nvalue(v2) != 0);
- default: return 1; /* everything else is valid */
- }
-}
-
-
-/*
-** Try to "constant-fold" an operation; return 1 iff successful
-*/
-static int constfolding (FuncState *fs, int op, expdesc *e1, expdesc *e2) {
- TValue v1, v2, res;
- if (!tonumeral(e1, &v1) || !tonumeral(e2, &v2) || !validop(op, &v1, &v2))
- return 0; /* non-numeric operands or not safe to fold */
- luaO_arith(fs->ls->L, op, &v1, &v2, &res); /* does operation */
- if (ttisinteger(&res)) {
- e1->k = VKINT;
- e1->u.ival = ivalue(&res);
- }
- else { /* folds neither NaN nor 0.0 (to avoid collapsing with -0.0) */
- lua_Number n = fltvalue(&res);
- if (luai_numisnan(n) || n == 0)
- return 0;
- e1->k = VKFLT;
- e1->u.nval = n;
- }
- return 1;
-}
-
-
-/*
-** Code for binary and unary expressions that "produce values"
-** (arithmetic operations, bitwise operations, concat, length). First
-** try to do constant folding (only for numeric [arithmetic and
-** bitwise] operations, which is what 'lua_arith' accepts).
-** Expression to produce final result will be encoded in 'e1'.
-*/
-static void codeexpval (FuncState *fs, OpCode op,
- expdesc *e1, expdesc *e2, int line) {
- lua_assert(op >= OP_ADD);
- if (op <= OP_BNOT && constfolding(fs, op - OP_ADD + LUA_OPADD, e1, e2))
- return; /* result has been folded */
- else {
- int o1, o2;
- /* move operands to registers (if needed) */
- if (op == OP_UNM || op == OP_BNOT || op == OP_LEN) { /* unary op? */
- o2 = 0; /* no second expression */
- o1 = luaK_exp2anyreg(fs, e1); /* cannot operate on constants */
- }
- else { /* regular case (binary operators) */
- o2 = luaK_exp2RK(fs, e2); /* both operands are "RK" */
- o1 = luaK_exp2RK(fs, e1);
- }
- if (o1 > o2) { /* free registers in proper order */
- freeexp(fs, e1);
- freeexp(fs, e2);
- }
- else {
- freeexp(fs, e2);
- freeexp(fs, e1);
- }
- e1->u.info = luaK_codeABC(fs, op, 0, o1, o2); /* generate opcode */
- e1->k = VRELOCABLE; /* all those operations are relocable */
- luaK_fixline(fs, line);
- }
-}
-
-
-static void codecomp (FuncState *fs, OpCode op, int cond, expdesc *e1,
- expdesc *e2) {
- int o1 = luaK_exp2RK(fs, e1);
- int o2 = luaK_exp2RK(fs, e2);
- freeexp(fs, e2);
- freeexp(fs, e1);
- if (cond == 0 && op != OP_EQ) {
- int temp; /* exchange args to replace by '<' or '<=' */
- temp = o1; o1 = o2; o2 = temp; /* o1 <==> o2 */
- cond = 1;
- }
- e1->u.info = condjump(fs, op, cond, o1, o2);
- e1->k = VJMP;
-}
-
-
-void luaK_prefix (FuncState *fs, UnOpr op, expdesc *e, int line) {
- expdesc e2;
- e2.t = e2.f = NO_JUMP; e2.k = VKINT; e2.u.ival = 0;
- switch (op) {
- case OPR_MINUS: case OPR_BNOT: case OPR_LEN: {
- codeexpval(fs, cast(OpCode, (op - OPR_MINUS) + OP_UNM), e, &e2, line);
- break;
- }
- case OPR_NOT: codenot(fs, e); break;
- default: lua_assert(0);
- }
-}
-
-
-void luaK_infix (FuncState *fs, BinOpr op, expdesc *v) {
- switch (op) {
- case OPR_AND: {
- luaK_goiftrue(fs, v);
- break;
- }
- case OPR_OR: {
- luaK_goiffalse(fs, v);
- break;
- }
- case OPR_CONCAT: {
- luaK_exp2nextreg(fs, v); /* operand must be on the 'stack' */
- break;
- }
- case OPR_ADD: case OPR_SUB:
- case OPR_MUL: case OPR_DIV: case OPR_IDIV:
- case OPR_MOD: case OPR_POW:
- case OPR_BAND: case OPR_BOR: case OPR_BXOR:
- case OPR_SHL: case OPR_SHR: {
- if (!tonumeral(v, NULL)) luaK_exp2RK(fs, v);
- break;
- }
- default: {
- luaK_exp2RK(fs, v);
- break;
- }
- }
-}
-
-
-void luaK_posfix (FuncState *fs, BinOpr op,
- expdesc *e1, expdesc *e2, int line) {
- switch (op) {
- case OPR_AND: {
- lua_assert(e1->t == NO_JUMP); /* list must be closed */
- luaK_dischargevars(fs, e2);
- luaK_concat(fs, &e2->f, e1->f);
- *e1 = *e2;
- break;
- }
- case OPR_OR: {
- lua_assert(e1->f == NO_JUMP); /* list must be closed */
- luaK_dischargevars(fs, e2);
- luaK_concat(fs, &e2->t, e1->t);
- *e1 = *e2;
- break;
- }
- case OPR_CONCAT: {
- luaK_exp2val(fs, e2);
- if (e2->k == VRELOCABLE && GET_OPCODE(getcode(fs, e2)) == OP_CONCAT) {
- lua_assert(e1->u.info == GETARG_B(getcode(fs, e2))-1);
- freeexp(fs, e1);
- SETARG_B(getcode(fs, e2), e1->u.info);
- e1->k = VRELOCABLE; e1->u.info = e2->u.info;
- }
- else {
- luaK_exp2nextreg(fs, e2); /* operand must be on the 'stack' */
- codeexpval(fs, OP_CONCAT, e1, e2, line);
- }
- break;
- }
- case OPR_ADD: case OPR_SUB: case OPR_MUL: case OPR_DIV:
- case OPR_IDIV: case OPR_MOD: case OPR_POW:
- case OPR_BAND: case OPR_BOR: case OPR_BXOR:
- case OPR_SHL: case OPR_SHR: {
- codeexpval(fs, cast(OpCode, (op - OPR_ADD) + OP_ADD), e1, e2, line);
- break;
- }
- case OPR_EQ: case OPR_LT: case OPR_LE: {
- codecomp(fs, cast(OpCode, op - OPR_EQ + OP_EQ), 1, e1, e2);
- break;
- }
- case OPR_NE: case OPR_GT: case OPR_GE: {
- codecomp(fs, cast(OpCode, op - OPR_NE + OP_EQ), 0, e1, e2);
- break;
- }
- default: lua_assert(0);
- }
-}
-
-
-void luaK_fixline (FuncState *fs, int line) {
- fs->f->lineinfo[fs->pc - 1] = line;
-}
-
-
-void luaK_setlist (FuncState *fs, int base, int nelems, int tostore) {
- int c = (nelems - 1)/LFIELDS_PER_FLUSH + 1;
- int b = (tostore == LUA_MULTRET) ? 0 : tostore;
- lua_assert(tostore != 0);
- if (c <= MAXARG_C)
- luaK_codeABC(fs, OP_SETLIST, base, b, c);
- else if (c <= MAXARG_Ax) {
- luaK_codeABC(fs, OP_SETLIST, base, b, 0);
- codeextraarg(fs, c);
- }
- else
- luaX_syntaxerror(fs->ls, "constructor too long");
- fs->freereg = base + 1; /* free registers with list values */
-}
-
diff --git a/3rd/lua/src/lcode.h b/3rd/lua/src/lcode.h
deleted file mode 100644
index 43ab86d..0000000
--- a/3rd/lua/src/lcode.h
+++ /dev/null
@@ -1,87 +0,0 @@
-/*
-** $Id: lcode.h,v 1.63 2013/12/30 20:47:58 roberto Exp $
-** Code generator for Lua
-** See Copyright Notice in lua.h
-*/
-
-#ifndef lcode_h
-#define lcode_h
-
-#include "llex.h"
-#include "lobject.h"
-#include "lopcodes.h"
-#include "lparser.h"
-
-
-/*
-** Marks the end of a patch list. It is an invalid value both as an absolute
-** address, and as a list link (would link an element to itself).
-*/
-#define NO_JUMP (-1)
-
-
-/*
-** grep "ORDER OPR" if you change these enums (ORDER OP)
-*/
-typedef enum BinOpr {
- OPR_ADD, OPR_SUB, OPR_MUL, OPR_MOD, OPR_POW,
- OPR_DIV,
- OPR_IDIV,
- OPR_BAND, OPR_BOR, OPR_BXOR,
- OPR_SHL, OPR_SHR,
- OPR_CONCAT,
- OPR_EQ, OPR_LT, OPR_LE,
- OPR_NE, OPR_GT, OPR_GE,
- OPR_AND, OPR_OR,
- OPR_NOBINOPR
-} BinOpr;
-
-
-typedef enum UnOpr { OPR_MINUS, OPR_BNOT, OPR_NOT, OPR_LEN, OPR_NOUNOPR } UnOpr;
-
-
-#define getcode(fs,e) ((fs)->f->code[(e)->u.info])
-
-#define luaK_codeAsBx(fs,o,A,sBx) luaK_codeABx(fs,o,A,(sBx)+MAXARG_sBx)
-
-#define luaK_setmultret(fs,e) luaK_setreturns(fs, e, LUA_MULTRET)
-
-#define luaK_jumpto(fs,t) luaK_patchlist(fs, luaK_jump(fs), t)
-
-LUAI_FUNC int luaK_codeABx (FuncState *fs, OpCode o, int A, unsigned int Bx);
-LUAI_FUNC int luaK_codeABC (FuncState *fs, OpCode o, int A, int B, int C);
-LUAI_FUNC int luaK_codek (FuncState *fs, int reg, int k);
-LUAI_FUNC void luaK_fixline (FuncState *fs, int line);
-LUAI_FUNC void luaK_nil (FuncState *fs, int from, int n);
-LUAI_FUNC void luaK_reserveregs (FuncState *fs, int n);
-LUAI_FUNC void luaK_checkstack (FuncState *fs, int n);
-LUAI_FUNC int luaK_stringK (FuncState *fs, TString *s);
-LUAI_FUNC int luaK_intK (FuncState *fs, lua_Integer n);
-LUAI_FUNC void luaK_dischargevars (FuncState *fs, expdesc *e);
-LUAI_FUNC int luaK_exp2anyreg (FuncState *fs, expdesc *e);
-LUAI_FUNC void luaK_exp2anyregup (FuncState *fs, expdesc *e);
-LUAI_FUNC void luaK_exp2nextreg (FuncState *fs, expdesc *e);
-LUAI_FUNC void luaK_exp2val (FuncState *fs, expdesc *e);
-LUAI_FUNC int luaK_exp2RK (FuncState *fs, expdesc *e);
-LUAI_FUNC void luaK_self (FuncState *fs, expdesc *e, expdesc *key);
-LUAI_FUNC void luaK_indexed (FuncState *fs, expdesc *t, expdesc *k);
-LUAI_FUNC void luaK_goiftrue (FuncState *fs, expdesc *e);
-LUAI_FUNC void luaK_goiffalse (FuncState *fs, expdesc *e);
-LUAI_FUNC void luaK_storevar (FuncState *fs, expdesc *var, expdesc *e);
-LUAI_FUNC void luaK_setreturns (FuncState *fs, expdesc *e, int nresults);
-LUAI_FUNC void luaK_setoneret (FuncState *fs, expdesc *e);
-LUAI_FUNC int luaK_jump (FuncState *fs);
-LUAI_FUNC void luaK_ret (FuncState *fs, int first, int nret);
-LUAI_FUNC void luaK_patchlist (FuncState *fs, int list, int target);
-LUAI_FUNC void luaK_patchtohere (FuncState *fs, int list);
-LUAI_FUNC void luaK_patchclose (FuncState *fs, int list, int level);
-LUAI_FUNC void luaK_concat (FuncState *fs, int *l1, int l2);
-LUAI_FUNC int luaK_getlabel (FuncState *fs);
-LUAI_FUNC void luaK_prefix (FuncState *fs, UnOpr op, expdesc *v, int line);
-LUAI_FUNC void luaK_infix (FuncState *fs, BinOpr op, expdesc *v);
-LUAI_FUNC void luaK_posfix (FuncState *fs, BinOpr op, expdesc *v1,
- expdesc *v2, int line);
-LUAI_FUNC void luaK_setlist (FuncState *fs, int base, int nelems, int tostore);
-
-
-#endif
diff --git a/3rd/lua/src/lcorolib.c b/3rd/lua/src/lcorolib.c
deleted file mode 100644
index 0c0b7fa..0000000
--- a/3rd/lua/src/lcorolib.c
+++ /dev/null
@@ -1,168 +0,0 @@
-/*
-** $Id: lcorolib.c,v 1.9 2014/11/02 19:19:04 roberto Exp $
-** Coroutine Library
-** See Copyright Notice in lua.h
-*/
-
-#define lcorolib_c
-#define LUA_LIB
-
-#include "lprefix.h"
-
-
-#include
-
-#include "lua.h"
-
-#include "lauxlib.h"
-#include "lualib.h"
-
-
-static lua_State *getco (lua_State *L) {
- lua_State *co = lua_tothread(L, 1);
- luaL_argcheck(L, co, 1, "thread expected");
- return co;
-}
-
-
-static int auxresume (lua_State *L, lua_State *co, int narg) {
- int status;
- if (!lua_checkstack(co, narg)) {
- lua_pushliteral(L, "too many arguments to resume");
- return -1; /* error flag */
- }
- if (lua_status(co) == LUA_OK && lua_gettop(co) == 0) {
- lua_pushliteral(L, "cannot resume dead coroutine");
- return -1; /* error flag */
- }
- lua_xmove(L, co, narg);
- status = lua_resume(co, L, narg);
- if (status == LUA_OK || status == LUA_YIELD) {
- int nres = lua_gettop(co);
- if (!lua_checkstack(L, nres + 1)) {
- lua_pop(co, nres); /* remove results anyway */
- lua_pushliteral(L, "too many results to resume");
- return -1; /* error flag */
- }
- lua_xmove(co, L, nres); /* move yielded values */
- return nres;
- }
- else {
- lua_xmove(co, L, 1); /* move error message */
- return -1; /* error flag */
- }
-}
-
-
-static int luaB_coresume (lua_State *L) {
- lua_State *co = getco(L);
- int r;
- r = auxresume(L, co, lua_gettop(L) - 1);
- if (r < 0) {
- lua_pushboolean(L, 0);
- lua_insert(L, -2);
- return 2; /* return false + error message */
- }
- else {
- lua_pushboolean(L, 1);
- lua_insert(L, -(r + 1));
- return r + 1; /* return true + 'resume' returns */
- }
-}
-
-
-static int luaB_auxwrap (lua_State *L) {
- lua_State *co = lua_tothread(L, lua_upvalueindex(1));
- int r = auxresume(L, co, lua_gettop(L));
- if (r < 0) {
- if (lua_isstring(L, -1)) { /* error object is a string? */
- luaL_where(L, 1); /* add extra info */
- lua_insert(L, -2);
- lua_concat(L, 2);
- }
- return lua_error(L); /* propagate error */
- }
- return r;
-}
-
-
-static int luaB_cocreate (lua_State *L) {
- lua_State *NL;
- luaL_checktype(L, 1, LUA_TFUNCTION);
- NL = lua_newthread(L);
- lua_pushvalue(L, 1); /* move function to top */
- lua_xmove(L, NL, 1); /* move function from L to NL */
- return 1;
-}
-
-
-static int luaB_cowrap (lua_State *L) {
- luaB_cocreate(L);
- lua_pushcclosure(L, luaB_auxwrap, 1);
- return 1;
-}
-
-
-static int luaB_yield (lua_State *L) {
- return lua_yield(L, lua_gettop(L));
-}
-
-
-static int luaB_costatus (lua_State *L) {
- lua_State *co = getco(L);
- if (L == co) lua_pushliteral(L, "running");
- else {
- switch (lua_status(co)) {
- case LUA_YIELD:
- lua_pushliteral(L, "suspended");
- break;
- case LUA_OK: {
- lua_Debug ar;
- if (lua_getstack(co, 0, &ar) > 0) /* does it have frames? */
- lua_pushliteral(L, "normal"); /* it is running */
- else if (lua_gettop(co) == 0)
- lua_pushliteral(L, "dead");
- else
- lua_pushliteral(L, "suspended"); /* initial state */
- break;
- }
- default: /* some error occurred */
- lua_pushliteral(L, "dead");
- break;
- }
- }
- return 1;
-}
-
-
-static int luaB_yieldable (lua_State *L) {
- lua_pushboolean(L, lua_isyieldable(L));
- return 1;
-}
-
-
-static int luaB_corunning (lua_State *L) {
- int ismain = lua_pushthread(L);
- lua_pushboolean(L, ismain);
- return 2;
-}
-
-
-static const luaL_Reg co_funcs[] = {
- {"create", luaB_cocreate},
- {"resume", luaB_coresume},
- {"running", luaB_corunning},
- {"status", luaB_costatus},
- {"wrap", luaB_cowrap},
- {"yield", luaB_yield},
- {"isyieldable", luaB_yieldable},
- {NULL, NULL}
-};
-
-
-
-LUAMOD_API int luaopen_coroutine (lua_State *L) {
- luaL_newlib(L, co_funcs);
- return 1;
-}
-
diff --git a/3rd/lua/src/lctype.c b/3rd/lua/src/lctype.c
deleted file mode 100644
index ae9367e..0000000
--- a/3rd/lua/src/lctype.c
+++ /dev/null
@@ -1,55 +0,0 @@
-/*
-** $Id: lctype.c,v 1.12 2014/11/02 19:19:04 roberto Exp $
-** 'ctype' functions for Lua
-** See Copyright Notice in lua.h
-*/
-
-#define lctype_c
-#define LUA_CORE
-
-#include "lprefix.h"
-
-
-#include "lctype.h"
-
-#if !LUA_USE_CTYPE /* { */
-
-#include
-
-LUAI_DDEF const lu_byte luai_ctype_[UCHAR_MAX + 2] = {
- 0x00, /* EOZ */
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0. */
- 0x00, 0x08, 0x08, 0x08, 0x08, 0x08, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 1. */
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x0c, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, /* 2. */
- 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04,
- 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, /* 3. */
- 0x16, 0x16, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04,
- 0x04, 0x15, 0x15, 0x15, 0x15, 0x15, 0x15, 0x05, /* 4. */
- 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05,
- 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, /* 5. */
- 0x05, 0x05, 0x05, 0x04, 0x04, 0x04, 0x04, 0x05,
- 0x04, 0x15, 0x15, 0x15, 0x15, 0x15, 0x15, 0x05, /* 6. */
- 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05,
- 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, /* 7. */
- 0x05, 0x05, 0x05, 0x04, 0x04, 0x04, 0x04, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 8. */
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 9. */
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* a. */
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* b. */
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* c. */
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* d. */
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* e. */
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* f. */
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-};
-
-#endif /* } */
diff --git a/3rd/lua/src/lctype.h b/3rd/lua/src/lctype.h
deleted file mode 100644
index 99c7d12..0000000
--- a/3rd/lua/src/lctype.h
+++ /dev/null
@@ -1,95 +0,0 @@
-/*
-** $Id: lctype.h,v 1.12 2011/07/15 12:50:29 roberto Exp $
-** 'ctype' functions for Lua
-** See Copyright Notice in lua.h
-*/
-
-#ifndef lctype_h
-#define lctype_h
-
-#include "lua.h"
-
-
-/*
-** WARNING: the functions defined here do not necessarily correspond
-** to the similar functions in the standard C ctype.h. They are
-** optimized for the specific needs of Lua
-*/
-
-#if !defined(LUA_USE_CTYPE)
-
-#if 'A' == 65 && '0' == 48
-/* ASCII case: can use its own tables; faster and fixed */
-#define LUA_USE_CTYPE 0
-#else
-/* must use standard C ctype */
-#define LUA_USE_CTYPE 1
-#endif
-
-#endif
-
-
-#if !LUA_USE_CTYPE /* { */
-
-#include
-
-#include "llimits.h"
-
-
-#define ALPHABIT 0
-#define DIGITBIT 1
-#define PRINTBIT 2
-#define SPACEBIT 3
-#define XDIGITBIT 4
-
-
-#define MASK(B) (1 << (B))
-
-
-/*
-** add 1 to char to allow index -1 (EOZ)
-*/
-#define testprop(c,p) (luai_ctype_[(c)+1] & (p))
-
-/*
-** 'lalpha' (Lua alphabetic) and 'lalnum' (Lua alphanumeric) both include '_'
-*/
-#define lislalpha(c) testprop(c, MASK(ALPHABIT))
-#define lislalnum(c) testprop(c, (MASK(ALPHABIT) | MASK(DIGITBIT)))
-#define lisdigit(c) testprop(c, MASK(DIGITBIT))
-#define lisspace(c) testprop(c, MASK(SPACEBIT))
-#define lisprint(c) testprop(c, MASK(PRINTBIT))
-#define lisxdigit(c) testprop(c, MASK(XDIGITBIT))
-
-/*
-** this 'ltolower' only works for alphabetic characters
-*/
-#define ltolower(c) ((c) | ('A' ^ 'a'))
-
-
-/* two more entries for 0 and -1 (EOZ) */
-LUAI_DDEC const lu_byte luai_ctype_[UCHAR_MAX + 2];
-
-
-#else /* }{ */
-
-/*
-** use standard C ctypes
-*/
-
-#include
-
-
-#define lislalpha(c) (isalpha(c) || (c) == '_')
-#define lislalnum(c) (isalnum(c) || (c) == '_')
-#define lisdigit(c) (isdigit(c))
-#define lisspace(c) (isspace(c))
-#define lisprint(c) (isprint(c))
-#define lisxdigit(c) (isxdigit(c))
-
-#define ltolower(c) (tolower(c))
-
-#endif /* } */
-
-#endif
-
diff --git a/3rd/lua/src/ldblib.c b/3rd/lua/src/ldblib.c
deleted file mode 100644
index 24a11b5..0000000
--- a/3rd/lua/src/ldblib.c
+++ /dev/null
@@ -1,437 +0,0 @@
-/*
-** $Id: ldblib.c,v 1.148 2015/01/02 12:52:22 roberto Exp $
-** Interface from Lua to its debug API
-** See Copyright Notice in lua.h
-*/
-
-#define ldblib_c
-#define LUA_LIB
-
-#include "lprefix.h"
-
-
-#include
-#include
-#include
-
-#include "lua.h"
-
-#include "lauxlib.h"
-#include "lualib.h"
-
-
-/*
-** The hook table at registry[&HOOKKEY] maps threads to their current
-** hook function. (We only need the unique address of 'HOOKKEY'.)
-*/
-static const int HOOKKEY = 0;
-
-
-static int db_getregistry (lua_State *L) {
- lua_pushvalue(L, LUA_REGISTRYINDEX);
- return 1;
-}
-
-
-static int db_getmetatable (lua_State *L) {
- luaL_checkany(L, 1);
- if (!lua_getmetatable(L, 1)) {
- lua_pushnil(L); /* no metatable */
- }
- return 1;
-}
-
-
-static int db_setmetatable (lua_State *L) {
- int t = lua_type(L, 2);
- luaL_argcheck(L, t == LUA_TNIL || t == LUA_TTABLE, 2,
- "nil or table expected");
- lua_settop(L, 2);
- lua_setmetatable(L, 1);
- return 1; /* return 1st argument */
-}
-
-
-static int db_getuservalue (lua_State *L) {
- if (lua_type(L, 1) != LUA_TUSERDATA)
- lua_pushnil(L);
- else
- lua_getuservalue(L, 1);
- return 1;
-}
-
-
-static int db_setuservalue (lua_State *L) {
- luaL_checktype(L, 1, LUA_TUSERDATA);
- luaL_checkany(L, 2);
- lua_settop(L, 2);
- lua_setuservalue(L, 1);
- return 1;
-}
-
-
-/*
-** Auxiliary function used by several library functions: check for
-** an optional thread as function's first argument and set 'arg' with
-** 1 if this argument is present (so that functions can skip it to
-** access their other arguments)
-*/
-static lua_State *getthread (lua_State *L, int *arg) {
- if (lua_isthread(L, 1)) {
- *arg = 1;
- return lua_tothread(L, 1);
- }
- else {
- *arg = 0;
- return L; /* function will operate over current thread */
- }
-}
-
-
-/*
-** Variations of 'lua_settable', used by 'db_getinfo' to put results
-** from 'lua_getinfo' into result table. Key is always a string;
-** value can be a string, an int, or a boolean.
-*/
-static void settabss (lua_State *L, const char *k, const char *v) {
- lua_pushstring(L, v);
- lua_setfield(L, -2, k);
-}
-
-static void settabsi (lua_State *L, const char *k, int v) {
- lua_pushinteger(L, v);
- lua_setfield(L, -2, k);
-}
-
-static void settabsb (lua_State *L, const char *k, int v) {
- lua_pushboolean(L, v);
- lua_setfield(L, -2, k);
-}
-
-
-/*
-** In function 'db_getinfo', the call to 'lua_getinfo' may push
-** results on the stack; later it creates the result table to put
-** these objects. Function 'treatstackoption' puts the result from
-** 'lua_getinfo' on top of the result table so that it can call
-** 'lua_setfield'.
-*/
-static void treatstackoption (lua_State *L, lua_State *L1, const char *fname) {
- if (L == L1)
- lua_rotate(L, -2, 1); /* exchange object and table */
- else
- lua_xmove(L1, L, 1); /* move object to the "main" stack */
- lua_setfield(L, -2, fname); /* put object into table */
-}
-
-
-/*
-** Calls 'lua_getinfo' and collects all results in a new table.
-*/
-static int db_getinfo (lua_State *L) {
- lua_Debug ar;
- int arg;
- lua_State *L1 = getthread(L, &arg);
- const char *options = luaL_optstring(L, arg+2, "flnStu");
- if (lua_isfunction(L, arg + 1)) { /* info about a function? */
- options = lua_pushfstring(L, ">%s", options); /* add '>' to 'options' */
- lua_pushvalue(L, arg + 1); /* move function to 'L1' stack */
- lua_xmove(L, L1, 1);
- }
- else { /* stack level */
- if (!lua_getstack(L1, (int)luaL_checkinteger(L, arg + 1), &ar)) {
- lua_pushnil(L); /* level out of range */
- return 1;
- }
- }
- if (!lua_getinfo(L1, options, &ar))
- return luaL_argerror(L, arg+2, "invalid option");
- lua_newtable(L); /* table to collect results */
- if (strchr(options, 'S')) {
- settabss(L, "source", ar.source);
- settabss(L, "short_src", ar.short_src);
- settabsi(L, "linedefined", ar.linedefined);
- settabsi(L, "lastlinedefined", ar.lastlinedefined);
- settabss(L, "what", ar.what);
- }
- if (strchr(options, 'l'))
- settabsi(L, "currentline", ar.currentline);
- if (strchr(options, 'u')) {
- settabsi(L, "nups", ar.nups);
- settabsi(L, "nparams", ar.nparams);
- settabsb(L, "isvararg", ar.isvararg);
- }
- if (strchr(options, 'n')) {
- settabss(L, "name", ar.name);
- settabss(L, "namewhat", ar.namewhat);
- }
- if (strchr(options, 't'))
- settabsb(L, "istailcall", ar.istailcall);
- if (strchr(options, 'L'))
- treatstackoption(L, L1, "activelines");
- if (strchr(options, 'f'))
- treatstackoption(L, L1, "func");
- return 1; /* return table */
-}
-
-
-static int db_getlocal (lua_State *L) {
- int arg;
- lua_State *L1 = getthread(L, &arg);
- lua_Debug ar;
- const char *name;
- int nvar = (int)luaL_checkinteger(L, arg + 2); /* local-variable index */
- if (lua_isfunction(L, arg + 1)) { /* function argument? */
- lua_pushvalue(L, arg + 1); /* push function */
- lua_pushstring(L, lua_getlocal(L, NULL, nvar)); /* push local name */
- return 1; /* return only name (there is no value) */
- }
- else { /* stack-level argument */
- int level = (int)luaL_checkinteger(L, arg + 1);
- if (!lua_getstack(L1, level, &ar)) /* out of range? */
- return luaL_argerror(L, arg+1, "level out of range");
- name = lua_getlocal(L1, &ar, nvar);
- if (name) {
- lua_xmove(L1, L, 1); /* move local value */
- lua_pushstring(L, name); /* push name */
- lua_rotate(L, -2, 1); /* re-order */
- return 2;
- }
- else {
- lua_pushnil(L); /* no name (nor value) */
- return 1;
- }
- }
-}
-
-
-static int db_setlocal (lua_State *L) {
- int arg;
- const char *name;
- lua_State *L1 = getthread(L, &arg);
- lua_Debug ar;
- int level = (int)luaL_checkinteger(L, arg + 1);
- int nvar = (int)luaL_checkinteger(L, arg + 2);
- if (!lua_getstack(L1, level, &ar)) /* out of range? */
- return luaL_argerror(L, arg+1, "level out of range");
- luaL_checkany(L, arg+3);
- lua_settop(L, arg+3);
- lua_xmove(L, L1, 1);
- name = lua_setlocal(L1, &ar, nvar);
- if (name == NULL)
- lua_pop(L1, 1); /* pop value (if not popped by 'lua_setlocal') */
- lua_pushstring(L, name);
- return 1;
-}
-
-
-/*
-** get (if 'get' is true) or set an upvalue from a closure
-*/
-static int auxupvalue (lua_State *L, int get) {
- const char *name;
- int n = (int)luaL_checkinteger(L, 2); /* upvalue index */
- luaL_checktype(L, 1, LUA_TFUNCTION); /* closure */
- name = get ? lua_getupvalue(L, 1, n) : lua_setupvalue(L, 1, n);
- if (name == NULL) return 0;
- lua_pushstring(L, name);
- lua_insert(L, -(get+1)); /* no-op if get is false */
- return get + 1;
-}
-
-
-static int db_getupvalue (lua_State *L) {
- return auxupvalue(L, 1);
-}
-
-
-static int db_setupvalue (lua_State *L) {
- luaL_checkany(L, 3);
- return auxupvalue(L, 0);
-}
-
-
-/*
-** Check whether a given upvalue from a given closure exists and
-** returns its index
-*/
-static int checkupval (lua_State *L, int argf, int argnup) {
- int nup = (int)luaL_checkinteger(L, argnup); /* upvalue index */
- luaL_checktype(L, argf, LUA_TFUNCTION); /* closure */
- luaL_argcheck(L, (lua_getupvalue(L, argf, nup) != NULL), argnup,
- "invalid upvalue index");
- return nup;
-}
-
-
-static int db_upvalueid (lua_State *L) {
- int n = checkupval(L, 1, 2);
- lua_pushlightuserdata(L, lua_upvalueid(L, 1, n));
- return 1;
-}
-
-
-static int db_upvaluejoin (lua_State *L) {
- int n1 = checkupval(L, 1, 2);
- int n2 = checkupval(L, 3, 4);
- luaL_argcheck(L, !lua_iscfunction(L, 1), 1, "Lua function expected");
- luaL_argcheck(L, !lua_iscfunction(L, 3), 3, "Lua function expected");
- lua_upvaluejoin(L, 1, n1, 3, n2);
- return 0;
-}
-
-
-/*
-** Call hook function registered at hook table for the current
-** thread (if there is one)
-*/
-static void hookf (lua_State *L, lua_Debug *ar) {
- static const char *const hooknames[] =
- {"call", "return", "line", "count", "tail call"};
- lua_rawgetp(L, LUA_REGISTRYINDEX, &HOOKKEY);
- lua_pushthread(L);
- if (lua_rawget(L, -2) == LUA_TFUNCTION) { /* is there a hook function? */
- lua_pushstring(L, hooknames[(int)ar->event]); /* push event name */
- if (ar->currentline >= 0)
- lua_pushinteger(L, ar->currentline); /* push current line */
- else lua_pushnil(L);
- lua_assert(lua_getinfo(L, "lS", ar));
- lua_call(L, 2, 0); /* call hook function */
- }
-}
-
-
-/*
-** Convert a string mask (for 'sethook') into a bit mask
-*/
-static int makemask (const char *smask, int count) {
- int mask = 0;
- if (strchr(smask, 'c')) mask |= LUA_MASKCALL;
- if (strchr(smask, 'r')) mask |= LUA_MASKRET;
- if (strchr(smask, 'l')) mask |= LUA_MASKLINE;
- if (count > 0) mask |= LUA_MASKCOUNT;
- return mask;
-}
-
-
-/*
-** Convert a bit mask (for 'gethook') into a string mask
-*/
-static char *unmakemask (int mask, char *smask) {
- int i = 0;
- if (mask & LUA_MASKCALL) smask[i++] = 'c';
- if (mask & LUA_MASKRET) smask[i++] = 'r';
- if (mask & LUA_MASKLINE) smask[i++] = 'l';
- smask[i] = '\0';
- return smask;
-}
-
-
-static int db_sethook (lua_State *L) {
- int arg, mask, count;
- lua_Hook func;
- lua_State *L1 = getthread(L, &arg);
- if (lua_isnoneornil(L, arg+1)) { /* no hook? */
- lua_settop(L, arg+1);
- func = NULL; mask = 0; count = 0; /* turn off hooks */
- }
- else {
- const char *smask = luaL_checkstring(L, arg+2);
- luaL_checktype(L, arg+1, LUA_TFUNCTION);
- count = (int)luaL_optinteger(L, arg + 3, 0);
- func = hookf; mask = makemask(smask, count);
- }
- if (lua_rawgetp(L, LUA_REGISTRYINDEX, &HOOKKEY) == LUA_TNIL) {
- lua_createtable(L, 0, 2); /* create a hook table */
- lua_pushvalue(L, -1);
- lua_rawsetp(L, LUA_REGISTRYINDEX, &HOOKKEY); /* set it in position */
- lua_pushstring(L, "k");
- lua_setfield(L, -2, "__mode"); /** hooktable.__mode = "k" */
- lua_pushvalue(L, -1);
- lua_setmetatable(L, -2); /* setmetatable(hooktable) = hooktable */
- }
- lua_pushthread(L1); lua_xmove(L1, L, 1); /* key (thread) */
- lua_pushvalue(L, arg + 1); /* value (hook function) */
- lua_rawset(L, -3); /* hooktable[L1] = new Lua hook */
- lua_sethook(L1, func, mask, count);
- return 0;
-}
-
-
-static int db_gethook (lua_State *L) {
- int arg;
- lua_State *L1 = getthread(L, &arg);
- char buff[5];
- int mask = lua_gethookmask(L1);
- lua_Hook hook = lua_gethook(L1);
- if (hook == NULL) /* no hook? */
- lua_pushnil(L);
- else if (hook != hookf) /* external hook? */
- lua_pushliteral(L, "external hook");
- else { /* hook table must exist */
- lua_rawgetp(L, LUA_REGISTRYINDEX, &HOOKKEY);
- lua_pushthread(L1); lua_xmove(L1, L, 1);
- lua_rawget(L, -2); /* 1st result = hooktable[L1] */
- lua_remove(L, -2); /* remove hook table */
- }
- lua_pushstring(L, unmakemask(mask, buff)); /* 2nd result = mask */
- lua_pushinteger(L, lua_gethookcount(L1)); /* 3rd result = count */
- return 3;
-}
-
-
-static int db_debug (lua_State *L) {
- for (;;) {
- char buffer[250];
- lua_writestringerror("%s", "lua_debug> ");
- if (fgets(buffer, sizeof(buffer), stdin) == 0 ||
- strcmp(buffer, "cont\n") == 0)
- return 0;
- if (luaL_loadbuffer(L, buffer, strlen(buffer), "=(debug command)") ||
- lua_pcall(L, 0, 0, 0))
- lua_writestringerror("%s\n", lua_tostring(L, -1));
- lua_settop(L, 0); /* remove eventual returns */
- }
-}
-
-
-static int db_traceback (lua_State *L) {
- int arg;
- lua_State *L1 = getthread(L, &arg);
- const char *msg = lua_tostring(L, arg + 1);
- if (msg == NULL && !lua_isnoneornil(L, arg + 1)) /* non-string 'msg'? */
- lua_pushvalue(L, arg + 1); /* return it untouched */
- else {
- int level = (int)luaL_optinteger(L, arg + 2, (L == L1) ? 1 : 0);
- luaL_traceback(L, L1, msg, level);
- }
- return 1;
-}
-
-
-static const luaL_Reg dblib[] = {
- {"debug", db_debug},
- {"getuservalue", db_getuservalue},
- {"gethook", db_gethook},
- {"getinfo", db_getinfo},
- {"getlocal", db_getlocal},
- {"getregistry", db_getregistry},
- {"getmetatable", db_getmetatable},
- {"getupvalue", db_getupvalue},
- {"upvaluejoin", db_upvaluejoin},
- {"upvalueid", db_upvalueid},
- {"setuservalue", db_setuservalue},
- {"sethook", db_sethook},
- {"setlocal", db_setlocal},
- {"setmetatable", db_setmetatable},
- {"setupvalue", db_setupvalue},
- {"traceback", db_traceback},
- {NULL, NULL}
-};
-
-
-LUAMOD_API int luaopen_debug (lua_State *L) {
- luaL_newlib(L, dblib);
- return 1;
-}
-
diff --git a/3rd/lua/src/ldebug.c b/3rd/lua/src/ldebug.c
deleted file mode 100644
index 6986bf0..0000000
--- a/3rd/lua/src/ldebug.c
+++ /dev/null
@@ -1,643 +0,0 @@
-/*
-** $Id: ldebug.c,v 2.110 2015/01/02 12:52:22 roberto Exp $
-** Debug Interface
-** See Copyright Notice in lua.h
-*/
-
-#define ldebug_c
-#define LUA_CORE
-
-#include "lprefix.h"
-
-
-#include
-#include
-#include
-
-#include "lua.h"
-
-#include "lapi.h"
-#include "lcode.h"
-#include "ldebug.h"
-#include "ldo.h"
-#include "lfunc.h"
-#include "lobject.h"
-#include "lopcodes.h"
-#include "lstate.h"
-#include "lstring.h"
-#include "ltable.h"
-#include "ltm.h"
-#include "lvm.h"
-
-
-
-#define noLuaClosure(f) ((f) == NULL || (f)->c.tt == LUA_TCCL)
-
-
-static const char *getfuncname (lua_State *L, CallInfo *ci, const char **name);
-
-
-static int currentpc (CallInfo *ci) {
- lua_assert(isLua(ci));
- return pcRel(ci->u.l.savedpc, ci_func(ci)->p);
-}
-
-
-static int currentline (CallInfo *ci) {
- return getfuncline(ci_func(ci)->p, currentpc(ci));
-}
-
-
-/*
-** this function can be called asynchronous (e.g. during a signal)
-*/
-LUA_API void lua_sethook (lua_State *L, lua_Hook func, int mask, int count) {
- if (func == NULL || mask == 0) { /* turn off hooks? */
- mask = 0;
- func = NULL;
- }
- if (isLua(L->ci))
- L->oldpc = L->ci->u.l.savedpc;
- L->hook = func;
- L->basehookcount = count;
- resethookcount(L);
- L->hookmask = cast_byte(mask);
-}
-
-
-LUA_API lua_Hook lua_gethook (lua_State *L) {
- return L->hook;
-}
-
-
-LUA_API int lua_gethookmask (lua_State *L) {
- return L->hookmask;
-}
-
-
-LUA_API int lua_gethookcount (lua_State *L) {
- return L->basehookcount;
-}
-
-
-LUA_API int lua_getstack (lua_State *L, int level, lua_Debug *ar) {
- int status;
- CallInfo *ci;
- if (level < 0) return 0; /* invalid (negative) level */
- lua_lock(L);
- for (ci = L->ci; level > 0 && ci != &L->base_ci; ci = ci->previous)
- level--;
- if (level == 0 && ci != &L->base_ci) { /* level found? */
- status = 1;
- ar->i_ci = ci;
- }
- else status = 0; /* no such level */
- lua_unlock(L);
- return status;
-}
-
-
-static const char *upvalname (Proto *p, int uv) {
- TString *s = check_exp(uv < p->sizeupvalues, p->upvalues[uv].name);
- if (s == NULL) return "?";
- else return getstr(s);
-}
-
-
-static const char *findvararg (CallInfo *ci, int n, StkId *pos) {
- int nparams = clLvalue(ci->func)->p->numparams;
- if (n >= ci->u.l.base - ci->func - nparams)
- return NULL; /* no such vararg */
- else {
- *pos = ci->func + nparams + n;
- return "(*vararg)"; /* generic name for any vararg */
- }
-}
-
-
-static const char *findlocal (lua_State *L, CallInfo *ci, int n,
- StkId *pos) {
- const char *name = NULL;
- StkId base;
- if (isLua(ci)) {
- if (n < 0) /* access to vararg values? */
- return findvararg(ci, -n, pos);
- else {
- base = ci->u.l.base;
- name = luaF_getlocalname(ci_func(ci)->p, n, currentpc(ci));
- }
- }
- else
- base = ci->func + 1;
- if (name == NULL) { /* no 'standard' name? */
- StkId limit = (ci == L->ci) ? L->top : ci->next->func;
- if (limit - base >= n && n > 0) /* is 'n' inside 'ci' stack? */
- name = "(*temporary)"; /* generic name for any valid slot */
- else
- return NULL; /* no name */
- }
- *pos = base + (n - 1);
- return name;
-}
-
-
-LUA_API const char *lua_getlocal (lua_State *L, const lua_Debug *ar, int n) {
- const char *name;
- lua_lock(L);
- if (ar == NULL) { /* information about non-active function? */
- if (!isLfunction(L->top - 1)) /* not a Lua function? */
- name = NULL;
- else /* consider live variables at function start (parameters) */
- name = luaF_getlocalname(clLvalue(L->top - 1)->p, n, 0);
- }
- else { /* active function; get information through 'ar' */
- StkId pos = 0; /* to avoid warnings */
- name = findlocal(L, ar->i_ci, n, &pos);
- if (name) {
- setobj2s(L, L->top, pos);
- api_incr_top(L);
- }
- }
- lua_unlock(L);
- return name;
-}
-
-
-LUA_API const char *lua_setlocal (lua_State *L, const lua_Debug *ar, int n) {
- StkId pos = 0; /* to avoid warnings */
- const char *name = findlocal(L, ar->i_ci, n, &pos);
- lua_lock(L);
- if (name) {
- setobjs2s(L, pos, L->top - 1);
- L->top--; /* pop value */
- }
- lua_unlock(L);
- return name;
-}
-
-
-static void funcinfo (lua_Debug *ar, Closure *cl) {
- if (noLuaClosure(cl)) {
- ar->source = "=[C]";
- ar->linedefined = -1;
- ar->lastlinedefined = -1;
- ar->what = "C";
- }
- else {
- Proto *p = cl->l.p;
- ar->source = p->source ? getstr(p->source) : "=?";
- ar->linedefined = p->linedefined;
- ar->lastlinedefined = p->lastlinedefined;
- ar->what = (ar->linedefined == 0) ? "main" : "Lua";
- }
- luaO_chunkid(ar->short_src, ar->source, LUA_IDSIZE);
-}
-
-
-static void collectvalidlines (lua_State *L, Closure *f) {
- if (noLuaClosure(f)) {
- setnilvalue(L->top);
- api_incr_top(L);
- }
- else {
- int i;
- TValue v;
- int *lineinfo = f->l.p->lineinfo;
- Table *t = luaH_new(L); /* new table to store active lines */
- sethvalue(L, L->top, t); /* push it on stack */
- api_incr_top(L);
- setbvalue(&v, 1); /* boolean 'true' to be the value of all indices */
- for (i = 0; i < f->l.p->sizelineinfo; i++) /* for all lines with code */
- luaH_setint(L, t, lineinfo[i], &v); /* table[line] = true */
- }
-}
-
-
-static int auxgetinfo (lua_State *L, const char *what, lua_Debug *ar,
- Closure *f, CallInfo *ci) {
- int status = 1;
- for (; *what; what++) {
- switch (*what) {
- case 'S': {
- funcinfo(ar, f);
- break;
- }
- case 'l': {
- ar->currentline = (ci && isLua(ci)) ? currentline(ci) : -1;
- break;
- }
- case 'u': {
- ar->nups = (f == NULL) ? 0 : f->c.nupvalues;
- if (noLuaClosure(f)) {
- ar->isvararg = 1;
- ar->nparams = 0;
- }
- else {
- ar->isvararg = f->l.p->is_vararg;
- ar->nparams = f->l.p->numparams;
- }
- break;
- }
- case 't': {
- ar->istailcall = (ci) ? ci->callstatus & CIST_TAIL : 0;
- break;
- }
- case 'n': {
- /* calling function is a known Lua function? */
- if (ci && !(ci->callstatus & CIST_TAIL) && isLua(ci->previous))
- ar->namewhat = getfuncname(L, ci->previous, &ar->name);
- else
- ar->namewhat = NULL;
- if (ar->namewhat == NULL) {
- ar->namewhat = ""; /* not found */
- ar->name = NULL;
- }
- break;
- }
- case 'L':
- case 'f': /* handled by lua_getinfo */
- break;
- default: status = 0; /* invalid option */
- }
- }
- return status;
-}
-
-
-LUA_API int lua_getinfo (lua_State *L, const char *what, lua_Debug *ar) {
- int status;
- Closure *cl;
- CallInfo *ci;
- StkId func;
- lua_lock(L);
- if (*what == '>') {
- ci = NULL;
- func = L->top - 1;
- api_check(ttisfunction(func), "function expected");
- what++; /* skip the '>' */
- L->top--; /* pop function */
- }
- else {
- ci = ar->i_ci;
- func = ci->func;
- lua_assert(ttisfunction(ci->func));
- }
- cl = ttisclosure(func) ? clvalue(func) : NULL;
- status = auxgetinfo(L, what, ar, cl, ci);
- if (strchr(what, 'f')) {
- setobjs2s(L, L->top, func);
- api_incr_top(L);
- }
- if (strchr(what, 'L'))
- collectvalidlines(L, cl);
- lua_unlock(L);
- return status;
-}
-
-
-/*
-** {======================================================
-** Symbolic Execution
-** =======================================================
-*/
-
-static const char *getobjname (Proto *p, int lastpc, int reg,
- const char **name);
-
-
-/*
-** find a "name" for the RK value 'c'
-*/
-static void kname (Proto *p, int pc, int c, const char **name) {
- if (ISK(c)) { /* is 'c' a constant? */
- TValue *kvalue = &p->k[INDEXK(c)];
- if (ttisstring(kvalue)) { /* literal constant? */
- *name = svalue(kvalue); /* it is its own name */
- return;
- }
- /* else no reasonable name found */
- }
- else { /* 'c' is a register */
- const char *what = getobjname(p, pc, c, name); /* search for 'c' */
- if (what && *what == 'c') { /* found a constant name? */
- return; /* 'name' already filled */
- }
- /* else no reasonable name found */
- }
- *name = "?"; /* no reasonable name found */
-}
-
-
-static int filterpc (int pc, int jmptarget) {
- if (pc < jmptarget) /* is code conditional (inside a jump)? */
- return -1; /* cannot know who sets that register */
- else return pc; /* current position sets that register */
-}
-
-
-/*
-** try to find last instruction before 'lastpc' that modified register 'reg'
-*/
-static int findsetreg (Proto *p, int lastpc, int reg) {
- int pc;
- int setreg = -1; /* keep last instruction that changed 'reg' */
- int jmptarget = 0; /* any code before this address is conditional */
- for (pc = 0; pc < lastpc; pc++) {
- Instruction i = p->code[pc];
- OpCode op = GET_OPCODE(i);
- int a = GETARG_A(i);
- switch (op) {
- case OP_LOADNIL: {
- int b = GETARG_B(i);
- if (a <= reg && reg <= a + b) /* set registers from 'a' to 'a+b' */
- setreg = filterpc(pc, jmptarget);
- break;
- }
- case OP_TFORCALL: {
- if (reg >= a + 2) /* affect all regs above its base */
- setreg = filterpc(pc, jmptarget);
- break;
- }
- case OP_CALL:
- case OP_TAILCALL: {
- if (reg >= a) /* affect all registers above base */
- setreg = filterpc(pc, jmptarget);
- break;
- }
- case OP_JMP: {
- int b = GETARG_sBx(i);
- int dest = pc + 1 + b;
- /* jump is forward and do not skip 'lastpc'? */
- if (pc < dest && dest <= lastpc) {
- if (dest > jmptarget)
- jmptarget = dest; /* update 'jmptarget' */
- }
- break;
- }
- default:
- if (testAMode(op) && reg == a) /* any instruction that set A */
- setreg = filterpc(pc, jmptarget);
- break;
- }
- }
- return setreg;
-}
-
-
-static const char *getobjname (Proto *p, int lastpc, int reg,
- const char **name) {
- int pc;
- *name = luaF_getlocalname(p, reg + 1, lastpc);
- if (*name) /* is a local? */
- return "local";
- /* else try symbolic execution */
- pc = findsetreg(p, lastpc, reg);
- if (pc != -1) { /* could find instruction? */
- Instruction i = p->code[pc];
- OpCode op = GET_OPCODE(i);
- switch (op) {
- case OP_MOVE: {
- int b = GETARG_B(i); /* move from 'b' to 'a' */
- if (b < GETARG_A(i))
- return getobjname(p, pc, b, name); /* get name for 'b' */
- break;
- }
- case OP_GETTABUP:
- case OP_GETTABLE: {
- int k = GETARG_C(i); /* key index */
- int t = GETARG_B(i); /* table index */
- const char *vn = (op == OP_GETTABLE) /* name of indexed variable */
- ? luaF_getlocalname(p, t + 1, pc)
- : upvalname(p, t);
- kname(p, pc, k, name);
- return (vn && strcmp(vn, LUA_ENV) == 0) ? "global" : "field";
- }
- case OP_GETUPVAL: {
- *name = upvalname(p, GETARG_B(i));
- return "upvalue";
- }
- case OP_LOADK:
- case OP_LOADKX: {
- int b = (op == OP_LOADK) ? GETARG_Bx(i)
- : GETARG_Ax(p->code[pc + 1]);
- if (ttisstring(&p->k[b])) {
- *name = svalue(&p->k[b]);
- return "constant";
- }
- break;
- }
- case OP_SELF: {
- int k = GETARG_C(i); /* key index */
- kname(p, pc, k, name);
- return "method";
- }
- default: break; /* go through to return NULL */
- }
- }
- return NULL; /* could not find reasonable name */
-}
-
-
-static const char *getfuncname (lua_State *L, CallInfo *ci, const char **name) {
- TMS tm = (TMS)0; /* to avoid warnings */
- Proto *p = ci_func(ci)->p; /* calling function */
- int pc = currentpc(ci); /* calling instruction index */
- Instruction i = p->code[pc]; /* calling instruction */
- if (ci->callstatus & CIST_HOOKED) { /* was it called inside a hook? */
- *name = "?";
- return "hook";
- }
- switch (GET_OPCODE(i)) {
- case OP_CALL:
- case OP_TAILCALL: /* get function name */
- return getobjname(p, pc, GETARG_A(i), name);
- case OP_TFORCALL: { /* for iterator */
- *name = "for iterator";
- return "for iterator";
- }
- /* all other instructions can call only through metamethods */
- case OP_SELF: case OP_GETTABUP: case OP_GETTABLE:
- tm = TM_INDEX;
- break;
- case OP_SETTABUP: case OP_SETTABLE:
- tm = TM_NEWINDEX;
- break;
- case OP_ADD: case OP_SUB: case OP_MUL: case OP_MOD:
- case OP_POW: case OP_DIV: case OP_IDIV: case OP_BAND:
- case OP_BOR: case OP_BXOR: case OP_SHL: case OP_SHR: {
- int offset = cast_int(GET_OPCODE(i)) - cast_int(OP_ADD); /* ORDER OP */
- tm = cast(TMS, offset + cast_int(TM_ADD)); /* ORDER TM */
- break;
- }
- case OP_UNM: tm = TM_UNM; break;
- case OP_BNOT: tm = TM_BNOT; break;
- case OP_LEN: tm = TM_LEN; break;
- case OP_CONCAT: tm = TM_CONCAT; break;
- case OP_EQ: tm = TM_EQ; break;
- case OP_LT: tm = TM_LT; break;
- case OP_LE: tm = TM_LE; break;
- default: lua_assert(0); /* other instructions cannot call a function */
- }
- *name = getstr(G(L)->tmname[tm]);
- return "metamethod";
-}
-
-/* }====================================================== */
-
-
-
-/*
-** The subtraction of two potentially unrelated pointers is
-** not ISO C, but it should not crash a program; the subsequent
-** checks are ISO C and ensure a correct result.
-*/
-static int isinstack (CallInfo *ci, const TValue *o) {
- ptrdiff_t i = o - ci->u.l.base;
- return (0 <= i && i < (ci->top - ci->u.l.base) && ci->u.l.base + i == o);
-}
-
-
-/*
-** Checks whether value 'o' came from an upvalue. (That can only happen
-** with instructions OP_GETTABUP/OP_SETTABUP, which operate directly on
-** upvalues.)
-*/
-static const char *getupvalname (CallInfo *ci, const TValue *o,
- const char **name) {
- LClosure *c = ci_func(ci);
- int i;
- for (i = 0; i < c->nupvalues; i++) {
- if (c->upvals[i]->v == o) {
- *name = upvalname(c->p, i);
- return "upvalue";
- }
- }
- return NULL;
-}
-
-
-static const char *varinfo (lua_State *L, const TValue *o) {
- const char *name = NULL; /* to avoid warnings */
- CallInfo *ci = L->ci;
- const char *kind = NULL;
- if (isLua(ci)) {
- kind = getupvalname(ci, o, &name); /* check whether 'o' is an upvalue */
- if (!kind && isinstack(ci, o)) /* no? try a register */
- kind = getobjname(ci_func(ci)->p, currentpc(ci),
- cast_int(o - ci->u.l.base), &name);
- }
- return (kind) ? luaO_pushfstring(L, " (%s '%s')", kind, name) : "";
-}
-
-
-l_noret luaG_typeerror (lua_State *L, const TValue *o, const char *op) {
- const char *t = objtypename(o);
- luaG_runerror(L, "attempt to %s a %s value%s", op, t, varinfo(L, o));
-}
-
-
-l_noret luaG_concaterror (lua_State *L, const TValue *p1, const TValue *p2) {
- if (ttisstring(p1) || cvt2str(p1)) p1 = p2;
- luaG_typeerror(L, p1, "concatenate");
-}
-
-
-l_noret luaG_opinterror (lua_State *L, const TValue *p1,
- const TValue *p2, const char *msg) {
- lua_Number temp;
- if (!tonumber(p1, &temp)) /* first operand is wrong? */
- p2 = p1; /* now second is wrong */
- luaG_typeerror(L, p2, msg);
-}
-
-
-/*
-** Error when both values are convertible to numbers, but not to integers
-*/
-l_noret luaG_tointerror (lua_State *L, const TValue *p1, const TValue *p2) {
- lua_Integer temp;
- if (!tointeger(p1, &temp))
- p2 = p1;
- luaG_runerror(L, "number%s has no integer representation", varinfo(L, p2));
-}
-
-
-l_noret luaG_ordererror (lua_State *L, const TValue *p1, const TValue *p2) {
- const char *t1 = objtypename(p1);
- const char *t2 = objtypename(p2);
- if (t1 == t2)
- luaG_runerror(L, "attempt to compare two %s values", t1);
- else
- luaG_runerror(L, "attempt to compare %s with %s", t1, t2);
-}
-
-
-static void addinfo (lua_State *L, const char *msg) {
- CallInfo *ci = L->ci;
- if (isLua(ci)) { /* is Lua code? */
- char buff[LUA_IDSIZE]; /* add file:line information */
- int line = currentline(ci);
- TString *src = ci_func(ci)->p->source;
- if (src)
- luaO_chunkid(buff, getstr(src), LUA_IDSIZE);
- else { /* no source available; use "?" instead */
- buff[0] = '?'; buff[1] = '\0';
- }
- luaO_pushfstring(L, "%s:%d: %s", buff, line, msg);
- }
-}
-
-
-l_noret luaG_errormsg (lua_State *L) {
- if (L->errfunc != 0) { /* is there an error handling function? */
- StkId errfunc = restorestack(L, L->errfunc);
- setobjs2s(L, L->top, L->top - 1); /* move argument */
- setobjs2s(L, L->top - 1, errfunc); /* push function */
- L->top++; /* assume EXTRA_STACK */
- luaD_call(L, L->top - 2, 1, 0); /* call it */
- }
- luaD_throw(L, LUA_ERRRUN);
-}
-
-
-l_noret luaG_runerror (lua_State *L, const char *fmt, ...) {
- va_list argp;
- va_start(argp, fmt);
- addinfo(L, luaO_pushvfstring(L, fmt, argp));
- va_end(argp);
- luaG_errormsg(L);
-}
-
-
-void luaG_traceexec (lua_State *L) {
- CallInfo *ci = L->ci;
- lu_byte mask = L->hookmask;
- int counthook = ((mask & LUA_MASKCOUNT) && L->hookcount == 0);
- if (counthook)
- resethookcount(L); /* reset count */
- if (ci->callstatus & CIST_HOOKYIELD) { /* called hook last time? */
- ci->callstatus &= ~CIST_HOOKYIELD; /* erase mark */
- return; /* do not call hook again (VM yielded, so it did not move) */
- }
- if (counthook)
- luaD_hook(L, LUA_HOOKCOUNT, -1); /* call count hook */
- if (mask & LUA_MASKLINE) {
- Proto *p = ci_func(ci)->p;
- int npc = pcRel(ci->u.l.savedpc, p);
- int newline = getfuncline(p, npc);
- if (npc == 0 || /* call linehook when enter a new function, */
- ci->u.l.savedpc <= L->oldpc || /* when jump back (loop), or when */
- newline != getfuncline(p, pcRel(L->oldpc, p))) /* enter a new line */
- luaD_hook(L, LUA_HOOKLINE, newline); /* call line hook */
- }
- L->oldpc = ci->u.l.savedpc;
- if (L->status == LUA_YIELD) { /* did hook yield? */
- if (counthook)
- L->hookcount = 1; /* undo decrement to zero */
- ci->u.l.savedpc--; /* undo increment (resume will increment it again) */
- ci->callstatus |= CIST_HOOKYIELD; /* mark that it yielded */
- ci->func = L->top - 1; /* protect stack below results */
- luaD_throw(L, LUA_YIELD);
- }
-}
-
diff --git a/3rd/lua/src/ldebug.h b/3rd/lua/src/ldebug.h
deleted file mode 100644
index 0d8966c..0000000
--- a/3rd/lua/src/ldebug.h
+++ /dev/null
@@ -1,40 +0,0 @@
-/*
-** $Id: ldebug.h,v 2.12 2014/11/10 14:46:05 roberto Exp $
-** Auxiliary functions from Debug Interface module
-** See Copyright Notice in lua.h
-*/
-
-#ifndef ldebug_h
-#define ldebug_h
-
-
-#include "lstate.h"
-
-
-#define pcRel(pc, p) (cast(int, (pc) - (p)->code) - 1)
-
-#define getfuncline(f,pc) (((f)->lineinfo) ? (f)->lineinfo[pc] : -1)
-
-#define resethookcount(L) (L->hookcount = L->basehookcount)
-
-/* Active Lua function (given call info) */
-#define ci_func(ci) (clLvalue((ci)->func))
-
-
-LUAI_FUNC l_noret luaG_typeerror (lua_State *L, const TValue *o,
- const char *opname);
-LUAI_FUNC l_noret luaG_concaterror (lua_State *L, const TValue *p1,
- const TValue *p2);
-LUAI_FUNC l_noret luaG_opinterror (lua_State *L, const TValue *p1,
- const TValue *p2,
- const char *msg);
-LUAI_FUNC l_noret luaG_tointerror (lua_State *L, const TValue *p1,
- const TValue *p2);
-LUAI_FUNC l_noret luaG_ordererror (lua_State *L, const TValue *p1,
- const TValue *p2);
-LUAI_FUNC l_noret luaG_runerror (lua_State *L, const char *fmt, ...);
-LUAI_FUNC l_noret luaG_errormsg (lua_State *L);
-LUAI_FUNC void luaG_traceexec (lua_State *L);
-
-
-#endif
diff --git a/3rd/lua/src/ldo.c b/3rd/lua/src/ldo.c
deleted file mode 100644
index 6159e51..0000000
--- a/3rd/lua/src/ldo.c
+++ /dev/null
@@ -1,717 +0,0 @@
-/*
-** $Id: ldo.c,v 2.135 2014/11/11 17:13:39 roberto Exp $
-** Stack and Call structure of Lua
-** See Copyright Notice in lua.h
-*/
-
-#define ldo_c
-#define LUA_CORE
-
-#include "lprefix.h"
-
-
-#include
-#include
-#include
-
-#include "lua.h"
-
-#include "lapi.h"
-#include "ldebug.h"
-#include "ldo.h"
-#include "lfunc.h"
-#include "lgc.h"
-#include "lmem.h"
-#include "lobject.h"
-#include "lopcodes.h"
-#include "lparser.h"
-#include "lstate.h"
-#include "lstring.h"
-#include "ltable.h"
-#include "ltm.h"
-#include "lundump.h"
-#include "lvm.h"
-#include "lzio.h"
-
-
-
-#define errorstatus(s) ((s) > LUA_YIELD)
-
-
-/*
-** {======================================================
-** Error-recovery functions
-** =======================================================
-*/
-
-/*
-** LUAI_THROW/LUAI_TRY define how Lua does exception handling. By
-** default, Lua handles errors with exceptions when compiling as
-** C++ code, with _longjmp/_setjmp when asked to use them, and with
-** longjmp/setjmp otherwise.
-*/
-#if !defined(LUAI_THROW) /* { */
-
-#if defined(__cplusplus) && !defined(LUA_USE_LONGJMP) /* { */
-
-/* C++ exceptions */
-#define LUAI_THROW(L,c) throw(c)
-#define LUAI_TRY(L,c,a) \
- try { a } catch(...) { if ((c)->status == 0) (c)->status = -1; }
-#define luai_jmpbuf int /* dummy variable */
-
-#elif defined(LUA_USE_POSIX) /* }{ */
-
-/* in POSIX, try _longjmp/_setjmp (more efficient) */
-#define LUAI_THROW(L,c) _longjmp((c)->b, 1)
-#define LUAI_TRY(L,c,a) if (_setjmp((c)->b) == 0) { a }
-#define luai_jmpbuf jmp_buf
-
-#else /* }{ */
-
-/* ISO C handling with long jumps */
-#define LUAI_THROW(L,c) longjmp((c)->b, 1)
-#define LUAI_TRY(L,c,a) if (setjmp((c)->b) == 0) { a }
-#define luai_jmpbuf jmp_buf
-
-#endif /* } */
-
-#endif /* } */
-
-
-
-/* chain list of long jump buffers */
-struct lua_longjmp {
- struct lua_longjmp *previous;
- luai_jmpbuf b;
- volatile int status; /* error code */
-};
-
-
-static void seterrorobj (lua_State *L, int errcode, StkId oldtop) {
- switch (errcode) {
- case LUA_ERRMEM: { /* memory error? */
- setsvalue2s(L, oldtop, G(L)->memerrmsg); /* reuse preregistered msg. */
- break;
- }
- case LUA_ERRERR: {
- setsvalue2s(L, oldtop, luaS_newliteral(L, "error in error handling"));
- break;
- }
- default: {
- setobjs2s(L, oldtop, L->top - 1); /* error message on current top */
- break;
- }
- }
- L->top = oldtop + 1;
-}
-
-
-l_noret luaD_throw (lua_State *L, int errcode) {
- if (L->errorJmp) { /* thread has an error handler? */
- L->errorJmp->status = errcode; /* set status */
- LUAI_THROW(L, L->errorJmp); /* jump to it */
- }
- else { /* thread has no error handler */
- global_State *g = G(L);
- L->status = cast_byte(errcode); /* mark it as dead */
- if (g->mainthread->errorJmp) { /* main thread has a handler? */
- setobjs2s(L, g->mainthread->top++, L->top - 1); /* copy error obj. */
- luaD_throw(g->mainthread, errcode); /* re-throw in main thread */
- }
- else { /* no handler at all; abort */
- if (g->panic) { /* panic function? */
- seterrorobj(L, errcode, L->top); /* assume EXTRA_STACK */
- if (L->ci->top < L->top)
- L->ci->top = L->top; /* pushing msg. can break this invariant */
- lua_unlock(L);
- g->panic(L); /* call panic function (last chance to jump out) */
- }
- abort();
- }
- }
-}
-
-
-int luaD_rawrunprotected (lua_State *L, Pfunc f, void *ud) {
- unsigned short oldnCcalls = L->nCcalls;
- struct lua_longjmp lj;
- lj.status = LUA_OK;
- lj.previous = L->errorJmp; /* chain new error handler */
- L->errorJmp = &lj;
- LUAI_TRY(L, &lj,
- (*f)(L, ud);
- );
- L->errorJmp = lj.previous; /* restore old error handler */
- L->nCcalls = oldnCcalls;
- return lj.status;
-}
-
-/* }====================================================== */
-
-
-static void correctstack (lua_State *L, TValue *oldstack) {
- CallInfo *ci;
- UpVal *up;
- L->top = (L->top - oldstack) + L->stack;
- for (up = L->openupval; up != NULL; up = up->u.open.next)
- up->v = (up->v - oldstack) + L->stack;
- for (ci = L->ci; ci != NULL; ci = ci->previous) {
- ci->top = (ci->top - oldstack) + L->stack;
- ci->func = (ci->func - oldstack) + L->stack;
- if (isLua(ci))
- ci->u.l.base = (ci->u.l.base - oldstack) + L->stack;
- }
-}
-
-
-/* some space for error handling */
-#define ERRORSTACKSIZE (LUAI_MAXSTACK + 200)
-
-
-void luaD_reallocstack (lua_State *L, int newsize) {
- TValue *oldstack = L->stack;
- int lim = L->stacksize;
- lua_assert(newsize <= LUAI_MAXSTACK || newsize == ERRORSTACKSIZE);
- lua_assert(L->stack_last - L->stack == L->stacksize - EXTRA_STACK);
- luaM_reallocvector(L, L->stack, L->stacksize, newsize, TValue);
- for (; lim < newsize; lim++)
- setnilvalue(L->stack + lim); /* erase new segment */
- L->stacksize = newsize;
- L->stack_last = L->stack + newsize - EXTRA_STACK;
- correctstack(L, oldstack);
-}
-
-
-void luaD_growstack (lua_State *L, int n) {
- int size = L->stacksize;
- if (size > LUAI_MAXSTACK) /* error after extra size? */
- luaD_throw(L, LUA_ERRERR);
- else {
- int needed = cast_int(L->top - L->stack) + n + EXTRA_STACK;
- int newsize = 2 * size;
- if (newsize > LUAI_MAXSTACK) newsize = LUAI_MAXSTACK;
- if (newsize < needed) newsize = needed;
- if (newsize > LUAI_MAXSTACK) { /* stack overflow? */
- luaD_reallocstack(L, ERRORSTACKSIZE);
- luaG_runerror(L, "stack overflow");
- }
- else
- luaD_reallocstack(L, newsize);
- }
-}
-
-
-static int stackinuse (lua_State *L) {
- CallInfo *ci;
- StkId lim = L->top;
- for (ci = L->ci; ci != NULL; ci = ci->previous) {
- lua_assert(ci->top <= L->stack_last);
- if (lim < ci->top) lim = ci->top;
- }
- return cast_int(lim - L->stack) + 1; /* part of stack in use */
-}
-
-
-void luaD_shrinkstack (lua_State *L) {
- int inuse = stackinuse(L);
- int goodsize = inuse + (inuse / 8) + 2*EXTRA_STACK;
- if (goodsize > LUAI_MAXSTACK) goodsize = LUAI_MAXSTACK;
- if (L->stacksize > LUAI_MAXSTACK) /* was handling stack overflow? */
- luaE_freeCI(L); /* free all CIs (list grew because of an error) */
- else
- luaE_shrinkCI(L); /* shrink list */
- if (inuse > LUAI_MAXSTACK || /* still handling stack overflow? */
- goodsize >= L->stacksize) /* would grow instead of shrink? */
- condmovestack(L); /* don't change stack (change only for debugging) */
- else
- luaD_reallocstack(L, goodsize); /* shrink it */
-}
-
-
-void luaD_hook (lua_State *L, int event, int line) {
- lua_Hook hook = L->hook;
- if (hook && L->allowhook) {
- CallInfo *ci = L->ci;
- ptrdiff_t top = savestack(L, L->top);
- ptrdiff_t ci_top = savestack(L, ci->top);
- lua_Debug ar;
- ar.event = event;
- ar.currentline = line;
- ar.i_ci = ci;
- luaD_checkstack(L, LUA_MINSTACK); /* ensure minimum stack size */
- ci->top = L->top + LUA_MINSTACK;
- lua_assert(ci->top <= L->stack_last);
- L->allowhook = 0; /* cannot call hooks inside a hook */
- ci->callstatus |= CIST_HOOKED;
- lua_unlock(L);
- (*hook)(L, &ar);
- lua_lock(L);
- lua_assert(!L->allowhook);
- L->allowhook = 1;
- ci->top = restorestack(L, ci_top);
- L->top = restorestack(L, top);
- ci->callstatus &= ~CIST_HOOKED;
- }
-}
-
-
-static void callhook (lua_State *L, CallInfo *ci) {
- int hook = LUA_HOOKCALL;
- ci->u.l.savedpc++; /* hooks assume 'pc' is already incremented */
- if (isLua(ci->previous) &&
- GET_OPCODE(*(ci->previous->u.l.savedpc - 1)) == OP_TAILCALL) {
- ci->callstatus |= CIST_TAIL;
- hook = LUA_HOOKTAILCALL;
- }
- luaD_hook(L, hook, -1);
- ci->u.l.savedpc--; /* correct 'pc' */
-}
-
-
-static StkId adjust_varargs (lua_State *L, Proto *p, int actual) {
- int i;
- int nfixargs = p->numparams;
- StkId base, fixed;
- lua_assert(actual >= nfixargs);
- /* move fixed parameters to final position */
- luaD_checkstack(L, p->maxstacksize); /* check again for new 'base' */
- fixed = L->top - actual; /* first fixed argument */
- base = L->top; /* final position of first argument */
- for (i=0; itop++, fixed + i);
- setnilvalue(fixed + i);
- }
- return base;
-}
-
-
-/*
-** Check whether __call metafield of 'func' is a function. If so, put
-** it in stack below original 'func' so that 'luaD_precall' can call
-** it. Raise an error if __call metafield is not a function.
-*/
-static void tryfuncTM (lua_State *L, StkId func) {
- const TValue *tm = luaT_gettmbyobj(L, func, TM_CALL);
- StkId p;
- if (!ttisfunction(tm))
- luaG_typeerror(L, func, "call");
- /* Open a hole inside the stack at 'func' */
- for (p = L->top; p > func; p--)
- setobjs2s(L, p, p-1);
- L->top++; /* slot ensured by caller */
- setobj2s(L, func, tm); /* tag method is the new function to be called */
-}
-
-
-
-#define next_ci(L) (L->ci = (L->ci->next ? L->ci->next : luaE_extendCI(L)))
-
-
-/*
-** returns true if function has been executed (C function)
-*/
-int luaD_precall (lua_State *L, StkId func, int nresults) {
- lua_CFunction f;
- CallInfo *ci;
- int n; /* number of arguments (Lua) or returns (C) */
- ptrdiff_t funcr = savestack(L, func);
- switch (ttype(func)) {
- case LUA_TLCF: /* light C function */
- f = fvalue(func);
- goto Cfunc;
- case LUA_TCCL: { /* C closure */
- f = clCvalue(func)->f;
- Cfunc:
- luaD_checkstack(L, LUA_MINSTACK); /* ensure minimum stack size */
- ci = next_ci(L); /* now 'enter' new function */
- ci->nresults = nresults;
- ci->func = restorestack(L, funcr);
- ci->top = L->top + LUA_MINSTACK;
- lua_assert(ci->top <= L->stack_last);
- ci->callstatus = 0;
- luaC_checkGC(L); /* stack grow uses memory */
- if (L->hookmask & LUA_MASKCALL)
- luaD_hook(L, LUA_HOOKCALL, -1);
- lua_unlock(L);
- n = (*f)(L); /* do the actual call */
- lua_lock(L);
- api_checknelems(L, n);
- luaD_poscall(L, L->top - n);
- return 1;
- }
- case LUA_TLCL: { /* Lua function: prepare its call */
- StkId base;
- Proto *p = clLvalue(func)->p;
- n = cast_int(L->top - func) - 1; /* number of real arguments */
- luaD_checkstack(L, p->maxstacksize);
- for (; n < p->numparams; n++)
- setnilvalue(L->top++); /* complete missing arguments */
- if (!p->is_vararg) {
- func = restorestack(L, funcr);
- base = func + 1;
- }
- else {
- base = adjust_varargs(L, p, n);
- func = restorestack(L, funcr); /* previous call can change stack */
- }
- ci = next_ci(L); /* now 'enter' new function */
- ci->nresults = nresults;
- ci->func = func;
- ci->u.l.base = base;
- ci->top = base + p->maxstacksize;
- lua_assert(ci->top <= L->stack_last);
- ci->u.l.savedpc = p->code; /* starting point */
- ci->callstatus = CIST_LUA;
- L->top = ci->top;
- luaC_checkGC(L); /* stack grow uses memory */
- if (L->hookmask & LUA_MASKCALL)
- callhook(L, ci);
- return 0;
- }
- default: { /* not a function */
- luaD_checkstack(L, 1); /* ensure space for metamethod */
- func = restorestack(L, funcr); /* previous call may change stack */
- tryfuncTM(L, func); /* try to get '__call' metamethod */
- return luaD_precall(L, func, nresults); /* now it must be a function */
- }
- }
-}
-
-
-int luaD_poscall (lua_State *L, StkId firstResult) {
- StkId res;
- int wanted, i;
- CallInfo *ci = L->ci;
- if (L->hookmask & (LUA_MASKRET | LUA_MASKLINE)) {
- if (L->hookmask & LUA_MASKRET) {
- ptrdiff_t fr = savestack(L, firstResult); /* hook may change stack */
- luaD_hook(L, LUA_HOOKRET, -1);
- firstResult = restorestack(L, fr);
- }
- L->oldpc = ci->previous->u.l.savedpc; /* 'oldpc' for caller function */
- }
- res = ci->func; /* res == final position of 1st result */
- wanted = ci->nresults;
- L->ci = ci = ci->previous; /* back to caller */
- /* move results to correct place */
- for (i = wanted; i != 0 && firstResult < L->top; i--)
- setobjs2s(L, res++, firstResult++);
- while (i-- > 0)
- setnilvalue(res++);
- L->top = res;
- return (wanted - LUA_MULTRET); /* 0 iff wanted == LUA_MULTRET */
-}
-
-
-/*
-** Call a function (C or Lua). The function to be called is at *func.
-** The arguments are on the stack, right after the function.
-** When returns, all the results are on the stack, starting at the original
-** function position.
-*/
-void luaD_call (lua_State *L, StkId func, int nResults, int allowyield) {
- if (++L->nCcalls >= LUAI_MAXCCALLS) {
- if (L->nCcalls == LUAI_MAXCCALLS)
- luaG_runerror(L, "C stack overflow");
- else if (L->nCcalls >= (LUAI_MAXCCALLS + (LUAI_MAXCCALLS>>3)))
- luaD_throw(L, LUA_ERRERR); /* error while handing stack error */
- }
- if (!allowyield) L->nny++;
- if (!luaD_precall(L, func, nResults)) /* is a Lua function? */
- luaV_execute(L); /* call it */
- if (!allowyield) L->nny--;
- L->nCcalls--;
-}
-
-
-/*
-** Completes the execution of an interrupted C function, calling its
-** continuation function.
-*/
-static void finishCcall (lua_State *L, int status) {
- CallInfo *ci = L->ci;
- int n;
- /* must have a continuation and must be able to call it */
- lua_assert(ci->u.c.k != NULL && L->nny == 0);
- /* error status can only happen in a protected call */
- lua_assert((ci->callstatus & CIST_YPCALL) || status == LUA_YIELD);
- if (ci->callstatus & CIST_YPCALL) { /* was inside a pcall? */
- ci->callstatus &= ~CIST_YPCALL; /* finish 'lua_pcall' */
- L->errfunc = ci->u.c.old_errfunc;
- }
- /* finish 'lua_callk'/'lua_pcall'; CIST_YPCALL and 'errfunc' already
- handled */
- adjustresults(L, ci->nresults);
- /* call continuation function */
- lua_unlock(L);
- n = (*ci->u.c.k)(L, status, ci->u.c.ctx);
- lua_lock(L);
- api_checknelems(L, n);
- /* finish 'luaD_precall' */
- luaD_poscall(L, L->top - n);
-}
-
-
-/*
-** Executes "full continuation" (everything in the stack) of a
-** previously interrupted coroutine until the stack is empty (or another
-** interruption long-jumps out of the loop). If the coroutine is
-** recovering from an error, 'ud' points to the error status, which must
-** be passed to the first continuation function (otherwise the default
-** status is LUA_YIELD).
-*/
-static void unroll (lua_State *L, void *ud) {
- if (ud != NULL) /* error status? */
- finishCcall(L, *(int *)ud); /* finish 'lua_pcallk' callee */
- while (L->ci != &L->base_ci) { /* something in the stack */
- if (!isLua(L->ci)) /* C function? */
- finishCcall(L, LUA_YIELD); /* complete its execution */
- else { /* Lua function */
- luaV_finishOp(L); /* finish interrupted instruction */
- luaV_execute(L); /* execute down to higher C 'boundary' */
- }
- }
-}
-
-
-/*
-** Try to find a suspended protected call (a "recover point") for the
-** given thread.
-*/
-static CallInfo *findpcall (lua_State *L) {
- CallInfo *ci;
- for (ci = L->ci; ci != NULL; ci = ci->previous) { /* search for a pcall */
- if (ci->callstatus & CIST_YPCALL)
- return ci;
- }
- return NULL; /* no pending pcall */
-}
-
-
-/*
-** Recovers from an error in a coroutine. Finds a recover point (if
-** there is one) and completes the execution of the interrupted
-** 'luaD_pcall'. If there is no recover point, returns zero.
-*/
-static int recover (lua_State *L, int status) {
- StkId oldtop;
- CallInfo *ci = findpcall(L);
- if (ci == NULL) return 0; /* no recovery point */
- /* "finish" luaD_pcall */
- oldtop = restorestack(L, ci->extra);
- luaF_close(L, oldtop);
- seterrorobj(L, status, oldtop);
- L->ci = ci;
- L->allowhook = getoah(ci->callstatus); /* restore original 'allowhook' */
- L->nny = 0; /* should be zero to be yieldable */
- luaD_shrinkstack(L);
- L->errfunc = ci->u.c.old_errfunc;
- return 1; /* continue running the coroutine */
-}
-
-
-/*
-** signal an error in the call to 'resume', not in the execution of the
-** coroutine itself. (Such errors should not be handled by any coroutine
-** error handler and should not kill the coroutine.)
-*/
-static l_noret resume_error (lua_State *L, const char *msg, StkId firstArg) {
- L->top = firstArg; /* remove args from the stack */
- setsvalue2s(L, L->top, luaS_new(L, msg)); /* push error message */
- api_incr_top(L);
- luaD_throw(L, -1); /* jump back to 'lua_resume' */
-}
-
-
-/*
-** Do the work for 'lua_resume' in protected mode. Most of the work
-** depends on the status of the coroutine: initial state, suspended
-** inside a hook, or regularly suspended (optionally with a continuation
-** function), plus erroneous cases: non-suspended coroutine or dead
-** coroutine.
-*/
-static void resume (lua_State *L, void *ud) {
- int nCcalls = L->nCcalls;
- StkId firstArg = cast(StkId, ud);
- CallInfo *ci = L->ci;
- if (nCcalls >= LUAI_MAXCCALLS)
- resume_error(L, "C stack overflow", firstArg);
- if (L->status == LUA_OK) { /* may be starting a coroutine */
- if (ci != &L->base_ci) /* not in base level? */
- resume_error(L, "cannot resume non-suspended coroutine", firstArg);
- /* coroutine is in base level; start running it */
- if (!luaD_precall(L, firstArg - 1, LUA_MULTRET)) /* Lua function? */
- luaV_execute(L); /* call it */
- }
- else if (L->status != LUA_YIELD)
- resume_error(L, "cannot resume dead coroutine", firstArg);
- else { /* resuming from previous yield */
- L->status = LUA_OK; /* mark that it is running (again) */
- ci->func = restorestack(L, ci->extra);
- if (isLua(ci)) /* yielded inside a hook? */
- luaV_execute(L); /* just continue running Lua code */
- else { /* 'common' yield */
- if (ci->u.c.k != NULL) { /* does it have a continuation function? */
- int n;
- lua_unlock(L);
- n = (*ci->u.c.k)(L, LUA_YIELD, ci->u.c.ctx); /* call continuation */
- lua_lock(L);
- api_checknelems(L, n);
- firstArg = L->top - n; /* yield results come from continuation */
- }
- luaD_poscall(L, firstArg); /* finish 'luaD_precall' */
- }
- unroll(L, NULL); /* run continuation */
- }
- lua_assert(nCcalls == L->nCcalls);
-}
-
-
-LUA_API int lua_resume (lua_State *L, lua_State *from, int nargs) {
- int status;
- int oldnny = L->nny; /* save "number of non-yieldable" calls */
- lua_lock(L);
- luai_userstateresume(L, nargs);
- L->nCcalls = (from) ? from->nCcalls + 1 : 1;
- L->nny = 0; /* allow yields */
- api_checknelems(L, (L->status == LUA_OK) ? nargs + 1 : nargs);
- status = luaD_rawrunprotected(L, resume, L->top - nargs);
- if (status == -1) /* error calling 'lua_resume'? */
- status = LUA_ERRRUN;
- else { /* continue running after recoverable errors */
- while (errorstatus(status) && recover(L, status)) {
- /* unroll continuation */
- status = luaD_rawrunprotected(L, unroll, &status);
- }
- if (errorstatus(status)) { /* unrecoverable error? */
- L->status = cast_byte(status); /* mark thread as 'dead' */
- seterrorobj(L, status, L->top); /* push error message */
- L->ci->top = L->top;
- }
- else lua_assert(status == L->status); /* normal end or yield */
- }
- L->nny = oldnny; /* restore 'nny' */
- L->nCcalls--;
- lua_assert(L->nCcalls == ((from) ? from->nCcalls : 0));
- lua_unlock(L);
- return status;
-}
-
-
-LUA_API int lua_isyieldable (lua_State *L) {
- return (L->nny == 0);
-}
-
-
-LUA_API int lua_yieldk (lua_State *L, int nresults, lua_KContext ctx,
- lua_KFunction k) {
- CallInfo *ci = L->ci;
- luai_userstateyield(L, nresults);
- lua_lock(L);
- api_checknelems(L, nresults);
- if (L->nny > 0) {
- if (L != G(L)->mainthread)
- luaG_runerror(L, "attempt to yield across a C-call boundary");
- else
- luaG_runerror(L, "attempt to yield from outside a coroutine");
- }
- L->status = LUA_YIELD;
- ci->extra = savestack(L, ci->func); /* save current 'func' */
- if (isLua(ci)) { /* inside a hook? */
- api_check(k == NULL, "hooks cannot continue after yielding");
- }
- else {
- if ((ci->u.c.k = k) != NULL) /* is there a continuation? */
- ci->u.c.ctx = ctx; /* save context */
- ci->func = L->top - nresults - 1; /* protect stack below results */
- luaD_throw(L, LUA_YIELD);
- }
- lua_assert(ci->callstatus & CIST_HOOKED); /* must be inside a hook */
- lua_unlock(L);
- return 0; /* return to 'luaD_hook' */
-}
-
-
-int luaD_pcall (lua_State *L, Pfunc func, void *u,
- ptrdiff_t old_top, ptrdiff_t ef) {
- int status;
- CallInfo *old_ci = L->ci;
- lu_byte old_allowhooks = L->allowhook;
- unsigned short old_nny = L->nny;
- ptrdiff_t old_errfunc = L->errfunc;
- L->errfunc = ef;
- status = luaD_rawrunprotected(L, func, u);
- if (status != LUA_OK) { /* an error occurred? */
- StkId oldtop = restorestack(L, old_top);
- luaF_close(L, oldtop); /* close possible pending closures */
- seterrorobj(L, status, oldtop);
- L->ci = old_ci;
- L->allowhook = old_allowhooks;
- L->nny = old_nny;
- luaD_shrinkstack(L);
- }
- L->errfunc = old_errfunc;
- return status;
-}
-
-
-
-/*
-** Execute a protected parser.
-*/
-struct SParser { /* data to 'f_parser' */
- ZIO *z;
- Mbuffer buff; /* dynamic structure used by the scanner */
- Dyndata dyd; /* dynamic structures used by the parser */
- const char *mode;
- const char *name;
-};
-
-
-static void checkmode (lua_State *L, const char *mode, const char *x) {
- if (mode && strchr(mode, x[0]) == NULL) {
- luaO_pushfstring(L,
- "attempt to load a %s chunk (mode is '%s')", x, mode);
- luaD_throw(L, LUA_ERRSYNTAX);
- }
-}
-
-
-static void f_parser (lua_State *L, void *ud) {
- LClosure *cl;
- struct SParser *p = cast(struct SParser *, ud);
- int c = zgetc(p->z); /* read first character */
- if (c == LUA_SIGNATURE[0]) {
- checkmode(L, p->mode, "binary");
- cl = luaU_undump(L, p->z, &p->buff, p->name);
- }
- else {
- checkmode(L, p->mode, "text");
- cl = luaY_parser(L, p->z, &p->buff, &p->dyd, p->name, c);
- }
- lua_assert(cl->nupvalues == cl->p->sizeupvalues);
- luaF_initupvals(L, cl);
-}
-
-
-int luaD_protectedparser (lua_State *L, ZIO *z, const char *name,
- const char *mode) {
- struct SParser p;
- int status;
- L->nny++; /* cannot yield during parsing */
- p.z = z; p.name = name; p.mode = mode;
- p.dyd.actvar.arr = NULL; p.dyd.actvar.size = 0;
- p.dyd.gt.arr = NULL; p.dyd.gt.size = 0;
- p.dyd.label.arr = NULL; p.dyd.label.size = 0;
- luaZ_initbuffer(L, &p.buff);
- status = luaD_pcall(L, f_parser, &p, savestack(L, L->top), L->errfunc);
- luaZ_freebuffer(L, &p.buff);
- luaM_freearray(L, p.dyd.actvar.arr, p.dyd.actvar.size);
- luaM_freearray(L, p.dyd.gt.arr, p.dyd.gt.size);
- luaM_freearray(L, p.dyd.label.arr, p.dyd.label.size);
- L->nny--;
- return status;
-}
-
-
diff --git a/3rd/lua/src/ldo.h b/3rd/lua/src/ldo.h
deleted file mode 100644
index 05745c8..0000000
--- a/3rd/lua/src/ldo.h
+++ /dev/null
@@ -1,46 +0,0 @@
-/*
-** $Id: ldo.h,v 2.21 2014/10/25 11:50:46 roberto Exp $
-** Stack and Call structure of Lua
-** See Copyright Notice in lua.h
-*/
-
-#ifndef ldo_h
-#define ldo_h
-
-
-#include "lobject.h"
-#include "lstate.h"
-#include "lzio.h"
-
-
-#define luaD_checkstack(L,n) if (L->stack_last - L->top <= (n)) \
- luaD_growstack(L, n); else condmovestack(L);
-
-
-#define incr_top(L) {L->top++; luaD_checkstack(L,0);}
-
-#define savestack(L,p) ((char *)(p) - (char *)L->stack)
-#define restorestack(L,n) ((TValue *)((char *)L->stack + (n)))
-
-
-/* type of protected functions, to be ran by 'runprotected' */
-typedef void (*Pfunc) (lua_State *L, void *ud);
-
-LUAI_FUNC int luaD_protectedparser (lua_State *L, ZIO *z, const char *name,
- const char *mode);
-LUAI_FUNC void luaD_hook (lua_State *L, int event, int line);
-LUAI_FUNC int luaD_precall (lua_State *L, StkId func, int nresults);
-LUAI_FUNC void luaD_call (lua_State *L, StkId func, int nResults,
- int allowyield);
-LUAI_FUNC int luaD_pcall (lua_State *L, Pfunc func, void *u,
- ptrdiff_t oldtop, ptrdiff_t ef);
-LUAI_FUNC int luaD_poscall (lua_State *L, StkId firstResult);
-LUAI_FUNC void luaD_reallocstack (lua_State *L, int newsize);
-LUAI_FUNC void luaD_growstack (lua_State *L, int n);
-LUAI_FUNC void luaD_shrinkstack (lua_State *L);
-
-LUAI_FUNC l_noret luaD_throw (lua_State *L, int errcode);
-LUAI_FUNC int luaD_rawrunprotected (lua_State *L, Pfunc f, void *ud);
-
-#endif
-
diff --git a/3rd/lua/src/ldump.c b/3rd/lua/src/ldump.c
deleted file mode 100644
index b6c7114..0000000
--- a/3rd/lua/src/ldump.c
+++ /dev/null
@@ -1,214 +0,0 @@
-/*
-** $Id: ldump.c,v 2.34 2014/11/02 19:19:04 roberto Exp $
-** save precompiled Lua chunks
-** See Copyright Notice in lua.h
-*/
-
-#define ldump_c
-#define LUA_CORE
-
-#include "lprefix.h"
-
-
-#include
-
-#include "lua.h"
-
-#include "lobject.h"
-#include "lstate.h"
-#include "lundump.h"
-
-
-typedef struct {
- lua_State *L;
- lua_Writer writer;
- void *data;
- int strip;
- int status;
-} DumpState;
-
-
-/*
-** All high-level dumps go through DumpVector; you can change it to
-** change the endianness of the result
-*/
-#define DumpVector(v,n,D) DumpBlock(v,(n)*sizeof((v)[0]),D)
-
-#define DumpLiteral(s,D) DumpBlock(s, sizeof(s) - sizeof(char), D)
-
-
-static void DumpBlock (const void *b, size_t size, DumpState *D) {
- if (D->status == 0) {
- lua_unlock(D->L);
- D->status = (*D->writer)(D->L, b, size, D->data);
- lua_lock(D->L);
- }
-}
-
-
-#define DumpVar(x,D) DumpVector(&x,1,D)
-
-
-static void DumpByte (int y, DumpState *D) {
- lu_byte x = (lu_byte)y;
- DumpVar(x, D);
-}
-
-
-static void DumpInt (int x, DumpState *D) {
- DumpVar(x, D);
-}
-
-
-static void DumpNumber (lua_Number x, DumpState *D) {
- DumpVar(x, D);
-}
-
-
-static void DumpInteger (lua_Integer x, DumpState *D) {
- DumpVar(x, D);
-}
-
-
-static void DumpString (const TString *s, DumpState *D) {
- if (s == NULL)
- DumpByte(0, D);
- else {
- size_t size = s->len + 1; /* include trailing '\0' */
- if (size < 0xFF)
- DumpByte(cast_int(size), D);
- else {
- DumpByte(0xFF, D);
- DumpVar(size, D);
- }
- DumpVector(getstr(s), size - 1, D); /* no need to save '\0' */
- }
-}
-
-
-static void DumpCode (const Proto *f, DumpState *D) {
- DumpInt(f->sizecode, D);
- DumpVector(f->code, f->sizecode, D);
-}
-
-
-static void DumpFunction(const Proto *f, TString *psource, DumpState *D);
-
-static void DumpConstants (const Proto *f, DumpState *D) {
- int i;
- int n = f->sizek;
- DumpInt(n, D);
- for (i = 0; i < n; i++) {
- const TValue *o = &f->k[i];
- DumpByte(ttype(o), D);
- switch (ttype(o)) {
- case LUA_TNIL:
- break;
- case LUA_TBOOLEAN:
- DumpByte(bvalue(o), D);
- break;
- case LUA_TNUMFLT:
- DumpNumber(fltvalue(o), D);
- break;
- case LUA_TNUMINT:
- DumpInteger(ivalue(o), D);
- break;
- case LUA_TSHRSTR:
- case LUA_TLNGSTR:
- DumpString(tsvalue(o), D);
- break;
- default:
- lua_assert(0);
- }
- }
-}
-
-
-static void DumpProtos (const Proto *f, DumpState *D) {
- int i;
- int n = f->sizep;
- DumpInt(n, D);
- for (i = 0; i < n; i++)
- DumpFunction(f->p[i], f->source, D);
-}
-
-
-static void DumpUpvalues (const Proto *f, DumpState *D) {
- int i, n = f->sizeupvalues;
- DumpInt(n, D);
- for (i = 0; i < n; i++) {
- DumpByte(f->upvalues[i].instack, D);
- DumpByte(f->upvalues[i].idx, D);
- }
-}
-
-
-static void DumpDebug (const Proto *f, DumpState *D) {
- int i, n;
- n = (D->strip) ? 0 : f->sizelineinfo;
- DumpInt(n, D);
- DumpVector(f->lineinfo, n, D);
- n = (D->strip) ? 0 : f->sizelocvars;
- DumpInt(n, D);
- for (i = 0; i < n; i++) {
- DumpString(f->locvars[i].varname, D);
- DumpInt(f->locvars[i].startpc, D);
- DumpInt(f->locvars[i].endpc, D);
- }
- n = (D->strip) ? 0 : f->sizeupvalues;
- DumpInt(n, D);
- for (i = 0; i < n; i++)
- DumpString(f->upvalues[i].name, D);
-}
-
-
-static void DumpFunction (const Proto *f, TString *psource, DumpState *D) {
- if (D->strip || f->source == psource)
- DumpString(NULL, D); /* no debug info or same source as its parent */
- else
- DumpString(f->source, D);
- DumpInt(f->linedefined, D);
- DumpInt(f->lastlinedefined, D);
- DumpByte(f->numparams, D);
- DumpByte(f->is_vararg, D);
- DumpByte(f->maxstacksize, D);
- DumpCode(f, D);
- DumpConstants(f, D);
- DumpUpvalues(f, D);
- DumpProtos(f, D);
- DumpDebug(f, D);
-}
-
-
-static void DumpHeader (DumpState *D) {
- DumpLiteral(LUA_SIGNATURE, D);
- DumpByte(LUAC_VERSION, D);
- DumpByte(LUAC_FORMAT, D);
- DumpLiteral(LUAC_DATA, D);
- DumpByte(sizeof(int), D);
- DumpByte(sizeof(size_t), D);
- DumpByte(sizeof(Instruction), D);
- DumpByte(sizeof(lua_Integer), D);
- DumpByte(sizeof(lua_Number), D);
- DumpInteger(LUAC_INT, D);
- DumpNumber(LUAC_NUM, D);
-}
-
-
-/*
-** dump Lua function as precompiled chunk
-*/
-int luaU_dump(lua_State *L, const Proto *f, lua_Writer w, void *data,
- int strip) {
- DumpState D;
- D.L = L;
- D.writer = w;
- D.data = data;
- D.strip = strip;
- D.status = 0;
- DumpHeader(&D);
- DumpByte(f->sizeupvalues, &D);
- DumpFunction(f, NULL, &D);
- return D.status;
-}
-
diff --git a/3rd/lua/src/lfunc.c b/3rd/lua/src/lfunc.c
deleted file mode 100644
index 67967da..0000000
--- a/3rd/lua/src/lfunc.c
+++ /dev/null
@@ -1,151 +0,0 @@
-/*
-** $Id: lfunc.c,v 2.45 2014/11/02 19:19:04 roberto Exp $
-** Auxiliary functions to manipulate prototypes and closures
-** See Copyright Notice in lua.h
-*/
-
-#define lfunc_c
-#define LUA_CORE
-
-#include "lprefix.h"
-
-
-#include
-
-#include "lua.h"
-
-#include "lfunc.h"
-#include "lgc.h"
-#include "lmem.h"
-#include "lobject.h"
-#include "lstate.h"
-
-
-
-CClosure *luaF_newCclosure (lua_State *L, int n) {
- GCObject *o = luaC_newobj(L, LUA_TCCL, sizeCclosure(n));
- CClosure *c = gco2ccl(o);
- c->nupvalues = cast_byte(n);
- return c;
-}
-
-
-LClosure *luaF_newLclosure (lua_State *L, int n) {
- GCObject *o = luaC_newobj(L, LUA_TLCL, sizeLclosure(n));
- LClosure *c = gco2lcl(o);
- c->p = NULL;
- c->nupvalues = cast_byte(n);
- while (n--) c->upvals[n] = NULL;
- return c;
-}
-
-/*
-** fill a closure with new closed upvalues
-*/
-void luaF_initupvals (lua_State *L, LClosure *cl) {
- int i;
- for (i = 0; i < cl->nupvalues; i++) {
- UpVal *uv = luaM_new(L, UpVal);
- uv->refcount = 1;
- uv->v = &uv->u.value; /* make it closed */
- setnilvalue(uv->v);
- cl->upvals[i] = uv;
- }
-}
-
-
-UpVal *luaF_findupval (lua_State *L, StkId level) {
- UpVal **pp = &L->openupval;
- UpVal *p;
- UpVal *uv;
- lua_assert(isintwups(L) || L->openupval == NULL);
- while (*pp != NULL && (p = *pp)->v >= level) {
- lua_assert(upisopen(p));
- if (p->v == level) /* found a corresponding upvalue? */
- return p; /* return it */
- pp = &p->u.open.next;
- }
- /* not found: create a new upvalue */
- uv = luaM_new(L, UpVal);
- uv->refcount = 0;
- uv->u.open.next = *pp; /* link it to list of open upvalues */
- uv->u.open.touched = 1;
- *pp = uv;
- uv->v = level; /* current value lives in the stack */
- if (!isintwups(L)) { /* thread not in list of threads with upvalues? */
- L->twups = G(L)->twups; /* link it to the list */
- G(L)->twups = L;
- }
- return uv;
-}
-
-
-void luaF_close (lua_State *L, StkId level) {
- UpVal *uv;
- while (L->openupval != NULL && (uv = L->openupval)->v >= level) {
- lua_assert(upisopen(uv));
- L->openupval = uv->u.open.next; /* remove from 'open' list */
- if (uv->refcount == 0) /* no references? */
- luaM_free(L, uv); /* free upvalue */
- else {
- setobj(L, &uv->u.value, uv->v); /* move value to upvalue slot */
- uv->v = &uv->u.value; /* now current value lives here */
- luaC_upvalbarrier(L, uv);
- }
- }
-}
-
-
-Proto *luaF_newproto (lua_State *L) {
- GCObject *o = luaC_newobj(L, LUA_TPROTO, sizeof(Proto));
- Proto *f = gco2p(o);
- f->k = NULL;
- f->sizek = 0;
- f->p = NULL;
- f->sizep = 0;
- f->code = NULL;
- f->cache = NULL;
- f->sizecode = 0;
- f->lineinfo = NULL;
- f->sizelineinfo = 0;
- f->upvalues = NULL;
- f->sizeupvalues = 0;
- f->numparams = 0;
- f->is_vararg = 0;
- f->maxstacksize = 0;
- f->locvars = NULL;
- f->sizelocvars = 0;
- f->linedefined = 0;
- f->lastlinedefined = 0;
- f->source = NULL;
- return f;
-}
-
-
-void luaF_freeproto (lua_State *L, Proto *f) {
- luaM_freearray(L, f->code, f->sizecode);
- luaM_freearray(L, f->p, f->sizep);
- luaM_freearray(L, f->k, f->sizek);
- luaM_freearray(L, f->lineinfo, f->sizelineinfo);
- luaM_freearray(L, f->locvars, f->sizelocvars);
- luaM_freearray(L, f->upvalues, f->sizeupvalues);
- luaM_free(L, f);
-}
-
-
-/*
-** Look for n-th local variable at line 'line' in function 'func'.
-** Returns NULL if not found.
-*/
-const char *luaF_getlocalname (const Proto *f, int local_number, int pc) {
- int i;
- for (i = 0; isizelocvars && f->locvars[i].startpc <= pc; i++) {
- if (pc < f->locvars[i].endpc) { /* is variable active? */
- local_number--;
- if (local_number == 0)
- return getstr(f->locvars[i].varname);
- }
- }
- return NULL; /* not found */
-}
-
diff --git a/3rd/lua/src/lfunc.h b/3rd/lua/src/lfunc.h
deleted file mode 100644
index 256d3cf..0000000
--- a/3rd/lua/src/lfunc.h
+++ /dev/null
@@ -1,54 +0,0 @@
-/*
-** $Id: lfunc.h,v 2.14 2014/06/19 18:27:20 roberto Exp $
-** Auxiliary functions to manipulate prototypes and closures
-** See Copyright Notice in lua.h
-*/
-
-#ifndef lfunc_h
-#define lfunc_h
-
-
-#include "lobject.h"
-
-
-#define sizeCclosure(n) (cast(int, sizeof(CClosure)) + \
- cast(int, sizeof(TValue)*((n)-1)))
-
-#define sizeLclosure(n) (cast(int, sizeof(LClosure)) + \
- cast(int, sizeof(TValue *)*((n)-1)))
-
-
-/* test whether thread is in 'twups' list */
-#define isintwups(L) (L->twups != L)
-
-
-/*
-** Upvalues for Lua closures
-*/
-struct UpVal {
- TValue *v; /* points to stack or to its own value */
- lu_mem refcount; /* reference counter */
- union {
- struct { /* (when open) */
- UpVal *next; /* linked list */
- int touched; /* mark to avoid cycles with dead threads */
- } open;
- TValue value; /* the value (when closed) */
- } u;
-};
-
-#define upisopen(up) ((up)->v != &(up)->u.value)
-
-
-LUAI_FUNC Proto *luaF_newproto (lua_State *L);
-LUAI_FUNC CClosure *luaF_newCclosure (lua_State *L, int nelems);
-LUAI_FUNC LClosure *luaF_newLclosure (lua_State *L, int nelems);
-LUAI_FUNC void luaF_initupvals (lua_State *L, LClosure *cl);
-LUAI_FUNC UpVal *luaF_findupval (lua_State *L, StkId level);
-LUAI_FUNC void luaF_close (lua_State *L, StkId level);
-LUAI_FUNC void luaF_freeproto (lua_State *L, Proto *f);
-LUAI_FUNC const char *luaF_getlocalname (const Proto *func, int local_number,
- int pc);
-
-
-#endif
diff --git a/3rd/lua/src/lgc.c b/3rd/lua/src/lgc.c
deleted file mode 100644
index 8b95fb6..0000000
--- a/3rd/lua/src/lgc.c
+++ /dev/null
@@ -1,1159 +0,0 @@
-/*
-** $Id: lgc.c,v 2.201 2014/12/20 13:58:15 roberto Exp $
-** Garbage Collector
-** See Copyright Notice in lua.h
-*/
-
-#define lgc_c
-#define LUA_CORE
-
-#include "lprefix.h"
-
-
-#include
-
-#include "lua.h"
-
-#include "ldebug.h"
-#include "ldo.h"
-#include "lfunc.h"
-#include "lgc.h"
-#include "lmem.h"
-#include "lobject.h"
-#include "lstate.h"
-#include "lstring.h"
-#include "ltable.h"
-#include "ltm.h"
-
-
-/*
-** internal state for collector while inside the atomic phase. The
-** collector should never be in this state while running regular code.
-*/
-#define GCSinsideatomic (GCSpause + 1)
-
-/*
-** cost of sweeping one element (the size of a small object divided
-** by some adjust for the sweep speed)
-*/
-#define GCSWEEPCOST ((sizeof(TString) + 4) / 4)
-
-/* maximum number of elements to sweep in each single step */
-#define GCSWEEPMAX (cast_int((GCSTEPSIZE / GCSWEEPCOST) / 4))
-
-/* cost of calling one finalizer */
-#define GCFINALIZECOST GCSWEEPCOST
-
-
-/*
-** macro to adjust 'stepmul': 'stepmul' is actually used like
-** 'stepmul / STEPMULADJ' (value chosen by tests)
-*/
-#define STEPMULADJ 200
-
-
-/*
-** macro to adjust 'pause': 'pause' is actually used like
-** 'pause / PAUSEADJ' (value chosen by tests)
-*/
-#define PAUSEADJ 100
-
-
-/*
-** 'makewhite' erases all color bits then sets only the current white
-** bit
-*/
-#define maskcolors (~(bitmask(BLACKBIT) | WHITEBITS))
-#define makewhite(g,x) \
- (x->marked = cast_byte((x->marked & maskcolors) | luaC_white(g)))
-
-#define white2gray(x) resetbits(x->marked, WHITEBITS)
-#define black2gray(x) resetbit(x->marked, BLACKBIT)
-
-
-#define valiswhite(x) (iscollectable(x) && iswhite(gcvalue(x)))
-
-#define checkdeadkey(n) lua_assert(!ttisdeadkey(gkey(n)) || ttisnil(gval(n)))
-
-
-#define checkconsistency(obj) \
- lua_longassert(!iscollectable(obj) || righttt(obj))
-
-
-#define markvalue(g,o) { checkconsistency(o); \
- if (valiswhite(o)) reallymarkobject(g,gcvalue(o)); }
-
-#define markobject(g,t) \
- { if ((t) && iswhite(t)) reallymarkobject(g, obj2gco(t)); }
-
-static void reallymarkobject (global_State *g, GCObject *o);
-
-
-/*
-** {======================================================
-** Generic functions
-** =======================================================
-*/
-
-
-/*
-** one after last element in a hash array
-*/
-#define gnodelast(h) gnode(h, cast(size_t, sizenode(h)))
-
-
-/*
-** link collectable object 'o' into list pointed by 'p'
-*/
-#define linkgclist(o,p) ((o)->gclist = (p), (p) = obj2gco(o))
-
-
-/*
-** if key is not marked, mark its entry as dead (therefore removing it
-** from the table)
-*/
-static void removeentry (Node *n) {
- lua_assert(ttisnil(gval(n)));
- if (valiswhite(gkey(n)))
- setdeadvalue(wgkey(n)); /* unused and unmarked key; remove it */
-}
-
-
-/*
-** tells whether a key or value can be cleared from a weak
-** table. Non-collectable objects are never removed from weak
-** tables. Strings behave as 'values', so are never removed too. for
-** other objects: if really collected, cannot keep them; for objects
-** being finalized, keep them in keys, but not in values
-*/
-static int iscleared (global_State *g, const TValue *o) {
- if (!iscollectable(o)) return 0;
- else if (ttisstring(o)) {
- markobject(g, tsvalue(o)); /* strings are 'values', so are never weak */
- return 0;
- }
- else return iswhite(gcvalue(o));
-}
-
-
-/*
-** barrier that moves collector forward, that is, mark the white object
-** being pointed by a black object. (If in sweep phase, clear the black
-** object to white [sweep it] to avoid other barrier calls for this
-** same object.)
-*/
-void luaC_barrier_ (lua_State *L, GCObject *o, GCObject *v) {
- global_State *g = G(L);
- lua_assert(isblack(o) && iswhite(v) && !isdead(g, v) && !isdead(g, o));
- if (keepinvariant(g)) /* must keep invariant? */
- reallymarkobject(g, v); /* restore invariant */
- else { /* sweep phase */
- lua_assert(issweepphase(g));
- makewhite(g, o); /* mark main obj. as white to avoid other barriers */
- }
-}
-
-
-/*
-** barrier that moves collector backward, that is, mark the black object
-** pointing to a white object as gray again.
-*/
-void luaC_barrierback_ (lua_State *L, Table *t) {
- global_State *g = G(L);
- lua_assert(isblack(t) && !isdead(g, t));
- black2gray(t); /* make table gray (again) */
- linkgclist(t, g->grayagain);
-}
-
-
-/*
-** barrier for assignments to closed upvalues. Because upvalues are
-** shared among closures, it is impossible to know the color of all
-** closures pointing to it. So, we assume that the object being assigned
-** must be marked.
-*/
-void luaC_upvalbarrier_ (lua_State *L, UpVal *uv) {
- global_State *g = G(L);
- GCObject *o = gcvalue(uv->v);
- lua_assert(!upisopen(uv)); /* ensured by macro luaC_upvalbarrier */
- if (keepinvariant(g))
- markobject(g, o);
-}
-
-
-void luaC_fix (lua_State *L, GCObject *o) {
- global_State *g = G(L);
- lua_assert(g->allgc == o); /* object must be 1st in 'allgc' list! */
- white2gray(o); /* they will be gray forever */
- g->allgc = o->next; /* remove object from 'allgc' list */
- o->next = g->fixedgc; /* link it to 'fixedgc' list */
- g->fixedgc = o;
-}
-
-
-/*
-** create a new collectable object (with given type and size) and link
-** it to 'allgc' list.
-*/
-GCObject *luaC_newobj (lua_State *L, int tt, size_t sz) {
- global_State *g = G(L);
- GCObject *o = cast(GCObject *, luaM_newobject(L, novariant(tt), sz));
- o->marked = luaC_white(g);
- o->tt = tt;
- o->next = g->allgc;
- g->allgc = o;
- return o;
-}
-
-/* }====================================================== */
-
-
-
-/*
-** {======================================================
-** Mark functions
-** =======================================================
-*/
-
-
-/*
-** mark an object. Userdata, strings, and closed upvalues are visited
-** and turned black here. Other objects are marked gray and added
-** to appropriate list to be visited (and turned black) later. (Open
-** upvalues are already linked in 'headuv' list.)
-*/
-static void reallymarkobject (global_State *g, GCObject *o) {
- reentry:
- white2gray(o);
- switch (o->tt) {
- case LUA_TSHRSTR:
- case LUA_TLNGSTR: {
- gray2black(o);
- g->GCmemtrav += sizestring(gco2ts(o));
- break;
- }
- case LUA_TUSERDATA: {
- TValue uvalue;
- markobject(g, gco2u(o)->metatable); /* mark its metatable */
- gray2black(o);
- g->GCmemtrav += sizeudata(gco2u(o));
- getuservalue(g->mainthread, gco2u(o), &uvalue);
- if (valiswhite(&uvalue)) { /* markvalue(g, &uvalue); */
- o = gcvalue(&uvalue);
- goto reentry;
- }
- break;
- }
- case LUA_TLCL: {
- linkgclist(gco2lcl(o), g->gray);
- break;
- }
- case LUA_TCCL: {
- linkgclist(gco2ccl(o), g->gray);
- break;
- }
- case LUA_TTABLE: {
- linkgclist(gco2t(o), g->gray);
- break;
- }
- case LUA_TTHREAD: {
- linkgclist(gco2th(o), g->gray);
- break;
- }
- case LUA_TPROTO: {
- linkgclist(gco2p(o), g->gray);
- break;
- }
- default: lua_assert(0); break;
- }
-}
-
-
-/*
-** mark metamethods for basic types
-*/
-static void markmt (global_State *g) {
- int i;
- for (i=0; i < LUA_NUMTAGS; i++)
- markobject(g, g->mt[i]);
-}
-
-
-/*
-** mark all objects in list of being-finalized
-*/
-static void markbeingfnz (global_State *g) {
- GCObject *o;
- for (o = g->tobefnz; o != NULL; o = o->next)
- markobject(g, o);
-}
-
-
-/*
-** Mark all values stored in marked open upvalues from non-marked threads.
-** (Values from marked threads were already marked when traversing the
-** thread.) Remove from the list threads that no longer have upvalues and
-** not-marked threads.
-*/
-static void remarkupvals (global_State *g) {
- lua_State *thread;
- lua_State **p = &g->twups;
- while ((thread = *p) != NULL) {
- lua_assert(!isblack(thread)); /* threads are never black */
- if (isgray(thread) && thread->openupval != NULL)
- p = &thread->twups; /* keep marked thread with upvalues in the list */
- else { /* thread is not marked or without upvalues */
- UpVal *uv;
- *p = thread->twups; /* remove thread from the list */
- thread->twups = thread; /* mark that it is out of list */
- for (uv = thread->openupval; uv != NULL; uv = uv->u.open.next) {
- if (uv->u.open.touched) {
- markvalue(g, uv->v); /* remark upvalue's value */
- uv->u.open.touched = 0;
- }
- }
- }
- }
-}
-
-
-/*
-** mark root set and reset all gray lists, to start a new collection
-*/
-static void restartcollection (global_State *g) {
- g->gray = g->grayagain = NULL;
- g->weak = g->allweak = g->ephemeron = NULL;
- markobject(g, g->mainthread);
- markvalue(g, &g->l_registry);
- markmt(g);
- markbeingfnz(g); /* mark any finalizing object left from previous cycle */
-}
-
-/* }====================================================== */
-
-
-/*
-** {======================================================
-** Traverse functions
-** =======================================================
-*/
-
-/*
-** Traverse a table with weak values and link it to proper list. During
-** propagate phase, keep it in 'grayagain' list, to be revisited in the
-** atomic phase. In the atomic phase, if table has any white value,
-** put it in 'weak' list, to be cleared.
-*/
-static void traverseweakvalue (global_State *g, Table *h) {
- Node *n, *limit = gnodelast(h);
- /* if there is array part, assume it may have white values (it is not
- worth traversing it now just to check) */
- int hasclears = (h->sizearray > 0);
- for (n = gnode(h, 0); n < limit; n++) { /* traverse hash part */
- checkdeadkey(n);
- if (ttisnil(gval(n))) /* entry is empty? */
- removeentry(n); /* remove it */
- else {
- lua_assert(!ttisnil(gkey(n)));
- markvalue(g, gkey(n)); /* mark key */
- if (!hasclears && iscleared(g, gval(n))) /* is there a white value? */
- hasclears = 1; /* table will have to be cleared */
- }
- }
- if (g->gcstate == GCSpropagate)
- linkgclist(h, g->grayagain); /* must retraverse it in atomic phase */
- else if (hasclears)
- linkgclist(h, g->weak); /* has to be cleared later */
-}
-
-
-/*
-** Traverse an ephemeron table and link it to proper list. Returns true
-** iff any object was marked during this traversal (which implies that
-** convergence has to continue). During propagation phase, keep table
-** in 'grayagain' list, to be visited again in the atomic phase. In
-** the atomic phase, if table has any white->white entry, it has to
-** be revisited during ephemeron convergence (as that key may turn
-** black). Otherwise, if it has any white key, table has to be cleared
-** (in the atomic phase).
-*/
-static int traverseephemeron (global_State *g, Table *h) {
- int marked = 0; /* true if an object is marked in this traversal */
- int hasclears = 0; /* true if table has white keys */
- int hasww = 0; /* true if table has entry "white-key -> white-value" */
- Node *n, *limit = gnodelast(h);
- unsigned int i;
- /* traverse array part */
- for (i = 0; i < h->sizearray; i++) {
- if (valiswhite(&h->array[i])) {
- marked = 1;
- reallymarkobject(g, gcvalue(&h->array[i]));
- }
- }
- /* traverse hash part */
- for (n = gnode(h, 0); n < limit; n++) {
- checkdeadkey(n);
- if (ttisnil(gval(n))) /* entry is empty? */
- removeentry(n); /* remove it */
- else if (iscleared(g, gkey(n))) { /* key is not marked (yet)? */
- hasclears = 1; /* table must be cleared */
- if (valiswhite(gval(n))) /* value not marked yet? */
- hasww = 1; /* white-white entry */
- }
- else if (valiswhite(gval(n))) { /* value not marked yet? */
- marked = 1;
- reallymarkobject(g, gcvalue(gval(n))); /* mark it now */
- }
- }
- /* link table into proper list */
- if (g->gcstate == GCSpropagate)
- linkgclist(h, g->grayagain); /* must retraverse it in atomic phase */
- else if (hasww) /* table has white->white entries? */
- linkgclist(h, g->ephemeron); /* have to propagate again */
- else if (hasclears) /* table has white keys? */
- linkgclist(h, g->allweak); /* may have to clean white keys */
- return marked;
-}
-
-
-static void traversestrongtable (global_State *g, Table *h) {
- Node *n, *limit = gnodelast(h);
- unsigned int i;
- for (i = 0; i < h->sizearray; i++) /* traverse array part */
- markvalue(g, &h->array[i]);
- for (n = gnode(h, 0); n < limit; n++) { /* traverse hash part */
- checkdeadkey(n);
- if (ttisnil(gval(n))) /* entry is empty? */
- removeentry(n); /* remove it */
- else {
- lua_assert(!ttisnil(gkey(n)));
- markvalue(g, gkey(n)); /* mark key */
- markvalue(g, gval(n)); /* mark value */
- }
- }
-}
-
-
-static lu_mem traversetable (global_State *g, Table *h) {
- const char *weakkey, *weakvalue;
- const TValue *mode = gfasttm(g, h->metatable, TM_MODE);
- markobject(g, h->metatable);
- if (mode && ttisstring(mode) && /* is there a weak mode? */
- ((weakkey = strchr(svalue(mode), 'k')),
- (weakvalue = strchr(svalue(mode), 'v')),
- (weakkey || weakvalue))) { /* is really weak? */
- black2gray(h); /* keep table gray */
- if (!weakkey) /* strong keys? */
- traverseweakvalue(g, h);
- else if (!weakvalue) /* strong values? */
- traverseephemeron(g, h);
- else /* all weak */
- linkgclist(h, g->allweak); /* nothing to traverse now */
- }
- else /* not weak */
- traversestrongtable(g, h);
- return sizeof(Table) + sizeof(TValue) * h->sizearray +
- sizeof(Node) * cast(size_t, sizenode(h));
-}
-
-
-static int traverseproto (global_State *g, Proto *f) {
- int i;
- if (f->cache && iswhite(f->cache))
- f->cache = NULL; /* allow cache to be collected */
- markobject(g, f->source);
- for (i = 0; i < f->sizek; i++) /* mark literals */
- markvalue(g, &f->k[i]);
- for (i = 0; i < f->sizeupvalues; i++) /* mark upvalue names */
- markobject(g, f->upvalues[i].name);
- for (i = 0; i < f->sizep; i++) /* mark nested protos */
- markobject(g, f->p[i]);
- for (i = 0; i < f->sizelocvars; i++) /* mark local-variable names */
- markobject(g, f->locvars[i].varname);
- return sizeof(Proto) + sizeof(Instruction) * f->sizecode +
- sizeof(Proto *) * f->sizep +
- sizeof(TValue) * f->sizek +
- sizeof(int) * f->sizelineinfo +
- sizeof(LocVar) * f->sizelocvars +
- sizeof(Upvaldesc) * f->sizeupvalues;
-}
-
-
-static lu_mem traverseCclosure (global_State *g, CClosure *cl) {
- int i;
- for (i = 0; i < cl->nupvalues; i++) /* mark its upvalues */
- markvalue(g, &cl->upvalue[i]);
- return sizeCclosure(cl->nupvalues);
-}
-
-/*
-** open upvalues point to values in a thread, so those values should
-** be marked when the thread is traversed except in the atomic phase
-** (because then the value cannot be changed by the thread and the
-** thread may not be traversed again)
-*/
-static lu_mem traverseLclosure (global_State *g, LClosure *cl) {
- int i;
- markobject(g, cl->p); /* mark its prototype */
- for (i = 0; i < cl->nupvalues; i++) { /* mark its upvalues */
- UpVal *uv = cl->upvals[i];
- if (uv != NULL) {
- if (upisopen(uv) && g->gcstate != GCSinsideatomic)
- uv->u.open.touched = 1; /* can be marked in 'remarkupvals' */
- else
- markvalue(g, uv->v);
- }
- }
- return sizeLclosure(cl->nupvalues);
-}
-
-
-static lu_mem traversethread (global_State *g, lua_State *th) {
- StkId o = th->stack;
- if (o == NULL)
- return 1; /* stack not completely built yet */
- lua_assert(g->gcstate == GCSinsideatomic ||
- th->openupval == NULL || isintwups(th));
- for (; o < th->top; o++) /* mark live elements in the stack */
- markvalue(g, o);
- if (g->gcstate == GCSinsideatomic) { /* final traversal? */
- StkId lim = th->stack + th->stacksize; /* real end of stack */
- for (; o < lim; o++) /* clear not-marked stack slice */
- setnilvalue(o);
- /* 'remarkupvals' may have removed thread from 'twups' list */
- if (!isintwups(th) && th->openupval != NULL) {
- th->twups = g->twups; /* link it back to the list */
- g->twups = th;
- }
- }
- else if (g->gckind != KGC_EMERGENCY)
- luaD_shrinkstack(th); /* do not change stack in emergency cycle */
- return (sizeof(lua_State) + sizeof(TValue) * th->stacksize);
-}
-
-
-/*
-** traverse one gray object, turning it to black (except for threads,
-** which are always gray).
-*/
-static void propagatemark (global_State *g) {
- lu_mem size;
- GCObject *o = g->gray;
- lua_assert(isgray(o));
- gray2black(o);
- switch (o->tt) {
- case LUA_TTABLE: {
- Table *h = gco2t(o);
- g->gray = h->gclist; /* remove from 'gray' list */
- size = traversetable(g, h);
- break;
- }
- case LUA_TLCL: {
- LClosure *cl = gco2lcl(o);
- g->gray = cl->gclist; /* remove from 'gray' list */
- size = traverseLclosure(g, cl);
- break;
- }
- case LUA_TCCL: {
- CClosure *cl = gco2ccl(o);
- g->gray = cl->gclist; /* remove from 'gray' list */
- size = traverseCclosure(g, cl);
- break;
- }
- case LUA_TTHREAD: {
- lua_State *th = gco2th(o);
- g->gray = th->gclist; /* remove from 'gray' list */
- linkgclist(th, g->grayagain); /* insert into 'grayagain' list */
- black2gray(o);
- size = traversethread(g, th);
- break;
- }
- case LUA_TPROTO: {
- Proto *p = gco2p(o);
- g->gray = p->gclist; /* remove from 'gray' list */
- size = traverseproto(g, p);
- break;
- }
- default: lua_assert(0); return;
- }
- g->GCmemtrav += size;
-}
-
-
-static void propagateall (global_State *g) {
- while (g->gray) propagatemark(g);
-}
-
-
-static void convergeephemerons (global_State *g) {
- int changed;
- do {
- GCObject *w;
- GCObject *next = g->ephemeron; /* get ephemeron list */
- g->ephemeron = NULL; /* tables may return to this list when traversed */
- changed = 0;
- while ((w = next) != NULL) {
- next = gco2t(w)->gclist;
- if (traverseephemeron(g, gco2t(w))) { /* traverse marked some value? */
- propagateall(g); /* propagate changes */
- changed = 1; /* will have to revisit all ephemeron tables */
- }
- }
- } while (changed);
-}
-
-/* }====================================================== */
-
-
-/*
-** {======================================================
-** Sweep Functions
-** =======================================================
-*/
-
-
-/*
-** clear entries with unmarked keys from all weaktables in list 'l' up
-** to element 'f'
-*/
-static void clearkeys (global_State *g, GCObject *l, GCObject *f) {
- for (; l != f; l = gco2t(l)->gclist) {
- Table *h = gco2t(l);
- Node *n, *limit = gnodelast(h);
- for (n = gnode(h, 0); n < limit; n++) {
- if (!ttisnil(gval(n)) && (iscleared(g, gkey(n)))) {
- setnilvalue(gval(n)); /* remove value ... */
- removeentry(n); /* and remove entry from table */
- }
- }
- }
-}
-
-
-/*
-** clear entries with unmarked values from all weaktables in list 'l' up
-** to element 'f'
-*/
-static void clearvalues (global_State *g, GCObject *l, GCObject *f) {
- for (; l != f; l = gco2t(l)->gclist) {
- Table *h = gco2t(l);
- Node *n, *limit = gnodelast(h);
- unsigned int i;
- for (i = 0; i < h->sizearray; i++) {
- TValue *o = &h->array[i];
- if (iscleared(g, o)) /* value was collected? */
- setnilvalue(o); /* remove value */
- }
- for (n = gnode(h, 0); n < limit; n++) {
- if (!ttisnil(gval(n)) && iscleared(g, gval(n))) {
- setnilvalue(gval(n)); /* remove value ... */
- removeentry(n); /* and remove entry from table */
- }
- }
- }
-}
-
-
-void luaC_upvdeccount (lua_State *L, UpVal *uv) {
- lua_assert(uv->refcount > 0);
- uv->refcount--;
- if (uv->refcount == 0 && !upisopen(uv))
- luaM_free(L, uv);
-}
-
-
-static void freeLclosure (lua_State *L, LClosure *cl) {
- int i;
- for (i = 0; i < cl->nupvalues; i++) {
- UpVal *uv = cl->upvals[i];
- if (uv)
- luaC_upvdeccount(L, uv);
- }
- luaM_freemem(L, cl, sizeLclosure(cl->nupvalues));
-}
-
-
-static void freeobj (lua_State *L, GCObject *o) {
- switch (o->tt) {
- case LUA_TPROTO: luaF_freeproto(L, gco2p(o)); break;
- case LUA_TLCL: {
- freeLclosure(L, gco2lcl(o));
- break;
- }
- case LUA_TCCL: {
- luaM_freemem(L, o, sizeCclosure(gco2ccl(o)->nupvalues));
- break;
- }
- case LUA_TTABLE: luaH_free(L, gco2t(o)); break;
- case LUA_TTHREAD: luaE_freethread(L, gco2th(o)); break;
- case LUA_TUSERDATA: luaM_freemem(L, o, sizeudata(gco2u(o))); break;
- case LUA_TSHRSTR:
- luaS_remove(L, gco2ts(o)); /* remove it from hash table */
- /* go through */
- case LUA_TLNGSTR: {
- luaM_freemem(L, o, sizestring(gco2ts(o)));
- break;
- }
- default: lua_assert(0);
- }
-}
-
-
-#define sweepwholelist(L,p) sweeplist(L,p,MAX_LUMEM)
-static GCObject **sweeplist (lua_State *L, GCObject **p, lu_mem count);
-
-
-/*
-** sweep at most 'count' elements from a list of GCObjects erasing dead
-** objects, where a dead object is one marked with the old (non current)
-** white; change all non-dead objects back to white, preparing for next
-** collection cycle. Return where to continue the traversal or NULL if
-** list is finished.
-*/
-static GCObject **sweeplist (lua_State *L, GCObject **p, lu_mem count) {
- global_State *g = G(L);
- int ow = otherwhite(g);
- int white = luaC_white(g); /* current white */
- while (*p != NULL && count-- > 0) {
- GCObject *curr = *p;
- int marked = curr->marked;
- if (isdeadm(ow, marked)) { /* is 'curr' dead? */
- *p = curr->next; /* remove 'curr' from list */
- freeobj(L, curr); /* erase 'curr' */
- }
- else { /* change mark to 'white' */
- curr->marked = cast_byte((marked & maskcolors) | white);
- p = &curr->next; /* go to next element */
- }
- }
- return (*p == NULL) ? NULL : p;
-}
-
-
-/*
-** sweep a list until a live object (or end of list)
-*/
-static GCObject **sweeptolive (lua_State *L, GCObject **p, int *n) {
- GCObject **old = p;
- int i = 0;
- do {
- i++;
- p = sweeplist(L, p, 1);
- } while (p == old);
- if (n) *n += i;
- return p;
-}
-
-/* }====================================================== */
-
-
-/*
-** {======================================================
-** Finalization
-** =======================================================
-*/
-
-/*
-** If possible, free concatenation buffer and shrink string table
-*/
-static void checkSizes (lua_State *L, global_State *g) {
- if (g->gckind != KGC_EMERGENCY) {
- l_mem olddebt = g->GCdebt;
- luaZ_freebuffer(L, &g->buff); /* free concatenation buffer */
- if (g->strt.nuse < g->strt.size / 4) /* string table too big? */
- luaS_resize(L, g->strt.size / 2); /* shrink it a little */
- g->GCestimate += g->GCdebt - olddebt; /* update estimate */
- }
-}
-
-
-static GCObject *udata2finalize (global_State *g) {
- GCObject *o = g->tobefnz; /* get first element */
- lua_assert(tofinalize(o));
- g->tobefnz = o->next; /* remove it from 'tobefnz' list */
- o->next = g->allgc; /* return it to 'allgc' list */
- g->allgc = o;
- resetbit(o->marked, FINALIZEDBIT); /* object is "normal" again */
- if (issweepphase(g))
- makewhite(g, o); /* "sweep" object */
- return o;
-}
-
-
-static void dothecall (lua_State *L, void *ud) {
- UNUSED(ud);
- luaD_call(L, L->top - 2, 0, 0);
-}
-
-
-static void GCTM (lua_State *L, int propagateerrors) {
- global_State *g = G(L);
- const TValue *tm;
- TValue v;
- setgcovalue(L, &v, udata2finalize(g));
- tm = luaT_gettmbyobj(L, &v, TM_GC);
- if (tm != NULL && ttisfunction(tm)) { /* is there a finalizer? */
- int status;
- lu_byte oldah = L->allowhook;
- int running = g->gcrunning;
- L->allowhook = 0; /* stop debug hooks during GC metamethod */
- g->gcrunning = 0; /* avoid GC steps */
- setobj2s(L, L->top, tm); /* push finalizer... */
- setobj2s(L, L->top + 1, &v); /* ... and its argument */
- L->top += 2; /* and (next line) call the finalizer */
- status = luaD_pcall(L, dothecall, NULL, savestack(L, L->top - 2), 0);
- L->allowhook = oldah; /* restore hooks */
- g->gcrunning = running; /* restore state */
- if (status != LUA_OK && propagateerrors) { /* error while running __gc? */
- if (status == LUA_ERRRUN) { /* is there an error object? */
- const char *msg = (ttisstring(L->top - 1))
- ? svalue(L->top - 1)
- : "no message";
- luaO_pushfstring(L, "error in __gc metamethod (%s)", msg);
- status = LUA_ERRGCMM; /* error in __gc metamethod */
- }
- luaD_throw(L, status); /* re-throw error */
- }
- }
-}
-
-
-/*
-** call a few (up to 'g->gcfinnum') finalizers
-*/
-static int runafewfinalizers (lua_State *L) {
- global_State *g = G(L);
- unsigned int i;
- lua_assert(!g->tobefnz || g->gcfinnum > 0);
- for (i = 0; g->tobefnz && i < g->gcfinnum; i++)
- GCTM(L, 1); /* call one finalizer */
- g->gcfinnum = (!g->tobefnz) ? 0 /* nothing more to finalize? */
- : g->gcfinnum * 2; /* else call a few more next time */
- return i;
-}
-
-
-/*
-** call all pending finalizers
-*/
-static void callallpendingfinalizers (lua_State *L, int propagateerrors) {
- global_State *g = G(L);
- while (g->tobefnz)
- GCTM(L, propagateerrors);
-}
-
-
-/*
-** find last 'next' field in list 'p' list (to add elements in its end)
-*/
-static GCObject **findlast (GCObject **p) {
- while (*p != NULL)
- p = &(*p)->next;
- return p;
-}
-
-
-/*
-** move all unreachable objects (or 'all' objects) that need
-** finalization from list 'finobj' to list 'tobefnz' (to be finalized)
-*/
-static void separatetobefnz (global_State *g, int all) {
- GCObject *curr;
- GCObject **p = &g->finobj;
- GCObject **lastnext = findlast(&g->tobefnz);
- while ((curr = *p) != NULL) { /* traverse all finalizable objects */
- lua_assert(tofinalize(curr));
- if (!(iswhite(curr) || all)) /* not being collected? */
- p = &curr->next; /* don't bother with it */
- else {
- *p = curr->next; /* remove 'curr' from 'finobj' list */
- curr->next = *lastnext; /* link at the end of 'tobefnz' list */
- *lastnext = curr;
- lastnext = &curr->next;
- }
- }
-}
-
-
-/*
-** if object 'o' has a finalizer, remove it from 'allgc' list (must
-** search the list to find it) and link it in 'finobj' list.
-*/
-void luaC_checkfinalizer (lua_State *L, GCObject *o, Table *mt) {
- global_State *g = G(L);
- if (tofinalize(o) || /* obj. is already marked... */
- gfasttm(g, mt, TM_GC) == NULL) /* or has no finalizer? */
- return; /* nothing to be done */
- else { /* move 'o' to 'finobj' list */
- GCObject **p;
- if (issweepphase(g)) {
- makewhite(g, o); /* "sweep" object 'o' */
- if (g->sweepgc == &o->next) /* should not remove 'sweepgc' object */
- g->sweepgc = sweeptolive(L, g->sweepgc, NULL); /* change 'sweepgc' */
- }
- /* search for pointer pointing to 'o' */
- for (p = &g->allgc; *p != o; p = &(*p)->next) { /* empty */ }
- *p = o->next; /* remove 'o' from 'allgc' list */
- o->next = g->finobj; /* link it in 'finobj' list */
- g->finobj = o;
- l_setbit(o->marked, FINALIZEDBIT); /* mark it as such */
- }
-}
-
-/* }====================================================== */
-
-
-
-/*
-** {======================================================
-** GC control
-** =======================================================
-*/
-
-
-/*
-** Set a reasonable "time" to wait before starting a new GC cycle; cycle
-** will start when memory use hits threshold. (Division by 'estimate'
-** should be OK: it cannot be zero (because Lua cannot even start with
-** less than PAUSEADJ bytes).
-*/
-static void setpause (global_State *g) {
- l_mem threshold, debt;
- l_mem estimate = g->GCestimate / PAUSEADJ; /* adjust 'estimate' */
- lua_assert(estimate > 0);
- threshold = (g->gcpause < MAX_LMEM / estimate) /* overflow? */
- ? estimate * g->gcpause /* no overflow */
- : MAX_LMEM; /* overflow; truncate to maximum */
- debt = gettotalbytes(g) - threshold;
- luaE_setdebt(g, debt);
-}
-
-
-/*
-** Enter first sweep phase.
-** The call to 'sweeptolive' makes pointer point to an object inside
-** the list (instead of to the header), so that the real sweep do not
-** need to skip objects created between "now" and the start of the real
-** sweep.
-** Returns how many objects it swept.
-*/
-static int entersweep (lua_State *L) {
- global_State *g = G(L);
- int n = 0;
- g->gcstate = GCSswpallgc;
- lua_assert(g->sweepgc == NULL);
- g->sweepgc = sweeptolive(L, &g->allgc, &n);
- return n;
-}
-
-
-void luaC_freeallobjects (lua_State *L) {
- global_State *g = G(L);
- separatetobefnz(g, 1); /* separate all objects with finalizers */
- lua_assert(g->finobj == NULL);
- callallpendingfinalizers(L, 0);
- lua_assert(g->tobefnz == NULL);
- g->currentwhite = WHITEBITS; /* this "white" makes all objects look dead */
- g->gckind = KGC_NORMAL;
- sweepwholelist(L, &g->finobj);
- sweepwholelist(L, &g->allgc);
- sweepwholelist(L, &g->fixedgc); /* collect fixed objects */
- lua_assert(g->strt.nuse == 0);
-}
-
-
-static l_mem atomic (lua_State *L) {
- global_State *g = G(L);
- l_mem work;
- GCObject *origweak, *origall;
- GCObject *grayagain = g->grayagain; /* save original list */
- lua_assert(g->ephemeron == NULL && g->weak == NULL);
- lua_assert(!iswhite(g->mainthread));
- g->gcstate = GCSinsideatomic;
- g->GCmemtrav = 0; /* start counting work */
- markobject(g, L); /* mark running thread */
- /* registry and global metatables may be changed by API */
- markvalue(g, &g->l_registry);
- markmt(g); /* mark global metatables */
- /* remark occasional upvalues of (maybe) dead threads */
- remarkupvals(g);
- propagateall(g); /* propagate changes */
- work = g->GCmemtrav; /* stop counting (do not recount 'grayagain') */
- g->gray = grayagain;
- propagateall(g); /* traverse 'grayagain' list */
- g->GCmemtrav = 0; /* restart counting */
- convergeephemerons(g);
- /* at this point, all strongly accessible objects are marked. */
- /* Clear values from weak tables, before checking finalizers */
- clearvalues(g, g->weak, NULL);
- clearvalues(g, g->allweak, NULL);
- origweak = g->weak; origall = g->allweak;
- work += g->GCmemtrav; /* stop counting (objects being finalized) */
- separatetobefnz(g, 0); /* separate objects to be finalized */
- g->gcfinnum = 1; /* there may be objects to be finalized */
- markbeingfnz(g); /* mark objects that will be finalized */
- propagateall(g); /* remark, to propagate 'resurrection' */
- g->GCmemtrav = 0; /* restart counting */
- convergeephemerons(g);
- /* at this point, all resurrected objects are marked. */
- /* remove dead objects from weak tables */
- clearkeys(g, g->ephemeron, NULL); /* clear keys from all ephemeron tables */
- clearkeys(g, g->allweak, NULL); /* clear keys from all 'allweak' tables */
- /* clear values from resurrected weak tables */
- clearvalues(g, g->weak, origweak);
- clearvalues(g, g->allweak, origall);
- g->currentwhite = cast_byte(otherwhite(g)); /* flip current white */
- work += g->GCmemtrav; /* complete counting */
- return work; /* estimate of memory marked by 'atomic' */
-}
-
-
-static lu_mem sweepstep (lua_State *L, global_State *g,
- int nextstate, GCObject **nextlist) {
- if (g->sweepgc) {
- l_mem olddebt = g->GCdebt;
- g->sweepgc = sweeplist(L, g->sweepgc, GCSWEEPMAX);
- g->GCestimate += g->GCdebt - olddebt; /* update estimate */
- if (g->sweepgc) /* is there still something to sweep? */
- return (GCSWEEPMAX * GCSWEEPCOST);
- }
- /* else enter next state */
- g->gcstate = nextstate;
- g->sweepgc = nextlist;
- return 0;
-}
-
-
-static lu_mem singlestep (lua_State *L) {
- global_State *g = G(L);
- switch (g->gcstate) {
- case GCSpause: {
- g->GCmemtrav = g->strt.size * sizeof(GCObject*);
- restartcollection(g);
- g->gcstate = GCSpropagate;
- return g->GCmemtrav;
- }
- case GCSpropagate: {
- g->GCmemtrav = 0;
- lua_assert(g->gray);
- propagatemark(g);
- if (g->gray == NULL) /* no more gray objects? */
- g->gcstate = GCSatomic; /* finish propagate phase */
- return g->GCmemtrav; /* memory traversed in this step */
- }
- case GCSatomic: {
- lu_mem work;
- int sw;
- propagateall(g); /* make sure gray list is empty */
- work = atomic(L); /* work is what was traversed by 'atomic' */
- sw = entersweep(L);
- g->GCestimate = gettotalbytes(g); /* first estimate */;
- return work + sw * GCSWEEPCOST;
- }
- case GCSswpallgc: { /* sweep "regular" objects */
- return sweepstep(L, g, GCSswpfinobj, &g->finobj);
- }
- case GCSswpfinobj: { /* sweep objects with finalizers */
- return sweepstep(L, g, GCSswptobefnz, &g->tobefnz);
- }
- case GCSswptobefnz: { /* sweep objects to be finalized */
- return sweepstep(L, g, GCSswpend, NULL);
- }
- case GCSswpend: { /* finish sweeps */
- makewhite(g, g->mainthread); /* sweep main thread */
- checkSizes(L, g);
- g->gcstate = GCScallfin;
- return 0;
- }
- case GCScallfin: { /* call remaining finalizers */
- if (g->tobefnz && g->gckind != KGC_EMERGENCY) {
- int n = runafewfinalizers(L);
- return (n * GCFINALIZECOST);
- }
- else { /* emergency mode or no more finalizers */
- g->gcstate = GCSpause; /* finish collection */
- return 0;
- }
- }
- default: lua_assert(0); return 0;
- }
-}
-
-
-/*
-** advances the garbage collector until it reaches a state allowed
-** by 'statemask'
-*/
-void luaC_runtilstate (lua_State *L, int statesmask) {
- global_State *g = G(L);
- while (!testbit(statesmask, g->gcstate))
- singlestep(L);
-}
-
-
-/*
-** get GC debt and convert it from Kb to 'work units' (avoid zero debt
-** and overflows)
-*/
-static l_mem getdebt (global_State *g) {
- l_mem debt = g->GCdebt;
- int stepmul = g->gcstepmul;
- debt = (debt / STEPMULADJ) + 1;
- debt = (debt < MAX_LMEM / stepmul) ? debt * stepmul : MAX_LMEM;
- return debt;
-}
-
-/*
-** performs a basic GC step when collector is running
-*/
-void luaC_step (lua_State *L) {
- global_State *g = G(L);
- l_mem debt = getdebt(g); /* GC deficit (be paid now) */
- if (!g->gcrunning) { /* not running? */
- luaE_setdebt(g, -GCSTEPSIZE * 10); /* avoid being called too often */
- return;
- }
- do { /* repeat until pause or enough "credit" (negative debt) */
- lu_mem work = singlestep(L); /* perform one single step */
- debt -= work;
- } while (debt > -GCSTEPSIZE && g->gcstate != GCSpause);
- if (g->gcstate == GCSpause)
- setpause(g); /* pause until next cycle */
- else {
- debt = (debt / g->gcstepmul) * STEPMULADJ; /* convert 'work units' to Kb */
- luaE_setdebt(g, debt);
- runafewfinalizers(L);
- }
-}
-
-
-/*
-** Performs a full GC cycle; if 'isemergency', set a flag to avoid
-** some operations which could change the interpreter state in some
-** unexpected ways (running finalizers and shrinking some structures).
-** Before running the collection, check 'keepinvariant'; if it is true,
-** there may be some objects marked as black, so the collector has
-** to sweep all objects to turn them back to white (as white has not
-** changed, nothing will be collected).
-*/
-void luaC_fullgc (lua_State *L, int isemergency) {
- global_State *g = G(L);
- lua_assert(g->gckind == KGC_NORMAL);
- if (isemergency) g->gckind = KGC_EMERGENCY; /* set flag */
- if (keepinvariant(g)) { /* black objects? */
- entersweep(L); /* sweep everything to turn them back to white */
- }
- /* finish any pending sweep phase to start a new cycle */
- luaC_runtilstate(L, bitmask(GCSpause));
- luaC_runtilstate(L, ~bitmask(GCSpause)); /* start new collection */
- luaC_runtilstate(L, bitmask(GCScallfin)); /* run up to finalizers */
- /* estimate must be correct after a full GC cycle */
- lua_assert(g->GCestimate == gettotalbytes(g));
- luaC_runtilstate(L, bitmask(GCSpause)); /* finish collection */
- g->gckind = KGC_NORMAL;
- setpause(g);
-}
-
-/* }====================================================== */
-
-
diff --git a/3rd/lua/src/lgc.h b/3rd/lua/src/lgc.h
deleted file mode 100644
index 0eedf84..0000000
--- a/3rd/lua/src/lgc.h
+++ /dev/null
@@ -1,138 +0,0 @@
-/*
-** $Id: lgc.h,v 2.86 2014/10/25 11:50:46 roberto Exp $
-** Garbage Collector
-** See Copyright Notice in lua.h
-*/
-
-#ifndef lgc_h
-#define lgc_h
-
-
-#include "lobject.h"
-#include "lstate.h"
-
-/*
-** Collectable objects may have one of three colors: white, which
-** means the object is not marked; gray, which means the
-** object is marked, but its references may be not marked; and
-** black, which means that the object and all its references are marked.
-** The main invariant of the garbage collector, while marking objects,
-** is that a black object can never point to a white one. Moreover,
-** any gray object must be in a "gray list" (gray, grayagain, weak,
-** allweak, ephemeron) so that it can be visited again before finishing
-** the collection cycle. These lists have no meaning when the invariant
-** is not being enforced (e.g., sweep phase).
-*/
-
-
-
-/* how much to allocate before next GC step */
-#if !defined(GCSTEPSIZE)
-/* ~100 small strings */
-#define GCSTEPSIZE (cast_int(100 * sizeof(TString)))
-#endif
-
-
-/*
-** Possible states of the Garbage Collector
-*/
-#define GCSpropagate 0
-#define GCSatomic 1
-#define GCSswpallgc 2
-#define GCSswpfinobj 3
-#define GCSswptobefnz 4
-#define GCSswpend 5
-#define GCScallfin 6
-#define GCSpause 7
-
-
-#define issweepphase(g) \
- (GCSswpallgc <= (g)->gcstate && (g)->gcstate <= GCSswpend)
-
-
-/*
-** macro to tell when main invariant (white objects cannot point to black
-** ones) must be kept. During a collection, the sweep
-** phase may break the invariant, as objects turned white may point to
-** still-black objects. The invariant is restored when sweep ends and
-** all objects are white again.
-*/
-
-#define keepinvariant(g) ((g)->gcstate <= GCSatomic)
-
-
-/*
-** some useful bit tricks
-*/
-#define resetbits(x,m) ((x) &= cast(lu_byte, ~(m)))
-#define setbits(x,m) ((x) |= (m))
-#define testbits(x,m) ((x) & (m))
-#define bitmask(b) (1<<(b))
-#define bit2mask(b1,b2) (bitmask(b1) | bitmask(b2))
-#define l_setbit(x,b) setbits(x, bitmask(b))
-#define resetbit(x,b) resetbits(x, bitmask(b))
-#define testbit(x,b) testbits(x, bitmask(b))
-
-
-/* Layout for bit use in 'marked' field: */
-#define WHITE0BIT 0 /* object is white (type 0) */
-#define WHITE1BIT 1 /* object is white (type 1) */
-#define BLACKBIT 2 /* object is black */
-#define FINALIZEDBIT 3 /* object has been marked for finalization */
-/* bit 7 is currently used by tests (luaL_checkmemory) */
-
-#define WHITEBITS bit2mask(WHITE0BIT, WHITE1BIT)
-
-
-#define iswhite(x) testbits((x)->marked, WHITEBITS)
-#define isblack(x) testbit((x)->marked, BLACKBIT)
-#define isgray(x) /* neither white nor black */ \
- (!testbits((x)->marked, WHITEBITS | bitmask(BLACKBIT)))
-
-#define tofinalize(x) testbit((x)->marked, FINALIZEDBIT)
-
-#define otherwhite(g) ((g)->currentwhite ^ WHITEBITS)
-#define isdeadm(ow,m) (!(((m) ^ WHITEBITS) & (ow)))
-#define isdead(g,v) isdeadm(otherwhite(g), (v)->marked)
-
-#define changewhite(x) ((x)->marked ^= WHITEBITS)
-#define gray2black(x) l_setbit((x)->marked, BLACKBIT)
-
-#define luaC_white(g) cast(lu_byte, (g)->currentwhite & WHITEBITS)
-
-
-#define luaC_condGC(L,c) \
- {if (G(L)->GCdebt > 0) {c;}; condchangemem(L);}
-#define luaC_checkGC(L) luaC_condGC(L, luaC_step(L);)
-
-
-#define luaC_barrier(L,p,v) { \
- if (iscollectable(v) && isblack(p) && iswhite(gcvalue(v))) \
- luaC_barrier_(L,obj2gco(p),gcvalue(v)); }
-
-#define luaC_barrierback(L,p,v) { \
- if (iscollectable(v) && isblack(p) && iswhite(gcvalue(v))) \
- luaC_barrierback_(L,p); }
-
-#define luaC_objbarrier(L,p,o) { \
- if (isblack(p) && iswhite(o)) \
- luaC_barrier_(L,obj2gco(p),obj2gco(o)); }
-
-#define luaC_upvalbarrier(L,uv) \
- { if (iscollectable((uv)->v) && !upisopen(uv)) \
- luaC_upvalbarrier_(L,uv); }
-
-LUAI_FUNC void luaC_fix (lua_State *L, GCObject *o);
-LUAI_FUNC void luaC_freeallobjects (lua_State *L);
-LUAI_FUNC void luaC_step (lua_State *L);
-LUAI_FUNC void luaC_runtilstate (lua_State *L, int statesmask);
-LUAI_FUNC void luaC_fullgc (lua_State *L, int isemergency);
-LUAI_FUNC GCObject *luaC_newobj (lua_State *L, int tt, size_t sz);
-LUAI_FUNC void luaC_barrier_ (lua_State *L, GCObject *o, GCObject *v);
-LUAI_FUNC void luaC_barrierback_ (lua_State *L, Table *o);
-LUAI_FUNC void luaC_upvalbarrier_ (lua_State *L, UpVal *uv);
-LUAI_FUNC void luaC_checkfinalizer (lua_State *L, GCObject *o, Table *mt);
-LUAI_FUNC void luaC_upvdeccount (lua_State *L, UpVal *uv);
-
-
-#endif
diff --git a/3rd/lua/src/linit.c b/3rd/lua/src/linit.c
deleted file mode 100644
index 8ce94cc..0000000
--- a/3rd/lua/src/linit.c
+++ /dev/null
@@ -1,68 +0,0 @@
-/*
-** $Id: linit.c,v 1.38 2015/01/05 13:48:33 roberto Exp $
-** Initialization of libraries for lua.c and other clients
-** See Copyright Notice in lua.h
-*/
-
-
-#define linit_c
-#define LUA_LIB
-
-/*
-** If you embed Lua in your program and need to open the standard
-** libraries, call luaL_openlibs in your program. If you need a
-** different set of libraries, copy this file to your project and edit
-** it to suit your needs.
-**
-** You can also *preload* libraries, so that a later 'require' can
-** open the library, which is already linked to the application.
-** For that, do the following code:
-**
-** luaL_getsubtable(L, LUA_REGISTRYINDEX, "_PRELOAD");
-** lua_pushcfunction(L, luaopen_modname);
-** lua_setfield(L, -2, modname);
-** lua_pop(L, 1); // remove _PRELOAD table
-*/
-
-#include "lprefix.h"
-
-
-#include
-
-#include "lua.h"
-
-#include "lualib.h"
-#include "lauxlib.h"
-
-
-/*
-** these libs are loaded by lua.c and are readily available to any Lua
-** program
-*/
-static const luaL_Reg loadedlibs[] = {
- {"_G", luaopen_base},
- {LUA_LOADLIBNAME, luaopen_package},
- {LUA_COLIBNAME, luaopen_coroutine},
- {LUA_TABLIBNAME, luaopen_table},
- {LUA_IOLIBNAME, luaopen_io},
- {LUA_OSLIBNAME, luaopen_os},
- {LUA_STRLIBNAME, luaopen_string},
- {LUA_MATHLIBNAME, luaopen_math},
- {LUA_UTF8LIBNAME, luaopen_utf8},
- {LUA_DBLIBNAME, luaopen_debug},
-#if defined(LUA_COMPAT_BITLIB)
- {LUA_BITLIBNAME, luaopen_bit32},
-#endif
- {NULL, NULL}
-};
-
-
-LUALIB_API void luaL_openlibs (lua_State *L) {
- const luaL_Reg *lib;
- /* "require" functions from 'loadedlibs' and set results to global table */
- for (lib = loadedlibs; lib->func; lib++) {
- luaL_requiref(L, lib->name, lib->func, 1);
- lua_pop(L, 1); /* remove lib */
- }
-}
-
diff --git a/3rd/lua/src/liolib.c b/3rd/lua/src/liolib.c
deleted file mode 100644
index 4dea396..0000000
--- a/3rd/lua/src/liolib.c
+++ /dev/null
@@ -1,757 +0,0 @@
-/*
-** $Id: liolib.c,v 2.142 2015/01/02 12:50:28 roberto Exp $
-** Standard I/O (and system) library
-** See Copyright Notice in lua.h
-*/
-
-#define liolib_c
-#define LUA_LIB
-
-#include "lprefix.h"
-
-
-#include
-#include
-#include
-#include
-#include
-#include
-
-#include "lua.h"
-
-#include "lauxlib.h"
-#include "lualib.h"
-
-
-#if !defined(l_checkmode)
-
-/*
-** Check whether 'mode' matches '[rwa]%+?b?'.
-** Change this macro to accept other modes for 'fopen' besides
-** the standard ones.
-*/
-#define l_checkmode(mode) \
- (*mode != '\0' && strchr("rwa", *(mode++)) != NULL && \
- (*mode != '+' || ++mode) && /* skip if char is '+' */ \
- (*mode != 'b' || ++mode) && /* skip if char is 'b' */ \
- (*mode == '\0'))
-
-#endif
-
-/*
-** {======================================================
-** l_popen spawns a new process connected to the current
-** one through the file streams.
-** =======================================================
-*/
-
-#if !defined(l_popen) /* { */
-
-#if defined(LUA_USE_POSIX) /* { */
-
-#define l_popen(L,c,m) (fflush(NULL), popen(c,m))
-#define l_pclose(L,file) (pclose(file))
-
-#elif defined(LUA_USE_WINDOWS) /* }{ */
-
-#define l_popen(L,c,m) (_popen(c,m))
-#define l_pclose(L,file) (_pclose(file))
-
-#else /* }{ */
-
-/* ISO C definitions */
-#define l_popen(L,c,m) \
- ((void)((void)c, m), \
- luaL_error(L, "'popen' not supported"), \
- (FILE*)0)
-#define l_pclose(L,file) ((void)L, (void)file, -1)
-
-#endif /* } */
-
-#endif /* } */
-
-/* }====================================================== */
-
-
-#if !defined(l_getc) /* { */
-
-#if defined(LUA_USE_POSIX)
-#define l_getc(f) getc_unlocked(f)
-#define l_lockfile(f) flockfile(f)
-#define l_unlockfile(f) funlockfile(f)
-#else
-#define l_getc(f) getc(f)
-#define l_lockfile(f) ((void)0)
-#define l_unlockfile(f) ((void)0)
-#endif
-
-#endif /* } */
-
-
-/*
-** {======================================================
-** l_fseek: configuration for longer offsets
-** =======================================================
-*/
-
-#if !defined(l_fseek) /* { */
-
-#if defined(LUA_USE_POSIX) /* { */
-
-#include
-
-#define l_fseek(f,o,w) fseeko(f,o,w)
-#define l_ftell(f) ftello(f)
-#define l_seeknum off_t
-
-#elif defined(LUA_USE_WINDOWS) && !defined(_CRTIMP_TYPEINFO) \
- && defined(_MSC_VER) && (_MSC_VER >= 1400) /* }{ */
-
-/* Windows (but not DDK) and Visual C++ 2005 or higher */
-#define l_fseek(f,o,w) _fseeki64(f,o,w)
-#define l_ftell(f) _ftelli64(f)
-#define l_seeknum __int64
-
-#else /* }{ */
-
-/* ISO C definitions */
-#define l_fseek(f,o,w) fseek(f,o,w)
-#define l_ftell(f) ftell(f)
-#define l_seeknum long
-
-#endif /* } */
-
-#endif /* } */
-
-/* }====================================================== */
-
-
-#define IO_PREFIX "_IO_"
-#define IOPREF_LEN (sizeof(IO_PREFIX)/sizeof(char) - 1)
-#define IO_INPUT (IO_PREFIX "input")
-#define IO_OUTPUT (IO_PREFIX "output")
-
-
-typedef luaL_Stream LStream;
-
-
-#define tolstream(L) ((LStream *)luaL_checkudata(L, 1, LUA_FILEHANDLE))
-
-#define isclosed(p) ((p)->closef == NULL)
-
-
-static int io_type (lua_State *L) {
- LStream *p;
- luaL_checkany(L, 1);
- p = (LStream *)luaL_testudata(L, 1, LUA_FILEHANDLE);
- if (p == NULL)
- lua_pushnil(L); /* not a file */
- else if (isclosed(p))
- lua_pushliteral(L, "closed file");
- else
- lua_pushliteral(L, "file");
- return 1;
-}
-
-
-static int f_tostring (lua_State *L) {
- LStream *p = tolstream(L);
- if (isclosed(p))
- lua_pushliteral(L, "file (closed)");
- else
- lua_pushfstring(L, "file (%p)", p->f);
- return 1;
-}
-
-
-static FILE *tofile (lua_State *L) {
- LStream *p = tolstream(L);
- if (isclosed(p))
- luaL_error(L, "attempt to use a closed file");
- lua_assert(p->f);
- return p->f;
-}
-
-
-/*
-** When creating file handles, always creates a 'closed' file handle
-** before opening the actual file; so, if there is a memory error, the
-** file is not left opened.
-*/
-static LStream *newprefile (lua_State *L) {
- LStream *p = (LStream *)lua_newuserdata(L, sizeof(LStream));
- p->closef = NULL; /* mark file handle as 'closed' */
- luaL_setmetatable(L, LUA_FILEHANDLE);
- return p;
-}
-
-
-/*
-** Calls the 'close' function from a file handle. The 'volatile' avoids
-** a bug in some versions of the Clang compiler (e.g., clang 3.0 for
-** 32 bits).
-*/
-static int aux_close (lua_State *L) {
- LStream *p = tolstream(L);
- volatile lua_CFunction cf = p->closef;
- p->closef = NULL; /* mark stream as closed */
- return (*cf)(L); /* close it */
-}
-
-
-static int io_close (lua_State *L) {
- if (lua_isnone(L, 1)) /* no argument? */
- lua_getfield(L, LUA_REGISTRYINDEX, IO_OUTPUT); /* use standard output */
- tofile(L); /* make sure argument is an open stream */
- return aux_close(L);
-}
-
-
-static int f_gc (lua_State *L) {
- LStream *p = tolstream(L);
- if (!isclosed(p) && p->f != NULL)
- aux_close(L); /* ignore closed and incompletely open files */
- return 0;
-}
-
-
-/*
-** function to close regular files
-*/
-static int io_fclose (lua_State *L) {
- LStream *p = tolstream(L);
- int res = fclose(p->f);
- return luaL_fileresult(L, (res == 0), NULL);
-}
-
-
-static LStream *newfile (lua_State *L) {
- LStream *p = newprefile(L);
- p->f = NULL;
- p->closef = &io_fclose;
- return p;
-}
-
-
-static void opencheck (lua_State *L, const char *fname, const char *mode) {
- LStream *p = newfile(L);
- p->f = fopen(fname, mode);
- if (p->f == NULL)
- luaL_error(L, "cannot open file '%s' (%s)", fname, strerror(errno));
-}
-
-
-static int io_open (lua_State *L) {
- const char *filename = luaL_checkstring(L, 1);
- const char *mode = luaL_optstring(L, 2, "r");
- LStream *p = newfile(L);
- const char *md = mode; /* to traverse/check mode */
- luaL_argcheck(L, l_checkmode(md), 2, "invalid mode");
- p->f = fopen(filename, mode);
- return (p->f == NULL) ? luaL_fileresult(L, 0, filename) : 1;
-}
-
-
-/*
-** function to close 'popen' files
-*/
-static int io_pclose (lua_State *L) {
- LStream *p = tolstream(L);
- return luaL_execresult(L, l_pclose(L, p->f));
-}
-
-
-static int io_popen (lua_State *L) {
- const char *filename = luaL_checkstring(L, 1);
- const char *mode = luaL_optstring(L, 2, "r");
- LStream *p = newprefile(L);
- p->f = l_popen(L, filename, mode);
- p->closef = &io_pclose;
- return (p->f == NULL) ? luaL_fileresult(L, 0, filename) : 1;
-}
-
-
-static int io_tmpfile (lua_State *L) {
- LStream *p = newfile(L);
- p->f = tmpfile();
- return (p->f == NULL) ? luaL_fileresult(L, 0, NULL) : 1;
-}
-
-
-static FILE *getiofile (lua_State *L, const char *findex) {
- LStream *p;
- lua_getfield(L, LUA_REGISTRYINDEX, findex);
- p = (LStream *)lua_touserdata(L, -1);
- if (isclosed(p))
- luaL_error(L, "standard %s file is closed", findex + IOPREF_LEN);
- return p->f;
-}
-
-
-static int g_iofile (lua_State *L, const char *f, const char *mode) {
- if (!lua_isnoneornil(L, 1)) {
- const char *filename = lua_tostring(L, 1);
- if (filename)
- opencheck(L, filename, mode);
- else {
- tofile(L); /* check that it's a valid file handle */
- lua_pushvalue(L, 1);
- }
- lua_setfield(L, LUA_REGISTRYINDEX, f);
- }
- /* return current value */
- lua_getfield(L, LUA_REGISTRYINDEX, f);
- return 1;
-}
-
-
-static int io_input (lua_State *L) {
- return g_iofile(L, IO_INPUT, "r");
-}
-
-
-static int io_output (lua_State *L) {
- return g_iofile(L, IO_OUTPUT, "w");
-}
-
-
-static int io_readline (lua_State *L);
-
-
-static void aux_lines (lua_State *L, int toclose) {
- int n = lua_gettop(L) - 1; /* number of arguments to read */
- lua_pushinteger(L, n); /* number of arguments to read */
- lua_pushboolean(L, toclose); /* close/not close file when finished */
- lua_rotate(L, 2, 2); /* move 'n' and 'toclose' to their positions */
- lua_pushcclosure(L, io_readline, 3 + n);
-}
-
-
-static int f_lines (lua_State *L) {
- tofile(L); /* check that it's a valid file handle */
- aux_lines(L, 0);
- return 1;
-}
-
-
-static int io_lines (lua_State *L) {
- int toclose;
- if (lua_isnone(L, 1)) lua_pushnil(L); /* at least one argument */
- if (lua_isnil(L, 1)) { /* no file name? */
- lua_getfield(L, LUA_REGISTRYINDEX, IO_INPUT); /* get default input */
- lua_replace(L, 1); /* put it at index 1 */
- tofile(L); /* check that it's a valid file handle */
- toclose = 0; /* do not close it after iteration */
- }
- else { /* open a new file */
- const char *filename = luaL_checkstring(L, 1);
- opencheck(L, filename, "r");
- lua_replace(L, 1); /* put file at index 1 */
- toclose = 1; /* close it after iteration */
- }
- aux_lines(L, toclose);
- return 1;
-}
-
-
-/*
-** {======================================================
-** READ
-** =======================================================
-*/
-
-
-/* maximum length of a numeral */
-#define MAXRN 200
-
-/* auxiliary structure used by 'read_number' */
-typedef struct {
- FILE *f; /* file being read */
- int c; /* current character (look ahead) */
- int n; /* number of elements in buffer 'buff' */
- char buff[MAXRN + 1]; /* +1 for ending '\0' */
-} RN;
-
-
-/*
-** Add current char to buffer (if not out of space) and read next one
-*/
-static int nextc (RN *rn) {
- if (rn->n >= MAXRN) { /* buffer overflow? */
- rn->buff[0] = '\0'; /* invalidate result */
- return 0; /* fail */
- }
- else {
- rn->buff[rn->n++] = rn->c; /* save current char */
- rn->c = l_getc(rn->f); /* read next one */
- return 1;
- }
-}
-
-
-/*
-** Accept current char if it is in 'set' (of size 1 or 2)
-*/
-static int test2 (RN *rn, const char *set) {
- if (rn->c == set[0] || (rn->c == set[1] && rn->c != '\0'))
- return nextc(rn);
- else return 0;
-}
-
-
-/*
-** Read a sequence of (hex)digits
-*/
-static int readdigits (RN *rn, int hex) {
- int count = 0;
- while ((hex ? isxdigit(rn->c) : isdigit(rn->c)) && nextc(rn))
- count++;
- return count;
-}
-
-
-/* access to locale "radix character" (decimal point) */
-#if !defined(l_getlocaledecpoint)
-#define l_getlocaledecpoint() (localeconv()->decimal_point[0])
-#endif
-
-
-/*
-** Read a number: first reads a valid prefix of a numeral into a buffer.
-** Then it calls 'lua_stringtonumber' to check whether the format is
-** correct and to convert it to a Lua number
-*/
-static int read_number (lua_State *L, FILE *f) {
- RN rn;
- int count = 0;
- int hex = 0;
- char decp[2] = ".";
- rn.f = f; rn.n = 0;
- decp[0] = l_getlocaledecpoint(); /* get decimal point from locale */
- l_lockfile(rn.f);
- do { rn.c = l_getc(rn.f); } while (isspace(rn.c)); /* skip spaces */
- test2(&rn, "-+"); /* optional signal */
- if (test2(&rn, "0")) {
- if (test2(&rn, "xX")) hex = 1; /* numeral is hexadecimal */
- else count = 1; /* count initial '0' as a valid digit */
- }
- count += readdigits(&rn, hex); /* integral part */
- if (test2(&rn, decp)) /* decimal point? */
- count += readdigits(&rn, hex); /* fractional part */
- if (count > 0 && test2(&rn, (hex ? "pP" : "eE"))) { /* exponent mark? */
- test2(&rn, "-+"); /* exponent signal */
- readdigits(&rn, 0); /* exponent digits */
- }
- ungetc(rn.c, rn.f); /* unread look-ahead char */
- l_unlockfile(rn.f);
- rn.buff[rn.n] = '\0'; /* finish string */
- if (lua_stringtonumber(L, rn.buff)) /* is this a valid number? */
- return 1; /* ok */
- else { /* invalid format */
- lua_pushnil(L); /* "result" to be removed */
- return 0; /* read fails */
- }
-}
-
-
-static int test_eof (lua_State *L, FILE *f) {
- int c = getc(f);
- ungetc(c, f); /* no-op when c == EOF */
- lua_pushlstring(L, NULL, 0);
- return (c != EOF);
-}
-
-
-static int read_line (lua_State *L, FILE *f, int chop) {
- luaL_Buffer b;
- int c = '\0';
- luaL_buffinit(L, &b);
- while (c != EOF && c != '\n') { /* repeat until end of line */
- char *buff = luaL_prepbuffer(&b); /* pre-allocate buffer */
- int i = 0;
- l_lockfile(f); /* no memory errors can happen inside the lock */
- while (i < LUAL_BUFFERSIZE && (c = l_getc(f)) != EOF && c != '\n')
- buff[i++] = c;
- l_unlockfile(f);
- luaL_addsize(&b, i);
- }
- if (!chop && c == '\n') /* want a newline and have one? */
- luaL_addchar(&b, c); /* add ending newline to result */
- luaL_pushresult(&b); /* close buffer */
- /* return ok if read something (either a newline or something else) */
- return (c == '\n' || lua_rawlen(L, -1) > 0);
-}
-
-
-static void read_all (lua_State *L, FILE *f) {
- size_t nr;
- luaL_Buffer b;
- luaL_buffinit(L, &b);
- do { /* read file in chunks of LUAL_BUFFERSIZE bytes */
- char *p = luaL_prepbuffsize(&b, LUAL_BUFFERSIZE);
- nr = fread(p, sizeof(char), LUAL_BUFFERSIZE, f);
- luaL_addsize(&b, nr);
- } while (nr == LUAL_BUFFERSIZE);
- luaL_pushresult(&b); /* close buffer */
-}
-
-
-static int read_chars (lua_State *L, FILE *f, size_t n) {
- size_t nr; /* number of chars actually read */
- char *p;
- luaL_Buffer b;
- luaL_buffinit(L, &b);
- p = luaL_prepbuffsize(&b, n); /* prepare buffer to read whole block */
- nr = fread(p, sizeof(char), n, f); /* try to read 'n' chars */
- luaL_addsize(&b, nr);
- luaL_pushresult(&b); /* close buffer */
- return (nr > 0); /* true iff read something */
-}
-
-
-static int g_read (lua_State *L, FILE *f, int first) {
- int nargs = lua_gettop(L) - 1;
- int success;
- int n;
- clearerr(f);
- if (nargs == 0) { /* no arguments? */
- success = read_line(L, f, 1);
- n = first+1; /* to return 1 result */
- }
- else { /* ensure stack space for all results and for auxlib's buffer */
- luaL_checkstack(L, nargs+LUA_MINSTACK, "too many arguments");
- success = 1;
- for (n = first; nargs-- && success; n++) {
- if (lua_type(L, n) == LUA_TNUMBER) {
- size_t l = (size_t)luaL_checkinteger(L, n);
- success = (l == 0) ? test_eof(L, f) : read_chars(L, f, l);
- }
- else {
- const char *p = luaL_checkstring(L, n);
- if (*p == '*') p++; /* skip optional '*' (for compatibility) */
- switch (*p) {
- case 'n': /* number */
- success = read_number(L, f);
- break;
- case 'l': /* line */
- success = read_line(L, f, 1);
- break;
- case 'L': /* line with end-of-line */
- success = read_line(L, f, 0);
- break;
- case 'a': /* file */
- read_all(L, f); /* read entire file */
- success = 1; /* always success */
- break;
- default:
- return luaL_argerror(L, n, "invalid format");
- }
- }
- }
- }
- if (ferror(f))
- return luaL_fileresult(L, 0, NULL);
- if (!success) {
- lua_pop(L, 1); /* remove last result */
- lua_pushnil(L); /* push nil instead */
- }
- return n - first;
-}
-
-
-static int io_read (lua_State *L) {
- return g_read(L, getiofile(L, IO_INPUT), 1);
-}
-
-
-static int f_read (lua_State *L) {
- return g_read(L, tofile(L), 2);
-}
-
-
-static int io_readline (lua_State *L) {
- LStream *p = (LStream *)lua_touserdata(L, lua_upvalueindex(1));
- int i;
- int n = (int)lua_tointeger(L, lua_upvalueindex(2));
- if (isclosed(p)) /* file is already closed? */
- return luaL_error(L, "file is already closed");
- lua_settop(L , 1);
- luaL_checkstack(L, n, "too many arguments");
- for (i = 1; i <= n; i++) /* push arguments to 'g_read' */
- lua_pushvalue(L, lua_upvalueindex(3 + i));
- n = g_read(L, p->f, 2); /* 'n' is number of results */
- lua_assert(n > 0); /* should return at least a nil */
- if (lua_toboolean(L, -n)) /* read at least one value? */
- return n; /* return them */
- else { /* first result is nil: EOF or error */
- if (n > 1) { /* is there error information? */
- /* 2nd result is error message */
- return luaL_error(L, "%s", lua_tostring(L, -n + 1));
- }
- if (lua_toboolean(L, lua_upvalueindex(3))) { /* generator created file? */
- lua_settop(L, 0);
- lua_pushvalue(L, lua_upvalueindex(1));
- aux_close(L); /* close it */
- }
- return 0;
- }
-}
-
-/* }====================================================== */
-
-
-static int g_write (lua_State *L, FILE *f, int arg) {
- int nargs = lua_gettop(L) - arg;
- int status = 1;
- for (; nargs--; arg++) {
- if (lua_type(L, arg) == LUA_TNUMBER) {
- /* optimization: could be done exactly as for strings */
- int len = lua_isinteger(L, arg)
- ? fprintf(f, LUA_INTEGER_FMT, lua_tointeger(L, arg))
- : fprintf(f, LUA_NUMBER_FMT, lua_tonumber(L, arg));
- status = status && (len > 0);
- }
- else {
- size_t l;
- const char *s = luaL_checklstring(L, arg, &l);
- status = status && (fwrite(s, sizeof(char), l, f) == l);
- }
- }
- if (status) return 1; /* file handle already on stack top */
- else return luaL_fileresult(L, status, NULL);
-}
-
-
-static int io_write (lua_State *L) {
- return g_write(L, getiofile(L, IO_OUTPUT), 1);
-}
-
-
-static int f_write (lua_State *L) {
- FILE *f = tofile(L);
- lua_pushvalue(L, 1); /* push file at the stack top (to be returned) */
- return g_write(L, f, 2);
-}
-
-
-static int f_seek (lua_State *L) {
- static const int mode[] = {SEEK_SET, SEEK_CUR, SEEK_END};
- static const char *const modenames[] = {"set", "cur", "end", NULL};
- FILE *f = tofile(L);
- int op = luaL_checkoption(L, 2, "cur", modenames);
- lua_Integer p3 = luaL_optinteger(L, 3, 0);
- l_seeknum offset = (l_seeknum)p3;
- luaL_argcheck(L, (lua_Integer)offset == p3, 3,
- "not an integer in proper range");
- op = l_fseek(f, offset, mode[op]);
- if (op)
- return luaL_fileresult(L, 0, NULL); /* error */
- else {
- lua_pushinteger(L, (lua_Integer)l_ftell(f));
- return 1;
- }
-}
-
-
-static int f_setvbuf (lua_State *L) {
- static const int mode[] = {_IONBF, _IOFBF, _IOLBF};
- static const char *const modenames[] = {"no", "full", "line", NULL};
- FILE *f = tofile(L);
- int op = luaL_checkoption(L, 2, NULL, modenames);
- lua_Integer sz = luaL_optinteger(L, 3, LUAL_BUFFERSIZE);
- int res = setvbuf(f, NULL, mode[op], (size_t)sz);
- return luaL_fileresult(L, res == 0, NULL);
-}
-
-
-
-static int io_flush (lua_State *L) {
- return luaL_fileresult(L, fflush(getiofile(L, IO_OUTPUT)) == 0, NULL);
-}
-
-
-static int f_flush (lua_State *L) {
- return luaL_fileresult(L, fflush(tofile(L)) == 0, NULL);
-}
-
-
-/*
-** functions for 'io' library
-*/
-static const luaL_Reg iolib[] = {
- {"close", io_close},
- {"flush", io_flush},
- {"input", io_input},
- {"lines", io_lines},
- {"open", io_open},
- {"output", io_output},
- {"popen", io_popen},
- {"read", io_read},
- {"tmpfile", io_tmpfile},
- {"type", io_type},
- {"write", io_write},
- {NULL, NULL}
-};
-
-
-/*
-** methods for file handles
-*/
-static const luaL_Reg flib[] = {
- {"close", io_close},
- {"flush", f_flush},
- {"lines", f_lines},
- {"read", f_read},
- {"seek", f_seek},
- {"setvbuf", f_setvbuf},
- {"write", f_write},
- {"__gc", f_gc},
- {"__tostring", f_tostring},
- {NULL, NULL}
-};
-
-
-static void createmeta (lua_State *L) {
- luaL_newmetatable(L, LUA_FILEHANDLE); /* create metatable for file handles */
- lua_pushvalue(L, -1); /* push metatable */
- lua_setfield(L, -2, "__index"); /* metatable.__index = metatable */
- luaL_setfuncs(L, flib, 0); /* add file methods to new metatable */
- lua_pop(L, 1); /* pop new metatable */
-}
-
-
-/*
-** function to (not) close the standard files stdin, stdout, and stderr
-*/
-static int io_noclose (lua_State *L) {
- LStream *p = tolstream(L);
- p->closef = &io_noclose; /* keep file opened */
- lua_pushnil(L);
- lua_pushliteral(L, "cannot close standard file");
- return 2;
-}
-
-
-static void createstdfile (lua_State *L, FILE *f, const char *k,
- const char *fname) {
- LStream *p = newprefile(L);
- p->f = f;
- p->closef = &io_noclose;
- if (k != NULL) {
- lua_pushvalue(L, -1);
- lua_setfield(L, LUA_REGISTRYINDEX, k); /* add file to registry */
- }
- lua_setfield(L, -2, fname); /* add file to module */
-}
-
-
-LUAMOD_API int luaopen_io (lua_State *L) {
- luaL_newlib(L, iolib); /* new module */
- createmeta(L);
- /* create (and set) default files */
- createstdfile(L, stdin, IO_INPUT, "stdin");
- createstdfile(L, stdout, IO_OUTPUT, "stdout");
- createstdfile(L, stderr, NULL, "stderr");
- return 1;
-}
-
diff --git a/3rd/lua/src/llex.c b/3rd/lua/src/llex.c
deleted file mode 100644
index 6e4a457..0000000
--- a/3rd/lua/src/llex.c
+++ /dev/null
@@ -1,602 +0,0 @@
-/*
-** $Id: llex.c,v 2.89 2014/11/14 16:06:09 roberto Exp $
-** Lexical Analyzer
-** See Copyright Notice in lua.h
-*/
-
-#define llex_c
-#define LUA_CORE
-
-#include "lprefix.h"
-
-
-#include
-#include
-
-#include "lua.h"
-
-#include "lctype.h"
-#include "ldo.h"
-#include "lgc.h"
-#include "llex.h"
-#include "lobject.h"
-#include "lparser.h"
-#include "lstate.h"
-#include "lstring.h"
-#include "ltable.h"
-#include "lzio.h"
-
-
-
-#define next(ls) (ls->current = zgetc(ls->z))
-
-
-
-#define currIsNewline(ls) (ls->current == '\n' || ls->current == '\r')
-
-
-/* ORDER RESERVED */
-static const char *const luaX_tokens [] = {
- "and", "break", "do", "else", "elseif",
- "end", "false", "for", "function", "goto", "if",
- "in", "local", "nil", "not", "or", "repeat",
- "return", "then", "true", "until", "while",
- "//", "..", "...", "==", ">=", "<=", "~=",
- "<<", ">>", "::", "",
- "", "", "", ""
-};
-
-
-#define save_and_next(ls) (save(ls, ls->current), next(ls))
-
-
-static l_noret lexerror (LexState *ls, const char *msg, int token);
-
-
-static void save (LexState *ls, int c) {
- Mbuffer *b = ls->buff;
- if (luaZ_bufflen(b) + 1 > luaZ_sizebuffer(b)) {
- size_t newsize;
- if (luaZ_sizebuffer(b) >= MAX_SIZE/2)
- lexerror(ls, "lexical element too long", 0);
- newsize = luaZ_sizebuffer(b) * 2;
- luaZ_resizebuffer(ls->L, b, newsize);
- }
- b->buffer[luaZ_bufflen(b)++] = cast(char, c);
-}
-
-
-void luaX_init (lua_State *L) {
- int i;
- TString *e = luaS_new(L, LUA_ENV); /* create env name */
- luaC_fix(L, obj2gco(e)); /* never collect this name */
- for (i=0; iextra = cast_byte(i+1); /* reserved word */
- }
-}
-
-
-const char *luaX_token2str (LexState *ls, int token) {
- if (token < FIRST_RESERVED) { /* single-byte symbols? */
- lua_assert(token == cast_uchar(token));
- return luaO_pushfstring(ls->L, "'%c'", token);
- }
- else {
- const char *s = luaX_tokens[token - FIRST_RESERVED];
- if (token < TK_EOS) /* fixed format (symbols and reserved words)? */
- return luaO_pushfstring(ls->L, "'%s'", s);
- else /* names, strings, and numerals */
- return s;
- }
-}
-
-
-static const char *txtToken (LexState *ls, int token) {
- switch (token) {
- case TK_NAME: case TK_STRING:
- case TK_FLT: case TK_INT:
- save(ls, '\0');
- return luaO_pushfstring(ls->L, "'%s'", luaZ_buffer(ls->buff));
- default:
- return luaX_token2str(ls, token);
- }
-}
-
-
-static l_noret lexerror (LexState *ls, const char *msg, int token) {
- char buff[LUA_IDSIZE];
- luaO_chunkid(buff, getstr(ls->source), LUA_IDSIZE);
- msg = luaO_pushfstring(ls->L, "%s:%d: %s", buff, ls->linenumber, msg);
- if (token)
- luaO_pushfstring(ls->L, "%s near %s", msg, txtToken(ls, token));
- luaD_throw(ls->L, LUA_ERRSYNTAX);
-}
-
-
-l_noret luaX_syntaxerror (LexState *ls, const char *msg) {
- lexerror(ls, msg, ls->t.token);
-}
-
-
-/*
-** creates a new string and anchors it in scanner's table so that
-** it will not be collected until the end of the compilation
-** (by that time it should be anchored somewhere)
-*/
-TString *luaX_newstring (LexState *ls, const char *str, size_t l) {
- lua_State *L = ls->L;
- TValue *o; /* entry for 'str' */
- TString *ts = luaS_newlstr(L, str, l); /* create new string */
- setsvalue2s(L, L->top++, ts); /* temporarily anchor it in stack */
- o = luaH_set(L, ls->h, L->top - 1);
- if (ttisnil(o)) { /* not in use yet? */
- /* boolean value does not need GC barrier;
- table has no metatable, so it does not need to invalidate cache */
- setbvalue(o, 1); /* t[string] = true */
- luaC_checkGC(L);
- }
- else { /* string already present */
- ts = tsvalue(keyfromval(o)); /* re-use value previously stored */
- }
- L->top--; /* remove string from stack */
- return ts;
-}
-
-
-/*
-** increment line number and skips newline sequence (any of
-** \n, \r, \n\r, or \r\n)
-*/
-static void inclinenumber (LexState *ls) {
- int old = ls->current;
- lua_assert(currIsNewline(ls));
- next(ls); /* skip '\n' or '\r' */
- if (currIsNewline(ls) && ls->current != old)
- next(ls); /* skip '\n\r' or '\r\n' */
- if (++ls->linenumber >= MAX_INT)
- lexerror(ls, "chunk has too many lines", 0);
-}
-
-
-void luaX_setinput (lua_State *L, LexState *ls, ZIO *z, TString *source,
- int firstchar) {
- ls->t.token = 0;
- ls->decpoint = '.';
- ls->L = L;
- ls->current = firstchar;
- ls->lookahead.token = TK_EOS; /* no look-ahead token */
- ls->z = z;
- ls->fs = NULL;
- ls->linenumber = 1;
- ls->lastline = 1;
- ls->source = source;
- ls->envn = luaS_new(L, LUA_ENV); /* get env name */
- luaZ_resizebuffer(ls->L, ls->buff, LUA_MINBUFFER); /* initialize buffer */
-}
-
-
-
-/*
-** =======================================================
-** LEXICAL ANALYZER
-** =======================================================
-*/
-
-
-static int check_next1 (LexState *ls, int c) {
- if (ls->current == c) {
- next(ls);
- return 1;
- }
- else return 0;
-}
-
-
-/*
-** Check whether current char is in set 'set' (with two chars) and
-** saves it
-*/
-static int check_next2 (LexState *ls, const char *set) {
- lua_assert(set[2] == '\0');
- if (ls->current == set[0] || ls->current == set[1]) {
- save_and_next(ls);
- return 1;
- }
- else return 0;
-}
-
-
-/*
-** change all characters 'from' in buffer to 'to'
-*/
-static void buffreplace (LexState *ls, char from, char to) {
- if (from != to) {
- size_t n = luaZ_bufflen(ls->buff);
- char *p = luaZ_buffer(ls->buff);
- while (n--)
- if (p[n] == from) p[n] = to;
- }
-}
-
-
-#if !defined(l_getlocaledecpoint)
-#define l_getlocaledecpoint() (localeconv()->decimal_point[0])
-#endif
-
-
-#define buff2num(b,o) (luaO_str2num(luaZ_buffer(b), o) != 0)
-
-/*
-** in case of format error, try to change decimal point separator to
-** the one defined in the current locale and check again
-*/
-static void trydecpoint (LexState *ls, TValue *o) {
- char old = ls->decpoint;
- ls->decpoint = l_getlocaledecpoint();
- buffreplace(ls, old, ls->decpoint); /* try new decimal separator */
- if (!buff2num(ls->buff, o)) {
- /* format error with correct decimal point: no more options */
- buffreplace(ls, ls->decpoint, '.'); /* undo change (for error message) */
- lexerror(ls, "malformed number", TK_FLT);
- }
-}
-
-
-/* LUA_NUMBER */
-/*
-** this function is quite liberal in what it accepts, as 'luaO_str2num'
-** will reject ill-formed numerals.
-*/
-static int read_numeral (LexState *ls, SemInfo *seminfo) {
- TValue obj;
- const char *expo = "Ee";
- int first = ls->current;
- lua_assert(lisdigit(ls->current));
- save_and_next(ls);
- if (first == '0' && check_next2(ls, "xX")) /* hexadecimal? */
- expo = "Pp";
- for (;;) {
- if (check_next2(ls, expo)) /* exponent part? */
- check_next2(ls, "-+"); /* optional exponent sign */
- if (lisxdigit(ls->current))
- save_and_next(ls);
- else if (ls->current == '.')
- save_and_next(ls);
- else break;
- }
- save(ls, '\0');
- buffreplace(ls, '.', ls->decpoint); /* follow locale for decimal point */
- if (!buff2num(ls->buff, &obj)) /* format error? */
- trydecpoint(ls, &obj); /* try to update decimal point separator */
- if (ttisinteger(&obj)) {
- seminfo->i = ivalue(&obj);
- return TK_INT;
- }
- else {
- lua_assert(ttisfloat(&obj));
- seminfo->r = fltvalue(&obj);
- return TK_FLT;
- }
-}
-
-
-/*
-** skip a sequence '[=*[' or ']=*]' and return its number of '='s or
-** -1 if sequence is malformed
-*/
-static int skip_sep (LexState *ls) {
- int count = 0;
- int s = ls->current;
- lua_assert(s == '[' || s == ']');
- save_and_next(ls);
- while (ls->current == '=') {
- save_and_next(ls);
- count++;
- }
- return (ls->current == s) ? count : (-count) - 1;
-}
-
-
-static void read_long_string (LexState *ls, SemInfo *seminfo, int sep) {
- int line = ls->linenumber; /* initial line (for error message) */
- save_and_next(ls); /* skip 2nd '[' */
- if (currIsNewline(ls)) /* string starts with a newline? */
- inclinenumber(ls); /* skip it */
- for (;;) {
- switch (ls->current) {
- case EOZ: { /* error */
- const char *what = (seminfo ? "string" : "comment");
- const char *msg = luaO_pushfstring(ls->L,
- "unfinished long %s (starting at line %d)", what, line);
- lexerror(ls, msg, TK_EOS);
- break; /* to avoid warnings */
- }
- case ']': {
- if (skip_sep(ls) == sep) {
- save_and_next(ls); /* skip 2nd ']' */
- goto endloop;
- }
- break;
- }
- case '\n': case '\r': {
- save(ls, '\n');
- inclinenumber(ls);
- if (!seminfo) luaZ_resetbuffer(ls->buff); /* avoid wasting space */
- break;
- }
- default: {
- if (seminfo) save_and_next(ls);
- else next(ls);
- }
- }
- } endloop:
- if (seminfo)
- seminfo->ts = luaX_newstring(ls, luaZ_buffer(ls->buff) + (2 + sep),
- luaZ_bufflen(ls->buff) - 2*(2 + sep));
-}
-
-
-static void esccheck (LexState *ls, int c, const char *msg) {
- if (!c) {
- if (ls->current != EOZ)
- save_and_next(ls); /* add current to buffer for error message */
- lexerror(ls, msg, TK_STRING);
- }
-}
-
-
-static int gethexa (LexState *ls) {
- save_and_next(ls);
- esccheck (ls, lisxdigit(ls->current), "hexadecimal digit expected");
- return luaO_hexavalue(ls->current);
-}
-
-
-static int readhexaesc (LexState *ls) {
- int r = gethexa(ls);
- r = (r << 4) + gethexa(ls);
- luaZ_buffremove(ls->buff, 2); /* remove saved chars from buffer */
- return r;
-}
-
-
-static unsigned long readutf8esc (LexState *ls) {
- unsigned long r;
- int i = 4; /* chars to be removed: '\', 'u', '{', and first digit */
- save_and_next(ls); /* skip 'u' */
- esccheck(ls, ls->current == '{', "missing '{'");
- r = gethexa(ls); /* must have at least one digit */
- while ((save_and_next(ls), lisxdigit(ls->current))) {
- i++;
- r = (r << 4) + luaO_hexavalue(ls->current);
- esccheck(ls, r <= 0x10FFFF, "UTF-8 value too large");
- }
- esccheck(ls, ls->current == '}', "missing '}'");
- next(ls); /* skip '}' */
- luaZ_buffremove(ls->buff, i); /* remove saved chars from buffer */
- return r;
-}
-
-
-static void utf8esc (LexState *ls) {
- char buff[UTF8BUFFSZ];
- int n = luaO_utf8esc(buff, readutf8esc(ls));
- for (; n > 0; n--) /* add 'buff' to string */
- save(ls, buff[UTF8BUFFSZ - n]);
-}
-
-
-static int readdecesc (LexState *ls) {
- int i;
- int r = 0; /* result accumulator */
- for (i = 0; i < 3 && lisdigit(ls->current); i++) { /* read up to 3 digits */
- r = 10*r + ls->current - '0';
- save_and_next(ls);
- }
- esccheck(ls, r <= UCHAR_MAX, "decimal escape too large");
- luaZ_buffremove(ls->buff, i); /* remove read digits from buffer */
- return r;
-}
-
-
-static void read_string (LexState *ls, int del, SemInfo *seminfo) {
- save_and_next(ls); /* keep delimiter (for error messages) */
- while (ls->current != del) {
- switch (ls->current) {
- case EOZ:
- lexerror(ls, "unfinished string", TK_EOS);
- break; /* to avoid warnings */
- case '\n':
- case '\r':
- lexerror(ls, "unfinished string", TK_STRING);
- break; /* to avoid warnings */
- case '\\': { /* escape sequences */
- int c; /* final character to be saved */
- save_and_next(ls); /* keep '\\' for error messages */
- switch (ls->current) {
- case 'a': c = '\a'; goto read_save;
- case 'b': c = '\b'; goto read_save;
- case 'f': c = '\f'; goto read_save;
- case 'n': c = '\n'; goto read_save;
- case 'r': c = '\r'; goto read_save;
- case 't': c = '\t'; goto read_save;
- case 'v': c = '\v'; goto read_save;
- case 'x': c = readhexaesc(ls); goto read_save;
- case 'u': utf8esc(ls); goto no_save;
- case '\n': case '\r':
- inclinenumber(ls); c = '\n'; goto only_save;
- case '\\': case '\"': case '\'':
- c = ls->current; goto read_save;
- case EOZ: goto no_save; /* will raise an error next loop */
- case 'z': { /* zap following span of spaces */
- luaZ_buffremove(ls->buff, 1); /* remove '\\' */
- next(ls); /* skip the 'z' */
- while (lisspace(ls->current)) {
- if (currIsNewline(ls)) inclinenumber(ls);
- else next(ls);
- }
- goto no_save;
- }
- default: {
- esccheck(ls, lisdigit(ls->current), "invalid escape sequence");
- c = readdecesc(ls); /* digital escape '\ddd' */
- goto only_save;
- }
- }
- read_save:
- next(ls);
- /* go through */
- only_save:
- luaZ_buffremove(ls->buff, 1); /* remove '\\' */
- save(ls, c);
- /* go through */
- no_save: break;
- }
- default:
- save_and_next(ls);
- }
- }
- save_and_next(ls); /* skip delimiter */
- seminfo->ts = luaX_newstring(ls, luaZ_buffer(ls->buff) + 1,
- luaZ_bufflen(ls->buff) - 2);
-}
-
-
-static int llex (LexState *ls, SemInfo *seminfo) {
- luaZ_resetbuffer(ls->buff);
- for (;;) {
- switch (ls->current) {
- case '\n': case '\r': { /* line breaks */
- inclinenumber(ls);
- break;
- }
- case ' ': case '\f': case '\t': case '\v': { /* spaces */
- next(ls);
- break;
- }
- case '-': { /* '-' or '--' (comment) */
- next(ls);
- if (ls->current != '-') return '-';
- /* else is a comment */
- next(ls);
- if (ls->current == '[') { /* long comment? */
- int sep = skip_sep(ls);
- luaZ_resetbuffer(ls->buff); /* 'skip_sep' may dirty the buffer */
- if (sep >= 0) {
- read_long_string(ls, NULL, sep); /* skip long comment */
- luaZ_resetbuffer(ls->buff); /* previous call may dirty the buff. */
- break;
- }
- }
- /* else short comment */
- while (!currIsNewline(ls) && ls->current != EOZ)
- next(ls); /* skip until end of line (or end of file) */
- break;
- }
- case '[': { /* long string or simply '[' */
- int sep = skip_sep(ls);
- if (sep >= 0) {
- read_long_string(ls, seminfo, sep);
- return TK_STRING;
- }
- else if (sep == -1) return '[';
- else lexerror(ls, "invalid long string delimiter", TK_STRING);
- }
- case '=': {
- next(ls);
- if (check_next1(ls, '=')) return TK_EQ;
- else return '=';
- }
- case '<': {
- next(ls);
- if (check_next1(ls, '=')) return TK_LE;
- else if (check_next1(ls, '<')) return TK_SHL;
- else return '<';
- }
- case '>': {
- next(ls);
- if (check_next1(ls, '=')) return TK_GE;
- else if (check_next1(ls, '>')) return TK_SHR;
- else return '>';
- }
- case '/': {
- next(ls);
- if (check_next1(ls, '/')) return TK_IDIV;
- else return '/';
- }
- case '~': {
- next(ls);
- if (check_next1(ls, '=')) return TK_NE;
- else return '~';
- }
- case ':': {
- next(ls);
- if (check_next1(ls, ':')) return TK_DBCOLON;
- else return ':';
- }
- case '"': case '\'': { /* short literal strings */
- read_string(ls, ls->current, seminfo);
- return TK_STRING;
- }
- case '.': { /* '.', '..', '...', or number */
- save_and_next(ls);
- if (check_next1(ls, '.')) {
- if (check_next1(ls, '.'))
- return TK_DOTS; /* '...' */
- else return TK_CONCAT; /* '..' */
- }
- else if (!lisdigit(ls->current)) return '.';
- else return read_numeral(ls, seminfo);
- }
- case '0': case '1': case '2': case '3': case '4':
- case '5': case '6': case '7': case '8': case '9': {
- return read_numeral(ls, seminfo);
- }
- case EOZ: {
- return TK_EOS;
- }
- default: {
- if (lislalpha(ls->current)) { /* identifier or reserved word? */
- TString *ts;
- do {
- save_and_next(ls);
- } while (lislalnum(ls->current));
- ts = luaX_newstring(ls, luaZ_buffer(ls->buff),
- luaZ_bufflen(ls->buff));
- seminfo->ts = ts;
- if (isreserved(ts)) /* reserved word? */
- return ts->extra - 1 + FIRST_RESERVED;
- else {
- return TK_NAME;
- }
- }
- else { /* single-char tokens (+ - / ...) */
- int c = ls->current;
- next(ls);
- return c;
- }
- }
- }
- }
-}
-
-
-void luaX_next (LexState *ls) {
- ls->lastline = ls->linenumber;
- if (ls->lookahead.token != TK_EOS) { /* is there a look-ahead token? */
- ls->t = ls->lookahead; /* use this one */
- ls->lookahead.token = TK_EOS; /* and discharge it */
- }
- else
- ls->t.token = llex(ls, &ls->t.seminfo); /* read next token */
-}
-
-
-int luaX_lookahead (LexState *ls) {
- lua_assert(ls->lookahead.token == TK_EOS);
- ls->lookahead.token = llex(ls, &ls->lookahead.seminfo);
- return ls->lookahead.token;
-}
-
diff --git a/3rd/lua/src/llex.h b/3rd/lua/src/llex.h
deleted file mode 100644
index afb40b5..0000000
--- a/3rd/lua/src/llex.h
+++ /dev/null
@@ -1,86 +0,0 @@
-/*
-** $Id: llex.h,v 1.78 2014/10/29 15:38:24 roberto Exp $
-** Lexical Analyzer
-** See Copyright Notice in lua.h
-*/
-
-#ifndef llex_h
-#define llex_h
-
-#include "lobject.h"
-#include "lzio.h"
-
-
-#define FIRST_RESERVED 257
-
-
-#if !defined(LUA_ENV)
-#define LUA_ENV "_ENV"
-#endif
-
-
-/*
-* WARNING: if you change the order of this enumeration,
-* grep "ORDER RESERVED"
-*/
-enum RESERVED {
- /* terminal symbols denoted by reserved words */
- TK_AND = FIRST_RESERVED, TK_BREAK,
- TK_DO, TK_ELSE, TK_ELSEIF, TK_END, TK_FALSE, TK_FOR, TK_FUNCTION,
- TK_GOTO, TK_IF, TK_IN, TK_LOCAL, TK_NIL, TK_NOT, TK_OR, TK_REPEAT,
- TK_RETURN, TK_THEN, TK_TRUE, TK_UNTIL, TK_WHILE,
- /* other terminal symbols */
- TK_IDIV, TK_CONCAT, TK_DOTS, TK_EQ, TK_GE, TK_LE, TK_NE,
- TK_SHL, TK_SHR,
- TK_DBCOLON, TK_EOS,
- TK_FLT, TK_INT, TK_NAME, TK_STRING
-};
-
-/* number of reserved words */
-#define NUM_RESERVED (cast(int, TK_WHILE-FIRST_RESERVED+1))
-
-
-typedef union {
- lua_Number r;
- lua_Integer i;
- TString *ts;
-} SemInfo; /* semantics information */
-
-
-typedef struct Token {
- int token;
- SemInfo seminfo;
-} Token;
-
-
-/* state of the lexer plus state of the parser when shared by all
- functions */
-typedef struct LexState {
- int current; /* current character (charint) */
- int linenumber; /* input line counter */
- int lastline; /* line of last token 'consumed' */
- Token t; /* current token */
- Token lookahead; /* look ahead token */
- struct FuncState *fs; /* current function (parser) */
- struct lua_State *L;
- ZIO *z; /* input stream */
- Mbuffer *buff; /* buffer for tokens */
- Table *h; /* to avoid collection/reuse strings */
- struct Dyndata *dyd; /* dynamic structures used by the parser */
- TString *source; /* current source name */
- TString *envn; /* environment variable name */
- char decpoint; /* locale decimal point */
-} LexState;
-
-
-LUAI_FUNC void luaX_init (lua_State *L);
-LUAI_FUNC void luaX_setinput (lua_State *L, LexState *ls, ZIO *z,
- TString *source, int firstchar);
-LUAI_FUNC TString *luaX_newstring (LexState *ls, const char *str, size_t l);
-LUAI_FUNC void luaX_next (LexState *ls);
-LUAI_FUNC int luaX_lookahead (LexState *ls);
-LUAI_FUNC l_noret luaX_syntaxerror (LexState *ls, const char *s);
-LUAI_FUNC const char *luaX_token2str (LexState *ls, int token);
-
-
-#endif
diff --git a/3rd/lua/src/llimits.h b/3rd/lua/src/llimits.h
deleted file mode 100644
index 8f71a6f..0000000
--- a/3rd/lua/src/llimits.h
+++ /dev/null
@@ -1,242 +0,0 @@
-/*
-** $Id: llimits.h,v 1.125 2014/12/19 13:30:23 roberto Exp $
-** Limits, basic types, and some other 'installation-dependent' definitions
-** See Copyright Notice in lua.h
-*/
-
-#ifndef llimits_h
-#define llimits_h
-
-
-#include
-#include
-
-
-#include "lua.h"
-
-/*
-** 'lu_mem' and 'l_mem' are unsigned/signed integers big enough to count
-** the total memory used by Lua (in bytes). Usually, 'size_t' and
-** 'ptrdiff_t' should work, but we use 'long' for 16-bit machines.
-*/
-#if defined(LUAI_MEM) /* { external definitions? */
-typedef LUAI_UMEM lu_mem;
-typedef LUAI_MEM l_mem;
-#elif LUAI_BITSINT >= 32 /* }{ */
-typedef size_t lu_mem;
-typedef ptrdiff_t l_mem;
-#else /* 16-bit ints */ /* }{ */
-typedef unsigned long lu_mem;
-typedef long l_mem;
-#endif /* } */
-
-
-/* chars used as small naturals (so that 'char' is reserved for characters) */
-typedef unsigned char lu_byte;
-
-
-/* maximum value for size_t */
-#define MAX_SIZET ((size_t)(~(size_t)0))
-
-/* maximum size visible for Lua (must be representable in a lua_Integer */
-#define MAX_SIZE (sizeof(size_t) < sizeof(lua_Integer) ? MAX_SIZET \
- : (size_t)(LUA_MAXINTEGER))
-
-
-#define MAX_LUMEM ((lu_mem)(~(lu_mem)0))
-
-#define MAX_LMEM ((l_mem)(MAX_LUMEM >> 1))
-
-
-#define MAX_INT INT_MAX /* maximum value of an int */
-
-
-/*
-** conversion of pointer to integer:
-** this is for hashing only; there is no problem if the integer
-** cannot hold the whole pointer value
-*/
-#define point2int(p) ((unsigned int)((size_t)(p) & UINT_MAX))
-
-
-
-/* type to ensure maximum alignment */
-#if defined(LUAI_USER_ALIGNMENT_T)
-typedef LUAI_USER_ALIGNMENT_T L_Umaxalign;
-#else
-typedef union { double u; void *s; lua_Integer i; long l; } L_Umaxalign;
-#endif
-
-
-
-/* types of 'usual argument conversions' for lua_Number and lua_Integer */
-typedef LUAI_UACNUMBER l_uacNumber;
-typedef LUAI_UACINT l_uacInt;
-
-
-/* internal assertions for in-house debugging */
-#if defined(lua_assert)
-#define check_exp(c,e) (lua_assert(c), (e))
-/* to avoid problems with conditions too long */
-#define lua_longassert(c) { if (!(c)) lua_assert(0); }
-#else
-#define lua_assert(c) ((void)0)
-#define check_exp(c,e) (e)
-#define lua_longassert(c) ((void)0)
-#endif
-
-/*
-** assertion for checking API calls
-*/
-#if defined(LUA_USE_APICHECK)
-#include
-#define luai_apicheck(e) assert(e)
-#else
-#define luai_apicheck(e) lua_assert(e)
-#endif
-
-
-#define api_check(e,msg) luai_apicheck((e) && msg)
-
-
-#if !defined(UNUSED)
-#define UNUSED(x) ((void)(x)) /* to avoid warnings */
-#endif
-
-
-#define cast(t, exp) ((t)(exp))
-
-#define cast_void(i) cast(void, (i))
-#define cast_byte(i) cast(lu_byte, (i))
-#define cast_num(i) cast(lua_Number, (i))
-#define cast_int(i) cast(int, (i))
-#define cast_uchar(i) cast(unsigned char, (i))
-
-
-/* cast a signed lua_Integer to lua_Unsigned */
-#if !defined(l_castS2U)
-#define l_castS2U(i) ((lua_Unsigned)(i))
-#endif
-
-/*
-** cast a lua_Unsigned to a signed lua_Integer; this cast is
-** not strict ISO C, but two-complement architectures should
-** work fine.
-*/
-#if !defined(l_castU2S)
-#define l_castU2S(i) ((lua_Integer)(i))
-#endif
-
-
-/*
-** non-return type
-*/
-#if defined(__GNUC__)
-#define l_noret void __attribute__((noreturn))
-#elif defined(_MSC_VER) && _MSC_VER >= 1200
-#define l_noret void __declspec(noreturn)
-#else
-#define l_noret void
-#endif
-
-
-
-/*
-** maximum depth for nested C calls and syntactical nested non-terminals
-** in a program. (Value must fit in an unsigned short int.)
-*/
-#if !defined(LUAI_MAXCCALLS)
-#define LUAI_MAXCCALLS 200
-#endif
-
-/*
-** maximum number of upvalues in a closure (both C and Lua). (Value
-** must fit in an unsigned char.)
-*/
-#define MAXUPVAL UCHAR_MAX
-
-
-/*
-** type for virtual-machine instructions;
-** must be an unsigned with (at least) 4 bytes (see details in lopcodes.h)
-*/
-#if LUAI_BITSINT >= 32
-typedef unsigned int Instruction;
-#else
-typedef unsigned long Instruction;
-#endif
-
-
-
-
-/* minimum size for the string table (must be power of 2) */
-#if !defined(MINSTRTABSIZE)
-#define MINSTRTABSIZE 64 /* minimum size for "predefined" strings */
-#endif
-
-
-/* minimum size for string buffer */
-#if !defined(LUA_MINBUFFER)
-#define LUA_MINBUFFER 32
-#endif
-
-
-#if !defined(lua_lock)
-#define lua_lock(L) ((void) 0)
-#define lua_unlock(L) ((void) 0)
-#endif
-
-#if !defined(luai_threadyield)
-#define luai_threadyield(L) {lua_unlock(L); lua_lock(L);}
-#endif
-
-
-/*
-** these macros allow user-specific actions on threads when you defined
-** LUAI_EXTRASPACE and need to do something extra when a thread is
-** created/deleted/resumed/yielded.
-*/
-#if !defined(luai_userstateopen)
-#define luai_userstateopen(L) ((void)L)
-#endif
-
-#if !defined(luai_userstateclose)
-#define luai_userstateclose(L) ((void)L)
-#endif
-
-#if !defined(luai_userstatethread)
-#define luai_userstatethread(L,L1) ((void)L)
-#endif
-
-#if !defined(luai_userstatefree)
-#define luai_userstatefree(L,L1) ((void)L)
-#endif
-
-#if !defined(luai_userstateresume)
-#define luai_userstateresume(L,n) ((void)L)
-#endif
-
-#if !defined(luai_userstateyield)
-#define luai_userstateyield(L,n) ((void)L)
-#endif
-
-
-
-/*
-** macro to control inclusion of some hard tests on stack reallocation
-*/
-#if !defined(HARDSTACKTESTS)
-#define condmovestack(L) ((void)0)
-#else
-/* realloc stack keeping its size */
-#define condmovestack(L) luaD_reallocstack((L), (L)->stacksize)
-#endif
-
-#if !defined(HARDMEMTESTS)
-#define condchangemem(L) condmovestack(L)
-#else
-#define condchangemem(L) \
- ((void)(!(G(L)->gcrunning) || (luaC_fullgc(L, 0), 1)))
-#endif
-
-#endif
diff --git a/3rd/lua/src/lmathlib.c b/3rd/lua/src/lmathlib.c
deleted file mode 100644
index 002c508..0000000
--- a/3rd/lua/src/lmathlib.c
+++ /dev/null
@@ -1,404 +0,0 @@
-/*
-** $Id: lmathlib.c,v 1.114 2014/12/27 20:32:26 roberto Exp $
-** Standard mathematical library
-** See Copyright Notice in lua.h
-*/
-
-#define lmathlib_c
-#define LUA_LIB
-
-#include "lprefix.h"
-
-
-#include
-#include
-
-#include "lua.h"
-
-#include "lauxlib.h"
-#include "lualib.h"
-
-
-#undef PI
-#define PI (l_mathop(3.141592653589793238462643383279502884))
-
-
-#if !defined(l_rand) /* { */
-#if defined(LUA_USE_POSIX)
-#define l_rand() random()
-#define l_srand(x) srandom(x)
-#define L_RANDMAX 2147483647 /* (2^31 - 1), following POSIX */
-#else
-#define l_rand() rand()
-#define l_srand(x) srand(x)
-#define L_RANDMAX RAND_MAX
-#endif
-#endif /* } */
-
-
-static int math_abs (lua_State *L) {
- if (lua_isinteger(L, 1)) {
- lua_Integer n = lua_tointeger(L, 1);
- if (n < 0) n = (lua_Integer)(0u - n);
- lua_pushinteger(L, n);
- }
- else
- lua_pushnumber(L, l_mathop(fabs)(luaL_checknumber(L, 1)));
- return 1;
-}
-
-static int math_sin (lua_State *L) {
- lua_pushnumber(L, l_mathop(sin)(luaL_checknumber(L, 1)));
- return 1;
-}
-
-static int math_cos (lua_State *L) {
- lua_pushnumber(L, l_mathop(cos)(luaL_checknumber(L, 1)));
- return 1;
-}
-
-static int math_tan (lua_State *L) {
- lua_pushnumber(L, l_mathop(tan)(luaL_checknumber(L, 1)));
- return 1;
-}
-
-static int math_asin (lua_State *L) {
- lua_pushnumber(L, l_mathop(asin)(luaL_checknumber(L, 1)));
- return 1;
-}
-
-static int math_acos (lua_State *L) {
- lua_pushnumber(L, l_mathop(acos)(luaL_checknumber(L, 1)));
- return 1;
-}
-
-static int math_atan (lua_State *L) {
- lua_Number y = luaL_checknumber(L, 1);
- lua_Number x = luaL_optnumber(L, 2, 1);
- lua_pushnumber(L, l_mathop(atan2)(y, x));
- return 1;
-}
-
-
-static int math_toint (lua_State *L) {
- int valid;
- lua_Integer n = lua_tointegerx(L, 1, &valid);
- if (valid)
- lua_pushinteger(L, n);
- else {
- luaL_checkany(L, 1);
- lua_pushnil(L); /* value is not convertible to integer */
- }
- return 1;
-}
-
-
-static void pushnumint (lua_State *L, lua_Number d) {
- lua_Integer n;
- if (lua_numbertointeger(d, &n)) /* does 'd' fit in an integer? */
- lua_pushinteger(L, n); /* result is integer */
- else
- lua_pushnumber(L, d); /* result is float */
-}
-
-
-static int math_floor (lua_State *L) {
- if (lua_isinteger(L, 1))
- lua_settop(L, 1); /* integer is its own floor */
- else {
- lua_Number d = l_mathop(floor)(luaL_checknumber(L, 1));
- pushnumint(L, d);
- }
- return 1;
-}
-
-
-static int math_ceil (lua_State *L) {
- if (lua_isinteger(L, 1))
- lua_settop(L, 1); /* integer is its own ceil */
- else {
- lua_Number d = l_mathop(ceil)(luaL_checknumber(L, 1));
- pushnumint(L, d);
- }
- return 1;
-}
-
-
-static int math_fmod (lua_State *L) {
- if (lua_isinteger(L, 1) && lua_isinteger(L, 2)) {
- lua_Integer d = lua_tointeger(L, 2);
- if ((lua_Unsigned)d + 1u <= 1u) { /* special cases: -1 or 0 */
- luaL_argcheck(L, d != 0, 2, "zero");
- lua_pushinteger(L, 0); /* avoid overflow with 0x80000... / -1 */
- }
- else
- lua_pushinteger(L, lua_tointeger(L, 1) % d);
- }
- else
- lua_pushnumber(L, l_mathop(fmod)(luaL_checknumber(L, 1),
- luaL_checknumber(L, 2)));
- return 1;
-}
-
-
-/*
-** next function does not use 'modf', avoiding problems with 'double*'
-** (which is not compatible with 'float*') when lua_Number is not
-** 'double'.
-*/
-static int math_modf (lua_State *L) {
- if (lua_isinteger(L ,1)) {
- lua_settop(L, 1); /* number is its own integer part */
- lua_pushnumber(L, 0); /* no fractional part */
- }
- else {
- lua_Number n = luaL_checknumber(L, 1);
- /* integer part (rounds toward zero) */
- lua_Number ip = (n < 0) ? l_mathop(ceil)(n) : l_mathop(floor)(n);
- pushnumint(L, ip);
- /* fractional part (test needed for inf/-inf) */
- lua_pushnumber(L, (n == ip) ? l_mathop(0.0) : (n - ip));
- }
- return 2;
-}
-
-
-static int math_sqrt (lua_State *L) {
- lua_pushnumber(L, l_mathop(sqrt)(luaL_checknumber(L, 1)));
- return 1;
-}
-
-
-static int math_ult (lua_State *L) {
- lua_Integer a = luaL_checkinteger(L, 1);
- lua_Integer b = luaL_checkinteger(L, 2);
- lua_pushboolean(L, (lua_Unsigned)a < (lua_Unsigned)b);
- return 1;
-}
-
-static int math_log (lua_State *L) {
- lua_Number x = luaL_checknumber(L, 1);
- lua_Number res;
- if (lua_isnoneornil(L, 2))
- res = l_mathop(log)(x);
- else {
- lua_Number base = luaL_checknumber(L, 2);
- if (base == 10.0) res = l_mathop(log10)(x);
- else res = l_mathop(log)(x)/l_mathop(log)(base);
- }
- lua_pushnumber(L, res);
- return 1;
-}
-
-static int math_exp (lua_State *L) {
- lua_pushnumber(L, l_mathop(exp)(luaL_checknumber(L, 1)));
- return 1;
-}
-
-static int math_deg (lua_State *L) {
- lua_pushnumber(L, luaL_checknumber(L, 1) * (l_mathop(180.0) / PI));
- return 1;
-}
-
-static int math_rad (lua_State *L) {
- lua_pushnumber(L, luaL_checknumber(L, 1) * (PI / l_mathop(180.0)));
- return 1;
-}
-
-
-static int math_min (lua_State *L) {
- int n = lua_gettop(L); /* number of arguments */
- int imin = 1; /* index of current minimum value */
- int i;
- luaL_argcheck(L, n >= 1, 1, "value expected");
- for (i = 2; i <= n; i++) {
- if (lua_compare(L, i, imin, LUA_OPLT))
- imin = i;
- }
- lua_pushvalue(L, imin);
- return 1;
-}
-
-
-static int math_max (lua_State *L) {
- int n = lua_gettop(L); /* number of arguments */
- int imax = 1; /* index of current maximum value */
- int i;
- luaL_argcheck(L, n >= 1, 1, "value expected");
- for (i = 2; i <= n; i++) {
- if (lua_compare(L, imax, i, LUA_OPLT))
- imax = i;
- }
- lua_pushvalue(L, imax);
- return 1;
-}
-
-/*
-** This function uses 'double' (instead of 'lua_Number') to ensure that
-** all bits from 'l_rand' can be represented, and that 'RANDMAX + 1.0'
-** will keep full precision (ensuring that 'r' is always less than 1.0.)
-*/
-static int math_random (lua_State *L) {
- lua_Integer low, up;
- double r = (double)l_rand() * (1.0 / ((double)L_RANDMAX + 1.0));
- switch (lua_gettop(L)) { /* check number of arguments */
- case 0: { /* no arguments */
- lua_pushnumber(L, (lua_Number)r); /* Number between 0 and 1 */
- return 1;
- }
- case 1: { /* only upper limit */
- low = 1;
- up = luaL_checkinteger(L, 1);
- break;
- }
- case 2: { /* lower and upper limits */
- low = luaL_checkinteger(L, 1);
- up = luaL_checkinteger(L, 2);
- break;
- }
- default: return luaL_error(L, "wrong number of arguments");
- }
- /* random integer in the interval [low, up] */
- luaL_argcheck(L, low <= up, 1, "interval is empty");
- luaL_argcheck(L, low >= 0 || up <= LUA_MAXINTEGER + low, 1,
- "interval too large");
- r *= (double)(up - low) + 1.0;
- lua_pushinteger(L, (lua_Integer)r + low);
- return 1;
-}
-
-
-static int math_randomseed (lua_State *L) {
- l_srand((unsigned int)(lua_Integer)luaL_checknumber(L, 1));
- (void)rand(); /* discard first value to avoid undesirable correlations */
- return 0;
-}
-
-
-static int math_type (lua_State *L) {
- if (lua_type(L, 1) == LUA_TNUMBER) {
- if (lua_isinteger(L, 1))
- lua_pushliteral(L, "integer");
- else
- lua_pushliteral(L, "float");
- }
- else {
- luaL_checkany(L, 1);
- lua_pushnil(L);
- }
- return 1;
-}
-
-
-/*
-** {==================================================================
-** Deprecated functions (for compatibility only)
-** ===================================================================
-*/
-#if defined(LUA_COMPAT_MATHLIB)
-
-static int math_cosh (lua_State *L) {
- lua_pushnumber(L, l_mathop(cosh)(luaL_checknumber(L, 1)));
- return 1;
-}
-
-static int math_sinh (lua_State *L) {
- lua_pushnumber(L, l_mathop(sinh)(luaL_checknumber(L, 1)));
- return 1;
-}
-
-static int math_tanh (lua_State *L) {
- lua_pushnumber(L, l_mathop(tanh)(luaL_checknumber(L, 1)));
- return 1;
-}
-
-static int math_pow (lua_State *L) {
- lua_Number x = luaL_checknumber(L, 1);
- lua_Number y = luaL_checknumber(L, 2);
- lua_pushnumber(L, l_mathop(pow)(x, y));
- return 1;
-}
-
-static int math_frexp (lua_State *L) {
- int e;
- lua_pushnumber(L, l_mathop(frexp)(luaL_checknumber(L, 1), &e));
- lua_pushinteger(L, e);
- return 2;
-}
-
-static int math_ldexp (lua_State *L) {
- lua_Number x = luaL_checknumber(L, 1);
- int ep = (int)luaL_checkinteger(L, 2);
- lua_pushnumber(L, l_mathop(ldexp)(x, ep));
- return 1;
-}
-
-static int math_log10 (lua_State *L) {
- lua_pushnumber(L, l_mathop(log10)(luaL_checknumber(L, 1)));
- return 1;
-}
-
-#endif
-/* }================================================================== */
-
-
-
-static const luaL_Reg mathlib[] = {
- {"abs", math_abs},
- {"acos", math_acos},
- {"asin", math_asin},
- {"atan", math_atan},
- {"ceil", math_ceil},
- {"cos", math_cos},
- {"deg", math_deg},
- {"exp", math_exp},
- {"tointeger", math_toint},
- {"floor", math_floor},
- {"fmod", math_fmod},
- {"ult", math_ult},
- {"log", math_log},
- {"max", math_max},
- {"min", math_min},
- {"modf", math_modf},
- {"rad", math_rad},
- {"random", math_random},
- {"randomseed", math_randomseed},
- {"sin", math_sin},
- {"sqrt", math_sqrt},
- {"tan", math_tan},
- {"type", math_type},
-#if defined(LUA_COMPAT_MATHLIB)
- {"atan2", math_atan},
- {"cosh", math_cosh},
- {"sinh", math_sinh},
- {"tanh", math_tanh},
- {"pow", math_pow},
- {"frexp", math_frexp},
- {"ldexp", math_ldexp},
- {"log10", math_log10},
-#endif
- /* placeholders */
- {"pi", NULL},
- {"huge", NULL},
- {"maxinteger", NULL},
- {"mininteger", NULL},
- {NULL, NULL}
-};
-
-
-/*
-** Open math library
-*/
-LUAMOD_API int luaopen_math (lua_State *L) {
- luaL_newlib(L, mathlib);
- lua_pushnumber(L, PI);
- lua_setfield(L, -2, "pi");
- lua_pushnumber(L, (lua_Number)HUGE_VAL);
- lua_setfield(L, -2, "huge");
- lua_pushinteger(L, LUA_MAXINTEGER);
- lua_setfield(L, -2, "maxinteger");
- lua_pushinteger(L, LUA_MININTEGER);
- lua_setfield(L, -2, "mininteger");
- return 1;
-}
-
diff --git a/3rd/lua/src/lmem.c b/3rd/lua/src/lmem.c
deleted file mode 100644
index 4feaf03..0000000
--- a/3rd/lua/src/lmem.c
+++ /dev/null
@@ -1,99 +0,0 @@
-/*
-** $Id: lmem.c,v 1.89 2014/11/02 19:33:33 roberto Exp $
-** Interface to Memory Manager
-** See Copyright Notice in lua.h
-*/
-
-#define lmem_c
-#define LUA_CORE
-
-#include "lprefix.h"
-
-
-#include
-
-#include "lua.h"
-
-#include "ldebug.h"
-#include "ldo.h"
-#include "lgc.h"
-#include "lmem.h"
-#include "lobject.h"
-#include "lstate.h"
-
-
-
-/*
-** About the realloc function:
-** void * frealloc (void *ud, void *ptr, size_t osize, size_t nsize);
-** ('osize' is the old size, 'nsize' is the new size)
-**
-** * frealloc(ud, NULL, x, s) creates a new block of size 's' (no
-** matter 'x').
-**
-** * frealloc(ud, p, x, 0) frees the block 'p'
-** (in this specific case, frealloc must return NULL);
-** particularly, frealloc(ud, NULL, 0, 0) does nothing
-** (which is equivalent to free(NULL) in ISO C)
-**
-** frealloc returns NULL if it cannot create or reallocate the area
-** (any reallocation to an equal or smaller size cannot fail!)
-*/
-
-
-
-#define MINSIZEARRAY 4
-
-
-void *luaM_growaux_ (lua_State *L, void *block, int *size, size_t size_elems,
- int limit, const char *what) {
- void *newblock;
- int newsize;
- if (*size >= limit/2) { /* cannot double it? */
- if (*size >= limit) /* cannot grow even a little? */
- luaG_runerror(L, "too many %s (limit is %d)", what, limit);
- newsize = limit; /* still have at least one free place */
- }
- else {
- newsize = (*size)*2;
- if (newsize < MINSIZEARRAY)
- newsize = MINSIZEARRAY; /* minimum size */
- }
- newblock = luaM_reallocv(L, block, *size, newsize, size_elems);
- *size = newsize; /* update only when everything else is OK */
- return newblock;
-}
-
-
-l_noret luaM_toobig (lua_State *L) {
- luaG_runerror(L, "memory allocation error: block too big");
-}
-
-
-
-/*
-** generic allocation routine.
-*/
-void *luaM_realloc_ (lua_State *L, void *block, size_t osize, size_t nsize) {
- void *newblock;
- global_State *g = G(L);
- size_t realosize = (block) ? osize : 0;
- lua_assert((realosize == 0) == (block == NULL));
-#if defined(HARDMEMTESTS)
- if (nsize > realosize && g->gcrunning)
- luaC_fullgc(L, 1); /* force a GC whenever possible */
-#endif
- newblock = (*g->frealloc)(g->ud, block, osize, nsize);
- if (newblock == NULL && nsize > 0) {
- api_check( nsize > realosize,
- "realloc cannot fail when shrinking a block");
- luaC_fullgc(L, 1); /* try to free some memory... */
- newblock = (*g->frealloc)(g->ud, block, osize, nsize); /* try again */
- if (newblock == NULL)
- luaD_throw(L, LUA_ERRMEM);
- }
- lua_assert((nsize == 0) == (newblock == NULL));
- g->GCdebt = (g->GCdebt + nsize) - realosize;
- return newblock;
-}
-
diff --git a/3rd/lua/src/lmem.h b/3rd/lua/src/lmem.h
deleted file mode 100644
index 30f4848..0000000
--- a/3rd/lua/src/lmem.h
+++ /dev/null
@@ -1,69 +0,0 @@
-/*
-** $Id: lmem.h,v 1.43 2014/12/19 17:26:14 roberto Exp $
-** Interface to Memory Manager
-** See Copyright Notice in lua.h
-*/
-
-#ifndef lmem_h
-#define lmem_h
-
-
-#include
-
-#include "llimits.h"
-#include "lua.h"
-
-
-/*
-** This macro reallocs a vector 'b' from 'on' to 'n' elements, where
-** each element has size 'e'. In case of arithmetic overflow of the
-** product 'n'*'e', it raises an error (calling 'luaM_toobig'). Because
-** 'e' is always constant, it avoids the runtime division MAX_SIZET/(e).
-**
-** (The macro is somewhat complex to avoid warnings: The 'sizeof'
-** comparison avoids a runtime comparison when overflow cannot occur.
-** The compiler should be able to optimize the real test by itself, but
-** when it does it, it may give a warning about "comparison is always
-** false due to limited range of data type"; the +1 tricks the compiler,
-** avoiding this warning but also this optimization.)
-*/
-#define luaM_reallocv(L,b,on,n,e) \
- (((sizeof(n) >= sizeof(size_t) && cast(size_t, (n)) + 1 > MAX_SIZET/(e)) \
- ? luaM_toobig(L) : cast_void(0)) , \
- luaM_realloc_(L, (b), (on)*(e), (n)*(e)))
-
-/*
-** Arrays of chars do not need any test
-*/
-#define luaM_reallocvchar(L,b,on,n) \
- cast(char *, luaM_realloc_(L, (b), (on)*sizeof(char), (n)*sizeof(char)))
-
-#define luaM_freemem(L, b, s) luaM_realloc_(L, (b), (s), 0)
-#define luaM_free(L, b) luaM_realloc_(L, (b), sizeof(*(b)), 0)
-#define luaM_freearray(L, b, n) luaM_realloc_(L, (b), (n)*sizeof(*(b)), 0)
-
-#define luaM_malloc(L,s) luaM_realloc_(L, NULL, 0, (s))
-#define luaM_new(L,t) cast(t *, luaM_malloc(L, sizeof(t)))
-#define luaM_newvector(L,n,t) \
- cast(t *, luaM_reallocv(L, NULL, 0, n, sizeof(t)))
-
-#define luaM_newobject(L,tag,s) luaM_realloc_(L, NULL, tag, (s))
-
-#define luaM_growvector(L,v,nelems,size,t,limit,e) \
- if ((nelems)+1 > (size)) \
- ((v)=cast(t *, luaM_growaux_(L,v,&(size),sizeof(t),limit,e)))
-
-#define luaM_reallocvector(L, v,oldn,n,t) \
- ((v)=cast(t *, luaM_reallocv(L, v, oldn, n, sizeof(t))))
-
-LUAI_FUNC l_noret luaM_toobig (lua_State *L);
-
-/* not to be called directly */
-LUAI_FUNC void *luaM_realloc_ (lua_State *L, void *block, size_t oldsize,
- size_t size);
-LUAI_FUNC void *luaM_growaux_ (lua_State *L, void *block, int *size,
- size_t size_elem, int limit,
- const char *what);
-
-#endif
-
diff --git a/3rd/lua/src/loadlib.c b/3rd/lua/src/loadlib.c
deleted file mode 100644
index 7f8d990..0000000
--- a/3rd/lua/src/loadlib.c
+++ /dev/null
@@ -1,786 +0,0 @@
-/*
-** $Id: loadlib.c,v 1.124 2015/01/05 13:51:39 roberto Exp $
-** Dynamic library loader for Lua
-** See Copyright Notice in lua.h
-**
-** This module contains an implementation of loadlib for Unix systems
-** that have dlfcn, an implementation for Windows, and a stub for other
-** systems.
-*/
-
-#define loadlib_c
-#define LUA_LIB
-
-#include "lprefix.h"
-
-
-#include
-#include
-
-#include "lua.h"
-
-#include "lauxlib.h"
-#include "lualib.h"
-
-
-/*
-** LUA_PATH_VAR and LUA_CPATH_VAR are the names of the environment
-** variables that Lua check to set its paths.
-*/
-#if !defined(LUA_PATH_VAR)
-#define LUA_PATH_VAR "LUA_PATH"
-#endif
-
-#if !defined(LUA_CPATH_VAR)
-#define LUA_CPATH_VAR "LUA_CPATH"
-#endif
-
-#define LUA_PATHSUFFIX "_" LUA_VERSION_MAJOR "_" LUA_VERSION_MINOR
-
-#define LUA_PATHVARVERSION LUA_PATH_VAR LUA_PATHSUFFIX
-#define LUA_CPATHVARVERSION LUA_CPATH_VAR LUA_PATHSUFFIX
-
-/*
-** LUA_PATH_SEP is the character that separates templates in a path.
-** LUA_PATH_MARK is the string that marks the substitution points in a
-** template.
-** LUA_EXEC_DIR in a Windows path is replaced by the executable's
-** directory.
-** LUA_IGMARK is a mark to ignore all before it when building the
-** luaopen_ function name.
-*/
-#if !defined (LUA_PATH_SEP)
-#define LUA_PATH_SEP ";"
-#endif
-#if !defined (LUA_PATH_MARK)
-#define LUA_PATH_MARK "?"
-#endif
-#if !defined (LUA_EXEC_DIR)
-#define LUA_EXEC_DIR "!"
-#endif
-#if !defined (LUA_IGMARK)
-#define LUA_IGMARK "-"
-#endif
-
-
-/*
-** LUA_CSUBSEP is the character that replaces dots in submodule names
-** when searching for a C loader.
-** LUA_LSUBSEP is the character that replaces dots in submodule names
-** when searching for a Lua loader.
-*/
-#if !defined(LUA_CSUBSEP)
-#define LUA_CSUBSEP LUA_DIRSEP
-#endif
-
-#if !defined(LUA_LSUBSEP)
-#define LUA_LSUBSEP LUA_DIRSEP
-#endif
-
-
-/* prefix for open functions in C libraries */
-#define LUA_POF "luaopen_"
-
-/* separator for open functions in C libraries */
-#define LUA_OFSEP "_"
-
-
-/*
-** unique key for table in the registry that keeps handles
-** for all loaded C libraries
-*/
-static const int CLIBS = 0;
-
-#define LIB_FAIL "open"
-
-#define setprogdir(L) ((void)0)
-
-
-/*
-** system-dependent functions
-*/
-
-/*
-** unload library 'lib'
-*/
-static void lsys_unloadlib (void *lib);
-
-/*
-** load C library in file 'path'. If 'seeglb', load with all names in
-** the library global.
-** Returns the library; in case of error, returns NULL plus an
-** error string in the stack.
-*/
-static void *lsys_load (lua_State *L, const char *path, int seeglb);
-
-/*
-** Try to find a function named 'sym' in library 'lib'.
-** Returns the function; in case of error, returns NULL plus an
-** error string in the stack.
-*/
-static lua_CFunction lsys_sym (lua_State *L, void *lib, const char *sym);
-
-
-
-
-#if defined(LUA_USE_DLOPEN) /* { */
-/*
-** {========================================================================
-** This is an implementation of loadlib based on the dlfcn interface.
-** The dlfcn interface is available in Linux, SunOS, Solaris, IRIX, FreeBSD,
-** NetBSD, AIX 4.2, HPUX 11, and probably most other Unix flavors, at least
-** as an emulation layer on top of native functions.
-** =========================================================================
-*/
-
-#include
-
-/*
-** Macro to covert pointer to void* to pointer to function. This cast
-** is undefined according to ISO C, but POSIX assumes that it must work.
-** (The '__extension__' in gnu compilers is only to avoid warnings.)
-*/
-#if defined(__GNUC__)
-#define cast_func(p) (__extension__ (lua_CFunction)(p))
-#else
-#define cast_func(p) ((lua_CFunction)(p))
-#endif
-
-
-static void lsys_unloadlib (void *lib) {
- dlclose(lib);
-}
-
-
-static void *lsys_load (lua_State *L, const char *path, int seeglb) {
- void *lib = dlopen(path, RTLD_NOW | (seeglb ? RTLD_GLOBAL : RTLD_LOCAL));
- if (lib == NULL) lua_pushstring(L, dlerror());
- return lib;
-}
-
-
-static lua_CFunction lsys_sym (lua_State *L, void *lib, const char *sym) {
- lua_CFunction f = cast_func(dlsym(lib, sym));
- if (f == NULL) lua_pushstring(L, dlerror());
- return f;
-}
-
-/* }====================================================== */
-
-
-
-#elif defined(LUA_DL_DLL) /* }{ */
-/*
-** {======================================================================
-** This is an implementation of loadlib for Windows using native functions.
-** =======================================================================
-*/
-
-#include
-
-#undef setprogdir
-
-/*
-** optional flags for LoadLibraryEx
-*/
-#if !defined(LUA_LLE_FLAGS)
-#define LUA_LLE_FLAGS 0
-#endif
-
-
-static void setprogdir (lua_State *L) {
- char buff[MAX_PATH + 1];
- char *lb;
- DWORD nsize = sizeof(buff)/sizeof(char);
- DWORD n = GetModuleFileNameA(NULL, buff, nsize);
- if (n == 0 || n == nsize || (lb = strrchr(buff, '\\')) == NULL)
- luaL_error(L, "unable to get ModuleFileName");
- else {
- *lb = '\0';
- luaL_gsub(L, lua_tostring(L, -1), LUA_EXEC_DIR, buff);
- lua_remove(L, -2); /* remove original string */
- }
-}
-
-
-static void pusherror (lua_State *L) {
- int error = GetLastError();
- char buffer[128];
- if (FormatMessageA(FORMAT_MESSAGE_IGNORE_INSERTS | FORMAT_MESSAGE_FROM_SYSTEM,
- NULL, error, 0, buffer, sizeof(buffer)/sizeof(char), NULL))
- lua_pushstring(L, buffer);
- else
- lua_pushfstring(L, "system error %d\n", error);
-}
-
-static void lsys_unloadlib (void *lib) {
- FreeLibrary((HMODULE)lib);
-}
-
-
-static void *lsys_load (lua_State *L, const char *path, int seeglb) {
- HMODULE lib = LoadLibraryExA(path, NULL, LUA_LLE_FLAGS);
- (void)(seeglb); /* not used: symbols are 'global' by default */
- if (lib == NULL) pusherror(L);
- return lib;
-}
-
-
-static lua_CFunction lsys_sym (lua_State *L, void *lib, const char *sym) {
- lua_CFunction f = (lua_CFunction)GetProcAddress((HMODULE)lib, sym);
- if (f == NULL) pusherror(L);
- return f;
-}
-
-/* }====================================================== */
-
-
-#else /* }{ */
-/*
-** {======================================================
-** Fallback for other systems
-** =======================================================
-*/
-
-#undef LIB_FAIL
-#define LIB_FAIL "absent"
-
-
-#define DLMSG "dynamic libraries not enabled; check your Lua installation"
-
-
-static void lsys_unloadlib (void *lib) {
- (void)(lib); /* not used */
-}
-
-
-static void *lsys_load (lua_State *L, const char *path, int seeglb) {
- (void)(path); (void)(seeglb); /* not used */
- lua_pushliteral(L, DLMSG);
- return NULL;
-}
-
-
-static lua_CFunction lsys_sym (lua_State *L, void *lib, const char *sym) {
- (void)(lib); (void)(sym); /* not used */
- lua_pushliteral(L, DLMSG);
- return NULL;
-}
-
-/* }====================================================== */
-#endif /* } */
-
-
-/*
-** return registry.CLIBS[path]
-*/
-static void *checkclib (lua_State *L, const char *path) {
- void *plib;
- lua_rawgetp(L, LUA_REGISTRYINDEX, &CLIBS);
- lua_getfield(L, -1, path);
- plib = lua_touserdata(L, -1); /* plib = CLIBS[path] */
- lua_pop(L, 2); /* pop CLIBS table and 'plib' */
- return plib;
-}
-
-
-/*
-** registry.CLIBS[path] = plib -- for queries
-** registry.CLIBS[#CLIBS + 1] = plib -- also keep a list of all libraries
-*/
-static void addtoclib (lua_State *L, const char *path, void *plib) {
- lua_rawgetp(L, LUA_REGISTRYINDEX, &CLIBS);
- lua_pushlightuserdata(L, plib);
- lua_pushvalue(L, -1);
- lua_setfield(L, -3, path); /* CLIBS[path] = plib */
- lua_rawseti(L, -2, luaL_len(L, -2) + 1); /* CLIBS[#CLIBS + 1] = plib */
- lua_pop(L, 1); /* pop CLIBS table */
-}
-
-
-/*
-** __gc tag method for CLIBS table: calls 'lsys_unloadlib' for all lib
-** handles in list CLIBS
-*/
-static int gctm (lua_State *L) {
- lua_Integer n = luaL_len(L, 1);
- for (; n >= 1; n--) { /* for each handle, in reverse order */
- lua_rawgeti(L, 1, n); /* get handle CLIBS[n] */
- lsys_unloadlib(lua_touserdata(L, -1));
- lua_pop(L, 1); /* pop handle */
- }
- return 0;
-}
-
-
-
-/* error codes for 'lookforfunc' */
-#define ERRLIB 1
-#define ERRFUNC 2
-
-/*
-** Look for a C function named 'sym' in a dynamically loaded library
-** 'path'.
-** First, check whether the library is already loaded; if not, try
-** to load it.
-** Then, if 'sym' is '*', return true (as library has been loaded).
-** Otherwise, look for symbol 'sym' in the library and push a
-** C function with that symbol.
-** Return 0 and 'true' or a function in the stack; in case of
-** errors, return an error code and an error message in the stack.
-*/
-static int lookforfunc (lua_State *L, const char *path, const char *sym) {
- void *reg = checkclib(L, path); /* check loaded C libraries */
- if (reg == NULL) { /* must load library? */
- reg = lsys_load(L, path, *sym == '*'); /* global symbols if 'sym'=='*' */
- if (reg == NULL) return ERRLIB; /* unable to load library */
- addtoclib(L, path, reg);
- }
- if (*sym == '*') { /* loading only library (no function)? */
- lua_pushboolean(L, 1); /* return 'true' */
- return 0; /* no errors */
- }
- else {
- lua_CFunction f = lsys_sym(L, reg, sym);
- if (f == NULL)
- return ERRFUNC; /* unable to find function */
- lua_pushcfunction(L, f); /* else create new function */
- return 0; /* no errors */
- }
-}
-
-
-static int ll_loadlib (lua_State *L) {
- const char *path = luaL_checkstring(L, 1);
- const char *init = luaL_checkstring(L, 2);
- int stat = lookforfunc(L, path, init);
- if (stat == 0) /* no errors? */
- return 1; /* return the loaded function */
- else { /* error; error message is on stack top */
- lua_pushnil(L);
- lua_insert(L, -2);
- lua_pushstring(L, (stat == ERRLIB) ? LIB_FAIL : "init");
- return 3; /* return nil, error message, and where */
- }
-}
-
-
-
-/*
-** {======================================================
-** 'require' function
-** =======================================================
-*/
-
-
-static int readable (const char *filename) {
- FILE *f = fopen(filename, "r"); /* try to open file */
- if (f == NULL) return 0; /* open failed */
- fclose(f);
- return 1;
-}
-
-
-static const char *pushnexttemplate (lua_State *L, const char *path) {
- const char *l;
- while (*path == *LUA_PATH_SEP) path++; /* skip separators */
- if (*path == '\0') return NULL; /* no more templates */
- l = strchr(path, *LUA_PATH_SEP); /* find next separator */
- if (l == NULL) l = path + strlen(path);
- lua_pushlstring(L, path, l - path); /* template */
- return l;
-}
-
-
-static const char *searchpath (lua_State *L, const char *name,
- const char *path,
- const char *sep,
- const char *dirsep) {
- luaL_Buffer msg; /* to build error message */
- luaL_buffinit(L, &msg);
- if (*sep != '\0') /* non-empty separator? */
- name = luaL_gsub(L, name, sep, dirsep); /* replace it by 'dirsep' */
- while ((path = pushnexttemplate(L, path)) != NULL) {
- const char *filename = luaL_gsub(L, lua_tostring(L, -1),
- LUA_PATH_MARK, name);
- lua_remove(L, -2); /* remove path template */
- if (readable(filename)) /* does file exist and is readable? */
- return filename; /* return that file name */
- lua_pushfstring(L, "\n\tno file '%s'", filename);
- lua_remove(L, -2); /* remove file name */
- luaL_addvalue(&msg); /* concatenate error msg. entry */
- }
- luaL_pushresult(&msg); /* create error message */
- return NULL; /* not found */
-}
-
-
-static int ll_searchpath (lua_State *L) {
- const char *f = searchpath(L, luaL_checkstring(L, 1),
- luaL_checkstring(L, 2),
- luaL_optstring(L, 3, "."),
- luaL_optstring(L, 4, LUA_DIRSEP));
- if (f != NULL) return 1;
- else { /* error message is on top of the stack */
- lua_pushnil(L);
- lua_insert(L, -2);
- return 2; /* return nil + error message */
- }
-}
-
-
-static const char *findfile (lua_State *L, const char *name,
- const char *pname,
- const char *dirsep) {
- const char *path;
- lua_getfield(L, lua_upvalueindex(1), pname);
- path = lua_tostring(L, -1);
- if (path == NULL)
- luaL_error(L, "'package.%s' must be a string", pname);
- return searchpath(L, name, path, ".", dirsep);
-}
-
-
-static int checkload (lua_State *L, int stat, const char *filename) {
- if (stat) { /* module loaded successfully? */
- lua_pushstring(L, filename); /* will be 2nd argument to module */
- return 2; /* return open function and file name */
- }
- else
- return luaL_error(L, "error loading module '%s' from file '%s':\n\t%s",
- lua_tostring(L, 1), filename, lua_tostring(L, -1));
-}
-
-
-static int searcher_Lua (lua_State *L) {
- const char *filename;
- const char *name = luaL_checkstring(L, 1);
- filename = findfile(L, name, "path", LUA_LSUBSEP);
- if (filename == NULL) return 1; /* module not found in this path */
- return checkload(L, (luaL_loadfile(L, filename) == LUA_OK), filename);
-}
-
-
-/*
-** Try to find a load function for module 'modname' at file 'filename'.
-** First, change '.' to '_' in 'modname'; then, if 'modname' has
-** the form X-Y (that is, it has an "ignore mark"), build a function
-** name "luaopen_X" and look for it. (For compatibility, if that
-** fails, it also tries "luaopen_Y".) If there is no ignore mark,
-** look for a function named "luaopen_modname".
-*/
-static int loadfunc (lua_State *L, const char *filename, const char *modname) {
- const char *openfunc;
- const char *mark;
- modname = luaL_gsub(L, modname, ".", LUA_OFSEP);
- mark = strchr(modname, *LUA_IGMARK);
- if (mark) {
- int stat;
- openfunc = lua_pushlstring(L, modname, mark - modname);
- openfunc = lua_pushfstring(L, LUA_POF"%s", openfunc);
- stat = lookforfunc(L, filename, openfunc);
- if (stat != ERRFUNC) return stat;
- modname = mark + 1; /* else go ahead and try old-style name */
- }
- openfunc = lua_pushfstring(L, LUA_POF"%s", modname);
- return lookforfunc(L, filename, openfunc);
-}
-
-
-static int searcher_C (lua_State *L) {
- const char *name = luaL_checkstring(L, 1);
- const char *filename = findfile(L, name, "cpath", LUA_CSUBSEP);
- if (filename == NULL) return 1; /* module not found in this path */
- return checkload(L, (loadfunc(L, filename, name) == 0), filename);
-}
-
-
-static int searcher_Croot (lua_State *L) {
- const char *filename;
- const char *name = luaL_checkstring(L, 1);
- const char *p = strchr(name, '.');
- int stat;
- if (p == NULL) return 0; /* is root */
- lua_pushlstring(L, name, p - name);
- filename = findfile(L, lua_tostring(L, -1), "cpath", LUA_CSUBSEP);
- if (filename == NULL) return 1; /* root not found */
- if ((stat = loadfunc(L, filename, name)) != 0) {
- if (stat != ERRFUNC)
- return checkload(L, 0, filename); /* real error */
- else { /* open function not found */
- lua_pushfstring(L, "\n\tno module '%s' in file '%s'", name, filename);
- return 1;
- }
- }
- lua_pushstring(L, filename); /* will be 2nd argument to module */
- return 2;
-}
-
-
-static int searcher_preload (lua_State *L) {
- const char *name = luaL_checkstring(L, 1);
- lua_getfield(L, LUA_REGISTRYINDEX, "_PRELOAD");
- if (lua_getfield(L, -1, name) == LUA_TNIL) /* not found? */
- lua_pushfstring(L, "\n\tno field package.preload['%s']", name);
- return 1;
-}
-
-
-static void findloader (lua_State *L, const char *name) {
- int i;
- luaL_Buffer msg; /* to build error message */
- luaL_buffinit(L, &msg);
- /* push 'package.searchers' to index 3 in the stack */
- if (lua_getfield(L, lua_upvalueindex(1), "searchers") != LUA_TTABLE)
- luaL_error(L, "'package.searchers' must be a table");
- /* iterate over available searchers to find a loader */
- for (i = 1; ; i++) {
- if (lua_rawgeti(L, 3, i) == LUA_TNIL) { /* no more searchers? */
- lua_pop(L, 1); /* remove nil */
- luaL_pushresult(&msg); /* create error message */
- luaL_error(L, "module '%s' not found:%s", name, lua_tostring(L, -1));
- }
- lua_pushstring(L, name);
- lua_call(L, 1, 2); /* call it */
- if (lua_isfunction(L, -2)) /* did it find a loader? */
- return; /* module loader found */
- else if (lua_isstring(L, -2)) { /* searcher returned error message? */
- lua_pop(L, 1); /* remove extra return */
- luaL_addvalue(&msg); /* concatenate error message */
- }
- else
- lua_pop(L, 2); /* remove both returns */
- }
-}
-
-
-static int ll_require (lua_State *L) {
- const char *name = luaL_checkstring(L, 1);
- lua_settop(L, 1); /* _LOADED table will be at index 2 */
- lua_getfield(L, LUA_REGISTRYINDEX, "_LOADED");
- lua_getfield(L, 2, name); /* _LOADED[name] */
- if (lua_toboolean(L, -1)) /* is it there? */
- return 1; /* package is already loaded */
- /* else must load package */
- lua_pop(L, 1); /* remove 'getfield' result */
- findloader(L, name);
- lua_pushstring(L, name); /* pass name as argument to module loader */
- lua_insert(L, -2); /* name is 1st argument (before search data) */
- lua_call(L, 2, 1); /* run loader to load module */
- if (!lua_isnil(L, -1)) /* non-nil return? */
- lua_setfield(L, 2, name); /* _LOADED[name] = returned value */
- if (lua_getfield(L, 2, name) == LUA_TNIL) { /* module set no value? */
- lua_pushboolean(L, 1); /* use true as result */
- lua_pushvalue(L, -1); /* extra copy to be returned */
- lua_setfield(L, 2, name); /* _LOADED[name] = true */
- }
- return 1;
-}
-
-/* }====================================================== */
-
-
-
-/*
-** {======================================================
-** 'module' function
-** =======================================================
-*/
-#if defined(LUA_COMPAT_MODULE)
-
-/*
-** changes the environment variable of calling function
-*/
-static void set_env (lua_State *L) {
- lua_Debug ar;
- if (lua_getstack(L, 1, &ar) == 0 ||
- lua_getinfo(L, "f", &ar) == 0 || /* get calling function */
- lua_iscfunction(L, -1))
- luaL_error(L, "'module' not called from a Lua function");
- lua_pushvalue(L, -2); /* copy new environment table to top */
- lua_setupvalue(L, -2, 1);
- lua_pop(L, 1); /* remove function */
-}
-
-
-static void dooptions (lua_State *L, int n) {
- int i;
- for (i = 2; i <= n; i++) {
- if (lua_isfunction(L, i)) { /* avoid 'calling' extra info. */
- lua_pushvalue(L, i); /* get option (a function) */
- lua_pushvalue(L, -2); /* module */
- lua_call(L, 1, 0);
- }
- }
-}
-
-
-static void modinit (lua_State *L, const char *modname) {
- const char *dot;
- lua_pushvalue(L, -1);
- lua_setfield(L, -2, "_M"); /* module._M = module */
- lua_pushstring(L, modname);
- lua_setfield(L, -2, "_NAME");
- dot = strrchr(modname, '.'); /* look for last dot in module name */
- if (dot == NULL) dot = modname;
- else dot++;
- /* set _PACKAGE as package name (full module name minus last part) */
- lua_pushlstring(L, modname, dot - modname);
- lua_setfield(L, -2, "_PACKAGE");
-}
-
-
-static int ll_module (lua_State *L) {
- const char *modname = luaL_checkstring(L, 1);
- int lastarg = lua_gettop(L); /* last parameter */
- luaL_pushmodule(L, modname, 1); /* get/create module table */
- /* check whether table already has a _NAME field */
- if (lua_getfield(L, -1, "_NAME") != LUA_TNIL)
- lua_pop(L, 1); /* table is an initialized module */
- else { /* no; initialize it */
- lua_pop(L, 1);
- modinit(L, modname);
- }
- lua_pushvalue(L, -1);
- set_env(L);
- dooptions(L, lastarg);
- return 1;
-}
-
-
-static int ll_seeall (lua_State *L) {
- luaL_checktype(L, 1, LUA_TTABLE);
- if (!lua_getmetatable(L, 1)) {
- lua_createtable(L, 0, 1); /* create new metatable */
- lua_pushvalue(L, -1);
- lua_setmetatable(L, 1);
- }
- lua_pushglobaltable(L);
- lua_setfield(L, -2, "__index"); /* mt.__index = _G */
- return 0;
-}
-
-#endif
-/* }====================================================== */
-
-
-
-/* auxiliary mark (for internal use) */
-#define AUXMARK "\1"
-
-
-/*
-** return registry.LUA_NOENV as a boolean
-*/
-static int noenv (lua_State *L) {
- int b;
- lua_getfield(L, LUA_REGISTRYINDEX, "LUA_NOENV");
- b = lua_toboolean(L, -1);
- lua_pop(L, 1); /* remove value */
- return b;
-}
-
-
-static void setpath (lua_State *L, const char *fieldname, const char *envname1,
- const char *envname2, const char *def) {
- const char *path = getenv(envname1);
- if (path == NULL) /* no environment variable? */
- path = getenv(envname2); /* try alternative name */
- if (path == NULL || noenv(L)) /* no environment variable? */
- lua_pushstring(L, def); /* use default */
- else {
- /* replace ";;" by ";AUXMARK;" and then AUXMARK by default path */
- path = luaL_gsub(L, path, LUA_PATH_SEP LUA_PATH_SEP,
- LUA_PATH_SEP AUXMARK LUA_PATH_SEP);
- luaL_gsub(L, path, AUXMARK, def);
- lua_remove(L, -2);
- }
- setprogdir(L);
- lua_setfield(L, -2, fieldname);
-}
-
-
-static const luaL_Reg pk_funcs[] = {
- {"loadlib", ll_loadlib},
- {"searchpath", ll_searchpath},
-#if defined(LUA_COMPAT_MODULE)
- {"seeall", ll_seeall},
-#endif
- /* placeholders */
- {"preload", NULL},
- {"cpath", NULL},
- {"path", NULL},
- {"searchers", NULL},
- {"loaded", NULL},
- {NULL, NULL}
-};
-
-
-static const luaL_Reg ll_funcs[] = {
-#if defined(LUA_COMPAT_MODULE)
- {"module", ll_module},
-#endif
- {"require", ll_require},
- {NULL, NULL}
-};
-
-
-static void createsearcherstable (lua_State *L) {
- static const lua_CFunction searchers[] =
- {searcher_preload, searcher_Lua, searcher_C, searcher_Croot, NULL};
- int i;
- /* create 'searchers' table */
- lua_createtable(L, sizeof(searchers)/sizeof(searchers[0]) - 1, 0);
- /* fill it with pre-defined searchers */
- for (i=0; searchers[i] != NULL; i++) {
- lua_pushvalue(L, -2); /* set 'package' as upvalue for all searchers */
- lua_pushcclosure(L, searchers[i], 1);
- lua_rawseti(L, -2, i+1);
- }
-#if defined(LUA_COMPAT_LOADERS)
- lua_pushvalue(L, -1); /* make a copy of 'searchers' table */
- lua_setfield(L, -3, "loaders"); /* put it in field 'loaders' */
-#endif
- lua_setfield(L, -2, "searchers"); /* put it in field 'searchers' */
-}
-
-
-/*
-** create table CLIBS to keep track of loaded C libraries,
-** setting a finalizer to close all libraries when closing state.
-*/
-static void createclibstable (lua_State *L) {
- lua_newtable(L); /* create CLIBS table */
- lua_createtable(L, 0, 1); /* create metatable for CLIBS */
- lua_pushcfunction(L, gctm);
- lua_setfield(L, -2, "__gc"); /* set finalizer for CLIBS table */
- lua_setmetatable(L, -2);
- lua_rawsetp(L, LUA_REGISTRYINDEX, &CLIBS); /* set CLIBS table in registry */
-}
-
-
-LUAMOD_API int luaopen_package (lua_State *L) {
- createclibstable(L);
- luaL_newlib(L, pk_funcs); /* create 'package' table */
- createsearcherstable(L);
- /* set field 'path' */
- setpath(L, "path", LUA_PATHVARVERSION, LUA_PATH_VAR, LUA_PATH_DEFAULT);
- /* set field 'cpath' */
- setpath(L, "cpath", LUA_CPATHVARVERSION, LUA_CPATH_VAR, LUA_CPATH_DEFAULT);
- /* store config information */
- lua_pushliteral(L, LUA_DIRSEP "\n" LUA_PATH_SEP "\n" LUA_PATH_MARK "\n"
- LUA_EXEC_DIR "\n" LUA_IGMARK "\n");
- lua_setfield(L, -2, "config");
- /* set field 'loaded' */
- luaL_getsubtable(L, LUA_REGISTRYINDEX, "_LOADED");
- lua_setfield(L, -2, "loaded");
- /* set field 'preload' */
- luaL_getsubtable(L, LUA_REGISTRYINDEX, "_PRELOAD");
- lua_setfield(L, -2, "preload");
- lua_pushglobaltable(L);
- lua_pushvalue(L, -2); /* set 'package' as upvalue for next lib */
- luaL_setfuncs(L, ll_funcs, 1); /* open lib into global table */
- lua_pop(L, 1); /* pop global table */
- return 1; /* return 'package' table */
-}
-
diff --git a/3rd/lua/src/lobject.c b/3rd/lua/src/lobject.c
deleted file mode 100644
index 6a24aff..0000000
--- a/3rd/lua/src/lobject.c
+++ /dev/null
@@ -1,470 +0,0 @@
-/*
-** $Id: lobject.c,v 2.101 2014/12/26 14:43:45 roberto Exp $
-** Some generic functions over Lua objects
-** See Copyright Notice in lua.h
-*/
-
-#define lobject_c
-#define LUA_CORE
-
-#include "lprefix.h"
-
-
-#include
-#include
-#include
-#include
-
-#include "lua.h"
-
-#include "lctype.h"
-#include "ldebug.h"
-#include "ldo.h"
-#include "lmem.h"
-#include "lobject.h"
-#include "lstate.h"
-#include "lstring.h"
-#include "lvm.h"
-
-
-
-LUAI_DDEF const TValue luaO_nilobject_ = {NILCONSTANT};
-
-
-/*
-** converts an integer to a "floating point byte", represented as
-** (eeeeexxx), where the real value is (1xxx) * 2^(eeeee - 1) if
-** eeeee != 0 and (xxx) otherwise.
-*/
-int luaO_int2fb (unsigned int x) {
- int e = 0; /* exponent */
- if (x < 8) return x;
- while (x >= 0x10) {
- x = (x+1) >> 1;
- e++;
- }
- return ((e+1) << 3) | (cast_int(x) - 8);
-}
-
-
-/* converts back */
-int luaO_fb2int (int x) {
- int e = (x >> 3) & 0x1f;
- if (e == 0) return x;
- else return ((x & 7) + 8) << (e - 1);
-}
-
-
-int luaO_ceillog2 (unsigned int x) {
- static const lu_byte log_2[256] = {
- 0,1,2,2,3,3,3,3,4,4,4,4,4,4,4,4,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,
- 6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,
- 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,
- 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,
- 8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,
- 8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,
- 8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,
- 8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8
- };
- int l = 0;
- x--;
- while (x >= 256) { l += 8; x >>= 8; }
- return l + log_2[x];
-}
-
-
-static lua_Integer intarith (lua_State *L, int op, lua_Integer v1,
- lua_Integer v2) {
- switch (op) {
- case LUA_OPADD: return intop(+, v1, v2);
- case LUA_OPSUB:return intop(-, v1, v2);
- case LUA_OPMUL:return intop(*, v1, v2);
- case LUA_OPMOD: return luaV_mod(L, v1, v2);
- case LUA_OPIDIV: return luaV_div(L, v1, v2);
- case LUA_OPBAND: return intop(&, v1, v2);
- case LUA_OPBOR: return intop(|, v1, v2);
- case LUA_OPBXOR: return intop(^, v1, v2);
- case LUA_OPSHL: return luaV_shiftl(v1, v2);
- case LUA_OPSHR: return luaV_shiftl(v1, -v2);
- case LUA_OPUNM: return intop(-, 0, v1);
- case LUA_OPBNOT: return intop(^, ~l_castS2U(0), v1);
- default: lua_assert(0); return 0;
- }
-}
-
-
-static lua_Number numarith (lua_State *L, int op, lua_Number v1,
- lua_Number v2) {
- switch (op) {
- case LUA_OPADD: return luai_numadd(L, v1, v2);
- case LUA_OPSUB: return luai_numsub(L, v1, v2);
- case LUA_OPMUL: return luai_nummul(L, v1, v2);
- case LUA_OPDIV: return luai_numdiv(L, v1, v2);
- case LUA_OPPOW: return luai_numpow(L, v1, v2);
- case LUA_OPIDIV: return luai_numidiv(L, v1, v2);
- case LUA_OPUNM: return luai_numunm(L, v1);
- case LUA_OPMOD: {
- lua_Number m;
- luai_nummod(L, v1, v2, m);
- return m;
- }
- default: lua_assert(0); return 0;
- }
-}
-
-
-void luaO_arith (lua_State *L, int op, const TValue *p1, const TValue *p2,
- TValue *res) {
- switch (op) {
- case LUA_OPBAND: case LUA_OPBOR: case LUA_OPBXOR:
- case LUA_OPSHL: case LUA_OPSHR:
- case LUA_OPBNOT: { /* operate only on integers */
- lua_Integer i1; lua_Integer i2;
- if (tointeger(p1, &i1) && tointeger(p2, &i2)) {
- setivalue(res, intarith(L, op, i1, i2));
- return;
- }
- else break; /* go to the end */
- }
- case LUA_OPDIV: case LUA_OPPOW: { /* operate only on floats */
- lua_Number n1; lua_Number n2;
- if (tonumber(p1, &n1) && tonumber(p2, &n2)) {
- setfltvalue(res, numarith(L, op, n1, n2));
- return;
- }
- else break; /* go to the end */
- }
- default: { /* other operations */
- lua_Number n1; lua_Number n2;
- if (ttisinteger(p1) && ttisinteger(p2)) {
- setivalue(res, intarith(L, op, ivalue(p1), ivalue(p2)));
- return;
- }
- else if (tonumber(p1, &n1) && tonumber(p2, &n2)) {
- setfltvalue(res, numarith(L, op, n1, n2));
- return;
- }
- else break; /* go to the end */
- }
- }
- /* could not perform raw operation; try metamethod */
- lua_assert(L != NULL); /* should not fail when folding (compile time) */
- luaT_trybinTM(L, p1, p2, res, cast(TMS, op - LUA_OPADD + TM_ADD));
-}
-
-
-int luaO_hexavalue (int c) {
- if (lisdigit(c)) return c - '0';
- else return ltolower(c) - 'a' + 10;
-}
-
-
-static int isneg (const char **s) {
- if (**s == '-') { (*s)++; return 1; }
- else if (**s == '+') (*s)++;
- return 0;
-}
-
-
-
-/*
-** {==================================================================
-** Lua's implementation for 'lua_strx2number'
-** ===================================================================
-*/
-#if !defined(lua_strx2number)
-
-#include
-
-/* maximum number of significant digits to read (to avoid overflows
- even with single floats) */
-#define MAXSIGDIG 30
-
-/*
-** convert an hexadecimal numeric string to a number, following
-** C99 specification for 'strtod'
-*/
-static lua_Number lua_strx2number (const char *s, char **endptr) {
- lua_Number r = 0.0; /* result (accumulator) */
- int sigdig = 0; /* number of significant digits */
- int nosigdig = 0; /* number of non-significant digits */
- int e = 0; /* exponent correction */
- int neg; /* 1 if number is negative */
- int dot = 0; /* true after seen a dot */
- *endptr = cast(char *, s); /* nothing is valid yet */
- while (lisspace(cast_uchar(*s))) s++; /* skip initial spaces */
- neg = isneg(&s); /* check signal */
- if (!(*s == '0' && (*(s + 1) == 'x' || *(s + 1) == 'X'))) /* check '0x' */
- return 0.0; /* invalid format (no '0x') */
- for (s += 2; ; s++) { /* skip '0x' and read numeral */
- if (*s == '.') {
- if (dot) break; /* second dot? stop loop */
- else dot = 1;
- }
- else if (lisxdigit(cast_uchar(*s))) {
- if (sigdig == 0 && *s == '0') /* non-significant digit (zero)? */
- nosigdig++;
- else if (++sigdig <= MAXSIGDIG) /* can read it without overflow? */
- r = (r * cast_num(16.0)) + luaO_hexavalue(*s);
- else e++; /* too many digits; ignore, but still count for exponent */
- if (dot) e--; /* decimal digit? correct exponent */
- }
- else break; /* neither a dot nor a digit */
- }
- if (nosigdig + sigdig == 0) /* no digits? */
- return 0.0; /* invalid format */
- *endptr = cast(char *, s); /* valid up to here */
- e *= 4; /* each digit multiplies/divides value by 2^4 */
- if (*s == 'p' || *s == 'P') { /* exponent part? */
- int exp1 = 0; /* exponent value */
- int neg1; /* exponent signal */
- s++; /* skip 'p' */
- neg1 = isneg(&s); /* signal */
- if (!lisdigit(cast_uchar(*s)))
- return 0.0; /* invalid; must have at least one digit */
- while (lisdigit(cast_uchar(*s))) /* read exponent */
- exp1 = exp1 * 10 + *(s++) - '0';
- if (neg1) exp1 = -exp1;
- e += exp1;
- *endptr = cast(char *, s); /* valid up to here */
- }
- if (neg) r = -r;
- return l_mathop(ldexp)(r, e);
-}
-
-#endif
-/* }====================================================== */
-
-
-static const char *l_str2d (const char *s, lua_Number *result) {
- char *endptr;
- if (strpbrk(s, "nN")) /* reject 'inf' and 'nan' */
- return NULL;
- else if (strpbrk(s, "xX")) /* hex? */
- *result = lua_strx2number(s, &endptr);
- else
- *result = lua_str2number(s, &endptr);
- if (endptr == s) return 0; /* nothing recognized */
- while (lisspace(cast_uchar(*endptr))) endptr++;
- return (*endptr == '\0' ? endptr : NULL); /* OK if no trailing characters */
-}
-
-
-static const char *l_str2int (const char *s, lua_Integer *result) {
- lua_Unsigned a = 0;
- int empty = 1;
- int neg;
- while (lisspace(cast_uchar(*s))) s++; /* skip initial spaces */
- neg = isneg(&s);
- if (s[0] == '0' &&
- (s[1] == 'x' || s[1] == 'X')) { /* hex? */
- s += 2; /* skip '0x' */
- for (; lisxdigit(cast_uchar(*s)); s++) {
- a = a * 16 + luaO_hexavalue(*s);
- empty = 0;
- }
- }
- else { /* decimal */
- for (; lisdigit(cast_uchar(*s)); s++) {
- a = a * 10 + *s - '0';
- empty = 0;
- }
- }
- while (lisspace(cast_uchar(*s))) s++; /* skip trailing spaces */
- if (empty || *s != '\0') return NULL; /* something wrong in the numeral */
- else {
- *result = l_castU2S((neg) ? 0u - a : a);
- return s;
- }
-}
-
-
-size_t luaO_str2num (const char *s, TValue *o) {
- lua_Integer i; lua_Number n;
- const char *e;
- if ((e = l_str2int(s, &i)) != NULL) { /* try as an integer */
- setivalue(o, i);
- }
- else if ((e = l_str2d(s, &n)) != NULL) { /* else try as a float */
- setfltvalue(o, n);
- }
- else
- return 0; /* conversion failed */
- return (e - s + 1); /* success; return string size */
-}
-
-
-int luaO_utf8esc (char *buff, unsigned long x) {
- int n = 1; /* number of bytes put in buffer (backwards) */
- lua_assert(x <= 0x10FFFF);
- if (x < 0x80) /* ascii? */
- buff[UTF8BUFFSZ - 1] = cast(char, x);
- else { /* need continuation bytes */
- unsigned int mfb = 0x3f; /* maximum that fits in first byte */
- do { /* add continuation bytes */
- buff[UTF8BUFFSZ - (n++)] = cast(char, 0x80 | (x & 0x3f));
- x >>= 6; /* remove added bits */
- mfb >>= 1; /* now there is one less bit available in first byte */
- } while (x > mfb); /* still needs continuation byte? */
- buff[UTF8BUFFSZ - n] = cast(char, (~mfb << 1) | x); /* add first byte */
- }
- return n;
-}
-
-
-/* maximum length of the conversion of a number to a string */
-#define MAXNUMBER2STR 50
-
-
-/*
-** Convert a number object to a string
-*/
-void luaO_tostring (lua_State *L, StkId obj) {
- char buff[MAXNUMBER2STR];
- size_t len;
- lua_assert(ttisnumber(obj));
- if (ttisinteger(obj))
- len = lua_integer2str(buff, ivalue(obj));
- else {
- len = lua_number2str(buff, fltvalue(obj));
-#if !defined(LUA_COMPAT_FLOATSTRING)
- if (buff[strspn(buff, "-0123456789")] == '\0') { /* looks like an int? */
- buff[len++] = '.';
- buff[len++] = '0'; /* adds '.0' to result */
- }
-#endif
- }
- setsvalue2s(L, obj, luaS_newlstr(L, buff, len));
-}
-
-
-static void pushstr (lua_State *L, const char *str, size_t l) {
- setsvalue2s(L, L->top++, luaS_newlstr(L, str, l));
-}
-
-
-/* this function handles only '%d', '%c', '%f', '%p', and '%s'
- conventional formats, plus Lua-specific '%I' and '%U' */
-const char *luaO_pushvfstring (lua_State *L, const char *fmt, va_list argp) {
- int n = 0;
- for (;;) {
- const char *e = strchr(fmt, '%');
- if (e == NULL) break;
- luaD_checkstack(L, 2); /* fmt + item */
- pushstr(L, fmt, e - fmt);
- switch (*(e+1)) {
- case 's': {
- const char *s = va_arg(argp, char *);
- if (s == NULL) s = "(null)";
- pushstr(L, s, strlen(s));
- break;
- }
- case 'c': {
- char buff = cast(char, va_arg(argp, int));
- if (lisprint(cast_uchar(buff)))
- pushstr(L, &buff, 1);
- else /* non-printable character; print its code */
- luaO_pushfstring(L, "<\\%d>", cast_uchar(buff));
- break;
- }
- case 'd': {
- setivalue(L->top++, va_arg(argp, int));
- luaO_tostring(L, L->top - 1);
- break;
- }
- case 'I': {
- setivalue(L->top++, cast(lua_Integer, va_arg(argp, l_uacInt)));
- luaO_tostring(L, L->top - 1);
- break;
- }
- case 'f': {
- setfltvalue(L->top++, cast_num(va_arg(argp, l_uacNumber)));
- luaO_tostring(L, L->top - 1);
- break;
- }
- case 'p': {
- char buff[4*sizeof(void *) + 8]; /* should be enough space for a '%p' */
- int l = sprintf(buff, "%p", va_arg(argp, void *));
- pushstr(L, buff, l);
- break;
- }
- case 'U': {
- char buff[UTF8BUFFSZ];
- int l = luaO_utf8esc(buff, cast(long, va_arg(argp, long)));
- pushstr(L, buff + UTF8BUFFSZ - l, l);
- break;
- }
- case '%': {
- pushstr(L, "%", 1);
- break;
- }
- default: {
- luaG_runerror(L, "invalid option '%%%c' to 'lua_pushfstring'",
- *(e + 1));
- }
- }
- n += 2;
- fmt = e+2;
- }
- luaD_checkstack(L, 1);
- pushstr(L, fmt, strlen(fmt));
- if (n > 0) luaV_concat(L, n + 1);
- return svalue(L->top - 1);
-}
-
-
-const char *luaO_pushfstring (lua_State *L, const char *fmt, ...) {
- const char *msg;
- va_list argp;
- va_start(argp, fmt);
- msg = luaO_pushvfstring(L, fmt, argp);
- va_end(argp);
- return msg;
-}
-
-
-/* number of chars of a literal string without the ending \0 */
-#define LL(x) (sizeof(x)/sizeof(char) - 1)
-
-#define RETS "..."
-#define PRE "[string \""
-#define POS "\"]"
-
-#define addstr(a,b,l) ( memcpy(a,b,(l) * sizeof(char)), a += (l) )
-
-void luaO_chunkid (char *out, const char *source, size_t bufflen) {
- size_t l = strlen(source);
- if (*source == '=') { /* 'literal' source */
- if (l <= bufflen) /* small enough? */
- memcpy(out, source + 1, l * sizeof(char));
- else { /* truncate it */
- addstr(out, source + 1, bufflen - 1);
- *out = '\0';
- }
- }
- else if (*source == '@') { /* file name */
- if (l <= bufflen) /* small enough? */
- memcpy(out, source + 1, l * sizeof(char));
- else { /* add '...' before rest of name */
- addstr(out, RETS, LL(RETS));
- bufflen -= LL(RETS);
- memcpy(out, source + 1 + l - bufflen, bufflen * sizeof(char));
- }
- }
- else { /* string; format as [string "source"] */
- const char *nl = strchr(source, '\n'); /* find first new line (if any) */
- addstr(out, PRE, LL(PRE)); /* add prefix */
- bufflen -= LL(PRE RETS POS) + 1; /* save space for prefix+suffix+'\0' */
- if (l < bufflen && nl == NULL) { /* small one-line source? */
- addstr(out, source, l); /* keep it */
- }
- else {
- if (nl != NULL) l = nl - source; /* stop at first newline */
- if (l > bufflen) l = bufflen;
- addstr(out, source, l);
- addstr(out, RETS, LL(RETS));
- }
- memcpy(out, POS, (LL(POS) + 1) * sizeof(char));
- }
-}
-
diff --git a/3rd/lua/src/lobject.h b/3rd/lua/src/lobject.h
deleted file mode 100644
index d7d0ebf..0000000
--- a/3rd/lua/src/lobject.h
+++ /dev/null
@@ -1,540 +0,0 @@
-/*
-** $Id: lobject.h,v 2.106 2015/01/05 13:52:37 roberto Exp $
-** Type definitions for Lua objects
-** See Copyright Notice in lua.h
-*/
-
-
-#ifndef lobject_h
-#define lobject_h
-
-
-#include
-
-
-#include "llimits.h"
-#include "lua.h"
-
-
-/*
-** Extra tags for non-values
-*/
-#define LUA_TPROTO LUA_NUMTAGS
-#define LUA_TDEADKEY (LUA_NUMTAGS+1)
-
-/*
-** number of all possible tags (including LUA_TNONE but excluding DEADKEY)
-*/
-#define LUA_TOTALTAGS (LUA_TPROTO + 2)
-
-
-/*
-** tags for Tagged Values have the following use of bits:
-** bits 0-3: actual tag (a LUA_T* value)
-** bits 4-5: variant bits
-** bit 6: whether value is collectable
-*/
-
-#define VARBITS (3 << 4)
-
-
-/*
-** LUA_TFUNCTION variants:
-** 0 - Lua function
-** 1 - light C function
-** 2 - regular C function (closure)
-*/
-
-/* Variant tags for functions */
-#define LUA_TLCL (LUA_TFUNCTION | (0 << 4)) /* Lua closure */
-#define LUA_TLCF (LUA_TFUNCTION | (1 << 4)) /* light C function */
-#define LUA_TCCL (LUA_TFUNCTION | (2 << 4)) /* C closure */
-
-
-/* Variant tags for strings */
-#define LUA_TSHRSTR (LUA_TSTRING | (0 << 4)) /* short strings */
-#define LUA_TLNGSTR (LUA_TSTRING | (1 << 4)) /* long strings */
-
-
-/* Variant tags for numbers */
-#define LUA_TNUMFLT (LUA_TNUMBER | (0 << 4)) /* float numbers */
-#define LUA_TNUMINT (LUA_TNUMBER | (1 << 4)) /* integer numbers */
-
-
-/* Bit mark for collectable types */
-#define BIT_ISCOLLECTABLE (1 << 6)
-
-/* mark a tag as collectable */
-#define ctb(t) ((t) | BIT_ISCOLLECTABLE)
-
-
-/*
-** Common type for all collectable objects
-*/
-typedef struct GCObject GCObject;
-
-
-/*
-** Common Header for all collectable objects (in macro form, to be
-** included in other objects)
-*/
-#define CommonHeader GCObject *next; lu_byte tt; lu_byte marked
-
-
-/*
-** Common type has only the common header
-*/
-struct GCObject {
- CommonHeader;
-};
-
-
-
-/*
-** Union of all Lua values
-*/
-typedef union Value Value;
-
-
-
-
-/*
-** Tagged Values. This is the basic representation of values in Lua,
-** an actual value plus a tag with its type.
-*/
-
-#define TValuefields Value value_; int tt_
-
-typedef struct lua_TValue TValue;
-
-
-/* macro defining a nil value */
-#define NILCONSTANT {NULL}, LUA_TNIL
-
-
-#define val_(o) ((o)->value_)
-
-
-/* raw type tag of a TValue */
-#define rttype(o) ((o)->tt_)
-
-/* tag with no variants (bits 0-3) */
-#define novariant(x) ((x) & 0x0F)
-
-/* type tag of a TValue (bits 0-3 for tags + variant bits 4-5) */
-#define ttype(o) (rttype(o) & 0x3F)
-
-/* type tag of a TValue with no variants (bits 0-3) */
-#define ttnov(o) (novariant(rttype(o)))
-
-
-/* Macros to test type */
-#define checktag(o,t) (rttype(o) == (t))
-#define checktype(o,t) (ttnov(o) == (t))
-#define ttisnumber(o) checktype((o), LUA_TNUMBER)
-#define ttisfloat(o) checktag((o), LUA_TNUMFLT)
-#define ttisinteger(o) checktag((o), LUA_TNUMINT)
-#define ttisnil(o) checktag((o), LUA_TNIL)
-#define ttisboolean(o) checktag((o), LUA_TBOOLEAN)
-#define ttislightuserdata(o) checktag((o), LUA_TLIGHTUSERDATA)
-#define ttisstring(o) checktype((o), LUA_TSTRING)
-#define ttisshrstring(o) checktag((o), ctb(LUA_TSHRSTR))
-#define ttislngstring(o) checktag((o), ctb(LUA_TLNGSTR))
-#define ttistable(o) checktag((o), ctb(LUA_TTABLE))
-#define ttisfunction(o) checktype(o, LUA_TFUNCTION)
-#define ttisclosure(o) ((rttype(o) & 0x1F) == LUA_TFUNCTION)
-#define ttisCclosure(o) checktag((o), ctb(LUA_TCCL))
-#define ttisLclosure(o) checktag((o), ctb(LUA_TLCL))
-#define ttislcf(o) checktag((o), LUA_TLCF)
-#define ttisfulluserdata(o) checktag((o), ctb(LUA_TUSERDATA))
-#define ttisthread(o) checktag((o), ctb(LUA_TTHREAD))
-#define ttisdeadkey(o) checktag((o), LUA_TDEADKEY)
-
-
-/* Macros to access values */
-#define ivalue(o) check_exp(ttisinteger(o), val_(o).i)
-#define fltvalue(o) check_exp(ttisfloat(o), val_(o).n)
-#define nvalue(o) check_exp(ttisnumber(o), \
- (ttisinteger(o) ? cast_num(ivalue(o)) : fltvalue(o)))
-#define gcvalue(o) check_exp(iscollectable(o), val_(o).gc)
-#define pvalue(o) check_exp(ttislightuserdata(o), val_(o).p)
-#define tsvalue(o) check_exp(ttisstring(o), gco2ts(val_(o).gc))
-#define uvalue(o) check_exp(ttisfulluserdata(o), gco2u(val_(o).gc))
-#define clvalue(o) check_exp(ttisclosure(o), gco2cl(val_(o).gc))
-#define clLvalue(o) check_exp(ttisLclosure(o), gco2lcl(val_(o).gc))
-#define clCvalue(o) check_exp(ttisCclosure(o), gco2ccl(val_(o).gc))
-#define fvalue(o) check_exp(ttislcf(o), val_(o).f)
-#define hvalue(o) check_exp(ttistable(o), gco2t(val_(o).gc))
-#define bvalue(o) check_exp(ttisboolean(o), val_(o).b)
-#define thvalue(o) check_exp(ttisthread(o), gco2th(val_(o).gc))
-/* a dead value may get the 'gc' field, but cannot access its contents */
-#define deadvalue(o) check_exp(ttisdeadkey(o), cast(void *, val_(o).gc))
-
-#define l_isfalse(o) (ttisnil(o) || (ttisboolean(o) && bvalue(o) == 0))
-
-
-#define iscollectable(o) (rttype(o) & BIT_ISCOLLECTABLE)
-
-
-/* Macros for internal tests */
-#define righttt(obj) (ttype(obj) == gcvalue(obj)->tt)
-
-#define checkliveness(g,obj) \
- lua_longassert(!iscollectable(obj) || \
- (righttt(obj) && !isdead(g,gcvalue(obj))))
-
-
-/* Macros to set values */
-#define settt_(o,t) ((o)->tt_=(t))
-
-#define setfltvalue(obj,x) \
- { TValue *io=(obj); val_(io).n=(x); settt_(io, LUA_TNUMFLT); }
-
-#define setivalue(obj,x) \
- { TValue *io=(obj); val_(io).i=(x); settt_(io, LUA_TNUMINT); }
-
-#define setnilvalue(obj) settt_(obj, LUA_TNIL)
-
-#define setfvalue(obj,x) \
- { TValue *io=(obj); val_(io).f=(x); settt_(io, LUA_TLCF); }
-
-#define setpvalue(obj,x) \
- { TValue *io=(obj); val_(io).p=(x); settt_(io, LUA_TLIGHTUSERDATA); }
-
-#define setbvalue(obj,x) \
- { TValue *io=(obj); val_(io).b=(x); settt_(io, LUA_TBOOLEAN); }
-
-#define setgcovalue(L,obj,x) \
- { TValue *io = (obj); GCObject *i_g=(x); \
- val_(io).gc = i_g; settt_(io, ctb(i_g->tt)); }
-
-#define setsvalue(L,obj,x) \
- { TValue *io = (obj); TString *x_ = (x); \
- val_(io).gc = obj2gco(x_); settt_(io, ctb(x_->tt)); \
- checkliveness(G(L),io); }
-
-#define setuvalue(L,obj,x) \
- { TValue *io = (obj); Udata *x_ = (x); \
- val_(io).gc = obj2gco(x_); settt_(io, ctb(LUA_TUSERDATA)); \
- checkliveness(G(L),io); }
-
-#define setthvalue(L,obj,x) \
- { TValue *io = (obj); lua_State *x_ = (x); \
- val_(io).gc = obj2gco(x_); settt_(io, ctb(LUA_TTHREAD)); \
- checkliveness(G(L),io); }
-
-#define setclLvalue(L,obj,x) \
- { TValue *io = (obj); LClosure *x_ = (x); \
- val_(io).gc = obj2gco(x_); settt_(io, ctb(LUA_TLCL)); \
- checkliveness(G(L),io); }
-
-#define setclCvalue(L,obj,x) \
- { TValue *io = (obj); CClosure *x_ = (x); \
- val_(io).gc = obj2gco(x_); settt_(io, ctb(LUA_TCCL)); \
- checkliveness(G(L),io); }
-
-#define sethvalue(L,obj,x) \
- { TValue *io = (obj); Table *x_ = (x); \
- val_(io).gc = obj2gco(x_); settt_(io, ctb(LUA_TTABLE)); \
- checkliveness(G(L),io); }
-
-#define setdeadvalue(obj) settt_(obj, LUA_TDEADKEY)
-
-
-
-#define setobj(L,obj1,obj2) \
- { TValue *io1=(obj1); *io1 = *(obj2); \
- (void)L; checkliveness(G(L),io1); }
-
-
-/*
-** different types of assignments, according to destination
-*/
-
-/* from stack to (same) stack */
-#define setobjs2s setobj
-/* to stack (not from same stack) */
-#define setobj2s setobj
-#define setsvalue2s setsvalue
-#define sethvalue2s sethvalue
-#define setptvalue2s setptvalue
-/* from table to same table */
-#define setobjt2t setobj
-/* to table */
-#define setobj2t setobj
-/* to new object */
-#define setobj2n setobj
-#define setsvalue2n setsvalue
-
-
-
-
-/*
-** {======================================================
-** types and prototypes
-** =======================================================
-*/
-
-
-union Value {
- GCObject *gc; /* collectable objects */
- void *p; /* light userdata */
- int b; /* booleans */
- lua_CFunction f; /* light C functions */
- lua_Integer i; /* integer numbers */
- lua_Number n; /* float numbers */
-};
-
-
-struct lua_TValue {
- TValuefields;
-};
-
-
-typedef TValue *StkId; /* index to stack elements */
-
-
-
-
-/*
-** Header for string value; string bytes follow the end of this structure
-** (aligned according to 'UTString'; see next).
-*/
-typedef struct TString {
- CommonHeader;
- lu_byte extra; /* reserved words for short strings; "has hash" for longs */
- unsigned int hash;
- size_t len; /* number of characters in string */
- struct TString *hnext; /* linked list for hash table */
-} TString;
-
-
-/*
-** Ensures that address after this type is always fully aligned.
-*/
-typedef union UTString {
- L_Umaxalign dummy; /* ensures maximum alignment for strings */
- TString tsv;
-} UTString;
-
-
-/*
-** Get the actual string (array of bytes) from a 'TString'.
-** (Access to 'extra' ensures that value is really a 'TString'.)
-*/
-#define getaddrstr(ts) (cast(char *, (ts)) + sizeof(UTString))
-#define getstr(ts) \
- check_exp(sizeof((ts)->extra), cast(const char*, getaddrstr(ts)))
-
-/* get the actual string (array of bytes) from a Lua value */
-#define svalue(o) getstr(tsvalue(o))
-
-
-/*
-** Header for userdata; memory area follows the end of this structure
-** (aligned according to 'UUdata'; see next).
-*/
-typedef struct Udata {
- CommonHeader;
- lu_byte ttuv_; /* user value's tag */
- struct Table *metatable;
- size_t len; /* number of bytes */
- union Value user_; /* user value */
-} Udata;
-
-
-/*
-** Ensures that address after this type is always fully aligned.
-*/
-typedef union UUdata {
- L_Umaxalign dummy; /* ensures maximum alignment for 'local' udata */
- Udata uv;
-} UUdata;
-
-
-/*
-** Get the address of memory block inside 'Udata'.
-** (Access to 'ttuv_' ensures that value is really a 'Udata'.)
-*/
-#define getudatamem(u) \
- check_exp(sizeof((u)->ttuv_), (cast(char*, (u)) + sizeof(UUdata)))
-
-#define setuservalue(L,u,o) \
- { const TValue *io=(o); Udata *iu = (u); \
- iu->user_ = io->value_; iu->ttuv_ = io->tt_; \
- checkliveness(G(L),io); }
-
-
-#define getuservalue(L,u,o) \
- { TValue *io=(o); const Udata *iu = (u); \
- io->value_ = iu->user_; io->tt_ = iu->ttuv_; \
- checkliveness(G(L),io); }
-
-
-/*
-** Description of an upvalue for function prototypes
-*/
-typedef struct Upvaldesc {
- TString *name; /* upvalue name (for debug information) */
- lu_byte instack; /* whether it is in stack */
- lu_byte idx; /* index of upvalue (in stack or in outer function's list) */
-} Upvaldesc;
-
-
-/*
-** Description of a local variable for function prototypes
-** (used for debug information)
-*/
-typedef struct LocVar {
- TString *varname;
- int startpc; /* first point where variable is active */
- int endpc; /* first point where variable is dead */
-} LocVar;
-
-
-/*
-** Function Prototypes
-*/
-typedef struct Proto {
- CommonHeader;
- lu_byte numparams; /* number of fixed parameters */
- lu_byte is_vararg;
- lu_byte maxstacksize; /* maximum stack used by this function */
- int sizeupvalues; /* size of 'upvalues' */
- int sizek; /* size of 'k' */
- int sizecode;
- int sizelineinfo;
- int sizep; /* size of 'p' */
- int sizelocvars;
- int linedefined;
- int lastlinedefined;
- TValue *k; /* constants used by the function */
- Instruction *code;
- struct Proto **p; /* functions defined inside the function */
- int *lineinfo; /* map from opcodes to source lines (debug information) */
- LocVar *locvars; /* information about local variables (debug information) */
- Upvaldesc *upvalues; /* upvalue information */
- struct LClosure *cache; /* last created closure with this prototype */
- TString *source; /* used for debug information */
- GCObject *gclist;
-} Proto;
-
-
-
-/*
-** Lua Upvalues
-*/
-typedef struct UpVal UpVal;
-
-
-/*
-** Closures
-*/
-
-#define ClosureHeader \
- CommonHeader; lu_byte nupvalues; GCObject *gclist
-
-typedef struct CClosure {
- ClosureHeader;
- lua_CFunction f;
- TValue upvalue[1]; /* list of upvalues */
-} CClosure;
-
-
-typedef struct LClosure {
- ClosureHeader;
- struct Proto *p;
- UpVal *upvals[1]; /* list of upvalues */
-} LClosure;
-
-
-typedef union Closure {
- CClosure c;
- LClosure l;
-} Closure;
-
-
-#define isLfunction(o) ttisLclosure(o)
-
-#define getproto(o) (clLvalue(o)->p)
-
-
-/*
-** Tables
-*/
-
-typedef union TKey {
- struct {
- TValuefields;
- int next; /* for chaining (offset for next node) */
- } nk;
- TValue tvk;
-} TKey;
-
-
-/* copy a value into a key without messing up field 'next' */
-#define setnodekey(L,key,obj) \
- { TKey *k_=(key); const TValue *io_=(obj); \
- k_->nk.value_ = io_->value_; k_->nk.tt_ = io_->tt_; \
- (void)L; checkliveness(G(L),io_); }
-
-
-typedef struct Node {
- TValue i_val;
- TKey i_key;
-} Node;
-
-
-typedef struct Table {
- CommonHeader;
- lu_byte flags; /* 1<