This commit is contained in:
blueloveTH 2024-08-04 23:39:04 +08:00
parent 0b649f3bef
commit 04804ad410
7 changed files with 30 additions and 12 deletions

View File

@ -94,7 +94,7 @@ int pk_arrayequal(py_TValue* lhs, int lhs_length, py_TValue* rhs, int rhs_length
bool pk_arrayiter(py_Ref val); bool pk_arrayiter(py_Ref val);
bool pk_arraycontains(py_Ref self, py_Ref val); bool pk_arraycontains(py_Ref self, py_Ref val);
bool pk_pushmethod(py_StackRef self, py_Name name); bool pk_loadmethod(py_StackRef self, py_Name name);
bool pk_callmagic(py_Name name, int argc, py_Ref argv); bool pk_callmagic(py_Name name, int argc, py_Ref argv);
/// Assumes [a, b] are on the stack, performs a binary op. /// Assumes [a, b] are on the stack, performs a binary op.

View File

@ -234,7 +234,7 @@ void pk_sprintf(c11_sbuf* ss, const char* fmt, ...) {
} }
int py_replinput(char* buf, int max_size) { int py_replinput(char* buf, int max_size) {
buf[0] = '\0'; buf[0] = '\0'; // reset first char because we check '@' at the beginning
int size = 0; int size = 0;
bool multiline = false; bool multiline = false;

View File

@ -484,7 +484,7 @@ FrameResult VM__vectorcall(VM* self, uint16_t argc, uint16_t kwargc, bool opcall
} }
// handle `__call__` overload // handle `__call__` overload
if(pk_pushmethod(p0, __call__)) { if(pk_loadmethod(p0, __call__)) {
// [__call__, self, args..., kwargs...] // [__call__, self, args..., kwargs...]
return VM__vectorcall(self, argc, kwargc, opcall); return VM__vectorcall(self, argc, kwargc, opcall);
} }

View File

@ -231,9 +231,13 @@ bool py_vectorcall(uint16_t argc, uint16_t kwargc) {
py_Ref py_retval() { return &pk_current_vm->last_retval; } py_Ref py_retval() { return &pk_current_vm->last_retval; }
bool py_pushmethod(py_Name name) { return pk_pushmethod(py_peek(-1), name); } bool py_pushmethod(py_Name name) {
bool ok = pk_loadmethod(py_peek(-1), name);
if(ok) pk_current_vm->stack.sp++;
return ok;
}
bool pk_pushmethod(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`
py_Type type; py_Type type;
// handle super() proxy // handle super() proxy
@ -246,7 +250,6 @@ bool pk_pushmethod(py_StackRef self, py_Name name) {
py_Ref cls_var = py_tpfindname(type, name); py_Ref cls_var = py_tpfindname(type, name);
if(cls_var != NULL) { if(cls_var != NULL) {
pk_current_vm->stack.sp++;
switch(cls_var->type) { switch(cls_var->type) {
case tp_function: case tp_function:
case tp_nativefunc: { case tp_nativefunc: {

View File

@ -72,7 +72,7 @@ static bool str__hash__(int argc, py_Ref argv) {
PY_CHECK_ARGC(1); PY_CHECK_ARGC(1);
int size; int size;
const char* data = py_tostrn(&argv[0], &size); const char* data = py_tostrn(&argv[0], &size);
py_i64 res = 0; uint64_t res = 0;
for(int i = 0; i < size; i++) { for(int i = 0; i < size; i++) {
res = res * 31 + data[i]; res = res * 31 + data[i];
} }

View File

@ -131,6 +131,21 @@ static bool tuple__contains__(int argc, py_Ref argv) {
return pk_arraycontains(py_arg(0), py_arg(1)); return pk_arraycontains(py_arg(0), py_arg(1));
} }
static bool tuple__hash__(int argc, py_Ref argv) {
PY_CHECK_ARGC(1);
int length = py_tuple__len(argv);
py_TValue* data = py_tuple__data(argv);
uint64_t x = 1000003;
for(int i = 0; i < length; i++) {
py_i64 y;
if(!py_hash(&data[i], &y)) return false;
// recommended by Github Copilot
x = x ^ (y + 0x9e3779b9 + (x << 6) + (x >> 2));
}
py_newint(py_retval(), x);
return true;
}
py_Type pk_tuple__register() { py_Type pk_tuple__register() {
py_Type type = pk_newtype("tuple", tp_object, NULL, NULL, false, true); py_Type type = pk_newtype("tuple", tp_object, NULL, NULL, false, true);
@ -142,5 +157,6 @@ py_Type pk_tuple__register() {
py_bindmagic(type, __ne__, tuple__ne__); py_bindmagic(type, __ne__, tuple__ne__);
py_bindmagic(type, __iter__, tuple__iter__); py_bindmagic(type, __iter__, tuple__iter__);
py_bindmagic(type, __contains__, tuple__contains__); py_bindmagic(type, __contains__, tuple__contains__);
py_bindmagic(type, __hash__, tuple__hash__);
return type; return type;
} }

View File

@ -8,8 +8,12 @@ class A:
def x(self): def x(self):
return self._x return self._x
def __call__(self, b):
return self.x + b
a = A(1) a = A(1)
assert a.x == 1 assert a.x == 1
assert a(2) == 3
class B: class B:
def __init__(self): def __init__(self):
@ -28,9 +32,6 @@ assert b.x == 1
b.x = 2 b.x = 2
assert b.x == 2 assert b.x == 2
@cache
@cache
@cache @cache
def fib(n): def fib(n):
# print(f'fib({n})') # print(f'fib({n})')
@ -76,5 +77,3 @@ def f():
f() f()
assert res == ['w2', 'w1', 'w'] assert res == ['w2', 'w1', 'w']