Skip to content

Commit df611ce

Browse files
committed
Merge branch 'eris' into zepto8
Additional changes: - lua.h: do not try to persist loadlib and liolib - eris.c: fix read and write functions for lua_Number - .gitignore: add z8lua
2 parents 0f649c5 + 1b9d0f3 commit df611ce

10 files changed

+2950
-11
lines changed

.gitignore

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,3 @@
11
*.o
22
*.a
3-
lua
3+
z8lua

eris.c

+2,711
Large diffs are not rendered by default.

eris.h

+153
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,153 @@
1+
/*
2+
Eris - Heavy-duty persistence for Lua 5.2.4 - Based on Pluto
3+
Copyright (c) 2013-2015 by Florian Nuecke.
4+
5+
Permission is hereby granted, free of charge, to any person obtaining a copy
6+
of this software and associated documentation files (the "Software"), to deal
7+
in the Software without restriction, including without limitation the rights
8+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9+
copies of the Software, and to permit persons to whom the Software is
10+
furnished to do so, subject to the following conditions:
11+
12+
The above copyright notice and this permission notice shall be included in
13+
all copies or substantial portions of the Software.
14+
15+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
21+
THE SOFTWARE.
22+
*/
23+
24+
/* lua.h must be included before this file */
25+
26+
#ifndef ERIS_H
27+
#define ERIS_H
28+
29+
#define ERIS_VERSION_MAJOR "1"
30+
#define ERIS_VERSION_MINOR "1"
31+
#define ERIS_VERSION_NUM 101
32+
#define ERIS_VERSION_RELEASE "1"
33+
34+
/*
35+
** ==================================================================
36+
** API
37+
** ==================================================================
38+
*/
39+
40+
/**
41+
* This provides an interface to Eris' persist functionality for writing in
42+
* an arbitrary way, using a writer.
43+
*
44+
* When called, the stack in 'L' must look like this:
45+
* 1: perms:table
46+
* 2: value:any
47+
*
48+
* 'writer' is the writer function used to store all data, 'ud' is passed to
49+
* the writer function whenever it is called.
50+
*
51+
* [-0, +0, e]
52+
*/
53+
LUA_API void eris_dump(lua_State* L, lua_Writer writer, void* ud);
54+
55+
/**
56+
* This provides an interface to Eris' unpersist functionality for reading
57+
* in an arbitrary way, using a reader.
58+
*
59+
* When called, the stack in 'L' must look like this:
60+
* 1: perms:table
61+
*
62+
* 'reader' is the reader function used to read all data, 'ud' is passed to
63+
* the reader function whenever it is called.
64+
*
65+
* The result of the operation will be pushed onto the stack.
66+
*
67+
* [-0, +1, e]
68+
*/
69+
LUA_API void eris_undump(lua_State* L, lua_Reader reader, void* ud);
70+
71+
/**
72+
* This is a stack-based alternative to eris_dump.
73+
*
74+
* It expects the perms table at the specified index 'perms' and the value to
75+
* persist at the specified index 'value'. It will push the resulting string
76+
* onto the stack on success.
77+
*
78+
* [-0, +1, e]
79+
*/
80+
LUA_API void eris_persist(lua_State* L, int perms, int value);
81+
82+
/**
83+
* This is a stack-based alternative to eris_undump.
84+
*
85+
* It expects the perms table at the specified index 'perms' and the string
86+
* containing persisted data at the specified index 'value'. It will push the
87+
* resulting value onto the stack on success.
88+
*
89+
* [-0, +1, e]
90+
*/
91+
LUA_API void eris_unpersist(lua_State* L, int perms, int value);
92+
93+
/**
94+
* Pushes the current value of a setting onto the stack.
95+
*
96+
* The name is the name of the setting to get the value for:
97+
* - 'debug' whether to write debug information when persisting function
98+
* prototypes (line numbers, local variable names, upvalue names).
99+
* - 'maxrec' the maximum complexity of objects we support (the nesting level
100+
* of tables, for example). This can be useful to avoid segmentation
101+
* faults due to too deep recursion when working with user-provided
102+
* data.
103+
* - 'path' whether to generate a "path" used to indicate where in an object
104+
* an error occurred. This adds considerable overhead and should
105+
* only be used to debug errors as they appear.
106+
* - 'spio' whether to pass IO objects along as light userdata to special
107+
* persistence functions. When persisting this will pass along the
108+
* lua_Writer and its void* in addition to the original object, when
109+
* unpersisting it will pass along a ZIO*.
110+
* - 'spkey' the name of the field in the metatable of tables and userdata
111+
* used to control persistence (on/off or special persistence).
112+
*
113+
* If an unknown name is specified this will throw an error.
114+
*
115+
* [-0, +1, e]
116+
*/
117+
LUA_API void eris_get_setting(lua_State *L, const char *name);
118+
119+
/**
120+
* Changes the value of a setting to a value on the stack.
121+
*
122+
* For the available settings see eris_set_setting(). This will get the new
123+
* value from the specified stack index 'value'. If the type does not match
124+
* this will throw an error. Specify a nil value to reset the setting to its
125+
* default value.
126+
*
127+
* [-0, +0, e]
128+
*/
129+
LUA_API void eris_set_setting(lua_State *L, const char *name, int value);
130+
131+
/*
132+
** ==================================================================
133+
** Library installer
134+
** ==================================================================
135+
*/
136+
137+
/**
138+
* This pushes a table with the two functions 'persist' and 'unpersist':
139+
* persist([perms,] value)
140+
* Where 'perms' is a table with "permanent" objects and 'value' is the
141+
* value that should be persisted. Returns the string with persisted data.
142+
* If only one value is given, the perms table is assumed to be empty.
143+
*
144+
* unpersist([perms,] value)
145+
* Where 'perms' is a table with the inverse mapping as used when
146+
* persisting the data via persist() and 'value' is the string with the
147+
* persisted data returned by persist(). Returns the unpersisted value.
148+
* If only one value is given, the perms table is assumed to be empty.
149+
*/
150+
LUA_API int luaopen_eris(lua_State* L);
151+
152+
#endif
153+

