diff options
Diffstat (limited to 'lbaselib.c')
-rw-r--r-- | lbaselib.c | 46 |
1 files changed, 24 insertions, 22 deletions
@@ -1,5 +1,5 @@ | |||
1 | /* | 1 | /* |
2 | ** $Id: lbaselib.c,v 1.102 2002/10/25 21:31:28 roberto Exp roberto $ | 2 | ** $Id: lbaselib.c,v 1.103 2002/10/25 21:36:54 roberto Exp roberto $ |
3 | ** Basic library | 3 | ** Basic library |
4 | ** See Copyright Notice in lua.h | 4 | ** See Copyright Notice in lua.h |
5 | */ | 5 | */ |
@@ -557,12 +557,23 @@ static const luaL_reg base_funcs[] = { | |||
557 | ** ======================================================= | 557 | ** ======================================================= |
558 | */ | 558 | */ |
559 | 559 | ||
560 | 560 | static int auxresume (lua_State *L, lua_State *co, int narg) { | |
561 | static int luaB_auxresume (lua_State *L, lua_State *co) { | ||
562 | int status; | 561 | int status; |
563 | int oldtop = lua_gettop(L); | 562 | if (!lua_checkstack(co, narg)) |
564 | status = lua_resume(L, co); | 563 | luaL_error(L, "too many arguments to resume"); |
565 | return (status != 0) ? -1 : lua_gettop(L) - oldtop; | 564 | lua_movethread(L, co, narg); |
565 | status = lua_resume(co, narg); | ||
566 | if (status == 0) { | ||
567 | int nres = lua_gettop(co); | ||
568 | if (!lua_checkstack(L, narg)) | ||
569 | luaL_error(L, "too many results to resume"); | ||
570 | lua_movethread(co, L, nres); /* move yielded values */ | ||
571 | return nres; | ||
572 | } | ||
573 | else { | ||
574 | lua_movethread(co, L, 1); /* move error message */ | ||
575 | return -1; /* error flag */ | ||
576 | } | ||
566 | } | 577 | } |
567 | 578 | ||
568 | 579 | ||
@@ -570,7 +581,7 @@ static int luaB_coresume (lua_State *L) { | |||
570 | lua_State *co = lua_tothread(L, 1); | 581 | lua_State *co = lua_tothread(L, 1); |
571 | int r; | 582 | int r; |
572 | luaL_arg_check(L, co, 1, "coroutine/thread expected"); | 583 | luaL_arg_check(L, co, 1, "coroutine/thread expected"); |
573 | r = luaB_auxresume(L, co); | 584 | r = auxresume(L, co, lua_gettop(L) - 1); |
574 | if (r < 0) { | 585 | if (r < 0) { |
575 | lua_pushboolean(L, 0); | 586 | lua_pushboolean(L, 0); |
576 | lua_insert(L, -2); | 587 | lua_insert(L, -2); |
@@ -585,28 +596,19 @@ static int luaB_coresume (lua_State *L) { | |||
585 | 596 | ||
586 | 597 | ||
587 | static int luaB_auxwrap (lua_State *L) { | 598 | static int luaB_auxwrap (lua_State *L) { |
588 | int r = luaB_auxresume(L, lua_tothread(L, lua_upvalueindex(1))); | 599 | lua_State *co = lua_tothread(L, lua_upvalueindex(1)); |
589 | if (r < 0) lua_error(L); | 600 | int r = auxresume(L, co, lua_gettop(L)); |
601 | if (r < 0) lua_error(L); /* propagate error */ | ||
590 | return r; | 602 | return r; |
591 | } | 603 | } |
592 | 604 | ||
593 | 605 | ||
594 | static int luaB_cocreate (lua_State *L) { | 606 | static int luaB_cocreate (lua_State *L) { |
595 | lua_State *NL; | 607 | lua_State *NL = lua_newthread(L); |
596 | int ref; | ||
597 | int i; | ||
598 | int n = lua_gettop(L); | ||
599 | luaL_arg_check(L, lua_isfunction(L, 1) && !lua_iscfunction(L, 1), 1, | 608 | luaL_arg_check(L, lua_isfunction(L, 1) && !lua_iscfunction(L, 1), 1, |
600 | "Lua function expected"); | 609 | "Lua function expected"); |
601 | NL = lua_newthread(L); | 610 | lua_pushvalue(L, 1); /* move function to top */ |
602 | /* move function and arguments from L to NL */ | 611 | lua_movethread(L, NL, 1); /* move function from L to NL */ |
603 | for (i = 1; i <= n; i++) { | ||
604 | lua_pushvalue(L, i); | ||
605 | ref = lua_ref(L, 1); | ||
606 | lua_getref(NL, ref); | ||
607 | lua_unref(L, ref); | ||
608 | } | ||
609 | lua_cobegin(NL, n-1); | ||
610 | return 1; | 612 | return 1; |
611 | } | 613 | } |
612 | 614 | ||