mirror of
https://github.com/pocketpy/pocketpy
synced 2025-10-20 03:20:18 +00:00
...
This commit is contained in:
parent
8264f125d6
commit
f481337f98
@ -7,4 +7,4 @@ typedef struct Generator{
|
|||||||
int state;
|
int state;
|
||||||
} Generator;
|
} Generator;
|
||||||
|
|
||||||
void pk_newgenerator(py_Ref out, Frame* frame, int slots);
|
void pk_newgenerator(py_Ref out, Frame* frame);
|
@ -1,16 +1,63 @@
|
|||||||
#include "pocketpy/interpreter/generator.h"
|
#include "pocketpy/interpreter/generator.h"
|
||||||
#include "pocketpy/interpreter/frame.h"
|
#include "pocketpy/interpreter/frame.h"
|
||||||
#include "pocketpy/interpreter/vm.h"
|
#include "pocketpy/interpreter/vm.h"
|
||||||
|
#include "pocketpy/objects/base.h"
|
||||||
#include "pocketpy/pocketpy.h"
|
#include "pocketpy/pocketpy.h"
|
||||||
|
#include <stdbool.h>
|
||||||
|
|
||||||
void pk_newgenerator(py_Ref out, Frame* frame, int slots) {
|
void pk_newgenerator(py_Ref out, Frame* frame) {
|
||||||
Generator* ud = py_newobject(out, tp_generator, slots, sizeof(Generator));
|
Generator* ud = py_newobject(out, tp_generator, 1, sizeof(Generator));
|
||||||
ud->frame = frame;
|
ud->frame = frame;
|
||||||
ud->state = 0;
|
ud->state = 0;
|
||||||
|
py_newlist(py_getslot(out, 0));
|
||||||
}
|
}
|
||||||
|
|
||||||
static bool generator__next__(int argc, py_Ref argv){
|
static bool generator__next__(int argc, py_Ref argv) {
|
||||||
return true;
|
PY_CHECK_ARGC(1);
|
||||||
|
Generator* ud = py_touserdata(argv);
|
||||||
|
py_StackRef p0 = py_peek(0);
|
||||||
|
VM* vm = pk_current_vm;
|
||||||
|
if(ud->state == 2) return StopIteration();
|
||||||
|
|
||||||
|
// reset frame->p0
|
||||||
|
ud->frame->p0 = py_peek(0);
|
||||||
|
ud->frame->locals = py_peek(0);
|
||||||
|
|
||||||
|
// restore the context
|
||||||
|
py_Ref backup = py_getslot(argv, 0);
|
||||||
|
int length = py_list_len(backup);
|
||||||
|
py_TValue* p = py_list_data(backup);
|
||||||
|
for(int i = 0; i < length; i++)
|
||||||
|
py_push(&p[i]);
|
||||||
|
py_list_clear(backup);
|
||||||
|
|
||||||
|
// push frame
|
||||||
|
VM__push_frame(vm, ud->frame);
|
||||||
|
|
||||||
|
FrameResult res = VM__run_top_frame(vm);
|
||||||
|
|
||||||
|
if(res == RES_ERROR) {
|
||||||
|
ud->state = 2; // end this generator immediately on error
|
||||||
|
if(py_matchexc(tp_StopIteration)) {
|
||||||
|
py_clearexc(p0);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(res == RES_YIELD) {
|
||||||
|
// backup the context
|
||||||
|
ud->frame = vm->top_frame;
|
||||||
|
for(py_StackRef p = ud->frame->p0; p != vm->stack.sp; p++) {
|
||||||
|
py_list_append(backup, p);
|
||||||
|
}
|
||||||
|
vm->top_frame = vm->top_frame->f_back;
|
||||||
|
ud->state = 1;
|
||||||
|
return true;
|
||||||
|
} else {
|
||||||
|
ud->state = 2;
|
||||||
|
return StopIteration();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
py_Type pk_generator__register() {
|
py_Type pk_generator__register() {
|
||||||
|
@ -457,7 +457,7 @@ FrameResult VM__vectorcall(VM* self, uint16_t argc, uint16_t kwargc, bool opcall
|
|||||||
bool ok = prepare_py_call(self->__vectorcall_buffer, argv, p1, kwargc, fn->decl);
|
bool ok = prepare_py_call(self->__vectorcall_buffer, argv, p1, kwargc, fn->decl);
|
||||||
if(!ok) return RES_ERROR;
|
if(!ok) return RES_ERROR;
|
||||||
Frame* frame = Frame__new(co, &fn->module, p0, p0, argv);
|
Frame* frame = Frame__new(co, &fn->module, p0, p0, argv);
|
||||||
pk_newgenerator(py_retval(), frame, 0);
|
pk_newgenerator(py_retval(), frame);
|
||||||
self->stack.sp = p0;
|
self->stack.sp = p0;
|
||||||
return RES_RETURN;
|
return RES_RETURN;
|
||||||
}
|
}
|
||||||
@ -592,7 +592,7 @@ void ManagedHeap__mark(ManagedHeap* self) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void pk_print_stack(VM* self, Frame* frame, Bytecode byte) {
|
void pk_print_stack(VM* self, Frame* frame, Bytecode byte) {
|
||||||
return;
|
// return;
|
||||||
if(frame == NULL || py_isnil(&self->main)) return;
|
if(frame == NULL || py_isnil(&self->main)) return;
|
||||||
|
|
||||||
py_TValue* sp = self->stack.sp;
|
py_TValue* sp = self->stack.sp;
|
||||||
|
@ -54,8 +54,6 @@ static bool _py_BaseException__new__(int argc, py_Ref argv) {
|
|||||||
py_Type cls = py_totype(argv);
|
py_Type cls = py_totype(argv);
|
||||||
BaseException* ud = py_newobject(py_retval(), cls, 2, sizeof(BaseException));
|
BaseException* ud = py_newobject(py_retval(), cls, 2, sizeof(BaseException));
|
||||||
c11_vector__ctor(&ud->stacktrace, sizeof(BaseExceptionFrame));
|
c11_vector__ctor(&ud->stacktrace, sizeof(BaseExceptionFrame));
|
||||||
py_setslot(py_retval(), 0, py_NIL);
|
|
||||||
py_setslot(py_retval(), 1, py_NIL);
|
|
||||||
ud->lineno_backup = -1;
|
ud->lineno_backup = -1;
|
||||||
ud->code_backup = NULL;
|
ud->code_backup = NULL;
|
||||||
return true;
|
return true;
|
||||||
|
Loading…
x
Reference in New Issue
Block a user