Commit 20beb619 authored by Kevin Modzelewski's avatar Kevin Modzelewski

Merge commit '78ab38' into refcounting

parents 2eee8416 78ab3861
......@@ -335,19 +335,23 @@ public:
= var->getType()->getattrType(attr, true)->callType(ArgPassSpec(1), { SLICE }, NULL);
assert(return_type->getConcreteType() == return_type);
llvm::Value* cstart, *cstop;
cstart = slice_val.start ? slice_val.start->makeConverted(emitter, UNKNOWN)->getValue()
: getNullPtr(g.llvm_value_type_ptr);
cstop = slice_val.stop ? slice_val.stop->makeConverted(emitter, UNKNOWN)->getValue()
: getNullPtr(g.llvm_value_type_ptr);
llvm::Value* r
= emitter.createCall3(info.unw_info, g.funcs.apply_slice, var->getValue(), cstart, cstop);
emitter.setType(r, RefType::OWNED);
emitter.checkAndPropagateCapiException(info.unw_info, r, getNullPtr(g.llvm_value_type_ptr));
if (return_type != UNDEF) {
llvm::Value* cstart, *cstop;
cstart = slice_val.start ? slice_val.start->makeConverted(emitter, UNKNOWN)->getValue()
: getNullPtr(g.llvm_value_type_ptr);
cstop = slice_val.stop ? slice_val.stop->makeConverted(emitter, UNKNOWN)->getValue()
: getNullPtr(g.llvm_value_type_ptr);
llvm::Value* r
= emitter.createCall3(info.unw_info, g.funcs.apply_slice, var->getValue(), cstart, cstop);
emitter.setType(r, RefType::OWNED);
emitter.checkAndPropagateCapiException(info.unw_info, r, getNullPtr(g.llvm_value_type_ptr));
return new ConcreteCompilerVariable(static_cast<ConcreteCompilerType*>(return_type), r);
return new ConcreteCompilerVariable(static_cast<ConcreteCompilerType*>(return_type), r);
} else {
// TODO: we could directly emit an exception if we know getitem is undefined but for now let it just
// call the normal getitem which will raise the exception
}
}
}
......
......@@ -133,10 +133,7 @@ public:
}
virtual CompilerVariable* call(IREmitter& emitter, const OpInfo& info, VAR* var, struct ArgPassSpec argspec,
const std::vector<CompilerVariable*>& args,
const std::vector<BoxedString*>* keyword_names) {
printf("call not defined for %s\n", debugName().c_str());
abort();
}
const std::vector<BoxedString*>* keyword_names);
virtual CompilerVariable* len(IREmitter& emitter, const OpInfo& info, VAR* var) {
printf("len not defined for %s\n", debugName().c_str());
abort();
......@@ -164,10 +161,7 @@ public:
abort();
}
CompilerType* callType(struct ArgPassSpec argspec, const std::vector<CompilerType*>& arg_types,
const std::vector<llvm::StringRef>* keyword_names) override {
printf("callType not defined for %s\n", debugName().c_str());
abort();
}
const std::vector<llvm::StringRef>* keyword_names) override;
BoxedClass* guaranteedClass() override {
ASSERT((CompilerType*)getConcreteType() != this, "%s", debugName().c_str());
return getConcreteType()->guaranteedClass();
......@@ -412,6 +406,22 @@ std::vector<CompilerVariable*> _ValuedCompilerType<V>::unpack(IREmitter& emitter
return r;
}
template <typename V>
CompilerType* _ValuedCompilerType<V>::callType(struct ArgPassSpec argspec, const std::vector<CompilerType*>& arg_types,
const std::vector<llvm::StringRef>* keyword_names) {
return UNKNOWN;
}
template <typename V>
CompilerVariable* _ValuedCompilerType<V>::call(IREmitter& emitter, const OpInfo& info, VAR* var,
struct ArgPassSpec argspec, const std::vector<CompilerVariable*>& args,
const std::vector<BoxedString*>* keyword_names) {
assert((CompilerType*)this != UNKNOWN);
ConcreteCompilerVariable* converted = makeConverted(emitter, var, UNKNOWN);
auto r = UNKNOWN->call(emitter, info, converted, argspec, args, keyword_names);
return r;
}
} // namespace pyston
#endif
......@@ -186,7 +186,7 @@ static Box* propertyDeleter(Box* self, Box* obj) {
}
static Box* staticmethodInit(Box* _self, Box* f) {
RELEASE_ASSERT(_self->cls == staticmethod_cls, "");
RELEASE_ASSERT(isSubclass(_self->cls, staticmethod_cls), "");
BoxedStaticmethod* self = static_cast<BoxedStaticmethod*>(_self);
self->sm_callable = f;
......@@ -194,7 +194,7 @@ static Box* staticmethodInit(Box* _self, Box* f) {
}
static Box* staticmethodGet(Box* self, Box* obj, Box* type) {
RELEASE_ASSERT(self->cls == staticmethod_cls, "");
RELEASE_ASSERT(isSubclass(self->cls, staticmethod_cls), "");
BoxedStaticmethod* sm = static_cast<BoxedStaticmethod*>(self);
......@@ -210,7 +210,7 @@ extern "C" PyObject* PyClassMethod_New(PyObject* callable) noexcept {
}
static Box* classmethodInit(Box* _self, Box* f) {
RELEASE_ASSERT(_self->cls == classmethod_cls, "");
RELEASE_ASSERT(isSubclass(_self->cls, classmethod_cls), "");
BoxedClassmethod* self = static_cast<BoxedClassmethod*>(_self);
self->cm_callable = f;
......@@ -218,7 +218,7 @@ static Box* classmethodInit(Box* _self, Box* f) {
}
static Box* classmethodGet(Box* self, Box* obj, Box* type) {
RELEASE_ASSERT(self->cls == classmethod_cls, "");
RELEASE_ASSERT(isSubclass(self->cls, classmethod_cls), "");
BoxedClassmethod* cm = static_cast<BoxedClassmethod*>(self);
......
......@@ -24,3 +24,21 @@ def g(cls, a, b, c, d):
f.__get__(c, C)(17, 18, 19, 20)
g.__get__(c, C)(21, 22, 23, 24)
class classonlymethod(classmethod):
def __get__(self, instance, owner):
if instance is not None:
raise AttributeError("This method is available only on the class, not on instances.")
return super(classonlymethod, self).__get__(instance, owner)
class C(object):
@classonlymethod
def f(cls):
print "f called"
C.f()
try:
C().f()
except AttributeError, e:
print e
......@@ -42,3 +42,48 @@ def f2():
for i in xrange(100):
f2()
# make sure we don't abort when calling a type which is not callable
def f(call):
i = 1
f = 1.0
l = 1l
s = "str"
t = (1,)
if call:
i()
f()
l()
s()
t()
try:
for i in range(10000):
f(i == 9999)
except TypeError, e:
print e
# make sure we don't abort when calling getitem
def f(error):
i = 1
f = 1.0
l = 1l
if error:
i[:]
f[:]
l[:]
i[1]
f[1]
l[1]
i[1:2]
f[1:2]
l[1:2]
try:
for i in range(10000):
f(i == 9999)
except TypeError as e:
print e
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