Commit 9b45e675 authored by Kevin Modzelewski's avatar Kevin Modzelewski

Add some more CPython stuff

We're starting to have more functionality from CPython than we
wrote ourselves -- I think this is a good thing, but we should switch
Pyston code to calling it rather than supporting duplicates.

After I finish adding this stuff I'll try to clean things up a bit.
parent cfb1045a
......@@ -66,6 +66,7 @@
#include "classobject.h"
#include "fileobject.h"
#include "pycapsule.h"
#include "traceback.h"
#include "sliceobject.h"
#include "iterobject.h"
#include "descrobject.h"
......
// This file is originally from CPython 2.7, with modifications for Pyston
#ifndef Py_TRACEBACK_H
#define Py_TRACEBACK_H
#ifdef __cplusplus
extern "C" {
#endif
struct _frame;
/* Traceback interface */
// Pyston change: not necessarily our object format
#if 0
typedef struct _traceback {
PyObject_HEAD
struct _traceback *tb_next;
struct _frame *tb_frame;
int tb_lasti;
int tb_lineno;
} PyTracebackObject;
#endif
typedef struct _PyTracebackObject PyTracebackObject;
PyAPI_FUNC(int) PyTraceBack_Here(struct _frame *);
PyAPI_FUNC(int) PyTraceBack_Print(PyObject *, PyObject *);
PyAPI_FUNC(int) _Py_DisplaySourceLine(PyObject *, const char *, int, int);
/* Reveal traceback type so we can typecheck traceback objects */
// Pyston change: not a static type any more
PyAPI_DATA(PyTypeObject*) traceback_cls;
#define PyTraceback_Type (*traceback_cls)
// PyAPI_DATA(PyTypeObject) PyTraceBack_Type;
#define PyTraceBack_Check(v) (Py_TYPE(v) == &PyTraceBack_Type)
#ifdef __cplusplus
}
#endif
#endif /* !Py_TRACEBACK_H */
......@@ -182,10 +182,107 @@ extern "C" void PyErr_WriteUnraisable(PyObject* obj) {
Py_XDECREF(tb);
}
extern "C" void PyErr_Display(PyObject* exception, PyObject* value, PyObject* tb) {
static int parse_syntax_error(PyObject* err, PyObject** message, const char** filename, int* lineno, int* offset,
const char** text) noexcept {
Py_FatalError("unimplemented");
}
static void print_error_text(PyObject* f, int offset, const char* text) noexcept {
Py_FatalError("unimplemented");
}
extern "C" void PyErr_Display(PyObject* exception, PyObject* value, PyObject* tb) {
int err = 0;
PyObject* f = PySys_GetObject("stderr");
Py_INCREF(value);
if (f == NULL || f == Py_None)
fprintf(stderr, "lost sys.stderr\n");
else {
if (Py_FlushLine())
PyErr_Clear();
fflush(stdout);
if (tb && tb != Py_None)
err = PyTraceBack_Print(tb, f);
if (err == 0 && PyObject_HasAttrString(value, "print_file_and_line")) {
PyObject* message;
const char* filename, *text;
int lineno, offset;
if (!parse_syntax_error(value, &message, &filename, &lineno, &offset, &text))
PyErr_Clear();
else {
char buf[10];
PyFile_WriteString(" File \"", f);
if (filename == NULL)
PyFile_WriteString("<string>", f);
else
PyFile_WriteString(filename, f);
PyFile_WriteString("\", line ", f);
PyOS_snprintf(buf, sizeof(buf), "%d", lineno);
PyFile_WriteString(buf, f);
PyFile_WriteString("\n", f);
if (text != NULL)
print_error_text(f, offset, text);
Py_DECREF(value);
value = message;
/* Can't be bothered to check all those
PyFile_WriteString() calls */
if (PyErr_Occurred())
err = -1;
}
}
if (err) {
/* Don't do anything else */
} else if (PyExceptionClass_Check(exception)) {
PyObject* moduleName;
const char* className = PyExceptionClass_Name(exception);
if (className != NULL) {
const char* dot = strrchr(className, '.');
if (dot != NULL)
className = dot + 1;
}
moduleName = PyObject_GetAttrString(exception, "__module__");
if (moduleName == NULL)
err = PyFile_WriteString("<unknown>", f);
else {
char* modstr = PyString_AsString(moduleName);
if (modstr && strcmp(modstr, "exceptions")) {
err = PyFile_WriteString(modstr, f);
err += PyFile_WriteString(".", f);
}
Py_DECREF(moduleName);
}
if (err == 0) {
if (className == NULL)
err = PyFile_WriteString("<unknown>", f);
else
err = PyFile_WriteString(className, f);
}
} else
err = PyFile_WriteObject(exception, f, Py_PRINT_RAW);
if (err == 0 && (value != Py_None)) {
PyObject* s = PyObject_Str(value);
/* only print colon if the str() of the
object is not the empty string
*/
if (s == NULL)
err = -1;
else if (!PyString_Check(s) || PyString_GET_SIZE(s) != 0)
err = PyFile_WriteString(": ", f);
if (err == 0)
err = PyFile_WriteObject(s, f, Py_PRINT_RAW);
Py_XDECREF(s);
}
/* try to write a newline in any case */
err += PyFile_WriteString("\n", f);
}
Py_DECREF(value);
/* If an error happened here, don't show it.
XXX This is wrong, but too many callers rely on this behavior. */
if (err != 0)
PyErr_Clear();
}
static void handle_system_exit(void) noexcept {
Py_FatalError("unimplemented");
}
......
......@@ -72,6 +72,29 @@ extern "C" int PyObject_GenericSetAttr(PyObject* obj, PyObject* name, PyObject*
Py_FatalError("unimplemented");
}
extern "C" PyObject* PyObject_GetAttrString(PyObject* o, const char* attr) {
// 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?
// threading::GLDemoteRegion _gil_demote;
try {
return getattr(o, attr);
} catch (Box* b) {
PyErr_SetObject(b->cls, b);
return NULL;
}
}
extern "C" int PyObject_HasAttrString(PyObject* v, const char* name) {
PyObject* res = PyObject_GetAttrString(v, name);
if (res != NULL) {
Py_DECREF(res);
return 1;
}
PyErr_Clear();
return 0;
}
extern "C" int PyObject_AsWriteBuffer(PyObject* obj, void** buffer, Py_ssize_t* buffer_len) {
Py_FatalError("unimplemented");
}
......
......@@ -235,18 +235,6 @@ extern "C" PyObject* _PyObject_CallMethod_SizeT(PyObject* o, char* name, char* f
Py_FatalError("unimplemented");
}
extern "C" PyObject* PyObject_GetAttrString(PyObject* o, const char* attr) {
// 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?
// threading::GLDemoteRegion _gil_demote;
try {
return getattr(o, attr);
} catch (Box* b) {
Py_FatalError("unimplemented");
}
}
extern "C" Py_ssize_t PyObject_Size(PyObject* o) {
try {
return len(o)->n;
......@@ -808,7 +796,7 @@ extern "C" int PyExceptionInstance_Check(PyObject* o) {
}
extern "C" const char* PyExceptionClass_Name(PyObject* o) {
Py_FatalError("unimplemented");
return PyClass_Check(o) ? PyString_AS_STRING(static_cast<BoxedClassobj*>(o)->name) : o->cls->tp_name;
}
extern "C" PyObject* PyExceptionInstance_Class(PyObject* o) {
......
......@@ -199,11 +199,61 @@ extern "C" FILE* PyFile_AsFile(PyObject* f) {
}
extern "C" int PyFile_WriteObject(PyObject* v, PyObject* f, int flags) {
Py_FatalError("unimplemented");
if (f->cls != file_cls || v->cls != str_cls || flags != Py_PRINT_RAW)
Py_FatalError("unimplemented");
try {
Box* r = fileWrite(static_cast<BoxedFile*>(f), v);
assert(r == None);
return 0;
} catch (Box* b) {
PyErr_SetObject(b->cls, b);
return -1;
}
}
#define FILE_BEGIN_ALLOW_THREADS(fobj) \
{ \
/*fobj->unlocked_count++;*/ \
Py_BEGIN_ALLOW_THREADS
#define FILE_END_ALLOW_THREADS(fobj) \
Py_END_ALLOW_THREADS \
/*fobj->unlocked_count--;*/ \
/*assert(fobj->unlocked_count >= 0);*/ \
}
static PyObject* err_closed(void) noexcept {
PyErr_SetString(PyExc_ValueError, "I/O operation on closed file");
return NULL;
}
extern "C" int PyFile_WriteString(const char* s, PyObject* f) {
Py_FatalError("unimplemented");
if (f == NULL) {
/* Should be caused by a pre-existing error */
if (!PyErr_Occurred())
PyErr_SetString(PyExc_SystemError, "null file for PyFile_WriteString");
return -1;
} else if (PyFile_Check(f)) {
PyFileObject* fobj = (PyFileObject*)f;
FILE* fp = PyFile_AsFile(f);
if (fp == NULL) {
err_closed();
return -1;
}
FILE_BEGIN_ALLOW_THREADS(fobj)
fputs(s, fp);
FILE_END_ALLOW_THREADS(fobj)
return 0;
} else if (!PyErr_Occurred()) {
PyObject* v = PyString_FromString(s);
int err;
if (v == NULL)
return -1;
err = PyFile_WriteObject(v, f, Py_PRINT_RAW);
Py_DECREF(v);
return err;
} else
return -1;
}
extern "C" void PyFile_SetBufSize(PyObject* f, int bufsize) {
......@@ -219,7 +269,11 @@ extern "C" int PyObject_AsFileDescriptor(PyObject* o) {
}
extern "C" int PyFile_SoftSpace(PyObject* f, int newflag) {
Py_FatalError("unimplemented");
try {
return softspace(f, newflag);
} catch (Box* b) {
abort();
}
}
void setupFile() {
......
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