Merge lp:~widelands-dev/widelands/bug-1543001-eris into lp:widelands

Proposed by GunChleoc
Status: Merged
Merged at revision: 7954
Proposed branch: lp:~widelands-dev/widelands/bug-1543001-eris
Merge into: lp:widelands
Diff against target: 20384 lines (+8124/-4571)
75 files modified
src/logic/cmd_luacoroutine.cc (+4/-2)
src/logic/map_objects/tribes/soldier.cc (+2/-2)
src/logic/map_objects/tribes/worker.cc (+1/-1)
src/map_io/map_scripting_packet.cc (+1/-1)
src/scripting/logic.cc (+3/-3)
src/scripting/lua.h (+2/-0)
src/scripting/lua_coroutine.cc (+2/-2)
src/scripting/lua_globals.cc (+4/-7)
src/scripting/lua_map.cc (+19/-19)
src/scripting/lua_ui.cc (+4/-4)
src/third_party/CMakeLists.txt (+4/-0)
src/third_party/eris/README.eris (+2/-2)
src/third_party/eris/eris.c (+337/-209)
src/third_party/eris/eris.h (+7/-2)
src/third_party/eris/lapi.c (+277/-291)
src/third_party/eris/lapi.h (+3/-3)
src/third_party/eris/lauxlib.c (+167/-154)
src/third_party/eris/lauxlib.h (+69/-25)
src/third_party/eris/lbaselib.c (+194/-119)
src/third_party/eris/lbitlib.c (+49/-31)
src/third_party/eris/lcode.c (+151/-78)
src/third_party/eris/lcode.h (+8/-4)
src/third_party/eris/lcorolib.c (+23/-10)
src/third_party/eris/lctype.c (+4/-1)
src/third_party/eris/lctype.h (+1/-1)
src/third_party/eris/ldblib.c (+126/-87)
src/third_party/eris/ldebug.c (+109/-59)
src/third_party/eris/ldebug.h (+10/-4)
src/third_party/eris/ldo.c (+116/-80)
src/third_party/eris/ldo.h (+2/-2)
src/third_party/eris/ldump.c (+192/-151)
src/third_party/eris/lfunc.c (+61/-71)
src/third_party/eris/lfunc.h (+26/-5)
src/third_party/eris/lgc.c (+425/-486)
src/third_party/eris/lgc.h (+43/-62)
src/third_party/eris/linit.c (+22/-21)
src/third_party/eris/liolib.c (+195/-104)
src/third_party/eris/llex.c (+178/-106)
src/third_party/eris/llex.h (+12/-4)
src/third_party/eris/llimits.h (+80/-147)
src/third_party/eris/lmathlib.c (+236/-111)
src/third_party/eris/lmem.c (+13/-13)
src/third_party/eris/lmem.h (+21/-9)
src/third_party/eris/loadlib.c (+163/-102)
src/third_party/eris/lobject.c (+245/-62)
src/third_party/eris/lobject.h (+147/-214)
src/third_party/eris/lopcodes.c (+21/-4)
src/third_party/eris/lopcodes.h (+23/-16)
src/third_party/eris/loslib.c (+69/-36)
src/third_party/eris/lparser.c (+95/-86)
src/third_party/eris/lparser.h (+14/-13)
src/third_party/eris/lprefix.h (+45/-0)
src/third_party/eris/lstate.c (+60/-37)
src/third_party/eris/lstate.h (+73/-78)
src/third_party/eris/lstring.c (+68/-71)
src/third_party/eris/lstring.h (+9/-9)
src/third_party/eris/lstrlib.c (+526/-115)
src/third_party/eris/ltable.c (+202/-140)
src/third_party/eris/ltable.h (+14/-6)
src/third_party/eris/ltablib.c (+155/-81)
src/third_party/eris/ltm.c (+76/-10)
src/third_party/eris/ltm.h (+23/-5)
src/third_party/eris/lua.c (+611/-0)
src/third_party/eris/lua.h (+105/-64)
src/third_party/eris/luac.c (+449/-0)
src/third_party/eris/luaconf.h (+496/-312)
src/third_party/eris/lualib.h (+4/-2)
src/third_party/eris/lundump.c (+251/-232)
src/third_party/eris/lundump.h (+17/-12)
src/third_party/eris/lutf8lib.c (+255/-0)
src/third_party/eris/lvm.c (+659/-344)
src/third_party/eris/lvm.h (+32/-18)
src/third_party/eris/lzio.c (+6/-4)
src/third_party/eris/lzio.h (+6/-4)
test/maps/lua_testsuite.wmf/scripting/string_bformat.lua (+0/-1)
To merge this branch: bzr merge lp:~widelands-dev/widelands/bug-1543001-eris
Reviewer Review Type Date Requested Status
Miroslav Remák code Approve
kaputtnik (community) testing Approve
GunChleoc Needs Resubmitting
Review via email: mp+291294@code.launchpad.net

Commit message

Updated Eris to version 1.1.0.

Description of the change

I just dumped the files and updated the readme. As long as we don't change to a newer Lua version, savegames should be compatible. I did a quick test with my long Trident of Fire savegame, and it loaded with no issues.

To post a comment you must log in.
Revision history for this message
Miroslav Remák (miroslavr256) wrote :

We're going to break savegame compatibility for this release anyway. What's holding us from updating to Lua 5.3 eris?

Revision history for this message
GunChleoc (gunchleoc) wrote :

The highest Lua version available on my system is 5.2. Ubuntu introduced Lua with version 15.04, but I usually only use long term releases, which means that I will have to wait until 16.04 comes out in order to switch to Lua 5.3.

Revision history for this message
SirVer (sirver) wrote :

I think Eris is lua 5.3 - Eris bundles all of lua with it since it needs the private headers for serialization. So by updating Eris, we switch to lua 5.3.

This is from my memory. I cannot check right now, but it should be documented on the GitHub project page or the commit history of Eris.

> Am 08.04.2016 um 07:54 schrieb GunChleoc <email address hidden>:
>
> The highest Lua version available on my system is 5.2. Ubuntu introduced Lua with version 15.04, but I usually only use long term releases, which means that I will have to wait until 16.04 comes out in order to switch to Lua 5.3.
> --
> https://code.launchpad.net/~widelands-dev/widelands/bug-1543001-eris/+merge/291294
> Your team Widelands Developers is requested to review the proposed merge of lp:~widelands-dev/widelands/bug-1543001-eris into lp:widelands.
>
> _______________________________________________
> Mailing list: https://launchpad.net/~widelands-dev
> Post to : <email address hidden>
> Unsubscribe : https://launchpad.net/~widelands-dev
> More help : https://help.launchpad.net/ListHelp

Revision history for this message
Miroslav Remák (miroslavr256) wrote :

SirVer is correct. Here's an explanation:
https://github.com/fnuecke/eris/tree/master-lua5.3#core-library

You don't need to have Lua installed on your system at all.

Revision history for this message
bunnybot (widelandsofficial) wrote :

Continuous integration builds have changed state:

Travis build 984. State: failed. Details: https://travis-ci.org/widelands/widelands/builds/121502471.
Appveyor build 817. State: success. Details: https://ci.appveyor.com/project/widelands-dev/widelands/build/_widelands_dev_widelands_bug_1543001_eris-817.

Revision history for this message
Klaus Halfmann (klaus-halfmann) wrote :

On OSX (with macports) I have 'lua @5.3.1_2 (lang)'. hope this helps

Revision history for this message
GunChleoc (gunchleoc) wrote :

OK, I'll try the Lua 5.3 version then to see if it will run on my system :)

Revision history for this message
GunChleoc (gunchleoc) wrote :

Seems to be working - I could even load some savegames, so I haven't upgraded any packet numbers.

Revision history for this message
Miroslav Remák (miroslavr256) wrote :

Tutorials and campaigns seem to be crashing:

Error in Lua Coroutine
[/home/miroslavr/Games/widelands/src/scripting/lua_errors.cc:22] [string "scripting/ui.lua"]:102: bad argument #-1 to '__newindex' (number has no integer representation)
Send message to all players and pause gameFatal exception: [/home/miroslavr/Games/widelands/src/graphic/image_io.h:35] Image not found: Coroutine
Game: Writing Preload Data ... The program has unexpectedly finished.
/home/miroslavr/Games/widelands/build/src/widelands crashed

Revision history for this message
Miroslav Remák (miroslavr256) wrote :

Besides the obvious error in Lua coroutine, there seems to be another issue with the message that is supposed to show up, which ultimately leads to a crash. This message (in CmdLuaCoroutine::execute) is constructed with icon and title parameters swapped.

Revision history for this message
Miroslav Remák (miroslavr256) wrote :

Regarding the "number has no integer representation" error: Since Lua 5.3 added integer support, luaL_checkinteger does not seem to accept floating-point numbers anymore. We need to make sure to pass integers from Lua where required.

These changes seem to do the trick:

=== modified file 'data/scripting/ui.lua'
--- data/scripting/ui.lua 2016-01-28 05:24:34 +0000
+++ data/scripting/ui.lua 2016-04-09 01:25:31 +0000
@@ -99,8 +99,8 @@
    wl.Game().desired_speed = 1000

    for idx,p in ipairs(points) do
- mv.viewpoint_x = p.x
- mv.viewpoint_y = p.y
+ mv.viewpoint_x = math.floor(p.x)
+ mv.viewpoint_y = math.floor(p.y)

       sleep(dt)
    end
@@ -196,8 +196,8 @@
    wl.Game().desired_speed = 1000

    for idx,p in ipairs(points) do
- mv.mouse_position_x = p.x
- mv.mouse_position_y = p.y
+ mv.mouse_position_x = math.floor(p.x)
+ mv.mouse_position_y = math.floor(p.y)

       sleep(dt)
    end

Revision history for this message
GunChleoc (gunchleoc) wrote :

I can't reproduce the crash. Where were you exactly when it happened? What is your screen resolution?

Revision history for this message
Miroslav Remák (miroslavr256) wrote :

My in-game resolution is 1024x768, 60 fps. It happens anytime the view or mouse pointer moves automatically (see diff). For example, the first tutorial mission errors just after activating build spaces.

Can you try running 'wl.ui.MapView().viewpoint_x = 2.5' via the script console to see if you can reproduce it at all?

Revision history for this message
Miroslav Remák (miroslavr256) wrote :

Also, what does 'print(_VERSION)' output on your end? It should be 'Lua+Eris 5.3'.

Revision history for this message
kaputtnik (franku) wrote :

I just get a crash in Economy tutorial. The crash happens after clicking the "OK" button of first text screen:

Error in Lua Coroutine
[/home/kaputtnik/Quellcode/widelands-repo/bug-1543001-eris/src/scripting/lua_errors.cc:22] [string "scripting/ui.lua"]:102: bad argument #-1 to '__newindex' (number has no integer representation)
Send message to all players and pause gameFatal exception: [/home/kaputtnik/Quellcode/widelands-repo/bug-1543001-eris/src/graphic/image_io.h:35] Image not found: Coroutine
Game: Writing Preload Data ... Speicherzugriffsfehler (Speicherabzug geschrieben

The same crash happens when playing the warefare tutorial after the Citadel has been build.

Revision history for this message
kaputtnik (franku) wrote :

Another crash with a savegame saved with current trunk:

Reading Scripting Data ... PANIC: unprotected error in call to Lua API (incompatible integer type)

I attach the savegame to the bug.

Revision history for this message
Miroslav Remák (miroslavr256) wrote :

@kaputtnik: You won't be able to load older savegames because the save format of Eris is not compatible. I'm not sure if we can catch the error and display a message box instead of aborting, though.

Revision history for this message
kaputtnik (franku) wrote :

I just mentioned this because GunChleoc says:

> I could even load some savegames, so I haven't upgraded any packet numbers.

If the packet numbers are upgraded a message box is displayed automatically when trying to load an incompatible save game :-)

review: Needs Fixing
Revision history for this message
Miroslav Remák (miroslavr256) wrote :

Right, I see. We should definitely up the MapScriptingPacket version.

Revision history for this message
SirVer (sirver) wrote :

Theoretically, this should invalidate all savegames. Also non scenario ones. Since every game as a win condition (be it an empty one), all savegames contain Lua serialized coroutines. If they load it is by luck, there is no guarantee in Eris for compatibility. We should up the version for all savegames imho.

Revision history for this message
GunChleoc (gunchleoc) wrote :

> Also, what does 'print(_VERSION)' output on your end? It should be 'Lua+Eris
> 5.3'.

That was it. I had to delete the build directory to get the correct version. I can reproduce the crashes now.

I'll put this merge request on hold now, since there is obviously work to be done.

Revision history for this message
GunChleoc (gunchleoc) wrote :

This should be ready now :)

review: Needs Resubmitting
Revision history for this message
bunnybot (widelandsofficial) wrote :

Continuous integration builds have changed state:

Travis build 989. State: failed. Details: https://travis-ci.org/widelands/widelands/builds/121769847.
Appveyor build 822. State: success. Details: https://ci.appveyor.com/project/widelands-dev/widelands/build/_widelands_dev_widelands_bug_1543001_eris-822.

Revision history for this message
Miroslav Remák (miroslavr256) wrote :

Can you also fix the issue I mentioned here: https://code.launchpad.net/~widelands-dev/widelands/bug-1543001-eris/+merge/291294/comments/746462

This is what lead to the crash in the first place...

Revision history for this message
GunChleoc (gunchleoc) wrote :

Sorry, I overlooked this one. Which message do you mean by "this message"? I played the first tutorial through without any crashes.

> Besides the obvious error in Lua coroutine, there seems to be another issue
> with the message that is supposed to show up, which ultimately leads to a
> crash. This message (in CmdLuaCoroutine::execute) is constructed with icon and
> title parameters swapped.

Revision history for this message
Miroslav Remák (miroslavr256) wrote :

When a coroutine errors, an in-game message is supposed to be sent to all of the players:
http://bazaar.launchpad.net/~widelands-dev/widelands/bug-1543001-eris/view/head:/src/logic/cmd_luacoroutine.cc#L51

Revision history for this message
bunnybot (widelandsofficial) wrote :

Bunnybot encountered an error while working on this merge proposal:

Running 'bzr pull --overwrite' failed. Output:

ssh: Could not resolve hostname bazaar.launchpad.net: No address associated with hostname
ConnectionReset reading response for 'BzrDir.open_2.1', retrying
ssh: Could not resolve hostname bazaar.launchpad.net: No address associated with hostname
bzr: ERROR: Connection closed: Unexpected end of message. Please check connectivity and permissions, and report a bug if problems persist.
Using saved parent location: bzr+ssh://bazaar.launchpad.net/~widelands-dev/widelands/bug-1543001-eris/

Revision history for this message
kaputtnik (franku) wrote :

I have played some Tutorials and Campaigns, played a new game and also played with the editor.

Works fine i think :-)

review: Approve (testing)
Revision history for this message
bunnybot (widelandsofficial) wrote :

Continuous integration builds have changed state:

Travis build 993. State: passed. Details: https://travis-ci.org/widelands/widelands/builds/122023836.
Appveyor build 826. State: success. Details: https://ci.appveyor.com/project/widelands-dev/widelands/build/_widelands_dev_widelands_bug_1543001_eris-826.

Revision history for this message
GunChleoc (gunchleoc) wrote :

This should now be fixed as well. It has been broken for ages.

> When a coroutine errors, an in-game message is supposed to be sent to all of
> the players:
> http://bazaar.launchpad.net/~widelands-
> dev/widelands/bug-1543001-eris/view/head:/src/logic/cmd_luacoroutine.cc#L51

Revision history for this message
bunnybot (widelandsofficial) wrote :

Continuous integration builds have changed state:

Travis build 994. State: passed. Details: https://travis-ci.org/widelands/widelands/builds/122074637.
Appveyor build 827. State: failed. Details: https://ci.appveyor.com/project/widelands-dev/widelands/build/_widelands_dev_widelands_bug_1543001_eris-827.

Revision history for this message
Miroslav Remák (miroslavr256) wrote :

LGTM.

review: Approve (code)
Revision history for this message
GunChleoc (gunchleoc) wrote :

Thanks!

