mirror of
https://github.com/jart/cosmopolitan.git
synced 2025-02-07 06:53:33 +00:00
Bring Lua to 5.4.6. (#1214)
This essentially re-does the work of #875 on top of master. This is what I did to check that Cosmo's Lua extensions still worked: ``` $ build/bootstrap/make MODE=aarch64 o/aarch64/third_party/lua/lua $ ape o/aarch64/third_party/lua/lua >: 10 10 >: 010 8 >: 0b10 2 >: string.byte("\e") 27 >: "Hello, %s" % {"world"} Hello, world >: "*" * 3 *** ``` `luaL_traceback2` was used to show the stack trace with parameter values; it's used in `LuaCallWithTrace`, which is used in Redbean to run Lua code. You should be able to see the extended stack trace by running something like this: `redbean -e "function a(b)c()end a(2)"` (with "params" indicating the extended stack trace): ``` stack traceback: [string "function a(b)c()end a(2)"]:1: in function 'a', params: b = 2; [string "function a(b)c()end a(2)"]:1: in main chunk ``` @pkulchenko confirmed that I get the expected result with the updated code. This is what I did to check that Lua itself still worked: ``` $ cd third_party/lua/test/ $ ape ../../../o/aarch64/third_party/lua/lua all.lua ``` There's one test failure, in `files.lua`: ``` ***** FILE 'files.lua'***** testing i/o ../../../o/aarch64/third_party/lua/lua: files.lua:84: assertion failed! stack traceback: [C]: in function 'assert' files.lua:84: in main chunk (...tail calls...) all.lua:195: in main chunk [C]: in ? .>>> closing state <<< ``` That isn't a result of these changes; the same test is failing in master. The failure is here: ```lua if not _port then -- invalid seek local status, msg, code = io.stdin:seek("set", 1000) assert(not status and type(msg) == "string" and type(code) == "number") end ``` The test expects a seek to offset 1,000 on stdin to fail — but it doesn't. `status` ends up being the new offset rather than `nil`. If I comment out that one test, the remaining tests succeed.
This commit is contained in:
parent
3a599bfbe1
commit
0dbf01bf1d
90 changed files with 2741 additions and 1376 deletions
136
third_party/lua/README.cosmo
vendored
136
third_party/lua/README.cosmo
vendored
|
@ -9,14 +9,14 @@ PROVENANCE
|
||||||
|
|
||||||
https://github.com/lua/lua/
|
https://github.com/lua/lua/
|
||||||
|
|
||||||
commit e7803f7dbcdc966ab1f9db143424ee811ab1a398
|
commit 6443185167c77adcc8552a3fee7edab7895db1a9
|
||||||
Author: Roberto Ierusalimschy <roberto@inf.puc-rio.br>
|
Author: Roberto Ierusalimschy <roberto@inf.puc-rio.br>
|
||||||
Date: Wed Mar 3 09:44:20 2021 -0300
|
Date: May 2, 2023 at 3:44 PM EDT
|
||||||
|
|
||||||
New release number (5.4.3)
|
New release number (5.4.6)
|
||||||
|
|
||||||
luac.c needed to be sourced from:
|
luac.c needed to be sourced from:
|
||||||
https://www.lua.org/ftp/lua-5.4.3.tar.gz
|
https://www.lua.org/ftp/lua-5.4.6.tar.gz
|
||||||
|
|
||||||
LOCAL MODIFICATIONS
|
LOCAL MODIFICATIONS
|
||||||
|
|
||||||
|
@ -31,10 +31,130 @@ LOCAL MODIFICATIONS
|
||||||
character. It may be used for teletypewriter control like having
|
character. It may be used for teletypewriter control like having
|
||||||
bold text, which can be encoded elegantly as `\e[1mHELLO\e[0m`.
|
bold text, which can be encoded elegantly as `\e[1mHELLO\e[0m`.
|
||||||
|
|
||||||
|
Added Python-like printf modulus operator for strings, e.g.:
|
||||||
|
`"Hello, %s!" % {"world"}`.
|
||||||
|
|
||||||
|
Added Python-like printf multiply operator for strings, e.g.:
|
||||||
|
`"Hello, world! " * 3`.
|
||||||
|
|
||||||
|
Added `unix` module that exposes the low-level System Five system
|
||||||
|
call interface, e.g.: `require("unix"); print(unix.getcwd())`.
|
||||||
|
|
||||||
Added luaL_traceback2() for function parameters in traceback.
|
Added luaL_traceback2() for function parameters in traceback.
|
||||||
|
|
||||||
Added Python-like printf modulus operator for strings.
|
|
||||||
|
|
||||||
Added Python-like printf multiply operator for strings.
|
|
||||||
|
|
||||||
Fixed a buffer overflow in os.tmpname
|
Fixed a buffer overflow in os.tmpname
|
||||||
|
|
||||||
|
NOTES
|
||||||
|
|
||||||
|
If you'd like to update Cosmo's Lua to the latest version, here
|
||||||
|
are some things that might be helpful to know.
|
||||||
|
|
||||||
|
Cosmo's Lua adds ~20 or so files (e.g., `luacallwithtrace.c`,
|
||||||
|
`luaencodejsondata.c`, `luaencodeluadata.c`, etc.) to the
|
||||||
|
directory. In other words, a bunch of Cosmo's files don't
|
||||||
|
have any Lua counterpart.
|
||||||
|
|
||||||
|
Some of those files (e.g., `lunix.c`, `lunix.h`) implement
|
||||||
|
functionality that's available within the `lua` that Cosmo builds;
|
||||||
|
most, though, implement functionality that's (currently?) only
|
||||||
|
available within `redbean`. In other words, not everything can be
|
||||||
|
tested using `lua`; some things need to be tested using `redbean`.
|
||||||
|
|
||||||
|
Some of Lua's files were renamed. For example, `lua.c` was renamed
|
||||||
|
to `lua.main.c`, and `luac.c` (which is only available in Lua's
|
||||||
|
distributions, and not in Lua's Github repo) was renamed to
|
||||||
|
`luac.main.c`. `ljumptab.h` was renamed to `ljumptab.inc`, and
|
||||||
|
`lopnames.h` was renamed to `lopnames.inc`. In other words, you'll
|
||||||
|
need to take some kind of action in order to properly diff all of
|
||||||
|
Lua's files.
|
||||||
|
|
||||||
|
Lua's `.h` files had the comment headers that look like this
|
||||||
|
removed:
|
||||||
|
|
||||||
|
/*
|
||||||
|
** $Id: lua.h $
|
||||||
|
** Lua - A Scripting Language
|
||||||
|
** Lua.org, PUC-Rio, Brazil (http://www.lua.org)
|
||||||
|
** See Copyright Notice at the end of this file
|
||||||
|
*/
|
||||||
|
|
||||||
|
Lua's `.c` files *replaced* those comment headers with a Cosmo
|
||||||
|
emacs/vim header followed by a Lua copyright declaration.
|
||||||
|
|
||||||
|
The `.c` files also added a `__static_yoink("lua_notice");`
|
||||||
|
right after the `#include`s.
|
||||||
|
|
||||||
|
Some of Lua's tests have been modified to accommodate Cosmo's
|
||||||
|
changes. (And some of Lua's tests have been commented out
|
||||||
|
due to Cosmo's changes.)
|
||||||
|
|
||||||
|
Five of Lua's test files intentionally contain ISO-8859-1 (rather
|
||||||
|
than UTF-8) characters:
|
||||||
|
|
||||||
|
* test/db.lua
|
||||||
|
* test/files.lua
|
||||||
|
* test/pm.lua
|
||||||
|
* test/sort.lua
|
||||||
|
* test/strings.lua
|
||||||
|
|
||||||
|
If you edit those files as if they were UTF-8-encoded you'll
|
||||||
|
corrupt the ISO-8859-1 characters and cause certain tests to fail.
|
||||||
|
(Some of the tests count bytes, so you can't just fix the problem
|
||||||
|
by converting the files — you also have to change various expected
|
||||||
|
results.)
|
||||||
|
|
||||||
|
The modifications listed way up above are really only the
|
||||||
|
*user-visible* modifications. There are many that aren't
|
||||||
|
user-visible. For example, `_longjmp` was replaced with
|
||||||
|
`gclongjmp`, and `abort` was replaced, ultimately, with a
|
||||||
|
call to `_Exit`.
|
||||||
|
|
||||||
|
To update Cosmo's Lua, you'll need to diff the latest Lua against
|
||||||
|
the previous Lua, and Cosmo's Lua against the latest Lua. As you
|
||||||
|
do that, you'll be trying to figure out both what Lua changed
|
||||||
|
*and* what Cosmo changed; you'll be trying to add Lua's changes
|
||||||
|
without accidentally removing Cosmo's changes.
|
||||||
|
|
||||||
|
It's tricky!
|
||||||
|
|
||||||
|
We've started to try to make that process a bit easier by tagging
|
||||||
|
Cosmo's changes with `[jart]`. For example, one side of the diff
|
||||||
|
might (now) show:
|
||||||
|
|
||||||
|
#define LUAI_THROW(L,c) _longjmp((c)->b, 1)
|
||||||
|
|
||||||
|
while the other side might (now) show:
|
||||||
|
|
||||||
|
#define LUAI_THROW(L,c) gclongjmp((c)->b, 1) // [jart]
|
||||||
|
|
||||||
|
The presence of the `[jart]` tag makes it easy to see that the
|
||||||
|
Cosmo change was intentional.
|
||||||
|
|
||||||
|
Be aware that not all changes have been tagged!
|
||||||
|
|
||||||
|
There are *other* things we've done that are *also* meant to make
|
||||||
|
diffing easier — though the intention is less obvious.
|
||||||
|
|
||||||
|
For example, Cosmo moved the `enum` of opcodes from `ltm.h` to
|
||||||
|
`tms.h`. Originally nothing at all was left behind in `ltm.h`.
|
||||||
|
Because of that, you'd see an `enum` in Lua that seemed to be
|
||||||
|
missing in Cosmo's Lua — as though the `enum` had recently been
|
||||||
|
added to Lua, and now needed to be added to Cosmo! To make the
|
||||||
|
intention of Cosmo's change more obvious, we added a tombstone
|
||||||
|
of sorts to `ltm.h`:
|
||||||
|
|
||||||
|
/*
|
||||||
|
* WARNING: if you change the order of this enumeration,
|
||||||
|
* grep "ORDER TM" and "ORDER OP"
|
||||||
|
*/
|
||||||
|
// [jart] moved to tms.h
|
||||||
|
|
||||||
|
The comment just above the tag comes from Lua; it's the comment
|
||||||
|
above Lua's original `enum`. *The presence of the comment in both
|
||||||
|
Lua and Cosmo helps diff tools "resync" at that point.* That in
|
||||||
|
turn makes it easier to see Cosmo's change, and to see that it was
|
||||||
|
intentional.
|
||||||
|
|
||||||
|
The more things like that we do — the easier we can make it to
|
||||||
|
quickly and correctly read diffs — the easier we'll make it to
|
||||||
|
keep Cosmo's Lua in sync with the latest Lua.
|
||||||
|
|
292
third_party/lua/lapi.c
vendored
292
third_party/lua/lapi.c
vendored
|
@ -3,7 +3,7 @@
|
||||||
╚──────────────────────────────────────────────────────────────────────────────╝
|
╚──────────────────────────────────────────────────────────────────────────────╝
|
||||||
│ │
|
│ │
|
||||||
│ Lua │
|
│ Lua │
|
||||||
│ Copyright © 2004-2021 Lua.org, PUC-Rio. │
|
│ Copyright © 2004-2023 Lua.org, PUC-Rio. │
|
||||||
│ │
|
│ │
|
||||||
│ Permission is hereby granted, free of charge, to any person obtaining │
|
│ Permission is hereby granted, free of charge, to any person obtaining │
|
||||||
│ a copy of this software and associated documentation files (the │
|
│ a copy of this software and associated documentation files (the │
|
||||||
|
@ -27,6 +27,7 @@
|
||||||
╚─────────────────────────────────────────────────────────────────────────────*/
|
╚─────────────────────────────────────────────────────────────────────────────*/
|
||||||
#define lapi_c
|
#define lapi_c
|
||||||
#define LUA_CORE
|
#define LUA_CORE
|
||||||
|
|
||||||
#include "third_party/lua/lapi.h"
|
#include "third_party/lua/lapi.h"
|
||||||
#include "third_party/lua/ldebug.h"
|
#include "third_party/lua/ldebug.h"
|
||||||
#include "third_party/lua/ldo.h"
|
#include "third_party/lua/ldo.h"
|
||||||
|
@ -66,45 +67,57 @@ const char lua_ident[] =
|
||||||
#define isupvalue(i) ((i) < LUA_REGISTRYINDEX)
|
#define isupvalue(i) ((i) < LUA_REGISTRYINDEX)
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
** Convert an acceptable index to a pointer to its respective value.
|
||||||
|
** Non-valid indices return the special nil value 'G(L)->nilvalue'.
|
||||||
|
*/
|
||||||
static TValue *index2value (lua_State *L, int idx) {
|
static TValue *index2value (lua_State *L, int idx) {
|
||||||
CallInfo *ci = L->ci;
|
CallInfo *ci = L->ci;
|
||||||
if (idx > 0) {
|
if (idx > 0) {
|
||||||
StkId o = ci->func + idx;
|
StkId o = ci->func.p + idx;
|
||||||
api_check(L, idx <= L->ci->top - (ci->func + 1), "unacceptable index");
|
api_check(L, idx <= ci->top.p - (ci->func.p + 1), "unacceptable index");
|
||||||
if (o >= L->top) return &G(L)->nilvalue;
|
if (o >= L->top.p) return &G(L)->nilvalue;
|
||||||
else return s2v(o);
|
else return s2v(o);
|
||||||
}
|
}
|
||||||
else if (!ispseudo(idx)) { /* negative index */
|
else if (!ispseudo(idx)) { /* negative index */
|
||||||
api_check(L, idx != 0 && -idx <= L->top - (ci->func + 1), "invalid index");
|
api_check(L, idx != 0 && -idx <= L->top.p - (ci->func.p + 1),
|
||||||
return s2v(L->top + idx);
|
"invalid index");
|
||||||
|
return s2v(L->top.p + idx);
|
||||||
}
|
}
|
||||||
else if (idx == LUA_REGISTRYINDEX)
|
else if (idx == LUA_REGISTRYINDEX)
|
||||||
return &G(L)->l_registry;
|
return &G(L)->l_registry;
|
||||||
else { /* upvalues */
|
else { /* upvalues */
|
||||||
idx = LUA_REGISTRYINDEX - idx;
|
idx = LUA_REGISTRYINDEX - idx;
|
||||||
api_check(L, idx <= MAXUPVAL + 1, "upvalue index too large");
|
api_check(L, idx <= MAXUPVAL + 1, "upvalue index too large");
|
||||||
if (ttislcf(s2v(ci->func))) /* light C function? */
|
if (ttisCclosure(s2v(ci->func.p))) { /* C closure? */
|
||||||
return &G(L)->nilvalue; /* it has no upvalues */
|
CClosure *func = clCvalue(s2v(ci->func.p));
|
||||||
else {
|
|
||||||
CClosure *func = clCvalue(s2v(ci->func));
|
|
||||||
return (idx <= func->nupvalues) ? &func->upvalue[idx-1]
|
return (idx <= func->nupvalues) ? &func->upvalue[idx-1]
|
||||||
: &G(L)->nilvalue;
|
: &G(L)->nilvalue;
|
||||||
}
|
}
|
||||||
|
else { /* light C function or Lua function (through a hook)?) */
|
||||||
|
api_check(L, ttislcf(s2v(ci->func.p)), "caller not a C function");
|
||||||
|
return &G(L)->nilvalue; /* no upvalues */
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static StkId index2stack (lua_State *L, int idx) {
|
|
||||||
|
/*
|
||||||
|
** Convert a valid actual index (not a pseudo-index) to its address.
|
||||||
|
*/
|
||||||
|
l_sinline StkId index2stack (lua_State *L, int idx) {
|
||||||
CallInfo *ci = L->ci;
|
CallInfo *ci = L->ci;
|
||||||
if (idx > 0) {
|
if (idx > 0) {
|
||||||
StkId o = ci->func + idx;
|
StkId o = ci->func.p + idx;
|
||||||
api_check(L, o < L->top, "unacceptable index");
|
api_check(L, o < L->top.p, "invalid index");
|
||||||
return o;
|
return o;
|
||||||
}
|
}
|
||||||
else { /* non-positive index */
|
else { /* non-positive index */
|
||||||
api_check(L, idx != 0 && -idx <= L->top - (ci->func + 1), "invalid index");
|
api_check(L, idx != 0 && -idx <= L->top.p - (ci->func.p + 1),
|
||||||
|
"invalid index");
|
||||||
api_check(L, !ispseudo(idx), "invalid index");
|
api_check(L, !ispseudo(idx), "invalid index");
|
||||||
return L->top + idx;
|
return L->top.p + idx;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -115,17 +128,12 @@ LUA_API int lua_checkstack (lua_State *L, int n) {
|
||||||
lua_lock(L);
|
lua_lock(L);
|
||||||
ci = L->ci;
|
ci = L->ci;
|
||||||
api_check(L, n >= 0, "negative 'n'");
|
api_check(L, n >= 0, "negative 'n'");
|
||||||
if (L->stack_last - L->top > n) /* stack large enough? */
|
if (L->stack_last.p - L->top.p > n) /* stack large enough? */
|
||||||
res = 1; /* yes; check is OK */
|
res = 1; /* yes; check is OK */
|
||||||
else { /* no; need to grow stack */
|
else /* need to grow stack */
|
||||||
int inuse = cast_int(L->top - L->stack) + EXTRA_STACK;
|
|
||||||
if (inuse > LUAI_MAXSTACK - n) /* can grow without overflow? */
|
|
||||||
res = 0; /* no */
|
|
||||||
else /* try to grow stack */
|
|
||||||
res = luaD_growstack(L, n, 0);
|
res = luaD_growstack(L, n, 0);
|
||||||
}
|
if (res && ci->top.p < L->top.p + n)
|
||||||
if (res && ci->top < L->top + n)
|
ci->top.p = L->top.p + n; /* adjust frame top */
|
||||||
ci->top = L->top + n; /* adjust frame top */
|
|
||||||
lua_unlock(L);
|
lua_unlock(L);
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
|
@ -142,11 +150,11 @@ LUA_API void lua_xmove (lua_State *from, lua_State *to, int n) {
|
||||||
lua_lock(to);
|
lua_lock(to);
|
||||||
api_checknelems(from, n);
|
api_checknelems(from, n);
|
||||||
api_check(from, G(from) == G(to), "moving among independent states");
|
api_check(from, G(from) == G(to), "moving among independent states");
|
||||||
api_check(from, to->ci->top - to->top >= n, "stack overflow");
|
api_check(from, to->ci->top.p - to->top.p >= n, "stack overflow");
|
||||||
from->top -= n;
|
from->top.p -= n;
|
||||||
for (i = 0; i < n; i++) {
|
for (i = 0; i < n; i++) {
|
||||||
setobjs2s(to, to->top, from->top + i);
|
setobjs2s(to, to->top.p, from->top.p + i);
|
||||||
to->top++; /* stack already checked by previous 'api_check' */
|
to->top.p++; /* stack already checked by previous 'api_check' */
|
||||||
}
|
}
|
||||||
lua_unlock(to);
|
lua_unlock(to);
|
||||||
}
|
}
|
||||||
|
@ -199,7 +207,7 @@ LUA_API lua_Number lua_version (lua_State *L) {
|
||||||
LUA_API int lua_absindex (lua_State *L, int idx) {
|
LUA_API int lua_absindex (lua_State *L, int idx) {
|
||||||
return (idx > 0 || ispseudo(idx))
|
return (idx > 0 || ispseudo(idx))
|
||||||
? idx
|
? idx
|
||||||
: cast_int(L->top - L->ci->func) + idx;
|
: cast_int(L->top.p - L->ci->func.p) + idx;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -210,7 +218,7 @@ LUA_API int lua_absindex (lua_State *L, int idx) {
|
||||||
* particular, 0 means an empty stack.
|
* particular, 0 means an empty stack.
|
||||||
*/
|
*/
|
||||||
LUA_API int lua_gettop (lua_State *L) {
|
LUA_API int lua_gettop (lua_State *L) {
|
||||||
return cast_int(L->top - (L->ci->func + 1));
|
return cast_int(L->top.p - (L->ci->func.p + 1));
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -229,24 +237,24 @@ LUA_API void lua_settop (lua_State *L, int idx) {
|
||||||
ptrdiff_t diff; /* difference for new top */
|
ptrdiff_t diff; /* difference for new top */
|
||||||
lua_lock(L);
|
lua_lock(L);
|
||||||
ci = L->ci;
|
ci = L->ci;
|
||||||
func = ci->func;
|
func = ci->func.p;
|
||||||
if (idx >= 0) {
|
if (idx >= 0) {
|
||||||
api_check(L, idx <= ci->top - (func + 1), "new top too large");
|
api_check(L, idx <= ci->top.p - (func + 1), "new top too large");
|
||||||
diff = ((func + 1) + idx) - L->top;
|
diff = ((func + 1) + idx) - L->top.p;
|
||||||
for (; diff > 0; diff--)
|
for (; diff > 0; diff--)
|
||||||
setnilvalue(s2v(L->top++)); /* clear new slots */
|
setnilvalue(s2v(L->top.p++)); /* clear new slots */
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
api_check(L, -(idx+1) <= (L->top - (func + 1)), "invalid new top");
|
api_check(L, -(idx+1) <= (L->top.p - (func + 1)), "invalid new top");
|
||||||
diff = idx + 1; /* will "subtract" index (as it is negative) */
|
diff = idx + 1; /* will "subtract" index (as it is negative) */
|
||||||
}
|
}
|
||||||
api_check(L, L->tbclist < L->top, "previous pop of an unclosed slot");
|
api_check(L, L->tbclist.p < L->top.p, "previous pop of an unclosed slot");
|
||||||
newtop = L->top + diff;
|
newtop = L->top.p + diff;
|
||||||
if (diff < 0 && L->tbclist >= newtop) {
|
if (diff < 0 && L->tbclist.p >= newtop) {
|
||||||
lua_assert(hastocloseCfunc(ci->nresults));
|
lua_assert(hastocloseCfunc(ci->nresults));
|
||||||
luaF_close(L, newtop, CLOSEKTOP, 0);
|
newtop = luaF_close(L, newtop, CLOSEKTOP, 0);
|
||||||
}
|
}
|
||||||
L->top = newtop; /* correct top only after closing any upvalue */
|
L->top.p = newtop; /* correct top only after closing any upvalue */
|
||||||
lua_unlock(L);
|
lua_unlock(L);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -255,10 +263,9 @@ LUA_API void lua_closeslot (lua_State *L, int idx) {
|
||||||
StkId level;
|
StkId level;
|
||||||
lua_lock(L);
|
lua_lock(L);
|
||||||
level = index2stack(L, idx);
|
level = index2stack(L, idx);
|
||||||
api_check(L, hastocloseCfunc(L->ci->nresults) && L->tbclist == level,
|
api_check(L, hastocloseCfunc(L->ci->nresults) && L->tbclist.p == level,
|
||||||
"no variable to close at given level");
|
"no variable to close at given level");
|
||||||
luaF_close(L, level, CLOSEKTOP, 0);
|
level = luaF_close(L, level, CLOSEKTOP, 0);
|
||||||
level = index2stack(L, idx); /* stack may be moved */
|
|
||||||
setnilvalue(s2v(level));
|
setnilvalue(s2v(level));
|
||||||
lua_unlock(L);
|
lua_unlock(L);
|
||||||
}
|
}
|
||||||
|
@ -270,7 +277,7 @@ LUA_API void lua_closeslot (lua_State *L, int idx) {
|
||||||
** Note that we move(copy) only the value inside the stack.
|
** Note that we move(copy) only the value inside the stack.
|
||||||
** (We do not move additional fields that may exist.)
|
** (We do not move additional fields that may exist.)
|
||||||
*/
|
*/
|
||||||
static void reverse (lua_State *L, StkId from, StkId to) {
|
l_sinline void reverse (lua_State *L, StkId from, StkId to) {
|
||||||
for (; from < to; from++, to--) {
|
for (; from < to; from++, to--) {
|
||||||
TValue temp;
|
TValue temp;
|
||||||
setobj(L, &temp, s2v(from));
|
setobj(L, &temp, s2v(from));
|
||||||
|
@ -287,7 +294,7 @@ static void reverse (lua_State *L, StkId from, StkId to) {
|
||||||
LUA_API void lua_rotate (lua_State *L, int idx, int n) {
|
LUA_API void lua_rotate (lua_State *L, int idx, int n) {
|
||||||
StkId p, t, m;
|
StkId p, t, m;
|
||||||
lua_lock(L);
|
lua_lock(L);
|
||||||
t = L->top - 1; /* end of stack segment being rotated */
|
t = L->top.p - 1; /* end of stack segment being rotated */
|
||||||
p = index2stack(L, idx); /* start of segment */
|
p = index2stack(L, idx); /* start of segment */
|
||||||
api_check(L, (n >= 0 ? n : -n) <= (t - p + 1), "invalid 'n'");
|
api_check(L, (n >= 0 ? n : -n) <= (t - p + 1), "invalid 'n'");
|
||||||
m = (n >= 0 ? t - n : p - n - 1); /* end of prefix */
|
m = (n >= 0 ? t - n : p - n - 1); /* end of prefix */
|
||||||
|
@ -306,7 +313,7 @@ LUA_API void lua_copy (lua_State *L, int fromidx, int toidx) {
|
||||||
api_check(L, isvalid(L, to), "invalid index");
|
api_check(L, isvalid(L, to), "invalid index");
|
||||||
setobj(L, to, fr);
|
setobj(L, to, fr);
|
||||||
if (isupvalue(toidx)) /* function upvalue? */
|
if (isupvalue(toidx)) /* function upvalue? */
|
||||||
luaC_barrier(L, clCvalue(s2v(L->ci->func)), fr);
|
luaC_barrier(L, clCvalue(s2v(L->ci->func.p)), fr);
|
||||||
/* LUA_REGISTRYINDEX does not need gc barrier
|
/* LUA_REGISTRYINDEX does not need gc barrier
|
||||||
(collector revisits it before finishing collection) */
|
(collector revisits it before finishing collection) */
|
||||||
lua_unlock(L);
|
lua_unlock(L);
|
||||||
|
@ -315,7 +322,7 @@ LUA_API void lua_copy (lua_State *L, int fromidx, int toidx) {
|
||||||
|
|
||||||
LUA_API void lua_pushvalue (lua_State *L, int idx) {
|
LUA_API void lua_pushvalue (lua_State *L, int idx) {
|
||||||
lua_lock(L);
|
lua_lock(L);
|
||||||
setobj2s(L, L->top, index2value(L, idx));
|
setobj2s(L, L->top.p, index2value(L, idx));
|
||||||
api_incr_top(L);
|
api_incr_top(L);
|
||||||
lua_unlock(L);
|
lua_unlock(L);
|
||||||
}
|
}
|
||||||
|
@ -384,12 +391,12 @@ LUA_API void lua_arith (lua_State *L, int op) {
|
||||||
api_checknelems(L, 2); /* all other operations expect two operands */
|
api_checknelems(L, 2); /* all other operations expect two operands */
|
||||||
else { /* for unary operations, add fake 2nd operand */
|
else { /* for unary operations, add fake 2nd operand */
|
||||||
api_checknelems(L, 1);
|
api_checknelems(L, 1);
|
||||||
setobjs2s(L, L->top, L->top - 1);
|
setobjs2s(L, L->top.p, L->top.p - 1);
|
||||||
api_incr_top(L);
|
api_incr_top(L);
|
||||||
}
|
}
|
||||||
/* first operand at top - 2, second at top - 1; result go to top - 2 */
|
/* first operand at top - 2, second at top - 1; result go to top - 2 */
|
||||||
luaO_arith(L, op, s2v(L->top - 2), s2v(L->top - 1), L->top - 2);
|
luaO_arith(L, op, s2v(L->top.p - 2), s2v(L->top.p - 1), L->top.p - 2);
|
||||||
L->top--; /* remove second operand */
|
L->top.p--; /* remove second operand */
|
||||||
lua_unlock(L);
|
lua_unlock(L);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -415,7 +422,7 @@ LUA_API int lua_compare (lua_State *L, int index1, int index2, int op) {
|
||||||
|
|
||||||
|
|
||||||
LUA_API size_t lua_stringtonumber (lua_State *L, const char *s) {
|
LUA_API size_t lua_stringtonumber (lua_State *L, const char *s) {
|
||||||
size_t sz = luaO_str2num(s, s2v(L->top));
|
size_t sz = luaO_str2num(s, s2v(L->top.p));
|
||||||
if (sz != 0)
|
if (sz != 0)
|
||||||
api_incr_top(L);
|
api_incr_top(L);
|
||||||
return sz;
|
return sz;
|
||||||
|
@ -490,7 +497,7 @@ LUA_API lua_CFunction lua_tocfunction (lua_State *L, int idx) {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static void *touserdata (const TValue *o) {
|
l_sinline void *touserdata (const TValue *o) {
|
||||||
switch (ttype(o)) {
|
switch (ttype(o)) {
|
||||||
case LUA_TUSERDATA: return getudatamem(uvalue(o));
|
case LUA_TUSERDATA: return getudatamem(uvalue(o));
|
||||||
case LUA_TLIGHTUSERDATA: return pvalue(o);
|
case LUA_TLIGHTUSERDATA: return pvalue(o);
|
||||||
|
@ -572,7 +579,7 @@ LUA_API const void *lua_topointer (lua_State *L, int idx) {
|
||||||
*/
|
*/
|
||||||
LUA_API void lua_pushnil (lua_State *L) {
|
LUA_API void lua_pushnil (lua_State *L) {
|
||||||
lua_lock(L);
|
lua_lock(L);
|
||||||
setnilvalue(s2v(L->top));
|
setnilvalue(s2v(L->top.p));
|
||||||
api_incr_top(L);
|
api_incr_top(L);
|
||||||
lua_unlock(L);
|
lua_unlock(L);
|
||||||
}
|
}
|
||||||
|
@ -585,7 +592,7 @@ LUA_API void lua_pushnil (lua_State *L) {
|
||||||
*/
|
*/
|
||||||
LUA_API void lua_pushnumber (lua_State *L, lua_Number n) {
|
LUA_API void lua_pushnumber (lua_State *L, lua_Number n) {
|
||||||
lua_lock(L);
|
lua_lock(L);
|
||||||
setfltvalue(s2v(L->top), n);
|
setfltvalue(s2v(L->top.p), n);
|
||||||
api_incr_top(L);
|
api_incr_top(L);
|
||||||
lua_unlock(L);
|
lua_unlock(L);
|
||||||
}
|
}
|
||||||
|
@ -600,7 +607,7 @@ LUA_API void lua_pushnumber (lua_State *L, lua_Number n) {
|
||||||
*/
|
*/
|
||||||
LUA_API void lua_pushinteger (lua_State *L, lua_Integer n) {
|
LUA_API void lua_pushinteger (lua_State *L, lua_Integer n) {
|
||||||
lua_lock(L);
|
lua_lock(L);
|
||||||
setivalue(s2v(L->top), n);
|
setivalue(s2v(L->top.p), n);
|
||||||
api_incr_top(L);
|
api_incr_top(L);
|
||||||
lua_unlock(L);
|
lua_unlock(L);
|
||||||
}
|
}
|
||||||
|
@ -615,7 +622,7 @@ LUA_API const char *lua_pushlstring (lua_State *L, const char *s, size_t len) {
|
||||||
TString *ts;
|
TString *ts;
|
||||||
lua_lock(L);
|
lua_lock(L);
|
||||||
ts = (len == 0) ? luaS_new(L, "") : luaS_newlstr(L, s, len);
|
ts = (len == 0) ? luaS_new(L, "") : luaS_newlstr(L, s, len);
|
||||||
setsvalue2s(L, L->top, ts);
|
setsvalue2s(L, L->top.p, ts);
|
||||||
api_incr_top(L);
|
api_incr_top(L);
|
||||||
luaC_checkGC(L);
|
luaC_checkGC(L);
|
||||||
lua_unlock(L);
|
lua_unlock(L);
|
||||||
|
@ -637,11 +644,11 @@ LUA_API const char *lua_pushlstring (lua_State *L, const char *s, size_t len) {
|
||||||
LUA_API const char *lua_pushstring (lua_State *L, const char *s) {
|
LUA_API const char *lua_pushstring (lua_State *L, const char *s) {
|
||||||
lua_lock(L);
|
lua_lock(L);
|
||||||
if (s == NULL)
|
if (s == NULL)
|
||||||
setnilvalue(s2v(L->top));
|
setnilvalue(s2v(L->top.p));
|
||||||
else {
|
else {
|
||||||
TString *ts;
|
TString *ts;
|
||||||
ts = luaS_new(L, s);
|
ts = luaS_new(L, s);
|
||||||
setsvalue2s(L, L->top, ts);
|
setsvalue2s(L, L->top.p, ts);
|
||||||
s = getstr(ts); /* internal copy's address */
|
s = getstr(ts); /* internal copy's address */
|
||||||
}
|
}
|
||||||
api_incr_top(L);
|
api_incr_top(L);
|
||||||
|
@ -729,7 +736,7 @@ LUA_API const char *lua_pushfstring (lua_State *L, const char *fmt, ...) {
|
||||||
LUA_API void lua_pushcclosure (lua_State *L, lua_CFunction fn, int n) {
|
LUA_API void lua_pushcclosure (lua_State *L, lua_CFunction fn, int n) {
|
||||||
lua_lock(L);
|
lua_lock(L);
|
||||||
if (n == 0) {
|
if (n == 0) {
|
||||||
setfvalue(s2v(L->top), fn);
|
setfvalue(s2v(L->top.p), fn);
|
||||||
api_incr_top(L);
|
api_incr_top(L);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
|
@ -738,13 +745,13 @@ LUA_API void lua_pushcclosure (lua_State *L, lua_CFunction fn, int n) {
|
||||||
api_check(L, n <= MAXUPVAL, "upvalue index too large");
|
api_check(L, n <= MAXUPVAL, "upvalue index too large");
|
||||||
cl = luaF_newCclosure(L, n);
|
cl = luaF_newCclosure(L, n);
|
||||||
cl->f = fn;
|
cl->f = fn;
|
||||||
L->top -= n;
|
L->top.p -= n;
|
||||||
while (n--) {
|
while (n--) {
|
||||||
setobj2n(L, &cl->upvalue[n], s2v(L->top + n));
|
setobj2n(L, &cl->upvalue[n], s2v(L->top.p + n));
|
||||||
/* does not need barrier because closure is white */
|
/* does not need barrier because closure is white */
|
||||||
lua_assert(iswhite(cl));
|
lua_assert(iswhite(cl));
|
||||||
}
|
}
|
||||||
setclCvalue(L, s2v(L->top), cl);
|
setclCvalue(L, s2v(L->top.p), cl);
|
||||||
api_incr_top(L);
|
api_incr_top(L);
|
||||||
luaC_checkGC(L);
|
luaC_checkGC(L);
|
||||||
}
|
}
|
||||||
|
@ -761,9 +768,9 @@ LUA_API void lua_pushboolean (lua_State *L, int b) {
|
||||||
lua_lock(L);
|
lua_lock(L);
|
||||||
/* a.k.a. L->top->val.tt_ = b ? LUA_VTRUE : LUA_VFALSE; */
|
/* a.k.a. L->top->val.tt_ = b ? LUA_VTRUE : LUA_VFALSE; */
|
||||||
if (b)
|
if (b)
|
||||||
setbtvalue(s2v(L->top));
|
setbtvalue(s2v(L->top.p));
|
||||||
else
|
else
|
||||||
setbfvalue(s2v(L->top));
|
setbfvalue(s2v(L->top.p));
|
||||||
api_incr_top(L);
|
api_incr_top(L);
|
||||||
lua_unlock(L);
|
lua_unlock(L);
|
||||||
}
|
}
|
||||||
|
@ -781,7 +788,7 @@ LUA_API void lua_pushboolean (lua_State *L, int b) {
|
||||||
*/
|
*/
|
||||||
LUA_API void lua_pushlightuserdata (lua_State *L, void *p) {
|
LUA_API void lua_pushlightuserdata (lua_State *L, void *p) {
|
||||||
lua_lock(L);
|
lua_lock(L);
|
||||||
setpvalue(s2v(L->top), p);
|
setpvalue(s2v(L->top.p), p);
|
||||||
api_incr_top(L);
|
api_incr_top(L);
|
||||||
lua_unlock(L);
|
lua_unlock(L);
|
||||||
}
|
}
|
||||||
|
@ -795,7 +802,7 @@ LUA_API void lua_pushlightuserdata (lua_State *L, void *p) {
|
||||||
*/
|
*/
|
||||||
LUA_API int lua_pushthread (lua_State *L) {
|
LUA_API int lua_pushthread (lua_State *L) {
|
||||||
lua_lock(L);
|
lua_lock(L);
|
||||||
setthvalue(L, s2v(L->top), L);
|
setthvalue(L, s2v(L->top.p), L);
|
||||||
api_incr_top(L);
|
api_incr_top(L);
|
||||||
lua_unlock(L);
|
lua_unlock(L);
|
||||||
return (G(L)->mainthread == L);
|
return (G(L)->mainthread == L);
|
||||||
|
@ -808,20 +815,20 @@ LUA_API int lua_pushthread (lua_State *L) {
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
|
||||||
static int auxgetstr (lua_State *L, const TValue *t, const char *k) {
|
l_sinline int auxgetstr (lua_State *L, const TValue *t, const char *k) {
|
||||||
const TValue *slot;
|
const TValue *slot;
|
||||||
TString *str = luaS_new(L, k);
|
TString *str = luaS_new(L, k);
|
||||||
if (luaV_fastget(L, t, str, slot, luaH_getstr)) {
|
if (luaV_fastget(L, t, str, slot, luaH_getstr)) {
|
||||||
setobj2s(L, L->top, slot);
|
setobj2s(L, L->top.p, slot);
|
||||||
api_incr_top(L);
|
api_incr_top(L);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
setsvalue2s(L, L->top, str);
|
setsvalue2s(L, L->top.p, str);
|
||||||
api_incr_top(L);
|
api_incr_top(L);
|
||||||
luaV_finishget(L, t, s2v(L->top - 1), L->top - 1, slot);
|
luaV_finishget(L, t, s2v(L->top.p - 1), L->top.p - 1, slot);
|
||||||
}
|
}
|
||||||
lua_unlock(L);
|
lua_unlock(L);
|
||||||
return ttype(s2v(L->top - 1));
|
return ttype(s2v(L->top.p - 1));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -848,13 +855,13 @@ LUA_API int lua_gettable (lua_State *L, int idx) {
|
||||||
TValue *t;
|
TValue *t;
|
||||||
lua_lock(L);
|
lua_lock(L);
|
||||||
t = index2value(L, idx);
|
t = index2value(L, idx);
|
||||||
if (luaV_fastget(L, t, s2v(L->top - 1), slot, luaH_get)) {
|
if (luaV_fastget(L, t, s2v(L->top.p - 1), slot, luaH_get)) {
|
||||||
setobj2s(L, L->top - 1, slot);
|
setobj2s(L, L->top.p - 1, slot);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
luaV_finishget(L, t, s2v(L->top - 1), L->top - 1, slot);
|
luaV_finishget(L, t, s2v(L->top.p - 1), L->top.p - 1, slot);
|
||||||
lua_unlock(L);
|
lua_unlock(L);
|
||||||
return ttype(s2v(L->top - 1));
|
return ttype(s2v(L->top.p - 1));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -870,27 +877,27 @@ LUA_API int lua_geti (lua_State *L, int idx, lua_Integer n) {
|
||||||
lua_lock(L);
|
lua_lock(L);
|
||||||
t = index2value(L, idx);
|
t = index2value(L, idx);
|
||||||
if (luaV_fastgeti(L, t, n, slot)) {
|
if (luaV_fastgeti(L, t, n, slot)) {
|
||||||
setobj2s(L, L->top, slot);
|
setobj2s(L, L->top.p, slot);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
TValue aux;
|
TValue aux;
|
||||||
setivalue(&aux, n);
|
setivalue(&aux, n);
|
||||||
luaV_finishget(L, t, &aux, L->top, slot);
|
luaV_finishget(L, t, &aux, L->top.p, slot);
|
||||||
}
|
}
|
||||||
api_incr_top(L);
|
api_incr_top(L);
|
||||||
lua_unlock(L);
|
lua_unlock(L);
|
||||||
return ttype(s2v(L->top - 1));
|
return ttype(s2v(L->top.p - 1));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static int finishrawget (lua_State *L, const TValue *val) {
|
l_sinline int finishrawget (lua_State *L, const TValue *val) {
|
||||||
if (isempty(val)) /* avoid copying empty items to the stack */
|
if (isempty(val)) /* avoid copying empty items to the stack */
|
||||||
setnilvalue(s2v(L->top));
|
setnilvalue(s2v(L->top.p));
|
||||||
else
|
else
|
||||||
setobj2s(L, L->top, val);
|
setobj2s(L, L->top.p, val);
|
||||||
api_incr_top(L);
|
api_incr_top(L);
|
||||||
lua_unlock(L);
|
lua_unlock(L);
|
||||||
return ttype(s2v(L->top - 1));
|
return ttype(s2v(L->top.p - 1));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -913,8 +920,8 @@ LUA_API int lua_rawget (lua_State *L, int idx) {
|
||||||
lua_lock(L);
|
lua_lock(L);
|
||||||
api_checknelems(L, 1);
|
api_checknelems(L, 1);
|
||||||
t = gettable(L, idx);
|
t = gettable(L, idx);
|
||||||
val = luaH_get(t, s2v(L->top - 1));
|
val = luaH_get(t, s2v(L->top.p - 1));
|
||||||
L->top--; /* remove key */
|
L->top.p--; /* remove key */
|
||||||
return finishrawget(L, val);
|
return finishrawget(L, val);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -961,7 +968,7 @@ LUA_API void lua_createtable (lua_State *L, int narray, int nrec) {
|
||||||
Table *t;
|
Table *t;
|
||||||
lua_lock(L);
|
lua_lock(L);
|
||||||
t = luaH_new(L);
|
t = luaH_new(L);
|
||||||
sethvalue2s(L, L->top, t);
|
sethvalue2s(L, L->top.p, t);
|
||||||
api_incr_top(L);
|
api_incr_top(L);
|
||||||
if (narray > 0 || nrec > 0)
|
if (narray > 0 || nrec > 0)
|
||||||
luaH_resize(L, t, narray, nrec);
|
luaH_resize(L, t, narray, nrec);
|
||||||
|
@ -997,7 +1004,7 @@ LUA_API int lua_getmetatable (lua_State *L, int objindex) {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
if (mt != NULL) {
|
if (mt != NULL) {
|
||||||
sethvalue2s(L, L->top, mt);
|
sethvalue2s(L, L->top.p, mt);
|
||||||
api_incr_top(L);
|
api_incr_top(L);
|
||||||
res = 1;
|
res = 1;
|
||||||
}
|
}
|
||||||
|
@ -1024,12 +1031,12 @@ LUA_API int lua_getiuservalue (lua_State *L, int idx, int n) {
|
||||||
o = index2value(L, idx);
|
o = index2value(L, idx);
|
||||||
api_check(L, ttisfulluserdata(o), "full userdata expected");
|
api_check(L, ttisfulluserdata(o), "full userdata expected");
|
||||||
if (n <= 0 || n > uvalue(o)->nuvalue) {
|
if (n <= 0 || n > uvalue(o)->nuvalue) {
|
||||||
setnilvalue(s2v(L->top));
|
setnilvalue(s2v(L->top.p));
|
||||||
t = LUA_TNONE;
|
t = LUA_TNONE;
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
setobj2s(L, L->top, &uvalue(o)->uv[n - 1].uv);
|
setobj2s(L, L->top.p, &uvalue(o)->uv[n - 1].uv);
|
||||||
t = ttype(s2v(L->top));
|
t = ttype(s2v(L->top.p));
|
||||||
}
|
}
|
||||||
api_incr_top(L);
|
api_incr_top(L);
|
||||||
lua_unlock(L);
|
lua_unlock(L);
|
||||||
|
@ -1049,14 +1056,14 @@ static void auxsetstr (lua_State *L, const TValue *t, const char *k) {
|
||||||
TString *str = luaS_new(L, k);
|
TString *str = luaS_new(L, k);
|
||||||
api_checknelems(L, 1);
|
api_checknelems(L, 1);
|
||||||
if (luaV_fastget(L, t, str, slot, luaH_getstr)) {
|
if (luaV_fastget(L, t, str, slot, luaH_getstr)) {
|
||||||
luaV_finishfastset(L, t, slot, s2v(L->top - 1));
|
luaV_finishfastset(L, t, slot, s2v(L->top.p - 1));
|
||||||
L->top--; /* pop value */
|
L->top.p--; /* pop value */
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
setsvalue2s(L, L->top, str); /* push 'str' (to make it a TValue) */
|
setsvalue2s(L, L->top.p, str); /* push 'str' (to make it a TValue) */
|
||||||
api_incr_top(L);
|
api_incr_top(L);
|
||||||
luaV_finishset(L, t, s2v(L->top - 1), s2v(L->top - 2), slot);
|
luaV_finishset(L, t, s2v(L->top.p - 1), s2v(L->top.p - 2), slot);
|
||||||
L->top -= 2; /* pop value and key */
|
L->top.p -= 2; /* pop value and key */
|
||||||
}
|
}
|
||||||
lua_unlock(L); /* lock done by caller */
|
lua_unlock(L); /* lock done by caller */
|
||||||
}
|
}
|
||||||
|
@ -1076,12 +1083,12 @@ LUA_API void lua_settable (lua_State *L, int idx) {
|
||||||
lua_lock(L);
|
lua_lock(L);
|
||||||
api_checknelems(L, 2);
|
api_checknelems(L, 2);
|
||||||
t = index2value(L, idx);
|
t = index2value(L, idx);
|
||||||
if (luaV_fastget(L, t, s2v(L->top - 2), slot, luaH_get)) {
|
if (luaV_fastget(L, t, s2v(L->top.p - 2), slot, luaH_get)) {
|
||||||
luaV_finishfastset(L, t, slot, s2v(L->top - 1));
|
luaV_finishfastset(L, t, slot, s2v(L->top.p - 1));
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
luaV_finishset(L, t, s2v(L->top - 2), s2v(L->top - 1), slot);
|
luaV_finishset(L, t, s2v(L->top.p - 2), s2v(L->top.p - 1), slot);
|
||||||
L->top -= 2; /* pop index and value */
|
L->top.p -= 2; /* pop index and value */
|
||||||
lua_unlock(L);
|
lua_unlock(L);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1108,14 +1115,14 @@ LUA_API void lua_seti (lua_State *L, int idx, lua_Integer n) {
|
||||||
api_checknelems(L, 1);
|
api_checknelems(L, 1);
|
||||||
t = index2value(L, idx);
|
t = index2value(L, idx);
|
||||||
if (luaV_fastgeti(L, t, n, slot)) {
|
if (luaV_fastgeti(L, t, n, slot)) {
|
||||||
luaV_finishfastset(L, t, slot, s2v(L->top - 1));
|
luaV_finishfastset(L, t, slot, s2v(L->top.p - 1));
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
TValue aux;
|
TValue aux;
|
||||||
setivalue(&aux, n);
|
setivalue(&aux, n);
|
||||||
luaV_finishset(L, t, &aux, s2v(L->top - 1), slot);
|
luaV_finishset(L, t, &aux, s2v(L->top.p - 1), slot);
|
||||||
}
|
}
|
||||||
L->top--; /* pop value */
|
L->top.p--; /* pop value */
|
||||||
lua_unlock(L);
|
lua_unlock(L);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1125,10 +1132,10 @@ static void aux_rawset (lua_State *L, int idx, TValue *key, int n) {
|
||||||
lua_lock(L);
|
lua_lock(L);
|
||||||
api_checknelems(L, n);
|
api_checknelems(L, n);
|
||||||
t = gettable(L, idx);
|
t = gettable(L, idx);
|
||||||
luaH_set(L, t, key, s2v(L->top - 1));
|
luaH_set(L, t, key, s2v(L->top.p - 1));
|
||||||
invalidateTMcache(t);
|
invalidateTMcache(t);
|
||||||
luaC_barrierback(L, obj2gco(t), s2v(L->top - 1));
|
luaC_barrierback(L, obj2gco(t), s2v(L->top.p - 1));
|
||||||
L->top -= n;
|
L->top.p -= n;
|
||||||
lua_unlock(L);
|
lua_unlock(L);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1140,7 +1147,7 @@ static void aux_rawset (lua_State *L, int idx, TValue *key, int n) {
|
||||||
* metamethods).
|
* metamethods).
|
||||||
*/
|
*/
|
||||||
LUA_API void lua_rawset (lua_State *L, int idx) {
|
LUA_API void lua_rawset (lua_State *L, int idx) {
|
||||||
aux_rawset(L, idx, s2v(L->top - 2), 2);
|
aux_rawset(L, idx, s2v(L->top.p - 2), 2);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -1175,9 +1182,9 @@ LUA_API void lua_rawseti (lua_State *L, int idx, lua_Integer n) {
|
||||||
lua_lock(L);
|
lua_lock(L);
|
||||||
api_checknelems(L, 1);
|
api_checknelems(L, 1);
|
||||||
t = gettable(L, idx);
|
t = gettable(L, idx);
|
||||||
luaH_setint(L, t, n, s2v(L->top - 1));
|
luaH_setint(L, t, n, s2v(L->top.p - 1));
|
||||||
luaC_barrierback(L, obj2gco(t), s2v(L->top - 1));
|
luaC_barrierback(L, obj2gco(t), s2v(L->top.p - 1));
|
||||||
L->top--;
|
L->top.p--;
|
||||||
lua_unlock(L);
|
lua_unlock(L);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1197,11 +1204,11 @@ LUA_API int lua_setmetatable (lua_State *L, int objindex) {
|
||||||
lua_lock(L);
|
lua_lock(L);
|
||||||
api_checknelems(L, 1);
|
api_checknelems(L, 1);
|
||||||
obj = index2value(L, objindex);
|
obj = index2value(L, objindex);
|
||||||
if (ttisnil(s2v(L->top - 1)))
|
if (ttisnil(s2v(L->top.p - 1)))
|
||||||
mt = NULL;
|
mt = NULL;
|
||||||
else {
|
else {
|
||||||
api_check(L, ttistable(s2v(L->top - 1)), "table expected");
|
api_check(L, ttistable(s2v(L->top.p - 1)), "table expected");
|
||||||
mt = hvalue(s2v(L->top - 1));
|
mt = hvalue(s2v(L->top.p - 1));
|
||||||
}
|
}
|
||||||
switch (ttype(obj)) {
|
switch (ttype(obj)) {
|
||||||
case LUA_TTABLE: {
|
case LUA_TTABLE: {
|
||||||
|
@ -1225,7 +1232,7 @@ LUA_API int lua_setmetatable (lua_State *L, int objindex) {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
L->top--;
|
L->top.p--;
|
||||||
lua_unlock(L);
|
lua_unlock(L);
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
@ -1248,11 +1255,11 @@ LUA_API int lua_setiuservalue (lua_State *L, int idx, int n) {
|
||||||
if (!(cast_uint(n) - 1u < cast_uint(uvalue(o)->nuvalue)))
|
if (!(cast_uint(n) - 1u < cast_uint(uvalue(o)->nuvalue)))
|
||||||
res = 0; /* 'n' not in [1, uvalue(o)->nuvalue] */
|
res = 0; /* 'n' not in [1, uvalue(o)->nuvalue] */
|
||||||
else {
|
else {
|
||||||
setobj(L, &uvalue(o)->uv[n - 1].uv, s2v(L->top - 1));
|
setobj(L, &uvalue(o)->uv[n - 1].uv, s2v(L->top.p - 1));
|
||||||
luaC_barrierback(L, gcvalue(o), s2v(L->top - 1));
|
luaC_barrierback(L, gcvalue(o), s2v(L->top.p - 1));
|
||||||
res = 1;
|
res = 1;
|
||||||
}
|
}
|
||||||
L->top--;
|
L->top.p--;
|
||||||
lua_unlock(L);
|
lua_unlock(L);
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
|
@ -1264,7 +1271,8 @@ LUA_API int lua_setiuservalue (lua_State *L, int idx, int n) {
|
||||||
|
|
||||||
|
|
||||||
#define checkresults(L,na,nr) \
|
#define checkresults(L,na,nr) \
|
||||||
api_check(L, (nr) == LUA_MULTRET || (L->ci->top - L->top >= (nr) - (na)), \
|
api_check(L, (nr) == LUA_MULTRET \
|
||||||
|
|| (L->ci->top.p - L->top.p >= (nr) - (na)), \
|
||||||
"results from function overflow current stack size")
|
"results from function overflow current stack size")
|
||||||
|
|
||||||
|
|
||||||
|
@ -1277,7 +1285,7 @@ LUA_API void lua_callk (lua_State *L, int nargs, int nresults,
|
||||||
api_checknelems(L, nargs+1);
|
api_checknelems(L, nargs+1);
|
||||||
api_check(L, L->status == LUA_OK, "cannot do calls on non-normal thread");
|
api_check(L, L->status == LUA_OK, "cannot do calls on non-normal thread");
|
||||||
checkresults(L, nargs, nresults);
|
checkresults(L, nargs, nresults);
|
||||||
func = L->top - (nargs+1);
|
func = L->top.p - (nargs+1);
|
||||||
if (k != NULL && yieldable(L)) { /* need to prepare continuation? */
|
if (k != NULL && yieldable(L)) { /* need to prepare continuation? */
|
||||||
L->ci->u.c.k = k; /* save continuation */
|
L->ci->u.c.k = k; /* save continuation */
|
||||||
L->ci->u.c.ctx = ctx; /* save context */
|
L->ci->u.c.ctx = ctx; /* save context */
|
||||||
|
@ -1325,7 +1333,7 @@ LUA_API int lua_pcallk (lua_State *L, int nargs, int nresults, int errfunc,
|
||||||
api_check(L, ttisfunction(s2v(o)), "error handler must be a function");
|
api_check(L, ttisfunction(s2v(o)), "error handler must be a function");
|
||||||
func = savestack(L, o);
|
func = savestack(L, o);
|
||||||
}
|
}
|
||||||
c.func = L->top - (nargs+1); /* function to be called */
|
c.func = L->top.p - (nargs+1); /* function to be called */
|
||||||
if (k == NULL || !yieldable(L)) { /* no continuation or no yieldable? */
|
if (k == NULL || !yieldable(L)) { /* no continuation or no yieldable? */
|
||||||
c.nresults = nresults; /* do a 'conventional' protected call */
|
c.nresults = nresults; /* do a 'conventional' protected call */
|
||||||
status = luaD_pcall(L, f_call, &c, savestack(L, c.func), func);
|
status = luaD_pcall(L, f_call, &c, savestack(L, c.func), func);
|
||||||
|
@ -1360,12 +1368,12 @@ LUA_API int lua_load (lua_State *L, lua_Reader reader, void *data,
|
||||||
luaZ_init(L, &z, reader, data);
|
luaZ_init(L, &z, reader, data);
|
||||||
status = luaD_protectedparser(L, &z, chunkname, mode);
|
status = luaD_protectedparser(L, &z, chunkname, mode);
|
||||||
if (status == LUA_OK) { /* no errors? */
|
if (status == LUA_OK) { /* no errors? */
|
||||||
LClosure *f = clLvalue(s2v(L->top - 1)); /* get newly created function */
|
LClosure *f = clLvalue(s2v(L->top.p - 1)); /* get new function */
|
||||||
if (f->nupvalues >= 1) { /* does it have an upvalue? */
|
if (f->nupvalues >= 1) { /* does it have an upvalue? */
|
||||||
/* get global table from registry */
|
/* get global table from registry */
|
||||||
const TValue *gt = getGtable(L);
|
const TValue *gt = getGtable(L);
|
||||||
/* set global table as 1st upvalue of 'f' (may be LUA_ENV) */
|
/* set global table as 1st upvalue of 'f' (may be LUA_ENV) */
|
||||||
setobj(L, f->upvals[0]->v, gt);
|
setobj(L, f->upvals[0]->v.p, gt);
|
||||||
luaC_barrier(L, f->upvals[0], gt);
|
luaC_barrier(L, f->upvals[0], gt);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1379,7 +1387,7 @@ LUA_API int lua_dump (lua_State *L, lua_Writer writer, void *data, int strip) {
|
||||||
TValue *o;
|
TValue *o;
|
||||||
lua_lock(L);
|
lua_lock(L);
|
||||||
api_checknelems(L, 1);
|
api_checknelems(L, 1);
|
||||||
o = s2v(L->top - 1);
|
o = s2v(L->top.p - 1);
|
||||||
if (isLfunction(o))
|
if (isLfunction(o))
|
||||||
status = luaU_dump(L, getproto(o), writer, data, strip);
|
status = luaU_dump(L, getproto(o), writer, data, strip);
|
||||||
else
|
else
|
||||||
|
@ -1400,18 +1408,19 @@ LUA_API int lua_status (lua_State *L) {
|
||||||
LUA_API int lua_gc (lua_State *L, int what, ...) {
|
LUA_API int lua_gc (lua_State *L, int what, ...) {
|
||||||
va_list argp;
|
va_list argp;
|
||||||
int res = 0;
|
int res = 0;
|
||||||
global_State *g;
|
global_State *g = G(L);
|
||||||
|
if (g->gcstp & GCSTPGC) /* internal stop? */
|
||||||
|
return -1; /* all options are invalid when stopped */
|
||||||
lua_lock(L);
|
lua_lock(L);
|
||||||
g = G(L);
|
|
||||||
va_start(argp, what);
|
va_start(argp, what);
|
||||||
switch (what) {
|
switch (what) {
|
||||||
case LUA_GCSTOP: {
|
case LUA_GCSTOP: {
|
||||||
g->gcrunning = 0;
|
g->gcstp = GCSTPUSR; /* stopped by the user */
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case LUA_GCRESTART: {
|
case LUA_GCRESTART: {
|
||||||
luaE_setdebt(g, 0);
|
luaE_setdebt(g, 0);
|
||||||
g->gcrunning = 1;
|
g->gcstp = 0; /* (GCSTPGC must be already zero here) */
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case LUA_GCCOLLECT: {
|
case LUA_GCCOLLECT: {
|
||||||
|
@ -1430,8 +1439,8 @@ LUA_API int lua_gc (lua_State *L, int what, ...) {
|
||||||
case LUA_GCSTEP: {
|
case LUA_GCSTEP: {
|
||||||
int data = va_arg(argp, int);
|
int data = va_arg(argp, int);
|
||||||
l_mem debt = 1; /* =1 to signal that it did an actual step */
|
l_mem debt = 1; /* =1 to signal that it did an actual step */
|
||||||
lu_byte oldrunning = g->gcrunning;
|
lu_byte oldstp = g->gcstp;
|
||||||
g->gcrunning = 1; /* allow GC to run */
|
g->gcstp = 0; /* allow GC to run (GCSTPGC must be zero here) */
|
||||||
if (data == 0) {
|
if (data == 0) {
|
||||||
luaE_setdebt(g, 0); /* do a basic step */
|
luaE_setdebt(g, 0); /* do a basic step */
|
||||||
luaC_step(L);
|
luaC_step(L);
|
||||||
|
@ -1441,7 +1450,7 @@ LUA_API int lua_gc (lua_State *L, int what, ...) {
|
||||||
luaE_setdebt(g, debt);
|
luaE_setdebt(g, debt);
|
||||||
luaC_checkGC(L);
|
luaC_checkGC(L);
|
||||||
}
|
}
|
||||||
g->gcrunning = oldrunning; /* restore previous state */
|
g->gcstp = oldstp; /* restore previous state */
|
||||||
if (debt > 0 && g->gcstate == GCSpause) /* end of cycle? */
|
if (debt > 0 && g->gcstate == GCSpause) /* end of cycle? */
|
||||||
res = 1; /* signal it */
|
res = 1; /* signal it */
|
||||||
break;
|
break;
|
||||||
|
@ -1459,7 +1468,7 @@ LUA_API int lua_gc (lua_State *L, int what, ...) {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case LUA_GCISRUNNING: {
|
case LUA_GCISRUNNING: {
|
||||||
res = g->gcrunning;
|
res = gcrunning(g);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case LUA_GCGEN: {
|
case LUA_GCGEN: {
|
||||||
|
@ -1511,7 +1520,7 @@ LUA_API int lua_gc (lua_State *L, int what, ...) {
|
||||||
LUA_API int lua_error (lua_State *L) {
|
LUA_API int lua_error (lua_State *L) {
|
||||||
TValue *errobj;
|
TValue *errobj;
|
||||||
lua_lock(L);
|
lua_lock(L);
|
||||||
errobj = s2v(L->top - 1);
|
errobj = s2v(L->top.p - 1);
|
||||||
api_checknelems(L, 1);
|
api_checknelems(L, 1);
|
||||||
/* error object is the memory error message? */
|
/* error object is the memory error message? */
|
||||||
if (ttisshrstring(errobj) && eqshrstr(tsvalue(errobj), G(L)->memerrmsg))
|
if (ttisshrstring(errobj) && eqshrstr(tsvalue(errobj), G(L)->memerrmsg))
|
||||||
|
@ -1519,7 +1528,7 @@ LUA_API int lua_error (lua_State *L) {
|
||||||
else
|
else
|
||||||
luaG_errormsg(L); /* raise a regular error */
|
luaG_errormsg(L); /* raise a regular error */
|
||||||
/* code unreachable; will unlock when control actually leaves the kernel */
|
/* code unreachable; will unlock when control actually leaves the kernel */
|
||||||
__builtin_unreachable();
|
__builtin_unreachable(); // [jart]
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -1558,12 +1567,12 @@ LUA_API int lua_next (lua_State *L, int idx) {
|
||||||
lua_lock(L);
|
lua_lock(L);
|
||||||
api_checknelems(L, 1);
|
api_checknelems(L, 1);
|
||||||
t = gettable(L, idx);
|
t = gettable(L, idx);
|
||||||
more = luaH_next(L, t, L->top - 1);
|
more = luaH_next(L, t, L->top.p - 1);
|
||||||
if (more) {
|
if (more) {
|
||||||
api_incr_top(L);
|
api_incr_top(L);
|
||||||
}
|
}
|
||||||
else /* no more elements */
|
else /* no more elements */
|
||||||
L->top -= 1; /* remove key */
|
L->top.p -= 1; /* remove key */
|
||||||
lua_unlock(L);
|
lua_unlock(L);
|
||||||
return more;
|
return more;
|
||||||
}
|
}
|
||||||
|
@ -1596,7 +1605,7 @@ LUA_API void lua_toclose (lua_State *L, int idx) {
|
||||||
lua_lock(L);
|
lua_lock(L);
|
||||||
o = index2stack(L, idx);
|
o = index2stack(L, idx);
|
||||||
nresults = L->ci->nresults;
|
nresults = L->ci->nresults;
|
||||||
api_check(L, L->tbclist < o, "given index below or equal a marked one");
|
api_check(L, L->tbclist.p < o, "given index below or equal a marked one");
|
||||||
luaF_newtbcupval(L, o); /* create new to-be-closed upvalue */
|
luaF_newtbcupval(L, o); /* create new to-be-closed upvalue */
|
||||||
if (!hastocloseCfunc(nresults)) /* function not marked yet? */
|
if (!hastocloseCfunc(nresults)) /* function not marked yet? */
|
||||||
L->ci->nresults = codeNresults(nresults); /* mark it */
|
L->ci->nresults = codeNresults(nresults); /* mark it */
|
||||||
|
@ -1619,7 +1628,7 @@ LUA_API void lua_concat (lua_State *L, int n) {
|
||||||
if (n > 0)
|
if (n > 0)
|
||||||
luaV_concat(L, n);
|
luaV_concat(L, n);
|
||||||
else { /* nothing to concatenate */
|
else { /* nothing to concatenate */
|
||||||
setsvalue2s(L, L->top, luaS_newlstr(L, "", 0)); /* push empty string */
|
setsvalue2s(L, L->top.p, luaS_newlstr(L, "", 0)); /* push empty string */
|
||||||
api_incr_top(L);
|
api_incr_top(L);
|
||||||
}
|
}
|
||||||
luaC_checkGC(L);
|
luaC_checkGC(L);
|
||||||
|
@ -1638,7 +1647,7 @@ LUA_API void lua_len (lua_State *L, int idx) {
|
||||||
TValue *t;
|
TValue *t;
|
||||||
lua_lock(L);
|
lua_lock(L);
|
||||||
t = index2value(L, idx);
|
t = index2value(L, idx);
|
||||||
luaV_objlen(L, L->top, t);
|
luaV_objlen(L, L->top.p, t);
|
||||||
api_incr_top(L);
|
api_incr_top(L);
|
||||||
lua_unlock(L);
|
lua_unlock(L);
|
||||||
}
|
}
|
||||||
|
@ -1725,7 +1734,7 @@ LUA_API void *lua_newuserdatauv (lua_State *L, size_t size, int nuvalue) {
|
||||||
lua_lock(L);
|
lua_lock(L);
|
||||||
api_check(L, 0 <= nuvalue && nuvalue < USHRT_MAX, "invalid value");
|
api_check(L, 0 <= nuvalue && nuvalue < USHRT_MAX, "invalid value");
|
||||||
u = luaS_newudata(L, size, nuvalue);
|
u = luaS_newudata(L, size, nuvalue);
|
||||||
setuvalue(L, s2v(L->top), u);
|
setuvalue(L, s2v(L->top.p), u);
|
||||||
api_incr_top(L);
|
api_incr_top(L);
|
||||||
luaC_checkGC(L);
|
luaC_checkGC(L);
|
||||||
lua_unlock(L);
|
lua_unlock(L);
|
||||||
|
@ -1733,6 +1742,7 @@ LUA_API void *lua_newuserdatauv (lua_State *L, size_t size, int nuvalue) {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
static const char *aux_upvalue (TValue *fi, int n, TValue **val,
|
static const char *aux_upvalue (TValue *fi, int n, TValue **val,
|
||||||
GCObject **owner) {
|
GCObject **owner) {
|
||||||
switch (ttypetag(fi)) {
|
switch (ttypetag(fi)) {
|
||||||
|
@ -1750,7 +1760,7 @@ static const char *aux_upvalue (TValue *fi, int n, TValue **val,
|
||||||
Proto *p = f->p;
|
Proto *p = f->p;
|
||||||
if (!(cast_uint(n) - 1u < cast_uint(p->sizeupvalues)))
|
if (!(cast_uint(n) - 1u < cast_uint(p->sizeupvalues)))
|
||||||
return NULL; /* 'n' not in [1, p->sizeupvalues] */
|
return NULL; /* 'n' not in [1, p->sizeupvalues] */
|
||||||
*val = f->upvals[n-1]->v;
|
*val = f->upvals[n-1]->v.p;
|
||||||
if (owner) *owner = obj2gco(f->upvals[n - 1]);
|
if (owner) *owner = obj2gco(f->upvals[n - 1]);
|
||||||
name = p->upvalues[n-1].name;
|
name = p->upvalues[n-1].name;
|
||||||
return (name == NULL) ? "(no name)" : getstr(name);
|
return (name == NULL) ? "(no name)" : getstr(name);
|
||||||
|
@ -1776,7 +1786,7 @@ LUA_API const char *lua_getupvalue (lua_State *L, int funcindex, int n) {
|
||||||
lua_lock(L);
|
lua_lock(L);
|
||||||
name = aux_upvalue(index2value(L, funcindex), n, &val, NULL);
|
name = aux_upvalue(index2value(L, funcindex), n, &val, NULL);
|
||||||
if (name) {
|
if (name) {
|
||||||
setobj2s(L, L->top, val);
|
setobj2s(L, L->top.p, val);
|
||||||
api_incr_top(L);
|
api_incr_top(L);
|
||||||
}
|
}
|
||||||
lua_unlock(L);
|
lua_unlock(L);
|
||||||
|
@ -1806,8 +1816,8 @@ LUA_API const char *lua_setupvalue (lua_State *L, int funcindex, int n) {
|
||||||
api_checknelems(L, 1);
|
api_checknelems(L, 1);
|
||||||
name = aux_upvalue(fi, n, &val, &owner);
|
name = aux_upvalue(fi, n, &val, &owner);
|
||||||
if (name) {
|
if (name) {
|
||||||
L->top--;
|
L->top.p--;
|
||||||
setobj(L, val, s2v(L->top));
|
setobj(L, val, s2v(L->top.p));
|
||||||
luaC_barrier(L, owner, val);
|
luaC_barrier(L, owner, val);
|
||||||
}
|
}
|
||||||
lua_unlock(L);
|
lua_unlock(L);
|
||||||
|
|
13
third_party/lua/lapi.h
vendored
13
third_party/lua/lapi.h
vendored
|
@ -5,22 +5,25 @@
|
||||||
#include "third_party/lua/lstate.h"
|
#include "third_party/lua/lstate.h"
|
||||||
|
|
||||||
|
|
||||||
/* Increments 'L->top', checking for stack overflows */
|
/* Increments 'L->top.p', checking for stack overflows */
|
||||||
#define api_incr_top(L) {L->top++; api_check(L, L->top <= L->ci->top, \
|
#define api_incr_top(L) {L->top.p++; \
|
||||||
|
api_check(L, L->top.p <= L->ci->top.p, \
|
||||||
"stack overflow");}
|
"stack overflow");}
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
** If a call returns too many multiple returns, the callee may not have
|
** If a call returns too many multiple returns, the callee may not have
|
||||||
** stack space to accommodate all results. In this case, this macro
|
** stack space to accommodate all results. In this case, this macro
|
||||||
** increases its stack space ('L->ci->top').
|
** increases its stack space ('L->ci->top.p').
|
||||||
*/
|
*/
|
||||||
#define adjustresults(L,nres) \
|
#define adjustresults(L,nres) \
|
||||||
{ if ((nres) <= LUA_MULTRET && L->ci->top < L->top) L->ci->top = L->top; }
|
{ if ((nres) <= LUA_MULTRET && L->ci->top.p < L->top.p) \
|
||||||
|
L->ci->top.p = L->top.p; }
|
||||||
|
|
||||||
|
|
||||||
/* Ensure the stack has at least 'n' elements */
|
/* Ensure the stack has at least 'n' elements */
|
||||||
#define api_checknelems(L,n) api_check(L, (n) < (L->top - L->ci->func), \
|
#define api_checknelems(L,n) \
|
||||||
|
api_check(L, (n) < (L->top.p - L->ci->func.p), \
|
||||||
"not enough elements in the stack")
|
"not enough elements in the stack")
|
||||||
|
|
||||||
|
|
||||||
|
|
64
third_party/lua/lauxlib.c
vendored
64
third_party/lua/lauxlib.c
vendored
|
@ -3,7 +3,7 @@
|
||||||
╚──────────────────────────────────────────────────────────────────────────────╝
|
╚──────────────────────────────────────────────────────────────────────────────╝
|
||||||
│ │
|
│ │
|
||||||
│ Lua │
|
│ Lua │
|
||||||
│ Copyright © 2004-2021 Lua.org, PUC-Rio. │
|
│ Copyright © 2004-2023 Lua.org, PUC-Rio. │
|
||||||
│ │
|
│ │
|
||||||
│ Permission is hereby granted, free of charge, to any person obtaining │
|
│ Permission is hereby granted, free of charge, to any person obtaining │
|
||||||
│ a copy of this software and associated documentation files (the │
|
│ a copy of this software and associated documentation files (the │
|
||||||
|
@ -27,6 +27,7 @@
|
||||||
╚─────────────────────────────────────────────────────────────────────────────*/
|
╚─────────────────────────────────────────────────────────────────────────────*/
|
||||||
#define lauxlib_c
|
#define lauxlib_c
|
||||||
#define LUA_LIB
|
#define LUA_LIB
|
||||||
|
|
||||||
#include "libc/calls/calls.h"
|
#include "libc/calls/calls.h"
|
||||||
#include "libc/errno.h"
|
#include "libc/errno.h"
|
||||||
#include "libc/mem/mem.h"
|
#include "libc/mem/mem.h"
|
||||||
|
@ -191,21 +192,21 @@ LUALIB_API void luaL_traceback (lua_State *L, lua_State *L1,
|
||||||
while (lua_getstack(L1, level++, &ar)) {
|
while (lua_getstack(L1, level++, &ar)) {
|
||||||
if (limit2show-- == 0) { /* too many levels? */
|
if (limit2show-- == 0) { /* too many levels? */
|
||||||
int n = last - level - LEVELS2 + 1; /* number of levels to skip */
|
int n = last - level - LEVELS2 + 1; /* number of levels to skip */
|
||||||
lua_pushfstring(L, "\n...(skipping %d levels)", n);
|
lua_pushfstring(L, "\n\t...\t(skipping %d levels)", n);
|
||||||
luaL_addvalue(&b); /* add warning about skip */
|
luaL_addvalue(&b); /* add warning about skip */
|
||||||
level += n; /* and skip to last levels */
|
level += n; /* and skip to last levels */
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
lua_getinfo(L1, "Slnt", &ar);
|
lua_getinfo(L1, "Slnt", &ar);
|
||||||
if (ar.currentline <= 0)
|
if (ar.currentline <= 0)
|
||||||
lua_pushfstring(L, "\n%s: in ", ar.short_src);
|
lua_pushfstring(L, "\n\t%s: in ", ar.short_src);
|
||||||
else
|
else
|
||||||
lua_pushfstring(L, "\n%s:%d: in ", ar.short_src, ar.currentline);
|
lua_pushfstring(L, "\n\t%s:%d: in ", ar.short_src, ar.currentline);
|
||||||
luaL_addvalue(&b);
|
luaL_addvalue(&b);
|
||||||
pushfuncname(L, &ar);
|
pushfuncname(L, &ar);
|
||||||
luaL_addvalue(&b);
|
luaL_addvalue(&b);
|
||||||
if (ar.istailcall)
|
if (ar.istailcall)
|
||||||
luaL_addstring(&b, "\n(...tail calls...)");
|
luaL_addstring(&b, "\n\t(...tail calls...)");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
luaL_pushresult(&b);
|
luaL_pushresult(&b);
|
||||||
|
@ -764,13 +765,14 @@ static void newbox (lua_State *L) {
|
||||||
|
|
||||||
/*
|
/*
|
||||||
** Compute new size for buffer 'B', enough to accommodate extra 'sz'
|
** Compute new size for buffer 'B', enough to accommodate extra 'sz'
|
||||||
** bytes.
|
** bytes. (The test for "not big enough" also gets the case when the
|
||||||
|
** computation of 'newsize' overflows.)
|
||||||
*/
|
*/
|
||||||
static size_t newbuffsize (luaL_Buffer *B, size_t sz) {
|
static size_t newbuffsize (luaL_Buffer *B, size_t sz) {
|
||||||
size_t newsize = B->size * 2; /* double buffer size */
|
size_t newsize = (B->size / 2) * 3; /* buffer size * 1.5 */
|
||||||
if (l_unlikely(MAX_SIZET - sz < B->n)) /* overflow in (B->n + sz)? */
|
if (l_unlikely(MAX_SIZET - sz < B->n)) /* overflow in (B->n + sz)? */
|
||||||
return luaL_error(B->L, "buffer too large");
|
return luaL_error(B->L, "buffer too large");
|
||||||
if (newsize < B->n + sz) /* double is not big enough? */
|
if (newsize < B->n + sz) /* not big enough? */
|
||||||
newsize = B->n + sz;
|
newsize = B->n + sz;
|
||||||
return newsize;
|
return newsize;
|
||||||
}
|
}
|
||||||
|
@ -872,7 +874,7 @@ LUALIB_API void luaL_pushresultsize (luaL_Buffer *B, size_t sz) {
|
||||||
** box (if existent) is not on the top of the stack. So, instead of
|
** box (if existent) is not on the top of the stack. So, instead of
|
||||||
** calling 'luaL_addlstring', it replicates the code using -2 as the
|
** calling 'luaL_addlstring', it replicates the code using -2 as the
|
||||||
** last argument to 'prepbuffsize', signaling that the box is (or will
|
** last argument to 'prepbuffsize', signaling that the box is (or will
|
||||||
** be) bellow the string being added to the buffer. (Box creation can
|
** be) below the string being added to the buffer. (Box creation can
|
||||||
** trigger an emergency GC, so we should not remove the string from the
|
** trigger an emergency GC, so we should not remove the string from the
|
||||||
** stack before we have the space guaranteed.)
|
** stack before we have the space guaranteed.)
|
||||||
*/
|
*/
|
||||||
|
@ -1020,17 +1022,18 @@ static int errfile (lua_State *L, const char *what, int fnameindex) {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static int skipBOM (LoadF *lf) {
|
/*
|
||||||
const char *p = "\xEF\xBB\xBF"; /* UTF-8 BOM mark */
|
** Skip an optional BOM at the start of a stream. If there is an
|
||||||
int c;
|
** incomplete BOM (the first character is correct but the rest is
|
||||||
lf->n = 0;
|
** not), returns the first character anyway to force an error
|
||||||
do {
|
** (as no chunk can start with 0xEF).
|
||||||
c = getc(lf->f);
|
*/
|
||||||
if (c == EOF || c != *(const unsigned char *)p++) return c;
|
static int skipBOM (FILE *f) {
|
||||||
lf->buff[lf->n++] = c; /* to be read by the parser */
|
int c = getc(f); /* read first character */
|
||||||
} while (*p != '\0');
|
if (c == 0xEF && getc(f) == 0xBB && getc(f) == 0xBF) /* correct BOM? */
|
||||||
lf->n = 0; /* prefix matched; discard it */
|
return getc(f); /* ignore BOM and return next char */
|
||||||
return getc(lf->f); /* return next character */
|
else /* no (valid) BOM */
|
||||||
|
return c; /* return first character */
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -1041,13 +1044,13 @@ static int skipBOM (LoadF *lf) {
|
||||||
** first "valid" character of the file (after the optional BOM and
|
** first "valid" character of the file (after the optional BOM and
|
||||||
** a first-line comment).
|
** a first-line comment).
|
||||||
*/
|
*/
|
||||||
static int skipcomment (LoadF *lf, int *cp) {
|
static int skipcomment (FILE *f, int *cp) {
|
||||||
int c = *cp = skipBOM(lf);
|
int c = *cp = skipBOM(f);
|
||||||
if (c == '#') { /* first line is a comment (Unix exec. file)? */
|
if (c == '#') { /* first line is a comment (Unix exec. file)? */
|
||||||
do { /* skip first line */
|
do { /* skip first line */
|
||||||
c = getc(lf->f);
|
c = getc(f);
|
||||||
} while (c != EOF && c != '\n');
|
} while (c != EOF && c != '\n');
|
||||||
*cp = getc(lf->f); /* skip end-of-line, if present */
|
*cp = getc(f); /* next character after comment, if present */
|
||||||
return 1; /* there was a comment */
|
return 1; /* there was a comment */
|
||||||
}
|
}
|
||||||
else return 0; /* no comment */
|
else return 0; /* no comment */
|
||||||
|
@ -1084,12 +1087,16 @@ LUALIB_API int luaL_loadfilex (lua_State *L, const char *filename,
|
||||||
lf.f = fopen(filename, "r");
|
lf.f = fopen(filename, "r");
|
||||||
if (lf.f == NULL) return errfile(L, "open", fnameindex);
|
if (lf.f == NULL) return errfile(L, "open", fnameindex);
|
||||||
}
|
}
|
||||||
if (skipcomment(&lf, &c)) /* read initial portion */
|
lf.n = 0;
|
||||||
lf.buff[lf.n++] = '\n'; /* add line to correct line numbers */
|
if (skipcomment(lf.f, &c)) /* read initial portion */
|
||||||
if (c == LUA_SIGNATURE[0] && filename) { /* binary file? */
|
lf.buff[lf.n++] = '\n'; /* add newline to correct line numbers */
|
||||||
|
if (c == LUA_SIGNATURE[0]) { /* binary file? */
|
||||||
|
lf.n = 0; /* remove possible newline */
|
||||||
|
if (filename) { /* "real" file? */
|
||||||
lf.f = freopen(filename, "rb", lf.f); /* reopen in binary mode */
|
lf.f = freopen(filename, "rb", lf.f); /* reopen in binary mode */
|
||||||
if (lf.f == NULL) return errfile(L, "reopen", fnameindex);
|
if (lf.f == NULL) return errfile(L, "reopen", fnameindex);
|
||||||
skipcomment(&lf, &c); /* re-read initial portion */
|
skipcomment(lf.f, &c); /* re-read initial portion */
|
||||||
|
}
|
||||||
}
|
}
|
||||||
if (c != EOF)
|
if (c != EOF)
|
||||||
lf.buff[lf.n++] = c; /* 'c' is the first character of the stream */
|
lf.buff[lf.n++] = c; /* 'c' is the first character of the stream */
|
||||||
|
@ -1236,6 +1243,7 @@ LUALIB_API lua_Integer luaL_len (lua_State *L, int idx) {
|
||||||
* the result of the call as its result.
|
* the result of the call as its result.
|
||||||
*/
|
*/
|
||||||
LUALIB_API const char *luaL_tolstring (lua_State *L, int idx, size_t *len) {
|
LUALIB_API const char *luaL_tolstring (lua_State *L, int idx, size_t *len) {
|
||||||
|
idx = lua_absindex(L,idx);
|
||||||
if (luaL_callmeta(L, idx, "__tostring")) { /* metafield? */
|
if (luaL_callmeta(L, idx, "__tostring")) { /* metafield? */
|
||||||
if (!lua_isstring(L, -1))
|
if (!lua_isstring(L, -1))
|
||||||
luaL_error(L, "'__tostring' must return a string");
|
luaL_error(L, "'__tostring' must return a string");
|
||||||
|
|
13
third_party/lua/lauxlib.h
vendored
13
third_party/lua/lauxlib.h
vendored
|
@ -1,10 +1,12 @@
|
||||||
#ifndef lauxlib_h
|
#ifndef lauxlib_h
|
||||||
#define lauxlib_h
|
#define lauxlib_h
|
||||||
|
|
||||||
#include "libc/assert.h"
|
#include "libc/assert.h"
|
||||||
#include "libc/stdio/stdio.h"
|
#include "libc/stdio/stdio.h"
|
||||||
#include "third_party/lua/lua.h"
|
#include "third_party/lua/lua.h"
|
||||||
#include "third_party/lua/luaconf.h"
|
#include "third_party/lua/luaconf.h"
|
||||||
|
|
||||||
|
|
||||||
/* global table */
|
/* global table */
|
||||||
#define LUA_GNAME "_G"
|
#define LUA_GNAME "_G"
|
||||||
|
|
||||||
|
@ -91,7 +93,7 @@ LUALIB_API lua_State *(luaL_newstate) (void);
|
||||||
|
|
||||||
LUALIB_API lua_Integer (luaL_len) (lua_State *L, int idx);
|
LUALIB_API lua_Integer (luaL_len) (lua_State *L, int idx);
|
||||||
|
|
||||||
LUALIB_API void luaL_addgsub (luaL_Buffer *b, const char *s,
|
LUALIB_API void (luaL_addgsub) (luaL_Buffer *b, const char *s,
|
||||||
const char *p, const char *r);
|
const char *p, const char *r);
|
||||||
LUALIB_API const char *(luaL_gsub) (lua_State *L, const char *s,
|
LUALIB_API const char *(luaL_gsub) (lua_State *L, const char *s,
|
||||||
const char *p, const char *r);
|
const char *p, const char *r);
|
||||||
|
@ -146,6 +148,14 @@ LUALIB_API void (luaL_requiref) (lua_State *L, const char *modname,
|
||||||
#define luaL_loadbuffer(L,s,sz,n) luaL_loadbufferx(L,s,sz,n,NULL)
|
#define luaL_loadbuffer(L,s,sz,n) luaL_loadbufferx(L,s,sz,n,NULL)
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
** Perform arithmetic operations on lua_Integer values with wrap-around
|
||||||
|
** semantics, as the Lua core does.
|
||||||
|
*/
|
||||||
|
#define luaL_intop(op,v1,v2) \
|
||||||
|
((lua_Integer)((lua_Unsigned)(v1) op (lua_Unsigned)(v2)))
|
||||||
|
|
||||||
|
|
||||||
/* push the value used to represent failure/error */
|
/* push the value used to represent failure/error */
|
||||||
#define luaL_pushfail(L) lua_pushnil(L)
|
#define luaL_pushfail(L) lua_pushnil(L)
|
||||||
|
|
||||||
|
@ -158,6 +168,7 @@ LUALIB_API void (luaL_requiref) (lua_State *L, const char *modname,
|
||||||
#if defined LUAI_ASSERT
|
#if defined LUAI_ASSERT
|
||||||
#define lua_assert(c) assert(c)
|
#define lua_assert(c) assert(c)
|
||||||
#else
|
#else
|
||||||
|
// [jart]
|
||||||
#define lua_assert(c) unassert(c)
|
#define lua_assert(c) unassert(c)
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
28
third_party/lua/lbaselib.c
vendored
28
third_party/lua/lbaselib.c
vendored
|
@ -3,7 +3,7 @@
|
||||||
╚──────────────────────────────────────────────────────────────────────────────╝
|
╚──────────────────────────────────────────────────────────────────────────────╝
|
||||||
│ │
|
│ │
|
||||||
│ Lua │
|
│ Lua │
|
||||||
│ Copyright © 2004-2021 Lua.org, PUC-Rio. │
|
│ Copyright © 2004-2023 Lua.org, PUC-Rio. │
|
||||||
│ │
|
│ │
|
||||||
│ Permission is hereby granted, free of charge, to any person obtaining │
|
│ Permission is hereby granted, free of charge, to any person obtaining │
|
||||||
│ a copy of this software and associated documentation files (the │
|
│ a copy of this software and associated documentation files (the │
|
||||||
|
@ -27,6 +27,7 @@
|
||||||
╚─────────────────────────────────────────────────────────────────────────────*/
|
╚─────────────────────────────────────────────────────────────────────────────*/
|
||||||
#define lbaselib_c
|
#define lbaselib_c
|
||||||
#define LUA_LIB
|
#define LUA_LIB
|
||||||
|
|
||||||
#include "libc/str/str.h"
|
#include "libc/str/str.h"
|
||||||
#include "third_party/lua/lauxlib.h"
|
#include "third_party/lua/lauxlib.h"
|
||||||
#include "third_party/lua/lprefix.h"
|
#include "third_party/lua/lprefix.h"
|
||||||
|
@ -196,12 +197,20 @@ static int luaB_rawset (lua_State *L) {
|
||||||
|
|
||||||
|
|
||||||
static int pushmode (lua_State *L, int oldmode) {
|
static int pushmode (lua_State *L, int oldmode) {
|
||||||
|
if (oldmode == -1)
|
||||||
|
luaL_pushfail(L); /* invalid call to 'lua_gc' */
|
||||||
|
else
|
||||||
lua_pushstring(L, (oldmode == LUA_GCINC) ? "incremental"
|
lua_pushstring(L, (oldmode == LUA_GCINC) ? "incremental"
|
||||||
: "generational");
|
: "generational");
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
** check whether call to 'lua_gc' was valid (not inside a finalizer)
|
||||||
|
*/
|
||||||
|
#define checkvalres(res) { if (res == -1) break; }
|
||||||
|
|
||||||
static int luaB_collectgarbage (lua_State *L) {
|
static int luaB_collectgarbage (lua_State *L) {
|
||||||
static const char *const opts[] = {"stop", "restart", "collect",
|
static const char *const opts[] = {"stop", "restart", "collect",
|
||||||
"count", "step", "setpause", "setstepmul",
|
"count", "step", "setpause", "setstepmul",
|
||||||
|
@ -214,12 +223,14 @@ static int luaB_collectgarbage (lua_State *L) {
|
||||||
case LUA_GCCOUNT: {
|
case LUA_GCCOUNT: {
|
||||||
int k = lua_gc(L, o);
|
int k = lua_gc(L, o);
|
||||||
int b = lua_gc(L, LUA_GCCOUNTB);
|
int b = lua_gc(L, LUA_GCCOUNTB);
|
||||||
|
checkvalres(k);
|
||||||
lua_pushnumber(L, (lua_Number)k + ((lua_Number)b/1024));
|
lua_pushnumber(L, (lua_Number)k + ((lua_Number)b/1024));
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
case LUA_GCSTEP: {
|
case LUA_GCSTEP: {
|
||||||
int step = (int)luaL_optinteger(L, 2, 0);
|
int step = (int)luaL_optinteger(L, 2, 0);
|
||||||
int res = lua_gc(L, o, step);
|
int res = lua_gc(L, o, step);
|
||||||
|
checkvalres(res);
|
||||||
lua_pushboolean(L, res);
|
lua_pushboolean(L, res);
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
@ -227,11 +238,13 @@ static int luaB_collectgarbage (lua_State *L) {
|
||||||
case LUA_GCSETSTEPMUL: {
|
case LUA_GCSETSTEPMUL: {
|
||||||
int p = (int)luaL_optinteger(L, 2, 0);
|
int p = (int)luaL_optinteger(L, 2, 0);
|
||||||
int previous = lua_gc(L, o, p);
|
int previous = lua_gc(L, o, p);
|
||||||
|
checkvalres(previous);
|
||||||
lua_pushinteger(L, previous);
|
lua_pushinteger(L, previous);
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
case LUA_GCISRUNNING: {
|
case LUA_GCISRUNNING: {
|
||||||
int res = lua_gc(L, o);
|
int res = lua_gc(L, o);
|
||||||
|
checkvalres(res);
|
||||||
lua_pushboolean(L, res);
|
lua_pushboolean(L, res);
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
@ -248,10 +261,13 @@ static int luaB_collectgarbage (lua_State *L) {
|
||||||
}
|
}
|
||||||
default: {
|
default: {
|
||||||
int res = lua_gc(L, o);
|
int res = lua_gc(L, o);
|
||||||
|
checkvalres(res);
|
||||||
lua_pushinteger(L, res);
|
lua_pushinteger(L, res);
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
luaL_pushfail(L); /* invalid call (inside a finalizer) */
|
||||||
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -275,6 +291,11 @@ static int luaB_next (lua_State *L) {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static int pairscont (lua_State *L, int status, lua_KContext k) {
|
||||||
|
(void)L; (void)status; (void)k; /* unused */
|
||||||
|
return 3;
|
||||||
|
}
|
||||||
|
|
||||||
static int luaB_pairs (lua_State *L) {
|
static int luaB_pairs (lua_State *L) {
|
||||||
luaL_checkany(L, 1);
|
luaL_checkany(L, 1);
|
||||||
if (luaL_getmetafield(L, 1, "__pairs") == LUA_TNIL) { /* no metamethod? */
|
if (luaL_getmetafield(L, 1, "__pairs") == LUA_TNIL) { /* no metamethod? */
|
||||||
|
@ -284,7 +305,7 @@ static int luaB_pairs (lua_State *L) {
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
lua_pushvalue(L, 1); /* argument 'self' to metamethod */
|
lua_pushvalue(L, 1); /* argument 'self' to metamethod */
|
||||||
lua_call(L, 1, 3); /* get 3 values from metamethod */
|
lua_callk(L, 1, 3, 0, pairscont); /* get 3 values from metamethod */
|
||||||
}
|
}
|
||||||
return 3;
|
return 3;
|
||||||
}
|
}
|
||||||
|
@ -294,7 +315,8 @@ static int luaB_pairs (lua_State *L) {
|
||||||
** Traversal function for 'ipairs'
|
** Traversal function for 'ipairs'
|
||||||
*/
|
*/
|
||||||
static int ipairsaux (lua_State *L) {
|
static int ipairsaux (lua_State *L) {
|
||||||
lua_Integer i = luaL_checkinteger(L, 2) + 1;
|
lua_Integer i = luaL_checkinteger(L, 2);
|
||||||
|
i = luaL_intop(+, i, 1);
|
||||||
lua_pushinteger(L, i);
|
lua_pushinteger(L, i);
|
||||||
return (lua_geti(L, 1, i) == LUA_TNIL) ? 1 : 2;
|
return (lua_geti(L, 1, i) == LUA_TNIL) ? 1 : 2;
|
||||||
}
|
}
|
||||||
|
|
171
third_party/lua/lcode.c
vendored
171
third_party/lua/lcode.c
vendored
|
@ -3,7 +3,7 @@
|
||||||
╚──────────────────────────────────────────────────────────────────────────────╝
|
╚──────────────────────────────────────────────────────────────────────────────╝
|
||||||
│ │
|
│ │
|
||||||
│ Lua │
|
│ Lua │
|
||||||
│ Copyright © 2004-2021 Lua.org, PUC-Rio. │
|
│ Copyright © 2004-2023 Lua.org, PUC-Rio. │
|
||||||
│ │
|
│ │
|
||||||
│ Permission is hereby granted, free of charge, to any person obtaining │
|
│ Permission is hereby granted, free of charge, to any person obtaining │
|
||||||
│ a copy of this software and associated documentation files (the │
|
│ a copy of this software and associated documentation files (the │
|
||||||
|
@ -27,6 +27,7 @@
|
||||||
╚─────────────────────────────────────────────────────────────────────────────*/
|
╚─────────────────────────────────────────────────────────────────────────────*/
|
||||||
#define lcode_c
|
#define lcode_c
|
||||||
#define LUA_CORE
|
#define LUA_CORE
|
||||||
|
|
||||||
#include "libc/fmt/conv.h"
|
#include "libc/fmt/conv.h"
|
||||||
#include "third_party/lua/lcode.h"
|
#include "third_party/lua/lcode.h"
|
||||||
#include "third_party/lua/ldebug.h"
|
#include "third_party/lua/ldebug.h"
|
||||||
|
@ -595,24 +596,41 @@ static int stringK (FuncState *fs, TString *s) {
|
||||||
|
|
||||||
/*
|
/*
|
||||||
** Add an integer to list of constants and return its index.
|
** Add an integer to list of constants and return its index.
|
||||||
** Integers use userdata as keys to avoid collision with floats with
|
|
||||||
** same value; conversion to 'void*' is used only for hashing, so there
|
|
||||||
** are no "precision" problems.
|
|
||||||
*/
|
*/
|
||||||
static int luaK_intK (FuncState *fs, lua_Integer n) {
|
static int luaK_intK (FuncState *fs, lua_Integer n) {
|
||||||
TValue k, o;
|
TValue o;
|
||||||
setpvalue(&k, cast_voidp(cast_sizet(n)));
|
|
||||||
setivalue(&o, n);
|
setivalue(&o, n);
|
||||||
return addk(fs, &k, &o);
|
return addk(fs, &o, &o); /* use integer itself as key */
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
** Add a float to list of constants and return its index.
|
** Add a float to list of constants and return its index. Floats
|
||||||
|
** with integral values need a different key, to avoid collision
|
||||||
|
** with actual integers. To that, we add to the number its smaller
|
||||||
|
** power-of-two fraction that is still significant in its scale.
|
||||||
|
** For doubles, that would be 1/2^52.
|
||||||
|
** (This method is not bulletproof: there may be another float
|
||||||
|
** with that value, and for floats larger than 2^53 the result is
|
||||||
|
** still an integer. At worst, this only wastes an entry with
|
||||||
|
** a duplicate.)
|
||||||
*/
|
*/
|
||||||
static int luaK_numberK (FuncState *fs, lua_Number r) {
|
static int luaK_numberK (FuncState *fs, lua_Number r) {
|
||||||
TValue o;
|
TValue o;
|
||||||
|
lua_Integer ik;
|
||||||
setfltvalue(&o, r);
|
setfltvalue(&o, r);
|
||||||
|
if (!luaV_flttointeger(r, &ik, F2Ieq)) /* not an integral value? */
|
||||||
return addk(fs, &o, &o); /* use number itself as key */
|
return addk(fs, &o, &o); /* use number itself as key */
|
||||||
|
else { /* must build an alternative key */
|
||||||
|
const int nbm = l_floatatt(MANT_DIG);
|
||||||
|
const lua_Number q = l_mathop(ldexp)(l_mathop(1.0), -nbm + 1);
|
||||||
|
const lua_Number k = (ik == 0) ? q : r + r*q; /* new key */
|
||||||
|
TValue kv;
|
||||||
|
setfltvalue(&kv, k);
|
||||||
|
/* result is not an integral value, unless value is too large */
|
||||||
|
lua_assert(!luaV_flttointeger(k, &ik, F2Ieq) ||
|
||||||
|
l_mathop(fabs)(r) >= l_mathop(1e6));
|
||||||
|
return addk(fs, &kv, &o);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -1348,6 +1366,35 @@ static int constfolding (FuncState *fs, int op, expdesc *e1,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
** Convert a BinOpr to an OpCode (ORDER OPR - ORDER OP)
|
||||||
|
*/
|
||||||
|
l_sinline OpCode binopr2op (BinOpr opr, BinOpr baser, OpCode base) {
|
||||||
|
lua_assert(baser <= opr &&
|
||||||
|
((baser == OPR_ADD && opr <= OPR_SHR) ||
|
||||||
|
(baser == OPR_LT && opr <= OPR_LE)));
|
||||||
|
return cast(OpCode, (cast_int(opr) - cast_int(baser)) + cast_int(base));
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
** Convert a UnOpr to an OpCode (ORDER OPR - ORDER OP)
|
||||||
|
*/
|
||||||
|
l_sinline OpCode unopr2op (UnOpr opr) {
|
||||||
|
return cast(OpCode, (cast_int(opr) - cast_int(OPR_MINUS)) +
|
||||||
|
cast_int(OP_UNM));
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
** Convert a BinOpr to a tag method (ORDER OPR - ORDER TM)
|
||||||
|
*/
|
||||||
|
l_sinline TMS binopr2TM (BinOpr opr) {
|
||||||
|
lua_assert(OPR_ADD <= opr && opr <= OPR_SHR);
|
||||||
|
return cast(TMS, (cast_int(opr) - cast_int(OPR_ADD)) + cast_int(TM_ADD));
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
** Emit code for unary expressions that "produce values"
|
** Emit code for unary expressions that "produce values"
|
||||||
** (everything but 'not').
|
** (everything but 'not').
|
||||||
|
@ -1386,12 +1433,15 @@ static void finishbinexpval (FuncState *fs, expdesc *e1, expdesc *e2,
|
||||||
** Emit code for binary expressions that "produce values" over
|
** Emit code for binary expressions that "produce values" over
|
||||||
** two registers.
|
** two registers.
|
||||||
*/
|
*/
|
||||||
static void codebinexpval (FuncState *fs, OpCode op,
|
static void codebinexpval (FuncState *fs, BinOpr opr,
|
||||||
expdesc *e1, expdesc *e2, int line) {
|
expdesc *e1, expdesc *e2, int line) {
|
||||||
int v2 = luaK_exp2anyreg(fs, e2); /* both operands are in registers */
|
OpCode op = binopr2op(opr, OPR_ADD, OP_ADD);
|
||||||
|
int v2 = luaK_exp2anyreg(fs, e2); /* make sure 'e2' is in a register */
|
||||||
|
/* 'e1' must be already in a register or it is a constant */
|
||||||
|
lua_assert((VNIL <= e1->k && e1->k <= VKSTR) ||
|
||||||
|
e1->k == VNONRELOC || e1->k == VRELOC);
|
||||||
lua_assert(OP_ADD <= op && op <= OP_SHR);
|
lua_assert(OP_ADD <= op && op <= OP_SHR);
|
||||||
finishbinexpval(fs, e1, e2, op, v2, 0, line, OP_MMBIN,
|
finishbinexpval(fs, e1, e2, op, v2, 0, line, OP_MMBIN, binopr2TM(opr));
|
||||||
cast(TMS, (op - OP_ADD) + TM_ADD));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -1407,6 +1457,18 @@ static void codebini (FuncState *fs, OpCode op,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
** Code binary operators with K operand.
|
||||||
|
*/
|
||||||
|
static void codebinK (FuncState *fs, BinOpr opr,
|
||||||
|
expdesc *e1, expdesc *e2, int flip, int line) {
|
||||||
|
TMS event = binopr2TM(opr);
|
||||||
|
int v2 = e2->u.info; /* K index */
|
||||||
|
OpCode op = binopr2op(opr, OPR_ADD, OP_ADDK);
|
||||||
|
finishbinexpval(fs, e1, e2, op, v2, flip, line, OP_MMBINK, event);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/* Try to code a binary operator negating its second operand.
|
/* Try to code a binary operator negating its second operand.
|
||||||
** For the metamethod, 2nd operand must keep its original value.
|
** For the metamethod, 2nd operand must keep its original value.
|
||||||
*/
|
*/
|
||||||
|
@ -1434,24 +1496,27 @@ static void swapexps (expdesc *e1, expdesc *e2) {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
** Code binary operators with no constant operand.
|
||||||
|
*/
|
||||||
|
static void codebinNoK (FuncState *fs, BinOpr opr,
|
||||||
|
expdesc *e1, expdesc *e2, int flip, int line) {
|
||||||
|
if (flip)
|
||||||
|
swapexps(e1, e2); /* back to original order */
|
||||||
|
codebinexpval(fs, opr, e1, e2, line); /* use standard operators */
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
** Code arithmetic operators ('+', '-', ...). If second operand is a
|
** Code arithmetic operators ('+', '-', ...). If second operand is a
|
||||||
** constant in the proper range, use variant opcodes with K operands.
|
** constant in the proper range, use variant opcodes with K operands.
|
||||||
*/
|
*/
|
||||||
static void codearith (FuncState *fs, BinOpr opr,
|
static void codearith (FuncState *fs, BinOpr opr,
|
||||||
expdesc *e1, expdesc *e2, int flip, int line) {
|
expdesc *e1, expdesc *e2, int flip, int line) {
|
||||||
TMS event = cast(TMS, opr + TM_ADD);
|
if (tonumeral(e2, NULL) && luaK_exp2K(fs, e2)) /* K operand? */
|
||||||
if (tonumeral(e2, NULL) && luaK_exp2K(fs, e2)) { /* K operand? */
|
codebinK(fs, opr, e1, e2, flip, line);
|
||||||
int v2 = e2->u.info; /* K index */
|
else /* 'e2' is neither an immediate nor a K operand */
|
||||||
OpCode op = cast(OpCode, opr + OP_ADDK);
|
codebinNoK(fs, opr, e1, e2, flip, line);
|
||||||
finishbinexpval(fs, e1, e2, op, v2, flip, line, OP_MMBINK, event);
|
|
||||||
}
|
|
||||||
else { /* 'e2' is neither an immediate nor a K operand */
|
|
||||||
OpCode op = cast(OpCode, opr + OP_ADD);
|
|
||||||
if (flip)
|
|
||||||
swapexps(e1, e2); /* back to original order */
|
|
||||||
codebinexpval(fs, op, e1, e2, line); /* use standard operators */
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -1468,35 +1533,27 @@ static void codecommutative (FuncState *fs, BinOpr op,
|
||||||
flip = 1;
|
flip = 1;
|
||||||
}
|
}
|
||||||
if (op == OPR_ADD && isSCint(e2)) /* immediate operand? */
|
if (op == OPR_ADD && isSCint(e2)) /* immediate operand? */
|
||||||
codebini(fs, cast(OpCode, OP_ADDI), e1, e2, flip, line, TM_ADD);
|
codebini(fs, OP_ADDI, e1, e2, flip, line, TM_ADD);
|
||||||
else
|
else
|
||||||
codearith(fs, op, e1, e2, flip, line);
|
codearith(fs, op, e1, e2, flip, line);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
** Code bitwise operations; they are all associative, so the function
|
** Code bitwise operations; they are all commutative, so the function
|
||||||
** tries to put an integer constant as the 2nd operand (a K operand).
|
** tries to put an integer constant as the 2nd operand (a K operand).
|
||||||
*/
|
*/
|
||||||
static void codebitwise (FuncState *fs, BinOpr opr,
|
static void codebitwise (FuncState *fs, BinOpr opr,
|
||||||
expdesc *e1, expdesc *e2, int line) {
|
expdesc *e1, expdesc *e2, int line) {
|
||||||
int flip = 0;
|
int flip = 0;
|
||||||
int v2;
|
if (e1->k == VKINT) {
|
||||||
OpCode op;
|
|
||||||
if (e1->k == VKINT && luaK_exp2RK(fs, e1)) {
|
|
||||||
swapexps(e1, e2); /* 'e2' will be the constant operand */
|
swapexps(e1, e2); /* 'e2' will be the constant operand */
|
||||||
flip = 1;
|
flip = 1;
|
||||||
}
|
}
|
||||||
else if (!(e2->k == VKINT && luaK_exp2RK(fs, e2))) { /* no constants? */
|
if (e2->k == VKINT && luaK_exp2K(fs, e2)) /* K operand? */
|
||||||
op = cast(OpCode, opr + OP_ADD);
|
codebinK(fs, opr, e1, e2, flip, line);
|
||||||
codebinexpval(fs, op, e1, e2, line); /* all-register opcodes */
|
else /* no constants */
|
||||||
return;
|
codebinNoK(fs, opr, e1, e2, flip, line);
|
||||||
}
|
|
||||||
v2 = e2->u.info; /* index in K array */
|
|
||||||
op = cast(OpCode, opr + OP_ADDK);
|
|
||||||
lua_assert(ttisinteger(&fs->f->k[v2]));
|
|
||||||
finishbinexpval(fs, e1, e2, op, v2, flip, line, OP_MMBINK,
|
|
||||||
cast(TMS, opr + TM_ADD));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -1504,25 +1561,27 @@ static void codebitwise (FuncState *fs, BinOpr opr,
|
||||||
** Emit code for order comparisons. When using an immediate operand,
|
** Emit code for order comparisons. When using an immediate operand,
|
||||||
** 'isfloat' tells whether the original value was a float.
|
** 'isfloat' tells whether the original value was a float.
|
||||||
*/
|
*/
|
||||||
static void codeorder (FuncState *fs, OpCode op, expdesc *e1, expdesc *e2) {
|
static void codeorder (FuncState *fs, BinOpr opr, expdesc *e1, expdesc *e2) {
|
||||||
int r1, r2;
|
int r1, r2;
|
||||||
int im;
|
int im;
|
||||||
int isfloat = 0;
|
int isfloat = 0;
|
||||||
|
OpCode op;
|
||||||
if (isSCnumber(e2, &im, &isfloat)) {
|
if (isSCnumber(e2, &im, &isfloat)) {
|
||||||
/* use immediate operand */
|
/* use immediate operand */
|
||||||
r1 = luaK_exp2anyreg(fs, e1);
|
r1 = luaK_exp2anyreg(fs, e1);
|
||||||
r2 = im;
|
r2 = im;
|
||||||
op = cast(OpCode, (op - OP_LT) + OP_LTI);
|
op = binopr2op(opr, OPR_LT, OP_LTI);
|
||||||
}
|
}
|
||||||
else if (isSCnumber(e1, &im, &isfloat)) {
|
else if (isSCnumber(e1, &im, &isfloat)) {
|
||||||
/* transform (A < B) to (B > A) and (A <= B) to (B >= A) */
|
/* transform (A < B) to (B > A) and (A <= B) to (B >= A) */
|
||||||
r1 = luaK_exp2anyreg(fs, e2);
|
r1 = luaK_exp2anyreg(fs, e2);
|
||||||
r2 = im;
|
r2 = im;
|
||||||
op = (op == OP_LT) ? OP_GTI : OP_GEI;
|
op = binopr2op(opr, OPR_LT, OP_GTI);
|
||||||
}
|
}
|
||||||
else { /* regular case, compare two registers */
|
else { /* regular case, compare two registers */
|
||||||
r1 = luaK_exp2anyreg(fs, e1);
|
r1 = luaK_exp2anyreg(fs, e1);
|
||||||
r2 = luaK_exp2anyreg(fs, e2);
|
r2 = luaK_exp2anyreg(fs, e2);
|
||||||
|
op = binopr2op(opr, OPR_LT, OP_LT);
|
||||||
}
|
}
|
||||||
freeexps(fs, e1, e2);
|
freeexps(fs, e1, e2);
|
||||||
e1->u.info = condjump(fs, op, r1, r2, isfloat, 1);
|
e1->u.info = condjump(fs, op, r1, r2, isfloat, 1);
|
||||||
|
@ -1548,7 +1607,7 @@ static void codeeq (FuncState *fs, BinOpr opr, expdesc *e1, expdesc *e2) {
|
||||||
op = OP_EQI;
|
op = OP_EQI;
|
||||||
r2 = im; /* immediate operand */
|
r2 = im; /* immediate operand */
|
||||||
}
|
}
|
||||||
else if (luaK_exp2RK(fs, e2)) { /* 1st expression is constant? */
|
else if (luaK_exp2RK(fs, e2)) { /* 2nd expression is constant? */
|
||||||
op = OP_EQK;
|
op = OP_EQK;
|
||||||
r2 = e2->u.info; /* constant index */
|
r2 = e2->u.info; /* constant index */
|
||||||
}
|
}
|
||||||
|
@ -1565,16 +1624,16 @@ static void codeeq (FuncState *fs, BinOpr opr, expdesc *e1, expdesc *e2) {
|
||||||
/*
|
/*
|
||||||
** Apply prefix operation 'op' to expression 'e'.
|
** Apply prefix operation 'op' to expression 'e'.
|
||||||
*/
|
*/
|
||||||
void luaK_prefix (FuncState *fs, UnOpr op, expdesc *e, int line) {
|
void luaK_prefix (FuncState *fs, UnOpr opr, expdesc *e, int line) {
|
||||||
static const expdesc ef = {VKINT, {0}, NO_JUMP, NO_JUMP};
|
static const expdesc ef = {VKINT, {0}, NO_JUMP, NO_JUMP};
|
||||||
luaK_dischargevars(fs, e);
|
luaK_dischargevars(fs, e);
|
||||||
switch (op) {
|
switch (opr) {
|
||||||
case OPR_MINUS: case OPR_BNOT: /* use 'ef' as fake 2nd operand */
|
case OPR_MINUS: case OPR_BNOT: /* use 'ef' as fake 2nd operand */
|
||||||
if (constfolding(fs, op + LUA_OPUNM, e, &ef))
|
if (constfolding(fs, opr + LUA_OPUNM, e, &ef))
|
||||||
break;
|
break;
|
||||||
/* else */ /* FALLTHROUGH */
|
/* else */ /* FALLTHROUGH */
|
||||||
case OPR_LEN:
|
case OPR_LEN:
|
||||||
codeunexpval(fs, cast(OpCode, op + OP_UNM), e, line);
|
codeunexpval(fs, unopr2op(opr), e, line);
|
||||||
break;
|
break;
|
||||||
case OPR_NOT: codenot(fs, e); break;
|
case OPR_NOT: codenot(fs, e); break;
|
||||||
default: lua_assert(0);
|
default: lua_assert(0);
|
||||||
|
@ -1608,7 +1667,8 @@ void luaK_infix (FuncState *fs, BinOpr op, expdesc *v) {
|
||||||
case OPR_SHL: case OPR_SHR: {
|
case OPR_SHL: case OPR_SHR: {
|
||||||
if (!tonumeral(v, NULL))
|
if (!tonumeral(v, NULL))
|
||||||
luaK_exp2anyreg(fs, v);
|
luaK_exp2anyreg(fs, v);
|
||||||
/* else keep numeral, which may be folded with 2nd operand */
|
/* else keep numeral, which may be folded or used as an immediate
|
||||||
|
operand */
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case OPR_EQ: case OPR_NE: {
|
case OPR_EQ: case OPR_NE: {
|
||||||
|
@ -1703,30 +1763,27 @@ void luaK_posfix (FuncState *fs, BinOpr opr,
|
||||||
/* coded as (r1 >> -I) */;
|
/* coded as (r1 >> -I) */;
|
||||||
}
|
}
|
||||||
else /* regular case (two registers) */
|
else /* regular case (two registers) */
|
||||||
codebinexpval(fs, OP_SHL, e1, e2, line);
|
codebinexpval(fs, opr, e1, e2, line);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case OPR_SHR: {
|
case OPR_SHR: {
|
||||||
if (isSCint(e2))
|
if (isSCint(e2))
|
||||||
codebini(fs, OP_SHRI, e1, e2, 0, line, TM_SHR); /* r1 >> I */
|
codebini(fs, OP_SHRI, e1, e2, 0, line, TM_SHR); /* r1 >> I */
|
||||||
else /* regular case (two registers) */
|
else /* regular case (two registers) */
|
||||||
codebinexpval(fs, OP_SHR, e1, e2, line);
|
codebinexpval(fs, opr, e1, e2, line);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case OPR_EQ: case OPR_NE: {
|
case OPR_EQ: case OPR_NE: {
|
||||||
codeeq(fs, opr, e1, e2);
|
codeeq(fs, opr, e1, e2);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case OPR_LT: case OPR_LE: {
|
|
||||||
OpCode op = cast(OpCode, (opr - OPR_EQ) + OP_EQ);
|
|
||||||
codeorder(fs, op, e1, e2);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
case OPR_GT: case OPR_GE: {
|
case OPR_GT: case OPR_GE: {
|
||||||
/* '(a > b)' <=> '(b < a)'; '(a >= b)' <=> '(b <= a)' */
|
/* '(a > b)' <=> '(b < a)'; '(a >= b)' <=> '(b <= a)' */
|
||||||
OpCode op = cast(OpCode, (opr - OPR_NE) + OP_EQ);
|
|
||||||
swapexps(e1, e2);
|
swapexps(e1, e2);
|
||||||
codeorder(fs, op, e1, e2);
|
opr = cast(BinOpr, (opr - OPR_GT) + OPR_LT);
|
||||||
|
} /* FALLTHROUGH */
|
||||||
|
case OPR_LT: case OPR_LE: {
|
||||||
|
codeorder(fs, opr, e1, e2);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
default: lua_assert(0);
|
default: lua_assert(0);
|
||||||
|
|
11
third_party/lua/lcorolib.c
vendored
11
third_party/lua/lcorolib.c
vendored
|
@ -3,7 +3,7 @@
|
||||||
╚──────────────────────────────────────────────────────────────────────────────╝
|
╚──────────────────────────────────────────────────────────────────────────────╝
|
||||||
│ │
|
│ │
|
||||||
│ Lua │
|
│ Lua │
|
||||||
│ Copyright © 2004-2021 Lua.org, PUC-Rio. │
|
│ Copyright © 2004-2023 Lua.org, PUC-Rio. │
|
||||||
│ │
|
│ │
|
||||||
│ Permission is hereby granted, free of charge, to any person obtaining │
|
│ Permission is hereby granted, free of charge, to any person obtaining │
|
||||||
│ a copy of this software and associated documentation files (the │
|
│ a copy of this software and associated documentation files (the │
|
||||||
|
@ -27,6 +27,7 @@
|
||||||
╚─────────────────────────────────────────────────────────────────────────────*/
|
╚─────────────────────────────────────────────────────────────────────────────*/
|
||||||
#define lcorolib_c
|
#define lcorolib_c
|
||||||
#define LUA_LIB
|
#define LUA_LIB
|
||||||
|
|
||||||
#include "third_party/lua/lauxlib.h"
|
#include "third_party/lua/lauxlib.h"
|
||||||
#include "third_party/lua/lprefix.h"
|
#include "third_party/lua/lprefix.h"
|
||||||
#include "third_party/lua/lua.h"
|
#include "third_party/lua/lua.h"
|
||||||
|
@ -92,9 +93,9 @@ static int luaB_auxwrap (lua_State *L) {
|
||||||
if (l_unlikely(r < 0)) { /* error? */
|
if (l_unlikely(r < 0)) { /* error? */
|
||||||
int stat = lua_status(co);
|
int stat = lua_status(co);
|
||||||
if (stat != LUA_OK && stat != LUA_YIELD) { /* error in the coroutine? */
|
if (stat != LUA_OK && stat != LUA_YIELD) { /* error in the coroutine? */
|
||||||
stat = lua_resetthread(co); /* close its tbc variables */
|
stat = lua_closethread(co, L); /* close its tbc variables */
|
||||||
lua_assert(stat != LUA_OK);
|
lua_assert(stat != LUA_OK);
|
||||||
lua_xmove(co, L, 1); /* copy error message */
|
lua_xmove(co, L, 1); /* move error message to the caller */
|
||||||
}
|
}
|
||||||
if (stat != LUA_ERRMEM && /* not a memory error and ... */
|
if (stat != LUA_ERRMEM && /* not a memory error and ... */
|
||||||
lua_type(L, -1) == LUA_TSTRING) { /* ... error object is a string? */
|
lua_type(L, -1) == LUA_TSTRING) { /* ... error object is a string? */
|
||||||
|
@ -188,14 +189,14 @@ static int luaB_close (lua_State *L) {
|
||||||
int status = auxstatus(L, co);
|
int status = auxstatus(L, co);
|
||||||
switch (status) {
|
switch (status) {
|
||||||
case COS_DEAD: case COS_YIELD: {
|
case COS_DEAD: case COS_YIELD: {
|
||||||
status = lua_resetthread(co);
|
status = lua_closethread(co, L);
|
||||||
if (status == LUA_OK) {
|
if (status == LUA_OK) {
|
||||||
lua_pushboolean(L, 1);
|
lua_pushboolean(L, 1);
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
lua_pushboolean(L, 0);
|
lua_pushboolean(L, 0);
|
||||||
lua_xmove(co, L, 1); /* copy error message */
|
lua_xmove(co, L, 1); /* move error message */
|
||||||
return 2;
|
return 2;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
3
third_party/lua/lctype.h
vendored
3
third_party/lua/lctype.h
vendored
|
@ -1,7 +1,9 @@
|
||||||
#ifndef lctype_h
|
#ifndef lctype_h
|
||||||
#define lctype_h
|
#define lctype_h
|
||||||
|
|
||||||
#include "third_party/lua/lua.h"
|
#include "third_party/lua/lua.h"
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
** In ASCII, this 'ltolower' is correct for alphabetic characters and
|
** In ASCII, this 'ltolower' is correct for alphabetic characters and
|
||||||
** for '.'. That is enough for Lua needs. ('check_exp' ensures that
|
** for '.'. That is enough for Lua needs. ('check_exp' ensures that
|
||||||
|
@ -12,6 +14,7 @@
|
||||||
check_exp(('A' <= (c) && (c) <= 'Z') || (c) == ((c) | ('A' ^ 'a')), \
|
check_exp(('A' <= (c) && (c) <= 'Z') || (c) == ((c) | ('A' ^ 'a')), \
|
||||||
(c) | ('A' ^ 'a'))
|
(c) | ('A' ^ 'a'))
|
||||||
|
|
||||||
|
// [jart]
|
||||||
#define lisdigit(C) \
|
#define lisdigit(C) \
|
||||||
({ \
|
({ \
|
||||||
unsigned char c_ = (C); \
|
unsigned char c_ = (C); \
|
||||||
|
|
4
third_party/lua/ldblib.c
vendored
4
third_party/lua/ldblib.c
vendored
|
@ -3,7 +3,7 @@
|
||||||
╚──────────────────────────────────────────────────────────────────────────────╝
|
╚──────────────────────────────────────────────────────────────────────────────╝
|
||||||
│ │
|
│ │
|
||||||
│ Lua │
|
│ Lua │
|
||||||
│ Copyright © 2004-2021 Lua.org, PUC-Rio. │
|
│ Copyright © 2004-2023 Lua.org, PUC-Rio. │
|
||||||
│ │
|
│ │
|
||||||
│ Permission is hereby granted, free of charge, to any person obtaining │
|
│ Permission is hereby granted, free of charge, to any person obtaining │
|
||||||
│ a copy of this software and associated documentation files (the │
|
│ a copy of this software and associated documentation files (the │
|
||||||
|
@ -27,6 +27,7 @@
|
||||||
╚─────────────────────────────────────────────────────────────────────────────*/
|
╚─────────────────────────────────────────────────────────────────────────────*/
|
||||||
#define ldblib_c
|
#define ldblib_c
|
||||||
#define LUA_LIB
|
#define LUA_LIB
|
||||||
|
|
||||||
#include "libc/str/str.h"
|
#include "libc/str/str.h"
|
||||||
#include "third_party/lua/lauxlib.h"
|
#include "third_party/lua/lauxlib.h"
|
||||||
#include "third_party/lua/lprefix.h"
|
#include "third_party/lua/lprefix.h"
|
||||||
|
@ -495,3 +496,4 @@ LUAMOD_API int luaopen_debug (lua_State *L) {
|
||||||
luaL_newlib(L, dblib);
|
luaL_newlib(L, dblib);
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
186
third_party/lua/ldebug.c
vendored
186
third_party/lua/ldebug.c
vendored
|
@ -3,7 +3,7 @@
|
||||||
╚──────────────────────────────────────────────────────────────────────────────╝
|
╚──────────────────────────────────────────────────────────────────────────────╝
|
||||||
│ │
|
│ │
|
||||||
│ Lua │
|
│ Lua │
|
||||||
│ Copyright © 2004-2021 Lua.org, PUC-Rio. │
|
│ Copyright © 2004-2023 Lua.org, PUC-Rio. │
|
||||||
│ │
|
│ │
|
||||||
│ Permission is hereby granted, free of charge, to any person obtaining │
|
│ Permission is hereby granted, free of charge, to any person obtaining │
|
||||||
│ a copy of this software and associated documentation files (the │
|
│ a copy of this software and associated documentation files (the │
|
||||||
|
@ -27,6 +27,7 @@
|
||||||
╚─────────────────────────────────────────────────────────────────────────────*/
|
╚─────────────────────────────────────────────────────────────────────────────*/
|
||||||
#define ldebug_c
|
#define ldebug_c
|
||||||
#define LUA_CORE
|
#define LUA_CORE
|
||||||
|
|
||||||
#include "libc/str/str.h"
|
#include "libc/str/str.h"
|
||||||
#include "third_party/lua/lapi.h"
|
#include "third_party/lua/lapi.h"
|
||||||
#include "third_party/lua/lcode.h"
|
#include "third_party/lua/lcode.h"
|
||||||
|
@ -48,7 +49,7 @@ __static_yoink("lua_notice");
|
||||||
#define noLuaClosure(f) ((f) == NULL || (f)->c.tt == LUA_VCCL)
|
#define noLuaClosure(f) ((f) == NULL || (f)->c.tt == LUA_VCCL)
|
||||||
|
|
||||||
|
|
||||||
static const char *funcnamefromcode (lua_State *L, CallInfo *ci,
|
static const char *funcnamefromcall (lua_State *L, CallInfo *ci,
|
||||||
const char **name);
|
const char **name);
|
||||||
|
|
||||||
|
|
||||||
|
@ -78,7 +79,7 @@ static int getbaseline (const Proto *f, int pc, int *basepc) {
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
int i = cast_uint(pc) / MAXIWTHABS - 1; /* get an estimate */
|
int i = cast_uint(pc) / MAXIWTHABS - 1; /* get an estimate */
|
||||||
/* estimate must be a lower bond of the correct base */
|
/* estimate must be a lower bound of the correct base */
|
||||||
lua_assert(i < 0 ||
|
lua_assert(i < 0 ||
|
||||||
(i < f->sizeabslineinfo && f->abslineinfo[i].pc <= pc));
|
(i < f->sizeabslineinfo && f->abslineinfo[i].pc <= pc));
|
||||||
while (i + 1 < f->sizeabslineinfo && pc >= f->abslineinfo[i + 1].pc)
|
while (i + 1 < f->sizeabslineinfo && pc >= f->abslineinfo[i + 1].pc)
|
||||||
|
@ -196,10 +197,10 @@ static const char *upvalname (const Proto *p, int uv) {
|
||||||
|
|
||||||
|
|
||||||
static const char *findvararg (CallInfo *ci, int n, StkId *pos) {
|
static const char *findvararg (CallInfo *ci, int n, StkId *pos) {
|
||||||
if (clLvalue(s2v(ci->func))->p->is_vararg) {
|
if (clLvalue(s2v(ci->func.p))->p->is_vararg) {
|
||||||
int nextra = ci->u.l.nextraargs;
|
int nextra = ci->u.l.nextraargs;
|
||||||
if (n >= -nextra) { /* 'n' is negative */
|
if (n >= -nextra) { /* 'n' is negative */
|
||||||
*pos = ci->func - nextra - (n + 1);
|
*pos = ci->func.p - nextra - (n + 1);
|
||||||
return "(vararg)"; /* generic name for any vararg */
|
return "(vararg)"; /* generic name for any vararg */
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -208,7 +209,7 @@ static const char *findvararg (CallInfo *ci, int n, StkId *pos) {
|
||||||
|
|
||||||
|
|
||||||
const char *luaG_findlocal (lua_State *L, CallInfo *ci, int n, StkId *pos) {
|
const char *luaG_findlocal (lua_State *L, CallInfo *ci, int n, StkId *pos) {
|
||||||
StkId base = ci->func + 1;
|
StkId base = ci->func.p + 1;
|
||||||
const char *name = NULL;
|
const char *name = NULL;
|
||||||
if (isLua(ci)) {
|
if (isLua(ci)) {
|
||||||
if (n < 0) /* access to vararg values? */
|
if (n < 0) /* access to vararg values? */
|
||||||
|
@ -217,7 +218,7 @@ const char *luaG_findlocal (lua_State *L, CallInfo *ci, int n, StkId *pos) {
|
||||||
name = luaF_getlocalname(ci_func(ci)->p, n, currentpc(ci));
|
name = luaF_getlocalname(ci_func(ci)->p, n, currentpc(ci));
|
||||||
}
|
}
|
||||||
if (name == NULL) { /* no 'standard' name? */
|
if (name == NULL) { /* no 'standard' name? */
|
||||||
StkId limit = (ci == L->ci) ? L->top : ci->next->func;
|
StkId limit = (ci == L->ci) ? L->top.p : ci->next->func.p;
|
||||||
if (limit - base >= n && n > 0) { /* is 'n' inside 'ci' stack? */
|
if (limit - base >= n && n > 0) { /* is 'n' inside 'ci' stack? */
|
||||||
/* generic name for any valid slot */
|
/* generic name for any valid slot */
|
||||||
name = isLua(ci) ? "(temporary)" : "(C temporary)";
|
name = isLua(ci) ? "(temporary)" : "(C temporary)";
|
||||||
|
@ -235,16 +236,16 @@ LUA_API const char *lua_getlocal (lua_State *L, const lua_Debug *ar, int n) {
|
||||||
const char *name;
|
const char *name;
|
||||||
lua_lock(L);
|
lua_lock(L);
|
||||||
if (ar == NULL) { /* information about non-active function? */
|
if (ar == NULL) { /* information about non-active function? */
|
||||||
if (!isLfunction(s2v(L->top - 1))) /* not a Lua function? */
|
if (!isLfunction(s2v(L->top.p - 1))) /* not a Lua function? */
|
||||||
name = NULL;
|
name = NULL;
|
||||||
else /* consider live variables at function start (parameters) */
|
else /* consider live variables at function start (parameters) */
|
||||||
name = luaF_getlocalname(clLvalue(s2v(L->top - 1))->p, n, 0);
|
name = luaF_getlocalname(clLvalue(s2v(L->top.p - 1))->p, n, 0);
|
||||||
}
|
}
|
||||||
else { /* active function; get information through 'ar' */
|
else { /* active function; get information through 'ar' */
|
||||||
StkId pos = NULL; /* to avoid warnings */
|
StkId pos = NULL; /* to avoid warnings */
|
||||||
name = luaG_findlocal(L, ar->i_ci, n, &pos);
|
name = luaG_findlocal(L, ar->i_ci, n, &pos);
|
||||||
if (name) {
|
if (name) {
|
||||||
setobjs2s(L, L->top, pos);
|
setobjs2s(L, L->top.p, pos);
|
||||||
api_incr_top(L);
|
api_incr_top(L);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -259,8 +260,8 @@ LUA_API const char *lua_setlocal (lua_State *L, const lua_Debug *ar, int n) {
|
||||||
lua_lock(L);
|
lua_lock(L);
|
||||||
name = luaG_findlocal(L, ar->i_ci, n, &pos);
|
name = luaG_findlocal(L, ar->i_ci, n, &pos);
|
||||||
if (name) {
|
if (name) {
|
||||||
setobjs2s(L, pos, L->top - 1);
|
setobjs2s(L, pos, L->top.p - 1);
|
||||||
L->top--; /* pop value */
|
L->top.p--; /* pop value */
|
||||||
}
|
}
|
||||||
lua_unlock(L);
|
lua_unlock(L);
|
||||||
return name;
|
return name;
|
||||||
|
@ -303,7 +304,7 @@ static int nextline (const Proto *p, int currentline, int pc) {
|
||||||
|
|
||||||
static void collectvalidlines (lua_State *L, Closure *f) {
|
static void collectvalidlines (lua_State *L, Closure *f) {
|
||||||
if (noLuaClosure(f)) {
|
if (noLuaClosure(f)) {
|
||||||
setnilvalue(s2v(L->top));
|
setnilvalue(s2v(L->top.p));
|
||||||
api_incr_top(L);
|
api_incr_top(L);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
|
@ -312,10 +313,17 @@ static void collectvalidlines (lua_State *L, Closure *f) {
|
||||||
const Proto *p = f->l.p;
|
const Proto *p = f->l.p;
|
||||||
int currentline = p->linedefined;
|
int currentline = p->linedefined;
|
||||||
Table *t = luaH_new(L); /* new table to store active lines */
|
Table *t = luaH_new(L); /* new table to store active lines */
|
||||||
sethvalue2s(L, L->top, t); /* push it on stack */
|
sethvalue2s(L, L->top.p, t); /* push it on stack */
|
||||||
api_incr_top(L);
|
api_incr_top(L);
|
||||||
setbtvalue(&v); /* boolean 'true' to be the value of all indices */
|
setbtvalue(&v); /* boolean 'true' to be the value of all indices */
|
||||||
for (i = 0; i < p->sizelineinfo; i++) { /* for all instructions */
|
if (!p->is_vararg) /* regular function? */
|
||||||
|
i = 0; /* consider all instructions */
|
||||||
|
else { /* vararg function */
|
||||||
|
lua_assert(GET_OPCODE(p->code[0]) == OP_VARARGPREP);
|
||||||
|
currentline = nextline(p, currentline, 0);
|
||||||
|
i = 1; /* skip first instruction (OP_VARARGPREP) */
|
||||||
|
}
|
||||||
|
for (; i < p->sizelineinfo; i++) { /* for each instruction */
|
||||||
currentline = nextline(p, currentline, i); /* get its line */
|
currentline = nextline(p, currentline, i); /* get its line */
|
||||||
luaH_setint(L, t, currentline, &v); /* table[line] = true */
|
luaH_setint(L, t, currentline, &v); /* table[line] = true */
|
||||||
}
|
}
|
||||||
|
@ -324,15 +332,9 @@ static void collectvalidlines (lua_State *L, Closure *f) {
|
||||||
|
|
||||||
|
|
||||||
static const char *getfuncname (lua_State *L, CallInfo *ci, const char **name) {
|
static const char *getfuncname (lua_State *L, CallInfo *ci, const char **name) {
|
||||||
if (ci == NULL) /* no 'ci'? */
|
/* calling function is a known function? */
|
||||||
return NULL; /* no info */
|
if (ci != NULL && !(ci->callstatus & CIST_TAIL))
|
||||||
else if (ci->callstatus & CIST_FIN) { /* is this a finalizer? */
|
return funcnamefromcall(L, ci->previous, name);
|
||||||
*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 */
|
else return NULL; /* no way to find a name */
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -401,20 +403,20 @@ LUA_API int lua_getinfo (lua_State *L, const char *what, lua_Debug *ar) {
|
||||||
lua_lock(L);
|
lua_lock(L);
|
||||||
if (*what == '>') {
|
if (*what == '>') {
|
||||||
ci = NULL;
|
ci = NULL;
|
||||||
func = s2v(L->top - 1);
|
func = s2v(L->top.p - 1);
|
||||||
api_check(L, ttisfunction(func), "function expected");
|
api_check(L, ttisfunction(func), "function expected");
|
||||||
what++; /* skip the '>' */
|
what++; /* skip the '>' */
|
||||||
L->top--; /* pop function */
|
L->top.p--; /* pop function */
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
ci = ar->i_ci;
|
ci = ar->i_ci;
|
||||||
func = s2v(ci->func);
|
func = s2v(ci->func.p);
|
||||||
lua_assert(ttisfunction(func));
|
lua_assert(ttisfunction(func));
|
||||||
}
|
}
|
||||||
cl = ttisclosure(func) ? clvalue(func) : NULL;
|
cl = ttisclosure(func) ? clvalue(func) : NULL;
|
||||||
status = auxgetinfo(L, what, ar, cl, ci);
|
status = auxgetinfo(L, what, ar, cl, ci);
|
||||||
if (strchr(what, 'f')) {
|
if (strchr(what, 'f')) {
|
||||||
setobj2s(L, L->top, func);
|
setobj2s(L, L->top.p, func);
|
||||||
api_incr_top(L);
|
api_incr_top(L);
|
||||||
}
|
}
|
||||||
if (strchr(what, 'L'))
|
if (strchr(what, 'L'))
|
||||||
|
@ -604,16 +606,10 @@ static const char *getobjname (const Proto *p, int lastpc, int reg,
|
||||||
** Returns what the name is (e.g., "for iterator", "method",
|
** Returns what the name is (e.g., "for iterator", "method",
|
||||||
** "metamethod") and sets '*name' to point to the name.
|
** "metamethod") and sets '*name' to point to the name.
|
||||||
*/
|
*/
|
||||||
static const char *funcnamefromcode (lua_State *L, CallInfo *ci,
|
static const char *funcnamefromcode (lua_State *L, const Proto *p,
|
||||||
const char **name) {
|
int pc, const char **name) {
|
||||||
TMS tm = (TMS)0; /* (initial value avoids warnings) */
|
TMS tm = (TMS)0; /* (initial value avoids warnings) */
|
||||||
const Proto *p = ci_func(ci)->p; /* calling function */
|
|
||||||
int pc = currentpc(ci); /* calling instruction index */
|
|
||||||
Instruction i = p->code[pc]; /* calling instruction */
|
Instruction i = p->code[pc]; /* calling instruction */
|
||||||
if (ci->callstatus & CIST_HOOKED) { /* was it called inside a hook? */
|
|
||||||
*name = "?";
|
|
||||||
return "hook";
|
|
||||||
}
|
|
||||||
switch (GET_OPCODE(i)) {
|
switch (GET_OPCODE(i)) {
|
||||||
case OP_CALL:
|
case OP_CALL:
|
||||||
case OP_TAILCALL:
|
case OP_TAILCALL:
|
||||||
|
@ -650,23 +646,44 @@ static const char *funcnamefromcode (lua_State *L, CallInfo *ci,
|
||||||
return "metamethod";
|
return "metamethod";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
** Try to find a name for a function based on how it was called.
|
||||||
|
*/
|
||||||
|
static const char *funcnamefromcall (lua_State *L, CallInfo *ci,
|
||||||
|
const char **name) {
|
||||||
|
if (ci->callstatus & CIST_HOOKED) { /* was it called inside a hook? */
|
||||||
|
*name = "?";
|
||||||
|
return "hook";
|
||||||
|
}
|
||||||
|
else if (ci->callstatus & CIST_FIN) { /* was it called as a finalizer? */
|
||||||
|
*name = "__gc";
|
||||||
|
return "metamethod"; /* report it as such */
|
||||||
|
}
|
||||||
|
else if (isLua(ci))
|
||||||
|
return funcnamefromcode(L, ci_func(ci)->p, currentpc(ci), name);
|
||||||
|
else
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
/* }====================================================== */
|
/* }====================================================== */
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
** Check whether pointer 'o' points to some value in the stack
|
** Check whether pointer 'o' points to some value in the stack frame of
|
||||||
** frame of the current function. Because 'o' may not point to a
|
** the current function and, if so, returns its index. Because 'o' may
|
||||||
** value in this stack, we cannot compare it with the region
|
** not point to a value in this stack, we cannot compare it with the
|
||||||
** boundaries (undefined behaviour in ISO C).
|
** region boundaries (undefined behavior in ISO C).
|
||||||
*/
|
*/
|
||||||
static int isinstack (CallInfo *ci, const TValue *o) {
|
static int instack (CallInfo *ci, const TValue *o) {
|
||||||
StkId pos;
|
int pos;
|
||||||
for (pos = ci->func + 1; pos < ci->top; pos++) {
|
StkId base = ci->func.p + 1;
|
||||||
if (o == s2v(pos))
|
for (pos = 0; base + pos < ci->top.p; pos++) {
|
||||||
return 1;
|
if (o == s2v(base + pos))
|
||||||
|
return pos;
|
||||||
}
|
}
|
||||||
return 0; /* not found */
|
return -1; /* not found */
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -680,7 +697,7 @@ static const char *getupvalname (CallInfo *ci, const TValue *o,
|
||||||
LClosure *c = ci_func(ci);
|
LClosure *c = ci_func(ci);
|
||||||
int i;
|
int i;
|
||||||
for (i = 0; i < c->nupvalues; i++) {
|
for (i = 0; i < c->nupvalues; i++) {
|
||||||
if (c->upvals[i]->v == o) {
|
if (c->upvals[i]->v.p == o) {
|
||||||
*name = upvalname(c->p, i);
|
*name = upvalname(c->p, i);
|
||||||
return "upvalue";
|
return "upvalue";
|
||||||
}
|
}
|
||||||
|
@ -689,36 +706,64 @@ static const char *getupvalname (CallInfo *ci, const TValue *o,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static const char *formatvarinfo (lua_State *L, const char *kind,
|
||||||
|
const char *name) {
|
||||||
|
if (kind == NULL)
|
||||||
|
return ""; /* no information */
|
||||||
|
else
|
||||||
|
return luaO_pushfstring(L, " (%s '%s')", kind, name);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
** Build a string with a "description" for the value 'o', such as
|
||||||
|
** "variable 'x'" or "upvalue 'y'".
|
||||||
|
*/
|
||||||
static const char *varinfo (lua_State *L, const TValue *o) {
|
static const char *varinfo (lua_State *L, const TValue *o) {
|
||||||
const char *name = NULL; /* to avoid warnings */
|
|
||||||
CallInfo *ci = L->ci;
|
CallInfo *ci = L->ci;
|
||||||
|
const char *name = NULL; /* to avoid warnings */
|
||||||
const char *kind = NULL;
|
const char *kind = NULL;
|
||||||
if (isLua(ci)) {
|
if (isLua(ci)) {
|
||||||
kind = getupvalname(ci, o, &name); /* check whether 'o' is an upvalue */
|
kind = getupvalname(ci, o, &name); /* check whether 'o' is an upvalue */
|
||||||
if (!kind && isinstack(ci, o)) /* no? try a register */
|
if (!kind) { /* not an upvalue? */
|
||||||
kind = getobjname(ci_func(ci)->p, currentpc(ci),
|
int reg = instack(ci, o); /* try a register */
|
||||||
cast_int(cast(StkId, o) - (ci->func + 1)), &name);
|
if (reg >= 0) /* is 'o' a register? */
|
||||||
|
kind = getobjname(ci_func(ci)->p, currentpc(ci), reg, &name);
|
||||||
}
|
}
|
||||||
return (kind) ? luaO_pushfstring(L, " (%s '%s')", kind, name) : "";
|
}
|
||||||
|
return formatvarinfo(L, kind, name);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
l_noret luaG_typeerror (lua_State *L, const TValue *o, const char *op) {
|
/*
|
||||||
|
** Raise a type error
|
||||||
|
*/
|
||||||
|
static l_noret typeerror (lua_State *L, const TValue *o, const char *op,
|
||||||
|
const char *extra) {
|
||||||
const char *t = luaT_objtypename(L, o);
|
const char *t = luaT_objtypename(L, o);
|
||||||
luaG_runerror(L, "attempt to %s a %s value%s", op, t, varinfo(L, o));
|
luaG_runerror(L, "attempt to %s a %s value%s", op, t, extra);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
** Raise a type error with "standard" information about the faulty
|
||||||
|
** object 'o' (using 'varinfo').
|
||||||
|
*/
|
||||||
|
l_noret luaG_typeerror (lua_State *L, const TValue *o, const char *op) {
|
||||||
|
typeerror(L, o, op, varinfo(L, o));
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
** Raise an error for calling a non-callable object. Try to find a name
|
||||||
|
** for the object based on how it was called ('funcnamefromcall'); if it
|
||||||
|
** cannot get a name there, try 'varinfo'.
|
||||||
|
*/
|
||||||
l_noret luaG_callerror (lua_State *L, const TValue *o) {
|
l_noret luaG_callerror (lua_State *L, const TValue *o) {
|
||||||
CallInfo *ci = L->ci;
|
CallInfo *ci = L->ci;
|
||||||
const char *name = NULL; /* to avoid warnings */
|
const char *name = NULL; /* to avoid warnings */
|
||||||
const char *what = (isLua(ci)) ? funcnamefromcode(L, ci, &name) : NULL;
|
const char *kind = funcnamefromcall(L, ci, &name);
|
||||||
if (what != NULL) {
|
const char *extra = kind ? formatvarinfo(L, kind, name) : varinfo(L, o);
|
||||||
const char *t = luaT_objtypename(L, o);
|
typeerror(L, o, "call", extra);
|
||||||
luaG_runerror(L, "%s '%s' is not callable (a %s value)", what, name, t);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
luaG_typeerror(L, o, "call");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -780,10 +825,10 @@ l_noret luaG_errormsg (lua_State *L) {
|
||||||
if (L->errfunc != 0) { /* is there an error handling function? */
|
if (L->errfunc != 0) { /* is there an error handling function? */
|
||||||
StkId errfunc = restorestack(L, L->errfunc);
|
StkId errfunc = restorestack(L, L->errfunc);
|
||||||
lua_assert(ttisfunction(s2v(errfunc)));
|
lua_assert(ttisfunction(s2v(errfunc)));
|
||||||
setobjs2s(L, L->top, L->top - 1); /* move argument */
|
setobjs2s(L, L->top.p, L->top.p - 1); /* move argument */
|
||||||
setobjs2s(L, L->top - 1, errfunc); /* push function */
|
setobjs2s(L, L->top.p - 1, errfunc); /* push function */
|
||||||
L->top++; /* assume EXTRA_STACK */
|
L->top.p++; /* assume EXTRA_STACK */
|
||||||
luaD_callnoyield(L, L->top - 2, 1); /* call it */
|
luaD_callnoyield(L, L->top.p - 2, 1); /* call it */
|
||||||
}
|
}
|
||||||
luaD_throw(L, LUA_ERRRUN);
|
luaD_throw(L, LUA_ERRRUN);
|
||||||
}
|
}
|
||||||
|
@ -797,8 +842,11 @@ l_noret luaG_runerror (lua_State *L, const char *fmt, ...) {
|
||||||
va_start(argp, fmt);
|
va_start(argp, fmt);
|
||||||
msg = luaO_pushvfstring(L, fmt, argp); /* format message */
|
msg = luaO_pushvfstring(L, fmt, argp); /* format message */
|
||||||
va_end(argp);
|
va_end(argp);
|
||||||
if (isLua(ci)) /* if Lua function, add source:line information */
|
if (isLua(ci)) { /* if Lua function, add source:line information */
|
||||||
luaG_addinfo(L, msg, ci_func(ci)->p->source, getcurrentline(ci));
|
luaG_addinfo(L, msg, ci_func(ci)->p->source, getcurrentline(ci));
|
||||||
|
setobjs2s(L, L->top.p - 2, L->top.p - 1); /* remove 'msg' */
|
||||||
|
L->top.p--;
|
||||||
|
}
|
||||||
luaG_errormsg(L);
|
luaG_errormsg(L);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -815,7 +863,7 @@ static int changedline (const Proto *p, int oldpc, int newpc) {
|
||||||
if (p->lineinfo == NULL) /* no debug information? */
|
if (p->lineinfo == NULL) /* no debug information? */
|
||||||
return 0;
|
return 0;
|
||||||
if (newpc - oldpc < MAXIWTHABS / 2) { /* not too far apart? */
|
if (newpc - oldpc < MAXIWTHABS / 2) { /* not too far apart? */
|
||||||
int delta = 0; /* line diference */
|
int delta = 0; /* line difference */
|
||||||
int pc = oldpc;
|
int pc = oldpc;
|
||||||
for (;;) {
|
for (;;) {
|
||||||
int lineinfo = p->lineinfo[++pc];
|
int lineinfo = p->lineinfo[++pc];
|
||||||
|
@ -842,7 +890,7 @@ static int changedline (const Proto *p, int oldpc, int newpc) {
|
||||||
** invalid; if so, use zero as a valid value. (A wrong but valid 'oldpc'
|
** invalid; if so, use zero as a valid value. (A wrong but valid 'oldpc'
|
||||||
** at most causes an extra call to a line hook.)
|
** at most causes an extra call to a line hook.)
|
||||||
** This function is not "Protected" when called, so it should correct
|
** This function is not "Protected" when called, so it should correct
|
||||||
** 'L->top' before calling anything that can run the GC.
|
** 'L->top.p' before calling anything that can run the GC.
|
||||||
*/
|
*/
|
||||||
int luaG_traceexec (lua_State *L, const Instruction *pc) {
|
int luaG_traceexec (lua_State *L, const Instruction *pc) {
|
||||||
CallInfo *ci = L->ci;
|
CallInfo *ci = L->ci;
|
||||||
|
@ -865,7 +913,7 @@ int luaG_traceexec (lua_State *L, const Instruction *pc) {
|
||||||
return 1; /* do not call hook again (VM yielded, so it did not move) */
|
return 1; /* do not call hook again (VM yielded, so it did not move) */
|
||||||
}
|
}
|
||||||
if (!isIT(*(ci->u.l.savedpc - 1))) /* top not being used? */
|
if (!isIT(*(ci->u.l.savedpc - 1))) /* top not being used? */
|
||||||
L->top = ci->top; /* correct top */
|
L->top.p = ci->top.p; /* correct top */
|
||||||
if (counthook)
|
if (counthook)
|
||||||
luaD_hook(L, LUA_HOOKCOUNT, -1, 0, 0); /* call count hook */
|
luaD_hook(L, LUA_HOOKCOUNT, -1, 0, 0); /* call count hook */
|
||||||
if (mask & LUA_MASKLINE) {
|
if (mask & LUA_MASKLINE) {
|
||||||
|
|
4
third_party/lua/ldebug.h
vendored
4
third_party/lua/ldebug.h
vendored
|
@ -1,15 +1,15 @@
|
||||||
#ifndef ldebug_h
|
#ifndef ldebug_h
|
||||||
#define ldebug_h
|
#define ldebug_h
|
||||||
|
|
||||||
#include "third_party/lua/lstate.h"
|
|
||||||
|
|
||||||
|
#include "third_party/lua/lstate.h"
|
||||||
|
|
||||||
|
|
||||||
#define pcRel(pc, p) (cast_int((pc) - (p)->code) - 1)
|
#define pcRel(pc, p) (cast_int((pc) - (p)->code) - 1)
|
||||||
|
|
||||||
|
|
||||||
/* Active Lua function (given call info) */
|
/* Active Lua function (given call info) */
|
||||||
#define ci_func(ci) (clLvalue(s2v((ci)->func)))
|
#define ci_func(ci) (clLvalue(s2v((ci)->func.p)))
|
||||||
|
|
||||||
|
|
||||||
#define resethookcount(L) (L->hookcount = L->basehookcount)
|
#define resethookcount(L) (L->hookcount = L->basehookcount)
|
||||||
|
|
333
third_party/lua/ldo.c
vendored
333
third_party/lua/ldo.c
vendored
|
@ -3,7 +3,7 @@
|
||||||
╚──────────────────────────────────────────────────────────────────────────────╝
|
╚──────────────────────────────────────────────────────────────────────────────╝
|
||||||
│ │
|
│ │
|
||||||
│ Lua │
|
│ Lua │
|
||||||
│ Copyright © 2004-2021 Lua.org, PUC-Rio. │
|
│ Copyright © 2004-2023 Lua.org, PUC-Rio. │
|
||||||
│ │
|
│ │
|
||||||
│ Permission is hereby granted, free of charge, to any person obtaining │
|
│ Permission is hereby granted, free of charge, to any person obtaining │
|
||||||
│ a copy of this software and associated documentation files (the │
|
│ a copy of this software and associated documentation files (the │
|
||||||
|
@ -27,7 +27,7 @@
|
||||||
╚─────────────────────────────────────────────────────────────────────────────*/
|
╚─────────────────────────────────────────────────────────────────────────────*/
|
||||||
#define ldo_c
|
#define ldo_c
|
||||||
#define LUA_CORE
|
#define LUA_CORE
|
||||||
#include "third_party/lua/ldo.h"
|
|
||||||
#include "libc/intrin/weaken.h"
|
#include "libc/intrin/weaken.h"
|
||||||
#include "libc/log/log.h"
|
#include "libc/log/log.h"
|
||||||
#include "libc/mem/gc.h"
|
#include "libc/mem/gc.h"
|
||||||
|
@ -82,14 +82,14 @@ __static_yoink("lua_notice");
|
||||||
#elif defined(LUA_USE_POSIX) /* }{ */
|
#elif defined(LUA_USE_POSIX) /* }{ */
|
||||||
|
|
||||||
/* in POSIX, try _longjmp/_setjmp (more efficient) */
|
/* in POSIX, try _longjmp/_setjmp (more efficient) */
|
||||||
#define LUAI_THROW(L,c) gclongjmp((c)->b, 1)
|
#define LUAI_THROW(L,c) gclongjmp((c)->b, 1) // [jart]
|
||||||
#define LUAI_TRY(L,c,a) if (_setjmp((c)->b) == 0) { a }
|
#define LUAI_TRY(L,c,a) if (_setjmp((c)->b) == 0) { a }
|
||||||
#define luai_jmpbuf jmp_buf
|
#define luai_jmpbuf jmp_buf
|
||||||
|
|
||||||
#else /* }{ */
|
#else /* }{ */
|
||||||
|
|
||||||
/* ISO C handling with long jumps */
|
/* ISO C handling with long jumps */
|
||||||
#define LUAI_THROW(L,c) gclongjmp((c)->b, 1)
|
#define LUAI_THROW(L,c) gclongjmp((c)->b, 1) // [jart]
|
||||||
#define LUAI_TRY(L,c,a) if (setjmp((c)->b) == 0) { a }
|
#define LUAI_TRY(L,c,a) if (setjmp((c)->b) == 0) { a }
|
||||||
#define luai_jmpbuf jmp_buf
|
#define luai_jmpbuf jmp_buf
|
||||||
|
|
||||||
|
@ -123,11 +123,11 @@ void luaD_seterrorobj (lua_State *L, int errcode, StkId oldtop) {
|
||||||
}
|
}
|
||||||
default: {
|
default: {
|
||||||
lua_assert(errorstatus(errcode)); /* real error */
|
lua_assert(errorstatus(errcode)); /* real error */
|
||||||
setobjs2s(L, oldtop, L->top - 1); /* error message on current top */
|
setobjs2s(L, oldtop, L->top.p - 1); /* error message on current top */
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
L->top = oldtop + 1;
|
L->top.p = oldtop + 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -140,7 +140,7 @@ l_noret luaD_throw (lua_State *L, int errcode) {
|
||||||
global_State *g = G(L);
|
global_State *g = G(L);
|
||||||
errcode = luaE_resetthread(L, errcode); /* close all upvalues */
|
errcode = luaE_resetthread(L, errcode); /* close all upvalues */
|
||||||
if (g->mainthread->errorJmp) { /* main thread has a handler? */
|
if (g->mainthread->errorJmp) { /* main thread has a handler? */
|
||||||
setobjs2s(L, g->mainthread->top++, L->top - 1); /* copy error obj. */
|
setobjs2s(L, g->mainthread->top.p++, L->top.p - 1); /* copy error obj. */
|
||||||
luaD_throw(g->mainthread, errcode); /* re-throw in main thread */
|
luaD_throw(g->mainthread, errcode); /* re-throw in main thread */
|
||||||
}
|
}
|
||||||
else { /* no handler at all; abort */
|
else { /* no handler at all; abort */
|
||||||
|
@ -148,7 +148,7 @@ l_noret luaD_throw (lua_State *L, int errcode) {
|
||||||
lua_unlock(L);
|
lua_unlock(L);
|
||||||
g->panic(L); /* call panic function (last chance to jump out) */
|
g->panic(L); /* call panic function (last chance to jump out) */
|
||||||
}
|
}
|
||||||
if (_weaken(__die)) _weaken(__die)();
|
if (_weaken(__die)) _weaken(__die)(); // [jart]
|
||||||
_Exit(41);
|
_Exit(41);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -177,16 +177,38 @@ int luaD_rawrunprotected (lua_State *L, Pfunc f, void *ud) {
|
||||||
** Stack reallocation
|
** Stack reallocation
|
||||||
** ===================================================================
|
** ===================================================================
|
||||||
*/
|
*/
|
||||||
static void correctstack (lua_State *L, StkId oldstack, StkId newstack) {
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
** Change all pointers to the stack into offsets.
|
||||||
|
*/
|
||||||
|
static void relstack (lua_State *L) {
|
||||||
CallInfo *ci;
|
CallInfo *ci;
|
||||||
UpVal *up;
|
UpVal *up;
|
||||||
L->top = (L->top - oldstack) + newstack;
|
L->top.offset = savestack(L, L->top.p);
|
||||||
L->tbclist = (L->tbclist - oldstack) + newstack;
|
L->tbclist.offset = savestack(L, L->tbclist.p);
|
||||||
for (up = L->openupval; up != NULL; up = up->u.open.next)
|
for (up = L->openupval; up != NULL; up = up->u.open.next)
|
||||||
up->v = s2v((uplevel(up) - oldstack) + newstack);
|
up->v.offset = savestack(L, uplevel(up));
|
||||||
for (ci = L->ci; ci != NULL; ci = ci->previous) {
|
for (ci = L->ci; ci != NULL; ci = ci->previous) {
|
||||||
ci->top = (ci->top - oldstack) + newstack;
|
ci->top.offset = savestack(L, ci->top.p);
|
||||||
ci->func = (ci->func - oldstack) + newstack;
|
ci->func.offset = savestack(L, ci->func.p);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
** Change back all offsets into pointers.
|
||||||
|
*/
|
||||||
|
static void correctstack (lua_State *L) {
|
||||||
|
CallInfo *ci;
|
||||||
|
UpVal *up;
|
||||||
|
L->top.p = restorestack(L, L->top.offset);
|
||||||
|
L->tbclist.p = restorestack(L, L->tbclist.offset);
|
||||||
|
for (up = L->openupval; up != NULL; up = up->u.open.next)
|
||||||
|
up->v.p = s2v(restorestack(L, up->v.offset));
|
||||||
|
for (ci = L->ci; ci != NULL; ci = ci->previous) {
|
||||||
|
ci->top.p = restorestack(L, ci->top.offset);
|
||||||
|
ci->func.p = restorestack(L, ci->func.offset);
|
||||||
if (isLua(ci))
|
if (isLua(ci))
|
||||||
ci->u.l.trap = 1; /* signal to update 'trap' in 'luaV_execute' */
|
ci->u.l.trap = 1; /* signal to update 'trap' in 'luaV_execute' */
|
||||||
}
|
}
|
||||||
|
@ -196,44 +218,45 @@ static void correctstack (lua_State *L, StkId oldstack, StkId newstack) {
|
||||||
/* some space for error handling */
|
/* some space for error handling */
|
||||||
#define ERRORSTACKSIZE (LUAI_MAXSTACK + 200)
|
#define ERRORSTACKSIZE (LUAI_MAXSTACK + 200)
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
** Reallocate the stack to a new size, correcting all pointers into
|
** Reallocate the stack to a new size, correcting all pointers into it.
|
||||||
** it. (There are pointers to a stack from its upvalues, from its list
|
** In ISO C, any pointer use after the pointer has been deallocated is
|
||||||
** of call infos, plus a few individual pointers.) The reallocation is
|
** undefined behavior. So, before the reallocation, all pointers are
|
||||||
** done in two steps (allocation + free) because the correction must be
|
** changed to offsets, and after the reallocation they are changed back
|
||||||
** done while both addresses (the old stack and the new one) are valid.
|
** to pointers. As during the reallocation the pointers are invalid, the
|
||||||
** (In ISO C, any pointer use after the pointer has been deallocated is
|
** reallocation cannot run emergency collections.
|
||||||
** undefined behavior.)
|
**
|
||||||
** In case of allocation error, raise an error or return false according
|
** In case of allocation error, raise an error or return false according
|
||||||
** to 'raiseerror'.
|
** to 'raiseerror'.
|
||||||
*/
|
*/
|
||||||
int luaD_reallocstack (lua_State *L, int newsize, int raiseerror) {
|
int luaD_reallocstack (lua_State *L, int newsize, int raiseerror) {
|
||||||
int oldsize = stacksize(L);
|
int oldsize = stacksize(L);
|
||||||
int i;
|
int i;
|
||||||
StkId newstack = luaM_reallocvector(L, NULL, 0,
|
StkId newstack;
|
||||||
newsize + EXTRA_STACK, StackValue);
|
int oldgcstop = G(L)->gcstopem;
|
||||||
lua_assert(newsize <= LUAI_MAXSTACK || newsize == ERRORSTACKSIZE);
|
lua_assert(newsize <= LUAI_MAXSTACK || newsize == ERRORSTACKSIZE);
|
||||||
|
relstack(L); /* change pointers to offsets */
|
||||||
|
G(L)->gcstopem = 1; /* stop emergency collection */
|
||||||
|
newstack = luaM_reallocvector(L, L->stack.p, oldsize + EXTRA_STACK,
|
||||||
|
newsize + EXTRA_STACK, StackValue);
|
||||||
|
G(L)->gcstopem = oldgcstop; /* restore emergency collection */
|
||||||
if (l_unlikely(newstack == NULL)) { /* reallocation failed? */
|
if (l_unlikely(newstack == NULL)) { /* reallocation failed? */
|
||||||
|
correctstack(L); /* change offsets back to pointers */
|
||||||
if (raiseerror)
|
if (raiseerror)
|
||||||
luaM_error(L);
|
luaM_error(L);
|
||||||
else return 0; /* do not raise an error */
|
else return 0; /* do not raise an error */
|
||||||
}
|
}
|
||||||
/* number of elements to be copied to the new stack */
|
L->stack.p = newstack;
|
||||||
i = ((oldsize <= newsize) ? oldsize : newsize) + EXTRA_STACK;
|
correctstack(L); /* change offsets back to pointers */
|
||||||
memcpy(newstack, L->stack, i * sizeof(StackValue));
|
L->stack_last.p = L->stack.p + newsize;
|
||||||
for (; i < newsize + EXTRA_STACK; i++)
|
for (i = oldsize + EXTRA_STACK; i < newsize + EXTRA_STACK; i++)
|
||||||
setnilvalue(s2v(newstack + i)); /* erase new segment */
|
setnilvalue(s2v(newstack + i)); /* erase new segment */
|
||||||
correctstack(L, L->stack, newstack);
|
|
||||||
luaM_freearray(L, L->stack, oldsize + EXTRA_STACK);
|
|
||||||
L->stack = newstack;
|
|
||||||
L->stack_last = L->stack + newsize;
|
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
** Try to grow the stack by at least 'n' elements. when 'raiseerror'
|
** Try to grow the stack by at least 'n' elements. When 'raiseerror'
|
||||||
** is true, raises any error; otherwise, return 0 in case of errors.
|
** is true, raises any error; otherwise, return 0 in case of errors.
|
||||||
*/
|
*/
|
||||||
int luaD_growstack (lua_State *L, int n, int raiseerror) {
|
int luaD_growstack (lua_State *L, int n, int raiseerror) {
|
||||||
|
@ -247,35 +270,38 @@ int luaD_growstack (lua_State *L, int n, int raiseerror) {
|
||||||
luaD_throw(L, LUA_ERRERR); /* error inside message handler */
|
luaD_throw(L, LUA_ERRERR); /* error inside message handler */
|
||||||
return 0; /* if not 'raiseerror', just signal it */
|
return 0; /* if not 'raiseerror', just signal it */
|
||||||
}
|
}
|
||||||
else {
|
else if (n < LUAI_MAXSTACK) { /* avoids arithmetic overflows */
|
||||||
int newsize = 2 * size; /* tentative new size */
|
int newsize = 2 * size; /* tentative new size */
|
||||||
int needed = cast_int(L->top - L->stack) + n;
|
int needed = cast_int(L->top.p - L->stack.p) + n;
|
||||||
if (newsize > LUAI_MAXSTACK) /* cannot cross the limit */
|
if (newsize > LUAI_MAXSTACK) /* cannot cross the limit */
|
||||||
newsize = LUAI_MAXSTACK;
|
newsize = LUAI_MAXSTACK;
|
||||||
if (newsize < needed) /* but must respect what was asked for */
|
if (newsize < needed) /* but must respect what was asked for */
|
||||||
newsize = needed;
|
newsize = needed;
|
||||||
if (l_likely(newsize <= LUAI_MAXSTACK))
|
if (l_likely(newsize <= LUAI_MAXSTACK))
|
||||||
return luaD_reallocstack(L, newsize, raiseerror);
|
return luaD_reallocstack(L, newsize, raiseerror);
|
||||||
else { /* stack overflow */
|
}
|
||||||
|
/* else stack overflow */
|
||||||
/* add extra size to be able to handle the error message */
|
/* add extra size to be able to handle the error message */
|
||||||
luaD_reallocstack(L, ERRORSTACKSIZE, raiseerror);
|
luaD_reallocstack(L, ERRORSTACKSIZE, raiseerror);
|
||||||
if (raiseerror)
|
if (raiseerror)
|
||||||
luaG_runerror(L, "stack overflow");
|
luaG_runerror(L, "stack overflow");
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
** Compute how much of the stack is being used, by computing the
|
||||||
|
** maximum top of all call frames in the stack and the current top.
|
||||||
|
*/
|
||||||
static int stackinuse (lua_State *L) {
|
static int stackinuse (lua_State *L) {
|
||||||
CallInfo *ci;
|
CallInfo *ci;
|
||||||
int res;
|
int res;
|
||||||
StkId lim = L->top;
|
StkId lim = L->top.p;
|
||||||
for (ci = L->ci; ci != NULL; ci = ci->previous) {
|
for (ci = L->ci; ci != NULL; ci = ci->previous) {
|
||||||
if (lim < ci->top) lim = ci->top;
|
if (lim < ci->top.p) lim = ci->top.p;
|
||||||
}
|
}
|
||||||
lua_assert(lim <= L->stack_last);
|
lua_assert(lim <= L->stack_last.p + EXTRA_STACK);
|
||||||
res = cast_int(lim - L->stack) + 1; /* part of stack in use */
|
res = cast_int(lim - L->stack.p) + 1; /* part of stack in use */
|
||||||
if (res < LUA_MINSTACK)
|
if (res < LUA_MINSTACK)
|
||||||
res = LUA_MINSTACK; /* ensure a minimum size */
|
res = LUA_MINSTACK; /* ensure a minimum size */
|
||||||
return res;
|
return res;
|
||||||
|
@ -293,17 +319,13 @@ static int stackinuse (lua_State *L) {
|
||||||
*/
|
*/
|
||||||
void luaD_shrinkstack (lua_State *L) {
|
void luaD_shrinkstack (lua_State *L) {
|
||||||
int inuse = stackinuse(L);
|
int inuse = stackinuse(L);
|
||||||
int nsize = inuse * 2; /* proposed new size */
|
int max = (inuse > LUAI_MAXSTACK / 3) ? LUAI_MAXSTACK : inuse * 3;
|
||||||
int max = inuse * 3; /* maximum "reasonable" size */
|
|
||||||
if (max > LUAI_MAXSTACK) {
|
|
||||||
max = LUAI_MAXSTACK; /* respect stack limit */
|
|
||||||
if (nsize > LUAI_MAXSTACK)
|
|
||||||
nsize = LUAI_MAXSTACK;
|
|
||||||
}
|
|
||||||
/* if thread is currently not handling a stack overflow and its
|
/* if thread is currently not handling a stack overflow and its
|
||||||
size is larger than maximum "reasonable" size, shrink it */
|
size is larger than maximum "reasonable" size, shrink it */
|
||||||
if (inuse <= LUAI_MAXSTACK && stacksize(L) > max)
|
if (inuse <= LUAI_MAXSTACK && stacksize(L) > max) {
|
||||||
|
int nsize = (inuse > LUAI_MAXSTACK / 2) ? LUAI_MAXSTACK : inuse * 2;
|
||||||
luaD_reallocstack(L, nsize, 0); /* ok if that fails */
|
luaD_reallocstack(L, nsize, 0); /* ok if that fails */
|
||||||
|
}
|
||||||
else /* don't change stack */
|
else /* don't change stack */
|
||||||
condmovestack(L,{},{}); /* (change only for debugging) */
|
condmovestack(L,{},{}); /* (change only for debugging) */
|
||||||
luaE_shrinkCI(L); /* shrink CI list */
|
luaE_shrinkCI(L); /* shrink CI list */
|
||||||
|
@ -312,7 +334,7 @@ void luaD_shrinkstack (lua_State *L) {
|
||||||
|
|
||||||
void luaD_inctop (lua_State *L) {
|
void luaD_inctop (lua_State *L) {
|
||||||
luaD_checkstack(L, 1);
|
luaD_checkstack(L, 1);
|
||||||
L->top++;
|
L->top.p++;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* }================================================================== */
|
/* }================================================================== */
|
||||||
|
@ -329,8 +351,8 @@ void luaD_hook (lua_State *L, int event, int line,
|
||||||
if (hook && L->allowhook) { /* make sure there is a hook */
|
if (hook && L->allowhook) { /* make sure there is a hook */
|
||||||
int mask = CIST_HOOKED;
|
int mask = CIST_HOOKED;
|
||||||
CallInfo *ci = L->ci;
|
CallInfo *ci = L->ci;
|
||||||
ptrdiff_t top = savestack(L, L->top); /* preserve original 'top' */
|
ptrdiff_t top = savestack(L, L->top.p); /* preserve original 'top' */
|
||||||
ptrdiff_t ci_top = savestack(L, ci->top); /* idem for 'ci->top' */
|
ptrdiff_t ci_top = savestack(L, ci->top.p); /* idem for 'ci->top' */
|
||||||
lua_Debug ar;
|
lua_Debug ar;
|
||||||
ar.event = event;
|
ar.event = event;
|
||||||
ar.currentline = line;
|
ar.currentline = line;
|
||||||
|
@ -340,11 +362,11 @@ void luaD_hook (lua_State *L, int event, int line,
|
||||||
ci->u2.transferinfo.ftransfer = ftransfer;
|
ci->u2.transferinfo.ftransfer = ftransfer;
|
||||||
ci->u2.transferinfo.ntransfer = ntransfer;
|
ci->u2.transferinfo.ntransfer = ntransfer;
|
||||||
}
|
}
|
||||||
if (isLua(ci) && L->top < ci->top)
|
if (isLua(ci) && L->top.p < ci->top.p)
|
||||||
L->top = ci->top; /* protect entire activation register */
|
L->top.p = ci->top.p; /* protect entire activation register */
|
||||||
luaD_checkstack(L, LUA_MINSTACK); /* ensure minimum stack size */
|
luaD_checkstack(L, LUA_MINSTACK); /* ensure minimum stack size */
|
||||||
if (ci->top < L->top + LUA_MINSTACK)
|
if (ci->top.p < L->top.p + LUA_MINSTACK)
|
||||||
ci->top = L->top + LUA_MINSTACK;
|
ci->top.p = L->top.p + LUA_MINSTACK;
|
||||||
L->allowhook = 0; /* cannot call hooks inside a hook */
|
L->allowhook = 0; /* cannot call hooks inside a hook */
|
||||||
ci->callstatus |= mask;
|
ci->callstatus |= mask;
|
||||||
lua_unlock(L);
|
lua_unlock(L);
|
||||||
|
@ -352,8 +374,8 @@ void luaD_hook (lua_State *L, int event, int line,
|
||||||
lua_lock(L);
|
lua_lock(L);
|
||||||
lua_assert(!L->allowhook);
|
lua_assert(!L->allowhook);
|
||||||
L->allowhook = 1;
|
L->allowhook = 1;
|
||||||
ci->top = restorestack(L, ci_top);
|
ci->top.p = restorestack(L, ci_top);
|
||||||
L->top = restorestack(L, top);
|
L->top.p = restorestack(L, top);
|
||||||
ci->callstatus &= ~mask;
|
ci->callstatus &= ~mask;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -384,7 +406,7 @@ void luaD_hookcall (lua_State *L, CallInfo *ci) {
|
||||||
*/
|
*/
|
||||||
static void rethook (lua_State *L, CallInfo *ci, int nres) {
|
static void rethook (lua_State *L, CallInfo *ci, int nres) {
|
||||||
if (L->hookmask & LUA_MASKRET) { /* is return hook on? */
|
if (L->hookmask & LUA_MASKRET) { /* is return hook on? */
|
||||||
StkId firstres = L->top - nres; /* index of first result */
|
StkId firstres = L->top.p - nres; /* index of first result */
|
||||||
int delta = 0; /* correction for vararg functions */
|
int delta = 0; /* correction for vararg functions */
|
||||||
int ftransfer;
|
int ftransfer;
|
||||||
if (isLua(ci)) {
|
if (isLua(ci)) {
|
||||||
|
@ -392,10 +414,10 @@ static void rethook (lua_State *L, CallInfo *ci, int nres) {
|
||||||
if (p->is_vararg)
|
if (p->is_vararg)
|
||||||
delta = ci->u.l.nextraargs + p->numparams + 1;
|
delta = ci->u.l.nextraargs + p->numparams + 1;
|
||||||
}
|
}
|
||||||
ci->func += delta; /* if vararg, back to virtual 'func' */
|
ci->func.p += delta; /* if vararg, back to virtual 'func' */
|
||||||
ftransfer = cast(unsigned short, firstres - ci->func);
|
ftransfer = cast(unsigned short, firstres - ci->func.p);
|
||||||
luaD_hook(L, LUA_HOOKRET, -1, ftransfer, nres); /* call it */
|
luaD_hook(L, LUA_HOOKRET, -1, ftransfer, nres); /* call it */
|
||||||
ci->func -= delta;
|
ci->func.p -= delta;
|
||||||
}
|
}
|
||||||
if (isLua(ci = ci->previous))
|
if (isLua(ci = ci->previous))
|
||||||
L->oldpc = pcRel(ci->u.l.savedpc, ci_func(ci)->p); /* set 'oldpc' */
|
L->oldpc = pcRel(ci->u.l.savedpc, ci_func(ci)->p); /* set 'oldpc' */
|
||||||
|
@ -407,15 +429,18 @@ static void rethook (lua_State *L, CallInfo *ci, int nres) {
|
||||||
** stack, below original 'func', so that 'luaD_precall' can call it. Raise
|
** stack, below original 'func', so that 'luaD_precall' can call it. Raise
|
||||||
** an error if there is no '__call' metafield.
|
** an error if there is no '__call' metafield.
|
||||||
*/
|
*/
|
||||||
void luaD_tryfuncTM (lua_State *L, StkId func) {
|
StkId luaD_tryfuncTM (lua_State *L, StkId func) {
|
||||||
const TValue *tm = luaT_gettmbyobj(L, s2v(func), TM_CALL);
|
const TValue *tm;
|
||||||
StkId p;
|
StkId p;
|
||||||
|
checkstackGCp(L, 1, func); /* space for metamethod */
|
||||||
|
tm = luaT_gettmbyobj(L, s2v(func), TM_CALL); /* (after previous GC) */
|
||||||
if (l_unlikely(ttisnil(tm)))
|
if (l_unlikely(ttisnil(tm)))
|
||||||
luaG_callerror(L, s2v(func)); /* nothing to call */
|
luaG_callerror(L, s2v(func)); /* nothing to call */
|
||||||
for (p = L->top; p > func; p--) /* open space for metamethod */
|
for (p = L->top.p; p > func; p--) /* open space for metamethod */
|
||||||
setobjs2s(L, p, p-1);
|
setobjs2s(L, p, p-1);
|
||||||
L->top++; /* stack space pre-allocated by the caller */
|
L->top.p++; /* stack space pre-allocated by the caller */
|
||||||
setobj2s(L, func, tm); /* metamethod is the new function to be called */
|
setobj2s(L, func, tm); /* metamethod is the new function to be called */
|
||||||
|
return func;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -425,33 +450,34 @@ void luaD_tryfuncTM (lua_State *L, StkId func) {
|
||||||
** expressions, multiple results for tail calls/single parameters)
|
** expressions, multiple results for tail calls/single parameters)
|
||||||
** separated.
|
** separated.
|
||||||
*/
|
*/
|
||||||
static void moveresults (lua_State *L, StkId res, int nres, int wanted) {
|
l_sinline void moveresults (lua_State *L, StkId res, int nres, int wanted) {
|
||||||
StkId firstresult;
|
StkId firstresult;
|
||||||
int i;
|
int i;
|
||||||
switch (wanted) { /* handle typical cases separately */
|
switch (wanted) { /* handle typical cases separately */
|
||||||
case 0: /* no values needed */
|
case 0: /* no values needed */
|
||||||
L->top = res;
|
L->top.p = res;
|
||||||
return;
|
return;
|
||||||
case 1: /* one value needed */
|
case 1: /* one value needed */
|
||||||
if (nres == 0) /* no results? */
|
if (nres == 0) /* no results? */
|
||||||
setnilvalue(s2v(res)); /* adjust with nil */
|
setnilvalue(s2v(res)); /* adjust with nil */
|
||||||
else /* at least one result */
|
else /* at least one result */
|
||||||
setobjs2s(L, res, L->top - nres); /* move it to proper place */
|
setobjs2s(L, res, L->top.p - nres); /* move it to proper place */
|
||||||
L->top = res + 1;
|
L->top.p = res + 1;
|
||||||
return;
|
return;
|
||||||
case LUA_MULTRET:
|
case LUA_MULTRET:
|
||||||
wanted = nres; /* we want all results */
|
wanted = nres; /* we want all results */
|
||||||
break;
|
break;
|
||||||
default: /* two/more results and/or to-be-closed variables */
|
default: /* two/more results and/or to-be-closed variables */
|
||||||
if (hastocloseCfunc(wanted)) { /* to-be-closed variables? */
|
if (hastocloseCfunc(wanted)) { /* to-be-closed variables? */
|
||||||
ptrdiff_t savedres = savestack(L, res);
|
|
||||||
L->ci->callstatus |= CIST_CLSRET; /* in case of yields */
|
L->ci->callstatus |= CIST_CLSRET; /* in case of yields */
|
||||||
L->ci->u2.nres = nres;
|
L->ci->u2.nres = nres;
|
||||||
luaF_close(L, res, CLOSEKTOP, 1);
|
res = luaF_close(L, res, CLOSEKTOP, 1);
|
||||||
L->ci->callstatus &= ~CIST_CLSRET;
|
L->ci->callstatus &= ~CIST_CLSRET;
|
||||||
if (L->hookmask) /* if needed, call hook after '__close's */
|
if (L->hookmask) { /* if needed, call hook after '__close's */
|
||||||
|
ptrdiff_t savedres = savestack(L, res);
|
||||||
rethook(L, L->ci, nres);
|
rethook(L, L->ci, nres);
|
||||||
res = restorestack(L, savedres); /* close and hook can move stack */
|
res = restorestack(L, savedres); /* hook can move stack */
|
||||||
|
}
|
||||||
wanted = decodeNresults(wanted);
|
wanted = decodeNresults(wanted);
|
||||||
if (wanted == LUA_MULTRET)
|
if (wanted == LUA_MULTRET)
|
||||||
wanted = nres; /* we want all results */
|
wanted = nres; /* we want all results */
|
||||||
|
@ -459,14 +485,14 @@ static void moveresults (lua_State *L, StkId res, int nres, int wanted) {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
/* generic case */
|
/* generic case */
|
||||||
firstresult = L->top - nres; /* index of first result */
|
firstresult = L->top.p - nres; /* index of first result */
|
||||||
if (nres > wanted) /* extra results? */
|
if (nres > wanted) /* extra results? */
|
||||||
nres = wanted; /* don't need them */
|
nres = wanted; /* don't need them */
|
||||||
for (i = 0; i < nres; i++) /* move all results to correct place */
|
for (i = 0; i < nres; i++) /* move all results to correct place */
|
||||||
setobjs2s(L, res + i, firstresult + i);
|
setobjs2s(L, res + i, firstresult + i);
|
||||||
for (; i < wanted; i++) /* complete wanted number of results */
|
for (; i < wanted; i++) /* complete wanted number of results */
|
||||||
setnilvalue(s2v(res + i));
|
setnilvalue(s2v(res + i));
|
||||||
L->top = res + wanted; /* top points after the last result */
|
L->top.p = res + wanted; /* top points after the last result */
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -481,7 +507,7 @@ void luaD_poscall (lua_State *L, CallInfo *ci, int nres) {
|
||||||
if (l_unlikely(L->hookmask && !hastocloseCfunc(wanted)))
|
if (l_unlikely(L->hookmask && !hastocloseCfunc(wanted)))
|
||||||
rethook(L, ci, nres);
|
rethook(L, ci, nres);
|
||||||
/* move results to proper place */
|
/* move results to proper place */
|
||||||
moveresults(L, ci->func, nres, wanted);
|
moveresults(L, ci->func.p, nres, wanted);
|
||||||
/* function cannot be in any of these cases when returning */
|
/* function cannot be in any of these cases when returning */
|
||||||
lua_assert(!(ci->callstatus &
|
lua_assert(!(ci->callstatus &
|
||||||
(CIST_HOOKED | CIST_YPCALL | CIST_FIN | CIST_TRAN | CIST_CLSRET)));
|
(CIST_HOOKED | CIST_YPCALL | CIST_FIN | CIST_TRAN | CIST_CLSRET)));
|
||||||
|
@ -493,27 +519,81 @@ void luaD_poscall (lua_State *L, CallInfo *ci, int nres) {
|
||||||
#define next_ci(L) (L->ci->next ? L->ci->next : luaE_extendCI(L))
|
#define next_ci(L) (L->ci->next ? L->ci->next : luaE_extendCI(L))
|
||||||
|
|
||||||
|
|
||||||
|
l_sinline CallInfo *prepCallInfo (lua_State *L, StkId func, int nret,
|
||||||
|
int mask, StkId top) {
|
||||||
|
CallInfo *ci = L->ci = next_ci(L); /* new frame */
|
||||||
|
ci->func.p = func;
|
||||||
|
ci->nresults = nret;
|
||||||
|
ci->callstatus = mask;
|
||||||
|
ci->top.p = top;
|
||||||
|
return ci;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
** precall for C functions
|
||||||
|
*/
|
||||||
|
l_sinline int precallC (lua_State *L, StkId func, int nresults,
|
||||||
|
lua_CFunction f) {
|
||||||
|
int n; /* number of returns */
|
||||||
|
CallInfo *ci;
|
||||||
|
checkstackGCp(L, LUA_MINSTACK, func); /* ensure minimum stack size */
|
||||||
|
L->ci = ci = prepCallInfo(L, func, nresults, CIST_C,
|
||||||
|
L->top.p + LUA_MINSTACK);
|
||||||
|
lua_assert(ci->top.p <= L->stack_last.p);
|
||||||
|
if (l_unlikely(L->hookmask & LUA_MASKCALL)) {
|
||||||
|
int narg = cast_int(L->top.p - func) - 1;
|
||||||
|
luaD_hook(L, LUA_HOOKCALL, -1, 1, narg);
|
||||||
|
}
|
||||||
|
lua_unlock(L);
|
||||||
|
n = (*f)(L); /* do the actual call */
|
||||||
|
lua_lock(L);
|
||||||
|
api_checknelems(L, n);
|
||||||
|
luaD_poscall(L, ci, n);
|
||||||
|
return n;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
** Prepare a function for a tail call, building its call info on top
|
** Prepare a function for a tail call, building its call info on top
|
||||||
** of the current call info. 'narg1' is the number of arguments plus 1
|
** of the current call info. 'narg1' is the number of arguments plus 1
|
||||||
** (so that it includes the function itself).
|
** (so that it includes the function itself). Return the number of
|
||||||
|
** results, if it was a C function, or -1 for a Lua function.
|
||||||
*/
|
*/
|
||||||
void luaD_pretailcall (lua_State *L, CallInfo *ci, StkId func, int narg1) {
|
int luaD_pretailcall (lua_State *L, CallInfo *ci, StkId func,
|
||||||
|
int narg1, int delta) {
|
||||||
|
retry:
|
||||||
|
switch (ttypetag(s2v(func))) {
|
||||||
|
case LUA_VCCL: /* C closure */
|
||||||
|
return precallC(L, func, LUA_MULTRET, clCvalue(s2v(func))->f);
|
||||||
|
case LUA_VLCF: /* light C function */
|
||||||
|
return precallC(L, func, LUA_MULTRET, fvalue(s2v(func)));
|
||||||
|
case LUA_VLCL: { /* Lua function */
|
||||||
Proto *p = clLvalue(s2v(func))->p;
|
Proto *p = clLvalue(s2v(func))->p;
|
||||||
int fsize = p->maxstacksize; /* frame size */
|
int fsize = p->maxstacksize; /* frame size */
|
||||||
int nfixparams = p->numparams;
|
int nfixparams = p->numparams;
|
||||||
int i;
|
int i;
|
||||||
|
checkstackGCp(L, fsize - delta, func);
|
||||||
|
ci->func.p -= delta; /* restore 'func' (if vararg) */
|
||||||
for (i = 0; i < narg1; i++) /* move down function and arguments */
|
for (i = 0; i < narg1; i++) /* move down function and arguments */
|
||||||
setobjs2s(L, ci->func + i, func + i);
|
setobjs2s(L, ci->func.p + i, func + i);
|
||||||
checkstackGC(L, fsize);
|
func = ci->func.p; /* moved-down function */
|
||||||
func = ci->func; /* moved-down function */
|
|
||||||
for (; narg1 <= nfixparams; narg1++)
|
for (; narg1 <= nfixparams; narg1++)
|
||||||
setnilvalue(s2v(func + narg1)); /* complete missing arguments */
|
setnilvalue(s2v(func + narg1)); /* complete missing arguments */
|
||||||
ci->top = func + 1 + fsize; /* top for new function */
|
ci->top.p = func + 1 + fsize; /* top for new function */
|
||||||
lua_assert(ci->top <= L->stack_last);
|
lua_assert(ci->top.p <= L->stack_last.p);
|
||||||
ci->u.l.savedpc = p->code; /* starting point */
|
ci->u.l.savedpc = p->code; /* starting point */
|
||||||
ci->callstatus |= CIST_TAIL;
|
ci->callstatus |= CIST_TAIL;
|
||||||
L->top = func + narg1; /* set top */
|
L->top.p = func + narg1; /* set top */
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
default: { /* not a function */
|
||||||
|
func = luaD_tryfuncTM(L, func); /* try to get '__call' metamethod */
|
||||||
|
/* return luaD_pretailcall(L, ci, func, narg1 + 1, delta); */
|
||||||
|
narg1++;
|
||||||
|
goto retry; /* try again */
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -526,56 +606,31 @@ void luaD_pretailcall (lua_State *L, CallInfo *ci, StkId func, int narg1) {
|
||||||
** original function position.
|
** original function position.
|
||||||
*/
|
*/
|
||||||
CallInfo *luaD_precall (lua_State *L, StkId func, int nresults) {
|
CallInfo *luaD_precall (lua_State *L, StkId func, int nresults) {
|
||||||
lua_CFunction f;
|
|
||||||
retry:
|
retry:
|
||||||
switch (ttypetag(s2v(func))) {
|
switch (ttypetag(s2v(func))) {
|
||||||
case LUA_VCCL: /* C closure */
|
case LUA_VCCL: /* C closure */
|
||||||
f = clCvalue(s2v(func))->f;
|
precallC(L, func, nresults, clCvalue(s2v(func))->f);
|
||||||
goto Cfunc;
|
return NULL;
|
||||||
case LUA_VLCF: /* light C function */
|
case LUA_VLCF: /* light C function */
|
||||||
f = fvalue(s2v(func));
|
precallC(L, func, nresults, fvalue(s2v(func)));
|
||||||
Cfunc: {
|
|
||||||
int n; /* number of returns */
|
|
||||||
CallInfo *ci;
|
|
||||||
checkstackGCp(L, LUA_MINSTACK, func); /* ensure minimum stack size */
|
|
||||||
L->ci = ci = next_ci(L);
|
|
||||||
ci->nresults = nresults;
|
|
||||||
ci->callstatus = CIST_C;
|
|
||||||
ci->top = L->top + LUA_MINSTACK;
|
|
||||||
ci->func = func;
|
|
||||||
lua_assert(ci->top <= L->stack_last);
|
|
||||||
if (l_unlikely(L->hookmask & LUA_MASKCALL)) {
|
|
||||||
int narg = cast_int(L->top - func) - 1;
|
|
||||||
luaD_hook(L, LUA_HOOKCALL, -1, 1, narg);
|
|
||||||
}
|
|
||||||
lua_unlock(L);
|
|
||||||
n = (*f)(L); /* do the actual call */
|
|
||||||
lua_lock(L);
|
|
||||||
api_checknelems(L, n);
|
|
||||||
luaD_poscall(L, ci, n);
|
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
|
||||||
case LUA_VLCL: { /* Lua function */
|
case LUA_VLCL: { /* Lua function */
|
||||||
CallInfo *ci;
|
CallInfo *ci;
|
||||||
Proto *p = clLvalue(s2v(func))->p;
|
Proto *p = clLvalue(s2v(func))->p;
|
||||||
int narg = cast_int(L->top - func) - 1; /* number of real arguments */
|
int narg = cast_int(L->top.p - func) - 1; /* number of real arguments */
|
||||||
int nfixparams = p->numparams;
|
int nfixparams = p->numparams;
|
||||||
int fsize = p->maxstacksize; /* frame size */
|
int fsize = p->maxstacksize; /* frame size */
|
||||||
checkstackGCp(L, fsize, func);
|
checkstackGCp(L, fsize, func);
|
||||||
L->ci = ci = next_ci(L);
|
L->ci = ci = prepCallInfo(L, func, nresults, 0, func + 1 + fsize);
|
||||||
ci->nresults = nresults;
|
|
||||||
ci->u.l.savedpc = p->code; /* starting point */
|
ci->u.l.savedpc = p->code; /* starting point */
|
||||||
ci->top = func + 1 + fsize;
|
|
||||||
ci->func = func;
|
|
||||||
L->ci = ci;
|
|
||||||
for (; narg < nfixparams; narg++)
|
for (; narg < nfixparams; narg++)
|
||||||
setnilvalue(s2v(L->top++)); /* complete missing arguments */
|
setnilvalue(s2v(L->top.p++)); /* complete missing arguments */
|
||||||
lua_assert(ci->top <= L->stack_last);
|
lua_assert(ci->top.p <= L->stack_last.p);
|
||||||
return ci;
|
return ci;
|
||||||
}
|
}
|
||||||
default: { /* not a function */
|
default: { /* not a function */
|
||||||
checkstackGCp(L, 1, func); /* space for metamethod */
|
func = luaD_tryfuncTM(L, func); /* try to get '__call' metamethod */
|
||||||
luaD_tryfuncTM(L, func); /* try to get '__call' metamethod */
|
/* return luaD_precall(L, func, nresults); */
|
||||||
goto retry; /* try again with metamethod */
|
goto retry; /* try again with metamethod */
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -586,12 +641,17 @@ CallInfo *luaD_precall (lua_State *L, StkId func, int nresults) {
|
||||||
** Call a function (C or Lua) through C. 'inc' can be 1 (increment
|
** Call a function (C or Lua) through C. 'inc' can be 1 (increment
|
||||||
** number of recursive invocations in the C stack) or nyci (the same
|
** number of recursive invocations in the C stack) or nyci (the same
|
||||||
** plus increment number of non-yieldable calls).
|
** plus increment number of non-yieldable calls).
|
||||||
|
** This function can be called with some use of EXTRA_STACK, so it should
|
||||||
|
** check the stack before doing anything else. 'luaD_precall' already
|
||||||
|
** does that.
|
||||||
*/
|
*/
|
||||||
static void ccall (lua_State *L, StkId func, int nResults, int inc) {
|
l_sinline void ccall (lua_State *L, StkId func, int nResults, l_uint32 inc) {
|
||||||
CallInfo *ci;
|
CallInfo *ci;
|
||||||
L->nCcalls += inc;
|
L->nCcalls += inc;
|
||||||
if (l_unlikely(getCcalls(L) >= LUAI_MAXCCALLS))
|
if (l_unlikely(getCcalls(L) >= LUAI_MAXCCALLS)) {
|
||||||
|
checkstackp(L, 0, func); /* free any use of EXTRA_STACK */
|
||||||
luaE_checkcstack(L);
|
luaE_checkcstack(L);
|
||||||
|
}
|
||||||
if ((ci = luaD_precall(L, func, nResults)) != NULL) { /* Lua function? */
|
if ((ci = luaD_precall(L, func, nResults)) != NULL) { /* Lua function? */
|
||||||
ci->callstatus = CIST_FRESH; /* mark that it is a "fresh" execute */
|
ci->callstatus = CIST_FRESH; /* mark that it is a "fresh" execute */
|
||||||
luaV_execute(L, ci); /* call it */
|
luaV_execute(L, ci); /* call it */
|
||||||
|
@ -639,8 +699,7 @@ static int finishpcallk (lua_State *L, CallInfo *ci) {
|
||||||
else { /* error */
|
else { /* error */
|
||||||
StkId func = restorestack(L, ci->u2.funcidx);
|
StkId func = restorestack(L, ci->u2.funcidx);
|
||||||
L->allowhook = getoah(ci->callstatus); /* restore 'allowhook' */
|
L->allowhook = getoah(ci->callstatus); /* restore 'allowhook' */
|
||||||
luaF_close(L, func, status, 1); /* can yield or raise an error */
|
func = luaF_close(L, func, status, 1); /* can yield or raise an error */
|
||||||
func = restorestack(L, ci->u2.funcidx); /* stack may be moved */
|
|
||||||
luaD_seterrorobj(L, status, func);
|
luaD_seterrorobj(L, status, func);
|
||||||
luaD_shrinkstack(L); /* restore stack size in case of overflow */
|
luaD_shrinkstack(L); /* restore stack size in case of overflow */
|
||||||
setcistrecst(ci, LUA_OK); /* clear original status */
|
setcistrecst(ci, LUA_OK); /* clear original status */
|
||||||
|
@ -728,8 +787,8 @@ static CallInfo *findpcall (lua_State *L) {
|
||||||
** coroutine error handler and should not kill the coroutine.)
|
** coroutine error handler and should not kill the coroutine.)
|
||||||
*/
|
*/
|
||||||
static int resume_error (lua_State *L, const char *msg, int narg) {
|
static int resume_error (lua_State *L, const char *msg, int narg) {
|
||||||
L->top -= narg; /* remove args from the stack */
|
L->top.p -= narg; /* remove args from the stack */
|
||||||
setsvalue2s(L, L->top, luaS_new(L, msg)); /* push error message */
|
setsvalue2s(L, L->top.p, luaS_new(L, msg)); /* push error message */
|
||||||
api_incr_top(L);
|
api_incr_top(L);
|
||||||
lua_unlock(L);
|
lua_unlock(L);
|
||||||
return LUA_ERRRUN;
|
return LUA_ERRRUN;
|
||||||
|
@ -745,16 +804,15 @@ static int resume_error (lua_State *L, const char *msg, int narg) {
|
||||||
*/
|
*/
|
||||||
static void resume (lua_State *L, void *ud) {
|
static void resume (lua_State *L, void *ud) {
|
||||||
int n = *(cast(int*, ud)); /* number of arguments */
|
int n = *(cast(int*, ud)); /* number of arguments */
|
||||||
StkId firstArg = L->top - n; /* first argument */
|
StkId firstArg = L->top.p - n; /* first argument */
|
||||||
CallInfo *ci = L->ci;
|
CallInfo *ci = L->ci;
|
||||||
if (L->status == LUA_OK) /* starting a coroutine? */
|
if (L->status == LUA_OK) /* starting a coroutine? */
|
||||||
ccall(L, firstArg - 1, LUA_MULTRET, 1); /* just call its body */
|
ccall(L, firstArg - 1, LUA_MULTRET, 0); /* just call its body */
|
||||||
else { /* resuming from previous yield */
|
else { /* resuming from previous yield */
|
||||||
lua_assert(L->status == LUA_YIELD);
|
lua_assert(L->status == LUA_YIELD);
|
||||||
L->status = LUA_OK; /* mark that it is running (again) */
|
L->status = LUA_OK; /* mark that it is running (again) */
|
||||||
luaE_incCstack(L); /* control the C stack */
|
|
||||||
if (isLua(ci)) { /* yielded inside a hook? */
|
if (isLua(ci)) { /* yielded inside a hook? */
|
||||||
L->top = firstArg; /* discard arguments */
|
L->top.p = firstArg; /* discard arguments */
|
||||||
luaV_execute(L, ci); /* just continue running Lua code */
|
luaV_execute(L, ci); /* just continue running Lua code */
|
||||||
}
|
}
|
||||||
else { /* 'common' yield */
|
else { /* 'common' yield */
|
||||||
|
@ -797,12 +855,15 @@ LUA_API int lua_resume (lua_State *L, lua_State *from, int nargs,
|
||||||
if (L->status == LUA_OK) { /* may be starting a coroutine */
|
if (L->status == LUA_OK) { /* may be starting a coroutine */
|
||||||
if (L->ci != &L->base_ci) /* not in base level? */
|
if (L->ci != &L->base_ci) /* not in base level? */
|
||||||
return resume_error(L, "cannot resume non-suspended coroutine", nargs);
|
return resume_error(L, "cannot resume non-suspended coroutine", nargs);
|
||||||
else if (L->top - (L->ci->func + 1) == nargs) /* no function? */
|
else if (L->top.p - (L->ci->func.p + 1) == nargs) /* no function? */
|
||||||
return resume_error(L, "cannot resume dead coroutine", nargs);
|
return resume_error(L, "cannot resume dead coroutine", nargs);
|
||||||
}
|
}
|
||||||
else if (L->status != LUA_YIELD) /* ended with errors? */
|
else if (L->status != LUA_YIELD) /* ended with errors? */
|
||||||
return resume_error(L, "cannot resume dead coroutine", nargs);
|
return resume_error(L, "cannot resume dead coroutine", nargs);
|
||||||
L->nCcalls = (from) ? getCcalls(from) : 0;
|
L->nCcalls = (from) ? getCcalls(from) : 0;
|
||||||
|
if (getCcalls(L) >= LUAI_MAXCCALLS)
|
||||||
|
return resume_error(L, "C stack overflow", nargs);
|
||||||
|
L->nCcalls++;
|
||||||
luai_userstateresume(L, nargs);
|
luai_userstateresume(L, nargs);
|
||||||
api_checknelems(L, (L->status == LUA_OK) ? nargs + 1 : nargs);
|
api_checknelems(L, (L->status == LUA_OK) ? nargs + 1 : nargs);
|
||||||
status = luaD_rawrunprotected(L, resume, &nargs);
|
status = luaD_rawrunprotected(L, resume, &nargs);
|
||||||
|
@ -812,11 +873,11 @@ LUA_API int lua_resume (lua_State *L, lua_State *from, int nargs,
|
||||||
lua_assert(status == L->status); /* normal end or yield */
|
lua_assert(status == L->status); /* normal end or yield */
|
||||||
else { /* unrecoverable error */
|
else { /* unrecoverable error */
|
||||||
L->status = cast_byte(status); /* mark thread as 'dead' */
|
L->status = cast_byte(status); /* mark thread as 'dead' */
|
||||||
luaD_seterrorobj(L, status, L->top); /* push error message */
|
luaD_seterrorobj(L, status, L->top.p); /* push error message */
|
||||||
L->ci->top = L->top;
|
L->ci->top.p = L->top.p;
|
||||||
}
|
}
|
||||||
*nresults = (status == LUA_YIELD) ? L->ci->u2.nyield
|
*nresults = (status == LUA_YIELD) ? L->ci->u2.nyield
|
||||||
: cast_int(L->top - (L->ci->func + 1));
|
: cast_int(L->top.p - (L->ci->func.p + 1));
|
||||||
lua_unlock(L);
|
lua_unlock(L);
|
||||||
return status;
|
return status;
|
||||||
}
|
}
|
||||||
|
@ -971,7 +1032,7 @@ int luaD_protectedparser (lua_State *L, ZIO *z, const char *name,
|
||||||
p.dyd.gt.arr = NULL; p.dyd.gt.size = 0;
|
p.dyd.gt.arr = NULL; p.dyd.gt.size = 0;
|
||||||
p.dyd.label.arr = NULL; p.dyd.label.size = 0;
|
p.dyd.label.arr = NULL; p.dyd.label.size = 0;
|
||||||
luaZ_initbuffer(L, &p.buff);
|
luaZ_initbuffer(L, &p.buff);
|
||||||
status = luaD_pcall(L, f_parser, &p, savestack(L, L->top), L->errfunc);
|
status = luaD_pcall(L, f_parser, &p, savestack(L, L->top.p), L->errfunc);
|
||||||
luaZ_freebuffer(L, &p.buff);
|
luaZ_freebuffer(L, &p.buff);
|
||||||
luaM_freearray(L, p.dyd.actvar.arr, p.dyd.actvar.size);
|
luaM_freearray(L, p.dyd.actvar.arr, p.dyd.actvar.size);
|
||||||
luaM_freearray(L, p.dyd.gt.arr, p.dyd.gt.size);
|
luaM_freearray(L, p.dyd.gt.arr, p.dyd.gt.size);
|
||||||
|
|
18
third_party/lua/ldo.h
vendored
18
third_party/lua/ldo.h
vendored
|
@ -16,7 +16,7 @@
|
||||||
** at every check.
|
** at every check.
|
||||||
*/
|
*/
|
||||||
#define luaD_checkstackaux(L,n,pre,pos) \
|
#define luaD_checkstackaux(L,n,pre,pos) \
|
||||||
if (l_unlikely(L->stack_last - L->top <= (n))) \
|
if (l_unlikely(L->stack_last.p - L->top.p <= (n))) \
|
||||||
{ pre; luaD_growstack(L, n, 1); pos; } \
|
{ pre; luaD_growstack(L, n, 1); pos; } \
|
||||||
else { condmovestack(L,pre,pos); }
|
else { condmovestack(L,pre,pos); }
|
||||||
|
|
||||||
|
@ -25,11 +25,18 @@
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
#define savestack(L,p) ((char *)(p) - (char *)L->stack)
|
#define savestack(L,pt) (cast_charp(pt) - cast_charp(L->stack.p))
|
||||||
#define restorestack(L,n) ((StkId)((char *)L->stack + (n)))
|
#define restorestack(L,n) cast(StkId, cast_charp(L->stack.p) + (n))
|
||||||
|
|
||||||
|
|
||||||
/* macro to check stack size, preserving 'p' */
|
/* macro to check stack size, preserving 'p' */
|
||||||
|
#define checkstackp(L,n,p) \
|
||||||
|
luaD_checkstackaux(L, n, \
|
||||||
|
ptrdiff_t t__ = savestack(L, p), /* save 'p' */ \
|
||||||
|
p = restorestack(L, t__)) /* 'pos' part: restore 'p' */
|
||||||
|
|
||||||
|
|
||||||
|
/* macro to check stack size and GC, preserving 'p' */
|
||||||
#define checkstackGCp(L,n,p) \
|
#define checkstackGCp(L,n,p) \
|
||||||
luaD_checkstackaux(L, n, \
|
luaD_checkstackaux(L, n, \
|
||||||
ptrdiff_t t__ = savestack(L, p); /* save 'p' */ \
|
ptrdiff_t t__ = savestack(L, p); /* save 'p' */ \
|
||||||
|
@ -51,11 +58,12 @@ LUAI_FUNC int luaD_protectedparser (lua_State *L, ZIO *z, const char *name,
|
||||||
LUAI_FUNC void luaD_hook (lua_State *L, int event, int line,
|
LUAI_FUNC void luaD_hook (lua_State *L, int event, int line,
|
||||||
int fTransfer, int nTransfer);
|
int fTransfer, int nTransfer);
|
||||||
LUAI_FUNC void luaD_hookcall (lua_State *L, CallInfo *ci);
|
LUAI_FUNC void luaD_hookcall (lua_State *L, CallInfo *ci);
|
||||||
LUAI_FUNC void luaD_pretailcall (lua_State *L, CallInfo *ci, StkId func, int n);
|
LUAI_FUNC int luaD_pretailcall (lua_State *L, CallInfo *ci, StkId func,
|
||||||
|
int narg1, int delta);
|
||||||
LUAI_FUNC CallInfo *luaD_precall (lua_State *L, StkId func, int nResults);
|
LUAI_FUNC CallInfo *luaD_precall (lua_State *L, StkId func, int nResults);
|
||||||
LUAI_FUNC void luaD_call (lua_State *L, StkId func, int nResults);
|
LUAI_FUNC void luaD_call (lua_State *L, StkId func, int nResults);
|
||||||
LUAI_FUNC void luaD_callnoyield (lua_State *L, StkId func, int nResults);
|
LUAI_FUNC void luaD_callnoyield (lua_State *L, StkId func, int nResults);
|
||||||
LUAI_FUNC void luaD_tryfuncTM (lua_State *L, StkId func);
|
LUAI_FUNC StkId luaD_tryfuncTM (lua_State *L, StkId func);
|
||||||
LUAI_FUNC int luaD_closeprotected (lua_State *L, ptrdiff_t level, int status);
|
LUAI_FUNC int luaD_closeprotected (lua_State *L, ptrdiff_t level, int status);
|
||||||
LUAI_FUNC int luaD_pcall (lua_State *L, Pfunc func, void *u,
|
LUAI_FUNC int luaD_pcall (lua_State *L, Pfunc func, void *u,
|
||||||
ptrdiff_t oldtop, ptrdiff_t ef);
|
ptrdiff_t oldtop, ptrdiff_t ef);
|
||||||
|
|
10
third_party/lua/ldump.c
vendored
10
third_party/lua/ldump.c
vendored
|
@ -3,7 +3,7 @@
|
||||||
╚──────────────────────────────────────────────────────────────────────────────╝
|
╚──────────────────────────────────────────────────────────────────────────────╝
|
||||||
│ │
|
│ │
|
||||||
│ Lua │
|
│ Lua │
|
||||||
│ Copyright © 2004-2021 Lua.org, PUC-Rio. │
|
│ Copyright © 2004-2023 Lua.org, PUC-Rio. │
|
||||||
│ │
|
│ │
|
||||||
│ Permission is hereby granted, free of charge, to any person obtaining │
|
│ Permission is hereby granted, free of charge, to any person obtaining │
|
||||||
│ a copy of this software and associated documentation files (the │
|
│ a copy of this software and associated documentation files (the │
|
||||||
|
@ -27,6 +27,7 @@
|
||||||
╚─────────────────────────────────────────────────────────────────────────────*/
|
╚─────────────────────────────────────────────────────────────────────────────*/
|
||||||
#define ldump_c
|
#define ldump_c
|
||||||
#define LUA_CORE
|
#define LUA_CORE
|
||||||
|
|
||||||
#include "third_party/lua/lobject.h"
|
#include "third_party/lua/lobject.h"
|
||||||
#include "third_party/lua/lprefix.h"
|
#include "third_party/lua/lprefix.h"
|
||||||
#include "third_party/lua/lstate.h"
|
#include "third_party/lua/lstate.h"
|
||||||
|
@ -71,8 +72,11 @@ static void dumpByte (DumpState *D, int y) {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/* dumpInt Buff Size */
|
/*
|
||||||
#define DIBS ((sizeof(size_t) * 8 / 7) + 1)
|
** 'dumpSize' buffer size: each byte can store up to 7 bits. (The "+6"
|
||||||
|
** rounds up the division.)
|
||||||
|
*/
|
||||||
|
#define DIBS ((sizeof(size_t) * CHAR_BIT + 6) / 7)
|
||||||
|
|
||||||
static void dumpSize (DumpState *D, size_t x) {
|
static void dumpSize (DumpState *D, size_t x) {
|
||||||
lu_byte buff[DIBS];
|
lu_byte buff[DIBS];
|
||||||
|
|
57
third_party/lua/lfunc.c
vendored
57
third_party/lua/lfunc.c
vendored
|
@ -3,7 +3,7 @@
|
||||||
╚──────────────────────────────────────────────────────────────────────────────╝
|
╚──────────────────────────────────────────────────────────────────────────────╝
|
||||||
│ │
|
│ │
|
||||||
│ Lua │
|
│ Lua │
|
||||||
│ Copyright © 2004-2021 Lua.org, PUC-Rio. │
|
│ Copyright © 2004-2023 Lua.org, PUC-Rio. │
|
||||||
│ │
|
│ │
|
||||||
│ Permission is hereby granted, free of charge, to any person obtaining │
|
│ Permission is hereby granted, free of charge, to any person obtaining │
|
||||||
│ a copy of this software and associated documentation files (the │
|
│ a copy of this software and associated documentation files (the │
|
||||||
|
@ -27,6 +27,7 @@
|
||||||
╚─────────────────────────────────────────────────────────────────────────────*/
|
╚─────────────────────────────────────────────────────────────────────────────*/
|
||||||
#define lfunc_c
|
#define lfunc_c
|
||||||
#define LUA_CORE
|
#define LUA_CORE
|
||||||
|
|
||||||
#include "third_party/lua/ldebug.h"
|
#include "third_party/lua/ldebug.h"
|
||||||
#include "third_party/lua/ldo.h"
|
#include "third_party/lua/ldo.h"
|
||||||
#include "third_party/lua/lfunc.h"
|
#include "third_party/lua/lfunc.h"
|
||||||
|
@ -66,8 +67,8 @@ void luaF_initupvals (lua_State *L, LClosure *cl) {
|
||||||
for (i = 0; i < cl->nupvalues; i++) {
|
for (i = 0; i < cl->nupvalues; i++) {
|
||||||
GCObject *o = luaC_newobj(L, LUA_VUPVAL, sizeof(UpVal));
|
GCObject *o = luaC_newobj(L, LUA_VUPVAL, sizeof(UpVal));
|
||||||
UpVal *uv = gco2upv(o);
|
UpVal *uv = gco2upv(o);
|
||||||
uv->v = &uv->u.value; /* make it closed */
|
uv->v.p = &uv->u.value; /* make it closed */
|
||||||
setnilvalue(uv->v);
|
setnilvalue(uv->v.p);
|
||||||
cl->upvals[i] = uv;
|
cl->upvals[i] = uv;
|
||||||
luaC_objbarrier(L, cl, uv);
|
luaC_objbarrier(L, cl, uv);
|
||||||
}
|
}
|
||||||
|
@ -78,12 +79,11 @@ void luaF_initupvals (lua_State *L, LClosure *cl) {
|
||||||
** Create a new upvalue at the given level, and link it to the list of
|
** Create a new upvalue at the given level, and link it to the list of
|
||||||
** open upvalues of 'L' after entry 'prev'.
|
** open upvalues of 'L' after entry 'prev'.
|
||||||
**/
|
**/
|
||||||
static UpVal *newupval (lua_State *L, int tbc, StkId level, UpVal **prev) {
|
static UpVal *newupval (lua_State *L, StkId level, UpVal **prev) {
|
||||||
GCObject *o = luaC_newobj(L, LUA_VUPVAL, sizeof(UpVal));
|
GCObject *o = luaC_newobj(L, LUA_VUPVAL, sizeof(UpVal));
|
||||||
UpVal *uv = gco2upv(o);
|
UpVal *uv = gco2upv(o);
|
||||||
UpVal *next = *prev;
|
UpVal *next = *prev;
|
||||||
uv->v = s2v(level); /* current value lives in the stack */
|
uv->v.p = s2v(level); /* current value lives in the stack */
|
||||||
uv->tbc = tbc;
|
|
||||||
uv->u.open.next = next; /* link it to list of open upvalues */
|
uv->u.open.next = next; /* link it to list of open upvalues */
|
||||||
uv->u.open.previous = prev;
|
uv->u.open.previous = prev;
|
||||||
if (next)
|
if (next)
|
||||||
|
@ -112,7 +112,7 @@ UpVal *luaF_findupval (lua_State *L, StkId level) {
|
||||||
pp = &p->u.open.next;
|
pp = &p->u.open.next;
|
||||||
}
|
}
|
||||||
/* not found: create a new upvalue after 'pp' */
|
/* not found: create a new upvalue after 'pp' */
|
||||||
return newupval(L, 0, level, pp);
|
return newupval(L, level, pp);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -122,12 +122,12 @@ UpVal *luaF_findupval (lua_State *L, StkId level) {
|
||||||
** (This function assumes EXTRA_STACK.)
|
** (This function assumes EXTRA_STACK.)
|
||||||
*/
|
*/
|
||||||
static void callclosemethod (lua_State *L, TValue *obj, TValue *err, int yy) {
|
static void callclosemethod (lua_State *L, TValue *obj, TValue *err, int yy) {
|
||||||
StkId top = L->top;
|
StkId top = L->top.p;
|
||||||
const TValue *tm = luaT_gettmbyobj(L, obj, TM_CLOSE);
|
const TValue *tm = luaT_gettmbyobj(L, obj, TM_CLOSE);
|
||||||
setobj2s(L, top, tm); /* will call metamethod... */
|
setobj2s(L, top, tm); /* will call metamethod... */
|
||||||
setobj2s(L, top + 1, obj); /* with 'self' as the 1st argument */
|
setobj2s(L, top + 1, obj); /* with 'self' as the 1st argument */
|
||||||
setobj2s(L, top + 2, err); /* and error msg. as 2nd argument */
|
setobj2s(L, top + 2, err); /* and error msg. as 2nd argument */
|
||||||
L->top = top + 3; /* add function and arguments */
|
L->top.p = top + 3; /* add function and arguments */
|
||||||
if (yy)
|
if (yy)
|
||||||
luaD_call(L, top, 0);
|
luaD_call(L, top, 0);
|
||||||
else
|
else
|
||||||
|
@ -142,7 +142,7 @@ static void callclosemethod (lua_State *L, TValue *obj, TValue *err, int yy) {
|
||||||
static void checkclosemth (lua_State *L, StkId level) {
|
static void checkclosemth (lua_State *L, StkId level) {
|
||||||
const TValue *tm = luaT_gettmbyobj(L, s2v(level), TM_CLOSE);
|
const TValue *tm = luaT_gettmbyobj(L, s2v(level), TM_CLOSE);
|
||||||
if (ttisnil(tm)) { /* no metamethod? */
|
if (ttisnil(tm)) { /* no metamethod? */
|
||||||
int idx = cast_int(level - L->ci->func); /* variable index */
|
int idx = cast_int(level - L->ci->func.p); /* variable index */
|
||||||
const char *vname = luaG_findlocal(L, L->ci, idx, NULL);
|
const char *vname = luaG_findlocal(L, L->ci, idx, NULL);
|
||||||
if (vname == NULL) vname = "?";
|
if (vname == NULL) vname = "?";
|
||||||
luaG_runerror(L, "variable '%s' got a non-closable value", vname);
|
luaG_runerror(L, "variable '%s' got a non-closable value", vname);
|
||||||
|
@ -176,23 +176,23 @@ static void prepcallclosemth (lua_State *L, StkId level, int status, int yy) {
|
||||||
** is used.)
|
** is used.)
|
||||||
*/
|
*/
|
||||||
#define MAXDELTA \
|
#define MAXDELTA \
|
||||||
((256ul << ((sizeof(L->stack->tbclist.delta) - 1) * 8)) - 1)
|
((256ul << ((sizeof(L->stack.p->tbclist.delta) - 1) * 8)) - 1)
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
** Insert a variable in the list of to-be-closed variables.
|
** Insert a variable in the list of to-be-closed variables.
|
||||||
*/
|
*/
|
||||||
void luaF_newtbcupval (lua_State *L, StkId level) {
|
void luaF_newtbcupval (lua_State *L, StkId level) {
|
||||||
lua_assert(level > L->tbclist);
|
lua_assert(level > L->tbclist.p);
|
||||||
if (l_isfalse(s2v(level)))
|
if (l_isfalse(s2v(level)))
|
||||||
return; /* false doesn't need to be closed */
|
return; /* false doesn't need to be closed */
|
||||||
checkclosemth(L, level); /* value must have a close method */
|
checkclosemth(L, level); /* value must have a close method */
|
||||||
while (cast_uint(level - L->tbclist) > MAXDELTA) {
|
while (cast_uint(level - L->tbclist.p) > MAXDELTA) {
|
||||||
L->tbclist += MAXDELTA; /* create a dummy node at maximum delta */
|
L->tbclist.p += MAXDELTA; /* create a dummy node at maximum delta */
|
||||||
L->tbclist->tbclist.delta = 0;
|
L->tbclist.p->tbclist.delta = 0;
|
||||||
}
|
}
|
||||||
level->tbclist.delta = cast(unsigned short, level - L->tbclist);
|
level->tbclist.delta = cast(unsigned short, level - L->tbclist.p);
|
||||||
L->tbclist = level;
|
L->tbclist.p = level;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -212,10 +212,10 @@ void luaF_closeupval (lua_State *L, StkId level) {
|
||||||
StkId upl; /* stack index pointed by 'uv' */
|
StkId upl; /* stack index pointed by 'uv' */
|
||||||
while ((uv = L->openupval) != NULL && (upl = uplevel(uv)) >= level) {
|
while ((uv = L->openupval) != NULL && (upl = uplevel(uv)) >= level) {
|
||||||
TValue *slot = &uv->u.value; /* new position for value */
|
TValue *slot = &uv->u.value; /* new position for value */
|
||||||
lua_assert(uplevel(uv) < L->top);
|
lua_assert(uplevel(uv) < L->top.p);
|
||||||
luaF_unlinkupval(uv); /* remove upvalue from 'openupval' list */
|
luaF_unlinkupval(uv); /* remove upvalue from 'openupval' list */
|
||||||
setobj(L, slot, uv->v); /* move value to upvalue slot */
|
setobj(L, slot, uv->v.p); /* move value to upvalue slot */
|
||||||
uv->v = slot; /* now current value lives here */
|
uv->v.p = slot; /* now current value lives here */
|
||||||
if (!iswhite(uv)) { /* neither white nor dead? */
|
if (!iswhite(uv)) { /* neither white nor dead? */
|
||||||
nw2black(uv); /* closed upvalues cannot be gray */
|
nw2black(uv); /* closed upvalues cannot be gray */
|
||||||
luaC_barrier(L, uv, slot);
|
luaC_barrier(L, uv, slot);
|
||||||
|
@ -225,31 +225,32 @@ void luaF_closeupval (lua_State *L, StkId level) {
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
** Remove firt element from the tbclist plus its dummy nodes.
|
** Remove first element from the tbclist plus its dummy nodes.
|
||||||
*/
|
*/
|
||||||
static void poptbclist (lua_State *L) {
|
static void poptbclist (lua_State *L) {
|
||||||
StkId tbc = L->tbclist;
|
StkId tbc = L->tbclist.p;
|
||||||
lua_assert(tbc->tbclist.delta > 0); /* first element cannot be dummy */
|
lua_assert(tbc->tbclist.delta > 0); /* first element cannot be dummy */
|
||||||
tbc -= tbc->tbclist.delta;
|
tbc -= tbc->tbclist.delta;
|
||||||
while (tbc > L->stack && tbc->tbclist.delta == 0)
|
while (tbc > L->stack.p && tbc->tbclist.delta == 0)
|
||||||
tbc -= MAXDELTA; /* remove dummy nodes */
|
tbc -= MAXDELTA; /* remove dummy nodes */
|
||||||
L->tbclist = tbc;
|
L->tbclist.p = tbc;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
** Close all upvalues and to-be-closed variables up to the given stack
|
** Close all upvalues and to-be-closed variables up to the given stack
|
||||||
** level.
|
** level. Return restored 'level'.
|
||||||
*/
|
*/
|
||||||
void luaF_close (lua_State *L, StkId level, int status, int yy) {
|
StkId luaF_close (lua_State *L, StkId level, int status, int yy) {
|
||||||
ptrdiff_t levelrel = savestack(L, level);
|
ptrdiff_t levelrel = savestack(L, level);
|
||||||
luaF_closeupval(L, level); /* first, close the upvalues */
|
luaF_closeupval(L, level); /* first, close the upvalues */
|
||||||
while (L->tbclist >= level) { /* traverse tbc's down to that level */
|
while (L->tbclist.p >= level) { /* traverse tbc's down to that level */
|
||||||
StkId tbc = L->tbclist; /* get variable index */
|
StkId tbc = L->tbclist.p; /* get variable index */
|
||||||
poptbclist(L); /* remove it from list */
|
poptbclist(L); /* remove it from list */
|
||||||
prepcallclosemth(L, tbc, status, yy); /* close variable */
|
prepcallclosemth(L, tbc, status, yy); /* close variable */
|
||||||
level = restorestack(L, levelrel);
|
level = restorestack(L, levelrel);
|
||||||
}
|
}
|
||||||
|
return level;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
6
third_party/lua/lfunc.h
vendored
6
third_party/lua/lfunc.h
vendored
|
@ -22,10 +22,10 @@
|
||||||
#define MAXUPVAL 255
|
#define MAXUPVAL 255
|
||||||
|
|
||||||
|
|
||||||
#define upisopen(up) ((up)->v != &(up)->u.value)
|
#define upisopen(up) ((up)->v.p != &(up)->u.value)
|
||||||
|
|
||||||
|
|
||||||
#define uplevel(up) check_exp(upisopen(up), cast(StkId, (up)->v))
|
#define uplevel(up) check_exp(upisopen(up), cast(StkId, (up)->v.p))
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -47,7 +47,7 @@ LUAI_FUNC void luaF_initupvals (lua_State *L, LClosure *cl);
|
||||||
LUAI_FUNC UpVal *luaF_findupval (lua_State *L, StkId level);
|
LUAI_FUNC UpVal *luaF_findupval (lua_State *L, StkId level);
|
||||||
LUAI_FUNC void luaF_newtbcupval (lua_State *L, StkId level);
|
LUAI_FUNC void luaF_newtbcupval (lua_State *L, StkId level);
|
||||||
LUAI_FUNC void luaF_closeupval (lua_State *L, StkId level);
|
LUAI_FUNC void luaF_closeupval (lua_State *L, StkId level);
|
||||||
LUAI_FUNC void luaF_close (lua_State *L, StkId level, int status, int yy);
|
LUAI_FUNC StkId luaF_close (lua_State *L, StkId level, int status, int yy);
|
||||||
LUAI_FUNC void luaF_unlinkupval (UpVal *uv);
|
LUAI_FUNC void luaF_unlinkupval (UpVal *uv);
|
||||||
LUAI_FUNC void luaF_freeproto (lua_State *L, Proto *f);
|
LUAI_FUNC void luaF_freeproto (lua_State *L, Proto *f);
|
||||||
LUAI_FUNC const char *luaF_getlocalname (const Proto *func, int local_number,
|
LUAI_FUNC const char *luaF_getlocalname (const Proto *func, int local_number,
|
||||||
|
|
124
third_party/lua/lgc.c
vendored
124
third_party/lua/lgc.c
vendored
|
@ -3,7 +3,7 @@
|
||||||
╚──────────────────────────────────────────────────────────────────────────────╝
|
╚──────────────────────────────────────────────────────────────────────────────╝
|
||||||
│ │
|
│ │
|
||||||
│ Lua │
|
│ Lua │
|
||||||
│ Copyright © 2004-2021 Lua.org, PUC-Rio. │
|
│ Copyright © 2004-2023 Lua.org, PUC-Rio. │
|
||||||
│ │
|
│ │
|
||||||
│ Permission is hereby granted, free of charge, to any person obtaining │
|
│ Permission is hereby granted, free of charge, to any person obtaining │
|
||||||
│ a copy of this software and associated documentation files (the │
|
│ a copy of this software and associated documentation files (the │
|
||||||
|
@ -27,6 +27,7 @@
|
||||||
╚─────────────────────────────────────────────────────────────────────────────*/
|
╚─────────────────────────────────────────────────────────────────────────────*/
|
||||||
#define lgc_c
|
#define lgc_c
|
||||||
#define LUA_CORE
|
#define LUA_CORE
|
||||||
|
|
||||||
#include "libc/str/str.h"
|
#include "libc/str/str.h"
|
||||||
#include "third_party/lua/ldebug.h"
|
#include "third_party/lua/ldebug.h"
|
||||||
#include "third_party/lua/ldo.h"
|
#include "third_party/lua/ldo.h"
|
||||||
|
@ -268,12 +269,13 @@ void luaC_fix (lua_State *L, GCObject *o) {
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
** create a new collectable object (with given type and size) and link
|
** create a new collectable object (with given type, size, and offset)
|
||||||
** it to 'allgc' list.
|
** and link it to 'allgc' list.
|
||||||
*/
|
*/
|
||||||
GCObject *luaC_newobj (lua_State *L, int tt, size_t sz) {
|
GCObject *luaC_newobjdt (lua_State *L, int tt, size_t sz, size_t offset) {
|
||||||
global_State *g = G(L);
|
global_State *g = G(L);
|
||||||
GCObject *o = cast(GCObject *, luaM_newobject(L, novariant(tt), sz));
|
char *p = cast_charp(luaM_newobject(L, novariant(tt), sz));
|
||||||
|
GCObject *o = cast(GCObject *, p + offset);
|
||||||
o->marked = luaC_white(g);
|
o->marked = luaC_white(g);
|
||||||
o->tt = tt;
|
o->tt = tt;
|
||||||
o->next = g->allgc;
|
o->next = g->allgc;
|
||||||
|
@ -281,6 +283,11 @@ GCObject *luaC_newobj (lua_State *L, int tt, size_t sz) {
|
||||||
return o;
|
return o;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
GCObject *luaC_newobj (lua_State *L, int tt, size_t sz) {
|
||||||
|
return luaC_newobjdt(L, tt, sz, 0);
|
||||||
|
}
|
||||||
|
|
||||||
/* }====================================================== */
|
/* }====================================================== */
|
||||||
|
|
||||||
|
|
||||||
|
@ -317,7 +324,7 @@ static void reallymarkobject (global_State *g, GCObject *o) {
|
||||||
set2gray(uv); /* open upvalues are kept gray */
|
set2gray(uv); /* open upvalues are kept gray */
|
||||||
else
|
else
|
||||||
set2black(uv); /* closed upvalues are visited here */
|
set2black(uv); /* closed upvalues are visited here */
|
||||||
markvalue(g, uv->v); /* mark its content */
|
markvalue(g, uv->v.p); /* mark its content */
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case LUA_VUSERDATA: {
|
case LUA_VUSERDATA: {
|
||||||
|
@ -392,7 +399,7 @@ static int remarkupvals (global_State *g) {
|
||||||
work++;
|
work++;
|
||||||
if (!iswhite(uv)) { /* upvalue already visited? */
|
if (!iswhite(uv)) { /* upvalue already visited? */
|
||||||
lua_assert(upisopen(uv) && isgray(uv));
|
lua_assert(upisopen(uv) && isgray(uv));
|
||||||
markvalue(g, uv->v); /* mark its value */
|
markvalue(g, uv->v.p); /* mark its value */
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -636,19 +643,19 @@ static int traverseLclosure (global_State *g, LClosure *cl) {
|
||||||
*/
|
*/
|
||||||
static int traversethread (global_State *g, lua_State *th) {
|
static int traversethread (global_State *g, lua_State *th) {
|
||||||
UpVal *uv;
|
UpVal *uv;
|
||||||
StkId o = th->stack;
|
StkId o = th->stack.p;
|
||||||
if (isold(th) || g->gcstate == GCSpropagate)
|
if (isold(th) || g->gcstate == GCSpropagate)
|
||||||
linkgclist(th, g->grayagain); /* insert into 'grayagain' list */
|
linkgclist(th, g->grayagain); /* insert into 'grayagain' list */
|
||||||
if (o == NULL)
|
if (o == NULL)
|
||||||
return 1; /* stack not completely built yet */
|
return 1; /* stack not completely built yet */
|
||||||
lua_assert(g->gcstate == GCSatomic ||
|
lua_assert(g->gcstate == GCSatomic ||
|
||||||
th->openupval == NULL || isintwups(th));
|
th->openupval == NULL || isintwups(th));
|
||||||
for (; o < th->top; o++) /* mark live elements in the stack */
|
for (; o < th->top.p; o++) /* mark live elements in the stack */
|
||||||
markvalue(g, s2v(o));
|
markvalue(g, s2v(o));
|
||||||
for (uv = th->openupval; uv != NULL; uv = uv->u.open.next)
|
for (uv = th->openupval; uv != NULL; uv = uv->u.open.next)
|
||||||
markobject(g, uv); /* open upvalues cannot be collected */
|
markobject(g, uv); /* open upvalues cannot be collected */
|
||||||
if (g->gcstate == GCSatomic) { /* final traversal? */
|
if (g->gcstate == GCSatomic) { /* final traversal? */
|
||||||
for (; o < th->stack_last + EXTRA_STACK; o++)
|
for (; o < th->stack_last.p + EXTRA_STACK; o++)
|
||||||
setnilvalue(s2v(o)); /* clear dead stack slice */
|
setnilvalue(s2v(o)); /* clear dead stack slice */
|
||||||
/* 'remarkupvals' may have removed thread from 'twups' list */
|
/* 'remarkupvals' may have removed thread from 'twups' list */
|
||||||
if (!isintwups(th) && th->openupval != NULL) {
|
if (!isintwups(th) && th->openupval != NULL) {
|
||||||
|
@ -908,7 +915,7 @@ static GCObject *udata2finalize (global_State *g) {
|
||||||
|
|
||||||
static void dothecall (lua_State *L, void *ud) {
|
static void dothecall (lua_State *L, void *ud) {
|
||||||
UNUSED(ud);
|
UNUSED(ud);
|
||||||
luaD_callnoyield(L, L->top - 2, 0);
|
luaD_callnoyield(L, L->top.p - 2, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -922,19 +929,19 @@ static void GCTM (lua_State *L) {
|
||||||
if (!notm(tm)) { /* is there a finalizer? */
|
if (!notm(tm)) { /* is there a finalizer? */
|
||||||
int status;
|
int status;
|
||||||
lu_byte oldah = L->allowhook;
|
lu_byte oldah = L->allowhook;
|
||||||
int running = g->gcrunning;
|
int oldgcstp = g->gcstp;
|
||||||
|
g->gcstp |= GCSTPGC; /* avoid GC steps */
|
||||||
L->allowhook = 0; /* stop debug hooks during GC metamethod */
|
L->allowhook = 0; /* stop debug hooks during GC metamethod */
|
||||||
g->gcrunning = 0; /* avoid GC steps */
|
setobj2s(L, L->top.p++, tm); /* push finalizer... */
|
||||||
setobj2s(L, L->top++, tm); /* push finalizer... */
|
setobj2s(L, L->top.p++, &v); /* ... and its argument */
|
||||||
setobj2s(L, L->top++, &v); /* ... and its argument */
|
|
||||||
L->ci->callstatus |= CIST_FIN; /* will run a finalizer */
|
L->ci->callstatus |= CIST_FIN; /* will run a finalizer */
|
||||||
status = luaD_pcall(L, dothecall, NULL, savestack(L, L->top - 2), 0);
|
status = luaD_pcall(L, dothecall, NULL, savestack(L, L->top.p - 2), 0);
|
||||||
L->ci->callstatus &= ~CIST_FIN; /* not running a finalizer anymore */
|
L->ci->callstatus &= ~CIST_FIN; /* not running a finalizer anymore */
|
||||||
L->allowhook = oldah; /* restore hooks */
|
L->allowhook = oldah; /* restore hooks */
|
||||||
g->gcrunning = running; /* restore state */
|
g->gcstp = oldgcstp; /* restore state */
|
||||||
if (l_unlikely(status != LUA_OK)) { /* error while running __gc? */
|
if (l_unlikely(status != LUA_OK)) { /* error while running __gc? */
|
||||||
luaE_warnerror(L, "__gc metamethod");
|
luaE_warnerror(L, "__gc");
|
||||||
L->top--; /* pops error object */
|
L->top.p--; /* pops error object */
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1027,7 +1034,8 @@ static void correctpointers (global_State *g, GCObject *o) {
|
||||||
void luaC_checkfinalizer (lua_State *L, GCObject *o, Table *mt) {
|
void luaC_checkfinalizer (lua_State *L, GCObject *o, Table *mt) {
|
||||||
global_State *g = G(L);
|
global_State *g = G(L);
|
||||||
if (tofinalize(o) || /* obj. is already marked... */
|
if (tofinalize(o) || /* obj. is already marked... */
|
||||||
gfasttm(g, mt, TM_GC) == NULL) /* or has no finalizer? */
|
gfasttm(g, mt, TM_GC) == NULL || /* or has no finalizer... */
|
||||||
|
(g->gcstp & GCSTPCLS)) /* or closing state? */
|
||||||
return; /* nothing to be done */
|
return; /* nothing to be done */
|
||||||
else { /* move 'o' to 'finobj' list */
|
else { /* move 'o' to 'finobj' list */
|
||||||
GCObject **p;
|
GCObject **p;
|
||||||
|
@ -1056,7 +1064,25 @@ void luaC_checkfinalizer (lua_State *L, GCObject *o, Table *mt) {
|
||||||
** =======================================================
|
** =======================================================
|
||||||
*/
|
*/
|
||||||
|
|
||||||
static void setpause (global_State *g);
|
|
||||||
|
/*
|
||||||
|
** Set the "time" to wait before starting a new GC cycle; cycle will
|
||||||
|
** start when memory use hits the threshold of ('estimate' * pause /
|
||||||
|
** PAUSEADJ). (Division by 'estimate' should be OK: it cannot be zero,
|
||||||
|
** because Lua cannot even start with less than PAUSEADJ bytes).
|
||||||
|
*/
|
||||||
|
static void setpause (global_State *g) {
|
||||||
|
l_mem threshold, debt;
|
||||||
|
int pause = getgcparam(g->gcpause);
|
||||||
|
l_mem estimate = g->GCestimate / PAUSEADJ; /* adjust 'estimate' */
|
||||||
|
lua_assert(estimate > 0);
|
||||||
|
threshold = (pause < MAX_LMEM / estimate) /* overflow? */
|
||||||
|
? estimate * pause /* no overflow */
|
||||||
|
: MAX_LMEM; /* overflow; truncate to maximum */
|
||||||
|
debt = gettotalbytes(g) - threshold;
|
||||||
|
if (debt > 0) debt = 0;
|
||||||
|
luaE_setdebt(g, debt);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -1300,6 +1326,15 @@ static void atomic2gen (lua_State *L, global_State *g) {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
** Set debt for the next minor collection, which will happen when
|
||||||
|
** memory grows 'genminormul'%.
|
||||||
|
*/
|
||||||
|
static void setminordebt (global_State *g) {
|
||||||
|
luaE_setdebt(g, -(cast(l_mem, (gettotalbytes(g) / 100)) * g->genminormul));
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
** Enter generational mode. Must go until the end of an atomic cycle
|
** Enter generational mode. Must go until the end of an atomic cycle
|
||||||
** to ensure that all objects are correctly marked and weak tables
|
** to ensure that all objects are correctly marked and weak tables
|
||||||
|
@ -1312,6 +1347,7 @@ static lu_mem entergen (lua_State *L, global_State *g) {
|
||||||
luaC_runtilstate(L, bitmask(GCSpropagate)); /* start new cycle */
|
luaC_runtilstate(L, bitmask(GCSpropagate)); /* start new cycle */
|
||||||
numobjs = atomic(L); /* propagates all and then do the atomic stuff */
|
numobjs = atomic(L); /* propagates all and then do the atomic stuff */
|
||||||
atomic2gen(L, g);
|
atomic2gen(L, g);
|
||||||
|
setminordebt(g); /* set debt assuming next cycle will be minor */
|
||||||
return numobjs;
|
return numobjs;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1357,15 +1393,6 @@ static lu_mem fullgen (lua_State *L, global_State *g) {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/*
|
|
||||||
** Set debt for the next minor collection, which will happen when
|
|
||||||
** memory grows 'genminormul'%.
|
|
||||||
*/
|
|
||||||
static void setminordebt (global_State *g) {
|
|
||||||
luaE_setdebt(g, -(cast(l_mem, (gettotalbytes(g) / 100)) * g->genminormul));
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
** Does a major collection after last collection was a "bad collection".
|
** Does a major collection after last collection was a "bad collection".
|
||||||
**
|
**
|
||||||
|
@ -1437,8 +1464,8 @@ static void genstep (lua_State *L, global_State *g) {
|
||||||
lu_mem numobjs = fullgen(L, g); /* do a major collection */
|
lu_mem numobjs = fullgen(L, g); /* do a major collection */
|
||||||
if (gettotalbytes(g) < majorbase + (majorinc / 2)) {
|
if (gettotalbytes(g) < majorbase + (majorinc / 2)) {
|
||||||
/* collected at least half of memory growth since last major
|
/* collected at least half of memory growth since last major
|
||||||
collection; keep doing minor collections */
|
collection; keep doing minor collections. */
|
||||||
setminordebt(g);
|
lua_assert(g->lastatomic == 0);
|
||||||
}
|
}
|
||||||
else { /* bad collection */
|
else { /* bad collection */
|
||||||
g->lastatomic = numobjs; /* signal that last collection was bad */
|
g->lastatomic = numobjs; /* signal that last collection was bad */
|
||||||
|
@ -1464,26 +1491,6 @@ static void genstep (lua_State *L, global_State *g) {
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
|
||||||
/*
|
|
||||||
** Set the "time" to wait before starting a new GC cycle; cycle will
|
|
||||||
** start when memory use hits the threshold of ('estimate' * pause /
|
|
||||||
** PAUSEADJ). (Division by 'estimate' should be OK: it cannot be zero,
|
|
||||||
** because Lua cannot even start with less than PAUSEADJ bytes).
|
|
||||||
*/
|
|
||||||
static void setpause (global_State *g) {
|
|
||||||
l_mem threshold, debt;
|
|
||||||
int pause = getgcparam(g->gcpause);
|
|
||||||
l_mem estimate = g->GCestimate / PAUSEADJ; /* adjust 'estimate' */
|
|
||||||
lua_assert(estimate > 0);
|
|
||||||
threshold = (pause < MAX_LMEM / estimate) /* overflow? */
|
|
||||||
? estimate * pause /* no overflow */
|
|
||||||
: MAX_LMEM; /* overflow; truncate to maximum */
|
|
||||||
debt = gettotalbytes(g) - threshold;
|
|
||||||
if (debt > 0) debt = 0;
|
|
||||||
luaE_setdebt(g, debt);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
** Enter first sweep phase.
|
** Enter first sweep phase.
|
||||||
** The call to 'sweeptolive' makes the pointer point to an object
|
** The call to 'sweeptolive' makes the pointer point to an object
|
||||||
|
@ -1518,12 +1525,13 @@ static void deletelist (lua_State *L, GCObject *p, GCObject *limit) {
|
||||||
*/
|
*/
|
||||||
void luaC_freeallobjects (lua_State *L) {
|
void luaC_freeallobjects (lua_State *L) {
|
||||||
global_State *g = G(L);
|
global_State *g = G(L);
|
||||||
|
g->gcstp = GCSTPCLS; /* no extra finalizers after here */
|
||||||
luaC_changemode(L, KGC_INC);
|
luaC_changemode(L, KGC_INC);
|
||||||
separatetobefnz(g, 1); /* separate all objects with finalizers */
|
separatetobefnz(g, 1); /* separate all objects with finalizers */
|
||||||
lua_assert(g->finobj == NULL);
|
lua_assert(g->finobj == NULL);
|
||||||
callallpendingfinalizers(L);
|
callallpendingfinalizers(L);
|
||||||
deletelist(L, g->allgc, obj2gco(g->mainthread));
|
deletelist(L, g->allgc, obj2gco(g->mainthread));
|
||||||
deletelist(L, g->finobj, NULL);
|
lua_assert(g->finobj == NULL); /* no new finalizers */
|
||||||
deletelist(L, g->fixedgc, NULL); /* collect fixed objects */
|
deletelist(L, g->fixedgc, NULL); /* collect fixed objects */
|
||||||
lua_assert(g->strt.nuse == 0);
|
lua_assert(g->strt.nuse == 0);
|
||||||
}
|
}
|
||||||
|
@ -1663,6 +1671,7 @@ void luaC_runtilstate (lua_State *L, int statesmask) {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
** Performs a basic incremental step. The debt and step size are
|
** Performs a basic incremental step. The debt and step size are
|
||||||
** converted from bytes to "units of work"; then the function loops
|
** converted from bytes to "units of work"; then the function loops
|
||||||
|
@ -1689,12 +1698,15 @@ static void incstep (lua_State *L, global_State *g) {
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
** performs a basic GC step if collector is running
|
** Performs a basic GC step if collector is running. (If collector is
|
||||||
|
** not running, set a reasonable debt to avoid it being called at
|
||||||
|
** every single check.)
|
||||||
*/
|
*/
|
||||||
void luaC_step (lua_State *L) {
|
void luaC_step (lua_State *L) {
|
||||||
global_State *g = G(L);
|
global_State *g = G(L);
|
||||||
lua_assert(!g->gcemergency);
|
if (!gcrunning(g)) /* not running? */
|
||||||
if (g->gcrunning) { /* running? */
|
luaE_setdebt(g, -2000);
|
||||||
|
else {
|
||||||
if(isdecGCmodegen(g))
|
if(isdecGCmodegen(g))
|
||||||
genstep(L, g);
|
genstep(L, g);
|
||||||
else
|
else
|
||||||
|
|
29
third_party/lua/lgc.h
vendored
29
third_party/lua/lgc.h
vendored
|
@ -142,6 +142,16 @@
|
||||||
*/
|
*/
|
||||||
#define isdecGCmodegen(g) (g->gckind == KGC_GEN || g->lastatomic != 0)
|
#define isdecGCmodegen(g) (g->gckind == KGC_GEN || g->lastatomic != 0)
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
** Control when GC is running:
|
||||||
|
*/
|
||||||
|
#define GCSTPUSR 1 /* bit true when GC stopped by user */
|
||||||
|
#define GCSTPGC 2 /* bit true when GC stopped by itself */
|
||||||
|
#define GCSTPCLS 4 /* bit true when closing Lua state */
|
||||||
|
#define gcrunning(g) ((g)->gcstp == 0)
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
** Does one step of collection when debt becomes positive. 'pre'/'pos'
|
** Does one step of collection when debt becomes positive. 'pre'/'pos'
|
||||||
** allows some adjustments to be done only when needed. macro
|
** allows some adjustments to be done only when needed. macro
|
||||||
|
@ -156,24 +166,27 @@
|
||||||
#define luaC_checkGC(L) luaC_condGC(L,(void)0,(void)0)
|
#define luaC_checkGC(L) luaC_condGC(L,(void)0,(void)0)
|
||||||
|
|
||||||
|
|
||||||
#define luaC_barrier(L,p,v) ( \
|
|
||||||
(iscollectable(v) && isblack(p) && iswhite(gcvalue(v))) ? \
|
|
||||||
luaC_barrier_(L,obj2gco(p),gcvalue(v)) : cast_void(0))
|
|
||||||
|
|
||||||
#define luaC_barrierback(L,p,v) ( \
|
|
||||||
(iscollectable(v) && isblack(p) && iswhite(gcvalue(v))) ? \
|
|
||||||
luaC_barrierback_(L,p) : cast_void(0))
|
|
||||||
|
|
||||||
#define luaC_objbarrier(L,p,o) ( \
|
#define luaC_objbarrier(L,p,o) ( \
|
||||||
(isblack(p) && iswhite(o)) ? \
|
(isblack(p) && iswhite(o)) ? \
|
||||||
luaC_barrier_(L,obj2gco(p),obj2gco(o)) : cast_void(0))
|
luaC_barrier_(L,obj2gco(p),obj2gco(o)) : cast_void(0))
|
||||||
|
|
||||||
|
#define luaC_barrier(L,p,v) ( \
|
||||||
|
iscollectable(v) ? luaC_objbarrier(L,p,gcvalue(v)) : cast_void(0))
|
||||||
|
|
||||||
|
#define luaC_objbarrierback(L,p,o) ( \
|
||||||
|
(isblack(p) && iswhite(o)) ? luaC_barrierback_(L,p) : cast_void(0))
|
||||||
|
|
||||||
|
#define luaC_barrierback(L,p,v) ( \
|
||||||
|
iscollectable(v) ? luaC_objbarrierback(L, p, gcvalue(v)) : cast_void(0))
|
||||||
|
|
||||||
LUAI_FUNC void luaC_fix (lua_State *L, GCObject *o);
|
LUAI_FUNC void luaC_fix (lua_State *L, GCObject *o);
|
||||||
LUAI_FUNC void luaC_freeallobjects (lua_State *L);
|
LUAI_FUNC void luaC_freeallobjects (lua_State *L);
|
||||||
LUAI_FUNC void luaC_step (lua_State *L);
|
LUAI_FUNC void luaC_step (lua_State *L);
|
||||||
LUAI_FUNC void luaC_runtilstate (lua_State *L, int statesmask);
|
LUAI_FUNC void luaC_runtilstate (lua_State *L, int statesmask);
|
||||||
LUAI_FUNC void luaC_fullgc (lua_State *L, int isemergency);
|
LUAI_FUNC void luaC_fullgc (lua_State *L, int isemergency);
|
||||||
LUAI_FUNC GCObject *luaC_newobj (lua_State *L, int tt, size_t sz);
|
LUAI_FUNC GCObject *luaC_newobj (lua_State *L, int tt, size_t sz);
|
||||||
|
LUAI_FUNC GCObject *luaC_newobjdt (lua_State *L, int tt, size_t sz,
|
||||||
|
size_t offset);
|
||||||
LUAI_FUNC void luaC_barrier_ (lua_State *L, GCObject *o, GCObject *v);
|
LUAI_FUNC void luaC_barrier_ (lua_State *L, GCObject *o, GCObject *v);
|
||||||
LUAI_FUNC void luaC_barrierback_ (lua_State *L, GCObject *o);
|
LUAI_FUNC void luaC_barrierback_ (lua_State *L, GCObject *o);
|
||||||
LUAI_FUNC void luaC_checkfinalizer (lua_State *L, GCObject *o, Table *mt);
|
LUAI_FUNC void luaC_checkfinalizer (lua_State *L, GCObject *o, Table *mt);
|
||||||
|
|
4
third_party/lua/linit.c
vendored
4
third_party/lua/linit.c
vendored
|
@ -3,7 +3,7 @@
|
||||||
╚──────────────────────────────────────────────────────────────────────────────╝
|
╚──────────────────────────────────────────────────────────────────────────────╝
|
||||||
│ │
|
│ │
|
||||||
│ Lua │
|
│ Lua │
|
||||||
│ Copyright © 2004-2021 Lua.org, PUC-Rio. │
|
│ Copyright © 2004-2023 Lua.org, PUC-Rio. │
|
||||||
│ │
|
│ │
|
||||||
│ Permission is hereby granted, free of charge, to any person obtaining │
|
│ Permission is hereby granted, free of charge, to any person obtaining │
|
||||||
│ a copy of this software and associated documentation files (the │
|
│ a copy of this software and associated documentation files (the │
|
||||||
|
@ -27,6 +27,7 @@
|
||||||
╚─────────────────────────────────────────────────────────────────────────────*/
|
╚─────────────────────────────────────────────────────────────────────────────*/
|
||||||
#define linit_c
|
#define linit_c
|
||||||
#define LUA_LIB
|
#define LUA_LIB
|
||||||
|
|
||||||
/*
|
/*
|
||||||
** If you embed Lua in your program and need to open the standard
|
** If you embed Lua in your program and need to open the standard
|
||||||
** libraries, call luaL_openlibs in your program. If you need a
|
** libraries, call luaL_openlibs in your program. If you need a
|
||||||
|
@ -42,6 +43,7 @@
|
||||||
** lua_setfield(L, -2, modname);
|
** lua_setfield(L, -2, modname);
|
||||||
** lua_pop(L, 1); // remove PRELOAD table
|
** lua_pop(L, 1); // remove PRELOAD table
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include "third_party/lua/lauxlib.h"
|
#include "third_party/lua/lauxlib.h"
|
||||||
#include "third_party/lua/lprefix.h"
|
#include "third_party/lua/lprefix.h"
|
||||||
#include "third_party/lua/lua.h"
|
#include "third_party/lua/lua.h"
|
||||||
|
|
3
third_party/lua/liolib.c
vendored
3
third_party/lua/liolib.c
vendored
|
@ -3,7 +3,7 @@
|
||||||
╚──────────────────────────────────────────────────────────────────────────────╝
|
╚──────────────────────────────────────────────────────────────────────────────╝
|
||||||
│ │
|
│ │
|
||||||
│ Lua │
|
│ Lua │
|
||||||
│ Copyright © 2004-2021 Lua.org, PUC-Rio. │
|
│ Copyright © 2004-2023 Lua.org, PUC-Rio. │
|
||||||
│ │
|
│ │
|
||||||
│ Permission is hereby granted, free of charge, to any person obtaining │
|
│ Permission is hereby granted, free of charge, to any person obtaining │
|
||||||
│ a copy of this software and associated documentation files (the │
|
│ a copy of this software and associated documentation files (the │
|
||||||
|
@ -27,6 +27,7 @@
|
||||||
╚─────────────────────────────────────────────────────────────────────────────*/
|
╚─────────────────────────────────────────────────────────────────────────────*/
|
||||||
#define liolib_c
|
#define liolib_c
|
||||||
#define LUA_LIB
|
#define LUA_LIB
|
||||||
|
|
||||||
#include "libc/calls/calls.h"
|
#include "libc/calls/calls.h"
|
||||||
#include "libc/calls/weirdtypes.h"
|
#include "libc/calls/weirdtypes.h"
|
||||||
#include "libc/errno.h"
|
#include "libc/errno.h"
|
||||||
|
|
6
third_party/lua/ljumptab.inc
vendored
6
third_party/lua/ljumptab.inc
vendored
|
@ -1,9 +1,3 @@
|
||||||
/*
|
|
||||||
** $Id: ljumptab.h $
|
|
||||||
** Jump Table for the Lua interpreter
|
|
||||||
** See Copyright Notice in lua.h
|
|
||||||
*/
|
|
||||||
|
|
||||||
#undef vmdispatch
|
#undef vmdispatch
|
||||||
#undef vmcase
|
#undef vmcase
|
||||||
#undef vmbreak
|
#undef vmbreak
|
||||||
|
|
11
third_party/lua/llex.c
vendored
11
third_party/lua/llex.c
vendored
|
@ -3,7 +3,7 @@
|
||||||
╚──────────────────────────────────────────────────────────────────────────────╝
|
╚──────────────────────────────────────────────────────────────────────────────╝
|
||||||
│ │
|
│ │
|
||||||
│ Lua │
|
│ Lua │
|
||||||
│ Copyright © 2004-2021 Lua.org, PUC-Rio. │
|
│ Copyright © 2004-2023 Lua.org, PUC-Rio. │
|
||||||
│ │
|
│ │
|
||||||
│ Permission is hereby granted, free of charge, to any person obtaining │
|
│ Permission is hereby granted, free of charge, to any person obtaining │
|
||||||
│ a copy of this software and associated documentation files (the │
|
│ a copy of this software and associated documentation files (the │
|
||||||
|
@ -27,6 +27,7 @@
|
||||||
╚─────────────────────────────────────────────────────────────────────────────*/
|
╚─────────────────────────────────────────────────────────────────────────────*/
|
||||||
#define llex_c
|
#define llex_c
|
||||||
#define LUA_CORE
|
#define LUA_CORE
|
||||||
|
|
||||||
#include "third_party/lua/llex.h"
|
#include "third_party/lua/llex.h"
|
||||||
#include "third_party/lua/lctype.h"
|
#include "third_party/lua/lctype.h"
|
||||||
#include "third_party/lua/ldebug.h"
|
#include "third_party/lua/ldebug.h"
|
||||||
|
@ -142,7 +143,7 @@ l_noret luaX_syntaxerror (LexState *ls, const char *msg) {
|
||||||
** ensuring there is only one copy of each unique string. The table
|
** ensuring there is only one copy of each unique string. The table
|
||||||
** here is used as a set: the string enters as the key, while its value
|
** here is used as a set: the string enters as the key, while its value
|
||||||
** is irrelevant. We use the string itself as the value only because it
|
** is irrelevant. We use the string itself as the value only because it
|
||||||
** is a TValue readly available. Later, the code generation can change
|
** is a TValue readily available. Later, the code generation can change
|
||||||
** this value.
|
** this value.
|
||||||
*/
|
*/
|
||||||
TString *luaX_newstring (LexState *ls, const char *str, size_t l) {
|
TString *luaX_newstring (LexState *ls, const char *str, size_t l) {
|
||||||
|
@ -152,12 +153,12 @@ TString *luaX_newstring (LexState *ls, const char *str, size_t l) {
|
||||||
if (!ttisnil(o)) /* string already present? */
|
if (!ttisnil(o)) /* string already present? */
|
||||||
ts = keystrval(nodefromval(o)); /* get saved copy */
|
ts = keystrval(nodefromval(o)); /* get saved copy */
|
||||||
else { /* not in use yet */
|
else { /* not in use yet */
|
||||||
TValue *stv = s2v(L->top++); /* reserve stack space for string */
|
TValue *stv = s2v(L->top.p++); /* reserve stack space for string */
|
||||||
setsvalue(L, stv, ts); /* temporarily anchor the string */
|
setsvalue(L, stv, ts); /* temporarily anchor the string */
|
||||||
luaH_finishset(L, ls->h, stv, o, stv); /* t[string] = string */
|
luaH_finishset(L, ls->h, stv, o, stv); /* t[string] = string */
|
||||||
/* table is not a metatable, so it does not need to invalidate cache */
|
/* table is not a metatable, so it does not need to invalidate cache */
|
||||||
luaC_checkGC(L);
|
luaC_checkGC(L);
|
||||||
L->top--; /* remove string from stack */
|
L->top.p--; /* remove string from stack */
|
||||||
}
|
}
|
||||||
return ts;
|
return ts;
|
||||||
}
|
}
|
||||||
|
@ -408,9 +409,9 @@ static void read_string (LexState *ls, int del, SemInfo *seminfo) {
|
||||||
int c; /* final character to be saved */
|
int c; /* final character to be saved */
|
||||||
save_and_next(ls); /* keep '\\' for error messages */
|
save_and_next(ls); /* keep '\\' for error messages */
|
||||||
switch (ls->current) {
|
switch (ls->current) {
|
||||||
case 'e': c = '\e'; goto read_save;
|
|
||||||
case 'a': c = '\a'; goto read_save;
|
case 'a': c = '\a'; goto read_save;
|
||||||
case 'b': c = '\b'; goto read_save;
|
case 'b': c = '\b'; goto read_save;
|
||||||
|
case 'e': c = '\e'; goto read_save; // [jart]
|
||||||
case 'f': c = '\f'; goto read_save;
|
case 'f': c = '\f'; goto read_save;
|
||||||
case 'n': c = '\n'; goto read_save;
|
case 'n': c = '\n'; goto read_save;
|
||||||
case 'r': c = '\r'; goto read_save;
|
case 'r': c = '\r'; goto read_save;
|
||||||
|
|
6
third_party/lua/llex.h
vendored
6
third_party/lua/llex.h
vendored
|
@ -1,9 +1,3 @@
|
||||||
/*
|
|
||||||
** $Id: llex.h $
|
|
||||||
** Lexical Analyzer
|
|
||||||
** See Copyright Notice in lua.h
|
|
||||||
*/
|
|
||||||
|
|
||||||
#ifndef llex_h
|
#ifndef llex_h
|
||||||
#define llex_h
|
#define llex_h
|
||||||
|
|
||||||
|
|
37
third_party/lua/llimits.h
vendored
37
third_party/lua/llimits.h
vendored
|
@ -62,11 +62,24 @@ typedef signed char ls_byte;
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
** conversion of pointer to unsigned integer:
|
** conversion of pointer to unsigned integer: this is for hashing only;
|
||||||
** this is for hashing only; there is no problem if the integer
|
** there is no problem if the integer cannot hold the whole pointer
|
||||||
** cannot hold the whole pointer value
|
** value. (In strict ISO C this may cause undefined behavior, but no
|
||||||
|
** actual machine seems to bother.)
|
||||||
*/
|
*/
|
||||||
#define point2uint(p) ((unsigned int)((size_t)(p) & UINT_MAX))
|
#if !defined(LUA_USE_C89) && defined(__STDC_VERSION__) && \
|
||||||
|
__STDC_VERSION__ >= 199901L
|
||||||
|
|
||||||
|
#if defined(UINTPTR_MAX) /* even in C99 this type is optional */
|
||||||
|
#define L_P2I uintptr_t
|
||||||
|
#else /* no 'intptr'? */
|
||||||
|
#define L_P2I uintmax_t /* use the largest available integer */
|
||||||
|
#endif
|
||||||
|
#else /* C89 option */
|
||||||
|
#define L_P2I size_t
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#define point2uint(p) ((unsigned int)((L_P2I)(p) & UINT_MAX))
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
@ -155,6 +168,20 @@ typedef LUAI_UACINT l_uacInt;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
** Inline functions
|
||||||
|
*/
|
||||||
|
#if !defined(LUA_USE_C89)
|
||||||
|
#define l_inline inline
|
||||||
|
#elif defined(__GNUC__)
|
||||||
|
#define l_inline __inline__
|
||||||
|
#else
|
||||||
|
#define l_inline /* empty */
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#define l_sinline static l_inline
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
** type for virtual-machine instructions;
|
** type for virtual-machine instructions;
|
||||||
** must be an unsigned with (at least) 4 bytes (see details in lopcodes.h)
|
** must be an unsigned with (at least) 4 bytes (see details in lopcodes.h)
|
||||||
|
@ -337,7 +364,7 @@ typedef l_uint32 Instruction;
|
||||||
#define condchangemem(L,pre,pos) ((void)0)
|
#define condchangemem(L,pre,pos) ((void)0)
|
||||||
#else
|
#else
|
||||||
#define condchangemem(L,pre,pos) \
|
#define condchangemem(L,pre,pos) \
|
||||||
{ if (G(L)->gcrunning) { pre; luaC_fullgc(L, 0); pos; } }
|
{ if (gcrunning(G(L))) { pre; luaC_fullgc(L, 0); pos; } }
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
17
third_party/lua/lmathlib.c
vendored
17
third_party/lua/lmathlib.c
vendored
|
@ -3,7 +3,7 @@
|
||||||
╚──────────────────────────────────────────────────────────────────────────────╝
|
╚──────────────────────────────────────────────────────────────────────────────╝
|
||||||
│ │
|
│ │
|
||||||
│ Lua │
|
│ Lua │
|
||||||
│ Copyright © 2004-2021 Lua.org, PUC-Rio. │
|
│ Copyright © 2004-2023 Lua.org, PUC-Rio. │
|
||||||
│ │
|
│ │
|
||||||
│ Permission is hereby granted, free of charge, to any person obtaining │
|
│ Permission is hereby granted, free of charge, to any person obtaining │
|
||||||
│ a copy of this software and associated documentation files (the │
|
│ a copy of this software and associated documentation files (the │
|
||||||
|
@ -27,6 +27,7 @@
|
||||||
╚─────────────────────────────────────────────────────────────────────────────*/
|
╚─────────────────────────────────────────────────────────────────────────────*/
|
||||||
#define lmathlib_c
|
#define lmathlib_c
|
||||||
#define LUA_LIB
|
#define LUA_LIB
|
||||||
|
|
||||||
#include "libc/calls/calls.h"
|
#include "libc/calls/calls.h"
|
||||||
#include "libc/math.h"
|
#include "libc/math.h"
|
||||||
#include "libc/nt/struct/msg.h"
|
#include "libc/nt/struct/msg.h"
|
||||||
|
@ -282,7 +283,7 @@ static int math_type (lua_State *L) {
|
||||||
|
|
||||||
/* try to find an integer type with at least 64 bits */
|
/* try to find an integer type with at least 64 bits */
|
||||||
|
|
||||||
#if (ULONG_MAX >> 31 >> 31) >= 3
|
#if ((ULONG_MAX >> 31) >> 31) >= 3
|
||||||
|
|
||||||
/* 'long' has at least 64 bits */
|
/* 'long' has at least 64 bits */
|
||||||
#define Rand64 unsigned long
|
#define Rand64 unsigned long
|
||||||
|
@ -292,9 +293,9 @@ static int math_type (lua_State *L) {
|
||||||
/* there is a 'long long' type (which must have at least 64 bits) */
|
/* there is a 'long long' type (which must have at least 64 bits) */
|
||||||
#define Rand64 unsigned long long
|
#define Rand64 unsigned long long
|
||||||
|
|
||||||
#elif (LUA_MAXUNSIGNED >> 31 >> 31) >= 3
|
#elif ((LUA_MAXUNSIGNED >> 31) >> 31) >= 3
|
||||||
|
|
||||||
/* 'lua_Integer' has at least 64 bits */
|
/* 'lua_Unsigned' has at least 64 bits */
|
||||||
#define Rand64 lua_Unsigned
|
#define Rand64 lua_Unsigned
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
@ -490,7 +491,7 @@ static lua_Number I2d (Rand64 x) {
|
||||||
|
|
||||||
/* 2^(-FIGS) = 1.0 / 2^30 / 2^3 / 2^(FIGS-33) */
|
/* 2^(-FIGS) = 1.0 / 2^30 / 2^3 / 2^(FIGS-33) */
|
||||||
#define scaleFIG \
|
#define scaleFIG \
|
||||||
((lua_Number)1.0 / (UONE << 30) / 8.0 / (UONE << (FIGS - 33)))
|
(l_mathop(1.0) / (UONE << 30) / l_mathop(8.0) / (UONE << (FIGS - 33)))
|
||||||
|
|
||||||
/*
|
/*
|
||||||
** use FIGS - 32 bits from lower half, throwing out the other
|
** use FIGS - 32 bits from lower half, throwing out the other
|
||||||
|
@ -501,7 +502,7 @@ static lua_Number I2d (Rand64 x) {
|
||||||
/*
|
/*
|
||||||
** higher 32 bits go after those (FIGS - 32) bits: shiftHI = 2^(FIGS - 32)
|
** higher 32 bits go after those (FIGS - 32) bits: shiftHI = 2^(FIGS - 32)
|
||||||
*/
|
*/
|
||||||
#define shiftHI ((lua_Number)(UONE << (FIGS - 33)) * 2.0)
|
#define shiftHI ((lua_Number)(UONE << (FIGS - 33)) * l_mathop(2.0))
|
||||||
|
|
||||||
|
|
||||||
static lua_Number I2d (Rand64 x) {
|
static lua_Number I2d (Rand64 x) {
|
||||||
|
@ -515,12 +516,12 @@ static lua_Number I2d (Rand64 x) {
|
||||||
|
|
||||||
/* convert a 'Rand64' to a 'lua_Unsigned' */
|
/* convert a 'Rand64' to a 'lua_Unsigned' */
|
||||||
static lua_Unsigned I2UInt (Rand64 x) {
|
static lua_Unsigned I2UInt (Rand64 x) {
|
||||||
return ((lua_Unsigned)trim32(x.h) << 31 << 1) | (lua_Unsigned)trim32(x.l);
|
return (((lua_Unsigned)trim32(x.h) << 31) << 1) | (lua_Unsigned)trim32(x.l);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* convert a 'lua_Unsigned' to a 'Rand64' */
|
/* convert a 'lua_Unsigned' to a 'Rand64' */
|
||||||
static Rand64 Int2I (lua_Unsigned n) {
|
static Rand64 Int2I (lua_Unsigned n) {
|
||||||
return packI((lu_int32)(n >> 31 >> 1), (lu_int32)n);
|
return packI((lu_int32)((n >> 31) >> 1), (lu_int32)n);
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif /* } */
|
#endif /* } */
|
||||||
|
|
74
third_party/lua/lmem.c
vendored
74
third_party/lua/lmem.c
vendored
|
@ -3,7 +3,7 @@
|
||||||
╚──────────────────────────────────────────────────────────────────────────────╝
|
╚──────────────────────────────────────────────────────────────────────────────╝
|
||||||
│ │
|
│ │
|
||||||
│ Lua │
|
│ Lua │
|
||||||
│ Copyright © 2004-2021 Lua.org, PUC-Rio. │
|
│ Copyright © 2004-2023 Lua.org, PUC-Rio. │
|
||||||
│ │
|
│ │
|
||||||
│ Permission is hereby granted, free of charge, to any person obtaining │
|
│ Permission is hereby granted, free of charge, to any person obtaining │
|
||||||
│ a copy of this software and associated documentation files (the │
|
│ a copy of this software and associated documentation files (the │
|
||||||
|
@ -27,6 +27,7 @@
|
||||||
╚─────────────────────────────────────────────────────────────────────────────*/
|
╚─────────────────────────────────────────────────────────────────────────────*/
|
||||||
#define lmem_c
|
#define lmem_c
|
||||||
#define LUA_CORE
|
#define LUA_CORE
|
||||||
|
|
||||||
#include "libc/log/log.h"
|
#include "libc/log/log.h"
|
||||||
#include "third_party/lua/ldebug.h"
|
#include "third_party/lua/ldebug.h"
|
||||||
#include "third_party/lua/ldo.h"
|
#include "third_party/lua/ldo.h"
|
||||||
|
@ -39,26 +40,6 @@
|
||||||
__static_yoink("lua_notice");
|
__static_yoink("lua_notice");
|
||||||
|
|
||||||
|
|
||||||
#if defined(EMERGENCYGCTESTS)
|
|
||||||
/*
|
|
||||||
** First allocation will fail whenever not building initial state.
|
|
||||||
** (This fail will trigger 'tryagain' and a full GC cycle at every
|
|
||||||
** allocation.)
|
|
||||||
*/
|
|
||||||
static void *firsttry (global_State *g, void *block, size_t os, size_t ns) {
|
|
||||||
if (completestate(g) && ns > 0) /* frees never fail */
|
|
||||||
return NULL; /* fail */
|
|
||||||
else /* normal allocation */
|
|
||||||
return (*g->frealloc)(g->ud, block, os, ns);
|
|
||||||
}
|
|
||||||
#else
|
|
||||||
#define firsttry(g,block,os,ns) ((*g->frealloc)(g->ud, block, os, ns))
|
|
||||||
#endif
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
** About the realloc function:
|
** About the realloc function:
|
||||||
** void *frealloc (void *ud, void *ptr, size_t osize, size_t nsize);
|
** void *frealloc (void *ud, void *ptr, size_t osize, size_t nsize);
|
||||||
|
@ -77,6 +58,43 @@ static void *firsttry (global_State *g, void *block, size_t os, size_t ns) {
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
** Macro to call the allocation function.
|
||||||
|
*/
|
||||||
|
#define callfrealloc(g,block,os,ns) ((*g->frealloc)(g->ud, block, os, ns))
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
** When an allocation fails, it will try again after an emergency
|
||||||
|
** collection, except when it cannot run a collection. The GC should
|
||||||
|
** not be called while the state is not fully built, as the collector
|
||||||
|
** is not yet fully initialized. Also, it should not be called when
|
||||||
|
** 'gcstopem' is true, because then the interpreter is in the middle of
|
||||||
|
** a collection step.
|
||||||
|
*/
|
||||||
|
#define cantryagain(g) (completestate(g) && !g->gcstopem)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
#if defined(EMERGENCYGCTESTS)
|
||||||
|
/*
|
||||||
|
** First allocation will fail except when freeing a block (frees never
|
||||||
|
** fail) and when it cannot try again; this fail will trigger 'tryagain'
|
||||||
|
** and a full GC cycle at every allocation.
|
||||||
|
*/
|
||||||
|
static void *firsttry (global_State *g, void *block, size_t os, size_t ns) {
|
||||||
|
if (ns > 0 && cantryagain(g))
|
||||||
|
return NULL; /* fail */
|
||||||
|
else /* normal allocation */
|
||||||
|
return callfrealloc(g, block, os, ns);
|
||||||
|
}
|
||||||
|
#else
|
||||||
|
#define firsttry(g,block,os,ns) callfrealloc(g, block, os, ns)
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -149,7 +167,7 @@ l_noret luaM_toobig (lua_State *L) {
|
||||||
void luaM_free_ (lua_State *L, void *block, size_t osize) {
|
void luaM_free_ (lua_State *L, void *block, size_t osize) {
|
||||||
global_State *g = G(L);
|
global_State *g = G(L);
|
||||||
lua_assert((osize == 0) == (block == NULL));
|
lua_assert((osize == 0) == (block == NULL));
|
||||||
(*g->frealloc)(g->ud, block, osize, 0);
|
callfrealloc(g, block, osize, 0);
|
||||||
g->GCdebt -= osize;
|
g->GCdebt -= osize;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -157,20 +175,16 @@ void luaM_free_ (lua_State *L, void *block, size_t osize) {
|
||||||
/*
|
/*
|
||||||
** In case of allocation fail, this function will do an emergency
|
** In case of allocation fail, this function will do an emergency
|
||||||
** collection to free some memory and then try the allocation again.
|
** collection to free some memory and then try the allocation again.
|
||||||
** The GC should not be called while state is not fully built, as the
|
|
||||||
** collector is not yet fully initialized. Also, it should not be called
|
|
||||||
** when 'gcstopem' is true, because then the interpreter is in the
|
|
||||||
** middle of a collection step.
|
|
||||||
*/
|
*/
|
||||||
static void *tryagain (lua_State *L, void *block,
|
static void *tryagain (lua_State *L, void *block,
|
||||||
size_t osize, size_t nsize) {
|
size_t osize, size_t nsize) {
|
||||||
global_State *g = G(L);
|
global_State *g = G(L);
|
||||||
if (completestate(g) && !g->gcstopem) {
|
if (cantryagain(g)) {
|
||||||
WARNF("reacting to malloc() failure by running lua garbage collector...");
|
WARNF("reacting to malloc() failure by running lua garbage collector..."); // [jart]
|
||||||
luaC_fullgc(L, 1); /* try to free some memory... */
|
luaC_fullgc(L, 1); /* try to free some memory... */
|
||||||
return (*g->frealloc)(g->ud, block, osize, nsize); /* try again */
|
return callfrealloc(g, block, osize, nsize); /* try again */
|
||||||
}
|
}
|
||||||
else return NULL; /* cannot free any memory without a full state */
|
else return NULL; /* cannot run an emergency collection */
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
4
third_party/lua/lnotice.c
vendored
4
third_party/lua/lnotice.c
vendored
|
@ -1,3 +1,3 @@
|
||||||
__notice(lua_notice, "\
|
__notice(lua_notice, "\
|
||||||
Lua 5.4.3 (MIT License)\n\
|
Lua 5.4.6 (MIT License)\n\
|
||||||
Copyright 1994–2021 Lua.org, PUC-Rio.");
|
Copyright 1994–2023 Lua.org, PUC-Rio.");
|
||||||
|
|
20
third_party/lua/loadlib.c
vendored
20
third_party/lua/loadlib.c
vendored
|
@ -3,7 +3,7 @@
|
||||||
╚──────────────────────────────────────────────────────────────────────────────╝
|
╚──────────────────────────────────────────────────────────────────────────────╝
|
||||||
│ │
|
│ │
|
||||||
│ Lua │
|
│ Lua │
|
||||||
│ Copyright © 2004-2021 Lua.org, PUC-Rio. │
|
│ Copyright © 2004-2023 Lua.org, PUC-Rio. │
|
||||||
│ │
|
│ │
|
||||||
│ Permission is hereby granted, free of charge, to any person obtaining │
|
│ Permission is hereby granted, free of charge, to any person obtaining │
|
||||||
│ a copy of this software and associated documentation files (the │
|
│ a copy of this software and associated documentation files (the │
|
||||||
|
@ -27,6 +27,7 @@
|
||||||
╚─────────────────────────────────────────────────────────────────────────────*/
|
╚─────────────────────────────────────────────────────────────────────────────*/
|
||||||
#define loadlib_c
|
#define loadlib_c
|
||||||
#define LUA_LIB
|
#define LUA_LIB
|
||||||
|
|
||||||
#include "libc/dlopen/dlfcn.h"
|
#include "libc/dlopen/dlfcn.h"
|
||||||
#include "libc/runtime/runtime.h"
|
#include "libc/runtime/runtime.h"
|
||||||
#include "libc/str/str.h"
|
#include "libc/str/str.h"
|
||||||
|
@ -36,14 +37,16 @@
|
||||||
#include "third_party/lua/lualib.h"
|
#include "third_party/lua/lualib.h"
|
||||||
__static_yoink("lua_notice");
|
__static_yoink("lua_notice");
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
** This module contains an implementation of loadlib for Unix systems
|
**
|
||||||
|
** [jart] This module contains an implementation of loadlib for Unix systems
|
||||||
** that have dlfcn, an implementation for Windows, and a stub for other
|
** that have dlfcn, an implementation for Windows, and a stub for other
|
||||||
** systems.
|
** systems.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
|
||||||
const char *g_lua_path_default = LUA_PATH_DEFAULT;
|
const char *g_lua_path_default = LUA_PATH_DEFAULT; // [jart]
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -728,8 +731,13 @@ static const luaL_Reg ll_funcs[] = {
|
||||||
|
|
||||||
|
|
||||||
static void createsearcherstable (lua_State *L) {
|
static void createsearcherstable (lua_State *L) {
|
||||||
static const lua_CFunction searchers[] =
|
static const lua_CFunction searchers[] = {
|
||||||
{searcher_preload, searcher_Lua, searcher_C, searcher_Croot, NULL};
|
searcher_preload,
|
||||||
|
searcher_Lua,
|
||||||
|
searcher_C,
|
||||||
|
searcher_Croot,
|
||||||
|
NULL
|
||||||
|
};
|
||||||
int i;
|
int i;
|
||||||
/* create 'searchers' table */
|
/* create 'searchers' table */
|
||||||
lua_createtable(L, sizeof(searchers)/sizeof(searchers[0]) - 1, 0);
|
lua_createtable(L, sizeof(searchers)/sizeof(searchers[0]) - 1, 0);
|
||||||
|
@ -757,7 +765,7 @@ static void createclibstable (lua_State *L) {
|
||||||
|
|
||||||
|
|
||||||
static const char *GetLuaPathDefault(void) {
|
static const char *GetLuaPathDefault(void) {
|
||||||
return g_lua_path_default;
|
return g_lua_path_default; // [jart]
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
61
third_party/lua/lobject.c
vendored
61
third_party/lua/lobject.c
vendored
|
@ -3,7 +3,7 @@
|
||||||
╚──────────────────────────────────────────────────────────────────────────────╝
|
╚──────────────────────────────────────────────────────────────────────────────╝
|
||||||
│ │
|
│ │
|
||||||
│ Lua │
|
│ Lua │
|
||||||
│ Copyright © 2004-2021 Lua.org, PUC-Rio. │
|
│ Copyright © 2004-2023 Lua.org, PUC-Rio. │
|
||||||
│ │
|
│ │
|
||||||
│ Permission is hereby granted, free of charge, to any person obtaining │
|
│ Permission is hereby granted, free of charge, to any person obtaining │
|
||||||
│ a copy of this software and associated documentation files (the │
|
│ a copy of this software and associated documentation files (the │
|
||||||
|
@ -27,6 +27,7 @@
|
||||||
╚─────────────────────────────────────────────────────────────────────────────*/
|
╚─────────────────────────────────────────────────────────────────────────────*/
|
||||||
#define lobject_c
|
#define lobject_c
|
||||||
#define LUA_CORE
|
#define LUA_CORE
|
||||||
|
|
||||||
#include "libc/str/str.h"
|
#include "libc/str/str.h"
|
||||||
#include "third_party/lua/lctype.h"
|
#include "third_party/lua/lctype.h"
|
||||||
#include "third_party/lua/ldebug.h"
|
#include "third_party/lua/ldebug.h"
|
||||||
|
@ -41,6 +42,12 @@
|
||||||
__static_yoink("lua_notice");
|
__static_yoink("lua_notice");
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
** Computes ceil(log2(x))
|
||||||
|
*/
|
||||||
|
// [jart] moved to lobject.h
|
||||||
|
|
||||||
|
|
||||||
static lua_Integer intarith (lua_State *L, int op, lua_Integer v1,
|
static lua_Integer intarith (lua_State *L, int op, lua_Integer v1,
|
||||||
lua_Integer v2) {
|
lua_Integer v2) {
|
||||||
switch (op) {
|
switch (op) {
|
||||||
|
@ -53,7 +60,7 @@ static lua_Integer intarith (lua_State *L, int op, lua_Integer v1,
|
||||||
case LUA_OPBOR: return intop(|, v1, v2);
|
case LUA_OPBOR: return intop(|, v1, v2);
|
||||||
case LUA_OPBXOR: return intop(^, v1, v2);
|
case LUA_OPBXOR: return intop(^, v1, v2);
|
||||||
case LUA_OPSHL: return luaV_shiftl(v1, v2);
|
case LUA_OPSHL: return luaV_shiftl(v1, v2);
|
||||||
case LUA_OPSHR: return luaV_shiftl(v1, -v2);
|
case LUA_OPSHR: return luaV_shiftr(v1, v2);
|
||||||
case LUA_OPUNM: return intop(-, 0, v1);
|
case LUA_OPUNM: return intop(-, 0, v1);
|
||||||
case LUA_OPBNOT: return intop(^, ~l_castS2U(0), v1);
|
case LUA_OPBNOT: return intop(^, ~l_castS2U(0), v1);
|
||||||
default: lua_assert(0); return 0;
|
default: lua_assert(0); return 0;
|
||||||
|
@ -155,7 +162,7 @@ static int isneg (const char **s) {
|
||||||
*/
|
*/
|
||||||
static lua_Number lua_strx2number (const char *s, char **endptr) {
|
static lua_Number lua_strx2number (const char *s, char **endptr) {
|
||||||
int dot = lua_getlocaledecpoint();
|
int dot = lua_getlocaledecpoint();
|
||||||
lua_Number r = 0.0; /* result (accumulator) */
|
lua_Number r = l_mathop(0.0); /* result (accumulator) */
|
||||||
int sigdig = 0; /* number of significant digits */
|
int sigdig = 0; /* number of significant digits */
|
||||||
int nosigdig = 0; /* number of non-significant digits */
|
int nosigdig = 0; /* number of non-significant digits */
|
||||||
int e = 0; /* exponent correction */
|
int e = 0; /* exponent correction */
|
||||||
|
@ -165,7 +172,7 @@ static lua_Number lua_strx2number (const char *s, char **endptr) {
|
||||||
while (lisspace(cast_uchar(*s))) s++; /* skip initial spaces */
|
while (lisspace(cast_uchar(*s))) s++; /* skip initial spaces */
|
||||||
neg = isneg(&s); /* check sign */
|
neg = isneg(&s); /* check sign */
|
||||||
if (!(*s == '0' && (*(s + 1) == 'x' || *(s + 1) == 'X'))) /* check '0x' */
|
if (!(*s == '0' && (*(s + 1) == 'x' || *(s + 1) == 'X'))) /* check '0x' */
|
||||||
return 0.0; /* invalid format (no '0x') */
|
return l_mathop(0.0); /* invalid format (no '0x') */
|
||||||
for (s += 2; ; s++) { /* skip '0x' and read numeral */
|
for (s += 2; ; s++) { /* skip '0x' and read numeral */
|
||||||
if (*s == dot) {
|
if (*s == dot) {
|
||||||
if (hasdot) break; /* second dot? stop loop */
|
if (hasdot) break; /* second dot? stop loop */
|
||||||
|
@ -175,14 +182,14 @@ static lua_Number lua_strx2number (const char *s, char **endptr) {
|
||||||
if (sigdig == 0 && *s == '0') /* non-significant digit (zero)? */
|
if (sigdig == 0 && *s == '0') /* non-significant digit (zero)? */
|
||||||
nosigdig++;
|
nosigdig++;
|
||||||
else if (++sigdig <= MAXSIGDIG) /* can read it without overflow? */
|
else if (++sigdig <= MAXSIGDIG) /* can read it without overflow? */
|
||||||
r = (r * cast_num(16.0)) + luaO_hexavalue(*s);
|
r = (r * l_mathop(16.0)) + luaO_hexavalue(*s);
|
||||||
else e++; /* too many digits; ignore, but still count for exponent */
|
else e++; /* too many digits; ignore, but still count for exponent */
|
||||||
if (hasdot) e--; /* decimal digit? correct exponent */
|
if (hasdot) e--; /* decimal digit? correct exponent */
|
||||||
}
|
}
|
||||||
else break; /* neither a dot nor a digit */
|
else break; /* neither a dot nor a digit */
|
||||||
}
|
}
|
||||||
if (nosigdig + sigdig == 0) /* no digits? */
|
if (nosigdig + sigdig == 0) /* no digits? */
|
||||||
return 0.0; /* invalid format */
|
return l_mathop(0.0); /* invalid format */
|
||||||
*endptr = cast_charp(s); /* valid up to here */
|
*endptr = cast_charp(s); /* valid up to here */
|
||||||
e *= 4; /* each digit multiplies/divides value by 2^4 */
|
e *= 4; /* each digit multiplies/divides value by 2^4 */
|
||||||
if (*s == 'p' || *s == 'P') { /* exponent part? */
|
if (*s == 'p' || *s == 'P') { /* exponent part? */
|
||||||
|
@ -191,7 +198,7 @@ static lua_Number lua_strx2number (const char *s, char **endptr) {
|
||||||
s++; /* skip 'p' */
|
s++; /* skip 'p' */
|
||||||
neg1 = isneg(&s); /* sign */
|
neg1 = isneg(&s); /* sign */
|
||||||
if (!lisdigit(cast_uchar(*s)))
|
if (!lisdigit(cast_uchar(*s)))
|
||||||
return 0.0; /* invalid; must have at least one digit */
|
return l_mathop(0.0); /* invalid; must have at least one digit */
|
||||||
while (lisdigit(cast_uchar(*s))) /* read exponent */
|
while (lisdigit(cast_uchar(*s))) /* read exponent */
|
||||||
exp1 = exp1 * 10 + *(s++) - '0';
|
exp1 = exp1 * 10 + *(s++) - '0';
|
||||||
if (neg1) exp1 = -exp1;
|
if (neg1) exp1 = -exp1;
|
||||||
|
@ -262,9 +269,9 @@ static const char *l_str2d (const char *s, lua_Number *result) {
|
||||||
|
|
||||||
|
|
||||||
#define MAXBY10 cast(lua_Unsigned, LUA_MAXINTEGER / 10)
|
#define MAXBY10 cast(lua_Unsigned, LUA_MAXINTEGER / 10)
|
||||||
#define MAXBY8 cast(lua_Unsigned, LUA_MAXINTEGER / 8)
|
#define MAXBY8 cast(lua_Unsigned, LUA_MAXINTEGER / 8) // [jart]
|
||||||
#define MAXLASTD cast_int(LUA_MAXINTEGER % 10)
|
#define MAXLASTD cast_int(LUA_MAXINTEGER % 10)
|
||||||
#define MAXLASTD8 cast_int(LUA_MAXINTEGER % 8)
|
#define MAXLASTD8 cast_int(LUA_MAXINTEGER % 8) // [jart]
|
||||||
|
|
||||||
static const char *l_str2int (const char *s, lua_Integer *result) {
|
static const char *l_str2int (const char *s, lua_Integer *result) {
|
||||||
lua_Unsigned a = 0;
|
lua_Unsigned a = 0;
|
||||||
|
@ -396,29 +403,39 @@ void luaO_tostring (lua_State *L, TValue *obj) {
|
||||||
** ===================================================================
|
** ===================================================================
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/* size for buffer space used by 'luaO_pushvfstring' */
|
/*
|
||||||
#define BUFVFS 200
|
** Size for buffer space used by 'luaO_pushvfstring'. It should be
|
||||||
|
** (LUA_IDSIZE + MAXNUMBER2STR) + a minimal space for basic messages,
|
||||||
|
** so that 'luaG_addinfo' can work directly on the buffer.
|
||||||
|
*/
|
||||||
|
#define BUFVFS (LUA_IDSIZE + MAXNUMBER2STR + 95)
|
||||||
|
|
||||||
/* buffer used by 'luaO_pushvfstring' */
|
/* buffer used by 'luaO_pushvfstring' */
|
||||||
typedef struct BuffFS {
|
typedef struct BuffFS {
|
||||||
lua_State *L;
|
lua_State *L;
|
||||||
int pushed; /* number of string pieces already on the stack */
|
int pushed; /* true if there is a part of the result on the stack */
|
||||||
int blen; /* length of partial string in 'space' */
|
int blen; /* length of partial string in 'space' */
|
||||||
char space[BUFVFS]; /* holds last part of the result */
|
char space[BUFVFS]; /* holds last part of the result */
|
||||||
} BuffFS;
|
} BuffFS;
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
** Push given string to the stack, as part of the buffer, and
|
** Push given string to the stack, as part of the result, and
|
||||||
** join the partial strings in the stack into one.
|
** join it to previous partial result if there is one.
|
||||||
|
** It may call 'luaV_concat' while using one slot from EXTRA_STACK.
|
||||||
|
** This call cannot invoke metamethods, as both operands must be
|
||||||
|
** strings. It can, however, raise an error if the result is too
|
||||||
|
** long. In that case, 'luaV_concat' frees the extra slot before
|
||||||
|
** raising the error.
|
||||||
*/
|
*/
|
||||||
static void pushstr (BuffFS *buff, const char *str, size_t l) {
|
static void pushstr (BuffFS *buff, const char *str, size_t lstr) {
|
||||||
lua_State *L = buff->L;
|
lua_State *L = buff->L;
|
||||||
setsvalue2s(L, L->top, luaS_newlstr(L, str, l));
|
setsvalue2s(L, L->top.p, luaS_newlstr(L, str, lstr));
|
||||||
L->top++; /* may use one extra slot */
|
L->top.p++; /* may use one slot from EXTRA_STACK */
|
||||||
buff->pushed++;
|
if (!buff->pushed) /* no previous string on the stack? */
|
||||||
luaV_concat(L, buff->pushed); /* join partial results into one */
|
buff->pushed = 1; /* now there is one */
|
||||||
buff->pushed = 1;
|
else /* join previous string with new one */
|
||||||
|
luaV_concat(L, 2);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -464,7 +481,7 @@ static void addstr2buff (BuffFS *buff, const char *str, size_t slen) {
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
** Add a number to the buffer.
|
** Add a numeral to the buffer.
|
||||||
*/
|
*/
|
||||||
static void addnum2buff (BuffFS *buff, TValue *num) {
|
static void addnum2buff (BuffFS *buff, TValue *num) {
|
||||||
char *numbuff = getbuff(buff, MAXNUMBER2STR);
|
char *numbuff = getbuff(buff, MAXNUMBER2STR);
|
||||||
|
@ -542,7 +559,7 @@ const char *luaO_pushvfstring (lua_State *L, const char *fmt, va_list argp) {
|
||||||
addstr2buff(&buff, fmt, strlen(fmt)); /* rest of 'fmt' */
|
addstr2buff(&buff, fmt, strlen(fmt)); /* rest of 'fmt' */
|
||||||
clearbuff(&buff); /* empty buffer into the stack */
|
clearbuff(&buff); /* empty buffer into the stack */
|
||||||
lua_assert(buff.pushed == 1);
|
lua_assert(buff.pushed == 1);
|
||||||
return svalue(s2v(L->top - 1));
|
return svalue(s2v(L->top.p - 1));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
28
third_party/lua/lobject.h
vendored
28
third_party/lua/lobject.h
vendored
|
@ -13,11 +13,14 @@
|
||||||
#define LUA_TPROTO (LUA_NUMTYPES + 1) /* function prototypes */
|
#define LUA_TPROTO (LUA_NUMTYPES + 1) /* function prototypes */
|
||||||
#define LUA_TDEADKEY (LUA_NUMTYPES + 2) /* removed keys in tables */
|
#define LUA_TDEADKEY (LUA_NUMTYPES + 2) /* removed keys in tables */
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
** number of all possible types (including LUA_TNONE but excluding DEADKEY)
|
** number of all possible types (including LUA_TNONE but excluding DEADKEY)
|
||||||
*/
|
*/
|
||||||
#define LUA_TOTALTYPES (LUA_TPROTO + 2)
|
#define LUA_TOTALTYPES (LUA_TPROTO + 2)
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
** tags for Tagged Values have the following use of bits:
|
** tags for Tagged Values have the following use of bits:
|
||||||
** bits 0-3: actual tag (a LUA_T* constant)
|
** bits 0-3: actual tag (a LUA_T* constant)
|
||||||
|
@ -39,6 +42,8 @@ typedef union Value {
|
||||||
lua_CFunction f; /* light C functions */
|
lua_CFunction f; /* light C functions */
|
||||||
lua_Integer i; /* integer numbers */
|
lua_Integer i; /* integer numbers */
|
||||||
lua_Number n; /* float numbers */
|
lua_Number n; /* float numbers */
|
||||||
|
/* not used, but may avoid warnings for uninitialized value */
|
||||||
|
lu_byte ub;
|
||||||
} Value;
|
} Value;
|
||||||
|
|
||||||
|
|
||||||
|
@ -55,7 +60,7 @@ typedef struct TValue {
|
||||||
|
|
||||||
|
|
||||||
#define val_(o) ((o)->value_)
|
#define val_(o) ((o)->value_)
|
||||||
#define valraw(o) (&val_(o))
|
#define valraw(o) (val_(o))
|
||||||
|
|
||||||
|
|
||||||
/* raw type tag of a TValue */
|
/* raw type tag of a TValue */
|
||||||
|
@ -99,7 +104,7 @@ typedef struct TValue {
|
||||||
#define settt_(o,t) ((o)->tt_=(t))
|
#define settt_(o,t) ((o)->tt_=(t))
|
||||||
|
|
||||||
|
|
||||||
/* main macro to copy values (from 'obj1' to 'obj2') */
|
/* main macro to copy values (from 'obj2' to 'obj1') */
|
||||||
#define setobj(L,obj1,obj2) \
|
#define setobj(L,obj1,obj2) \
|
||||||
{ TValue *io1=(obj1); const TValue *io2=(obj2); \
|
{ TValue *io1=(obj1); const TValue *io2=(obj2); \
|
||||||
io1->value_ = io2->value_; settt_(io1, io2->tt_); \
|
io1->value_ = io2->value_; settt_(io1, io2->tt_); \
|
||||||
|
@ -142,6 +147,17 @@ typedef union StackValue {
|
||||||
/* index to stack elements */
|
/* index to stack elements */
|
||||||
typedef StackValue *StkId;
|
typedef StackValue *StkId;
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
** When reallocating the stack, change all pointers to the stack into
|
||||||
|
** proper offsets.
|
||||||
|
*/
|
||||||
|
typedef union {
|
||||||
|
StkId p; /* actual pointer */
|
||||||
|
ptrdiff_t offset; /* used while the stack is being reallocated */
|
||||||
|
} StkIdRel;
|
||||||
|
|
||||||
|
|
||||||
/* convert a 'StackValue' to a 'TValue' */
|
/* convert a 'StackValue' to a 'TValue' */
|
||||||
#define s2v(o) (&(o)->val)
|
#define s2v(o) (&(o)->val)
|
||||||
|
|
||||||
|
@ -602,8 +618,10 @@ typedef struct Proto {
|
||||||
*/
|
*/
|
||||||
typedef struct UpVal {
|
typedef struct UpVal {
|
||||||
CommonHeader;
|
CommonHeader;
|
||||||
lu_byte tbc; /* true if it represents a to-be-closed variable */
|
union {
|
||||||
TValue *v; /* points to stack or to its own value */
|
TValue *p; /* points to stack or to its own value */
|
||||||
|
ptrdiff_t offset; /* used while the stack is being reallocated */
|
||||||
|
} v;
|
||||||
union {
|
union {
|
||||||
struct { /* (when open) */
|
struct { /* (when open) */
|
||||||
struct UpVal *next; /* linked list */
|
struct UpVal *next; /* linked list */
|
||||||
|
@ -785,7 +803,7 @@ LUAI_FUNC void luaO_chunkid (char *out, const char *source, size_t srclen);
|
||||||
** Computes ceil(log2(x))
|
** Computes ceil(log2(x))
|
||||||
*/
|
*/
|
||||||
static inline int luaO_ceillog2 (unsigned int x) {
|
static inline int luaO_ceillog2 (unsigned int x) {
|
||||||
return --x ? bsr(x) + 1 : 0;
|
return --x ? _bsr(x) + 1 : 0; // [jart]
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
3
third_party/lua/lopcodes.c
vendored
3
third_party/lua/lopcodes.c
vendored
|
@ -3,7 +3,7 @@
|
||||||
╚──────────────────────────────────────────────────────────────────────────────╝
|
╚──────────────────────────────────────────────────────────────────────────────╝
|
||||||
│ │
|
│ │
|
||||||
│ Lua │
|
│ Lua │
|
||||||
│ Copyright © 2004-2021 Lua.org, PUC-Rio. │
|
│ Copyright © 2004-2023 Lua.org, PUC-Rio. │
|
||||||
│ │
|
│ │
|
||||||
│ Permission is hereby granted, free of charge, to any person obtaining │
|
│ Permission is hereby granted, free of charge, to any person obtaining │
|
||||||
│ a copy of this software and associated documentation files (the │
|
│ a copy of this software and associated documentation files (the │
|
||||||
|
@ -27,6 +27,7 @@
|
||||||
╚─────────────────────────────────────────────────────────────────────────────*/
|
╚─────────────────────────────────────────────────────────────────────────────*/
|
||||||
#define lopcodes_c
|
#define lopcodes_c
|
||||||
#define LUA_CORE
|
#define LUA_CORE
|
||||||
|
|
||||||
#include "third_party/lua/lopcodes.h"
|
#include "third_party/lua/lopcodes.h"
|
||||||
#include "third_party/lua/lprefix.h"
|
#include "third_party/lua/lprefix.h"
|
||||||
__static_yoink("lua_notice");
|
__static_yoink("lua_notice");
|
||||||
|
|
23
third_party/lua/lopcodes.h
vendored
23
third_party/lua/lopcodes.h
vendored
|
@ -15,7 +15,7 @@ iABC C(8) | B(8) |k| A(8) | Op(7) |
|
||||||
iABx Bx(17) | A(8) | Op(7) |
|
iABx Bx(17) | A(8) | Op(7) |
|
||||||
iAsBx sBx (signed)(17) | A(8) | Op(7) |
|
iAsBx sBx (signed)(17) | A(8) | Op(7) |
|
||||||
iAx Ax(25) | Op(7) |
|
iAx Ax(25) | Op(7) |
|
||||||
isJ sJ(25) | Op(7) |
|
isJ sJ (signed)(25) | Op(7) |
|
||||||
|
|
||||||
A signed argument is represented in excess K: the represented value is
|
A signed argument is represented in excess K: the represented value is
|
||||||
the written unsigned value minus K, where K is half the maximum for the
|
the written unsigned value minus K, where K is half the maximum for the
|
||||||
|
@ -184,7 +184,8 @@ enum OpMode {iABC, iABx, iAsBx, iAx, isJ}; /* basic instruction formats */
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
** grep "ORDER OP" if you change these enums
|
** Grep "ORDER OP" if you change these enums. Opcodes marked with a (*)
|
||||||
|
** has extra descriptions in the notes after the enumeration.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
typedef enum {
|
typedef enum {
|
||||||
|
@ -197,7 +198,7 @@ OP_LOADF,/* A sBx R[A] := (lua_Number)sBx */
|
||||||
OP_LOADK,/* A Bx R[A] := K[Bx] */
|
OP_LOADK,/* A Bx R[A] := K[Bx] */
|
||||||
OP_LOADKX,/* A R[A] := K[extra arg] */
|
OP_LOADKX,/* A R[A] := K[extra arg] */
|
||||||
OP_LOADFALSE,/* A R[A] := false */
|
OP_LOADFALSE,/* A R[A] := false */
|
||||||
OP_LFALSESKIP,/*A R[A] := false; pc++ */
|
OP_LFALSESKIP,/*A R[A] := false; pc++ (*) */
|
||||||
OP_LOADTRUE,/* A R[A] := true */
|
OP_LOADTRUE,/* A R[A] := true */
|
||||||
OP_LOADNIL,/* A B R[A], R[A+1], ..., R[A+B] := nil */
|
OP_LOADNIL,/* A B R[A], R[A+1], ..., R[A+B] := nil */
|
||||||
OP_GETUPVAL,/* A B R[A] := UpValue[B] */
|
OP_GETUPVAL,/* A B R[A] := UpValue[B] */
|
||||||
|
@ -248,7 +249,7 @@ OP_BXOR,/* A B C R[A] := R[B] ~ R[C] */
|
||||||
OP_SHL,/* A B C R[A] := R[B] << R[C] */
|
OP_SHL,/* A B C R[A] := R[B] << R[C] */
|
||||||
OP_SHR,/* A B C R[A] := R[B] >> R[C] */
|
OP_SHR,/* A B C R[A] := R[B] >> R[C] */
|
||||||
|
|
||||||
OP_MMBIN,/* A B C call C metamethod over R[A] and R[B] */
|
OP_MMBIN,/* A B C call C metamethod over R[A] and R[B] (*) */
|
||||||
OP_MMBINI,/* A sB C k call C metamethod over R[A] and sB */
|
OP_MMBINI,/* A sB C k call C metamethod over R[A] and sB */
|
||||||
OP_MMBINK,/* A B C k call C metamethod over R[A] and K[B] */
|
OP_MMBINK,/* A B C k call C metamethod over R[A] and K[B] */
|
||||||
|
|
||||||
|
@ -274,7 +275,7 @@ OP_GTI,/* A sB k if ((R[A] > sB) ~= k) then pc++ */
|
||||||
OP_GEI,/* A sB k if ((R[A] >= sB) ~= k) then pc++ */
|
OP_GEI,/* A sB k if ((R[A] >= sB) ~= k) then pc++ */
|
||||||
|
|
||||||
OP_TEST,/* A k if (not R[A] == k) then pc++ */
|
OP_TEST,/* A k if (not R[A] == k) then pc++ */
|
||||||
OP_TESTSET,/* A B k if (not R[B] == k) then pc++ else R[A] := R[B] */
|
OP_TESTSET,/* A B k if (not R[B] == k) then pc++ else R[A] := R[B] (*) */
|
||||||
|
|
||||||
OP_CALL,/* A B C R[A], ... ,R[A+C-2] := R[A](R[A+1], ... ,R[A+B-1]) */
|
OP_CALL,/* A B C R[A], ... ,R[A+C-2] := R[A](R[A+1], ... ,R[A+B-1]) */
|
||||||
OP_TAILCALL,/* A B C k return R[A](R[A+1], ... ,R[A+B-1]) */
|
OP_TAILCALL,/* A B C k return R[A](R[A+1], ... ,R[A+B-1]) */
|
||||||
|
@ -309,6 +310,18 @@ OP_EXTRAARG/* Ax extra (larger) argument for previous opcode */
|
||||||
|
|
||||||
/*===========================================================================
|
/*===========================================================================
|
||||||
Notes:
|
Notes:
|
||||||
|
|
||||||
|
(*) Opcode OP_LFALSESKIP is used to convert a condition to a boolean
|
||||||
|
value, in a code equivalent to (not cond ? false : true). (It
|
||||||
|
produces false and skips the next instruction producing true.)
|
||||||
|
|
||||||
|
(*) Opcodes OP_MMBIN and variants follow each arithmetic and
|
||||||
|
bitwise opcode. If the operation succeeds, it skips this next
|
||||||
|
opcode. Otherwise, this opcode calls the corresponding metamethod.
|
||||||
|
|
||||||
|
(*) Opcode OP_TESTSET is used in short-circuit expressions that need
|
||||||
|
both to jump and to produce a value, such as (a = b or c).
|
||||||
|
|
||||||
(*) In OP_CALL, if (B == 0) then B = top - A. If (C == 0), then
|
(*) In OP_CALL, if (B == 0) then B = top - A. If (C == 0), then
|
||||||
'top' is set to last_result+1, so next open instruction (OP_CALL,
|
'top' is set to last_result+1, so next open instruction (OP_CALL,
|
||||||
OP_RETURN*, OP_SETLIST) may use 'top'.
|
OP_RETURN*, OP_SETLIST) may use 'top'.
|
||||||
|
|
9
third_party/lua/lopnames.inc
vendored
9
third_party/lua/lopnames.inc
vendored
|
@ -1,14 +1,7 @@
|
||||||
/*
|
#ifndef lopnames_h
|
||||||
** $Id: lopnames.h $
|
|
||||||
** Opcode names
|
|
||||||
** See Copyright Notice in lua.h
|
|
||||||
*/
|
|
||||||
|
|
||||||
#if !defined(lopnames_h)
|
|
||||||
#define lopnames_h
|
#define lopnames_h
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/* ORDER OP */
|
/* ORDER OP */
|
||||||
|
|
||||||
static const char *const opnames[] = {
|
static const char *const opnames[] = {
|
||||||
|
|
40
third_party/lua/loslib.c
vendored
40
third_party/lua/loslib.c
vendored
|
@ -3,7 +3,7 @@
|
||||||
╚──────────────────────────────────────────────────────────────────────────────╝
|
╚──────────────────────────────────────────────────────────────────────────────╝
|
||||||
│ │
|
│ │
|
||||||
│ Lua │
|
│ Lua │
|
||||||
│ Copyright © 2004-2021 Lua.org, PUC-Rio. │
|
│ Copyright © 2004-2023 Lua.org, PUC-Rio. │
|
||||||
│ │
|
│ │
|
||||||
│ Permission is hereby granted, free of charge, to any person obtaining │
|
│ Permission is hereby granted, free of charge, to any person obtaining │
|
||||||
│ a copy of this software and associated documentation files (the │
|
│ a copy of this software and associated documentation files (the │
|
||||||
|
@ -27,6 +27,7 @@
|
||||||
╚─────────────────────────────────────────────────────────────────────────────*/
|
╚─────────────────────────────────────────────────────────────────────────────*/
|
||||||
#define loslib_c
|
#define loslib_c
|
||||||
#define LUA_LIB
|
#define LUA_LIB
|
||||||
|
|
||||||
#include "libc/calls/calls.h"
|
#include "libc/calls/calls.h"
|
||||||
#include "libc/calls/weirdtypes.h"
|
#include "libc/calls/weirdtypes.h"
|
||||||
#include "libc/errno.h"
|
#include "libc/errno.h"
|
||||||
|
@ -51,23 +52,14 @@ __static_yoink("lua_notice");
|
||||||
*/
|
*/
|
||||||
#if !defined(LUA_STRFTIMEOPTIONS) /* { */
|
#if !defined(LUA_STRFTIMEOPTIONS) /* { */
|
||||||
|
|
||||||
/* options for ANSI C 89 (only 1-char options) */
|
|
||||||
#define L_STRFTIMEC89 "aAbBcdHIjmMpSUwWxXyYZ%"
|
|
||||||
|
|
||||||
/* options for ISO C 99 and POSIX */
|
|
||||||
#define L_STRFTIMEC99 "aAbBcCdDeFgGhHIjmMnprRStTuUVwWxXyYzZ%" \
|
|
||||||
"||" "EcECExEXEyEY" "OdOeOHOIOmOMOSOuOUOVOwOWOy" /* two-char options */
|
|
||||||
|
|
||||||
/* options for Windows */
|
|
||||||
#define L_STRFTIMEWIN "aAbBcdHIjmMpSUwWxXyYzZ%" \
|
|
||||||
"||" "#c#x#d#H#I#j#m#M#S#U#w#W#y#Y" /* two-char options */
|
|
||||||
|
|
||||||
#if defined(LUA_USE_WINDOWS)
|
#if defined(LUA_USE_WINDOWS)
|
||||||
#define LUA_STRFTIMEOPTIONS L_STRFTIMEWIN
|
#define LUA_STRFTIMEOPTIONS "aAbBcdHIjmMpSUwWxXyYzZ%" \
|
||||||
#elif defined(LUA_USE_C89)
|
"||" "#c#x#d#H#I#j#m#M#S#U#w#W#y#Y" /* two-char options */
|
||||||
#define LUA_STRFTIMEOPTIONS L_STRFTIMEC89
|
#elif defined(LUA_USE_C89) /* ANSI C 89 (only 1-char options) */
|
||||||
|
#define LUA_STRFTIMEOPTIONS "aAbBcdHIjmMpSUwWxXyYZ%"
|
||||||
#else /* C99 specification */
|
#else /* C99 specification */
|
||||||
#define LUA_STRFTIMEOPTIONS L_STRFTIMEC99
|
#define LUA_STRFTIMEOPTIONS "aAbBcCdDeFgGhHIjmMnprRStTuUVwWxXyYzZ%" \
|
||||||
|
"||" "EcECExEXEyEY" "OdOeOHOIOmOMOSOuOUOVOwOWOy" /* two-char options */
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#endif /* } */
|
#endif /* } */
|
||||||
|
@ -135,6 +127,7 @@ __static_yoink("lua_notice");
|
||||||
|
|
||||||
#define LUA_TMPNAMBUFSIZE 128
|
#define LUA_TMPNAMBUFSIZE 128
|
||||||
|
|
||||||
|
// [jart]
|
||||||
#define lua_tmpnam(b,e) { \
|
#define lua_tmpnam(b,e) { \
|
||||||
strlcpy(b, __get_tmpdir(), LUA_TMPNAMBUFSIZE); \
|
strlcpy(b, __get_tmpdir(), LUA_TMPNAMBUFSIZE); \
|
||||||
e = strlcat(b, "lua_XXXXXX", LUA_TMPNAMBUFSIZE) >= LUA_TMPNAMBUFSIZE; \
|
e = strlcat(b, "lua_XXXXXX", LUA_TMPNAMBUFSIZE) >= LUA_TMPNAMBUFSIZE; \
|
||||||
|
@ -154,12 +147,21 @@ __static_yoink("lua_notice");
|
||||||
/* }================================================================== */
|
/* }================================================================== */
|
||||||
|
|
||||||
|
|
||||||
|
#if !defined(l_system)
|
||||||
|
#if defined(LUA_USE_IOS)
|
||||||
|
/* Despite claiming to be ISO C, iOS does not implement 'system'. */
|
||||||
|
#define l_system(cmd) ((cmd) == NULL ? 0 : -1)
|
||||||
|
#else
|
||||||
|
#define l_system(cmd) system(cmd) /* default definition */
|
||||||
|
#endif
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
static int os_execute (lua_State *L) {
|
static int os_execute (lua_State *L) {
|
||||||
const char *cmd = luaL_optstring(L, 1, NULL);
|
const char *cmd = luaL_optstring(L, 1, NULL);
|
||||||
int stat;
|
int stat;
|
||||||
errno = 0;
|
errno = 0;
|
||||||
stat = system(cmd);
|
stat = l_system(cmd);
|
||||||
if (cmd != NULL)
|
if (cmd != NULL)
|
||||||
return luaL_execresult(L, stat);
|
return luaL_execresult(L, stat);
|
||||||
else {
|
else {
|
||||||
|
@ -276,9 +278,7 @@ static int getfield (lua_State *L, const char *key, int d, int delta) {
|
||||||
res = d;
|
res = d;
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
/* unsigned avoids overflow when lua_Integer has 32 bits */
|
if (!(res >= 0 ? res - delta <= INT_MAX : INT_MIN + delta <= res))
|
||||||
if (!(res >= 0 ? (lua_Unsigned)res <= (lua_Unsigned)INT_MAX + delta
|
|
||||||
: (lua_Integer)INT_MIN + delta <= res))
|
|
||||||
return luaL_error(L, "field '%s' is out-of-bound", key);
|
return luaL_error(L, "field '%s' is out-of-bound", key);
|
||||||
res -= delta;
|
res -= delta;
|
||||||
}
|
}
|
||||||
|
|
56
third_party/lua/lparser.c
vendored
56
third_party/lua/lparser.c
vendored
|
@ -3,7 +3,7 @@
|
||||||
╚──────────────────────────────────────────────────────────────────────────────╝
|
╚──────────────────────────────────────────────────────────────────────────────╝
|
||||||
│ │
|
│ │
|
||||||
│ Lua │
|
│ Lua │
|
||||||
│ Copyright © 2004-2021 Lua.org, PUC-Rio. │
|
│ Copyright © 2004-2023 Lua.org, PUC-Rio. │
|
||||||
│ │
|
│ │
|
||||||
│ Permission is hereby granted, free of charge, to any person obtaining │
|
│ Permission is hereby granted, free of charge, to any person obtaining │
|
||||||
│ a copy of this software and associated documentation files (the │
|
│ a copy of this software and associated documentation files (the │
|
||||||
|
@ -27,6 +27,7 @@
|
||||||
╚─────────────────────────────────────────────────────────────────────────────*/
|
╚─────────────────────────────────────────────────────────────────────────────*/
|
||||||
#define lparser_c
|
#define lparser_c
|
||||||
#define LUA_CORE
|
#define LUA_CORE
|
||||||
|
|
||||||
#include "libc/str/str.h"
|
#include "libc/str/str.h"
|
||||||
#include "third_party/lua/lcode.h"
|
#include "third_party/lua/lcode.h"
|
||||||
#include "third_party/lua/ldebug.h"
|
#include "third_party/lua/ldebug.h"
|
||||||
|
@ -431,6 +432,17 @@ static void markupval (FuncState *fs, int level) {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
** Mark that current block has a to-be-closed variable.
|
||||||
|
*/
|
||||||
|
static void marktobeclosed (FuncState *fs) {
|
||||||
|
BlockCnt *bl = fs->bl;
|
||||||
|
bl->upval = 1;
|
||||||
|
bl->insidetbc = 1;
|
||||||
|
fs->needclose = 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
** Find a variable with the given name 'n'. If it is an upvalue, add
|
** Find a variable with the given name 'n'. If it is an upvalue, add
|
||||||
** this upvalue into all intermediate functions. If it is a global, set
|
** this upvalue into all intermediate functions. If it is a global, set
|
||||||
|
@ -472,6 +484,7 @@ static void singlevar (LexState *ls, expdesc *var) {
|
||||||
expdesc key;
|
expdesc key;
|
||||||
singlevaraux(fs, ls->envn, var, 1); /* get environment variable */
|
singlevaraux(fs, ls->envn, var, 1); /* get environment variable */
|
||||||
lua_assert(var->k != VVOID); /* this one must exist */
|
lua_assert(var->k != VVOID); /* this one must exist */
|
||||||
|
luaK_exp2anyregup(fs, var); /* but could be a constant */
|
||||||
codestring(&key, varname); /* key is variable name */
|
codestring(&key, varname); /* key is variable name */
|
||||||
luaK_indexed(fs, var, &key); /* env[varname] */
|
luaK_indexed(fs, var, &key); /* env[varname] */
|
||||||
}
|
}
|
||||||
|
@ -524,12 +537,12 @@ static l_noret jumpscopeerror (LexState *ls, Labeldesc *gt) {
|
||||||
|
|
||||||
/*
|
/*
|
||||||
** Solves the goto at index 'g' to given 'label' and removes it
|
** Solves the goto at index 'g' to given 'label' and removes it
|
||||||
** from the list of pending goto's.
|
** from the list of pending gotos.
|
||||||
** If it jumps into the scope of some variable, raises an error.
|
** If it jumps into the scope of some variable, raises an error.
|
||||||
*/
|
*/
|
||||||
static void solvegoto (LexState *ls, int g, Labeldesc *label) {
|
static void solvegoto (LexState *ls, int g, Labeldesc *label) {
|
||||||
int i;
|
int i;
|
||||||
Labellist *gl = &ls->dyd->gt; /* list of goto's */
|
Labellist *gl = &ls->dyd->gt; /* list of gotos */
|
||||||
Labeldesc *gt = &gl->arr[g]; /* goto to be resolved */
|
Labeldesc *gt = &gl->arr[g]; /* goto to be resolved */
|
||||||
lua_assert(eqstr(gt->name, label->name));
|
lua_assert(eqstr(gt->name, label->name));
|
||||||
if (l_unlikely(gt->nactvar < label->nactvar)) /* enter some scope? */
|
if (l_unlikely(gt->nactvar < label->nactvar)) /* enter some scope? */
|
||||||
|
@ -583,7 +596,7 @@ static int newgotoentry (LexState *ls, TString *name, int line, int pc) {
|
||||||
/*
|
/*
|
||||||
** Solves forward jumps. Check whether new label 'lb' matches any
|
** Solves forward jumps. Check whether new label 'lb' matches any
|
||||||
** pending gotos in current block and solves them. Return true
|
** pending gotos in current block and solves them. Return true
|
||||||
** if any of the goto's need to close upvalues.
|
** if any of the gotos need to close upvalues.
|
||||||
*/
|
*/
|
||||||
static int solvegotos (LexState *ls, Labeldesc *lb) {
|
static int solvegotos (LexState *ls, Labeldesc *lb) {
|
||||||
Labellist *gl = &ls->dyd->gt;
|
Labellist *gl = &ls->dyd->gt;
|
||||||
|
@ -604,7 +617,7 @@ static int solvegotos (LexState *ls, Labeldesc *lb) {
|
||||||
/*
|
/*
|
||||||
** Create a new label with the given 'name' at the given 'line'.
|
** Create a new label with the given 'name' at the given 'line'.
|
||||||
** 'last' tells whether label is the last non-op statement in its
|
** 'last' tells whether label is the last non-op statement in its
|
||||||
** block. Solves all pending goto's to this new label and adds
|
** block. Solves all pending gotos to this new label and adds
|
||||||
** a close instruction if necessary.
|
** a close instruction if necessary.
|
||||||
** Returns true iff it added a close instruction.
|
** Returns true iff it added a close instruction.
|
||||||
*/
|
*/
|
||||||
|
@ -677,19 +690,19 @@ static void leaveblock (FuncState *fs) {
|
||||||
LexState *ls = fs->ls;
|
LexState *ls = fs->ls;
|
||||||
int hasclose = 0;
|
int hasclose = 0;
|
||||||
int stklevel = reglevel(fs, bl->nactvar); /* level outside the block */
|
int stklevel = reglevel(fs, bl->nactvar); /* level outside the block */
|
||||||
if (bl->isloop) /* fix pending breaks? */
|
removevars(fs, bl->nactvar); /* remove block locals */
|
||||||
|
lua_assert(bl->nactvar == fs->nactvar); /* back to level on entry */
|
||||||
|
if (bl->isloop) /* has to fix pending breaks? */
|
||||||
hasclose = createlabel(ls, luaS_newliteral(ls->L, "break"), 0, 0);
|
hasclose = createlabel(ls, luaS_newliteral(ls->L, "break"), 0, 0);
|
||||||
if (!hasclose && bl->previous && bl->upval)
|
if (!hasclose && bl->previous && bl->upval) /* still need a 'close'? */
|
||||||
luaK_codeABC(fs, OP_CLOSE, stklevel, 0, 0);
|
luaK_codeABC(fs, OP_CLOSE, stklevel, 0, 0);
|
||||||
fs->bl = bl->previous;
|
|
||||||
removevars(fs, bl->nactvar);
|
|
||||||
lua_assert(bl->nactvar == fs->nactvar);
|
|
||||||
fs->freereg = stklevel; /* free registers */
|
fs->freereg = stklevel; /* free registers */
|
||||||
ls->dyd->label.n = bl->firstlabel; /* remove local labels */
|
ls->dyd->label.n = bl->firstlabel; /* remove local labels */
|
||||||
if (bl->previous) /* inner block? */
|
fs->bl = bl->previous; /* current block now is previous one */
|
||||||
movegotosout(fs, bl); /* update pending gotos to outer block */
|
if (bl->previous) /* was it a nested block? */
|
||||||
|
movegotosout(fs, bl); /* update pending gotos to enclosing block */
|
||||||
else {
|
else {
|
||||||
if (bl->firstgoto < ls->dyd->gt.n) /* pending gotos in outer block? */
|
if (bl->firstgoto < ls->dyd->gt.n) /* still pending gotos? */
|
||||||
undefgoto(ls, &ls->dyd->gt.arr[bl->firstgoto]); /* error */
|
undefgoto(ls, &ls->dyd->gt.arr[bl->firstgoto]); /* error */
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1614,7 +1627,7 @@ static void forlist (LexState *ls, TString *indexname) {
|
||||||
line = ls->linenumber;
|
line = ls->linenumber;
|
||||||
adjust_assign(ls, 4, explist(ls, &e), &e);
|
adjust_assign(ls, 4, explist(ls, &e), &e);
|
||||||
adjustlocalvars(ls, 4); /* control variables */
|
adjustlocalvars(ls, 4); /* control variables */
|
||||||
markupval(fs, fs->nactvar); /* last control var. must be closed */
|
marktobeclosed(fs); /* last control var. must be closed */
|
||||||
luaK_checkstack(fs, 3); /* extra space to call generator */
|
luaK_checkstack(fs, 3); /* extra space to call generator */
|
||||||
forbody(ls, base, line, nvars - 4, 1);
|
forbody(ls, base, line, nvars - 4, 1);
|
||||||
}
|
}
|
||||||
|
@ -1718,11 +1731,9 @@ static int getlocalattribute (LexState *ls) {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static void checktoclose (LexState *ls, int level) {
|
static void checktoclose (FuncState *fs, int level) {
|
||||||
if (level != -1) { /* is there a to-be-closed variable? */
|
if (level != -1) { /* is there a to-be-closed variable? */
|
||||||
FuncState *fs = ls->fs;
|
marktobeclosed(fs);
|
||||||
markupval(fs, level + 1);
|
|
||||||
fs->bl->insidetbc = 1; /* in the scope of a to-be-closed variable */
|
|
||||||
luaK_codeABC(fs, OP_TBC, reglevel(fs, level), 0, 0);
|
luaK_codeABC(fs, OP_TBC, reglevel(fs, level), 0, 0);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1766,7 +1777,7 @@ static void localstat (LexState *ls) {
|
||||||
adjust_assign(ls, nvars, nexps, &e);
|
adjust_assign(ls, nvars, nexps, &e);
|
||||||
adjustlocalvars(ls, nvars);
|
adjustlocalvars(ls, nvars);
|
||||||
}
|
}
|
||||||
checktoclose(ls, toclose);
|
checktoclose(fs, toclose);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -1791,6 +1802,7 @@ static void funcstat (LexState *ls, int line) {
|
||||||
luaX_next(ls); /* skip FUNCTION */
|
luaX_next(ls); /* skip FUNCTION */
|
||||||
ismethod = funcname(ls, &v);
|
ismethod = funcname(ls, &v);
|
||||||
body(ls, &b, ismethod, line);
|
body(ls, &b, ismethod, line);
|
||||||
|
check_readonly(ls, &v);
|
||||||
luaK_storevar(ls->fs, &v, &b);
|
luaK_storevar(ls->fs, &v, &b);
|
||||||
luaK_fixline(ls->fs, line); /* definition "happens" in the first line */
|
luaK_fixline(ls->fs, line); /* definition "happens" in the first line */
|
||||||
}
|
}
|
||||||
|
@ -1948,10 +1960,10 @@ LClosure *luaY_parser (lua_State *L, ZIO *z, Mbuffer *buff,
|
||||||
LexState lexstate;
|
LexState lexstate;
|
||||||
FuncState funcstate;
|
FuncState funcstate;
|
||||||
LClosure *cl = luaF_newLclosure(L, 1); /* create main closure */
|
LClosure *cl = luaF_newLclosure(L, 1); /* create main closure */
|
||||||
setclLvalue2s(L, L->top, cl); /* anchor it (to avoid being collected) */
|
setclLvalue2s(L, L->top.p, cl); /* anchor it (to avoid being collected) */
|
||||||
luaD_inctop(L);
|
luaD_inctop(L);
|
||||||
lexstate.h = luaH_new(L); /* create table for scanner */
|
lexstate.h = luaH_new(L); /* create table for scanner */
|
||||||
sethvalue2s(L, L->top, lexstate.h); /* anchor it */
|
sethvalue2s(L, L->top.p, lexstate.h); /* anchor it */
|
||||||
luaD_inctop(L);
|
luaD_inctop(L);
|
||||||
funcstate.f = cl->p = luaF_newproto(L);
|
funcstate.f = cl->p = luaF_newproto(L);
|
||||||
luaC_objbarrier(L, cl, cl->p);
|
luaC_objbarrier(L, cl, cl->p);
|
||||||
|
@ -1965,7 +1977,7 @@ LClosure *luaY_parser (lua_State *L, ZIO *z, Mbuffer *buff,
|
||||||
lua_assert(!funcstate.prev && funcstate.nups == 1 && !lexstate.fs);
|
lua_assert(!funcstate.prev && funcstate.nups == 1 && !lexstate.fs);
|
||||||
/* all scopes should be correctly finished */
|
/* all scopes should be correctly finished */
|
||||||
lua_assert(dyd->actvar.n == 0 && dyd->gt.n == 0 && dyd->label.n == 0);
|
lua_assert(dyd->actvar.n == 0 && dyd->gt.n == 0 && dyd->label.n == 0);
|
||||||
L->top--; /* remove scanner's table */
|
L->top.p--; /* remove scanner's table */
|
||||||
return cl; /* closure is on the stack, too */
|
return cl; /* closure is on the stack, too */
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
2
third_party/lua/lprefix.h
vendored
2
third_party/lua/lprefix.h
vendored
|
@ -1,6 +1,7 @@
|
||||||
#ifndef lprefix_h
|
#ifndef lprefix_h
|
||||||
#define lprefix_h
|
#define lprefix_h
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
** Allows POSIX/XSI stuff
|
** Allows POSIX/XSI stuff
|
||||||
*/
|
*/
|
||||||
|
@ -22,6 +23,7 @@
|
||||||
|
|
||||||
#endif /* } */
|
#endif /* } */
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
** Windows stuff
|
** Windows stuff
|
||||||
*/
|
*/
|
||||||
|
|
2
third_party/lua/lrepl.c
vendored
2
third_party/lua/lrepl.c
vendored
|
@ -3,7 +3,7 @@
|
||||||
╚──────────────────────────────────────────────────────────────────────────────╝
|
╚──────────────────────────────────────────────────────────────────────────────╝
|
||||||
│ │
|
│ │
|
||||||
│ Lua │
|
│ Lua │
|
||||||
│ Copyright © 2004-2021 Lua.org, PUC-Rio. │
|
│ Copyright © 2004-2023 Lua.org, PUC-Rio. │
|
||||||
│ │
|
│ │
|
||||||
│ Permission is hereby granted, free of charge, to any person obtaining │
|
│ Permission is hereby granted, free of charge, to any person obtaining │
|
||||||
│ a copy of this software and associated documentation files (the │
|
│ a copy of this software and associated documentation files (the │
|
||||||
|
|
79
third_party/lua/lstate.c
vendored
79
third_party/lua/lstate.c
vendored
|
@ -3,7 +3,7 @@
|
||||||
╚──────────────────────────────────────────────────────────────────────────────╝
|
╚──────────────────────────────────────────────────────────────────────────────╝
|
||||||
│ │
|
│ │
|
||||||
│ Lua │
|
│ Lua │
|
||||||
│ Copyright © 2004-2021 Lua.org, PUC-Rio. │
|
│ Copyright © 2004-2023 Lua.org, PUC-Rio. │
|
||||||
│ │
|
│ │
|
||||||
│ Permission is hereby granted, free of charge, to any person obtaining │
|
│ Permission is hereby granted, free of charge, to any person obtaining │
|
||||||
│ a copy of this software and associated documentation files (the │
|
│ a copy of this software and associated documentation files (the │
|
||||||
|
@ -27,6 +27,7 @@
|
||||||
╚─────────────────────────────────────────────────────────────────────────────*/
|
╚─────────────────────────────────────────────────────────────────────────────*/
|
||||||
#define lstate_c
|
#define lstate_c
|
||||||
#define LUA_CORE
|
#define LUA_CORE
|
||||||
|
|
||||||
#include "libc/str/str.h"
|
#include "libc/str/str.h"
|
||||||
#include "libc/time.h"
|
#include "libc/time.h"
|
||||||
#include "third_party/lua/lapi.h"
|
#include "third_party/lua/lapi.h"
|
||||||
|
@ -180,7 +181,7 @@ void luaE_checkcstack (lua_State *L) {
|
||||||
if (getCcalls(L) == LUAI_MAXCCALLS)
|
if (getCcalls(L) == LUAI_MAXCCALLS)
|
||||||
luaG_runerror(L, "C stack overflow");
|
luaG_runerror(L, "C stack overflow");
|
||||||
else if (getCcalls(L) >= (LUAI_MAXCCALLS / 10 * 11))
|
else if (getCcalls(L) >= (LUAI_MAXCCALLS / 10 * 11))
|
||||||
luaD_throw(L, LUA_ERRERR); /* error while handing stack error */
|
luaD_throw(L, LUA_ERRERR); /* error while handling stack error */
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -194,33 +195,33 @@ LUAI_FUNC void luaE_incCstack (lua_State *L) {
|
||||||
static void stack_init (lua_State *L1, lua_State *L) {
|
static void stack_init (lua_State *L1, lua_State *L) {
|
||||||
int i; CallInfo *ci;
|
int i; CallInfo *ci;
|
||||||
/* initialize stack array */
|
/* initialize stack array */
|
||||||
L1->stack = luaM_newvector(L, BASIC_STACK_SIZE + EXTRA_STACK, StackValue);
|
L1->stack.p = luaM_newvector(L, BASIC_STACK_SIZE + EXTRA_STACK, StackValue);
|
||||||
L1->tbclist = L1->stack;
|
L1->tbclist.p = L1->stack.p;
|
||||||
for (i = 0; i < BASIC_STACK_SIZE + EXTRA_STACK; i++)
|
for (i = 0; i < BASIC_STACK_SIZE + EXTRA_STACK; i++)
|
||||||
setnilvalue(s2v(L1->stack + i)); /* erase new stack */
|
setnilvalue(s2v(L1->stack.p + i)); /* erase new stack */
|
||||||
L1->top = L1->stack;
|
L1->top.p = L1->stack.p;
|
||||||
L1->stack_last = L1->stack + BASIC_STACK_SIZE;
|
L1->stack_last.p = L1->stack.p + BASIC_STACK_SIZE;
|
||||||
/* initialize first ci */
|
/* initialize first ci */
|
||||||
ci = &L1->base_ci;
|
ci = &L1->base_ci;
|
||||||
ci->next = ci->previous = NULL;
|
ci->next = ci->previous = NULL;
|
||||||
ci->callstatus = CIST_C;
|
ci->callstatus = CIST_C;
|
||||||
ci->func = L1->top;
|
ci->func.p = L1->top.p;
|
||||||
ci->u.c.k = NULL;
|
ci->u.c.k = NULL;
|
||||||
ci->nresults = 0;
|
ci->nresults = 0;
|
||||||
setnilvalue(s2v(L1->top)); /* 'function' entry for this 'ci' */
|
setnilvalue(s2v(L1->top.p)); /* 'function' entry for this 'ci' */
|
||||||
L1->top++;
|
L1->top.p++;
|
||||||
ci->top = L1->top + LUA_MINSTACK;
|
ci->top.p = L1->top.p + LUA_MINSTACK;
|
||||||
L1->ci = ci;
|
L1->ci = ci;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static void freestack (lua_State *L) {
|
static void freestack (lua_State *L) {
|
||||||
if (L->stack == NULL)
|
if (L->stack.p == NULL)
|
||||||
return; /* stack not completely built yet */
|
return; /* stack not completely built yet */
|
||||||
L->ci = &L->base_ci; /* free the entire 'ci' list */
|
L->ci = &L->base_ci; /* free the entire 'ci' list */
|
||||||
luaE_freeCI(L);
|
luaE_freeCI(L);
|
||||||
lua_assert(L->nci == 0);
|
lua_assert(L->nci == 0);
|
||||||
luaM_freearray(L, L->stack, stacksize(L) + EXTRA_STACK); /* free stack */
|
luaM_freearray(L, L->stack.p, stacksize(L) + EXTRA_STACK); /* free stack */
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -250,7 +251,7 @@ static void f_luaopen (lua_State *L, void *ud) {
|
||||||
luaS_init(L);
|
luaS_init(L);
|
||||||
luaT_init(L);
|
luaT_init(L);
|
||||||
luaX_init(L);
|
luaX_init(L);
|
||||||
g->gcrunning = 1; /* allow gc */
|
g->gcstp = 0; /* allow gc */
|
||||||
setnilvalue(&g->nilvalue); /* now state is complete */
|
setnilvalue(&g->nilvalue); /* now state is complete */
|
||||||
luai_userstateopen(L);
|
luai_userstateopen(L);
|
||||||
}
|
}
|
||||||
|
@ -262,7 +263,7 @@ static void f_luaopen (lua_State *L, void *ud) {
|
||||||
*/
|
*/
|
||||||
static void preinit_thread (lua_State *L, global_State *g) {
|
static void preinit_thread (lua_State *L, global_State *g) {
|
||||||
G(L) = g;
|
G(L) = g;
|
||||||
L->stack = NULL;
|
L->stack.p = NULL;
|
||||||
L->ci = NULL;
|
L->ci = NULL;
|
||||||
L->nci = 0;
|
L->nci = 0;
|
||||||
L->twups = L; /* thread has no upvalues */
|
L->twups = L; /* thread has no upvalues */
|
||||||
|
@ -283,8 +284,9 @@ static void preinit_thread (lua_State *L, global_State *g) {
|
||||||
static void close_state (lua_State *L) {
|
static void close_state (lua_State *L) {
|
||||||
global_State *g = G(L);
|
global_State *g = G(L);
|
||||||
if (!completestate(g)) /* closing a partially built state? */
|
if (!completestate(g)) /* closing a partially built state? */
|
||||||
luaC_freeallobjects(L); /* jucst collect its objects */
|
luaC_freeallobjects(L); /* just collect its objects */
|
||||||
else { /* closing a fully built state */
|
else { /* closing a fully built state */
|
||||||
|
L->ci = &L->base_ci; /* unwind CallInfo list */
|
||||||
luaD_closeprotected(L, 1, LUA_OK); /* close all upvalues */
|
luaD_closeprotected(L, 1, LUA_OK); /* close all upvalues */
|
||||||
luaC_freeallobjects(L); /* collect all objects */
|
luaC_freeallobjects(L); /* collect all objects */
|
||||||
luai_userstateclose(L);
|
luai_userstateclose(L);
|
||||||
|
@ -307,20 +309,16 @@ static void close_state (lua_State *L) {
|
||||||
* Threads are subject to garbage collection, like any Lua object.
|
* Threads are subject to garbage collection, like any Lua object.
|
||||||
*/
|
*/
|
||||||
LUA_API lua_State *lua_newthread (lua_State *L) {
|
LUA_API lua_State *lua_newthread (lua_State *L) {
|
||||||
global_State *g;
|
global_State *g = G(L);
|
||||||
|
GCObject *o;
|
||||||
lua_State *L1;
|
lua_State *L1;
|
||||||
lua_lock(L);
|
lua_lock(L);
|
||||||
g = G(L);
|
|
||||||
luaC_checkGC(L);
|
luaC_checkGC(L);
|
||||||
/* create new thread */
|
/* create new thread */
|
||||||
L1 = &cast(LX *, luaM_newobject(L, LUA_TTHREAD, sizeof(LX)))->l;
|
o = luaC_newobjdt(L, LUA_TTHREAD, sizeof(LX), offsetof(LX, l));
|
||||||
L1->marked = luaC_white(g);
|
L1 = gco2th(o);
|
||||||
L1->tt = LUA_VTHREAD;
|
|
||||||
/* link it on list 'allgc' */
|
|
||||||
L1->next = g->allgc;
|
|
||||||
g->allgc = obj2gco(L1);
|
|
||||||
/* anchor it on L stack */
|
/* anchor it on L stack */
|
||||||
setthvalue2s(L, L->top, L1);
|
setthvalue2s(L, L->top.p, L1);
|
||||||
api_incr_top(L);
|
api_incr_top(L);
|
||||||
preinit_thread(L1, g);
|
preinit_thread(L1, g);
|
||||||
L1->hookmask = L->hookmask;
|
L1->hookmask = L->hookmask;
|
||||||
|
@ -339,7 +337,7 @@ LUA_API lua_State *lua_newthread (lua_State *L) {
|
||||||
|
|
||||||
void luaE_freethread (lua_State *L, lua_State *L1) {
|
void luaE_freethread (lua_State *L, lua_State *L1) {
|
||||||
LX *l = fromstate(L1);
|
LX *l = fromstate(L1);
|
||||||
luaF_closeupval(L1, L1->stack); /* close all upvalues */
|
luaF_closeupval(L1, L1->stack.p); /* close all upvalues */
|
||||||
lua_assert(L1->openupval == NULL);
|
lua_assert(L1->openupval == NULL);
|
||||||
luai_userstatefree(L, L1);
|
luai_userstatefree(L, L1);
|
||||||
freestack(L1);
|
freestack(L1);
|
||||||
|
@ -349,32 +347,41 @@ void luaE_freethread (lua_State *L, lua_State *L1) {
|
||||||
|
|
||||||
int luaE_resetthread (lua_State *L, int status) {
|
int luaE_resetthread (lua_State *L, int status) {
|
||||||
CallInfo *ci = L->ci = &L->base_ci; /* unwind CallInfo list */
|
CallInfo *ci = L->ci = &L->base_ci; /* unwind CallInfo list */
|
||||||
setnilvalue(s2v(L->stack)); /* 'function' entry for basic 'ci' */
|
setnilvalue(s2v(L->stack.p)); /* 'function' entry for basic 'ci' */
|
||||||
ci->func = L->stack;
|
ci->func.p = L->stack.p;
|
||||||
ci->callstatus = CIST_C;
|
ci->callstatus = CIST_C;
|
||||||
if (status == LUA_YIELD)
|
if (status == LUA_YIELD)
|
||||||
status = LUA_OK;
|
status = LUA_OK;
|
||||||
|
L->status = LUA_OK; /* so it can run __close metamethods */
|
||||||
status = luaD_closeprotected(L, 1, status);
|
status = luaD_closeprotected(L, 1, status);
|
||||||
if (status != LUA_OK) /* errors? */
|
if (status != LUA_OK) /* errors? */
|
||||||
luaD_seterrorobj(L, status, L->stack + 1);
|
luaD_seterrorobj(L, status, L->stack.p + 1);
|
||||||
else
|
else
|
||||||
L->top = L->stack + 1;
|
L->top.p = L->stack.p + 1;
|
||||||
ci->top = L->top + LUA_MINSTACK;
|
ci->top.p = L->top.p + LUA_MINSTACK;
|
||||||
L->status = cast_byte(status);
|
luaD_reallocstack(L, cast_int(ci->top.p - L->stack.p), 0);
|
||||||
luaD_reallocstack(L, cast_int(ci->top - L->stack), 0);
|
|
||||||
return status;
|
return status;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
LUA_API int lua_resetthread (lua_State *L) {
|
LUA_API int lua_closethread (lua_State *L, lua_State *from) {
|
||||||
int status;
|
int status;
|
||||||
lua_lock(L);
|
lua_lock(L);
|
||||||
|
L->nCcalls = (from) ? getCcalls(from) : 0;
|
||||||
status = luaE_resetthread(L, L->status);
|
status = luaE_resetthread(L, L->status);
|
||||||
lua_unlock(L);
|
lua_unlock(L);
|
||||||
return status;
|
return status;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
** Deprecated! Use 'lua_closethread' instead.
|
||||||
|
*/
|
||||||
|
LUA_API int lua_resetthread (lua_State *L) {
|
||||||
|
return lua_closethread(L, NULL);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
LUA_API lua_State *lua_newstate (lua_Alloc f, void *ud) {
|
LUA_API lua_State *lua_newstate (lua_Alloc f, void *ud) {
|
||||||
int i;
|
int i;
|
||||||
lua_State *L;
|
lua_State *L;
|
||||||
|
@ -396,7 +403,7 @@ LUA_API lua_State *lua_newstate (lua_Alloc f, void *ud) {
|
||||||
g->ud_warn = NULL;
|
g->ud_warn = NULL;
|
||||||
g->mainthread = L;
|
g->mainthread = L;
|
||||||
g->seed = luai_makeseed(L);
|
g->seed = luai_makeseed(L);
|
||||||
g->gcrunning = 0; /* no GC while building state */
|
g->gcstp = GCSTPGC; /* no GC while building state */
|
||||||
g->strt.size = g->strt.nuse = 0;
|
g->strt.size = g->strt.nuse = 0;
|
||||||
g->strt.hash = NULL;
|
g->strt.hash = NULL;
|
||||||
setnilvalue(&g->l_registry);
|
setnilvalue(&g->l_registry);
|
||||||
|
@ -449,7 +456,7 @@ void luaE_warning (lua_State *L, const char *msg, int tocont) {
|
||||||
** Generate a warning from an error message
|
** Generate a warning from an error message
|
||||||
*/
|
*/
|
||||||
void luaE_warnerror (lua_State *L, const char *where) {
|
void luaE_warnerror (lua_State *L, const char *where) {
|
||||||
TValue *errobj = s2v(L->top - 1); /* error object */
|
TValue *errobj = s2v(L->top.p - 1); /* error object */
|
||||||
const char *msg = (ttisstring(errobj))
|
const char *msg = (ttisstring(errobj))
|
||||||
? svalue(errobj)
|
? svalue(errobj)
|
||||||
: "error object is not a string";
|
: "error object is not a string";
|
||||||
|
|
29
third_party/lua/lstate.h
vendored
29
third_party/lua/lstate.h
vendored
|
@ -1,6 +1,9 @@
|
||||||
#ifndef lstate_h
|
#ifndef lstate_h
|
||||||
#define lstate_h
|
#define lstate_h
|
||||||
|
|
||||||
|
/* Some header files included here need this definition */
|
||||||
|
typedef struct CallInfo CallInfo;
|
||||||
|
|
||||||
#include "libc/calls/calls.h"
|
#include "libc/calls/calls.h"
|
||||||
#include "third_party/lua/lobject.h"
|
#include "third_party/lua/lobject.h"
|
||||||
#include "third_party/lua/lua.h"
|
#include "third_party/lua/lua.h"
|
||||||
|
@ -132,7 +135,7 @@ struct lua_longjmp; /* defined in ldo.c */
|
||||||
|
|
||||||
#define BASIC_STACK_SIZE (2*LUA_MINSTACK)
|
#define BASIC_STACK_SIZE (2*LUA_MINSTACK)
|
||||||
|
|
||||||
#define stacksize(th) cast_int((th)->stack_last - (th)->stack)
|
#define stacksize(th) cast_int((th)->stack_last.p - (th)->stack.p)
|
||||||
|
|
||||||
|
|
||||||
/* kinds of Garbage Collection */
|
/* kinds of Garbage Collection */
|
||||||
|
@ -158,13 +161,13 @@ typedef struct stringtable {
|
||||||
** - field 'nyield' is used only while a function is "doing" an
|
** - field 'nyield' is used only while a function is "doing" an
|
||||||
** yield (from the yield until the next resume);
|
** yield (from the yield until the next resume);
|
||||||
** - field 'nres' is used only while closing tbc variables when
|
** - field 'nres' is used only while closing tbc variables when
|
||||||
** returning from a C function;
|
** returning from a function;
|
||||||
** - field 'transferinfo' is used only during call/returnhooks,
|
** - field 'transferinfo' is used only during call/returnhooks,
|
||||||
** before the function starts or after it ends.
|
** before the function starts or after it ends.
|
||||||
*/
|
*/
|
||||||
typedef struct CallInfo {
|
struct CallInfo {
|
||||||
StkId func; /* function index in the stack */
|
StkIdRel func; /* function index in the stack */
|
||||||
StkId top; /* top for this function */
|
StkIdRel top; /* top for this function */
|
||||||
struct CallInfo *previous, *next; /* dynamic call link */
|
struct CallInfo *previous, *next; /* dynamic call link */
|
||||||
union {
|
union {
|
||||||
struct { /* only for Lua functions */
|
struct { /* only for Lua functions */
|
||||||
|
@ -189,7 +192,7 @@ typedef struct CallInfo {
|
||||||
} u2;
|
} u2;
|
||||||
short nresults; /* expected number of results from this function */
|
short nresults; /* expected number of results from this function */
|
||||||
unsigned short callstatus;
|
unsigned short callstatus;
|
||||||
} CallInfo;
|
};
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -202,7 +205,7 @@ typedef struct CallInfo {
|
||||||
#define CIST_YPCALL (1<<4) /* doing a yieldable protected call */
|
#define CIST_YPCALL (1<<4) /* doing a yieldable protected call */
|
||||||
#define CIST_TAIL (1<<5) /* call was tail called */
|
#define CIST_TAIL (1<<5) /* call was tail called */
|
||||||
#define CIST_HOOKYIELD (1<<6) /* last hook called yielded */
|
#define CIST_HOOKYIELD (1<<6) /* last hook called yielded */
|
||||||
#define CIST_FIN (1<<7) /* call is running a finalizer */
|
#define CIST_FIN (1<<7) /* function "called" a finalizer */
|
||||||
#define CIST_TRAN (1<<8) /* 'ci' has transfer information */
|
#define CIST_TRAN (1<<8) /* 'ci' has transfer information */
|
||||||
#define CIST_CLSRET (1<<9) /* function is closing tbc variables */
|
#define CIST_CLSRET (1<<9) /* function is closing tbc variables */
|
||||||
/* Bits 10-12 are used for CIST_RECST (see below) */
|
/* Bits 10-12 are used for CIST_RECST (see below) */
|
||||||
|
@ -256,7 +259,7 @@ typedef struct global_State {
|
||||||
lu_byte gcstopem; /* stops emergency collections */
|
lu_byte gcstopem; /* stops emergency collections */
|
||||||
lu_byte genminormul; /* control for minor generational collections */
|
lu_byte genminormul; /* control for minor generational collections */
|
||||||
lu_byte genmajormul; /* control for major generational collections */
|
lu_byte genmajormul; /* control for major generational collections */
|
||||||
lu_byte gcrunning; /* true if GC is running */
|
lu_byte gcstp; /* control whether GC is running */
|
||||||
lu_byte gcemergency; /* true if this is an emergency collection */
|
lu_byte gcemergency; /* true if this is an emergency collection */
|
||||||
lu_byte gcpause; /* size of pause between successive GCs */
|
lu_byte gcpause; /* size of pause between successive GCs */
|
||||||
lu_byte gcstepmul; /* GC "speed" */
|
lu_byte gcstepmul; /* GC "speed" */
|
||||||
|
@ -284,7 +287,7 @@ typedef struct global_State {
|
||||||
struct lua_State *mainthread;
|
struct lua_State *mainthread;
|
||||||
TString *memerrmsg; /* message for memory-allocation errors */
|
TString *memerrmsg; /* message for memory-allocation errors */
|
||||||
TString *tmname[TM_N]; /* array with tag-method names */
|
TString *tmname[TM_N]; /* array with tag-method names */
|
||||||
struct Table *mt[LUA_NUMTAGS]; /* metatables for basic types */
|
struct Table *mt[LUA_NUMTYPES]; /* metatables for basic types */
|
||||||
TString *strcache[STRCACHE_N][STRCACHE_M]; /* cache for strings in API */
|
TString *strcache[STRCACHE_N][STRCACHE_M]; /* cache for strings in API */
|
||||||
lua_WarnFunction warnf; /* warning function */
|
lua_WarnFunction warnf; /* warning function */
|
||||||
void *ud_warn; /* auxiliary data to 'warnf' */
|
void *ud_warn; /* auxiliary data to 'warnf' */
|
||||||
|
@ -299,13 +302,13 @@ struct lua_State {
|
||||||
lu_byte status;
|
lu_byte status;
|
||||||
lu_byte allowhook;
|
lu_byte allowhook;
|
||||||
unsigned short nci; /* number of items in 'ci' list */
|
unsigned short nci; /* number of items in 'ci' list */
|
||||||
StkId top; /* first free slot in the stack */
|
StkIdRel top; /* first free slot in the stack */
|
||||||
global_State *l_G;
|
global_State *l_G;
|
||||||
CallInfo *ci; /* call info for current function */
|
CallInfo *ci; /* call info for current function */
|
||||||
StkId stack_last; /* end of stack (last element + 1) */
|
StkIdRel stack_last; /* end of stack (last element + 1) */
|
||||||
StkId stack; /* stack base */
|
StkIdRel stack; /* stack base */
|
||||||
UpVal *openupval; /* list of open upvalues in this stack */
|
UpVal *openupval; /* list of open upvalues in this stack */
|
||||||
StkId tbclist; /* list of to-be-closed variables */
|
StkIdRel tbclist; /* list of to-be-closed variables */
|
||||||
GCObject *gclist;
|
GCObject *gclist;
|
||||||
struct lua_State *twups; /* list of threads with open upvalues */
|
struct lua_State *twups; /* list of threads with open upvalues */
|
||||||
struct lua_longjmp *errorJmp; /* current error recover point */
|
struct lua_longjmp *errorJmp; /* current error recover point */
|
||||||
|
|
3
third_party/lua/lstring.c
vendored
3
third_party/lua/lstring.c
vendored
|
@ -3,7 +3,7 @@
|
||||||
╚──────────────────────────────────────────────────────────────────────────────╝
|
╚──────────────────────────────────────────────────────────────────────────────╝
|
||||||
│ │
|
│ │
|
||||||
│ Lua │
|
│ Lua │
|
||||||
│ Copyright © 2004-2021 Lua.org, PUC-Rio. │
|
│ Copyright © 2004-2023 Lua.org, PUC-Rio. │
|
||||||
│ │
|
│ │
|
||||||
│ Permission is hereby granted, free of charge, to any person obtaining │
|
│ Permission is hereby granted, free of charge, to any person obtaining │
|
||||||
│ a copy of this software and associated documentation files (the │
|
│ a copy of this software and associated documentation files (the │
|
||||||
|
@ -27,6 +27,7 @@
|
||||||
╚─────────────────────────────────────────────────────────────────────────────*/
|
╚─────────────────────────────────────────────────────────────────────────────*/
|
||||||
#define lstring_c
|
#define lstring_c
|
||||||
#define LUA_CORE
|
#define LUA_CORE
|
||||||
|
|
||||||
#include "libc/str/str.h"
|
#include "libc/str/str.h"
|
||||||
#include "third_party/lua/ldebug.h"
|
#include "third_party/lua/ldebug.h"
|
||||||
#include "third_party/lua/ldo.h"
|
#include "third_party/lua/ldo.h"
|
||||||
|
|
136
third_party/lua/lstrlib.c
vendored
136
third_party/lua/lstrlib.c
vendored
|
@ -3,7 +3,7 @@
|
||||||
╚──────────────────────────────────────────────────────────────────────────────╝
|
╚──────────────────────────────────────────────────────────────────────────────╝
|
||||||
│ │
|
│ │
|
||||||
│ Lua │
|
│ Lua │
|
||||||
│ Copyright © 2004-2021 Lua.org, PUC-Rio. │
|
│ Copyright © 2004-2023 Lua.org, PUC-Rio. │
|
||||||
│ │
|
│ │
|
||||||
│ Permission is hereby granted, free of charge, to any person obtaining │
|
│ Permission is hereby granted, free of charge, to any person obtaining │
|
||||||
│ a copy of this software and associated documentation files (the │
|
│ a copy of this software and associated documentation files (the │
|
||||||
|
@ -27,6 +27,7 @@
|
||||||
╚─────────────────────────────────────────────────────────────────────────────*/
|
╚─────────────────────────────────────────────────────────────────────────────*/
|
||||||
#define lstrlib_c
|
#define lstrlib_c
|
||||||
#define LUA_LIB
|
#define LUA_LIB
|
||||||
|
|
||||||
#include "libc/math.h"
|
#include "libc/math.h"
|
||||||
#include "libc/str/str.h"
|
#include "libc/str/str.h"
|
||||||
#include "third_party/lua/cosmo.h"
|
#include "third_party/lua/cosmo.h"
|
||||||
|
@ -62,7 +63,7 @@ __static_yoink("lua_notice");
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
static int str_format(lua_State *);
|
static int str_format(lua_State *); // [jart]
|
||||||
|
|
||||||
|
|
||||||
static int str_len (lua_State *L) {
|
static int str_len (lua_State *L) {
|
||||||
|
@ -607,7 +608,7 @@ static const char *match_capture (MatchState *ms, const char *s, int l) {
|
||||||
static const char *match (MatchState *ms, const char *s, const char *p) {
|
static const char *match (MatchState *ms, const char *s, const char *p) {
|
||||||
if (l_unlikely(ms->matchdepth-- == 0))
|
if (l_unlikely(ms->matchdepth-- == 0))
|
||||||
luaL_error(ms->L, "pattern too complex");
|
luaL_error(ms->L, "pattern too complex");
|
||||||
init: /* using goto's to optimize tail recursion */
|
init: /* using goto to optimize tail recursion */
|
||||||
if (p != ms->p_end) { /* end of pattern? */
|
if (p != ms->p_end) { /* end of pattern? */
|
||||||
switch (*p) {
|
switch (*p) {
|
||||||
case '(': { /* start capture */
|
case '(': { /* start capture */
|
||||||
|
@ -1127,13 +1128,31 @@ static int lua_number2strx (lua_State *L, char *buff, int sz,
|
||||||
|
|
||||||
|
|
||||||
/* valid flags in a format specification */
|
/* valid flags in a format specification */
|
||||||
#if !defined(L_FMTFLAGS)
|
#if !defined(L_FMTFLAGSF)
|
||||||
#define L_FMTFLAGS "-+ #0"
|
|
||||||
|
/* valid flags for a, A, e, E, f, F, g, and G conversions */
|
||||||
|
#define L_FMTFLAGSF "-+#0 "
|
||||||
|
|
||||||
|
/* valid flags for o, x, and X conversions */
|
||||||
|
#define L_FMTFLAGSX "-#0"
|
||||||
|
|
||||||
|
/* valid flags for d and i conversions */
|
||||||
|
#define L_FMTFLAGSI "-+0 "
|
||||||
|
|
||||||
|
/* valid flags for u conversions */
|
||||||
|
#define L_FMTFLAGSU "-0"
|
||||||
|
|
||||||
|
/* valid flags for c, p, and s conversions */
|
||||||
|
#define L_FMTFLAGSC "-"
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
** maximum size of each format specification (such as "%-099.99d")
|
** Maximum size of each format specification (such as "%-099.99d"):
|
||||||
|
** Initial '%', flags (up to 5), width (2), period, precision (2),
|
||||||
|
** length modifier (8), conversion specifier, and final '\0', plus some
|
||||||
|
** extra.
|
||||||
*/
|
*/
|
||||||
#define MAX_FORMAT 32
|
#define MAX_FORMAT 32
|
||||||
|
|
||||||
|
@ -1226,25 +1245,53 @@ static void addliteral (lua_State *L, luaL_Buffer *b, int arg) {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static const char *scanformat (lua_State *L, const char *strfrmt, char *form) {
|
static const char *get2digits (const char *s) {
|
||||||
const char *p = strfrmt;
|
if (isdigit(uchar(*s))) {
|
||||||
while (*p != '\0' && strchr(L_FMTFLAGS, *p) != NULL) p++; /* skip flags */
|
s++;
|
||||||
if ((size_t)(p - strfrmt) >= sizeof(L_FMTFLAGS)/sizeof(char))
|
if (isdigit(uchar(*s))) s++; /* (2 digits at most) */
|
||||||
luaL_error(L, "invalid format (repeated flags)");
|
|
||||||
if (isdigit(uchar(*p))) p++; /* skip width */
|
|
||||||
if (isdigit(uchar(*p))) p++; /* (2 digits at most) */
|
|
||||||
if (*p == '.') {
|
|
||||||
p++;
|
|
||||||
if (isdigit(uchar(*p))) p++; /* skip precision */
|
|
||||||
if (isdigit(uchar(*p))) p++; /* (2 digits at most) */
|
|
||||||
}
|
}
|
||||||
if (isdigit(uchar(*p)))
|
return s;
|
||||||
luaL_error(L, "invalid format (width or precision too long)");
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
** Check whether a conversion specification is valid. When called,
|
||||||
|
** first character in 'form' must be '%' and last character must
|
||||||
|
** be a valid conversion specifier. 'flags' are the accepted flags;
|
||||||
|
** 'precision' signals whether to accept a precision.
|
||||||
|
*/
|
||||||
|
static void checkformat (lua_State *L, const char *form, const char *flags,
|
||||||
|
int precision) {
|
||||||
|
const char *spec = form + 1; /* skip '%' */
|
||||||
|
spec += strspn(spec, flags); /* skip flags */
|
||||||
|
if (*spec != '0') { /* a width cannot start with '0' */
|
||||||
|
spec = get2digits(spec); /* skip width */
|
||||||
|
if (*spec == '.' && precision) {
|
||||||
|
spec++;
|
||||||
|
spec = get2digits(spec); /* skip precision */
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (!isalpha(uchar(*spec))) /* did not go to the end? */
|
||||||
|
luaL_error(L, "invalid conversion specification: '%s'", form);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
** Get a conversion specification and copy it to 'form'.
|
||||||
|
** Return the address of its last character.
|
||||||
|
*/
|
||||||
|
static const char *getformat (lua_State *L, const char *strfrmt,
|
||||||
|
char *form) {
|
||||||
|
/* spans flags, width, and precision ('0' is included as a flag) */
|
||||||
|
size_t len = strspn(strfrmt, L_FMTFLAGSF "123456789.");
|
||||||
|
len++; /* adds following character (should be the specifier) */
|
||||||
|
/* still needs space for '%', '\0', plus a length modifier */
|
||||||
|
if (len >= MAX_FORMAT - 10)
|
||||||
|
luaL_error(L, "invalid format (too long)");
|
||||||
*(form++) = '%';
|
*(form++) = '%';
|
||||||
memcpy(form, strfrmt, ((p - strfrmt) + 1) * sizeof(char));
|
memcpy(form, strfrmt, len * sizeof(char));
|
||||||
form += (p - strfrmt) + 1;
|
*(form + len) = '\0';
|
||||||
*form = '\0';
|
return strfrmt + len - 1;
|
||||||
return p;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -1267,6 +1314,7 @@ static int str_format (lua_State *L) {
|
||||||
size_t sfl;
|
size_t sfl;
|
||||||
const char *strfrmt = luaL_checklstring(L, arg, &sfl);
|
const char *strfrmt = luaL_checklstring(L, arg, &sfl);
|
||||||
const char *strfrmt_end = strfrmt+sfl;
|
const char *strfrmt_end = strfrmt+sfl;
|
||||||
|
const char *flags;
|
||||||
luaL_Buffer b;
|
luaL_Buffer b;
|
||||||
luaL_buffinit(L, &b);
|
luaL_buffinit(L, &b);
|
||||||
while (strfrmt < strfrmt_end) {
|
while (strfrmt < strfrmt_end) {
|
||||||
|
@ -1276,25 +1324,35 @@ static int str_format (lua_State *L) {
|
||||||
luaL_addchar(&b, *strfrmt++); /* %% */
|
luaL_addchar(&b, *strfrmt++); /* %% */
|
||||||
else { /* format item */
|
else { /* format item */
|
||||||
char form[MAX_FORMAT]; /* to store the format ('%...') */
|
char form[MAX_FORMAT]; /* to store the format ('%...') */
|
||||||
int maxitem = MAX_ITEM;
|
int maxitem = MAX_ITEM; /* maximum length for the result */
|
||||||
char *buff = luaL_prepbuffsize(&b, maxitem); /* to put formatted item */
|
char *buff = luaL_prepbuffsize(&b, maxitem); /* to put result */
|
||||||
int nb = 0; /* number of bytes in added item */
|
int nb = 0; /* number of bytes in result */
|
||||||
if (++arg > top)
|
if (++arg > top)
|
||||||
return luaL_argerror(L, arg, "no value");
|
return luaL_argerror(L, arg, "no value");
|
||||||
strfrmt = scanformat(L, strfrmt, form);
|
strfrmt = getformat(L, strfrmt, form);
|
||||||
switch (*strfrmt++) {
|
switch (*strfrmt++) {
|
||||||
case 'c': {
|
case 'c': {
|
||||||
|
checkformat(L, form, L_FMTFLAGSC, 0);
|
||||||
nb = l_sprintf(buff, maxitem, form, (int)luaL_checkinteger(L, arg));
|
nb = l_sprintf(buff, maxitem, form, (int)luaL_checkinteger(L, arg));
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case 'd': case 'i':
|
case 'd': case 'i':
|
||||||
case 'o': case 'u': case 'x': case 'X': {
|
flags = L_FMTFLAGSI;
|
||||||
|
goto intcase;
|
||||||
|
case 'u':
|
||||||
|
flags = L_FMTFLAGSU;
|
||||||
|
goto intcase;
|
||||||
|
case 'o': case 'x': case 'X':
|
||||||
|
flags = L_FMTFLAGSX;
|
||||||
|
intcase: {
|
||||||
lua_Integer n = luaL_checkinteger(L, arg);
|
lua_Integer n = luaL_checkinteger(L, arg);
|
||||||
|
checkformat(L, form, flags, 1);
|
||||||
addlenmod(form, LUA_INTEGER_FRMLEN);
|
addlenmod(form, LUA_INTEGER_FRMLEN);
|
||||||
nb = l_sprintf(buff, maxitem, form, (LUAI_UACINT)n);
|
nb = l_sprintf(buff, maxitem, form, (LUAI_UACINT)n);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case 'a': case 'A':
|
case 'a': case 'A':
|
||||||
|
checkformat(L, form, L_FMTFLAGSF, 1);
|
||||||
addlenmod(form, LUA_NUMBER_FRMLEN);
|
addlenmod(form, LUA_NUMBER_FRMLEN);
|
||||||
nb = lua_number2strx(L, buff, maxitem, form,
|
nb = lua_number2strx(L, buff, maxitem, form,
|
||||||
luaL_checknumber(L, arg));
|
luaL_checknumber(L, arg));
|
||||||
|
@ -1305,12 +1363,14 @@ static int str_format (lua_State *L) {
|
||||||
/* FALLTHROUGH */
|
/* FALLTHROUGH */
|
||||||
case 'e': case 'E': case 'g': case 'G': {
|
case 'e': case 'E': case 'g': case 'G': {
|
||||||
lua_Number n = luaL_checknumber(L, arg);
|
lua_Number n = luaL_checknumber(L, arg);
|
||||||
|
checkformat(L, form, L_FMTFLAGSF, 1);
|
||||||
addlenmod(form, LUA_NUMBER_FRMLEN);
|
addlenmod(form, LUA_NUMBER_FRMLEN);
|
||||||
nb = l_sprintf(buff, maxitem, form, (LUAI_UACNUMBER)n);
|
nb = l_sprintf(buff, maxitem, form, (LUAI_UACNUMBER)n);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case 'p': {
|
case 'p': {
|
||||||
const void *p = lua_topointer(L, arg);
|
const void *p = lua_topointer(L, arg);
|
||||||
|
checkformat(L, form, L_FMTFLAGSC, 0);
|
||||||
if (p == NULL) { /* avoid calling 'printf' with argument NULL */
|
if (p == NULL) { /* avoid calling 'printf' with argument NULL */
|
||||||
p = "(null)"; /* result */
|
p = "(null)"; /* result */
|
||||||
form[strlen(form) - 1] = 's'; /* format it as a string */
|
form[strlen(form) - 1] = 's'; /* format it as a string */
|
||||||
|
@ -1331,7 +1391,8 @@ static int str_format (lua_State *L) {
|
||||||
luaL_addvalue(&b); /* keep entire string */
|
luaL_addvalue(&b); /* keep entire string */
|
||||||
else {
|
else {
|
||||||
luaL_argcheck(L, l == strlen(s), arg, "string contains zeros");
|
luaL_argcheck(L, l == strlen(s), arg, "string contains zeros");
|
||||||
if (!strchr(form, '.') && l >= 100) {
|
checkformat(L, form, L_FMTFLAGSC, 1);
|
||||||
|
if (strchr(form, '.') == NULL && l >= 100) {
|
||||||
/* no precision and string is too long to be formatted */
|
/* no precision and string is too long to be formatted */
|
||||||
luaL_addvalue(&b); /* keep entire string */
|
luaL_addvalue(&b); /* keep entire string */
|
||||||
}
|
}
|
||||||
|
@ -1389,15 +1450,6 @@ static const union {
|
||||||
} nativeendian = {1};
|
} nativeendian = {1};
|
||||||
|
|
||||||
|
|
||||||
/* dummy structure to get native alignment requirements */
|
|
||||||
struct cD {
|
|
||||||
char c;
|
|
||||||
union { double d; void *p; lua_Integer i; lua_Number n; } u;
|
|
||||||
};
|
|
||||||
|
|
||||||
#define MAXALIGN (offsetof(struct cD, u))
|
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
** information to pack/unpack stuff
|
** information to pack/unpack stuff
|
||||||
*/
|
*/
|
||||||
|
@ -1472,6 +1524,8 @@ static void initheader (lua_State *L, Header *h) {
|
||||||
** Read and classify next option. 'size' is filled with option's size.
|
** Read and classify next option. 'size' is filled with option's size.
|
||||||
*/
|
*/
|
||||||
static KOption getoption (Header *h, const char **fmt, int *size) {
|
static KOption getoption (Header *h, const char **fmt, int *size) {
|
||||||
|
/* dummy structure to get native alignment requirements */
|
||||||
|
struct cD { char c; union { LUAI_MAXALIGN; } u; };
|
||||||
int opt = *((*fmt)++);
|
int opt = *((*fmt)++);
|
||||||
*size = 0; /* default */
|
*size = 0; /* default */
|
||||||
switch (opt) {
|
switch (opt) {
|
||||||
|
@ -1502,7 +1556,11 @@ static KOption getoption (Header *h, const char **fmt, int *size) {
|
||||||
case '<': h->islittle = 1; break;
|
case '<': h->islittle = 1; break;
|
||||||
case '>': h->islittle = 0; break;
|
case '>': h->islittle = 0; break;
|
||||||
case '=': h->islittle = nativeendian.little; break;
|
case '=': h->islittle = nativeendian.little; break;
|
||||||
case '!': h->maxalign = getnumlimit(h, fmt, MAXALIGN); break;
|
case '!': {
|
||||||
|
const int maxalign = offsetof(struct cD, u);
|
||||||
|
h->maxalign = getnumlimit(h, fmt, maxalign);
|
||||||
|
break;
|
||||||
|
}
|
||||||
default: luaL_error(h->L, "invalid format option '%c'", opt);
|
default: luaL_error(h->L, "invalid format option '%c'", opt);
|
||||||
}
|
}
|
||||||
return Knop;
|
return Knop;
|
||||||
|
|
60
third_party/lua/ltable.c
vendored
60
third_party/lua/ltable.c
vendored
|
@ -3,7 +3,7 @@
|
||||||
╚──────────────────────────────────────────────────────────────────────────────╝
|
╚──────────────────────────────────────────────────────────────────────────────╝
|
||||||
│ │
|
│ │
|
||||||
│ Lua │
|
│ Lua │
|
||||||
│ Copyright © 2004-2021 Lua.org, PUC-Rio. │
|
│ Copyright © 2004-2023 Lua.org, PUC-Rio. │
|
||||||
│ │
|
│ │
|
||||||
│ Permission is hereby granted, free of charge, to any person obtaining │
|
│ Permission is hereby granted, free of charge, to any person obtaining │
|
||||||
│ a copy of this software and associated documentation files (the │
|
│ a copy of this software and associated documentation files (the │
|
||||||
|
@ -27,6 +27,7 @@
|
||||||
╚─────────────────────────────────────────────────────────────────────────────*/
|
╚─────────────────────────────────────────────────────────────────────────────*/
|
||||||
#define ltable_c
|
#define ltable_c
|
||||||
#define LUA_CORE
|
#define LUA_CORE
|
||||||
|
|
||||||
#include "third_party/lua/ldebug.h"
|
#include "third_party/lua/ldebug.h"
|
||||||
#include "third_party/lua/ldo.h"
|
#include "third_party/lua/ldo.h"
|
||||||
#include "third_party/lua/lgc.h"
|
#include "third_party/lua/lgc.h"
|
||||||
|
@ -100,8 +101,6 @@ __static_yoink("lua_notice");
|
||||||
#define hashstr(t,str) hashpow2(t, (str)->hash)
|
#define hashstr(t,str) hashpow2(t, (str)->hash)
|
||||||
#define hashboolean(t,p) hashpow2(t, p)
|
#define hashboolean(t,p) hashpow2(t, p)
|
||||||
|
|
||||||
#define hashint(t,i) hashpow2(t, i)
|
|
||||||
|
|
||||||
|
|
||||||
#define hashpointer(t,p) hashmod(t, point2uint(p))
|
#define hashpointer(t,p) hashmod(t, point2uint(p))
|
||||||
|
|
||||||
|
@ -117,6 +116,20 @@ static const Node dummynode_ = {
|
||||||
static const TValue absentkey = {ABSTKEYCONSTANT};
|
static const TValue absentkey = {ABSTKEYCONSTANT};
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
** Hash for integers. To allow a good hash, use the remainder operator
|
||||||
|
** ('%'). If integer fits as a non-negative int, compute an int
|
||||||
|
** remainder, which is faster. Otherwise, use an unsigned-integer
|
||||||
|
** remainder, which uses all bits and ensures a non-negative result.
|
||||||
|
*/
|
||||||
|
static Node *hashint (const Table *t, lua_Integer i) {
|
||||||
|
lua_Unsigned ui = l_castS2U(i);
|
||||||
|
if (ui <= cast_uint(INT_MAX))
|
||||||
|
return hashmod(t, cast_int(ui));
|
||||||
|
else
|
||||||
|
return hashmod(t, ui);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
** Hash for floating-point numbers.
|
** Hash for floating-point numbers.
|
||||||
|
@ -150,26 +163,24 @@ static int l_hashfloat (lua_Number n) {
|
||||||
|
|
||||||
/*
|
/*
|
||||||
** returns the 'main' position of an element in a table (that is,
|
** returns the 'main' position of an element in a table (that is,
|
||||||
** the index of its hash value). The key comes broken (tag in 'ktt'
|
** the index of its hash value).
|
||||||
** and value in 'vkl') so that we can call it on keys inserted into
|
|
||||||
** nodes.
|
|
||||||
*/
|
*/
|
||||||
static Node *mainposition (const Table *t, int ktt, const Value *kvl) {
|
static Node *mainpositionTV (const Table *t, const TValue *key) {
|
||||||
switch (withvariant(ktt)) {
|
switch (ttypetag(key)) {
|
||||||
case LUA_VNUMINT: {
|
case LUA_VNUMINT: {
|
||||||
lua_Integer key = ivalueraw(*kvl);
|
lua_Integer i = ivalue(key);
|
||||||
return hashint(t, key);
|
return hashint(t, i);
|
||||||
}
|
}
|
||||||
case LUA_VNUMFLT: {
|
case LUA_VNUMFLT: {
|
||||||
lua_Number n = fltvalueraw(*kvl);
|
lua_Number n = fltvalue(key);
|
||||||
return hashmod(t, l_hashfloat(n));
|
return hashmod(t, l_hashfloat(n));
|
||||||
}
|
}
|
||||||
case LUA_VSHRSTR: {
|
case LUA_VSHRSTR: {
|
||||||
TString *ts = tsvalueraw(*kvl);
|
TString *ts = tsvalue(key);
|
||||||
return hashstr(t, ts);
|
return hashstr(t, ts);
|
||||||
}
|
}
|
||||||
case LUA_VLNGSTR: {
|
case LUA_VLNGSTR: {
|
||||||
TString *ts = tsvalueraw(*kvl);
|
TString *ts = tsvalue(key);
|
||||||
return hashpow2(t, luaS_hashlongstr(ts));
|
return hashpow2(t, luaS_hashlongstr(ts));
|
||||||
}
|
}
|
||||||
case LUA_VFALSE:
|
case LUA_VFALSE:
|
||||||
|
@ -177,26 +188,25 @@ static Node *mainposition (const Table *t, int ktt, const Value *kvl) {
|
||||||
case LUA_VTRUE:
|
case LUA_VTRUE:
|
||||||
return hashboolean(t, 1);
|
return hashboolean(t, 1);
|
||||||
case LUA_VLIGHTUSERDATA: {
|
case LUA_VLIGHTUSERDATA: {
|
||||||
void *p = pvalueraw(*kvl);
|
void *p = pvalue(key);
|
||||||
return hashpointer(t, p);
|
return hashpointer(t, p);
|
||||||
}
|
}
|
||||||
case LUA_VLCF: {
|
case LUA_VLCF: {
|
||||||
lua_CFunction f = fvalueraw(*kvl);
|
lua_CFunction f = fvalue(key);
|
||||||
return hashpointer(t, f);
|
return hashpointer(t, f);
|
||||||
}
|
}
|
||||||
default: {
|
default: {
|
||||||
GCObject *o = gcvalueraw(*kvl);
|
GCObject *o = gcvalue(key);
|
||||||
return hashpointer(t, o);
|
return hashpointer(t, o);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/*
|
l_sinline Node *mainpositionfromnode (const Table *t, Node *nd) {
|
||||||
** Returns the main position of an element given as a 'TValue'
|
TValue key;
|
||||||
*/
|
getnodekey(cast(lua_State *, NULL), &key, nd);
|
||||||
static Node *mainpositionTV (const Table *t, const TValue *key) {
|
return mainpositionTV(t, &key);
|
||||||
return mainposition(t, rawtt(key), valraw(key));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -264,9 +274,11 @@ LUAI_FUNC unsigned int luaH_realasize (const Table *t) {
|
||||||
size |= (size >> 2);
|
size |= (size >> 2);
|
||||||
size |= (size >> 4);
|
size |= (size >> 4);
|
||||||
size |= (size >> 8);
|
size |= (size >> 8);
|
||||||
|
#if (UINT_MAX >> 14) > 3 /* unsigned int has more than 16 bits */
|
||||||
size |= (size >> 16);
|
size |= (size >> 16);
|
||||||
#if (UINT_MAX >> 30) > 3
|
#if (UINT_MAX >> 30) > 3
|
||||||
size |= (size >> 32); /* unsigned int has more than 32 bits */
|
size |= (size >> 32); /* unsigned int has more than 32 bits */
|
||||||
|
#endif
|
||||||
#endif
|
#endif
|
||||||
size++;
|
size++;
|
||||||
lua_assert(ispow2(size) && size/2 < t->alimit && t->alimit < size);
|
lua_assert(ispow2(size) && size/2 < t->alimit && t->alimit < size);
|
||||||
|
@ -495,7 +507,7 @@ static void setnodevector (lua_State *L, Table *t, unsigned int size) {
|
||||||
luaG_runerror(L, "table overflow");
|
luaG_runerror(L, "table overflow");
|
||||||
size = twoto(lsize);
|
size = twoto(lsize);
|
||||||
t->node = luaM_newvector(L, size, Node);
|
t->node = luaM_newvector(L, size, Node);
|
||||||
for (i = 0; i < (int)size; i++) {
|
for (i = 0; i < cast_int(size); i++) {
|
||||||
Node *n = gnode(t, i);
|
Node *n = gnode(t, i);
|
||||||
gnext(n) = 0;
|
gnext(n) = 0;
|
||||||
setnilkey(n);
|
setnilkey(n);
|
||||||
|
@ -695,7 +707,7 @@ void luaH_newkey (lua_State *L, Table *t, const TValue *key, TValue *value) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
lua_assert(!isdummy(t));
|
lua_assert(!isdummy(t));
|
||||||
othern = mainposition(t, keytt(mp), &keyval(mp));
|
othern = mainpositionfromnode(t, mp);
|
||||||
if (othern != mp) { /* is colliding node out of its main position? */
|
if (othern != mp) { /* is colliding node out of its main position? */
|
||||||
/* yes; move colliding node into free position */
|
/* yes; move colliding node into free position */
|
||||||
while (othern + gnext(othern) != mp) /* find previous */
|
while (othern + gnext(othern) != mp) /* find previous */
|
||||||
|
@ -982,6 +994,4 @@ Node *luaH_mainposition (const Table *t, const TValue *key) {
|
||||||
return mainpositionTV(t, key);
|
return mainpositionTV(t, key);
|
||||||
}
|
}
|
||||||
|
|
||||||
int luaH_isdummy (const Table *t) { return isdummy(t); }
|
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
1
third_party/lua/ltable.h
vendored
1
third_party/lua/ltable.h
vendored
|
@ -53,7 +53,6 @@ LUAI_FUNC unsigned int luaH_realasize (const Table *t);
|
||||||
|
|
||||||
#if defined(LUA_DEBUG)
|
#if defined(LUA_DEBUG)
|
||||||
LUAI_FUNC Node *luaH_mainposition (const Table *t, const TValue *key);
|
LUAI_FUNC Node *luaH_mainposition (const Table *t, const TValue *key);
|
||||||
LUAI_FUNC int luaH_isdummy (const Table *t);
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
|
10
third_party/lua/ltablib.c
vendored
10
third_party/lua/ltablib.c
vendored
|
@ -3,7 +3,7 @@
|
||||||
╚──────────────────────────────────────────────────────────────────────────────╝
|
╚──────────────────────────────────────────────────────────────────────────────╝
|
||||||
│ │
|
│ │
|
||||||
│ Lua │
|
│ Lua │
|
||||||
│ Copyright © 2004-2021 Lua.org, PUC-Rio. │
|
│ Copyright © 2004-2023 Lua.org, PUC-Rio. │
|
||||||
│ │
|
│ │
|
||||||
│ Permission is hereby granted, free of charge, to any person obtaining │
|
│ Permission is hereby granted, free of charge, to any person obtaining │
|
||||||
│ a copy of this software and associated documentation files (the │
|
│ a copy of this software and associated documentation files (the │
|
||||||
|
@ -27,6 +27,7 @@
|
||||||
╚─────────────────────────────────────────────────────────────────────────────*/
|
╚─────────────────────────────────────────────────────────────────────────────*/
|
||||||
#define ltablib_c
|
#define ltablib_c
|
||||||
#define LUA_LIB
|
#define LUA_LIB
|
||||||
|
|
||||||
#include "libc/calls/calls.h"
|
#include "libc/calls/calls.h"
|
||||||
#include "libc/calls/weirdtypes.h"
|
#include "libc/calls/weirdtypes.h"
|
||||||
#include "libc/str/str.h"
|
#include "libc/str/str.h"
|
||||||
|
@ -76,8 +77,9 @@ static void checktab (lua_State *L, int arg, int what) {
|
||||||
|
|
||||||
|
|
||||||
static int tinsert (lua_State *L) {
|
static int tinsert (lua_State *L) {
|
||||||
lua_Integer e = aux_getn(L, 1, TAB_RW) + 1; /* first empty element */
|
|
||||||
lua_Integer pos; /* where to insert new element */
|
lua_Integer pos; /* where to insert new element */
|
||||||
|
lua_Integer e = aux_getn(L, 1, TAB_RW);
|
||||||
|
e = luaL_intop(+, e, 1); /* first empty element */
|
||||||
switch (lua_gettop(L)) {
|
switch (lua_gettop(L)) {
|
||||||
case 2: { /* called with only 2 arguments */
|
case 2: { /* called with only 2 arguments */
|
||||||
pos = e; /* insert new element at the end */
|
pos = e; /* insert new element at the end */
|
||||||
|
@ -109,7 +111,7 @@ static int tremove (lua_State *L) {
|
||||||
lua_Integer pos = luaL_optinteger(L, 2, size);
|
lua_Integer pos = luaL_optinteger(L, 2, size);
|
||||||
if (pos != size) /* validate 'pos' if given */
|
if (pos != size) /* validate 'pos' if given */
|
||||||
/* check whether 'pos' is in [1, size + 1] */
|
/* check whether 'pos' is in [1, size + 1] */
|
||||||
luaL_argcheck(L, (lua_Unsigned)pos - 1u <= (lua_Unsigned)size, 1,
|
luaL_argcheck(L, (lua_Unsigned)pos - 1u <= (lua_Unsigned)size, 2,
|
||||||
"position out of bounds");
|
"position out of bounds");
|
||||||
lua_geti(L, 1, pos); /* result = t[pos] */
|
lua_geti(L, 1, pos); /* result = t[pos] */
|
||||||
for ( ; pos < size; pos++) {
|
for ( ; pos < size; pos++) {
|
||||||
|
@ -164,7 +166,7 @@ static void addfield (lua_State *L, luaL_Buffer *b, lua_Integer i) {
|
||||||
lua_geti(L, 1, i);
|
lua_geti(L, 1, i);
|
||||||
if (l_unlikely(!lua_isstring(L, -1)))
|
if (l_unlikely(!lua_isstring(L, -1)))
|
||||||
luaL_error(L, "invalid value (%s) at index %I in table for 'concat'",
|
luaL_error(L, "invalid value (%s) at index %I in table for 'concat'",
|
||||||
luaL_typename(L, -1), i);
|
luaL_typename(L, -1), (LUAI_UACINT)i);
|
||||||
luaL_addvalue(b);
|
luaL_addvalue(b);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
46
third_party/lua/ltests.c
vendored
46
third_party/lua/ltests.c
vendored
|
@ -3,7 +3,7 @@
|
||||||
╚──────────────────────────────────────────────────────────────────────────────╝
|
╚──────────────────────────────────────────────────────────────────────────────╝
|
||||||
│ │
|
│ │
|
||||||
│ Lua │
|
│ Lua │
|
||||||
│ Copyright © 2004-2021 Lua.org, PUC-Rio. │
|
│ Copyright © 2004-2023 Lua.org, PUC-Rio. │
|
||||||
│ │
|
│ │
|
||||||
│ Permission is hereby granted, free of charge, to any person obtaining │
|
│ Permission is hereby granted, free of charge, to any person obtaining │
|
||||||
│ a copy of this software and associated documentation files (the │
|
│ a copy of this software and associated documentation files (the │
|
||||||
|
@ -27,6 +27,7 @@
|
||||||
╚─────────────────────────────────────────────────────────────────────────────*/
|
╚─────────────────────────────────────────────────────────────────────────────*/
|
||||||
#define ltests_c
|
#define ltests_c
|
||||||
#define LUA_CORE
|
#define LUA_CORE
|
||||||
|
|
||||||
#include "third_party/lua/lapi.h"
|
#include "third_party/lua/lapi.h"
|
||||||
#include "third_party/lua/lauxlib.h"
|
#include "third_party/lua/lauxlib.h"
|
||||||
#include "third_party/lua/lcode.h"
|
#include "third_party/lua/lcode.h"
|
||||||
|
@ -55,7 +56,7 @@ __static_yoink("lua_notice");
|
||||||
void *l_Trick = 0;
|
void *l_Trick = 0;
|
||||||
|
|
||||||
|
|
||||||
#define obj_at(L,k) s2v(L->ci->func + (k))
|
#define obj_at(L,k) s2v(L->ci->func.p + (k))
|
||||||
|
|
||||||
|
|
||||||
static int runC (lua_State *L, lua_State *L1, const char *pc);
|
static int runC (lua_State *L, lua_State *L1, const char *pc);
|
||||||
|
@ -68,7 +69,7 @@ static void setnameval (lua_State *L, const char *name, int val) {
|
||||||
|
|
||||||
|
|
||||||
static void pushobject (lua_State *L, const TValue *o) {
|
static void pushobject (lua_State *L, const TValue *o) {
|
||||||
setobj2s(L, L->top, o);
|
setobj2s(L, L->top.p, o);
|
||||||
api_incr_top(L);
|
api_incr_top(L);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -430,7 +431,7 @@ static void checkLclosure (global_State *g, LClosure *cl) {
|
||||||
if (uv) {
|
if (uv) {
|
||||||
checkobjrefN(g, clgc, uv);
|
checkobjrefN(g, clgc, uv);
|
||||||
if (!upisopen(uv))
|
if (!upisopen(uv))
|
||||||
checkvalref(g, obj2gco(uv), uv->v);
|
checkvalref(g, obj2gco(uv), uv->v.p);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -439,7 +440,7 @@ static void checkLclosure (global_State *g, LClosure *cl) {
|
||||||
static int lua_checkpc (CallInfo *ci) {
|
static int lua_checkpc (CallInfo *ci) {
|
||||||
if (!isLua(ci)) return 1;
|
if (!isLua(ci)) return 1;
|
||||||
else {
|
else {
|
||||||
StkId f = ci->func;
|
StkId f = ci->func.p;
|
||||||
Proto *p = clLvalue(s2v(f))->p;
|
Proto *p = clLvalue(s2v(f))->p;
|
||||||
return p->code <= ci->u.l.savedpc &&
|
return p->code <= ci->u.l.savedpc &&
|
||||||
ci->u.l.savedpc <= p->code + p->sizecode;
|
ci->u.l.savedpc <= p->code + p->sizecode;
|
||||||
|
@ -452,19 +453,19 @@ static void checkstack (global_State *g, lua_State *L1) {
|
||||||
CallInfo *ci;
|
CallInfo *ci;
|
||||||
UpVal *uv;
|
UpVal *uv;
|
||||||
assert(!isdead(g, L1));
|
assert(!isdead(g, L1));
|
||||||
if (L1->stack == NULL) { /* incomplete thread? */
|
if (L1->stack.p == NULL) { /* incomplete thread? */
|
||||||
assert(L1->openupval == NULL && L1->ci == NULL);
|
assert(L1->openupval == NULL && L1->ci == NULL);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
for (uv = L1->openupval; uv != NULL; uv = uv->u.open.next)
|
for (uv = L1->openupval; uv != NULL; uv = uv->u.open.next)
|
||||||
assert(upisopen(uv)); /* must be open */
|
assert(upisopen(uv)); /* must be open */
|
||||||
assert(L1->top <= L1->stack_last);
|
assert(L1->top.p <= L1->stack_last.p);
|
||||||
assert(L1->tbclist <= L1->top);
|
assert(L1->tbclist.p <= L1->top.p);
|
||||||
for (ci = L1->ci; ci != NULL; ci = ci->previous) {
|
for (ci = L1->ci; ci != NULL; ci = ci->previous) {
|
||||||
assert(ci->top <= L1->stack_last);
|
assert(ci->top.p <= L1->stack_last.p);
|
||||||
assert(lua_checkpc(ci));
|
assert(lua_checkpc(ci));
|
||||||
}
|
}
|
||||||
for (o = L1->stack; o < L1->stack_last; o++)
|
for (o = L1->stack.p; o < L1->stack_last.p; o++)
|
||||||
checkliveness(L1, s2v(o)); /* entire stack must have valid values */
|
checkliveness(L1, s2v(o)); /* entire stack must have valid values */
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -476,7 +477,7 @@ static void checkrefs (global_State *g, GCObject *o) {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case LUA_VUPVAL: {
|
case LUA_VUPVAL: {
|
||||||
checkvalref(g, o, gco2upv(o)->v);
|
checkvalref(g, o, gco2upv(o)->v.p);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case LUA_VTABLE: {
|
case LUA_VTABLE: {
|
||||||
|
@ -544,7 +545,7 @@ static void checkobject (global_State *g, GCObject *o, int maybedead,
|
||||||
|
|
||||||
static lu_mem checkgraylist (global_State *g, GCObject *o) {
|
static lu_mem checkgraylist (global_State *g, GCObject *o) {
|
||||||
int total = 0; /* count number of elements in the list */
|
int total = 0; /* count number of elements in the list */
|
||||||
((void)g); /* better to keep it available if we need to print an object */
|
cast_void(g); /* better to keep it if we need to print an object */
|
||||||
while (o) {
|
while (o) {
|
||||||
assert(!!isgray(o) ^ (getage(o) == G_TOUCHED2));
|
assert(!!isgray(o) ^ (getage(o) == G_TOUCHED2));
|
||||||
assert(!testbit(o->marked, TESTBIT));
|
assert(!testbit(o->marked, TESTBIT));
|
||||||
|
@ -991,7 +992,7 @@ static int hash_query (lua_State *L) {
|
||||||
|
|
||||||
static int stacklevel (lua_State *L) {
|
static int stacklevel (lua_State *L) {
|
||||||
unsigned long a = 0;
|
unsigned long a = 0;
|
||||||
lua_pushinteger(L, (L->top - L->stack));
|
lua_pushinteger(L, (L->top.p - L->stack.p));
|
||||||
lua_pushinteger(L, stacksize(L));
|
lua_pushinteger(L, stacksize(L));
|
||||||
lua_pushinteger(L, L->nCcalls);
|
lua_pushinteger(L, L->nCcalls);
|
||||||
lua_pushinteger(L, L->nci);
|
lua_pushinteger(L, L->nci);
|
||||||
|
@ -1051,7 +1052,7 @@ static int string_query (lua_State *L) {
|
||||||
TString *ts;
|
TString *ts;
|
||||||
int n = 0;
|
int n = 0;
|
||||||
for (ts = tb->hash[s]; ts != NULL; ts = ts->u.hnext) {
|
for (ts = tb->hash[s]; ts != NULL; ts = ts->u.hnext) {
|
||||||
setsvalue2s(L, L->top, ts);
|
setsvalue2s(L, L->top.p, ts);
|
||||||
api_incr_top(L);
|
api_incr_top(L);
|
||||||
n++;
|
n++;
|
||||||
}
|
}
|
||||||
|
@ -1066,7 +1067,7 @@ static int tref (lua_State *L) {
|
||||||
luaL_checkany(L, 1);
|
luaL_checkany(L, 1);
|
||||||
lua_pushvalue(L, 1);
|
lua_pushvalue(L, 1);
|
||||||
lua_pushinteger(L, luaL_ref(L, LUA_REGISTRYINDEX));
|
lua_pushinteger(L, luaL_ref(L, LUA_REGISTRYINDEX));
|
||||||
(void)level; /* to avoid warnings */
|
cast_void(level); /* to avoid warnings */
|
||||||
lua_assert(lua_gettop(L) == level+1); /* +1 for result */
|
lua_assert(lua_gettop(L) == level+1); /* +1 for result */
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
@ -1074,7 +1075,7 @@ static int tref (lua_State *L) {
|
||||||
static int getref (lua_State *L) {
|
static int getref (lua_State *L) {
|
||||||
int level = lua_gettop(L);
|
int level = lua_gettop(L);
|
||||||
lua_rawgeti(L, LUA_REGISTRYINDEX, luaL_checkinteger(L, 1));
|
lua_rawgeti(L, LUA_REGISTRYINDEX, luaL_checkinteger(L, 1));
|
||||||
(void)level; /* to avoid warnings */
|
cast_void(level); /* to avoid warnings */
|
||||||
lua_assert(lua_gettop(L) == level+1);
|
lua_assert(lua_gettop(L) == level+1);
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
@ -1082,7 +1083,7 @@ static int getref (lua_State *L) {
|
||||||
static int unref (lua_State *L) {
|
static int unref (lua_State *L) {
|
||||||
int level = lua_gettop(L);
|
int level = lua_gettop(L);
|
||||||
luaL_unref(L, LUA_REGISTRYINDEX, cast_int(luaL_checkinteger(L, 1)));
|
luaL_unref(L, LUA_REGISTRYINDEX, cast_int(luaL_checkinteger(L, 1)));
|
||||||
(void)level; /* to avoid warnings */
|
cast_void(level); /* to avoid warnings */
|
||||||
lua_assert(lua_gettop(L) == level);
|
lua_assert(lua_gettop(L) == level);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
@ -1258,7 +1259,7 @@ static int panicback (lua_State *L) {
|
||||||
b = (struct Aux *)lua_touserdata(L, -1);
|
b = (struct Aux *)lua_touserdata(L, -1);
|
||||||
lua_pop(L, 1); /* remove 'Aux' struct */
|
lua_pop(L, 1); /* remove 'Aux' struct */
|
||||||
runC(b->L, L, b->paniccode); /* run optional panic code */
|
runC(b->L, L, b->paniccode); /* run optional panic code */
|
||||||
gclongjmp(b->jb, 1);
|
gclongjmp(b->jb, 1); // [jart]
|
||||||
return 1; /* to avoid warnings */
|
return 1; /* to avoid warnings */
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1544,7 +1545,7 @@ static int runC (lua_State *L, lua_State *L1, const char *pc) {
|
||||||
lua_newthread(L1);
|
lua_newthread(L1);
|
||||||
}
|
}
|
||||||
else if EQ("resetthread") {
|
else if EQ("resetthread") {
|
||||||
lua_pushinteger(L1, lua_resetthread(L1));
|
lua_pushinteger(L1, lua_resetthread(L1)); /* deprecated */
|
||||||
}
|
}
|
||||||
else if EQ("newuserdata") {
|
else if EQ("newuserdata") {
|
||||||
lua_newuserdata(L1, getnum);
|
lua_newuserdata(L1, getnum);
|
||||||
|
@ -1719,7 +1720,7 @@ static int runC (lua_State *L, lua_State *L1, const char *pc) {
|
||||||
lua_error(L1);
|
lua_error(L1);
|
||||||
}
|
}
|
||||||
else if EQ("abort") {
|
else if EQ("abort") {
|
||||||
__die();
|
__die(); // [jart]
|
||||||
}
|
}
|
||||||
else if EQ("throw") {
|
else if EQ("throw") {
|
||||||
#if defined(__cplusplus)
|
#if defined(__cplusplus)
|
||||||
|
@ -1751,9 +1752,12 @@ static struct X { int x; } x;
|
||||||
else if EQ("tostring") {
|
else if EQ("tostring") {
|
||||||
const char *s = lua_tostring(L1, getindex);
|
const char *s = lua_tostring(L1, getindex);
|
||||||
const char *s1 = lua_pushstring(L1, s);
|
const char *s1 = lua_pushstring(L1, s);
|
||||||
(void)s1; /* to avoid warnings */
|
cast_void(s1); /* to avoid warnings */
|
||||||
lua_longassert((s == NULL && s1 == NULL) || strcmp(s, s1) == 0);
|
lua_longassert((s == NULL && s1 == NULL) || strcmp(s, s1) == 0);
|
||||||
}
|
}
|
||||||
|
else if EQ("Ltolstring") {
|
||||||
|
luaL_tolstring(L1, getindex, NULL);
|
||||||
|
}
|
||||||
else if EQ("type") {
|
else if EQ("type") {
|
||||||
lua_pushstring(L1, luaL_typename(L1, getnum));
|
lua_pushstring(L1, luaL_typename(L1, getnum));
|
||||||
}
|
}
|
||||||
|
|
8
third_party/lua/ltests.h
vendored
8
third_party/lua/ltests.h
vendored
|
@ -1,5 +1,6 @@
|
||||||
#ifndef ltests_h
|
#ifndef ltests_h
|
||||||
#define ltests_h
|
#define ltests_h
|
||||||
|
|
||||||
#include "third_party/lua/lua.h"
|
#include "third_party/lua/lua.h"
|
||||||
|
|
||||||
|
|
||||||
|
@ -117,6 +118,13 @@ LUA_API void *debug_realloc (void *ud, void *block,
|
||||||
#define LUAI_USER_ALIGNMENT_T union { char b[sizeof(void*) * 8]; }
|
#define LUAI_USER_ALIGNMENT_T union { char b[sizeof(void*) * 8]; }
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
** This one is not compatible with tests for opcode optimizations,
|
||||||
|
** as it blocks some optimizations
|
||||||
|
#define MAXINDEXRK 0
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
/* make stack-overflow tests run faster */
|
/* make stack-overflow tests run faster */
|
||||||
#undef LUAI_MAXSTACK
|
#undef LUAI_MAXSTACK
|
||||||
#define LUAI_MAXSTACK 50000
|
#define LUAI_MAXSTACK 50000
|
||||||
|
|
41
third_party/lua/ltm.c
vendored
41
third_party/lua/ltm.c
vendored
|
@ -3,7 +3,7 @@
|
||||||
╚──────────────────────────────────────────────────────────────────────────────╝
|
╚──────────────────────────────────────────────────────────────────────────────╝
|
||||||
│ │
|
│ │
|
||||||
│ Lua │
|
│ Lua │
|
||||||
│ Copyright © 2004-2021 Lua.org, PUC-Rio. │
|
│ Copyright © 2004-2023 Lua.org, PUC-Rio. │
|
||||||
│ │
|
│ │
|
||||||
│ Permission is hereby granted, free of charge, to any person obtaining │
|
│ Permission is hereby granted, free of charge, to any person obtaining │
|
||||||
│ a copy of this software and associated documentation files (the │
|
│ a copy of this software and associated documentation files (the │
|
||||||
|
@ -27,6 +27,7 @@
|
||||||
╚─────────────────────────────────────────────────────────────────────────────*/
|
╚─────────────────────────────────────────────────────────────────────────────*/
|
||||||
#define ltm_c
|
#define ltm_c
|
||||||
#define LUA_CORE
|
#define LUA_CORE
|
||||||
|
|
||||||
#include "third_party/lua/ldebug.h"
|
#include "third_party/lua/ldebug.h"
|
||||||
#include "third_party/lua/ldo.h"
|
#include "third_party/lua/ldo.h"
|
||||||
#include "third_party/lua/lgc.h"
|
#include "third_party/lua/lgc.h"
|
||||||
|
@ -118,12 +119,12 @@ const char *luaT_objtypename (lua_State *L, const TValue *o) {
|
||||||
|
|
||||||
void luaT_callTM (lua_State *L, const TValue *f, const TValue *p1,
|
void luaT_callTM (lua_State *L, const TValue *f, const TValue *p1,
|
||||||
const TValue *p2, const TValue *p3) {
|
const TValue *p2, const TValue *p3) {
|
||||||
StkId func = L->top;
|
StkId func = L->top.p;
|
||||||
setobj2s(L, func, f); /* push function (assume EXTRA_STACK) */
|
setobj2s(L, func, f); /* push function (assume EXTRA_STACK) */
|
||||||
setobj2s(L, func + 1, p1); /* 1st argument */
|
setobj2s(L, func + 1, p1); /* 1st argument */
|
||||||
setobj2s(L, func + 2, p2); /* 2nd argument */
|
setobj2s(L, func + 2, p2); /* 2nd argument */
|
||||||
setobj2s(L, func + 3, p3); /* 3rd argument */
|
setobj2s(L, func + 3, p3); /* 3rd argument */
|
||||||
L->top = func + 4;
|
L->top.p = func + 4;
|
||||||
/* metamethod may yield only when called from Lua code */
|
/* metamethod may yield only when called from Lua code */
|
||||||
if (isLuacode(L->ci))
|
if (isLuacode(L->ci))
|
||||||
luaD_call(L, func, 0);
|
luaD_call(L, func, 0);
|
||||||
|
@ -135,18 +136,18 @@ void luaT_callTM (lua_State *L, const TValue *f, const TValue *p1,
|
||||||
void luaT_callTMres (lua_State *L, const TValue *f, const TValue *p1,
|
void luaT_callTMres (lua_State *L, const TValue *f, const TValue *p1,
|
||||||
const TValue *p2, StkId res) {
|
const TValue *p2, StkId res) {
|
||||||
ptrdiff_t result = savestack(L, res);
|
ptrdiff_t result = savestack(L, res);
|
||||||
StkId func = L->top;
|
StkId func = L->top.p;
|
||||||
setobj2s(L, func, f); /* push function (assume EXTRA_STACK) */
|
setobj2s(L, func, f); /* push function (assume EXTRA_STACK) */
|
||||||
setobj2s(L, func + 1, p1); /* 1st argument */
|
setobj2s(L, func + 1, p1); /* 1st argument */
|
||||||
setobj2s(L, func + 2, p2); /* 2nd argument */
|
setobj2s(L, func + 2, p2); /* 2nd argument */
|
||||||
L->top += 3;
|
L->top.p += 3;
|
||||||
/* metamethod may yield only when called from Lua code */
|
/* metamethod may yield only when called from Lua code */
|
||||||
if (isLuacode(L->ci))
|
if (isLuacode(L->ci))
|
||||||
luaD_call(L, func, 1);
|
luaD_call(L, func, 1);
|
||||||
else
|
else
|
||||||
luaD_callnoyield(L, func, 1);
|
luaD_callnoyield(L, func, 1);
|
||||||
res = restorestack(L, result);
|
res = restorestack(L, result);
|
||||||
setobjs2s(L, res, --L->top); /* move result to its place */
|
setobjs2s(L, res, --L->top.p); /* move result to its place */
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -181,7 +182,7 @@ void luaT_trybinTM (lua_State *L, const TValue *p1, const TValue *p2,
|
||||||
|
|
||||||
|
|
||||||
void luaT_tryconcatTM (lua_State *L) {
|
void luaT_tryconcatTM (lua_State *L) {
|
||||||
StkId top = L->top;
|
StkId top = L->top.p;
|
||||||
if (l_unlikely(!callbinTM(L, s2v(top - 2), s2v(top - 1), top - 2,
|
if (l_unlikely(!callbinTM(L, s2v(top - 2), s2v(top - 1), top - 2,
|
||||||
TM_CONCAT)))
|
TM_CONCAT)))
|
||||||
luaG_concaterror(L, s2v(top - 2), s2v(top - 1));
|
luaG_concaterror(L, s2v(top - 2), s2v(top - 1));
|
||||||
|
@ -216,15 +217,15 @@ void luaT_trybiniTM (lua_State *L, const TValue *p1, lua_Integer i2,
|
||||||
*/
|
*/
|
||||||
int luaT_callorderTM (lua_State *L, const TValue *p1, const TValue *p2,
|
int luaT_callorderTM (lua_State *L, const TValue *p1, const TValue *p2,
|
||||||
TMS event) {
|
TMS event) {
|
||||||
if (callbinTM(L, p1, p2, L->top, event)) /* try original event */
|
if (callbinTM(L, p1, p2, L->top.p, event)) /* try original event */
|
||||||
return !l_isfalse(s2v(L->top));
|
return !l_isfalse(s2v(L->top.p));
|
||||||
#if defined(LUA_COMPAT_LT_LE)
|
#if defined(LUA_COMPAT_LT_LE)
|
||||||
else if (event == TM_LE) {
|
else if (event == TM_LE) {
|
||||||
/* try '!(p2 < p1)' for '(p1 <= p2)' */
|
/* try '!(p2 < p1)' for '(p1 <= p2)' */
|
||||||
L->ci->callstatus |= CIST_LEQ; /* mark it is doing 'lt' for 'le' */
|
L->ci->callstatus |= CIST_LEQ; /* mark it is doing 'lt' for 'le' */
|
||||||
if (callbinTM(L, p2, p1, L->top, TM_LT)) {
|
if (callbinTM(L, p2, p1, L->top.p, TM_LT)) {
|
||||||
L->ci->callstatus ^= CIST_LEQ; /* clear mark */
|
L->ci->callstatus ^= CIST_LEQ; /* clear mark */
|
||||||
return l_isfalse(s2v(L->top));
|
return l_isfalse(s2v(L->top.p));
|
||||||
}
|
}
|
||||||
/* else error will remove this 'ci'; no need to clear mark */
|
/* else error will remove this 'ci'; no need to clear mark */
|
||||||
}
|
}
|
||||||
|
@ -254,20 +255,20 @@ int luaT_callorderiTM (lua_State *L, const TValue *p1, int v2,
|
||||||
void luaT_adjustvarargs (lua_State *L, int nfixparams, CallInfo *ci,
|
void luaT_adjustvarargs (lua_State *L, int nfixparams, CallInfo *ci,
|
||||||
const Proto *p) {
|
const Proto *p) {
|
||||||
int i;
|
int i;
|
||||||
int actual = cast_int(L->top - ci->func) - 1; /* number of arguments */
|
int actual = cast_int(L->top.p - ci->func.p) - 1; /* number of arguments */
|
||||||
int nextra = actual - nfixparams; /* number of extra arguments */
|
int nextra = actual - nfixparams; /* number of extra arguments */
|
||||||
ci->u.l.nextraargs = nextra;
|
ci->u.l.nextraargs = nextra;
|
||||||
luaD_checkstack(L, p->maxstacksize + 1);
|
luaD_checkstack(L, p->maxstacksize + 1);
|
||||||
/* copy function to the top of the stack */
|
/* copy function to the top of the stack */
|
||||||
setobjs2s(L, L->top++, ci->func);
|
setobjs2s(L, L->top.p++, ci->func.p);
|
||||||
/* move fixed parameters to the top of the stack */
|
/* move fixed parameters to the top of the stack */
|
||||||
for (i = 1; i <= nfixparams; i++) {
|
for (i = 1; i <= nfixparams; i++) {
|
||||||
setobjs2s(L, L->top++, ci->func + i);
|
setobjs2s(L, L->top.p++, ci->func.p + i);
|
||||||
setnilvalue(s2v(ci->func + i)); /* erase original parameter (for GC) */
|
setnilvalue(s2v(ci->func.p + i)); /* erase original parameter (for GC) */
|
||||||
}
|
}
|
||||||
ci->func += actual + 1;
|
ci->func.p += actual + 1;
|
||||||
ci->top += actual + 1;
|
ci->top.p += actual + 1;
|
||||||
lua_assert(L->top <= ci->top && ci->top <= L->stack_last);
|
lua_assert(L->top.p <= ci->top.p && ci->top.p <= L->stack_last.p);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -277,10 +278,10 @@ void luaT_getvarargs (lua_State *L, CallInfo *ci, StkId where, int wanted) {
|
||||||
if (wanted < 0) {
|
if (wanted < 0) {
|
||||||
wanted = nextra; /* get all extra arguments available */
|
wanted = nextra; /* get all extra arguments available */
|
||||||
checkstackGCp(L, nextra, where); /* ensure stack space */
|
checkstackGCp(L, nextra, where); /* ensure stack space */
|
||||||
L->top = where + nextra; /* next instruction will need top */
|
L->top.p = where + nextra; /* next instruction will need top */
|
||||||
}
|
}
|
||||||
for (i = 0; i < wanted && i < nextra; i++)
|
for (i = 0; i < wanted && i < nextra; i++)
|
||||||
setobjs2s(L, where + i, ci->func - nextra + i);
|
setobjs2s(L, where + i, ci->func.p - nextra + i);
|
||||||
for (; i < wanted; i++) /* complete required results with nil */
|
for (; i < wanted; i++) /* complete required results with nil */
|
||||||
setnilvalue(s2v(where + i));
|
setnilvalue(s2v(where + i));
|
||||||
}
|
}
|
||||||
|
|
13
third_party/lua/ltm.h
vendored
13
third_party/lua/ltm.h
vendored
|
@ -1,9 +1,18 @@
|
||||||
#ifndef ltm_h
|
#ifndef ltm_h
|
||||||
#define ltm_h
|
#define ltm_h
|
||||||
|
|
||||||
#include "third_party/lua/lobject.h"
|
#include "third_party/lua/lobject.h"
|
||||||
|
#include "third_party/lua/lstate.h"
|
||||||
#include "third_party/lua/luaconf.h"
|
#include "third_party/lua/luaconf.h"
|
||||||
#include "third_party/lua/tms.h"
|
#include "third_party/lua/tms.h"
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
* WARNING: if you change the order of this enumeration,
|
||||||
|
* grep "ORDER TM" and "ORDER OP"
|
||||||
|
*/
|
||||||
|
// [jart] moved to tms.h
|
||||||
|
|
||||||
/*
|
/*
|
||||||
** Mask with 1 in all fast-access methods. A 1 in any of these bits
|
** Mask with 1 in all fast-access methods. A 1 in any of these bits
|
||||||
** in the flag of a (meta)table means the metatable does not have the
|
** in the flag of a (meta)table means the metatable does not have the
|
||||||
|
@ -54,8 +63,8 @@ LUAI_FUNC int luaT_callorderiTM (lua_State *L, const TValue *p1, int v2,
|
||||||
int inv, int isfloat, TMS event);
|
int inv, int isfloat, TMS event);
|
||||||
|
|
||||||
LUAI_FUNC void luaT_adjustvarargs (lua_State *L, int nfixparams,
|
LUAI_FUNC void luaT_adjustvarargs (lua_State *L, int nfixparams,
|
||||||
struct CallInfo *ci, const Proto *p);
|
CallInfo *ci, const Proto *p);
|
||||||
LUAI_FUNC void luaT_getvarargs (lua_State *L, struct CallInfo *ci,
|
LUAI_FUNC void luaT_getvarargs (lua_State *L, CallInfo *ci,
|
||||||
StkId where, int wanted);
|
StkId where, int wanted);
|
||||||
|
|
||||||
|
|
||||||
|
|
30
third_party/lua/lua.h
vendored
30
third_party/lua/lua.h
vendored
|
@ -1,18 +1,21 @@
|
||||||
#ifndef COSMOPOLITAN_THIRD_PARTY_LUA_LUA_H_
|
#ifndef COSMOPOLITAN_THIRD_PARTY_LUA_LUA_H_
|
||||||
#define COSMOPOLITAN_THIRD_PARTY_LUA_LUA_H_
|
#define COSMOPOLITAN_THIRD_PARTY_LUA_LUA_H_
|
||||||
|
|
||||||
#include "third_party/lua/luaconf.h"
|
#include "third_party/lua/luaconf.h"
|
||||||
|
|
||||||
COSMOPOLITAN_C_START_
|
COSMOPOLITAN_C_START_
|
||||||
|
|
||||||
|
|
||||||
#define LUA_VERSION_MAJOR "5"
|
#define LUA_VERSION_MAJOR "5"
|
||||||
#define LUA_VERSION_MINOR "4"
|
#define LUA_VERSION_MINOR "4"
|
||||||
#define LUA_VERSION_RELEASE "3"
|
#define LUA_VERSION_RELEASE "6"
|
||||||
|
|
||||||
#define LUA_VERSION_NUM 504
|
#define LUA_VERSION_NUM 504
|
||||||
#define LUA_VERSION_RELEASE_NUM (LUA_VERSION_NUM * 100 + 0)
|
#define LUA_VERSION_RELEASE_NUM (LUA_VERSION_NUM * 100 + 6)
|
||||||
|
|
||||||
#define LUA_VERSION "Lua " LUA_VERSION_MAJOR "." LUA_VERSION_MINOR
|
#define LUA_VERSION "Lua " LUA_VERSION_MAJOR "." LUA_VERSION_MINOR
|
||||||
#define LUA_RELEASE LUA_VERSION "." LUA_VERSION_RELEASE
|
#define LUA_RELEASE LUA_VERSION "." LUA_VERSION_RELEASE
|
||||||
#define LUA_COPYRIGHT LUA_RELEASE " Copyright (C) 1994-2021 Lua.org, PUC-Rio"
|
#define LUA_COPYRIGHT LUA_RELEASE " Copyright (C) 1994-2023 Lua.org, PUC-Rio"
|
||||||
#define LUA_AUTHORS "R. Ierusalimschy, L. H. de Figueiredo, W. Celes"
|
#define LUA_AUTHORS "R. Ierusalimschy, L. H. de Figueiredo, W. Celes"
|
||||||
|
|
||||||
|
|
||||||
|
@ -118,6 +121,16 @@ typedef void * (*lua_Alloc) (void *ud, void *ptr, size_t osize, size_t nsize);
|
||||||
typedef void (*lua_WarnFunction) (void *ud, const char *msg, int tocont);
|
typedef void (*lua_WarnFunction) (void *ud, const char *msg, int tocont);
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
** Type used by the debug API to collect debug information
|
||||||
|
*/
|
||||||
|
typedef struct lua_Debug lua_Debug;
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
** Functions to be called by the debugger in specific events
|
||||||
|
*/
|
||||||
|
typedef void (*lua_Hook) (lua_State *L, lua_Debug *ar);
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -140,7 +153,8 @@ extern const char lua_ident[];
|
||||||
LUA_API lua_State *(lua_newstate) (lua_Alloc f, void *ud);
|
LUA_API lua_State *(lua_newstate) (lua_Alloc f, void *ud);
|
||||||
LUA_API void (lua_close) (lua_State *L);
|
LUA_API void (lua_close) (lua_State *L);
|
||||||
LUA_API lua_State *(lua_newthread) (lua_State *L);
|
LUA_API lua_State *(lua_newthread) (lua_State *L);
|
||||||
LUA_API int (lua_resetthread) (lua_State *L);
|
LUA_API int (lua_closethread) (lua_State *L, lua_State *from);
|
||||||
|
LUA_API int (lua_resetthread) (lua_State *L); /* Deprecated! */
|
||||||
|
|
||||||
LUA_API lua_CFunction (lua_atpanic) (lua_State *L, lua_CFunction panicf);
|
LUA_API lua_CFunction (lua_atpanic) (lua_State *L, lua_CFunction panicf);
|
||||||
|
|
||||||
|
@ -429,12 +443,6 @@ LUA_API void (lua_closeslot) (lua_State *L, int idx);
|
||||||
#define LUA_MASKLINE (1 << LUA_HOOKLINE)
|
#define LUA_MASKLINE (1 << LUA_HOOKLINE)
|
||||||
#define LUA_MASKCOUNT (1 << LUA_HOOKCOUNT)
|
#define LUA_MASKCOUNT (1 << LUA_HOOKCOUNT)
|
||||||
|
|
||||||
typedef struct lua_Debug lua_Debug; /* activation record */
|
|
||||||
|
|
||||||
|
|
||||||
/* Functions to be called by the debugger in specific events */
|
|
||||||
typedef void (*lua_Hook) (lua_State *L, lua_Debug *ar);
|
|
||||||
|
|
||||||
|
|
||||||
LUA_API int (lua_getstack) (lua_State *L, int level, lua_Debug *ar);
|
LUA_API int (lua_getstack) (lua_State *L, int level, lua_Debug *ar);
|
||||||
LUA_API int (lua_getinfo) (lua_State *L, const char *what, lua_Debug *ar);
|
LUA_API int (lua_getinfo) (lua_State *L, const char *what, lua_Debug *ar);
|
||||||
|
@ -477,7 +485,7 @@ struct lua_Debug {
|
||||||
|
|
||||||
/* }====================================================================== */
|
/* }====================================================================== */
|
||||||
|
|
||||||
extern const char *g_lua_path_default;
|
extern const char *g_lua_path_default; // [jart]
|
||||||
|
|
||||||
COSMOPOLITAN_C_END_
|
COSMOPOLITAN_C_END_
|
||||||
#endif /* COSMOPOLITAN_THIRD_PARTY_LUA_LUA_H_ */
|
#endif /* COSMOPOLITAN_THIRD_PARTY_LUA_LUA_H_ */
|
||||||
|
|
67
third_party/lua/lua.main.c
vendored
67
third_party/lua/lua.main.c
vendored
|
@ -3,7 +3,7 @@
|
||||||
╚──────────────────────────────────────────────────────────────────────────────╝
|
╚──────────────────────────────────────────────────────────────────────────────╝
|
||||||
│ │
|
│ │
|
||||||
│ Lua │
|
│ Lua │
|
||||||
│ Copyright © 2004-2021 Lua.org, PUC-Rio. │
|
│ Copyright © 2004-2023 Lua.org, PUC-Rio. │
|
||||||
│ │
|
│ │
|
||||||
│ Permission is hereby granted, free of charge, to any person obtaining │
|
│ Permission is hereby granted, free of charge, to any person obtaining │
|
||||||
│ a copy of this software and associated documentation files (the │
|
│ a copy of this software and associated documentation files (the │
|
||||||
|
@ -26,6 +26,7 @@
|
||||||
│ │
|
│ │
|
||||||
╚─────────────────────────────────────────────────────────────────────────────*/
|
╚─────────────────────────────────────────────────────────────────────────────*/
|
||||||
#define lua_c
|
#define lua_c
|
||||||
|
|
||||||
#include "third_party/lua/lua.h"
|
#include "third_party/lua/lua.h"
|
||||||
#include "libc/calls/calls.h"
|
#include "libc/calls/calls.h"
|
||||||
#include "libc/calls/struct/sigaction.h"
|
#include "libc/calls/struct/sigaction.h"
|
||||||
|
@ -52,6 +53,7 @@
|
||||||
#include "tool/args/args.h"
|
#include "tool/args/args.h"
|
||||||
__static_yoink("lua_notice");
|
__static_yoink("lua_notice");
|
||||||
|
|
||||||
|
|
||||||
STATIC_STACK_ALIGN(GetStackSize());
|
STATIC_STACK_ALIGN(GetStackSize());
|
||||||
|
|
||||||
#if !defined(LUA_PROGNAME)
|
#if !defined(LUA_PROGNAME)
|
||||||
|
@ -81,7 +83,8 @@ static void print_usage (const char *badoption) {
|
||||||
"Available options are:\n"
|
"Available options are:\n"
|
||||||
" -e stat execute string 'stat'\n"
|
" -e stat execute string 'stat'\n"
|
||||||
" -i enter interactive mode after executing 'script'\n"
|
" -i enter interactive mode after executing 'script'\n"
|
||||||
" -l name require library 'name' into global 'name'\n"
|
" -l mod require library 'mod' into global 'mod'\n"
|
||||||
|
" -l g=mod require library 'mod' into global 'g'\n"
|
||||||
" -v show version information\n"
|
" -v show version information\n"
|
||||||
" -E ignore environment variables\n"
|
" -E ignore environment variables\n"
|
||||||
" -W turn warnings on\n"
|
" -W turn warnings on\n"
|
||||||
|
@ -105,10 +108,11 @@ static void print_version (void) {
|
||||||
** to the script (everything after 'script') go to positive indices;
|
** to the script (everything after 'script') go to positive indices;
|
||||||
** other arguments (before the script name) go to negative indices.
|
** other arguments (before the script name) go to negative indices.
|
||||||
** If there is no script name, assume interpreter's name as base.
|
** If there is no script name, assume interpreter's name as base.
|
||||||
|
** (If there is no interpreter's name either, 'script' is -1, so
|
||||||
|
** table sizes are zero.)
|
||||||
*/
|
*/
|
||||||
static void createargtable (lua_State *L, char **argv, int argc, int script) {
|
static void createargtable (lua_State *L, char **argv, int argc, int script) {
|
||||||
int i, narg;
|
int i, narg;
|
||||||
if (script == argc) script = 0; /* no script name? */
|
|
||||||
narg = argc - (script + 1); /* number of positive indices */
|
narg = argc - (script + 1); /* number of positive indices */
|
||||||
lua_createtable(L, narg, script + 1);
|
lua_createtable(L, narg, script + 1);
|
||||||
for (i = 0; i < argc; i++) {
|
for (i = 0; i < argc; i++) {
|
||||||
|
@ -136,16 +140,22 @@ static int dostring (lua_State *L, const char *s, const char *name) {
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
** Calls 'require(name)' and stores the result in a global variable
|
** Receives 'globname[=modname]' and runs 'globname = require(modname)'.
|
||||||
** with the given name.
|
|
||||||
*/
|
*/
|
||||||
static int dolibrary (lua_State *L, const char *name) {
|
static int dolibrary (lua_State *L, char *globname) {
|
||||||
int status;
|
int status;
|
||||||
|
char *modname = strchr(globname, '=');
|
||||||
|
if (modname == NULL) /* no explicit name? */
|
||||||
|
modname = globname; /* module name is equal to global name */
|
||||||
|
else {
|
||||||
|
*modname = '\0'; /* global name ends here */
|
||||||
|
modname++; /* module name starts after the '=' */
|
||||||
|
}
|
||||||
lua_getglobal(L, "require");
|
lua_getglobal(L, "require");
|
||||||
lua_pushstring(L, name);
|
lua_pushstring(L, modname);
|
||||||
status = lua_runchunk(L, 1, 1); /* call 'require(name)' */
|
status = lua_runchunk(L, 1, 1); /* call 'require(modname)' */
|
||||||
if (status == LUA_OK)
|
if (status == LUA_OK)
|
||||||
lua_setglobal(L, name); /* global[name] = require return */
|
lua_setglobal(L, globname); /* globname = require(modname) */
|
||||||
return lua_report(L, status);
|
return lua_report(L, status);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -190,14 +200,23 @@ static int handle_script (lua_State *L, char **argv) {
|
||||||
|
|
||||||
/*
|
/*
|
||||||
** Traverses all arguments from 'argv', returning a mask with those
|
** Traverses all arguments from 'argv', returning a mask with those
|
||||||
** needed before running any Lua code (or an error code if it finds
|
** needed before running any Lua code or an error code if it finds any
|
||||||
** any invalid argument). 'first' returns the first not-handled argument
|
** invalid argument. In case of error, 'first' is the index of the bad
|
||||||
** (either the script name or a bad argument in case of error).
|
** argument. Otherwise, 'first' is -1 if there is no program name,
|
||||||
|
** 0 if there is no script name, or the index of the script name.
|
||||||
*/
|
*/
|
||||||
static int collectargs (char **argv, int *first) {
|
static int collectargs (char **argv, int *first) {
|
||||||
int args = 0;
|
int args = 0;
|
||||||
int i;
|
int i;
|
||||||
for (i = 1; argv[i] != NULL; i++) {
|
if (argv[0] != NULL) { /* is there a program name? */
|
||||||
|
if (argv[0][0]) /* not empty? */
|
||||||
|
lua_progname = argv[0]; /* save it */
|
||||||
|
}
|
||||||
|
else { /* no program name */
|
||||||
|
*first = -1;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
for (i = 1; argv[i] != NULL; i++) { /* handle arguments */
|
||||||
*first = i;
|
*first = i;
|
||||||
if (argv[i][0] != '-') /* not an option? */
|
if (argv[i][0] != '-') /* not an option? */
|
||||||
return args; /* stop handling options */
|
return args; /* stop handling options */
|
||||||
|
@ -238,7 +257,7 @@ static int collectargs (char **argv, int *first) {
|
||||||
return has_error;
|
return has_error;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
*first = i; /* no script name */
|
*first = 0; /* no script name */
|
||||||
return args;
|
return args;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -256,7 +275,7 @@ static int runargs (lua_State *L, char **argv, int n) {
|
||||||
switch (option) {
|
switch (option) {
|
||||||
case 'e': case 'l': {
|
case 'e': case 'l': {
|
||||||
int status;
|
int status;
|
||||||
const char *extra = argv[i] + 2; /* both options need an argument */
|
char *extra = argv[i] + 2; /* both options need an argument */
|
||||||
if (*extra == '\0') extra = argv[++i];
|
if (*extra == '\0') extra = argv[++i];
|
||||||
lua_assert(extra != NULL);
|
lua_assert(extra != NULL);
|
||||||
status = (option == 'e')
|
status = (option == 'e')
|
||||||
|
@ -344,9 +363,8 @@ static int pmain (lua_State *L) {
|
||||||
char **argv = (char **)lua_touserdata(L, 2);
|
char **argv = (char **)lua_touserdata(L, 2);
|
||||||
int script;
|
int script;
|
||||||
int args = collectargs(argv, &script);
|
int args = collectargs(argv, &script);
|
||||||
|
int optlim = (script > 0) ? script : argc; /* first argv not an option */
|
||||||
luaL_checkversion(L); /* check that interpreter has correct version */
|
luaL_checkversion(L); /* check that interpreter has correct version */
|
||||||
lua_progname = LUA_PROGNAME;
|
|
||||||
if (argv[0] && argv[0][0]) lua_progname = argv[0];
|
|
||||||
if (args == has_error) { /* bad arg? */
|
if (args == has_error) { /* bad arg? */
|
||||||
print_usage(argv[script]); /* 'script' has index of bad arg. */
|
print_usage(argv[script]); /* 'script' has index of bad arg. */
|
||||||
return 0;
|
return 0;
|
||||||
|
@ -361,19 +379,21 @@ static int pmain (lua_State *L) {
|
||||||
luaL_requiref(L, "unix", LuaUnix, 1);
|
luaL_requiref(L, "unix", LuaUnix, 1);
|
||||||
lua_pop(L, 1);
|
lua_pop(L, 1);
|
||||||
createargtable(L, argv, argc, script); /* create table 'arg' */
|
createargtable(L, argv, argc, script); /* create table 'arg' */
|
||||||
lua_gc(L, LUA_GCGEN, 0, 0); /* GC in generational mode */
|
lua_gc(L, LUA_GCRESTART); /* start GC... */
|
||||||
|
lua_gc(L, LUA_GCGEN, 0, 0); /* ...in generational mode */
|
||||||
if (!(args & has_E)) { /* no option '-E'? */
|
if (!(args & has_E)) { /* no option '-E'? */
|
||||||
if (handle_luainit(L) != LUA_OK) /* run LUA_INIT */
|
if (handle_luainit(L) != LUA_OK) /* run LUA_INIT */
|
||||||
return 0; /* error running LUA_INIT */
|
return 0; /* error running LUA_INIT */
|
||||||
}
|
}
|
||||||
if (!runargs(L, argv, script)) /* execute arguments -e and -l */
|
if (!runargs(L, argv, optlim)) /* execute arguments -e and -l */
|
||||||
return 0; /* something failed */
|
return 0; /* something failed */
|
||||||
if (script < argc && /* execute main script (if there is one) */
|
if (script > 0) { /* execute main script (if there is one) */
|
||||||
handle_script(L, argv + script) != LUA_OK)
|
if (handle_script(L, argv + script) != LUA_OK)
|
||||||
return 0;
|
return 0; /* interrupt in case of error */
|
||||||
|
}
|
||||||
if (args & has_i) /* -i option? */
|
if (args & has_i) /* -i option? */
|
||||||
doREPL(L); /* do read-eval-print loop */
|
doREPL(L); /* do read-eval-print loop */
|
||||||
else if (script == argc && !(args & (has_e | has_v))) { /* no arguments? */
|
else if (script < 1 && !(args & (has_e | has_v))) { /* no active option? */
|
||||||
if (lua_stdin_is_tty()) { /* running in interactive mode? */
|
if (lua_stdin_is_tty()) { /* running in interactive mode? */
|
||||||
print_version();
|
print_version();
|
||||||
doREPL(L); /* do read-eval-print loop */
|
doREPL(L); /* do read-eval-print loop */
|
||||||
|
@ -397,6 +417,7 @@ int main (int argc, char **argv) {
|
||||||
lua_l_message(argv[0], "cannot create state: not enough memory");
|
lua_l_message(argv[0], "cannot create state: not enough memory");
|
||||||
return EXIT_FAILURE;
|
return EXIT_FAILURE;
|
||||||
}
|
}
|
||||||
|
lua_gc(L, LUA_GCSTOP); /* stop GC while building state */
|
||||||
lua_pushcfunction(L, &pmain); /* to call 'pmain' in protected mode */
|
lua_pushcfunction(L, &pmain); /* to call 'pmain' in protected mode */
|
||||||
lua_pushinteger(L, argc); /* 1st argument */
|
lua_pushinteger(L, argc); /* 1st argument */
|
||||||
lua_pushlightuserdata(L, argv); /* 2nd argument */
|
lua_pushlightuserdata(L, argv); /* 2nd argument */
|
||||||
|
|
15
third_party/lua/luac.main.c
vendored
15
third_party/lua/luac.main.c
vendored
|
@ -3,7 +3,7 @@
|
||||||
╚──────────────────────────────────────────────────────────────────────────────╝
|
╚──────────────────────────────────────────────────────────────────────────────╝
|
||||||
│ │
|
│ │
|
||||||
│ Lua │
|
│ Lua │
|
||||||
│ Copyright © 2004-2021 Lua.org, PUC-Rio. │
|
│ Copyright © 2004-2023 Lua.org, PUC-Rio. │
|
||||||
│ │
|
│ │
|
||||||
│ Permission is hereby granted, free of charge, to any person obtaining │
|
│ Permission is hereby granted, free of charge, to any person obtaining │
|
||||||
│ a copy of this software and associated documentation files (the │
|
│ a copy of this software and associated documentation files (the │
|
||||||
|
@ -27,6 +27,7 @@
|
||||||
╚─────────────────────────────────────────────────────────────────────────────*/
|
╚─────────────────────────────────────────────────────────────────────────────*/
|
||||||
#define luac_c
|
#define luac_c
|
||||||
#define LUA_CORE
|
#define LUA_CORE
|
||||||
|
|
||||||
#include "libc/calls/calls.h"
|
#include "libc/calls/calls.h"
|
||||||
#include "libc/calls/struct/sigaction.h"
|
#include "libc/calls/struct/sigaction.h"
|
||||||
#include "libc/errno.h"
|
#include "libc/errno.h"
|
||||||
|
@ -45,6 +46,7 @@
|
||||||
#include "third_party/lua/lundump.h"
|
#include "third_party/lua/lundump.h"
|
||||||
__static_yoink("lua_notice");
|
__static_yoink("lua_notice");
|
||||||
|
|
||||||
|
|
||||||
static void PrintFunction(const Proto* f, int full);
|
static void PrintFunction(const Proto* f, int full);
|
||||||
#define luaU_print PrintFunction
|
#define luaU_print PrintFunction
|
||||||
|
|
||||||
|
@ -141,7 +143,7 @@ static int doargs(int argc, char* argv[])
|
||||||
return i;
|
return i;
|
||||||
}
|
}
|
||||||
|
|
||||||
#define FUNCTION "(function()end)();"
|
#define FUNCTION "(function()end)();\n"
|
||||||
|
|
||||||
static const char* reader(lua_State* L, void* ud, size_t* size)
|
static const char* reader(lua_State* L, void* ud, size_t* size)
|
||||||
{
|
{
|
||||||
|
@ -158,7 +160,7 @@ static const char* reader(lua_State* L, void* ud, size_t* size)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#define toproto(L,i) getproto(s2v(L->top+(i)))
|
#define toproto(L,i) getproto(s2v(L->top.p+(i)))
|
||||||
|
|
||||||
static const Proto* combine(lua_State* L, int n)
|
static const Proto* combine(lua_State* L, int n)
|
||||||
{
|
{
|
||||||
|
@ -175,7 +177,6 @@ static const Proto* combine(lua_State* L, int n)
|
||||||
f->p[i]=toproto(L,i-n-1);
|
f->p[i]=toproto(L,i-n-1);
|
||||||
if (f->p[i]->sizeupvalues>0) f->p[i]->upvalues[0].instack=0;
|
if (f->p[i]->sizeupvalues>0) f->p[i]->upvalues[0].instack=0;
|
||||||
}
|
}
|
||||||
f->sizelineinfo=0;
|
|
||||||
return f;
|
return f;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -620,11 +621,11 @@ static void PrintCode(const Proto* f)
|
||||||
if (c==0) printf("all out"); else printf("%d out",c-1);
|
if (c==0) printf("all out"); else printf("%d out",c-1);
|
||||||
break;
|
break;
|
||||||
case OP_TAILCALL:
|
case OP_TAILCALL:
|
||||||
printf("%d %d %d",a,b,c);
|
printf("%d %d %d%s",a,b,c,ISK);
|
||||||
printf(COMMENT "%d in",b-1);
|
printf(COMMENT "%d in",b-1);
|
||||||
break;
|
break;
|
||||||
case OP_RETURN:
|
case OP_RETURN:
|
||||||
printf("%d %d %d",a,b,c);
|
printf("%d %d %d%s",a,b,c,ISK);
|
||||||
printf(COMMENT);
|
printf(COMMENT);
|
||||||
if (b==0) printf("all out"); else printf("%d out",b-1);
|
if (b==0) printf("all out"); else printf("%d out",b-1);
|
||||||
break;
|
break;
|
||||||
|
@ -639,7 +640,7 @@ static void PrintCode(const Proto* f)
|
||||||
break;
|
break;
|
||||||
case OP_FORPREP:
|
case OP_FORPREP:
|
||||||
printf("%d %d",a,bx);
|
printf("%d %d",a,bx);
|
||||||
printf(COMMENT "to %d",pc+bx+2);
|
printf(COMMENT "exit to %d",pc+bx+3);
|
||||||
break;
|
break;
|
||||||
case OP_TFORPREP:
|
case OP_TFORPREP:
|
||||||
printf("%d %d",a,bx);
|
printf("%d %d",a,bx);
|
||||||
|
|
21
third_party/lua/luaconf.h
vendored
21
third_party/lua/luaconf.h
vendored
|
@ -1,5 +1,6 @@
|
||||||
#ifndef luaconf_h
|
#ifndef luaconf_h
|
||||||
#define luaconf_h
|
#define luaconf_h
|
||||||
|
|
||||||
#include "libc/assert.h"
|
#include "libc/assert.h"
|
||||||
#include "libc/dce.h"
|
#include "libc/dce.h"
|
||||||
#include "libc/fmt/conv.h"
|
#include "libc/fmt/conv.h"
|
||||||
|
@ -7,8 +8,9 @@
|
||||||
#include "libc/stdio/stdio.h"
|
#include "libc/stdio/stdio.h"
|
||||||
#include "libc/str/unicode.h"
|
#include "libc/str/unicode.h"
|
||||||
|
|
||||||
#define LUA_USE_POSIX
|
|
||||||
#define LUA_USE_LINENOISE
|
#define LUA_USE_LINENOISE
|
||||||
|
#define LUA_USE_POSIX
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -69,6 +71,12 @@
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
#if defined(LUA_USE_IOS)
|
||||||
|
#define LUA_USE_POSIX
|
||||||
|
#define LUA_USE_DLOPEN
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@@ LUAI_IS32INT is true iff 'int' has (at least) 32 bits.
|
@@ LUAI_IS32INT is true iff 'int' has (at least) 32 bits.
|
||||||
*/
|
*/
|
||||||
|
@ -422,7 +430,6 @@
|
||||||
@@ LUA_MAXINTEGER is the maximum value for a LUA_INTEGER.
|
@@ LUA_MAXINTEGER is the maximum value for a LUA_INTEGER.
|
||||||
@@ LUA_MININTEGER is the minimum value for a LUA_INTEGER.
|
@@ LUA_MININTEGER is the minimum value for a LUA_INTEGER.
|
||||||
@@ LUA_MAXUNSIGNED is the maximum value for a LUA_UNSIGNED.
|
@@ LUA_MAXUNSIGNED is the maximum value for a LUA_UNSIGNED.
|
||||||
@@ LUA_UNSIGNEDBITS is the number of bits in a LUA_UNSIGNED.
|
|
||||||
@@ lua_integer2str converts an integer to a string.
|
@@ lua_integer2str converts an integer to a string.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
@ -443,9 +450,6 @@
|
||||||
#define LUA_UNSIGNED unsigned LUAI_UACINT
|
#define LUA_UNSIGNED unsigned LUAI_UACINT
|
||||||
|
|
||||||
|
|
||||||
#define LUA_UNSIGNEDBITS (sizeof(LUA_UNSIGNED) * CHAR_BIT)
|
|
||||||
|
|
||||||
|
|
||||||
/* now the variable definitions */
|
/* now the variable definitions */
|
||||||
|
|
||||||
#if LUA_INT_TYPE == LUA_INT_INT /* { int */
|
#if LUA_INT_TYPE == LUA_INT_INT /* { int */
|
||||||
|
@ -667,7 +671,7 @@
|
||||||
** CHANGE it if you need a different limit. This limit is arbitrary;
|
** CHANGE it if you need a different limit. This limit is arbitrary;
|
||||||
** its only purpose is to stop Lua from consuming unlimited stack
|
** its only purpose is to stop Lua from consuming unlimited stack
|
||||||
** space (and to reserve some numbers for pseudo-indices).
|
** space (and to reserve some numbers for pseudo-indices).
|
||||||
** (It must fit into max(size_t)/32.)
|
** (It must fit into max(size_t)/32 and max(int)/2.)
|
||||||
*/
|
*/
|
||||||
#if LUAI_IS32INT
|
#if LUAI_IS32INT
|
||||||
#define LUAI_MAXSTACK 1000000
|
#define LUAI_MAXSTACK 1000000
|
||||||
|
@ -686,14 +690,15 @@
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@@ LUA_IDSIZE gives the maximum size for the description of the source
|
@@ LUA_IDSIZE gives the maximum size for the description of the source
|
||||||
@@ of a function in debug information.
|
** of a function in debug information.
|
||||||
** CHANGE it if you want a different size.
|
** CHANGE it if you want a different size.
|
||||||
*/
|
*/
|
||||||
#define LUA_IDSIZE 60
|
#define LUA_IDSIZE 60
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@@ LUAL_BUFFERSIZE is the buffer size used by the lauxlib buffer system.
|
@@ LUAL_BUFFERSIZE is the initial buffer size used by the lauxlib
|
||||||
|
** buffer system.
|
||||||
*/
|
*/
|
||||||
#define LUAL_BUFFERSIZE ((int)(16 * sizeof(void*) * sizeof(lua_Number)))
|
#define LUAL_BUFFERSIZE ((int)(16 * sizeof(void*) * sizeof(lua_Number)))
|
||||||
|
|
||||||
|
|
1
third_party/lua/lualib.h
vendored
1
third_party/lua/lualib.h
vendored
|
@ -1,5 +1,6 @@
|
||||||
#ifndef lualib_h
|
#ifndef lualib_h
|
||||||
#define lualib_h
|
#define lualib_h
|
||||||
|
|
||||||
#include "third_party/lua/lua.h"
|
#include "third_party/lua/lua.h"
|
||||||
|
|
||||||
|
|
||||||
|
|
42
third_party/lua/lundump.c
vendored
42
third_party/lua/lundump.c
vendored
|
@ -1,9 +1,30 @@
|
||||||
/*
|
/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│
|
||||||
** $Id: lundump.c $
|
│vi: set et ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi│
|
||||||
** load precompiled Lua chunks
|
╚──────────────────────────────────────────────────────────────────────────────╝
|
||||||
** See Copyright Notice in lua.h
|
│ │
|
||||||
*/
|
│ Lua │
|
||||||
|
│ Copyright © 2004-2023 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 │
|
||||||
|
│ "Software"), to deal in the Software without restriction, including │
|
||||||
|
│ without limitation the rights to use, copy, modify, merge, publish, │
|
||||||
|
│ distribute, sublicense, and/or sell copies of the Software, and to │
|
||||||
|
│ permit persons to whom the Software is furnished to do so, subject to │
|
||||||
|
│ the following conditions: │
|
||||||
|
│ │
|
||||||
|
│ The above copyright notice and this permission notice shall be │
|
||||||
|
│ included in all copies or substantial portions of the Software. │
|
||||||
|
│ │
|
||||||
|
│ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, │
|
||||||
|
│ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF │
|
||||||
|
│ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. │
|
||||||
|
│ IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY │
|
||||||
|
│ CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, │
|
||||||
|
│ TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE │
|
||||||
|
│ SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. │
|
||||||
|
│ │
|
||||||
|
╚─────────────────────────────────────────────────────────────────────────────*/
|
||||||
#define lundump_c
|
#define lundump_c
|
||||||
#define LUA_CORE
|
#define LUA_CORE
|
||||||
|
|
||||||
|
@ -18,6 +39,7 @@
|
||||||
#include "third_party/lua/lua.h"
|
#include "third_party/lua/lua.h"
|
||||||
#include "third_party/lua/lundump.h"
|
#include "third_party/lua/lundump.h"
|
||||||
#include "third_party/lua/lzio.h"
|
#include "third_party/lua/lzio.h"
|
||||||
|
__static_yoink("lua_notice");
|
||||||
|
|
||||||
|
|
||||||
#if !defined(luai_verifycode)
|
#if !defined(luai_verifycode)
|
||||||
|
@ -115,10 +137,10 @@ static TString *loadStringN (LoadState *S, Proto *p) {
|
||||||
}
|
}
|
||||||
else { /* long string */
|
else { /* long string */
|
||||||
ts = luaS_createlngstrobj(L, size); /* create string */
|
ts = luaS_createlngstrobj(L, size); /* create string */
|
||||||
setsvalue2s(L, L->top, ts); /* anchor it ('loadVector' can GC) */
|
setsvalue2s(L, L->top.p, ts); /* anchor it ('loadVector' can GC) */
|
||||||
luaD_inctop(L);
|
luaD_inctop(L);
|
||||||
loadVector(S, getstr(ts), size); /* load directly in final place */
|
loadVector(S, getstr(ts), size); /* load directly in final place */
|
||||||
L->top--; /* pop string */
|
L->top.p--; /* pop string */
|
||||||
}
|
}
|
||||||
luaC_objbarrier(L, p, ts);
|
luaC_objbarrier(L, p, ts);
|
||||||
return ts;
|
return ts;
|
||||||
|
@ -243,6 +265,8 @@ static void loadDebug (LoadState *S, Proto *f) {
|
||||||
f->locvars[i].endpc = loadInt(S);
|
f->locvars[i].endpc = loadInt(S);
|
||||||
}
|
}
|
||||||
n = loadInt(S);
|
n = loadInt(S);
|
||||||
|
if (n != 0) /* does it have debug information? */
|
||||||
|
n = f->sizeupvalues; /* must be this many */
|
||||||
for (i = 0; i < n; i++)
|
for (i = 0; i < n; i++)
|
||||||
f->upvalues[i].name = loadStringN(S, f);
|
f->upvalues[i].name = loadStringN(S, f);
|
||||||
}
|
}
|
||||||
|
@ -316,7 +340,7 @@ LClosure *luaU_undump(lua_State *L, ZIO *Z, const char *name) {
|
||||||
S.Z = Z;
|
S.Z = Z;
|
||||||
checkHeader(&S);
|
checkHeader(&S);
|
||||||
cl = luaF_newLclosure(L, loadByte(&S));
|
cl = luaF_newLclosure(L, loadByte(&S));
|
||||||
setclLvalue2s(L, L->top, cl);
|
setclLvalue2s(L, L->top.p, cl);
|
||||||
luaD_inctop(L);
|
luaD_inctop(L);
|
||||||
cl->p = luaF_newproto(L);
|
cl->p = luaF_newproto(L);
|
||||||
luaC_objbarrier(L, cl, cl->p);
|
luaC_objbarrier(L, cl, cl->p);
|
||||||
|
|
1
third_party/lua/lundump.h
vendored
1
third_party/lua/lundump.h
vendored
|
@ -1,5 +1,6 @@
|
||||||
#ifndef lundump_h
|
#ifndef lundump_h
|
||||||
#define lundump_h
|
#define lundump_h
|
||||||
|
|
||||||
#include "third_party/lua/llimits.h"
|
#include "third_party/lua/llimits.h"
|
||||||
#include "third_party/lua/lobject.h"
|
#include "third_party/lua/lobject.h"
|
||||||
#include "third_party/lua/lzio.h"
|
#include "third_party/lua/lzio.h"
|
||||||
|
|
70
third_party/lua/lutf8lib.c
vendored
70
third_party/lua/lutf8lib.c
vendored
|
@ -1,9 +1,30 @@
|
||||||
/*
|
/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│
|
||||||
** $Id: lutf8lib.c $
|
│vi: set et ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi│
|
||||||
** Standard library for UTF-8 manipulation
|
╚──────────────────────────────────────────────────────────────────────────────╝
|
||||||
** See Copyright Notice in lua.h
|
│ │
|
||||||
*/
|
│ Lua │
|
||||||
|
│ Copyright © 2004-2023 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 │
|
||||||
|
│ "Software"), to deal in the Software without restriction, including │
|
||||||
|
│ without limitation the rights to use, copy, modify, merge, publish, │
|
||||||
|
│ distribute, sublicense, and/or sell copies of the Software, and to │
|
||||||
|
│ permit persons to whom the Software is furnished to do so, subject to │
|
||||||
|
│ the following conditions: │
|
||||||
|
│ │
|
||||||
|
│ The above copyright notice and this permission notice shall be │
|
||||||
|
│ included in all copies or substantial portions of the Software. │
|
||||||
|
│ │
|
||||||
|
│ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, │
|
||||||
|
│ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF │
|
||||||
|
│ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. │
|
||||||
|
│ IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY │
|
||||||
|
│ CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, │
|
||||||
|
│ TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE │
|
||||||
|
│ SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. │
|
||||||
|
│ │
|
||||||
|
╚─────────────────────────────────────────────────────────────────────────────*/
|
||||||
#define lutf8lib_c
|
#define lutf8lib_c
|
||||||
#define LUA_LIB
|
#define LUA_LIB
|
||||||
|
|
||||||
|
@ -11,12 +32,16 @@
|
||||||
#include "third_party/lua/lprefix.h"
|
#include "third_party/lua/lprefix.h"
|
||||||
#include "third_party/lua/lua.h"
|
#include "third_party/lua/lua.h"
|
||||||
#include "third_party/lua/lualib.h"
|
#include "third_party/lua/lualib.h"
|
||||||
|
__static_yoink("lua_notice");
|
||||||
|
|
||||||
|
|
||||||
#define MAXUNICODE 0x10FFFFu
|
#define MAXUNICODE 0x10FFFFu
|
||||||
|
|
||||||
#define MAXUTF 0x7FFFFFFFu
|
#define MAXUTF 0x7FFFFFFFu
|
||||||
|
|
||||||
|
|
||||||
|
#define MSGInvalid "invalid UTF-8 code"
|
||||||
|
|
||||||
/*
|
/*
|
||||||
** Integer type for decoded UTF-8 values; MAXUTF needs 31 bits.
|
** Integer type for decoded UTF-8 values; MAXUTF needs 31 bits.
|
||||||
*/
|
*/
|
||||||
|
@ -27,7 +52,8 @@ typedef unsigned long utfint;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
||||||
#define iscont(p) ((*(p) & 0xC0) == 0x80)
|
#define iscont(c) (((c) & 0xC0) == 0x80)
|
||||||
|
#define iscontp(p) iscont(*(p))
|
||||||
|
|
||||||
|
|
||||||
/* from strlib */
|
/* from strlib */
|
||||||
|
@ -57,7 +83,7 @@ static const char *utf8_decode (const char *s, utfint *val, int strict) {
|
||||||
int count = 0; /* to count number of continuation bytes */
|
int count = 0; /* to count number of continuation bytes */
|
||||||
for (; c & 0x40; c <<= 1) { /* while it needs continuation bytes... */
|
for (; c & 0x40; c <<= 1) { /* while it needs continuation bytes... */
|
||||||
unsigned int cc = (unsigned char)s[++count]; /* read next byte */
|
unsigned int cc = (unsigned char)s[++count]; /* read next byte */
|
||||||
if ((cc & 0xC0) != 0x80) /* not a continuation byte? */
|
if (!iscont(cc)) /* not a continuation byte? */
|
||||||
return NULL; /* invalid byte sequence */
|
return NULL; /* invalid byte sequence */
|
||||||
res = (res << 6) | (cc & 0x3F); /* add lower 6 bits from cont. byte */
|
res = (res << 6) | (cc & 0x3F); /* add lower 6 bits from cont. byte */
|
||||||
}
|
}
|
||||||
|
@ -132,7 +158,7 @@ static int codepoint (lua_State *L) {
|
||||||
utfint code;
|
utfint code;
|
||||||
s = utf8_decode(s, &code, !lax);
|
s = utf8_decode(s, &code, !lax);
|
||||||
if (s == NULL)
|
if (s == NULL)
|
||||||
return luaL_error(L, "invalid UTF-8 code");
|
return luaL_error(L, MSGInvalid);
|
||||||
lua_pushinteger(L, code);
|
lua_pushinteger(L, code);
|
||||||
n++;
|
n++;
|
||||||
}
|
}
|
||||||
|
@ -182,16 +208,16 @@ static int byteoffset (lua_State *L) {
|
||||||
"position out of bounds");
|
"position out of bounds");
|
||||||
if (n == 0) {
|
if (n == 0) {
|
||||||
/* find beginning of current byte sequence */
|
/* find beginning of current byte sequence */
|
||||||
while (posi > 0 && iscont(s + posi)) posi--;
|
while (posi > 0 && iscontp(s + posi)) posi--;
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
if (iscont(s + posi))
|
if (iscontp(s + posi))
|
||||||
return luaL_error(L, "initial position is a continuation byte");
|
return luaL_error(L, "initial position is a continuation byte");
|
||||||
if (n < 0) {
|
if (n < 0) {
|
||||||
while (n < 0 && posi > 0) { /* move back */
|
while (n < 0 && posi > 0) { /* move back */
|
||||||
do { /* find beginning of previous character */
|
do { /* find beginning of previous character */
|
||||||
posi--;
|
posi--;
|
||||||
} while (posi > 0 && iscont(s + posi));
|
} while (posi > 0 && iscontp(s + posi));
|
||||||
n++;
|
n++;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -200,7 +226,7 @@ static int byteoffset (lua_State *L) {
|
||||||
while (n > 0 && posi < (lua_Integer)len) {
|
while (n > 0 && posi < (lua_Integer)len) {
|
||||||
do { /* find beginning of next character */
|
do { /* find beginning of next character */
|
||||||
posi++;
|
posi++;
|
||||||
} while (iscont(s + posi)); /* (cannot pass final '\0') */
|
} while (iscontp(s + posi)); /* (cannot pass final '\0') */
|
||||||
n--;
|
n--;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -216,20 +242,17 @@ static int byteoffset (lua_State *L) {
|
||||||
static int iter_aux (lua_State *L, int strict) {
|
static int iter_aux (lua_State *L, int strict) {
|
||||||
size_t len;
|
size_t len;
|
||||||
const char *s = luaL_checklstring(L, 1, &len);
|
const char *s = luaL_checklstring(L, 1, &len);
|
||||||
lua_Integer n = lua_tointeger(L, 2) - 1;
|
lua_Unsigned n = (lua_Unsigned)lua_tointeger(L, 2);
|
||||||
if (n < 0) /* first iteration? */
|
if (n < len) {
|
||||||
n = 0; /* start from here */
|
while (iscontp(s + n)) n++; /* go to next character */
|
||||||
else if (n < (lua_Integer)len) {
|
|
||||||
n++; /* skip current byte */
|
|
||||||
while (iscont(s + n)) n++; /* and its continuations */
|
|
||||||
}
|
}
|
||||||
if (n >= (lua_Integer)len)
|
if (n >= len) /* (also handles original 'n' being negative) */
|
||||||
return 0; /* no more codepoints */
|
return 0; /* no more codepoints */
|
||||||
else {
|
else {
|
||||||
utfint code;
|
utfint code;
|
||||||
const char *next = utf8_decode(s + n, &code, strict);
|
const char *next = utf8_decode(s + n, &code, strict);
|
||||||
if (next == NULL)
|
if (next == NULL || iscontp(next))
|
||||||
return luaL_error(L, "invalid UTF-8 code");
|
return luaL_error(L, MSGInvalid);
|
||||||
lua_pushinteger(L, n + 1);
|
lua_pushinteger(L, n + 1);
|
||||||
lua_pushinteger(L, code);
|
lua_pushinteger(L, code);
|
||||||
return 2;
|
return 2;
|
||||||
|
@ -248,7 +271,8 @@ static int iter_auxlax (lua_State *L) {
|
||||||
|
|
||||||
static int iter_codes (lua_State *L) {
|
static int iter_codes (lua_State *L) {
|
||||||
int lax = lua_toboolean(L, 2);
|
int lax = lua_toboolean(L, 2);
|
||||||
luaL_checkstring(L, 1);
|
const char *s = luaL_checkstring(L, 1);
|
||||||
|
luaL_argcheck(L, !iscontp(s), 1, MSGInvalid);
|
||||||
lua_pushcfunction(L, lax ? iter_auxlax : iter_auxstrict);
|
lua_pushcfunction(L, lax ? iter_auxlax : iter_auxstrict);
|
||||||
lua_pushvalue(L, 1);
|
lua_pushvalue(L, 1);
|
||||||
lua_pushinteger(L, 0);
|
lua_pushinteger(L, 0);
|
||||||
|
|
234
third_party/lua/lvm.c
vendored
234
third_party/lua/lvm.c
vendored
|
@ -3,7 +3,7 @@
|
||||||
╚──────────────────────────────────────────────────────────────────────────────╝
|
╚──────────────────────────────────────────────────────────────────────────────╝
|
||||||
│ │
|
│ │
|
||||||
│ Lua │
|
│ Lua │
|
||||||
│ Copyright © 2004-2021 Lua.org, PUC-Rio. │
|
│ Copyright © 2004-2023 Lua.org, PUC-Rio. │
|
||||||
│ │
|
│ │
|
||||||
│ Permission is hereby granted, free of charge, to any person obtaining │
|
│ Permission is hereby granted, free of charge, to any person obtaining │
|
||||||
│ a copy of this software and associated documentation files (the │
|
│ a copy of this software and associated documentation files (the │
|
||||||
|
@ -27,6 +27,7 @@
|
||||||
╚─────────────────────────────────────────────────────────────────────────────*/
|
╚─────────────────────────────────────────────────────────────────────────────*/
|
||||||
#define lvm_c
|
#define lvm_c
|
||||||
#define LUA_CORE
|
#define LUA_CORE
|
||||||
|
|
||||||
#include "libc/str/str.h"
|
#include "libc/str/str.h"
|
||||||
#include "third_party/lua/ldebug.h"
|
#include "third_party/lua/ldebug.h"
|
||||||
#include "third_party/lua/ldo.h"
|
#include "third_party/lua/ldo.h"
|
||||||
|
@ -419,7 +420,7 @@ static int l_strcmp (const TString *ls, const TString *rs) {
|
||||||
** from float to int.)
|
** from float to int.)
|
||||||
** When 'f' is NaN, comparisons must result in false.
|
** When 'f' is NaN, comparisons must result in false.
|
||||||
*/
|
*/
|
||||||
static int LTintfloat (lua_Integer i, lua_Number f) {
|
l_sinline int LTintfloat (lua_Integer i, lua_Number f) {
|
||||||
if (l_intfitsf(i))
|
if (l_intfitsf(i))
|
||||||
return luai_numlt(cast_num(i), f); /* compare them as floats */
|
return luai_numlt(cast_num(i), f); /* compare them as floats */
|
||||||
else { /* i < f <=> i < ceil(f) */
|
else { /* i < f <=> i < ceil(f) */
|
||||||
|
@ -436,7 +437,7 @@ static int LTintfloat (lua_Integer i, lua_Number f) {
|
||||||
** Check whether integer 'i' is less than or equal to float 'f'.
|
** Check whether integer 'i' is less than or equal to float 'f'.
|
||||||
** See comments on previous function.
|
** See comments on previous function.
|
||||||
*/
|
*/
|
||||||
static int LEintfloat (lua_Integer i, lua_Number f) {
|
l_sinline int LEintfloat (lua_Integer i, lua_Number f) {
|
||||||
if (l_intfitsf(i))
|
if (l_intfitsf(i))
|
||||||
return luai_numle(cast_num(i), f); /* compare them as floats */
|
return luai_numle(cast_num(i), f); /* compare them as floats */
|
||||||
else { /* i <= f <=> i <= floor(f) */
|
else { /* i <= f <=> i <= floor(f) */
|
||||||
|
@ -453,7 +454,7 @@ static int LEintfloat (lua_Integer i, lua_Number f) {
|
||||||
** Check whether float 'f' is less than integer 'i'.
|
** Check whether float 'f' is less than integer 'i'.
|
||||||
** See comments on previous function.
|
** See comments on previous function.
|
||||||
*/
|
*/
|
||||||
static int LTfloatint (lua_Number f, lua_Integer i) {
|
l_sinline int LTfloatint (lua_Number f, lua_Integer i) {
|
||||||
if (l_intfitsf(i))
|
if (l_intfitsf(i))
|
||||||
return luai_numlt(f, cast_num(i)); /* compare them as floats */
|
return luai_numlt(f, cast_num(i)); /* compare them as floats */
|
||||||
else { /* f < i <=> floor(f) < i */
|
else { /* f < i <=> floor(f) < i */
|
||||||
|
@ -470,7 +471,7 @@ static int LTfloatint (lua_Number f, lua_Integer i) {
|
||||||
** Check whether float 'f' is less than or equal to integer 'i'.
|
** Check whether float 'f' is less than or equal to integer 'i'.
|
||||||
** See comments on previous function.
|
** See comments on previous function.
|
||||||
*/
|
*/
|
||||||
static int LEfloatint (lua_Number f, lua_Integer i) {
|
l_sinline int LEfloatint (lua_Number f, lua_Integer i) {
|
||||||
if (l_intfitsf(i))
|
if (l_intfitsf(i))
|
||||||
return luai_numle(f, cast_num(i)); /* compare them as floats */
|
return luai_numle(f, cast_num(i)); /* compare them as floats */
|
||||||
else { /* f <= i <=> ceil(f) <= i */
|
else { /* f <= i <=> ceil(f) <= i */
|
||||||
|
@ -486,7 +487,7 @@ static int LEfloatint (lua_Number f, lua_Integer i) {
|
||||||
/*
|
/*
|
||||||
** Return 'l < r', for numbers.
|
** Return 'l < r', for numbers.
|
||||||
*/
|
*/
|
||||||
static int LTnum (const TValue *l, const TValue *r) {
|
l_sinline int LTnum (const TValue *l, const TValue *r) {
|
||||||
lua_assert(ttisnumber(l) && ttisnumber(r));
|
lua_assert(ttisnumber(l) && ttisnumber(r));
|
||||||
if (ttisinteger(l)) {
|
if (ttisinteger(l)) {
|
||||||
lua_Integer li = ivalue(l);
|
lua_Integer li = ivalue(l);
|
||||||
|
@ -508,7 +509,7 @@ static int LTnum (const TValue *l, const TValue *r) {
|
||||||
/*
|
/*
|
||||||
** Return 'l <= r', for numbers.
|
** Return 'l <= r', for numbers.
|
||||||
*/
|
*/
|
||||||
static int LEnum (const TValue *l, const TValue *r) {
|
l_sinline int LEnum (const TValue *l, const TValue *r) {
|
||||||
lua_assert(ttisnumber(l) && ttisnumber(r));
|
lua_assert(ttisnumber(l) && ttisnumber(r));
|
||||||
if (ttisinteger(l)) {
|
if (ttisinteger(l)) {
|
||||||
lua_Integer li = ivalue(l);
|
lua_Integer li = ivalue(l);
|
||||||
|
@ -621,8 +622,8 @@ int luaV_equalobj (lua_State *L, const TValue *t1, const TValue *t2) {
|
||||||
if (tm == NULL) /* no TM? */
|
if (tm == NULL) /* no TM? */
|
||||||
return 0; /* objects are different */
|
return 0; /* objects are different */
|
||||||
else {
|
else {
|
||||||
luaT_callTMres(L, tm, t1, t2, L->top); /* call TM */
|
luaT_callTMres(L, tm, t1, t2, L->top.p); /* call TM */
|
||||||
return !l_isfalse(s2v(L->top));
|
return !l_isfalse(s2v(L->top.p));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -646,17 +647,17 @@ static void copy2buff (StkId top, int n, char *buff) {
|
||||||
|
|
||||||
/*
|
/*
|
||||||
** Main operation for concatenation: concat 'total' values in the stack,
|
** Main operation for concatenation: concat 'total' values in the stack,
|
||||||
** from 'L->top - total' up to 'L->top - 1'.
|
** from 'L->top.p - total' up to 'L->top.p - 1'.
|
||||||
*/
|
*/
|
||||||
void luaV_concat (lua_State *L, int total) {
|
void luaV_concat (lua_State *L, int total) {
|
||||||
if (total == 1)
|
if (total == 1)
|
||||||
return; /* "all" values already concatenated */
|
return; /* "all" values already concatenated */
|
||||||
do {
|
do {
|
||||||
StkId top = L->top;
|
StkId top = L->top.p;
|
||||||
int n = 2; /* number of elements handled in this pass (at least 2) */
|
int n = 2; /* number of elements handled in this pass (at least 2) */
|
||||||
if (!(ttisstring(s2v(top - 2)) || cvt2str(s2v(top - 2))) ||
|
if (!(ttisstring(s2v(top - 2)) || cvt2str(s2v(top - 2))) ||
|
||||||
!tostring(L, s2v(top - 1)))
|
!tostring(L, s2v(top - 1)))
|
||||||
luaT_tryconcatTM(L);
|
luaT_tryconcatTM(L); /* may invalidate 'top' */
|
||||||
else if (isemptystr(s2v(top - 1))) /* second operand is empty? */
|
else if (isemptystr(s2v(top - 1))) /* second operand is empty? */
|
||||||
cast_void(tostring(L, s2v(top - 2))); /* result is first operand */
|
cast_void(tostring(L, s2v(top - 2))); /* result is first operand */
|
||||||
else if (isemptystr(s2v(top - 2))) { /* first operand is empty string? */
|
else if (isemptystr(s2v(top - 2))) { /* first operand is empty string? */
|
||||||
|
@ -669,8 +670,10 @@ void luaV_concat (lua_State *L, int total) {
|
||||||
/* collect total length and number of strings */
|
/* collect total length and number of strings */
|
||||||
for (n = 1; n < total && tostring(L, s2v(top - n - 1)); n++) {
|
for (n = 1; n < total && tostring(L, s2v(top - n - 1)); n++) {
|
||||||
size_t l = vslen(s2v(top - n - 1));
|
size_t l = vslen(s2v(top - n - 1));
|
||||||
if (l_unlikely(l >= (MAX_SIZE/sizeof(char)) - tl))
|
if (l_unlikely(l >= (MAX_SIZE/sizeof(char)) - tl)) {
|
||||||
|
L->top.p = top - total; /* pop strings to avoid wasting stack */
|
||||||
luaG_runerror(L, "string length overflow");
|
luaG_runerror(L, "string length overflow");
|
||||||
|
}
|
||||||
tl += l;
|
tl += l;
|
||||||
}
|
}
|
||||||
if (tl <= LUAI_MAXSHORTLEN) { /* is result a short string? */
|
if (tl <= LUAI_MAXSHORTLEN) { /* is result a short string? */
|
||||||
|
@ -684,8 +687,8 @@ void luaV_concat (lua_State *L, int total) {
|
||||||
}
|
}
|
||||||
setsvalue2s(L, top - n, ts); /* create result */
|
setsvalue2s(L, top - n, ts); /* create result */
|
||||||
}
|
}
|
||||||
total -= n-1; /* got 'n' strings to create 1 new */
|
total -= n - 1; /* got 'n' strings to create one new */
|
||||||
L->top -= n-1; /* popped 'n' strings and pushed one */
|
L->top.p -= n - 1; /* popped 'n' strings and pushed one */
|
||||||
} while (total > 1); /* repeat until only 1 result left */
|
} while (total > 1); /* repeat until only 1 result left */
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -776,11 +779,10 @@ lua_Number luaV_modf (lua_State *L, lua_Number m, lua_Number n) {
|
||||||
/* number of bits in an integer */
|
/* number of bits in an integer */
|
||||||
#define NBITS cast_int(sizeof(lua_Integer) * CHAR_BIT)
|
#define NBITS cast_int(sizeof(lua_Integer) * CHAR_BIT)
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
** Shift left operation. (Shift right just negates 'y'.)
|
** Shift left operation. (Shift right just negates 'y'.)
|
||||||
*/
|
*/
|
||||||
#define luaV_shiftr(x,y) luaV_shiftl(x,-(y))
|
|
||||||
|
|
||||||
lua_Integer luaV_shiftl (lua_Integer x, lua_Integer y) {
|
lua_Integer luaV_shiftl (lua_Integer x, lua_Integer y) {
|
||||||
if (y < 0) { /* shift right? */
|
if (y < 0) { /* shift right? */
|
||||||
if (y <= -NBITS) return 0;
|
if (y <= -NBITS) return 0;
|
||||||
|
@ -820,26 +822,26 @@ static void pushclosure (lua_State *L, Proto *p, UpVal **encup, StkId base,
|
||||||
*/
|
*/
|
||||||
void luaV_finishOp (lua_State *L) {
|
void luaV_finishOp (lua_State *L) {
|
||||||
CallInfo *ci = L->ci;
|
CallInfo *ci = L->ci;
|
||||||
StkId base = ci->func + 1;
|
StkId base = ci->func.p + 1;
|
||||||
Instruction inst = *(ci->u.l.savedpc - 1); /* interrupted instruction */
|
Instruction inst = *(ci->u.l.savedpc - 1); /* interrupted instruction */
|
||||||
OpCode op = GET_OPCODE(inst);
|
OpCode op = GET_OPCODE(inst);
|
||||||
switch (op) { /* finish its execution */
|
switch (op) { /* finish its execution */
|
||||||
case OP_MMBIN: case OP_MMBINI: case OP_MMBINK: {
|
case OP_MMBIN: case OP_MMBINI: case OP_MMBINK: {
|
||||||
setobjs2s(L, base + GETARG_A(*(ci->u.l.savedpc - 2)), --L->top);
|
setobjs2s(L, base + GETARG_A(*(ci->u.l.savedpc - 2)), --L->top.p);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case OP_UNM: case OP_BNOT: case OP_LEN:
|
case OP_UNM: case OP_BNOT: case OP_LEN:
|
||||||
case OP_GETTABUP: case OP_GETTABLE: case OP_GETI:
|
case OP_GETTABUP: case OP_GETTABLE: case OP_GETI:
|
||||||
case OP_GETFIELD: case OP_SELF: {
|
case OP_GETFIELD: case OP_SELF: {
|
||||||
setobjs2s(L, base + GETARG_A(inst), --L->top);
|
setobjs2s(L, base + GETARG_A(inst), --L->top.p);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case OP_LT: case OP_LE:
|
case OP_LT: case OP_LE:
|
||||||
case OP_LTI: case OP_LEI:
|
case OP_LTI: case OP_LEI:
|
||||||
case OP_GTI: case OP_GEI:
|
case OP_GTI: case OP_GEI:
|
||||||
case OP_EQ: { /* note that 'OP_EQI'/'OP_EQK' cannot yield */
|
case OP_EQ: { /* note that 'OP_EQI'/'OP_EQK' cannot yield */
|
||||||
int res = !l_isfalse(s2v(L->top - 1));
|
int res = !l_isfalse(s2v(L->top.p - 1));
|
||||||
L->top--;
|
L->top.p--;
|
||||||
#if defined(LUA_COMPAT_LT_LE)
|
#if defined(LUA_COMPAT_LT_LE)
|
||||||
if (ci->callstatus & CIST_LEQ) { /* "<=" using "<" instead? */
|
if (ci->callstatus & CIST_LEQ) { /* "<=" using "<" instead? */
|
||||||
ci->callstatus ^= CIST_LEQ; /* clear mark */
|
ci->callstatus ^= CIST_LEQ; /* clear mark */
|
||||||
|
@ -852,18 +854,27 @@ void luaV_finishOp (lua_State *L) {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case OP_CONCAT: {
|
case OP_CONCAT: {
|
||||||
StkId top = L->top - 1; /* top when 'luaT_tryconcatTM' was called */
|
StkId top = L->top.p - 1; /* top when 'luaT_tryconcatTM' was called */
|
||||||
int a = GETARG_A(inst); /* first element to concatenate */
|
int a = GETARG_A(inst); /* first element to concatenate */
|
||||||
int total = cast_int(top - 1 - (base + a)); /* yet to concatenate */
|
int total = cast_int(top - 1 - (base + a)); /* yet to concatenate */
|
||||||
setobjs2s(L, top - 2, top); /* put TM result in proper position */
|
setobjs2s(L, top - 2, top); /* put TM result in proper position */
|
||||||
L->top = top - 1; /* top is one after last element (at top-2) */
|
L->top.p = top - 1; /* top is one after last element (at top-2) */
|
||||||
luaV_concat(L, total); /* concat them (may yield again) */
|
luaV_concat(L, total); /* concat them (may yield again) */
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case OP_CLOSE: case OP_RETURN: { /* yielded closing variables */
|
case OP_CLOSE: { /* yielded closing variables */
|
||||||
ci->u.l.savedpc--; /* repeat instruction to close other vars. */
|
ci->u.l.savedpc--; /* repeat instruction to close other vars. */
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
case OP_RETURN: { /* yielded closing variables */
|
||||||
|
StkId ra = base + GETARG_A(inst);
|
||||||
|
/* adjust top to signal correct number of returns, in case the
|
||||||
|
return is "up to top" ('isIT') */
|
||||||
|
L->top.p = ra + ci->u2.nres;
|
||||||
|
/* repeat instruction to close other vars. and complete the return */
|
||||||
|
ci->u.l.savedpc--;
|
||||||
|
break;
|
||||||
|
}
|
||||||
default: {
|
default: {
|
||||||
/* only these other opcodes can yield */
|
/* only these other opcodes can yield */
|
||||||
lua_assert(op == OP_TFORCALL || op == OP_CALL ||
|
lua_assert(op == OP_TFORCALL || op == OP_CALL ||
|
||||||
|
@ -901,6 +912,7 @@ void luaV_finishOp (lua_State *L) {
|
||||||
** operation, 'fop' is the float operation.
|
** operation, 'fop' is the float operation.
|
||||||
*/
|
*/
|
||||||
#define op_arithI(L,iop,fop) { \
|
#define op_arithI(L,iop,fop) { \
|
||||||
|
StkId ra = RA(i); \
|
||||||
TValue *v1 = vRB(i); \
|
TValue *v1 = vRB(i); \
|
||||||
int imm = GETARG_sC(i); \
|
int imm = GETARG_sC(i); \
|
||||||
if (ttisinteger(v1)) { \
|
if (ttisinteger(v1)) { \
|
||||||
|
@ -929,6 +941,7 @@ void luaV_finishOp (lua_State *L) {
|
||||||
** Arithmetic operations over floats and others with register operands.
|
** Arithmetic operations over floats and others with register operands.
|
||||||
*/
|
*/
|
||||||
#define op_arithf(L,fop) { \
|
#define op_arithf(L,fop) { \
|
||||||
|
StkId ra = RA(i); \
|
||||||
TValue *v1 = vRB(i); \
|
TValue *v1 = vRB(i); \
|
||||||
TValue *v2 = vRC(i); \
|
TValue *v2 = vRC(i); \
|
||||||
op_arithf_aux(L, v1, v2, fop); }
|
op_arithf_aux(L, v1, v2, fop); }
|
||||||
|
@ -938,6 +951,7 @@ void luaV_finishOp (lua_State *L) {
|
||||||
** Arithmetic operations with K operands for floats.
|
** Arithmetic operations with K operands for floats.
|
||||||
*/
|
*/
|
||||||
#define op_arithfK(L,fop) { \
|
#define op_arithfK(L,fop) { \
|
||||||
|
StkId ra = RA(i); \
|
||||||
TValue *v1 = vRB(i); \
|
TValue *v1 = vRB(i); \
|
||||||
TValue *v2 = KC(i); lua_assert(ttisnumber(v2)); \
|
TValue *v2 = KC(i); lua_assert(ttisnumber(v2)); \
|
||||||
op_arithf_aux(L, v1, v2, fop); }
|
op_arithf_aux(L, v1, v2, fop); }
|
||||||
|
@ -947,6 +961,7 @@ void luaV_finishOp (lua_State *L) {
|
||||||
** Arithmetic operations over integers and floats.
|
** Arithmetic operations over integers and floats.
|
||||||
*/
|
*/
|
||||||
#define op_arith_aux(L,v1,v2,iop,fop) { \
|
#define op_arith_aux(L,v1,v2,iop,fop) { \
|
||||||
|
StkId ra = RA(i); \
|
||||||
if (ttisinteger(v1) && ttisinteger(v2)) { \
|
if (ttisinteger(v1) && ttisinteger(v2)) { \
|
||||||
lua_Integer i1 = ivalue(v1); lua_Integer i2 = ivalue(v2); \
|
lua_Integer i1 = ivalue(v1); lua_Integer i2 = ivalue(v2); \
|
||||||
pc++; setivalue(s2v(ra), iop(L, i1, i2)); \
|
pc++; setivalue(s2v(ra), iop(L, i1, i2)); \
|
||||||
|
@ -976,6 +991,7 @@ void luaV_finishOp (lua_State *L) {
|
||||||
** Bitwise operations with constant operand.
|
** Bitwise operations with constant operand.
|
||||||
*/
|
*/
|
||||||
#define op_bitwiseK(L,op) { \
|
#define op_bitwiseK(L,op) { \
|
||||||
|
StkId ra = RA(i); \
|
||||||
TValue *v1 = vRB(i); \
|
TValue *v1 = vRB(i); \
|
||||||
TValue *v2 = KC(i); \
|
TValue *v2 = KC(i); \
|
||||||
lua_Integer i1; \
|
lua_Integer i1; \
|
||||||
|
@ -989,6 +1005,7 @@ void luaV_finishOp (lua_State *L) {
|
||||||
** Bitwise operations with register operands.
|
** Bitwise operations with register operands.
|
||||||
*/
|
*/
|
||||||
#define op_bitwise(L,op) { \
|
#define op_bitwise(L,op) { \
|
||||||
|
StkId ra = RA(i); \
|
||||||
TValue *v1 = vRB(i); \
|
TValue *v1 = vRB(i); \
|
||||||
TValue *v2 = vRC(i); \
|
TValue *v2 = vRC(i); \
|
||||||
lua_Integer i1; lua_Integer i2; \
|
lua_Integer i1; lua_Integer i2; \
|
||||||
|
@ -1003,6 +1020,7 @@ void luaV_finishOp (lua_State *L) {
|
||||||
** integers.
|
** integers.
|
||||||
*/
|
*/
|
||||||
#define op_order(L,opi,opn,other) { \
|
#define op_order(L,opi,opn,other) { \
|
||||||
|
StkId ra = RA(i); \
|
||||||
int cond; \
|
int cond; \
|
||||||
TValue *rb = vRB(i); \
|
TValue *rb = vRB(i); \
|
||||||
if (ttisinteger(s2v(ra)) && ttisinteger(rb)) { \
|
if (ttisinteger(s2v(ra)) && ttisinteger(rb)) { \
|
||||||
|
@ -1022,6 +1040,7 @@ void luaV_finishOp (lua_State *L) {
|
||||||
** always small enough to have an exact representation as a float.)
|
** always small enough to have an exact representation as a float.)
|
||||||
*/
|
*/
|
||||||
#define op_orderI(L,opi,opf,inv,tm) { \
|
#define op_orderI(L,opi,opf,inv,tm) { \
|
||||||
|
StkId ra = RA(i); \
|
||||||
int cond; \
|
int cond; \
|
||||||
int im = GETARG_sB(i); \
|
int im = GETARG_sB(i); \
|
||||||
if (ttisinteger(s2v(ra))) \
|
if (ttisinteger(s2v(ra))) \
|
||||||
|
@ -1064,7 +1083,7 @@ void luaV_finishOp (lua_State *L) {
|
||||||
|
|
||||||
#define updatetrap(ci) (trap = ci->u.l.trap)
|
#define updatetrap(ci) (trap = ci->u.l.trap)
|
||||||
|
|
||||||
#define updatebase(ci) (base = ci->func + 1)
|
#define updatebase(ci) (base = ci->func.p + 1)
|
||||||
|
|
||||||
|
|
||||||
#define updatestack(ci) \
|
#define updatestack(ci) \
|
||||||
|
@ -1099,7 +1118,7 @@ void luaV_finishOp (lua_State *L) {
|
||||||
** Whenever code can raise errors, the global 'pc' and the global
|
** Whenever code can raise errors, the global 'pc' and the global
|
||||||
** 'top' must be correct to report occasional errors.
|
** 'top' must be correct to report occasional errors.
|
||||||
*/
|
*/
|
||||||
#define savestate(L,ci) (savepc(L), L->top = ci->top)
|
#define savestate(L,ci) (savepc(L), L->top.p = ci->top.p)
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -1112,14 +1131,14 @@ void luaV_finishOp (lua_State *L) {
|
||||||
#define ProtectNT(exp) (savepc(L), (exp), updatetrap(ci))
|
#define ProtectNT(exp) (savepc(L), (exp), updatetrap(ci))
|
||||||
|
|
||||||
/*
|
/*
|
||||||
** Protect code that can only raise errors. (That is, it cannnot change
|
** Protect code that can only raise errors. (That is, it cannot change
|
||||||
** the stack or hooks.)
|
** the stack or hooks.)
|
||||||
*/
|
*/
|
||||||
#define halfProtect(exp) (savestate(L,ci), (exp))
|
#define halfProtect(exp) (savestate(L,ci), (exp))
|
||||||
|
|
||||||
/* 'c' is the limit of live values in the stack */
|
/* 'c' is the limit of live values in the stack */
|
||||||
#define checkGC(L,c) \
|
#define checkGC(L,c) \
|
||||||
{ luaC_condGC(L, (savepc(L), L->top = (c)), \
|
{ luaC_condGC(L, (savepc(L), L->top.p = (c)), \
|
||||||
updatetrap(ci)); \
|
updatetrap(ci)); \
|
||||||
luai_threadyield(L); }
|
luai_threadyield(L); }
|
||||||
|
|
||||||
|
@ -1131,7 +1150,6 @@ void luaV_finishOp (lua_State *L) {
|
||||||
updatebase(ci); /* correct stack */ \
|
updatebase(ci); /* correct stack */ \
|
||||||
} \
|
} \
|
||||||
i = *(pc++); \
|
i = *(pc++); \
|
||||||
ra = RA(i); /* WARNING: any stack reallocation invalidates 'ra' */ \
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#define vmdispatch(o) switch(o)
|
#define vmdispatch(o) switch(o)
|
||||||
|
@ -1151,7 +1169,7 @@ void luaV_execute (lua_State *L, CallInfo *ci) {
|
||||||
startfunc:
|
startfunc:
|
||||||
trap = L->hookmask;
|
trap = L->hookmask;
|
||||||
returning: /* trap already set */
|
returning: /* trap already set */
|
||||||
cl = clLvalue(s2v(ci->func));
|
cl = clLvalue(s2v(ci->func.p));
|
||||||
k = cl->p->k;
|
k = cl->p->k;
|
||||||
pc = ci->u.l.savedpc;
|
pc = ci->u.l.savedpc;
|
||||||
if (l_unlikely(trap)) {
|
if (l_unlikely(trap)) {
|
||||||
|
@ -1163,58 +1181,68 @@ void luaV_execute (lua_State *L, CallInfo *ci) {
|
||||||
}
|
}
|
||||||
ci->u.l.trap = 1; /* assume trap is on, for now */
|
ci->u.l.trap = 1; /* assume trap is on, for now */
|
||||||
}
|
}
|
||||||
base = ci->func + 1;
|
base = ci->func.p + 1;
|
||||||
/* main loop of interpreter */
|
/* main loop of interpreter */
|
||||||
for (;;) {
|
for (;;) {
|
||||||
Instruction i; /* instruction being executed */
|
Instruction i; /* instruction being executed */
|
||||||
StkId ra; /* instruction's A register */
|
|
||||||
vmfetch();
|
vmfetch();
|
||||||
// low-level line tracing for debugging Lua
|
#if 0
|
||||||
// printf("line: %d\n", luaG_getfuncline(cl->p, pcRel(pc, cl->p)));
|
/* low-level line tracing for debugging Lua */
|
||||||
lua_assert(base == ci->func + 1);
|
printf("line: %d\n", luaG_getfuncline(cl->p, pcRel(pc, cl->p)));
|
||||||
lua_assert(base <= L->top && L->top < L->stack_last);
|
#endif
|
||||||
|
lua_assert(base == ci->func.p + 1);
|
||||||
|
lua_assert(base <= L->top.p && L->top.p <= L->stack_last.p);
|
||||||
/* invalidate top for instructions not expecting it */
|
/* invalidate top for instructions not expecting it */
|
||||||
lua_assert(isIT(i) || (cast_void(L->top = base), 1));
|
lua_assert(isIT(i) || (cast_void(L->top.p = base), 1));
|
||||||
vmdispatch (GET_OPCODE(i)) {
|
vmdispatch (GET_OPCODE(i)) {
|
||||||
vmcase(OP_MOVE) {
|
vmcase(OP_MOVE) {
|
||||||
|
StkId ra = RA(i);
|
||||||
setobjs2s(L, ra, RB(i));
|
setobjs2s(L, ra, RB(i));
|
||||||
vmbreak;
|
vmbreak;
|
||||||
}
|
}
|
||||||
vmcase(OP_LOADI) {
|
vmcase(OP_LOADI) {
|
||||||
|
StkId ra = RA(i);
|
||||||
lua_Integer b = GETARG_sBx(i);
|
lua_Integer b = GETARG_sBx(i);
|
||||||
setivalue(s2v(ra), b);
|
setivalue(s2v(ra), b);
|
||||||
vmbreak;
|
vmbreak;
|
||||||
}
|
}
|
||||||
vmcase(OP_LOADF) {
|
vmcase(OP_LOADF) {
|
||||||
|
StkId ra = RA(i);
|
||||||
int b = GETARG_sBx(i);
|
int b = GETARG_sBx(i);
|
||||||
setfltvalue(s2v(ra), cast_num(b));
|
setfltvalue(s2v(ra), cast_num(b));
|
||||||
vmbreak;
|
vmbreak;
|
||||||
}
|
}
|
||||||
vmcase(OP_LOADK) {
|
vmcase(OP_LOADK) {
|
||||||
|
StkId ra = RA(i);
|
||||||
TValue *rb = k + GETARG_Bx(i);
|
TValue *rb = k + GETARG_Bx(i);
|
||||||
setobj2s(L, ra, rb);
|
setobj2s(L, ra, rb);
|
||||||
vmbreak;
|
vmbreak;
|
||||||
}
|
}
|
||||||
vmcase(OP_LOADKX) {
|
vmcase(OP_LOADKX) {
|
||||||
|
StkId ra = RA(i);
|
||||||
TValue *rb;
|
TValue *rb;
|
||||||
rb = k + GETARG_Ax(*pc); pc++;
|
rb = k + GETARG_Ax(*pc); pc++;
|
||||||
setobj2s(L, ra, rb);
|
setobj2s(L, ra, rb);
|
||||||
vmbreak;
|
vmbreak;
|
||||||
}
|
}
|
||||||
vmcase(OP_LOADFALSE) {
|
vmcase(OP_LOADFALSE) {
|
||||||
|
StkId ra = RA(i);
|
||||||
setbfvalue(s2v(ra));
|
setbfvalue(s2v(ra));
|
||||||
vmbreak;
|
vmbreak;
|
||||||
}
|
}
|
||||||
vmcase(OP_LFALSESKIP) {
|
vmcase(OP_LFALSESKIP) {
|
||||||
|
StkId ra = RA(i);
|
||||||
setbfvalue(s2v(ra));
|
setbfvalue(s2v(ra));
|
||||||
pc++; /* skip next instruction */
|
pc++; /* skip next instruction */
|
||||||
vmbreak;
|
vmbreak;
|
||||||
}
|
}
|
||||||
vmcase(OP_LOADTRUE) {
|
vmcase(OP_LOADTRUE) {
|
||||||
|
StkId ra = RA(i);
|
||||||
setbtvalue(s2v(ra));
|
setbtvalue(s2v(ra));
|
||||||
vmbreak;
|
vmbreak;
|
||||||
}
|
}
|
||||||
vmcase(OP_LOADNIL) {
|
vmcase(OP_LOADNIL) {
|
||||||
|
StkId ra = RA(i);
|
||||||
int b = GETARG_B(i);
|
int b = GETARG_B(i);
|
||||||
do {
|
do {
|
||||||
setnilvalue(s2v(ra++));
|
setnilvalue(s2v(ra++));
|
||||||
|
@ -1222,19 +1250,22 @@ void luaV_execute (lua_State *L, CallInfo *ci) {
|
||||||
vmbreak;
|
vmbreak;
|
||||||
}
|
}
|
||||||
vmcase(OP_GETUPVAL) {
|
vmcase(OP_GETUPVAL) {
|
||||||
|
StkId ra = RA(i);
|
||||||
int b = GETARG_B(i);
|
int b = GETARG_B(i);
|
||||||
setobj2s(L, ra, cl->upvals[b]->v);
|
setobj2s(L, ra, cl->upvals[b]->v.p);
|
||||||
vmbreak;
|
vmbreak;
|
||||||
}
|
}
|
||||||
vmcase(OP_SETUPVAL) {
|
vmcase(OP_SETUPVAL) {
|
||||||
|
StkId ra = RA(i);
|
||||||
UpVal *uv = cl->upvals[GETARG_B(i)];
|
UpVal *uv = cl->upvals[GETARG_B(i)];
|
||||||
setobj(L, uv->v, s2v(ra));
|
setobj(L, uv->v.p, s2v(ra));
|
||||||
luaC_barrier(L, uv, s2v(ra));
|
luaC_barrier(L, uv, s2v(ra));
|
||||||
vmbreak;
|
vmbreak;
|
||||||
}
|
}
|
||||||
vmcase(OP_GETTABUP) {
|
vmcase(OP_GETTABUP) {
|
||||||
|
StkId ra = RA(i);
|
||||||
const TValue *slot;
|
const TValue *slot;
|
||||||
TValue *upval = cl->upvals[GETARG_B(i)]->v;
|
TValue *upval = cl->upvals[GETARG_B(i)]->v.p;
|
||||||
TValue *rc = KC(i);
|
TValue *rc = KC(i);
|
||||||
TString *key = tsvalue(rc); /* key must be a string */
|
TString *key = tsvalue(rc); /* key must be a string */
|
||||||
if (luaV_fastget(L, upval, key, slot, luaH_getshortstr)) {
|
if (luaV_fastget(L, upval, key, slot, luaH_getshortstr)) {
|
||||||
|
@ -1245,6 +1276,7 @@ void luaV_execute (lua_State *L, CallInfo *ci) {
|
||||||
vmbreak;
|
vmbreak;
|
||||||
}
|
}
|
||||||
vmcase(OP_GETTABLE) {
|
vmcase(OP_GETTABLE) {
|
||||||
|
StkId ra = RA(i);
|
||||||
const TValue *slot;
|
const TValue *slot;
|
||||||
TValue *rb = vRB(i);
|
TValue *rb = vRB(i);
|
||||||
TValue *rc = vRC(i);
|
TValue *rc = vRC(i);
|
||||||
|
@ -1259,6 +1291,7 @@ void luaV_execute (lua_State *L, CallInfo *ci) {
|
||||||
vmbreak;
|
vmbreak;
|
||||||
}
|
}
|
||||||
vmcase(OP_GETI) {
|
vmcase(OP_GETI) {
|
||||||
|
StkId ra = RA(i);
|
||||||
const TValue *slot;
|
const TValue *slot;
|
||||||
TValue *rb = vRB(i);
|
TValue *rb = vRB(i);
|
||||||
int c = GETARG_C(i);
|
int c = GETARG_C(i);
|
||||||
|
@ -1273,6 +1306,7 @@ void luaV_execute (lua_State *L, CallInfo *ci) {
|
||||||
vmbreak;
|
vmbreak;
|
||||||
}
|
}
|
||||||
vmcase(OP_GETFIELD) {
|
vmcase(OP_GETFIELD) {
|
||||||
|
StkId ra = RA(i);
|
||||||
const TValue *slot;
|
const TValue *slot;
|
||||||
TValue *rb = vRB(i);
|
TValue *rb = vRB(i);
|
||||||
TValue *rc = KC(i);
|
TValue *rc = KC(i);
|
||||||
|
@ -1286,7 +1320,7 @@ void luaV_execute (lua_State *L, CallInfo *ci) {
|
||||||
}
|
}
|
||||||
vmcase(OP_SETTABUP) {
|
vmcase(OP_SETTABUP) {
|
||||||
const TValue *slot;
|
const TValue *slot;
|
||||||
TValue *upval = cl->upvals[GETARG_A(i)]->v;
|
TValue *upval = cl->upvals[GETARG_A(i)]->v.p;
|
||||||
TValue *rb = KB(i);
|
TValue *rb = KB(i);
|
||||||
TValue *rc = RKC(i);
|
TValue *rc = RKC(i);
|
||||||
TString *key = tsvalue(rb); /* key must be a string */
|
TString *key = tsvalue(rb); /* key must be a string */
|
||||||
|
@ -1298,6 +1332,7 @@ void luaV_execute (lua_State *L, CallInfo *ci) {
|
||||||
vmbreak;
|
vmbreak;
|
||||||
}
|
}
|
||||||
vmcase(OP_SETTABLE) {
|
vmcase(OP_SETTABLE) {
|
||||||
|
StkId ra = RA(i);
|
||||||
const TValue *slot;
|
const TValue *slot;
|
||||||
TValue *rb = vRB(i); /* key (table is in 'ra') */
|
TValue *rb = vRB(i); /* key (table is in 'ra') */
|
||||||
TValue *rc = RKC(i); /* value */
|
TValue *rc = RKC(i); /* value */
|
||||||
|
@ -1312,6 +1347,7 @@ void luaV_execute (lua_State *L, CallInfo *ci) {
|
||||||
vmbreak;
|
vmbreak;
|
||||||
}
|
}
|
||||||
vmcase(OP_SETI) {
|
vmcase(OP_SETI) {
|
||||||
|
StkId ra = RA(i);
|
||||||
const TValue *slot;
|
const TValue *slot;
|
||||||
int c = GETARG_B(i);
|
int c = GETARG_B(i);
|
||||||
TValue *rc = RKC(i);
|
TValue *rc = RKC(i);
|
||||||
|
@ -1326,6 +1362,7 @@ void luaV_execute (lua_State *L, CallInfo *ci) {
|
||||||
vmbreak;
|
vmbreak;
|
||||||
}
|
}
|
||||||
vmcase(OP_SETFIELD) {
|
vmcase(OP_SETFIELD) {
|
||||||
|
StkId ra = RA(i);
|
||||||
const TValue *slot;
|
const TValue *slot;
|
||||||
TValue *rb = KB(i);
|
TValue *rb = KB(i);
|
||||||
TValue *rc = RKC(i);
|
TValue *rc = RKC(i);
|
||||||
|
@ -1338,6 +1375,7 @@ void luaV_execute (lua_State *L, CallInfo *ci) {
|
||||||
vmbreak;
|
vmbreak;
|
||||||
}
|
}
|
||||||
vmcase(OP_NEWTABLE) {
|
vmcase(OP_NEWTABLE) {
|
||||||
|
StkId ra = RA(i);
|
||||||
int b = GETARG_B(i); /* log2(hash size) + 1 */
|
int b = GETARG_B(i); /* log2(hash size) + 1 */
|
||||||
int c = GETARG_C(i); /* array size */
|
int c = GETARG_C(i); /* array size */
|
||||||
Table *t;
|
Table *t;
|
||||||
|
@ -1347,7 +1385,7 @@ void luaV_execute (lua_State *L, CallInfo *ci) {
|
||||||
if (TESTARG_k(i)) /* non-zero extra argument? */
|
if (TESTARG_k(i)) /* non-zero extra argument? */
|
||||||
c += GETARG_Ax(*pc) * (MAXARG_C + 1); /* add it to size */
|
c += GETARG_Ax(*pc) * (MAXARG_C + 1); /* add it to size */
|
||||||
pc++; /* skip extra argument */
|
pc++; /* skip extra argument */
|
||||||
L->top = ra + 1; /* correct top in case of emergency GC */
|
L->top.p = ra + 1; /* correct top in case of emergency GC */
|
||||||
t = luaH_new(L); /* memory allocation */
|
t = luaH_new(L); /* memory allocation */
|
||||||
sethvalue2s(L, ra, t);
|
sethvalue2s(L, ra, t);
|
||||||
if (b != 0 || c != 0)
|
if (b != 0 || c != 0)
|
||||||
|
@ -1356,6 +1394,7 @@ void luaV_execute (lua_State *L, CallInfo *ci) {
|
||||||
vmbreak;
|
vmbreak;
|
||||||
}
|
}
|
||||||
vmcase(OP_SELF) {
|
vmcase(OP_SELF) {
|
||||||
|
StkId ra = RA(i);
|
||||||
const TValue *slot;
|
const TValue *slot;
|
||||||
TValue *rb = vRB(i);
|
TValue *rb = vRB(i);
|
||||||
TValue *rc = RKC(i);
|
TValue *rc = RKC(i);
|
||||||
|
@ -1385,6 +1424,7 @@ void luaV_execute (lua_State *L, CallInfo *ci) {
|
||||||
vmbreak;
|
vmbreak;
|
||||||
}
|
}
|
||||||
vmcase(OP_MODK) {
|
vmcase(OP_MODK) {
|
||||||
|
savestate(L, ci); /* in case of division by 0 */
|
||||||
op_arithK(L, luaV_mod, luaV_modf);
|
op_arithK(L, luaV_mod, luaV_modf);
|
||||||
vmbreak;
|
vmbreak;
|
||||||
}
|
}
|
||||||
|
@ -1397,6 +1437,7 @@ void luaV_execute (lua_State *L, CallInfo *ci) {
|
||||||
vmbreak;
|
vmbreak;
|
||||||
}
|
}
|
||||||
vmcase(OP_IDIVK) {
|
vmcase(OP_IDIVK) {
|
||||||
|
savestate(L, ci); /* in case of division by 0 */
|
||||||
op_arithK(L, luaV_idiv, luai_numidiv);
|
op_arithK(L, luaV_idiv, luai_numidiv);
|
||||||
vmbreak;
|
vmbreak;
|
||||||
}
|
}
|
||||||
|
@ -1413,6 +1454,7 @@ void luaV_execute (lua_State *L, CallInfo *ci) {
|
||||||
vmbreak;
|
vmbreak;
|
||||||
}
|
}
|
||||||
vmcase(OP_SHRI) {
|
vmcase(OP_SHRI) {
|
||||||
|
StkId ra = RA(i);
|
||||||
TValue *rb = vRB(i);
|
TValue *rb = vRB(i);
|
||||||
int ic = GETARG_sC(i);
|
int ic = GETARG_sC(i);
|
||||||
lua_Integer ib;
|
lua_Integer ib;
|
||||||
|
@ -1422,6 +1464,7 @@ void luaV_execute (lua_State *L, CallInfo *ci) {
|
||||||
vmbreak;
|
vmbreak;
|
||||||
}
|
}
|
||||||
vmcase(OP_SHLI) {
|
vmcase(OP_SHLI) {
|
||||||
|
StkId ra = RA(i);
|
||||||
TValue *rb = vRB(i);
|
TValue *rb = vRB(i);
|
||||||
int ic = GETARG_sC(i);
|
int ic = GETARG_sC(i);
|
||||||
lua_Integer ib;
|
lua_Integer ib;
|
||||||
|
@ -1443,6 +1486,7 @@ void luaV_execute (lua_State *L, CallInfo *ci) {
|
||||||
vmbreak;
|
vmbreak;
|
||||||
}
|
}
|
||||||
vmcase(OP_MOD) {
|
vmcase(OP_MOD) {
|
||||||
|
savestate(L, ci); /* in case of division by 0 */
|
||||||
op_arith(L, luaV_mod, luaV_modf);
|
op_arith(L, luaV_mod, luaV_modf);
|
||||||
vmbreak;
|
vmbreak;
|
||||||
}
|
}
|
||||||
|
@ -1455,6 +1499,7 @@ void luaV_execute (lua_State *L, CallInfo *ci) {
|
||||||
vmbreak;
|
vmbreak;
|
||||||
}
|
}
|
||||||
vmcase(OP_IDIV) { /* floor division */
|
vmcase(OP_IDIV) { /* floor division */
|
||||||
|
savestate(L, ci); /* in case of division by 0 */
|
||||||
op_arith(L, luaV_idiv, luai_numidiv);
|
op_arith(L, luaV_idiv, luai_numidiv);
|
||||||
vmbreak;
|
vmbreak;
|
||||||
}
|
}
|
||||||
|
@ -1479,6 +1524,7 @@ void luaV_execute (lua_State *L, CallInfo *ci) {
|
||||||
vmbreak;
|
vmbreak;
|
||||||
}
|
}
|
||||||
vmcase(OP_MMBIN) {
|
vmcase(OP_MMBIN) {
|
||||||
|
StkId ra = RA(i);
|
||||||
Instruction pi = *(pc - 2); /* original arith. expression */
|
Instruction pi = *(pc - 2); /* original arith. expression */
|
||||||
TValue *rb = vRB(i);
|
TValue *rb = vRB(i);
|
||||||
TMS tm = (TMS)GETARG_C(i);
|
TMS tm = (TMS)GETARG_C(i);
|
||||||
|
@ -1488,6 +1534,7 @@ void luaV_execute (lua_State *L, CallInfo *ci) {
|
||||||
vmbreak;
|
vmbreak;
|
||||||
}
|
}
|
||||||
vmcase(OP_MMBINI) {
|
vmcase(OP_MMBINI) {
|
||||||
|
StkId ra = RA(i);
|
||||||
Instruction pi = *(pc - 2); /* original arith. expression */
|
Instruction pi = *(pc - 2); /* original arith. expression */
|
||||||
int imm = GETARG_sB(i);
|
int imm = GETARG_sB(i);
|
||||||
TMS tm = (TMS)GETARG_C(i);
|
TMS tm = (TMS)GETARG_C(i);
|
||||||
|
@ -1497,6 +1544,7 @@ void luaV_execute (lua_State *L, CallInfo *ci) {
|
||||||
vmbreak;
|
vmbreak;
|
||||||
}
|
}
|
||||||
vmcase(OP_MMBINK) {
|
vmcase(OP_MMBINK) {
|
||||||
|
StkId ra = RA(i);
|
||||||
Instruction pi = *(pc - 2); /* original arith. expression */
|
Instruction pi = *(pc - 2); /* original arith. expression */
|
||||||
TValue *imm = KB(i);
|
TValue *imm = KB(i);
|
||||||
TMS tm = (TMS)GETARG_C(i);
|
TMS tm = (TMS)GETARG_C(i);
|
||||||
|
@ -1506,6 +1554,7 @@ void luaV_execute (lua_State *L, CallInfo *ci) {
|
||||||
vmbreak;
|
vmbreak;
|
||||||
}
|
}
|
||||||
vmcase(OP_UNM) {
|
vmcase(OP_UNM) {
|
||||||
|
StkId ra = RA(i);
|
||||||
TValue *rb = vRB(i);
|
TValue *rb = vRB(i);
|
||||||
lua_Number nb;
|
lua_Number nb;
|
||||||
if (ttisinteger(rb)) {
|
if (ttisinteger(rb)) {
|
||||||
|
@ -1520,6 +1569,7 @@ void luaV_execute (lua_State *L, CallInfo *ci) {
|
||||||
vmbreak;
|
vmbreak;
|
||||||
}
|
}
|
||||||
vmcase(OP_BNOT) {
|
vmcase(OP_BNOT) {
|
||||||
|
StkId ra = RA(i);
|
||||||
TValue *rb = vRB(i);
|
TValue *rb = vRB(i);
|
||||||
lua_Integer ib;
|
lua_Integer ib;
|
||||||
if (tointegerns(rb, &ib)) {
|
if (tointegerns(rb, &ib)) {
|
||||||
|
@ -1530,6 +1580,7 @@ void luaV_execute (lua_State *L, CallInfo *ci) {
|
||||||
vmbreak;
|
vmbreak;
|
||||||
}
|
}
|
||||||
vmcase(OP_NOT) {
|
vmcase(OP_NOT) {
|
||||||
|
StkId ra = RA(i);
|
||||||
TValue *rb = vRB(i);
|
TValue *rb = vRB(i);
|
||||||
if (l_isfalse(rb))
|
if (l_isfalse(rb))
|
||||||
setbtvalue(s2v(ra));
|
setbtvalue(s2v(ra));
|
||||||
|
@ -1538,21 +1589,25 @@ void luaV_execute (lua_State *L, CallInfo *ci) {
|
||||||
vmbreak;
|
vmbreak;
|
||||||
}
|
}
|
||||||
vmcase(OP_LEN) {
|
vmcase(OP_LEN) {
|
||||||
|
StkId ra = RA(i);
|
||||||
Protect(luaV_objlen(L, ra, vRB(i)));
|
Protect(luaV_objlen(L, ra, vRB(i)));
|
||||||
vmbreak;
|
vmbreak;
|
||||||
}
|
}
|
||||||
vmcase(OP_CONCAT) {
|
vmcase(OP_CONCAT) {
|
||||||
|
StkId ra = RA(i);
|
||||||
int n = GETARG_B(i); /* number of elements to concatenate */
|
int n = GETARG_B(i); /* number of elements to concatenate */
|
||||||
L->top = ra + n; /* mark the end of concat operands */
|
L->top.p = ra + n; /* mark the end of concat operands */
|
||||||
ProtectNT(luaV_concat(L, n));
|
ProtectNT(luaV_concat(L, n));
|
||||||
checkGC(L, L->top); /* 'luaV_concat' ensures correct top */
|
checkGC(L, L->top.p); /* 'luaV_concat' ensures correct top */
|
||||||
vmbreak;
|
vmbreak;
|
||||||
}
|
}
|
||||||
vmcase(OP_CLOSE) {
|
vmcase(OP_CLOSE) {
|
||||||
|
StkId ra = RA(i);
|
||||||
Protect(luaF_close(L, ra, LUA_OK, 1));
|
Protect(luaF_close(L, ra, LUA_OK, 1));
|
||||||
vmbreak;
|
vmbreak;
|
||||||
}
|
}
|
||||||
vmcase(OP_TBC) {
|
vmcase(OP_TBC) {
|
||||||
|
StkId ra = RA(i);
|
||||||
/* create new to-be-closed upvalue */
|
/* create new to-be-closed upvalue */
|
||||||
halfProtect(luaF_newtbcupval(L, ra));
|
halfProtect(luaF_newtbcupval(L, ra));
|
||||||
vmbreak;
|
vmbreak;
|
||||||
|
@ -1562,6 +1617,7 @@ void luaV_execute (lua_State *L, CallInfo *ci) {
|
||||||
vmbreak;
|
vmbreak;
|
||||||
}
|
}
|
||||||
vmcase(OP_EQ) {
|
vmcase(OP_EQ) {
|
||||||
|
StkId ra = RA(i);
|
||||||
int cond;
|
int cond;
|
||||||
TValue *rb = vRB(i);
|
TValue *rb = vRB(i);
|
||||||
Protect(cond = luaV_equalobj(L, s2v(ra), rb));
|
Protect(cond = luaV_equalobj(L, s2v(ra), rb));
|
||||||
|
@ -1577,6 +1633,7 @@ void luaV_execute (lua_State *L, CallInfo *ci) {
|
||||||
vmbreak;
|
vmbreak;
|
||||||
}
|
}
|
||||||
vmcase(OP_EQK) {
|
vmcase(OP_EQK) {
|
||||||
|
StkId ra = RA(i);
|
||||||
TValue *rb = KB(i);
|
TValue *rb = KB(i);
|
||||||
/* basic types do not use '__eq'; we can use raw equality */
|
/* basic types do not use '__eq'; we can use raw equality */
|
||||||
int cond = luaV_rawequalobj(s2v(ra), rb);
|
int cond = luaV_rawequalobj(s2v(ra), rb);
|
||||||
|
@ -1584,6 +1641,7 @@ void luaV_execute (lua_State *L, CallInfo *ci) {
|
||||||
vmbreak;
|
vmbreak;
|
||||||
}
|
}
|
||||||
vmcase(OP_EQI) {
|
vmcase(OP_EQI) {
|
||||||
|
StkId ra = RA(i);
|
||||||
int cond;
|
int cond;
|
||||||
int im = GETARG_sB(i);
|
int im = GETARG_sB(i);
|
||||||
if (ttisinteger(s2v(ra)))
|
if (ttisinteger(s2v(ra)))
|
||||||
|
@ -1612,11 +1670,13 @@ void luaV_execute (lua_State *L, CallInfo *ci) {
|
||||||
vmbreak;
|
vmbreak;
|
||||||
}
|
}
|
||||||
vmcase(OP_TEST) {
|
vmcase(OP_TEST) {
|
||||||
|
StkId ra = RA(i);
|
||||||
int cond = !l_isfalse(s2v(ra));
|
int cond = !l_isfalse(s2v(ra));
|
||||||
docondjump();
|
docondjump();
|
||||||
vmbreak;
|
vmbreak;
|
||||||
}
|
}
|
||||||
vmcase(OP_TESTSET) {
|
vmcase(OP_TESTSET) {
|
||||||
|
StkId ra = RA(i);
|
||||||
TValue *rb = vRB(i);
|
TValue *rb = vRB(i);
|
||||||
if (l_isfalse(rb) == GETARG_k(i))
|
if (l_isfalse(rb) == GETARG_k(i))
|
||||||
pc++;
|
pc++;
|
||||||
|
@ -1627,78 +1687,74 @@ void luaV_execute (lua_State *L, CallInfo *ci) {
|
||||||
vmbreak;
|
vmbreak;
|
||||||
}
|
}
|
||||||
vmcase(OP_CALL) {
|
vmcase(OP_CALL) {
|
||||||
|
StkId ra = RA(i);
|
||||||
CallInfo *newci;
|
CallInfo *newci;
|
||||||
int b = GETARG_B(i);
|
int b = GETARG_B(i);
|
||||||
int nresults = GETARG_C(i) - 1;
|
int nresults = GETARG_C(i) - 1;
|
||||||
if (b != 0) /* fixed number of arguments? */
|
if (b != 0) /* fixed number of arguments? */
|
||||||
L->top = ra + b; /* top signals number of arguments */
|
L->top.p = ra + b; /* top signals number of arguments */
|
||||||
/* else previous instruction set top */
|
/* else previous instruction set top */
|
||||||
savepc(L); /* in case of errors */
|
savepc(L); /* in case of errors */
|
||||||
if ((newci = luaD_precall(L, ra, nresults)) == NULL)
|
if ((newci = luaD_precall(L, ra, nresults)) == NULL)
|
||||||
updatetrap(ci); /* C call; nothing else to be done */
|
updatetrap(ci); /* C call; nothing else to be done */
|
||||||
else { /* Lua call: run function in this same C frame */
|
else { /* Lua call: run function in this same C frame */
|
||||||
ci = newci;
|
ci = newci;
|
||||||
ci->callstatus = 0; /* call re-uses 'luaV_execute' */
|
|
||||||
goto startfunc;
|
goto startfunc;
|
||||||
}
|
}
|
||||||
vmbreak;
|
vmbreak;
|
||||||
}
|
}
|
||||||
vmcase(OP_TAILCALL) {
|
vmcase(OP_TAILCALL) {
|
||||||
|
StkId ra = RA(i);
|
||||||
int b = GETARG_B(i); /* number of arguments + 1 (function) */
|
int b = GETARG_B(i); /* number of arguments + 1 (function) */
|
||||||
|
int n; /* number of results when calling a C function */
|
||||||
int nparams1 = GETARG_C(i);
|
int nparams1 = GETARG_C(i);
|
||||||
/* delta is virtual 'func' - real 'func' (vararg functions) */
|
/* delta is virtual 'func' - real 'func' (vararg functions) */
|
||||||
int delta = (nparams1) ? ci->u.l.nextraargs + nparams1 : 0;
|
int delta = (nparams1) ? ci->u.l.nextraargs + nparams1 : 0;
|
||||||
if (b != 0)
|
if (b != 0)
|
||||||
L->top = ra + b;
|
L->top.p = ra + b;
|
||||||
else /* previous instruction set top */
|
else /* previous instruction set top */
|
||||||
b = cast_int(L->top - ra);
|
b = cast_int(L->top.p - ra);
|
||||||
savepc(ci); /* several calls here can raise errors */
|
savepc(ci); /* several calls here can raise errors */
|
||||||
if (TESTARG_k(i)) {
|
if (TESTARG_k(i)) {
|
||||||
luaF_closeupval(L, base); /* close upvalues from current call */
|
luaF_closeupval(L, base); /* close upvalues from current call */
|
||||||
lua_assert(L->tbclist < base); /* no pending tbc variables */
|
lua_assert(L->tbclist.p < base); /* no pending tbc variables */
|
||||||
lua_assert(base == ci->func + 1);
|
lua_assert(base == ci->func.p + 1);
|
||||||
}
|
}
|
||||||
while (!ttisfunction(s2v(ra))) { /* not a function? */
|
if ((n = luaD_pretailcall(L, ci, ra, b, delta)) < 0) /* Lua function? */
|
||||||
luaD_tryfuncTM(L, ra); /* try '__call' metamethod */
|
goto startfunc; /* execute the callee */
|
||||||
b++; /* there is now one extra argument */
|
else { /* C function? */
|
||||||
checkstackGCp(L, 1, ra);
|
ci->func.p -= delta; /* restore 'func' (if vararg) */
|
||||||
}
|
luaD_poscall(L, ci, n); /* finish caller */
|
||||||
if (!ttisLclosure(s2v(ra))) { /* C function? */
|
|
||||||
luaD_precall(L, ra, LUA_MULTRET); /* call it */
|
|
||||||
updatetrap(ci);
|
|
||||||
updatestack(ci); /* stack may have been relocated */
|
|
||||||
ci->func -= delta; /* restore 'func' (if vararg) */
|
|
||||||
luaD_poscall(L, ci, cast_int(L->top - ra)); /* finish caller */
|
|
||||||
updatetrap(ci); /* 'luaD_poscall' can change hooks */
|
updatetrap(ci); /* 'luaD_poscall' can change hooks */
|
||||||
goto ret; /* caller returns after the tail call */
|
goto ret; /* caller returns after the tail call */
|
||||||
}
|
}
|
||||||
ci->func -= delta; /* restore 'func' (if vararg) */
|
|
||||||
luaD_pretailcall(L, ci, ra, b); /* prepare call frame */
|
|
||||||
goto startfunc; /* execute the callee */
|
|
||||||
}
|
}
|
||||||
vmcase(OP_RETURN) {
|
vmcase(OP_RETURN) {
|
||||||
|
StkId ra = RA(i);
|
||||||
int n = GETARG_B(i) - 1; /* number of results */
|
int n = GETARG_B(i) - 1; /* number of results */
|
||||||
int nparams1 = GETARG_C(i);
|
int nparams1 = GETARG_C(i);
|
||||||
if (n < 0) /* not fixed? */
|
if (n < 0) /* not fixed? */
|
||||||
n = cast_int(L->top - ra); /* get what is available */
|
n = cast_int(L->top.p - ra); /* get what is available */
|
||||||
savepc(ci);
|
savepc(ci);
|
||||||
if (TESTARG_k(i)) { /* may there be open upvalues? */
|
if (TESTARG_k(i)) { /* may there be open upvalues? */
|
||||||
if (L->top < ci->top)
|
ci->u2.nres = n; /* save number of returns */
|
||||||
L->top = ci->top;
|
if (L->top.p < ci->top.p)
|
||||||
|
L->top.p = ci->top.p;
|
||||||
luaF_close(L, base, CLOSEKTOP, 1);
|
luaF_close(L, base, CLOSEKTOP, 1);
|
||||||
updatetrap(ci);
|
updatetrap(ci);
|
||||||
updatestack(ci);
|
updatestack(ci);
|
||||||
}
|
}
|
||||||
if (nparams1) /* vararg function? */
|
if (nparams1) /* vararg function? */
|
||||||
ci->func -= ci->u.l.nextraargs + nparams1;
|
ci->func.p -= ci->u.l.nextraargs + nparams1;
|
||||||
L->top = ra + n; /* set call for 'luaD_poscall' */
|
L->top.p = ra + n; /* set call for 'luaD_poscall' */
|
||||||
luaD_poscall(L, ci, n);
|
luaD_poscall(L, ci, n);
|
||||||
updatetrap(ci); /* 'luaD_poscall' can change hooks */
|
updatetrap(ci); /* 'luaD_poscall' can change hooks */
|
||||||
goto ret;
|
goto ret;
|
||||||
}
|
}
|
||||||
vmcase(OP_RETURN0) {
|
vmcase(OP_RETURN0) {
|
||||||
if (l_unlikely(L->hookmask)) {
|
if (l_unlikely(L->hookmask)) {
|
||||||
L->top = ra;
|
StkId ra = RA(i);
|
||||||
|
L->top.p = ra;
|
||||||
savepc(ci);
|
savepc(ci);
|
||||||
luaD_poscall(L, ci, 0); /* no hurry... */
|
luaD_poscall(L, ci, 0); /* no hurry... */
|
||||||
trap = 1;
|
trap = 1;
|
||||||
|
@ -1706,15 +1762,16 @@ void luaV_execute (lua_State *L, CallInfo *ci) {
|
||||||
else { /* do the 'poscall' here */
|
else { /* do the 'poscall' here */
|
||||||
int nres;
|
int nres;
|
||||||
L->ci = ci->previous; /* back to caller */
|
L->ci = ci->previous; /* back to caller */
|
||||||
L->top = base - 1;
|
L->top.p = base - 1;
|
||||||
for (nres = ci->nresults; l_unlikely(nres > 0); nres--)
|
for (nres = ci->nresults; l_unlikely(nres > 0); nres--)
|
||||||
setnilvalue(s2v(L->top++)); /* all results are nil */
|
setnilvalue(s2v(L->top.p++)); /* all results are nil */
|
||||||
}
|
}
|
||||||
goto ret;
|
goto ret;
|
||||||
}
|
}
|
||||||
vmcase(OP_RETURN1) {
|
vmcase(OP_RETURN1) {
|
||||||
if (l_unlikely(L->hookmask)) {
|
if (l_unlikely(L->hookmask)) {
|
||||||
L->top = ra + 1;
|
StkId ra = RA(i);
|
||||||
|
L->top.p = ra + 1;
|
||||||
savepc(ci);
|
savepc(ci);
|
||||||
luaD_poscall(L, ci, 1); /* no hurry... */
|
luaD_poscall(L, ci, 1); /* no hurry... */
|
||||||
trap = 1;
|
trap = 1;
|
||||||
|
@ -1723,12 +1780,13 @@ void luaV_execute (lua_State *L, CallInfo *ci) {
|
||||||
int nres = ci->nresults;
|
int nres = ci->nresults;
|
||||||
L->ci = ci->previous; /* back to caller */
|
L->ci = ci->previous; /* back to caller */
|
||||||
if (nres == 0)
|
if (nres == 0)
|
||||||
L->top = base - 1; /* asked for no results */
|
L->top.p = base - 1; /* asked for no results */
|
||||||
else {
|
else {
|
||||||
|
StkId ra = RA(i);
|
||||||
setobjs2s(L, base - 1, ra); /* at least this result */
|
setobjs2s(L, base - 1, ra); /* at least this result */
|
||||||
L->top = base;
|
L->top.p = base;
|
||||||
for (; l_unlikely(nres > 1); nres--)
|
for (; l_unlikely(nres > 1); nres--)
|
||||||
setnilvalue(s2v(L->top++)); /* complete missing results */
|
setnilvalue(s2v(L->top.p++)); /* complete missing results */
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
ret: /* return from a Lua function */
|
ret: /* return from a Lua function */
|
||||||
|
@ -1740,6 +1798,7 @@ void luaV_execute (lua_State *L, CallInfo *ci) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
vmcase(OP_FORLOOP) {
|
vmcase(OP_FORLOOP) {
|
||||||
|
StkId ra = RA(i);
|
||||||
if (ttisinteger(s2v(ra + 2))) { /* integer loop? */
|
if (ttisinteger(s2v(ra + 2))) { /* integer loop? */
|
||||||
lua_Unsigned count = l_castS2U(ivalue(s2v(ra + 1)));
|
lua_Unsigned count = l_castS2U(ivalue(s2v(ra + 1)));
|
||||||
if (count > 0) { /* still more iterations? */
|
if (count > 0) { /* still more iterations? */
|
||||||
|
@ -1758,12 +1817,14 @@ void luaV_execute (lua_State *L, CallInfo *ci) {
|
||||||
vmbreak;
|
vmbreak;
|
||||||
}
|
}
|
||||||
vmcase(OP_FORPREP) {
|
vmcase(OP_FORPREP) {
|
||||||
|
StkId ra = RA(i);
|
||||||
savestate(L, ci); /* in case of errors */
|
savestate(L, ci); /* in case of errors */
|
||||||
if (forprep(L, ra))
|
if (forprep(L, ra))
|
||||||
pc += GETARG_Bx(i) + 1; /* skip the loop */
|
pc += GETARG_Bx(i) + 1; /* skip the loop */
|
||||||
vmbreak;
|
vmbreak;
|
||||||
}
|
}
|
||||||
vmcase(OP_TFORPREP) {
|
vmcase(OP_TFORPREP) {
|
||||||
|
StkId ra = RA(i);
|
||||||
/* create to-be-closed upvalue (if needed) */
|
/* create to-be-closed upvalue (if needed) */
|
||||||
halfProtect(luaF_newtbcupval(L, ra + 3));
|
halfProtect(luaF_newtbcupval(L, ra + 3));
|
||||||
pc += GETARG_Bx(i);
|
pc += GETARG_Bx(i);
|
||||||
|
@ -1772,7 +1833,8 @@ void luaV_execute (lua_State *L, CallInfo *ci) {
|
||||||
goto l_tforcall;
|
goto l_tforcall;
|
||||||
}
|
}
|
||||||
vmcase(OP_TFORCALL) {
|
vmcase(OP_TFORCALL) {
|
||||||
l_tforcall:
|
l_tforcall: {
|
||||||
|
StkId ra = RA(i);
|
||||||
/* 'ra' has the iterator function, 'ra + 1' has the state,
|
/* 'ra' has the iterator function, 'ra + 1' has the state,
|
||||||
'ra + 2' has the control variable, and 'ra + 3' has the
|
'ra + 2' has the control variable, and 'ra + 3' has the
|
||||||
to-be-closed variable. The call will use the stack after
|
to-be-closed variable. The call will use the stack after
|
||||||
|
@ -1780,29 +1842,31 @@ void luaV_execute (lua_State *L, CallInfo *ci) {
|
||||||
*/
|
*/
|
||||||
/* push function, state, and control variable */
|
/* push function, state, and control variable */
|
||||||
memcpy(ra + 4, ra, 3 * sizeof(*ra));
|
memcpy(ra + 4, ra, 3 * sizeof(*ra));
|
||||||
L->top = ra + 4 + 3;
|
L->top.p = ra + 4 + 3;
|
||||||
ProtectNT(luaD_call(L, ra + 4, GETARG_C(i))); /* do the call */
|
ProtectNT(luaD_call(L, ra + 4, GETARG_C(i))); /* do the call */
|
||||||
updatestack(ci); /* stack may have changed */
|
updatestack(ci); /* stack may have changed */
|
||||||
i = *(pc++); /* go to next instruction */
|
i = *(pc++); /* go to next instruction */
|
||||||
lua_assert(GET_OPCODE(i) == OP_TFORLOOP && ra == RA(i));
|
lua_assert(GET_OPCODE(i) == OP_TFORLOOP && ra == RA(i));
|
||||||
goto l_tforloop;
|
goto l_tforloop;
|
||||||
}
|
}}
|
||||||
vmcase(OP_TFORLOOP) {
|
vmcase(OP_TFORLOOP) {
|
||||||
l_tforloop:
|
l_tforloop: {
|
||||||
|
StkId ra = RA(i);
|
||||||
if (!ttisnil(s2v(ra + 4))) { /* continue loop? */
|
if (!ttisnil(s2v(ra + 4))) { /* continue loop? */
|
||||||
setobjs2s(L, ra + 2, ra + 4); /* save control variable */
|
setobjs2s(L, ra + 2, ra + 4); /* save control variable */
|
||||||
pc -= GETARG_Bx(i); /* jump back */
|
pc -= GETARG_Bx(i); /* jump back */
|
||||||
}
|
}
|
||||||
vmbreak;
|
vmbreak;
|
||||||
}
|
}}
|
||||||
vmcase(OP_SETLIST) {
|
vmcase(OP_SETLIST) {
|
||||||
|
StkId ra = RA(i);
|
||||||
int n = GETARG_B(i);
|
int n = GETARG_B(i);
|
||||||
unsigned int last = GETARG_C(i);
|
unsigned int last = GETARG_C(i);
|
||||||
Table *h = hvalue(s2v(ra));
|
Table *h = hvalue(s2v(ra));
|
||||||
if (n == 0)
|
if (n == 0)
|
||||||
n = cast_int(L->top - ra) - 1; /* get up to the top */
|
n = cast_int(L->top.p - ra) - 1; /* get up to the top */
|
||||||
else
|
else
|
||||||
L->top = ci->top; /* correct top in case of emergency GC */
|
L->top.p = ci->top.p; /* correct top in case of emergency GC */
|
||||||
last += n;
|
last += n;
|
||||||
if (TESTARG_k(i)) {
|
if (TESTARG_k(i)) {
|
||||||
last += GETARG_Ax(*pc) * (MAXARG_C + 1);
|
last += GETARG_Ax(*pc) * (MAXARG_C + 1);
|
||||||
|
@ -1819,12 +1883,14 @@ void luaV_execute (lua_State *L, CallInfo *ci) {
|
||||||
vmbreak;
|
vmbreak;
|
||||||
}
|
}
|
||||||
vmcase(OP_CLOSURE) {
|
vmcase(OP_CLOSURE) {
|
||||||
|
StkId ra = RA(i);
|
||||||
Proto *p = cl->p->p[GETARG_Bx(i)];
|
Proto *p = cl->p->p[GETARG_Bx(i)];
|
||||||
halfProtect(pushclosure(L, p, cl->upvals, base, ra));
|
halfProtect(pushclosure(L, p, cl->upvals, base, ra));
|
||||||
checkGC(L, ra + 1);
|
checkGC(L, ra + 1);
|
||||||
vmbreak;
|
vmbreak;
|
||||||
}
|
}
|
||||||
vmcase(OP_VARARG) {
|
vmcase(OP_VARARG) {
|
||||||
|
StkId ra = RA(i);
|
||||||
int n = GETARG_C(i) - 1; /* required results */
|
int n = GETARG_C(i) - 1; /* required results */
|
||||||
Protect(luaT_getvarargs(L, ci, ra, n));
|
Protect(luaT_getvarargs(L, ci, ra, n));
|
||||||
vmbreak;
|
vmbreak;
|
||||||
|
|
6
third_party/lua/lvm.h
vendored
6
third_party/lua/lvm.h
vendored
|
@ -1,5 +1,6 @@
|
||||||
#ifndef lvm_h
|
#ifndef lvm_h
|
||||||
#define lvm_h
|
#define lvm_h
|
||||||
|
|
||||||
#include "third_party/lua/ldo.h"
|
#include "third_party/lua/ldo.h"
|
||||||
#include "third_party/lua/lobject.h"
|
#include "third_party/lua/lobject.h"
|
||||||
#include "third_party/lua/ltm.h"
|
#include "third_party/lua/ltm.h"
|
||||||
|
@ -102,6 +103,11 @@ typedef enum {
|
||||||
luaC_barrierback(L, gcvalue(t), v); }
|
luaC_barrierback(L, gcvalue(t), v); }
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
** Shift right is the same as shift left with a negative 'y'
|
||||||
|
*/
|
||||||
|
#define luaV_shiftr(x,y) luaV_shiftl(x,intop(-, 0, y))
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
LUAI_FUNC int luaV_equalobj (lua_State *L, const TValue *t1, const TValue *t2);
|
LUAI_FUNC int luaV_equalobj (lua_State *L, const TValue *t1, const TValue *t2);
|
||||||
|
|
3
third_party/lua/lzio.c
vendored
3
third_party/lua/lzio.c
vendored
|
@ -3,7 +3,7 @@
|
||||||
╚──────────────────────────────────────────────────────────────────────────────╝
|
╚──────────────────────────────────────────────────────────────────────────────╝
|
||||||
│ │
|
│ │
|
||||||
│ Lua │
|
│ Lua │
|
||||||
│ Copyright © 2004-2021 Lua.org, PUC-Rio. │
|
│ Copyright © 2004-2023 Lua.org, PUC-Rio. │
|
||||||
│ │
|
│ │
|
||||||
│ Permission is hereby granted, free of charge, to any person obtaining │
|
│ Permission is hereby granted, free of charge, to any person obtaining │
|
||||||
│ a copy of this software and associated documentation files (the │
|
│ a copy of this software and associated documentation files (the │
|
||||||
|
@ -27,6 +27,7 @@
|
||||||
╚─────────────────────────────────────────────────────────────────────────────*/
|
╚─────────────────────────────────────────────────────────────────────────────*/
|
||||||
#define lzio_c
|
#define lzio_c
|
||||||
#define LUA_CORE
|
#define LUA_CORE
|
||||||
|
|
||||||
#include "libc/str/str.h"
|
#include "libc/str/str.h"
|
||||||
#include "third_party/lua/llimits.h"
|
#include "third_party/lua/llimits.h"
|
||||||
#include "third_party/lua/lmem.h"
|
#include "third_party/lua/lmem.h"
|
||||||
|
|
6
third_party/lua/lzio.h
vendored
6
third_party/lua/lzio.h
vendored
|
@ -1,9 +1,3 @@
|
||||||
/*
|
|
||||||
** $Id: lzio.h $
|
|
||||||
** Buffered streams
|
|
||||||
** See Copyright Notice in lua.h
|
|
||||||
*/
|
|
||||||
|
|
||||||
#ifndef lzio_h
|
#ifndef lzio_h
|
||||||
#define lzio_h
|
#define lzio_h
|
||||||
|
|
||||||
|
|
1
third_party/lua/test/all.lua
vendored
1
third_party/lua/test/all.lua
vendored
|
@ -163,6 +163,7 @@ f()
|
||||||
|
|
||||||
dofile('db.lua')
|
dofile('db.lua')
|
||||||
assert(dofile('calls.lua') == deep and deep)
|
assert(dofile('calls.lua') == deep and deep)
|
||||||
|
_G.deep = nil
|
||||||
olddofile('strings.lua')
|
olddofile('strings.lua')
|
||||||
olddofile('literals.lua')
|
olddofile('literals.lua')
|
||||||
dofile('tpack.lua')
|
dofile('tpack.lua')
|
||||||
|
|
117
third_party/lua/test/api.lua
vendored
117
third_party/lua/test/api.lua
vendored
|
@ -14,7 +14,7 @@ local pack = table.pack
|
||||||
-- standard error message for memory errors
|
-- standard error message for memory errors
|
||||||
local MEMERRMSG = "not enough memory"
|
local MEMERRMSG = "not enough memory"
|
||||||
|
|
||||||
function tcheck (t1, t2)
|
local function tcheck (t1, t2)
|
||||||
assert(t1.n == (t2.n or #t2) + 1)
|
assert(t1.n == (t2.n or #t2) + 1)
|
||||||
for i = 2, t1.n do assert(t1[i] == t2[i - 1]) end
|
for i = 2, t1.n do assert(t1[i] == t2[i - 1]) end
|
||||||
end
|
end
|
||||||
|
@ -28,7 +28,7 @@ end
|
||||||
|
|
||||||
print('testing C API')
|
print('testing C API')
|
||||||
|
|
||||||
a = T.testC("pushvalue R; return 1")
|
local a = T.testC("pushvalue R; return 1")
|
||||||
assert(a == debug.getregistry())
|
assert(a == debug.getregistry())
|
||||||
|
|
||||||
|
|
||||||
|
@ -43,10 +43,10 @@ a = T.d2s(12458954321123.0)
|
||||||
assert(a == string.pack("d", 12458954321123.0))
|
assert(a == string.pack("d", 12458954321123.0))
|
||||||
assert(T.s2d(a) == 12458954321123.0)
|
assert(T.s2d(a) == 12458954321123.0)
|
||||||
|
|
||||||
a,b,c = T.testC("pushnum 1; pushnum 2; pushnum 3; return 2")
|
local a,b,c = T.testC("pushnum 1; pushnum 2; pushnum 3; return 2")
|
||||||
assert(a == 2 and b == 3 and not c)
|
assert(a == 2 and b == 3 and not c)
|
||||||
|
|
||||||
f = T.makeCfunc("pushnum 1; pushnum 2; pushnum 3; return 2")
|
local f = T.makeCfunc("pushnum 1; pushnum 2; pushnum 3; return 2")
|
||||||
a,b,c = f()
|
a,b,c = f()
|
||||||
assert(a == 2 and b == 3 and not c)
|
assert(a == 2 and b == 3 and not c)
|
||||||
|
|
||||||
|
@ -61,7 +61,7 @@ assert(a==false and b==true and c==false)
|
||||||
a,b,c = T.testC("gettop; return 2", 10, 20, 30, 40)
|
a,b,c = T.testC("gettop; return 2", 10, 20, 30, 40)
|
||||||
assert(a == 40 and b == 5 and not c)
|
assert(a == 40 and b == 5 and not c)
|
||||||
|
|
||||||
t = pack(T.testC("settop 5; return *", 2, 3))
|
local t = pack(T.testC("settop 5; return *", 2, 3))
|
||||||
tcheck(t, {n=4,2,3})
|
tcheck(t, {n=4,2,3})
|
||||||
|
|
||||||
t = pack(T.testC("settop 0; settop 15; return 10", 3, 1, 23))
|
t = pack(T.testC("settop 0; settop 15; return 10", 3, 1, 23))
|
||||||
|
@ -166,16 +166,17 @@ end
|
||||||
|
|
||||||
|
|
||||||
-- testing globals
|
-- testing globals
|
||||||
_G.a = 14; _G.b = "a31"
|
_G.AA = 14; _G.BB = "a31"
|
||||||
local a = {T.testC[[
|
local a = {T.testC[[
|
||||||
getglobal a;
|
getglobal AA;
|
||||||
getglobal b;
|
getglobal BB;
|
||||||
getglobal b;
|
getglobal BB;
|
||||||
setglobal a;
|
setglobal AA;
|
||||||
return *
|
return *
|
||||||
]]}
|
]]}
|
||||||
assert(a[2] == 14 and a[3] == "a31" and a[4] == nil and _G.a == "a31")
|
assert(a[2] == 14 and a[3] == "a31" and a[4] == nil and _G.AA == "a31")
|
||||||
|
|
||||||
|
_G.AA, _G.BB = nil
|
||||||
|
|
||||||
-- testing arith
|
-- testing arith
|
||||||
assert(T.testC("pushnum 10; pushnum 20; arith /; return 1") == 0.5)
|
assert(T.testC("pushnum 10; pushnum 20; arith /; return 1") == 0.5)
|
||||||
|
@ -199,13 +200,14 @@ a,b,c = T.testC([[pushnum 1;
|
||||||
pushstring 10; arith _;
|
pushstring 10; arith _;
|
||||||
pushstring 5; return 3]])
|
pushstring 5; return 3]])
|
||||||
assert(a == 1 and b == -10 and c == "5")
|
assert(a == 1 and b == -10 and c == "5")
|
||||||
mt = {__add = function (a,b) return setmetatable({a[1] + b[1]}, mt) end,
|
local mt = {
|
||||||
|
__add = function (a,b) return setmetatable({a[1] + b[1]}, mt) end,
|
||||||
__mod = function (a,b) return setmetatable({a[1] % b[1]}, mt) end,
|
__mod = function (a,b) return setmetatable({a[1] % b[1]}, mt) end,
|
||||||
__unm = function (a) return setmetatable({a[1]* 2}, mt) end}
|
__unm = function (a) return setmetatable({a[1]* 2}, mt) end}
|
||||||
a,b,c = setmetatable({4}, mt),
|
a,b,c = setmetatable({4}, mt),
|
||||||
setmetatable({8}, mt),
|
setmetatable({8}, mt),
|
||||||
setmetatable({-3}, mt)
|
setmetatable({-3}, mt)
|
||||||
x,y,z = T.testC("arith +; return 2", 10, a, b)
|
local x,y,z = T.testC("arith +; return 2", 10, a, b)
|
||||||
assert(x == 10 and y[1] == 12 and z == nil)
|
assert(x == 10 and y[1] == 12 and z == nil)
|
||||||
assert(T.testC("arith %; return 1", a, c)[1] == 4%-3)
|
assert(T.testC("arith %; return 1", a, c)[1] == 4%-3)
|
||||||
assert(T.testC("arith _; arith +; arith %; return 1", b, a, c)[1] ==
|
assert(T.testC("arith _; arith +; arith %; return 1", b, a, c)[1] ==
|
||||||
|
@ -312,9 +314,9 @@ assert(T.testC("concat 1; return 1", "xuxu") == "xuxu")
|
||||||
|
|
||||||
-- testing lua_is
|
-- testing lua_is
|
||||||
|
|
||||||
function B(x) return x and 1 or 0 end
|
local function B (x) return x and 1 or 0 end
|
||||||
|
|
||||||
function count (x, n)
|
local function count (x, n)
|
||||||
n = n or 2
|
n = n or 2
|
||||||
local prog = [[
|
local prog = [[
|
||||||
isnumber %d;
|
isnumber %d;
|
||||||
|
@ -345,7 +347,7 @@ assert(count(nil, 15) == 100)
|
||||||
|
|
||||||
-- testing lua_to...
|
-- testing lua_to...
|
||||||
|
|
||||||
function to (s, x, n)
|
local function to (s, x, n)
|
||||||
n = n or 2
|
n = n or 2
|
||||||
return T.testC(string.format("%s %d; return 1", s, n), x)
|
return T.testC(string.format("%s %d; return 1", s, n), x)
|
||||||
end
|
end
|
||||||
|
@ -486,11 +488,12 @@ a = T.testC([[
|
||||||
pushvalue 3; insert -2; pcall 1 1 0;
|
pushvalue 3; insert -2; pcall 1 1 0;
|
||||||
pcall 0 0 0;
|
pcall 0 0 0;
|
||||||
return 1
|
return 1
|
||||||
]], "x=150", function (a) assert(a==nil); return 3 end)
|
]], "XX=150", function (a) assert(a==nil); return 3 end)
|
||||||
|
|
||||||
assert(type(a) == 'string' and x == 150)
|
assert(type(a) == 'string' and XX == 150)
|
||||||
|
_G.XX = nil
|
||||||
|
|
||||||
function check3(p, ...)
|
local function check3(p, ...)
|
||||||
local arg = {...}
|
local arg = {...}
|
||||||
assert(#arg == 3)
|
assert(#arg == 3)
|
||||||
assert(string.find(arg[3], p))
|
assert(string.find(arg[3], p))
|
||||||
|
@ -500,7 +503,7 @@ check3("%.", T.testC("loadfile 2; return *", "."))
|
||||||
check3("xxxx", T.testC("loadfile 2; return *", "xxxx"))
|
check3("xxxx", T.testC("loadfile 2; return *", "xxxx"))
|
||||||
|
|
||||||
-- test errors in non protected threads
|
-- test errors in non protected threads
|
||||||
function checkerrnopro (code, msg)
|
local function checkerrnopro (code, msg)
|
||||||
local th = coroutine.create(function () end) -- create new thread
|
local th = coroutine.create(function () end) -- create new thread
|
||||||
local stt, err = pcall(T.testC, th, code) -- run code there
|
local stt, err = pcall(T.testC, th, code) -- run code there
|
||||||
assert(not stt and string.find(err, msg))
|
assert(not stt and string.find(err, msg))
|
||||||
|
@ -510,8 +513,9 @@ if not _soft then
|
||||||
collectgarbage("stop") -- avoid __gc with full stack
|
collectgarbage("stop") -- avoid __gc with full stack
|
||||||
checkerrnopro("pushnum 3; call 0 0", "attempt to call")
|
checkerrnopro("pushnum 3; call 0 0", "attempt to call")
|
||||||
print"testing stack overflow in unprotected thread"
|
print"testing stack overflow in unprotected thread"
|
||||||
function f () f() end
|
function F () F() end
|
||||||
checkerrnopro("getglobal 'f'; call 0 0;", "stack overflow")
|
checkerrnopro("getglobal 'F'; call 0 0;", "stack overflow")
|
||||||
|
F = nil
|
||||||
collectgarbage("restart")
|
collectgarbage("restart")
|
||||||
end
|
end
|
||||||
print"+"
|
print"+"
|
||||||
|
@ -588,7 +592,7 @@ assert(a[a] == "x")
|
||||||
|
|
||||||
b = setmetatable({p = a}, {})
|
b = setmetatable({p = a}, {})
|
||||||
getmetatable(b).__index = function (t, i) return t.p[i] end
|
getmetatable(b).__index = function (t, i) return t.p[i] end
|
||||||
k, x = T.testC("gettable 3, return 2", 4, b, 20, 35, "x")
|
local k, x = T.testC("gettable 3, return 2", 4, b, 20, 35, "x")
|
||||||
assert(x == 15 and k == 35)
|
assert(x == 15 and k == 35)
|
||||||
k = T.testC("getfield 2 y, return 1", b)
|
k = T.testC("getfield 2 y, return 1", b)
|
||||||
assert(k == 12)
|
assert(k == 12)
|
||||||
|
@ -748,8 +752,8 @@ local i = T.ref{}
|
||||||
T.unref(i)
|
T.unref(i)
|
||||||
assert(T.ref{} == i)
|
assert(T.ref{} == i)
|
||||||
|
|
||||||
Arr = {}
|
local Arr = {}
|
||||||
Lim = 100
|
local Lim = 100
|
||||||
for i=1,Lim do -- lock many objects
|
for i=1,Lim do -- lock many objects
|
||||||
Arr[i] = T.ref({})
|
Arr[i] = T.ref({})
|
||||||
end
|
end
|
||||||
|
@ -761,7 +765,7 @@ for i=1,Lim do -- unlock all them
|
||||||
T.unref(Arr[i])
|
T.unref(Arr[i])
|
||||||
end
|
end
|
||||||
|
|
||||||
function printlocks ()
|
local function printlocks ()
|
||||||
local f = T.makeCfunc("gettable R; return 1")
|
local f = T.makeCfunc("gettable R; return 1")
|
||||||
local n = f("n")
|
local n = f("n")
|
||||||
print("n", n)
|
print("n", n)
|
||||||
|
@ -793,8 +797,8 @@ assert(type(T.getref(a)) == 'table')
|
||||||
|
|
||||||
|
|
||||||
-- colect in cl the `val' of all collected userdata
|
-- colect in cl the `val' of all collected userdata
|
||||||
tt = {}
|
local tt = {}
|
||||||
cl = {n=0}
|
local cl = {n=0}
|
||||||
A = nil; B = nil
|
A = nil; B = nil
|
||||||
local F
|
local F
|
||||||
F = function (x)
|
F = function (x)
|
||||||
|
@ -804,20 +808,20 @@ F = function (x)
|
||||||
d = nil
|
d = nil
|
||||||
assert(debug.getmetatable(x).__gc == F)
|
assert(debug.getmetatable(x).__gc == F)
|
||||||
assert(load("table.insert({}, {})"))() -- create more garbage
|
assert(load("table.insert({}, {})"))() -- create more garbage
|
||||||
collectgarbage() -- force a GC during GC
|
assert(not collectgarbage()) -- GC during GC (no op)
|
||||||
assert(debug.getmetatable(x).__gc == F) -- previous GC did not mess this?
|
|
||||||
local dummy = {} -- create more garbage during GC
|
local dummy = {} -- create more garbage during GC
|
||||||
if A ~= nil then
|
if A ~= nil then
|
||||||
assert(type(A) == "userdata")
|
assert(type(A) == "userdata")
|
||||||
assert(T.udataval(A) == B)
|
assert(T.udataval(A) == B)
|
||||||
debug.getmetatable(A) -- just access it
|
debug.getmetatable(A) -- just access it
|
||||||
end
|
end
|
||||||
A = x -- ressucita userdata
|
A = x -- ressurect userdata
|
||||||
B = udval
|
B = udval
|
||||||
return 1,2,3
|
return 1,2,3
|
||||||
end
|
end
|
||||||
tt.__gc = F
|
tt.__gc = F
|
||||||
|
|
||||||
|
|
||||||
-- test whether udate collection frees memory in the right time
|
-- test whether udate collection frees memory in the right time
|
||||||
do
|
do
|
||||||
collectgarbage();
|
collectgarbage();
|
||||||
|
@ -854,9 +858,9 @@ end
|
||||||
collectgarbage("stop")
|
collectgarbage("stop")
|
||||||
|
|
||||||
-- create 3 userdatas with tag `tt'
|
-- create 3 userdatas with tag `tt'
|
||||||
a = T.newuserdata(0); debug.setmetatable(a, tt); na = T.udataval(a)
|
a = T.newuserdata(0); debug.setmetatable(a, tt); local na = T.udataval(a)
|
||||||
b = T.newuserdata(0); debug.setmetatable(b, tt); nb = T.udataval(b)
|
b = T.newuserdata(0); debug.setmetatable(b, tt); local nb = T.udataval(b)
|
||||||
c = T.newuserdata(0); debug.setmetatable(c, tt); nc = T.udataval(c)
|
c = T.newuserdata(0); debug.setmetatable(c, tt); local nc = T.udataval(c)
|
||||||
|
|
||||||
-- create userdata without meta table
|
-- create userdata without meta table
|
||||||
x = T.newuserdata(4)
|
x = T.newuserdata(4)
|
||||||
|
@ -867,9 +871,9 @@ checkerr("FILE%* expected, got userdata", io.input, x)
|
||||||
|
|
||||||
assert(debug.getmetatable(x) == nil and debug.getmetatable(y) == nil)
|
assert(debug.getmetatable(x) == nil and debug.getmetatable(y) == nil)
|
||||||
|
|
||||||
d=T.ref(a);
|
local d = T.ref(a);
|
||||||
e=T.ref(b);
|
local e = T.ref(b);
|
||||||
f=T.ref(c);
|
local f = T.ref(c);
|
||||||
t = {T.getref(d), T.getref(e), T.getref(f)}
|
t = {T.getref(d), T.getref(e), T.getref(f)}
|
||||||
assert(t[1] == a and t[2] == b and t[3] == c)
|
assert(t[1] == a and t[2] == b and t[3] == c)
|
||||||
|
|
||||||
|
@ -889,7 +893,7 @@ tt=nil -- frees tt for GC
|
||||||
A = nil
|
A = nil
|
||||||
b = nil
|
b = nil
|
||||||
T.unref(d);
|
T.unref(d);
|
||||||
n5 = T.newuserdata(0)
|
local n5 = T.newuserdata(0)
|
||||||
debug.setmetatable(n5, {__gc=F})
|
debug.setmetatable(n5, {__gc=F})
|
||||||
n5 = T.udataval(n5)
|
n5 = T.udataval(n5)
|
||||||
collectgarbage()
|
collectgarbage()
|
||||||
|
@ -960,11 +964,11 @@ print'+'
|
||||||
|
|
||||||
|
|
||||||
-- testing changing hooks during hooks
|
-- testing changing hooks during hooks
|
||||||
_G.t = {}
|
_G.TT = {}
|
||||||
T.sethook([[
|
T.sethook([[
|
||||||
# set a line hook after 3 count hooks
|
# set a line hook after 3 count hooks
|
||||||
sethook 4 0 '
|
sethook 4 0 '
|
||||||
getglobal t;
|
getglobal TT;
|
||||||
pushvalue -3; append -2
|
pushvalue -3; append -2
|
||||||
pushvalue -2; append -2
|
pushvalue -2; append -2
|
||||||
']], "c", 3)
|
']], "c", 3)
|
||||||
|
@ -974,12 +978,13 @@ a = 1 -- count hook (set line hook)
|
||||||
a = 1 -- line hook
|
a = 1 -- line hook
|
||||||
a = 1 -- line hook
|
a = 1 -- line hook
|
||||||
debug.sethook()
|
debug.sethook()
|
||||||
t = _G.t
|
local t = _G.TT
|
||||||
assert(t[1] == "line")
|
assert(t[1] == "line")
|
||||||
line = t[2]
|
local line = t[2]
|
||||||
assert(t[3] == "line" and t[4] == line + 1)
|
assert(t[3] == "line" and t[4] == line + 1)
|
||||||
assert(t[5] == "line" and t[6] == line + 2)
|
assert(t[5] == "line" and t[6] == line + 2)
|
||||||
assert(t[7] == nil)
|
assert(t[7] == nil)
|
||||||
|
_G.TT = nil
|
||||||
|
|
||||||
|
|
||||||
-------------------------------------------------------------------------
|
-------------------------------------------------------------------------
|
||||||
|
@ -1004,6 +1009,7 @@ do -- testing errors during GC
|
||||||
collectgarbage("restart")
|
collectgarbage("restart")
|
||||||
warn("@on")
|
warn("@on")
|
||||||
end
|
end
|
||||||
|
_G.A = nil
|
||||||
-------------------------------------------------------------------------
|
-------------------------------------------------------------------------
|
||||||
-- test for userdata vals
|
-- test for userdata vals
|
||||||
do
|
do
|
||||||
|
@ -1033,8 +1039,8 @@ assert(a == 'alo' and b == '3')
|
||||||
|
|
||||||
T.doremote(L1, "_ERRORMESSAGE = nil")
|
T.doremote(L1, "_ERRORMESSAGE = nil")
|
||||||
-- error: `sin' is not defined
|
-- error: `sin' is not defined
|
||||||
a, _, b = T.doremote(L1, "return sin(1)")
|
a, b, c = T.doremote(L1, "return sin(1)")
|
||||||
assert(a == nil and b == 2) -- 2 == run-time error
|
assert(a == nil and c == 2) -- 2 == run-time error
|
||||||
|
|
||||||
-- error: syntax error
|
-- error: syntax error
|
||||||
a, b, c = T.doremote(L1, "return a+")
|
a, b, c = T.doremote(L1, "return a+")
|
||||||
|
@ -1205,7 +1211,7 @@ T.alloccount() -- remove limit
|
||||||
-- o that we get memory errors in all allocations of a given
|
-- o that we get memory errors in all allocations of a given
|
||||||
-- task, until there is enough memory to complete the task without
|
-- task, until there is enough memory to complete the task without
|
||||||
-- errors.
|
-- errors.
|
||||||
function testbytes (s, f)
|
local function testbytes (s, f)
|
||||||
collectgarbage()
|
collectgarbage()
|
||||||
local M = T.totalmem()
|
local M = T.totalmem()
|
||||||
local oldM = M
|
local oldM = M
|
||||||
|
@ -1230,7 +1236,7 @@ end
|
||||||
-- task, until there is enough allocations to complete the task without
|
-- task, until there is enough allocations to complete the task without
|
||||||
-- errors.
|
-- errors.
|
||||||
|
|
||||||
function testalloc (s, f)
|
local function testalloc (s, f)
|
||||||
collectgarbage()
|
collectgarbage()
|
||||||
local M = 0
|
local M = 0
|
||||||
local a,b = nil
|
local a,b = nil
|
||||||
|
@ -1297,12 +1303,12 @@ end)
|
||||||
-- testing threads
|
-- testing threads
|
||||||
|
|
||||||
-- get main thread from registry (at index LUA_RIDX_MAINTHREAD == 1)
|
-- get main thread from registry (at index LUA_RIDX_MAINTHREAD == 1)
|
||||||
mt = T.testC("rawgeti R 1; return 1")
|
local mt = T.testC("rawgeti R 1; return 1")
|
||||||
assert(type(mt) == "thread" and coroutine.running() == mt)
|
assert(type(mt) == "thread" and coroutine.running() == mt)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
function expand (n,s)
|
local function expand (n,s)
|
||||||
if n==0 then return "" end
|
if n==0 then return "" end
|
||||||
local e = string.rep("=", n)
|
local e = string.rep("=", n)
|
||||||
return string.format("T.doonnewstack([%s[ %s;\n collectgarbage(); %s]%s])\n",
|
return string.format("T.doonnewstack([%s[ %s;\n collectgarbage(); %s]%s])\n",
|
||||||
|
@ -1312,9 +1318,10 @@ end
|
||||||
G=0; collectgarbage(); a =collectgarbage("count")
|
G=0; collectgarbage(); a =collectgarbage("count")
|
||||||
load(expand(20,"G=G+1"))()
|
load(expand(20,"G=G+1"))()
|
||||||
assert(G==20); collectgarbage(); -- assert(gcinfo() <= a+1)
|
assert(G==20); collectgarbage(); -- assert(gcinfo() <= a+1)
|
||||||
|
G = nil
|
||||||
|
|
||||||
testamem("running code on new thread", function ()
|
testamem("running code on new thread", function ()
|
||||||
return T.doonnewstack("x=1") == 0 -- try to create thread
|
return T.doonnewstack("local x=1") == 0 -- try to create thread
|
||||||
end)
|
end)
|
||||||
|
|
||||||
|
|
||||||
|
@ -1328,13 +1335,13 @@ end)
|
||||||
local testprog = [[
|
local testprog = [[
|
||||||
local function foo () return end
|
local function foo () return end
|
||||||
local t = {"x"}
|
local t = {"x"}
|
||||||
a = "aaa"
|
AA = "aaa"
|
||||||
for i = 1, #t do a=a..t[i] end
|
for i = 1, #t do AA = AA .. t[i] end
|
||||||
return true
|
return true
|
||||||
]]
|
]]
|
||||||
|
|
||||||
-- testing memory x dofile
|
-- testing memory x dofile
|
||||||
_G.a = nil
|
_G.AA = nil
|
||||||
local t =os.tmpname()
|
local t =os.tmpname()
|
||||||
local f = assert(io.open(t, "w"))
|
local f = assert(io.open(t, "w"))
|
||||||
f:write(testprog)
|
f:write(testprog)
|
||||||
|
@ -1344,7 +1351,7 @@ testamem("dofile", function ()
|
||||||
return a and a()
|
return a and a()
|
||||||
end)
|
end)
|
||||||
assert(os.remove(t))
|
assert(os.remove(t))
|
||||||
assert(_G.a == "aaax")
|
assert(_G.AA == "aaax")
|
||||||
|
|
||||||
|
|
||||||
-- other generic tests
|
-- other generic tests
|
||||||
|
@ -1361,6 +1368,8 @@ testamem("dump/undump", function ()
|
||||||
return a and a()
|
return a and a()
|
||||||
end)
|
end)
|
||||||
|
|
||||||
|
_G.AA = nil
|
||||||
|
|
||||||
local t = os.tmpname()
|
local t = os.tmpname()
|
||||||
testamem("file creation", function ()
|
testamem("file creation", function ()
|
||||||
local f = assert(io.open(t, 'w'))
|
local f = assert(io.open(t, 'w'))
|
||||||
|
@ -1382,7 +1391,7 @@ testamem("constructors", function ()
|
||||||
end)
|
end)
|
||||||
|
|
||||||
local a = 1
|
local a = 1
|
||||||
close = nil
|
local close = nil
|
||||||
testamem("closure creation", function ()
|
testamem("closure creation", function ()
|
||||||
function close (b)
|
function close (b)
|
||||||
return function (x) return b + x end
|
return function (x) return b + x end
|
||||||
|
|
34
third_party/lua/test/attrib.lua
vendored
34
third_party/lua/test/attrib.lua
vendored
|
@ -85,7 +85,7 @@ local DIR = "libs" .. dirsep
|
||||||
|
|
||||||
-- prepend DIR to a name and correct directory separators
|
-- prepend DIR to a name and correct directory separators
|
||||||
local function D (x)
|
local function D (x)
|
||||||
x = string.gsub(x, "/", dirsep)
|
local x = string.gsub(x, "/", dirsep)
|
||||||
return DIR .. x
|
return DIR .. x
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@ -106,7 +106,7 @@ local function createfiles (files, preextras, posextras)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
function removefiles (files)
|
local function removefiles (files)
|
||||||
for n in pairs(files) do
|
for n in pairs(files) do
|
||||||
os.remove(D(n))
|
os.remove(D(n))
|
||||||
end
|
end
|
||||||
|
@ -154,10 +154,9 @@ local try = function (p, n, r, ext)
|
||||||
assert(ext == x)
|
assert(ext == x)
|
||||||
end
|
end
|
||||||
|
|
||||||
a = require"names"
|
local a = require"names"
|
||||||
assert(a[1] == "names" and a[2] == D"names.lua")
|
assert(a[1] == "names" and a[2] == D"names.lua")
|
||||||
|
|
||||||
_G.a = nil
|
|
||||||
local st, msg = pcall(require, "err")
|
local st, msg = pcall(require, "err")
|
||||||
assert(not st and string.find(msg, "arithmetic") and B == 15)
|
assert(not st and string.find(msg, "arithmetic") and B == 15)
|
||||||
st, msg = pcall(require, "synerr")
|
st, msg = pcall(require, "synerr")
|
||||||
|
@ -191,6 +190,7 @@ try("X", "XXxX", AA, "libs/XXxX")
|
||||||
|
|
||||||
|
|
||||||
removefiles(files)
|
removefiles(files)
|
||||||
|
NAME, REQUIRED, AA, B = nil
|
||||||
|
|
||||||
|
|
||||||
-- testing require of sub-packages
|
-- testing require of sub-packages
|
||||||
|
@ -223,7 +223,7 @@ assert(require"P1" == m and m.AA == 10)
|
||||||
|
|
||||||
|
|
||||||
removefiles(files)
|
removefiles(files)
|
||||||
|
AA = nil
|
||||||
|
|
||||||
package.path = ""
|
package.path = ""
|
||||||
assert(not pcall(require, "file_does_not_exist"))
|
assert(not pcall(require, "file_does_not_exist"))
|
||||||
|
@ -305,6 +305,7 @@ else
|
||||||
assert(_ENV.x == "lib1.sub" and _ENV.y == DC"lib1")
|
assert(_ENV.x == "lib1.sub" and _ENV.y == DC"lib1")
|
||||||
assert(string.find(ext, "libs/lib1", 1, true))
|
assert(string.find(ext, "libs/lib1", 1, true))
|
||||||
assert(fs.id(45) == 45)
|
assert(fs.id(45) == 45)
|
||||||
|
_ENV.x, _ENV.y = nil
|
||||||
end
|
end
|
||||||
|
|
||||||
_ENV = _G
|
_ENV = _G
|
||||||
|
@ -338,10 +339,10 @@ print("testing assignments, logical operators, and constructors")
|
||||||
|
|
||||||
local res, res2 = 27
|
local res, res2 = 27
|
||||||
|
|
||||||
a, b = 1, 2+3
|
local a, b = 1, 2+3
|
||||||
assert(a==1 and b==5)
|
assert(a==1 and b==5)
|
||||||
a={}
|
a={}
|
||||||
function f() return 10, 11, 12 end
|
local function f() return 10, 11, 12 end
|
||||||
a.x, b, a[1] = 1, 2, f()
|
a.x, b, a[1] = 1, 2, f()
|
||||||
assert(a.x==1 and b==2 and a[1]==10)
|
assert(a.x==1 and b==2 and a[1]==10)
|
||||||
a[f()], b, a[f()+3] = f(), a, 'x'
|
a[f()], b, a[f()+3] = f(), a, 'x'
|
||||||
|
@ -353,15 +354,15 @@ do
|
||||||
local a,b,c
|
local a,b,c
|
||||||
a,b = 0, f(1)
|
a,b = 0, f(1)
|
||||||
assert(a == 0 and b == 1)
|
assert(a == 0 and b == 1)
|
||||||
A,b = 0, f(1)
|
a,b = 0, f(1)
|
||||||
assert(A == 0 and b == 1)
|
assert(a == 0 and b == 1)
|
||||||
a,b,c = 0,5,f(4)
|
a,b,c = 0,5,f(4)
|
||||||
assert(a==0 and b==5 and c==1)
|
assert(a==0 and b==5 and c==1)
|
||||||
a,b,c = 0,5,f(0)
|
a,b,c = 0,5,f(0)
|
||||||
assert(a==0 and b==5 and c==nil)
|
assert(a==0 and b==5 and c==nil)
|
||||||
end
|
end
|
||||||
|
|
||||||
a, b, c, d = 1 and nil, 1 or nil, (1 and (nil or 1)), 6
|
local a, b, c, d = 1 and nil, 1 or nil, (1 and (nil or 1)), 6
|
||||||
assert(not a and b and c and d==6)
|
assert(not a and b and c and d==6)
|
||||||
|
|
||||||
d = 20
|
d = 20
|
||||||
|
@ -419,6 +420,7 @@ assert(not pcall(function () local a = {[nil] = 10} end))
|
||||||
assert(a[nil] == undef)
|
assert(a[nil] == undef)
|
||||||
a = nil
|
a = nil
|
||||||
|
|
||||||
|
local a, b, c
|
||||||
a = {10,9,8,7,6,5,4,3,2; [-3]='a', [f]=print, a='a', b='ab'}
|
a = {10,9,8,7,6,5,4,3,2; [-3]='a', [f]=print, a='a', b='ab'}
|
||||||
a, a.x, a.y = a, a[-3]
|
a, a.x, a.y = a, a[-3]
|
||||||
assert(a[1]==10 and a[-3]==a.a and a[f]==print and a.x=='a' and not a.y)
|
assert(a[1]==10 and a[-3]==a.a and a[f]==print and a.x=='a' and not a.y)
|
||||||
|
@ -434,6 +436,16 @@ a.aVeryLongName012345678901234567890123456789012345678901234567890123456789 ==
|
||||||
10)
|
10)
|
||||||
|
|
||||||
|
|
||||||
|
do
|
||||||
|
-- _ENV constant
|
||||||
|
local function foo ()
|
||||||
|
local _ENV <const> = 11
|
||||||
|
X = "hi"
|
||||||
|
end
|
||||||
|
local st, msg = pcall(foo)
|
||||||
|
assert(not st and string.find(msg, "number"))
|
||||||
|
end
|
||||||
|
|
||||||
|
|
||||||
-- test of large float/integer indices
|
-- test of large float/integer indices
|
||||||
|
|
||||||
|
@ -445,7 +457,7 @@ while maxint ~= (maxint + 0.0) or (maxint - 1) ~= (maxint - 1.0) do
|
||||||
maxint = maxint // 2
|
maxint = maxint // 2
|
||||||
end
|
end
|
||||||
|
|
||||||
maxintF = maxint + 0.0 -- float version
|
local maxintF = maxint + 0.0 -- float version
|
||||||
|
|
||||||
assert(maxintF == maxint and math.type(maxintF) == "float" and
|
assert(maxintF == maxint and math.type(maxintF) == "float" and
|
||||||
maxintF >= 2.0^14)
|
maxintF >= 2.0^14)
|
||||||
|
|
2
third_party/lua/test/big.lua
vendored
2
third_party/lua/test/big.lua
vendored
|
@ -32,7 +32,7 @@ setmetatable(env, {
|
||||||
})
|
})
|
||||||
|
|
||||||
X = nil
|
X = nil
|
||||||
co = coroutine.wrap(f)
|
local co = coroutine.wrap(f)
|
||||||
assert(co() == 's')
|
assert(co() == 's')
|
||||||
assert(co() == 'g')
|
assert(co() == 'g')
|
||||||
assert(co() == 'g')
|
assert(co() == 'g')
|
||||||
|
|
17
third_party/lua/test/bitwise.lua
vendored
17
third_party/lua/test/bitwise.lua
vendored
|
@ -38,6 +38,18 @@ d = d << 32
|
||||||
assert(a | b ~ c & d == 0xF4000000 << 32)
|
assert(a | b ~ c & d == 0xF4000000 << 32)
|
||||||
assert(~~a == a and ~a == -1 ~ a and -d == ~d + 1)
|
assert(~~a == a and ~a == -1 ~ a and -d == ~d + 1)
|
||||||
|
|
||||||
|
|
||||||
|
do -- constant folding
|
||||||
|
local code = string.format("return -1 >> %d", math.maxinteger)
|
||||||
|
assert(load(code)() == 0)
|
||||||
|
local code = string.format("return -1 >> %d", math.mininteger)
|
||||||
|
assert(load(code)() == 0)
|
||||||
|
local code = string.format("return -1 << %d", math.maxinteger)
|
||||||
|
assert(load(code)() == 0)
|
||||||
|
local code = string.format("return -1 << %d", math.mininteger)
|
||||||
|
assert(load(code)() == 0)
|
||||||
|
end
|
||||||
|
|
||||||
assert(-1 >> 1 == (1 << (numbits - 1)) - 1 and 1 << 31 == 0x80000000)
|
assert(-1 >> 1 == (1 << (numbits - 1)) - 1 and 1 << 31 == 0x80000000)
|
||||||
assert(-1 >> (numbits - 1) == 1)
|
assert(-1 >> (numbits - 1) == 1)
|
||||||
assert(-1 >> numbits == 0 and
|
assert(-1 >> numbits == 0 and
|
||||||
|
@ -45,6 +57,11 @@ assert(-1 >> numbits == 0 and
|
||||||
-1 << numbits == 0 and
|
-1 << numbits == 0 and
|
||||||
-1 << -numbits == 0)
|
-1 << -numbits == 0)
|
||||||
|
|
||||||
|
assert(1 >> math.mininteger == 0)
|
||||||
|
assert(1 >> math.maxinteger == 0)
|
||||||
|
assert(1 << math.mininteger == 0)
|
||||||
|
assert(1 << math.maxinteger == 0)
|
||||||
|
|
||||||
assert((2^30 - 1) << 2^30 == 0)
|
assert((2^30 - 1) << 2^30 == 0)
|
||||||
assert((2^30 - 1) >> 2^30 == 0)
|
assert((2^30 - 1) >> 2^30 == 0)
|
||||||
|
|
||||||
|
|
68
third_party/lua/test/calls.lua
vendored
68
third_party/lua/test/calls.lua
vendored
|
@ -16,7 +16,7 @@ assert(type(nil) == 'nil'
|
||||||
and type(type) == 'function')
|
and type(type) == 'function')
|
||||||
|
|
||||||
assert(type(assert) == type(print))
|
assert(type(assert) == type(print))
|
||||||
function f (x) return a:x (x) end
|
local function f (x) return a:x (x) end
|
||||||
assert(type(f) == 'function')
|
assert(type(f) == 'function')
|
||||||
assert(not pcall(type))
|
assert(not pcall(type))
|
||||||
|
|
||||||
|
@ -33,10 +33,11 @@ do
|
||||||
assert(fact(5) == 120)
|
assert(fact(5) == 120)
|
||||||
end
|
end
|
||||||
assert(fact == false)
|
assert(fact == false)
|
||||||
|
fact = nil
|
||||||
|
|
||||||
-- testing declarations
|
-- testing declarations
|
||||||
a = {i = 10}
|
local a = {i = 10}
|
||||||
self = 20
|
local self = 20
|
||||||
function a:x (x) return x+self.i end
|
function a:x (x) return x+self.i end
|
||||||
function a.y (x) return x+self end
|
function a.y (x) return x+self end
|
||||||
|
|
||||||
|
@ -72,6 +73,8 @@ f(1,2, -- this one too
|
||||||
3,4)
|
3,4)
|
||||||
assert(t[1] == 1 and t[2] == 2 and t[3] == 3 and t[4] == 'a')
|
assert(t[1] == 1 and t[2] == 2 and t[3] == 3 and t[4] == 'a')
|
||||||
|
|
||||||
|
t = nil -- delete 't'
|
||||||
|
|
||||||
function fat(x)
|
function fat(x)
|
||||||
if x <= 1 then return 1
|
if x <= 1 then return 1
|
||||||
else return x*load("return fat(" .. x-1 .. ")", "")()
|
else return x*load("return fat(" .. x-1 .. ")", "")()
|
||||||
|
@ -80,26 +83,29 @@ end
|
||||||
|
|
||||||
assert(load "load 'assert(fat(6)==720)' () ")()
|
assert(load "load 'assert(fat(6)==720)' () ")()
|
||||||
a = load('return fat(5), 3')
|
a = load('return fat(5), 3')
|
||||||
a,b = a()
|
local a,b = a()
|
||||||
assert(a == 120 and b == 3)
|
assert(a == 120 and b == 3)
|
||||||
|
fat = nil
|
||||||
print('+')
|
print('+')
|
||||||
|
|
||||||
function err_on_n (n)
|
local function err_on_n (n)
|
||||||
if n==0 then error(); exit(1);
|
if n==0 then error(); exit(1);
|
||||||
else err_on_n (n-1); exit(1);
|
else err_on_n (n-1); exit(1);
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
do
|
do
|
||||||
function dummy (n)
|
local function dummy (n)
|
||||||
if n > 0 then
|
if n > 0 then
|
||||||
assert(not pcall(err_on_n, n))
|
assert(not pcall(err_on_n, n))
|
||||||
dummy(n-1)
|
dummy(n-1)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
dummy(10)
|
||||||
end
|
end
|
||||||
|
|
||||||
dummy(10)
|
_G.deep = nil -- "declaration" (used by 'all.lua')
|
||||||
|
|
||||||
function deep (n)
|
function deep (n)
|
||||||
if n>0 then deep(n-1) end
|
if n>0 then deep(n-1) end
|
||||||
|
@ -151,6 +157,16 @@ do -- tail calls x varargs
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
||||||
|
do -- C-stack overflow while handling C-stack overflow
|
||||||
|
local function loop ()
|
||||||
|
assert(pcall(loop))
|
||||||
|
end
|
||||||
|
|
||||||
|
local err, msg = xpcall(loop, loop)
|
||||||
|
assert(not err and string.find(msg, "error"))
|
||||||
|
end
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
do -- tail calls x chain of __call
|
do -- tail calls x chain of __call
|
||||||
local n = 10000 -- depth
|
local n = 10000 -- depth
|
||||||
|
@ -199,7 +215,7 @@ assert(a == 23 and (function (x) return x*2 end)(20) == 40)
|
||||||
-- testing closures
|
-- testing closures
|
||||||
|
|
||||||
-- fixed-point operator
|
-- fixed-point operator
|
||||||
Z = function (le)
|
local Z = function (le)
|
||||||
local function a (f)
|
local function a (f)
|
||||||
return le(function (x) return f(f)(x) end)
|
return le(function (x) return f(f)(x) end)
|
||||||
end
|
end
|
||||||
|
@ -209,14 +225,14 @@ Z = function (le)
|
||||||
|
|
||||||
-- non-recursive factorial
|
-- non-recursive factorial
|
||||||
|
|
||||||
F = function (f)
|
local F = function (f)
|
||||||
return function (n)
|
return function (n)
|
||||||
if n == 0 then return 1
|
if n == 0 then return 1
|
||||||
else return n*f(n-1) end
|
else return n*f(n-1) end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
fat = Z(F)
|
local fat = Z(F)
|
||||||
|
|
||||||
assert(fat(0) == 1 and fat(4) == 24 and Z(F)(5)==5*Z(F)(4))
|
assert(fat(0) == 1 and fat(4) == 24 and Z(F)(5)==5*Z(F)(4))
|
||||||
|
|
||||||
|
@ -227,22 +243,21 @@ local function g (z)
|
||||||
return f(z,z+1,z+2,z+3)
|
return f(z,z+1,z+2,z+3)
|
||||||
end
|
end
|
||||||
|
|
||||||
f = g(10)
|
local f = g(10)
|
||||||
assert(f(9, 16) == 10+11+12+13+10+9+16+10)
|
assert(f(9, 16) == 10+11+12+13+10+9+16+10)
|
||||||
|
|
||||||
Z, F, f = nil
|
|
||||||
print('+')
|
print('+')
|
||||||
|
|
||||||
-- testing multiple returns
|
-- testing multiple returns
|
||||||
|
|
||||||
function unlpack (t, i)
|
local function unlpack (t, i)
|
||||||
i = i or 1
|
i = i or 1
|
||||||
if (i <= #t) then
|
if (i <= #t) then
|
||||||
return t[i], unlpack(t, i+1)
|
return t[i], unlpack(t, i+1)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
function equaltab (t1, t2)
|
local function equaltab (t1, t2)
|
||||||
assert(#t1 == #t2)
|
assert(#t1 == #t2)
|
||||||
for i = 1, #t1 do
|
for i = 1, #t1 do
|
||||||
assert(t1[i] == t2[i])
|
assert(t1[i] == t2[i])
|
||||||
|
@ -251,8 +266,8 @@ end
|
||||||
|
|
||||||
local pack = function (...) return (table.pack(...)) end
|
local pack = function (...) return (table.pack(...)) end
|
||||||
|
|
||||||
function f() return 1,2,30,4 end
|
local function f() return 1,2,30,4 end
|
||||||
function ret2 (a,b) return a,b end
|
local function ret2 (a,b) return a,b end
|
||||||
|
|
||||||
local a,b,c,d = unlpack{1,2,3}
|
local a,b,c,d = unlpack{1,2,3}
|
||||||
assert(a==1 and b==2 and c==3 and d==nil)
|
assert(a==1 and b==2 and c==3 and d==nil)
|
||||||
|
@ -281,7 +296,7 @@ table.sort({10,9,8,4,19,23,0,0}, function (a,b) return a<b end, "extra arg")
|
||||||
local x = "-- a comment\0\0\0\n x = 10 + \n23; \
|
local x = "-- a comment\0\0\0\n x = 10 + \n23; \
|
||||||
local a = function () x = 'hi' end; \
|
local a = function () x = 'hi' end; \
|
||||||
return '\0'"
|
return '\0'"
|
||||||
function read1 (x)
|
local function read1 (x)
|
||||||
local i = 0
|
local i = 0
|
||||||
return function ()
|
return function ()
|
||||||
collectgarbage()
|
collectgarbage()
|
||||||
|
@ -290,7 +305,7 @@ function read1 (x)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
function cannotload (msg, a,b)
|
local function cannotload (msg, a,b)
|
||||||
assert(not a and string.find(b, msg))
|
assert(not a and string.find(b, msg))
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@ -327,11 +342,26 @@ do -- another bug (in 5.4.0)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
||||||
|
do -- another bug (since 5.2)
|
||||||
|
-- corrupted binary dump: list of upvalue names is larger than number
|
||||||
|
-- of upvalues, overflowing the array of upvalues.
|
||||||
|
local code =
|
||||||
|
"\x1b\x4c\x75\x61\x54\x00\x19\x93\x0d\x0a\x1a\x0a\x04\x08\x08\x78\x56\z
|
||||||
|
\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x28\x77\x40\x00\x86\x40\z
|
||||||
|
\x74\x65\x6d\x70\x81\x81\x01\x00\x02\x82\x48\x00\x02\x00\xc7\x00\x01\z
|
||||||
|
\x00\x80\x80\x80\x82\x00\x00\x80\x81\x82\x78\x80\x82\x81\x86\x40\x74\z
|
||||||
|
\x65\x6d\x70"
|
||||||
|
|
||||||
|
assert(load(code)) -- segfaults in previous versions
|
||||||
|
end
|
||||||
|
|
||||||
|
|
||||||
x = string.dump(load("x = 1; return x"))
|
x = string.dump(load("x = 1; return x"))
|
||||||
a = assert(load(read1(x), nil, "b"))
|
a = assert(load(read1(x), nil, "b"))
|
||||||
assert(a() == 1 and _G.x == 1)
|
assert(a() == 1 and _G.x == 1)
|
||||||
cannotload("attempt to load a binary chunk", load(read1(x), nil, "t"))
|
cannotload("attempt to load a binary chunk", load(read1(x), nil, "t"))
|
||||||
cannotload("attempt to load a binary chunk", load(x, nil, "t"))
|
cannotload("attempt to load a binary chunk", load(x, nil, "t"))
|
||||||
|
_G.x = nil
|
||||||
|
|
||||||
assert(not pcall(string.dump, print)) -- no dump of C functions
|
assert(not pcall(string.dump, print)) -- no dump of C functions
|
||||||
|
|
||||||
|
@ -356,7 +386,7 @@ debug.setupvalue(x, 2, _G)
|
||||||
assert(x() == 123)
|
assert(x() == 123)
|
||||||
|
|
||||||
assert(assert(load("return XX + ...", nil, nil, {XX = 13}))(4) == 17)
|
assert(assert(load("return XX + ...", nil, nil, {XX = 13}))(4) == 17)
|
||||||
|
XX = nil
|
||||||
|
|
||||||
-- test generic load with nested functions
|
-- test generic load with nested functions
|
||||||
x = [[
|
x = [[
|
||||||
|
|
6
third_party/lua/test/closure.lua
vendored
6
third_party/lua/test/closure.lua
vendored
|
@ -4,7 +4,7 @@
|
||||||
print "testing closures"
|
print "testing closures"
|
||||||
|
|
||||||
local A,B = 0,{g=10}
|
local A,B = 0,{g=10}
|
||||||
function f(x)
|
local function f(x)
|
||||||
local a = {}
|
local a = {}
|
||||||
for i=1,1000 do
|
for i=1,1000 do
|
||||||
local y = 0
|
local y = 0
|
||||||
|
@ -89,6 +89,7 @@ assert(r == "a" and s == "b")
|
||||||
|
|
||||||
|
|
||||||
-- testing closures with 'for' control variable x break
|
-- testing closures with 'for' control variable x break
|
||||||
|
local f
|
||||||
for i=1,3 do
|
for i=1,3 do
|
||||||
f = function () return i end
|
f = function () return i end
|
||||||
break
|
break
|
||||||
|
@ -139,7 +140,7 @@ assert(b('get') == 'xuxu')
|
||||||
b('set', 10); assert(b('get') == 14)
|
b('set', 10); assert(b('get') == 14)
|
||||||
|
|
||||||
|
|
||||||
local w
|
local y, w
|
||||||
-- testing multi-level closure
|
-- testing multi-level closure
|
||||||
function f(x)
|
function f(x)
|
||||||
return function (y)
|
return function (y)
|
||||||
|
@ -230,6 +231,7 @@ t()
|
||||||
-- test for debug manipulation of upvalues
|
-- test for debug manipulation of upvalues
|
||||||
local debug = require'debug'
|
local debug = require'debug'
|
||||||
|
|
||||||
|
local foo1, foo2, foo3
|
||||||
do
|
do
|
||||||
local a , b, c = 3, 5, 7
|
local a , b, c = 3, 5, 7
|
||||||
foo1 = function () return a+b end;
|
foo1 = function () return a+b end;
|
||||||
|
|
20
third_party/lua/test/code.lua
vendored
20
third_party/lua/test/code.lua
vendored
|
@ -69,10 +69,24 @@ foo = function (f, a)
|
||||||
checkKlist(foo, {100000, 100000.0, -100000, -100000.0})
|
checkKlist(foo, {100000, 100000.0, -100000, -100000.0})
|
||||||
|
|
||||||
|
|
||||||
|
-- floats x integers
|
||||||
|
foo = function (t, a)
|
||||||
|
t[a] = 1; t[a] = 1.0
|
||||||
|
t[a] = 1; t[a] = 1.0
|
||||||
|
t[a] = 2; t[a] = 2.0
|
||||||
|
t[a] = 0; t[a] = 0.0
|
||||||
|
t[a] = 1; t[a] = 1.0
|
||||||
|
t[a] = 2; t[a] = 2.0
|
||||||
|
t[a] = 0; t[a] = 0.0
|
||||||
|
end
|
||||||
|
|
||||||
|
checkKlist(foo, {1, 1.0, 2, 2.0, 0, 0.0})
|
||||||
|
|
||||||
|
|
||||||
-- testing opcodes
|
-- testing opcodes
|
||||||
|
|
||||||
-- check that 'f' opcodes match '...'
|
-- check that 'f' opcodes match '...'
|
||||||
function check (f, ...)
|
local function check (f, ...)
|
||||||
local arg = {...}
|
local arg = {...}
|
||||||
local c = T.listcode(f)
|
local c = T.listcode(f)
|
||||||
for i=1, #arg do
|
for i=1, #arg do
|
||||||
|
@ -85,7 +99,7 @@ end
|
||||||
|
|
||||||
|
|
||||||
-- check that 'f' opcodes match '...' and that 'f(p) == r'.
|
-- check that 'f' opcodes match '...' and that 'f(p) == r'.
|
||||||
function checkR (f, p, r, ...)
|
local function checkR (f, p, r, ...)
|
||||||
local r1 = f(p)
|
local r1 = f(p)
|
||||||
assert(r == r1 and math.type(r) == math.type(r1))
|
assert(r == r1 and math.type(r) == math.type(r1))
|
||||||
check(f, ...)
|
check(f, ...)
|
||||||
|
@ -93,7 +107,7 @@ end
|
||||||
|
|
||||||
|
|
||||||
-- check that 'a' and 'b' has the same opcodes
|
-- check that 'a' and 'b' has the same opcodes
|
||||||
function checkequal (a, b)
|
local function checkequal (a, b)
|
||||||
a = T.listcode(a)
|
a = T.listcode(a)
|
||||||
b = T.listcode(b)
|
b = T.listcode(b)
|
||||||
assert(#a == #b)
|
assert(#a == #b)
|
||||||
|
|
61
third_party/lua/test/constructs.lua
vendored
61
third_party/lua/test/constructs.lua
vendored
|
@ -11,6 +11,7 @@ local function checkload (s, msg)
|
||||||
end
|
end
|
||||||
|
|
||||||
-- testing semicollons
|
-- testing semicollons
|
||||||
|
local a
|
||||||
do ;;; end
|
do ;;; end
|
||||||
; do ; a = 3; assert(a == 3) end;
|
; do ; a = 3; assert(a == 3) end;
|
||||||
;
|
;
|
||||||
|
@ -49,10 +50,10 @@ assert((((nil and true) or false) and true) == false)
|
||||||
|
|
||||||
local a,b = 1,nil;
|
local a,b = 1,nil;
|
||||||
assert(-(1 or 2) == -1 and (1 and 2)+(-1.25 or -4) == 0.75);
|
assert(-(1 or 2) == -1 and (1 and 2)+(-1.25 or -4) == 0.75);
|
||||||
x = ((b or a)+1 == 2 and (10 or a)+1 == 11); assert(x);
|
local x = ((b or a)+1 == 2 and (10 or a)+1 == 11); assert(x);
|
||||||
x = (((2<3) or 1) == true and (2<3 and 4) == 4); assert(x);
|
x = (((2<3) or 1) == true and (2<3 and 4) == 4); assert(x);
|
||||||
|
|
||||||
x,y=1,2;
|
local x, y = 1, 2;
|
||||||
assert((x>y) and x or y == 2);
|
assert((x>y) and x or y == 2);
|
||||||
x,y=2,1;
|
x,y=2,1;
|
||||||
assert((x>y) and x or y == 2);
|
assert((x>y) and x or y == 2);
|
||||||
|
@ -77,13 +78,13 @@ do -- testing operators with diffent kinds of constants
|
||||||
local gab = f(o1, o2)
|
local gab = f(o1, o2)
|
||||||
|
|
||||||
_ENV.XX = o1
|
_ENV.XX = o1
|
||||||
code = string.format("return XX %s %s", op, o2)
|
local code = string.format("return XX %s %s", op, o2)
|
||||||
res = assert(load(code))()
|
local res = assert(load(code))()
|
||||||
assert(res == gab)
|
assert(res == gab)
|
||||||
|
|
||||||
_ENV.XX = o2
|
_ENV.XX = o2
|
||||||
local code = string.format("return (%s) %s XX", o1, op)
|
code = string.format("return (%s) %s XX", o1, op)
|
||||||
local res = assert(load(code))()
|
res = assert(load(code))()
|
||||||
assert(res == gab)
|
assert(res == gab)
|
||||||
|
|
||||||
code = string.format("return (%s) %s %s", o1, op, o2)
|
code = string.format("return (%s) %s %s", o1, op, o2)
|
||||||
|
@ -92,6 +93,7 @@ do -- testing operators with diffent kinds of constants
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
_ENV.XX = nil
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
||||||
|
@ -100,10 +102,35 @@ repeat until 1; repeat until true;
|
||||||
while false do end; while nil do end;
|
while false do end; while nil do end;
|
||||||
|
|
||||||
do -- test old bug (first name could not be an `upvalue')
|
do -- test old bug (first name could not be an `upvalue')
|
||||||
local a; function f(x) x={a=1}; x={x=1}; x={G=1} end
|
local a; local function f(x) x={a=1}; x={x=1}; x={G=1} end
|
||||||
end
|
end
|
||||||
|
|
||||||
function f (i)
|
|
||||||
|
do -- bug since 5.4.0
|
||||||
|
-- create code with a table using more than 256 constants
|
||||||
|
local code = {"local x = {"}
|
||||||
|
for i = 1, 257 do
|
||||||
|
code[#code + 1] = i .. ".1,"
|
||||||
|
end
|
||||||
|
code[#code + 1] = "};"
|
||||||
|
code = table.concat(code)
|
||||||
|
|
||||||
|
-- add "ret" to the end of that code and checks that
|
||||||
|
-- it produces the expected value "val"
|
||||||
|
local function check (ret, val)
|
||||||
|
local code = code .. ret
|
||||||
|
code = load(code)
|
||||||
|
assert(code() == val)
|
||||||
|
end
|
||||||
|
|
||||||
|
check("return (1 ~ (2 or 3))", 1 ~ 2)
|
||||||
|
check("return (1 | (2 or 3))", 1 | 2)
|
||||||
|
check("return (1 + (2 or 3))", 1 + 2)
|
||||||
|
check("return (1 << (2 or 3))", 1 << 2)
|
||||||
|
end
|
||||||
|
|
||||||
|
|
||||||
|
local function f (i)
|
||||||
if type(i) ~= 'number' then return i,'jojo'; end;
|
if type(i) ~= 'number' then return i,'jojo'; end;
|
||||||
if i > 0 then return i, f(i-1); end;
|
if i > 0 then return i, f(i-1); end;
|
||||||
end
|
end
|
||||||
|
@ -129,10 +156,10 @@ end
|
||||||
assert(f(3) == 'a' and f(12) == 'b' and f(26) == 'c' and f(100) == nil)
|
assert(f(3) == 'a' and f(12) == 'b' and f(26) == 'c' and f(100) == nil)
|
||||||
|
|
||||||
for i=1,1000 do break; end;
|
for i=1,1000 do break; end;
|
||||||
n=100;
|
local n=100;
|
||||||
i=3;
|
local i=3;
|
||||||
t = {};
|
local t = {};
|
||||||
a=nil
|
local a=nil
|
||||||
while not a do
|
while not a do
|
||||||
a=0; for i=1,n do for i=i,1,-1 do a=a+1; t[i]=1; end; end;
|
a=0; for i=1,n do for i=i,1,-1 do a=a+1; t[i]=1; end; end;
|
||||||
end
|
end
|
||||||
|
@ -175,14 +202,14 @@ a={y=1}
|
||||||
x = {a.y}
|
x = {a.y}
|
||||||
assert(x[1] == 1)
|
assert(x[1] == 1)
|
||||||
|
|
||||||
function f(i)
|
local function f (i)
|
||||||
while 1 do
|
while 1 do
|
||||||
if i>0 then i=i-1;
|
if i>0 then i=i-1;
|
||||||
else return; end;
|
else return; end;
|
||||||
end;
|
end;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
function g(i)
|
local function g(i)
|
||||||
while 1 do
|
while 1 do
|
||||||
if i>0 then i=i-1
|
if i>0 then i=i-1
|
||||||
else return end
|
else return end
|
||||||
|
@ -247,7 +274,7 @@ function g (a,b,c,d,e)
|
||||||
if not (a>=b or c or d and e or nil) then return 0; else return 1; end;
|
if not (a>=b or c or d and e or nil) then return 0; else return 1; end;
|
||||||
end
|
end
|
||||||
|
|
||||||
function h (a,b,c,d,e)
|
local function h (a,b,c,d,e)
|
||||||
while (a>=b or c or (d and e) or nil) do return 1; end;
|
while (a>=b or c or (d and e) or nil) do return 1; end;
|
||||||
return 0;
|
return 0;
|
||||||
end;
|
end;
|
||||||
|
@ -275,7 +302,7 @@ do
|
||||||
assert(a==2)
|
assert(a==2)
|
||||||
end
|
end
|
||||||
|
|
||||||
function F(a)
|
local function F (a)
|
||||||
assert(debug.getinfo(1, "n").name == 'F')
|
assert(debug.getinfo(1, "n").name == 'F')
|
||||||
return a,2,3
|
return a,2,3
|
||||||
end
|
end
|
||||||
|
@ -368,6 +395,8 @@ for n = 1, level do
|
||||||
if i % 60000 == 0 then print('+') end
|
if i % 60000 == 0 then print('+') end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
IX = nil
|
||||||
|
_G.GLOB1 = nil
|
||||||
------------------------------------------------------------------
|
------------------------------------------------------------------
|
||||||
|
|
||||||
-- testing some syntax errors (chosen through 'gcov')
|
-- testing some syntax errors (chosen through 'gcov')
|
||||||
|
|
117
third_party/lua/test/coroutine.lua
vendored
117
third_party/lua/test/coroutine.lua
vendored
|
@ -30,7 +30,8 @@ local function eqtab (t1, t2)
|
||||||
end
|
end
|
||||||
|
|
||||||
_G.x = nil -- declare x
|
_G.x = nil -- declare x
|
||||||
function foo (a, ...)
|
_G.f = nil -- declare f
|
||||||
|
local function foo (a, ...)
|
||||||
local x, y = coroutine.running()
|
local x, y = coroutine.running()
|
||||||
assert(x == f and y == false)
|
assert(x == f and y == false)
|
||||||
-- next call should not corrupt coroutine (but must fail,
|
-- next call should not corrupt coroutine (but must fail,
|
||||||
|
@ -67,10 +68,11 @@ assert(coroutine.status(f) == "dead")
|
||||||
s, a = coroutine.resume(f, "xuxu")
|
s, a = coroutine.resume(f, "xuxu")
|
||||||
assert(not s and string.find(a, "dead") and coroutine.status(f) == "dead")
|
assert(not s and string.find(a, "dead") and coroutine.status(f) == "dead")
|
||||||
|
|
||||||
|
_G.f = nil
|
||||||
|
|
||||||
-- yields in tail calls
|
-- yields in tail calls
|
||||||
local function foo (i) return coroutine.yield(i) end
|
local function foo (i) return coroutine.yield(i) end
|
||||||
f = coroutine.wrap(function ()
|
local f = coroutine.wrap(function ()
|
||||||
for i=1,10 do
|
for i=1,10 do
|
||||||
assert(foo(i) == _G.x)
|
assert(foo(i) == _G.x)
|
||||||
end
|
end
|
||||||
|
@ -79,8 +81,10 @@ end)
|
||||||
for i=1,10 do _G.x = i; assert(f(i) == i) end
|
for i=1,10 do _G.x = i; assert(f(i) == i) end
|
||||||
_G.x = 'xuxu'; assert(f('xuxu') == 'a')
|
_G.x = 'xuxu'; assert(f('xuxu') == 'a')
|
||||||
|
|
||||||
|
_G.x = nil
|
||||||
|
|
||||||
-- recursive
|
-- recursive
|
||||||
function pf (n, i)
|
local function pf (n, i)
|
||||||
coroutine.yield(n)
|
coroutine.yield(n)
|
||||||
pf(n*i, i+1)
|
pf(n*i, i+1)
|
||||||
end
|
end
|
||||||
|
@ -93,14 +97,14 @@ for i=1,10 do
|
||||||
end
|
end
|
||||||
|
|
||||||
-- sieve
|
-- sieve
|
||||||
function gen (n)
|
local function gen (n)
|
||||||
return coroutine.wrap(function ()
|
return coroutine.wrap(function ()
|
||||||
for i=2,n do coroutine.yield(i) end
|
for i=2,n do coroutine.yield(i) end
|
||||||
end)
|
end)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
||||||
function filter (p, g)
|
local function filter (p, g)
|
||||||
return coroutine.wrap(function ()
|
return coroutine.wrap(function ()
|
||||||
while 1 do
|
while 1 do
|
||||||
local n = g()
|
local n = g()
|
||||||
|
@ -136,6 +140,10 @@ do
|
||||||
assert(coroutine.status(co) == "dead")
|
assert(coroutine.status(co) == "dead")
|
||||||
local st, msg = coroutine.close(co)
|
local st, msg = coroutine.close(co)
|
||||||
assert(st and msg == nil)
|
assert(st and msg == nil)
|
||||||
|
-- also ok to close it again
|
||||||
|
st, msg = coroutine.close(co)
|
||||||
|
assert(st and msg == nil)
|
||||||
|
|
||||||
|
|
||||||
-- cannot close the running coroutine
|
-- cannot close the running coroutine
|
||||||
local st, msg = pcall(coroutine.close, coroutine.running())
|
local st, msg = pcall(coroutine.close, coroutine.running())
|
||||||
|
@ -149,6 +157,22 @@ do
|
||||||
assert(not st and string.find(msg, "normal"))
|
assert(not st and string.find(msg, "normal"))
|
||||||
end))()
|
end))()
|
||||||
|
|
||||||
|
-- cannot close a coroutine while closing it
|
||||||
|
do
|
||||||
|
local co
|
||||||
|
co = coroutine.create(
|
||||||
|
function()
|
||||||
|
local x <close> = func2close(function()
|
||||||
|
coroutine.close(co) -- try to close it again
|
||||||
|
end)
|
||||||
|
coroutine.yield(20)
|
||||||
|
end)
|
||||||
|
local st, msg = coroutine.resume(co)
|
||||||
|
assert(st and msg == 20)
|
||||||
|
st, msg = coroutine.close(co)
|
||||||
|
assert(not st and string.find(msg, "running coroutine"))
|
||||||
|
end
|
||||||
|
|
||||||
-- to-be-closed variables in coroutines
|
-- to-be-closed variables in coroutines
|
||||||
local X
|
local X
|
||||||
|
|
||||||
|
@ -158,6 +182,9 @@ do
|
||||||
assert(not st and msg == 100)
|
assert(not st and msg == 100)
|
||||||
st, msg = coroutine.close(co)
|
st, msg = coroutine.close(co)
|
||||||
assert(not st and msg == 100)
|
assert(not st and msg == 100)
|
||||||
|
-- after closing, no more errors
|
||||||
|
st, msg = coroutine.close(co)
|
||||||
|
assert(st and msg == nil)
|
||||||
|
|
||||||
co = coroutine.create(function ()
|
co = coroutine.create(function ()
|
||||||
local x <close> = func2close(function (self, err)
|
local x <close> = func2close(function (self, err)
|
||||||
|
@ -189,23 +216,26 @@ do
|
||||||
local st, msg = coroutine.close(co)
|
local st, msg = coroutine.close(co)
|
||||||
assert(st == false and coroutine.status(co) == "dead" and msg == 200)
|
assert(st == false and coroutine.status(co) == "dead" and msg == 200)
|
||||||
assert(x == 200)
|
assert(x == 200)
|
||||||
|
-- after closing, no more errors
|
||||||
|
st, msg = coroutine.close(co)
|
||||||
|
assert(st and msg == nil)
|
||||||
end
|
end
|
||||||
|
|
||||||
do
|
do
|
||||||
-- <close> versus pcall in coroutines
|
-- <close> versus pcall in coroutines
|
||||||
local X = false
|
local X = false
|
||||||
local Y = false
|
local Y = false
|
||||||
function foo ()
|
local function foo ()
|
||||||
local x <close> = func2close(function (self, err)
|
local x <close> = func2close(function (self, err)
|
||||||
Y = debug.getinfo(2)
|
Y = debug.getinfo(2)
|
||||||
X = err
|
X = err
|
||||||
end)
|
end)
|
||||||
error(43)
|
error(43)
|
||||||
end
|
end
|
||||||
co = coroutine.create(function () return pcall(foo) end)
|
local co = coroutine.create(function () return pcall(foo) end)
|
||||||
local st1, st2, err = coroutine.resume(co)
|
local st1, st2, err = coroutine.resume(co)
|
||||||
assert(st1 and not st2 and err == 43)
|
assert(st1 and not st2 and err == 43)
|
||||||
assert(X == 43 and Y.name == "pcall")
|
assert(X == 43 and Y.what == "C")
|
||||||
|
|
||||||
-- recovering from errors in __close metamethods
|
-- recovering from errors in __close metamethods
|
||||||
local track = {}
|
local track = {}
|
||||||
|
@ -249,7 +279,7 @@ end
|
||||||
|
|
||||||
-- yielding across C boundaries
|
-- yielding across C boundaries
|
||||||
|
|
||||||
co = coroutine.wrap(function()
|
local co = coroutine.wrap(function()
|
||||||
assert(not pcall(table.sort,{1,2,3}, coroutine.yield))
|
assert(not pcall(table.sort,{1,2,3}, coroutine.yield))
|
||||||
assert(coroutine.isyieldable())
|
assert(coroutine.isyieldable())
|
||||||
coroutine.yield(20)
|
coroutine.yield(20)
|
||||||
|
@ -277,15 +307,15 @@ local r1, r2, v = f1(nil)
|
||||||
assert(r1 and not r2 and v[1] == (10 + 1)*10/2)
|
assert(r1 and not r2 and v[1] == (10 + 1)*10/2)
|
||||||
|
|
||||||
|
|
||||||
function f (a, b) a = coroutine.yield(a); error{a + b} end
|
local function f (a, b) a = coroutine.yield(a); error{a + b} end
|
||||||
function g(x) return x[1]*2 end
|
local function g(x) return x[1]*2 end
|
||||||
|
|
||||||
co = coroutine.wrap(function ()
|
co = coroutine.wrap(function ()
|
||||||
coroutine.yield(xpcall(f, g, 10, 20))
|
coroutine.yield(xpcall(f, g, 10, 20))
|
||||||
end)
|
end)
|
||||||
|
|
||||||
assert(co() == 10)
|
assert(co() == 10)
|
||||||
r, msg = co(100)
|
local r, msg = co(100)
|
||||||
assert(not r and msg == 240)
|
assert(not r and msg == 240)
|
||||||
|
|
||||||
|
|
||||||
|
@ -347,9 +377,10 @@ assert(not a and b == foo and coroutine.status(x) == "dead")
|
||||||
a,b = coroutine.resume(x)
|
a,b = coroutine.resume(x)
|
||||||
assert(not a and string.find(b, "dead") and coroutine.status(x) == "dead")
|
assert(not a and string.find(b, "dead") and coroutine.status(x) == "dead")
|
||||||
|
|
||||||
|
goo = nil
|
||||||
|
|
||||||
-- co-routines x for loop
|
-- co-routines x for loop
|
||||||
function all (a, n, k)
|
local function all (a, n, k)
|
||||||
if k == 0 then coroutine.yield(a)
|
if k == 0 then coroutine.yield(a)
|
||||||
else
|
else
|
||||||
for i=1,n do
|
for i=1,n do
|
||||||
|
@ -389,7 +420,7 @@ assert(f() == 43 and f() == 53)
|
||||||
|
|
||||||
-- old bug: attempt to resume itself
|
-- old bug: attempt to resume itself
|
||||||
|
|
||||||
function co_func (current_co)
|
local function co_func (current_co)
|
||||||
assert(coroutine.running() == current_co)
|
assert(coroutine.running() == current_co)
|
||||||
assert(coroutine.resume(current_co) == false)
|
assert(coroutine.resume(current_co) == false)
|
||||||
coroutine.yield(10, 20)
|
coroutine.yield(10, 20)
|
||||||
|
@ -419,7 +450,7 @@ do
|
||||||
|
|
||||||
local X = false
|
local X = false
|
||||||
A = coroutine.wrap(function()
|
A = coroutine.wrap(function()
|
||||||
local _ <close> = setmetatable({}, {__close = function () X = true end})
|
local _ <close> = func2close(function () X = true end)
|
||||||
return pcall(A, 1)
|
return pcall(A, 1)
|
||||||
end)
|
end)
|
||||||
st, res = A()
|
st, res = A()
|
||||||
|
@ -427,6 +458,22 @@ do
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
||||||
|
-- bug in 5.4.1
|
||||||
|
do
|
||||||
|
-- coroutine ran close metamethods with invalid status during a
|
||||||
|
-- reset.
|
||||||
|
local co
|
||||||
|
co = coroutine.wrap(function()
|
||||||
|
local x <close> = func2close(function() return pcall(co) end)
|
||||||
|
error(111)
|
||||||
|
end)
|
||||||
|
local st, errobj = pcall(co)
|
||||||
|
assert(not st and errobj == 111)
|
||||||
|
st, errobj = pcall(co)
|
||||||
|
assert(not st and string.find(errobj, "dead coroutine"))
|
||||||
|
end
|
||||||
|
|
||||||
|
|
||||||
-- attempt to resume 'normal' coroutine
|
-- attempt to resume 'normal' coroutine
|
||||||
local co1, co2
|
local co1, co2
|
||||||
co1 = coroutine.create(function () return co2() end)
|
co1 = coroutine.create(function () return co2() end)
|
||||||
|
@ -449,15 +496,16 @@ a = nil
|
||||||
-- access to locals of erroneous coroutines
|
-- access to locals of erroneous coroutines
|
||||||
local x = coroutine.create (function ()
|
local x = coroutine.create (function ()
|
||||||
local a = 10
|
local a = 10
|
||||||
_G.f = function () a=a+1; return a end
|
_G.F = function () a=a+1; return a end
|
||||||
error('x')
|
error('x')
|
||||||
end)
|
end)
|
||||||
|
|
||||||
assert(not coroutine.resume(x))
|
assert(not coroutine.resume(x))
|
||||||
-- overwrite previous position of local `a'
|
-- overwrite previous position of local `a'
|
||||||
assert(not coroutine.resume(x, 1, 1, 1, 1, 1, 1, 1))
|
assert(not coroutine.resume(x, 1, 1, 1, 1, 1, 1, 1))
|
||||||
assert(_G.f() == 11)
|
assert(_G.F() == 11)
|
||||||
assert(_G.f() == 12)
|
assert(_G.F() == 12)
|
||||||
|
_G.F = nil
|
||||||
|
|
||||||
|
|
||||||
if not T then
|
if not T then
|
||||||
|
@ -468,7 +516,7 @@ else
|
||||||
|
|
||||||
local turn
|
local turn
|
||||||
|
|
||||||
function fact (t, x)
|
local function fact (t, x)
|
||||||
assert(turn == t)
|
assert(turn == t)
|
||||||
if x == 0 then return 1
|
if x == 0 then return 1
|
||||||
else return x*fact(t, x-1)
|
else return x*fact(t, x-1)
|
||||||
|
@ -537,6 +585,7 @@ else
|
||||||
_G.X = nil; co(); assert(_G.X == line + 2 and _G.XX == nil)
|
_G.X = nil; co(); assert(_G.X == line + 2 and _G.XX == nil)
|
||||||
_G.X = nil; co(); assert(_G.X == line + 3 and _G.XX == 20)
|
_G.X = nil; co(); assert(_G.X == line + 3 and _G.XX == 20)
|
||||||
assert(co() == 10)
|
assert(co() == 10)
|
||||||
|
_G.X = nil
|
||||||
|
|
||||||
-- testing yields in count hook
|
-- testing yields in count hook
|
||||||
co = coroutine.wrap(function ()
|
co = coroutine.wrap(function ()
|
||||||
|
@ -614,6 +663,8 @@ else
|
||||||
|
|
||||||
assert(X == 'a a a' and Y == 'OK')
|
assert(X == 'a a a' and Y == 'OK')
|
||||||
|
|
||||||
|
X, Y = nil
|
||||||
|
|
||||||
|
|
||||||
-- resuming running coroutine
|
-- resuming running coroutine
|
||||||
C = coroutine.create(function ()
|
C = coroutine.create(function ()
|
||||||
|
@ -659,7 +710,7 @@ else
|
||||||
X = function (x) coroutine.yield(x, 'BB'); return 'CC' end;
|
X = function (x) coroutine.yield(x, 'BB'); return 'CC' end;
|
||||||
return 'ok']]))
|
return 'ok']]))
|
||||||
|
|
||||||
t = table.pack(T.testC(state, [[
|
local t = table.pack(T.testC(state, [[
|
||||||
rawgeti R 1 # get main thread
|
rawgeti R 1 # get main thread
|
||||||
pushstring 'XX'
|
pushstring 'XX'
|
||||||
getglobal X # get function for body
|
getglobal X # get function for body
|
||||||
|
@ -688,31 +739,28 @@ end
|
||||||
|
|
||||||
|
|
||||||
-- leaving a pending coroutine open
|
-- leaving a pending coroutine open
|
||||||
_X = coroutine.wrap(function ()
|
_G.TO_SURVIVE = coroutine.wrap(function ()
|
||||||
local a = 10
|
local a = 10
|
||||||
local x = function () a = a+1 end
|
local x = function () a = a+1 end
|
||||||
coroutine.yield()
|
coroutine.yield()
|
||||||
end)
|
end)
|
||||||
|
|
||||||
_X()
|
_G.TO_SURVIVE()
|
||||||
|
|
||||||
|
|
||||||
if not _soft then
|
if not _soft then
|
||||||
-- bug (stack overflow)
|
-- bug (stack overflow)
|
||||||
local j = 2^9
|
local lim = 1000000 -- stack limit; assume 32-bit machine
|
||||||
local lim = 1000000 -- (C stack limit; assume 32-bit machine)
|
local t = {lim - 10, lim - 5, lim - 1, lim, lim + 1, lim + 5}
|
||||||
local t = {lim - 10, lim - 5, lim - 1, lim, lim + 1}
|
|
||||||
for i = 1, #t do
|
for i = 1, #t do
|
||||||
local j = t[i]
|
local j = t[i]
|
||||||
co = coroutine.create(function()
|
local co = coroutine.create(function()
|
||||||
local t = {}
|
return table.unpack({}, 1, j)
|
||||||
for i = 1, j do t[i] = i end
|
|
||||||
return table.unpack(t)
|
|
||||||
end)
|
end)
|
||||||
local r, msg = coroutine.resume(co)
|
local r, msg = coroutine.resume(co)
|
||||||
assert(not r)
|
-- must fail for unpacking larger than stack limit
|
||||||
|
assert(j < lim or not r)
|
||||||
end
|
end
|
||||||
co = nil
|
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
||||||
|
@ -896,7 +944,7 @@ assert(run(function ()
|
||||||
do local _ENV = _ENV
|
do local _ENV = _ENV
|
||||||
f = function () AAA = BBB + 1; return AAA end
|
f = function () AAA = BBB + 1; return AAA end
|
||||||
end
|
end
|
||||||
g = new(10); g.k.BBB = 10;
|
local g = new(10); g.k.BBB = 10;
|
||||||
debug.setupvalue(f, 1, g)
|
debug.setupvalue(f, 1, g)
|
||||||
assert(run(f, {"idx", "nidx", "idx"}) == 11)
|
assert(run(f, {"idx", "nidx", "idx"}) == 11)
|
||||||
assert(g.k.AAA == 11)
|
assert(g.k.AAA == 11)
|
||||||
|
@ -1036,6 +1084,8 @@ assert(#a == 3 and a[1] == a[2] and a[2] == a[3] and a[3] == 34)
|
||||||
|
|
||||||
-- testing yields with continuations
|
-- testing yields with continuations
|
||||||
|
|
||||||
|
local y
|
||||||
|
|
||||||
co = coroutine.wrap(function (...) return
|
co = coroutine.wrap(function (...) return
|
||||||
T.testC([[ # initial function
|
T.testC([[ # initial function
|
||||||
yieldk 1 2
|
yieldk 1 2
|
||||||
|
@ -1088,6 +1138,9 @@ assert(x == "YIELD" and y == 4)
|
||||||
|
|
||||||
assert(not pcall(co)) -- coroutine should be dead
|
assert(not pcall(co)) -- coroutine should be dead
|
||||||
|
|
||||||
|
_G.ctx = nil
|
||||||
|
_G.status = nil
|
||||||
|
|
||||||
|
|
||||||
-- bug in nCcalls
|
-- bug in nCcalls
|
||||||
local co = coroutine.wrap(function ()
|
local co = coroutine.wrap(function ()
|
||||||
|
|
40
third_party/lua/test/cstack.lua
vendored
40
third_party/lua/test/cstack.lua
vendored
|
@ -84,6 +84,32 @@ do -- bug in 5.4.0
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
||||||
|
do -- bug since 5.4.0
|
||||||
|
local count = 0
|
||||||
|
print("chain of 'coroutine.close'")
|
||||||
|
-- create N coroutines forming a list so that each one, when closed,
|
||||||
|
-- closes the previous one. (With a large enough N, previous Lua
|
||||||
|
-- versions crash in this test.)
|
||||||
|
local coro = false
|
||||||
|
for i = 1, 1000 do
|
||||||
|
local previous = coro
|
||||||
|
coro = coroutine.create(function()
|
||||||
|
local cc <close> = setmetatable({}, {__close=function()
|
||||||
|
count = count + 1
|
||||||
|
if previous then
|
||||||
|
assert(coroutine.close(previous))
|
||||||
|
end
|
||||||
|
end})
|
||||||
|
coroutine.yield() -- leaves 'cc' pending to be closed
|
||||||
|
end)
|
||||||
|
assert(coroutine.resume(coro)) -- start it and run until it yields
|
||||||
|
end
|
||||||
|
local st, msg = coroutine.close(coro)
|
||||||
|
assert(not st and string.find(msg, "C stack overflow"))
|
||||||
|
print("final count: ", count)
|
||||||
|
end
|
||||||
|
|
||||||
|
|
||||||
do
|
do
|
||||||
print("nesting of resuming yielded coroutines")
|
print("nesting of resuming yielded coroutines")
|
||||||
local count = 0
|
local count = 0
|
||||||
|
@ -103,6 +129,20 @@ do
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
||||||
|
do -- bug in 5.4.2
|
||||||
|
print("nesting coroutines running after recoverable errors")
|
||||||
|
local count = 0
|
||||||
|
local function foo()
|
||||||
|
count = count + 1
|
||||||
|
pcall(1) -- create an error
|
||||||
|
-- running now inside 'precover' ("protected recover")
|
||||||
|
coroutine.wrap(foo)() -- call another coroutine
|
||||||
|
end
|
||||||
|
checkerror("C stack overflow", foo)
|
||||||
|
print("final count: ", count)
|
||||||
|
end
|
||||||
|
|
||||||
|
|
||||||
if T then
|
if T then
|
||||||
print("testing stack recovery")
|
print("testing stack recovery")
|
||||||
local N = 0 -- trace number of calls
|
local N = 0 -- trace number of calls
|
||||||
|
|
72
third_party/lua/test/db.lua
vendored
72
third_party/lua/test/db.lua
vendored
|
@ -16,7 +16,7 @@ end
|
||||||
assert(not debug.gethook())
|
assert(not debug.gethook())
|
||||||
|
|
||||||
local testline = 19 -- line where 'test' is defined
|
local testline = 19 -- line where 'test' is defined
|
||||||
function test (s, l, p) -- this must be line 19
|
local function test (s, l, p) -- this must be line 19
|
||||||
collectgarbage() -- avoid gc during trace
|
collectgarbage() -- avoid gc during trace
|
||||||
local function f (event, line)
|
local function f (event, line)
|
||||||
assert(event == 'line')
|
assert(event == 'line')
|
||||||
|
@ -50,7 +50,7 @@ end
|
||||||
|
|
||||||
|
|
||||||
-- test file and string names truncation
|
-- test file and string names truncation
|
||||||
a = "function f () end"
|
local a = "function f () end"
|
||||||
local function dostring (s, x) return load(s, x)() end
|
local function dostring (s, x) return load(s, x)() end
|
||||||
dostring(a)
|
dostring(a)
|
||||||
assert(debug.getinfo(f).short_src == string.format('[string "%s"]', a))
|
assert(debug.getinfo(f).short_src == string.format('[string "%s"]', a))
|
||||||
|
@ -72,7 +72,8 @@ dostring(a, string.format("=%s", string.rep('x', 500)))
|
||||||
assert(string.find(debug.getinfo(f).short_src, "^x*$"))
|
assert(string.find(debug.getinfo(f).short_src, "^x*$"))
|
||||||
dostring(a, "=")
|
dostring(a, "=")
|
||||||
assert(debug.getinfo(f).short_src == "")
|
assert(debug.getinfo(f).short_src == "")
|
||||||
a = nil; f = nil;
|
_G.a = nil; _G.f = nil;
|
||||||
|
_G[string.rep("p", 400)] = nil
|
||||||
|
|
||||||
|
|
||||||
repeat
|
repeat
|
||||||
|
@ -120,6 +121,7 @@ else
|
||||||
end
|
end
|
||||||
]], {2,3,4,7})
|
]], {2,3,4,7})
|
||||||
|
|
||||||
|
|
||||||
test([[
|
test([[
|
||||||
local function foo()
|
local function foo()
|
||||||
end
|
end
|
||||||
|
@ -128,6 +130,7 @@ A = 1
|
||||||
A = 2
|
A = 2
|
||||||
A = 3
|
A = 3
|
||||||
]], {2, 3, 2, 4, 5, 6})
|
]], {2, 3, 2, 4, 5, 6})
|
||||||
|
_G.A = nil
|
||||||
|
|
||||||
|
|
||||||
test([[--
|
test([[--
|
||||||
|
@ -175,6 +178,8 @@ end
|
||||||
|
|
||||||
test([[for i=1,4 do a=1 end]], {1,1,1,1})
|
test([[for i=1,4 do a=1 end]], {1,1,1,1})
|
||||||
|
|
||||||
|
_G.a = nil
|
||||||
|
|
||||||
|
|
||||||
do -- testing line info/trace with large gaps in source
|
do -- testing line info/trace with large gaps in source
|
||||||
|
|
||||||
|
@ -194,6 +199,50 @@ do -- testing line info/trace with large gaps in source
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
_G.a = nil
|
||||||
|
|
||||||
|
|
||||||
|
do -- testing active lines
|
||||||
|
local function checkactivelines (f, lines)
|
||||||
|
local t = debug.getinfo(f, "SL")
|
||||||
|
for _, l in pairs(lines) do
|
||||||
|
l = l + t.linedefined
|
||||||
|
assert(t.activelines[l])
|
||||||
|
t.activelines[l] = undef
|
||||||
|
end
|
||||||
|
assert(next(t.activelines) == nil) -- no extra lines
|
||||||
|
end
|
||||||
|
|
||||||
|
checkactivelines(function (...) -- vararg function
|
||||||
|
-- 1st line is empty
|
||||||
|
-- 2nd line is empty
|
||||||
|
-- 3th line is empty
|
||||||
|
local a = 20
|
||||||
|
-- 5th line is empty
|
||||||
|
local b = 30
|
||||||
|
-- 7th line is empty
|
||||||
|
end, {4, 6, 8})
|
||||||
|
|
||||||
|
checkactivelines(function (a)
|
||||||
|
-- 1st line is empty
|
||||||
|
-- 2nd line is empty
|
||||||
|
local a = 20
|
||||||
|
local b = 30
|
||||||
|
-- 5th line is empty
|
||||||
|
end, {3, 4, 6})
|
||||||
|
|
||||||
|
checkactivelines(function (a, b, ...) end, {0})
|
||||||
|
|
||||||
|
checkactivelines(function (a, b)
|
||||||
|
end, {1})
|
||||||
|
|
||||||
|
for _, n in pairs{0, 1, 2, 10, 50, 100, 1000, 10000} do
|
||||||
|
checkactivelines(
|
||||||
|
load(string.format("%s return 1", string.rep("\n", n))),
|
||||||
|
{n + 1})
|
||||||
|
end
|
||||||
|
|
||||||
|
end
|
||||||
|
|
||||||
print'+'
|
print'+'
|
||||||
|
|
||||||
|
@ -244,7 +293,6 @@ foo(200, 3, 4)
|
||||||
local a = {}
|
local a = {}
|
||||||
for i = 1, (_soft and 100 or 1000) do a[i] = i end
|
for i = 1, (_soft and 100 or 1000) do a[i] = i end
|
||||||
foo(table.unpack(a))
|
foo(table.unpack(a))
|
||||||
a = nil
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
@ -264,13 +312,14 @@ do -- test hook presence in debug info
|
||||||
debug.sethook()
|
debug.sethook()
|
||||||
assert(count == 4)
|
assert(count == 4)
|
||||||
end
|
end
|
||||||
|
_ENV.a = nil
|
||||||
|
|
||||||
|
|
||||||
-- hook table has weak keys
|
-- hook table has weak keys
|
||||||
assert(getmetatable(debug.getregistry()._HOOKKEY).__mode == 'k')
|
assert(getmetatable(debug.getregistry()._HOOKKEY).__mode == 'k')
|
||||||
|
|
||||||
|
|
||||||
a = {}; L = nil
|
a = {}; local L = nil
|
||||||
local glob = 1
|
local glob = 1
|
||||||
local oldglob = glob
|
local oldglob = glob
|
||||||
debug.sethook(function (e,l)
|
debug.sethook(function (e,l)
|
||||||
|
@ -311,7 +360,7 @@ function foo()
|
||||||
end; foo() -- set L
|
end; foo() -- set L
|
||||||
-- check line counting inside strings and empty lines
|
-- check line counting inside strings and empty lines
|
||||||
|
|
||||||
_ = 'alo\
|
local _ = 'alo\
|
||||||
alo' .. [[
|
alo' .. [[
|
||||||
|
|
||||||
]]
|
]]
|
||||||
|
@ -360,6 +409,7 @@ function g(a,b) return (a+1) + f() end
|
||||||
|
|
||||||
assert(g(0,0) == 30)
|
assert(g(0,0) == 30)
|
||||||
|
|
||||||
|
_G.f, _G.g = nil
|
||||||
|
|
||||||
debug.sethook(nil);
|
debug.sethook(nil);
|
||||||
assert(not debug.gethook())
|
assert(not debug.gethook())
|
||||||
|
@ -403,7 +453,7 @@ local function collectlocals (level)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
||||||
X = nil
|
local X = nil
|
||||||
a = {}
|
a = {}
|
||||||
function a:f (a, b, ...) local arg = {...}; local c = 13 end
|
function a:f (a, b, ...) local arg = {...}; local c = 13 end
|
||||||
debug.sethook(function (e)
|
debug.sethook(function (e)
|
||||||
|
@ -426,6 +476,7 @@ a:f(1,2,3,4,5)
|
||||||
assert(X.self == a and X.a == 1 and X.b == 2 and X.c == nil)
|
assert(X.self == a and X.a == 1 and X.b == 2 and X.c == nil)
|
||||||
assert(XX == 12)
|
assert(XX == 12)
|
||||||
assert(not debug.gethook())
|
assert(not debug.gethook())
|
||||||
|
_G.XX = nil
|
||||||
|
|
||||||
|
|
||||||
-- testing access to local variables in return hook (bug in 5.2)
|
-- testing access to local variables in return hook (bug in 5.2)
|
||||||
|
@ -550,6 +601,7 @@ end
|
||||||
|
|
||||||
debug.sethook()
|
debug.sethook()
|
||||||
|
|
||||||
|
local g, g1
|
||||||
|
|
||||||
-- tests for tail calls
|
-- tests for tail calls
|
||||||
local function f (x)
|
local function f (x)
|
||||||
|
@ -595,7 +647,7 @@ h(false)
|
||||||
debug.sethook()
|
debug.sethook()
|
||||||
assert(b == 2) -- two tail calls
|
assert(b == 2) -- two tail calls
|
||||||
|
|
||||||
lim = _soft and 3000 or 30000
|
local lim = _soft and 3000 or 30000
|
||||||
local function foo (x)
|
local function foo (x)
|
||||||
if x==0 then
|
if x==0 then
|
||||||
assert(debug.getinfo(2).what == "main")
|
assert(debug.getinfo(2).what == "main")
|
||||||
|
@ -844,7 +896,7 @@ do -- testing debug info for finalizers
|
||||||
|
|
||||||
-- create a piece of garbage with a finalizer
|
-- create a piece of garbage with a finalizer
|
||||||
setmetatable({}, {__gc = function ()
|
setmetatable({}, {__gc = function ()
|
||||||
local t = debug.getinfo(2) -- get callee information
|
local t = debug.getinfo(1) -- get function information
|
||||||
assert(t.namewhat == "metamethod")
|
assert(t.namewhat == "metamethod")
|
||||||
name = t.name
|
name = t.name
|
||||||
end})
|
end})
|
||||||
|
@ -897,7 +949,7 @@ end
|
||||||
|
|
||||||
|
|
||||||
print("testing debug functions on chunk without debug info")
|
print("testing debug functions on chunk without debug info")
|
||||||
prog = [[-- program to be loaded without debug information (strip)
|
local prog = [[-- program to be loaded without debug information (strip)
|
||||||
local debug = require'debug'
|
local debug = require'debug'
|
||||||
local a = 12 -- a local variable
|
local a = 12 -- a local variable
|
||||||
|
|
||||||
|
|
111
third_party/lua/test/errors.lua
vendored
111
third_party/lua/test/errors.lua
vendored
|
@ -26,7 +26,7 @@ end
|
||||||
|
|
||||||
local function checkmessage (prog, msg, debug)
|
local function checkmessage (prog, msg, debug)
|
||||||
local m = doit(prog)
|
local m = doit(prog)
|
||||||
if debug then print(m) end
|
if debug then print(m, msg) end
|
||||||
assert(string.find(m, msg, 1, true))
|
assert(string.find(m, msg, 1, true))
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@ -114,12 +114,14 @@ checkmessage("a = {} | 1", "bitwise operation")
|
||||||
checkmessage("a = {} < 1", "attempt to compare")
|
checkmessage("a = {} < 1", "attempt to compare")
|
||||||
checkmessage("a = {} <= 1", "attempt to compare")
|
checkmessage("a = {} <= 1", "attempt to compare")
|
||||||
|
|
||||||
checkmessage("a=1; bbbb=2; a=math.sin(3)+bbbb(3)", "global 'bbbb'")
|
checkmessage("aaa=1; bbbb=2; aaa=math.sin(3)+bbbb(3)", "global 'bbbb'")
|
||||||
checkmessage("a={}; do local a=1 end a:bbbb(3)", "method 'bbbb'")
|
checkmessage("aaa={}; do local aaa=1 end aaa:bbbb(3)", "method 'bbbb'")
|
||||||
checkmessage("local a={}; a.bbbb(3)", "field 'bbbb'")
|
checkmessage("local a={}; a.bbbb(3)", "field 'bbbb'")
|
||||||
assert(not string.find(doit"a={13}; local bbbb=1; a[bbbb](3)", "'bbbb'"))
|
assert(not string.find(doit"aaa={13}; local bbbb=1; aaa[bbbb](3)", "'bbbb'"))
|
||||||
checkmessage("a={13}; local bbbb=1; a[bbbb](3)", "number")
|
checkmessage("aaa={13}; local bbbb=1; aaa[bbbb](3)", "number")
|
||||||
checkmessage("a=(1)..{}", "a table value")
|
checkmessage("aaa=(1)..{}", "a table value")
|
||||||
|
|
||||||
|
_G.aaa, _G.bbbb = nil
|
||||||
|
|
||||||
-- calls
|
-- calls
|
||||||
checkmessage("local a; a(13)", "local 'a'")
|
checkmessage("local a; a(13)", "local 'a'")
|
||||||
|
@ -134,12 +136,13 @@ checkmessage([[
|
||||||
|
|
||||||
-- tail calls
|
-- tail calls
|
||||||
checkmessage("local a={}; return a.bbbb(3)", "field 'bbbb'")
|
checkmessage("local a={}; return a.bbbb(3)", "field 'bbbb'")
|
||||||
checkmessage("a={}; do local a=1 end; return a:bbbb(3)", "method 'bbbb'")
|
checkmessage("aaa={}; do local aaa=1 end; return aaa:bbbb(3)", "method 'bbbb'")
|
||||||
|
|
||||||
checkmessage("a = #print", "length of a function value")
|
checkmessage("aaa = #print", "length of a function value")
|
||||||
checkmessage("a = #3", "length of a number value")
|
checkmessage("aaa = #3", "length of a number value")
|
||||||
|
|
||||||
|
_G.aaa = nil
|
||||||
|
|
||||||
aaa = nil
|
|
||||||
checkmessage("aaa.bbb:ddd(9)", "global 'aaa'")
|
checkmessage("aaa.bbb:ddd(9)", "global 'aaa'")
|
||||||
checkmessage("local aaa={bbb=1}; aaa.bbb:ddd(9)", "field 'bbb'")
|
checkmessage("local aaa={bbb=1}; aaa.bbb:ddd(9)", "field 'bbb'")
|
||||||
checkmessage("local aaa={bbb={}}; aaa.bbb:ddd(9)", "method 'ddd'")
|
checkmessage("local aaa={bbb={}}; aaa.bbb:ddd(9)", "method 'ddd'")
|
||||||
|
@ -152,15 +155,16 @@ checkmessage("local a,b,cc; (function () a.x = 1 end)()", "upvalue 'a'")
|
||||||
|
|
||||||
checkmessage("local _ENV = {x={}}; a = a + 1", "global 'a'")
|
checkmessage("local _ENV = {x={}}; a = a + 1", "global 'a'")
|
||||||
|
|
||||||
checkmessage("b=1; local aaa={}; x=aaa+b", "local 'aaa'")
|
checkmessage("BB=1; local aaa={}; x=aaa+BB", "local 'aaa'")
|
||||||
checkmessage("aaa={}; x=3.3/aaa", "global 'aaa'")
|
checkmessage("aaa={}; x=3.3/aaa", "global 'aaa'")
|
||||||
checkmessage("aaa=2; b=nil;x=aaa*b", "global 'b'")
|
checkmessage("aaa=2; BB=nil;x=aaa*BB", "global 'BB'")
|
||||||
checkmessage("aaa={}; x=-aaa", "global 'aaa'")
|
checkmessage("aaa={}; x=-aaa", "global 'aaa'")
|
||||||
|
|
||||||
-- short circuit
|
-- short circuit
|
||||||
checkmessage("a=1; local a,bbbb=2,3; a = math.sin(1) and bbbb(3)",
|
checkmessage("aaa=1; local aaa,bbbb=2,3; aaa = math.sin(1) and bbbb(3)",
|
||||||
|
"local 'bbbb'")
|
||||||
|
checkmessage("aaa=1; local aaa,bbbb=2,3; aaa = bbbb(1) or aaa(3)",
|
||||||
"local 'bbbb'")
|
"local 'bbbb'")
|
||||||
checkmessage("a=1; local a,bbbb=2,3; a = bbbb(1) or a(3)", "local 'bbbb'")
|
|
||||||
checkmessage("local a,b,c,f = 1,1,1; f((a and b) or c)", "local 'f'")
|
checkmessage("local a,b,c,f = 1,1,1; f((a and b) or c)", "local 'f'")
|
||||||
checkmessage("local a,b,c = 1,1,1; ((a and b) or c)()", "call a number value")
|
checkmessage("local a,b,c = 1,1,1; ((a and b) or c)()", "call a number value")
|
||||||
assert(not string.find(doit"aaa={}; x=(aaa or aaa)+(aaa and aaa)", "'aaa'"))
|
assert(not string.find(doit"aaa={}; x=(aaa or aaa)+(aaa and aaa)", "'aaa'"))
|
||||||
|
@ -187,8 +191,8 @@ checkmessage("return ~-3e40", "has no integer representation")
|
||||||
checkmessage("return ~-3.009", "has no integer representation")
|
checkmessage("return ~-3.009", "has no integer representation")
|
||||||
checkmessage("return 3.009 & 1", "has no integer representation")
|
checkmessage("return 3.009 & 1", "has no integer representation")
|
||||||
checkmessage("return 34 >> {}", "table value")
|
checkmessage("return 34 >> {}", "table value")
|
||||||
checkmessage("a = 24 // 0", "divide by zero")
|
checkmessage("aaa = 24 // 0", "divide by zero")
|
||||||
checkmessage("a = 1 % 0", "'n%0'")
|
checkmessage("aaa = 1 % 0", "'n%0'")
|
||||||
|
|
||||||
|
|
||||||
-- type error for an object which is neither in an upvalue nor a register.
|
-- type error for an object which is neither in an upvalue nor a register.
|
||||||
|
@ -228,6 +232,22 @@ do -- named objects (field '__name')
|
||||||
checkmessage("return {} < XX", "table with My Type")
|
checkmessage("return {} < XX", "table with My Type")
|
||||||
checkmessage("return XX < io.stdin", "My Type with FILE*")
|
checkmessage("return XX < io.stdin", "My Type with FILE*")
|
||||||
_G.XX = nil
|
_G.XX = nil
|
||||||
|
|
||||||
|
if T then -- extra tests for 'luaL_tolstring'
|
||||||
|
-- bug in 5.4.3; 'luaL_tolstring' with negative indices
|
||||||
|
local x = setmetatable({}, {__name="TABLE"})
|
||||||
|
assert(T.testC("Ltolstring -1; return 1", x) == tostring(x))
|
||||||
|
|
||||||
|
local a, b = T.testC("pushint 10; Ltolstring -2; return 2", x)
|
||||||
|
assert(a == 10 and b == tostring(x))
|
||||||
|
|
||||||
|
setmetatable(x, {__tostring=function (o)
|
||||||
|
assert(o == x)
|
||||||
|
return "ABC"
|
||||||
|
end})
|
||||||
|
local a, b, c = T.testC("pushint 10; Ltolstring -2; return 3", x)
|
||||||
|
assert(a == x and b == 10 and c == "ABC")
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
-- global functions
|
-- global functions
|
||||||
|
@ -253,13 +273,13 @@ end
|
||||||
-- tests for field accesses after RK limit
|
-- tests for field accesses after RK limit
|
||||||
local t = {}
|
local t = {}
|
||||||
for i = 1, 1000 do
|
for i = 1, 1000 do
|
||||||
t[i] = "a = x" .. i
|
t[i] = "aaa = x" .. i
|
||||||
end
|
end
|
||||||
local s = table.concat(t, "; ")
|
local s = table.concat(t, "; ")
|
||||||
t = nil
|
t = nil
|
||||||
checkmessage(s.."; a = bbb + 1", "global 'bbb'")
|
checkmessage(s.."; aaa = bbb + 1", "global 'bbb'")
|
||||||
checkmessage("local _ENV=_ENV;"..s.."; a = bbb + 1", "global 'bbb'")
|
checkmessage("local _ENV=_ENV;"..s.."; aaa = bbb + 1", "global 'bbb'")
|
||||||
checkmessage(s.."; local t = {}; a = t.bbb + 1", "field 'bbb'")
|
checkmessage(s.."; local t = {}; aaa = t.bbb + 1", "field 'bbb'")
|
||||||
checkmessage(s.."; local t = {}; t:bbb()", "method 'bbb'")
|
checkmessage(s.."; local t = {}; t:bbb()", "method 'bbb'")
|
||||||
|
|
||||||
checkmessage([[aaa=9
|
checkmessage([[aaa=9
|
||||||
|
@ -289,7 +309,7 @@ end]], "global 'insert'")
|
||||||
|
|
||||||
checkmessage([[ -- tail call
|
checkmessage([[ -- tail call
|
||||||
return math.sin("a")
|
return math.sin("a")
|
||||||
]], "'sin'")
|
]], "sin")
|
||||||
|
|
||||||
checkmessage([[collectgarbage("nooption")]], "invalid option")
|
checkmessage([[collectgarbage("nooption")]], "invalid option")
|
||||||
|
|
||||||
|
@ -308,14 +328,17 @@ main()
|
||||||
]], "global 'NoSuchName'")
|
]], "global 'NoSuchName'")
|
||||||
print'+'
|
print'+'
|
||||||
|
|
||||||
a = {}; setmetatable(a, {__index = string})
|
aaa = {}; setmetatable(aaa, {__index = string})
|
||||||
checkmessage("a:sub()", "bad self")
|
checkmessage("aaa:sub()", "bad self")
|
||||||
checkmessage("string.sub('a', {})", "#2")
|
checkmessage("string.sub('a', {})", "#2")
|
||||||
checkmessage("('a'):sub{}", "#1")
|
checkmessage("('a'):sub{}", "#1")
|
||||||
|
|
||||||
checkmessage("table.sort({1,2,3}, table.sort)", "'table.sort'")
|
checkmessage("table.sort({1,2,3}, table.sort)", "'table.sort'")
|
||||||
checkmessage("string.gsub('s', 's', setmetatable)", "'setmetatable'")
|
checkmessage("string.gsub('s', 's', setmetatable)", "'setmetatable'")
|
||||||
|
|
||||||
|
_G.aaa = nil
|
||||||
|
|
||||||
|
|
||||||
-- tests for errors in coroutines
|
-- tests for errors in coroutines
|
||||||
|
|
||||||
local function f (n)
|
local function f (n)
|
||||||
|
@ -333,7 +356,7 @@ checkerr("yield across", f)
|
||||||
|
|
||||||
-- testing size of 'source' info; size of buffer for that info is
|
-- testing size of 'source' info; size of buffer for that info is
|
||||||
-- LUA_IDSIZE, declared as 60 in luaconf. Get one position for '\0'.
|
-- LUA_IDSIZE, declared as 60 in luaconf. Get one position for '\0'.
|
||||||
idsize = 60 - 1
|
local idsize = 60 - 1
|
||||||
local function checksize (source)
|
local function checksize (source)
|
||||||
-- syntax error
|
-- syntax error
|
||||||
local _, msg = load("x", source)
|
local _, msg = load("x", source)
|
||||||
|
@ -395,13 +418,14 @@ x
|
||||||
|
|
||||||
local p = [[
|
local p = [[
|
||||||
function g() f() end
|
function g() f() end
|
||||||
function f(x) error('a', X) end
|
function f(x) error('a', XX) end
|
||||||
g()
|
g()
|
||||||
]]
|
]]
|
||||||
X=3;lineerror((p), 3)
|
XX=3;lineerror((p), 3)
|
||||||
X=0;lineerror((p), false)
|
XX=0;lineerror((p), false)
|
||||||
X=1;lineerror((p), 2)
|
XX=1;lineerror((p), 2)
|
||||||
X=2;lineerror((p), 1)
|
XX=2;lineerror((p), 1)
|
||||||
|
_G.XX, _G.g, _G.f = nil
|
||||||
|
|
||||||
|
|
||||||
lineerror([[
|
lineerror([[
|
||||||
|
@ -420,6 +444,14 @@ if not b then
|
||||||
end
|
end
|
||||||
end]], 5)
|
end]], 5)
|
||||||
|
|
||||||
|
|
||||||
|
-- bug in 5.4.0
|
||||||
|
lineerror([[
|
||||||
|
local a = 0
|
||||||
|
local b = 1
|
||||||
|
local c = b % a
|
||||||
|
]], 3)
|
||||||
|
|
||||||
do
|
do
|
||||||
-- Force a negative estimate for base line. Error in instruction 2
|
-- Force a negative estimate for base line. Error in instruction 2
|
||||||
-- (after VARARGPREP, GETGLOBAL), with first absolute line information
|
-- (after VARARGPREP, GETGLOBAL), with first absolute line information
|
||||||
|
@ -433,11 +465,11 @@ if not _soft then
|
||||||
-- several tests that exaust the Lua stack
|
-- several tests that exaust the Lua stack
|
||||||
collectgarbage()
|
collectgarbage()
|
||||||
print"testing stack overflow"
|
print"testing stack overflow"
|
||||||
C = 0
|
local C = 0
|
||||||
-- get line where stack overflow will happen
|
-- get line where stack overflow will happen
|
||||||
local l = debug.getinfo(1, "l").currentline + 1
|
local l = debug.getinfo(1, "l").currentline + 1
|
||||||
local function auxy () C=C+1; auxy() end -- produce a stack overflow
|
local function auxy () C=C+1; auxy() end -- produce a stack overflow
|
||||||
function y ()
|
function YY ()
|
||||||
collectgarbage("stop") -- avoid running finalizers without stack space
|
collectgarbage("stop") -- avoid running finalizers without stack space
|
||||||
auxy()
|
auxy()
|
||||||
collectgarbage("restart")
|
collectgarbage("restart")
|
||||||
|
@ -449,9 +481,11 @@ if not _soft then
|
||||||
return (string.find(m, "stack overflow"))
|
return (string.find(m, "stack overflow"))
|
||||||
end
|
end
|
||||||
-- repeated stack overflows (to check stack recovery)
|
-- repeated stack overflows (to check stack recovery)
|
||||||
assert(checkstackmessage(doit('y()')))
|
assert(checkstackmessage(doit('YY()')))
|
||||||
assert(checkstackmessage(doit('y()')))
|
assert(checkstackmessage(doit('YY()')))
|
||||||
assert(checkstackmessage(doit('y()')))
|
assert(checkstackmessage(doit('YY()')))
|
||||||
|
|
||||||
|
_G.YY = nil
|
||||||
|
|
||||||
|
|
||||||
-- error lines in stack overflow
|
-- error lines in stack overflow
|
||||||
|
@ -545,7 +579,7 @@ do
|
||||||
end
|
end
|
||||||
|
|
||||||
-- xpcall with arguments
|
-- xpcall with arguments
|
||||||
a, b, c = xpcall(string.find, error, "alo", "al")
|
local a, b, c = xpcall(string.find, error, "alo", "al")
|
||||||
assert(a and b == 1 and c == 2)
|
assert(a and b == 1 and c == 2)
|
||||||
a, b, c = xpcall(string.find, function (x) return {} end, true, "al")
|
a, b, c = xpcall(string.find, function (x) return {} end, true, "al")
|
||||||
assert(not a and type(b) == "table" and c == nil)
|
assert(not a and type(b) == "table" and c == nil)
|
||||||
|
@ -565,11 +599,12 @@ checksyntax("a\1a = 1", "", "<\\1>", 1)
|
||||||
-- test 255 as first char in a chunk
|
-- test 255 as first char in a chunk
|
||||||
checksyntax("\255a = 1", "", "<\\255>", 1)
|
checksyntax("\255a = 1", "", "<\\255>", 1)
|
||||||
|
|
||||||
doit('I = load("a=9+"); a=3')
|
doit('I = load("a=9+"); aaa=3')
|
||||||
assert(a==3 and not I)
|
assert(_G.aaa==3 and not _G.I)
|
||||||
|
_G.I,_G.aaa = nil
|
||||||
print('+')
|
print('+')
|
||||||
|
|
||||||
lim = 1000
|
local lim = 1000
|
||||||
if _soft then lim = 100 end
|
if _soft then lim = 100 end
|
||||||
for i=1,lim do
|
for i=1,lim do
|
||||||
doit('a = ')
|
doit('a = ')
|
||||||
|
|
3
third_party/lua/test/events.lua
vendored
3
third_party/lua/test/events.lua
vendored
|
@ -420,6 +420,9 @@ assert(i == 3 and x[1] == 3 and x[3] == 5)
|
||||||
|
|
||||||
assert(_G.X == 20)
|
assert(_G.X == 20)
|
||||||
|
|
||||||
|
_G.X, _G.B = nil
|
||||||
|
|
||||||
|
|
||||||
print'+'
|
print'+'
|
||||||
|
|
||||||
local _g = _G
|
local _g = _G
|
||||||
|
|
18
third_party/lua/test/files.lua
vendored
18
third_party/lua/test/files.lua
vendored
|
@ -507,15 +507,17 @@ load((io.lines(file, 1)))()
|
||||||
assert(_G.X == 4)
|
assert(_G.X == 4)
|
||||||
load((io.lines(file, 3)))()
|
load((io.lines(file, 3)))()
|
||||||
assert(_G.X == 8)
|
assert(_G.X == 8)
|
||||||
|
_G.X = nil
|
||||||
|
|
||||||
print('+')
|
print('+')
|
||||||
|
|
||||||
local x1 = "string\n\n\\com \"\"''coisas [[estranhas]] ]]'"
|
local x1 = "string\n\n\\com \"\"''coisas [[estranhas]] ]]'"
|
||||||
io.output(file)
|
io.output(file)
|
||||||
assert(io.write(string.format("x2 = %q\n-- comment without ending EOS", x1)))
|
assert(io.write(string.format("X2 = %q\n-- comment without ending EOS", x1)))
|
||||||
io.close()
|
io.close()
|
||||||
assert(loadfile(file))()
|
assert(loadfile(file))()
|
||||||
assert(x1 == x2)
|
assert(x1 == _G.X2)
|
||||||
|
_G.X2 = nil
|
||||||
print('+')
|
print('+')
|
||||||
assert(os.remove(file))
|
assert(os.remove(file))
|
||||||
assert(not os.remove(file))
|
assert(not os.remove(file))
|
||||||
|
@ -610,6 +612,7 @@ do
|
||||||
assert(os.remove(file))
|
assert(os.remove(file))
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
||||||
io.output(file)
|
io.output(file)
|
||||||
assert(io.write("qualquer coisa\n"))
|
assert(io.write("qualquer coisa\n"))
|
||||||
assert(io.write("mais qualquer coisa"))
|
assert(io.write("mais qualquer coisa"))
|
||||||
|
@ -743,7 +746,7 @@ if not _port then
|
||||||
{"exit 129", "exit", 129},
|
{"exit 129", "exit", 129},
|
||||||
{"kill -s HUP $$", "signal", 1},
|
{"kill -s HUP $$", "signal", 1},
|
||||||
{"kill -s KILL $$", "signal", 9},
|
{"kill -s KILL $$", "signal", 9},
|
||||||
{"sh -c 'kill -s HUP $$'", "signal", 1},
|
{"sh -c 'kill -s HUP $$'", "signal", 1}, -- [jart]
|
||||||
{progname .. ' -e " "', "ok"},
|
{progname .. ' -e " "', "ok"},
|
||||||
{progname .. ' -e "os.exit(0, true)"', "ok"},
|
{progname .. ' -e "os.exit(0, true)"', "ok"},
|
||||||
{progname .. ' -e "os.exit(20, true)"', "exit", 20},
|
{progname .. ' -e "os.exit(20, true)"', "exit", 20},
|
||||||
|
@ -833,8 +836,17 @@ checkerr("missing", os.time, {hour = 12}) -- missing date
|
||||||
if string.packsize("i") == 4 then -- 4-byte ints
|
if string.packsize("i") == 4 then -- 4-byte ints
|
||||||
checkerr("field 'year' is out-of-bound", os.time,
|
checkerr("field 'year' is out-of-bound", os.time,
|
||||||
{year = -(1 << 31) + 1899, month = 1, day = 1})
|
{year = -(1 << 31) + 1899, month = 1, day = 1})
|
||||||
|
|
||||||
|
checkerr("field 'year' is out-of-bound", os.time,
|
||||||
|
{year = -(1 << 31), month = 1, day = 1})
|
||||||
|
|
||||||
|
if math.maxinteger > 2^31 then -- larger lua_integer?
|
||||||
|
checkerr("field 'year' is out-of-bound", os.time,
|
||||||
|
{year = (1 << 31) + 1900, month = 1, day = 1})
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
||||||
if not _port then
|
if not _port then
|
||||||
-- test Posix-specific modifiers
|
-- test Posix-specific modifiers
|
||||||
assert(type(os.date("%Ex")) == 'string')
|
assert(type(os.date("%Ex")) == 'string')
|
||||||
|
|
34
third_party/lua/test/gc.lua
vendored
34
third_party/lua/test/gc.lua
vendored
|
@ -125,7 +125,7 @@ do
|
||||||
end
|
end
|
||||||
|
|
||||||
a:test()
|
a:test()
|
||||||
|
_G.temp = nil
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
||||||
|
@ -134,7 +134,7 @@ do local f = function () end end
|
||||||
|
|
||||||
|
|
||||||
print("functions with errors")
|
print("functions with errors")
|
||||||
prog = [[
|
local prog = [[
|
||||||
do
|
do
|
||||||
a = 10;
|
a = 10;
|
||||||
function foo(x,y)
|
function foo(x,y)
|
||||||
|
@ -153,22 +153,25 @@ do
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
rawset(_G, "a", nil)
|
||||||
|
_G.x = nil
|
||||||
|
|
||||||
|
do
|
||||||
foo = nil
|
foo = nil
|
||||||
print('long strings')
|
print('long strings')
|
||||||
x = "01234567890123456789012345678901234567890123456789012345678901234567890123456789"
|
local x = "01234567890123456789012345678901234567890123456789012345678901234567890123456789"
|
||||||
assert(string.len(x)==80)
|
assert(string.len(x)==80)
|
||||||
s = ''
|
local s = ''
|
||||||
k = math.min(300, (math.maxinteger // 80) // 2)
|
local k = math.min(300, (math.maxinteger // 80) // 2)
|
||||||
for n = 1, k do s = s..x; j=tostring(n) end
|
for n = 1, k do s = s..x; local j=tostring(n) end
|
||||||
assert(string.len(s) == k*80)
|
assert(string.len(s) == k*80)
|
||||||
s = string.sub(s, 1, 10000)
|
s = string.sub(s, 1, 10000)
|
||||||
s, i = string.gsub(s, '(%d%d%d%d)', '')
|
local s, i = string.gsub(s, '(%d%d%d%d)', '')
|
||||||
assert(i==10000 // 4)
|
assert(i==10000 // 4)
|
||||||
s = nil
|
|
||||||
x = nil
|
|
||||||
|
|
||||||
assert(_G["while"] == 234)
|
assert(_G["while"] == 234)
|
||||||
|
_G["while"] = nil
|
||||||
|
end
|
||||||
|
|
||||||
|
|
||||||
--
|
--
|
||||||
|
@ -227,8 +230,8 @@ end
|
||||||
|
|
||||||
|
|
||||||
print("clearing tables")
|
print("clearing tables")
|
||||||
lim = 15
|
local lim = 15
|
||||||
a = {}
|
local a = {}
|
||||||
-- fill a with `collectable' indices
|
-- fill a with `collectable' indices
|
||||||
for i=1,lim do a[{}] = i end
|
for i=1,lim do a[{}] = i end
|
||||||
b = {}
|
b = {}
|
||||||
|
@ -371,7 +374,7 @@ if T then
|
||||||
|
|
||||||
warn("@on"); warn("@store")
|
warn("@on"); warn("@store")
|
||||||
collectgarbage()
|
collectgarbage()
|
||||||
assert(string.find(_WARN, "error in __gc metamethod"))
|
assert(string.find(_WARN, "error in __gc"))
|
||||||
assert(string.match(_WARN, "@(.-)@") == "expected"); _WARN = false
|
assert(string.match(_WARN, "@(.-)@") == "expected"); _WARN = false
|
||||||
for i = 8, 10 do assert(s[i]) end
|
for i = 8, 10 do assert(s[i]) end
|
||||||
|
|
||||||
|
@ -552,6 +555,7 @@ do
|
||||||
for i=1,1000 do _ENV.a = {} end -- no collection during the loop
|
for i=1,1000 do _ENV.a = {} end -- no collection during the loop
|
||||||
until gcinfo() > 2 * x
|
until gcinfo() > 2 * x
|
||||||
collectgarbage"restart"
|
collectgarbage"restart"
|
||||||
|
_ENV.a = nil
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
||||||
|
@ -676,11 +680,13 @@ end
|
||||||
-- just to make sure
|
-- just to make sure
|
||||||
assert(collectgarbage'isrunning')
|
assert(collectgarbage'isrunning')
|
||||||
|
|
||||||
do -- check that the collector is reentrant in incremental mode
|
do -- check that the collector is not reentrant in incremental mode
|
||||||
|
local res = true
|
||||||
setmetatable({}, {__gc = function ()
|
setmetatable({}, {__gc = function ()
|
||||||
collectgarbage()
|
res = collectgarbage()
|
||||||
end})
|
end})
|
||||||
collectgarbage()
|
collectgarbage()
|
||||||
|
assert(not res)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
||||||
|
|
10
third_party/lua/test/libs/makefile
vendored
10
third_party/lua/test/libs/makefile
vendored
|
@ -11,17 +11,17 @@ CFLAGS = -Wall -std=gnu99 -O2 -I$(LUA_DIR) -fPIC -shared
|
||||||
all: lib1.so lib11.so lib2.so lib21.so lib2-v2.so
|
all: lib1.so lib11.so lib2.so lib21.so lib2-v2.so
|
||||||
touch all
|
touch all
|
||||||
|
|
||||||
lib1.so: lib1.c $(LUA_DIR)/luaconf.h
|
lib1.so: lib1.c $(LUA_DIR)/luaconf.h $(LUA_DIR)/lua.h
|
||||||
$(CC) $(CFLAGS) -o lib1.so lib1.c
|
$(CC) $(CFLAGS) -o lib1.so lib1.c
|
||||||
|
|
||||||
lib11.so: lib11.c $(LUA_DIR)/luaconf.h
|
lib11.so: lib11.c $(LUA_DIR)/luaconf.h $(LUA_DIR)/lua.h
|
||||||
$(CC) $(CFLAGS) -o lib11.so lib11.c
|
$(CC) $(CFLAGS) -o lib11.so lib11.c
|
||||||
|
|
||||||
lib2.so: lib2.c $(LUA_DIR)/luaconf.h
|
lib2.so: lib2.c $(LUA_DIR)/luaconf.h $(LUA_DIR)/lua.h
|
||||||
$(CC) $(CFLAGS) -o lib2.so lib2.c
|
$(CC) $(CFLAGS) -o lib2.so lib2.c
|
||||||
|
|
||||||
lib21.so: lib21.c $(LUA_DIR)/luaconf.h
|
lib21.so: lib21.c $(LUA_DIR)/luaconf.h $(LUA_DIR)/lua.h
|
||||||
$(CC) $(CFLAGS) -o lib21.so lib21.c
|
$(CC) $(CFLAGS) -o lib21.so lib21.c
|
||||||
|
|
||||||
lib2-v2.so: lib21.c $(LUA_DIR)/luaconf.h
|
lib2-v2.so: lib21.c $(LUA_DIR)/luaconf.h $(LUA_DIR)/lua.h
|
||||||
$(CC) $(CFLAGS) -o lib2-v2.so lib22.c
|
$(CC) $(CFLAGS) -o lib2-v2.so lib22.c
|
||||||
|
|
57
third_party/lua/test/literals.lua
vendored
57
third_party/lua/test/literals.lua
vendored
|
@ -10,6 +10,7 @@ local function dostring (x) return assert(load(x), "")() end
|
||||||
|
|
||||||
dostring("x \v\f = \t\r 'a\0a' \v\f\f")
|
dostring("x \v\f = \t\r 'a\0a' \v\f\f")
|
||||||
assert(x == 'a\0a' and string.len(x) == 3)
|
assert(x == 'a\0a' and string.len(x) == 3)
|
||||||
|
_G.x = nil
|
||||||
|
|
||||||
-- escape sequences
|
-- escape sequences
|
||||||
assert('\n\"\'\\' == [[
|
assert('\n\"\'\\' == [[
|
||||||
|
@ -129,16 +130,16 @@ end
|
||||||
|
|
||||||
-- long variable names
|
-- long variable names
|
||||||
|
|
||||||
var1 = string.rep('a', 15000) .. '1'
|
local var1 = string.rep('a', 15000) .. '1'
|
||||||
var2 = string.rep('a', 15000) .. '2'
|
local var2 = string.rep('a', 15000) .. '2'
|
||||||
prog = string.format([[
|
local prog = string.format([[
|
||||||
%s = 5
|
%s = 5
|
||||||
%s = %s + 1
|
%s = %s + 1
|
||||||
return function () return %s - %s end
|
return function () return %s - %s end
|
||||||
]], var1, var2, var1, var1, var2)
|
]], var1, var2, var1, var1, var2)
|
||||||
local f = dostring(prog)
|
local f = dostring(prog)
|
||||||
assert(_G[var1] == 5 and _G[var2] == 6 and f() == -1)
|
assert(_G[var1] == 5 and _G[var2] == 6 and f() == -1)
|
||||||
var1, var2, f = nil
|
_G[var1], _G[var2] = nil
|
||||||
print('+')
|
print('+')
|
||||||
|
|
||||||
-- escapes --
|
-- escapes --
|
||||||
|
@ -150,13 +151,13 @@ assert([[
|
||||||
$debug]] == "\n $debug")
|
$debug]] == "\n $debug")
|
||||||
assert([[ [ ]] ~= [[ ] ]])
|
assert([[ [ ]] ~= [[ ] ]])
|
||||||
-- long strings --
|
-- long strings --
|
||||||
b = "001234567890123456789012345678901234567891234567890123456789012345678901234567890012345678901234567890123456789012345678912345678901234567890123456789012345678900123456789012345678901234567890123456789123456789012345678901234567890123456789001234567890123456789012345678901234567891234567890123456789012345678901234567890012345678901234567890123456789012345678912345678901234567890123456789012345678900123456789012345678901234567890123456789123456789012345678901234567890123456789001234567890123456789012345678901234567891234567890123456789012345678901234567890012345678901234567890123456789012345678912345678901234567890123456789012345678900123456789012345678901234567890123456789123456789012345678901234567890123456789001234567890123456789012345678901234567891234567890123456789012345678901234567890012345678901234567890123456789012345678912345678901234567890123456789012345678900123456789012345678901234567890123456789123456789012345678901234567890123456789"
|
local b = "001234567890123456789012345678901234567891234567890123456789012345678901234567890012345678901234567890123456789012345678912345678901234567890123456789012345678900123456789012345678901234567890123456789123456789012345678901234567890123456789001234567890123456789012345678901234567891234567890123456789012345678901234567890012345678901234567890123456789012345678912345678901234567890123456789012345678900123456789012345678901234567890123456789123456789012345678901234567890123456789001234567890123456789012345678901234567891234567890123456789012345678901234567890012345678901234567890123456789012345678912345678901234567890123456789012345678900123456789012345678901234567890123456789123456789012345678901234567890123456789001234567890123456789012345678901234567891234567890123456789012345678901234567890012345678901234567890123456789012345678912345678901234567890123456789012345678900123456789012345678901234567890123456789123456789012345678901234567890123456789"
|
||||||
assert(string.len(b) == 960)
|
assert(string.len(b) == 960)
|
||||||
prog = [=[
|
prog = [=[
|
||||||
print('+')
|
print('+')
|
||||||
|
|
||||||
a1 = [["this is a 'string' with several 'quotes'"]]
|
local a1 = [["this is a 'string' with several 'quotes'"]]
|
||||||
a2 = "'quotes'"
|
local a2 = "'quotes'"
|
||||||
|
|
||||||
assert(string.find(a1, a2) == 34)
|
assert(string.find(a1, a2) == 34)
|
||||||
print('+')
|
print('+')
|
||||||
|
@ -164,12 +165,13 @@ print('+')
|
||||||
a1 = [==[temp = [[an arbitrary value]]; ]==]
|
a1 = [==[temp = [[an arbitrary value]]; ]==]
|
||||||
assert(load(a1))()
|
assert(load(a1))()
|
||||||
assert(temp == 'an arbitrary value')
|
assert(temp == 'an arbitrary value')
|
||||||
|
_G.temp = nil
|
||||||
-- long strings --
|
-- long strings --
|
||||||
b = "001234567890123456789012345678901234567891234567890123456789012345678901234567890012345678901234567890123456789012345678912345678901234567890123456789012345678900123456789012345678901234567890123456789123456789012345678901234567890123456789001234567890123456789012345678901234567891234567890123456789012345678901234567890012345678901234567890123456789012345678912345678901234567890123456789012345678900123456789012345678901234567890123456789123456789012345678901234567890123456789001234567890123456789012345678901234567891234567890123456789012345678901234567890012345678901234567890123456789012345678912345678901234567890123456789012345678900123456789012345678901234567890123456789123456789012345678901234567890123456789001234567890123456789012345678901234567891234567890123456789012345678901234567890012345678901234567890123456789012345678912345678901234567890123456789012345678900123456789012345678901234567890123456789123456789012345678901234567890123456789"
|
local b = "001234567890123456789012345678901234567891234567890123456789012345678901234567890012345678901234567890123456789012345678912345678901234567890123456789012345678900123456789012345678901234567890123456789123456789012345678901234567890123456789001234567890123456789012345678901234567891234567890123456789012345678901234567890012345678901234567890123456789012345678912345678901234567890123456789012345678900123456789012345678901234567890123456789123456789012345678901234567890123456789001234567890123456789012345678901234567891234567890123456789012345678901234567890012345678901234567890123456789012345678912345678901234567890123456789012345678900123456789012345678901234567890123456789123456789012345678901234567890123456789001234567890123456789012345678901234567891234567890123456789012345678901234567890012345678901234567890123456789012345678912345678901234567890123456789012345678900123456789012345678901234567890123456789123456789012345678901234567890123456789"
|
||||||
assert(string.len(b) == 960)
|
assert(string.len(b) == 960)
|
||||||
print('+')
|
print('+')
|
||||||
|
|
||||||
a = [[00123456789012345678901234567890123456789123456789012345678901234567890123456789
|
local a = [[00123456789012345678901234567890123456789123456789012345678901234567890123456789
|
||||||
00123456789012345678901234567890123456789123456789012345678901234567890123456789
|
00123456789012345678901234567890123456789123456789012345678901234567890123456789
|
||||||
00123456789012345678901234567890123456789123456789012345678901234567890123456789
|
00123456789012345678901234567890123456789123456789012345678901234567890123456789
|
||||||
00123456789012345678901234567890123456789123456789012345678901234567890123456789
|
00123456789012345678901234567890123456789123456789012345678901234567890123456789
|
||||||
|
@ -199,19 +201,41 @@ x = 1
|
||||||
]=]
|
]=]
|
||||||
|
|
||||||
print('+')
|
print('+')
|
||||||
x = nil
|
_G.x = nil
|
||||||
dostring(prog)
|
dostring(prog)
|
||||||
assert(x)
|
assert(x)
|
||||||
|
_G.x = nil
|
||||||
|
|
||||||
prog = nil
|
|
||||||
a = nil
|
|
||||||
b = nil
|
do -- reuse of long strings
|
||||||
|
|
||||||
|
-- get the address of a string
|
||||||
|
local function getadd (s) return string.format("%p", s) end
|
||||||
|
|
||||||
|
local s1 <const> = "01234567890123456789012345678901234567890123456789"
|
||||||
|
local s2 <const> = "01234567890123456789012345678901234567890123456789"
|
||||||
|
local s3 = "01234567890123456789012345678901234567890123456789"
|
||||||
|
local function foo() return s1 end
|
||||||
|
local function foo1() return s3 end
|
||||||
|
local function foo2()
|
||||||
|
return "01234567890123456789012345678901234567890123456789"
|
||||||
|
end
|
||||||
|
local a1 = getadd(s1)
|
||||||
|
assert(a1 == getadd(s2))
|
||||||
|
assert(a1 == getadd(foo()))
|
||||||
|
assert(a1 == getadd(foo1()))
|
||||||
|
assert(a1 == getadd(foo2()))
|
||||||
|
|
||||||
|
local sd = "0123456789" .. "0123456789012345678901234567890123456789"
|
||||||
|
assert(sd == s1 and getadd(sd) ~= a1)
|
||||||
|
end
|
||||||
|
|
||||||
|
|
||||||
-- testing line ends
|
-- testing line ends
|
||||||
prog = [[
|
prog = [[
|
||||||
a = 1 -- a comment
|
local a = 1 -- a comment
|
||||||
b = 2
|
local b = 2
|
||||||
|
|
||||||
|
|
||||||
x = [=[
|
x = [=[
|
||||||
|
@ -228,10 +252,11 @@ for _, n in pairs{"\n", "\r", "\n\r", "\r\n"} do
|
||||||
assert(dostring(prog) == nn)
|
assert(dostring(prog) == nn)
|
||||||
assert(_G.x == "hi\n" and _G.y == "\nhello\r\n\n")
|
assert(_G.x == "hi\n" and _G.y == "\nhello\r\n\n")
|
||||||
end
|
end
|
||||||
|
_G.x, _G.y = nil
|
||||||
|
|
||||||
|
|
||||||
-- testing comments and strings with long brackets
|
-- testing comments and strings with long brackets
|
||||||
a = [==[]=]==]
|
local a = [==[]=]==]
|
||||||
assert(a == "]=")
|
assert(a == "]=")
|
||||||
|
|
||||||
a = [==[[===[[=[]]=][====[]]===]===]==]
|
a = [==[[===[[=[]]=][====[]]===]===]==]
|
||||||
|
|
134
third_party/lua/test/locals.lua
vendored
134
third_party/lua/test/locals.lua
vendored
|
@ -37,7 +37,7 @@ end
|
||||||
f = nil
|
f = nil
|
||||||
|
|
||||||
local f
|
local f
|
||||||
x = 1
|
local x = 1
|
||||||
|
|
||||||
a = nil
|
a = nil
|
||||||
load('local a = {}')()
|
load('local a = {}')()
|
||||||
|
@ -152,7 +152,7 @@ local dummy
|
||||||
local _ENV = (function (...) return ... end)(_G, dummy) -- {
|
local _ENV = (function (...) return ... end)(_G, dummy) -- {
|
||||||
|
|
||||||
do local _ENV = {assert=assert}; assert(true) end
|
do local _ENV = {assert=assert}; assert(true) end
|
||||||
mt = {_G = _G}
|
local mt = {_G = _G}
|
||||||
local foo,x
|
local foo,x
|
||||||
A = false -- "declare" A
|
A = false -- "declare" A
|
||||||
do local _ENV = mt
|
do local _ENV = mt
|
||||||
|
@ -174,6 +174,8 @@ do local _ENV = {assert=assert, A=10};
|
||||||
end
|
end
|
||||||
assert(x==20)
|
assert(x==20)
|
||||||
|
|
||||||
|
A = nil
|
||||||
|
|
||||||
|
|
||||||
do -- constants
|
do -- constants
|
||||||
local a<const>, b, c<const> = 10, 20, 30
|
local a<const>, b, c<const> = 10, 20, 30
|
||||||
|
@ -187,6 +189,8 @@ do -- constants
|
||||||
checkro("y", "local x, y <const>, z = 10, 20, 30; x = 11; y = 12")
|
checkro("y", "local x, y <const>, z = 10, 20, 30; x = 11; y = 12")
|
||||||
checkro("x", "local x <const>, y, z <const> = 10, 20, 30; x = 11")
|
checkro("x", "local x <const>, y, z <const> = 10, 20, 30; x = 11")
|
||||||
checkro("z", "local x <const>, y, z <const> = 10, 20, 30; y = 10; z = 11")
|
checkro("z", "local x <const>, y, z <const> = 10, 20, 30; y = 10; z = 11")
|
||||||
|
checkro("foo", "local foo <const> = 10; function foo() end")
|
||||||
|
checkro("foo", "local foo <const> = {}; function foo() end")
|
||||||
|
|
||||||
checkro("z", [[
|
checkro("z", [[
|
||||||
local a, z <const>, b = 10;
|
local a, z <const>, b = 10;
|
||||||
|
@ -335,6 +339,49 @@ do
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
||||||
|
do
|
||||||
|
-- bug in 5.4.3: previous condition (calls cannot be tail in the
|
||||||
|
-- scope of to-be-closed variables) must be valid for tbc variables
|
||||||
|
-- created by 'for' loops.
|
||||||
|
|
||||||
|
local closed = false
|
||||||
|
|
||||||
|
local function foo ()
|
||||||
|
return function () return true end, 0, 0,
|
||||||
|
func2close(function () closed = true end)
|
||||||
|
end
|
||||||
|
|
||||||
|
local function tail() return closed end
|
||||||
|
|
||||||
|
local function foo1 ()
|
||||||
|
for k in foo() do return tail() end
|
||||||
|
end
|
||||||
|
|
||||||
|
assert(foo1() == false)
|
||||||
|
assert(closed == true)
|
||||||
|
end
|
||||||
|
|
||||||
|
|
||||||
|
do
|
||||||
|
-- bug in 5.4.4: 'break' may generate wrong 'close' instruction when
|
||||||
|
-- leaving a loop block.
|
||||||
|
|
||||||
|
local closed = false
|
||||||
|
|
||||||
|
local o1 = setmetatable({}, {__close=function() closed = true end})
|
||||||
|
|
||||||
|
local function test()
|
||||||
|
for k, v in next, {}, nil, o1 do
|
||||||
|
local function f() return k end -- create an upvalue
|
||||||
|
break
|
||||||
|
end
|
||||||
|
assert(closed)
|
||||||
|
end
|
||||||
|
|
||||||
|
test()
|
||||||
|
end
|
||||||
|
|
||||||
|
|
||||||
do print("testing errors in __close")
|
do print("testing errors in __close")
|
||||||
|
|
||||||
-- original error is in __close
|
-- original error is in __close
|
||||||
|
@ -567,6 +614,28 @@ end
|
||||||
|
|
||||||
if rawget(_G, "T") then
|
if rawget(_G, "T") then
|
||||||
|
|
||||||
|
do
|
||||||
|
-- bug in 5.4.3
|
||||||
|
-- 'lua_settop' may use a pointer to stack invalidated by 'luaF_close'
|
||||||
|
|
||||||
|
-- reduce stack size
|
||||||
|
collectgarbage(); collectgarbage(); collectgarbage()
|
||||||
|
|
||||||
|
-- force a stack reallocation
|
||||||
|
local function loop (n)
|
||||||
|
if n < 400 then loop(n + 1) end
|
||||||
|
end
|
||||||
|
|
||||||
|
-- close metamethod will reallocate the stack
|
||||||
|
local o = setmetatable({}, {__close = function () loop(0) end})
|
||||||
|
|
||||||
|
local script = [[toclose 2; settop 1; return 1]]
|
||||||
|
|
||||||
|
assert(T.testC(script, o) == script)
|
||||||
|
|
||||||
|
end
|
||||||
|
|
||||||
|
|
||||||
-- memory error inside closing function
|
-- memory error inside closing function
|
||||||
local function foo ()
|
local function foo ()
|
||||||
local y <close> = func2close(function () T.alloccount() end)
|
local y <close> = func2close(function () T.alloccount() end)
|
||||||
|
@ -644,7 +713,7 @@ if rawget(_G, "T") then
|
||||||
|
|
||||||
collectgarbage(); collectgarbage()
|
collectgarbage(); collectgarbage()
|
||||||
|
|
||||||
m = T.totalmem()
|
local m = T.totalmem()
|
||||||
collectgarbage("stop")
|
collectgarbage("stop")
|
||||||
|
|
||||||
-- error in the first buffer allocation
|
-- error in the first buffer allocation
|
||||||
|
@ -790,6 +859,65 @@ do
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
||||||
|
do
|
||||||
|
-- yielding inside closing metamethods while returning
|
||||||
|
-- (bug in 5.4.3)
|
||||||
|
|
||||||
|
local extrares -- result from extra yield (if any)
|
||||||
|
|
||||||
|
local function check (body, extra, ...)
|
||||||
|
local t = table.pack(...) -- expected returns
|
||||||
|
local co = coroutine.wrap(body)
|
||||||
|
if extra then
|
||||||
|
extrares = co() -- runs until first (extra) yield
|
||||||
|
end
|
||||||
|
local res = table.pack(co()) -- runs until yield inside '__close'
|
||||||
|
assert(res.n == 2 and res[2] == nil)
|
||||||
|
local res2 = table.pack(co()) -- runs until end of function
|
||||||
|
assert(res2.n == t.n)
|
||||||
|
for i = 1, #t do
|
||||||
|
if t[i] == "x" then
|
||||||
|
assert(res2[i] == res[1]) -- value that was closed
|
||||||
|
else
|
||||||
|
assert(res2[i] == t[i])
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
local function foo ()
|
||||||
|
local x <close> = func2close(coroutine.yield)
|
||||||
|
local extra <close> = func2close(function (self)
|
||||||
|
assert(self == extrares)
|
||||||
|
coroutine.yield(100)
|
||||||
|
end)
|
||||||
|
extrares = extra
|
||||||
|
return table.unpack{10, x, 30}
|
||||||
|
end
|
||||||
|
check(foo, true, 10, "x", 30)
|
||||||
|
assert(extrares == 100)
|
||||||
|
|
||||||
|
local function foo ()
|
||||||
|
local x <close> = func2close(coroutine.yield)
|
||||||
|
return
|
||||||
|
end
|
||||||
|
check(foo, false)
|
||||||
|
|
||||||
|
local function foo ()
|
||||||
|
local x <close> = func2close(coroutine.yield)
|
||||||
|
local y, z = 20, 30
|
||||||
|
return x
|
||||||
|
end
|
||||||
|
check(foo, false, "x")
|
||||||
|
|
||||||
|
local function foo ()
|
||||||
|
local x <close> = func2close(coroutine.yield)
|
||||||
|
local extra <close> = func2close(coroutine.yield)
|
||||||
|
return table.unpack({}, 1, 100) -- 100 nils
|
||||||
|
end
|
||||||
|
check(foo, true, table.unpack({}, 1, 100))
|
||||||
|
|
||||||
|
end
|
||||||
|
|
||||||
do
|
do
|
||||||
-- yielding inside closing metamethods after an error
|
-- yielding inside closing metamethods after an error
|
||||||
|
|
||||||
|
|
72
third_party/lua/test/main.lua
vendored
72
third_party/lua/test/main.lua
vendored
|
@ -94,6 +94,33 @@ RUN('echo "print(10)\nprint(2)\n" | lua > %s', out)
|
||||||
checkout("10\n2\n")
|
checkout("10\n2\n")
|
||||||
|
|
||||||
|
|
||||||
|
-- testing BOM
|
||||||
|
prepfile("\xEF\xBB\xBF")
|
||||||
|
RUN('lua %s > %s', prog, out)
|
||||||
|
checkout("")
|
||||||
|
|
||||||
|
prepfile("\xEF\xBB\xBFprint(3)")
|
||||||
|
RUN('lua %s > %s', prog, out)
|
||||||
|
checkout("3\n")
|
||||||
|
|
||||||
|
prepfile("\xEF\xBB\xBF# comment!!\nprint(3)")
|
||||||
|
RUN('lua %s > %s', prog, out)
|
||||||
|
checkout("3\n")
|
||||||
|
|
||||||
|
-- bad BOMs
|
||||||
|
prepfile("\xEF")
|
||||||
|
NoRun("unexpected symbol", 'lua %s > %s', prog, out)
|
||||||
|
|
||||||
|
prepfile("\xEF\xBB")
|
||||||
|
NoRun("unexpected symbol", 'lua %s > %s', prog, out)
|
||||||
|
|
||||||
|
prepfile("\xEFprint(3)")
|
||||||
|
NoRun("unexpected symbol", 'lua %s > %s', prog, out)
|
||||||
|
|
||||||
|
prepfile("\xEF\xBBprint(3)")
|
||||||
|
NoRun("unexpected symbol", 'lua %s > %s', prog, out)
|
||||||
|
|
||||||
|
|
||||||
-- test option '-'
|
-- test option '-'
|
||||||
RUN('echo "print(arg[1])" | lua - -h > %s', out)
|
RUN('echo "print(arg[1])" | lua - -h > %s', out)
|
||||||
checkout("-h\n")
|
checkout("-h\n")
|
||||||
|
@ -190,6 +217,11 @@ prepfile(("print(a); print(_G['%s'].x)"):format(prog), otherprog)
|
||||||
RUN('env LUA_PATH="?;;" lua -l %s -l%s -lstring -l io %s > %s', prog, otherprog, otherprog, out)
|
RUN('env LUA_PATH="?;;" lua -l %s -l%s -lstring -l io %s > %s', prog, otherprog, otherprog, out)
|
||||||
checkout("1\n2\n15\n2\n15\n")
|
checkout("1\n2\n15\n2\n15\n")
|
||||||
|
|
||||||
|
-- test explicit global names in -l
|
||||||
|
prepfile("print(str.upper'alo alo', m.max(10, 20))")
|
||||||
|
RUN("lua -l 'str=string' '-lm=math' -e 'print(m.sin(0))' %s > %s", prog, out)
|
||||||
|
checkout("0.0\nALO ALO\t20\n")
|
||||||
|
|
||||||
-- test 'arg' table
|
-- test 'arg' table
|
||||||
local a = [[
|
local a = [[
|
||||||
assert(#arg == 3 and arg[1] == 'a' and
|
assert(#arg == 3 and arg[1] == 'a' and
|
||||||
|
@ -256,6 +288,34 @@ u2 = setmetatable({}, {__gc = function () error("ZYX") end})
|
||||||
RUN('lua -W %s 2> %s', prog, out)
|
RUN('lua -W %s 2> %s', prog, out)
|
||||||
checkprogout("ZYX)\nXYZ)\n")
|
checkprogout("ZYX)\nXYZ)\n")
|
||||||
|
|
||||||
|
-- bug since 5.2: finalizer called when closing a state could
|
||||||
|
-- subvert finalization order
|
||||||
|
prepfile[[
|
||||||
|
-- should be called last
|
||||||
|
print("creating 1")
|
||||||
|
setmetatable({}, {__gc = function () print(1) end})
|
||||||
|
|
||||||
|
print("creating 2")
|
||||||
|
setmetatable({}, {__gc = function ()
|
||||||
|
print("2")
|
||||||
|
print("creating 3")
|
||||||
|
-- this finalizer should not be called, as object will be
|
||||||
|
-- created after 'lua_close' has been called
|
||||||
|
setmetatable({}, {__gc = function () print(3) end})
|
||||||
|
print(collectgarbage()) -- cannot call collector here
|
||||||
|
os.exit(0, true)
|
||||||
|
end})
|
||||||
|
]]
|
||||||
|
RUN('lua -W %s > %s', prog, out)
|
||||||
|
checkout[[
|
||||||
|
creating 1
|
||||||
|
creating 2
|
||||||
|
2
|
||||||
|
creating 3
|
||||||
|
nil
|
||||||
|
1
|
||||||
|
]]
|
||||||
|
|
||||||
|
|
||||||
-- test many arguments
|
-- test many arguments
|
||||||
prepfile[[print(({...})[30])]]
|
prepfile[[print(({...})[30])]]
|
||||||
|
@ -279,7 +339,7 @@ prepfile("a = [[b\nc\nd\ne]]\n=a")
|
||||||
RUN([[lua -e"_PROMPT='' _PROMPT2=''" -i < %s > %s]], prog, out)
|
RUN([[lua -e"_PROMPT='' _PROMPT2=''" -i < %s > %s]], prog, out)
|
||||||
checkprogout("b\nc\nd\ne\n\n")
|
checkprogout("b\nc\nd\ne\n\n")
|
||||||
|
|
||||||
prompt = "alo"
|
local prompt = "alo"
|
||||||
prepfile[[ --
|
prepfile[[ --
|
||||||
a = 2
|
a = 2
|
||||||
]]
|
]]
|
||||||
|
@ -339,7 +399,7 @@ NoRun("error object is a table value", [[lua %s]], prog)
|
||||||
|
|
||||||
|
|
||||||
-- chunk broken in many lines
|
-- chunk broken in many lines
|
||||||
s = [=[ --
|
local s = [=[ --
|
||||||
function f ( x )
|
function f ( x )
|
||||||
local a = [[
|
local a = [[
|
||||||
xuxu
|
xuxu
|
||||||
|
@ -361,12 +421,10 @@ checkprogout("101\n13\t22\n\n")
|
||||||
prepfile[[#comment in 1st line without \n at the end]]
|
prepfile[[#comment in 1st line without \n at the end]]
|
||||||
RUN('lua %s', prog)
|
RUN('lua %s', prog)
|
||||||
|
|
||||||
prepfile[[#test line number when file starts with comment line
|
-- first-line comment with binary file
|
||||||
debug = require"debug"
|
prepfile("#comment\n" .. string.dump(load("print(3)")))
|
||||||
print(debug.getinfo(1).currentline)
|
|
||||||
]]
|
|
||||||
RUN('lua %s > %s', prog, out)
|
RUN('lua %s > %s', prog, out)
|
||||||
checkprogout('3\n')
|
checkout('3\n')
|
||||||
|
|
||||||
-- close Lua with an open file
|
-- close Lua with an open file
|
||||||
prepfile(string.format([[io.output(%q); io.write('alo')]], out))
|
prepfile(string.format([[io.output(%q); io.write('alo')]], out))
|
||||||
|
|
7
third_party/lua/test/math.lua
vendored
7
third_party/lua/test/math.lua
vendored
|
@ -50,7 +50,7 @@ end
|
||||||
local msgf2i = "number.* has no integer representation"
|
local msgf2i = "number.* has no integer representation"
|
||||||
|
|
||||||
-- float equality
|
-- float equality
|
||||||
function eq (a,b,limit)
|
local function eq (a,b,limit)
|
||||||
if not limit then
|
if not limit then
|
||||||
if floatbits >= 50 then limit = 1E-11
|
if floatbits >= 50 then limit = 1E-11
|
||||||
else limit = 1E-5
|
else limit = 1E-5
|
||||||
|
@ -62,7 +62,7 @@ end
|
||||||
|
|
||||||
|
|
||||||
-- equality with types
|
-- equality with types
|
||||||
function eqT (a,b)
|
local function eqT (a,b)
|
||||||
return a == b and math.type(a) == math.type(b)
|
return a == b and math.type(a) == math.type(b)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@ -83,7 +83,7 @@ end
|
||||||
do
|
do
|
||||||
local x = -1
|
local x = -1
|
||||||
local mz = 0/x -- minus zero
|
local mz = 0/x -- minus zero
|
||||||
t = {[0] = 10, 20, 30, 40, 50}
|
local t = {[0] = 10, 20, 30, 40, 50}
|
||||||
assert(t[mz] == t[0] and t[-0] == t[0])
|
assert(t[mz] == t[0] and t[-0] == t[0])
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@ -849,6 +849,7 @@ do
|
||||||
math.randomseed(x, y) -- again should repeat the state
|
math.randomseed(x, y) -- again should repeat the state
|
||||||
assert(math.random(0) == res)
|
assert(math.random(0) == res)
|
||||||
-- keep the random seed for following tests
|
-- keep the random seed for following tests
|
||||||
|
print(string.format("random seeds: %d, %d", x, y))
|
||||||
end
|
end
|
||||||
|
|
||||||
do -- test random for floats
|
do -- test random for floats
|
||||||
|
|
78
third_party/lua/test/nextvar.lua
vendored
78
third_party/lua/test/nextvar.lua
vendored
|
@ -9,6 +9,16 @@ local function checkerror (msg, f, ...)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
||||||
|
local function check (t, na, nh)
|
||||||
|
if not T then return end
|
||||||
|
local a, h = T.querytab(t)
|
||||||
|
if a ~= na or h ~= nh then
|
||||||
|
print(na, nh, a, h)
|
||||||
|
assert(nil)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
|
||||||
local a = {}
|
local a = {}
|
||||||
|
|
||||||
-- make sure table has lots of space in hash part
|
-- make sure table has lots of space in hash part
|
||||||
|
@ -20,6 +30,25 @@ for i=1,100 do
|
||||||
assert(#a == i)
|
assert(#a == i)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
||||||
|
do -- rehash moving elements from array to hash
|
||||||
|
local a = {}
|
||||||
|
for i = 1, 100 do a[i] = i end
|
||||||
|
check(a, 128, 0)
|
||||||
|
|
||||||
|
for i = 5, 95 do a[i] = nil end
|
||||||
|
check(a, 128, 0)
|
||||||
|
|
||||||
|
a.x = 1 -- force a re-hash
|
||||||
|
check(a, 4, 8)
|
||||||
|
|
||||||
|
for i = 1, 4 do assert(a[i] == i) end
|
||||||
|
for i = 5, 95 do assert(a[i] == nil) end
|
||||||
|
for i = 96, 100 do assert(a[i] == i) end
|
||||||
|
assert(a.x == 1)
|
||||||
|
end
|
||||||
|
|
||||||
|
|
||||||
-- testing ipairs
|
-- testing ipairs
|
||||||
local x = 0
|
local x = 0
|
||||||
for k,v in ipairs{10,20,30;x=12} do
|
for k,v in ipairs{10,20,30;x=12} do
|
||||||
|
@ -43,6 +72,14 @@ assert(i == 4)
|
||||||
assert(type(ipairs{}) == 'function' and ipairs{} == ipairs{})
|
assert(type(ipairs{}) == 'function' and ipairs{} == ipairs{})
|
||||||
|
|
||||||
|
|
||||||
|
do -- overflow (must wrap-around)
|
||||||
|
local f = ipairs{}
|
||||||
|
local k, v = f({[math.mininteger] = 10}, math.maxinteger)
|
||||||
|
assert(k == math.mininteger and v == 10)
|
||||||
|
k, v = f({[math.mininteger] = 10}, k)
|
||||||
|
assert(k == nil)
|
||||||
|
end
|
||||||
|
|
||||||
if not T then
|
if not T then
|
||||||
(Message or print)
|
(Message or print)
|
||||||
('\n >>> testC not active: skipping tests for table sizes <<<\n')
|
('\n >>> testC not active: skipping tests for table sizes <<<\n')
|
||||||
|
@ -57,15 +94,6 @@ local function mp2 (n) -- minimum power of 2 >= n
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
||||||
local function check (t, na, nh)
|
|
||||||
local a, h = T.querytab(t)
|
|
||||||
if a ~= na or h ~= nh then
|
|
||||||
print(na, nh, a, h)
|
|
||||||
assert(nil)
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
|
|
||||||
-- testing C library sizes
|
-- testing C library sizes
|
||||||
do
|
do
|
||||||
local s = 0
|
local s = 0
|
||||||
|
@ -161,7 +189,7 @@ end
|
||||||
|
|
||||||
-- size tests for vararg
|
-- size tests for vararg
|
||||||
lim = 35
|
lim = 35
|
||||||
function foo (n, ...)
|
local function foo (n, ...)
|
||||||
local arg = {...}
|
local arg = {...}
|
||||||
check(arg, n, 0)
|
check(arg, n, 0)
|
||||||
assert(select('#', ...) == n)
|
assert(select('#', ...) == n)
|
||||||
|
@ -499,6 +527,15 @@ do -- testing table library with metamethods
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
||||||
|
do -- testing overflow in table.insert (must wrap-around)
|
||||||
|
|
||||||
|
local t = setmetatable({},
|
||||||
|
{__len = function () return math.maxinteger end})
|
||||||
|
table.insert(t, 20)
|
||||||
|
local k, v = next(t)
|
||||||
|
assert(k == math.mininteger and v == 20)
|
||||||
|
end
|
||||||
|
|
||||||
if not T then
|
if not T then
|
||||||
(Message or print)
|
(Message or print)
|
||||||
('\n >>> testC not active: skipping tests for table library on non-tables <<<\n')
|
('\n >>> testC not active: skipping tests for table library on non-tables <<<\n')
|
||||||
|
@ -764,4 +801,25 @@ for k,v in ipairs(a) do
|
||||||
end
|
end
|
||||||
assert(i == a.n)
|
assert(i == a.n)
|
||||||
|
|
||||||
|
|
||||||
|
-- testing yield inside __pairs
|
||||||
|
do
|
||||||
|
local t = setmetatable({10, 20, 30}, {__pairs = function (t)
|
||||||
|
local inc = coroutine.yield()
|
||||||
|
return function (t, i)
|
||||||
|
if i > 1 then return i - inc, t[i - inc] else return nil end
|
||||||
|
end, t, #t + 1
|
||||||
|
end})
|
||||||
|
|
||||||
|
local res = {}
|
||||||
|
local co = coroutine.wrap(function ()
|
||||||
|
for i,p in pairs(t) do res[#res + 1] = p end
|
||||||
|
end)
|
||||||
|
|
||||||
|
co() -- start coroutine
|
||||||
|
co(1) -- continue after yield
|
||||||
|
assert(res[1] == 30 and res[2] == 20 and res[3] == 10 and #res == 3)
|
||||||
|
|
||||||
|
end
|
||||||
|
|
||||||
print"OK"
|
print"OK"
|
||||||
|
|
24
third_party/lua/test/pm.lua
vendored
24
third_party/lua/test/pm.lua
vendored
|
@ -9,12 +9,12 @@ local function checkerror (msg, f, ...)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
||||||
function f(s, p)
|
local function f (s, p)
|
||||||
local i,e = string.find(s, p)
|
local i,e = string.find(s, p)
|
||||||
if i then return string.sub(s, i, e) end
|
if i then return string.sub(s, i, e) end
|
||||||
end
|
end
|
||||||
|
|
||||||
a,b = string.find('', '') -- empty patterns are tricky
|
local a,b = string.find('', '') -- empty patterns are tricky
|
||||||
assert(a == 1 and b == 0);
|
assert(a == 1 and b == 0);
|
||||||
a,b = string.find('alo', '')
|
a,b = string.find('alo', '')
|
||||||
assert(a == 1 and b == 0)
|
assert(a == 1 and b == 0)
|
||||||
|
@ -88,7 +88,7 @@ assert(f("alo alo", "%C+") == "alo alo")
|
||||||
print('+')
|
print('+')
|
||||||
|
|
||||||
|
|
||||||
function f1(s, p)
|
local function f1 (s, p)
|
||||||
p = string.gsub(p, "%%([0-9])", function (s)
|
p = string.gsub(p, "%%([0-9])", function (s)
|
||||||
return "%" .. (tonumber(s)+1)
|
return "%" .. (tonumber(s)+1)
|
||||||
end)
|
end)
|
||||||
|
@ -113,7 +113,7 @@ local abc = string.char(range(0, 127)) .. string.char(range(128, 255));
|
||||||
|
|
||||||
assert(string.len(abc) == 256)
|
assert(string.len(abc) == 256)
|
||||||
|
|
||||||
function strset (p)
|
local function strset (p)
|
||||||
local res = {s=''}
|
local res = {s=''}
|
||||||
string.gsub(abc, p, function (c) res.s = res.s .. c end)
|
string.gsub(abc, p, function (c) res.s = res.s .. c end)
|
||||||
return res.s
|
return res.s
|
||||||
|
@ -147,7 +147,7 @@ assert(string.gsub('
|
||||||
assert(string.gsub('alo úlo ', ' +$', '') == 'alo úlo') -- trim
|
assert(string.gsub('alo úlo ', ' +$', '') == 'alo úlo') -- trim
|
||||||
assert(string.gsub(' alo alo ', '^%s*(.-)%s*$', '%1') == 'alo alo') -- double trim
|
assert(string.gsub(' alo alo ', '^%s*(.-)%s*$', '%1') == 'alo alo') -- double trim
|
||||||
assert(string.gsub('alo alo \n 123\n ', '%s+', ' ') == 'alo alo 123 ')
|
assert(string.gsub('alo alo \n 123\n ', '%s+', ' ') == 'alo alo 123 ')
|
||||||
t = "abç d"
|
local t = "abç d"
|
||||||
a, b = string.gsub(t, '(.)', '%1@')
|
a, b = string.gsub(t, '(.)', '%1@')
|
||||||
assert('@'..a == string.gsub(t, '', '@') and b == 5)
|
assert('@'..a == string.gsub(t, '', '@') and b == 5)
|
||||||
a, b = string.gsub('abçd', '(.)', '%0@', 2)
|
a, b = string.gsub('abçd', '(.)', '%0@', 2)
|
||||||
|
@ -184,6 +184,7 @@ do
|
||||||
local function setglobal (n,v) rawset(_G, n, v) end
|
local function setglobal (n,v) rawset(_G, n, v) end
|
||||||
string.gsub("a=roberto,roberto=a", "(%w+)=(%w%w*)", setglobal)
|
string.gsub("a=roberto,roberto=a", "(%w+)=(%w%w*)", setglobal)
|
||||||
assert(_G.a=="roberto" and _G.roberto=="a")
|
assert(_G.a=="roberto" and _G.roberto=="a")
|
||||||
|
_G.a = nil; _G.roberto = nil
|
||||||
end
|
end
|
||||||
|
|
||||||
function f(a,b) return string.gsub(a,'.',b) end
|
function f(a,b) return string.gsub(a,'.',b) end
|
||||||
|
@ -195,20 +196,21 @@ assert(string.gsub("alo $a='x'$ novamente $return a$",
|
||||||
"$([^$]*)%$",
|
"$([^$]*)%$",
|
||||||
dostring) == "alo novamente x")
|
dostring) == "alo novamente x")
|
||||||
|
|
||||||
x = string.gsub("$x=string.gsub('alo', '.', string.upper)$ assim vai para $return x$",
|
local x = string.gsub("$x=string.gsub('alo', '.', string.upper)$ assim vai para $return x$",
|
||||||
"$([^$]*)%$", dostring)
|
"$([^$]*)%$", dostring)
|
||||||
assert(x == ' assim vai para ALO')
|
assert(x == ' assim vai para ALO')
|
||||||
|
_G.a, _G.x = nil
|
||||||
|
|
||||||
t = {}
|
local t = {}
|
||||||
s = 'a alo jose joao'
|
local s = 'a alo jose joao'
|
||||||
r = string.gsub(s, '()(%w+)()', function (a,w,b)
|
local r = string.gsub(s, '()(%w+)()', function (a,w,b)
|
||||||
assert(string.len(w) == b-a);
|
assert(string.len(w) == b-a);
|
||||||
t[a] = b-a;
|
t[a] = b-a;
|
||||||
end)
|
end)
|
||||||
assert(s == r and t[1] == 1 and t[3] == 3 and t[7] == 4 and t[13] == 4)
|
assert(s == r and t[1] == 1 and t[3] == 3 and t[7] == 4 and t[13] == 4)
|
||||||
|
|
||||||
|
|
||||||
function isbalanced (s)
|
local function isbalanced (s)
|
||||||
return not string.find(string.gsub(s, "%b()", ""), "[()]")
|
return not string.find(string.gsub(s, "%b()", ""), "[()]")
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@ -251,7 +253,7 @@ if not _soft then
|
||||||
end
|
end
|
||||||
|
|
||||||
-- recursive nest of gsubs
|
-- recursive nest of gsubs
|
||||||
function rev (s)
|
local function rev (s)
|
||||||
return string.gsub(s, "(.)(.+)", function (c,s1) return rev(s1)..c end)
|
return string.gsub(s, "(.)(.+)", function (c,s1) return rev(s1)..c end)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
23
third_party/lua/test/sort.lua
vendored
23
third_party/lua/test/sort.lua
vendored
|
@ -20,7 +20,7 @@ end
|
||||||
checkerror("wrong number of arguments", table.insert, {}, 2, 3, 4)
|
checkerror("wrong number of arguments", table.insert, {}, 2, 3, 4)
|
||||||
|
|
||||||
local x,y,z,a,n
|
local x,y,z,a,n
|
||||||
a = {}; lim = _soft and 200 or 2000
|
a = {}; local lim = _soft and 200 or 2000
|
||||||
for i=1, lim do a[i]=i end
|
for i=1, lim do a[i]=i end
|
||||||
assert(select(lim, unpack(a)) == lim and select('#', unpack(a)) == lim)
|
assert(select(lim, unpack(a)) == lim and select('#', unpack(a)) == lim)
|
||||||
x = unpack(a)
|
x = unpack(a)
|
||||||
|
@ -222,7 +222,7 @@ a = {"Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep",
|
||||||
table.sort(a)
|
table.sort(a)
|
||||||
check(a)
|
check(a)
|
||||||
|
|
||||||
function perm (s, n)
|
local function perm (s, n)
|
||||||
n = n or #s
|
n = n or #s
|
||||||
if n == 1 then
|
if n == 1 then
|
||||||
local t = {unpack(s)}
|
local t = {unpack(s)}
|
||||||
|
@ -248,7 +248,7 @@ perm{1,2,3,3,5}
|
||||||
perm{1,2,3,4,5,6}
|
perm{1,2,3,4,5,6}
|
||||||
perm{2,2,3,3,5,6}
|
perm{2,2,3,3,5,6}
|
||||||
|
|
||||||
function timesort (a, n, func, msg, pre)
|
local function timesort (a, n, func, msg, pre)
|
||||||
local x = os.clock()
|
local x = os.clock()
|
||||||
table.sort(a, func)
|
table.sort(a, func)
|
||||||
x = (os.clock() - x) * 1000
|
x = (os.clock() - x) * 1000
|
||||||
|
@ -257,7 +257,7 @@ function timesort (a, n, func, msg, pre)
|
||||||
check(a, func)
|
check(a, func)
|
||||||
end
|
end
|
||||||
|
|
||||||
limit = 50000
|
local limit = 50000
|
||||||
if _soft then limit = 5000 end
|
if _soft then limit = 5000 end
|
||||||
|
|
||||||
a = {}
|
a = {}
|
||||||
|
@ -274,7 +274,7 @@ for i=1,limit do
|
||||||
a[i] = math.random()
|
a[i] = math.random()
|
||||||
end
|
end
|
||||||
|
|
||||||
x = os.clock(); i=0
|
local x = os.clock(); local i = 0
|
||||||
table.sort(a, function(x,y) i=i+1; return y<x end)
|
table.sort(a, function(x,y) i=i+1; return y<x end)
|
||||||
x = (os.clock() - x) * 1000
|
x = (os.clock() - x) * 1000
|
||||||
print(string.format("Invert-sorting other %d elements in %.2f msec., with %i comparisons",
|
print(string.format("Invert-sorting other %d elements in %.2f msec., with %i comparisons",
|
||||||
|
@ -289,18 +289,19 @@ timesort(a, limit, function(x,y) return nil end, "equal")
|
||||||
|
|
||||||
for i,v in pairs(a) do assert(v == false) end
|
for i,v in pairs(a) do assert(v == false) end
|
||||||
|
|
||||||
A = {"álo", "\0first :-)", "alo", "then this one", "45", "and a new"}
|
AA = {"álo", "\0first :-)", "alo", "then this one", "45", "and a new"}
|
||||||
table.sort(A)
|
table.sort(AA)
|
||||||
check(A)
|
check(AA)
|
||||||
|
|
||||||
table.sort(A, function (x, y)
|
table.sort(AA, function (x, y)
|
||||||
load(string.format("A[%q] = ''", x), "")()
|
load(string.format("AA[%q] = ''", x), "")()
|
||||||
collectgarbage()
|
collectgarbage()
|
||||||
return x<y
|
return x<y
|
||||||
end)
|
end)
|
||||||
|
|
||||||
|
_G.AA = nil
|
||||||
|
|
||||||
tt = {__lt = function (a,b) return a.val < b.val end}
|
local tt = {__lt = function (a,b) return a.val < b.val end}
|
||||||
a = {}
|
a = {}
|
||||||
for i=1,10 do a[i] = {val=math.random(100)}; setmetatable(a[i], tt); end
|
for i=1,10 do a[i] = {val=math.random(100)}; setmetatable(a[i], tt); end
|
||||||
table.sort(a)
|
table.sort(a)
|
||||||
|
|
47
third_party/lua/test/strings.lua
vendored
47
third_party/lua/test/strings.lua
vendored
|
@ -52,7 +52,7 @@ assert(("\000123456789"):sub(8) == "789")
|
||||||
|
|
||||||
-- testing string.find
|
-- testing string.find
|
||||||
assert(string.find("123456789", "345") == 3)
|
assert(string.find("123456789", "345") == 3)
|
||||||
a,b = string.find("123456789", "345")
|
local a,b = string.find("123456789", "345")
|
||||||
assert(string.sub("123456789", a, b) == "345")
|
assert(string.sub("123456789", a, b) == "345")
|
||||||
assert(string.find("1234567890123456789", "345", 3) == 3)
|
assert(string.find("1234567890123456789", "345", 3) == 3)
|
||||||
assert(string.find("1234567890123456789", "345", 4) == 13)
|
assert(string.find("1234567890123456789", "345", 4) == 13)
|
||||||
|
@ -192,7 +192,7 @@ do -- tests for '%p' format
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
x = '"ílo"\n\\'
|
local x = '"ílo"\n\\'
|
||||||
assert(string.format('%q%s', x, x) == '"\\"ílo\\"\\\n\\\\""ílo"\n\\')
|
assert(string.format('%q%s', x, x) == '"\\"ílo\\"\\\n\\\\""ílo"\n\\')
|
||||||
assert(string.format('%q', "\0") == [["\0"]])
|
assert(string.format('%q', "\0") == [["\0"]])
|
||||||
assert(load(string.format('return %q', x))() == x)
|
assert(load(string.format('return %q', x))() == x)
|
||||||
|
@ -202,13 +202,11 @@ assert(string.format("\0%c\0%c%x\0", string.byte("\xe4"), string.byte("b"), 140)
|
||||||
"\0\xe4\0b8c\0")
|
"\0\xe4\0b8c\0")
|
||||||
assert(string.format('') == "")
|
assert(string.format('') == "")
|
||||||
assert(string.format("%c",34)..string.format("%c",48)..string.format("%c",90)..string.format("%c",100) ==
|
assert(string.format("%c",34)..string.format("%c",48)..string.format("%c",90)..string.format("%c",100) ==
|
||||||
string.format("%c%c%c%c", 34, 48, 90, 100))
|
string.format("%1c%-c%-1c%c", 34, 48, 90, 100))
|
||||||
assert(string.format("%s\0 is not \0%s", 'not be', 'be') == 'not be\0 is not \0be')
|
assert(string.format("%s\0 is not \0%s", 'not be', 'be') == 'not be\0 is not \0be')
|
||||||
assert(string.format("%%%d %010d", 10, 23) == "%10 0000000023")
|
assert(string.format("%%%d %010d", 10, 23) == "%10 0000000023")
|
||||||
assert(tonumber(string.format("%f", 10.3)) == 10.3)
|
assert(tonumber(string.format("%f", 10.3)) == 10.3)
|
||||||
x = string.format('"%-50s"', 'a')
|
assert(string.format('"%-50s"', 'a') == '"a' .. string.rep(' ', 49) .. '"')
|
||||||
assert(#x == 52)
|
|
||||||
assert(string.sub(x, 1, 4) == '"a ')
|
|
||||||
|
|
||||||
assert(string.format("-%.20s.20s", string.rep("%", 2000)) ==
|
assert(string.format("-%.20s.20s", string.rep("%", 2000)) ==
|
||||||
"-"..string.rep("%", 20)..".20s")
|
"-"..string.rep("%", 20)..".20s")
|
||||||
|
@ -237,7 +235,6 @@ end
|
||||||
|
|
||||||
assert(string.format("\0%s\0", "\0\0\1") == "\0\0\0\1\0")
|
assert(string.format("\0%s\0", "\0\0\1") == "\0\0\0\1\0")
|
||||||
checkerror("contains zeros", string.format, "%10s", "\0")
|
checkerror("contains zeros", string.format, "%10s", "\0")
|
||||||
checkerror("cannot have modifiers", string.format, "%10q", "1")
|
|
||||||
|
|
||||||
-- format x tostring
|
-- format x tostring
|
||||||
assert(string.format("%s %s", nil, true) == "nil true")
|
assert(string.format("%s %s", nil, true) == "nil true")
|
||||||
|
@ -341,6 +338,26 @@ do print("testing 'format %a %A'")
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
||||||
|
-- testing some flags (all these results are required by ISO C)
|
||||||
|
assert(string.format("%#12o", 10) == " 012")
|
||||||
|
assert(string.format("%#10x", 100) == " 0x64")
|
||||||
|
assert(string.format("%#-17X", 100) == "0X64 ")
|
||||||
|
assert(string.format("%013i", -100) == "-000000000100")
|
||||||
|
assert(string.format("%2.5d", -100) == "-00100")
|
||||||
|
assert(string.format("%.u", 0) == "")
|
||||||
|
assert(string.format("%+#014.0f", 100) == "+000000000100.")
|
||||||
|
assert(string.format("%-16c", 97) == "a ")
|
||||||
|
assert(string.format("%+.3G", 1.5) == "+1.5")
|
||||||
|
assert(string.format("%.0s", "alo") == "")
|
||||||
|
assert(string.format("%.s", "alo") == "")
|
||||||
|
|
||||||
|
-- ISO C89 says that "The exponent always contains at least two digits",
|
||||||
|
-- but unlike ISO C99 it does not ensure that it contains "only as many
|
||||||
|
-- more digits as necessary".
|
||||||
|
assert(string.match(string.format("% 1.0E", 100), "^ 1E%+0+2$"))
|
||||||
|
assert(string.match(string.format("% .1g", 2^10), "^ 1e%+0+3$"))
|
||||||
|
|
||||||
|
|
||||||
-- errors in format
|
-- errors in format
|
||||||
|
|
||||||
local function check (fmt, msg)
|
local function check (fmt, msg)
|
||||||
|
@ -348,13 +365,21 @@ local function check (fmt, msg)
|
||||||
end
|
end
|
||||||
|
|
||||||
local aux = string.rep('0', 600)
|
local aux = string.rep('0', 600)
|
||||||
check("%100.3d", "too long")
|
check("%100.3d", "invalid conversion")
|
||||||
check("%1"..aux..".3d", "too long")
|
check("%1"..aux..".3d", "too long")
|
||||||
check("%1.100d", "too long")
|
check("%1.100d", "invalid conversion")
|
||||||
check("%10.1"..aux.."004d", "too long")
|
check("%10.1"..aux.."004d", "too long")
|
||||||
check("%t", "invalid conversion")
|
check("%t", "invalid conversion")
|
||||||
check("%"..aux.."d", "repeated flags")
|
check("%"..aux.."d", "too long")
|
||||||
check("%d %d", "no value")
|
check("%d %d", "no value")
|
||||||
|
check("%010c", "invalid conversion")
|
||||||
|
check("%.10c", "invalid conversion")
|
||||||
|
check("%0.34s", "invalid conversion")
|
||||||
|
check("%#i", "invalid conversion")
|
||||||
|
check("%3.1p", "invalid conversion")
|
||||||
|
check("%0.s", "invalid conversion")
|
||||||
|
check("%10q", "cannot have modifiers")
|
||||||
|
check("%F", "invalid conversion") -- useless and not in C89
|
||||||
|
|
||||||
|
|
||||||
assert(load("return 1\n--comment without ending EOL")() == 1)
|
assert(load("return 1\n--comment without ending EOL")() == 1)
|
||||||
|
@ -427,7 +452,7 @@ end
|
||||||
do
|
do
|
||||||
local f = string.gmatch("1 2 3 4 5", "%d+")
|
local f = string.gmatch("1 2 3 4 5", "%d+")
|
||||||
assert(f() == "1")
|
assert(f() == "1")
|
||||||
co = coroutine.wrap(f)
|
local co = coroutine.wrap(f)
|
||||||
assert(co() == "2")
|
assert(co() == "2")
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
2
third_party/lua/test/tpack.lua
vendored
2
third_party/lua/test/tpack.lua
vendored
|
@ -35,7 +35,7 @@ print("\talignment: " .. align)
|
||||||
|
|
||||||
|
|
||||||
-- check errors in arguments
|
-- check errors in arguments
|
||||||
function checkerror (msg, f, ...)
|
local function checkerror (msg, f, ...)
|
||||||
local status, err = pcall(f, ...)
|
local status, err = pcall(f, ...)
|
||||||
-- print(status, err, msg)
|
-- print(status, err, msg)
|
||||||
assert(not status and string.find(err, msg))
|
assert(not status and string.find(err, msg))
|
||||||
|
|
20
third_party/lua/test/utf8.lua
vendored
20
third_party/lua/test/utf8.lua
vendored
|
@ -97,9 +97,15 @@ do -- error indication in utf8.len
|
||||||
assert(not a and b == p)
|
assert(not a and b == p)
|
||||||
end
|
end
|
||||||
check("abc\xE3def", 4)
|
check("abc\xE3def", 4)
|
||||||
check("汉字\x80", #("汉字") + 1)
|
|
||||||
check("\xF4\x9F\xBF", 1)
|
check("\xF4\x9F\xBF", 1)
|
||||||
check("\xF4\x9F\xBF\xBF", 1)
|
check("\xF4\x9F\xBF\xBF", 1)
|
||||||
|
-- spurious continuation bytes
|
||||||
|
check("汉字\x80", #("汉字") + 1)
|
||||||
|
check("\x80hello", 1)
|
||||||
|
check("hel\x80lo", 4)
|
||||||
|
check("汉字\xBF", #("汉字") + 1)
|
||||||
|
check("\xBFhello", 1)
|
||||||
|
check("hel\xBFlo", 4)
|
||||||
end
|
end
|
||||||
|
|
||||||
-- errors in utf8.codes
|
-- errors in utf8.codes
|
||||||
|
@ -112,6 +118,16 @@ do
|
||||||
end
|
end
|
||||||
errorcodes("ab\xff")
|
errorcodes("ab\xff")
|
||||||
errorcodes("\u{110000}")
|
errorcodes("\u{110000}")
|
||||||
|
errorcodes("in\x80valid")
|
||||||
|
errorcodes("\xbfinvalid")
|
||||||
|
errorcodes("αλφ\xBFα")
|
||||||
|
|
||||||
|
-- calling interation function with invalid arguments
|
||||||
|
local f = utf8.codes("")
|
||||||
|
assert(f("", 2) == nil)
|
||||||
|
assert(f("", -1) == nil)
|
||||||
|
assert(f("", math.mininteger) == nil)
|
||||||
|
|
||||||
end
|
end
|
||||||
|
|
||||||
-- error in initial position for offset
|
-- error in initial position for offset
|
||||||
|
@ -214,7 +230,7 @@ do
|
||||||
check(s, {0x10000, 0x1FFFFF}, true)
|
check(s, {0x10000, 0x1FFFFF}, true)
|
||||||
end
|
end
|
||||||
|
|
||||||
x = "日本語a-4\0éó"
|
local x = "日本語a-4\0éó"
|
||||||
check(x, {26085, 26412, 35486, 97, 45, 52, 0, 233, 243})
|
check(x, {26085, 26412, 35486, 97, 45, 52, 0, 233, 243})
|
||||||
|
|
||||||
|
|
||||||
|
|
18
third_party/lua/test/vararg.lua
vendored
18
third_party/lua/test/vararg.lua
vendored
|
@ -3,13 +3,13 @@
|
||||||
|
|
||||||
print('testing vararg')
|
print('testing vararg')
|
||||||
|
|
||||||
function f(a, ...)
|
local function f (a, ...)
|
||||||
local x = {n = select('#', ...), ...}
|
local x = {n = select('#', ...), ...}
|
||||||
for i = 1, x.n do assert(a[i] == x[i]) end
|
for i = 1, x.n do assert(a[i] == x[i]) end
|
||||||
return x.n
|
return x.n
|
||||||
end
|
end
|
||||||
|
|
||||||
function c12 (...)
|
local function c12 (...)
|
||||||
assert(arg == _G.arg) -- no local 'arg'
|
assert(arg == _G.arg) -- no local 'arg'
|
||||||
local x = {...}; x.n = #x
|
local x = {...}; x.n = #x
|
||||||
local res = (x.n==2 and x[1] == 1 and x[2] == 2)
|
local res = (x.n==2 and x[1] == 1 and x[2] == 2)
|
||||||
|
@ -17,7 +17,7 @@ function c12 (...)
|
||||||
return res, 2
|
return res, 2
|
||||||
end
|
end
|
||||||
|
|
||||||
function vararg (...) return {n = select('#', ...), ...} end
|
local function vararg (...) return {n = select('#', ...), ...} end
|
||||||
|
|
||||||
local call = function (f, args) return f(table.unpack(args, 1, args.n)) end
|
local call = function (f, args) return f(table.unpack(args, 1, args.n)) end
|
||||||
|
|
||||||
|
@ -29,7 +29,7 @@ assert(vararg().n == 0)
|
||||||
assert(vararg(nil, nil).n == 2)
|
assert(vararg(nil, nil).n == 2)
|
||||||
|
|
||||||
assert(c12(1,2)==55)
|
assert(c12(1,2)==55)
|
||||||
a,b = assert(call(c12, {1,2}))
|
local a,b = assert(call(c12, {1,2}))
|
||||||
assert(a == 55 and b == 2)
|
assert(a == 55 and b == 2)
|
||||||
a = call(c12, {1,2;n=2})
|
a = call(c12, {1,2;n=2})
|
||||||
assert(a == 55 and b == 2)
|
assert(a == 55 and b == 2)
|
||||||
|
@ -49,7 +49,7 @@ function t:f (...) local arg = {...}; return self[...]+#arg end
|
||||||
assert(t:f(1,4) == 3 and t:f(2) == 11)
|
assert(t:f(1,4) == 3 and t:f(2) == 11)
|
||||||
print('+')
|
print('+')
|
||||||
|
|
||||||
lim = 20
|
local lim = 20
|
||||||
local i, a = 1, {}
|
local i, a = 1, {}
|
||||||
while i <= lim do a[i] = i+0.3; i=i+1 end
|
while i <= lim do a[i] = i+0.3; i=i+1 end
|
||||||
|
|
||||||
|
@ -59,7 +59,7 @@ function f(a, b, c, d, ...)
|
||||||
more[lim-4] == lim+0.3 and not more[lim-3])
|
more[lim-4] == lim+0.3 and not more[lim-3])
|
||||||
end
|
end
|
||||||
|
|
||||||
function g(a,b,c)
|
local function g (a,b,c)
|
||||||
assert(a == 1.3 and b == 2.3 and c == 3.3)
|
assert(a == 1.3 and b == 2.3 and c == 3.3)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@ -76,7 +76,7 @@ print("+")
|
||||||
|
|
||||||
-- new-style varargs
|
-- new-style varargs
|
||||||
|
|
||||||
function oneless (a, ...) return ... end
|
local function oneless (a, ...) return ... end
|
||||||
|
|
||||||
function f (n, a, ...)
|
function f (n, a, ...)
|
||||||
local b
|
local b
|
||||||
|
@ -99,8 +99,8 @@ assert(a==nil and b==nil and c==nil and d==nil and e==nil)
|
||||||
|
|
||||||
|
|
||||||
-- varargs for main chunks
|
-- varargs for main chunks
|
||||||
f = load[[ return {...} ]]
|
local f = load[[ return {...} ]]
|
||||||
x = f(2,3)
|
local x = f(2,3)
|
||||||
assert(x[1] == 2 and x[2] == 3 and x[3] == undef)
|
assert(x[1] == 2 and x[2] == 3 and x[3] == undef)
|
||||||
|
|
||||||
|
|
||||||
|
|
12
third_party/lua/test/verybig.lua
vendored
12
third_party/lua/test/verybig.lua
vendored
|
@ -52,7 +52,7 @@ if _soft then return 10 end
|
||||||
print "testing large programs (>64k)"
|
print "testing large programs (>64k)"
|
||||||
|
|
||||||
-- template to create a very big test file
|
-- template to create a very big test file
|
||||||
prog = [[$
|
local prog = [[$
|
||||||
|
|
||||||
local a,b
|
local a,b
|
||||||
|
|
||||||
|
@ -85,7 +85,7 @@ function b:xxx (a,b) return a+b end
|
||||||
assert(b:xxx(10, 12) == 22) -- pushself with non-constant index
|
assert(b:xxx(10, 12) == 22) -- pushself with non-constant index
|
||||||
b["xxx"] = undef
|
b["xxx"] = undef
|
||||||
|
|
||||||
s = 0; n=0
|
local s = 0; local n=0
|
||||||
for a,b in pairs(b) do s=s+b; n=n+1 end
|
for a,b in pairs(b) do s=s+b; n=n+1 end
|
||||||
-- with 32-bit floats, exact value of 's' depends on summation order
|
-- with 32-bit floats, exact value of 's' depends on summation order
|
||||||
assert(81800000.0 < s and s < 81860000 and n == 70001)
|
assert(81800000.0 < s and s < 81860000 and n == 70001)
|
||||||
|
@ -93,7 +93,7 @@ assert(81800000.0 < s and s < 81860000 and n == 70001)
|
||||||
a = nil; b = nil
|
a = nil; b = nil
|
||||||
print'+'
|
print'+'
|
||||||
|
|
||||||
function f(x) b=x end
|
local function f(x) b=x end
|
||||||
|
|
||||||
a = f{$3$} or 10
|
a = f{$3$} or 10
|
||||||
|
|
||||||
|
@ -118,7 +118,7 @@ local function sig (x)
|
||||||
return (x % 2 == 0) and '' or '-'
|
return (x % 2 == 0) and '' or '-'
|
||||||
end
|
end
|
||||||
|
|
||||||
F = {
|
local F = {
|
||||||
function () -- $1$
|
function () -- $1$
|
||||||
for i=10,50009 do
|
for i=10,50009 do
|
||||||
io.write('a', i, ' = ', sig(i), 5+((i-10)/2), ',\n')
|
io.write('a', i, ' = ', sig(i), 5+((i-10)/2), ',\n')
|
||||||
|
@ -138,14 +138,14 @@ function () -- $3$
|
||||||
end,
|
end,
|
||||||
}
|
}
|
||||||
|
|
||||||
file = os.tmpname()
|
local file = os.tmpname()
|
||||||
io.output(file)
|
io.output(file)
|
||||||
for s in string.gmatch(prog, "$([^$]+)") do
|
for s in string.gmatch(prog, "$([^$]+)") do
|
||||||
local n = tonumber(s)
|
local n = tonumber(s)
|
||||||
if not n then io.write(s) else F[n]() end
|
if not n then io.write(s) else F[n]() end
|
||||||
end
|
end
|
||||||
io.close()
|
io.close()
|
||||||
result = dofile(file)
|
local result = dofile(file)
|
||||||
assert(os.remove(file))
|
assert(os.remove(file))
|
||||||
print'OK'
|
print'OK'
|
||||||
return result
|
return result
|
||||||
|
|
Loading…
Reference in a new issue