Commit fe1ee643 authored by Kevin Modzelewski's avatar Kevin Modzelewski

Enable init_sre and importing of the _sre module

fixed a number of small things to get it to work.

Also, updated most of the abort()-ing functions to print out a
Python-level stacktrace before actually calling abort() --
hopefully that won't cause any issues.
parent 79dc30d1
......@@ -34,7 +34,7 @@ PyAPI_DATA(int) Py_HashRandomizationFlag;
PYTHONPATH and PYTHONHOME from the environment */
#define Py_GETENV(s) (Py_IgnoreEnvironmentFlag ? NULL : getenv(s))
PyAPI_FUNC(void) Py_FatalError(const char *message);
PyAPI_FUNC(void) Py_FatalError(const char *message) __attribute__((__noreturn__));
#ifdef __cplusplus
}
......
......@@ -67,9 +67,9 @@ inline bool Register::isCalleeSave() {
struct Indirect {
public:
const Register base;
const int offset;
const int64_t offset;
Indirect(const Register base, int offset) : base(base), offset(offset) {}
Indirect(const Register base, int64_t offset) : base(base), offset(offset) {}
};
struct XMMRegister {
......
......@@ -59,8 +59,26 @@ static int vgetargs1(PyObject* _tuple, const char* fmt, va_list* ap, int flags)
}
PyObject* arg = tuple->elts[arg_idx];
arg_idx++;
switch (c) {
case 'i': { // signed int
int* p = (int*)va_arg(*ap, int*);
RELEASE_ASSERT(arg->cls == int_cls, "%s", getTypeName(arg)->c_str());
int64_t n = static_cast<BoxedInt*>(arg)->n;
RELEASE_ASSERT(n >= INT_MIN, "");
RELEASE_ASSERT(n <= INT_MAX, "");
*p = n;
break;
}
case 'n': { // ssize_t
Py_ssize_t* p = (Py_ssize_t*)va_arg(*ap, Py_ssize_t*);
// could also be a long:
RELEASE_ASSERT(arg->cls == int_cls, "%s", getTypeName(arg)->c_str());
int64_t n = static_cast<BoxedInt*>(arg)->n;
*p = n;
break;
}
case 's': {
if (*fmt == '*') {
Py_buffer* p = (Py_buffer*)va_arg(*ap, Py_buffer*);
......@@ -76,8 +94,25 @@ static int vgetargs1(PyObject* _tuple, const char* fmt, va_list* ap, int flags)
break;
}
case 'O': {
PyObject** p = (PyObject**)va_arg(*ap, PyObject**);
*p = arg;
if (fmt && *fmt == '!') {
fmt++;
PyObject* _cls = (PyObject*)va_arg(*ap, PyObject*);
PyObject** p = (PyObject**)va_arg(*ap, PyObject**);
RELEASE_ASSERT(_cls->cls == type_cls, "%s", getTypeName(_cls)->c_str());
PyTypeObject* cls = static_cast<PyTypeObject*>(_cls);
if (!isSubclass(arg->cls, cls)) {
// should raise a TypeError
abort();
}
*p = arg;
} else {
PyObject** p = (PyObject**)va_arg(*ap, PyObject**);
*p = arg;
}
break;
}
default:
......
......@@ -55,7 +55,7 @@ extern "C" PyObject* Py_InitModule4(const char* name, PyMethodDef* methods, cons
if (VERBOSITY())
printf("Loading method %s\n", methods->ml_name);
assert((methods->ml_flags & (~(METH_VARARGS | METH_KEYWORDS))) == 0);
assert((methods->ml_flags & (~(METH_VARARGS | METH_KEYWORDS | METH_NOARGS))) == 0);
module->giveAttr(methods->ml_name,
new BoxedCApiFunction(methods->ml_flags, passthrough, methods->ml_name, methods->ml_meth));
......
......@@ -49,6 +49,10 @@ public:
rtn = (Box*)self->func(self->passthrough, varargs);
} else if (self->ml_flags == (METH_VARARGS | METH_KEYWORDS)) {
rtn = (Box*)((PyCFunctionWithKeywords)self->func)(self->passthrough, varargs, kwargs);
} else if (self->ml_flags == METH_NOARGS) {
assert(kwargs->d.size() == 0);
assert(varargs->elts.size() == 0);
rtn = (Box*)self->func(self->passthrough, NULL);
} else {
RELEASE_ASSERT(0, "0x%x", self->ml_flags);
}
......
......@@ -47,12 +47,18 @@
#define NOINLINE
#endif
// From http://stackoverflow.com/questions/3767869/adding-message-to-assert, modified to use fprintf
namespace pyston {
void _printStacktrace();
}
// From http://stackoverflow.com/questions/3767869/adding-message-to-assert, modified to use fprintf and give a Python
// stacktrace
#define RELEASE_ASSERT(condition, fmt, ...) \
do { \
if (!(condition)) { \
fprintf(stderr, __FILE__ ":" STRINGIFY(__LINE__) ": %s: Assertion `" #condition "' failed: " fmt "\n", \
__PRETTY_FUNCTION__, ##__VA_ARGS__); \
pyston::_printStacktrace(); \
abort(); \
} \
} while (false)
......
......@@ -124,7 +124,7 @@ extern "C" int PyDict_SetItem(PyObject* mp, PyObject* _key, PyObject* _item) {
r = callattrInternal(b, &setitem_str, CLASS_ONLY, NULL, ArgPassSpec(2), key, item, NULL, NULL, NULL);
} catch (Box* b) {
fprintf(stderr, "Error: uncaught error would be propagated to C code!\n");
abort();
Py_FatalError("unimplemented");
}
RELEASE_ASSERT(r, "");
......@@ -164,7 +164,6 @@ extern "C" int PyType_Ready(PyTypeObject* cls) {
RELEASE_ASSERT(cls->tp_traverse == NULL, "");
RELEASE_ASSERT(cls->tp_clear == NULL, "");
RELEASE_ASSERT(cls->tp_richcompare == NULL, "");
RELEASE_ASSERT(cls->tp_weaklistoffset == 0, "");
RELEASE_ASSERT(cls->tp_iter == NULL, "");
RELEASE_ASSERT(cls->tp_iternext == NULL, "");
RELEASE_ASSERT(cls->tp_base == NULL, "");
......@@ -184,11 +183,18 @@ extern "C" int PyType_Ready(PyTypeObject* cls) {
RELEASE_ASSERT(cls->tp_del == NULL, "");
RELEASE_ASSERT(cls->tp_version_tag == 0, "");
// I think it is safe to ignore tp_weaklistoffset for now:
// RELEASE_ASSERT(cls->tp_weaklistoffset == 0, "");
#define INITIALIZE(a) new (&(a)) decltype(a)
INITIALIZE(cls->attrs);
INITIALIZE(cls->dependent_icgetattrs);
#undef INITIALIZE
cls->base = object_cls;
if (!cls->cls)
cls->cls = cls->base->cls;
assert(cls->tp_name);
cls->giveAttr("__name__", boxStrConstant(cls->tp_name));
// tp_name
......@@ -209,8 +215,6 @@ extern "C" int PyType_Ready(PyTypeObject* cls) {
printf("warning: ignoring tp_getset for now\n");
}
cls->base = object_cls;
cls->gc_visit = &conservativeGCHandler;
// TODO not sure how we can handle extension types that manually
......@@ -270,13 +274,16 @@ extern "C" void PyBuffer_Release(Py_buffer* view) {
view->obj = NULL;
}
// Not sure why we need another declaration here:
extern "C" void Py_FatalError(const char* msg) __attribute__((__noreturn__));
extern "C" void Py_FatalError(const char* msg) {
fprintf(stderr, "%s", msg);
fprintf(stderr, "Fatal Python error: %s\n", msg);
_printStacktrace();
abort();
}
extern "C" void _PyErr_BadInternalCall(const char* filename, int lineno) {
abort();
Py_FatalError("unimplemented");
}
extern "C" PyObject* PyObject_Init(PyObject* op, PyTypeObject* tp) {
......@@ -287,7 +294,7 @@ extern "C" PyObject* PyObject_Init(PyObject* op, PyTypeObject* tp) {
}
extern "C" PyVarObject* PyObject_InitVar(PyVarObject* op, PyTypeObject* tp, Py_ssize_t size) {
abort(); // "var" objects not tested yet
Py_FatalError("'var' objects not tested yet");
RELEASE_ASSERT(op, "");
RELEASE_ASSERT(tp, "");
......@@ -320,16 +327,16 @@ extern "C" PyObject* PyObject_CallObject(PyObject* obj, PyObject* args) {
Box* r = runtimeCall(obj, ArgPassSpec(0, 0, true, false), args, NULL, NULL, NULL, NULL);
return r;
} catch (Box* b) {
abort();
Py_FatalError("unimplemented");
}
}
extern "C" PyObject* PyObject_CallMethod(PyObject* o, char* name, char* format, ...) {
abort();
Py_FatalError("unimplemented");
}
extern "C" PyObject* _PyObject_CallMethod_SizeT(PyObject* o, char* name, char* format, ...) {
abort();
Py_FatalError("unimplemented");
}
extern "C" PyObject* PyObject_GetAttrString(PyObject* o, const char* attr) {
......@@ -340,7 +347,7 @@ extern "C" PyObject* PyObject_GetAttrString(PyObject* o, const char* attr) {
try {
return getattr(o, attr);
} catch (Box* b) {
abort();
Py_FatalError("unimplemented");
}
}
......@@ -348,7 +355,7 @@ extern "C" Py_ssize_t PyObject_Size(PyObject* o) {
try {
return len(o)->n;
} catch (Box* b) {
abort();
Py_FatalError("unimplemented");
}
}
......@@ -356,12 +363,12 @@ extern "C" PyObject* PyObject_GetItem(PyObject* o, PyObject* key) {
try {
return getitem(o, key);
} catch (Box* b) {
abort();
Py_FatalError("unimplemented");
}
}
extern "C" void PyObject_ClearWeakRefs(PyObject* object) {
abort();
Py_FatalError("unimplemented");
}
......@@ -370,7 +377,7 @@ extern "C" PyObject* PySequence_GetItem(PyObject* o, Py_ssize_t i) {
// Not sure if this is really the same:
return getitem(o, boxInt(i));
} catch (Box* b) {
abort();
Py_FatalError("unimplemented");
}
}
......@@ -379,7 +386,7 @@ extern "C" PyObject* PySequence_GetSlice(PyObject* o, Py_ssize_t i1, Py_ssize_t
// Not sure if this is really the same:
return getitem(o, new BoxedSlice(boxInt(i1), boxInt(i2), None));
} catch (Box* b) {
abort();
Py_FatalError("unimplemented");
}
}
......@@ -394,7 +401,7 @@ extern "C" int PyCallable_Check(PyObject* x) {
extern "C" void PyErr_Restore(PyObject* type, PyObject* value, PyObject* traceback) {
abort();
Py_FatalError("unimplemented");
}
extern "C" void PyErr_Clear() {
......@@ -410,23 +417,23 @@ extern "C" void PyErr_SetObject(PyObject* exception, PyObject* value) {
}
extern "C" PyObject* PyErr_Format(PyObject* exception, const char* format, ...) {
abort();
Py_FatalError("unimplemented");
}
extern "C" PyObject* PyErr_NoMemory() {
abort();
Py_FatalError("unimplemented");
}
extern "C" int PyErr_CheckSignals() {
abort();
Py_FatalError("unimplemented");
}
extern "C" int PyErr_ExceptionMatches(PyObject* exc) {
abort();
Py_FatalError("unimplemented");
}
extern "C" PyObject* PyErr_Occurred() {
abort();
Py_FatalError("unimplemented");
/*
printf("need to hook exception handling -- make sure errors dont propagate into C code, and error codes get "
"checked coming out\n");
......@@ -435,7 +442,7 @@ extern "C" PyObject* PyErr_Occurred() {
}
extern "C" int PyErr_WarnEx(PyObject* category, const char* text, Py_ssize_t stacklevel) {
abort();
Py_FatalError("unimplemented");
}
......@@ -446,13 +453,13 @@ extern "C" PyObject* PyImport_Import(PyObject* module_name) {
try {
return import(&static_cast<BoxedString*>(module_name)->s);
} catch (Box* e) {
abort();
Py_FatalError("unimplemented");
}
}
extern "C" PyObject* PyCallIter_New(PyObject* callable, PyObject* sentinel) {
abort();
Py_FatalError("unimplemented");
}
......
......@@ -150,15 +150,26 @@ Box* longSub(BoxedLong* v1, Box* _v2) {
raiseExcHelper(TypeError, "descriptor '__sub__' requires a 'long' object but received a '%s'",
getTypeName(v1)->c_str());
if (!isSubclass(_v2->cls, long_cls))
if (isSubclass(_v2->cls, long_cls)) {
BoxedLong* v2 = static_cast<BoxedLong*>(_v2);
BoxedLong* r = new BoxedLong(long_cls);
mpz_init(r->n);
mpz_sub(r->n, v1->n, v2->n);
return r;
} else if (isSubclass(_v2->cls, int_cls)) {
BoxedInt* v2 = static_cast<BoxedInt*>(_v2);
BoxedLong* r = new BoxedLong(long_cls);
mpz_init(r->n);
if (v2->n >= 0)
mpz_sub_ui(r->n, v1->n, v2->n);
else
mpz_add_ui(r->n, v1->n, -v2->n);
return r;
} else {
return NotImplemented;
BoxedLong* v2 = static_cast<BoxedLong*>(_v2);
BoxedLong* r = new BoxedLong(long_cls);
mpz_init(r->n);
mpz_sub(r->n, v1->n, v2->n);
return r;
}
}
Box* longMul(BoxedLong* v1, Box* _v2) {
......@@ -225,6 +236,8 @@ void setupLong() {
long_cls->giveAttr("__mul__", new BoxedFunction(boxRTFunction((void*)longMul, UNKNOWN, 2)));
long_cls->giveAttr("__div__", new BoxedFunction(boxRTFunction((void*)longDiv, UNKNOWN, 2)));
long_cls->giveAttr("__sub__", new BoxedFunction(boxRTFunction((void*)longSub, UNKNOWN, 2)));
long_cls->giveAttr("__add__", new BoxedFunction(boxRTFunction((void*)longAdd, UNKNOWN, 2)));
long_cls->giveAttr("__repr__", new BoxedFunction(boxRTFunction((void*)longRepr, STR, 1)));
long_cls->giveAttr("__str__", new BoxedFunction(boxRTFunction((void*)longStr, STR, 1)));
......
......@@ -135,10 +135,10 @@ void raiseSyntaxError(const char* msg, int lineno, int col_offset, const std::st
raiseRaw(last_exc);
}
void printLastTraceback() {
static void _printTraceback(const std::vector<const LineInfo*>& tb) {
fprintf(stderr, "Traceback (most recent call last):\n");
for (auto line : last_tb) {
for (auto line : tb) {
fprintf(stderr, " File \"%s\", line %d, in %s:\n", line->file.c_str(), line->line, line->func.c_str());
FILE* f = fopen(line->file.c_str(), "r");
......@@ -170,6 +170,14 @@ void printLastTraceback() {
}
}
void printLastTraceback() {
_printTraceback(last_tb);
}
void _printStacktrace() {
_printTraceback(getTracebackEntries());
}
static std::vector<const LineInfo*> getTracebackEntries() {
std::vector<const LineInfo*> entries;
......
......@@ -767,7 +767,7 @@ void setupRuntime() {
init_sha256();
init_sha512();
init_md5();
// init_sre();
init_sre();
setupSysEnd();
......
......@@ -11,3 +11,6 @@ print 1L / 5L
print -1L / 5L
print 1L / -5L
print -1L / -5L
print (2L).__sub__(1)
print (2L).__sub__(-1)
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