├── .gitignore
├── doc
├── rings.png
├── doc.css
├── license.html
├── index.html
└── manual.html
├── src
├── rings.def
├── stable.lua
└── rings.c
├── vc6
├── rings.def
├── rings.dsw
└── rings_dll.dsp
├── tests
├── sample.lua
├── sample_state.lua
└── test.lua
├── Makefile
├── config.win
├── rockspecs
├── rings-cvs-4.rockspec
├── rings-1.3.0-1.rockspec
├── rings-1.2.2-2.rockspec
├── rings-1.2.3-1.rockspec
├── rings-1.2.1rc1-1.rockspec
├── rings-1.2.0-1.rockspec
├── rings-1.2.0-2.rockspec
├── rings-1.2.1-1.rockspec
├── rings-1.2.2-1.rockspec
├── rings-cvs-2.rockspec
└── rings-cvs-3.rockspec
├── configure
├── Makefile.win
├── config
└── README.md
/.gitignore:
--------------------------------------------------------------------------------
1 | *.o
2 | *.so
3 |
--------------------------------------------------------------------------------
/doc/rings.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/keplerproject/rings/HEAD/doc/rings.png
--------------------------------------------------------------------------------
/src/rings.def:
--------------------------------------------------------------------------------
1 | LIBRARY rings.dll
2 | DESCRIPTION "Rings"
3 | VERSION 1.3.0
4 | EXPORTS
5 | luaopen_rings
6 |
--------------------------------------------------------------------------------
/vc6/rings.def:
--------------------------------------------------------------------------------
1 | LIBRARY rings.dll
2 | DESCRIPTION "Rings"
3 | VERSION 1.0
4 | EXPORTS
5 | luaopen_rings
6 |
--------------------------------------------------------------------------------
/tests/sample.lua:
--------------------------------------------------------------------------------
1 | -- $Id: sample.lua,v 1.4 2008/05/30 18:44:05 carregal Exp $
2 |
3 | require"rings"
4 |
5 | S = rings.new ()
6 |
7 | data = { 12, 13, 14, }
8 | print (S:dostring ([[
9 | aux = {}
10 | for i, v in ipairs {...} do
11 | table.insert (aux, 1, v)
12 | end
13 | return unpack (aux)]], unpack (data)))
14 |
15 | S:close ()
16 |
17 | print("OK!")
18 |
--------------------------------------------------------------------------------
/Makefile:
--------------------------------------------------------------------------------
1 | # $Id: Makefile,v 1.6 2008/05/08 22:08:31 carregal Exp $
2 |
3 | T= rings
4 | CONFIG= ./config
5 |
6 | include $(CONFIG)
7 |
8 | SRCS= src/rings.c
9 | OBJS= src/rings.o
10 |
11 | all: src/rings.so
12 |
13 | src/rings.so: $(OBJS)
14 | export MACOSX_DEPLOYMENT_TARGET="10.3"; $(CC) $(CFLAGS) $(LIB_OPTION) -o src/rings.so $(OBJS)
15 |
16 | install:
17 | mkdir -p $(DESTDIR)$(LUA_LIBDIR)
18 | cp src/rings.so $(DESTDIR)$(LUA_LIBDIR)
19 | mkdir -p $(DESTDIR)$(LUA_DIR)
20 | cp src/stable.lua $(DESTDIR)$(LUA_DIR)
21 |
22 | clean:
23 | rm -f src/rings.so $(OBJS)
24 |
--------------------------------------------------------------------------------
/config.win:
--------------------------------------------------------------------------------
1 | # Installation directories
2 | # Lua binary libraries directory (where Lua binary libraries will be installed)
3 | # This is the LUA_CPATH
4 | LUA_LIBDIR= c:\lua5.1
5 | # Lua directory (where Lua source libraries will be installed)
6 | # This is the LUA_PATH
7 | LUA_DIR= c:\lua5.1\lua
8 | # Lua includes directory
9 | LUA_INC= c:\lua5.1\include
10 | # Lua library
11 | LUA_LIB= c:\lua5.1\lua5.1.lib
12 |
13 | # OS dependent
14 | LIBNAME= $T.dll
15 |
16 | # Compilation directives
17 | WARN= /O2
18 | INCS= /I$(LUA_INC)
19 | CFLAGS= $(WARN) $(INCS)
20 | CC= cl
21 |
22 | # $Id: config.win,v 1.4 2007/05/18 19:53:06 carregal Exp $
23 |
--------------------------------------------------------------------------------
/tests/sample_state.lua:
--------------------------------------------------------------------------------
1 | -- $Id: sample_state.lua,v 1.2 2006/07/25 14:09:45 tomas Exp $
2 |
3 | require"rings"
4 |
5 | local init_cmd = [[
6 | stable = require"stable"]]
7 |
8 | local count_cmd = [[
9 | count = stable.get"shared_counter" or 0
10 | stable.set ("shared_counter", count + 1)
11 | return count
12 | ]]
13 |
14 | S = rings.new () -- new state
15 | assert(S:dostring (init_cmd))
16 | print (S:dostring (count_cmd)) -- true, 0
17 | print (S:dostring (count_cmd)) -- true, 1
18 | S:close ()
19 |
20 | S = rings.new () -- another new state
21 | assert (S:dostring (init_cmd))
22 | print (S:dostring (count_cmd)) -- true, 2
23 | S:close ()
24 |
25 | print("OK!")
26 |
--------------------------------------------------------------------------------
/rockspecs/rings-cvs-4.rockspec:
--------------------------------------------------------------------------------
1 | package = "Rings"
2 | version = "cvs-4"
3 | source = {
4 | url = "git://github.com/keplerproject/rings.git"
5 | }
6 | description = {
7 | summary = "Create new Lua states from within Lua",
8 | detailed = [[
9 | Rings is a library which provides a way to create new Lua states
10 | from within Lua. It also offers a simple way to communicate
11 | between the creator (master) and the created (slave) states.
12 | ]],
13 | license = "MIT/X11",
14 | homepage = "http://www.keplerproject.org/rings/"
15 | }
16 | dependencies = {
17 | "lua >= 5.1"
18 | }
19 | build = {
20 | type = "builtin",
21 | modules = {
22 | rings = "src/rings.c",
23 | stable = "src/stable.lua"
24 | }
25 | }
26 |
--------------------------------------------------------------------------------
/configure:
--------------------------------------------------------------------------------
1 | #!/bin/sh
2 |
3 | if [ -f config.orig ]; then
4 | mv config.orig config
5 | fi
6 |
7 | echo "Trying to where you installed Lua..."
8 |
9 | arg="${1}"
10 |
11 | if which lua; then
12 | lua_bin=`which lua`
13 | lua_bin_dir=`dirname $lua_bin`
14 | elif which ${arg}; then
15 | lua_bin=`which ${arg}`
16 | lua_bin_dir=`dirname $lua_bin`
17 | else
18 | lua_bin=`which lua51`
19 | lua_bin_dir=`dirname $lua_bin`
20 | fi
21 |
22 | lua_root=`dirname $lua_bin_dir`
23 |
24 | if [ $lua_root != "" ]; then
25 | echo "Lua is in $lua_root"
26 | echo "Changing config"
27 | sed -i.orig -e "s|/usr/local|$lua_root|" config
28 | echo "Now run 'make' and 'make install'"
29 | else
30 | echo "Lua not found, please install Lua (and put in your PATH)"
31 | fi
32 |
33 |
--------------------------------------------------------------------------------
/vc6/rings.dsw:
--------------------------------------------------------------------------------
1 | Microsoft Developer Studio Workspace File, Format Version 6.00
2 | # WARNING: DO NOT EDIT OR DELETE THIS WORKSPACE FILE!
3 |
4 | ###############################################################################
5 |
6 | Project: "rings_dll"=.\rings_dll.dsp - Package Owner=<4>
7 |
8 | Package=<5>
9 | {{{
10 | begin source code control
11 | rings
12 | ..
13 | end source code control
14 | }}}
15 |
16 | Package=<4>
17 | {{{
18 | }}}
19 |
20 | ###############################################################################
21 |
22 | Global:
23 |
24 | Package=<5>
25 | {{{
26 | }}}
27 |
28 | Package=<3>
29 | {{{
30 | }}}
31 |
32 | ###############################################################################
33 |
34 |
--------------------------------------------------------------------------------
/rockspecs/rings-1.3.0-1.rockspec:
--------------------------------------------------------------------------------
1 | package = "Rings"
2 | version = "1.3.0-1"
3 |
4 | source = {
5 | url = "http://www.keplerproject.org/rings/rings-1.3.0.tar.gz",
6 | }
7 |
8 | description = {
9 | summary = "Create new Lua states from within Lua",
10 | detailed = [[
11 | Rings is a library which provides a way to create new Lua states
12 | from within Lua. It also offers a simple way to communicate
13 | between the creator (master) and the created (slave) states.
14 | ]],
15 | license = "MIT/X11",
16 | homepage = "http://www.keplerproject.org/rings/"
17 | }
18 | dependencies = {
19 | "lua >= 5.1"
20 | }
21 | build = {
22 | type = "builtin",
23 | modules = {
24 | rings = "src/rings.c",
25 | stable = "src/stable.lua"
26 | }
27 | }
28 |
--------------------------------------------------------------------------------
/rockspecs/rings-1.2.2-2.rockspec:
--------------------------------------------------------------------------------
1 | package = "Rings"
2 | version = "1.2.2-2"
3 |
4 | source = {
5 | url = "http://luaforge.net/frs/download.php/3511/rings-1.2.2.tar.gz",
6 | }
7 |
8 | description = {
9 | summary = "Create new Lua states from within Lua",
10 | detailed = [[
11 | Rings is a library which provides a way to create new Lua states
12 | from within Lua. It also offers a simple way to communicate
13 | between the creator (master) and the created (slave) states.
14 | ]],
15 | license = "MIT/X11",
16 | homepage = "http://www.keplerproject.org/rings/"
17 | }
18 | dependencies = {
19 | "lua >= 5.1"
20 | }
21 | build = {
22 | type = "module",
23 | modules = {
24 | rings = "src/rings.c",
25 | stable = "src/stable.lua"
26 | }
27 | }
28 |
--------------------------------------------------------------------------------
/rockspecs/rings-1.2.3-1.rockspec:
--------------------------------------------------------------------------------
1 | package = "Rings"
2 | version = "1.2.3-1"
3 |
4 | source = {
5 | url = "http://cloud.github.com/downloads/keplerproject/rings/rings-1.2.3.tar.gz",
6 | }
7 |
8 | description = {
9 | summary = "Create new Lua states from within Lua",
10 | detailed = [[
11 | Rings is a library which provides a way to create new Lua states
12 | from within Lua. It also offers a simple way to communicate
13 | between the creator (master) and the created (slave) states.
14 | ]],
15 | license = "MIT/X11",
16 | homepage = "http://www.keplerproject.org/rings/"
17 | }
18 | dependencies = {
19 | "lua >= 5.1"
20 | }
21 | build = {
22 | type = "module",
23 | modules = {
24 | rings = "src/rings.c",
25 | stable = "src/stable.lua"
26 | }
27 | }
28 |
--------------------------------------------------------------------------------
/Makefile.win:
--------------------------------------------------------------------------------
1 | # $Id: Makefile.win,v 1.13 2008/02/15 21:33:02 carregal Exp $
2 |
3 | include config.win
4 |
5 | SRCS= src\rings.c
6 | OBJS= src\rings.obj
7 |
8 | .c.obj:
9 | $(CC) /c /Fo$@ $(CFLAGS) $<
10 |
11 | all: src\rings.dll
12 |
13 | src\rings.dll: src\rings.obj
14 | link /dll /def:src\rings.def /out:src\rings.dll "$(LUA_LIB)" src\rings.obj
15 | IF EXIST src\rings.dll.manifest mt -manifest src\rings.dll.manifest -outputresource:src\rings.dll;2
16 |
17 | install:
18 | IF NOT EXIST "$(LUA_LIBDIR)" mkdir "$(LUA_LIBDIR)"
19 | copy src\rings.dll "$(LUA_LIBDIR)"
20 | IF NOT EXIST "$(LUA_DIR)" mkdir "$(LUA_DIR)"
21 | copy src\stable.lua "$(LUA_DIR)"
22 |
23 | clean:
24 | del src\rings.dll src\rings.obj src\rings.lib src\rings.exp
25 | IF EXIST src\rings.dll.manifest del src\rings.dll.manifest
26 |
--------------------------------------------------------------------------------
/config:
--------------------------------------------------------------------------------
1 | # Installation directories
2 |
3 | # Default prefix
4 | PREFIX ?= /usr/local
5 |
6 | DESTDIR ?= /
7 |
8 | # System's libraries directory (where binary libraries are installed)
9 | LUA_LIBDIR ?= $(PREFIX)/lib/lua/5.1
10 |
11 | # System's lua directory (where Lua libraries are installed)
12 | LUA_DIR ?= $(PREFIX)/share/lua/5.1
13 |
14 | # Lua includes directory
15 | LUA_INC ?= $(PREFIX)/include
16 |
17 | # OS dependent
18 | LIB_OPTION ?= -shared #for Linux
19 | #LIB_OPTION ?= -bundle -undefined dynamic_lookup #for MacOS X
20 |
21 | LIBNAME ?= $T.so.$V
22 |
23 | # Compilation directives
24 | WARN ?= -O2 -Wall -fPIC -W -Waggregate-return -Wcast-align -Wmissing-prototypes -Wnested-externs -Wshadow -Wwrite-strings -Wpointer-arith -pedantic
25 | INCS ?= -I$(LUA_INC)
26 | CFLAGS ?= $(WARN) $(INCS)
27 | CC ?= gcc
28 |
29 | # $Id: config,v 1.7 2007/10/29 22:51:39 carregal Exp $
30 |
--------------------------------------------------------------------------------
/src/stable.lua:
--------------------------------------------------------------------------------
1 | ----------------------------------------------------------------------------
2 | -- Stable: State persistent table for Rings.
3 | --
4 | -- Copyright (c) 2006-2007 Kepler Project
5 | -- $Id: stable.lua,v 1.7 2008/06/30 17:52:31 carregal Exp $
6 | ----------------------------------------------------------------------------
7 |
8 | local remotedostring = assert (remotedostring, "There is no `remotedostring'. Probably not in a slave state")
9 |
10 | -- creating persistent table at master state.
11 | assert (remotedostring[[_state_persistent_table_ = _state_persistent_table_ or {}]])
12 |
13 | local _M = {}
14 |
15 | ----------------------------------------------------------------------------
16 | _COPYRIGHT = "Copyright (C) 2006 Kepler Project"
17 | _DESCRIPTION = "State persistent table"
18 | _VERSION = "Stable 1.0"
19 |
20 | ----------------------------------------------------------------------------
21 | function _M.get (i)
22 | local ok, value = remotedostring ("return _state_persistent_table_[...]", i)
23 | return value
24 | end
25 |
26 | ----------------------------------------------------------------------------
27 | function _M.set (i, v)
28 | remotedostring ("_state_persistent_table_[select(1,...)] = select(2,...)", i, v)
29 | end
30 |
31 | return _M
32 |
33 |
--------------------------------------------------------------------------------
/rockspecs/rings-1.2.1rc1-1.rockspec:
--------------------------------------------------------------------------------
1 | package = "Rings"
2 | version = "1.2.1rc1-1"
3 | source = {
4 | url = "http://rings.luaforge.net/rings-1.2.1rc1.tar.gz",
5 | }
6 | description = {
7 | summary = "Create new Lua states from within Lua",
8 | detailed = [[
9 | Rings is a library which provides a way to create new Lua states
10 | from within Lua. It also offers a simple way to communicate
11 | between the creator (master) and the created (slave) states.
12 | ]],
13 | license = "MIT/X11",
14 | homepage = "http://www.keplerproject.org/rings/"
15 | }
16 | dependencies = {
17 | "lua >= 5.1"
18 | }
19 | build = {
20 | platforms = {
21 | unix = {
22 | type = "make",
23 | build_variables = {
24 | LIB_OPTION = "$(LIBFLAG)",
25 | CFLAGS = "$(CFLAGS) -I$(LUA_INCDIR)",
26 | },
27 | install_variables = {
28 | LUA_LIBDIR = "$(LIBDIR)",
29 | LUA_DIR = "$(LUADIR)"
30 | }
31 | },
32 | win32 = {
33 | type = "make",
34 | build_variables = {
35 | LUA_LIB = "$(LUA_LIBDIR)\\lua5.1.lib",
36 | CFLAGS = "/MD $(CFLAGS) /I$(LUA_INCDIR)",
37 | },
38 | install_variables = {
39 | LUA_LIBDIR = "$(LIBDIR)",
40 | LUA_DIR = "$(LUADIR)",
41 | BIN_DIR = "$(BINDIR)"
42 | }
43 | }
44 | }
45 | }
46 |
--------------------------------------------------------------------------------
/rockspecs/rings-1.2.0-1.rockspec:
--------------------------------------------------------------------------------
1 | package = "Rings"
2 | version = "1.2.0-1"
3 | source = {
4 | url = "http://luaforge.net/frs/download.php/3168/rings-1.2.0.tar.gz",
5 | }
6 | description = {
7 | summary = "Create new Lua states from within Lua",
8 | detailed = [[
9 | Rings is a library which provides a way to create new Lua states
10 | from within Lua. It also offers a simple way to communicate
11 | between the creator (master) and the created (slave) states.
12 | ]],
13 | license = "MIT/X11",
14 | homepage = "http://www.keplerproject.org/rings/"
15 | }
16 | dependencies = {
17 | "lua >= 5.1"
18 | }
19 | build = {
20 | platforms = {
21 | unix = {
22 | type = "make",
23 | build_variables = {
24 | LIB_OPTION = "$(LIBFLAG)",
25 | CFLAGS = "$(CFLAGS) -I$(LUA_INCDIR)",
26 | },
27 | install_variables = {
28 | LUA_LIBDIR = "$(LIBDIR)",
29 | LUA_DIR = "$(LUADIR)"
30 | }
31 | },
32 | win32 = {
33 | type = "make",
34 | build_variables = {
35 | LUA_LIB = "$(LUA_LIBDIR)\\lua5.1.lib",
36 | CFLAGS = "/MD $(CFLAGS) /I$(LUA_INCDIR)",
37 | },
38 | install_variables = {
39 | LUA_LIBDIR = "$(LIBDIR)",
40 | LUA_DIR = "$(LUADIR)",
41 | BIN_DIR = "$(BINDIR)"
42 | }
43 | }
44 | }
45 | }
46 |
--------------------------------------------------------------------------------
/rockspecs/rings-1.2.0-2.rockspec:
--------------------------------------------------------------------------------
1 | package = "Rings"
2 | version = "1.2.0-2"
3 | source = {
4 | url = "http://luaforge.net/frs/download.php/3168/rings-1.2.0.tar.gz",
5 | }
6 | description = {
7 | summary = "Create new Lua states from within Lua",
8 | detailed = [[
9 | Rings is a library which provides a way to create new Lua states
10 | from within Lua. It also offers a simple way to communicate
11 | between the creator (master) and the created (slave) states.
12 | ]],
13 | license = "MIT/X11",
14 | homepage = "http://www.keplerproject.org/rings/"
15 | }
16 | dependencies = {
17 | "lua >= 5.1"
18 | }
19 | build = {
20 | platforms = {
21 | unix = {
22 | type = "make",
23 | build_variables = {
24 | LIB_OPTION = "$(LIBFLAG)",
25 | CFLAGS = "$(CFLAGS) -I$(LUA_INCDIR)",
26 | },
27 | install_variables = {
28 | LUA_LIBDIR = "$(LIBDIR)",
29 | LUA_DIR = "$(LUADIR)"
30 | }
31 | },
32 | win32 = {
33 | type = "make",
34 | build_variables = {
35 | LUA_LIB = "$(LUA_LIBDIR)\\lua5.1.lib",
36 | CFLAGS = "/MD $(CFLAGS) /I$(LUA_INCDIR)",
37 | },
38 | install_variables = {
39 | LUA_LIBDIR = "$(LIBDIR)",
40 | LUA_DIR = "$(LUADIR)",
41 | BIN_DIR = "$(BINDIR)"
42 | }
43 | }
44 | }
45 | }
46 |
--------------------------------------------------------------------------------
/rockspecs/rings-1.2.1-1.rockspec:
--------------------------------------------------------------------------------
1 | package = "Rings"
2 | version = "1.2.1-1"
3 | source = {
4 | url = "http://luaforge.net/frs/download.php/3348/rings-1.2.1.tar.gz",
5 | }
6 | description = {
7 | summary = "Create new Lua states from within Lua",
8 | detailed = [[
9 | Rings is a library which provides a way to create new Lua states
10 | from within Lua. It also offers a simple way to communicate
11 | between the creator (master) and the created (slave) states.
12 | ]],
13 | license = "MIT/X11",
14 | homepage = "http://www.keplerproject.org/rings/"
15 | }
16 | dependencies = {
17 | "lua >= 5.1"
18 | }
19 | build = {
20 | platforms = {
21 | unix = {
22 | type = "make",
23 | build_variables = {
24 | LIB_OPTION = "$(LIBFLAG)",
25 | CFLAGS = "$(CFLAGS) -I$(LUA_INCDIR)",
26 | },
27 | install_variables = {
28 | LUA_LIBDIR = "$(LIBDIR)",
29 | LUA_DIR = "$(LUADIR)"
30 | }
31 | },
32 | win32 = {
33 | type = "make",
34 | build_variables = {
35 | LUA_LIB = "$(LUA_LIBDIR)\\lua5.1.lib",
36 | CFLAGS = "/MD $(CFLAGS) /I$(LUA_INCDIR)",
37 | },
38 | install_variables = {
39 | LUA_LIBDIR = "$(LIBDIR)",
40 | LUA_DIR = "$(LUADIR)",
41 | BIN_DIR = "$(BINDIR)"
42 | }
43 | }
44 | }
45 | }
46 |
--------------------------------------------------------------------------------
/rockspecs/rings-1.2.2-1.rockspec:
--------------------------------------------------------------------------------
1 | package = "Rings"
2 | version = "1.2.2-1"
3 |
4 | source = {
5 | url = "http://luaforge.net/frs/download.php/3511/rings-1.2.2.tar.gz",
6 | }
7 |
8 | description = {
9 | summary = "Create new Lua states from within Lua",
10 | detailed = [[
11 | Rings is a library which provides a way to create new Lua states
12 | from within Lua. It also offers a simple way to communicate
13 | between the creator (master) and the created (slave) states.
14 | ]],
15 | license = "MIT/X11",
16 | homepage = "http://www.keplerproject.org/rings/"
17 | }
18 | dependencies = {
19 | "lua >= 5.1"
20 | }
21 | build = {
22 | platforms = {
23 | unix = {
24 | type = "make",
25 | build_variables = {
26 | LIB_OPTION = "$(LIBFLAG)",
27 | CFLAGS = "$(CFLAGS) -I$(LUA_INCDIR)",
28 | },
29 | install_variables = {
30 | LUA_LIBDIR = "$(LIBDIR)",
31 | LUA_DIR = "$(LUADIR)"
32 | }
33 | },
34 | win32 = {
35 | type = "make",
36 | build_variables = {
37 | LUA_LIB = "$(LUA_LIBDIR)\\lua5.1.lib",
38 | CFLAGS = "/MD $(CFLAGS) /I$(LUA_INCDIR)",
39 | },
40 | install_variables = {
41 | LUA_LIBDIR = "$(LIBDIR)",
42 | LUA_DIR = "$(LUADIR)",
43 | BIN_DIR = "$(BINDIR)"
44 | }
45 | }
46 | }
47 | }
48 |
--------------------------------------------------------------------------------
/rockspecs/rings-cvs-2.rockspec:
--------------------------------------------------------------------------------
1 | package = "Rings"
2 | version = "cvs-2"
3 | source = {
4 | url = "cvs://:pserver:anonymous:@cvs.luaforge.net:/cvsroot/rings",
5 | cvs_tag = "HEAD",
6 | }
7 | description = {
8 | summary = "Create new Lua states from within Lua",
9 | detailed = [[
10 | Rings is a library which provides a way to create new Lua states
11 | from within Lua. It also offers a simple way to communicate
12 | between the creator (master) and the created (slave) states.
13 | ]],
14 | license = "MIT/X11",
15 | homepage = "http://www.keplerproject.org/rings/"
16 | }
17 | dependencies = {
18 | "lua >= 5.1"
19 | }
20 | build = {
21 | platforms = {
22 | unix = {
23 | type = "make",
24 | build_variables = {
25 | LIB_OPTION = "$(LIBFLAG)",
26 | CFLAGS = "$(CFLAGS) -I$(LUA_INCDIR)",
27 | },
28 | install_variables = {
29 | LUA_LIBDIR = "$(LIBDIR)",
30 | LUA_DIR = "$(LUADIR)"
31 | }
32 | },
33 | win32 = {
34 | type = "make",
35 | build_variables = {
36 | LUA_LIB = "$(LUA_LIBDIR)\\lua5.1.lib",
37 | CFLAGS = "$(CFLAGS) /I$(LUA_INCDIR)",
38 | },
39 | install_variables = {
40 | LUA_LIBDIR = "$(LIBDIR)",
41 | LUA_DIR = "$(LUADIR)",
42 | BIN_DIR = "$(BINDIR)"
43 | }
44 | }
45 | }
46 | }
47 |
--------------------------------------------------------------------------------
/rockspecs/rings-cvs-3.rockspec:
--------------------------------------------------------------------------------
1 | package = "Rings"
2 | version = "cvs-3"
3 | source = {
4 | url = "cvs://:pserver:anonymous:@cvs.luaforge.net:/cvsroot/rings",
5 | cvs_tag = "HEAD",
6 | }
7 | description = {
8 | summary = "Create new Lua states from within Lua",
9 | detailed = [[
10 | Rings is a library which provides a way to create new Lua states
11 | from within Lua. It also offers a simple way to communicate
12 | between the creator (master) and the created (slave) states.
13 | ]],
14 | license = "MIT/X11",
15 | homepage = "http://www.keplerproject.org/rings/"
16 | }
17 | dependencies = {
18 | "lua >= 5.1"
19 | }
20 | build = {
21 | platforms = {
22 | unix = {
23 | type = "make",
24 | build_variables = {
25 | LIB_OPTION = "$(LIBFLAG)",
26 | CFLAGS = "$(CFLAGS) -I$(LUA_INCDIR)",
27 | },
28 | install_variables = {
29 | LUA_LIBDIR = "$(LIBDIR)",
30 | LUA_DIR = "$(LUADIR)"
31 | }
32 | },
33 | win32 = {
34 | type = "make",
35 | build_variables = {
36 | LUA_LIB = "$(LUA_LIBDIR)\\lua5.1.lib",
37 | CFLAGS = "/MD $(CFLAGS) /I$(LUA_INCDIR)",
38 | },
39 | install_variables = {
40 | LUA_LIBDIR = "$(LIBDIR)",
41 | LUA_DIR = "$(LUADIR)",
42 | BIN_DIR = "$(BINDIR)"
43 | }
44 | }
45 | }
46 | }
47 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # Rings - Multiple Lua States
2 |
3 | http://keplerproject.github.io/rings/
4 |
5 | ## Overview
6 |
7 | Rings is a library which provides a way to create new Lua states from within Lua.
8 | It also offers a simple way to communicate between the creator (master) and the created (slave) states.
9 |
10 | Rings is free software and uses the same license as Lua 5.x (MIT).
11 |
12 | ## Download
13 |
14 | Rings can be downloaded in source code from its Github page:
15 |
16 | http://github.com/keplerproject/rings
17 |
18 | ## Installation
19 |
20 | If you are using LuaRocks just type
21 |
22 | ```
23 | luarocks install rings
24 | ```
25 |
26 | If you prefer to install manually, the compiled binary file should be copied to a directory in your C path.
27 | The file stable.lua should be copied to a directory in your Lua path.
28 |
29 | ## History
30 |
31 | Version 1.3.0 [30/Jan/2013]
32 | * Support for Lua 5.2
33 |
34 | Version 1.2.3 [20/Oct/2009]
35 | * Fixing an old reference to "arg" instead of {...} - Reported by MFarm
36 |
37 | Version 1.2.2 [30/Jun/2008]
38 | * Fixed a stack handling issue (bug report and patch by Shmuel Zeigerman)
39 |
40 | ## Credits
41 |
42 | Rings was designed by Roberto Ierusalimschy and Tomas Guisasola as part of the Kepler Project.
43 | The implementation was coded by Tomas Guisasola.
44 |
45 | Rings development was sponsored by Fabrica Digital.
46 |
--------------------------------------------------------------------------------
/doc/doc.css:
--------------------------------------------------------------------------------
1 | body {
2 | color: #47555c;
3 | font-size: 16px;
4 | font-family: "Open Sans", sans-serif;
5 | margin: 0;
6 | padding: 0;
7 | background: #eff4ff;
8 | }
9 |
10 | a:link { color: #008fee; }
11 | a:visited { color: #008fee; }
12 | a:hover { color: #22a7ff; }
13 |
14 | h1 { font-size:26px; }
15 | h2 { font-size:24px; }
16 | h3 { font-size:18px; }
17 | h4 { font-size:16px; }
18 |
19 | hr {
20 | height: 1px;
21 | background: #c1cce4;
22 | border: 0px;
23 | margin: 20px 0;
24 | }
25 |
26 | code {
27 | font-family: "Open Sans Mono", "Andale Mono", monospace;
28 | }
29 |
30 | tt {
31 | font-family: "Open Sans Mono", "Andale Mono", monospace;
32 | }
33 |
34 | body, td, th {
35 | }
36 |
37 | textarea, pre, tt {
38 | font-family: "Open Sans Mono", "Andale Mono", monospace;
39 | }
40 |
41 | img {
42 | border-width: 0px;
43 | }
44 |
45 | .example {
46 | background-color: #323744;
47 | color: white;
48 | font-size: 16px;
49 | padding: 16px 24px;
50 | border-radius: 2px;
51 | overflow-x: auto;
52 | }
53 |
54 | div.header, div.footer {
55 | }
56 |
57 | #container {
58 | }
59 |
60 | #product {
61 | background-color: white;
62 | padding: 10px;
63 | height: 130px;
64 | border-bottom: solid #d3dbec 1px;
65 | }
66 |
67 | #product big {
68 | font-size: 42px;
69 | }
70 | #product strong {
71 | font-weight: normal;
72 | }
73 |
74 | #product_logo {
75 | float: right;
76 | }
77 |
78 | #product_name {
79 | padding-top: 15px;
80 | padding-left: 30px;
81 | font-size: 42px;
82 | font-weight: normal;
83 | }
84 |
85 | #product_description {
86 | padding-left: 30px;
87 | color: #757779;
88 | }
89 |
90 | #main {
91 | background: #eff4ff;
92 | margin: 0;
93 | }
94 |
95 | #navigation {
96 | width: 100%;
97 | background-color: rgb(44,62,103);
98 | padding: 10px;
99 | margin: 0;
100 | }
101 |
102 | #navigation h1 {
103 | display: none;
104 | }
105 |
106 | #navigation a:hover {
107 | text-decoration: underline;
108 | }
109 |
110 | #navigation ul li a {
111 | color: rgb(136, 208, 255);
112 | font-weight: bold;
113 | text-decoration: none;
114 | }
115 |
116 | #navigation ul li li a {
117 | color: rgb(136, 208, 255);
118 | font-weight: normal;
119 | text-decoration: none;
120 | }
121 |
122 | #navigation ul {
123 | display: inline;
124 | color: white;
125 | padding: 0px;
126 | padding-top: 10px;
127 | padding-bottom: 10px;
128 | }
129 |
130 | #navigation li {
131 | display: inline;
132 | list-style-type: none;
133 | padding-left: 5px;
134 | padding-right: 5px;
135 | }
136 |
137 | #navigation li {
138 | padding: 10px;
139 | padding: 10px;
140 | }
141 |
142 | #navigation li li {
143 | }
144 |
145 | #navigation li:hover a {
146 | color: rgb(166, 238, 255);
147 | }
148 |
149 | #content {
150 | padding: 20px;
151 | width: 800px;
152 | margin-left: auto;
153 | margin-right: auto;
154 | }
155 |
156 | #about {
157 | display: none;
158 | }
159 |
160 | dl.reference {
161 | background-color: white;
162 | padding-left: 20px;
163 | padding-right: 20px;
164 | padding-bottom: 20px;
165 | border: solid #d3dbec 1px;
166 | }
167 |
168 | dl.reference dt {
169 | padding: 5px;
170 | padding-top: 25px;
171 | color: #637bbc;
172 | }
173 |
174 | dl.reference dl dt {
175 | padding-top: 5px;
176 | color: #637383;
177 | }
178 |
179 | dl.reference dd {
180 | }
181 |
182 | @media print {
183 | body {
184 | font: 10pt "Times New Roman", "TimeNR", Times, serif;
185 | }
186 | a {
187 | font-weight:bold; color: #004080; text-decoration: underline;
188 | }
189 | #main {
190 | background-color: #ffffff; border-left: 0px;
191 | }
192 | #container {
193 | margin-left: 2%; margin-right: 2%; background-color: #ffffff;
194 | }
195 | #content {
196 | margin-left: 0px; padding: 1em; border-left: 0px; border-right: 0px; background-color: #ffffff;
197 | }
198 | #navigation {
199 | display: none;
200 | }
201 | #product_logo {
202 | display: none;
203 | }
204 | #about img {
205 | display: none;
206 | }
207 | .example {
208 | font-family: "Andale Mono", monospace;
209 | font-size: 8pt;
210 | page-break-inside: avoid;
211 | }
212 | }
213 |
--------------------------------------------------------------------------------
/doc/license.html:
--------------------------------------------------------------------------------
1 |
3 |
4 |
5 | Rings License
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
17 |
Rings
18 |
Multiple Lua States
19 |
20 |
21 |
22 |
57 |
58 |
59 |
60 |
License
61 |
62 |
Rings is free software: it can be used for both academic and commercial
63 | purposes at absolutely no cost. There are no royalties or GNU-like "copyleft"
64 | restrictions. Rings qualifies as
65 | Open Source
66 | software.
67 | Its licenses are compatible with
68 | GPL .
69 | Rings is not in the public domain and the
70 | Kepler Project
71 | keeps its copyright. The legal details are below.
72 |
73 |
The spirit of the license is that
74 | you are free to use Rings for any purpose at no cost without having to ask us.
75 | The only requirement is that if you do use Rings,
76 | then you should give us credit by including the appropriate copyright notice
77 | somewhere in your product or its documentation.
78 |
79 |
The Rings library is designed and implemented by Roberto Ierusalimschy
80 | and Tomás Guisasola.
81 | The implementation is not derived from licensed software.
82 |
83 |
84 |
Copyright © 2006-2017 Kepler Project.
85 |
86 |
Permission is hereby granted, free of charge, to any person obtaining a copy
87 | of this software and associated documentation files (the "Software"), to deal
88 | in the Software without restriction, including without limitation the rights
89 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
90 | copies of the Software, and to permit persons to whom the Software is
91 | furnished to do so, subject to the following conditions:
92 |
93 |
The above copyright notice and this permission notice shall be included in
94 | all copies or substantial portions of the Software.
95 |
96 |
97 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
98 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
99 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
100 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
101 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
102 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
103 | THE SOFTWARE.
104 |
105 |
106 |
107 |
108 |
111 |
112 |
113 |
114 |
115 |
--------------------------------------------------------------------------------
/vc6/rings_dll.dsp:
--------------------------------------------------------------------------------
1 | # Microsoft Developer Studio Project File - Name="rings_dll" - Package Owner=<4>
2 | # Microsoft Developer Studio Generated Build File, Format Version 6.00
3 | # ** DO NOT EDIT **
4 |
5 | # TARGTYPE "Win32 (x86) Dynamic-Link Library" 0x0102
6 |
7 | CFG=rings_dll - Win32 Debug
8 | !MESSAGE This is not a valid makefile. To build this project using NMAKE,
9 | !MESSAGE use the Export Makefile command and run
10 | !MESSAGE
11 | !MESSAGE NMAKE /f "rings_dll.mak".
12 | !MESSAGE
13 | !MESSAGE You can specify a configuration when running NMAKE
14 | !MESSAGE by defining the macro CFG on the command line. For example:
15 | !MESSAGE
16 | !MESSAGE NMAKE /f "rings_dll.mak" CFG="rings_dll - Win32 Debug"
17 | !MESSAGE
18 | !MESSAGE Possible choices for configuration are:
19 | !MESSAGE
20 | !MESSAGE "rings_dll - Win32 Release" (based on "Win32 (x86) Dynamic-Link Library")
21 | !MESSAGE "rings_dll - Win32 Debug" (based on "Win32 (x86) Dynamic-Link Library")
22 | !MESSAGE
23 |
24 | # Begin Project
25 | # PROP AllowPerConfigDependencies 0
26 | # PROP Scc_ProjName "rings_dll"
27 | # PROP Scc_LocalPath ".."
28 | CPP=cl.exe
29 | MTL=midl.exe
30 | RSC=rc.exe
31 |
32 | !IF "$(CFG)" == "rings_dll - Win32 Release"
33 |
34 | # PROP BASE Use_MFC 0
35 | # PROP BASE Use_Debug_Libraries 0
36 | # PROP BASE Output_Dir "Release"
37 | # PROP BASE Intermediate_Dir "Release"
38 | # PROP BASE Target_Dir ""
39 | # PROP Use_MFC 0
40 | # PROP Use_Debug_Libraries 0
41 | # PROP Output_Dir "../lib/vc6"
42 | # PROP Intermediate_Dir "rings_dll/Release"
43 | # PROP Ignore_Export_Lib 0
44 | # PROP Target_Dir ""
45 | # ADD BASE CPP /nologo /MT /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "RINGS_EXPORTS" /YX /FD /c
46 | # ADD CPP /nologo /MD /W3 /GX /O2 /I "../../external-src/lua50/include" /I "../../compat/src" /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "RINGS_EXPORTS" /YX /FD /c
47 | # ADD BASE MTL /nologo /D "NDEBUG" /mktyplib203 /win32
48 | # ADD MTL /nologo /D "NDEBUG" /mktyplib203 /win32
49 | # ADD BASE RSC /l 0x416 /d "NDEBUG"
50 | # ADD RSC /l 0x416 /d "NDEBUG"
51 | BSC32=bscmake.exe
52 | # ADD BASE BSC32 /nologo
53 | # ADD BSC32 /nologo
54 | LINK32=link.exe
55 | # ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /dll /machine:I386
56 | # ADD LINK32 lua50.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /dll /machine:I386 /out:"../bin/vc6/rings.dll" /libpath:"../../external-src/lua50/lib/dll"
57 | # Begin Special Build Tool
58 | SOURCE="$(InputPath)"
59 | PostBuild_Cmds=cd ../bin/vc6 zip.exe rings-1.0-win32.zip rings.dll
60 | # End Special Build Tool
61 |
62 | !ELSEIF "$(CFG)" == "rings_dll - Win32 Debug"
63 |
64 | # PROP BASE Use_MFC 0
65 | # PROP BASE Use_Debug_Libraries 1
66 | # PROP BASE Output_Dir "Debug"
67 | # PROP BASE Intermediate_Dir "Debug"
68 | # PROP BASE Target_Dir ""
69 | # PROP Use_MFC 0
70 | # PROP Use_Debug_Libraries 1
71 | # PROP Output_Dir "../lib/vc6"
72 | # PROP Intermediate_Dir "rings_dll/Debug"
73 | # PROP Ignore_Export_Lib 0
74 | # PROP Target_Dir ""
75 | # ADD BASE CPP /nologo /MTd /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "RINGS_EXPORTS" /YX /FD /GZ /c
76 | # ADD CPP /nologo /MDd /W3 /Gm /GX /ZI /Od /I "../../external-src/lua50/include" /I "../../compat/src" /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "RINGS_EXPORTS" /YX /FD /GZ /c
77 | # ADD BASE MTL /nologo /D "_DEBUG" /mktyplib203 /win32
78 | # ADD MTL /nologo /D "_DEBUG" /mktyplib203 /win32
79 | # ADD BASE RSC /l 0x416 /d "_DEBUG"
80 | # ADD RSC /l 0x416 /d "_DEBUG"
81 | BSC32=bscmake.exe
82 | # ADD BASE BSC32 /nologo
83 | # ADD BSC32 /nologo
84 | LINK32=link.exe
85 | # ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /dll /debug /machine:I386 /pdbtype:sept
86 | # ADD LINK32 lua50.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /dll /debug /machine:I386 /out:"../bin/vc6/ringsd.dll" /pdbtype:sept /libpath:"../../external-src/lua50/lib/dll"
87 |
88 | !ENDIF
89 |
90 | # Begin Target
91 |
92 | # Name "rings_dll - Win32 Release"
93 | # Name "rings_dll - Win32 Debug"
94 | # Begin Group "Source Files"
95 |
96 | # PROP Default_Filter "cpp;c;cxx;rc;def;r;odl;idl;hpj;bat"
97 | # Begin Source File
98 |
99 | SOURCE="..\..\compat\src\compat-5.1.c"
100 | # End Source File
101 | # Begin Source File
102 |
103 | SOURCE=..\src\rings.c
104 | # End Source File
105 | # Begin Source File
106 |
107 | SOURCE=.\rings.def
108 | # End Source File
109 | # End Group
110 | # Begin Group "Header Files"
111 |
112 | # PROP Default_Filter "h;hpp;hxx;hm;inl"
113 | # Begin Source File
114 |
115 | SOURCE="..\..\compat\src\compat-5.1.h"
116 | # End Source File
117 | # End Group
118 | # Begin Group "Resource Files"
119 |
120 | # PROP Default_Filter "ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe"
121 | # End Group
122 | # End Target
123 | # End Project
124 |
--------------------------------------------------------------------------------
/doc/index.html:
--------------------------------------------------------------------------------
1 |
3 |
4 |
5 | Rings: Multiple Lua States
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
18 |
Rings
19 |
Multiple Lua States
20 |
21 |
22 |
23 |
24 |
59 |
60 |
61 |
62 |
Overview
63 |
64 |
Rings is a library which provides a way to create new Lua states from within
65 | Lua. It also offers a simple way to communicate between the creator (master) and
66 | the created (slave) states.
67 |
68 |
Rings is free software and uses the same license
69 | as Lua 5.x (MIT).
70 |
71 |
Status
72 |
73 |
74 | Rings version 1.3.0 is now available for download .
75 |
76 |
Download
77 |
78 |
Rings can be installed using LuaRocks by simply typing:
79 |
80 |
luarocks install rings
81 |
82 |
Rings can also be downloaded in source code from its
83 | Github
84 | page.
85 |
86 |
History
87 |
88 |
89 |
90 | Version 1.3.0 [30/Jan/2013]
91 |
92 | Support for Lua 5.2
93 |
94 |
95 | Version 1.2.3 [20/Oct/2009]
96 |
97 | Fixing an old reference to "arg" instead of {...} - Reported by MFarm
98 |
99 |
100 |
101 | Version 1.2.2 [30/Jun/2008]
102 |
103 | Fixed a stack handling issue (bug report and patch by Shmuel Zeigerman)
104 |
105 |
106 | Version 1.2.1 [8/May/2008]
107 |
108 | Fixed bug #2074 (old bugtracker) -
109 | Rings uses the deprecated function luaL_openlib (patch by Ignacio Burgueño)
110 |
111 |
112 | Version 1.2 [18/Feb/2008]
113 |
114 |
115 | rings.new now takes
116 | an optional environment to be used by
117 | remotedostring .
118 | If the environment is nil, it defaults to _M or _G.
119 | Fixed a bug with interaction of rings and coroutines, rings was assuming a 1:1 mapping
120 | between lua_States and rings master and slave states, which is not true when coroutines/threads are involved.
121 | (bug found by Ignacio Burgueño)
122 |
123 |
124 |
125 | Version 1.1 [11/Jun/2007]
126 | Adapted to work with Lua 5.1.
127 |
128 | Version 1.0 [10/Mar/2006]
129 | First public version, works with Lua 5.0.
130 |
131 |
132 |
Credits
133 |
134 |
Rings was designed by Roberto Ierusalimschy and Tomás Guisasola
135 | as part of the Kepler Project .
136 | The implementation was coded by Tomás Guisasola.
137 |
138 |
Rings development was sponsored by
139 | Fábrica Digital .
140 |
141 |
142 |
143 |
144 |
145 |
148 |
149 |
150 |
151 |
152 |
153 |
--------------------------------------------------------------------------------
/tests/test.lua:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env lua
2 |
3 | ---------------------------------------------------------------------
4 | -- checks for a value and throw an error if it is invalid.
5 | ---------------------------------------------------------------------
6 | local function assert2 (expected, value, msg)
7 | if not msg then
8 | msg = ''
9 | else
10 | msg = msg..'\n'
11 | end
12 | return assert (value == expected,
13 | msg.."wrong value (["..tostring(value).."] instead of "..
14 | tostring(expected)..")")
15 | end
16 |
17 | ---------------------------------------------------------------------
18 | -- State object test.
19 | ---------------------------------------------------------------------
20 | local statemethods = { "close", "dostring", }
21 | local function test_state (obj)
22 | -- checking object type.
23 | assert2 (true, type(obj) == "userdata" or type(obj) == "table", "incorrect object type")
24 | -- trying to get metatable.
25 | assert2 ("You're not allowed to get the metatable of a Lua State",
26 | getmetatable(obj), "error permitting access to object's metatable")
27 | -- trying to set metatable.
28 | assert2 (false, pcall (setmetatable, obj, {}))
29 | -- checking existence of object's methods.
30 | for i = 1, #statemethods do
31 | local method = obj[statemethods[i]]
32 | assert2 ("function", type(method))
33 | assert2 (false, pcall (method), "no 'self' parameter accepted")
34 | end
35 | return obj
36 | end
37 |
38 | ---------------------------------------------------------------------
39 | ---------------------------------------------------------------------
40 | local rings = require"rings"
41 | local unpack = table.unpack or unpack
42 |
43 | print(rings._VERSION)
44 |
45 | local S = test_state (rings.new())
46 | S:dostring([[pcall(require, "luarocks.require")]])
47 |
48 | -- How to handle errors on another Lua State?
49 |
50 | local ok, err = S:dostring"bla()"
51 | assert2 (false, ok, "Unexpected success")
52 | assert2 ("stack traceback", err:match"stack traceback", "Unexpected error without traceback: "..tostring(err))
53 | assert2 (false, S:dostring"bla(")
54 | assert2 (true, S:dostring"print'Hello World!'")
55 | -- Checking returning value
56 | io.write(".")
57 | local ok, _x = S:dostring"return x"
58 | assert2 (true, ok, "Error while returning a value ("..tostring(_x)..")")
59 | assert2 (nil, _x, "Unexpected initialized variable (x = "..tostring(_x)..")")
60 | -- setting a value
61 | io.write(".")
62 | assert2 (nil, x, "I need an uninitialized variable to do the test!")
63 | S:dostring"x = 1"
64 | assert2 (nil, x, "Changing original Lua State instead of the new one!")
65 | -- obtaining a value from the new state
66 | io.write(".")
67 | local ok, _x = S:dostring"return x"
68 | assert2 (true, ok, "Error while returning a value ("..tostring(_x)..")")
69 | assert2 (1, _x, "Unexpected initialized variable (x = "..tostring(_x)..")")
70 |
71 | -- executing code in the master state from the new state
72 | io.write(".")
73 | global = 2
74 | local ok, _x = S:dostring[[
75 | local ok, _x = remotedostring"return global"
76 | if not ok then
77 | error(_x)
78 | else
79 | return _x
80 | end
81 | ]]
82 | assert2 (true, ok, "Unexpected error: "..tostring(_x).." (status == "..tostring(ok)..")")
83 | assert2 (global, _x, "Unexpected error: "..tostring(_x).." (status == "..tostring(ok)..")")
84 |
85 | -- new state obtaining data from the master state by using remotedostring
86 | io.write(".")
87 | f1 = function () return "function 1" end
88 | f2 = function () return "function 2" end
89 | f3 = function () return "function 3" end
90 | data = {
91 | key1 = { f1, f2, f3, },
92 | key2 = { f3, f1, f2, },
93 | }
94 | local ok, k, i, f = S:dostring ([[
95 | require"math"
96 | require"os"
97 | math.randomseed(os.time())
98 | local key = "key"..tostring(math.random(2))
99 | local i = math.random(3)
100 | local ok, f = remotedostring("return data."..key.."["..tostring(i).."]()")
101 | return key, i, f
102 | ]], package.path)
103 | assert2 (true, ok, "Unexpected error: "..k)
104 | assert2 ("string", type(k), string.format ("Wrong #1 return value (expected string, got "..type(k)..")"))
105 | assert2 ("number", type(i), string.format ("Wrong #2 return value (expected number, got "..type(i)..")"))
106 | assert2 ("string", type(f), string.format ("Wrong #3 return value (expected string, got "..type(f)..")"))
107 | assert2 (f, data[k][i](), "Wrong #3 return value")
108 |
109 | -- Passing arguments and returning values
110 | io.write(".")
111 | local data = { 12, 13, 14, 15, }
112 | local cmd = string.format ([[
113 | local unpack = table.unpack or unpack
114 | local arg = { ... }
115 | assert (type(arg) == "table")
116 | assert (arg[1] == %d)
117 | assert (arg[2] == %d)
118 | assert (arg[3] == %d)
119 | assert (arg[4] == %d)
120 | assert (arg[5] == nil)
121 | return unpack (arg)]], unpack (data))
122 | local _data = { S:dostring(cmd, data[1], data[2], data[3], data[4]) }
123 | assert2 (true, table.remove (_data, 1), "Unexpected error: "..tostring(_data[2]))
124 | for i, v in ipairs (data) do
125 | assert2 (v, _data[i])
126 | end
127 |
128 | -- Transferring userdata
129 | io.write(".")
130 | local ok, f1, f2, f3 = S:dostring([[ return ..., io.stdout ]], io.stdout)
131 | assert ((not f1) and (not f2), "Same file objects (io.stdout) in different states (user data objects were supposed not to be copyable")
132 |
133 | -- Checking cache
134 | io.write(".")
135 | local chunk = [[return tostring(debug.getinfo(1,'f').func)]]
136 | local ok, f1 = S:dostring(chunk)
137 | local ok, f2 = S:dostring(chunk)
138 | local ok, f3 = S:dostring([[return tostring (debug.getinfo(1,'f').func)]])
139 | assert (f1 == f2, "Cache is not working")
140 | assert (f1 ~= f3, "Function `dostring' is producing the same function for different strings")
141 | assert (S:dostring"collectgarbage(); collectgarbage()")
142 | local ok, f4 = S:dostring(chunk)
143 | assert (f4 ~= f1, "Cache is not being collected")
144 | local ok, f5 = S:dostring(chunk)
145 | assert (f4 == f5, "Cache is not working")
146 |
147 | -- Checking Stable
148 | io.write(".")
149 | assert (S:dostring[[stable = require"stable"]])
150 | assert (type(_state_persistent_table_) == "table", "Stable could not create persistent table")
151 | assert (S:dostring[[stable.set("key", "value")]])
152 | assert (_state_persistent_table_.key == "value", "Stable could not store a value")
153 | assert (S:dostring[[assert(stable.get"key" == "value")]])
154 |
155 | -- Closing new state
156 | io.write(".")
157 | S:close ()
158 | assert2 (false, pcall (S.dostring, S, "print[[This won't work!]]"))
159 | collectgarbage()
160 | collectgarbage()
161 |
162 | -- Checking Stable's persistent table
163 | io.write(".")
164 | local NS = test_state (rings.new())
165 | assert (NS:dostring ([[
166 | pcall(require, "luarocks.require")
167 | package.path = ...
168 | ]], package.path))
169 | assert (NS:dostring[[stable = require"stable"]])
170 | assert (type(_state_persistent_table_) == "table", "Stable persistent table was removed")
171 | assert (_state_persistent_table_.key == "value", "Stable key vanished")
172 | assert (NS:dostring[[assert(stable.get"key" == "value")]])
173 |
174 | -- Checking remotedostring environment
175 | io.write(".")
176 | S = rings.new({ a = 2, b = 3, assert = assert })
177 | S:dostring([[pcall(require, "luarocks.require")]])
178 |
179 | assert (S:dostring[[remotedostring[=[assert(a == 2)]=] ]])
180 | assert (S:dostring[[remotedostring[=[assert(b == 3)]=] ]])
181 | assert (S:dostring[[remotedostring[=[assert(print == nil)]=] ]])
182 |
183 | -- Checking inherited environment
184 | io.write(".")
185 | local env = { msg = "Hi!"}
186 | local r = rings.new(env)
187 | r:dostring([[pcall(require, "luarocks.require")]])
188 | r:dostring([==[remotedostring([[assert(msg == "Hi!", "Environment failure")]])]==])
189 |
190 | -- Test dostring with bytecode
191 | io.write(".")
192 | local function bytecode(code)
193 | local chunk = assert((loadstring or load)(code))
194 | return string.dump(chunk)
195 | end
196 |
197 | local rr = rings.new()
198 | local _, v1 = assert(rr:dostring(bytecode[[return 1]]))
199 | assert(v1 == 1)
200 | local _, v2 = assert(rr:dostring(bytecode[[return 'abc']]))
201 | assert(v2 == "abc")
202 |
203 | print"Ok!"
204 |
--------------------------------------------------------------------------------
/doc/manual.html:
--------------------------------------------------------------------------------
1 |
3 |
4 |
5 | Rings Manual
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
17 |
Rings
18 |
Multiple Lua States
19 |
20 |
21 |
22 |
23 |
58 |
59 |
60 |
61 |
Introduction
62 |
63 |
Rings is a library which provides a way to create new Lua states from within
64 | Lua. It also offers a simple way to communicate between the creator (master) and
65 | the created (slave) states.
66 |
67 |
Rings is free software and uses the same license
68 | as Lua 5.x (MIT).
69 |
70 |
Rings also offers Stable ,
71 | a very simple API to manage a shared table at the master state.
72 |
73 |
74 |
Building
75 |
76 |
77 | Rings works with Lua 5.1, 5.2, 5.3, and LuaJIT. In order to build it the language library and header files
78 | for the desired Lua version must be installed properly.
79 |
80 |
81 |
82 | If you wish to install by hand, the distribution provides a
83 | Makefile prepared to compile the library and install it.
84 | The file config should be edited to suit the particularities of the target platform
85 | before running make.
86 | This file has some definitions like paths to the external libraries,
87 | compiler options and the like.
88 | One important definition is the Lua version,
89 | which is not obtained from the installed software.
90 |
91 |
92 |
Installation
93 |
94 |
95 | If you are using LuaRocks, just type
96 |
97 |
98 |
99 | luarocks install rings
100 |
101 |
102 |
103 | If you prefer to install manually, the compiled binary file should be copied to a directory in your
104 | C path .
105 | The file stable.lua should be copied to a directory in your
106 | Lua path .
107 |
108 |
109 |
Reference
110 |
111 |
Master functions
112 |
113 |
Rings offers a single function which creates a new Lua state and returns
114 | an object representing it. The state which creates other states is called
115 | the master and the created ones are called slaves.
116 | The master can execute code in any of its slaves but each slave only has
117 | direct access to its master (or its own slaves).
118 |
119 |
All standard Lua libraries are opened automatically in a new state;
120 | other libraries have to be loaded explicitly.
121 |
122 |
The object representing a slave state has a method (dostring)
123 | which can execute Lua code in the corresponding state.
124 | This method can receive arguments (only numbers, strings, booleans and userdata,
125 | which are converted to lightuserdata) and always returns a boolean indicating
126 | whether the code executed correctly or not, followed by eventual return values
127 | or an error message.
128 |
129 |
130 | rings.new (env)
131 | Returns a newly created Lua state. Takes an optional environment to be used by
132 | remotedostring .
133 | If the environment is nil, it defaults to the master_M or _G tables.
134 |
135 | state :close ()
136 | Closes the state.
137 |
138 | state :dostring (string, ...)
139 | Executes a string in the slave state.
140 | The arguments could be accessed exactly as in a
141 | vararg
142 | function . Valid types of arguments and return values are:
143 | number, string, boolean, nil and userdata (which are converted
144 | to lightuserdata).
145 |
146 | Returns a boolean indicating the status of the operation,
147 | followed by the returned values or an error message in case of error.
148 |
149 |
150 |
151 |
Slave function
152 |
153 |
The following function is registered in the newly created slave state.
154 |
155 |
156 |
157 | remotedostring (string, ...)
158 | Executes a string in the master state.
159 | Behaves exactly as the method dostring
160 | except that it acts in the master state.
161 |
162 |
163 |
164 |
Stable
165 |
166 |
Stable is a simple API which provides a way for a slave state to store
167 | and retrieve data to and from its master state.
168 | This library is not opened automatically in a slave state.
169 |
170 |
171 |
172 | stable.get (key)
173 | Returns the value of a given key .
174 |
175 | stable.set (key, value)
176 | Stores a value associated to a key .
177 | Returns nothing.
178 |
179 |
180 |
181 |
182 |
Examples
183 |
184 |
The following sample shows how to execute code in another state passing
185 | arguments and returning values:
186 |
187 |
188 | local rings = require "rings"
189 |
190 | local code = [[
191 | local args_reversed = {}
192 |
193 | for _, value in ipairs({...}) do
194 | table.insert(args_reversed, 1, value)
195 | end
196 |
197 | return table.unpack(args_reversed)
198 | ]]
199 |
200 | local state = rings.new()
201 | print(state:dostring(code, 1, 2, 3)) -- true, 3, 2, 1
202 | state:close()
203 |
204 |
205 |
The following example uses Stable to store a value in the master state:
206 |
207 |
208 | local rings = require "rings"
209 |
210 | local code = [[
211 | local stable = require "stable"
212 |
213 | local count = stable.get("shared_counter") or 0
214 | stable.set("shared_counter", count + 1)
215 | return count
216 | ]]
217 |
218 | local state = rings.new()
219 | print(state:dostring(code)) -- true, 0
220 | print(state:dostring(code)) -- true, 1
221 | state:close()
222 |
223 | local another_state = rings.new()
224 | print(another_state:dostring(code)) -- true, 2
225 | another_state:close()
226 |
227 |
228 |
229 |
230 |
231 |
232 |
235 |
236 |
237 |
238 |
239 |
240 |
--------------------------------------------------------------------------------
/src/rings.c:
--------------------------------------------------------------------------------
1 | /*
2 | ** Rings: Multiple Lua States
3 | ** $Id: rings.c,v 1.24 2008/06/30 17:52:31 carregal Exp $
4 | ** See Copyright Notice in license.html
5 | */
6 |
7 | #include "string.h"
8 |
9 | #include "lua.h"
10 | #include "lualib.h"
11 | #include "lauxlib.h"
12 |
13 |
14 | #define RINGS_STATE "rings state"
15 | #define RINGS_TABLENAME "rings"
16 | #define RINGS_ENV "rings environment"
17 | #define STATE_NAME "rings Lua state"
18 | #define RINGS_CACHE "rings cache"
19 |
20 | /* default initialization for fresh states */
21 | #define RINGS_INITIALIZE luaL_openlibs
22 |
23 | #if LUA_VERSION_NUM < 502
24 | # define luaL_newlib(L,l) (lua_newtable(L), luaL_register(L,NULL,l))
25 | # define luaL_setfuncs(L,l,n) luaL_register(L,NULL,l)
26 | #else
27 | # define lua_setfenv(L,i) lua_setupvalue(L, i, 1)
28 | #endif
29 |
30 | #if LUA_VERSION_NUM < 503
31 | # define lua_isinteger(L, i) ((void) (L), (void) (i), 0)
32 | #endif
33 |
34 | typedef struct {
35 | lua_State *L;
36 | } state_data;
37 |
38 | int luaopen_rings (lua_State *L);
39 |
40 | /*
41 | ** Get a State object from the first call stack position.
42 | */
43 | static state_data *getstate (lua_State *L) {
44 | state_data *s = (state_data *)luaL_checkudata (L, 1, STATE_NAME);
45 | luaL_argcheck (L, s != NULL, 1, "not a Lua State");
46 | luaL_argcheck (L, s->L, 1, "already closed state");
47 | return s;
48 | }
49 |
50 |
51 | /*
52 | **
53 | */
54 | static int state_tostring (lua_State *L) {
55 | state_data *s = (state_data *)luaL_checkudata (L, 1, STATE_NAME);
56 | lua_pushfstring (L, "Lua State (%p)", s);
57 | return 1;
58 | }
59 |
60 |
61 | /*
62 | ** Copies values from State src to State dst.
63 | */
64 | static void copy_values (lua_State *dst, lua_State *src, int i, int top) {
65 | lua_checkstack(dst, top - i + 1);
66 | for (; i <= top; i++) {
67 | switch (lua_type (src, i)) {
68 | case LUA_TNUMBER:
69 | if (lua_isinteger(src, i)) {
70 | lua_pushinteger(dst, lua_tointeger(src, i));
71 | } else {
72 | lua_pushnumber(dst, lua_tonumber(src, i));
73 | }
74 | break;
75 | case LUA_TBOOLEAN:
76 | lua_pushboolean (dst, lua_toboolean (src, i));
77 | break;
78 | case LUA_TSTRING: {
79 | size_t length;
80 | const char *string = lua_tolstring (src, i, &length);
81 | lua_pushlstring (dst, string, length);
82 | break;
83 | }
84 | case LUA_TLIGHTUSERDATA: {
85 | lua_pushlightuserdata (dst, lua_touserdata (src, i));
86 | break;
87 | }
88 | case LUA_TFUNCTION: {
89 | lua_CFunction f = lua_tocfunction(src, i);
90 | if(f)
91 | lua_pushcfunction(dst, f);
92 | else
93 | lua_pushnil(dst);
94 | }
95 | case LUA_TNIL:
96 | default:
97 | lua_pushnil (dst);
98 | break;
99 | }
100 | }
101 | }
102 |
103 |
104 | /*
105 | ** Obtains a function which is the compiled string in the given state.
106 | ** It also caches the resulting function to optimize future uses.
107 | ** Leaves the compiled function on top of the stack or the error message
108 | ** produced by luaL_loadbuffer.
109 | */
110 | static int compile_string (lua_State *L, void *cache, const char *str, size_t str_len) {
111 | if(cache == NULL) {
112 | lua_pushliteral(L, RINGS_CACHE);
113 | } else {
114 | lua_pushlightuserdata(L, cache);
115 | }
116 | lua_gettable (L, LUA_REGISTRYINDEX); /* push cache table */
117 | lua_getfield (L, -1, str); /* cache[str] */
118 | if (!lua_isfunction (L, -1)) {
119 | int status;
120 | lua_pop (L, 1); /* remove cache[str] (= nil) from top of the stack */
121 | status = luaL_loadbuffer (L, str, str_len, str); /* Compile */
122 | if (status != 0) { /* error? */
123 | lua_remove (L, -2); /* removes cache table; leaves the error message */
124 | return status;
125 | }
126 | /* Sets environment */
127 | lua_getfield(L, LUA_REGISTRYINDEX, RINGS_ENV);
128 | if(cache == NULL) {
129 | lua_pushliteral(L, RINGS_CACHE);
130 | } else {
131 | lua_pushlightuserdata(L, cache);
132 | }
133 | lua_gettable(L, -2);
134 | if(!lua_isnil(L, -1)) {
135 | lua_setfenv(L, -3);
136 | lua_pop(L, 1);
137 | } else lua_pop(L, 2);
138 | /* Stores the produced function at cache[str] */
139 | lua_pushlstring (L, str, str_len);
140 | lua_pushvalue (L, -2);
141 | lua_settable (L, -4); /* cache[str] = func */ }
142 | lua_remove (L, -2); /* removes cache table; leaves the function */
143 | return 0;
144 | }
145 |
146 |
147 | /*
148 | ** Executes a string of code from State src into State dst.
149 | ** idx is the index of the string of code.
150 | */
151 | static int dostring (lua_State *dst, lua_State *src, void *cache, int idx) {
152 | int base;
153 | size_t str_len;
154 | const char *str = luaL_checklstring (src, idx, &str_len);
155 | lua_getfield(dst, LUA_REGISTRYINDEX, "rings_traceback");
156 | base = lua_gettop (dst);
157 | idx++; /* ignore first argument (string of code) */
158 | if (compile_string (dst, cache, str, str_len) == 0) { /* Compile OK? => push function */
159 | int arg_top = lua_gettop (src);
160 | copy_values (dst, src, idx, arg_top); /* Push arguments to dst stack */
161 | if (lua_pcall (dst, arg_top-idx+1, LUA_MULTRET, base) == 0) { /* run OK? */
162 | int ret_top = lua_gettop (dst);
163 | lua_pushboolean (src, 1); /* Push status = OK */
164 | copy_values (src, dst, base+1, ret_top); /* Return values to src */
165 | lua_pop (dst, ret_top - base+1);
166 | return 1+(ret_top-base); /* Return true (success) plus return values */
167 | }
168 | }
169 | lua_pushboolean (src, 0); /* Push status = ERR */
170 | lua_pushstring (src, lua_tostring (dst, -1));
171 | lua_pop (dst, 2); /* pops debug.traceback and result from dst state */
172 | return 2;
173 | }
174 |
175 |
176 | /*
177 | ** Executes a string of Lua code in the master state.
178 | */
179 | static int master_dostring (lua_State *S) {
180 | lua_State *M;
181 | void *C;
182 | lua_getfield(S, LUA_REGISTRYINDEX, RINGS_STATE);
183 | M = (lua_State *)lua_touserdata (S, -1);
184 | lua_pop(S, 1);
185 | C = lua_touserdata (S, lua_upvalueindex (1));
186 | return dostring (M, S, C, 1);
187 | }
188 |
189 |
190 | /*
191 | ** Executes a string of Lua code in a given slave state.
192 | */
193 | static int slave_dostring (lua_State *M) {
194 | state_data *s = getstate (M); /* S == s->L */
195 | lua_pushlightuserdata(s->L, M);
196 | lua_setfield(s->L, LUA_REGISTRYINDEX, RINGS_STATE);
197 | return dostring (s->L, M, NULL, 2);
198 | }
199 |
200 |
201 | /*
202 | ** Creates a weak table in the registry.
203 | */
204 | static void create_cache (lua_State *L) {
205 | lua_newtable (L);
206 | lua_newtable (L); /* cache metatable */
207 | lua_pushliteral (L, "v");
208 | lua_setfield (L, -2, "__mode"); /* metatable.__mode = "v" */
209 | lua_setmetatable (L, -2);
210 | lua_settable (L, LUA_REGISTRYINDEX);
211 | }
212 |
213 |
214 | /*
215 | ** Creates a new Lua State and returns an userdata that represents it.
216 | */
217 | static int state_new (lua_State *L) {
218 | state_data *s;
219 | if(lua_gettop(L) == 0) {
220 | lua_getglobal(L, "_M");
221 | if(lua_isnil(L, 1)) {
222 | lua_settop(L, 0);
223 | lua_getglobal(L, "_G");
224 | if(lua_isnil(L, 1)) {
225 | lua_settop(L, 0);
226 | lua_newtable(L);
227 | }
228 | }
229 | }
230 | s = (state_data *)lua_newuserdata (L, sizeof (state_data));
231 | if(s == NULL) {
232 | lua_pushliteral(L, "rings: could not create state data");
233 | lua_error(L);
234 | }
235 | s->L = NULL;
236 | luaL_getmetatable (L, STATE_NAME);
237 | lua_setmetatable (L, -2);
238 | s->L = luaL_newstate ();
239 | if(s->L == NULL) {
240 | lua_pushliteral(L, "rings: could not create new state");
241 | lua_error(L);
242 | }
243 |
244 | /* Initialize environment */
245 |
246 | lua_getfield(L, LUA_REGISTRYINDEX, RINGS_ENV);
247 | lua_pushlightuserdata(L, s->L);
248 | lua_pushvalue(L, 1);
249 | lua_settable(L, -3);
250 | lua_pop(L, 1);
251 |
252 | /* load base libraries */
253 | RINGS_INITIALIZE(s->L);
254 |
255 | /* define dostring function (which runs strings on the master state) */
256 | lua_pushlightuserdata (s->L, s->L);
257 | lua_pushcclosure (s->L, master_dostring, 1);
258 | lua_setglobal (s->L, "remotedostring");
259 |
260 | /* fetches debug.traceback to registry */
261 | lua_getglobal(s->L, "debug");
262 | lua_getfield(s->L, -1, "traceback");
263 | lua_setfield(s->L, LUA_REGISTRYINDEX, "rings_traceback");
264 |
265 | /* Create caches */
266 | lua_pushlightuserdata(L, s->L);
267 | create_cache (L);
268 | lua_pushliteral(s->L, RINGS_CACHE);
269 | create_cache (s->L);
270 | lua_pushliteral(s->L, RINGS_ENV);
271 | create_cache (s->L);
272 |
273 | return 1;
274 | }
275 |
276 |
277 | /*
278 | ** Closes a Lua State.
279 | ** Returns `true' in case of success; `nil' when the state was already closed.
280 | */
281 | static int slave_close (lua_State *L) {
282 | state_data *s = (state_data *)luaL_checkudata (L, 1, STATE_NAME);
283 | luaL_argcheck (L, s != NULL, 1, "not a Lua State");
284 | if (s->L != NULL) {
285 | lua_getfield(L, LUA_REGISTRYINDEX, RINGS_ENV);
286 | lua_pushlightuserdata(L, s->L);
287 | lua_pushnil(L);
288 | lua_settable(L, -3);
289 | lua_close (s->L);
290 | s->L = NULL;
291 | }
292 | return 0;
293 | }
294 |
295 |
296 | /*
297 | ** Creates the metatable for the state on top of the stack.
298 | */
299 | static int state_createmetatable (lua_State *L) {
300 | /* State methods */
301 | struct luaL_Reg methods[] = {
302 | {"close", slave_close},
303 | {"dostring", slave_dostring},
304 | {NULL, NULL},
305 | };
306 | /* State metatable */
307 | if (!luaL_newmetatable (L, STATE_NAME)) {
308 | return 0;
309 | }
310 | /* define methods */
311 | luaL_setfuncs(L, methods, 0);
312 | /* define metamethods */
313 | lua_pushcfunction (L, slave_close);
314 | lua_setfield (L, -2, "__gc");
315 |
316 | lua_pushvalue (L, -1);
317 | lua_setfield (L, -2, "__index");
318 |
319 | lua_pushcfunction (L, state_tostring);
320 | lua_setfield (L, -2, "__tostring");
321 |
322 | lua_pushliteral (L, "You're not allowed to get the metatable of a Lua State");
323 | lua_setfield (L, -2, "__metatable");
324 | return 1;
325 | }
326 |
327 |
328 | /*
329 | **
330 | */
331 | static void set_info (lua_State *L) {
332 | lua_pushliteral (L, "Copyright (C) 2006 Kepler Project");
333 | lua_setfield (L, -2, "_COPYRIGHT");
334 | lua_pushliteral (L, "Rings: Multiple Lua States");
335 | lua_setfield (L, -2, "_DESCRIPTION");
336 | lua_pushliteral (L, "Rings 1.3.0");
337 | lua_setfield (L, -2, "_VERSION");
338 | }
339 |
340 |
341 | /*
342 | ** Opens library.
343 | */
344 | int luaopen_rings (lua_State *L) {
345 | /* Library functions */
346 | struct luaL_Reg rings[] = {
347 | {"new", state_new},
348 | {NULL, NULL},
349 | };
350 | if (!state_createmetatable (L))
351 | return 0;
352 | lua_pop (L, 1);
353 | /* define library functions */
354 | lua_newtable(L);
355 | luaL_newlib(L, rings);
356 | lua_pushvalue(L, -1);
357 | lua_setglobal(L, RINGS_TABLENAME);
358 | lua_newtable (L);
359 | lua_setfield (L, LUA_REGISTRYINDEX, RINGS_ENV);
360 | set_info (L);
361 |
362 | /* fetches debug.traceback to registry */
363 | lua_getglobal(L, "debug");
364 | if(!lua_isnil(L, -1)) {
365 | lua_getfield(L, -1, "traceback");
366 | lua_setfield(L, LUA_REGISTRYINDEX, "rings_traceback");
367 | }
368 | lua_pop(L, 1);
369 |
370 | return 1;
371 | }
372 |
--------------------------------------------------------------------------------