diff options
| author | Roberto Ierusalimschy <roberto@inf.puc-rio.br> | 2002-01-25 20:14:54 -0200 |
|---|---|---|
| committer | Roberto Ierusalimschy <roberto@inf.puc-rio.br> | 2002-01-25 20:14:54 -0200 |
| commit | 50e29525936be4891f9db090f293432913b5f7c0 (patch) | |
| tree | 8e487b87f82761e15cd096ac345354f57f38fedc /ldo.c | |
| parent | b217ae644e3a83def93be2fe742e2cd0970e1a5f (diff) | |
| download | lua-50e29525936be4891f9db090f293432913b5f7c0.tar.gz lua-50e29525936be4891f9db090f293432913b5f7c0.tar.bz2 lua-50e29525936be4891f9db090f293432913b5f7c0.zip | |
first version of dynamic stack
Diffstat (limited to 'ldo.c')
| -rw-r--r-- | ldo.c | 215 |
1 files changed, 132 insertions, 83 deletions
| @@ -30,22 +30,72 @@ | |||
| 30 | 30 | ||
| 31 | 31 | ||
| 32 | 32 | ||
| 33 | /* chain list of long jump buffers */ | ||
| 34 | struct lua_longjmp { | ||
| 35 | jmp_buf b; | ||
| 36 | struct lua_longjmp *previous; | ||
| 37 | CallInfo *ci; /* index of call info of active function that set protection */ | ||
| 38 | StkId top; /* top stack when protection was set */ | ||
| 39 | TObject *stack; /* active stack for this entry */ | ||
| 40 | int allowhooks; /* `allowhook' state when protection was set */ | ||
| 41 | volatile int status; /* error code */ | ||
| 42 | }; | ||
| 43 | |||
| 44 | |||
| 45 | static void correctstack (lua_State *L, TObject *oldstack) { | ||
| 46 | struct lua_longjmp *lj; | ||
| 47 | CallInfo *ci; | ||
| 48 | UpVal *up; | ||
| 49 | L->top = (L->top - oldstack) + L->stack; | ||
| 50 | for (lj = L->errorJmp; lj && lj->stack == oldstack; lj = lj->previous) { | ||
| 51 | lj->top = (lj->top - oldstack) + L->stack; | ||
| 52 | lj->stack = L->stack; | ||
| 53 | } | ||
| 54 | for (up = L->openupval; up != NULL; up = up->next) | ||
| 55 | up->v = (up->v - oldstack) + L->stack; | ||
| 56 | for (ci = L->base_ci; ci <= L->ci; ci++) { | ||
| 57 | ci->base = (ci->base - oldstack) + L->stack; | ||
| 58 | ci->top = (ci->top - oldstack) + L->stack; | ||
| 59 | if (ci->pc) { /* entry is of an active Lua function? */ | ||
| 60 | if (ci->pc != (ci-1)->pc) | ||
| 61 | *ci->pb = (*ci->pb - oldstack) + L->stack; | ||
| 62 | } | ||
| 63 | } | ||
| 64 | } | ||
| 65 | |||
| 66 | |||
| 67 | void luaD_reallocstack (lua_State *L, int newsize) { | ||
| 68 | TObject *oldstack = L->stack; | ||
| 69 | luaM_reallocvector(L, L->stack, L->stacksize, newsize, TObject); | ||
| 70 | L->stacksize = newsize; | ||
| 71 | L->stack_last = L->stack+(newsize-EXTRA_STACK)-1; | ||
| 72 | correctstack(L, oldstack); | ||
| 73 | } | ||
| 74 | |||
| 75 | |||
| 33 | static void restore_stack_limit (lua_State *L) { | 76 | static void restore_stack_limit (lua_State *L) { |
| 34 | StkId limit = L->stack+(L->stacksize-EXTRA_STACK)-1; | 77 | if (L->stacksize > L->maxstacksize) { /* there was an overflow? */ |
| 35 | if (L->top < limit) | 78 | int inuse = (L->top - L->stack); |
| 36 | L->stack_last = limit; | 79 | if (inuse + MAXSTACK < L->maxstacksize) /* can `undo' overflow? */ |
| 80 | luaD_reallocstack(L, L->maxstacksize); | ||
| 81 | } | ||
| 37 | } | 82 | } |
| 38 | 83 | ||
| 39 | 84 | ||
| 40 | void luaD_stackerror (lua_State *L) { | 85 | void luaD_growstack (lua_State *L, int n) { |
| 41 | if (L->stack_last == L->stack+L->stacksize-1) { | 86 | if (L->stacksize > L->maxstacksize) { /* overflow while handling overflow? */ |
| 42 | /* overflow while handling overflow */ | ||
| 43 | luaD_breakrun(L, LUA_ERRERR); /* break run without error message */ | 87 | luaD_breakrun(L, LUA_ERRERR); /* break run without error message */ |
| 44 | } | 88 | } |
| 45 | else { | 89 | else { |
| 46 | L->stack_last += EXTRA_STACK; /* to be used by error message */ | 90 | if (n <= L->stacksize && 2*L->stacksize < L->maxstacksize) /* can double? */ |
| 47 | lua_assert(L->stack_last == L->stack+L->stacksize-1); | 91 | luaD_reallocstack(L, 2*L->stacksize); |
| 48 | luaD_error(L, "stack overflow"); | 92 | else if (L->stacksize+n <= L->maxstacksize) /* no overflow? */ |
| 93 | luaD_reallocstack(L, L->maxstacksize); | ||
| 94 | else { | ||
| 95 | /* resize to maximum + some extra space to handle error */ | ||
| 96 | luaD_reallocstack(L, L->maxstacksize+4*LUA_MINSTACK); | ||
| 97 | luaD_error(L, "stack overflow"); | ||
| 98 | } | ||
| 49 | } | 99 | } |
| 50 | } | 100 | } |
| 51 | 101 | ||
| @@ -56,12 +106,12 @@ void luaD_stackerror (lua_State *L) { | |||
| 56 | static void luaD_openstack (lua_State *L, StkId pos) { | 106 | static void luaD_openstack (lua_State *L, StkId pos) { |
| 57 | int i = L->top-pos; | 107 | int i = L->top-pos; |
| 58 | while (i--) setobj(pos+i+1, pos+i); | 108 | while (i--) setobj(pos+i+1, pos+i); |
| 59 | incr_top; | 109 | incr_top(L); |
| 60 | } | 110 | } |
| 61 | 111 | ||
| 62 | 112 | ||
| 63 | static void dohook (lua_State *L, lua_Debug *ar, lua_Hook hook) { | 113 | static void dohook (lua_State *L, lua_Debug *ar, lua_Hook hook) { |
| 64 | StkId old_top = L->top; | 114 | L->ci->top = L->top; |
| 65 | luaD_checkstack(L, LUA_MINSTACK); /* ensure minimum stack size */ | 115 | luaD_checkstack(L, LUA_MINSTACK); /* ensure minimum stack size */ |
| 66 | L->allowhooks = 0; /* cannot call hooks inside a hook */ | 116 | L->allowhooks = 0; /* cannot call hooks inside a hook */ |
| 67 | lua_unlock(L); | 117 | lua_unlock(L); |
| @@ -69,7 +119,7 @@ static void dohook (lua_State *L, lua_Debug *ar, lua_Hook hook) { | |||
| 69 | lua_lock(L); | 119 | lua_lock(L); |
| 70 | lua_assert(L->allowhooks == 0); | 120 | lua_assert(L->allowhooks == 0); |
| 71 | L->allowhooks = 1; | 121 | L->allowhooks = 1; |
| 72 | L->top = old_top; | 122 | L->top = L->ci->top; |
| 73 | } | 123 | } |
| 74 | 124 | ||
| 75 | 125 | ||
| @@ -95,66 +145,82 @@ void luaD_callHook (lua_State *L, lua_Hook callhook, const char *event) { | |||
| 95 | } | 145 | } |
| 96 | 146 | ||
| 97 | 147 | ||
| 98 | static CallInfo *growci (lua_State *L) { | 148 | static void correctCI (lua_State *L, CallInfo *oldci) { |
| 99 | lua_assert(L->ci == L->end_ci); | 149 | struct lua_longjmp *lj; |
| 100 | luaM_reallocvector(L, L->base_ci, L->size_ci, 2*L->size_ci, CallInfo); | 150 | for (lj = L->errorJmp; lj && lj->stack == L->stack; lj = lj->previous) { |
| 101 | L->ci = L->base_ci + L->size_ci; | 151 | lj->ci = (lj->ci - oldci) + L->base_ci; |
| 102 | L->size_ci *= 2; | 152 | } |
| 103 | L->end_ci = L->base_ci + L->size_ci; | ||
| 104 | return L->ci; | ||
| 105 | } | 153 | } |
| 106 | 154 | ||
| 107 | 155 | ||
| 108 | static void adjust_varargs (lua_State *L, StkId base, int nfixargs) { | 156 | void luaD_reallocCI (lua_State *L, int newsize) { |
| 157 | CallInfo *oldci = L->base_ci; | ||
| 158 | luaM_reallocvector(L, L->base_ci, L->size_ci, newsize, CallInfo); | ||
| 159 | L->size_ci = newsize; | ||
| 160 | if (oldci != L->ci) { | ||
| 161 | L->ci = (L->ci - oldci) + L->base_ci; | ||
| 162 | L->end_ci = L->base_ci + L->size_ci; | ||
| 163 | correctCI(L, oldci); | ||
| 164 | } | ||
| 165 | } | ||
| 166 | |||
| 167 | |||
| 168 | static void adjust_varargs (lua_State *L, int nfixargs) { | ||
| 109 | int i; | 169 | int i; |
| 110 | Table *htab; | 170 | Table *htab; |
| 111 | TObject n, nname; | 171 | TObject n, nname; |
| 112 | StkId firstvar = base + nfixargs; /* position of first vararg */ | 172 | int actual = L->top - L->ci->base; /* actual number of arguments */ |
| 113 | if (L->top < firstvar) { | 173 | if (actual < nfixargs) { |
| 114 | luaD_checkstack(L, firstvar - L->top); | 174 | luaD_checkstack(L, nfixargs - actual); |
| 115 | while (L->top < firstvar) | 175 | for (; actual < nfixargs; ++actual) |
| 116 | setnilvalue(L->top++); | 176 | setnilvalue(L->top++); |
| 117 | } | 177 | } |
| 118 | htab = luaH_new(L, 0, 0); | 178 | actual -= nfixargs; /* number of extra arguments */ |
| 119 | for (i=0; firstvar+i<L->top; i++) | 179 | htab = luaH_new(L, 0, 0); /* create `arg' table */ |
| 120 | luaH_setnum(L, htab, i+1, firstvar+i); | 180 | for (i=0; i<actual; i++) /* put extra arguments into `arg' table */ |
| 181 | luaH_setnum(L, htab, i+1, L->top - actual + i); | ||
| 121 | /* store counter in field `n' */ | 182 | /* store counter in field `n' */ |
| 122 | setnvalue(&n, i); | 183 | setnvalue(&n, actual); |
| 123 | setsvalue(&nname, luaS_newliteral(L, "n")); | 184 | setsvalue(&nname, luaS_newliteral(L, "n")); |
| 124 | luaH_set(L, htab, &nname, &n); | 185 | luaH_set(L, htab, &nname, &n); |
| 125 | L->top = firstvar; /* remove elements from the stack */ | 186 | L->top -= actual; /* remove extra elements from the stack */ |
| 126 | sethvalue(L->top, htab); | 187 | sethvalue(L->top, htab); |
| 127 | incr_top; | 188 | incr_top(L); |
| 128 | } | 189 | } |
| 129 | 190 | ||
| 130 | 191 | ||
| 131 | StkId luaD_precall (lua_State *L, StkId func) { | 192 | StkId luaD_precall (lua_State *L, StkId func) { |
| 132 | CallInfo *ci; | 193 | CallInfo *ci; |
| 133 | LClosure *cl; | 194 | LClosure *cl; |
| 195 | if (++L->ci == L->end_ci) luaD_reallocCI(L, 2*L->size_ci); | ||
| 196 | ci = L->ci; | ||
| 197 | ci->base = func+1; | ||
| 198 | ci->pc = NULL; | ||
| 134 | if (ttype(func) != LUA_TFUNCTION) { | 199 | if (ttype(func) != LUA_TFUNCTION) { |
| 135 | /* `func' is not a function; check the `function' tag method */ | 200 | /* `func' is not a function; check the `function' tag method */ |
| 136 | const TObject *tm = luaT_gettmbyobj(L, func, TM_CALL); | 201 | const TObject *tm = luaT_gettmbyobj(L, func, TM_CALL); |
| 137 | if (ttype(tm) != LUA_TFUNCTION) | 202 | if (ttype(tm) != LUA_TFUNCTION) { |
| 203 | L->ci--; /* undo increment (no function here) */ | ||
| 138 | luaG_typeerror(L, func, "call"); | 204 | luaG_typeerror(L, func, "call"); |
| 205 | } | ||
| 139 | luaD_openstack(L, func); | 206 | luaD_openstack(L, func); |
| 207 | func = ci->base - 1; /* previous call may change stack */ | ||
| 140 | setobj(func, tm); /* tag method is the new function to be called */ | 208 | setobj(func, tm); /* tag method is the new function to be called */ |
| 141 | } | 209 | } |
| 142 | ci = ++L->ci; | ||
| 143 | if (L->ci == L->end_ci) ci = growci(L); | ||
| 144 | ci->base = func+1; | ||
| 145 | if (L->callhook) | ||
| 146 | luaD_callHook(L, L->callhook, "call"); | ||
| 147 | cl = &clvalue(func)->l; | 210 | cl = &clvalue(func)->l; |
| 211 | if (L->callhook) { | ||
| 212 | luaD_callHook(L, L->callhook, "call"); | ||
| 213 | ci = L->ci; /* previous call may realocate `ci' */ | ||
| 214 | } | ||
| 148 | if (!cl->isC) { /* Lua function? prepare its call */ | 215 | if (!cl->isC) { /* Lua function? prepare its call */ |
| 149 | StkId base = func+1; | ||
| 150 | Proto *p = cl->p; | 216 | Proto *p = cl->p; |
| 151 | ci->savedpc = p->code; /* starting point */ | 217 | ci->savedpc = p->code; /* starting point */ |
| 152 | if (p->is_vararg) /* varargs? */ | 218 | if (p->is_vararg) /* varargs? */ |
| 153 | adjust_varargs(L, base, p->numparams); | 219 | adjust_varargs(L, p->numparams); |
| 154 | if (base > L->stack_last - p->maxstacksize) | 220 | if (ci->base > L->stack_last - p->maxstacksize) |
| 155 | luaD_stackerror(L); | 221 | luaD_growstack(L, p->maxstacksize); |
| 156 | ci->line = 0; | 222 | ci->line = 0; |
| 157 | ci->top = base + p->maxstacksize; | 223 | ci->top = ci->base + p->maxstacksize; |
| 158 | while (L->top < ci->top) | 224 | while (L->top < ci->top) |
| 159 | setnilvalue(L->top++); | 225 | setnilvalue(L->top++); |
| 160 | L->top = ci->top; | 226 | L->top = ci->top; |
| @@ -162,13 +228,12 @@ StkId luaD_precall (lua_State *L, StkId func) { | |||
| 162 | } | 228 | } |
| 163 | else { /* if is a C function, call it */ | 229 | else { /* if is a C function, call it */ |
| 164 | int n; | 230 | int n; |
| 165 | ci->savedpc = NULL; | ||
| 166 | luaD_checkstack(L, LUA_MINSTACK); /* ensure minimum stack size */ | 231 | luaD_checkstack(L, LUA_MINSTACK); /* ensure minimum stack size */ |
| 167 | lua_unlock(L); | 232 | lua_unlock(L); |
| 168 | #if LUA_COMPATUPVALUES | 233 | #if LUA_COMPATUPVALUES |
| 169 | lua_pushupvalues(L); | 234 | lua_pushupvalues(L); |
| 170 | #endif | 235 | #endif |
| 171 | n = (*clvalue(func)->c.f)(L); /* do the actual call */ | 236 | n = (*clvalue(ci->base-1)->c.f)(L); /* do the actual call */ |
| 172 | lua_lock(L); | 237 | lua_lock(L); |
| 173 | return L->top - n; | 238 | return L->top - n; |
| 174 | } | 239 | } |
| @@ -177,9 +242,12 @@ StkId luaD_precall (lua_State *L, StkId func) { | |||
| 177 | 242 | ||
| 178 | void luaD_poscall (lua_State *L, int wanted, StkId firstResult) { | 243 | void luaD_poscall (lua_State *L, int wanted, StkId firstResult) { |
| 179 | StkId res; | 244 | StkId res; |
| 180 | if (L->callhook) | 245 | if (L->callhook) { |
| 246 | StkId stack = L->stack; /* next call may change stack */ | ||
| 181 | luaD_callHook(L, L->callhook, "return"); | 247 | luaD_callHook(L, L->callhook, "return"); |
| 182 | res = L->ci->base - 1; /* `func' = final position of 1st result */ | 248 | firstResult = (firstResult - stack) + L->stack; |
| 249 | } | ||
| 250 | res = L->ci->base - 1; /* func == final position of 1st result */ | ||
| 183 | L->ci--; | 251 | L->ci--; |
| 184 | /* move results to correct place */ | 252 | /* move results to correct place */ |
| 185 | while (wanted != 0 && firstResult < L->top) { | 253 | while (wanted != 0 && firstResult < L->top) { |
| @@ -223,7 +291,7 @@ static void resume_results (lua_State *L, lua_State *from, int numresults) { | |||
| 223 | while (numresults) { | 291 | while (numresults) { |
| 224 | setobj(L->top, from->top - numresults); | 292 | setobj(L->top, from->top - numresults); |
| 225 | numresults--; | 293 | numresults--; |
| 226 | incr_top; | 294 | incr_top(L); |
| 227 | } | 295 | } |
| 228 | } | 296 | } |
| 229 | 297 | ||
| @@ -231,7 +299,7 @@ static void resume_results (lua_State *L, lua_State *from, int numresults) { | |||
| 231 | LUA_API void lua_resume (lua_State *L, lua_State *co) { | 299 | LUA_API void lua_resume (lua_State *L, lua_State *co) { |
| 232 | StkId firstResult; | 300 | StkId firstResult; |
| 233 | lua_lock(L); | 301 | lua_lock(L); |
| 234 | if (co->ci->savedpc == NULL) /* no activation record? */ | 302 | if (co->ci == co->base_ci) /* no activation record? ?? */ |
| 235 | luaD_error(L, "thread is dead - cannot be resumed"); | 303 | luaD_error(L, "thread is dead - cannot be resumed"); |
| 236 | lua_assert(co->errorJmp == NULL); | 304 | lua_assert(co->errorJmp == NULL); |
| 237 | co->errorJmp = L->errorJmp; | 305 | co->errorJmp = L->errorJmp; |
| @@ -253,15 +321,13 @@ LUA_API void lua_resume (lua_State *L, lua_State *co) { | |||
| 253 | 321 | ||
| 254 | LUA_API int lua_yield (lua_State *L, int nresults) { | 322 | LUA_API int lua_yield (lua_State *L, int nresults) { |
| 255 | CallInfo *ci; | 323 | CallInfo *ci; |
| 256 | int ibase; | ||
| 257 | lua_lock(L); | 324 | lua_lock(L); |
| 258 | ci = L->ci; | 325 | ci = L->ci; |
| 259 | if (ci_func(ci-1)->c.isC) | 326 | if (ci_func(ci-1)->c.isC) |
| 260 | luaD_error(L, "cannot `yield' a C function"); | 327 | luaD_error(L, "cannot `yield' a C function"); |
| 261 | ci->yield_results = nresults; /* very dirty trick! */ | 328 | ci->yield_results = nresults; |
| 262 | ibase = L->top - (ci-1)->base; | ||
| 263 | lua_unlock(L); | 329 | lua_unlock(L); |
| 264 | return ibase; | 330 | return -1; |
| 265 | } | 331 | } |
| 266 | 332 | ||
| 267 | 333 | ||
| @@ -280,16 +346,15 @@ static void f_call (lua_State *L, void *ud) { | |||
| 280 | 346 | ||
| 281 | 347 | ||
| 282 | LUA_API int lua_call (lua_State *L, int nargs, int nresults) { | 348 | LUA_API int lua_call (lua_State *L, int nargs, int nresults) { |
| 283 | StkId func; | ||
| 284 | struct CallS c; | 349 | struct CallS c; |
| 285 | int status; | 350 | int status; |
| 286 | lua_lock(L); | 351 | lua_lock(L); |
| 287 | func = L->top - (nargs+1); /* function to be called */ | 352 | c.func = L->top - (nargs+1); /* function to be called */ |
| 288 | c.func = func; c.nresults = nresults; | 353 | c.nresults = nresults; |
| 289 | status = luaD_runprotected(L, f_call, &c); | 354 | status = luaD_runprotected(L, f_call, &c); |
| 290 | if (status != 0) { /* an error occurred? */ | 355 | if (status != 0) { /* an error occurred? */ |
| 291 | luaF_close(L, func); /* close eventual pending closures */ | 356 | L->top -= nargs+1; /* remove parameters and func from the stack */ |
| 292 | L->top = func; /* remove parameters from the stack */ | 357 | luaF_close(L, L->top); /* close eventual pending closures */ |
| 293 | } | 358 | } |
| 294 | lua_unlock(L); | 359 | lua_unlock(L); |
| 295 | return status; | 360 | return status; |
| @@ -310,7 +375,7 @@ static void f_parser (lua_State *L, void *ud) { | |||
| 310 | Closure *cl = luaF_newLclosure(L, 0); | 375 | Closure *cl = luaF_newLclosure(L, 0); |
| 311 | cl->l.p = tf; | 376 | cl->l.p = tf; |
| 312 | setclvalue(L->top, cl); | 377 | setclvalue(L->top, cl); |
| 313 | incr_top; | 378 | incr_top(L); |
| 314 | } | 379 | } |
| 315 | 380 | ||
| 316 | 381 | ||
| @@ -351,7 +416,7 @@ LUA_API int lua_loadfile (lua_State *L, const char *filename) { | |||
| 351 | if (f == NULL) return LUA_ERRFILE; /* unable to reopen file */ | 416 | if (f == NULL) return LUA_ERRFILE; /* unable to reopen file */ |
| 352 | } | 417 | } |
| 353 | lua_pushliteral(L, "@"); | 418 | lua_pushliteral(L, "@"); |
| 354 | lua_pushstring(L, (filename == NULL) ? "(stdin)" : filename); | 419 | lua_pushstring(L, (filename == NULL) ? "=stdin" : filename); |
| 355 | lua_concat(L, 2); | 420 | lua_concat(L, 2); |
| 356 | nlevel = lua_gettop(L); | 421 | nlevel = lua_gettop(L); |
| 357 | filename = lua_tostring(L, -1); /* filename = `@'..filename */ | 422 | filename = lua_tostring(L, -1); /* filename = `@'..filename */ |
| @@ -380,28 +445,17 @@ LUA_API int lua_loadbuffer (lua_State *L, const char *buff, size_t size, | |||
| 380 | ** ======================================================= | 445 | ** ======================================================= |
| 381 | */ | 446 | */ |
| 382 | 447 | ||
| 383 | /* chain list of long jump buffers */ | ||
| 384 | struct lua_longjmp { | ||
| 385 | jmp_buf b; | ||
| 386 | struct lua_longjmp *previous; | ||
| 387 | volatile int status; /* error code */ | ||
| 388 | int ci; /* index of call info of active function that set protection */ | ||
| 389 | StkId top; /* top stack when protection was set */ | ||
| 390 | int allowhooks; /* `allowhook' state when protection was set */ | ||
| 391 | }; | ||
| 392 | |||
| 393 | 448 | ||
| 394 | static void message (lua_State *L, const char *s) { | 449 | static void message (lua_State *L, const char *s) { |
| 395 | TObject o, m; | 450 | TObject o, m; |
| 396 | setsvalue(&o, luaS_newliteral(L, LUA_ERRORMESSAGE)); | 451 | setsvalue(&o, luaS_newliteral(L, LUA_ERRORMESSAGE)); |
| 397 | luaV_gettable(L, gt(L), &o, &m); | 452 | luaV_gettable(L, gt(L), &o, &m); |
| 398 | if (ttype(&m) == LUA_TFUNCTION) { | 453 | if (ttype(&m) == LUA_TFUNCTION) { |
| 399 | StkId top = L->top; | 454 | setobj(L->top, &m); |
| 400 | setobj(top, &m); | 455 | incr_top(L); |
| 401 | incr_top; | 456 | setsvalue(L->top, luaS_new(L, s)); |
| 402 | setsvalue(top+1, luaS_new(L, s)); | 457 | incr_top(L); |
| 403 | incr_top; | 458 | luaD_call(L, L->top-2, 0); |
| 404 | luaD_call(L, top, 0); | ||
| 405 | } | 459 | } |
| 406 | } | 460 | } |
| 407 | 461 | ||
| @@ -410,13 +464,7 @@ static void message (lua_State *L, const char *s) { | |||
| 410 | ** Reports an error, and jumps up to the available recovery label | 464 | ** Reports an error, and jumps up to the available recovery label |
| 411 | */ | 465 | */ |
| 412 | void luaD_error (lua_State *L, const char *s) { | 466 | void luaD_error (lua_State *L, const char *s) { |
| 413 | if (s) { | 467 | if (s) message(L, s); |
| 414 | if (L->ci->savedpc) { /* error in Lua function preamble? */ | ||
| 415 | L->ci->savedpc = NULL; /* pretend function was already running */ | ||
| 416 | L->ci->pc = NULL; | ||
| 417 | } | ||
| 418 | message(L, s); | ||
| 419 | } | ||
| 420 | luaD_breakrun(L, LUA_ERRRUN); | 468 | luaD_breakrun(L, LUA_ERRRUN); |
| 421 | } | 469 | } |
| 422 | 470 | ||
| @@ -436,8 +484,9 @@ void luaD_breakrun (lua_State *L, int errcode) { | |||
| 436 | 484 | ||
| 437 | int luaD_runprotected (lua_State *L, void (*f)(lua_State *, void *), void *ud) { | 485 | int luaD_runprotected (lua_State *L, void (*f)(lua_State *, void *), void *ud) { |
| 438 | struct lua_longjmp lj; | 486 | struct lua_longjmp lj; |
| 439 | lj.ci = L->ci - L->base_ci; | 487 | lj.ci = L->ci; |
| 440 | lj.top = L->top; | 488 | lj.top = L->top; |
| 489 | lj.stack = L->stack; | ||
| 441 | lj.allowhooks = L->allowhooks; | 490 | lj.allowhooks = L->allowhooks; |
| 442 | lj.status = 0; | 491 | lj.status = 0; |
| 443 | lj.previous = L->errorJmp; /* chain new error handler */ | 492 | lj.previous = L->errorJmp; /* chain new error handler */ |
| @@ -445,7 +494,7 @@ int luaD_runprotected (lua_State *L, void (*f)(lua_State *, void *), void *ud) { | |||
| 445 | if (setjmp(lj.b) == 0) | 494 | if (setjmp(lj.b) == 0) |
| 446 | (*f)(L, ud); | 495 | (*f)(L, ud); |
| 447 | else { /* an error occurred: restore the state */ | 496 | else { /* an error occurred: restore the state */ |
| 448 | L->ci = L->base_ci + lj.ci; | 497 | L->ci = lj.ci; |
| 449 | L->top = lj.top; | 498 | L->top = lj.top; |
| 450 | L->allowhooks = lj.allowhooks; | 499 | L->allowhooks = lj.allowhooks; |
| 451 | restore_stack_limit(L); | 500 | restore_stack_limit(L); |
