Support Lua 5.2, 5.3, 5.4;

This commit is contained in:
bjorn 2020-08-19 13:12:06 -06:00
parent f364fe030b
commit ec257b179f
20 changed files with 74 additions and 38 deletions

View File

@ -68,7 +68,7 @@ void _luax_registertype(lua_State* L, const char* name, const luaL_Reg* function
// Register class functions
if (functions) {
luaL_register(L, NULL, functions);
luax_register(L, functions);
}
// :release function
@ -93,12 +93,25 @@ void* _luax_checktype(lua_State* L, int index, uint64_t hash, const char* debug)
void* object = _luax_totype(L, index, hash);
if (!object) {
luaL_typerror(L, index, debug);
luax_typeerror(L, index, debug);
}
return object;
}
int luax_typeerror(lua_State* L, int index, const char* expected) {
const char* name;
if (luaL_getmetafield(L, index, "__name") == LUA_TSTRING) {
name = lua_tostring(L, -1);
} else if (lua_type(L, index) == LUA_TLIGHTUSERDATA) {
name = "light userdata";
} else {
name = luaL_typename(L, index);
}
const char* message = lua_pushfstring(L, "%s expected, got %s", name, expected);
return luaL_argerror(L, index, message);
}
// Registers the userdata on the top of the stack in the registry.
void _luax_pushtype(lua_State* L, const char* type, uint64_t hash, void* object) {
if (!object) {
@ -175,16 +188,33 @@ void luax_registerloader(lua_State* L, lua_CFunction loader, int index) {
lua_getglobal(L, "table");
lua_getfield(L, -1, "insert");
lua_getglobal(L, "package");
#if LUA_VERSION_NUM == 501
lua_getfield(L, -1, "loaders");
#else
lua_getfield(L, -1, "searchers");
#endif
lua_remove(L, -2);
if (lua_istable(L, -1)) {
lua_pushinteger(L, index);
lua_pushcfunction(L, loader);
lua_call(L, 3, 0);
} else {
lua_pop(L, 2);
}
lua_pop(L, 1);
}
int luax_resume(lua_State* T, int n) {
#if LUA_VERSION_NUM >= 504
int results;
return lua_resume(T, NULL, n, &results);
#elif LUA_VERSION_NUM >= 502
return lua_resume(T, NULL, n);
#else
return lua_resume(T, n);
#endif
}
void luax_vthrow(void* context, const char* format, va_list args) {
lua_State* L = (lua_State*) context;
lua_pushvfstring(L, format, args);

View File

@ -107,11 +107,15 @@ typedef struct {
void* object;
} Proxy;
#ifndef LUA_RIDX_MAINTHERAD
#if LUA_VERSION_NUM > 501
#define luax_len(L, i) (int) lua_rawlen(L, i)
#define luax_register(L, f) luaL_setfuncs(L, f, 0)
#else
#define luax_len(L, i) (int) lua_objlen(L, i)
#define luax_register(L, f) luaL_register(L, NULL, f)
#define LUA_RIDX_MAINTHREAD 1
#endif
#define luax_len(L, i) (int) lua_objlen(L, i)
#define luax_registertype(L, T) _luax_registertype(L, #T, lovr ## T, lovr ## T ## Destroy)
#define luax_totype(L, i, T) (T*) _luax_totype(L, i, hash64(#T, strlen(#T)))
#define luax_checktype(L, i, T) (T*) _luax_checktype(L, i, hash64(#T, strlen(#T)), #T)
@ -126,9 +130,11 @@ typedef struct {
void _luax_registertype(lua_State* L, const char* name, const luaL_Reg* functions, void (*destructor)(void*));
void* _luax_totype(lua_State* L, int index, uint64_t hash);
void* _luax_checktype(lua_State* L, int index, uint64_t hash, const char* debug);
int luax_typeerror(lua_State* L, int index, const char* expected);
void _luax_pushtype(lua_State* L, const char* name, uint64_t hash, void* object);
int luax_checkenum(lua_State* L, int index, const StringEntry* map, const char* fallback, const char* label);
void luax_registerloader(lua_State* L, lua_CFunction loader, int index);
int luax_resume(lua_State* T, int n);
void luax_vthrow(void* L, const char* format, va_list args);
void luax_vlog(void* context, int level, const char* tag, const char* format, va_list args);
void luax_traceback(lua_State* L, lua_State* T, const char* message, int level);

View File

@ -237,7 +237,7 @@ static const luaL_Reg lovrAudio[] = {
int luaopen_lovr_audio(lua_State* L) {
lua_newtable(L);
luaL_register(L, NULL, lovrAudio);
luax_register(L, lovrAudio);
luax_registertype(L, Microphone);
luax_registertype(L, Source);
if (lovrAudioInit()) {

View File

@ -150,7 +150,7 @@ static const luaL_Reg lovrData[] = {
int luaopen_lovr_data(lua_State* L) {
lua_newtable(L);
luaL_register(L, NULL, lovrData);
luax_register(L, lovrData);
luax_registertype(L, Blob);
luax_registertype(L, AudioStream);
luax_registertype(L, ModelData);

View File

@ -272,7 +272,7 @@ static int l_lovrEventPush(lua_State* L) {
static int l_lovrEventQuit(lua_State* L) {
EventData data;
data.quit.exitCode = luaL_optint(L, 1, 0);
data.quit.exitCode = luaL_optinteger(L, 1, 0);
EventType type = EVENT_QUIT;
Event event = { .type = type, .data = data };
@ -299,7 +299,7 @@ static const luaL_Reg lovrEvent[] = {
int luaopen_lovr_event(lua_State* L) {
lua_newtable(L);
luaL_register(L, NULL, lovrEvent);
luax_register(L, lovrEvent);
// Store nextEvent in the registry to avoid creating a closure every time we poll for events.
lua_pushcfunction(L, nextEvent);

View File

@ -490,7 +490,7 @@ int luaopen_lovr_filesystem(lua_State* L) {
}
lua_newtable(L);
luaL_register(L, NULL, lovrFilesystem);
luax_register(L, lovrFilesystem);
luax_registerloader(L, luaLoader, 2);
luax_registerloader(L, libLoader, 3);
return 1;

View File

@ -1734,7 +1734,7 @@ static const luaL_Reg lovrGraphics[] = {
int luaopen_lovr_graphics(lua_State* L) {
lua_newtable(L);
luaL_register(L, NULL, lovrGraphics);
luax_register(L, lovrGraphics);
luax_registertype(L, Canvas);
luax_registertype(L, Font);
luax_registertype(L, Material);

View File

@ -305,7 +305,7 @@ static int l_lovrMeshSetVertices(lua_State* L) {
}
luaL_checktype(L, 2, LUA_TTABLE);
count = MIN(count, lua_objlen(L, 2));
count = MIN(count, (uint32_t) luax_len(L, 2));
lovrAssert(start + count <= capacity, "Overflow in Mesh:setVertices: Mesh can only hold %d vertices", capacity);
AttributeData data = { .raw = lovrBufferMap(buffer, start * stride, false) };

View File

@ -15,7 +15,7 @@ static uint32_t luax_checkanimation(lua_State* L, int index, Model* model) {
return (uint32_t) animationIndex;
}
case LUA_TNUMBER: return lua_tointeger(L, index) - 1;
default: return luaL_typerror(L, index, "number or string");
default: return luax_typeerror(L, index, "number or string");
}
}
@ -59,7 +59,7 @@ static int l_lovrModelPose(lua_State* L) {
break;
}
default:
return luaL_typerror(L, 2, "nil, number, or string");
return luax_typeerror(L, 2, "nil, number, or string");
}
int index = 3;
@ -89,7 +89,7 @@ static int l_lovrModelGetMaterial(lua_State* L) {
break;
}
default:
return luaL_typerror(L, 2, "nil, number, or string");
return luax_typeerror(L, 2, "nil, number, or string");
}
luax_pushtype(L, Material, lovrModelGetMaterial(model, material));
@ -123,7 +123,7 @@ static int l_lovrModelGetNodePose(lua_State* L) {
break;
}
default:
return luaL_typerror(L, 2, "number or string");
return luax_typeerror(L, 2, "number or string");
}
float position[4], rotation[4], angle, ax, ay, az;

View File

@ -710,7 +710,7 @@ static const luaL_Reg lovrHeadset[] = {
int luaopen_lovr_headset(lua_State* L) {
lua_newtable(L);
luaL_register(L, NULL, lovrHeadset);
luax_register(L, lovrHeadset);
luax_pushconf(L);
lua_getfield(L, -1, "headset");

View File

@ -66,6 +66,6 @@ static const luaL_Reg lovr[] = {
LOVR_EXPORT int luaopen_lovr(lua_State* L) {
lua_newtable(L);
luaL_register(L, NULL, lovr);
luax_register(L, lovr);
return 1;
}

View File

@ -74,7 +74,7 @@ float* luax_tovector(lua_State* L, int index, VectorType* type) {
float* luax_checkvector(lua_State* L, int index, VectorType type, const char* expected) {
VectorType t;
float* p = luax_tovector(L, index, &t);
if (!p || t != type) luaL_typerror(L, index, expected ? expected : lovrVectorTypeNames[type]);
if (!p || t != type) luax_typeerror(L, index, expected ? expected : lovrVectorTypeNames[type]);
return p;
}
@ -345,7 +345,7 @@ static int l_lovrLightUserdataOp(lua_State* L) {
int luaopen_lovr_math(lua_State* L) {
lua_newtable(L);
luaL_register(L, NULL, lovrMath);
luax_register(L, lovrMath);
luax_registertype(L, Curve);
luax_registertype(L, RandomGenerator);
@ -353,7 +353,7 @@ int luaopen_lovr_math(lua_State* L) {
lua_newtable(L);
lua_pushstring(L, lovrVectorTypeNames[i]);
lua_setfield(L, -2, "__name");
luaL_register(L, NULL, lovrVectorMetatables[i]);
luax_register(L, lovrVectorMetatables[i]);
lovrVectorMetatableRefs[i] = luaL_ref(L, LUA_REGISTRYINDEX);
}

View File

@ -495,7 +495,7 @@ int l_lovrVec3Set(lua_State* L) {
} else if (p && t == V_MAT4) {
vec3_set(v, p[12], p[13], p[14]);
} else{
luaL_typerror(L, 2, "vec3, mat4, or number");
luax_typeerror(L, 2, "vec3, mat4, or number");
}
}
lua_settop(L, 1);
@ -1257,7 +1257,7 @@ int l_lovrQuatSet(lua_State* L) {
} else {
VectorType type;
float* p = luax_tovector(L, 2, &type);
if (!p) return luaL_typerror(L, 2, "vec3, quat, or number");
if (!p) return luax_typeerror(L, 2, "vec3, quat, or number");
if (type == V_VEC3) {
if (lua_gettop(L) > 2) {
@ -1271,7 +1271,7 @@ int l_lovrQuatSet(lua_State* L) {
} else if (type == V_MAT4) {
quat_fromMat4(q, p);
} else {
return luaL_typerror(L, 2, "vec3, quat, mat4, or number");
return luax_typeerror(L, 2, "vec3, quat, mat4, or number");
}
}
lua_settop(L, 1);
@ -1282,7 +1282,7 @@ static int l_lovrQuatMul(lua_State* L) {
quat q = luax_checkvector(L, 1, V_QUAT, NULL);
VectorType type;
float* r = luax_tovector(L, 2, &type);
if (!r || (type != V_VEC3 && type != V_QUAT)) return luaL_typerror(L, 2, "quat or vec3");
if (!r || (type != V_VEC3 && type != V_QUAT)) return luax_typeerror(L, 2, "quat or vec3");
if (type == V_VEC3) {
quat_rotate(q, r);
lua_settop(L, 2);
@ -1333,7 +1333,7 @@ static int l_lovrQuat__mul(lua_State* L) {
quat q = luax_checkvector(L, 1, V_QUAT, NULL);
VectorType type;
float* r = luax_tovector(L, 2, &type);
if (!r) return luaL_typerror(L, 2, "quat or vec3");
if (!r) return luax_typeerror(L, 2, "quat or vec3");
if (type == V_VEC3) {
vec3 out = luax_newtempvector(L, V_VEC3);
quat_rotate(q, vec3_init(out, r));
@ -1546,7 +1546,7 @@ static int l_lovrMat4Mul(lua_State* L) {
lua_pushnumber(L, v[2]);
return 3;
} else {
return luaL_typerror(L, 2, "mat4, vec3, or number");
return luax_typeerror(L, 2, "mat4, vec3, or number");
}
}
@ -1659,7 +1659,7 @@ static int l_lovrMat4__mul(lua_State* L) {
mat4 m = luax_checkvector(L, 1, V_MAT4, NULL);
VectorType type;
float* n = luax_tovector(L, 2, &type);
if (!n || (type == V_VEC2 || type == V_QUAT)) return luaL_typerror(L, 2, "mat4, vec3, or vec4");
if (!n || (type == V_VEC2 || type == V_QUAT)) return luax_typeerror(L, 2, "mat4, vec3, or vec4");
if (type == V_MAT4) {
mat4 out = luax_newtempvector(L, V_MAT4);
mat4_multiply(mat4_init(out, m), n);

View File

@ -142,7 +142,7 @@ static const luaL_Reg lovrPhysics[] = {
int luaopen_lovr_physics(lua_State* L) {
lua_newtable(L);
luaL_register(L, NULL, lovrPhysics);
luax_register(L, lovrPhysics);
luax_registertype(L, World);
luax_registertype(L, Collider);
luax_registertype(L, BallJoint);

View File

@ -29,7 +29,7 @@ Joint* luax_checkjoint(lua_State* L, int index) {
}
}
luaL_typerror(L, index, "Joint");
luax_typeerror(L, index, "Joint");
return NULL;
}

View File

@ -29,7 +29,7 @@ Shape* luax_checkshape(lua_State* L, int index) {
}
}
luaL_typerror(L, index, "Shape");
luax_typeerror(L, index, "Shape");
return NULL;
}

View File

@ -20,7 +20,7 @@ static int threadRunner(void* data) {
lua_getglobal(L, "package");
lua_getfield(L, -1, "preload");
luaL_register(L, NULL, lovrModules);
luax_register(L, lovrModules);
lua_pop(L, 2);
if (!luaL_loadbuffer(L, thread->body->data, thread->body->size, "thread")) {
@ -98,7 +98,7 @@ static const luaL_Reg lovrThreadModule[] = {
int luaopen_lovr_thread(lua_State* L) {
lua_newtable(L);
luaL_register(L, NULL, lovrThreadModule);
luax_register(L, lovrThreadModule);
luax_registertype(L, Thread);
luax_registertype(L, Channel);
if (lovrThreadModuleInit()) {

View File

@ -44,7 +44,7 @@ static const luaL_Reg lovrTimer[] = {
int luaopen_lovr_timer(lua_State* L) {
lua_newtable(L);
luaL_register(L, NULL, lovrTimer);
luax_register(L, lovrTimer);
if (lovrTimerInit()) {
luax_atexit(L, lovrTimerDestroy);
}

View File

@ -35,7 +35,7 @@ static void emscriptenLoop(void* arg) {
luax_geterror(T);
luax_clearerror(T);
if (lua_resume(T, 1) != LUA_YIELD) {
if (luax_resume(T, 1) != LUA_YIELD) {
bool restart = lua_type(T, -1) == LUA_TSTRING && !strcmp(lua_tostring(T, -1), "restart");
int status = lua_tonumber(T, -1);
@ -138,7 +138,7 @@ int main(int argc, char** argv) {
lua_getglobal(L, "package");
lua_getfield(L, -1, "preload");
luaL_register(L, NULL, lovrModules);
luax_register(L, lovrModules);
lua_pop(L, 2);
lua_pushcfunction(L, luax_getstack);
@ -160,7 +160,7 @@ int main(int argc, char** argv) {
return 0;
#endif
while (lua_resume(T, 0) == LUA_YIELD) {
while (luax_resume(T, 0) == LUA_YIELD) {
lovrPlatformSleep(0.);
}

View File

@ -453,7 +453,7 @@ static void lovrPicoBoot(void) {
lua_getglobal(L, "package");
lua_getfield(L, -1, "preload");
luaL_register(L, NULL, lovrModules);
luax_register(L, lovrModules);
lua_pop(L, 2);
lua_pushcfunction(L, luax_getstack);
@ -520,7 +520,7 @@ JNIEXPORT void JNICALL Java_org_lovr_app_Activity_lovrPicoOnFrame(JNIEnv* jni, j
if (L && T) {
luax_geterror(T);
luax_clearerror(T);
if (lua_resume(T, 1) != LUA_YIELD) {
if (luax_resume(T, 1) != LUA_YIELD) {
bool restart = lua_type(T, 1) == LUA_TSTRING && !strcmp(lua_tostring(T, 1), "restart");
if (restart) {
luax_checkvariant(T, 2, &cookie);