mirror of
https://github.com/pocketpy/pocketpy
synced 2025-10-19 19:10:17 +00:00
...
This commit is contained in:
parent
20cd2064d4
commit
51e2433404
@ -38,7 +38,7 @@ typedef struct Frame {
|
|||||||
struct Frame* f_back;
|
struct Frame* f_back;
|
||||||
const Bytecode* ip;
|
const Bytecode* ip;
|
||||||
const CodeObject* co;
|
const CodeObject* co;
|
||||||
PyObject* module;
|
py_TValue module; // weak ref
|
||||||
PyObject* function; // a function object or NULL (global scope)
|
PyObject* function; // a function object or NULL (global scope)
|
||||||
py_TValue* p0; // unwinding base
|
py_TValue* p0; // unwinding base
|
||||||
py_TValue* locals; // locals base
|
py_TValue* locals; // locals base
|
||||||
@ -47,7 +47,7 @@ typedef struct Frame {
|
|||||||
} Frame;
|
} Frame;
|
||||||
|
|
||||||
Frame* Frame__new(const CodeObject* co,
|
Frame* Frame__new(const CodeObject* co,
|
||||||
PyObject* module,
|
py_TValue* module,
|
||||||
const py_TValue* function,
|
const py_TValue* function,
|
||||||
py_TValue* p0,
|
py_TValue* p0,
|
||||||
py_TValue* locals,
|
py_TValue* locals,
|
||||||
@ -66,12 +66,6 @@ PK_INLINE int Frame__iblock(const Frame* self) {
|
|||||||
return c11__getitem(BytecodeEx, &self->co->codes_ex, ip).iblock;
|
return c11__getitem(BytecodeEx, &self->co->codes_ex, ip).iblock;
|
||||||
}
|
}
|
||||||
|
|
||||||
PK_INLINE pk_NameDict* Frame__f_globals(Frame* self) { return PyObject__dict(self->module); }
|
|
||||||
|
|
||||||
PK_INLINE py_TValue* Frame__f_globals_try_get(Frame* self, py_Name name) {
|
|
||||||
return pk_NameDict__try_get(Frame__f_globals(self), name);
|
|
||||||
}
|
|
||||||
|
|
||||||
PK_INLINE py_TValue* Frame__f_locals_try_get(Frame* self, py_Name name) {
|
PK_INLINE py_TValue* Frame__f_locals_try_get(Frame* self, py_Name name) {
|
||||||
return FastLocals__try_get_by_name(self->locals, self->locals_co, name);
|
return FastLocals__try_get_by_name(self->locals, self->locals_co, name);
|
||||||
}
|
}
|
||||||
|
@ -23,7 +23,7 @@ typedef struct pk_TypeInfo {
|
|||||||
|
|
||||||
c11_vector /*T=py_Name*/ annotated_fields;
|
c11_vector /*T=py_Name*/ annotated_fields;
|
||||||
|
|
||||||
py_CFunction on_end_subclass; // backdoor for enum module
|
void (*on_end_subclass)(struct pk_TypeInfo*); // backdoor for enum module
|
||||||
|
|
||||||
/* Magic Slots */
|
/* Magic Slots */
|
||||||
py_TValue magic[64];
|
py_TValue magic[64];
|
||||||
@ -49,7 +49,7 @@ typedef struct pk_VM {
|
|||||||
|
|
||||||
py_TValue reg[8]; // users' registers
|
py_TValue reg[8]; // users' registers
|
||||||
|
|
||||||
py_TValue __curr_class;
|
py_TValue* __curr_class;
|
||||||
FuncDecl_ __dynamic_func_decl;
|
FuncDecl_ __dynamic_func_decl;
|
||||||
py_TValue __vectorcall_buffer[PK_MAX_CO_VARNAMES];
|
py_TValue __vectorcall_buffer[PK_MAX_CO_VARNAMES];
|
||||||
|
|
||||||
|
@ -36,8 +36,6 @@ typedef struct py_TValue {
|
|||||||
static_assert(sizeof(py_CFunction) <= 8, "sizeof(py_CFunction) > 8");
|
static_assert(sizeof(py_CFunction) <= 8, "sizeof(py_CFunction) > 8");
|
||||||
static_assert(sizeof(py_TValue) == 16, "sizeof(py_TValue) != 16");
|
static_assert(sizeof(py_TValue) == 16, "sizeof(py_TValue) != 16");
|
||||||
|
|
||||||
extern py_TValue PY_NIL;
|
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
@ -137,13 +137,13 @@ FuncDecl_ FuncDecl__build(c11_sv name,
|
|||||||
// runtime function
|
// runtime function
|
||||||
typedef struct Function {
|
typedef struct Function {
|
||||||
FuncDecl_ decl;
|
FuncDecl_ decl;
|
||||||
PyObject* module; // weak ref
|
py_TValue module; // weak ref
|
||||||
PyObject* clazz; // weak ref
|
PyObject* clazz; // weak ref
|
||||||
pk_NameDict* closure; // strong ref
|
pk_NameDict* closure; // strong ref
|
||||||
py_CFunction cfunc; // wrapped C function
|
py_CFunction cfunc; // wrapped C function
|
||||||
} Function;
|
} Function;
|
||||||
|
|
||||||
void Function__ctor(Function* self, FuncDecl_ decl, PyObject* module);
|
void Function__ctor(Function* self, FuncDecl_ decl, py_TValue* module);
|
||||||
void Function__dtor(Function* self);
|
void Function__dtor(Function* self);
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
|
@ -132,6 +132,7 @@ bool py_issubclass(py_Type derived, py_Type base);
|
|||||||
extern py_GlobalRef py_True;
|
extern py_GlobalRef py_True;
|
||||||
extern py_GlobalRef py_False;
|
extern py_GlobalRef py_False;
|
||||||
extern py_GlobalRef py_None;
|
extern py_GlobalRef py_None;
|
||||||
|
extern py_GlobalRef py_NIL;
|
||||||
|
|
||||||
/************* References *************/
|
/************* References *************/
|
||||||
#define PY_CHECK_ARGC(n) \
|
#define PY_CHECK_ARGC(n) \
|
||||||
@ -183,6 +184,7 @@ py_GlobalRef py_reg(int i);
|
|||||||
/// Returns a reference to the value or NULL if not found.
|
/// Returns a reference to the value or NULL if not found.
|
||||||
py_ObjectRef py_getdict(const py_Ref self, py_Name name);
|
py_ObjectRef py_getdict(const py_Ref self, py_Name name);
|
||||||
void py_setdict(py_Ref self, py_Name name, const py_Ref val);
|
void py_setdict(py_Ref self, py_Name name, const py_Ref val);
|
||||||
|
bool py_deldict(py_Ref self, py_Name name);
|
||||||
|
|
||||||
/// Get the reference of the i-th slot of the object.
|
/// Get the reference of the i-th slot of the object.
|
||||||
/// The object must have slots and `i` must be in range.
|
/// The object must have slots and `i` must be in range.
|
||||||
|
@ -96,8 +96,6 @@ OPCODE(UNPACK_EX)
|
|||||||
OPCODE(BEGIN_CLASS)
|
OPCODE(BEGIN_CLASS)
|
||||||
OPCODE(END_CLASS)
|
OPCODE(END_CLASS)
|
||||||
OPCODE(STORE_CLASS_ATTR)
|
OPCODE(STORE_CLASS_ATTR)
|
||||||
OPCODE(BEGIN_CLASS_DECORATION)
|
|
||||||
OPCODE(END_CLASS_DECORATION)
|
|
||||||
OPCODE(ADD_CLASS_ANNOTATION)
|
OPCODE(ADD_CLASS_ANNOTATION)
|
||||||
/**************************/
|
/**************************/
|
||||||
OPCODE(WITH_ENTER)
|
OPCODE(WITH_ENTER)
|
||||||
|
@ -1291,6 +1291,7 @@ static void Ctx__exit_block(Ctx* self) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
static void Ctx__s_emit_decorators(Ctx* self, int count) {
|
static void Ctx__s_emit_decorators(Ctx* self, int count) {
|
||||||
|
if(count == 0) return;
|
||||||
assert(Ctx__s_size(self) >= count);
|
assert(Ctx__s_size(self) >= count);
|
||||||
// [obj]
|
// [obj]
|
||||||
for(int i = 0; i < count; i++) {
|
for(int i = 0; i < count; i++) {
|
||||||
@ -2252,7 +2253,7 @@ static Error* read_literal(Compiler* self, py_Ref out) {
|
|||||||
}
|
}
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
default: *out = PY_NIL; return NULL;
|
default: py_newnil(out); return NULL;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -2346,6 +2347,37 @@ static Error* compile_function(Compiler* self, int decorators) {
|
|||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static Error* compile_class(Compiler* self, int decorators) {
|
||||||
|
Error* err;
|
||||||
|
consume(TK_ID);
|
||||||
|
py_Name name = py_namev(Token__sv(prev()));
|
||||||
|
bool has_base = false;
|
||||||
|
if(match(TK_LPAREN)) {
|
||||||
|
if(is_expression(self, false)) {
|
||||||
|
check(EXPR(self));
|
||||||
|
has_base = true; // [base]
|
||||||
|
}
|
||||||
|
consume(TK_RPAREN);
|
||||||
|
}
|
||||||
|
if(!has_base) {
|
||||||
|
Ctx__emit_(ctx(), OP_LOAD_NONE, BC_NOARG, prev()->line);
|
||||||
|
} else {
|
||||||
|
Ctx__s_emit_top(ctx()); // []
|
||||||
|
}
|
||||||
|
Ctx__emit_(ctx(), OP_BEGIN_CLASS, name, BC_KEEPLINE);
|
||||||
|
|
||||||
|
c11__foreach(Ctx, &self->contexts, it) {
|
||||||
|
if(it->is_compiling_class) return SyntaxError("nested class is not allowed");
|
||||||
|
}
|
||||||
|
ctx()->is_compiling_class = true;
|
||||||
|
check(compile_block_body(self, compile_stmt));
|
||||||
|
ctx()->is_compiling_class = false;
|
||||||
|
|
||||||
|
Ctx__s_emit_decorators(ctx(), decorators);
|
||||||
|
Ctx__emit_(ctx(), OP_END_CLASS, name, BC_KEEPLINE);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
static Error* compile_decorated(Compiler* self) {
|
static Error* compile_decorated(Compiler* self) {
|
||||||
Error* err;
|
Error* err;
|
||||||
int count = 0;
|
int count = 0;
|
||||||
@ -2356,7 +2388,7 @@ static Error* compile_decorated(Compiler* self) {
|
|||||||
} while(match(TK_DECORATOR));
|
} while(match(TK_DECORATOR));
|
||||||
|
|
||||||
if(match(TK_CLASS)) {
|
if(match(TK_CLASS)) {
|
||||||
// check(compile_class(count));
|
check(compile_class(self, count));
|
||||||
} else {
|
} else {
|
||||||
consume(TK_DEF);
|
consume(TK_DEF);
|
||||||
check(compile_function(self, count));
|
check(compile_function(self, count));
|
||||||
@ -2467,8 +2499,7 @@ static Error* compile_try_except(Compiler* self) {
|
|||||||
static Error* compile_stmt(Compiler* self) {
|
static Error* compile_stmt(Compiler* self) {
|
||||||
Error* err;
|
Error* err;
|
||||||
if(match(TK_CLASS)) {
|
if(match(TK_CLASS)) {
|
||||||
// check(compile_class());
|
check(compile_class(self, 0));
|
||||||
assert(false);
|
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
advance();
|
advance();
|
||||||
|
@ -143,7 +143,7 @@ pk_FrameResult pk_VM__run_top_frame(pk_VM* self) {
|
|||||||
case OP_LOAD_FUNCTION: {
|
case OP_LOAD_FUNCTION: {
|
||||||
FuncDecl_ decl = c11__getitem(FuncDecl_, &frame->co->func_decls, byte.arg);
|
FuncDecl_ decl = c11__getitem(FuncDecl_, &frame->co->func_decls, byte.arg);
|
||||||
Function* ud = py_newobject(SP(), tp_function, 0, sizeof(Function));
|
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) {
|
if(decl->nested) {
|
||||||
ud->closure = FastLocals__to_namedict(frame->locals, frame->locals_co);
|
ud->closure = FastLocals__to_namedict(frame->locals, frame->locals_co);
|
||||||
py_Name name = py_namev(c11_string__sv(decl->code.name));
|
py_Name name = py_namev(c11_string__sv(decl->code.name));
|
||||||
@ -182,7 +182,7 @@ pk_FrameResult pk_VM__run_top_frame(pk_VM* self) {
|
|||||||
PUSH(tmp);
|
PUSH(tmp);
|
||||||
DISPATCH();
|
DISPATCH();
|
||||||
}
|
}
|
||||||
tmp = Frame__f_globals_try_get(frame, name);
|
tmp = py_getdict(&frame->module, name);
|
||||||
if(tmp != NULL) {
|
if(tmp != NULL) {
|
||||||
PUSH(tmp);
|
PUSH(tmp);
|
||||||
DISPATCH();
|
DISPATCH();
|
||||||
@ -202,7 +202,7 @@ pk_FrameResult pk_VM__run_top_frame(pk_VM* self) {
|
|||||||
PUSH(tmp);
|
PUSH(tmp);
|
||||||
DISPATCH();
|
DISPATCH();
|
||||||
}
|
}
|
||||||
tmp = Frame__f_globals_try_get(frame, name);
|
tmp = py_getdict(&frame->module, name);
|
||||||
if(tmp != NULL) {
|
if(tmp != NULL) {
|
||||||
PUSH(tmp);
|
PUSH(tmp);
|
||||||
DISPATCH();
|
DISPATCH();
|
||||||
@ -217,7 +217,7 @@ pk_FrameResult pk_VM__run_top_frame(pk_VM* self) {
|
|||||||
}
|
}
|
||||||
case OP_LOAD_GLOBAL: {
|
case OP_LOAD_GLOBAL: {
|
||||||
py_Name name = byte.arg;
|
py_Name name = byte.arg;
|
||||||
py_Ref tmp = Frame__f_globals_try_get(frame, name);
|
py_Ref tmp = py_getdict(&frame->module, name);
|
||||||
if(tmp != NULL) {
|
if(tmp != NULL) {
|
||||||
PUSH(tmp);
|
PUSH(tmp);
|
||||||
DISPATCH();
|
DISPATCH();
|
||||||
@ -238,14 +238,13 @@ pk_FrameResult pk_VM__run_top_frame(pk_VM* self) {
|
|||||||
DISPATCH();
|
DISPATCH();
|
||||||
}
|
}
|
||||||
case OP_LOAD_CLASS_GLOBAL: {
|
case OP_LOAD_CLASS_GLOBAL: {
|
||||||
assert(self->__curr_class.type);
|
|
||||||
py_Name name = byte.arg;
|
py_Name name = byte.arg;
|
||||||
if(py_getattr(&self->__curr_class, name, SP())) {
|
if(py_getattr(self->__curr_class, name, SP())) {
|
||||||
SP()++;
|
SP()++;
|
||||||
DISPATCH();
|
DISPATCH();
|
||||||
}
|
}
|
||||||
// load global if attribute not found
|
// load global if attribute not found
|
||||||
py_Ref tmp = Frame__f_globals_try_get(frame, name);
|
py_Ref tmp = py_getdict(&frame->module, name);
|
||||||
if(tmp) {
|
if(tmp) {
|
||||||
PUSH(tmp);
|
PUSH(tmp);
|
||||||
DISPATCH();
|
DISPATCH();
|
||||||
@ -294,12 +293,11 @@ pk_FrameResult pk_VM__run_top_frame(pk_VM* self) {
|
|||||||
}
|
}
|
||||||
case OP_STORE_FAST: frame->locals[byte.arg] = POPX(); DISPATCH();
|
case OP_STORE_FAST: frame->locals[byte.arg] = POPX(); DISPATCH();
|
||||||
case OP_STORE_NAME: {
|
case OP_STORE_NAME: {
|
||||||
py_Name _name = byte.arg;
|
py_Name name = byte.arg;
|
||||||
py_TValue _0 = POPX();
|
|
||||||
if(frame->function) {
|
if(frame->function) {
|
||||||
py_Ref slot = Frame__f_locals_try_get(frame, _name);
|
py_Ref slot = Frame__f_locals_try_get(frame, name);
|
||||||
if(slot != NULL) {
|
if(slot != NULL) {
|
||||||
*slot = _0; // store in locals if possible
|
*slot = *TOP(); // store in locals if possible
|
||||||
} else {
|
} else {
|
||||||
// Function& func = frame->_callable->as<Function>();
|
// Function& func = frame->_callable->as<Function>();
|
||||||
// if(func.decl == __dynamic_func_decl) {
|
// if(func.decl == __dynamic_func_decl) {
|
||||||
@ -311,14 +309,16 @@ pk_FrameResult pk_VM__run_top_frame(pk_VM* self) {
|
|||||||
// }
|
// }
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
pk_NameDict__set(Frame__f_globals(frame), _name, _0);
|
py_setdict(&frame->module, name, TOP());
|
||||||
}
|
}
|
||||||
|
POP();
|
||||||
DISPATCH();
|
DISPATCH();
|
||||||
}
|
}
|
||||||
case OP_STORE_GLOBAL:
|
case OP_STORE_GLOBAL: {
|
||||||
pk_NameDict__set(Frame__f_globals(frame), byte.arg, POPX());
|
py_setdict(&frame->module, byte.arg, TOP());
|
||||||
|
POP();
|
||||||
DISPATCH();
|
DISPATCH();
|
||||||
|
}
|
||||||
case OP_STORE_ATTR: {
|
case OP_STORE_ATTR: {
|
||||||
int err = py_setattr(TOP(), byte.arg, SECOND());
|
int err = py_setattr(TOP(), byte.arg, SECOND());
|
||||||
if(err) goto __ERROR;
|
if(err) goto __ERROR;
|
||||||
@ -370,8 +370,7 @@ pk_FrameResult pk_VM__run_top_frame(pk_VM* self) {
|
|||||||
// }
|
// }
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
// if(!frame->f_globals().del(_name)) vm->NameError(_name);
|
bool ok = py_deldict(&frame->module, name);
|
||||||
bool ok = pk_NameDict__del(Frame__f_globals(frame), name);
|
|
||||||
if(!ok) {
|
if(!ok) {
|
||||||
NameError(name);
|
NameError(name);
|
||||||
goto __ERROR;
|
goto __ERROR;
|
||||||
@ -381,7 +380,7 @@ pk_FrameResult pk_VM__run_top_frame(pk_VM* self) {
|
|||||||
}
|
}
|
||||||
case OP_DELETE_GLOBAL: {
|
case OP_DELETE_GLOBAL: {
|
||||||
py_Name name = byte.arg;
|
py_Name name = byte.arg;
|
||||||
bool ok = pk_NameDict__del(Frame__f_globals(frame), name);
|
bool ok = py_deldict(&frame->module, name);
|
||||||
if(!ok) {
|
if(!ok) {
|
||||||
NameError(name);
|
NameError(name);
|
||||||
goto __ERROR;
|
goto __ERROR;
|
||||||
@ -794,7 +793,58 @@ pk_FrameResult pk_VM__run_top_frame(pk_VM* self) {
|
|||||||
}
|
}
|
||||||
DISPATCH();
|
DISPATCH();
|
||||||
}
|
}
|
||||||
|
///////////
|
||||||
|
case OP_BEGIN_CLASS: {
|
||||||
|
// [base]
|
||||||
|
py_Name name = byte.arg;
|
||||||
|
py_Type base;
|
||||||
|
if(py_isnone(TOP())) {
|
||||||
|
base = tp_object;
|
||||||
|
} else {
|
||||||
|
if(!py_checktype(TOP(), tp_type)) goto __ERROR;
|
||||||
|
base = py_totype(TOP());
|
||||||
|
}
|
||||||
|
POP();
|
||||||
|
py_Type type = py_newtype(py_name2str(name), base, &frame->module, NULL);
|
||||||
|
PUSH(py_tpobject(type));
|
||||||
|
self->__curr_class = TOP();
|
||||||
|
DISPATCH();
|
||||||
|
}
|
||||||
|
case OP_END_CLASS: {
|
||||||
|
// [cls or decorated]
|
||||||
|
py_Name name = byte.arg;
|
||||||
|
// set into f_globals
|
||||||
|
py_setdict(&frame->module, name, TOP());
|
||||||
|
|
||||||
|
if(py_istype(TOP(), tp_type)) {
|
||||||
|
// call on_end_subclass
|
||||||
|
pk_TypeInfo* ti = c11__at(pk_TypeInfo, &self->types, py_totype(TOP()));
|
||||||
|
if(ti->base != tp_object) {
|
||||||
|
// PyTypeInfo* base_ti = &_all_types[ti->base];
|
||||||
|
pk_TypeInfo* base_ti = c11__at(pk_TypeInfo, &self->types, ti->base);
|
||||||
|
if(base_ti->on_end_subclass) base_ti->on_end_subclass(ti);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
POP();
|
||||||
|
self->__curr_class = NULL;
|
||||||
|
DISPATCH();
|
||||||
|
}
|
||||||
|
case OP_STORE_CLASS_ATTR: {
|
||||||
|
py_Name name = byte.arg;
|
||||||
|
if(py_istype(TOP(), tp_function)) {
|
||||||
|
Function* ud = py_touserdata(TOP());
|
||||||
|
ud->clazz = self->__curr_class->_obj;
|
||||||
|
}
|
||||||
|
py_setdict(self->__curr_class, name, TOP());
|
||||||
|
POP();
|
||||||
|
DISPATCH();
|
||||||
|
}
|
||||||
|
case OP_ADD_CLASS_ANNOTATION: {
|
||||||
|
py_Type type = py_totype(self->__curr_class);
|
||||||
|
pk_TypeInfo* ti = c11__at(pk_TypeInfo, &self->types, type);
|
||||||
|
c11_vector__push(py_Name, &ti->annotated_fields, byte.arg);
|
||||||
|
DISPATCH();
|
||||||
|
}
|
||||||
///////////
|
///////////
|
||||||
case OP_RAISE_ASSERT: {
|
case OP_RAISE_ASSERT: {
|
||||||
if(byte.arg) {
|
if(byte.arg) {
|
||||||
|
@ -34,7 +34,7 @@ UnwindTarget* UnwindTarget__new(UnwindTarget* next, int iblock, int offset) {
|
|||||||
void UnwindTarget__delete(UnwindTarget* self) { free(self); }
|
void UnwindTarget__delete(UnwindTarget* self) { free(self); }
|
||||||
|
|
||||||
Frame* Frame__new(const CodeObject* co,
|
Frame* Frame__new(const CodeObject* co,
|
||||||
PyObject* module,
|
py_TValue* module,
|
||||||
const py_TValue* function,
|
const py_TValue* function,
|
||||||
py_TValue* p0,
|
py_TValue* p0,
|
||||||
py_TValue* locals,
|
py_TValue* locals,
|
||||||
@ -44,7 +44,7 @@ Frame* Frame__new(const CodeObject* co,
|
|||||||
self->f_back = NULL;
|
self->f_back = NULL;
|
||||||
self->ip = (Bytecode*)co->codes.data - 1;
|
self->ip = (Bytecode*)co->codes.data - 1;
|
||||||
self->co = co;
|
self->co = co;
|
||||||
self->module = module;
|
self->module = *module;
|
||||||
self->function = function ? function->_obj : NULL;
|
self->function = function ? function->_obj : NULL;
|
||||||
self->p0 = p0;
|
self->p0 = p0;
|
||||||
self->locals = locals;
|
self->locals = locals;
|
||||||
|
@ -47,7 +47,7 @@ static void pk_TypeInfo__ctor(pk_TypeInfo* self,
|
|||||||
._obj = typeobj,
|
._obj = typeobj,
|
||||||
};
|
};
|
||||||
|
|
||||||
self->module = module ? *module : PY_NIL;
|
self->module = module ? *module : *py_NIL;
|
||||||
c11_vector__ctor(&self->annotated_fields, sizeof(py_Name));
|
c11_vector__ctor(&self->annotated_fields, sizeof(py_Name));
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -59,19 +59,19 @@ void pk_VM__ctor(pk_VM* self) {
|
|||||||
pk_NameDict__ctor(&self->modules);
|
pk_NameDict__ctor(&self->modules);
|
||||||
c11_vector__ctor(&self->types, sizeof(pk_TypeInfo));
|
c11_vector__ctor(&self->types, sizeof(pk_TypeInfo));
|
||||||
|
|
||||||
self->builtins = PY_NIL;
|
self->builtins = *py_NIL;
|
||||||
self->main = PY_NIL;
|
self->main = *py_NIL;
|
||||||
|
|
||||||
self->_ceval_on_step = NULL;
|
self->_ceval_on_step = NULL;
|
||||||
self->_import_file = pk_default_import_file;
|
self->_import_file = pk_default_import_file;
|
||||||
self->_stdout = pk_default_stdout;
|
self->_stdout = pk_default_stdout;
|
||||||
self->_stderr = pk_default_stderr;
|
self->_stderr = pk_default_stderr;
|
||||||
|
|
||||||
self->last_retval = PY_NIL;
|
self->last_retval = *py_NIL;
|
||||||
self->last_exception = PY_NIL;
|
self->last_exception = *py_NIL;
|
||||||
self->is_stopiteration = false;
|
self->is_stopiteration = false;
|
||||||
|
|
||||||
self->__curr_class = PY_NIL;
|
self->__curr_class = NULL;
|
||||||
self->__dynamic_func_decl = NULL;
|
self->__dynamic_func_decl = NULL;
|
||||||
|
|
||||||
pk_ManagedHeap__ctor(&self->heap, self);
|
pk_ManagedHeap__ctor(&self->heap, self);
|
||||||
@ -388,7 +388,7 @@ pk_FrameResult pk_VM__vectorcall(pk_VM* self, uint16_t argc, uint16_t kwargc, bo
|
|||||||
memcpy(argv, self->__vectorcall_buffer, co->nlocals * sizeof(py_TValue));
|
memcpy(argv, self->__vectorcall_buffer, co->nlocals * sizeof(py_TValue));
|
||||||
// submit the call
|
// submit the call
|
||||||
if(!fn->cfunc) {
|
if(!fn->cfunc) {
|
||||||
pk_VM__push_frame(self, Frame__new(co, fn->module, p0, p0, argv, co));
|
pk_VM__push_frame(self, Frame__new(co, &fn->module, p0, p0, argv, co));
|
||||||
return opcall ? RES_CALL : pk_VM__run_top_frame(self);
|
return opcall ? RES_CALL : pk_VM__run_top_frame(self);
|
||||||
} else {
|
} else {
|
||||||
bool ok = py_callcfunc(p0, fn->cfunc, co->nlocals, argv);
|
bool ok = py_callcfunc(p0, fn->cfunc, co->nlocals, argv);
|
||||||
@ -408,10 +408,10 @@ pk_FrameResult pk_VM__vectorcall(pk_VM* self, uint16_t argc, uint16_t kwargc, bo
|
|||||||
// [callable, <self>, args..., local_vars...]
|
// [callable, <self>, args..., local_vars...]
|
||||||
// ^p0 ^p1 ^_sp
|
// ^p0 ^p1 ^_sp
|
||||||
self->stack.sp = argv + co->nlocals;
|
self->stack.sp = argv + co->nlocals;
|
||||||
// initialize local variables to PY_NIL
|
// initialize local variables to py_NIL
|
||||||
memset(p1, 0, (char*)self->stack.sp - (char*)p1);
|
memset(p1, 0, (char*)self->stack.sp - (char*)p1);
|
||||||
// submit the call
|
// submit the call
|
||||||
pk_VM__push_frame(self, Frame__new(co, fn->module, p0, p0, argv, co));
|
pk_VM__push_frame(self, Frame__new(co, &fn->module, p0, p0, argv, co));
|
||||||
return opcall ? RES_CALL : pk_VM__run_top_frame(self);
|
return opcall ? RES_CALL : pk_VM__run_top_frame(self);
|
||||||
case FuncType_GENERATOR:
|
case FuncType_GENERATOR:
|
||||||
assert(false);
|
assert(false);
|
||||||
@ -537,15 +537,17 @@ void pk_ManagedHeap__mark(pk_ManagedHeap* self) {
|
|||||||
for(py_TValue* p = vm->stack.begin; p != vm->stack.end; p++) {
|
for(py_TValue* p = vm->stack.begin; p != vm->stack.end; p++) {
|
||||||
mark_value(p);
|
mark_value(p);
|
||||||
}
|
}
|
||||||
|
// mark frame
|
||||||
|
for(Frame* frame = vm->top_frame; frame; frame = frame->f_back) {
|
||||||
|
mark_value(&frame->module);
|
||||||
|
if(frame->function) mark_object(frame->function);
|
||||||
|
}
|
||||||
// mark vm's registers
|
// mark vm's registers
|
||||||
mark_value(&vm->last_retval);
|
mark_value(&vm->last_retval);
|
||||||
mark_value(&vm->last_exception);
|
mark_value(&vm->last_exception);
|
||||||
for(int i = 0; i < c11__count_array(vm->reg); i++) {
|
for(int i = 0; i < c11__count_array(vm->reg); i++) {
|
||||||
mark_value(&vm->reg[i]);
|
mark_value(&vm->reg[i]);
|
||||||
}
|
}
|
||||||
|
|
||||||
mark_value(&vm->__curr_class);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void pk_print_stack(pk_VM* self, Frame* frame, Bytecode byte) {
|
void pk_print_stack(pk_VM* self, Frame* frame, Bytecode byte) {
|
||||||
|
@ -1,4 +0,0 @@
|
|||||||
#include "pocketpy/objects/base.h"
|
|
||||||
|
|
||||||
py_TValue PY_NIL = {.type=0, .is_ptr=false, .extra=0, ._i64=0};
|
|
||||||
|
|
@ -158,10 +158,10 @@ void CodeObject__dtor(CodeObject* self) {
|
|||||||
c11_vector__dtor(&self->func_decls);
|
c11_vector__dtor(&self->func_decls);
|
||||||
}
|
}
|
||||||
|
|
||||||
void Function__ctor(Function* self, FuncDecl_ decl, PyObject* module) {
|
void Function__ctor(Function* self, FuncDecl_ decl, py_TValue* module) {
|
||||||
PK_INCREF(decl);
|
PK_INCREF(decl);
|
||||||
self->decl = decl;
|
self->decl = decl;
|
||||||
self->module = module;
|
self->module = module ? *module : *py_NIL;
|
||||||
self->clazz = NULL;
|
self->clazz = NULL;
|
||||||
self->closure = NULL;
|
self->closure = NULL;
|
||||||
self->cfunc = NULL;
|
self->cfunc = NULL;
|
||||||
|
@ -25,6 +25,15 @@ void py_setdict(py_Ref self, py_Name name, const py_Ref val) {
|
|||||||
pk_NameDict__set(PyObject__dict(self->_obj), name, *val);
|
pk_NameDict__set(PyObject__dict(self->_obj), name, *val);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool py_deldict(py_Ref self, py_Name name) {
|
||||||
|
assert(self && self->is_ptr);
|
||||||
|
if(self->type == tp_type && py_ismagicname(name)) {
|
||||||
|
py_Type* ud = py_touserdata(self);
|
||||||
|
py_newnil(py_tpmagic(*ud, name));
|
||||||
|
}
|
||||||
|
return pk_NameDict__del(PyObject__dict(self->_obj), name);
|
||||||
|
}
|
||||||
|
|
||||||
py_Ref py_getslot(const py_Ref self, int i) {
|
py_Ref py_getslot(const py_Ref self, int i) {
|
||||||
assert(self && self->is_ptr);
|
assert(self && self->is_ptr);
|
||||||
assert(i >= 0 && i < self->_obj->slots);
|
assert(i >= 0 && i < self->_obj->slots);
|
||||||
|
@ -14,6 +14,7 @@ pk_VM* pk_current_vm;
|
|||||||
py_GlobalRef py_True;
|
py_GlobalRef py_True;
|
||||||
py_GlobalRef py_False;
|
py_GlobalRef py_False;
|
||||||
py_GlobalRef py_None;
|
py_GlobalRef py_None;
|
||||||
|
py_GlobalRef py_NIL;
|
||||||
|
|
||||||
static pk_VM pk_default_vm;
|
static pk_VM pk_default_vm;
|
||||||
|
|
||||||
@ -23,14 +24,15 @@ void py_initialize() {
|
|||||||
pk_current_vm = &pk_default_vm;
|
pk_current_vm = &pk_default_vm;
|
||||||
|
|
||||||
// initialize some convenient references
|
// initialize some convenient references
|
||||||
static py_TValue _True, _False, _None;
|
static py_TValue _True, _False, _None, _NIL;
|
||||||
py_newbool(&_True, true);
|
py_newbool(&_True, true);
|
||||||
py_newbool(&_False, false);
|
py_newbool(&_False, false);
|
||||||
py_newnone(&_None);
|
py_newnone(&_None);
|
||||||
|
py_newnil(&_NIL);
|
||||||
py_True = &_True;
|
py_True = &_True;
|
||||||
py_False = &_False;
|
py_False = &_False;
|
||||||
py_None = &_None;
|
py_None = &_None;
|
||||||
|
py_NIL = &_NIL;
|
||||||
pk_VM__ctor(&pk_default_vm);
|
pk_VM__ctor(&pk_default_vm);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -183,7 +185,7 @@ static bool
|
|||||||
|
|
||||||
// disassemble(&co);
|
// disassemble(&co);
|
||||||
|
|
||||||
Frame* frame = Frame__new(&co, vm->main._obj, NULL, vm->stack.sp, vm->stack.sp, &co);
|
Frame* frame = Frame__new(&co, &vm->main, NULL, vm->stack.sp, vm->stack.sp, &co);
|
||||||
pk_VM__push_frame(vm, frame);
|
pk_VM__push_frame(vm, frame);
|
||||||
pk_FrameResult res = pk_VM__run_top_frame(vm);
|
pk_FrameResult res = pk_VM__run_top_frame(vm);
|
||||||
CodeObject__dtor(&co);
|
CodeObject__dtor(&co);
|
||||||
@ -289,6 +291,7 @@ py_Ref py_tpmagic(py_Type type, py_Name name) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
py_Ref py_tpobject(py_Type type) {
|
py_Ref py_tpobject(py_Type type) {
|
||||||
|
assert(type);
|
||||||
pk_VM* vm = pk_current_vm;
|
pk_VM* vm = pk_current_vm;
|
||||||
return &c11__at(pk_TypeInfo, &vm->types, type)->self;
|
return &c11__at(pk_TypeInfo, &vm->types, type)->self;
|
||||||
}
|
}
|
||||||
|
@ -1,8 +1,3 @@
|
|||||||
class A: pass
|
|
||||||
class B: pass
|
|
||||||
a = A()
|
|
||||||
assert type(a) is A
|
|
||||||
|
|
||||||
x = 0
|
x = 0
|
||||||
if x==0: x=1
|
if x==0: x=1
|
||||||
assert x==1
|
assert x==1
|
||||||
@ -17,4 +12,9 @@ else: x=3
|
|||||||
assert x==2
|
assert x==2
|
||||||
|
|
||||||
def f1(x): return x+1
|
def f1(x): return x+1
|
||||||
assert f1(1)==2
|
assert f1(1)==2
|
||||||
|
|
||||||
|
# class A: pass
|
||||||
|
# class B: pass
|
||||||
|
# a = A()
|
||||||
|
# assert type(a) is A
|
Loading…
x
Reference in New Issue
Block a user