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

Merge branch 'selfhost_merge'

parents e8506fef 6b1bc93e
...@@ -46,6 +46,7 @@ ...@@ -46,6 +46,7 @@
#define HAVE_EPOLL 1 #define HAVE_EPOLL 1
#define HAVE_POLL 1 #define HAVE_POLL 1
#define HAVE_SELECT 1 #define HAVE_SELECT 1
#define HAVE_ALARM 1
#define PY_FORMAT_LONG_LONG "ll" #define PY_FORMAT_LONG_LONG "ll"
#define PY_FORMAT_SIZE_T "z" #define PY_FORMAT_SIZE_T "z"
......
...@@ -284,6 +284,116 @@ extern "C" PyObject* PyObject_CallFunctionObjArgs(PyObject* callable, ...) noexc ...@@ -284,6 +284,116 @@ extern "C" PyObject* PyObject_CallFunctionObjArgs(PyObject* callable, ...) noexc
return tmp; 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 { static int recursive_issubclass(PyObject* derived, PyObject* cls) noexcept {
int retval; int retval;
...@@ -508,4 +618,44 @@ extern "C" PyObject* PySequence_List(PyObject* v) noexcept { ...@@ -508,4 +618,44 @@ extern "C" PyObject* PySequence_List(PyObject* v) noexcept {
extern "C" PyObject* PyObject_CallFunction(PyObject* callable, char* format, ...) noexcept { extern "C" PyObject* PyObject_CallFunction(PyObject* callable, char* format, ...) noexcept {
Py_FatalError("unimplemented"); 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 { ...@@ -218,6 +218,10 @@ extern "C" PyObject* Py_VaBuildValue(const char* format, va_list va) noexcept {
return va_build_value(format, va, 0); 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 { extern "C" PyObject* _Py_BuildValue_SizeT(const char* fmt, ...) noexcept {
va_list ap; va_list ap;
va_start(ap, fmt); va_start(ap, fmt);
......
...@@ -606,6 +606,13 @@ class BoxedException : public Box { ...@@ -606,6 +606,13 @@ class BoxedException : public Box {
public: public:
HCAttrs attrs; HCAttrs attrs;
BoxedException() {} 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) { Box* exceptionNew2(BoxedClass* cls, Box* message) {
...@@ -854,9 +861,6 @@ public: ...@@ -854,9 +861,6 @@ public:
static Box* __init__(BoxedEnvironmentError* self, Box* errno_, Box* strerror, Box** _args) { static Box* __init__(BoxedEnvironmentError* self, Box* errno_, Box* strerror, Box** _args) {
Box* filename = _args[0]; Box* filename = _args[0];
if (!errno_)
return None;
RELEASE_ASSERT(isSubclass(self->cls, EnvironmentError), ""); RELEASE_ASSERT(isSubclass(self->cls, EnvironmentError), "");
self->myerrno = errno_; self->myerrno = errno_;
...@@ -865,6 +869,8 @@ public: ...@@ -865,6 +869,8 @@ public:
return None; return None;
} }
static Box* __reduce__(Box* self) { Py_FatalError("unimplemented"); }
static PyObject* __str__(BoxedEnvironmentError* self) noexcept { static PyObject* __str__(BoxedEnvironmentError* self) noexcept {
PyObject* rtnval = NULL; PyObject* rtnval = NULL;
...@@ -1022,6 +1028,11 @@ void setupBuiltins() { ...@@ -1022,6 +1028,11 @@ void setupBuiltins() {
PendingDeprecationWarning = makeBuiltinException(Warning, "PendingDeprecationWarning"); PendingDeprecationWarning = makeBuiltinException(Warning, "PendingDeprecationWarning");
EOFError = makeBuiltinException(StandardError, "EOFError"); 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->gc_visit = BoxedEnvironmentError::gcHandler;
EnvironmentError->giveAttr( EnvironmentError->giveAttr(
"__init__", new BoxedFunction(boxRTFunction((void*)BoxedEnvironmentError::__init__, NONE, 4, 3, false, false), "__init__", new BoxedFunction(boxRTFunction((void*)BoxedEnvironmentError::__init__, NONE, 4, 3, false, false),
......
...@@ -154,57 +154,6 @@ extern "C" void PyObject_Free(void* p) noexcept { ...@@ -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"); 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 { extern "C" PyObject* PyObject_Format(PyObject* obj, PyObject* format_spec) noexcept {
PyObject* empty = NULL; PyObject* empty = NULL;
PyObject* result = NULL; PyObject* result = NULL;
...@@ -543,6 +492,9 @@ extern "C" Py_ssize_t PySequence_Index(PyObject* o, PyObject* value) noexcept { ...@@ -543,6 +492,9 @@ extern "C" Py_ssize_t PySequence_Index(PyObject* o, PyObject* value) noexcept {
} }
extern "C" PyObject* PySequence_Tuple(PyObject* o) noexcept { extern "C" PyObject* PySequence_Tuple(PyObject* o) noexcept {
if (o->cls == tuple_cls)
return o;
Py_FatalError("unimplemented"); Py_FatalError("unimplemented");
} }
......
...@@ -535,30 +535,6 @@ extern "C" Box* dictInit(BoxedDict* self, BoxedTuple* args, BoxedDict* kwargs) { ...@@ -535,30 +535,6 @@ extern "C" Box* dictInit(BoxedDict* self, BoxedTuple* args, BoxedDict* kwargs) {
return None; 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; BoxedClass* dict_iterator_cls = NULL;
extern "C" void dictIteratorGCHandler(GCVisitor* v, Box* b) { extern "C" void dictIteratorGCHandler(GCVisitor* v, Box* b) {
boxGCHandler(v, b); boxGCHandler(v, b);
......
...@@ -619,6 +619,14 @@ Box* fileClose(BoxedFile* self) { ...@@ -619,6 +619,14 @@ Box* fileClose(BoxedFile* self) {
return sts; 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) { Box* fileEnter(BoxedFile* self) {
assert(self->cls == file_cls); assert(self->cls == file_cls);
return self; return self;
...@@ -1067,6 +1075,7 @@ void setupFile() { ...@@ -1067,6 +1075,7 @@ void setupFile() {
file_cls->giveAttr("flush", new BoxedFunction(boxRTFunction((void*)fileFlush, NONE, 1))); 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("write", new BoxedFunction(boxRTFunction((void*)fileWrite, NONE, 2)));
file_cls->giveAttr("close", new BoxedFunction(boxRTFunction((void*)fileClose, NONE, 1))); 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))); file_cls->giveAttr("__repr__", new BoxedFunction(boxRTFunction((void*)fileRepr, STR, 1)));
......
...@@ -109,6 +109,18 @@ static uint64_t asUnsignedLong(BoxedLong* self) { ...@@ -109,6 +109,18 @@ static uint64_t asUnsignedLong(BoxedLong* self) {
} }
extern "C" unsigned long PyLong_AsUnsignedLong(PyObject* vv) noexcept { 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), ""); RELEASE_ASSERT(PyLong_Check(vv), "");
BoxedLong* l = static_cast<BoxedLong*>(vv); BoxedLong* l = static_cast<BoxedLong*>(vv);
......
...@@ -1710,7 +1710,8 @@ extern "C" bool nonzero(Box* obj) { ...@@ -1710,7 +1710,8 @@ extern "C" bool nonzero(Box* obj) {
if (func == NULL) { if (func == NULL) {
ASSERT(isUserDefined(obj->cls) || obj->cls == classobj_cls || obj->cls == type_cls 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__", "%s.__nonzero__",
getTypeName(obj)); // TODO getTypeName(obj)); // TODO
// TODO should rewrite these? // TODO should rewrite these?
......
...@@ -213,10 +213,15 @@ void raise3(Box* arg0, Box* arg1, Box* arg2) { ...@@ -213,10 +213,15 @@ void raise3(Box* arg0, Box* arg1, Box* arg2) {
BoxedClass* c = static_cast<BoxedClass*>(arg0); BoxedClass* c = static_cast<BoxedClass*>(arg0);
if (isSubclass(c, BaseException)) { if (isSubclass(c, BaseException)) {
Box* exc_obj; Box* exc_obj;
if (arg1 != None)
exc_obj = exceptionNew2(c, arg1); if (isSubclass(arg1->cls, BaseException)) {
else exc_obj = arg1;
exc_obj = exceptionNew1(c); 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)); raiseRaw(ExcInfo(c, exc_obj, arg2));
} }
......
...@@ -687,6 +687,11 @@ extern "C" Box* sliceNew(Box* cls, Box* start, Box* stop, Box** args) { ...@@ -687,6 +687,11 @@ extern "C" Box* sliceNew(Box* cls, Box* start, Box* stop, Box** args) {
return createSlice(start, stop, step); 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) { Box* instancemethodGet(BoxedInstanceMethod* self, Box* obj, Box* type) {
RELEASE_ASSERT(self->cls == instancemethod_cls, ""); RELEASE_ASSERT(self->cls == instancemethod_cls, "");
...@@ -1200,6 +1205,8 @@ void setupRuntime() { ...@@ -1200,6 +1205,8 @@ void setupRuntime() {
instancemethod_cls->giveAttr("__eq__", new BoxedFunction(boxRTFunction((void*)instancemethodEq, UNKNOWN, 2))); instancemethod_cls->giveAttr("__eq__", new BoxedFunction(boxRTFunction((void*)instancemethodEq, UNKNOWN, 2)));
instancemethod_cls->giveAttr( instancemethod_cls->giveAttr(
"__get__", new BoxedFunction(boxRTFunction((void*)instancemethodGet, UNKNOWN, 3, 0, false, false))); "__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( instancemethod_cls->giveAttr(
"im_func", new BoxedMemberDescriptor(BoxedMemberDescriptor::OBJECT, offsetof(BoxedInstanceMethod, func))); "im_func", new BoxedMemberDescriptor(BoxedMemberDescriptor::OBJECT, offsetof(BoxedInstanceMethod, func)));
instancemethod_cls->giveAttr( instancemethod_cls->giveAttr(
......
# no-collect-stats
import os
os.execvpe("echo", ["it", "worked!"], {})
...@@ -4,3 +4,9 @@ for k in sorted(dir(resource)): ...@@ -4,3 +4,9 @@ for k in sorted(dir(resource)):
if not k.startswith("RLIMIT_"): if not k.startswith("RLIMIT_"):
continue continue
print k, getattr(resource, k) 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)): ...@@ -4,3 +4,5 @@ for k in sorted(dir(signal)):
if not k.startswith("SIG"): if not k.startswith("SIG"):
continue continue
print k, getattr(signal, k) print k, getattr(signal, k)
print hasattr(signal, "alarm")
...@@ -233,3 +233,17 @@ def f13(): ...@@ -233,3 +233,17 @@ def f13():
print sys.exc_info()[0] print sys.exc_info()[0]
f13() 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 ...@@ -2,3 +2,5 @@ import sys
sys.stdout.write("hello world\n") sys.stdout.write("hello world\n")
print >>sys.stdout, "hello world" print >>sys.stdout, "hello world"
print sys.stdout.fileno()
...@@ -412,6 +412,17 @@ if __name__ == "__main__": ...@@ -412,6 +412,17 @@ if __name__ == "__main__":
] ]
tests += big_tests 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: for t in TOSKIP:
assert t in ("%s/t.py" % TEST_DIR, "%s/t2.py" % TEST_DIR) or t in tests, t 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