From: Ilya Markov <imarkov@tarantool.org> To: georgy@tarantool.org Cc: tarantool-patches@freelists.org Subject: [tarantool-patches] [error 1/3] lua: moving lua error functions to separate file Date: Fri, 4 May 2018 17:07:18 +0300 [thread overview] Message-ID: <e969df7ad306884fc41f31c0a15475ff9491dd6e.1525442633.git.imarkov@tarantool.org> (raw) In-Reply-To: <cover.1525442633.git.imarkov@tarantool.org> In-Reply-To: <cover.1525442633.git.imarkov@tarantool.org> Refactoring. Move lua error functions to separate file. Prerequisite #677 --- src/CMakeLists.txt | 3 + src/box/func.c | 1 + src/box/lua/call.c | 1 + src/box/lua/cfg.cc | 3 +- src/box/lua/ctl.c | 1 + src/box/lua/error.cc | 1 + src/box/lua/index.c | 1 + src/box/lua/init.c | 1 + src/box/lua/misc.cc | 1 + src/box/lua/sequence.c | 1 + src/box/lua/session.c | 1 + src/box/lua/tuple.c | 1 + src/box/lua/xlog.c | 1 + src/lua/error.c | 117 +++++++++++++++++++++++++++++++++++++ src/lua/error.h | 67 +++++++++++++++++++++ src/lua/error.lua | 156 +++++++++++++++++++++++++++++++++++++++++++++++++ src/lua/fiber.c | 1 + src/lua/fio.c | 1 + src/lua/httpc.c | 1 + src/lua/init.c | 4 ++ src/lua/init.lua | 150 +---------------------------------------------- src/lua/pickle.c | 1 + src/lua/socket.c | 1 + src/lua/utils.c | 77 +----------------------- src/lua/utils.h | 14 ----- 25 files changed, 368 insertions(+), 239 deletions(-) create mode 100644 src/lua/error.c create mode 100644 src/lua/error.h create mode 100644 src/lua/error.lua diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 8ab09e9..f5c5bec 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -24,6 +24,7 @@ lua_source(lua_sources lua/fiber.lua) lua_source(lua_sources lua/buffer.lua) lua_source(lua_sources lua/uuid.lua) lua_source(lua_sources lua/crypto.lua) +lua_source(lua_sources lua/error.lua) lua_source(lua_sources lua/digest.lua) lua_source(lua_sources lua/msgpackffi.lua) lua_source(lua_sources lua/uri.lua) @@ -159,6 +160,7 @@ set (server_sources lua/msgpack.c lua/utils.c lua/errno.c + lua/error.c lua/socket.c lua/pickle.c lua/fio.c @@ -180,6 +182,7 @@ set(api_headers ${CMAKE_SOURCE_DIR}/src/coio.h ${CMAKE_SOURCE_DIR}/src/coio_task.h ${CMAKE_SOURCE_DIR}/src/lua/utils.h + ${CMAKE_SOURCE_DIR}/src/lua/error.h ${CMAKE_SOURCE_DIR}/src/box/txn.h ${CMAKE_SOURCE_DIR}/src/box/key_def.h ${CMAKE_SOURCE_DIR}/src/box/field_def.h diff --git a/src/box/func.c b/src/box/func.c index dfbc5f3..72336c1 100644 --- a/src/box/func.c +++ b/src/box/func.c @@ -32,6 +32,7 @@ #include "trivia/config.h" #include "assoc.h" #include "lua/utils.h" +#include <lua/error.h> #include "error.h" #include "diag.h" #include <dlfcn.h> diff --git a/src/box/lua/call.c b/src/box/lua/call.c index be13812..dbab02b 100644 --- a/src/box/lua/call.c +++ b/src/box/lua/call.c @@ -28,6 +28,7 @@ * THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. */ +#include <lua/error.h> #include "box/lua/call.h" #include "box/call.h" #include "box/error.h" diff --git a/src/box/lua/cfg.cc b/src/box/lua/cfg.cc index 5e88ca3..99fa63e 100644 --- a/src/box/lua/cfg.cc +++ b/src/box/lua/cfg.cc @@ -33,8 +33,9 @@ #include "exception.h" #include <cfg.h> -#include "main.h" #include "lua/utils.h" +#include <lua/error.h> +#include "main.h" #include "box/box.h" #include "libeio/eio.h" diff --git a/src/box/lua/ctl.c b/src/box/lua/ctl.c index 9a105ed..2ede16a 100644 --- a/src/box/lua/ctl.c +++ b/src/box/lua/ctl.c @@ -35,6 +35,7 @@ #include <lua.h> #include <lauxlib.h> #include <lualib.h> +#include <lua/error.h> #include "lua/utils.h" diff --git a/src/box/lua/error.cc b/src/box/lua/error.cc index 3149074..2adf123 100644 --- a/src/box/lua/error.cc +++ b/src/box/lua/error.cc @@ -38,6 +38,7 @@ extern "C" { #include <fiber.h> #include <errinj.h> +#include <lua/error.h> #include "lua/utils.h" #include "box/error.h" diff --git a/src/box/lua/index.c b/src/box/lua/index.c index 6dfa648..116c369 100644 --- a/src/box/lua/index.c +++ b/src/box/lua/index.c @@ -28,6 +28,7 @@ * THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. */ +#include <lua/error.h> #include "box/lua/index.h" #include "lua/utils.h" #include "box/box.h" diff --git a/src/box/lua/init.c b/src/box/lua/init.c index 7547758..0fdaaf9 100644 --- a/src/box/lua/init.c +++ b/src/box/lua/init.c @@ -33,6 +33,7 @@ #include <lua.h> #include <lauxlib.h> #include <lualib.h> +#include <lua/error.h> #include "lua/utils.h" /* luaT_error() */ diff --git a/src/box/lua/misc.cc b/src/box/lua/misc.cc index bc76065..f3e6021 100644 --- a/src/box/lua/misc.cc +++ b/src/box/lua/misc.cc @@ -33,6 +33,7 @@ #include "fiber.h" /* fiber->gc() */ #include <small/region.h> #include "lua/utils.h" +#include <lua/error.h> #include "lua/msgpack.h" #include "box/box.h" diff --git a/src/box/lua/sequence.c b/src/box/lua/sequence.c index 2fead2e..9e8322a 100644 --- a/src/box/lua/sequence.c +++ b/src/box/lua/sequence.c @@ -28,6 +28,7 @@ * THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. */ +#include <lua/error.h> #include "box/lua/sequence.h" #include "box/lua/tuple.h" #include "lua/utils.h" diff --git a/src/box/lua/session.c b/src/box/lua/session.c index 51caf19..277b710 100644 --- a/src/box/lua/session.c +++ b/src/box/lua/session.c @@ -36,6 +36,7 @@ #include <lauxlib.h> #include <lualib.h> #include <sio.h> +#include <lua/error.h> #include "box/box.h" #include "box/session.h" diff --git a/src/box/lua/tuple.c b/src/box/lua/tuple.c index 7ca4299..cb4969e 100644 --- a/src/box/lua/tuple.c +++ b/src/box/lua/tuple.c @@ -36,6 +36,7 @@ #include <small/ibuf.h> #include <small/region.h> #include <fiber.h> +#include <lua/error.h> #include "box/tuple.h" #include "box/tuple_convert.h" diff --git a/src/box/lua/xlog.c b/src/box/lua/xlog.c index 030f5c2..583cc28 100644 --- a/src/box/lua/xlog.c +++ b/src/box/lua/xlog.c @@ -43,6 +43,7 @@ #include <box/lua/tuple.h> #include <lua/msgpack.h> #include <lua/utils.h> +#include <lua/error.h> #include "box/memtx_tuple.h" /* {{{ Helpers */ diff --git a/src/lua/error.c b/src/lua/error.c new file mode 100644 index 0000000..d660e4c --- /dev/null +++ b/src/lua/error.c @@ -0,0 +1,117 @@ +/* + * Copyright 2010-2018, Tarantool AUTHORS, please see AUTHORS file. + * + * Redistribution and use in source and binary forms, with or + * without modification, are permitted provided that the following + * conditions are met: + * + * 1. Redistributions of source code must retain the above + * copyright notice, this list of conditions and the + * following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following + * disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY <COPYRIGHT HOLDER> ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED + * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL + * <COPYRIGHT HOLDER> OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, + * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR + * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF + * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF + * THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#include <diag.h> +#include <fiber.h> +#include "utils.h" +#include "error.h" + +static int CTID_CONST_STRUCT_ERROR_REF = 0; + +int +luaT_error(lua_State *L) +{ + struct error *e = diag_last_error(&fiber()->diag); + assert(e != NULL); + error_ref(e); + /* + * gh-1955 luaT_pusherror allocates Lua objects, thus it may trigger + * GC. GC may invoke finalizers which are arbitrary Lua code, + * potentially invalidating last error object, hence error_ref + * below. + */ + luaT_pusherror(L, e); + error_unref(e); + lua_error(L); + unreachable(); + return 0; +} + +struct error * +luaL_iserror(struct lua_State *L, int narg) +{ + assert(CTID_CONST_STRUCT_ERROR_REF != 0); + if (lua_type(L, narg) != LUA_TCDATA) + return NULL; + + uint32_t ctypeid; + void *data = luaL_checkcdata(L, narg, &ctypeid); + if (ctypeid != (uint32_t) CTID_CONST_STRUCT_ERROR_REF) + return NULL; + + struct error *e = *(struct error **) data; + assert(e->refs); + return e; +} + +static struct error * +luaL_checkerror(struct lua_State *L, int narg) +{ + struct error *error = luaL_iserror(L, narg); + if (error == NULL) { + luaL_error(L, "Invalid argument #%d (error expected, got %s)", + narg, lua_typename(L, lua_type(L, narg))); + } + return error; +} + +static int +luaL_error_gc(struct lua_State *L) +{ + struct error *error = luaL_checkerror(L, 1); + error_unref(error); + return 0; +} + +void +luaT_pusherror(struct lua_State *L, struct error *e) +{ + assert(CTID_CONST_STRUCT_ERROR_REF != 0); + struct error **ptr = (struct error **) + luaL_pushcdata(L, CTID_CONST_STRUCT_ERROR_REF); + *ptr = e; + /* The order is important - first reference the error, then set gc */ + error_ref(e); + lua_pushcfunction(L, luaL_error_gc); + luaL_setcdatagc(L, -2); +} + +void +tarantool_lua_error_init(struct lua_State *L) +{ + + /* Get CTypeID for `struct error *' */ + int rc = luaL_cdef(L, "struct error;"); + assert(rc == 0); + (void) rc; + CTID_CONST_STRUCT_ERROR_REF = luaL_ctypeid(L, "const struct error &"); + assert(CTID_CONST_STRUCT_ERROR_REF != 0); +} diff --git a/src/lua/error.h b/src/lua/error.h new file mode 100644 index 0000000..ee489da --- /dev/null +++ b/src/lua/error.h @@ -0,0 +1,67 @@ +#ifndef TARANTOOL_ERROR_H +#define TARANTOOL_ERROR_H +/* + * Copyright 2010-2018, Tarantool AUTHORS, please see AUTHORS file. + * + * Redistribution and use in source and binary forms, with or + * without modification, are permitted provided that the following + * conditions are met: + * + * 1. Redistributions of source code must retain the above + * copyright notice, this list of conditions and the + * following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following + * disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY <COPYRIGHT HOLDER> ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED + * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL + * <COPYRIGHT HOLDER> OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, + * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR + * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF + * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF + * THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ +#include <lua.h> +#include <lauxlib.h> /* luaL_error */ + +#if defined(__cplusplus) +extern "C" { +#endif /* defined(__cplusplus) */ + + +/** \cond public */ +struct error; + +/** + * Re-throws the last Tarantool error as a Lua object. + * \sa lua_error() + * \sa box_error_last() + */ +LUA_API int +luaT_error(lua_State *L); + +void +luaT_pusherror(struct lua_State *L, struct error *e); +/** \endcond public */ + + +struct error * +luaL_iserror(struct lua_State *L, int narg); + +void +tarantool_lua_error_init(struct lua_State *L); + +#if defined(__cplusplus) +} /* extern "C" */ +#endif /* defined(__cplusplus) */ + +#endif //TARANTOOL_ERROR_H diff --git a/src/lua/error.lua b/src/lua/error.lua new file mode 100644 index 0000000..a402378 --- /dev/null +++ b/src/lua/error.lua @@ -0,0 +1,156 @@ +-- error.lua (internal file) + +local ffi = require('ffi') +ffi.cdef[[ +enum { METHOD_ARG_MAX = 8 }; + +struct method_info { + const struct type_info *owner; + const char *name; + enum ctype rtype; + enum ctype atype[METHOD_ARG_MAX]; + int nargs; + bool isconst; + + union { + /* Add extra space to get proper struct size in C */ + void *_spacer[2]; + }; +}; + +char * +exception_get_string(struct error *e, const struct method_info *method); +int +exception_get_int(struct error *e, const struct method_info *method); + +]] + +local REFLECTION_CACHE = {} + +local function reflection_enumerate(err) + local key = tostring(err._type) + local result = REFLECTION_CACHE[key] + if result ~= nil then + return result + end + result = {} + -- See type_foreach_method() in reflection.h + local t = err._type + while t ~= nil do + local m = t.methods + while m.name ~= nil do + result[ffi.string(m.name)] = m + m = m + 1 + end + t = t.parent + end + REFLECTION_CACHE[key] = result + return result +end + +local function reflection_get(err, method) + if method.nargs ~= 0 then + return nil -- NYI + end + if method.rtype == ffi.C.CTYPE_INT then + return tonumber(ffi.C.exception_get_int(err, method)) + elseif method.rtype == ffi.C.CTYPE_CONST_CHAR_PTR then + local str = ffi.C.exception_get_string(err, method) + if str == nil then + return nil + end + return ffi.string(str) + end +end + +local function error_type(err) + return ffi.string(err._type.name) +end + +local function error_message(err) + return ffi.string(err._errmsg) +end + +local function error_trace(err) + if err._file[0] == 0 then + return {} + end + return { + { file = ffi.string(err._file), line = tonumber(err._line) }; + } +end + + +local error_fields = { + ["type"] = error_type; + ["message"] = error_message; + ["trace"] = error_trace; +} + +local function error_unpack(err) + if not ffi.istype('struct error', err) then + error("Usage: error:unpack()") + end + local result = {} + for key, getter in pairs(error_fields) do + result[key] = getter(err) + end + for key, getter in pairs(reflection_enumerate(err)) do + local value = reflection_get(err, getter) + if value ~= nil then + result[key] = value + end + end + return result +end + +local function error_raise(err) + if not ffi.istype('struct error', err) then + error("Usage: error:raise()") + end + error(err) +end + +local function error_match(err, ...) + if not ffi.istype('struct error', err) then + error("Usage: error:match()") + end + return string.match(error_message(err), ...) +end + +local function error_serialize(err) + -- Return an error message only in admin console to keep compatibility + return error_message(err) +end + +local error_methods = { + ["unpack"] = error_unpack; + ["raise"] = error_raise; + ["match"] = error_match; -- Tarantool 1.6 backward compatibility + ["__serialize"] = error_serialize; +} + +local function error_index(err, key) + local getter = error_fields[key] + if getter ~= nil then + return getter(err) + end + getter = reflection_enumerate(err)[key] + if getter ~= nil and getter.nargs == 0 then + local val = reflection_get(err, getter) + if val ~= nil then + return val + end + end + return error_methods[key] +end + + +local error_mt = { + __index = error_index; + __tostring = error_message; +}; + +ffi.metatype('struct error', error_mt); + +return error \ No newline at end of file diff --git a/src/lua/fiber.c b/src/lua/fiber.c index 83b5825..7ab3808 100644 --- a/src/lua/fiber.c +++ b/src/lua/fiber.c @@ -31,6 +31,7 @@ #include "lua/fiber.h" #include <fiber.h> +#include "lua/error.h" #include "lua/utils.h" #include "backtrace.h" diff --git a/src/lua/fio.c b/src/lua/fio.c index 806f425..a58dbf3 100644 --- a/src/lua/fio.c +++ b/src/lua/fio.c @@ -46,6 +46,7 @@ #include "lua/utils.h" #include "coio_file.h" +#include "lua/error.h" static inline void lbox_fio_pushsyserror(struct lua_State *L) diff --git a/src/lua/httpc.c b/src/lua/httpc.c index 45abb98..203e929 100644 --- a/src/lua/httpc.c +++ b/src/lua/httpc.c @@ -40,6 +40,7 @@ #include "lua/utils.h" #include "lua/httpc.h" #include "src/fiber.h" +#include "lua/error.h" /** Internal util functions * {{{ diff --git a/src/lua/init.c b/src/lua/init.c index a0a7f63..257c6c9 100644 --- a/src/lua/init.c +++ b/src/lua/init.c @@ -58,6 +58,7 @@ #include "lua/fio.h" #include "lua/httpc.h" #include "digest.h" +#include "error.h" #include <small/ibuf.h> #include <ctype.h> @@ -95,6 +96,7 @@ extern char strict_lua[], help_en_US_lua[], tap_lua[], fio_lua[], + error_lua[], argparse_lua[], iconv_lua[], /* jit.* library */ @@ -134,6 +136,7 @@ static const char *lua_modules[] = { "log", log_lua, "uri", uri_lua, "fio", fio_lua, + "error", error_lua, "csv", csv_lua, "clock", clock_lua, "socket", socket_lua, @@ -404,6 +407,7 @@ tarantool_lua_init(const char *tarantool_bin, int argc, char **argv) tarantool_lua_fiber_cond_init(L); tarantool_lua_fiber_channel_init(L); tarantool_lua_errno_init(L); + tarantool_lua_error_init(L); tarantool_lua_fio_init(L); tarantool_lua_socket_init(L); tarantool_lua_pickle_init(L); diff --git a/src/lua/init.lua b/src/lua/init.lua index 83f2c8d..5d08151 100644 --- a/src/lua/init.lua +++ b/src/lua/init.lua @@ -1,10 +1,10 @@ + -- init.lua -- internal file local ffi = require('ffi') ffi.cdef[[ struct type_info; struct method_info; -struct error; enum ctype { CTYPE_VOID = 0, @@ -39,27 +39,6 @@ struct error { char _errmsg[DIAG_ERRMSG_MAX]; }; -enum { METHOD_ARG_MAX = 8 }; - -struct method_info { - const struct type_info *owner; - const char *name; - enum ctype rtype; - enum ctype atype[METHOD_ARG_MAX]; - int nargs; - bool isconst; - - union { - /* Add extra space to get proper struct size in C */ - void *_spacer[2]; - }; -}; - -char * -exception_get_string(struct error *e, const struct method_info *method); -int -exception_get_int(struct error *e, const struct method_info *method); - double tarantool_uptime(void); typedef int32_t pid_t; @@ -68,132 +47,6 @@ pid_t getpid(void); local fio = require("fio") -local REFLECTION_CACHE = {} - -local function reflection_enumerate(err) - local key = tostring(err._type) - local result = REFLECTION_CACHE[key] - if result ~= nil then - return result - end - result = {} - -- See type_foreach_method() in reflection.h - local t = err._type - while t ~= nil do - local m = t.methods - while m.name ~= nil do - result[ffi.string(m.name)] = m - m = m + 1 - end - t = t.parent - end - REFLECTION_CACHE[key] = result - return result -end - -local function reflection_get(err, method) - if method.nargs ~= 0 then - return nil -- NYI - end - if method.rtype == ffi.C.CTYPE_INT then - return tonumber(ffi.C.exception_get_int(err, method)) - elseif method.rtype == ffi.C.CTYPE_CONST_CHAR_PTR then - local str = ffi.C.exception_get_string(err, method) - if str == nil then - return nil - end - return ffi.string(str) - end -end - -local function error_type(err) - return ffi.string(err._type.name) -end - -local function error_message(err) - return ffi.string(err._errmsg) -end - -local function error_trace(err) - if err._file[0] == 0 then - return {} - end - return { - { file = ffi.string(err._file), line = tonumber(err._line) }; - } -end - -local error_fields = { - ["type"] = error_type; - ["message"] = error_message; - ["trace"] = error_trace; -} - -local function error_unpack(err) - if not ffi.istype('struct error', err) then - error("Usage: error:unpack()") - end - local result = {} - for key, getter in pairs(error_fields) do - result[key] = getter(err) - end - for key, getter in pairs(reflection_enumerate(err)) do - local value = reflection_get(err, getter) - if value ~= nil then - result[key] = value - end - end - return result -end - -local function error_raise(err) - if not ffi.istype('struct error', err) then - error("Usage: error:raise()") - end - error(err) -end - -local function error_match(err, ...) - if not ffi.istype('struct error', err) then - error("Usage: error:match()") - end - return string.match(error_message(err), ...) -end - -local function error_serialize(err) - -- Return an error message only in admin console to keep compatibility - return error_message(err) -end - -local error_methods = { - ["unpack"] = error_unpack; - ["raise"] = error_raise; - ["match"] = error_match; -- Tarantool 1.6 backward compatibility - ["__serialize"] = error_serialize; -} - -local function error_index(err, key) - local getter = error_fields[key] - if getter ~= nil then - return getter(err) - end - getter = reflection_enumerate(err)[key] - if getter ~= nil and getter.nargs == 0 then - local val = reflection_get(err, getter) - if val ~= nil then - return val - end - end - return error_methods[key] -end - -local error_mt = { - __index = error_index; - __tostring = error_message; -}; - -ffi.metatype('struct error', error_mt); - dostring = function(s, ...) local chunk, message = loadstring(s) if chunk == nil then @@ -343,6 +196,7 @@ table.insert(package.loaders, 5, rocks_loader_func(true)) -- croot 8 package.search = search + return { uptime = uptime; pid = pid; diff --git a/src/lua/pickle.c b/src/lua/pickle.c index e47ac11..4238491 100644 --- a/src/lua/pickle.c +++ b/src/lua/pickle.c @@ -41,6 +41,7 @@ #include "lua/msgpack.h" /* luaL_msgpack_default */ #include <fiber.h> #include "bit/bit.h" +#include "lua/error.h" static inline void luaL_region_dup(struct lua_State *L, struct region *region, diff --git a/src/lua/socket.c b/src/lua/socket.c index 14d49d1..1ed8021 100644 --- a/src/lua/socket.c +++ b/src/lua/socket.c @@ -53,6 +53,7 @@ #include <coio_task.h> /* coio_getaddrinfo() */ #include <fiber.h> #include "lua/utils.h" +#include "lua/error.h" #include "lua/fiber.h" extern int coio_wait(int fd, int event, double timeout); diff --git a/src/lua/utils.c b/src/lua/utils.c index 2094bcc..bf1548b 100644 --- a/src/lua/utils.c +++ b/src/lua/utils.c @@ -29,6 +29,7 @@ * SUCH DAMAGE. */ #include "lua/utils.h" +#include "error.h" #include <assert.h> #include <errno.h> @@ -40,7 +41,6 @@ int luaL_nil_ref = LUA_REFNIL; int luaL_map_metatable_ref = LUA_REFNIL; int luaL_array_metatable_ref = LUA_REFNIL; -static int CTID_CONST_STRUCT_ERROR_REF = 0; void * luaL_pushcdata(struct lua_State *L, uint32_t ctypeid) @@ -843,73 +843,6 @@ luaL_toint64(struct lua_State *L, int idx) return 0; } -struct error * -luaL_iserror(struct lua_State *L, int narg) -{ - assert(CTID_CONST_STRUCT_ERROR_REF != 0); - if (lua_type(L, narg) != LUA_TCDATA) - return NULL; - - uint32_t ctypeid; - void *data = luaL_checkcdata(L, narg, &ctypeid); - if (ctypeid != (uint32_t) CTID_CONST_STRUCT_ERROR_REF) - return NULL; - - struct error *e = *(struct error **) data; - assert(e->refs); - return e; -} - -static struct error * -luaL_checkerror(struct lua_State *L, int narg) -{ - struct error *error = luaL_iserror(L, narg); - if (error == NULL) { - luaL_error(L, "Invalid argument #%d (error expected, got %s)", - narg, lua_typename(L, lua_type(L, narg))); - } - return error; -} - -static int -luaL_error_gc(struct lua_State *L) -{ - struct error *error = luaL_checkerror(L, 1); - error_unref(error); - return 0; -} - -void -luaT_pusherror(struct lua_State *L, struct error *e) -{ - assert(CTID_CONST_STRUCT_ERROR_REF != 0); - struct error **ptr = (struct error **) luaL_pushcdata(L, - CTID_CONST_STRUCT_ERROR_REF); - *ptr = e; - /* The order is important - first reference the error, then set gc */ - error_ref(e); - lua_pushcfunction(L, luaL_error_gc); - luaL_setcdatagc(L, -2); -} - -int -luaT_error(lua_State *L) -{ - struct error *e = diag_last_error(&fiber()->diag); - assert(e != NULL); - /* - * gh-1955 luaT_pusherror allocates Lua objects, thus it may trigger - * GC. GC may invoke finalizers which are arbitrary Lua code, - * potentially invalidating last error object, hence error_ref - * below. - */ - error_ref(e); - luaT_pusherror(L, e); - error_unref(e); - lua_error(L); - unreachable(); - return 0; -} static inline int lbox_catch(lua_State *L) @@ -954,13 +887,6 @@ tarantool_lua_utils_init(struct lua_State *L) {NULL, NULL}, }; - /* Get CTypeID for `struct error *' */ - int rc = luaL_cdef(L, "struct error;"); - assert(rc == 0); - (void) rc; - CTID_CONST_STRUCT_ERROR_REF = luaL_ctypeid(L, "const struct error &"); - assert(CTID_CONST_STRUCT_ERROR_REF != 0); - luaL_register_type(L, LUAL_SERIALIZER, serializermeta); /* Create NULL constant */ *(void **) luaL_pushcdata(L, CTID_P_VOID) = NULL; @@ -984,4 +910,3 @@ tarantool_lua_utils_init(struct lua_State *L) return 0; } - diff --git a/src/lua/utils.h b/src/lua/utils.h index 77c2204..02ce93b 100644 --- a/src/lua/utils.h +++ b/src/lua/utils.h @@ -55,7 +55,6 @@ extern "C" { struct lua_State; struct ibuf; -struct error; /** * Single global lua_State shared by core and modules. @@ -403,14 +402,6 @@ LUA_API int64_t luaL_toint64(struct lua_State *L, int idx); /** - * Re-throws the last Tarantool error as a Lua object. - * \sa lua_error() - * \sa box_error_last() - */ -LUA_API int -luaT_error(lua_State *L); - -/** * Like lua_call(), but with the proper support of Tarantool errors. * \sa lua_call() */ @@ -432,11 +423,6 @@ luaT_state(void); /** \endcond public */ -void -luaT_pusherror(struct lua_State *L, struct error *e); - -struct error * -luaL_iserror(struct lua_State *L, int narg); /** * Push Lua Table with __serialize = 'map' hint onto the stack. -- 2.7.4
next prev parent reply other threads:[~2018-05-04 14:07 UTC|newest] Thread overview: 4+ messages / expand[flat|nested] mbox.gz Atom feed top [not found] <14848871.eLyv8AkjAN@home.lan> 2018-05-04 14:07 ` [tarantool-patches] [error 0/3] Introduce error traceback Ilya Markov 2018-05-04 14:07 ` Ilya Markov [this message] 2018-05-04 14:07 ` [tarantool-patches] [error 2/3] error: Add lua traceback Ilya Markov 2018-05-04 14:07 ` [tarantool-patches] [error 3/3] error: Add C frames in error.traceback Ilya Markov
Reply instructions: You may reply publicly to this message via plain-text email using any one of the following methods: * Save the following mbox file, import it into your mail client, and reply-to-all from there: mbox Avoid top-posting and favor interleaved quoting: https://en.wikipedia.org/wiki/Posting_style#Interleaved_style * Reply using the --to, --cc, and --in-reply-to switches of git-send-email(1): git send-email \ --in-reply-to=e969df7ad306884fc41f31c0a15475ff9491dd6e.1525442633.git.imarkov@tarantool.org \ --to=imarkov@tarantool.org \ --cc=georgy@tarantool.org \ --cc=tarantool-patches@freelists.org \ --subject='Re: [tarantool-patches] [error 1/3] lua: moving lua error functions to separate file' \ /path/to/YOUR_REPLY https://kernel.org/pub/software/scm/git/docs/git-send-email.html * If your mail client supports setting the In-Reply-To header via mailto: links, try the mailto: link
This is a public inbox, see mirroring instructions for how to clone and mirror all data and code used for this inbox