diff --git a/src/box/lua/call.c b/src/box/lua/call.c index eacd6781e227d6585691e8e9f47983b848b26edd..2013a61fc7e62c949be0f8201361f593b77a68b4 100644 --- a/src/box/lua/call.c +++ b/src/box/lua/call.c @@ -756,23 +756,26 @@ prepare_lua_sandbox(struct lua_State *L, const char *exports[], /** * Assemble a Lua function object by user-defined function body. + * On success, returns a Lua reference to the loaded function. + * On error, returns LUA_NOREF and sets diag. */ static int -func_persistent_lua_load(struct func_lua *func) +func_persistent_lua_load(struct func_def *def) { - int rc = -1; + assert(def->body != NULL); + int func_ref = LUA_NOREF; int top = lua_gettop(tarantool_L); struct region *region = &fiber()->gc; size_t region_svp = region_used(region); const char *load_pref = "return "; uint32_t load_str_sz = - strlen(load_pref) + strlen(func->base.def->body) + 1; + strlen(load_pref) + strlen(def->body) + 1; char *load_str = region_alloc(region, load_str_sz); if (load_str == NULL) { diag_set(OutOfMemory, load_str_sz, "region", "load_str"); - return -1; + return LUA_NOREF; } - snprintf(load_str, load_str_sz, "%s%s", load_pref, func->base.def->body); + snprintf(load_str, load_str_sz, "%s%s", load_pref, def->body); /* * Perform loading of the persistent Lua function @@ -783,8 +786,8 @@ func_persistent_lua_load(struct func_lua *func) */ lua_State *coro_L = luaT_newthread(tarantool_L); if (coro_L == NULL) - return -1; - if (!func->base.def->is_sandboxed) { + return LUA_NOREF; + if (!def->is_sandboxed) { /* * Keep the original env to apply to a non-sandboxed * persistent function. It is necessary since @@ -799,35 +802,33 @@ func_persistent_lua_load(struct func_lua *func) int coro_ref = luaL_ref(tarantool_L, LUA_REGISTRYINDEX); if (luaL_loadstring(coro_L, load_str) != 0 || lua_pcall(coro_L, 0, 1, 0) != 0) { - diag_set(ClientError, ER_LOAD_FUNCTION, func->base.def->name, + diag_set(ClientError, ER_LOAD_FUNCTION, def->name, luaT_tolstring(coro_L, -1, NULL)); goto end; } if (!lua_isfunction(coro_L, -1)) { - diag_set(ClientError, ER_LOAD_FUNCTION, func->base.def->name, + diag_set(ClientError, ER_LOAD_FUNCTION, def->name, "given body doesn't define a function"); goto end; } lua_xmove(coro_L, tarantool_L, 1); - if (func->base.def->is_sandboxed) { + if (def->is_sandboxed) { if (prepare_lua_sandbox(tarantool_L, default_sandbox_exports, nelem(default_sandbox_exports)) != 0) { diag_add(ClientError, ER_LOAD_FUNCTION, - func->base.def->name, - "can't prepare a Lua sandbox"); + def->name, "can't prepare a Lua sandbox"); goto end; } } else { lua_insert(tarantool_L, -2); } lua_setfenv(tarantool_L, -2); - func->lua_ref = luaL_ref(tarantool_L, LUA_REGISTRYINDEX); - rc = 0; + func_ref = luaL_ref(tarantool_L, LUA_REGISTRYINDEX); end: lua_settop(tarantool_L, top); region_truncate(region, region_svp); luaL_unref(tarantool_L, LUA_REGISTRYINDEX, coro_ref); - return rc; + return func_ref; } struct func * @@ -841,12 +842,12 @@ func_lua_new(struct func_def *def) return NULL; } if (def->body != NULL) { - func->base.def = def; - func->base.vtab = &func_persistent_lua_vtab; - if (func_persistent_lua_load(func) != 0) { + func->lua_ref = func_persistent_lua_load(def); + if (func->lua_ref == LUA_NOREF) { free(func); return NULL; } + func->base.vtab = &func_persistent_lua_vtab; } else { func->lua_ref = LUA_REFNIL; func->base.vtab = &func_lua_vtab;