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 }, |
