Browse Source

new function `lua_cpcall'

Roberto Ierusalimschy 22 years ago
parent
commit
0bb8eb5151
5 changed files with 105 additions and 41 deletions
  1. 56 2
      lapi.c
  2. 7 24
      ldo.c
  3. 3 2
      ldo.h
  4. 37 12
      lua.c
  5. 2 1
      lua.h

+ 56 - 2
lapi.c

@@ -1,5 +1,5 @@
 /*
-** $Id: lapi.c,v 1.223 2002/11/25 11:16:48 roberto Exp roberto $
+** $Id: lapi.c,v 1.224 2002/11/25 17:50:14 roberto Exp roberto $
 ** Lua API
 ** See Copyright Notice in lua.h
 */
@@ -649,12 +649,66 @@ LUA_API void lua_call (lua_State *L, int nargs, int nresults) {
 }
 
 
+
+/*
+** Execute a protected call.
+*/
+struct CallS {  /* data to `f_call' */
+  StkId func;
+  int nresults;
+};
+
+
+static void f_call (lua_State *L, void *ud) {
+  struct CallS *c = cast(struct CallS *, ud);
+  luaD_call(L, c->func, c->nresults);
+}
+
+
+
 LUA_API int lua_pcall (lua_State *L, int nargs, int nresults, int errfunc) {
+  struct CallS c;
   int status;
   ptrdiff_t func;
   lua_lock(L);
   func = (errfunc == 0) ? 0 : savestack(L, luaA_index(L, errfunc));
-  status = luaD_pcall(L, nargs, nresults, func);
+  c.func = L->top - (nargs+1);  /* function to be called */
+  c.nresults = nresults;
+  status = luaD_pcall(L, &f_call, &c, savestack(L, c.func), func);
+  lua_unlock(L);
+  return status;
+}
+
+
+/*
+** Execute a protected C call.
+*/
+struct CCallS {  /* data to `f_Ccall' */
+  lua_CFunction func;
+  void *ud;
+};
+
+
+static void f_Ccall (lua_State *L, void *ud) {
+  struct CCallS *c = cast(struct CCallS *, ud);
+  Closure *cl;
+  cl = luaF_newCclosure(L, 0);
+  cl->c.f = c->func;
+  setclvalue(L->top, cl);  /* push function */
+  incr_top(L);
+  setpvalue(L->top, c->ud);  /* push only argument */
+  incr_top(L);
+  luaD_call(L, L->top - 2, 0);
+}
+
+
+LUA_API int lua_cpcall (lua_State *L, lua_CFunction func, void *ud) {
+  struct CCallS c;
+  int status;
+  lua_lock(L);
+  c.func = func;
+  c.ud = ud;
+  status = luaD_pcall(L, &f_Ccall, &c, savestack(L, L->top), 0);
   lua_unlock(L);
   return status;
 }

+ 7 - 24
ldo.c

@@ -1,5 +1,5 @@
 /*
-** $Id: ldo.c,v 1.208 2002/11/22 17:16:52 roberto Exp roberto $
+** $Id: ldo.c,v 1.209 2002/11/22 18:01:46 roberto Exp roberto $
 ** Stack and Call structure of Lua
 ** See Copyright Notice in lua.h
 */
@@ -378,35 +378,17 @@ LUA_API int lua_yield (lua_State *L, int nresults) {
 }
 
 
