├── .gitignore ├── 3rd ├── kcp │ ├── LICENSE │ ├── README.md │ ├── donation.png │ ├── ikcp.c │ ├── ikcp.h │ ├── test.cpp │ └── test.h └── lua │ ├── Makefile │ ├── README │ ├── doc │ ├── contents.html │ ├── logo.gif │ ├── lua.1 │ ├── lua.css │ ├── luac.1 │ ├── manual.css │ ├── manual.html │ ├── osi-certified-72x60.png │ └── readme.html │ └── src │ ├── Makefile │ ├── lapi.c │ ├── lapi.h │ ├── lauxlib.c │ ├── lauxlib.h │ ├── lbaselib.c │ ├── lbitlib.c │ ├── lcode.c │ ├── lcode.h │ ├── lcorolib.c │ ├── lctype.c │ ├── lctype.h │ ├── ldblib.c │ ├── ldebug.c │ ├── ldebug.h │ ├── ldo.c │ ├── ldo.h │ ├── ldump.c │ ├── lfunc.c │ ├── lfunc.h │ ├── lgc.c │ ├── lgc.h │ ├── linit.c │ ├── liolib.c │ ├── llex.c │ ├── llex.h │ ├── llimits.h │ ├── lmathlib.c │ ├── lmem.c │ ├── lmem.h │ ├── loadlib.c │ ├── lobject.c │ ├── lobject.h │ ├── lopcodes.c │ ├── lopcodes.h │ ├── loslib.c │ ├── lparser.c │ ├── lparser.h │ ├── lprefix.h │ ├── lstate.c │ ├── lstate.h │ ├── lstring.c │ ├── lstring.h │ ├── lstrlib.c │ ├── ltable.c │ ├── ltable.h │ ├── ltablib.c │ ├── ltm.c │ ├── ltm.h │ ├── lua │ ├── lua.c │ ├── lua.h │ ├── lua.hpp │ ├── luac │ ├── luac.c │ ├── luaconf.h │ ├── lualib.h │ ├── lundump.c │ ├── lundump.h │ ├── lutf8lib.c │ ├── lvm.c │ ├── lvm.h │ ├── lzio.c │ └── lzio.h ├── LICENSE ├── Makefile ├── README.md ├── lua-interface.md ├── run_test.sh └── src ├── latencysm.lua ├── lkcp.c ├── lutil.c └── testkcp.lua /.gitignore: -------------------------------------------------------------------------------- 1 | *~ 2 | *.so 3 | *.o 4 | *.lo 5 | *.bak 6 | *.swp 7 | *.tmp 8 | *.out 9 | *.md5 10 | *.tar.gz 11 | *.pid 12 | *.a 13 | bin/ 14 | build/ 15 | include/ 16 | lualib/ 17 | -------------------------------------------------------------------------------- /3rd/kcp/README.md: -------------------------------------------------------------------------------- 1 | KCP - A Fast and Reliable ARQ Protocol 2 | ====================================== 3 | 4 | # 简介 5 | 6 | KCP是一个快速可靠协议,能以比 TCP浪费10%-20%的带宽的代价,换取平均延迟降低 7 | 30%-40%,且最大延迟降低三倍的传输效果。纯算法实现,并不负责底层协议(如UDP) 8 | 的收发,需要使用者自己定义下层数据包的发送方式,以 callback的方式提供给 KCP。 9 | 连时钟都需要外部传递进来,内部不会有任何一次系统调用。 10 | 11 | 整个协议只有 ikcp.h, ikcp.c两个源文件,可以方便的集成到用户自己的协议栈中。 12 | 也许你实现了一个P2P,或者某个基于 UDP的协议,而缺乏一套完善的ARQ可靠协议实现, 13 | 那么简单的拷贝这两个文件到现有项目中,稍微编写两行代码,即可使用。 14 | 15 | 16 | # 技术特性 17 | 18 | TCP是为流量设计的(每秒内可以传输多少KB的数据),讲究的是充分利用带宽。而KCP 19 | 是为流速设计的(单个数据包从一端发送到一端需要多少时间),以10%-20%带宽浪费 20 | 的代价换取了比 TCP快30%-40%的传输速度。TCP信道是一条流速很慢,但每秒流量很大 21 | 的大运河,而KCP是水流湍急的小激流。KCP有正常模式和快速模式两种,通过以下策略 22 | 达到提高流速的结果: 23 | 24 | #### RTO翻倍vs不翻倍: 25 | 26 | TCP超时计算是RTOx2,这样连续丢三次包就变成RTOx8了,十分恐怖,而KCP启动快速 27 | 模式后不x2,只是x1.5(实验证明1.5这个值相对比较好),提高了传输速度。 28 | 29 | #### 选择性重传 vs 全部重传: 30 | 31 | TCP丢包时会全部重传从丢的那个包开始以后的数据,KCP是选择性重传,只重传真正 32 | 丢失的数据包。 33 | 34 | #### 快速重传: 35 | 36 | 发送端发送了1,2,3,4,5几个包,然后收到远端的ACK: 1, 3, 4, 5,当收到ACK3时, 37 | KCP知道2被跳过1次,收到ACK4时,知道2被跳过了2次,此时可以认为2号丢失,不用 38 | 等超时,直接重传2号包,大大改善了丢包时的传输速度。 39 | 40 | #### 延迟ACK vs 非延迟ACK: 41 | 42 | TCP为了充分利用带宽,延迟发送ACK(NODELAY都没用),这样超时计算会算出较大 43 | RTT时间,延长了丢包时的判断过程。KCP的ACK是否延迟发送可以调节。 44 | 45 | #### UNA vs ACK+UNA: 46 | 47 | ARQ模型响应有两种,UNA(此编号前所有包已收到,如TCP)和ACK(该编号包已收到 48 | ),光用UNA将导致全部重传,光用ACK则丢失成本太高,以往协议都是二选其一,而 49 | KCP协议中,除去单独的 ACK包外,所有包都有UNA信息。 50 | 51 | #### 非退让流控: 52 | 53 | KCP正常模式同TCP一样使用公平退让法则,即发送窗口大小由:发送缓存大小、接收 54 | 端剩余接收缓存大小、丢包退让及慢启动这四要素决定。但传送及时性要求很高的小 55 | 数据时,可选择通过配置跳过后两步,仅用前两项来控制发送频率。以牺牲部分公平 56 | 性及带宽利用率之代价,换取了开着BT都能流畅传输的效果。 57 | 58 | 59 | # 基本使用 60 | 61 | 1. 创建 KCP对象: 62 | 63 | ```cpp 64 | // 初始化 kcp对象,conv为一个表示会话编号的整数,和tcp的 conv一样,通信双 65 | // 方需保证 conv相同,相互的数据包才能够被认可,user是一个给回调函数的指针 66 | ikcpcb *kcp = ikcp_create(conv, user); 67 | ``` 68 | 69 | 2. 设置回调函数: 70 | 71 | ```cpp 72 | // KCP的下层协议输出函数,KCP需要发送数据时会调用它 73 | // buf/len 表示缓存和长度 74 | // user指针为 kcp对象创建时传入的值,用于区别多个 KCP对象 75 | int udp_output(const char *buf, int len, ikcpcb *kcp, void *user) 76 | { 77 | .... 78 | } 79 | // 设置回调函数 80 | kcp->output = udp_output; 81 | ``` 82 | 83 | 3. 循环调用 update: 84 | 85 | ```cpp 86 | // 以一定频率调用 ikcp_update来更新 kcp状态,并且传入当前时钟(毫秒单位) 87 | // 如 10ms调用一次,或用 ikcp_check确定下次调用 update的时间不必每次调用 88 | ikcp_update(kcp, millisec); 89 | ``` 90 | 91 | 4. 输入一个下层数据包: 92 | 93 | ```cpp 94 | // 收到一个下层数据包(比如UDP包)时需要调用: 95 | ikcp_input(kcp, received_udp_packet, received_udp_size); 96 | ``` 97 | 处理了下层协议的输出/输入后 KCP协议就可以正常工作了,使用 ikcp_send 来向 98 | 远端发送数据。而另一端使用 ikcp_recv(kcp, ptr, size)来接收数据。 99 | 100 | 101 | # 协议配置 102 | 103 | 协议默认模式是一个标准的 ARQ,需要通过配置打开各项加速开关: 104 | 105 | 1. 工作模式: 106 | ```cpp 107 | int ikcp_nodelay(ikcpcb *kcp, int nodelay, int interval, int resend, int nc) 108 | ``` 109 | 110 | > nodelay :是否启用 nodelay模式,0不启用;1启用。 111 | > interval :协议内部工作的 interval,单位毫秒,比如 10ms或者 20ms 112 | > resend :快速重传模式,默认0关闭,可以设置2(2次ACK跨越将会直接重传) 113 | > nc :是否关闭流控,默认是0代表不关闭,1代表关闭。 114 | > 普通模式:`ikcp_nodelay(kcp, 0, 40, 0, 0); 115 | > 极速模式: ikcp_nodelay(kcp, 1, 10, 2, 1); 116 | 117 | 2. 最大窗口: 118 | ```cpp 119 | int ikcp_wndsize(ikcpcb *kcp, int sndwnd, int rcvwnd); 120 | ``` 121 | 该调用将会设置协议的最大发送窗口和最大接收窗口大小,默认为32. 122 | 123 | 3. 最大传输单元: 124 | 125 | 纯算法协议并不负责探测 MTU,默认 mtu是1400字节,可以使用ikcp_setmtu来设置 126 | 该值。该值将会影响数据包归并及分片时候的最大传输单元。 127 | 128 | 4. 最小RTO: 129 | 130 | 不管是 TCP还是 KCP计算 RTO时都有最小 RTO的限制,即便计算出来RTO为40ms,由 131 | 于默认的 RTO是100ms,协议只有在100ms后才能检测到丢包,快速模式下为30ms,可 132 | 以手动更改该值: 133 | ```cpp 134 | kcp->rx_minrto = 10; 135 | ``` 136 | 137 | # 最佳实践 138 | #### 内存分配器 139 | 140 | 默认KCP协议使用 malloc/free进行内存分配释放,如果应用层接管了内存分配,可以 141 | 用ikcp_allocator来设置新的内存分配器,注意要在一开始设置: 142 | 143 | > ikcp_allocator(my_new_malloc, my_new_free); 144 | 145 | 146 | #### 前向纠错注意 147 | 148 | 为了进一步提高传输速度,下层协议也许会使用前向纠错技术。需要注意,前向纠错会根 149 | 据冗余信息解出原始数据包。相同的原始数据包不要两次input到KCP,否则将会导致kcp 150 | 以为对方重发了,这样会产生更多的ack占用额外带宽。 151 | 152 | 比如下层协议使用最简单的冗余包:单个数据包除了自己外,还会重复存储一次上一个数 153 | 据包,以及上上一个数据包的内容: 154 | 155 | ```cpp 156 | Fn = (Pn, Pn-1, Pn-2) 157 | 158 | P0 = (0, X, X) 159 | P1 = (1, 0, X) 160 | P2 = (2, 1, 0) 161 | P3 = (3, 2, 1) 162 | ``` 163 | 164 | 这样几个包发送出去,接收方对于单个原始包都可能被解出3次来(后面两个包任然会重 165 | 复该包内容),那么这里需要记录一下,一个下层数据包只会input给kcp一次,避免过 166 | 多重复ack带来的浪费。 167 | 168 | #### 管理大规模连接 169 | 170 | 如果需要同时管理大规模的 KCP连接(比如大于3000个),比如你正在实现一套类 epoll 171 | 的机制,那么为了避免每秒钟对每个连接调用大量的调用 ikcp_update,我们可以使用 172 | ikcp_check来大大减少 ikcp_update调用的次数。 ikcp_check返回值会告诉你需要 173 | 在什么时间点再次调用 ikcp_update(如果中途没有 ikcp_send, ikcp_input的话, 174 | 否则中途调用了 ikcp_send, ikcp_input的话,需要在下一次interval时调用 update) 175 | 176 | 标准顺序是每次调用了 ikcp_update后,使用 ikcp_check决定下次什么时间点再次调用 177 | ikcp_update,而如果中途发生了 ikcp_send, ikcp_input的话,在下一轮 interval 178 | 立马调用 ikcp_update和 ikcp_check。 使用该方法,原来在处理2000个 kcp连接且每 179 | 个连接每10ms调用一次update,改为 check机制后,cpu从 60%降低到 15%。 180 | 181 | 182 | # 欢迎捐赠 183 | 184 | ![欢迎使用支付宝对该项目进行捐赠](https://raw.githubusercontent.com/skywind3000/kcp/master/donation.png) 185 | 186 | 欢迎使用支付宝手扫描上面的二维码,对该项目进行捐赠。捐赠款项将用于改进 KCP性能以及 187 | 后续持续优化。 188 | -------------------------------------------------------------------------------- /3rd/kcp/donation.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/linxiaolong/lua-kcp/367284d8e46686a5c9d3985e0abdcc9d49e1ecc2/3rd/kcp/donation.png -------------------------------------------------------------------------------- /3rd/kcp/test.cpp: -------------------------------------------------------------------------------- 1 | //===================================================================== 2 | // 3 | // test.cpp - kcp 测试用例 4 | // 5 | // 说明: 6 | // gcc test.cpp -o test -lstdc++ 7 | // 8 | //===================================================================== 9 | 10 | #include 11 | #include 12 | 13 | #include "test.h" 14 | #include "ikcp.c" 15 | 16 | 17 | // 模拟网络 18 | LatencySimulator *vnet; 19 | 20 | // 模拟网络:模拟发送一个 udp包 21 | int udp_output(const char *buf, int len, ikcpcb *kcp, void *user) 22 | { 23 | int id = (int)user; 24 | vnet->send(id, buf, len); 25 | return 0; 26 | } 27 | 28 | // 测试用例 29 | void test(int mode) 30 | { 31 | // 创建模拟网络:丢包率10%,Rtt 60ms~125ms 32 | vnet = new LatencySimulator(10, 60, 125); 33 | 34 | // 创建两个端点的 kcp对象,第一个参数 conv是会话编号,同一个会话需要相同 35 | // 最后一个是 user参数,用来传递标识 36 | ikcpcb *kcp1 = ikcp_create(0x11223344, (void*)0); 37 | ikcpcb *kcp2 = ikcp_create(0x11223344, (void*)1); 38 | 39 | // 设置kcp的下层输出,这里为 udp_output,模拟udp网络输出函数 40 | kcp1->output = udp_output; 41 | kcp2->output = udp_output; 42 | 43 | IUINT32 current = iclock(); 44 | IUINT32 slap = current + 20; 45 | IUINT32 index = 0; 46 | IUINT32 next = 0; 47 | IINT64 sumrtt = 0; 48 | int count = 0; 49 | int maxrtt = 0; 50 | 51 | // 配置窗口大小:平均延迟200ms,每20ms发送一个包, 52 | // 而考虑到丢包重发,设置最大收发窗口为128 53 | ikcp_wndsize(kcp1, 128, 128); 54 | ikcp_wndsize(kcp2, 128, 128); 55 | 56 | // 判断测试用例的模式 57 | if (mode == 0) { 58 | // 默认模式 59 | ikcp_nodelay(kcp1, 0, 10, 0, 0); 60 | ikcp_nodelay(kcp2, 0, 10, 0, 0); 61 | } 62 | else if (mode == 1) { 63 | // 普通模式,关闭流控等 64 | ikcp_nodelay(kcp1, 0, 10, 0, 1); 65 | ikcp_nodelay(kcp2, 0, 10, 0, 1); 66 | } else { 67 | // 启动快速模式 68 | // 第二个参数 nodelay-启用以后若干常规加速将启动 69 | // 第三个参数 interval为内部处理时钟,默认设置为 10ms 70 | // 第四个参数 resend为快速重传指标,设置为2 71 | // 第五个参数 为是否禁用常规流控,这里禁止 72 | ikcp_nodelay(kcp1, 1, 10, 2, 1); 73 | ikcp_nodelay(kcp2, 1, 10, 2, 1); 74 | } 75 | 76 | 77 | char buffer[2000]; 78 | int hr; 79 | 80 | IUINT32 ts1 = iclock(); 81 | 82 | while (1) { 83 | isleep(1); 84 | current = iclock(); 85 | ikcp_update(kcp1, iclock()); 86 | ikcp_update(kcp2, iclock()); 87 | 88 | // 每隔 20ms,kcp1发送数据 89 | for (; current >= slap; slap += 20) { 90 | *(IUINT32*)(buffer + 0) = index++; 91 | *(IUINT32*)(buffer + 4) = current; 92 | 93 | // 发送上层协议包 94 | ikcp_send(kcp1, buffer, 8); 95 | } 96 | 97 | // 处理虚拟网络:检测是否有udp包从p1->p2 98 | while (1) { 99 | hr = vnet->recv(1, buffer, 2000); 100 | if (hr < 0) break; 101 | // 如果 p2收到udp,则作为下层协议输入到kcp2 102 | ikcp_input(kcp2, buffer, hr); 103 | } 104 | 105 | // 处理虚拟网络:检测是否有udp包从p2->p1 106 | while (1) { 107 | hr = vnet->recv(0, buffer, 2000); 108 | if (hr < 0) break; 109 | // 如果 p1收到udp,则作为下层协议输入到kcp1 110 | ikcp_input(kcp1, buffer, hr); 111 | } 112 | 113 | // kcp2接收到任何包都返回回去 114 | while (1) { 115 | hr = ikcp_recv(kcp2, buffer, 10); 116 | // 没有收到包就退出 117 | if (hr < 0) break; 118 | // 如果收到包就回射 119 | ikcp_send(kcp2, buffer, hr); 120 | } 121 | 122 | // kcp1收到kcp2的回射数据 123 | while (1) { 124 | hr = ikcp_recv(kcp1, buffer, 10); 125 | // 没有收到包就退出 126 | if (hr < 0) break; 127 | IUINT32 sn = *(IUINT32*)(buffer + 0); 128 | IUINT32 ts = *(IUINT32*)(buffer + 4); 129 | IUINT32 rtt = current - ts; 130 | 131 | if (sn != next) { 132 | // 如果收到的包不连续 133 | printf("ERROR sn %d<->%d\n", (int)count, (int)next); 134 | return; 135 | } 136 | 137 | next++; 138 | sumrtt += rtt; 139 | count++; 140 | if (rtt > (IUINT32)maxrtt) maxrtt = rtt; 141 | 142 | printf("[RECV] mode=%d sn=%d rtt=%d\n", mode, (int)sn, (int)rtt); 143 | } 144 | if (next > 1000) break; 145 | } 146 | 147 | ts1 = iclock() - ts1; 148 | 149 | ikcp_release(kcp1); 150 | ikcp_release(kcp2); 151 | 152 | const char *names[3] = { "default", "normal", "fast" }; 153 | printf("%s mode result (%dms):\n", names[mode], (int)ts1); 154 | printf("avgrtt=%d maxrtt=%d\n", (int)(sumrtt / count), maxrtt); 155 | printf("press enter to next ...\n"); 156 | char ch; scanf("%c", &ch); 157 | } 158 | 159 | int main() 160 | { 161 | test(0); // 默认模式,类似 TCP:正常模式,无快速重传,常规流控 162 | test(1); // 普通模式,关闭流控等 163 | test(2); // 快速模式,所有开关都打开,且关闭流控 164 | return 0; 165 | } 166 | 167 | /* 168 | default mode result (20917ms): 169 | avgrtt=740 maxrtt=1507 170 | 171 | normal mode result (20131ms): 172 | avgrtt=156 maxrtt=571 173 | 174 | fast mode result (20207ms): 175 | avgrtt=138 maxrtt=392 176 | */ 177 | 178 | -------------------------------------------------------------------------------- /3rd/kcp/test.h: -------------------------------------------------------------------------------- 1 | #ifndef __TEST_H__ 2 | #define __TEST_H__ 3 | 4 | #include 5 | #include 6 | #include 7 | #include 8 | #include 9 | 10 | #include "ikcp.h" 11 | 12 | #if defined(WIN32) || defined(_WIN32) || defined(WIN64) || defined(_WIN64) 13 | #include 14 | #elif !defined(__unix) 15 | #define __unix 16 | #endif 17 | 18 | #ifdef __unix 19 | #include 20 | #include 21 | #include 22 | #include 23 | #endif 24 | 25 | /* get system time */ 26 | static inline void itimeofday(long *sec, long *usec) 27 | { 28 | #if defined(__unix) 29 | struct timeval time; 30 | gettimeofday(&time, NULL); 31 | if (sec) *sec = time.tv_sec; 32 | if (usec) *usec = time.tv_usec; 33 | #else 34 | static long mode = 0, addsec = 0; 35 | BOOL retval; 36 | static IINT64 freq = 1; 37 | IINT64 qpc; 38 | if (mode == 0) { 39 | retval = QueryPerformanceFrequency((LARGE_INTEGER*)&freq); 40 | freq = (freq == 0)? 1 : freq; 41 | retval = QueryPerformanceCounter((LARGE_INTEGER*)&qpc); 42 | addsec = (long)time(NULL); 43 | addsec = addsec - (long)((qpc / freq) & 0x7fffffff); 44 | mode = 1; 45 | } 46 | retval = QueryPerformanceCounter((LARGE_INTEGER*)&qpc); 47 | retval = retval * 2; 48 | if (sec) *sec = (long)(qpc / freq) + addsec; 49 | if (usec) *usec = (long)((qpc % freq) * 1000000 / freq); 50 | #endif 51 | } 52 | 53 | /* get clock in millisecond 64 */ 54 | static inline IINT64 iclock64(void) 55 | { 56 | long s, u; 57 | IINT64 value; 58 | itimeofday(&s, &u); 59 | value = ((IINT64)s) * 1000 + (u / 1000); 60 | return value; 61 | } 62 | 63 | static inline IUINT32 iclock() 64 | { 65 | return (IUINT32)(iclock64() & 0xfffffffful); 66 | } 67 | 68 | /* sleep in millisecond */ 69 | static inline void isleep(unsigned long millisecond) 70 | { 71 | #ifdef __unix /* usleep( time * 1000 ); */ 72 | struct timespec ts; 73 | ts.tv_sec = (time_t)(millisecond / 1000); 74 | ts.tv_nsec = (long)((millisecond % 1000) * 1000000); 75 | /*nanosleep(&ts, NULL);*/ 76 | usleep((millisecond << 10) - (millisecond << 4) - (millisecond << 3)); 77 | #elif defined(_WIN32) 78 | Sleep(millisecond); 79 | #endif 80 | } 81 | 82 | #ifdef __cplusplus 83 | #include 84 | #include 85 | 86 | // 带延迟的数据包 87 | class DelayPacket 88 | { 89 | public: 90 | virtual ~DelayPacket() { 91 | if (_ptr) delete _ptr; 92 | _ptr = NULL; 93 | } 94 | 95 | DelayPacket(int size, const void *src = NULL) { 96 | _ptr = new unsigned char[size]; 97 | _size = size; 98 | if (src) { 99 | memcpy(_ptr, src, size); 100 | } 101 | } 102 | 103 | unsigned char* ptr() { return _ptr; } 104 | const unsigned char* ptr() const { return _ptr; } 105 | 106 | int size() const { return _size; } 107 | IUINT32 ts() const { return _ts; } 108 | void setts(IUINT32 ts) { _ts = ts; } 109 | 110 | protected: 111 | unsigned char *_ptr; 112 | int _size; 113 | IUINT32 _ts; 114 | }; 115 | 116 | // 均匀分布的随机数 117 | class Random 118 | { 119 | public: 120 | Random(int size) { 121 | this->size = 0; 122 | seeds.resize(size); 123 | } 124 | 125 | int random() { 126 | int x, i; 127 | if (seeds.size() == 0) return 0; 128 | if (size == 0) { 129 | for (i = 0; i < (int)seeds.size(); i++) { 130 | seeds[i] = i; 131 | } 132 | size = (int)seeds.size(); 133 | } 134 | i = rand() % size; 135 | x = seeds[i]; 136 | seeds[i] = seeds[--size]; 137 | return x; 138 | } 139 | 140 | protected: 141 | int size; 142 | std::vector seeds; 143 | }; 144 | 145 | // 网络延迟模拟器 146 | class LatencySimulator 147 | { 148 | public: 149 | virtual ~LatencySimulator() { 150 | clear(); 151 | } 152 | 153 | // lostrate: 往返一周丢包率的百分比,默认 10% 154 | // rttmin:rtt最小值,默认 60 155 | // rttmax:rtt最大值,默认 125 156 | LatencySimulator(int lostrate = 10, int rttmin = 60, int rttmax = 125, int nmax = 1000): 157 | r12(100), r21(100) { 158 | current = iclock(); 159 | this->lostrate = lostrate / 2; // 上面数据是往返丢包率,单程除以2 160 | this->rttmin = rttmin / 2; 161 | this->rttmax = rttmax / 2; 162 | this->nmax = nmax; 163 | } 164 | 165 | // 清除数据 166 | void clear() { 167 | DelayTunnel::iterator it; 168 | for (it = p12.begin(); it != p12.end(); it++) { 169 | delete *it; 170 | } 171 | for (it = p21.begin(); it != p21.end(); it++) { 172 | delete *it; 173 | } 174 | p12.clear(); 175 | p21.clear(); 176 | } 177 | 178 | // 发送数据 179 | // peer - 端点0/1,从0发送,从1接收;从1发送从0接收 180 | void send(int peer, const void *data, int size) { 181 | if (peer == 0) { 182 | if (r12.random() < lostrate) return; 183 | if ((int)p12.size() >= nmax) return; 184 | } else { 185 | if (r21.random() < lostrate) return; 186 | if ((int)p21.size() >= nmax) return; 187 | } 188 | DelayPacket *pkt = new DelayPacket(size, data); 189 | current = iclock(); 190 | IUINT32 delay = rttmin; 191 | if (rttmax > rttmin) delay += rand() % (rttmax - rttmin); 192 | pkt->setts(current + delay); 193 | if (peer == 0) { 194 | p12.push_back(pkt); 195 | } else { 196 | p21.push_back(pkt); 197 | } 198 | } 199 | 200 | // 接收数据 201 | int recv(int peer, void *data, int maxsize) { 202 | DelayTunnel::iterator it; 203 | if (peer == 0) { 204 | it = p21.begin(); 205 | if (p21.size() == 0) return -1; 206 | } else { 207 | it = p12.begin(); 208 | if (p12.size() == 0) return -1; 209 | } 210 | DelayPacket *pkt = *it; 211 | current = iclock(); 212 | if (current < pkt->ts()) return -2; 213 | if (maxsize < pkt->size()) return -3; 214 | if (peer == 0) { 215 | p21.erase(it); 216 | } else { 217 | p12.erase(it); 218 | } 219 | maxsize = pkt->size(); 220 | memcpy(data, pkt->ptr(), maxsize); 221 | delete pkt; 222 | return maxsize; 223 | } 224 | 225 | protected: 226 | IUINT32 current; 227 | int lostrate; 228 | int rttmin; 229 | int rttmax; 230 | int nmax; 231 | typedef std::list DelayTunnel; 232 | DelayTunnel p12; 233 | DelayTunnel p21; 234 | Random r12; 235 | Random r21; 236 | }; 237 | 238 | #endif 239 | 240 | #endif 241 | 242 | 243 | -------------------------------------------------------------------------------- /3rd/lua/Makefile: -------------------------------------------------------------------------------- 1 | # Makefile for installing Lua 2 | # See doc/readme.html for installation and customization instructions. 3 | 4 | # == CHANGE THE SETTINGS BELOW TO SUIT YOUR ENVIRONMENT ======================= 5 | 6 | # Your platform. See PLATS for possible values. 7 | PLAT= none 8 | 9 | # Where to install. The installation starts in the src and doc directories, 10 | # so take care if INSTALL_TOP is not an absolute path. See the local target. 11 | # You may want to make INSTALL_LMOD and INSTALL_CMOD consistent with 12 | # LUA_ROOT, LUA_LDIR, and LUA_CDIR in luaconf.h. 13 | INSTALL_TOP= /usr/local 14 | INSTALL_BIN= $(INSTALL_TOP)/bin 15 | INSTALL_INC= $(INSTALL_TOP)/include 16 | INSTALL_LIB= $(INSTALL_TOP)/lib 17 | INSTALL_MAN= $(INSTALL_TOP)/man/man1 18 | INSTALL_LMOD= $(INSTALL_TOP)/share/lua/$V 19 | INSTALL_CMOD= $(INSTALL_TOP)/lib/lua/$V 20 | 21 | # How to install. If your install program does not support "-p", then 22 | # you may have to run ranlib on the installed liblua.a. 23 | INSTALL= install -p 24 | INSTALL_EXEC= $(INSTALL) -m 0755 25 | INSTALL_DATA= $(INSTALL) -m 0644 26 | # 27 | # If you don't have "install" you can use "cp" instead. 28 | # INSTALL= cp -p 29 | # INSTALL_EXEC= $(INSTALL) 30 | # INSTALL_DATA= $(INSTALL) 31 | 32 | # Other utilities. 33 | MKDIR= mkdir -p 34 | RM= rm -f 35 | 36 | # == END OF USER SETTINGS -- NO NEED TO CHANGE ANYTHING BELOW THIS LINE ======= 37 | 38 | # Convenience platforms targets. 39 | PLATS= aix bsd c89 freebsd generic linux macosx mingw posix solaris 40 | 41 | # What to install. 42 | TO_BIN= lua luac 43 | TO_INC= lua.h luaconf.h lualib.h lauxlib.h lua.hpp 44 | TO_LIB= liblua.a 45 | TO_MAN= lua.1 luac.1 46 | 47 | # Lua version and release. 48 | V= 5.3 49 | R= $V.0 50 | 51 | # Targets start here. 52 | all: $(PLAT) 53 | 54 | $(PLATS) clean: 55 | cd src && $(MAKE) $@ 56 | 57 | test: dummy 58 | src/lua -v 59 | 60 | install: dummy 61 | cd src && $(MKDIR) $(INSTALL_BIN) $(INSTALL_INC) $(INSTALL_LIB) $(INSTALL_MAN) $(INSTALL_LMOD) $(INSTALL_CMOD) 62 | cd src && $(INSTALL_EXEC) $(TO_BIN) $(INSTALL_BIN) 63 | cd src && $(INSTALL_DATA) $(TO_INC) $(INSTALL_INC) 64 | cd src && $(INSTALL_DATA) $(TO_LIB) $(INSTALL_LIB) 65 | cd doc && $(INSTALL_DATA) $(TO_MAN) $(INSTALL_MAN) 66 | 67 | uninstall: 68 | cd src && cd $(INSTALL_BIN) && $(RM) $(TO_BIN) 69 | cd src && cd $(INSTALL_INC) && $(RM) $(TO_INC) 70 | cd src && cd $(INSTALL_LIB) && $(RM) $(TO_LIB) 71 | cd doc && cd $(INSTALL_MAN) && $(RM) $(TO_MAN) 72 | 73 | local: 74 | $(MAKE) install INSTALL_TOP=../install 75 | 76 | none: 77 | @echo "Please do 'make PLATFORM' where PLATFORM is one of these:" 78 | @echo " $(PLATS)" 79 | @echo "See doc/readme.html for complete instructions." 80 | 81 | # make may get confused with test/ and install/ 82 | dummy: 83 | 84 | # echo config parameters 85 | echo: 86 | @cd src && $(MAKE) -s echo 87 | @echo "PLAT= $(PLAT)" 88 | @echo "V= $V" 89 | @echo "R= $R" 90 | @echo "TO_BIN= $(TO_BIN)" 91 | @echo "TO_INC= $(TO_INC)" 92 | @echo "TO_LIB= $(TO_LIB)" 93 | @echo "TO_MAN= $(TO_MAN)" 94 | @echo "INSTALL_TOP= $(INSTALL_TOP)" 95 | @echo "INSTALL_BIN= $(INSTALL_BIN)" 96 | @echo "INSTALL_INC= $(INSTALL_INC)" 97 | @echo "INSTALL_LIB= $(INSTALL_LIB)" 98 | @echo "INSTALL_MAN= $(INSTALL_MAN)" 99 | @echo "INSTALL_LMOD= $(INSTALL_LMOD)" 100 | @echo "INSTALL_CMOD= $(INSTALL_CMOD)" 101 | @echo "INSTALL_EXEC= $(INSTALL_EXEC)" 102 | @echo "INSTALL_DATA= $(INSTALL_DATA)" 103 | 104 | # echo pkg-config data 105 | pc: 106 | @echo "version=$R" 107 | @echo "prefix=$(INSTALL_TOP)" 108 | @echo "libdir=$(INSTALL_LIB)" 109 | @echo "includedir=$(INSTALL_INC)" 110 | 111 | # list targets that do not create files (but not all makes understand .PHONY) 112 | .PHONY: all $(PLATS) clean test install local none dummy echo pecho lecho 113 | 114 | # (end of Makefile) 115 | -------------------------------------------------------------------------------- /3rd/lua/README: -------------------------------------------------------------------------------- 1 | 2 | This is Lua 5.3.0, released on 06 Jan 2015. 3 | 4 | For installation instructions, license details, and 5 | further information about Lua, see doc/readme.html. 6 | 7 | -------------------------------------------------------------------------------- /3rd/lua/doc/logo.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/linxiaolong/lua-kcp/367284d8e46686a5c9d3985e0abdcc9d49e1ecc2/3rd/lua/doc/logo.gif -------------------------------------------------------------------------------- /3rd/lua/doc/lua.1: -------------------------------------------------------------------------------- 1 | .TH LUA 1 "$Date: 2014/12/10 15:55:45 $" 2 | .SH NAME 3 | lua \- Lua interpreter 4 | .SH SYNOPSIS 5 | .B lua 6 | [ 7 | .I options 8 | ] 9 | [ 10 | .I script 11 | [ 12 | .I args 13 | ] 14 | ] 15 | .SH DESCRIPTION 16 | .B lua 17 | is the standalone Lua interpreter. 18 | It loads and executes Lua programs, 19 | either in textual source form or 20 | in precompiled binary form. 21 | (Precompiled binaries are output by 22 | .BR luac , 23 | the Lua compiler.) 24 | .B lua 25 | can be used as a batch interpreter and also interactively. 26 | .LP 27 | The given 28 | .I options 29 | are handled in order and then 30 | the Lua program in file 31 | .I script 32 | is loaded and executed. 33 | The given 34 | .I args 35 | are available to 36 | .I script 37 | as strings in a global table named 38 | .BR arg . 39 | If no options or arguments are given, 40 | then 41 | .B "\-v \-i" 42 | is assumed when the standard input is a terminal; 43 | otherwise, 44 | .B "\-" 45 | is assumed. 46 | .LP 47 | In interactive mode, 48 | .B lua 49 | prompts the user, 50 | reads lines from the standard input, 51 | and executes them as they are read. 52 | If the line contains an expression or list of expressions, 53 | then the line is evaluated and the results are printed. 54 | If a line does not contain a complete statement, 55 | then a secondary prompt is displayed and 56 | lines are read until a complete statement is formed or 57 | a syntax error is found. 58 | .LP 59 | At the very start, 60 | before even handling the command line, 61 | .B lua 62 | checks the contents of the environment variables 63 | .B LUA_INIT_5_3 64 | or 65 | .BR LUA_INIT , 66 | in that order. 67 | If the contents is of the form 68 | .RI '@ filename ', 69 | then 70 | .I filename 71 | is executed. 72 | Otherwise, the string is assumed to be a Lua statement and is executed. 73 | .SH OPTIONS 74 | .TP 75 | .BI \-e " stat" 76 | execute statement 77 | .IR stat . 78 | .TP 79 | .B \-i 80 | enter interactive mode after executing 81 | .IR script . 82 | .TP 83 | .BI \-l " name" 84 | execute the equivalent of 85 | .IB name =require(' name ') 86 | before executing 87 | .IR script . 88 | .TP 89 | .B \-v 90 | show version information. 91 | .TP 92 | .B \-E 93 | ignore environment variables. 94 | .TP 95 | .B \-\- 96 | stop handling options. 97 | .TP 98 | .B \- 99 | stop handling options and execute the standard input as a file. 100 | .SH "SEE ALSO" 101 | .BR luac (1) 102 | .br 103 | The documentation at lua.org, 104 | especially section 7 of the reference manual. 105 | .SH DIAGNOSTICS 106 | Error messages should be self explanatory. 107 | .SH AUTHORS 108 | R. Ierusalimschy, 109 | L. H. de Figueiredo, 110 | W. Celes 111 | .\" EOF 112 | -------------------------------------------------------------------------------- /3rd/lua/doc/lua.css: -------------------------------------------------------------------------------- 1 | html { 2 | background-color: #F8F8F8 ; 3 | } 4 | 5 | body { 6 | border: solid #a0a0a0 1px ; 7 | border-radius: 20px ; 8 | padding: 26px ; 9 | margin: 16px ; 10 | color: #000000 ; 11 | background-color: #FFFFFF ; 12 | font-family: Helvetica, Arial, sans-serif ; 13 | text-align: justify ; 14 | } 15 | 16 | h1, h2, h3, h4 { 17 | font-family: Verdana, Geneva, sans-serif ; 18 | font-weight: normal ; 19 | font-style: normal ; 20 | } 21 | 22 | h2 { 23 | padding-top: 0.4em ; 24 | padding-bottom: 0.4em ; 25 | padding-left: 0.8em ; 26 | padding-right: 0.8em ; 27 | background-color: #D0D0FF ; 28 | border-radius: 8px ; 29 | border: solid #a0a0a0 1px ; 30 | } 31 | 32 | h3 { 33 | padding-left: 0.5em ; 34 | border-left: solid #D0D0FF 1em ; 35 | } 36 | 37 | table h3 { 38 | padding-left: 0px ; 39 | border-left: none ; 40 | } 41 | 42 | a:link { 43 | color: #000080 ; 44 | background-color: inherit ; 45 | text-decoration: none ; 46 | } 47 | 48 | a:visited { 49 | background-color: inherit ; 50 | text-decoration: none ; 51 | } 52 | 53 | a:link:hover, a:visited:hover { 54 | color: #000080 ; 55 | background-color: #D0D0FF ; 56 | border-radius: 4px; 57 | } 58 | 59 | a:link:active, a:visited:active { 60 | color: #FF0000 ; 61 | } 62 | 63 | h1 a img { 64 | vertical-align: text-bottom ; 65 | } 66 | 67 | hr { 68 | border: 0 ; 69 | height: 1px ; 70 | color: #a0a0a0 ; 71 | background-color: #a0a0a0 ; 72 | display: none ; 73 | } 74 | 75 | table hr { 76 | display: block ; 77 | } 78 | 79 | :target { 80 | background-color: #F8F8F8 ; 81 | padding: 8px ; 82 | border: solid #a0a0a0 2px ; 83 | border-radius: 8px ; 84 | } 85 | 86 | .footer { 87 | color: gray ; 88 | font-size: x-small ; 89 | } 90 | 91 | input[type=text] { 92 | border: solid #a0a0a0 2px ; 93 | border-radius: 2em ; 94 | background-image: url('images/search.png') ; 95 | background-repeat: no-repeat ; 96 | background-position: 4px center ; 97 | padding-left: 20px ; 98 | height: 2em ; 99 | } 100 | 101 | pre.session { 102 | background-color: #F8F8F8 ; 103 | padding: 1em ; 104 | border-radius: 8px ; 105 | } 106 | -------------------------------------------------------------------------------- /3rd/lua/doc/luac.1: -------------------------------------------------------------------------------- 1 | .\" $Id: luac.man,v 1.29 2011/11/16 13:53:40 lhf Exp $ 2 | .TH LUAC 1 "$Date: 2011/11/16 13:53:40 $" 3 | .SH NAME 4 | luac \- Lua compiler 5 | .SH SYNOPSIS 6 | .B luac 7 | [ 8 | .I options 9 | ] [ 10 | .I filenames 11 | ] 12 | .SH DESCRIPTION 13 | .B luac 14 | is the Lua compiler. 15 | It translates programs written in the Lua programming language 16 | into binary files containing precompiled chunks 17 | that can be later loaded and executed. 18 | .LP 19 | The main advantages of precompiling chunks are: 20 | faster loading, 21 | protecting source code from accidental user changes, 22 | and 23 | off-line syntax checking. 24 | Precompiling does not imply faster execution 25 | because in Lua chunks are always compiled into bytecodes before being executed. 26 | .B luac 27 | simply allows those bytecodes to be saved in a file for later execution. 28 | Precompiled chunks are not necessarily smaller than the corresponding source. 29 | The main goal in precompiling is faster loading. 30 | .LP 31 | In the command line, 32 | you can mix 33 | text files containing Lua source and 34 | binary files containing precompiled chunks. 35 | .B luac 36 | produces a single output file containing the combined bytecodes 37 | for all files given. 38 | Executing the combined file is equivalent to executing the given files. 39 | By default, 40 | the output file is named 41 | .BR luac.out , 42 | but you can change this with the 43 | .B \-o 44 | option. 45 | .LP 46 | Precompiled chunks are 47 | .I not 48 | portable across different architectures. 49 | Moreover, 50 | the internal format of precompiled chunks 51 | is likely to change when a new version of Lua is released. 52 | Make sure you save the source files of all Lua programs that you precompile. 53 | .LP 54 | .SH OPTIONS 55 | .TP 56 | .B \-l 57 | produce a listing of the compiled bytecode for Lua's virtual machine. 58 | Listing bytecodes is useful to learn about Lua's virtual machine. 59 | If no files are given, then 60 | .B luac 61 | loads 62 | .B luac.out 63 | and lists its contents. 64 | Use 65 | .B \-l \-l 66 | for a full listing. 67 | .TP 68 | .BI \-o " file" 69 | output to 70 | .IR file , 71 | instead of the default 72 | .BR luac.out . 73 | (You can use 74 | .B "'\-'" 75 | for standard output, 76 | but not on platforms that open standard output in text mode.) 77 | The output file may be one of the given files because 78 | all files are loaded before the output file is written. 79 | Be careful not to overwrite precious files. 80 | .TP 81 | .B \-p 82 | load files but do not generate any output file. 83 | Used mainly for syntax checking and for testing precompiled chunks: 84 | corrupted files will probably generate errors when loaded. 85 | If no files are given, then 86 | .B luac 87 | loads 88 | .B luac.out 89 | and tests its contents. 90 | No messages are displayed if the file loads without errors. 91 | .TP 92 | .B \-s 93 | strip debug information before writing the output file. 94 | This saves some space in very large chunks, 95 | but if errors occur when running a stripped chunk, 96 | then the error messages may not contain the full information they usually do. 97 | In particular, 98 | line numbers and names of local variables are lost. 99 | .TP 100 | .B \-v 101 | show version information. 102 | .TP 103 | .B \-\- 104 | stop handling options. 105 | .TP 106 | .B \- 107 | stop handling options and process standard input. 108 | .SH "SEE ALSO" 109 | .BR lua (1) 110 | .br 111 | The documentation at lua.org. 112 | .SH DIAGNOSTICS 113 | Error messages should be self explanatory. 114 | .SH AUTHORS 115 | R. Ierusalimschy, 116 | L. H. de Figueiredo, 117 | W. Celes 118 | .\" EOF 119 | -------------------------------------------------------------------------------- /3rd/lua/doc/manual.css: -------------------------------------------------------------------------------- 1 | h3 code { 2 | font-family: inherit ; 3 | font-size: inherit ; 4 | } 5 | 6 | pre, code { 7 | font-size: 12pt ; 8 | } 9 | 10 | span.apii { 11 | float: right ; 12 | font-family: inherit ; 13 | font-style: normal ; 14 | font-size: small ; 15 | color: gray ; 16 | } 17 | 18 | p+h1, ul+h1 { 19 | font-style: normal ; 20 | padding-top: 0.4em ; 21 | padding-bottom: 0.4em ; 22 | padding-left: 16px ; 23 | margin-left: -16px ; 24 | background-color: #D0D0FF ; 25 | border-radius: 8px ; 26 | border: solid #000080 1px ; 27 | } 28 | -------------------------------------------------------------------------------- /3rd/lua/doc/osi-certified-72x60.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/linxiaolong/lua-kcp/367284d8e46686a5c9d3985e0abdcc9d49e1ecc2/3rd/lua/doc/osi-certified-72x60.png -------------------------------------------------------------------------------- /3rd/lua/src/Makefile: -------------------------------------------------------------------------------- 1 | # Makefile for building Lua 2 | # See ../doc/readme.html for installation and customization instructions. 3 | 4 | # == CHANGE THE SETTINGS BELOW TO SUIT YOUR ENVIRONMENT ======================= 5 | 6 | # Your platform. See PLATS for possible values. 7 | PLAT= none 8 | 9 | CC= gcc -std=gnu99 10 | CFLAGS= -O2 -Wall -Wextra -DLUA_COMPAT_5_2 $(SYSCFLAGS) $(MYCFLAGS) 11 | LDFLAGS= $(SYSLDFLAGS) $(MYLDFLAGS) 12 | LIBS= -lm $(SYSLIBS) $(MYLIBS) 13 | 14 | AR= ar rcu 15 | RANLIB= ranlib 16 | RM= rm -f 17 | 18 | SYSCFLAGS= 19 | SYSLDFLAGS= 20 | SYSLIBS= 21 | 22 | MYCFLAGS= 23 | MYLDFLAGS= 24 | MYLIBS= 25 | MYOBJS= 26 | 27 | # == END OF USER SETTINGS -- NO NEED TO CHANGE ANYTHING BELOW THIS LINE ======= 28 | 29 | PLATS= aix bsd c89 freebsd generic linux macosx mingw posix solaris 30 | 31 | LUA_A= liblua.a 32 | CORE_O= lapi.o lcode.o lctype.o ldebug.o ldo.o ldump.o lfunc.o lgc.o llex.o \ 33 | lmem.o lobject.o lopcodes.o lparser.o lstate.o lstring.o ltable.o \ 34 | ltm.o lundump.o lvm.o lzio.o 35 | LIB_O= lauxlib.o lbaselib.o lbitlib.o lcorolib.o ldblib.o liolib.o \ 36 | lmathlib.o loslib.o lstrlib.o ltablib.o lutf8lib.o loadlib.o linit.o 37 | BASE_O= $(CORE_O) $(LIB_O) $(MYOBJS) 38 | 39 | LUA_T= lua 40 | LUA_O= lua.o 41 | 42 | LUAC_T= luac 43 | LUAC_O= luac.o 44 | 45 | ALL_O= $(BASE_O) $(LUA_O) $(LUAC_O) 46 | ALL_T= $(LUA_A) $(LUA_T) $(LUAC_T) 47 | ALL_A= $(LUA_A) 48 | 49 | # Targets start here. 50 | default: $(PLAT) 51 | 52 | all: $(ALL_T) 53 | 54 | o: $(ALL_O) 55 | 56 | a: $(ALL_A) 57 | 58 | $(LUA_A): $(BASE_O) 59 | $(AR) $@ $(BASE_O) 60 | $(RANLIB) $@ 61 | 62 | $(LUA_T): $(LUA_O) $(LUA_A) 63 | $(CC) -o $@ $(LDFLAGS) $(LUA_O) $(LUA_A) $(LIBS) 64 | 65 | $(LUAC_T): $(LUAC_O) $(LUA_A) 66 | $(CC) -o $@ $(LDFLAGS) $(LUAC_O) $(LUA_A) $(LIBS) 67 | 68 | clean: 69 | $(RM) $(ALL_T) $(ALL_O) 70 | 71 | depend: 72 | @$(CC) $(CFLAGS) -MM l*.c 73 | 74 | echo: 75 | @echo "PLAT= $(PLAT)" 76 | @echo "CC= $(CC)" 77 | @echo "CFLAGS= $(CFLAGS)" 78 | @echo "LDFLAGS= $(SYSLDFLAGS)" 79 | @echo "LIBS= $(LIBS)" 80 | @echo "AR= $(AR)" 81 | @echo "RANLIB= $(RANLIB)" 82 | @echo "RM= $(RM)" 83 | 84 | # Convenience targets for popular platforms 85 | ALL= all 86 | 87 | none: 88 | @echo "Please do 'make PLATFORM' where PLATFORM is one of these:" 89 | @echo " $(PLATS)" 90 | 91 | aix: 92 | $(MAKE) $(ALL) CC="xlc" CFLAGS="-O2 -DLUA_USE_POSIX -DLUA_USE_DLOPEN" SYSLIBS="-ldl" SYSLDFLAGS="-brtl -bexpall" 93 | 94 | bsd: 95 | $(MAKE) $(ALL) SYSCFLAGS="-DLUA_USE_POSIX -DLUA_USE_DLOPEN" SYSLIBS="-Wl,-E" 96 | 97 | c89: 98 | $(MAKE) $(ALL) SYSCFLAGS="-DLUA_USE_C89" CC="gcc -std=c89" 99 | @echo '' 100 | @echo '*** C89 does not guarantee 64-bit integers for Lua.' 101 | @echo '' 102 | 103 | 104 | freebsd: 105 | $(MAKE) $(ALL) SYSCFLAGS="-DLUA_USE_LINUX" SYSLIBS="-Wl,-E -lreadline" 106 | 107 | generic: $(ALL) 108 | 109 | linux: 110 | $(MAKE) $(ALL) SYSCFLAGS="-DLUA_USE_LINUX" SYSLIBS="-Wl,-E -ldl -lreadline" 111 | 112 | macosx: 113 | $(MAKE) $(ALL) SYSCFLAGS="-DLUA_USE_MACOSX" SYSLIBS="-lreadline" CC=cc 114 | 115 | mingw: 116 | $(MAKE) "LUA_A=lua53.dll" "LUA_T=lua.exe" \ 117 | "AR=$(CC) -shared -o" "RANLIB=strip --strip-unneeded" \ 118 | "SYSCFLAGS=-DLUA_BUILD_AS_DLL" "SYSLIBS=" "SYSLDFLAGS=-s" lua.exe 119 | $(MAKE) "LUAC_T=luac.exe" luac.exe 120 | 121 | posix: 122 | $(MAKE) $(ALL) SYSCFLAGS="-DLUA_USE_POSIX" 123 | 124 | solaris: 125 | $(MAKE) $(ALL) SYSCFLAGS="-DLUA_USE_POSIX -DLUA_USE_DLOPEN -D_REENTRANT" SYSLIBS="-ldl" 126 | 127 | # list targets that do not create files (but not all makes understand .PHONY) 128 | .PHONY: all $(PLATS) default o a clean depend echo none 129 | 130 | # DO NOT DELETE 131 | 132 | lapi.o: lapi.c lprefix.h lua.h luaconf.h lapi.h llimits.h lstate.h \ 133 | lobject.h ltm.h lzio.h lmem.h ldebug.h ldo.h lfunc.h lgc.h lstring.h \ 134 | ltable.h lundump.h lvm.h 135 | lauxlib.o: lauxlib.c lprefix.h lua.h luaconf.h lauxlib.h 136 | lbaselib.o: lbaselib.c lprefix.h lua.h luaconf.h lauxlib.h lualib.h 137 | lbitlib.o: lbitlib.c lprefix.h lua.h luaconf.h lauxlib.h lualib.h 138 | lcode.o: lcode.c lprefix.h lua.h luaconf.h lcode.h llex.h lobject.h \ 139 | llimits.h lzio.h lmem.h lopcodes.h lparser.h ldebug.h lstate.h ltm.h \ 140 | ldo.h lgc.h lstring.h ltable.h lvm.h 141 | lcorolib.o: lcorolib.c lprefix.h lua.h luaconf.h lauxlib.h lualib.h 142 | lctype.o: lctype.c lprefix.h lctype.h lua.h luaconf.h llimits.h 143 | ldblib.o: ldblib.c lprefix.h lua.h luaconf.h lauxlib.h lualib.h 144 | ldebug.o: ldebug.c lprefix.h lua.h luaconf.h lapi.h llimits.h lstate.h \ 145 | lobject.h ltm.h lzio.h lmem.h lcode.h llex.h lopcodes.h lparser.h \ 146 | ldebug.h ldo.h lfunc.h lstring.h lgc.h ltable.h lvm.h 147 | ldo.o: ldo.c lprefix.h lua.h luaconf.h lapi.h llimits.h lstate.h \ 148 | lobject.h ltm.h lzio.h lmem.h ldebug.h ldo.h lfunc.h lgc.h lopcodes.h \ 149 | lparser.h lstring.h ltable.h lundump.h lvm.h 150 | ldump.o: ldump.c lprefix.h lua.h luaconf.h lobject.h llimits.h lstate.h \ 151 | ltm.h lzio.h lmem.h lundump.h 152 | lfunc.o: lfunc.c lprefix.h lua.h luaconf.h lfunc.h lobject.h llimits.h \ 153 | lgc.h lstate.h ltm.h lzio.h lmem.h 154 | lgc.o: lgc.c lprefix.h lua.h luaconf.h ldebug.h lstate.h lobject.h \ 155 | llimits.h ltm.h lzio.h lmem.h ldo.h lfunc.h lgc.h lstring.h ltable.h 156 | linit.o: linit.c lprefix.h lua.h luaconf.h lualib.h lauxlib.h 157 | liolib.o: liolib.c lprefix.h lua.h luaconf.h lauxlib.h lualib.h 158 | llex.o: llex.c lprefix.h lua.h luaconf.h lctype.h llimits.h ldo.h \ 159 | lobject.h lstate.h ltm.h lzio.h lmem.h lgc.h llex.h lparser.h lstring.h \ 160 | ltable.h 161 | lmathlib.o: lmathlib.c lprefix.h lua.h luaconf.h lauxlib.h lualib.h 162 | lmem.o: lmem.c lprefix.h lua.h luaconf.h ldebug.h lstate.h lobject.h \ 163 | llimits.h ltm.h lzio.h lmem.h ldo.h lgc.h 164 | loadlib.o: loadlib.c lprefix.h lua.h luaconf.h lauxlib.h lualib.h 165 | lobject.o: lobject.c lprefix.h lua.h luaconf.h lctype.h llimits.h \ 166 | ldebug.h lstate.h lobject.h ltm.h lzio.h lmem.h ldo.h lstring.h lgc.h \ 167 | lvm.h 168 | lopcodes.o: lopcodes.c lprefix.h lopcodes.h llimits.h lua.h luaconf.h 169 | loslib.o: loslib.c lprefix.h lua.h luaconf.h lauxlib.h lualib.h 170 | lparser.o: lparser.c lprefix.h lua.h luaconf.h lcode.h llex.h lobject.h \ 171 | llimits.h lzio.h lmem.h lopcodes.h lparser.h ldebug.h lstate.h ltm.h \ 172 | ldo.h lfunc.h lstring.h lgc.h ltable.h 173 | lstate.o: lstate.c lprefix.h lua.h luaconf.h lapi.h llimits.h lstate.h \ 174 | lobject.h ltm.h lzio.h lmem.h ldebug.h ldo.h lfunc.h lgc.h llex.h \ 175 | lstring.h ltable.h 176 | lstring.o: lstring.c lprefix.h lua.h luaconf.h ldebug.h lstate.h \ 177 | lobject.h llimits.h ltm.h lzio.h lmem.h ldo.h lstring.h lgc.h 178 | lstrlib.o: lstrlib.c lprefix.h lua.h luaconf.h lauxlib.h lualib.h 179 | ltable.o: ltable.c lprefix.h lua.h luaconf.h ldebug.h lstate.h lobject.h \ 180 | llimits.h ltm.h lzio.h lmem.h ldo.h lgc.h lstring.h ltable.h lvm.h 181 | ltablib.o: ltablib.c lprefix.h lua.h luaconf.h lauxlib.h lualib.h 182 | ltm.o: ltm.c lprefix.h lua.h luaconf.h ldebug.h lstate.h lobject.h \ 183 | llimits.h ltm.h lzio.h lmem.h ldo.h lstring.h lgc.h ltable.h lvm.h 184 | lua.o: lua.c lprefix.h lua.h luaconf.h lauxlib.h lualib.h 185 | luac.o: luac.c lprefix.h lua.h luaconf.h lauxlib.h lobject.h llimits.h \ 186 | lstate.h ltm.h lzio.h lmem.h lundump.h ldebug.h lopcodes.h 187 | lundump.o: lundump.c lprefix.h lua.h luaconf.h ldebug.h lstate.h \ 188 | lobject.h llimits.h ltm.h lzio.h lmem.h ldo.h lfunc.h lstring.h lgc.h \ 189 | lundump.h 190 | lutf8lib.o: lutf8lib.c lprefix.h lua.h luaconf.h lauxlib.h lualib.h 191 | lvm.o: lvm.c lprefix.h lua.h luaconf.h ldebug.h lstate.h lobject.h \ 192 | llimits.h ltm.h lzio.h lmem.h ldo.h lfunc.h lgc.h lopcodes.h lstring.h \ 193 | ltable.h lvm.h 194 | lzio.o: lzio.c lprefix.h lua.h luaconf.h llimits.h lmem.h lstate.h \ 195 | lobject.h ltm.h lzio.h 196 | 197 | # (end of Makefile) 198 | -------------------------------------------------------------------------------- /3rd/lua/src/lapi.h: -------------------------------------------------------------------------------- 1 | /* 2 | ** $Id: lapi.h,v 2.8 2014/07/15 21:26:50 roberto Exp $ 3 | ** Auxiliary functions from Lua API 4 | ** See Copyright Notice in lua.h 5 | */ 6 | 7 | #ifndef lapi_h 8 | #define lapi_h 9 | 10 | 11 | #include "llimits.h" 12 | #include "lstate.h" 13 | 14 | #define api_incr_top(L) {L->top++; api_check(L->top <= L->ci->top, \ 15 | "stack overflow");} 16 | 17 | #define adjustresults(L,nres) \ 18 | { if ((nres) == LUA_MULTRET && L->ci->top < L->top) L->ci->top = L->top; } 19 | 20 | #define api_checknelems(L,n) api_check((n) < (L->top - L->ci->func), \ 21 | "not enough elements in the stack") 22 | 23 | 24 | #endif 25 | -------------------------------------------------------------------------------- /3rd/lua/src/lauxlib.h: -------------------------------------------------------------------------------- 1 | /* 2 | ** $Id: lauxlib.h,v 1.128 2014/10/29 16:11:17 roberto Exp $ 3 | ** Auxiliary functions for building Lua libraries 4 | ** See Copyright Notice in lua.h 5 | */ 6 | 7 | 8 | #ifndef lauxlib_h 9 | #define lauxlib_h 10 | 11 | 12 | #include 13 | #include 14 | 15 | #include "lua.h" 16 | 17 | 18 | 19 | /* extra error code for 'luaL_load' */ 20 | #define LUA_ERRFILE (LUA_ERRERR+1) 21 | 22 | 23 | typedef struct luaL_Reg { 24 | const char *name; 25 | lua_CFunction func; 26 | } luaL_Reg; 27 | 28 | 29 | #define LUAL_NUMSIZES (sizeof(lua_Integer)*16 + sizeof(lua_Number)) 30 | 31 | LUALIB_API void (luaL_checkversion_) (lua_State *L, lua_Number ver, size_t sz); 32 | #define luaL_checkversion(L) \ 33 | luaL_checkversion_(L, LUA_VERSION_NUM, LUAL_NUMSIZES) 34 | 35 | LUALIB_API int (luaL_getmetafield) (lua_State *L, int obj, const char *e); 36 | LUALIB_API int (luaL_callmeta) (lua_State *L, int obj, const char *e); 37 | LUALIB_API const char *(luaL_tolstring) (lua_State *L, int idx, size_t *len); 38 | LUALIB_API int (luaL_argerror) (lua_State *L, int arg, const char *extramsg); 39 | LUALIB_API const char *(luaL_checklstring) (lua_State *L, int arg, 40 | size_t *l); 41 | LUALIB_API const char *(luaL_optlstring) (lua_State *L, int arg, 42 | const char *def, size_t *l); 43 | LUALIB_API lua_Number (luaL_checknumber) (lua_State *L, int arg); 44 | LUALIB_API lua_Number (luaL_optnumber) (lua_State *L, int arg, lua_Number def); 45 | 46 | LUALIB_API lua_Integer (luaL_checkinteger) (lua_State *L, int arg); 47 | LUALIB_API lua_Integer (luaL_optinteger) (lua_State *L, int arg, 48 | lua_Integer def); 49 | 50 | LUALIB_API void (luaL_checkstack) (lua_State *L, int sz, const char *msg); 51 | LUALIB_API void (luaL_checktype) (lua_State *L, int arg, int t); 52 | LUALIB_API void (luaL_checkany) (lua_State *L, int arg); 53 | 54 | LUALIB_API int (luaL_newmetatable) (lua_State *L, const char *tname); 55 | LUALIB_API void (luaL_setmetatable) (lua_State *L, const char *tname); 56 | LUALIB_API void *(luaL_testudata) (lua_State *L, int ud, const char *tname); 57 | LUALIB_API void *(luaL_checkudata) (lua_State *L, int ud, const char *tname); 58 | 59 | LUALIB_API void (luaL_where) (lua_State *L, int lvl); 60 | LUALIB_API int (luaL_error) (lua_State *L, const char *fmt, ...); 61 | 62 | LUALIB_API int (luaL_checkoption) (lua_State *L, int arg, const char *def, 63 | const char *const lst[]); 64 | 65 | LUALIB_API int (luaL_fileresult) (lua_State *L, int stat, const char *fname); 66 | LUALIB_API int (luaL_execresult) (lua_State *L, int stat); 67 | 68 | /* pre-defined references */ 69 | #define LUA_NOREF (-2) 70 | #define LUA_REFNIL (-1) 71 | 72 | LUALIB_API int (luaL_ref) (lua_State *L, int t); 73 | LUALIB_API void (luaL_unref) (lua_State *L, int t, int ref); 74 | 75 | LUALIB_API int (luaL_loadfilex) (lua_State *L, const char *filename, 76 | const char *mode); 77 | 78 | #define luaL_loadfile(L,f) luaL_loadfilex(L,f,NULL) 79 | 80 | LUALIB_API int (luaL_loadbufferx) (lua_State *L, const char *buff, size_t sz, 81 | const char *name, const char *mode); 82 | LUALIB_API int (luaL_loadstring) (lua_State *L, const char *s); 83 | 84 | LUALIB_API lua_State *(luaL_newstate) (void); 85 | 86 | LUALIB_API lua_Integer (luaL_len) (lua_State *L, int idx); 87 | 88 | LUALIB_API const char *(luaL_gsub) (lua_State *L, const char *s, const char *p, 89 | const char *r); 90 | 91 | LUALIB_API void (luaL_setfuncs) (lua_State *L, const luaL_Reg *l, int nup); 92 | 93 | LUALIB_API int (luaL_getsubtable) (lua_State *L, int idx, const char *fname); 94 | 95 | LUALIB_API void (luaL_traceback) (lua_State *L, lua_State *L1, 96 | const char *msg, int level); 97 | 98 | LUALIB_API void (luaL_requiref) (lua_State *L, const char *modname, 99 | lua_CFunction openf, int glb); 100 | 101 | /* 102 | ** =============================================================== 103 | ** some useful macros 104 | ** =============================================================== 105 | */ 106 | 107 | 108 | #define luaL_newlibtable(L,l) \ 109 | lua_createtable(L, 0, sizeof(l)/sizeof((l)[0]) - 1) 110 | 111 | #define luaL_newlib(L,l) \ 112 | (luaL_checkversion(L), luaL_newlibtable(L,l), luaL_setfuncs(L,l,0)) 113 | 114 | #define luaL_argcheck(L, cond,arg,extramsg) \ 115 | ((void)((cond) || luaL_argerror(L, (arg), (extramsg)))) 116 | #define luaL_checkstring(L,n) (luaL_checklstring(L, (n), NULL)) 117 | #define luaL_optstring(L,n,d) (luaL_optlstring(L, (n), (d), NULL)) 118 | 119 | #define luaL_typename(L,i) lua_typename(L, lua_type(L,(i))) 120 | 121 | #define luaL_dofile(L, fn) \ 122 | (luaL_loadfile(L, fn) || lua_pcall(L, 0, LUA_MULTRET, 0)) 123 | 124 | #define luaL_dostring(L, s) \ 125 | (luaL_loadstring(L, s) || lua_pcall(L, 0, LUA_MULTRET, 0)) 126 | 127 | #define luaL_getmetatable(L,n) (lua_getfield(L, LUA_REGISTRYINDEX, (n))) 128 | 129 | #define luaL_opt(L,f,n,d) (lua_isnoneornil(L,(n)) ? (d) : f(L,(n))) 130 | 131 | #define luaL_loadbuffer(L,s,sz,n) luaL_loadbufferx(L,s,sz,n,NULL) 132 | 133 | 134 | /* 135 | ** {====================================================== 136 | ** Generic Buffer manipulation 137 | ** ======================================================= 138 | */ 139 | 140 | typedef struct luaL_Buffer { 141 | char *b; /* buffer address */ 142 | size_t size; /* buffer size */ 143 | size_t n; /* number of characters in buffer */ 144 | lua_State *L; 145 | char initb[LUAL_BUFFERSIZE]; /* initial buffer */ 146 | } luaL_Buffer; 147 | 148 | 149 | #define luaL_addchar(B,c) \ 150 | ((void)((B)->n < (B)->size || luaL_prepbuffsize((B), 1)), \ 151 | ((B)->b[(B)->n++] = (c))) 152 | 153 | #define luaL_addsize(B,s) ((B)->n += (s)) 154 | 155 | LUALIB_API void (luaL_buffinit) (lua_State *L, luaL_Buffer *B); 156 | LUALIB_API char *(luaL_prepbuffsize) (luaL_Buffer *B, size_t sz); 157 | LUALIB_API void (luaL_addlstring) (luaL_Buffer *B, const char *s, size_t l); 158 | LUALIB_API void (luaL_addstring) (luaL_Buffer *B, const char *s); 159 | LUALIB_API void (luaL_addvalue) (luaL_Buffer *B); 160 | LUALIB_API void (luaL_pushresult) (luaL_Buffer *B); 161 | LUALIB_API void (luaL_pushresultsize) (luaL_Buffer *B, size_t sz); 162 | LUALIB_API char *(luaL_buffinitsize) (lua_State *L, luaL_Buffer *B, size_t sz); 163 | 164 | #define luaL_prepbuffer(B) luaL_prepbuffsize(B, LUAL_BUFFERSIZE) 165 | 166 | /* }====================================================== */ 167 | 168 | 169 | 170 | /* 171 | ** {====================================================== 172 | ** File handles for IO library 173 | ** ======================================================= 174 | */ 175 | 176 | /* 177 | ** A file handle is a userdata with metatable 'LUA_FILEHANDLE' and 178 | ** initial structure 'luaL_Stream' (it may contain other fields 179 | ** after that initial structure). 180 | */ 181 | 182 | #define LUA_FILEHANDLE "FILE*" 183 | 184 | 185 | typedef struct luaL_Stream { 186 | FILE *f; /* stream (NULL for incompletely created streams) */ 187 | lua_CFunction closef; /* to close stream (NULL for closed streams) */ 188 | } luaL_Stream; 189 | 190 | /* }====================================================== */ 191 | 192 | 193 | 194 | /* compatibility with old module system */ 195 | #if defined(LUA_COMPAT_MODULE) 196 | 197 | LUALIB_API void (luaL_pushmodule) (lua_State *L, const char *modname, 198 | int sizehint); 199 | LUALIB_API void (luaL_openlib) (lua_State *L, const char *libname, 200 | const luaL_Reg *l, int nup); 201 | 202 | #define luaL_register(L,n,l) (luaL_openlib(L,(n),(l),0)) 203 | 204 | #endif 205 | 206 | 207 | /* 208 | ** {================================================================== 209 | ** "Abstraction Layer" for basic report of messages and errors 210 | ** =================================================================== 211 | */ 212 | 213 | /* print a string */ 214 | #if !defined(lua_writestring) 215 | #define lua_writestring(s,l) fwrite((s), sizeof(char), (l), stdout) 216 | #endif 217 | 218 | /* print a newline and flush the output */ 219 | #if !defined(lua_writeline) 220 | #define lua_writeline() (lua_writestring("\n", 1), fflush(stdout)) 221 | #endif 222 | 223 | /* print an error message */ 224 | #if !defined(lua_writestringerror) 225 | #define lua_writestringerror(s,p) \ 226 | (fprintf(stderr, (s), (p)), fflush(stderr)) 227 | #endif 228 | 229 | /* }================================================================== */ 230 | 231 | 232 | /* 233 | ** {============================================================ 234 | ** Compatibility with deprecated conversions 235 | ** ============================================================= 236 | */ 237 | #if defined(LUA_COMPAT_APIINTCASTS) 238 | 239 | #define luaL_checkunsigned(L,a) ((lua_Unsigned)luaL_checkinteger(L,a)) 240 | #define luaL_optunsigned(L,a,d) \ 241 | ((lua_Unsigned)luaL_optinteger(L,a,(lua_Integer)(d))) 242 | 243 | #define luaL_checkint(L,n) ((int)luaL_checkinteger(L, (n))) 244 | #define luaL_optint(L,n,d) ((int)luaL_optinteger(L, (n), (d))) 245 | 246 | #define luaL_checklong(L,n) ((long)luaL_checkinteger(L, (n))) 247 | #define luaL_optlong(L,n,d) ((long)luaL_optinteger(L, (n), (d))) 248 | 249 | #endif 250 | /* }============================================================ */ 251 | 252 | 253 | 254 | #endif 255 | 256 | 257 | -------------------------------------------------------------------------------- /3rd/lua/src/lbitlib.c: -------------------------------------------------------------------------------- 1 | /* 2 | ** $Id: lbitlib.c,v 1.28 2014/11/02 19:19:04 roberto Exp $ 3 | ** Standard library for bitwise operations 4 | ** See Copyright Notice in lua.h 5 | */ 6 | 7 | #define lbitlib_c 8 | #define LUA_LIB 9 | 10 | #include "lprefix.h" 11 | 12 | 13 | #include "lua.h" 14 | 15 | #include "lauxlib.h" 16 | #include "lualib.h" 17 | 18 | 19 | #if defined(LUA_COMPAT_BITLIB) /* { */ 20 | 21 | 22 | /* number of bits to consider in a number */ 23 | #if !defined(LUA_NBITS) 24 | #define LUA_NBITS 32 25 | #endif 26 | 27 | 28 | /* 29 | ** a lua_Unsigned with its first LUA_NBITS bits equal to 1. (Shift must 30 | ** be made in two parts to avoid problems when LUA_NBITS is equal to the 31 | ** number of bits in a lua_Unsigned.) 32 | */ 33 | #define ALLONES (~(((~(lua_Unsigned)0) << (LUA_NBITS - 1)) << 1)) 34 | 35 | 36 | /* macro to trim extra bits */ 37 | #define trim(x) ((x) & ALLONES) 38 | 39 | 40 | /* builds a number with 'n' ones (1 <= n <= LUA_NBITS) */ 41 | #define mask(n) (~((ALLONES << 1) << ((n) - 1))) 42 | 43 | 44 | 45 | static lua_Unsigned andaux (lua_State *L) { 46 | int i, n = lua_gettop(L); 47 | lua_Unsigned r = ~(lua_Unsigned)0; 48 | for (i = 1; i <= n; i++) 49 | r &= luaL_checkunsigned(L, i); 50 | return trim(r); 51 | } 52 | 53 | 54 | static int b_and (lua_State *L) { 55 | lua_Unsigned r = andaux(L); 56 | lua_pushunsigned(L, r); 57 | return 1; 58 | } 59 | 60 | 61 | static int b_test (lua_State *L) { 62 | lua_Unsigned r = andaux(L); 63 | lua_pushboolean(L, r != 0); 64 | return 1; 65 | } 66 | 67 | 68 | static int b_or (lua_State *L) { 69 | int i, n = lua_gettop(L); 70 | lua_Unsigned r = 0; 71 | for (i = 1; i <= n; i++) 72 | r |= luaL_checkunsigned(L, i); 73 | lua_pushunsigned(L, trim(r)); 74 | return 1; 75 | } 76 | 77 | 78 | static int b_xor (lua_State *L) { 79 | int i, n = lua_gettop(L); 80 | lua_Unsigned r = 0; 81 | for (i = 1; i <= n; i++) 82 | r ^= luaL_checkunsigned(L, i); 83 | lua_pushunsigned(L, trim(r)); 84 | return 1; 85 | } 86 | 87 | 88 | static int b_not (lua_State *L) { 89 | lua_Unsigned r = ~luaL_checkunsigned(L, 1); 90 | lua_pushunsigned(L, trim(r)); 91 | return 1; 92 | } 93 | 94 | 95 | static int b_shift (lua_State *L, lua_Unsigned r, lua_Integer i) { 96 | if (i < 0) { /* shift right? */ 97 | i = -i; 98 | r = trim(r); 99 | if (i >= LUA_NBITS) r = 0; 100 | else r >>= i; 101 | } 102 | else { /* shift left */ 103 | if (i >= LUA_NBITS) r = 0; 104 | else r <<= i; 105 | r = trim(r); 106 | } 107 | lua_pushunsigned(L, r); 108 | return 1; 109 | } 110 | 111 | 112 | static int b_lshift (lua_State *L) { 113 | return b_shift(L, luaL_checkunsigned(L, 1), luaL_checkinteger(L, 2)); 114 | } 115 | 116 | 117 | static int b_rshift (lua_State *L) { 118 | return b_shift(L, luaL_checkunsigned(L, 1), -luaL_checkinteger(L, 2)); 119 | } 120 | 121 | 122 | static int b_arshift (lua_State *L) { 123 | lua_Unsigned r = luaL_checkunsigned(L, 1); 124 | lua_Integer i = luaL_checkinteger(L, 2); 125 | if (i < 0 || !(r & ((lua_Unsigned)1 << (LUA_NBITS - 1)))) 126 | return b_shift(L, r, -i); 127 | else { /* arithmetic shift for 'negative' number */ 128 | if (i >= LUA_NBITS) r = ALLONES; 129 | else 130 | r = trim((r >> i) | ~(trim(~(lua_Unsigned)0) >> i)); /* add signal bit */ 131 | lua_pushunsigned(L, r); 132 | return 1; 133 | } 134 | } 135 | 136 | 137 | static int b_rot (lua_State *L, lua_Integer d) { 138 | lua_Unsigned r = luaL_checkunsigned(L, 1); 139 | int i = d & (LUA_NBITS - 1); /* i = d % NBITS */ 140 | r = trim(r); 141 | if (i != 0) /* avoid undefined shift of LUA_NBITS when i == 0 */ 142 | r = (r << i) | (r >> (LUA_NBITS - i)); 143 | lua_pushunsigned(L, trim(r)); 144 | return 1; 145 | } 146 | 147 | 148 | static int b_lrot (lua_State *L) { 149 | return b_rot(L, luaL_checkinteger(L, 2)); 150 | } 151 | 152 | 153 | static int b_rrot (lua_State *L) { 154 | return b_rot(L, -luaL_checkinteger(L, 2)); 155 | } 156 | 157 | 158 | /* 159 | ** get field and width arguments for field-manipulation functions, 160 | ** checking whether they are valid. 161 | ** ('luaL_error' called without 'return' to avoid later warnings about 162 | ** 'width' being used uninitialized.) 163 | */ 164 | static int fieldargs (lua_State *L, int farg, int *width) { 165 | lua_Integer f = luaL_checkinteger(L, farg); 166 | lua_Integer w = luaL_optinteger(L, farg + 1, 1); 167 | luaL_argcheck(L, 0 <= f, farg, "field cannot be negative"); 168 | luaL_argcheck(L, 0 < w, farg + 1, "width must be positive"); 169 | if (f + w > LUA_NBITS) 170 | luaL_error(L, "trying to access non-existent bits"); 171 | *width = (int)w; 172 | return (int)f; 173 | } 174 | 175 | 176 | static int b_extract (lua_State *L) { 177 | int w; 178 | lua_Unsigned r = trim(luaL_checkunsigned(L, 1)); 179 | int f = fieldargs(L, 2, &w); 180 | r = (r >> f) & mask(w); 181 | lua_pushunsigned(L, r); 182 | return 1; 183 | } 184 | 185 | 186 | static int b_replace (lua_State *L) { 187 | int w; 188 | lua_Unsigned r = trim(luaL_checkunsigned(L, 1)); 189 | lua_Unsigned v = luaL_checkunsigned(L, 2); 190 | int f = fieldargs(L, 3, &w); 191 | int m = mask(w); 192 | v &= m; /* erase bits outside given width */ 193 | r = (r & ~(m << f)) | (v << f); 194 | lua_pushunsigned(L, r); 195 | return 1; 196 | } 197 | 198 | 199 | static const luaL_Reg bitlib[] = { 200 | {"arshift", b_arshift}, 201 | {"band", b_and}, 202 | {"bnot", b_not}, 203 | {"bor", b_or}, 204 | {"bxor", b_xor}, 205 | {"btest", b_test}, 206 | {"extract", b_extract}, 207 | {"lrotate", b_lrot}, 208 | {"lshift", b_lshift}, 209 | {"replace", b_replace}, 210 | {"rrotate", b_rrot}, 211 | {"rshift", b_rshift}, 212 | {NULL, NULL} 213 | }; 214 | 215 | 216 | 217 | LUAMOD_API int luaopen_bit32 (lua_State *L) { 218 | luaL_newlib(L, bitlib); 219 | return 1; 220 | } 221 | 222 | 223 | #else /* }{ */ 224 | 225 | 226 | LUAMOD_API int luaopen_bit32 (lua_State *L) { 227 | return luaL_error(L, "library 'bit32' has been deprecated"); 228 | } 229 | 230 | #endif /* } */ 231 | -------------------------------------------------------------------------------- /3rd/lua/src/lcode.h: -------------------------------------------------------------------------------- 1 | /* 2 | ** $Id: lcode.h,v 1.63 2013/12/30 20:47:58 roberto Exp $ 3 | ** Code generator for Lua 4 | ** See Copyright Notice in lua.h 5 | */ 6 | 7 | #ifndef lcode_h 8 | #define lcode_h 9 | 10 | #include "llex.h" 11 | #include "lobject.h" 12 | #include "lopcodes.h" 13 | #include "lparser.h" 14 | 15 | 16 | /* 17 | ** Marks the end of a patch list. It is an invalid value both as an absolute 18 | ** address, and as a list link (would link an element to itself). 19 | */ 20 | #define NO_JUMP (-1) 21 | 22 | 23 | /* 24 | ** grep "ORDER OPR" if you change these enums (ORDER OP) 25 | */ 26 | typedef enum BinOpr { 27 | OPR_ADD, OPR_SUB, OPR_MUL, OPR_MOD, OPR_POW, 28 | OPR_DIV, 29 | OPR_IDIV, 30 | OPR_BAND, OPR_BOR, OPR_BXOR, 31 | OPR_SHL, OPR_SHR, 32 | OPR_CONCAT, 33 | OPR_EQ, OPR_LT, OPR_LE, 34 | OPR_NE, OPR_GT, OPR_GE, 35 | OPR_AND, OPR_OR, 36 | OPR_NOBINOPR 37 | } BinOpr; 38 | 39 | 40 | typedef enum UnOpr { OPR_MINUS, OPR_BNOT, OPR_NOT, OPR_LEN, OPR_NOUNOPR } UnOpr; 41 | 42 | 43 | #define getcode(fs,e) ((fs)->f->code[(e)->u.info]) 44 | 45 | #define luaK_codeAsBx(fs,o,A,sBx) luaK_codeABx(fs,o,A,(sBx)+MAXARG_sBx) 46 | 47 | #define luaK_setmultret(fs,e) luaK_setreturns(fs, e, LUA_MULTRET) 48 | 49 | #define luaK_jumpto(fs,t) luaK_patchlist(fs, luaK_jump(fs), t) 50 | 51 | LUAI_FUNC int luaK_codeABx (FuncState *fs, OpCode o, int A, unsigned int Bx); 52 | LUAI_FUNC int luaK_codeABC (FuncState *fs, OpCode o, int A, int B, int C); 53 | LUAI_FUNC int luaK_codek (FuncState *fs, int reg, int k); 54 | LUAI_FUNC void luaK_fixline (FuncState *fs, int line); 55 | LUAI_FUNC void luaK_nil (FuncState *fs, int from, int n); 56 | LUAI_FUNC void luaK_reserveregs (FuncState *fs, int n); 57 | LUAI_FUNC void luaK_checkstack (FuncState *fs, int n); 58 | LUAI_FUNC int luaK_stringK (FuncState *fs, TString *s); 59 | LUAI_FUNC int luaK_intK (FuncState *fs, lua_Integer n); 60 | LUAI_FUNC void luaK_dischargevars (FuncState *fs, expdesc *e); 61 | LUAI_FUNC int luaK_exp2anyreg (FuncState *fs, expdesc *e); 62 | LUAI_FUNC void luaK_exp2anyregup (FuncState *fs, expdesc *e); 63 | LUAI_FUNC void luaK_exp2nextreg (FuncState *fs, expdesc *e); 64 | LUAI_FUNC void luaK_exp2val (FuncState *fs, expdesc *e); 65 | LUAI_FUNC int luaK_exp2RK (FuncState *fs, expdesc *e); 66 | LUAI_FUNC void luaK_self (FuncState *fs, expdesc *e, expdesc *key); 67 | LUAI_FUNC void luaK_indexed (FuncState *fs, expdesc *t, expdesc *k); 68 | LUAI_FUNC void luaK_goiftrue (FuncState *fs, expdesc *e); 69 | LUAI_FUNC void luaK_goiffalse (FuncState *fs, expdesc *e); 70 | LUAI_FUNC void luaK_storevar (FuncState *fs, expdesc *var, expdesc *e); 71 | LUAI_FUNC void luaK_setreturns (FuncState *fs, expdesc *e, int nresults); 72 | LUAI_FUNC void luaK_setoneret (FuncState *fs, expdesc *e); 73 | LUAI_FUNC int luaK_jump (FuncState *fs); 74 | LUAI_FUNC void luaK_ret (FuncState *fs, int first, int nret); 75 | LUAI_FUNC void luaK_patchlist (FuncState *fs, int list, int target); 76 | LUAI_FUNC void luaK_patchtohere (FuncState *fs, int list); 77 | LUAI_FUNC void luaK_patchclose (FuncState *fs, int list, int level); 78 | LUAI_FUNC void luaK_concat (FuncState *fs, int *l1, int l2); 79 | LUAI_FUNC int luaK_getlabel (FuncState *fs); 80 | LUAI_FUNC void luaK_prefix (FuncState *fs, UnOpr op, expdesc *v, int line); 81 | LUAI_FUNC void luaK_infix (FuncState *fs, BinOpr op, expdesc *v); 82 | LUAI_FUNC void luaK_posfix (FuncState *fs, BinOpr op, expdesc *v1, 83 | expdesc *v2, int line); 84 | LUAI_FUNC void luaK_setlist (FuncState *fs, int base, int nelems, int tostore); 85 | 86 | 87 | #endif 88 | -------------------------------------------------------------------------------- /3rd/lua/src/lcorolib.c: -------------------------------------------------------------------------------- 1 | /* 2 | ** $Id: lcorolib.c,v 1.9 2014/11/02 19:19:04 roberto Exp $ 3 | ** Coroutine Library 4 | ** See Copyright Notice in lua.h 5 | */ 6 | 7 | #define lcorolib_c 8 | #define LUA_LIB 9 | 10 | #include "lprefix.h" 11 | 12 | 13 | #include 14 | 15 | #include "lua.h" 16 | 17 | #include "lauxlib.h" 18 | #include "lualib.h" 19 | 20 | 21 | static lua_State *getco (lua_State *L) { 22 | lua_State *co = lua_tothread(L, 1); 23 | luaL_argcheck(L, co, 1, "thread expected"); 24 | return co; 25 | } 26 | 27 | 28 | static int auxresume (lua_State *L, lua_State *co, int narg) { 29 | int status; 30 | if (!lua_checkstack(co, narg)) { 31 | lua_pushliteral(L, "too many arguments to resume"); 32 | return -1; /* error flag */ 33 | } 34 | if (lua_status(co) == LUA_OK && lua_gettop(co) == 0) { 35 | lua_pushliteral(L, "cannot resume dead coroutine"); 36 | return -1; /* error flag */ 37 | } 38 | lua_xmove(L, co, narg); 39 | status = lua_resume(co, L, narg); 40 | if (status == LUA_OK || status == LUA_YIELD) { 41 | int nres = lua_gettop(co); 42 | if (!lua_checkstack(L, nres + 1)) { 43 | lua_pop(co, nres); /* remove results anyway */ 44 | lua_pushliteral(L, "too many results to resume"); 45 | return -1; /* error flag */ 46 | } 47 | lua_xmove(co, L, nres); /* move yielded values */ 48 | return nres; 49 | } 50 | else { 51 | lua_xmove(co, L, 1); /* move error message */ 52 | return -1; /* error flag */ 53 | } 54 | } 55 | 56 | 57 | static int luaB_coresume (lua_State *L) { 58 | lua_State *co = getco(L); 59 | int r; 60 | r = auxresume(L, co, lua_gettop(L) - 1); 61 | if (r < 0) { 62 | lua_pushboolean(L, 0); 63 | lua_insert(L, -2); 64 | return 2; /* return false + error message */ 65 | } 66 | else { 67 | lua_pushboolean(L, 1); 68 | lua_insert(L, -(r + 1)); 69 | return r + 1; /* return true + 'resume' returns */ 70 | } 71 | } 72 | 73 | 74 | static int luaB_auxwrap (lua_State *L) { 75 | lua_State *co = lua_tothread(L, lua_upvalueindex(1)); 76 | int r = auxresume(L, co, lua_gettop(L)); 77 | if (r < 0) { 78 | if (lua_isstring(L, -1)) { /* error object is a string? */ 79 | luaL_where(L, 1); /* add extra info */ 80 | lua_insert(L, -2); 81 | lua_concat(L, 2); 82 | } 83 | return lua_error(L); /* propagate error */ 84 | } 85 | return r; 86 | } 87 | 88 | 89 | static int luaB_cocreate (lua_State *L) { 90 | lua_State *NL; 91 | luaL_checktype(L, 1, LUA_TFUNCTION); 92 | NL = lua_newthread(L); 93 | lua_pushvalue(L, 1); /* move function to top */ 94 | lua_xmove(L, NL, 1); /* move function from L to NL */ 95 | return 1; 96 | } 97 | 98 | 99 | static int luaB_cowrap (lua_State *L) { 100 | luaB_cocreate(L); 101 | lua_pushcclosure(L, luaB_auxwrap, 1); 102 | return 1; 103 | } 104 | 105 | 106 | static int luaB_yield (lua_State *L) { 107 | return lua_yield(L, lua_gettop(L)); 108 | } 109 | 110 | 111 | static int luaB_costatus (lua_State *L) { 112 | lua_State *co = getco(L); 113 | if (L == co) lua_pushliteral(L, "running"); 114 | else { 115 | switch (lua_status(co)) { 116 | case LUA_YIELD: 117 | lua_pushliteral(L, "suspended"); 118 | break; 119 | case LUA_OK: { 120 | lua_Debug ar; 121 | if (lua_getstack(co, 0, &ar) > 0) /* does it have frames? */ 122 | lua_pushliteral(L, "normal"); /* it is running */ 123 | else if (lua_gettop(co) == 0) 124 | lua_pushliteral(L, "dead"); 125 | else 126 | lua_pushliteral(L, "suspended"); /* initial state */ 127 | break; 128 | } 129 | default: /* some error occurred */ 130 | lua_pushliteral(L, "dead"); 131 | break; 132 | } 133 | } 134 | return 1; 135 | } 136 | 137 | 138 | static int luaB_yieldable (lua_State *L) { 139 | lua_pushboolean(L, lua_isyieldable(L)); 140 | return 1; 141 | } 142 | 143 | 144 | static int luaB_corunning (lua_State *L) { 145 | int ismain = lua_pushthread(L); 146 | lua_pushboolean(L, ismain); 147 | return 2; 148 | } 149 | 150 | 151 | static const luaL_Reg co_funcs[] = { 152 | {"create", luaB_cocreate}, 153 | {"resume", luaB_coresume}, 154 | {"running", luaB_corunning}, 155 | {"status", luaB_costatus}, 156 | {"wrap", luaB_cowrap}, 157 | {"yield", luaB_yield}, 158 | {"isyieldable", luaB_yieldable}, 159 | {NULL, NULL} 160 | }; 161 | 162 | 163 | 164 | LUAMOD_API int luaopen_coroutine (lua_State *L) { 165 | luaL_newlib(L, co_funcs); 166 | return 1; 167 | } 168 | 169 | -------------------------------------------------------------------------------- /3rd/lua/src/lctype.c: -------------------------------------------------------------------------------- 1 | /* 2 | ** $Id: lctype.c,v 1.12 2014/11/02 19:19:04 roberto Exp $ 3 | ** 'ctype' functions for Lua 4 | ** See Copyright Notice in lua.h 5 | */ 6 | 7 | #define lctype_c 8 | #define LUA_CORE 9 | 10 | #include "lprefix.h" 11 | 12 | 13 | #include "lctype.h" 14 | 15 | #if !LUA_USE_CTYPE /* { */ 16 | 17 | #include 18 | 19 | LUAI_DDEF const lu_byte luai_ctype_[UCHAR_MAX + 2] = { 20 | 0x00, /* EOZ */ 21 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0. */ 22 | 0x00, 0x08, 0x08, 0x08, 0x08, 0x08, 0x00, 0x00, 23 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 1. */ 24 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 25 | 0x0c, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, /* 2. */ 26 | 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 27 | 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, /* 3. */ 28 | 0x16, 0x16, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 29 | 0x04, 0x15, 0x15, 0x15, 0x15, 0x15, 0x15, 0x05, /* 4. */ 30 | 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 31 | 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, /* 5. */ 32 | 0x05, 0x05, 0x05, 0x04, 0x04, 0x04, 0x04, 0x05, 33 | 0x04, 0x15, 0x15, 0x15, 0x15, 0x15, 0x15, 0x05, /* 6. */ 34 | 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 35 | 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, /* 7. */ 36 | 0x05, 0x05, 0x05, 0x04, 0x04, 0x04, 0x04, 0x00, 37 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 8. */ 38 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 39 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 9. */ 40 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 41 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* a. */ 42 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 43 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* b. */ 44 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 45 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* c. */ 46 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 47 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* d. */ 48 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 49 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* e. */ 50 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 51 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* f. */ 52 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 53 | }; 54 | 55 | #endif /* } */ 56 | -------------------------------------------------------------------------------- /3rd/lua/src/lctype.h: -------------------------------------------------------------------------------- 1 | /* 2 | ** $Id: lctype.h,v 1.12 2011/07/15 12:50:29 roberto Exp $ 3 | ** 'ctype' functions for Lua 4 | ** See Copyright Notice in lua.h 5 | */ 6 | 7 | #ifndef lctype_h 8 | #define lctype_h 9 | 10 | #include "lua.h" 11 | 12 | 13 | /* 14 | ** WARNING: the functions defined here do not necessarily correspond 15 | ** to the similar functions in the standard C ctype.h. They are 16 | ** optimized for the specific needs of Lua 17 | */ 18 | 19 | #if !defined(LUA_USE_CTYPE) 20 | 21 | #if 'A' == 65 && '0' == 48 22 | /* ASCII case: can use its own tables; faster and fixed */ 23 | #define LUA_USE_CTYPE 0 24 | #else 25 | /* must use standard C ctype */ 26 | #define LUA_USE_CTYPE 1 27 | #endif 28 | 29 | #endif 30 | 31 | 32 | #if !LUA_USE_CTYPE /* { */ 33 | 34 | #include 35 | 36 | #include "llimits.h" 37 | 38 | 39 | #define ALPHABIT 0 40 | #define DIGITBIT 1 41 | #define PRINTBIT 2 42 | #define SPACEBIT 3 43 | #define XDIGITBIT 4 44 | 45 | 46 | #define MASK(B) (1 << (B)) 47 | 48 | 49 | /* 50 | ** add 1 to char to allow index -1 (EOZ) 51 | */ 52 | #define testprop(c,p) (luai_ctype_[(c)+1] & (p)) 53 | 54 | /* 55 | ** 'lalpha' (Lua alphabetic) and 'lalnum' (Lua alphanumeric) both include '_' 56 | */ 57 | #define lislalpha(c) testprop(c, MASK(ALPHABIT)) 58 | #define lislalnum(c) testprop(c, (MASK(ALPHABIT) | MASK(DIGITBIT))) 59 | #define lisdigit(c) testprop(c, MASK(DIGITBIT)) 60 | #define lisspace(c) testprop(c, MASK(SPACEBIT)) 61 | #define lisprint(c) testprop(c, MASK(PRINTBIT)) 62 | #define lisxdigit(c) testprop(c, MASK(XDIGITBIT)) 63 | 64 | /* 65 | ** this 'ltolower' only works for alphabetic characters 66 | */ 67 | #define ltolower(c) ((c) | ('A' ^ 'a')) 68 | 69 | 70 | /* two more entries for 0 and -1 (EOZ) */ 71 | LUAI_DDEC const lu_byte luai_ctype_[UCHAR_MAX + 2]; 72 | 73 | 74 | #else /* }{ */ 75 | 76 | /* 77 | ** use standard C ctypes 78 | */ 79 | 80 | #include 81 | 82 | 83 | #define lislalpha(c) (isalpha(c) || (c) == '_') 84 | #define lislalnum(c) (isalnum(c) || (c) == '_') 85 | #define lisdigit(c) (isdigit(c)) 86 | #define lisspace(c) (isspace(c)) 87 | #define lisprint(c) (isprint(c)) 88 | #define lisxdigit(c) (isxdigit(c)) 89 | 90 | #define ltolower(c) (tolower(c)) 91 | 92 | #endif /* } */ 93 | 94 | #endif 95 | 96 | -------------------------------------------------------------------------------- /3rd/lua/src/ldebug.h: -------------------------------------------------------------------------------- 1 | /* 2 | ** $Id: ldebug.h,v 2.12 2014/11/10 14:46:05 roberto Exp $ 3 | ** Auxiliary functions from Debug Interface module 4 | ** See Copyright Notice in lua.h 5 | */ 6 | 7 | #ifndef ldebug_h 8 | #define ldebug_h 9 | 10 | 11 | #include "lstate.h" 12 | 13 | 14 | #define pcRel(pc, p) (cast(int, (pc) - (p)->code) - 1) 15 | 16 | #define getfuncline(f,pc) (((f)->lineinfo) ? (f)->lineinfo[pc] : -1) 17 | 18 | #define resethookcount(L) (L->hookcount = L->basehookcount) 19 | 20 | /* Active Lua function (given call info) */ 21 | #define ci_func(ci) (clLvalue((ci)->func)) 22 | 23 | 24 | LUAI_FUNC l_noret luaG_typeerror (lua_State *L, const TValue *o, 25 | const char *opname); 26 | LUAI_FUNC l_noret luaG_concaterror (lua_State *L, const TValue *p1, 27 | const TValue *p2); 28 | LUAI_FUNC l_noret luaG_opinterror (lua_State *L, const TValue *p1, 29 | const TValue *p2, 30 | const char *msg); 31 | LUAI_FUNC l_noret luaG_tointerror (lua_State *L, const TValue *p1, 32 | const TValue *p2); 33 | LUAI_FUNC l_noret luaG_ordererror (lua_State *L, const TValue *p1, 34 | const TValue *p2); 35 | LUAI_FUNC l_noret luaG_runerror (lua_State *L, const char *fmt, ...); 36 | LUAI_FUNC l_noret luaG_errormsg (lua_State *L); 37 | LUAI_FUNC void luaG_traceexec (lua_State *L); 38 | 39 | 40 | #endif 41 | -------------------------------------------------------------------------------- /3rd/lua/src/ldo.h: -------------------------------------------------------------------------------- 1 | /* 2 | ** $Id: ldo.h,v 2.21 2014/10/25 11:50:46 roberto Exp $ 3 | ** Stack and Call structure of Lua 4 | ** See Copyright Notice in lua.h 5 | */ 6 | 7 | #ifndef ldo_h 8 | #define ldo_h 9 | 10 | 11 | #include "lobject.h" 12 | #include "lstate.h" 13 | #include "lzio.h" 14 | 15 | 16 | #define luaD_checkstack(L,n) if (L->stack_last - L->top <= (n)) \ 17 | luaD_growstack(L, n); else condmovestack(L); 18 | 19 | 20 | #define incr_top(L) {L->top++; luaD_checkstack(L,0);} 21 | 22 | #define savestack(L,p) ((char *)(p) - (char *)L->stack) 23 | #define restorestack(L,n) ((TValue *)((char *)L->stack + (n))) 24 | 25 | 26 | /* type of protected functions, to be ran by 'runprotected' */ 27 | typedef void (*Pfunc) (lua_State *L, void *ud); 28 | 29 | LUAI_FUNC int luaD_protectedparser (lua_State *L, ZIO *z, const char *name, 30 | const char *mode); 31 | LUAI_FUNC void luaD_hook (lua_State *L, int event, int line); 32 | LUAI_FUNC int luaD_precall (lua_State *L, StkId func, int nresults); 33 | LUAI_FUNC void luaD_call (lua_State *L, StkId func, int nResults, 34 | int allowyield); 35 | LUAI_FUNC int luaD_pcall (lua_State *L, Pfunc func, void *u, 36 | ptrdiff_t oldtop, ptrdiff_t ef); 37 | LUAI_FUNC int luaD_poscall (lua_State *L, StkId firstResult); 38 | LUAI_FUNC void luaD_reallocstack (lua_State *L, int newsize); 39 | LUAI_FUNC void luaD_growstack (lua_State *L, int n); 40 | LUAI_FUNC void luaD_shrinkstack (lua_State *L); 41 | 42 | LUAI_FUNC l_noret luaD_throw (lua_State *L, int errcode); 43 | LUAI_FUNC int luaD_rawrunprotected (lua_State *L, Pfunc f, void *ud); 44 | 45 | #endif 46 | 47 | -------------------------------------------------------------------------------- /3rd/lua/src/ldump.c: -------------------------------------------------------------------------------- 1 | /* 2 | ** $Id: ldump.c,v 2.34 2014/11/02 19:19:04 roberto Exp $ 3 | ** save precompiled Lua chunks 4 | ** See Copyright Notice in lua.h 5 | */ 6 | 7 | #define ldump_c 8 | #define LUA_CORE 9 | 10 | #include "lprefix.h" 11 | 12 | 13 | #include 14 | 15 | #include "lua.h" 16 | 17 | #include "lobject.h" 18 | #include "lstate.h" 19 | #include "lundump.h" 20 | 21 | 22 | typedef struct { 23 | lua_State *L; 24 | lua_Writer writer; 25 | void *data; 26 | int strip; 27 | int status; 28 | } DumpState; 29 | 30 | 31 | /* 32 | ** All high-level dumps go through DumpVector; you can change it to 33 | ** change the endianness of the result 34 | */ 35 | #define DumpVector(v,n,D) DumpBlock(v,(n)*sizeof((v)[0]),D) 36 | 37 | #define DumpLiteral(s,D) DumpBlock(s, sizeof(s) - sizeof(char), D) 38 | 39 | 40 | static void DumpBlock (const void *b, size_t size, DumpState *D) { 41 | if (D->status == 0) { 42 | lua_unlock(D->L); 43 | D->status = (*D->writer)(D->L, b, size, D->data); 44 | lua_lock(D->L); 45 | } 46 | } 47 | 48 | 49 | #define DumpVar(x,D) DumpVector(&x,1,D) 50 | 51 | 52 | static void DumpByte (int y, DumpState *D) { 53 | lu_byte x = (lu_byte)y; 54 | DumpVar(x, D); 55 | } 56 | 57 | 58 | static void DumpInt (int x, DumpState *D) { 59 | DumpVar(x, D); 60 | } 61 | 62 | 63 | static void DumpNumber (lua_Number x, DumpState *D) { 64 | DumpVar(x, D); 65 | } 66 | 67 | 68 | static void DumpInteger (lua_Integer x, DumpState *D) { 69 | DumpVar(x, D); 70 | } 71 | 72 | 73 | static void DumpString (const TString *s, DumpState *D) { 74 | if (s == NULL) 75 | DumpByte(0, D); 76 | else { 77 | size_t size = s->len + 1; /* include trailing '\0' */ 78 | if (size < 0xFF) 79 | DumpByte(cast_int(size), D); 80 | else { 81 | DumpByte(0xFF, D); 82 | DumpVar(size, D); 83 | } 84 | DumpVector(getstr(s), size - 1, D); /* no need to save '\0' */ 85 | } 86 | } 87 | 88 | 89 | static void DumpCode (const Proto *f, DumpState *D) { 90 | DumpInt(f->sizecode, D); 91 | DumpVector(f->code, f->sizecode, D); 92 | } 93 | 94 | 95 | static void DumpFunction(const Proto *f, TString *psource, DumpState *D); 96 | 97 | static void DumpConstants (const Proto *f, DumpState *D) { 98 | int i; 99 | int n = f->sizek; 100 | DumpInt(n, D); 101 | for (i = 0; i < n; i++) { 102 | const TValue *o = &f->k[i]; 103 | DumpByte(ttype(o), D); 104 | switch (ttype(o)) { 105 | case LUA_TNIL: 106 | break; 107 | case LUA_TBOOLEAN: 108 | DumpByte(bvalue(o), D); 109 | break; 110 | case LUA_TNUMFLT: 111 | DumpNumber(fltvalue(o), D); 112 | break; 113 | case LUA_TNUMINT: 114 | DumpInteger(ivalue(o), D); 115 | break; 116 | case LUA_TSHRSTR: 117 | case LUA_TLNGSTR: 118 | DumpString(tsvalue(o), D); 119 | break; 120 | default: 121 | lua_assert(0); 122 | } 123 | } 124 | } 125 | 126 | 127 | static void DumpProtos (const Proto *f, DumpState *D) { 128 | int i; 129 | int n = f->sizep; 130 | DumpInt(n, D); 131 | for (i = 0; i < n; i++) 132 | DumpFunction(f->p[i], f->source, D); 133 | } 134 | 135 | 136 | static void DumpUpvalues (const Proto *f, DumpState *D) { 137 | int i, n = f->sizeupvalues; 138 | DumpInt(n, D); 139 | for (i = 0; i < n; i++) { 140 | DumpByte(f->upvalues[i].instack, D); 141 | DumpByte(f->upvalues[i].idx, D); 142 | } 143 | } 144 | 145 | 146 | static void DumpDebug (const Proto *f, DumpState *D) { 147 | int i, n; 148 | n = (D->strip) ? 0 : f->sizelineinfo; 149 | DumpInt(n, D); 150 | DumpVector(f->lineinfo, n, D); 151 | n = (D->strip) ? 0 : f->sizelocvars; 152 | DumpInt(n, D); 153 | for (i = 0; i < n; i++) { 154 | DumpString(f->locvars[i].varname, D); 155 | DumpInt(f->locvars[i].startpc, D); 156 | DumpInt(f->locvars[i].endpc, D); 157 | } 158 | n = (D->strip) ? 0 : f->sizeupvalues; 159 | DumpInt(n, D); 160 | for (i = 0; i < n; i++) 161 | DumpString(f->upvalues[i].name, D); 162 | } 163 | 164 | 165 | static void DumpFunction (const Proto *f, TString *psource, DumpState *D) { 166 | if (D->strip || f->source == psource) 167 | DumpString(NULL, D); /* no debug info or same source as its parent */ 168 | else 169 | DumpString(f->source, D); 170 | DumpInt(f->linedefined, D); 171 | DumpInt(f->lastlinedefined, D); 172 | DumpByte(f->numparams, D); 173 | DumpByte(f->is_vararg, D); 174 | DumpByte(f->maxstacksize, D); 175 | DumpCode(f, D); 176 | DumpConstants(f, D); 177 | DumpUpvalues(f, D); 178 | DumpProtos(f, D); 179 | DumpDebug(f, D); 180 | } 181 | 182 | 183 | static void DumpHeader (DumpState *D) { 184 | DumpLiteral(LUA_SIGNATURE, D); 185 | DumpByte(LUAC_VERSION, D); 186 | DumpByte(LUAC_FORMAT, D); 187 | DumpLiteral(LUAC_DATA, D); 188 | DumpByte(sizeof(int), D); 189 | DumpByte(sizeof(size_t), D); 190 | DumpByte(sizeof(Instruction), D); 191 | DumpByte(sizeof(lua_Integer), D); 192 | DumpByte(sizeof(lua_Number), D); 193 | DumpInteger(LUAC_INT, D); 194 | DumpNumber(LUAC_NUM, D); 195 | } 196 | 197 | 198 | /* 199 | ** dump Lua function as precompiled chunk 200 | */ 201 | int luaU_dump(lua_State *L, const Proto *f, lua_Writer w, void *data, 202 | int strip) { 203 | DumpState D; 204 | D.L = L; 205 | D.writer = w; 206 | D.data = data; 207 | D.strip = strip; 208 | D.status = 0; 209 | DumpHeader(&D); 210 | DumpByte(f->sizeupvalues, &D); 211 | DumpFunction(f, NULL, &D); 212 | return D.status; 213 | } 214 | 215 | -------------------------------------------------------------------------------- /3rd/lua/src/lfunc.c: -------------------------------------------------------------------------------- 1 | /* 2 | ** $Id: lfunc.c,v 2.45 2014/11/02 19:19:04 roberto Exp $ 3 | ** Auxiliary functions to manipulate prototypes and closures 4 | ** See Copyright Notice in lua.h 5 | */ 6 | 7 | #define lfunc_c 8 | #define LUA_CORE 9 | 10 | #include "lprefix.h" 11 | 12 | 13 | #include 14 | 15 | #include "lua.h" 16 | 17 | #include "lfunc.h" 18 | #include "lgc.h" 19 | #include "lmem.h" 20 | #include "lobject.h" 21 | #include "lstate.h" 22 | 23 | 24 | 25 | CClosure *luaF_newCclosure (lua_State *L, int n) { 26 | GCObject *o = luaC_newobj(L, LUA_TCCL, sizeCclosure(n)); 27 | CClosure *c = gco2ccl(o); 28 | c->nupvalues = cast_byte(n); 29 | return c; 30 | } 31 | 32 | 33 | LClosure *luaF_newLclosure (lua_State *L, int n) { 34 | GCObject *o = luaC_newobj(L, LUA_TLCL, sizeLclosure(n)); 35 | LClosure *c = gco2lcl(o); 36 | c->p = NULL; 37 | c->nupvalues = cast_byte(n); 38 | while (n--) c->upvals[n] = NULL; 39 | return c; 40 | } 41 | 42 | /* 43 | ** fill a closure with new closed upvalues 44 | */ 45 | void luaF_initupvals (lua_State *L, LClosure *cl) { 46 | int i; 47 | for (i = 0; i < cl->nupvalues; i++) { 48 | UpVal *uv = luaM_new(L, UpVal); 49 | uv->refcount = 1; 50 | uv->v = &uv->u.value; /* make it closed */ 51 | setnilvalue(uv->v); 52 | cl->upvals[i] = uv; 53 | } 54 | } 55 | 56 | 57 | UpVal *luaF_findupval (lua_State *L, StkId level) { 58 | UpVal **pp = &L->openupval; 59 | UpVal *p; 60 | UpVal *uv; 61 | lua_assert(isintwups(L) || L->openupval == NULL); 62 | while (*pp != NULL && (p = *pp)->v >= level) { 63 | lua_assert(upisopen(p)); 64 | if (p->v == level) /* found a corresponding upvalue? */ 65 | return p; /* return it */ 66 | pp = &p->u.open.next; 67 | } 68 | /* not found: create a new upvalue */ 69 | uv = luaM_new(L, UpVal); 70 | uv->refcount = 0; 71 | uv->u.open.next = *pp; /* link it to list of open upvalues */ 72 | uv->u.open.touched = 1; 73 | *pp = uv; 74 | uv->v = level; /* current value lives in the stack */ 75 | if (!isintwups(L)) { /* thread not in list of threads with upvalues? */ 76 | L->twups = G(L)->twups; /* link it to the list */ 77 | G(L)->twups = L; 78 | } 79 | return uv; 80 | } 81 | 82 | 83 | void luaF_close (lua_State *L, StkId level) { 84 | UpVal *uv; 85 | while (L->openupval != NULL && (uv = L->openupval)->v >= level) { 86 | lua_assert(upisopen(uv)); 87 | L->openupval = uv->u.open.next; /* remove from 'open' list */ 88 | if (uv->refcount == 0) /* no references? */ 89 | luaM_free(L, uv); /* free upvalue */ 90 | else { 91 | setobj(L, &uv->u.value, uv->v); /* move value to upvalue slot */ 92 | uv->v = &uv->u.value; /* now current value lives here */ 93 | luaC_upvalbarrier(L, uv); 94 | } 95 | } 96 | } 97 | 98 | 99 | Proto *luaF_newproto (lua_State *L) { 100 | GCObject *o = luaC_newobj(L, LUA_TPROTO, sizeof(Proto)); 101 | Proto *f = gco2p(o); 102 | f->k = NULL; 103 | f->sizek = 0; 104 | f->p = NULL; 105 | f->sizep = 0; 106 | f->code = NULL; 107 | f->cache = NULL; 108 | f->sizecode = 0; 109 | f->lineinfo = NULL; 110 | f->sizelineinfo = 0; 111 | f->upvalues = NULL; 112 | f->sizeupvalues = 0; 113 | f->numparams = 0; 114 | f->is_vararg = 0; 115 | f->maxstacksize = 0; 116 | f->locvars = NULL; 117 | f->sizelocvars = 0; 118 | f->linedefined = 0; 119 | f->lastlinedefined = 0; 120 | f->source = NULL; 121 | return f; 122 | } 123 | 124 | 125 | void luaF_freeproto (lua_State *L, Proto *f) { 126 | luaM_freearray(L, f->code, f->sizecode); 127 | luaM_freearray(L, f->p, f->sizep); 128 | luaM_freearray(L, f->k, f->sizek); 129 | luaM_freearray(L, f->lineinfo, f->sizelineinfo); 130 | luaM_freearray(L, f->locvars, f->sizelocvars); 131 | luaM_freearray(L, f->upvalues, f->sizeupvalues); 132 | luaM_free(L, f); 133 | } 134 | 135 | 136 | /* 137 | ** Look for n-th local variable at line 'line' in function 'func'. 138 | ** Returns NULL if not found. 139 | */ 140 | const char *luaF_getlocalname (const Proto *f, int local_number, int pc) { 141 | int i; 142 | for (i = 0; isizelocvars && f->locvars[i].startpc <= pc; i++) { 143 | if (pc < f->locvars[i].endpc) { /* is variable active? */ 144 | local_number--; 145 | if (local_number == 0) 146 | return getstr(f->locvars[i].varname); 147 | } 148 | } 149 | return NULL; /* not found */ 150 | } 151 | 152 | -------------------------------------------------------------------------------- /3rd/lua/src/lfunc.h: -------------------------------------------------------------------------------- 1 | /* 2 | ** $Id: lfunc.h,v 2.14 2014/06/19 18:27:20 roberto Exp $ 3 | ** Auxiliary functions to manipulate prototypes and closures 4 | ** See Copyright Notice in lua.h 5 | */ 6 | 7 | #ifndef lfunc_h 8 | #define lfunc_h 9 | 10 | 11 | #include "lobject.h" 12 | 13 | 14 | #define sizeCclosure(n) (cast(int, sizeof(CClosure)) + \ 15 | cast(int, sizeof(TValue)*((n)-1))) 16 | 17 | #define sizeLclosure(n) (cast(int, sizeof(LClosure)) + \ 18 | cast(int, sizeof(TValue *)*((n)-1))) 19 | 20 | 21 | /* test whether thread is in 'twups' list */ 22 | #define isintwups(L) (L->twups != L) 23 | 24 | 25 | /* 26 | ** Upvalues for Lua closures 27 | */ 28 | struct UpVal { 29 | TValue *v; /* points to stack or to its own value */ 30 | lu_mem refcount; /* reference counter */ 31 | union { 32 | struct { /* (when open) */ 33 | UpVal *next; /* linked list */ 34 | int touched; /* mark to avoid cycles with dead threads */ 35 | } open; 36 | TValue value; /* the value (when closed) */ 37 | } u; 38 | }; 39 | 40 | #define upisopen(up) ((up)->v != &(up)->u.value) 41 | 42 | 43 | LUAI_FUNC Proto *luaF_newproto (lua_State *L); 44 | LUAI_FUNC CClosure *luaF_newCclosure (lua_State *L, int nelems); 45 | LUAI_FUNC LClosure *luaF_newLclosure (lua_State *L, int nelems); 46 | LUAI_FUNC void luaF_initupvals (lua_State *L, LClosure *cl); 47 | LUAI_FUNC UpVal *luaF_findupval (lua_State *L, StkId level); 48 | LUAI_FUNC void luaF_close (lua_State *L, StkId level); 49 | LUAI_FUNC void luaF_freeproto (lua_State *L, Proto *f); 50 | LUAI_FUNC const char *luaF_getlocalname (const Proto *func, int local_number, 51 | int pc); 52 | 53 | 54 | #endif 55 | -------------------------------------------------------------------------------- /3rd/lua/src/lgc.h: -------------------------------------------------------------------------------- 1 | /* 2 | ** $Id: lgc.h,v 2.86 2014/10/25 11:50:46 roberto Exp $ 3 | ** Garbage Collector 4 | ** See Copyright Notice in lua.h 5 | */ 6 | 7 | #ifndef lgc_h 8 | #define lgc_h 9 | 10 | 11 | #include "lobject.h" 12 | #include "lstate.h" 13 | 14 | /* 15 | ** Collectable objects may have one of three colors: white, which 16 | ** means the object is not marked; gray, which means the 17 | ** object is marked, but its references may be not marked; and 18 | ** black, which means that the object and all its references are marked. 19 | ** The main invariant of the garbage collector, while marking objects, 20 | ** is that a black object can never point to a white one. Moreover, 21 | ** any gray object must be in a "gray list" (gray, grayagain, weak, 22 | ** allweak, ephemeron) so that it can be visited again before finishing 23 | ** the collection cycle. These lists have no meaning when the invariant 24 | ** is not being enforced (e.g., sweep phase). 25 | */ 26 | 27 | 28 | 29 | /* how much to allocate before next GC step */ 30 | #if !defined(GCSTEPSIZE) 31 | /* ~100 small strings */ 32 | #define GCSTEPSIZE (cast_int(100 * sizeof(TString))) 33 | #endif 34 | 35 | 36 | /* 37 | ** Possible states of the Garbage Collector 38 | */ 39 | #define GCSpropagate 0 40 | #define GCSatomic 1 41 | #define GCSswpallgc 2 42 | #define GCSswpfinobj 3 43 | #define GCSswptobefnz 4 44 | #define GCSswpend 5 45 | #define GCScallfin 6 46 | #define GCSpause 7 47 | 48 | 49 | #define issweepphase(g) \ 50 | (GCSswpallgc <= (g)->gcstate && (g)->gcstate <= GCSswpend) 51 | 52 | 53 | /* 54 | ** macro to tell when main invariant (white objects cannot point to black 55 | ** ones) must be kept. During a collection, the sweep 56 | ** phase may break the invariant, as objects turned white may point to 57 | ** still-black objects. The invariant is restored when sweep ends and 58 | ** all objects are white again. 59 | */ 60 | 61 | #define keepinvariant(g) ((g)->gcstate <= GCSatomic) 62 | 63 | 64 | /* 65 | ** some useful bit tricks 66 | */ 67 | #define resetbits(x,m) ((x) &= cast(lu_byte, ~(m))) 68 | #define setbits(x,m) ((x) |= (m)) 69 | #define testbits(x,m) ((x) & (m)) 70 | #define bitmask(b) (1<<(b)) 71 | #define bit2mask(b1,b2) (bitmask(b1) | bitmask(b2)) 72 | #define l_setbit(x,b) setbits(x, bitmask(b)) 73 | #define resetbit(x,b) resetbits(x, bitmask(b)) 74 | #define testbit(x,b) testbits(x, bitmask(b)) 75 | 76 | 77 | /* Layout for bit use in 'marked' field: */ 78 | #define WHITE0BIT 0 /* object is white (type 0) */ 79 | #define WHITE1BIT 1 /* object is white (type 1) */ 80 | #define BLACKBIT 2 /* object is black */ 81 | #define FINALIZEDBIT 3 /* object has been marked for finalization */ 82 | /* bit 7 is currently used by tests (luaL_checkmemory) */ 83 | 84 | #define WHITEBITS bit2mask(WHITE0BIT, WHITE1BIT) 85 | 86 | 87 | #define iswhite(x) testbits((x)->marked, WHITEBITS) 88 | #define isblack(x) testbit((x)->marked, BLACKBIT) 89 | #define isgray(x) /* neither white nor black */ \ 90 | (!testbits((x)->marked, WHITEBITS | bitmask(BLACKBIT))) 91 | 92 | #define tofinalize(x) testbit((x)->marked, FINALIZEDBIT) 93 | 94 | #define otherwhite(g) ((g)->currentwhite ^ WHITEBITS) 95 | #define isdeadm(ow,m) (!(((m) ^ WHITEBITS) & (ow))) 96 | #define isdead(g,v) isdeadm(otherwhite(g), (v)->marked) 97 | 98 | #define changewhite(x) ((x)->marked ^= WHITEBITS) 99 | #define gray2black(x) l_setbit((x)->marked, BLACKBIT) 100 | 101 | #define luaC_white(g) cast(lu_byte, (g)->currentwhite & WHITEBITS) 102 | 103 | 104 | #define luaC_condGC(L,c) \ 105 | {if (G(L)->GCdebt > 0) {c;}; condchangemem(L);} 106 | #define luaC_checkGC(L) luaC_condGC(L, luaC_step(L);) 107 | 108 | 109 | #define luaC_barrier(L,p,v) { \ 110 | if (iscollectable(v) && isblack(p) && iswhite(gcvalue(v))) \ 111 | luaC_barrier_(L,obj2gco(p),gcvalue(v)); } 112 | 113 | #define luaC_barrierback(L,p,v) { \ 114 | if (iscollectable(v) && isblack(p) && iswhite(gcvalue(v))) \ 115 | luaC_barrierback_(L,p); } 116 | 117 | #define luaC_objbarrier(L,p,o) { \ 118 | if (isblack(p) && iswhite(o)) \ 119 | luaC_barrier_(L,obj2gco(p),obj2gco(o)); } 120 | 121 | #define luaC_upvalbarrier(L,uv) \ 122 | { if (iscollectable((uv)->v) && !upisopen(uv)) \ 123 | luaC_upvalbarrier_(L,uv); } 124 | 125 | LUAI_FUNC void luaC_fix (lua_State *L, GCObject *o); 126 | LUAI_FUNC void luaC_freeallobjects (lua_State *L); 127 | LUAI_FUNC void luaC_step (lua_State *L); 128 | LUAI_FUNC void luaC_runtilstate (lua_State *L, int statesmask); 129 | LUAI_FUNC void luaC_fullgc (lua_State *L, int isemergency); 130 | LUAI_FUNC GCObject *luaC_newobj (lua_State *L, int tt, size_t sz); 131 | LUAI_FUNC void luaC_barrier_ (lua_State *L, GCObject *o, GCObject *v); 132 | LUAI_FUNC void luaC_barrierback_ (lua_State *L, Table *o); 133 | LUAI_FUNC void luaC_upvalbarrier_ (lua_State *L, UpVal *uv); 134 | LUAI_FUNC void luaC_checkfinalizer (lua_State *L, GCObject *o, Table *mt); 135 | LUAI_FUNC void luaC_upvdeccount (lua_State *L, UpVal *uv); 136 | 137 | 138 | #endif 139 | -------------------------------------------------------------------------------- /3rd/lua/src/linit.c: -------------------------------------------------------------------------------- 1 | /* 2 | ** $Id: linit.c,v 1.38 2015/01/05 13:48:33 roberto Exp $ 3 | ** Initialization of libraries for lua.c and other clients 4 | ** See Copyright Notice in lua.h 5 | */ 6 | 7 | 8 | #define linit_c 9 | #define LUA_LIB 10 | 11 | /* 12 | ** If you embed Lua in your program and need to open the standard 13 | ** libraries, call luaL_openlibs in your program. If you need a 14 | ** different set of libraries, copy this file to your project and edit 15 | ** it to suit your needs. 16 | ** 17 | ** You can also *preload* libraries, so that a later 'require' can 18 | ** open the library, which is already linked to the application. 19 | ** For that, do the following code: 20 | ** 21 | ** luaL_getsubtable(L, LUA_REGISTRYINDEX, "_PRELOAD"); 22 | ** lua_pushcfunction(L, luaopen_modname); 23 | ** lua_setfield(L, -2, modname); 24 | ** lua_pop(L, 1); // remove _PRELOAD table 25 | */ 26 | 27 | #include "lprefix.h" 28 | 29 | 30 | #include 31 | 32 | #include "lua.h" 33 | 34 | #include "lualib.h" 35 | #include "lauxlib.h" 36 | 37 | 38 | /* 39 | ** these libs are loaded by lua.c and are readily available to any Lua 40 | ** program 41 | */ 42 | static const luaL_Reg loadedlibs[] = { 43 | {"_G", luaopen_base}, 44 | {LUA_LOADLIBNAME, luaopen_package}, 45 | {LUA_COLIBNAME, luaopen_coroutine}, 46 | {LUA_TABLIBNAME, luaopen_table}, 47 | {LUA_IOLIBNAME, luaopen_io}, 48 | {LUA_OSLIBNAME, luaopen_os}, 49 | {LUA_STRLIBNAME, luaopen_string}, 50 | {LUA_MATHLIBNAME, luaopen_math}, 51 | {LUA_UTF8LIBNAME, luaopen_utf8}, 52 | {LUA_DBLIBNAME, luaopen_debug}, 53 | #if defined(LUA_COMPAT_BITLIB) 54 | {LUA_BITLIBNAME, luaopen_bit32}, 55 | #endif 56 | {NULL, NULL} 57 | }; 58 | 59 | 60 | LUALIB_API void luaL_openlibs (lua_State *L) { 61 | const luaL_Reg *lib; 62 | /* "require" functions from 'loadedlibs' and set results to global table */ 63 | for (lib = loadedlibs; lib->func; lib++) { 64 | luaL_requiref(L, lib->name, lib->func, 1); 65 | lua_pop(L, 1); /* remove lib */ 66 | } 67 | } 68 | 69 | -------------------------------------------------------------------------------- /3rd/lua/src/llex.h: -------------------------------------------------------------------------------- 1 | /* 2 | ** $Id: llex.h,v 1.78 2014/10/29 15:38:24 roberto Exp $ 3 | ** Lexical Analyzer 4 | ** See Copyright Notice in lua.h 5 | */ 6 | 7 | #ifndef llex_h 8 | #define llex_h 9 | 10 | #include "lobject.h" 11 | #include "lzio.h" 12 | 13 | 14 | #define FIRST_RESERVED 257 15 | 16 | 17 | #if !defined(LUA_ENV) 18 | #define LUA_ENV "_ENV" 19 | #endif 20 | 21 | 22 | /* 23 | * WARNING: if you change the order of this enumeration, 24 | * grep "ORDER RESERVED" 25 | */ 26 | enum RESERVED { 27 | /* terminal symbols denoted by reserved words */ 28 | TK_AND = FIRST_RESERVED, TK_BREAK, 29 | TK_DO, TK_ELSE, TK_ELSEIF, TK_END, TK_FALSE, TK_FOR, TK_FUNCTION, 30 | TK_GOTO, TK_IF, TK_IN, TK_LOCAL, TK_NIL, TK_NOT, TK_OR, TK_REPEAT, 31 | TK_RETURN, TK_THEN, TK_TRUE, TK_UNTIL, TK_WHILE, 32 | /* other terminal symbols */ 33 | TK_IDIV, TK_CONCAT, TK_DOTS, TK_EQ, TK_GE, TK_LE, TK_NE, 34 | TK_SHL, TK_SHR, 35 | TK_DBCOLON, TK_EOS, 36 | TK_FLT, TK_INT, TK_NAME, TK_STRING 37 | }; 38 | 39 | /* number of reserved words */ 40 | #define NUM_RESERVED (cast(int, TK_WHILE-FIRST_RESERVED+1)) 41 | 42 | 43 | typedef union { 44 | lua_Number r; 45 | lua_Integer i; 46 | TString *ts; 47 | } SemInfo; /* semantics information */ 48 | 49 | 50 | typedef struct Token { 51 | int token; 52 | SemInfo seminfo; 53 | } Token; 54 | 55 | 56 | /* state of the lexer plus state of the parser when shared by all 57 | functions */ 58 | typedef struct LexState { 59 | int current; /* current character (charint) */ 60 | int linenumber; /* input line counter */ 61 | int lastline; /* line of last token 'consumed' */ 62 | Token t; /* current token */ 63 | Token lookahead; /* look ahead token */ 64 | struct FuncState *fs; /* current function (parser) */ 65 | struct lua_State *L; 66 | ZIO *z; /* input stream */ 67 | Mbuffer *buff; /* buffer for tokens */ 68 | Table *h; /* to avoid collection/reuse strings */ 69 | struct Dyndata *dyd; /* dynamic structures used by the parser */ 70 | TString *source; /* current source name */ 71 | TString *envn; /* environment variable name */ 72 | char decpoint; /* locale decimal point */ 73 | } LexState; 74 | 75 | 76 | LUAI_FUNC void luaX_init (lua_State *L); 77 | LUAI_FUNC void luaX_setinput (lua_State *L, LexState *ls, ZIO *z, 78 | TString *source, int firstchar); 79 | LUAI_FUNC TString *luaX_newstring (LexState *ls, const char *str, size_t l); 80 | LUAI_FUNC void luaX_next (LexState *ls); 81 | LUAI_FUNC int luaX_lookahead (LexState *ls); 82 | LUAI_FUNC l_noret luaX_syntaxerror (LexState *ls, const char *s); 83 | LUAI_FUNC const char *luaX_token2str (LexState *ls, int token); 84 | 85 | 86 | #endif 87 | -------------------------------------------------------------------------------- /3rd/lua/src/llimits.h: -------------------------------------------------------------------------------- 1 | /* 2 | ** $Id: llimits.h,v 1.125 2014/12/19 13:30:23 roberto Exp $ 3 | ** Limits, basic types, and some other 'installation-dependent' definitions 4 | ** See Copyright Notice in lua.h 5 | */ 6 | 7 | #ifndef llimits_h 8 | #define llimits_h 9 | 10 | 11 | #include 12 | #include 13 | 14 | 15 | #include "lua.h" 16 | 17 | /* 18 | ** 'lu_mem' and 'l_mem' are unsigned/signed integers big enough to count 19 | ** the total memory used by Lua (in bytes). Usually, 'size_t' and 20 | ** 'ptrdiff_t' should work, but we use 'long' for 16-bit machines. 21 | */ 22 | #if defined(LUAI_MEM) /* { external definitions? */ 23 | typedef LUAI_UMEM lu_mem; 24 | typedef LUAI_MEM l_mem; 25 | #elif LUAI_BITSINT >= 32 /* }{ */ 26 | typedef size_t lu_mem; 27 | typedef ptrdiff_t l_mem; 28 | #else /* 16-bit ints */ /* }{ */ 29 | typedef unsigned long lu_mem; 30 | typedef long l_mem; 31 | #endif /* } */ 32 | 33 | 34 | /* chars used as small naturals (so that 'char' is reserved for characters) */ 35 | typedef unsigned char lu_byte; 36 | 37 | 38 | /* maximum value for size_t */ 39 | #define MAX_SIZET ((size_t)(~(size_t)0)) 40 | 41 | /* maximum size visible for Lua (must be representable in a lua_Integer */ 42 | #define MAX_SIZE (sizeof(size_t) < sizeof(lua_Integer) ? MAX_SIZET \ 43 | : (size_t)(LUA_MAXINTEGER)) 44 | 45 | 46 | #define MAX_LUMEM ((lu_mem)(~(lu_mem)0)) 47 | 48 | #define MAX_LMEM ((l_mem)(MAX_LUMEM >> 1)) 49 | 50 | 51 | #define MAX_INT INT_MAX /* maximum value of an int */ 52 | 53 | 54 | /* 55 | ** conversion of pointer to integer: 56 | ** this is for hashing only; there is no problem if the integer 57 | ** cannot hold the whole pointer value 58 | */ 59 | #define point2int(p) ((unsigned int)((size_t)(p) & UINT_MAX)) 60 | 61 | 62 | 63 | /* type to ensure maximum alignment */ 64 | #if defined(LUAI_USER_ALIGNMENT_T) 65 | typedef LUAI_USER_ALIGNMENT_T L_Umaxalign; 66 | #else 67 | typedef union { double u; void *s; lua_Integer i; long l; } L_Umaxalign; 68 | #endif 69 | 70 | 71 | 72 | /* types of 'usual argument conversions' for lua_Number and lua_Integer */ 73 | typedef LUAI_UACNUMBER l_uacNumber; 74 | typedef LUAI_UACINT l_uacInt; 75 | 76 | 77 | /* internal assertions for in-house debugging */ 78 | #if defined(lua_assert) 79 | #define check_exp(c,e) (lua_assert(c), (e)) 80 | /* to avoid problems with conditions too long */ 81 | #define lua_longassert(c) { if (!(c)) lua_assert(0); } 82 | #else 83 | #define lua_assert(c) ((void)0) 84 | #define check_exp(c,e) (e) 85 | #define lua_longassert(c) ((void)0) 86 | #endif 87 | 88 | /* 89 | ** assertion for checking API calls 90 | */ 91 | #if defined(LUA_USE_APICHECK) 92 | #include 93 | #define luai_apicheck(e) assert(e) 94 | #else 95 | #define luai_apicheck(e) lua_assert(e) 96 | #endif 97 | 98 | 99 | #define api_check(e,msg) luai_apicheck((e) && msg) 100 | 101 | 102 | #if !defined(UNUSED) 103 | #define UNUSED(x) ((void)(x)) /* to avoid warnings */ 104 | #endif 105 | 106 | 107 | #define cast(t, exp) ((t)(exp)) 108 | 109 | #define cast_void(i) cast(void, (i)) 110 | #define cast_byte(i) cast(lu_byte, (i)) 111 | #define cast_num(i) cast(lua_Number, (i)) 112 | #define cast_int(i) cast(int, (i)) 113 | #define cast_uchar(i) cast(unsigned char, (i)) 114 | 115 | 116 | /* cast a signed lua_Integer to lua_Unsigned */ 117 | #if !defined(l_castS2U) 118 | #define l_castS2U(i) ((lua_Unsigned)(i)) 119 | #endif 120 | 121 | /* 122 | ** cast a lua_Unsigned to a signed lua_Integer; this cast is 123 | ** not strict ISO C, but two-complement architectures should 124 | ** work fine. 125 | */ 126 | #if !defined(l_castU2S) 127 | #define l_castU2S(i) ((lua_Integer)(i)) 128 | #endif 129 | 130 | 131 | /* 132 | ** non-return type 133 | */ 134 | #if defined(__GNUC__) 135 | #define l_noret void __attribute__((noreturn)) 136 | #elif defined(_MSC_VER) && _MSC_VER >= 1200 137 | #define l_noret void __declspec(noreturn) 138 | #else 139 | #define l_noret void 140 | #endif 141 | 142 | 143 | 144 | /* 145 | ** maximum depth for nested C calls and syntactical nested non-terminals 146 | ** in a program. (Value must fit in an unsigned short int.) 147 | */ 148 | #if !defined(LUAI_MAXCCALLS) 149 | #define LUAI_MAXCCALLS 200 150 | #endif 151 | 152 | /* 153 | ** maximum number of upvalues in a closure (both C and Lua). (Value 154 | ** must fit in an unsigned char.) 155 | */ 156 | #define MAXUPVAL UCHAR_MAX 157 | 158 | 159 | /* 160 | ** type for virtual-machine instructions; 161 | ** must be an unsigned with (at least) 4 bytes (see details in lopcodes.h) 162 | */ 163 | #if LUAI_BITSINT >= 32 164 | typedef unsigned int Instruction; 165 | #else 166 | typedef unsigned long Instruction; 167 | #endif 168 | 169 | 170 | 171 | 172 | /* minimum size for the string table (must be power of 2) */ 173 | #if !defined(MINSTRTABSIZE) 174 | #define MINSTRTABSIZE 64 /* minimum size for "predefined" strings */ 175 | #endif 176 | 177 | 178 | /* minimum size for string buffer */ 179 | #if !defined(LUA_MINBUFFER) 180 | #define LUA_MINBUFFER 32 181 | #endif 182 | 183 | 184 | #if !defined(lua_lock) 185 | #define lua_lock(L) ((void) 0) 186 | #define lua_unlock(L) ((void) 0) 187 | #endif 188 | 189 | #if !defined(luai_threadyield) 190 | #define luai_threadyield(L) {lua_unlock(L); lua_lock(L);} 191 | #endif 192 | 193 | 194 | /* 195 | ** these macros allow user-specific actions on threads when you defined 196 | ** LUAI_EXTRASPACE and need to do something extra when a thread is 197 | ** created/deleted/resumed/yielded. 198 | */ 199 | #if !defined(luai_userstateopen) 200 | #define luai_userstateopen(L) ((void)L) 201 | #endif 202 | 203 | #if !defined(luai_userstateclose) 204 | #define luai_userstateclose(L) ((void)L) 205 | #endif 206 | 207 | #if !defined(luai_userstatethread) 208 | #define luai_userstatethread(L,L1) ((void)L) 209 | #endif 210 | 211 | #if !defined(luai_userstatefree) 212 | #define luai_userstatefree(L,L1) ((void)L) 213 | #endif 214 | 215 | #if !defined(luai_userstateresume) 216 | #define luai_userstateresume(L,n) ((void)L) 217 | #endif 218 | 219 | #if !defined(luai_userstateyield) 220 | #define luai_userstateyield(L,n) ((void)L) 221 | #endif 222 | 223 | 224 | 225 | /* 226 | ** macro to control inclusion of some hard tests on stack reallocation 227 | */ 228 | #if !defined(HARDSTACKTESTS) 229 | #define condmovestack(L) ((void)0) 230 | #else 231 | /* realloc stack keeping its size */ 232 | #define condmovestack(L) luaD_reallocstack((L), (L)->stacksize) 233 | #endif 234 | 235 | #if !defined(HARDMEMTESTS) 236 | #define condchangemem(L) condmovestack(L) 237 | #else 238 | #define condchangemem(L) \ 239 | ((void)(!(G(L)->gcrunning) || (luaC_fullgc(L, 0), 1))) 240 | #endif 241 | 242 | #endif 243 | -------------------------------------------------------------------------------- /3rd/lua/src/lmem.c: -------------------------------------------------------------------------------- 1 | /* 2 | ** $Id: lmem.c,v 1.89 2014/11/02 19:33:33 roberto Exp $ 3 | ** Interface to Memory Manager 4 | ** See Copyright Notice in lua.h 5 | */ 6 | 7 | #define lmem_c 8 | #define LUA_CORE 9 | 10 | #include "lprefix.h" 11 | 12 | 13 | #include 14 | 15 | #include "lua.h" 16 | 17 | #include "ldebug.h" 18 | #include "ldo.h" 19 | #include "lgc.h" 20 | #include "lmem.h" 21 | #include "lobject.h" 22 | #include "lstate.h" 23 | 24 | 25 | 26 | /* 27 | ** About the realloc function: 28 | ** void * frealloc (void *ud, void *ptr, size_t osize, size_t nsize); 29 | ** ('osize' is the old size, 'nsize' is the new size) 30 | ** 31 | ** * frealloc(ud, NULL, x, s) creates a new block of size 's' (no 32 | ** matter 'x'). 33 | ** 34 | ** * frealloc(ud, p, x, 0) frees the block 'p' 35 | ** (in this specific case, frealloc must return NULL); 36 | ** particularly, frealloc(ud, NULL, 0, 0) does nothing 37 | ** (which is equivalent to free(NULL) in ISO C) 38 | ** 39 | ** frealloc returns NULL if it cannot create or reallocate the area 40 | ** (any reallocation to an equal or smaller size cannot fail!) 41 | */ 42 | 43 | 44 | 45 | #define MINSIZEARRAY 4 46 | 47 | 48 | void *luaM_growaux_ (lua_State *L, void *block, int *size, size_t size_elems, 49 | int limit, const char *what) { 50 | void *newblock; 51 | int newsize; 52 | if (*size >= limit/2) { /* cannot double it? */ 53 | if (*size >= limit) /* cannot grow even a little? */ 54 | luaG_runerror(L, "too many %s (limit is %d)", what, limit); 55 | newsize = limit; /* still have at least one free place */ 56 | } 57 | else { 58 | newsize = (*size)*2; 59 | if (newsize < MINSIZEARRAY) 60 | newsize = MINSIZEARRAY; /* minimum size */ 61 | } 62 | newblock = luaM_reallocv(L, block, *size, newsize, size_elems); 63 | *size = newsize; /* update only when everything else is OK */ 64 | return newblock; 65 | } 66 | 67 | 68 | l_noret luaM_toobig (lua_State *L) { 69 | luaG_runerror(L, "memory allocation error: block too big"); 70 | } 71 | 72 | 73 | 74 | /* 75 | ** generic allocation routine. 76 | */ 77 | void *luaM_realloc_ (lua_State *L, void *block, size_t osize, size_t nsize) { 78 | void *newblock; 79 | global_State *g = G(L); 80 | size_t realosize = (block) ? osize : 0; 81 | lua_assert((realosize == 0) == (block == NULL)); 82 | #if defined(HARDMEMTESTS) 83 | if (nsize > realosize && g->gcrunning) 84 | luaC_fullgc(L, 1); /* force a GC whenever possible */ 85 | #endif 86 | newblock = (*g->frealloc)(g->ud, block, osize, nsize); 87 | if (newblock == NULL && nsize > 0) { 88 | api_check( nsize > realosize, 89 | "realloc cannot fail when shrinking a block"); 90 | luaC_fullgc(L, 1); /* try to free some memory... */ 91 | newblock = (*g->frealloc)(g->ud, block, osize, nsize); /* try again */ 92 | if (newblock == NULL) 93 | luaD_throw(L, LUA_ERRMEM); 94 | } 95 | lua_assert((nsize == 0) == (newblock == NULL)); 96 | g->GCdebt = (g->GCdebt + nsize) - realosize; 97 | return newblock; 98 | } 99 | 100 | -------------------------------------------------------------------------------- /3rd/lua/src/lmem.h: -------------------------------------------------------------------------------- 1 | /* 2 | ** $Id: lmem.h,v 1.43 2014/12/19 17:26:14 roberto Exp $ 3 | ** Interface to Memory Manager 4 | ** See Copyright Notice in lua.h 5 | */ 6 | 7 | #ifndef lmem_h 8 | #define lmem_h 9 | 10 | 11 | #include 12 | 13 | #include "llimits.h" 14 | #include "lua.h" 15 | 16 | 17 | /* 18 | ** This macro reallocs a vector 'b' from 'on' to 'n' elements, where 19 | ** each element has size 'e'. In case of arithmetic overflow of the 20 | ** product 'n'*'e', it raises an error (calling 'luaM_toobig'). Because 21 | ** 'e' is always constant, it avoids the runtime division MAX_SIZET/(e). 22 | ** 23 | ** (The macro is somewhat complex to avoid warnings: The 'sizeof' 24 | ** comparison avoids a runtime comparison when overflow cannot occur. 25 | ** The compiler should be able to optimize the real test by itself, but 26 | ** when it does it, it may give a warning about "comparison is always 27 | ** false due to limited range of data type"; the +1 tricks the compiler, 28 | ** avoiding this warning but also this optimization.) 29 | */ 30 | #define luaM_reallocv(L,b,on,n,e) \ 31 | (((sizeof(n) >= sizeof(size_t) && cast(size_t, (n)) + 1 > MAX_SIZET/(e)) \ 32 | ? luaM_toobig(L) : cast_void(0)) , \ 33 | luaM_realloc_(L, (b), (on)*(e), (n)*(e))) 34 | 35 | /* 36 | ** Arrays of chars do not need any test 37 | */ 38 | #define luaM_reallocvchar(L,b,on,n) \ 39 | cast(char *, luaM_realloc_(L, (b), (on)*sizeof(char), (n)*sizeof(char))) 40 | 41 | #define luaM_freemem(L, b, s) luaM_realloc_(L, (b), (s), 0) 42 | #define luaM_free(L, b) luaM_realloc_(L, (b), sizeof(*(b)), 0) 43 | #define luaM_freearray(L, b, n) luaM_realloc_(L, (b), (n)*sizeof(*(b)), 0) 44 | 45 | #define luaM_malloc(L,s) luaM_realloc_(L, NULL, 0, (s)) 46 | #define luaM_new(L,t) cast(t *, luaM_malloc(L, sizeof(t))) 47 | #define luaM_newvector(L,n,t) \ 48 | cast(t *, luaM_reallocv(L, NULL, 0, n, sizeof(t))) 49 | 50 | #define luaM_newobject(L,tag,s) luaM_realloc_(L, NULL, tag, (s)) 51 | 52 | #define luaM_growvector(L,v,nelems,size,t,limit,e) \ 53 | if ((nelems)+1 > (size)) \ 54 | ((v)=cast(t *, luaM_growaux_(L,v,&(size),sizeof(t),limit,e))) 55 | 56 | #define luaM_reallocvector(L, v,oldn,n,t) \ 57 | ((v)=cast(t *, luaM_reallocv(L, v, oldn, n, sizeof(t)))) 58 | 59 | LUAI_FUNC l_noret luaM_toobig (lua_State *L); 60 | 61 | /* not to be called directly */ 62 | LUAI_FUNC void *luaM_realloc_ (lua_State *L, void *block, size_t oldsize, 63 | size_t size); 64 | LUAI_FUNC void *luaM_growaux_ (lua_State *L, void *block, int *size, 65 | size_t size_elem, int limit, 66 | const char *what); 67 | 68 | #endif 69 | 70 | -------------------------------------------------------------------------------- /3rd/lua/src/lopcodes.c: -------------------------------------------------------------------------------- 1 | /* 2 | ** $Id: lopcodes.c,v 1.55 2015/01/05 13:48:33 roberto Exp $ 3 | ** Opcodes for Lua virtual machine 4 | ** See Copyright Notice in lua.h 5 | */ 6 | 7 | #define lopcodes_c 8 | #define LUA_CORE 9 | 10 | #include "lprefix.h" 11 | 12 | 13 | #include 14 | 15 | #include "lopcodes.h" 16 | 17 | 18 | /* ORDER OP */ 19 | 20 | LUAI_DDEF const char *const luaP_opnames[NUM_OPCODES+1] = { 21 | "MOVE", 22 | "LOADK", 23 | "LOADKX", 24 | "LOADBOOL", 25 | "LOADNIL", 26 | "GETUPVAL", 27 | "GETTABUP", 28 | "GETTABLE", 29 | "SETTABUP", 30 | "SETUPVAL", 31 | "SETTABLE", 32 | "NEWTABLE", 33 | "SELF", 34 | "ADD", 35 | "SUB", 36 | "MUL", 37 | "MOD", 38 | "POW", 39 | "DIV", 40 | "IDIV", 41 | "BAND", 42 | "BOR", 43 | "BXOR", 44 | "SHL", 45 | "SHR", 46 | "UNM", 47 | "BNOT", 48 | "NOT", 49 | "LEN", 50 | "CONCAT", 51 | "JMP", 52 | "EQ", 53 | "LT", 54 | "LE", 55 | "TEST", 56 | "TESTSET", 57 | "CALL", 58 | "TAILCALL", 59 | "RETURN", 60 | "FORLOOP", 61 | "FORPREP", 62 | "TFORCALL", 63 | "TFORLOOP", 64 | "SETLIST", 65 | "CLOSURE", 66 | "VARARG", 67 | "EXTRAARG", 68 | NULL 69 | }; 70 | 71 | 72 | #define opmode(t,a,b,c,m) (((t)<<7) | ((a)<<6) | ((b)<<4) | ((c)<<2) | (m)) 73 | 74 | LUAI_DDEF const lu_byte luaP_opmodes[NUM_OPCODES] = { 75 | /* T A B C mode opcode */ 76 | opmode(0, 1, OpArgR, OpArgN, iABC) /* OP_MOVE */ 77 | ,opmode(0, 1, OpArgK, OpArgN, iABx) /* OP_LOADK */ 78 | ,opmode(0, 1, OpArgN, OpArgN, iABx) /* OP_LOADKX */ 79 | ,opmode(0, 1, OpArgU, OpArgU, iABC) /* OP_LOADBOOL */ 80 | ,opmode(0, 1, OpArgU, OpArgN, iABC) /* OP_LOADNIL */ 81 | ,opmode(0, 1, OpArgU, OpArgN, iABC) /* OP_GETUPVAL */ 82 | ,opmode(0, 1, OpArgU, OpArgK, iABC) /* OP_GETTABUP */ 83 | ,opmode(0, 1, OpArgR, OpArgK, iABC) /* OP_GETTABLE */ 84 | ,opmode(0, 0, OpArgK, OpArgK, iABC) /* OP_SETTABUP */ 85 | ,opmode(0, 0, OpArgU, OpArgN, iABC) /* OP_SETUPVAL */ 86 | ,opmode(0, 0, OpArgK, OpArgK, iABC) /* OP_SETTABLE */ 87 | ,opmode(0, 1, OpArgU, OpArgU, iABC) /* OP_NEWTABLE */ 88 | ,opmode(0, 1, OpArgR, OpArgK, iABC) /* OP_SELF */ 89 | ,opmode(0, 1, OpArgK, OpArgK, iABC) /* OP_ADD */ 90 | ,opmode(0, 1, OpArgK, OpArgK, iABC) /* OP_SUB */ 91 | ,opmode(0, 1, OpArgK, OpArgK, iABC) /* OP_MUL */ 92 | ,opmode(0, 1, OpArgK, OpArgK, iABC) /* OP_MOD */ 93 | ,opmode(0, 1, OpArgK, OpArgK, iABC) /* OP_POW */ 94 | ,opmode(0, 1, OpArgK, OpArgK, iABC) /* OP_DIV */ 95 | ,opmode(0, 1, OpArgK, OpArgK, iABC) /* OP_IDIV */ 96 | ,opmode(0, 1, OpArgK, OpArgK, iABC) /* OP_BAND */ 97 | ,opmode(0, 1, OpArgK, OpArgK, iABC) /* OP_BOR */ 98 | ,opmode(0, 1, OpArgK, OpArgK, iABC) /* OP_BXOR */ 99 | ,opmode(0, 1, OpArgK, OpArgK, iABC) /* OP_SHL */ 100 | ,opmode(0, 1, OpArgK, OpArgK, iABC) /* OP_SHR */ 101 | ,opmode(0, 1, OpArgR, OpArgN, iABC) /* OP_UNM */ 102 | ,opmode(0, 1, OpArgR, OpArgN, iABC) /* OP_BNOT */ 103 | ,opmode(0, 1, OpArgR, OpArgN, iABC) /* OP_NOT */ 104 | ,opmode(0, 1, OpArgR, OpArgN, iABC) /* OP_LEN */ 105 | ,opmode(0, 1, OpArgR, OpArgR, iABC) /* OP_CONCAT */ 106 | ,opmode(0, 0, OpArgR, OpArgN, iAsBx) /* OP_JMP */ 107 | ,opmode(1, 0, OpArgK, OpArgK, iABC) /* OP_EQ */ 108 | ,opmode(1, 0, OpArgK, OpArgK, iABC) /* OP_LT */ 109 | ,opmode(1, 0, OpArgK, OpArgK, iABC) /* OP_LE */ 110 | ,opmode(1, 0, OpArgN, OpArgU, iABC) /* OP_TEST */ 111 | ,opmode(1, 1, OpArgR, OpArgU, iABC) /* OP_TESTSET */ 112 | ,opmode(0, 1, OpArgU, OpArgU, iABC) /* OP_CALL */ 113 | ,opmode(0, 1, OpArgU, OpArgU, iABC) /* OP_TAILCALL */ 114 | ,opmode(0, 0, OpArgU, OpArgN, iABC) /* OP_RETURN */ 115 | ,opmode(0, 1, OpArgR, OpArgN, iAsBx) /* OP_FORLOOP */ 116 | ,opmode(0, 1, OpArgR, OpArgN, iAsBx) /* OP_FORPREP */ 117 | ,opmode(0, 0, OpArgN, OpArgU, iABC) /* OP_TFORCALL */ 118 | ,opmode(0, 1, OpArgR, OpArgN, iAsBx) /* OP_TFORLOOP */ 119 | ,opmode(0, 0, OpArgU, OpArgU, iABC) /* OP_SETLIST */ 120 | ,opmode(0, 1, OpArgU, OpArgN, iABx) /* OP_CLOSURE */ 121 | ,opmode(0, 1, OpArgU, OpArgN, iABC) /* OP_VARARG */ 122 | ,opmode(0, 0, OpArgU, OpArgU, iAx) /* OP_EXTRAARG */ 123 | }; 124 | 125 | -------------------------------------------------------------------------------- /3rd/lua/src/lopcodes.h: -------------------------------------------------------------------------------- 1 | /* 2 | ** $Id: lopcodes.h,v 1.148 2014/10/25 11:50:46 roberto Exp $ 3 | ** Opcodes for Lua virtual machine 4 | ** See Copyright Notice in lua.h 5 | */ 6 | 7 | #ifndef lopcodes_h 8 | #define lopcodes_h 9 | 10 | #include "llimits.h" 11 | 12 | 13 | /*=========================================================================== 14 | We assume that instructions are unsigned numbers. 15 | All instructions have an opcode in the first 6 bits. 16 | Instructions can have the following fields: 17 | 'A' : 8 bits 18 | 'B' : 9 bits 19 | 'C' : 9 bits 20 | 'Ax' : 26 bits ('A', 'B', and 'C' together) 21 | 'Bx' : 18 bits ('B' and 'C' together) 22 | 'sBx' : signed Bx 23 | 24 | A signed argument is represented in excess K; that is, the number 25 | value is the unsigned value minus K. K is exactly the maximum value 26 | for that argument (so that -max is represented by 0, and +max is 27 | represented by 2*max), which is half the maximum for the corresponding 28 | unsigned argument. 29 | ===========================================================================*/ 30 | 31 | 32 | enum OpMode {iABC, iABx, iAsBx, iAx}; /* basic instruction format */ 33 | 34 | 35 | /* 36 | ** size and position of opcode arguments. 37 | */ 38 | #define SIZE_C 9 39 | #define SIZE_B 9 40 | #define SIZE_Bx (SIZE_C + SIZE_B) 41 | #define SIZE_A 8 42 | #define SIZE_Ax (SIZE_C + SIZE_B + SIZE_A) 43 | 44 | #define SIZE_OP 6 45 | 46 | #define POS_OP 0 47 | #define POS_A (POS_OP + SIZE_OP) 48 | #define POS_C (POS_A + SIZE_A) 49 | #define POS_B (POS_C + SIZE_C) 50 | #define POS_Bx POS_C 51 | #define POS_Ax POS_A 52 | 53 | 54 | /* 55 | ** limits for opcode arguments. 56 | ** we use (signed) int to manipulate most arguments, 57 | ** so they must fit in LUAI_BITSINT-1 bits (-1 for sign) 58 | */ 59 | #if SIZE_Bx < LUAI_BITSINT-1 60 | #define MAXARG_Bx ((1<>1) /* 'sBx' is signed */ 62 | #else 63 | #define MAXARG_Bx MAX_INT 64 | #define MAXARG_sBx MAX_INT 65 | #endif 66 | 67 | #if SIZE_Ax < LUAI_BITSINT-1 68 | #define MAXARG_Ax ((1<>POS_OP) & MASK1(SIZE_OP,0))) 90 | #define SET_OPCODE(i,o) ((i) = (((i)&MASK0(SIZE_OP,POS_OP)) | \ 91 | ((cast(Instruction, o)<>pos) & MASK1(size,0))) 94 | #define setarg(i,v,pos,size) ((i) = (((i)&MASK0(size,pos)) | \ 95 | ((cast(Instruction, v)<> RK(C) */ 199 | OP_UNM,/* A B R(A) := -R(B) */ 200 | OP_BNOT,/* A B R(A) := ~R(B) */ 201 | OP_NOT,/* A B R(A) := not R(B) */ 202 | OP_LEN,/* A B R(A) := length of R(B) */ 203 | 204 | OP_CONCAT,/* A B C R(A) := R(B).. ... ..R(C) */ 205 | 206 | OP_JMP,/* A sBx pc+=sBx; if (A) close all upvalues >= R(A - 1) */ 207 | OP_EQ,/* A B C if ((RK(B) == RK(C)) ~= A) then pc++ */ 208 | OP_LT,/* A B C if ((RK(B) < RK(C)) ~= A) then pc++ */ 209 | OP_LE,/* A B C if ((RK(B) <= RK(C)) ~= A) then pc++ */ 210 | 211 | OP_TEST,/* A C if not (R(A) <=> C) then pc++ */ 212 | OP_TESTSET,/* A B C if (R(B) <=> C) then R(A) := R(B) else pc++ */ 213 | 214 | OP_CALL,/* A B C R(A), ... ,R(A+C-2) := R(A)(R(A+1), ... ,R(A+B-1)) */ 215 | OP_TAILCALL,/* A B C return R(A)(R(A+1), ... ,R(A+B-1)) */ 216 | OP_RETURN,/* A B return R(A), ... ,R(A+B-2) (see note) */ 217 | 218 | OP_FORLOOP,/* A sBx R(A)+=R(A+2); 219 | if R(A) > 4) & 3)) 283 | #define getCMode(m) (cast(enum OpArgMask, (luaP_opmodes[m] >> 2) & 3)) 284 | #define testAMode(m) (luaP_opmodes[m] & (1 << 6)) 285 | #define testTMode(m) (luaP_opmodes[m] & (1 << 7)) 286 | 287 | 288 | LUAI_DDEC const char *const luaP_opnames[NUM_OPCODES+1]; /* opcode names */ 289 | 290 | 291 | /* number of list items to accumulate before a SETLIST instruction */ 292 | #define LFIELDS_PER_FLUSH 50 293 | 294 | 295 | #endif 296 | -------------------------------------------------------------------------------- /3rd/lua/src/loslib.c: -------------------------------------------------------------------------------- 1 | /* 2 | ** $Id: loslib.c,v 1.54 2014/12/26 14:46:07 roberto Exp $ 3 | ** Standard Operating System library 4 | ** See Copyright Notice in lua.h 5 | */ 6 | 7 | #define loslib_c 8 | #define LUA_LIB 9 | 10 | #include "lprefix.h" 11 | 12 | 13 | #include 14 | #include 15 | #include 16 | #include 17 | #include 18 | 19 | #include "lua.h" 20 | 21 | #include "lauxlib.h" 22 | #include "lualib.h" 23 | 24 | 25 | #if !defined(LUA_STRFTIMEOPTIONS) /* { */ 26 | /* 27 | ** list of valid conversion specifiers for the 'strftime' function 28 | */ 29 | 30 | #if defined(LUA_USE_C89) 31 | #define LUA_STRFTIMEOPTIONS { "aAbBcdHIjmMpSUwWxXyYz%", "" } 32 | #else /* C99 specification */ 33 | #define LUA_STRFTIMEOPTIONS \ 34 | { "aAbBcCdDeFgGhHIjmMnprRStTuUVwWxXyYzZ%", "", \ 35 | "E", "cCxXyY", \ 36 | "O", "deHImMSuUVwWy" } 37 | #endif 38 | 39 | #endif /* } */ 40 | 41 | 42 | 43 | #if !defined(l_time_t) /* { */ 44 | /* 45 | ** type to represent time_t in Lua 46 | */ 47 | #define l_timet lua_Integer 48 | #define l_pushtime(L,t) lua_pushinteger(L,(lua_Integer)(t)) 49 | #define l_checktime(L,a) ((time_t)luaL_checkinteger(L,a)) 50 | 51 | #endif /* } */ 52 | 53 | 54 | 55 | #if !defined(lua_tmpnam) /* { */ 56 | /* 57 | ** By default, Lua uses tmpnam except when POSIX is available, where it 58 | ** uses mkstemp. 59 | */ 60 | 61 | #if defined(LUA_USE_POSIX) /* { */ 62 | 63 | #include 64 | 65 | #define LUA_TMPNAMBUFSIZE 32 66 | 67 | #if !defined(LUA_TMPNAMTEMPLATE) 68 | #define LUA_TMPNAMTEMPLATE "/tmp/lua_XXXXXX" 69 | #endif 70 | 71 | #define lua_tmpnam(b,e) { \ 72 | strcpy(b, LUA_TMPNAMTEMPLATE); \ 73 | e = mkstemp(b); \ 74 | if (e != -1) close(e); \ 75 | e = (e == -1); } 76 | 77 | #else /* }{ */ 78 | 79 | /* ISO C definitions */ 80 | #define LUA_TMPNAMBUFSIZE L_tmpnam 81 | #define lua_tmpnam(b,e) { e = (tmpnam(b) == NULL); } 82 | 83 | #endif /* } */ 84 | 85 | #endif /* } */ 86 | 87 | 88 | 89 | #if !defined(l_gmtime) /* { */ 90 | /* 91 | ** By default, Lua uses gmtime/localtime, except when POSIX is available, 92 | ** where it uses gmtime_r/localtime_r 93 | */ 94 | 95 | #if defined(LUA_USE_POSIX) /* { */ 96 | 97 | #define l_gmtime(t,r) gmtime_r(t,r) 98 | #define l_localtime(t,r) localtime_r(t,r) 99 | 100 | #else /* }{ */ 101 | 102 | /* ISO C definitions */ 103 | #define l_gmtime(t,r) ((void)(r)->tm_sec, gmtime(t)) 104 | #define l_localtime(t,r) ((void)(r)->tm_sec, localtime(t)) 105 | 106 | #endif /* } */ 107 | 108 | #endif /* } */ 109 | 110 | 111 | 112 | static int os_execute (lua_State *L) { 113 | const char *cmd = luaL_optstring(L, 1, NULL); 114 | int stat = system(cmd); 115 | if (cmd != NULL) 116 | return luaL_execresult(L, stat); 117 | else { 118 | lua_pushboolean(L, stat); /* true if there is a shell */ 119 | return 1; 120 | } 121 | } 122 | 123 | 124 | static int os_remove (lua_State *L) { 125 | const char *filename = luaL_checkstring(L, 1); 126 | return luaL_fileresult(L, remove(filename) == 0, filename); 127 | } 128 | 129 | 130 | static int os_rename (lua_State *L) { 131 | const char *fromname = luaL_checkstring(L, 1); 132 | const char *toname = luaL_checkstring(L, 2); 133 | return luaL_fileresult(L, rename(fromname, toname) == 0, NULL); 134 | } 135 | 136 | 137 | static int os_tmpname (lua_State *L) { 138 | char buff[LUA_TMPNAMBUFSIZE]; 139 | int err; 140 | lua_tmpnam(buff, err); 141 | if (err) 142 | return luaL_error(L, "unable to generate a unique filename"); 143 | lua_pushstring(L, buff); 144 | return 1; 145 | } 146 | 147 | 148 | static int os_getenv (lua_State *L) { 149 | lua_pushstring(L, getenv(luaL_checkstring(L, 1))); /* if NULL push nil */ 150 | return 1; 151 | } 152 | 153 | 154 | static int os_clock (lua_State *L) { 155 | lua_pushnumber(L, ((lua_Number)clock())/(lua_Number)CLOCKS_PER_SEC); 156 | return 1; 157 | } 158 | 159 | 160 | /* 161 | ** {====================================================== 162 | ** Time/Date operations 163 | ** { year=%Y, month=%m, day=%d, hour=%H, min=%M, sec=%S, 164 | ** wday=%w+1, yday=%j, isdst=? } 165 | ** ======================================================= 166 | */ 167 | 168 | static void setfield (lua_State *L, const char *key, int value) { 169 | lua_pushinteger(L, value); 170 | lua_setfield(L, -2, key); 171 | } 172 | 173 | static void setboolfield (lua_State *L, const char *key, int value) { 174 | if (value < 0) /* undefined? */ 175 | return; /* does not set field */ 176 | lua_pushboolean(L, value); 177 | lua_setfield(L, -2, key); 178 | } 179 | 180 | static int getboolfield (lua_State *L, const char *key) { 181 | int res; 182 | res = (lua_getfield(L, -1, key) == LUA_TNIL) ? -1 : lua_toboolean(L, -1); 183 | lua_pop(L, 1); 184 | return res; 185 | } 186 | 187 | 188 | static int getfield (lua_State *L, const char *key, int d) { 189 | int res, isnum; 190 | lua_getfield(L, -1, key); 191 | res = (int)lua_tointegerx(L, -1, &isnum); 192 | if (!isnum) { 193 | if (d < 0) 194 | return luaL_error(L, "field '%s' missing in date table", key); 195 | res = d; 196 | } 197 | lua_pop(L, 1); 198 | return res; 199 | } 200 | 201 | 202 | static const char *checkoption (lua_State *L, const char *conv, char *buff) { 203 | static const char *const options[] = LUA_STRFTIMEOPTIONS; 204 | unsigned int i; 205 | for (i = 0; i < sizeof(options)/sizeof(options[0]); i += 2) { 206 | if (*conv != '\0' && strchr(options[i], *conv) != NULL) { 207 | buff[1] = *conv; 208 | if (*options[i + 1] == '\0') { /* one-char conversion specifier? */ 209 | buff[2] = '\0'; /* end buffer */ 210 | return conv + 1; 211 | } 212 | else if (*(conv + 1) != '\0' && 213 | strchr(options[i + 1], *(conv + 1)) != NULL) { 214 | buff[2] = *(conv + 1); /* valid two-char conversion specifier */ 215 | buff[3] = '\0'; /* end buffer */ 216 | return conv + 2; 217 | } 218 | } 219 | } 220 | luaL_argerror(L, 1, 221 | lua_pushfstring(L, "invalid conversion specifier '%%%s'", conv)); 222 | return conv; /* to avoid warnings */ 223 | } 224 | 225 | 226 | static int os_date (lua_State *L) { 227 | const char *s = luaL_optstring(L, 1, "%c"); 228 | time_t t = luaL_opt(L, l_checktime, 2, time(NULL)); 229 | struct tm tmr, *stm; 230 | if (*s == '!') { /* UTC? */ 231 | stm = l_gmtime(&t, &tmr); 232 | s++; /* skip '!' */ 233 | } 234 | else 235 | stm = l_localtime(&t, &tmr); 236 | if (stm == NULL) /* invalid date? */ 237 | lua_pushnil(L); 238 | else if (strcmp(s, "*t") == 0) { 239 | lua_createtable(L, 0, 9); /* 9 = number of fields */ 240 | setfield(L, "sec", stm->tm_sec); 241 | setfield(L, "min", stm->tm_min); 242 | setfield(L, "hour", stm->tm_hour); 243 | setfield(L, "day", stm->tm_mday); 244 | setfield(L, "month", stm->tm_mon+1); 245 | setfield(L, "year", stm->tm_year+1900); 246 | setfield(L, "wday", stm->tm_wday+1); 247 | setfield(L, "yday", stm->tm_yday+1); 248 | setboolfield(L, "isdst", stm->tm_isdst); 249 | } 250 | else { 251 | char cc[4]; 252 | luaL_Buffer b; 253 | cc[0] = '%'; 254 | luaL_buffinit(L, &b); 255 | while (*s) { 256 | if (*s != '%') /* no conversion specifier? */ 257 | luaL_addchar(&b, *s++); 258 | else { 259 | size_t reslen; 260 | char buff[200]; /* should be big enough for any conversion result */ 261 | s = checkoption(L, s + 1, cc); 262 | reslen = strftime(buff, sizeof(buff), cc, stm); 263 | luaL_addlstring(&b, buff, reslen); 264 | } 265 | } 266 | luaL_pushresult(&b); 267 | } 268 | return 1; 269 | } 270 | 271 | 272 | static int os_time (lua_State *L) { 273 | time_t t; 274 | if (lua_isnoneornil(L, 1)) /* called without args? */ 275 | t = time(NULL); /* get current time */ 276 | else { 277 | struct tm ts; 278 | luaL_checktype(L, 1, LUA_TTABLE); 279 | lua_settop(L, 1); /* make sure table is at the top */ 280 | ts.tm_sec = getfield(L, "sec", 0); 281 | ts.tm_min = getfield(L, "min", 0); 282 | ts.tm_hour = getfield(L, "hour", 12); 283 | ts.tm_mday = getfield(L, "day", -1); 284 | ts.tm_mon = getfield(L, "month", -1) - 1; 285 | ts.tm_year = getfield(L, "year", -1) - 1900; 286 | ts.tm_isdst = getboolfield(L, "isdst"); 287 | t = mktime(&ts); 288 | } 289 | if (t != (time_t)(l_timet)t) 290 | luaL_error(L, "time result cannot be represented in this Lua instalation"); 291 | else if (t == (time_t)(-1)) 292 | lua_pushnil(L); 293 | else 294 | l_pushtime(L, t); 295 | return 1; 296 | } 297 | 298 | 299 | static int os_difftime (lua_State *L) { 300 | double res = difftime((l_checktime(L, 1)), (l_checktime(L, 2))); 301 | lua_pushnumber(L, (lua_Number)res); 302 | return 1; 303 | } 304 | 305 | /* }====================================================== */ 306 | 307 | 308 | static int os_setlocale (lua_State *L) { 309 | static const int cat[] = {LC_ALL, LC_COLLATE, LC_CTYPE, LC_MONETARY, 310 | LC_NUMERIC, LC_TIME}; 311 | static const char *const catnames[] = {"all", "collate", "ctype", "monetary", 312 | "numeric", "time", NULL}; 313 | const char *l = luaL_optstring(L, 1, NULL); 314 | int op = luaL_checkoption(L, 2, "all", catnames); 315 | lua_pushstring(L, setlocale(cat[op], l)); 316 | return 1; 317 | } 318 | 319 | 320 | static int os_exit (lua_State *L) { 321 | int status; 322 | if (lua_isboolean(L, 1)) 323 | status = (lua_toboolean(L, 1) ? EXIT_SUCCESS : EXIT_FAILURE); 324 | else 325 | status = (int)luaL_optinteger(L, 1, EXIT_SUCCESS); 326 | if (lua_toboolean(L, 2)) 327 | lua_close(L); 328 | if (L) exit(status); /* 'if' to avoid warnings for unreachable 'return' */ 329 | return 0; 330 | } 331 | 332 | 333 | static const luaL_Reg syslib[] = { 334 | {"clock", os_clock}, 335 | {"date", os_date}, 336 | {"difftime", os_difftime}, 337 | {"execute", os_execute}, 338 | {"exit", os_exit}, 339 | {"getenv", os_getenv}, 340 | {"remove", os_remove}, 341 | {"rename", os_rename}, 342 | {"setlocale", os_setlocale}, 343 | {"time", os_time}, 344 | {"tmpname", os_tmpname}, 345 | {NULL, NULL} 346 | }; 347 | 348 | /* }====================================================== */ 349 | 350 | 351 | 352 | LUAMOD_API int luaopen_os (lua_State *L) { 353 | luaL_newlib(L, syslib); 354 | return 1; 355 | } 356 | 357 | -------------------------------------------------------------------------------- /3rd/lua/src/lparser.h: -------------------------------------------------------------------------------- 1 | /* 2 | ** $Id: lparser.h,v 1.74 2014/10/25 11:50:46 roberto Exp $ 3 | ** Lua Parser 4 | ** See Copyright Notice in lua.h 5 | */ 6 | 7 | #ifndef lparser_h 8 | #define lparser_h 9 | 10 | #include "llimits.h" 11 | #include "lobject.h" 12 | #include "lzio.h" 13 | 14 | 15 | /* 16 | ** Expression descriptor 17 | */ 18 | 19 | typedef enum { 20 | VVOID, /* no value */ 21 | VNIL, 22 | VTRUE, 23 | VFALSE, 24 | VK, /* info = index of constant in 'k' */ 25 | VKFLT, /* nval = numerical float value */ 26 | VKINT, /* nval = numerical integer value */ 27 | VNONRELOC, /* info = result register */ 28 | VLOCAL, /* info = local register */ 29 | VUPVAL, /* info = index of upvalue in 'upvalues' */ 30 | VINDEXED, /* t = table register/upvalue; idx = index R/K */ 31 | VJMP, /* info = instruction pc */ 32 | VRELOCABLE, /* info = instruction pc */ 33 | VCALL, /* info = instruction pc */ 34 | VVARARG /* info = instruction pc */ 35 | } expkind; 36 | 37 | 38 | #define vkisvar(k) (VLOCAL <= (k) && (k) <= VINDEXED) 39 | #define vkisinreg(k) ((k) == VNONRELOC || (k) == VLOCAL) 40 | 41 | typedef struct expdesc { 42 | expkind k; 43 | union { 44 | struct { /* for indexed variables (VINDEXED) */ 45 | short idx; /* index (R/K) */ 46 | lu_byte t; /* table (register or upvalue) */ 47 | lu_byte vt; /* whether 't' is register (VLOCAL) or upvalue (VUPVAL) */ 48 | } ind; 49 | int info; /* for generic use */ 50 | lua_Number nval; /* for VKFLT */ 51 | lua_Integer ival; /* for VKINT */ 52 | } u; 53 | int t; /* patch list of 'exit when true' */ 54 | int f; /* patch list of 'exit when false' */ 55 | } expdesc; 56 | 57 | 58 | /* description of active local variable */ 59 | typedef struct Vardesc { 60 | short idx; /* variable index in stack */ 61 | } Vardesc; 62 | 63 | 64 | /* description of pending goto statements and label statements */ 65 | typedef struct Labeldesc { 66 | TString *name; /* label identifier */ 67 | int pc; /* position in code */ 68 | int line; /* line where it appeared */ 69 | lu_byte nactvar; /* local level where it appears in current block */ 70 | } Labeldesc; 71 | 72 | 73 | /* list of labels or gotos */ 74 | typedef struct Labellist { 75 | Labeldesc *arr; /* array */ 76 | int n; /* number of entries in use */ 77 | int size; /* array size */ 78 | } Labellist; 79 | 80 | 81 | /* dynamic structures used by the parser */ 82 | typedef struct Dyndata { 83 | struct { /* list of active local variables */ 84 | Vardesc *arr; 85 | int n; 86 | int size; 87 | } actvar; 88 | Labellist gt; /* list of pending gotos */ 89 | Labellist label; /* list of active labels */ 90 | } Dyndata; 91 | 92 | 93 | /* control of blocks */ 94 | struct BlockCnt; /* defined in lparser.c */ 95 | 96 | 97 | /* state needed to generate code for a given function */ 98 | typedef struct FuncState { 99 | Proto *f; /* current function header */ 100 | struct FuncState *prev; /* enclosing function */ 101 | struct LexState *ls; /* lexical state */ 102 | struct BlockCnt *bl; /* chain of current blocks */ 103 | int pc; /* next position to code (equivalent to 'ncode') */ 104 | int lasttarget; /* 'label' of last 'jump label' */ 105 | int jpc; /* list of pending jumps to 'pc' */ 106 | int nk; /* number of elements in 'k' */ 107 | int np; /* number of elements in 'p' */ 108 | int firstlocal; /* index of first local var (in Dyndata array) */ 109 | short nlocvars; /* number of elements in 'f->locvars' */ 110 | lu_byte nactvar; /* number of active local variables */ 111 | lu_byte nups; /* number of upvalues */ 112 | lu_byte freereg; /* first free register */ 113 | } FuncState; 114 | 115 | 116 | LUAI_FUNC LClosure *luaY_parser (lua_State *L, ZIO *z, Mbuffer *buff, 117 | Dyndata *dyd, const char *name, int firstchar); 118 | 119 | 120 | #endif 121 | -------------------------------------------------------------------------------- /3rd/lua/src/lprefix.h: -------------------------------------------------------------------------------- 1 | /* 2 | ** $Id: lprefix.h,v 1.2 2014/12/29 16:54:13 roberto Exp $ 3 | ** Definitions for Lua code that must come before any other header file 4 | ** See Copyright Notice in lua.h 5 | */ 6 | 7 | #ifndef lprefix_h 8 | #define lprefix_h 9 | 10 | 11 | /* 12 | ** Allows POSIX/XSI stuff 13 | */ 14 | #if !defined(LUA_USE_C89) /* { */ 15 | 16 | #if !defined(_XOPEN_SOURCE) 17 | #define _XOPEN_SOURCE 600 18 | #elif _XOPEN_SOURCE == 0 19 | #undef _XOPEN_SOURCE /* use -D_XOPEN_SOURCE=0 to undefine it */ 20 | #endif 21 | 22 | /* 23 | ** Allows manipulation of large files in gcc and some other compilers 24 | */ 25 | #if !defined(LUA_32BITS) && !defined(_FILE_OFFSET_BITS) 26 | #define _LARGEFILE_SOURCE 1 27 | #define _FILE_OFFSET_BITS 64 28 | #endif 29 | 30 | #endif /* } */ 31 | 32 | 33 | /* 34 | ** Windows stuff 35 | */ 36 | #if defined(_WIN32) /* { */ 37 | 38 | #if !defined(_CRT_SECURE_NO_WARNINGS) 39 | #define _CRT_SECURE_NO_WARNINGS /* avoid warnings about ISO C functions */ 40 | #endif 41 | 42 | #endif /* } */ 43 | 44 | #endif 45 | 46 | -------------------------------------------------------------------------------- /3rd/lua/src/lstate.c: -------------------------------------------------------------------------------- 1 | /* 2 | ** $Id: lstate.c,v 2.127 2014/11/02 19:33:33 roberto Exp $ 3 | ** Global State 4 | ** See Copyright Notice in lua.h 5 | */ 6 | 7 | #define lstate_c 8 | #define LUA_CORE 9 | 10 | #include "lprefix.h" 11 | 12 | 13 | #include 14 | #include 15 | 16 | #include "lua.h" 17 | 18 | #include "lapi.h" 19 | #include "ldebug.h" 20 | #include "ldo.h" 21 | #include "lfunc.h" 22 | #include "lgc.h" 23 | #include "llex.h" 24 | #include "lmem.h" 25 | #include "lstate.h" 26 | #include "lstring.h" 27 | #include "ltable.h" 28 | #include "ltm.h" 29 | 30 | 31 | #if !defined(LUAI_GCPAUSE) 32 | #define LUAI_GCPAUSE 200 /* 200% */ 33 | #endif 34 | 35 | #if !defined(LUAI_GCMUL) 36 | #define LUAI_GCMUL 200 /* GC runs 'twice the speed' of memory allocation */ 37 | #endif 38 | 39 | 40 | #define MEMERRMSG "not enough memory" 41 | 42 | 43 | /* 44 | ** a macro to help the creation of a unique random seed when a state is 45 | ** created; the seed is used to randomize hashes. 46 | */ 47 | #if !defined(luai_makeseed) 48 | #include 49 | #define luai_makeseed() cast(unsigned int, time(NULL)) 50 | #endif 51 | 52 | 53 | 54 | /* 55 | ** thread state + extra space 56 | */ 57 | typedef struct LX { 58 | lu_byte extra_[LUA_EXTRASPACE]; 59 | lua_State l; 60 | } LX; 61 | 62 | 63 | /* 64 | ** Main thread combines a thread state and the global state 65 | */ 66 | typedef struct LG { 67 | LX l; 68 | global_State g; 69 | } LG; 70 | 71 | 72 | 73 | #define fromstate(L) (cast(LX *, cast(lu_byte *, (L)) - offsetof(LX, l))) 74 | 75 | 76 | /* 77 | ** Compute an initial seed as random as possible. Rely on Address Space 78 | ** Layout Randomization (if present) to increase randomness.. 79 | */ 80 | #define addbuff(b,p,e) \ 81 | { size_t t = cast(size_t, e); \ 82 | memcpy(buff + p, &t, sizeof(t)); p += sizeof(t); } 83 | 84 | static unsigned int makeseed (lua_State *L) { 85 | char buff[4 * sizeof(size_t)]; 86 | unsigned int h = luai_makeseed(); 87 | int p = 0; 88 | addbuff(buff, p, L); /* heap variable */ 89 | addbuff(buff, p, &h); /* local variable */ 90 | addbuff(buff, p, luaO_nilobject); /* global variable */ 91 | addbuff(buff, p, &lua_newstate); /* public function */ 92 | lua_assert(p == sizeof(buff)); 93 | return luaS_hash(buff, p, h); 94 | } 95 | 96 | 97 | /* 98 | ** set GCdebt to a new value keeping the value (totalbytes + GCdebt) 99 | ** invariant 100 | */ 101 | void luaE_setdebt (global_State *g, l_mem debt) { 102 | g->totalbytes -= (debt - g->GCdebt); 103 | g->GCdebt = debt; 104 | } 105 | 106 | 107 | CallInfo *luaE_extendCI (lua_State *L) { 108 | CallInfo *ci = luaM_new(L, CallInfo); 109 | lua_assert(L->ci->next == NULL); 110 | L->ci->next = ci; 111 | ci->previous = L->ci; 112 | ci->next = NULL; 113 | return ci; 114 | } 115 | 116 | 117 | /* 118 | ** free all CallInfo structures not in use by a thread 119 | */ 120 | void luaE_freeCI (lua_State *L) { 121 | CallInfo *ci = L->ci; 122 | CallInfo *next = ci->next; 123 | ci->next = NULL; 124 | while ((ci = next) != NULL) { 125 | next = ci->next; 126 | luaM_free(L, ci); 127 | } 128 | } 129 | 130 | 131 | /* 132 | ** free half of the CallInfo structures not in use by a thread 133 | */ 134 | void luaE_shrinkCI (lua_State *L) { 135 | CallInfo *ci = L->ci; 136 | while (ci->next != NULL) { /* while there is 'next' */ 137 | CallInfo *next2 = ci->next->next; /* next's next */ 138 | if (next2 == NULL) break; 139 | luaM_free(L, ci->next); /* remove next */ 140 | ci->next = next2; /* remove 'next' from the list */ 141 | next2->previous = ci; 142 | ci = next2; 143 | } 144 | } 145 | 146 | 147 | static void stack_init (lua_State *L1, lua_State *L) { 148 | int i; CallInfo *ci; 149 | /* initialize stack array */ 150 | L1->stack = luaM_newvector(L, BASIC_STACK_SIZE, TValue); 151 | L1->stacksize = BASIC_STACK_SIZE; 152 | for (i = 0; i < BASIC_STACK_SIZE; i++) 153 | setnilvalue(L1->stack + i); /* erase new stack */ 154 | L1->top = L1->stack; 155 | L1->stack_last = L1->stack + L1->stacksize - EXTRA_STACK; 156 | /* initialize first ci */ 157 | ci = &L1->base_ci; 158 | ci->next = ci->previous = NULL; 159 | ci->callstatus = 0; 160 | ci->func = L1->top; 161 | setnilvalue(L1->top++); /* 'function' entry for this 'ci' */ 162 | ci->top = L1->top + LUA_MINSTACK; 163 | L1->ci = ci; 164 | } 165 | 166 | 167 | static void freestack (lua_State *L) { 168 | if (L->stack == NULL) 169 | return; /* stack not completely built yet */ 170 | L->ci = &L->base_ci; /* free the entire 'ci' list */ 171 | luaE_freeCI(L); 172 | luaM_freearray(L, L->stack, L->stacksize); /* free stack array */ 173 | } 174 | 175 | 176 | /* 177 | ** Create registry table and its predefined values 178 | */ 179 | static void init_registry (lua_State *L, global_State *g) { 180 | TValue temp; 181 | /* create registry */ 182 | Table *registry = luaH_new(L); 183 | sethvalue(L, &g->l_registry, registry); 184 | luaH_resize(L, registry, LUA_RIDX_LAST, 0); 185 | /* registry[LUA_RIDX_MAINTHREAD] = L */ 186 | setthvalue(L, &temp, L); /* temp = L */ 187 | luaH_setint(L, registry, LUA_RIDX_MAINTHREAD, &temp); 188 | /* registry[LUA_RIDX_GLOBALS] = table of globals */ 189 | sethvalue(L, &temp, luaH_new(L)); /* temp = new table (global table) */ 190 | luaH_setint(L, registry, LUA_RIDX_GLOBALS, &temp); 191 | } 192 | 193 | 194 | /* 195 | ** open parts of the state that may cause memory-allocation errors. 196 | ** ('g->version' != NULL flags that the state was completely build) 197 | */ 198 | static void f_luaopen (lua_State *L, void *ud) { 199 | global_State *g = G(L); 200 | UNUSED(ud); 201 | stack_init(L, L); /* init stack */ 202 | init_registry(L, g); 203 | luaS_resize(L, MINSTRTABSIZE); /* initial size of string table */ 204 | luaT_init(L); 205 | luaX_init(L); 206 | /* pre-create memory-error message */ 207 | g->memerrmsg = luaS_newliteral(L, MEMERRMSG); 208 | luaC_fix(L, obj2gco(g->memerrmsg)); /* it should never be collected */ 209 | g->gcrunning = 1; /* allow gc */ 210 | g->version = lua_version(NULL); 211 | luai_userstateopen(L); 212 | } 213 | 214 | 215 | /* 216 | ** preinitialize a thread with consistent values without allocating 217 | ** any memory (to avoid errors) 218 | */ 219 | static void preinit_thread (lua_State *L, global_State *g) { 220 | G(L) = g; 221 | L->stack = NULL; 222 | L->ci = NULL; 223 | L->stacksize = 0; 224 | L->twups = L; /* thread has no upvalues */ 225 | L->errorJmp = NULL; 226 | L->nCcalls = 0; 227 | L->hook = NULL; 228 | L->hookmask = 0; 229 | L->basehookcount = 0; 230 | L->allowhook = 1; 231 | resethookcount(L); 232 | L->openupval = NULL; 233 | L->nny = 1; 234 | L->status = LUA_OK; 235 | L->errfunc = 0; 236 | } 237 | 238 | 239 | static void close_state (lua_State *L) { 240 | global_State *g = G(L); 241 | luaF_close(L, L->stack); /* close all upvalues for this thread */ 242 | luaC_freeallobjects(L); /* collect all objects */ 243 | if (g->version) /* closing a fully built state? */ 244 | luai_userstateclose(L); 245 | luaM_freearray(L, G(L)->strt.hash, G(L)->strt.size); 246 | luaZ_freebuffer(L, &g->buff); 247 | freestack(L); 248 | lua_assert(gettotalbytes(g) == sizeof(LG)); 249 | (*g->frealloc)(g->ud, fromstate(L), sizeof(LG), 0); /* free main block */ 250 | } 251 | 252 | 253 | LUA_API lua_State *lua_newthread (lua_State *L) { 254 | global_State *g = G(L); 255 | lua_State *L1; 256 | lua_lock(L); 257 | luaC_checkGC(L); 258 | /* create new thread */ 259 | L1 = &cast(LX *, luaM_newobject(L, LUA_TTHREAD, sizeof(LX)))->l; 260 | L1->marked = luaC_white(g); 261 | L1->tt = LUA_TTHREAD; 262 | /* link it on list 'allgc' */ 263 | L1->next = g->allgc; 264 | g->allgc = obj2gco(L1); 265 | /* anchor it on L stack */ 266 | setthvalue(L, L->top, L1); 267 | api_incr_top(L); 268 | preinit_thread(L1, g); 269 | L1->hookmask = L->hookmask; 270 | L1->basehookcount = L->basehookcount; 271 | L1->hook = L->hook; 272 | resethookcount(L1); 273 | /* initialize L1 extra space */ 274 | memcpy(lua_getextraspace(L1), lua_getextraspace(g->mainthread), 275 | LUA_EXTRASPACE); 276 | luai_userstatethread(L, L1); 277 | stack_init(L1, L); /* init stack */ 278 | lua_unlock(L); 279 | return L1; 280 | } 281 | 282 | 283 | void luaE_freethread (lua_State *L, lua_State *L1) { 284 | LX *l = fromstate(L1); 285 | luaF_close(L1, L1->stack); /* close all upvalues for this thread */ 286 | lua_assert(L1->openupval == NULL); 287 | luai_userstatefree(L, L1); 288 | freestack(L1); 289 | luaM_free(L, l); 290 | } 291 | 292 | 293 | LUA_API lua_State *lua_newstate (lua_Alloc f, void *ud) { 294 | int i; 295 | lua_State *L; 296 | global_State *g; 297 | LG *l = cast(LG *, (*f)(ud, NULL, LUA_TTHREAD, sizeof(LG))); 298 | if (l == NULL) return NULL; 299 | L = &l->l.l; 300 | g = &l->g; 301 | L->next = NULL; 302 | L->tt = LUA_TTHREAD; 303 | g->currentwhite = bitmask(WHITE0BIT); 304 | L->marked = luaC_white(g); 305 | preinit_thread(L, g); 306 | g->frealloc = f; 307 | g->ud = ud; 308 | g->mainthread = L; 309 | g->seed = makeseed(L); 310 | g->gcrunning = 0; /* no GC while building state */ 311 | g->GCestimate = 0; 312 | g->strt.size = g->strt.nuse = 0; 313 | g->strt.hash = NULL; 314 | setnilvalue(&g->l_registry); 315 | luaZ_initbuffer(L, &g->buff); 316 | g->panic = NULL; 317 | g->version = NULL; 318 | g->gcstate = GCSpause; 319 | g->gckind = KGC_NORMAL; 320 | g->allgc = g->finobj = g->tobefnz = g->fixedgc = NULL; 321 | g->sweepgc = NULL; 322 | g->gray = g->grayagain = NULL; 323 | g->weak = g->ephemeron = g->allweak = NULL; 324 | g->twups = NULL; 325 | g->totalbytes = sizeof(LG); 326 | g->GCdebt = 0; 327 | g->gcfinnum = 0; 328 | g->gcpause = LUAI_GCPAUSE; 329 | g->gcstepmul = LUAI_GCMUL; 330 | for (i=0; i < LUA_NUMTAGS; i++) g->mt[i] = NULL; 331 | if (luaD_rawrunprotected(L, f_luaopen, NULL) != LUA_OK) { 332 | /* memory allocation error: free partial state */ 333 | close_state(L); 334 | L = NULL; 335 | } 336 | return L; 337 | } 338 | 339 | 340 | LUA_API void lua_close (lua_State *L) { 341 | L = G(L)->mainthread; /* only the main thread can be closed */ 342 | lua_lock(L); 343 | close_state(L); 344 | } 345 | 346 | 347 | -------------------------------------------------------------------------------- /3rd/lua/src/lstate.h: -------------------------------------------------------------------------------- 1 | /* 2 | ** $Id: lstate.h,v 2.119 2014/10/30 18:53:28 roberto Exp $ 3 | ** Global State 4 | ** See Copyright Notice in lua.h 5 | */ 6 | 7 | #ifndef lstate_h 8 | #define lstate_h 9 | 10 | #include "lua.h" 11 | 12 | #include "lobject.h" 13 | #include "ltm.h" 14 | #include "lzio.h" 15 | 16 | 17 | /* 18 | 19 | ** Some notes about garbage-collected objects: All objects in Lua must 20 | ** be kept somehow accessible until being freed, so all objects always 21 | ** belong to one (and only one) of these lists, using field 'next' of 22 | ** the 'CommonHeader' for the link: 23 | ** 24 | ** 'allgc': all objects not marked for finalization; 25 | ** 'finobj': all objects marked for finalization; 26 | ** 'tobefnz': all objects ready to be finalized; 27 | ** 'fixedgc': all objects that are not to be collected (currently 28 | ** only small strings, such as reserved words). 29 | 30 | */ 31 | 32 | 33 | struct lua_longjmp; /* defined in ldo.c */ 34 | 35 | 36 | 37 | /* extra stack space to handle TM calls and some other extras */ 38 | #define EXTRA_STACK 5 39 | 40 | 41 | #define BASIC_STACK_SIZE (2*LUA_MINSTACK) 42 | 43 | 44 | /* kinds of Garbage Collection */ 45 | #define KGC_NORMAL 0 46 | #define KGC_EMERGENCY 1 /* gc was forced by an allocation failure */ 47 | 48 | 49 | typedef struct stringtable { 50 | TString **hash; 51 | int nuse; /* number of elements */ 52 | int size; 53 | } stringtable; 54 | 55 | 56 | /* 57 | ** Information about a call. 58 | ** When a thread yields, 'func' is adjusted to pretend that the 59 | ** top function has only the yielded values in its stack; in that 60 | ** case, the actual 'func' value is saved in field 'extra'. 61 | ** When a function calls another with a continuation, 'extra' keeps 62 | ** the function index so that, in case of errors, the continuation 63 | ** function can be called with the correct top. 64 | */ 65 | typedef struct CallInfo { 66 | StkId func; /* function index in the stack */ 67 | StkId top; /* top for this function */ 68 | struct CallInfo *previous, *next; /* dynamic call link */ 69 | union { 70 | struct { /* only for Lua functions */ 71 | StkId base; /* base for this function */ 72 | const Instruction *savedpc; 73 | } l; 74 | struct { /* only for C functions */ 75 | lua_KFunction k; /* continuation in case of yields */ 76 | ptrdiff_t old_errfunc; 77 | lua_KContext ctx; /* context info. in case of yields */ 78 | } c; 79 | } u; 80 | ptrdiff_t extra; 81 | short nresults; /* expected number of results from this function */ 82 | lu_byte callstatus; 83 | } CallInfo; 84 | 85 | 86 | /* 87 | ** Bits in CallInfo status 88 | */ 89 | #define CIST_OAH (1<<0) /* original value of 'allowhook' */ 90 | #define CIST_LUA (1<<1) /* call is running a Lua function */ 91 | #define CIST_HOOKED (1<<2) /* call is running a debug hook */ 92 | #define CIST_REENTRY (1<<3) /* call is running on same invocation of 93 | luaV_execute of previous call */ 94 | #define CIST_YPCALL (1<<4) /* call is a yieldable protected call */ 95 | #define CIST_TAIL (1<<5) /* call was tail called */ 96 | #define CIST_HOOKYIELD (1<<6) /* last hook called yielded */ 97 | 98 | #define isLua(ci) ((ci)->callstatus & CIST_LUA) 99 | 100 | /* assume that CIST_OAH has offset 0 and that 'v' is strictly 0/1 */ 101 | #define setoah(st,v) ((st) = ((st) & ~CIST_OAH) | (v)) 102 | #define getoah(st) ((st) & CIST_OAH) 103 | 104 | 105 | /* 106 | ** 'global state', shared by all threads of this state 107 | */ 108 | typedef struct global_State { 109 | lua_Alloc frealloc; /* function to reallocate memory */ 110 | void *ud; /* auxiliary data to 'frealloc' */ 111 | lu_mem totalbytes; /* number of bytes currently allocated - GCdebt */ 112 | l_mem GCdebt; /* bytes allocated not yet compensated by the collector */ 113 | lu_mem GCmemtrav; /* memory traversed by the GC */ 114 | lu_mem GCestimate; /* an estimate of the non-garbage memory in use */ 115 | stringtable strt; /* hash table for strings */ 116 | TValue l_registry; 117 | unsigned int seed; /* randomized seed for hashes */ 118 | lu_byte currentwhite; 119 | lu_byte gcstate; /* state of garbage collector */ 120 | lu_byte gckind; /* kind of GC running */ 121 | lu_byte gcrunning; /* true if GC is running */ 122 | GCObject *allgc; /* list of all collectable objects */ 123 | GCObject **sweepgc; /* current position of sweep in list */ 124 | GCObject *finobj; /* list of collectable objects with finalizers */ 125 | GCObject *gray; /* list of gray objects */ 126 | GCObject *grayagain; /* list of objects to be traversed atomically */ 127 | GCObject *weak; /* list of tables with weak values */ 128 | GCObject *ephemeron; /* list of ephemeron tables (weak keys) */ 129 | GCObject *allweak; /* list of all-weak tables */ 130 | GCObject *tobefnz; /* list of userdata to be GC */ 131 | GCObject *fixedgc; /* list of objects not to be collected */ 132 | struct lua_State *twups; /* list of threads with open upvalues */ 133 | Mbuffer buff; /* temporary buffer for string concatenation */ 134 | unsigned int gcfinnum; /* number of finalizers to call in each GC step */ 135 | int gcpause; /* size of pause between successive GCs */ 136 | int gcstepmul; /* GC 'granularity' */ 137 | lua_CFunction panic; /* to be called in unprotected errors */ 138 | struct lua_State *mainthread; 139 | const lua_Number *version; /* pointer to version number */ 140 | TString *memerrmsg; /* memory-error message */ 141 | TString *tmname[TM_N]; /* array with tag-method names */ 142 | struct Table *mt[LUA_NUMTAGS]; /* metatables for basic types */ 143 | } global_State; 144 | 145 | 146 | /* 147 | ** 'per thread' state 148 | */ 149 | struct lua_State { 150 | CommonHeader; 151 | lu_byte status; 152 | StkId top; /* first free slot in the stack */ 153 | global_State *l_G; 154 | CallInfo *ci; /* call info for current function */ 155 | const Instruction *oldpc; /* last pc traced */ 156 | StkId stack_last; /* last free slot in the stack */ 157 | StkId stack; /* stack base */ 158 | UpVal *openupval; /* list of open upvalues in this stack */ 159 | GCObject *gclist; 160 | struct lua_State *twups; /* list of threads with open upvalues */ 161 | struct lua_longjmp *errorJmp; /* current error recover point */ 162 | CallInfo base_ci; /* CallInfo for first level (C calling Lua) */ 163 | lua_Hook hook; 164 | ptrdiff_t errfunc; /* current error handling function (stack index) */ 165 | int stacksize; 166 | int basehookcount; 167 | int hookcount; 168 | unsigned short nny; /* number of non-yieldable calls in stack */ 169 | unsigned short nCcalls; /* number of nested C calls */ 170 | lu_byte hookmask; 171 | lu_byte allowhook; 172 | }; 173 | 174 | 175 | #define G(L) (L->l_G) 176 | 177 | 178 | /* 179 | ** Union of all collectable objects (only for conversions) 180 | */ 181 | union GCUnion { 182 | GCObject gc; /* common header */ 183 | struct TString ts; 184 | struct Udata u; 185 | union Closure cl; 186 | struct Table h; 187 | struct Proto p; 188 | struct lua_State th; /* thread */ 189 | }; 190 | 191 | 192 | #define cast_u(o) cast(union GCUnion *, (o)) 193 | 194 | /* macros to convert a GCObject into a specific value */ 195 | #define gco2ts(o) \ 196 | check_exp(novariant((o)->tt) == LUA_TSTRING, &((cast_u(o))->ts)) 197 | #define gco2u(o) check_exp((o)->tt == LUA_TUSERDATA, &((cast_u(o))->u)) 198 | #define gco2lcl(o) check_exp((o)->tt == LUA_TLCL, &((cast_u(o))->cl.l)) 199 | #define gco2ccl(o) check_exp((o)->tt == LUA_TCCL, &((cast_u(o))->cl.c)) 200 | #define gco2cl(o) \ 201 | check_exp(novariant((o)->tt) == LUA_TFUNCTION, &((cast_u(o))->cl)) 202 | #define gco2t(o) check_exp((o)->tt == LUA_TTABLE, &((cast_u(o))->h)) 203 | #define gco2p(o) check_exp((o)->tt == LUA_TPROTO, &((cast_u(o))->p)) 204 | #define gco2th(o) check_exp((o)->tt == LUA_TTHREAD, &((cast_u(o))->th)) 205 | 206 | 207 | /* macro to convert a Lua object into a GCObject */ 208 | #define obj2gco(v) \ 209 | check_exp(novariant((v)->tt) < LUA_TDEADKEY, (&(cast_u(v)->gc))) 210 | 211 | 212 | /* actual number of total bytes allocated */ 213 | #define gettotalbytes(g) ((g)->totalbytes + (g)->GCdebt) 214 | 215 | LUAI_FUNC void luaE_setdebt (global_State *g, l_mem debt); 216 | LUAI_FUNC void luaE_freethread (lua_State *L, lua_State *L1); 217 | LUAI_FUNC CallInfo *luaE_extendCI (lua_State *L); 218 | LUAI_FUNC void luaE_freeCI (lua_State *L); 219 | LUAI_FUNC void luaE_shrinkCI (lua_State *L); 220 | 221 | 222 | #endif 223 | 224 | -------------------------------------------------------------------------------- /3rd/lua/src/lstring.c: -------------------------------------------------------------------------------- 1 | /* 2 | ** $Id: lstring.c,v 2.45 2014/11/02 19:19:04 roberto Exp $ 3 | ** String table (keeps all strings handled by Lua) 4 | ** See Copyright Notice in lua.h 5 | */ 6 | 7 | #define lstring_c 8 | #define LUA_CORE 9 | 10 | #include "lprefix.h" 11 | 12 | 13 | #include 14 | 15 | #include "lua.h" 16 | 17 | #include "ldebug.h" 18 | #include "ldo.h" 19 | #include "lmem.h" 20 | #include "lobject.h" 21 | #include "lstate.h" 22 | #include "lstring.h" 23 | 24 | 25 | 26 | /* 27 | ** Lua will use at most ~(2^LUAI_HASHLIMIT) bytes from a string to 28 | ** compute its hash 29 | */ 30 | #if !defined(LUAI_HASHLIMIT) 31 | #define LUAI_HASHLIMIT 5 32 | #endif 33 | 34 | 35 | /* 36 | ** equality for long strings 37 | */ 38 | int luaS_eqlngstr (TString *a, TString *b) { 39 | size_t len = a->len; 40 | lua_assert(a->tt == LUA_TLNGSTR && b->tt == LUA_TLNGSTR); 41 | return (a == b) || /* same instance or... */ 42 | ((len == b->len) && /* equal length and ... */ 43 | (memcmp(getstr(a), getstr(b), len) == 0)); /* equal contents */ 44 | } 45 | 46 | 47 | unsigned int luaS_hash (const char *str, size_t l, unsigned int seed) { 48 | unsigned int h = seed ^ cast(unsigned int, l); 49 | size_t l1; 50 | size_t step = (l >> LUAI_HASHLIMIT) + 1; 51 | for (l1 = l; l1 >= step; l1 -= step) 52 | h = h ^ ((h<<5) + (h>>2) + cast_byte(str[l1 - 1])); 53 | return h; 54 | } 55 | 56 | 57 | /* 58 | ** resizes the string table 59 | */ 60 | void luaS_resize (lua_State *L, int newsize) { 61 | int i; 62 | stringtable *tb = &G(L)->strt; 63 | if (newsize > tb->size) { /* grow table if needed */ 64 | luaM_reallocvector(L, tb->hash, tb->size, newsize, TString *); 65 | for (i = tb->size; i < newsize; i++) 66 | tb->hash[i] = NULL; 67 | } 68 | for (i = 0; i < tb->size; i++) { /* rehash */ 69 | TString *p = tb->hash[i]; 70 | tb->hash[i] = NULL; 71 | while (p) { /* for each node in the list */ 72 | TString *hnext = p->hnext; /* save next */ 73 | unsigned int h = lmod(p->hash, newsize); /* new position */ 74 | p->hnext = tb->hash[h]; /* chain it */ 75 | tb->hash[h] = p; 76 | p = hnext; 77 | } 78 | } 79 | if (newsize < tb->size) { /* shrink table if needed */ 80 | /* vanishing slice should be empty */ 81 | lua_assert(tb->hash[newsize] == NULL && tb->hash[tb->size - 1] == NULL); 82 | luaM_reallocvector(L, tb->hash, tb->size, newsize, TString *); 83 | } 84 | tb->size = newsize; 85 | } 86 | 87 | 88 | 89 | /* 90 | ** creates a new string object 91 | */ 92 | static TString *createstrobj (lua_State *L, const char *str, size_t l, 93 | int tag, unsigned int h) { 94 | TString *ts; 95 | GCObject *o; 96 | size_t totalsize; /* total size of TString object */ 97 | totalsize = sizelstring(l); 98 | o = luaC_newobj(L, tag, totalsize); 99 | ts = gco2ts(o); 100 | ts->len = l; 101 | ts->hash = h; 102 | ts->extra = 0; 103 | memcpy(getaddrstr(ts), str, l * sizeof(char)); 104 | getaddrstr(ts)[l] = '\0'; /* ending 0 */ 105 | return ts; 106 | } 107 | 108 | 109 | void luaS_remove (lua_State *L, TString *ts) { 110 | stringtable *tb = &G(L)->strt; 111 | TString **p = &tb->hash[lmod(ts->hash, tb->size)]; 112 | while (*p != ts) /* find previous element */ 113 | p = &(*p)->hnext; 114 | *p = (*p)->hnext; /* remove element from its list */ 115 | tb->nuse--; 116 | } 117 | 118 | 119 | /* 120 | ** checks whether short string exists and reuses it or creates a new one 121 | */ 122 | static TString *internshrstr (lua_State *L, const char *str, size_t l) { 123 | TString *ts; 124 | global_State *g = G(L); 125 | unsigned int h = luaS_hash(str, l, g->seed); 126 | TString **list = &g->strt.hash[lmod(h, g->strt.size)]; 127 | for (ts = *list; ts != NULL; ts = ts->hnext) { 128 | if (l == ts->len && 129 | (memcmp(str, getstr(ts), l * sizeof(char)) == 0)) { 130 | /* found! */ 131 | if (isdead(g, ts)) /* dead (but not collected yet)? */ 132 | changewhite(ts); /* resurrect it */ 133 | return ts; 134 | } 135 | } 136 | if (g->strt.nuse >= g->strt.size && g->strt.size <= MAX_INT/2) { 137 | luaS_resize(L, g->strt.size * 2); 138 | list = &g->strt.hash[lmod(h, g->strt.size)]; /* recompute with new size */ 139 | } 140 | ts = createstrobj(L, str, l, LUA_TSHRSTR, h); 141 | ts->hnext = *list; 142 | *list = ts; 143 | g->strt.nuse++; 144 | return ts; 145 | } 146 | 147 | 148 | /* 149 | ** new string (with explicit length) 150 | */ 151 | TString *luaS_newlstr (lua_State *L, const char *str, size_t l) { 152 | if (l <= LUAI_MAXSHORTLEN) /* short string? */ 153 | return internshrstr(L, str, l); 154 | else { 155 | if (l + 1 > (MAX_SIZE - sizeof(TString))/sizeof(char)) 156 | luaM_toobig(L); 157 | return createstrobj(L, str, l, LUA_TLNGSTR, G(L)->seed); 158 | } 159 | } 160 | 161 | 162 | /* 163 | ** new zero-terminated string 164 | */ 165 | TString *luaS_new (lua_State *L, const char *str) { 166 | return luaS_newlstr(L, str, strlen(str)); 167 | } 168 | 169 | 170 | Udata *luaS_newudata (lua_State *L, size_t s) { 171 | Udata *u; 172 | GCObject *o; 173 | if (s > MAX_SIZE - sizeof(Udata)) 174 | luaM_toobig(L); 175 | o = luaC_newobj(L, LUA_TUSERDATA, sizeludata(s)); 176 | u = gco2u(o); 177 | u->len = s; 178 | u->metatable = NULL; 179 | setuservalue(L, u, luaO_nilobject); 180 | return u; 181 | } 182 | 183 | -------------------------------------------------------------------------------- /3rd/lua/src/lstring.h: -------------------------------------------------------------------------------- 1 | /* 2 | ** $Id: lstring.h,v 1.56 2014/07/18 14:46:47 roberto Exp $ 3 | ** String table (keep all strings handled by Lua) 4 | ** See Copyright Notice in lua.h 5 | */ 6 | 7 | #ifndef lstring_h 8 | #define lstring_h 9 | 10 | #include "lgc.h" 11 | #include "lobject.h" 12 | #include "lstate.h" 13 | 14 | 15 | #define sizelstring(l) (sizeof(union UTString) + ((l) + 1) * sizeof(char)) 16 | #define sizestring(s) sizelstring((s)->len) 17 | 18 | #define sizeludata(l) (sizeof(union UUdata) + (l)) 19 | #define sizeudata(u) sizeludata((u)->len) 20 | 21 | #define luaS_newliteral(L, s) (luaS_newlstr(L, "" s, \ 22 | (sizeof(s)/sizeof(char))-1)) 23 | 24 | 25 | /* 26 | ** test whether a string is a reserved word 27 | */ 28 | #define isreserved(s) ((s)->tt == LUA_TSHRSTR && (s)->extra > 0) 29 | 30 | 31 | /* 32 | ** equality for short strings, which are always internalized 33 | */ 34 | #define eqshrstr(a,b) check_exp((a)->tt == LUA_TSHRSTR, (a) == (b)) 35 | 36 | 37 | LUAI_FUNC unsigned int luaS_hash (const char *str, size_t l, unsigned int seed); 38 | LUAI_FUNC int luaS_eqlngstr (TString *a, TString *b); 39 | LUAI_FUNC void luaS_resize (lua_State *L, int newsize); 40 | LUAI_FUNC void luaS_remove (lua_State *L, TString *ts); 41 | LUAI_FUNC Udata *luaS_newudata (lua_State *L, size_t s); 42 | LUAI_FUNC TString *luaS_newlstr (lua_State *L, const char *str, size_t l); 43 | LUAI_FUNC TString *luaS_new (lua_State *L, const char *str); 44 | 45 | 46 | #endif 47 | -------------------------------------------------------------------------------- /3rd/lua/src/ltable.h: -------------------------------------------------------------------------------- 1 | /* 2 | ** $Id: ltable.h,v 2.20 2014/09/04 18:15:29 roberto Exp $ 3 | ** Lua tables (hash) 4 | ** See Copyright Notice in lua.h 5 | */ 6 | 7 | #ifndef ltable_h 8 | #define ltable_h 9 | 10 | #include "lobject.h" 11 | 12 | 13 | #define gnode(t,i) (&(t)->node[i]) 14 | #define gval(n) (&(n)->i_val) 15 | #define gnext(n) ((n)->i_key.nk.next) 16 | 17 | 18 | /* 'const' to avoid wrong writings that can mess up field 'next' */ 19 | #define gkey(n) cast(const TValue*, (&(n)->i_key.tvk)) 20 | 21 | #define wgkey(n) (&(n)->i_key.nk) 22 | 23 | #define invalidateTMcache(t) ((t)->flags = 0) 24 | 25 | 26 | /* returns the key, given the value of a table entry */ 27 | #define keyfromval(v) \ 28 | (gkey(cast(Node *, cast(char *, (v)) - offsetof(Node, i_val)))) 29 | 30 | 31 | LUAI_FUNC const TValue *luaH_getint (Table *t, lua_Integer key); 32 | LUAI_FUNC void luaH_setint (lua_State *L, Table *t, lua_Integer key, 33 | TValue *value); 34 | LUAI_FUNC const TValue *luaH_getstr (Table *t, TString *key); 35 | LUAI_FUNC const TValue *luaH_get (Table *t, const TValue *key); 36 | LUAI_FUNC TValue *luaH_newkey (lua_State *L, Table *t, const TValue *key); 37 | LUAI_FUNC TValue *luaH_set (lua_State *L, Table *t, const TValue *key); 38 | LUAI_FUNC Table *luaH_new (lua_State *L); 39 | LUAI_FUNC void luaH_resize (lua_State *L, Table *t, unsigned int nasize, 40 | unsigned int nhsize); 41 | LUAI_FUNC void luaH_resizearray (lua_State *L, Table *t, unsigned int nasize); 42 | LUAI_FUNC void luaH_free (lua_State *L, Table *t); 43 | LUAI_FUNC int luaH_next (lua_State *L, Table *t, StkId key); 44 | LUAI_FUNC int luaH_getn (Table *t); 45 | 46 | 47 | #if defined(LUA_DEBUG) 48 | LUAI_FUNC Node *luaH_mainposition (const Table *t, const TValue *key); 49 | LUAI_FUNC int luaH_isdummy (Node *n); 50 | #endif 51 | 52 | 53 | #endif 54 | -------------------------------------------------------------------------------- /3rd/lua/src/ltablib.c: -------------------------------------------------------------------------------- 1 | /* 2 | ** $Id: ltablib.c,v 1.79 2014/11/02 19:19:04 roberto Exp $ 3 | ** Library for Table Manipulation 4 | ** See Copyright Notice in lua.h 5 | */ 6 | 7 | #define ltablib_c 8 | #define LUA_LIB 9 | 10 | #include "lprefix.h" 11 | 12 | 13 | #include 14 | #include 15 | 16 | #include "lua.h" 17 | 18 | #include "lauxlib.h" 19 | #include "lualib.h" 20 | 21 | 22 | 23 | /* 24 | ** Structure with table-access functions 25 | */ 26 | typedef struct { 27 | int (*geti) (lua_State *L, int idx, lua_Integer n); 28 | void (*seti) (lua_State *L, int idx, lua_Integer n); 29 | } TabA; 30 | 31 | 32 | /* 33 | ** Check that 'arg' has a table and set access functions in 'ta' to raw 34 | ** or non-raw according to the presence of corresponding metamethods. 35 | */ 36 | static void checktab (lua_State *L, int arg, TabA *ta) { 37 | ta->geti = NULL; ta->seti = NULL; 38 | if (lua_getmetatable(L, arg)) { 39 | lua_pushliteral(L, "__index"); /* 'index' metamethod */ 40 | if (lua_rawget(L, -2) != LUA_TNIL) 41 | ta->geti = lua_geti; 42 | lua_pushliteral(L, "__newindex"); /* 'newindex' metamethod */ 43 | if (lua_rawget(L, -3) != LUA_TNIL) 44 | ta->seti = lua_seti; 45 | lua_pop(L, 3); /* pop metatable plus both metamethods */ 46 | } 47 | if (ta->geti == NULL || ta->seti == NULL) { 48 | luaL_checktype(L, arg, LUA_TTABLE); /* must be table for raw methods */ 49 | if (ta->geti == NULL) ta->geti = lua_rawgeti; 50 | if (ta->seti == NULL) ta->seti = lua_rawseti; 51 | } 52 | } 53 | 54 | 55 | #define aux_getn(L,n,ta) (checktab(L, n, ta), luaL_len(L, n)) 56 | 57 | 58 | #if defined(LUA_COMPAT_MAXN) 59 | static int maxn (lua_State *L) { 60 | lua_Number max = 0; 61 | luaL_checktype(L, 1, LUA_TTABLE); 62 | lua_pushnil(L); /* first key */ 63 | while (lua_next(L, 1)) { 64 | lua_pop(L, 1); /* remove value */ 65 | if (lua_type(L, -1) == LUA_TNUMBER) { 66 | lua_Number v = lua_tonumber(L, -1); 67 | if (v > max) max = v; 68 | } 69 | } 70 | lua_pushnumber(L, max); 71 | return 1; 72 | } 73 | #endif 74 | 75 | 76 | static int tinsert (lua_State *L) { 77 | TabA ta; 78 | lua_Integer e = aux_getn(L, 1, &ta) + 1; /* first empty element */ 79 | lua_Integer pos; /* where to insert new element */ 80 | switch (lua_gettop(L)) { 81 | case 2: { /* called with only 2 arguments */ 82 | pos = e; /* insert new element at the end */ 83 | break; 84 | } 85 | case 3: { 86 | lua_Integer i; 87 | pos = luaL_checkinteger(L, 2); /* 2nd argument is the position */ 88 | luaL_argcheck(L, 1 <= pos && pos <= e, 2, "position out of bounds"); 89 | for (i = e; i > pos; i--) { /* move up elements */ 90 | (*ta.geti)(L, 1, i - 1); 91 | (*ta.seti)(L, 1, i); /* t[i] = t[i - 1] */ 92 | } 93 | break; 94 | } 95 | default: { 96 | return luaL_error(L, "wrong number of arguments to 'insert'"); 97 | } 98 | } 99 | (*ta.seti)(L, 1, pos); /* t[pos] = v */ 100 | return 0; 101 | } 102 | 103 | 104 | static int tremove (lua_State *L) { 105 | TabA ta; 106 | lua_Integer size = aux_getn(L, 1, &ta); 107 | lua_Integer pos = luaL_optinteger(L, 2, size); 108 | if (pos != size) /* validate 'pos' if given */ 109 | luaL_argcheck(L, 1 <= pos && pos <= size + 1, 1, "position out of bounds"); 110 | (*ta.geti)(L, 1, pos); /* result = t[pos] */ 111 | for ( ; pos < size; pos++) { 112 | (*ta.geti)(L, 1, pos + 1); 113 | (*ta.seti)(L, 1, pos); /* t[pos] = t[pos + 1] */ 114 | } 115 | lua_pushnil(L); 116 | (*ta.seti)(L, 1, pos); /* t[pos] = nil */ 117 | return 1; 118 | } 119 | 120 | 121 | static int tmove (lua_State *L) { 122 | TabA ta; 123 | lua_Integer f = luaL_checkinteger(L, 2); 124 | lua_Integer e = luaL_checkinteger(L, 3); 125 | lua_Integer t = luaL_checkinteger(L, 4); 126 | int tt = !lua_isnoneornil(L, 5) ? 5 : 1; /* destination table */ 127 | /* the following restriction avoids several problems with overflows */ 128 | luaL_argcheck(L, f > 0, 2, "initial position must be positive"); 129 | if (e >= f) { /* otherwise, nothing to move */ 130 | lua_Integer n, i; 131 | ta.geti = (luaL_getmetafield(L, 1, "__index") == LUA_TNIL) 132 | ? (luaL_checktype(L, 1, LUA_TTABLE), lua_rawgeti) 133 | : lua_geti; 134 | ta.seti = (luaL_getmetafield(L, tt, "__newindex") == LUA_TNIL) 135 | ? (luaL_checktype(L, tt, LUA_TTABLE), lua_rawseti) 136 | : lua_seti; 137 | n = e - f + 1; /* number of elements to move */ 138 | if (t > f) { 139 | for (i = n - 1; i >= 0; i--) { 140 | (*ta.geti)(L, 1, f + i); 141 | (*ta.seti)(L, tt, t + i); 142 | } 143 | } 144 | else { 145 | for (i = 0; i < n; i++) { 146 | (*ta.geti)(L, 1, f + i); 147 | (*ta.seti)(L, tt, t + i); 148 | } 149 | } 150 | } 151 | lua_pushvalue(L, tt); /* return "to table" */ 152 | return 1; 153 | } 154 | 155 | 156 | static void addfield (lua_State *L, luaL_Buffer *b, TabA *ta, lua_Integer i) { 157 | (*ta->geti)(L, 1, i); 158 | if (!lua_isstring(L, -1)) 159 | luaL_error(L, "invalid value (%s) at index %d in table for 'concat'", 160 | luaL_typename(L, -1), i); 161 | luaL_addvalue(b); 162 | } 163 | 164 | 165 | static int tconcat (lua_State *L) { 166 | TabA ta; 167 | luaL_Buffer b; 168 | size_t lsep; 169 | lua_Integer i, last; 170 | const char *sep = luaL_optlstring(L, 2, "", &lsep); 171 | checktab(L, 1, &ta); 172 | i = luaL_optinteger(L, 3, 1); 173 | last = luaL_opt(L, luaL_checkinteger, 4, luaL_len(L, 1)); 174 | luaL_buffinit(L, &b); 175 | for (; i < last; i++) { 176 | addfield(L, &b, &ta, i); 177 | luaL_addlstring(&b, sep, lsep); 178 | } 179 | if (i == last) /* add last value (if interval was not empty) */ 180 | addfield(L, &b, &ta, i); 181 | luaL_pushresult(&b); 182 | return 1; 183 | } 184 | 185 | 186 | /* 187 | ** {====================================================== 188 | ** Pack/unpack 189 | ** ======================================================= 190 | */ 191 | 192 | static int pack (lua_State *L) { 193 | int i; 194 | int n = lua_gettop(L); /* number of elements to pack */ 195 | lua_createtable(L, n, 1); /* create result table */ 196 | lua_insert(L, 1); /* put it at index 1 */ 197 | for (i = n; i >= 1; i--) /* assign elements */ 198 | lua_rawseti(L, 1, i); 199 | lua_pushinteger(L, n); 200 | lua_setfield(L, 1, "n"); /* t.n = number of elements */ 201 | return 1; /* return table */ 202 | } 203 | 204 | 205 | static int unpack (lua_State *L) { 206 | TabA ta; 207 | lua_Integer i, e; 208 | lua_Unsigned n; 209 | checktab(L, 1, &ta); 210 | i = luaL_optinteger(L, 2, 1); 211 | e = luaL_opt(L, luaL_checkinteger, 3, luaL_len(L, 1)); 212 | if (i > e) return 0; /* empty range */ 213 | n = (lua_Unsigned)e - i; /* number of elements minus 1 (avoid overflows) */ 214 | if (n >= (unsigned int)INT_MAX || !lua_checkstack(L, (int)(++n))) 215 | return luaL_error(L, "too many results to unpack"); 216 | do { /* must have at least one element */ 217 | (*ta.geti)(L, 1, i); /* push arg[i..e] */ 218 | } while (i++ < e); 219 | 220 | return (int)n; 221 | } 222 | 223 | /* }====================================================== */ 224 | 225 | 226 | 227 | /* 228 | ** {====================================================== 229 | ** Quicksort 230 | ** (based on 'Algorithms in MODULA-3', Robert Sedgewick; 231 | ** Addison-Wesley, 1993.) 232 | ** ======================================================= 233 | */ 234 | 235 | 236 | static void set2 (lua_State *L, TabA *ta, int i, int j) { 237 | (*ta->seti)(L, 1, i); 238 | (*ta->seti)(L, 1, j); 239 | } 240 | 241 | static int sort_comp (lua_State *L, int a, int b) { 242 | if (!lua_isnil(L, 2)) { /* function? */ 243 | int res; 244 | lua_pushvalue(L, 2); 245 | lua_pushvalue(L, a-1); /* -1 to compensate function */ 246 | lua_pushvalue(L, b-2); /* -2 to compensate function and 'a' */ 247 | lua_call(L, 2, 1); 248 | res = lua_toboolean(L, -1); 249 | lua_pop(L, 1); 250 | return res; 251 | } 252 | else /* a < b? */ 253 | return lua_compare(L, a, b, LUA_OPLT); 254 | } 255 | 256 | static void auxsort (lua_State *L, TabA *ta, int l, int u) { 257 | while (l < u) { /* for tail recursion */ 258 | int i, j; 259 | /* sort elements a[l], a[(l+u)/2] and a[u] */ 260 | (*ta->geti)(L, 1, l); 261 | (*ta->geti)(L, 1, u); 262 | if (sort_comp(L, -1, -2)) /* a[u] < a[l]? */ 263 | set2(L, ta, l, u); /* swap a[l] - a[u] */ 264 | else 265 | lua_pop(L, 2); 266 | if (u-l == 1) break; /* only 2 elements */ 267 | i = (l+u)/2; 268 | (*ta->geti)(L, 1, i); 269 | (*ta->geti)(L, 1, l); 270 | if (sort_comp(L, -2, -1)) /* a[i]geti)(L, 1, u); 275 | if (sort_comp(L, -1, -2)) /* a[u]geti)(L, 1, i); /* Pivot */ 282 | lua_pushvalue(L, -1); 283 | (*ta->geti)(L, 1, u-1); 284 | set2(L, ta, i, u-1); 285 | /* a[l] <= P == a[u-1] <= a[u], only need to sort from l+1 to u-2 */ 286 | i = l; j = u-1; 287 | for (;;) { /* invariant: a[l..i] <= P <= a[j..u] */ 288 | /* repeat ++i until a[i] >= P */ 289 | while ((*ta->geti)(L, 1, ++i), sort_comp(L, -1, -2)) { 290 | if (i>=u) luaL_error(L, "invalid order function for sorting"); 291 | lua_pop(L, 1); /* remove a[i] */ 292 | } 293 | /* repeat --j until a[j] <= P */ 294 | while ((*ta->geti)(L, 1, --j), sort_comp(L, -3, -1)) { 295 | if (j<=l) luaL_error(L, "invalid order function for sorting"); 296 | lua_pop(L, 1); /* remove a[j] */ 297 | } 298 | if (jgeti)(L, 1, u-1); 305 | (*ta->geti)(L, 1, i); 306 | set2(L, ta, u-1, i); /* swap pivot (a[u-1]) with a[i] */ 307 | /* a[l..i-1] <= a[i] == P <= a[i+1..u] */ 308 | /* adjust so that smaller half is in [j..i] and larger one in [l..u] */ 309 | if (i-l < u-i) { 310 | j=l; i=i-1; l=i+2; 311 | } 312 | else { 313 | j=i+1; i=u; u=j-2; 314 | } 315 | auxsort(L, ta, j, i); /* call recursively the smaller one */ 316 | } /* repeat the routine for the larger one */ 317 | } 318 | 319 | static int sort (lua_State *L) { 320 | TabA ta; 321 | int n = (int)aux_getn(L, 1, &ta); 322 | luaL_checkstack(L, 50, ""); /* assume array is smaller than 2^50 */ 323 | if (!lua_isnoneornil(L, 2)) /* is there a 2nd argument? */ 324 | luaL_checktype(L, 2, LUA_TFUNCTION); 325 | lua_settop(L, 2); /* make sure there are two arguments */ 326 | auxsort(L, &ta, 1, n); 327 | return 0; 328 | } 329 | 330 | /* }====================================================== */ 331 | 332 | 333 | static const luaL_Reg tab_funcs[] = { 334 | {"concat", tconcat}, 335 | #if defined(LUA_COMPAT_MAXN) 336 | {"maxn", maxn}, 337 | #endif 338 | {"insert", tinsert}, 339 | {"pack", pack}, 340 | {"unpack", unpack}, 341 | {"remove", tremove}, 342 | {"move", tmove}, 343 | {"sort", sort}, 344 | {NULL, NULL} 345 | }; 346 | 347 | 348 | LUAMOD_API int luaopen_table (lua_State *L) { 349 | luaL_newlib(L, tab_funcs); 350 | #if defined(LUA_COMPAT_UNPACK) 351 | /* _G.unpack = table.unpack */ 352 | lua_getfield(L, -1, "unpack"); 353 | lua_setglobal(L, "unpack"); 354 | #endif 355 | return 1; 356 | } 357 | 358 | -------------------------------------------------------------------------------- /3rd/lua/src/ltm.c: -------------------------------------------------------------------------------- 1 | /* 2 | ** $Id: ltm.c,v 2.33 2014/11/21 12:15:57 roberto Exp $ 3 | ** Tag methods 4 | ** See Copyright Notice in lua.h 5 | */ 6 | 7 | #define ltm_c 8 | #define LUA_CORE 9 | 10 | #include "lprefix.h" 11 | 12 | 13 | #include 14 | 15 | #include "lua.h" 16 | 17 | #include "ldebug.h" 18 | #include "ldo.h" 19 | #include "lobject.h" 20 | #include "lstate.h" 21 | #include "lstring.h" 22 | #include "ltable.h" 23 | #include "ltm.h" 24 | #include "lvm.h" 25 | 26 | 27 | static const char udatatypename[] = "userdata"; 28 | 29 | LUAI_DDEF const char *const luaT_typenames_[LUA_TOTALTAGS] = { 30 | "no value", 31 | "nil", "boolean", udatatypename, "number", 32 | "string", "table", "function", udatatypename, "thread", 33 | "proto" /* this last case is used for tests only */ 34 | }; 35 | 36 | 37 | void luaT_init (lua_State *L) { 38 | static const char *const luaT_eventname[] = { /* ORDER TM */ 39 | "__index", "__newindex", 40 | "__gc", "__mode", "__len", "__eq", 41 | "__add", "__sub", "__mul", "__mod", "__pow", 42 | "__div", "__idiv", 43 | "__band", "__bor", "__bxor", "__shl", "__shr", 44 | "__unm", "__bnot", "__lt", "__le", 45 | "__concat", "__call" 46 | }; 47 | int i; 48 | for (i=0; itmname[i] = luaS_new(L, luaT_eventname[i]); 50 | luaC_fix(L, obj2gco(G(L)->tmname[i])); /* never collect these names */ 51 | } 52 | } 53 | 54 | 55 | /* 56 | ** function to be used with macro "fasttm": optimized for absence of 57 | ** tag methods 58 | */ 59 | const TValue *luaT_gettm (Table *events, TMS event, TString *ename) { 60 | const TValue *tm = luaH_getstr(events, ename); 61 | lua_assert(event <= TM_EQ); 62 | if (ttisnil(tm)) { /* no tag method? */ 63 | events->flags |= cast_byte(1u<metatable; 75 | break; 76 | case LUA_TUSERDATA: 77 | mt = uvalue(o)->metatable; 78 | break; 79 | default: 80 | mt = G(L)->mt[ttnov(o)]; 81 | } 82 | return (mt ? luaH_getstr(mt, G(L)->tmname[event]) : luaO_nilobject); 83 | } 84 | 85 | 86 | void luaT_callTM (lua_State *L, const TValue *f, const TValue *p1, 87 | const TValue *p2, TValue *p3, int hasres) { 88 | ptrdiff_t result = savestack(L, p3); 89 | setobj2s(L, L->top++, f); /* push function (assume EXTRA_STACK) */ 90 | setobj2s(L, L->top++, p1); /* 1st argument */ 91 | setobj2s(L, L->top++, p2); /* 2nd argument */ 92 | if (!hasres) /* no result? 'p3' is third argument */ 93 | setobj2s(L, L->top++, p3); /* 3rd argument */ 94 | /* metamethod may yield only when called from Lua code */ 95 | luaD_call(L, L->top - (4 - hasres), hasres, isLua(L->ci)); 96 | if (hasres) { /* if has result, move it to its place */ 97 | p3 = restorestack(L, result); 98 | setobjs2s(L, p3, --L->top); 99 | } 100 | } 101 | 102 | 103 | int luaT_callbinTM (lua_State *L, const TValue *p1, const TValue *p2, 104 | StkId res, TMS event) { 105 | const TValue *tm = luaT_gettmbyobj(L, p1, event); /* try first operand */ 106 | if (ttisnil(tm)) 107 | tm = luaT_gettmbyobj(L, p2, event); /* try second operand */ 108 | if (ttisnil(tm)) return 0; 109 | luaT_callTM(L, tm, p1, p2, res, 1); 110 | return 1; 111 | } 112 | 113 | 114 | void luaT_trybinTM (lua_State *L, const TValue *p1, const TValue *p2, 115 | StkId res, TMS event) { 116 | if (!luaT_callbinTM(L, p1, p2, res, event)) { 117 | switch (event) { 118 | case TM_CONCAT: 119 | luaG_concaterror(L, p1, p2); 120 | case TM_BAND: case TM_BOR: case TM_BXOR: 121 | case TM_SHL: case TM_SHR: case TM_BNOT: { 122 | lua_Number dummy; 123 | if (tonumber(p1, &dummy) && tonumber(p2, &dummy)) 124 | luaG_tointerror(L, p1, p2); 125 | else 126 | luaG_opinterror(L, p1, p2, "perform bitwise operation on"); 127 | /* else go through */ 128 | } 129 | default: 130 | luaG_opinterror(L, p1, p2, "perform arithmetic on"); 131 | } 132 | } 133 | } 134 | 135 | 136 | int luaT_callorderTM (lua_State *L, const TValue *p1, const TValue *p2, 137 | TMS event) { 138 | if (!luaT_callbinTM(L, p1, p2, L->top, event)) 139 | return -1; /* no metamethod */ 140 | else 141 | return !l_isfalse(L->top); 142 | } 143 | 144 | -------------------------------------------------------------------------------- /3rd/lua/src/ltm.h: -------------------------------------------------------------------------------- 1 | /* 2 | ** $Id: ltm.h,v 2.21 2014/10/25 11:50:46 roberto Exp $ 3 | ** Tag methods 4 | ** See Copyright Notice in lua.h 5 | */ 6 | 7 | #ifndef ltm_h 8 | #define ltm_h 9 | 10 | 11 | #include "lobject.h" 12 | 13 | 14 | /* 15 | * WARNING: if you change the order of this enumeration, 16 | * grep "ORDER TM" and "ORDER OP" 17 | */ 18 | typedef enum { 19 | TM_INDEX, 20 | TM_NEWINDEX, 21 | TM_GC, 22 | TM_MODE, 23 | TM_LEN, 24 | TM_EQ, /* last tag method with fast access */ 25 | TM_ADD, 26 | TM_SUB, 27 | TM_MUL, 28 | TM_MOD, 29 | TM_POW, 30 | TM_DIV, 31 | TM_IDIV, 32 | TM_BAND, 33 | TM_BOR, 34 | TM_BXOR, 35 | TM_SHL, 36 | TM_SHR, 37 | TM_UNM, 38 | TM_BNOT, 39 | TM_LT, 40 | TM_LE, 41 | TM_CONCAT, 42 | TM_CALL, 43 | TM_N /* number of elements in the enum */ 44 | } TMS; 45 | 46 | 47 | 48 | #define gfasttm(g,et,e) ((et) == NULL ? NULL : \ 49 | ((et)->flags & (1u<<(e))) ? NULL : luaT_gettm(et, e, (g)->tmname[e])) 50 | 51 | #define fasttm(l,et,e) gfasttm(G(l), et, e) 52 | 53 | #define ttypename(x) luaT_typenames_[(x) + 1] 54 | #define objtypename(x) ttypename(ttnov(x)) 55 | 56 | LUAI_DDEC const char *const luaT_typenames_[LUA_TOTALTAGS]; 57 | 58 | 59 | LUAI_FUNC const TValue *luaT_gettm (Table *events, TMS event, TString *ename); 60 | LUAI_FUNC const TValue *luaT_gettmbyobj (lua_State *L, const TValue *o, 61 | TMS event); 62 | LUAI_FUNC void luaT_init (lua_State *L); 63 | 64 | LUAI_FUNC void luaT_callTM (lua_State *L, const TValue *f, const TValue *p1, 65 | const TValue *p2, TValue *p3, int hasres); 66 | LUAI_FUNC int luaT_callbinTM (lua_State *L, const TValue *p1, const TValue *p2, 67 | StkId res, TMS event); 68 | LUAI_FUNC void luaT_trybinTM (lua_State *L, const TValue *p1, const TValue *p2, 69 | StkId res, TMS event); 70 | LUAI_FUNC int luaT_callorderTM (lua_State *L, const TValue *p1, 71 | const TValue *p2, TMS event); 72 | 73 | 74 | 75 | #endif 76 | -------------------------------------------------------------------------------- /3rd/lua/src/lua: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/linxiaolong/lua-kcp/367284d8e46686a5c9d3985e0abdcc9d49e1ecc2/3rd/lua/src/lua -------------------------------------------------------------------------------- /3rd/lua/src/lua.hpp: -------------------------------------------------------------------------------- 1 | // lua.hpp 2 | // Lua header files for C++ 3 | // <> not supplied automatically because Lua also compiles as C++ 4 | 5 | extern "C" { 6 | #include "lua.h" 7 | #include "lualib.h" 8 | #include "lauxlib.h" 9 | } 10 | -------------------------------------------------------------------------------- /3rd/lua/src/luac: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/linxiaolong/lua-kcp/367284d8e46686a5c9d3985e0abdcc9d49e1ecc2/3rd/lua/src/luac -------------------------------------------------------------------------------- /3rd/lua/src/lualib.h: -------------------------------------------------------------------------------- 1 | /* 2 | ** $Id: lualib.h,v 1.44 2014/02/06 17:32:33 roberto Exp $ 3 | ** Lua standard libraries 4 | ** See Copyright Notice in lua.h 5 | */ 6 | 7 | 8 | #ifndef lualib_h 9 | #define lualib_h 10 | 11 | #include "lua.h" 12 | 13 | 14 | 15 | LUAMOD_API int (luaopen_base) (lua_State *L); 16 | 17 | #define LUA_COLIBNAME "coroutine" 18 | LUAMOD_API int (luaopen_coroutine) (lua_State *L); 19 | 20 | #define LUA_TABLIBNAME "table" 21 | LUAMOD_API int (luaopen_table) (lua_State *L); 22 | 23 | #define LUA_IOLIBNAME "io" 24 | LUAMOD_API int (luaopen_io) (lua_State *L); 25 | 26 | #define LUA_OSLIBNAME "os" 27 | LUAMOD_API int (luaopen_os) (lua_State *L); 28 | 29 | #define LUA_STRLIBNAME "string" 30 | LUAMOD_API int (luaopen_string) (lua_State *L); 31 | 32 | #define LUA_UTF8LIBNAME "utf8" 33 | LUAMOD_API int (luaopen_utf8) (lua_State *L); 34 | 35 | #define LUA_BITLIBNAME "bit32" 36 | LUAMOD_API int (luaopen_bit32) (lua_State *L); 37 | 38 | #define LUA_MATHLIBNAME "math" 39 | LUAMOD_API int (luaopen_math) (lua_State *L); 40 | 41 | #define LUA_DBLIBNAME "debug" 42 | LUAMOD_API int (luaopen_debug) (lua_State *L); 43 | 44 | #define LUA_LOADLIBNAME "package" 45 | LUAMOD_API int (luaopen_package) (lua_State *L); 46 | 47 | 48 | /* open all previous libraries */ 49 | LUALIB_API void (luaL_openlibs) (lua_State *L); 50 | 51 | 52 | 53 | #if !defined(lua_assert) 54 | #define lua_assert(x) ((void)0) 55 | #endif 56 | 57 | 58 | #endif 59 | -------------------------------------------------------------------------------- /3rd/lua/src/lundump.c: -------------------------------------------------------------------------------- 1 | /* 2 | ** $Id: lundump.c,v 2.41 2014/11/02 19:19:04 roberto Exp $ 3 | ** load precompiled Lua chunks 4 | ** See Copyright Notice in lua.h 5 | */ 6 | 7 | #define lundump_c 8 | #define LUA_CORE 9 | 10 | #include "lprefix.h" 11 | 12 | 13 | #include 14 | 15 | #include "lua.h" 16 | 17 | #include "ldebug.h" 18 | #include "ldo.h" 19 | #include "lfunc.h" 20 | #include "lmem.h" 21 | #include "lobject.h" 22 | #include "lstring.h" 23 | #include "lundump.h" 24 | #include "lzio.h" 25 | 26 | 27 | #if !defined(luai_verifycode) 28 | #define luai_verifycode(L,b,f) /* empty */ 29 | #endif 30 | 31 | 32 | typedef struct { 33 | lua_State *L; 34 | ZIO *Z; 35 | Mbuffer *b; 36 | const char *name; 37 | } LoadState; 38 | 39 | 40 | static l_noret error(LoadState *S, const char *why) { 41 | luaO_pushfstring(S->L, "%s: %s precompiled chunk", S->name, why); 42 | luaD_throw(S->L, LUA_ERRSYNTAX); 43 | } 44 | 45 | 46 | /* 47 | ** All high-level loads go through LoadVector; you can change it to 48 | ** adapt to the endianness of the input 49 | */ 50 | #define LoadVector(S,b,n) LoadBlock(S,b,(n)*sizeof((b)[0])) 51 | 52 | static void LoadBlock (LoadState *S, void *b, size_t size) { 53 | if (luaZ_read(S->Z, b, size) != 0) 54 | error(S, "truncated"); 55 | } 56 | 57 | 58 | #define LoadVar(S,x) LoadVector(S,&x,1) 59 | 60 | 61 | static lu_byte LoadByte (LoadState *S) { 62 | lu_byte x; 63 | LoadVar(S, x); 64 | return x; 65 | } 66 | 67 | 68 | static int LoadInt (LoadState *S) { 69 | int x; 70 | LoadVar(S, x); 71 | return x; 72 | } 73 | 74 | 75 | static lua_Number LoadNumber (LoadState *S) { 76 | lua_Number x; 77 | LoadVar(S, x); 78 | return x; 79 | } 80 | 81 | 82 | static lua_Integer LoadInteger (LoadState *S) { 83 | lua_Integer x; 84 | LoadVar(S, x); 85 | return x; 86 | } 87 | 88 | 89 | static TString *LoadString (LoadState *S) { 90 | size_t size = LoadByte(S); 91 | if (size == 0xFF) 92 | LoadVar(S, size); 93 | if (size == 0) 94 | return NULL; 95 | else { 96 | char *s = luaZ_openspace(S->L, S->b, --size); 97 | LoadVector(S, s, size); 98 | return luaS_newlstr(S->L, s, size); 99 | } 100 | } 101 | 102 | 103 | static void LoadCode (LoadState *S, Proto *f) { 104 | int n = LoadInt(S); 105 | f->code = luaM_newvector(S->L, n, Instruction); 106 | f->sizecode = n; 107 | LoadVector(S, f->code, n); 108 | } 109 | 110 | 111 | static void LoadFunction(LoadState *S, Proto *f, TString *psource); 112 | 113 | 114 | static void LoadConstants (LoadState *S, Proto *f) { 115 | int i; 116 | int n = LoadInt(S); 117 | f->k = luaM_newvector(S->L, n, TValue); 118 | f->sizek = n; 119 | for (i = 0; i < n; i++) 120 | setnilvalue(&f->k[i]); 121 | for (i = 0; i < n; i++) { 122 | TValue *o = &f->k[i]; 123 | int t = LoadByte(S); 124 | switch (t) { 125 | case LUA_TNIL: 126 | setnilvalue(o); 127 | break; 128 | case LUA_TBOOLEAN: 129 | setbvalue(o, LoadByte(S)); 130 | break; 131 | case LUA_TNUMFLT: 132 | setfltvalue(o, LoadNumber(S)); 133 | break; 134 | case LUA_TNUMINT: 135 | setivalue(o, LoadInteger(S)); 136 | break; 137 | case LUA_TSHRSTR: 138 | case LUA_TLNGSTR: 139 | setsvalue2n(S->L, o, LoadString(S)); 140 | break; 141 | default: 142 | lua_assert(0); 143 | } 144 | } 145 | } 146 | 147 | 148 | static void LoadProtos (LoadState *S, Proto *f) { 149 | int i; 150 | int n = LoadInt(S); 151 | f->p = luaM_newvector(S->L, n, Proto *); 152 | f->sizep = n; 153 | for (i = 0; i < n; i++) 154 | f->p[i] = NULL; 155 | for (i = 0; i < n; i++) { 156 | f->p[i] = luaF_newproto(S->L); 157 | LoadFunction(S, f->p[i], f->source); 158 | } 159 | } 160 | 161 | 162 | static void LoadUpvalues (LoadState *S, Proto *f) { 163 | int i, n; 164 | n = LoadInt(S); 165 | f->upvalues = luaM_newvector(S->L, n, Upvaldesc); 166 | f->sizeupvalues = n; 167 | for (i = 0; i < n; i++) 168 | f->upvalues[i].name = NULL; 169 | for (i = 0; i < n; i++) { 170 | f->upvalues[i].instack = LoadByte(S); 171 | f->upvalues[i].idx = LoadByte(S); 172 | } 173 | } 174 | 175 | 176 | static void LoadDebug (LoadState *S, Proto *f) { 177 | int i, n; 178 | n = LoadInt(S); 179 | f->lineinfo = luaM_newvector(S->L, n, int); 180 | f->sizelineinfo = n; 181 | LoadVector(S, f->lineinfo, n); 182 | n = LoadInt(S); 183 | f->locvars = luaM_newvector(S->L, n, LocVar); 184 | f->sizelocvars = n; 185 | for (i = 0; i < n; i++) 186 | f->locvars[i].varname = NULL; 187 | for (i = 0; i < n; i++) { 188 | f->locvars[i].varname = LoadString(S); 189 | f->locvars[i].startpc = LoadInt(S); 190 | f->locvars[i].endpc = LoadInt(S); 191 | } 192 | n = LoadInt(S); 193 | for (i = 0; i < n; i++) 194 | f->upvalues[i].name = LoadString(S); 195 | } 196 | 197 | 198 | static void LoadFunction (LoadState *S, Proto *f, TString *psource) { 199 | f->source = LoadString(S); 200 | if (f->source == NULL) /* no source in dump? */ 201 | f->source = psource; /* reuse parent's source */ 202 | f->linedefined = LoadInt(S); 203 | f->lastlinedefined = LoadInt(S); 204 | f->numparams = LoadByte(S); 205 | f->is_vararg = LoadByte(S); 206 | f->maxstacksize = LoadByte(S); 207 | LoadCode(S, f); 208 | LoadConstants(S, f); 209 | LoadUpvalues(S, f); 210 | LoadProtos(S, f); 211 | LoadDebug(S, f); 212 | } 213 | 214 | 215 | static void checkliteral (LoadState *S, const char *s, const char *msg) { 216 | char buff[sizeof(LUA_SIGNATURE) + sizeof(LUAC_DATA)]; /* larger than both */ 217 | size_t len = strlen(s); 218 | LoadVector(S, buff, len); 219 | if (memcmp(s, buff, len) != 0) 220 | error(S, msg); 221 | } 222 | 223 | 224 | static void fchecksize (LoadState *S, size_t size, const char *tname) { 225 | if (LoadByte(S) != size) 226 | error(S, luaO_pushfstring(S->L, "%s size mismatch in", tname)); 227 | } 228 | 229 | 230 | #define checksize(S,t) fchecksize(S,sizeof(t),#t) 231 | 232 | static void checkHeader (LoadState *S) { 233 | checkliteral(S, LUA_SIGNATURE + 1, "not a"); /* 1st char already checked */ 234 | if (LoadByte(S) != LUAC_VERSION) 235 | error(S, "version mismatch in"); 236 | if (LoadByte(S) != LUAC_FORMAT) 237 | error(S, "format mismatch in"); 238 | checkliteral(S, LUAC_DATA, "corrupted"); 239 | checksize(S, int); 240 | checksize(S, size_t); 241 | checksize(S, Instruction); 242 | checksize(S, lua_Integer); 243 | checksize(S, lua_Number); 244 | if (LoadInteger(S) != LUAC_INT) 245 | error(S, "endianness mismatch in"); 246 | if (LoadNumber(S) != LUAC_NUM) 247 | error(S, "float format mismatch in"); 248 | } 249 | 250 | 251 | /* 252 | ** load precompiled chunk 253 | */ 254 | LClosure *luaU_undump(lua_State *L, ZIO *Z, Mbuffer *buff, 255 | const char *name) { 256 | LoadState S; 257 | LClosure *cl; 258 | if (*name == '@' || *name == '=') 259 | S.name = name + 1; 260 | else if (*name == LUA_SIGNATURE[0]) 261 | S.name = "binary string"; 262 | else 263 | S.name = name; 264 | S.L = L; 265 | S.Z = Z; 266 | S.b = buff; 267 | checkHeader(&S); 268 | cl = luaF_newLclosure(L, LoadByte(&S)); 269 | setclLvalue(L, L->top, cl); 270 | incr_top(L); 271 | cl->p = luaF_newproto(L); 272 | LoadFunction(&S, cl->p, NULL); 273 | lua_assert(cl->nupvalues == cl->p->sizeupvalues); 274 | luai_verifycode(L, buff, cl->p); 275 | return cl; 276 | } 277 | 278 | -------------------------------------------------------------------------------- /3rd/lua/src/lundump.h: -------------------------------------------------------------------------------- 1 | /* 2 | ** $Id: lundump.h,v 1.44 2014/06/19 18:27:20 roberto Exp $ 3 | ** load precompiled Lua chunks 4 | ** See Copyright Notice in lua.h 5 | */ 6 | 7 | #ifndef lundump_h 8 | #define lundump_h 9 | 10 | #include "llimits.h" 11 | #include "lobject.h" 12 | #include "lzio.h" 13 | 14 | 15 | /* data to catch conversion errors */ 16 | #define LUAC_DATA "\x19\x93\r\n\x1a\n" 17 | 18 | #define LUAC_INT 0x5678 19 | #define LUAC_NUM cast_num(370.5) 20 | 21 | #define MYINT(s) (s[0]-'0') 22 | #define LUAC_VERSION (MYINT(LUA_VERSION_MAJOR)*16+MYINT(LUA_VERSION_MINOR)) 23 | #define LUAC_FORMAT 0 /* this is the official format */ 24 | 25 | /* load one chunk; from lundump.c */ 26 | LUAI_FUNC LClosure* luaU_undump (lua_State* L, ZIO* Z, Mbuffer* buff, 27 | const char* name); 28 | 29 | /* dump one chunk; from ldump.c */ 30 | LUAI_FUNC int luaU_dump (lua_State* L, const Proto* f, lua_Writer w, 31 | void* data, int strip); 32 | 33 | #endif 34 | -------------------------------------------------------------------------------- /3rd/lua/src/lutf8lib.c: -------------------------------------------------------------------------------- 1 | /* 2 | ** $Id: lutf8lib.c,v 1.13 2014/11/02 19:19:04 roberto Exp $ 3 | ** Standard library for UTF-8 manipulation 4 | ** See Copyright Notice in lua.h 5 | */ 6 | 7 | #define lutf8lib_c 8 | #define LUA_LIB 9 | 10 | #include "lprefix.h" 11 | 12 | 13 | #include 14 | #include 15 | #include 16 | 17 | #include "lua.h" 18 | 19 | #include "lauxlib.h" 20 | #include "lualib.h" 21 | 22 | #define MAXUNICODE 0x10FFFF 23 | 24 | #define iscont(p) ((*(p) & 0xC0) == 0x80) 25 | 26 | 27 | /* from strlib */ 28 | /* translate a relative string position: negative means back from end */ 29 | static lua_Integer u_posrelat (lua_Integer pos, size_t len) { 30 | if (pos >= 0) return pos; 31 | else if (0u - (size_t)pos > len) return 0; 32 | else return (lua_Integer)len + pos + 1; 33 | } 34 | 35 | 36 | /* 37 | ** Decode one UTF-8 sequence, returning NULL if byte sequence is invalid. 38 | */ 39 | static const char *utf8_decode (const char *o, int *val) { 40 | static unsigned int limits[] = {0xFF, 0x7F, 0x7FF, 0xFFFF}; 41 | const unsigned char *s = (const unsigned char *)o; 42 | unsigned int c = s[0]; 43 | unsigned int res = 0; /* final result */ 44 | if (c < 0x80) /* ascii? */ 45 | res = c; 46 | else { 47 | int count = 0; /* to count number of continuation bytes */ 48 | while (c & 0x40) { /* still have continuation bytes? */ 49 | int cc = s[++count]; /* read next byte */ 50 | if ((cc & 0xC0) != 0x80) /* not a continuation byte? */ 51 | return NULL; /* invalid byte sequence */ 52 | res = (res << 6) | (cc & 0x3F); /* add lower 6 bits from cont. byte */ 53 | c <<= 1; /* to test next bit */ 54 | } 55 | res |= ((c & 0x7F) << (count * 5)); /* add first byte */ 56 | if (count > 3 || res > MAXUNICODE || res <= limits[count]) 57 | return NULL; /* invalid byte sequence */ 58 | s += count; /* skip continuation bytes read */ 59 | } 60 | if (val) *val = res; 61 | return (const char *)s + 1; /* +1 to include first byte */ 62 | } 63 | 64 | 65 | /* 66 | ** utf8len(s [, i [, j]]) --> number of characters that start in the 67 | ** range [i,j], or nil + current position if 's' is not well formed in 68 | ** that interval 69 | */ 70 | static int utflen (lua_State *L) { 71 | int n = 0; 72 | size_t len; 73 | const char *s = luaL_checklstring(L, 1, &len); 74 | lua_Integer posi = u_posrelat(luaL_optinteger(L, 2, 1), len); 75 | lua_Integer posj = u_posrelat(luaL_optinteger(L, 3, -1), len); 76 | luaL_argcheck(L, 1 <= posi && --posi <= (lua_Integer)len, 2, 77 | "initial position out of string"); 78 | luaL_argcheck(L, --posj < (lua_Integer)len, 3, 79 | "final position out of string"); 80 | while (posi <= posj) { 81 | const char *s1 = utf8_decode(s + posi, NULL); 82 | if (s1 == NULL) { /* conversion error? */ 83 | lua_pushnil(L); /* return nil ... */ 84 | lua_pushinteger(L, posi + 1); /* ... and current position */ 85 | return 2; 86 | } 87 | posi = s1 - s; 88 | n++; 89 | } 90 | lua_pushinteger(L, n); 91 | return 1; 92 | } 93 | 94 | 95 | /* 96 | ** codepoint(s, [i, [j]]) -> returns codepoints for all characters 97 | ** that start in the range [i,j] 98 | */ 99 | static int codepoint (lua_State *L) { 100 | size_t len; 101 | const char *s = luaL_checklstring(L, 1, &len); 102 | lua_Integer posi = u_posrelat(luaL_optinteger(L, 2, 1), len); 103 | lua_Integer pose = u_posrelat(luaL_optinteger(L, 3, posi), len); 104 | int n; 105 | const char *se; 106 | luaL_argcheck(L, posi >= 1, 2, "out of range"); 107 | luaL_argcheck(L, pose <= (lua_Integer)len, 3, "out of range"); 108 | if (posi > pose) return 0; /* empty interval; return no values */ 109 | n = (int)(pose - posi + 1); 110 | if (posi + n <= pose) /* (lua_Integer -> int) overflow? */ 111 | return luaL_error(L, "string slice too long"); 112 | luaL_checkstack(L, n, "string slice too long"); 113 | n = 0; 114 | se = s + pose; 115 | for (s += posi - 1; s < se;) { 116 | int code; 117 | s = utf8_decode(s, &code); 118 | if (s == NULL) 119 | return luaL_error(L, "invalid UTF-8 code"); 120 | lua_pushinteger(L, code); 121 | n++; 122 | } 123 | return n; 124 | } 125 | 126 | 127 | static void pushutfchar (lua_State *L, int arg) { 128 | lua_Integer code = luaL_checkinteger(L, arg); 129 | luaL_argcheck(L, 0 <= code && code <= MAXUNICODE, arg, "value out of range"); 130 | lua_pushfstring(L, "%U", (long)code); 131 | } 132 | 133 | 134 | /* 135 | ** utfchar(n1, n2, ...) -> char(n1)..char(n2)... 136 | */ 137 | static int utfchar (lua_State *L) { 138 | int n = lua_gettop(L); /* number of arguments */ 139 | if (n == 1) /* optimize common case of single char */ 140 | pushutfchar(L, 1); 141 | else { 142 | int i; 143 | luaL_Buffer b; 144 | luaL_buffinit(L, &b); 145 | for (i = 1; i <= n; i++) { 146 | pushutfchar(L, i); 147 | luaL_addvalue(&b); 148 | } 149 | luaL_pushresult(&b); 150 | } 151 | return 1; 152 | } 153 | 154 | 155 | /* 156 | ** offset(s, n, [i]) -> index where n-th character counting from 157 | ** position 'i' starts; 0 means character at 'i'. 158 | */ 159 | static int byteoffset (lua_State *L) { 160 | size_t len; 161 | const char *s = luaL_checklstring(L, 1, &len); 162 | lua_Integer n = luaL_checkinteger(L, 2); 163 | lua_Integer posi = (n >= 0) ? 1 : len + 1; 164 | posi = u_posrelat(luaL_optinteger(L, 3, posi), len); 165 | luaL_argcheck(L, 1 <= posi && --posi <= (lua_Integer)len, 3, 166 | "position out of range"); 167 | if (n == 0) { 168 | /* find beginning of current byte sequence */ 169 | while (posi > 0 && iscont(s + posi)) posi--; 170 | } 171 | else { 172 | if (iscont(s + posi)) 173 | luaL_error(L, "initial position is a continuation byte"); 174 | if (n < 0) { 175 | while (n < 0 && posi > 0) { /* move back */ 176 | do { /* find beginning of previous character */ 177 | posi--; 178 | } while (posi > 0 && iscont(s + posi)); 179 | n++; 180 | } 181 | } 182 | else { 183 | n--; /* do not move for 1st character */ 184 | while (n > 0 && posi < (lua_Integer)len) { 185 | do { /* find beginning of next character */ 186 | posi++; 187 | } while (iscont(s + posi)); /* (cannot pass final '\0') */ 188 | n--; 189 | } 190 | } 191 | } 192 | if (n == 0) /* did it find given character? */ 193 | lua_pushinteger(L, posi + 1); 194 | else /* no such character */ 195 | lua_pushnil(L); 196 | return 1; 197 | } 198 | 199 | 200 | static int iter_aux (lua_State *L) { 201 | size_t len; 202 | const char *s = luaL_checklstring(L, 1, &len); 203 | lua_Integer n = lua_tointeger(L, 2) - 1; 204 | if (n < 0) /* first iteration? */ 205 | n = 0; /* start from here */ 206 | else if (n < (lua_Integer)len) { 207 | n++; /* skip current byte */ 208 | while (iscont(s + n)) n++; /* and its continuations */ 209 | } 210 | if (n >= (lua_Integer)len) 211 | return 0; /* no more codepoints */ 212 | else { 213 | int code; 214 | const char *next = utf8_decode(s + n, &code); 215 | if (next == NULL || iscont(next)) 216 | return luaL_error(L, "invalid UTF-8 code"); 217 | lua_pushinteger(L, n + 1); 218 | lua_pushinteger(L, code); 219 | return 2; 220 | } 221 | } 222 | 223 | 224 | static int iter_codes (lua_State *L) { 225 | luaL_checkstring(L, 1); 226 | lua_pushcfunction(L, iter_aux); 227 | lua_pushvalue(L, 1); 228 | lua_pushinteger(L, 0); 229 | return 3; 230 | } 231 | 232 | 233 | /* pattern to match a single UTF-8 character */ 234 | #define UTF8PATT "[\0-\x7F\xC2-\xF4][\x80-\xBF]*" 235 | 236 | 237 | static struct luaL_Reg funcs[] = { 238 | {"offset", byteoffset}, 239 | {"codepoint", codepoint}, 240 | {"char", utfchar}, 241 | {"len", utflen}, 242 | {"codes", iter_codes}, 243 | /* placeholders */ 244 | {"charpattern", NULL}, 245 | {NULL, NULL} 246 | }; 247 | 248 | 249 | LUAMOD_API int luaopen_utf8 (lua_State *L) { 250 | luaL_newlib(L, funcs); 251 | lua_pushliteral(L, UTF8PATT); 252 | lua_setfield(L, -2, "charpattern"); 253 | return 1; 254 | } 255 | 256 | -------------------------------------------------------------------------------- /3rd/lua/src/lvm.h: -------------------------------------------------------------------------------- 1 | /* 2 | ** $Id: lvm.h,v 2.34 2014/08/01 17:24:02 roberto Exp $ 3 | ** Lua virtual machine 4 | ** See Copyright Notice in lua.h 5 | */ 6 | 7 | #ifndef lvm_h 8 | #define lvm_h 9 | 10 | 11 | #include "ldo.h" 12 | #include "lobject.h" 13 | #include "ltm.h" 14 | 15 | 16 | #if !defined(LUA_NOCVTN2S) 17 | #define cvt2str(o) ttisnumber(o) 18 | #else 19 | #define cvt2str(o) 0 /* no conversion from numbers to strings */ 20 | #endif 21 | 22 | 23 | #if !defined(LUA_NOCVTS2N) 24 | #define cvt2num(o) ttisstring(o) 25 | #else 26 | #define cvt2num(o) 0 /* no conversion from strings to numbers */ 27 | #endif 28 | 29 | 30 | #define tonumber(o,n) \ 31 | (ttisfloat(o) ? (*(n) = fltvalue(o), 1) : luaV_tonumber_(o,n)) 32 | 33 | #define tointeger(o,i) \ 34 | (ttisinteger(o) ? (*(i) = ivalue(o), 1) : luaV_tointeger_(o,i)) 35 | 36 | #define intop(op,v1,v2) l_castU2S(l_castS2U(v1) op l_castS2U(v2)) 37 | 38 | #define luaV_rawequalobj(t1,t2) luaV_equalobj(NULL,t1,t2) 39 | 40 | 41 | LUAI_FUNC int luaV_equalobj (lua_State *L, const TValue *t1, const TValue *t2); 42 | LUAI_FUNC int luaV_lessthan (lua_State *L, const TValue *l, const TValue *r); 43 | LUAI_FUNC int luaV_lessequal (lua_State *L, const TValue *l, const TValue *r); 44 | LUAI_FUNC int luaV_tonumber_ (const TValue *obj, lua_Number *n); 45 | LUAI_FUNC int luaV_tointeger_ (const TValue *obj, lua_Integer *p); 46 | LUAI_FUNC void luaV_gettable (lua_State *L, const TValue *t, TValue *key, 47 | StkId val); 48 | LUAI_FUNC void luaV_settable (lua_State *L, const TValue *t, TValue *key, 49 | StkId val); 50 | LUAI_FUNC void luaV_finishOp (lua_State *L); 51 | LUAI_FUNC void luaV_execute (lua_State *L); 52 | LUAI_FUNC void luaV_concat (lua_State *L, int total); 53 | LUAI_FUNC lua_Integer luaV_div (lua_State *L, lua_Integer x, lua_Integer y); 54 | LUAI_FUNC lua_Integer luaV_mod (lua_State *L, lua_Integer x, lua_Integer y); 55 | LUAI_FUNC lua_Integer luaV_shiftl (lua_Integer x, lua_Integer y); 56 | LUAI_FUNC void luaV_objlen (lua_State *L, StkId ra, const TValue *rb); 57 | 58 | #endif 59 | -------------------------------------------------------------------------------- /3rd/lua/src/lzio.c: -------------------------------------------------------------------------------- 1 | /* 2 | ** $Id: lzio.c,v 1.36 2014/11/02 19:19:04 roberto Exp $ 3 | ** Buffered streams 4 | ** See Copyright Notice in lua.h 5 | */ 6 | 7 | #define lzio_c 8 | #define LUA_CORE 9 | 10 | #include "lprefix.h" 11 | 12 | 13 | #include 14 | 15 | #include "lua.h" 16 | 17 | #include "llimits.h" 18 | #include "lmem.h" 19 | #include "lstate.h" 20 | #include "lzio.h" 21 | 22 | 23 | int luaZ_fill (ZIO *z) { 24 | size_t size; 25 | lua_State *L = z->L; 26 | const char *buff; 27 | lua_unlock(L); 28 | buff = z->reader(L, z->data, &size); 29 | lua_lock(L); 30 | if (buff == NULL || size == 0) 31 | return EOZ; 32 | z->n = size - 1; /* discount char being returned */ 33 | z->p = buff; 34 | return cast_uchar(*(z->p++)); 35 | } 36 | 37 | 38 | void luaZ_init (lua_State *L, ZIO *z, lua_Reader reader, void *data) { 39 | z->L = L; 40 | z->reader = reader; 41 | z->data = data; 42 | z->n = 0; 43 | z->p = NULL; 44 | } 45 | 46 | 47 | /* --------------------------------------------------------------- read --- */ 48 | size_t luaZ_read (ZIO *z, void *b, size_t n) { 49 | while (n) { 50 | size_t m; 51 | if (z->n == 0) { /* no bytes in buffer? */ 52 | if (luaZ_fill(z) == EOZ) /* try to read more */ 53 | return n; /* no more input; return number of missing bytes */ 54 | else { 55 | z->n++; /* luaZ_fill consumed first byte; put it back */ 56 | z->p--; 57 | } 58 | } 59 | m = (n <= z->n) ? n : z->n; /* min. between n and z->n */ 60 | memcpy(b, z->p, m); 61 | z->n -= m; 62 | z->p += m; 63 | b = (char *)b + m; 64 | n -= m; 65 | } 66 | return 0; 67 | } 68 | 69 | /* ------------------------------------------------------------------------ */ 70 | char *luaZ_openspace (lua_State *L, Mbuffer *buff, size_t n) { 71 | if (n > buff->buffsize) { 72 | if (n < LUA_MINBUFFER) n = LUA_MINBUFFER; 73 | luaZ_resizebuffer(L, buff, n); 74 | } 75 | return buff->buffer; 76 | } 77 | 78 | 79 | -------------------------------------------------------------------------------- /3rd/lua/src/lzio.h: -------------------------------------------------------------------------------- 1 | /* 2 | ** $Id: lzio.h,v 1.30 2014/12/19 17:26:14 roberto Exp $ 3 | ** Buffered streams 4 | ** See Copyright Notice in lua.h 5 | */ 6 | 7 | 8 | #ifndef lzio_h 9 | #define lzio_h 10 | 11 | #include "lua.h" 12 | 13 | #include "lmem.h" 14 | 15 | 16 | #define EOZ (-1) /* end of stream */ 17 | 18 | typedef struct Zio ZIO; 19 | 20 | #define zgetc(z) (((z)->n--)>0 ? cast_uchar(*(z)->p++) : luaZ_fill(z)) 21 | 22 | 23 | typedef struct Mbuffer { 24 | char *buffer; 25 | size_t n; 26 | size_t buffsize; 27 | } Mbuffer; 28 | 29 | #define luaZ_initbuffer(L, buff) ((buff)->buffer = NULL, (buff)->buffsize = 0) 30 | 31 | #define luaZ_buffer(buff) ((buff)->buffer) 32 | #define luaZ_sizebuffer(buff) ((buff)->buffsize) 33 | #define luaZ_bufflen(buff) ((buff)->n) 34 | 35 | #define luaZ_buffremove(buff,i) ((buff)->n -= (i)) 36 | #define luaZ_resetbuffer(buff) ((buff)->n = 0) 37 | 38 | 39 | #define luaZ_resizebuffer(L, buff, size) \ 40 | ((buff)->buffer = luaM_reallocvchar(L, (buff)->buffer, \ 41 | (buff)->buffsize, size), \ 42 | (buff)->buffsize = size) 43 | 44 | #define luaZ_freebuffer(L, buff) luaZ_resizebuffer(L, buff, 0) 45 | 46 | 47 | LUAI_FUNC char *luaZ_openspace (lua_State *L, Mbuffer *buff, size_t n); 48 | LUAI_FUNC void luaZ_init (lua_State *L, ZIO *z, lua_Reader reader, 49 | void *data); 50 | LUAI_FUNC size_t luaZ_read (ZIO* z, void *b, size_t n); /* read next n bytes */ 51 | 52 | 53 | 54 | /* --------- Private Part ------------------ */ 55 | 56 | struct Zio { 57 | size_t n; /* bytes still unread */ 58 | const char *p; /* current position in buffer */ 59 | lua_Reader reader; /* reader function */ 60 | void *data; /* additional data */ 61 | lua_State *L; /* Lua state (for reader) */ 62 | }; 63 | 64 | 65 | LUAI_FUNC int luaZ_fill (ZIO *z); 66 | 67 | #endif 68 | -------------------------------------------------------------------------------- /Makefile: -------------------------------------------------------------------------------- 1 | .PHONY: all lua53 build_dir clean 2 | 3 | TOP=$(PWD) 4 | BUILD_DIR=$(TOP)/build 5 | BIN_DIR=$(TOP)/bin 6 | INCLUDE_DIR=$(TOP)/include 7 | LUA_EX_LIB=$(TOP)/lualib 8 | EXTERNAL=$(TOP)/3rd 9 | SRC=$(TOP)/src 10 | 11 | CFLAGS = -g3 -O2 -rdynamic -Wall -I$(INCLUDE_DIR) 12 | SHARED = -fPIC --shared 13 | LDFLAGS = -L$(BUILD_DIR) -Wl,-rpath $(BUILD_DIR) 14 | 15 | all: build_dir 16 | 17 | build_dir: 18 | -mkdir $(BUILD_DIR) 19 | -mkdir $(BIN_DIR) 20 | -mkdir $(INCLUDE_DIR) 21 | -mkdir $(LUA_EX_LIB) 22 | 23 | all: lua53 24 | 25 | lua53: 26 | cd $(EXTERNAL)/lua && $(MAKE) clean && $(MAKE) MYCFLAGS="-O2 -fPIC -g" linux 27 | install -p -m 0755 $(EXTERNAL)/lua/src/lua $(BIN_DIR)/lua 28 | install -p -m 0755 $(EXTERNAL)/lua/src/luac $(BIN_DIR)/luac 29 | install -p -m 0644 $(EXTERNAL)/lua/src/liblua.a $(BUILD_DIR) 30 | install -p -m 0644 $(EXTERNAL)/lua/src/*.h $(INCLUDE_DIR) 31 | 32 | all: $(LUA_EX_LIB)/lutil.so $(LUA_EX_LIB)/lkcp.so 33 | 34 | $(LUA_EX_LIB)/lutil.so: $(SRC)/lutil.c 35 | gcc $(CFLAGS) $(SHARED) $^ -o $@ 36 | 37 | $(LUA_EX_LIB)/lkcp.so: $(SRC)/lkcp.c $(EXTERNAL)/kcp/ikcp.c 38 | cp $(EXTERNAL)/kcp/ikcp.h $(INCLUDE_DIR) 39 | gcc $(CFLAGS) $(SHARED) $^ -o $@ $(LDFLAGS) 40 | 41 | all: 42 | -rm -rf $(TOP)/*.a $(TOP)/*.o 43 | @echo 'make finish!!!!!!!!!!!!!!!!!' 44 | 45 | clean: 46 | -rm -rf *.o *.a $(BIN_DIR) $(BUILD_DIR) $(INCLUDE_DIR) $(LUA_EX_LIB) 47 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Introduction: 2 | 3 | Lua binding for KCP, interface description written in lua-interface.md, see details of the project description within the KCP. what is KCP? please visit: https://github.com/skywind3000/kcp, http://www.skywind.me/blog/archives/1048 4 | 5 | #Make: 6 | Just make 7 | 8 | #Structure: 9 | ####3rd: 10 | lua: taken lua53 11 | kcp: visit https://github.com/skywind3000/kcp 12 | 13 | ####src: 14 | lkcp.c: the file for bind kcp 15 | testkcp.lua: the file for test kcp 16 | 17 | ####run_test.sh: 18 | After the project compile successfully, you can run this file to test kcp 19 | 20 | #lua-interface: 21 | 22 | ## LKcp.lkcp_init(output) 23 | 24 | ### DESCRIPTION 25 | Init KCP layer. 26 | 27 | ### PARAMETERS 28 | output: a callback for KCP layer to invoke when send data to transport layer 29 | [ 30 | output prototype: 31 | function output(info, buf) 32 | ... 33 | end 34 | info is brought when invoke lkcp_create 35 | buf is to be sent 36 | ] 37 | 38 | ### RETURN 39 | ret: always 0 40 | 41 | ## LKcp.lkcp_create(session, info) 42 | 43 | ### DESCRIPTION 44 | Create kcp object. 45 | 46 | ### PARAMETERS 47 | session: number mark session 48 | info: extra info, when KCP layer invoke callback to send data, KCP layer would brings that to output 49 | [ 50 | info prototype: 51 | info = {1, "who", ...} 52 | notice: 53 | the form of info must be sequential, and elements must be string or integer 54 | ] 55 | 56 | ### RETURN 57 | kcp: kcp object 58 | 59 | ## kcp:lkcp_wndsize(sndwnd, rcvwnd) 60 | 61 | ### DESCRIPTION 62 | Set maximum window size: sndwnd=32, rcvwnd=32 by default 63 | 64 | ### PARAMETERS 65 | sndwnd: send window size 66 | rcvwnd: recive window size 67 | 68 | ### RETURN 69 | None 70 | 71 | ## kcp:lkcp_nodelay(nodelay, interval, resend, nc) 72 | 73 | ### DESCRIPTION 74 | Config re-transmission and flow control 75 | 76 | ### PARAMETERS 77 | nodelay: 0:disable(default), 1:enable 78 | interval: internal update timer interval in millisec, default is 100ms 79 | resend: 0:disable fast resend(default), 1:enable fast resend 80 | nc: 0:normal congestion control(default), 1:disable congestion control 81 | 82 | ### RETURN 83 | ret: always 0 84 | 85 | ## kcp:lkcp_check(current) 86 | 87 | ### DESCRIPTION 88 | Get when to invoke lkcp_update 89 | 90 | ### PARAMETERS 91 | current: current timestamp in millisec 92 | 93 | ### RETURN 94 | when: timestamp in millisec when to invoke lkcp_update 95 | 96 | ## kcp:lkcp_update(current) 97 | 98 | ### DESCRIPTION 99 | Update state (call it repeatedly, every 10ms-100ms), or you can ask 100 | 101 | ### PARAMETERS 102 | current: current timestamp in millisec 103 | 104 | ### RETURN 105 | None 106 | 107 | ## kcp:lkcp_send(data) 108 | 109 | ### DESCRIPTION 110 | User/upper level send 111 | 112 | ### PARAMETERS 113 | data: data to be sent 114 | 115 | ### RETURN 116 | sent_len: below zero for error, otherwise succeed 117 | 118 | ## kcp:lkcp_flush() 119 | 120 | ### DESCRIPTION 121 | Flush pending data 122 | 123 | ### PARAMETERS 124 | None 125 | 126 | ### RETURN 127 | None 128 | 129 | ## kcp:lkcp_input(data) 130 | 131 | ### DESCRIPTION 132 | When you received a low level packet (eg. UDP packet), call it 133 | 134 | ### PARAMETERS 135 | data: data received from transport layer 136 | 137 | ### RETURN 138 | ret: below zero for error, otherwise succeed 139 | 140 | ## kcp:lkcp_recv() 141 | 142 | ### DESCRIPTION 143 | User/upper level recv 144 | 145 | ### PARAMETERS 146 | None 147 | 148 | ### RETURN 149 | rcv_len: Less than or equal to 0 for EAGAIN, otherwise for rcv_len 150 | rcv_buf: if rcv_len greater than 0, rcv_buf is data to recv 151 | 152 | -------------------------------------------------------------------------------- /lua-interface.md: -------------------------------------------------------------------------------- 1 | 2 | # LUA-INTERFACE 3 | 4 | ## LKcp.lkcp_create(session, func) 5 | 6 | ### DESCRIPTION 7 | Create kcp object. 8 | 9 | ### PARAMETERS 10 | session: number mark session 11 | func: extra closures, which KCP layer invoke callback to send data, see detail in testkcp.lua 12 | 13 | ### RETURN 14 | kcp: kcp object 15 | 16 | ## kcp:lkcp_wndsize(sndwnd, rcvwnd) 17 | 18 | ### DESCRIPTION 19 | Set maximum window size: sndwnd=32, rcvwnd=32 by default 20 | 21 | ### PARAMETERS 22 | sndwnd: send window size 23 | rcvwnd: recive window size 24 | 25 | ### RETURN 26 | None 27 | 28 | ## kcp:lkcp_nodelay(nodelay, interval, resend, nc) 29 | 30 | ### DESCRIPTION 31 | Config re-transmission and flow control 32 | 33 | ### PARAMETERS 34 | nodelay: 0:disable(default), 1:enable 35 | interval: internal update timer interval in millisec, default is 100ms 36 | resend: 0:disable fast resend(default), 1:enable fast resend 37 | nc: 0:normal congestion control(default), 1:disable congestion control 38 | 39 | ### RETURN 40 | ret: always 0 41 | 42 | ## kcp:lkcp_check(current) 43 | 44 | ### DESCRIPTION 45 | Get when to invoke lkcp_update 46 | 47 | ### PARAMETERS 48 | current: current timestamp in millisec 49 | 50 | ### RETURN 51 | when: timestamp in millisec when to invoke lkcp_update 52 | 53 | ## kcp:lkcp_update(current) 54 | 55 | ### DESCRIPTION 56 | Update state (call it repeatedly, every 10ms-100ms), or you can ask 57 | 58 | ### PARAMETERS 59 | current: current timestamp in millisec 60 | 61 | ### RETURN 62 | None 63 | 64 | ## kcp:lkcp_send(data) 65 | 66 | ### DESCRIPTION 67 | User/upper level send 68 | 69 | ### PARAMETERS 70 | data: data to be sent 71 | 72 | ### RETURN 73 | sent_len: below zero for error, otherwise succeed 74 | 75 | ## kcp:lkcp_flush() 76 | 77 | ### DESCRIPTION 78 | Flush pending data 79 | 80 | ### PARAMETERS 81 | None 82 | 83 | ### RETURN 84 | None 85 | 86 | ## kcp:lkcp_input(data) 87 | 88 | ### DESCRIPTION 89 | When you received a low level packet (eg. UDP packet), call it 90 | 91 | ### PARAMETERS 92 | data: data received from transport layer 93 | 94 | ### RETURN 95 | ret: below zero for error, otherwise succeed 96 | 97 | ## kcp:lkcp_recv() 98 | 99 | ### DESCRIPTION 100 | User/upper level recv 101 | 102 | ### PARAMETERS 103 | None 104 | 105 | ### RETURN 106 | rcv_len: Less than or equal to 0 for EAGAIN, otherwise for rcv_len 107 | rcv_buf: if rcv_len greater than 0, rcv_buf is data to recv 108 | 109 | -------------------------------------------------------------------------------- /run_test.sh: -------------------------------------------------------------------------------- 1 | ./bin/lua ./src/testkcp.lua 2 | -------------------------------------------------------------------------------- /src/latencysm.lua: -------------------------------------------------------------------------------- 1 | 2 | local lutil = require "lutil" 3 | 4 | local M = {} 5 | local DelayPacket = {} 6 | local LatencySM = {} 7 | 8 | local function getms() 9 | return math.floor(lutil.gettimeofday()) 10 | end 11 | 12 | local function rand() 13 | return math.random(100) 14 | end 15 | 16 | --delay packet 17 | function DelayPacket.new(data) 18 | local self = {} 19 | self.data = data 20 | self.ts = 0 21 | setmetatable(self, {__index = DelayPacket}) 22 | return self 23 | end 24 | 25 | function DelayPacket:getdata() 26 | return self.data 27 | end 28 | 29 | function DelayPacket:getts() 30 | return self.ts 31 | end 32 | 33 | function DelayPacket:setts(ts) 34 | self.ts = ts 35 | end 36 | 37 | --latency simulator 38 | function LatencySM.new(lostrate, rttmin, rttmax) 39 | local self = {} 40 | lostrate = lostrate or 10 41 | rttmin = rttmin or 60 42 | rttmax = rttmin or 125 43 | 44 | self.lostrate = lostrate/2 45 | self.rttmin = rttmin/2 46 | self.rttmax = rttmax/2 47 | 48 | self.tunnel01 = {} 49 | self.tunnel10 = {} 50 | 51 | setmetatable(self, {__index = LatencySM}) 52 | return self 53 | end 54 | 55 | function LatencySM:send(peer, data) 56 | local ra = rand() 57 | if rand() < self.lostrate then 58 | return 59 | end 60 | local pkt = DelayPacket.new(data) 61 | local nowt = getms() 62 | local delay = self.rttmin 63 | 64 | if self.rttmax > self.rttmin then 65 | delay = delay + rand() % (self.rttmax - self.rttmin) 66 | end 67 | pkt:setts(nowt + delay) 68 | if peer == 0 then 69 | table.insert(self.tunnel01, pkt) 70 | else 71 | table.insert(self.tunnel10, pkt) 72 | end 73 | end 74 | 75 | function LatencySM:recv(peer) 76 | local tunnel 77 | if peer == 0 then 78 | tunnel = self.tunnel10 79 | else 80 | tunnel = self.tunnel01 81 | end 82 | if #tunnel == 0 then 83 | return -1 84 | end 85 | local pkt = tunnel[1] 86 | local nowt = getms() 87 | if nowt < pkt:getts() then 88 | return -2 89 | end 90 | table.remove(tunnel, 1) 91 | local ret = pkt:getdata() 92 | return #ret, ret 93 | end 94 | 95 | M.LatencySM = LatencySM 96 | 97 | return M 98 | 99 | -------------------------------------------------------------------------------- /src/lkcp.c: -------------------------------------------------------------------------------- 1 | /** 2 | * 3 | * Copyright (C) 2015 by David Lin 4 | * 5 | * Permission is hereby granted, free of charge, to any person obtaining a copy 6 | * of this software and associated documentation files (the "Software"), to deal 7 | * in the Software without restriction, including without limitation the rights 8 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | * copies of the Software, and to permit persons to whom the Software is 10 | * furnished to do so, subject to the following conditions: 11 | * 12 | * The above copyright notice and this permission notice shall be included in 13 | * all copies or substantial portions of the Software. 14 | * 15 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALING IN 21 | * THE SOFTWARE. 22 | * 23 | */ 24 | 25 | #include 26 | #include 27 | #include 28 | 29 | #include 30 | #include 31 | 32 | #include "ikcp.h" 33 | 34 | #define RECV_BUFFER_LEN 4*1024*1024 35 | 36 | #define check_kcp(L, idx)\ 37 | *(ikcpcb**)luaL_checkudata(L, idx, "kcp_meta") 38 | 39 | #define check_buf(L, idx)\ 40 | (char*)luaL_checkudata(L, idx, "recv_buffer") 41 | 42 | struct Callback { 43 | uint64_t handle; 44 | lua_State* L; 45 | }; 46 | 47 | static int kcp_output_callback(const char *buf, int len, ikcpcb *kcp, void *arg) { 48 | struct Callback* c = (struct Callback*)arg; 49 | lua_State* L = c -> L; 50 | uint64_t handle = c -> handle; 51 | 52 | lua_rawgeti(L, LUA_REGISTRYINDEX, handle); 53 | lua_pushlstring(L, buf, len); 54 | lua_call(L, 1, 0); 55 | 56 | return 0; 57 | } 58 | 59 | static int kcp_gc(lua_State* L) { 60 | ikcpcb* kcp = check_kcp(L, 1); 61 | if (kcp == NULL) { 62 | return 0; 63 | } 64 | if (kcp->user != NULL) { 65 | struct Callback* c = (struct Callback*)kcp -> user; 66 | uint64_t handle = c -> handle; 67 | luaL_unref(L, LUA_REGISTRYINDEX, handle); 68 | free(c); 69 | kcp->user = NULL; 70 | } 71 | ikcp_release(kcp); 72 | kcp = NULL; 73 | return 0; 74 | } 75 | 76 | static int lkcp_create(lua_State* L){ 77 | uint64_t handle = luaL_ref(L, LUA_REGISTRYINDEX); 78 | int32_t conv = luaL_checkinteger(L, 1); 79 | 80 | struct Callback* c = malloc(sizeof(struct Callback)); 81 | memset(c, 0, sizeof(struct Callback)); 82 | c -> handle = handle; 83 | c -> L = L; 84 | 85 | ikcpcb* kcp = ikcp_create(conv, (void*)c); 86 | if (kcp == NULL) { 87 | lua_pushnil(L); 88 | lua_pushstring(L, "error: fail to create kcp"); 89 | return 2; 90 | } 91 | 92 | kcp->output = kcp_output_callback; 93 | 94 | *(ikcpcb**)lua_newuserdata(L, sizeof(void*)) = kcp; 95 | luaL_getmetatable(L, "kcp_meta"); 96 | lua_setmetatable(L, -2); 97 | return 1; 98 | } 99 | 100 | static int lkcp_recv(lua_State* L){ 101 | ikcpcb* kcp = check_kcp(L, 1); 102 | if (kcp == NULL) { 103 | lua_pushnil(L); 104 | lua_pushstring(L, "error: kcp not args"); 105 | return 2; 106 | } 107 | lua_getfield(L, LUA_REGISTRYINDEX, "kcp_lua_recv_buffer"); 108 | char* buf = check_buf(L, -1); 109 | lua_pop(L, 1); 110 | 111 | int32_t hr = ikcp_recv(kcp, buf, RECV_BUFFER_LEN); 112 | if (hr <= 0) { 113 | lua_pushinteger(L, hr); 114 | return 1; 115 | } 116 | 117 | lua_pushinteger(L, hr); 118 | lua_pushlstring(L, (const char *)buf, hr); 119 | 120 | return 2; 121 | } 122 | 123 | static int lkcp_send(lua_State* L){ 124 | ikcpcb* kcp = check_kcp(L, 1); 125 | if (kcp == NULL) { 126 | lua_pushnil(L); 127 | lua_pushstring(L, "error: kcp not args"); 128 | return 2; 129 | } 130 | size_t size; 131 | const char *data = luaL_checklstring(L, 2, &size); 132 | int32_t hr = ikcp_send(kcp, data, size); 133 | 134 | lua_pushinteger(L, hr); 135 | return 1; 136 | } 137 | 138 | static int lkcp_update(lua_State* L){ 139 | ikcpcb* kcp = check_kcp(L, 1); 140 | if (kcp == NULL) { 141 | lua_pushnil(L); 142 | lua_pushstring(L, "error: kcp not args"); 143 | return 2; 144 | } 145 | int32_t current = luaL_checkinteger(L, 2); 146 | ikcp_update(kcp, current); 147 | return 0; 148 | } 149 | 150 | static int lkcp_check(lua_State* L){ 151 | ikcpcb* kcp = check_kcp(L, 1); 152 | if (kcp == NULL) { 153 | lua_pushnil(L); 154 | lua_pushstring(L, "error: kcp not args"); 155 | return 2; 156 | } 157 | int32_t current = luaL_checkinteger(L, 2); 158 | int32_t hr = ikcp_check(kcp, current); 159 | lua_pushinteger(L, hr); 160 | return 1; 161 | } 162 | 163 | static int lkcp_input(lua_State* L){ 164 | ikcpcb* kcp = check_kcp(L, 1); 165 | if (kcp == NULL) { 166 | lua_pushnil(L); 167 | lua_pushstring(L, "error: kcp not args"); 168 | return 2; 169 | } 170 | size_t size; 171 | const char *data = luaL_checklstring(L, 2, &size); 172 | int32_t hr = ikcp_input(kcp, data, size); 173 | 174 | lua_pushinteger(L, hr); 175 | return 1; 176 | } 177 | 178 | static int lkcp_flush(lua_State* L){ 179 | ikcpcb* kcp = check_kcp(L, 1); 180 | if (kcp == NULL) { 181 | lua_pushnil(L); 182 | lua_pushstring(L, "error: kcp not args"); 183 | return 2; 184 | } 185 | ikcp_flush(kcp); 186 | return 0; 187 | } 188 | 189 | static int lkcp_wndsize(lua_State* L){ 190 | ikcpcb* kcp = check_kcp(L, 1); 191 | if (kcp == NULL) { 192 | lua_pushnil(L); 193 | lua_pushstring(L, "error: kcp not args"); 194 | return 2; 195 | } 196 | int32_t sndwnd = luaL_checkinteger(L, 2); 197 | int32_t rcvwnd = luaL_checkinteger(L, 3); 198 | ikcp_wndsize(kcp, sndwnd, rcvwnd); 199 | return 0; 200 | } 201 | 202 | static int lkcp_nodelay(lua_State* L){ 203 | ikcpcb* kcp = check_kcp(L, 1); 204 | if (kcp == NULL) { 205 | lua_pushnil(L); 206 | lua_pushstring(L, "error: kcp not args"); 207 | return 2; 208 | } 209 | int32_t nodelay = luaL_checkinteger(L, 2); 210 | int32_t interval = luaL_checkinteger(L, 3); 211 | int32_t resend = luaL_checkinteger(L, 4); 212 | int32_t nc = luaL_checkinteger(L, 5); 213 | int32_t hr = ikcp_nodelay(kcp, nodelay, interval, resend, nc); 214 | lua_pushinteger(L, hr); 215 | return 1; 216 | } 217 | 218 | 219 | static const struct luaL_Reg lkcp_methods [] = { 220 | { "lkcp_recv" , lkcp_recv }, 221 | { "lkcp_send" , lkcp_send }, 222 | { "lkcp_update" , lkcp_update }, 223 | { "lkcp_check" , lkcp_check }, 224 | { "lkcp_input" , lkcp_input }, 225 | { "lkcp_flush" , lkcp_flush }, 226 | { "lkcp_wndsize" , lkcp_wndsize }, 227 | { "lkcp_nodelay" , lkcp_nodelay }, 228 | {NULL, NULL}, 229 | }; 230 | 231 | static const struct luaL_Reg l_methods[] = { 232 | { "lkcp_create" , lkcp_create }, 233 | {NULL, NULL}, 234 | }; 235 | 236 | int luaopen_lkcp(lua_State* L) { 237 | luaL_checkversion(L); 238 | 239 | luaL_newmetatable(L, "kcp_meta"); 240 | 241 | lua_newtable(L); 242 | luaL_setfuncs(L, lkcp_methods, 0); 243 | lua_setfield(L, -2, "__index"); 244 | lua_pushcfunction(L, kcp_gc); 245 | lua_setfield(L, -2, "__gc"); 246 | 247 | luaL_newmetatable(L, "recv_buffer"); 248 | 249 | char* global_recv_buffer = lua_newuserdata(L, sizeof(char)*RECV_BUFFER_LEN); 250 | memset(global_recv_buffer, 0, sizeof(char)*RECV_BUFFER_LEN); 251 | luaL_getmetatable(L, "recv_buffer"); 252 | lua_setmetatable(L, -2); 253 | lua_setfield(L, LUA_REGISTRYINDEX, "kcp_lua_recv_buffer"); 254 | 255 | luaL_newlib(L, l_methods); 256 | 257 | return 1; 258 | } 259 | 260 | -------------------------------------------------------------------------------- /src/lutil.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | 5 | #include 6 | #include 7 | 8 | #if defined(WIN32) || defined(_WIN32) || defined(WIN64) || defined(_WIN64) 9 | #include 10 | #elif !defined(__unix) 11 | #define __unix 12 | #endif 13 | 14 | #ifdef __unix 15 | #include 16 | #include 17 | #include 18 | #include 19 | #endif 20 | 21 | static int _l_gettimeofday(lua_State * L){ 22 | struct timeval tv; 23 | gettimeofday(&tv, NULL); 24 | 25 | uint32_t r = (uint32_t)(((uint64_t)tv.tv_sec * 1000 + (uint64_t)tv.tv_usec / 1000) & 0x7ffffffful); 26 | lua_pushinteger(L, r); 27 | return 1; 28 | } 29 | 30 | /* sleep in millisecond */ 31 | static int _l_isleep(lua_State* L) 32 | { 33 | uint32_t millisecond = luaL_checkinteger(L, 1); 34 | #ifdef __unix 35 | usleep((millisecond << 10) - (millisecond << 4) - (millisecond << 3)); 36 | #elif defined(_WIN32) 37 | Sleep(millisecond); 38 | #endif 39 | return 0; 40 | } 41 | 42 | static int _netbytes2uint32(lua_State* L){ 43 | const char* s = luaL_checkstring(L, 1); 44 | uint32_t a0 = (uint8_t)s[0] << 24; 45 | uint32_t a1 = (uint8_t)s[1] << 16; 46 | uint32_t a2 = (uint8_t)s[2] << 8; 47 | uint32_t a3 = (uint8_t)s[3]; 48 | uint32_t ret = (uint32_t)(a0 | a1 | a2 | a3); 49 | lua_pushinteger(L, ret); 50 | return 1; 51 | } 52 | 53 | static int _uint322netbytes(lua_State* L){ 54 | uint32_t i = lua_tointeger(L, 1); 55 | char s[4]; 56 | s[0] = (char)(i >> 24); 57 | s[1] = (char)(i >> 16); 58 | s[2] = (char)(i >> 8); 59 | s[3] = (char)(i); 60 | lua_pushlstring(L, s, 4); 61 | return 1; 62 | } 63 | 64 | int luaopen_lutil(lua_State *L) { 65 | luaL_Reg libs[] = { 66 | {"gettimeofday", _l_gettimeofday}, 67 | {"isleep", _l_isleep}, 68 | {"netbytes2uint32", _netbytes2uint32}, 69 | {"uint322netbytes", _uint322netbytes}, 70 | {NULL, NULL}, 71 | }; 72 | 73 | luaL_newlib(L, libs); 74 | return 1; 75 | } 76 | 77 | -------------------------------------------------------------------------------- /src/testkcp.lua: -------------------------------------------------------------------------------- 1 | 2 | package.cpath=package.cpath..";./lualib/?.so" 3 | package.path=package.path..";./src/?.lua" 4 | 5 | 6 | local LatencySM = require "latencysm" 7 | local LKcp = require "lkcp" 8 | local LUtil = require "lutil" 9 | 10 | --创建模拟网络:丢包率10%,RTT 60-125ms 11 | local lsm = LatencySM.LatencySM.new(10, 60, 125) 12 | 13 | 14 | local function getms() 15 | return math.floor(LUtil.gettimeofday()) 16 | end 17 | 18 | local function udp_output(buf, info) 19 | print(info.id, info.a, info.b, info.c) 20 | if info.b then 21 | info.c(info.a) 22 | end 23 | lsm:send(info.id, buf) 24 | end 25 | 26 | local function test(mode) 27 | --此处info用于output接口回调数据 28 | local session = 0x11223344 29 | local info = { 30 | id = 0, 31 | a = 'aaa', 32 | b = false, 33 | } 34 | local kcp1 = LKcp.lkcp_create(session, function (buf) 35 | udp_output(buf, info) 36 | end) 37 | local info2 = { 38 | id = 1, 39 | a = 'aaaaaaaaaaaaa', 40 | b = true, 41 | c = function (a) 42 | print 'hahahah!!!' 43 | end, 44 | } 45 | local kcp2 = LKcp.lkcp_create(session, function (buf) 46 | udp_output(buf, info2) 47 | end) 48 | 49 | local current = getms() 50 | local slap = current + 20 51 | local index = 0 52 | local inext = 0 53 | local sumrtt = 0 54 | 55 | local count = 0 56 | local maxrtt = 0 57 | 58 | --配置窗口大小:平均延迟200ms,每20ms发送一个包, 59 | --而考虑到丢包重发,设置最大收发窗口为128 60 | kcp1:lkcp_wndsize(128, 128) 61 | kcp2:lkcp_wndsize(128, 128) 62 | 63 | --判断测试用例的模式 64 | if mode == 0 then 65 | --默认模式 66 | kcp1:lkcp_nodelay(0, 10, 0, 0) 67 | kcp2:lkcp_nodelay(0, 10, 0, 0) 68 | elseif mode == 1 then 69 | --普通模式,关闭流控等 70 | kcp1:lkcp_nodelay(0, 10, 0, 1) 71 | kcp2:lkcp_nodelay(0, 10, 0, 1) 72 | else 73 | --启动快速模式 74 | --第二个参数 nodelay-启用以后若干常规加速将启动 75 | --第三个参数 interval为内部处理时钟,默认设置为 10ms 76 | --第四个参数 resend为快速重传指标,设置为2 77 | --第五个参数 为是否禁用常规流控,这里禁止 78 | kcp1:lkcp_nodelay(1, 10, 2, 1) 79 | kcp2:lkcp_nodelay(1, 10, 2, 1) 80 | end 81 | 82 | local buffer = "" 83 | local hrlen = 0 84 | local hr = "" 85 | local ts1 = getms() 86 | 87 | while 1 do 88 | current = getms() 89 | 90 | local nextt1 = kcp1:lkcp_check(current) 91 | local nextt2 = kcp2:lkcp_check(current) 92 | local nextt = math.min(nextt1, nextt2) 93 | local diff = nextt - current 94 | if diff > 0 then 95 | LUtil.isleep(diff) 96 | current = getms() 97 | end 98 | 99 | kcp1:lkcp_update(current) 100 | kcp2:lkcp_update(current) 101 | 102 | --每隔 20ms,kcp1发送数据 103 | while current >= slap do 104 | local s1 = LUtil.uint322netbytes(index) 105 | local s2 = LUtil.uint322netbytes(current) 106 | kcp1:lkcp_send(s1..s2) 107 | --kcp1:lkcp_flush() 108 | slap = slap + 20 109 | index = index + 1 110 | end 111 | 112 | --处理虚拟网络:检测是否有udp包从p1->p2 113 | while 1 do 114 | hrlen, hr = lsm:recv(1) 115 | if hrlen < 0 then 116 | break 117 | end 118 | --如果 p2收到udp,则作为下层协议输入到kcp2 119 | kcp2:lkcp_input(hr) 120 | end 121 | 122 | --处理虚拟网络:检测是否有udp包从p2->p1 123 | while 1 do 124 | hrlen, hr = lsm:recv(0) 125 | if hrlen < 0 then 126 | break 127 | end 128 | --如果 p1收到udp,则作为下层协议输入到kcp1 129 | kcp1:lkcp_input(hr) 130 | end 131 | 132 | --kcp2接收到任何包都返回回去 133 | while 1 do 134 | hrlen, hr = kcp2:lkcp_recv() 135 | if hrlen <= 0 then 136 | break 137 | end 138 | kcp2:lkcp_send(hr) 139 | --kcp2:lkcp_flush() 140 | end 141 | 142 | --kcp1收到kcp2的回射数据 143 | while 1 do 144 | hrlen, hr = kcp1:lkcp_recv() 145 | --没有收到包就退出 146 | if hrlen <= 0 then 147 | break 148 | end 149 | 150 | local hr1 = string.sub(hr, 1, 4) 151 | local hr2 = string.sub(hr, 5, 8) 152 | local sn = LUtil.netbytes2uint32(hr1) 153 | local ts = LUtil.netbytes2uint32(hr2) 154 | local rtt = current - ts 155 | 156 | if sn ~= inext then 157 | --如果收到的包不连续 158 | print(string.format("ERROR sn %d<->%d\n", count, inext)) 159 | return 160 | end 161 | 162 | inext = inext + 1 163 | sumrtt = sumrtt + rtt 164 | count = count + 1 165 | if rtt > maxrtt then 166 | maxrtt = rtt 167 | end 168 | 169 | print(string.format("[RECV] mode=%d sn=%d rtt=%d\n", mode, sn, rtt)) 170 | end 171 | if inext > 10 then 172 | break 173 | end 174 | end 175 | 176 | ts1 = getms() - ts1 177 | names = {"default", "normal", "fast"} 178 | print(string.format("%s mode result (%dms):", names[mode+1], ts1)) 179 | print(string.format("avgrtt=%d maxrtt=%d", math.floor(sumrtt/count), maxrtt)) 180 | print("press enter to next ...") 181 | io.read() 182 | end 183 | 184 | --测试 185 | test(0) --默认模式,类似 TCP:正常模式,无快速重传,常规流控 186 | test(1) --普通模式,关闭流控等 187 | test(2) --快速模式,所有开关都打开,且关闭流控 188 | 189 | --------------------------------------------------------------------------------