Skip to content

Commit 67e8a6f

Browse files
committed
yield实现简单协程
1 parent a296d40 commit 67e8a6f

File tree

6 files changed

+84
-5
lines changed

6 files changed

+84
-5
lines changed

object/hiList.cpp

Lines changed: 11 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@ void ListKlass::initialize() {
2222
klass_dict->put(new HiString("insert"), new FunctionObject(list_insert));
2323
klass_dict->put(new HiString("index"), new FunctionObject(list_index));
2424
klass_dict->put(new HiString("pop"), new FunctionObject(list_pop));
25+
klass_dict->put(new HiString("popleft"), new FunctionObject(list_popleft));
2526
klass_dict->put(new HiString("remove"), new FunctionObject(list_remove));
2627
klass_dict->put(new HiString("reverse"), new FunctionObject(list_reverse));
2728
klass_dict->put(new HiString("sort"), new FunctionObject(list_sort));
@@ -251,6 +252,14 @@ HiObject *list_pop(ObjList args) {
251252
return list->pop();
252253
}
253254

255+
HiObject *list_popleft(ObjList args) {
256+
HiList *list = (HiList *) (args->get(0));
257+
assert(list && list->klass() == ListKlass::get_instance());
258+
HiObject *left = list->get(0);
259+
list->delete_index(0);
260+
return left;
261+
}
262+
254263
HiObject *list_remove(ObjList args) {
255264
HiList *list = (HiList *) (args->get(0));
256265
HiObject *target = args->get(1);
@@ -345,7 +354,7 @@ size_t ListKlass::size() {
345354
}
346355

347356
void ListKlass::oops_do(OopClosure *f, HiObject *obj) {
348-
assert(obj && obj->klass() == (Klass*) this);
357+
assert(obj && obj->klass() == (Klass *) this);
349358

350-
f->do_array_list(&((HiList*)obj)->_inner_list);
359+
f->do_array_list(&((HiList *) obj)->_inner_list);
351360
}

object/hiList.hpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -64,6 +64,7 @@ HiObject *list_append(ObjList args);
6464
HiObject *list_insert(ObjList args);
6565
HiObject *list_index(ObjList args);
6666
HiObject *list_pop(ObjList args);
67+
HiObject *list_popleft(ObjList args);
6768
HiObject *list_remove(ObjList args);
6869
HiObject *list_reverse(ObjList args);
6970
HiObject *list_sort(ObjList args);

runtime/interpreter.cpp

Lines changed: 22 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -150,6 +150,7 @@ void Interpreter::eval_frame() {
150150
break;
151151

152152
case ByteCode::BINARY_MULTIPLY:
153+
case ByteCode::INPLACE_MULTIPLY:
153154
v = POP();
154155
w = POP();
155156
PUSH(w->mul(v));
@@ -189,6 +190,7 @@ void Interpreter::eval_frame() {
189190
break;
190191

191192
case ByteCode::BINARY_SUBTRACT:
193+
case ByteCode::INPLACE_SUBSTRACT:
192194
v = POP();
193195
w = POP();
194196
PUSH(w->sub(v));
@@ -318,6 +320,11 @@ void Interpreter::eval_frame() {
318320
u->setattr(v, w);
319321
break;
320322

323+
case ByteCode::STORE_GLOBAL:
324+
v = _frame->names()->get(op_arg);
325+
_frame->globals()->put(v, POP());
326+
break;
327+
321328
case ByteCode::DUP_TOPX:
322329
for (int i = 0; i < op_arg; i++) {
323330
int index = STACK_LEVEL() - op_arg;
@@ -481,8 +488,16 @@ void Interpreter::eval_frame() {
481488

482489
case ByteCode::POP_JUMP_IF_FALSE:
483490
v = POP();
484-
if (v == Universe::HiFalse)
491+
if (v == Universe::HiFalse) {
492+
_frame->set_pc(op_arg);
493+
}
494+
break;
495+
496+
case ByteCode::POP_JUMP_IF_TRUE:
497+
v = POP();
498+
if (v == Universe::HiTrue) {
485499
_frame->set_pc(op_arg);
500+
}
486501
break;
487502

488503
case ByteCode::JUMP_FORWARD:
@@ -729,6 +744,12 @@ void Interpreter::eval_frame() {
729744
}
730745

731746
HiObject *Interpreter::eval_generator(Generator *g) {
747+
if (g->frame() == NULL) {
748+
// 说明frame已经被销毁了
749+
do_raise(Universe::stop_iteration, NULL, NULL);
750+
return NULL;
751+
}
752+
732753
Handle handle(g);
733754
enter_frame(g->frame());
734755
g->_frame->set_entry_frame(true);

test/test_coroutine.py

Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,49 @@
1+
# Two simple generator functions
2+
def countdown(n):
3+
while n > 0:
4+
print('T-minus', n)
5+
yield
6+
n -= 1
7+
print('Blastoff!')
8+
9+
10+
def countup(n):
11+
x = 0
12+
while x < n:
13+
print('Counting up', x)
14+
yield
15+
x += 1
16+
17+
18+
class TaskScheduler:
19+
def __init__(self):
20+
self._task_queue = []
21+
22+
def new_task(self, task):
23+
'''
24+
Admit a newly started task to the scheduler
25+
26+
'''
27+
self._task_queue.append(task)
28+
29+
def run(self):
30+
'''
31+
Run until there are no more tasks
32+
'''
33+
while len(self._task_queue) > 0:
34+
task = self._task_queue.popleft()
35+
try:
36+
# Run until the next yield statement
37+
task.next()
38+
self._task_queue.append(task)
39+
40+
except StopIteration:
41+
# Generator is no longer executing
42+
pass
43+
44+
45+
# Example use
46+
sched = TaskScheduler()
47+
sched.new_task(countdown(2))
48+
sched.new_task(countup(5))
49+
sched.run()

test/test_iter_fib.py

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,5 @@ def next(self):
3333
while True:
3434
try:
3535
print itor.next()
36-
# TODO raise ex
3736
except StopIteration, e:
3837
break

util/arrayList.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -51,7 +51,7 @@ void ArrayList<T>::expand() {
5151
_array = new_array;
5252

5353
_length <<= 1;
54-
printf("expand an array to %d, size is %d\n", _length, _size);
54+
// printf("expand an array to %d, size is %d\n", _length, _size);
5555
}
5656

5757
template<typename T>

0 commit comments

Comments
 (0)