Commit 6d010d06 authored by Travis Hance's avatar Travis Hance Committed by Travis Hance

special case and rewriting for staticmethod, classmethod, instancemethod

parent 6d873adb
......@@ -128,6 +128,7 @@ void setupDescr() {
{ None, None, None, None }));
staticmethod_cls->giveAttr("__get__",
new BoxedFunction(boxRTFunction((void*)staticmethodGet, UNKNOWN, 3, 0, false, false)));
staticmethod_cls->freeze();
classmethod_cls->giveAttr("__name__", boxStrConstant("classmethod"));
......@@ -136,6 +137,7 @@ void setupDescr() {
{ None, None, None, None }));
classmethod_cls->giveAttr("__get__",
new BoxedFunction(boxRTFunction((void*)classmethodGet, UNKNOWN, 3, 0, false, false)));
classmethod_cls->freeze();
}
void teardownDescr() {
......
This diff is collapsed.
......@@ -105,7 +105,7 @@ struct CompareRewriteArgs;
Box* compareInternal(Box* lhs, Box* rhs, int op_type, CompareRewriteArgs* rewrite_args);
Box* getattrInternal(Box* obj, const std::string& attr, GetattrRewriteArgs* rewrite_args);
Box* getattrInternalGeneral(Box* obj, const std::string& attr, GetattrRewriteArgs* rewrite_args, bool cls_only,
bool for_call, bool* should_bind_out);
bool for_call, Box** bind_obj_out, RewriterVar** r_bind_obj_out);
Box* typeLookup(BoxedClass* cls, const std::string& attr, GetattrRewriteArgs* rewrite_args);
......
......@@ -213,6 +213,33 @@ extern "C" void instancemethodGCHandler(GCVisitor* v, Box* b) {
v->visit(im->func);
}
extern "C" void propertyGCHandler(GCVisitor* v, Box* b) {
BoxedProperty* prop = (BoxedProperty*)b;
if (prop->prop_get)
v->visit(prop->prop_get);
if (prop->prop_set)
v->visit(prop->prop_set);
if (prop->prop_del)
v->visit(prop->prop_del);
if (prop->prop_doc)
v->visit(prop->prop_doc);
}
extern "C" void staticmethodGCHandler(GCVisitor* v, Box* b) {
BoxedStaticmethod* sm = (BoxedStaticmethod*)b;
if (sm->sm_callable)
v->visit(sm->sm_callable);
}
extern "C" void classmethodGCHandler(GCVisitor* v, Box* b) {
BoxedClassmethod* cm = (BoxedClassmethod*)b;
if (cm->cm_callable)
v->visit(cm->cm_callable);
}
// This probably belongs in list.cpp?
extern "C" void listGCHandler(GCVisitor* v, Box* b) {
boxGCHandler(v, b);
......@@ -438,6 +465,18 @@ extern "C" Box* sliceNew(Box* cls, Box* start, Box* stop, Box** args) {
return createSlice(start, stop, step);
}
Box* instancemethodGet(BoxedInstanceMethod* self, Box* obj, Box* type) {
RELEASE_ASSERT(self->cls == instancemethod_cls, "");
if (self->obj != NULL) {
return self;
}
// TODO subclass test
return new BoxedInstanceMethod(obj, self->func);
}
Box* instancemethodRepr(BoxedInstanceMethod* self) {
if (self->obj)
return boxStrConstant("<bound instancemethod object>");
......@@ -701,9 +740,10 @@ void setupRuntime() {
member_cls = new BoxedClass(type_cls, object_cls, NULL, 0, sizeof(BoxedMemberDescriptor), false);
closure_cls = new BoxedClass(type_cls, object_cls, &closureGCHandler, offsetof(BoxedClosure, attrs),
sizeof(BoxedClosure), false);
property_cls = new BoxedClass(type_cls, object_cls, NULL, 0, sizeof(BoxedProperty), false);
staticmethod_cls = new BoxedClass(type_cls, object_cls, NULL, 0, sizeof(BoxedStaticmethod), false);
classmethod_cls = new BoxedClass(type_cls, object_cls, NULL, 0, sizeof(BoxedClassmethod), false);
property_cls = new BoxedClass(type_cls, object_cls, &propertyGCHandler, 0, sizeof(BoxedProperty), false);
staticmethod_cls
= new BoxedClass(type_cls, object_cls, &staticmethodGCHandler, 0, sizeof(BoxedStaticmethod), false);
classmethod_cls = new BoxedClass(type_cls, object_cls, &classmethodGCHandler, 0, sizeof(BoxedClassmethod), false);
attrwrapper_cls = new BoxedClass(type_cls, object_cls, &AttrWrapper::gcHandler, 0, sizeof(AttrWrapper), false);
STR = typeFromClass(str_cls);
......@@ -786,6 +826,8 @@ void setupRuntime() {
instancemethod_cls->giveAttr("__name__", boxStrConstant("instancemethod"));
instancemethod_cls->giveAttr("__repr__", new BoxedFunction(boxRTFunction((void*)instancemethodRepr, STR, 1)));
instancemethod_cls->giveAttr("__eq__", new BoxedFunction(boxRTFunction((void*)instancemethodEq, UNKNOWN, 2)));
instancemethod_cls->giveAttr(
"__get__", new BoxedFunction(boxRTFunction((void*)instancemethodGet, UNKNOWN, 3, 0, false, false)));
instancemethod_cls->freeze();
slice_cls->giveAttr("__name__", boxStrConstant("slice"));
......
# run_args: -n
# statcheck: noninit_count('slowpath_classmethod_get') <= 10
# statcheck: noninit_count('slowpath_staticmethod_get') <= 10
# statcheck: noninit_count('slowpath_instancemethod_get') <= 10
def _f_plain(self, a, b, c, d):
print 'in f', type(self), a, b, c, d
@staticmethod
def _g(a, b, c, d):
print 'in g', a, b, c, d
@classmethod
def _h(cls, a, b, c, d):
print 'in h', cls, a, b, c, d
class C(object):
f_plain = _f_plain
g = _g
h = _h
_f = C.f_plain
C.f = _f
def run():
c = C()
c.f(1, 2, 3, 4)
c.g(1, 2, 3, 4)
c.h(1, 2, 3, 4)
f1 = c.f
f1(1,2,3,4)
g1 = c.g
g1(1,2,3,4)
h1 = c.h
h1(1,2,3,4)
_f.__get__(c, C)(1,2,3,4)
_g.__get__(c, C)(1,2,3,4)
_h.__get__(c, C)(1,2,3,4)
for i in xrange(1000):
run()
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