リビジョン | 2458337550003bc3b360ed7d0fb01296d9a7dc8b (tree) |
---|---|
日時 | 2018-10-12 13:28:37 |
作者 | Agustina Arzille <avarzille@rise...> |
コミッター | Agustina Arzille |
Rename continuations as generators
@@ -1,7 +1,7 @@ | ||
1 | 1 | CXXFLAGS += -Wall -g -D_GNU_SOURCE -D_LARGEFILE_SOURCE -std=c++11 |
2 | 2 | |
3 | 3 | HEADERS = arith.h array.h builtins.h bvector.h bytecode.h config.h \ |
4 | - cons.h continuation.h defs.h event.h floatp.h function.h \ | |
4 | + cons.h generator.h defs.h event.h floatp.h function.h \ | |
5 | 5 | initop.h integer.h interp.h io.h memory.h module.h quipu.h \ |
6 | 6 | stream.h str.h symbol.h table.h thread.h tree.h xtime.h \ |
7 | 7 | sysdeps/atomic.h utils/chmask.h utils/dlist.h utils/raw_acc.h \ |
@@ -9,7 +9,7 @@ | ||
9 | 9 | |
10 | 10 | OBJS = quipu.o arith.o integer.o floatp.o memory.o stream.o str.o \ |
11 | 11 | module.o bvector.o table.o array.o cons.o thread.o interp.o misc.o \ |
12 | - symbol.o tree.o io.o builtins.o xtime.o function.o continuation.o \ | |
12 | + symbol.o tree.o io.o builtins.o xtime.o function.o generator.o \ | |
13 | 13 | bytecode.o event.o initop.o compiler.o eval.o |
14 | 14 | |
15 | 15 | LIBS = -lm -ldl -lpthread |
@@ -37,7 +37,7 @@ | ||
37 | 37 | DISPATCH (TREE, o); |
38 | 38 | DISPATCH (SYMBOL, S); |
39 | 39 | DISPATCH (FCT, x); |
40 | - DISPATCH (CONTINUATION, C); | |
40 | + DISPATCH (GENERATOR, G); | |
41 | 41 | DISPATCH (PKG, P); |
42 | 42 | default: |
43 | 43 | // XXX: Other objects. |
@@ -124,7 +124,7 @@ | ||
124 | 124 | DISPATCH (TREE, o); |
125 | 125 | DISPATCH (SYMBOL, S); |
126 | 126 | DISPATCH (FCT, x); |
127 | - DISPATCH (CONTINUATION, C); | |
127 | + DISPATCH (GENERATOR, G); | |
128 | 128 | DISPATCH (PKG, P); |
129 | 129 | default: |
130 | 130 | // XXX: Other objects. |
@@ -202,7 +202,7 @@ | ||
202 | 202 | DISPATCH (TREE, o); |
203 | 203 | DISPATCH (SYMBOL, S); |
204 | 204 | DISPATCH (FCT, x); |
205 | - DISPATCH (CONTINUATION, C); | |
205 | + DISPATCH (GENERATOR, G); | |
206 | 206 | DISPATCH (PKG, P); |
207 | 207 | default: |
208 | 208 | // XXX: Other objects. |
@@ -1393,7 +1393,7 @@ | ||
1393 | 1393 | // XXX: stream_p |
1394 | 1394 | TYPE_P (symbol, SYMBOL) |
1395 | 1395 | TYPE_P (fct, FCT) |
1396 | -TYPE_P (continuation, CONTINUATION) | |
1396 | +TYPE_P (generator, GENERATOR) | |
1397 | 1397 | TYPE_P (thread, THREAD) |
1398 | 1398 | TYPE_P (lock, LOCK) |
1399 | 1399 | TYPE_P (condvar, CONDVAR) |
@@ -1409,10 +1409,10 @@ | ||
1409 | 1409 | interp->raise_nargs ("iter-val", 1, 1, argc); |
1410 | 1410 | |
1411 | 1411 | object cn = *argv; |
1412 | - if (!continuation_p (cn)) | |
1412 | + if (!generator_p (cn)) | |
1413 | 1413 | interp->raise2 ("arg-error", "iter-val: argument must be a generator"); |
1414 | 1414 | |
1415 | - qp_return (as_continuation(cn)->value); | |
1415 | + qp_return (as_generator(cn)->value); | |
1416 | 1416 | } |
1417 | 1417 | |
1418 | 1418 | DEFBUILTIN (symname_fct) |
@@ -1479,7 +1479,7 @@ | ||
1479 | 1479 | "tree-p\0" |
1480 | 1480 | "symbol-p\0" |
1481 | 1481 | "fct-p\0" |
1482 | - "continuation-p\0" | |
1482 | + "generator-p\0" | |
1483 | 1483 | "thread-p\0" |
1484 | 1484 | "lock-p\0" |
1485 | 1485 | "condvar-p\0" |
@@ -1547,7 +1547,7 @@ | ||
1547 | 1547 | tree_pred, |
1548 | 1548 | symbol_pred, |
1549 | 1549 | fct_pred, |
1550 | - continuation_pred, | |
1550 | + generator_pred, | |
1551 | 1551 | thread_pred, |
1552 | 1552 | lock_pred, |
1553 | 1553 | condvar_pred, |
@@ -1,156 +0,0 @@ | ||
1 | -#include "continuation.h" | |
2 | -#include "memory.h" | |
3 | -#include "array.h" | |
4 | -#include "integer.h" | |
5 | -#include "function.h" | |
6 | -#include "stream.h" | |
7 | -#include "io.h" | |
8 | - | |
9 | -QP_DECLS_BEGIN | |
10 | - | |
11 | -static object | |
12 | -make_argv (interpreter *interp, uint32_t ilastf, continuation *outp) | |
13 | -{ | |
14 | - uint32_t start = ilastf - as_int (interp->stack[ilastf - 3]) - | |
15 | - interpreter::frame_size - 1; | |
16 | - uint32_t sp = interp->stklen (); | |
17 | - | |
18 | - outp->sframes[1] = interp->cur_frame - ilastf; | |
19 | - uint32_t max_sp = as_fct(interp->stack[start])->max_sp; | |
20 | - | |
21 | - array *ap = as_array (alloc_array (interp, | |
22 | - max (sp - start, max_sp), UNBOUND)); | |
23 | - copy_objs (ap->data, interp->stack + start, sp - start); | |
24 | - | |
25 | - for (uint32_t cf = interp->cur_frame ; ; ) | |
26 | - { | |
27 | - if (cf == ilastf) | |
28 | - { | |
29 | - outp->sframes[0] = cf - start; | |
30 | - ap->data[cf - start - 4] = intobj (0); | |
31 | - break; | |
32 | - } | |
33 | - | |
34 | - uint32_t ipos = cf - start; | |
35 | - uint32_t prev = as_int (interp->stack[cf - 4]); | |
36 | - ap->data[ipos - 4] = intobj (prev - start); | |
37 | - cf = prev; | |
38 | - } | |
39 | - | |
40 | - outp->sframes[1] += outp->sframes[0]; | |
41 | - return (ap->as_obj ()); | |
42 | -} | |
43 | - | |
44 | -struct cont_state | |
45 | -{ | |
46 | - interpreter *interp; | |
47 | - object stkobj; | |
48 | - uint32_t cf; | |
49 | - uint32_t sp; | |
50 | - | |
51 | - cont_state (interpreter *ip) : interp (ip), | |
52 | - stkobj (ip->stkobj), cf (ip->cur_frame), sp (ip->stklen ()) {} | |
53 | - | |
54 | - ~cont_state () | |
55 | - { | |
56 | - this->interp->stkobj = this->stkobj; | |
57 | - this->interp->stack = &xaref(this->stkobj, 0); | |
58 | - this->interp->stkend = this->interp->stack + this->sp; | |
59 | - this->interp->cur_frame = this->cf; | |
60 | - } | |
61 | -}; | |
62 | - | |
63 | -object iter_next (interpreter *interp, object *argv, int argc) | |
64 | -{ | |
65 | - if (argc != 1) | |
66 | - interp->raise_nargs ("iter-next", 1, 1, argc); | |
67 | - | |
68 | - object cn = *argv; | |
69 | - if (!continuation_p (cn)) | |
70 | - interp->raise2 ("arg-error", "iter-next: argument must be a generator"); | |
71 | - | |
72 | - continuation *cnp = as_continuation (cn); | |
73 | - | |
74 | - try | |
75 | - { // XXX: Implement chained backtraces instead. | |
76 | - cont_state state (interp); | |
77 | - interp->stkobj = cnp->argv; | |
78 | - interp->stack = &xaref(interp->stkobj, 0); | |
79 | - interp->cur_frame = 0; | |
80 | - interp->stkend = interp->stack + cnp->sframes[1] + cnp->sp_diff; | |
81 | - object ret = call_continuation (interp, cn); | |
82 | - qp_return (continuation_p (ret) ? ret : NIL); | |
83 | - } | |
84 | - catch (...) | |
85 | - { | |
86 | - if (interp->throw_frame != 0) | |
87 | - interp->throw_frame = interp->cur_frame; | |
88 | - | |
89 | - throw; | |
90 | - } | |
91 | -} | |
92 | - | |
93 | -continuation* continuation::alloc_raw () | |
94 | -{ | |
95 | - continuation *retp = (continuation *)alloch | |
96 | - (sizeof (*retp), typecode::CONTINUATION); | |
97 | - | |
98 | - retp->value = retp->argv = NIL; | |
99 | - return (retp); | |
100 | -} | |
101 | - | |
102 | -object alloc_continuation (interpreter *interp) | |
103 | -{ | |
104 | - continuation *retp = continuation::alloc_raw (); | |
105 | - interp->alval = retp->as_obj (); | |
106 | - gcregister (interp, retp); | |
107 | - return (interp->alval); | |
108 | -} | |
109 | - | |
110 | -object continuation::make (interpreter *interp, uint32_t lastf) | |
111 | -{ | |
112 | - evh_guard eg (interp); | |
113 | - continuation *ret = alloc_raw (); | |
114 | - ret->value = UNBOUND; | |
115 | - | |
116 | - ret->argv = make_argv (interp, lastf, ret); | |
117 | - interp->alval = ret->as_obj (); | |
118 | - gcregister (interp, ret); | |
119 | - return (interp->alval); | |
120 | -} | |
121 | - | |
122 | -int write_C (interpreter *interp, stream *strm, object obj, io_info&) | |
123 | -{ | |
124 | - char buf[100]; | |
125 | - return (strm->write (interp, buf, | |
126 | - sprintf (buf, "#<continuation at %p>", maskp (obj)))); | |
127 | -} | |
128 | - | |
129 | -int serialize_C (interpreter *interp, stream *strm, | |
130 | - object obj, serial_info& info) | |
131 | -{ | |
132 | - continuation *cnp = as_continuation (obj); | |
133 | - return (strm->write (interp, &cnp->ip_offset) + | |
134 | - strm->write (interp, &cnp->sp_diff) + | |
135 | - strm->write (interp, cnp->sframes, sizeof (cnp->sframes)) + | |
136 | - xserialize (interp, strm, cnp->value, info) + | |
137 | - xserialize (interp, strm, cnp->argv, info)); | |
138 | -} | |
139 | - | |
140 | -object deserialize_C (interpreter *interp, stream *strm, serial_info& info) | |
141 | -{ | |
142 | - valref ret (interp, alloc_continuation (interp)); | |
143 | - continuation *cnp = as_continuation (*ret); | |
144 | - | |
145 | - if (!strm->sread (interp, &cnp->ip_offset) || | |
146 | - !strm->sread (interp, &cnp->sp_diff) || | |
147 | - strm->read (interp, cnp->sframes, sizeof (cnp->sframes)) != | |
148 | - (int)sizeof (cnp->sframes) || | |
149 | - (cnp->value = xdeserialize (interp, strm, info)) == UNBOUND || | |
150 | - !array_p (cnp->argv = xdeserialize (interp, strm, info))) | |
151 | - qp_return (UNBOUND); | |
152 | - | |
153 | - qp_return (*ret); | |
154 | -} | |
155 | - | |
156 | -QP_DECLS_END |
@@ -1,51 +0,0 @@ | ||
1 | -#ifndef __QP_CONTINUATION_H__ | |
2 | -#define __QP_CONTINUATION_H__ 1 | |
3 | - | |
4 | -#include "interp.h" | |
5 | - | |
6 | -QP_DECLS_BEGIN | |
7 | - | |
8 | -struct continuation : public varobj | |
9 | -{ | |
10 | - static continuation* alloc_raw (); | |
11 | - static object make (interpreter *__interp, uint32_t __lastf); | |
12 | - | |
13 | - object value; | |
14 | - object argv; | |
15 | - int ip_offset; | |
16 | - int sp_diff; | |
17 | - uint32_t sframes[2]; | |
18 | -}; | |
19 | - | |
20 | -inline bool continuation_p (object __obj) | |
21 | -{ | |
22 | - return (itype (__obj) == typecode::CONTINUATION); | |
23 | -} | |
24 | - | |
25 | -inline continuation* as_continuation (object __obj) | |
26 | -{ | |
27 | - return ((continuation *)maskp (__obj)); | |
28 | -} | |
29 | - | |
30 | -QP_EXPORT object alloc_continuation (interpreter *__interp); | |
31 | - | |
32 | -QP_EXPORT object call_continuation (interpreter *__interp, object __cont); | |
33 | - | |
34 | -QP_EXPORT object iter_next (interpreter *__interp, object *__argv, int __argc); | |
35 | - | |
36 | -struct stream; | |
37 | -struct io_info; | |
38 | -struct serial_info; | |
39 | - | |
40 | -QP_EXPORT int write_C (interpreter *__interp, | |
41 | - stream *__strm, object __obj, io_info& __info); | |
42 | - | |
43 | -QP_EXPORT int serialize_C (interpreter *__interp, | |
44 | - stream *__strm, object __obj, serial_info& __info); | |
45 | - | |
46 | -QP_EXPORT object deserialize_C (interpreter *__interp, | |
47 | - stream *__strm, serial_info& __info); | |
48 | - | |
49 | -QP_DECLS_END | |
50 | - | |
51 | -#endif |
@@ -37,7 +37,7 @@ | ||
37 | 37 | STREAM, |
38 | 38 | SYMBOL, |
39 | 39 | FCT, |
40 | - CONTINUATION, | |
40 | + GENERATOR, | |
41 | 41 | THREAD, |
42 | 42 | LOCK, |
43 | 43 | CONDVAR, |
@@ -240,7 +240,7 @@ | ||
240 | 240 | |
241 | 241 | static object __attribute__((hot)) |
242 | 242 | run_bytecode (interpreter *interp, uint32_t nargs, |
243 | - object cont = UNBOUND, const call_data *cdp = 0) | |
243 | + object gen = UNBOUND, const call_data *cdp = 0) | |
244 | 244 | { |
245 | 245 | uint32_t lastf, top_frame = interp->cur_frame; |
246 | 246 | uint32_t n = 0, bp, ix; |
@@ -293,15 +293,15 @@ | ||
293 | 293 | fn = stack[bp - 1]; |
294 | 294 | ip = as_bvector(fct_bcode (fn))->data + cdp->ip_offset; |
295 | 295 | } |
296 | - else if (cont != UNBOUND) | |
296 | + else if (gen != UNBOUND) | |
297 | 297 | { // Continuation-passing style. |
298 | - continuation *cnp = as_continuation (cont); | |
299 | - lastf = cnp->sframes[0]; | |
300 | - interp->cur_frame = cnp->sframes[1]; | |
298 | + generator *gp = as_generator (gen); | |
299 | + lastf = gp->sframes[0]; | |
300 | + interp->cur_frame = gp->sframes[1]; | |
301 | 301 | nargs = as_int (stack[lastf - 3]); |
302 | 302 | bp = 1, fn = stack[bp - 1]; |
303 | - ip = as_bvector(fct_bcode (fn))->data + cnp->ip_offset; | |
304 | - U_PUSH (cnp->value); | |
303 | + ip = as_bvector(fct_bcode (fn))->data + gp->ip_offset; | |
304 | + U_PUSH (gp->value); | |
305 | 305 | } |
306 | 306 | else |
307 | 307 | { // Regular function call. |
@@ -394,7 +394,7 @@ | ||
394 | 394 | if (native_fct_p (fn)) |
395 | 395 | { |
396 | 396 | as_native_fct(fn)->call (interp, n); |
397 | - stkend -= n; | |
397 | + stack = interp->stack, stkend -= n; | |
398 | 398 | r_stkend(1) = retval; |
399 | 399 | NEXT_OP; |
400 | 400 | } |
@@ -409,7 +409,7 @@ | ||
409 | 409 | } |
410 | 410 | else if (call_sequence (interp, fn, n)) |
411 | 411 | { |
412 | - stkend -= n; | |
412 | + stack = interp->stack, stkend -= n; | |
413 | 413 | r_stkend(1) = retval; |
414 | 414 | NEXT_OP; |
415 | 415 | } |
@@ -429,7 +429,7 @@ | ||
429 | 429 | if (native_fct_p (fn)) |
430 | 430 | { |
431 | 431 | as_native_fct(fn)->call (interp, n); |
432 | - stkend -= n; | |
432 | + stack = interp->stack, stkend -= n; | |
433 | 433 | r_stkend(1) = retval; |
434 | 434 | NEXT_OP; |
435 | 435 | } |
@@ -441,7 +441,7 @@ | ||
441 | 441 | } |
442 | 442 | else if (call_sequence (interp, fn, n)) |
443 | 443 | { |
444 | - stkend -= n; | |
444 | + stack = interp->stack, stkend -= n; | |
445 | 445 | r_stkend(1) = retval; |
446 | 446 | NEXT_OP; |
447 | 447 | } |
@@ -813,25 +813,25 @@ | ||
813 | 813 | OP_(MKCONT): |
814 | 814 | { |
815 | 815 | interp->pop (); |
816 | - continuation *p; | |
816 | + generator *gp; | |
817 | 817 | |
818 | - if (cont != UNBOUND) | |
818 | + if (gen != UNBOUND) | |
819 | 819 | { // Update current continuation. |
820 | - p = as_continuation (cont); | |
821 | - p->argv = interp->stkobj; | |
822 | - p->sframes[1] = interp->cur_frame; | |
820 | + gp = as_generator (gen); | |
821 | + gp->argv = interp->stkobj; | |
822 | + gp->sframes[1] = interp->cur_frame; | |
823 | 823 | } |
824 | 824 | else |
825 | - p = as_continuation (continuation::make (interp, lastf)); | |
825 | + gp = as_generator (generator::make (interp, lastf)); | |
826 | 826 | |
827 | 827 | sx = *ip++; |
828 | 828 | |
829 | - p->ip_offset = sx + (ip - | |
829 | + gp->ip_offset = sx + (ip - | |
830 | 830 | as_bvector (fct_bcode(stack[bp - 1]))->data); |
831 | - p->value = retval; | |
832 | - p->sp_diff = interp->stklen () - interp->cur_frame; | |
831 | + gp->value = retval; | |
832 | + gp->sp_diff = interp->stklen () - interp->cur_frame; | |
833 | 833 | |
834 | - U_PUSH (p->as_obj ()); | |
834 | + U_PUSH (gp->as_obj ()); | |
835 | 835 | NEXT_OP; |
836 | 836 | } |
837 | 837 |
@@ -919,7 +919,7 @@ | ||
919 | 919 | } |
920 | 920 | |
921 | 921 | static object |
922 | -apply_n (interpreter *interp, uint32_t nargs, object cont = UNBOUND) | |
922 | +apply_n (interpreter *interp, uint32_t nargs, object gen = UNBOUND) | |
923 | 923 | { |
924 | 924 | call_data cd, *cdp = nullptr; |
925 | 925 | cd.topf = interp->cur_frame; |
@@ -928,7 +928,7 @@ | ||
928 | 928 | { |
929 | 929 | try |
930 | 930 | { |
931 | - return (run_bytecode (interp, nargs, cont, cdp)); | |
931 | + return (run_bytecode (interp, nargs, gen, cdp)); | |
932 | 932 | } |
933 | 933 | catch (object&) |
934 | 934 | { |
@@ -945,9 +945,9 @@ | ||
945 | 945 | } |
946 | 946 | } |
947 | 947 | |
948 | -object call_continuation (interpreter *interp, object cont) | |
948 | +object call_generator (interpreter *interp, object gen) | |
949 | 949 | { |
950 | - return (apply_n (interp, 0, cont)); | |
950 | + return (apply_n (interp, 0, gen)); | |
951 | 951 | } |
952 | 952 | |
953 | 953 | object call_n (interpreter *interp, uint32_t nargs) |
@@ -0,0 +1,156 @@ | ||
1 | +#include "generator.h" | |
2 | +#include "memory.h" | |
3 | +#include "array.h" | |
4 | +#include "integer.h" | |
5 | +#include "function.h" | |
6 | +#include "stream.h" | |
7 | +#include "io.h" | |
8 | + | |
9 | +QP_DECLS_BEGIN | |
10 | + | |
11 | +static object | |
12 | +make_argv (interpreter *interp, uint32_t ilastf, generator *outp) | |
13 | +{ | |
14 | + uint32_t start = ilastf - as_int (interp->stack[ilastf - 3]) - | |
15 | + interpreter::frame_size - 1; | |
16 | + uint32_t sp = interp->stklen (); | |
17 | + | |
18 | + outp->sframes[1] = interp->cur_frame - ilastf; | |
19 | + uint32_t max_sp = as_fct(interp->stack[start])->max_sp; | |
20 | + | |
21 | + array *ap = as_array (alloc_array (interp, | |
22 | + max (sp - start, max_sp), UNBOUND)); | |
23 | + copy_objs (ap->data, interp->stack + start, sp - start); | |
24 | + | |
25 | + for (uint32_t cf = interp->cur_frame ; ; ) | |
26 | + { | |
27 | + if (cf == ilastf) | |
28 | + { | |
29 | + outp->sframes[0] = cf - start; | |
30 | + ap->data[cf - start - 4] = intobj (0); | |
31 | + break; | |
32 | + } | |
33 | + | |
34 | + uint32_t ipos = cf - start; | |
35 | + uint32_t prev = as_int (interp->stack[cf - 4]); | |
36 | + ap->data[ipos - 4] = intobj (prev - start); | |
37 | + cf = prev; | |
38 | + } | |
39 | + | |
40 | + outp->sframes[1] += outp->sframes[0]; | |
41 | + return (ap->as_obj ()); | |
42 | +} | |
43 | + | |
44 | +struct gen_state | |
45 | +{ | |
46 | + interpreter *interp; | |
47 | + object stkobj; | |
48 | + uint32_t cf; | |
49 | + uint32_t sp; | |
50 | + | |
51 | + gen_state (interpreter *ip) : interp (ip), | |
52 | + stkobj (ip->stkobj), cf (ip->cur_frame), sp (ip->stklen ()) {} | |
53 | + | |
54 | + ~gen_state () | |
55 | + { | |
56 | + this->interp->stkobj = this->stkobj; | |
57 | + this->interp->stack = &xaref(this->stkobj, 0); | |
58 | + this->interp->stkend = this->interp->stack + this->sp; | |
59 | + this->interp->cur_frame = this->cf; | |
60 | + } | |
61 | +}; | |
62 | + | |
63 | +object iter_next (interpreter *interp, object *argv, int argc) | |
64 | +{ | |
65 | + if (argc != 1) | |
66 | + interp->raise_nargs ("iter-next", 1, 1, argc); | |
67 | + | |
68 | + object cn = *argv; | |
69 | + if (!generator_p (cn)) | |
70 | + interp->raise2 ("arg-error", "iter-next: argument must be a generator"); | |
71 | + | |
72 | + generator *gp = as_generator (cn); | |
73 | + | |
74 | + try | |
75 | + { // XXX: Implement chained backtraces instead. | |
76 | + gen_state state (interp); | |
77 | + interp->stkobj = gp->argv; | |
78 | + interp->stack = &xaref(interp->stkobj, 0); | |
79 | + interp->cur_frame = 0; | |
80 | + interp->stkend = interp->stack + gp->sframes[1] + gp->sp_diff; | |
81 | + object ret = call_generator (interp, cn); | |
82 | + qp_return (generator_p (ret) ? ret : NIL); | |
83 | + } | |
84 | + catch (...) | |
85 | + { | |
86 | + if (interp->throw_frame != 0) | |
87 | + interp->throw_frame = interp->cur_frame; | |
88 | + | |
89 | + throw; | |
90 | + } | |
91 | +} | |
92 | + | |
93 | +generator* generator::alloc_raw () | |
94 | +{ | |
95 | + generator *retp = (generator *)alloch | |
96 | + (sizeof (*retp), typecode::GENERATOR); | |
97 | + | |
98 | + retp->value = retp->argv = NIL; | |
99 | + return (retp); | |
100 | +} | |
101 | + | |
102 | +object alloc_generator (interpreter *interp) | |
103 | +{ | |
104 | + generator *retp = generator::alloc_raw (); | |
105 | + interp->alval = retp->as_obj (); | |
106 | + gcregister (interp, retp); | |
107 | + return (interp->alval); | |
108 | +} | |
109 | + | |
110 | +object generator::make (interpreter *interp, uint32_t lastf) | |
111 | +{ | |
112 | + evh_guard eg (interp); | |
113 | + generator *ret = alloc_raw (); | |
114 | + ret->value = UNBOUND; | |
115 | + | |
116 | + ret->argv = make_argv (interp, lastf, ret); | |
117 | + interp->alval = ret->as_obj (); | |
118 | + gcregister (interp, ret); | |
119 | + return (interp->alval); | |
120 | +} | |
121 | + | |
122 | +int write_G (interpreter *interp, stream *strm, object obj, io_info&) | |
123 | +{ | |
124 | + char buf[100]; | |
125 | + return (strm->write (interp, buf, | |
126 | + sprintf (buf, "#<generator at %p>", maskp (obj)))); | |
127 | +} | |
128 | + | |
129 | +int serialize_G (interpreter *interp, stream *strm, | |
130 | + object obj, serial_info& info) | |
131 | +{ | |
132 | + generator *gp = as_generator (obj); | |
133 | + return (strm->write (interp, &gp->ip_offset) + | |
134 | + strm->write (interp, &gp->sp_diff) + | |
135 | + strm->write (interp, gp->sframes, sizeof (gp->sframes)) + | |
136 | + xserialize (interp, strm, gp->value, info) + | |
137 | + xserialize (interp, strm, gp->argv, info)); | |
138 | +} | |
139 | + | |
140 | +object deserialize_G (interpreter *interp, stream *strm, serial_info& info) | |
141 | +{ | |
142 | + valref ret (interp, alloc_generator (interp)); | |
143 | + generator *gp = as_generator (*ret); | |
144 | + | |
145 | + if (!strm->sread (interp, &gp->ip_offset) || | |
146 | + !strm->sread (interp, &gp->sp_diff) || | |
147 | + strm->read (interp, gp->sframes, sizeof (gp->sframes)) != | |
148 | + (int)sizeof (gp->sframes) || | |
149 | + (gp->value = xdeserialize (interp, strm, info)) == UNBOUND || | |
150 | + !array_p (gp->argv = xdeserialize (interp, strm, info))) | |
151 | + qp_return (UNBOUND); | |
152 | + | |
153 | + qp_return (*ret); | |
154 | +} | |
155 | + | |
156 | +QP_DECLS_END |
@@ -0,0 +1,51 @@ | ||
1 | +#ifndef __QP_GENERATOR_H__ | |
2 | +#define __QP_GENERATOR_H__ 1 | |
3 | + | |
4 | +#include "interp.h" | |
5 | + | |
6 | +QP_DECLS_BEGIN | |
7 | + | |
8 | +struct generator : public varobj | |
9 | +{ | |
10 | + static generator* alloc_raw (); | |
11 | + static object make (interpreter *__interp, uint32_t __lastf); | |
12 | + | |
13 | + object value; | |
14 | + object argv; | |
15 | + int ip_offset; | |
16 | + int sp_diff; | |
17 | + uint32_t sframes[2]; | |
18 | +}; | |
19 | + | |
20 | +inline bool generator_p (object __obj) | |
21 | +{ | |
22 | + return (itype (__obj) == typecode::GENERATOR); | |
23 | +} | |
24 | + | |
25 | +inline generator* as_generator (object __obj) | |
26 | +{ | |
27 | + return ((generator *)maskp (__obj)); | |
28 | +} | |
29 | + | |
30 | +QP_EXPORT object alloc_generator (interpreter *__interp); | |
31 | + | |
32 | +QP_EXPORT object call_generator (interpreter *__interp, object __cont); | |
33 | + | |
34 | +QP_EXPORT object iter_next (interpreter *__interp, object *__argv, int __argc); | |
35 | + | |
36 | +struct stream; | |
37 | +struct io_info; | |
38 | +struct serial_info; | |
39 | + | |
40 | +QP_EXPORT int write_G (interpreter *__interp, | |
41 | + stream *__strm, object __obj, io_info& __info); | |
42 | + | |
43 | +QP_EXPORT int serialize_G (interpreter *__interp, | |
44 | + stream *__strm, object __obj, serial_info& __info); | |
45 | + | |
46 | +QP_EXPORT object deserialize_G (interpreter *__interp, | |
47 | + stream *__strm, serial_info& __info); | |
48 | + | |
49 | +QP_DECLS_END | |
50 | + | |
51 | +#endif |
@@ -15,7 +15,7 @@ | ||
15 | 15 | #include "function.h" |
16 | 16 | #include "io.h" |
17 | 17 | #include "xtime.h" |
18 | -#include "continuation.h" | |
18 | +#include "generator.h" | |
19 | 19 | #include "bytecode.h" |
20 | 20 | #include "builtins.h" |
21 | 21 | #include "event.h" |