Commit dff9c845 authored by Kevin Modzelewski's avatar Kevin Modzelewski

cStringIO.StringIO is now METH_O

Module-level functions go through a slightly different code path than class-level
ones, so this commit adds the METH_O3/METH_D3 calling conventions to that as well.
parent d2e9aed7
......@@ -685,11 +685,8 @@ newIobject(PyObject *s) {
PyObject *args;
int result;
args = Py_BuildValue("(O)", s);
if (args == NULL)
return NULL;
result = PyArg_ParseTuple(args, "s*:StringIO", &buf);
Py_DECREF(args);
// Pyston change:
result = PyArg_ParseSingle(s, 1, "StringIO", "s*", &buf);
if (!result)
return NULL;
......@@ -714,11 +711,7 @@ PyDoc_STRVAR(IO_StringIO__doc__,
"StringIO([s]) -- Return a StringIO-like stream for reading or writing");
static PyObject *
IO_StringIO(PyObject *self, PyObject *args) {
PyObject *s=0;
if (!PyArg_UnpackTuple(args, "StringIO", 0, 1, &s)) return NULL;
IO_StringIO(PyObject *self, PyObject *s) {
if (s) return newIobject(s);
return newOobject(128);
}
......@@ -727,7 +720,7 @@ IO_StringIO(PyObject *self, PyObject *args) {
static struct PyMethodDef IO_methods[] = {
{"StringIO", (PyCFunction)IO_StringIO,
METH_VARARGS, IO_StringIO__doc__},
/* Pyston change: */ METH_O | METH_D1, IO_StringIO__doc__},
{NULL, NULL} /* sentinel */
};
......
......@@ -161,12 +161,20 @@ cleanup_buffer(PyObject *self)
}
}
// A special cleanup "list" that specifies that we don't need to keep track of cleanups.
// This is useful for vgetsingle, where there are no partial-failure cases that require
// keeping track of cleanups.
#define NOCLEANUP ((PyObject**)1)
static int
addcleanup(void *ptr, PyObject **freelist, PyCapsule_Destructor destr)
{
PyObject *cobj;
const char *name;
if (freelist == NOCLEANUP)
return 0;
if (!*freelist) {
*freelist = PyList_New(0);
if (!*freelist) {
......@@ -576,12 +584,8 @@ int vgetsingle(PyObject* obj, int arg_idx, const char* fname, const char* format
assert(format[0] != '\0');
assert(format[0] != '(');
assert(format[0] != '|');
assert(format[0] != '|');
assert(format[1] != '*'); // would need to pass a non-null freelist
assert(format[0] != 'e'); // would need to pass a non-null freelist
msg = convertsimple(obj, &format, v_pa, flags, msgbuf, sizeof(msgbuf), NULL);
msg = convertsimple(obj, &format, v_pa, flags, msgbuf, sizeof(msgbuf), NOCLEANUP);
if (msg) {
int levels[1];
......
......@@ -423,8 +423,6 @@ extern "C" PyObject* Py_InitModule4(const char* name, PyMethodDef* methods, cons
Box* passthrough = static_cast<Box*>(self);
while (methods && methods->ml_name) {
RELEASE_ASSERT((methods->ml_flags & (~(METH_VARARGS | METH_KEYWORDS | METH_NOARGS | METH_O))) == 0, "%d",
methods->ml_flags);
module->giveAttr(methods->ml_name, new BoxedCApiFunction(methods, passthrough, boxString(name)));
methods++;
......
......@@ -1509,6 +1509,7 @@ Box* BoxedCApiFunction::tppCall(Box* _self, CallRewriteArgs* rewrite_args, ArgPa
auto func = self->method_def->ml_meth;
ParamReceiveSpec paramspec(0, 0, true, false);
Box** defaults = NULL;
if (flags == METH_VARARGS) {
paramspec = ParamReceiveSpec(0, 0, true, false);
} else if (flags == (METH_VARARGS | METH_KEYWORDS)) {
......@@ -1519,6 +1520,27 @@ Box* BoxedCApiFunction::tppCall(Box* _self, CallRewriteArgs* rewrite_args, ArgPa
paramspec = ParamReceiveSpec(1, 0, false, false);
} else if (flags == METH_OLDARGS) {
paramspec = ParamReceiveSpec(1, 0, false, false);
} else if ((flags & ~(METH_O3 | METH_D3)) == 0) {
int num_args = 0;
if (flags & METH_O)
num_args++;
if (flags & METH_O2)
num_args += 2;
int num_defaults = 0;
if (flags & METH_D1)
num_defaults++;
if (flags & METH_D2)
num_defaults += 2;
paramspec = ParamReceiveSpec(num_args, num_defaults, false, false);
if (num_defaults) {
static Box* _defaults[] = { NULL, NULL, NULL };
assert(num_defaults <= 3);
defaults = _defaults;
}
assert(paramspec.totalReceived() <= 3); // would need to allocate oargs
} else {
RELEASE_ASSERT(0, "0x%x", flags);
}
......@@ -1549,8 +1571,8 @@ Box* BoxedCApiFunction::tppCall(Box* _self, CallRewriteArgs* rewrite_args, ArgPa
}
bool rewrite_success = false;
rearrangeArguments(paramspec, NULL, self->method_def->ml_name, NULL, rewrite_args, rewrite_success, argspec, arg1,
arg2, arg3, args, oargs, keyword_names);
rearrangeArguments(paramspec, NULL, self->method_def->ml_name, defaults, rewrite_args, rewrite_success, argspec,
arg1, arg2, arg3, args, oargs, keyword_names);
if (!rewrite_success)
rewrite_args = NULL;
......@@ -1578,6 +1600,22 @@ Box* BoxedCApiFunction::tppCall(Box* _self, CallRewriteArgs* rewrite_args, ArgPa
rtn = (Box*)func(self->passthrough, arg1);
if (rewrite_args)
rewrite_args->out_rtn = rewrite_args->rewriter->call(true, (void*)func, r_passthrough, rewrite_args->arg1);
} else if ((flags & ~(METH_O3 | METH_D3)) == 0) {
assert(paramspec.totalReceived() <= 3); // would need to pass through oargs
rtn = ((Box * (*)(Box*, Box*, Box*, Box*))func)(self->passthrough, arg1, arg2, arg3);
if (rewrite_args) {
if (paramspec.totalReceived() == 1)
rewrite_args->out_rtn
= rewrite_args->rewriter->call(true, (void*)func, r_passthrough, rewrite_args->arg1);
else if (paramspec.totalReceived() == 2)
rewrite_args->out_rtn = rewrite_args->rewriter->call(true, (void*)func, r_passthrough,
rewrite_args->arg1, rewrite_args->arg2);
else if (paramspec.totalReceived() == 3)
rewrite_args->out_rtn = rewrite_args->rewriter->call(
true, (void*)func, r_passthrough, rewrite_args->arg1, rewrite_args->arg2, rewrite_args->arg3);
else
abort();
}
} else if (flags == METH_OLDARGS) {
/* the really old style */
......
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