mirror of
https://github.com/cloudwu/skynet.git
synced 2026-07-23 11:33:09 +00:00
Compare commits
203 Commits
v1.0.0-rc4
...
v1.1.0
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
ba59b879ad | ||
|
|
1e9e16f16b | ||
|
|
ece075ef6e | ||
|
|
c4c429b699 | ||
|
|
21f881910b | ||
|
|
37157273ff | ||
|
|
460ed2e9e2 | ||
|
|
03ce7ab385 | ||
|
|
1c605bed2b | ||
|
|
55136b77ad | ||
|
|
d8798a280a | ||
|
|
c8d6ffd393 | ||
|
|
100329f09f | ||
|
|
553c30c6d1 | ||
|
|
415459e656 | ||
|
|
596e8cfab2 | ||
|
|
dab4419335 | ||
|
|
932ebfa0fd | ||
|
|
9d74307836 | ||
|
|
7be5ea0148 | ||
|
|
525279e9dd | ||
|
|
d0fbf0802f | ||
|
|
fad154f474 | ||
|
|
40543d42d5 | ||
|
|
fa763181c0 | ||
|
|
e48e6c40e7 | ||
|
|
64a318a9f1 | ||
|
|
5e50aeab2b | ||
|
|
53fef98acf | ||
|
|
f94ca6f4b3 | ||
|
|
90536e4a0d | ||
|
|
9c37f5292a | ||
|
|
23ee7dd814 | ||
|
|
990bede9b2 | ||
|
|
b8d18d198e | ||
|
|
6d81c2b818 | ||
|
|
f966199f28 | ||
|
|
793fa4fdeb | ||
|
|
814cd31cee | ||
|
|
bf9466d568 | ||
|
|
317b4fb08f | ||
|
|
2b5c5e3dd3 | ||
|
|
d6eb49e4eb | ||
|
|
751517d7c1 | ||
|
|
03acc7f5a9 | ||
|
|
9320d8b28d | ||
|
|
86883c7d9a | ||
|
|
2553afd6c9 | ||
|
|
9fc8754369 | ||
|
|
ba59ed2e6c | ||
|
|
14aab9085a | ||
|
|
eb2bc91e3f | ||
|
|
38171f3bc9 | ||
|
|
72b6039328 | ||
|
|
c10cceb1f7 | ||
|
|
7dd78ec89d | ||
|
|
01032087ec | ||
|
|
933f6730b2 | ||
|
|
2b7b51614c | ||
|
|
a9122a9fe1 | ||
|
|
78ea3d4091 | ||
|
|
b3c60d1de2 | ||
|
|
b438d5a6b0 | ||
|
|
aa42534208 | ||
|
|
171f8eef01 | ||
|
|
e96b4e782d | ||
|
|
626ad544b7 | ||
|
|
c53da829d3 | ||
|
|
eeb06014da | ||
|
|
cc138adda9 | ||
|
|
5632dbeec3 | ||
|
|
8ca47f76bf | ||
|
|
48e031f2fb | ||
|
|
5479848df6 | ||
|
|
52026eb8f2 | ||
|
|
af1769aa25 | ||
|
|
953fa2c819 | ||
|
|
6f670685e2 | ||
|
|
9618dd47ce | ||
|
|
c72a133178 | ||
|
|
7a4189f830 | ||
|
|
a8b5b36737 | ||
|
|
6e36cf9940 | ||
|
|
1328895ff9 | ||
|
|
4e54a27500 | ||
|
|
a0ac8640c7 | ||
|
|
38e4d81fb1 | ||
|
|
2798c778c7 | ||
|
|
94374cf06f | ||
|
|
624fbf6f22 | ||
|
|
5aa3ed8d8f | ||
|
|
c7d2e2cb0e | ||
|
|
895c0dae3b | ||
|
|
1d364b5c22 | ||
|
|
5a4ebe6a73 | ||
|
|
2be915e3c7 | ||
|
|
f9f009a4c1 | ||
|
|
f1ed482001 | ||
|
|
8a6243d2a0 | ||
|
|
24537b3001 | ||
|
|
25763fc70b | ||
|
|
7400e51451 | ||
|
|
a504c5e624 | ||
|
|
648504119e | ||
|
|
acb0c57844 | ||
|
|
ea129cd9f6 | ||
|
|
4b2efd4785 | ||
|
|
72e3973cf9 | ||
|
|
d4eeb1ff28 | ||
|
|
fd427843a9 | ||
|
|
73e61a9cc6 | ||
|
|
cce8f0086a | ||
|
|
a7be332023 | ||
|
|
3fb46241f2 | ||
|
|
1153873321 | ||
|
|
000b46ec37 | ||
|
|
3b6b31266d | ||
|
|
89d771929a | ||
|
|
77ed1bd68b | ||
|
|
b7d79ff343 | ||
|
|
dab5a4e308 | ||
|
|
999a941110 | ||
|
|
ad36be1bd7 | ||
|
|
66f8fbd1b7 | ||
|
|
7b10ee8d56 | ||
|
|
62a4bcdc71 | ||
|
|
312943c6a0 | ||
|
|
61d13846cd | ||
|
|
8e7796a672 | ||
|
|
6fa241453c | ||
|
|
1f4a84edc2 | ||
|
|
6699279d53 | ||
|
|
2a79d7bed9 | ||
|
|
fd0291845f | ||
|
|
570a8356e6 | ||
|
|
6289b2b8e4 | ||
|
|
3a4a673b43 | ||
|
|
67b055009d | ||
|
|
80d9ec379f | ||
|
|
673ffcce00 | ||
|
|
6170346da2 | ||
|
|
b00b006c4a | ||
|
|
48034ae22e | ||
|
|
1cdc0d7558 | ||
|
|
cb19ab54e9 | ||
|
|
feab147563 | ||
|
|
f5911342e8 | ||
|
|
c6cbc2f6b6 | ||
|
|
ca290355fa | ||
|
|
2b55bc57a4 | ||
|
|
5c831e2465 | ||
|
|
521a387271 | ||
|
|
f25e396181 | ||
|
|
6fd1072fde | ||
|
|
d637d720db | ||
|
|
5c508e45a7 | ||
|
|
2e919505f1 | ||
|
|
af6b5609de | ||
|
|
9e90ee2dde | ||
|
|
8bc018fe20 | ||
|
|
2dbb0129d3 | ||
|
|
f10793e99b | ||
|
|
1e51af2d62 | ||
|
|
7ee9cdb29b | ||
|
|
a3eccf5e37 | ||
|
|
ace41d7c22 | ||
|
|
d0a41eb494 | ||
|
|
060e5384f5 | ||
|
|
0e6a106180 | ||
|
|
bac383441e | ||
|
|
3498bf9329 | ||
|
|
708d57a77e | ||
|
|
c5fb8ef3f7 | ||
|
|
ffe5de468e | ||
|
|
249ffb9362 | ||
|
|
07a1499886 | ||
|
|
9c6f8f8b82 | ||
|
|
f48eeca667 | ||
|
|
ccb0e1b24c | ||
|
|
18bc3216ae | ||
|
|
0782b355a4 | ||
|
|
c91efa5134 | ||
|
|
26ad20aa2b | ||
|
|
283c3f10fe | ||
|
|
2f23367671 | ||
|
|
c082d71a56 | ||
|
|
e2fa2a1a4d | ||
|
|
9882dd1cfd | ||
|
|
b278106336 | ||
|
|
97538286fd | ||
|
|
fd1b230a54 | ||
|
|
33321e89a1 | ||
|
|
b50e663a3a | ||
|
|
14a699cb85 | ||
|
|
098d44162b | ||
|
|
16af94795e | ||
|
|
00f41c6bc9 | ||
|
|
0465688403 | ||
|
|
8cd5834d28 | ||
|
|
040089639f | ||
|
|
81c4e47a6d | ||
|
|
2aef994aa4 | ||
|
|
ffa2bbf1e4 |
Submodule 3rd/jemalloc updated: 3de0353352...896ed3a8b3
@@ -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;
|
||||
|
||||
|
||||
|
||||
@@ -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) {
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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 © 2007-2015 Lua.org, PUC-Rio.
|
||||
Copyright © 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" -->
|
||||
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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,
|
||||
|
||||
@@ -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)
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
|
||||
|
||||
@@ -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++;
|
||||
|
||||
@@ -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 <- exp !.
|
||||
exp <- S (alternative / grammar)
|
||||
exp <- S (grammar / alternative)
|
||||
|
||||
alternative <- seq ('/' S seq)*
|
||||
seq <- 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" -->
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -19,7 +19,7 @@ SYSCFLAGS=
|
||||
SYSLDFLAGS=
|
||||
SYSLIBS=
|
||||
|
||||
MYCFLAGS=-I../../skynet-src
|
||||
MYCFLAGS=-I../../skynet-src -g
|
||||
MYLDFLAGS=
|
||||
MYLIBS=
|
||||
MYOBJS=
|
||||
|
||||
@@ -1012,7 +1012,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;
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
** $Id: lauxlib.c,v 1.286 2016/01/08 15:33:09 roberto Exp $
|
||||
** $Id: lauxlib.c,v 1.289 2016/12/20 18:37:00 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
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
** $Id: lauxlib.h,v 1.129 2015/11/23 11:29:43 roberto Exp $
|
||||
** $Id: lauxlib.h,v 1.131 2016/12/06 14:54:31 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;
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
** $Id: lbaselib.c,v 1.313 2016/04/11 19:18:40 roberto Exp $
|
||||
** $Id: lbaselib.c,v 1.314 2016/09/05 19:06: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 */
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
** $Id: lcode.c,v 2.109 2016/05/13 19:09:21 roberto Exp $
|
||||
** $Id: lcode.c,v 2.112 2016/12/22 13:08:50 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 */
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
** $Id: ldebug.c,v 2.120 2016/03/31 19:01:21 roberto Exp $
|
||||
** $Id: ldebug.c,v 2.121 2016/10/19 12:32:10 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);
|
||||
|
||||
226
3rd/lua/ldo.c
226
3rd/lua/ldo.c
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
** $Id: ldo.c,v 2.151 2015/12/16 16:40:07 roberto Exp $
|
||||
** $Id: ldo.c,v 2.157 2016/12/13 15:52:21 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);
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
** $Id: lgc.c,v 2.212 2016/03/31 19:02:03 roberto Exp $
|
||||
** $Id: lgc.c,v 2.215 2016/12/22 13:08:50 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? */
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
** $Id: linit.c,v 1.38 2015/01/05 13:48:33 roberto Exp $
|
||||
** $Id: linit.c,v 1.39 2016/12/04 20:17:24 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"
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
** $Id: liolib.c,v 2.149 2016/05/02 14:03:19 roberto Exp $
|
||||
** $Id: liolib.c,v 2.151 2016/12/20 18:37:00 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
|
||||
|
||||
@@ -618,8 +619,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 {
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
** $Id: lmathlib.c,v 1.117 2015/10/02 15:39:23 roberto Exp $
|
||||
** $Id: lmathlib.c,v 1.119 2016/12/22 13:08:50 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);
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
** $Id: loadlib.c,v 1.127 2015/11/23 11:30:45 roberto Exp $
|
||||
** $Id: loadlib.c,v 1.130 2017/01/12 17:14:26 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 */
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
** $Id: lobject.c,v 2.111 2016/05/20 14:07:48 roberto Exp $
|
||||
** $Id: lobject.c,v 2.113 2016/12/22 13:08:50 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) {
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
** $Id: lobject.h,v 2.116 2015/11/03 18:33:10 roberto Exp $
|
||||
** $Id: lobject.h,v 2.117 2016/08/01 19:51:24 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' */
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
** $Id: lopcodes.h,v 1.148 2014/10/25 11:50:46 roberto Exp $
|
||||
** $Id: lopcodes.h,v 1.149 2016/07/19 17:12:21 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)
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
** $Id: loslib.c,v 1.64 2016/04/18 13:06:55 roberto Exp $
|
||||
** $Id: loslib.c,v 1.65 2016/07/18 17:58:58 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);
|
||||
@@ -300,13 +303,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);
|
||||
}
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
** $Id: lparser.c,v 2.153 2016/05/13 19:10:16 roberto Exp $
|
||||
** $Id: lparser.c,v 2.155 2016/08/01 19:51:24 roberto Exp $
|
||||
** Lua Parser
|
||||
** See Copyright Notice in lua.h
|
||||
*/
|
||||
@@ -325,6 +325,8 @@ static void adjust_assign (LexState *ls, int nvars, int nexps, expdesc *e) {
|
||||
luaK_nil(fs, reg, extra);
|
||||
}
|
||||
}
|
||||
if (nexps > nvars)
|
||||
ls->fs->freereg -= nexps - nvars; /* remove extra values */
|
||||
}
|
||||
|
||||
|
||||
@@ -767,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");
|
||||
@@ -963,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;
|
||||
}
|
||||
@@ -1163,11 +1164,8 @@ static void assignment (LexState *ls, struct LHS_assign *lh, int nvars) {
|
||||
int nexps;
|
||||
checknext(ls, '=');
|
||||
nexps = explist(ls, &e);
|
||||
if (nexps != nvars) {
|
||||
if (nexps != nvars)
|
||||
adjust_assign(ls, nvars, nexps, &e);
|
||||
if (nexps > nvars)
|
||||
ls->fs->freereg -= nexps - nvars; /* remove extra values */
|
||||
}
|
||||
else {
|
||||
luaK_setoneret(ls->fs, &e); /* close last expression */
|
||||
luaK_storevar(ls->fs, &lh->v, &e);
|
||||
@@ -1397,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 semicolons */
|
||||
if (block_follow(ls, 0)) { /* 'goto' is the entire block? */
|
||||
leaveblock(fs);
|
||||
return; /* and that is it */
|
||||
@@ -1618,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 */
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
** $Id: lstate.h,v 2.130 2015/12/16 16:39:38 roberto Exp $
|
||||
** $Id: lstate.h,v 2.133 2016/12/22 13:08:50 roberto Exp $
|
||||
** Global State
|
||||
** See Copyright Notice in lua.h
|
||||
*/
|
||||
@@ -23,7 +23,7 @@
|
||||
**
|
||||
** '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).
|
||||
|
||||
@@ -34,7 +34,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 +66,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 +88,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 +104,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)
|
||||
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
** $Id: lstrlib.c,v 1.251 2016/05/20 14:13:21 roberto Exp $
|
||||
** $Id: lstrlib.c,v 1.254 2016/12/22 13:08:50 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;
|
||||
@@ -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': {
|
||||
@@ -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.
|
||||
*/
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
** $Id: ltable.c,v 2.117 2015/11/19 19:16:22 roberto Exp $
|
||||
** $Id: ltable.c,v 2.118 2016/11/07 12:38:35 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 */
|
||||
@@ -308,14 +306,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 +324,9 @@ 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 */
|
||||
}
|
||||
|
||||
|
||||
@@ -337,7 +335,7 @@ void luaH_resize (lua_State *L, Table *t, unsigned int nasize,
|
||||
unsigned int i;
|
||||
int j;
|
||||
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);
|
||||
@@ -354,7 +352,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 +360,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 +412,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 +420,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 +445,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 +453,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 +461,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 */
|
||||
@@ -651,7 +651,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 +664,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
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
** $Id: ltable.h,v 2.21 2015/11/03 15:47:30 roberto Exp $
|
||||
** $Id: ltable.h,v 2.23 2016/12/22 13:08:50 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))))
|
||||
@@ -51,7 +59,7 @@ LUAI_FUNC int 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
|
||||
|
||||
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
** $Id: ltm.c,v 2.37 2016/02/26 19:20:15 roberto Exp $
|
||||
** $Id: ltm.c,v 2.38 2016/12/22 13:08:50 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"
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
** $Id: lua.c,v 1.226 2015/08/14 19:11:20 roberto Exp $
|
||||
** $Id: lua.c,v 1.230 2017/01/12 17:14:26 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 /* }{ */
|
||||
@@ -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);
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
** $Id: lua.h,v 1.331 2016/05/30 15:53:28 roberto Exp $
|
||||
** $Id: lua.h,v 1.332 2016/12/22 15:51:20 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 "4"
|
||||
|
||||
#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-2017 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-2017 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
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
** $Id: luaconf.h,v 1.255 2016/05/01 20:06:09 roberto Exp $
|
||||
** $Id: luaconf.h,v 1.259 2016/12/22 13:08:50 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,14 @@
|
||||
|
||||
|
||||
/*
|
||||
@@ lua_number2strx converts a float to an hexadecimal numeric string.
|
||||
@@ 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 +744,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)))
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
** $Id: lualib.h,v 1.44 2014/02/06 17:32:33 roberto Exp $
|
||||
** $Id: lualib.h,v 1.45 2017/01/12 17:14:26 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);
|
||||
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
** $Id: lutf8lib.c,v 1.15 2015/03/28 19:16:55 roberto Exp $
|
||||
** $Id: lutf8lib.c,v 1.16 2016/12/22 13:08:50 roberto Exp $
|
||||
** Standard library for UTF-8 manipulation
|
||||
** See Copyright Notice in lua.h
|
||||
*/
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -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 */
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
** $Id: lvm.h,v 2.40 2016/01/05 16:07:21 roberto Exp $
|
||||
** $Id: lvm.h,v 2.41 2016/12/22 13:08:50 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);
|
||||
|
||||
48
HISTORY.md
48
HISTORY.md
@@ -1,3 +1,51 @@
|
||||
v1.1.0 (2017-10-31)
|
||||
-----------
|
||||
* add socket.disconnected()
|
||||
* fix bugs : see comments for detail
|
||||
|
||||
v1.1.0-rc (2017-7-18)
|
||||
-----------
|
||||
* config file : support include
|
||||
* debug console : User config binding IP
|
||||
* debug console : Add call command
|
||||
* debug console : Report error message of inject code
|
||||
* debug console : Change response message
|
||||
* sharedata : Add sharedata.flush
|
||||
* sharedata : Add sharedata.deepcopy
|
||||
* cluster : Add cluster.send
|
||||
* cluster : Add API to update config table
|
||||
* skynet : Add skynet.state
|
||||
* skynet : Keep the order of skynet.wakeup
|
||||
* skynet : Add a MEMORY_CHECK macro for debugging
|
||||
* httpc : Add httpc.timeout
|
||||
* mongo driver : sort support multi-key
|
||||
* bson : Check utf8 string
|
||||
* bson : No longer support numberic key
|
||||
* daemon mode: Can output the error messages
|
||||
* sproto : Support decimal number
|
||||
* sproto: Support binary type
|
||||
* sproto: Support response nil
|
||||
* crypt: Add crypt.hmac64_md5
|
||||
* redis: Add redis-cluster support
|
||||
* socket server : Optimize socket write (Try direct write from worker thread first)
|
||||
* Add prefix skynet to all skynet lua modules
|
||||
* datasheet : New module for replacement of sharedata
|
||||
* jemalloc : Update to 5.0.1
|
||||
* lua : Update to 5.3.4
|
||||
* lpeg : Update to 1.0.1
|
||||
|
||||
v1.0.0 (2016-7-11)
|
||||
-----------
|
||||
* Version 1.0.0 Released
|
||||
|
||||
v1.0.0-rc5 (2016-7-4)
|
||||
-----------
|
||||
* MongoDB : Support auth_scram_sha1
|
||||
* MongoDB : Auto determine primary host
|
||||
* Bugfix : memory leak in multicast
|
||||
* Bugfix : Lua 5.3.3
|
||||
* Bson : support meta array
|
||||
|
||||
v1.0.0-rc4 (2016-6-13)
|
||||
-----------
|
||||
* Update lua to 5.3.3
|
||||
|
||||
2
LICENSE
2
LICENSE
@@ -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
|
||||
|
||||
66
Makefile
66
Makefile
@@ -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)
|
||||
|
||||
10
README.md
10
README.md
@@ -1,3 +1,7 @@
|
||||
## Skynet
|
||||
|
||||
Skynet is a lightweight online game framework, and it can be used in many other fields.
|
||||
|
||||
## Build
|
||||
|
||||
For Linux, install autoconf first for jemalloc:
|
||||
@@ -28,13 +32,11 @@ Run these in different consoles:
|
||||
|
||||
## About Lua version
|
||||
|
||||
Skynet now uses a modified version of lua 5.3.3 ( http://www.lua.org/ftp/lua-5.3.3.tar.gz ) .
|
||||
|
||||
For details: http://lua-users.org/lists/lua-l/2014-03/msg00489.html
|
||||
Skynet now uses a modified version of lua 5.3.4 ( 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)
|
||||
|
||||
* Read Wiki https://github.com/cloudwu/skynet/wiki
|
||||
* Read Wiki for documents https://github.com/cloudwu/skynet/wiki
|
||||
* The FAQ in wiki https://github.com/cloudwu/skynet/wiki/FAQ
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
local skynet = require "skynet"
|
||||
local netpack = require "netpack"
|
||||
local socket = require "socket"
|
||||
local netpack = require "skynet.netpack"
|
||||
local socket = require "skynet.socket"
|
||||
local sproto = require "sproto"
|
||||
local sprotoloader = require "sprotoloader"
|
||||
|
||||
|
||||
@@ -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"
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
local skynet = require "skynet"
|
||||
local cluster = require "cluster"
|
||||
local cluster = require "skynet.cluster"
|
||||
|
||||
skynet.start(function()
|
||||
-- query name "sdb" of cluster db.
|
||||
@@ -11,9 +11,11 @@ skynet.start(function()
|
||||
print(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"))
|
||||
cluster.send("db2", sdb, "PING", "db2:longstring" .. largevalue)
|
||||
|
||||
-- test snax service
|
||||
local pingserver = cluster.snax("db", "pingserver")
|
||||
|
||||
@@ -1,4 +1,6 @@
|
||||
root = "./"
|
||||
include "config.path"
|
||||
|
||||
-- preload = "./examples/preload.lua" -- run preload.lua before every lua service run
|
||||
thread = 8
|
||||
logger = nil
|
||||
logpath = "."
|
||||
@@ -8,10 +10,6 @@ master = "127.0.0.1:2013"
|
||||
start = "main" -- main script
|
||||
bootstrap = "snlua bootstrap" -- The service for bootstrap
|
||||
standalone = "0.0.0.0:2013"
|
||||
luaservice = root.."service/?.lua;"..root.."test/?.lua;"..root.."examples/?.lua"
|
||||
lualoader = "lualib/loader.lua"
|
||||
-- preload = "./examples/preload.lua" -- run preload.lua before every lua service run
|
||||
snax = root.."examples/?.lua;"..root.."test/?.lua"
|
||||
-- snax_interface_g = "snax_g"
|
||||
cpath = root.."cservice/?.so"
|
||||
-- daemon = "./skynet.pid"
|
||||
|
||||
@@ -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"
|
||||
|
||||
6
examples/config.path
Normal file
6
examples/config.path
Normal 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"
|
||||
@@ -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"
|
||||
|
||||
@@ -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(...)
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
local login = require "snax.loginserver"
|
||||
local crypt = require "crypt"
|
||||
local crypt = require "skynet.crypt"
|
||||
local skynet = require "skynet"
|
||||
|
||||
local server = {
|
||||
|
||||
@@ -6,7 +6,9 @@ local max_client = 64
|
||||
skynet.start(function()
|
||||
skynet.error("Server start")
|
||||
skynet.uniqueservice("protoloader")
|
||||
local console = skynet.newservice("console")
|
||||
if not skynet.getenv "daemon" then
|
||||
local console = skynet.newservice("console")
|
||||
end
|
||||
skynet.newservice("debug_console",8000)
|
||||
skynet.newservice("simpledb")
|
||||
local watchdog = skynet.newservice("watchdog")
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
local skynet = require "skynet"
|
||||
local sharedata = require "sharedata"
|
||||
local sharedata = require "skynet.sharedata"
|
||||
|
||||
local mode = ...
|
||||
|
||||
|
||||
@@ -16,7 +16,17 @@ 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
|
||||
|
||||
@@ -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"
|
||||
|
||||
@@ -1,5 +1,4 @@
|
||||
local skynet = require "skynet"
|
||||
local netpack = require "netpack"
|
||||
|
||||
local CMD = {}
|
||||
local SOCKET = {}
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -1,3 +1,5 @@
|
||||
#define LUA_LIB
|
||||
|
||||
#include <lua.h>
|
||||
#include <lauxlib.h>
|
||||
|
||||
@@ -198,10 +200,50 @@ write_length(struct bson *b, int32_t v, int off) {
|
||||
b->ptr[off++] = (uv >> 24)&0xff;
|
||||
}
|
||||
|
||||
#define MAXUNICODE 0x10FFFF
|
||||
|
||||
static int
|
||||
utf8_copy(const char *s, char *d, size_t limit) {
|
||||
static const unsigned int limits[] = {0xFF, 0x7F, 0x7FF, 0xFFFF};
|
||||
unsigned int c = s[0];
|
||||
unsigned int res = 0;
|
||||
if (limit < 1)
|
||||
return 0;
|
||||
d[0] = s[0];
|
||||
if (c < 0x80) {
|
||||
return 1;
|
||||
} else {
|
||||
int count = 0;
|
||||
while (c & 0x40) {
|
||||
int cc = s[++count];
|
||||
if (limit <= count || (cc & 0xC0) != 0x80)
|
||||
return 0;
|
||||
d[count] = s[count];
|
||||
res = (res << 6) | (cc & 0x3F);
|
||||
c <<= 1;
|
||||
}
|
||||
res |= ((c & 0x7F) << (count * 5));
|
||||
if (count > 3 || res > MAXUNICODE || res <= limits[count])
|
||||
return 0;
|
||||
return count+1;
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
write_string(struct bson *b, const char *key, size_t sz) {
|
||||
write_string(struct bson *b, lua_State *L, const char *key, size_t sz) {
|
||||
bson_reserve(b,sz+1);
|
||||
memcpy(b->ptr + b->size, key, sz);
|
||||
char *dst = (char *)(b->ptr + b->size);
|
||||
const char *src = key;
|
||||
size_t n = sz;
|
||||
while(n > 0) {
|
||||
int c = utf8_copy(src, dst, n);
|
||||
if (c == 0) {
|
||||
luaL_error(L, "Invalid utf8 string");
|
||||
}
|
||||
src += c;
|
||||
dst += c;
|
||||
n -= c;
|
||||
}
|
||||
b->ptr[b->size+sz] = '\0';
|
||||
b->size+=sz+1;
|
||||
}
|
||||
@@ -238,12 +280,10 @@ write_double(struct bson *b, lua_Number d) {
|
||||
}
|
||||
}
|
||||
|
||||
static void pack_dict(lua_State *L, struct bson *b, bool array, int depth);
|
||||
|
||||
static inline void
|
||||
append_key(struct bson *bs, int type, const char *key, size_t sz) {
|
||||
append_key(struct bson *bs, lua_State *L, int type, const char *key, size_t sz) {
|
||||
write_byte(bs, type);
|
||||
write_string(bs, key, sz);
|
||||
write_string(bs, L, key, sz);
|
||||
}
|
||||
|
||||
static inline int
|
||||
@@ -256,38 +296,20 @@ append_number(struct bson *bs, lua_State *L, const char *key, size_t sz) {
|
||||
if (lua_isinteger(L, -1)) {
|
||||
int64_t i = lua_tointeger(L, -1);
|
||||
if (is_32bit(i)) {
|
||||
append_key(bs, BSON_INT32, key, sz);
|
||||
append_key(bs, L, BSON_INT32, key, sz);
|
||||
write_int32(bs, i);
|
||||
} else {
|
||||
append_key(bs, BSON_INT64, key, sz);
|
||||
append_key(bs, L, BSON_INT64, key, sz);
|
||||
write_int64(bs, i);
|
||||
}
|
||||
} else {
|
||||
lua_Number d = lua_tonumber(L,-1);
|
||||
append_key(bs, BSON_REAL, key, sz);
|
||||
append_key(bs, L, BSON_REAL, key, sz);
|
||||
write_double(bs, d);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
append_table(struct bson *bs, lua_State *L, const char *key, size_t sz, int depth) {
|
||||
size_t len = lua_rawlen(L, -1);
|
||||
bool isarray = false;
|
||||
if (len > 0) {
|
||||
lua_pushinteger(L, len);
|
||||
if (lua_next(L,-2) == 0) {
|
||||
isarray = true;
|
||||
} else {
|
||||
lua_pop(L,2);
|
||||
}
|
||||
}
|
||||
if (isarray) {
|
||||
append_key(bs, BSON_ARRAY, key, sz);
|
||||
} else {
|
||||
append_key(bs, BSON_DOCUMENT, key, sz);
|
||||
}
|
||||
pack_dict(L, bs, isarray, depth);
|
||||
}
|
||||
static void append_table(struct bson *bs, lua_State *L, const char *key, size_t sz, int depth);
|
||||
|
||||
static void
|
||||
write_binary(struct bson *b, const void * buffer, size_t sz) {
|
||||
@@ -306,7 +328,7 @@ append_one(struct bson *bs, lua_State *L, const char *key, size_t sz, int depth)
|
||||
append_number(bs, L, key, sz);
|
||||
break;
|
||||
case LUA_TUSERDATA: {
|
||||
append_key(bs, BSON_DOCUMENT, key, sz);
|
||||
append_key(bs, L, BSON_DOCUMENT, key, sz);
|
||||
int32_t * doc = lua_touserdata(L,-1);
|
||||
int32_t sz = *doc;
|
||||
bson_reserve(bs,sz);
|
||||
@@ -319,7 +341,7 @@ append_one(struct bson *bs, lua_State *L, const char *key, size_t sz, int depth)
|
||||
const char * str = lua_tolstring(L,-1,&len);
|
||||
if (len > 1 && str[0]==0) {
|
||||
int subt = (uint8_t)str[1];
|
||||
append_key(bs, subt, key, sz);
|
||||
append_key(bs, L, subt, key, sz);
|
||||
switch(subt) {
|
||||
case BSON_BINARY:
|
||||
write_binary(bs, str+2, len-2);
|
||||
@@ -365,8 +387,8 @@ append_one(struct bson *bs, lua_State *L, const char *key, size_t sz, int depth)
|
||||
break;
|
||||
}
|
||||
}
|
||||
write_string(bs, str, len-i-1);
|
||||
write_string(bs, str + len-i, i);
|
||||
write_string(bs, L, str, len-i-1);
|
||||
write_string(bs, L, str + len-i, i);
|
||||
break;
|
||||
}
|
||||
case BSON_MINKEY:
|
||||
@@ -379,9 +401,9 @@ append_one(struct bson *bs, lua_State *L, const char *key, size_t sz, int depth)
|
||||
} else {
|
||||
size_t len;
|
||||
const char * str = lua_tolstring(L,-1,&len);
|
||||
append_key(bs, BSON_STRING, key, sz);
|
||||
append_key(bs, L, BSON_STRING, key, sz);
|
||||
int off = reserve_length(bs);
|
||||
write_string(bs, str, len);
|
||||
write_string(bs, L, str, len);
|
||||
write_length(bs, len+1, off);
|
||||
}
|
||||
break;
|
||||
@@ -390,9 +412,11 @@ append_one(struct bson *bs, lua_State *L, const char *key, size_t sz, int depth)
|
||||
append_table(bs, L, key, sz, depth+1);
|
||||
break;
|
||||
case LUA_TBOOLEAN:
|
||||
append_key(bs, BSON_BOOLEAN, key, sz);
|
||||
append_key(bs, L, BSON_BOOLEAN, key, sz);
|
||||
write_byte(bs, lua_toboolean(L,-1));
|
||||
break;
|
||||
case LUA_TNIL:
|
||||
luaL_error(L, "Bson array has a hole (nil), Use bson.null instead");
|
||||
default:
|
||||
luaL_error(L, "Invalid value type : %s", lua_typename(L,vt));
|
||||
}
|
||||
@@ -409,65 +433,54 @@ bson_numstr( char *str, unsigned int i ) {
|
||||
}
|
||||
|
||||
static void
|
||||
pack_dict_data(lua_State *L, struct bson *b, bool isarray, int depth, int kt) {
|
||||
char numberkey[32];
|
||||
const char * key = NULL;
|
||||
size_t sz;
|
||||
if (isarray) {
|
||||
if (kt != LUA_TNUMBER) {
|
||||
luaL_error(L, "Invalid array key type : %s", lua_typename(L, kt));
|
||||
return;
|
||||
}
|
||||
sz = bson_numstr(numberkey, (unsigned int)lua_tointeger(L,-2)-1);
|
||||
key = numberkey;
|
||||
|
||||
append_one(b, L, key, sz, depth);
|
||||
lua_pop(L,1);
|
||||
} else {
|
||||
switch(kt) {
|
||||
case LUA_TNUMBER:
|
||||
// copy key, don't change key type
|
||||
lua_pushvalue(L,-2);
|
||||
lua_insert(L,-2);
|
||||
key = lua_tolstring(L,-2,&sz);
|
||||
append_one(b, L, key, sz, depth);
|
||||
lua_pop(L,2);
|
||||
break;
|
||||
case LUA_TSTRING:
|
||||
key = lua_tolstring(L,-2,&sz);
|
||||
append_one(b, L, key, sz, depth);
|
||||
lua_pop(L,1);
|
||||
break;
|
||||
default:
|
||||
luaL_error(L, "Invalid key type : %s", lua_typename(L, kt));
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
pack_simple_dict(lua_State *L, struct bson *b, bool isarray, int depth) {
|
||||
if (depth > MAX_DEPTH) {
|
||||
luaL_error(L, "Too depth while encoding bson");
|
||||
}
|
||||
luaL_checkstack(L, 16, NULL); // reserve enough stack space to pack table
|
||||
pack_array(lua_State *L, struct bson *b, int depth, size_t len) {
|
||||
int length = reserve_length(b);
|
||||
lua_pushnil(L);
|
||||
while(lua_next(L,-2) != 0) {
|
||||
int kt = lua_type(L, -2);
|
||||
pack_dict_data(L, b, isarray, depth, kt);
|
||||
size_t i;
|
||||
for (i=1;i<=len;i++) {
|
||||
char numberkey[32];
|
||||
size_t sz = bson_numstr(numberkey, i - 1);
|
||||
const char * key = numberkey;
|
||||
lua_geti(L, -1, i);
|
||||
append_one(b, L, key, sz, depth);
|
||||
lua_pop(L, 1);
|
||||
}
|
||||
write_byte(b,0);
|
||||
write_length(b, b->size - length, length);
|
||||
}
|
||||
|
||||
static void
|
||||
pack_dict_data(lua_State *L, struct bson *b, int depth, int kt) {
|
||||
const char * key = NULL;
|
||||
size_t sz;
|
||||
switch(kt) {
|
||||
case LUA_TNUMBER:
|
||||
luaL_error(L, "Bson dictionary's key can't be number");
|
||||
break;
|
||||
case LUA_TSTRING:
|
||||
key = lua_tolstring(L,-2,&sz);
|
||||
append_one(b, L, key, sz, depth);
|
||||
lua_pop(L,1);
|
||||
break;
|
||||
default:
|
||||
luaL_error(L, "Invalid key type : %s", lua_typename(L, kt));
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
pack_meta_dict(lua_State *L, struct bson *b, bool isarray, int depth) {
|
||||
if (depth > MAX_DEPTH) {
|
||||
luaL_error(L, "Too depth while encoding bson");
|
||||
pack_simple_dict(lua_State *L, struct bson *b, int depth) {
|
||||
int length = reserve_length(b);
|
||||
lua_pushnil(L);
|
||||
while(lua_next(L,-2) != 0) {
|
||||
int kt = lua_type(L, -2);
|
||||
pack_dict_data(L, b, depth, kt);
|
||||
}
|
||||
luaL_checkstack(L, 16, NULL); // reserve enough stack space to pack table
|
||||
write_byte(b,0);
|
||||
write_length(b, b->size - length, length);
|
||||
}
|
||||
|
||||
static void
|
||||
pack_meta_dict(lua_State *L, struct bson *b, int depth) {
|
||||
int length = reserve_length(b);
|
||||
|
||||
lua_pushvalue(L, -2); // push meta_obj
|
||||
@@ -483,18 +496,51 @@ pack_meta_dict(lua_State *L, struct bson *b, bool isarray, int depth) {
|
||||
lua_pop(L, 4); // pop all k, v, next_func, obj
|
||||
break;
|
||||
}
|
||||
pack_dict_data(L, b, isarray, depth, kt);
|
||||
pack_dict_data(L, b, depth, kt);
|
||||
}
|
||||
write_byte(b,0);
|
||||
write_length(b, b->size - length, length);
|
||||
}
|
||||
|
||||
static bool
|
||||
is_rawarray(lua_State *L) {
|
||||
size_t len = lua_rawlen(L, -1);
|
||||
if (len > 0) {
|
||||
lua_pushinteger(L, len);
|
||||
if (lua_next(L,-2) == 0) {
|
||||
return true;
|
||||
} else {
|
||||
lua_pop(L,2);
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
static void
|
||||
pack_dict(lua_State *L, struct bson *b, bool isarray, int depth) {
|
||||
if (luaL_getmetafield(L, -1, "__pairs") != LUA_TNIL) {
|
||||
pack_meta_dict(L, b, isarray, depth);
|
||||
append_table(struct bson *bs, lua_State *L, const char *key, size_t sz, int depth) {
|
||||
if (depth > MAX_DEPTH) {
|
||||
luaL_error(L, "Too depth while encoding bson");
|
||||
}
|
||||
luaL_checkstack(L, 16, NULL); // reserve enough stack space to pack table
|
||||
if (luaL_getmetafield(L, -1, "__len") != LUA_TNIL) {
|
||||
lua_pushvalue(L, -2);
|
||||
lua_call(L, 1, 1);
|
||||
if (!lua_isinteger(L, -1)) {
|
||||
luaL_error(L, "__len should return integer");
|
||||
}
|
||||
size_t len = lua_tointeger(L, -1);
|
||||
lua_pop(L, 1);
|
||||
append_key(bs, L, BSON_ARRAY, key, sz);
|
||||
pack_array(L, bs, depth, len);
|
||||
} else if (luaL_getmetafield(L, -1, "__pairs") != LUA_TNIL) {
|
||||
append_key(bs, L, BSON_DOCUMENT, key, sz);
|
||||
pack_meta_dict(L, bs, depth);
|
||||
} else if (is_rawarray(L)) {
|
||||
append_key(bs, L, BSON_ARRAY, key, sz);
|
||||
pack_array(L, bs, depth, lua_rawlen(L, -1));
|
||||
} else {
|
||||
pack_simple_dict(L, b, isarray, depth);
|
||||
append_key(bs, L, BSON_DOCUMENT, key, sz);
|
||||
pack_simple_dict(L, bs, depth);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -502,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);
|
||||
@@ -889,32 +937,66 @@ bson_meta(lua_State *L) {
|
||||
lua_setmetatable(L, -2);
|
||||
}
|
||||
|
||||
static int
|
||||
encode_bson(lua_State *L) {
|
||||
struct bson *b = lua_touserdata(L, 2);
|
||||
lua_settop(L, 1);
|
||||
if (luaL_getmetafield(L, -1, "__pairs") != LUA_TNIL) {
|
||||
pack_meta_dict(L, b, 0);
|
||||
} else {
|
||||
pack_simple_dict(L, b, 0);
|
||||
}
|
||||
void * ud = lua_newuserdata(L, b->size);
|
||||
memcpy(ud, b->ptr, b->size);
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int
|
||||
lencode(lua_State *L) {
|
||||
struct bson b;
|
||||
bson_create(&b);
|
||||
lua_settop(L,1);
|
||||
luaL_checktype(L, 1, LUA_TTABLE);
|
||||
pack_dict(L, &b, false, 0);
|
||||
void * ud = lua_newuserdata(L, b.size);
|
||||
memcpy(ud, b.ptr, b.size);
|
||||
bson_create(&b);
|
||||
lua_pushcfunction(L, encode_bson);
|
||||
lua_pushvalue(L, 1);
|
||||
lua_pushlightuserdata(L, &b);
|
||||
if (lua_pcall(L, 2, 1, 0) != LUA_OK) {
|
||||
bson_destroy(&b);
|
||||
return lua_error(L);
|
||||
}
|
||||
bson_destroy(&b);
|
||||
bson_meta(L);
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int
|
||||
encode_bson_byorder(lua_State *L) {
|
||||
int n = lua_gettop(L);
|
||||
struct bson *b = lua_touserdata(L, n);
|
||||
lua_settop(L, --n);
|
||||
pack_ordered_dict(L, b, n, 0);
|
||||
lua_settop(L,0);
|
||||
void * ud = lua_newuserdata(L, b->size);
|
||||
memcpy(ud, b->ptr, b->size);
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int
|
||||
lencode_order(lua_State *L) {
|
||||
struct bson b;
|
||||
bson_create(&b);
|
||||
int n = lua_gettop(L);
|
||||
if (n%2 != 0) {
|
||||
return luaL_error(L, "Invalid ordered dict");
|
||||
}
|
||||
pack_ordered_dict(L, &b, n, 0);
|
||||
lua_settop(L,1);
|
||||
void * ud = lua_newuserdata(L, b.size);
|
||||
memcpy(ud, b.ptr, b.size);
|
||||
bson_create(&b);
|
||||
lua_pushvalue(L, 1); // copy the first arg to n
|
||||
lua_pushcfunction(L, encode_bson_byorder);
|
||||
lua_replace(L, 1);
|
||||
lua_pushlightuserdata(L, &b);
|
||||
if (lua_pcall(L, n+1, 1, 0) != LUA_OK) {
|
||||
bson_destroy(&b);
|
||||
return lua_error(L);
|
||||
}
|
||||
bson_destroy(&b);
|
||||
bson_meta(L);
|
||||
return 1;
|
||||
@@ -1206,7 +1288,7 @@ lobjectid(lua_State *L) {
|
||||
return 1;
|
||||
}
|
||||
|
||||
int
|
||||
LUAMOD_API int
|
||||
luaopen_bson(lua_State *L) {
|
||||
luaL_checkversion(L);
|
||||
int i;
|
||||
|
||||
@@ -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 },
|
||||
|
||||
@@ -1,3 +1,5 @@
|
||||
#define LUA_LIB
|
||||
|
||||
#include <lua.h>
|
||||
#include <lauxlib.h>
|
||||
#include <string.h>
|
||||
@@ -35,7 +37,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 +47,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 +61,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
|
||||
@@ -71,14 +75,14 @@ fill_header(lua_State *L, uint8_t *buf, int sz) {
|
||||
PADDING msgpart(sz)
|
||||
*/
|
||||
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 +90,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 +100,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 +114,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 +122,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 +159,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,9 +173,9 @@ 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) {
|
||||
@@ -189,6 +193,16 @@ lpackrequest(lua_State *L) {
|
||||
}
|
||||
}
|
||||
|
||||
static int
|
||||
lpackrequest(lua_State *L) {
|
||||
return packrequest(L, 0);
|
||||
}
|
||||
|
||||
static int
|
||||
lpackpush(lua_State *L) {
|
||||
return packrequest(L, 1);
|
||||
}
|
||||
|
||||
/*
|
||||
string packed message
|
||||
return
|
||||
@@ -213,12 +227,17 @@ unpackreq_number(lua_State *L, const uint8_t * buf, int sz) {
|
||||
lua_pushinteger(L, address);
|
||||
lua_pushinteger(L, session);
|
||||
lua_pushlstring(L, (const char *)buf+9, sz-9);
|
||||
if (session == 0) {
|
||||
lua_pushnil(L);
|
||||
lua_pushboolean(L,1); // is_push, no reponse
|
||||
return 5;
|
||||
}
|
||||
|
||||
return 3;
|
||||
}
|
||||
|
||||
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);
|
||||
}
|
||||
@@ -229,8 +248,9 @@ unpackmreq_number(lua_State *L, const uint8_t * buf, int sz) {
|
||||
lua_pushinteger(L, session);
|
||||
lua_pushinteger(L, size);
|
||||
lua_pushboolean(L, 1); // padding multi part
|
||||
lua_pushboolean(L, is_push);
|
||||
|
||||
return 4;
|
||||
return 5;
|
||||
}
|
||||
|
||||
static int
|
||||
@@ -261,12 +281,17 @@ unpackreq_string(lua_State *L, const uint8_t * buf, int sz) {
|
||||
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);
|
||||
if (session == 0) {
|
||||
lua_pushnil(L);
|
||||
lua_pushboolean(L,1); // is_push, no reponse
|
||||
return 5;
|
||||
}
|
||||
|
||||
return 3;
|
||||
}
|
||||
|
||||
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);
|
||||
}
|
||||
@@ -280,8 +305,9 @@ unpackmreq_string(lua_State *L, const uint8_t * buf, int sz) {
|
||||
lua_pushinteger(L, session);
|
||||
lua_pushinteger(L, size);
|
||||
lua_pushboolean(L, 1); // padding multipart
|
||||
lua_pushboolean(L, is_push);
|
||||
|
||||
return 4;
|
||||
return 5;
|
||||
}
|
||||
|
||||
static int
|
||||
@@ -293,20 +319,26 @@ lunpackrequest(lua_State *L) {
|
||||
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 '\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
|
||||
@@ -475,10 +507,11 @@ lconcat(lua_State *L) {
|
||||
return 2;
|
||||
}
|
||||
|
||||
int
|
||||
luaopen_cluster_core(lua_State *L) {
|
||||
LUAMOD_API int
|
||||
luaopen_skynet_cluster_core(lua_State *L) {
|
||||
luaL_Reg l[] = {
|
||||
{ "packrequest", lpackrequest },
|
||||
{ "packpush", lpackpush },
|
||||
{ "unpackrequest", lunpackrequest },
|
||||
{ "packresponse", lpackresponse },
|
||||
{ "unpackresponse", lunpackresponse },
|
||||
|
||||
@@ -1,3 +1,5 @@
|
||||
#define LUA_LIB
|
||||
|
||||
#include <lua.h>
|
||||
#include <lauxlib.h>
|
||||
|
||||
@@ -494,7 +496,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 +519,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 +538,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 +556,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 +576,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 +668,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
|
||||
@@ -751,7 +803,7 @@ ldhexchange(lua_State *L) {
|
||||
if (x64 == 0)
|
||||
return luaL_error(L, "Can't be 0");
|
||||
|
||||
uint64_t r = powmodp(5, x64);
|
||||
uint64_t r = powmodp(G, x64);
|
||||
push64(L, r);
|
||||
return 1;
|
||||
}
|
||||
@@ -878,12 +930,31 @@ lb64decode(lua_State *L) {
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int
|
||||
lxor_str(lua_State *L) {
|
||||
size_t len1,len2;
|
||||
const char *s1 = luaL_checklstring(L,1,&len1);
|
||||
const char *s2 = luaL_checklstring(L,2,&len2);
|
||||
if (len2 == 0) {
|
||||
return luaL_error(L, "Can't xor empty string");
|
||||
}
|
||||
luaL_Buffer b;
|
||||
char * buffer = luaL_buffinitsize(L, &b, len1);
|
||||
int i;
|
||||
for (i=0;i<len1;i++) {
|
||||
buffer[i] = s1[i] ^ s2[i % len2];
|
||||
}
|
||||
luaL_addsize(&b, len1);
|
||||
luaL_pushresult(&b);
|
||||
return 1;
|
||||
}
|
||||
|
||||
// defined in lsha1.c
|
||||
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) {
|
||||
@@ -899,6 +970,7 @@ luaopen_crypt(lua_State *L) {
|
||||
{ "hexencode", ltohex },
|
||||
{ "hexdecode", lfromhex },
|
||||
{ "hmac64", lhmac64 },
|
||||
{ "hmac64_md5", lhmac64_md5 },
|
||||
{ "dhexchange", ldhexchange },
|
||||
{ "dhsecret", ldhsecret },
|
||||
{ "base64encode", lb64encode },
|
||||
@@ -906,8 +978,14 @@ luaopen_crypt(lua_State *L) {
|
||||
{ "sha1", lsha1 },
|
||||
{ "hmac_sha1", lhmac_sha1 },
|
||||
{ "hmac_hash", lhmac_hash },
|
||||
{ "xor_str", lxor_str },
|
||||
{ NULL, NULL },
|
||||
};
|
||||
luaL_newlib(L,l);
|
||||
return 1;
|
||||
}
|
||||
|
||||
LUAMOD_API int
|
||||
luaopen_client_crypt(lua_State *L) {
|
||||
return luaopen_skynet_crypt(L);
|
||||
}
|
||||
|
||||
372
lualib-src/lua-datasheet.c
Normal file
372
lualib-src/lua-datasheet.c
Normal file
@@ -0,0 +1,372 @@
|
||||
#include <lua.h>
|
||||
#include <lauxlib.h>
|
||||
#include <stdint.h>
|
||||
|
||||
#define NODECACHE "_ctable"
|
||||
#define PROXYCACHE "_proxy"
|
||||
#define TABLES "_ctables"
|
||||
|
||||
#define VALUE_NIL 0
|
||||
#define VALUE_INTEGER 1
|
||||
#define VALUE_REAL 2
|
||||
#define VALUE_BOOLEAN 3
|
||||
#define VALUE_TABLE 4
|
||||
#define VALUE_STRING 5
|
||||
#define VALUE_INVALID 6
|
||||
|
||||
#define INVALID_OFFSET 0xffffffff
|
||||
|
||||
struct proxy {
|
||||
const char * data;
|
||||
int index;
|
||||
};
|
||||
|
||||
struct document {
|
||||
uint32_t strtbl;
|
||||
uint32_t n;
|
||||
uint32_t index[1];
|
||||
// table[n]
|
||||
// strings
|
||||
};
|
||||
|
||||
struct table {
|
||||
uint32_t array;
|
||||
uint32_t dict;
|
||||
uint8_t type[1];
|
||||
// value[array]
|
||||
// kvpair[dict]
|
||||
};
|
||||
|
||||
static inline const struct table *
|
||||
gettable(const struct document *doc, int index) {
|
||||
if (doc->index[index] == INVALID_OFFSET) {
|
||||
return NULL;
|
||||
}
|
||||
return (const struct table *)((const char *)doc + sizeof(uint32_t) + sizeof(uint32_t) + doc->n * sizeof(uint32_t) + doc->index[index]);
|
||||
}
|
||||
|
||||
static void
|
||||
create_proxy(lua_State *L, const void *data, int index) {
|
||||
const struct table * t = gettable(data, index);
|
||||
if (t == NULL) {
|
||||
luaL_error(L, "Invalid index %d", index);
|
||||
}
|
||||
lua_getfield(L, LUA_REGISTRYINDEX, NODECACHE);
|
||||
if (lua_rawgetp(L, -1, t) == LUA_TTABLE) {
|
||||
lua_replace(L, -2);
|
||||
return;
|
||||
}
|
||||
lua_pop(L, 1);
|
||||
lua_newtable(L);
|
||||
lua_pushvalue(L, lua_upvalueindex(1));
|
||||
lua_setmetatable(L, -2);
|
||||
lua_pushvalue(L, -1);
|
||||
// NODECACHE, table, table
|
||||
lua_rawsetp(L, -3, t);
|
||||
// NODECACHE, table
|
||||
lua_getfield(L, LUA_REGISTRYINDEX, PROXYCACHE);
|
||||
// NODECACHE, table, PROXYCACHE
|
||||
lua_pushvalue(L, -2);
|
||||
// NODECACHE, table, PROXYCACHE, table
|
||||
struct proxy * p = lua_newuserdata(L, sizeof(struct proxy));
|
||||
// NODECACHE, table, PROXYCACHE, table, proxy
|
||||
p->data = data;
|
||||
p->index = index;
|
||||
lua_rawset(L, -3);
|
||||
// NODECACHE, table, PROXYCACHE
|
||||
lua_pop(L, 1);
|
||||
// NODECACHE, table
|
||||
lua_replace(L, -2);
|
||||
// table
|
||||
}
|
||||
|
||||
static void
|
||||
clear_table(lua_State *L) {
|
||||
int t = lua_gettop(L); // clear top table
|
||||
if (lua_type(L, t) != LUA_TTABLE) {
|
||||
luaL_error(L, "Invalid cache");
|
||||
}
|
||||
lua_pushnil(L);
|
||||
while (lua_next(L, t) != 0) {
|
||||
// key value
|
||||
lua_pop(L, 1);
|
||||
lua_pushvalue(L, -1);
|
||||
lua_pushnil(L);
|
||||
// key key nil
|
||||
lua_rawset(L, t);
|
||||
// key
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
update_cache(lua_State *L, const void *data, const void * newdata) {
|
||||
lua_getfield(L, LUA_REGISTRYINDEX, NODECACHE);
|
||||
int t = lua_gettop(L);
|
||||
lua_getfield(L, LUA_REGISTRYINDEX, PROXYCACHE);
|
||||
int pt = t + 1;
|
||||
lua_newtable(L); // temp table
|
||||
int nt = pt + 1;
|
||||
lua_pushnil(L);
|
||||
while (lua_next(L, t) != 0) {
|
||||
// pointer (-2) -> table (-1)
|
||||
lua_pushvalue(L, -1);
|
||||
if (lua_rawget(L, pt) == LUA_TUSERDATA) {
|
||||
// pointer, table, proxy
|
||||
struct proxy * p = lua_touserdata(L, -1);
|
||||
if (p->data == data) {
|
||||
// update to newdata
|
||||
p->data = newdata;
|
||||
const struct table * newt = gettable(newdata, p->index);
|
||||
lua_pop(L, 1);
|
||||
// pointer, table
|
||||
clear_table(L);
|
||||
lua_pushvalue(L, lua_upvalueindex(1));
|
||||
// pointer, table, meta
|
||||
lua_setmetatable(L, -2);
|
||||
// pointer, table
|
||||
if (newt) {
|
||||
lua_rawsetp(L, nt, newt);
|
||||
} else {
|
||||
lua_pop(L, 1);
|
||||
}
|
||||
// pointer
|
||||
lua_pushvalue(L, -1);
|
||||
lua_pushnil(L);
|
||||
lua_rawset(L, t);
|
||||
} else {
|
||||
lua_pop(L, 2);
|
||||
}
|
||||
} else {
|
||||
lua_pop(L, 2);
|
||||
// pointer
|
||||
}
|
||||
}
|
||||
// copy nt to t
|
||||
lua_pushnil(L);
|
||||
while (lua_next(L, nt) != 0) {
|
||||
lua_pushvalue(L, -2);
|
||||
lua_insert(L, -2);
|
||||
// key key value
|
||||
lua_rawset(L, t);
|
||||
}
|
||||
// NODECACHE PROXYCACHE TEMP
|
||||
lua_pop(L, 3);
|
||||
}
|
||||
|
||||
static int
|
||||
lupdate(lua_State *L) {
|
||||
lua_getfield(L, LUA_REGISTRYINDEX, PROXYCACHE);
|
||||
lua_pushvalue(L, 1);
|
||||
// PROXYCACHE, table
|
||||
if (lua_rawget(L, -2) != LUA_TUSERDATA) {
|
||||
luaL_error(L, "Invalid proxy table %p", lua_topointer(L, 1));
|
||||
}
|
||||
struct proxy * p = lua_touserdata(L, -1);
|
||||
luaL_checktype(L, 2, LUA_TLIGHTUSERDATA);
|
||||
const char * newdata = lua_touserdata(L, 2);
|
||||
update_cache(L, p->data, newdata);
|
||||
return 1;
|
||||
}
|
||||
|
||||
static inline uint32_t
|
||||
getuint32(const void *v) {
|
||||
union {
|
||||
uint32_t d;
|
||||
uint8_t t[4];
|
||||
} test = { 1 };
|
||||
if (test.t[0] == 0) {
|
||||
// big endian
|
||||
test.d = *(const uint32_t *)v;
|
||||
return test.t[0] | test.t[1] << 4 | test.t[2] << 8 | test.t[3] << 12;
|
||||
} else {
|
||||
return *(const uint32_t *)v;
|
||||
}
|
||||
}
|
||||
|
||||
static inline float
|
||||
getfloat(const void *v) {
|
||||
union {
|
||||
uint32_t d;
|
||||
float f;
|
||||
uint8_t t[4];
|
||||
} test = { 1 };
|
||||
if (test.t[0] == 0) {
|
||||
// big endian
|
||||
test.d = *(const uint32_t *)v;
|
||||
test.d = test.t[0] | test.t[1] << 4 | test.t[2] << 8 | test.t[3] << 12;
|
||||
return test.f;
|
||||
} else {
|
||||
return *(const float *)v;
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
pushvalue(lua_State *L, const void *v, int type, const struct document * doc) {
|
||||
switch (type) {
|
||||
case VALUE_NIL:
|
||||
lua_pushnil(L);
|
||||
break;
|
||||
case VALUE_INTEGER:
|
||||
lua_pushinteger(L, (int32_t)getuint32(v));
|
||||
break;
|
||||
case VALUE_REAL:
|
||||
lua_pushnumber(L, getfloat(v));
|
||||
break;
|
||||
case VALUE_BOOLEAN:
|
||||
lua_pushboolean(L, getuint32(v));
|
||||
break;
|
||||
case VALUE_TABLE:
|
||||
create_proxy(L, doc, getuint32(v));
|
||||
break;
|
||||
case VALUE_STRING:
|
||||
lua_pushstring(L, (const char *)doc + doc->strtbl + getuint32(v));
|
||||
break;
|
||||
default:
|
||||
luaL_error(L, "Invalid type %d at %p", type, v);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
copytable(lua_State *L, int tbl, struct proxy *p) {
|
||||
const struct document * doc = (const struct document *)p->data;
|
||||
if (p->index < 0 || p->index >= doc->n) {
|
||||
luaL_error(L, "Invalid proxy (index = %d, total = %d)", p->index, (int)doc->n);
|
||||
}
|
||||
const struct table * t = gettable(doc, p->index);
|
||||
if (t == NULL) {
|
||||
luaL_error(L, "Invalid proxy (index = %d)", p->index);
|
||||
}
|
||||
const uint32_t * v = (const uint32_t *)((const char *)t + sizeof(uint32_t) + sizeof(uint32_t) + ((t->array + t->dict + 3) & ~3));
|
||||
int i;
|
||||
for (i=0;i<t->array;i++) {
|
||||
pushvalue(L, v++, t->type[i], doc);
|
||||
lua_rawseti(L, tbl, i+1);
|
||||
}
|
||||
for (i=0;i<t->dict;i++) {
|
||||
pushvalue(L, v++, VALUE_STRING, doc);
|
||||
pushvalue(L, v++, t->type[t->array+i], doc);
|
||||
lua_rawset(L, tbl);
|
||||
}
|
||||
}
|
||||
|
||||
static int
|
||||
lnew(lua_State *L) {
|
||||
luaL_checktype(L, 1, LUA_TLIGHTUSERDATA);
|
||||
const char * data = lua_touserdata(L, 1);
|
||||
// hold ref to data
|
||||
lua_getfield(L, LUA_REGISTRYINDEX, TABLES);
|
||||
lua_pushvalue(L, 1);
|
||||
lua_rawsetp(L, -2, data);
|
||||
|
||||
create_proxy(L, data, 0);
|
||||
return 1;
|
||||
}
|
||||
|
||||
static void
|
||||
copyfromdata(lua_State *L) {
|
||||
lua_getfield(L, LUA_REGISTRYINDEX, PROXYCACHE);
|
||||
lua_pushvalue(L, 1);
|
||||
// PROXYCACHE, table
|
||||
if (lua_rawget(L, -2) != LUA_TUSERDATA) {
|
||||
luaL_error(L, "Invalid proxy table %p", lua_topointer(L, 1));
|
||||
}
|
||||
struct proxy * p = lua_touserdata(L, -1);
|
||||
lua_pop(L, 2);
|
||||
copytable(L, 1, p);
|
||||
lua_pushnil(L);
|
||||
lua_setmetatable(L, 1); // remove metatable
|
||||
}
|
||||
|
||||
static int
|
||||
lindex(lua_State *L) {
|
||||
copyfromdata(L);
|
||||
lua_rawget(L, 1);
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int
|
||||
lnext(lua_State *L) {
|
||||
luaL_checktype(L, 1, LUA_TTABLE);
|
||||
lua_settop(L, 2); /* create a 2nd argument if there isn't one */
|
||||
if (lua_next(L, 1))
|
||||
return 2;
|
||||
else {
|
||||
lua_pushnil(L);
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
|
||||
static int
|
||||
lpairs(lua_State *L) {
|
||||
copyfromdata(L);
|
||||
lua_pushcfunction(L, lnext);
|
||||
lua_pushvalue(L, 1);
|
||||
lua_pushnil(L);
|
||||
return 3;
|
||||
}
|
||||
|
||||
static int
|
||||
llen(lua_State *L) {
|
||||
copyfromdata(L);
|
||||
lua_pushinteger(L, lua_rawlen(L, 1));
|
||||
return 1;
|
||||
}
|
||||
|
||||
static void
|
||||
new_weak_table(lua_State *L, const char *mode) {
|
||||
lua_newtable(L); // NODECACHE { pointer:table }
|
||||
|
||||
lua_createtable(L, 0, 1); // weak meta table
|
||||
lua_pushstring(L, mode);
|
||||
lua_setfield(L, -2, "__mode");
|
||||
|
||||
lua_setmetatable(L, -2); // make NODECACHE weak
|
||||
}
|
||||
|
||||
static void
|
||||
gen_metatable(lua_State *L) {
|
||||
new_weak_table(L, "kv"); // NODECACHE { pointer:table }
|
||||
lua_setfield(L, LUA_REGISTRYINDEX, NODECACHE);
|
||||
|
||||
new_weak_table(L, "k"); // PROXYCACHE { table:userdata }
|
||||
lua_setfield(L, LUA_REGISTRYINDEX, PROXYCACHE);
|
||||
|
||||
lua_newtable(L);
|
||||
lua_setfield(L, LUA_REGISTRYINDEX, TABLES);
|
||||
|
||||
lua_createtable(L, 0, 1); // mod table
|
||||
|
||||
lua_createtable(L, 0, 2); // metatable
|
||||
luaL_Reg l[] = {
|
||||
{ "__index", lindex },
|
||||
{ "__pairs", lpairs },
|
||||
{ "__len", llen },
|
||||
{ NULL, NULL },
|
||||
};
|
||||
lua_pushvalue(L, -1);
|
||||
luaL_setfuncs(L, l, 1);
|
||||
}
|
||||
|
||||
static int
|
||||
lstringpointer(lua_State *L) {
|
||||
const char * str = luaL_checkstring(L, 1);
|
||||
lua_pushlightuserdata(L, (void *)str);
|
||||
return 1;
|
||||
}
|
||||
|
||||
LUAMOD_API int
|
||||
luaopen_skynet_datasheet_core(lua_State *L) {
|
||||
luaL_checkversion(L);
|
||||
luaL_Reg l[] = {
|
||||
{ "new", lnew },
|
||||
{ "update", lupdate },
|
||||
{ NULL, NULL },
|
||||
};
|
||||
|
||||
luaL_newlibtable(L,l);
|
||||
gen_metatable(L);
|
||||
luaL_setfuncs(L, l, 1);
|
||||
lua_pushcfunction(L, lstringpointer);
|
||||
lua_setfield(L, -2, "stringpointer");
|
||||
return 1;
|
||||
}
|
||||
@@ -1,3 +1,5 @@
|
||||
#define LUA_LIB
|
||||
|
||||
// only for debug use
|
||||
#include <lua.h>
|
||||
#include <lauxlib.h>
|
||||
@@ -268,8 +270,8 @@ static int db_sethook (lua_State *L) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
int
|
||||
luaopen_debugchannel(lua_State *L) {
|
||||
LUAMOD_API int
|
||||
luaopen_skynet_debugchannel(lua_State *L) {
|
||||
luaL_Reg l[] = {
|
||||
{ "create", lcreate }, // for write
|
||||
{ "connect", lconnect }, // for read
|
||||
|
||||
@@ -1,3 +1,5 @@
|
||||
#define LUA_LIB
|
||||
|
||||
#include <lua.h>
|
||||
#include <lauxlib.h>
|
||||
|
||||
@@ -47,8 +49,8 @@ lcurrent(lua_State *L) {
|
||||
return 1;
|
||||
}
|
||||
|
||||
int
|
||||
luaopen_memory(lua_State *L) {
|
||||
LUAMOD_API int
|
||||
luaopen_skynet_memory(lua_State *L) {
|
||||
luaL_checkversion(L);
|
||||
|
||||
luaL_Reg l[] = {
|
||||
|
||||
@@ -1,3 +1,5 @@
|
||||
#define LUA_LIB
|
||||
|
||||
#include "skynet_malloc.h"
|
||||
|
||||
#include <lua.h>
|
||||
@@ -529,8 +531,8 @@ reply_length(lua_State *L) {
|
||||
return 1;
|
||||
}
|
||||
|
||||
int
|
||||
luaopen_mongo_driver(lua_State *L) {
|
||||
LUAMOD_API int
|
||||
luaopen_skynet_mongo_driver(lua_State *L) {
|
||||
luaL_checkversion(L);
|
||||
luaL_Reg l[] ={
|
||||
{ "query", op_query },
|
||||
|
||||
@@ -1,3 +1,5 @@
|
||||
#define LUA_LIB
|
||||
|
||||
#include "skynet.h"
|
||||
|
||||
#include <lua.h>
|
||||
@@ -60,18 +62,6 @@ mc_packremote(lua_State *L) {
|
||||
return pack(L, msg, size);
|
||||
}
|
||||
|
||||
static int
|
||||
mc_packstring(lua_State *L) {
|
||||
size_t size;
|
||||
const char * msg = luaL_checklstring(L, 1, &size);
|
||||
if (size != (uint32_t)size) {
|
||||
return luaL_error(L, "string is too long");
|
||||
}
|
||||
void * data = skynet_malloc(size);
|
||||
memcpy(data, msg, size);
|
||||
return pack(L, data, size);
|
||||
}
|
||||
|
||||
/*
|
||||
lightuserdata struct mc_package **
|
||||
integer size (must be sizeof(struct mc_package *)
|
||||
@@ -82,7 +72,7 @@ static int
|
||||
mc_unpacklocal(lua_State *L) {
|
||||
struct mc_package ** pack = lua_touserdata(L,1);
|
||||
int sz = luaL_checkinteger(L,2);
|
||||
if (sz != sizeof(*pack)) {
|
||||
if (sz != sizeof(pack)) {
|
||||
return luaL_error(L, "Invalid multicast package size %d", sz);
|
||||
}
|
||||
lua_pushlightuserdata(L, *pack);
|
||||
@@ -108,6 +98,8 @@ mc_bindrefer(lua_State *L) {
|
||||
|
||||
lua_pushlightuserdata(L, *pack);
|
||||
|
||||
skynet_free(pack);
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
@@ -153,15 +145,14 @@ mc_nextid(lua_State *L) {
|
||||
return 1;
|
||||
}
|
||||
|
||||
int
|
||||
luaopen_multicast_core(lua_State *L) {
|
||||
LUAMOD_API int
|
||||
luaopen_skynet_multicast_core(lua_State *L) {
|
||||
luaL_Reg l[] = {
|
||||
{ "pack", mc_packlocal },
|
||||
{ "unpack", mc_unpacklocal },
|
||||
{ "bind", mc_bindrefer },
|
||||
{ "close", mc_closelocal },
|
||||
{ "remote", mc_remote },
|
||||
{ "packstring", mc_packstring },
|
||||
{ "packremote", mc_packremote },
|
||||
{ "nextid", mc_nextid },
|
||||
{ NULL, NULL },
|
||||
|
||||
@@ -1,9 +1,5 @@
|
||||
//
|
||||
// lua_mysqlaux.c
|
||||
//
|
||||
// Created by changfeng on 6/17/14.
|
||||
// Copyright (c) 2014 changfeng. All rights reserved.
|
||||
//
|
||||
#define LUA_LIB
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
@@ -162,7 +158,7 @@ static struct luaL_Reg mysqlauxlib[] = {
|
||||
};
|
||||
|
||||
|
||||
int luaopen_mysqlaux_c (lua_State *L) {
|
||||
LUAMOD_API int luaopen_skynet_mysqlaux_c (lua_State *L) {
|
||||
lua_newtable(L);
|
||||
luaL_setfuncs(L, mysqlauxlib, 0);
|
||||
return 1;
|
||||
|
||||
@@ -1,3 +1,5 @@
|
||||
#define LUA_LIB
|
||||
|
||||
#include "skynet_malloc.h"
|
||||
|
||||
#include "skynet_socket.h"
|
||||
@@ -462,8 +464,8 @@ ltostring(lua_State *L) {
|
||||
return 1;
|
||||
}
|
||||
|
||||
int
|
||||
luaopen_netpack(lua_State *L) {
|
||||
LUAMOD_API int
|
||||
luaopen_skynet_netpack(lua_State *L) {
|
||||
luaL_checkversion(L);
|
||||
luaL_Reg l[] = {
|
||||
{ "pop", lpop },
|
||||
|
||||
@@ -1,3 +1,5 @@
|
||||
#define LUA_LIB
|
||||
|
||||
#include <stdio.h>
|
||||
#include <lua.h>
|
||||
#include <lauxlib.h>
|
||||
@@ -50,20 +52,22 @@ diff_time(double start) {
|
||||
|
||||
static int
|
||||
lstart(lua_State *L) {
|
||||
if (lua_type(L,1) == LUA_TTHREAD) {
|
||||
if (lua_gettop(L) != 0) {
|
||||
lua_settop(L,1);
|
||||
luaL_checktype(L, 1, LUA_TTHREAD);
|
||||
} else {
|
||||
lua_pushthread(L);
|
||||
}
|
||||
lua_pushvalue(L, 1); // push coroutine
|
||||
lua_rawget(L, lua_upvalueindex(2));
|
||||
if (!lua_isnil(L, -1)) {
|
||||
return luaL_error(L, "Thread %p start profile more than once", lua_topointer(L, 1));
|
||||
}
|
||||
lua_pushthread(L);
|
||||
lua_pushvalue(L, 1); // push coroutine
|
||||
lua_pushnumber(L, 0);
|
||||
lua_rawset(L, lua_upvalueindex(2));
|
||||
|
||||
lua_pushthread(L);
|
||||
lua_pushvalue(L, 1); // push coroutine
|
||||
double ti = get_time();
|
||||
#ifdef DEBUG_LOG
|
||||
fprintf(stderr, "PROFILE [%p] start\n", L);
|
||||
@@ -76,32 +80,34 @@ lstart(lua_State *L) {
|
||||
|
||||
static int
|
||||
lstop(lua_State *L) {
|
||||
if (lua_type(L,1) == LUA_TTHREAD) {
|
||||
if (lua_gettop(L) != 0) {
|
||||
lua_settop(L,1);
|
||||
luaL_checktype(L, 1, LUA_TTHREAD);
|
||||
} else {
|
||||
lua_pushthread(L);
|
||||
}
|
||||
lua_pushvalue(L, 1); // push coroutine
|
||||
lua_rawget(L, lua_upvalueindex(1));
|
||||
if (lua_type(L, -1) != LUA_TNUMBER) {
|
||||
return luaL_error(L, "Call profile.start() before profile.stop()");
|
||||
}
|
||||
double ti = diff_time(lua_tonumber(L, -1));
|
||||
lua_pushthread(L);
|
||||
lua_pushvalue(L, 1); // push coroutine
|
||||
lua_rawget(L, lua_upvalueindex(2));
|
||||
double total_time = lua_tonumber(L, -1);
|
||||
|
||||
lua_pushthread(L);
|
||||
lua_pushvalue(L, 1); // push coroutine
|
||||
lua_pushnil(L);
|
||||
lua_rawset(L, lua_upvalueindex(1));
|
||||
|
||||
lua_pushthread(L);
|
||||
lua_pushvalue(L, 1); // push coroutine
|
||||
lua_pushnil(L);
|
||||
lua_rawset(L, lua_upvalueindex(2));
|
||||
|
||||
total_time += ti;
|
||||
lua_pushnumber(L, total_time);
|
||||
#ifdef DEBUG_LOG
|
||||
fprintf(stderr, "PROFILE [%p] stop (%lf / %lf)\n", L, ti, total_time);
|
||||
fprintf(stderr, "PROFILE [%p] stop (%lf/%lf)\n", lua_tothread(L,1), ti, total_time);
|
||||
#endif
|
||||
|
||||
return 1;
|
||||
@@ -109,18 +115,15 @@ lstop(lua_State *L) {
|
||||
|
||||
static int
|
||||
timing_resume(lua_State *L) {
|
||||
#ifdef DEBUG_LOG
|
||||
lua_State *from = lua_tothread(L, -1);
|
||||
#endif
|
||||
lua_pushvalue(L, -1);
|
||||
lua_rawget(L, lua_upvalueindex(2));
|
||||
if (lua_isnil(L, -1)) { // check total time
|
||||
lua_pop(L,1);
|
||||
lua_pop(L,2); // pop from coroutine
|
||||
} else {
|
||||
lua_pop(L,1);
|
||||
lua_pushvalue(L,1);
|
||||
double ti = get_time();
|
||||
#ifdef DEBUG_LOG
|
||||
fprintf(stderr, "PROFILE [%p] resume\n", from);
|
||||
fprintf(stderr, "PROFILE [%p] resume %lf\n", lua_tothread(L, -1), ti);
|
||||
#endif
|
||||
lua_pushnumber(L, ti);
|
||||
lua_rawset(L, lua_upvalueindex(1)); // set start time
|
||||
@@ -141,7 +144,7 @@ lresume(lua_State *L) {
|
||||
static int
|
||||
lresume_co(lua_State *L) {
|
||||
luaL_checktype(L, 2, LUA_TTHREAD);
|
||||
lua_rotate(L, 2, -1);
|
||||
lua_rotate(L, 2, -1); // 'from' coroutine rotate to the top(index -1)
|
||||
|
||||
return timing_resume(L);
|
||||
}
|
||||
@@ -151,14 +154,15 @@ timing_yield(lua_State *L) {
|
||||
#ifdef DEBUG_LOG
|
||||
lua_State *from = lua_tothread(L, -1);
|
||||
#endif
|
||||
lua_pushvalue(L, -1);
|
||||
lua_rawget(L, lua_upvalueindex(2)); // check total time
|
||||
if (lua_isnil(L, -1)) {
|
||||
lua_pop(L,1);
|
||||
lua_pop(L,2);
|
||||
} else {
|
||||
double ti = lua_tonumber(L, -1);
|
||||
lua_pop(L,1);
|
||||
|
||||
lua_pushthread(L);
|
||||
lua_pushvalue(L, -1); // push coroutine
|
||||
lua_rawget(L, lua_upvalueindex(1));
|
||||
double starttime = lua_tonumber(L, -1);
|
||||
lua_pop(L,1);
|
||||
@@ -169,9 +173,10 @@ timing_yield(lua_State *L) {
|
||||
fprintf(stderr, "PROFILE [%p] yield (%lf/%lf)\n", from, diff, ti);
|
||||
#endif
|
||||
|
||||
lua_pushthread(L);
|
||||
lua_pushvalue(L, -1); // push coroutine
|
||||
lua_pushnumber(L, ti);
|
||||
lua_rawset(L, lua_upvalueindex(2));
|
||||
lua_pop(L, 1); // pop coroutine
|
||||
}
|
||||
|
||||
lua_CFunction co_yield = lua_tocfunction(L, lua_upvalueindex(3));
|
||||
@@ -194,8 +199,8 @@ lyield_co(lua_State *L) {
|
||||
return timing_yield(L);
|
||||
}
|
||||
|
||||
int
|
||||
luaopen_profile(lua_State *L) {
|
||||
LUAMOD_API int
|
||||
luaopen_skynet_profile(lua_State *L) {
|
||||
luaL_checkversion(L);
|
||||
luaL_Reg l[] = {
|
||||
{ "start", lstart },
|
||||
|
||||
@@ -2,6 +2,8 @@
|
||||
modify from https://github.com/cloudwu/lua-serialize
|
||||
*/
|
||||
|
||||
#define LUA_LIB
|
||||
|
||||
#include "skynet_malloc.h"
|
||||
|
||||
#include <lua.h>
|
||||
@@ -594,7 +596,7 @@ luaseri_unpack(lua_State *L) {
|
||||
return lua_gettop(L) - 1;
|
||||
}
|
||||
|
||||
int
|
||||
LUAMOD_API int
|
||||
luaseri_pack(lua_State *L) {
|
||||
struct block temp;
|
||||
temp.next = NULL;
|
||||
|
||||
@@ -1,3 +1,5 @@
|
||||
#define LUA_LIB
|
||||
|
||||
#include <lua.h>
|
||||
#include <lauxlib.h>
|
||||
#include <stdint.h>
|
||||
@@ -762,8 +764,8 @@ lupdate(lua_State *L) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
int
|
||||
luaopen_sharedata_core(lua_State *L) {
|
||||
LUAMOD_API int
|
||||
luaopen_skynet_sharedata_core(lua_State *L) {
|
||||
luaL_Reg l[] = {
|
||||
// used by host
|
||||
{ "new", lnewconf },
|
||||
|
||||
@@ -1,3 +1,5 @@
|
||||
#define LUA_LIB
|
||||
|
||||
#include "skynet.h"
|
||||
#include "lua-seri.h"
|
||||
|
||||
@@ -126,15 +128,30 @@ lintcommand(lua_State *L) {
|
||||
const char * parm = NULL;
|
||||
char tmp[64]; // for integer parm
|
||||
if (lua_gettop(L) == 2) {
|
||||
int32_t n = (int32_t)luaL_checkinteger(L,2);
|
||||
sprintf(tmp, "%d", n);
|
||||
parm = tmp;
|
||||
if (lua_isnumber(L, 2)) {
|
||||
int32_t n = (int32_t)luaL_checkinteger(L,2);
|
||||
sprintf(tmp, "%d", n);
|
||||
parm = tmp;
|
||||
} else {
|
||||
parm = luaL_checkstring(L,2);
|
||||
}
|
||||
}
|
||||
|
||||
result = skynet_command(context, cmd, parm);
|
||||
if (result) {
|
||||
lua_Integer r = strtoll(result, NULL, 0);
|
||||
lua_pushinteger(L, r);
|
||||
char *endptr = NULL;
|
||||
lua_Integer r = strtoll(result, &endptr, 0);
|
||||
if (endptr == NULL || *endptr != '\0') {
|
||||
// may be real number
|
||||
double n = strtod(result, &endptr);
|
||||
if (endptr == NULL || *endptr != '\0') {
|
||||
return luaL_error(L, "Invalid result %s", result);
|
||||
} else {
|
||||
lua_pushnumber(L, n);
|
||||
}
|
||||
} else {
|
||||
lua_pushinteger(L, r);
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
return 0;
|
||||
@@ -157,17 +174,8 @@ get_dest_string(lua_State *L, int index) {
|
||||
return dest_string;
|
||||
}
|
||||
|
||||
/*
|
||||
uint32 address
|
||||
string address
|
||||
integer type
|
||||
integer session
|
||||
string message
|
||||
lightuserdata message_ptr
|
||||
integer len
|
||||
*/
|
||||
static int
|
||||
lsend(lua_State *L) {
|
||||
send_message(lua_State *L, int source, int idx_type) {
|
||||
struct skynet_context * context = lua_touserdata(L, lua_upvalueindex(1));
|
||||
uint32_t dest = (uint32_t)lua_tointeger(L, 1);
|
||||
const char * dest_string = NULL;
|
||||
@@ -178,68 +186,19 @@ lsend(lua_State *L) {
|
||||
dest_string = get_dest_string(L, 1);
|
||||
}
|
||||
|
||||
int type = luaL_checkinteger(L, 2);
|
||||
int type = luaL_checkinteger(L, idx_type+0);
|
||||
int session = 0;
|
||||
if (lua_isnil(L,3)) {
|
||||
if (lua_isnil(L,idx_type+1)) {
|
||||
type |= PTYPE_TAG_ALLOCSESSION;
|
||||
} else {
|
||||
session = luaL_checkinteger(L,3);
|
||||
session = luaL_checkinteger(L,idx_type+1);
|
||||
}
|
||||
|
||||
int mtype = lua_type(L,4);
|
||||
int mtype = lua_type(L,idx_type+2);
|
||||
switch (mtype) {
|
||||
case LUA_TSTRING: {
|
||||
size_t len = 0;
|
||||
void * msg = (void *)lua_tolstring(L,4,&len);
|
||||
if (len == 0) {
|
||||
msg = NULL;
|
||||
}
|
||||
if (dest_string) {
|
||||
session = skynet_sendname(context, 0, dest_string, type, session , msg, len);
|
||||
} else {
|
||||
session = skynet_send(context, 0, dest, type, session , msg, len);
|
||||
}
|
||||
break;
|
||||
}
|
||||
case LUA_TLIGHTUSERDATA: {
|
||||
void * msg = lua_touserdata(L,4);
|
||||
int size = luaL_checkinteger(L,5);
|
||||
if (dest_string) {
|
||||
session = skynet_sendname(context, 0, dest_string, type | PTYPE_TAG_DONTCOPY, session, msg, size);
|
||||
} else {
|
||||
session = skynet_send(context, 0, dest, type | PTYPE_TAG_DONTCOPY, session, msg, size);
|
||||
}
|
||||
break;
|
||||
}
|
||||
default:
|
||||
luaL_error(L, "skynet.send invalid param %s", lua_typename(L, lua_type(L,4)));
|
||||
}
|
||||
if (session < 0) {
|
||||
// send to invalid address
|
||||
// todo: maybe throw an error would be better
|
||||
return 0;
|
||||
}
|
||||
lua_pushinteger(L,session);
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int
|
||||
lredirect(lua_State *L) {
|
||||
struct skynet_context * context = lua_touserdata(L, lua_upvalueindex(1));
|
||||
uint32_t dest = (uint32_t)lua_tointeger(L,1);
|
||||
const char * dest_string = NULL;
|
||||
if (dest == 0) {
|
||||
dest_string = get_dest_string(L, 1);
|
||||
}
|
||||
uint32_t source = (uint32_t)luaL_checkinteger(L,2);
|
||||
int type = luaL_checkinteger(L,3);
|
||||
int session = luaL_checkinteger(L,4);
|
||||
|
||||
int mtype = lua_type(L,5);
|
||||
switch (mtype) {
|
||||
case LUA_TSTRING: {
|
||||
size_t len = 0;
|
||||
void * msg = (void *)lua_tolstring(L,5,&len);
|
||||
void * msg = (void *)lua_tolstring(L,idx_type+2,&len);
|
||||
if (len == 0) {
|
||||
msg = NULL;
|
||||
}
|
||||
@@ -251,8 +210,8 @@ lredirect(lua_State *L) {
|
||||
break;
|
||||
}
|
||||
case LUA_TLIGHTUSERDATA: {
|
||||
void * msg = lua_touserdata(L,5);
|
||||
int size = luaL_checkinteger(L,6);
|
||||
void * msg = lua_touserdata(L,idx_type+2);
|
||||
int size = luaL_checkinteger(L,idx_type+3);
|
||||
if (dest_string) {
|
||||
session = skynet_sendname(context, source, dest_string, type | PTYPE_TAG_DONTCOPY, session, msg, size);
|
||||
} else {
|
||||
@@ -261,9 +220,45 @@ lredirect(lua_State *L) {
|
||||
break;
|
||||
}
|
||||
default:
|
||||
luaL_error(L, "skynet.redirect invalid param %s", lua_typename(L,mtype));
|
||||
luaL_error(L, "invalid param %s", lua_typename(L, lua_type(L,idx_type+2)));
|
||||
}
|
||||
return 0;
|
||||
if (session < 0) {
|
||||
// send to invalid address
|
||||
// todo: maybe throw an error would be better
|
||||
return 0;
|
||||
}
|
||||
lua_pushinteger(L,session);
|
||||
return 1;
|
||||
}
|
||||
|
||||
/*
|
||||
uint32 address
|
||||
string address
|
||||
integer type
|
||||
integer session
|
||||
string message
|
||||
lightuserdata message_ptr
|
||||
integer len
|
||||
*/
|
||||
static int
|
||||
lsend(lua_State *L) {
|
||||
return send_message(L, 0, 2);
|
||||
}
|
||||
|
||||
/*
|
||||
uint32 address
|
||||
string address
|
||||
integer source_address
|
||||
integer type
|
||||
integer session
|
||||
string message
|
||||
lightuserdata message_ptr
|
||||
integer len
|
||||
*/
|
||||
static int
|
||||
lredirect(lua_State *L) {
|
||||
uint32_t source = (uint32_t)luaL_checkinteger(L,2);
|
||||
return send_message(L, source, 3);
|
||||
}
|
||||
|
||||
static int
|
||||
@@ -351,7 +346,7 @@ lnow(lua_State *L) {
|
||||
return 1;
|
||||
}
|
||||
|
||||
int
|
||||
LUAMOD_API int
|
||||
luaopen_skynet_core(lua_State *L) {
|
||||
luaL_checkversion(L);
|
||||
|
||||
|
||||
@@ -1,3 +1,5 @@
|
||||
#define LUA_LIB
|
||||
|
||||
#include "skynet_malloc.h"
|
||||
|
||||
#include <stdlib.h>
|
||||
@@ -87,8 +89,8 @@ lnewbuffer(lua_State *L) {
|
||||
Comment: The table pool record all the buffers chunk,
|
||||
and the first index [1] is a lightuserdata : free_node. We can always use this pointer for struct buffer_node .
|
||||
The following ([2] ...) userdatas in table pool is the buffer chunk (for struct buffer_node),
|
||||
we never free them until the VM closed. The size of first chunk ([2]) is 8 struct buffer_node,
|
||||
and the second size is 16 ... The largest size of chunk is LARGE_PAGE_NODE (4096)
|
||||
we never free them until the VM closed. The size of first chunk ([2]) is 16 struct buffer_node,
|
||||
and the second size is 32 ... The largest size of chunk is LARGE_PAGE_NODE (4096)
|
||||
|
||||
lpushbbuffer will get a free struct buffer_node from table pool, and then put the msg/size in it.
|
||||
lpopbuffer return the struct buffer_node back to table pool (By calling return_free_node).
|
||||
@@ -255,6 +257,9 @@ static int
|
||||
lclearbuffer(lua_State *L) {
|
||||
struct socket_buffer * sb = lua_touserdata(L, 1);
|
||||
if (sb == NULL) {
|
||||
if (lua_isnil(L, 1)) {
|
||||
return 0;
|
||||
}
|
||||
return luaL_error(L, "Need buffer object at param 1");
|
||||
}
|
||||
luaL_checktype(L,2,LUA_TTABLE);
|
||||
@@ -565,8 +570,9 @@ lsendlow(lua_State *L) {
|
||||
int id = luaL_checkinteger(L, 1);
|
||||
int sz = 0;
|
||||
void *buffer = get_buffer(L, 2, &sz);
|
||||
skynet_socket_send_lowpriority(ctx, id, buffer, sz);
|
||||
return 0;
|
||||
int err = skynet_socket_send_lowpriority(ctx, id, buffer, sz);
|
||||
lua_pushboolean(L, !err);
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int
|
||||
@@ -674,8 +680,8 @@ ludp_address(lua_State *L) {
|
||||
return 2;
|
||||
}
|
||||
|
||||
int
|
||||
luaopen_socketdriver(lua_State *L) {
|
||||
LUAMOD_API int
|
||||
luaopen_skynet_socketdriver(lua_State *L) {
|
||||
luaL_checkversion(L);
|
||||
luaL_Reg l[] = {
|
||||
{ "buffer", lnewbuffer },
|
||||
|
||||
@@ -1,3 +1,5 @@
|
||||
#define LUA_LIB
|
||||
|
||||
#include <lua.h>
|
||||
#include <lauxlib.h>
|
||||
#include <stdlib.h>
|
||||
@@ -232,8 +234,8 @@ lread(lua_State *L) {
|
||||
}
|
||||
}
|
||||
|
||||
int
|
||||
luaopen_stm(lua_State *L) {
|
||||
LUAMOD_API int
|
||||
luaopen_skynet_stm(lua_State *L) {
|
||||
luaL_checkversion(L);
|
||||
lua_createtable(L, 0, 3);
|
||||
|
||||
|
||||
@@ -82,7 +82,7 @@ lua-cjson | 4.92s | 8.30s | 183 bytes
|
||||
* pbc-lua is a google protocol buffers library https://github.com/cloudwu/pbc
|
||||
* lua-cjson is a json library https://github.com/efelix/lua-cjson
|
||||
|
||||
Lua API
|
||||
Parser
|
||||
=======
|
||||
|
||||
```lua
|
||||
@@ -93,24 +93,50 @@ local parser = require "sprotoparser"
|
||||
|
||||
The parser is needed for parsing the sproto schema. You can use it to generate binary string offline. The schema text and the parser is not needed when your program is running.
|
||||
|
||||
Lua API
|
||||
=======
|
||||
|
||||
```lua
|
||||
local sproto = require "sproto.core"
|
||||
local sproto = require "sproto"
|
||||
local sprotocore = require "sproto.core" -- optional
|
||||
```
|
||||
|
||||
* `sproto.newproto(sp)` creates a sproto object by a schema string (generates by parser).
|
||||
* `sproto.querytype(sp, typename)` queries a type object from a sproto object by typename.
|
||||
* `sproto.encode(st, luatable)` encodes a lua table by a type object, and generates a string message.
|
||||
* `sproto.decode(st, message)` decodes a message string generated by sproto.encode with type.
|
||||
* `sproto.pack(sprotomessage)` packs a string encoded by sproto.encode to reduce the size.
|
||||
* `sproto.unpack(packedmessage)` unpacks the string packed by sproto.pack.
|
||||
|
||||
The sproto supports protocol tag for RPC. Use `sproto.protocol(tagorname)` to convert the protocol name to the tag id, or convert back from tag id to the name, and returns the request/response message type objects of this protocol.
|
||||
* `sproto.new(spbin)` creates a sproto object by a schema binary string (generates by parser).
|
||||
* `sprotocore.newproto(spbin)` creates a sproto c object by a schema binary string (generates by parser).
|
||||
* `sproto.sharenew(spbin)` share a sproto object from a sproto c object (generates by sprotocore.newproto).
|
||||
* `sproto.parse(schema)` creares a sproto object by a schema text string (by calling parser.parse)
|
||||
* `sproto:exist_type(typename)` detect whether a type exist in sproto object.
|
||||
* `sproto:encode(typename, luatable)` encodes a lua table with typename into a binary string.
|
||||
* `sproto:decode(typename, blob [,sz])` decodes a binary string generated by sproto.encode with typename. If blob is a lightuserdata (C ptr), sz (integer) is needed.
|
||||
* `sproto:pencode(typename, luatable)` The same with sproto:encode, but pack (compress) the results.
|
||||
* `sproto:pdecode(typename, blob [,sz])` The same with sproto.decode, but unpack the blob (generated by sproto:pencode) first.
|
||||
* `sproto:default(typename, type)` Create a table with default values of typename. Type can be nil , "REQUEST", or "RESPONSE".
|
||||
|
||||
RPC API
|
||||
=======
|
||||
|
||||
There is a lua wrapper for the core API for RPC .
|
||||
|
||||
`sproto:host([packagename])` creates a host object to deliver the rpc message.
|
||||
|
||||
`host:dispatch(blob [,sz])` unpack and decode (sproto:pdecode) the binary string with type the host created (packagename).
|
||||
|
||||
If .type is exist, it's a REQUEST message with .type , returns "REQUEST", protoname, message, responser, .ud. The responser is a function for encode the response message. The responser will be nil when .session is not exist.
|
||||
|
||||
If .type is not exist, it's a RESPONSE message for .session . Returns "RESPONSE", .session, message, .ud .
|
||||
|
||||
`host:attach(sprotoobj)` creates a function(protoname, message, session, ud) to pack and encode request message with sprotoobj.
|
||||
|
||||
If you don't want to use host object, you can also use these following apis to encode and decode the rpc message:
|
||||
|
||||
`sproto:request_encode(protoname, tbl)` encode a request message with protoname.
|
||||
|
||||
`sproto:response_encode(protoname, tbl)` encode a response message with protoname.
|
||||
|
||||
`sproto:request_decode(protoname, blob [,sz])` decode a request message with protoname.
|
||||
|
||||
`sproto:response_decode(protoname, blob [,sz]` decode a response message with protoname.
|
||||
|
||||
Read testrpc.lua for detail.
|
||||
|
||||
Schema Language
|
||||
@@ -137,6 +163,8 @@ The schema text is like this:
|
||||
}
|
||||
|
||||
phone 3 : *PhoneNumber # *PhoneNumber means an array of PhoneNumber.
|
||||
height 4 : integer(2) # (2) means a 1/100 fixed-point number.
|
||||
data 5 : binary # Some binary data
|
||||
}
|
||||
|
||||
.AddressBook {
|
||||
@@ -159,7 +187,7 @@ A schema text can be self-described by the sproto schema language.
|
||||
.field {
|
||||
name 0 : string
|
||||
buildin 1 : integer
|
||||
type 2 : integer
|
||||
type 2 : integer # type is fixed-point number precision when buildin is SPROTO_TINTEGER; When buildin is SPROTO_TSTRING, it means binary string when type is 1.
|
||||
tag 3 : integer
|
||||
array 4 : boolean
|
||||
key 5 : integer # If key exists, array must be true, and it's a map.
|
||||
@@ -173,6 +201,7 @@ A schema text can be self-described by the sproto schema language.
|
||||
tag 1 : integer
|
||||
request 2 : integer # index
|
||||
response 3 : integer # index
|
||||
confirm 4 : boolean # response nil where confirm == true
|
||||
}
|
||||
|
||||
.group {
|
||||
@@ -184,8 +213,9 @@ A schema text can be self-described by the sproto schema language.
|
||||
Types
|
||||
=======
|
||||
|
||||
* **string** : binary string
|
||||
* **integer** : integer, the max length of an integer is signed 64bit.
|
||||
* **string** : string
|
||||
* **binary** : binary string (it's a sub type of string)
|
||||
* **integer** : integer, the max length of an integer is signed 64bit. It can be a fixed-point number with specified precision.
|
||||
* **boolean** : true or false
|
||||
|
||||
You can add * before the typename to declare an array.
|
||||
@@ -196,7 +226,7 @@ User defined type can be any name in alphanumeric characters except the build-in
|
||||
|
||||
* Where are double or real types?
|
||||
|
||||
I have been using Google protocol buffers for many years in many projects, and I found the real types were seldom used. If you really need it, you can use string to serialize the double numbers.
|
||||
I have been using Google protocol buffers for many years in many projects, and I found the real types were seldom used. If you really need it, you can use string to serialize the double numbers. When you need decimal, you can specify the fixed-point presision.
|
||||
|
||||
* Where is enum?
|
||||
|
||||
@@ -222,7 +252,7 @@ If n is odd, that means the tags is not continuous, and we should add current ta
|
||||
|
||||
Arrays are always encode in data part, 4 bytes header for the size, and the following bytes is the contents. See the example 2 for the struct array; example 3/4 for the integer array ; example 5 for the boolean array.
|
||||
|
||||
Fot integer array, an additional byte (4 or 8) to indicate the value is 32bit or 64bit.
|
||||
For integer array, an additional byte (4 or 8) to indicate the value is 32bit or 64bit.
|
||||
|
||||
Read the examples below to see more details.
|
||||
|
||||
@@ -436,6 +466,7 @@ struct sproto_arg {
|
||||
int length;
|
||||
int index; // array base 1
|
||||
int mainindex; // for map
|
||||
int extra; // SPROTO_TINTEGER: fixed-point presision ; SPROTO_TSTRING 0:utf8 string 1:binary
|
||||
};
|
||||
|
||||
typedef int (*sproto_callback)(const struct sproto_arg *args);
|
||||
|
||||
@@ -1,3 +1,5 @@
|
||||
#define LUA_LIB
|
||||
|
||||
#include <string.h>
|
||||
#include <stdlib.h>
|
||||
#include "msvcint.h"
|
||||
@@ -42,10 +44,10 @@ LUALIB_API void luaL_setfuncs (lua_State *L, const luaL_Reg *l, int nup) {
|
||||
#if LUA_VERSION_NUM < 503
|
||||
|
||||
#if LUA_VERSION_NUM < 502
|
||||
static lua_Integer lua_tointegerx(lua_State *L, int idx, int *isnum) {
|
||||
static int64_t lua_tointegerx(lua_State *L, int idx, int *isnum) {
|
||||
if (lua_isnumber(L, idx)) {
|
||||
if (isnum) *isnum = 1;
|
||||
return lua_tointeger(L, idx);
|
||||
return (int64_t)lua_tointeger(L, idx);
|
||||
}
|
||||
else {
|
||||
if (isnum) *isnum = 0;
|
||||
@@ -163,13 +165,20 @@ encode(const struct sproto_arg *args) {
|
||||
}
|
||||
switch (args->type) {
|
||||
case SPROTO_TINTEGER: {
|
||||
lua_Integer v;
|
||||
int64_t v;
|
||||
lua_Integer vh;
|
||||
int isnum;
|
||||
v = lua_tointegerx(L, -1, &isnum);
|
||||
if(!isnum) {
|
||||
return luaL_error(L, ".%s[%d] is not an integer (Is a %s)",
|
||||
args->tagname, args->index, lua_typename(L, lua_type(L, -1)));
|
||||
if (args->extra) {
|
||||
// It's decimal.
|
||||
lua_Number vn = lua_tonumber(L, -1);
|
||||
// use 64bit integer for 32bit architecture.
|
||||
v = (int64_t)(vn * args->extra + 0.5);
|
||||
} else {
|
||||
v = lua_tointegerx(L, -1, &isnum);
|
||||
if(!isnum) {
|
||||
return luaL_error(L, ".%s[%d] is not an integer (Is a %s)",
|
||||
args->tagname, args->index, lua_typename(L, lua_type(L, -1)));
|
||||
}
|
||||
}
|
||||
lua_pop(L,1);
|
||||
// notice: in lua 5.2, lua_Integer maybe 52bit
|
||||
@@ -267,7 +276,9 @@ lencode(lua_State *L) {
|
||||
int tbl_index = 2;
|
||||
struct sproto_type * st = lua_touserdata(L, 1);
|
||||
if (st == NULL) {
|
||||
return luaL_argerror(L, 1, "Need a sproto_type object");
|
||||
luaL_checktype(L, tbl_index, LUA_TNIL);
|
||||
lua_pushstring(L, "");
|
||||
return 1; // response nil
|
||||
}
|
||||
luaL_checktype(L, tbl_index, LUA_TTABLE);
|
||||
luaL_checkstack(L, ENCODE_DEEPLEVEL*2 + 8, NULL);
|
||||
@@ -332,8 +343,16 @@ decode(const struct sproto_arg *args) {
|
||||
switch (args->type) {
|
||||
case SPROTO_TINTEGER: {
|
||||
// notice: in lua 5.2, 52bit integer support (not 64)
|
||||
lua_Integer v = *(uint64_t*)args->value;
|
||||
lua_pushinteger(L, v);
|
||||
if (args->extra) {
|
||||
// lua_Integer is 32bit in small lua.
|
||||
int64_t v = *(int64_t*)args->value;
|
||||
lua_Number vn = (lua_Number)v;
|
||||
vn /= args->extra;
|
||||
lua_pushnumber(L, vn);
|
||||
} else {
|
||||
int64_t v = *(int64_t*)args->value;
|
||||
lua_pushinteger(L, v);
|
||||
}
|
||||
break;
|
||||
}
|
||||
case SPROTO_TBOOLEAN: {
|
||||
@@ -433,7 +452,8 @@ ldecode(lua_State *L) {
|
||||
size_t sz;
|
||||
int r;
|
||||
if (st == NULL) {
|
||||
return luaL_argerror(L, 1, "Need a sproto_type object");
|
||||
// return nil
|
||||
return 0;
|
||||
}
|
||||
sz = 0;
|
||||
buffer = getbuffer(L, 2, &sz);
|
||||
@@ -557,7 +577,11 @@ lprotocol(lua_State *L) {
|
||||
}
|
||||
response = sproto_protoquery(sp, tag, SPROTO_RESPONSE);
|
||||
if (response == NULL) {
|
||||
lua_pushnil(L);
|
||||
if (sproto_protoresponse(sp, tag)) {
|
||||
lua_pushlightuserdata(L, NULL); // response nil
|
||||
} else {
|
||||
lua_pushnil(L);
|
||||
}
|
||||
} else {
|
||||
lua_pushlightuserdata(L, response);
|
||||
}
|
||||
@@ -598,31 +622,49 @@ lloadproto(lua_State *L) {
|
||||
return 1;
|
||||
}
|
||||
|
||||
static void
|
||||
push_default(const struct sproto_arg *args, int array) {
|
||||
lua_State *L = args->ud;
|
||||
switch(args->type) {
|
||||
case SPROTO_TINTEGER:
|
||||
if (args->extra)
|
||||
lua_pushnumber(L, 0.0);
|
||||
else
|
||||
lua_pushinteger(L, 0);
|
||||
break;
|
||||
case SPROTO_TBOOLEAN:
|
||||
lua_pushboolean(L, 0);
|
||||
break;
|
||||
case SPROTO_TSTRING:
|
||||
lua_pushliteral(L, "");
|
||||
break;
|
||||
case SPROTO_TSTRUCT:
|
||||
if (array) {
|
||||
lua_pushstring(L, sproto_name(args->subtype));
|
||||
} else {
|
||||
lua_createtable(L, 0, 1);
|
||||
lua_pushstring(L, sproto_name(args->subtype));
|
||||
lua_setfield(L, -2, "__type");
|
||||
}
|
||||
break;
|
||||
default:
|
||||
luaL_error(L, "Invalid type %d", args->type);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
static int
|
||||
encode_default(const struct sproto_arg *args) {
|
||||
lua_State *L = args->ud;
|
||||
lua_pushstring(L, args->tagname);
|
||||
if (args->index > 0) {
|
||||
lua_newtable(L);
|
||||
push_default(args, 1);
|
||||
lua_setfield(L, -2, "__array");
|
||||
lua_rawset(L, -3);
|
||||
return SPROTO_CB_NOARRAY;
|
||||
} else {
|
||||
switch(args->type) {
|
||||
case SPROTO_TINTEGER:
|
||||
lua_pushinteger(L, 0);
|
||||
break;
|
||||
case SPROTO_TBOOLEAN:
|
||||
lua_pushboolean(L, 0);
|
||||
break;
|
||||
case SPROTO_TSTRING:
|
||||
lua_pushliteral(L, "");
|
||||
break;
|
||||
case SPROTO_TSTRUCT:
|
||||
lua_createtable(L, 0, 1);
|
||||
lua_pushstring(L, sproto_name(args->subtype));
|
||||
lua_setfield(L, -2, "__type");
|
||||
break;
|
||||
}
|
||||
push_default(args, 0);
|
||||
lua_rawset(L, -3);
|
||||
return SPROTO_CB_NIL;
|
||||
}
|
||||
@@ -660,7 +702,7 @@ ldefault(lua_State *L) {
|
||||
return 1;
|
||||
}
|
||||
|
||||
int
|
||||
LUAMOD_API int
|
||||
luaopen_sproto_core(lua_State *L) {
|
||||
#ifdef luaL_checkversion
|
||||
luaL_checkversion(L);
|
||||
|
||||
@@ -18,6 +18,7 @@ struct field {
|
||||
const char * name;
|
||||
struct sproto_type * st;
|
||||
int key;
|
||||
int extra;
|
||||
};
|
||||
|
||||
struct sproto_type {
|
||||
@@ -31,6 +32,7 @@ struct sproto_type {
|
||||
struct protocol {
|
||||
const char *name;
|
||||
int tag;
|
||||
int confirm; // confirm == 1 where response nil
|
||||
struct sproto_type * p[2];
|
||||
};
|
||||
|
||||
@@ -177,6 +179,18 @@ import_string(struct sproto *s, const uint8_t * stream) {
|
||||
return buffer;
|
||||
}
|
||||
|
||||
static int
|
||||
calc_pow(int base, int n) {
|
||||
int r;
|
||||
if (n == 0)
|
||||
return 1;
|
||||
r = calc_pow(base * base , n / 2);
|
||||
if (n&1) {
|
||||
r *= base;
|
||||
}
|
||||
return r;
|
||||
}
|
||||
|
||||
static const uint8_t *
|
||||
import_field(struct sproto *s, struct field *f, const uint8_t * stream) {
|
||||
uint32_t sz;
|
||||
@@ -190,6 +204,7 @@ import_field(struct sproto *s, struct field *f, const uint8_t * stream) {
|
||||
f->name = NULL;
|
||||
f->st = NULL;
|
||||
f->key = -1;
|
||||
f->extra = 0;
|
||||
|
||||
sz = todword(stream);
|
||||
stream += SIZEOF_LENGTH;
|
||||
@@ -222,12 +237,18 @@ import_field(struct sproto *s, struct field *f, const uint8_t * stream) {
|
||||
f->type = value;
|
||||
break;
|
||||
case 2: // type index
|
||||
if (value >= s->type_n)
|
||||
return NULL; // invalid type index
|
||||
if (f->type >= 0)
|
||||
return NULL;
|
||||
f->type = SPROTO_TSTRUCT;
|
||||
f->st = &s->type[value];
|
||||
if (f->type == SPROTO_TINTEGER) {
|
||||
f->extra = calc_pow(10, value);
|
||||
} else if (f->type == SPROTO_TSTRING) {
|
||||
f->extra = value; // string if 0 ; binary is 1
|
||||
} else {
|
||||
if (value >= s->type_n)
|
||||
return NULL; // invalid type index
|
||||
if (f->type >= 0)
|
||||
return NULL;
|
||||
f->type = SPROTO_TSTRUCT;
|
||||
f->st = &s->type[value];
|
||||
}
|
||||
break;
|
||||
case 3: // tag
|
||||
f->tag = value;
|
||||
@@ -344,6 +365,7 @@ import_protocol(struct sproto *s, struct protocol *p, const uint8_t * stream) {
|
||||
p->tag = -1;
|
||||
p->p[SPROTO_REQUEST] = NULL;
|
||||
p->p[SPROTO_RESPONSE] = NULL;
|
||||
p->confirm = 0;
|
||||
tag = 0;
|
||||
for (i=0;i<fn;i++,tag++) {
|
||||
int value = toword(stream + SIZEOF_FIELD * i);
|
||||
@@ -375,6 +397,9 @@ import_protocol(struct sproto *s, struct protocol *p, const uint8_t * stream) {
|
||||
return NULL;
|
||||
p->p[SPROTO_RESPONSE] = &s->type[value];
|
||||
break;
|
||||
case 4: // confirm
|
||||
p->confirm = value;
|
||||
break;
|
||||
default:
|
||||
return NULL;
|
||||
}
|
||||
@@ -463,11 +488,6 @@ sproto_release(struct sproto * s) {
|
||||
void
|
||||
sproto_dump(struct sproto *s) {
|
||||
int i,j;
|
||||
static const char * buildin[] = {
|
||||
"integer",
|
||||
"boolean",
|
||||
"string",
|
||||
};
|
||||
printf("=== %d types ===\n", s->type_n);
|
||||
for (i=0;i<s->type_n;i++) {
|
||||
struct sproto_type *t = &s->type[i];
|
||||
@@ -476,25 +496,45 @@ sproto_dump(struct sproto *s) {
|
||||
char array[2] = { 0, 0 };
|
||||
const char * type_name = NULL;
|
||||
struct field *f = &t->f[j];
|
||||
int type = f->type & ~SPROTO_TARRAY;
|
||||
if (f->type & SPROTO_TARRAY) {
|
||||
array[0] = '*';
|
||||
} else {
|
||||
array[0] = 0;
|
||||
}
|
||||
{
|
||||
int t = f->type & ~SPROTO_TARRAY;
|
||||
if (t == SPROTO_TSTRUCT) {
|
||||
type_name = f->st->name;
|
||||
} else {
|
||||
assert(t<SPROTO_TSTRUCT);
|
||||
type_name = buildin[t];
|
||||
if (type == SPROTO_TSTRUCT) {
|
||||
type_name = f->st->name;
|
||||
} else {
|
||||
switch(type) {
|
||||
case SPROTO_TINTEGER:
|
||||
if (f->extra) {
|
||||
type_name = "decimal";
|
||||
} else {
|
||||
type_name = "integer";
|
||||
}
|
||||
break;
|
||||
case SPROTO_TBOOLEAN:
|
||||
type_name = "boolean";
|
||||
break;
|
||||
case SPROTO_TSTRING:
|
||||
if (f->extra == SPROTO_TSTRING_BINARY)
|
||||
type_name = "binary";
|
||||
else
|
||||
type_name = "string";
|
||||
break;
|
||||
default:
|
||||
type_name = "invalid";
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (f->key >= 0) {
|
||||
printf("\t%s (%d) %s%s(%d)\n", f->name, f->tag, array, type_name, f->key);
|
||||
} else {
|
||||
printf("\t%s (%d) %s%s\n", f->name, f->tag, array, type_name);
|
||||
printf("\t%s (%d) %s%s", f->name, f->tag, array, type_name);
|
||||
if (type == SPROTO_TINTEGER && f->extra > 0) {
|
||||
printf("(%d)", f->extra);
|
||||
}
|
||||
if (f->key >= 0) {
|
||||
printf("[%d]", f->key);
|
||||
}
|
||||
printf("\n");
|
||||
}
|
||||
}
|
||||
printf("=== %d protocol ===\n", s->protocol_n);
|
||||
@@ -507,6 +547,8 @@ sproto_dump(struct sproto *s) {
|
||||
}
|
||||
if (p->p[SPROTO_RESPONSE]) {
|
||||
printf(" response:%s", p->p[SPROTO_RESPONSE]->name);
|
||||
} else if (p->confirm) {
|
||||
printf(" response nil");
|
||||
}
|
||||
printf("\n");
|
||||
}
|
||||
@@ -555,6 +597,12 @@ sproto_protoquery(const struct sproto *sp, int proto, int what) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
int
|
||||
sproto_protoresponse(const struct sproto * sp, int proto) {
|
||||
struct protocol * p = query_proto(sp, proto);
|
||||
return (p!=NULL && (p->p[SPROTO_RESPONSE] || p->confirm));
|
||||
}
|
||||
|
||||
const char *
|
||||
sproto_protoname(const struct sproto *sp, int proto) {
|
||||
struct protocol * p = query_proto(sp, proto);
|
||||
@@ -884,6 +932,7 @@ sproto_encode(const struct sproto_type *st, void * buffer, int size, sproto_call
|
||||
args.tagid = f->tag;
|
||||
args.subtype = f->st;
|
||||
args.mainindex = f->key;
|
||||
args.extra = f->extra;
|
||||
if (type & SPROTO_TARRAY) {
|
||||
args.type = type & ~SPROTO_TARRAY;
|
||||
sz = encode_array(cb, &args, data, size);
|
||||
@@ -1116,6 +1165,7 @@ sproto_decode(const struct sproto_type *st, const void * data, int size, sproto_
|
||||
args.subtype = f->st;
|
||||
args.index = 0;
|
||||
args.mainindex = f->key;
|
||||
args.extra = f->extra;
|
||||
if (value < 0) {
|
||||
if (f->type & SPROTO_TARRAY) {
|
||||
if (decode_array(cb, &args, currentdata)) {
|
||||
|
||||
@@ -9,11 +9,16 @@ struct sproto_type;
|
||||
#define SPROTO_REQUEST 0
|
||||
#define SPROTO_RESPONSE 1
|
||||
|
||||
// type (sproto_arg.type)
|
||||
#define SPROTO_TINTEGER 0
|
||||
#define SPROTO_TBOOLEAN 1
|
||||
#define SPROTO_TSTRING 2
|
||||
#define SPROTO_TSTRUCT 3
|
||||
|
||||
// sub type of string (sproto_arg.extra)
|
||||
#define SPROTO_TSTRING_STRING 0
|
||||
#define SPROTO_TSTRING_BINARY 1
|
||||
|
||||
#define SPROTO_CB_ERROR -1
|
||||
#define SPROTO_CB_NIL -2
|
||||
#define SPROTO_CB_NOARRAY -3
|
||||
@@ -25,6 +30,7 @@ int sproto_prototag(const struct sproto *, const char * name);
|
||||
const char * sproto_protoname(const struct sproto *, int proto);
|
||||
// SPROTO_REQUEST(0) : request, SPROTO_RESPONSE(1): response
|
||||
struct sproto_type * sproto_protoquery(const struct sproto *, int proto, int what);
|
||||
int sproto_protoresponse(const struct sproto *, int proto);
|
||||
|
||||
struct sproto_type * sproto_type(const struct sproto *, const char * type_name);
|
||||
|
||||
@@ -41,6 +47,7 @@ struct sproto_arg {
|
||||
int length;
|
||||
int index; // array base 1
|
||||
int mainindex; // for map
|
||||
int extra; // SPROTO_TINTEGER: decimal ; SPROTO_TSTRING 0:utf8 string 1:binary
|
||||
};
|
||||
|
||||
typedef int (*sproto_callback)(const struct sproto_arg *args);
|
||||
|
||||
1
lualib/compat10/cluster.lua
Normal file
1
lualib/compat10/cluster.lua
Normal file
@@ -0,0 +1 @@
|
||||
return require "skynet.cluster"
|
||||
1
lualib/compat10/crypt.lua
Normal file
1
lualib/compat10/crypt.lua
Normal file
@@ -0,0 +1 @@
|
||||
return require "skynet.crypt"
|
||||
1
lualib/compat10/datacenter.lua
Normal file
1
lualib/compat10/datacenter.lua
Normal file
@@ -0,0 +1 @@
|
||||
return require "skynet.datacenter"
|
||||
1
lualib/compat10/dns.lua
Normal file
1
lualib/compat10/dns.lua
Normal file
@@ -0,0 +1 @@
|
||||
return require "skynet.dns"
|
||||
1
lualib/compat10/memory.lua
Normal file
1
lualib/compat10/memory.lua
Normal file
@@ -0,0 +1 @@
|
||||
return require "skynet.memory"
|
||||
1
lualib/compat10/mongo.lua
Normal file
1
lualib/compat10/mongo.lua
Normal file
@@ -0,0 +1 @@
|
||||
return require "skynet.db.mongo"
|
||||
1
lualib/compat10/mqueue.lua
Normal file
1
lualib/compat10/mqueue.lua
Normal file
@@ -0,0 +1 @@
|
||||
return require "skynet.mqueue"
|
||||
1
lualib/compat10/multicast.lua
Normal file
1
lualib/compat10/multicast.lua
Normal file
@@ -0,0 +1 @@
|
||||
return require "skynet.multicast"
|
||||
1
lualib/compat10/mysql.lua
Normal file
1
lualib/compat10/mysql.lua
Normal file
@@ -0,0 +1 @@
|
||||
return require "skynet.db.mysql"
|
||||
1
lualib/compat10/netpack.lua
Normal file
1
lualib/compat10/netpack.lua
Normal file
@@ -0,0 +1 @@
|
||||
return require "skynet.netpack"
|
||||
1
lualib/compat10/profile.lua
Normal file
1
lualib/compat10/profile.lua
Normal file
@@ -0,0 +1 @@
|
||||
return require "skynet.profile"
|
||||
1
lualib/compat10/redis.lua
Normal file
1
lualib/compat10/redis.lua
Normal file
@@ -0,0 +1 @@
|
||||
return require "skynet.db.redis"
|
||||
1
lualib/compat10/sharedata.lua
Normal file
1
lualib/compat10/sharedata.lua
Normal file
@@ -0,0 +1 @@
|
||||
return require "skynet.sharedata"
|
||||
1
lualib/compat10/sharemap.lua
Normal file
1
lualib/compat10/sharemap.lua
Normal file
@@ -0,0 +1 @@
|
||||
return require "skynet.sharemap"
|
||||
1
lualib/compat10/snax.lua
Normal file
1
lualib/compat10/snax.lua
Normal file
@@ -0,0 +1 @@
|
||||
return require "skynet.snax"
|
||||
1
lualib/compat10/socket.lua
Normal file
1
lualib/compat10/socket.lua
Normal file
@@ -0,0 +1 @@
|
||||
return require "skynet.socket"
|
||||
1
lualib/compat10/socketchannel.lua
Normal file
1
lualib/compat10/socketchannel.lua
Normal file
@@ -0,0 +1 @@
|
||||
return require "skynet.socketchannel"
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user