ldblib.c

+8-1
Original file line numberDiff line numberDiff line change
@@ -276,7 +276,12 @@ static void hookf (lua_State *L, lua_Debug *ar) {
276276
lua_pushinteger(L, ar->currentline);
277277
else lua_pushnil(L);
278278
lua_assert(lua_getinfo(L, "lS", ar));
279-
lua_call(L, 2, 0);
279+
int yield =
280+
(ar->event == LUA_HOOKLINE || ar->event == LUA_HOOKCOUNT)
281+
&& (lua_gethookmask(L) & LUA_MASKYIELD) ? 1 : 0;
282+
lua_call(L, 2, yield); /* call hook function */
283+
if (yield && lua_toboolean(L, -1))
284+
lua_yield(L, 0);
280285
}
281286
}
282287

@@ -286,6 +291,7 @@ static int makemask (const char *smask, int count) {
286291
if (strchr(smask, 'c')) mask |= LUA_MASKCALL;
287292
if (strchr(smask, 'r')) mask |= LUA_MASKRET;
288293
if (strchr(smask, 'l')) mask |= LUA_MASKLINE;
294+
if (strchr(smask, 'y')) mask |= LUA_MASKYIELD;
289295
if (count > 0) mask |= LUA_MASKCOUNT;
290296
return mask;
291297
}
@@ -296,6 +302,7 @@ static char *unmakemask (int mask, char *smask) {
296302
if (mask & LUA_MASKCALL) smask[i++] = 'c';
297303
if (mask & LUA_MASKRET) smask[i++] = 'r';
298304
if (mask & LUA_MASKLINE) smask[i++] = 'l';
305+
if (mask & LUA_MASKYIELD) smask[i++] = 'y';
299306
smask[i] = '\0';
300307
return smask;
301308
}

lgc.c

+2-1
Original file line numberDiff line numberDiff line change
@@ -629,8 +629,9 @@ static void clearkeys (global_State *g, GCObject *l, GCObject *f) {
629629
for (n = gnode(h, 0); n < limit; n++) {
630630
if (!ttisnil(gval(n)) && (iscleared(g, gkey(n)))) {
631631
setnilvalue(gval(n)); /* remove value ... */
632-
removeentry(n); /* and remove entry from table */
633632
}
633+
if (ttisnil(gval(n))) /* is entry empty? */
634+
removeentry(n); /* remove entry from table */
634635
}
635636
}
636637
}

linit.c

