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;
|
||||
const Bytecode* ip;
|
||||
const CodeObject* co;
|
||||
PyObject* module;
|
||||
py_TValue module; // weak ref
|
||||
PyObject* function; // a function object or NULL (global scope)
|
||||
py_TValue* p0; // unwinding base
|
||||
py_TValue* locals; // locals base
|
||||
@ -47,7 +47,7 @@ typedef struct Frame {
|
||||
} Frame;
|
||||
|
||||
Frame* Frame__new(const CodeObject* co,
|
||||
PyObject* module,
|
||||
py_TValue* module,
|
||||
const py_TValue* function,
|
||||
py_TValue* p0,
|
||||
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;
|
||||
}
|
||||
|
||||
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) {
|
||||
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;
|
||||
|
||||
py_CFunction on_end_subclass; // backdoor for enum module
|
||||
void (*on_end_subclass)(struct pk_TypeInfo*); // backdoor for enum module
|
||||
|
||||
/* Magic Slots */
|
||||
py_TValue magic[64];
|
||||
@ -49,7 +49,7 @@ typedef struct pk_VM {
|
||||
|
||||
py_TValue reg[8]; // users' registers
|
||||
|
||||
py_TValue __curr_class;
|
||||
py_TValue* __curr_class;
|
||||
FuncDecl_ __dynamic_func_decl;
|
||||
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_TValue) == 16, "sizeof(py_TValue) != 16");
|
||||
|
||||
extern py_TValue PY_NIL;
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
@ -137,13 +137,13 @@ FuncDecl_ FuncDecl__build(c11_sv name,
|
||||
// runtime function
|
||||
typedef struct Function {
|
||||
FuncDecl_ decl;
|
||||
PyObject* module; // weak ref
|
||||
py_TValue module; // weak ref
|
||||
PyObject* clazz; // weak ref
|
||||
pk_NameDict* closure; // strong ref
|
||||
py_CFunction cfunc; // wrapped C 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);
|
||||
|
||||
#ifdef __cplusplus
|
||||
|
@ -132,6 +132,7 @@ bool py_issubclass(py_Type derived, py_Type base);
|
||||
extern py_GlobalRef py_True;
|
||||
extern py_GlobalRef py_False;
|
||||
extern py_GlobalRef py_None;
|
||||
extern py_GlobalRef py_NIL;
|
||||
|
||||
/************* References *************/
|
||||
#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.
|
||||
py_ObjectRef py_getdict(const py_Ref self, py_Name name);
|
||||
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.
|
||||
/// The object must have slots and `i` must be in range.
|
||||
|
@ -96,8 +96,6 @@ OPCODE(UNPACK_EX)
|
||||
OPCODE(BEGIN_CLASS)
|
||||
OPCODE(END_CLASS)
|
||||
OPCODE(STORE_CLASS_ATTR)
|
||||
OPCODE(BEGIN_CLASS_DECORATION)
|
||||
OPCODE(END_CLASS_DECORATION)
|
||||
OPCODE(ADD_CLASS_ANNOTATION)
|
||||
/**************************/
|
||||
OPCODE(WITH_ENTER)
|
||||
|
@ -1291,6 +1291,7 @@ static void Ctx__exit_block(Ctx* self) {
|
||||
}
|
||||
|
||||
static void Ctx__s_emit_decorators(Ctx* self, int count) {
|
||||
if(count == 0) return;
|
||||
assert(Ctx__s_size(self) >= count);
|
||||
// [obj]
|
||||
for(int i = 0; i < count; i++) {
|
||||
@ -2252,7 +2253,7 @@ static Error* read_literal(Compiler* self, py_Ref out) {
|
||||
}
|
||||
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;
|
||||
}
|
||||
|
||||
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) {
|
||||
Error* err;
|
||||
int count = 0;
|
||||
@ -2356,7 +2388,7 @@ static Error* compile_decorated(Compiler* self) {
|
||||
} while(match(TK_DECORATOR));
|
||||
|
||||
if(match(TK_CLASS)) {
|
||||
// check(compile_class(count));
|
||||
check(compile_class(self, count));
|
||||
} else {
|
||||
consume(TK_DEF);
|
||||
check(compile_function(self, count));
|
||||
@ -2467,8 +2499,7 @@ static Error* compile_try_except(Compiler* self) {
|
||||
static Error* compile_stmt(Compiler* self) {
|
||||
Error* err;
|
||||
if(match(TK_CLASS)) {
|
||||
// check(compile_class());
|
||||
assert(false);
|
||||
check(compile_class(self, 0));
|
||||
return NULL;
|
||||
}
|
||||
advance();
|
||||
|
@ -143,7 +143,7 @@ pk_FrameResult pk_VM__run_top_frame(pk_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->locals_co);
|
||||
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);
|
||||
DISPATCH();
|
||||
}
|
||||
tmp = Frame__f_globals_try_get(frame, name);
|
||||
tmp = py_getdict(&frame->module, name);
|
||||
if(tmp != NULL) {
|
||||
PUSH(tmp);
|
||||
DISPATCH();
|
||||
@ -202,7 +202,7 @@ pk_FrameResult pk_VM__run_top_frame(pk_VM* self) {
|
||||
PUSH(tmp);
|
||||
DISPATCH();
|
||||
}
|
||||
tmp = Frame__f_globals_try_get(frame, name);
|
||||
tmp = py_getdict(&frame->module, name);
|
||||
if(tmp != NULL) {
|
||||
PUSH(tmp);
|
||||
DISPATCH();
|
||||
@ -217,7 +217,7 @@ pk_FrameResult pk_VM__run_top_frame(pk_VM* self) {
|
||||
}
|
||||
case OP_LOAD_GLOBAL: {
|
||||
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) {
|
||||
PUSH(tmp);
|
||||
DISPATCH();
|
||||
@ -238,14 +238,13 @@ pk_FrameResult pk_VM__run_top_frame(pk_VM* self) {
|
||||
DISPATCH();
|
||||
}
|
||||
case OP_LOAD_CLASS_GLOBAL: {
|
||||
assert(self->__curr_class.type);
|
||||
py_Name name = byte.arg;
|
||||
if(py_getattr(&self->__curr_class, name, SP())) {
|
||||
if(py_getattr(self->__curr_class, name, SP())) {
|
||||
SP()++;
|
||||
DISPATCH();
|
||||
}
|
||||
// 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) {
|
||||
PUSH(tmp);
|
||||
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_NAME: {
|
||||
py_Name _name = byte.arg;
|
||||
py_TValue _0 = POPX();
|
||||
py_Name name = byte.arg;
|
||||
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) {
|
||||
*slot = _0; // store in locals if possible
|
||||
*slot = *TOP(); // store in locals if possible
|
||||
} else {
|
||||
// Function& func = frame->_callable->as<Function>();
|
||||
// if(func.decl == __dynamic_func_decl) {
|
||||
@ -311,14 +309,16 @@ pk_FrameResult pk_VM__run_top_frame(pk_VM* self) {
|
||||
// }
|
||||
}
|
||||
} else {
|
||||
pk_NameDict__set(Frame__f_globals(frame), _name, _0);
|
||||
py_setdict(&frame->module, name, TOP());
|
||||
}
|
||||
POP();
|
||||
DISPATCH();
|
||||
}
|
||||
case OP_STORE_GLOBAL:
|
||||
pk_NameDict__set(Frame__f_globals(frame), byte.arg, POPX());
|
||||
case OP_STORE_GLOBAL: {
|
||||
py_setdict(&frame->module, byte.arg, TOP());
|
||||
POP();
|
||||
DISPATCH();
|
||||
|
||||
}
|
||||
case OP_STORE_ATTR: {
|
||||
int err = py_setattr(TOP(), byte.arg, SECOND());
|
||||
if(err) goto __ERROR;
|
||||
@ -370,8 +370,7 @@ pk_FrameResult pk_VM__run_top_frame(pk_VM* self) {
|
||||
// }
|
||||
}
|
||||
} else {
|
||||
// if(!frame->f_globals().del(_name)) vm->NameError(_name);
|
||||
bool ok = pk_NameDict__del(Frame__f_globals(frame), name);
|
||||
bool ok = py_deldict(&frame->module, name);
|
||||
if(!ok) {
|
||||
NameError(name);
|
||||
goto __ERROR;
|
||||
@ -381,7 +380,7 @@ pk_FrameResult pk_VM__run_top_frame(pk_VM* self) {
|
||||
}
|
||||
case OP_DELETE_GLOBAL: {
|
||||
py_Name name = byte.arg;
|
||||
bool ok = pk_NameDict__del(Frame__f_globals(frame), name);
|
||||
bool ok = py_deldict(&frame->module, name);
|
||||
if(!ok) {
|
||||
NameError(name);
|
||||
goto __ERROR;
|
||||
@ -794,7 +793,58 @@ pk_FrameResult pk_VM__run_top_frame(pk_VM* self) {
|
||||
}
|
||||
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: {
|
||||
if(byte.arg) {
|
||||
|
@ -34,7 +34,7 @@ UnwindTarget* UnwindTarget__new(UnwindTarget* next, int iblock, int offset) {
|
||||
void UnwindTarget__delete(UnwindTarget* self) { free(self); }
|
||||
|
||||
Frame* Frame__new(const CodeObject* co,
|
||||
PyObject* module,
|
||||
py_TValue* module,
|
||||
const py_TValue* function,
|
||||
py_TValue* p0,
|
||||
py_TValue* locals,
|
||||
@ -44,7 +44,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 ? function->_obj : NULL;
|
||||
self->p0 = p0;
|
||||
self->locals = locals;
|
||||
|
@ -47,7 +47,7 @@ static void pk_TypeInfo__ctor(pk_TypeInfo* self,
|
||||
._obj = typeobj,
|
||||
};
|
||||
|
||||
self->module = module ? *module : PY_NIL;
|
||||
self->module = module ? *module : *py_NIL;
|
||||
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);
|
||||
c11_vector__ctor(&self->types, sizeof(pk_TypeInfo));
|
||||
|
||||
self->builtins = PY_NIL;
|
||||
self->main = PY_NIL;
|
||||
self->builtins = *py_NIL;
|
||||
self->main = *py_NIL;
|
||||
|
||||
self->_ceval_on_step = NULL;
|
||||
self->_import_file = pk_default_import_file;
|
||||
self->_stdout = pk_default_stdout;
|
||||
self->_stderr = pk_default_stderr;
|
||||
|
||||
self->last_retval = PY_NIL;
|
||||
self->last_exception = PY_NIL;
|
||||
self->last_retval = *py_NIL;
|
||||
self->last_exception = *py_NIL;
|
||||
self->is_stopiteration = false;
|
||||
|
||||
self->__curr_class = PY_NIL;
|
||||
self->__curr_class = NULL;
|
||||
self->__dynamic_func_decl = NULL;
|
||||
|
||||
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));
|
||||
// submit the call
|
||||
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);
|
||||
} else {
|
||||
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...]
|
||||
// ^p0 ^p1 ^_sp
|
||||
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);
|
||||
// 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);
|
||||
case FuncType_GENERATOR:
|
||||
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++) {
|
||||
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_value(&vm->last_retval);
|
||||
mark_value(&vm->last_exception);
|
||||
for(int i = 0; i < c11__count_array(vm->reg); i++) {
|
||||
mark_value(&vm->reg[i]);
|
||||
}
|
||||
|
||||
mark_value(&vm->__curr_class);
|
||||
}
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
void Function__ctor(Function* self, FuncDecl_ decl, PyObject* module) {
|
||||
void Function__ctor(Function* self, FuncDecl_ decl, py_TValue* module) {
|
||||
PK_INCREF(decl);
|
||||
self->decl = decl;
|
||||
self->module = module;
|
||||
self->module = module ? *module : *py_NIL;
|
||||
self->clazz = NULL;
|
||||
self->closure = 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);
|
||||
}
|
||||
|
||||
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) {
|
||||
assert(self && self->is_ptr);
|
||||
assert(i >= 0 && i < self->_obj->slots);
|
||||
|
@ -14,6 +14,7 @@ pk_VM* pk_current_vm;
|
||||
py_GlobalRef py_True;
|
||||
py_GlobalRef py_False;
|
||||
py_GlobalRef py_None;
|
||||
py_GlobalRef py_NIL;
|
||||
|
||||
static pk_VM pk_default_vm;
|
||||
|
||||
@ -23,14 +24,15 @@ void py_initialize() {
|
||||
pk_current_vm = &pk_default_vm;
|
||||
|
||||
// initialize some convenient references
|
||||
static py_TValue _True, _False, _None;
|
||||
static py_TValue _True, _False, _None, _NIL;
|
||||
py_newbool(&_True, true);
|
||||
py_newbool(&_False, false);
|
||||
py_newnone(&_None);
|
||||
py_newnil(&_NIL);
|
||||
py_True = &_True;
|
||||
py_False = &_False;
|
||||
py_None = &_None;
|
||||
|
||||
py_NIL = &_NIL;
|
||||
pk_VM__ctor(&pk_default_vm);
|
||||
}
|
||||
|
||||
@ -183,7 +185,7 @@ static bool
|
||||
|
||||
// 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_FrameResult res = pk_VM__run_top_frame(vm);
|
||||
CodeObject__dtor(&co);
|
||||
@ -289,6 +291,7 @@ py_Ref py_tpmagic(py_Type type, py_Name name) {
|
||||
}
|
||||
|
||||
py_Ref py_tpobject(py_Type type) {
|
||||
assert(type);
|
||||
pk_VM* vm = pk_current_vm;
|
||||
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
|
||||
if x==0: x=1
|
||||
assert x==1
|
||||
@ -17,4 +12,9 @@ else: x=3
|
||||
assert x==2
|
||||
|
||||
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