Commit 14f4fe98 authored by Kevin Modzelewski's avatar Kevin Modzelewski

Minor fixes

parent f9ba4449
...@@ -458,6 +458,30 @@ static PyObject* sys_displayhook(PyObject* self, PyObject* o) noexcept { ...@@ -458,6 +458,30 @@ static PyObject* sys_displayhook(PyObject* self, PyObject* o) noexcept {
return Py_None; 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" PyDoc_STRVAR(excepthook_doc, "excepthook(exctype, value, traceback) -> None\n"
"\n" "\n"
"Handle an exception by displaying it with a traceback on sys.stderr.\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" ...@@ -469,6 +493,8 @@ PyDoc_STRVAR(displayhook_doc, "displayhook(object) -> None\n"
static PyMethodDef sys_methods[] = { static PyMethodDef sys_methods[] = {
{ "excepthook", sys_excepthook, METH_VARARGS, excepthook_doc }, { "excepthook", sys_excepthook, METH_VARARGS, excepthook_doc },
{ "displayhook", sys_displayhook, METH_O, displayhook_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\ PyDoc_STRVAR(version_info__doc__, "sys.version_info\n\
......
...@@ -1314,6 +1314,7 @@ struct method_cache_entry { ...@@ -1314,6 +1314,7 @@ struct method_cache_entry {
static struct method_cache_entry method_cache[1 << MCACHE_SIZE_EXP]; static struct method_cache_entry method_cache[1 << MCACHE_SIZE_EXP];
static unsigned int next_version_tag = 0; static unsigned int next_version_tag = 0;
static bool is_wrap_around = false; // Pyston addition
extern "C" unsigned int PyType_ClearCache() noexcept { extern "C" unsigned int PyType_ClearCache() noexcept {
Py_ssize_t i; Py_ssize_t i;
...@@ -1327,6 +1328,7 @@ extern "C" unsigned int PyType_ClearCache() noexcept { ...@@ -1327,6 +1328,7 @@ extern "C" unsigned int PyType_ClearCache() noexcept {
next_version_tag = 0; next_version_tag = 0;
/* mark all version tags as invalid */ /* mark all version tags as invalid */
PyType_Modified(&PyBaseObject_Type); PyType_Modified(&PyBaseObject_Type);
is_wrap_around = false;
return cur_version_tag; return cur_version_tag;
} }
...@@ -1351,7 +1353,6 @@ int assign_version_tag(PyTypeObject* type) noexcept { ...@@ -1351,7 +1353,6 @@ int assign_version_tag(PyTypeObject* type) noexcept {
if (unlikely(type->tp_version_tag == 0)) { 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 // 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) if (is_wrap_around)
abort(); abort();
is_wrap_around = true; is_wrap_around = true;
...@@ -2739,18 +2740,20 @@ void setattrGeneric(Box* obj, BoxedString* attr, STOLEN(Box*) val, SetattrRewrit ...@@ -2739,18 +2740,20 @@ void setattrGeneric(Box* obj, BoxedString* attr, STOLEN(Box*) val, SetattrRewrit
// __set__ with `val` rather than directly calling setattr // __set__ with `val` rather than directly calling setattr
if (descr && _set_) { if (descr && _set_) {
AUTO_DECREF(val); AUTO_DECREF(val);
Box* set_rtn;
if (rewrite_args) { if (rewrite_args) {
CallRewriteArgs crewrite_args(rewrite_args->rewriter, r_set, Location::any()); CallRewriteArgs crewrite_args(rewrite_args->rewriter, r_set, Location::any());
crewrite_args.arg1 = r_descr; crewrite_args.arg1 = r_descr;
crewrite_args.arg2 = rewrite_args->obj; crewrite_args.arg2 = rewrite_args->obj;
crewrite_args.arg3 = rewrite_args->attrval; 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) { if (crewrite_args.out_success) {
rewrite_args->out_success = true; rewrite_args->out_success = true;
} }
} else { } 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. // We don't need to to the invalidation stuff in this case.
return; return;
...@@ -6107,6 +6110,7 @@ extern "C" void delattrGeneric(Box* obj, BoxedString* attr, DelattrRewriteArgs* ...@@ -6107,6 +6110,7 @@ extern "C" void delattrGeneric(Box* obj, BoxedString* attr, DelattrRewriteArgs*
if (delAttr != NULL) { if (delAttr != NULL) {
Box* rtn = runtimeCallInternal<CXX, NOT_REWRITABLE>(delAttr, NULL, ArgPassSpec(2), clsAttr, obj, NULL, NULL, Box* rtn = runtimeCallInternal<CXX, NOT_REWRITABLE>(delAttr, NULL, ArgPassSpec(2), clsAttr, obj, NULL, NULL,
NULL); NULL);
Py_DECREF(rtn);
return; return;
} }
} }
...@@ -6154,6 +6158,7 @@ extern "C" void delattrInternal(Box* obj, BoxedString* attr, DelattrRewriteArgs* ...@@ -6154,6 +6158,7 @@ extern "C" void delattrInternal(Box* obj, BoxedString* attr, DelattrRewriteArgs*
assert(0 && "how to keep delAttr alive (esp in rewrite)"); assert(0 && "how to keep delAttr alive (esp in rewrite)");
if (delAttr != NULL) { if (delAttr != NULL) {
Box* rtn = runtimeCallInternal<CXX, NOT_REWRITABLE>(delAttr, NULL, ArgPassSpec(2), obj, attr, NULL, NULL, NULL); Box* rtn = runtimeCallInternal<CXX, NOT_REWRITABLE>(delAttr, NULL, ArgPassSpec(2), obj, attr, NULL, NULL, NULL);
Py_DECREF(rtn);
return; return;
} }
......
# 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 import sys
class C(object): 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 "__delattr__"
print other_arg
del C.__delattr__ del C.__delattr__
print other_arg
sys._clear_type_cache() sys._clear_type_cache()
print other_arg
c = C() c = C()
del c.a del c.a
try: try:
...@@ -13,10 +37,13 @@ except Exception as e: ...@@ -13,10 +37,13 @@ except Exception as e:
print e print e
class C(object): class C(object):
def __getattr__(self, attr): def __getattr__(self, attr, other_arg=2.2**10):
print "__getattr__" print "__getattr__"
print other_arg
del C.__getattr__ del C.__getattr__
print other_arg
sys._clear_type_cache() sys._clear_type_cache()
print other_arg
return attr return attr
c = C() c = C()
print c.a print c.a
...@@ -26,10 +53,13 @@ except Exception as e: ...@@ -26,10 +53,13 @@ except Exception as e:
print e print e
class C(object): class C(object):
def __setattr__(self, attr, val): def __setattr__(self, attr, val, other_arg=2.1**10):
print "__setattr__", attr, val print "__setattr__", attr, val
print other_arg
del C.__setattr__ del C.__setattr__
print other_arg
sys._clear_type_cache() sys._clear_type_cache()
print other_arg
c = C() c = C()
c.a = 1 c.a = 1
try: try:
...@@ -39,16 +69,24 @@ except Exception as e: ...@@ -39,16 +69,24 @@ except Exception as e:
class D(object): class D(object):
def __get__(self, obj, type): def __get__(self, obj, type, other_arg=2.4**10):
print "D.__get__" print "D.__get__"
print other_arg
del D.__get__ del D.__get__
print other_arg
sys._clear_type_cache() sys._clear_type_cache()
print other_arg
return 1 return 1
def __set__(self, obj, value): def __set__(self, obj, value, other_arg=2.0**10):
print "D.__set__" print "D.__set__", obj, value
print other_arg
del D.__set__ del D.__set__
print other_arg
sys._clear_type_cache() sys._clear_type_cache()
print other_arg
return 1
C.x = D() C.x = D()
c = C() c = C()
...@@ -57,3 +95,4 @@ print c.x ...@@ -57,3 +95,4 @@ print c.x
c.x = 0 c.x = 0
print c.x print c.x
# TODO: lots of other cases that could/should get tested.
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