From 32261b8fb505c5764f7682e9b47825f3d5b5f629 Mon Sep 17 00:00:00 2001 From: Lourival Vieira Neto Date: Fri, 9 May 2025 00:00:51 +0000 Subject: [PATCH 1/2] add support for 64-bit integer on 32-bit platforms --- README.md | 6 +++++ lib/lualinux.c | 36 ++++++++++++----------------- lua | 2 +- lunatik_conf.h | 62 ++++++++++++++++++++++++++++++++++++++++---------- 4 files changed, 71 insertions(+), 35 deletions(-) diff --git a/README.md b/README.md index 2dd1151a2..ce4f82c87 100644 --- a/README.md +++ b/README.md @@ -104,6 +104,12 @@ thus it **does not** support `__div` nor `__pow` [metamethods](https://www.lua.org/manual/5.4/manual.html#2.4) and the type _number_ has only the subtype _integer_. +### Integer type + +Lunatik uses 64-bit integers on both 32-bit and 64-bit platforms. +However, on 32-bit systems, only division and modulo operations with 32-bit divisors are supported. +Attempting to divide or take the remainder using a divisor greater than `2^32 - 1` will raise an error. + ### Lua API Lunatik **does not** support both [io](https://www.lua.org/manual/5.4/manual.html#6.8) and diff --git a/lib/lualinux.c b/lib/lualinux.c index e5d56e500..191acdd50 100644 --- a/lib/lualinux.c +++ b/lib/lualinux.c @@ -1,5 +1,5 @@ /* -* SPDX-FileCopyrightText: (c) 2023-2024 Ring Zero Desenvolvimento de Software LTDA +* SPDX-FileCopyrightText: (c) 2023-2025 Ring Zero Desenvolvimento de Software LTDA * SPDX-License-Identifier: MIT OR GPL-2.0-only */ @@ -24,11 +24,7 @@ static int lualinux_random(lua_State *L) switch (lua_gettop(L)) { /* check number of arguments */ case 0: { /* no arguments */ -#ifdef __LP64__ lua_pushinteger(L, (lua_Integer)get_random_u64()); -#else - lua_pushinteger(L, (lua_Integer)get_random_u32()); -#endif return 1; } case 1: { /* only upper limit */ @@ -49,7 +45,7 @@ static int lualinux_random(lua_State *L) luaL_argcheck(L, low <= up, 1, "interval is empty"); luaL_argcheck(L, low >= 0 || up <= LUA_MAXINTEGER + low, 1, "interval too large"); - rand = low + get_random_u32() % (up - low + 1); + rand = low + lunatik_imod(L, get_random_u32(), up - low + 1); lua_pushinteger(L, rand); return 1; } @@ -125,20 +121,18 @@ static int lualinux_##func(lua_State *L) \ return 1; \ } -LUALINUX_NEW_BYTESWAPPER(cpu_to_be16, uint32_t); -LUALINUX_NEW_BYTESWAPPER(cpu_to_be32, uint32_t); -LUALINUX_NEW_BYTESWAPPER(cpu_to_le16, uint32_t); -LUALINUX_NEW_BYTESWAPPER(cpu_to_le32, uint32_t); -LUALINUX_NEW_BYTESWAPPER(be16_to_cpu, uint32_t); -LUALINUX_NEW_BYTESWAPPER(be32_to_cpu, uint32_t); -LUALINUX_NEW_BYTESWAPPER(le16_to_cpu, uint32_t); -LUALINUX_NEW_BYTESWAPPER(le32_to_cpu, uint32_t); -#ifdef __LP64__ -LUALINUX_NEW_BYTESWAPPER(cpu_to_be64, uint32_t); -LUALINUX_NEW_BYTESWAPPER(cpu_to_le64, uint32_t); -LUALINUX_NEW_BYTESWAPPER(be64_to_cpu, uint32_t); -LUALINUX_NEW_BYTESWAPPER(le64_to_cpu, uint32_t); -#endif +LUALINUX_NEW_BYTESWAPPER(cpu_to_be16, u16); +LUALINUX_NEW_BYTESWAPPER(cpu_to_be32, u32); +LUALINUX_NEW_BYTESWAPPER(cpu_to_le16, u16); +LUALINUX_NEW_BYTESWAPPER(cpu_to_le32, u32); +LUALINUX_NEW_BYTESWAPPER(be16_to_cpu, u16); +LUALINUX_NEW_BYTESWAPPER(be32_to_cpu, u32); +LUALINUX_NEW_BYTESWAPPER(le16_to_cpu, u16); +LUALINUX_NEW_BYTESWAPPER(le32_to_cpu, u32); +LUALINUX_NEW_BYTESWAPPER(cpu_to_be64, u64); +LUALINUX_NEW_BYTESWAPPER(cpu_to_le64, u64); +LUALINUX_NEW_BYTESWAPPER(be64_to_cpu, u64); +LUALINUX_NEW_BYTESWAPPER(le64_to_cpu, u64); static const lunatik_reg_t lualinux_task[] = { {"INTERRUPTIBLE", TASK_INTERRUPTIBLE}, @@ -238,14 +232,12 @@ static const luaL_Reg lualinux_lib[] = { {"be32toh", lualinux_be32_to_cpu}, {"le16toh", lualinux_le16_to_cpu}, {"le32toh", lualinux_le32_to_cpu}, -#ifdef __LP64__ {"ntoh64", lualinux_be64_to_cpu}, {"hton64", lualinux_cpu_to_be64}, {"htobe64", lualinux_cpu_to_be64}, {"htole64", lualinux_cpu_to_le64}, {"be64toh", lualinux_be64_to_cpu}, {"le64toh", lualinux_le64_to_cpu}, -#endif {NULL, NULL} }; diff --git a/lua b/lua index 4e8fd9a54..6997948d2 160000 --- a/lua +++ b/lua @@ -1 +1 @@ -Subproject commit 4e8fd9a543d4f58c15eb3d0e127e3605b59a6460 +Subproject commit 6997948d2c6b34d228d408a9465a88750d5e336a diff --git a/lunatik_conf.h b/lunatik_conf.h index 3608f9389..e29a1d565 100644 --- a/lunatik_conf.h +++ b/lunatik_conf.h @@ -1,11 +1,13 @@ /* -* SPDX-FileCopyrightText: (c) 2023-2024 Ring Zero Desenvolvimento de Software LTDA +* SPDX-FileCopyrightText: (c) 2023-2025 Ring Zero Desenvolvimento de Software LTDA * SPDX-License-Identifier: MIT OR GPL-2.0-only */ #ifndef lunatik_conf_h #define lunatik_conf_h +typedef struct lua_State lua_State; + #undef LUA_INTEGER #undef LUA_INTEGER_FRMLEN #undef LUA_UNSIGNED @@ -13,26 +15,64 @@ #undef LUA_MAXINTEGER #undef LUA_MININTEGER -#ifdef __LP64__ #define LUA_INTEGER long long #define LUA_INTEGER_FRMLEN "ll" #define LUA_UNSIGNED unsigned long long #define LUA_MAXUNSIGNED ULLONG_MAX #define LUA_MAXINTEGER LLONG_MAX #define LUA_MININTEGER LLONG_MIN -#else -#define LUA_INTEGER long -#define LUA_INTEGER_FRMLEN "l" -#define LUA_UNSIGNED unsigned long -#define LUA_MAXUNSIGNED ULONG_MAX -#define LUA_MAXINTEGER LONG_MAX -#define LUA_MININTEGER LONG_MIN -#endif /* __LP64__ */ #define LUAI_UACNUMBER LUA_INTEGER #define LUA_NUMBER LUA_INTEGER #define LUA_NUMBER_FMT LUA_INTEGER_FMT +#if BITS_PER_LONG == 64 +#define lunatik_idiv(L, m, n) ((m) / (n)) +#define lunatik_uidiv(L, m, n) ((m) / (n)) +#define lunatik_imod(L, m, n) ((m) % (n)) +#define lunatik_hashmod(t, n) hashmod((t), (n)) +#elif BITS_PER_LONG == 32 +#include +#include +static inline LUA_UNSIGNED _lunatik_uimod(LUA_UNSIGNED m, LUA_UNSIGNED n) +{ + u64 r; + BUG_ON(n < LONG_MIN || n > LONG_MAX); + div64_u64_rem(m, n, &r); + return r; +} +#define lunatik_hashmod(t, n) (gnode(t, _lunatik_uimod((n), ((sizenode(t)-1)|1)))) + +int (luaL_error) (lua_State *L, const char *fmt, ...); +#define lunatik_checklong(L, n, s) \ +do { \ + if (unlikely(n < LONG_MIN || n > LONG_MAX)) \ + luaL_error(L, s); \ +} while(0) + +static inline LUA_INTEGER lunatik_idiv(lua_State *L, LUA_INTEGER m, LUA_INTEGER n) +{ + lunatik_checklong(L, n, "attempt to divide by a 64-bit value"); + return div64_s64(m, n); +} + +static inline LUA_UNSIGNED lunatik_uidiv(lua_State *L, LUA_UNSIGNED m, LUA_UNSIGNED n) +{ + lunatik_checklong(L, n, "attempt to divide by a 64-bit value"); + return div64_u64(m, n); +} + +static inline LUA_INTEGER lunatik_imod(lua_State *L, LUA_INTEGER m, LUA_INTEGER n) +{ + s32 r; + lunatik_checklong(L, n, "attempt to perform 'n%%' with a 64-bit value"); + div_s64_rem(m, (s32)n, &r); + return (LUA_INTEGER)r; +} +#else /* BITS_PER_LONG */ +#error unsuported platform +#endif /* BITS_PER_LONG */ + #define l_randomizePivot() (~0) #include @@ -68,8 +108,6 @@ void *lunatik_lookup(const char *symbol); #define lsys_sym(L,l,s) ((lua_CFunction)(l)) -typedef struct lua_State lua_State; - const char *lua_pushfstring(lua_State *L, const char *fmt, ...); static inline void *lsys_load(lua_State *L, const char *symbol, int seeglb) From 4fc2612262014bf99fd7245aff518cb7f079c735 Mon Sep 17 00:00:00 2001 From: Lourival Vieira Neto Date: Thu, 15 May 2025 00:20:04 +0000 Subject: [PATCH 2/2] fixup! add support for 64-bit integer on 32-bit platforms --- lunatik_conf.h | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/lunatik_conf.h b/lunatik_conf.h index e29a1d565..c4efe3ffd 100644 --- a/lunatik_conf.h +++ b/lunatik_conf.h @@ -37,19 +37,26 @@ typedef struct lua_State lua_State; static inline LUA_UNSIGNED _lunatik_uimod(LUA_UNSIGNED m, LUA_UNSIGNED n) { u64 r; - BUG_ON(n < LONG_MIN || n > LONG_MAX); + //BUG_ON(n > ULONG_MAX); div64_u64_rem(m, n, &r); return r; } #define lunatik_hashmod(t, n) (gnode(t, _lunatik_uimod((n), ((sizenode(t)-1)|1)))) int (luaL_error) (lua_State *L, const char *fmt, ...); + #define lunatik_checklong(L, n, s) \ do { \ if (unlikely(n < LONG_MIN || n > LONG_MAX)) \ luaL_error(L, s); \ } while(0) +#define lunatik_checkulong(L, n, s) \ +do { \ + if (unlikely(n > ULONG_MAX)) \ + luaL_error(L, s); \ +} while(0) + static inline LUA_INTEGER lunatik_idiv(lua_State *L, LUA_INTEGER m, LUA_INTEGER n) { lunatik_checklong(L, n, "attempt to divide by a 64-bit value"); @@ -58,7 +65,7 @@ static inline LUA_INTEGER lunatik_idiv(lua_State *L, LUA_INTEGER m, LUA_INTEGER static inline LUA_UNSIGNED lunatik_uidiv(lua_State *L, LUA_UNSIGNED m, LUA_UNSIGNED n) { - lunatik_checklong(L, n, "attempt to divide by a 64-bit value"); + lunatik_checkulong(L, n, "attempt to divide by a 64-bit value"); return div64_u64(m, n); }