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
14f4fe98
Commit
14f4fe98
authored
Mar 14, 2016
by
Kevin Modzelewski
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Minor fixes
parent
f9ba4449
Changes
3
Hide whitespace changes
Inline
Side-by-side
Showing
3 changed files
with
79 additions
and
9 deletions
+79
-9
src/runtime/builtin_modules/sys.cpp
src/runtime/builtin_modules/sys.cpp
+26
-0
src/runtime/objmodel.cpp
src/runtime/objmodel.cpp
+8
-3
test/tests/descr_selfdelete.py
test/tests/descr_selfdelete.py
+45
-6
No files found.
src/runtime/builtin_modules/sys.cpp
View file @
14f4fe98
...
...
@@ -458,6 +458,30 @@ static PyObject* sys_displayhook(PyObject* self, PyObject* o) noexcept {
return
Py_None
;
}
static
PyObject
*
sys_clear_type_cache
(
PyObject
*
self
,
PyObject
*
args
)
{
PyType_ClearCache
();
Py_RETURN_NONE
;
}
PyDoc_STRVAR
(
sys_clear_type_cache__doc__
,
"_clear_type_cache() -> None
\n
\
Clear the internal type lookup cache."
);
static
PyObject
*
sys_getrefcount
(
PyObject
*
self
,
PyObject
*
arg
)
{
return
PyInt_FromSsize_t
(
arg
->
ob_refcnt
);
}
#ifdef Py_REF_DEBUG
static
PyObject
*
sys_gettotalrefcount
(
PyObject
*
self
)
{
return
PyInt_FromSsize_t
(
_Py_GetRefTotal
());
}
#endif
/* Py_REF_DEBUG */
PyDoc_STRVAR
(
getrefcount_doc
,
"getrefcount(object) -> integer
\n
\
\n
\
Return the reference count of object. The count returned is generally
\n
\
one higher than you might expect, because it includes the (temporary)
\n
\
reference as an argument to getrefcount()."
);
PyDoc_STRVAR
(
excepthook_doc
,
"excepthook(exctype, value, traceback) -> None
\n
"
"
\n
"
"Handle an exception by displaying it with a traceback on sys.stderr.
\n
"
);
...
...
@@ -469,6 +493,8 @@ PyDoc_STRVAR(displayhook_doc, "displayhook(object) -> None\n"
static
PyMethodDef
sys_methods
[]
=
{
{
"excepthook"
,
sys_excepthook
,
METH_VARARGS
,
excepthook_doc
},
{
"displayhook"
,
sys_displayhook
,
METH_O
,
displayhook_doc
},
{
"_clear_type_cache"
,
sys_clear_type_cache
,
METH_NOARGS
,
sys_clear_type_cache__doc__
},
{
"getrefcount"
,
(
PyCFunction
)
sys_getrefcount
,
METH_O
,
getrefcount_doc
},
};
PyDoc_STRVAR
(
version_info__doc__
,
"sys.version_info
\n
\
...
...
src/runtime/objmodel.cpp
View file @
14f4fe98
...
...
@@ -1314,6 +1314,7 @@ struct method_cache_entry {
static
struct
method_cache_entry
method_cache
[
1
<<
MCACHE_SIZE_EXP
];
static
unsigned
int
next_version_tag
=
0
;
static
bool
is_wrap_around
=
false
;
// Pyston addition
extern
"C"
unsigned
int
PyType_ClearCache
()
noexcept
{
Py_ssize_t
i
;
...
...
@@ -1327,6 +1328,7 @@ extern "C" unsigned int PyType_ClearCache() noexcept {
next_version_tag
=
0
;
/* mark all version tags as invalid */
PyType_Modified
(
&
PyBaseObject_Type
);
is_wrap_around
=
false
;
return
cur_version_tag
;
}
...
...
@@ -1351,7 +1353,6 @@ int assign_version_tag(PyTypeObject* type) noexcept {
if
(
unlikely
(
type
->
tp_version_tag
==
0
))
{
// Pyston change: check for a wrap around because they are not allowed to happen with our 64bit version tag
static
bool
is_wrap_around
=
false
;
if
(
is_wrap_around
)
abort
();
is_wrap_around
=
true
;
...
...
@@ -2739,18 +2740,20 @@ void setattrGeneric(Box* obj, BoxedString* attr, STOLEN(Box*) val, SetattrRewrit
// __set__ with `val` rather than directly calling setattr
if
(
descr
&&
_set_
)
{
AUTO_DECREF
(
val
);
Box
*
set_rtn
;
if
(
rewrite_args
)
{
CallRewriteArgs
crewrite_args
(
rewrite_args
->
rewriter
,
r_set
,
Location
::
any
());
crewrite_args
.
arg1
=
r_descr
;
crewrite_args
.
arg2
=
rewrite_args
->
obj
;
crewrite_args
.
arg3
=
rewrite_args
->
attrval
;
runtimeCallInternal
<
CXX
,
REWRITABLE
>
(
_set_
,
&
crewrite_args
,
ArgPassSpec
(
3
),
descr
,
obj
,
val
,
NULL
,
NULL
);
set_rtn
=
runtimeCallInternal
<
CXX
,
REWRITABLE
>
(
_set_
,
&
crewrite_args
,
ArgPassSpec
(
3
),
descr
,
obj
,
val
,
NULL
,
NULL
);
if
(
crewrite_args
.
out_success
)
{
rewrite_args
->
out_success
=
true
;
}
}
else
{
runtimeCallInternal
<
CXX
,
NOT_REWRITABLE
>
(
_set_
,
NULL
,
ArgPassSpec
(
3
),
descr
,
obj
,
val
,
NULL
,
NULL
);
set_rtn
=
runtimeCallInternal
<
CXX
,
NOT_REWRITABLE
>
(
_set_
,
NULL
,
ArgPassSpec
(
3
),
descr
,
obj
,
val
,
NULL
,
NULL
);
}
Py_DECREF
(
set_rtn
);
// We don't need to to the invalidation stuff in this case.
return
;
...
...
@@ -6107,6 +6110,7 @@ extern "C" void delattrGeneric(Box* obj, BoxedString* attr, DelattrRewriteArgs*
if
(
delAttr
!=
NULL
)
{
Box
*
rtn
=
runtimeCallInternal
<
CXX
,
NOT_REWRITABLE
>
(
delAttr
,
NULL
,
ArgPassSpec
(
2
),
clsAttr
,
obj
,
NULL
,
NULL
,
NULL
);
Py_DECREF
(
rtn
);
return
;
}
}
...
...
@@ -6154,6 +6158,7 @@ extern "C" void delattrInternal(Box* obj, BoxedString* attr, DelattrRewriteArgs*
assert
(
0
&&
"how to keep delAttr alive (esp in rewrite)"
);
if
(
delAttr
!=
NULL
)
{
Box
*
rtn
=
runtimeCallInternal
<
CXX
,
NOT_REWRITABLE
>
(
delAttr
,
NULL
,
ArgPassSpec
(
2
),
obj
,
attr
,
NULL
,
NULL
,
NULL
);
Py_DECREF
(
rtn
);
return
;
}
...
...
test/tests/descr_selfdelete.py
View file @
14f4fe98
# Test some internals: when we execute some special functions, we often need to
# make sure to keep a reference to that function, in case that function ends up
# unsetting itself.
#
# A couple notes about this test:
# - I think the _clear_type_cache calls are unnecessary, since the type cache is all borrowed references,
# but I left them in just in case.
# - Pyston is relatively capable of continuing to run a function that has been deallocated,
# since most of the metadata is stored on another structure that has a longer lifetime.
# So to try to get around that, this test adds some "other_arg" default arguments, since those
# will get collected when the function gets destroyed.
import
sys
class
C
(
object
):
def
__delattr__
(
self
,
attr
):
def
f
(
self
,
other_arg
=
2.5
**
10
):
print
"f"
print
other_arg
del
C
.
f
print
other_arg
c
=
C
()
c
.
f
()
class
C
(
object
):
def
__delattr__
(
self
,
attr
,
other_arg
=
2.3
**
10
):
print
"__delattr__"
print
other_arg
del
C
.
__delattr__
print
other_arg
sys
.
_clear_type_cache
()
print
other_arg
c
=
C
()
del
c
.
a
try
:
...
...
@@ -13,10 +37,13 @@ except Exception as e:
print
e
class
C
(
object
):
def
__getattr__
(
self
,
attr
):
def
__getattr__
(
self
,
attr
,
other_arg
=
2.2
**
10
):
print
"__getattr__"
print
other_arg
del
C
.
__getattr__
print
other_arg
sys
.
_clear_type_cache
()
print
other_arg
return
attr
c
=
C
()
print
c
.
a
...
...
@@ -26,10 +53,13 @@ except Exception as e:
print
e
class
C
(
object
):
def
__setattr__
(
self
,
attr
,
val
):
def
__setattr__
(
self
,
attr
,
val
,
other_arg
=
2.1
**
10
):
print
"__setattr__"
,
attr
,
val
print
other_arg
del
C
.
__setattr__
print
other_arg
sys
.
_clear_type_cache
()
print
other_arg
c
=
C
()
c
.
a
=
1
try
:
...
...
@@ -39,16 +69,24 @@ except Exception as e:
class
D
(
object
):
def
__get__
(
self
,
obj
,
type
):
def
__get__
(
self
,
obj
,
type
,
other_arg
=
2.4
**
10
):
print
"D.__get__"
print
other_arg
del
D
.
__get__
print
other_arg
sys
.
_clear_type_cache
()
print
other_arg
return
1
def
__set__
(
self
,
obj
,
value
):
print
"D.__set__"
def
__set__
(
self
,
obj
,
value
,
other_arg
=
2.0
**
10
):
print
"D.__set__"
,
obj
,
value
print
other_arg
del
D
.
__set__
print
other_arg
sys
.
_clear_type_cache
()
print
other_arg
return
1
C
.
x
=
D
()
c
=
C
()
...
...
@@ -57,3 +95,4 @@ print c.x
c
.
x
=
0
print
c
.
x
# TODO: lots of other cases that could/should get tested.
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