mirror of
https://github.com/pocketpy/pocketpy
synced 2025-10-19 19:10:17 +00:00
backup
This commit is contained in:
parent
f941d26845
commit
96ff66ef69
@ -136,5 +136,4 @@ py_Type pk_code__register();
|
||||
py_TValue pk_builtins__register();
|
||||
|
||||
/* mappingproxy */
|
||||
void pk_mappingproxy__namedict(py_Ref out, py_Ref object);
|
||||
void pk_mappingproxy__locals(py_Ref out, Frame* frame);
|
||||
void pk_mappingproxy__namedict(py_Ref out, py_Ref object);
|
@ -208,38 +208,31 @@ FrameResult VM__run_top_frame(VM* self) {
|
||||
DISPATCH();
|
||||
}
|
||||
case OP_LOAD_NAME: {
|
||||
// assert(frame->is_dynamic);
|
||||
py_Name name = byte.arg;
|
||||
py_TValue* tmp;
|
||||
py_assign(SP()++, py_name2ref(name));
|
||||
// locals
|
||||
if(!py_isnone(&frame->p0[1])) {
|
||||
if(py_getitem(&frame->p0[1], TOP())) {
|
||||
py_assign(TOP(), py_retval());
|
||||
DISPATCH();
|
||||
} else {
|
||||
if(py_matchexc(tp_KeyError)) {
|
||||
py_clearexc(NULL);
|
||||
} else {
|
||||
goto __ERROR;
|
||||
}
|
||||
}
|
||||
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();
|
||||
}
|
||||
// globals
|
||||
if(py_getitem(&frame->p0[0], TOP())) {
|
||||
py_assign(TOP(), py_retval());
|
||||
res = Frame__getglobal(frame, name);
|
||||
if(res == 1) {
|
||||
PUSH(&self->last_retval);
|
||||
DISPATCH();
|
||||
} else {
|
||||
if(py_matchexc(tp_KeyError)) {
|
||||
py_clearexc(NULL);
|
||||
} else {
|
||||
goto __ERROR;
|
||||
}
|
||||
}
|
||||
if(res == -1) goto __ERROR;
|
||||
// builtins
|
||||
tmp = py_getdict(&self->builtins, name);
|
||||
if(tmp != NULL) {
|
||||
py_assign(TOP(), tmp);
|
||||
PUSH(tmp);
|
||||
DISPATCH();
|
||||
}
|
||||
NameError(name);
|
||||
@ -353,36 +346,22 @@ FrameResult VM__run_top_frame(VM* self) {
|
||||
DISPATCH();
|
||||
}
|
||||
case OP_STORE_NAME: {
|
||||
// assert(frame->is_dynamic);
|
||||
py_Name name = byte.arg;
|
||||
py_assign(SP()++, py_name2ref(name));
|
||||
// [value, name]
|
||||
if(!py_isnone(&frame->p0[1])) {
|
||||
if(frame->locals != NULL) {
|
||||
// locals
|
||||
if(py_setitem(&frame->p0[1], TOP(), SECOND())) {
|
||||
STACK_SHRINK(2);
|
||||
int res = Frame__setlocal(frame, name, TOP());
|
||||
if(res == 1) {
|
||||
POP();
|
||||
DISPATCH();
|
||||
} else {
|
||||
if(py_matchexc(tp_KeyError)) {
|
||||
py_clearexc(NULL);
|
||||
NameError(name);
|
||||
}
|
||||
goto __ERROR;
|
||||
}
|
||||
if(res == 0) NameError(name);
|
||||
goto __ERROR;
|
||||
} else {
|
||||
// globals
|
||||
if(py_setitem(&frame->p0[0], TOP(), SECOND())) {
|
||||
STACK_SHRINK(2);
|
||||
DISPATCH();
|
||||
} else {
|
||||
if(py_matchexc(tp_KeyError)) {
|
||||
py_clearexc(NULL);
|
||||
NameError(name);
|
||||
}
|
||||
goto __ERROR;
|
||||
}
|
||||
if(!Frame__setglobal(frame, name, TOP())) { goto __ERROR; }
|
||||
POP();
|
||||
DISPATCH();
|
||||
}
|
||||
DISPATCH();
|
||||
}
|
||||
case OP_STORE_GLOBAL: {
|
||||
if(!Frame__setglobal(frame, byte.arg, TOP())) goto __ERROR;
|
||||
@ -424,42 +403,27 @@ FrameResult VM__run_top_frame(VM* self) {
|
||||
DISPATCH();
|
||||
}
|
||||
case OP_DELETE_NAME: {
|
||||
// assert(frame->is_dynamic);
|
||||
py_Name name = byte.arg;
|
||||
py_assign(SP()++, py_name2ref(name));
|
||||
if(!py_isnone(&frame->p0[1])) {
|
||||
if(frame->locals != NULL) {
|
||||
// locals
|
||||
if(py_delitem(&frame->p0[1], TOP())) {
|
||||
POP();
|
||||
DISPATCH();
|
||||
} else {
|
||||
if(py_matchexc(tp_KeyError)) {
|
||||
py_clearexc(NULL);
|
||||
NameError(name);
|
||||
}
|
||||
goto __ERROR;
|
||||
}
|
||||
int res = Frame__dellocal(frame, name);
|
||||
if(res == 1) DISPATCH();
|
||||
if(res == 0) NameError(name);
|
||||
goto __ERROR;
|
||||
} else {
|
||||
// globals
|
||||
if(py_delitem(&frame->p0[0], TOP())) {
|
||||
POP();
|
||||
DISPATCH();
|
||||
} else {
|
||||
if(py_matchexc(tp_KeyError)) {
|
||||
py_clearexc(NULL);
|
||||
NameError(name);
|
||||
}
|
||||
goto __ERROR;
|
||||
}
|
||||
int res = Frame__delglobal(frame, name);
|
||||
if(res == 1) DISPATCH();
|
||||
if(res == 0) NameError(name);
|
||||
goto __ERROR;
|
||||
DISPATCH();
|
||||
}
|
||||
DISPATCH();
|
||||
}
|
||||
case OP_DELETE_GLOBAL: {
|
||||
py_Name name = byte.arg;
|
||||
int res = Frame__delglobal(frame, name);
|
||||
if(res == 1) DISPATCH();
|
||||
if(res == -1) goto __ERROR;
|
||||
// res == 0
|
||||
NameError(name);
|
||||
goto __ERROR;
|
||||
}
|
||||
|
@ -54,7 +54,9 @@ Frame* Frame__new(const CodeObject* co,
|
||||
py_Ref locals,
|
||||
bool is_p0_function,
|
||||
bool is_locals_proxy) {
|
||||
assert(module->type == tp_module || module->type == tp_dict);
|
||||
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);
|
||||
Frame* self = FixedMemoryPool__alloc(&pk_current_vm->pool_frame);
|
||||
self->f_back = NULL;
|
||||
self->co = co;
|
||||
@ -78,10 +80,8 @@ void Frame__delete(Frame* self) {
|
||||
FixedMemoryPool__dealloc(&pk_current_vm->pool_frame, self);
|
||||
}
|
||||
|
||||
py_StackRef Frame__locals_sp(Frame *self){
|
||||
if(!self->is_locals_proxy){
|
||||
return self->locals;
|
||||
}
|
||||
py_StackRef Frame__locals_sp(Frame* self) {
|
||||
if(!self->is_locals_proxy) { return self->locals; }
|
||||
return self->p0;
|
||||
}
|
||||
|
||||
|
@ -3,15 +3,13 @@
|
||||
#include "pocketpy/pocketpy.h"
|
||||
|
||||
#include "pocketpy/common/utils.h"
|
||||
#include "pocketpy/common/sstream.h"
|
||||
#include "pocketpy/objects/object.h"
|
||||
#include "pocketpy/interpreter/vm.h"
|
||||
#include "pocketpy/compiler/compiler.h"
|
||||
#include <assert.h>
|
||||
|
||||
py_Type pk_code__register() {
|
||||
py_Type type = pk_newtype("code", tp_object, NULL, (py_Dtor)CodeObject__dtor, false, true);
|
||||
pk__tp_set_marker(type, (void (*)(void *))CodeObject__gc_mark);
|
||||
pk__tp_set_marker(type, (void (*)(void*))CodeObject__gc_mark);
|
||||
return type;
|
||||
}
|
||||
|
||||
@ -56,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, sp, false, false);
|
||||
Frame* frame = Frame__new(co, sp, module, module, py_NIL(), false, false);
|
||||
VM__push_frame(vm, frame);
|
||||
FrameResult res = VM__run_top_frame(vm);
|
||||
if(res == RES_ERROR) return false;
|
||||
@ -70,7 +68,7 @@ bool pk_execdyn(CodeObject* co, py_Ref module, py_Ref globals, py_Ref locals) {
|
||||
assert(module->type == tp_module);
|
||||
|
||||
py_StackRef sp = vm->stack.sp;
|
||||
assert(globals != NULL && locals != NULL);
|
||||
assert(globals != NULL);
|
||||
|
||||
if(globals->type == tp_namedict) {
|
||||
globals = py_getslot(globals, 0);
|
||||
|
@ -507,7 +507,7 @@ void py_newglobals(py_Ref out) {
|
||||
|
||||
void py_newlocals(py_Ref out) {
|
||||
Frame* frame = pk_current_vm->top_frame;
|
||||
if(!frame || !frame->is_p0_function) {
|
||||
if(!frame) {
|
||||
py_newglobals(out);
|
||||
return;
|
||||
}
|
||||
@ -524,61 +524,97 @@ void py_newlocals(py_Ref out) {
|
||||
py_assign(out, py_retval());
|
||||
}
|
||||
|
||||
static void pk_push_locals_proxy() {
|
||||
Frame* frame = pk_current_vm->top_frame;
|
||||
if(!frame) {
|
||||
py_pushnil();
|
||||
return;
|
||||
}
|
||||
if(frame->is_locals_proxy) {
|
||||
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;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static bool _builtins_execdyn(const char* title, int argc, py_Ref argv, enum py_CompileMode mode) {
|
||||
switch(argc) {
|
||||
case 1: {
|
||||
py_newglobals(py_pushtmp());
|
||||
py_newlocals(py_pushtmp());
|
||||
pk_push_locals_proxy();
|
||||
break;
|
||||
}
|
||||
case 2: {
|
||||
// globals
|
||||
if(py_isnone(py_arg(1))) {
|
||||
py_newglobals(py_pushtmp());
|
||||
} else {
|
||||
if(!py_checktype(py_arg(1), tp_dict)) return false;
|
||||
py_push(py_arg(1));
|
||||
}
|
||||
py_pushnone();
|
||||
// locals
|
||||
pk_push_locals_proxy();
|
||||
break;
|
||||
}
|
||||
case 3: {
|
||||
// globals
|
||||
if(py_isnone(py_arg(1))) {
|
||||
py_newglobals(py_pushtmp());
|
||||
} else {
|
||||
if(!py_checktype(py_arg(1), tp_dict)) return false;
|
||||
py_push(py_arg(1));
|
||||
}
|
||||
py_push(py_arg(2));
|
||||
// locals
|
||||
if(py_isnone(py_arg(2))) {
|
||||
pk_push_locals_proxy();
|
||||
} else {
|
||||
if(!py_checktype(py_arg(2), tp_dict)) return false;
|
||||
py_push(py_arg(2));
|
||||
}
|
||||
break;
|
||||
}
|
||||
default: return TypeError("%s() takes at most 3 arguments", title);
|
||||
}
|
||||
|
||||
py_Ref code;
|
||||
py_Ref tmp_code;
|
||||
if(py_isstr(argv)) {
|
||||
bool ok = py_compile(py_tostr(argv), "<string>", mode, true);
|
||||
if(!ok) return false;
|
||||
code = py_retval();
|
||||
tmp_code = py_retval();
|
||||
} else if(py_istype(argv, tp_code)) {
|
||||
code = argv;
|
||||
tmp_code = argv;
|
||||
} else {
|
||||
return TypeError("%s() expected 'str' or 'code', got '%t'", title, argv->type);
|
||||
}
|
||||
|
||||
py_push(code); // keep it alive
|
||||
py_push(tmp_code); // keep it alive
|
||||
Frame* frame = pk_current_vm->top_frame;
|
||||
|
||||
// [globals, locals, code]
|
||||
CodeObject* co = py_touserdata(code);
|
||||
if(!co->src->is_dynamic) {
|
||||
CodeObject* code = py_touserdata(tmp_code);
|
||||
if(code->src->is_dynamic) {
|
||||
bool ok = pk_execdyn(code, frame ? frame->module : NULL, py_peek(-3), py_peek(-2));
|
||||
py_shrink(3);
|
||||
if(argc != 1)
|
||||
return ValueError("code object is not dynamic, `globals` and `locals` must be None");
|
||||
return ok;
|
||||
} else {
|
||||
if(argc != 1) {
|
||||
return ValueError(
|
||||
"code object is not dynamic, `globals` and `locals` must not be specified");
|
||||
}
|
||||
bool ok = pk_exec(code, frame ? frame->module : NULL);
|
||||
py_shrink(3);
|
||||
return ok;
|
||||
}
|
||||
|
||||
Frame* frame = pk_current_vm->top_frame;
|
||||
bool ok = pk_execdyn(co, frame ? frame->module : NULL, py_peek(-3), py_peek(-2));
|
||||
py_shrink(3);
|
||||
return ok;
|
||||
}
|
||||
|
||||
static bool builtins_exec(int argc, py_Ref argv) {
|
||||
|
@ -1,9 +1,7 @@
|
||||
#include "pocketpy/pocketpy.h"
|
||||
|
||||
#include "pocketpy/common/utils.h"
|
||||
#include "pocketpy/objects/object.h"
|
||||
#include "pocketpy/interpreter/vm.h"
|
||||
#include "pocketpy/common/sstream.h"
|
||||
#include <stdbool.h>
|
||||
|
||||
void pk_mappingproxy__namedict(py_Ref out, py_Ref object) {
|
||||
@ -104,15 +102,3 @@ py_Type pk_namedict__register() {
|
||||
py_bindmethod(type, "clear", namedict_clear);
|
||||
return type;
|
||||
}
|
||||
|
||||
//////////////////////
|
||||
|
||||
void pk_mappingproxy__locals(py_Ref out, Frame* frame) {
|
||||
assert(frame->is_p0_function && !frame->is_locals_proxy);
|
||||
out->type = tp_locals;
|
||||
out->is_ptr = false;
|
||||
out->extra = 0;
|
||||
// this is a weak reference
|
||||
// locals() will expire when the frame is destroyed
|
||||
out->_ptr = frame;
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user