+1
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,7 @@ static const luaL_Reg loadedlibs[] = {
3333
{LUA_TABLIBNAME, luaopen_table},
3434
{LUA_STRLIBNAME, luaopen_string},
3535
{LUA_DBLIBNAME, luaopen_debug},
36+
{LUA_ERISLIBNAME, luaopen_eris},
3637
{NULL, NULL}
3738
};
3839

lparser.c

+5-6
Original file line numberDiff line numberDiff line change
@@ -324,6 +324,8 @@ static void adjust_assign (LexState *ls, int nvars, int nexps, expdesc *e) {
324324
luaK_nil(fs, reg, extra);
325325
}
326326
}
327+
if (nexps > nvars)
328+
ls->fs->freereg -= nexps - nvars; /* remove extra values */
327329
}
328330

329331

@@ -1151,11 +1153,8 @@ static void assignment (LexState *ls, struct LHS_assign *lh, int nvars) {
11511153
int nexps;
11521154
checknext(ls, '=');
11531155
nexps = explist(ls, &e);
1154-
if (nexps != nvars) {
1156+
if (nexps != nvars)
11551157
adjust_assign(ls, nvars, nexps, &e);
1156-
if (nexps > nvars)
1157-
ls->fs->freereg -= nexps - nvars; /* remove extra values */
1158-
}
11591158
else {
11601159
luaK_setoneret(ls->fs, &e); /* close last expression */
11611160
luaK_storevar(ls->fs, &lh->v, &e);
@@ -1252,7 +1251,7 @@ static void labelstat (LexState *ls, TString *label, int line) {
12521251
checkrepeated(fs, ll, label); /* check for repeated labels */
12531252
checknext(ls, TK_DBCOLON); /* skip double colon */
12541253
/* create new entry for this label */
1255-
l = newlabelentry(ls, ll, label, line, fs->pc);
1254+
l = newlabelentry(ls, ll, label, line, luaK_getlabel(fs));
12561255
skipnoopstat(ls); /* skip other no-op statements */
12571256
if (block_follow(ls, 0)) { /* label is last no-op statement in the block? */
12581257
/* assume that locals are already out of scope */
@@ -1424,7 +1423,7 @@ static int test_then_block (LexState *ls, int *escapelist) {
14241423
luaK_goiffalse(ls->fs, &v); /* will jump to label if condition is true */
14251424
enterblock(fs, &bl, 0); /* must enter block before 'goto' */
14261425
gotostat(ls, v.t); /* handle goto/break */
1427-
skipnoopstat(ls); /* skip other no-op statements */
1426+
while (testnext(ls, ';')) {} /* skip semicolons */
14281427
if (block_follow(ls, 0)) { /* 'goto' is the entire block? */
14291428
leaveblock(fs);
14301429
return short_if; /* and that is it */

lua.h

+62-1
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@
2121
#define LUA_VERSION_NUM 502
2222
#define LUA_VERSION_RELEASE "4"
2323

24-
#define LUA_VERSION "Lua " LUA_VERSION_MAJOR "." LUA_VERSION_MINOR
24+
#define LUA_VERSION "Lua+Eris " LUA_VERSION_MAJOR "." LUA_VERSION_MINOR
2525
#define LUA_RELEASE LUA_VERSION "." LUA_VERSION_RELEASE
2626
#define LUA_COPYRIGHT LUA_RELEASE " Copyright (C) 1994-2015 Lua.org, PUC-Rio"
2727
#define LUA_AUTHORS "R. Ierusalimschy, L. H. de Figueiredo, W. Celes"
@@ -347,6 +347,66 @@ LUA_API void (lua_setallocf) (lua_State *L, lua_Alloc f, void *ud);
347347

348348

349349

350+
/*
351+
** =======================================================================
352+
** Eris persistence
353+
** =======================================================================
354+
*/
355+
356+
#if defined(eris_c)
357+
/* Utility macro for populating the perms table with internal C functions. */
358+
# define eris_persist(lib, fn)\
359+
extern lua_CFunction __perm_##lib##_##fn;\
360+
if (forUnpersist) {\
361+
lua_pushstring(L, "__eris." #lib "_" #fn);\
362+
lua_pushcfunction(L, *__perm_##lib##_##fn);\
363+
}\
364+
else {\
365+
lua_pushcfunction(L, *__perm_##lib##_##fn);\
366+
lua_pushstring(L, "__eris." #lib "_" #fn);\
367+
}\
368+
lua_rawset(L, -3);
369+
#else
370+
/* Utility macro to export internal C functions to eris. */
371+
# define eris_persist(lib, fn)\
372+
static int fn (lua_State *L);\
373+
lua_CFunction __perm_##lib##_##fn = fn;
374+
#endif
375+
376+
#if defined(eris_c)
377+
/* Functions in Lua libraries used to access C functions we need to add to the
378+
* permanents table to fully support yielded coroutines. */
379+
static void populateperms(lua_State *L, bool forUnpersist)
380+
{
381+
#endif
382+
#if defined(eris_c) || defined(lstrlib_c)
383+
eris_persist(strlib, gmatch_aux)
384+
#endif
385+
/*#if defined(eris_c) || defined(loadlib_c)
386+
eris_persist(loadlib, searcher_preload)
387+
eris_persist(loadlib, searcher_Lua)
388+
eris_persist(loadlib, searcher_C)
389+
eris_persist(loadlib, searcher_Croot)
390+
#endif
391+
#if defined(eris_c) || defined(liolib_c)
392+
eris_persist(iolib, io_readline)
393+
#endif*/
394+
#if defined(eris_c) || defined(lbaselib_c)
395+
eris_persist(baselib, pcallcont)
396+
eris_persist(baselib, luaB_next)
397+
eris_persist(baselib, ipairsaux)
398+
#endif
399+
#if defined(eris_c) || defined(lcorolib_c)
400+
eris_persist(corolib, luaB_auxwrap)
401+
#endif
402+
#if defined(eris_c)
403+
}
404+
#endif
405+
406+
#undef eris_persist
407+
408+
409+
350410
/*
351411
** {======================================================================
352412
** Debug API
@@ -371,6 +431,7 @@ LUA_API void (lua_setallocf) (lua_State *L, lua_Alloc f, void *ud);
371431
#define LUA_MASKRET (1 << LUA_HOOKRET)
372432
#define LUA_MASKLINE (1 << LUA_HOOKLINE)
373433
#define LUA_MASKCOUNT (1 << LUA_HOOKCOUNT)
434+
#define LUA_MASKYIELD (1 << LUA_HOOKTAILCALL)
374435

375436
typedef struct lua_Debug lua_Debug; /* activation record */
376437

lualib.h

+3
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,9 @@ LUAMOD_API int (luaopen_debug) (lua_State *L);
4343
#define LUA_LOADLIBNAME "package"
4444
LUAMOD_API int (luaopen_package) (lua_State *L);
4545

46+
#define LUA_ERISLIBNAME "eris"
47+
LUAMOD_API int (luaopen_eris) (lua_State *L);
48+
4649

4750
/* open all previous libraries */
4851
LUALIB_API void (luaL_openlibs) (lua_State *L);

makefile

+4-1
Original file line numberDiff line numberDiff line change
@@ -42,7 +42,7 @@ LIBS = -lm
4242
CORE_T= liblua.a
4343
CORE_O= lapi.o lcode.o ldebug.o ldo.o ldump.o lfunc.o lgc.o llex.o lmem.o \
4444
lobject.o lopcodes.o lparser.o lstate.o lstring.o ltable.o ltm.o \
45-
lundump.o lvm.o lzio.o lctype.o
45+
lundump.o lvm.o lzio.o lctype.o eris.o
4646
AUX_O= lauxlib.o
4747
LIB_O= lbaselib.o lcorolib.o ldblib.o ltablib.o lstrlib.o lpico8lib.o linit.o
4848

@@ -156,5 +156,8 @@ lvm.o: lvm.c lua.h luaconf.h fix32.h ldebug.h lstate.h lobject.h \
156156
ltable.h lvm.h
157157
lzio.o: lzio.c lua.h luaconf.h fix32.h llimits.h lmem.h lstate.h \
158158
lobject.h ltm.h lzio.h
159+
eris.o: eris.c lua.h luaconf.h lauxlib.h lualib.h ldebug.h lstate.h \
160+
lobject.h llimits.h ltm.h lzio.h lmem.h ldo.h lfunc.h lstring.h lgc.h \
161+
eris.h
159162

160163
# (end of Makefile)

0 commit comments

Comments
 (0)