aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--lbaselib.c149
-rw-r--r--lcorolib.c154
-rw-r--r--linit.c3
-rw-r--r--ltests.c3
-rw-r--r--lualib.h6
-rw-r--r--makefile7
6 files changed, 169 insertions, 153 deletions
diff --git a/lbaselib.c b/lbaselib.c
index d9669dfc..d28708af 100644
--- a/lbaselib.c
+++ b/lbaselib.c
@@ -1,5 +1,5 @@
1/* 1/*
2** $Id: lbaselib.c,v 1.242 2010/04/19 16:36:06 roberto Exp roberto $ 2** $Id: lbaselib.c,v 1.243 2010/04/19 17:02:02 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*/
@@ -500,144 +500,7 @@ static const luaL_Reg base_funcs[] = {
500}; 500};
501 501
502 502
503/* 503LUAMOD_API int luaopen_base (lua_State *L) {
504** {======================================================
505** Coroutine library
506** =======================================================
507*/
508
509static int auxresume (lua_State *L, lua_State *co, int narg) {
510 int status;
511 if (!lua_checkstack(co, narg)) {
512 lua_pushliteral(L, "too many arguments to resume");
513 return -1; /* error flag */
514 }
515 if (lua_status(co) == LUA_OK && lua_gettop(co) == 0) {
516 lua_pushliteral(L, "cannot resume dead coroutine");
517 return -1; /* error flag */
518 }
519 lua_xmove(L, co, narg);
520 status = lua_resume(co, narg);
521 if (status == LUA_OK || status == LUA_YIELD) {
522 int nres = lua_gettop(co);
523 if (!lua_checkstack(L, nres + 1)) {
524 lua_pop(co, nres); /* remove results anyway */
525 lua_pushliteral(L, "too many results to resume");
526 return -1; /* error flag */
527 }
528 lua_xmove(co, L, nres); /* move yielded values */
529 return nres;
530 }
531 else {
532 lua_xmove(co, L, 1); /* move error message */
533 return -1; /* error flag */
534 }
535}
536
537
538static int luaB_coresume (lua_State *L) {
539 lua_State *co = lua_tothread(L, 1);
540 int r;
541 luaL_argcheck(L, co, 1, "coroutine expected");
542 r = auxresume(L, co, lua_gettop(L) - 1);
543 if (r < 0) {
544 lua_pushboolean(L, 0);
545 lua_insert(L, -2);
546 return 2; /* return false + error message */
547 }
548 else {
549 lua_pushboolean(L, 1);
550 lua_insert(L, -(r + 1));
551 return r + 1; /* return true + `resume' returns */
552 }
553}
554
555
556static int luaB_auxwrap (lua_State *L) {
557 lua_State *co = lua_tothread(L, lua_upvalueindex(1));
558 int r = auxresume(L, co, lua_gettop(L));
559 if (r < 0) {
560 if (lua_isstring(L, -1)) { /* error object is a string? */
561 luaL_where(L, 1); /* add extra info */
562 lua_insert(L, -2);
563 lua_concat(L, 2);
564 }
565 lua_error(L); /* propagate error */
566 }
567 return r;
568}
569
570
571static int luaB_cocreate (lua_State *L) {
572 lua_State *NL = lua_newthread(L);
573 luaL_checktype(L, 1, LUA_TFUNCTION);
574 lua_pushvalue(L, 1); /* move function to top */
575 lua_xmove(L, NL, 1); /* move function from L to NL */
576 return 1;
577}
578
579
580static int luaB_cowrap (lua_State *L) {
581 luaB_cocreate(L);
582 lua_pushcclosure(L, luaB_auxwrap, 1);
583 return 1;
584}
585
586
587static int luaB_yield (lua_State *L) {
588 return lua_yield(L, lua_gettop(L));
589}
590
591
592static int luaB_costatus (lua_State *L) {
593 lua_State *co = lua_tothread(L, 1);
594 luaL_argcheck(L, co, 1, "coroutine expected");
595 if (L == co) lua_pushliteral(L, "running");
596 else {
597 switch (lua_status(co)) {
598 case LUA_YIELD:
599 lua_pushliteral(L, "suspended");
600 break;
601 case LUA_OK: {
602 lua_Debug ar;
603 if (lua_getstack(co, 0, &ar) > 0) /* does it have frames? */
604 lua_pushliteral(L, "normal"); /* it is running */
605 else if (lua_gettop(co) == 0)
606 lua_pushliteral(L, "dead");
607 else
608 lua_pushliteral(L, "suspended"); /* initial state */
609 break;
610 }
611 default: /* some error occurred */
612 lua_pushliteral(L, "dead");
613 break;
614 }
615 }
616 return 1;
617}
618
619
620static int luaB_corunning (lua_State *L) {
621 int ismain = lua_pushthread(L);
622 lua_pushboolean(L, ismain);
623 return 2;
624}
625
626
627static const luaL_Reg co_funcs[] = {
628 {"create", luaB_cocreate},
629 {"resume", luaB_coresume},
630 {"running", luaB_corunning},
631 {"status", luaB_costatus},
632 {"wrap", luaB_cowrap},
633 {"yield", luaB_yield},
634 {NULL, NULL}
635};
636
637/* }====================================================== */
638
639
640static void base_open (lua_State *L) {
641 /* set global _G */ 504 /* set global _G */
642 lua_pushglobaltable(L); 505 lua_pushglobaltable(L);
643 lua_pushglobaltable(L); 506 lua_pushglobaltable(L);
@@ -654,12 +517,6 @@ static void base_open (lua_State *L) {
654 lua_setfield(L, -2, "__mode"); /* metatable(w).__mode = "kv" */ 517 lua_setfield(L, -2, "__mode"); /* metatable(w).__mode = "kv" */
655 lua_pushcclosure(L, luaB_newproxy, 1); 518 lua_pushcclosure(L, luaB_newproxy, 1);
656 lua_setfield(L, -2, "newproxy"); /* set global `newproxy' */ 519 lua_setfield(L, -2, "newproxy"); /* set global `newproxy' */
657} 520 return 1;
658
659
660LUAMOD_API int luaopen_base (lua_State *L) {
661 base_open(L);
662 luaL_register(L, LUA_COLIBNAME, co_funcs);
663 return 2;
664} 521}
665 522
diff --git a/lcorolib.c b/lcorolib.c
new file mode 100644
index 00000000..fdcbc6de
--- /dev/null
+++ b/lcorolib.c
@@ -0,0 +1,154 @@
1/*
2** $Id: lcorolib.c,v $
3** Coroutine Library
4** See Copyright Notice in lua.h
5*/
6
7
8#include <stdlib.h>
9
10
11#define lcorolib_c
12#define LUA_LIB
13
14#include "lua.h"
15
16#include "lauxlib.h"
17#include "lualib.h"
18
19
20static int auxresume (lua_State *L, lua_State *co, int narg) {
21 int status;
22 if (!lua_checkstack(co, narg)) {
23 lua_pushliteral(L, "too many arguments to resume");
24 return -1; /* error flag */
25 }
26 if (lua_status(co) == LUA_OK && lua_gettop(co) == 0) {
27 lua_pushliteral(L, "cannot resume dead coroutine");
28 return -1; /* error flag */
29 }
30 lua_xmove(L, co, narg);
31 status = lua_resume(co, narg);
32 if (status == LUA_OK || status == LUA_YIELD) {
33 int nres = lua_gettop(co);
34 if (!lua_checkstack(L, nres + 1)) {
35 lua_pop(co, nres); /* remove results anyway */
36 lua_pushliteral(L, "too many results to resume");
37 return -1; /* error flag */
38 }
39 lua_xmove(co, L, nres); /* move yielded values */
40 return nres;
41 }
42 else {
43 lua_xmove(co, L, 1); /* move error message */
44 return -1; /* error flag */
45 }
46}
47
48
49static int luaB_coresume (lua_State *L) {
50 lua_State *co = lua_tothread(L, 1);
51 int r;
52 luaL_argcheck(L, co, 1, "coroutine expected");
53 r = auxresume(L, co, lua_gettop(L) - 1);
54 if (r < 0) {
55 lua_pushboolean(L, 0);
56 lua_insert(L, -2);
57 return 2; /* return false + error message */
58 }
59 else {
60 lua_pushboolean(L, 1);
61 lua_insert(L, -(r + 1));
62 return r + 1; /* return true + `resume' returns */
63 }
64}
65
66
67static int luaB_auxwrap (lua_State *L) {
68 lua_State *co = lua_tothread(L, lua_upvalueindex(1));
69 int r = auxresume(L, co, lua_gettop(L));
70 if (r < 0) {
71 if (lua_isstring(L, -1)) { /* error object is a string? */
72 luaL_where(L, 1); /* add extra info */
73 lua_insert(L, -2);
74 lua_concat(L, 2);
75 }
76 lua_error(L); /* propagate error */
77 }
78 return r;
79}
80
81
82static int luaB_cocreate (lua_State *L) {
83 lua_State *NL = lua_newthread(L);
84 luaL_checktype(L, 1, LUA_TFUNCTION);
85 lua_pushvalue(L, 1); /* move function to top */
86 lua_xmove(L, NL, 1); /* move function from L to NL */
87 return 1;
88}
89
90
91static int luaB_cowrap (lua_State *L) {
92 luaB_cocreate(L);
93 lua_pushcclosure(L, luaB_auxwrap, 1);
94 return 1;
95}
96
97
98static int luaB_yield (lua_State *L) {
99 return lua_yield(L, lua_gettop(L));
100}
101
102
103static int luaB_costatus (lua_State *L) {
104 lua_State *co = lua_tothread(L, 1);
105 luaL_argcheck(L, co, 1, "coroutine expected");
106 if (L == co) lua_pushliteral(L, "running");
107 else {
108 switch (lua_status(co)) {
109 case LUA_YIELD:
110 lua_pushliteral(L, "suspended");
111 break;
112 case LUA_OK: {
113 lua_Debug ar;
114 if (lua_getstack(co, 0, &ar) > 0) /* does it have frames? */
115 lua_pushliteral(L, "normal"); /* it is running */
116 else if (lua_gettop(co) == 0)
117 lua_pushliteral(L, "dead");
118 else
119 lua_pushliteral(L, "suspended"); /* initial state */
120 break;
121 }
122 default: /* some error occurred */
123 lua_pushliteral(L, "dead");
124 break;
125 }
126 }
127 return 1;
128}
129
130
131static int luaB_corunning (lua_State *L) {
132 int ismain = lua_pushthread(L);
133 lua_pushboolean(L, ismain);
134 return 2;
135}
136
137
138static const luaL_Reg co_funcs[] = {
139 {"create", luaB_cocreate},
140 {"resume", luaB_coresume},
141 {"running", luaB_corunning},
142 {"status", luaB_costatus},
143 {"wrap", luaB_cowrap},
144 {"yield", luaB_yield},
145 {NULL, NULL}
146};
147
148
149
150LUAMOD_API int luaopen_coroutine (lua_State *L) {
151 luaL_register(L, LUA_COLIBNAME, co_funcs);
152 return 1;
153}
154
diff --git a/linit.c b/linit.c
index 2e9fb0b9..99c33e92 100644
--- a/linit.c
+++ b/linit.c
@@ -1,5 +1,5 @@
1/* 1/*
2** $Id: linit.c,v 1.24 2010/03/26 20:58:11 roberto Exp roberto $ 2** $Id: linit.c,v 1.25 2010/05/20 12:57:59 roberto Exp roberto $
3** Initialization of libraries for lua.c and other clients 3** Initialization of libraries for lua.c and other clients
4** See Copyright Notice in lua.h 4** See Copyright Notice in lua.h
5*/ 5*/
@@ -29,6 +29,7 @@
29static const luaL_Reg loadedlibs[] = { 29static const luaL_Reg loadedlibs[] = {
30 {"_G", luaopen_base}, 30 {"_G", luaopen_base},
31 {LUA_LOADLIBNAME, luaopen_package}, 31 {LUA_LOADLIBNAME, luaopen_package},
32 {LUA_COLIBNAME, luaopen_coroutine},
32 {LUA_TABLIBNAME, luaopen_table}, 33 {LUA_TABLIBNAME, luaopen_table},
33 {LUA_IOLIBNAME, luaopen_io}, 34 {LUA_IOLIBNAME, luaopen_io},
34 {LUA_OSLIBNAME, luaopen_os}, 35 {LUA_OSLIBNAME, luaopen_os},
diff --git a/ltests.c b/ltests.c
index 4b60bd2a..2b38b5e0 100644
--- a/ltests.c
+++ b/ltests.c
@@ -1,5 +1,5 @@
1/* 1/*
2** $Id: ltests.c,v 2.107 2010/05/14 13:15:54 roberto Exp roberto $ 2** $Id: ltests.c,v 2.108 2010/05/17 20:10:17 roberto Exp roberto $
3** Internal Module for Debugging of the Lua Implementation 3** Internal Module for Debugging of the Lua Implementation
4** See Copyright Notice in lua.h 4** See Copyright Notice in lua.h
5*/ 5*/
@@ -842,6 +842,7 @@ static lua_State *getstate (lua_State *L) {
842static int loadlib (lua_State *L) { 842static int loadlib (lua_State *L) {
843 static const luaL_Reg libs[] = { 843 static const luaL_Reg libs[] = {
844 {"baselibopen", luaopen_base}, 844 {"baselibopen", luaopen_base},
845 {"corolibopen", luaopen_coroutine},
845 {"dblibopen", luaopen_debug}, 846 {"dblibopen", luaopen_debug},
846 {"iolibopen", luaopen_io}, 847 {"iolibopen", luaopen_io},
847 {"mathlibopen", luaopen_math}, 848 {"mathlibopen", luaopen_math},
diff --git a/lualib.h b/lualib.h
index 178083c5..5c5d0a9c 100644
--- a/lualib.h
+++ b/lualib.h
@@ -1,5 +1,5 @@
1/* 1/*
2** $Id: lualib.h,v 1.38 2009/07/01 16:16:40 roberto Exp roberto $ 2** $Id: lualib.h,v 1.39 2009/11/24 12:05:44 roberto Exp roberto $
3** Lua standard libraries 3** Lua standard libraries
4** See Copyright Notice in lua.h 4** See Copyright Notice in lua.h
5*/ 5*/
@@ -15,9 +15,11 @@
15#define LUA_FILEHANDLE "FILE*" 15#define LUA_FILEHANDLE "FILE*"
16 16
17 17
18#define LUA_COLIBNAME "coroutine"
19LUAMOD_API int (luaopen_base) (lua_State *L); 18LUAMOD_API int (luaopen_base) (lua_State *L);
20 19
20#define LUA_COLIBNAME "coroutine"
21LUAMOD_API int (luaopen_coroutine) (lua_State *L);
22
21#define LUA_TABLIBNAME "table" 23#define LUA_TABLIBNAME "table"
22LUAMOD_API int (luaopen_table) (lua_State *L); 24LUAMOD_API int (luaopen_table) (lua_State *L);
23 25
diff --git a/makefile b/makefile
index 00fe2b2e..1e6dcb0e 100644
--- a/makefile
+++ b/makefile
@@ -67,7 +67,7 @@ CORE_O= lapi.o lcode.o lctype.o ldebug.o ldo.o ldump.o lfunc.o lgc.o llex.o \
67 ltm.o lundump.o lvm.o lzio.o ltests.o 67 ltm.o lundump.o lvm.o lzio.o ltests.o
68AUX_O= lauxlib.o 68AUX_O= lauxlib.o
69LIB_O= lbaselib.o ldblib.o liolib.o lmathlib.o loslib.o ltablib.o lstrlib.o \ 69LIB_O= lbaselib.o ldblib.o liolib.o lmathlib.o loslib.o ltablib.o lstrlib.o \
70 lbitlib.o loadlib.o linit.o 70 lbitlib.o loadlib.o lcorolib.o linit.o
71 71
72LUA_T= lua 72LUA_T= lua
73LUA_O= lua.o 73LUA_O= lua.o
@@ -126,6 +126,7 @@ lbitlib.o: lbitlib.c lua.h luaconf.h lauxlib.h lualib.h
126lcode.o: lcode.c lua.h luaconf.h lcode.h llex.h lobject.h llimits.h \ 126lcode.o: lcode.c lua.h luaconf.h lcode.h llex.h lobject.h llimits.h \
127 lzio.h lmem.h lopcodes.h lparser.h ldebug.h lstate.h ltm.h ldo.h lgc.h \ 127 lzio.h lmem.h lopcodes.h lparser.h ldebug.h lstate.h ltm.h ldo.h lgc.h \
128 lstring.h ltable.h 128 lstring.h ltable.h
129lcorolib.o: lcorolib.c lua.h luaconf.h lauxlib.h lualib.h
129lctype.o: lctype.c lctype.h lua.h luaconf.h llimits.h 130lctype.o: lctype.c lctype.h lua.h luaconf.h llimits.h
130ldblib.o: ldblib.c lua.h luaconf.h lauxlib.h lualib.h 131ldblib.o: ldblib.c lua.h luaconf.h lauxlib.h lualib.h
131ldebug.o: ldebug.c lua.h luaconf.h lapi.h llimits.h lstate.h lobject.h \ 132ldebug.o: ldebug.c lua.h luaconf.h lapi.h llimits.h lstate.h lobject.h \
@@ -136,8 +137,8 @@ ldo.o: ldo.c lua.h luaconf.h lapi.h llimits.h lstate.h lobject.h ltm.h \
136 lstring.h ltable.h lundump.h lvm.h 137 lstring.h ltable.h lundump.h lvm.h
137ldump.o: ldump.c lua.h luaconf.h lobject.h llimits.h lstate.h ltm.h \ 138ldump.o: ldump.c lua.h luaconf.h lobject.h llimits.h lstate.h ltm.h \
138 lzio.h lmem.h lundump.h 139 lzio.h lmem.h lundump.h
139lfunc.o: lfunc.c lua.h luaconf.h lfunc.h lobject.h llimits.h lgc.h lmem.h \ 140lfunc.o: lfunc.c lua.h luaconf.h lfunc.h lobject.h llimits.h lgc.h \
140 lopcodes.h lstate.h ltm.h lzio.h 141 lstate.h ltm.h lzio.h lmem.h
141lgc.o: lgc.c lua.h luaconf.h ldebug.h lstate.h lobject.h llimits.h ltm.h \ 142lgc.o: lgc.c lua.h luaconf.h ldebug.h lstate.h lobject.h llimits.h ltm.h \
142 lzio.h lmem.h ldo.h lfunc.h lgc.h lstring.h ltable.h 143 lzio.h lmem.h ldo.h lfunc.h lgc.h lstring.h ltable.h
143linit.o: linit.c lua.h luaconf.h lualib.h lauxlib.h 144linit.o: linit.c lua.h luaconf.h lualib.h lauxlib.h