diff options
| author | Roberto Ierusalimschy <roberto@inf.puc-rio.br> | 1999-11-26 16:53:03 -0200 |
|---|---|---|
| committer | Roberto Ierusalimschy <roberto@inf.puc-rio.br> | 1999-11-26 16:53:03 -0200 |
| commit | 790690a2236ab0ad0cce35551c17e62064b4c85b (patch) | |
| tree | cafa7dc4b8d6de9bbe3a4ae3592dfa2de1f485d6 | |
| parent | 33b8a010324863ddb495768ebe9e92403c5116c8 (diff) | |
| download | lua-790690a2236ab0ad0cce35551c17e62064b4c85b.tar.gz lua-790690a2236ab0ad0cce35551c17e62064b4c85b.tar.bz2 lua-790690a2236ab0ad0cce35551c17e62064b4c85b.zip | |
new way to keep function arguments (with StkId instead of copy)
| -rw-r--r-- | lbuiltin.c | 103 |
1 files changed, 51 insertions, 52 deletions
| @@ -1,5 +1,5 @@ | |||
| 1 | /* | 1 | /* |
| 2 | ** $Id: lbuiltin.c,v 1.74 1999/11/22 13:12:07 roberto Exp roberto $ | 2 | ** $Id: lbuiltin.c,v 1.75 1999/11/22 17:39:51 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 | */ |
| @@ -48,10 +48,10 @@ static real getsize (const Hash *h) { | |||
| 48 | int i = h->size; | 48 | int i = h->size; |
| 49 | Node *n = h->node; | 49 | Node *n = h->node; |
| 50 | while (i--) { | 50 | while (i--) { |
| 51 | if (ttype(key(L, n)) == LUA_T_NUMBER && | 51 | if (ttype(key(n)) == LUA_T_NUMBER && |
| 52 | ttype(val(L, n)) != LUA_T_NIL && | 52 | ttype(val(n)) != LUA_T_NIL && |
| 53 | nvalue(key(L, n)) > max) | 53 | nvalue(key(n)) > max) |
| 54 | max = nvalue(key(L, n)); | 54 | max = nvalue(key(n)); |
| 55 | n++; | 55 | n++; |
| 56 | } | 56 | } |
| 57 | return max; | 57 | return max; |
| @@ -170,7 +170,6 @@ static void luaB_setglobal (lua_State *L) { | |||
| 170 | lua_Object value = luaL_nonnullarg(L, 2); | 170 | lua_Object value = luaL_nonnullarg(L, 2); |
| 171 | lua_pushobject(L, value); | 171 | lua_pushobject(L, value); |
| 172 | lua_setglobal(L, n); | 172 | lua_setglobal(L, n); |
| 173 | lua_pushobject(L, value); /* return given value */ | ||
| 174 | } | 173 | } |
| 175 | 174 | ||
| 176 | static void luaB_rawsetglobal (lua_State *L) { | 175 | static void luaB_rawsetglobal (lua_State *L) { |
| @@ -178,7 +177,6 @@ static void luaB_rawsetglobal (lua_State *L) { | |||
| 178 | lua_Object value = luaL_nonnullarg(L, 2); | 177 | lua_Object value = luaL_nonnullarg(L, 2); |
| 179 | lua_pushobject(L, value); | 178 | lua_pushobject(L, value); |
| 180 | lua_rawsetglobal(L, n); | 179 | lua_rawsetglobal(L, n); |
| 181 | lua_pushobject(L, value); /* return given value */ | ||
| 182 | } | 180 | } |
| 183 | 181 | ||
| 184 | static void luaB_getglobal (lua_State *L) { | 182 | static void luaB_getglobal (lua_State *L) { |
| @@ -235,7 +233,8 @@ static void luaB_settagmethod (lua_State *L) { | |||
| 235 | } | 233 | } |
| 236 | 234 | ||
| 237 | static void luaB_gettagmethod (lua_State *L) { | 235 | static void luaB_gettagmethod (lua_State *L) { |
| 238 | lua_pushobject(L, lua_gettagmethod(L, luaL_check_int(L, 1), luaL_check_string(L, 2))); | 236 | lua_pushobject(L, lua_gettagmethod(L, luaL_check_int(L, 1), |
| 237 | luaL_check_string(L, 2))); | ||
| 239 | } | 238 | } |
| 240 | 239 | ||
| 241 | static void luaB_seterrormethod (lua_State *L) { | 240 | static void luaB_seterrormethod (lua_State *L) { |
| @@ -252,7 +251,6 @@ static void luaB_collectgarbage (lua_State *L) { | |||
| 252 | static void luaB_type (lua_State *L) { | 251 | static void luaB_type (lua_State *L) { |
| 253 | lua_Object o = luaL_nonnullarg(L, 1); | 252 | lua_Object o = luaL_nonnullarg(L, 1); |
| 254 | lua_pushstring(L, lua_type(L, o)); | 253 | lua_pushstring(L, lua_type(L, o)); |
| 255 | lua_pushnumber(L, lua_tag(L, o)); | ||
| 256 | } | 254 | } |
| 257 | 255 | ||
| 258 | /* }====================================================== */ | 256 | /* }====================================================== */ |
| @@ -416,66 +414,65 @@ static void luaB_assert (lua_State *L) { | |||
| 416 | 414 | ||
| 417 | 415 | ||
| 418 | static void luaB_foreachi (lua_State *L) { | 416 | static void luaB_foreachi (lua_State *L) { |
| 417 | struct Stack *S = &L->stack; | ||
| 419 | const Hash *t = gettable(L, 1); | 418 | const Hash *t = gettable(L, 1); |
| 420 | int i; | ||
| 421 | int n = (int)getnarg(L, t); | 419 | int n = (int)getnarg(L, t); |
| 422 | TObject f; | 420 | int i; |
| 421 | StkId f = luaA_Address(L, luaL_functionarg(L, 2)) - S->stack; | ||
| 423 | /* 'f' cannot be a pointer to TObject, because it is on the stack, and the | 422 | /* 'f' cannot be a pointer to TObject, because it is on the stack, and the |
| 424 | stack may be reallocated by the call. Moreover, some C compilers do not | 423 | stack may be reallocated by the call. */ |
| 425 | initialize structs, so we must do the assignment after the declaration */ | ||
| 426 | f = *luaA_Address(L, luaL_functionarg(L, 2)); | ||
| 427 | luaD_checkstack(L, 3); /* for f, key, and val */ | 424 | luaD_checkstack(L, 3); /* for f, key, and val */ |
| 428 | for (i=1; i<=n; i++) { | 425 | for (i=1; i<=n; i++) { |
| 429 | *(L->stack.top++) = f; | 426 | *(S->top++) = *(S->stack+f); |
| 430 | ttype(L->stack.top) = LUA_T_NUMBER; nvalue(L->stack.top++) = i; | 427 | ttype(S->top) = LUA_T_NUMBER; nvalue(S->top++) = i; |
| 431 | *(L->stack.top++) = *luaH_getint(L, t, i); | 428 | *(S->top++) = *luaH_getint(L, t, i); |
| 432 | luaD_calln(L, 2, 1); | 429 | luaD_call(L, S->top-3, 1); |
| 433 | if (ttype(L->stack.top-1) != LUA_T_NIL) | 430 | if (ttype(S->top-1) != LUA_T_NIL) |
| 434 | return; | 431 | return; |
| 435 | L->stack.top--; | 432 | S->top--; |
| 436 | } | 433 | } |
| 437 | } | 434 | } |
| 438 | 435 | ||
| 439 | 436 | ||
| 440 | static void luaB_foreach (lua_State *L) { | 437 | static void luaB_foreach (lua_State *L) { |
| 438 | struct Stack *S = &L->stack; | ||
| 441 | const Hash *a = gettable(L, 1); | 439 | const Hash *a = gettable(L, 1); |
| 440 | StkId f = luaA_Address(L, luaL_functionarg(L, 2)) - S->stack; | ||
| 442 | int i; | 441 | int i; |
| 443 | TObject f; /* see comment in 'foreachi' */ | ||
| 444 | f = *luaA_Address(L, luaL_functionarg(L, 2)); | ||
| 445 | luaD_checkstack(L, 3); /* for f, key, and val */ | 442 | luaD_checkstack(L, 3); /* for f, key, and val */ |
| 446 | for (i=0; i<a->size; i++) { | 443 | for (i=0; i<a->size; i++) { |
| 447 | const Node *nd = &(a->node[i]); | 444 | const Node *nd = &(a->node[i]); |
| 448 | if (ttype(val(L, nd)) != LUA_T_NIL) { | 445 | if (ttype(val(nd)) != LUA_T_NIL) { |
| 449 | *(L->stack.top++) = f; | 446 | *(S->top++) = *(S->stack+f); |
| 450 | *(L->stack.top++) = *key(L, nd); | 447 | *(S->top++) = *key(nd); |
| 451 | *(L->stack.top++) = *val(L, nd); | 448 | *(S->top++) = *val(nd); |
| 452 | luaD_calln(L, 2, 1); | 449 | luaD_call(L, S->top-3, 1); |
| 453 | if (ttype(L->stack.top-1) != LUA_T_NIL) | 450 | if (ttype(S->top-1) != LUA_T_NIL) |
| 454 | return; | 451 | return; |
| 455 | L->stack.top--; /* remove result */ | 452 | S->top--; /* remove result */ |
| 456 | } | 453 | } |
| 457 | } | 454 | } |
| 458 | } | 455 | } |
| 459 | 456 | ||
| 460 | 457 | ||
| 461 | static void luaB_foreachvar (lua_State *L) { | 458 | static void luaB_foreachvar (lua_State *L) { |
| 459 | struct Stack *S = &L->stack; | ||
| 460 | StkId f = luaA_Address(L, luaL_functionarg(L, 1)) - S->stack; | ||
| 462 | GlobalVar *gv; | 461 | GlobalVar *gv; |
| 463 | TObject f; /* see comment in 'foreachi' */ | ||
| 464 | f = *luaA_Address(L, luaL_functionarg(L, 1)); | ||
| 465 | luaD_checkstack(L, 4); /* for extra var name, f, var name, and globalval */ | 462 | luaD_checkstack(L, 4); /* for extra var name, f, var name, and globalval */ |
| 466 | for (gv = L->rootglobal; gv; gv = gv->next) { | 463 | for (gv = L->rootglobal; gv; gv = gv->next) { |
| 467 | if (gv->value.ttype != LUA_T_NIL) { | 464 | if (gv->value.ttype != LUA_T_NIL) { |
| 468 | pushtagstring(L, gv->name); /* keep (extra) name on stack to avoid GC */ | 465 | pushtagstring(L, gv->name); /* keep (extra) name on stack to avoid GC */ |
| 469 | *(L->stack.top++) = f; | 466 | *(S->top++) = *(S->stack+f); |
| 470 | pushtagstring(L, gv->name); | 467 | pushtagstring(L, gv->name); |
| 471 | *(L->stack.top++) = gv->value; | 468 | *(S->top++) = gv->value; |
| 472 | luaD_calln(L, 2, 1); | 469 | luaD_call(L, S->top-3, 1); |
| 473 | if (ttype(L->stack.top-1) != LUA_T_NIL) { | 470 | if (ttype(S->top-1) != LUA_T_NIL) { |
| 474 | L->stack.top--; | 471 | S->top--; |
| 475 | *(L->stack.top-1) = *L->stack.top; /* remove extra name */ | 472 | *(S->top-1) = *S->top; /* remove extra name */ |
| 476 | return; | 473 | return; |
| 477 | } | 474 | } |
| 478 | L->stack.top-=2; /* remove result and extra name */ | 475 | S->top-=2; /* remove result and extra name */ |
| 479 | } | 476 | } |
| 480 | } | 477 | } |
| 481 | } | 478 | } |
| @@ -529,14 +526,15 @@ static void swap (lua_State *L, Hash *a, int i, int j) { | |||
| 529 | luaH_setint(L, a, j, &temp); | 526 | luaH_setint(L, a, j, &temp); |
| 530 | } | 527 | } |
| 531 | 528 | ||
| 532 | static int sort_comp (lua_State *L, lua_Object f, const TObject *a, const TObject *b) { | 529 | static int sort_comp (lua_State *L, lua_Object f, const TObject *a, |
| 530 | const TObject *b) { | ||
| 533 | /* notice: the caller (auxsort) must check stack space */ | 531 | /* notice: the caller (auxsort) must check stack space */ |
| 534 | if (f != LUA_NOOBJECT) { | 532 | if (f != LUA_NOOBJECT) { |
| 535 | *(L->stack.top) = *luaA_Address(L, f); | 533 | *(L->stack.top) = *luaA_Address(L, f); |
| 536 | *(L->stack.top+1) = *a; | 534 | *(L->stack.top+1) = *a; |
| 537 | *(L->stack.top+2) = *b; | 535 | *(L->stack.top+2) = *b; |
| 538 | L->stack.top += 3; | 536 | L->stack.top += 3; |
| 539 | luaD_calln(L, 2, 1); | 537 | luaD_call(L, L->stack.top-3, 1); |
| 540 | } | 538 | } |
| 541 | else { /* a < b? */ | 539 | else { /* a < b? */ |
| 542 | *(L->stack.top) = *a; | 540 | *(L->stack.top) = *a; |
| @@ -548,32 +546,33 @@ static int sort_comp (lua_State *L, lua_Object f, const TObject *a, const TObjec | |||
| 548 | } | 546 | } |
| 549 | 547 | ||
| 550 | static void auxsort (lua_State *L, Hash *a, int l, int u, lua_Object f) { | 548 | static void auxsort (lua_State *L, Hash *a, int l, int u, lua_Object f) { |
| 551 | StkId P = L->stack.top - L->stack.stack; /* temporary place for pivot */ | 549 | struct Stack *S = &L->stack; |
| 552 | L->stack.top++; | 550 | StkId P = S->top - S->stack; /* temporary place for pivot */ |
| 553 | ttype(L->stack.stack+P) = LUA_T_NIL; | 551 | S->top++; |
| 552 | ttype(S->stack+P) = LUA_T_NIL; | ||
| 554 | while (l < u) { /* for tail recursion */ | 553 | while (l < u) { /* for tail recursion */ |
| 555 | int i, j; | 554 | int i, j; |
| 556 | /* sort elements a[l], a[(l+u)/2] and a[u] */ | 555 | /* sort elements a[l], a[(l+u)/2] and a[u] */ |
| 557 | if (sort_comp(L, f, luaH_getint(L, a, u), luaH_getint(L, a, l))) /* a[u]<a[l]? */ | 556 | if (sort_comp(L, f, luaH_getint(L, a, u), luaH_getint(L, a, l))) |
| 558 | swap(L, a, l, u); | 557 | swap(L, a, l, u); /* a[u]<a[l] */ |
| 559 | if (u-l == 1) break; /* only 2 elements */ | 558 | if (u-l == 1) break; /* only 2 elements */ |
| 560 | i = (l+u)/2; | 559 | i = (l+u)/2; |
| 561 | *(L->stack.stack+P) = *luaH_getint(L, a, i); /* P = a[i] */ | 560 | *(S->stack+P) = *luaH_getint(L, a, i); /* P = a[i] */ |
| 562 | if (sort_comp(L, f, L->stack.stack+P, luaH_getint(L, a, l))) /* a[i]<a[l]? */ | 561 | if (sort_comp(L, f, S->stack+P, luaH_getint(L, a, l))) /* a[i]<a[l]? */ |
| 563 | swap(L, a, l, i); | 562 | swap(L, a, l, i); |
| 564 | else if (sort_comp(L, f, luaH_getint(L, a, u), L->stack.stack+P)) /* a[u]<a[i]? */ | 563 | else if (sort_comp(L, f, luaH_getint(L, a, u), S->stack+P)) /* a[u]<a[i]? */ |
| 565 | swap(L, a, i, u); | 564 | swap(L, a, i, u); |
| 566 | if (u-l == 2) break; /* only 3 elements */ | 565 | if (u-l == 2) break; /* only 3 elements */ |
| 567 | *(L->stack.stack+P) = *luaH_getint(L, a, i); /* save pivot on stack (GC) */ | 566 | *(S->stack+P) = *luaH_getint(L, a, i); /* save pivot on stack (GC) */ |
| 568 | swap(L, a, i, u-1); /* put median element as pivot (a[u-1]) */ | 567 | swap(L, a, i, u-1); /* put median element as pivot (a[u-1]) */ |
| 569 | /* a[l] <= P == a[u-1] <= a[u], only needs to sort from l+1 to u-2 */ | 568 | /* a[l] <= P == a[u-1] <= a[u], only needs to sort from l+1 to u-2 */ |
| 570 | i = l; j = u-1; | 569 | i = l; j = u-1; |
| 571 | for (;;) { /* invariant: a[l..i] <= P <= a[j..u] */ | 570 | for (;;) { /* invariant: a[l..i] <= P <= a[j..u] */ |
| 572 | /* repeat i++ until a[i] >= P */ | 571 | /* repeat i++ until a[i] >= P */ |
| 573 | while (sort_comp(L, f, luaH_getint(L, a, ++i), L->stack.stack+P)) | 572 | while (sort_comp(L, f, luaH_getint(L, a, ++i), S->stack+P)) |
| 574 | if (i>u) lua_error(L, "invalid order function for sorting"); | 573 | if (i>u) lua_error(L, "invalid order function for sorting"); |
| 575 | /* repeat j-- until a[j] <= P */ | 574 | /* repeat j-- until a[j] <= P */ |
| 576 | while (sort_comp(L, f, (L->stack.stack+P), luaH_getint(L, a, --j))) | 575 | while (sort_comp(L, f, (S->stack+P), luaH_getint(L, a, --j))) |
| 577 | if (j<l) lua_error(L, "invalid order function for sorting"); | 576 | if (j<l) lua_error(L, "invalid order function for sorting"); |
| 578 | if (j<i) break; | 577 | if (j<i) break; |
| 579 | swap(L, a, i, j); | 578 | swap(L, a, i, j); |
| @@ -589,7 +588,7 @@ static void auxsort (lua_State *L, Hash *a, int l, int u, lua_Object f) { | |||
| 589 | } | 588 | } |
| 590 | auxsort(L, a, j, i, f); /* call recursively the smaller one */ | 589 | auxsort(L, a, j, i, f); /* call recursively the smaller one */ |
| 591 | } /* repeat the routine for the larger one */ | 590 | } /* repeat the routine for the larger one */ |
| 592 | L->stack.top--; /* remove pivot from stack */ | 591 | S->top--; /* remove pivot from stack */ |
| 593 | } | 592 | } |
| 594 | 593 | ||
| 595 | static void luaB_sort (lua_State *L) { | 594 | static void luaB_sort (lua_State *L) { |
