diff options
author | Philipp Janda <siffiejoe@gmx.net> | 2018-07-27 07:35:24 +0200 |
---|---|---|
committer | Philipp Janda <siffiejoe@gmx.net> | 2018-07-27 07:35:24 +0200 |
commit | c325be435c64be57cf2210fa6936af0d425d0ce0 (patch) | |
tree | 0a6398c67346ff8df989994e7e29d4110c515889 | |
parent | 3c76f8f5edf602b023672f8d8f317b0eea2f1195 (diff) | |
download | lua-compat-5.3-c325be435c64be57cf2210fa6936af0d425d0ce0.tar.gz lua-compat-5.3-c325be435c64be57cf2210fa6936af0d425d0ce0.tar.bz2 lua-compat-5.3-c325be435c64be57cf2210fa6936af0d425d0ce0.zip |
Add an implementation of `lua_getextraspace()`.
-rw-r--r-- | README.md | 2 | ||||
-rw-r--r-- | c-api/compat-5.3.c | 57 | ||||
-rw-r--r-- | c-api/compat-5.3.h | 4 | ||||
-rwxr-xr-x | tests/test.lua | 19 | ||||
-rw-r--r-- | tests/testmod.c | 16 |
5 files changed, 92 insertions, 6 deletions
@@ -125,6 +125,7 @@ For Lua 5.1 additionally: | |||
125 | * `lua_KContext` (see [here][14]) | 125 | * `lua_KContext` (see [here][14]) |
126 | * `lua_KFunction` (see [here][14]) | 126 | * `lua_KFunction` (see [here][14]) |
127 | * `lua_dump` (extra `strip` parameter, ignored, see [here][15]) | 127 | * `lua_dump` (extra `strip` parameter, ignored, see [here][15]) |
128 | * `lua_getextraspace` (limited compatibilitiy, may throw out-of-memory errors) | ||
128 | * `lua_getfield` (return value) | 129 | * `lua_getfield` (return value) |
129 | * `lua_geti` and `lua_seti` | 130 | * `lua_geti` and `lua_seti` |
130 | * `lua_getglobal` (return value) | 131 | * `lua_getglobal` (return value) |
@@ -186,7 +187,6 @@ For Lua 5.1 additionally: | |||
186 | [`lua-compat-5.2`][2] for a detailed list. | 187 | [`lua-compat-5.2`][2] for a detailed list. |
187 | * the following C API functions/macros: | 188 | * the following C API functions/macros: |
188 | * `lua_isyieldable` | 189 | * `lua_isyieldable` |
189 | * `lua_getextraspace` | ||
190 | * `lua_arith` (new operators missing) | 190 | * `lua_arith` (new operators missing) |
191 | * `lua_push(v)fstring` (new formats missing) | 191 | * `lua_push(v)fstring` (new formats missing) |
192 | * `lua_upvalueid` (5.1) | 192 | * `lua_upvalueid` (5.1) |
diff --git a/c-api/compat-5.3.c b/c-api/compat-5.3.c index bf81673..590e3c8 100644 --- a/c-api/compat-5.3.c +++ b/c-api/compat-5.3.c | |||
@@ -720,6 +720,63 @@ COMPAT53_API int lua_geti (lua_State *L, int index, lua_Integer i) { | |||
720 | } | 720 | } |
721 | 721 | ||
722 | 722 | ||
723 | #ifndef LUA_EXTRASPACE | ||
724 | #define LUA_EXTRASPACE (sizeof(void*)) | ||
725 | #endif | ||
726 | |||
727 | COMPAT53_API void *lua_getextraspace (lua_State *L) { | ||
728 | int is_main = 0; | ||
729 | void *ptr = NULL; | ||
730 | luaL_checkstack(L, 4, "not enough stack slots available"); | ||
731 | lua_pushliteral(L, "__compat53_extraspace"); | ||
732 | lua_pushvalue(L, -1); | ||
733 | lua_rawget(L, LUA_REGISTRYINDEX); | ||
734 | if (!lua_istable(L, -1)) { | ||
735 | lua_pop(L, 1); | ||
736 | lua_createtable(L, 0, 2); | ||
737 | lua_createtable(L, 0, 1); | ||
738 | lua_pushliteral(L, "k"); | ||
739 | lua_setfield(L, -2, "__mode"); | ||
740 | lua_setmetatable(L, -2); | ||
741 | lua_pushvalue(L, -2); | ||
742 | lua_pushvalue(L, -2); | ||
743 | lua_rawset(L, LUA_REGISTRYINDEX); | ||
744 | } | ||
745 | lua_replace(L, -2); | ||
746 | is_main = lua_pushthread(L); | ||
747 | lua_rawget(L, -2); | ||
748 | ptr = lua_touserdata(L, -1); | ||
749 | if (!ptr) { | ||
750 | lua_pop(L, 1); | ||
751 | ptr = lua_newuserdata(L, LUA_EXTRASPACE); | ||
752 | if (is_main) { | ||
753 | memset(ptr, '\0', LUA_EXTRASPACE); | ||
754 | lua_pushthread(L); | ||
755 | lua_pushvalue(L, -2); | ||
756 | lua_rawset(L, -4); | ||
757 | lua_pushboolean(L, 1); | ||
758 | lua_pushvalue(L, -2); | ||
759 | lua_rawset(L, -4); | ||
760 | } else { | ||
761 | void* mptr = NULL; | ||
762 | lua_pushboolean(L, 1); | ||
763 | lua_rawget(L, -3); | ||
764 | mptr = lua_touserdata(L, -1); | ||
765 | if (mptr) | ||
766 | memcpy(ptr, mptr, LUA_EXTRASPACE); | ||
767 | else | ||
768 | memset(ptr, '\0', LUA_EXTRASPACE); | ||
769 | lua_pop(L, 1); | ||
770 | lua_pushthread(L); | ||
771 | lua_pushvalue(L, -2); | ||
772 | lua_rawset(L, -4); | ||
773 | } | ||
774 | } | ||
775 | lua_pop(L, 2); | ||
776 | return ptr; | ||
777 | } | ||
778 | |||
779 | |||
723 | COMPAT53_API int lua_isinteger (lua_State *L, int index) { | 780 | COMPAT53_API int lua_isinteger (lua_State *L, int index) { |
724 | if (lua_type(L, index) == LUA_TNUMBER) { | 781 | if (lua_type(L, index) == LUA_TNUMBER) { |
725 | lua_Number n = lua_tonumber(L, index); | 782 | lua_Number n = lua_tonumber(L, index); |
diff --git a/c-api/compat-5.3.h b/c-api/compat-5.3.h index 8e10893..082a6a0 100644 --- a/c-api/compat-5.3.h +++ b/c-api/compat-5.3.h | |||
@@ -293,6 +293,9 @@ typedef int (*lua_KFunction)(lua_State *L, int status, lua_KContext ctx); | |||
293 | #define lua_geti COMPAT53_CONCAT(COMPAT53_PREFIX, _geti) | 293 | #define lua_geti COMPAT53_CONCAT(COMPAT53_PREFIX, _geti) |
294 | COMPAT53_API int lua_geti (lua_State *L, int index, lua_Integer i); | 294 | COMPAT53_API int lua_geti (lua_State *L, int index, lua_Integer i); |
295 | 295 | ||
296 | #define lua_getextraspace COMPAT53_CONCAT(COMPAT53_PREFIX, _getextraspace) | ||
297 | COMPAT53_API void *lua_getextraspace (lua_State *L); | ||
298 | |||
296 | #define lua_isinteger COMPAT53_CONCAT(COMPAT53_PREFIX, _isinteger) | 299 | #define lua_isinteger COMPAT53_CONCAT(COMPAT53_PREFIX, _isinteger) |
297 | COMPAT53_API int lua_isinteger (lua_State *L, int index); | 300 | COMPAT53_API int lua_isinteger (lua_State *L, int index); |
298 | 301 | ||
@@ -339,7 +342,6 @@ COMPAT53_API void luaL_requiref (lua_State *L, const char *modname, | |||
339 | 342 | ||
340 | /* XXX not implemented: | 343 | /* XXX not implemented: |
341 | * lua_isyieldable | 344 | * lua_isyieldable |
342 | * lua_getextraspace | ||
343 | * lua_arith (new operators) | 345 | * lua_arith (new operators) |
344 | * lua_pushfstring (new formats) | 346 | * lua_pushfstring (new formats) |
345 | */ | 347 | */ |
diff --git a/tests/test.lua b/tests/test.lua index c2c0abf..9bb08da 100755 --- a/tests/test.lua +++ b/tests/test.lua | |||
@@ -664,14 +664,12 @@ print("isinteger", mod.isinteger(12.3)) | |||
664 | print("isinteger", mod.isinteger(math.huge)) | 664 | print("isinteger", mod.isinteger(math.huge)) |
665 | print("isinteger", mod.isinteger(math.sqrt(-1))) | 665 | print("isinteger", mod.isinteger(math.sqrt(-1))) |
666 | 666 | ||
667 | |||
668 | ___'' | 667 | ___'' |
669 | print("rotate", mod.rotate(1, 1, 2, 3, 4, 5, 6)) | 668 | print("rotate", mod.rotate(1, 1, 2, 3, 4, 5, 6)) |
670 | print("rotate", mod.rotate(-1, 1, 2, 3, 4, 5, 6)) | 669 | print("rotate", mod.rotate(-1, 1, 2, 3, 4, 5, 6)) |
671 | print("rotate", mod.rotate(4, 1, 2, 3, 4, 5, 6)) | 670 | print("rotate", mod.rotate(4, 1, 2, 3, 4, 5, 6)) |
672 | print("rotate", mod.rotate(-4, 1, 2, 3, 4, 5, 6)) | 671 | print("rotate", mod.rotate(-4, 1, 2, 3, 4, 5, 6)) |
673 | 672 | ||
674 | |||
675 | ___'' | 673 | ___'' |
676 | print("strtonum", mod.strtonum("+123")) | 674 | print("strtonum", mod.strtonum("+123")) |
677 | print("strtonum", mod.strtonum(" 123 ")) | 675 | print("strtonum", mod.strtonum(" 123 ")) |
@@ -679,7 +677,6 @@ print("strtonum", mod.strtonum("-1.23")) | |||
679 | print("strtonum", mod.strtonum(" 123 abc")) | 677 | print("strtonum", mod.strtonum(" 123 abc")) |
680 | print("strtonum", mod.strtonum("jkl")) | 678 | print("strtonum", mod.strtonum("jkl")) |
681 | 679 | ||
682 | |||
683 | ___'' | 680 | ___'' |
684 | local a, b, c = mod.requiref() | 681 | local a, b, c = mod.requiref() |
685 | print("requiref", type(a), type(b), type(c), | 682 | print("requiref", type(a), type(b), type(c), |
@@ -687,6 +684,20 @@ print("requiref", type(a), type(b), type(c), | |||
687 | type(requiref1), type(requiref2), type(requiref3)) | 684 | type(requiref1), type(requiref2), type(requiref3)) |
688 | 685 | ||
689 | ___'' | 686 | ___'' |
687 | mod.extraspace("abc") | ||
688 | print("getextraspace", mod.extraspace("xyz")) | ||
689 | local c = coroutine.wrap(function() | ||
690 | print("getextraspace", mod.extraspace("uvw")) | ||
691 | print("getextraspace", mod.extraspace("123")) | ||
692 | coroutine.yield() | ||
693 | print("getextraspace", mod.extraspace("asd")) | ||
694 | end) | ||
695 | c() | ||
696 | print("getextraspace", mod.extraspace("456")) | ||
697 | c() | ||
698 | print("getextraspace", mod.extraspace("789")) | ||
699 | |||
700 | ___'' | ||
690 | local proxy, backend = {}, {} | 701 | local proxy, backend = {}, {} |
691 | setmetatable(proxy, { __index = backend, __newindex = backend }) | 702 | setmetatable(proxy, { __index = backend, __newindex = backend }) |
692 | print("geti/seti", rawget(proxy, 1), rawget(backend, 1)) | 703 | print("geti/seti", rawget(proxy, 1), rawget(backend, 1)) |
@@ -705,7 +716,7 @@ print("tonumber", mod.tonumber("error")) | |||
705 | 716 | ||
706 | ___'' | 717 | ___'' |
707 | print("tointeger", mod.tointeger(12)) | 718 | print("tointeger", mod.tointeger(12)) |
708 | print("tointeger", mod.tointeger(-12)) | 719 | print("tointeger", mod.tointeger(12)) |
709 | print("tointeger", mod.tointeger(12.1)) | 720 | print("tointeger", mod.tointeger(12.1)) |
710 | print("tointeger", mod.tointeger(12.9)) | 721 | print("tointeger", mod.tointeger(12.9)) |
711 | print("tointeger", mod.tointeger(-12.1)) | 722 | print("tointeger", mod.tointeger(-12.1)) |
diff --git a/tests/testmod.c b/tests/testmod.c index cd56e76..345a8c9 100644 --- a/tests/testmod.c +++ b/tests/testmod.c | |||
@@ -63,6 +63,21 @@ static int test_getseti (lua_State *L) { | |||
63 | } | 63 | } |
64 | 64 | ||
65 | 65 | ||
66 | #ifndef LUA_EXTRASPACE | ||
67 | #define LUA_EXTRASPACE (sizeof(void*)) | ||
68 | #endif | ||
69 | |||
70 | static int test_getextraspace (lua_State *L) { | ||
71 | size_t len = 0; | ||
72 | char const* s = luaL_optlstring(L, 1, NULL, &len); | ||
73 | void* p = lua_getextraspace(L); | ||
74 | lua_pushstring(L, p); | ||
75 | if (s) | ||
76 | memcpy(p, s, len > LUA_EXTRASPACE-1 ? LUA_EXTRASPACE-1 : len+1); | ||
77 | return 1; | ||
78 | } | ||
79 | |||
80 | |||
66 | /* additional tests for Lua5.1 */ | 81 | /* additional tests for Lua5.1 */ |
67 | #define NUP 3 | 82 | #define NUP 3 |
68 | 83 | ||
@@ -307,6 +322,7 @@ static const luaL_Reg funcs[] = { | |||
307 | { "strtonum", test_str2num }, | 322 | { "strtonum", test_str2num }, |
308 | { "requiref", test_requiref }, | 323 | { "requiref", test_requiref }, |
309 | { "getseti", test_getseti }, | 324 | { "getseti", test_getseti }, |
325 | { "extraspace", test_getextraspace }, | ||
310 | { "newproxy", test_newproxy }, | 326 | { "newproxy", test_newproxy }, |
311 | { "arith", test_arith }, | 327 | { "arith", test_arith }, |
312 | { "compare", test_compare }, | 328 | { "compare", test_compare }, |