Compare commits

...

426 Commits

Author SHA1 Message Date
Cloud Wu
2ee85a91f9 Release 1.2.0 2018-11-06 11:11:29 +08:00
Cloud Wu
8a3a0c1b71 register logger name in framework, see #909 2018-10-21 13:21:51 +08:00
Sean Feng
b4752f2394 multiresultset spelling mistake 2018-10-17 19:54:38 +08:00
Cloud Wu
f110b51290 add socketchannel.overload 2018-10-17 14:54:44 +08:00
Cloud Wu
e0f16b8df5 remove dead_service table, address may reused 2018-10-15 10:05:23 +08:00
Cloud Wu
08e56f4316 fix #793 2018-10-11 17:38:49 +08:00
Cloud Wu
7e57e498f6 remove dead_service table, address may reused 2018-10-08 15:44:12 +08:00
Cloud Wu
98b5c7c7c6 address 0 is reserved 2018-10-08 14:20:53 +08:00
sundream
02d5f4fbe9 rediscluster: support eval/evalshal + subscribe/publish 2018-09-27 10:00:30 +08:00
Hanlei Qin
818ff8314d remove unused code 2018-09-27 09:59:18 +08:00
Hanlei Qin
d23e6f8d8e 1. remove unused code; 2. weird indents fixed. 2018-09-20 00:31:14 +08:00
Hanlei Qin
f217a56f6e Uniform indent to tab and clear up. 2018-09-20 00:29:19 +08:00
Hanlei Qin
46b49adf9e remove useless file 2018-09-16 18:41:30 +08:00
Hanlei Qin
d9fb4d06ec remove useless local function 2018-09-16 18:41:06 +08:00
Cloud Wu
34a9979255 check launching address 2018-09-13 18:59:03 +08:00
Cloud Wu
89e7a06deb add more info when service init blocked 2018-09-13 18:27:05 +08:00
Cloud Wu
43d02ac456 update jemalloc to 5.1.0 2018-09-12 15:23:59 +08:00
Cloud Wu
c839159470 remove netpack from gate service 2018-09-12 11:45:41 +08:00
Cloud Wu
823b773051 remove unused require 2018-09-12 11:31:12 +08:00
Cloud Wu
f8434d34b6 report last accept time 2018-09-07 16:26:56 +08:00
Cloud Wu
61980c8a1f add socket.netstat 2018-09-07 16:11:27 +08:00
Cloud Wu
35176383b7 add skynet.context 2018-09-06 19:01:10 +08:00
Cloud Wu
c96e20e6c3 add skynet.context and enhance debug console command service 2018-09-06 18:59:33 +08:00
LiuYang
ce0cdc7bd3 add mongo test case: auth 2018-08-30 11:42:47 +08:00
Cloud Wu
7e63080c03 add mongo_db:auth 2018-08-30 10:50:52 +08:00
Cloud Wu
1c8ed8a46e add mongo config option: authdb, see issue #884 2018-08-30 10:50:52 +08:00
Cloud Wu
c4334be9c3 add mongo_db:auth 2018-08-30 09:51:55 +08:00
Cloud Wu
e6e69ae805 add mongo config option: authdb, see issue #884 2018-08-30 09:38:18 +08:00
LiuYang
8ce816de7f fix mongodb testcase 2018-08-29 23:33:17 +08:00
Cloud Wu
2fb52f6fce cleanup 2018-08-29 15:29:26 +08:00
Cloud Wu
c72d4d2134 support string address name, see #883 2018-08-28 15:15:38 +08:00
btt
18a36c171f debug console inject cmd support args 2018-08-23 17:02:06 +08:00
Cloud Wu
7b3c1631d1 more stable 2018-08-17 21:27:14 +08:00
Cloud Wu
4613fde654 fix #877 2018-08-17 21:16:35 +08:00
Cloud Wu
143baec319 remove duplicate code 2018-08-13 14:12:15 +08:00
fanyh
168a07d658 sleep time 1s-> 1m, sleep 1s prodcut more message 2018-08-09 19:28:59 +08:00
Cloud Wu
281acf4c71 Use fork instead of timeout 0, see #873 2018-08-07 14:55:26 +08:00
Cloud Wu
d2ab6863e3 fix #872 2018-08-07 10:49:21 +08:00
Cloud Wu
e55ad63d3c fix #873 2018-08-07 09:43:50 +08:00
Cloud Wu
ec2eaa70a4 Merge branch 'master' of https://github.com/cloudwu/skynet 2018-08-03 11:29:12 +08:00
Cloud Wu
d402619347 see #870 2018-08-03 11:28:18 +08:00
Cloud Wu
c101d9df17 see #870 2018-08-03 11:24:14 +08:00
hong
b5653a68ea runnging拼写错误 2018-08-02 21:30:03 +08:00
hong
c9942deaa9 queryname并发导致消息乱序
当有1个以上的co进入queryname,后面的协程有在第1个以后某个的co先执行(第一个已经返回),导致cluster消息乱序
2018-08-02 21:30:03 +08:00
yenshan98
2df1446c37 Rearranged sentence to be reader friendly. 2018-07-30 15:10:57 +08:00
Cloud Wu
9421815327 add posix_memalign hook 2018-07-23 15:32:35 +08:00
Cloud Wu
1a0c9997ec fix #863 2018-07-23 14:53:01 +08:00
Cloud Wu
16f060f864 hook aligned_alloc 2018-07-20 14:46:53 +08:00
Cloud Wu
ea7c6402dd update lua to 5.3.5 2018-07-10 22:11:56 +08:00
zixun
07db2580c4 fix kqueue error flag 2018-07-05 18:55:51 +08:00
zixun
1df72c0afe fix kqueue eof event 2018-07-05 18:37:50 +08:00
Cloud Wu
0e41231298 fix #857 2018-07-04 15:10:32 +08:00
Cloud Wu
8224b5a62a udp_connect may raise error 2018-06-26 09:49:18 +08:00
Cloud Wu
d8ab9dea1b fix #852 2018-06-25 14:24:04 +08:00
Cloud Wu
a8e5c31381 check udp address, see #852 2018-06-25 12:10:30 +08:00
Cloud Wu
3a1556e1fd add new debug command trace 2018-06-08 11:24:27 +08:00
Cloud Wu
4b5fbab129 recycle coroutine bugfix 2018-06-08 10:23:36 +08:00
Cloud Wu
b1ec1f4d18 token bugfix 2018-06-08 10:23:36 +08:00
Cloud Wu
16d8f4c774 cleanup 2018-06-08 10:23:36 +08:00
Cloud Wu
f8b5ec48e8 support user tag 2018-05-28 23:13:05 +08:00
Cloud Wu
7a26926965 resume trace log 2018-05-28 21:45:41 +08:00
Cloud Wu
2990fbc7cf ignore response, fix #841 2018-05-28 20:38:10 +08:00
Cloud Wu
e8e38f1682 add session log 2018-05-28 18:16:31 +08:00
Cloud Wu
35b4a09c3d unique cluster trace tag 2018-05-28 18:09:34 +08:00
Cloud Wu
9035fbe96b cluster trace 2018-05-28 16:39:04 +08:00
Cloud Wu
a41a5fadd2 ignore ret in clientagent 2018-05-28 11:24:55 +08:00
Cloud Wu
d6f265e703 call skynet.trace() in example 2018-05-26 17:37:19 +08:00
Cloud Wu
596c77afcd trace bugfix 2018-05-26 17:17:20 +08:00
Cloud Wu
e53d985c4f add skynet.trace() 2018-05-26 16:26:50 +08:00
Cloud Wu
348e53245b skynet.wait use token instead of coroutine.running() 2018-05-25 10:42:58 +08:00
Cloud Wu
2fde0a0ae4 log error when forget response a session. Add skynet.ignoreret() 2018-05-24 16:53:27 +08:00
Cloud Wu
85ec428f3f remove assert 2018-05-22 20:04:05 +08:00
Cloud Wu
a8ab809928 add __nowating flag to cluster config, see issue #803 2018-05-22 19:49:07 +08:00
caijietao
6c7cb5313d set backlog to 128 2018-05-22 13:08:00 +08:00
spin6lock
188e38198a add ipv6 host support to service_gate.c
service_gate的地址解析用strchr找到第一个':',并将后续的字符串作为
端口号解析。填ipv6地址"0:0:0:0:0:0:0:0:9999"的时候会出错,现在改成
strrchr,从右面找到的第一个':'
2018-05-22 13:07:02 +08:00
Cloud Wu
294f557268 lua 5.3.4 bug report 6 2018-05-17 12:03:03 +08:00
Cloud Wu
4dd622e180 socket channel order mode support padding, see issue #835 2018-05-09 17:38:32 +08:00
Cloud Wu
5f8e5f9be5 add random for seed 2018-05-07 11:10:45 +08:00
Cloud Wu
e561896966 Merge branch 'master' of github.com:cloudwu/skynet 2018-05-07 10:55:34 +08:00
Cloud Wu
ea25e20c88 more random seed 2018-05-07 10:55:18 +08:00
云风
003b0fdb02 Add logo 2018-05-03 23:26:53 +08:00
xjdrew
8de6500677 update mongo driver: safe_insert, safe_update, safe_delete 2018-05-02 01:36:00 +08:00
Cloud Wu
7df13e922b add testtimeout 2018-04-20 11:44:05 +08:00
Cloud Wu
182d7c7dc7 support @name, see #823 2018-04-20 10:11:16 +08:00
Cloud Wu
f4d5bc7aa4 forward fd to agent 2018-04-18 19:32:15 +08:00
Cloud Wu
d53d98b625 Merge branch 'clusteragent' 2018-04-18 19:30:24 +08:00
Cloud Wu
2bfba716ef forward fd to agent 2018-04-18 19:29:41 +08:00
Cloud Wu
4cbe33d15d remove unused sz 2018-04-17 10:47:41 +08:00
Cloud Wu
a9852273cb add addresscommand 2018-04-17 10:47:41 +08:00
Cloud Wu
eb8a2b5e65 Improve cluster package module 2018-04-17 10:47:41 +08:00
Cloud Wu
7304a990cb use clusteragent to dispatch cluster request 2018-04-17 10:47:41 +08:00
Cloud Wu
311d7c8f6a remove unused sz 2018-04-16 12:56:34 +08:00
Cloud Wu
5a3d2fdac7 add addresscommand 2018-04-14 20:30:47 +08:00
Cloud Wu
4b88f68ab8 Improve cluster package module 2018-04-14 18:14:44 +08:00
Cloud Wu
70c224c3e7 use clusteragent to dispatch cluster request 2018-04-14 16:11:26 +08:00
Cloud Wu
1932d33b41 set node = false when node is down, see #803 2018-02-24 21:26:24 +08:00
Cloud Wu
9cf4525a8f avoid error circulation 2018-02-12 18:07:16 +08:00
Cloud Wu
0846a6533d fix a legacy problem. make harbor service more stable 2018-02-12 18:07:16 +08:00
Cloud Wu
484404295e Merge branch 'hongling0-master' 2018-02-05 11:38:22 +08:00
云风
3e54becb95 Merge branch 'master' into master 2018-02-05 11:34:52 +08:00
hong
ab13305b64 monitor中不增加ref 2018-02-05 10:18:35 +08:00
Cloud Wu
6fdb123df4 bugfix, See #800 2018-02-04 21:32:41 +08:00
Cloud Wu
6cdc1cf95c collect used response, see #800 2018-02-04 16:25:19 +08:00
hong
2dd5a06616 抄写错误 2018-02-03 15:49:01 +08:00
hong
e7436bfa95 skynet.response() leak
datasheet在monitor接口里面产生的reponse在release接口里面没有释放
2018-02-03 15:43:33 +08:00
Cloud Wu
084aab4bcd dns server auto retire 2018-01-25 15:56:47 +08:00
Cloud Wu
cd99557368 udp send don't need inc/dec sending ref, see issue #794 2018-01-25 15:55:45 +08:00
Cloud Wu
04f4004934 sproto bugfix 2018-01-23 11:24:44 +08:00
Cloud Wu
bbf46f935a dec sending count asap, this may fix #794 2018-01-19 10:41:35 +08:00
Cloud Wu
b792c7144d clusterd wait for cluster.reload when the name no exist 2018-01-04 14:18:29 +08:00
Cloud Wu
5d5112257c use 32bit sending, see issue #777 2017-12-06 20:58:36 +08:00
云风
747e6c7848 Merge pull request #775 from cloudwu/tcpwriteorder
Tcpwriteorder, Fix #744
2017-12-04 11:45:49 +08:00
Cloud Wu
45d848c910 bugfix: inc sending ref, See issue #774 2017-12-04 10:55:47 +08:00
Cloud Wu
f12fa7e8f9 May fix issue #774 2017-12-03 00:26:12 +08:00
Cloud Wu
568a435e9e fix issue #773 2017-11-30 16:13:58 +08:00
Cloud Wu
c46f2633be fork may not execute when the service exit, and __gc would send message release without monitor 2017-11-16 10:47:18 +08:00
Cloud Wu
b51e28a3e0 set nodelay, see issue #763 2017-11-14 18:01:08 +08:00
云风
badfab8561 Merge pull request #761 from cloudwu/mongolimit
positive limit support
2017-11-07 10:17:04 +08:00
Cloud Wu
d5c0d687b3 positive limit support 2017-11-06 20:51:33 +08:00
Cloud Wu
57f08426ee concurrent cluster link, fix issue #757 2017-11-02 22:31:54 +08:00
Cloud Wu
ba59b879ad release v1.1 2017-10-31 11:27:14 +08:00
Cloud Wu
1e9e16f16b fix #755 2017-10-30 11:43:17 +08:00
Cloud Wu
ece075ef6e update sproto 2017-10-18 10:02:59 +08:00
Cloud Wu
c4c429b699 fix #747 2017-10-18 09:51:22 +08:00
云风
21f881910b Merge pull request #749 from chengdd1987/master
http中connect可能会连接失败,不应当将错误的fd继续传递下去
2017-10-18 09:44:43 +08:00
chengzhe
37157273ff http中connect可能会连接失败,不应当将错误的fd继续传递下去 2017-10-17 17:50:54 +08:00
云风
460ed2e9e2 Merge pull request #745 from qinhanlei/patch1
remove useless code.
2017-10-07 11:13:27 +08:00
Hanlei Qin
03ce7ab385 remove useless code. 2017-10-06 00:42:48 +08:00
Cloud Wu
1c605bed2b this may fix #744 2017-10-04 00:11:31 +08:00
Cloud Wu
55136b77ad fix issue #741 2017-09-25 15:10:21 +08:00
Cloud Wu
d8798a280a Revert "pthread may call __libc_memalign, see #731"
This reverts commit c8d6ffd393.
2017-09-06 22:21:04 +08:00
Cloud Wu
c8d6ffd393 pthread may call __libc_memalign, see #731 2017-09-06 20:19:29 +08:00
Cloud Wu
100329f09f official lua bugfix 2017-09-04 16:23:19 +08:00
Cloud Wu
553c30c6d1 sproto.default returns array type 2017-09-01 11:46:43 +08:00
云风
415459e656 Merge pull request #728 from hwangcc23/init-sigaction
Properly initialize sigaction struct
2017-09-01 10:05:08 +08:00
hwangcc23
596e8cfab2 Properly initialize sigaction struct
The code in skynet_main.c wasn't clearing the struct sigaction before passing it to sigaction().
This meant that we would block a random set of signals while executing the SIGPIPE handler, or jump to the uninitialized __sa_sigaction__ (instead of sa_handler).
Initialize properly as we do in skynet_start.c.
2017-08-31 22:38:50 +08:00
Cloud Wu
dab4419335 catch error , see #726 2017-08-28 16:06:51 +08:00
Cloud Wu
932ebfa0fd lua bugfix 2017-08-28 16:06:05 +08:00
云风
9d74307836 Merge pull request #725 from dingmingxin/master
using clock_gettime in macos(in macos_10.12 and later)
2017-08-28 12:08:41 +08:00
dmx
7be5ea0148 using clock_gettime in macos(in macos_10.12 and laster) 2017-08-28 11:26:51 +08:00
Cloud Wu
525279e9dd lua bugfix, see http://lua-users.org/lists/lua-l/2017-08/msg00065.html 2017-08-24 10:50:36 +08:00
云风
d0fbf0802f Merge pull request #722 from hwangcc23/fix-double-free
Fix double free
2017-08-24 10:05:46 +08:00
云风
fad154f474 remove this free would be better 2017-08-24 10:01:47 +08:00
hwangcc23
40543d42d5 Fix double free
In the mainloop function, calling __skynet_free__ frees the pointer which may has already been freed in __push_socket_data__.

