Commit 22f1e432 authored by Dong-hee Na's avatar Dong-hee Na

Directly use cpythons errors.c file

parent 35ddf8d2
......@@ -87,6 +87,7 @@ file(GLOB_RECURSE STDOBJECT_SRCS Objects
complexobject.c
dictobject.c
dictproxy.c
errors.c
exceptions.c
floatobject.c
fileobject.c
......
This diff is collapsed.
......@@ -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);
}
}
......@@ -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:
......
......@@ -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);
}
......
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