-/*
-** Execute a protected call.
-*/
-struct CallS {  /* data to `f_call' */
-  StkId func;
-  int nresults;
-};
-
-
-static void f_call (lua_State *L, void *ud) {
-  struct CallS *c = cast(struct CallS *, ud);
-  luaD_call(L, c->func, c->nresults);
-}
-
-
-int luaD_pcall (lua_State *L, int nargs, int nresults, ptrdiff_t errfunc) {
-  struct CallS c;
+int luaD_pcall (lua_State *L, Pfunc func, void *u,
+                ptrdiff_t old_top, ptrdiff_t ef) {
   int status;
   unsigned short oldnCcalls = L->nCcalls;
-  ptrdiff_t old_top = savestack(L, L->top);
   ptrdiff_t old_ci = saveci(L, L->ci);
   lu_byte old_allowhooks = L->allowhook;
   ptrdiff_t old_errfunc = L->errfunc;
-  L->errfunc = errfunc;
-  c.func = L->top - (nargs+1);  /* function to be called */
-  c.nresults = nresults;
-  status = luaD_rawrunprotected(L, &f_call, &c);
+  L->errfunc = ef;
+  status = luaD_rawrunprotected(L, func, u);
   if (status != 0) {  /* an error occurred? */
-    StkId oldtop = restorestack(L, old_top) - (nargs+1);
+    StkId oldtop = restorestack(L, old_top);
     luaF_close(L, oldtop);  /* close eventual pending closures */
     seterrorobj(L, status, oldtop);
     L->nCcalls = oldnCcalls;
@@ -420,6 +402,7 @@ int luaD_pcall (lua_State *L, int nargs, int nresults, ptrdiff_t errfunc) {
 }
 
 
+
 /*
 ** Execute a protected parser.
 */

+ 3 - 2
ldo.h

@@ -1,5 +1,5 @@
 /*
-** $Id: ldo.h,v 1.54 2002/11/21 17:19:11 roberto Exp roberto $
+** $Id: ldo.h,v 1.55 2002/11/21 17:41:25 roberto Exp roberto $
 ** Stack and Call structure of Lua
 ** See Copyright Notice in lua.h
 */
@@ -46,7 +46,8 @@ int luaD_protectedparser (lua_State *L, ZIO *z, int bin);
 void luaD_callhook (lua_State *L, int event, int line);
 StkId luaD_precall (lua_State *L, StkId func);
 void luaD_call (lua_State *L, StkId func, int nResults);
-int luaD_pcall (lua_State *L, int nargs, int nresults, ptrdiff_t errfunc);
+int luaD_pcall (lua_State *L, Pfunc func, void *u,
+                ptrdiff_t oldtop, ptrdiff_t ef);
 void luaD_poscall (lua_State *L, int wanted, StkId firstResult);
 void luaD_reallocCI (lua_State *L, int newsize);
 void luaD_reallocstack (lua_State *L, int newsize);

+ 37 - 12
lua.c

@@ -1,5 +1,5 @@
 /*
-** $Id: lua.c,v 1.110 2002/11/25 17:47:13 roberto Exp roberto $
+** $Id: lua.c,v 1.111 2002/12/04 15:38:25 roberto Exp roberto $
 ** Lua stand-alone interpreter
 ** See Copyright Notice in lua.h
 */
@@ -388,19 +388,44 @@ static int handle_luainit (void) {
 }
 
 
-int main (int argc, char *argv[]) {
+struct Smain {
+  int argc;
+  char **argv;
+  int status;
+};
+
+
+static int pmain (lua_State *l) {
+  struct Smain *s = (struct Smain *)lua_touserdata(l, 1);
   int status;
   int interactive = 0;
-  (void)argc;  /* to avoid warnings */
-  progname = argv[0];
-  L = lua_open();  /* create state */
-  lua_atpanic(L, l_panic);
-  lua_userinit(L);  /* open libraries */
+  progname = s->argv[0];
+  L = l;
+  lua_userinit(l);  /* open libraries */
   status = handle_luainit();
-  if (status != 0) return status;
-  status = handle_argv(argv, &interactive);
-  if (status == 0 && interactive) manual_input();
-  lua_close(L);
-  return status;
+  if (status == 0) {
+    status = handle_argv(s->argv, &interactive);
+    if (status == 0 && interactive) manual_input();
+  }
+  s->status = status;
+  return 0;
+}
+
+
+int main (int argc, char *argv[]) {
+  int status;
+  struct Smain s;
+  lua_State *l = lua_open();  /* create state */
+  if (l == NULL) {
+    l_message(argv[0], "cannot create state: not enough memory");
+    return EXIT_FAILURE;
+  }
+  s.argc = argc;
+  s.argv = argv;
+  lua_atpanic(l, l_panic);
+  status = lua_cpcall(l, &pmain, &s);
+  report(status);
+  lua_close(l);
+  return (status || s.status) ? EXIT_FAILURE : EXIT_SUCCESS;
 }
 

+ 2 - 1
lua.h

@@ -1,5 +1,5 @@
 /*
-** $Id: lua.h,v 1.167 2002/11/25 17:50:14 roberto Exp roberto $
+** $Id: lua.h,v 1.168 2002/11/26 12:53:29 roberto Exp roberto $
 ** Lua - An Extensible Extension Language
 ** Tecgraf: Computer Graphics Technology Group, PUC-Rio, Brazil
 ** http://www.lua.org	mailto:[email protected]
@@ -186,6 +186,7 @@ LUA_API int   lua_setglobals (lua_State *L, int idx);
 */
 LUA_API void  lua_call (lua_State *L, int nargs, int nresults);
 LUA_API int   lua_pcall (lua_State *L, int nargs, int nresults, int errfunc);
+LUA_API int lua_cpcall (lua_State *L, lua_CFunction func, void *ud);
 LUA_API int   lua_load (lua_State *L, lua_Chunkreader reader, void *dt,
                         const char *chunkname);