mirror of
https://github.com/pocketpy/pocketpy
synced 2025-10-20 11:30:18 +00:00
fix direct call of __new__
This commit is contained in:
parent
f9d6321a09
commit
46e92166d5
@ -10,6 +10,10 @@
|
|||||||
// 1. __eq__ and __ne__ fallbacks
|
// 1. __eq__ and __ne__ fallbacks
|
||||||
// 2. un-cleared exception detection
|
// 2. un-cleared exception detection
|
||||||
// 3. super()
|
// 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 {
|
typedef struct py_TypeInfo {
|
||||||
py_Name name;
|
py_Name name;
|
||||||
|
@ -78,7 +78,6 @@ void py_sys_setargv(int argc, char** argv) {
|
|||||||
|
|
||||||
py_Callbacks* py_getcallbacks() { return &pk_current_vm->callbacks; }
|
py_Callbacks* py_getcallbacks() { return &pk_current_vm->callbacks; }
|
||||||
|
|
||||||
|
|
||||||
const char* pk_opname(Opcode op) {
|
const char* pk_opname(Opcode op) {
|
||||||
const static char* OP_NAMES[] = {
|
const static char* OP_NAMES[] = {
|
||||||
#define OPCODE(name) #name,
|
#define OPCODE(name) #name,
|
||||||
@ -140,6 +139,19 @@ bool py_pushmethod(py_Name name) {
|
|||||||
|
|
||||||
bool pk_loadmethod(py_StackRef self, py_Name name) {
|
bool pk_loadmethod(py_StackRef self, py_Name name) {
|
||||||
// NOTE: `out` and `out_self` may overlap with `self`
|
// 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;
|
py_Type type;
|
||||||
// handle super() proxy
|
// handle super() proxy
|
||||||
if(py_istype(self, tp_super)) {
|
if(py_istype(self, tp_super)) {
|
||||||
|
@ -129,10 +129,12 @@ bool py_getattr(py_Ref self, py_Name name) {
|
|||||||
// bound method is non-data descriptor
|
// bound method is non-data descriptor
|
||||||
switch(cls_var->type) {
|
switch(cls_var->type) {
|
||||||
case tp_function: {
|
case tp_function: {
|
||||||
|
if(name == __new__) goto __STATIC_NEW;
|
||||||
py_newboundmethod(py_retval(), self, cls_var);
|
py_newboundmethod(py_retval(), self, cls_var);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
case tp_nativefunc: {
|
case tp_nativefunc: {
|
||||||
|
if(name == __new__) goto __STATIC_NEW;
|
||||||
py_newboundmethod(py_retval(), self, cls_var);
|
py_newboundmethod(py_retval(), self, cls_var);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
@ -145,6 +147,7 @@ bool py_getattr(py_Ref self, py_Name name) {
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
default: {
|
default: {
|
||||||
|
__STATIC_NEW:
|
||||||
py_assign(py_retval(), cls_var);
|
py_assign(py_retval(), cls_var);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
@ -152,7 +155,7 @@ bool py_getattr(py_Ref self, py_Name name) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
py_Ref fallback = py_tpfindmagic(type, __getattr__);
|
py_Ref fallback = py_tpfindmagic(type, __getattr__);
|
||||||
if(fallback){
|
if(fallback) {
|
||||||
py_push(fallback);
|
py_push(fallback);
|
||||||
py_push(self);
|
py_push(self);
|
||||||
py_newstr(py_pushtmp(), py_name2str(name));
|
py_newstr(py_pushtmp(), py_name2str(name));
|
||||||
|
@ -134,3 +134,6 @@ a = [1, 10, 3]
|
|||||||
a[test()] += 1
|
a[test()] += 1
|
||||||
assert (a == [1, 11, 3]), a
|
assert (a == [1, 11, 3]), a
|
||||||
assert (g == 1), g
|
assert (g == 1), g
|
||||||
|
|
||||||
|
assert list.__new__(list) == []
|
||||||
|
assert a.__new__ == list.__new__
|
||||||
|
Loading…
x
Reference in New Issue
Block a user