aboutsummaryrefslogtreecommitdiff
path: root/src/script/cpp_api
diff options
context:
space:
mode:
Diffstat (limited to 'src/script/cpp_api')
-rw-r--r--src/script/cpp_api/s_base.cpp33
-rw-r--r--src/script/cpp_api/s_base.h3
-rw-r--r--src/script/cpp_api/s_entity.cpp60
-rw-r--r--src/script/cpp_api/s_inventory.cpp147
-rw-r--r--src/script/cpp_api/s_item.cpp70
-rw-r--r--src/script/cpp_api/s_mainmenu.cpp28
-rw-r--r--src/script/cpp_api/s_node.cpp92
-rw-r--r--src/script/cpp_api/s_nodemeta.cpp162
-rw-r--r--src/script/cpp_api/s_server.cpp31
9 files changed, 345 insertions, 281 deletions
diff --git a/src/script/cpp_api/s_base.cpp b/src/script/cpp_api/s_base.cpp
index e26d54ba7..b1272b64e 100644
--- a/src/script/cpp_api/s_base.cpp
+++ b/src/script/cpp_api/s_base.cpp
@@ -55,23 +55,6 @@ public:
}
};
-static int loadScript_ErrorHandler(lua_State *L) {
- lua_getfield(L, LUA_GLOBALSINDEX, "debug");
- if (!lua_istable(L, -1)) {
- lua_pop(L, 1);
- return 1;
- }
- lua_getfield(L, -1, "traceback");
- if (!lua_isfunction(L, -1)) {
- lua_pop(L, 2);
- return 1;
- }
- lua_pushvalue(L, 1);
- lua_pushinteger(L, 2);
- lua_call(L, 2, 1);
- return 1;
-}
-
/*
ScriptApiBase
@@ -133,7 +116,7 @@ bool ScriptApiBase::loadScript(const std::string &scriptpath)
lua_State *L = getStack();
- lua_pushcfunction(L, loadScript_ErrorHandler);
+ lua_pushcfunction(L, script_error_handler);
int errorhandler = lua_gettop(L);
int ret = luaL_loadfile(L, scriptpath.c_str()) || lua_pcall(L, 0, 0, errorhandler);
@@ -144,7 +127,7 @@ bool ScriptApiBase::loadScript(const std::string &scriptpath)
errorstream<<std::endl;
errorstream<<lua_tostring(L, -1)<<std::endl;
errorstream<<std::endl;
- errorstream<<"=======END OF ERROR FROM LUA ========"<<std::endl;
+ errorstream<<"======= END OF ERROR FROM LUA ========"<<std::endl;
lua_pop(L, 1); // Pop error message from stack
lua_pop(L, 1); // Pop the error handler from stack
return false;
@@ -159,19 +142,13 @@ void ScriptApiBase::realityCheck()
if(top >= 30){
dstream<<"Stack is over 30:"<<std::endl;
stackDump(dstream);
- scriptError("Stack is over 30 (reality check)");
+ throw LuaError(m_luastack, "Stack is over 30 (reality check)");
}
}
-void ScriptApiBase::scriptError(const char *fmt, ...)
+void ScriptApiBase::scriptError()
{
- va_list argp;
- va_start(argp, fmt);
- char buf[10000];
- vsnprintf(buf, 10000, fmt, argp);
- va_end(argp);
- //errorstream<<"SCRIPT ERROR: "<<buf;
- throw LuaError(m_luastack, buf);
+ throw LuaError(NULL, lua_tostring(m_luastack, -1));
}
void ScriptApiBase::stackDump(std::ostream &o)
diff --git a/src/script/cpp_api/s_base.h b/src/script/cpp_api/s_base.h
index 63f7e423f..75552cc34 100644
--- a/src/script/cpp_api/s_base.h
+++ b/src/script/cpp_api/s_base.h
@@ -31,6 +31,7 @@ extern "C" {
#include "jthread/jmutex.h"
#include "jthread/jmutexautolock.h"
#include "common/c_types.h"
+#include "common/c_internal.h"
#define SCRIPTAPI_LOCK_DEBUG
@@ -65,7 +66,7 @@ protected:
{ return m_luastack; }
void realityCheck();
- void scriptError(const char *fmt, ...);
+ void scriptError();
void stackDump(std::ostream &o);
Server* getServer() { return m_server; }
diff --git a/src/script/cpp_api/s_entity.cpp b/src/script/cpp_api/s_entity.cpp
index cefa27cb1..c9d1bd8e0 100644
--- a/src/script/cpp_api/s_entity.cpp
+++ b/src/script/cpp_api/s_entity.cpp
@@ -78,25 +78,29 @@ void ScriptApiEntity::luaentity_Activate(u16 id,
{
SCRIPTAPI_PRECHECKHEADER
+ lua_pushcfunction(L, script_error_handler);
+ int errorhandler = lua_gettop(L);
+
verbosestream<<"scriptapi_luaentity_activate: id="<<id<<std::endl;
// Get minetest.luaentities[id]
- luaentity_get(L,id);
+ luaentity_get(L, id);
int object = lua_gettop(L);
// Get on_activate function
- lua_pushvalue(L, object);
lua_getfield(L, -1, "on_activate");
- if(!lua_isnil(L, -1)){
+ if(!lua_isnil(L, -1)) {
luaL_checktype(L, -1, LUA_TFUNCTION);
lua_pushvalue(L, object); // self
lua_pushlstring(L, staticdata.c_str(), staticdata.size());
lua_pushinteger(L, dtime_s);
// Call with 3 arguments, 0 results
- if(lua_pcall(L, 3, 0, 0))
- scriptError("error running function on_activate: %s\n",
- lua_tostring(L, -1));
+ if(lua_pcall(L, 3, 0, errorhandler))
+ scriptError();
+ } else {
+ lua_pop(L, 1);
}
+ lua_pop(L, 2); // Pop object and error handler
}
void ScriptApiEntity::luaentity_Remove(u16 id)
@@ -123,14 +127,16 @@ std::string ScriptApiEntity::luaentity_GetStaticdata(u16 id)
{
SCRIPTAPI_PRECHECKHEADER
+ lua_pushcfunction(L, script_error_handler);
+ int errorhandler = lua_gettop(L);
+
//infostream<<"scriptapi_luaentity_get_staticdata: id="<<id<<std::endl;
// Get minetest.luaentities[id]
- luaentity_get(L,id);
+ luaentity_get(L, id);
int object = lua_gettop(L);
// Get get_staticdata function
- lua_pushvalue(L, object);
lua_getfield(L, -1, "get_staticdata");
if(lua_isnil(L, -1))
return "";
@@ -138,11 +144,12 @@ std::string ScriptApiEntity::luaentity_GetStaticdata(u16 id)
luaL_checktype(L, -1, LUA_TFUNCTION);
lua_pushvalue(L, object); // self
// Call with 1 arguments, 1 results
- if(lua_pcall(L, 1, 1, 0))
- scriptError("error running function get_staticdata: %s\n",
- lua_tostring(L, -1));
+ if(lua_pcall(L, 1, 1, errorhandler))
+ scriptError();
+ lua_remove(L, object); // Remove object
+ lua_remove(L, errorhandler); // Remove error handler
- size_t len=0;
+ size_t len = 0;
const char *s = lua_tolstring(L, -1, &len);
return std::string(s, len);
}
@@ -192,10 +199,13 @@ void ScriptApiEntity::luaentity_Step(u16 id, float dtime)
{
SCRIPTAPI_PRECHECKHEADER
+ lua_pushcfunction(L, script_error_handler);
+ int errorhandler = lua_gettop(L);
+
//infostream<<"scriptapi_luaentity_step: id="<<id<<std::endl;
// Get minetest.luaentities[id]
- luaentity_get(L,id);
+ luaentity_get(L, id);
int object = lua_gettop(L);
// State: object is at top of stack
// Get step function
@@ -206,8 +216,10 @@ void ScriptApiEntity::luaentity_Step(u16 id, float dtime)
lua_pushvalue(L, object); // self
lua_pushnumber(L, dtime); // dtime
// Call with 2 arguments, 0 results
- if(lua_pcall(L, 2, 0, 0))
- scriptError("error running function 'on_step': %s\n", lua_tostring(L, -1));
+ if(lua_pcall(L, 2, 0, errorhandler))
+ scriptError();
+ lua_remove(L, object); // Remove object
+ lua_remove(L, errorhandler); // Remove error handler
}
// Calls entity:on_punch(ObjectRef puncher, time_from_last_punch,
@@ -218,6 +230,9 @@ void ScriptApiEntity::luaentity_Punch(u16 id,
{
SCRIPTAPI_PRECHECKHEADER
+ lua_pushcfunction(L, script_error_handler);
+ int errorhandler = lua_gettop(L);
+
//infostream<<"scriptapi_luaentity_step: id="<<id<<std::endl;
// Get minetest.luaentities[id]
@@ -235,8 +250,10 @@ void ScriptApiEntity::luaentity_Punch(u16 id,
push_tool_capabilities(L, *toolcap);
push_v3f(L, dir);
// Call with 5 arguments, 0 results
- if(lua_pcall(L, 5, 0, 0))
- scriptError("error running function 'on_punch': %s\n", lua_tostring(L, -1));
+ if(lua_pcall(L, 5, 0, errorhandler))
+ scriptError();
+ lua_remove(L, object); // Remove object
+ lua_remove(L, errorhandler); // Remove error handler
}
// Calls entity:on_rightclick(ObjectRef clicker)
@@ -245,6 +262,9 @@ void ScriptApiEntity::luaentity_Rightclick(u16 id,
{
SCRIPTAPI_PRECHECKHEADER
+ lua_pushcfunction(L, script_error_handler);
+ int errorhandler = lua_gettop(L);
+
//infostream<<"scriptapi_luaentity_step: id="<<id<<std::endl;
// Get minetest.luaentities[id]
@@ -259,7 +279,9 @@ void ScriptApiEntity::luaentity_Rightclick(u16 id,
lua_pushvalue(L, object); // self
objectrefGetOrCreate(clicker); // Clicker reference
// Call with 2 arguments, 0 results
- if(lua_pcall(L, 2, 0, 0))
- scriptError("error running function 'on_rightclick': %s\n", lua_tostring(L, -1));
+ if(lua_pcall(L, 2, 0, errorhandler))
+ scriptError();
+ lua_remove(L, object); // Remove object
+ lua_remove(L, errorhandler); // Remove error handler
}
diff --git a/src/script/cpp_api/s_inventory.cpp b/src/script/cpp_api/s_inventory.cpp
index 09f26d80c..4ee6e4be0 100644
--- a/src/script/cpp_api/s_inventory.cpp
+++ b/src/script/cpp_api/s_inventory.cpp
@@ -33,6 +33,9 @@ int ScriptApiDetached::detached_inventory_AllowMove(
{
SCRIPTAPI_PRECHECKHEADER
+ lua_pushcfunction(L, script_error_handler);
+ int errorhandler = lua_gettop(L);
+
// Push callback function on stack
if(!getDetachedInventoryCallback(name, "allow_move"))
return count;
@@ -42,23 +45,19 @@ int ScriptApiDetached::detached_inventory_AllowMove(
InventoryLocation loc;
loc.setDetached(name);
InvRef::create(L, loc);
- // from_list
- lua_pushstring(L, from_list.c_str());
- // from_index
- lua_pushinteger(L, from_index + 1);
- // to_list
- lua_pushstring(L, to_list.c_str());
- // to_index
- lua_pushinteger(L, to_index + 1);
- // count
- lua_pushinteger(L, count);
- // player
- objectrefGetOrCreate(player);
- if(lua_pcall(L, 7, 1, 0))
- scriptError("error: %s", lua_tostring(L, -1));
+ lua_pushstring(L, from_list.c_str()); // from_list
+ lua_pushinteger(L, from_index + 1); // from_index
+ lua_pushstring(L, to_list.c_str()); // to_list
+ lua_pushinteger(L, to_index + 1); // to_index
+ lua_pushinteger(L, count); // count
+ objectrefGetOrCreate(player); // player
+ if(lua_pcall(L, 7, 1, errorhandler))
+ scriptError();
if(!lua_isnumber(L, -1))
throw LuaError(L, "allow_move should return a number");
- return luaL_checkinteger(L, -1);
+ int ret = luaL_checkinteger(L, -1);
+ lua_pop(L, 2); // Pop integer and error handler
+ return ret;
}
// Return number of accepted items to be put
@@ -69,28 +68,28 @@ int ScriptApiDetached::detached_inventory_AllowPut(
{
SCRIPTAPI_PRECHECKHEADER
+ lua_pushcfunction(L, script_error_handler);
+ int errorhandler = lua_gettop(L);
+
// Push callback function on stack
if(!getDetachedInventoryCallback(name, "allow_put"))
return stack.count; // All will be accepted
// Call function(inv, listname, index, stack, player)
- // inv
InventoryLocation loc;
loc.setDetached(name);
- InvRef::create(L, loc);
- // listname
- lua_pushstring(L, listname.c_str());
- // index
- lua_pushinteger(L, index + 1);
- // stack
- LuaItemStack::create(L, stack);
- // player
- objectrefGetOrCreate(player);
- if(lua_pcall(L, 5, 1, 0))
- scriptError("error: %s", lua_tostring(L, -1));
+ InvRef::create(L, loc); // inv
+ lua_pushstring(L, listname.c_str()); // listname
+ lua_pushinteger(L, index + 1); // index
+ LuaItemStack::create(L, stack); // stack
+ objectrefGetOrCreate(player); // player
+ if(lua_pcall(L, 5, 1, errorhandler))
+ scriptError();
if(!lua_isnumber(L, -1))
throw LuaError(L, "allow_put should return a number");
- return luaL_checkinteger(L, -1);
+ int ret = luaL_checkinteger(L, -1);
+ lua_pop(L, 2); // Pop integer and error handler
+ return ret;
}
// Return number of accepted items to be taken
@@ -101,28 +100,28 @@ int ScriptApiDetached::detached_inventory_AllowTake(
{
SCRIPTAPI_PRECHECKHEADER
+ lua_pushcfunction(L, script_error_handler);
+ int errorhandler = lua_gettop(L);
+
// Push callback function on stack
if(!getDetachedInventoryCallback(name, "allow_take"))
return stack.count; // All will be accepted
// Call function(inv, listname, index, stack, player)
- // inv
InventoryLocation loc;
loc.setDetached(name);
- InvRef::create(L, loc);
- // listname
- lua_pushstring(L, listname.c_str());
- // index
- lua_pushinteger(L, index + 1);
- // stack
- LuaItemStack::create(L, stack);
- // player
- objectrefGetOrCreate(player);
- if(lua_pcall(L, 5, 1, 0))
- scriptError("error: %s", lua_tostring(L, -1));
+ InvRef::create(L, loc); // inv
+ lua_pushstring(L, listname.c_str()); // listname
+ lua_pushinteger(L, index + 1); // index
+ LuaItemStack::create(L, stack); // stack
+ objectrefGetOrCreate(player); // player
+ if(lua_pcall(L, 5, 1, errorhandler))
+ scriptError();
if(!lua_isnumber(L, -1))
throw LuaError(L, "allow_take should return a number");
- return luaL_checkinteger(L, -1);
+ int ret = luaL_checkinteger(L, -1);
+ lua_pop(L, 2); // Pop integer and error handler
+ return ret;
}
// Report moved items
@@ -134,6 +133,9 @@ void ScriptApiDetached::detached_inventory_OnMove(
{
SCRIPTAPI_PRECHECKHEADER
+ lua_pushcfunction(L, script_error_handler);
+ int errorhandler = lua_gettop(L);
+
// Push callback function on stack
if(!getDetachedInventoryCallback(name, "on_move"))
return;
@@ -143,20 +145,15 @@ void ScriptApiDetached::detached_inventory_OnMove(
InventoryLocation loc;
loc.setDetached(name);
InvRef::create(L, loc);
- // from_list
- lua_pushstring(L, from_list.c_str());
- // from_index
- lua_pushinteger(L, from_index + 1);
- // to_list
- lua_pushstring(L, to_list.c_str());
- // to_index
- lua_pushinteger(L, to_index + 1);
- // count
- lua_pushinteger(L, count);
- // player
- objectrefGetOrCreate(player);
- if(lua_pcall(L, 7, 0, 0))
- scriptError("error: %s", lua_tostring(L, -1));
+ lua_pushstring(L, from_list.c_str()); // from_list
+ lua_pushinteger(L, from_index + 1); // from_index
+ lua_pushstring(L, to_list.c_str()); // to_list
+ lua_pushinteger(L, to_index + 1); // to_index
+ lua_pushinteger(L, count); // count
+ objectrefGetOrCreate(player); // player
+ if(lua_pcall(L, 7, 0, errorhandler))
+ scriptError();
+ lua_pop(L, 1); // Pop error handler
}
// Report put items
@@ -167,6 +164,9 @@ void ScriptApiDetached::detached_inventory_OnPut(
{
SCRIPTAPI_PRECHECKHEADER
+ lua_pushcfunction(L, script_error_handler);
+ int errorhandler = lua_gettop(L);
+
// Push callback function on stack
if(!getDetachedInventoryCallback(name, "on_put"))
return;
@@ -176,16 +176,13 @@ void ScriptApiDetached::detached_inventory_OnPut(
InventoryLocation loc;
loc.setDetached(name);
InvRef::create(L, loc);
- // listname
- lua_pushstring(L, listname.c_str());
- // index
- lua_pushinteger(L, index + 1);
- // stack
- LuaItemStack::create(L, stack);
- // player
- objectrefGetOrCreate(player);
- if(lua_pcall(L, 5, 0, 0))
- scriptError("error: %s", lua_tostring(L, -1));
+ lua_pushstring(L, listname.c_str()); // listname
+ lua_pushinteger(L, index + 1); // index
+ LuaItemStack::create(L, stack); // stack
+ objectrefGetOrCreate(player); // player
+ if(lua_pcall(L, 5, 0, errorhandler))
+ scriptError();
+ lua_pop(L, 1); // Pop error handler
}
// Report taken items
@@ -196,6 +193,9 @@ void ScriptApiDetached::detached_inventory_OnTake(
{
SCRIPTAPI_PRECHECKHEADER
+ lua_pushcfunction(L, script_error_handler);
+ int errorhandler = lua_gettop(L);
+
// Push callback function on stack
if(!getDetachedInventoryCallback(name, "on_take"))
return;
@@ -205,16 +205,13 @@ void ScriptApiDetached::detached_inventory_OnTake(
InventoryLocation loc;
loc.setDetached(name);
InvRef::create(L, loc);
- // listname
- lua_pushstring(L, listname.c_str());
- // index
- lua_pushinteger(L, index + 1);
- // stack
- LuaItemStack::create(L, stack);
- // player
- objectrefGetOrCreate(player);
- if(lua_pcall(L, 5, 0, 0))
- scriptError("error: %s", lua_tostring(L, -1));
+ lua_pushstring(L, listname.c_str()); // listname
+ lua_pushinteger(L, index + 1); // index
+ LuaItemStack::create(L, stack); // stack
+ objectrefGetOrCreate(player); // player
+ if(lua_pcall(L, 5, 0, errorhandler))
+ scriptError();
+ lua_pop(L, 1); // Pop error handler
}
// Retrieves minetest.detached_inventories[name][callbackname]
diff --git a/src/script/cpp_api/s_item.cpp b/src/script/cpp_api/s_item.cpp
index 1d5f218cf..49729e57b 100644
--- a/src/script/cpp_api/s_item.cpp
+++ b/src/script/cpp_api/s_item.cpp
@@ -34,6 +34,9 @@ bool ScriptApiItem::item_OnDrop(ItemStack &item,
{
SCRIPTAPI_PRECHECKHEADER
+ lua_pushcfunction(L, script_error_handler);
+ int errorhandler = lua_gettop(L);
+
// Push callback function on stack
if(!getItemCallback(item.name.c_str(), "on_drop"))
return false;
@@ -42,10 +45,11 @@ bool ScriptApiItem::item_OnDrop(ItemStack &item,
LuaItemStack::create(L, item);
objectrefGetOrCreate(dropper);
pushFloatPos(L, pos);
- if(lua_pcall(L, 3, 1, 0))
- scriptError("error: %s", lua_tostring(L, -1));
+ if(lua_pcall(L, 3, 1, errorhandler))
+ scriptError();
if(!lua_isnil(L, -1))
item = read_item(L,-1, getServer());
+ lua_pop(L, 2); // Pop item and error handler
return true;
}
@@ -54,6 +58,9 @@ bool ScriptApiItem::item_OnPlace(ItemStack &item,
{
SCRIPTAPI_PRECHECKHEADER
+ lua_pushcfunction(L, script_error_handler);
+ int errorhandler = lua_gettop(L);
+
// Push callback function on stack
if(!getItemCallback(item.name.c_str(), "on_place"))
return false;
@@ -62,10 +69,11 @@ bool ScriptApiItem::item_OnPlace(ItemStack &item,
LuaItemStack::create(L, item);
objectrefGetOrCreate(placer);
pushPointedThing(pointed);
- if(lua_pcall(L, 3, 1, 0))
- scriptError("error: %s", lua_tostring(L, -1));
+ if(lua_pcall(L, 3, 1, errorhandler))
+ scriptError();
if(!lua_isnil(L, -1))
item = read_item(L,-1, getServer());
+ lua_pop(L, 2); // Pop item and error handler
return true;
}
@@ -74,6 +82,9 @@ bool ScriptApiItem::item_OnUse(ItemStack &item,
{
SCRIPTAPI_PRECHECKHEADER
+ lua_pushcfunction(L, script_error_handler);
+ int errorhandler = lua_gettop(L);
+
// Push callback function on stack
if(!getItemCallback(item.name.c_str(), "on_use"))
return false;
@@ -82,10 +93,11 @@ bool ScriptApiItem::item_OnUse(ItemStack &item,
LuaItemStack::create(L, item);
objectrefGetOrCreate(user);
pushPointedThing(pointed);
- if(lua_pcall(L, 3, 1, 0))
- scriptError("error: %s", lua_tostring(L, -1));
+ if(lua_pcall(L, 3, 1, errorhandler))
+ scriptError();
if(!lua_isnil(L, -1))
item = read_item(L,-1, getServer());
+ lua_pop(L, 2); // Pop item and error handler
return true;
}
@@ -94,6 +106,9 @@ bool ScriptApiItem::item_OnCraft(ItemStack &item, ServerActiveObject *user,
{
SCRIPTAPI_PRECHECKHEADER
+ lua_pushcfunction(L, script_error_handler);
+ int errorhandler = lua_gettop(L);
+
lua_getglobal(L, "minetest");
lua_getfield(L, -1, "on_craft");
LuaItemStack::create(L, item);
@@ -106,10 +121,11 @@ bool ScriptApiItem::item_OnCraft(ItemStack &item, ServerActiveObject *user,
push_items(L, items);
InvRef::create(L, craft_inv);
- if(lua_pcall(L, 4, 1, 0))
- scriptError("error: %s", lua_tostring(L, -1));
+ if(lua_pcall(L, 4, 1, errorhandler))
+ scriptError();
if(!lua_isnil(L, -1))
item = read_item(L,-1, getServer());
+ lua_pop(L, 2); // Pop item and error handler
return true;
}
@@ -118,11 +134,14 @@ bool ScriptApiItem::item_CraftPredict(ItemStack &item, ServerActiveObject *user,
{
SCRIPTAPI_PRECHECKHEADER
+ lua_pushcfunction(L, script_error_handler);
+ int errorhandler = lua_gettop(L);
+
lua_getglobal(L, "minetest");
lua_getfield(L, -1, "craft_predict");
LuaItemStack::create(L, item);
objectrefGetOrCreate(user);
-
+
//Push inventory list
std::vector<ItemStack> items;
for(u32 i=0; i<old_craft_grid->getSize(); i++)
@@ -130,10 +149,11 @@ bool ScriptApiItem::item_CraftPredict(ItemStack &item, ServerActiveObject *user,
push_items(L, items);
InvRef::create(L, craft_inv);
- if(lua_pcall(L, 4, 1, 0))
- scriptError("error: %s", lua_tostring(L, -1));
+ if(lua_pcall(L, 4, 1, errorhandler))
+ scriptError();
if(!lua_isnil(L, -1))
item = read_item(L,-1, getServer());
+ lua_pop(L, 2); // Pop item and error handler
return true;
}
@@ -149,15 +169,15 @@ bool ScriptApiItem::getItemCallback(const char *name, const char *callbackname)
lua_getglobal(L, "minetest");
lua_getfield(L, -1, "registered_items");
- lua_remove(L, -2);
+ lua_remove(L, -2); // Remove minetest
luaL_checktype(L, -1, LUA_TTABLE);
lua_getfield(L, -1, name);
- lua_remove(L, -2);
+ lua_remove(L, -2); // Remove registered_items
// Should be a table
if(lua_type(L, -1) != LUA_TTABLE)
{
// Report error and clean up
- errorstream<<"Item \""<<name<<"\" not defined"<<std::endl;
+ errorstream << "Item \"" << name << "\" not defined" << std::endl;
lua_pop(L, 1);
// Try minetest.nodedef_default instead
@@ -167,24 +187,16 @@ bool ScriptApiItem::getItemCallback(const char *name, const char *callbackname)
luaL_checktype(L, -1, LUA_TTABLE);
}
lua_getfield(L, -1, callbackname);
- lua_remove(L, -2);
+ lua_remove(L, -2); // Remove item def
// Should be a function or nil
- if(lua_type(L, -1) == LUA_TFUNCTION)
- {
+ if (lua_type(L, -1) == LUA_TFUNCTION) {
return true;
+ } else if (!lua_isnil(L, -1)) {
+ errorstream << "Item \"" << name << "\" callback \""
+ << callbackname << "\" is not a function" << std::endl;
}
- else if(lua_isnil(L, -1))
- {
- lua_pop(L, 1);
- return false;
- }
- else
- {
- errorstream<<"Item \""<<name<<"\" callback \""
- <<callbackname<<" is not a function"<<std::endl;
- lua_pop(L, 1);
- return false;
- }
+ lua_pop(L, 1);
+ return false;
}
void ScriptApiItem::pushPointedThing(const PointedThing& pointed)
diff --git a/src/script/cpp_api/s_mainmenu.cpp b/src/script/cpp_api/s_mainmenu.cpp
index af92c59a9..5c54f7368 100644
--- a/src/script/cpp_api/s_mainmenu.cpp
+++ b/src/script/cpp_api/s_mainmenu.cpp
@@ -37,29 +37,41 @@ void ScriptApiMainMenu::handleMainMenuEvent(std::string text)
{
SCRIPTAPI_PRECHECKHEADER
+ lua_pushcfunction(L, script_error_handler);
+ int errorhandler = lua_gettop(L);
+
// Get handler function
lua_getglobal(L, "engine");
lua_getfield(L, -1, "event_handler");
- if(lua_isnil(L, -1))
+ lua_remove(L, -2); // Remove engine
+ if(lua_isnil(L, -1)) {
+ lua_pop(L, 1); // Pop event_handler
return;
+ }
luaL_checktype(L, -1, LUA_TFUNCTION);
// Call it
lua_pushstring(L, text.c_str());
- if(lua_pcall(L, 1, 0, 0))
- scriptError("error running function engine.event_handler: %s\n",
- lua_tostring(L, -1));
+ if(lua_pcall(L, 1, 0, errorhandler))
+ scriptError();
+ lua_pop(L, 1); // Pop error handler
}
void ScriptApiMainMenu::handleMainMenuButtons(std::map<std::string, std::string> fields)
{
SCRIPTAPI_PRECHECKHEADER
+ lua_pushcfunction(L, script_error_handler);
+ int errorhandler = lua_gettop(L);
+
// Get handler function
lua_getglobal(L, "engine");
lua_getfield(L, -1, "button_handler");
- if(lua_isnil(L, -1))
+ lua_remove(L, -2); // Remove engine
+ if(lua_isnil(L, -1)) {
+ lua_pop(L, 1); // Pop button handler
return;
+ }
luaL_checktype(L, -1, LUA_TFUNCTION);
// Convert fields to lua table
@@ -74,7 +86,7 @@ void ScriptApiMainMenu::handleMainMenuButtons(std::map<std::string, std::string>
}
// Call it
- if(lua_pcall(L, 1, 0, 0))
- scriptError("error running function engine.button_handler: %s\n",
- lua_tostring(L, -1));
+ if(lua_pcall(L, 1, 0, errorhandler))
+ scriptError();
+ lua_pop(L, 1); // Pop error handler
}
diff --git a/src/script/cpp_api/s_node.cpp b/src/script/cpp_api/s_node.cpp
index 92fd00a74..cd8451cf0 100644
--- a/src/script/cpp_api/s_node.cpp
+++ b/src/script/cpp_api/s_node.cpp
@@ -91,6 +91,9 @@ bool ScriptApiNode::node_on_punch(v3s16 p, MapNode node,
{
SCRIPTAPI_PRECHECKHEADER
+ lua_pushcfunction(L, script_error_handler);
+ int errorhandler = lua_gettop(L);
+
INodeDefManager *ndef = getServer()->ndef();
// Push callback function on stack
@@ -101,8 +104,9 @@ bool ScriptApiNode::node_on_punch(v3s16 p, MapNode node,
push_v3s16(L, p);
pushnode(L, node, ndef);
objectrefGetOrCreate(puncher);
- if(lua_pcall(L, 3, 0, 0))
- scriptError("error: %s", lua_tostring(L, -1));
+ if(lua_pcall(L, 3, 0, errorhandler))
+ scriptError();
+ lua_pop(L, 1); // Pop error handler
return true;
}
@@ -111,6 +115,9 @@ bool ScriptApiNode::node_on_dig(v3s16 p, MapNode node,
{
SCRIPTAPI_PRECHECKHEADER
+ lua_pushcfunction(L, script_error_handler);
+ int errorhandler = lua_gettop(L);
+
INodeDefManager *ndef = getServer()->ndef();
// Push callback function on stack
@@ -121,8 +128,9 @@ bool ScriptApiNode::node_on_dig(v3s16 p, MapNode node,
push_v3s16(L, p);
pushnode(L, node, ndef);
objectrefGetOrCreate(digger);
- if(lua_pcall(L, 3, 0, 0))
- scriptError("error: %s", lua_tostring(L, -1));
+ if(lua_pcall(L, 3, 0, errorhandler))
+ scriptError();
+ lua_pop(L, 1); // Pop error handler
return true;
}
@@ -130,6 +138,9 @@ void ScriptApiNode::node_on_construct(v3s16 p, MapNode node)
{
SCRIPTAPI_PRECHECKHEADER
+ lua_pushcfunction(L, script_error_handler);
+ int errorhandler = lua_gettop(L);
+
INodeDefManager *ndef = getServer()->ndef();
// Push callback function on stack
@@ -138,14 +149,18 @@ void ScriptApiNode::node_on_construct(v3s16 p, MapNode node)
// Call function
push_v3s16(L, p);
- if(lua_pcall(L, 1, 0, 0))
- scriptError("error: %s", lua_tostring(L, -1));
+ if(lua_pcall(L, 1, 0, errorhandler))
+ scriptError();
+ lua_pop(L, 1); // Pop error handler
}
void ScriptApiNode::node_on_destruct(v3s16 p, MapNode node)
{
SCRIPTAPI_PRECHECKHEADER
+ lua_pushcfunction(L, script_error_handler);
+ int errorhandler = lua_gettop(L);
+
INodeDefManager *ndef = getServer()->ndef();
// Push callback function on stack
@@ -154,14 +169,18 @@ void ScriptApiNode::node_on_destruct(v3s16 p, MapNode node)
// Call function
push_v3s16(L, p);
- if(lua_pcall(L, 1, 0, 0))
- scriptError("error: %s", lua_tostring(L, -1));
+ if(lua_pcall(L, 1, 0, errorhandler))
+ scriptError();
+ lua_pop(L, 1); // Pop error handler
}
void ScriptApiNode::node_after_destruct(v3s16 p, MapNode node)
{
SCRIPTAPI_PRECHECKHEADER
+ lua_pushcfunction(L, script_error_handler);
+ int errorhandler = lua_gettop(L);
+
INodeDefManager *ndef = getServer()->ndef();
// Push callback function on stack
@@ -171,14 +190,18 @@ void ScriptApiNode::node_after_destruct(v3s16 p, MapNode node)
// Call function
push_v3s16(L, p);
pushnode(L, node, ndef);
- if(lua_pcall(L, 2, 0, 0))
- scriptError("error: %s", lua_tostring(L, -1));
+ if(lua_pcall(L, 2, 0, errorhandler))
+ scriptError();
+ lua_pop(L, 1); // Pop error handler
}
bool ScriptApiNode::node_on_timer(v3s16 p, MapNode node, f32 dtime)
{
SCRIPTAPI_PRECHECKHEADER
+ lua_pushcfunction(L, script_error_handler);
+ int errorhandler = lua_gettop(L);
+
INodeDefManager *ndef = getServer()->ndef();
// Push callback function on stack
@@ -188,12 +211,10 @@ bool ScriptApiNode::node_on_timer(v3s16 p, MapNode node, f32 dtime)
// Call function
push_v3s16(L, p);
lua_pushnumber(L,dtime);
- if(lua_pcall(L, 2, 1, 0))
- scriptError("error: %s", lua_tostring(L, -1));
- if((bool)lua_isboolean(L,-1) && (bool)lua_toboolean(L,-1) == true)
- return true;
-
- return false;
+ if(lua_pcall(L, 2, 1, errorhandler))
+ scriptError();
+ lua_remove(L, errorhandler); // Remove error handler
+ return (bool) lua_isboolean(L, -1) && (bool) lua_toboolean(L, -1) == true;
}
void ScriptApiNode::node_on_receive_fields(v3s16 p,
@@ -203,6 +224,9 @@ void ScriptApiNode::node_on_receive_fields(v3s16 p,
{
SCRIPTAPI_PRECHECKHEADER
+ lua_pushcfunction(L, script_error_handler);
+ int errorhandler = lua_gettop(L);
+
INodeDefManager *ndef = getServer()->ndef();
// If node doesn't exist, we don't know what callback to call
@@ -215,12 +239,9 @@ void ScriptApiNode::node_on_receive_fields(v3s16 p,
return;
// Call function
- // param 1
- push_v3s16(L, p);
- // param 2
- lua_pushstring(L, formname.c_str());
- // param 3
- lua_newtable(L);
+ push_v3s16(L, p); // pos
+ lua_pushstring(L, formname.c_str()); // formname
+ lua_newtable(L); // fields
for(std::map<std::string, std::string>::const_iterator
i = fields.begin(); i != fields.end(); i++){
const std::string &name = i->first;
@@ -229,26 +250,37 @@ void ScriptApiNode::node_on_receive_fields(v3s16 p,
lua_pushlstring(L, value.c_str(), value.size());
lua_settable(L, -3);
}
- // param 4
- objectrefGetOrCreate(sender);
- if(lua_pcall(L, 4, 0, 0))
- scriptError("error: %s", lua_tostring(L, -1));
+ objectrefGetOrCreate(sender); // player
+ if(lua_pcall(L, 4, 0, errorhandler))
+ scriptError();
+ lua_pop(L, 1); // Pop error handler
}
void ScriptApiNode::node_falling_update(v3s16 p)
{
SCRIPTAPI_PRECHECKHEADER
+
+ lua_pushcfunction(L, script_error_handler);
+ int errorhandler = lua_gettop(L);
+
lua_getglobal(L, "nodeupdate");
push_v3s16(L, p);
- if(lua_pcall(L, 1, 0, 0))
- scriptError("error: %s", lua_tostring(L, -1));
+ if(lua_pcall(L, 1, 0, errorhandler))
+ scriptError();
+ lua_pop(L, 1); // Pop error handler
}
void ScriptApiNode::node_falling_update_single(v3s16 p)
{
SCRIPTAPI_PRECHECKHEADER
+
+ lua_pushcfunction(L, script_error_handler);
+ int errorhandler = lua_gettop(L);
+
lua_getglobal(L, "nodeupdate_single");
push_v3s16(L, p);
- if(lua_pcall(L, 1, 0, 0))
- scriptError("error: %s", lua_tostring(L, -1));
+ if(lua_pcall(L, 1, 0, errorhandler))
+ scriptError();
+ lua_pop(L, 1); // Pop error handler
}
+
diff --git a/src/script/cpp_api/s_nodemeta.cpp b/src/script/cpp_api/s_nodemeta.cpp
index e87464c61..1f04383f1 100644
--- a/src/script/cpp_api/s_nodemeta.cpp
+++ b/src/script/cpp_api/s_nodemeta.cpp
@@ -34,6 +34,9 @@ int ScriptApiNodemeta::nodemeta_inventory_AllowMove(v3s16 p,
{
SCRIPTAPI_PRECHECKHEADER
+ lua_pushcfunction(L, script_error_handler);
+ int errorhandler = lua_gettop(L);
+
INodeDefManager *ndef = getServer()->ndef();
// If node doesn't exist, we don't know what callback to call
@@ -47,25 +50,21 @@ int ScriptApiNodemeta::nodemeta_inventory_AllowMove(v3s16 p,
return count;
// function(pos, from_list, from_index, to_list, to_index, count, player)
- // pos
- push_v3s16(L, p);
- // from_list
- lua_pushstring(L, from_list.c_str());
- // from_index
- lua_pushinteger(L, from_index + 1);
- // to_list
- lua_pushstring(L, to_list.c_str());
- // to_index
- lua_pushinteger(L, to_index + 1);
- // count
- lua_pushinteger(L, count);
- // player
- objectrefGetOrCreate(player);
- if(lua_pcall(L, 7, 1, 0))
- scriptError("error: %s", lua_tostring(L, -1));
+ push_v3s16(L, p); // pos
+ lua_pushstring(L, from_list.c_str()); // from_list
+ lua_pushinteger(L, from_index + 1); // from_index
+ lua_pushstring(L, to_list.c_str()); // to_list
+ lua_pushinteger(L, to_index + 1); // to_index
+ lua_pushinteger(L, count); // count
+ objectrefGetOrCreate(player); // player
+ if(lua_pcall(L, 7, 1, errorhandler))
+ scriptError();
+ lua_remove(L, errorhandler); // Remove error handler
if(!lua_isnumber(L, -1))
throw LuaError(L, "allow_metadata_inventory_move should return a number");
- return luaL_checkinteger(L, -1);
+ int num = luaL_checkinteger(L, -1);
+ lua_pop(L, 1); // Pop integer
+ return num;
}
// Return number of accepted items to be put
@@ -75,6 +74,9 @@ int ScriptApiNodemeta::nodemeta_inventory_AllowPut(v3s16 p,
{
SCRIPTAPI_PRECHECKHEADER
+ lua_pushcfunction(L, script_error_handler);
+ int errorhandler = lua_gettop(L);
+
INodeDefManager *ndef = getServer()->ndef();
// If node doesn't exist, we don't know what callback to call
@@ -88,21 +90,19 @@ int ScriptApiNodemeta::nodemeta_inventory_AllowPut(v3s16 p,
return stack.count;
// Call function(pos, listname, index, stack, player)
- // pos
- push_v3s16(L, p);
- // listname
- lua_pushstring(L, listname.c_str());
- // index
- lua_pushinteger(L, index + 1);
- // stack
- LuaItemStack::create(L, stack);
- // player
- objectrefGetOrCreate(player);
- if(lua_pcall(L, 5, 1, 0))
- scriptError("error: %s", lua_tostring(L, -1));
+ push_v3s16(L, p); // pos
+ lua_pushstring(L, listname.c_str()); // listname
+ lua_pushinteger(L, index + 1); // index
+ LuaItemStack::create(L, stack); // stack
+ objectrefGetOrCreate(player); // player
+ if(lua_pcall(L, 5, 1, errorhandler))
+ scriptError();
+ lua_remove(L, errorhandler); // Remove error handler
if(!lua_isnumber(L, -1))
throw LuaError(L, "allow_metadata_inventory_put should return a number");
- return luaL_checkinteger(L, -1);
+ int num = luaL_checkinteger(L, -1);
+ lua_pop(L, 1); // Pop integer
+ return num;
}
// Return number of accepted items to be taken
@@ -112,6 +112,9 @@ int ScriptApiNodemeta::nodemeta_inventory_AllowTake(v3s16 p,
{
SCRIPTAPI_PRECHECKHEADER
+ lua_pushcfunction(L, script_error_handler);
+ int errorhandler = lua_gettop(L);
+
INodeDefManager *ndef = getServer()->ndef();
// If node doesn't exist, we don't know what callback to call
@@ -125,21 +128,19 @@ int ScriptApiNodemeta::nodemeta_inventory_AllowTake(v3s16 p,
return stack.count;
// Call function(pos, listname, index, count, player)
- // pos
- push_v3s16(L, p);
- // listname
- lua_pushstring(L, listname.c_str());
- // index
- lua_pushinteger(L, index + 1);
- // stack
- LuaItemStack::create(L, stack);
- // player
- objectrefGetOrCreate(player);
- if(lua_pcall(L, 5, 1, 0))
- scriptError("error: %s", lua_tostring(L, -1));
+ push_v3s16(L, p); // pos
+ lua_pushstring(L, listname.c_str()); // listname
+ lua_pushinteger(L, index + 1); // index
+ LuaItemStack::create(L, stack); // stack
+ objectrefGetOrCreate(player); // player
+ if(lua_pcall(L, 5, 1, errorhandler))
+ scriptError();
+ lua_remove(L, errorhandler); // Remove error handler
if(!lua_isnumber(L, -1))
throw LuaError(L, "allow_metadata_inventory_take should return a number");
- return luaL_checkinteger(L, -1);
+ int num = luaL_checkinteger(L, -1);
+ lua_pop(L, 1); // Pop integer
+ return num;
}
// Report moved items
@@ -150,6 +151,9 @@ void ScriptApiNodemeta::nodemeta_inventory_OnMove(v3s16 p,
{
SCRIPTAPI_PRECHECKHEADER
+ lua_pushcfunction(L, script_error_handler);
+ int errorhandler = lua_gettop(L);
+
INodeDefManager *ndef = getServer()->ndef();
// If node doesn't exist, we don't know what callback to call
@@ -163,22 +167,16 @@ void ScriptApiNodemeta::nodemeta_inventory_OnMove(v3s16 p,
return;
// function(pos, from_list, from_index, to_list, to_index, count, player)
- // pos
- push_v3s16(L, p);
- // from_list
- lua_pushstring(L, from_list.c_str());
- // from_index
- lua_pushinteger(L, from_index + 1);
- // to_list
- lua_pushstring(L, to_list.c_str());
- // to_index
- lua_pushinteger(L, to_index + 1);
- // count
- lua_pushinteger(L, count);
- // player
- objectrefGetOrCreate(player);
- if(lua_pcall(L, 7, 0, 0))
- scriptError("error: %s", lua_tostring(L, -1));
+ push_v3s16(L, p); // pos
+ lua_pushstring(L, from_list.c_str()); // from_list
+ lua_pushinteger(L, from_index + 1); // from_index
+ lua_pushstring(L, to_list.c_str()); // to_list
+ lua_pushinteger(L, to_index + 1); // to_index
+ lua_pushinteger(L, count); // count
+ objectrefGetOrCreate(player); // player
+ if(lua_pcall(L, 7, 0, errorhandler))
+ scriptError();
+ lua_pop(L, 1); // Pop error handler
}
// Report put items
@@ -188,6 +186,9 @@ void ScriptApiNodemeta::nodemeta_inventory_OnPut(v3s16 p,
{
SCRIPTAPI_PRECHECKHEADER
+ lua_pushcfunction(L, script_error_handler);
+ int errorhandler = lua_gettop(L);
+
INodeDefManager *ndef = getServer()->ndef();
// If node doesn't exist, we don't know what callback to call
@@ -201,18 +202,14 @@ void ScriptApiNodemeta::nodemeta_inventory_OnPut(v3s16 p,
return;
// Call function(pos, listname, index, stack, player)
- // pos
- push_v3s16(L, p);
- // listname
- lua_pushstring(L, listname.c_str());
- // index
- lua_pushinteger(L, index + 1);
- // stack
- LuaItemStack::create(L, stack);
- // player
- objectrefGetOrCreate(player);
- if(lua_pcall(L, 5, 0, 0))
- scriptError("error: %s", lua_tostring(L, -1));
+ push_v3s16(L, p); // pos
+ lua_pushstring(L, listname.c_str()); // listname
+ lua_pushinteger(L, index + 1); // index
+ LuaItemStack::create(L, stack); // stack
+ objectrefGetOrCreate(player); // player
+ if(lua_pcall(L, 5, 0, errorhandler))
+ scriptError();
+ lua_pop(L, 1); // Pop error handler
}
// Report taken items
@@ -222,6 +219,9 @@ void ScriptApiNodemeta::nodemeta_inventory_OnTake(v3s16 p,
{
SCRIPTAPI_PRECHECKHEADER
+ lua_pushcfunction(L, script_error_handler);
+ int errorhandler = lua_gettop(L);
+
INodeDefManager *ndef = getServer()->ndef();
// If node doesn't exist, we don't know what callback to call
@@ -235,18 +235,14 @@ void ScriptApiNodemeta::nodemeta_inventory_OnTake(v3s16 p,
return;
// Call function(pos, listname, index, stack, player)
- // pos
- push_v3s16(L, p);
- // listname
- lua_pushstring(L, listname.c_str());
- // index
- lua_pushinteger(L, index + 1);
- // stack
- LuaItemStack::create(L, stack);
- // player
- objectrefGetOrCreate(player);
- if(lua_pcall(L, 5, 0, 0))
- scriptError("error: %s", lua_tostring(L, -1));
+ push_v3s16(L, p); // pos
+ lua_pushstring(L, listname.c_str()); // listname
+ lua_pushinteger(L, index + 1); // index
+ LuaItemStack::create(L, stack); // stack
+ objectrefGetOrCreate(player); // player
+ if(lua_pcall(L, 5, 0, errorhandler))
+ scriptError();
+ lua_pop(L, 1); // Pop error handler
}
ScriptApiNodemeta::ScriptApiNodemeta() {
diff --git a/src/script/cpp_api/s_server.cpp b/src/script/cpp_api/s_server.cpp
index d41805b7b..4baf90636 100644
--- a/src/script/cpp_api/s_server.cpp
+++ b/src/script/cpp_api/s_server.cpp
@@ -27,13 +27,18 @@ bool ScriptApiServer::getAuth(const std::string &playername,
{
SCRIPTAPI_PRECHECKHEADER
+ lua_pushcfunction(L, script_error_handler);
+ int errorhandler = lua_gettop(L);
+
getAuthHandler();
lua_getfield(L, -1, "get_auth");
if(lua_type(L, -1) != LUA_TFUNCTION)
throw LuaError(L, "Authentication handler missing get_auth");
lua_pushstring(L, playername.c_str());
- if(lua_pcall(L, 1, 1, 0))
- scriptError("error: %s", lua_tostring(L, -1));
+ if(lua_pcall(L, 1, 1, errorhandler))
+ scriptError();
+ lua_remove(L, -2); // Remove auth handler
+ lua_remove(L, errorhandler); // Remove error handler
// nil = login not allowed
if(lua_isnil(L, -1))
@@ -49,8 +54,7 @@ bool ScriptApiServer::getAuth(const std::string &playername,
lua_getfield(L, -1, "privileges");
if(!lua_istable(L, -1))
- throw LuaError(L,
- "Authentication handler didn't return privilege table");
+ throw LuaError(L, "Authentication handler didn't return privilege table");
if(dst_privs)
readPrivileges(-1, *dst_privs);
lua_pop(L, 1);
@@ -68,6 +72,7 @@ void ScriptApiServer::getAuthHandler()
lua_pop(L, 1);
lua_getfield(L, -1, "builtin_auth_handler");
}
+ lua_remove(L, -2); // Remove minetest
if(lua_type(L, -1) != LUA_TTABLE)
throw LuaError(L, "Authentication handler table not valid");
}
@@ -96,14 +101,19 @@ void ScriptApiServer::createAuth(const std::string &playername,
{
SCRIPTAPI_PRECHECKHEADER
+ lua_pushcfunction(L, script_error_handler);
+ int errorhandler = lua_gettop(L);
+
getAuthHandler();
lua_getfield(L, -1, "create_auth");
+ lua_remove(L, -2); // Remove auth handler
if(lua_type(L, -1) != LUA_TFUNCTION)
throw LuaError(L, "Authentication handler missing create_auth");
lua_pushstring(L, playername.c_str());
lua_pushstring(L, password.c_str());
- if(lua_pcall(L, 2, 0, 0))
- scriptError("error: %s", lua_tostring(L, -1));
+ if(lua_pcall(L, 2, 0, errorhandler))
+ scriptError();
+ lua_pop(L, 1); // Pop error handler
}
bool ScriptApiServer::setPassword(const std::string &playername,
@@ -111,14 +121,19 @@ bool ScriptApiServer::setPassword(const std::string &playername,
{
SCRIPTAPI_PRECHECKHEADER
+ lua_pushcfunction(L, script_error_handler);
+ int errorhandler = lua_gettop(L);
+
getAuthHandler();
lua_getfield(L, -1, "set_password");
+ lua_remove(L, -2); // Remove auth handler
if(lua_type(L, -1) != LUA_TFUNCTION)
throw LuaError(L, "Authentication handler missing set_password");
lua_pushstring(L, playername.c_str());
lua_pushstring(L, password.c_str());
- if(lua_pcall(L, 2, 1, 0))
- scriptError("error: %s", lua_tostring(L, -1));
+ if(lua_pcall(L, 2, 1, errorhandler))
+ scriptError();
+ lua_remove(L, -2); // Remove error handler
return lua_toboolean(L, -1);
}