Disallow subclassing of some core types that are not subclasses of Instance
This commit is contained in:
parent
3f0522dd98
commit
b3c693eae5
@ -187,7 +187,7 @@ typedef struct KrkClass {
|
||||
size_t allocSize; /**< @brief Size to allocate when creating instances of this class */
|
||||
KrkCleanupCallback _ongcscan; /**< @brief C function to call when the garbage collector visits an instance of this class in the scan phase */
|
||||
KrkCleanupCallback _ongcsweep; /**< @brief C function to call when the garbage collector is discarding an instance of this class */
|
||||
KrkTable subclasses;
|
||||
KrkTable subclasses; /**< @brief Set of classes that subclass this class */
|
||||
|
||||
KrkObj * _getter; /**< @brief @c %__getitem__ Called when an instance is subscripted */
|
||||
KrkObj * _setter; /**< @brief @c %__setitem__ Called when a subscripted instance is assigned to */
|
||||
|
@ -79,6 +79,7 @@ static KrkValue _class_subclasses(int argc, const KrkValue argv[], int hasKw) {
|
||||
_noexport
|
||||
void _createAndBind_type(void) {
|
||||
ADD_BASE_CLASS(vm.baseClasses->typeClass, "type", vm.baseClasses->objectClass);
|
||||
vm.baseClasses->typeClass->allocSize = 0;
|
||||
krk_defineNative(&vm.baseClasses->typeClass->methods, "__base__", krk_baseOfClass)->flags = KRK_NATIVE_FLAGS_IS_DYNAMIC_PROPERTY;
|
||||
krk_defineNative(&vm.baseClasses->typeClass->methods, "__file__", krk_fileOfClass)->flags = KRK_NATIVE_FLAGS_IS_DYNAMIC_PROPERTY;
|
||||
krk_defineNative(&vm.baseClasses->typeClass->methods, "__doc__", krk_docOfClass) ->flags = KRK_NATIVE_FLAGS_IS_DYNAMIC_PROPERTY;
|
||||
|
@ -379,6 +379,7 @@ KRK_METHOD(bytearray,__iter__,{
|
||||
_noexport
|
||||
void _createAndBind_bytesClass(void) {
|
||||
KrkClass * bytes = ADD_BASE_CLASS(vm.baseClasses->bytesClass, "bytes", vm.baseClasses->objectClass);
|
||||
bytes->allocSize = 0; /* cannot subclass */
|
||||
KRK_DOC(BIND_METHOD(bytes,__init__),
|
||||
"@brief An array of bytes.\n"
|
||||
"@arguments iter=None\n\n"
|
||||
|
@ -311,6 +311,7 @@ KRK_FUNC(classmethod,{
|
||||
_noexport
|
||||
void _createAndBind_functionClass(void) {
|
||||
KrkClass * codeobject = ADD_BASE_CLASS(vm.baseClasses->codeobjectClass, "codeobject", vm.baseClasses->objectClass);
|
||||
codeobject->allocSize = 0; /* cannot subclass */
|
||||
BIND_METHOD(codeobject,__str__);
|
||||
BIND_METHOD(codeobject,_ip_to_line);
|
||||
BIND_PROP(codeobject,__constants__);
|
||||
@ -320,6 +321,7 @@ void _createAndBind_functionClass(void) {
|
||||
krk_finalizeClass(codeobject);
|
||||
|
||||
KrkClass * function = ADD_BASE_CLASS(vm.baseClasses->functionClass, "function", vm.baseClasses->objectClass);
|
||||
function->allocSize = 0; /* cannot subclass */
|
||||
BIND_METHOD(function,__str__);
|
||||
BIND_METHOD(function,_ip_to_line);
|
||||
BIND_PROP(function,__doc__);
|
||||
@ -334,6 +336,7 @@ void _createAndBind_functionClass(void) {
|
||||
krk_finalizeClass(function);
|
||||
|
||||
KrkClass * method = ADD_BASE_CLASS(vm.baseClasses->methodClass, "method", vm.baseClasses->objectClass);
|
||||
method->allocSize = 0; /* cannot subclass */
|
||||
BIND_METHOD(method,__str__);
|
||||
BIND_METHOD(method,_ip_to_line);
|
||||
BIND_PROP(method,__doc__);
|
||||
|
@ -136,6 +136,7 @@ KRK_METHOD(NotImplementedType,__hash__,{
|
||||
_noexport
|
||||
void _createAndBind_numericClasses(void) {
|
||||
KrkClass * _int = ADD_BASE_CLASS(vm.baseClasses->intClass, "int", vm.baseClasses->objectClass);
|
||||
_int->allocSize = 0; /* cannot subclass */
|
||||
BIND_METHOD(int,__init__);
|
||||
BIND_METHOD(int,__str__);
|
||||
BIND_METHOD(int,__int__);
|
||||
@ -148,6 +149,7 @@ void _createAndBind_numericClasses(void) {
|
||||
KRK_DOC(_int, "Convert a number or string type to an integer representation.");
|
||||
|
||||
KrkClass * _float = ADD_BASE_CLASS(vm.baseClasses->floatClass, "float", vm.baseClasses->objectClass);
|
||||
_float->allocSize = 0; /* cannot subclass */
|
||||
BIND_METHOD(float,__init__);
|
||||
BIND_METHOD(float,__int__);
|
||||
BIND_METHOD(float,__float__);
|
||||
@ -159,6 +161,7 @@ void _createAndBind_numericClasses(void) {
|
||||
KRK_DOC(_float, "Convert a number or string type to a float representation.");
|
||||
|
||||
KrkClass * _bool = ADD_BASE_CLASS(vm.baseClasses->boolClass, "bool", vm.baseClasses->intClass);
|
||||
_bool->allocSize = 0; /* cannot subclass */
|
||||
BIND_METHOD(bool,__init__);
|
||||
BIND_METHOD(bool,__str__);
|
||||
krk_defineNative(&_bool->methods, "__repr__", FUNC_NAME(bool,__str__));
|
||||
@ -166,12 +169,14 @@ void _createAndBind_numericClasses(void) {
|
||||
KRK_DOC(_bool, "Returns False if the argument is 'falsey', otherwise True.");
|
||||
|
||||
KrkClass * _NoneType = ADD_BASE_CLASS(vm.baseClasses->noneTypeClass, "NoneType", vm.baseClasses->objectClass);
|
||||
_NoneType->allocSize = 0; /* cannot subclass */
|
||||
BIND_METHOD(NoneType, __str__);
|
||||
BIND_METHOD(NoneType, __hash__);
|
||||
krk_defineNative(&_NoneType->methods, "__repr__", FUNC_NAME(NoneType,__str__));
|
||||
krk_finalizeClass(_NoneType);
|
||||
|
||||
KrkClass * _NotImplementedType = ADD_BASE_CLASS(vm.baseClasses->notImplClass, "NotImplementedType", vm.baseClasses->objectClass);
|
||||
_NotImplementedType->allocSize = 0; /* cannot subclass */
|
||||
BIND_METHOD(NotImplementedType, __str__);
|
||||
BIND_METHOD(NotImplementedType, __hash__);
|
||||
krk_defineNative(&_NotImplementedType->methods, "__repr__", FUNC_NAME(NotImplementedType,__str__));
|
||||
|
@ -885,6 +885,7 @@ _corrupt:
|
||||
_noexport
|
||||
void _createAndBind_strClass(void) {
|
||||
KrkClass * str = ADD_BASE_CLASS(vm.baseClasses->strClass, "str", vm.baseClasses->objectClass);
|
||||
str->allocSize = 0; /* cannot subclass */
|
||||
BIND_METHOD(str,__init__);
|
||||
BIND_METHOD(str,__iter__);
|
||||
BIND_METHOD(str,__ord__);
|
||||
|
@ -203,6 +203,7 @@ _unhashable:
|
||||
_noexport
|
||||
void _createAndBind_tupleClass(void) {
|
||||
KrkClass * tuple = ADD_BASE_CLASS(vm.baseClasses->tupleClass, "tuple", vm.baseClasses->objectClass);
|
||||
tuple->allocSize = 0; /* cannot subclass */
|
||||
BIND_METHOD(tuple,__repr__);
|
||||
BIND_METHOD(tuple,__getitem__);
|
||||
BIND_METHOD(tuple,__len__);
|
||||
|
@ -327,7 +327,8 @@ KrkClass * krk_newClass(KrkString * name, KrkClass * baseClass) {
|
||||
}
|
||||
|
||||
KrkInstance * krk_newInstance(KrkClass * _class) {
|
||||
KrkInstance * instance = (KrkInstance*)allocateObject(_class->allocSize, KRK_OBJ_INSTANCE);
|
||||
size_t allocSize = _class->allocSize ? _class->allocSize : sizeof(KrkInstance);
|
||||
KrkInstance * instance = (KrkInstance*)allocateObject(allocSize, KRK_OBJ_INSTANCE);
|
||||
instance->_class = _class;
|
||||
krk_initTable(&instance->fields);
|
||||
return instance;
|
||||
|
5
src/vm.c
5
src/vm.c
@ -2601,6 +2601,11 @@ _finishReturn: (void)0;
|
||||
krk_typeName(superclass));
|
||||
goto _finishException;
|
||||
}
|
||||
if (AS_CLASS(superclass)->allocSize == 0) {
|
||||
krk_runtimeError(vm.exceptions->typeError, "'%s' can not be subclassed",
|
||||
AS_CLASS(superclass)->name->chars);
|
||||
goto _finishException;
|
||||
}
|
||||
KrkClass * subclass = AS_CLASS(krk_peek(1));
|
||||
if (subclass->base) {
|
||||
krk_tableDelete(&subclass->base->subclasses, krk_peek(1));
|
||||
|
Loading…
Reference in New Issue
Block a user