Commit dc9d0adc authored by Kevin Modzelewski's avatar Kevin Modzelewski

Simple 'subprocess' support

parent ce3bca51
...@@ -37,6 +37,9 @@ typedef struct { ...@@ -37,6 +37,9 @@ typedef struct {
#endif #endif
typedef struct _PyFileObject PyFileObject; 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 // Pyston change: this is no longer a static object
PyAPI_DATA(PyTypeObject*) file_cls; PyAPI_DATA(PyTypeObject*) file_cls;
#define PyFile_Type (*file_cls) #define PyFile_Type (*file_cls)
......
...@@ -6916,7 +6916,7 @@ posix_fdopen(PyObject *self, PyObject *args) ...@@ -6916,7 +6916,7 @@ posix_fdopen(PyObject *self, PyObject *args)
/* We now know we will succeed, so initialize the file object. */ /* We now know we will succeed, so initialize the file object. */
// Pyston change: // Pyston change:
Py_FatalError("Pyston TODO: implement this"); PyFile_SetFP(f, fp);
//((PyFileObject *)f)->f_fp = fp; //((PyFileObject *)f)->f_fp = fp;
PyFile_SetBufSize(f, bufsize); PyFile_SetBufSize(f, bufsize);
......
...@@ -288,6 +288,17 @@ static void sweepPhase() { ...@@ -288,6 +288,17 @@ static void sweepPhase() {
global_heap.freeUnmarked(); 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; static int ncollections = 0;
void runCollection() { void runCollection() {
static StatCounter sc("gc_collections"); static StatCounter sc("gc_collections");
......
...@@ -47,6 +47,13 @@ public: ...@@ -47,6 +47,13 @@ public:
void runCollection(); 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: // These are mostly for debugging:
bool isValidGCObject(void* p); bool isValidGCObject(void* p);
bool isNonheapRoot(void* p); bool isNonheapRoot(void* p);
......
...@@ -45,6 +45,9 @@ void _collectIfNeeded(size_t bytes) { ...@@ -45,6 +45,9 @@ void _collectIfNeeded(size_t bytes) {
thread_bytesAllocatedSinceCollection = 0; thread_bytesAllocatedSinceCollection = 0;
if (bytesAllocatedSinceCollection >= ALLOCBYTES_PER_COLLECTION) { if (bytesAllocatedSinceCollection >= ALLOCBYTES_PER_COLLECTION) {
if (!gcIsEnabled())
return;
// bytesAllocatedSinceCollection = 0; // bytesAllocatedSinceCollection = 0;
// threading::GLPromoteRegion _lock; // threading::GLPromoteRegion _lock;
// runCollection(); // runCollection();
......
...@@ -18,14 +18,31 @@ ...@@ -18,14 +18,31 @@
namespace pyston { namespace pyston {
Box* gcCollect() { static Box* gcCollect() {
gc::runCollection(); gc::runCollection();
return None; 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() { void setupGC() {
BoxedModule* gc_module = createModule("gc", "__builtin__"); BoxedModule* gc_module = createModule("gc", "__builtin__");
gc_module->giveAttr("__hex__", new BoxedFunction(boxRTFunction((void*)gcCollect, NONE, 0))); 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) { ...@@ -188,8 +188,16 @@ Box* fileIterHasNext(Box* s) {
return boxBool(!fileEof(self)); 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 { 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 { extern "C" FILE* PyFile_AsFile(PyObject* f) noexcept {
...@@ -258,11 +266,59 @@ extern "C" int PyFile_WriteString(const char* s, 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 { 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 { 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 { extern "C" int PyObject_AsFileDescriptor(PyObject* o) noexcept {
......
...@@ -1717,7 +1717,7 @@ extern "C" bool nonzero(Box* obj) { ...@@ -1717,7 +1717,7 @@ 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), || isSubclass(obj->cls, Exception) || obj->cls == file_cls,
"%s.__nonzero__", "%s.__nonzero__",
getTypeName(obj)->c_str()); // TODO getTypeName(obj)->c_str()); // TODO
return true; 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