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
bd2ee538
Commit
bd2ee538
authored
Aug 21, 2015
by
Kevin Modzelewski
Browse files
Options
Browse Files
Download
Plain Diff
Merge pull request #852 from kmod/perf4
more small exceptions optimizations
parents
93ff229e
dbada809
Changes
13
Expand all
Show whitespace changes
Inline
Side-by-side
Showing
13 changed files
with
267 additions
and
114 deletions
+267
-114
from_cpython/Include/Python.h
from_cpython/Include/Python.h
+30
-0
from_cpython/Include/pyerrors.h
from_cpython/Include/pyerrors.h
+18
-6
from_cpython/Objects/exceptions.c
from_cpython/Objects/exceptions.c
+35
-25
src/capi/abstract.cpp
src/capi/abstract.cpp
+9
-2
src/capi/typeobject.cpp
src/capi/typeobject.cpp
+16
-4
src/capi/typeobject.h
src/capi/typeobject.h
+1
-0
src/core/thread_utils.h
src/core/thread_utils.h
+5
-0
src/core/types.h
src/core/types.h
+1
-0
src/runtime/capi.cpp
src/runtime/capi.cpp
+7
-0
src/runtime/descr.cpp
src/runtime/descr.cpp
+9
-3
src/runtime/types.cpp
src/runtime/types.cpp
+134
-73
src/runtime/types.h
src/runtime/types.h
+1
-0
test/tests/exceptions_basic.py
test/tests/exceptions_basic.py
+1
-1
No files found.
from_cpython/Include/Python.h
View file @
bd2ee538
...
...
@@ -86,6 +86,36 @@
#include "warnings.h"
#include "weakrefobject.h"
// Pyston additions:
// These new APIS give access to our fast hidden-class-based attributes implementation.
// Ideally in the future this will just be "storage strategy" of dicts and all Python
// dicts will benefit from it, but for now classes have to explicitly opt-in to having
// these kinds of attrs.
struct
_hcattrs
{
char
_data
[
16
];
};
#ifndef _PYSTON_API
typedef
struct
_hcattrs
PyHcAttrs
;
#else
namespace
pyston
{
class
HCAttrs
;
}
typedef
int
PyHcAttrs
;
#endif
PyAPI_FUNC
(
void
)
PyObject_InitHcAttrs
(
PyHcAttrs
*
)
PYSTON_NOEXCEPT
;
PyAPI_FUNC
(
PyObject
*
)
PyObject_GetAttrWrapper
(
PyObject
*
)
PYSTON_NOEXCEPT
;
PyAPI_FUNC
(
void
)
PyType_RequestHcAttrs
(
PyTypeObject
*
,
int
offset
)
PYSTON_NOEXCEPT
;
// Sets a descriptor on the type so that the attrs are available via __dict__
PyAPI_FUNC
(
void
)
PyType_GiveHcAttrsDictDescr
(
PyTypeObject
*
)
PYSTON_NOEXCEPT
;
// These functions directly manipulate the hcattrs storage, bypassing any getattro
// or descriptor logic. This is the equivallent of callling PyDict_GetItemString
// on an instance's dict.
// These functions try to mimic the Dict versions as much as possible, so for example
// the PyObject_GetHcAttrString function does not set an exception.
PyAPI_FUNC
(
PyObject
*
)
PyObject_GetHcAttrString
(
PyObject
*
,
const
char
*
)
PYSTON_NOEXCEPT
;
PyAPI_FUNC
(
int
)
PyObject_SetHcAttrString
(
PyObject
*
,
const
char
*
,
PyObject
*
)
PYSTON_NOEXCEPT
;
PyAPI_FUNC
(
int
)
PyObject_DelHcAttrString
(
PyObject
*
,
const
char
*
)
PYSTON_NOEXCEPT
;
#include "codecs.h"
#include "pyerrors.h"
...
...
from_cpython/Include/pyerrors.h
View file @
bd2ee538
...
...
@@ -10,14 +10,18 @@ extern "C" {
typedef
struct
{
PyObject_HEAD
PyObject
*
dict
;
// Pyston change: changed from dict to hcattrs
// PyObject *dict;
struct
_hcattrs
hcattrs
;
PyObject
*
args
;
PyObject
*
message
;
}
PyBaseExceptionObject
;
typedef
struct
{
PyObject_HEAD
PyObject
*
dict
;
// Pyston change: changed from dict to hcattrs
// PyObject *dict;
struct
_hcattrs
hcattrs
;
PyObject
*
args
;
PyObject
*
message
;
PyObject
*
msg
;
...
...
@@ -31,7 +35,9 @@ typedef struct {
#ifdef Py_USING_UNICODE
typedef
struct
{
PyObject_HEAD
PyObject
*
dict
;
// Pyston change: changed from dict to hcattrs
// PyObject *dict;
struct
_hcattrs
hcattrs
;
PyObject
*
args
;
PyObject
*
message
;
PyObject
*
encoding
;
...
...
@@ -44,7 +50,9 @@ typedef struct {
typedef
struct
{
PyObject_HEAD
PyObject
*
dict
;
// Pyston change: changed from dict to hcattrs
// PyObject *dict;
struct
_hcattrs
hcattrs
;
PyObject
*
args
;
PyObject
*
message
;
PyObject
*
code
;
...
...
@@ -52,7 +60,9 @@ typedef struct {
typedef
struct
{
PyObject_HEAD
PyObject
*
dict
;
// Pyston change: changed from dict to hcattrs
// PyObject *dict;
struct
_hcattrs
hcattrs
;
PyObject
*
args
;
PyObject
*
message
;
PyObject
*
myerrno
;
...
...
@@ -63,7 +73,9 @@ typedef struct {
#ifdef MS_WINDOWS
typedef
struct
{
PyObject_HEAD
PyObject
*
dict
;
// Pyston change: changed from dict to hcattrs
// PyObject *dict;
struct
_hcattrs
hcattrs
;
PyObject
*
args
;
PyObject
*
message
;
PyObject
*
myerrno
;
...
...
from_cpython/Objects/exceptions.c
View file @
bd2ee538
...
...
@@ -36,8 +36,8 @@ BaseException_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
self
=
(
PyBaseExceptionObject
*
)
type
->
tp_alloc
(
type
,
0
);
if
(
!
self
)
return
NULL
;
/* the dict is created on the fly in PyObject_GenericSetAttr */
self
->
message
=
self
->
dict
=
NULL
;
self
->
message
=
NULL
;
PyObject_InitHcAttrs
(
&
self
->
hcattrs
)
;
self
->
args
=
PyTuple_New
(
0
);
if
(
!
self
->
args
)
{
...
...
@@ -84,7 +84,7 @@ PyObject* PyErr_CreateExceptionInstance(PyObject* _type, PyObject* arg) {
if
(
!
self
)
return
NULL
;
self
->
dict
=
NULL
;
PyObject_InitHcAttrs
(
&
self
->
hcattrs
)
;
if
(
arg
)
{
self
->
args
=
PyTuple_Pack
(
1
,
arg
);
if
(
!
self
->
args
)
...
...
@@ -115,7 +115,8 @@ PyObject* PyErr_CreateExceptionInstance(PyObject* _type, PyObject* arg) {
static
int
BaseException_clear
(
PyBaseExceptionObject
*
self
)
{
Py_CLEAR
(
self
->
dict
);
// Pyston change:
// Py_CLEAR(self->dict);
Py_CLEAR
(
self
->
args
);
Py_CLEAR
(
self
->
message
);
return
0
;
...
...
@@ -132,7 +133,8 @@ BaseException_dealloc(PyBaseExceptionObject *self)
static
int
BaseException_traverse
(
PyBaseExceptionObject
*
self
,
visitproc
visit
,
void
*
arg
)
{
Py_VISIT
(
self
->
dict
);
// Pyston change:
// Py_VISIT(self->dict);
Py_VISIT
(
self
->
args
);
Py_VISIT
(
self
->
message
);
return
0
;
...
...
@@ -225,10 +227,16 @@ BaseException_repr(PyBaseExceptionObject *self)
static
PyObject
*
BaseException_reduce
(
PyBaseExceptionObject
*
self
)
{
/* Pyston change:
if (self->args && self->dict)
return PyTuple_Pack(3, Py_TYPE(self), self->args, self->dict);
else
return PyTuple_Pack(2, Py_TYPE(self), self->args);
*/
PyObject
*
attr_wrapper
=
PyObject_GetAttrWrapper
((
PyObject
*
)
self
);
if
(
!
attr_wrapper
)
return
NULL
;
return
PyTuple_Pack
(
3
,
Py_TYPE
(
self
),
self
->
args
,
attr_wrapper
);
}
/*
...
...
@@ -299,6 +307,7 @@ static PySequenceMethods BaseException_as_sequence = {
0
/* sq_inplace_repeat; */
};
/* Pyston change: we use the standard dict descriptor for these types now
static PyObject *
BaseException_get_dict(PyBaseExceptionObject *self)
{
...
...
@@ -327,6 +336,7 @@ BaseException_set_dict(PyBaseExceptionObject *self, PyObject *val)
self->dict = val;
return 0;
}
*/
static
PyObject
*
BaseException_get_args
(
PyBaseExceptionObject
*
self
)
...
...
@@ -361,8 +371,7 @@ BaseException_get_message(PyBaseExceptionObject *self)
PyObject
*
msg
;
/* if "message" is in self->dict, accessing a user-set message attribute */
if
(
self
->
dict
&&
(
msg
=
PyDict_GetItemString
(
self
->
dict
,
"message"
)))
{
if
((
msg
=
PyObject_GetHcAttrString
((
PyObject
*
)
self
,
"message"
)))
{
Py_INCREF
(
msg
);
return
msg
;
}
...
...
@@ -387,25 +396,18 @@ BaseException_set_message(PyBaseExceptionObject *self, PyObject *val)
{
/* if val is NULL, delete the message attribute */
if
(
val
==
NULL
)
{
if
(
self
->
dict
&&
PyDict_GetItemString
(
self
->
dict
,
"message"
))
{
if
(
Py
Dict_DelItemString
(
self
->
dict
,
"message"
)
<
0
)
if
(
PyObject_GetHcAttrString
((
PyObject
*
)
self
,
"message"
))
{
if
(
Py
Object_DelHcAttrString
((
PyObject
*
)
self
,
"message"
)
<
0
)
return
-
1
;
}
Py_CLEAR
(
self
->
message
);
return
0
;
}
/* else set it in __dict__, but may need to create the dict first */
if
(
self
->
dict
==
NULL
)
{
self
->
dict
=
PyDict_New
();
if
(
!
self
->
dict
)
return
-
1
;
}
return
PyDict_SetItemString
(
self
->
dict
,
"message"
,
val
);
return
PyObject_SetHcAttrString
((
PyObject
*
)
self
,
"message"
,
val
);
}
static
PyGetSetDef
BaseException_getset
[]
=
{
{
"__dict__"
,
(
getter
)
BaseException_get_dict
,
(
setter
)
BaseException_set_dict
},
{
"args"
,
(
getter
)
BaseException_get_args
,
(
setter
)
BaseException_set_args
},
{
"message"
,
(
getter
)
BaseException_get_message
,
(
setter
)
BaseException_set_message
},
...
...
@@ -450,7 +452,7 @@ static PyTypeObject _PyExc_BaseException = {
0
,
/* tp_dict */
0
,
/* tp_descr_get */
0
,
/* tp_descr_set */
offsetof
(
PyBaseExceptionObject
,
dict
)
,
/* tp_dictoffset */
/* Pyston change: offsetof(PyBaseExceptionObject, dict)*/
0
,
/* tp_dictoffset */
(
initproc
)
BaseException_init
,
/* tp_init */
0
,
/* tp_alloc */
BaseException_new
,
/* tp_new */
...
...
@@ -474,7 +476,7 @@ static PyTypeObject _PyExc_ ## EXCNAME = { \
Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE | Py_TPFLAGS_HAVE_GC, \
PyDoc_STR(EXCDOC), (traverseproc)BaseException_traverse, \
(inquiry)BaseException_clear, 0, 0, 0, 0, 0, 0, 0, &_ ## EXCBASE, \
0, 0, 0,
offsetof(PyBaseExceptionObject, dict)
, \
0, 0, 0,
/* Pyston change: offsetof(PyBaseExceptionObject, dict) */
0
, \
(initproc)BaseException_init, 0, BaseException_new,\
}; \
PyObject *PyExc_ ## EXCNAME = (PyObject *)&_PyExc_ ## EXCNAME
...
...
@@ -490,7 +492,7 @@ static PyTypeObject _PyExc_ ## EXCNAME = { \
Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE | Py_TPFLAGS_HAVE_GC, \
PyDoc_STR(EXCDOC), (traverseproc)EXCSTORE ## _traverse, \
(inquiry)EXCSTORE ## _clear, 0, 0, 0, 0, 0, 0, 0, &_ ## EXCBASE, \
0, 0, 0,
offsetof(Py ## EXCSTORE ## Object, dict)
, \
0, 0, 0,
/* Pyston change: offsetof(Py ## EXCSTORE ## Object, dict) */
0
, \
(initproc)EXCSTORE ## _init, 0, BaseException_new,\
}; \
PyObject *PyExc_ ## EXCNAME = (PyObject *)&_PyExc_ ## EXCNAME
...
...
@@ -507,7 +509,7 @@ static PyTypeObject _PyExc_ ## EXCNAME = { \
PyDoc_STR(EXCDOC), (traverseproc)EXCSTORE ## _traverse, \
(inquiry)EXCSTORE ## _clear, 0, 0, 0, 0, EXCMETHODS, \
EXCMEMBERS, 0, &_ ## EXCBASE, \
0, 0, 0,
offsetof(Py ## EXCSTORE ## Object, dict)
, \
0, 0, 0,
/* Pyston change: offsetof(Py ## EXCSTORE ## Object, dict) */
0
, \
(initproc)EXCSTORE ## _init, 0, BaseException_new,\
}; \
PyObject *PyExc_ ## EXCNAME = (PyObject *)&_PyExc_ ## EXCNAME
...
...
@@ -831,12 +833,17 @@ EnvironmentError_reduce(PyEnvironmentErrorObject *self)
}
else
Py_INCREF
(
args
);
/* Pyston change:
if (self->dict)
res = PyTuple_Pack(3, Py_TYPE(self), args, self->dict);
else
res = PyTuple_Pack(2, Py_TYPE(self), args);
Py_DECREF(args);
return
res
;
return res; */
PyObject
*
attr_wrapper
=
PyObject_GetAttrWrapper
((
PyObject
*
)
self
);
if
(
!
attr_wrapper
)
return
NULL
;
return
PyTuple_Pack
(
3
,
Py_TYPE
(
self
),
args
,
attr_wrapper
);
}
...
...
@@ -1743,7 +1750,7 @@ static PyTypeObject _PyExc_UnicodeEncodeError = {
Py_TPFLAGS_DEFAULT
|
Py_TPFLAGS_BASETYPE
|
Py_TPFLAGS_HAVE_GC
,
PyDoc_STR
(
"Unicode encoding error."
),
(
traverseproc
)
UnicodeError_traverse
,
(
inquiry
)
UnicodeError_clear
,
0
,
0
,
0
,
0
,
0
,
UnicodeError_members
,
0
,
&
_PyExc_UnicodeError
,
0
,
0
,
0
,
offsetof
(
PyUnicodeErrorObject
,
dict
)
,
0
,
&
_PyExc_UnicodeError
,
0
,
0
,
0
,
/* Pyston change: offsetof(PyUnicodeErrorObject, dict) */
0
,
(
initproc
)
UnicodeEncodeError_init
,
0
,
BaseException_new
,
};
PyObject
*
PyExc_UnicodeEncodeError
=
(
PyObject
*
)
&
_PyExc_UnicodeEncodeError
;
...
...
@@ -1828,7 +1835,7 @@ static PyTypeObject _PyExc_UnicodeDecodeError = {
Py_TPFLAGS_DEFAULT
|
Py_TPFLAGS_BASETYPE
|
Py_TPFLAGS_HAVE_GC
,
PyDoc_STR
(
"Unicode decoding error."
),
(
traverseproc
)
UnicodeError_traverse
,
(
inquiry
)
UnicodeError_clear
,
0
,
0
,
0
,
0
,
0
,
UnicodeError_members
,
0
,
&
_PyExc_UnicodeError
,
0
,
0
,
0
,
offsetof
(
PyUnicodeErrorObject
,
dict
)
,
0
,
&
_PyExc_UnicodeError
,
0
,
0
,
0
,
/* Pyston change: offsetof(PyUnicodeErrorObject, dict) */
0
,
(
initproc
)
UnicodeDecodeError_init
,
0
,
BaseException_new
,
};
PyObject
*
PyExc_UnicodeDecodeError
=
(
PyObject
*
)
&
_PyExc_UnicodeDecodeError
;
...
...
@@ -1926,7 +1933,7 @@ static PyTypeObject _PyExc_UnicodeTranslateError = {
Py_TPFLAGS_DEFAULT
|
Py_TPFLAGS_BASETYPE
|
Py_TPFLAGS_HAVE_GC
,
PyDoc_STR
(
"Unicode translation error."
),
(
traverseproc
)
UnicodeError_traverse
,
(
inquiry
)
UnicodeError_clear
,
0
,
0
,
0
,
0
,
0
,
UnicodeError_members
,
0
,
&
_PyExc_UnicodeError
,
0
,
0
,
0
,
offsetof
(
PyUnicodeErrorObject
,
dict
)
,
0
,
&
_PyExc_UnicodeError
,
0
,
0
,
0
,
/* Pyston change: offsetof(PyUnicodeErrorObject, dict) */
0
,
(
initproc
)
UnicodeTranslateError_init
,
0
,
BaseException_new
,
};
PyObject
*
PyExc_UnicodeTranslateError
=
(
PyObject
*
)
&
_PyExc_UnicodeTranslateError
;
...
...
@@ -2110,7 +2117,10 @@ _PyExc_Init(void)
{
PyObject
*
m
,
*
bltinmod
,
*
bdict
;
PyType_RequestHcAttrs
(
&
_PyExc_BaseException
,
offsetof
(
PyBaseExceptionObject
,
hcattrs
));
PRE_INIT
(
BaseException
)
PyType_GiveHcAttrsDictDescr
(
&
_PyExc_BaseException
);
PRE_INIT
(
Exception
)
PRE_INIT
(
StandardError
)
PRE_INIT
(
TypeError
)
...
...
src/capi/abstract.cpp
View file @
bd2ee538
...
...
@@ -797,8 +797,15 @@ extern "C" int PyObject_IsSubclass(PyObject* derived, PyObject* cls) noexcept {
return
r
;
}
if
(
!
(
PyClass_Check
(
cls
)
||
PyInstance_Check
(
cls
)))
{
PyObject
*
checker
;
PyObject
*
checker
=
NULL
;
if
(
cls
->
cls
->
has_subclasscheck
)
{
checker
=
_PyObject_LookupSpecial
(
cls
,
"__subclasscheck__"
,
&
name
);
if
(
!
checker
&&
PyErr_Occurred
())
return
-
1
;
assert
(
checker
);
}
if
(
checker
!=
NULL
)
{
PyObject
*
res
;
int
ok
=
-
1
;
...
...
src/capi/typeobject.cpp
View file @
bd2ee538
...
...
@@ -1152,7 +1152,7 @@ static PyObject* slot_tp_del(PyObject* self) noexcept {
}
}
static
int
slot_tp_init
(
PyObject
*
self
,
PyObject
*
args
,
PyObject
*
kwds
)
noexcept
{
/* Pyston change: static */
int
slot_tp_init
(
PyObject
*
self
,
PyObject
*
args
,
PyObject
*
kwds
)
noexcept
{
STAT_TIMER
(
t0
,
"us_timer_slot_tpinit"
,
SLOT_AVOIDABILITY
(
self
));
static
PyObject
*
init_str
;
...
...
@@ -1645,6 +1645,7 @@ static slotdef slotdefs[]
TPSLOT
(
"__del__"
,
tp_del
,
slot_tp_del
,
NULL
,
""
),
FLSLOT
(
"__class__"
,
has___class__
,
NULL
,
NULL
,
""
,
PyWrapperFlag_BOOL
),
FLSLOT
(
"__instancecheck__"
,
has_instancecheck
,
NULL
,
NULL
,
""
,
PyWrapperFlag_BOOL
),
FLSLOT
(
"__subclasscheck__"
,
has_subclasscheck
,
NULL
,
NULL
,
""
,
PyWrapperFlag_BOOL
),
FLSLOT
(
"__getattribute__"
,
has_getattribute
,
NULL
,
NULL
,
""
,
PyWrapperFlag_BOOL
),
TPPSLOT
(
"__hasnext__"
,
tpp_hasnext
,
slotTppHasnext
,
wrapInquirypred
,
"hasnext"
),
...
...
@@ -3262,6 +3263,18 @@ static Box* tppProxyToTpCall(Box* self, CallRewriteArgs* rewrite_args, ArgPassSp
return
r
;
}
extern
"C"
void
PyType_RequestHcAttrs
(
PyTypeObject
*
cls
,
int
offset
)
noexcept
{
assert
(
cls
->
attrs_offset
==
0
);
assert
(
cls
->
tp_dictoffset
==
0
);
cls
->
attrs_offset
=
offset
;
}
extern
"C"
void
PyType_GiveHcAttrsDictDescr
(
PyTypeObject
*
cls
)
noexcept
{
static
BoxedString
*
dict_str
=
internStringImmortal
(
"__dict__"
);
assert
(
!
cls
->
hasattr
(
dict_str
));
cls
->
giveAttr
(
dict_str
,
dict_descr
);
}
extern
"C"
int
PyType_Ready
(
PyTypeObject
*
cls
)
noexcept
{
ASSERT
(
!
cls
->
is_pyston_class
,
"should not call this on Pyston classes"
);
...
...
@@ -3389,11 +3402,10 @@ extern "C" int PyType_Ready(PyTypeObject* cls) noexcept {
// e.g. CTypes does this.
bool
is_metaclass
=
PyType_IsSubtype
(
cls
,
type_cls
);
assert
(
!
is_metaclass
||
cls
->
instancesHaveHCAttrs
()
||
cls
->
instancesHaveDictAttrs
());
}
else
{
// this should get automatically initialized to 0 on this path:
assert
(
cls
->
attrs_offset
==
0
);
}
assert
(
!
(
cls
->
instancesHaveHCAttrs
()
&&
cls
->
instancesHaveDictAttrs
()));
if
(
Py_TPFLAGS_BASE_EXC_SUBCLASS
&
cls
->
tp_flags
)
{
exception_types
.
push_back
(
cls
);
}
...
...
src/capi/typeobject.h
View file @
bd2ee538
...
...
@@ -51,6 +51,7 @@ int slot_sq_contains(PyObject* self, PyObject* value) noexcept;
Py_ssize_t
slot_sq_length
(
PyObject
*
self
)
noexcept
;
PyObject
*
slot_tp_getattr_hook
(
PyObject
*
self
,
PyObject
*
name
)
noexcept
;
PyObject
*
tp_new_wrapper
(
PyTypeObject
*
self
,
BoxedTuple
*
args
,
Box
*
kwds
)
noexcept
;
int
slot_tp_init
(
PyObject
*
self
,
PyObject
*
args
,
PyObject
*
kwds
)
noexcept
;
class
GetattrRewriteArgs
;
Box
*
slotTpGetattrHookInternal
(
Box
*
self
,
BoxedString
*
attr
,
GetattrRewriteArgs
*
rewrite_args
);
...
...
src/core/thread_utils.h
View file @
bd2ee538
...
...
@@ -225,15 +225,18 @@ protected:
}
else
++
it
;
}
ASSERT
(
this
->
map
.
size
()
==
this
->
map_elts
,
"%ld %d"
,
this
->
map
.
size
(),
this
->
map_elts
);
}
public:
PerThreadSet
(
CtorArgs
...
ctor_args
)
:
ctor_args
(
std
::
forward
<
CtorArgs
>
(
ctor_args
)...)
{
int
code
=
pthread_key_create
(
&
pthread_key
,
&
dtor
);
ASSERT
(
this
->
map
.
size
()
==
this
->
map_elts
,
"%ld %d"
,
this
->
map
.
size
(),
this
->
map_elts
);
}
void
forEachValue
(
std
::
function
<
void
(
T
*
)
>
f
)
{
LOCK_REGION
(
&
lock
);
ASSERT
(
this
->
map
.
size
()
==
this
->
map_elts
,
"%ld %d"
,
this
->
map
.
size
(),
this
->
map_elts
);
for
(
auto
&
p
:
map
)
{
f
(
&
p
.
second
->
val
);
...
...
@@ -242,6 +245,7 @@ public:
template
<
typename
...
Arguments
>
void
forEachValue
(
std
::
function
<
void
(
T
*
,
Arguments
...)
>
f
,
Arguments
...
args
)
{
LOCK_REGION
(
&
lock
);
ASSERT
(
this
->
map
.
size
()
==
this
->
map_elts
,
"%ld %d"
,
this
->
map
.
size
(),
this
->
map_elts
);
for
(
auto
&
p
:
map
)
{
f
(
&
p
.
second
->
val
,
std
::
forward
<
Arguments
>
(
args
)...);
...
...
@@ -267,6 +271,7 @@ public:
assert
(
map
.
count
(
pthread_self
())
==
0
);
map
[
pthread_self
()]
=
s
;
ASSERT
(
this
->
map
.
size
()
==
this
->
map_elts
,
"%ld %d"
,
this
->
map
.
size
(),
this
->
map_elts
);
}
return
&
s
->
val
;
}
...
...
src/core/types.h
View file @
bd2ee538
...
...
@@ -505,6 +505,7 @@ public:
HCAttrs
(
HiddenClass
*
hcls
=
root_hcls
)
:
hcls
(
hcls
),
attr_list
(
nullptr
)
{}
};
static_assert
(
sizeof
(
HCAttrs
)
==
sizeof
(
struct
_hcattrs
),
""
);
class
BoxedDict
;
class
BoxedString
;
...
...
src/runtime/capi.cpp
View file @
bd2ee538
...
...
@@ -984,6 +984,13 @@ extern "C" int PyErr_GivenExceptionMatches(PyObject* err, PyObject* exc) noexcep
err
=
PyExceptionInstance_Class
(
err
);
if
(
PyExceptionClass_Check
(
err
)
&&
PyExceptionClass_Check
(
exc
))
{
// Pyston addition: fast-path the check for if the exception exactly-matches the specifier.
// Note that we have to check that the exception specifier doesn't have a custom metaclass
// (ie it's cls is type_cls), since otherwise we would have to check for subclasscheck overloading.
// (TODO actually, that should be fast now)
if
(
exc
->
cls
==
type_cls
&&
exc
==
err
)
return
1
;
int
res
=
0
,
reclimit
;
PyObject
*
exception
,
*
value
,
*
tb
;
PyErr_Fetch
(
&
exception
,
&
value
,
&
tb
);
...
...
src/runtime/descr.cpp
View file @
bd2ee538
...
...
@@ -75,9 +75,9 @@ static Box* propertyInit(Box* _self, Box* fget, Box* fset, Box** args) {
Box
*
doc
=
args
[
1
];
BoxedProperty
*
self
=
static_cast
<
BoxedProperty
*>
(
_self
);
self
->
prop_get
=
fget
;
self
->
prop_set
=
fset
;
self
->
prop_del
=
fdel
;
self
->
prop_get
=
fget
==
None
?
NULL
:
fget
;
self
->
prop_set
=
fset
==
None
?
NULL
:
fset
;
self
->
prop_del
=
fdel
==
None
?
NULL
:
fdel
;
self
->
prop_doc
=
doc
;
self
->
getter_doc
=
false
;
...
...
@@ -151,6 +151,12 @@ static Box* property_copy(BoxedProperty* old, Box* get, Box* set, Box* del) {
return
prop
;
}
else
{
if
(
!
get
)
get
=
None
;
if
(
!
set
)
set
=
None
;
if
(
!
del
)
del
=
None
;
Box
*
doc
;
if
((
old
->
getter_doc
&&
get
!=
None
)
||
!
old
->
prop_doc
)
doc
=
None
;
...
...
src/runtime/types.cpp
View file @
bd2ee538
This diff is collapsed.
Click to expand it.
src/runtime/types.h
View file @
bd2ee538
...
...
@@ -232,6 +232,7 @@ public:
bool
has___class__
;
// Has a custom __class__ attribute (ie different from object's __class__ descriptor)
bool
has_instancecheck
;
bool
has_subclasscheck
;
bool
has_getattribute
;
typedef
bool
(
*
pyston_inquiry
)(
Box
*
);
...
...
test/tests/exceptions_basic.py
View file @
bd2ee538
...
...
@@ -104,7 +104,7 @@ f14()
def
test_set_state
():
exc
=
BaseException
()
print
exc
.
__dict__
print
sorted
(
exc
.
__dict__
.
items
())
attrs
=
{
"x"
:
1
,
"y"
:
2
}
exc
.
__setstate__
(
attrs
)
print
exc
.
__dict__
==
attrs
...
...
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