Compare commits

..

No commits in common. "01f04b2e410b83181d568f8206bd44925fb40449" and "7016a8780ca8fa0b30f53cb5bf37397c09b0413b" have entirely different histories.

6 changed files with 32 additions and 53 deletions

View File

@ -14,12 +14,11 @@ typedef struct py_TypeInfo {
py_GlobalRef module;
bool is_python; // is it a python class? (not derived from c object)
bool is_final; // can it be subclassed?
bool is_sealed; // can it be subclassed?
bool (*getattribute)(py_Ref self, py_Name name) PY_RAISE PY_RETURN;
bool (*setattribute)(py_Ref self, py_Name name, py_Ref val) PY_RAISE PY_RETURN;
bool (*delattribute)(py_Ref self, py_Name name) PY_RAISE;
bool (*getunboundmethod)(py_Ref self, py_Name name) PY_RETURN;
bool (*getattribute)(py_Ref self, py_Name name);
bool (*setattribute)(py_Ref self, py_Name name, py_Ref val);
bool (*delattribute)(py_Ref self, py_Name name);
py_TValue annotations;
py_Dtor dtor; // destructor for this type, NULL if no dtor
@ -35,7 +34,7 @@ py_Type pk_newtype(const char* name,
const py_GlobalRef module,
void (*dtor)(void*),
bool is_python,
bool is_final);
bool is_sealed);
py_Type pk_newtypewithmode(py_Name name,
@ -43,4 +42,4 @@ py_Type pk_newtypewithmode(py_Name name,
const py_GlobalRef module,
void (*dtor)(void*),
bool is_python,
bool is_final, enum py_CompileMode mode);
bool is_sealed, enum py_CompileMode mode);

View File

