Use LuaJIT when available; add LuaBitOp for bitop accel; remove sackit hack thanks to new API; enforce C99 support in CMake (#250)

* default to LuaJIT when available

* add LuaBitOp for efficient bitwise operations in Lua

* make lib_bits use LuaBitOp if present

* add LuaBitOp licence notice

* fix CMake to work with LuaJIT/LuaBitOp, enforce C99
This commit is contained in:
Adrian Siekierka 2016-09-30 08:23:34 +02:00 committed by GitHub
parent 64e9121086
commit 8153b68d46
11 changed files with 297 additions and 29 deletions

View File

@ -25,7 +25,13 @@ endif ()
find_package(ENet REQUIRED)
find_package(SDL2 REQUIRED)
find_package(ZLIB REQUIRED)
find_package(Lua REQUIRED)
find_package(LuaJIT)
if (LUAJIT_FOUND)
add_definitions(-DUSE_LUAJIT)
set(LUA_LIBRARIES ${LUA_LIBRARY} m)
else ()
find_package(Lua REQUIRED)
endif ()
find_package(sackit REQUIRED)
find_package(OpenGL REQUIRED)
@ -37,7 +43,7 @@ include_directories(
${LUA_INCLUDE_DIR}
)
file(GLOB LUA_FILES src/lua*)
file(GLOB LUA_FILES src/lua* src/external/bit.c)
set(MAIN_FILES
src/dsp.c
src/img.c
@ -66,10 +72,12 @@ source_group(lua FILES ${LUA_FILES})
# iceball target
add_executable(iceball ${MAIN_FILES} ${LUA_FILES} ${GL_FILES})
target_link_libraries(iceball ${CMAKE_DL_LIBS} ${ENet_LIBRARIES} ${ZLIB_LIBRARIES} ${sackit_LIBRARY} ${LUA_LIBRARIES} ${SDL2_LIBRARIES} ${OPENGL_LIBRARIES})
set_target_properties(iceball PROPERTIES C_STANDARD 99)
# iceball-dedi target
add_executable(iceball-dedi EXCLUDE_FROM_ALL ${MAIN_FILES} ${LUA_FILES})
target_link_libraries(iceball-dedi ${CMAKE_DL_LIBS} ${ENet_LIBRARIES} ${ZLIB_LIBRARIES} ${LUA_LIBRARIES} ${SDL_LIBRARY})
set_target_properties(iceball-dedi PROPERTIES C_STANDARD 99)
set_target_properties(iceball-dedi PROPERTIES COMPILE_DEFINITIONS "DEDI")
function(copy_run_dep arg1)

23
LICENCE-others.txt Normal file
View File

@ -0,0 +1,23 @@
Iceball includes source code of Lua BitOp, a bit operations library for
Lua 5.1/5.2 - http://bitop.luajit.org/.
Copyright (C) 2008-2012 Mike Pall. All rights reserved.
Permission is hereby granted, free of charge, to any person obtaining
a copy of this software and associated documentation files (the
"Software"), to deal in the Software without restriction, including
without limitation the rights to use, copy, modify, merge, publish,
distribute, sublicense, and/or sell copies of the Software, and to
permit persons to whom the Software is furnished to do so, subject to
the following conditions:
The above copyright notice and this permission notice shall be
included in all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.

View File

@ -40,6 +40,9 @@ Ice Lua Components contains some content from libSDL,
which is licensed under the LGPL version 2.1.
It is marked accordingly.
Code in src/external is licensed under their respective licenses,
which are listed in LICENCE-others.txt.
The manual is in the public domain, except where otherwise specified.
Copyright (C) 2012-2015, Iceball contributors

50
cmake/FindLuaJIT.cmake Normal file
View File

@ -0,0 +1,50 @@
# Locate LuaJIT library
# This module defines
# LUAJIT_FOUND, if false, do not try to link to Lua
# LUA_INCLUDE_DIR, where to find lua.h
# LUA_VERSION_STRING, the version of Lua found (since CMake 2.8.8)
#
# This module is similar to FindLua51.cmake except that it finds LuaJit instead.
FIND_PATH(LUA_INCLUDE_DIR luajit.h
HINTS
$ENV{LUA_DIR}
PATH_SUFFIXES include/luajit-2.0 include/luajit-5_1-2.0 include
PATHS
~/Library/Frameworks
/Library/Frameworks
/sw # Fink
/opt/local # DarwinPorts
/opt/csw # Blastwave
/opt
)
FIND_LIBRARY(LUA_LIBRARY
NAMES luajit-5.1
HINTS
$ENV{LUA_DIR}
PATH_SUFFIXES lib64 lib
PATHS
~/Library/Frameworks
/Library/Frameworks
/sw
/opt/local
/opt/csw
/opt
)
IF(LUA_INCLUDE_DIR AND EXISTS "${LUA_INCLUDE_DIR}/luajit.h")
FILE(STRINGS "${LUA_INCLUDE_DIR}/luajit.h" lua_version_str REGEX "^#define[ \t]+LUA_RELEASE[ \t]+\"LuaJIT .+\"")
STRING(REGEX REPLACE "^#define[ \t]+LUA_RELEASE[ \t]+\"LuaJIT ([^\"]+)\".*" "\\1" LUA_VERSION_STRING "${lua_version_str}")
UNSET(lua_version_str)
ENDIF()
INCLUDE(FindPackageHandleStandardArgs)
# handle the QUIETLY and REQUIRED arguments and set LUAJIT_FOUND to TRUE if
# all listed variables are TRUE
FIND_PACKAGE_HANDLE_STANDARD_ARGS(LuaJit
REQUIRED_VARS LUA_LIBRARY LUA_INCLUDE_DIR
VERSION_VAR LUA_VERSION_STRING)
MARK_AS_ADVANCED(LUA_INCLUDE_DIR LUA_LIBRARY LUA_MATH_LIBRARY)

View File

@ -3,7 +3,9 @@
# Because EVERY DISTRO JUST HAS TO INSIST ON DOING IT DIFFERENTLY
# IT'S LIKE THESE MORONS DON'T KNOW WHAT STANDARDS ARE
if pkg-config lua-5.1 ; then
if pkg-config luajit ; then
pkg-config luajit $@
elif pkg-config lua-5.1 ; then
# FreeBSD
pkg-config lua-5.1 $@
elif pkg-config lua5.1 ; then

View File

@ -754,3 +754,5 @@ int wav_init(void);
void wav_deinit(void);
#endif
// external/bit.c
extern int luaopen_bit(lua_State *L);

View File

@ -21,7 +21,8 @@ OBJS = \
$(OBJDIR)/lua.o $(OBJDIR)/network.o \
$(OBJDIR)/path.o $(OBJDIR)/json.o \
$(OBJDIR)/random.o \
$(OBJDIR)/wav.o
$(OBJDIR)/wav.o \
$(OBJDIR)/external/bit.o
# TODO: make the renderer part not depend on, say, render_img.o
@ -36,7 +37,10 @@ $(OBJDIR):
$(OBJDIR)/$(RENDERER):
mkdir -p $(OBJDIR)/$(RENDERER)
$(BINNAME): $(OBJDIR) $(OBJDIR)/$(RENDERER) $(OBJS)
$(OBJDIR)/external:
mkdir -p $(OBJDIR)/external
$(BINNAME): $(OBJDIR) $(OBJDIR)/$(RENDERER) $(OBJDIR)/external $(OBJS)
$(CC) -o $(BINNAME) $(LDFLAGS) $(OBJS) $(LIBS)
$(OBJDIR)/lua.o: $(SRCDIR)/lua.c $(SRCDIR)/lua_*.h $(INCLUDES)

View File

@ -65,3 +65,9 @@ function bit_and(a,b)
end
return v
end
if bit then
bit_xor = bit.bxor
bit_or = bit.bor
bit_and = bit.band
end

189
src/external/bit.c vendored Normal file
View File

@ -0,0 +1,189 @@
/*
** Lua BitOp -- a bit operations library for Lua 5.1/5.2.
** http://bitop.luajit.org/
**
** Copyright (C) 2008-2012 Mike Pall. All rights reserved.
**
** Permission is hereby granted, free of charge, to any person obtaining
** a copy of this software and associated documentation files (the
** "Software"), to deal in the Software without restriction, including
** without limitation the rights to use, copy, modify, merge, publish,
** distribute, sublicense, and/or sell copies of the Software, and to
** permit persons to whom the Software is furnished to do so, subject to
** the following conditions:
**
** The above copyright notice and this permission notice shall be
** included in all copies or substantial portions of the Software.
**
** THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
** EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
** MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
** IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
** CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
** TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
** SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
**
** [ MIT license: http://www.opensource.org/licenses/mit-license.php ]
*/
#define LUA_BITOP_VERSION "1.0.2"
#define LUA_LIB
#include "lua.h"
#include "lauxlib.h"
#ifdef _MSC_VER
/* MSVC is stuck in the last century and doesn't have C99's stdint.h. */
typedef __int32 int32_t;
typedef unsigned __int32 uint32_t;
typedef unsigned __int64 uint64_t;
#else
#include <stdint.h>
#endif
typedef int32_t SBits;
typedef uint32_t UBits;
typedef union {
lua_Number n;
#ifdef LUA_NUMBER_DOUBLE
uint64_t b;
#else
UBits b;
#endif
} BitNum;
/* Convert argument to bit type. */
static UBits barg(lua_State *L, int idx)
{
BitNum bn;
UBits b;
#if LUA_VERSION_NUM < 502
bn.n = lua_tonumber(L, idx);
#else
bn.n = luaL_checknumber(L, idx);
#endif
#if defined(LUA_NUMBER_DOUBLE)
bn.n += 6755399441055744.0; /* 2^52+2^51 */
#ifdef SWAPPED_DOUBLE
b = (UBits)(bn.b >> 32);
#else
b = (UBits)bn.b;
#endif
#elif defined(LUA_NUMBER_INT) || defined(LUA_NUMBER_LONG) || \
defined(LUA_NUMBER_LONGLONG) || defined(LUA_NUMBER_LONG_LONG) || \
defined(LUA_NUMBER_LLONG)
if (sizeof(UBits) == sizeof(lua_Number))
b = bn.b;
else
b = (UBits)(SBits)bn.n;
#elif defined(LUA_NUMBER_FLOAT)
#error "A 'float' lua_Number type is incompatible with this library"
#else
#error "Unknown number type, check LUA_NUMBER_* in luaconf.h"
#endif
#if LUA_VERSION_NUM < 502
if (b == 0 && !lua_isnumber(L, idx)) {
luaL_typerror(L, idx, "number");
}
#endif
return b;
}
/* Return bit type. */
#define BRET(b) lua_pushnumber(L, (lua_Number)(SBits)(b)); return 1;
static int bit_tobit(lua_State *L) { BRET(barg(L, 1)) }
static int bit_bnot(lua_State *L) { BRET(~barg(L, 1)) }
#define BIT_OP(func, opr) \
static int func(lua_State *L) { int i; UBits b = barg(L, 1); \
for (i = lua_gettop(L); i > 1; i--) b opr barg(L, i); BRET(b) }
BIT_OP(bit_band, &=)
BIT_OP(bit_bor, |=)
BIT_OP(bit_bxor, ^=)
#define bshl(b, n) (b << n)
#define bshr(b, n) (b >> n)
#define bsar(b, n) ((SBits)b >> n)
#define brol(b, n) ((b << n) | (b >> (32-n)))
#define bror(b, n) ((b << (32-n)) | (b >> n))
#define BIT_SH(func, fn) \
static int func(lua_State *L) { \
UBits b = barg(L, 1); UBits n = barg(L, 2) & 31; BRET(fn(b, n)) }
BIT_SH(bit_lshift, bshl)
BIT_SH(bit_rshift, bshr)
BIT_SH(bit_arshift, bsar)
BIT_SH(bit_rol, brol)
BIT_SH(bit_ror, bror)
static int bit_bswap(lua_State *L)
{
UBits b = barg(L, 1);
b = (b >> 24) | ((b >> 8) & 0xff00) | ((b & 0xff00) << 8) | (b << 24);
BRET(b)
}
static int bit_tohex(lua_State *L)
{
UBits b = barg(L, 1);
SBits n = lua_isnone(L, 2) ? 8 : (SBits)barg(L, 2);
const char *hexdigits = "0123456789abcdef";
char buf[8];
int i;
if (n < 0) { n = -n; hexdigits = "0123456789ABCDEF"; }
if (n > 8) n = 8;
for (i = (int)n; --i >= 0; ) { buf[i] = hexdigits[b & 15]; b >>= 4; }
lua_pushlstring(L, buf, (size_t)n);
return 1;
}
static const struct luaL_Reg bit_funcs[] = {
{ "tobit", bit_tobit },
{ "bnot", bit_bnot },
{ "band", bit_band },
{ "bor", bit_bor },
{ "bxor", bit_bxor },
{ "lshift", bit_lshift },
{ "rshift", bit_rshift },
{ "arshift", bit_arshift },
{ "rol", bit_rol },
{ "ror", bit_ror },
{ "bswap", bit_bswap },
{ "tohex", bit_tohex },
{ NULL, NULL }
};
/* Signed right-shifts are implementation-defined per C89/C99.
** But the de facto standard are arithmetic right-shifts on two's
** complement CPUs. This behaviour is required here, so test for it.
*/
#define BAD_SAR (bsar(-8, 2) != (SBits)-2)
LUALIB_API int luaopen_bit(lua_State *L)
{
UBits b;
lua_pushnumber(L, (lua_Number)1437217655L);
b = barg(L, -1);
if (b != (UBits)1437217655L || BAD_SAR) { /* Perform a simple self-test. */
const char *msg = "compiled with incompatible luaconf.h";
#ifdef LUA_NUMBER_DOUBLE
#ifdef _WIN32
if (b == (UBits)1610612736L)
msg = "use D3DCREATE_FPU_PRESERVE with DirectX";
#endif
if (b == (UBits)1127743488L)
msg = "not compiled with SWAPPED_DOUBLE";
#endif
if (BAD_SAR)
msg = "arithmetic right-shift broken";
luaL_error(L, "bit library self-test failed (%s)", msg);
}
#if LUA_VERSION_NUM < 502
luaL_register(L, "bit", bit_funcs);
#else
luaL_newlib(L, bit_funcs);
#endif
return 1;
}

View File

@ -39,9 +39,7 @@ int whitelist_validate(const char *name, int port)
if(name == NULL || port == 0 || port == -1)
return 0;
int i;
for(i = 0; i < raw_whitelist_len; i++)
for(int i = 0; i < raw_whitelist_len; i++)
if(!strcmp(raw_whitelist[i].addr, name) && (raw_whitelist[i].port == -1 || port == raw_whitelist[i].port))
return 1;
@ -374,6 +372,9 @@ void icelua_loadbasefuncs(lua_State *L)
lua_pushcfunction(L, luaopen_table);
lua_call(L, 0, 0);
// additional libraries
luaopen_bit(L);
// overwrite dofile/loadfile.
lua_pushcfunction(L, icelua_fn_base_loadfile);
lua_setglobal(L, "loadfile");

View File

@ -354,25 +354,7 @@ int icelua_fn_common_fetch_poll(lua_State *L)
lua_pushlstring(L, to_client_local.cfetch_ubuf, to_client_local.cfetch_ulen);
ret = 1;
#else
// create temp file (sackit doesn't support loading from memory, at least right now)
// "Never use this function." i have no other choice
char *tfname = tempnam(NULL, "ibsit");
if(tfname == NULL)
{
ret = 0;
break;
}
FILE *fp = fopen(tfname, "wb");
if(fp == NULL)
{
ret = 0;
free(tfname);
break;
}
fwrite(to_client_local.cfetch_ubuf, to_client_local.cfetch_ulen, 1, fp);
fclose(fp);
it_module_t *mus = sackit_module_load(tfname);
it_module_t *mus = sackit_module_load_memory(to_client_local.cfetch_ubuf, to_client_local.cfetch_ulen);
if(mus == NULL)
{
ret = 0;
@ -380,8 +362,6 @@ int icelua_fn_common_fetch_poll(lua_State *L)
ret = 1;
lua_pushlightuserdata(L, mus);
}
free(tfname);
#endif
} break;