Compare commits

..

309 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
242 changed files with 6325 additions and 1757 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.259 2016/02/29 14:27:14 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
*/
@@ -534,6 +534,7 @@ 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;
@@ -547,9 +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);
luaC_checkGC(L);
lua_unlock(L);
}
@@ -1012,7 +1013,7 @@ LUA_API int lua_load (lua_State *L, lua_Reader reader, void *data,
return status;
}
void cloneproto (lua_State *L, Proto *f, const Proto *src) {
static void cloneproto (lua_State *L, Proto *f, const Proto *src) {
/* copy constants and nested proto */
int i,n;
n = src->sp->sizek;

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.286 2016/01/08 15:33:09 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
*/
@@ -69,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.'? */
@@ -809,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:
@@ -827,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);
@@ -882,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 */
}
@@ -962,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 */
@@ -1030,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.313 2016/04/11 19:18:40 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
*/
@@ -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 */

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
*/

View File

@@ -1,5 +1,5 @@
/*
** $Id: lcode.c,v 2.109 2016/05/13 19:09:21 roberto Exp $
** $Id: lcode.c,v 2.112.1.1 2017/04/19 17:20:42 roberto Exp $
** Code generator for Lua
** See Copyright Notice in lua.h
*/
@@ -40,7 +40,7 @@
** If expression is a numeric constant, fills 'v' with its value
** and returns 1. Otherwise, returns 0.
*/
static int tonumeral(expdesc *e, TValue *v) {
static int tonumeral(const expdesc *e, TValue *v) {
if (hasjumps(e))
return 0; /* not a numeral */
switch (e->k) {
@@ -86,7 +86,7 @@ void luaK_nil (FuncState *fs, int from, int n) {
/*
** Gets the destination address of a jump instruction. Used to traverse
** a list of jumps.
*/
*/
static int getjump (FuncState *fs, int pc) {
int offset = GETARG_sBx(fs->f->sp->code[pc]);
if (offset == NO_JUMP) /* point to itself represents end of list */
@@ -176,7 +176,6 @@ int luaK_getlabel (FuncState *fs) {
** jump (that is, its condition), or the jump itself if it is
** unconditional.
*/
static Instruction *getjumpcontrol (FuncState *fs, int pc) {
Instruction *pi = &fs->f->sp->code[pc];
if (pc >= 1 && testTMode(GET_OPCODE(*(pi-1))))
@@ -755,7 +754,7 @@ void luaK_exp2val (FuncState *fs, expdesc *e) {
** (that is, it is either in a register or in 'k' with an index
** in the range of R/K indices).
** Returns R/K index.
*/
*/
int luaK_exp2RK (FuncState *fs, expdesc *e) {
luaK_exp2val(fs, e);
switch (e->k) { /* move constants to 'k' */
@@ -976,7 +975,8 @@ static int validop (int op, TValue *v1, TValue *v2) {
** Try to "constant-fold" an operation; return 1 iff successful.
** (In this case, 'e1' has the final result.)
*/
static int constfolding (FuncState *fs, int op, expdesc *e1, expdesc *e2) {
static int constfolding (FuncState *fs, int op, expdesc *e1,
const expdesc *e2) {
TValue v1, v2, res;
if (!tonumeral(e1, &v1) || !tonumeral(e2, &v2) || !validop(op, &v1, &v2))
return 0; /* non-numeric operands or not safe to fold */
@@ -1015,11 +1015,14 @@ static void codeunexpval (FuncState *fs, OpCode op, expdesc *e, int line) {
** (everything but logical operators 'and'/'or' and comparison
** operators).
** Expression to produce final result will be encoded in 'e1'.
** Because 'luaK_exp2RK' can free registers, its calls must be
** in "stack order" (that is, first on 'e2', which may have more
** recent registers to be released).
*/
static void codebinexpval (FuncState *fs, OpCode op,
expdesc *e1, expdesc *e2, int line) {
int rk1 = luaK_exp2RK(fs, e1); /* both operands are "RK" */
int rk2 = luaK_exp2RK(fs, e2);
int rk2 = luaK_exp2RK(fs, e2); /* both operands are "RK" */
int rk1 = luaK_exp2RK(fs, e1);
freeexps(fs, e1, e2);
e1->u.info = luaK_codeABC(fs, op, 0, rk1, rk2); /* generate opcode */
e1->k = VRELOCABLE; /* all those operations are relocatable */
@@ -1061,9 +1064,9 @@ static void codecomp (FuncState *fs, BinOpr opr, expdesc *e1, expdesc *e2) {
** Aplly prefix operation 'op' to expression 'e'.
*/
void luaK_prefix (FuncState *fs, UnOpr op, expdesc *e, int line) {
static expdesc ef = {VKINT, {0}, NO_JUMP, NO_JUMP}; /* fake 2nd operand */
static const expdesc ef = {VKINT, {0}, NO_JUMP, NO_JUMP};
switch (op) {
case OPR_MINUS: case OPR_BNOT:
case OPR_MINUS: case OPR_BNOT: /* use 'ef' as fake 2nd operand */
if (constfolding(fs, op + LUA_OPUNM, e, &ef))
break;
/* FALLTHROUGH */

View File

@@ -1,5 +1,5 @@
/*
** $Id: lcode.h,v 1.64 2016/01/05 16:22:37 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
*/

View File

@@ -1,5 +1,5 @@
/*
** $Id: lcorolib.c,v 1.10 2016/04/11 19:19:55 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
*/

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.120 2016/03/31 19:01:21 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) {
@@ -244,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;
@@ -274,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;
@@ -471,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 */
@@ -482,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;
@@ -509,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";
@@ -634,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.151 2015/12/16 16:40:07 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) */
}
@@ -322,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
@@ -468,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
@@ -520,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' */
}
@@ -595,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;
}
@@ -615,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? */
@@ -647,7 +642,6 @@ static void resume (lua_State *L, void *ud) {
}
unroll(L, NULL); /* run continuation */
}
lua_assert(nCcalls == L->nCcalls);
}
@@ -655,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);

View File

@@ -1,5 +1,5 @@
/*
** $Id: ldo.h,v 2.29 2015/12/21 13:02:14 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
*/

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.212 2016/03/31 19:02:03 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) {
@@ -550,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;
@@ -654,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 */
}
}
}
@@ -829,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? */

View File

@@ -1,5 +1,5 @@
/*
** $Id: lgc.h,v 2.91 2015/12/21 13:02:14 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
*/

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.149 2016/05/02 14:03:19 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);
}
@@ -618,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 {
@@ -709,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.96 2016/05/02 14:02:12 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
*/

View File

@@ -1,5 +1,5 @@
/*
** $Id: llex.h,v 1.79 2016/05/02 14:02:12 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
*/

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.111 2016/05/20 14:07:48 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
*/
@@ -280,7 +280,7 @@ static const char *l_str2d (const char *s, lua_Number *result) {
endptr = l_str2dloc(s, result, mode); /* try to convert */
if (endptr == NULL) { /* failed? may be a different locale */
char buff[L_MAXLENNUM + 1];
char *pdot = strchr(s, '.');
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 */
@@ -394,7 +394,7 @@ static void pushstr (lua_State *L, const char *str, size_t l) {
/*
** this function handles only '%d', '%c', '%f', '%p', and '%s'
** 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) {
@@ -435,7 +435,8 @@ const char *luaO_pushvfstring (lua_State *L, const char *fmt, va_list argp) {
}
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;
}

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.64 2016/04/18 13:06:55 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
*/
@@ -30,16 +30,16 @@
*/
#if !defined(LUA_STRFTIMEOPTIONS) /* { */
/* options for ANSI C 89 */
/* 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"
"||" "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"
"||" "#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
@@ -257,12 +257,13 @@ 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) {
const char *option;
int oplen = 1;
for (option = LUA_STRFTIMEOPTIONS; *option != '\0'; option += oplen) {
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++; /* next length */
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';
@@ -280,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);
@@ -290,7 +293,8 @@ 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 */
setallfields(L, stm);
@@ -300,13 +304,14 @@ static int os_date (lua_State *L) {
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 + 1); /* copy specifier to '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);
}
@@ -336,7 +341,8 @@ static int os_time (lua_State *L) {
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.153 2016/05/13 19:10:16 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
*/
@@ -769,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");
@@ -965,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;
}
@@ -1396,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 */
@@ -1617,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.76 2015/12/30 18:16:13 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
*/

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.130 2015/12/16 16:39:38 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.
*/
@@ -34,7 +52,7 @@ struct lua_longjmp; /* defined in ldo.c */
/*
** Atomic type (relative to signals) to better ensure that 'lua_sethook'
** Atomic type (relative to signals) to better ensure that 'lua_sethook'
** is thread safe
*/
#if !defined(l_signalT)
@@ -66,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.
@@ -88,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;
@@ -104,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)

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
*/

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.251 2016/05/20 14:13:21 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
*/
@@ -839,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;
@@ -878,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;
}
@@ -933,7 +934,7 @@ static void addquoted (luaL_Buffer *b, const char *s, size_t len) {
static void checkdp (char *buff, int nb) {
if (memchr(buff, '.', nb) == NULL) { /* no dot? */
char point = lua_getlocaledecpoint(); /* try locale point */
char *ppoint = memchr(buff, point, nb);
char *ppoint = (char *)memchr(buff, point, nb);
if (ppoint) *ppoint = '.'; /* change it to a dot */
}
}
@@ -960,7 +961,7 @@ static void addliteral (lua_State *L, luaL_Buffer *b, int 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, n);
nb = l_sprintf(buff, MAX_ITEM, format, (LUAI_UACINT)n);
}
luaL_addsize(b, nb);
break;
@@ -1041,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':
@@ -1051,8 +1052,9 @@ 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': {
@@ -1197,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;
}
@@ -1259,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.
*/

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.93 2016/02/25 19:41:54 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
*/

View File

@@ -1,5 +1,5 @@
/*
** $Id: ltm.c,v 2.37 2016/02/26 19:20:15 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"

View File

@@ -1,5 +1,5 @@
/*
** $Id: ltm.h,v 2.22 2016/02/26 19:20:15 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
*/

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.331 2016/05/30 15:53:28 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 "3"
#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-2016 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"
@@ -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-2016 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.255 2016/05/01 20:06:09 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) ((void)L, 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
*/

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.268 2016/02/05 19:59:14 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
*/
@@ -1201,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.40 2016/01/05 16:07:21 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
*/
@@ -90,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);

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,58 @@
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

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,4 +1,4 @@
## Skynet
## ![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.
@@ -32,11 +32,11 @@ Run these in different consoles:
## About Lua version
Skynet now uses a modified version of lua 5.3.3 ( https://github.com/ejoy/lua/tree/skynet ) for multiple lua states.
Skynet now uses a modified version of lua 5.3.5 ( https://github.com/ejoy/lua/tree/skynet ) for multiple lua states.
You can also use official Lua versions, just edit the Makefile by yourself.
## How To Use (Sorry, Only in Chinese now)
## How To Use (Sorry, currently only available in Chinese)
* 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

@@ -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,12 +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 = root .. "lualib/loader.lua"
lua_path = root.."lualib/?.lua;"..root.."lualib/?/init.lua"
lua_cpath = root .. "luaclib/?.so"
-- 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 = {

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,6 +1,7 @@
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,
@@ -21,5 +22,4 @@ skynet.register_protocol {
}
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;
}
@@ -239,9 +281,9 @@ write_double(struct bson *b, lua_Number d) {
}
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
@@ -254,15 +296,15 @@ 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);
}
}
@@ -286,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);
@@ -299,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);
@@ -345,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:
@@ -359,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;
@@ -370,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));
}
@@ -410,12 +454,7 @@ pack_dict_data(lua_State *L, struct bson *b, int depth, int kt) {
size_t sz;
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);
luaL_error(L, "Bson dictionary's key can't be number");
break;
case LUA_TSTRING:
key = lua_tolstring(L,-2,&sz);
@@ -491,16 +530,16 @@ append_table(struct bson *bs, lua_State *L, const char *key, size_t sz, int dept
}
size_t len = lua_tointeger(L, -1);
lua_pop(L, 1);
append_key(bs, BSON_ARRAY, key, sz);
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, BSON_DOCUMENT, key, sz);
append_key(bs, L, BSON_DOCUMENT, key, sz);
pack_meta_dict(L, bs, depth);
} else if (is_rawarray(L)) {
append_key(bs, BSON_ARRAY, key, sz);
append_key(bs, L, BSON_ARRAY, key, sz);
pack_array(L, bs, depth, lua_rawlen(L, -1));
} else {
append_key(bs, BSON_DOCUMENT, key, sz);
append_key(bs, L, BSON_DOCUMENT, key, sz);
pack_simple_dict(L, bs, depth);
}
}
@@ -509,15 +548,17 @@ 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);
@@ -896,36 +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);
if (luaL_getmetafield(L, -1, "__pairs") != LUA_TNIL) {
pack_meta_dict(L, &b, 0);
} else {
pack_simple_dict(L, &b, 0);
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);
}
void * ud = lua_newuserdata(L, b.size);
memcpy(ud, b.ptr, b.size);
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;
@@ -1217,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 },

