diff options
-rw-r--r-- | apps/plugins/lua/lauxlib.c | 132 |
1 files changed, 132 insertions, 0 deletions
diff --git a/apps/plugins/lua/lauxlib.c b/apps/plugins/lua/lauxlib.c index 5e7c15931d..2e4b3b1e3c 100644 --- a/apps/plugins/lua/lauxlib.c +++ b/apps/plugins/lua/lauxlib.c | |||
@@ -254,10 +254,142 @@ static int libsize_storenames (lua_State *L, const char* libname, const luaL_Reg | |||
254 | } | 254 | } |
255 | 255 | ||
256 | 256 | ||
257 | #if 0 | ||
257 | LUALIB_API void (luaL_register) (lua_State *L, const char *libname, | 258 | LUALIB_API void (luaL_register) (lua_State *L, const char *libname, |
258 | const luaL_Reg *l) { | 259 | const luaL_Reg *l) { |
259 | luaI_openlib(L, libname, l, 0); | 260 | luaI_openlib(L, libname, l, 0); |
260 | } | 261 | } |
262 | #else /* late bind cfunction tables to save ram */ | ||
263 | static int latebind_func_index(lua_State *L) | ||
264 | { | ||
265 | const luaL_Reg *llib; | ||
266 | /* name @ top of stack 1(basetable;name)-1*/ | ||
267 | const char *name = lua_tostring(L, -1); | ||
268 | |||
269 | lua_pushstring (L, "__latebind");/* basetable;name;__latebind;*/ | ||
270 | lua_rawget (L, -3);/* basetable;name;__latebind(t);*/ | ||
271 | |||
272 | luaL_argcheck(L, lua_istable(L, -3) && lua_istable(L, -1), 1, | ||
273 | "__latebind table expected"); | ||
274 | /* (btable;name;__latebind(t)) */ | ||
275 | |||
276 | /* lookup late bound func(s), lua_objlen allows check of multiple luaL_Reg */ | ||
277 | for(int i = lua_objlen(L, -1); i > 0; i--) { | ||
278 | lua_rawgeti (L, -1, i);/* btable;name;__lb(t);llib*/ | ||
279 | llib = (const luaL_Reg *) lua_touserdata (L, -1); | ||
280 | lua_pop(L, 1); /* (btable;name;__lb(t);llib) -> (btable;name;__lb(t)) */ | ||
281 | |||
282 | if(!llib) | ||
283 | continue; | ||
284 | |||
285 | for (; llib->name; llib++) { | ||
286 | if(!name || strcmp(name, llib->name) == 0) { | ||
287 | /* don't overwrite existing keys within basetable */ | ||
288 | lua_pushstring(L, llib->name); /* (btable;name;__lb(t);llib->name) */ | ||
289 | lua_rawget(L, -4); /* (btable;name;__lb(t);btable[func]?) */ | ||
290 | |||
291 | if(lua_isnil(L, -1)) { | ||
292 | /* if function is used it is added to the base table */ | ||
293 | lua_pop(L, 1); | ||
294 | lua_pushcclosure(L, llib->func, 0); /* (btable;name;__lb(t);llib->func) */ | ||
295 | } | ||
296 | |||
297 | if(!name) /* nil name binds all functions in table immediately */ | ||
298 | lua_setfield(L, -4, llib->name); /* (btable;name;mtable) */ | ||
299 | else { | ||
300 | lua_pushvalue(L, -1); /* dupe closure or existing func */ | ||
301 | /* (btable;name;__lb(t);llib->func;llib->func) */ | ||
302 | lua_setfield(L, -5, llib->name); /* (btable;name;__lb(t);llib->func) */ | ||
303 | /* returns the closure */ | ||
304 | return 1; | ||
305 | } | ||
306 | } | ||
307 | } | ||
308 | } | ||
309 | |||
310 | lua_pop(L, 2); /* (btable;name;__lb(t)) -> (btable) */ | ||
311 | if(!name) { | ||
312 | lua_pushnil(L); /* remove metatable (btable;name;__lb(t);nil)*/ | ||
313 | lua_setmetatable(L, -2); | ||
314 | lua_pushnil(L); /* remove __latebind table*/ | ||
315 | lua_setfield (L, -2, "__latebind"); | ||
316 | } | ||
317 | |||
318 | return 0; | ||
319 | } | ||
320 | |||
321 | |||
322 | static int latebind_func_pairs(lua_State *L) | ||
323 | { | ||
324 | /* basetable @ top of stack 1(basetable)-1 */ | ||
325 | luaL_argcheck(L, lua_istable(L, 1), 1, "table expected"); | ||
326 | lua_getglobal(L, "pairs"); /* function to be called / returned (btable;pairs) */ | ||
327 | |||
328 | lua_createtable(L, 0, 15); /* btable;pairs;newtable; */ | ||
329 | /* clone base table */ | ||
330 | lua_pushnil(L); /* first key */ | ||
331 | while(lua_next(L, 1) != 0) { | ||
332 | /* (btable;pairs;ntable;k;v) */ | ||
333 | lua_pushvalue(L, -2); /* dupe key Stk = (..;k;v -> ..k;v;k)*/ | ||
334 | lua_insert(L, -2); /* Stk = (..k;k;v) */ | ||
335 | lua_rawset(L, 3); /* btable;pairs;ntable;k */ | ||
336 | } | ||
337 | |||
338 | lua_pushnil(L); /*nil name retrieves all unbound late bound functions */ | ||
339 | latebind_func_index(L);/* (btable;pairs;ntable;nil) -> (btable;pairs;ntable) */ | ||
340 | |||
341 | /* (btable;pairs;ntable) */ | ||
342 | lua_call(L, 1, 3); /* pairs(ntable) -> (btable;iter;state;value) */ | ||
343 | |||
344 | return 3; | ||
345 | } | ||
346 | |||
347 | |||
348 | LUALIB_API void (luaL_register) (lua_State *L, const char *libname, | ||
349 | const luaL_Reg *l) { | ||
350 | if(!libname) | ||
351 | { | ||
352 | /* if there is no libname register normally */ | ||
353 | luaI_openlib(L, libname, l, 0); | ||
354 | return; | ||
355 | } | ||
356 | |||
357 | /* store empty table instead of passed luaL_Reg table */ | ||
358 | static const struct luaL_reg late_lib [] = | ||
359 | { | ||
360 | {NULL, NULL} | ||
361 | }; | ||
362 | |||
363 | static const struct luaL_reg late_meta [] = | ||
364 | { | ||
365 | {"__index", latebind_func_index}, | ||
366 | {"__pairs", latebind_func_pairs}, | ||
367 | {"__call", latebind_func_index}, /* allows t("func") -- nil binds all */ | ||
368 | {NULL, NULL} | ||
369 | }; | ||
370 | |||
371 | libsize_storenames(L, libname, l); /* store func names */ | ||
372 | luaI_openlib(L, libname, late_lib, 0); /* basetable; */ | ||
373 | |||
374 | luaL_findtable(L, -1,"__latebind", 0); /* create table if doesn't exist */ | ||
375 | /* basetable;__latebind(t); */ | ||
376 | /* save pointer to real luaL_reg */ | ||
377 | lua_pushlightuserdata (L, (void *) l); /*basetable;__lb(t);userdata;*/ | ||
378 | lua_rawseti(L, -2, lua_objlen(L, -2) + 1); /*lb(t)[n] = userdata */ | ||
379 | |||
380 | lua_pop(L, 1);/* (basetable;__latebind(t)) -> (basetable) */ | ||
381 | |||
382 | if(luaL_newmetatable(L, "META_LATEBIND")) | ||
383 | { | ||
384 | luaI_openlib(L, NULL, late_meta, 0); /*basetable;metatable*/ | ||
385 | lua_pushvalue(L, -1); /* dupe the metatable (basetable;mt;mt) */ | ||
386 | lua_setfield (L, -2, "__metatable"); /* metatable[__metatable] = metatable */ | ||
387 | } | ||
388 | |||
389 | lua_setmetatable(L, -2); /* (basetable;mt) -> (basetable+mtable) */ | ||
390 | /* base table is top of stack (basetable) */ | ||
391 | } | ||
392 | #endif | ||
261 | 393 | ||
262 | #if 0 | 394 | #if 0 |
263 | static int libsize (const luaL_Reg *l) { | 395 | static int libsize (const luaL_Reg *l) { |