Commit 077fffc6 authored by Kevin Modzelewski's avatar Kevin Modzelewski

Merge branch 'exceptions'

parents e3016cd2 acf80b82
......@@ -292,7 +292,7 @@ STDLIB_RELEASE_OBJS := stdlib.release.bc.o
ASM_SRCS := $(wildcard src/runtime/*.S)
STDMODULE_SRCS := errnomodule.c shamodule.c sha256module.c sha512module.c _math.c mathmodule.c md5.c md5module.c _randommodule.c _sre.c operator.c binascii.c pwdmodule.c posixmodule.c _struct.c datetimemodule.c _functoolsmodule.c _collectionsmodule.c itertoolsmodule.c resource.c signalmodule.c selectmodule.c fcntlmodule.c timemodule.c arraymodule.c zlibmodule.c _codecsmodule.c socketmodule.c $(EXTRA_STDMODULE_SRCS)
STDOBJECT_SRCS := structseq.c capsule.c stringobject.c $(EXTRA_STDOBJECT_SRCS)
STDOBJECT_SRCS := structseq.c capsule.c stringobject.c exceptions.c $(EXTRA_STDOBJECT_SRCS)
STDPYTHON_SRCS := pyctype.c getargs.c formatter_string.c pystrtod.c dtoa.c $(EXTRA_STDPYTHON_SRCS)
FROM_CPYTHON_SRCS := $(addprefix from_cpython/Modules/,$(STDMODULE_SRCS)) $(addprefix from_cpython/Objects/,$(STDOBJECT_SRCS)) $(addprefix from_cpython/Python/,$(STDPYTHON_SRCS))
......
......@@ -18,7 +18,7 @@ add_custom_target(copy_stdlib ALL DEPENDS ${STDLIB_TARGETS})
file(GLOB_RECURSE STDMODULE_SRCS Modules errnomodule.c shamodule.c sha256module.c sha512module.c _math.c mathmodule.c md5.c md5module.c _randommodule.c _sre.c operator.c binascii.c pwdmodule.c posixmodule.c _struct.c datetimemodule.c _functoolsmodule.c _collectionsmodule.c itertoolsmodule.c resource.c signalmodule.c selectmodule.c fcntlmodule.c timemodule.c arraymodule.c zlibmodule.c _codecsmodule.c socketmodule.c)
# compile specified files in from_cpython/Objects
file(GLOB_RECURSE STDOBJECT_SRCS Objects structseq.c capsule.c stringobject.c)
file(GLOB_RECURSE STDOBJECT_SRCS Objects structseq.c capsule.c stringobject.c exceptions.c)
# compile specified files in from_cpython/Python
file(GLOB_RECURSE STDPYTHON_SRCS Python getargs.c pyctype.c formatter_string.c pystrtod.c dtoa.c)
......
// This file is originally from CPython 2.7, with modifications for Pyston
#ifndef Py_OSDEFS_H
#define Py_OSDEFS_H
#ifdef __cplusplus
extern "C" {
#endif
/* Operating system dependencies */
/* Mod by chrish: QNX has WATCOM, but isn't DOS */
#if !defined(__QNX__)
#if defined(MS_WINDOWS) || defined(__BORLANDC__) || defined(__WATCOMC__) || defined(__DJGPP__) || defined(PYOS_OS2)
#if defined(PYOS_OS2) && defined(PYCC_GCC)
#define MAXPATHLEN 260
#define SEP '/'
#define ALTSEP '\\'
#else
#define SEP '\\'
#define ALTSEP '/'
#define MAXPATHLEN 256
#endif
#define DELIM ';'
#endif
#endif
#ifdef RISCOS
#define SEP '.'
#define MAXPATHLEN 256
#define DELIM ','
#endif
/* Filename separator */
#ifndef SEP
#define SEP '/'
#endif
/* Max pathname length */
#ifdef __hpux
#include <sys/param.h>
#include <limits.h>
#ifndef PATH_MAX
#define PATH_MAX MAXPATHLEN
#endif
#endif
#ifndef MAXPATHLEN
#if defined(PATH_MAX) && PATH_MAX > 1024
#define MAXPATHLEN PATH_MAX
#else
#define MAXPATHLEN 1024
#endif
#endif
/* Search path entry delimiter */
#ifndef DELIM
#define DELIM ':'
#endif
#ifdef __cplusplus
}
#endif
#endif /* !Py_OSDEFS_H */
......@@ -8,8 +8,6 @@ extern "C" {
/* Error objects */
// Pyston change: these are not our object formats
#if 0
typedef struct {
PyObject_HEAD
PyObject *dict;
......@@ -74,8 +72,6 @@ typedef struct {
PyObject *winerror;
} PyWindowsErrorObject;
#endif
#endif
// (Pyston TODO: add opaque definitions of those names)
/* Error handling definitions */
......@@ -132,119 +128,68 @@ PyAPI_FUNC(PyObject*) PyExceptionInstance_Class(PyObject*) PYSTON_NOEXCEPT;
// as PyTypeObject's.
// TODO not sure if this is worth it -- a fair amount of confusion (duplicating these names) for fairly
// little gain (getting to treat them as PyTypeObject's and using our own names)
#define PyExc_BaseException ((PyObject*)BaseException)
PyAPI_DATA(PyTypeObject *) BaseException;
#define PyExc_Exception ((PyObject*)Exception)
PyAPI_DATA(PyTypeObject *) Exception;
#define PyExc_StopIteration ((PyObject*)StopIteration)
PyAPI_DATA(PyTypeObject *) StopIteration;
#define PyExc_GeneratorExit ((PyObject*)GeneratorExit)
PyAPI_DATA(PyTypeObject *) GeneratorExit;
#define PyExc_StandardError ((PyObject*)StandardError)
PyAPI_DATA(PyTypeObject *) StandardError;
#define PyExc_ArithmeticError ((PyObject*)ArithmeticError)
PyAPI_DATA(PyTypeObject *) ArithmeticError;
#define PyExc_LookupError ((PyObject*)LookupError)
PyAPI_DATA(PyTypeObject *) LookupError;
#define PyExc_AssertionError ((PyObject*)AssertionError)
PyAPI_DATA(PyTypeObject *) AssertionError;
#define PyExc_AttributeError ((PyObject*)AttributeError)
PyAPI_DATA(PyTypeObject *) AttributeError;
#define PyExc_EOFError ((PyObject*)EOFError)
PyAPI_DATA(PyTypeObject *) EOFError;
#define PyExc_FloatingPointError ((PyObject*)FloatingPointError)
PyAPI_DATA(PyTypeObject *) FloatingPointError;
#define PyExc_EnvironmentError ((PyObject*)EnvironmentError)
PyAPI_DATA(PyTypeObject *) EnvironmentError;
#define PyExc_IOError ((PyObject*)IOError)
PyAPI_DATA(PyTypeObject *) IOError;
#define PyExc_OSError ((PyObject*)OSError)
PyAPI_DATA(PyTypeObject *) OSError;
#define PyExc_ImportError ((PyObject*)ImportError)
PyAPI_DATA(PyTypeObject *) ImportError;
#define PyExc_IndexError ((PyObject*)IndexError)
PyAPI_DATA(PyTypeObject *) IndexError;
#define PyExc_KeyError ((PyObject*)KeyError)
PyAPI_DATA(PyTypeObject *) KeyError;
#define PyExc_KeyboardInterrupt ((PyObject*)KeyboardInterrupt)
PyAPI_DATA(PyTypeObject *) KeyboardInterrupt;
#define PyExc_MemoryError ((PyObject*)MemoryError)
PyAPI_DATA(PyTypeObject *) MemoryError;
#define PyExc_NameError ((PyObject*)NameError)
PyAPI_DATA(PyTypeObject *) NameError;
#define PyExc_OverflowError ((PyObject*)OverflowError)
PyAPI_DATA(PyTypeObject *) OverflowError;
#define PyExc_RuntimeError ((PyObject*)RuntimeError)
PyAPI_DATA(PyTypeObject *) RuntimeError;
#define PyExc_NotImplementedError ((PyObject*)NotImplementedError)
PyAPI_DATA(PyTypeObject *) NotImplementedError;
#define PyExc_SyntaxError ((PyObject*)SyntaxError)
PyAPI_DATA(PyTypeObject *) SyntaxError;
#define PyExc_IndentationError ((PyObject*)IndentationError)
PyAPI_DATA(PyTypeObject *) IndentationError;
#define PyExc_TabError ((PyObject*)TabError)
PyAPI_DATA(PyTypeObject *) TabError;
#define PyExc_ReferenceError ((PyObject*)ReferenceError)
PyAPI_DATA(PyTypeObject *) ReferenceError;
#define PyExc_SystemError ((PyObject*)SystemError)
PyAPI_DATA(PyTypeObject *) SystemError;
#define PyExc_SystemExit ((PyObject*)SystemExit)
PyAPI_DATA(PyTypeObject *) SystemExit;
#define PyExc_TypeError ((PyObject*)TypeError)
PyAPI_DATA(PyTypeObject *) TypeError;
#define PyExc_UnboundLocalError ((PyObject*)UnboundLocalError)
PyAPI_DATA(PyTypeObject *) UnboundLocalError;
#define PyExc_UnicodeError ((PyObject*)UnicodeError)
PyAPI_DATA(PyTypeObject *) UnicodeError;
#define PyExc_UnicodeEncodeError ((PyObject*)UnicodeEncodeError)
PyAPI_DATA(PyTypeObject *) UnicodeEncodeError;
#define PyExc_UnicodeDecodeError ((PyObject*)UnicodeDecodeError)
PyAPI_DATA(PyTypeObject *) UnicodeDecodeError;
#define PyExc_UnicodeTranslateError ((PyObject*)UnicodeTranslateError)
PyAPI_DATA(PyTypeObject *) UnicodeTranslateError;
#define PyExc_ValueError ((PyObject*)ValueError)
PyAPI_DATA(PyTypeObject *) ValueError;
#define PyExc_ZeroDivisionError ((PyObject*)ZeroDivisionError)
PyAPI_DATA(PyTypeObject *) ZeroDivisionError;
PyAPI_DATA(PyObject *) PyExc_BaseException;
PyAPI_DATA(PyObject *) PyExc_Exception;
PyAPI_DATA(PyObject *) PyExc_StopIteration;
PyAPI_DATA(PyObject *) PyExc_GeneratorExit;
PyAPI_DATA(PyObject *) PyExc_StandardError;
PyAPI_DATA(PyObject *) PyExc_ArithmeticError;
PyAPI_DATA(PyObject *) PyExc_LookupError;
PyAPI_DATA(PyObject *) PyExc_AssertionError;
PyAPI_DATA(PyObject *) PyExc_AttributeError;
PyAPI_DATA(PyObject *) PyExc_EOFError;
PyAPI_DATA(PyObject *) PyExc_FloatingPointError;
PyAPI_DATA(PyObject *) PyExc_EnvironmentError;
PyAPI_DATA(PyObject *) PyExc_IOError;
PyAPI_DATA(PyObject *) PyExc_OSError;
PyAPI_DATA(PyObject *) PyExc_ImportError;
PyAPI_DATA(PyObject *) PyExc_IndexError;
PyAPI_DATA(PyObject *) PyExc_KeyError;
PyAPI_DATA(PyObject *) PyExc_KeyboardInterrupt;
PyAPI_DATA(PyObject *) PyExc_MemoryError;
PyAPI_DATA(PyObject *) PyExc_NameError;
PyAPI_DATA(PyObject *) PyExc_OverflowError;
PyAPI_DATA(PyObject *) PyExc_RuntimeError;
PyAPI_DATA(PyObject *) PyExc_NotImplementedError;
PyAPI_DATA(PyObject *) PyExc_SyntaxError;
PyAPI_DATA(PyObject *) PyExc_IndentationError;
PyAPI_DATA(PyObject *) PyExc_TabError;
PyAPI_DATA(PyObject *) PyExc_ReferenceError;
PyAPI_DATA(PyObject *) PyExc_SystemError;
PyAPI_DATA(PyObject *) PyExc_SystemExit;
PyAPI_DATA(PyObject *) PyExc_TypeError;
PyAPI_DATA(PyObject *) PyExc_UnboundLocalError;
PyAPI_DATA(PyObject *) PyExc_UnicodeError;
PyAPI_DATA(PyObject *) PyExc_UnicodeEncodeError;
PyAPI_DATA(PyObject *) PyExc_UnicodeDecodeError;
PyAPI_DATA(PyObject *) PyExc_UnicodeTranslateError;
PyAPI_DATA(PyObject *) PyExc_ValueError;
PyAPI_DATA(PyObject *) PyExc_ZeroDivisionError;
#ifdef MS_WINDOWS
#define PyExc_WindowsError ((PyObject*)WindowsError)
PyAPI_DATA(PyTypeObject *) WindowsError;
PyAPI_DATA(PyObject *) PyExc_WindowsError;
#endif
#ifdef __VMS
#define PyExc_VMSError ((PyObject*)VMSError)
PyAPI_DATA(PyTypeObject *) VMSError;
PyAPI_DATA(PyObject *) PyExc_VMSError;
#endif
#define PyExc_BufferError ((PyObject*)BufferError)
PyAPI_DATA(PyTypeObject *) BufferError;
PyAPI_DATA(PyObject *) PyExc_BufferError;
PyAPI_DATA(PyObject *) PyExc_MemoryErrorInst;
PyAPI_DATA(PyObject *) PyExc_RecursionErrorInst;
/* Predefined warning categories */
#define PyExc_Warning ((PyObject*)Warning)
PyAPI_DATA(PyTypeObject *) Warning;
#define PyExc_UserWarning ((PyObject*)UserWarning)
PyAPI_DATA(PyTypeObject *) UserWarning;
#define PyExc_DeprecationWarning ((PyObject*)DeprecationWarning)
PyAPI_DATA(PyTypeObject *) DeprecationWarning;
#define PyExc_PendingDeprecationWarning ((PyObject*)PendingDeprecationWarning)
PyAPI_DATA(PyTypeObject *) PendingDeprecationWarning;
#define PyExc_SyntaxWarning ((PyObject*)SyntaxWarning)
PyAPI_DATA(PyTypeObject *) SyntaxWarning;
#define PyExc_RuntimeWarning ((PyObject*)RuntimeWarning)
PyAPI_DATA(PyTypeObject *) RuntimeWarning;
#define PyExc_FutureWarning ((PyObject*)FutureWarning)
PyAPI_DATA(PyTypeObject *) FutureWarning;
#define PyExc_ImportWarning ((PyObject*)ImportWarning)
PyAPI_DATA(PyTypeObject *) ImportWarning;
#define PyExc_UnicodeWarning ((PyObject*)UnicodeWarning)
PyAPI_DATA(PyTypeObject *) UnicodeWarning;
#define PyExc_BytesWarning ((PyObject*)BytesWarning)
PyAPI_DATA(PyTypeObject *) BytesWarning;
PyAPI_DATA(PyObject *) PyExc_Warning;
PyAPI_DATA(PyObject *) PyExc_UserWarning;
PyAPI_DATA(PyObject *) PyExc_DeprecationWarning;
PyAPI_DATA(PyObject *) PyExc_PendingDeprecationWarning;
PyAPI_DATA(PyObject *) PyExc_SyntaxWarning;
PyAPI_DATA(PyObject *) PyExc_RuntimeWarning;
PyAPI_DATA(PyObject *) PyExc_FutureWarning;
PyAPI_DATA(PyObject *) PyExc_ImportWarning;
PyAPI_DATA(PyObject *) PyExc_UnicodeWarning;
PyAPI_DATA(PyObject *) PyExc_BytesWarning;
/* Convenience functions */
......
This diff is collapsed.
// This file is originally from CPython 2.7, with modifications for Pyston
/* Implements the unicode (as opposed to string) version of the
built-in formatter for unicode. That is, unicode.__format__(). */
#include "Python.h"
#ifdef Py_USING_UNICODE
#include "../Objects/stringlib/unicodedefs.h"
#define FORMAT_STRING _PyUnicode_FormatAdvanced
/* don't define FORMAT_LONG, FORMAT_FLOAT, and FORMAT_COMPLEX, since
we can live with only the string versions of those. The builtin
format() will convert them to unicode. */
#include "../Objects/stringlib/formatter.h"
#endif
......@@ -188,7 +188,73 @@ extern "C" void PyErr_WriteUnraisable(PyObject* obj) noexcept {
static int parse_syntax_error(PyObject* err, PyObject** message, const char** filename, int* lineno, int* offset,
const char** text) noexcept {
Py_FatalError("unimplemented");
long hold;
PyObject* v;
/* old style errors */
if (PyTuple_Check(err))
return PyArg_ParseTuple(err, "O(ziiz)", message, filename, lineno, offset, text);
*message = NULL;
/* new style errors. `err' is an instance */
*message = PyObject_GetAttrString(err, "msg");
if (!*message)
goto finally;
v = PyObject_GetAttrString(err, "filename");
if (!v)
goto finally;
if (v == Py_None) {
Py_DECREF(v);
*filename = NULL;
} else {
*filename = PyString_AsString(v);
Py_DECREF(v);
if (!*filename)
goto finally;
}
v = PyObject_GetAttrString(err, "lineno");
if (!v)
goto finally;
hold = PyInt_AsLong(v);
Py_DECREF(v);
if (hold < 0 && PyErr_Occurred())
goto finally;
*lineno = (int)hold;
v = PyObject_GetAttrString(err, "offset");
if (!v)
goto finally;
if (v == Py_None) {
*offset = -1;
Py_DECREF(v);
} else {
hold = PyInt_AsLong(v);
Py_DECREF(v);
if (hold < 0 && PyErr_Occurred())
goto finally;
*offset = (int)hold;
}
v = PyObject_GetAttrString(err, "text");
if (!v)
goto finally;
if (v == Py_None) {
Py_DECREF(v);
*text = NULL;
} else {
*text = PyString_AsString(v);
Py_DECREF(v);
if (!*text)
goto finally;
}
return 1;
finally:
Py_XDECREF(*message);
return 0;
}
static void print_error_text(PyObject* f, int offset, const char* text) noexcept {
......
......@@ -72,6 +72,10 @@ extern "C" int PyObject_GenericSetAttr(PyObject* obj, PyObject* name, PyObject*
Py_FatalError("unimplemented");
}
extern "C" int PyObject_SetAttr(PyObject* v, PyObject* name, PyObject* value) noexcept {
Py_FatalError("unimplemented");
}
extern "C" PyObject* PyObject_GetAttrString(PyObject* o, const char* attr) noexcept {
// TODO do something like this? not sure if this is safe; will people expect that calling into a known function
// won't end up doing a GIL check?
......
......@@ -1784,6 +1784,10 @@ void PystonType_Ready(BoxedClass* cls) {
}
}
extern "C" void PyType_Modified(PyTypeObject* type) noexcept {
// We don't cache anything yet that would need to be invalidated:
}
extern "C" int PyType_Ready(PyTypeObject* cls) noexcept {
gc::registerNonheapRootObject(cls);
......
......@@ -522,8 +522,6 @@ void appendToSysPath(const std::string& path);
void prependToSysPath(const std::string& path);
void addToSysArgv(const char* str);
std::string formatException(Box* e);
// Raise a SyntaxError that occurs at a specific location.
// The traceback given to the user will include this,
// even though the execution didn't actually arrive there.
......
......@@ -589,19 +589,6 @@ Box* eval(Box* code) {
BoxedClass* notimplemented_cls;
BoxedModule* builtins_module;
// TODO looks like CPython and pypy put this into an "exceptions" module:
extern "C" {
BoxedClass* BaseException, *Exception, *StandardError, *AssertionError, *AttributeError, *GeneratorExit, *TypeError,
*NameError, *KeyError, *IndexError, *IOError, *OSError, *ZeroDivisionError, *ValueError, *UnboundLocalError,
*RuntimeError, *ImportError, *StopIteration, *Warning, *SyntaxError, *OverflowError, *DeprecationWarning,
*MemoryError, *LookupError, *EnvironmentError, *ArithmeticError, *BufferError, *KeyboardInterrupt, *SystemExit,
*SystemError, *NotImplementedError, *PendingDeprecationWarning, *EOFError, *UnicodeError, *UnicodeEncodeError,
*UnicodeDecodeError, *UnicodeTranslateError;
Box* PyExc_RecursionErrorInst;
Box* PyExc_MemoryErrorInst;
}
class BoxedException : public Box {
public:
HCAttrs attrs;
......@@ -879,123 +866,6 @@ Box* pydumpAddr(Box* p) {
return None;
}
class BoxedEnvironmentError : public BoxedException {
public:
// Box* args, *message, *myerrno, *strerror, *filename;
Box* myerrno, *strerror, *filename;
static Box* __init__(BoxedEnvironmentError* self, Box* errno_, Box* strerror, Box** _args) {
Box* filename = _args[0];
RELEASE_ASSERT(isSubclass(self->cls, EnvironmentError), "");
self->myerrno = errno_;
self->strerror = strerror;
self->filename = filename;
return None;
}
static Box* __reduce__(Box* self) { Py_FatalError("unimplemented"); }
static PyObject* __str__(BoxedEnvironmentError* self) noexcept {
PyObject* rtnval = NULL;
if (self->filename) {
PyObject* fmt;
PyObject* repr;
PyObject* tuple;
fmt = PyString_FromString("[Errno %s] %s: %s");
if (!fmt)
return NULL;
repr = PyObject_Repr(self->filename);
if (!repr) {
Py_DECREF(fmt);
return NULL;
}
tuple = PyTuple_New(3);
if (!tuple) {
Py_DECREF(repr);
Py_DECREF(fmt);
return NULL;
}
if (self->myerrno) {
Py_INCREF(self->myerrno);
PyTuple_SET_ITEM(tuple, 0, self->myerrno);
} else {
Py_INCREF(Py_None);
PyTuple_SET_ITEM(tuple, 0, Py_None);
}
if (self->strerror) {
Py_INCREF(self->strerror);
PyTuple_SET_ITEM(tuple, 1, self->strerror);
} else {
Py_INCREF(Py_None);
PyTuple_SET_ITEM(tuple, 1, Py_None);
}
PyTuple_SET_ITEM(tuple, 2, repr);
rtnval = PyString_Format(fmt, tuple);
Py_DECREF(fmt);
Py_DECREF(tuple);
} else if (self->myerrno && self->strerror) {
PyObject* fmt;
PyObject* tuple;
fmt = PyString_FromString("[Errno %s] %s");
if (!fmt)
return NULL;
tuple = PyTuple_New(2);
if (!tuple) {
Py_DECREF(fmt);
return NULL;
}
if (self->myerrno) {
Py_INCREF(self->myerrno);
PyTuple_SET_ITEM(tuple, 0, self->myerrno);
} else {
Py_INCREF(Py_None);
PyTuple_SET_ITEM(tuple, 0, Py_None);
}
if (self->strerror) {
Py_INCREF(self->strerror);
PyTuple_SET_ITEM(tuple, 1, self->strerror);
} else {
Py_INCREF(Py_None);
PyTuple_SET_ITEM(tuple, 1, Py_None);
}
rtnval = PyString_Format(fmt, tuple);
Py_DECREF(fmt);
Py_DECREF(tuple);
} else
rtnval = exceptionStr(self);
return rtnval;
}
static void gcHandler(GCVisitor* v, Box* _b) {
assert(isSubclass(_b->cls, EnvironmentError));
boxGCHandler(v, _b);
BoxedEnvironmentError* ee = static_cast<BoxedEnvironmentError*>(_b);
if (ee->myerrno)
v->visit(ee->myerrno);
if (ee->strerror)
v->visit(ee->strerror);
if (ee->filename)
v->visit(ee->filename);
}
};
void setupBuiltins() {
builtins_module = createModule("__builtin__", "__builtin__");
......@@ -1018,67 +888,6 @@ void setupBuiltins() {
builtins_module->giveAttr("all", new BoxedBuiltinFunctionOrMethod(boxRTFunction((void*)all, BOXED_BOOL, 1), "all"));
builtins_module->giveAttr("any", new BoxedBuiltinFunctionOrMethod(boxRTFunction((void*)any, BOXED_BOOL, 1), "any"));
BaseException = makeBuiltinException(object_cls, "BaseException", sizeof(BoxedException));
Exception = makeBuiltinException(BaseException, "Exception");
StandardError = makeBuiltinException(Exception, "StandardError");
AssertionError = makeBuiltinException(StandardError, "AssertionError");
AttributeError = makeBuiltinException(StandardError, "AttributeError");
GeneratorExit = makeBuiltinException(BaseException, "GeneratorExit");
TypeError = makeBuiltinException(StandardError, "TypeError");
NameError = makeBuiltinException(StandardError, "NameError");
LookupError = makeBuiltinException(StandardError, "LookupError");
KeyError = makeBuiltinException(LookupError, "KeyError");
IndexError = makeBuiltinException(LookupError, "IndexError");
EnvironmentError = makeBuiltinException(StandardError, "EnvironmentError", sizeof(BoxedEnvironmentError));
IOError = makeBuiltinException(EnvironmentError, "IOError");
OSError = makeBuiltinException(EnvironmentError, "OSError");
ArithmeticError = makeBuiltinException(StandardError, "ArithmeticError");
ZeroDivisionError = makeBuiltinException(ArithmeticError, "ZeroDivisionError");
ValueError = makeBuiltinException(StandardError, "ValueError");
UnboundLocalError = makeBuiltinException(NameError, "UnboundLocalError");
RuntimeError = makeBuiltinException(StandardError, "RuntimeError");
ImportError = makeBuiltinException(StandardError, "ImportError");
StopIteration = makeBuiltinException(Exception, "StopIteration");
Warning = makeBuiltinException(Exception, "Warning");
SyntaxError = makeBuiltinException(StandardError, "SyntaxError");
OverflowError = makeBuiltinException(ArithmeticError, "OverflowError");
/*ImportWarning =*/makeBuiltinException(Warning, "ImportWarning");
DeprecationWarning = makeBuiltinException(Warning, "DeprecationWarning");
/*BytesWarning =*/makeBuiltinException(Warning, "BytesWarning");
MemoryError = makeBuiltinException(StandardError, "MemoryError");
BufferError = makeBuiltinException(StandardError, "BufferError");
KeyboardInterrupt = makeBuiltinException(BaseException, "KeyboardInterrupt");
SystemExit = makeBuiltinException(BaseException, "SystemExit");
SystemError = makeBuiltinException(StandardError, "SystemError");
NotImplementedError = makeBuiltinException(RuntimeError, "NotImplementedError");
PendingDeprecationWarning = makeBuiltinException(Warning, "PendingDeprecationWarning");
EOFError = makeBuiltinException(StandardError, "EOFError");
// Unicode errors
UnicodeError = makeBuiltinException(ValueError, "UnicodeError");
UnicodeEncodeError = makeBuiltinException(UnicodeError, "UnicodeEncodeError");
UnicodeDecodeError = makeBuiltinException(UnicodeError, "UnicodeDecodeError");
UnicodeTranslateError = makeBuiltinException(UnicodeError, "UnicodeTranslateError");
BaseException->giveAttr("__reduce__",
new BoxedFunction(boxRTFunction((void*)BoxedException::__reduce__, UNKNOWN, 1)));
EnvironmentError->giveAttr("__reduce__",
new BoxedFunction(boxRTFunction((void*)BoxedEnvironmentError::__reduce__, UNKNOWN, 1)));
EnvironmentError->gc_visit = BoxedEnvironmentError::gcHandler;
EnvironmentError->giveAttr(
"__init__", new BoxedFunction(boxRTFunction((void*)BoxedEnvironmentError::__init__, NONE, 4, 3, false, false),
{ NULL, NULL, NULL }));
EnvironmentError->giveAttr(
"errno", new BoxedMemberDescriptor(BoxedMemberDescriptor::OBJECT, offsetof(BoxedEnvironmentError, myerrno)));
EnvironmentError->giveAttr("strerror", new BoxedMemberDescriptor(BoxedMemberDescriptor::OBJECT,
offsetof(BoxedEnvironmentError, strerror)));
EnvironmentError->giveAttr("filename", new BoxedMemberDescriptor(BoxedMemberDescriptor::OBJECT,
offsetof(BoxedEnvironmentError, filename)));
EnvironmentError->giveAttr("__str__",
new BoxedFunction(boxRTFunction((void*)BoxedEnvironmentError::__str__, UNKNOWN, 1)));
repr_obj = new BoxedBuiltinFunctionOrMethod(boxRTFunction((void*)repr, UNKNOWN, 1), "repr");
builtins_module->giveAttr("repr", repr_obj);
......@@ -1228,10 +1037,5 @@ void setupBuiltins() {
builtins_module->giveAttr("classmethod", classmethod_cls);
builtins_module->giveAttr(
"eval", new BoxedBuiltinFunctionOrMethod(boxRTFunction((void*)eval, UNKNOWN, 1, 0, false, false), "eval"));
PyExc_RecursionErrorInst = new (RuntimeError) BoxedException();
gc::registerPermanentRoot(PyExc_RecursionErrorInst);
PyExc_MemoryErrorInst = new (MemoryError) BoxedException();
gc::registerPermanentRoot(PyExc_MemoryErrorInst);
}
}
......@@ -673,21 +673,24 @@ void checkAndThrowCAPIException() {
if (!tb)
tb = None;
// Make sure to call PyErr_Clear() *before* normalizing the exception, since otherwise
// the normalization can think that it had raised an exception, resulting to a call
// to checkAndThrowCAPIException, and boom.
PyErr_Clear();
// This is similar to PyErr_NormalizeException:
if (!isInstance(value, type)) {
if (value->cls == tuple_cls) {
value = runtimeCall(cur_thread_state.curexc_type, ArgPassSpec(0, 0, true, false), value, NULL, NULL,
NULL, NULL);
value = runtimeCall(type, ArgPassSpec(0, 0, true, false), value, NULL, NULL, NULL, NULL);
} else if (value == None) {
value = runtimeCall(cur_thread_state.curexc_type, ArgPassSpec(0), NULL, NULL, NULL, NULL, NULL);
value = runtimeCall(type, ArgPassSpec(0), NULL, NULL, NULL, NULL, NULL);
} else {
value = runtimeCall(cur_thread_state.curexc_type, ArgPassSpec(1), value, NULL, NULL, NULL, NULL);
value = runtimeCall(type, ArgPassSpec(1), value, NULL, NULL, NULL, NULL);
}
}
RELEASE_ASSERT(value->cls == type, "unsupported");
PyErr_Clear();
if (tb != None)
raiseRaw(ExcInfo(value->cls, value, tb));
raiseExc(value);
......@@ -856,6 +859,11 @@ extern "C" PyObject* PyErr_Occurred() noexcept {
}
extern "C" int PyErr_WarnEx(PyObject* category, const char* text, Py_ssize_t stacklevel) noexcept {
// These warnings are silenced by default:
// We should copy the real CPython code in here
if (category == PyExc_DeprecationWarning)
return 0;
Py_FatalError("unimplemented");
}
......
......@@ -174,12 +174,7 @@ Box* dictGetitem(BoxedDict* self, Box* k) {
auto it = self->d.find(k);
if (it == self->d.end()) {
BoxedString* s = reprOrNull(k);
if (s)
raiseExcHelper(KeyError, "%s", s->s.c_str());
else
raiseExcHelper(KeyError, "");
raiseExcHelper(KeyError, k);
}
Box* pos = self->d[k];
......@@ -306,12 +301,7 @@ Box* dictDelitem(BoxedDict* self, Box* k) {
auto it = self->d.find(k);
if (it == self->d.end()) {
BoxedString* s = reprOrNull(k);
if (s)
raiseExcHelper(KeyError, "%s", s->s.c_str());
else
raiseExcHelper(KeyError, "");
raiseExcHelper(KeyError, k);
}
self->d.erase(it);
......@@ -329,6 +319,18 @@ extern "C" int PyDict_DelItem(PyObject* op, PyObject* key) noexcept {
return 0;
}
extern "C" int PyDict_DelItemString(PyObject* v, const char* key) noexcept {
PyObject* kv;
int err;
kv = PyString_FromString(key);
if (kv == NULL)
return -1;
err = PyDict_DelItem(v, kv);
Py_DECREF(kv);
return err;
}
Box* dictPop(BoxedDict* self, Box* k, Box* d) {
if (!isSubclass(self->cls, dict_cls))
raiseExcHelper(TypeError, "descriptor 'pop' requires a 'dict' object but received a '%s'", getTypeName(self));
......@@ -338,12 +340,7 @@ Box* dictPop(BoxedDict* self, Box* k, Box* d) {
if (d)
return d;
BoxedString* s = reprOrNull(k);
if (s)
raiseExcHelper(KeyError, "%s", s->s.c_str());
else
raiseExcHelper(KeyError, "");
raiseExcHelper(KeyError, k);
}
Box* rtn = it->second;
......
......@@ -261,6 +261,13 @@ static void ensure_fromlist(Box* module, Box* fromlist, const std::string& modul
}
}
extern "C" PyObject* PyImport_ImportModule(const char* name) noexcept {
if (strcmp("__builtin__", name) == 0)
return builtins_module;
Py_FatalError("unimplemented");
}
extern "C" Box* import(int level, Box* from_imports, const std::string* module_name) {
RELEASE_ASSERT(level == -1 || level == 0, "not implemented");
......
......@@ -45,7 +45,8 @@ extern "C" long PyInt_AsLong(PyObject* op) noexcept {
if (op->cls == long_cls)
return PyLong_AsLong(op);
Py_FatalError("unimplemented");
PyErr_SetString(PyExc_TypeError, "an integer is required");
return -1;
}
extern "C" Py_ssize_t PyInt_AsSsize_t(PyObject* op) noexcept {
......
......@@ -208,7 +208,7 @@ extern "C" void assertFail(BoxedModule* inModule, Box* msg) {
BoxedString* tostr = str(msg);
raiseExcHelper(AssertionError, "%s", tostr->s.c_str());
} else {
raiseExcHelper(AssertionError, NULL);
raiseExcHelper(AssertionError, "");
}
}
......
......@@ -41,6 +41,7 @@ extern "C" Box* deopt(AST_expr* expr, Box* value);
// helper function for raising from the runtime:
void raiseExcHelper(BoxedClass*, const char* fmt, ...) __attribute__((__noreturn__));
void raiseExcHelper(BoxedClass*, Box* arg) __attribute__((__noreturn__));
BoxedModule* getCurrentModule();
......
......@@ -200,12 +200,7 @@ Box* setRemove(BoxedSet* self, Box* v) {
auto it = self->s.find(v);
if (it == self->s.end()) {
BoxedString* s = reprOrNull(v);
if (s)
raiseExcHelper(KeyError, "%s", s->s.c_str());
else
raiseExcHelper(KeyError, "");
raiseExcHelper(KeyError, v);
}
self->s.erase(it);
......
......@@ -196,9 +196,7 @@ ExcInfo::ExcInfo(Box* type, Box* value, Box* traceback) : type(type), value(valu
#endif
void ExcInfo::printExcAndTraceback() const {
std::string msg = formatException(value);
printTraceback(traceback);
fprintf(stderr, "%s\n", msg.c_str());
PyErr_Display(type, value, traceback);
}
bool ExcInfo::matches(BoxedClass* cls) const {
......@@ -242,6 +240,11 @@ void raise3(Box* arg0, Box* arg1, Box* arg2) {
getTypeName(arg0));
}
void raiseExcHelper(BoxedClass* cls, Box* arg) {
Box* exc_obj = runtimeCall(cls, ArgPassSpec(1), arg, NULL, NULL, NULL, NULL);
raiseExc(exc_obj);
}
void raiseExcHelper(BoxedClass* cls, const char* msg, ...) {
if (msg != NULL) {
va_list ap;
......@@ -265,18 +268,4 @@ void raiseExcHelper(BoxedClass* cls, const char* msg, ...) {
raiseExc(exc_obj);
}
}
std::string formatException(Box* b) {
std::string name = getTypeName(b);
BoxedString* r = strOrNull(b);
if (!r)
return name;
assert(r->cls == str_cls);
const std::string* msg = &r->s;
if (msg->size())
return name + ": " + *msg;
return name;
}
}
......@@ -559,7 +559,7 @@ extern "C" Box* createUserClass(const std::string* name, Box* _bases, Box* _attr
RELEASE_ASSERT(e.matches(BaseException), "");
Box* msg = e.value->getattr("message");
Box* msg = getattr(e.value, "message");
RELEASE_ASSERT(msg, "");
RELEASE_ASSERT(msg->cls == str_cls, "");
......@@ -834,6 +834,40 @@ Box* typeRepr(BoxedClass* self) {
return boxString(os.str());
}
static PyObject* typeModule(Box* _type, void* context) {
PyTypeObject* type = static_cast<PyTypeObject*>(_type);
PyObject* mod;
const char* s;
if (type->tp_flags & Py_TPFLAGS_HEAPTYPE) {
mod = type->getattr("__module__");
if (!mod)
raiseExcHelper(AttributeError, "__module__");
return mod;
} else {
s = strrchr(type->tp_name, '.');
if (s != NULL)
return PyString_FromStringAndSize(type->tp_name, (Py_ssize_t)(s - type->tp_name));
return PyString_FromString("__builtin__");
}
}
static void typeSetModule(Box* _type, PyObject* value, void* context) {
PyTypeObject* type = static_cast<PyTypeObject*>(_type);
if (!(type->tp_flags & Py_TPFLAGS_HEAPTYPE)) {
raiseExcHelper(TypeError, "can't set %s.__module__", type->tp_name);
}
if (!value) {
raiseExcHelper(TypeError, "can't delete %s.__module__", type->tp_name);
}
PyType_Modified(type);
type->setattr("__module__", value, NULL);
}
Box* typeHash(BoxedClass* self) {
assert(isSubclass(self->cls, type_cls));
......@@ -1272,6 +1306,7 @@ void setupRuntime() {
new BoxedFunction(boxRTFunction((void*)typeNew, UNKNOWN, 4, 2, false, false), { NULL, NULL }));
type_cls->giveAttr("__repr__", new BoxedFunction(boxRTFunction((void*)typeRepr, STR, 1)));
type_cls->giveAttr("__hash__", new BoxedFunction(boxRTFunction((void*)typeHash, BOXED_INT, 1)));
type_cls->giveAttr("__module__", new (pyston_getset_cls) BoxedGetsetDescriptor(typeModule, typeSetModule, NULL));
type_cls->freeze();
none_cls->giveAttr("__repr__", new BoxedFunction(boxRTFunction((void*)noneRepr, STR, 1)));
......@@ -1365,6 +1400,7 @@ void setupRuntime() {
setupSys();
setupBuiltins();
_PyExc_Init();
setupThread();
setupGC();
setupImport();
......
......@@ -613,12 +613,29 @@ extern "C" void boxGCHandler(GCVisitor* v, Box* b);
Box* objectNewNoArgs(BoxedClass* cls);
extern "C" BoxedClass* Exception, *AssertionError, *AttributeError, *TypeError, *NameError, *KeyError, *IndexError,
*IOError, *OSError, *ZeroDivisionError, *ValueError, *UnboundLocalError, *RuntimeError, *ImportError,
*StopIteration, *GeneratorExit, *SyntaxError;
Box* makeAttrWrapper(Box* b);
#define SystemError ((BoxedClass*)PyExc_SystemError)
#define StopIteration ((BoxedClass*)PyExc_StopIteration)
#define NameError ((BoxedClass*)PyExc_NameError)
#define UnboundLocalError ((BoxedClass*)PyExc_UnboundLocalError)
#define BaseException ((BoxedClass*)PyExc_BaseException)
#define TypeError ((BoxedClass*)PyExc_TypeError)
#define AssertionError ((BoxedClass*)PyExc_AssertionError)
#define ValueError ((BoxedClass*)PyExc_ValueError)
#define SystemExit ((BoxedClass*)PyExc_SystemExit)
#define SyntaxError ((BoxedClass*)PyExc_SyntaxError)
#define Exception ((BoxedClass*)PyExc_Exception)
#define AttributeError ((BoxedClass*)PyExc_AttributeError)
#define RuntimeError ((BoxedClass*)PyExc_RuntimeError)
#define ZeroDivisionError ((BoxedClass*)PyExc_ZeroDivisionError)
#define ImportError ((BoxedClass*)PyExc_ImportError)
#define IndexError ((BoxedClass*)PyExc_IndexError)
#define GeneratorExit ((BoxedClass*)PyExc_GeneratorExit)
#define IOError ((BoxedClass*)PyExc_IOError)
#define KeyError ((BoxedClass*)PyExc_KeyError)
#define OverflowError ((BoxedClass*)PyExc_OverflowError)
// Our default for tp_alloc:
PyObject* PystonType_GenericAlloc(BoxedClass* cls, Py_ssize_t nitems) noexcept;
}
......
......@@ -373,34 +373,6 @@ extern "C" Py_UNICODE _PyUnicode_ToUppercase(Py_UNICODE ch) noexcept {
Py_FatalError("unimplemented");
}
extern "C" int PyUnicodeEncodeError_GetStart(PyObject*, Py_ssize_t*) noexcept {
Py_FatalError("unimplemented");
}
extern "C" int PyUnicodeDecodeError_GetStart(PyObject*, Py_ssize_t*) noexcept {
Py_FatalError("unimplemented");
}
extern "C" int PyUnicodeTranslateError_GetStart(PyObject*, Py_ssize_t*) noexcept {
Py_FatalError("unimplemented");
}
extern "C" int PyUnicodeEncodeError_GetEnd(PyObject*, Py_ssize_t*) noexcept {
Py_FatalError("unimplemented");
}
extern "C" int PyUnicodeDecodeError_GetEnd(PyObject*, Py_ssize_t*) noexcept {
Py_FatalError("unimplemented");
}
extern "C" int PyUnicodeTranslateError_GetEnd(PyObject*, Py_ssize_t*) noexcept {
Py_FatalError("unimplemented");
}
extern "C" PyObject* PyUnicodeEncodeError_GetObject(PyObject*) noexcept {
Py_FatalError("unimplemented");
}
extern "C" PyObject* _PyUnicode_DecodeUnicodeInternal(const char* s, Py_ssize_t size, const char* errors) noexcept {
Py_FatalError("unimplemented");
}
......
# expected: fail
# - exception printing
class BadException(Exception):
def __str__(self):
print "str"
......
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