From bf7bfa938c1484b44cec6698c10a50d32e1bd263 Mon Sep 17 00:00:00 2001 From: blueloveTH Date: Fri, 28 Feb 2025 16:25:22 +0800 Subject: [PATCH] some fix --- include/pocketpy/interpreter/frame.h | 4 - src/interpreter/ceval.c | 111 ++++++++++++++++++--------- src/interpreter/frame.c | 53 ------------- src/public/modules.c | 17 ++-- 4 files changed, 81 insertions(+), 104 deletions(-) diff --git a/include/pocketpy/interpreter/frame.h b/include/pocketpy/interpreter/frame.h index 03426333..510ae0f6 100644 --- a/include/pocketpy/interpreter/frame.h +++ b/include/pocketpy/interpreter/frame.h @@ -55,10 +55,6 @@ int Frame__getglobal(Frame* self, py_Name name) PY_RAISE PY_RETURN; bool Frame__setglobal(Frame* self, py_Name name, py_TValue* val) PY_RAISE; int Frame__delglobal(Frame* self, py_Name name) PY_RAISE; -int Frame__getlocal(Frame* self, py_Name name) PY_RAISE PY_RETURN; -bool Frame__setlocal(Frame* self, py_Name name, py_TValue* val) PY_RAISE; -int Frame__dellocal(Frame* self, py_Name name) PY_RAISE; - py_Ref Frame__getclosure(Frame* self, py_Name name); py_StackRef Frame__getlocal_noproxy(Frame* self, py_Name name); diff --git a/src/interpreter/ceval.c b/src/interpreter/ceval.c index 4db89b2b..2b337614 100644 --- a/src/interpreter/ceval.c +++ b/src/interpreter/ceval.c @@ -208,29 +208,43 @@ FrameResult VM__run_top_frame(VM* self) { DISPATCH(); } case OP_LOAD_NAME: { + assert(frame->is_locals_special); py_Name name = byte.arg; // locals - int res = Frame__getlocal(frame, name); - if(res == 1) { - PUSH(&self->last_retval); - DISPATCH(); - } - if(res == -1) goto __ERROR; - // closure - py_Ref tmp = Frame__getclosure(frame, name); - if(tmp != NULL) { - PUSH(tmp); - DISPATCH(); + switch(frame->locals->type) { + case tp_locals: { + Frame* noproxy = frame->locals->_ptr; + py_Ref slot = Frame__getlocal_noproxy(noproxy, name); + if(slot == NULL) break; + if(py_isnil(slot)) { + UnboundLocalError(name); + goto __ERROR; + } + PUSH(slot); + DISPATCH(); + } + case tp_dict: { + int res = py_dict_getitem(frame->locals, py_name2ref(name)); + if(res == 1) { + PUSH(&self->last_retval); + DISPATCH(); + } + if(res == 0) break; + assert(res == -1); + goto __ERROR; + } + case tp_nil: break; + default: c11__unreachable(); } // globals - res = Frame__getglobal(frame, name); + int res = Frame__getglobal(frame, name); if(res == 1) { PUSH(&self->last_retval); DISPATCH(); } if(res == -1) goto __ERROR; // builtins - tmp = py_getdict(&self->builtins, name); + py_Ref tmp = py_getdict(&self->builtins, name); if(tmp != NULL) { PUSH(tmp); DISPATCH(); @@ -346,21 +360,31 @@ FrameResult VM__run_top_frame(VM* self) { DISPATCH(); } case OP_STORE_NAME: { + assert(frame->is_locals_special); py_Name name = byte.arg; - if(frame->locals != NULL) { - // locals - int res = Frame__setlocal(frame, name, TOP()); - if(res == 1) { + switch(frame->locals->type) { + case tp_locals: { + Frame* noproxy = frame->locals->_ptr; + py_Ref slot = Frame__getlocal_noproxy(noproxy, name); + if(slot == NULL) { + UnboundLocalError(name); + goto __ERROR; + } + *slot = POPX(); + DISPATCH(); + } + case tp_dict: { + if(!py_dict_setitem(frame->locals, py_name2ref(name), TOP())) goto __ERROR; POP(); DISPATCH(); } - if(res == 0) NameError(name); - goto __ERROR; - } else { - // globals - if(!Frame__setglobal(frame, name, TOP())) { goto __ERROR; } - POP(); - DISPATCH(); + case tp_nil: { + // globals + if(!Frame__setglobal(frame, name, TOP())) goto __ERROR; + POP(); + DISPATCH(); + } + default: c11__unreachable(); } } case OP_STORE_GLOBAL: { @@ -403,20 +427,33 @@ FrameResult VM__run_top_frame(VM* self) { DISPATCH(); } case OP_DELETE_NAME: { + assert(frame->is_locals_special); py_Name name = byte.arg; - if(frame->locals != NULL) { - // locals - int res = Frame__dellocal(frame, name); - if(res == 1) DISPATCH(); - if(res == 0) NameError(name); - goto __ERROR; - } else { - // globals - int res = Frame__delglobal(frame, name); - if(res == 1) DISPATCH(); - if(res == 0) NameError(name); - goto __ERROR; - DISPATCH(); + switch(frame->locals->type) { + case tp_locals: { + Frame* noproxy = frame->locals->_ptr; + py_Ref slot = Frame__getlocal_noproxy(noproxy, name); + if(slot == NULL || py_isnil(slot)) { + UnboundLocalError(name); + goto __ERROR; + } + py_newnil(slot); + DISPATCH(); + } + case tp_dict: { + int res = py_dict_delitem(frame->locals, py_name2ref(name)); + if(res == 1) DISPATCH(); + if(res == 0) UnboundLocalError(name); + goto __ERROR; + } + case tp_nil: { + // globals + int res = Frame__delglobal(frame, name); + if(res == 1) DISPATCH(); + if(res == 0) NameError(name); + goto __ERROR; + } + default: c11__unreachable(); } } case OP_DELETE_GLOBAL: { diff --git a/src/interpreter/frame.c b/src/interpreter/frame.c index dfeb35a6..7ce44fab 100644 --- a/src/interpreter/frame.c +++ b/src/interpreter/frame.c @@ -160,59 +160,6 @@ int Frame__delglobal(Frame* self, py_Name name) { } } -int Frame__getlocal(Frame* self, py_Name 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); - if(slot == NULL) return 0; // bad slot - if(py_isnil(slot)) { - UnboundLocalError(name); - return -1; - } - py_assign(py_retval(), slot); - return 1; -} - -bool Frame__setlocal(Frame* self, py_Name name, py_TValue* 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); - if(slot == NULL) return false; // bad slot - *slot = *val; - return true; -} - -int Frame__dellocal(Frame* self, py_Name 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); - if(slot == NULL) return 0; // bad slot - if(py_isnil(slot)) { - UnboundLocalError(name); - return -1; - } - py_newnil(slot); - return 1; -} - py_StackRef Frame__getlocal_noproxy(Frame* self, py_Name name) { assert(!self->is_locals_special); int index = c11_smallmap_n2i__get(&self->co->varnames_inv, name, -1); diff --git a/src/public/modules.c b/src/public/modules.c index 37782c32..091b4fbc 100644 --- a/src/public/modules.c +++ b/src/public/modules.c @@ -523,7 +523,7 @@ void py_newlocals(py_Ref out) { py_assign(out, py_retval()); } -static void pk_push_locals_proxy() { +static void pk_push_special_locals() { Frame* frame = pk_current_vm->top_frame; if(!frame) { py_pushnil(); @@ -546,7 +546,7 @@ static bool _builtins_execdyn(const char* title, int argc, py_Ref argv, enum py_ switch(argc) { case 1: { py_newglobals(py_pushtmp()); - pk_push_locals_proxy(); + pk_push_special_locals(); break; } case 2: { @@ -558,7 +558,7 @@ static bool _builtins_execdyn(const char* title, int argc, py_Ref argv, enum py_ py_push(py_arg(1)); } // locals - pk_push_locals_proxy(); + pk_push_special_locals(); break; } case 3: { @@ -571,7 +571,7 @@ static bool _builtins_execdyn(const char* title, int argc, py_Ref argv, enum py_ } // locals if(py_isnone(py_arg(2))) { - pk_push_locals_proxy(); + pk_push_special_locals(); } else { if(!py_checktype(py_arg(2), tp_dict)) return false; py_push(py_arg(2)); @@ -581,22 +581,19 @@ static bool _builtins_execdyn(const char* title, int argc, py_Ref argv, enum py_ default: return TypeError("%s() takes at most 3 arguments", title); } - py_Ref tmp_code; if(py_isstr(argv)) { bool ok = py_compile(py_tostr(argv), "", mode, true); if(!ok) return false; - tmp_code = py_retval(); + py_push(py_retval()); } else if(py_istype(argv, tp_code)) { - tmp_code = argv; + py_push(argv); } else { return TypeError("%s() expected 'str' or 'code', got '%t'", title, argv->type); } - py_push(tmp_code); // keep it alive Frame* frame = pk_current_vm->top_frame; - // [globals, locals, code] - CodeObject* code = py_touserdata(tmp_code); + CodeObject* code = py_touserdata(py_peek(-1)); if(code->src->is_dynamic) { bool ok = pk_execdyn(code, frame ? frame->module : NULL, py_peek(-3), py_peek(-2)); py_shrink(3);