diff options
author | Roberto Ierusalimschy <roberto@inf.puc-rio.br> | 1999-05-24 14:53:49 -0300 |
---|---|---|
committer | Roberto Ierusalimschy <roberto@inf.puc-rio.br> | 1999-05-24 14:53:49 -0300 |
commit | 3b533ea7c7fd65c2c2e61cd4c0a00578152e450a (patch) | |
tree | 06486bdf503d6a5fb5bce9e641e02920e455c656 | |
parent | 995775e1cb2ffeec96a07be93c22a7710b3ae41c (diff) | |
download | lua-3b533ea7c7fd65c2c2e61cd4c0a00578152e450a.tar.gz lua-3b533ea7c7fd65c2c2e61cd4c0a00578152e450a.tar.bz2 lua-3b533ea7c7fd65c2c2e61cd4c0a00578152e450a.zip |
foreach, foreachi, foreachvar points to function in stack when stack
can be reallocated.
-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 | ||