Commit dc9d0adc authored by Kevin Modzelewski's avatar Kevin Modzelewski

Simple 'subprocess' support

parent ce3bca51
......@@ -37,6 +37,9 @@ typedef struct {
#endif
typedef struct _PyFileObject PyFileObject;
// Pyston change: use this to access the fp instead of ->f_fp
PyAPI_FUNC(void) PyFile_SetFP(PyObject*, FILE*) PYSTON_NOEXCEPT;
// Pyston change: this is no longer a static object
PyAPI_DATA(PyTypeObject*) file_cls;
#define PyFile_Type (*file_cls)
......
......@@ -6916,7 +6916,7 @@ posix_fdopen(PyObject *self, PyObject *args)
/* We now know we will succeed, so initialize the file object. */
// Pyston change:
Py_FatalError("Pyston TODO: implement this");
PyFile_SetFP(f, fp);
//((PyFileObject *)f)->f_fp = fp;
PyFile_SetBufSize(f, bufsize);
......
......@@ -288,6 +288,17 @@ static void sweepPhase() {
global_heap.freeUnmarked();
}
static bool gc_enabled = true;
bool gcIsEnabled() {
return gc_enabled;
}
void enableGC() {
gc_enabled = true;
}
void disableGC() {
gc_enabled = false;
}
static int ncollections = 0;
void runCollection() {
static StatCounter sc("gc_collections");
......
......@@ -47,6 +47,13 @@ public:
void runCollection();
// Python programs are allowed to pause the GC. This is supposed to pause automatic GC,
// but does not seem to pause manual calls to gc.collect(). So, callers should check gcIsEnabled(),
// if appropriate, before calling runCollection().
bool gcIsEnabled();
void disableGC();
void enableGC();
// These are mostly for debugging:
bool isValidGCObject(void* p);
bool isNonheapRoot(void* p);
......
......@@ -45,6 +45,9 @@ void _collectIfNeeded(size_t bytes) {
thread_bytesAllocatedSinceCollection = 0;
if (bytesAllocatedSinceCollection >= ALLOCBYTES_PER_COLLECTION) {
if (!gcIsEnabled())
return;
// bytesAllocatedSinceCollection = 0;
// threading::GLPromoteRegion _lock;
// runCollection();
......
......@@ -18,14 +18,31 @@
namespace pyston {
Box* gcCollect() {
static Box* gcCollect() {
gc::runCollection();
return None;
}
static Box* isEnabled() {
return boxBool(gc::gcIsEnabled());
}
static Box* disable() {
gc::disableGC();
return None;
}
static Box* enable() {
gc::enableGC();
return None;
}
void setupGC() {
BoxedModule* gc_module = createModule("gc", "__builtin__");
gc_module->giveAttr("__hex__", new BoxedFunction(boxRTFunction((void*)gcCollect, NONE, 0)));
gc_module->giveAttr("isenabled", new BoxedFunction(boxRTFunction((void*)isEnabled, BOXED_BOOL, 0)));
gc_module->giveAttr("disable", new BoxedFunction(boxRTFunction((void*)disable, NONE, 0)));
gc_module->giveAttr("enable", new BoxedFunction(boxRTFunction((void*)enable, NONE, 0)));
}
}
......@@ -188,8 +188,16 @@ Box* fileIterHasNext(Box* s) {
return boxBool(!fileEof(self));
}
extern "C" void PyFile_SetFP(PyObject* _f, FILE* fp) noexcept {
assert(_f->cls == file_cls);
BoxedFile* f = static_cast<BoxedFile*>(_f);
assert(f->f == NULL);
f->f = fp;
}
extern "C" PyObject* PyFile_FromFile(FILE* fp, char* name, char* mode, int (*close)(FILE*)) noexcept {
Py_FatalError("unimplemented");
RELEASE_ASSERT(close == fclose, "unsupported");
return new BoxedFile(fp, name, mode);
}
extern "C" FILE* PyFile_AsFile(PyObject* f) noexcept {
......@@ -258,11 +266,59 @@ extern "C" int PyFile_WriteString(const char* s, PyObject* f) noexcept {
}
extern "C" void PyFile_SetBufSize(PyObject* f, int bufsize) noexcept {
Py_FatalError("unimplemented");
assert(f->cls == file_cls);
if (bufsize >= 0) {
if (bufsize == 0) {
setvbuf(static_cast<BoxedFile*>(f)->f, NULL, _IONBF, 0);
} else {
Py_FatalError("unimplemented");
}
}
}
extern "C" int _PyFile_SanitizeMode(char* mode) noexcept {
Py_FatalError("unimplemented");
char* upos;
size_t len = strlen(mode);
if (!len) {
PyErr_SetString(PyExc_ValueError, "empty mode string");
return -1;
}
upos = strchr(mode, 'U');
if (upos) {
memmove(upos, upos + 1, len - (upos - mode)); /* incl null char */
if (mode[0] == 'w' || mode[0] == 'a') {
PyErr_Format(PyExc_ValueError, "universal newline "
"mode can only be used with modes "
"starting with 'r'");
return -1;
}
if (mode[0] != 'r') {
memmove(mode + 1, mode, strlen(mode) + 1);
mode[0] = 'r';
}
if (!strchr(mode, 'b')) {
memmove(mode + 2, mode + 1, strlen(mode));
mode[1] = 'b';
}
} else if (mode[0] != 'r' && mode[0] != 'w' && mode[0] != 'a') {
PyErr_Format(PyExc_ValueError, "mode string must begin with "
"one of 'r', 'w', 'a' or 'U', not '%.200s'",
mode);
return -1;
}
#ifdef Py_VERIFY_WINNT
/* additional checks on NT with visual studio 2005 and higher */
if (!_PyVerify_Mode_WINNT(mode)) {
PyErr_Format(PyExc_ValueError, "Invalid mode ('%.50s')", mode);
return -1;
}
#endif
return 0;
}
extern "C" int PyObject_AsFileDescriptor(PyObject* o) noexcept {
......
......@@ -1717,7 +1717,7 @@ 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),
|| isSubclass(obj->cls, Exception) || obj->cls == file_cls,
"%s.__nonzero__",
getTypeName(obj)->c_str()); // TODO
return true;
......
# allow-warning: converting unicode literal to str
import subprocess
subprocess.check_call(["true"])
# This constructor is usually called using keyword arguments, but we don't currently support
# keyword names on built-in functions.
p = subprocess.Popen(["echo", "hello", "world"], 0, None, None, subprocess.PIPE)
out, err = p.communicate()
print (out, err)
print p.wait()
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