Commit 89d32425 authored by Kevin Modzelewski's avatar Kevin Modzelewski

Merge commit '26587156' into refcounting

Lots of merge issues, so tried to beef up the is_subclassable test as well.
parents e7ad6be1 26587156
......@@ -575,11 +575,11 @@ public:
return irstate->getSourceInfo()->parent_module->getFloatConstant(d);
}
void refConsumed(llvm::Value* v, llvm::Instruction* inst) {
void refConsumed(llvm::Value* v, llvm::Instruction* inst) override {
irstate->getRefcounts()->refConsumed(v, inst);
}
llvm::Value* setType(llvm::Value* v, RefType reftype) {
llvm::Value* setType(llvm::Value* v, RefType reftype) override {
assert(llvm::isa<PointerType>(v->getType()));
irstate->getRefcounts()->setType(v, reftype);
......@@ -591,7 +591,7 @@ public:
return v;
}
ConcreteCompilerVariable* getNone() {
ConcreteCompilerVariable* getNone() override {
llvm::Constant* none = embedRelocatablePtr(None, g.llvm_value_type_ptr, "cNone");
setType(none, RefType::BORROWED);
return new ConcreteCompilerVariable(typeFromClass(none_cls), none);
......@@ -678,7 +678,7 @@ public:
types(types),
state(RUNNING) {}
virtual CFGBlock* getCFGBlock() {
virtual CFGBlock* getCFGBlock() override {
return myblock;
}
......
......@@ -1853,7 +1853,7 @@ void setupBuiltins() {
"Built-in functions, exceptions, and other objects.\n\nNoteworthy: None is "
"the `nil' object; Ellipsis represents `...' in slices.");
ellipsis_cls = BoxedClass::create(type_cls, object_cls, 0, 0, sizeof(Box), false, "ellipsis", NULL, NULL, false);
ellipsis_cls = BoxedClass::create(type_cls, object_cls, 0, 0, sizeof(Box), false, "ellipsis", false, NULL, NULL, false);
ellipsis_cls->giveAttr("__repr__", new BoxedFunction(FunctionMetadata::create((void*)ellipsisRepr, STR, 1)));
Ellipsis = new (ellipsis_cls) Box();
assert(Ellipsis->cls);
......@@ -1868,8 +1868,8 @@ void setupBuiltins() {
"print", new BoxedBuiltinFunctionOrMethod(FunctionMetadata::create((void*)print, NONE, 0, true, true), "print",
print_doc));
notimplemented_cls
= BoxedClass::create(type_cls, object_cls, 0, 0, sizeof(Box), false, "NotImplementedType", NULL, NULL, false);
notimplemented_cls = BoxedClass::create(type_cls, object_cls, 0, 0, sizeof(Box), false, "NotImplementedType", false,
NULL, NULL, false);
notimplemented_cls->giveAttr("__repr__",
new BoxedFunction(FunctionMetadata::create((void*)notimplementedRepr, STR, 1)));
notimplemented_cls->freeze();
......@@ -1981,8 +1981,8 @@ void setupBuiltins() {
"__import__", new BoxedBuiltinFunctionOrMethod(import_func, "__import__",
{ None, None, None, autoDecref(boxInt(-1)) }, NULL, import_doc));
enumerate_cls = BoxedClass::create(type_cls, object_cls, 0, 0, sizeof(BoxedEnumerate),
false, "enumerate", BoxedEnumerate::dealloc, NULL, true, BoxedEnumerate::traverse, NOCLEAR);
enumerate_cls = BoxedClass::create(type_cls, object_cls, 0, 0, sizeof(BoxedEnumerate), false, "enumerate", false,
BoxedEnumerate::dealloc, NULL, true, BoxedEnumerate::traverse, NOCLEAR);
enumerate_cls->giveAttr(
"__new__", new BoxedFunction(FunctionMetadata::create((void*)BoxedEnumerate::new_, UNKNOWN, 3, false, false),
{ autoDecref(boxInt(0)) }));
......
......@@ -722,8 +722,8 @@ void setupSys() {
sys_module->giveAttr("maxint", boxInt(PYSTON_INT_MAX));
sys_module->giveAttr("maxsize", boxInt(PY_SSIZE_T_MAX));
sys_flags_cls
= BoxedClass::create(type_cls, object_cls, 0, 0, sizeof(BoxedSysFlags), false, "flags", NULL, NULL, false);
sys_flags_cls = BoxedClass::create(type_cls, object_cls, 0, 0, sizeof(BoxedSysFlags), false, "flags", false, NULL,
NULL, false);
sys_flags_cls->giveAttr(
"__new__", new BoxedFunction(FunctionMetadata::create((void*)BoxedSysFlags::__new__, UNKNOWN, 1, true, true)));
sys_flags_cls->tp_dealloc = (destructor)BoxedSysFlags::dealloc;
......
......@@ -228,7 +228,7 @@ void setupThread() {
FunctionMetadata::create((void*)threadCount, BOXED_INT, 0), "_count"));
thread_lock_cls = BoxedClass::create(type_cls, object_cls, 0, 0, sizeof(BoxedThreadLock), false, "lock",
BoxedThreadLock::dealloc, NULL, false);
true, BoxedThreadLock::dealloc, NULL, false);
thread_lock_cls->tp_dealloc = BoxedThreadLock::threadLockDestructor;
thread_lock_cls->has_safe_tp_dealloc = true;
thread_lock_cls->instances_are_nonzero = true;
......@@ -250,7 +250,7 @@ void setupThread() {
thread_lock_cls->freeze();
ThreadError = BoxedClass::create(type_cls, Exception, Exception->attrs_offset, Exception->tp_weaklistoffset,
Exception->tp_basicsize, false, "error", NULL, NULL, false);
Exception->tp_basicsize, false, "error", true, NULL, NULL, false);
ThreadError->giveAttr("__module__", boxString("thread"));
ThreadError->freeze();
......
......@@ -1764,12 +1764,12 @@ int BoxedClassobj::clear(Box* self) noexcept {
void setupClassobj() {
classobj_cls
= BoxedClass::create(type_cls, object_cls, offsetof(BoxedClassobj, attrs), offsetof(BoxedClassobj, weakreflist),
sizeof(BoxedClassobj), false, "classobj", (destructor)BoxedClassobj::dealloc, NULL, true,
(traverseproc)BoxedClassobj::traverse, (inquiry)BoxedClassobj::clear);
sizeof(BoxedClassobj), false, "classobj", false, (destructor)BoxedClassobj::dealloc, NULL,
true, (traverseproc)BoxedClassobj::traverse, (inquiry)BoxedClassobj::clear);
instance_cls
= BoxedClass::create(type_cls, object_cls, offsetof(BoxedInstance, attrs), offsetof(BoxedInstance, weakreflist),
sizeof(BoxedInstance), false, "instance", (destructor)BoxedInstance::dealloc, NULL, true,
(traverseproc)BoxedInstance::traverse, (inquiry)BoxedInstance::clear);
sizeof(BoxedInstance), false, "instance", false, (destructor)BoxedInstance::dealloc, NULL,
true, (traverseproc)BoxedInstance::traverse, (inquiry)BoxedInstance::clear);
classobj_cls->giveAttr("__new__",
new BoxedFunction(FunctionMetadata::create((void*)classobjNew, UNKNOWN, 4, false, false)));
......
......@@ -111,7 +111,8 @@ extern "C" int PyCode_GetArgCount(PyCodeObject* op) noexcept {
}
void setupCode() {
code_cls = BoxedClass::create(type_cls, object_cls, 0, 0, sizeof(BoxedCode), false, "code", NULL, NULL, false);
code_cls
= BoxedClass::create(type_cls, object_cls, 0, 0, sizeof(BoxedCode), false, "code", true, NULL, NULL, false);
code_cls->giveAttrBorrowed("__new__", None); // Hacky way of preventing users from instantiating this
......
......@@ -854,13 +854,13 @@ void setupDict() {
dict_cls->tp_as_sequence = &dict_as_sequence;
dictiterkey_cls = BoxedClass::create(type_cls, object_cls, 0, 0, sizeof(BoxedDictIterator), false,
"dictionary-keyiterator", (destructor)BoxedDictIterator::dealloc, NULL, true,
"dictionary-keyiterator", true, (destructor)BoxedDictIterator::dealloc, NULL, true,
(traverseproc)BoxedDictIterator::traverse, NOCLEAR);
dictitervalue_cls = BoxedClass::create(type_cls, object_cls, 0, 0, sizeof(BoxedDictIterator), false,
"dictionary-valueiterator", (destructor)BoxedDictIterator::dealloc, NULL,
"dictionary-valueiterator", true, (destructor)BoxedDictIterator::dealloc, NULL,
true, (traverseproc)BoxedDictIterator::traverse, NOCLEAR);
dictiteritem_cls = BoxedClass::create(type_cls, object_cls, 0, 0, sizeof(BoxedDictIterator), false,
"dictionary-itemiterator", (destructor)BoxedDictIterator::dealloc, NULL, true,
"dictionary-itemiterator", true, (destructor)BoxedDictIterator::dealloc, NULL, true,
(traverseproc)BoxedDictIterator::traverse, NOCLEAR);
dictiterkey_cls->instances_are_nonzero = dictitervalue_cls->instances_are_nonzero
......
......@@ -176,7 +176,7 @@ extern "C" PyFrameObject* PyFrame_ForStackLevel(int stack_level) noexcept {
}
void setupFrame() {
frame_cls = BoxedClass::create(type_cls, object_cls, 0, 0, sizeof(BoxedFrame), false, "frame",
frame_cls = BoxedClass::create(type_cls, object_cls, 0, 0, sizeof(BoxedFrame), false, "frame", false,
(destructor)BoxedFrame::dealloc, NULL, true, (traverseproc)BoxedFrame::traverse,
(inquiry)BoxedFrame::clear);
frame_cls->tp_dealloc = BoxedFrame::simpleDestructor;
......
......@@ -489,8 +489,8 @@ static int generator_traverse(BoxedGenerator* self, visitproc visit, void *arg)
void setupGenerator() {
generator_cls = BoxedClass::create(type_cls, object_cls, 0, offsetof(BoxedGenerator, weakreflist),
sizeof(BoxedGenerator), false, "generator", (destructor)generator_dealloc, NULL,
true, (traverseproc)generator_traverse, NOCLEAR);
sizeof(BoxedGenerator), false, "generator", false, (destructor)generator_dealloc,
NULL, true, (traverseproc)generator_traverse, NOCLEAR);
generator_cls->has_safe_tp_dealloc = true;
generator_cls->giveAttr(
"__iter__", new BoxedFunction(FunctionMetadata::create((void*)generatorIter, typeFromClass(generator_cls), 1)));
......
......@@ -955,7 +955,8 @@ void setupImport() {
imp_module->giveAttr("C_BUILTIN", boxInt(SearchResult::C_BUILTIN));
imp_module->giveAttr("PY_FROZEN", boxInt(SearchResult::PY_FROZEN));
null_importer_cls = BoxedClass::create(type_cls, object_cls, 0, 0, sizeof(Box), false, "NullImporter", NULL, NULL, false);
null_importer_cls
= BoxedClass::create(type_cls, object_cls, 0, 0, sizeof(Box), false, "NullImporter", true, NULL, NULL, false);
null_importer_cls->giveAttr(
"__init__",
new BoxedFunction(FunctionMetadata::create((void*)nullImporterInit, NONE, 2, false, false), { None }));
......
......@@ -253,9 +253,10 @@ Box* xrangeReduce(Box* self) {
}
void setupXrange() {
xrange_cls = BoxedClass::create(type_cls, object_cls, 0, 0, sizeof(BoxedXrange), false, "xrange", NULL, NULL, false);
xrange_cls = BoxedClass::create(type_cls, object_cls, 0, 0, sizeof(BoxedXrange), false, "xrange", false, NULL, NULL,
false);
xrange_iterator_cls
= BoxedClass::create(type_cls, object_cls, 0, 0, sizeof(BoxedXrangeIterator), false, "rangeiterator",
= BoxedClass::create(type_cls, object_cls, 0, 0, sizeof(BoxedXrangeIterator), false, "rangeiterator", false,
BoxedXrangeIterator::dealloc, NULL, true, BoxedXrangeIterator::traverse, NOCLEAR);
static PySequenceMethods xrange_as_sequence;
......
......@@ -189,7 +189,7 @@ llvm_compat_bool calliterHasnextUnboxed(Box* b) {
void setupIter() {
seqiter_cls = BoxedClass::create(type_cls, object_cls, 0, 0, sizeof(BoxedSeqIter), false, "iterator",
seqiter_cls = BoxedClass::create(type_cls, object_cls, 0, 0, sizeof(BoxedSeqIter), false, "iterator", false,
(destructor)BoxedSeqIter::dealloc, NULL, true,
(traverseproc)BoxedSeqIter::traverse, NOCLEAR);
......@@ -203,7 +203,7 @@ void setupIter() {
seqiter_cls->tp_iter = PyObject_SelfIter;
seqiter_cls->tp_iternext = seqiter_next;
seqreviter_cls = BoxedClass::create(type_cls, object_cls, 0, 0, sizeof(BoxedSeqIter), false, "reversed",
seqreviter_cls = BoxedClass::create(type_cls, object_cls, 0, 0, sizeof(BoxedSeqIter), false, "reversed", false,
(destructor)BoxedSeqIter::dealloc, NULL, true,
(traverseproc)BoxedSeqIter::traverse, NOCLEAR);
......@@ -217,7 +217,7 @@ void setupIter() {
seqreviter_cls->tp_iternext = seqiter_next;
iterwrapper_cls = BoxedClass::create(type_cls, object_cls, 0, 0, sizeof(BoxedIterWrapper), false, "iterwrapper",
(destructor)BoxedIterWrapper::dealloc, NULL, true,
false, (destructor)BoxedIterWrapper::dealloc, NULL, true,
(traverseproc)BoxedIterWrapper::traverse, NOCLEAR);
iterwrapper_cls->giveAttr("next", new BoxedFunction(FunctionMetadata::create((void*)iterwrapperNext, UNKNOWN, 1)));
......
......@@ -1375,11 +1375,11 @@ void setupList() {
list_cls->tp_as_mapping = &list_as_mapping;
list_iterator_cls = BoxedClass::create(type_cls, object_cls, 0, 0, sizeof(BoxedListIterator), false, "listiterator",
(destructor)BoxedListIterator::dealloc, NULL, true,
false, (destructor)BoxedListIterator::dealloc, NULL, true,
(traverseproc)BoxedListIterator::traverse, NOCLEAR);
list_reverse_iterator_cls = BoxedClass::create(type_cls, object_cls, 0, 0, sizeof(BoxedListIterator), false,
"listreverseiterator", (destructor)BoxedListIterator::dealloc, NULL,
true, (traverseproc)BoxedListIterator::traverse, NOCLEAR);
"listreverseiterator", false, (destructor)BoxedListIterator::dealloc,
NULL, true, (traverseproc)BoxedListIterator::traverse, NOCLEAR);
list_iterator_cls->instances_are_nonzero = list_reverse_iterator_cls->instances_are_nonzero = true;
list_cls->giveAttr("__len__", new BoxedFunction(FunctionMetadata::create((void*)listLen, BOXED_INT, 1)));
......
......@@ -634,8 +634,8 @@ void BoxedClass::freeze() {
std::vector<BoxedClass*> classes;
BoxedClass::BoxedClass(BoxedClass* base, int attrs_offset, int weaklist_offset, int instance_size, bool is_user_defined,
const char* name, destructor dealloc, freefunc free, bool is_gc, traverseproc traverse,
inquiry clear)
const char* name, bool is_subclassable, destructor dealloc, freefunc free, bool is_gc,
traverseproc traverse, inquiry clear)
: attrs(HiddenClass::makeSingleton()),
attrs_offset(attrs_offset),
is_constant(false),
......@@ -666,7 +666,8 @@ BoxedClass::BoxedClass(BoxedClass* base, int attrs_offset, int weaklist_offset,
tp_flags |= Py_TPFLAGS_DEFAULT_CORE;
tp_flags |= Py_TPFLAGS_CHECKTYPES;
tp_flags |= Py_TPFLAGS_BASETYPE;
if (is_subclassable)
tp_flags |= Py_TPFLAGS_BASETYPE;
if (is_gc)
tp_flags |= Py_TPFLAGS_HAVE_GC;
......@@ -759,11 +760,12 @@ BoxedClass::BoxedClass(BoxedClass* base, int attrs_offset, int weaklist_offset,
}
BoxedClass* BoxedClass::create(BoxedClass* metaclass, BoxedClass* base, int attrs_offset, int weaklist_offset,
int instance_size, bool is_user_defined, const char* name, destructor dealloc,
freefunc free, bool is_gc, traverseproc traverse, inquiry clear) {
int instance_size, bool is_user_defined, const char* name, bool is_subclassable,
destructor dealloc, freefunc free, bool is_gc, traverseproc traverse, inquiry clear) {
assert(!is_user_defined);
BoxedClass* made = new (metaclass, 0) BoxedClass(base, attrs_offset, weaklist_offset, instance_size,
is_user_defined, name, dealloc, free, is_gc, traverse, clear);
BoxedClass* made = new (metaclass, 0)
BoxedClass(base, attrs_offset, weaklist_offset, instance_size, is_user_defined, name, is_subclassable, dealloc,
free, is_gc, traverse, clear);
// While it might be ok if these were set, it'd indicate a difference in
// expectations as to who was going to calculate them:
......@@ -870,8 +872,8 @@ static int subtype_clear(PyObject* self) noexcept {
BoxedHeapClass::BoxedHeapClass(BoxedClass* base, int attrs_offset, int weaklist_offset, int instance_size,
bool is_user_defined, BoxedString* name)
: BoxedClass(base, attrs_offset, weaklist_offset, instance_size, is_user_defined, name->data(), subtype_dealloc,
PyObject_GC_Del, true, subtype_traverse, subtype_clear),
: BoxedClass(base, attrs_offset, weaklist_offset, instance_size, is_user_defined, name->data(), true,
subtype_dealloc, PyObject_GC_Del, true, subtype_traverse, subtype_clear),
ht_name(name),
ht_slots(NULL) {
assert(is_user_defined);
......
......@@ -865,7 +865,7 @@ void setupSet() {
set_cls->has_safe_tp_dealloc = frozenset_cls->has_safe_tp_dealloc = true;
set_iterator_cls = BoxedClass::create(type_cls, object_cls, 0, 0, sizeof(BoxedSetIterator), false, "setiterator",
(destructor)BoxedSetIterator::dealloc, NULL, true,
false, (destructor)BoxedSetIterator::dealloc, NULL, true,
(traverseproc)BoxedSetIterator::traverse, NOCLEAR);
set_iterator_cls->giveAttr("__iter__", new BoxedFunction(FunctionMetadata::create(
(void*)setiteratorIter, typeFromClass(set_iterator_cls), 1)));
......
......@@ -2827,7 +2827,7 @@ void setupStr() {
str_cls->tp_flags |= Py_TPFLAGS_HAVE_NEWBUFFER;
str_iterator_cls = BoxedClass::create(type_cls, object_cls, 0, 0, sizeof(BoxedStringIterator), false, "striterator",
(destructor)BoxedStringIterator::dealloc, NULL, true,
false, (destructor)BoxedStringIterator::dealloc, NULL, true,
(traverseproc)BoxedStringIterator::traverse, NOCLEAR);
str_iterator_cls->giveAttr(
"__hasnext__", new BoxedFunction(FunctionMetadata::create((void*)BoxedStringIterator::hasnext, BOXED_BOOL, 1)));
......
......@@ -192,7 +192,7 @@ Box* superInit(Box* _self, Box* _type, Box* obj) {
void setupSuper() {
super_cls
= BoxedClass::create(type_cls, object_cls, 0, 0, sizeof(BoxedSuper), false, "super",
= BoxedClass::create(type_cls, object_cls, 0, 0, sizeof(BoxedSuper), false, "super", true,
(destructor)BoxedSuper::dealloc, NULL, true, (traverseproc)BoxedSuper::traverse, NOCLEAR);
// super_cls->giveAttr("__getattribute__", new BoxedFunction(FunctionMetadata::create((void*)superGetattribute,
......
......@@ -144,7 +144,7 @@ extern "C" int _Py_DisplaySourceLine(PyObject* f, const char* filename, int line
}
void setupTraceback() {
traceback_cls = BoxedClass::create(type_cls, object_cls, 0, 0, sizeof(BoxedTraceback), false, "traceback",
traceback_cls = BoxedClass::create(type_cls, object_cls, 0, 0, sizeof(BoxedTraceback), false, "traceback", true,
(destructor)BoxedTraceback::dealloc, NULL, true,
(traverseproc)BoxedTraceback::traverse, (inquiry)BoxedTraceback::clear);
......
......@@ -684,7 +684,7 @@ void setupTuple() {
tuple_cls->tp_as_mapping = &tuple_as_mapping;
tuple_iterator_cls = BoxedClass::create(type_cls, object_cls, 0, 0, sizeof(BoxedTupleIterator), false,
"tupleiterator", (destructor)BoxedTupleIterator::dealloc, NULL, true,
"tupleiterator", true, (destructor)BoxedTupleIterator::dealloc, NULL, true,
(traverseproc)BoxedTupleIterator::traverse, NOCLEAR);
tuple_cls->giveAttr("__new__",
......
This diff is collapsed.
......@@ -276,13 +276,13 @@ public:
// These should only be used for builtin types:
static BoxedClass* create(BoxedClass* metatype, BoxedClass* base, int attrs_offset, int weaklist_offset,
int instance_size, bool is_user_defined, const char* name, destructor dealloc = NULL,
freefunc free = NULL, bool is_gc = true, traverseproc traverse = NULL,
inquiry clear = NULL);
int instance_size, bool is_user_defined, const char* name, bool is_subclassable = true,
destructor dealloc = NULL, freefunc free = NULL, bool is_gc = true,
traverseproc traverse = NULL, inquiry clear = NULL);
BoxedClass(BoxedClass* base, int attrs_offset, int weaklist_offset, int instance_size, bool is_user_defined,
const char* name, destructor dealloc, freefunc free, bool is_gc = true, traverseproc traverse = NULL,
inquiry clear = NULL);
const char* name, bool is_subclassable, destructor dealloc, freefunc free, bool is_gc = true,
traverseproc traverse = NULL, inquiry clear = NULL);
DEFAULT_CLASS_VAR(type_cls, sizeof(SlotOffset));
......
# should_error
class foo(slice):
pass
import re
import inspect
def gen():
print ("generator test")
yield 'a'
yield 'b'
def is_subclassable(base_cls):
try:
class C(base_cls):
pass
except TypeError as e:
assert 'is not an acceptable base type' in repr(e)
return False
return True
class b:
def __init__(self):
self.c = 1
def d(self):
print self.c
def test(cls):
print cls.__name__, is_subclassable(cls)
def testall(module):
for n in sorted(dir((module))):
if n in ("reversed", "AttrwrapperType", "BuiltinMethodType", "BufferType", "DictProxyType"):
continue
cls = getattr(module, n)
if not isinstance(cls, type):
continue
test(cls)
import types
testall(types)
testall(__builtins__)
#slice
assert not is_subclassable(slice)
#xrange
assert not is_subclassable(type(xrange(1)))
#range-iterator
assert not is_subclassable(type(iter(range(5))))
#xrange-iterator
assert not is_subclassable(type(iter(xrange(5))))
#callable-iterator
assert not is_subclassable(type(re.finditer(r'\bs\w+', "some text with swords")))
#striterator
assert not is_subclassable(type(iter("abc")))
#memoryview
assert not is_subclassable(type(memoryview("abc")))
#buffer
assert not is_subclassable(type(buffer('abcde', 2,1)))
#Ellipsis
assert not is_subclassable(type(Ellipsis))
#generator
assert not is_subclassable(type(gen()))
#bool
assert not is_subclassable(type(True))
#classobj
assert not is_subclassable(type(b))
#code
assert not is_subclassable(type(compile('sum([1, 2, 3])', '', 'single')))
#instance
ins = b()
assert not is_subclassable(type(ins))
#instance_method
assert not is_subclassable(type(ins.d))
#frame
assert not is_subclassable(type(inspect.currentframe()))
#function
assert not is_subclassable(type(is_subclassable))
test(type(iter([])))
test(type(reversed([])))
test(type(reversed(()))) # not the same as reversed([])
test(type(iter(set())))
test(type(iter("")))
test(type(iter({})))
test(type(iter(())))
test(type({}.iterkeys()))
test(type(enumerate([])))
import sys
test(type(sys.flags))
test(super)
test(type(None))
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment