[Date Prev][Date Next][Thread Prev][Thread Next]
[Date Index]
[Thread Index]
- Subject: Some lua-5.0.2 patches, and PlayStation2 binary distrib.
- From: Nicolas Noble <pixel@...>
- Date: Sun, 02 Jan 2005 07:44:36 +0100
Hello all,
First, I'd like to tell you that I compiled lua-5.0.2 for "homebrew"
on PlayStation2 and gave out a binary distribution of it on the
ps2dev.net website. I also added a link at the lua-wiki in the binary
distributions page (http://lua-users.org/wiki/LuaBinaries). This is not
a 100% vanilla lua, since I've added another mathlib which is only using
some float functions (that is, cosf, sinf, etc...) instead of doubles.
That way, the host program is able to either let the normal luamath go
(and then, produce slowness when calling math function) or have a #ifdef
around it so that when run from ps2, it would call the mathlibf. I also
compiled that distribution with a USE_FLOAT in the config, since the PS2
can't really handle doubles (its cop1 only handles floats). I have to
say this package is completely untested :) But I honestly think it
should run: the ps2sdk we are hosting is now quite mature and shouldn't
produce problems in the lua's core. Some poeple should give that package
a shoot really soon (tm), but I think people over here have better ideas
about how to conduct tests for lua.
Second, I created some patches I'd like to submit here. There are two
of them, quite independant. I've attached them within that mail.
The first one is to add a "CallWrap", when lua is calling a C closure.
That way, if the host program want to, a callback is called to wrap the
closure. For example, one usage is, when using C++, encapsulating that
call into a try{...} catch{ lua_error(...) } block. That's what I am
doing with this patch, but I can sense other operations with it, such as
creating a sandbox. I know that one solution to get around that would be
to register the wrapper as the actual C closure, but since I am handling
kindof "plugins", I can't control the way they are registering their
closures into the Lua state. So this is for me a nice solution.
The second patch is to implement a "user_break". I am actually having
a console where the user can interactively enter lua code. Problem is,
if the user enters an infinite loop, there are quite no good method to
"break" the actual lua longrun, and return from there. At least, I've
tried several methods, and none worked correctly for me. So, now, I am
having this patch, and a line hook. The line hook checks a certain
semaphore into my interface that tells if the user has done a user break
(like hitting a button in the interface or whatever) then it calls
lua_break(). Afterward, when the line hook returns, after the core
checks if the hook yield, it also check if the hook did a break. Maybe
there should be other positions where this break check should be done
(maybe, around each hook, or more generally, after each callback) but I
am not sure... Anyway: if this check matches, the code throws an error,
thus returning nicely to an idle state, allowing my user to continue
working with something else. I remember that one of my test was to do
the lua_error directly inside the line hook. I think that was not
successful, but I can't remember the exact reason.
Cheers,
-- Nicolas Noble.
diff -ur lua-5.0.2/include/lua.h lua-5.0.2-userbreak/include/lua.h
--- lua-5.0.2/include/lua.h Sun Jan 2 06:07:21 2005
+++ lua-5.0.2-userbreak/include/lua.h Sun Jan 2 06:10:13 2005
@@ -219,6 +219,8 @@
LUA_API void lua_concat (lua_State *L, int n);
+LUA_API void lua_break (lua_State *L);
+
/*
diff -ur lua-5.0.2/src/ldo.c lua-5.0.2-userbreak/src/ldo.c
--- lua-5.0.2/src/ldo.c Sun Jan 2 06:07:21 2005
+++ lua-5.0.2-userbreak/src/ldo.c Sun Jan 2 06:10:13 2005
@@ -404,6 +404,13 @@
return -1;
}
+LUA_API void lua_break (lua_State *L) {
+ CallInfo * ci;
+ lua_lock(L);
+ ci = L->ci;
+ ci->state |= CI_BREAK;
+ lua_unlock(L);
+}
int luaD_pcall (lua_State *L, Pfunc func, void *u,
ptrdiff_t old_top, ptrdiff_t ef) {
diff -ur lua-5.0.2/src/lstate.h lua-5.0.2-userbreak/src/lstate.h
--- lua-5.0.2/src/lstate.h Sun Jan 2 06:07:21 2005
+++ lua-5.0.2-userbreak/src/lstate.h Sun Jan 2 06:10:13 2005
@@ -100,6 +100,7 @@
#define CI_CALLING (1<<2)
#define CI_SAVEDPC (1<<3) /* 1 if `savedpc' is updated */
#define CI_YIELD (1<<4) /* 1 if thread is suspended */
+#define CI_BREAK (1<<5) /* 1 if user break */
#define ci_func(ci) (clvalue((ci)->base - 1))
diff -ur lua-5.0.2/src/lvm.c lua-5.0.2-userbreak/src/lvm.c
--- lua-5.0.2/src/lvm.c Sun Jan 2 06:07:21 2005
+++ lua-5.0.2-userbreak/src/lvm.c Sun Jan 2 06:10:13 2005
@@ -423,6 +423,10 @@
L->ci->state = CI_YIELD | CI_SAVEDPC;
return NULL;
}
+ if (L->ci->state & CI_BREAK) { /* did hook break? */
+ luaG_runerror(L, "breaking");
+ L->ci->state &= ~CI_BREAK;
+ }
}
/* warning!! several calls may realloc the stack and invalidate `ra' */
base = L->base;
diff -ur lua-5.0.2/include/lua.h lua-5.0.2-callwrap/include/lua.h
--- lua-5.0.2/include/lua.h Sun Jan 2 06:07:21 2005
+++ lua-5.0.2-callwrap/include/lua.h Sun Jan 2 06:10:01 2005
@@ -330,6 +330,7 @@
typedef struct lua_Debug lua_Debug; /* activation record */
typedef void (*lua_Hook) (lua_State *L, lua_Debug *ar);
+typedef int (*lua_CallWrap) (lua_State *L, lua_CFunction func);
LUA_API int lua_getstack (lua_State *L, int level, lua_Debug *ar);
@@ -343,6 +344,8 @@
LUA_API lua_Hook lua_gethook (lua_State *L);
LUA_API int lua_gethookmask (lua_State *L);
LUA_API int lua_gethookcount (lua_State *L);
+
+LUA_API lua_CallWrap lua_setcallwrap (lua_State *L, lua_CallWrap func);
#define LUA_IDSIZE 60
diff -ur lua-5.0.2/src/ldebug.c lua-5.0.2-callwrap/src/ldebug.c
--- lua-5.0.2/src/ldebug.c Sun Jan 2 06:07:21 2005
+++ lua-5.0.2-callwrap/src/ldebug.c Sun Jan 2 06:10:01 2005
@@ -91,6 +91,16 @@
}
+LUA_API lua_CallWrap lua_setcallwrap (lua_State *L, lua_CallWrap func) {
+ lua_CallWrap old_func;
+ lua_lock(L);
+ old_func = L->callwrap;
+ L->callwrap = func;
+ lua_unlock(L);
+ return old_func;
+}
+
+
LUA_API int lua_getstack (lua_State *L, int level, lua_Debug *ar) {
int status;
CallInfo *ci;
diff -ur lua-5.0.2/src/ldo.c lua-5.0.2-callwrap/src/ldo.c
--- lua-5.0.2/src/ldo.c Sun Jan 2 06:07:21 2005
+++ lua-5.0.2-callwrap/src/ldo.c Sun Jan 2 06:10:01 2005
@@ -257,7 +257,11 @@
#ifdef LUA_COMPATUPVALUES
lua_pushupvalues(L);
#endif
- n = (*clvalue(L->base - 1)->c.f)(L); /* do the actual call */
+ if (L->callwrap) {
+ n = L->callwrap(L, clvalue(L->base - 1)->c.f); /* wrap the call */
+ } else {
+ n = (*clvalue(L->base - 1)->c.f)(L); /* do the actual call */
+ }
lua_lock(L);
return L->top - n;
}
diff -ur lua-5.0.2/src/lstate.c lua-5.0.2-callwrap/src/lstate.c
--- lua-5.0.2/src/lstate.c Sun Jan 2 06:07:21 2005
+++ lua-5.0.2-callwrap/src/lstate.c Sun Jan 2 06:10:01 2005
@@ -137,6 +137,7 @@
L->nCcalls = 0;
L->base_ci = L->ci = NULL;
L->errfunc = 0;
+ L->callwrap = 0;
setnilvalue(gt(L));
}
diff -ur lua-5.0.2/src/lstate.h lua-5.0.2-callwrap/src/lstate.h
--- lua-5.0.2/src/lstate.h Sun Jan 2 06:07:21 2005
+++ lua-5.0.2-callwrap/src/lstate.h Sun Jan 2 06:10:01 2005
@@ -152,6 +152,7 @@
GCObject *gclist;
struct lua_longjmp *errorJmp; /* current error recover point */
ptrdiff_t errfunc; /* current error handling function (stack index) */
+ lua_CallWrap callwrap;
};