fix direct call of __new__

This commit is contained in:
blueloveTH 2024-08-18 21:10:54 +08:00
parent f9d6321a09
commit 46e92166d5
4 changed files with 24 additions and 2 deletions

View File

@ -10,6 +10,10 @@
// 1. __eq__ and __ne__ fallbacks
// 2. un-cleared exception detection
// 3. super()
// 4. stack balance guanrantee
// 5. stack effect of each opcode
// 6. py_TypeInfo
// 7. Direct assignment of py_NIL, py_True, py_False, py_None. They are slow.
typedef struct py_TypeInfo {
py_Name name;

View File

@ -78,7 +78,6 @@ void py_sys_setargv(int argc, char** argv) {
py_Callbacks* py_getcallbacks() { return &pk_current_vm->callbacks; }
const char* pk_opname(Opcode op) {
const static char* OP_NAMES[] = {
#define OPCODE(name) #name,
@ -140,6 +139,19 @@ bool py_pushmethod(py_Name name) {
bool pk_loadmethod(py_StackRef self, py_Name name) {
// NOTE: `out` and `out_self` may overlap with `self`
if(name == __new__ && py_istype(self, tp_type)) {
// __new__ acts like a @staticmethod
// T.__new__(...)
py_Ref cls_var = py_tpfindmagic(py_totype(self), name);
if(cls_var) {
self[0] = *cls_var;
self[1] = *py_NIL;
return true;
}
return false;
}
py_Type type;
// handle super() proxy
if(py_istype(self, tp_super)) {

View File

@ -129,10 +129,12 @@ bool py_getattr(py_Ref self, py_Name name) {
// bound method is non-data descriptor
switch(cls_var->type) {
case tp_function: {
if(name == __new__) goto __STATIC_NEW;
py_newboundmethod(py_retval(), self, cls_var);
return true;
}
case tp_nativefunc: {
if(name == __new__) goto __STATIC_NEW;
py_newboundmethod(py_retval(), self, cls_var);
return true;
}
@ -145,6 +147,7 @@ bool py_getattr(py_Ref self, py_Name name) {
return true;
}
default: {
__STATIC_NEW:
py_assign(py_retval(), cls_var);
return true;
}
@ -152,7 +155,7 @@ bool py_getattr(py_Ref self, py_Name name) {
}
py_Ref fallback = py_tpfindmagic(type, __getattr__);
if(fallback){
if(fallback) {
py_push(fallback);
py_push(self);
py_newstr(py_pushtmp(), py_name2str(name));

View File

@ -134,3 +134,6 @@ a = [1, 10, 3]
a[test()] += 1
assert (a == [1, 11, 3]), a
assert (g == 1), g
assert list.__new__(list) == []
assert a.__new__ == list.__new__