LuaValueList LuaFunction::call(const LuaValueList& args) {
	int err_idx = 0;
	int stackTop;

	if (_errorFunction) {
		// push the error function
		_errorFunction->pushValue();
		err_idx = lua_gettop(_luaState);
		stackTop = err_idx;
	} else {
		stackTop = lua_gettop(_luaState);
	}

	// Push the function onto the stack
	this->pushValue();

	// Push the arguments onto the stack
	for (LuaValueList::const_iterator iter = args.begin(); iter != args.end(); ++iter) {
		iter->pushValue();
	}

	// actually call the function now!
	int err = lua_pcall(_luaState, (int) args.size(), LUA_MULTRET, err_idx);

	if (!err) {
		int numReturn = lua_gettop(_luaState) - stackTop;
		LuaValueList values;
		values.reserve(numReturn);

		LuaValue val;
		for (int i = 0; i < numReturn; ++i) {
			if (convert::popValue(_luaState, val)) {
				// Add values at the begin as the last return value is on top
				// of the stack.
				values.insert(values.begin(), val);
			}
		}

		if (err_idx != 0) {
			// Remove the error function
			lua_pop(_luaState, 1);
		}

		return values;
	} else {
		// Make sure that there is exactly one parameter left on the stack
		// If the error function didn't return anything then this will push nil
		// If it pushed more than one value then this will discard all of them except the last one
		lua_settop(_luaState, stackTop + 1);

		std::string err_msg;
		if (!lua_isstring(_luaState, -1)) {
			err_msg = "Invalid lua value on stack!";
			lua_pop(_luaState, 1); // Remove the value on the stack
		} else {
			err_msg = convert::popValue<std::string>(_luaState);
		}

		// Throw exception with generated message
		LuaException exception(err_msg);

		if (err_idx != 0) {
			// Pop the error function
			lua_pop(_luaState, 1);
		}

		throw exception;
	}
}
Beispiel #2
0
	LuaValueList LuaFunction::call(const LuaValueList& args)
	{
		int err_idx = 0;
		int stackTop;

		if (errorFunction)
		{
			// push the error function
			errorFunction->pushValue();
			err_idx = lua_gettop(luaState);
			stackTop = err_idx;
		}
		else
		{
			stackTop = lua_gettop(luaState);
		}

		// Push the function onto the stack
		this->pushValue();

		// Push the arguments onto the stack
		for (LuaValueList::const_iterator iter = args.begin(); iter != args.end(); ++iter)
		{
			iter->pushValue();
		}

		// actually call the function now!
		int err = lua_pcall(luaState, args.size(), LUA_MULTRET, err_idx);

		if (!err)
		{
			int numReturn = lua_gettop(luaState) - stackTop;
			LuaValueList values;
			values.reserve(numReturn);

			LuaValue val;
			for (int i = 0; i < numReturn; ++i)
			{
				auto top = lua_gettop(luaState);
				if (convert::popValue(luaState, val))
				{
					top = lua_gettop(luaState);
					// Add values at the begin as the last return value is on top
					// of the stack.
					values.insert(values.begin(), val);
				}
			}

			if (err_idx != 0)
			{
				// Remove the error function
				lua_remove(luaState, err_idx);
			}

			return values;
		}
		else
		{
			// Throw exception with generated message
			LuaException exception(convert::popValue<std::string>(luaState));

			if (err_idx != 0)
			{
				// Pop the error function
				lua_pop(luaState, 1);
			}

			throw exception;
		}
	}