Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
P
Pyston
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Issues
0
Issues
0
List
Boards
Labels
Milestones
Merge Requests
0
Merge Requests
0
Analytics
Analytics
Repository
Value Stream
Wiki
Wiki
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Commits
Issue Boards
Open sidebar
Boxiang Sun
Pyston
Commits
4210ed9b
Commit
4210ed9b
authored
Apr 13, 2015
by
Travis Hance
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Add im_class field to BoxedInstanceMethod, implement instancemethodRepr
parent
3d9ead49
Changes
10
Hide whitespace changes
Inline
Side-by-side
Showing
10 changed files
with
145 additions
and
41 deletions
+145
-41
src/capi/types.h
src/capi/types.h
+2
-2
src/codegen/compvars.cpp
src/codegen/compvars.cpp
+14
-8
src/core/common.h
src/core/common.h
+8
-0
src/runtime/descr.cpp
src/runtime/descr.cpp
+1
-1
src/runtime/dict.cpp
src/runtime/dict.cpp
+1
-1
src/runtime/objmodel.cpp
src/runtime/objmodel.cpp
+14
-7
src/runtime/types.cpp
src/runtime/types.cpp
+58
-17
src/runtime/types.h
src/runtime/types.h
+5
-5
test/tests/function_instancemethod.py
test/tests/function_instancemethod.py
+10
-0
test/tests/instance_methods.py
test/tests/instance_methods.py
+32
-0
No files found.
src/capi/types.h
View file @
4210ed9b
...
@@ -150,7 +150,7 @@ public:
...
@@ -150,7 +150,7 @@ public:
// CPython handles this differently: they create the equivalent of different BoxedMethodDescriptor
// CPython handles this differently: they create the equivalent of different BoxedMethodDescriptor
// objects but with different class objects, which define different __get__ and __call__ methods.
// objects but with different class objects, which define different __get__ and __call__ methods.
if
(
self
->
method
->
ml_flags
&
METH_CLASS
)
if
(
self
->
method
->
ml_flags
&
METH_CLASS
)
return
boxInstanceMethod
(
owner
,
self
);
return
boxInstanceMethod
(
owner
,
self
,
self
->
type
);
if
(
self
->
method
->
ml_flags
&
METH_STATIC
)
if
(
self
->
method
->
ml_flags
&
METH_STATIC
)
Py_FatalError
(
"unimplemented"
);
Py_FatalError
(
"unimplemented"
);
...
@@ -160,7 +160,7 @@ public:
...
@@ -160,7 +160,7 @@ public:
if
(
inst
==
None
)
if
(
inst
==
None
)
return
self
;
return
self
;
else
else
return
boxInstanceMethod
(
inst
,
self
);
return
boxInstanceMethod
(
inst
,
self
,
self
->
type
);
}
}
static
Box
*
__call__
(
BoxedMethodDescriptor
*
self
,
Box
*
obj
,
BoxedTuple
*
varargs
,
Box
**
_args
);
static
Box
*
__call__
(
BoxedMethodDescriptor
*
self
,
Box
*
obj
,
BoxedTuple
*
varargs
,
Box
**
_args
);
...
...
src/codegen/compvars.cpp
View file @
4210ed9b
...
@@ -75,9 +75,10 @@ std::string ValuedCompilerType<llvm::Value*>::debugName() {
...
@@ -75,9 +75,10 @@ std::string ValuedCompilerType<llvm::Value*>::debugName() {
}
}
struct
RawInstanceMethod
{
struct
RawInstanceMethod
{
CompilerVariable
*
obj
,
*
func
;
CompilerVariable
*
obj
,
*
func
,
*
im_class
;
RawInstanceMethod
(
CompilerVariable
*
obj
,
CompilerVariable
*
func
)
:
obj
(
obj
),
func
(
func
)
{}
RawInstanceMethod
(
CompilerVariable
*
obj
,
CompilerVariable
*
func
,
CompilerVariable
*
im_class
)
:
obj
(
obj
),
func
(
func
),
im_class
(
im_class
)
{}
};
};
class
InstanceMethodType
:
public
ValuedCompilerType
<
RawInstanceMethod
*>
{
class
InstanceMethodType
:
public
ValuedCompilerType
<
RawInstanceMethod
*>
{
...
@@ -108,9 +109,9 @@ public:
...
@@ -108,9 +109,9 @@ public:
return
rtn
;
return
rtn
;
}
}
static
CompilerVariable
*
makeIM
(
CompilerVariable
*
obj
,
CompilerVariable
*
func
)
{
static
CompilerVariable
*
makeIM
(
CompilerVariable
*
obj
,
CompilerVariable
*
func
,
CompilerVariable
*
im_class
)
{
CompilerVariable
*
rtn
=
new
ValuedCompilerVariable
<
RawInstanceMethod
*>
(
CompilerVariable
*
rtn
=
new
ValuedCompilerVariable
<
RawInstanceMethod
*>
(
InstanceMethodType
::
get
(
obj
->
getType
(),
func
->
getType
()),
new
RawInstanceMethod
(
obj
,
func
),
true
);
InstanceMethodType
::
get
(
obj
->
getType
(),
func
->
getType
()),
new
RawInstanceMethod
(
obj
,
func
,
im_class
),
true
);
obj
->
incvref
();
obj
->
incvref
();
func
->
incvref
();
func
->
incvref
();
return
rtn
;
return
rtn
;
...
@@ -160,9 +161,10 @@ public:
...
@@ -160,9 +161,10 @@ public:
assert
(
im
->
func
);
assert
(
im
->
func
);
ConcreteCompilerVariable
*
obj
=
im
->
obj
->
makeConverted
(
emitter
,
UNKNOWN
);
ConcreteCompilerVariable
*
obj
=
im
->
obj
->
makeConverted
(
emitter
,
UNKNOWN
);
ConcreteCompilerVariable
*
func
=
im
->
func
->
makeConverted
(
emitter
,
UNKNOWN
);
ConcreteCompilerVariable
*
func
=
im
->
func
->
makeConverted
(
emitter
,
UNKNOWN
);
ConcreteCompilerVariable
*
im_class
=
im
->
im_class
->
makeConverted
(
emitter
,
UNKNOWN
);
llvm
::
Value
*
boxed
llvm
::
Value
*
boxed
=
emitter
.
getBuilder
()
->
CreateCall3
(
g
.
funcs
.
boxInstanceMethod
,
obj
->
getValue
(),
=
emitter
.
getBuilder
()
->
CreateCall2
(
g
.
funcs
.
boxInstanceMethod
,
obj
->
getValue
(),
func
->
getValue
());
func
->
getValue
(),
im_class
->
getValue
());
obj
->
decvref
(
emitter
);
obj
->
decvref
(
emitter
);
func
->
decvref
(
emitter
);
func
->
decvref
(
emitter
);
...
@@ -175,7 +177,8 @@ public:
...
@@ -175,7 +177,8 @@ public:
CompilerVariable
*
rtn
=
cache
[
var
];
CompilerVariable
*
rtn
=
cache
[
var
];
if
(
rtn
==
NULL
)
{
if
(
rtn
==
NULL
)
{
RawInstanceMethod
*
im
=
var
->
getValue
();
RawInstanceMethod
*
im
=
var
->
getValue
();
RawInstanceMethod
*
new_im
=
new
RawInstanceMethod
(
im
->
obj
->
dup
(
cache
),
im
->
func
->
dup
(
cache
));
RawInstanceMethod
*
new_im
=
new
RawInstanceMethod
(
im
->
obj
->
dup
(
cache
),
im
->
func
->
dup
(
cache
),
im
->
im_class
->
dup
(
cache
));
rtn
=
new
VAR
(
this
,
new_im
,
var
->
isGrabbed
());
rtn
=
new
VAR
(
this
,
new_im
,
var
->
isGrabbed
());
while
(
rtn
->
getVrefs
()
<
var
->
getVrefs
())
while
(
rtn
->
getVrefs
()
<
var
->
getVrefs
())
rtn
->
incvref
();
rtn
->
incvref
();
...
@@ -1476,7 +1479,10 @@ public:
...
@@ -1476,7 +1479,10 @@ public:
if
(
rtattr
->
cls
==
function_cls
)
{
if
(
rtattr
->
cls
==
function_cls
)
{
CompilerVariable
*
clattr
=
new
ConcreteCompilerVariable
(
CompilerVariable
*
clattr
=
new
ConcreteCompilerVariable
(
typeFromClass
(
function_cls
),
embedRelocatablePtr
(
rtattr
,
g
.
llvm_value_type_ptr
),
false
);
typeFromClass
(
function_cls
),
embedRelocatablePtr
(
rtattr
,
g
.
llvm_value_type_ptr
),
false
);
return
InstanceMethodType
::
makeIM
(
var
,
clattr
);
return
InstanceMethodType
::
makeIM
(
var
,
clattr
,
new
ConcreteCompilerVariable
(
UNKNOWN
,
embedRelocatablePtr
(
cls
,
g
.
llvm_value_type_ptr
),
false
));
}
}
}
}
...
...
src/core/common.h
View file @
4210ed9b
...
@@ -87,4 +87,12 @@ template <typename T1, typename T2> struct hash<pair<T1, T2>> {
...
@@ -87,4 +87,12 @@ template <typename T1, typename T2> struct hash<pair<T1, T2>> {
};
};
}
}
namespace
std
{
template
<
typename
T1
,
typename
T2
,
typename
T3
>
struct
hash
<
tuple
<
T1
,
T2
,
T3
>>
{
size_t
operator
()(
const
tuple
<
T1
,
T2
,
T3
>
p
)
const
{
return
hash
<
T1
>
()(
std
::
get
<
0
>
(
p
))
^
(
hash
<
T2
>
()(
std
::
get
<
1
>
(
p
))
<<
1
)
^
(
hash
<
T3
>
()(
std
::
get
<
2
>
(
p
))
<<
2
);
}
};
}
#endif
#endif
src/runtime/descr.cpp
View file @
4210ed9b
...
@@ -165,7 +165,7 @@ static Box* classmethodGet(Box* self, Box* obj, Box* type) {
...
@@ -165,7 +165,7 @@ static Box* classmethodGet(Box* self, Box* obj, Box* type) {
type
=
obj
->
cls
;
type
=
obj
->
cls
;
}
}
return
new
BoxedInstanceMethod
(
type
,
cm
->
cm_callable
);
return
new
BoxedInstanceMethod
(
type
,
cm
->
cm_callable
,
type
);
}
}
void
setupDescr
()
{
void
setupDescr
()
{
...
...
src/runtime/dict.cpp
View file @
4210ed9b
...
@@ -667,7 +667,7 @@ void setupDict() {
...
@@ -667,7 +667,7 @@ void setupDict() {
dict_cls
->
giveAttr
(
"popitem"
,
new
BoxedFunction
(
boxRTFunction
((
void
*
)
dictPopitem
,
BOXED_TUPLE
,
1
)));
dict_cls
->
giveAttr
(
"popitem"
,
new
BoxedFunction
(
boxRTFunction
((
void
*
)
dictPopitem
,
BOXED_TUPLE
,
1
)));
auto
*
fromkeys_func
=
new
BoxedFunction
(
boxRTFunction
((
void
*
)
dictFromkeys
,
DICT
,
3
,
1
,
false
,
false
),
{
None
});
auto
*
fromkeys_func
=
new
BoxedFunction
(
boxRTFunction
((
void
*
)
dictFromkeys
,
DICT
,
3
,
1
,
false
,
false
),
{
None
});
dict_cls
->
giveAttr
(
"fromkeys"
,
boxInstanceMethod
(
dict_cls
,
fromkeys_func
));
dict_cls
->
giveAttr
(
"fromkeys"
,
boxInstanceMethod
(
dict_cls
,
fromkeys_func
,
dict_cls
));
dict_cls
->
giveAttr
(
"viewkeys"
,
new
BoxedFunction
(
boxRTFunction
((
void
*
)
dictViewKeys
,
UNKNOWN
,
1
)));
dict_cls
->
giveAttr
(
"viewkeys"
,
new
BoxedFunction
(
boxRTFunction
((
void
*
)
dictViewKeys
,
UNKNOWN
,
1
)));
dict_cls
->
giveAttr
(
"viewvalues"
,
new
BoxedFunction
(
boxRTFunction
((
void
*
)
dictViewValues
,
UNKNOWN
,
1
)));
dict_cls
->
giveAttr
(
"viewvalues"
,
new
BoxedFunction
(
boxRTFunction
((
void
*
)
dictViewValues
,
UNKNOWN
,
1
)));
...
...
src/runtime/objmodel.cpp
View file @
4210ed9b
...
@@ -860,8 +860,13 @@ Box* nondataDescriptorInstanceSpecialCases(GetattrRewriteArgs* rewrite_args, Box
...
@@ -860,8 +860,13 @@ Box* nondataDescriptorInstanceSpecialCases(GetattrRewriteArgs* rewrite_args, Box
if
(
descr
->
cls
==
function_cls
||
descr
->
cls
==
instancemethod_cls
||
descr
->
cls
==
classmethod_cls
if
(
descr
->
cls
==
function_cls
||
descr
->
cls
==
instancemethod_cls
||
descr
->
cls
==
classmethod_cls
||
(
descr
->
cls
==
method_cls
||
(
descr
->
cls
==
method_cls
&&
(
static_cast
<
BoxedMethodDescriptor
*>
(
descr
)
->
method
->
ml_flags
&
(
METH_CLASS
|
METH_STATIC
))
==
0
))
{
&&
(
static_cast
<
BoxedMethodDescriptor
*>
(
descr
)
->
method
->
ml_flags
&
(
METH_CLASS
|
METH_STATIC
))
==
0
))
{
Box
*
im_self
=
NULL
,
*
im_func
=
NULL
;
Box
*
im_self
=
NULL
,
*
im_func
=
NULL
,
*
im_class
=
obj
->
cls
;
RewriterVar
*
r_im_self
=
NULL
,
*
r_im_func
=
NULL
;
RewriterVar
*
r_im_self
=
NULL
,
*
r_im_func
=
NULL
,
*
r_im_class
=
NULL
;
if
(
rewrite_args
)
{
r_im_class
=
rewrite_args
->
obj
->
getAttr
(
BOX_CLS_OFFSET
);
}
if
(
descr
->
cls
==
function_cls
)
{
if
(
descr
->
cls
==
function_cls
)
{
im_self
=
obj
;
im_self
=
obj
;
im_func
=
descr
;
im_func
=
descr
;
...
@@ -888,7 +893,7 @@ Box* nondataDescriptorInstanceSpecialCases(GetattrRewriteArgs* rewrite_args, Box
...
@@ -888,7 +893,7 @@ Box* nondataDescriptorInstanceSpecialCases(GetattrRewriteArgs* rewrite_args, Box
im_func
=
cm
->
cm_callable
;
im_func
=
cm
->
cm_callable
;
if
(
rewrite_args
)
{
if
(
rewrite_args
)
{
r_im_self
=
r
ewrite_args
->
obj
->
getAttr
(
BOX_CLS_OFFSET
)
;
r_im_self
=
r
_im_class
;
r_im_func
=
r_descr
->
getAttr
(
offsetof
(
BoxedClassmethod
,
cm_callable
));
r_im_func
=
r_descr
->
getAttr
(
offsetof
(
BoxedClassmethod
,
cm_callable
));
r_im_func
->
addGuardNotEq
(
0
);
r_im_func
->
addGuardNotEq
(
0
);
}
}
...
@@ -919,10 +924,10 @@ Box* nondataDescriptorInstanceSpecialCases(GetattrRewriteArgs* rewrite_args, Box
...
@@ -919,10 +924,10 @@ Box* nondataDescriptorInstanceSpecialCases(GetattrRewriteArgs* rewrite_args, Box
if
(
!
for_call
)
{
if
(
!
for_call
)
{
if
(
rewrite_args
)
{
if
(
rewrite_args
)
{
rewrite_args
->
out_rtn
rewrite_args
->
out_rtn
=
rewrite_args
->
rewriter
->
call
(
true
,
(
void
*
)
boxInstanceMethod
,
r_im_self
,
r_im_func
);
=
rewrite_args
->
rewriter
->
call
(
true
,
(
void
*
)
boxInstanceMethod
,
r_im_self
,
r_im_func
,
r_im_class
);
rewrite_args
->
out_success
=
true
;
rewrite_args
->
out_success
=
true
;
}
}
return
boxInstanceMethod
(
im_self
,
im_func
);
return
boxInstanceMethod
(
im_self
,
im_func
,
im_class
);
}
else
{
}
else
{
*
bind_obj_out
=
im_self
;
*
bind_obj_out
=
im_self
;
if
(
rewrite_args
)
{
if
(
rewrite_args
)
{
...
@@ -966,10 +971,12 @@ Box* descriptorClsSpecialCases(GetattrRewriteArgs* rewrite_args, BoxedClass* cls
...
@@ -966,10 +971,12 @@ Box* descriptorClsSpecialCases(GetattrRewriteArgs* rewrite_args, BoxedClass* cls
if
(
!
for_call
&&
descr
->
cls
==
function_cls
)
{
if
(
!
for_call
&&
descr
->
cls
==
function_cls
)
{
if
(
rewrite_args
)
{
if
(
rewrite_args
)
{
// return an unbound instancemethod
// return an unbound instancemethod
rewrite_args
->
out_rtn
=
rewrite_args
->
rewriter
->
call
(
true
,
(
void
*
)
boxUnboundInstanceMethod
,
r_descr
);
RewriterVar
*
r_cls
=
rewrite_args
->
obj
;
rewrite_args
->
out_rtn
=
rewrite_args
->
rewriter
->
call
(
true
,
(
void
*
)
boxUnboundInstanceMethod
,
r_descr
,
r_cls
);
rewrite_args
->
out_success
=
true
;
rewrite_args
->
out_success
=
true
;
}
}
return
boxUnboundInstanceMethod
(
descr
);
return
boxUnboundInstanceMethod
(
descr
,
cls
);
}
}
if
(
rewrite_args
)
{
if
(
rewrite_args
)
{
...
...
src/runtime/types.cpp
View file @
4210ed9b
...
@@ -715,15 +715,15 @@ extern "C" Box* createUserClass(const std::string* name, Box* _bases, Box* _attr
...
@@ -715,15 +715,15 @@ extern "C" Box* createUserClass(const std::string* name, Box* _bases, Box* _attr
}
}
}
}
extern
"C"
Box
*
boxInstanceMethod
(
Box
*
obj
,
Box
*
func
)
{
extern
"C"
Box
*
boxInstanceMethod
(
Box
*
obj
,
Box
*
func
,
Box
*
type
)
{
static
StatCounter
num_ims
(
"num_instancemethods"
);
static
StatCounter
num_ims
(
"num_instancemethods"
);
num_ims
.
log
();
num_ims
.
log
();
return
new
BoxedInstanceMethod
(
obj
,
func
);
return
new
BoxedInstanceMethod
(
obj
,
func
,
type
);
}
}
extern
"C"
Box
*
boxUnboundInstanceMethod
(
Box
*
func
)
{
extern
"C"
Box
*
boxUnboundInstanceMethod
(
Box
*
func
,
Box
*
type
)
{
return
new
BoxedInstanceMethod
(
NULL
,
func
);
return
new
BoxedInstanceMethod
(
NULL
,
func
,
type
);
}
}
extern
"C"
BoxedString
*
noneRepr
(
Box
*
v
)
{
extern
"C"
BoxedString
*
noneRepr
(
Box
*
v
)
{
...
@@ -773,8 +773,8 @@ static Box* functionGet(BoxedFunction* self, Box* inst, Box* owner) {
...
@@ -773,8 +773,8 @@ static Box* functionGet(BoxedFunction* self, Box* inst, Box* owner) {
RELEASE_ASSERT
(
self
->
cls
==
function_cls
,
""
);
RELEASE_ASSERT
(
self
->
cls
==
function_cls
,
""
);
if
(
inst
==
None
)
if
(
inst
==
None
)
return
boxUnboundInstanceMethod
(
self
)
;
inst
=
NULL
;
return
boxInstanceMethod
(
inst
,
self
);
return
new
BoxedInstanceMethod
(
inst
,
self
,
owner
);
}
}
static
Box
*
functionCall
(
BoxedFunction
*
self
,
Box
*
args
,
Box
*
kwargs
)
{
static
Box
*
functionCall
(
BoxedFunction
*
self
,
Box
*
args
,
Box
*
kwargs
)
{
...
@@ -919,9 +919,11 @@ Box* instancemethodGet(BoxedInstanceMethod* self, Box* obj, Box* type) {
...
@@ -919,9 +919,11 @@ Box* instancemethodGet(BoxedInstanceMethod* self, Box* obj, Box* type) {
return
self
;
return
self
;
}
}
// TODO subclass test
if
(
!
PyObject_IsSubclass
(
type
,
self
->
im_class
))
{
return
self
;
}
return
new
BoxedInstanceMethod
(
obj
,
self
->
func
);
return
new
BoxedInstanceMethod
(
obj
,
self
->
func
,
self
->
im_class
);
}
}
Box
*
instancemethodNew
(
BoxedClass
*
cls
,
Box
*
func
,
Box
*
self
,
Box
**
args
)
{
Box
*
instancemethodNew
(
BoxedClass
*
cls
,
Box
*
func
,
Box
*
self
,
Box
**
args
)
{
...
@@ -938,14 +940,49 @@ Box* instancemethodNew(BoxedClass* cls, Box* func, Box* self, Box** args) {
...
@@ -938,14 +940,49 @@ Box* instancemethodNew(BoxedClass* cls, Box* func, Box* self, Box** args) {
return
NULL
;
return
NULL
;
}
}
return
new
BoxedInstanceMethod
(
self
,
func
);
return
new
BoxedInstanceMethod
(
self
,
func
,
classObj
);
}
}
Box
*
instancemethodRepr
(
BoxedInstanceMethod
*
self
)
{
// Modified from cpython, Objects/object.c, instancemethod_repr
if
(
self
->
obj
)
static
Box
*
instancemethodRepr
(
Box
*
b
)
{
return
boxStrConstant
(
"<bound instancemethod object>"
);
assert
(
isSubclass
(
b
->
cls
,
instancemethod_cls
));
else
BoxedInstanceMethod
*
a
=
static_cast
<
BoxedInstanceMethod
*>
(
b
);
return
boxStrConstant
(
"<unbound instancemethod object>"
);
Box
*
self
=
a
->
obj
;
Box
*
func
=
a
->
func
;
Box
*
klass
=
a
->
im_class
;
Box
*
funcname
=
NULL
,
*
klassname
=
NULL
,
*
result
=
NULL
;
const
char
*
sfuncname
=
"?"
,
*
sklassname
=
"?"
;
funcname
=
getattrInternal
(
func
,
"__name__"
,
NULL
);
if
(
funcname
!=
NULL
)
{
if
(
!
PyString_Check
(
funcname
))
{
funcname
=
NULL
;
}
else
sfuncname
=
PyString_AS_STRING
(
funcname
);
}
if
(
klass
==
NULL
)
{
klassname
=
NULL
;
}
else
{
klassname
=
getattrInternal
(
klass
,
"__name__"
,
NULL
);
if
(
klassname
!=
NULL
)
{
if
(
!
PyString_Check
(
klassname
))
{
klassname
=
NULL
;
}
else
{
sklassname
=
PyString_AS_STRING
(
klassname
);
}
}
}
if
(
self
==
NULL
)
result
=
PyString_FromFormat
(
"<unbound method %s.%s>"
,
sklassname
,
sfuncname
);
else
{
// This was a CPython comment: /* XXX Shouldn't use repr() here! */
Box
*
selfrepr
=
repr
(
self
);
assert
(
PyString_Check
(
selfrepr
));
result
=
PyString_FromFormat
(
"<bound method %s.%s of %s>"
,
sklassname
,
sfuncname
,
PyString_AS_STRING
(
selfrepr
));
}
return
result
;
}
}
Box
*
instancemethodEq
(
BoxedInstanceMethod
*
self
,
Box
*
rhs
)
{
Box
*
instancemethodEq
(
BoxedInstanceMethod
*
self
,
Box
*
rhs
)
{
...
@@ -2203,9 +2240,10 @@ void setupRuntime() {
...
@@ -2203,9 +2240,10 @@ void setupRuntime() {
object_cls
->
giveAttr
(
"__init__"
,
new
BoxedFunction
(
boxRTFunction
((
void
*
)
objectInit
,
UNKNOWN
,
1
,
0
,
true
,
false
)));
object_cls
->
giveAttr
(
"__init__"
,
new
BoxedFunction
(
boxRTFunction
((
void
*
)
objectInit
,
UNKNOWN
,
1
,
0
,
true
,
false
)));
object_cls
->
giveAttr
(
"__repr__"
,
new
BoxedFunction
(
boxRTFunction
((
void
*
)
objectRepr
,
UNKNOWN
,
1
,
0
,
false
,
false
)));
object_cls
->
giveAttr
(
"__repr__"
,
new
BoxedFunction
(
boxRTFunction
((
void
*
)
objectRepr
,
UNKNOWN
,
1
,
0
,
false
,
false
)));
object_cls
->
giveAttr
(
"__str__"
,
new
BoxedFunction
(
boxRTFunction
((
void
*
)
objectStr
,
UNKNOWN
,
1
,
0
,
false
,
false
)));
object_cls
->
giveAttr
(
"__str__"
,
new
BoxedFunction
(
boxRTFunction
((
void
*
)
objectStr
,
UNKNOWN
,
1
,
0
,
false
,
false
)));
object_cls
->
giveAttr
(
object_cls
->
giveAttr
(
"__subclasshook__"
,
"__subclasshook__"
,
boxInstanceMethod
(
object_cls
,
boxInstanceMethod
(
object_cls
,
new
BoxedFunction
(
boxRTFunction
((
void
*
)
objectSubclasshook
,
UNKNOWN
,
2
))));
new
BoxedFunction
(
boxRTFunction
((
void
*
)
objectSubclasshook
,
UNKNOWN
,
2
)),
object_cls
));
// __setattr__ was already set to a WrapperDescriptor; it'd be nice to set this to a faster BoxedFunction
// __setattr__ was already set to a WrapperDescriptor; it'd be nice to set this to a faster BoxedFunction
// object_cls->setattr("__setattr__", new BoxedFunction(boxRTFunction((void*)objectSetattr, UNKNOWN, 3)), NULL);
// object_cls->setattr("__setattr__", new BoxedFunction(boxRTFunction((void*)objectSetattr, UNKNOWN, 3)), NULL);
// but unfortunately that will set tp_setattro to slot_tp_setattro on object_cls and all already-made subclasses!
// but unfortunately that will set tp_setattro to slot_tp_setattro on object_cls and all already-made subclasses!
...
@@ -2317,6 +2355,9 @@ void setupRuntime() {
...
@@ -2317,6 +2355,9 @@ void setupRuntime() {
instancemethod_cls
->
giveAttr
(
"__self__"
,
instancemethod_cls
->
getattr
(
"im_self"
));
instancemethod_cls
->
giveAttr
(
"__self__"
,
instancemethod_cls
->
getattr
(
"im_self"
));
instancemethod_cls
->
freeze
();
instancemethod_cls
->
freeze
();
instancemethod_cls
->
giveAttr
(
"im_class"
,
new
BoxedMemberDescriptor
(
BoxedMemberDescriptor
::
OBJECT
,
offsetof
(
BoxedInstanceMethod
,
im_class
),
true
));
slice_cls
->
giveAttr
(
"__new__"
,
slice_cls
->
giveAttr
(
"__new__"
,
new
BoxedFunction
(
boxRTFunction
((
void
*
)
sliceNew
,
UNKNOWN
,
4
,
2
,
false
,
false
),
{
NULL
,
None
}));
new
BoxedFunction
(
boxRTFunction
((
void
*
)
sliceNew
,
UNKNOWN
,
4
,
2
,
false
,
false
),
{
NULL
,
None
}));
slice_cls
->
giveAttr
(
"__repr__"
,
new
BoxedFunction
(
boxRTFunction
((
void
*
)
sliceRepr
,
STR
,
1
)));
slice_cls
->
giveAttr
(
"__repr__"
,
new
BoxedFunction
(
boxRTFunction
((
void
*
)
sliceRepr
,
STR
,
1
)));
...
...
src/runtime/types.h
View file @
4210ed9b
...
@@ -107,8 +107,8 @@ extern "C" Box* boxBool(bool);
...
@@ -107,8 +107,8 @@ extern "C" Box* boxBool(bool);
extern
"C"
Box
*
boxInt
(
i64
);
extern
"C"
Box
*
boxInt
(
i64
);
extern
"C"
i64
unboxInt
(
Box
*
);
extern
"C"
i64
unboxInt
(
Box
*
);
extern
"C"
Box
*
boxFloat
(
double
d
);
extern
"C"
Box
*
boxFloat
(
double
d
);
extern
"C"
Box
*
boxInstanceMethod
(
Box
*
obj
,
Box
*
func
);
extern
"C"
Box
*
boxInstanceMethod
(
Box
*
obj
,
Box
*
func
,
Box
*
type
);
extern
"C"
Box
*
boxUnboundInstanceMethod
(
Box
*
func
);
extern
"C"
Box
*
boxUnboundInstanceMethod
(
Box
*
func
,
Box
*
type
);
extern
"C"
Box
*
boxStringPtr
(
const
std
::
string
*
s
);
extern
"C"
Box
*
boxStringPtr
(
const
std
::
string
*
s
);
Box
*
boxString
(
const
std
::
string
&
s
);
Box
*
boxString
(
const
std
::
string
&
s
);
...
@@ -470,10 +470,10 @@ public:
...
@@ -470,10 +470,10 @@ public:
Box
**
in_weakreflist
;
Box
**
in_weakreflist
;
// obj is NULL for unbound instancemethod
// obj is NULL for unbound instancemethod
Box
*
obj
,
*
func
;
Box
*
obj
,
*
func
,
*
im_class
;
BoxedInstanceMethod
(
Box
*
obj
,
Box
*
func
)
__attribute__
((
visibility
(
"default"
)))
BoxedInstanceMethod
(
Box
*
obj
,
Box
*
func
,
Box
*
im_class
)
__attribute__
((
visibility
(
"default"
)))
:
in_weakreflist
(
NULL
),
obj
(
obj
),
func
(
func
)
{}
:
in_weakreflist
(
NULL
),
obj
(
obj
),
func
(
func
)
,
im_class
(
im_class
)
{}
DEFAULT_CLASS_SIMPLE
(
instancemethod_cls
);
DEFAULT_CLASS_SIMPLE
(
instancemethod_cls
);
};
};
...
...
test/tests/function_instancemethod.py
View file @
4210ed9b
...
@@ -117,3 +117,13 @@ print type(bound_instancemethod)
...
@@ -117,3 +117,13 @@ print type(bound_instancemethod)
unbound_instancemethod
=
C
.
l
unbound_instancemethod
=
C
.
l
unbound_instancemethod
(
c2
)
unbound_instancemethod
(
c2
)
print
type
(
unbound_instancemethod
)
print
type
(
unbound_instancemethod
)
### Test instancemethod repr
print
'test instancemethod repr'
class
C
(
object
):
def
f
(
self
):
pass
def
__repr__
(
self
):
return
'(alpacas are cool)'
print
repr
(
C
.
f
)
print
repr
(
C
().
f
)
test/tests/instance_methods.py
View file @
4210ed9b
...
@@ -2,6 +2,38 @@ class C(object):
...
@@ -2,6 +2,38 @@ class C(object):
def
foo
(
self
):
def
foo
(
self
):
pass
pass
def
__repr__
(
self
):
return
'some C obj'
print
type
(
C
.
foo
)
print
type
(
C
.
foo
.
im_func
),
type
(
C
.
foo
.
__func__
)
print
type
(
C
.
foo
.
im_self
),
type
(
C
.
foo
.
__self__
)
print
type
(
C
.
foo
.
im_class
)
print
repr
(
C
.
foo
)
print
type
(
C
().
foo
)
print
type
(
C
().
foo
.
im_func
),
type
(
C
().
foo
.
__func__
)
print
type
(
C
().
foo
.
im_self
),
type
(
C
().
foo
.
__self__
)
print
type
(
C
().
foo
.
im_class
)
print
repr
(
C
().
foo
)
# old-style classes
class
C
:
def
foo
(
self
):
pass
def
__repr__
(
self
):
return
'some old-style C obj'
print
type
(
C
.
foo
)
print
type
(
C
.
foo
)
print
type
(
C
.
foo
.
im_func
),
type
(
C
.
foo
.
__func__
)
print
type
(
C
.
foo
.
im_func
),
type
(
C
.
foo
.
__func__
)
print
type
(
C
.
foo
.
im_self
),
type
(
C
.
foo
.
__self__
)
print
type
(
C
.
foo
.
im_self
),
type
(
C
.
foo
.
__self__
)
print
type
(
C
.
foo
.
im_class
)
print
repr
(
C
.
foo
)
print
type
(
C
().
foo
)
print
type
(
C
().
foo
.
im_func
),
type
(
C
().
foo
.
__func__
)
print
type
(
C
().
foo
.
im_self
),
type
(
C
().
foo
.
__self__
)
print
type
(
C
().
foo
.
im_class
)
print
repr
(
C
().
foo
)
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment