diff options
Diffstat (limited to 'lbaselib.c')
| -rw-r--r-- | lbaselib.c | 35 |
1 files changed, 28 insertions, 7 deletions
| @@ -415,6 +415,14 @@ static int luaB_tostring (lua_State *L) { | |||
| 415 | static int luaB_resume (lua_State *L) { | 415 | static int luaB_resume (lua_State *L) { |
| 416 | lua_State *co = (lua_State *)lua_touserdata(L, lua_upvalueindex(1)); | 416 | lua_State *co = (lua_State *)lua_touserdata(L, lua_upvalueindex(1)); |
| 417 | lua_resume(L, co); | 417 | lua_resume(L, co); |
| 418 | return lua_gettop(L); | ||
| 419 | } | ||
| 420 | |||
| 421 | |||
| 422 | |||
| 423 | static int gc_coroutine (lua_State *L) { | ||
| 424 | lua_State *co = (lua_State *)lua_touserdata(L, 1); | ||
| 425 | lua_closethread(L, co); | ||
| 418 | return 0; | 426 | return 0; |
| 419 | } | 427 | } |
| 420 | 428 | ||
| @@ -422,22 +430,30 @@ static int luaB_resume (lua_State *L) { | |||
| 422 | static int luaB_coroutine (lua_State *L) { | 430 | static int luaB_coroutine (lua_State *L) { |
| 423 | lua_State *NL; | 431 | lua_State *NL; |
| 424 | int ref; | 432 | int ref; |
| 425 | luaL_check_type(L, 1, LUA_TFUNCTION); | 433 | int i; |
| 434 | int n = lua_gettop(L); | ||
| 435 | luaL_arg_check(L, lua_isfunction(L, 1) && !lua_iscfunction(L, 1), 1, | ||
| 436 | "Lua function expected"); | ||
| 426 | NL = lua_newthread(L, 0); | 437 | NL = lua_newthread(L, 0); |
| 427 | if (NL == NULL) lua_error(L, "unable to create new thread"); | 438 | if (NL == NULL) lua_error(L, "unable to create new thread"); |
| 428 | /* move function from L to NL */ | 439 | /* move function and arguments from L to NL */ |
| 429 | ref = lua_ref(L, 1); | 440 | for (i=0; i<n; i++) { |
| 430 | lua_getref(NL, ref); | 441 | ref = lua_ref(L, 1); |
| 431 | lua_unref(L, ref); | 442 | lua_getref(NL, ref); |
| 432 | lua_cobegin(NL, 0); | 443 | lua_insert(NL, 1); |
| 444 | lua_unref(L, ref); | ||
| 445 | } | ||
| 446 | lua_cobegin(NL, n-1); | ||
| 433 | lua_newuserdatabox(L, NL); | 447 | lua_newuserdatabox(L, NL); |
| 448 | lua_getstr(L, LUA_REGISTRYINDEX, "Coroutine"); | ||
| 449 | lua_seteventtable(L, -2); | ||
| 434 | lua_pushcclosure(L, luaB_resume, 1); | 450 | lua_pushcclosure(L, luaB_resume, 1); |
| 435 | return 1; | 451 | return 1; |
| 436 | } | 452 | } |
| 437 | 453 | ||
| 438 | 454 | ||
| 439 | static int luaB_yield (lua_State *L) { | 455 | static int luaB_yield (lua_State *L) { |
| 440 | return lua_yield(L, 0); | 456 | return lua_yield(L, lua_gettop(L)); |
| 441 | } | 457 | } |
| 442 | 458 | ||
| 443 | 459 | ||
| @@ -683,6 +699,11 @@ LUALIB_API int lua_baselibopen (lua_State *L) { | |||
| 683 | lua_newtable(L); | 699 | lua_newtable(L); |
| 684 | lua_pushcclosure(L, luaB_require, 1); | 700 | lua_pushcclosure(L, luaB_require, 1); |
| 685 | lua_setglobal(L, "require"); | 701 | lua_setglobal(L, "require"); |
| 702 | /* create metatable for coroutines */ | ||
| 703 | lua_newtable(L); | ||
| 704 | lua_pushcfunction(L, gc_coroutine); | ||
| 705 | lua_setstr(L, -2, "gc"); | ||
| 706 | lua_setstr(L, LUA_REGISTRYINDEX, "Coroutine"); | ||
| 686 | return 0; | 707 | return 0; |
| 687 | } | 708 | } |
| 688 | 709 | ||