View File

@@ -1,7 +1,10 @@
#define LUA_LIB
#include <lua.h>
#include <lauxlib.h>
#include <string.h>
#include <assert.h>
#include <unistd.h>
#include "skynet.h"
@@ -35,7 +38,9 @@ fill_header(lua_State *L, uint8_t *buf, int sz) {
}
/*
The request package :
The request package :
first WORD is size of the package with big-endian
DWORD in content is small-endian
size <= 0x8000 (32K) and address is id
WORD sz+9
BYTE 0
@@ -43,8 +48,8 @@ fill_header(lua_State *L, uint8_t *buf, int sz) {
DWORD session
PADDING msg(sz)
size > 0x8000 and address is id
DWORD 13
BYTE 1 ; multireq
WORD 13
BYTE 1 ; multireq , 0x41: multi push
DWORD addr
DWORD session
DWORD sz
@@ -57,8 +62,8 @@ fill_header(lua_State *L, uint8_t *buf, int sz) {
DWORD session
PADDING msg(sz)
size > 0x8000 and address is string
DWORD 10 + namelen
BYTE 0x81
WORD 10 + namelen
BYTE 0x81 ; 0xc1 : multi push
BYTE namelen
STRING name
DWORD session
@@ -69,16 +74,21 @@ fill_header(lua_State *L, uint8_t *buf, int sz) {
BYTE 2/3 ; 2:multipart, 3:multipart end
DWORD SESSION
PADDING msgpart(sz)
trace
WORD stringsz + 1
BYTE 4
STRING tag
*/
static int
packreq_number(lua_State *L, int session, void * msg, uint32_t sz) {
packreq_number(lua_State *L, int session, void * msg, uint32_t sz, int is_push) {
uint32_t addr = (uint32_t)lua_tointeger(L,1);
uint8_t buf[TEMP_LENGTH];
if (sz < MULTI_PART) {
fill_header(L, buf, sz+9);
buf[2] = 0;
fill_uint32(buf+3, addr);
fill_uint32(buf+7, (uint32_t)session);
fill_uint32(buf+7, is_push ? 0 : (uint32_t)session);
memcpy(buf+11,msg,sz);
lua_pushlstring(L, (const char *)buf, sz+11);
@@ -86,7 +96,7 @@ packreq_number(lua_State *L, int session, void * msg, uint32_t sz) {
} else {
int part = (sz - 1) / MULTI_PART + 1;
fill_header(L, buf, 13);
buf[2] = 1;
buf[2] = is_push ? 0x41 : 1; // multi push or request
fill_uint32(buf+3, addr);
fill_uint32(buf+7, (uint32_t)session);
fill_uint32(buf+11, sz);
@@ -96,7 +106,7 @@ packreq_number(lua_State *L, int session, void * msg, uint32_t sz) {
}
static int
packreq_string(lua_State *L, int session, void * msg, uint32_t sz) {
packreq_string(lua_State *L, int session, void * msg, uint32_t sz, int is_push) {
size_t namelen = 0;
const char *name = lua_tolstring(L, 1, &namelen);
if (name == NULL || namelen < 1 || namelen > 255) {
@@ -110,7 +120,7 @@ packreq_string(lua_State *L, int session, void * msg, uint32_t sz) {
buf[2] = 0x80;
buf[3] = (uint8_t)namelen;
memcpy(buf+4, name, namelen);
fill_uint32(buf+4+namelen, (uint32_t)session);
fill_uint32(buf+4+namelen, is_push ? 0 : (uint32_t)session);
memcpy(buf+8+namelen,msg,sz);
lua_pushlstring(L, (const char *)buf, sz+8+namelen);
@@ -118,7 +128,7 @@ packreq_string(lua_State *L, int session, void * msg, uint32_t sz) {
} else {
int part = (sz - 1) / MULTI_PART + 1;
fill_header(L, buf, 10+namelen);
buf[2] = 0x81;
buf[2] = is_push ? 0xc1 : 0x81; // multi push or request
buf[3] = (uint8_t)namelen;
memcpy(buf+4, name, namelen);
fill_uint32(buf+4+namelen, (uint32_t)session);
@@ -155,7 +165,7 @@ packreq_multi(lua_State *L, int session, void * msg, uint32_t sz) {
}
static int
lpackrequest(lua_State *L) {
packrequest(lua_State *L, int is_push) {
void *msg = lua_touserdata(L,3);
if (msg == NULL) {
return luaL_error(L, "Invalid request message");
@@ -169,18 +179,18 @@ lpackrequest(lua_State *L) {
int addr_type = lua_type(L,1);
int multipak;
if (addr_type == LUA_TNUMBER) {
multipak = packreq_number(L, session, msg, sz);
multipak = packreq_number(L, session, msg, sz, is_push);
} else {
multipak = packreq_string(L, session, msg, sz);
multipak = packreq_string(L, session, msg, sz, is_push);
}
int current_session = session;
if (++session < 0) {
session = 1;
uint32_t new_session = (uint32_t)session + 1;
if (new_session > INT32_MAX) {
new_session = 1;
}
lua_pushinteger(L, session);
lua_pushinteger(L, new_session);
if (multipak) {
lua_createtable(L, multipak, 0);
packreq_multi(L, current_session, msg, sz);
packreq_multi(L, session, msg, sz);
skynet_free(msg);
return 3;
} else {
@@ -189,13 +199,40 @@ lpackrequest(lua_State *L) {
}
}
static int
lpackrequest(lua_State *L) {
return packrequest(L, 0);
}
static int
lpackpush(lua_State *L) {
return packrequest(L, 1);
}
static int
lpacktrace(lua_State *L) {
size_t sz;
const char * tag = luaL_checklstring(L, 1, &sz);
if (sz > 0x8000) {
return luaL_error(L, "trace tag is too long : %d", (int) sz);
}
uint8_t buf[TEMP_LENGTH];
buf[2] = 4;
fill_header(L, buf, sz+1);
memcpy(buf+3, tag, sz);
lua_pushlstring(L, (const char *)buf, sz+3);
return 1;
}
/*
string packed message
return
uint32_t or string addr
int session
string msg
lightuserdata msg
int sz
boolean padding
boolean is_push
*/
static inline uint32_t
@@ -203,6 +240,14 @@ unpack_uint32(const uint8_t * buf) {
return buf[0] | buf[1]<<8 | buf[2]<<16 | buf[3]<<24;
}
static void
return_buffer(lua_State *L, const char * buffer, int sz) {
void * ptr = skynet_malloc(sz);
memcpy(ptr, buffer, sz);
lua_pushlightuserdata(L, ptr);
lua_pushinteger(L, sz);
}
static int
unpackreq_number(lua_State *L, const uint8_t * buf, int sz) {
if (sz < 9) {
@@ -212,13 +257,19 @@ unpackreq_number(lua_State *L, const uint8_t * buf, int sz) {
uint32_t session = unpack_uint32(buf+5);
lua_pushinteger(L, address);
lua_pushinteger(L, session);
lua_pushlstring(L, (const char *)buf+9, sz-9);
return 3;
return_buffer(L, (const char *)buf+9, sz-9);
if (session == 0) {
lua_pushnil(L);
lua_pushboolean(L,1); // is_push, no reponse
return 6;
}
return 4;
}
static int
unpackmreq_number(lua_State *L, const uint8_t * buf, int sz) {
unpackmreq_number(lua_State *L, const uint8_t * buf, int sz, int is_push) {
if (sz != 13) {
return luaL_error(L, "Invalid cluster message size %d (multi req must be 13)", sz);
}
@@ -227,10 +278,12 @@ unpackmreq_number(lua_State *L, const uint8_t * buf, int sz) {
uint32_t size = unpack_uint32(buf+9);
lua_pushinteger(L, address);
lua_pushinteger(L, session);
lua_pushnil(L);
lua_pushinteger(L, size);
lua_pushboolean(L, 1); // padding multi part
lua_pushboolean(L, is_push);
return 4;
return 6;
}
static int
@@ -242,10 +295,16 @@ unpackmreq_part(lua_State *L, const uint8_t * buf, int sz) {
uint32_t session = unpack_uint32(buf+1);
lua_pushboolean(L, 0); // no address
lua_pushinteger(L, session);
lua_pushlstring(L, (const char *)buf+5, sz-5);
return_buffer(L, (const char *)buf+5, sz-5);
lua_pushboolean(L, padding);
return 4;
return 5;
}
static int
unpacktrace(lua_State *L, const char * buf, int sz) {
lua_pushlstring(L, buf + 1, sz - 1);
return 1;
}
static int
@@ -260,13 +319,18 @@ unpackreq_string(lua_State *L, const uint8_t * buf, int sz) {
lua_pushlstring(L, (const char *)buf+2, namesz);
uint32_t session = unpack_uint32(buf + namesz + 2);
lua_pushinteger(L, (uint32_t)session);
lua_pushlstring(L, (const char *)buf+2+namesz+4, sz - namesz - 6);
return_buffer(L, (const char *)buf+2+namesz+4, sz - namesz - 6);
if (session == 0) {
lua_pushnil(L);
lua_pushboolean(L,1); // is_push, no reponse
return 6;
}
return 3;
return 4;
}
static int
unpackmreq_string(lua_State *L, const uint8_t * buf, int sz) {
unpackmreq_string(lua_State *L, const uint8_t * buf, int sz, int is_push) {
if (sz < 2) {
return luaL_error(L, "Invalid cluster message (size=%d)", sz);
}
@@ -278,35 +342,52 @@ unpackmreq_string(lua_State *L, const uint8_t * buf, int sz) {
uint32_t session = unpack_uint32(buf + namesz + 2);
uint32_t size = unpack_uint32(buf + namesz + 6);
lua_pushinteger(L, session);
lua_pushnil(L);
lua_pushinteger(L, size);
lua_pushboolean(L, 1); // padding multipart
lua_pushboolean(L, is_push);
return 4;
return 6;
}
static int
lunpackrequest(lua_State *L) {
size_t ssz;
const char *msg = luaL_checklstring(L,1,&ssz);
int sz = (int)ssz;
int sz;
const char *msg;
if (lua_type(L, 1) == LUA_TLIGHTUSERDATA) {
msg = (const char *)lua_touserdata(L, 1);
sz = luaL_checkinteger(L, 2);
} else {
size_t ssz;
msg = luaL_checklstring(L,1,&ssz);
sz = (int)ssz;
}
switch (msg[0]) {
case 0:
return unpackreq_number(L, (const uint8_t *)msg, sz);
case 1:
return unpackmreq_number(L, (const uint8_t *)msg, sz);
return unpackmreq_number(L, (const uint8_t *)msg, sz, 0); // request
case '\x41':
return unpackmreq_number(L, (const uint8_t *)msg, sz, 1); // push
case 2:
case 3:
return unpackmreq_part(L, (const uint8_t *)msg, sz);
case 4:
return unpacktrace(L, msg, sz);
case '\x80':
return unpackreq_string(L, (const uint8_t *)msg, sz);
case '\x81':
return unpackmreq_string(L, (const uint8_t *)msg, sz);
return unpackmreq_string(L, (const uint8_t *)msg, sz, 0 ); // request
case '\xc1':
return unpackmreq_string(L, (const uint8_t *)msg, sz, 1 ); // push
default:
return luaL_error(L, "Invalid req package type %d", msg[0]);
}
}
/*
The response package :
WORD size (big endian)
DWORD session
BYTE type
0: error
@@ -442,6 +523,32 @@ lunpackresponse(lua_State *L) {
}
}
/*
table
pointer
sz
push (pointer/sz) as string into table, and free pointer
*/
static int
lappend(lua_State *L) {
luaL_checktype(L, 1, LUA_TTABLE);
int n = lua_rawlen(L, 1);
if (lua_isnil(L, 2)) {
lua_settop(L, 3);
lua_seti(L, 1, n + 1);
return 0;
}
void * buffer = lua_touserdata(L, 2);
if (buffer == NULL)
return luaL_error(L, "Need lightuserdata");
int sz = luaL_checkinteger(L, 3);
lua_pushlstring(L, (const char *)buffer, sz);
skynet_free((void *)buffer);
lua_seti(L, 1, n+1);
return 0;
}
static int
lconcat(lua_State *L) {
if (!lua_istable(L,1))
@@ -475,14 +582,41 @@ lconcat(lua_State *L) {
return 2;
}
int
luaopen_cluster_core(lua_State *L) {
static int
lisname(lua_State *L) {
const char * name = lua_tostring(L, 1);
if (name && name[0] == '@') {
lua_pushboolean(L, 1);
return 1;
}
return 0;
}
static int
lnodename(lua_State *L) {
pid_t pid = getpid();
char hostname[256];
if (gethostname(hostname, sizeof(hostname))==0) {
lua_pushfstring(L, "%s%d", hostname, (int)pid);
} else {
lua_pushfstring(L, "noname%d", (int)pid);
}
return 1;
}
LUAMOD_API int
luaopen_skynet_cluster_core(lua_State *L) {
luaL_Reg l[] = {
{ "packrequest", lpackrequest },
{ "packpush", lpackpush },
{ "packtrace", lpacktrace },
{ "unpackrequest", lunpackrequest },
{ "packresponse", lpackresponse },
{ "unpackresponse", lunpackresponse },
{ "append", lappend },
{ "concat", lconcat },
{ "isname", lisname },
{ "nodename", lnodename },
{ NULL, NULL },
};
luaL_checkversion(L);

View File

@@ -1,3 +1,5 @@
#define LUA_LIB
#include <lua.h>
#include <lauxlib.h>
@@ -5,6 +7,7 @@
#include <stdint.h>
#include <string.h>
#include <stdlib.h>
#include <unistd.h>
#define SMALL_CHUNK 256
@@ -494,7 +497,7 @@ static int
lfromhex(lua_State *L) {
size_t sz = 0;
const char * text = luaL_checklstring(L, 1, &sz);
if (sz & 2) {
if (sz & 1) {
return luaL_error(L, "Invalid hex text size %d", (int)sz);
}
char tmp[SMALL_CHUNK];
@@ -517,7 +520,7 @@ lfromhex(lua_State *L) {
}
// Constants are the integer part of the sines of integers (in radians) * 2^32.
const uint32_t k[64] = {
static const uint32_t k[64] = {
0xd76aa478, 0xe8c7b756, 0x242070db, 0xc1bdceee ,
0xf57c0faf, 0x4787c62a, 0xa8304613, 0xfd469501 ,
0x698098d8, 0x8b44f7af, 0xffff5bb1, 0x895cd7be ,
@@ -536,17 +539,16 @@ const uint32_t k[64] = {
0xf7537e82, 0xbd3af235, 0x2ad7d2bb, 0xeb86d391 };
// r specifies the per-round shift amounts
const uint32_t r[] = {7, 12, 17, 22, 7, 12, 17, 22, 7, 12, 17, 22, 7, 12, 17, 22,
static const uint32_t r[] = {7, 12, 17, 22, 7, 12, 17, 22, 7, 12, 17, 22, 7, 12, 17, 22,
5, 9, 14, 20, 5, 9, 14, 20, 5, 9, 14, 20, 5, 9, 14, 20,
4, 11, 16, 23, 4, 11, 16, 23, 4, 11, 16, 23, 4, 11, 16, 23,
6, 10, 15, 21, 6, 10, 15, 21, 6, 10, 15, 21, 6, 10, 15, 21};
// leftrotate function definition
#define LEFTROTATE(x, c) (((x) << (c)) | ((x) >> (32 - (c))))
static void
hmac(uint32_t x[2], uint32_t y[2], uint32_t result[2]) {
uint32_t w[16];
digest_md5(uint32_t w[16], uint32_t result[4]) {
uint32_t a, b, c, d, f, g, temp;
int i;
@@ -555,13 +557,6 @@ hmac(uint32_t x[2], uint32_t y[2], uint32_t result[2]) {
c = 0x98badcfeu;
d = 0x10325476u;
for (i=0;i<16;i+=4) {
w[i] = x[1];
w[i+1] = x[0];
w[i+2] = y[1];
w[i+3] = y[0];
}
for(i = 0; i<64; i++) {
if (i < 16) {
f = (b & c) | ((~b) & d);
@@ -582,11 +577,54 @@ hmac(uint32_t x[2], uint32_t y[2], uint32_t result[2]) {
c = b;
b = b + LEFTROTATE((a + f + k[i] + w[g]), r[i]);
a = temp;
}
result[0] = c^d;
result[1] = a^b;
result[0] = a;
result[1] = b;
result[2] = c;
result[3] = d;
}
// hmac64 use md5 algorithm without padding, and the result is (c^d .. a^b)
static void
hmac(uint32_t x[2], uint32_t y[2], uint32_t result[2]) {
uint32_t w[16];
uint32_t r[4];
int i;
for (i=0;i<16;i+=4) {
w[i] = x[1];
w[i+1] = x[0];
w[i+2] = y[1];
w[i+3] = y[0];
}
digest_md5(w,r);
result[0] = r[2]^r[3];
result[1] = r[0]^r[1];
}
static void
hmac_md5(uint32_t x[2], uint32_t y[2], uint32_t result[2]) {
uint32_t w[16];
uint32_t r[4];
int i;
for (i=0;i<12;i+=4) {
w[i] = x[0];
w[i+1] = x[1];
w[i+2] = y[0];
w[i+3] = y[1];
}
w[12] = 0x80;
w[13] = 0;
w[14] = 384;
w[15] = 0;
digest_md5(w,r);
result[0] = (r[0] + 0x67452301u) ^ (r[2] + 0x98badcfeu);
result[1] = (r[1] + 0xefcdab89u) ^ (r[3] + 0x10325476u);
}
static void
@@ -631,6 +669,21 @@ lhmac64(lua_State *L) {
return pushqword(L, result);
}
/*
h1 = crypt.hmac64_md5(a,b)
m = md5.sum((a..b):rep(3))
h2 = crypt.xor_str(m:sub(1,8), m:sub(9,16))
assert(h1 == h2)
*/
static int
lhmac64_md5(lua_State *L) {
uint32_t x[2], y[2];
read64(L, x, y);
uint32_t result[2];
hmac_md5(x,y,result);
return pushqword(L, result);
}
/*
8bytes key
string text
@@ -901,14 +954,14 @@ lxor_str(lua_State *L) {
int lsha1(lua_State *L);
int lhmac_sha1(lua_State *L);
int
luaopen_crypt(lua_State *L) {
LUAMOD_API int
luaopen_skynet_crypt(lua_State *L) {
luaL_checkversion(L);
static int init = 0;
if (!init) {
// Don't need call srandom more than once.
init = 1 ;
srandom(time(NULL));
srandom((random() << 8) ^ (time(NULL) << 16) ^ getpid());
}
luaL_Reg l[] = {
{ "hashkey", lhashkey },
@@ -918,6 +971,7 @@ luaopen_crypt(lua_State *L) {
{ "hexencode", ltohex },
{ "hexdecode", lfromhex },
{ "hmac64", lhmac64 },
{ "hmac64_md5", lhmac64_md5 },
{ "dhexchange", ldhexchange },
{ "dhsecret", ldhsecret },
{ "base64encode", lb64encode },
@@ -931,3 +985,8 @@ luaopen_crypt(lua_State *L) {
luaL_newlib(L,l);
return 1;
}
LUAMOD_API int
luaopen_client_crypt(lua_State *L) {
return luaopen_skynet_crypt(L);
}

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