@bunnybot merge

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1=== modified file 'src/logic/cmd_luacoroutine.cc'
2--- src/logic/cmd_luacoroutine.cc 2016-02-15 23:26:42 +0000
3+++ src/logic/cmd_luacoroutine.cc 2016-04-10 16:54:20 +0000
4@@ -19,6 +19,8 @@
5
6 #include "logic/cmd_luacoroutine.h"
7
8+#include <boost/format.hpp>
9+
10 #include "base/log.h"
11 #include "base/macros.h"
12 #include "io/fileread.h"
13@@ -52,10 +54,10 @@
14 *new Widelands::Message
15 (Message::Type::kGameLogic,
16 game.get_gametime(),
17+ "Coroutine",
18 "images/ui_basic/menu_help.png",
19- "Coroutine",
20 "Lua Coroutine Failed",
21- e.what());
22+ (boost::format("<rt><p font-size=12>%s</p></rt>") % e.what()).str());
23 game.player(i).add_message(game, msg, true);
24 }
25 game.game_controller()->set_desired_speed(0);
26
27=== modified file 'src/logic/map_objects/tribes/soldier.cc'
28--- src/logic/map_objects/tribes/soldier.cc 2016-04-03 16:18:24 +0000
29+++ src/logic/map_objects/tribes/soldier.cc 2016-04-10 16:54:20 +0000
30@@ -1483,7 +1483,7 @@
31 descr().descname(),
32 "images/ui_basic/menu_help.png",
33 _("Logic error"),
34- messagetext,
35+ (boost::format("<rt><p font-size=12>%s</p></rt>") % messagetext).str(),
36 get_position(),
37 serial_));
38 opponent.owner().add_message
39@@ -1494,7 +1494,7 @@
40 descr().descname(),
41 "images/ui_basic/menu_help.png",
42 _("Logic error"),
43- messagetext,
44+ (boost::format("<rt><p font-size=12>%s</p></rt>") % messagetext).str(),
45 opponent.get_position(),
46 serial_));
47 game.game_controller()->set_desired_speed(0);
48
49=== modified file 'src/logic/map_objects/tribes/worker.cc'
50--- src/logic/map_objects/tribes/worker.cc 2016-03-08 15:21:41 +0000
51+++ src/logic/map_objects/tribes/worker.cc 2016-04-10 16:54:20 +0000
52@@ -1844,7 +1844,7 @@
53 _("Worker"),
54 "images/ui_basic/menu_help.png",
55 _("Worker got lost!"),
56- message,
57+ (boost::format("<rt><p font-size=12>%s</p></rt>") % message).str(),
58 get_position()),
59 serial_);
60 set_location(nullptr);
61
62=== modified file 'src/map_io/map_scripting_packet.cc'
63--- src/map_io/map_scripting_packet.cc 2015-11-28 22:29:26 +0000
64+++ src/map_io/map_scripting_packet.cc 2016-04-10 16:54:20 +0000
65@@ -37,7 +37,7 @@
66 namespace Widelands {
67
68 namespace {
69-constexpr uint32_t kCurrentPacketVersion = 2;
70+constexpr uint32_t kCurrentPacketVersion = 3;
71 } // namespace
72 /*
73 * ========================================================================
74
75=== modified file 'src/scripting/logic.cc'
76--- src/scripting/logic.cc 2016-02-12 16:58:41 +0000
77+++ src/scripting/logic.cc 2016-04-10 16:54:20 +0000
78@@ -99,14 +99,14 @@
79 switch (lua_gettop(L)) { /* check number of arguments */
80 case 0:
81 { /* no arguments */
82- lua_pushnumber(L, r); /* Number between 0 and 1 */
83+ lua_pushdouble(L, r); /* Number between 0 and 1 */
84 break;
85 }
86 case 1:
87 { /* only upper limit */
88 int32_t u = luaL_checkint32(L, 1);
89 luaL_argcheck(L, 1 <= u, 1, "interval is empty");
90- lua_pushnumber(L, floor(r * u) + 1); /* int between 1 and `u' */
91+ lua_pushuint32(L, floor(r * u) + 1); /* int between 1 and `u' */
92 break;
93 }
94 case 2:
95@@ -115,7 +115,7 @@
96 int32_t u = luaL_checkint32(L, 2);
97 luaL_argcheck(L, l <= u, 2, "interval is empty");
98 /* int between `l' and `u' */
99- lua_pushnumber(L, floor(r * (u - l + 1)) + l);
100+ lua_pushint32(L, floor(r * (u - l + 1)) + l);
101 break;
102 }
103 default: return luaL_error(L, "wrong number of arguments");
104
105=== modified file 'src/scripting/lua.h'
106--- src/scripting/lua.h 2016-02-12 16:58:41 +0000
107+++ src/scripting/lua.h 2016-04-10 16:54:20 +0000
108@@ -26,9 +26,11 @@
109
110 #define luaL_checkint32(L, n) static_cast<int32_t>(luaL_checkinteger(L, (n)))
111 #define luaL_checkuint32(L, n) static_cast<uint32_t>(luaL_checkinteger(L, (n)))
112+#define luaL_checkdouble(L, n) static_cast<double>(luaL_checknumber(L, (n)))
113
114 #define lua_pushint32(L, n) (lua_pushinteger(L, static_cast<int32_t>(n)))
115 #define lua_pushuint32(L, n) (lua_pushinteger(L, static_cast<uint32_t>(n)))
116+#define lua_pushdouble(L, n) (lua_pushnumber(L, static_cast<double>(n)))
117
118 void lua_pushstring (lua_State * L, const std::string & s);
119
120
121=== modified file 'src/scripting/lua_coroutine.cc'
122--- src/scripting/lua_coroutine.cc 2016-03-21 08:06:33 +0000
123+++ src/scripting/lua_coroutine.cc 2016-04-10 16:54:20 +0000
124@@ -124,7 +124,7 @@
125 if (!nreturn_values_) {
126 return 0;
127 }
128- if (!lua_isnumber(lua_state_, -1)) {
129+ if (!lua_isinteger(lua_state_, -1)) {
130 throw LuaError("pop_uint32(), but no integer on the stack.");
131 }
132 const uint32_t return_value = luaL_checkuint32(lua_state_, -1);
133@@ -144,7 +144,7 @@
134 return result;
135 }
136
137-constexpr uint8_t kCoroutineDataPacketVersion = 3;
138+constexpr uint8_t kCoroutineDataPacketVersion = 4;
139 void LuaCoroutine::write(FileWrite& fw) {
140 fw.unsigned_8(kCoroutineDataPacketVersion);
141
142
143=== modified file 'src/scripting/lua_globals.cc'
144--- src/scripting/lua_globals.cc 2016-04-03 12:35:43 +0000
145+++ src/scripting/lua_globals.cc 2016-04-10 16:54:20 +0000
146@@ -80,13 +80,10 @@
147 break;
148
149 case LUA_TNUMBER:
150- {
151- const int d = lua_tointeger(L, i);
152- if (d == 0 && !lua_isnumber(L, 1)) {
153- fmt % d;
154- } else {
155- fmt % luaL_checknumber(L, i);
156- }
157+ if (lua_isinteger(L, i)) {
158+ fmt % luaL_checkint32(L, i);
159+ } else {
160+ fmt % luaL_checknumber(L, i);
161 }
162 break;
163
164
165=== modified file 'src/scripting/lua_map.cc'
166--- src/scripting/lua_map.cc 2016-04-05 07:51:48 +0000
167+++ src/scripting/lua_map.cc 2016-04-10 16:54:20 +0000
168@@ -98,11 +98,11 @@
169 lua_newtable(L);
170 int counter = 0;
171 for (const std::vector<std::string>& foodlist : table) {
172- lua_pushnumber(L, ++counter);
173+ lua_pushuint32(L, ++counter);
174 lua_newtable(L);
175 int counter2 = 0;
176 for (const std::string& foodname : foodlist) {
177- lua_pushnumber(L, ++counter2);
178+ lua_pushuint32(L, ++counter2);
179 lua_pushstring(L, foodname);
180 lua_settable(L, -3);
181 }
182@@ -1506,8 +1506,8 @@
183 /* RST
184 .. attribute:: returns the terrain affinity values for this immovable
185
186- (RO) a table containing numbers labeled as pickiness, preferred_fertility,
187- preferred_humidity, and preferred_temperature,
188+ (RO) a table containing numbers labeled as pickiness (double), preferred_fertility (double),
189+ preferred_humidity (double), and preferred_temperature (uint),
190 or nil if the immovable has no terrain affinity.
191 */
192 int LuaImmovableDescription::get_terrain_affinity(lua_State * L) {
193@@ -1515,16 +1515,16 @@
194 const TerrainAffinity& affinity = get()->terrain_affinity();
195 lua_newtable(L);
196 lua_pushstring(L, "pickiness");
197- lua_pushnumber(L, affinity.pickiness());
198+ lua_pushdouble(L, affinity.pickiness());
199 lua_settable(L, -3);
200 lua_pushstring(L, "preferred_fertility");
201- lua_pushnumber(L, affinity.preferred_fertility());
202+ lua_pushdouble(L, affinity.preferred_fertility());
203 lua_settable(L, -3);
204 lua_pushstring(L, "preferred_humidity");
205- lua_pushnumber(L, affinity.preferred_humidity());
206+ lua_pushdouble(L, affinity.preferred_humidity());
207 lua_settable(L, -3);
208 lua_pushstring(L, "preferred_temperature");
209- lua_pushnumber(L, affinity.preferred_temperature());
210+ lua_pushuint32(L, affinity.preferred_temperature());
211 lua_settable(L, -3);
212 } else {
213 lua_pushnil(L);
214@@ -1620,7 +1620,7 @@
215 }
216 if (get()->has_terrain_affinity()) {
217 const TerrainDescription* terrain = (*get_user_class<LuaMaps::LuaTerrainDescription>(L, 2))->get();
218- lua_pushnumber(L, Widelands::probability_to_grow(get()->terrain_affinity(), *terrain));
219+ lua_pushdouble(L, Widelands::probability_to_grow(get()->terrain_affinity(), *terrain));
220 } else {
221 lua_pushnil(L);
222 }
223@@ -2062,11 +2062,11 @@
224 lua_newtable(L);
225 int counter = 0;
226 for (const auto& group: program.consumed_wares()) {
227- lua_pushnumber(L, ++counter);
228+ lua_pushuint32(L, ++counter);
229 lua_newtable(L);
230 for (const DescriptionIndex& ware_index : group.first) {
231 lua_pushstring(L, get_egbase(L).tribes().get_ware_descr(ware_index)->name());
232- lua_pushnumber(L, group.second);
233+ lua_pushuint32(L, group.second);
234 lua_settable(L, -3);
235 }
236 lua_settable(L, -3);
237@@ -2380,7 +2380,7 @@
238 lua_newtable(L);
239 int counter = 0;
240 for (const std::string& weaponname : get()->get_weapons_attack()) {
241- lua_pushnumber(L, ++counter);
242+ lua_pushuint32(L, ++counter);
243 lua_pushstring(L, weaponname);
244 lua_settable(L, -3);
245 }
246@@ -2396,7 +2396,7 @@
247 lua_newtable(L);
248 int counter = 0;
249 for (const std::string& weaponname : get()->get_weapons_defense()) {
250- lua_pushnumber(L, ++counter);
251+ lua_pushuint32(L, ++counter);
252 lua_pushstring(L, weaponname);
253 lua_settable(L, -3);
254 }
255@@ -2412,7 +2412,7 @@
256 lua_newtable(L);
257 int counter = 0;
258 for (const std::string& weaponname : get()->get_weapons_evade()) {
259- lua_pushnumber(L, ++counter);
260+ lua_pushuint32(L, ++counter);
261 lua_pushstring(L, weaponname);
262 lua_settable(L, -3);
263 }
264@@ -2428,7 +2428,7 @@
265 lua_newtable(L);
266 int counter = 0;
267 for (const std::string& weaponname : get()->get_weapons_health()) {
268- lua_pushnumber(L, ++counter);
269+ lua_pushuint32(L, ++counter);
270 lua_pushstring(L, weaponname);
271 lua_settable(L, -3);
272 }
273@@ -3128,7 +3128,7 @@
274 */
275
276 int LuaTerrainDescription::get_fertility(lua_State * L) {
277- lua_pushnumber(L, get()->fertility());
278+ lua_pushdouble(L, get()->fertility());
279 return 1;
280 }
281
282@@ -3139,7 +3139,7 @@
283 */
284
285 int LuaTerrainDescription::get_humidity(lua_State * L) {
286- lua_pushnumber(L, get()->humidity());
287+ lua_pushdouble(L, get()->humidity());
288 return 1;
289 }
290
291@@ -3157,11 +3157,11 @@
292 /* RST
293 .. attribute:: temperature
294
295- (RO) the :class:`double` temperature value for this terrain
296+ (RO) the :class:`uint` temperature value for this terrain
297 */
298
299 int LuaTerrainDescription::get_temperature(lua_State * L) {
300- lua_pushnumber(L, get()->temperature());
301+ lua_pushuint32(L, get()->temperature());
302 return 1;
303 }
304
305
306=== modified file 'src/scripting/lua_ui.cc'
307--- src/scripting/lua_ui.cc 2016-02-14 14:09:29 +0000
308+++ src/scripting/lua_ui.cc 2016-04-10 16:54:20 +0000
309@@ -206,7 +206,7 @@
310 int LuaPanel::set_mouse_position_x(lua_State * L) {
311 assert(panel_);
312 Point p = panel_->get_mouse_position();
313- p.x = luaL_checkint32(L, -1);
314+ p.x = floor(luaL_checkdouble(L, -1));
315 panel_->set_mouse_pos(p);
316 return 1;
317 }
318@@ -218,7 +218,7 @@
319 int LuaPanel::set_mouse_position_y(lua_State * L) {
320 assert(panel_);
321 Point p = panel_->get_mouse_position();
322- p.y = luaL_checkint32(L, -1);
323+ p.y = floor(luaL_checkdouble(L, -1));
324 panel_->set_mouse_pos(p);
325 return 1;
326 }
327@@ -554,7 +554,7 @@
328
329 MapView * mv = get();
330 Point p = mv->get_viewpoint();
331- p.x = luaL_checkuint32(L, -1);
332+ p.x = floor(luaL_checkdouble(L, -1));
333 mv->set_viewpoint(p, true);
334 return 0;
335 }
336@@ -571,7 +571,7 @@
337
338 MapView * mv = get();
339 Point p = mv->get_viewpoint();
340- p.y = luaL_checkuint32(L, -1);
341+ p.y = floor(luaL_checkdouble(L, -1));
342 mv->set_viewpoint(p, true);
343 return 0;
344 }
345
346=== modified file 'src/third_party/CMakeLists.txt'
347--- src/third_party/CMakeLists.txt 2015-07-05 11:05:23 +0000
348+++ src/third_party/CMakeLists.txt 2016-04-10 16:54:20 +0000
349@@ -51,6 +51,7 @@
350 eris/loslib.c
351 eris/lparser.c
352 eris/lparser.h
353+ eris/lprefix.h
354 eris/lstate.c
355 eris/lstate.h
356 eris/lstring.c
357@@ -63,10 +64,13 @@
358 eris/ltm.h
359 eris/lua.h
360 eris/lua.hpp
361+ eris/lua.c
362+ eris/luac.c
363 eris/luaconf.h
364 eris/lualib.h
365 eris/lundump.c
366 eris/lundump.h
367+ eris/lutf8lib.c
368 eris/lvm.c
369 eris/lvm.h
370 eris/lzio.c
371
372=== modified file 'src/third_party/eris/README.eris'
373--- src/third_party/eris/README.eris 2014-02-22 14:47:28 +0000
374+++ src/third_party/eris/README.eris 2016-04-10 16:54:20 +0000
375@@ -1,11 +1,11 @@
376 This directory contains a verbatim copy of Eris by Florian Nücke.
377
378 URL: https://github.com/fnuecke/eris
379-VERSION: 2e39ecc7dcb73120dde775929227fa661fbc6bc0
380+VERSION: 1.1.0 for Lua 5.3
381
382 We use this for heavy persistence and it also brings with it the Lua version
383 that we use in Widelands. The Widelands Team wishes to expresses total and
384 complete gratitude to the authors of Eris for making it available under the MIT
385-License.
386+License.
387
388 -- SirVer, in behalf of the Widelands Team
389
390=== modified file 'src/third_party/eris/eris.c'
391--- src/third_party/eris/eris.c 2014-07-25 11:14:03 +0000
392+++ src/third_party/eris/eris.c 2016-04-10 16:54:20 +0000
393@@ -1,6 +1,6 @@
394 /*
395-Eris - Heavy-duty persistence for Lua 5.2.2 - Based on Pluto
396-Copyright (c) 2013 by Florian Nuecke.
397+Eris - Heavy-duty persistence for Lua 5.3.0 - Based on Pluto
398+Copyright (c) 2013-2015 by Florian Nuecke.
399
400 Permission is hereby granted, free of charge, to any person obtaining a copy
401 of this software and associated documentation files (the "Software"), to deal
402@@ -113,14 +113,13 @@
403 /* lfunc.h */
404 #define eris_newproto luaF_newproto
405 #define eris_newLclosure luaF_newLclosure
406-#define eris_newupval luaF_newupval
407+#define eris_initupvals luaF_initupvals
408 #define eris_findupval luaF_findupval
409-/* lgc.h */
410-#define eris_barrierproto luaC_barrierproto
411 /* lmem.h */
412 #define eris_reallocvector luaM_reallocvector
413 /* lobject.h */
414-#define eris_ttypenv ttypenv
415+#define eris_ttnov ttnov
416+#define eris_clLvalue clLvalue
417 #define eris_setnilvalue setnilvalue
418 #define eris_setclLvalue setclLvalue
419 #define eris_setobj setobj
420@@ -176,15 +175,60 @@
421
422 /*
423 ** ============================================================================
424+** Language strings for errors.
425+** ============================================================================
426+*/
427+
428+#define ERIS_ERR_CFUNC "attempt to persist a light C function (%p)"
429+#define ERIS_ERR_COMPLEXITY "object too complex"
430+#define ERIS_ERR_HOOK "cannot persist yielded hooks"
431+#define ERIS_ERR_METATABLE "bad metatable, not nil or table"
432+#define ERIS_ERR_NOFUNC "attempt to persist unknown function type"
433+#define ERIS_ERR_READ "could not read data"
434+#define ERIS_ERR_SPER_FUNC "%s did not return a function"
435+#define ERIS_ERR_SPER_LOAD "bad unpersist function (%s expected, returned %s)"
436+#define ERIS_ERR_SPER_PROT "attempt to persist forbidden table"
437+#define ERIS_ERR_SPER_TYPE "%d not nil, boolean, or function"
438+#define ERIS_ERR_SPER_UFUNC "invalid restore function"
439+#define ERIS_ERR_SPER_UPERM "bad permanent value (%s expected, got %s)"
440+#define ERIS_ERR_SPER_UPERMNIL "bad permanent value (no value)"
441+#define ERIS_ERR_STACKBOUNDS "stack index out of bounds"
442+#define ERIS_ERR_TABLE "bad table value, got a nil value"
443+#define ERIS_ERR_THREAD "cannot persist currently running thread"
444+#define ERIS_ERR_THREADCI "invalid callinfo"
445+#define ERIS_ERR_THREADCTX "bad C continuation function"
446+#define ERIS_ERR_THREADERRF "invalid errfunc"
447+#define ERIS_ERR_THREADPC "saved program counter out of bounds"
448+#define ERIS_ERR_TRUNC_INT "int value would get truncated"
449+#define ERIS_ERR_TRUNC_SIZE "size_t value would get truncated"
450+#define ERIS_ERR_TYPE_FLOAT "unsupported lua_Number type"
451+#define ERIS_ERR_TYPE_INT "unsupported int type"
452+#define ERIS_ERR_TYPE_SIZE "unsupported size_t type"
453+#define ERIS_ERR_TYPEP "trying to persist unknown type %d"
454+#define ERIS_ERR_TYPEU "trying to unpersist unknown type %d"
455+#define ERIS_ERR_UCFUNC "bad C closure (C function expected, got %s)"
456+#define ERIS_ERR_UCFUNCNULL "bad C closure (C function expected, got null)"
457+#define ERIS_ERR_USERDATA "attempt to literally persist userdata"
458+#define ERIS_ERR_WRITE "could not write data"
459+#define ERIS_ERR_REF "invalid reference #%d. this usually means a special "\
460+ "persistence callback of a table referenced said table "\
461+ "(directly or indirectly via an upvalue)."
462+
463+/*
464+** ============================================================================
465 ** Constants, settings, types and forward declarations.
466 ** ============================================================================
467 */
468
469+/* The upvalue tag type was removed in Lua 5.3, but we still need it for
470+ * special handling of upvalues, so we redeclare it for internal use. */
471+#define LUA_TUPVAL (LUA_TOTALTAGS + 1)
472+
473 /* The "type" we write when we persist a value via a replacement from the
474 * permanents table. This is just an arbitrary number, but it must we lower
475 * than the reference offset (below) and outside the range Lua uses for its
476 * types (> LUA_TOTALTAGS). */
477-#define ERIS_PERMANENT (LUA_TOTALTAGS + 1)
478+#define ERIS_PERMANENT (LUA_TOTALTAGS + 2)
479
480 /* This is essentially the first reference we'll use. We do this to save one
481 * field in our persisted data: if the value is smaller than this, the object
482@@ -266,6 +310,12 @@
483 #define BUFFIDX 3
484 #define PATHIDX 4
485
486+/* Table indices for upvalue tables, keeping track of upvals to open. */
487+#define UVTOCL 1
488+#define UVTONU 2
489+#define UVTVAL 3
490+#define UVTREF 4
491+
492 /* }======================================================================== */
493
494 /*
495@@ -405,12 +455,13 @@
496 }
497
498 /* Used as a callback for luaL_opt to check boolean setting values. */
499-static void
500+static bool
501 checkboolean(lua_State *L, int narg) { /* ... bool? ... */
502 if (!lua_isboolean(L, narg)) { /* ... :( ... */
503- luaL_argerror(L, narg, lua_pushfstring(L,
504+ return luaL_argerror(L, narg, lua_pushfstring(L,
505 "boolean expected, got %s", lua_typename(L, lua_type(L, narg))));
506 } /* ... bool ... */
507+ return lua_toboolean(L, narg);
508 }
509
510 /* }======================================================================== */
511@@ -427,7 +478,7 @@
512 /* Writes a raw memory block with the specified size. */
513 #define WRITE_RAW(value, size) {\
514 if (info->u.pi.writer(info->L, (value), (size), info->u.pi.ud)) \
515- eris_error(info, "could not write data"); }
516+ eris_error(info, ERIS_ERR_WRITE); }
517
518 /* Writes a single value with the specified type. */
519 #define WRITE_VALUE(value, type) write_##type(info, value)
520@@ -441,7 +492,7 @@
521 /* Reads a raw block of memory with the specified size. */
522 #define READ_RAW(value, size) {\
523 if (eris_read(&info->u.upi.zio, (value), (size))) \
524- eris_error(info, "could not read data"); }
525+ eris_error(info, ERIS_ERR_READ); }
526
527 /* Reads a single value with the specified type. */
528 #define READ_VALUE(type) read_##type(info)
529@@ -527,7 +578,7 @@
530 write_int64_t(info, value);
531 }
532 else {
533- eris_error(info, "unsupported int type");
534+ eris_error(info, ERIS_ERR_TYPE_INT);
535 }
536 }
537
538@@ -543,7 +594,7 @@
539 write_uint64_t(info, value);
540 }
541 else {
542- eris_error(info, "unsupported size_t type");
543+ eris_error(info, ERIS_ERR_TYPE_SIZE);
544 }
545 }
546
547@@ -556,7 +607,20 @@
548 write_float64(info, value);
549 }
550 else {
551- eris_error(info, "unsupported lua_Number type");
552+ eris_error(info, ERIS_ERR_TYPE_FLOAT);
553+ }
554+}
555+
556+static void
557+write_lua_Integer(Info *info, lua_Integer value) {
558+ if (sizeof(lua_Integer) == sizeof(uint32_t)) {
559+ write_uint32_t(info, value);
560+ }
561+ else if (sizeof(lua_Integer) == sizeof(uint64_t)) {
562+ write_uint64_t(info, value);
563+ }
564+ else {
565+ eris_error(info, ERIS_ERR_TYPE_INT);
566 }
567 }
568
569@@ -657,25 +721,25 @@
570 int16_t pvalue = read_int16_t(info);
571 value = (int)pvalue;
572 if ((int32_t)value != pvalue) {
573- eris_error(info, "int value would get truncated");
574+ eris_error(info, ERIS_ERR_TRUNC_INT);
575 }
576 }
577 else if (info->u.upi.sizeof_int == sizeof(int32_t)) {
578 int32_t pvalue = read_int32_t(info);
579 value = (int)pvalue;
580 if ((int32_t)value != pvalue) {
581- eris_error(info, "int value would get truncated");
582+ eris_error(info, ERIS_ERR_TRUNC_INT);
583 }
584 }
585 else if (info->u.upi.sizeof_int == sizeof(int64_t)) {
586 int64_t pvalue = read_int64_t(info);
587 value = (int)pvalue;
588 if ((int64_t)value != pvalue) {
589- eris_error(info, "int value would get truncated");
590+ eris_error(info, ERIS_ERR_TRUNC_INT);
591 }
592 }
593 else {
594- eris_error(info, "unsupported int type");
595+ eris_error(info, ERIS_ERR_TYPE_INT);
596 value = 0; /* not reached */
597 }
598 return value;
599@@ -688,25 +752,25 @@
600 uint16_t pvalue = read_uint16_t(info);
601 value = (size_t)pvalue;
602 if ((uint32_t)value != pvalue) {
603- eris_error(info, "size_t value would get truncated");
604+ eris_error(info, ERIS_ERR_TRUNC_SIZE);
605 }
606 }
607 else if (info->u.upi.sizeof_size_t == sizeof(uint32_t)) {
608 uint32_t pvalue = read_uint32_t(info);
609 value = (size_t)pvalue;
610 if ((uint32_t)value != pvalue) {
611- eris_error(info, "size_t value would get truncated");
612+ eris_error(info, ERIS_ERR_TRUNC_SIZE);
613 }
614 }
615 else if (info->u.upi.sizeof_size_t == sizeof(uint64_t)) {
616 uint64_t pvalue = read_uint64_t(info);
617 value = (size_t)pvalue;
618 if ((uint64_t)value != pvalue) {
619- eris_error(info, "size_t value would get truncated");
620+ eris_error(info, ERIS_ERR_TRUNC_SIZE);
621 }
622 }
623 else {
624- eris_error(info, "unsupported size_t type");
625+ eris_error(info, ERIS_ERR_TYPE_SIZE);
626 value = 0; /* not reached */
627 }
628 return value;
629@@ -721,7 +785,21 @@
630 return read_float64(info);
631 }
632 else {
633- eris_error(info, "unsupported lua_Number type");
634+ eris_error(info, ERIS_ERR_TYPE_FLOAT);
635+ return 0; /* not reached */
636+ }
637+}
638+
639+static lua_Integer
640+read_lua_Integer(Info *info) {
641+ if (sizeof(lua_Integer) == sizeof(uint32_t)) {
642+ return (lua_Integer) read_uint32_t(info);
643+ }
644+ else if (sizeof(lua_Integer) == sizeof(uint64_t)) {
645+ return (lua_Integer) read_uint64_t(info);
646+ }
647+ else {
648+ eris_error(info, ERIS_ERR_TYPE_INT);
649 return 0; /* not reached */
650 }
651 }
652@@ -776,13 +854,25 @@
653
654 static void
655 p_number(Info *info) { /* ... num */
656- WRITE_VALUE(lua_tonumber(info->L, -1), lua_Number);
657+ if (lua_isinteger(info->L, -1)) {
658+ WRITE_VALUE(true, uint8_t);
659+ WRITE_VALUE(lua_tointeger(info->L, -1), lua_Integer);
660+ }
661+ else {
662+ WRITE_VALUE(false, uint8_t);
663+ WRITE_VALUE(lua_tonumber(info->L, -1), lua_Number);
664+ }
665 }
666
667 static void
668 u_number(Info *info) { /* ... */
669 eris_checkstack(info->L, 1);
670- lua_pushnumber(info->L, READ_VALUE(lua_Number)); /* ... num */
671+ if (READ_VALUE(uint8_t)) {
672+ lua_pushinteger(info->L, READ_VALUE(lua_Integer));
673+ }
674+ else {
675+ lua_pushnumber(info->L, READ_VALUE(lua_Number)); /* ... num */
676+ }
677
678 eris_assert(lua_type(info->L, -1) == LUA_TNUMBER);
679 }
680@@ -801,7 +891,7 @@
681 u_string(Info *info) { /* ... */
682 eris_checkstack(info->L, 2);
683 {
684- // TODO(unknown): Can we avoid this copy somehow? (Without it getting too nasty)
685+ /* TODO Can we avoid this copy somehow? (Without it getting too nasty) */
686 const size_t length = READ_VALUE(size_t);
687 char *value = lua_newuserdata(info->L, length * sizeof(char)); /* ... tmp */
688 READ_RAW(value, length);
689@@ -843,7 +933,7 @@
690 lua_pop(info->L, 1); /* ... tbl */
691 }
692 else { /* tbl :( */
693- eris_error(info, "bad metatable, not nil or table");
694+ eris_error(info, ERIS_ERR_METATABLE);
695 }
696 poppath(info);
697 }
698@@ -923,7 +1013,7 @@
699 lua_rawset(info->L, -3); /* ... tbl */
700 }
701 else {
702- eris_error(info, "bad table value, got a nil value");
703+ eris_error(info, ERIS_ERR_TABLE);
704 }
705
706 poppath(info);
707@@ -996,8 +1086,7 @@
708 lua_call(info->L, 1, 1); /* ... obj func? */
709 }
710 if (!lua_isfunction(info->L, -1)) { /* ... obj :( */
711- eris_error(info, "%s did not return a function",
712- info->u.pi.metafield);
713+ eris_error(info, ERIS_ERR_SPER_FUNC, info->u.pi.metafield);
714 } /* ... obj func */
715
716 /* Special persistence, call this function when unpersisting. */
717@@ -1006,8 +1095,7 @@
718 lua_pop(info->L, 1); /* ... obj */
719 return;
720 default: /* ... obj mt :( */
721- eris_error(info, "%d not nil, boolean, or function",
722- info->u.pi.metafield);
723+ eris_error(info, ERIS_ERR_SPER_TYPE, info->u.pi.metafield);
724 return; /* not reached */
725 }
726 }
727@@ -1018,10 +1106,10 @@
728 literal(info); /* ... obj */
729 }
730 else if (lua_type(info->L, -1) == LUA_TTABLE) {
731- eris_error(info, "attempt to persist forbidden table");
732+ eris_error(info, ERIS_ERR_SPER_PROT);
733 }
734 else {
735- eris_error(info, "attempt to literally persist userdata");
736+ eris_error(info, ERIS_ERR_USERDATA);
737 }
738 }
739
740@@ -1040,7 +1128,7 @@
741 * persisting a special object. */
742 unpersist(info); /* ... spfunc? */
743 if (!lua_isfunction(info->L, -1)) { /* ... :( */
744- eris_error(info, "invalid restore function");
745+ eris_error(info, ERIS_ERR_SPER_UFUNC);
746 } /* ... spfunc */
747
748 if (info->passIOToPersist) {
749@@ -1051,8 +1139,9 @@
750 }
751
752 if (lua_type(info->L, -1) != type) { /* ... :( */
753- eris_error(info, "bad unpersist function (%s expected, returned %s)",
754- kTypenames[type], kTypenames[lua_type(info->L, -1)]);
755+ const char *want = kTypenames[type];
756+ const char *have = kTypenames[lua_type(info->L, -1)];
757+ eris_error(info, ERIS_ERR_SPER_LOAD, want, have);
758 } /* ... obj */
759
760 /* Update the reftable entry. */
761@@ -1326,12 +1415,14 @@
762 u_upval(Info *info) { /* ... */
763 eris_checkstack(info->L, 2);
764
765- /* Create the table we use to store the pointer to the actual upval (1), the
766- * value of the upval (2) and any pointers to the pointer to the upval (3+).*/
767- lua_createtable(info->L, 3, 0); /* ... tbl */
768+ /* Create the table we use to store the stack location to the upval (1+2),
769+ * the value of the upval (3) and any references to the upvalue's value (4+).
770+ * References are stored as two entries each, the actual closure holding the
771+ * upvalue, and the index of the upvalue in that closure. */
772+ lua_createtable(info->L, 5, 0); /* ... tbl */
773 registerobject(info);
774 unpersist(info); /* ... tbl obj */
775- lua_rawseti(info->L, -2, 1); /* ... tbl */
776+ lua_rawseti(info->L, -2, UVTVAL); /* ... tbl */
777
778 eris_assert(lua_type(info->L, -1) == LUA_TTABLE);
779 }
780@@ -1354,8 +1445,7 @@
781 switch (ttype(info->L->top - 1)) {
782 case LUA_TLCF: /* light C function */
783 /* We cannot persist these, they have to be handled via the permtable. */
784- eris_error(info, "attempt to persist a light C function (%p)",
785- lua_tocfunction(info->L, -1));
786+ eris_error(info, ERIS_ERR_CFUNC, lua_tocfunction(info->L, -1));
787 return; /* not reached */
788 case LUA_TCCL: /* C closure */ { /* perms reftbl ... ccl */
789 CClosure *cl = clCvalue(info->L->top - 1);
790@@ -1387,7 +1477,7 @@
791 break;
792 }
793 case LUA_TLCL: /* Lua function */ { /* perms reftbl ... lcl */
794- LClosure *cl = clLvalue(info->L->top - 1);
795+ LClosure *cl = eris_clLvalue(info->L->top - 1);
796 /* Mark it as a Lua closure. */
797 WRITE_VALUE(false, uint8_t);
798 /* Write the upvalue count first, since we have to know it when creating
799@@ -1421,7 +1511,7 @@
800 break;
801 }
802 default:
803- eris_error(info, "attempt to persist unknown function type");
804+ eris_error(info, ERIS_ERR_NOFUNC);
805 return; /* not reached */
806 }
807 }
808@@ -1444,12 +1534,11 @@
809 /* Read the C function from the permanents table. */
810 unpersist(info); /* ... cfunc */
811 if (!lua_iscfunction(info->L, -1)) {
812- eris_error(info, "bad C closure (C function expected, got %s)",
813- kTypenames[lua_type(info->L, -1)]);
814+ eris_error(info, ERIS_ERR_UCFUNC, kTypenames[lua_type(info->L, -1)]);
815 }
816 f = lua_tocfunction(info->L, -1);
817 if (!f) {
818- eris_error(info, "bad C closure (C function expected, got null)");
819+ eris_error(info, ERIS_ERR_UCFUNCNULL);
820 }
821 lua_pop(info->L, 1); /* ... */
822
823@@ -1476,7 +1565,7 @@
824 poppath(info);
825 }
826 else {
827- Closure *cl;
828+ LClosure *cl;
829 Proto *p;
830
831 eris_checkstack(info->L, 4);
832@@ -1494,27 +1583,28 @@
833 * unpersist function. This way the instance is safely hooked up to an
834 * object, so we don't have to worry about it getting GCed. */
835 pushpath(info, ".proto");
836- cl->l.p = eris_newproto(info->L);
837+ cl->p = eris_newproto(info->L);
838 /* Push the proto into which to unpersist as a parameter to u_proto. */
839- lua_pushlightuserdata(info->L, cl->l.p); /* ... lcl nproto */
840+ lua_pushlightuserdata(info->L, cl->p); /* ... lcl nproto */
841 unpersist(info); /* ... lcl nproto nproto/oproto */
842 eris_assert(lua_type(info->L, -1) == LUA_TLIGHTUSERDATA);
843 /* The proto we have now may differ, if we already unpersisted it before.
844 * In that case we now have a reference to the originally unpersisted
845 * proto so we'll use that. */
846 p = lua_touserdata(info->L, -1);
847- if (p != cl->l.p) { /* ... lcl nproto oproto */
848+ if (p != cl->p) { /* ... lcl nproto oproto */
849 /* Just overwrite the old one, GC will clean this up. */
850- cl->l.p = p;
851+ cl->p = p;
852 }
853 lua_pop(info->L, 2); /* ... lcl */
854- eris_assert(cl->l.p->sizeupvalues == nups);
855+ eris_assert(cl->nupvalues == cl->p->sizeupvalues);
856+ eris_initupvals(info->L, cl); /* Init to all closed, fill in later. */
857 poppath(info);
858
859 /* Unpersist all upvalues. */
860 pushpath(info, ".upvalues");
861 for (nup = 1; nup <= nups; ++nup) {
862- UpVal **uv = &cl->l.upvals[nup - 1];
863+ UpVal **uv = &cl->upvals[nup - 1];
864 /* Get the actual name of the upvalue, if possible. */
865 if (p->upvalues[nup - 1].name) {
866 pushpath(info, "[%s]", getstr(p->upvalues[nup - 1].name));
867@@ -1524,50 +1614,60 @@
868 }
869 unpersist(info); /* ... lcl tbl */
870 eris_assert(lua_type(info->L, -1) == LUA_TTABLE);
871- lua_rawgeti(info->L, -1, 2); /* ... lcl tbl upval/nil */
872+ lua_rawgeti(info->L, -1, UVTOCL); /* ... lcl tbl olcl/nil */
873 if (lua_isnil(info->L, -1)) { /* ... lcl tbl nil */
874 lua_pop(info->L, 1); /* ... lcl tbl */
875- *uv = eris_newupval(info->L);
876- lua_pushlightuserdata(info->L, *uv); /* ... lcl tbl upval */
877- lua_rawseti(info->L, -2, 2); /* ... lcl tbl */
878+ lua_pushvalue(info->L, -2); /* ... lcl tbl lcl */
879+ lua_rawseti(info->L, -2, UVTOCL); /* ... lcl tbl */
880+ lua_pushinteger(info->L, nup); /* ... lcl tbl nup */
881+ lua_rawseti(info->L, -2, UVTONU); /* ... lcl tbl */
882 }
883- else { /* ... lcl tbl upval */
884- eris_assert(lua_type(info->L, -1) == LUA_TLIGHTUSERDATA);
885- *uv = (UpVal*)lua_touserdata(info->L, -1);
886+ else { /* ... lcl tbl olcl */
887+ int onup;
888+ eris_assert(lua_type(info->L, -1) == LUA_TFUNCTION);
889+ lua_rawgeti(info->L, -2, UVTONU); /* ... lcl tbl olcl onup */
890+ eris_assert(lua_type(info->L, -1) == LUA_TNUMBER);
891+ onup = lua_tointeger(info->L, -1);
892+ lua_pop(info->L, 1); /* ... lcl tbl olcl */
893+ lua_upvaluejoin(info->L, -3, nup, -1, onup);
894 lua_pop(info->L, 1); /* ... lcl tbl */
895 }
896
897 /* Set the upvalue's actual value and add our reference to the upvalue to
898- * the list, for pointer patching if we have to open the upvalue in
899+ * the list, for reference patching if we have to open the upvalue in
900 * u_thread. Either is only necessary if the upvalue is still closed. */
901- if ((*uv)->v == &(*uv)->u.value) {
902+ if (!upisopen(*uv)) {
903+ int i;
904 /* Always update the value of the upvalue's value for closed upvalues,
905 * even if we re-used one - if we had a cycle, it might have been
906- * incorrectly initialized to nil before. */
907- lua_rawgeti(info->L, -1, 1); /* ... lcl tbl obj */
908+ * incorrectly initialized to nil before (or rather, not yet set). */
909+ lua_rawgeti(info->L, -1, UVTVAL); /* ... lcl tbl obj */
910 eris_setobj(info->L, &(*uv)->u.value, info->L->top - 1);
911 lua_pop(info->L, 1); /* ... lcl tbl */
912
913- lua_pushlightuserdata(info->L, uv); /* ... lcl tbl upvalp */
914- if (luaL_len(info->L, -2) >= 2) {
915- /* Got a valid sequence, insert at the end. */
916- lua_rawseti(info->L, -2, luaL_len(info->L, -2) + 1); /* ... lcl tbl */
917+ lua_pushinteger(info->L, nup); /* ... lcl tbl nup */
918+ lua_pushvalue(info->L, -3); /* ... lcl tbl nup lcl */
919+ if (luaL_len(info->L, -3) >= UVTVAL) {
920+ /* Got a valid sequence (value already set), insert at the end. */
921+ i = luaL_len(info->L, -3);
922+ lua_rawseti(info->L, -3, i + 1); /* ... lcl tbl nup */
923+ lua_rawseti(info->L, -2, i + 2); /* ... lcl tbl */
924 }
925- else { /* ... lcl tbl upvalp */
926- int i;
927+ else { /* ... lcl tbl nup lcl */
928 /* Find where to insert. This can happen if we have cycles, in which
929 * case the table is not fully initialized at this point, i.e. the
930 * value is not in it, yet (we work around that by always setting it,
931 * as seen above). */
932- for (i = 3;; ++i) {
933- lua_rawgeti(info->L, -2, i); /* ... lcl tbl upvalp upvalp/nil */
934- if (lua_isnil(info->L, -1)) { /* ... lcl tbl upvalp nil */
935- lua_pop(info->L, 1); /* ... lcl tbl upvalp */
936- lua_rawseti(info->L, -2, i); /* ... lcl tbl */
937+ for (i = UVTREF;; i += 2) {
938+ lua_rawgeti(info->L, -3, i); /* ... lcl tbl nup lcl lcl/nil */
939+ if (lua_isnil(info->L, -1)) { /* ... lcl tbl nup lcl nil */
940+ lua_pop(info->L, 1); /* ... lcl tbl nup lcl */
941+ lua_rawseti(info->L, -3, i); /* ... lcl tbl nup */
942+ lua_rawseti(info->L, -2, i + 1); /* ... lcl tbl */
943 break;
944 }
945 else {
946- lua_pop(info->L, 1); /* ... lcl tbl upvalp */
947+ lua_pop(info->L, 1); /* ... lcl tbl nup lcl */
948 }
949 } /* ... lcl tbl */
950 }
951@@ -1578,8 +1678,9 @@
952 }
953 poppath(info);
954
955- eris_barrierproto(info->L, p, cl);
956- p->cache = cl; /* save it in cache for reuse, see lvm.c:416 */
957+ /* save it in cache for reuse, see lvm.c:416 */
958+ if (!isblack(p))
959+ p->cache = cl;
960 }
961
962 eris_assert(lua_type(info->L, -1) == LUA_TFUNCTION);
963@@ -1590,8 +1691,7 @@
964 static void
965 p_thread(Info *info) { /* ... thread */
966 lua_State* thread = lua_tothread(info->L, -1);
967- size_t level;
968- StkId o;
969+ size_t level = 0, total = thread->top - thread->stack;
970 CallInfo *ci;
971 UpVal *uv;
972
973@@ -1600,13 +1700,13 @@
974 /* We cannot persist any running threads, because by definition we *are* that
975 * running thread. And we use the stack. So yeah, really not a good idea. */
976 if (thread == info->L) {
977- eris_error(info, "cannot persist currently running thread");
978+ eris_error(info, ERIS_ERR_THREAD);
979 return; /* not reached */
980 }
981
982 /* Persist the stack. Save the total size and used space first. */
983 WRITE_VALUE(thread->stacksize, int);
984- WRITE_VALUE(thread->top - thread->stack, size_t);
985+ WRITE_VALUE(total, size_t);
986
987 /* The Lua stack looks like this:
988 * stack ... top ... stack_last
989@@ -1614,10 +1714,15 @@
990 * element, i.e. there's nothing stored there. So we stop one below that. */
991 pushpath(info, ".stack");
992 lua_pushnil(info->L); /* ... thread nil */
993- level = 0;
994- for (o = thread->stack; o < thread->top; ++o) {
995- pushpath(info, "[%d]", level++);
996- eris_setobj(info->L, info->L->top - 1, o); /* ... thread obj */
997+ /* Since the thread's stack may be re-allocated in the meantime, we cannot
998+ * use pointer arithmetic here (i.e. o = thread->stack; ...; ++o). Instead we
999+ * have to keep track of our position in the stack directly (which we do for
1000+ * the path info anyway) and compute the actual address each time.
1001+ */
1002+ for (; level < total; ++level) {
1003+ pushpath(info, "[%d]", level);
1004+ eris_setobj(info->L, info->L->top - 1, thread->stack + level);
1005+ /* ... thread obj */
1006 persist(info); /* ... thread obj */
1007 poppath(info);
1008 }
1009@@ -1647,7 +1752,7 @@
1010 WRITE_VALUE(thread->hookcount, int); */
1011
1012 if (thread->hook) {
1013- // TODO(unknown): Warn that hooks are not persisted?
1014+ /* TODO Warn that hooks are not persisted? */
1015 }
1016
1017 /* Write call information (stack frames). In 5.2 CallInfo is stored in a
1018@@ -1665,42 +1770,46 @@
1019 WRITE_VALUE(eris_savestackidx(thread, ci->top), size_t);
1020 WRITE_VALUE(ci->nresults, int16_t);
1021 WRITE_VALUE(ci->callstatus, uint8_t);
1022- /* CallInfo.extra is used in two contexts: if L->status == LUA_YIELD and
1023- * CallInfo is the one stored as L->ci, in which case ci->extra refers to
1024- * the original value of L->ci->func, and when we have a yieldable pcall
1025- * (ci->callstatus & CIST_YPCALL) where ci->extra holds the stack level
1026- * of the function being called (see lua_pcallk). We save the ci->extra
1027- * for L->ci after the loop, because we won't know which one it is when
1028- * unpersisting. */
1029- if (ci->callstatus & CIST_YPCALL) {
1030- WRITE_VALUE(eris_savestackidx(thread,
1031- eris_restorestack(thread, ci->extra)), size_t);
1032- }
1033-
1034- eris_assert(eris_isLua(ci) || (ci->callstatus & CIST_TAIL) == 0);
1035- if (ci->callstatus & CIST_HOOKYIELD) {
1036- eris_error(info, "cannot persist yielded hooks");
1037- }
1038-
1039- if (eris_isLua(ci)) {
1040- const LClosure *lcl = eris_ci_func(ci);
1041- WRITE_VALUE(eris_savestackidx(thread, ci->u.l.base), size_t);
1042- WRITE_VALUE(ci->u.l.savedpc - lcl->p->code, size_t);
1043- }
1044- else {
1045- WRITE_VALUE(ci->u.c.status, uint8_t);
1046-
1047- /* These are only used while a thread is being executed:
1048- WRITE_VALUE(ci->u.c.old_errfunc, ptrdiff_t);
1049- WRITE_VALUE(ci->u.c.old_allowhook, uint8_t); */
1050-
1051- // TODO(unknown): Is this really right? Hooks may be a problem?
1052- if (ci->callstatus & (CIST_YPCALL | CIST_YIELDED)) {
1053- WRITE_VALUE(ci->u.c.ctx, int);
1054- eris_assert(ci->u.c.k);
1055- lua_pushcfunction(info->L, ci->u.c.k); /* ... thread func */
1056- persist(info); /* ... thread func/nil */
1057- lua_pop(info->L, 1); /* ... thread */
1058+ if (ci->callstatus) {
1059+ /* CallInfo.extra is used in two contexts: if L->status == LUA_YIELD and
1060+ * CallInfo is the one stored as L->ci, in which case ci->extra refers to
1061+ * the original value of L->ci->func, and when we have a yieldable pcall
1062+ * (ci->callstatus & CIST_YPCALL) where ci->extra holds the stack level
1063+ * of the function being called (see lua_pcallk). We save the ci->extra
1064+ * for L->ci after the loop, because we won't know which one it is when
1065+ * unpersisting. */
1066+ if (ci->callstatus & CIST_YPCALL) {
1067+ WRITE_VALUE(eris_savestackidx(thread,
1068+ eris_restorestack(thread, ci->extra)), size_t);
1069+ }
1070+
1071+ eris_assert(eris_isLua(ci) || (ci->callstatus & CIST_TAIL) == 0);
1072+ if (ci->callstatus & CIST_HOOKYIELD) {
1073+ eris_error(info, ERIS_ERR_HOOK);
1074+ }
1075+
1076+ if (eris_isLua(ci)) {
1077+ const LClosure *lcl = eris_ci_func(ci);
1078+ WRITE_VALUE(eris_savestackidx(thread, ci->u.l.base), size_t);
1079+ WRITE_VALUE(ci->u.l.savedpc - lcl->p->code, size_t);
1080+ }
1081+ else {
1082+ /* These are only used while a thread is being executed:
1083+ WRITE_VALUE(ci->u.c.old_errfunc, ptrdiff_t); */
1084+ if (thread->status == LUA_YIELD && ci->u.c.k) {
1085+ WRITE_VALUE(true, uint8_t);
1086+ WRITE_VALUE(ci->u.c.ctx, int);
1087+ /* NOTE Ugly hack. We have to push the continuation function as a C
1088+ * function to properly track it in our ref table. It's never called,
1089+ * so we can get away with this. */
1090+ lua_pushcfunction(info->L, (lua_CFunction) ci->u.c.k);
1091+ /* ... thread func */
1092+ persist(info); /* ... thread func/nil */
1093+ lua_pop(info->L, 1); /* ... thread */
1094+ }
1095+ else {
1096+ WRITE_VALUE(false, uint8_t);
1097+ }
1098 }
1099 }
1100
1101@@ -1719,11 +1828,11 @@
1102 pushpath(info, ".openupval");
1103 lua_pushnil(info->L); /* ... thread nil */
1104 level = 0;
1105- for (uv = eris_gco2uv(thread->openupval);
1106+ for (uv = thread->openupval;
1107 uv != NULL;
1108- uv = eris_gco2uv(eris_gch(eris_obj2gco(uv))->next))
1109+ uv = uv->u.open.next)
1110 {
1111- pushpath(info, "[%d]", level);
1112+ pushpath(info, "[%d]", level++);
1113 WRITE_VALUE(eris_savestackidx(thread, uv->v) + 1, size_t);
1114 eris_setobj(info->L, info->L->top - 1, uv->v); /* ... thread obj */
1115 lua_pushlightuserdata(info->L, uv); /* ... thread obj id */
1116@@ -1739,7 +1848,7 @@
1117 #define validate(stackpos, inclmax) \
1118 if ((stackpos) < thread->stack || stackpos > (inclmax)) { \
1119 (stackpos) = thread->stack; \
1120- eris_error(info, "stack index out of bounds"); }
1121+ eris_error(info, ERIS_ERR_STACKBOUNDS); }
1122
1123 /* I had so hoped to get by without any 'hacks', but I surrender. We mark the
1124 * thread as incomplete to avoid the GC messing with it while we're building
1125@@ -1805,8 +1914,8 @@
1126 if (thread->errfunc) {
1127 o = eris_restorestack(thread, thread->errfunc);
1128 validate(o, thread->top);
1129- if (eris_ttypenv(o) != LUA_TFUNCTION) {
1130- eris_error(info, "invalid errfunc");
1131+ if (eris_ttnov(o) != LUA_TFUNCTION) {
1132+ eris_error(info, ERIS_ERR_THREADERRF);
1133 }
1134 }
1135 /* These are only used while a thread is being executed or can be deduced:
1136@@ -1835,61 +1944,64 @@
1137 validate(thread->ci->top, thread->stack_last);
1138 thread->ci->nresults = READ_VALUE(int16_t);
1139 thread->ci->callstatus = READ_VALUE(uint8_t);
1140- /** See comment in p_thread. */
1141- if (thread->ci->callstatus & CIST_YPCALL) {
1142- thread->ci->extra = eris_savestack(thread,
1143- eris_restorestackidx(thread, READ_VALUE(size_t)));
1144- o = eris_restorestack(thread, thread->ci->extra);
1145- validate(o, thread->top);
1146- if (eris_ttypenv(o) != LUA_TFUNCTION) {
1147- eris_error(info, "invalid callinfo");
1148- }
1149- }
1150-
1151- if (eris_isLua(thread->ci)) {
1152- LClosure *lcl = eris_ci_func(thread->ci);
1153- thread->ci->u.l.base = eris_restorestackidx(thread, READ_VALUE(size_t));
1154- validate(thread->ci->u.l.base, thread->top);
1155- thread->ci->u.l.savedpc = lcl->p->code + READ_VALUE(size_t);
1156- if (thread->ci->u.l.savedpc < lcl->p->code ||
1157- thread->ci->u.l.savedpc > lcl->p->code + lcl->p->sizecode)
1158- {
1159- thread->ci->u.l.savedpc = lcl->p->code; /* Just to be safe. */
1160- eris_error(info, "saved program counter out of bounds");
1161- }
1162+ if (thread->ci->callstatus) {
1163+ /** See comment in p_thread. */
1164+ if (thread->ci->callstatus & CIST_YPCALL) {
1165+ thread->ci->extra = eris_savestack(thread,
1166+ eris_restorestackidx(thread, READ_VALUE(size_t)));
1167+ o = eris_restorestack(thread, thread->ci->extra);
1168+ validate(o, thread->top);
1169+ if (eris_ttnov(o) != LUA_TFUNCTION) {
1170+ eris_error(info, ERIS_ERR_THREADCI);
1171+ }
1172+ }
1173+
1174+ if (eris_isLua(thread->ci)) {
1175+ LClosure *lcl = eris_ci_func(thread->ci);
1176+ thread->ci->u.l.base = eris_restorestackidx(thread, READ_VALUE(size_t));
1177+ validate(thread->ci->u.l.base, thread->top);
1178+ thread->ci->u.l.savedpc = lcl->p->code + READ_VALUE(size_t);
1179+ if (thread->ci->u.l.savedpc < lcl->p->code ||
1180+ thread->ci->u.l.savedpc > lcl->p->code + lcl->p->sizecode)
1181+ {
1182+ thread->ci->u.l.savedpc = lcl->p->code; /* Just to be safe. */
1183+ eris_error(info, ERIS_ERR_THREADPC);
1184+ }
1185+ }
1186+ else {
1187+ /* These are only used while a thread is being executed:
1188+ thread->ci->u.c.old_errfunc = READ_VALUE(ptrdiff_t); */
1189+ thread->ci->u.c.old_errfunc = 0;
1190+
1191+ if (thread->status == LUA_YIELD && READ_VALUE(uint8_t)) {
1192+ thread->ci->u.c.ctx = READ_VALUE(int);
1193+ LOCK(thread);
1194+ unpersist(info); /* ... thread func? */
1195+ UNLOCK(thread);
1196+ if (lua_iscfunction(info->L, -1)) { /* ... thread func */
1197+ /* NOTE Ugly hack. See p_thread. */
1198+ thread->ci->u.c.k = (lua_KFunction) lua_tocfunction(info->L, -1);
1199+ }
1200+ else {
1201+ eris_error(info, ERIS_ERR_THREADCTX);
1202+ return; /* not reached */
1203+ }
1204+ lua_pop(info->L, 1); /* ... thread */
1205+ }
1206+ else {
1207+ thread->ci->u.c.ctx = 0;
1208+ thread->ci->u.c.k = NULL;
1209+ }
1210+ }
1211+ LOCK(thread);
1212+ poppath(info);
1213+ UNLOCK(thread);
1214 }
1215 else {
1216- thread->ci->u.c.status = READ_VALUE(uint8_t);
1217-
1218- /* These are only used while a thread is being executed:
1219- thread->ci->u.c.old_errfunc = READ_VALUE(ptrdiff_t);
1220- thread->ci->u.c.old_allowhook = READ_VALUE(uint8_t); */
1221+ thread->ci->u.c.k = NULL;
1222 thread->ci->u.c.old_errfunc = 0;
1223- thread->ci->u.c.old_allowhook = 0;
1224-
1225- // TODO(unknown): Is this really right?
1226- if (thread->ci->callstatus & (CIST_YPCALL | CIST_YIELDED)) {
1227- thread->ci->u.c.ctx = READ_VALUE(int);
1228- LOCK(thread);
1229- unpersist(info); /* ... thread func? */
1230- UNLOCK(thread);
1231- if (lua_iscfunction(info->L, -1)) { /* ... thread func */
1232- thread->ci->u.c.k = lua_tocfunction(info->L, -1);
1233- }
1234- else {
1235- eris_error(info, "bad C continuation function");
1236- return; /* not reached */
1237- }
1238- lua_pop(info->L, 1); /* ... thread */
1239- }
1240- else {
1241- thread->ci->u.c.ctx = 0;
1242- thread->ci->u.c.k = NULL;
1243- }
1244+ thread->ci->u.c.ctx = 0;
1245 }
1246- LOCK(thread);
1247- poppath(info);
1248- UNLOCK(thread);
1249
1250 /* Read in value for check for next iteration. */
1251 if (READ_VALUE(uint8_t)) {
1252@@ -1904,8 +2016,8 @@
1253 eris_restorestackidx(thread, READ_VALUE(size_t)));
1254 o = eris_restorestack(thread, thread->ci->extra);
1255 validate(o, thread->top);
1256- if (eris_ttypenv(o) != LUA_TFUNCTION) {
1257- eris_error(info, "invalid callinfo");
1258+ if (eris_ttnov(o) != LUA_TFUNCTION) {
1259+ eris_error(info, ERIS_ERR_THREADCI);
1260 }
1261 }
1262 LOCK(thread);
1263@@ -1919,7 +2031,7 @@
1264 * functions using them having been unpersisted (they'll usually be in the
1265 * stack of the thread). For this reason we store all previous references to
1266 * the upvalue in a table that is returned when we try to unpersist an
1267- * upvalue, so that we can adjust these pointers in here. */
1268+ * upvalue, so that we can adjust these references in here. */
1269 LOCK(thread);
1270 pushpath(info, ".openupval");
1271 UNLOCK(thread);
1272@@ -1948,19 +2060,27 @@
1273 nuv = eris_findupval(thread, stk);
1274 UNLOCK(thread);
1275
1276- /* Then check if we need to patch some pointers. */
1277- lua_rawgeti(info->L, -1, 2); /* ... thread tbl upval/nil */
1278- if (!lua_isnil(info->L, -1)) { /* ... thread tbl upval */
1279+ /* Then check if we need to patch some references. */
1280+ lua_rawgeti(info->L, -1, UVTREF); /* ... thread tbl lcl/nil */
1281+ if (!lua_isnil(info->L, -1)) { /* ... thread tbl lcl */
1282 int i, n;
1283- eris_assert(lua_type(info->L, -1) == LUA_TLIGHTUSERDATA);
1284+ eris_assert(lua_type(info->L, -1) == LUA_TFUNCTION);
1285 /* Already exists, replace it. To do this we have to patch all the
1286- * pointers to the already existing one, which we added to the table in
1287- * u_closure, starting at index 3. */
1288+ * references to the already existing one, which we added to the table in
1289+ * u_closure. */
1290 lua_pop(info->L, 1); /* ... thread tbl */
1291- for (i = 3, n = luaL_len(info->L, -1); i <= n; ++i) {
1292- lua_rawgeti(info->L, -1, i); /* ... thread tbl upvalp */
1293- (*(UpVal**)lua_touserdata(info->L, -1)) = nuv;
1294- lua_pop(info->L, 1); /* ... thread tbl */
1295+ for (i = UVTREF, n = luaL_len(info->L, -1); i <= n; i += 2) {
1296+ LClosure *cl;
1297+ int nup;
1298+ lua_rawgeti(info->L, -1, i); /* ... thread tbl lcl */
1299+ cl = eris_clLvalue(info->L->top - 1);
1300+ lua_pop(info->L, 1); /* ... thread tbl */
1301+ lua_rawgeti(info->L, -1, i + 1); /* ... thread tbl nup */
1302+ nup = lua_tointeger(info->L, -1);
1303+ lua_pop(info->L, 1); /* ... thread tbl */
1304+ /* Open the upvalue by pointing to the stack and register in GC. */
1305+ cl->upvals[nup - 1] = nuv;
1306+ cl->upvals[nup - 1]->refcount++;
1307 }
1308 }
1309 else { /* ... thread tbl nil */
1310@@ -1970,8 +2090,6 @@
1311
1312 /* Store open upvalue in table for future references. */
1313 LOCK(thread);
1314- lua_pushlightuserdata(info->L, nuv); /* ... thread tbl upval */
1315- lua_rawseti(info->L, -2, 2); /* ... thread tbl */
1316 lua_pop(info->L, 1); /* ... thread */
1317 poppath(info);
1318 UNLOCK(thread);
1319@@ -1996,7 +2114,7 @@
1320 persist_typed(Info *info, int type) { /* perms reftbl ... obj */
1321 eris_ifassert(const int top = lua_gettop(info->L));
1322 if (info->level >= info->maxComplexity) {
1323- eris_error(info, "object too complex");
1324+ eris_error(info, ERIS_ERR_COMPLEXITY);
1325 }
1326 ++info->level;
1327
1328@@ -2033,7 +2151,7 @@
1329 p_upval(info);
1330 break;
1331 default:
1332- eris_error(info, "trying to persist unknown type");
1333+ eris_error(info, ERIS_ERR_TYPEP, type);
1334 } /* perms reftbl ... obj */
1335
1336 --info->level;
1337@@ -2130,13 +2248,14 @@
1338 if (lua_isnil(info->L, -1)) { /* perms reftbl ... nil */
1339 /* Since we may need permanent values to rebuild other structures, namely
1340 * closures and threads, we cannot allow perms to fail unpersisting. */
1341- eris_error(info, "bad permanent value (no value)");
1342+ eris_error(info, ERIS_ERR_SPER_UPERMNIL);
1343 }
1344 else if (lua_type(info->L, -1) != type) { /* perms reftbl ... :( */
1345 /* For the same reason that we cannot allow nil we must also require the
1346 * unpersisted value to be of the correct type. */
1347- eris_error(info, "bad permanent value (%s expected, got %s)",
1348- kTypenames[type], kTypenames[lua_type(info->L, -1)]);
1349+ const char *want = kTypenames[type];
1350+ const char *have = kTypenames[lua_type(info->L, -1)];
1351+ eris_error(info, ERIS_ERR_SPER_UPERM, want, have);
1352 } /* perms reftbl ... obj */
1353 /* Create the entry in the reftable. */
1354 lua_pushvalue(info->L, -1); /* perms reftbl ... obj obj */
1355@@ -2147,7 +2266,7 @@
1356 unpersist(Info *info) { /* perms reftbl ... */
1357 eris_ifassert(const int top = lua_gettop(info->L));
1358 if (info->level >= info->maxComplexity) {
1359- eris_error(info, "object too complex");
1360+ eris_error(info, ERIS_ERR_COMPLEXITY);
1361 }
1362 ++info->level;
1363
1364@@ -2158,7 +2277,7 @@
1365 const int reference = typeOrReference - ERIS_REFERENCE_OFFSET;
1366 lua_rawgeti(info->L, REFTIDX, reference); /* perms reftbl ud ... obj? */
1367 if (lua_isnil(info->L, -1)) { /* perms reftbl ud ... :( */
1368- eris_error(info, "invalid reference #%d", reference);
1369+ eris_error(info, ERIS_ERR_REF, reference);
1370 } /* perms reftbl ud ... obj */
1371 }
1372 else {
1373@@ -2201,7 +2320,7 @@
1374 u_permanent(info);
1375 break;
1376 default:
1377- eris_error(info, "trying to unpersist unknown type %d", type);
1378+ eris_error(info, ERIS_ERR_TYPEU, type);
1379 } /* perms reftbl ... obj? */
1380 }
1381 }
1382@@ -2289,6 +2408,7 @@
1383 WRITE_RAW(kHeader, HEADER_LENGTH);
1384 WRITE_VALUE(sizeof(lua_Number), uint8_t);
1385 WRITE_VALUE(kHeaderNumber, lua_Number);
1386+ WRITE_VALUE(sizeof(lua_Integer), uint8_t);
1387 WRITE_VALUE(sizeof(int), uint8_t);
1388 WRITE_VALUE(sizeof(size_t), uint8_t);
1389 }
1390@@ -2317,6 +2437,9 @@
1391 if (READ_VALUE(lua_Number) != kHeaderNumber) {
1392 luaL_error(info->L, "incompatible floating point representation");
1393 }
1394+ if (READ_VALUE(uint8_t) != sizeof(lua_Integer)) {
1395+ luaL_error(info->L, "incompatible integer type");
1396+ }
1397 info->u.upi.sizeof_int = READ_VALUE(uint8_t);
1398 info->u.upi.sizeof_size_t = READ_VALUE(uint8_t);
1399 }
1400@@ -2339,7 +2462,7 @@
1401
1402 if (get_setting(L, (void*)&kSettingMaxComplexity)) {
1403 /* perms buff rootobj value */
1404- info.maxComplexity = lua_tounsigned(L, -1);
1405+ info.maxComplexity = lua_tointeger(L, -1);
1406 lua_pop(L, 1); /* perms buff rootobj */
1407 }
1408 if (get_setting(L, (void*)&kSettingGeneratePath)) {
1409@@ -2399,7 +2522,7 @@
1410
1411 if (get_setting(L, (void*)&kSettingMaxComplexity)) {
1412 /* perms buff rootobj value */
1413- info.maxComplexity = lua_tounsigned(L, -1);
1414+ info.maxComplexity = lua_tointeger(L, -1);
1415 lua_pop(L, 1); /* perms buff rootobj */
1416 }
1417 if (get_setting(L, (void*)&kSettingGeneratePath)) {
1418@@ -2533,7 +2656,7 @@
1419 }
1420 else if (IS(kSettingMaxComplexity)) {
1421 if (!get_setting(L, (void*)&kSettingMaxComplexity)) {
1422- lua_pushunsigned(L, kMaxComplexity);
1423+ lua_pushinteger(L, kMaxComplexity);
1424 }
1425 }
1426 else {
1427@@ -2561,7 +2684,7 @@
1428 set_setting(L, (void*)&kSettingGeneratePath);
1429 }
1430 else if (IS(kSettingMaxComplexity)) {
1431- luaL_optunsigned(L, 2, 0);
1432+ luaL_optinteger(L, 2, 0);
1433 set_setting(L, (void*)&kSettingMaxComplexity);
1434 }
1435 else {
1436@@ -2621,6 +2744,8 @@
1437
1438 LUA_API void
1439 eris_persist(lua_State *L, int perms, int value) { /* ...? */
1440+ perms = lua_absindex(L, perms);
1441+ value = lua_absindex(L, value);
1442 eris_checkstack(L, 3);
1443 lua_pushcfunction(L, l_persist); /* ... l_persist */
1444 lua_pushvalue(L, perms); /* ... l_persist perms */
1445@@ -2630,6 +2755,8 @@
1446
1447 LUA_API void
1448 eris_unpersist(lua_State *L, int perms, int value) { /* ... */
1449+ perms = lua_absindex(L, perms);
1450+ value = lua_absindex(L, value);
1451 eris_checkstack(L, 3);
1452 lua_pushcfunction(L, l_unpersist); /* ... l_unpersist */
1453 lua_pushvalue(L, perms); /* ... l_unpersist perms */
1454@@ -2647,6 +2774,7 @@
1455
1456 LUA_API void
1457 eris_set_setting(lua_State *L, const char *name, int value) { /* ... */
1458+ value = lua_absindex(L, value);
1459 eris_checkstack(L, 3);
1460 lua_pushcfunction(L, l_settings); /* ... l_settings */
1461 lua_pushstring(L, name); /* ... l_settings name */
1462
1463=== modified file 'src/third_party/eris/eris.h'
1464--- src/third_party/eris/eris.h 2013-10-17 07:22:46 +0000
1465+++ src/third_party/eris/eris.h 2016-04-10 16:54:20 +0000
1466@@ -1,6 +1,6 @@
1467 /*
1468-Eris - Heavy-duty persistence for Lua 5.2.2 - Based on Pluto
1469-Copyright (c) 2013 by Florian Nuecke.
1470+Eris - Heavy-duty persistence for Lua 5.3.0 - Based on Pluto
1471+Copyright (c) 2013-2015 by Florian Nuecke.
1472
1473 Permission is hereby granted, free of charge, to any person obtaining a copy
1474 of this software and associated documentation files (the "Software"), to deal
1475@@ -26,6 +26,11 @@
1476 #ifndef ERIS_H
1477 #define ERIS_H
1478
1479+#define ERIS_VERSION_MAJOR "1"
1480+#define ERIS_VERSION_MINOR "1"
1481+#define ERIS_VERSION_NUM 101
1482+#define ERIS_VERSION_RELEASE "0"
1483+
1484 /*
1485 ** ==================================================================
1486 ** API
1487
1488=== modified file 'src/third_party/eris/lapi.c'
1489--- src/third_party/eris/lapi.c 2014-02-22 14:47:28 +0000
1490+++ src/third_party/eris/lapi.c 2016-04-10 16:54:20 +0000
1491@@ -1,16 +1,18 @@
1492 /*
1493-** $Id: lapi.c,v 2.171.1.1 2013/04/12 18:48:47 roberto Exp $
1494+** $Id: lapi.c,v 2.244 2014/12/26 14:43:45 roberto Exp $
1495 ** Lua API
1496 ** See Copyright Notice in lua.h
1497 */
1498
1499+#define lapi_c
1500+#define LUA_CORE
1501+
1502+#include "lprefix.h"
1503+
1504
1505 #include <stdarg.h>
1506 #include <string.h>
1507
1508-#define lapi_c
1509-#define LUA_CORE
1510-
1511 #include "lua.h"
1512
1513 #include "lapi.h"
1514@@ -43,32 +45,35 @@
1515 /* test for pseudo index */
1516 #define ispseudo(i) ((i) <= LUA_REGISTRYINDEX)
1517
1518+/* test for upvalue */
1519+#define isupvalue(i) ((i) < LUA_REGISTRYINDEX)
1520+
1521 /* test for valid but not pseudo index */
1522 #define isstackindex(i, o) (isvalid(o) && !ispseudo(i))
1523
1524-#define api_checkvalidindex(L, o) api_check(L, isvalid(o), "invalid index")
1525+#define api_checkvalidindex(o) api_check(isvalid(o), "invalid index")
1526
1527-#define api_checkstackindex(L, i, o) \
1528- api_check(L, isstackindex(i, o), "index not in the stack")
1529+#define api_checkstackindex(i, o) \
1530+ api_check(isstackindex(i, o), "index not in the stack")
1531
1532
1533 static TValue *index2addr (lua_State *L, int idx) {
1534 CallInfo *ci = L->ci;
1535 if (idx > 0) {
1536 TValue *o = ci->func + idx;
1537- api_check(L, idx <= ci->top - (ci->func + 1), "unacceptable index");
1538+ api_check(idx <= ci->top - (ci->func + 1), "unacceptable index");
1539 if (o >= L->top) return NONVALIDVALUE;
1540 else return o;
1541 }
1542 else if (!ispseudo(idx)) { /* negative index */
1543- api_check(L, idx != 0 && -idx <= L->top - (ci->func + 1), "invalid index");
1544+ api_check(idx != 0 && -idx <= L->top - (ci->func + 1), "invalid index");
1545 return L->top + idx;
1546 }
1547 else if (idx == LUA_REGISTRYINDEX)
1548 return &G(L)->l_registry;
1549 else { /* upvalues */
1550 idx = LUA_REGISTRYINDEX - idx;
1551- api_check(L, idx <= MAXUPVAL + 1, "upvalue index too large");
1552+ api_check(idx <= MAXUPVAL + 1, "upvalue index too large");
1553 if (ttislcf(ci->func)) /* light C function? */
1554 return NONVALIDVALUE; /* it has no upvalues */
1555 else {
1556@@ -89,21 +94,22 @@
1557 }
1558
1559
1560-LUA_API int lua_checkstack (lua_State *L, int size) {
1561+LUA_API int lua_checkstack (lua_State *L, int n) {
1562 int res;
1563 CallInfo *ci = L->ci;
1564 lua_lock(L);
1565- if (L->stack_last - L->top > size) /* stack large enough? */
1566+ api_check(n >= 0, "negative 'n'");
1567+ if (L->stack_last - L->top > n) /* stack large enough? */
1568 res = 1; /* yes; check is OK */
1569 else { /* no; need to grow stack */
1570 int inuse = cast_int(L->top - L->stack) + EXTRA_STACK;
1571- if (inuse > LUAI_MAXSTACK - size) /* can grow without overflow? */
1572+ if (inuse > LUAI_MAXSTACK - n) /* can grow without overflow? */
1573 res = 0; /* no */
1574 else /* try to grow stack */
1575- res = (luaD_rawrunprotected(L, &growstack, &size) == LUA_OK);
1576+ res = (luaD_rawrunprotected(L, &growstack, &n) == LUA_OK);
1577 }
1578- if (res && ci->top < L->top + size)
1579- ci->top = L->top + size; /* adjust frame top */
1580+ if (res && ci->top < L->top + n)
1581+ ci->top = L->top + n; /* adjust frame top */
1582 lua_unlock(L);
1583 return res;
1584 }
1585@@ -114,8 +120,8 @@
1586 if (from == to) return;
1587 lua_lock(to);
1588 api_checknelems(from, n);
1589- api_check(from, G(from) == G(to), "moving among independent states");
1590- api_check(from, to->ci->top - to->top >= n, "not enough elements to move");
1591+ api_check(G(from) == G(to), "moving among independent states");
1592+ api_check(to->ci->top - to->top >= n, "not enough elements to move");
1593 from->top -= n;
1594 for (i = 0; i < n; i++) {
1595 setobj2s(to, to->top++, from->top + i);
1596@@ -166,68 +172,63 @@
1597 StkId func = L->ci->func;
1598 lua_lock(L);
1599 if (idx >= 0) {
1600- api_check(L, idx <= L->stack_last - (func + 1), "new top too large");
1601+ api_check(idx <= L->stack_last - (func + 1), "new top too large");
1602 while (L->top < (func + 1) + idx)
1603 setnilvalue(L->top++);
1604 L->top = (func + 1) + idx;
1605 }
1606 else {
1607- api_check(L, -(idx+1) <= (L->top - (func + 1)), "invalid new top");
1608- L->top += idx+1; /* `subtract' index (index is negative) */
1609- }
1610- lua_unlock(L);
1611-}
1612-
1613-
1614-LUA_API void lua_remove (lua_State *L, int idx) {
1615- StkId p;
1616- lua_lock(L);
1617- p = index2addr(L, idx);
1618- api_checkstackindex(L, idx, p);
1619- while (++p < L->top) setobjs2s(L, p-1, p);
1620- L->top--;
1621- lua_unlock(L);
1622-}
1623-
1624-
1625-LUA_API void lua_insert (lua_State *L, int idx) {
1626- StkId p;
1627- StkId q;
1628- lua_lock(L);
1629- p = index2addr(L, idx);
1630- api_checkstackindex(L, idx, p);
1631- for (q = L->top; q > p; q--) /* use L->top as a temporary */
1632- setobjs2s(L, q, q - 1);
1633- setobjs2s(L, p, L->top);
1634- lua_unlock(L);
1635-}
1636-
1637-
1638-static void moveto (lua_State *L, TValue *fr, int idx) {
1639- TValue *to = index2addr(L, idx);
1640- api_checkvalidindex(L, to);
1641+ api_check(-(idx+1) <= (L->top - (func + 1)), "invalid new top");
1642+ L->top += idx+1; /* 'subtract' index (index is negative) */
1643+ }
1644+ lua_unlock(L);
1645+}
1646+
1647+
1648+/*
1649+** Reverse the stack segment from 'from' to 'to'
1650+** (auxiliary to 'lua_rotate')
1651+*/
1652+static void reverse (lua_State *L, StkId from, StkId to) {
1653+ for (; from < to; from++, to--) {
1654+ TValue temp;
1655+ setobj(L, &temp, from);
1656+ setobjs2s(L, from, to);
1657+ setobj2s(L, to, &temp);
1658+ }
1659+}
1660+
1661+
1662+/*
1663+** Let x = AB, where A is a prefix of length 'n'. Then,
1664+** rotate x n == BA. But BA == (A^r . B^r)^r.
1665+*/
1666+LUA_API void lua_rotate (lua_State *L, int idx, int n) {
1667+ StkId p, t, m;
1668+ lua_lock(L);
1669+ t = L->top - 1; /* end of stack segment being rotated */
1670+ p = index2addr(L, idx); /* start of segment */
1671+ api_checkstackindex(idx, p);
1672+ api_check((n >= 0 ? n : -n) <= (t - p + 1), "invalid 'n'");
1673+ m = (n >= 0 ? t - n : p - n - 1); /* end of prefix */
1674+ reverse(L, p, m); /* reverse the prefix with length 'n' */
1675+ reverse(L, m + 1, t); /* reverse the suffix */
1676+ reverse(L, p, t); /* reverse the entire segment */
1677+ lua_unlock(L);
1678+}
1679+
1680+
1681+LUA_API void lua_copy (lua_State *L, int fromidx, int toidx) {
1682+ TValue *fr, *to;
1683+ lua_lock(L);
1684+ fr = index2addr(L, fromidx);
1685+ to = index2addr(L, toidx);
1686+ api_checkvalidindex(to);
1687 setobj(L, to, fr);
1688- if (idx < LUA_REGISTRYINDEX) /* function upvalue? */
1689+ if (isupvalue(toidx)) /* function upvalue? */
1690 luaC_barrier(L, clCvalue(L->ci->func), fr);
1691 /* LUA_REGISTRYINDEX does not need gc barrier
1692 (collector revisits it before finishing collection) */
1693-}
1694-
1695-
1696-LUA_API void lua_replace (lua_State *L, int idx) {
1697- lua_lock(L);
1698- api_checknelems(L, 1);
1699- moveto(L, L->top - 1, idx);
1700- L->top--;
1701- lua_unlock(L);
1702-}
1703-
1704-
1705-LUA_API void lua_copy (lua_State *L, int fromidx, int toidx) {
1706- TValue *fr;
1707- lua_lock(L);
1708- fr = index2addr(L, fromidx);
1709- moveto(L, fr, toidx);
1710 lua_unlock(L);
1711 }
1712
1713@@ -248,12 +249,13 @@
1714
1715 LUA_API int lua_type (lua_State *L, int idx) {
1716 StkId o = index2addr(L, idx);
1717- return (isvalid(o) ? ttypenv(o) : LUA_TNONE);
1718+ return (isvalid(o) ? ttnov(o) : LUA_TNONE);
1719 }
1720
1721
1722 LUA_API const char *lua_typename (lua_State *L, int t) {
1723 UNUSED(L);
1724+ api_check(LUA_TNONE <= t && t < LUA_NUMTAGS, "invalid tag");
1725 return ttypename(t);
1726 }
1727
1728@@ -264,22 +266,28 @@
1729 }
1730
1731
1732+LUA_API int lua_isinteger (lua_State *L, int idx) {
1733+ StkId o = index2addr(L, idx);
1734+ return ttisinteger(o);
1735+}
1736+
1737+
1738 LUA_API int lua_isnumber (lua_State *L, int idx) {
1739- TValue n;
1740+ lua_Number n;
1741 const TValue *o = index2addr(L, idx);
1742 return tonumber(o, &n);
1743 }
1744
1745
1746 LUA_API int lua_isstring (lua_State *L, int idx) {
1747- int t = lua_type(L, idx);
1748- return (t == LUA_TSTRING || t == LUA_TNUMBER);
1749+ const TValue *o = index2addr(L, idx);
1750+ return (ttisstring(o) || cvt2str(o));
1751 }
1752
1753
1754 LUA_API int lua_isuserdata (lua_State *L, int idx) {
1755 const TValue *o = index2addr(L, idx);
1756- return (ttisuserdata(o) || ttislightuserdata(o));
1757+ return (ttisfulluserdata(o) || ttislightuserdata(o));
1758 }
1759
1760
1761@@ -291,24 +299,17 @@
1762
1763
1764 LUA_API void lua_arith (lua_State *L, int op) {
1765- StkId o1; /* 1st operand */
1766- StkId o2; /* 2nd operand */
1767 lua_lock(L);
1768- if (op != LUA_OPUNM) /* all other operations expect two operands */
1769- api_checknelems(L, 2);
1770- else { /* for unary minus, add fake 2nd operand */
1771+ if (op != LUA_OPUNM && op != LUA_OPBNOT)
1772+ api_checknelems(L, 2); /* all other operations expect two operands */
1773+ else { /* for unary operations, add fake 2nd operand */
1774 api_checknelems(L, 1);
1775 setobjs2s(L, L->top, L->top - 1);
1776 L->top++;
1777 }
1778- o1 = L->top - 2;
1779- o2 = L->top - 1;
1780- if (ttisnumber(o1) && ttisnumber(o2)) {
1781- setnvalue(o1, luaO_arith(op, nvalue(o1), nvalue(o2)));
1782- }
1783- else
1784- luaV_arith(L, o1, o1, o2, cast(TMS, op - LUA_OPADD + TM_ADD));
1785- L->top--;
1786+ /* first operand at top - 2, second at top - 1; result go to top - 2 */
1787+ luaO_arith(L, op, L->top - 2, L->top - 1, L->top - 2);
1788+ L->top--; /* remove second operand */
1789 lua_unlock(L);
1790 }
1791
1792@@ -321,10 +322,10 @@
1793 o2 = index2addr(L, index2);
1794 if (isvalid(o1) && isvalid(o2)) {
1795 switch (op) {
1796- case LUA_OPEQ: i = equalobj(L, o1, o2); break;
1797+ case LUA_OPEQ: i = luaV_equalobj(L, o1, o2); break;
1798 case LUA_OPLT: i = luaV_lessthan(L, o1, o2); break;
1799 case LUA_OPLE: i = luaV_lessequal(L, o1, o2); break;
1800- default: api_check(L, 0, "invalid option");
1801+ default: api_check(0, "invalid option");
1802 }
1803 }
1804 lua_unlock(L);
1805@@ -332,51 +333,33 @@
1806 }
1807
1808
1809-LUA_API lua_Number lua_tonumberx (lua_State *L, int idx, int *isnum) {
1810- TValue n;
1811- const TValue *o = index2addr(L, idx);
1812- if (tonumber(o, &n)) {
1813- if (isnum) *isnum = 1;
1814- return nvalue(o);
1815- }
1816- else {
1817- if (isnum) *isnum = 0;
1818- return 0;
1819- }
1820-}
1821-
1822-
1823-LUA_API lua_Integer lua_tointegerx (lua_State *L, int idx, int *isnum) {
1824- TValue n;
1825- const TValue *o = index2addr(L, idx);
1826- if (tonumber(o, &n)) {
1827- lua_Integer res;
1828- lua_Number num = nvalue(o);
1829- lua_number2integer(res, num);
1830- if (isnum) *isnum = 1;
1831- return res;
1832- }
1833- else {
1834- if (isnum) *isnum = 0;
1835- return 0;
1836- }
1837-}
1838-
1839-
1840-LUA_API lua_Unsigned lua_tounsignedx (lua_State *L, int idx, int *isnum) {
1841- TValue n;
1842- const TValue *o = index2addr(L, idx);
1843- if (tonumber(o, &n)) {
1844- lua_Unsigned res;
1845- lua_Number num = nvalue(o);
1846- lua_number2unsigned(res, num);
1847- if (isnum) *isnum = 1;
1848- return res;
1849- }
1850- else {
1851- if (isnum) *isnum = 0;
1852- return 0;
1853- }
1854+LUA_API size_t lua_stringtonumber (lua_State *L, const char *s) {
1855+ size_t sz = luaO_str2num(s, L->top);
1856+ if (sz != 0)
1857+ api_incr_top(L);
1858+ return sz;
1859+}
1860+
1861+
1862+LUA_API lua_Number lua_tonumberx (lua_State *L, int idx, int *pisnum) {
1863+ lua_Number n;
1864+ const TValue *o = index2addr(L, idx);
1865+ int isnum = tonumber(o, &n);
1866+ if (!isnum)
1867+ n = 0; /* call to 'tonumber' may change 'n' even if it fails */
1868+ if (pisnum) *pisnum = isnum;
1869+ return n;
1870+}
1871+
1872+
1873+LUA_API lua_Integer lua_tointegerx (lua_State *L, int idx, int *pisnum) {
1874+ lua_Integer res;
1875+ const TValue *o = index2addr(L, idx);
1876+ int isnum = tointeger(o, &res);
1877+ if (!isnum)
1878+ res = 0; /* call to 'tointeger' may change 'n' even if it fails */
1879+ if (pisnum) *pisnum = isnum;
1880+ return res;
1881 }
1882
1883
1884@@ -389,14 +372,14 @@
1885 LUA_API const char *lua_tolstring (lua_State *L, int idx, size_t *len) {
1886 StkId o = index2addr(L, idx);
1887 if (!ttisstring(o)) {
1888- lua_lock(L); /* `luaV_tostring' may create a new string */
1889- if (!luaV_tostring(L, o)) { /* conversion failed? */
1890+ if (!cvt2str(o)) { /* not convertible? */
1891 if (len != NULL) *len = 0;
1892- lua_unlock(L);
1893 return NULL;
1894 }
1895+ lua_lock(L); /* 'luaO_tostring' may create a new string */
1896 luaC_checkGC(L);
1897 o = index2addr(L, idx); /* previous call may reallocate the stack */
1898+ luaO_tostring(L, o);
1899 lua_unlock(L);
1900 }
1901 if (len != NULL) *len = tsvalue(o)->len;
1902@@ -406,7 +389,7 @@
1903
1904 LUA_API size_t lua_rawlen (lua_State *L, int idx) {
1905 StkId o = index2addr(L, idx);
1906- switch (ttypenv(o)) {
1907+ switch (ttnov(o)) {
1908 case LUA_TSTRING: return tsvalue(o)->len;
1909 case LUA_TUSERDATA: return uvalue(o)->len;
1910 case LUA_TTABLE: return luaH_getn(hvalue(o));
1911@@ -426,8 +409,8 @@
1912
1913 LUA_API void *lua_touserdata (lua_State *L, int idx) {
1914 StkId o = index2addr(L, idx);
1915- switch (ttypenv(o)) {
1916- case LUA_TUSERDATA: return (rawuvalue(o) + 1);
1917+ switch (ttnov(o)) {
1918+ case LUA_TUSERDATA: return getudatamem(uvalue(o));
1919 case LUA_TLIGHTUSERDATA: return pvalue(o);
1920 default: return NULL;
1921 }
1922@@ -472,9 +455,7 @@
1923
1924 LUA_API void lua_pushnumber (lua_State *L, lua_Number n) {
1925 lua_lock(L);
1926- setnvalue(L->top, n);
1927- luai_checknum(L, L->top,
1928- luaG_runerror(L, "C API - attempt to push a signaling NaN"));
1929+ setfltvalue(L->top, n);
1930 api_incr_top(L);
1931 lua_unlock(L);
1932 }
1933@@ -482,17 +463,7 @@
1934
1935 LUA_API void lua_pushinteger (lua_State *L, lua_Integer n) {
1936 lua_lock(L);
1937- setnvalue(L->top, cast_num(n));
1938- api_incr_top(L);
1939- lua_unlock(L);
1940-}
1941-
1942-
1943-LUA_API void lua_pushunsigned (lua_State *L, lua_Unsigned u) {
1944- lua_Number n;
1945- lua_lock(L);
1946- n = lua_unsigned2number(u);
1947- setnvalue(L->top, n);
1948+ setivalue(L->top, n);
1949 api_incr_top(L);
1950 lua_unlock(L);
1951 }
1952@@ -558,15 +529,17 @@
1953 setfvalue(L->top, fn);
1954 }
1955 else {
1956- Closure *cl;
1957+ CClosure *cl;
1958 api_checknelems(L, n);
1959- api_check(L, n <= MAXUPVAL, "upvalue index too large");
1960+ api_check(n <= MAXUPVAL, "upvalue index too large");
1961 luaC_checkGC(L);
1962 cl = luaF_newCclosure(L, n);
1963- cl->c.f = fn;
1964+ cl->f = fn;
1965 L->top -= n;
1966- while (n--)
1967- setobj2n(L, &cl->c.upvalue[n], L->top + n);
1968+ while (n--) {
1969+ setobj2n(L, &cl->upvalue[n], L->top + n);
1970+ /* does not need barrier because closure is white */
1971+ }
1972 setclCvalue(L, L->top, cl);
1973 }
1974 api_incr_top(L);
1975@@ -605,27 +578,29 @@
1976 */
1977
1978
1979-LUA_API void lua_getglobal (lua_State *L, const char *var) {
1980+LUA_API int lua_getglobal (lua_State *L, const char *name) {
1981 Table *reg = hvalue(&G(L)->l_registry);
1982 const TValue *gt; /* global table */
1983 lua_lock(L);
1984 gt = luaH_getint(reg, LUA_RIDX_GLOBALS);
1985- setsvalue2s(L, L->top++, luaS_new(L, var));
1986+ setsvalue2s(L, L->top++, luaS_new(L, name));
1987 luaV_gettable(L, gt, L->top - 1, L->top - 1);
1988 lua_unlock(L);
1989+ return ttnov(L->top - 1);
1990 }
1991
1992
1993-LUA_API void lua_gettable (lua_State *L, int idx) {
1994+LUA_API int lua_gettable (lua_State *L, int idx) {
1995 StkId t;
1996 lua_lock(L);
1997 t = index2addr(L, idx);
1998 luaV_gettable(L, t, L->top - 1, L->top - 1);
1999 lua_unlock(L);
2000+ return ttnov(L->top - 1);
2001 }
2002
2003
2004-LUA_API void lua_getfield (lua_State *L, int idx, const char *k) {
2005+LUA_API int lua_getfield (lua_State *L, int idx, const char *k) {
2006 StkId t;
2007 lua_lock(L);
2008 t = index2addr(L, idx);
2009@@ -633,40 +608,56 @@
2010 api_incr_top(L);
2011 luaV_gettable(L, t, L->top - 1, L->top - 1);
2012 lua_unlock(L);
2013-}
2014-
2015-
2016-LUA_API void lua_rawget (lua_State *L, int idx) {
2017- StkId t;
2018- lua_lock(L);
2019- t = index2addr(L, idx);
2020- api_check(L, ttistable(t), "table expected");
2021+ return ttnov(L->top - 1);
2022+}
2023+
2024+
2025+LUA_API int lua_geti (lua_State *L, int idx, lua_Integer n) {
2026+ StkId t;
2027+ lua_lock(L);
2028+ t = index2addr(L, idx);
2029+ setivalue(L->top, n);
2030+ api_incr_top(L);
2031+ luaV_gettable(L, t, L->top - 1, L->top - 1);
2032+ lua_unlock(L);
2033+ return ttnov(L->top - 1);
2034+}
2035+
2036+
2037+LUA_API int lua_rawget (lua_State *L, int idx) {
2038+ StkId t;
2039+ lua_lock(L);
2040+ t = index2addr(L, idx);
2041+ api_check(ttistable(t), "table expected");
2042 setobj2s(L, L->top - 1, luaH_get(hvalue(t), L->top - 1));
2043 lua_unlock(L);
2044+ return ttnov(L->top - 1);
2045 }
2046
2047
2048-LUA_API void lua_rawgeti (lua_State *L, int idx, int n) {
2049+LUA_API int lua_rawgeti (lua_State *L, int idx, lua_Integer n) {
2050 StkId t;
2051 lua_lock(L);
2052 t = index2addr(L, idx);
2053- api_check(L, ttistable(t), "table expected");
2054+ api_check(ttistable(t), "table expected");
2055 setobj2s(L, L->top, luaH_getint(hvalue(t), n));
2056 api_incr_top(L);
2057 lua_unlock(L);
2058+ return ttnov(L->top - 1);
2059 }
2060
2061
2062-LUA_API void lua_rawgetp (lua_State *L, int idx, const void *p) {
2063+LUA_API int lua_rawgetp (lua_State *L, int idx, const void *p) {
2064 StkId t;
2065 TValue k;
2066 lua_lock(L);
2067 t = index2addr(L, idx);
2068- api_check(L, ttistable(t), "table expected");
2069+ api_check(ttistable(t), "table expected");
2070 setpvalue(&k, cast(void *, p));
2071 setobj2s(L, L->top, luaH_get(hvalue(t), &k));
2072 api_incr_top(L);
2073 lua_unlock(L);
2074+ return ttnov(L->top - 1);
2075 }
2076
2077
2078@@ -685,11 +676,11 @@
2079
2080 LUA_API int lua_getmetatable (lua_State *L, int objindex) {
2081 const TValue *obj;
2082- Table *mt = NULL;
2083- int res;
2084+ Table *mt;
2085+ int res = 0;
2086 lua_lock(L);
2087 obj = index2addr(L, objindex);
2088- switch (ttypenv(obj)) {
2089+ switch (ttnov(obj)) {
2090 case LUA_TTABLE:
2091 mt = hvalue(obj)->metatable;
2092 break;
2093@@ -697,12 +688,10 @@
2094 mt = uvalue(obj)->metatable;
2095 break;
2096 default:
2097- mt = G(L)->mt[ttypenv(obj)];
2098+ mt = G(L)->mt[ttnov(obj)];
2099 break;
2100 }
2101- if (mt == NULL)
2102- res = 0;
2103- else {
2104+ if (mt != NULL) {
2105 sethvalue(L, L->top, mt);
2106 api_incr_top(L);
2107 res = 1;
2108@@ -712,17 +701,15 @@
2109 }
2110
2111
2112-LUA_API void lua_getuservalue (lua_State *L, int idx) {
2113+LUA_API int lua_getuservalue (lua_State *L, int idx) {
2114 StkId o;
2115 lua_lock(L);
2116 o = index2addr(L, idx);
2117- api_check(L, ttisuserdata(o), "userdata expected");
2118- if (uvalue(o)->env) {
2119- sethvalue(L, L->top, uvalue(o)->env);
2120- } else
2121- setnilvalue(L->top);
2122+ api_check(ttisfulluserdata(o), "full userdata expected");
2123+ getuservalue(L, uvalue(o), L->top);
2124 api_incr_top(L);
2125 lua_unlock(L);
2126+ return ttnov(L->top - 1);
2127 }
2128
2129
2130@@ -731,13 +718,13 @@
2131 */
2132
2133
2134-LUA_API void lua_setglobal (lua_State *L, const char *var) {
2135+LUA_API void lua_setglobal (lua_State *L, const char *name) {
2136 Table *reg = hvalue(&G(L)->l_registry);
2137 const TValue *gt; /* global table */
2138 lua_lock(L);
2139 api_checknelems(L, 1);
2140 gt = luaH_getint(reg, LUA_RIDX_GLOBALS);
2141- setsvalue2s(L, L->top++, luaS_new(L, var));
2142+ setsvalue2s(L, L->top++, luaS_new(L, name));
2143 luaV_settable(L, gt, L->top - 1, L->top - 2);
2144 L->top -= 2; /* pop value and key */
2145 lua_unlock(L);
2146@@ -767,43 +754,61 @@
2147 }
2148
2149
2150+LUA_API void lua_seti (lua_State *L, int idx, lua_Integer n) {
2151+ StkId t;
2152+ lua_lock(L);
2153+ api_checknelems(L, 1);
2154+ t = index2addr(L, idx);
2155+ setivalue(L->top++, n);
2156+ luaV_settable(L, t, L->top - 1, L->top - 2);
2157+ L->top -= 2; /* pop value and key */
2158+ lua_unlock(L);
2159+}
2160+
2161+
2162 LUA_API void lua_rawset (lua_State *L, int idx) {
2163- StkId t;
2164+ StkId o;
2165+ Table *t;
2166 lua_lock(L);
2167 api_checknelems(L, 2);
2168- t = index2addr(L, idx);
2169- api_check(L, ttistable(t), "table expected");
2170- setobj2t(L, luaH_set(L, hvalue(t), L->top-2), L->top-1);
2171- invalidateTMcache(hvalue(t));
2172- luaC_barrierback(L, gcvalue(t), L->top-1);
2173+ o = index2addr(L, idx);
2174+ api_check(ttistable(o), "table expected");
2175+ t = hvalue(o);
2176+ setobj2t(L, luaH_set(L, t, L->top-2), L->top-1);
2177+ invalidateTMcache(t);
2178+ luaC_barrierback(L, t, L->top-1);
2179 L->top -= 2;
2180 lua_unlock(L);
2181 }
2182
2183
2184-LUA_API void lua_rawseti (lua_State *L, int idx, int n) {
2185- StkId t;
2186+LUA_API void lua_rawseti (lua_State *L, int idx, lua_Integer n) {
2187+ StkId o;
2188+ Table *t;
2189 lua_lock(L);
2190 api_checknelems(L, 1);
2191- t = index2addr(L, idx);
2192- api_check(L, ttistable(t), "table expected");
2193- luaH_setint(L, hvalue(t), n, L->top - 1);
2194- luaC_barrierback(L, gcvalue(t), L->top-1);
2195+ o = index2addr(L, idx);
2196+ api_check(ttistable(o), "table expected");
2197+ t = hvalue(o);
2198+ luaH_setint(L, t, n, L->top - 1);
2199+ luaC_barrierback(L, t, L->top-1);
2200 L->top--;
2201 lua_unlock(L);
2202 }
2203
2204
2205 LUA_API void lua_rawsetp (lua_State *L, int idx, const void *p) {
2206- StkId t;
2207+ StkId o;
2208+ Table *t;
2209 TValue k;
2210 lua_lock(L);
2211 api_checknelems(L, 1);
2212- t = index2addr(L, idx);
2213- api_check(L, ttistable(t), "table expected");
2214+ o = index2addr(L, idx);
2215+ api_check(ttistable(o), "table expected");
2216+ t = hvalue(o);
2217 setpvalue(&k, cast(void *, p));
2218- setobj2t(L, luaH_set(L, hvalue(t), &k), L->top - 1);
2219- luaC_barrierback(L, gcvalue(t), L->top - 1);
2220+ setobj2t(L, luaH_set(L, t, &k), L->top - 1);
2221+ luaC_barrierback(L, t, L->top - 1);
2222 L->top--;
2223 lua_unlock(L);
2224 }
2225@@ -818,14 +823,14 @@
2226 if (ttisnil(L->top - 1))
2227 mt = NULL;
2228 else {
2229- api_check(L, ttistable(L->top - 1), "table expected");
2230+ api_check(ttistable(L->top - 1), "table expected");
2231 mt = hvalue(L->top - 1);
2232 }
2233- switch (ttypenv(obj)) {
2234+ switch (ttnov(obj)) {
2235 case LUA_TTABLE: {
2236 hvalue(obj)->metatable = mt;
2237 if (mt) {
2238- luaC_objbarrierback(L, gcvalue(obj), mt);
2239+ luaC_objbarrier(L, gcvalue(obj), mt);
2240 luaC_checkfinalizer(L, gcvalue(obj), mt);
2241 }
2242 break;
2243@@ -833,13 +838,13 @@
2244 case LUA_TUSERDATA: {
2245 uvalue(obj)->metatable = mt;
2246 if (mt) {
2247- luaC_objbarrier(L, rawuvalue(obj), mt);
2248+ luaC_objbarrier(L, uvalue(obj), mt);
2249 luaC_checkfinalizer(L, gcvalue(obj), mt);
2250 }
2251 break;
2252 }
2253 default: {
2254- G(L)->mt[ttypenv(obj)] = mt;
2255+ G(L)->mt[ttnov(obj)] = mt;
2256 break;
2257 }
2258 }
2259@@ -854,46 +859,32 @@
2260 lua_lock(L);
2261 api_checknelems(L, 1);
2262 o = index2addr(L, idx);
2263- api_check(L, ttisuserdata(o), "userdata expected");
2264- if (ttisnil(L->top - 1))
2265- uvalue(o)->env = NULL;
2266- else {
2267- api_check(L, ttistable(L->top - 1), "table expected");
2268- uvalue(o)->env = hvalue(L->top - 1);
2269- luaC_objbarrier(L, gcvalue(o), hvalue(L->top - 1));
2270- }
2271+ api_check(ttisfulluserdata(o), "full userdata expected");
2272+ setuservalue(L, uvalue(o), L->top - 1);
2273+ luaC_barrier(L, gcvalue(o), L->top - 1);
2274 L->top--;
2275 lua_unlock(L);
2276 }
2277
2278
2279 /*
2280-** `load' and `call' functions (run Lua code)
2281+** 'load' and 'call' functions (run Lua code)
2282 */
2283
2284
2285 #define checkresults(L,na,nr) \
2286- api_check(L, (nr) == LUA_MULTRET || (L->ci->top - L->top >= (nr) - (na)), \
2287+ api_check((nr) == LUA_MULTRET || (L->ci->top - L->top >= (nr) - (na)), \
2288 "results from function overflow current stack size")
2289
2290
2291-LUA_API int lua_getctx (lua_State *L, int *ctx) {
2292- if (L->ci->callstatus & CIST_YIELDED) {
2293- if (ctx) *ctx = L->ci->u.c.ctx;
2294- return L->ci->u.c.status;
2295- }
2296- else return LUA_OK;
2297-}
2298-
2299-
2300-LUA_API void lua_callk (lua_State *L, int nargs, int nresults, int ctx,
2301- lua_CFunction k) {
2302+LUA_API void lua_callk (lua_State *L, int nargs, int nresults,
2303+ lua_KContext ctx, lua_KFunction k) {
2304 StkId func;
2305 lua_lock(L);
2306- api_check(L, k == NULL || !isLua(L->ci),
2307+ api_check(k == NULL || !isLua(L->ci),
2308 "cannot use continuations inside hooks");
2309 api_checknelems(L, nargs+1);
2310- api_check(L, L->status == LUA_OK, "cannot do calls on non-normal thread");
2311+ api_check(L->status == LUA_OK, "cannot do calls on non-normal thread");
2312 checkresults(L, nargs, nresults);
2313 func = L->top - (nargs+1);
2314 if (k != NULL && L->nny == 0) { /* need to prepare continuation? */
2315@@ -912,7 +903,7 @@
2316 /*
2317 ** Execute a protected call.
2318 */
2319-struct CallS { /* data to `f_call' */
2320+struct CallS { /* data to 'f_call' */
2321 StkId func;
2322 int nresults;
2323 };
2324@@ -926,21 +917,21 @@
2325
2326
2327 LUA_API int lua_pcallk (lua_State *L, int nargs, int nresults, int errfunc,
2328- int ctx, lua_CFunction k) {
2329+ lua_KContext ctx, lua_KFunction k) {
2330 struct CallS c;
2331 int status;
2332 ptrdiff_t func;
2333 lua_lock(L);
2334- api_check(L, k == NULL || !isLua(L->ci),
2335+ api_check(k == NULL || !isLua(L->ci),
2336 "cannot use continuations inside hooks");
2337 api_checknelems(L, nargs+1);
2338- api_check(L, L->status == LUA_OK, "cannot do calls on non-normal thread");
2339+ api_check(L->status == LUA_OK, "cannot do calls on non-normal thread");
2340 checkresults(L, nargs, nresults);
2341 if (errfunc == 0)
2342 func = 0;
2343 else {
2344 StkId o = index2addr(L, errfunc);
2345- api_checkstackindex(L, errfunc, o);
2346+ api_checkstackindex(errfunc, o);
2347 func = savestack(L, o);
2348 }
2349 c.func = L->top - (nargs+1); /* function to be called */
2350@@ -954,11 +945,10 @@
2351 ci->u.c.ctx = ctx; /* save context */
2352 /* save information for error recovery */
2353 ci->extra = savestack(L, c.func);
2354- ci->u.c.old_allowhook = L->allowhook;
2355 ci->u.c.old_errfunc = L->errfunc;
2356 L->errfunc = func;
2357- /* mark that function may do error recovery */
2358- ci->callstatus |= CIST_YPCALL;
2359+ setoah(ci->callstatus, L->allowhook); /* save value of 'allowhook' */
2360+ ci->callstatus |= CIST_YPCALL; /* function can do error recovery */
2361 luaD_call(L, c.func, nresults, 1); /* do the call */
2362 ci->callstatus &= ~CIST_YPCALL;
2363 L->errfunc = ci->u.c.old_errfunc;
2364@@ -980,13 +970,13 @@
2365 status = luaD_protectedparser(L, &z, chunkname, mode);
2366 if (status == LUA_OK) { /* no errors? */
2367 LClosure *f = clLvalue(L->top - 1); /* get newly created function */
2368- if (f->nupvalues == 1) { /* does it have one upvalue? */
2369+ if (f->nupvalues >= 1) { /* does it have an upvalue? */
2370 /* get global table from registry */
2371 Table *reg = hvalue(&G(L)->l_registry);
2372 const TValue *gt = luaH_getint(reg, LUA_RIDX_GLOBALS);
2373 /* set global table as 1st upvalue of 'f' (may be LUA_ENV) */
2374 setobj(L, f->upvals[0]->v, gt);
2375- luaC_barrier(L, f->upvals[0], gt);
2376+ luaC_upvalbarrier(L, f->upvals[0]);
2377 }
2378 }
2379 lua_unlock(L);
2380@@ -994,14 +984,14 @@
2381 }
2382
2383
2384-LUA_API int lua_dump (lua_State *L, lua_Writer writer, void *data) {
2385+LUA_API int lua_dump (lua_State *L, lua_Writer writer, void *data, int strip) {
2386 int status;
2387 TValue *o;
2388 lua_lock(L);
2389 api_checknelems(L, 1);
2390 o = L->top - 1;
2391 if (isLfunction(o))
2392- status = luaU_dump(L, getproto(o), writer, data, 0);
2393+ status = luaU_dump(L, getproto(o), writer, data, strip);
2394 else
2395 status = 1;
2396 lua_unlock(L);
2397@@ -1047,19 +1037,21 @@
2398 break;
2399 }
2400 case LUA_GCSTEP: {
2401- if (g->gckind == KGC_GEN) { /* generational mode? */
2402- res = (g->GCestimate == 0); /* true if it will do major collection */
2403- luaC_forcestep(L); /* do a single step */
2404- }
2405- else {
2406- lu_mem debt = cast(lu_mem, data) * 1024 - GCSTEPSIZE;
2407- if (g->gcrunning)
2408- debt += g->GCdebt; /* include current debt */
2409- luaE_setdebt(g, debt);
2410- luaC_forcestep(L);
2411- if (g->gcstate == GCSpause) /* end of cycle? */
2412- res = 1; /* signal it */
2413- }
2414+ l_mem debt = 1; /* =1 to signal that it did an actual step */
2415+ int oldrunning = g->gcrunning;
2416+ g->gcrunning = 1; /* allow GC to run */
2417+ if (data == 0) {
2418+ luaE_setdebt(g, -GCSTEPSIZE); /* to do a "small" step */
2419+ luaC_step(L);
2420+ }
2421+ else { /* add 'data' to total debt */
2422+ debt = cast(l_mem, data) * 1024 + g->GCdebt;
2423+ luaE_setdebt(g, debt);
2424+ luaC_checkGC(L);
2425+ }
2426+ g->gcrunning = oldrunning; /* restore previous state */
2427+ if (debt > 0 && g->gcstate == GCSpause) /* end of cycle? */
2428+ res = 1; /* signal it */
2429 break;
2430 }
2431 case LUA_GCSETPAUSE: {
2432@@ -1067,13 +1059,9 @@
2433 g->gcpause = data;
2434 break;
2435 }
2436- case LUA_GCSETMAJORINC: {
2437- res = g->gcmajorinc;
2438- g->gcmajorinc = data;
2439- break;
2440- }
2441 case LUA_GCSETSTEPMUL: {
2442 res = g->gcstepmul;
2443+ if (data < 40) data = 40; /* avoid ridiculous low values (and 0) */
2444 g->gcstepmul = data;
2445 break;
2446 }
2447@@ -1081,14 +1069,6 @@
2448 res = g->gcrunning;
2449 break;
2450 }
2451- case LUA_GCGEN: { /* change collector to generational mode */
2452- luaC_changemode(L, KGC_GEN);
2453- break;
2454- }
2455- case LUA_GCINC: { /* change collector to incremental mode */
2456- luaC_changemode(L, KGC_NORMAL);
2457- break;
2458- }
2459 default: res = -1; /* invalid option */
2460 }
2461 lua_unlock(L);
2462@@ -1116,7 +1096,7 @@
2463 int more;
2464 lua_lock(L);
2465 t = index2addr(L, idx);
2466- api_check(L, ttistable(t), "table expected");
2467+ api_check(ttistable(t), "table expected");
2468 more = luaH_next(L, hvalue(t), L->top - 1);
2469 if (more) {
2470 api_incr_top(L);
2471@@ -1176,23 +1156,23 @@
2472 Udata *u;
2473 lua_lock(L);
2474 luaC_checkGC(L);
2475- u = luaS_newudata(L, size, NULL);
2476+ u = luaS_newudata(L, size);
2477 setuvalue(L, L->top, u);
2478 api_incr_top(L);
2479 lua_unlock(L);
2480- return u + 1;
2481+ return getudatamem(u);
2482 }
2483
2484
2485
2486 static const char *aux_upvalue (StkId fi, int n, TValue **val,
2487- GCObject **owner) {
2488+ CClosure **owner, UpVal **uv) {
2489 switch (ttype(fi)) {
2490 case LUA_TCCL: { /* C closure */
2491 CClosure *f = clCvalue(fi);
2492 if (!(1 <= n && n <= f->nupvalues)) return NULL;
2493 *val = &f->upvalue[n-1];
2494- if (owner) *owner = obj2gco(f);
2495+ if (owner) *owner = f;
2496 return "";
2497 }
2498 case LUA_TLCL: { /* Lua closure */
2499@@ -1201,9 +1181,9 @@
2500 Proto *p = f->p;
2501 if (!(1 <= n && n <= p->sizeupvalues)) return NULL;
2502 *val = f->upvals[n-1]->v;
2503- if (owner) *owner = obj2gco(f->upvals[n - 1]);
2504+ if (uv) *uv = f->upvals[n - 1];
2505 name = p->upvalues[n-1].name;
2506- return (name == NULL) ? "" : getstr(name);
2507+ return (name == NULL) ? "(*no name)" : getstr(name);
2508 }
2509 default: return NULL; /* not a closure */
2510 }
2511@@ -1214,7 +1194,7 @@
2512 const char *name;
2513 TValue *val = NULL; /* to avoid warnings */
2514 lua_lock(L);
2515- name = aux_upvalue(index2addr(L, funcindex), n, &val, NULL);
2516+ name = aux_upvalue(index2addr(L, funcindex), n, &val, NULL, NULL);
2517 if (name) {
2518 setobj2s(L, L->top, val);
2519 api_incr_top(L);
2520@@ -1227,16 +1207,18 @@
2521 LUA_API const char *lua_setupvalue (lua_State *L, int funcindex, int n) {
2522 const char *name;
2523 TValue *val = NULL; /* to avoid warnings */
2524- GCObject *owner = NULL; /* to avoid warnings */
2525+ CClosure *owner = NULL;
2526+ UpVal *uv = NULL;
2527 StkId fi;
2528 lua_lock(L);
2529 fi = index2addr(L, funcindex);
2530 api_checknelems(L, 1);
2531- name = aux_upvalue(fi, n, &val, &owner);
2532+ name = aux_upvalue(fi, n, &val, &owner, &uv);
2533 if (name) {
2534 L->top--;
2535 setobj(L, val, L->top);
2536- luaC_barrier(L, owner, L->top);
2537+ if (owner) { luaC_barrier(L, owner, L->top); }
2538+ else if (uv) { luaC_upvalbarrier(L, uv); }
2539 }
2540 lua_unlock(L);
2541 return name;
2542@@ -1246,9 +1228,9 @@
2543 static UpVal **getupvalref (lua_State *L, int fidx, int n, LClosure **pf) {
2544 LClosure *f;
2545 StkId fi = index2addr(L, fidx);
2546- api_check(L, ttisLclosure(fi), "Lua function expected");
2547+ api_check(ttisLclosure(fi), "Lua function expected");
2548 f = clLvalue(fi);
2549- api_check(L, (1 <= n && n <= f->p->sizeupvalues), "invalid upvalue index");
2550+ api_check((1 <= n && n <= f->p->sizeupvalues), "invalid upvalue index");
2551 if (pf) *pf = f;
2552 return &f->upvals[n - 1]; /* get its upvalue pointer */
2553 }
2554@@ -1262,11 +1244,11 @@
2555 }
2556 case LUA_TCCL: { /* C closure */
2557 CClosure *f = clCvalue(fi);
2558- api_check(L, 1 <= n && n <= f->nupvalues, "invalid upvalue index");
2559+ api_check(1 <= n && n <= f->nupvalues, "invalid upvalue index");
2560 return &f->upvalue[n - 1];
2561 }
2562 default: {
2563- api_check(L, 0, "closure expected");
2564+ api_check(0, "closure expected");
2565 return NULL;
2566 }
2567 }
2568@@ -1278,7 +1260,11 @@
2569 LClosure *f1;
2570 UpVal **up1 = getupvalref(L, fidx1, n1, &f1);
2571 UpVal **up2 = getupvalref(L, fidx2, n2, NULL);
2572+ luaC_upvdeccount(L, *up1);
2573 *up1 = *up2;
2574- luaC_objbarrier(L, f1, *up2);
2575+ (*up1)->refcount++;
2576+ if (upisopen(*up1)) (*up1)->u.open.touched = 1;
2577+ luaC_upvalbarrier(L, *up1);
2578 }
2579
2580+
2581
2582=== modified file 'src/third_party/eris/lapi.h'
2583--- src/third_party/eris/lapi.h 2014-02-22 14:47:28 +0000
2584+++ src/third_party/eris/lapi.h 2016-04-10 16:54:20 +0000
2585@@ -1,5 +1,5 @@
2586 /*
2587-** $Id: lapi.h,v 2.7.1.1 2013/04/12 18:48:47 roberto Exp $
2588+** $Id: lapi.h,v 2.8 2014/07/15 21:26:50 roberto Exp $
2589 ** Auxiliary functions from Lua API
2590 ** See Copyright Notice in lua.h
2591 */
2592@@ -11,13 +11,13 @@
2593 #include "llimits.h"
2594 #include "lstate.h"
2595
2596-#define api_incr_top(L) {L->top++; api_check(L, L->top <= L->ci->top, \
2597+#define api_incr_top(L) {L->top++; api_check(L->top <= L->ci->top, \
2598 "stack overflow");}
2599
2600 #define adjustresults(L,nres) \
2601 { if ((nres) == LUA_MULTRET && L->ci->top < L->top) L->ci->top = L->top; }
2602
2603-#define api_checknelems(L,n) api_check(L, (n) < (L->top - L->ci->func), \
2604+#define api_checknelems(L,n) api_check((n) < (L->top - L->ci->func), \
2605 "not enough elements in the stack")
2606
2607
2608
2609=== modified file 'src/third_party/eris/lauxlib.c'
2610--- src/third_party/eris/lauxlib.c 2014-02-22 14:47:28 +0000
2611+++ src/third_party/eris/lauxlib.c 2016-04-10 16:54:20 +0000
2612@@ -1,9 +1,14 @@
2613 /*
2614-** $Id: lauxlib.c,v 1.248.1.1 2013/04/12 18:48:47 roberto Exp $
2615+** $Id: lauxlib.c,v 1.279 2014/12/14 18:32:26 roberto Exp $
2616 ** Auxiliary functions for building Lua libraries
2617 ** See Copyright Notice in lua.h
2618 */
2619
2620+#define lauxlib_c
2621+#define LUA_LIB
2622+
2623+#include "lprefix.h"
2624+
2625
2626 #include <errno.h>
2627 #include <stdarg.h>
2628@@ -16,9 +21,6 @@
2629 ** Any function declared here could be written as an application function.
2630 */
2631
2632-#define lauxlib_c
2633-#define LUA_LIB
2634-
2635 #include "lua.h"
2636
2637 #include "lauxlib.h"
2638@@ -64,11 +66,20 @@
2639 }
2640
2641
2642+/*
2643+** Search for a name for a function in all loaded modules
2644+** (registry._LOADED).
2645+*/
2646 static int pushglobalfuncname (lua_State *L, lua_Debug *ar) {
2647 int top = lua_gettop(L);
2648 lua_getinfo(L, "f", ar); /* push function */
2649- lua_pushglobaltable(L);
2650+ lua_getfield(L, LUA_REGISTRYINDEX, "_LOADED");
2651 if (findfield(L, top + 1, 2)) {
2652+ const char *name = lua_tostring(L, -1);
2653+ if (strncmp(name, "_G.", 3) == 0) { /* name start with '_G.'? */
2654+ lua_pushstring(L, name + 3); /* push name without prefix */
2655+ lua_remove(L, -2); /* remove original name */
2656+ }
2657 lua_copy(L, -1, top + 1); /* move name to proper place */
2658 lua_pop(L, 2); /* remove pushed values */
2659 return 1;
2660@@ -81,20 +92,18 @@
2661
2662
2663 static void pushfuncname (lua_State *L, lua_Debug *ar) {
2664- if (*ar->namewhat != '\0') /* is there a name? */
2665- lua_pushfstring(L, "function " LUA_QS, ar->name);
2666+ if (pushglobalfuncname(L, ar)) { /* try first a global name */
2667+ lua_pushfstring(L, "function '%s'", lua_tostring(L, -1));
2668+ lua_remove(L, -2); /* remove name */
2669+ }
2670+ else if (*ar->namewhat != '\0') /* is there a name from code? */
2671+ lua_pushfstring(L, "%s '%s'", ar->namewhat, ar->name); /* use it */
2672 else if (*ar->what == 'm') /* main? */
2673 lua_pushliteral(L, "main chunk");
2674- else if (*ar->what == 'C') {
2675- if (pushglobalfuncname(L, ar)) {
2676- lua_pushfstring(L, "function " LUA_QS, lua_tostring(L, -1));
2677- lua_remove(L, -2); /* remove name */
2678- }
2679- else
2680- lua_pushliteral(L, "?");
2681- }
2682- else
2683+ else if (*ar->what != 'C') /* for Lua functions, use <file:line> */
2684 lua_pushfstring(L, "function <%s:%d>", ar->short_src, ar->linedefined);
2685+ else /* nothing left... */
2686+ lua_pushliteral(L, "?");
2687 }
2688
2689
2690@@ -150,33 +159,40 @@
2691 ** =======================================================
2692 */
2693
2694-LUALIB_API int luaL_argerror (lua_State *L, int narg, const char *extramsg) {
2695+LUALIB_API int luaL_argerror (lua_State *L, int arg, const char *extramsg) {
2696 lua_Debug ar;
2697 if (!lua_getstack(L, 0, &ar)) /* no stack frame? */
2698- return luaL_error(L, "bad argument #%d (%s)", narg, extramsg);
2699+ return luaL_error(L, "bad argument #%d (%s)", arg, extramsg);
2700 lua_getinfo(L, "n", &ar);
2701 if (strcmp(ar.namewhat, "method") == 0) {
2702- narg--; /* do not count `self' */
2703- if (narg == 0) /* error is in the self argument itself? */
2704- return luaL_error(L, "calling " LUA_QS " on bad self (%s)",
2705+ arg--; /* do not count 'self' */
2706+ if (arg == 0) /* error is in the self argument itself? */
2707+ return luaL_error(L, "calling '%s' on bad self (%s)",
2708 ar.name, extramsg);
2709 }
2710 if (ar.name == NULL)
2711 ar.name = (pushglobalfuncname(L, &ar)) ? lua_tostring(L, -1) : "?";
2712- return luaL_error(L, "bad argument #%d to " LUA_QS " (%s)",
2713- narg, ar.name, extramsg);
2714-}
2715-
2716-
2717-static int typeerror (lua_State *L, int narg, const char *tname) {
2718- const char *msg = lua_pushfstring(L, "%s expected, got %s",
2719- tname, luaL_typename(L, narg));
2720- return luaL_argerror(L, narg, msg);
2721-}
2722-
2723-
2724-static void tag_error (lua_State *L, int narg, int tag) {
2725- typeerror(L, narg, lua_typename(L, tag));
2726+ return luaL_error(L, "bad argument #%d to '%s' (%s)",
2727+ arg, ar.name, extramsg);
2728+}
2729+
2730+
2731+static int typeerror (lua_State *L, int arg, const char *tname) {
2732+ const char *msg;
2733+ const char *typearg; /* name for the type of the actual argument */
2734+ if (luaL_getmetafield(L, arg, "__name") == LUA_TSTRING)
2735+ typearg = lua_tostring(L, -1); /* use the given type name */
2736+ else if (lua_type(L, arg) == LUA_TLIGHTUSERDATA)
2737+ typearg = "light userdata"; /* special name for messages */
2738+ else
2739+ typearg = luaL_typename(L, arg); /* standard name */
2740+ msg = lua_pushfstring(L, "%s expected, got %s", tname, typearg);
2741+ return luaL_argerror(L, arg, msg);
2742+}
2743+
2744+
2745+static void tag_error (lua_State *L, int arg, int tag) {
2746+ typeerror(L, arg, lua_typename(L, tag));
2747 }
2748
2749
2750@@ -222,7 +238,7 @@
2751 }
2752
2753
2754-#if !defined(inspectstat) /* { */
2755+#if !defined(l_inspectstat) /* { */
2756
2757 #if defined(LUA_USE_POSIX)
2758
2759@@ -231,13 +247,13 @@
2760 /*
2761 ** use appropriate macros to interpret 'pclose' return status
2762 */
2763-#define inspectstat(stat,what) \
2764+#define l_inspectstat(stat,what) \
2765 if (WIFEXITED(stat)) { stat = WEXITSTATUS(stat); } \
2766 else if (WIFSIGNALED(stat)) { stat = WTERMSIG(stat); what = "signal"; }
2767
2768 #else
2769
2770-#define inspectstat(stat,what) /* no op */
2771+#define l_inspectstat(stat,what) /* no op */
2772
2773 #endif
2774
2775@@ -249,7 +265,7 @@
2776 if (stat == -1) /* error? */
2777 return luaL_fileresult(L, 0, NULL);
2778 else {
2779- inspectstat(stat, what); /* interpret result */
2780+ l_inspectstat(stat, what); /* interpret result */
2781 if (*what == 'e' && stat == 0) /* successful termination? */
2782 lua_pushboolean(L, 1);
2783 else
2784@@ -270,11 +286,12 @@
2785 */
2786
2787 LUALIB_API int luaL_newmetatable (lua_State *L, const char *tname) {
2788- luaL_getmetatable(L, tname); /* try to get metatable */
2789- if (!lua_isnil(L, -1)) /* name already in use? */
2790+ if (luaL_getmetatable(L, tname)) /* name already in use? */
2791 return 0; /* leave previous value on top, but return 0 */
2792 lua_pop(L, 1);
2793 lua_newtable(L); /* create metatable */
2794+ lua_pushstring(L, tname);
2795+ lua_setfield(L, -2, "__name"); /* metatable.__name = tname */
2796 lua_pushvalue(L, -1);
2797 lua_setfield(L, LUA_REGISTRYINDEX, tname); /* registry.name = metatable */
2798 return 1;
2799@@ -317,16 +334,16 @@
2800 ** =======================================================
2801 */
2802
2803-LUALIB_API int luaL_checkoption (lua_State *L, int narg, const char *def,
2804+LUALIB_API int luaL_checkoption (lua_State *L, int arg, const char *def,
2805 const char *const lst[]) {
2806- const char *name = (def) ? luaL_optstring(L, narg, def) :
2807- luaL_checkstring(L, narg);
2808+ const char *name = (def) ? luaL_optstring(L, arg, def) :
2809+ luaL_checkstring(L, arg);
2810 int i;
2811 for (i=0; lst[i]; i++)
2812 if (strcmp(lst[i], name) == 0)
2813 return i;
2814- return luaL_argerror(L, narg,
2815- lua_pushfstring(L, "invalid option " LUA_QS, name));
2816+ return luaL_argerror(L, arg,
2817+ lua_pushfstring(L, "invalid option '%s'", name));
2818 }
2819
2820
2821@@ -342,77 +359,71 @@
2822 }
2823
2824
2825-LUALIB_API void luaL_checktype (lua_State *L, int narg, int t) {
2826- if (lua_type(L, narg) != t)
2827- tag_error(L, narg, t);
2828-}
2829-
2830-
2831-LUALIB_API void luaL_checkany (lua_State *L, int narg) {
2832- if (lua_type(L, narg) == LUA_TNONE)
2833- luaL_argerror(L, narg, "value expected");
2834-}
2835-
2836-
2837-LUALIB_API const char *luaL_checklstring (lua_State *L, int narg, size_t *len) {
2838- const char *s = lua_tolstring(L, narg, len);
2839- if (!s) tag_error(L, narg, LUA_TSTRING);
2840+LUALIB_API void luaL_checktype (lua_State *L, int arg, int t) {
2841+ if (lua_type(L, arg) != t)
2842+ tag_error(L, arg, t);
2843+}
2844+
2845+
2846+LUALIB_API void luaL_checkany (lua_State *L, int arg) {
2847+ if (lua_type(L, arg) == LUA_TNONE)
2848+ luaL_argerror(L, arg, "value expected");
2849+}
2850+
2851+
2852+LUALIB_API const char *luaL_checklstring (lua_State *L, int arg, size_t *len) {
2853+ const char *s = lua_tolstring(L, arg, len);
2854+ if (!s) tag_error(L, arg, LUA_TSTRING);
2855 return s;
2856 }
2857
2858
2859-LUALIB_API const char *luaL_optlstring (lua_State *L, int narg,
2860+LUALIB_API const char *luaL_optlstring (lua_State *L, int arg,
2861 const char *def, size_t *len) {
2862- if (lua_isnoneornil(L, narg)) {
2863+ if (lua_isnoneornil(L, arg)) {
2864 if (len)
2865 *len = (def ? strlen(def) : 0);
2866 return def;
2867 }
2868- else return luaL_checklstring(L, narg, len);
2869-}
2870-
2871-
2872-LUALIB_API lua_Number luaL_checknumber (lua_State *L, int narg) {
2873- int isnum;
2874- lua_Number d = lua_tonumberx(L, narg, &isnum);
2875- if (!isnum)
2876- tag_error(L, narg, LUA_TNUMBER);
2877- return d;
2878-}
2879-
2880-
2881-LUALIB_API lua_Number luaL_optnumber (lua_State *L, int narg, lua_Number def) {
2882- return luaL_opt(L, luaL_checknumber, narg, def);
2883-}
2884-
2885-
2886-LUALIB_API lua_Integer luaL_checkinteger (lua_State *L, int narg) {
2887- int isnum;
2888- lua_Integer d = lua_tointegerx(L, narg, &isnum);
2889- if (!isnum)
2890- tag_error(L, narg, LUA_TNUMBER);
2891- return d;
2892-}
2893-
2894-
2895-LUALIB_API lua_Unsigned luaL_checkunsigned (lua_State *L, int narg) {
2896- int isnum;
2897- lua_Unsigned d = lua_tounsignedx(L, narg, &isnum);
2898- if (!isnum)
2899- tag_error(L, narg, LUA_TNUMBER);
2900- return d;
2901-}
2902-
2903-
2904-LUALIB_API lua_Integer luaL_optinteger (lua_State *L, int narg,
2905+ else return luaL_checklstring(L, arg, len);
2906+}
2907+
2908+
2909+LUALIB_API lua_Number luaL_checknumber (lua_State *L, int arg) {
2910+ int isnum;
2911+ lua_Number d = lua_tonumberx(L, arg, &isnum);
2912+ if (!isnum)
2913+ tag_error(L, arg, LUA_TNUMBER);
2914+ return d;
2915+}
2916+
2917+
2918+LUALIB_API lua_Number luaL_optnumber (lua_State *L, int arg, lua_Number def) {
2919+ return luaL_opt(L, luaL_checknumber, arg, def);
2920+}
2921+
2922+
2923+static void interror (lua_State *L, int arg) {
2924+ if (lua_isnumber(L, arg))
2925+ luaL_argerror(L, arg, "number has no integer representation");
2926+ else
2927+ tag_error(L, arg, LUA_TNUMBER);
2928+}
2929+
2930+
2931+LUALIB_API lua_Integer luaL_checkinteger (lua_State *L, int arg) {
2932+ int isnum;
2933+ lua_Integer d = lua_tointegerx(L, arg, &isnum);
2934+ if (!isnum) {
2935+ interror(L, arg);
2936+ }
2937+ return d;
2938+}
2939+
2940+
2941+LUALIB_API lua_Integer luaL_optinteger (lua_State *L, int arg,
2942 lua_Integer def) {
2943- return luaL_opt(L, luaL_checkinteger, narg, def);
2944-}
2945-
2946-
2947-LUALIB_API lua_Unsigned luaL_optunsigned (lua_State *L, int narg,
2948- lua_Unsigned def) {
2949- return luaL_opt(L, luaL_checkunsigned, narg, def);
2950+ return luaL_opt(L, luaL_checkinteger, arg, def);
2951 }
2952
2953 /* }====================================================== */
2954@@ -523,7 +534,7 @@
2955 int ref;
2956 if (lua_isnil(L, -1)) {
2957 lua_pop(L, 1); /* remove from stack */
2958- return LUA_REFNIL; /* `nil' has a unique fixed reference */
2959+ return LUA_REFNIL; /* 'nil' has a unique fixed reference */
2960 }
2961 t = lua_absindex(L, t);
2962 lua_rawgeti(L, t, freelist); /* get first free element */
2963@@ -562,7 +573,7 @@
2964 typedef struct LoadF {
2965 int n; /* number of pre-read characters */
2966 FILE *f; /* file being read */
2967- char buff[LUAL_BUFFERSIZE]; /* area for reading file */
2968+ char buff[BUFSIZ]; /* area for reading file */
2969 } LoadF;
2970
2971
2972@@ -655,7 +666,7 @@
2973 readstatus = ferror(lf.f);
2974 if (filename) fclose(lf.f); /* close file (even in case of errors) */
2975 if (readstatus) {
2976- lua_settop(L, fnameindex); /* ignore results from `lua_load' */
2977+ lua_settop(L, fnameindex); /* ignore results from 'lua_load' */
2978 return errfile(L, "read", fnameindex);
2979 }
2980 lua_remove(L, fnameindex);
2981@@ -698,23 +709,23 @@
2982
2983 LUALIB_API int luaL_getmetafield (lua_State *L, int obj, const char *event) {
2984 if (!lua_getmetatable(L, obj)) /* no metatable? */
2985- return 0;
2986- lua_pushstring(L, event);
2987- lua_rawget(L, -2);
2988- if (lua_isnil(L, -1)) {
2989- lua_pop(L, 2); /* remove metatable and metafield */
2990- return 0;
2991- }
2992+ return LUA_TNIL;
2993 else {
2994- lua_remove(L, -2); /* remove only metatable */
2995- return 1;
2996+ int tt;
2997+ lua_pushstring(L, event);
2998+ tt = lua_rawget(L, -2);
2999+ if (tt == LUA_TNIL) /* is metafield nil? */
3000+ lua_pop(L, 2); /* remove metatable and metafield */
3001+ else
3002+ lua_remove(L, -2); /* remove only metatable */
3003+ return tt; /* return metafield type */
3004 }
3005 }
3006
3007
3008 LUALIB_API int luaL_callmeta (lua_State *L, int obj, const char *event) {
3009 obj = lua_absindex(L, obj);
3010- if (!luaL_getmetafield(L, obj, event)) /* no metafield? */
3011+ if (luaL_getmetafield(L, obj, event) == LUA_TNIL) /* no metafield? */
3012 return 0;
3013 lua_pushvalue(L, obj);
3014 lua_call(L, 1, 1);
3015@@ -722,13 +733,13 @@
3016 }
3017
3018
3019-LUALIB_API int luaL_len (lua_State *L, int idx) {
3020- int l;
3021+LUALIB_API lua_Integer luaL_len (lua_State *L, int idx) {
3022+ lua_Integer l;
3023 int isnum;
3024 lua_len(L, idx);
3025- l = (int)lua_tointegerx(L, -1, &isnum);
3026+ l = lua_tointegerx(L, -1, &isnum);
3027 if (!isnum)
3028- luaL_error(L, "object length is not a number");
3029+ luaL_error(L, "object length is not an integer");
3030 lua_pop(L, 1); /* remove object */
3031 return l;
3032 }
3033@@ -737,7 +748,13 @@
3034 LUALIB_API const char *luaL_tolstring (lua_State *L, int idx, size_t *len) {
3035 if (!luaL_callmeta(L, idx, "__tostring")) { /* no metafield? */
3036 switch (lua_type(L, idx)) {
3037- case LUA_TNUMBER:
3038+ case LUA_TNUMBER: {
3039+ if (lua_isinteger(L, idx))
3040+ lua_pushfstring(L, "%I", lua_tointeger(L, idx));
3041+ else
3042+ lua_pushfstring(L, "%f", lua_tonumber(L, idx));
3043+ break;
3044+ }
3045 case LUA_TSTRING:
3046 lua_pushvalue(L, idx);
3047 break;
3048@@ -772,8 +789,7 @@
3049 e = strchr(fname, '.');
3050 if (e == NULL) e = fname + strlen(fname);
3051 lua_pushlstring(L, fname, e - fname);
3052- lua_rawget(L, -2);
3053- if (lua_isnil(L, -1)) { /* no such field? */
3054+ if (lua_rawget(L, -2) == LUA_TNIL) { /* no such field? */
3055 lua_pop(L, 1); /* remove this nil */
3056 lua_createtable(L, 0, (*e == '.' ? 1 : szhint)); /* new table for field */
3057 lua_pushlstring(L, fname, e - fname);
3058@@ -810,13 +826,12 @@
3059 LUALIB_API void luaL_pushmodule (lua_State *L, const char *modname,
3060 int sizehint) {
3061 luaL_findtable(L, LUA_REGISTRYINDEX, "_LOADED", 1); /* get _LOADED table */
3062- lua_getfield(L, -1, modname); /* get _LOADED[modname] */
3063- if (!lua_istable(L, -1)) { /* not found? */
3064+ if (lua_getfield(L, -1, modname) != LUA_TTABLE) { /* no _LOADED[modname]? */
3065 lua_pop(L, 1); /* remove previous result */
3066 /* try global variable (and create one if it does not exist) */
3067 lua_pushglobaltable(L);
3068 if (luaL_findtable(L, 0, modname, sizehint) != NULL)
3069- luaL_error(L, "name conflict for module " LUA_QS, modname);
3070+ luaL_error(L, "name conflict for module '%s'", modname);
3071 lua_pushvalue(L, -1);
3072 lua_setfield(L, -3, modname); /* _LOADED[modname] = new table */
3073 }
3074@@ -846,7 +861,6 @@
3075 ** Returns with only the table at the stack.
3076 */
3077 LUALIB_API void luaL_setfuncs (lua_State *L, const luaL_Reg *l, int nup) {
3078- luaL_checkversion(L);
3079 luaL_checkstack(L, nup, "too many upvalues");
3080 for (; l->name != NULL; l++) { /* fill the table with given functions */
3081 int i;
3082@@ -864,8 +878,8 @@
3083 ** into the stack
3084 */
3085 LUALIB_API int luaL_getsubtable (lua_State *L, int idx, const char *fname) {
3086- lua_getfield(L, idx, fname);
3087- if (lua_istable(L, -1)) return 1; /* table already there */
3088+ if (lua_getfield(L, idx, fname) == LUA_TTABLE)
3089+ return 1; /* table already there */
3090 else {
3091 lua_pop(L, 1); /* remove previous result */
3092 idx = lua_absindex(L, idx);
3093@@ -878,22 +892,26 @@
3094
3095
3096 /*
3097-** stripped-down 'require'. Calls 'openf' to open a module,
3098-** registers the result in 'package.loaded' table and, if 'glb'
3099-** is true, also registers the result in the global table.
3100+** Stripped-down 'require': After checking "loaded" table, calls 'openf'
3101+** to open a module, registers the result in 'package.loaded' table and,
3102+** if 'glb' is true, also registers the result in the global table.
3103 ** Leaves resulting module on the top.
3104 */
3105 LUALIB_API void luaL_requiref (lua_State *L, const char *modname,
3106 lua_CFunction openf, int glb) {
3107- lua_pushcfunction(L, openf);
3108- lua_pushstring(L, modname); /* argument to open function */
3109- lua_call(L, 1, 1); /* open module */
3110 luaL_getsubtable(L, LUA_REGISTRYINDEX, "_LOADED");
3111- lua_pushvalue(L, -2); /* make copy of module (call result) */
3112- lua_setfield(L, -2, modname); /* _LOADED[modname] = module */
3113- lua_pop(L, 1); /* remove _LOADED table */
3114+ lua_getfield(L, -1, modname); /* _LOADED[modname] */
3115+ if (!lua_toboolean(L, -1)) { /* package not already loaded? */
3116+ lua_pop(L, 1); /* remove field */
3117+ lua_pushcfunction(L, openf);
3118+ lua_pushstring(L, modname); /* argument to open function */
3119+ lua_call(L, 1, 1); /* call 'openf' to open module */
3120+ lua_pushvalue(L, -1); /* make copy of module (call result) */
3121+ lua_setfield(L, -3, modname); /* _LOADED[modname] = module */
3122+ }
3123+ lua_remove(L, -2); /* remove _LOADED table */
3124 if (glb) {
3125- lua_pushvalue(L, -1); /* copy of 'mod' */
3126+ lua_pushvalue(L, -1); /* copy of module */
3127 lua_setglobal(L, modname); /* _G[modname] = module */
3128 }
3129 }
3130@@ -908,7 +926,7 @@
3131 while ((wild = strstr(s, p)) != NULL) {
3132 luaL_addlstring(&b, s, wild - s); /* push prefix */
3133 luaL_addstring(&b, r); /* push replacement in place of pattern */
3134- s = wild + l; /* continue after `p' */
3135+ s = wild + l; /* continue after 'p' */
3136 }
3137 luaL_addstring(&b, s); /* push last suffix */
3138 luaL_pushresult(&b);
3139@@ -928,8 +946,8 @@
3140
3141
3142 static int panic (lua_State *L) {
3143- luai_writestringerror("PANIC: unprotected error in call to Lua API (%s)\n",
3144- lua_tostring(L, -1));
3145+ lua_writestringerror("PANIC: unprotected error in call to Lua API (%s)\n",
3146+ lua_tostring(L, -1));
3147 return 0; /* return to Lua to abort */
3148 }
3149
3150@@ -941,19 +959,14 @@
3151 }
3152
3153
3154-LUALIB_API void luaL_checkversion_ (lua_State *L, lua_Number ver) {
3155+LUALIB_API void luaL_checkversion_ (lua_State *L, lua_Number ver, size_t sz) {
3156 const lua_Number *v = lua_version(L);
3157+ if (sz != LUAL_NUMSIZES) /* check numeric types */
3158+ luaL_error(L, "core and library have incompatible numeric types");
3159 if (v != lua_version(NULL))
3160 luaL_error(L, "multiple Lua VMs detected");
3161 else if (*v != ver)
3162 luaL_error(L, "version mismatch: app. needs %f, Lua core provides %f",
3163 ver, *v);
3164- /* check conversions number -> integer types */
3165- lua_pushnumber(L, -(lua_Number)0x1234);
3166- if (lua_tointeger(L, -1) != -0x1234 ||
3167- lua_tounsigned(L, -1) != (lua_Unsigned)-0x1234)
3168- luaL_error(L, "bad conversion number->int;"
3169- " must recompile Lua with proper settings");
3170- lua_pop(L, 1);
3171 }
3172
3173
3174=== modified file 'src/third_party/eris/lauxlib.h'
3175--- src/third_party/eris/lauxlib.h 2014-02-22 14:47:28 +0000
3176+++ src/third_party/eris/lauxlib.h 2016-04-10 16:54:20 +0000
3177@@ -1,5 +1,5 @@
3178 /*
3179-** $Id: lauxlib.h,v 1.120.1.1 2013/04/12 18:48:47 roberto Exp $
3180+** $Id: lauxlib.h,v 1.128 2014/10/29 16:11:17 roberto Exp $
3181 ** Auxiliary functions for building Lua libraries
3182 ** See Copyright Notice in lua.h
3183 */
3184@@ -16,7 +16,7 @@
3185
3186
3187
3188-/* extra error code for `luaL_load' */
3189+/* extra error code for 'luaL_load' */
3190 #define LUA_ERRFILE (LUA_ERRERR+1)
3191
3192
3193@@ -26,30 +26,30 @@
3194 } luaL_Reg;
3195
3196
3197-LUALIB_API void (luaL_checkversion_) (lua_State *L, lua_Number ver);
3198-#define luaL_checkversion(L) luaL_checkversion_(L, LUA_VERSION_NUM)
3199+#define LUAL_NUMSIZES (sizeof(lua_Integer)*16 + sizeof(lua_Number))
3200+
3201+LUALIB_API void (luaL_checkversion_) (lua_State *L, lua_Number ver, size_t sz);
3202+#define luaL_checkversion(L) \
3203+ luaL_checkversion_(L, LUA_VERSION_NUM, LUAL_NUMSIZES)
3204
3205 LUALIB_API int (luaL_getmetafield) (lua_State *L, int obj, const char *e);
3206 LUALIB_API int (luaL_callmeta) (lua_State *L, int obj, const char *e);
3207 LUALIB_API const char *(luaL_tolstring) (lua_State *L, int idx, size_t *len);
3208-LUALIB_API int (luaL_argerror) (lua_State *L, int numarg, const char *extramsg);
3209-LUALIB_API const char *(luaL_checklstring) (lua_State *L, int numArg,
3210+LUALIB_API int (luaL_argerror) (lua_State *L, int arg, const char *extramsg);
3211+LUALIB_API const char *(luaL_checklstring) (lua_State *L, int arg,
3212 size_t *l);
3213-LUALIB_API const char *(luaL_optlstring) (lua_State *L, int numArg,
3214+LUALIB_API const char *(luaL_optlstring) (lua_State *L, int arg,
3215 const char *def, size_t *l);
3216-LUALIB_API lua_Number (luaL_checknumber) (lua_State *L, int numArg);
3217-LUALIB_API lua_Number (luaL_optnumber) (lua_State *L, int nArg, lua_Number def);
3218+LUALIB_API lua_Number (luaL_checknumber) (lua_State *L, int arg);
3219+LUALIB_API lua_Number (luaL_optnumber) (lua_State *L, int arg, lua_Number def);
3220
3221-LUALIB_API lua_Integer (luaL_checkinteger) (lua_State *L, int numArg);
3222-LUALIB_API lua_Integer (luaL_optinteger) (lua_State *L, int nArg,
3223+LUALIB_API lua_Integer (luaL_checkinteger) (lua_State *L, int arg);
3224+LUALIB_API lua_Integer (luaL_optinteger) (lua_State *L, int arg,
3225 lua_Integer def);
3226-LUALIB_API lua_Unsigned (luaL_checkunsigned) (lua_State *L, int numArg);
3227-LUALIB_API lua_Unsigned (luaL_optunsigned) (lua_State *L, int numArg,
3228- lua_Unsigned def);
3229
3230 LUALIB_API void (luaL_checkstack) (lua_State *L, int sz, const char *msg);
3231-LUALIB_API void (luaL_checktype) (lua_State *L, int narg, int t);
3232-LUALIB_API void (luaL_checkany) (lua_State *L, int narg);
3233+LUALIB_API void (luaL_checktype) (lua_State *L, int arg, int t);
3234+LUALIB_API void (luaL_checkany) (lua_State *L, int arg);
3235
3236 LUALIB_API int (luaL_newmetatable) (lua_State *L, const char *tname);
3237 LUALIB_API void (luaL_setmetatable) (lua_State *L, const char *tname);
3238@@ -59,7 +59,7 @@
3239 LUALIB_API void (luaL_where) (lua_State *L, int lvl);
3240 LUALIB_API int (luaL_error) (lua_State *L, const char *fmt, ...);
3241
3242-LUALIB_API int (luaL_checkoption) (lua_State *L, int narg, const char *def,
3243+LUALIB_API int (luaL_checkoption) (lua_State *L, int arg, const char *def,
3244 const char *const lst[]);
3245
3246 LUALIB_API int (luaL_fileresult) (lua_State *L, int stat, const char *fname);
3247@@ -83,7 +83,7 @@
3248
3249 LUALIB_API lua_State *(luaL_newstate) (void);
3250
3251-LUALIB_API int (luaL_len) (lua_State *L, int idx);
3252+LUALIB_API lua_Integer (luaL_len) (lua_State *L, int idx);
3253
3254 LUALIB_API const char *(luaL_gsub) (lua_State *L, const char *s, const char *p,
3255 const char *r);
3256@@ -108,16 +108,13 @@
3257 #define luaL_newlibtable(L,l) \
3258 lua_createtable(L, 0, sizeof(l)/sizeof((l)[0]) - 1)
3259
3260-#define luaL_newlib(L,l) (luaL_newlibtable(L,l), luaL_setfuncs(L,l,0))
3261+#define luaL_newlib(L,l) \
3262+ (luaL_checkversion(L), luaL_newlibtable(L,l), luaL_setfuncs(L,l,0))
3263
3264-#define luaL_argcheck(L, cond,numarg,extramsg) \
3265- ((void)((cond) || luaL_argerror(L, (numarg), (extramsg))))
3266+#define luaL_argcheck(L, cond,arg,extramsg) \
3267+ ((void)((cond) || luaL_argerror(L, (arg), (extramsg))))
3268 #define luaL_checkstring(L,n) (luaL_checklstring(L, (n), NULL))
3269 #define luaL_optstring(L,n,d) (luaL_optlstring(L, (n), (d), NULL))
3270-#define luaL_checkint(L,n) ((int)luaL_checkinteger(L, (n)))
3271-#define luaL_optint(L,n,d) ((int)luaL_optinteger(L, (n), (d)))
3272-#define luaL_checklong(L,n) ((long)luaL_checkinteger(L, (n)))
3273-#define luaL_optlong(L,n,d) ((long)luaL_optinteger(L, (n), (d)))
3274
3275 #define luaL_typename(L,i) lua_typename(L, lua_type(L,(i)))
3276
3277@@ -207,6 +204,53 @@
3278 #endif
3279
3280
3281+/*
3282+** {==================================================================
3283+** "Abstraction Layer" for basic report of messages and errors
3284+** ===================================================================
3285+*/
3286+
3287+/* print a string */
3288+#if !defined(lua_writestring)
3289+#define lua_writestring(s,l) fwrite((s), sizeof(char), (l), stdout)
3290+#endif
3291+
3292+/* print a newline and flush the output */
3293+#if !defined(lua_writeline)
3294+#define lua_writeline() (lua_writestring("\n", 1), fflush(stdout))
3295+#endif
3296+
3297+/* print an error message */
3298+#if !defined(lua_writestringerror)
3299+#define lua_writestringerror(s,p) \
3300+ (fprintf(stderr, (s), (p)), fflush(stderr))
3301+#endif
3302+
3303+/* }================================================================== */
3304+
3305+
3306+/*
3307+** {============================================================
3308+** Compatibility with deprecated conversions
3309+** =============================================================
3310+*/
3311+#if defined(LUA_COMPAT_APIINTCASTS)
3312+
3313+#define luaL_checkunsigned(L,a) ((lua_Unsigned)luaL_checkinteger(L,a))
3314+#define luaL_optunsigned(L,a,d) \
3315+ ((lua_Unsigned)luaL_optinteger(L,a,(lua_Integer)(d)))
3316+
3317+#define luaL_checkint(L,n) ((int)luaL_checkinteger(L, (n)))
3318+#define luaL_optint(L,n,d) ((int)luaL_optinteger(L, (n), (d)))
3319+
3320+#define luaL_checklong(L,n) ((long)luaL_checkinteger(L, (n)))
3321+#define luaL_optlong(L,n,d) ((long)luaL_optinteger(L, (n), (d)))
3322+
3323+#endif
3324+/* }============================================================ */
3325+
3326+
3327+
3328 #endif
3329
3330
3331
3332=== modified file 'src/third_party/eris/lbaselib.c'
3333--- src/third_party/eris/lbaselib.c 2014-02-22 14:47:28 +0000
3334+++ src/third_party/eris/lbaselib.c 2016-04-10 16:54:20 +0000
3335@@ -1,9 +1,13 @@
3336 /*
3337-** $Id: lbaselib.c,v 1.276.1.1 2013/04/12 18:48:47 roberto Exp $
3338+** $Id: lbaselib.c,v 1.309 2014/12/10 12:26:42 roberto Exp $
3339 ** Basic library
3340 ** See Copyright Notice in lua.h
3341 */
3342
3343+#define lbaselib_c
3344+#define LUA_LIB
3345+
3346+#include "lprefix.h"
3347
3348
3349 #include <ctype.h>
3350@@ -11,9 +15,6 @@
3351 #include <stdlib.h>
3352 #include <string.h>
3353
3354-#define lbaselib_c
3355-#define LUA_LIB
3356-
3357 #include "lua.h"
3358
3359 #include "lauxlib.h"
3360@@ -32,62 +33,74 @@
3361 lua_call(L, 1, 1);
3362 s = lua_tolstring(L, -1, &l); /* get result */
3363 if (s == NULL)
3364- return luaL_error(L,
3365- LUA_QL("tostring") " must return a string to " LUA_QL("print"));
3366- if (i>1) luai_writestring("\t", 1);
3367- luai_writestring(s, l);
3368+ return luaL_error(L, "'tostring' must return a string to 'print'");
3369+ if (i>1) lua_writestring("\t", 1);
3370+ lua_writestring(s, l);
3371 lua_pop(L, 1); /* pop result */
3372 }
3373- luai_writeline();
3374+ lua_writeline();
3375 return 0;
3376 }
3377
3378
3379 #define SPACECHARS " \f\n\r\t\v"
3380
3381+static const char *b_str2int (const char *s, int base, lua_Integer *pn) {
3382+ lua_Unsigned n = 0;
3383+ int neg = 0;
3384+ s += strspn(s, SPACECHARS); /* skip initial spaces */
3385+ if (*s == '-') { s++; neg = 1; } /* handle signal */
3386+ else if (*s == '+') s++;
3387+ if (!isalnum((unsigned char)*s)) /* no digit? */
3388+ return NULL;
3389+ do {
3390+ int digit = (isdigit((unsigned char)*s)) ? *s - '0'
3391+ : toupper((unsigned char)*s) - 'A' + 10;
3392+ if (digit >= base) return NULL; /* invalid numeral */
3393+ n = n * base + digit;
3394+ s++;
3395+ } while (isalnum((unsigned char)*s));
3396+ s += strspn(s, SPACECHARS); /* skip trailing spaces */
3397+ *pn = (lua_Integer)((neg) ? (0u - n) : n);
3398+ return s;
3399+}
3400+
3401+
3402 static int luaB_tonumber (lua_State *L) {
3403- if (lua_isnoneornil(L, 2)) { /* standard conversion */
3404- int isnum;
3405- lua_Number n = lua_tonumberx(L, 1, &isnum);
3406- if (isnum) {
3407- lua_pushnumber(L, n);
3408- return 1;
3409- } /* else not a number; must be something */
3410+ if (lua_isnoneornil(L, 2)) { /* standard conversion? */
3411 luaL_checkany(L, 1);
3412+ if (lua_type(L, 1) == LUA_TNUMBER) { /* already a number? */
3413+ lua_settop(L, 1); /* yes; return it */
3414+ return 1;
3415+ }
3416+ else {
3417+ size_t l;
3418+ const char *s = lua_tolstring(L, 1, &l);
3419+ if (s != NULL && lua_stringtonumber(L, s) == l + 1)
3420+ return 1; /* successful conversion to number */
3421+ /* else not a number */
3422+ }
3423 }
3424 else {
3425 size_t l;
3426- const char *s = luaL_checklstring(L, 1, &l);
3427- const char *e = s + l; /* end point for 's' */
3428- int base = luaL_checkint(L, 2);
3429- int neg = 0;
3430+ const char *s;
3431+ lua_Integer n = 0; /* to avoid warnings */
3432+ lua_Integer base = luaL_checkinteger(L, 2);
3433+ luaL_checktype(L, 1, LUA_TSTRING); /* before 'luaL_checklstring'! */
3434+ s = luaL_checklstring(L, 1, &l);
3435 luaL_argcheck(L, 2 <= base && base <= 36, 2, "base out of range");
3436- s += strspn(s, SPACECHARS); /* skip initial spaces */
3437- if (*s == '-') { s++; neg = 1; } /* handle signal */
3438- else if (*s == '+') s++;
3439- if (isalnum((unsigned char)*s)) {
3440- lua_Number n = 0;
3441- do {
3442- int digit = (isdigit((unsigned char)*s)) ? *s - '0'
3443- : toupper((unsigned char)*s) - 'A' + 10;
3444- if (digit >= base) break; /* invalid numeral; force a fail */
3445- n = n * (lua_Number)base + (lua_Number)digit;
3446- s++;
3447- } while (isalnum((unsigned char)*s));
3448- s += strspn(s, SPACECHARS); /* skip trailing spaces */
3449- if (s == e) { /* no invalid trailing characters? */
3450- lua_pushnumber(L, (neg) ? -n : n);
3451- return 1;
3452- } /* else not a number */
3453+ if (b_str2int(s, (int)base, &n) == s + l) {
3454+ lua_pushinteger(L, n);
3455+ return 1;
3456 } /* else not a number */
3457- }
3458+ } /* else not a number */
3459 lua_pushnil(L); /* not a number */
3460 return 1;
3461 }
3462
3463
3464 static int luaB_error (lua_State *L) {
3465- int level = luaL_optint(L, 2, 1);
3466+ int level = (int)luaL_optinteger(L, 2, 1);
3467 lua_settop(L, 1);
3468 if (lua_isstring(L, 1) && level > 0) { /* add extra information? */
3469 luaL_where(L, level);
3470@@ -114,7 +127,7 @@
3471 luaL_checktype(L, 1, LUA_TTABLE);
3472 luaL_argcheck(L, t == LUA_TNIL || t == LUA_TTABLE, 2,
3473 "nil or table expected");
3474- if (luaL_getmetafield(L, 1, "__metatable"))
3475+ if (luaL_getmetafield(L, 1, "__metatable") != LUA_TNIL)
3476 return luaL_error(L, "cannot change a protected metatable");
3477 lua_settop(L, 2);
3478 lua_setmetatable(L, 1);
3479@@ -160,19 +173,18 @@
3480 static int luaB_collectgarbage (lua_State *L) {
3481 static const char *const opts[] = {"stop", "restart", "collect",
3482 "count", "step", "setpause", "setstepmul",
3483- "setmajorinc", "isrunning", "generational", "incremental", NULL};
3484+ "isrunning", NULL};
3485 static const int optsnum[] = {LUA_GCSTOP, LUA_GCRESTART, LUA_GCCOLLECT,
3486 LUA_GCCOUNT, LUA_GCSTEP, LUA_GCSETPAUSE, LUA_GCSETSTEPMUL,
3487- LUA_GCSETMAJORINC, LUA_GCISRUNNING, LUA_GCGEN, LUA_GCINC};
3488+ LUA_GCISRUNNING};
3489 int o = optsnum[luaL_checkoption(L, 1, "collect", opts)];
3490- int ex = luaL_optint(L, 2, 0);
3491+ int ex = (int)luaL_optinteger(L, 2, 0);
3492 int res = lua_gc(L, o, ex);
3493 switch (o) {
3494 case LUA_GCCOUNT: {
3495 int b = lua_gc(L, LUA_GCCOUNTB, 0);
3496- lua_pushnumber(L, res + ((lua_Number)b/1024));
3497- lua_pushinteger(L, b);
3498- return 2;
3499+ lua_pushnumber(L, (lua_Number)res + ((lua_Number)b/1024));
3500+ return 1;
3501 }
3502 case LUA_GCSTEP: case LUA_GCISRUNNING: {
3503 lua_pushboolean(L, res);
3504@@ -186,16 +198,19 @@
3505 }
3506
3507
3508+/*
3509+** This function has all type names as upvalues, to maximize performance.
3510+*/
3511 static int luaB_type (lua_State *L) {
3512 luaL_checkany(L, 1);
3513- lua_pushstring(L, luaL_typename(L, 1));
3514+ lua_pushvalue(L, lua_upvalueindex(lua_type(L, 1) + 1));
3515 return 1;
3516 }
3517
3518
3519 static int pairsmeta (lua_State *L, const char *method, int iszero,
3520 lua_CFunction iter) {
3521- if (!luaL_getmetafield(L, 1, method)) { /* no metamethod? */
3522+ if (luaL_getmetafield(L, 1, method) == LUA_TNIL) { /* no metamethod? */
3523 luaL_checktype(L, 1, LUA_TTABLE); /* argument must be a table */
3524 lua_pushcfunction(L, iter); /* will return generator, */
3525 lua_pushvalue(L, 1); /* state, */
3526@@ -227,18 +242,44 @@
3527 }
3528
3529
3530+/*
3531+** Traversal function for 'ipairs' for raw tables
3532+*/
3533+static int ipairsaux_raw (lua_State *L) {
3534+ lua_Integer i = luaL_checkinteger(L, 2) + 1;
3535+ luaL_checktype(L, 1, LUA_TTABLE);
3536+ lua_pushinteger(L, i);
3537+ return (lua_rawgeti(L, 1, i) == LUA_TNIL) ? 1 : 2;
3538+}
3539+
3540+
3541+/*
3542+** Traversal function for 'ipairs' for tables with metamethods
3543+*/
3544 static int ipairsaux (lua_State *L) {
3545- int i = luaL_checkint(L, 2);
3546- luaL_checktype(L, 1, LUA_TTABLE);
3547- i++; /* next value */
3548+ lua_Integer i = luaL_checkinteger(L, 2) + 1;
3549 lua_pushinteger(L, i);
3550- lua_rawgeti(L, 1, i);
3551- return (lua_isnil(L, -1)) ? 1 : 2;
3552+ return (lua_geti(L, 1, i) == LUA_TNIL) ? 1 : 2;
3553 }
3554
3555
3556+/*
3557+** This function will use either 'ipairsaux' or 'ipairsaux_raw' to
3558+** traverse a table, depending on whether the table has metamethods
3559+** that can affect the traversal.
3560+*/
3561 static int luaB_ipairs (lua_State *L) {
3562- return pairsmeta(L, "__ipairs", 1, ipairsaux);
3563+ lua_CFunction iter = (luaL_getmetafield(L, 1, "__index") != LUA_TNIL)
3564+ ? ipairsaux : ipairsaux_raw;
3565+#if defined(LUA_COMPAT_IPAIRS)
3566+ return pairsmeta(L, "__ipairs", 1, iter);
3567+#else
3568+ luaL_checkany(L, 1);
3569+ lua_pushcfunction(L, iter); /* iteration function */
3570+ lua_pushvalue(L, 1); /* state */
3571+ lua_pushinteger(L, 0); /* initial value */
3572+ return 3;
3573+#endif
3574 }
3575
3576
3577@@ -284,7 +325,7 @@
3578
3579
3580 /*
3581-** Reader for generic `load' function: `lua_load' uses the
3582+** Reader for generic 'load' function: 'lua_load' uses the
3583 ** stack for internal stuff, so the reader cannot change the
3584 ** stack top. Instead, it keeps its resulting string in a
3585 ** reserved slot inside the stack.
3586@@ -328,7 +369,8 @@
3587 /* }====================================================== */
3588
3589
3590-static int dofilecont (lua_State *L) {
3591+static int dofilecont (lua_State *L, int d1, lua_KContext d2) {
3592+ (void)d1; (void)d2; /* only to match 'lua_Kfunction' prototype */
3593 return lua_gettop(L) - 1;
3594 }
3595
3596@@ -339,14 +381,20 @@
3597 if (luaL_loadfile(L, fname) != LUA_OK)
3598 return lua_error(L);
3599 lua_callk(L, 0, LUA_MULTRET, 0, dofilecont);
3600- return dofilecont(L);
3601+ return dofilecont(L, 0, 0);
3602 }
3603
3604
3605 static int luaB_assert (lua_State *L) {
3606- if (!lua_toboolean(L, 1))
3607- return luaL_error(L, "%s", luaL_optstring(L, 2, "assertion failed!"));
3608- return lua_gettop(L);
3609+ if (lua_toboolean(L, 1)) /* condition is true? */
3610+ return lua_gettop(L); /* return all arguments */
3611+ else { /* error */
3612+ luaL_checkany(L, 1); /* there must be a condition */
3613+ lua_remove(L, 1); /* remove it */
3614+ lua_pushliteral(L, "assertion failed!"); /* default message */
3615+ lua_settop(L, 1); /* leave only message (default if no other one) */
3616+ return luaB_error(L); /* call 'error' */
3617+ }
3618 }
3619
3620
3621@@ -357,53 +405,57 @@
3622 return 1;
3623 }
3624 else {
3625- int i = luaL_checkint(L, 1);
3626+ lua_Integer i = luaL_checkinteger(L, 1);
3627 if (i < 0) i = n + i;
3628 else if (i > n) i = n;
3629 luaL_argcheck(L, 1 <= i, 1, "index out of range");
3630- return n - i;
3631+ return n - (int)i;
3632 }
3633 }
3634
3635
3636-static int finishpcall (lua_State *L, int status) {
3637- if (!lua_checkstack(L, 1)) { /* no space for extra boolean? */
3638- lua_settop(L, 0); /* create space for return values */
3639- lua_pushboolean(L, 0);
3640- lua_pushstring(L, "stack overflow");
3641+/*
3642+** Continuation function for 'pcall' and 'xpcall'. Both functions
3643+** already pushed a 'true' before doing the call, so in case of success
3644+** 'finishpcall' only has to return everything in the stack minus
3645+** 'extra' values (where 'extra' is exactly the number of items to be
3646+** ignored).
3647+*/
3648+static int finishpcall (lua_State *L, int status, lua_KContext extra) {
3649+ if (status != LUA_OK && status != LUA_YIELD) { /* error? */
3650+ lua_pushboolean(L, 0); /* first result (false) */
3651+ lua_pushvalue(L, -2); /* error message */
3652 return 2; /* return false, msg */
3653 }
3654- lua_pushboolean(L, status); /* first result (status) */
3655- lua_replace(L, 1); /* put first result in first slot */
3656- return lua_gettop(L);
3657-}
3658-
3659-
3660-static int pcallcont (lua_State *L) {
3661- int status = lua_getctx(L, NULL);
3662- return finishpcall(L, (status == LUA_YIELD));
3663+ else
3664+ return lua_gettop(L) - (int)extra; /* return all results */
3665 }
3666
3667
3668 static int luaB_pcall (lua_State *L) {
3669 int status;
3670 luaL_checkany(L, 1);
3671- lua_pushnil(L);
3672- lua_insert(L, 1); /* create space for status result */
3673- status = lua_pcallk(L, lua_gettop(L) - 2, LUA_MULTRET, 0, 0, pcallcont);
3674- return finishpcall(L, (status == LUA_OK));
3675+ lua_pushboolean(L, 1); /* first result if no errors */
3676+ lua_insert(L, 1); /* put it in place */
3677+ status = lua_pcallk(L, lua_gettop(L) - 2, LUA_MULTRET, 0, 0, finishpcall);
3678+ return finishpcall(L, status, 0);
3679 }
3680
3681
3682+/*
3683+** Do a protected call with error handling. After 'lua_rotate', the
3684+** stack will have <f, err, true, f, [args...]>; so, the function passes
3685+** 2 to 'finishpcall' to skip the 2 first values when returning results.
3686+*/
3687 static int luaB_xpcall (lua_State *L) {
3688 int status;
3689 int n = lua_gettop(L);
3690- luaL_argcheck(L, n >= 2, 2, "value expected");
3691- lua_pushvalue(L, 1); /* exchange function... */
3692- lua_copy(L, 2, 1); /* ...and error handler */
3693- lua_replace(L, 2);
3694- status = lua_pcallk(L, n - 2, LUA_MULTRET, 1, 0, pcallcont);
3695- return finishpcall(L, (status == LUA_OK));
3696+ luaL_checktype(L, 2, LUA_TFUNCTION); /* check error function */
3697+ lua_pushboolean(L, 1); /* first result */
3698+ lua_pushvalue(L, 1); /* function */
3699+ lua_rotate(L, 3, 2); /* move them below function's arguments */
3700+ status = lua_pcallk(L, n - 2, LUA_MULTRET, 2, 2, finishpcall);
3701+ return finishpcall(L, status, 2);
3702 }
3703
3704
3705@@ -438,21 +490,31 @@
3706 {"setmetatable", luaB_setmetatable},
3707 {"tonumber", luaB_tonumber},
3708 {"tostring", luaB_tostring},
3709- {"type", luaB_type},
3710 {"xpcall", luaB_xpcall},
3711+ /* placeholders */
3712+ {"type", NULL},
3713+ {"_G", NULL},
3714+ {"_VERSION", NULL},
3715 {NULL, NULL}
3716 };
3717
3718
3719 LUAMOD_API int luaopen_base (lua_State *L) {
3720+ int i;
3721+ /* open lib into global table */
3722+ lua_pushglobaltable(L);
3723+ luaL_setfuncs(L, base_funcs, 0);
3724 /* set global _G */
3725- lua_pushglobaltable(L);
3726- lua_pushglobaltable(L);
3727+ lua_pushvalue(L, -1);
3728 lua_setfield(L, -2, "_G");
3729- /* open lib into global table */
3730- luaL_setfuncs(L, base_funcs, 0);
3731+ /* set global _VERSION */
3732 lua_pushliteral(L, LUA_VERSION);
3733- lua_setfield(L, -2, "_VERSION"); /* set global _VERSION */
3734+ lua_setfield(L, -2, "_VERSION");
3735+ /* set function 'type' with proper upvalues */
3736+ for (i = 0; i < LUA_NUMTAGS; i++) /* push all type names as upvalues */
3737+ lua_pushstring(L, lua_typename(L, i));
3738+ lua_pushcclosure(L, luaB_type, LUA_NUMTAGS);
3739+ lua_setfield(L, -2, "type");
3740 return 1;
3741 }
3742
3743@@ -461,33 +523,46 @@
3744 luaL_checktype(L, -1, LUA_TTABLE);
3745 luaL_checkstack(L, 2, NULL);
3746
3747- if (forUnpersist) {
3748- lua_pushstring(L, "__eris.baselib_pcallcont");
3749- lua_pushcfunction(L, pcallcont);
3750- }
3751- else {
3752- lua_pushcfunction(L, pcallcont);
3753- lua_pushstring(L, "__eris.baselib_pcallcont");
3754- }
3755- lua_rawset(L, -3);
3756-
3757- if (forUnpersist) {
3758- lua_pushstring(L, "__eris.baselib_luaB_next");
3759- lua_pushcfunction(L, luaB_next);
3760- }
3761- else {
3762- lua_pushcfunction(L, luaB_next);
3763- lua_pushstring(L, "__eris.baselib_luaB_next");
3764- }
3765- lua_rawset(L, -3);
3766-
3767- if (forUnpersist) {
3768- lua_pushstring(L, "__eris.baselib_ipairsaux");
3769- lua_pushcfunction(L, ipairsaux);
3770- }
3771- else {
3772- lua_pushcfunction(L, ipairsaux);
3773- lua_pushstring(L, "__eris.baselib_ipairsaux");
3774+ /* NOTE: This is a terrible, terrible hack. We push a continuation function
3775+ * as a normal C function. We kinda have to, though, to allow proper lookup
3776+ * in the ref table, and it is never ever called, so we get away with it. */
3777+ if (forUnpersist) {
3778+ lua_pushstring(L, "__eris.baselib_finishpcall");
3779+ lua_pushcfunction(L, (lua_CFunction)finishpcall);
3780+ }
3781+ else {
3782+ lua_pushcfunction(L, (lua_CFunction)finishpcall);
3783+ lua_pushstring(L, "__eris.baselib_finishpcall");
3784+ }
3785+ lua_rawset(L, -3);
3786+
3787+ if (forUnpersist) {
3788+ lua_pushstring(L, "__eris.baselib_luaB_next");
3789+ lua_pushcfunction(L, luaB_next);
3790+ }
3791+ else {
3792+ lua_pushcfunction(L, luaB_next);
3793+ lua_pushstring(L, "__eris.baselib_luaB_next");
3794+ }
3795+ lua_rawset(L, -3);
3796+
3797+ if (forUnpersist) {
3798+ lua_pushstring(L, "__eris.baselib_ipairsaux");
3799+ lua_pushcfunction(L, ipairsaux);
3800+ }
3801+ else {
3802+ lua_pushcfunction(L, ipairsaux);
3803+ lua_pushstring(L, "__eris.baselib_ipairsaux");
3804+ }
3805+ lua_rawset(L, -3);
3806+
3807+ if (forUnpersist) {
3808+ lua_pushstring(L, "__eris.baselib_ipairsaux_raw");
3809+ lua_pushcfunction(L, ipairsaux_raw);
3810+ }
3811+ else {
3812+ lua_pushcfunction(L, ipairsaux_raw);
3813+ lua_pushstring(L, "__eris.baselib_ipairsaux_raw");
3814 }
3815 lua_rawset(L, -3);
3816 }
3817
3818=== modified file 'src/third_party/eris/lbitlib.c'
3819--- src/third_party/eris/lbitlib.c 2014-02-22 14:47:28 +0000
3820+++ src/third_party/eris/lbitlib.c 2016-04-10 16:54:20 +0000
3821@@ -1,5 +1,5 @@
3822 /*
3823-** $Id: lbitlib.c,v 1.18.1.2 2013/07/09 18:01:41 roberto Exp $
3824+** $Id: lbitlib.c,v 1.28 2014/11/02 19:19:04 roberto Exp $
3825 ** Standard library for bitwise operations
3826 ** See Copyright Notice in lua.h
3827 */
3828@@ -7,20 +7,32 @@
3829 #define lbitlib_c
3830 #define LUA_LIB
3831
3832+#include "lprefix.h"
3833+
3834+
3835 #include "lua.h"
3836
3837 #include "lauxlib.h"
3838 #include "lualib.h"
3839
3840
3841+#if defined(LUA_COMPAT_BITLIB) /* { */
3842+
3843+
3844 /* number of bits to consider in a number */
3845 #if !defined(LUA_NBITS)
3846 #define LUA_NBITS 32
3847 #endif
3848
3849
3850+/*
3851+** a lua_Unsigned with its first LUA_NBITS bits equal to 1. (Shift must
3852+** be made in two parts to avoid problems when LUA_NBITS is equal to the
3853+** number of bits in a lua_Unsigned.)
3854+*/
3855 #define ALLONES (~(((~(lua_Unsigned)0) << (LUA_NBITS - 1)) << 1))
3856
3857+
3858 /* macro to trim extra bits */
3859 #define trim(x) ((x) & ALLONES)
3860
3861@@ -29,13 +41,10 @@
3862 #define mask(n) (~((ALLONES << 1) << ((n) - 1)))
3863
3864
3865-typedef lua_Unsigned b_uint;
3866-
3867-
3868-
3869-static b_uint andaux (lua_State *L) {
3870+
3871+static lua_Unsigned andaux (lua_State *L) {
3872 int i, n = lua_gettop(L);
3873- b_uint r = ~(b_uint)0;
3874+ lua_Unsigned r = ~(lua_Unsigned)0;
3875 for (i = 1; i <= n; i++)
3876 r &= luaL_checkunsigned(L, i);
3877 return trim(r);
3878@@ -43,14 +52,14 @@
3879
3880
3881 static int b_and (lua_State *L) {
3882- b_uint r = andaux(L);
3883+ lua_Unsigned r = andaux(L);
3884 lua_pushunsigned(L, r);
3885 return 1;
3886 }
3887
3888
3889 static int b_test (lua_State *L) {
3890- b_uint r = andaux(L);
3891+ lua_Unsigned r = andaux(L);
3892 lua_pushboolean(L, r != 0);
3893 return 1;
3894 }
3895@@ -58,7 +67,7 @@
3896
3897 static int b_or (lua_State *L) {
3898 int i, n = lua_gettop(L);
3899- b_uint r = 0;
3900+ lua_Unsigned r = 0;
3901 for (i = 1; i <= n; i++)
3902 r |= luaL_checkunsigned(L, i);
3903 lua_pushunsigned(L, trim(r));
3904@@ -68,7 +77,7 @@
3905
3906 static int b_xor (lua_State *L) {
3907 int i, n = lua_gettop(L);
3908- b_uint r = 0;
3909+ lua_Unsigned r = 0;
3910 for (i = 1; i <= n; i++)
3911 r ^= luaL_checkunsigned(L, i);
3912 lua_pushunsigned(L, trim(r));
3913@@ -77,13 +86,13 @@
3914
3915
3916 static int b_not (lua_State *L) {
3917- b_uint r = ~luaL_checkunsigned(L, 1);
3918+ lua_Unsigned r = ~luaL_checkunsigned(L, 1);
3919 lua_pushunsigned(L, trim(r));
3920 return 1;
3921 }
3922
3923
3924-static int b_shift (lua_State *L, b_uint r, int i) {
3925+static int b_shift (lua_State *L, lua_Unsigned r, lua_Integer i) {
3926 if (i < 0) { /* shift right? */
3927 i = -i;
3928 r = trim(r);
3929@@ -101,33 +110,33 @@
3930
3931
3932 static int b_lshift (lua_State *L) {
3933- return b_shift(L, luaL_checkunsigned(L, 1), luaL_checkint(L, 2));
3934+ return b_shift(L, luaL_checkunsigned(L, 1), luaL_checkinteger(L, 2));
3935 }
3936
3937
3938 static int b_rshift (lua_State *L) {
3939- return b_shift(L, luaL_checkunsigned(L, 1), -luaL_checkint(L, 2));
3940+ return b_shift(L, luaL_checkunsigned(L, 1), -luaL_checkinteger(L, 2));
3941 }
3942
3943
3944 static int b_arshift (lua_State *L) {
3945- b_uint r = luaL_checkunsigned(L, 1);
3946- int i = luaL_checkint(L, 2);
3947- if (i < 0 || !(r & ((b_uint)1 << (LUA_NBITS - 1))))
3948+ lua_Unsigned r = luaL_checkunsigned(L, 1);
3949+ lua_Integer i = luaL_checkinteger(L, 2);
3950+ if (i < 0 || !(r & ((lua_Unsigned)1 << (LUA_NBITS - 1))))
3951 return b_shift(L, r, -i);
3952 else { /* arithmetic shift for 'negative' number */
3953 if (i >= LUA_NBITS) r = ALLONES;
3954 else
3955- r = trim((r >> i) | ~(~(b_uint)0 >> i)); /* add signal bit */
3956+ r = trim((r >> i) | ~(trim(~(lua_Unsigned)0) >> i)); /* add signal bit */
3957 lua_pushunsigned(L, r);
3958 return 1;
3959 }
3960 }
3961
3962
3963-static int b_rot (lua_State *L, int i) {
3964- b_uint r = luaL_checkunsigned(L, 1);
3965- i &= (LUA_NBITS - 1); /* i = i % NBITS */
3966+static int b_rot (lua_State *L, lua_Integer d) {
3967+ lua_Unsigned r = luaL_checkunsigned(L, 1);
3968+ int i = d & (LUA_NBITS - 1); /* i = d % NBITS */
3969 r = trim(r);
3970 if (i != 0) /* avoid undefined shift of LUA_NBITS when i == 0 */
3971 r = (r << i) | (r >> (LUA_NBITS - i));
3972@@ -137,12 +146,12 @@
3973
3974
3975 static int b_lrot (lua_State *L) {
3976- return b_rot(L, luaL_checkint(L, 2));
3977+ return b_rot(L, luaL_checkinteger(L, 2));
3978 }
3979
3980
3981 static int b_rrot (lua_State *L) {
3982- return b_rot(L, -luaL_checkint(L, 2));
3983+ return b_rot(L, -luaL_checkinteger(L, 2));
3984 }
3985
3986
3987@@ -153,20 +162,20 @@
3988 ** 'width' being used uninitialized.)
3989 */
3990 static int fieldargs (lua_State *L, int farg, int *width) {
3991- int f = luaL_checkint(L, farg);
3992- int w = luaL_optint(L, farg + 1, 1);
3993+ lua_Integer f = luaL_checkinteger(L, farg);
3994+ lua_Integer w = luaL_optinteger(L, farg + 1, 1);
3995 luaL_argcheck(L, 0 <= f, farg, "field cannot be negative");
3996 luaL_argcheck(L, 0 < w, farg + 1, "width must be positive");
3997 if (f + w > LUA_NBITS)
3998 luaL_error(L, "trying to access non-existent bits");
3999- *width = w;
4000- return f;
4001+ *width = (int)w;
4002+ return (int)f;
4003 }
4004
4005
4006 static int b_extract (lua_State *L) {
4007 int w;
4008- b_uint r = luaL_checkunsigned(L, 1);
4009+ lua_Unsigned r = trim(luaL_checkunsigned(L, 1));
4010 int f = fieldargs(L, 2, &w);
4011 r = (r >> f) & mask(w);
4012 lua_pushunsigned(L, r);
4013@@ -176,8 +185,8 @@
4014
4015 static int b_replace (lua_State *L) {
4016 int w;
4017- b_uint r = luaL_checkunsigned(L, 1);
4018- b_uint v = luaL_checkunsigned(L, 2);
4019+ lua_Unsigned r = trim(luaL_checkunsigned(L, 1));
4020+ lua_Unsigned v = luaL_checkunsigned(L, 2);
4021 int f = fieldargs(L, 3, &w);
4022 int m = mask(w);
4023 v &= m; /* erase bits outside given width */
4024@@ -210,3 +219,12 @@
4025 return 1;
4026 }
4027
4028+
4029+#else /* }{ */
4030+
4031+
4032+LUAMOD_API int luaopen_bit32 (lua_State *L) {
4033+ return luaL_error(L, "library 'bit32' has been deprecated");
4034+}
4035+
4036+#endif /* } */
4037
4038=== modified file 'src/third_party/eris/lcode.c'
4039--- src/third_party/eris/lcode.c 2014-02-22 14:47:28 +0000
4040+++ src/third_party/eris/lcode.c 2016-04-10 16:54:20 +0000
4041@@ -1,15 +1,18 @@
4042 /*
4043-** $Id: lcode.c,v 2.62.1.1 2013/04/12 18:48:47 roberto Exp $
4044+** $Id: lcode.c,v 2.99 2014/12/29 16:49:25 roberto Exp $
4045 ** Code generator for Lua
4046 ** See Copyright Notice in lua.h
4047 */
4048
4049-
4050-#include <stdlib.h>
4051-
4052 #define lcode_c
4053 #define LUA_CORE
4054
4055+#include "lprefix.h"
4056+
4057+
4058+#include <math.h>
4059+#include <stdlib.h>
4060+
4061 #include "lua.h"
4062
4063 #include "lcode.h"
4064@@ -26,11 +29,25 @@
4065 #include "lvm.h"
4066
4067
4068+/* Maximum number of registers in a Lua function */
4069+#define MAXREGS 250
4070+
4071+
4072 #define hasjumps(e) ((e)->t != (e)->f)
4073
4074
4075-static int isnumeral(expdesc *e) {
4076- return (e->k == VKNUM && e->t == NO_JUMP && e->f == NO_JUMP);
4077+static int tonumeral(expdesc *e, TValue *v) {
4078+ if (e->t != NO_JUMP || e->f != NO_JUMP)
4079+ return 0; /* not a numeral */
4080+ switch (e->k) {
4081+ case VKINT:
4082+ if (v) setivalue(v, e->u.ival);
4083+ return 1;
4084+ case VKFLT:
4085+ if (v) setfltvalue(v, e->u.nval);
4086+ return 1;
4087+ default: return 0;
4088+ }
4089 }
4090
4091
4092@@ -88,7 +105,7 @@
4093
4094
4095 /*
4096-** returns current `pc' and marks it as a jump target (to avoid wrong
4097+** returns current 'pc' and marks it as a jump target (to avoid wrong
4098 ** optimizations with consecutive instructions not in the same basic block).
4099 */
4100 int luaK_getlabel (FuncState *fs) {
4101@@ -176,7 +193,7 @@
4102 }
4103
4104
4105-LUAI_FUNC void luaK_patchclose (FuncState *fs, int list, int level) {
4106+void luaK_patchclose (FuncState *fs, int list, int level) {
4107 level++; /* argument is +1 to reserve 0 as non-op */
4108 while (list != NO_JUMP) {
4109 int next = getjump(fs, list);
4110@@ -211,7 +228,7 @@
4111
4112 static int luaK_code (FuncState *fs, Instruction i) {
4113 Proto *f = fs->f;
4114- dischargejpc(fs); /* `pc' will change */
4115+ dischargejpc(fs); /* 'pc' will change */
4116 /* put new instruction in code array */
4117 luaM_growvector(fs->ls->L, f->code, fs->pc, f->sizecode, Instruction,
4118 MAX_INT, "opcodes");
4119@@ -261,7 +278,7 @@
4120 void luaK_checkstack (FuncState *fs, int n) {
4121 int newstack = fs->freereg + n;
4122 if (newstack > fs->f->maxstacksize) {
4123- if (newstack >= MAXSTACK)
4124+ if (newstack >= MAXREGS)
4125 luaX_syntaxerror(fs->ls, "function or expression too complex");
4126 fs->f->maxstacksize = cast_byte(newstack);
4127 }
4128@@ -288,25 +305,28 @@
4129 }
4130
4131
4132+/*
4133+** Use scanner's table to cache position of constants in constant list
4134+** and try to reuse constants
4135+*/
4136 static int addk (FuncState *fs, TValue *key, TValue *v) {
4137 lua_State *L = fs->ls->L;
4138- TValue *idx = luaH_set(L, fs->h, key);
4139 Proto *f = fs->f;
4140+ TValue *idx = luaH_set(L, fs->ls->h, key); /* index scanner table */
4141 int k, oldsize;
4142- if (ttisnumber(idx)) {
4143- lua_Number n = nvalue(idx);
4144- lua_number2int(k, n);
4145- if (luaV_rawequalobj(&f->k[k], v))
4146- return k;
4147- /* else may be a collision (e.g., between 0.0 and "\0\0\0\0\0\0\0\0");
4148- go through and create a new entry for this value */
4149+ if (ttisinteger(idx)) { /* is there an index there? */
4150+ k = cast_int(ivalue(idx));
4151+ /* correct value? (warning: must distinguish floats from integers!) */
4152+ if (k < fs->nk && ttype(&f->k[k]) == ttype(v) &&
4153+ luaV_rawequalobj(&f->k[k], v))
4154+ return k; /* reuse index */
4155 }
4156 /* constant not found; create a new entry */
4157 oldsize = f->sizek;
4158 k = fs->nk;
4159 /* numerical value does not need GC barrier;
4160 table has no metatable, so it does not need to invalidate cache */
4161- setnvalue(idx, cast_num(k));
4162+ setivalue(idx, k);
4163 luaM_growvector(L, f->k, k, f->sizek, TValue, MAXARG_Ax, "constants");
4164 while (oldsize < f->sizek) setnilvalue(&f->k[oldsize++]);
4165 setobj(L, &f->k[k], v);
4166@@ -323,20 +343,23 @@
4167 }
4168
4169
4170-int luaK_numberK (FuncState *fs, lua_Number r) {
4171- int n;
4172- lua_State *L = fs->ls->L;
4173+/*
4174+** Integers use userdata as keys to avoid collision with floats with same
4175+** value; conversion to 'void*' used only for hashing, no "precision"
4176+** problems
4177+*/
4178+int luaK_intK (FuncState *fs, lua_Integer n) {
4179+ TValue k, o;
4180+ setpvalue(&k, cast(void*, cast(size_t, n)));
4181+ setivalue(&o, n);
4182+ return addk(fs, &k, &o);
4183+}
4184+
4185+
4186+static int luaK_numberK (FuncState *fs, lua_Number r) {
4187 TValue o;
4188- setnvalue(&o, r);
4189- if (r == 0 || luai_numisnan(NULL, r)) { /* handle -0 and NaN */
4190- /* use raw representation as key to avoid numeric problems */
4191- setsvalue(L, L->top++, luaS_newlstr(L, (char *)&r, sizeof(r)));
4192- n = addk(fs, L->top - 1, &o);
4193- L->top--;
4194- }
4195- else
4196- n = addk(fs, &o, &o); /* regular case */
4197- return n;
4198+ setfltvalue(&o, r);
4199+ return addk(fs, &o, &o);
4200 }
4201
4202
4203@@ -351,7 +374,7 @@
4204 TValue k, v;
4205 setnilvalue(&v);
4206 /* cannot use nil as key; instead use table itself to represent nil */
4207- sethvalue(fs->ls->L, &k, fs->h);
4208+ sethvalue(fs->ls->L, &k, fs->ls->h);
4209 return addk(fs, &k, &v);
4210 }
4211
4212@@ -433,10 +456,14 @@
4213 luaK_codek(fs, reg, e->u.info);
4214 break;
4215 }
4216- case VKNUM: {
4217+ case VKFLT: {
4218 luaK_codek(fs, reg, luaK_numberK(fs, e->u.nval));
4219 break;
4220 }
4221+ case VKINT: {
4222+ luaK_codek(fs, reg, luaK_intK(fs, e->u.ival));
4223+ break;
4224+ }
4225 case VRELOCABLE: {
4226 Instruction *pc = &getcode(fs, e);
4227 SETARG_A(*pc, reg);
4228@@ -468,7 +495,7 @@
4229 static void exp2reg (FuncState *fs, expdesc *e, int reg) {
4230 discharge2reg(fs, e, reg);
4231 if (e->k == VJMP)
4232- luaK_concat(fs, &e->t, e->u.info); /* put this jump in `t' list */
4233+ luaK_concat(fs, &e->t, e->u.info); /* put this jump in 't' list */
4234 if (hasjumps(e)) {
4235 int final; /* position after whole expression */
4236 int p_f = NO_JUMP; /* position of an eventual LOAD false */
4237@@ -538,13 +565,19 @@
4238 }
4239 else break;
4240 }
4241- case VKNUM: {
4242+ case VKINT: {
4243+ e->u.info = luaK_intK(fs, e->u.ival);
4244+ e->k = VK;
4245+ goto vk;
4246+ }
4247+ case VKFLT: {
4248 e->u.info = luaK_numberK(fs, e->u.nval);
4249 e->k = VK;
4250 /* go through */
4251 }
4252 case VK: {
4253- if (e->u.info <= MAXINDEXRK) /* constant fits in argC? */
4254+ vk:
4255+ if (e->u.info <= MAXINDEXRK) /* constant fits in 'argC'? */
4256 return RKASK(e->u.info);
4257 else break;
4258 }
4259@@ -627,7 +660,7 @@
4260 pc = e->u.info;
4261 break;
4262 }
4263- case VK: case VKNUM: case VTRUE: {
4264+ case VK: case VKFLT: case VKINT: case VTRUE: {
4265 pc = NO_JUMP; /* always true; do nothing */
4266 break;
4267 }
4268@@ -636,7 +669,7 @@
4269 break;
4270 }
4271 }
4272- luaK_concat(fs, &e->f, pc); /* insert last jump in `f' list */
4273+ luaK_concat(fs, &e->f, pc); /* insert last jump in 'f' list */
4274 luaK_patchtohere(fs, e->t);
4275 e->t = NO_JUMP;
4276 }
4277@@ -659,7 +692,7 @@
4278 break;
4279 }
4280 }
4281- luaK_concat(fs, &e->t, pc); /* insert last jump in `t' list */
4282+ luaK_concat(fs, &e->t, pc); /* insert last jump in 't' list */
4283 luaK_patchtohere(fs, e->f);
4284 e->f = NO_JUMP;
4285 }
4286@@ -672,7 +705,7 @@
4287 e->k = VTRUE;
4288 break;
4289 }
4290- case VK: case VKNUM: case VTRUE: {
4291+ case VK: case VKFLT: case VKINT: case VTRUE: {
4292 e->k = VFALSE;
4293 break;
4294 }
4295@@ -710,25 +743,70 @@
4296 }
4297
4298
4299-static int constfolding (OpCode op, expdesc *e1, expdesc *e2) {
4300- lua_Number r;
4301- if (!isnumeral(e1) || !isnumeral(e2)) return 0;
4302- if ((op == OP_DIV || op == OP_MOD) && e2->u.nval == 0)
4303- return 0; /* do not attempt to divide by 0 */
4304- r = luaO_arith(op - OP_ADD + LUA_OPADD, e1->u.nval, e2->u.nval);
4305- e1->u.nval = r;
4306+/*
4307+** return false if folding can raise an error
4308+*/
4309+static int validop (int op, TValue *v1, TValue *v2) {
4310+ switch (op) {
4311+ case LUA_OPBAND: case LUA_OPBOR: case LUA_OPBXOR:
4312+ case LUA_OPSHL: case LUA_OPSHR: case LUA_OPBNOT: { /* conversion errors */
4313+ lua_Integer i;
4314+ return (tointeger(v1, &i) && tointeger(v2, &i));
4315+ }
4316+ case LUA_OPDIV: case LUA_OPIDIV: case LUA_OPMOD: /* division by 0 */
4317+ return (nvalue(v2) != 0);
4318+ default: return 1; /* everything else is valid */
4319+ }
4320+}
4321+
4322+
4323+/*
4324+** Try to "constant-fold" an operation; return 1 iff successful
4325+*/
4326+static int constfolding (FuncState *fs, int op, expdesc *e1, expdesc *e2) {
4327+ TValue v1, v2, res;
4328+ if (!tonumeral(e1, &v1) || !tonumeral(e2, &v2) || !validop(op, &v1, &v2))
4329+ return 0; /* non-numeric operands or not safe to fold */
4330+ luaO_arith(fs->ls->L, op, &v1, &v2, &res); /* does operation */
4331+ if (ttisinteger(&res)) {
4332+ e1->k = VKINT;
4333+ e1->u.ival = ivalue(&res);
4334+ }
4335+ else { /* folds neither NaN nor 0.0 (to avoid collapsing with -0.0) */
4336+ lua_Number n = fltvalue(&res);
4337+ if (luai_numisnan(n) || n == 0)
4338+ return 0;
4339+ e1->k = VKFLT;
4340+ e1->u.nval = n;
4341+ }
4342 return 1;
4343 }
4344
4345
4346-static void codearith (FuncState *fs, OpCode op,
4347- expdesc *e1, expdesc *e2, int line) {
4348- if (constfolding(op, e1, e2))
4349- return;
4350+/*
4351+** Code for binary and unary expressions that "produce values"
4352+** (arithmetic operations, bitwise operations, concat, length). First
4353+** try to do constant folding (only for numeric [arithmetic and
4354+** bitwise] operations, which is what 'lua_arith' accepts).
4355+** Expression to produce final result will be encoded in 'e1'.
4356+*/
4357+static void codeexpval (FuncState *fs, OpCode op,
4358+ expdesc *e1, expdesc *e2, int line) {
4359+ lua_assert(op >= OP_ADD);
4360+ if (op <= OP_BNOT && constfolding(fs, op - OP_ADD + LUA_OPADD, e1, e2))
4361+ return; /* result has been folded */
4362 else {
4363- int o2 = (op != OP_UNM && op != OP_LEN) ? luaK_exp2RK(fs, e2) : 0;
4364- int o1 = luaK_exp2RK(fs, e1);
4365- if (o1 > o2) {
4366+ int o1, o2;
4367+ /* move operands to registers (if needed) */
4368+ if (op == OP_UNM || op == OP_BNOT || op == OP_LEN) { /* unary op? */
4369+ o2 = 0; /* no second expression */
4370+ o1 = luaK_exp2anyreg(fs, e1); /* cannot operate on constants */
4371+ }
4372+ else { /* regular case (binary operators) */
4373+ o2 = luaK_exp2RK(fs, e2); /* both operands are "RK" */
4374+ o1 = luaK_exp2RK(fs, e1);
4375+ }
4376+ if (o1 > o2) { /* free registers in proper order */
4377 freeexp(fs, e1);
4378 freeexp(fs, e2);
4379 }
4380@@ -736,8 +814,8 @@
4381 freeexp(fs, e2);
4382 freeexp(fs, e1);
4383 }
4384- e1->u.info = luaK_codeABC(fs, op, 0, o1, o2);
4385- e1->k = VRELOCABLE;
4386+ e1->u.info = luaK_codeABC(fs, op, 0, o1, o2); /* generate opcode */
4387+ e1->k = VRELOCABLE; /* all those operations are relocable */
4388 luaK_fixline(fs, line);
4389 }
4390 }
4391@@ -750,7 +828,7 @@
4392 freeexp(fs, e2);
4393 freeexp(fs, e1);
4394 if (cond == 0 && op != OP_EQ) {
4395- int temp; /* exchange args to replace by `<' or `<=' */
4396+ int temp; /* exchange args to replace by '<' or '<=' */
4397 temp = o1; o1 = o2; o2 = temp; /* o1 <==> o2 */
4398 cond = 1;
4399 }
4400@@ -761,23 +839,13 @@
4401
4402 void luaK_prefix (FuncState *fs, UnOpr op, expdesc *e, int line) {
4403 expdesc e2;
4404- e2.t = e2.f = NO_JUMP; e2.k = VKNUM; e2.u.nval = 0;
4405+ e2.t = e2.f = NO_JUMP; e2.k = VKINT; e2.u.ival = 0;
4406 switch (op) {
4407- case OPR_MINUS: {
4408- if (isnumeral(e)) /* minus constant? */
4409- e->u.nval = luai_numunm(NULL, e->u.nval); /* fold it */
4410- else {
4411- luaK_exp2anyreg(fs, e);
4412- codearith(fs, OP_UNM, e, &e2, line);
4413- }
4414+ case OPR_MINUS: case OPR_BNOT: case OPR_LEN: {
4415+ codeexpval(fs, cast(OpCode, (op - OPR_MINUS) + OP_UNM), e, &e2, line);
4416 break;
4417 }
4418 case OPR_NOT: codenot(fs, e); break;
4419- case OPR_LEN: {
4420- luaK_exp2anyreg(fs, e); /* cannot operate on constants */
4421- codearith(fs, OP_LEN, e, &e2, line);
4422- break;
4423- }
4424 default: lua_assert(0);
4425 }
4426 }
4427@@ -794,12 +862,15 @@
4428 break;
4429 }
4430 case OPR_CONCAT: {
4431- luaK_exp2nextreg(fs, v); /* operand must be on the `stack' */
4432+ luaK_exp2nextreg(fs, v); /* operand must be on the 'stack' */
4433 break;
4434 }
4435- case OPR_ADD: case OPR_SUB: case OPR_MUL: case OPR_DIV:
4436- case OPR_MOD: case OPR_POW: {
4437- if (!isnumeral(v)) luaK_exp2RK(fs, v);
4438+ case OPR_ADD: case OPR_SUB:
4439+ case OPR_MUL: case OPR_DIV: case OPR_IDIV:
4440+ case OPR_MOD: case OPR_POW:
4441+ case OPR_BAND: case OPR_BOR: case OPR_BXOR:
4442+ case OPR_SHL: case OPR_SHR: {
4443+ if (!tonumeral(v, NULL)) luaK_exp2RK(fs, v);
4444 break;
4445 }
4446 default: {
4447@@ -837,13 +908,15 @@
4448 }
4449 else {
4450 luaK_exp2nextreg(fs, e2); /* operand must be on the 'stack' */
4451- codearith(fs, OP_CONCAT, e1, e2, line);
4452+ codeexpval(fs, OP_CONCAT, e1, e2, line);
4453 }
4454 break;
4455 }
4456 case OPR_ADD: case OPR_SUB: case OPR_MUL: case OPR_DIV:
4457- case OPR_MOD: case OPR_POW: {
4458- codearith(fs, cast(OpCode, op - OPR_ADD + OP_ADD), e1, e2, line);
4459+ case OPR_IDIV: case OPR_MOD: case OPR_POW:
4460+ case OPR_BAND: case OPR_BOR: case OPR_BXOR:
4461+ case OPR_SHL: case OPR_SHR: {
4462+ codeexpval(fs, cast(OpCode, (op - OPR_ADD) + OP_ADD), e1, e2, line);
4463 break;
4464 }
4465 case OPR_EQ: case OPR_LT: case OPR_LE: {
4466
4467=== modified file 'src/third_party/eris/lcode.h'
4468--- src/third_party/eris/lcode.h 2014-02-22 14:47:28 +0000
4469+++ src/third_party/eris/lcode.h 2016-04-10 16:54:20 +0000
4470@@ -1,5 +1,5 @@
4471 /*
4472-** $Id: lcode.h,v 1.58.1.1 2013/04/12 18:48:47 roberto Exp $
4473+** $Id: lcode.h,v 1.63 2013/12/30 20:47:58 roberto Exp $
4474 ** Code generator for Lua
4475 ** See Copyright Notice in lua.h
4476 */
4477@@ -24,7 +24,11 @@
4478 ** grep "ORDER OPR" if you change these enums (ORDER OP)
4479 */
4480 typedef enum BinOpr {
4481- OPR_ADD, OPR_SUB, OPR_MUL, OPR_DIV, OPR_MOD, OPR_POW,
4482+ OPR_ADD, OPR_SUB, OPR_MUL, OPR_MOD, OPR_POW,
4483+ OPR_DIV,
4484+ OPR_IDIV,
4485+ OPR_BAND, OPR_BOR, OPR_BXOR,
4486+ OPR_SHL, OPR_SHR,
4487 OPR_CONCAT,
4488 OPR_EQ, OPR_LT, OPR_LE,
4489 OPR_NE, OPR_GT, OPR_GE,
4490@@ -33,7 +37,7 @@
4491 } BinOpr;
4492
4493
4494-typedef enum UnOpr { OPR_MINUS, OPR_NOT, OPR_LEN, OPR_NOUNOPR } UnOpr;
4495+typedef enum UnOpr { OPR_MINUS, OPR_BNOT, OPR_NOT, OPR_LEN, OPR_NOUNOPR } UnOpr;
4496
4497
4498 #define getcode(fs,e) ((fs)->f->code[(e)->u.info])
4499@@ -52,7 +56,7 @@
4500 LUAI_FUNC void luaK_reserveregs (FuncState *fs, int n);
4501 LUAI_FUNC void luaK_checkstack (FuncState *fs, int n);
4502 LUAI_FUNC int luaK_stringK (FuncState *fs, TString *s);
4503-LUAI_FUNC int luaK_numberK (FuncState *fs, lua_Number r);
4504+LUAI_FUNC int luaK_intK (FuncState *fs, lua_Integer n);
4505 LUAI_FUNC void luaK_dischargevars (FuncState *fs, expdesc *e);
4506 LUAI_FUNC int luaK_exp2anyreg (FuncState *fs, expdesc *e);
4507 LUAI_FUNC void luaK_exp2anyregup (FuncState *fs, expdesc *e);
4508
4509=== modified file 'src/third_party/eris/lcorolib.c'
4510--- src/third_party/eris/lcorolib.c 2014-02-22 14:47:28 +0000
4511+++ src/third_party/eris/lcorolib.c 2016-04-10 16:54:20 +0000
4512@@ -1,22 +1,30 @@
4513 /*
4514-** $Id: lcorolib.c,v 1.5.1.1 2013/04/12 18:48:47 roberto Exp $
4515+** $Id: lcorolib.c,v 1.9 2014/11/02 19:19:04 roberto Exp $
4516 ** Coroutine Library
4517 ** See Copyright Notice in lua.h
4518 */
4519
4520-
4521-#include <stdlib.h>
4522-
4523-
4524 #define lcorolib_c
4525 #define LUA_LIB
4526
4527+#include "lprefix.h"
4528+
4529+
4530+#include <stdlib.h>
4531+
4532 #include "lua.h"
4533
4534 #include "lauxlib.h"
4535 #include "lualib.h"
4536
4537
4538+static lua_State *getco (lua_State *L) {
4539+ lua_State *co = lua_tothread(L, 1);
4540+ luaL_argcheck(L, co, 1, "thread expected");
4541+ return co;
4542+}
4543+
4544+
4545 static int auxresume (lua_State *L, lua_State *co, int narg) {
4546 int status;
4547 if (!lua_checkstack(co, narg)) {
4548@@ -47,9 +55,8 @@
4549
4550
4551 static int luaB_coresume (lua_State *L) {
4552- lua_State *co = lua_tothread(L, 1);
4553+ lua_State *co = getco(L);
4554 int r;
4555- luaL_argcheck(L, co, 1, "coroutine expected");
4556 r = auxresume(L, co, lua_gettop(L) - 1);
4557 if (r < 0) {
4558 lua_pushboolean(L, 0);
4559@@ -59,7 +66,7 @@
4560 else {
4561 lua_pushboolean(L, 1);
4562 lua_insert(L, -(r + 1));
4563- return r + 1; /* return true + `resume' returns */
4564+ return r + 1; /* return true + 'resume' returns */
4565 }
4566 }
4567
4568@@ -102,8 +109,7 @@
4569
4570
4571 static int luaB_costatus (lua_State *L) {
4572- lua_State *co = lua_tothread(L, 1);
4573- luaL_argcheck(L, co, 1, "coroutine expected");
4574+ lua_State *co = getco(L);
4575 if (L == co) lua_pushliteral(L, "running");
4576 else {
4577 switch (lua_status(co)) {
4578@@ -129,6 +135,12 @@
4579 }
4580
4581
4582+static int luaB_yieldable (lua_State *L) {
4583+ lua_pushboolean(L, lua_isyieldable(L));
4584+ return 1;
4585+}
4586+
4587+
4588 static int luaB_corunning (lua_State *L) {
4589 int ismain = lua_pushthread(L);
4590 lua_pushboolean(L, ismain);
4591@@ -143,6 +155,7 @@
4592 {"status", luaB_costatus},
4593 {"wrap", luaB_cowrap},
4594 {"yield", luaB_yield},
4595+ {"isyieldable", luaB_yieldable},
4596 {NULL, NULL}
4597 };
4598
4599
4600=== modified file 'src/third_party/eris/lctype.c'
4601--- src/third_party/eris/lctype.c 2014-02-22 14:47:28 +0000
4602+++ src/third_party/eris/lctype.c 2016-04-10 16:54:20 +0000
4603@@ -1,5 +1,5 @@
4604 /*
4605-** $Id: lctype.c,v 1.11.1.1 2013/04/12 18:48:47 roberto Exp $
4606+** $Id: lctype.c,v 1.12 2014/11/02 19:19:04 roberto Exp $
4607 ** 'ctype' functions for Lua
4608 ** See Copyright Notice in lua.h
4609 */
4610@@ -7,6 +7,9 @@
4611 #define lctype_c
4612 #define LUA_CORE
4613
4614+#include "lprefix.h"
4615+
4616+
4617 #include "lctype.h"
4618
4619 #if !LUA_USE_CTYPE /* { */
4620
4621=== modified file 'src/third_party/eris/lctype.h'
4622--- src/third_party/eris/lctype.h 2014-02-22 14:47:28 +0000
4623+++ src/third_party/eris/lctype.h 2016-04-10 16:54:20 +0000
4624@@ -1,5 +1,5 @@
4625 /*
4626-** $Id: lctype.h,v 1.12.1.1 2013/04/12 18:48:47 roberto Exp $
4627+** $Id: lctype.h,v 1.12 2011/07/15 12:50:29 roberto Exp $
4628 ** 'ctype' functions for Lua
4629 ** See Copyright Notice in lua.h
4630 */
4631
4632=== modified file 'src/third_party/eris/ldblib.c'
4633--- src/third_party/eris/ldblib.c 2014-02-22 14:47:28 +0000
4634+++ src/third_party/eris/ldblib.c 2016-04-10 16:54:20 +0000
4635@@ -1,25 +1,30 @@
4636 /*
4637-** $Id: ldblib.c,v 1.132.1.1 2013/04/12 18:48:47 roberto Exp $
4638+** $Id: ldblib.c,v 1.148 2015/01/02 12:52:22 roberto Exp $
4639 ** Interface from Lua to its debug API
4640 ** See Copyright Notice in lua.h
4641 */
4642
4643+#define ldblib_c
4644+#define LUA_LIB
4645+
4646+#include "lprefix.h"
4647+
4648
4649 #include <stdio.h>
4650 #include <stdlib.h>
4651 #include <string.h>
4652
4653-#define ldblib_c
4654-#define LUA_LIB
4655-
4656 #include "lua.h"
4657
4658 #include "lauxlib.h"
4659 #include "lualib.h"
4660
4661
4662-#define HOOKKEY "_HKEY"
4663-
4664+/*
4665+** The hook table at registry[&HOOKKEY] maps threads to their current
4666+** hook function. (We only need the unique address of 'HOOKKEY'.)
4667+*/
4668+static const int HOOKKEY = 0;
4669
4670
4671 static int db_getregistry (lua_State *L) {
4672@@ -57,35 +62,20 @@
4673
4674
4675 static int db_setuservalue (lua_State *L) {
4676- if (lua_type(L, 1) == LUA_TLIGHTUSERDATA)
4677- luaL_argerror(L, 1, "full userdata expected, got light userdata");
4678 luaL_checktype(L, 1, LUA_TUSERDATA);
4679- if (!lua_isnoneornil(L, 2))
4680- luaL_checktype(L, 2, LUA_TTABLE);
4681+ luaL_checkany(L, 2);
4682 lua_settop(L, 2);
4683 lua_setuservalue(L, 1);
4684 return 1;
4685 }
4686
4687
4688-static void settabss (lua_State *L, const char *i, const char *v) {
4689- lua_pushstring(L, v);
4690- lua_setfield(L, -2, i);
4691-}
4692-
4693-
4694-static void settabsi (lua_State *L, const char *i, int v) {
4695- lua_pushinteger(L, v);
4696- lua_setfield(L, -2, i);
4697-}
4698-
4699-
4700-static void settabsb (lua_State *L, const char *i, int v) {
4701- lua_pushboolean(L, v);
4702- lua_setfield(L, -2, i);
4703-}
4704-
4705-
4706+/*
4707+** Auxiliary function used by several library functions: check for
4708+** an optional thread as function's first argument and set 'arg' with
4709+** 1 if this argument is present (so that functions can skip it to
4710+** access their other arguments)
4711+*/
4712 static lua_State *getthread (lua_State *L, int *arg) {
4713 if (lua_isthread(L, 1)) {
4714 *arg = 1;
4715@@ -93,44 +83,70 @@
4716 }
4717 else {
4718 *arg = 0;
4719- return L;
4720+ return L; /* function will operate over current thread */
4721 }
4722 }
4723
4724
4725+/*
4726+** Variations of 'lua_settable', used by 'db_getinfo' to put results
4727+** from 'lua_getinfo' into result table. Key is always a string;
4728+** value can be a string, an int, or a boolean.
4729+*/
4730+static void settabss (lua_State *L, const char *k, const char *v) {
4731+ lua_pushstring(L, v);
4732+ lua_setfield(L, -2, k);
4733+}
4734+
4735+static void settabsi (lua_State *L, const char *k, int v) {
4736+ lua_pushinteger(L, v);
4737+ lua_setfield(L, -2, k);
4738+}
4739+
4740+static void settabsb (lua_State *L, const char *k, int v) {
4741+ lua_pushboolean(L, v);
4742+ lua_setfield(L, -2, k);
4743+}
4744+
4745+
4746+/*
4747+** In function 'db_getinfo', the call to 'lua_getinfo' may push
4748+** results on the stack; later it creates the result table to put
4749+** these objects. Function 'treatstackoption' puts the result from
4750+** 'lua_getinfo' on top of the result table so that it can call
4751+** 'lua_setfield'.
4752+*/
4753 static void treatstackoption (lua_State *L, lua_State *L1, const char *fname) {
4754- if (L == L1) {
4755- lua_pushvalue(L, -2);
4756- lua_remove(L, -3);
4757- }
4758+ if (L == L1)
4759+ lua_rotate(L, -2, 1); /* exchange object and table */
4760 else
4761- lua_xmove(L1, L, 1);
4762- lua_setfield(L, -2, fname);
4763+ lua_xmove(L1, L, 1); /* move object to the "main" stack */
4764+ lua_setfield(L, -2, fname); /* put object into table */
4765 }
4766
4767
4768+/*
4769+** Calls 'lua_getinfo' and collects all results in a new table.
4770+*/
4771 static int db_getinfo (lua_State *L) {
4772 lua_Debug ar;
4773 int arg;
4774 lua_State *L1 = getthread(L, &arg);
4775 const char *options = luaL_optstring(L, arg+2, "flnStu");
4776- if (lua_isnumber(L, arg+1)) {
4777- if (!lua_getstack(L1, (int)lua_tointeger(L, arg+1), &ar)) {
4778+ if (lua_isfunction(L, arg + 1)) { /* info about a function? */
4779+ options = lua_pushfstring(L, ">%s", options); /* add '>' to 'options' */
4780+ lua_pushvalue(L, arg + 1); /* move function to 'L1' stack */
4781+ lua_xmove(L, L1, 1);
4782+ }
4783+ else { /* stack level */
4784+ if (!lua_getstack(L1, (int)luaL_checkinteger(L, arg + 1), &ar)) {
4785 lua_pushnil(L); /* level out of range */
4786 return 1;
4787 }
4788 }
4789- else if (lua_isfunction(L, arg+1)) {
4790- lua_pushfstring(L, ">%s", options);
4791- options = lua_tostring(L, -1);
4792- lua_pushvalue(L, arg+1);
4793- lua_xmove(L, L1, 1);
4794- }
4795- else
4796- return luaL_argerror(L, arg+1, "function or level expected");
4797 if (!lua_getinfo(L1, options, &ar))
4798 return luaL_argerror(L, arg+2, "invalid option");
4799- lua_createtable(L, 0, 2);
4800+ lua_newtable(L); /* table to collect results */
4801 if (strchr(options, 'S')) {
4802 settabss(L, "source", ar.source);
4803 settabss(L, "short_src", ar.short_src);
4804@@ -164,20 +180,21 @@
4805 lua_State *L1 = getthread(L, &arg);
4806 lua_Debug ar;
4807 const char *name;
4808- int nvar = luaL_checkint(L, arg+2); /* local-variable index */
4809+ int nvar = (int)luaL_checkinteger(L, arg + 2); /* local-variable index */
4810 if (lua_isfunction(L, arg + 1)) { /* function argument? */
4811 lua_pushvalue(L, arg + 1); /* push function */
4812 lua_pushstring(L, lua_getlocal(L, NULL, nvar)); /* push local name */
4813- return 1;
4814+ return 1; /* return only name (there is no value) */
4815 }
4816 else { /* stack-level argument */
4817- if (!lua_getstack(L1, luaL_checkint(L, arg+1), &ar)) /* out of range? */
4818+ int level = (int)luaL_checkinteger(L, arg + 1);
4819+ if (!lua_getstack(L1, level, &ar)) /* out of range? */
4820 return luaL_argerror(L, arg+1, "level out of range");
4821 name = lua_getlocal(L1, &ar, nvar);
4822 if (name) {
4823- lua_xmove(L1, L, 1); /* push local value */
4824+ lua_xmove(L1, L, 1); /* move local value */
4825 lua_pushstring(L, name); /* push name */
4826- lua_pushvalue(L, -2); /* re-order */
4827+ lua_rotate(L, -2, 1); /* re-order */
4828 return 2;
4829 }
4830 else {
4831@@ -190,26 +207,35 @@
4832
4833 static int db_setlocal (lua_State *L) {
4834 int arg;
4835+ const char *name;
4836 lua_State *L1 = getthread(L, &arg);
4837 lua_Debug ar;
4838- if (!lua_getstack(L1, luaL_checkint(L, arg+1), &ar)) /* out of range? */
4839+ int level = (int)luaL_checkinteger(L, arg + 1);
4840+ int nvar = (int)luaL_checkinteger(L, arg + 2);
4841+ if (!lua_getstack(L1, level, &ar)) /* out of range? */
4842 return luaL_argerror(L, arg+1, "level out of range");
4843 luaL_checkany(L, arg+3);
4844 lua_settop(L, arg+3);
4845 lua_xmove(L, L1, 1);
4846- lua_pushstring(L, lua_setlocal(L1, &ar, luaL_checkint(L, arg+2)));
4847+ name = lua_setlocal(L1, &ar, nvar);
4848+ if (name == NULL)
4849+ lua_pop(L1, 1); /* pop value (if not popped by 'lua_setlocal') */
4850+ lua_pushstring(L, name);
4851 return 1;
4852 }
4853
4854
4855+/*
4856+** get (if 'get' is true) or set an upvalue from a closure
4857+*/
4858 static int auxupvalue (lua_State *L, int get) {
4859 const char *name;
4860- int n = luaL_checkint(L, 2);
4861- luaL_checktype(L, 1, LUA_TFUNCTION);
4862+ int n = (int)luaL_checkinteger(L, 2); /* upvalue index */
4863+ luaL_checktype(L, 1, LUA_TFUNCTION); /* closure */
4864 name = get ? lua_getupvalue(L, 1, n) : lua_setupvalue(L, 1, n);
4865 if (name == NULL) return 0;
4866 lua_pushstring(L, name);
4867- lua_insert(L, -(get+1));
4868+ lua_insert(L, -(get+1)); /* no-op if get is false */
4869 return get + 1;
4870 }
4871
4872@@ -225,13 +251,15 @@
4873 }
4874
4875
4876+/*
4877+** Check whether a given upvalue from a given closure exists and
4878+** returns its index
4879+*/
4880 static int checkupval (lua_State *L, int argf, int argnup) {
4881- lua_Debug ar;
4882- int nup = luaL_checkint(L, argnup);
4883- luaL_checktype(L, argf, LUA_TFUNCTION);
4884- lua_pushvalue(L, argf);
4885- lua_getinfo(L, ">u", &ar);
4886- luaL_argcheck(L, 1 <= nup && nup <= ar.nups, argnup, "invalid upvalue index");
4887+ int nup = (int)luaL_checkinteger(L, argnup); /* upvalue index */
4888+ luaL_checktype(L, argf, LUA_TFUNCTION); /* closure */
4889+ luaL_argcheck(L, (lua_getupvalue(L, argf, nup) != NULL), argnup,
4890+ "invalid upvalue index");
4891 return nup;
4892 }
4893
4894@@ -253,26 +281,29 @@
4895 }
4896
4897
4898-#define gethooktable(L) luaL_getsubtable(L, LUA_REGISTRYINDEX, HOOKKEY)
4899-
4900-
4901+/*
4902+** Call hook function registered at hook table for the current
4903+** thread (if there is one)
4904+*/
4905 static void hookf (lua_State *L, lua_Debug *ar) {
4906 static const char *const hooknames[] =
4907 {"call", "return", "line", "count", "tail call"};
4908- gethooktable(L);
4909+ lua_rawgetp(L, LUA_REGISTRYINDEX, &HOOKKEY);
4910 lua_pushthread(L);
4911- lua_rawget(L, -2);
4912- if (lua_isfunction(L, -1)) {
4913- lua_pushstring(L, hooknames[(int)ar->event]);
4914+ if (lua_rawget(L, -2) == LUA_TFUNCTION) { /* is there a hook function? */
4915+ lua_pushstring(L, hooknames[(int)ar->event]); /* push event name */
4916 if (ar->currentline >= 0)
4917- lua_pushinteger(L, ar->currentline);
4918+ lua_pushinteger(L, ar->currentline); /* push current line */
4919 else lua_pushnil(L);
4920 lua_assert(lua_getinfo(L, "lS", ar));
4921- lua_call(L, 2, 0);
4922+ lua_call(L, 2, 0); /* call hook function */
4923 }
4924 }
4925
4926
4927+/*
4928+** Convert a string mask (for 'sethook') into a bit mask
4929+*/
4930 static int makemask (const char *smask, int count) {
4931 int mask = 0;
4932 if (strchr(smask, 'c')) mask |= LUA_MASKCALL;
4933@@ -283,6 +314,9 @@
4934 }
4935
4936
4937+/*
4938+** Convert a bit mask (for 'gethook') into a string mask
4939+*/
4940 static char *unmakemask (int mask, char *smask) {
4941 int i = 0;
4942 if (mask & LUA_MASKCALL) smask[i++] = 'c';
4943@@ -297,26 +331,29 @@
4944 int arg, mask, count;
4945 lua_Hook func;
4946 lua_State *L1 = getthread(L, &arg);
4947- if (lua_isnoneornil(L, arg+1)) {
4948+ if (lua_isnoneornil(L, arg+1)) { /* no hook? */
4949 lua_settop(L, arg+1);
4950 func = NULL; mask = 0; count = 0; /* turn off hooks */
4951 }
4952 else {
4953 const char *smask = luaL_checkstring(L, arg+2);
4954 luaL_checktype(L, arg+1, LUA_TFUNCTION);
4955- count = luaL_optint(L, arg+3, 0);
4956+ count = (int)luaL_optinteger(L, arg + 3, 0);
4957 func = hookf; mask = makemask(smask, count);
4958 }
4959- if (gethooktable(L) == 0) { /* creating hook table? */
4960+ if (lua_rawgetp(L, LUA_REGISTRYINDEX, &HOOKKEY) == LUA_TNIL) {
4961+ lua_createtable(L, 0, 2); /* create a hook table */
4962+ lua_pushvalue(L, -1);
4963+ lua_rawsetp(L, LUA_REGISTRYINDEX, &HOOKKEY); /* set it in position */
4964 lua_pushstring(L, "k");
4965 lua_setfield(L, -2, "__mode"); /** hooktable.__mode = "k" */
4966 lua_pushvalue(L, -1);
4967 lua_setmetatable(L, -2); /* setmetatable(hooktable) = hooktable */
4968 }
4969- lua_pushthread(L1); lua_xmove(L1, L, 1);
4970- lua_pushvalue(L, arg+1);
4971- lua_rawset(L, -3); /* set new hook */
4972- lua_sethook(L1, func, mask, count); /* set hooks */
4973+ lua_pushthread(L1); lua_xmove(L1, L, 1); /* key (thread) */
4974+ lua_pushvalue(L, arg + 1); /* value (hook function) */
4975+ lua_rawset(L, -3); /* hooktable[L1] = new Lua hook */
4976+ lua_sethook(L1, func, mask, count);
4977 return 0;
4978 }
4979
4980@@ -327,16 +364,18 @@
4981 char buff[5];
4982 int mask = lua_gethookmask(L1);
4983 lua_Hook hook = lua_gethook(L1);
4984- if (hook != NULL && hook != hookf) /* external hook? */
4985+ if (hook == NULL) /* no hook? */
4986+ lua_pushnil(L);
4987+ else if (hook != hookf) /* external hook? */
4988 lua_pushliteral(L, "external hook");
4989- else {
4990- gethooktable(L);
4991+ else { /* hook table must exist */
4992+ lua_rawgetp(L, LUA_REGISTRYINDEX, &HOOKKEY);
4993 lua_pushthread(L1); lua_xmove(L1, L, 1);
4994- lua_rawget(L, -2); /* get hook */
4995+ lua_rawget(L, -2); /* 1st result = hooktable[L1] */
4996 lua_remove(L, -2); /* remove hook table */
4997 }
4998- lua_pushstring(L, unmakemask(mask, buff));
4999- lua_pushinteger(L, lua_gethookcount(L1));
5000+ lua_pushstring(L, unmakemask(mask, buff)); /* 2nd result = mask */
The diff has been truncated for viewing.

Subscribers

People subscribed via source and target branches

to status/vote changes: