Commit bd39c49a authored by Boxiang Sun's avatar Boxiang Sun

Switch to CPython list sort

Comment out some part of listobject.c, use the CPython list sort and
apply some changes to existed Pyston code.
parent d84105ff
......@@ -8,6 +8,8 @@
#include <sys/types.h> /* For size_t */
#endif
// Pyston change: comment this out, Pyston do not use these for now
#if 0
/* Ensure ob_item has room for at least newsize elements, and set
* ob_size to newsize. If newsize > ob_size on entry, the content
* of the new slots at exit is undefined heap trash; it's the caller's
......@@ -960,6 +962,7 @@ listpop(PyListObject *self, PyObject *args)
return v;
}
#endif
/* Reverse a slice of a list in place, from lo up to (exclusive) hi. */
static void
......@@ -1880,7 +1883,9 @@ static void
sortwrapper_dealloc(sortwrapperobject *);
static PyTypeObject sortwrapper_type = {
PyVarObject_HEAD_INIT(&PyType_Type, 0)
// Pyston change:
// PyVarObject_HEAD_INIT(&PyType_Type, 0)
PyVarObject_HEAD_INIT(NULL, 0)
"sortwrapper", /* tp_name */
sizeof(sortwrapperobject), /* tp_basicsize */
0, /* tp_itemsize */
......@@ -1997,7 +2002,9 @@ cmpwrapper_call(cmpwrapperobject *co, PyObject *args, PyObject *kwds)
PyDoc_STRVAR(cmpwrapper_doc, "cmp() wrapper for sort with custom keys.");
static PyTypeObject cmpwrapper_type = {
PyVarObject_HEAD_INIT(&PyType_Type, 0)
// Pyston change:
// PyVarObject_HEAD_INIT(&PyType_Type, 0)
PyVarObject_HEAD_INIT(NULL, 0)
"cmpwrapper", /* tp_name */
sizeof(cmpwrapperobject), /* tp_basicsize */
0, /* tp_itemsize */
......@@ -2039,7 +2046,8 @@ build_cmpwrapper(PyObject *cmpfunc)
* list will be some permutation of its input state (nothing is lost or
* duplicated).
*/
static PyObject *
// pyston change: make not static
PyObject *
listsort(PyListObject *self, PyObject *args, PyObject *kwds)
{
MergeState ms;
......@@ -2202,7 +2210,9 @@ dsu_fail:
while (--i >= 0) {
Py_XDECREF(final_ob_item[i]);
}
PyMem_FREE(final_ob_item);
// Pyston change:
// PyMem_FREE(final_ob_item);
PyObject_Free(final_ob_item);
}
Py_XDECREF(compare);
Py_XINCREF(result);
......@@ -2233,6 +2243,8 @@ listreverse(PyListObject *self)
Py_RETURN_NONE;
}
// Pyston change: comment this out
#if 0
int
PyList_Reverse(PyObject *v)
{
......@@ -3042,3 +3054,5 @@ listreviter_len(listreviterobject *it)
len = 0;
return PyLong_FromSsize_t(len);
}
// pyston change:
#endif
......@@ -452,17 +452,44 @@ Box* notimplementedRepr(Box* self) {
return boxString("NotImplemented");
}
Box* sorted(Box* obj, Box* cmp, Box* key, Box** args) {
Box* reverse = args[0];
// Copied from CPython with some minor modifications
static PyObject* builtin_sorted(PyObject* self, PyObject* args, PyObject* kwds) {
PyObject* newlist, *v, *seq, * compare = NULL, * keyfunc = NULL, *newargs;
PyObject* callable;
static const char* kwlist[] = { "iterable", "cmp", "key", "reverse", 0 };
int reverse;
/* args 1-4 should match listsort in Objects/listobject.c */
if (!PyArg_ParseTupleAndKeywords(args, kwds, "O|OOi:sorted", const_cast<char**>(kwlist), &seq, &compare, &keyfunc,
&reverse))
return NULL;
BoxedList* rtn = new BoxedList();
AUTO_DECREF(rtn);
for (Box* e : obj->pyElements()) {
listAppendInternalStolen(rtn, e);
newlist = PySequence_List(seq);
if (newlist == NULL)
return NULL;
callable = PyObject_GetAttrString(newlist, "sort");
if (callable == NULL) {
Py_DECREF(newlist);
return NULL;
}
listSort(rtn, cmp, key, reverse);
return incref(rtn);
newargs = PyTuple_GetSlice(args, 1, 4);
if (newargs == NULL) {
Py_DECREF(newlist);
Py_DECREF(callable);
return NULL;
}
v = PyObject_Call(callable, newargs, kwds);
Py_DECREF(newargs);
Py_DECREF(callable);
if (v == NULL) {
Py_DECREF(newlist);
return NULL;
}
Py_DECREF(v);
return newlist;
}
Box* isinstance_func(Box* obj, Box* cls) {
......@@ -2487,13 +2514,6 @@ void setupBuiltins() {
enumerate_cls->tp_iter = PyObject_SelfIter;
builtins_module->giveAttrBorrowed("enumerate", enumerate_cls);
FunctionMetadata* sorted_func
= new FunctionMetadata(4, false, false, ParamNames({ "", "cmp", "key", "reverse" }, "", ""));
sorted_func->addVersion((void*)sorted, LIST, { UNKNOWN, UNKNOWN, UNKNOWN, UNKNOWN });
builtins_module->giveAttr("sorted", new BoxedBuiltinFunctionOrMethod(
sorted_func, "sorted", { Py_None, Py_None, Py_False }, NULL, sorted_doc));
builtins_module->giveAttrBorrowed("True", Py_True);
builtins_module->giveAttrBorrowed("False", Py_False);
......@@ -2611,6 +2631,7 @@ void setupBuiltins() {
{ "oct", builtin_oct, METH_O, oct_doc },
{ "print", (PyCFunction)builtin_print, METH_VARARGS | METH_KEYWORDS, print_doc },
{ "reload", builtin_reload, METH_O, reload_doc },
{ "sorted", (PyCFunction)builtin_sorted, METH_VARARGS | METH_KEYWORDS, sorted_doc },
};
for (auto& md : builtin_methods) {
builtins_module->giveAttr(md.ml_name, new BoxedCApiFunction(&md, NULL, autoDecref(boxString("__builtin__"))));
......
......@@ -17,6 +17,7 @@
#include <algorithm>
#include <cstring>
#include "capi/typeobject.h"
#include "capi/types.h"
#include "core/ast.h"
#include "core/common.h"
......@@ -27,6 +28,8 @@
#include "runtime/types.h"
#include "runtime/util.h"
extern "C" PyObject* listsort(PyListObject* self, PyObject* args, PyObject* kwds) noexcept;
namespace pyston {
static int list_ass_slice(PyListObject* a, Py_ssize_t ilow, Py_ssize_t ihigh, PyObject* v);
......@@ -991,64 +994,6 @@ void _sortArray(Box** elts, long num_elts, Box* cmp, Box* key) {
}
}
void listSort(BoxedList* self, Box* cmp, Box* key, Box* reverse) {
assert(PyList_Check(self));
if (cmp == Py_None)
cmp = NULL;
if (key == Py_None)
key = NULL;
RELEASE_ASSERT(!cmp || !key, "Specifying both the 'cmp' and 'key' keywords is currently not supported");
auto orig_size = self->size;
auto orig_elts = self->elts;
self->elts = new (0) GCdArray();
self->size = 0;
try {
_sortArray(orig_elts->elts, orig_size, cmp, key);
} catch (ExcInfo e) {
delete self->elts;
self->elts = orig_elts;
self->size = orig_size;
throw e;
}
delete self->elts;
self->elts = orig_elts;
self->size = orig_size;
if (nonzero(reverse)) {
Box* r = listReverse(self);
Py_DECREF(r);
}
}
Box* listSortFunc(BoxedList* self, Box* cmp, Box* key, Box** _args) {
Box* reverse = _args[0];
listSort(self, cmp, key, reverse);
Py_RETURN_NONE;
}
extern "C" int PyList_Sort(PyObject* v) noexcept {
if (v == NULL || !PyList_Check(v)) {
PyErr_BadInternalCall();
return -1;
}
try {
listSort((BoxedList*)v, Py_None, Py_None, Py_False);
} catch (ExcInfo e) {
setCAPIException(e);
return -1;
}
return 0;
}
extern "C" Box* PyList_GetSlice(PyObject* a, Py_ssize_t ilow, Py_ssize_t ihigh) noexcept {
assert(PyList_Check(a));
BoxedList* self = static_cast<BoxedList*>(a);
......@@ -1495,6 +1440,12 @@ int BoxedList::clear(Box* _a) noexcept {
return 0;
}
PyDoc_STRVAR(sort_doc, "L.sort(cmp=None, key=None, reverse=False) -- stable sort *IN PLACE*;\n\
cmp(x, y) -> -1, 0, 1");
static PyMethodDef list_methods[]
= { { "sort", (PyCFunction)listsort, METH_VARARGS | METH_KEYWORDS, sort_doc }, { NULL, NULL, 0, NULL } };
void setupList() {
static PySequenceMethods list_as_sequence;
list_cls->tp_as_sequence = &list_as_sequence;
......@@ -1568,10 +1519,6 @@ void setupList() {
list_cls->giveAttr("__iadd__", new BoxedFunction(FunctionMetadata::create((void*)listIAdd, UNKNOWN, 2)));
list_cls->giveAttr("__add__", new BoxedFunction(FunctionMetadata::create((void*)listAdd, UNKNOWN, 2)));
list_cls->giveAttr("sort",
new BoxedFunction(FunctionMetadata::create((void*)listSortFunc, NONE, 4, false, false,
ParamNames({ "", "cmp", "key", "reverse" }, "", "")),
{ Py_None, Py_None, Py_False }));
list_cls->giveAttr("__contains__", new BoxedFunction(FunctionMetadata::create((void*)listContains, BOXED_BOOL, 2)));
list_cls->giveAttr(
......@@ -1585,6 +1532,7 @@ void setupList() {
list_cls->giveAttr("reverse", new BoxedFunction(FunctionMetadata::create((void*)listReverse, NONE, 1)));
list_cls->giveAttrBorrowed("__hash__", Py_None);
add_methods(list_cls, list_methods);
list_cls->freeze();
list_cls->tp_iter = listIter;
list_cls->tp_repr = list_repr;
......
......@@ -51,7 +51,6 @@ Box* listreviterHasnext(Box* self);
llvm_compat_bool listreviterHasnextUnboxed(Box* self);
Box* listreviterNext(Box* self);
Box* listreviter_next(Box* s) noexcept;
void listSort(BoxedList* self, Box* cmp, Box* key, Box* reverse);
extern "C" Box* listAppend(Box* self, Box* v);
}
......
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