mirror of
https://github.com/pocketpy/pocketpy
synced 2025-10-20 03:20:18 +00:00
Compare commits
3 Commits
7016a8780c
...
01f04b2e41
Author | SHA1 | Date | |
---|---|---|---|
|
01f04b2e41 | ||
|
85885f414f | ||
|
5799af3fd7 |
@ -14,11 +14,12 @@ typedef struct py_TypeInfo {
|
|||||||
py_GlobalRef module;
|
py_GlobalRef module;
|
||||||
|
|
||||||
bool is_python; // is it a python class? (not derived from c object)
|
bool is_python; // is it a python class? (not derived from c object)
|
||||||
bool is_sealed; // can it be subclassed?
|
bool is_final; // can it be subclassed?
|
||||||
|
|
||||||
bool (*getattribute)(py_Ref self, py_Name name);
|
bool (*getattribute)(py_Ref self, py_Name name) PY_RAISE PY_RETURN;
|
||||||
bool (*setattribute)(py_Ref self, py_Name name, py_Ref val);
|
bool (*setattribute)(py_Ref self, py_Name name, py_Ref val) PY_RAISE PY_RETURN;
|
||||||
bool (*delattribute)(py_Ref self, py_Name name);
|
bool (*delattribute)(py_Ref self, py_Name name) PY_RAISE;
|
||||||
|
bool (*getunboundmethod)(py_Ref self, py_Name name) PY_RETURN;
|
||||||
|
|
||||||
py_TValue annotations;
|
py_TValue annotations;
|
||||||
py_Dtor dtor; // destructor for this type, NULL if no dtor
|
py_Dtor dtor; // destructor for this type, NULL if no dtor
|
||||||
@ -34,7 +35,7 @@ py_Type pk_newtype(const char* name,
|
|||||||
const py_GlobalRef module,
|
const py_GlobalRef module,
|
||||||
void (*dtor)(void*),
|
void (*dtor)(void*),
|
||||||
bool is_python,
|
bool is_python,
|
||||||
bool is_sealed);
|
bool is_final);
|
||||||
|
|
||||||
|
|
||||||
py_Type pk_newtypewithmode(py_Name name,
|
py_Type pk_newtypewithmode(py_Name name,
|
||||||
@ -42,4 +43,4 @@ py_Type pk_newtypewithmode(py_Name name,
|
|||||||
const py_GlobalRef module,
|
const py_GlobalRef module,
|
||||||
void (*dtor)(void*),
|
void (*dtor)(void*),
|
||||||
bool is_python,
|
bool is_python,
|
||||||
bool is_sealed, enum py_CompileMode mode);
|
bool is_final, enum py_CompileMode mode);
|
@ -33,6 +33,7 @@ typedef struct py_TValue {
|
|||||||
py_Type type;
|
py_Type type;
|
||||||
bool is_ptr;
|
bool is_ptr;
|
||||||
int extra;
|
int extra;
|
||||||
|
|
||||||
union {
|
union {
|
||||||
int64_t _i64;
|
int64_t _i64;
|
||||||
char _chars[16];
|
char _chars[16];
|
||||||
@ -369,12 +370,15 @@ PK_API py_GlobalRef py_tpobject(py_Type type);
|
|||||||
PK_API const char* py_tpname(py_Type type);
|
PK_API const char* py_tpname(py_Type type);
|
||||||
/// Call a type to create a new instance.
|
/// Call a type to create a new instance.
|
||||||
PK_API bool py_tpcall(py_Type type, int argc, py_Ref argv) PY_RAISE PY_RETURN;
|
PK_API bool py_tpcall(py_Type type, int argc, py_Ref argv) PY_RAISE PY_RETURN;
|
||||||
|
/// Disable the type for subclassing.
|
||||||
|
PK_API void py_tpsetfinal(py_Type type);
|
||||||
/// Set attribute hooks for the given type.
|
/// Set attribute hooks for the given type.
|
||||||
PK_API void py_tphookattributes(py_Type type,
|
PK_API void py_tphookattributes(py_Type type,
|
||||||
bool (*getattribute)(py_Ref self, py_Name name),
|
bool (*getattribute)(py_Ref self, py_Name name) PY_RAISE PY_RETURN,
|
||||||
bool (*setattribute)(py_Ref self, py_Name name, py_Ref val),
|
bool (*setattribute)(py_Ref self, py_Name name, py_Ref val)
|
||||||
bool (*delattribute)(py_Ref self, py_Name name));
|
PY_RAISE PY_RETURN,
|
||||||
|
bool (*delattribute)(py_Ref self, py_Name name) PY_RAISE,
|
||||||
|
bool (*getunboundmethod)(py_Ref self, py_Name name) PY_RETURN);
|
||||||
|
|
||||||
/// Check if the object is an instance of the given type exactly.
|
/// Check if the object is an instance of the given type exactly.
|
||||||
/// Raise `TypeError` if the check fails.
|
/// Raise `TypeError` if the check fails.
|
||||||
|
@ -1041,7 +1041,7 @@ __NEXT_STEP:
|
|||||||
POP();
|
POP();
|
||||||
|
|
||||||
py_TypeInfo* base_ti = pk_typeinfo(base);
|
py_TypeInfo* base_ti = pk_typeinfo(base);
|
||||||
if(base_ti->is_sealed) {
|
if(base_ti->is_final) {
|
||||||
TypeError("type '%t' is not an acceptable base type", base);
|
TypeError("type '%t' is not an acceptable base type", base);
|
||||||
goto __ERROR;
|
goto __ERROR;
|
||||||
}
|
}
|
||||||
|
@ -61,11 +61,11 @@ static void py_TypeInfo__common_init(py_Name name,
|
|||||||
const py_GlobalRef module,
|
const py_GlobalRef module,
|
||||||
void (*dtor)(void*),
|
void (*dtor)(void*),
|
||||||
bool is_python,
|
bool is_python,
|
||||||
bool is_sealed,
|
bool is_final,
|
||||||
py_TypeInfo* self,
|
py_TypeInfo* self,
|
||||||
py_TValue* typeobject) {
|
py_TValue* typeobject) {
|
||||||
py_TypeInfo* base_ti = base ? pk_typeinfo(base) : NULL;
|
py_TypeInfo* base_ti = base ? pk_typeinfo(base) : NULL;
|
||||||
if(base_ti && base_ti->is_sealed) {
|
if(base_ti && base_ti->is_final) {
|
||||||
c11__abort("type '%s' is not an acceptable base type", py_name2str(base_ti->name));
|
c11__abort("type '%s' is not an acceptable base type", py_name2str(base_ti->name));
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -79,11 +79,12 @@ static void py_TypeInfo__common_init(py_Name name,
|
|||||||
|
|
||||||
if(!dtor && base) dtor = base_ti->dtor;
|
if(!dtor && base) dtor = base_ti->dtor;
|
||||||
self->is_python = is_python;
|
self->is_python = is_python;
|
||||||
self->is_sealed = is_sealed;
|
self->is_final = is_final;
|
||||||
|
|
||||||
self->getattribute = NULL;
|
self->getattribute = NULL;
|
||||||
self->setattribute = NULL;
|
self->setattribute = NULL;
|
||||||
self->delattribute = NULL;
|
self->delattribute = NULL;
|
||||||
|
self->getunboundmethod = NULL;
|
||||||
|
|
||||||
self->annotations = *py_NIL();
|
self->annotations = *py_NIL();
|
||||||
self->dtor = dtor;
|
self->dtor = dtor;
|
||||||
@ -95,7 +96,7 @@ py_Type pk_newtype(const char* name,
|
|||||||
const py_GlobalRef module,
|
const py_GlobalRef module,
|
||||||
void (*dtor)(void*),
|
void (*dtor)(void*),
|
||||||
bool is_python,
|
bool is_python,
|
||||||
bool is_sealed) {
|
bool is_final) {
|
||||||
py_Type index = pk_current_vm->types.length;
|
py_Type index = pk_current_vm->types.length;
|
||||||
py_TypeInfo* self = py_newobject(py_retval(), tp_type, -1, sizeof(py_TypeInfo));
|
py_TypeInfo* self = py_newobject(py_retval(), tp_type, -1, sizeof(py_TypeInfo));
|
||||||
py_TypeInfo__common_init(py_name(name),
|
py_TypeInfo__common_init(py_name(name),
|
||||||
@ -104,7 +105,7 @@ py_Type pk_newtype(const char* name,
|
|||||||
module,
|
module,
|
||||||
dtor,
|
dtor,
|
||||||
is_python,
|
is_python,
|
||||||
is_sealed,
|
is_final,
|
||||||
self,
|
self,
|
||||||
py_retval());
|
py_retval());
|
||||||
TypePointer* pointer = c11_vector__emplace(&pk_current_vm->types);
|
TypePointer* pointer = c11_vector__emplace(&pk_current_vm->types);
|
||||||
@ -118,7 +119,7 @@ py_Type pk_newtypewithmode(py_Name name,
|
|||||||
const py_GlobalRef module,
|
const py_GlobalRef module,
|
||||||
void (*dtor)(void*),
|
void (*dtor)(void*),
|
||||||
bool is_python,
|
bool is_python,
|
||||||
bool is_sealed,
|
bool is_final,
|
||||||
enum py_CompileMode mode) {
|
enum py_CompileMode mode) {
|
||||||
if(mode == RELOAD_MODE && module != NULL) {
|
if(mode == RELOAD_MODE && module != NULL) {
|
||||||
py_ItemRef old_class = py_getdict(module, name);
|
py_ItemRef old_class = py_getdict(module, name);
|
||||||
@ -136,7 +137,7 @@ py_Type pk_newtypewithmode(py_Name name,
|
|||||||
module,
|
module,
|
||||||
dtor,
|
dtor,
|
||||||
is_python,
|
is_python,
|
||||||
is_sealed,
|
is_final,
|
||||||
self,
|
self,
|
||||||
&self->self);
|
&self->self);
|
||||||
TypePointer* pointer = c11__at(TypePointer, &pk_current_vm->types, index);
|
TypePointer* pointer = c11__at(TypePointer, &pk_current_vm->types, index);
|
||||||
@ -146,7 +147,7 @@ py_Type pk_newtypewithmode(py_Name name,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return pk_newtype(py_name2str(name), base, module, dtor, is_python, is_sealed);
|
return pk_newtype(py_name2str(name), base, module, dtor, is_python, is_final);
|
||||||
}
|
}
|
||||||
|
|
||||||
py_Type py_newtype(const char* name, py_Type base, const py_GlobalRef module, void (*dtor)(void*)) {
|
py_Type py_newtype(const char* name, py_Type base, const py_GlobalRef module, void (*dtor)(void*)) {
|
||||||
@ -156,13 +157,21 @@ py_Type py_newtype(const char* name, py_Type base, const py_GlobalRef module, vo
|
|||||||
return type;
|
return type;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void py_tpsetfinal(py_Type type) {
|
||||||
|
assert(type);
|
||||||
|
py_TypeInfo* ti = pk_typeinfo(type);
|
||||||
|
ti->is_final = true;
|
||||||
|
}
|
||||||
|
|
||||||
void py_tphookattributes(py_Type type,
|
void py_tphookattributes(py_Type type,
|
||||||
bool (*getattribute)(py_Ref self, py_Name name),
|
bool (*getattribute)(py_Ref self, py_Name name),
|
||||||
bool (*setattribute)(py_Ref self, py_Name name, py_Ref val),
|
bool (*setattribute)(py_Ref self, py_Name name, py_Ref val),
|
||||||
bool (*delattribute)(py_Ref self, py_Name name)) {
|
bool (*delattribute)(py_Ref self, py_Name name),
|
||||||
|
bool (*getunboundmethod)(py_Ref self, py_Name name)) {
|
||||||
assert(type);
|
assert(type);
|
||||||
py_TypeInfo* ti = pk_typeinfo(type);
|
py_TypeInfo* ti = pk_typeinfo(type);
|
||||||
ti->getattribute = getattribute;
|
ti->getattribute = getattribute;
|
||||||
ti->setattribute = setattribute;
|
ti->setattribute = setattribute;
|
||||||
ti->delattribute = delattribute;
|
ti->delattribute = delattribute;
|
||||||
|
ti->getunboundmethod = getunboundmethod;
|
||||||
}
|
}
|
||||||
|
@ -16,7 +16,7 @@ static bool Enum__wrapper_field(py_Name name, py_Ref value, void* ctx) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
static void Enum__on_end_subclass(py_TypeInfo* derived_ti) {
|
static void Enum__on_end_subclass(py_TypeInfo* derived_ti) {
|
||||||
derived_ti->is_sealed = true;
|
derived_ti->is_final = true;
|
||||||
py_applydict(&derived_ti->self, Enum__wrapper_field, &derived_ti->self);
|
py_applydict(&derived_ti->self, Enum__wrapper_field, &derived_ti->self);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -45,17 +45,11 @@ void py_initialize() {
|
|||||||
pk_initialized = true;
|
pk_initialized = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
void* py_malloc(size_t size) {
|
void* py_malloc(size_t size) { return PK_MALLOC(size); }
|
||||||
return PK_MALLOC(size);
|
|
||||||
}
|
|
||||||
|
|
||||||
void* py_realloc(void* ptr, size_t size) {
|
void* py_realloc(void* ptr, size_t size) { return PK_REALLOC(ptr, size); }
|
||||||
return PK_REALLOC(ptr, size);
|
|
||||||
}
|
|
||||||
|
|
||||||
void py_free(void* ptr) {
|
void py_free(void* ptr) { PK_FREE(ptr); }
|
||||||
PK_FREE(ptr);
|
|
||||||
}
|
|
||||||
|
|
||||||
py_GlobalRef py_True() { return &_True; }
|
py_GlobalRef py_True() { return &_True; }
|
||||||
|
|
||||||
@ -233,7 +227,20 @@ bool pk_loadmethod(py_StackRef self, py_Name name) {
|
|||||||
self_bak = *self;
|
self_bak = *self;
|
||||||
}
|
}
|
||||||
|
|
||||||
py_Ref cls_var = py_tpfindname(type, name);
|
py_TypeInfo* ti = pk_typeinfo(type);
|
||||||
|
|
||||||
|
if(ti->getunboundmethod) {
|
||||||
|
bool ok = ti->getunboundmethod(self, name);
|
||||||
|
if(ok) {
|
||||||
|
self[0] = *py_retval();
|
||||||
|
self[1] = self_bak;
|
||||||
|
return true;
|
||||||
|
} else {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
py_Ref cls_var = pk_tpfindname(ti, name);
|
||||||
if(cls_var != NULL) {
|
if(cls_var != NULL) {
|
||||||
switch(cls_var->type) {
|
switch(cls_var->type) {
|
||||||
case tp_function:
|
case tp_function:
|
||||||
@ -248,7 +255,7 @@ bool pk_loadmethod(py_StackRef self, py_Name name) {
|
|||||||
break;
|
break;
|
||||||
case tp_classmethod:
|
case tp_classmethod:
|
||||||
self[0] = *py_getslot(cls_var, 0);
|
self[0] = *py_getslot(cls_var, 0);
|
||||||
self[1] = pk_typeinfo(type)->self;
|
self[1] = ti->self;
|
||||||
break;
|
break;
|
||||||
default: c11__unreachable();
|
default: c11__unreachable();
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user