Kaynağa Gözat

add `py_tpsetfinal`

blueloveTH 7 ay önce
ebeveyn
işleme
01f04b2e41

+ 3 - 3
include/pocketpy/interpreter/typeinfo.h

@@ -14,7 +14,7 @@ typedef struct py_TypeInfo {
     py_GlobalRef module;
 
     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) PY_RAISE PY_RETURN;
     bool (*setattribute)(py_Ref self, py_Name name, py_Ref val) PY_RAISE PY_RETURN;
@@ -35,7 +35,7 @@ py_Type pk_newtype(const char* name,
                    const py_GlobalRef module,
                    void (*dtor)(void*),
                    bool is_python,
-                   bool is_sealed);
+                   bool is_final);
 
 
 py_Type pk_newtypewithmode(py_Name name,
@@ -43,4 +43,4 @@ py_Type pk_newtypewithmode(py_Name name,
                    const py_GlobalRef module,
                    void (*dtor)(void*),
                    bool is_python,
-                   bool is_sealed, enum py_CompileMode mode);
+                   bool is_final, enum py_CompileMode mode);

+ 2 - 1
include/pocketpy/pocketpy.h

@@ -370,7 +370,8 @@ 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,

+ 1 - 1
src/interpreter/ceval.c

@@ -1041,7 +1041,7 @@ __NEXT_STEP:
             POP();
 
             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);
                 goto __ERROR;
             }

+ 14 - 8
src/interpreter/typeinfo.c

@@ -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_sealed,
+                                     bool is_final,
                                      py_TypeInfo* self,
                                      py_TValue* typeobject) {
     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));
     }
 
@@ -79,7 +79,7 @@ static void py_TypeInfo__common_init(py_Name name,
 
     if(!dtor && base) dtor = base_ti->dtor;
     self->is_python = is_python;
-    self->is_sealed = is_sealed;
+    self->is_final = is_final;
 
     self->getattribute = NULL;
     self->setattribute = NULL;
@@ -96,7 +96,7 @@ py_Type pk_newtype(const char* name,
                    const py_GlobalRef module,
                    void (*dtor)(void*),
                    bool is_python,
-                   bool is_sealed) {
+                   bool is_final) {
     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 +105,7 @@ py_Type pk_newtype(const char* name,
                              module,
                              dtor,
                              is_python,
-                             is_sealed,
+                             is_final,
                              self,
                              py_retval());
     TypePointer* pointer = c11_vector__emplace(&pk_current_vm->types);
@@ -119,7 +119,7 @@ py_Type pk_newtypewithmode(py_Name name,
                            const py_GlobalRef module,
                            void (*dtor)(void*),
                            bool is_python,
-                           bool is_sealed,
+                           bool is_final,
                            enum py_CompileMode mode) {
     if(mode == RELOAD_MODE && module != NULL) {
         py_ItemRef old_class = py_getdict(module, name);
@@ -137,7 +137,7 @@ py_Type pk_newtypewithmode(py_Name name,
                                      module,
                                      dtor,
                                      is_python,
-                                     is_sealed,
+                                     is_final,
                                      self,
                                      &self->self);
             TypePointer* pointer = c11__at(TypePointer, &pk_current_vm->types, index);
@@ -147,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*)) {
@@ -157,6 +157,12 @@ 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),

+ 1 - 1
src/modules/enum.c

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