summaryrefslogtreecommitdiff
path: root/ldo.c
diff options
context:
space:
mode:
authorRoberto Ierusalimschy <roberto@inf.puc-rio.br>2001-12-20 13:13:38 -0200
committerRoberto Ierusalimschy <roberto@inf.puc-rio.br>2001-12-20 13:13:38 -0200
commit18afb90349fc1b698d179e29fdc014589c2e1145 (patch)
tree0ebee0d47aa91ce4bdf580baa2e5639c361c9a9a /ldo.c
parent22dd271cbba22c0765eb45296a957ecacf68755e (diff)
downloadlua-github-18afb90349fc1b698d179e29fdc014589c2e1145.tar.gz
first version of stackless Lua
Diffstat (limited to 'ldo.c')
-rw-r--r--ldo.c119
1 files changed, 72 insertions, 47 deletions
diff --git a/ldo.c b/ldo.c
index e46f84a3..ae70d268 100644
--- a/ldo.c
+++ b/ldo.c
@@ -43,8 +43,15 @@ void luaD_init (lua_State *L, int stacksize) {
stacksize += EXTRA_STACK;
L->stack = luaM_newvector(L, stacksize, TObject);
L->stacksize = stacksize;
- L->top = L->basefunc.base = L->stack + RESERVED_STACK_PREFIX;
+ L->top = L->stack + RESERVED_STACK_PREFIX;
restore_stack_limit(L);
+ luaM_reallocvector(L, L->base_ci, 0, 20, CallInfo);
+ L->ci = L->base_ci;
+ L->ci->base = L->top;
+ L->ci->savedpc = NULL;
+ L->ci->pc = NULL;
+ L->size_ci = 20;
+ L->end_ci = L->base_ci + L->size_ci;
}
@@ -98,35 +105,81 @@ void luaD_lineHook (lua_State *L, int line, lua_Hook linehook) {
if (L->allowhooks) {
lua_Debug ar;
ar.event = "line";
- ar._ci = L->ci;
+ ar._ci = L->ci - L->base_ci;
ar.currentline = line;
dohook(L, &ar, linehook);
}
}
-static void luaD_callHook (lua_State *L, lua_Hook callhook,
- const char *event) {
+void luaD_callHook (lua_State *L, lua_Hook callhook, const char *event) {
if (L->allowhooks) {
lua_Debug ar;
ar.event = event;
- ar._ci = L->ci;
- L->ci->pc = NULL; /* function is not active */
+ ar._ci = L->ci - L->base_ci;
dohook(L, &ar, callhook);
}
}
-static StkId callCclosure (lua_State *L, const struct CClosure *cl) {
+#define newci(L) ((++L->ci == L->end_ci) ? growci(L) : L->ci)
+
+static CallInfo *growci (lua_State *L) {
+ lua_assert(L->ci == L->end_ci);
+ luaM_reallocvector(L, L->base_ci, L->size_ci, 2*L->size_ci, CallInfo);
+ L->ci = L->base_ci + L->size_ci;
+ L->size_ci *= 2;
+ L->end_ci = L->base_ci + L->size_ci;
+ return L->ci;
+}
+
+
+StkId luaD_precall (lua_State *L, StkId func) {
+ CallInfo *ci;
int n;
+ if (ttype(func) != LUA_TFUNCTION) {
+ /* `func' is not a function; check the `function' tag method */
+ const TObject *tm = luaT_gettmbyobj(L, func, TM_CALL);
+ if (ttype(tm) != LUA_TFUNCTION)
+ luaG_typeerror(L, func, "call");
+ luaD_openstack(L, func);
+ setobj(func, tm); /* tag method is the new function to be called */
+ }
+ lua_assert(ttype(func) == LUA_TFUNCTION);
+ ci = newci(L);
+ ci->base = func+1;
+ ci->savedpc = NULL;
+ ci->pc = NULL;
+ if (L->callhook)
+ luaD_callHook(L, L->callhook, "call");
+ if (!clvalue(func)->c.isC) return NULL;
+ /* if is a C function, call it */
luaD_checkstack(L, LUA_MINSTACK); /* ensure minimum stack size */
lua_unlock(L);
#if LUA_COMPATUPVALUES
lua_pushupvalues(L);
#endif
- n = (*cl->f)(L); /* do the actual call */
+ n = (*clvalue(func)->c.f)(L); /* do the actual call */
lua_lock(L);
- return L->top - n; /* return index of first result */
+ return L->top - n;
+}
+
+
+void luaD_poscall (lua_State *L, int wanted, StkId firstResult) {
+ StkId res;
+ if (L->callhook)
+ luaD_callHook(L, L->callhook, "return");
+ res = L->ci->base - 1; /* `func' = final position of 1st result */
+ L->ci--;
+ /* move results to correct place */
+ while (wanted != 0 && firstResult < L->top) {
+ setobj(res++, firstResult++);
+ wanted--;
+ }
+ while (wanted-- > 0)
+ setnilvalue(res++);
+ L->top = res;
+ luaC_checkGC(L);
}
@@ -136,36 +189,11 @@ static StkId callCclosure (lua_State *L, const struct CClosure *cl) {
** When returns, all the results are on the stack, starting at the original
** function position.
*/
-void luaD_call (lua_State *L, StkId func) {
- lua_Hook callhook;
- StkId firstResult;
- CallInfo ci;
- if (ttype(func) != LUA_TFUNCTION) {
- /* `func' is not a function; check the `function' tag method */
- const TObject *tm = luaT_gettmbyobj(L, func, TM_CALL);
- if (ttype(tm) != LUA_TFUNCTION)
- luaG_typeerror(L, func, "call");
- luaD_openstack(L, func);
- setobj(func, tm); /* tag method is the new function to be called */
- }
- lua_assert(ttype(func) == LUA_TFUNCTION);
- ci.prev = L->ci; /* chain new callinfo */
- L->ci = &ci;
- ci.base = func+1;
- callhook = L->callhook;
- if (callhook)
- luaD_callHook(L, callhook, "call");
- firstResult = (clvalue(func)->c.isC ?
- callCclosure(L, &clvalue(func)->c) :
- luaV_execute(L, &clvalue(func)->l, func+1));
- if (callhook) /* same hook that was active at entry */
- luaD_callHook(L, callhook, "return");
- L->ci = ci.prev; /* unchain callinfo */
- /* move results to `func' (to erase parameters and function) */
- while (firstResult < L->top)
- setobj(func++, firstResult++);
- L->top = func;
- luaC_checkGC(L);
+void luaD_call (lua_State *L, StkId func, int nResults) {
+ StkId firstResult = luaD_precall(L, func);
+ if (firstResult == NULL) /* is a Lua function? */
+ firstResult = luaV_execute(L, &clvalue(func)->l, func+1); /* call it */
+ luaD_poscall(L, nResults, firstResult);
}
@@ -179,9 +207,7 @@ struct CallS { /* data to `f_call' */
static void f_call (lua_State *L, void *ud) {
struct CallS *c = cast(struct CallS *, ud);
- luaD_call(L, c->func);
- if (c->nresults != LUA_MULTRET)
- luaD_adjusttop(L, c->func + c->nresults);
+ luaD_call(L, c->func, c->nresults);
}
@@ -291,7 +317,7 @@ struct lua_longjmp {
jmp_buf b;
struct lua_longjmp *previous;
volatile int status; /* error code */
- CallInfo *ci; /* call info of active function that set protection */
+ int ci; /* index of call info of active function that set protection */
StkId top; /* top stack when protection was set */
int allowhooks; /* `allowhook' state when protection was set */
};
@@ -307,8 +333,7 @@ static void message (lua_State *L, const char *s) {
incr_top;
setsvalue(top+1, luaS_new(L, s));
incr_top;
- luaD_call(L, top);
- L->top = top;
+ luaD_call(L, top, 0);
}
}
@@ -337,7 +362,7 @@ void luaD_breakrun (lua_State *L, int errcode) {
int luaD_runprotected (lua_State *L, void (*f)(lua_State *, void *), void *ud) {
struct lua_longjmp lj;
- lj.ci = L->ci;
+ lj.ci = L->ci - L->base_ci;
lj.top = L->top;
lj.allowhooks = L->allowhooks;
lj.status = 0;
@@ -346,7 +371,7 @@ int luaD_runprotected (lua_State *L, void (*f)(lua_State *, void *), void *ud) {
if (setjmp(lj.b) == 0)
(*f)(L, ud);
else { /* an error occurred: restore the state */
- L->ci = lj.ci;
+ L->ci = L->base_ci + lj.ci;
L->top = lj.top;
L->allowhooks = lj.allowhooks;
restore_stack_limit(L);