This commit is contained in:
blueloveTH 2024-08-06 13:47:41 +08:00
parent f756bd813d
commit 749435e516
8 changed files with 71 additions and 36 deletions

View File

@ -6,6 +6,7 @@
#include "pocketpy/objects/object.h"
#include "pocketpy/common/config.h"
#include "pocketpy/common/strname.h"
#include "pocketpy/pocketpy.h"
py_TValue* FastLocals__try_get_by_name(py_TValue* locals, const CodeObject* co, py_Name name);
NameDict* FastLocals__to_namedict(py_TValue* locals, const CodeObject* co);
@ -34,7 +35,7 @@ typedef struct Frame {
struct Frame* f_back;
const Bytecode* ip;
const CodeObject* co;
py_TValue module; // weak ref
py_GlobalRef module;
py_StackRef function; // a function object or NULL (global scope)
py_StackRef p0; // unwinding base
py_StackRef locals; // locals base
@ -42,7 +43,7 @@ typedef struct Frame {
} Frame;
Frame* Frame__new(const CodeObject* co,
py_TValue* module,
py_GlobalRef module,
py_StackRef function,
py_StackRef p0,
py_StackRef locals);

View File

@ -1,2 +1,10 @@
#pragma once
#include "pocketpy/interpreter/frame.h"
typedef struct Generator{
Frame* frame;
int state;
} Generator;
void pk_newgenerator(py_Ref out, Frame* frame, int slots);

View File

@ -518,9 +518,10 @@ enum py_PredefinedTypes {
tp_NoneType,
tp_NotImplementedType,
tp_ellipsis,
tp_SyntaxError,
tp_StopIteration,
tp_generator,
/* builtin exceptions */
tp_StopIteration,
tp_SyntaxError,
tp_StackOverflowError,
tp_IOError,
tp_OSError,

View File

@ -134,7 +134,7 @@ FrameResult VM__run_top_frame(VM* self) {
case OP_LOAD_FUNCTION: {
FuncDecl_ decl = c11__getitem(FuncDecl_, &frame->co->func_decls, byte.arg);
Function* ud = py_newobject(SP(), tp_function, 0, sizeof(Function));
Function__ctor(ud, decl, &frame->module);
Function__ctor(ud, decl, frame->module);
if(decl->nested) {
ud->closure = FastLocals__to_namedict(frame->locals, frame->co);
py_Name name = py_name(decl->code.name->data);
@ -173,7 +173,7 @@ FrameResult VM__run_top_frame(VM* self) {
PUSH(tmp);
DISPATCH();
}
tmp = py_getdict(&frame->module, name);
tmp = py_getdict(frame->module, name);
if(tmp != NULL) {
PUSH(tmp);
DISPATCH();
@ -193,7 +193,7 @@ FrameResult VM__run_top_frame(VM* self) {
PUSH(tmp);
DISPATCH();
}
tmp = py_getdict(&frame->module, name);
tmp = py_getdict(frame->module, name);
if(tmp != NULL) {
PUSH(tmp);
DISPATCH();
@ -208,7 +208,7 @@ FrameResult VM__run_top_frame(VM* self) {
}
case OP_LOAD_GLOBAL: {
py_Name name = byte.arg;
py_Ref tmp = py_getdict(&frame->module, name);
py_Ref tmp = py_getdict(frame->module, name);
if(tmp != NULL) {
PUSH(tmp);
DISPATCH();
@ -237,7 +237,7 @@ FrameResult VM__run_top_frame(VM* self) {
DISPATCH();
}
// load global if attribute not found
tmp = py_getdict(&frame->module, name);
tmp = py_getdict(frame->module, name);
if(tmp) {
PUSH(tmp);
DISPATCH();
@ -300,13 +300,13 @@ FrameResult VM__run_top_frame(VM* self) {
// }
}
} else {
py_setdict(&frame->module, name, TOP());
py_setdict(frame->module, name, TOP());
}
POP();
DISPATCH();
}
case OP_STORE_GLOBAL: {
py_setdict(&frame->module, byte.arg, TOP());
py_setdict(frame->module, byte.arg, TOP());
POP();
DISPATCH();
}
@ -361,7 +361,7 @@ FrameResult VM__run_top_frame(VM* self) {
// }
}
} else {
bool ok = py_deldict(&frame->module, name);
bool ok = py_deldict(frame->module, name);
if(!ok) {
NameError(name);
goto __ERROR;
@ -371,7 +371,7 @@ FrameResult VM__run_top_frame(VM* self) {
}
case OP_DELETE_GLOBAL: {
py_Name name = byte.arg;
bool ok = py_deldict(&frame->module, name);
bool ok = py_deldict(frame->module, name);
if(!ok) {
NameError(name);
goto __ERROR;
@ -802,7 +802,7 @@ FrameResult VM__run_top_frame(VM* self) {
ImportError("cannot import name '%n'", name);
goto __ERROR;
} else {
py_setdict(&frame->module, name, value);
py_setdict(frame->module, name, value);
}
}
} else {
@ -811,7 +811,7 @@ FrameResult VM__run_top_frame(VM* self) {
if(!kv->key) continue;
c11_sv name = py_name2sv(kv->key);
if(name.size == 0 || name.data[0] == '_') continue;
py_setdict(&frame->module, kv->key, &kv->value);
py_setdict(frame->module, kv->key, &kv->value);
}
}
POP();
@ -857,7 +857,7 @@ FrameResult VM__run_top_frame(VM* self) {
}
POP();
py_Type type =
pk_newtype(py_name2str(name), base, &frame->module, NULL, true, false);
pk_newtype(py_name2str(name), base, frame->module, NULL, true, false);
PUSH(py_tpobject(type));
self->__curr_class = TOP();
DISPATCH();
@ -866,7 +866,7 @@ FrameResult VM__run_top_frame(VM* self) {
// [cls or decorated]
py_Name name = byte.arg;
// set into f_globals
py_setdict(&frame->module, name, TOP());
py_setdict(frame->module, name, TOP());
if(py_istype(TOP(), tp_type)) {
// call on_end_subclass
@ -950,7 +950,7 @@ FrameResult VM__run_top_frame(VM* self) {
py_TValue* tmp = c11__at(py_TValue, &frame->co->consts, byte.arg);
const char* string = py_tostr(tmp);
// TODO: optimize this
if(!py_exec(string, "<eval>", EVAL_MODE, &frame->module)) goto __ERROR;
if(!py_exec(string, "<eval>", EVAL_MODE, frame->module)) goto __ERROR;
PUSH(py_retval());
DISPATCH();
}

View File

@ -1,6 +1,7 @@
#include "pocketpy/interpreter/frame.h"
#include "pocketpy/objects/codeobject.h"
#include "pocketpy/objects/object.h"
#include "pocketpy/pocketpy.h"
void ValueStack__ctor(ValueStack* self) {
self->sp = self->begin;
@ -35,7 +36,7 @@ UnwindTarget* UnwindTarget__new(UnwindTarget* next, int iblock, int offset) {
void UnwindTarget__delete(UnwindTarget* self) { free(self); }
Frame* Frame__new(const CodeObject* co,
py_TValue* module,
py_GlobalRef module,
py_StackRef function,
py_StackRef p0,
py_StackRef locals) {
@ -44,7 +45,7 @@ Frame* Frame__new(const CodeObject* co,
self->f_back = NULL;
self->ip = (Bytecode*)co->codes.data - 1;
self->co = co;
self->module = *module;
self->module = module;
self->function = function;
self->p0 = p0;
self->locals = locals;

View File

@ -1 +1,8 @@
#include "pocketpy/interpreter/generator.h"
#include "pocketpy/interpreter/frame.h"
void pk_newgenerator(py_Ref out, Frame* frame, int slots) {
Generator* ud = py_newobject(out, tp_generator, slots, sizeof(Generator));
ud->frame = frame;
ud->state = 0;
}

View File

@ -2,6 +2,7 @@
#include "pocketpy/common/memorypool.h"
#include "pocketpy/common/sstream.h"
#include "pocketpy/common/utils.h"
#include "pocketpy/interpreter/generator.h"
#include "pocketpy/objects/base.h"
#include "pocketpy/common/_generated.h"
#include "pocketpy/pocketpy.h"
@ -126,9 +127,7 @@ void VM__ctor(VM* self) {
validate(tp_NotImplementedType,
pk_newtype("NotImplementedType", tp_object, NULL, NULL, false, true));
validate(tp_ellipsis, pk_newtype("ellipsis", tp_object, NULL, NULL, false, true));
validate(tp_SyntaxError, pk_newtype("SyntaxError", tp_Exception, NULL, NULL, false, true));
validate(tp_StopIteration, pk_newtype("StopIteration", tp_Exception, NULL, NULL, false, true));
validate(tp_generator, pk_newtype("generator", tp_object, NULL, NULL, false, true));
self->builtins = pk_builtins__register();
@ -140,6 +139,8 @@ void VM__ctor(VM* self) {
validate(tp_##name, type); \
} while(0)
INJECT_BUILTIN_EXC(StopIteration);
INJECT_BUILTIN_EXC(SyntaxError);
INJECT_BUILTIN_EXC(StackOverflowError);
INJECT_BUILTIN_EXC(IOError);
INJECT_BUILTIN_EXC(OSError);
@ -160,11 +161,26 @@ void VM__ctor(VM* self) {
#undef validate
/* Setup Public Builtin Types */
py_Type public_types[] = {tp_object, tp_type, tp_int, tp_float,
tp_bool, tp_str, tp_list, tp_tuple,
tp_slice, tp_range, tp_bytes, tp_dict,
tp_property, tp_staticmethod, tp_classmethod, tp_super,
tp_BaseException, tp_Exception, tp_StopIteration, tp_SyntaxError};
py_Type public_types[] = {
tp_object,
tp_type,
tp_int,
tp_float,
tp_bool,
tp_str,
tp_list,
tp_tuple,
tp_slice,
tp_range,
tp_bytes,
tp_dict,
tp_property,
tp_staticmethod,
tp_classmethod,
tp_super,
tp_BaseException,
tp_Exception,
};
for(int i = 0; i < c11__count_array(public_types); i++) {
py_TypeInfo* ti = c11__at(py_TypeInfo, &self->types, public_types[i]);
@ -438,6 +454,9 @@ FrameResult VM__vectorcall(VM* self, uint16_t argc, uint16_t kwargc, bool opcall
case FuncType_GENERATOR: {
bool ok = prepare_py_call(self->__vectorcall_buffer, argv, p1, kwargc, fn->decl);
if(!ok) return RES_ERROR;
Frame* frame = Frame__new(co, &fn->module, p0, p0, argv);
pk_newgenerator(py_retval(), frame, 0);
self->stack.sp = p0;
return RES_RETURN;
}
// prepare_py_call(__vectorcall_buffer, args, kwargs, fn.decl);
@ -560,7 +579,7 @@ void ManagedHeap__mark(ManagedHeap* self) {
}
// mark frame
for(Frame* frame = vm->top_frame; frame; frame = frame->f_back) {
mark_value(&frame->module);
mark_value(frame->module);
}
// mark vm's registers
mark_value(&vm->last_retval);

View File

@ -68,7 +68,7 @@ int py_import(const char* path_cstr) {
c11_sv top_filename = c11_string__sv(vm->top_frame->co->src->filename);
int is_init = c11_sv__endswith(top_filename, (c11_sv){"__init__.py", 11});
py_Ref package = py_getdict(&vm->top_frame->module, __path__);
py_Ref package = py_getdict(vm->top_frame->module, __path__);
c11_sv package_sv = py_tosv(package);
if(package_sv.size == 0) {
return ImportError("attempted relative import with no known parent package");
@ -323,14 +323,14 @@ static bool builtins_exec(int argc, py_Ref argv) {
PY_CHECK_ARGC(1);
PY_CHECK_ARG_TYPE(0, tp_str);
Frame* frame = pk_current_vm->top_frame;
return py_exec(py_tostr(argv), "<exec>", EXEC_MODE, &frame->module);
return py_exec(py_tostr(argv), "<exec>", EXEC_MODE, frame->module);
}
static bool builtins_eval(int argc, py_Ref argv) {
PY_CHECK_ARGC(1);
PY_CHECK_ARG_TYPE(0, tp_str);
Frame* frame = pk_current_vm->top_frame;
return py_exec(py_tostr(argv), "<eval>", EVAL_MODE, &frame->module);
return py_exec(py_tostr(argv), "<eval>", EVAL_MODE, frame->module);
}
static bool builtins_isinstance(int argc, py_Ref argv) {
@ -418,9 +418,7 @@ static bool builtins_chr(int argc, py_Ref argv) {
PY_CHECK_ARGC(1);
PY_CHECK_ARG_TYPE(0, tp_int);
py_i64 val = py_toint(py_arg(0));
if(val < 0 || val > 128) {
return ValueError("chr() arg not in range(128)");
}
if(val < 0 || val > 128) { return ValueError("chr() arg not in range(128)"); }
py_newstrn(py_retval(), (const char*)&val, 1);
return true;
}