Commit 7513842a authored by Kevin Modzelewski's avatar Kevin Modzelewski

Merge branch 'selfhost_merge'

parents e8506fef 6b1bc93e
......@@ -46,6 +46,7 @@
#define HAVE_EPOLL 1
#define HAVE_POLL 1
#define HAVE_SELECT 1
#define HAVE_ALARM 1
#define PY_FORMAT_LONG_LONG "ll"
#define PY_FORMAT_SIZE_T "z"
......
......@@ -284,6 +284,116 @@ extern "C" PyObject* PyObject_CallFunctionObjArgs(PyObject* callable, ...) noexc
return tmp;
}
extern "C" PyObject* PyObject_CallObject(PyObject* obj, PyObject* args) noexcept {
RELEASE_ASSERT(args, ""); // actually it looks like this is allowed to be NULL
RELEASE_ASSERT(args->cls == tuple_cls, "");
// 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 {
Box* r = runtimeCall(obj, ArgPassSpec(0, 0, true, false), args, NULL, NULL, NULL, NULL);
return r;
} catch (ExcInfo e) {
Py_FatalError("unimplemented");
}
}
static PyObject* call_function_tail(PyObject* callable, PyObject* args) {
PyObject* retval;
if (args == NULL)
return NULL;
if (!PyTuple_Check(args)) {
PyObject* a;
a = PyTuple_New(1);
if (a == NULL) {
Py_DECREF(args);
return NULL;
}
PyTuple_SET_ITEM(a, 0, args);
args = a;
}
retval = PyObject_Call(callable, args, NULL);
Py_DECREF(args);
return retval;
}
extern "C" PyObject* PyObject_CallMethod(PyObject* o, char* name, char* format, ...) noexcept {
Py_FatalError("unimplemented");
}
extern "C" PyObject* _PyObject_CallMethod_SizeT(PyObject* o, char* name, char* format, ...) noexcept {
// TODO it looks like this could be made much more efficient by calling our callattr(), but
// I haven't taken the time to verify that that has the same behavior
va_list va;
PyObject* args;
PyObject* func = NULL;
PyObject* retval = NULL;
if (o == NULL || name == NULL)
return null_error();
func = PyObject_GetAttrString(o, name);
if (func == NULL) {
PyErr_SetString(PyExc_AttributeError, name);
return 0;
}
if (!PyCallable_Check(func)) {
type_error("attribute of type '%.200s' is not callable", func);
goto exit;
}
if (format && *format) {
va_start(va, format);
args = _Py_VaBuildValue_SizeT(format, va);
va_end(va);
} else
args = PyTuple_New(0);
retval = call_function_tail(func, args);
exit:
/* args gets consumed in call_function_tail */
Py_XDECREF(func);
return retval;
}
extern "C" Py_ssize_t PyObject_Size(PyObject* o) noexcept {
try {
return len(o)->n;
} catch (ExcInfo e) {
setCAPIException(e);
return -1;
}
}
extern "C" PyObject* PyObject_GetIter(PyObject* o) noexcept {
try {
return getiter(o);
} catch (ExcInfo e) {
setCAPIException(e);
return NULL;
}
}
extern "C" PyObject* PyObject_Repr(PyObject* obj) noexcept {
try {
return repr(obj);
} catch (ExcInfo e) {
setCAPIException(e);
return NULL;
}
}
static int recursive_issubclass(PyObject* derived, PyObject* cls) noexcept {
int retval;
......@@ -508,4 +618,44 @@ extern "C" PyObject* PySequence_List(PyObject* v) noexcept {
extern "C" PyObject* PyObject_CallFunction(PyObject* callable, char* format, ...) noexcept {
Py_FatalError("unimplemented");
}
extern "C" int PyMapping_Check(PyObject* o) noexcept {
if (o && PyInstance_Check(o))
return PyObject_HasAttrString(o, "__getitem__");
return o && o->cls->tp_as_mapping && o->cls->tp_as_mapping->mp_subscript
&& !(o->cls->tp_as_sequence && o->cls->tp_as_sequence->sq_slice);
}
extern "C" Py_ssize_t PyMapping_Size(PyObject* o) noexcept {
PyMappingMethods* m;
if (o == NULL) {
null_error();
return -1;
}
m = o->cls->tp_as_mapping;
if (m && m->mp_length)
return m->mp_length(o);
type_error("object of type '%.200s' has no len()", o);
return -1;
}
extern "C" int PyMapping_HasKeyString(PyObject* o, char* key) noexcept {
Py_FatalError("unimplemented");
}
extern "C" int PyMapping_HasKey(PyObject* o, PyObject* key) noexcept {
Py_FatalError("unimplemented");
}
extern "C" PyObject* PyMapping_GetItemString(PyObject* o, char* key) noexcept {
Py_FatalError("unimplemented");
}
extern "C" int PyMapping_SetItemString(PyObject* o, char* key, PyObject* v) noexcept {
Py_FatalError("unimplemented");
}
}
......@@ -218,6 +218,10 @@ extern "C" PyObject* Py_VaBuildValue(const char* format, va_list va) noexcept {
return va_build_value(format, va, 0);
}
extern "C" PyObject* _Py_VaBuildValue_SizeT(const char* format, va_list va) noexcept {
return va_build_value(format, va, FLAG_SIZE_T);
}
extern "C" PyObject* _Py_BuildValue_SizeT(const char* fmt, ...) noexcept {
va_list ap;
va_start(ap, fmt);
......
......@@ -606,6 +606,13 @@ class BoxedException : public Box {
public:
HCAttrs attrs;
BoxedException() {}
static Box* __reduce__(Box* self) {
RELEASE_ASSERT(isSubclass(self->cls, BaseException), "");
BoxedException* exc = static_cast<BoxedException*>(self);
return new BoxedTuple({ self->cls, EmptyTuple, makeAttrWrapper(self) });
}
};
Box* exceptionNew2(BoxedClass* cls, Box* message) {
......@@ -854,9 +861,6 @@ public:
static Box* __init__(BoxedEnvironmentError* self, Box* errno_, Box* strerror, Box** _args) {
Box* filename = _args[0];
if (!errno_)
return None;
RELEASE_ASSERT(isSubclass(self->cls, EnvironmentError), "");
self->myerrno = errno_;
......@@ -865,6 +869,8 @@ public:
return None;
}
static Box* __reduce__(Box* self) { Py_FatalError("unimplemented"); }
static PyObject* __str__(BoxedEnvironmentError* self) noexcept {
PyObject* rtnval = NULL;
......@@ -1022,6 +1028,11 @@ void setupBuiltins() {
PendingDeprecationWarning = makeBuiltinException(Warning, "PendingDeprecationWarning");
EOFError = makeBuiltinException(StandardError, "EOFError");
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),
......
......@@ -154,57 +154,6 @@ extern "C" void PyObject_Free(void* p) noexcept {
ASSERT(0, "I think this is good enough but I'm not sure; should test");
}
extern "C" PyObject* PyObject_CallObject(PyObject* obj, PyObject* args) noexcept {
RELEASE_ASSERT(args, ""); // actually it looks like this is allowed to be NULL
RELEASE_ASSERT(args->cls == tuple_cls, "");
// 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 {
Box* r = runtimeCall(obj, ArgPassSpec(0, 0, true, false), args, NULL, NULL, NULL, NULL);
return r;
} catch (ExcInfo e) {
Py_FatalError("unimplemented");
}
}
extern "C" PyObject* PyObject_CallMethod(PyObject* o, char* name, char* format, ...) noexcept {
Py_FatalError("unimplemented");
}
extern "C" PyObject* _PyObject_CallMethod_SizeT(PyObject* o, char* name, char* format, ...) noexcept {
Py_FatalError("unimplemented");
}
extern "C" Py_ssize_t PyObject_Size(PyObject* o) noexcept {
try {
return len(o)->n;
} catch (ExcInfo e) {
setCAPIException(e);
return -1;
}
}
extern "C" PyObject* PyObject_GetIter(PyObject* o) noexcept {
try {
return getiter(o);
} catch (ExcInfo e) {
setCAPIException(e);
return NULL;
}
}
extern "C" PyObject* PyObject_Repr(PyObject* obj) noexcept {
try {
return repr(obj);
} catch (ExcInfo e) {
setCAPIException(e);
return NULL;
}
}
extern "C" PyObject* PyObject_Format(PyObject* obj, PyObject* format_spec) noexcept {
PyObject* empty = NULL;
PyObject* result = NULL;
......@@ -543,6 +492,9 @@ extern "C" Py_ssize_t PySequence_Index(PyObject* o, PyObject* value) noexcept {
}
extern "C" PyObject* PySequence_Tuple(PyObject* o) noexcept {
if (o->cls == tuple_cls)
return o;
Py_FatalError("unimplemented");
}
......
......@@ -535,30 +535,6 @@ extern "C" Box* dictInit(BoxedDict* self, BoxedTuple* args, BoxedDict* kwargs) {
return None;
}
extern "C" int PyMapping_Check(PyObject* o) noexcept {
Py_FatalError("unimplemented");
}
extern "C" Py_ssize_t PyMapping_Size(PyObject* o) noexcept {
Py_FatalError("unimplemented");
}
extern "C" int PyMapping_HasKeyString(PyObject* o, char* key) noexcept {
Py_FatalError("unimplemented");
}
extern "C" int PyMapping_HasKey(PyObject* o, PyObject* key) noexcept {
Py_FatalError("unimplemented");
}
extern "C" PyObject* PyMapping_GetItemString(PyObject* o, char* key) noexcept {
Py_FatalError("unimplemented");
}
extern "C" int PyMapping_SetItemString(PyObject* o, char* key, PyObject* v) noexcept {
Py_FatalError("unimplemented");
}
BoxedClass* dict_iterator_cls = NULL;
extern "C" void dictIteratorGCHandler(GCVisitor* v, Box* b) {
boxGCHandler(v, b);
......
......@@ -619,6 +619,14 @@ Box* fileClose(BoxedFile* self) {
return sts;
}
Box* fileFileno(BoxedFile* self) {
assert(self->cls == file_cls);
if (!self->f_fp)
raiseExcHelper(IOError, "file is closed");
return boxInt(fileno(self->f_fp));
}
Box* fileEnter(BoxedFile* self) {
assert(self->cls == file_cls);
return self;
......@@ -1067,6 +1075,7 @@ void setupFile() {
file_cls->giveAttr("flush", new BoxedFunction(boxRTFunction((void*)fileFlush, NONE, 1)));
file_cls->giveAttr("write", new BoxedFunction(boxRTFunction((void*)fileWrite, NONE, 2)));
file_cls->giveAttr("close", new BoxedFunction(boxRTFunction((void*)fileClose, NONE, 1)));
file_cls->giveAttr("fileno", new BoxedFunction(boxRTFunction((void*)fileFileno, BOXED_INT, 1)));
file_cls->giveAttr("__repr__", new BoxedFunction(boxRTFunction((void*)fileRepr, STR, 1)));
......
......@@ -109,6 +109,18 @@ static uint64_t asUnsignedLong(BoxedLong* self) {
}
extern "C" unsigned long PyLong_AsUnsignedLong(PyObject* vv) noexcept {
assert(vv);
if (vv->cls == int_cls) {
long val = PyInt_AsLong(vv);
if (val < 0) {
PyErr_SetString(PyExc_OverflowError, "can't convert negative value "
"to unsigned long");
return (unsigned long)-1;
}
return val;
}
RELEASE_ASSERT(PyLong_Check(vv), "");
BoxedLong* l = static_cast<BoxedLong*>(vv);
......
......@@ -1710,7 +1710,8 @@ extern "C" bool nonzero(Box* obj) {
if (func == NULL) {
ASSERT(isUserDefined(obj->cls) || obj->cls == classobj_cls || obj->cls == type_cls
|| isSubclass(obj->cls, Exception) || obj->cls == file_cls || obj->cls == traceback_cls,
|| isSubclass(obj->cls, Exception) || obj->cls == file_cls || obj->cls == traceback_cls
|| obj->cls == instancemethod_cls,
"%s.__nonzero__",
getTypeName(obj)); // TODO
// TODO should rewrite these?
......
......@@ -213,10 +213,15 @@ void raise3(Box* arg0, Box* arg1, Box* arg2) {
BoxedClass* c = static_cast<BoxedClass*>(arg0);
if (isSubclass(c, BaseException)) {
Box* exc_obj;
if (arg1 != None)
exc_obj = exceptionNew2(c, arg1);
else
exc_obj = exceptionNew1(c);
if (isSubclass(arg1->cls, BaseException)) {
exc_obj = arg1;
c = exc_obj->cls;
} else if (arg1 != None) {
exc_obj = runtimeCall(c, ArgPassSpec(1), arg1, NULL, NULL, NULL, NULL);
} else {
exc_obj = runtimeCall(c, ArgPassSpec(0), NULL, NULL, NULL, NULL, NULL);
}
raiseRaw(ExcInfo(c, exc_obj, arg2));
}
......
......@@ -687,6 +687,11 @@ extern "C" Box* sliceNew(Box* cls, Box* start, Box* stop, Box** args) {
return createSlice(start, stop, step);
}
static Box* instancemethodCall(BoxedInstanceMethod* self, Box* args, Box* kwargs) {
RELEASE_ASSERT(self->cls == instancemethod_cls, "");
Py_FatalError("unimplemented");
}
Box* instancemethodGet(BoxedInstanceMethod* self, Box* obj, Box* type) {
RELEASE_ASSERT(self->cls == instancemethod_cls, "");
......@@ -1200,6 +1205,8 @@ void setupRuntime() {
instancemethod_cls->giveAttr("__eq__", new BoxedFunction(boxRTFunction((void*)instancemethodEq, UNKNOWN, 2)));
instancemethod_cls->giveAttr(
"__get__", new BoxedFunction(boxRTFunction((void*)instancemethodGet, UNKNOWN, 3, 0, false, false)));
instancemethod_cls->giveAttr(
"__call__", new BoxedFunction(boxRTFunction((void*)instancemethodCall, UNKNOWN, 1, 0, true, true)));
instancemethod_cls->giveAttr(
"im_func", new BoxedMemberDescriptor(BoxedMemberDescriptor::OBJECT, offsetof(BoxedInstanceMethod, func)));
instancemethod_cls->giveAttr(
......
# no-collect-stats
import os
os.execvpe("echo", ["it", "worked!"], {})
......@@ -4,3 +4,9 @@ for k in sorted(dir(resource)):
if not k.startswith("RLIMIT_"):
continue
print k, getattr(resource, k)
TIME_LIMIT = 100
resource.setrlimit(resource.RLIMIT_CPU, (TIME_LIMIT + 1, TIME_LIMIT + 1))
MAX_MEM_MB = 100
resource.setrlimit(resource.RLIMIT_RSS, (MAX_MEM_MB * 1024 * 1024, MAX_MEM_MB * 1024 * 1024))
......@@ -4,3 +4,5 @@ for k in sorted(dir(signal)):
if not k.startswith("SIG"):
continue
print k, getattr(signal, k)
print hasattr(signal, "alarm")
......@@ -233,3 +233,17 @@ def f13():
print sys.exc_info()[0]
f13()
def f14():
try:
1/0
except Exception:
a, b, c = sys.exc_info()
for i in xrange(5):
try:
(i)[0]
except Exception:
pass
raise a, b, c
f14()
......@@ -2,3 +2,5 @@ import sys
sys.stdout.write("hello world\n")
print >>sys.stdout, "hello world"
print sys.stdout.fileno()
......@@ -412,6 +412,17 @@ if __name__ == "__main__":
]
tests += big_tests
for t in tests:
bn = os.path.basename(t)
assert bn.endswith(".py")
module_name = bn[:-3]
try:
__import__(module_name)
raise Exception("Error: %s hides builtin module '%s'" % (t, module_name))
except ImportError:
pass
# good
for t in TOSKIP:
assert t in ("%s/t.py" % TEST_DIR, "%s/t2.py" % TEST_DIR) or t in tests, t
......
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