@ -33,7 +33,6 @@ typedef struct py_TValue {
py_Type type;
bool is_ptr;
int extra;
union {
int64_t _i64;
char _chars[16];
@ -370,15 +369,12 @@ PK_API py_GlobalRef py_tpobject(py_Type type);
PK_API const char* py_tpname(py_Type type);
/// 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;
/// Disable the type for subclassing.
PK_API void py_tpsetfinal(py_Type type);
/// Set attribute hooks for the given type.
PK_API void py_tphookattributes(py_Type type,
bool (*getattribute)(py_Ref self, py_Name name) PY_RAISE PY_RETURN,
bool (*setattribute)(py_Ref self, py_Name name, py_Ref val)
PY_RAISE PY_RETURN,
bool (*delattribute)(py_Ref self, py_Name name) PY_RAISE,
bool (*getunboundmethod)(py_Ref self, py_Name name) PY_RETURN);
bool (*getattribute)(py_Ref self, py_Name name),
bool (*setattribute)(py_Ref self, py_Name name, py_Ref val),
bool (*delattribute)(py_Ref self, py_Name name));
/// Check if the object is an instance of the given type exactly.
/// Raise `TypeError` if the check fails.

View File

@ -1041,7 +1041,7 @@ __NEXT_STEP:
POP();
py_TypeInfo* base_ti = pk_typeinfo(base);
if(base_ti->is_final) {
if(base_ti->is_sealed) {
TypeError("type '%t' is not an acceptable base type", base);
goto __ERROR;
}

View File

@ -61,11 +61,11 @@ static void py_TypeInfo__common_init(py_Name name,
const py_GlobalRef module,
void (*dtor)(void*),
bool is_python,
bool is_final,
bool is_sealed,
py_TypeInfo* self,
py_TValue* typeobject) {
py_TypeInfo* base_ti = base ? pk_typeinfo(base) : NULL;
if(base_ti && base_ti->is_final) {
if(base_ti && base_ti->is_sealed) {
c11__abort("type '%s' is not an acceptable base type", py_name2str(base_ti->name));
}
@ -79,12 +79,11 @@ static void py_TypeInfo__common_init(py_Name name,
if(!dtor && base) dtor = base_ti->dtor;
self->is_python = is_python;
self->is_final = is_final;
self->is_sealed = is_sealed;
self->getattribute = NULL;
self->setattribute = NULL;
self->delattribute = NULL;
self->getunboundmethod = NULL;
self->annotations = *py_NIL();
self->dtor = dtor;
@ -96,7 +95,7 @@ py_Type pk_newtype(const char* name,
const py_GlobalRef module,
void (*dtor)(void*),
bool is_python,
bool is_final) {
bool is_sealed) {
py_Type index = pk_current_vm->types.length;
py_TypeInfo* self = py_newobject(py_retval(), tp_type, -1, sizeof(py_TypeInfo));
py_TypeInfo__common_init(py_name(name),
@ -105,7 +104,7 @@ py_Type pk_newtype(const char* name,
module,
dtor,
is_python,
is_final,
is_sealed,
self,
py_retval());
TypePointer* pointer = c11_vector__emplace(&pk_current_vm->types);
@ -119,7 +118,7 @@ py_Type pk_newtypewithmode(py_Name name,
const py_GlobalRef module,
void (*dtor)(void*),
bool is_python,
bool is_final,
bool is_sealed,
enum py_CompileMode mode) {
if(mode == RELOAD_MODE && module != NULL) {
py_ItemRef old_class = py_getdict(module, name);
@ -137,7 +136,7 @@ py_Type pk_newtypewithmode(py_Name name,
module,
dtor,
is_python,
is_final,
is_sealed,
self,
&self->self);
TypePointer* pointer = c11__at(TypePointer, &pk_current_vm->types, index);
@ -147,7 +146,7 @@ py_Type pk_newtypewithmode(py_Name name,
}
}
return pk_newtype(py_name2str(name), base, module, dtor, is_python, is_final);
return pk_newtype(py_name2str(name), base, module, dtor, is_python, is_sealed);
}
py_Type py_newtype(const char* name, py_Type base, const py_GlobalRef module, void (*dtor)(void*)) {
@ -157,21 +156,13 @@ py_Type py_newtype(const char* name, py_Type base, const py_GlobalRef module, vo
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,
bool (*getattribute)(py_Ref self, py_Name name),
bool (*setattribute)(py_Ref self, py_Name name, py_Ref val),
bool (*delattribute)(py_Ref self, py_Name name),
bool (*getunboundmethod)(py_Ref self, py_Name name)) {
bool (*delattribute)(py_Ref self, py_Name name)) {
assert(type);
py_TypeInfo* ti = pk_typeinfo(type);
ti->getattribute = getattribute;
ti->setattribute = setattribute;
ti->delattribute = delattribute;
ti->getunboundmethod = getunboundmethod;
}

View File

@ -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) {
derived_ti->is_final = true;
derived_ti->is_sealed = true;
py_applydict(&derived_ti->self, Enum__wrapper_field, &derived_ti->self);
}

View File

@ -45,11 +45,17 @@ void py_initialize() {
pk_initialized = true;
}
void* py_malloc(size_t size) { return PK_MALLOC(size); }
void* py_malloc(size_t size) {
return PK_MALLOC(size);
}
void* py_realloc(void* ptr, size_t size) { return PK_REALLOC(ptr, size); }
void* py_realloc(void* ptr, size_t size) {
return PK_REALLOC(ptr, size);
}
void py_free(void* ptr) { PK_FREE(ptr); }
void py_free(void* ptr) {
PK_FREE(ptr);
}
py_GlobalRef py_True() { return &_True; }
@ -227,20 +233,7 @@ bool pk_loadmethod(py_StackRef self, py_Name name) {
self_bak = *self;
}
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);
py_Ref cls_var = py_tpfindname(type, name);
if(cls_var != NULL) {
switch(cls_var->type) {
case tp_function:
@ -255,7 +248,7 @@ bool pk_loadmethod(py_StackRef self, py_Name name) {
break;
case tp_classmethod:
self[0] = *py_getslot(cls_var, 0);
self[1] = ti->self;
self[1] = pk_typeinfo(type)->self;
break;
default: c11__unreachable();
}