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
2e2456b3
Commit
2e2456b3
authored
Feb 15, 2016
by
Marius Wachtler
Browse files
Options
Browse Files
Download
Plain Diff
Merge pull request #1101 from corona10/error
Directly use cpythons errors.c file
parents
35ddf8d2
22f1e432
Changes
5
Hide whitespace changes
Inline
Side-by-side
Showing
5 changed files
with
802 additions
and
503 deletions
+802
-503
from_cpython/CMakeLists.txt
from_cpython/CMakeLists.txt
+1
-0
from_cpython/Python/errors.c
from_cpython/Python/errors.c
+801
-0
src/capi/errors.cpp
src/capi/errors.cpp
+0
-249
src/runtime/builtin_modules/builtins.cpp
src/runtime/builtin_modules/builtins.cpp
+0
-36
src/runtime/capi.cpp
src/runtime/capi.cpp
+0
-218
No files found.
from_cpython/CMakeLists.txt
View file @
2e2456b3
...
...
@@ -87,6 +87,7 @@ file(GLOB_RECURSE STDOBJECT_SRCS Objects
complexobject.c
dictobject.c
dictproxy.c
errors.c
exceptions.c
floatobject.c
fileobject.c
...
...
from_cpython/Python/errors.c
0 → 100644
View file @
2e2456b3
/* Error handling */
#include "Python.h"
#ifndef __STDC__
#ifndef MS_WINDOWS
extern
char
*
strerror
(
int
);
#endif
#endif
#ifdef MS_WINDOWS
#include "windows.h"
#include "winbase.h"
#endif
#include <ctype.h>
#ifdef __cplusplus
extern
"C"
{
#endif
void
PyErr_Restore
(
PyObject
*
type
,
PyObject
*
value
,
PyObject
*
traceback
)
{
PyThreadState
*
tstate
=
PyThreadState_GET
();
PyObject
*
oldtype
,
*
oldvalue
,
*
oldtraceback
;
if
(
traceback
!=
NULL
&&
!
PyTraceBack_Check
(
traceback
))
{
/* XXX Should never happen -- fatal error instead? */
/* Well, it could be None. */
Py_DECREF
(
traceback
);
traceback
=
NULL
;
}
/* Save these in locals to safeguard against recursive
invocation through Py_XDECREF */
oldtype
=
tstate
->
curexc_type
;
oldvalue
=
tstate
->
curexc_value
;
oldtraceback
=
tstate
->
curexc_traceback
;
tstate
->
curexc_type
=
type
;
tstate
->
curexc_value
=
value
;
tstate
->
curexc_traceback
=
traceback
;
Py_XDECREF
(
oldtype
);
Py_XDECREF
(
oldvalue
);
Py_XDECREF
(
oldtraceback
);
}
void
PyErr_SetObject
(
PyObject
*
exception
,
PyObject
*
value
)
{
Py_XINCREF
(
exception
);
Py_XINCREF
(
value
);
PyErr_Restore
(
exception
,
value
,
(
PyObject
*
)
NULL
);
}
void
PyErr_SetNone
(
PyObject
*
exception
)
{
PyErr_SetObject
(
exception
,
(
PyObject
*
)
NULL
);
}
void
PyErr_SetString
(
PyObject
*
exception
,
const
char
*
string
)
{
PyObject
*
value
=
PyString_FromString
(
string
);
PyErr_SetObject
(
exception
,
value
);
Py_XDECREF
(
value
);
}
PyObject
*
PyErr_Occurred
(
void
)
{
PyThreadState
*
tstate
=
PyThreadState_GET
();
return
tstate
->
curexc_type
;
}
int
PyErr_GivenExceptionMatches
(
PyObject
*
err
,
PyObject
*
exc
)
{
if
(
err
==
NULL
||
exc
==
NULL
)
{
/* maybe caused by "import exceptions" that failed early on */
return
0
;
}
if
(
PyTuple_Check
(
exc
))
{
Py_ssize_t
i
,
n
;
n
=
PyTuple_Size
(
exc
);
for
(
i
=
0
;
i
<
n
;
i
++
)
{
/* Test recursively */
if
(
PyErr_GivenExceptionMatches
(
err
,
PyTuple_GET_ITEM
(
exc
,
i
)))
{
return
1
;
}
}
return
0
;
}
/* err might be an instance, so check its class. */
if
(
PyExceptionInstance_Check
(
err
))
err
=
PyExceptionInstance_Class
(
err
);
if
(
PyExceptionClass_Check
(
err
)
&&
PyExceptionClass_Check
(
exc
))
{
int
res
=
0
,
reclimit
;
PyObject
*
exception
,
*
value
,
*
tb
;
PyErr_Fetch
(
&
exception
,
&
value
,
&
tb
);
/* Temporarily bump the recursion limit, so that in the most
common case PyObject_IsSubclass will not raise a recursion
error we have to ignore anyway. Don't do it when the limit
is already insanely high, to avoid overflow */
reclimit
=
Py_GetRecursionLimit
();
if
(
reclimit
<
(
1
<<
30
))
Py_SetRecursionLimit
(
reclimit
+
5
);
res
=
PyObject_IsSubclass
(
err
,
exc
);
Py_SetRecursionLimit
(
reclimit
);
/* This function must not fail, so print the error here */
if
(
res
==
-
1
)
{
PyErr_WriteUnraisable
(
err
);
res
=
0
;
}
PyErr_Restore
(
exception
,
value
,
tb
);
return
res
;
}
return
err
==
exc
;
}
int
PyErr_ExceptionMatches
(
PyObject
*
exc
)
{
return
PyErr_GivenExceptionMatches
(
PyErr_Occurred
(),
exc
);
}
/* pyston changed */
void
PyErr_NormalizeException
(
PyObject
**
exc
,
PyObject
**
val
,
PyObject
**
tb
)
{
PyObject
*
type
=
*
exc
;
PyObject
*
value
=
*
val
;
PyObject
*
inclass
=
NULL
;
PyObject
*
initial_tb
=
NULL
;
PyThreadState
*
tstate
=
NULL
;
if
(
type
==
NULL
)
{
/* There was no exception, so nothing to do. */
return
;
}
/* If PyErr_SetNone() was used, the value will have been actually
set to NULL.
*/
if
(
!
value
)
{
value
=
Py_None
;
Py_INCREF
(
value
);
}
if
(
PyExceptionInstance_Check
(
value
))
inclass
=
PyExceptionInstance_Class
(
value
);
/* Normalize the exception so that if the type is a class, the
value will be an instance.
*/
if
(
PyExceptionClass_Check
(
type
))
{
/* if the value was not an instance, or is not an instance
whose class is (or is derived from) type, then use the
value as an argument to instantiation of the type
class.
*/
if
(
!
inclass
||
!
PyObject_IsSubclass
(
inclass
,
type
))
{
// Pyston change: rewrote this section
PyObject
*
res
;
if
(
!
PyTuple_Check
(
value
))
{
res
=
PyErr_CreateExceptionInstance
(
type
,
value
==
Py_None
?
NULL
:
value
);
}
else
{
PyObject
*
args
=
value
;
// Pyston change:
// res = PyEval_CallObject(type, args);
res
=
PyObject_Call
(
type
,
args
,
NULL
);
}
if
(
res
==
NULL
)
goto
finally
;
value
=
res
;
}
/* if the class of the instance doesn't exactly match the
class of the type, believe the instance
*/
else
if
(
inclass
!=
type
)
{
Py_DECREF
(
type
);
type
=
inclass
;
Py_INCREF
(
type
);
}
}
*
exc
=
type
;
*
val
=
value
;
return
;
finally:
Py_DECREF
(
type
);
Py_DECREF
(
value
);
/* If the new exception doesn't set a traceback and the old
exception had a traceback, use the old traceback for the
new exception. It's better than nothing.
*/
initial_tb
=
*
tb
;
PyErr_Fetch
(
exc
,
val
,
tb
);
if
(
initial_tb
!=
NULL
)
{
if
(
*
tb
==
NULL
)
*
tb
=
initial_tb
;
else
Py_DECREF
(
initial_tb
);
}
/* normalize recursively */
tstate
=
PyThreadState_GET
();
if
(
++
tstate
->
recursion_depth
>
Py_GetRecursionLimit
())
{
--
tstate
->
recursion_depth
;
/* throw away the old exception... */
Py_DECREF
(
*
exc
);
Py_DECREF
(
*
val
);
/* ... and use the recursion error instead */
*
exc
=
PyExc_RuntimeError
;
*
val
=
PyExc_RecursionErrorInst
;
Py_INCREF
(
*
exc
);
Py_INCREF
(
*
val
);
/* just keeping the old traceback */
return
;
}
PyErr_NormalizeException
(
exc
,
val
,
tb
);
--
tstate
->
recursion_depth
;
}
void
PyErr_Fetch
(
PyObject
**
p_type
,
PyObject
**
p_value
,
PyObject
**
p_traceback
)
{
PyThreadState
*
tstate
=
PyThreadState_GET
();
*
p_type
=
tstate
->
curexc_type
;
*
p_value
=
tstate
->
curexc_value
;
*
p_traceback
=
tstate
->
curexc_traceback
;
tstate
->
curexc_type
=
NULL
;
tstate
->
curexc_value
=
NULL
;
tstate
->
curexc_traceback
=
NULL
;
}
void
PyErr_Clear
(
void
)
{
PyErr_Restore
(
NULL
,
NULL
,
NULL
);
}
/* Convenience functions to set a type error exception and return 0 */
int
PyErr_BadArgument
(
void
)
{
PyErr_SetString
(
PyExc_TypeError
,
"bad argument type for built-in operation"
);
return
0
;
}
PyObject
*
PyErr_NoMemory
(
void
)
{
if
(
PyErr_ExceptionMatches
(
PyExc_MemoryError
))
/* already current */
return
NULL
;
/* raise the pre-allocated instance if it still exists */
if
(
PyExc_MemoryErrorInst
)
PyErr_SetObject
(
PyExc_MemoryError
,
PyExc_MemoryErrorInst
);
else
/* this will probably fail since there's no memory and hee,
hee, we have to instantiate this class
*/
PyErr_SetNone
(
PyExc_MemoryError
);
return
NULL
;
}
PyObject
*
PyErr_SetFromErrnoWithFilenameObject
(
PyObject
*
exc
,
PyObject
*
filenameObject
)
{
PyObject
*
v
;
char
*
s
;
int
i
=
errno
;
#ifdef PLAN9
char
errbuf
[
ERRMAX
];
#endif
#ifdef MS_WINDOWS
char
*
s_buf
=
NULL
;
char
s_small_buf
[
28
];
/* Room for "Windows Error 0xFFFFFFFF" */
#endif
#ifdef EINTR
if
(
i
==
EINTR
&&
PyErr_CheckSignals
())
return
NULL
;
#endif
#ifdef PLAN9
rerrstr
(
errbuf
,
sizeof
errbuf
);
s
=
errbuf
;
#else
if
(
i
==
0
)
s
=
"Error"
;
/* Sometimes errno didn't get set */
else
#ifndef MS_WINDOWS
s
=
strerror
(
i
);
#else
{
/* Note that the Win32 errors do not lineup with the
errno error. So if the error is in the MSVC error
table, we use it, otherwise we assume it really _is_
a Win32 error code
*/
if
(
i
>
0
&&
i
<
_sys_nerr
)
{
s
=
_sys_errlist
[
i
];
}
else
{
int
len
=
FormatMessage
(
FORMAT_MESSAGE_ALLOCATE_BUFFER
|
FORMAT_MESSAGE_FROM_SYSTEM
|
FORMAT_MESSAGE_IGNORE_INSERTS
,
NULL
,
/* no message source */
i
,
MAKELANGID
(
LANG_NEUTRAL
,
SUBLANG_DEFAULT
),
/* Default language */
(
LPTSTR
)
&
s_buf
,
0
,
/* size not used */
NULL
);
/* no args */
if
(
len
==
0
)
{
/* Only ever seen this in out-of-mem
situations */
sprintf
(
s_small_buf
,
"Windows Error 0x%X"
,
i
);
s
=
s_small_buf
;
s_buf
=
NULL
;
}
else
{
s
=
s_buf
;
/* remove trailing cr/lf and dots */
while
(
len
>
0
&&
(
s
[
len
-
1
]
<=
' '
||
s
[
len
-
1
]
==
'.'
))
s
[
--
len
]
=
'\0'
;
}
}
}
#endif
/* Unix/Windows */
#endif
/* PLAN 9*/
if
(
filenameObject
!=
NULL
)
v
=
Py_BuildValue
(
"(isO)"
,
i
,
s
,
filenameObject
);
else
v
=
Py_BuildValue
(
"(is)"
,
i
,
s
);
if
(
v
!=
NULL
)
{
PyErr_SetObject
(
exc
,
v
);
Py_DECREF
(
v
);
}
#ifdef MS_WINDOWS
LocalFree
(
s_buf
);
#endif
return
NULL
;
}
PyObject
*
PyErr_SetFromErrnoWithFilename
(
PyObject
*
exc
,
const
char
*
filename
)
{
PyObject
*
name
=
filename
?
PyString_FromString
(
filename
)
:
NULL
;
PyObject
*
result
=
PyErr_SetFromErrnoWithFilenameObject
(
exc
,
name
);
Py_XDECREF
(
name
);
return
result
;
}
#ifdef MS_WINDOWS
PyObject
*
PyErr_SetFromErrnoWithUnicodeFilename
(
PyObject
*
exc
,
const
Py_UNICODE
*
filename
)
{
PyObject
*
name
=
filename
?
PyUnicode_FromUnicode
(
filename
,
wcslen
(
filename
))
:
NULL
;
PyObject
*
result
=
PyErr_SetFromErrnoWithFilenameObject
(
exc
,
name
);
Py_XDECREF
(
name
);
return
result
;
}
#endif
/* MS_WINDOWS */
PyObject
*
PyErr_SetFromErrno
(
PyObject
*
exc
)
{
return
PyErr_SetFromErrnoWithFilenameObject
(
exc
,
NULL
);
}
#ifdef MS_WINDOWS
/* Windows specific error code handling */
PyObject
*
PyErr_SetExcFromWindowsErrWithFilenameObject
(
PyObject
*
exc
,
int
ierr
,
PyObject
*
filenameObject
)
{
int
len
;
char
*
s
;
char
*
s_buf
=
NULL
;
/* Free via LocalFree */
char
s_small_buf
[
28
];
/* Room for "Windows Error 0xFFFFFFFF" */
PyObject
*
v
;
DWORD
err
=
(
DWORD
)
ierr
;
if
(
err
==
0
)
err
=
GetLastError
();
len
=
FormatMessage
(
/* Error API error */
FORMAT_MESSAGE_ALLOCATE_BUFFER
|
FORMAT_MESSAGE_FROM_SYSTEM
|
FORMAT_MESSAGE_IGNORE_INSERTS
,
NULL
,
/* no message source */
err
,
MAKELANGID
(
LANG_NEUTRAL
,
SUBLANG_DEFAULT
),
/* Default language */
(
LPTSTR
)
&
s_buf
,
0
,
/* size not used */
NULL
);
/* no args */
if
(
len
==
0
)
{
/* Only seen this in out of mem situations */
sprintf
(
s_small_buf
,
"Windows Error 0x%X"
,
err
);
s
=
s_small_buf
;
s_buf
=
NULL
;
}
else
{
s
=
s_buf
;
/* remove trailing cr/lf and dots */
while
(
len
>
0
&&
(
s
[
len
-
1
]
<=
' '
||
s
[
len
-
1
]
==
'.'
))
s
[
--
len
]
=
'\0'
;
}
if
(
filenameObject
!=
NULL
)
v
=
Py_BuildValue
(
"(isO)"
,
err
,
s
,
filenameObject
);
else
v
=
Py_BuildValue
(
"(is)"
,
err
,
s
);
if
(
v
!=
NULL
)
{
PyErr_SetObject
(
exc
,
v
);
Py_DECREF
(
v
);
}
LocalFree
(
s_buf
);
return
NULL
;
}
PyObject
*
PyErr_SetExcFromWindowsErrWithFilename
(
PyObject
*
exc
,
int
ierr
,
const
char
*
filename
)
{
PyObject
*
name
=
filename
?
PyString_FromString
(
filename
)
:
NULL
;
PyObject
*
ret
=
PyErr_SetExcFromWindowsErrWithFilenameObject
(
exc
,
ierr
,
name
);
Py_XDECREF
(
name
);
return
ret
;
}
PyObject
*
PyErr_SetExcFromWindowsErrWithUnicodeFilename
(
PyObject
*
exc
,
int
ierr
,
const
Py_UNICODE
*
filename
)
{
PyObject
*
name
=
filename
?
PyUnicode_FromUnicode
(
filename
,
wcslen
(
filename
))
:
NULL
;
PyObject
*
ret
=
PyErr_SetExcFromWindowsErrWithFilenameObject
(
exc
,
ierr
,
name
);
Py_XDECREF
(
name
);
return
ret
;
}
PyObject
*
PyErr_SetExcFromWindowsErr
(
PyObject
*
exc
,
int
ierr
)
{
return
PyErr_SetExcFromWindowsErrWithFilename
(
exc
,
ierr
,
NULL
);
}
PyObject
*
PyErr_SetFromWindowsErr
(
int
ierr
)
{
return
PyErr_SetExcFromWindowsErrWithFilename
(
PyExc_WindowsError
,
ierr
,
NULL
);
}
PyObject
*
PyErr_SetFromWindowsErrWithFilename
(
int
ierr
,
const
char
*
filename
)
{
PyObject
*
name
=
filename
?
PyString_FromString
(
filename
)
:
NULL
;
PyObject
*
result
=
PyErr_SetExcFromWindowsErrWithFilenameObject
(
PyExc_WindowsError
,
ierr
,
name
);
Py_XDECREF
(
name
);
return
result
;
}
PyObject
*
PyErr_SetFromWindowsErrWithUnicodeFilename
(
int
ierr
,
const
Py_UNICODE
*
filename
)
{
PyObject
*
name
=
filename
?
PyUnicode_FromUnicode
(
filename
,
wcslen
(
filename
))
:
NULL
;
PyObject
*
result
=
PyErr_SetExcFromWindowsErrWithFilenameObject
(
PyExc_WindowsError
,
ierr
,
name
);
Py_XDECREF
(
name
);
return
result
;
}
#endif
/* MS_WINDOWS */
void
_PyErr_BadInternalCall
(
const
char
*
filename
,
int
lineno
)
{
PyErr_Format
(
PyExc_SystemError
,
"%s:%d: bad argument to internal function"
,
filename
,
lineno
);
}
/* Remove the preprocessor macro for PyErr_BadInternalCall() so that we can
export the entry point for existing object code: */
#undef PyErr_BadInternalCall
void
PyErr_BadInternalCall
(
void
)
{
PyErr_Format
(
PyExc_SystemError
,
"bad argument to internal function"
);
}
#define PyErr_BadInternalCall() _PyErr_BadInternalCall(__FILE__, __LINE__)
PyObject
*
PyErr_Format
(
PyObject
*
exception
,
const
char
*
format
,
...)
{
va_list
vargs
;
PyObject
*
string
;
#ifdef HAVE_STDARG_PROTOTYPES
va_start
(
vargs
,
format
);
#else
va_start
(
vargs
);
#endif
string
=
PyString_FromFormatV
(
format
,
vargs
);
PyErr_SetObject
(
exception
,
string
);
Py_XDECREF
(
string
);
va_end
(
vargs
);
return
NULL
;
}
PyObject
*
PyErr_NewException
(
char
*
name
,
PyObject
*
base
,
PyObject
*
dict
)
{
char
*
dot
;
PyObject
*
modulename
=
NULL
;
PyObject
*
classname
=
NULL
;
PyObject
*
mydict
=
NULL
;
PyObject
*
bases
=
NULL
;
PyObject
*
result
=
NULL
;
dot
=
strrchr
(
name
,
'.'
);
if
(
dot
==
NULL
)
{
PyErr_SetString
(
PyExc_SystemError
,
"PyErr_NewException: name must be module.class"
);
return
NULL
;
}
if
(
base
==
NULL
)
base
=
PyExc_Exception
;
if
(
dict
==
NULL
)
{
dict
=
mydict
=
PyDict_New
();
if
(
dict
==
NULL
)
goto
failure
;
}
if
(
PyDict_GetItemString
(
dict
,
"__module__"
)
==
NULL
)
{
modulename
=
PyString_FromStringAndSize
(
name
,
(
Py_ssize_t
)(
dot
-
name
));
if
(
modulename
==
NULL
)
goto
failure
;
if
(
PyDict_SetItemString
(
dict
,
"__module__"
,
modulename
)
!=
0
)
goto
failure
;
}
if
(
PyTuple_Check
(
base
))
{
bases
=
base
;
/* INCREF as we create a new ref in the else branch */
Py_INCREF
(
bases
);
}
else
{
bases
=
PyTuple_Pack
(
1
,
base
);
if
(
bases
==
NULL
)
goto
failure
;
}
/* Create a real new-style class. */
result
=
PyObject_CallFunction
((
PyObject
*
)
&
PyType_Type
,
"sOO"
,
dot
+
1
,
bases
,
dict
);
failure:
Py_XDECREF
(
bases
);
Py_XDECREF
(
mydict
);
Py_XDECREF
(
classname
);
Py_XDECREF
(
modulename
);
return
result
;
}
/* Create an exception with docstring */
PyObject
*
PyErr_NewExceptionWithDoc
(
char
*
name
,
char
*
doc
,
PyObject
*
base
,
PyObject
*
dict
)
{
int
result
;
PyObject
*
ret
=
NULL
;
PyObject
*
mydict
=
NULL
;
/* points to the dict only if we create it */
PyObject
*
docobj
;
if
(
dict
==
NULL
)
{
dict
=
mydict
=
PyDict_New
();
if
(
dict
==
NULL
)
{
return
NULL
;
}
}
if
(
doc
!=
NULL
)
{
docobj
=
PyString_FromString
(
doc
);
if
(
docobj
==
NULL
)
goto
failure
;
result
=
PyDict_SetItemString
(
dict
,
"__doc__"
,
docobj
);
Py_DECREF
(
docobj
);
if
(
result
<
0
)
goto
failure
;
}
ret
=
PyErr_NewException
(
name
,
base
,
dict
);
failure:
Py_XDECREF
(
mydict
);
return
ret
;
}
/* Call when an exception has occurred but there is no way for Python
to handle it. Examples: exception in __del__ or during GC. */
void
PyErr_WriteUnraisable
(
PyObject
*
obj
)
{
PyObject
*
f
,
*
t
,
*
v
,
*
tb
;
PyErr_Fetch
(
&
t
,
&
v
,
&
tb
);
f
=
PySys_GetObject
(
"stderr"
);
if
(
f
!=
NULL
)
{
PyFile_WriteString
(
"Exception "
,
f
);
if
(
t
)
{
PyObject
*
moduleName
;
char
*
className
;
assert
(
PyExceptionClass_Check
(
t
));
className
=
(
char
*
)
PyExceptionClass_Name
(
t
);
if
(
className
!=
NULL
)
{
char
*
dot
=
strrchr
(
className
,
'.'
);
if
(
dot
!=
NULL
)
className
=
dot
+
1
;
}
moduleName
=
PyObject_GetAttrString
(
t
,
"__module__"
);
if
(
moduleName
==
NULL
)
PyFile_WriteString
(
"<unknown>"
,
f
);
else
{
char
*
modstr
=
PyString_AsString
(
moduleName
);
if
(
modstr
&&
strcmp
(
modstr
,
"exceptions"
)
!=
0
)
{
PyFile_WriteString
(
modstr
,
f
);
PyFile_WriteString
(
"."
,
f
);
}
}
if
(
className
==
NULL
)
PyFile_WriteString
(
"<unknown>"
,
f
);
else
PyFile_WriteString
(
className
,
f
);
if
(
v
&&
v
!=
Py_None
)
{
PyFile_WriteString
(
": "
,
f
);
PyFile_WriteObject
(
v
,
f
,
0
);
}
Py_XDECREF
(
moduleName
);
}
PyFile_WriteString
(
" in "
,
f
);
PyFile_WriteObject
(
obj
,
f
,
0
);
PyFile_WriteString
(
" ignored
\n
"
,
f
);
PyErr_Clear
();
/* Just in case */
}
Py_XDECREF
(
t
);
Py_XDECREF
(
v
);
Py_XDECREF
(
tb
);
}
extern
PyObject
*
PyModule_GetWarningsModule
(
void
);
/* Set file and line information for the current exception.
If the exception is not a SyntaxError, also sets additional attributes
to make printing of exceptions believe it is a syntax error. */
void
PyErr_SyntaxLocation
(
const
char
*
filename
,
int
lineno
)
{
PyObject
*
exc
,
*
v
,
*
tb
,
*
tmp
;
/* add attributes for the line number and filename for the error */
PyErr_Fetch
(
&
exc
,
&
v
,
&
tb
);
PyErr_NormalizeException
(
&
exc
,
&
v
,
&
tb
);
/* XXX check that it is, indeed, a syntax error. It might not
* be, though. */
tmp
=
PyInt_FromLong
(
lineno
);
if
(
tmp
==
NULL
)
PyErr_Clear
();
else
{
if
(
PyObject_SetAttrString
(
v
,
"lineno"
,
tmp
))
PyErr_Clear
();
Py_DECREF
(
tmp
);
}
if
(
filename
!=
NULL
)
{
tmp
=
PyString_FromString
(
filename
);
if
(
tmp
==
NULL
)
PyErr_Clear
();
else
{
if
(
PyObject_SetAttrString
(
v
,
"filename"
,
tmp
))
PyErr_Clear
();
Py_DECREF
(
tmp
);
}
tmp
=
PyErr_ProgramText
(
filename
,
lineno
);
if
(
tmp
)
{
if
(
PyObject_SetAttrString
(
v
,
"text"
,
tmp
))
PyErr_Clear
();
Py_DECREF
(
tmp
);
}
}
if
(
PyObject_SetAttrString
(
v
,
"offset"
,
Py_None
))
{
PyErr_Clear
();
}
if
(
exc
!=
PyExc_SyntaxError
)
{
if
(
!
PyObject_HasAttrString
(
v
,
"msg"
))
{
tmp
=
PyObject_Str
(
v
);
if
(
tmp
)
{
if
(
PyObject_SetAttrString
(
v
,
"msg"
,
tmp
))
PyErr_Clear
();
Py_DECREF
(
tmp
);
}
else
{
PyErr_Clear
();
}
}
if
(
!
PyObject_HasAttrString
(
v
,
"print_file_and_line"
))
{
if
(
PyObject_SetAttrString
(
v
,
"print_file_and_line"
,
Py_None
))
PyErr_Clear
();
}
}
PyErr_Restore
(
exc
,
v
,
tb
);
}
/* com_fetch_program_text will attempt to load the line of text that
the exception refers to. If it fails, it will return NULL but will
not set an exception.
XXX The functionality of this function is quite similar to the
functionality in tb_displayline() in traceback.c.
*/
PyObject
*
PyErr_ProgramText
(
const
char
*
filename
,
int
lineno
)
{
FILE
*
fp
;
int
i
;
char
linebuf
[
1000
];
if
(
filename
==
NULL
||
*
filename
==
'\0'
||
lineno
<=
0
)
return
NULL
;
fp
=
fopen
(
filename
,
"r"
PY_STDIOTEXTMODE
);
if
(
fp
==
NULL
)
return
NULL
;
for
(
i
=
0
;
i
<
lineno
;
i
++
)
{
char
*
pLastChar
=
&
linebuf
[
sizeof
(
linebuf
)
-
2
];
do
{
*
pLastChar
=
'\0'
;
if
(
Py_UniversalNewlineFgets
(
linebuf
,
sizeof
linebuf
,
fp
,
NULL
)
==
NULL
)
break
;
/* fgets read *something*; if it didn't get as
far as pLastChar, it must have found a newline
or hit the end of the file; if pLastChar is \n,
it obviously found a newline; else we haven't
yet seen a newline, so must continue */
}
while
(
*
pLastChar
!=
'\0'
&&
*
pLastChar
!=
'\n'
);
}
fclose
(
fp
);
if
(
i
==
lineno
)
{
char
*
p
=
linebuf
;
while
(
*
p
==
' '
||
*
p
==
'\t'
||
*
p
==
'\014'
)
p
++
;
return
PyString_FromString
(
p
);
}
return
NULL
;
}
#ifdef __cplusplus
}
#endif
src/capi/errors.cpp
View file @
2e2456b3
...
...
@@ -27,85 +27,6 @@
namespace
pyston
{
extern
"C"
PyObject
*
PyErr_SetFromErrnoWithFilenameObject
(
PyObject
*
exc
,
PyObject
*
filenameObject
)
noexcept
{
PyObject
*
v
;
// Pyston change: made const
const
char
*
s
;
int
i
=
errno
;
#ifdef PLAN9
char
errbuf
[
ERRMAX
];
#endif
#ifdef MS_WINDOWS
char
*
s_buf
=
NULL
;
char
s_small_buf
[
28
];
/* Room for "Windows Error 0xFFFFFFFF" */
#endif
#ifdef EINTR
if
(
i
==
EINTR
&&
PyErr_CheckSignals
())
return
NULL
;
#endif
#ifdef PLAN9
rerrstr
(
errbuf
,
sizeof
errbuf
);
s
=
errbuf
;
#else
if
(
i
==
0
)
s
=
"Error"
;
/* Sometimes errno didn't get set */
else
#ifndef MS_WINDOWS
s
=
strerror
(
i
);
#else
{
/* Note that the Win32 errors do not lineup with the
errno error. So if the error is in the MSVC error
table, we use it, otherwise we assume it really _is_
a Win32 error code
*/
if
(
i
>
0
&&
i
<
_sys_nerr
)
{
s
=
_sys_errlist
[
i
];
}
else
{
int
len
=
FormatMessage
(
FORMAT_MESSAGE_ALLOCATE_BUFFER
|
FORMAT_MESSAGE_FROM_SYSTEM
|
FORMAT_MESSAGE_IGNORE_INSERTS
,
NULL
,
/* no message source */
i
,
MAKELANGID
(
LANG_NEUTRAL
,
SUBLANG_DEFAULT
),
/* Default language */
(
LPTSTR
)
&
s_buf
,
0
,
/* size not used */
NULL
);
/* no args */
if
(
len
==
0
)
{
/* Only ever seen this in out-of-mem
situations */
sprintf
(
s_small_buf
,
"Windows Error 0x%X"
,
i
);
s
=
s_small_buf
;
s_buf
=
NULL
;
}
else
{
s
=
s_buf
;
/* remove trailing cr/lf and dots */
while
(
len
>
0
&&
(
s
[
len
-
1
]
<=
' '
||
s
[
len
-
1
]
==
'.'
))
s
[
--
len
]
=
'\0'
;
}
}
}
#endif
/* Unix/Windows */
#endif
/* PLAN 9*/
if
(
filenameObject
!=
NULL
)
v
=
Py_BuildValue
(
"(isO)"
,
i
,
s
,
filenameObject
);
else
v
=
Py_BuildValue
(
"(is)"
,
i
,
s
);
if
(
v
!=
NULL
)
{
PyErr_SetObject
(
exc
,
v
);
Py_DECREF
(
v
);
}
#ifdef MS_WINDOWS
LocalFree
(
s_buf
);
#endif
return
NULL
;
}
extern
"C"
PyObject
*
PyErr_SetFromErrnoWithFilename
(
PyObject
*
exc
,
const
char
*
filename
)
noexcept
{
PyObject
*
name
=
filename
?
PyString_FromString
(
filename
)
:
NULL
;
PyObject
*
result
=
PyErr_SetFromErrnoWithFilenameObject
(
exc
,
name
);
Py_XDECREF
(
name
);
return
result
;
}
#ifdef MS_WINDOWS
extern
"C"
PyObject
*
PyErr_SetFromErrnoWithUnicodeFilename
(
PyObject
*
exc
,
const
Py_UNICODE
*
filename
)
noexcept
{
PyObject
*
name
=
filename
?
PyUnicode_FromUnicode
(
filename
,
wcslen
(
filename
))
:
NULL
;
...
...
@@ -115,75 +36,6 @@ extern "C" PyObject* PyErr_SetFromErrnoWithUnicodeFilename(PyObject* exc, const
}
#endif
/* MS_WINDOWS */
extern
"C"
void
PyErr_Fetch
(
PyObject
**
p_type
,
PyObject
**
p_value
,
PyObject
**
p_traceback
)
noexcept
{
PyThreadState
*
tstate
=
PyThreadState_GET
();
*
p_type
=
tstate
->
curexc_type
;
*
p_value
=
tstate
->
curexc_value
;
*
p_traceback
=
tstate
->
curexc_traceback
;
tstate
->
curexc_type
=
NULL
;
tstate
->
curexc_value
=
NULL
;
tstate
->
curexc_traceback
=
NULL
;
}
extern
"C"
PyObject
*
PyErr_SetFromErrno
(
PyObject
*
exc
)
noexcept
{
return
PyErr_SetFromErrnoWithFilenameObject
(
exc
,
NULL
);
}
extern
"C"
void
PyErr_SetNone
(
PyObject
*
exception
)
noexcept
{
PyErr_SetObject
(
exception
,
(
PyObject
*
)
NULL
);
}
/* Call when an exception has occurred but there is no way for Python
to handle it. Examples: exception in __del__ or during GC. */
extern
"C"
void
PyErr_WriteUnraisable
(
PyObject
*
obj
)
noexcept
{
PyObject
*
f
,
*
t
,
*
v
,
*
tb
;
PyErr_Fetch
(
&
t
,
&
v
,
&
tb
);
f
=
PySys_GetObject
(
"stderr"
);
if
(
f
!=
NULL
)
{
PyFile_WriteString
(
"Exception "
,
f
);
if
(
t
)
{
PyObject
*
moduleName
;
const
char
*
className
;
assert
(
PyExceptionClass_Check
(
t
));
className
=
PyExceptionClass_Name
(
t
);
if
(
className
!=
NULL
)
{
const
char
*
dot
=
strrchr
(
className
,
'.'
);
if
(
dot
!=
NULL
)
className
=
dot
+
1
;
}
moduleName
=
PyObject_GetAttrString
(
t
,
"__module__"
);
if
(
moduleName
==
NULL
)
PyFile_WriteString
(
"<unknown>"
,
f
);
else
{
char
*
modstr
=
PyString_AsString
(
moduleName
);
if
(
modstr
&&
strcmp
(
modstr
,
"exceptions"
)
!=
0
)
{
PyFile_WriteString
(
modstr
,
f
);
PyFile_WriteString
(
"."
,
f
);
}
}
if
(
className
==
NULL
)
PyFile_WriteString
(
"<unknown>"
,
f
);
else
PyFile_WriteString
(
className
,
f
);
if
(
v
&&
v
!=
Py_None
)
{
PyFile_WriteString
(
": "
,
f
);
PyFile_WriteObject
(
v
,
f
,
0
);
}
Py_XDECREF
(
moduleName
);
}
PyFile_WriteString
(
" in "
,
f
);
PyFile_WriteObject
(
obj
,
f
,
0
);
PyFile_WriteString
(
" ignored
\n
"
,
f
);
PyErr_Clear
();
/* Just in case */
}
Py_XDECREF
(
t
);
Py_XDECREF
(
v
);
Py_XDECREF
(
tb
);
}
static
int
parse_syntax_error
(
PyObject
*
err
,
PyObject
**
message
,
const
char
**
filename
,
int
*
lineno
,
int
*
offset
,
const
char
**
text
)
noexcept
{
long
hold
;
...
...
@@ -493,108 +345,7 @@ extern "C" void PyErr_PrintEx(int set_sys_last_vars) noexcept {
Py_XDECREF
(
tb
);
}
extern
"C"
void
PyErr_Print
()
noexcept
{
PyErr_PrintEx
(
1
);
}
/* com_fetch_program_text will attempt to load the line of text that
the exception refers to. If it fails, it will return NULL but will
not set an exception.
XXX The functionality of this function is quite similar to the
functionality in tb_displayline() in traceback.c.
*/
extern
"C"
PyObject
*
PyErr_ProgramText
(
const
char
*
filename
,
int
lineno
)
noexcept
{
FILE
*
fp
;
int
i
;
char
linebuf
[
1000
];
if
(
filename
==
NULL
||
*
filename
==
'\0'
||
lineno
<=
0
)
return
NULL
;
fp
=
fopen
(
filename
,
"r"
PY_STDIOTEXTMODE
);
if
(
fp
==
NULL
)
return
NULL
;
for
(
i
=
0
;
i
<
lineno
;
i
++
)
{
char
*
pLastChar
=
&
linebuf
[
sizeof
(
linebuf
)
-
2
];
do
{
*
pLastChar
=
'\0'
;
if
(
Py_UniversalNewlineFgets
(
linebuf
,
sizeof
linebuf
,
fp
,
NULL
)
==
NULL
)
break
;
/* fgets read *something*; if it didn't get as
far as pLastChar, it must have found a newline
or hit the end of the file; if pLastChar is \n,
it obviously found a newline; else we haven't
yet seen a newline, so must continue */
}
while
(
*
pLastChar
!=
'\0'
&&
*
pLastChar
!=
'\n'
);
}
fclose
(
fp
);
if
(
i
==
lineno
)
{
char
*
p
=
linebuf
;
while
(
*
p
==
' '
||
*
p
==
'\t'
||
*
p
==
'\014'
)
p
++
;
return
PyString_FromString
(
p
);
}
return
NULL
;
}
/* Set file and line information for the current exception.
If the exception is not a SyntaxError, also sets additional attributes
to make printing of exceptions believe it is a syntax error. */
extern
"C"
void
PyErr_SyntaxLocation
(
const
char
*
filename
,
int
lineno
)
noexcept
{
PyObject
*
exc
,
*
v
,
*
tb
,
*
tmp
;
/* add attributes for the line number and filename for the error */
PyErr_Fetch
(
&
exc
,
&
v
,
&
tb
);
PyErr_NormalizeException
(
&
exc
,
&
v
,
&
tb
);
/* XXX check that it is, indeed, a syntax error. It might not
* be, though. */
tmp
=
PyInt_FromLong
(
lineno
);
if
(
tmp
==
NULL
)
PyErr_Clear
();
else
{
if
(
PyObject_SetAttrString
(
v
,
"lineno"
,
tmp
))
PyErr_Clear
();
Py_DECREF
(
tmp
);
}
if
(
filename
!=
NULL
)
{
tmp
=
PyString_FromString
(
filename
);
if
(
tmp
==
NULL
)
PyErr_Clear
();
else
{
if
(
PyObject_SetAttrString
(
v
,
"filename"
,
tmp
))
PyErr_Clear
();
Py_DECREF
(
tmp
);
}
tmp
=
PyErr_ProgramText
(
filename
,
lineno
);
if
(
tmp
)
{
if
(
PyObject_SetAttrString
(
v
,
"text"
,
tmp
))
PyErr_Clear
();
Py_DECREF
(
tmp
);
}
}
if
(
PyObject_SetAttrString
(
v
,
"offset"
,
Py_None
))
{
PyErr_Clear
();
}
if
(
exc
!=
PyExc_SyntaxError
)
{
if
(
!
PyObject_HasAttrString
(
v
,
"msg"
))
{
tmp
=
PyObject_Str
(
v
);
if
(
tmp
)
{
if
(
PyObject_SetAttrString
(
v
,
"msg"
,
tmp
))
PyErr_Clear
();
Py_DECREF
(
tmp
);
}
else
{
PyErr_Clear
();
}
}
if
(
!
PyObject_HasAttrString
(
v
,
"print_file_and_line"
))
{
if
(
PyObject_SetAttrString
(
v
,
"print_file_and_line"
,
Py_None
))
PyErr_Clear
();
}
}
PyErr_Restore
(
exc
,
v
,
tb
);
}
}
src/runtime/builtin_modules/builtins.cpp
View file @
2e2456b3
...
...
@@ -1132,42 +1132,6 @@ static BoxedClass* makeBuiltinException(BoxedClass* base, const char* name, int
return
cls
;
}
extern
"C"
PyObject
*
PyErr_NewException
(
char
*
name
,
PyObject
*
_base
,
PyObject
*
dict
)
noexcept
{
if
(
_base
==
NULL
)
_base
=
Exception
;
if
(
dict
==
NULL
)
dict
=
new
BoxedDict
();
try
{
char
*
dot_pos
=
strchr
(
name
,
'.'
);
RELEASE_ASSERT
(
dot_pos
,
""
);
int
n
=
strlen
(
name
);
BoxedString
*
boxedName
=
boxString
(
llvm
::
StringRef
(
dot_pos
+
1
,
n
-
(
dot_pos
-
name
)
-
1
));
// It can also be a tuple of bases
RELEASE_ASSERT
(
PyType_Check
(
_base
),
""
);
BoxedClass
*
base
=
static_cast
<
BoxedClass
*>
(
_base
);
if
(
PyDict_GetItemString
(
dict
,
"__module__"
)
==
NULL
)
{
PyDict_SetItemString
(
dict
,
"__module__"
,
boxString
(
llvm
::
StringRef
(
name
,
dot_pos
-
name
)));
}
checkAndThrowCAPIException
();
Box
*
cls
=
runtimeCall
(
type_cls
,
ArgPassSpec
(
3
),
boxedName
,
BoxedTuple
::
create
({
base
}),
dict
,
NULL
,
NULL
);
return
cls
;
}
catch
(
ExcInfo
e
)
{
// PyErr_NewException isn't supposed to fail, and callers sometimes take advantage of that
// by not checking the return value. Since failing probably indicates a bug anyway,
// to be safe just print the traceback and die.
e
.
printExcAndTraceback
();
RELEASE_ASSERT
(
0
,
"PyErr_NewException failed"
);
// The proper way of handling it:
setCAPIException
(
e
);
return
NULL
;
}
}
BoxedClass
*
enumerate_cls
;
class
BoxedEnumerate
:
public
Box
{
private:
...
...
src/runtime/capi.cpp
View file @
2e2456b3
...
...
@@ -65,10 +65,6 @@ int Py_Py3kWarningFlag;
BoxedClass
*
capifunc_cls
;
}
extern
"C"
void
_PyErr_BadInternalCall
(
const
char
*
filename
,
int
lineno
)
noexcept
{
PyErr_Format
(
PyExc_SystemError
,
"%s:%d: bad argument to internal function"
,
filename
,
lineno
);
}
extern
"C"
PyObject
*
PyObject_Format
(
PyObject
*
obj
,
PyObject
*
format_spec
)
noexcept
{
PyObject
*
empty
=
NULL
;
PyObject
*
result
=
NULL
;
...
...
@@ -684,102 +680,6 @@ extern "C" int Py_FlushLine(void) noexcept {
return
PyFile_WriteString
(
"
\n
"
,
f
);
}
extern
"C"
void
PyErr_NormalizeException
(
PyObject
**
exc
,
PyObject
**
val
,
PyObject
**
tb
)
noexcept
{
PyObject
*
type
=
*
exc
;
PyObject
*
value
=
*
val
;
PyObject
*
inclass
=
NULL
;
PyObject
*
initial_tb
=
NULL
;
PyThreadState
*
tstate
=
NULL
;
if
(
type
==
NULL
)
{
/* There was no exception, so nothing to do. */
return
;
}
/* If PyErr_SetNone() was used, the value will have been actually
set to NULL.
*/
if
(
!
value
)
{
value
=
Py_None
;
Py_INCREF
(
value
);
}
if
(
PyExceptionInstance_Check
(
value
))
inclass
=
PyExceptionInstance_Class
(
value
);
/* Normalize the exception so that if the type is a class, the
value will be an instance.
*/
if
(
PyExceptionClass_Check
(
type
))
{
/* if the value was not an instance, or is not an instance
whose class is (or is derived from) type, then use the
value as an argument to instantiation of the type
class.
*/
if
(
!
inclass
||
!
PyObject_IsSubclass
(
inclass
,
type
))
{
// Pyston change: rewrote this section
PyObject
*
res
;
if
(
!
PyTuple_Check
(
value
))
{
res
=
PyErr_CreateExceptionInstance
(
type
,
value
==
Py_None
?
NULL
:
value
);
}
else
{
PyObject
*
args
=
value
;
// Pyston change:
// res = PyEval_CallObject(type, args);
res
=
PyObject_Call
(
type
,
args
,
NULL
);
}
if
(
res
==
NULL
)
goto
finally
;
value
=
res
;
}
/* if the class of the instance doesn't exactly match the
class of the type, believe the instance
*/
else
if
(
inclass
!=
type
)
{
Py_DECREF
(
type
);
type
=
inclass
;
Py_INCREF
(
type
);
}
}
*
exc
=
type
;
*
val
=
value
;
return
;
finally:
Py_DECREF
(
type
);
Py_DECREF
(
value
);
/* If the new exception doesn't set a traceback and the old
exception had a traceback, use the old traceback for the
new exception. It's better than nothing.
*/
initial_tb
=
*
tb
;
PyErr_Fetch
(
exc
,
val
,
tb
);
if
(
initial_tb
!=
NULL
)
{
if
(
*
tb
==
NULL
)
*
tb
=
initial_tb
;
else
Py_DECREF
(
initial_tb
);
}
/* normalize recursively */
tstate
=
PyThreadState_GET
();
if
(
++
tstate
->
recursion_depth
>
Py_GetRecursionLimit
())
{
--
tstate
->
recursion_depth
;
/* throw away the old exception... */
Py_DECREF
(
*
exc
);
Py_DECREF
(
*
val
);
/* ... and use the recursion error instead */
*
exc
=
PyExc_RuntimeError
;
*
val
=
PyExc_RecursionErrorInst
;
Py_INCREF
(
*
exc
);
Py_INCREF
(
*
val
);
/* just keeping the old traceback */
return
;
}
PyErr_NormalizeException
(
exc
,
val
,
tb
);
--
tstate
->
recursion_depth
;
}
void
setCAPIException
(
const
ExcInfo
&
e
)
{
cur_thread_state
.
curexc_type
=
e
.
type
;
cur_thread_state
.
curexc_value
=
e
.
value
;
...
...
@@ -849,16 +749,6 @@ extern "C" void Py_Exit(int sts) noexcept {
exit
(
sts
);
}
extern
"C"
void
PyErr_Restore
(
PyObject
*
type
,
PyObject
*
value
,
PyObject
*
traceback
)
noexcept
{
cur_thread_state
.
curexc_type
=
type
;
cur_thread_state
.
curexc_value
=
value
;
cur_thread_state
.
curexc_traceback
=
traceback
;
}
extern
"C"
void
PyErr_Clear
()
noexcept
{
PyErr_Restore
(
NULL
,
NULL
,
NULL
);
}
extern
"C"
void
PyErr_GetExcInfo
(
PyObject
**
ptype
,
PyObject
**
pvalue
,
PyObject
**
ptraceback
)
noexcept
{
ExcInfo
*
exc
=
getFrameExcInfo
();
*
ptype
=
exc
->
type
;
...
...
@@ -873,54 +763,6 @@ extern "C" void PyErr_SetExcInfo(PyObject* type, PyObject* value, PyObject* trac
exc
->
traceback
=
traceback
?
traceback
:
None
;
}
extern
"C"
void
PyErr_SetString
(
PyObject
*
exception
,
const
char
*
string
)
noexcept
{
PyErr_SetObject
(
exception
,
boxString
(
string
));
}
extern
"C"
void
PyErr_SetObject
(
PyObject
*
exception
,
PyObject
*
value
)
noexcept
{
PyErr_Restore
(
exception
,
value
,
NULL
);
}
extern
"C"
PyObject
*
PyErr_Format
(
PyObject
*
exception
,
const
char
*
format
,
...)
noexcept
{
va_list
vargs
;
PyObject
*
string
;
#ifdef HAVE_STDARG_PROTOTYPES
va_start
(
vargs
,
format
);
#else
va_start
(
vargs
);
#endif
string
=
PyString_FromFormatV
(
format
,
vargs
);
PyErr_SetObject
(
exception
,
string
);
Py_XDECREF
(
string
);
va_end
(
vargs
);
return
NULL
;
}
extern
"C"
int
PyErr_BadArgument
()
noexcept
{
// TODO this is untested
PyErr_SetString
(
PyExc_TypeError
,
"bad argument type for built-in operation"
);
return
0
;
}
extern
"C"
PyObject
*
PyErr_NoMemory
()
noexcept
{
if
(
PyErr_ExceptionMatches
(
PyExc_MemoryError
))
/* already current */
return
NULL
;
/* raise the pre-allocated instance if it still exists */
if
(
PyExc_MemoryErrorInst
)
PyErr_SetObject
(
PyExc_MemoryError
,
PyExc_MemoryErrorInst
);
else
/* this will probably fail since there's no memory and hee,
hee, we have to instantiate this class
*/
PyErr_SetNone
(
PyExc_MemoryError
);
return
NULL
;
}
extern
"C"
const
char
*
PyExceptionClass_Name
(
PyObject
*
o
)
noexcept
{
return
PyClass_Check
(
o
)
?
PyString_AS_STRING
(
static_cast
<
BoxedClassobj
*>
(
o
)
->
name
)
:
static_cast
<
BoxedClass
*>
(
o
)
->
tp_name
;
...
...
@@ -969,66 +811,6 @@ extern "C" void Py_SetRecursionLimit(int new_limit) noexcept {
_Py_CheckRecursionLimit
=
recursion_limit
;
}
extern
"C"
int
PyErr_GivenExceptionMatches
(
PyObject
*
err
,
PyObject
*
exc
)
noexcept
{
if
(
err
==
NULL
||
exc
==
NULL
)
{
/* maybe caused by "import exceptions" that failed early on */
return
0
;
}
if
(
PyTuple_Check
(
exc
))
{
Py_ssize_t
i
,
n
;
n
=
PyTuple_Size
(
exc
);
for
(
i
=
0
;
i
<
n
;
i
++
)
{
/* Test recursively */
if
(
PyErr_GivenExceptionMatches
(
err
,
PyTuple_GET_ITEM
(
exc
,
i
)))
{
return
1
;
}
}
return
0
;
}
/* err might be an instance, so check its class. */
if
(
PyExceptionInstance_Check
(
err
))
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
);
/* Temporarily bump the recursion limit, so that in the most
common case PyObject_IsSubclass will not raise a recursion
error we have to ignore anyway. Don't do it when the limit
is already insanely high, to avoid overflow */
reclimit
=
Py_GetRecursionLimit
();
if
(
reclimit
<
(
1
<<
30
))
Py_SetRecursionLimit
(
reclimit
+
5
);
res
=
PyObject_IsSubclass
(
err
,
exc
);
Py_SetRecursionLimit
(
reclimit
);
/* This function must not fail, so print the error here */
if
(
res
==
-
1
)
{
PyErr_WriteUnraisable
(
err
);
res
=
0
;
}
PyErr_Restore
(
exception
,
value
,
tb
);
return
res
;
}
return
err
==
exc
;
}
extern
"C"
int
PyErr_ExceptionMatches
(
PyObject
*
exc
)
noexcept
{
return
PyErr_GivenExceptionMatches
(
PyErr_Occurred
(),
exc
);
}
extern
"C"
PyObject
*
PyErr_Occurred
()
noexcept
{
return
cur_thread_state
.
curexc_type
;
}
extern
"C"
void
*
PyObject_Malloc
(
size_t
sz
)
noexcept
{
return
gc_compat_malloc
(
sz
);
}
...
...
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