mirror of
https://github.com/pocketpy/pocketpy
synced 2025-10-20 03:20:18 +00:00
some fix
This commit is contained in:
parent
d160d79d3f
commit
bf7bfa938c
@ -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);
|
||||
|
||||
|
@ -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);
|
||||
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 == -1) goto __ERROR;
|
||||
// closure
|
||||
py_Ref tmp = Frame__getclosure(frame, name);
|
||||
if(tmp != NULL) {
|
||||
PUSH(tmp);
|
||||
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,22 +360,32 @@ 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 {
|
||||
case tp_nil: {
|
||||
// globals
|
||||
if(!Frame__setglobal(frame, name, TOP())) { goto __ERROR; }
|
||||
if(!Frame__setglobal(frame, name, TOP())) goto __ERROR;
|
||||
POP();
|
||||
DISPATCH();
|
||||
}
|
||||
default: c11__unreachable();
|
||||
}
|
||||
}
|
||||
case OP_STORE_GLOBAL: {
|
||||
if(!Frame__setglobal(frame, byte.arg, TOP())) goto __ERROR;
|
||||
@ -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);
|
||||
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;
|
||||
} else {
|
||||
}
|
||||
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;
|
||||
DISPATCH();
|
||||
}
|
||||
default: c11__unreachable();
|
||||
}
|
||||
}
|
||||
case OP_DELETE_GLOBAL: {
|
||||
|
@ -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);
|
||||
|
@ -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), "<string>", 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);
|
||||
|
Loading…
x
Reference in New Issue
Block a user