view C++/Luae.cpp @ 226:24501d428db3

Luae: clean up and add comments
author David Demelier <markand@malikania.fr>
date Fri, 09 May 2014 17:44:36 +0200
parents e01ee0c72c43
children
line wrap: on
line source

/*
 * Luae.cpp -- Lua helpers and such
 *
 * Copyright (c) 2013, 2014 David Demelier <markand@malikania.fr>
 *
 * Permission to use, copy, modify, and/or distribute this software for any
 * purpose with or without fee is hereby granted, provided that the above
 * copyright notice and this permission notice appear in all copies.
 *
 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
 */

#include "Luae.h"

void Luae::doexecute(lua_State *L, int status)
{
	if (status != LUA_OK) {
		auto error = lua_tostring(L, -1);
		lua_pop(L, 1);

		throw std::runtime_error(error);
	}
}

void Luae::assertBegin(lua_State *L)
{
#if !defined(NDEBUG)
	lua_pushinteger(L, lua_gettop(L));
	lua_setfield(L, LUA_REGISTRYINDEX, FieldTop);
#endif
}

void Luae::assertEnd(lua_State *L, int expected)
{
#if !defined(NDEBUG)
	lua_getfield(L, LUA_REGISTRYINDEX, FieldTop);
	if (lua_type(L, -1) == LUA_TNIL)
		luaL_error(L, "stack verification without top field, call assertBegin");
		// NOTREACHED

	auto before = lua_tointeger(L, -1);
	lua_pop(L, 1);

	if (before != (gettop(L) - expected))
		luaL_error(L, "stack size error: expected %d, got %d", expected, gettop(L) - before);
		// NOTREACHED

	lua_pushnil(L);
	lua_setfield(L, LUA_REGISTRYINDEX, FieldTop);
#endif
}

void Luae::preload(lua_State *L, const std::string &name, lua_CFunction func)
{
	assertBegin(L);

	lua_getglobal(L, "package");
	lua_getfield(L, -1, "preload");
	lua_pushcfunction(L, func);
	lua_setfield(L, -2, name.c_str());
	lua_pop(L, 2);

	assertEnd(L, 0);
}

void Luae::require(lua_State *L, const std::string &name, lua_CFunction func)
{
	assertBegin(L);

	luaL_requiref(L, name.c_str(), func, false);
	lua_pop(L, 1);

	assertEnd(L, 0);
}

void *operator new(size_t size, lua_State *L)
{
	return lua_newuserdata(L, size);
}

void *operator new(size_t size, lua_State *L, const char *metaname)
{
	void *object;

	object = lua_newuserdata(L, size);
	luaL_setmetatable(L, metaname);

	return object;
}

void operator delete(void *, lua_State *)
{
}

void operator delete(void *, lua_State *L, const char *)
{
	lua_pushnil(L);
	lua_setmetatable(L, -2);
}