mainloop(struct skynet_context * context, void * ud, int type, int session, uint32_t source, const void * msg, size_t sz) {
        struct harbor * h = ud;
        switch (type) {
        case PTYPE_SOCKET: {
                const struct skynet_socket_message * message = msg;
                switch(message->type) {
                case SKYNET_SOCKET_TYPE_DATA:
                        push_socket_data(h, message);
                        skynet_free(message->buffer);
                        // skip...

To fix this potential double-free bug, clear the pointer message->buffer in __push_socket_data__ after the pointer is freed.
2017-08-23 23:43:20 +08:00
Cloud Wu
fa763181c0 add \0 in dumper would be better 2017-08-22 09:41:24 +08:00
Cloud Wu
e48e6c40e7 use \0 instead of . 2017-08-21 21:49:36 +08:00
Cloud Wu
64a318a9f1 see issue #715 2017-08-19 10:20:05 +08:00
Cloud Wu
5e50aeab2b add postfix to datasheet data string 2017-08-18 14:31:25 +08:00
Cloud Wu
53fef98acf fix #718 2017-08-18 14:28:27 +08:00
Cloud Wu
f94ca6f4b3 add socket.disconnected(), used by socketchannle. see #715 2017-08-15 13:44:06 +08:00
Cloud Wu
90536e4a0d fix invalid type of generic response packets, see #712 2017-08-14 10:49:32 +08:00
Cloud Wu
9c37f5292a check direct write buffer before close, see #711 2017-08-11 17:06:01 +08:00
Cloud Wu
23ee7dd814 use skynet.pcall in init, fix #704 2017-08-09 14:34:09 +08:00
Cloud Wu
990bede9b2 can't setenv more than once 2017-08-08 20:35:45 +08:00
Cloud Wu
b8d18d198e update lua version in readme 2017-08-07 15:49:50 +08:00
Cloud Wu
6d81c2b818 use socket.shutdown where timeout 2017-08-01 09:35:16 +08:00
Cloud Wu
f966199f28 update license 2017-07-28 11:35:42 +08:00
Cloud Wu
793fa4fdeb skynet 1.1.0 rc 2017-07-18 11:55:57 +08:00
Cloud Wu
814cd31cee update jemalloc to 5.0.1 2017-07-18 11:27:28 +08:00
云风
bf9466d568 Merge pull request #685 from cloudwu/directwrite
Direct write
2017-07-18 11:08:41 +08:00
Cloud Wu
317b4fb08f merge master 2017-07-14 21:42:15 +08:00
Cloud Wu
2b5c5e3dd3 see pr #683 2017-07-14 21:38:21 +08:00
Cloud Wu
d6eb49e4eb bson dictionary's key can't be number 2017-07-04 21:32:04 +08:00
Cloud Wu
751517d7c1 spinlock can be nested, see issue #646 2017-06-27 22:59:21 +08:00
Cloud Wu
03acc7f5a9 sp_write should be lock 2017-06-27 22:09:41 +08:00
Cloud Wu
9320d8b28d Revert "add nested spinlock, see issue #646"
This reverts commit ba59ed2e6c.
2017-06-27 22:08:33 +08:00
云风
86883c7d9a Merge pull request #677 from sundream/upstream
redis-cluster: ensure port is integer
2017-06-27 19:24:12 +08:00
sundream
2553afd6c9 redis-cluster: ensure port is integer 2017-06-27 18:59:06 +08:00
云风
9fc8754369 Merge pull request #674 from RJie/master
更正connection丢失的问题
2017-06-27 18:14:18 +08:00
Cloud Wu
ba59ed2e6c add nested spinlock, see issue #646 2017-06-27 17:10:48 +08:00
Cloud Wu
14aab9085a Merge branch 'master' into directwrite 2017-06-27 16:15:45 +08:00
Cloud Wu
eb2bc91e3f negative decimal number 2017-06-26 16:32:43 +08:00
RJie
38171f3bc9 更正connection丢失的问题
根据test文件中,输入端口号为number类型,此处应该使用d%,否则只format直进来ip,容易造成同一个ip地址的connection丢失。
2017-06-22 21:18:41 +08:00
Cloud Wu
72b6039328 static const 2017-06-22 09:51:07 +08:00
Cloud Wu
c10cceb1f7 Merge branch 'master' of github.com:cloudwu/skynet 2017-06-21 19:07:16 +08:00
Cloud Wu
7dd78ec89d add crypt.hmac64_md5 2017-06-21 19:05:03 +08:00
云风
01032087ec Merge pull request #672 from Jexocn/master
hook memalign
2017-06-21 17:49:13 +08:00
Cloud Wu
933f6730b2 add comment to hmac64 2017-06-21 17:33:27 +08:00
Jexocn
2b7b51614c Merge branch 'master' of https://github.com/Jexocn/skynet 2017-06-21 17:22:52 +08:00
Jexocn
a9122a9fe1 hook memalign 2017-06-21 17:21:53 +08:00
Jexocn
78ea3d4091 hook memalign 2017-06-21 17:16:16 +08:00
Cloud Wu
b3c60d1de2 add MEMORY_CHECK macro to check double free 2017-06-21 15:41:46 +08:00
Cloud Wu
b438d5a6b0 remove typedef 2017-06-21 15:22:11 +08:00
Cloud Wu
aa42534208 use trylock in send_buffer 2017-06-21 11:50:06 +08:00
Cloud Wu
171f8eef01 Merge branch 'directwrite' of github.com:cloudwu/skynet into directwrite 2017-06-20 22:52:47 +08:00
Cloud Wu
e96b4e782d bugfix: lock bug & udp direct write 2017-06-20 22:50:09 +08:00
hongl
626ad544b7 send crash 2017-06-20 22:50:09 +08:00
Cloud Wu
c53da829d3 direct write if send queue is empty 2017-06-20 22:50:09 +08:00
Cloud Wu
eeb06014da Merge branch 'directwrite' of github.com:cloudwu/skynet into directwrite 2017-06-19 11:48:46 +08:00
Cloud Wu
cc138adda9 bugfix: lock bug & udp direct write 2017-06-19 11:48:17 +08:00
云风
5632dbeec3 Merge pull request #667 from hongling0/directwrite
send crash
2017-06-16 17:20:57 +08:00
hongl
8ca47f76bf send crash 2017-06-16 17:01:58 +08:00
云风
48e031f2fb Merge pull request #664 from hongling0/master
让service.lua可以在用一个服务中复用
2017-06-14 11:23:04 +08:00
hongl
5479848df6 service.lua可以在用一个服务中复用 2017-06-14 10:27:04 +08:00
Cloud Wu
52026eb8f2 missing file: fix #661 2017-06-13 14:35:29 +08:00
云风
af1769aa25 Merge pull request #660 from hongling0/master
skynet.profile
2017-06-13 11:12:23 +08:00
hongl
953fa2c819 skynet.profile 2017-06-13 10:54:13 +08:00
hong
6f670685e2 Merge pull request #2 from cloudwu/master
update origin
2017-06-13 10:50:17 +08:00
Cloud Wu
9618dd47ce direct write if send queue is empty 2017-06-08 20:02:39 +08:00
云风
c72a133178 Merge pull request #657 from cloudwu/datasheet
Datasheet
2017-06-06 16:05:40 +08:00
Cloud Wu
7a4189f830 PROXYCACHE key weak 2017-06-06 16:03:59 +08:00
Cloud Wu
a8b5b36737 remove datasheet.builder.diff 2017-06-06 16:03:59 +08:00
Cloud Wu
6e36cf9940 add skynet.datasheet 2017-06-06 16:03:59 +08:00
Cloud Wu
1328895ff9 copy crypt to client.crypt, see #655 2017-06-06 13:54:51 +08:00
云风
4e54a27500 Merge pull request #654 from mrvon/master
remove wrong prefix
2017-06-05 10:28:58 +08:00
dennis
a0ac8640c7 remove wrong prefix 2017-06-04 23:52:21 +08:00
云风
38e4d81fb1 Merge pull request #651 from sundream/upstream
redis cluster client
2017-06-03 13:53:50 +08:00
sundream
2798c778c7 redis cluster client 2017-06-03 12:26:19 +08:00
Cloud Wu
94374cf06f fix #648 2017-06-02 19:36:39 +08:00
Cloud Wu
624fbf6f22 fix issue #648 2017-06-02 19:16:36 +08:00
云风
5aa3ed8d8f Merge pull request #647 from cloudwu/module
Module namespace
2017-06-02 13:26:38 +08:00
Cloud Wu
c7d2e2cb0e remove debugchannel proxy 2017-06-02 13:24:24 +08:00
Cloud Wu
895c0dae3b skynet.db.mongo 2017-06-01 17:31:19 +08:00
Cloud Wu
1d364b5c22 add skynet.service 2017-06-01 16:58:51 +08:00
Cloud Wu
5a4ebe6a73 move snax to skynet 2017-06-01 12:18:42 +08:00
Cloud Wu
2be915e3c7 compat skynet 1.0 lua module 2017-06-01 12:10:14 +08:00
Cloud Wu
f9f009a4c1 add prefix skynet to c module 2017-06-01 11:56:16 +08:00
Cloud Wu
f1ed482001 move to skynet module 2017-06-01 11:29:07 +08:00
Cloud Wu
8a6243d2a0 rename socket to skynet.socket 2017-06-01 10:51:02 +08:00
Cloud Wu
24537b3001 move some module into skynet/ 2017-06-01 10:46:06 +08:00
Cloud Wu
25763fc70b consider EPOLLHUP as EPOLLIN, see #644 2017-05-31 11:00:00 +08:00
Cloud Wu
7400e51451 support error event, see #644 2017-05-27 10:41:29 +08:00
Cloud Wu
a504c5e624 lua 5.3.4 bugfix 2017-05-08 15:07:00 +08:00
Cloud Wu
648504119e bugfix: wakeup sleep 2017-05-08 11:45:50 +08:00
Cloud Wu
acb0c57844 profile.resume_co bugfix 2017-05-04 16:58:24 +08:00
Cloud Wu
ea129cd9f6 bugfix: skynet.coroutine 2017-05-04 00:59:52 +08:00
Cloud Wu
4b2efd4785 add debug info to lua 2017-05-03 13:42:13 +08:00
Cloud Wu
72e3973cf9 decode response nil 2017-05-02 16:44:43 +08:00
Cloud Wu
d4eeb1ff28 sproto support response nil 2017-05-02 15:29:48 +08:00
云风
fd427843a9 Merge pull request #631 from thomasheep/dev_socket_opt2
optimize SOCKET_WARNING msg
2017-04-28 15:18:45 +08:00
silveratom
73e61a9cc6 Update socketchannel.lua 2017-04-28 15:17:12 +08:00
Stocom
cce8f0086a optimize SOCKET_WARNING msg 2017-04-28 10:49:30 +08:00
Cloud Wu
a7be332023 don't check response, because gate use a fake session for PTYPE_CLIENT 2017-04-26 18:01:05 +08:00
Cloud Wu
3fb46241f2 raise error when you forget response the request, fix issue #625 2017-04-25 11:38:29 +08:00
Cloud Wu
1153873321 minor fix 2017-04-24 15:28:15 +08:00
云风
000b46ec37 Merge pull request #623 from t0350/sharedata
error report on sharedata newindex
2017-04-24 15:26:41 +08:00
caijietao
3b6b31266d error report on sharedata newindex 2017-04-24 15:23:12 +08:00
Cloud Wu
89d771929a add print in testmongodb 2017-04-20 18:52:02 +08:00
Cloud Wu
77ed1bd68b add check for testbson 2017-04-20 18:48:15 +08:00
云风
b7d79ff343 Merge pull request #619 from cloudwu/bsonfix
destroy bson object when encode error
2017-04-20 18:43:37 +08:00
Cloud Wu
dab5a4e308 mongo.sort 2017-04-20 18:37:27 +08:00
Cloud Wu
999a941110 destroy bson object when encode error 2017-04-20 17:57:44 +08:00
Cloud Wu
ad36be1bd7 bugfix: http://lua-users.org/lists/lua-l/2017-04/msg00045.html 2017-04-20 11:26:22 +08:00
Cloud Wu
66f8fbd1b7 see issue #615 2017-04-19 10:50:48 +08:00
云风
7b10ee8d56 Merge pull request #614 from dongjinxian/master
1、remove not used require file
2017-04-18 16:26:39 +08:00
djx
62a4bcdc71 1、remove not used require file 2017-04-18 16:03:01 +08:00
Cloud Wu
312943c6a0 connect timeout, see #611 2017-04-13 15:32:54 +08:00
Cloud Wu
61d13846cd fix a bug , issue #592 2017-04-12 17:04:58 +08:00
Cloud Wu
8e7796a672 lpeg 1.0.1 2017-04-11 13:09:24 +08:00
Cloud Wu
6fa241453c redirect support alloc session 2017-04-07 11:11:39 +08:00
Cloud Wu
1f4a84edc2 fix dns bug , see issue #605 2017-04-06 11:57:28 +08:00
Cloud Wu
6699279d53 update sproto 2017-04-05 14:16:17 +08:00
Cloud Wu
2a79d7bed9 add FAQ in comment 2017-03-31 17:51:11 +08:00
Cloud Wu
fd0291845f proto.request is the condition 2017-03-28 18:54:14 +08:00
Cloud Wu
570a8356e6 add comment 2017-03-25 15:05:39 +08:00
Cloud Wu
6289b2b8e4 complete cluster.send 2017-03-25 00:10:23 +08:00
Cloud Wu
3a4a673b43 enhance config include 2017-03-21 11:49:04 +08:00
Cloud Wu
67b055009d bugfix isse #592 2017-03-20 16:25:15 +08:00
Cloud Wu
80d9ec379f config support include 2017-03-20 14:32:05 +08:00
Cloud Wu
673ffcce00 close stdfds after write_pid, see issue #590 2017-03-19 11:38:25 +08:00
Cloud Wu
6170346da2 add LUAMOD_API 2017-03-16 15:24:11 +08:00
Cloud Wu
b00b006c4a update jemalloc 4.5.0 2017-03-14 21:01:26 +08:00
Cloud Wu
48034ae22e merge sproto 2017-03-14 20:56:49 +08:00
Cloud Wu
1cdc0d7558 add cluster.reload(config) 2017-03-13 17:24:39 +08:00
Cloud Wu
cb19ab54e9 keep skynet.wakeup order, see issue #587 2017-03-13 17:01:41 +08:00
Cloud Wu
feab147563 revert, see issue #579 2017-03-10 14:06:53 +08:00
云风
f5911342e8 Merge pull request #579 from footer/master
nice error log in skynet coroutine
2017-03-06 15:22:56 +08:00
footer
c6cbc2f6b6 nice error log in skynet coroutine 2017-03-06 14:47:03 +08:00
Cloud Wu
ca290355fa add assert 2017-03-03 10:52:25 +08:00
Cloud Wu
2b55bc57a4 do not response send, may fix issue #578 2017-03-02 14:21:56 +08:00
Cloud Wu
5c831e2465 fix issue #574 2017-02-13 11:48:31 +08:00
云风
521a387271 Merge pull request #573 from hqwrong/pr
improve snax
2017-02-10 11:43:37 +08:00
hqwrong
f25e396181 1. snax hotfix recursively patch func
2. load hotfix source with _ENV instead of empty table
2017-02-10 11:01:36 +08:00
hqwrong
6fd1072fde fix snax hotfix 2017-02-10 11:01:36 +08:00
hqwrong
d637d720db snax loader 2017-02-10 11:01:36 +08:00
hqwrong
5c508e45a7 pcall->xpcall 2017-02-10 11:01:36 +08:00
Cloud Wu
2e919505f1 bson check utf8 string 2017-02-09 17:33:30 +08:00
Cloud Wu
af6b5609de add checksig in OP_FORLOOP, see issue #568 2017-01-23 16:50:34 +08:00
Cloud Wu
9e90ee2dde update to 5.3.4 rc3 2017-01-13 10:59:10 +08:00
Cloud Wu
8bc018fe20 update to jemalloc 4.4.0 2017-01-03 10:53:56 +08:00
Cloud Wu
2dbb0129d3 update to lua 5.3.4 2017-01-03 10:44:39 +08:00
云风
f10793e99b Merge pull request #563 from dingmingxin/master
add snax.profile_info interface
2016-12-16 10:35:01 +08:00
dmx
1e51af2d62 get snax profile_table after rewriting info_func of snax service 2016-12-15 15:59:23 +08:00
Cloud Wu
7ee9cdb29b dummy session is 1 2016-12-02 21:23:12 +08:00
Cloud Wu
a3eccf5e37 trash message 2016-12-02 20:49:16 +08:00
Cloud Wu
ace41d7c22 clusterd support send 2016-12-02 20:43:06 +08:00
云风
d0a41eb494 Merge pull request #562 from wyaocn/patch-1
skynet.lua raw_dispatch_message
2016-12-02 16:04:39 +08:00
Wei Yao
060e5384f5 skynet.lua raw_dispatch_message
似乎少了个session判断
2016-12-02 11:43:14 +08:00
云风
0e6a106180 Merge pull request #557 from lipeiyuan/master
modify debug_console result string
2016-11-22 19:43:33 +08:00
lpy
bac383441e modify debug_console result string 2016-11-22 19:37:10 +08:00
云风
3498bf9329 Merge pull request #555 from lipeiyuan/master
pass the inject code error to debug_console
2016-11-22 11:36:23 +08:00
lpy
708d57a77e pass the inject code error to debug_console 2016-11-22 11:14:07 +08:00
Cloud Wu
c5fb8ef3f7 add sharedata.deepcopy 2016-11-14 13:05:01 +08:00
Cloud Wu
ffe5de468e add skynet.stat 'time' 2016-10-26 18:01:22 +08:00
Cloud Wu
249ffb9362 add skynet.stat() to get cpu cost and message count 2016-10-26 17:43:52 +08:00
Cloud Wu
07a1499886 bugfix: profile 2016-10-26 16:28:36 +08:00
Cloud Wu
9c6f8f8b82 add sharedata.flush() to collect old version immediately 2016-10-11 12:06:11 +08:00
Cloud Wu
f48eeca667 add debug command call 2016-09-26 13:07:55 +08:00
Cloud Wu
ccb0e1b24c suppot httpc.timeout 2016-09-24 12:28:57 +08:00
云风
18bc3216ae Merge pull request #536 from hanyu363/master
[bugfix] alpine linux 编译不通过。
2016-09-08 21:37:05 +08:00
张玮华
0782b355a4 [bugfix] alpine linux 编译不通过。 2016-09-08 15:18:35 +08:00
Cloud Wu
c91efa5134 debug_console support user defined ip 2016-09-01 17:53:25 +08:00
Cloud Wu
26ad20aa2b debug cmem print total memory used 2016-08-25 11:55:13 +08:00
Cloud Wu
283c3f10fe bugfix: Issue #531 2016-08-08 17:48:10 +08:00
云风
2f23367671 Merge pull request #530 from learno/master
sort support multi key
2016-08-04 13:56:11 +08:00
Learno
c082d71a56 sort support multi key 2016-08-04 12:44:11 +08:00
Cloud Wu
e2fa2a1a4d lua5.3.3 bugfix 2/3 2016-08-01 14:18:13 +08:00
云风
9882dd1cfd Merge pull request #528 from puXiaoyi/skynet_pr
fix comment for lpushbuffer
2016-07-14 15:15:12 +08:00
puXiaoyi
b278106336 fix comment for lpushbuffer
The size of first chunk ([2]) is 16 struct buffer_node, and the second
size is 32 ...
2016-07-14 13:49:06 +08:00
Cloud Wu
97538286fd 1.0.0 Released 2016-07-11 19:39:45 +08:00
Cloud Wu
fd1b230a54 1.0.0 rc5 2016-07-04 16:31:58 +08:00
Cloud Wu
33321e89a1 don't launch console service when in daemon mode 2016-06-28 18:31:12 +08:00
云风
b50e663a3a Merge pull request #525 from zxfishhack/master
auto determine primary host
2016-06-27 11:39:15 +08:00
zxfishhack
14a699cb85 auto determine primary host 2016-06-27 10:59:50 +08:00
Cloud Wu
098d44162b bson support meta array 2016-06-23 16:14:16 +08:00
Cloud Wu
16af94795e lua 5.3.3 bugfix 1 2016-06-22 22:28:54 +08:00
云风
00f41c6bc9 Merge pull request #521 from ahuang007/patch-1
Update lua-crypt.c
2016-06-21 15:37:56 +08:00
ahuang007
0465688403 Update lua-crypt.c
这个地方应该用G
2016-06-21 15:25:08 +08:00
Cloud Wu
8cd5834d28 Merge branch 'master' of github.com:cloudwu/skynet 2016-06-17 12:19:56 +08:00
Cloud Wu
040089639f memory leak bugfix in multicast, See issue #519 2016-06-17 12:17:53 +08:00
云风
81c4e47a6d Merge pull request #517 from cloudwu/mongoauth
Add mongo auth_scram_sha1 , See pr #492
2016-06-16 09:47:03 +08:00
Cloud Wu
2aef994aa4 add authmod in conf 2016-06-15 17:58:58 +08:00
Cloud Wu
ffa2bbf1e4 support mongo auth_scram_sha1 2016-06-15 16:49:58 +08:00
Cloud Wu
6a54fe8293 1.0.0 rc4 2016-06-13 15:13:17 +08:00
Cloud Wu
2020ce3c9c update jemalloc to 4.2.1 2016-06-13 15:08:33 +08:00
云风
2557559d5c Merge pull request #512 from cloudwu/createindex
add createindexes , for detail see pr #511
2016-06-13 13:12:57 +08:00
Cloud Wu
bb0143e476 add some assert 2016-06-13 12:29:01 +08:00
Cloud Wu
fd2c814fe0 default key ascending 2016-06-13 12:13:02 +08:00
Cloud Wu
bd3d9b70ec change arg name 2016-06-13 12:05:52 +08:00
Cloud Wu
ee1a218870 typo 2016-06-13 12:01:54 +08:00
Cloud Wu
84ee3da79a add mongo.createIndexs, and fix the bug in old API createIndex. For detail, see PR #511 2016-06-13 11:55:31 +08:00
云风
fdee7de36d Merge pull request #509 from dpull/master
重新设计debug.lua接口
2016-06-12 16:41:18 +08:00
dpull
bf5b74b6ca 重新设计debug.lua接口 2016-06-12 16:29:47 +08:00
Cloud Wu
d9b0347741 don't close fd twice 2016-06-12 15:07:56 +08:00
Cloud Wu
9546537256 debug console support simple http 2016-06-12 14:51:18 +08:00
Cloud Wu
f84fe84b96 update userlog 2016-06-12 13:48:53 +08:00
Cloud Wu
ea9bc53261 reopen log file when recv signal HUP 2016-06-12 13:40:23 +08:00
Cloud Wu
0edb839c95 Lua 5.3.3 released 2016-06-07 09:43:43 +08:00
Cloud Wu
b8bb327f98 make coroutine_pool weak would be better 2016-06-06 16:23:39 +08:00
cloudwu
27d69334ee Merge pull request #506 from rickone/master
Update socketchannel.lua
2016-06-05 01:07:42 +08:00
rickone
838e63ab62 Update socketchannel.lua
request的时候可能会连接失败,这时raise的不是socket_error,上层处理不太统一。
2016-06-04 16:26:07 +08:00
Cloud Wu
ba264700dc update jemalloc to 4.2.0 2016-05-31 09:36:21 +08:00
Cloud Wu
e00ad7ab79 update to lua 5.3.3 rc3 2016-05-31 09:30:21 +08:00
Cloud Wu
de176b735f update to lua 5.3.3 rc2 2016-05-19 13:16:19 +08:00
cloudwu
cc3e985834 Merge pull request #502 from pigparadise/cloudwu
lua_bson的encode方法增加对有自定义__pairs的table的支持
2016-05-19 13:19:21 +08:00
LiuYang
3b5f45eea2 lua_bson的encode方法增加对有自定义__pairs的table的支持 2016-05-19 13:10:33 +08:00
cloudwu
c3056b04c1 Merge pull request #498 from asanosoyokaze/patch-1
add vararg for INFO debug console command
2016-05-16 19:35:02 +08:00
David Feng
58755a6772 add vararg for INFO debug console command 2016-05-16 18:57:40 +08:00
Cloud Wu
1cf976c4e4 add debug console command : ping 2016-05-13 09:46:44 +08:00
Cloud Wu
5be836527c bugfix issue #494 2016-05-11 22:02:10 +08:00
Cloud Wu
e9f397945d bugfix issue #494 2016-05-10 16:59:34 +08:00
Cloud Wu
78df0b8161 refine code 2016-05-09 19:16:29 +08:00
cloudwu
db17245005 Merge pull request #493 from chenkete/master
修复redis auth操作没有进行compose_message的bug,该bug导致skynet连接twemproxy时,auth失败
2016-05-09 19:17:56 +08:00
chenkete
4edb586077 修复redis auth操作没有进行compose_message的bug,该bug导致skynet连接twemproxy时,auth失败 2016-05-09 17:16:37 +08:00
Cloud Wu
ed1a8313f4 1.0.0 rc3 2016-05-09 10:06:32 +08:00
Cloud Wu
c450b7b5d7 update jemaloc to 4.1.1 2016-05-09 09:56:30 +08:00
Cloud Wu
56846b7dda new script to check deadloop service 2016-05-09 09:47:01 +08:00
Cloud Wu
fb232cc43e update lua to 5.3.3 rc1 2016-05-09 09:45:40 +08:00
Cloud Wu
a5c79cc4bd move skynet.memlimit from skynet.manager to skynet 2016-05-07 09:23:01 +08:00
Cloud Wu
4b96ade660 support sandbox memory limit 2016-05-06 23:40:44 +08:00
Cloud Wu
76d1e6fa1f memory warning 2016-05-06 20:37:51 +08:00
Cloud Wu
a6299a0748 optimize skynet.error 2016-05-06 20:10:11 +08:00
Cloud Wu
6cc558bb82 output Exit when new service exit 2016-05-06 19:45:50 +08:00
Cloud Wu
84b08bf286 detect console fd closed 2016-05-06 19:37:16 +08:00
Cloud Wu
4ada09b93c add pcall in launcher 2016-05-06 14:06:38 +08:00
Cloud Wu
2862568eca typo in history 2016-04-29 16:25:12 +08:00
cloudwu
ed2e16a346 Merge pull request #491 from asanosoyokaze/patch-go
skynet.pcall support vararg; sharedata loader can use custom args
2016-04-27 21:44:59 +08:00
David Feng
45d46b9072 skynet.pcall support vararg; sharedata loader can use custom args 2016-04-27 20:53:05 +08:00
Cloud Wu
4924c6d30b Merge branch 'master' of github.com:cloudwu/skynet 2016-04-20 22:35:29 +08:00
Cloud Wu
6b2eb80188 fix #487 2016-04-20 22:35:01 +08:00
cloudwu
298e4baf0e Merge pull request #485 from dpull/patch-1
给dbgcmd增加扩展性
2016-04-20 10:24:54 +08:00
Cloud Wu
c5fb93823a update sproto, fix bug in sproto.default 2016-04-20 10:11:55 +08:00
Acai
f238113677 给dbgcmd增加扩展性
我们项目增加了一个dbgcmd的指令,主要用于热更新,但在升级skynet版本时,需要记得合并这个差异,感觉挺挫的。

但现有的debug.lua并不利于扩展,于是呢,我想通过给debug.lua增加一个upvalue来解决这个问题。

其实也是解决的挺挫的 :)
2016-04-19 21:11:31 +08:00
Cloud Wu
f56d777cc2 for compatible 2016-04-18 12:05:46 +08:00
Cloud Wu
b124d4c1b8 skynet.getenv can return empty string 2016-04-18 11:55:39 +08:00
cloudwu
4fe098713f Merge pull request #483 from t0350/master
bugfix, error when use lua apicheck
2016-04-08 10:34:45 +08:00
caijietao
146f8ea09d bugfix, error when use lua apicheck 2016-04-08 10:29:34 +08:00
Cloud Wu
69b5bd8c13 update sproto. support encode empty table 2016-04-07 10:12:30 +08:00
cloudwu
dd7e962c94 Merge pull request #480 from rickone/master
Update redis.lua
2016-04-01 14:33:10 +08:00
rickone
5332021086 Update redis.lua
exec执行时其中一条出错,看不到错误信息
2016-04-01 12:39:09 +08:00
Cloud Wu
8de3149485 request global name from master, see issue #476 2016-04-01 10:22:57 +08:00
cloudwu
e3fee604e1 Merge pull request #478 from xjdrew/skynet_init
skynet.init按照顺序初始化
2016-03-31 17:51:29 +08:00
xjdrew
dd152fc910 skynet.init按照顺序初始化 2016-03-31 17:33:47 +08:00
Cloud Wu
c4b45acae3 sproto: check args 2016-03-29 12:34:55 +08:00
cloudwu
cf50a582f2 Merge pull request #474 from felixonmars/patch-1
Improve some English in README
2016-03-24 17:53:00 +08:00
Felix Yan
ca5e855c34 Improve some English in README 2016-03-24 17:48:43 +08:00
Cloud Wu
13d1d9fc9d update jemalloc to 4.1.0 2016-03-24 16:29:00 +08:00
Cloud Wu
242ff32bca lua 5.3.2 bugfix 2/3 2016-03-24 16:19:06 +08:00
cloudwu
ba451c1cd2 Merge pull request #465 from mrvon/master
skynet.coroutine
2016-03-11 15:28:56 +08:00
dennis
e5490522ce this line is useless 2016-03-09 17:50:33 +08:00
dennis
ae717c3e7d Merge remote-tracking branch 'upstream/master' 2016-03-09 17:48:16 +08:00
cloudwu
1a7df9108a Merge pull request #463 from great90/master
delete unused local variable
2016-03-08 11:34:25 +08:00
great90
7771e180ec delete unused local variable
delete unused local variable table "udp_socket"
2016-03-08 11:25:59 +08:00
great90
82bbb1c944 Merge pull request #3 from cloudwu/master
release rc2
2016-03-08 11:21:18 +08:00
Cloud Wu
cbf22ac9f3 release rc2 2016-03-07 11:46:30 +08:00
great90
bacaf10f1b Merge pull request #2 from cloudwu/master
update from cloudwu
2016-03-02 09:08:40 +08:00
Cloud Wu
8f7fa6a562 merge sproto 2016-02-25 14:40:24 +08:00
cloudwu
7b96eb28eb Merge pull request #455 from niuys/patch-2
error deal for query containing multi statement
2016-02-22 16:15:51 +08:00
snail
14ccf96eb0 error deal for query containing multi statement
A query may execute multi sql statements.If an error occurs for any sql, the result should return the error info.
2016-02-22 11:23:35 +08:00
dennis
6303886b8c Merge remote-tracking branch 'upstream/master' 2016-02-15 10:12:09 +08:00
Cloud Wu
ea8557296b fix issue #450 2016-02-13 19:20:07 +08:00
cloudwu
2a821fb62a Merge pull request #445 from DavidFeng/patch
fix
2016-01-27 13:55:14 +08:00
David Feng
d982009260 fix 2016-01-27 10:35:48 +08:00
cloudwu
a3f028ee3d Merge pull request #444 from DavidFeng/patch-1
修复调试模块调试结束后定时器没有取消的问题
2016-01-22 11:05:04 +08:00
David Feng
d34b092cdd remotedebug.lua call skynet.timeout() only in debug hook
定时器在debug结束后没有取消。
2016-01-22 10:28:03 +08:00
David Feng
77f4071191 remove unused local variables 2016-01-22 10:26:13 +08:00
cloudwu
653b29145d Merge pull request #442 from DavidFeng/patch-2
change socket.write to socketdriver.send
2016-01-20 22:05:23 +08:00
David Feng
96e0a4e3cc change socket.write to socketdriver.send
这样改过之后可以直接调试使用了gate服务的模块。
因为gate服务注册了socket类型的消息,所以不能和socket模块一块使用;而debug模块只使用到了socket模块的write函数,所以这样修改后对debug的功能并没有影响,但改过之后就可以调试gate服务了。
2016-01-20 19:24:58 +08:00
Cloud Wu
1da92850a0 bugfix: dispatch local global message queue 2016-01-19 17:14:52 +08:00
Cloud Wu
9747cf9aee don't assert here 2016-01-19 16:16:18 +08:00
Cloud Wu
7f45b3fd10 correct maxsz 2016-01-13 13:13:31 +08:00
cloudwu
217ab47577 Merge pull request #435 from niuys/patch-1
reduce needless 'add_string' call
2016-01-11 15:56:52 +08:00
snail
532f47444b reduce needless 'add_string' call
Short strings in lua proto are reused most of the time. The string in SSM may be added by one service and used by other service,  there is no need to call `add_string`,which will call 'new_string' first.
2016-01-11 15:06:51 +08:00
Cloud Wu
24f9ee1560 work thread for channel may not create if you never connect 2016-01-08 18:34:45 +08:00
Cloud Wu
d7a76c7c72 If no content-length, read all. see issue #431 2016-01-07 16:01:17 +08:00
Cloud Wu
c175d66e23 remove unused function 2016-01-06 16:55:15 +08:00
dennis
30cbcfd013 Merge remote-tracking branch 'upstream/master' 2016-01-06 15:57:42 +08:00
Cloud Wu
05003e3e2a sproto.attach also need ud 2016-01-05 17:51:48 +08:00
Cloud Wu
64c2cb1b51 sproto dispatch support ud 2016-01-05 16:06:20 +08:00
cloudwu
7f0e4eac8a Merge pull request #428 from fztcjjl/master
fix comment error
2016-01-04 16:07:50 +08:00
Cloud Wu
141a4d0992 lua 5.3.2 bugfix,see http://lua-users.org/lists/lua-l/2016-01/msg00000.html 2016-01-04 16:01:03 +08:00
fztcjjl
645ce72e7e fix comment error 2016-01-04 14:55:28 +08:00
cloudwu
fca4d67a43 Merge pull request #425 from DeanHH/patch-1
Update skynet_mq.c
2016-01-01 00:08:23 +08:00
DeanHH
014cbb9676 Update skynet_mq.c
Comment error:-)
2015-12-31 17:31:08 +08:00
Dennis
a39e822184 Merge pull request #1 from cloudwu/master
update from origin
2015-12-30 09:51:58 +08:00
great90
716ecccaed Merge pull request #1 from cloudwu/master
update skynet
2015-10-23 14:33:54 +08:00
248 changed files with 8338 additions and 2712 deletions

View File

@@ -1,5 +1,5 @@
/*
** $Id: lpcap.h,v 1.2 2015/02/27 17:13:17 roberto Exp $
** $Id: lpcap.h,v 1.3 2016/09/13 17:45:58 roberto Exp $
*/
#if !defined(lpcap_h)
@@ -11,8 +11,21 @@
/* kinds of captures */
typedef enum CapKind {
Cclose, Cposition, Cconst, Cbackref, Carg, Csimple, Ctable, Cfunction,
Cquery, Cstring, Cnum, Csubst, Cfold, Cruntime, Cgroup
Cclose, /* not used in trees */
Cposition,
Cconst, /* ktable[key] is Lua constant */
Cbackref, /* ktable[key] is "name" of group to get capture */
Carg, /* 'key' is arg's number */
Csimple, /* next node is pattern */
Ctable, /* next node is pattern */
Cfunction, /* ktable[key] is function; next node is pattern */
Cquery, /* ktable[key] is table; next node is pattern */
Cstring, /* ktable[key] is string; next node is pattern */
Cnum, /* numbered capture; 'key' is number of value to return */
Csubst, /* substitution capture; next node is pattern */
Cfold, /* ktable[key] is function; next node is pattern */
Cruntime, /* not used in trees (is uses another type for tree) */
Cgroup /* ktable[key] is group's "name" */
} CapKind;

View File

@@ -1,5 +1,5 @@
/*
** $Id: lpcode.c,v 1.23 2015/06/12 18:36:47 roberto Exp $
** $Id: lpcode.c,v 1.24 2016/09/15 17:46:13 roberto Exp $
** Copyright 2007, Lua.org & PUC-Rio (see 'lpeg.html' for license)
*/
@@ -125,6 +125,27 @@ int tocharset (TTree *tree, Charset *cs) {
}
/*
** Visit a TCall node taking care to stop recursion. If node not yet
** visited, return 'f(sib2(tree))', otherwise return 'def' (default
** value)
*/
static int callrecursive (TTree *tree, int f (TTree *t), int def) {
int key = tree->key;
assert(tree->tag == TCall);
assert(sib2(tree)->tag == TRule);
if (key == 0) /* node already visited? */
return def; /* return default value */
else { /* first visit */
int result;
tree->key = 0; /* mark call as already visited */
result = f(sib2(tree)); /* go to called rule */
tree->key = key; /* restore tree */
return result;
}
}
/*
** Check whether a pattern tree has captures
*/
@@ -134,14 +155,17 @@ int hascaptures (TTree *tree) {
case TCapture: case TRunTime:
return 1;
case TCall:
tree = sib2(tree); goto tailcall; /* return hascaptures(sib2(tree)); */
return callrecursive(tree, hascaptures, 0);
case TRule: /* do not follow siblings */
tree = sib1(tree); goto tailcall;
case TOpenCall: assert(0);
default: {
switch (numsiblings[tree->tag]) {
case 1: /* return hascaptures(sib1(tree)); */
tree = sib1(tree); goto tailcall;
case 2:
if (hascaptures(sib1(tree))) return 1;
if (hascaptures(sib1(tree)))
return 1;
/* else return hascaptures(sib2(tree)); */
tree = sib2(tree); goto tailcall;
default: assert(numsiblings[tree->tag] == 0); return 0;
@@ -208,9 +232,9 @@ int checkaux (TTree *tree, int pred) {
/*
** number of characters to match a pattern (or -1 if variable)
** ('count' avoids infinite loops for grammars)
*/
int fixedlenx (TTree *tree, int count, int len) {
int fixedlen (TTree *tree) {
int len = 0; /* to accumulate in tail calls */
tailcall:
switch (tree->tag) {
case TChar: case TSet: case TAny:
@@ -220,26 +244,29 @@ int fixedlenx (TTree *tree, int count, int len) {
case TRep: case TRunTime: case TOpenCall:
return -1;
case TCapture: case TRule: case TGrammar:
/* return fixedlenx(sib1(tree), count); */
/* return fixedlen(sib1(tree)); */
tree = sib1(tree); goto tailcall;
case TCall:
if (count++ >= MAXRULES)
return -1; /* may be a loop */
/* else return fixedlenx(sib2(tree), count); */
tree = sib2(tree); goto tailcall;
case TCall: {
int n1 = callrecursive(tree, fixedlen, -1);
if (n1 < 0)
return -1;
else
return len + n1;
}
case TSeq: {
len = fixedlenx(sib1(tree), count, len);
if (len < 0) return -1;
/* else return fixedlenx(sib2(tree), count, len); */
tree = sib2(tree); goto tailcall;
int n1 = fixedlen(sib1(tree));
if (n1 < 0)
return -1;
/* else return fixedlen(sib2(tree)) + len; */
len += n1; tree = sib2(tree); goto tailcall;
}
case TChoice: {
int n1, n2;
n1 = fixedlenx(sib1(tree), count, len);
if (n1 < 0) return -1;
n2 = fixedlenx(sib2(tree), count, len);
if (n1 == n2) return n1;
else return -1;
int n1 = fixedlen(sib1(tree));
int n2 = fixedlen(sib2(tree));
if (n1 != n2 || n1 < 0)
return -1;
else
return len + n1;
}
default: assert(0); return 0;
};
@@ -710,9 +737,10 @@ static void codeand (CompileState *compst, TTree *tree, int tt) {
/*
** Captures: if pattern has fixed (and not too big) length, use
** a single IFullCapture instruction after the match; otherwise,
** enclose the pattern with OpenCapture - CloseCapture.
** Captures: if pattern has fixed (and not too big) length, and it
** has no nested captures, use a single IFullCapture instruction
** after the match; otherwise, enclose the pattern with OpenCapture -
** CloseCapture.
*/
static void codecapture (CompileState *compst, TTree *tree, int tt,
const Charset *fl) {

View File

@@ -1,5 +1,5 @@
/*
** $Id: lpcode.h,v 1.7 2015/06/12 18:24:45 roberto Exp $
** $Id: lpcode.h,v 1.8 2016/09/15 17:46:13 roberto Exp $
*/
#if !defined(lpcode_h)
@@ -13,7 +13,7 @@
int tocharset (TTree *tree, Charset *cs);
int checkaux (TTree *tree, int pred);
int fixedlenx (TTree *tree, int count, int len);
int fixedlen (TTree *tree);
int hascaptures (TTree *tree);
int lp_gc (lua_State *L);
Instruction *compile (lua_State *L, Pattern *p);
@@ -35,8 +35,6 @@ int sizei (const Instruction *i);
*/
#define nullable(t) checkaux(t, PEnullable)
#define fixedlen(t) fixedlenx(t, 0, 0)
#endif

View File

@@ -10,7 +10,7 @@
</head>
<body>
<!-- $Id: lpeg.html,v 1.75 2015/09/28 17:17:41 roberto Exp $ -->
<!-- $Id: lpeg.html,v 1.77 2017/01/13 13:40:05 roberto Exp $ -->
<div id="container">
@@ -577,8 +577,9 @@ It is equivalent to the following grammar in standard PEG notation:
<h2><a name="captures">Captures</a></h2>
<p>
A <em>capture</em> is a pattern that creates values
(the so called <em>semantic information</em>) when it matches.
A <em>capture</em> is a pattern that produces values
(the so called <em>semantic information</em>)
according to what it matches.
LPeg offers several kinds of captures,
which produces values based on matches and combine these values to
produce new values.
@@ -632,10 +633,7 @@ or no value when <code>number</code> is zero.</td></tr>
</tbody></table>
<p>
A capture pattern produces its values every time it succeeds.
For instance,
a capture inside a loop produces as many values as matched by the loop.
A capture produces a value only when it succeeds.
A capture pattern produces its values only when it succeeds.
For instance,
the pattern <code>lpeg.C(lpeg.P"a"^-1)</code>
produces the empty string when there is no <code>"a"</code>
@@ -643,14 +641,20 @@ produces the empty string when there is no <code>"a"</code>
while the pattern <code>lpeg.C("a")^-1</code>
does not produce any value when there is no <code>"a"</code>
(because the pattern <code>"a"</code> fails).
A pattern inside a loop or inside a recursive structure
produces values for each match.
</p>
<p>
Usually,
LPeg evaluates all captures only after (and if) the entire match succeeds.
During <em>match time</em> it only gathers enough information
to produce the capture values later.
As a particularly important consequence,
LPeg does not specify when (and if) it evaluates its captures.
(As an example,
consider the pattern <code>lpeg.P"a" / func / 0</code>.
Because the "division" by 0 instructs LPeg to throw away the
results from the pattern,
LPeg may or may not call <code>func</code>.)
Therefore, captures should avoid side effects.
Moreover,
most captures cannot affect the way a pattern matches a subject.
The only exception to this rule is the
so-called <a href="#matchtime"><em>match-time capture</em></a>.
@@ -700,6 +704,12 @@ An <em>Outermost</em> capture means that the capture is not inside
another complete capture.
</p>
<p>
In the same way that LPeg does not specify when it evaluates captures,
it does not specify whether it reuses
values previously produced by the group
or re-evaluates them.
</p>
<h3><a name="cap-cc"></a><code>lpeg.Cc ([value, ...])</code></h3>
<p>
@@ -806,7 +816,7 @@ all replacements.
<h3><a name="cap-t"></a><code>lpeg.Ct (patt)</code></h3>
<p>
Creates a <em>table capture</em>.
This capture creates a table and puts all values from all anonymous captures
This capture returns a table with all values from all anonymous captures
made by <code>patt</code> inside this table in successive integer keys,
starting at 1.
Moreover,
@@ -872,7 +882,8 @@ there is no captured value.
<p>
Creates a <em>match-time capture</em>.
Unlike all other captures,
this one is evaluated immediately when a match occurs.
this one is evaluated immediately when a match occurs
(even if it is part of a larger pattern that fails later).
It forces the immediate evaluation of all its nested captures
and then calls <code>function</code>.
</p>
@@ -1380,13 +1391,13 @@ and the new term for each repetition.
<h2><a name="download"></a>Download</h2>
<p>LPeg
<a href="http://www.inf.puc-rio.br/~roberto/lpeg/lpeg-1.0.0.tar.gz">source code</a>.</p>
<a href="http://www.inf.puc-rio.br/~roberto/lpeg/lpeg-1.0.1.tar.gz">source code</a>.</p>
<h2><a name="license">License</a></h2>
<p>
Copyright &copy; 2007-2015 Lua.org, PUC-Rio.
Copyright &copy; 2007-2017 Lua.org, PUC-Rio.
</p>
<p>
Permission is hereby granted, free of charge,
@@ -1424,7 +1435,7 @@ THE SOFTWARE.
<div id="about">
<p><small>
$Id: lpeg.html,v 1.75 2015/09/28 17:17:41 roberto Exp $
$Id: lpeg.html,v 1.77 2017/01/13 13:40:05 roberto Exp $
</small></p>
</div> <!-- id="about" -->

View File

@@ -1,5 +1,5 @@
/*
** $Id: lpprint.c,v 1.9 2015/06/15 16:09:57 roberto Exp $
** $Id: lpprint.c,v 1.10 2016/09/13 16:06:03 roberto Exp $
** Copyright 2007, Lua.org & PUC-Rio (see 'lpeg.html' for license)
*/
@@ -37,13 +37,13 @@ void printcharset (const byte *st) {
}
static void printcapkind (int kind) {
static const char *capkind (int kind) {
const char *const modes[] = {
"close", "position", "constant", "backref",
"argument", "simple", "table", "function",
"query", "string", "num", "substitution", "fold",
"runtime", "group"};
printf("%s", modes[kind]);
return modes[kind];
}
@@ -73,13 +73,12 @@ void printinst (const Instruction *op, const Instruction *p) {
break;
}
case IFullCapture: {
printcapkind(getkind(p));
printf(" (size = %d) (idx = %d)", getoff(p), p->i.key);
printf("%s (size = %d) (idx = %d)",
capkind(getkind(p)), getoff(p), p->i.key);
break;
}
case IOpenCapture: {
printcapkind(getkind(p));
printf(" (idx = %d)", p->i.key);
printf("%s (idx = %d)", capkind(getkind(p)), p->i.key);
break;
}
case ISet: {
@@ -124,8 +123,8 @@ void printpatt (Instruction *p, int n) {
#if defined(LPEG_DEBUG)
static void printcap (Capture *cap) {
printcapkind(cap->kind);
printf(" (idx: %d - size: %d) -> %p\n", cap->idx, cap->siz, cap->s);
printf("%s (idx: %d - size: %d) -> %p\n",
capkind(cap->kind), cap->idx, cap->siz, cap->s);
}
@@ -177,7 +176,8 @@ void printtree (TTree *tree, int ident) {
break;
}
case TOpenCall: case TCall: {
printf(" key: %d\n", tree->key);
assert(sib2(tree)->tag == TRule);
printf(" key: %d (rule: %d)\n", tree->key, sib2(tree)->cap);
break;
}
case TBehind: {
@@ -186,7 +186,7 @@ void printtree (TTree *tree, int ident) {
break;
}
case TCapture: {
printf(" cap: %d key: %d n: %d\n", tree->cap, tree->key, tree->u.n);
printf(" kind: '%s' key: %d\n", capkind(tree->cap), tree->key);
printtree(sib1(tree), ident + 2);
break;
}

View File

@@ -1,5 +1,5 @@
/*
** $Id: lptree.c,v 1.21 2015/09/28 17:01:25 roberto Exp $
** $Id: lptree.c,v 1.22 2016/09/13 18:10:22 roberto Exp $
** Copyright 2013, Lua.org & PUC-Rio (see 'lpeg.html' for license)
*/
@@ -64,7 +64,7 @@ static void fixonecall (lua_State *L, int postable, TTree *g, TTree *t) {
t->tag = TCall;
t->u.ps = n - (t - g); /* position relative to node */
assert(sib2(t)->tag == TRule);
sib2(t)->key = t->key;
sib2(t)->key = t->key; /* fix rule's key */
}
@@ -935,7 +935,7 @@ static void buildgrammar (lua_State *L, TTree *grammar, int frule, int n) {
int rulesize;
TTree *rn = gettree(L, ridx, &rulesize);
nd->tag = TRule;
nd->key = 0;
nd->key = 0; /* will be fixed when rule is used */
nd->cap = i; /* rule number */
nd->u.ps = rulesize + 1; /* point to next rule */
memcpy(sib1(nd), rn, rulesize * sizeof(TTree)); /* copy rule */
@@ -969,6 +969,11 @@ static int checkloops (TTree *tree) {
}
/*
** Give appropriate error message for 'verifyrule'. If a rule appears
** twice in 'passed', there is path from it back to itself without
** advancing the subject.
*/
static int verifyerror (lua_State *L, int *passed, int npassed) {
int i, j;
for (i = npassed - 1; i >= 0; i--) { /* search for a repetition */
@@ -990,6 +995,8 @@ static int verifyerror (lua_State *L, int *passed, int npassed) {
** is only relevant if the first is nullable.
** Parameter 'nb' works as an accumulator, to allow tail calls in
** choices. ('nb' true makes function returns true.)
** Parameter 'passed' is a list of already visited rules, 'npassed'
** counts the elements in 'passed'.
** Assume ktable at the top of the stack.
*/
static int verifyrule (lua_State *L, TTree *tree, int *passed, int npassed,

View File

@@ -1,5 +1,5 @@
/*
** $Id: lptree.h,v 1.2 2013/03/24 13:51:12 roberto Exp $
** $Id: lptree.h,v 1.3 2016/09/13 18:07:51 roberto Exp $
*/
#if !defined(lptree_h)
@@ -13,38 +13,43 @@
** types of trees
*/
typedef enum TTag {
TChar = 0, TSet, TAny, /* standard PEG elements */
TTrue, TFalse,
TRep,
TSeq, TChoice,
TNot, TAnd,
TCall,
TOpenCall,
TRule, /* sib1 is rule's pattern, sib2 is 'next' rule */
TGrammar, /* sib1 is initial (and first) rule */
TBehind, /* match behind */
TCapture, /* regular capture */
TRunTime /* run-time capture */
TChar = 0, /* 'n' = char */
TSet, /* the set is stored in next CHARSETSIZE bytes */
TAny,
TTrue,
TFalse,
TRep, /* 'sib1'* */
TSeq, /* 'sib1' 'sib2' */
TChoice, /* 'sib1' / 'sib2' */
TNot, /* !'sib1' */
TAnd, /* &'sib1' */
TCall, /* ktable[key] is rule's key; 'sib2' is rule being called */
TOpenCall, /* ktable[key] is rule's key */
TRule, /* ktable[key] is rule's key (but key == 0 for unused rules);
'sib1' is rule's pattern;
'sib2' is next rule; 'cap' is rule's sequential number */
TGrammar, /* 'sib1' is initial (and first) rule */
TBehind, /* 'sib1' is pattern, 'n' is how much to go back */
TCapture, /* captures: 'cap' is kind of capture (enum 'CapKind');
ktable[key] is Lua value associated with capture;
'sib1' is capture body */
TRunTime /* run-time capture: 'key' is Lua function;
'sib1' is capture body */
} TTag;
/* number of siblings for each tree */
extern const byte numsiblings[];
/*
** Tree trees
** The first sibling of a tree (if there is one) is immediately after
** the tree. A reference to a second sibling (ps) is its position
** relative to the position of the tree itself. A key in ktable
** uses the (unique) address of the original tree that created that
** entry. NULL means no data.
** The first child of a tree (if there is one) is immediately after
** the tree. A reference to a second child (ps) is its position
** relative to the position of the tree itself.
*/
typedef struct TTree {
byte tag;
byte cap; /* kind of capture (if it is a capture) */
unsigned short key; /* key in ktable for Lua data (0 if no key) */
union {
int ps; /* occasional second sibling */
int ps; /* occasional second child */
int n; /* occasional counter */
} u;
} TTree;
@@ -61,10 +66,10 @@ typedef struct Pattern {
} Pattern;
/* number of siblings for each tree */
/* number of children for each tree */
extern const byte numsiblings[];
/* access to siblings */
/* access to children */
#define sib1(t) ((t) + 1)
#define sib2(t) ((t) + (t)->u.ps)

View File

@@ -1,7 +1,7 @@
/*
** $Id: lptypes.h,v 1.14 2015/09/28 17:17:41 roberto Exp $
** $Id: lptypes.h,v 1.16 2017/01/13 13:33:17 roberto Exp $
** LPeg - PEG pattern matching for Lua
** Copyright 2007-2015, Lua.org & PUC-Rio (see 'lpeg.html' for license)
** Copyright 2007-2017, Lua.org & PUC-Rio (see 'lpeg.html' for license)
** written by Roberto Ierusalimschy
*/
@@ -19,7 +19,7 @@
#include "lua.h"
#define VERSION "1.0.0"
#define VERSION "1.0.1"
#define PATTERN_T "lpeg-pattern"
@@ -55,9 +55,9 @@
#endif
/* maximum number of rules in a grammar */
/* maximum number of rules in a grammar (limited by 'unsigned char') */
#if !defined(MAXRULES)
#define MAXRULES 1000
#define MAXRULES 250
#endif

View File

@@ -1,5 +1,5 @@
/*
** $Id: lpvm.c,v 1.6 2015/09/28 17:01:25 roberto Exp $
** $Id: lpvm.c,v 1.9 2016/06/03 20:11:18 roberto Exp $
** Copyright 2007, Lua.org & PUC-Rio (see 'lpeg.html' for license)
*/
@@ -45,14 +45,16 @@ typedef struct Stack {
/*
** Double the size of the array of captures
** Make the size of the array of captures 'cap' twice as large as needed
** (which is 'captop'). ('n' is the number of new elements.)
*/
static Capture *doublecap (lua_State *L, Capture *cap, int captop, int ptop) {
static Capture *doublecap (lua_State *L, Capture *cap, int captop,
int n, int ptop) {
Capture *newc;
if (captop >= INT_MAX/((int)sizeof(Capture) * 2))
luaL_error(L, "too many captures");
newc = (Capture *)lua_newuserdata(L, captop * 2 * sizeof(Capture));
memcpy(newc, cap, captop * sizeof(Capture));
memcpy(newc, cap, (captop - n) * sizeof(Capture));
lua_replace(L, caplistidx(ptop));
return newc;
}
@@ -113,8 +115,8 @@ static int resdyncaptures (lua_State *L, int fr, int curr, int limit) {
*/
static void adddyncaptures (const char *s, Capture *base, int n, int fd) {
int i;
/* Cgroup capture is already there */
assert(base[0].kind == Cgroup && base[0].siz == 0);
base[0].kind = Cgroup; /* create group capture */
base[0].siz = 0;
base[0].idx = 0; /* make it an anonymous group */
for (i = 1; i <= n; i++) { /* add runtime captures */
base[i].kind = Cruntime;
@@ -157,10 +159,11 @@ const char *match (lua_State *L, const char *o, const char *s, const char *e,
lua_pushlightuserdata(L, stackbase);
for (;;) {
#if defined(DEBUG)
printf("s: |%s| stck:%d, dyncaps:%d, caps:%d ",
s, stack - getstackbase(L, ptop), ndyncap, captop);
printinst(op, p);
printf("-------------------------------------\n");
printcaplist(capture, capture + captop);
printf("s: |%s| stck:%d, dyncaps:%d, caps:%d ",
s, (int)(stack - getstackbase(L, ptop)), ndyncap, captop);
printinst(op, p);
#endif
assert(stackidx(ptop) + ndyncap == lua_gettop(L) && ndyncap <= captop);
switch ((Opcode)p->i.code) {
@@ -284,6 +287,9 @@ const char *match (lua_State *L, const char *o, const char *s, const char *e,
ndyncap -= removedyncap(L, capture, stack->caplevel, captop);
captop = stack->caplevel;
p = stack->p;
#if defined(DEBUG)
printf("**FAIL**\n");
#endif
continue;
}
case ICloseRunTime: {
@@ -293,16 +299,19 @@ const char *match (lua_State *L, const char *o, const char *s, const char *e,
cs.s = o; cs.L = L; cs.ocap = capture; cs.ptop = ptop;
n = runtimecap(&cs, capture + captop, s, &rem); /* call function */
captop -= n; /* remove nested captures */
ndyncap -= rem; /* update number of dynamic captures */
fr -= rem; /* 'rem' items were popped from Lua stack */
res = resdyncaptures(L, fr, s - o, e - o); /* get result */
if (res == -1) /* fail? */
goto fail;
s = o + res; /* else update current position */
n = lua_gettop(L) - fr + 1; /* number of new captures */
ndyncap += n - rem; /* update number of dynamic captures */
ndyncap += n; /* update number of dynamic captures */
if (n > 0) { /* any new capture? */
if (fr + n >= SHRT_MAX)
luaL_error(L, "too many results in match-time capture");
if ((captop += n + 2) >= capsize) {
capture = doublecap(L, capture, captop, ptop);
capture = doublecap(L, capture, captop, n + 2, ptop);
capsize = 2 * captop;
}
/* add new captures to 'capture' list */
@@ -339,7 +348,7 @@ const char *match (lua_State *L, const char *o, const char *s, const char *e,
capture[captop].idx = p->i.key;
capture[captop].kind = getkind(p);
if (++captop >= capsize) {
capture = doublecap(L, capture, captop, ptop);
capture = doublecap(L, capture, captop, 0, ptop);
capsize = 2 * captop;
}
p++;

View File

@@ -10,7 +10,7 @@
</head>
<body>
<!-- $Id: re.html,v 1.23 2015/09/28 17:17:41 roberto Exp $ -->
<!-- $Id: re.html,v 1.24 2016/09/20 17:41:27 roberto Exp $ -->
<div id="container">
@@ -406,7 +406,7 @@ of patterns accepted by <code>re</code>.
p = [=[
pattern &lt;- exp !.
exp &lt;- S (alternative / grammar)
exp &lt;- S (grammar / alternative)
alternative &lt;- seq ('/' S seq)*
seq &lt;- prefix*
@@ -488,7 +488,7 @@ THE SOFTWARE.
<div id="about">
<p><small>
$Id: re.html,v 1.23 2015/09/28 17:17:41 roberto Exp $
$Id: re.html,v 1.24 2016/09/20 17:41:27 roberto Exp $
</small></p>
</div> <!-- id="about" -->

View File

@@ -1,6 +1,6 @@
#!/usr/bin/env lua
-- $Id: test.lua,v 1.109 2015/09/28 17:01:25 roberto Exp $
-- $Id: test.lua,v 1.112 2017/01/14 18:55:22 roberto Exp $
-- require"strict" -- just to be pedantic
@@ -202,6 +202,14 @@ do
end
-- bug: loop in 'hascaptures'
do
local p = m.C(-m.P{m.P'x' * m.V(1) + m.P'y'})
assert(p:match("xxx") == "")
end
-- test for small capture boundary
for i = 250,260 do
assert(#m.match(m.C(i), string.rep('a', i)) == i)
@@ -517,6 +525,27 @@ assert(m.match(m.Cs((#((#m.P"a")/"") * 1 + m.P(1)/".")^0), "aloal") == "a..a.")
assert(m.match(m.Cs((- -m.P("a") * 1 + m.P(1)/".")^0), "aloal") == "a..a.")
assert(m.match(m.Cs((-((-m.P"a")/"") * 1 + m.P(1)/".")^0), "aloal") == "a..a.")
-- fixed length
do
-- 'and' predicate using fixed length
local p = m.C(#("a" * (m.P("bd") + "cd")) * 2)
assert(p:match("acd") == "ac")
p = #m.P{ "a" * m.V(2), m.P"b" } * 2
assert(p:match("abc") == 3)
p = #(m.P"abc" * m.B"c")
assert(p:match("abc") == 1 and not p:match("ab"))
p = m.P{ "a" * m.V(2), m.P"b"^1 }
checkerr("pattern may not have fixed length", m.B, p)
p = "abc" * (m.P"b"^1 + m.P"a"^0)
checkerr("pattern may not have fixed length", m.B, p)
end
p = -m.P'a' * m.Cc(1) + -m.P'b' * m.Cc(2) + -m.P'c' * m.Cc(3)
assert(p:match('a') == 2 and p:match('') == 1 and p:match('b') == 1)
@@ -1098,6 +1127,32 @@ do
assert(c == 11)
end
-- Return a match-time capture that returns 'n' captures
local function manyCmt (n)
return m.Cmt("a", function ()
local a = {}; for i = 1, n do a[i] = n - i end
return true, unpack(a)
end)
end
-- bug in 1.0: failed match-time that used previous match-time results
do
local x
local function aux (...) x = #{...}; return false end
local res = {m.match(m.Cmt(manyCmt(20), aux) + manyCmt(10), "a")}
assert(#res == 10 and res[1] == 9 and res[10] == 0)
end
-- bug in 1.0: problems with math-times returning too many captures
do
local lim = 2^11 - 10
local res = {m.match(manyCmt(lim), "a")}
assert(#res == lim and res[1] == lim - 1 and res[lim] == 0)
checkerr("too many", m.match, manyCmt(2^15), "a")
end
p = (m.P(function () return true, "a" end) * 'a'
+ m.P(function (s, i) return i, "aa", 20 end) * 'b'
+ m.P(function (s,i) if i <= #s then return i, "aaa" end end) * 1)^0

View File

@@ -19,7 +19,7 @@ SYSCFLAGS=
SYSLDFLAGS=
SYSLIBS=
MYCFLAGS=-I../../skynet-src
MYCFLAGS=-I../../skynet-src -g
MYLDFLAGS=
MYLIBS=
MYOBJS=

View File

@@ -1,5 +1,5 @@
/*
** $Id: lapi.c,v 2.257 2015/11/02 18:48:07 roberto Exp $
** $Id: lapi.c,v 2.259.1.2 2017/12/06 18:35:12 roberto Exp $
** Lua API
** See Copyright Notice in lua.h
*/
@@ -379,9 +379,9 @@ LUA_API const char *lua_tolstring (lua_State *L, int idx, size_t *len) {
return NULL;
}
lua_lock(L); /* 'luaO_tostring' may create a new string */
luaO_tostring(L, o);
luaC_checkGC(L);
o = index2addr(L, idx); /* previous call may reallocate the stack */
luaO_tostring(L, o);
lua_unlock(L);
}
if (len != NULL)
@@ -480,10 +480,10 @@ LUA_API void lua_pushinteger (lua_State *L, lua_Integer n) {
LUA_API const char *lua_pushlstring (lua_State *L, const char *s, size_t len) {
TString *ts;
lua_lock(L);
luaC_checkGC(L);
ts = (len == 0) ? luaS_new(L, "") : luaS_newlstr(L, s, len);
setsvalue2s(L, L->top, ts);
api_incr_top(L);
luaC_checkGC(L);
lua_unlock(L);
return getstr(ts);
}
@@ -495,12 +495,12 @@ LUA_API const char *lua_pushstring (lua_State *L, const char *s) {
setnilvalue(L->top);
else {
TString *ts;
luaC_checkGC(L);
ts = luaS_new(L, s);
setsvalue2s(L, L->top, ts);
s = getstr(ts); /* internal copy's address */
}
api_incr_top(L);
luaC_checkGC(L);
lua_unlock(L);
return s;
}
@@ -510,8 +510,8 @@ LUA_API const char *lua_pushvfstring (lua_State *L, const char *fmt,
va_list argp) {
const char *ret;
lua_lock(L);
luaC_checkGC(L);
ret = luaO_pushvfstring(L, fmt, argp);
luaC_checkGC(L);
lua_unlock(L);
return ret;
}
@@ -521,10 +521,10 @@ LUA_API const char *lua_pushfstring (lua_State *L, const char *fmt, ...) {
const char *ret;
va_list argp;
lua_lock(L);
luaC_checkGC(L);
va_start(argp, fmt);
ret = luaO_pushvfstring(L, fmt, argp);
va_end(argp);
luaC_checkGC(L);
lua_unlock(L);
return ret;
}
@@ -534,12 +534,12 @@ LUA_API void lua_pushcclosure (lua_State *L, lua_CFunction fn, int n) {
lua_lock(L);
if (n == 0) {
setfvalue(L->top, fn);
api_incr_top(L);
}
else {
CClosure *cl;
api_checknelems(L, n);
api_check(L, n <= MAXUPVAL, "upvalue index too large");
luaC_checkGC(L);
cl = luaF_newCclosure(L, n);
cl->f = fn;
L->top -= n;
@@ -548,8 +548,9 @@ LUA_API void lua_pushcclosure (lua_State *L, lua_CFunction fn, int n) {
/* does not need barrier because closure is white */
}
setclCvalue(L, L->top, cl);
api_incr_top(L);
luaC_checkGC(L);
}
api_incr_top(L);
lua_unlock(L);
}
@@ -586,16 +587,16 @@ LUA_API int lua_pushthread (lua_State *L) {
static int auxgetstr (lua_State *L, const TValue *t, const char *k) {
const TValue *aux;
const TValue *slot;
TString *str = luaS_new(L, k);
if (luaV_fastget(L, t, str, aux, luaH_getstr)) {
setobj2s(L, L->top, aux);
if (luaV_fastget(L, t, str, slot, luaH_getstr)) {
setobj2s(L, L->top, slot);
api_incr_top(L);
}
else {
setsvalue2s(L, L->top, str);
api_incr_top(L);
luaV_finishget(L, t, L->top - 1, L->top - 1, aux);
luaV_finishget(L, t, L->top - 1, L->top - 1, slot);
}
lua_unlock(L);
return ttnov(L->top - 1);
@@ -627,17 +628,17 @@ LUA_API int lua_getfield (lua_State *L, int idx, const char *k) {
LUA_API int lua_geti (lua_State *L, int idx, lua_Integer n) {
StkId t;
const TValue *aux;
const TValue *slot;
lua_lock(L);
t = index2addr(L, idx);
if (luaV_fastget(L, t, n, aux, luaH_getint)) {
setobj2s(L, L->top, aux);
if (luaV_fastget(L, t, n, slot, luaH_getint)) {
setobj2s(L, L->top, slot);
api_incr_top(L);
}
else {
setivalue(L->top, n);
api_incr_top(L);
luaV_finishget(L, t, L->top - 1, L->top - 1, aux);
luaV_finishget(L, t, L->top - 1, L->top - 1, slot);
}
lua_unlock(L);
return ttnov(L->top - 1);
@@ -684,12 +685,12 @@ LUA_API int lua_rawgetp (lua_State *L, int idx, const void *p) {
LUA_API void lua_createtable (lua_State *L, int narray, int nrec) {
Table *t;
lua_lock(L);
luaC_checkGC(L);
t = luaH_new(L);
sethvalue(L, L->top, t);
api_incr_top(L);
if (narray > 0 || nrec > 0)
luaH_resize(L, t, narray, nrec);
luaC_checkGC(L);
lua_unlock(L);
}
@@ -741,15 +742,15 @@ LUA_API int lua_getuservalue (lua_State *L, int idx) {
** t[k] = value at the top of the stack (where 'k' is a string)
*/
static void auxsetstr (lua_State *L, const TValue *t, const char *k) {
const TValue *aux;
const TValue *slot;
TString *str = luaS_new(L, k);
api_checknelems(L, 1);
if (luaV_fastset(L, t, str, aux, luaH_getstr, L->top - 1))
if (luaV_fastset(L, t, str, slot, luaH_getstr, L->top - 1))
L->top--; /* pop value */
else {
setsvalue2s(L, L->top, str); /* push 'str' (to make it a TValue) */
api_incr_top(L);
luaV_finishset(L, t, L->top - 1, L->top - 2, aux);
luaV_finishset(L, t, L->top - 1, L->top - 2, slot);
L->top -= 2; /* pop value and key */
}
lua_unlock(L); /* lock done by caller */
@@ -782,16 +783,16 @@ LUA_API void lua_setfield (lua_State *L, int idx, const char *k) {
LUA_API void lua_seti (lua_State *L, int idx, lua_Integer n) {
StkId t;
const TValue *aux;
const TValue *slot;
lua_lock(L);
api_checknelems(L, 1);
t = index2addr(L, idx);
if (luaV_fastset(L, t, n, aux, luaH_getint, L->top - 1))
if (luaV_fastset(L, t, n, slot, luaH_getint, L->top - 1))
L->top--; /* pop value */
else {
setivalue(L->top, n);
api_incr_top(L);
luaV_finishset(L, t, L->top - 1, L->top - 2, aux);
luaV_finishset(L, t, L->top - 1, L->top - 2, slot);
L->top -= 2; /* pop value and key */
}
lua_unlock(L);
@@ -1012,10 +1013,9 @@ LUA_API int lua_load (lua_State *L, lua_Reader reader, void *data,
return status;
}
static Proto * cloneproto (lua_State *L, const Proto *src) {
static void cloneproto (lua_State *L, Proto *f, const Proto *src) {
/* copy constants and nested proto */
int i,n;
Proto *f = luaF_newproto(L, src->sp);
n = src->sp->sizek;
f->k=luaM_newvector(L,n,TValue);
for (i=0; i<n; i++) setnilvalue(&f->k[i]);
@@ -1033,9 +1033,9 @@ static Proto * cloneproto (lua_State *L, const Proto *src) {
f->p=luaM_newvector(L,n,struct Proto *);
for (i=0; i<n; i++) f->p[i]=NULL;
for (i=0; i<n; i++) {
f->p[i]=cloneproto(L, src->p[i]);
f->p[i]= luaF_newproto(L, src->p[i]->sp);
cloneproto(L, f->p[i], src->p[i]);
}
return f;
}
LUA_API void lua_clonefunction (lua_State *L, const void * fp) {
@@ -1049,9 +1049,10 @@ LUA_API void lua_clonefunction (lua_State *L, const void * fp) {
return;
}
cl = luaF_newLclosure(L,f->nupvalues);
cl->p = cloneproto(L, f->p);
setclLvalue(L,L->top,cl);
api_incr_top(L);
cl->p = luaF_newproto(L, f->p->sp);
cloneproto(L, cl->p, f->p);
luaF_initupvals(L, cl);
if (cl->nupvalues >= 1) { /* does it have an upvalue? */
@@ -1193,7 +1194,6 @@ LUA_API void lua_concat (lua_State *L, int n) {
lua_lock(L);
api_checknelems(L, n);
if (n >= 2) {
luaC_checkGC(L);
luaV_concat(L, n);
}
else if (n == 0) { /* push empty string */
@@ -1201,6 +1201,7 @@ LUA_API void lua_concat (lua_State *L, int n) {
api_incr_top(L);
}
/* else n == 1; nothing to do */
luaC_checkGC(L);
lua_unlock(L);
}
@@ -1236,10 +1237,10 @@ LUA_API void lua_setallocf (lua_State *L, lua_Alloc f, void *ud) {
LUA_API void *lua_newuserdata (lua_State *L, size_t size) {
Udata *u;
lua_lock(L);
luaC_checkGC(L);
u = luaS_newudata(L, size);
setuvalue(L, L->top, u);
api_incr_top(L);
luaC_checkGC(L);
lua_unlock(L);
return getudatamem(u);
}

View File

@@ -1,5 +1,5 @@
/*
** $Id: lapi.h,v 2.9 2015/03/06 19:49:50 roberto Exp $
** $Id: lapi.h,v 2.9.1.1 2017/04/19 17:20:42 roberto Exp $
** Auxiliary functions from Lua API
** See Copyright Notice in lua.h
*/

View File

@@ -1,5 +1,5 @@
/*
** $Id: lauxlib.c,v 1.284 2015/11/19 19:16:22 roberto Exp $
** $Id: lauxlib.c,v 1.289.1.1 2017/04/19 17:20:42 roberto Exp $
** Auxiliary functions for building Lua libraries
** See Copyright Notice in lua.h
*/
@@ -17,7 +17,8 @@
#include <string.h>
/* This file uses only the official API of Lua.
/*
** This file uses only the official API of Lua.
** Any function declared here could be written as an application function.
*/
@@ -68,12 +69,11 @@ static int findfield (lua_State *L, int objidx, int level) {
/*
** Search for a name for a function in all loaded modules
** (registry._LOADED).
*/
static int pushglobalfuncname (lua_State *L, lua_Debug *ar) {
int top = lua_gettop(L);
lua_getinfo(L, "f", ar); /* push function */
lua_getfield(L, LUA_REGISTRYINDEX, "_LOADED");
lua_getfield(L, LUA_REGISTRYINDEX, LUA_LOADED_TABLE);
if (findfield(L, top + 1, 2)) {
const char *name = lua_tostring(L, -1);
if (strncmp(name, "_G.", 3) == 0) { /* name start with '_G.'? */
@@ -198,6 +198,10 @@ static void tag_error (lua_State *L, int arg, int tag) {
}
/*
** The use of 'lua_pushfstring' ensures this function does not
** need reserved stack space when called.
*/
LUALIB_API void luaL_where (lua_State *L, int level) {
lua_Debug ar;
if (lua_getstack(L, level, &ar)) { /* check function at level */
@@ -207,10 +211,15 @@ LUALIB_API void luaL_where (lua_State *L, int level) {
return;
}
}
lua_pushliteral(L, ""); /* else, no information available... */
lua_pushfstring(L, ""); /* else, no information available... */
}
/*
** Again, the use of 'lua_pushvfstring' ensures this function does
** not need reserved stack space when called. (At worst, it generates
** an error with "stack overflow" instead of the given message.)
*/
LUALIB_API int luaL_error (lua_State *L, const char *fmt, ...) {
va_list argp;
va_start(argp, fmt);
@@ -349,10 +358,15 @@ LUALIB_API int luaL_checkoption (lua_State *L, int arg, const char *def,
}
/*
** Ensures the stack has at least 'space' extra slots, raising an error
** if it cannot fulfill the request. (The error handling needs a few
** extra slots to format the error message. In case of an error without
** this extra space, Lua will generate the same 'stack overflow' error,
** but without 'msg'.)
*/
LUALIB_API void luaL_checkstack (lua_State *L, int space, const char *msg) {
/* keep some extra space to run error routines, if needed */
const int extra = LUA_MINSTACK;
if (!lua_checkstack(L, space + extra)) {
if (!lua_checkstack(L, space)) {
if (msg)
luaL_error(L, "stack overflow (%s)", msg);
else
@@ -678,7 +692,7 @@ static int skipcomment (LoadF *lf, int *cp) {
if (c == '#') { /* first line is a comment (Unix exec. file)? */
do { /* skip first line */
c = getc(lf->f);
} while (c != EOF && c != '\n') ;
} while (c != EOF && c != '\n');
*cp = getc(lf->f); /* skip end-of-line, if present */
return 1; /* there was a comment */
}
@@ -794,13 +808,17 @@ LUALIB_API lua_Integer luaL_len (lua_State *L, int idx) {
LUALIB_API const char *luaL_tolstring (lua_State *L, int idx, size_t *len) {
if (!luaL_callmeta(L, idx, "__tostring")) { /* no metafield? */
if (luaL_callmeta(L, idx, "__tostring")) { /* metafield? */
if (!lua_isstring(L, -1))
luaL_error(L, "'__tostring' must return a string");
}
else {
switch (lua_type(L, idx)) {
case LUA_TNUMBER: {
if (lua_isinteger(L, idx))
lua_pushfstring(L, "%I", lua_tointeger(L, idx));
lua_pushfstring(L, "%I", (LUAI_UACINT)lua_tointeger(L, idx));
else
lua_pushfstring(L, "%f", lua_tonumber(L, idx));
lua_pushfstring(L, "%f", (LUAI_UACNUMBER)lua_tonumber(L, idx));
break;
}
case LUA_TSTRING:
@@ -812,10 +830,15 @@ LUALIB_API const char *luaL_tolstring (lua_State *L, int idx, size_t *len) {
case LUA_TNIL:
lua_pushliteral(L, "nil");
break;
default:
lua_pushfstring(L, "%s: %p", luaL_typename(L, idx),
lua_topointer(L, idx));
default: {
int tt = luaL_getmetafield(L, idx, "__name"); /* try name */
const char *kind = (tt == LUA_TSTRING) ? lua_tostring(L, -1) :
luaL_typename(L, idx);
lua_pushfstring(L, "%s: %p", kind, lua_topointer(L, idx));
if (tt != LUA_TNIL)
lua_remove(L, -2); /* remove '__name' */
break;
}
}
}
return lua_tolstring(L, -1, len);
@@ -867,23 +890,23 @@ static int libsize (const luaL_Reg *l) {
/*
** Find or create a module table with a given name. The function
** first looks at the _LOADED table and, if that fails, try a
** first looks at the LOADED table and, if that fails, try a
** global variable with that name. In any case, leaves on the stack
** the module table.
*/
LUALIB_API void luaL_pushmodule (lua_State *L, const char *modname,
int sizehint) {
luaL_findtable(L, LUA_REGISTRYINDEX, "_LOADED", 1); /* get _LOADED table */
if (lua_getfield(L, -1, modname) != LUA_TTABLE) { /* no _LOADED[modname]? */
luaL_findtable(L, LUA_REGISTRYINDEX, LUA_LOADED_TABLE, 1);
if (lua_getfield(L, -1, modname) != LUA_TTABLE) { /* no LOADED[modname]? */
lua_pop(L, 1); /* remove previous result */
/* try global variable (and create one if it does not exist) */
lua_pushglobaltable(L);
if (luaL_findtable(L, 0, modname, sizehint) != NULL)
luaL_error(L, "name conflict for module '%s'", modname);
lua_pushvalue(L, -1);
lua_setfield(L, -3, modname); /* _LOADED[modname] = new table */
lua_setfield(L, -3, modname); /* LOADED[modname] = new table */
}
lua_remove(L, -2); /* remove _LOADED table */
lua_remove(L, -2); /* remove LOADED table */
}
@@ -947,17 +970,17 @@ LUALIB_API int luaL_getsubtable (lua_State *L, int idx, const char *fname) {
*/
LUALIB_API void luaL_requiref (lua_State *L, const char *modname,
lua_CFunction openf, int glb) {
luaL_getsubtable(L, LUA_REGISTRYINDEX, "_LOADED");
lua_getfield(L, -1, modname); /* _LOADED[modname] */
luaL_getsubtable(L, LUA_REGISTRYINDEX, LUA_LOADED_TABLE);
lua_getfield(L, -1, modname); /* LOADED[modname] */
if (!lua_toboolean(L, -1)) { /* package not already loaded? */
lua_pop(L, 1); /* remove field */
lua_pushcfunction(L, openf);
lua_pushstring(L, modname); /* argument to open function */
lua_call(L, 1, 1); /* call 'openf' to open module */
lua_pushvalue(L, -1); /* make copy of module (call result) */
lua_setfield(L, -3, modname); /* _LOADED[modname] = module */
lua_setfield(L, -3, modname); /* LOADED[modname] = module */
}
lua_remove(L, -2); /* remove _LOADED table */
lua_remove(L, -2); /* remove LOADED table */
if (glb) {
lua_pushvalue(L, -1); /* copy of module */
lua_setglobal(L, modname); /* _G[modname] = module */
@@ -1015,7 +1038,7 @@ LUALIB_API void luaL_checkversion_ (lua_State *L, lua_Number ver, size_t sz) {
luaL_error(L, "multiple Lua VMs detected");
else if (*v != ver)
luaL_error(L, "version mismatch: app. needs %f, Lua core provides %f",
ver, *v);
(LUAI_UACNUMBER)ver, (LUAI_UACNUMBER)*v);
}
// use clonefunction

View File

@@ -1,5 +1,5 @@
/*
** $Id: lauxlib.h,v 1.129 2015/11/23 11:29:43 roberto Exp $
** $Id: lauxlib.h,v 1.131.1.1 2017/04/19 17:20:42 roberto Exp $
** Auxiliary functions for building Lua libraries
** See Copyright Notice in lua.h
*/
@@ -16,10 +16,18 @@
/* extra error code for 'luaL_load' */
/* extra error code for 'luaL_loadfilex' */
#define LUA_ERRFILE (LUA_ERRERR+1)
/* key, in the registry, for table of loaded modules */
#define LUA_LOADED_TABLE "_LOADED"
/* key, in the registry, for table of preloaded loaders */
#define LUA_PRELOAD_TABLE "_PRELOAD"
typedef struct luaL_Reg {
const char *name;
lua_CFunction func;

View File

@@ -1,5 +1,5 @@
/*
** $Id: lbaselib.c,v 1.312 2015/10/29 15:21:04 roberto Exp $
** $Id: lbaselib.c,v 1.314.1.1 2017/04/19 17:39:34 roberto Exp $
** Basic library
** See Copyright Notice in lua.h
*/
@@ -102,8 +102,8 @@ static int luaB_tonumber (lua_State *L) {
static int luaB_error (lua_State *L) {
int level = (int)luaL_optinteger(L, 2, 1);
lua_settop(L, 1);
if (lua_isstring(L, 1) && level > 0) { /* add extra information? */
luaL_where(L, level);
if (lua_type(L, 1) == LUA_TSTRING && level > 0) {
luaL_where(L, level); /* add extra information */
lua_pushvalue(L, 1);
lua_concat(L, 2);
}
@@ -208,8 +208,8 @@ static int luaB_type (lua_State *L) {
static int pairsmeta (lua_State *L, const char *method, int iszero,
lua_CFunction iter) {
luaL_checkany(L, 1);
if (luaL_getmetafield(L, 1, method) == LUA_TNIL) { /* no metamethod? */
luaL_checktype(L, 1, LUA_TTABLE); /* argument must be a table */
lua_pushcfunction(L, iter); /* will return generator, */
lua_pushvalue(L, 1); /* state, */
if (iszero) lua_pushinteger(L, 0); /* and initial value */
@@ -251,9 +251,8 @@ static int ipairsaux (lua_State *L) {
/*
** This function will use either 'ipairsaux' or 'ipairsaux_raw' to
** traverse a table, depending on whether the table has metamethods
** that can affect the traversal.
** 'ipairs' function. Returns 'ipairsaux', given "table", 0.
** (The given "table" may not be a table.)
*/
static int luaB_ipairs (lua_State *L) {
#if defined(LUA_COMPAT_IPAIRS)

View File

@@ -1,5 +1,5 @@
/*
** $Id: lbitlib.c,v 1.30 2015/11/11 19:08:09 roberto Exp $
** $Id: lbitlib.c,v 1.30.1.1 2017/04/19 17:20:42 roberto Exp $
** Standard library for bitwise operations
** See Copyright Notice in lua.h
*/

File diff suppressed because it is too large Load Diff

View File

@@ -1,5 +1,5 @@
/*
** $Id: lcode.h,v 1.63 2013/12/30 20:47:58 roberto Exp $
** $Id: lcode.h,v 1.64.1.1 2017/04/19 17:20:42 roberto Exp $
** Code generator for Lua
** See Copyright Notice in lua.h
*/
@@ -40,7 +40,8 @@ typedef enum BinOpr {
typedef enum UnOpr { OPR_MINUS, OPR_BNOT, OPR_NOT, OPR_LEN, OPR_NOUNOPR } UnOpr;
#define getcode(fs,e) ((fs)->f->sp->code[(e)->u.info])
/* get (pointer to) instruction of given 'expdesc' */
#define getinstruction(fs,e) ((fs)->f->sp->code[(e)->u.info])
#define luaK_codeAsBx(fs,o,A,sBx) luaK_codeABx(fs,o,A,(sBx)+MAXARG_sBx)

View File

@@ -1,5 +1,5 @@
/*
** $Id: lcorolib.c,v 1.9 2014/11/02 19:19:04 roberto Exp $
** $Id: lcorolib.c,v 1.10.1.1 2017/04/19 17:20:42 roberto Exp $
** Coroutine Library
** See Copyright Notice in lua.h
*/
@@ -75,7 +75,7 @@ static int luaB_auxwrap (lua_State *L) {
lua_State *co = lua_tothread(L, lua_upvalueindex(1));
int r = auxresume(L, co, lua_gettop(L));
if (r < 0) {
if (lua_isstring(L, -1)) { /* error object is a string? */
if (lua_type(L, -1) == LUA_TSTRING) { /* error object is a string? */
luaL_where(L, 1); /* add extra info */
lua_insert(L, -2);
lua_concat(L, 2);

View File

@@ -1,5 +1,5 @@
/*
** $Id: lctype.c,v 1.12 2014/11/02 19:19:04 roberto Exp $
** $Id: lctype.c,v 1.12.1.1 2017/04/19 17:20:42 roberto Exp $
** 'ctype' functions for Lua
** See Copyright Notice in lua.h
*/

View File

@@ -1,5 +1,5 @@
/*
** $Id: lctype.h,v 1.12 2011/07/15 12:50:29 roberto Exp $
** $Id: lctype.h,v 1.12.1.1 2013/04/12 18:48:47 roberto Exp $
** 'ctype' functions for Lua
** See Copyright Notice in lua.h
*/

View File

@@ -1,5 +1,5 @@
/*
** $Id: ldblib.c,v 1.151 2015/11/23 11:29:43 roberto Exp $
** $Id: ldblib.c,v 1.151.1.1 2017/04/19 17:20:42 roberto Exp $
** Interface from Lua to its debug API
** See Copyright Notice in lua.h
*/

View File

@@ -1,5 +1,5 @@
/*
** $Id: ldebug.c,v 2.117 2015/11/02 18:48:07 roberto Exp $
** $Id: ldebug.c,v 2.121.1.2 2017/07/10 17:21:50 roberto Exp $
** Debug Interface
** See Copyright Notice in lua.h
*/
@@ -38,7 +38,8 @@
#define ci_func(ci) (clLvalue((ci)->func))
static const char *getfuncname (lua_State *L, CallInfo *ci, const char **name);
static const char *funcnamefromcode (lua_State *L, CallInfo *ci,
const char **name);
static int currentpc (CallInfo *ci) {
@@ -69,7 +70,13 @@ static void swapextra (lua_State *L) {
/*
** this function can be called asynchronous (e.g. during a signal)
** This function can be called asynchronously (e.g. during a signal).
** Fields 'oldpc', 'basehookcount', and 'hookcount' (set by
** 'resethookcount') are for debug only, and it is no problem if they
** get arbitrary values (causes at most one wrong hook call). 'hookmask'
** is an atomic value. We assume that pointers are atomic too (e.g., gcc
** ensures that for all platforms where it runs). Moreover, 'hook' is
** always checked before being called (see 'luaD_hook').
*/
LUA_API void lua_sethook (lua_State *L, lua_Hook func, int mask, int count) {
if (func == NULL || mask == 0) { /* turn off hooks? */
@@ -118,7 +125,7 @@ LUA_API int lua_getstack (lua_State *L, int level, lua_Debug *ar) {
static const char *upvalname (Proto *p, int uv) {
TString *s = check_exp(uv < p->sizeupvalues, p->sp->upvalues[uv].name);
TString *s = check_exp(uv < p->sp->sizeupvalues, p->sp->upvalues[uv].name);
if (s == NULL) return "?";
else return getstr(s);
}
@@ -238,6 +245,20 @@ static void collectvalidlines (lua_State *L, Closure *f) {
}
static const char *getfuncname (lua_State *L, CallInfo *ci, const char **name) {
if (ci == NULL) /* no 'ci'? */
return NULL; /* no info */
else if (ci->callstatus & CIST_FIN) { /* is this a finalizer? */
*name = "__gc";
return "metamethod"; /* report it as such */
}
/* calling function is a known Lua function? */
else if (!(ci->callstatus & CIST_TAIL) && isLua(ci->previous))
return funcnamefromcode(L, ci->previous, name);
else return NULL; /* no way to find a name */
}
static int auxgetinfo (lua_State *L, const char *what, lua_Debug *ar,
Closure *f, CallInfo *ci) {
int status = 1;
@@ -268,11 +289,7 @@ static int auxgetinfo (lua_State *L, const char *what, lua_Debug *ar,
break;
}
case 'n': {
/* calling function is a known Lua function? */
if (ci && !(ci->callstatus & CIST_TAIL) && isLua(ci->previous))
ar->namewhat = getfuncname(L, ci->previous, &ar->name);
else
ar->namewhat = NULL;
ar->namewhat = getfuncname(L, ci, &ar->name);
if (ar->namewhat == NULL) {
ar->namewhat = ""; /* not found */
ar->name = NULL;
@@ -465,8 +482,15 @@ static const char *getobjname (Proto *p, int lastpc, int reg,
}
static const char *getfuncname (lua_State *L, CallInfo *ci, const char **name) {
TMS tm = (TMS)0; /* to avoid warnings */
/*
** Try to find a name for a function based on the code that called it.
** (Only works when function was called by a Lua function.)
** Returns what the name is (e.g., "for iterator", "method",
** "metamethod") and sets '*name' to point to the name.
*/
static const char *funcnamefromcode (lua_State *L, CallInfo *ci,
const char **name) {
TMS tm = (TMS)0; /* (initial value avoids warnings) */
Proto *p = ci_func(ci)->p; /* calling function */
int pc = currentpc(ci); /* calling instruction index */
Instruction i = p->sp->code[pc]; /* calling instruction */
@@ -476,13 +500,13 @@ static const char *getfuncname (lua_State *L, CallInfo *ci, const char **name) {
}
switch (GET_OPCODE(i)) {
case OP_CALL:
case OP_TAILCALL: /* get function name */
return getobjname(p, pc, GETARG_A(i), name);
case OP_TAILCALL:
return getobjname(p, pc, GETARG_A(i), name); /* get function name */
case OP_TFORCALL: { /* for iterator */
*name = "for iterator";
return "for iterator";
}
/* all other instructions can call only through metamethods */
/* other instructions can do calls through metamethods */
case OP_SELF: case OP_GETTABUP: case OP_GETTABLE:
tm = TM_INDEX;
break;
@@ -503,7 +527,8 @@ static const char *getfuncname (lua_State *L, CallInfo *ci, const char **name) {
case OP_EQ: tm = TM_EQ; break;
case OP_LT: tm = TM_LT; break;
case OP_LE: tm = TM_LE; break;
default: lua_assert(0); /* other instructions cannot call a function */
default:
return NULL; /* cannot find a reasonable name */
}
*name = getstr(G(L)->tmname[tm]);
return "metamethod";
@@ -558,7 +583,7 @@ static const char *varinfo (lua_State *L, const TValue *o) {
l_noret luaG_typeerror (lua_State *L, const TValue *o, const char *op) {
const char *t = objtypename(o);
const char *t = luaT_objtypename(L, o);
luaG_runerror(L, "attempt to %s a %s value%s", op, t, varinfo(L, o));
}
@@ -590,9 +615,9 @@ l_noret luaG_tointerror (lua_State *L, const TValue *p1, const TValue *p2) {
l_noret luaG_ordererror (lua_State *L, const TValue *p1, const TValue *p2) {
const char *t1 = objtypename(p1);
const char *t2 = objtypename(p2);
if (t1 == t2)
const char *t1 = luaT_objtypename(L, p1);
const char *t2 = luaT_objtypename(L, p2);
if (strcmp(t1, t2) == 0)
luaG_runerror(L, "attempt to compare two %s values", t1);
else
luaG_runerror(L, "attempt to compare %s with %s", t1, t2);
@@ -628,6 +653,7 @@ l_noret luaG_runerror (lua_State *L, const char *fmt, ...) {
CallInfo *ci = L->ci;
const char *msg;
va_list argp;
luaC_checkGC(L); /* error message uses memory */
va_start(argp, fmt);
msg = luaO_pushvfstring(L, fmt, argp); /* format message */
va_end(argp);

View File

@@ -1,5 +1,5 @@
/*
** $Id: ldebug.h,v 2.14 2015/05/22 17:45:56 roberto Exp $
** $Id: ldebug.h,v 2.14.1.1 2017/04/19 17:20:42 roberto Exp $
** Auxiliary functions from Debug Interface module
** See Copyright Notice in lua.h
*/

View File

@@ -1,5 +1,5 @@
/*
** $Id: ldo.c,v 2.150 2015/11/19 19:16:22 roberto Exp $
** $Id: ldo.c,v 2.157.1.1 2017/04/19 17:20:42 roberto Exp $
** Stack and Call structure of Lua
** See Copyright Notice in lua.h
*/
@@ -211,9 +211,9 @@ static int stackinuse (lua_State *L) {
CallInfo *ci;
StkId lim = L->top;
for (ci = L->ci; ci != NULL; ci = ci->previous) {
lua_assert(ci->top <= L->stack_last);
if (lim < ci->top) lim = ci->top;
}
lua_assert(lim <= L->stack_last);
return cast_int(lim - L->stack) + 1; /* part of stack in use */
}
@@ -221,16 +221,19 @@ static int stackinuse (lua_State *L) {
void luaD_shrinkstack (lua_State *L) {
int inuse = stackinuse(L);
int goodsize = inuse + (inuse / 8) + 2*EXTRA_STACK;
if (goodsize > LUAI_MAXSTACK) goodsize = LUAI_MAXSTACK;
if (L->stacksize > LUAI_MAXSTACK) /* was handling stack overflow? */
if (goodsize > LUAI_MAXSTACK)
goodsize = LUAI_MAXSTACK; /* respect stack limit */
if (L->stacksize > LUAI_MAXSTACK) /* had been handling stack overflow? */
luaE_freeCI(L); /* free all CIs (list grew because of an error) */
else
luaE_shrinkCI(L); /* shrink list */
if (inuse <= LUAI_MAXSTACK && /* not handling stack overflow? */
goodsize < L->stacksize) /* trying to shrink? */
luaD_reallocstack(L, goodsize); /* shrink it */
else
condmovestack(L,,); /* don't change stack (change only for debugging) */
/* if thread is currently not handling a stack overflow and its
good size is smaller than current size, shrink its stack */
if (inuse <= (LUAI_MAXSTACK - EXTRA_STACK) &&
goodsize < L->stacksize)
luaD_reallocstack(L, goodsize);
else /* don't change stack */
condmovestack(L,{},{}); /* (change only for debugging) */
}
@@ -242,9 +245,14 @@ void luaD_inctop (lua_State *L) {
/* }================================================================== */
/*
** Call a hook for the given event. Make sure there is a hook to be
** called. (Both 'L->hook' and 'L->hookmask', which triggers this
** function, can be changed asynchronously by signals.)
*/
void luaD_hook (lua_State *L, int event, int line) {
lua_Hook hook = L->hook;
if (hook && L->allowhook) {
if (hook && L->allowhook) { /* make sure there is a hook */
CallInfo *ci = L->ci;
ptrdiff_t top = savestack(L, L->top);
ptrdiff_t ci_top = savestack(L, ci->top);
@@ -317,86 +325,6 @@ static void tryfuncTM (lua_State *L, StkId func) {
}
#define next_ci(L) (L->ci = (L->ci->next ? L->ci->next : luaE_extendCI(L)))
/* macro to check stack size, preserving 'p' */
#define checkstackp(L,n,p) \
luaD_checkstackaux(L, n, \
ptrdiff_t t__ = savestack(L, p); /* save 'p' */ \
luaC_checkGC(L), /* stack grow uses memory */ \
p = restorestack(L, t__)) /* 'pos' part: restore 'p' */
/*
** Prepares a function call: checks the stack, creates a new CallInfo
** entry, fills in the relevant information, calls hook if needed.
** If function is a C function, does the call, too. (Otherwise, leave
** the execution ('luaV_execute') to the caller, to allow stackless
** calls.) Returns true iff function has been executed (C function).
*/
int luaD_precall (lua_State *L, StkId func, int nresults) {
lua_CFunction f;
CallInfo *ci;
switch (ttype(func)) {
case LUA_TCCL: /* C closure */
f = clCvalue(func)->f;
goto Cfunc;
case LUA_TLCF: /* light C function */
f = fvalue(func);
Cfunc: {
int n; /* number of returns */
checkstackp(L, LUA_MINSTACK, func); /* ensure minimum stack size */
ci = next_ci(L); /* now 'enter' new function */
ci->nresults = nresults;
ci->func = func;
ci->top = L->top + LUA_MINSTACK;
lua_assert(ci->top <= L->stack_last);
ci->callstatus = 0;
if (L->hookmask & LUA_MASKCALL)
luaD_hook(L, LUA_HOOKCALL, -1);
lua_unlock(L);
n = (*f)(L); /* do the actual call */
lua_lock(L);
api_checknelems(L, n);
luaD_poscall(L, ci, L->top - n, n);
return 1;
}
case LUA_TLCL: { /* Lua function: prepare its call */
StkId base;
SharedProto *p = clLvalue(func)->p->sp;
int n = cast_int(L->top - func) - 1; /* number of real arguments */
int fsize = p->maxstacksize; /* frame size */
checkstackp(L, fsize, func);
if (p->is_vararg != 1) { /* do not use vararg? */
for (; n < p->numparams; n++)
setnilvalue(L->top++); /* complete missing arguments */
base = func + 1;
}
else
base = adjust_varargs(L, p, n);
ci = next_ci(L); /* now 'enter' new function */
ci->nresults = nresults;
ci->func = func;
ci->u.l.base = base;
L->top = ci->top = base + fsize;
lua_assert(ci->top <= L->stack_last);
ci->u.l.savedpc = p->code; /* starting point */
ci->callstatus = CIST_LUA;
if (L->hookmask & LUA_MASKCALL)
callhook(L, ci);
return 0;
}
default: { /* not a function */
checkstackp(L, 1, func); /* ensure space for metamethod */
tryfuncTM(L, func); /* try to get '__call' metamethod */
return luaD_precall(L, func, nresults); /* now it must be a function */
}
}
}
/*
** Given 'nres' results at 'firstResult', move 'wanted' of them to 'res'.
** Handle most typical cases (zero results for commands, one result for
@@ -463,6 +391,86 @@ int luaD_poscall (lua_State *L, CallInfo *ci, StkId firstResult, int nres) {
}
#define next_ci(L) (L->ci = (L->ci->next ? L->ci->next : luaE_extendCI(L)))
/* macro to check stack size, preserving 'p' */
#define checkstackp(L,n,p) \
luaD_checkstackaux(L, n, \
ptrdiff_t t__ = savestack(L, p); /* save 'p' */ \
luaC_checkGC(L), /* stack grow uses memory */ \
p = restorestack(L, t__)) /* 'pos' part: restore 'p' */
/*
** Prepares a function call: checks the stack, creates a new CallInfo
** entry, fills in the relevant information, calls hook if needed.
** If function is a C function, does the call, too. (Otherwise, leave
** the execution ('luaV_execute') to the caller, to allow stackless
** calls.) Returns true iff function has been executed (C function).
*/
int luaD_precall (lua_State *L, StkId func, int nresults) {
lua_CFunction f;
CallInfo *ci;
switch (ttype(func)) {
case LUA_TCCL: /* C closure */
f = clCvalue(func)->f;
goto Cfunc;
case LUA_TLCF: /* light C function */
f = fvalue(func);
Cfunc: {
int n; /* number of returns */
checkstackp(L, LUA_MINSTACK, func); /* ensure minimum stack size */
ci = next_ci(L); /* now 'enter' new function */
ci->nresults = nresults;
ci->func = func;
ci->top = L->top + LUA_MINSTACK;
lua_assert(ci->top <= L->stack_last);
ci->callstatus = 0;
if (L->hookmask & LUA_MASKCALL)
luaD_hook(L, LUA_HOOKCALL, -1);
lua_unlock(L);
n = (*f)(L); /* do the actual call */
lua_lock(L);
api_checknelems(L, n);
luaD_poscall(L, ci, L->top - n, n);
return 1;
}
case LUA_TLCL: { /* Lua function: prepare its call */
StkId base;
SharedProto *p = clLvalue(func)->p->sp;
int n = cast_int(L->top - func) - 1; /* number of real arguments */
int fsize = p->maxstacksize; /* frame size */
checkstackp(L, fsize, func);
if (p->is_vararg)
base = adjust_varargs(L, p, n);
else { /* non vararg function */
for (; n < p->numparams; n++)
setnilvalue(L->top++); /* complete missing arguments */
base = func + 1;
}
ci = next_ci(L); /* now 'enter' new function */
ci->nresults = nresults;
ci->func = func;
ci->u.l.base = base;
L->top = ci->top = base + fsize;
lua_assert(ci->top <= L->stack_last);
ci->u.l.savedpc = p->code; /* starting point */
ci->callstatus = CIST_LUA;
if (L->hookmask & LUA_MASKCALL)
callhook(L, ci);
return 0;
}
default: { /* not a function */
checkstackp(L, 1, func); /* ensure space for metamethod */
tryfuncTM(L, func); /* try to get '__call' metamethod */
return luaD_precall(L, func, nresults); /* now it must be a function */
}
}
}
/*
** Check appropriate error for stack overflow ("regular" overflow or
** overflow while handling stack overflow). If 'nCalls' is larger than
@@ -515,19 +523,17 @@ static void finishCcall (lua_State *L, int status) {
/* error status can only happen in a protected call */
lua_assert((ci->callstatus & CIST_YPCALL) || status == LUA_YIELD);
if (ci->callstatus & CIST_YPCALL) { /* was inside a pcall? */
ci->callstatus &= ~CIST_YPCALL; /* finish 'lua_pcall' */
L->errfunc = ci->u.c.old_errfunc;
ci->callstatus &= ~CIST_YPCALL; /* continuation is also inside it */
L->errfunc = ci->u.c.old_errfunc; /* with the same error function */
}
/* finish 'lua_callk'/'lua_pcall'; CIST_YPCALL and 'errfunc' already
handled */
adjustresults(L, ci->nresults);
/* call continuation function */
lua_unlock(L);
n = (*ci->u.c.k)(L, status, ci->u.c.ctx);
n = (*ci->u.c.k)(L, status, ci->u.c.ctx); /* call continuation function */
lua_lock(L);
api_checknelems(L, n);
/* finish 'luaD_precall' */
luaD_poscall(L, ci, L->top - n, n);
luaD_poscall(L, ci, L->top - n, n); /* finish 'luaD_precall' */
}
@@ -590,15 +596,16 @@ static int recover (lua_State *L, int status) {
/*
** signal an error in the call to 'resume', not in the execution of the
** coroutine itself. (Such errors should not be handled by any coroutine
** error handler and should not kill the coroutine.)
** Signal an error in the call to 'lua_resume', not in the execution
** of the coroutine itself. (Such errors should not be handled by any
** coroutine error handler and should not kill the coroutine.)
*/
static l_noret resume_error (lua_State *L, const char *msg, StkId firstArg) {
L->top = firstArg; /* remove args from the stack */
static int resume_error (lua_State *L, const char *msg, int narg) {
L->top -= narg; /* remove args from the stack */
setsvalue2s(L, L->top, luaS_new(L, msg)); /* push error message */
api_incr_top(L);
luaD_throw(L, -1); /* jump back to 'lua_resume' */
lua_unlock(L);
return LUA_ERRRUN;
}
@@ -610,22 +617,15 @@ static l_noret resume_error (lua_State *L, const char *msg, StkId firstArg) {
** coroutine.
*/
static void resume (lua_State *L, void *ud) {
int nCcalls = L->nCcalls;
int n = *(cast(int*, ud)); /* number of arguments */
StkId firstArg = L->top - n; /* first argument */
CallInfo *ci = L->ci;
if (nCcalls >= LUAI_MAXCCALLS)
resume_error(L, "C stack overflow", firstArg);
if (L->status == LUA_OK) { /* may be starting a coroutine */
if (ci != &L->base_ci) /* not in base level? */
resume_error(L, "cannot resume non-suspended coroutine", firstArg);
/* coroutine is in base level; start running it */
if (L->status == LUA_OK) { /* starting a coroutine? */
if (!luaD_precall(L, firstArg - 1, LUA_MULTRET)) /* Lua function? */
luaV_execute(L); /* call it */
}
else if (L->status != LUA_YIELD)
resume_error(L, "cannot resume dead coroutine", firstArg);
else { /* resuming from previous yield */
lua_assert(L->status == LUA_YIELD);
L->status = LUA_OK; /* mark that it is running (again) */
ci->func = restorestack(L, ci->extra);
if (isLua(ci)) /* yielded inside a hook? */
@@ -642,7 +642,6 @@ static void resume (lua_State *L, void *ud) {
}
unroll(L, NULL); /* run continuation */
}
lua_assert(nCcalls == L->nCcalls);
}
@@ -650,8 +649,16 @@ LUA_API int lua_resume (lua_State *L, lua_State *from, int nargs) {
int status;
unsigned short oldnny = L->nny; /* save "number of non-yieldable" calls */
lua_lock(L);
luai_userstateresume(L, nargs);
if (L->status == LUA_OK) { /* may be starting a coroutine */
if (L->ci != &L->base_ci) /* not in base level? */
return resume_error(L, "cannot resume non-suspended coroutine", nargs);
}
else if (L->status != LUA_YIELD)
return resume_error(L, "cannot resume dead coroutine", nargs);
L->nCcalls = (from) ? from->nCcalls + 1 : 1;
if (L->nCcalls >= LUAI_MAXCCALLS)
return resume_error(L, "C stack overflow", nargs);
luai_userstateresume(L, nargs);
L->nny = 0; /* allow yields */
api_checknelems(L, (L->status == LUA_OK) ? nargs + 1 : nargs);
status = luaD_rawrunprotected(L, resume, &nargs);
@@ -768,7 +775,7 @@ static void f_parser (lua_State *L, void *ud) {
checkmode(L, p->mode, "text");
cl = luaY_parser(L, p->z, &p->buff, &p->dyd, p->name, c);
}
lua_assert(cl->nupvalues == cl->p->sizeupvalues);
lua_assert(cl->nupvalues == cl->p->sp->sizeupvalues);
luaF_initupvals(L, cl);
}

View File

@@ -1,5 +1,5 @@
/*
** $Id: ldo.h,v 2.28 2015/11/23 11:29:43 roberto Exp $
** $Id: ldo.h,v 2.29.1.1 2017/04/19 17:20:42 roberto Exp $
** Stack and Call structure of Lua
** See Copyright Notice in lua.h
*/
@@ -25,7 +25,7 @@
{ pre; luaD_growstack(L, n); pos; } else { condmovestack(L,pre,pos); }
/* In general, 'pre'/'pos' are empty (nothing to save) */
#define luaD_checkstack(L,n) luaD_checkstackaux(L,n,,)
#define luaD_checkstack(L,n) luaD_checkstackaux(L,n,(void)0,(void)0)

View File

@@ -1,5 +1,5 @@
/*
** $Id: ldump.c,v 2.37 2015/10/08 15:53:49 roberto Exp $
** $Id: ldump.c,v 2.37.1.1 2017/04/19 17:20:42 roberto Exp $
** save precompiled Lua chunks
** See Copyright Notice in lua.h
*/

View File

@@ -1,5 +1,5 @@
/*
** $Id: lfunc.c,v 2.45 2014/11/02 19:19:04 roberto Exp $
** $Id: lfunc.c,v 2.45.1.1 2017/04/19 17:39:34 roberto Exp $
** Auxiliary functions to manipulate prototypes and closures
** See Copyright Notice in lua.h
*/

View File

@@ -1,5 +1,5 @@
/*
** $Id: lfunc.h,v 2.15 2015/01/13 15:49:11 roberto Exp $
** $Id: lfunc.h,v 2.15.1.1 2017/04/19 17:39:34 roberto Exp $
** Auxiliary functions to manipulate prototypes and closures
** See Copyright Notice in lua.h
*/

View File

@@ -1,5 +1,5 @@
/*
** $Id: lgc.c,v 2.210 2015/11/03 18:10:44 roberto Exp $
** $Id: lgc.c,v 2.215.1.2 2017/08/31 16:15:27 roberto Exp $
** Garbage Collector
** See Copyright Notice in lua.h
*/
@@ -468,7 +468,7 @@ static lu_mem traversetable (global_State *g, Table *h) {
else /* not weak */
traversestrongtable(g, h);
return sizeof(Table) + sizeof(TValue) * h->sizearray +
sizeof(Node) * cast(size_t, sizenode(h));
sizeof(Node) * cast(size_t, allocsizenode(h));
}
static int marksharedproto (global_State *g, SharedProto *f) {
@@ -492,15 +492,19 @@ static int marksharedproto (global_State *g, SharedProto *f) {
** NULL, so the use of 'markobjectN')
*/
static int traverseproto (global_State *g, Proto *f) {
int i;
int i,nk,np;
if (f->cache && iswhite(f->cache))
f->cache = NULL; /* allow cache to be collected */
for (i = 0; i < f->sp->sizek; i++) /* mark literals */
if (f->sp == NULL)
return sizeof(Proto);
nk = (f->k == NULL) ? 0 : f->sp->sizek;
np = (f->p == NULL) ? 0 : f->sp->sizep;
for (i = 0; i < nk; i++) /* mark literals */
markvalue(g, &f->k[i]);
for (i = 0; i < f->sp->sizep; i++) /* mark nested protos */
for (i = 0; i < np; i++) /* mark nested protos */
markobjectN(g, f->p[i]);
return sizeof(Proto) + sizeof(Proto *) * f->sp->sizep +
sizeof(TValue) * f->sp->sizek +
return sizeof(Proto) + sizeof(Proto *) * np +
sizeof(TValue) * nk +
marksharedproto(g, f->sp);
}
@@ -546,7 +550,7 @@ static lu_mem traversethread (global_State *g, lua_State *th) {
StkId lim = th->stack + th->stacksize; /* real end of stack */
for (; o < lim; o++) /* clear not-marked stack slice */
setnilvalue(o);
/* 'remarkupvals' may have removed thread from 'twups' list */
/* 'remarkupvals' may have removed thread from 'twups' list */
if (!isintwups(th) && th->openupval != NULL) {
th->twups = g->twups; /* link it back to the list */
g->twups = th;
@@ -650,8 +654,9 @@ static void clearkeys (global_State *g, GCObject *l, GCObject *f) {
for (n = gnode(h, 0); n < limit; n++) {
if (!ttisnil(gval(n)) && (iscleared(g, gkey(n)))) {
setnilvalue(gval(n)); /* remove value ... */
removeentry(n); /* and remove entry from table */
}
if (ttisnil(gval(n))) /* is entry empty? */
removeentry(n); /* remove entry from table */
}
}
}
@@ -761,14 +766,11 @@ static GCObject **sweeplist (lua_State *L, GCObject **p, lu_mem count) {
/*
** sweep a list until a live object (or end of list)
*/
static GCObject **sweeptolive (lua_State *L, GCObject **p, int *n) {
static GCObject **sweeptolive (lua_State *L, GCObject **p) {
GCObject **old = p;
int i = 0;
do {
i++;
p = sweeplist(L, p, 1);
} while (p == old);
if (n) *n += i;
return p;
}
@@ -828,7 +830,9 @@ static void GCTM (lua_State *L, int propagateerrors) {
setobj2s(L, L->top, tm); /* push finalizer... */
setobj2s(L, L->top + 1, &v); /* ... and its argument */
L->top += 2; /* and (next line) call the finalizer */
L->ci->callstatus |= CIST_FIN; /* will run a finalizer */
status = luaD_pcall(L, dothecall, NULL, savestack(L, L->top - 2), 0);
L->ci->callstatus &= ~CIST_FIN; /* not running a finalizer anymore */
L->allowhook = oldah; /* restore hooks */
g->gcrunning = running; /* restore state */
if (status != LUA_OK && propagateerrors) { /* error while running __gc? */
@@ -863,10 +867,10 @@ static int runafewfinalizers (lua_State *L) {
/*
** call all pending finalizers
*/
static void callallpendingfinalizers (lua_State *L, int propagateerrors) {
static void callallpendingfinalizers (lua_State *L) {
global_State *g = G(L);
while (g->tobefnz)
GCTM(L, propagateerrors);
GCTM(L, 0);
}
@@ -916,7 +920,7 @@ void luaC_checkfinalizer (lua_State *L, GCObject *o, Table *mt) {
if (issweepphase(g)) {
makewhite(g, o); /* "sweep" object 'o' */
if (g->sweepgc == &o->next) /* should not remove 'sweepgc' object */
g->sweepgc = sweeptolive(L, g->sweepgc, NULL); /* change 'sweepgc' */
g->sweepgc = sweeptolive(L, g->sweepgc); /* change 'sweepgc' */
}
/* search for pointer pointing to 'o' */
for (p = &g->allgc; *p != o; p = &(*p)->next) { /* empty */ }
@@ -958,19 +962,16 @@ static void setpause (global_State *g) {
/*
** Enter first sweep phase.
** The call to 'sweeptolive' makes pointer point to an object inside
** the list (instead of to the header), so that the real sweep do not
** need to skip objects created between "now" and the start of the real
** sweep.
** Returns how many objects it swept.
** The call to 'sweeplist' tries to make pointer point to an object
** inside the list (instead of to the header), so that the real sweep do
** not need to skip objects created between "now" and the start of the
** real sweep.
*/
static int entersweep (lua_State *L) {
static void entersweep (lua_State *L) {
global_State *g = G(L);
int n = 0;
g->gcstate = GCSswpallgc;
lua_assert(g->sweepgc == NULL);
g->sweepgc = sweeptolive(L, &g->allgc, &n);
return n;
g->sweepgc = sweeplist(L, &g->allgc, 1);
}
@@ -978,7 +979,7 @@ void luaC_freeallobjects (lua_State *L) {
global_State *g = G(L);
separatetobefnz(g, 1); /* separate all objects with finalizers */
lua_assert(g->finobj == NULL);
callallpendingfinalizers(L, 0);
callallpendingfinalizers(L);
lua_assert(g->tobefnz == NULL);
g->currentwhite = WHITEBITS; /* this "white" makes all objects look dead */
g->gckind = KGC_NORMAL;
@@ -1071,12 +1072,11 @@ static lu_mem singlestep (lua_State *L) {
}
case GCSatomic: {
lu_mem work;
int sw;
propagateall(g); /* make sure gray list is empty */
work = atomic(L); /* work is what was traversed by 'atomic' */
sw = entersweep(L);
entersweep(L);
g->GCestimate = gettotalbytes(g); /* first estimate */;
return work + sw * GCSWEEPCOST;
return work;
}
case GCSswpallgc: { /* sweep "regular" objects */
return sweepstep(L, g, GCSswpfinobj, &g->finobj);

View File

@@ -1,5 +1,5 @@
/*
** $Id: lgc.h,v 2.90 2015/10/21 18:15:15 roberto Exp $
** $Id: lgc.h,v 2.91.1.1 2017/04/19 17:39:34 roberto Exp $
** Garbage Collector
** See Copyright Notice in lua.h
*/
@@ -112,7 +112,7 @@
condchangemem(L,pre,pos); }
/* more often than not, 'pre'/'pos' are empty */
#define luaC_checkGC(L) luaC_condGC(L,,)
#define luaC_checkGC(L) luaC_condGC(L,(void)0,(void)0)
#define luaC_barrier(L,p,v) ( \

View File

@@ -1,5 +1,5 @@
/*
** $Id: linit.c,v 1.38 2015/01/05 13:48:33 roberto Exp $
** $Id: linit.c,v 1.39.1.1 2017/04/19 17:20:42 roberto Exp $
** Initialization of libraries for lua.c and other clients
** See Copyright Notice in lua.h
*/
@@ -18,10 +18,10 @@
** open the library, which is already linked to the application.
** For that, do the following code:
**
** luaL_getsubtable(L, LUA_REGISTRYINDEX, "_PRELOAD");
** luaL_getsubtable(L, LUA_REGISTRYINDEX, LUA_PRELOAD_TABLE);
** lua_pushcfunction(L, luaopen_modname);
** lua_setfield(L, -2, modname);
** lua_pop(L, 1); // remove _PRELOAD table
** lua_pop(L, 1); // remove PRELOAD table
*/
#include "lprefix.h"

View File

@@ -1,5 +1,5 @@
/*
** $Id: liolib.c,v 2.148 2015/11/23 11:36:11 roberto Exp $
** $Id: liolib.c,v 2.151.1.1 2017/04/19 17:29:57 roberto Exp $
** Standard I/O (and system) library
** See Copyright Notice in lua.h
*/
@@ -37,10 +37,11 @@
#endif
/* Check whether 'mode' matches '[rwa]%+?[L_MODEEXT]*' */
#define l_checkmode(mode) \
(*mode != '\0' && strchr("rwa", *(mode++)) != NULL && \
(*mode != '+' || (++mode, 1)) && /* skip if char is '+' */ \
(strspn(mode, L_MODEEXT) == strlen(mode)))
static int l_checkmode (const char *mode) {
return (*mode != '\0' && strchr("rwa", *(mode++)) != NULL &&
(*mode != '+' || (++mode, 1)) && /* skip if char is '+' */
(strspn(mode, L_MODEEXT) == strlen(mode))); /* check extensions */
}
#endif
@@ -205,11 +206,16 @@ static int aux_close (lua_State *L) {
}
static int f_close (lua_State *L) {
tofile(L); /* make sure argument is an open stream */
return aux_close(L);
}
static int io_close (lua_State *L) {
if (lua_isnone(L, 1)) /* no argument? */
lua_getfield(L, LUA_REGISTRYINDEX, IO_OUTPUT); /* use standard output */
tofile(L); /* make sure argument is an open stream */
return aux_close(L);
return f_close(L);
}
@@ -375,14 +381,17 @@ static int io_lines (lua_State *L) {
/* maximum length of a numeral */
#define MAXRN 200
#if !defined (L_MAXLENNUM)
#define L_MAXLENNUM 200
#endif
/* auxiliary structure used by 'read_number' */
typedef struct {
FILE *f; /* file being read */
int c; /* current character (look ahead) */
int n; /* number of elements in buffer 'buff' */
char buff[MAXRN + 1]; /* +1 for ending '\0' */
char buff[L_MAXLENNUM + 1]; /* +1 for ending '\0' */
} RN;
@@ -390,7 +399,7 @@ typedef struct {
** Add current char to buffer (if not out of space) and read next one
*/
static int nextc (RN *rn) {
if (rn->n >= MAXRN) { /* buffer overflow? */
if (rn->n >= L_MAXLENNUM) { /* buffer overflow? */
rn->buff[0] = '\0'; /* invalidate result */
return 0; /* fail */
}
@@ -403,10 +412,10 @@ static int nextc (RN *rn) {
/*
** Accept current char if it is in 'set' (of size 1 or 2)
** Accept current char if it is in 'set' (of size 2)
*/
static int test2 (RN *rn, const char *set) {
if (rn->c == set[0] || (rn->c == set[1] && rn->c != '\0'))
if (rn->c == set[0] || rn->c == set[1])
return nextc(rn);
else return 0;
}
@@ -435,11 +444,11 @@ static int read_number (lua_State *L, FILE *f) {
char decp[2];
rn.f = f; rn.n = 0;
decp[0] = lua_getlocaledecpoint(); /* get decimal point from locale */
decp[1] = '\0';
decp[1] = '.'; /* always accept a dot */
l_lockfile(rn.f);
do { rn.c = l_getc(rn.f); } while (isspace(rn.c)); /* skip spaces */
test2(&rn, "-+"); /* optional signal */
if (test2(&rn, "0")) {
if (test2(&rn, "00")) {
if (test2(&rn, "xX")) hex = 1; /* numeral is hexadecimal */
else count = 1; /* count initial '0' as a valid digit */
}
@@ -615,8 +624,10 @@ static int g_write (lua_State *L, FILE *f, int arg) {
if (lua_type(L, arg) == LUA_TNUMBER) {
/* optimization: could be done exactly as for strings */
int len = lua_isinteger(L, arg)
? fprintf(f, LUA_INTEGER_FMT, lua_tointeger(L, arg))
: fprintf(f, LUA_NUMBER_FMT, lua_tonumber(L, arg));
? fprintf(f, LUA_INTEGER_FMT,
(LUAI_UACINT)lua_tointeger(L, arg))
: fprintf(f, LUA_NUMBER_FMT,
(LUAI_UACNUMBER)lua_tonumber(L, arg));
status = status && (len > 0);
}
else {
@@ -706,7 +717,7 @@ static const luaL_Reg iolib[] = {
** methods for file handles
*/
static const luaL_Reg flib[] = {
{"close", io_close},
{"close", f_close},
{"flush", f_flush},
{"lines", f_lines},
{"read", f_read},

View File

@@ -1,5 +1,5 @@
/*
** $Id: llex.c,v 2.95 2015/11/19 19:16:22 roberto Exp $
** $Id: llex.c,v 2.96.1.1 2017/04/19 17:20:42 roberto Exp $
** Lexical Analyzer
** See Copyright Notice in lua.h
*/
@@ -162,7 +162,6 @@ static void inclinenumber (LexState *ls) {
void luaX_setinput (lua_State *L, LexState *ls, ZIO *z, TString *source,
int firstchar) {
ls->t.token = 0;
ls->decpoint = '.';
ls->L = L;
ls->current = firstchar;
ls->lookahead.token = TK_EOS; /* no look-ahead token */
@@ -207,35 +206,6 @@ static int check_next2 (LexState *ls, const char *set) {
}
/*
** change all characters 'from' in buffer to 'to'
*/
static void buffreplace (LexState *ls, char from, char to) {
if (from != to) {
size_t n = luaZ_bufflen(ls->buff);
char *p = luaZ_buffer(ls->buff);
while (n--)
if (p[n] == from) p[n] = to;
}
}
/*
** in case of format error, try to change decimal point separator to
** the one defined in the current locale and check again
*/
static void trydecpoint (LexState *ls, TValue *o) {
char old = ls->decpoint;
ls->decpoint = lua_getlocaledecpoint();
buffreplace(ls, old, ls->decpoint); /* try new decimal separator */
if (luaO_str2num(luaZ_buffer(ls->buff), o) == 0) {
/* format error with correct decimal point: no more options */
buffreplace(ls, ls->decpoint, '.'); /* undo change (for error message) */
lexerror(ls, "malformed number", TK_FLT);
}
}
/* LUA_NUMBER */
/*
** this function is quite liberal in what it accepts, as 'luaO_str2num'
@@ -259,9 +229,8 @@ static int read_numeral (LexState *ls, SemInfo *seminfo) {
else break;
}
save(ls, '\0');
buffreplace(ls, '.', ls->decpoint); /* follow locale for decimal point */
if (luaO_str2num(luaZ_buffer(ls->buff), &obj) == 0) /* format error? */
trydecpoint(ls, &obj); /* try to update decimal point separator */
lexerror(ls, "malformed number", TK_FLT);
if (ttisinteger(&obj)) {
seminfo->i = ivalue(&obj);
return TK_INT;

View File

@@ -1,5 +1,5 @@
/*
** $Id: llex.h,v 1.78 2014/10/29 15:38:24 roberto Exp $
** $Id: llex.h,v 1.79.1.1 2017/04/19 17:20:42 roberto Exp $
** Lexical Analyzer
** See Copyright Notice in lua.h
*/
@@ -69,7 +69,6 @@ typedef struct LexState {
struct Dyndata *dyd; /* dynamic structures used by the parser */
TString *source; /* current source name */
TString *envn; /* environment variable name */
char decpoint; /* locale decimal point */
} LexState;

View File

@@ -1,5 +1,5 @@
/*
** $Id: llimits.h,v 1.141 2015/11/19 19:16:22 roberto Exp $
** $Id: llimits.h,v 1.141.1.1 2017/04/19 17:20:42 roberto Exp $
** Limits, basic types, and some other 'installation-dependent' definitions
** See Copyright Notice in lua.h
*/

View File

@@ -1,5 +1,5 @@
/*
** $Id: lmathlib.c,v 1.117 2015/10/02 15:39:23 roberto Exp $
** $Id: lmathlib.c,v 1.119.1.1 2017/04/19 17:20:42 roberto Exp $
** Standard mathematical library
** See Copyright Notice in lua.h
*/
@@ -184,10 +184,13 @@ static int math_log (lua_State *L) {
else {
lua_Number base = luaL_checknumber(L, 2);
#if !defined(LUA_USE_C89)
if (base == 2.0) res = l_mathop(log2)(x); else
if (base == l_mathop(2.0))
res = l_mathop(log2)(x); else
#endif
if (base == 10.0) res = l_mathop(log10)(x);
else res = l_mathop(log)(x)/l_mathop(log)(base);
if (base == l_mathop(10.0))
res = l_mathop(log10)(x);
else
res = l_mathop(log)(x)/l_mathop(log)(base);
}
lua_pushnumber(L, res);
return 1;
@@ -262,7 +265,7 @@ static int math_random (lua_State *L) {
default: return luaL_error(L, "wrong number of arguments");
}
/* random integer in the interval [low, up] */
luaL_argcheck(L, low <= up, 1, "interval is empty");
luaL_argcheck(L, low <= up, 1, "interval is empty");
luaL_argcheck(L, low >= 0 || up <= LUA_MAXINTEGER + low, 1,
"interval too large");
r *= (double)(up - low) + 1.0;
@@ -281,9 +284,9 @@ static int math_randomseed (lua_State *L) {
static int math_type (lua_State *L) {
if (lua_type(L, 1) == LUA_TNUMBER) {
if (lua_isinteger(L, 1))
lua_pushliteral(L, "integer");
lua_pushliteral(L, "integer");
else
lua_pushliteral(L, "float");
lua_pushliteral(L, "float");
}
else {
luaL_checkany(L, 1);

View File

@@ -1,5 +1,5 @@
/*
** $Id: lmem.c,v 1.91 2015/03/06 19:45:54 roberto Exp $
** $Id: lmem.c,v 1.91.1.1 2017/04/19 17:20:42 roberto Exp $
** Interface to Memory Manager
** See Copyright Notice in lua.h
*/

View File

@@ -1,5 +1,5 @@
/*
** $Id: lmem.h,v 1.43 2014/12/19 17:26:14 roberto Exp $
** $Id: lmem.h,v 1.43.1.1 2017/04/19 17:20:42 roberto Exp $
** Interface to Memory Manager
** See Copyright Notice in lua.h
*/

View File

@@ -1,5 +1,5 @@
/*
** $Id: loadlib.c,v 1.127 2015/11/23 11:30:45 roberto Exp $
** $Id: loadlib.c,v 1.130.1.1 2017/04/19 17:20:42 roberto Exp $
** Dynamic library loader for Lua
** See Copyright Notice in lua.h
**
@@ -25,40 +25,9 @@
/*
** LUA_PATH_VAR and LUA_CPATH_VAR are the names of the environment
** variables that Lua check to set its paths.
*/
#if !defined(LUA_PATH_VAR)
#define LUA_PATH_VAR "LUA_PATH"
#endif
#if !defined(LUA_CPATH_VAR)
#define LUA_CPATH_VAR "LUA_CPATH"
#endif
#define LUA_PATHSUFFIX "_" LUA_VERSION_MAJOR "_" LUA_VERSION_MINOR
#define LUA_PATHVARVERSION LUA_PATH_VAR LUA_PATHSUFFIX
#define LUA_CPATHVARVERSION LUA_CPATH_VAR LUA_PATHSUFFIX
/*
** LUA_PATH_SEP is the character that separates templates in a path.
** LUA_PATH_MARK is the string that marks the substitution points in a
** template.
** LUA_EXEC_DIR in a Windows path is replaced by the executable's
** directory.
** LUA_IGMARK is a mark to ignore all before it when building the
** luaopen_ function name.
*/
#if !defined (LUA_PATH_SEP)
#define LUA_PATH_SEP ";"
#endif
#if !defined (LUA_PATH_MARK)
#define LUA_PATH_MARK "?"
#endif
#if !defined (LUA_EXEC_DIR)
#define LUA_EXEC_DIR "!"
#endif
#if !defined (LUA_IGMARK)
#define LUA_IGMARK "-"
#endif
@@ -94,7 +63,8 @@ static const int CLIBS = 0;
#define LIB_FAIL "open"
#define setprogdir(L) ((void)0)
#define setprogdir(L) ((void)0)
/*
@@ -179,7 +149,6 @@ static lua_CFunction lsys_sym (lua_State *L, void *lib, const char *sym) {
#include <windows.h>
#undef setprogdir
/*
** optional flags for LoadLibraryEx
@@ -189,21 +158,30 @@ static lua_CFunction lsys_sym (lua_State *L, void *lib, const char *sym) {
#endif
#undef setprogdir
/*
** Replace in the path (on the top of the stack) any occurrence
** of LUA_EXEC_DIR with the executable's path.
*/
static void setprogdir (lua_State *L) {
char buff[MAX_PATH + 1];
char *lb;
DWORD nsize = sizeof(buff)/sizeof(char);
DWORD n = GetModuleFileNameA(NULL, buff, nsize);
DWORD n = GetModuleFileNameA(NULL, buff, nsize); /* get exec. name */
if (n == 0 || n == nsize || (lb = strrchr(buff, '\\')) == NULL)
luaL_error(L, "unable to get ModuleFileName");
else {
*lb = '\0';
*lb = '\0'; /* cut name on the last '\\' to get the path */
luaL_gsub(L, lua_tostring(L, -1), LUA_EXEC_DIR, buff);
lua_remove(L, -2); /* remove original string */
}
}
static void pusherror (lua_State *L) {
int error = GetLastError();
char buffer[128];
@@ -272,6 +250,67 @@ static lua_CFunction lsys_sym (lua_State *L, void *lib, const char *sym) {
#endif /* } */
/*
** {==================================================================
** Set Paths
** ===================================================================
*/
/*
** LUA_PATH_VAR and LUA_CPATH_VAR are the names of the environment
** variables that Lua check to set its paths.
*/
#if !defined(LUA_PATH_VAR)
#define LUA_PATH_VAR "LUA_PATH"
#endif
#if !defined(LUA_CPATH_VAR)
#define LUA_CPATH_VAR "LUA_CPATH"
#endif
#define AUXMARK "\1" /* auxiliary mark */
/*
** return registry.LUA_NOENV as a boolean
*/
static int noenv (lua_State *L) {
int b;
lua_getfield(L, LUA_REGISTRYINDEX, "LUA_NOENV");
b = lua_toboolean(L, -1);
lua_pop(L, 1); /* remove value */
return b;
}
/*
** Set a path
*/
static void setpath (lua_State *L, const char *fieldname,
const char *envname,
const char *dft) {
const char *nver = lua_pushfstring(L, "%s%s", envname, LUA_VERSUFFIX);
const char *path = getenv(nver); /* use versioned name */
if (path == NULL) /* no environment variable? */
path = getenv(envname); /* try unversioned name */
if (path == NULL || noenv(L)) /* no environment variable? */
lua_pushstring(L, dft); /* use default */
else {
/* replace ";;" by ";AUXMARK;" and then AUXMARK by default path */
path = luaL_gsub(L, path, LUA_PATH_SEP LUA_PATH_SEP,
LUA_PATH_SEP AUXMARK LUA_PATH_SEP);
luaL_gsub(L, path, AUXMARK, dft);
lua_remove(L, -2); /* remove result from 1st 'gsub' */
}
setprogdir(L);
lua_setfield(L, -3, fieldname); /* package[fieldname] = path value */
lua_pop(L, 1); /* pop versioned variable name */
}
/* }================================================================== */
/*
** return registry.CLIBS[path]
*/
@@ -520,7 +559,7 @@ static int searcher_Croot (lua_State *L) {
static int searcher_preload (lua_State *L) {
const char *name = luaL_checkstring(L, 1);
lua_getfield(L, LUA_REGISTRYINDEX, "_PRELOAD");
lua_getfield(L, LUA_REGISTRYINDEX, LUA_PRELOAD_TABLE);
if (lua_getfield(L, -1, name) == LUA_TNIL) /* not found? */
lua_pushfstring(L, "\n\tno field package.preload['%s']", name);
return 1;
@@ -557,9 +596,9 @@ static void findloader (lua_State *L, const char *name) {
static int ll_require (lua_State *L) {
const char *name = luaL_checkstring(L, 1);
lua_settop(L, 1); /* _LOADED table will be at index 2 */
lua_getfield(L, LUA_REGISTRYINDEX, "_LOADED");
lua_getfield(L, 2, name); /* _LOADED[name] */
lua_settop(L, 1); /* LOADED table will be at index 2 */
lua_getfield(L, LUA_REGISTRYINDEX, LUA_LOADED_TABLE);
lua_getfield(L, 2, name); /* LOADED[name] */
if (lua_toboolean(L, -1)) /* is it there? */
return 1; /* package is already loaded */
/* else must load package */
@@ -569,11 +608,11 @@ static int ll_require (lua_State *L) {
lua_insert(L, -2); /* name is 1st argument (before search data) */
lua_call(L, 2, 1); /* run loader to load module */
if (!lua_isnil(L, -1)) /* non-nil return? */
lua_setfield(L, 2, name); /* _LOADED[name] = returned value */
lua_setfield(L, 2, name); /* LOADED[name] = returned value */
if (lua_getfield(L, 2, name) == LUA_TNIL) { /* module set no value? */
lua_pushboolean(L, 1); /* use true as result */
lua_pushvalue(L, -1); /* extra copy to be returned */
lua_setfield(L, 2, name); /* _LOADED[name] = true */
lua_setfield(L, 2, name); /* LOADED[name] = true */
}
return 1;
}
@@ -666,41 +705,6 @@ static int ll_seeall (lua_State *L) {
/* auxiliary mark (for internal use) */
#define AUXMARK "\1"
/*
** return registry.LUA_NOENV as a boolean
*/
static int noenv (lua_State *L) {
int b;
lua_getfield(L, LUA_REGISTRYINDEX, "LUA_NOENV");
b = lua_toboolean(L, -1);
lua_pop(L, 1); /* remove value */
return b;
}
static void setpath (lua_State *L, const char *fieldname, const char *envname1,
const char *envname2, const char *def) {
const char *path = getenv(envname1);
if (path == NULL) /* no environment variable? */
path = getenv(envname2); /* try alternative name */
if (path == NULL || noenv(L)) /* no environment variable? */
lua_pushstring(L, def); /* use default */
else {
/* replace ";;" by ";AUXMARK;" and then AUXMARK by default path */
path = luaL_gsub(L, path, LUA_PATH_SEP LUA_PATH_SEP,
LUA_PATH_SEP AUXMARK LUA_PATH_SEP);
luaL_gsub(L, path, AUXMARK, def);
lua_remove(L, -2);
}
setprogdir(L);
lua_setfield(L, -2, fieldname);
}
static const luaL_Reg pk_funcs[] = {
{"loadlib", ll_loadlib},
{"searchpath", ll_searchpath},
@@ -764,19 +768,18 @@ LUAMOD_API int luaopen_package (lua_State *L) {
createclibstable(L);
luaL_newlib(L, pk_funcs); /* create 'package' table */
createsearcherstable(L);
/* set field 'path' */
setpath(L, "path", LUA_PATHVARVERSION, LUA_PATH_VAR, LUA_PATH_DEFAULT);
/* set field 'cpath' */
setpath(L, "cpath", LUA_CPATHVARVERSION, LUA_CPATH_VAR, LUA_CPATH_DEFAULT);
/* set paths */
setpath(L, "path", LUA_PATH_VAR, LUA_PATH_DEFAULT);
setpath(L, "cpath", LUA_CPATH_VAR, LUA_CPATH_DEFAULT);
/* store config information */
lua_pushliteral(L, LUA_DIRSEP "\n" LUA_PATH_SEP "\n" LUA_PATH_MARK "\n"
LUA_EXEC_DIR "\n" LUA_IGMARK "\n");
lua_setfield(L, -2, "config");
/* set field 'loaded' */
luaL_getsubtable(L, LUA_REGISTRYINDEX, "_LOADED");
luaL_getsubtable(L, LUA_REGISTRYINDEX, LUA_LOADED_TABLE);
lua_setfield(L, -2, "loaded");
/* set field 'preload' */
luaL_getsubtable(L, LUA_REGISTRYINDEX, "_PRELOAD");
luaL_getsubtable(L, LUA_REGISTRYINDEX, LUA_PRELOAD_TABLE);
lua_setfield(L, -2, "preload");
lua_pushglobaltable(L);
lua_pushvalue(L, -2); /* set 'package' as upvalue for next lib */

View File

@@ -1,5 +1,5 @@
/*
** $Id: lobject.c,v 2.108 2015/11/02 16:09:30 roberto Exp $
** $Id: lobject.c,v 2.113.1.1 2017/04/19 17:29:57 roberto Exp $
** Some generic functions over Lua objects
** See Copyright Notice in lua.h
*/
@@ -243,20 +243,59 @@ static lua_Number lua_strx2number (const char *s, char **endptr) {
/* }====================================================== */
static const char *l_str2d (const char *s, lua_Number *result) {
/* maximum length of a numeral */
#if !defined (L_MAXLENNUM)
#define L_MAXLENNUM 200
#endif
static const char *l_str2dloc (const char *s, lua_Number *result, int mode) {
char *endptr;
if (strpbrk(s, "nN")) /* reject 'inf' and 'nan' */
return NULL;
else if (strpbrk(s, "xX")) /* hex? */
*result = lua_strx2number(s, &endptr);
else
*result = lua_str2number(s, &endptr);
if (endptr == s) return NULL; /* nothing recognized */
while (lisspace(cast_uchar(*endptr))) endptr++;
return (*endptr == '\0' ? endptr : NULL); /* OK if no trailing characters */
*result = (mode == 'x') ? lua_strx2number(s, &endptr) /* try to convert */
: lua_str2number(s, &endptr);
if (endptr == s) return NULL; /* nothing recognized? */
while (lisspace(cast_uchar(*endptr))) endptr++; /* skip trailing spaces */
return (*endptr == '\0') ? endptr : NULL; /* OK if no trailing characters */
}
/*
** Convert string 's' to a Lua number (put in 'result'). Return NULL
** on fail or the address of the ending '\0' on success.
** 'pmode' points to (and 'mode' contains) special things in the string:
** - 'x'/'X' means an hexadecimal numeral
** - 'n'/'N' means 'inf' or 'nan' (which should be rejected)
** - '.' just optimizes the search for the common case (nothing special)
** This function accepts both the current locale or a dot as the radix
** mark. If the convertion fails, it may mean number has a dot but
** locale accepts something else. In that case, the code copies 's'
** to a buffer (because 's' is read-only), changes the dot to the
** current locale radix mark, and tries to convert again.
*/
static const char *l_str2d (const char *s, lua_Number *result) {
const char *endptr;
const char *pmode = strpbrk(s, ".xXnN");
int mode = pmode ? ltolower(cast_uchar(*pmode)) : 0;
if (mode == 'n') /* reject 'inf' and 'nan' */
return NULL;
endptr = l_str2dloc(s, result, mode); /* try to convert */
if (endptr == NULL) { /* failed? may be a different locale */
char buff[L_MAXLENNUM + 1];
const char *pdot = strchr(s, '.');
if (strlen(s) > L_MAXLENNUM || pdot == NULL)
return NULL; /* string too long or no dot; fail */
strcpy(buff, s); /* copy string to buffer */
buff[pdot - s] = lua_getlocaledecpoint(); /* correct decimal point */
endptr = l_str2dloc(buff, result, mode); /* try again */
if (endptr != NULL)
endptr = s + (endptr - buff); /* make relative to 's' */
}
return endptr;
}
#define MAXBY10 cast(lua_Unsigned, LUA_MAXINTEGER / 10)
#define MAXLASTD cast_int(LUA_MAXINTEGER % 10)
static const char *l_str2int (const char *s, lua_Integer *result) {
lua_Unsigned a = 0;
int empty = 1;
@@ -273,7 +312,10 @@ static const char *l_str2int (const char *s, lua_Integer *result) {
}
else { /* decimal */
for (; lisdigit(cast_uchar(*s)); s++) {
a = a * 10 + *s - '0';
int d = *s - '0';
if (a >= MAXBY10 && (a > MAXBY10 || d > MAXLASTD + neg)) /* overflow? */
return NULL; /* do not accept it (as integer) */
a = a * 10 + d;
empty = 0;
}
}
@@ -351,8 +393,10 @@ static void pushstr (lua_State *L, const char *str, size_t l) {
}
/* this function handles only '%d', '%c', '%f', '%p', and '%s'
conventional formats, plus Lua-specific '%I' and '%U' */
/*
** this function handles only '%d', '%c', '%f', '%p', and '%s'
conventional formats, plus Lua-specific '%I' and '%U'
*/
const char *luaO_pushvfstring (lua_State *L, const char *fmt, va_list argp) {
int n = 0;
for (;;) {
@@ -360,13 +404,13 @@ const char *luaO_pushvfstring (lua_State *L, const char *fmt, va_list argp) {
if (e == NULL) break;
pushstr(L, fmt, e - fmt);
switch (*(e+1)) {
case 's': {
case 's': { /* zero-terminated string */
const char *s = va_arg(argp, char *);
if (s == NULL) s = "(null)";
pushstr(L, s, strlen(s));
break;
}
case 'c': {
case 'c': { /* an 'int' as a character */
char buff = cast(char, va_arg(argp, int));
if (lisprint(cast_uchar(buff)))
pushstr(L, &buff, 1);
@@ -374,28 +418,29 @@ const char *luaO_pushvfstring (lua_State *L, const char *fmt, va_list argp) {
luaO_pushfstring(L, "<\\%d>", cast_uchar(buff));
break;
}
case 'd': {
case 'd': { /* an 'int' */
setivalue(L->top, va_arg(argp, int));
goto top2str;
}
case 'I': {
case 'I': { /* a 'lua_Integer' */
setivalue(L->top, cast(lua_Integer, va_arg(argp, l_uacInt)));
goto top2str;
}
case 'f': {
case 'f': { /* a 'lua_Number' */
setfltvalue(L->top, cast_num(va_arg(argp, l_uacNumber)));
top2str:
top2str: /* convert the top element to a string */
luaD_inctop(L);
luaO_tostring(L, L->top - 1);
break;
}
case 'p': {
case 'p': { /* a pointer */
char buff[4*sizeof(void *) + 8]; /* should be enough space for a '%p' */
int l = l_sprintf(buff, sizeof(buff), "%p", va_arg(argp, void *));
void *p = va_arg(argp, void *);
int l = lua_pointer2str(buff, sizeof(buff), p);
pushstr(L, buff, l);
break;
}
case 'U': {
case 'U': { /* an 'int' as a UTF-8 sequence */
char buff[UTF8BUFFSZ];
int l = luaO_utf8esc(buff, cast(long, va_arg(argp, long)));
pushstr(L, buff + UTF8BUFFSZ - l, l);

View File

@@ -1,5 +1,5 @@
/*
** $Id: lobject.h,v 2.116 2015/11/03 18:33:10 roberto Exp $
** $Id: lobject.h,v 2.117.1.1 2017/04/19 17:39:34 roberto Exp $
** Type definitions for Lua objects
** See Copyright Notice in lua.h
*/
@@ -402,7 +402,7 @@ typedef struct LocVar {
typedef struct SharedProto {
lu_byte numparams; /* number of fixed parameters */
lu_byte is_vararg; /* 2: declared vararg; 1: uses vararg */
lu_byte is_vararg;
lu_byte maxstacksize; /* number of registers needed by this function */
int sizeupvalues; /* size of 'upvalues' */
int sizek; /* size of 'k' */

View File

@@ -1,5 +1,5 @@
/*
** $Id: lopcodes.c,v 1.55 2015/01/05 13:48:33 roberto Exp $
** $Id: lopcodes.c,v 1.55.1.1 2017/04/19 17:20:42 roberto Exp $
** Opcodes for Lua virtual machine
** See Copyright Notice in lua.h
*/

View File

@@ -1,5 +1,5 @@
/*
** $Id: lopcodes.h,v 1.148 2014/10/25 11:50:46 roberto Exp $
** $Id: lopcodes.h,v 1.149.1.1 2017/04/19 17:20:42 roberto Exp $
** Opcodes for Lua virtual machine
** See Copyright Notice in lua.h
*/
@@ -139,7 +139,9 @@ enum OpMode {iABC, iABx, iAsBx, iAx}; /* basic instruction format */
/* gets the index of the constant */
#define INDEXK(r) ((int)(r) & ~BITRK)
#if !defined(MAXINDEXRK) /* (for debugging only) */
#define MAXINDEXRK (BITRK - 1)
#endif
/* code a constant index as a RK value */
#define RKASK(x) ((x) | BITRK)

View File

@@ -1,5 +1,5 @@
/*
** $Id: loslib.c,v 1.60 2015/11/19 19:16:22 roberto Exp $
** $Id: loslib.c,v 1.65.1.1 2017/04/19 17:29:57 roberto Exp $
** Standard Operating System library
** See Copyright Notice in lua.h
*/
@@ -24,18 +24,29 @@
/*
** {==================================================================
** list of valid conversion specifiers for the 'strftime' function
** List of valid conversion specifiers for the 'strftime' function;
** options are grouped by length; group of length 2 start with '||'.
** ===================================================================
*/
#if !defined(LUA_STRFTIMEOPTIONS) /* { */
#if defined(LUA_USE_C89)
#define LUA_STRFTIMEOPTIONS { "aAbBcdHIjmMpSUwWxXyYz%", "" }
/* options for ANSI C 89 (only 1-char options) */
#define L_STRFTIMEC89 "aAbBcdHIjmMpSUwWxXyYZ%"
/* options for ISO C 99 and POSIX */
#define L_STRFTIMEC99 "aAbBcCdDeFgGhHIjmMnprRStTuUVwWxXyYzZ%" \
"||" "EcECExEXEyEY" "OdOeOHOIOmOMOSOuOUOVOwOWOy" /* two-char options */
/* options for Windows */
#define L_STRFTIMEWIN "aAbBcdHIjmMpSUwWxXyYzZ%" \
"||" "#c#x#d#H#I#j#m#M#S#U#w#W#y#Y" /* two-char options */
#if defined(LUA_USE_WINDOWS)
#define LUA_STRFTIMEOPTIONS L_STRFTIMEWIN
#elif defined(LUA_USE_C89)
#define LUA_STRFTIMEOPTIONS L_STRFTIMEC89
#else /* C99 specification */
#define LUA_STRFTIMEOPTIONS \
{ "aAbBcCdDeFgGhHIjmMnprRStTuUVwWxXyYzZ%", "", \
"E", "cCxXyY", \
"O", "deHImMSuUVwWy" }
#define LUA_STRFTIMEOPTIONS L_STRFTIMEC99
#endif
#endif /* } */
@@ -195,6 +206,23 @@ static void setboolfield (lua_State *L, const char *key, int value) {
lua_setfield(L, -2, key);
}
/*
** Set all fields from structure 'tm' in the table on top of the stack
*/
static void setallfields (lua_State *L, struct tm *stm) {
setfield(L, "sec", stm->tm_sec);
setfield(L, "min", stm->tm_min);
setfield(L, "hour", stm->tm_hour);
setfield(L, "day", stm->tm_mday);
setfield(L, "month", stm->tm_mon + 1);
setfield(L, "year", stm->tm_year + 1900);
setfield(L, "wday", stm->tm_wday + 1);
setfield(L, "yday", stm->tm_yday + 1);
setboolfield(L, "isdst", stm->tm_isdst);
}
static int getboolfield (lua_State *L, const char *key) {
int res;
res = (lua_getfield(L, -1, key) == LUA_TNIL) ? -1 : lua_toboolean(L, -1);
@@ -210,18 +238,18 @@ static int getboolfield (lua_State *L, const char *key) {
static int getfield (lua_State *L, const char *key, int d, int delta) {
int isnum;
int t = lua_getfield(L, -1, key);
int t = lua_getfield(L, -1, key); /* get field and its type */
lua_Integer res = lua_tointegerx(L, -1, &isnum);
if (!isnum) { /* field is not a number? */
if (!isnum) { /* field is not an integer? */
if (t != LUA_TNIL) /* some other value? */
return luaL_error(L, "field '%s' not an integer", key);
return luaL_error(L, "field '%s' is not an integer", key);
else if (d < 0) /* absent field; no default? */
return luaL_error(L, "field '%s' missing in date table", key);
res = d;
}
else {
if (!(-L_MAXDATEFIELD <= res && res <= L_MAXDATEFIELD))
return luaL_error(L, "field '%s' out-of-bounds", key);
return luaL_error(L, "field '%s' is out-of-bound", key);
res -= delta;
}
lua_pop(L, 1);
@@ -229,22 +257,17 @@ static int getfield (lua_State *L, const char *key, int d, int delta) {
}
static const char *checkoption (lua_State *L, const char *conv, char *buff) {
static const char *const options[] = LUA_STRFTIMEOPTIONS;
unsigned int i;
for (i = 0; i < sizeof(options)/sizeof(options[0]); i += 2) {
if (*conv != '\0' && strchr(options[i], *conv) != NULL) {
buff[1] = *conv;
if (*options[i + 1] == '\0') { /* one-char conversion specifier? */
buff[2] = '\0'; /* end buffer */
return conv + 1;
}
else if (*(conv + 1) != '\0' &&
strchr(options[i + 1], *(conv + 1)) != NULL) {
buff[2] = *(conv + 1); /* valid two-char conversion specifier */
buff[3] = '\0'; /* end buffer */
return conv + 2;
}
static const char *checkoption (lua_State *L, const char *conv,
ptrdiff_t convlen, char *buff) {
const char *option = LUA_STRFTIMEOPTIONS;
int oplen = 1; /* length of options being checked */
for (; *option != '\0' && oplen <= convlen; option += oplen) {
if (*option == '|') /* next block? */
oplen++; /* will check options with next length (+1) */
else if (memcmp(conv, option, oplen) == 0) { /* match? */
memcpy(buff, conv, oplen); /* copy valid option to buffer */
buff[oplen] = '\0';
return conv + oplen; /* return next item */
}
}
luaL_argerror(L, 1,
@@ -258,8 +281,10 @@ static const char *checkoption (lua_State *L, const char *conv, char *buff) {
static int os_date (lua_State *L) {
const char *s = luaL_optstring(L, 1, "%c");
size_t slen;
const char *s = luaL_optlstring(L, 1, "%c", &slen);
time_t t = luaL_opt(L, l_checktime, 2, time(NULL));
const char *se = s + slen; /* 's' end */
struct tm tmr, *stm;
if (*s == '!') { /* UTC? */
stm = l_gmtime(&t, &tmr);
@@ -268,31 +293,25 @@ static int os_date (lua_State *L) {
else
stm = l_localtime(&t, &tmr);
if (stm == NULL) /* invalid date? */
luaL_error(L, "time result cannot be represented in this installation");
return luaL_error(L,
"time result cannot be represented in this installation");
if (strcmp(s, "*t") == 0) {
lua_createtable(L, 0, 9); /* 9 = number of fields */
setfield(L, "sec", stm->tm_sec);
setfield(L, "min", stm->tm_min);
setfield(L, "hour", stm->tm_hour);
setfield(L, "day", stm->tm_mday);
setfield(L, "month", stm->tm_mon+1);
setfield(L, "year", stm->tm_year+1900);
setfield(L, "wday", stm->tm_wday+1);
setfield(L, "yday", stm->tm_yday+1);
setboolfield(L, "isdst", stm->tm_isdst);
setallfields(L, stm);
}
else {
char cc[4];
char cc[4]; /* buffer for individual conversion specifiers */
luaL_Buffer b;
cc[0] = '%';
luaL_buffinit(L, &b);
while (*s) {
while (s < se) {
if (*s != '%') /* not a conversion specifier? */
luaL_addchar(&b, *s++);
else {
size_t reslen;
char *buff = luaL_prepbuffsize(&b, SIZETIMEFMT);
s = checkoption(L, s + 1, cc);
s++; /* skip '%' */
s = checkoption(L, s, se - s, cc + 1); /* copy specifier to 'cc' */
reslen = strftime(buff, SIZETIMEFMT, cc, stm);
luaL_addsize(&b, reslen);
}
@@ -319,9 +338,11 @@ static int os_time (lua_State *L) {
ts.tm_year = getfield(L, "year", -1, 1900);
ts.tm_isdst = getboolfield(L, "isdst");
t = mktime(&ts);
setallfields(L, &ts); /* update fields with normalized values */
}
if (t != (time_t)(l_timet)t || t == (time_t)(-1))
luaL_error(L, "time result cannot be represented in this installation");
return luaL_error(L,
"time result cannot be represented in this installation");
l_pushtime(L, t);
return 1;
}

View File

@@ -1,5 +1,5 @@
/*
** $Id: lparser.c,v 2.149 2015/11/02 16:09:30 roberto Exp $
** $Id: lparser.c,v 2.155.1.2 2017/04/29 18:11:40 roberto Exp $
** Lua Parser
** See Copyright Notice in lua.h
*/
@@ -165,7 +165,8 @@ static int registerlocalvar (LexState *ls, TString *varname) {
int oldsize = f->sizelocvars;
luaM_growvector(ls->L, f->locvars, fs->nlocvars, f->sizelocvars,
LocVar, SHRT_MAX, "local variables");
while (oldsize < f->sizelocvars) f->locvars[oldsize++].varname = NULL;
while (oldsize < f->sizelocvars)
f->locvars[oldsize++].varname = NULL;
f->locvars[fs->nlocvars].varname = varname;
luaC_objbarrier(ls->L, fp, varname);
return fs->nlocvars++;
@@ -232,7 +233,8 @@ static int newupvalue (FuncState *fs, TString *name, expdesc *v) {
checklimit(fs, fs->nups + 1, MAXUPVAL, "upvalues");
luaM_growvector(fs->ls->L, f->upvalues, fs->nups, f->sizeupvalues,
Upvaldesc, MAXUPVAL, "upvalues");
while (oldsize < f->sizeupvalues) f->upvalues[oldsize++].name = NULL;
while (oldsize < f->sizeupvalues)
f->upvalues[oldsize++].name = NULL;
f->upvalues[fs->nups].instack = (v->k == VLOCAL);
f->upvalues[fs->nups].idx = cast_byte(v->u.info);
f->upvalues[fs->nups].name = name;
@@ -257,7 +259,8 @@ static int searchvar (FuncState *fs, TString *n) {
*/
static void markupval (FuncState *fs, int level) {
BlockCnt *bl = fs->bl;
while (bl->nactvar > level) bl = bl->previous;
while (bl->nactvar > level)
bl = bl->previous;
bl->upval = 1;
}
@@ -266,27 +269,26 @@ static void markupval (FuncState *fs, int level) {
Find variable with given name 'n'. If it is an upvalue, add this
upvalue into all intermediate functions.
*/
static int singlevaraux (FuncState *fs, TString *n, expdesc *var, int base) {
static void singlevaraux (FuncState *fs, TString *n, expdesc *var, int base) {
if (fs == NULL) /* no more levels? */
return VVOID; /* default is global */
init_exp(var, VVOID, 0); /* default is global */
else {
int v = searchvar(fs, n); /* look up locals at current level */
if (v >= 0) { /* found? */
init_exp(var, VLOCAL, v); /* variable is local */
if (!base)
markupval(fs, v); /* local will be used as an upval */
return VLOCAL;
}
else { /* not found as local at current level; try upvalues */
int idx = searchupvalue(fs, n); /* try existing upvalues */
if (idx < 0) { /* not found? */
if (singlevaraux(fs->prev, n, var, 0) == VVOID) /* try upper levels */
return VVOID; /* not found; is a global */
singlevaraux(fs->prev, n, var, 0); /* try upper levels */
if (var->k == VVOID) /* not found? */
return; /* it is a global */
/* else was LOCAL or UPVAL */
idx = newupvalue(fs, n, var); /* will be a new upvalue */
}
init_exp(var, VUPVAL, idx);
return VUPVAL;
init_exp(var, VUPVAL, idx); /* new or old upvalue */
}
}
}
@@ -295,10 +297,11 @@ static int singlevaraux (FuncState *fs, TString *n, expdesc *var, int base) {
static void singlevar (LexState *ls, expdesc *var) {
TString *varname = str_checkname(ls);
FuncState *fs = ls->fs;
if (singlevaraux(fs, varname, var, 1) == VVOID) { /* global name? */
singlevaraux(fs, varname, var, 1);
if (var->k == VVOID) { /* global name? */
expdesc key;
singlevaraux(fs, ls->envn, var, 1); /* get environment variable */
lua_assert(var->k == VLOCAL || var->k == VUPVAL);
lua_assert(var->k != VVOID); /* this one must exist */
codestring(ls, &key, varname); /* key is variable name */
luaK_indexed(fs, var, &key); /* env[varname] */
}
@@ -322,6 +325,8 @@ static void adjust_assign (LexState *ls, int nvars, int nexps, expdesc *e) {
luaK_nil(fs, reg, extra);
}
}
if (nexps > nvars)
ls->fs->freereg -= nexps - nvars; /* remove extra values */
}
@@ -501,7 +506,8 @@ static Proto *addprototype (LexState *ls) {
if (fs->np >= f->sp->sizep) {
int oldsize = f->sp->sizep;
luaM_growvector(L, f->p, fs->np, f->sp->sizep, Proto *, MAXARG_Bx, "functions");
while (oldsize < f->sp->sizep) f->p[oldsize++] = NULL;
while (oldsize < f->sp->sizep)
f->p[oldsize++] = NULL;
}
f->p[fs->np++] = clp = luaF_newproto(L, NULL);
luaC_objbarrier(L, f, clp);
@@ -763,7 +769,7 @@ static void parlist (LexState *ls) {
}
case TK_DOTS: { /* param -> '...' */
luaX_next(ls);
f->is_vararg = 2; /* declared vararg */
f->is_vararg = 1; /* declared vararg */
break;
}
default: luaX_syntaxerror(ls, "<name> or '...' expected");
@@ -959,7 +965,6 @@ static void simpleexp (LexState *ls, expdesc *v) {
FuncState *fs = ls->fs;
check_condition(ls, fs->f->sp->is_vararg,
"cannot use '...' outside a vararg function");
fs->f->sp->is_vararg = 1; /* function actually uses vararg */
init_exp(v, VVARARG, luaK_codeABC(fs, OP_VARARG, 0, 1, 0));
break;
}
@@ -1159,11 +1164,8 @@ static void assignment (LexState *ls, struct LHS_assign *lh, int nvars) {
int nexps;
checknext(ls, '=');
nexps = explist(ls, &e);
if (nexps != nvars) {
if (nexps != nvars)
adjust_assign(ls, nvars, nexps, &e);
if (nexps > nvars)
ls->fs->freereg -= nexps - nvars; /* remove extra values */
}
else {
luaK_setoneret(ls->fs, &e); /* close last expression */
luaK_storevar(ls->fs, &lh->v, &e);
@@ -1229,7 +1231,7 @@ static void labelstat (LexState *ls, TString *label, int line) {
checkrepeated(fs, ll, label); /* check for repeated labels */
checknext(ls, TK_DBCOLON); /* skip double colon */
/* create new entry for this label */
l = newlabelentry(ls, ll, label, line, fs->pc);
l = newlabelentry(ls, ll, label, line, luaK_getlabel(fs));
skipnoopstat(ls); /* skip other no-op statements */
if (block_follow(ls, 0)) { /* label is last no-op statement in the block? */
/* assume that locals are already out of scope */
@@ -1393,7 +1395,7 @@ static void test_then_block (LexState *ls, int *escapelist) {
luaK_goiffalse(ls->fs, &v); /* will jump to label if condition is true */
enterblock(fs, &bl, 0); /* must enter block before 'goto' */
gotostat(ls, v.t); /* handle goto/break */
skipnoopstat(ls); /* skip other no-op statements */
while (testnext(ls, ';')) {} /* skip colons */
if (block_follow(ls, 0)) { /* 'goto' is the entire block? */
leaveblock(fs);
return; /* and that is it */
@@ -1497,7 +1499,7 @@ static void exprstat (LexState *ls) {
}
else { /* stat -> func */
check_condition(ls, v.v.k == VCALL, "syntax error");
SETARG_C(getcode(fs, &v.v), 1); /* call statement uses no results */
SETARG_C(getinstruction(fs, &v.v), 1); /* call statement uses no results */
}
}
@@ -1514,8 +1516,8 @@ static void retstat (LexState *ls) {
if (hasmultret(e.k)) {
luaK_setmultret(fs, &e);
if (e.k == VCALL && nret == 1) { /* tail call? */
SET_OPCODE(getcode(fs,&e), OP_TAILCALL);
lua_assert(GETARG_A(getcode(fs,&e)) == fs->nactvar);
SET_OPCODE(getinstruction(fs,&e), OP_TAILCALL);
lua_assert(GETARG_A(getinstruction(fs,&e)) == fs->nactvar);
}
first = fs->nactvar;
nret = LUA_MULTRET; /* return all values */
@@ -1597,7 +1599,7 @@ static void statement (LexState *ls) {
break;
}
}
lua_assert(ls->fs->f->maxstacksize >= ls->fs->freereg &&
lua_assert(ls->fs->f->sp->maxstacksize >= ls->fs->freereg &&
ls->fs->freereg >= ls->fs->nactvar);
ls->fs->freereg = ls->fs->nactvar; /* free registers */
leavelevel(ls);
@@ -1614,7 +1616,7 @@ static void mainfunc (LexState *ls, FuncState *fs) {
BlockCnt bl;
expdesc v;
open_func(ls, fs, &bl);
fs->f->sp->is_vararg = 2; /* main function is always declared vararg */
fs->f->sp->is_vararg = 1; /* main function is always declared vararg */
init_exp(&v, VLOCAL, 0); /* create and... */
newupvalue(fs, ls->envn, &v); /* ...set environment upvalue */
luaX_next(ls); /* read first token */

View File

@@ -1,5 +1,5 @@
/*
** $Id: lparser.h,v 1.74 2014/10/25 11:50:46 roberto Exp $
** $Id: lparser.h,v 1.76.1.1 2017/04/19 17:20:42 roberto Exp $
** Lua Parser
** See Copyright Notice in lua.h
*/
@@ -13,25 +13,38 @@
/*
** Expression descriptor
** Expression and variable descriptor.
** Code generation for variables and expressions can be delayed to allow
** optimizations; An 'expdesc' structure describes a potentially-delayed
** variable/expression. It has a description of its "main" value plus a
** list of conditional jumps that can also produce its value (generated
** by short-circuit operators 'and'/'or').
*/
/* kinds of variables/expressions */
typedef enum {
VVOID, /* no value */
VNIL,
VTRUE,
VFALSE,
VK, /* info = index of constant in 'k' */
VKFLT, /* nval = numerical float value */
VKINT, /* nval = numerical integer value */
VNONRELOC, /* info = result register */
VLOCAL, /* info = local register */
VUPVAL, /* info = index of upvalue in 'upvalues' */
VINDEXED, /* t = table register/upvalue; idx = index R/K */
VJMP, /* info = instruction pc */
VRELOCABLE, /* info = instruction pc */
VCALL, /* info = instruction pc */
VVARARG /* info = instruction pc */
VVOID, /* when 'expdesc' describes the last expression a list,
this kind means an empty list (so, no expression) */
VNIL, /* constant nil */
VTRUE, /* constant true */
VFALSE, /* constant false */
VK, /* constant in 'k'; info = index of constant in 'k' */
VKFLT, /* floating constant; nval = numerical float value */
VKINT, /* integer constant; nval = numerical integer value */
VNONRELOC, /* expression has its value in a fixed register;
info = result register */
VLOCAL, /* local variable; info = local register */
VUPVAL, /* upvalue variable; info = index of upvalue in 'upvalues' */
VINDEXED, /* indexed variable;
ind.vt = whether 't' is register or upvalue;
ind.t = table register or upvalue;
ind.idx = key's R/K index */
VJMP, /* expression is a test/comparison;
info = pc of corresponding jump instruction */
VRELOCABLE, /* expression can put result in any register;
info = instruction pc */
VCALL, /* expression is a function call; info = instruction pc */
VVARARG /* vararg expression; info = instruction pc */
} expkind;
@@ -41,14 +54,14 @@ typedef enum {
typedef struct expdesc {
expkind k;
union {
lua_Integer ival; /* for VKINT */
lua_Number nval; /* for VKFLT */
int info; /* for generic use */
struct { /* for indexed variables (VINDEXED) */
short idx; /* index (R/K) */
lu_byte t; /* table (register or upvalue) */
lu_byte vt; /* whether 't' is register (VLOCAL) or upvalue (VUPVAL) */
} ind;
int info; /* for generic use */
lua_Number nval; /* for VKFLT */
lua_Integer ival; /* for VKINT */
} u;
int t; /* patch list of 'exit when true' */
int f; /* patch list of 'exit when false' */

View File

@@ -1,5 +1,5 @@
/*
** $Id: lprefix.h,v 1.2 2014/12/29 16:54:13 roberto Exp $
** $Id: lprefix.h,v 1.2.1.1 2017/04/19 17:20:42 roberto Exp $
** Definitions for Lua code that must come before any other header file
** See Copyright Notice in lua.h
*/

View File

@@ -1,5 +1,5 @@
/*
** $Id: lstate.c,v 2.133 2015/11/13 12:16:51 roberto Exp $
** $Id: lstate.c,v 2.133.1.1 2017/04/19 17:39:34 roberto Exp $
** Global State
** See Copyright Notice in lua.h
*/

View File

@@ -1,5 +1,5 @@
/*
** $Id: lstate.h,v 2.128 2015/11/13 12:16:51 roberto Exp $
** $Id: lstate.h,v 2.133.1.1 2017/04/19 17:39:34 roberto Exp $
** Global State
** See Copyright Notice in lua.h
*/
@@ -23,9 +23,27 @@
**
** 'allgc': all objects not marked for finalization;
** 'finobj': all objects marked for finalization;
** 'tobefnz': all objects ready to be finalized;
** 'tobefnz': all objects ready to be finalized;
** 'fixedgc': all objects that are not to be collected (currently
** only small strings, such as reserved words).
**
** Moreover, there is another set of lists that control gray objects.
** These lists are linked by fields 'gclist'. (All objects that
** can become gray have such a field. The field is not the same
** in all objects, but it always has this name.) Any gray object
** must belong to one of these lists, and all objects in these lists
** must be gray:
**
** 'gray': regular gray objects, still waiting to be visited.
** 'grayagain': objects that must be revisited at the atomic phase.
** That includes
** - black objects got in a write barrier;
** - all kinds of weak tables during propagation phase;
** - all threads.
** 'weak': tables with weak values to be cleared;
** 'ephemeron': ephemeron tables with white->white entries;
** 'allweak': tables with weak keys and/or weak values to be cleared.
** The last three lists are used only during the atomic phase.
*/
@@ -33,6 +51,15 @@
struct lua_longjmp; /* defined in ldo.c */
/*
** Atomic type (relative to signals) to better ensure that 'lua_sethook'
** is thread safe
*/
#if !defined(l_signalT)
#include <signal.h>
#define l_signalT sig_atomic_t
#endif
/* extra stack space to handle TM calls and some other extras */
#define EXTRA_STACK 5
@@ -57,7 +84,7 @@ typedef struct stringtable {
** Information about a call.
** When a thread yields, 'func' is adjusted to pretend that the
** top function has only the yielded values in its stack; in that
** case, the actual 'func' value is saved in field 'extra'.
** case, the actual 'func' value is saved in field 'extra'.
** When a function calls another with a continuation, 'extra' keeps
** the function index so that, in case of errors, the continuation
** function can be called with the correct top.
@@ -79,7 +106,7 @@ typedef struct CallInfo {
} u;
ptrdiff_t extra;
short nresults; /* expected number of results from this function */
lu_byte callstatus;
unsigned short callstatus;
} CallInfo;
@@ -95,6 +122,7 @@ typedef struct CallInfo {
#define CIST_TAIL (1<<5) /* call was tail called */
#define CIST_HOOKYIELD (1<<6) /* last hook called yielded */
#define CIST_LEQ (1<<7) /* using __lt for __le */
#define CIST_FIN (1<<8) /* call is running a finalizer */
#define isLua(ci) ((ci)->callstatus & CIST_LUA)
@@ -162,14 +190,14 @@ struct lua_State {
struct lua_State *twups; /* list of threads with open upvalues */
struct lua_longjmp *errorJmp; /* current error recover point */
CallInfo base_ci; /* CallInfo for first level (C calling Lua) */
lua_Hook hook;
volatile lua_Hook hook;
ptrdiff_t errfunc; /* current error handling function (stack index) */
int stacksize;
int basehookcount;
int hookcount;
unsigned short nny; /* number of non-yieldable calls in stack */
unsigned short nCcalls; /* number of nested C calls */
lu_byte hookmask;
l_signalT hookmask;
lu_byte allowhook;
};

View File

@@ -1,5 +1,5 @@
/*
** $Id: lstring.c,v 2.56 2015/11/23 11:32:51 roberto Exp $
** $Id: lstring.c,v 2.56.1.1 2017/04/19 17:20:42 roberto Exp $
** String table (keeps all strings handled by Lua)
** See Copyright Notice in lua.h
*/
@@ -419,8 +419,11 @@ luaS_clonestring(lua_State *L, TString *ts) {
result = query_ptr(ts);
if (result)
return result;
// ts is not in SSM, so recalc hash, and add it to SSM
h = luaS_hash(str, l, 0);
result = query_string(h, str, l);
if (result)
return result;
// ts is not in SSM, so recalc hash, and add it to SSM
return add_string(h, str, l);
}

View File

@@ -1,5 +1,5 @@
/*
** $Id: lstring.h,v 1.61 2015/11/03 15:36:01 roberto Exp $
** $Id: lstring.h,v 1.61.1.1 2017/04/19 17:20:42 roberto Exp $
** String table (keep all strings handled by Lua)
** See Copyright Notice in lua.h
*/

View File

@@ -1,5 +1,5 @@
/*
** $Id: lstrlib.c,v 1.239 2015/11/25 16:28:17 roberto Exp $
** $Id: lstrlib.c,v 1.254.1.1 2017/04/19 17:29:57 roberto Exp $
** Standard library for string operations and pattern-matching
** See Copyright Notice in lua.h
*/
@@ -13,6 +13,7 @@
#include <ctype.h>
#include <float.h>
#include <limits.h>
#include <locale.h>
#include <stddef.h>
#include <stdio.h>
#include <stdlib.h>
@@ -26,7 +27,8 @@
/*
** maximum number of captures that a pattern can do during
** pattern-matching. This limit is arbitrary.
** pattern-matching. This limit is arbitrary, but must fit in
** an unsigned char.
*/
#if !defined(LUA_MAXCAPTURES)
#define LUA_MAXCAPTURES 32
@@ -214,9 +216,8 @@ typedef struct MatchState {
const char *src_end; /* end ('\0') of source string */
const char *p_end; /* end ('\0') of pattern */
lua_State *L;
size_t nrep; /* limit to avoid non-linear complexity */
int matchdepth; /* control for recursive depth (to avoid C stack overflow) */
int level; /* total number of captures (finished or unfinished) */
unsigned char level; /* total number of captures (finished or unfinished) */
struct {
const char *init;
ptrdiff_t len;
@@ -234,17 +235,6 @@ static const char *match (MatchState *ms, const char *s, const char *p);
#endif
/*
** parameters to control the maximum number of operators handled in
** a match (to avoid non-linear complexity). The maximum will be:
** (subject length) * A_REPS + B_REPS
*/
#if !defined(A_REPS)
#define A_REPS 4
#define B_REPS 100000
#endif
#define L_ESC '%'
#define SPECIALS "^$*+?.([%-"
@@ -502,8 +492,6 @@ static const char *match (MatchState *ms, const char *s, const char *p) {
s = NULL; /* fail */
}
else { /* matched once */
if (ms->nrep-- == 0)
luaL_error(ms->L, "pattern too complex");
switch (*ep) { /* handle optional suffix */
case '?': { /* optional */
const char *res;
@@ -607,10 +595,6 @@ static void prepstate (MatchState *ms, lua_State *L,
ms->src_init = s;
ms->src_end = s + ls;
ms->p_end = p + lp;
if (ls < (MAX_SIZET - B_REPS) / A_REPS)
ms->nrep = A_REPS * ls + B_REPS;
else /* overflow (very long subject) */
ms->nrep = MAX_SIZET; /* no limit */
}
@@ -681,6 +665,7 @@ static int str_match (lua_State *L) {
typedef struct GMatchState {
const char *src; /* current position */
const char *p; /* pattern */
const char *lastmatch; /* end of last match */
MatchState ms; /* match state */
} GMatchState;
@@ -688,14 +673,12 @@ typedef struct GMatchState {
static int gmatch_aux (lua_State *L) {
GMatchState *gm = (GMatchState *)lua_touserdata(L, lua_upvalueindex(3));
const char *src;
gm->ms.L = L;
for (src = gm->src; src <= gm->ms.src_end; src++) {
const char *e;
reprepstate(&gm->ms);
if ((e = match(&gm->ms, src, gm->p)) != NULL) {
if (e == src) /* empty match? */
gm->src =src + 1; /* go at least one position */
else
gm->src = e;
if ((e = match(&gm->ms, src, gm->p)) != NULL && e != gm->lastmatch) {
gm->src = gm->lastmatch = e;
return push_captures(&gm->ms, src, e);
}
}
@@ -711,7 +694,7 @@ static int gmatch (lua_State *L) {
lua_settop(L, 2); /* keep them on closure to avoid being collected */
gm = (GMatchState *)lua_newuserdata(L, sizeof(GMatchState));
prepstate(&gm->ms, L, s, ls, p, lp);
gm->src = s; gm->p = p;
gm->src = s; gm->p = p; gm->lastmatch = NULL;
lua_pushcclosure(L, gmatch_aux, 3);
return 1;
}
@@ -778,12 +761,13 @@ static void add_value (MatchState *ms, luaL_Buffer *b, const char *s,
static int str_gsub (lua_State *L) {
size_t srcl, lp;
const char *src = luaL_checklstring(L, 1, &srcl);
const char *p = luaL_checklstring(L, 2, &lp);
int tr = lua_type(L, 3);
lua_Integer max_s = luaL_optinteger(L, 4, srcl + 1);
const char *src = luaL_checklstring(L, 1, &srcl); /* subject */
const char *p = luaL_checklstring(L, 2, &lp); /* pattern */
const char *lastmatch = NULL; /* end of last match */
int tr = lua_type(L, 3); /* replacement type */
lua_Integer max_s = luaL_optinteger(L, 4, srcl + 1); /* max replacements */
int anchor = (*p == '^');
lua_Integer n = 0;
lua_Integer n = 0; /* replacement count */
MatchState ms;
luaL_Buffer b;
luaL_argcheck(L, tr == LUA_TNUMBER || tr == LUA_TSTRING ||
@@ -796,16 +780,15 @@ static int str_gsub (lua_State *L) {
prepstate(&ms, L, src, srcl, p, lp);
while (n < max_s) {
const char *e;
reprepstate(&ms);
if ((e = match(&ms, src, p)) != NULL) {
reprepstate(&ms); /* (re)prepare state for new match */
if ((e = match(&ms, src, p)) != NULL && e != lastmatch) { /* match? */
n++;
add_value(&ms, &b, src, e, tr);
add_value(&ms, &b, src, e, tr); /* add replacement to buffer */
src = lastmatch = e;
}
if (e && e>src) /* non empty match? */
src = e; /* skip it */
else if (src < ms.src_end)
else if (src < ms.src_end) /* otherwise, skip one character */
luaL_addchar(&b, *src++);
else break;
else break; /* end of subject */
if (anchor) break;
}
luaL_addlstring(&b, src, ms.src_end-src);
@@ -830,7 +813,6 @@ static int str_gsub (lua_State *L) {
** Hexadecimal floating-point formatter
*/
#include <locale.h>
#include <math.h>
#define SIZELENMOD (sizeof(LUA_NUMBER_FRMLEN)/sizeof(char))
@@ -857,11 +839,12 @@ static lua_Number adddigit (char *buff, int n, lua_Number x) {
static int num2straux (char *buff, int sz, lua_Number x) {
if (x != x || x == HUGE_VAL || x == -HUGE_VAL) /* inf or NaN? */
return l_sprintf(buff, sz, LUA_NUMBER_FMT, x); /* equal to '%g' */
/* if 'inf' or 'NaN', format it like '%g' */
if (x != x || x == (lua_Number)HUGE_VAL || x == -(lua_Number)HUGE_VAL)
return l_sprintf(buff, sz, LUA_NUMBER_FMT, (LUAI_UACNUMBER)x);
else if (x == 0) { /* can be -0... */
/* create "0" or "-0" followed by exponent */
return l_sprintf(buff, sz, LUA_NUMBER_FMT "x0p+0", x);
return l_sprintf(buff, sz, LUA_NUMBER_FMT "x0p+0", (LUAI_UACNUMBER)x);
}
else {
int e;
@@ -896,7 +879,7 @@ static int lua_number2strx (lua_State *L, char *buff, int sz,
buff[i] = toupper(uchar(buff[i]));
}
else if (fmt[SIZELENMOD] != 'a')
luaL_error(L, "modifiers for format '%%a'/'%%A' not implemented");
return luaL_error(L, "modifiers for format '%%a'/'%%A' not implemented");
return n;
}
@@ -922,16 +905,14 @@ static int lua_number2strx (lua_State *L, char *buff, int sz,
#define MAX_FORMAT 32
static void addquoted (lua_State *L, luaL_Buffer *b, int arg) {
size_t l;
const char *s = luaL_checklstring(L, arg, &l);
static void addquoted (luaL_Buffer *b, const char *s, size_t len) {
luaL_addchar(b, '"');
while (l--) {
while (len--) {
if (*s == '"' || *s == '\\' || *s == '\n') {
luaL_addchar(b, '\\');
luaL_addchar(b, *s);
}
else if (*s == '\0' || iscntrl(uchar(*s))) {
else if (iscntrl(uchar(*s))) {
char buff[10];
if (!isdigit(uchar(*(s+1))))
l_sprintf(buff, sizeof(buff), "\\%d", (int)uchar(*s));
@@ -946,6 +927,57 @@ static void addquoted (lua_State *L, luaL_Buffer *b, int arg) {
luaL_addchar(b, '"');
}
/*
** Ensures the 'buff' string uses a dot as the radix character.
*/
static void checkdp (char *buff, int nb) {
if (memchr(buff, '.', nb) == NULL) { /* no dot? */
char point = lua_getlocaledecpoint(); /* try locale point */
char *ppoint = (char *)memchr(buff, point, nb);
if (ppoint) *ppoint = '.'; /* change it to a dot */
}
}
static void addliteral (lua_State *L, luaL_Buffer *b, int arg) {
switch (lua_type(L, arg)) {
case LUA_TSTRING: {
size_t len;
const char *s = lua_tolstring(L, arg, &len);
addquoted(b, s, len);
break;
}
case LUA_TNUMBER: {
char *buff = luaL_prepbuffsize(b, MAX_ITEM);
int nb;
if (!lua_isinteger(L, arg)) { /* float? */
lua_Number n = lua_tonumber(L, arg); /* write as hexa ('%a') */
nb = lua_number2strx(L, buff, MAX_ITEM, "%" LUA_NUMBER_FRMLEN "a", n);
checkdp(buff, nb); /* ensure it uses a dot */
}
else { /* integers */
lua_Integer n = lua_tointeger(L, arg);
const char *format = (n == LUA_MININTEGER) /* corner case? */
? "0x%" LUA_INTEGER_FRMLEN "x" /* use hexa */
: LUA_INTEGER_FMT; /* else use default format */
nb = l_sprintf(buff, MAX_ITEM, format, (LUAI_UACINT)n);
}
luaL_addsize(b, nb);
break;
}
case LUA_TNIL: case LUA_TBOOLEAN: {
luaL_tolstring(L, arg, NULL);
luaL_addvalue(b);
break;
}
default: {
luaL_argerror(L, arg, "value has no literal form");
}
}
}
static const char *scanformat (lua_State *L, const char *strfrmt, char *form) {
const char *p = strfrmt;
while (*p != '\0' && strchr(FLAGS, *p) != NULL) p++; /* skip flags */
@@ -1010,7 +1042,7 @@ static int str_format (lua_State *L) {
case 'o': case 'u': case 'x': case 'X': {
lua_Integer n = luaL_checkinteger(L, arg);
addlenmod(form, LUA_INTEGER_FRMLEN);
nb = l_sprintf(buff, MAX_ITEM, form, n);
nb = l_sprintf(buff, MAX_ITEM, form, (LUAI_UACINT)n);
break;
}
case 'a': case 'A':
@@ -1020,12 +1052,13 @@ static int str_format (lua_State *L) {
break;
case 'e': case 'E': case 'f':
case 'g': case 'G': {
lua_Number n = luaL_checknumber(L, arg);
addlenmod(form, LUA_NUMBER_FRMLEN);
nb = l_sprintf(buff, MAX_ITEM, form, luaL_checknumber(L, arg));
nb = l_sprintf(buff, MAX_ITEM, form, (LUAI_UACNUMBER)n);
break;
}
case 'q': {
addquoted(L, &b, arg);
addliteral(L, &b, arg);
break;
}
case 's': {
@@ -1070,8 +1103,8 @@ static int str_format (lua_State *L) {
/* value used for padding */
#if !defined(LUA_PACKPADBYTE)
#define LUA_PACKPADBYTE 0x00
#if !defined(LUAL_PACKPADBYTE)
#define LUAL_PACKPADBYTE 0x00
#endif
/* maximum size for the binary representation of an integer */
@@ -1166,8 +1199,8 @@ static int getnum (const char **fmt, int df) {
static int getnumlimit (Header *h, const char **fmt, int df) {
int sz = getnum(fmt, df);
if (sz > MAXINTSIZE || sz <= 0)
luaL_error(h->L, "integral size (%d) out of limits [1,%d]",
sz, MAXINTSIZE);
return luaL_error(h->L, "integral size (%d) out of limits [1,%d]",
sz, MAXINTSIZE);
return sz;
}
@@ -1228,7 +1261,7 @@ static KOption getoption (Header *h, const char **fmt, int *size) {
** 'psize' is filled with option's size, 'notoalign' with its
** alignment requirements.
** Local variable 'size' gets the size to be aligned. (Kpadal option
** always gets its full alignment, other options are limited by
** always gets its full alignment, other options are limited by
** the maximum alignment ('maxalign'). Kchar option needs no alignment
** despite its size.
*/
@@ -1308,7 +1341,7 @@ static int str_pack (lua_State *L) {
KOption opt = getdetails(&h, totalsize, &fmt, &size, &ntoalign);
totalsize += ntoalign + size;
while (ntoalign-- > 0)
luaL_addchar(&b, LUA_PACKPADBYTE); /* fill alignment */
luaL_addchar(&b, LUAL_PACKPADBYTE); /* fill alignment */
arg++;
switch (opt) {
case Kint: { /* signed integers */
@@ -1343,13 +1376,11 @@ static int str_pack (lua_State *L) {
case Kchar: { /* fixed-size string */
size_t len;
const char *s = luaL_checklstring(L, arg, &len);
if ((size_t)size <= len) /* string larger than (or equal to) needed? */
luaL_addlstring(&b, s, size); /* truncate string to asked size */
else { /* string smaller than needed */
luaL_addlstring(&b, s, len); /* add it all */
while (len++ < (size_t)size) /* pad extra space */
luaL_addchar(&b, LUA_PACKPADBYTE);
}
luaL_argcheck(L, len <= (size_t)size, arg,
"string longer than given size");
luaL_addlstring(&b, s, len); /* add string */
while (len++ < (size_t)size) /* pad extra space */
luaL_addchar(&b, LUAL_PACKPADBYTE);
break;
}
case Kstring: { /* strings with length count */
@@ -1372,7 +1403,7 @@ static int str_pack (lua_State *L) {
totalsize += len + 1;
break;
}
case Kpadding: luaL_addchar(&b, LUA_PACKPADBYTE); /* FALLTHROUGH */
case Kpadding: luaL_addchar(&b, LUAL_PACKPADBYTE); /* FALLTHROUGH */
case Kpaddalign: case Knop:
arg--; /* undo increment */
break;

View File

@@ -1,5 +1,5 @@
/*
** $Id: ltable.c,v 2.117 2015/11/19 19:16:22 roberto Exp $
** $Id: ltable.c,v 2.118.1.4 2018/06/08 16:22:51 roberto Exp $
** Lua tables (hash)
** See Copyright Notice in lua.h
*/
@@ -74,8 +74,6 @@
#define dummynode (&dummynode_)
#define isdummy(n) ((n) == dummynode)
static const Node dummynode_ = {
{NILCONSTANT}, /* value */
{{NILCONSTANT, 0}} /* key */
@@ -225,7 +223,9 @@ static unsigned int computesizes (unsigned int nums[], unsigned int *pna) {
unsigned int na = 0; /* number of elements to go to array part */
unsigned int optimal = 0; /* optimal size for array part */
/* loop while keys can fill more than half of total size */
for (i = 0, twotoi = 1; *pna > twotoi / 2; i++, twotoi *= 2) {
for (i = 0, twotoi = 1;
twotoi > 0 && *pna > twotoi / 2;
i++, twotoi *= 2) {
if (nums[i] > 0) {
a += nums[i];
if (a > twotoi/2) { /* more than half elements present? */
@@ -308,14 +308,14 @@ static void setarrayvector (lua_State *L, Table *t, unsigned int size) {
static void setnodevector (lua_State *L, Table *t, unsigned int size) {
int lsize;
if (size == 0) { /* no elements to hash part? */
t->node = cast(Node *, dummynode); /* use common 'dummynode' */
lsize = 0;
t->lsizenode = 0;
t->lastfree = NULL; /* signal that it is using dummy node */
}
else {
int i;
lsize = luaO_ceillog2(size);
int lsize = luaO_ceillog2(size);
if (lsize > MAXHBITS)
luaG_runerror(L, "table overflow");
size = twoto(lsize);
@@ -326,9 +326,21 @@ static void setnodevector (lua_State *L, Table *t, unsigned int size) {
setnilvalue(wgkey(n));
setnilvalue(gval(n));
}
t->lsizenode = cast_byte(lsize);
t->lastfree = gnode(t, size); /* all positions are free */
}
t->lsizenode = cast_byte(lsize);
t->lastfree = gnode(t, size); /* all positions are free */
}
typedef struct {
Table *t;
unsigned int nhsize;
} AuxsetnodeT;
static void auxsetnode (lua_State *L, void *ud) {
AuxsetnodeT *asn = cast(AuxsetnodeT *, ud);
setnodevector(L, asn->t, asn->nhsize);
}
@@ -336,13 +348,18 @@ void luaH_resize (lua_State *L, Table *t, unsigned int nasize,
unsigned int nhsize) {
unsigned int i;
int j;
AuxsetnodeT asn;
unsigned int oldasize = t->sizearray;
int oldhsize = t->lsizenode;
int oldhsize = allocsizenode(t);
Node *nold = t->node; /* save old hash ... */
if (nasize > oldasize) /* array part must grow? */
setarrayvector(L, t, nasize);
/* create new hash part with appropriate size */
setnodevector(L, t, nhsize);
asn.t = t; asn.nhsize = nhsize;
if (luaD_rawrunprotected(L, auxsetnode, &asn) != LUA_OK) { /* mem. error? */
setarrayvector(L, t, oldasize); /* array back to its original size */
luaD_throw(L, LUA_ERRMEM); /* rethrow memory error */
}
if (nasize < oldasize) { /* array part must shrink? */
t->sizearray = nasize;
/* re-insert elements from vanishing slice */
@@ -354,7 +371,7 @@ void luaH_resize (lua_State *L, Table *t, unsigned int nasize,
luaM_reallocvector(L, t->array, oldasize, nasize, TValue);
}
/* re-insert elements from hash part */
for (j = twoto(oldhsize) - 1; j >= 0; j--) {
for (j = oldhsize - 1; j >= 0; j--) {
Node *old = nold + j;
if (!ttisnil(gval(old))) {
/* doesn't need barrier/invalidate cache, as entry was
@@ -362,13 +379,13 @@ void luaH_resize (lua_State *L, Table *t, unsigned int nasize,
setobjt2t(L, luaH_set(L, t, gkey(old)), gval(old));
}
}
if (!isdummy(nold))
luaM_freearray(L, nold, cast(size_t, twoto(oldhsize))); /* free old hash */
if (oldhsize > 0) /* not the dummy node? */
luaM_freearray(L, nold, cast(size_t, oldhsize)); /* free old hash */
}
void luaH_resizearray (lua_State *L, Table *t, unsigned int nasize) {
int nsize = isdummy(t->node) ? 0 : sizenode(t);
int nsize = allocsizenode(t);
luaH_resize(L, t, nasize, nsize);
}
@@ -414,7 +431,7 @@ Table *luaH_new (lua_State *L) {
void luaH_free (lua_State *L, Table *t) {
if (!isdummy(t->node))
if (!isdummy(t))
luaM_freearray(L, t->node, cast(size_t, sizenode(t)));
luaM_freearray(L, t->array, t->sizearray);
luaM_free(L, t);
@@ -422,10 +439,12 @@ void luaH_free (lua_State *L, Table *t) {
static Node *getfreepos (Table *t) {
while (t->lastfree > t->node) {
t->lastfree--;
if (ttisnil(gkey(t->lastfree)))
return t->lastfree;
if (!isdummy(t)) {
while (t->lastfree > t->node) {
t->lastfree--;
if (ttisnil(gkey(t->lastfree)))
return t->lastfree;
}
}
return NULL; /* could not find a free place */
}
@@ -445,7 +464,7 @@ TValue *luaH_newkey (lua_State *L, Table *t, const TValue *key) {
if (ttisnil(key)) luaG_runerror(L, "table index is nil");
else if (ttisfloat(key)) {
lua_Integer k;
if (luaV_tointeger(key, &k, 0)) { /* index is int? */
if (luaV_tointeger(key, &k, 0)) { /* does index fit in an integer? */
setivalue(&aux, k);
key = &aux; /* insert it as an integer */
}
@@ -453,7 +472,7 @@ TValue *luaH_newkey (lua_State *L, Table *t, const TValue *key) {
luaG_runerror(L, "table index is NaN");
}
mp = mainposition(t, key);
if (!ttisnil(gval(mp)) || isdummy(mp)) { /* main position is taken? */
if (!ttisnil(gval(mp)) || isdummy(t)) { /* main position is taken? */
Node *othern;
Node *f = getfreepos(t); /* get a free place */
if (f == NULL) { /* cannot find a free place? */
@@ -461,7 +480,7 @@ TValue *luaH_newkey (lua_State *L, Table *t, const TValue *key) {
/* whatever called 'newkey' takes care of TM cache */
return luaH_set(L, t, key); /* insert key into grown table */
}
lua_assert(!isdummy(f));
lua_assert(!isdummy(t));
othern = mainposition(t, gkey(mp));
if (othern != mp) { /* is colliding node out of its main position? */
/* yes; move colliding node into free position */
@@ -610,13 +629,13 @@ void luaH_setint (lua_State *L, Table *t, lua_Integer key, TValue *value) {
}
static int unbound_search (Table *t, unsigned int j) {
unsigned int i = j; /* i is zero or a present index */
static lua_Unsigned unbound_search (Table *t, lua_Unsigned j) {
lua_Unsigned i = j; /* i is zero or a present index */
j++;
/* find 'i' and 'j' such that i is present and j is not */
while (!ttisnil(luaH_getint(t, j))) {
i = j;
if (j > cast(unsigned int, MAX_INT)/2) { /* overflow? */
if (j > l_castS2U(LUA_MAXINTEGER) / 2) { /* overflow? */
/* table was built with bad purposes: resort to linear search */
i = 1;
while (!ttisnil(luaH_getint(t, i))) i++;
@@ -626,7 +645,7 @@ static int unbound_search (Table *t, unsigned int j) {
}
/* now do a binary search between them */
while (j - i > 1) {
unsigned int m = (i+j)/2;
lua_Unsigned m = (i+j)/2;
if (ttisnil(luaH_getint(t, m))) j = m;
else i = m;
}
@@ -638,7 +657,7 @@ static int unbound_search (Table *t, unsigned int j) {
** Try to find a boundary in table 't'. A 'boundary' is an integer index
** such that t[i] is non-nil and t[i+1] is nil (and 0 if t[1] is nil).
*/
int luaH_getn (Table *t) {
lua_Unsigned luaH_getn (Table *t) {
unsigned int j = t->sizearray;
if (j > 0 && ttisnil(&t->array[j - 1])) {
/* there is a boundary in the array part: (binary) search for it */
@@ -651,7 +670,7 @@ int luaH_getn (Table *t) {
return i;
}
/* else must find a boundary in hash part */
else if (isdummy(t->node)) /* hash part is empty? */
else if (isdummy(t)) /* hash part is empty? */
return j; /* that is easy... */
else return unbound_search(t, j);
}
@@ -664,6 +683,6 @@ Node *luaH_mainposition (const Table *t, const TValue *key) {
return mainposition(t, key);
}
int luaH_isdummy (Node *n) { return isdummy(n); }
int luaH_isdummy (const Table *t) { return isdummy(t); }
#endif

View File

@@ -1,5 +1,5 @@
/*
** $Id: ltable.h,v 2.21 2015/11/03 15:47:30 roberto Exp $
** $Id: ltable.h,v 2.23.1.2 2018/05/24 19:39:05 roberto Exp $
** Lua tables (hash)
** See Copyright Notice in lua.h
*/
@@ -15,7 +15,7 @@
#define gnext(n) ((n)->i_key.nk.next)
/* 'const' to avoid wrong writings that can mess up field 'next' */
/* 'const' to avoid wrong writings that can mess up field 'next' */
#define gkey(n) cast(const TValue*, (&(n)->i_key.tvk))
/*
@@ -27,6 +27,14 @@
#define invalidateTMcache(t) ((t)->flags = 0)
/* true when 't' is using 'dummynode' as its hash part */
#define isdummy(t) ((t)->lastfree == NULL)
/* allocated size for hash nodes */
#define allocsizenode(t) (isdummy(t) ? 0 : sizenode(t))
/* returns the key, given the value of a table entry */
#define keyfromval(v) \
(gkey(cast(Node *, cast(char *, (v)) - offsetof(Node, i_val))))
@@ -46,12 +54,12 @@ LUAI_FUNC void luaH_resize (lua_State *L, Table *t, unsigned int nasize,
LUAI_FUNC void luaH_resizearray (lua_State *L, Table *t, unsigned int nasize);
LUAI_FUNC void luaH_free (lua_State *L, Table *t);
LUAI_FUNC int luaH_next (lua_State *L, Table *t, StkId key);
LUAI_FUNC int luaH_getn (Table *t);
LUAI_FUNC lua_Unsigned luaH_getn (Table *t);
#if defined(LUA_DEBUG)
LUAI_FUNC Node *luaH_mainposition (const Table *t, const TValue *key);
LUAI_FUNC int luaH_isdummy (Node *n);
LUAI_FUNC int luaH_isdummy (const Table *t);
#endif

View File

@@ -1,5 +1,5 @@
/*
** $Id: ltablib.c,v 1.90 2015/11/25 12:48:57 roberto Exp $
** $Id: ltablib.c,v 1.93.1.1 2017/04/19 17:20:42 roberto Exp $
** Library for Table Manipulation
** See Copyright Notice in lua.h
*/
@@ -53,7 +53,7 @@ static void checktab (lua_State *L, int arg, int what) {
lua_pop(L, n); /* pop metatable and tested metamethods */
}
else
luaL_argerror(L, arg, "table expected"); /* force an error */
luaL_checktype(L, arg, LUA_TTABLE); /* force an error */
}
}
@@ -139,7 +139,7 @@ static int tmove (lua_State *L) {
n = e - f + 1; /* number of elements to move */
luaL_argcheck(L, t <= LUA_MAXINTEGER - n + 1, 4,
"destination wrap around");
if (t > e || t <= f || tt != 1) {
if (t > e || t <= f || (tt != 1 && !lua_compare(L, 1, tt, LUA_OPEQ))) {
for (i = 0; i < n; i++) {
lua_geti(L, 1, f + i);
lua_seti(L, tt, t + i);
@@ -152,7 +152,7 @@ static int tmove (lua_State *L) {
}
}
}
lua_pushvalue(L, tt); /* return "to table" */
lua_pushvalue(L, tt); /* return destination table */
return 1;
}
@@ -172,7 +172,7 @@ static int tconcat (lua_State *L) {
size_t lsep;
const char *sep = luaL_optlstring(L, 2, "", &lsep);
lua_Integer i = luaL_optinteger(L, 3, 1);
last = luaL_opt(L, luaL_checkinteger, 4, last);
last = luaL_optinteger(L, 4, last);
luaL_buffinit(L, &b);
for (; i < last; i++) {
addfield(L, &b, i);
@@ -232,6 +232,10 @@ static int unpack (lua_State *L) {
*/
/* type for array indices */
typedef unsigned int IdxT;
/*
** Produce a "random" 'unsigned int' to randomize pivot choice. This
** macro is used only when 'sort' detects a big imbalance in the result
@@ -270,7 +274,7 @@ static unsigned int l_randomizePivot (void) {
#define RANLIMIT 100u
static void set2 (lua_State *L, unsigned int i, unsigned int j) {
static void set2 (lua_State *L, IdxT i, IdxT j) {
lua_seti(L, 1, i);
lua_seti(L, 1, j);
}
@@ -303,10 +307,9 @@ static int sort_comp (lua_State *L, int a, int b) {
** Pos-condition: a[lo .. i - 1] <= a[i] == P <= a[i + 1 .. up]
** returns 'i'.
*/
static unsigned int partition (lua_State *L, unsigned int lo,
unsigned int up) {
unsigned int i = lo; /* will be incremented before first use */
unsigned int j = up - 1; /* will be decremented before first use */
static IdxT partition (lua_State *L, IdxT lo, IdxT up) {
IdxT i = lo; /* will be incremented before first use */
IdxT j = up - 1; /* will be decremented before first use */
/* loop invariant: a[lo .. i] <= P <= a[j .. up] */
for (;;) {
/* next loop: repeat ++i while a[i] < P */
@@ -340,10 +343,9 @@ static unsigned int partition (lua_State *L, unsigned int lo,
** Choose an element in the middle (2nd-3th quarters) of [lo,up]
** "randomized" by 'rnd'
*/
static unsigned int choosePivot (unsigned int lo, unsigned int up,
unsigned int rnd) {
unsigned int r4 = (unsigned int)(up - lo) / 4u; /* range/4 */
unsigned int p = rnd % (r4 * 2) + (lo + r4);
static IdxT choosePivot (IdxT lo, IdxT up, unsigned int rnd) {
IdxT r4 = (up - lo) / 4; /* range/4 */
IdxT p = rnd % (r4 * 2) + (lo + r4);
lua_assert(lo + r4 <= p && p <= up - r4);
return p;
}
@@ -352,11 +354,11 @@ static unsigned int choosePivot (unsigned int lo, unsigned int up,
/*
** QuickSort algorithm (recursive function)
*/
static void auxsort (lua_State *L, unsigned int lo, unsigned int up,
static void auxsort (lua_State *L, IdxT lo, IdxT up,
unsigned int rnd) {
while (lo < up) { /* loop for tail recursion */
unsigned int p; /* Pivot index */
unsigned int n; /* to be used later */
IdxT p; /* Pivot index */
IdxT n; /* to be used later */
/* sort elements 'lo', 'p', and 'up' */
lua_geti(L, 1, lo);
lua_geti(L, 1, up);
@@ -400,7 +402,7 @@ static void auxsort (lua_State *L, unsigned int lo, unsigned int up,
n = up - p; /* size of smaller interval */
up = p - 1; /* tail call for [lo .. p - 1] (lower interval) */
}
if ((up - lo) / 128u > n) /* partition too imbalanced? */
if ((up - lo) / 128 > n) /* partition too imbalanced? */
rnd = l_randomizePivot(); /* try a new randomization */
} /* tail call auxsort(L, lo, up, rnd) */
}
@@ -410,11 +412,10 @@ static int sort (lua_State *L) {
lua_Integer n = aux_getn(L, 1, TAB_RW);
if (n > 1) { /* non-trivial interval? */
luaL_argcheck(L, n < INT_MAX, 1, "array too big");
luaL_checkstack(L, 40, ""); /* assume array is smaller than 2^40 */
if (!lua_isnoneornil(L, 2)) /* is there a 2nd argument? */
luaL_checktype(L, 2, LUA_TFUNCTION); /* must be a function */
lua_settop(L, 2); /* make sure there are two arguments */
auxsort(L, 1, (unsigned int)n, 0u);
auxsort(L, 1, (IdxT)n, 0);
}
return 0;
}

View File

@@ -1,5 +1,5 @@
/*
** $Id: ltm.c,v 2.36 2015/11/03 15:47:30 roberto Exp $
** $Id: ltm.c,v 2.38.1.1 2017/04/19 17:39:34 roberto Exp $
** Tag methods
** See Copyright Notice in lua.h
*/
@@ -15,7 +15,7 @@
#include "lua.h"
#include "ldebug.h"
#include "ldo.h"
#include "ldo.h"
#include "lobject.h"
#include "lstate.h"
#include "lstring.h"
@@ -83,6 +83,22 @@ const TValue *luaT_gettmbyobj (lua_State *L, const TValue *o, TMS event) {
}
/*
** Return the name of the type of an object. For tables and userdata
** with metatable, use their '__name' metafield, if present.
*/
const char *luaT_objtypename (lua_State *L, const TValue *o) {
Table *mt;
if ((ttistable(o) && (mt = hvalue(o)->metatable) != NULL) ||
(ttisfulluserdata(o) && (mt = uvalue(o)->metatable) != NULL)) {
const TValue *name = luaH_getshortstr(mt, luaS_new(L, "__name"));
if (ttisstring(name)) /* is '__name' a string? */
return getstr(tsvalue(name)); /* use it as type name */
}
return ttypename(ttnov(o)); /* else use standard type name */
}
void luaT_callTM (lua_State *L, const TValue *f, const TValue *p1,
const TValue *p2, TValue *p3, int hasres) {
ptrdiff_t result = savestack(L, p3);

View File

@@ -1,5 +1,5 @@
/*
** $Id: ltm.h,v 2.21 2014/10/25 11:50:46 roberto Exp $
** $Id: ltm.h,v 2.22.1.1 2017/04/19 17:20:42 roberto Exp $
** Tag methods
** See Copyright Notice in lua.h
*/
@@ -51,11 +51,12 @@ typedef enum {
#define fasttm(l,et,e) gfasttm(G(l), et, e)
#define ttypename(x) luaT_typenames_[(x) + 1]
#define objtypename(x) ttypename(ttnov(x))
LUAI_DDEC const char *const luaT_typenames_[LUA_TOTALTAGS];
LUAI_FUNC const char *luaT_objtypename (lua_State *L, const TValue *o);
LUAI_FUNC const TValue *luaT_gettm (Table *events, TMS event, TString *ename);
LUAI_FUNC const TValue *luaT_gettmbyobj (lua_State *L, const TValue *o,
TMS event);

View File

@@ -1,5 +1,5 @@
/*
** $Id: lua.c,v 1.226 2015/08/14 19:11:20 roberto Exp $
** $Id: lua.c,v 1.230.1.1 2017/04/19 17:29:57 roberto Exp $
** Lua stand-alone interpreter
** See Copyright Notice in lua.h
*/
@@ -21,6 +21,7 @@
#include "lstring.h"
#if !defined(LUA_PROMPT)
#define LUA_PROMPT "> "
#define LUA_PROMPT2 ">> "
@@ -38,8 +39,7 @@
#define LUA_INIT_VAR "LUA_INIT"
#endif
#define LUA_INITVARVERSION \
LUA_INIT_VAR "_" LUA_VERSION_MAJOR "_" LUA_VERSION_MINOR
#define LUA_INITVARVERSION LUA_INIT_VAR LUA_VERSUFFIX
/*
@@ -56,6 +56,8 @@
#elif defined(LUA_USE_WINDOWS) /* }{ */
#include <io.h>
#include <windows.h>
#define lua_stdin_is_tty() _isatty(_fileno(stdin))
#else /* }{ */
@@ -137,7 +139,7 @@ static void print_usage (const char *badoption) {
"Available options are:\n"
" -e stat execute string 'stat'\n"
" -i enter interactive mode after executing 'script'\n"
" -l name require library 'name'\n"
" -l name require library 'name' into global 'name'\n"
" -v show version information\n"
" -E ignore environment variables\n"
" -- stop handling options\n"
@@ -458,7 +460,7 @@ static int handle_script (lua_State *L, char **argv) {
/*
** Traverses all arguments from 'argv', returning a mask with those
** needed before running any Lua code (or an error code if it finds
** any invalid argument). 'first' returns the first not-handled argument
** any invalid argument). 'first' returns the first not-handled argument
** (either the script name or a bad argument in case of error).
*/
static int collectargs (char **argv, int *first) {
@@ -482,7 +484,7 @@ static int collectargs (char **argv, int *first) {
args |= has_E;
break;
case 'i':
args |= has_i; /* (-i implies -v) *//* FALLTHROUGH */
args |= has_i; /* (-i implies -v) *//* FALLTHROUGH */
case 'v':
if (argv[i][2] != '\0') /* extra characters after 1st? */
return has_error; /* invalid option */
@@ -530,6 +532,7 @@ static int runargs (lua_State *L, char **argv, int n) {
}
static int handle_luainit (lua_State *L) {
const char *name = "=" LUA_INITVARVERSION;
const char *init = getenv(name + 1);

View File

@@ -1,5 +1,5 @@
/*
** $Id: lua.h,v 1.329 2015/11/13 17:18:42 roberto Exp $
** $Id: lua.h,v 1.332.1.2 2018/06/13 16:58:17 roberto Exp $
** Lua - A Scripting Language
** Lua.org, PUC-Rio, Brazil (http://www.lua.org)
** See Copyright Notice at the end of this file
@@ -19,11 +19,11 @@
#define LUA_VERSION_MAJOR "5"
#define LUA_VERSION_MINOR "3"
#define LUA_VERSION_NUM 503
#define LUA_VERSION_RELEASE "2"
#define LUA_VERSION_RELEASE "5"
#define LUA_VERSION "Lua " LUA_VERSION_MAJOR "." LUA_VERSION_MINOR
#define LUA_RELEASE LUA_VERSION "." LUA_VERSION_RELEASE
#define LUA_COPYRIGHT LUA_RELEASE " Copyright (C) 1994-2015 Lua.org, PUC-Rio"
#define LUA_COPYRIGHT LUA_RELEASE " Copyright (C) 1994-2018 Lua.org, PUC-Rio"
#define LUA_AUTHORS "R. Ierusalimschy, L. H. de Figueiredo, W. Celes"
@@ -363,7 +363,7 @@ LUA_API void (lua_setallocf) (lua_State *L, lua_Alloc f, void *ud);
#define lua_pushliteral(L, s) lua_pushstring(L, "" s)
#define lua_pushglobaltable(L) \
lua_rawgeti(L, LUA_REGISTRYINDEX, LUA_RIDX_GLOBALS)
((void)lua_rawgeti(L, LUA_REGISTRYINDEX, LUA_RIDX_GLOBALS))
#define lua_tostring(L,i) lua_tolstring(L, (i), NULL)
@@ -467,7 +467,7 @@ LUA_API void (lua_checksig_)(lua_State *L);
#define lua_checksig(L) if (skynet_sig_L) { lua_checksig_(L); }
/******************************************************************************
* Copyright (C) 1994-2015 Lua.org, PUC-Rio.
* Copyright (C) 1994-2018 Lua.org, PUC-Rio.
*
* Permission is hereby granted, free of charge, to any person obtaining
* a copy of this software and associated documentation files (the

View File

@@ -1,5 +1,5 @@
/*
** $Id: luac.c,v 1.75 2015/03/12 01:58:27 lhf Exp $
** $Id: luac.c,v 1.76 2018/06/19 01:32:02 lhf Exp $
** Lua compiler (saves bytecodes to files; also lists bytecodes)
** See Copyright Notice in lua.h
*/
@@ -208,7 +208,7 @@ int main(int argc, char* argv[])
}
/*
** $Id: luac.c,v 1.75 2015/03/12 01:58:27 lhf Exp $
** $Id: luac.c,v 1.76 2018/06/19 01:32:02 lhf Exp $
** print bytecodes
** See Copyright Notice in lua.h
*/
@@ -350,6 +350,7 @@ static void PrintCode(const Proto* f)
case OP_ADD:
case OP_SUB:
case OP_MUL:
case OP_MOD:
case OP_POW:
case OP_DIV:
case OP_IDIV:

View File

@@ -1,5 +1,5 @@
/*
** $Id: luaconf.h,v 1.254 2015/10/21 18:17:40 roberto Exp $
** $Id: luaconf.h,v 1.259.1.1 2017/04/19 17:29:57 roberto Exp $
** Configuration file for Lua
** See Copyright Notice in lua.h
*/
@@ -158,6 +158,18 @@
** ===================================================================
*/
/*
** LUA_PATH_SEP is the character that separates templates in a path.
** LUA_PATH_MARK is the string that marks the substitution points in a
** template.
** LUA_EXEC_DIR in a Windows path is replaced by the executable's
** directory.
*/
#define LUA_PATH_SEP ";"
#define LUA_PATH_MARK "?"
#define LUA_EXEC_DIR "!"
/*
@@ LUA_PATH_DEFAULT is the default path that Lua uses to look for
** Lua libraries.
@@ -404,7 +416,7 @@
/*
@@ LUA_NUMBER is the floating-point type used by Lua.
@@ LUAI_UACNUMBER is the result of an 'usual argument conversion'
@@ LUAI_UACNUMBER is the result of a 'default argument promotion'
@@ over a floating number.
@@ l_mathlim(x) corrects limit name 'x' to the proper float type
** by prefixing it with one of FLT/DBL/LDBL.
@@ -421,7 +433,8 @@
#define l_floor(x) (l_mathop(floor)(x))
#define lua_number2str(s,sz,n) l_sprintf((s), sz, LUA_NUMBER_FMT, (n))
#define lua_number2str(s,sz,n) \
l_sprintf((s), sz, LUA_NUMBER_FMT, (LUAI_UACNUMBER)(n))
/*
@@ lua_numbertointeger converts a float number to an integer, or
@@ -498,7 +511,7 @@
**
@@ LUA_UNSIGNED is the unsigned version of LUA_INTEGER.
**
@@ LUAI_UACINT is the result of an 'usual argument conversion'
@@ LUAI_UACINT is the result of a 'default argument promotion'
@@ over a lUA_INTEGER.
@@ LUA_INTEGER_FRMLEN is the length modifier for reading/writing integers.
@@ LUA_INTEGER_FMT is the format for writing integers.
@@ -511,10 +524,12 @@
/* The following definitions are good for most cases here */
#define LUA_INTEGER_FMT "%" LUA_INTEGER_FRMLEN "d"
#define lua_integer2str(s,sz,n) l_sprintf((s), sz, LUA_INTEGER_FMT, (n))
#define LUAI_UACINT LUA_INTEGER
#define lua_integer2str(s,sz,n) \
l_sprintf((s), sz, LUA_INTEGER_FMT, (LUAI_UACINT)(n))
/*
** use LUAI_UACINT here to avoid problems with promotions (which
** can turn a comparison between unsigneds into a signed comparison)
@@ -606,13 +621,21 @@
/*
@@ lua_number2strx converts a float to an hexadecimal numeric string.
@@ lua_pointer2str converts a pointer to a readable string in a
** non-specified way.
*/
#define lua_pointer2str(buff,sz,p) l_sprintf(buff,sz,"%p",p)
/*
@@ lua_number2strx converts a float to an hexadecimal numeric string.
** In C99, 'sprintf' (with format specifiers '%a'/'%A') does that.
** Otherwise, you can leave 'lua_number2strx' undefined and Lua will
** provide its own implementation.
*/
#if !defined(LUA_USE_C89)
#define lua_number2strx(L,b,sz,f,n) l_sprintf(b,sz,f,n)
#define lua_number2strx(L,b,sz,f,n) \
((void)L, l_sprintf(b,sz,f,(LUAI_UACNUMBER)(n)))
#endif
@@ -728,11 +751,11 @@
/*
@@ LUAL_BUFFERSIZE is the buffer size used by the lauxlib buffer system.
** CHANGE it if it uses too much C-stack space. (For long double,
** 'string.format("%.99f", 1e4932)' needs ~5030 bytes, so a
** 'string.format("%.99f", -1e4932)' needs 5034 bytes, so a
** smaller buffer would force a memory allocation for each call to
** 'string.format'.)
*/
#if defined(LUA_FLOAT_LONGDOUBLE)
#if LUA_FLOAT_TYPE == LUA_FLOAT_LONGDOUBLE
#define LUAL_BUFFERSIZE 8192
#else
#define LUAL_BUFFERSIZE ((int)(0x80 * sizeof(void*) * sizeof(lua_Integer)))

View File

@@ -1,5 +1,5 @@
/*
** $Id: lualib.h,v 1.44 2014/02/06 17:32:33 roberto Exp $
** $Id: lualib.h,v 1.45.1.1 2017/04/19 17:20:42 roberto Exp $
** Lua standard libraries
** See Copyright Notice in lua.h
*/
@@ -11,6 +11,9 @@
#include "lua.h"
/* version suffix for environment variable names */
#define LUA_VERSUFFIX "_" LUA_VERSION_MAJOR "_" LUA_VERSION_MINOR
LUAMOD_API int (luaopen_base) (lua_State *L);

View File

@@ -1,5 +1,5 @@
/*
** $Id: lundump.c,v 2.44 2015/11/02 16:09:30 roberto Exp $
** $Id: lundump.c,v 2.44.1.1 2017/04/19 17:20:42 roberto Exp $
** load precompiled Lua chunks
** See Copyright Notice in lua.h
*/
@@ -273,7 +273,7 @@ LClosure *luaU_undump(lua_State *L, ZIO *Z, const char *name) {
luaD_inctop(L);
cl->p = luaF_newproto(L, NULL);
LoadFunction(&S, cl->p, NULL);
lua_assert(cl->nupvalues == cl->p->sizeupvalues);
lua_assert(cl->nupvalues == cl->p->sp->sizeupvalues);
luai_verifycode(L, buff, cl->p);
return cl;
}

View File

@@ -1,5 +1,5 @@
/*
** $Id: lundump.h,v 1.45 2015/09/08 15:41:05 roberto Exp $
** $Id: lundump.h,v 1.45.1.1 2017/04/19 17:20:42 roberto Exp $
** load precompiled Lua chunks
** See Copyright Notice in lua.h
*/

View File

@@ -1,5 +1,5 @@
/*
** $Id: lutf8lib.c,v 1.15 2015/03/28 19:16:55 roberto Exp $
** $Id: lutf8lib.c,v 1.16.1.1 2017/04/19 17:29:57 roberto Exp $
** Standard library for UTF-8 manipulation
** See Copyright Notice in lua.h
*/
@@ -171,7 +171,7 @@ static int byteoffset (lua_State *L) {
}
else {
if (iscont(s + posi))
luaL_error(L, "initial position is a continuation byte");
return luaL_error(L, "initial position is a continuation byte");
if (n < 0) {
while (n < 0 && posi > 0) { /* move back */
do { /* find beginning of previous character */
@@ -194,7 +194,7 @@ static int byteoffset (lua_State *L) {
lua_pushinteger(L, posi + 1);
else /* no such character */
lua_pushnil(L);
return 1;
return 1;
}

View File

@@ -1,5 +1,5 @@
/*
** $Id: lvm.c,v 2.265 2015/11/23 11:30:45 roberto Exp $
** $Id: lvm.c,v 2.268.1.1 2017/04/19 17:39:34 roberto Exp $
** Lua virtual machine
** See Copyright Notice in lua.h
*/
@@ -163,55 +163,69 @@ static int forlimit (const TValue *obj, lua_Integer *p, lua_Integer step,
/*
** Complete a table access: if 't' is a table, 'tm' has its metamethod;
** otherwise, 'tm' is NULL.
** Finish the table access 'val = t[key]'.
** if 'slot' is NULL, 't' is not a table; otherwise, 'slot' points to
** t[k] entry (which must be nil).
*/
void luaV_finishget (lua_State *L, const TValue *t, TValue *key, StkId val,
const TValue *tm) {
const TValue *slot) {
int loop; /* counter to avoid infinite loops */
lua_assert(tm != NULL || !ttistable(t));
const TValue *tm; /* metamethod */
for (loop = 0; loop < MAXTAGLOOP; loop++) {
if (tm == NULL) { /* no metamethod (from a table)? */
if (ttisnil(tm = luaT_gettmbyobj(L, t, TM_INDEX)))
if (slot == NULL) { /* 't' is not a table? */
lua_assert(!ttistable(t));
tm = luaT_gettmbyobj(L, t, TM_INDEX);
if (ttisnil(tm))
luaG_typeerror(L, t, "index"); /* no metamethod */
/* else will try the metamethod */
}
if (ttisfunction(tm)) { /* metamethod is a function */
else { /* 't' is a table */
lua_assert(ttisnil(slot));
tm = fasttm(L, hvalue(t)->metatable, TM_INDEX); /* table's metamethod */
if (tm == NULL) { /* no metamethod? */
setnilvalue(val); /* result is nil */
return;
}
/* else will try the metamethod */
}
if (ttisfunction(tm)) { /* is metamethod a function? */
luaT_callTM(L, tm, t, key, val, 1); /* call it */
return;
}
t = tm; /* else repeat access over 'tm' */
if (luaV_fastget(L,t,key,tm,luaH_get)) { /* try fast track */
setobj2s(L, val, tm); /* done */
t = tm; /* else try to access 'tm[key]' */
if (luaV_fastget(L,t,key,slot,luaH_get)) { /* fast track? */
setobj2s(L, val, slot); /* done */
return;
}
/* else repeat */
/* else repeat (tail call 'luaV_finishget') */
}
luaG_runerror(L, "gettable chain too long; possible loop");
luaG_runerror(L, "'__index' chain too long; possible loop");
}
/*
** Main function for table assignment (invoking metamethods if needed).
** Compute 't[key] = val'
** Finish a table assignment 't[key] = val'.
** If 'slot' is NULL, 't' is not a table. Otherwise, 'slot' points
** to the entry 't[key]', or to 'luaO_nilobject' if there is no such
** entry. (The value at 'slot' must be nil, otherwise 'luaV_fastset'
** would have done the job.)
*/
void luaV_finishset (lua_State *L, const TValue *t, TValue *key,
StkId val, const TValue *oldval) {
StkId val, const TValue *slot) {
int loop; /* counter to avoid infinite loops */
for (loop = 0; loop < MAXTAGLOOP; loop++) {
const TValue *tm;
if (oldval != NULL) {
lua_assert(ttistable(t) && ttisnil(oldval));
/* must check the metamethod */
if ((tm = fasttm(L, hvalue(t)->metatable, TM_NEWINDEX)) == NULL &&
/* no metamethod; is there a previous entry in the table? */
(oldval != luaO_nilobject ||
/* no previous entry; must create one. (The next test is
always true; we only need the assignment.) */
(oldval = luaH_newkey(L, hvalue(t), key), 1))) {
const TValue *tm; /* '__newindex' metamethod */
if (slot != NULL) { /* is 't' a table? */
Table *h = hvalue(t); /* save 't' table */
lua_assert(ttisnil(slot)); /* old value must be nil */
tm = fasttm(L, h->metatable, TM_NEWINDEX); /* get metamethod */
if (tm == NULL) { /* no metamethod? */
if (slot == luaO_nilobject) /* no previous entry? */
slot = luaH_newkey(L, h, key); /* create one */
/* no metamethod and (now) there is an entry with given key */
setobj2t(L, cast(TValue *, oldval), val);
invalidateTMcache(hvalue(t));
luaC_barrierback(L, hvalue(t), val);
setobj2t(L, cast(TValue *, slot), val); /* set its new value */
invalidateTMcache(h);
luaC_barrierback(L, h, val);
return;
}
/* else will try the metamethod */
@@ -226,11 +240,11 @@ void luaV_finishset (lua_State *L, const TValue *t, TValue *key,
return;
}
t = tm; /* else repeat assignment over 'tm' */
if (luaV_fastset(L, t, key, oldval, luaH_get, val))
if (luaV_fastset(L, t, key, slot, luaH_get, val))
return; /* done */
/* else loop */
}
luaG_runerror(L, "settable chain too long; possible loop");
luaG_runerror(L, "'__newindex' chain too long; possible loop");
}
@@ -748,18 +762,28 @@ void luaV_finishOp (lua_State *L) {
luai_threadyield(L); }
/* fetch an instruction and prepare its execution */
#define vmfetch() { \
i = *(ci->u.l.savedpc++); \
if (L->hookmask & (LUA_MASKLINE | LUA_MASKCOUNT)) \
Protect(luaG_traceexec(L)); \
ra = RA(i); /* WARNING: any stack reallocation invalidates 'ra' */ \
lua_assert(base == ci->u.l.base); \
lua_assert(base <= L->top && L->top < L->stack + L->stacksize); \
}
#define vmdispatch(o) switch(o)
#define vmcase(l) case l:
#define vmbreak break
/*
** copy of 'luaV_gettable', but protecting call to potential metamethod
** (which can reallocate the stack)
** copy of 'luaV_gettable', but protecting the call to potential
** metamethod (which can reallocate the stack)
*/
#define gettableProtected(L,t,k,v) { const TValue *aux; \
if (luaV_fastget(L,t,k,aux,luaH_get)) { setobj2s(L, v, aux); } \
else Protect(luaV_finishget(L,t,k,v,aux)); }
#define gettableProtected(L,t,k,v) { const TValue *slot; \
if (luaV_fastget(L,t,k,slot,luaH_get)) { setobj2s(L, v, slot); } \
else Protect(luaV_finishget(L,t,k,v,slot)); }
/* same for 'luaV_settable' */
@@ -782,14 +806,9 @@ void luaV_execute (lua_State *L) {
base = ci->u.l.base; /* local copy of function's base */
/* main loop of interpreter */
for (;;) {
Instruction i = *(ci->u.l.savedpc++);
Instruction i;
StkId ra;
if (L->hookmask & (LUA_MASKLINE | LUA_MASKCOUNT))
Protect(luaG_traceexec(L));
/* WARNING: several calls may realloc the stack and invalidate 'ra' */
ra = RA(i);
lua_assert(base == ci->u.l.base);
lua_assert(base <= L->top && L->top < L->stack + L->stacksize);
vmfetch();
vmdispatch (GET_OPCODE(i)) {
vmcase(OP_MOVE) {
setobjs2s(L, ra, RB(i));
@@ -1162,7 +1181,7 @@ void luaV_execute (lua_State *L) {
oci->u.l.savedpc = nci->u.l.savedpc;
oci->callstatus |= CIST_TAIL; /* function was tail called */
ci = L->ci = oci; /* remove new frame */
lua_assert(L->top == oci->u.l.base + getproto(ofunc)->maxstacksize);
lua_assert(L->top == oci->u.l.base + getproto(ofunc)->sp->maxstacksize);
goto newframe; /* restart luaV_execute over new Lua function */
}
vmbreak;
@@ -1182,6 +1201,7 @@ void luaV_execute (lua_State *L) {
}
}
vmcase(OP_FORLOOP) {
lua_checksig(L);
if (ttisinteger(ra)) { /* integer loop? */
lua_Integer step = ivalue(ra + 2);
lua_Integer idx = intop(+, ivalue(ra), step); /* increment index */

View File

@@ -1,5 +1,5 @@
/*
** $Id: lvm.h,v 2.39 2015/09/09 13:44:07 roberto Exp $
** $Id: lvm.h,v 2.41.1.1 2017/04/19 17:20:42 roberto Exp $
** Lua virtual machine
** See Copyright Notice in lua.h
*/
@@ -49,25 +49,24 @@
/*
** fast track for 'gettable': 1 means 'aux' points to resulted value;
** 0 means 'aux' is metamethod (if 't' is a table) or NULL. 'f' is
** the raw get function to use.
** fast track for 'gettable': if 't' is a table and 't[k]' is not nil,
** return 1 with 'slot' pointing to 't[k]' (final result). Otherwise,
** return 0 (meaning it will have to check metamethod) with 'slot'
** pointing to a nil 't[k]' (if 't' is a table) or NULL (otherwise).
** 'f' is the raw get function to use.
*/
#define luaV_fastget(L,t,k,aux,f) \
#define luaV_fastget(L,t,k,slot,f) \
(!ttistable(t) \
? (aux = NULL, 0) /* not a table; 'aux' is NULL and result is 0 */ \
: (aux = f(hvalue(t), k), /* else, do raw access */ \
!ttisnil(aux) ? 1 /* result not nil? 'aux' has it */ \
: (aux = fasttm(L, hvalue(t)->metatable, TM_INDEX), /* get metamethod */\
aux != NULL ? 0 /* has metamethod? must call it */ \
: (aux = luaO_nilobject, 1)))) /* else, final result is nil */
? (slot = NULL, 0) /* not a table; 'slot' is NULL and result is 0 */ \
: (slot = f(hvalue(t), k), /* else, do raw access */ \
!ttisnil(slot))) /* result not nil? */
/*
** standard implementation for 'gettable'
*/
#define luaV_gettable(L,t,k,v) { const TValue *aux; \
if (luaV_fastget(L,t,k,aux,luaH_get)) { setobj2s(L, v, aux); } \
else luaV_finishget(L,t,k,v,aux); }
#define luaV_gettable(L,t,k,v) { const TValue *slot; \
if (luaV_fastget(L,t,k,slot,luaH_get)) { setobj2s(L, v, slot); } \
else luaV_finishget(L,t,k,v,slot); }
/*
@@ -91,7 +90,7 @@
#define luaV_settable(L,t,k,v) { const TValue *slot; \
if (!luaV_fastset(L,t,k,slot,luaH_get,v)) \
luaV_finishset(L,t,k,v,slot); }
LUAI_FUNC int luaV_equalobj (lua_State *L, const TValue *t1, const TValue *t2);
@@ -100,9 +99,9 @@ LUAI_FUNC int luaV_lessequal (lua_State *L, const TValue *l, const TValue *r);
LUAI_FUNC int luaV_tonumber_ (const TValue *obj, lua_Number *n);
LUAI_FUNC int luaV_tointeger (const TValue *obj, lua_Integer *p, int mode);
LUAI_FUNC void luaV_finishget (lua_State *L, const TValue *t, TValue *key,
StkId val, const TValue *tm);
StkId val, const TValue *slot);
LUAI_FUNC void luaV_finishset (lua_State *L, const TValue *t, TValue *key,
StkId val, const TValue *oldval);
StkId val, const TValue *slot);
LUAI_FUNC void luaV_finishOp (lua_State *L);
LUAI_FUNC void luaV_execute (lua_State *L);
LUAI_FUNC void luaV_concat (lua_State *L, int total);

View File

@@ -1,5 +1,5 @@
/*
** $Id: lzio.c,v 1.37 2015/09/08 15:41:05 roberto Exp $
** $Id: lzio.c,v 1.37.1.1 2017/04/19 17:20:42 roberto Exp $
** Buffered streams
** See Copyright Notice in lua.h
*/

View File

@@ -1,5 +1,5 @@
/*
** $Id: lzio.h,v 1.31 2015/09/08 15:41:05 roberto Exp $
** $Id: lzio.h,v 1.31.1.1 2017/04/19 17:20:42 roberto Exp $
** Buffered streams
** See Copyright Notice in lua.h
*/

View File

@@ -1,3 +1,101 @@
v1.2.0 (2018-11-6)
-----------
* Improve cluster support
* Improve mongodb driver
* Improve redis driver
* Improve socket concurrent write
* Improve socket channel
* Improve service gate
* Improve udp support
* Add skynet.ignoreret
* Add skynet.trace
* Add skynet.context
* Improve skynet.wait/wakeup
* Add socket.netstat
* Add socketchannel.overload
* Fix memory leak for dead service
* lua update to 5.3.5
* jemalloc update to 5.1.0
v1.1.0 (2017-10-31)
-----------
* add socket.disconnected()
* fix bugs : see comments for detail
v1.1.0-rc (2017-7-18)
-----------
* config file : support include
* debug console : User config binding IP
* debug console : Add call command
* debug console : Report error message of inject code
* debug console : Change response message
* sharedata : Add sharedata.flush
* sharedata : Add sharedata.deepcopy
* cluster : Add cluster.send
* cluster : Add API to update config table
* skynet : Add skynet.state
* skynet : Keep the order of skynet.wakeup
* skynet : Add a MEMORY_CHECK macro for debugging
* httpc : Add httpc.timeout
* mongo driver : sort support multi-key
* bson : Check utf8 string
* bson : No longer support numberic key
* daemon mode: Can output the error messages
* sproto : Support decimal number
* sproto: Support binary type
* sproto: Support response nil
* crypt: Add crypt.hmac64_md5
* redis: Add redis-cluster support
* socket server : Optimize socket write (Try direct write from worker thread first)
* Add prefix skynet to all skynet lua modules
* datasheet : New module for replacement of sharedata
* jemalloc : Update to 5.0.1
* lua : Update to 5.3.4
* lpeg : Update to 1.0.1
v1.0.0 (2016-7-11)
-----------
* Version 1.0.0 Released
v1.0.0-rc5 (2016-7-4)
-----------
* MongoDB : Support auth_scram_sha1
* MongoDB : Auto determine primary host
* Bugfix : memory leak in multicast
* Bugfix : Lua 5.3.3
* Bson : support meta array
v1.0.0-rc4 (2016-6-13)
-----------
* Update lua to 5.3.3
* Update jemalloc to 4.2.1
* Add debug console command ping
* Lua bson support __pairs
* Add mongo.createIndexes and fix bug in old mongo.createIndex
* Handle signal HUP to reopen log file (for logrotate)
v1.0.0-rc3 (2016-5-9)
-----------
* Update jemalloc 4.1.1
* Update lua 5.3.3 rc1
* Update sproto to support encoding empty table
* Make skynet.init stable (keep order)
* skynet.getenv can return empty string
* Add lua VM memory warning
* lua VM support memory limit
* skynet.pcall suport varargs
* Bugfix : Global name query
* Bugfix : snax.queryglobal
v1.0.0-rc2 (2016-3-7)
-----------
* Fix a bug in lua 5.3.2
* Update sproto (fix bugs and add ud for package)
* Fix a bug in http
* Fix a bug in harbor
* Fix a bug in socket channel
* Enhance remote debugger
v1.0.0-rc (2015-12-28)
-----------
* Update to lua 5.3.2

View File

@@ -1,6 +1,6 @@
The MIT License (MIT)
Copyright (c) 2012-2015 codingnow.com
Copyright (c) 2012-2017 codingnow.com
Permission is hereby granted, free of charge, to any person obtaining a copy of
this software and associated documentation files (the "Software"), to deal in

View File

@@ -45,10 +45,26 @@ update3rd :
# skynet
CSERVICE = snlua logger gate harbor
LUA_CLIB = skynet socketdriver bson mongo md5 netpack \
clientsocket memory profile multicast \
cluster crypt sharedata stm sproto lpeg \
mysqlaux debugchannel
LUA_CLIB = skynet \
client \
bson md5 sproto lpeg
LUA_CLIB_SKYNET = \
lua-skynet.c lua-seri.c \
lua-socket.c \
lua-mongo.c \
lua-netpack.c \
lua-memory.c \
lua-profile.c \
lua-multicast.c \
lua-cluster.c \
lua-crypt.c lsha1.c \
lua-sharedata.c \
lua-stm.c \
lua-mysqlaux.c \
lua-debugchannel.c \
lua-datasheet.c \
\
SKYNET_SRC = skynet_main.c skynet_handle.c skynet_module.c skynet_mq.c \
skynet_server.c skynet_start.c skynet_timer.c skynet_error.c \
@@ -76,66 +92,30 @@ endef
$(foreach v, $(CSERVICE), $(eval $(call CSERVICE_TEMP,$(v))))
$(LUA_CLIB_PATH)/skynet.so : lualib-src/lua-skynet.c lualib-src/lua-seri.c | $(LUA_CLIB_PATH)
$(LUA_CLIB_PATH)/skynet.so : $(addprefix lualib-src/,$(LUA_CLIB_SKYNET)) | $(LUA_CLIB_PATH)
$(CC) $(CFLAGS) $(SHARED) $^ -o $@ -Iskynet-src -Iservice-src -Ilualib-src
$(LUA_CLIB_PATH)/socketdriver.so : lualib-src/lua-socket.c | $(LUA_CLIB_PATH)
$(CC) $(CFLAGS) $(SHARED) $^ -o $@ -Iskynet-src -Iservice-src
$(LUA_CLIB_PATH)/bson.so : lualib-src/lua-bson.c | $(LUA_CLIB_PATH)
$(CC) $(CFLAGS) $(SHARED) -Iskynet-src $^ -o $@ -Iskynet-src
$(LUA_CLIB_PATH)/mongo.so : lualib-src/lua-mongo.c | $(LUA_CLIB_PATH)
$(CC) $(CFLAGS) $(SHARED) $^ -o $@ -Iskynet-src
$(LUA_CLIB_PATH)/md5.so : 3rd/lua-md5/md5.c 3rd/lua-md5/md5lib.c 3rd/lua-md5/compat-5.2.c | $(LUA_CLIB_PATH)
$(CC) $(CFLAGS) $(SHARED) -I3rd/lua-md5 $^ -o $@
$(LUA_CLIB_PATH)/netpack.so : lualib-src/lua-netpack.c | $(LUA_CLIB_PATH)
$(CC) $(CFLAGS) $(SHARED) $^ -Iskynet-src -o $@
$(LUA_CLIB_PATH)/clientsocket.so : lualib-src/lua-clientsocket.c | $(LUA_CLIB_PATH)
$(LUA_CLIB_PATH)/client.so : lualib-src/lua-clientsocket.c lualib-src/lua-crypt.c lualib-src/lsha1.c | $(LUA_CLIB_PATH)
$(CC) $(CFLAGS) $(SHARED) $^ -o $@ -lpthread
$(LUA_CLIB_PATH)/memory.so : lualib-src/lua-memory.c | $(LUA_CLIB_PATH)
$(CC) $(CFLAGS) $(SHARED) -Iskynet-src $^ -o $@
$(LUA_CLIB_PATH)/profile.so : lualib-src/lua-profile.c | $(LUA_CLIB_PATH)
$(CC) $(CFLAGS) $(SHARED) $^ -o $@
$(LUA_CLIB_PATH)/multicast.so : lualib-src/lua-multicast.c | $(LUA_CLIB_PATH)
$(CC) $(CFLAGS) $(SHARED) -Iskynet-src $^ -o $@
$(LUA_CLIB_PATH)/cluster.so : lualib-src/lua-cluster.c | $(LUA_CLIB_PATH)
$(CC) $(CFLAGS) $(SHARED) -Iskynet-src $^ -o $@
$(LUA_CLIB_PATH)/crypt.so : lualib-src/lua-crypt.c lualib-src/lsha1.c | $(LUA_CLIB_PATH)
$(CC) $(CFLAGS) $(SHARED) $^ -o $@
$(LUA_CLIB_PATH)/sharedata.so : lualib-src/lua-sharedata.c | $(LUA_CLIB_PATH)
$(CC) $(CFLAGS) $(SHARED) -Iskynet-src $^ -o $@
$(LUA_CLIB_PATH)/stm.so : lualib-src/lua-stm.c | $(LUA_CLIB_PATH)
$(CC) $(CFLAGS) $(SHARED) -Iskynet-src $^ -o $@
$(LUA_CLIB_PATH)/sproto.so : lualib-src/sproto/sproto.c lualib-src/sproto/lsproto.c | $(LUA_CLIB_PATH)
$(CC) $(CFLAGS) $(SHARED) -Ilualib-src/sproto $^ -o $@
$(LUA_CLIB_PATH)/lpeg.so : 3rd/lpeg/lpcap.c 3rd/lpeg/lpcode.c 3rd/lpeg/lpprint.c 3rd/lpeg/lptree.c 3rd/lpeg/lpvm.c | $(LUA_CLIB_PATH)
$(CC) $(CFLAGS) $(SHARED) -I3rd/lpeg $^ -o $@
$(LUA_CLIB_PATH)/mysqlaux.so : lualib-src/lua-mysqlaux.c | $(LUA_CLIB_PATH)
$(CC) $(CFLAGS) $(SHARED) $^ -o $@
$(LUA_CLIB_PATH)/debugchannel.so : lualib-src/lua-debugchannel.c | $(LUA_CLIB_PATH)
$(CC) $(CFLAGS) $(SHARED) -Iskynet-src $^ -o $@
clean :
rm -f $(SKYNET_BUILD_PATH)/skynet $(CSERVICE_PATH)/*.so $(LUA_CLIB_PATH)/*.so
cleanall: clean
ifneq (,$(wildcard 3rd/jemalloc/Makefile))
cd 3rd/jemalloc && $(MAKE) clean
cd 3rd/jemalloc && $(MAKE) clean && rm Makefile
endif
cd 3rd/lua && $(MAKE) clean
rm -f $(LUA_STATICLIB)

View File

@@ -1,6 +1,10 @@
## ![skynet logo](https://github.com/cloudwu/skynet/wiki/image/skynet_metro.jpg)
Skynet is a lightweight online game framework, and it can be used in many other fields.
## Build
For linux, install autoconf first for jemalloc
For Linux, install autoconf first for jemalloc:
```
git clone https://github.com/cloudwu/skynet.git
@@ -8,33 +12,31 @@ cd skynet
make 'PLATFORM' # PLATFORM can be linux, macosx, freebsd now
```
Or you can :
Or you can:
```
export PLAT=linux
make
```
For freeBSD , use gmake instead of make .
For FreeBSD , use gmake instead of make.
## Test
Run these in different console
Run these in different consoles:
```
./skynet examples/config # Launch first skynet node (Gate server) and a skynet-master (see config for standalone option)
./3rd/lua/lua examples/client.lua # Launch a client, and try to input hello.
```
## About Lua
## About Lua version
Skynet now use a modify version of lua 5.3.2 ( http://www.lua.org/ftp/lua-5.3.2.tar.gz ) .
Skynet now uses a modified version of lua 5.3.5 ( https://github.com/ejoy/lua/tree/skynet ) for multiple lua states.
For detail : http://lua-users.org/lists/lua-l/2014-03/msg00489.html
You can also use official Lua versions, just edit the Makefile by yourself.
You can also use the other official Lua version , edit the makefile by yourself .
## How To Use (Sorry, currently only available in Chinese)
## How To Use (Sorry, Only in Chinese now)
* Read Wiki https://github.com/cloudwu/skynet/wiki
* Read Wiki for documents https://github.com/cloudwu/skynet/wiki
* The FAQ in wiki https://github.com/cloudwu/skynet/wiki/FAQ

View File

@@ -1,6 +1,5 @@
local skynet = require "skynet"
local netpack = require "netpack"
local socket = require "socket"
local socket = require "skynet.socket"
local sproto = require "sproto"
local sprotoloader = require "sprotoloader"
@@ -50,7 +49,10 @@ skynet.register_protocol {
unpack = function (msg, sz)
return host:dispatch(msg, sz)
end,
dispatch = function (_, _, type, ...)
dispatch = function (fd, _, type, ...)
assert(fd == client_fd) -- You can use fd to reply message
skynet.ignoreret() -- session is fd, don't call skynet.ret
skynet.trace()
if type == "REQUEST" then
local ok, result = pcall(request, ...)
if ok then
@@ -92,6 +94,7 @@ end
skynet.start(function()
skynet.dispatch("lua", function(_,_, command, ...)
skynet.trace()
local f = CMD[command]
skynet.ret(skynet.pack(f(...)))
end)

View File

@@ -0,0 +1,30 @@
local skynet = require "skynet"
local list = {}
local function timeout_check(ti)
if not next(list) then
return
end
skynet.sleep(ti) -- sleep 10 sec
for k,v in pairs(list) do
skynet.error("timout",ti,k,v)
end
end
skynet.start(function()
skynet.error("ping all")
local list_ret = skynet.call(".launcher", "lua", "LIST")
for addr, desc in pairs(list_ret) do
list[addr] = desc
skynet.fork(function()
skynet.call(addr,"debug","INFO")
list[addr] = nil
end)
end
skynet.sleep(0)
timeout_check(100)
timeout_check(400)
timeout_check(500)
skynet.exit()
end)

View File

@@ -5,7 +5,7 @@ if _VERSION ~= "Lua 5.3" then
error "Use lua 5.3"
end
local socket = require "clientsocket"
local socket = require "client.socket"
local proto = require "proto"
local sproto = require "sproto"

View File

@@ -1,8 +1,13 @@
local skynet = require "skynet"
local cluster = require "cluster"
local snax = require "snax"
local cluster = require "skynet.cluster"
local snax = require "skynet.snax"
skynet.start(function()
cluster.reload {
db = "127.0.0.1:2528",
db2 = "127.0.0.1:2529",
}
local sdb = skynet.newservice("simpledb")
-- register name "sdb" for simpledb, you can use cluster.query() later.
-- See cluster2.lua

View File

@@ -1,21 +1,31 @@
local skynet = require "skynet"
local cluster = require "cluster"
local cluster = require "skynet.cluster"
skynet.start(function()
-- query name "sdb" of cluster db.
local sdb = cluster.query("db", "sdb")
print("db.sbd=",sdb)
local proxy = cluster.proxy("db", sdb)
local proxy = cluster.proxy "db@sdb" -- cluster.proxy("db", "@sdb")
local largekey = string.rep("X", 128*1024)
local largevalue = string.rep("R", 100 * 1024)
print(skynet.call(proxy, "lua", "SET", largekey, largevalue))
skynet.call(proxy, "lua", "SET", largekey, largevalue)
local v = skynet.call(proxy, "lua", "GET", largekey)
assert(largevalue == v)
skynet.send(proxy, "lua", "PING", "proxy")
print(cluster.call("db", sdb, "GET", "a"))
print(cluster.call("db2", sdb, "GET", "b"))
skynet.fork(function()
skynet.trace("cluster")
print(cluster.call("db", "@sdb", "GET", "a"))
print(cluster.call("db2", "@sdb", "GET", "b"))
cluster.send("db2", "@sdb", "PING", "db2:longstring" .. largevalue)
end)
-- test snax service
local pingserver = cluster.snax("db", "pingserver")
skynet.timeout(300,function()
cluster.reload {
db = false, -- db is down
db3 = "127.0.0.1:2529"
}
print(pcall(cluster.call, "db", "@sdb", "GET", "a")) -- db is down
end)
cluster.reload { __nowaiting = false }
local pingserver = cluster.snax("db3", "pingserver")
print(pingserver.req.ping "hello")
end)

View File

@@ -1,2 +1,4 @@
__nowaiting = true -- If you turn this flag off, cluster.call would block when node name is absent
db = "127.0.0.1:2528"
db2 = "127.0.0.1:2529"

View File

@@ -1,4 +1,6 @@
root = "./"
include "config.path"
-- preload = "./examples/preload.lua" -- run preload.lua before every lua service run
thread = 8
logger = nil
logpath = "."
@@ -8,10 +10,6 @@ master = "127.0.0.1:2013"
start = "main" -- main script
bootstrap = "snlua bootstrap" -- The service for bootstrap
standalone = "0.0.0.0:2013"
luaservice = root.."service/?.lua;"..root.."test/?.lua;"..root.."examples/?.lua"
lualoader = "lualib/loader.lua"
-- preload = "./examples/preload.lua" -- run preload.lua before every lua service run
snax = root.."examples/?.lua;"..root.."test/?.lua"
-- snax_interface_g = "snax_g"
cpath = root.."cservice/?.so"
-- daemon = "./skynet.pid"

View File

@@ -6,5 +6,6 @@ bootstrap = "snlua bootstrap" -- The service for bootstrap
luaservice = "./service/?.lua;./test/?.lua;./examples/?.lua"
lualoader = "lualib/loader.lua"
cpath = "./cservice/?.so"
cluster = "./examples/clustername.lua"
-- use cluster.reload instead, see cluster1.lua
-- cluster = "./examples/clustername.lua"
snax = "./test/?.lua"

11
examples/config.mongodb Normal file
View File

@@ -0,0 +1,11 @@
root = "./"
thread = 8
logger = nil
harbor = 0
start = "main_mongodb" -- main script
bootstrap = "snlua bootstrap" -- The service for bootstrap
luaservice = root.."service/?.lua;"..root.."test/?.lua;"..root.."examples/?.lua"
lualoader = "lualib/loader.lua"
snax = root.."examples/?.lua;"..root.."test/?.lua"
cpath = root.."cservice/?.so"
-- daemon = "./skynet.pid"

6
examples/config.path Normal file
View File

@@ -0,0 +1,6 @@
root = "./"
luaservice = root.."service/?.lua;"..root.."test/?.lua;"..root.."examples/?.lua;"..root.."test/?/init.lua"
lualoader = root .. "lualib/loader.lua"
lua_path = root.."lualib/?.lua;"..root.."lualib/?/init.lua"
lua_cpath = root .. "luaclib/?.so"
snax = root.."examples/?.lua;"..root.."test/?.lua"

View File

@@ -1,7 +1,7 @@
package.cpath = "luaclib/?.so"
local socket = require "clientsocket"
local crypt = require "crypt"
local socket = require "client.socket"
local crypt = require "client.crypt"
if _VERSION ~= "Lua 5.3" then
error "Use lua 5.3"

View File

@@ -1,5 +1,5 @@
local msgserver = require "snax.msgserver"
local crypt = require "crypt"
local crypt = require "skynet.crypt"
local skynet = require "skynet"
local loginservice = tonumber(...)

View File

@@ -1,5 +1,5 @@
local login = require "snax.loginserver"
local crypt = require "crypt"
local crypt = require "skynet.crypt"
local skynet = require "skynet"
local server = {

View File

@@ -4,9 +4,11 @@ local sprotoloader = require "sprotoloader"
local max_client = 64
skynet.start(function()
print("Server start")
skynet.error("Server start")
skynet.uniqueservice("protoloader")
local console = skynet.newservice("console")
if not skynet.getenv "daemon" then
local console = skynet.newservice("console")
end
skynet.newservice("debug_console",8000)
skynet.newservice("simpledb")
local watchdog = skynet.newservice("watchdog")
@@ -15,7 +17,6 @@ skynet.start(function()
maxclient = max_client,
nodelay = true,
})
print("Watchdog listen on ", 8888)
skynet.error("Watchdog listen on", 8888)
skynet.exit()
end)

12
examples/main_mongodb.lua Normal file
View File

@@ -0,0 +1,12 @@
local skynet = require "skynet"
skynet.start(function()
print("Main Server start")
local console = skynet.newservice(
"testmongodb", "127.0.0.1", 27017, "testdb", "test", "test"
)
print("Main Server exit")
skynet.exit()
end)

View File

@@ -1,5 +1,5 @@
local skynet = require "skynet"
local sharedata = require "sharedata"
local sharedata = require "skynet.sharedata"
local mode = ...

View File

@@ -16,12 +16,23 @@ end
skynet.start(function()
skynet.dispatch("lua", function(session, address, cmd, ...)
local f = command[string.upper(cmd)]
cmd = cmd:upper()
if cmd == "PING" then
assert(session == 0)
local str = (...)
if #str > 20 then
str = str:sub(1,20) .. "...(" .. #str .. ")"
end
skynet.error(string.format("%s ping %s", skynet.address(address), str))
return
end
local f = command[cmd]
if f then
skynet.ret(skynet.pack(f(...)))
else
error(string.format("Unknown command %s", tostring(cmd)))
end
end)
-- skynet.traceproto("lua", false) -- true off tracelog
skynet.register "SIMPLEDB"
end)

View File

@@ -1,5 +1,5 @@
local skynet = require "skynet"
local socket = require "socket"
local socket = require "skynet.socket"
local httpd = require "http.httpd"
local sockethelper = require "http.sockethelper"
local urllib = require "http.url"

View File

@@ -1,15 +1,25 @@
local skynet = require "skynet"
require "skynet.manager"
-- register protocol text before skynet.start would be better.
skynet.register_protocol {
name = "text",
id = skynet.PTYPE_TEXT,
unpack = skynet.tostring,
dispatch = function(_, address, msg)
print(string.format("%x(%.2f): %s", address, skynet.time(), msg))
print(string.format(":%08x(%.2f): %s", address, skynet.time(), msg))
end
}
skynet.register_protocol {
name = "SYSTEM",
id = skynet.PTYPE_SYSTEM,
unpack = function(...) return ... end,
dispatch = function()
-- reopen signal
print("SIGHUP")
end
}
skynet.start(function()
skynet.register ".logger"
end)

View File

@@ -1,5 +1,4 @@
local skynet = require "skynet"
local netpack = require "netpack"
local CMD = {}
local SOCKET = {}

View File

@@ -82,6 +82,8 @@ A million repetitions of "a"
34AA973C D4C4DAA4 F61EEB2B DBAD2731 6534016F
*/
#define LUA_LIB
#include <stdio.h>
#include <string.h>
#include <stdint.h>
@@ -269,7 +271,7 @@ xor_key(uint8_t key[BLOCKSIZE], uint32_t xor) {
}
}
int
LUAMOD_API int
lhmac_sha1(lua_State *L) {
size_t key_sz = 0;
const uint8_t * key = (const uint8_t *)luaL_checklstring(L, 1, &key_sz);

View File

@@ -1,3 +1,5 @@
#define LUA_LIB
#include <lua.h>
#include <lauxlib.h>
@@ -198,10 +200,50 @@ write_length(struct bson *b, int32_t v, int off) {
b->ptr[off++] = (uv >> 24)&0xff;
}
#define MAXUNICODE 0x10FFFF
static int
utf8_copy(const char *s, char *d, size_t limit) {
static const unsigned int limits[] = {0xFF, 0x7F, 0x7FF, 0xFFFF};
unsigned int c = s[0];
unsigned int res = 0;
if (limit < 1)
return 0;
d[0] = s[0];
if (c < 0x80) {
return 1;
} else {
int count = 0;
while (c & 0x40) {
int cc = s[++count];
if (limit <= count || (cc & 0xC0) != 0x80)
return 0;
d[count] = s[count];
res = (res << 6) | (cc & 0x3F);
c <<= 1;
}
res |= ((c & 0x7F) << (count * 5));
if (count > 3 || res > MAXUNICODE || res <= limits[count])
return 0;
return count+1;
}
}
static void
write_string(struct bson *b, const char *key, size_t sz) {
write_string(struct bson *b, lua_State *L, const char *key, size_t sz) {
bson_reserve(b,sz+1);
memcpy(b->ptr + b->size, key, sz);
char *dst = (char *)(b->ptr + b->size);
const char *src = key;
size_t n = sz;
while(n > 0) {
int c = utf8_copy(src, dst, n);
if (c == 0) {
luaL_error(L, "Invalid utf8 string");
}
src += c;
dst += c;
n -= c;
}
b->ptr[b->size+sz] = '\0';
b->size+=sz+1;
}
@@ -238,12 +280,10 @@ write_double(struct bson *b, lua_Number d) {
}
}
static void pack_dict(lua_State *L, struct bson *b, bool array, int depth);
static inline void
append_key(struct bson *bs, int type, const char *key, size_t sz) {
append_key(struct bson *bs, lua_State *L, int type, const char *key, size_t sz) {
write_byte(bs, type);
write_string(bs, key, sz);
write_string(bs, L, key, sz);
}
static inline int
@@ -256,38 +296,20 @@ append_number(struct bson *bs, lua_State *L, const char *key, size_t sz) {
if (lua_isinteger(L, -1)) {
int64_t i = lua_tointeger(L, -1);
if (is_32bit(i)) {
append_key(bs, BSON_INT32, key, sz);
append_key(bs, L, BSON_INT32, key, sz);
write_int32(bs, i);
} else {
append_key(bs, BSON_INT64, key, sz);
append_key(bs, L, BSON_INT64, key, sz);
write_int64(bs, i);
}
} else {
lua_Number d = lua_tonumber(L,-1);
append_key(bs, BSON_REAL, key, sz);
append_key(bs, L, BSON_REAL, key, sz);
write_double(bs, d);
}
}
static void
append_table(struct bson *bs, lua_State *L, const char *key, size_t sz, int depth) {
size_t len = lua_rawlen(L, -1);
bool isarray = false;
if (len > 0) {
lua_pushinteger(L, len);
if (lua_next(L,-2) == 0) {
isarray = true;
} else {
lua_pop(L,2);
}
}
if (isarray) {
append_key(bs, BSON_ARRAY, key, sz);
} else {
append_key(bs, BSON_DOCUMENT, key, sz);
}
pack_dict(L, bs, isarray, depth);
}
static void append_table(struct bson *bs, lua_State *L, const char *key, size_t sz, int depth);
static void
write_binary(struct bson *b, const void * buffer, size_t sz) {
@@ -306,7 +328,7 @@ append_one(struct bson *bs, lua_State *L, const char *key, size_t sz, int depth)
append_number(bs, L, key, sz);
break;
case LUA_TUSERDATA: {
append_key(bs, BSON_DOCUMENT, key, sz);
append_key(bs, L, BSON_DOCUMENT, key, sz);
int32_t * doc = lua_touserdata(L,-1);
int32_t sz = *doc;
bson_reserve(bs,sz);
@@ -319,7 +341,7 @@ append_one(struct bson *bs, lua_State *L, const char *key, size_t sz, int depth)
const char * str = lua_tolstring(L,-1,&len);
if (len > 1 && str[0]==0) {
int subt = (uint8_t)str[1];
append_key(bs, subt, key, sz);
append_key(bs, L, subt, key, sz);
switch(subt) {
case BSON_BINARY:
write_binary(bs, str+2, len-2);
@@ -365,8 +387,8 @@ append_one(struct bson *bs, lua_State *L, const char *key, size_t sz, int depth)
break;
}
}
write_string(bs, str, len-i-1);
write_string(bs, str + len-i, i);
write_string(bs, L, str, len-i-1);
write_string(bs, L, str + len-i, i);
break;
}
case BSON_MINKEY:
@@ -379,9 +401,9 @@ append_one(struct bson *bs, lua_State *L, const char *key, size_t sz, int depth)
} else {
size_t len;
const char * str = lua_tolstring(L,-1,&len);
append_key(bs, BSON_STRING, key, sz);
append_key(bs, L, BSON_STRING, key, sz);
int off = reserve_length(bs);
write_string(bs, str, len);
write_string(bs, L, str, len);
write_length(bs, len+1, off);
}
break;
@@ -390,9 +412,11 @@ append_one(struct bson *bs, lua_State *L, const char *key, size_t sz, int depth)
append_table(bs, L, key, sz, depth+1);
break;
case LUA_TBOOLEAN:
append_key(bs, BSON_BOOLEAN, key, sz);
append_key(bs, L, BSON_BOOLEAN, key, sz);
write_byte(bs, lua_toboolean(L,-1));
break;
case LUA_TNIL:
luaL_error(L, "Bson array has a hole (nil), Use bson.null instead");
default:
luaL_error(L, "Invalid value type : %s", lua_typename(L,vt));
}
@@ -409,66 +433,132 @@ bson_numstr( char *str, unsigned int i ) {
}
static void
pack_dict(lua_State *L, struct bson *b, bool isarray, int depth) {
if (depth > MAX_DEPTH) {
luaL_error(L, "Too depth while encoding bson");
}
luaL_checkstack(L, 16, NULL); // reserve enough stack space to pack table
pack_array(lua_State *L, struct bson *b, int depth, size_t len) {
int length = reserve_length(b);
lua_pushnil(L);
while(lua_next(L,-2) != 0) {
int kt = lua_type(L, -2);
size_t i;
for (i=1;i<=len;i++) {
char numberkey[32];
const char * key = NULL;
size_t sz;
if (isarray) {
if (kt != LUA_TNUMBER) {
luaL_error(L, "Invalid array key type : %s", lua_typename(L, kt));
return;
}
sz = bson_numstr(numberkey, (unsigned int)lua_tointeger(L,-2)-1);
key = numberkey;
append_one(b, L, key, sz, depth);
lua_pop(L,1);
} else {
switch(kt) {
case LUA_TNUMBER:
// copy key, don't change key type
lua_pushvalue(L,-2);
lua_insert(L,-2);
key = lua_tolstring(L,-2,&sz);
append_one(b, L, key, sz, depth);
lua_pop(L,2);
break;
case LUA_TSTRING:
key = lua_tolstring(L,-2,&sz);
append_one(b, L, key, sz, depth);
lua_pop(L,1);
break;
default:
luaL_error(L, "Invalid key type : %s", lua_typename(L, kt));
return;
}
}
size_t sz = bson_numstr(numberkey, i - 1);
const char * key = numberkey;
lua_geti(L, -1, i);
append_one(b, L, key, sz, depth);
lua_pop(L, 1);
}
write_byte(b,0);
write_length(b, b->size - length, length);
}
static void
pack_dict_data(lua_State *L, struct bson *b, int depth, int kt) {
const char * key = NULL;
size_t sz;
switch(kt) {
case LUA_TNUMBER:
luaL_error(L, "Bson dictionary's key can't be number");
break;
case LUA_TSTRING:
key = lua_tolstring(L,-2,&sz);
append_one(b, L, key, sz, depth);
lua_pop(L,1);
break;
default:
luaL_error(L, "Invalid key type : %s", lua_typename(L, kt));
return;
}
}
static void
pack_simple_dict(lua_State *L, struct bson *b, int depth) {
int length = reserve_length(b);
lua_pushnil(L);
while(lua_next(L,-2) != 0) {
int kt = lua_type(L, -2);
pack_dict_data(L, b, depth, kt);
}
write_byte(b,0);
write_length(b, b->size - length, length);
}
static void
pack_meta_dict(lua_State *L, struct bson *b, int depth) {
int length = reserve_length(b);
lua_pushvalue(L, -2); // push meta_obj
lua_call(L, 1, 3); // call __pairs_func => next_func, t_data, first_k
for(;;) {
lua_pushvalue(L, -2); // copy data
lua_pushvalue(L, -2); // copy k
lua_copy(L, -5, -3); // copy next_func replace old_k
lua_call(L, 2, 2); // call next_func
int kt = lua_type(L, -2);
if (kt == LUA_TNIL) {
lua_pop(L, 4); // pop all k, v, next_func, obj
break;
}
pack_dict_data(L, b, depth, kt);
}
write_byte(b,0);
write_length(b, b->size - length, length);
}
static bool
is_rawarray(lua_State *L) {
size_t len = lua_rawlen(L, -1);
if (len > 0) {
lua_pushinteger(L, len);
if (lua_next(L,-2) == 0) {
return true;
} else {
lua_pop(L,2);
}
}
return false;
}
static void
append_table(struct bson *bs, lua_State *L, const char *key, size_t sz, int depth) {
if (depth > MAX_DEPTH) {
luaL_error(L, "Too depth while encoding bson");
}
luaL_checkstack(L, 16, NULL); // reserve enough stack space to pack table
if (luaL_getmetafield(L, -1, "__len") != LUA_TNIL) {
lua_pushvalue(L, -2);
lua_call(L, 1, 1);
if (!lua_isinteger(L, -1)) {
luaL_error(L, "__len should return integer");
}
size_t len = lua_tointeger(L, -1);
lua_pop(L, 1);
append_key(bs, L, BSON_ARRAY, key, sz);
pack_array(L, bs, depth, len);
} else if (luaL_getmetafield(L, -1, "__pairs") != LUA_TNIL) {
append_key(bs, L, BSON_DOCUMENT, key, sz);
pack_meta_dict(L, bs, depth);
} else if (is_rawarray(L)) {
append_key(bs, L, BSON_ARRAY, key, sz);
pack_array(L, bs, depth, lua_rawlen(L, -1));
} else {
append_key(bs, L, BSON_DOCUMENT, key, sz);
pack_simple_dict(L, bs, depth);
}
}
static void
pack_ordered_dict(lua_State *L, struct bson *b, int n, int depth) {
int length = reserve_length(b);
int i;
size_t sz;
// the first key is at index n
const char * key = lua_tolstring(L, n, &sz);
for (i=0;i<n;i+=2) {
size_t sz;
const char * key = lua_tolstring(L, i+1, &sz);
if (key == NULL) {
luaL_error(L, "Argument %d need a string", i+1);
}
lua_pushvalue(L, i+2);
lua_pushvalue(L, i+1);
append_one(b, L, key, sz, depth);
lua_pop(L,1);
key = lua_tolstring(L, i+2, &sz); // next key
}
write_byte(b,0);
write_length(b, b->size - length, length);
@@ -847,32 +937,66 @@ bson_meta(lua_State *L) {
lua_setmetatable(L, -2);
}
static int
encode_bson(lua_State *L) {
struct bson *b = lua_touserdata(L, 2);
lua_settop(L, 1);
if (luaL_getmetafield(L, -1, "__pairs") != LUA_TNIL) {
pack_meta_dict(L, b, 0);
} else {
pack_simple_dict(L, b, 0);
}
void * ud = lua_newuserdata(L, b->size);
memcpy(ud, b->ptr, b->size);
return 1;
}
static int
lencode(lua_State *L) {
struct bson b;
bson_create(&b);
lua_settop(L,1);
luaL_checktype(L, 1, LUA_TTABLE);
pack_dict(L, &b, false, 0);
void * ud = lua_newuserdata(L, b.size);
memcpy(ud, b.ptr, b.size);
bson_create(&b);
lua_pushcfunction(L, encode_bson);
lua_pushvalue(L, 1);
lua_pushlightuserdata(L, &b);
if (lua_pcall(L, 2, 1, 0) != LUA_OK) {
bson_destroy(&b);
return lua_error(L);
}
bson_destroy(&b);
bson_meta(L);
return 1;
}
static int
encode_bson_byorder(lua_State *L) {
int n = lua_gettop(L);
struct bson *b = lua_touserdata(L, n);
lua_settop(L, --n);
pack_ordered_dict(L, b, n, 0);
lua_settop(L,0);
void * ud = lua_newuserdata(L, b->size);
memcpy(ud, b->ptr, b->size);
return 1;
}
static int
lencode_order(lua_State *L) {
struct bson b;
bson_create(&b);
int n = lua_gettop(L);
if (n%2 != 0) {
return luaL_error(L, "Invalid ordered dict");
}
pack_ordered_dict(L, &b, n, 0);
lua_settop(L,1);
void * ud = lua_newuserdata(L, b.size);
memcpy(ud, b.ptr, b.size);
bson_create(&b);
lua_pushvalue(L, 1); // copy the first arg to n
lua_pushcfunction(L, encode_bson_byorder);
lua_replace(L, 1);
lua_pushlightuserdata(L, &b);
if (lua_pcall(L, n+1, 1, 0) != LUA_OK) {
bson_destroy(&b);
return lua_error(L);
}
bson_destroy(&b);
bson_meta(L);
return 1;
@@ -1164,7 +1288,7 @@ lobjectid(lua_State *L) {
return 1;
}
int
LUAMOD_API int
luaopen_bson(lua_State *L) {
luaL_checkversion(L);
int i;

View File

@@ -2,6 +2,8 @@
// It's only for demo, limited feature. Don't use it in your project.
// Rewrite socket library by yourself .
#define LUA_LIB
#include <lua.h>
#include <lauxlib.h>
#include <string.h>
@@ -183,8 +185,8 @@ lreadstdin(lua_State *L) {
return 1;
}
int
luaopen_clientsocket(lua_State *L) {
LUAMOD_API int
luaopen_client_socket(lua_State *L) {
luaL_checkversion(L);
luaL_Reg l[] = {
{ "connect", lconnect },

Some files were not shown because too many files have changed in this diff Show More