mirror of
https://github.com/pocketpy/pocketpy
synced 2025-10-20 03:20:18 +00:00
backup
This commit is contained in:
parent
2800f5eedb
commit
330e005881
@ -34,9 +34,8 @@ typedef struct Frame {
|
|||||||
py_StackRef p0; // unwinding base
|
py_StackRef p0; // unwinding base
|
||||||
py_GlobalRef module;
|
py_GlobalRef module;
|
||||||
py_Ref globals; // a module object or a dict object
|
py_Ref globals; // a module object or a dict object
|
||||||
py_Ref locals; // locals base or a proxy object (such as dict)
|
py_Ref locals;
|
||||||
bool is_p0_function;
|
bool is_locals_special;
|
||||||
bool is_locals_proxy;
|
|
||||||
int ip;
|
int ip;
|
||||||
UnwindTarget* uw_list;
|
UnwindTarget* uw_list;
|
||||||
} Frame;
|
} Frame;
|
||||||
@ -46,8 +45,7 @@ Frame* Frame__new(const CodeObject* co,
|
|||||||
py_GlobalRef module,
|
py_GlobalRef module,
|
||||||
py_Ref globals,
|
py_Ref globals,
|
||||||
py_Ref locals,
|
py_Ref locals,
|
||||||
bool is_p0_function,
|
bool is_locals_special);
|
||||||
bool is_locals_proxy);
|
|
||||||
void Frame__delete(Frame* self);
|
void Frame__delete(Frame* self);
|
||||||
|
|
||||||
int Frame__lineno(const Frame* self);
|
int Frame__lineno(const Frame* self);
|
||||||
|
@ -181,8 +181,8 @@ FrameResult VM__run_top_frame(VM* self) {
|
|||||||
Function* ud = py_newobject(SP(), tp_function, 0, sizeof(Function));
|
Function* ud = py_newobject(SP(), tp_function, 0, sizeof(Function));
|
||||||
Function__ctor(ud, decl, frame->module, frame->globals);
|
Function__ctor(ud, decl, frame->module, frame->globals);
|
||||||
if(decl->nested) {
|
if(decl->nested) {
|
||||||
if(frame->is_locals_proxy) {
|
if(frame->is_locals_special) {
|
||||||
RuntimeError("cannot create closure from locals proxy");
|
RuntimeError("cannot create closure from special locals");
|
||||||
goto __ERROR;
|
goto __ERROR;
|
||||||
}
|
}
|
||||||
ud->closure = FastLocals__to_namedict(frame->locals, frame->co);
|
ud->closure = FastLocals__to_namedict(frame->locals, frame->co);
|
||||||
@ -198,7 +198,7 @@ FrameResult VM__run_top_frame(VM* self) {
|
|||||||
DISPATCH();
|
DISPATCH();
|
||||||
/*****************************************/
|
/*****************************************/
|
||||||
case OP_LOAD_FAST: {
|
case OP_LOAD_FAST: {
|
||||||
assert(!frame->is_locals_proxy);
|
assert(!frame->is_locals_special);
|
||||||
PUSH(&frame->locals[byte.arg]);
|
PUSH(&frame->locals[byte.arg]);
|
||||||
if(py_isnil(TOP())) {
|
if(py_isnil(TOP())) {
|
||||||
py_Name name = c11__getitem(uint16_t, &frame->co->varnames, byte.arg);
|
py_Name name = c11__getitem(uint16_t, &frame->co->varnames, byte.arg);
|
||||||
@ -341,7 +341,7 @@ FrameResult VM__run_top_frame(VM* self) {
|
|||||||
goto __ERROR;
|
goto __ERROR;
|
||||||
}
|
}
|
||||||
case OP_STORE_FAST: {
|
case OP_STORE_FAST: {
|
||||||
assert(!frame->is_locals_proxy);
|
assert(!frame->is_locals_special);
|
||||||
frame->locals[byte.arg] = POPX();
|
frame->locals[byte.arg] = POPX();
|
||||||
DISPATCH();
|
DISPATCH();
|
||||||
}
|
}
|
||||||
@ -392,7 +392,7 @@ FrameResult VM__run_top_frame(VM* self) {
|
|||||||
goto __ERROR;
|
goto __ERROR;
|
||||||
}
|
}
|
||||||
case OP_DELETE_FAST: {
|
case OP_DELETE_FAST: {
|
||||||
assert(!frame->is_locals_proxy);
|
assert(!frame->is_locals_special);
|
||||||
py_Ref tmp = &frame->locals[byte.arg];
|
py_Ref tmp = &frame->locals[byte.arg];
|
||||||
if(py_isnil(tmp)) {
|
if(py_isnil(tmp)) {
|
||||||
py_Name name = c11__getitem(py_Name, &frame->co->varnames, byte.arg);
|
py_Name name = c11__getitem(py_Name, &frame->co->varnames, byte.arg);
|
||||||
@ -1146,7 +1146,7 @@ FrameResult VM__run_top_frame(VM* self) {
|
|||||||
py_BaseException__stpush(&self->curr_exception,
|
py_BaseException__stpush(&self->curr_exception,
|
||||||
frame->co->src,
|
frame->co->src,
|
||||||
Frame__lineno(frame),
|
Frame__lineno(frame),
|
||||||
frame->is_p0_function ? frame->co->name->data : NULL);
|
!frame->is_locals_special ? frame->co->name->data : NULL);
|
||||||
__ERROR_RE_RAISE:
|
__ERROR_RE_RAISE:
|
||||||
do {
|
do {
|
||||||
} while(0);
|
} while(0);
|
||||||
|
@ -52,11 +52,12 @@ Frame* Frame__new(const CodeObject* co,
|
|||||||
py_GlobalRef module,
|
py_GlobalRef module,
|
||||||
py_Ref globals,
|
py_Ref globals,
|
||||||
py_Ref locals,
|
py_Ref locals,
|
||||||
bool is_p0_function,
|
bool is_locals_special) {
|
||||||
bool is_locals_proxy) {
|
|
||||||
assert(module->type == tp_module);
|
assert(module->type == tp_module);
|
||||||
assert(globals->type == tp_module || globals->type == tp_dict);
|
assert(globals->type == tp_module || globals->type == tp_dict);
|
||||||
assert(locals->type == tp_locals || locals->type == tp_dict || locals->type == tp_nil);
|
if(is_locals_special) {
|
||||||
|
assert(locals->type == tp_nil || locals->type == tp_locals || locals->type == tp_dict);
|
||||||
|
}
|
||||||
Frame* self = FixedMemoryPool__alloc(&pk_current_vm->pool_frame);
|
Frame* self = FixedMemoryPool__alloc(&pk_current_vm->pool_frame);
|
||||||
self->f_back = NULL;
|
self->f_back = NULL;
|
||||||
self->co = co;
|
self->co = co;
|
||||||
@ -64,8 +65,7 @@ Frame* Frame__new(const CodeObject* co,
|
|||||||
self->module = module;
|
self->module = module;
|
||||||
self->globals = globals;
|
self->globals = globals;
|
||||||
self->locals = locals;
|
self->locals = locals;
|
||||||
self->is_p0_function = is_p0_function;
|
self->is_locals_special = is_locals_special;
|
||||||
self->is_locals_proxy = is_locals_proxy;
|
|
||||||
self->ip = -1;
|
self->ip = -1;
|
||||||
self->uw_list = NULL;
|
self->uw_list = NULL;
|
||||||
return self;
|
return self;
|
||||||
@ -81,8 +81,7 @@ void Frame__delete(Frame* self) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
py_StackRef Frame__locals_sp(Frame* self) {
|
py_StackRef Frame__locals_sp(Frame* self) {
|
||||||
if(!self->is_locals_proxy) { return self->locals; }
|
return !self->is_locals_special ? self->locals : self->p0;
|
||||||
return self->p0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
int Frame__prepare_jump_exception_handler(Frame* self, ValueStack* _s) {
|
int Frame__prepare_jump_exception_handler(Frame* self, ValueStack* _s) {
|
||||||
@ -120,7 +119,7 @@ void Frame__set_unwind_target(Frame* self, py_TValue* sp) {
|
|||||||
|
|
||||||
void Frame__gc_mark(Frame* self) {
|
void Frame__gc_mark(Frame* self) {
|
||||||
pk__mark_value(self->globals);
|
pk__mark_value(self->globals);
|
||||||
if(self->is_locals_proxy) pk__mark_value(self->locals);
|
if(self->is_locals_special) pk__mark_value(self->locals);
|
||||||
CodeObject__gc_mark(self->co);
|
CodeObject__gc_mark(self->co);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -166,12 +165,12 @@ int Frame__delglobal(Frame* self, py_Name name) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
int Frame__getlocal(Frame* self, py_Name name) {
|
int Frame__getlocal(Frame* self, py_Name name) {
|
||||||
if(self->is_locals_proxy) {
|
if(self->is_locals_special) {
|
||||||
if(self->locals->type == tp_locals) {
|
switch(self->locals->type) {
|
||||||
self = self->locals->_ptr;
|
case tp_locals: self = self->locals->_ptr; break;
|
||||||
} else {
|
case tp_dict: return py_dict_getitem(self->locals, py_name2ref(name));
|
||||||
assert(self->locals->type == tp_dict);
|
case tp_nil: return 0;
|
||||||
return py_dict_getitem(self->locals, py_name2ref(name));
|
default: c11__unreachable();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
py_Ref slot = Frame__getlocal_noproxy(self, name);
|
py_Ref slot = Frame__getlocal_noproxy(self, name);
|
||||||
@ -185,12 +184,12 @@ int Frame__getlocal(Frame* self, py_Name name) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
bool Frame__setlocal(Frame* self, py_Name name, py_TValue* val) {
|
bool Frame__setlocal(Frame* self, py_Name name, py_TValue* val) {
|
||||||
if(self->is_locals_proxy) {
|
if(self->is_locals_special) {
|
||||||
if(self->locals->type == tp_locals) {
|
switch(self->locals->type) {
|
||||||
self = self->locals->_ptr;
|
case tp_locals: self = self->locals->_ptr; break;
|
||||||
} else {
|
case tp_dict: return py_dict_setitem(self->locals, py_name2ref(name), val);
|
||||||
assert(self->locals->type == tp_dict);
|
case tp_nil: return false;
|
||||||
return py_dict_setitem(self->locals, py_name2ref(name), val);
|
default: c11__unreachable();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
py_Ref slot = Frame__getlocal_noproxy(self, name);
|
py_Ref slot = Frame__getlocal_noproxy(self, name);
|
||||||
@ -200,12 +199,12 @@ bool Frame__setlocal(Frame* self, py_Name name, py_TValue* val) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
int Frame__dellocal(Frame* self, py_Name name) {
|
int Frame__dellocal(Frame* self, py_Name name) {
|
||||||
if(self->is_locals_proxy) {
|
if(self->is_locals_special) {
|
||||||
if(self->locals->type == tp_locals) {
|
switch(self->locals->type) {
|
||||||
self = self->locals->_ptr;
|
case tp_locals: self = self->locals->_ptr; break;
|
||||||
} else {
|
case tp_dict: return py_dict_delitem(self->locals, py_name2ref(name));
|
||||||
assert(self->locals->type == tp_dict);
|
case tp_nil: return 0;
|
||||||
return py_dict_delitem(self->locals, py_name2ref(name));
|
default: c11__unreachable();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
py_Ref slot = Frame__getlocal_noproxy(self, name);
|
py_Ref slot = Frame__getlocal_noproxy(self, name);
|
||||||
@ -219,14 +218,15 @@ int Frame__dellocal(Frame* self, py_Name name) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
py_StackRef Frame__getlocal_noproxy(Frame* self, py_Name name) {
|
py_StackRef Frame__getlocal_noproxy(Frame* self, py_Name name) {
|
||||||
assert(!self->is_locals_proxy);
|
assert(!self->is_locals_special);
|
||||||
int index = c11_smallmap_n2i__get(&self->co->varnames_inv, name, -1);
|
int index = c11_smallmap_n2i__get(&self->co->varnames_inv, name, -1);
|
||||||
if(index == -1) return NULL;
|
if(index == -1) return NULL;
|
||||||
return &self->locals[index];
|
return &self->locals[index];
|
||||||
}
|
}
|
||||||
|
|
||||||
py_Ref Frame__getclosure(Frame* self, py_Name name) {
|
py_Ref Frame__getclosure(Frame* self, py_Name name) {
|
||||||
if(!self->is_p0_function) return NULL;
|
if(self->is_locals_special) return NULL;
|
||||||
|
assert(self->p0->type == tp_function);
|
||||||
Function* ud = py_touserdata(self->p0);
|
Function* ud = py_touserdata(self->p0);
|
||||||
if(ud->closure == NULL) return NULL;
|
if(ud->closure == NULL) return NULL;
|
||||||
return NameDict__try_get(ud->closure, name);
|
return NameDict__try_get(ud->closure, name);
|
||||||
|
@ -28,9 +28,7 @@ static bool generator__next__(int argc, py_Ref argv) {
|
|||||||
if(ud->state == 2) return StopIteration();
|
if(ud->state == 2) return StopIteration();
|
||||||
|
|
||||||
// reset frame->p0
|
// reset frame->p0
|
||||||
if(ud->frame->is_locals_proxy){
|
assert(!ud->frame->is_locals_special);
|
||||||
return RuntimeError("cannot resume generator with locals proxy");
|
|
||||||
}
|
|
||||||
int locals_offset = ud->frame->locals - ud->frame->p0;
|
int locals_offset = ud->frame->locals - ud->frame->p0;
|
||||||
ud->frame->p0 = py_peek(0);
|
ud->frame->p0 = py_peek(0);
|
||||||
ud->frame->locals = ud->frame->p0 + locals_offset;
|
ud->frame->locals = ud->frame->p0 + locals_offset;
|
||||||
|
@ -485,8 +485,7 @@ FrameResult VM__vectorcall(VM* self, uint16_t argc, uint16_t kwargc, bool opcall
|
|||||||
// submit the call
|
// submit the call
|
||||||
if(!fn->cfunc) {
|
if(!fn->cfunc) {
|
||||||
// python function
|
// python function
|
||||||
VM__push_frame(self,
|
VM__push_frame(self, Frame__new(co, p0, fn->module, fn->globals, argv, false));
|
||||||
Frame__new(co, p0, fn->module, fn->globals, argv, true, false));
|
|
||||||
return opcall ? RES_CALL : VM__run_top_frame(self);
|
return opcall ? RES_CALL : VM__run_top_frame(self);
|
||||||
} else {
|
} else {
|
||||||
// decl-based binding
|
// decl-based binding
|
||||||
@ -515,8 +514,7 @@ FrameResult VM__vectorcall(VM* self, uint16_t argc, uint16_t kwargc, bool opcall
|
|||||||
// submit the call
|
// submit the call
|
||||||
if(!fn->cfunc) {
|
if(!fn->cfunc) {
|
||||||
// python function
|
// python function
|
||||||
VM__push_frame(self,
|
VM__push_frame(self, Frame__new(co, p0, fn->module, fn->globals, argv, false));
|
||||||
Frame__new(co, p0, fn->module, fn->globals, argv, true, false));
|
|
||||||
return opcall ? RES_CALL : VM__run_top_frame(self);
|
return opcall ? RES_CALL : VM__run_top_frame(self);
|
||||||
} else {
|
} else {
|
||||||
// decl-based binding
|
// decl-based binding
|
||||||
@ -532,7 +530,7 @@ FrameResult VM__vectorcall(VM* self, uint16_t argc, uint16_t kwargc, bool opcall
|
|||||||
// copy buffer back to stack
|
// copy buffer back to stack
|
||||||
self->stack.sp = argv + co->nlocals;
|
self->stack.sp = argv + co->nlocals;
|
||||||
memcpy(argv, self->__vectorcall_buffer, co->nlocals * sizeof(py_TValue));
|
memcpy(argv, self->__vectorcall_buffer, co->nlocals * sizeof(py_TValue));
|
||||||
Frame* frame = Frame__new(co, p0, fn->module, fn->globals, argv, true, false);
|
Frame* frame = Frame__new(co, p0, fn->module, fn->globals, argv, false);
|
||||||
pk_newgenerator(py_retval(), frame, p0, self->stack.sp);
|
pk_newgenerator(py_retval(), frame, p0, self->stack.sp);
|
||||||
self->stack.sp = p0; // reset the stack
|
self->stack.sp = p0; // reset the stack
|
||||||
return RES_RETURN;
|
return RES_RETURN;
|
||||||
|
@ -54,7 +54,7 @@ bool pk_exec(CodeObject* co, py_Ref module) {
|
|||||||
assert(module->type == tp_module);
|
assert(module->type == tp_module);
|
||||||
|
|
||||||
py_StackRef sp = vm->stack.sp;
|
py_StackRef sp = vm->stack.sp;
|
||||||
Frame* frame = Frame__new(co, sp, module, module, py_NIL(), false, false);
|
Frame* frame = Frame__new(co, sp, module, module, py_NIL(), true);
|
||||||
VM__push_frame(vm, frame);
|
VM__push_frame(vm, frame);
|
||||||
FrameResult res = VM__run_top_frame(vm);
|
FrameResult res = VM__run_top_frame(vm);
|
||||||
if(res == RES_ERROR) return false;
|
if(res == RES_ERROR) return false;
|
||||||
@ -76,7 +76,7 @@ bool pk_execdyn(CodeObject* co, py_Ref module, py_Ref globals, py_Ref locals) {
|
|||||||
} else {
|
} else {
|
||||||
assert(globals->type == tp_dict);
|
assert(globals->type == tp_dict);
|
||||||
}
|
}
|
||||||
Frame* frame = Frame__new(co, sp, module, globals, locals, false, true);
|
Frame* frame = Frame__new(co, sp, module, globals, locals, true);
|
||||||
VM__push_frame(vm, frame);
|
VM__push_frame(vm, frame);
|
||||||
FrameResult res = VM__run_top_frame(vm);
|
FrameResult res = VM__run_top_frame(vm);
|
||||||
if(res == RES_ERROR) return false;
|
if(res == RES_ERROR) return false;
|
||||||
|
@ -511,13 +511,12 @@ void py_newlocals(py_Ref out) {
|
|||||||
py_newglobals(out);
|
py_newglobals(out);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if(frame->is_locals_proxy) {
|
if(frame->is_locals_special) {
|
||||||
if(frame->locals->type == tp_locals) {
|
switch(frame->locals->type) {
|
||||||
frame = frame->locals->_ptr;
|
case tp_locals: frame = frame->locals->_ptr; break;
|
||||||
} else {
|
case tp_dict: *out = *frame->locals; return;
|
||||||
assert(frame->locals->type == tp_dict);
|
case tp_nil: py_newglobals(out); return;
|
||||||
*out = *frame->locals;
|
default: c11__unreachable();
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
FastLocals__to_dict(frame->locals, frame->co);
|
FastLocals__to_dict(frame->locals, frame->co);
|
||||||
@ -530,11 +529,8 @@ static void pk_push_locals_proxy() {
|
|||||||
py_pushnil();
|
py_pushnil();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if(frame->is_locals_proxy) {
|
if(frame->is_locals_special) {
|
||||||
py_push(frame->locals);
|
py_push(frame->locals);
|
||||||
} else {
|
|
||||||
if(py_isnil(frame->locals)) {
|
|
||||||
py_pushnil();
|
|
||||||
} else {
|
} else {
|
||||||
py_StackRef out = py_pushtmp();
|
py_StackRef out = py_pushtmp();
|
||||||
out->type = tp_locals;
|
out->type = tp_locals;
|
||||||
@ -545,7 +541,6 @@ static void pk_push_locals_proxy() {
|
|||||||
out->_ptr = frame;
|
out->_ptr = frame;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
static bool _builtins_execdyn(const char* title, int argc, py_Ref argv, enum py_CompileMode mode) {
|
static bool _builtins_execdyn(const char* title, int argc, py_Ref argv, enum py_CompileMode mode) {
|
||||||
switch(argc) {
|
switch(argc) {
|
||||||
@ -827,16 +822,14 @@ static bool super__new__(int argc, py_Ref argv) {
|
|||||||
py_Ref self_arg = NULL;
|
py_Ref self_arg = NULL;
|
||||||
if(argc == 1) {
|
if(argc == 1) {
|
||||||
// super()
|
// super()
|
||||||
if(frame->is_p0_function && !frame->is_locals_proxy) {
|
if(!frame->is_locals_special) {
|
||||||
py_TValue* callable = frame->p0;
|
py_TValue* callable = frame->p0;
|
||||||
if(callable->type == tp_boundmethod) callable = py_getslot(frame->p0, 1);
|
if(callable->type == tp_boundmethod) callable = py_getslot(frame->p0, 1);
|
||||||
if(callable->type == tp_function) {
|
if(callable->type == tp_function) {
|
||||||
Function* func = py_touserdata(callable);
|
Function* func = py_touserdata(callable);
|
||||||
if(func->clazz != NULL) {
|
if(func->clazz != NULL) {
|
||||||
class_arg = *(py_Type*)PyObject__userdata(func->clazz);
|
class_arg = *(py_Type*)PyObject__userdata(func->clazz);
|
||||||
if(frame->co->nlocals > 0) {
|
if(frame->co->nlocals > 0) { self_arg = &frame->locals[0]; }
|
||||||
if(!frame->is_locals_proxy) self_arg = &frame->locals[0];
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user