diff options
| -rw-r--r-- | bugs | 6 | ||||
| -rw-r--r-- | lbuiltin.c | 34 |
2 files changed, 26 insertions, 14 deletions
| @@ -90,3 +90,9 @@ Fri Apr 30 11:10:20 EST 1999 | |||
| 90 | >> '$' at end of pattern was matching regular '$', too. | 90 | >> '$' at end of pattern was matching regular '$', too. |
| 91 | (by anna) | 91 | (by anna) |
| 92 | 92 | ||
| 93 | ** lbuiltin.c | ||
| 94 | Fri May 21 17:15:11 EST 1999 | ||
| 95 | >> foreach, foreachi, foreachvar points to function in stack when stack | ||
| 96 | can be reallocated. | ||
| 97 | (by tomas) | ||
| 98 | |||
| @@ -1,5 +1,5 @@ | |||
| 1 | /* | 1 | /* |
| 2 | ** $Id: lbuiltin.c,v 1.55 1999/03/01 20:22:16 roberto Exp roberto $ | 2 | ** $Id: lbuiltin.c,v 1.56 1999/03/04 21:17:26 roberto Exp roberto $ |
| 3 | ** Built-in functions | 3 | ** Built-in functions |
| 4 | ** See Copyright Notice in lua.h | 4 | ** See Copyright Notice in lua.h |
| 5 | */ | 5 | */ |
| @@ -389,12 +389,16 @@ static void luaB_assert (void) { | |||
| 389 | 389 | ||
| 390 | static void luaB_foreachi (void) { | 390 | static void luaB_foreachi (void) { |
| 391 | Hash *t = gethash(1); | 391 | Hash *t = gethash(1); |
| 392 | TObject *f = luaA_Address(luaL_functionarg(2)); | ||
| 393 | int i; | 392 | int i; |
| 394 | int n = (int)getnarg(t); | 393 | int n = (int)getnarg(t); |
| 394 | TObject f; | ||
| 395 | /* 'f' cannot be a pointer to TObject, because it is on the stack, and the | ||
| 396 | stack may be reallocated by the call. Moreover, some C compilers do not | ||
| 397 | initialize structs, so we must do the assignment after the declaration */ | ||
| 398 | f = *luaA_Address(luaL_functionarg(2)); | ||
| 395 | luaD_checkstack(3); /* for f, ref, and val */ | 399 | luaD_checkstack(3); /* for f, ref, and val */ |
| 396 | for (i=1; i<=n; i++) { | 400 | for (i=1; i<=n; i++) { |
| 397 | *(L->stack.top++) = *f; | 401 | *(L->stack.top++) = f; |
| 398 | ttype(L->stack.top) = LUA_T_NUMBER; nvalue(L->stack.top++) = i; | 402 | ttype(L->stack.top) = LUA_T_NUMBER; nvalue(L->stack.top++) = i; |
| 399 | *(L->stack.top++) = *luaH_getint(t, i); | 403 | *(L->stack.top++) = *luaH_getint(t, i); |
| 400 | luaD_calln(2, 1); | 404 | luaD_calln(2, 1); |
| @@ -407,13 +411,14 @@ static void luaB_foreachi (void) { | |||
| 407 | 411 | ||
| 408 | static void luaB_foreach (void) { | 412 | static void luaB_foreach (void) { |
| 409 | Hash *a = gethash(1); | 413 | Hash *a = gethash(1); |
| 410 | TObject *f = luaA_Address(luaL_functionarg(2)); | ||
| 411 | int i; | 414 | int i; |
| 415 | TObject f; /* see comment in 'foreachi' */ | ||
| 416 | f = *luaA_Address(luaL_functionarg(2)); | ||
| 412 | luaD_checkstack(3); /* for f, ref, and val */ | 417 | luaD_checkstack(3); /* for f, ref, and val */ |
| 413 | for (i=0; i<a->nhash; i++) { | 418 | for (i=0; i<a->nhash; i++) { |
| 414 | Node *nd = &(a->node[i]); | 419 | Node *nd = &(a->node[i]); |
| 415 | if (ttype(val(nd)) != LUA_T_NIL) { | 420 | if (ttype(val(nd)) != LUA_T_NIL) { |
| 416 | *(L->stack.top++) = *f; | 421 | *(L->stack.top++) = f; |
| 417 | *(L->stack.top++) = *ref(nd); | 422 | *(L->stack.top++) = *ref(nd); |
| 418 | *(L->stack.top++) = *val(nd); | 423 | *(L->stack.top++) = *val(nd); |
| 419 | luaD_calln(2, 1); | 424 | luaD_calln(2, 1); |
| @@ -426,14 +431,15 @@ static void luaB_foreach (void) { | |||
| 426 | 431 | ||
| 427 | 432 | ||
| 428 | static void luaB_foreachvar (void) { | 433 | static void luaB_foreachvar (void) { |
| 429 | TObject *f = luaA_Address(luaL_functionarg(1)); | ||
| 430 | GCnode *g; | 434 | GCnode *g; |
| 435 | TObject f; /* see comment in 'foreachi' */ | ||
| 436 | f = *luaA_Address(luaL_functionarg(1)); | ||
| 431 | luaD_checkstack(4); /* for extra var name, f, var name, and globalval */ | 437 | luaD_checkstack(4); /* for extra var name, f, var name, and globalval */ |
| 432 | for (g = L->rootglobal.next; g; g = g->next) { | 438 | for (g = L->rootglobal.next; g; g = g->next) { |
| 433 | TaggedString *s = (TaggedString *)g; | 439 | TaggedString *s = (TaggedString *)g; |
| 434 | if (s->u.s.globalval.ttype != LUA_T_NIL) { | 440 | if (s->u.s.globalval.ttype != LUA_T_NIL) { |
| 435 | pushtagstring(s); /* keep (extra) s on stack to avoid GC */ | 441 | pushtagstring(s); /* keep (extra) s on stack to avoid GC */ |
| 436 | *(L->stack.top++) = *f; | 442 | *(L->stack.top++) = f; |
| 437 | pushtagstring(s); | 443 | pushtagstring(s); |
| 438 | *(L->stack.top++) = s->u.s.globalval; | 444 | *(L->stack.top++) = s->u.s.globalval; |
| 439 | luaD_calln(2, 1); | 445 | luaD_calln(2, 1); |
| @@ -494,10 +500,10 @@ static void swap (Hash *a, int i, int j) { | |||
| 494 | luaH_setint(a, j, &temp); | 500 | luaH_setint(a, j, &temp); |
| 495 | } | 501 | } |
| 496 | 502 | ||
| 497 | static int sort_comp (TObject *f, TObject *a, TObject *b) { | 503 | static int sort_comp (lua_Object f, TObject *a, TObject *b) { |
| 498 | /* notice: the caller (auxsort) must check stack space */ | 504 | /* notice: the caller (auxsort) must check stack space */ |
| 499 | if (f) { | 505 | if (f != LUA_NOOBJECT) { |
| 500 | *(L->stack.top) = *f; | 506 | *(L->stack.top) = *luaA_Address(f); |
| 501 | *(L->stack.top+1) = *a; | 507 | *(L->stack.top+1) = *a; |
| 502 | *(L->stack.top+2) = *b; | 508 | *(L->stack.top+2) = *b; |
| 503 | L->stack.top += 3; | 509 | L->stack.top += 3; |
| @@ -512,7 +518,7 @@ static int sort_comp (TObject *f, TObject *a, TObject *b) { | |||
| 512 | return ttype(--(L->stack.top)) != LUA_T_NIL; | 518 | return ttype(--(L->stack.top)) != LUA_T_NIL; |
| 513 | } | 519 | } |
| 514 | 520 | ||
| 515 | static void auxsort (Hash *a, int l, int u, TObject *f) { | 521 | static void auxsort (Hash *a, int l, int u, lua_Object f) { |
| 516 | while (l < u) { /* for tail recursion */ | 522 | while (l < u) { /* for tail recursion */ |
| 517 | TObject *P; | 523 | TObject *P; |
| 518 | int i, j; | 524 | int i, j; |
| @@ -560,10 +566,10 @@ static void luaB_sort (void) { | |||
| 560 | Hash *a = gethash(1); | 566 | Hash *a = gethash(1); |
| 561 | int n = (int)getnarg(a); | 567 | int n = (int)getnarg(a); |
| 562 | lua_Object func = lua_getparam(2); | 568 | lua_Object func = lua_getparam(2); |
| 563 | TObject *f = luaA_Address(func); | 569 | luaL_arg_check(func == LUA_NOOBJECT || lua_isfunction(func), 2, |
| 564 | luaL_arg_check(!f || lua_isfunction(func), 2, "function expected"); | 570 | "function expected"); |
| 565 | luaD_checkstack(4); /* for Pivot, f, a, b (sort_comp) */ | 571 | luaD_checkstack(4); /* for Pivot, f, a, b (sort_comp) */ |
| 566 | auxsort(a, 1, n, f); | 572 | auxsort(a, 1, n, func); |
| 567 | lua_pushobject(t); | 573 | lua_pushobject(t); |
| 568 | } | 574 | } |
| 569 | 575 | ||
