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_GlobalRef module;
|
||||
py_Ref globals; // a module object or a dict object
|
||||
py_Ref locals; // locals base or a proxy object (such as dict)
|
||||
bool is_p0_function;
|
||||
bool is_locals_proxy;
|
||||
py_Ref locals;
|
||||
bool is_locals_special;
|
||||
int ip;
|
||||
UnwindTarget* uw_list;
|
||||
} Frame;
|
||||
@ -46,8 +45,7 @@ Frame* Frame__new(const CodeObject* co,
|
||||
py_GlobalRef module,
|
||||
py_Ref globals,
|
||||
py_Ref locals,
|
||||
bool is_p0_function,
|
||||
bool is_locals_proxy);
|
||||
bool is_locals_special);
|
||||
void Frame__delete(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__ctor(ud, decl, frame->module, frame->globals);
|
||||
if(decl->nested) {
|
||||
if(frame->is_locals_proxy) {
|
||||
RuntimeError("cannot create closure from locals proxy");
|
||||
if(frame->is_locals_special) {
|
||||
RuntimeError("cannot create closure from special locals");
|
||||
goto __ERROR;
|
||||
}
|
||||
ud->closure = FastLocals__to_namedict(frame->locals, frame->co);
|
||||
@ -198,7 +198,7 @@ FrameResult VM__run_top_frame(VM* self) {
|
||||
DISPATCH();
|
||||
/*****************************************/
|
||||
case OP_LOAD_FAST: {
|
||||
assert(!frame->is_locals_proxy);
|
||||
assert(!frame->is_locals_special);
|
||||
PUSH(&frame->locals[byte.arg]);
|
||||
if(py_isnil(TOP())) {
|
||||
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;
|
||||
}
|
||||
case OP_STORE_FAST: {
|
||||
assert(!frame->is_locals_proxy);
|
||||
assert(!frame->is_locals_special);
|
||||
frame->locals[byte.arg] = POPX();
|
||||
DISPATCH();
|
||||
}
|
||||
@ -392,7 +392,7 @@ FrameResult VM__run_top_frame(VM* self) {
|
||||
goto __ERROR;
|
||||
}
|
||||
case OP_DELETE_FAST: {
|
||||
assert(!frame->is_locals_proxy);
|
||||
assert(!frame->is_locals_special);
|
||||
py_Ref tmp = &frame->locals[byte.arg];
|
||||
if(py_isnil(tmp)) {
|
||||
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,
|
||||
frame->co->src,
|
||||
Frame__lineno(frame),
|
||||
frame->is_p0_function ? frame->co->name->data : NULL);
|
||||
!frame->is_locals_special ? frame->co->name->data : NULL);
|
||||
__ERROR_RE_RAISE:
|
||||
do {
|
||||
} while(0);
|
||||
|
@ -52,11 +52,12 @@ Frame* Frame__new(const CodeObject* co,
|
||||
py_GlobalRef module,
|
||||
py_Ref globals,
|
||||
py_Ref locals,
|
||||
bool is_p0_function,
|
||||
bool is_locals_proxy) {
|
||||
bool is_locals_special) {
|
||||
assert(module->type == tp_module);
|
||||
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);
|
||||
self->f_back = NULL;
|
||||
self->co = co;
|
||||
@ -64,8 +65,7 @@ Frame* Frame__new(const CodeObject* co,
|
||||
self->module = module;
|
||||
self->globals = globals;
|
||||
self->locals = locals;
|
||||
self->is_p0_function = is_p0_function;
|
||||
self->is_locals_proxy = is_locals_proxy;
|
||||
self->is_locals_special = is_locals_special;
|
||||
self->ip = -1;
|
||||
self->uw_list = NULL;
|
||||
return self;
|
||||
@ -81,8 +81,7 @@ void Frame__delete(Frame* self) {
|
||||
}
|
||||
|
||||
py_StackRef Frame__locals_sp(Frame* self) {
|
||||
if(!self->is_locals_proxy) { return self->locals; }
|
||||
return self->p0;
|
||||
return !self->is_locals_special ? self->locals : self->p0;
|
||||
}
|
||||
|
||||
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) {
|
||||
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);
|
||||
}
|
||||
|
||||
@ -166,12 +165,12 @@ int Frame__delglobal(Frame* self, py_Name name) {
|
||||
}
|
||||
|
||||
int Frame__getlocal(Frame* self, py_Name name) {
|
||||
if(self->is_locals_proxy) {
|
||||
if(self->locals->type == tp_locals) {
|
||||
self = self->locals->_ptr;
|
||||
} else {
|
||||
assert(self->locals->type == tp_dict);
|
||||
return py_dict_getitem(self->locals, py_name2ref(name));
|
||||
if(self->is_locals_special) {
|
||||
switch(self->locals->type) {
|
||||
case tp_locals: self = self->locals->_ptr; break;
|
||||
case tp_dict: return py_dict_getitem(self->locals, py_name2ref(name));
|
||||
case tp_nil: return 0;
|
||||
default: c11__unreachable();
|
||||
}
|
||||
}
|
||||
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) {
|
||||
if(self->is_locals_proxy) {
|
||||
if(self->locals->type == tp_locals) {
|
||||
self = self->locals->_ptr;
|
||||
} else {
|
||||
assert(self->locals->type == tp_dict);
|
||||
return py_dict_setitem(self->locals, py_name2ref(name), val);
|
||||
if(self->is_locals_special) {
|
||||
switch(self->locals->type) {
|
||||
case tp_locals: self = self->locals->_ptr; break;
|
||||
case tp_dict: return py_dict_setitem(self->locals, py_name2ref(name), val);
|
||||
case tp_nil: return false;
|
||||
default: c11__unreachable();
|
||||
}
|
||||
}
|
||||
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) {
|
||||
if(self->is_locals_proxy) {
|
||||
if(self->locals->type == tp_locals) {
|
||||
self = self->locals->_ptr;
|
||||
} else {
|
||||
assert(self->locals->type == tp_dict);
|
||||
return py_dict_delitem(self->locals, py_name2ref(name));
|
||||
if(self->is_locals_special) {
|
||||
switch(self->locals->type) {
|
||||
case tp_locals: self = self->locals->_ptr; break;
|
||||
case tp_dict: return py_dict_delitem(self->locals, py_name2ref(name));
|
||||
case tp_nil: return 0;
|
||||
default: c11__unreachable();
|
||||
}
|
||||
}
|
||||
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) {
|
||||
assert(!self->is_locals_proxy);
|
||||
assert(!self->is_locals_special);
|
||||
int index = c11_smallmap_n2i__get(&self->co->varnames_inv, name, -1);
|
||||
if(index == -1) return NULL;
|
||||
return &self->locals[index];
|
||||
}
|
||||
|
||||
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);
|
||||
if(ud->closure == NULL) return NULL;
|
||||
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();
|
||||
|
||||
// reset frame->p0
|
||||
if(ud->frame->is_locals_proxy){
|
||||
return RuntimeError("cannot resume generator with locals proxy");
|
||||
}
|
||||
assert(!ud->frame->is_locals_special);
|
||||
int locals_offset = ud->frame->locals - ud->frame->p0;
|
||||
ud->frame->p0 = py_peek(0);
|
||||
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
|
||||
if(!fn->cfunc) {
|
||||
// python function
|
||||
VM__push_frame(self,
|
||||
Frame__new(co, p0, fn->module, fn->globals, argv, true, false));
|
||||
VM__push_frame(self, Frame__new(co, p0, fn->module, fn->globals, argv, false));
|
||||
return opcall ? RES_CALL : VM__run_top_frame(self);
|
||||
} else {
|
||||
// decl-based binding
|
||||
@ -515,8 +514,7 @@ FrameResult VM__vectorcall(VM* self, uint16_t argc, uint16_t kwargc, bool opcall
|
||||
// submit the call
|
||||
if(!fn->cfunc) {
|
||||
// python function
|
||||
VM__push_frame(self,
|
||||
Frame__new(co, p0, fn->module, fn->globals, argv, true, false));
|
||||
VM__push_frame(self, Frame__new(co, p0, fn->module, fn->globals, argv, false));
|
||||
return opcall ? RES_CALL : VM__run_top_frame(self);
|
||||
} else {
|
||||
// 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
|
||||
self->stack.sp = argv + co->nlocals;
|
||||
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);
|
||||
self->stack.sp = p0; // reset the stack
|
||||
return RES_RETURN;
|
||||
|
@ -54,7 +54,7 @@ bool pk_exec(CodeObject* co, py_Ref module) {
|
||||
assert(module->type == tp_module);
|
||||
|
||||
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);
|
||||
FrameResult res = VM__run_top_frame(vm);
|
||||
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 {
|
||||
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);
|
||||
FrameResult res = VM__run_top_frame(vm);
|
||||
if(res == RES_ERROR) return false;
|
||||
|
@ -511,13 +511,12 @@ void py_newlocals(py_Ref out) {
|
||||
py_newglobals(out);
|
||||
return;
|
||||
}
|
||||
if(frame->is_locals_proxy) {
|
||||
if(frame->locals->type == tp_locals) {
|
||||
frame = frame->locals->_ptr;
|
||||
} else {
|
||||
assert(frame->locals->type == tp_dict);
|
||||
*out = *frame->locals;
|
||||
return;
|
||||
if(frame->is_locals_special) {
|
||||
switch(frame->locals->type) {
|
||||
case tp_locals: frame = frame->locals->_ptr; break;
|
||||
case tp_dict: *out = *frame->locals; return;
|
||||
case tp_nil: py_newglobals(out); return;
|
||||
default: c11__unreachable();
|
||||
}
|
||||
}
|
||||
FastLocals__to_dict(frame->locals, frame->co);
|
||||
@ -530,20 +529,16 @@ static void pk_push_locals_proxy() {
|
||||
py_pushnil();
|
||||
return;
|
||||
}
|
||||
if(frame->is_locals_proxy) {
|
||||
if(frame->is_locals_special) {
|
||||
py_push(frame->locals);
|
||||
} else {
|
||||
if(py_isnil(frame->locals)) {
|
||||
py_pushnil();
|
||||
} else {
|
||||
py_StackRef out = py_pushtmp();
|
||||
out->type = tp_locals;
|
||||
out->is_ptr = false;
|
||||
out->extra = 0;
|
||||
// this is a weak reference
|
||||
// which will expire when the frame is destroyed
|
||||
out->_ptr = frame;
|
||||
}
|
||||
py_StackRef out = py_pushtmp();
|
||||
out->type = tp_locals;
|
||||
out->is_ptr = false;
|
||||
out->extra = 0;
|
||||
// this is a weak reference
|
||||
// which will expire when the frame is destroyed
|
||||
out->_ptr = frame;
|
||||
}
|
||||
}
|
||||
|
||||
@ -827,16 +822,14 @@ static bool super__new__(int argc, py_Ref argv) {
|
||||
py_Ref self_arg = NULL;
|
||||
if(argc == 1) {
|
||||
// super()
|
||||
if(frame->is_p0_function && !frame->is_locals_proxy) {
|
||||
if(!frame->is_locals_special) {
|
||||
py_TValue* callable = frame->p0;
|
||||
if(callable->type == tp_boundmethod) callable = py_getslot(frame->p0, 1);
|
||||
if(callable->type == tp_function) {
|
||||
Function* func = py_touserdata(callable);
|
||||
if(func->clazz != NULL) {
|
||||
class_arg = *(py_Type*)PyObject__userdata(func->clazz);
|
||||
if(frame->co->nlocals > 0) {
|
||||
if(!frame->is_locals_proxy) self_arg = &frame->locals[0];
|
||||
}
|
||||
if(frame->co->nlocals > 0) { self_arg = &frame->locals[0]; }
|
||||
}
|
||||
}
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user