From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from smtp31.i.mail.ru (smtp31.i.mail.ru [94.100.177.91]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by dev.tarantool.org (Postfix) with ESMTPS id 28E13469719 for ; Mon, 16 Nov 2020 12:34:44 +0300 (MSK) From: imeevma@tarantool.org Date: Mon, 16 Nov 2020 12:34:43 +0300 Message-Id: <019d13b57364ded2f43e93efbc99a0b1ef11fc51.1605518956.git.imeevma@gmail.com> MIME-Version: 1.0 Content-Transfer-Encoding: 8bit Subject: [Tarantool-patches] [PATCH v1 1/1] lua: replace tonumber64() with misc.tonumber64() List-Id: Tarantool development patches List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , To: imun@tarantool.org Cc: tarantool-patches@dev.tarantool.org This patch replaces tonumber64() with misc.tonumber(), which works in a similar way, but always returns 64-bit integer cdata. Closes #4738 --- https://github.com/tarantool/tarantool/issues/4738 https://github.com/tarantool/tarantool/tree/imeevma/gh-4738-move-tonumber64-to-luajit @ChangeLog - Now tonumber64() always returns 64-bit integer cdata (gh-4738). src/box/lua/schema.lua | 3 + src/lua/init.c | 121 ----------------------------------------- test/box/misc.result | 10 ++-- test/box/misc.test.lua | 8 +-- 4 files changed, 12 insertions(+), 130 deletions(-) diff --git a/src/box/lua/schema.lua b/src/box/lua/schema.lua index b77c07bc8..eb72b12a5 100644 --- a/src/box/lua/schema.lua +++ b/src/box/lua/schema.lua @@ -1,6 +1,7 @@ -- schema.lua (internal file) -- local ffi = require('ffi') +local misc = require('misc') local msgpack = require('msgpack') local fun = require('fun') local log = require('log') @@ -11,6 +12,8 @@ local function setmap(table) return setmetatable(table, { __serialize = 'map' }) end +tonumber64 = misc.tonumber64 + local builtin = ffi.C -- performance fixup for hot functions diff --git a/src/lua/init.c b/src/lua/init.c index a0b2fc775..a46dc6136 100644 --- a/src/lua/init.c +++ b/src/lua/init.c @@ -174,126 +174,6 @@ static const char *lua_modules[] = { * {{{ box Lua library: common functions */ -/** - * Convert lua number or string to lua cdata 64bit number. - */ -static int -lbox_tonumber64(struct lua_State *L) -{ - luaL_checkany(L, 1); - int base = luaL_optint(L, 2, -1); - luaL_argcheck(L, (2 <= base && base <= 36) || base == -1, 2, - "base out of range"); - switch (lua_type(L, 1)) { - case LUA_TNUMBER: - base = (base == -1 ? 10 : base); - if (base != 10) - return luaL_argerror(L, 1, "string expected"); - lua_settop(L, 1); /* return original value as is */ - return 1; - case LUA_TSTRING: - { - size_t argl = 0; - const char *arg = luaL_checklstring(L, 1, &argl); - /* Trim whitespaces at begin/end */ - while (argl > 0 && isspace(arg[argl - 1])) { - argl--; - } - while (isspace(*arg)) { - arg++; argl--; - } - - /* - * Check if we're parsing custom format: - * 1) '0x' or '0X' trim in case of base == 16 or base == -1 - * 2) '0b' or '0B' trim in case of base == 2 or base == -1 - * 3) '-' for negative numbers - * 4) LL, ULL, LLU - trim, but only for base == 2 or - * base == 16 or base == -1. For consistency do not bother - * with any non-common bases, since user may have specified - * base >= 22, in which case 'L' will be a digit. - */ - char negative = 0; - if (arg[0] == '-') { - arg++; argl--; - negative = 1; - } - if (argl > 2 && arg[0] == '0') { - if ((arg[1] == 'x' || arg[1] == 'X') && - (base == 16 || base == -1)) { - base = 16; arg += 2; argl -= 2; - } else if ((arg[1] == 'b' || arg[1] == 'B') && - (base == 2 || base == -1)) { - base = 2; arg += 2; argl -= 2; - } - } - bool ull = false; - if (argl > 2 && (base == 2 || base == 16 || base == -1)) { - if (arg[argl - 1] == 'u' || arg[argl - 1] == 'U') { - ull = true; - --argl; - } - if ((arg[argl - 1] == 'l' || arg[argl - 1] == 'L') && - (arg[argl - 2] == 'l' || arg[argl - 2] == 'L')) - argl -= 2; - else { - ull = false; - goto skip; - } - if (!ull && (arg[argl - 1] == 'u' || - arg[argl - 1] == 'U')) { - ull = true; - --argl; - } - } -skip: base = (base == -1 ? 10 : base); - errno = 0; - char *arge; - unsigned long long result = strtoull(arg, &arge, base); - if (errno == 0 && arge == arg + argl) { - if (argl == 0) { - lua_pushnil(L); - } else if (negative) { - /* - * To test overflow, consider - * result > -INT64_MIN; - * result - 1 > -INT64_MIN - 1; - * Assumption: - * INT64_MAX == -(INT64_MIN + 1); - * Finally, - * result - 1 > INT64_MAX; - */ - if (ull) - luaL_pushuint64(L, (UINT64_MAX - result) + 1); - else if (result != 0 && result - 1 > INT64_MAX) - lua_pushnil(L); - else - luaL_pushint64(L, -result); - } else { - luaL_pushuint64(L, result); - } - return 1; - } - break; - } /* LUA_TSTRING */ - case LUA_TCDATA: - { - base = (base == -1 ? 10 : base); - if (base != 10) - return luaL_argerror(L, 1, "string expected"); - uint32_t ctypeid = 0; - luaL_checkcdata(L, 1, &ctypeid); - if (ctypeid >= CTID_INT8 && ctypeid <= CTID_DOUBLE) { - lua_pushvalue(L, 1); - return 1; - } - break; - } /* LUA_TCDATA */ - } - lua_pushnil(L); - return 1; -} - /* }}} */ /** @@ -446,7 +326,6 @@ tarantool_lua_init(const char *tarantool_bin, int argc, char **argv) /* Initialize ffi to enable luaL_pushcdata/luaL_checkcdata functions */ luaL_loadstring(L, "return require('ffi')"); lua_call(L, 0, 0); - lua_register(L, "tonumber64", lbox_tonumber64); tarantool_lua_utf8_init(L); tarantool_lua_utils_init(L); diff --git a/test/box/misc.result b/test/box/misc.result index 714d5ee79..f6b72ccee 100644 --- a/test/box/misc.result +++ b/test/box/misc.result @@ -290,7 +290,7 @@ tonumber64('123') --- - 123 ... -type(tonumber64('4294967296')) == 'number' +type(tonumber64('4294967296')) == 'cdata' --- - true ... @@ -329,7 +329,7 @@ tonumber64(tonumber64(2)) ... tostring(tonumber64(tonumber64(3))) --- -- '3' +- 3ULL ... -- A test case for Bug#1131108 'tonumber64 from negative int inconsistency' tonumber64(-1) @@ -364,11 +364,11 @@ tonumber64(-1.0) --- - -1 ... -tostring(tonumber64('1234567890123')) == '1234567890123' +tostring(tonumber64('1234567890123')) == '1234567890123ULL' --- - true ... -tostring(tonumber64('12345678901234')) == '12345678901234' +tostring(tonumber64('12345678901234')) == '12345678901234ULL' --- - true ... @@ -403,7 +403,7 @@ tonumber64('-9223372036854775809') == nil --- - true ... -tostring(tonumber64('0')) == '0' +tostring(tonumber64('0')) == '0ULL' --- - true ... diff --git a/test/box/misc.test.lua b/test/box/misc.test.lua index 63cbe2bc5..c642cf95f 100644 --- a/test/box/misc.test.lua +++ b/test/box/misc.test.lua @@ -105,7 +105,7 @@ tonumber64() tonumber64('invalid number') tonumber64(123) tonumber64('123') -type(tonumber64('4294967296')) == 'number' +type(tonumber64('4294967296')) == 'cdata' tonumber64('9223372036854775807') == tonumber64('9223372036854775807') tonumber64('9223372036854775807') - tonumber64('9223372036854775800') tonumber64('18446744073709551615') == tonumber64('18446744073709551615') @@ -125,8 +125,8 @@ tonumber64(-1ULL) -1ULL tonumber64(-1.0) 6LL - 7LL -tostring(tonumber64('1234567890123')) == '1234567890123' -tostring(tonumber64('12345678901234')) == '12345678901234' +tostring(tonumber64('1234567890123')) == '1234567890123ULL' +tostring(tonumber64('12345678901234')) == '12345678901234ULL' tostring(tonumber64('123456789012345')) == '123456789012345ULL' tostring(tonumber64('1234567890123456')) == '1234567890123456ULL' @@ -138,7 +138,7 @@ tostring(tonumber64('18446744073709551615')) == '18446744073709551615ULL' tonumber64('18446744073709551616') == nil tostring(tonumber64('-9223372036854775808')) == '-9223372036854775808LL' tonumber64('-9223372036854775809') == nil -tostring(tonumber64('0')) == '0' +tostring(tonumber64('0')) == '0ULL' -- -- gh-3431: tonumber of strings with ULL. -- 2.25.1