This commit is contained in:
blueloveTH 2024-08-04 20:35:33 +08:00
parent 39947e8f15
commit 348bb2b7a5
5 changed files with 78 additions and 13 deletions

View File

@ -122,6 +122,7 @@ py_Type pk_range__register();
py_Type pk_range_iterator__register(); py_Type pk_range_iterator__register();
py_Type pk_BaseException__register(); py_Type pk_BaseException__register();
py_Type pk_Exception__register(); py_Type pk_Exception__register();
py_Type pk_super__register();
py_TValue pk_builtins__register(); py_TValue pk_builtins__register();

View File

@ -107,7 +107,7 @@ void VM__ctor(VM* self) {
validate(tp_nativefunc, pk_nativefunc__register()); validate(tp_nativefunc, pk_nativefunc__register());
validate(tp_boundmethod, pk_newtype("boundmethod", tp_object, NULL, NULL, false, true)); validate(tp_boundmethod, pk_newtype("boundmethod", tp_object, NULL, NULL, false, true));
validate(tp_super, pk_newtype("super", tp_object, NULL, NULL, false, true)); validate(tp_super, pk_super__register());
validate(tp_BaseException, pk_BaseException__register()); validate(tp_BaseException, pk_BaseException__register());
validate(tp_Exception, pk_Exception__register()); validate(tp_Exception, pk_Exception__register());
validate(tp_bytes, pk_bytes__register()); validate(tp_bytes, pk_bytes__register());
@ -147,6 +147,7 @@ void VM__ctor(VM* self) {
tp_bytes, tp_bytes,
tp_dict, tp_dict,
tp_property, tp_property,
tp_super,
tp_BaseException, tp_BaseException,
tp_Exception, tp_Exception,
tp_StopIteration, tp_StopIteration,
@ -504,7 +505,7 @@ FrameResult VM__vectorcall(VM* self, uint16_t argc, uint16_t kwargc, bool opcall
} }
TypeError("'%t' object is not callable", p0->type); TypeError("'%t' object is not callable", p0->type);
c11__unreachedable(); return RES_ERROR;
} }
/****************************************/ /****************************************/

View File

@ -238,8 +238,8 @@ bool pk_pushmethod(py_StackRef self, py_Name name) {
py_Type type; py_Type type;
// handle super() proxy // handle super() proxy
if(py_istype(self, tp_super)) { if(py_istype(self, tp_super)) {
self = py_getslot(self, 0);
type = *(py_Type*)py_touserdata(self); type = *(py_Type*)py_touserdata(self);
*self = *py_getslot(self, 0);
} else { } else {
type = self->type; type = self->type;
} }
@ -268,7 +268,6 @@ bool pk_pushmethod(py_StackRef self, py_Name name) {
} }
return true; return true;
} }
// TODO: __getattr__ fallback
return false; return false;
} }

View File

@ -326,6 +326,35 @@ static bool builtins__eval(int argc, py_Ref argv) {
return py_exec(py_tostr(argv), "<eval>", EVAL_MODE, NULL); return py_exec(py_tostr(argv), "<eval>", EVAL_MODE, NULL);
} }
static bool builtins__isinstance(int argc, py_Ref argv) {
PY_CHECK_ARGC(2);
if(py_istuple(py_arg(1))) {
int length = py_tuple__len(py_arg(1));
for(int i = 0; i < length; i++) {
py_Ref item = py_tuple__getitem(py_arg(1), i);
if(!py_checktype(item, tp_type)) return false;
if(py_isinstance(py_arg(0), py_totype(item))) {
py_newbool(py_retval(), true);
return true;
}
}
py_newbool(py_retval(), false);
return true;
}
if(!py_checktype(py_arg(1), tp_type)) return false;
py_newbool(py_retval(), py_isinstance(py_arg(0), py_totype(py_arg(1))));
return true;
}
static bool builtins__issubclass(int argc, py_Ref argv) {
PY_CHECK_ARGC(2);
if(!py_checktype(py_arg(0), tp_type)) return false;
if(!py_checktype(py_arg(1), tp_type)) return false;
py_newbool(py_retval(), py_issubclass(py_totype(py_arg(0)), py_totype(py_arg(1))));
return true;
}
py_TValue pk_builtins__register() { py_TValue pk_builtins__register() {
py_Ref builtins = py_newmodule("builtins"); py_Ref builtins = py_newmodule("builtins");
py_bindfunc(builtins, "repr", builtins__repr); py_bindfunc(builtins, "repr", builtins__repr);
@ -345,6 +374,9 @@ py_TValue pk_builtins__register() {
py_bind(builtins, "print(*args, sep=' ', end='\\n')", builtins__print); py_bind(builtins, "print(*args, sep=' ', end='\\n')", builtins__print);
py_bind(builtins, "sorted(iterable, key=None, reverse=False)", builtins__sorted); py_bind(builtins, "sorted(iterable, key=None, reverse=False)", builtins__sorted);
py_bindfunc(builtins, "isinstance", builtins__isinstance);
py_bindfunc(builtins, "issubclass", builtins__issubclass);
// None __repr__ // None __repr__
py_bindmagic(tp_NoneType, __repr__, NoneType__repr__); py_bindmagic(tp_NoneType, __repr__, NoneType__repr__);
return *builtins; return *builtins;
@ -367,3 +399,43 @@ py_Type pk_nativefunc__register() {
py_bindmagic(type, __repr__, nativefunc__repr); py_bindmagic(type, __repr__, nativefunc__repr);
return type; return type;
} }
static bool super__new__(int argc, py_Ref argv) {
py_Type* class_arg = py_newobject(py_retval(), tp_super, 1, sizeof(py_Type));
Frame* frame = pk_current_vm->top_frame;
*class_arg = 0;
py_Ref self_arg = NULL;
if(argc == 1) {
// super()
if(frame->function) {
// class_arg = PK_OBJ_GET(Function, frame->_callable)._class;
Function* func = PyObject__userdata(frame->function);
*class_arg = *(py_Type*)PyObject__userdata(func->clazz);
if(frame->locals_co->nlocals > 0) self_arg = &frame->locals[0];
}
if(class_arg == 0 || self_arg == NULL) return RuntimeError("super(): no arguments");
} else if(argc == 3) {
// super(type, obj)
PY_CHECK_ARG_TYPE(1, tp_type);
*class_arg = py_totype(py_arg(1));
self_arg = py_arg(2);
if(!py_isinstance(self_arg, *class_arg)) {
return TypeError("super(type, obj): obj must be an instance of type");
}
} else {
return TypeError("super() takes 0 or 2 arguments");
}
py_TypeInfo* types = pk_current_vm->types.data;
*class_arg = types[*class_arg].base;
if(*class_arg == 0) return RuntimeError("super(): base class is invalid");
py_setslot(py_retval(), 0, self_arg);
return true;
}
py_Type pk_super__register() {
py_Type type = pk_newtype("super", tp_object, NULL, NULL, false, true);
py_bindmagic(type, __new__, super__new__);
return type;
}

View File

@ -110,14 +110,6 @@ class B(A):
assert B.b == 3 assert B.b == 3
assert B.c == 4 assert B.c == 4
import c
class A(c.void_p):
pass
a = A(0)
assert repr(a).startswith('<void* at')
if 1: if 1:
class TrueClass: class TrueClass:
pass pass