Commit 4480e933 authored by Kevin Modzelewski's avatar Kevin Modzelewski

Merge branch 'django_dependencies'

parents 3ec5c835 4c729f7b
......@@ -293,7 +293,7 @@ STDLIB_RELEASE_OBJS := stdlib.release.bc.o
ASM_SRCS := $(wildcard src/runtime/*.S)
STDMODULE_SRCS := errnomodule.c shamodule.c sha256module.c sha512module.c _math.c mathmodule.c md5.c md5module.c _randommodule.c _sre.c operator.c binascii.c pwdmodule.c posixmodule.c _struct.c datetimemodule.c _functoolsmodule.c _collectionsmodule.c itertoolsmodule.c resource.c signalmodule.c selectmodule.c fcntlmodule.c timemodule.c arraymodule.c zlibmodule.c _codecsmodule.c socketmodule.c unicodedata.c _weakref.c cStringIO.c _io/bufferedio.c _io/bytesio.c _io/fileio.c _io/iobase.c _io/_iomodule.c _io/stringio.c _io/textio.c $(EXTRA_STDMODULE_SRCS)
STDOBJECT_SRCS := structseq.c capsule.c stringobject.c exceptions.c unicodeobject.c unicodectype.c bytearrayobject.c bytes_methods.c weakrefobject.c memoryobject.c $(EXTRA_STDOBJECT_SRCS)
STDOBJECT_SRCS := structseq.c capsule.c stringobject.c exceptions.c unicodeobject.c unicodectype.c bytearrayobject.c bytes_methods.c weakrefobject.c memoryobject.c iterobject.c $(EXTRA_STDOBJECT_SRCS)
STDPYTHON_SRCS := pyctype.c getargs.c formatter_string.c pystrtod.c dtoa.c formatter_unicode.c structmember.c $(EXTRA_STDPYTHON_SRCS)
FROM_CPYTHON_SRCS := $(addprefix from_cpython/Modules/,$(STDMODULE_SRCS)) $(addprefix from_cpython/Objects/,$(STDOBJECT_SRCS)) $(addprefix from_cpython/Python/,$(STDPYTHON_SRCS))
......
......@@ -18,7 +18,7 @@ add_custom_target(copy_stdlib ALL DEPENDS ${STDLIB_TARGETS})
file(GLOB_RECURSE STDMODULE_SRCS Modules errnomodule.c shamodule.c sha256module.c sha512module.c _math.c mathmodule.c md5.c md5module.c _randommodule.c _sre.c operator.c binascii.c pwdmodule.c posixmodule.c _struct.c datetimemodule.c _functoolsmodule.c _collectionsmodule.c itertoolsmodule.c resource.c signalmodule.c selectmodule.c fcntlmodule.c timemodule.c arraymodule.c zlibmodule.c _codecsmodule.c socketmodule.c unicodedata.c _weakref.c cStringIO.c bufferedio.c bytesio.c fileio.c iobase.c _iomodule.c stringio.c textio.c)
# compile specified files in from_cpython/Objects
file(GLOB_RECURSE STDOBJECT_SRCS Objects structseq.c capsule.c stringobject.c exceptions.c unicodeobject.c unicodectype.c bytearrayobject.c bytes_methods.c weakrefobject.c memoryobject.c)
file(GLOB_RECURSE STDOBJECT_SRCS Objects structseq.c capsule.c stringobject.c exceptions.c unicodeobject.c unicodectype.c bytearrayobject.c bytes_methods.c weakrefobject.c memoryobject.c iterobject.c)
# compile specified files in from_cpython/Python
file(GLOB_RECURSE STDPYTHON_SRCS Python getargs.c pyctype.c formatter_string.c pystrtod.c dtoa.c formatter_unicode.c structmember.c)
......
......@@ -14,8 +14,7 @@ extern "C" {
PyAPI_FUNC(PyObject *) PySeqIter_New(PyObject *) PYSTON_NOEXCEPT;
// Pyston change: this is no longer a static object
//PyAPI_DATA(PyTypeObject) PyCallIter_Type;
PyAPI_DATA(PyTypeObject) PyCallIter_Type;
#define PyCallIter_Check(op) (Py_TYPE(op) == &PyCallIter_Type)
......
// This file is originally from CPython 2.7, with modifications for Pyston
// (actually it's just a subset of the CPython version)
#include "Python.h"
extern PyTypeObject PyCallIter_Type;
typedef struct {
PyObject_HEAD
PyObject *it_callable; /* Set to NULL when iterator is exhausted */
PyObject *it_sentinel; /* Set to NULL when iterator is exhausted */
} calliterobject;
PyObject *
PyCallIter_New(PyObject *callable, PyObject *sentinel)
{
calliterobject *it;
it = PyObject_GC_New(calliterobject, &PyCallIter_Type);
if (it == NULL)
return NULL;
Py_INCREF(callable);
it->it_callable = callable;
Py_INCREF(sentinel);
it->it_sentinel = sentinel;
_PyObject_GC_TRACK(it);
return (PyObject *)it;
}
static void
calliter_dealloc(calliterobject *it)
{
_PyObject_GC_UNTRACK(it);
Py_XDECREF(it->it_callable);
Py_XDECREF(it->it_sentinel);
PyObject_GC_Del(it);
}
static int
calliter_traverse(calliterobject *it, visitproc visit, void *arg)
{
Py_VISIT(it->it_callable);
Py_VISIT(it->it_sentinel);
return 0;
}
static PyObject *
calliter_iternext(calliterobject *it)
{
if (it->it_callable != NULL) {
PyObject *args = PyTuple_New(0);
PyObject *result;
if (args == NULL)
return NULL;
result = PyObject_Call(it->it_callable, args, NULL);
Py_DECREF(args);
if (result != NULL) {
int ok;
ok = PyObject_RichCompareBool(result,
it->it_sentinel,
Py_EQ);
if (ok == 0)
return result; /* Common case, fast path */
Py_DECREF(result);
if (ok > 0) {
Py_CLEAR(it->it_callable);
Py_CLEAR(it->it_sentinel);
}
}
else if (PyErr_ExceptionMatches(PyExc_StopIteration)) {
PyErr_Clear();
Py_CLEAR(it->it_callable);
Py_CLEAR(it->it_sentinel);
}
}
return NULL;
}
PyTypeObject PyCallIter_Type = {
// Pyston change:
PyVarObject_HEAD_INIT(NULL /* &PyType_Type */, 0)
"callable-iterator", /* tp_name */
sizeof(calliterobject), /* tp_basicsize */
0, /* tp_itemsize */
/* methods */
(destructor)calliter_dealloc, /* tp_dealloc */
0, /* tp_print */
0, /* tp_getattr */
0, /* tp_setattr */
0, /* tp_compare */
0, /* tp_repr */
0, /* tp_as_number */
0, /* tp_as_sequence */
0, /* tp_as_mapping */
0, /* tp_hash */
0, /* tp_call */
0, /* tp_str */
PyObject_GenericGetAttr, /* tp_getattro */
0, /* tp_setattro */
0, /* tp_as_buffer */
Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC,/* tp_flags */
0, /* tp_doc */
(traverseproc)calliter_traverse, /* tp_traverse */
0, /* tp_clear */
0, /* tp_richcompare */
0, /* tp_weaklistoffset */
PyObject_SelfIter, /* tp_iter */
(iternextfunc)calliter_iternext, /* tp_iternext */
0, /* tp_methods */
};
......@@ -407,6 +407,8 @@ public:
for (AST_comprehension* c : node->generators) {
if (!first)
c->iter->accept(this);
for (auto i : c->ifs)
i->accept(this);
c->target->accept(this);
first = false;
}
......
......@@ -135,7 +135,9 @@ extern "C" void PyBuffer_Release(Py_buffer* view) noexcept {
PyObject* obj = view->obj;
if (obj) {
assert(obj->cls == str_cls);
// This is a Pyston assert
assert(isSubclass(obj->cls, str_cls));
if (obj && Py_TYPE(obj)->tp_as_buffer && Py_TYPE(obj)->tp_as_buffer->bf_releasebuffer)
Py_TYPE(obj)->tp_as_buffer->bf_releasebuffer(obj, view);
Py_XDECREF(obj);
......
......@@ -45,23 +45,28 @@
#error
#endif
using namespace pyston;
namespace pyston {
// returns true iff we got a request to exit, i.e. SystemExit, placing the
// return code in `*retcode`. does not touch `*retcode* if it returns false.
static bool handle_toplevel_exn(const ExcInfo& e, int* retcode) {
if (e.matches(SystemExit)) {
Box* code = e.value->getattr("code");
*retcode = 1;
if (code && isSubclass(code->cls, pyston::int_cls))
if (!code || code == None)
*retcode = 0;
else if (isSubclass(code->cls, int_cls))
*retcode = static_cast<BoxedInt*>(code)->n;
else
*retcode = 1;
return true;
}
e.printExcAndTraceback();
return false;
}
int main(int argc, char** argv) {
static int main(int argc, char** argv) {
Timer _t("for jit startup");
// llvm::sys::PrintStackTraceOnErrorSignal();
// llvm::PrettyStackTraceProgram X(argc, argv);
......@@ -259,3 +264,9 @@ int main(int argc, char** argv) {
return rtncode;
}
} // namespace pyston
int main(int argc, char** argv) {
return pyston::main(argc, argv);
}
......@@ -852,10 +852,6 @@ extern "C" PyObject* PyImport_Import(PyObject* module_name) noexcept {
}
extern "C" PyObject* PyCallIter_New(PyObject* callable, PyObject* sentinel) noexcept {
Py_FatalError("unimplemented");
}
extern "C" void* PyObject_Malloc(size_t sz) noexcept {
return gc_compat_malloc(sz);
}
......
......@@ -57,6 +57,7 @@ public:
Box* dictViewKeysIter(Box* self);
Box* dictViewValuesIter(Box* self);
Box* dictViewItemsIter(Box* self);
void dictMerge(BoxedDict* self, Box* other);
}
#endif
......@@ -1055,14 +1055,27 @@ extern "C" size_t Py_UniversalNewlineFread(char* buf, size_t n, FILE* stream, Py
return dst - buf;
}
static PyObject* file_isatty(BoxedFile* f) noexcept {
long res;
if (f->f_fp == NULL)
return err_closed();
FILE_BEGIN_ALLOW_THREADS(f)
res = isatty((int)fileno(f->f_fp));
FILE_END_ALLOW_THREADS(f)
return PyBool_FromLong(res);
}
PyDoc_STRVAR(readlines_doc, "readlines([size]) -> list of strings, each a line from the file.\n"
"\n"
"Call readline() repeatedly and return a list of the lines so read.\n"
"The optional size argument, if given, is an approximate bound on the\n"
"total number of bytes in the lines returned.");
PyDoc_STRVAR(isatty_doc, "isatty() -> true or false. True if the file is connected to a tty device.");
PyMethodDef file_methods[] = {
{ "readlines", (PyCFunction)file_readlines, METH_VARARGS, readlines_doc },
{ "isatty", (PyCFunction)file_isatty, METH_NOARGS, isatty_doc },
};
void fileDestructor(Box* b) {
......
......@@ -87,6 +87,8 @@ extern "C" Box* floatAdd(BoxedFloat* lhs, Box* rhs) {
return floatAddInt(lhs, static_cast<BoxedInt*>(rhs));
} else if (rhs->cls == float_cls) {
return floatAddFloat(lhs, static_cast<BoxedFloat*>(rhs));
} else if (rhs->cls == long_cls) {
return boxFloat(lhs->d + PyLong_AsDouble(rhs));
} else {
return NotImplemented;
}
......@@ -112,6 +114,8 @@ extern "C" Box* floatDiv(BoxedFloat* lhs, Box* rhs) {
return floatDivInt(lhs, static_cast<BoxedInt*>(rhs));
} else if (rhs->cls == float_cls) {
return floatDivFloat(lhs, static_cast<BoxedFloat*>(rhs));
} else if (rhs->cls == long_cls) {
return boxFloat(lhs->d / PyLong_AsDouble(rhs));
} else {
return NotImplemented;
}
......@@ -123,6 +127,8 @@ extern "C" Box* floatTruediv(BoxedFloat* lhs, Box* rhs) {
return floatDivInt(lhs, static_cast<BoxedInt*>(rhs));
} else if (rhs->cls == float_cls) {
return floatDivFloat(lhs, static_cast<BoxedFloat*>(rhs));
} else if (rhs->cls == long_cls) {
return boxFloat(lhs->d / PyLong_AsDouble(rhs));
} else {
return NotImplemented;
}
......@@ -148,6 +154,8 @@ extern "C" Box* floatRDiv(BoxedFloat* lhs, Box* rhs) {
return floatRDivInt(lhs, static_cast<BoxedInt*>(rhs));
} else if (rhs->cls == float_cls) {
return floatRDivFloat(lhs, static_cast<BoxedFloat*>(rhs));
} else if (rhs->cls == long_cls) {
return boxFloat(PyLong_AsDouble(rhs) / lhs->d);
} else {
return NotImplemented;
}
......@@ -196,6 +204,8 @@ extern "C" Box* floatEq(BoxedFloat* lhs, Box* rhs) {
return floatEqInt(lhs, static_cast<BoxedInt*>(rhs));
} else if (rhs->cls == float_cls) {
return floatEqFloat(lhs, static_cast<BoxedFloat*>(rhs));
} else if (rhs->cls == long_cls) {
return boxBool(lhs->d == PyLong_AsDouble(rhs));
} else {
return NotImplemented;
}
......@@ -219,6 +229,8 @@ extern "C" Box* floatNe(BoxedFloat* lhs, Box* rhs) {
return floatNeInt(lhs, static_cast<BoxedInt*>(rhs));
} else if (rhs->cls == float_cls) {
return floatNeFloat(lhs, static_cast<BoxedFloat*>(rhs));
} else if (rhs->cls == long_cls) {
return boxBool(lhs->d != PyLong_AsDouble(rhs));
} else {
return NotImplemented;
}
......@@ -242,6 +254,8 @@ extern "C" Box* floatLt(BoxedFloat* lhs, Box* rhs) {
return floatLtInt(lhs, static_cast<BoxedInt*>(rhs));
} else if (rhs->cls == float_cls) {
return floatLtFloat(lhs, static_cast<BoxedFloat*>(rhs));
} else if (rhs->cls == long_cls) {
return boxBool(lhs->d < PyLong_AsDouble(rhs));
} else {
return NotImplemented;
}
......@@ -265,6 +279,8 @@ extern "C" Box* floatLe(BoxedFloat* lhs, Box* rhs) {
return floatLeInt(lhs, static_cast<BoxedInt*>(rhs));
} else if (rhs->cls == float_cls) {
return floatLeFloat(lhs, static_cast<BoxedFloat*>(rhs));
} else if (rhs->cls == long_cls) {
return boxBool(lhs->d <= PyLong_AsDouble(rhs));
} else {
return NotImplemented;
}
......@@ -288,6 +304,8 @@ extern "C" Box* floatGt(BoxedFloat* lhs, Box* rhs) {
return floatGtInt(lhs, static_cast<BoxedInt*>(rhs));
} else if (rhs->cls == float_cls) {
return floatGtFloat(lhs, static_cast<BoxedFloat*>(rhs));
} else if (rhs->cls == long_cls) {
return boxBool(lhs->d > PyLong_AsDouble(rhs));
} else {
return NotImplemented;
}
......@@ -311,6 +329,8 @@ extern "C" Box* floatGe(BoxedFloat* lhs, Box* rhs) {
return floatGeInt(lhs, static_cast<BoxedInt*>(rhs));
} else if (rhs->cls == float_cls) {
return floatGeFloat(lhs, static_cast<BoxedFloat*>(rhs));
} else if (rhs->cls == long_cls) {
return boxBool(lhs->d >= PyLong_AsDouble(rhs));
} else {
return NotImplemented;
}
......@@ -334,6 +354,8 @@ extern "C" Box* floatMod(BoxedFloat* lhs, Box* rhs) {
return floatModInt(lhs, static_cast<BoxedInt*>(rhs));
} else if (rhs->cls == float_cls) {
return floatModFloat(lhs, static_cast<BoxedFloat*>(rhs));
} else if (rhs->cls == long_cls) {
return boxFloat(mod_float_float(lhs->d, PyLong_AsDouble(rhs)));
} else {
return NotImplemented;
}
......@@ -357,6 +379,8 @@ extern "C" Box* floatRMod(BoxedFloat* lhs, Box* rhs) {
return floatRModInt(lhs, static_cast<BoxedInt*>(rhs));
} else if (rhs->cls == float_cls) {
return floatRModFloat(lhs, static_cast<BoxedFloat*>(rhs));
} else if (rhs->cls == long_cls) {
return boxFloat(mod_float_float(PyLong_AsDouble(rhs), lhs->d));
} else {
return NotImplemented;
}
......@@ -380,6 +404,8 @@ extern "C" Box* floatPow(BoxedFloat* lhs, Box* rhs) {
return floatPowInt(lhs, static_cast<BoxedInt*>(rhs));
} else if (rhs->cls == float_cls) {
return floatPowFloat(lhs, static_cast<BoxedFloat*>(rhs));
} else if (rhs->cls == long_cls) {
return boxFloat(pow(lhs->d, PyLong_AsDouble(rhs)));
} else {
return NotImplemented;
}
......@@ -403,6 +429,8 @@ extern "C" Box* floatMul(BoxedFloat* lhs, Box* rhs) {
return floatMulInt(lhs, static_cast<BoxedInt*>(rhs));
} else if (rhs->cls == float_cls) {
return floatMulFloat(lhs, static_cast<BoxedFloat*>(rhs));
} else if (rhs->cls == long_cls) {
return boxFloat(lhs->d * PyLong_AsDouble(rhs));
} else {
return NotImplemented;
}
......@@ -426,6 +454,8 @@ extern "C" Box* floatSub(BoxedFloat* lhs, Box* rhs) {
return floatSubInt(lhs, static_cast<BoxedInt*>(rhs));
} else if (rhs->cls == float_cls) {
return floatSubFloat(lhs, static_cast<BoxedFloat*>(rhs));
} else if (rhs->cls == long_cls) {
return boxFloat(lhs->d - PyLong_AsDouble(rhs));
} else {
return NotImplemented;
}
......@@ -449,6 +479,8 @@ extern "C" Box* floatRSub(BoxedFloat* lhs, Box* rhs) {
return floatRSubInt(lhs, static_cast<BoxedInt*>(rhs));
} else if (rhs->cls == float_cls) {
return floatRSubFloat(lhs, static_cast<BoxedFloat*>(rhs));
} else if (rhs->cls == long_cls) {
return boxFloat(PyLong_AsDouble(rhs) - lhs->d);
} else {
return NotImplemented;
}
......@@ -545,6 +577,9 @@ std::string floatFmt(double x, int precision, char code) {
}
BoxedFloat* _floatNew(Box* a) {
// FIXME CPython uses PyUnicode_EncodeDecimal:
a = coerceUnicodeToStr(a);
if (a->cls == float_cls) {
return static_cast<BoxedFloat*>(a);
} else if (isSubclass(a->cls, float_cls)) {
......
......@@ -41,6 +41,7 @@
#include "gc/heap.h"
#include "runtime/capi.h"
#include "runtime/classobj.h"
#include "runtime/dict.h"
#include "runtime/file.h"
#include "runtime/float.h"
#include "runtime/generator.h"
......@@ -303,6 +304,9 @@ BoxedClass::BoxedClass(BoxedClass* base, gcvisit_func gc_visit, int attrs_offset
tp_flags |= Py_TPFLAGS_HAVE_GC;
tp_flags |= Py_TPFLAGS_HAVE_WEAKREFS;
if (base && (base->tp_flags & Py_TPFLAGS_HAVE_NEWBUFFER))
tp_flags |= Py_TPFLAGS_HAVE_NEWBUFFER;
tp_base = base;
if (tp_base) {
......@@ -1940,7 +1944,7 @@ extern "C" BoxedInt* hash(Box* obj) {
Box* hash = getclsattr_internal(obj, "__hash__", NULL);
if (hash == NULL) {
ASSERT(isUserDefined(obj->cls), "%s.__hash__", getTypeName(obj));
ASSERT(isUserDefined(obj->cls) || obj->cls == function_cls, "%s.__hash__", getTypeName(obj));
// TODO not the best way to handle this...
return static_cast<BoxedInt*>(boxInt((i64)obj));
}
......@@ -2693,7 +2697,13 @@ Box* callFunc(BoxedFunctionBase* func, CallRewriteArgs* rewrite_args, ArgPassSpe
Box* kwargs
= getArg(argspec.num_args + argspec.num_keywords + (argspec.has_starargs ? 1 : 0), arg1, arg2, arg3, args);
RELEASE_ASSERT(kwargs->cls == dict_cls, "haven't implemented this for non-dicts");
if (!isSubclass(kwargs->cls, dict_cls)) {
BoxedDict* d = new BoxedDict();
dictMerge(d, kwargs);
kwargs = d;
}
assert(isSubclass(kwargs->cls, dict_cls));
BoxedDict* d_kwargs = static_cast<BoxedDict*>(kwargs);
for (auto& p : d_kwargs->d) {
......@@ -3288,6 +3298,7 @@ Box* compareInternal(Box* lhs, Box* rhs, int op_type, CompareRewriteArgs* rewrit
#ifndef NDEBUG
if ((lhs->cls == int_cls || lhs->cls == float_cls || lhs->cls == long_cls)
&& (rhs->cls == int_cls || rhs->cls == float_cls || rhs->cls == long_cls)) {
printf("\n%s %s %s\n", lhs->cls->tp_name, op_name.c_str(), rhs->cls->tp_name);
Py_FatalError("missing comparison between these classes");
}
#endif
......
......@@ -296,7 +296,7 @@ extern "C" PyObject* PyString_FromFormat(const char* format, ...) noexcept {
}
extern "C" Box* strAdd(BoxedString* lhs, Box* _rhs) {
assert(lhs->cls == str_cls);
assert(isSubclass(lhs->cls, str_cls));
if (_rhs->cls == unicode_cls) {
Box* rtn = PyUnicode_Concat(lhs, _rhs);
......@@ -934,7 +934,7 @@ extern "C" Box* strMod(BoxedString* lhs, Box* rhs) {
}
extern "C" Box* strMul(BoxedString* lhs, Box* rhs) {
assert(lhs->cls == str_cls);
assert(isSubclass(lhs->cls, str_cls));
int n;
if (isSubclass(rhs->cls, int_cls))
......@@ -952,7 +952,7 @@ extern "C" Box* strMul(BoxedString* lhs, Box* rhs) {
}
extern "C" Box* strLt(BoxedString* lhs, Box* rhs) {
assert(lhs->cls == str_cls);
assert(isSubclass(lhs->cls, str_cls));
if (rhs->cls != str_cls)
return NotImplemented;
......@@ -962,7 +962,7 @@ extern "C" Box* strLt(BoxedString* lhs, Box* rhs) {
}
extern "C" Box* strLe(BoxedString* lhs, Box* rhs) {
assert(lhs->cls == str_cls);
assert(isSubclass(lhs->cls, str_cls));
if (rhs->cls != str_cls)
return NotImplemented;
......@@ -972,7 +972,7 @@ extern "C" Box* strLe(BoxedString* lhs, Box* rhs) {
}
extern "C" Box* strGt(BoxedString* lhs, Box* rhs) {
assert(lhs->cls == str_cls);
assert(isSubclass(lhs->cls, str_cls));
if (rhs->cls != str_cls)
return NotImplemented;
......@@ -982,7 +982,7 @@ extern "C" Box* strGt(BoxedString* lhs, Box* rhs) {
}
extern "C" Box* strGe(BoxedString* lhs, Box* rhs) {
assert(lhs->cls == str_cls);
assert(isSubclass(lhs->cls, str_cls));
if (rhs->cls != str_cls)
return NotImplemented;
......@@ -992,7 +992,7 @@ extern "C" Box* strGe(BoxedString* lhs, Box* rhs) {
}
extern "C" Box* strEq(BoxedString* lhs, Box* rhs) {
assert(lhs->cls == str_cls);
assert(isSubclass(lhs->cls, str_cls));
if (rhs->cls != str_cls)
return NotImplemented;
......@@ -1002,7 +1002,7 @@ extern "C" Box* strEq(BoxedString* lhs, Box* rhs) {
}
extern "C" Box* strNe(BoxedString* lhs, Box* rhs) {
assert(lhs->cls == str_cls);
assert(isSubclass(lhs->cls, str_cls));
if (rhs->cls != str_cls)
return NotImplemented;
......@@ -1016,7 +1016,7 @@ extern "C" Box* strNe(BoxedString* lhs, Box* rhs) {
#define JUST_CENTER 2
static Box* pad(BoxedString* self, Box* width, Box* fillchar, int justType) {
assert(width->cls == int_cls);
assert(fillchar->cls == str_cls);
assert(isSubclass(fillchar->cls, str_cls));
assert(static_cast<BoxedString*>(fillchar)->s.size() == 1);
int64_t curWidth = self->s.size();
int64_t targetWidth = static_cast<BoxedInt*>(width)->n;
......@@ -1067,13 +1067,13 @@ extern "C" Box* strCenter(BoxedString* lhs, Box* width, Box* fillchar) {
}
extern "C" Box* strLen(BoxedString* self) {
assert(self->cls == str_cls);
assert(isSubclass(self->cls, str_cls));
return boxInt(self->s.size());
}
extern "C" Box* strStr(BoxedString* self) {
assert(self->cls == str_cls);
assert(isSubclass(self->cls, str_cls));
return self;
}
......@@ -1099,7 +1099,7 @@ static char _hex[17] = "0123456789abcdef"; // really only needs to be 16 but cla
extern "C" PyObject* PyString_Repr(PyObject* obj, int smartquotes) noexcept {
BoxedString* self = (BoxedString*)obj;
assert(self->cls == str_cls);
assert(isSubclass(self->cls, str_cls));
std::ostringstream os("");
......@@ -1333,22 +1333,28 @@ failed:
}
extern "C" Box* strHash(BoxedString* self) {
assert(self->cls == str_cls);
assert(isSubclass(self->cls, str_cls));
std::hash<std::string> H;
return boxInt(H(self->s));
}
extern "C" Box* strNonzero(BoxedString* self) {
ASSERT(self->cls == str_cls, "%s", self->cls->tp_name);
ASSERT(isSubclass(self->cls, str_cls), "%s", self->cls->tp_name);
return boxBool(self->s.size() != 0);
}
extern "C" Box* strNew(BoxedClass* cls, Box* obj) {
assert(cls == str_cls);
assert(isSubclass(cls, str_cls));
return str(obj);
Box* rtn = str(obj);
assert(rtn->cls == str_cls);
if (cls == str_cls)
return rtn;
return new (cls) BoxedString(static_cast<BoxedString*>(rtn)->s);
}
extern "C" Box* basestringNew(BoxedClass* cls, Box* args, Box* kwargs) {
......@@ -1356,7 +1362,7 @@ extern "C" Box* basestringNew(BoxedClass* cls, Box* args, Box* kwargs) {
}
Box* _strSlice(BoxedString* self, i64 start, i64 stop, i64 step, i64 length) {
assert(self->cls == str_cls);
assert(isSubclass(self->cls, str_cls));
const std::string& s = self->s;
......@@ -1378,7 +1384,7 @@ Box* _strSlice(BoxedString* self, i64 start, i64 stop, i64 step, i64 length) {
}
Box* strIsAlpha(BoxedString* self) {
assert(self->cls == str_cls);
assert(isSubclass(self->cls, str_cls));
const std::string& str(self->s);
if (str.empty())
......@@ -1393,7 +1399,7 @@ Box* strIsAlpha(BoxedString* self) {
}
Box* strIsDigit(BoxedString* self) {
assert(self->cls == str_cls);
assert(isSubclass(self->cls, str_cls));
const std::string& str(self->s);
if (str.empty())
......@@ -1408,7 +1414,7 @@ Box* strIsDigit(BoxedString* self) {
}
Box* strIsAlnum(BoxedString* self) {
assert(self->cls == str_cls);
assert(isSubclass(self->cls, str_cls));
const std::string& str(self->s);
if (str.empty())
......@@ -1423,7 +1429,7 @@ Box* strIsAlnum(BoxedString* self) {
}
Box* strIsLower(BoxedString* self) {
assert(self->cls == str_cls);
assert(isSubclass(self->cls, str_cls));
const std::string& str(self->s);
bool lowered = false;
......@@ -1445,7 +1451,7 @@ Box* strIsLower(BoxedString* self) {
}
Box* strIsUpper(BoxedString* self) {
assert(self->cls == str_cls);
assert(isSubclass(self->cls, str_cls));
const std::string& str(self->s);
bool uppered = false;
......@@ -1467,7 +1473,7 @@ Box* strIsUpper(BoxedString* self) {
}
Box* strIsSpace(BoxedString* self) {
assert(self->cls == str_cls);
assert(isSubclass(self->cls, str_cls));
const std::string& str(self->s);
if (str.empty())
......@@ -1482,7 +1488,7 @@ Box* strIsSpace(BoxedString* self) {
}
Box* strIsTitle(BoxedString* self) {
assert(self->cls == str_cls);
assert(isSubclass(self->cls, str_cls));
const std::string& str(self->s);
......@@ -1517,7 +1523,7 @@ Box* strIsTitle(BoxedString* self) {
}
Box* strJoin(BoxedString* self, Box* rhs) {
assert(self->cls == str_cls);
assert(isSubclass(self->cls, str_cls));
std::string output_str;
llvm::raw_string_ostream os(output_str);
......@@ -1534,7 +1540,7 @@ Box* strJoin(BoxedString* self, Box* rhs) {
extern "C" PyObject* _PyString_Join(PyObject* sep, PyObject* x) noexcept {
try {
RELEASE_ASSERT(sep->cls == str_cls, "");
RELEASE_ASSERT(isSubclass(sep->cls, str_cls), "");
return strJoin((BoxedString*)sep, x);
} catch (ExcInfo e) {
setCAPIException(e);
......@@ -1548,6 +1554,11 @@ Box* strReplace(Box* _self, Box* _old, Box* _new, Box** _args) {
getTypeName(_self));
BoxedString* self = static_cast<BoxedString*>(_self);
#ifdef Py_USING_UNICODE
if (PyUnicode_Check(_old) || PyUnicode_Check(_new))
return PyUnicode_Replace((PyObject*)self, _old, _new, -1 /*count*/);
#endif
if (_old->cls != str_cls)
raiseExcHelper(TypeError, "expected a character buffer object");
BoxedString* old = static_cast<BoxedString*>(_old);
......@@ -1574,8 +1585,8 @@ Box* strReplace(Box* _self, Box* _old, Box* _new, Box** _args) {
}
Box* strPartition(BoxedString* self, BoxedString* sep) {
RELEASE_ASSERT(self->cls == str_cls, "");
RELEASE_ASSERT(sep->cls == str_cls, "");
RELEASE_ASSERT(isSubclass(self->cls, str_cls), "");
RELEASE_ASSERT(isSubclass(sep->cls, str_cls), "");
size_t found_idx = self->s.find(sep->s);
if (found_idx == std::string::npos)
......@@ -1601,11 +1612,11 @@ Box* strFormat(BoxedString* self, BoxedTuple* args, BoxedDict* kwargs) {
}
Box* strSplit(BoxedString* self, BoxedString* sep, BoxedInt* _max_split) {
assert(self->cls == str_cls);
assert(isSubclass(self->cls, str_cls));
if (_max_split->cls != int_cls)
raiseExcHelper(TypeError, "an integer is required");
if (sep->cls == str_cls) {
if (isSubclass(sep->cls, str_cls)) {
if (!sep->s.empty()) {
llvm::SmallVector<llvm::StringRef, 16> parts;
llvm::StringRef(self->s).split(parts, sep->s, _max_split->n);
......@@ -1642,9 +1653,9 @@ Box* strSplit(BoxedString* self, BoxedString* sep, BoxedInt* _max_split) {
}
Box* strStrip(BoxedString* self, Box* chars) {
assert(self->cls == str_cls);
assert(isSubclass(self->cls, str_cls));
if (chars->cls == str_cls) {
if (isSubclass(chars->cls, str_cls)) {
return new BoxedString(llvm::StringRef(self->s).trim(static_cast<BoxedString*>(chars)->s));
} else if (chars->cls == none_cls) {
return new BoxedString(llvm::StringRef(self->s).trim(" \t\n\r\f\v"));
......@@ -1654,9 +1665,9 @@ Box* strStrip(BoxedString* self, Box* chars) {
}
Box* strLStrip(BoxedString* self, Box* chars) {
assert(self->cls == str_cls);
assert(isSubclass(self->cls, str_cls));
if (chars->cls == str_cls) {
if (isSubclass(chars->cls, str_cls)) {
return new BoxedString(llvm::StringRef(self->s).ltrim(static_cast<BoxedString*>(chars)->s));
} else if (chars->cls == none_cls) {
return new BoxedString(llvm::StringRef(self->s).ltrim(" \t\n\r\f\v"));
......@@ -1666,9 +1677,9 @@ Box* strLStrip(BoxedString* self, Box* chars) {
}
Box* strRStrip(BoxedString* self, Box* chars) {
assert(self->cls == str_cls);
assert(isSubclass(self->cls, str_cls));
if (chars->cls == str_cls) {
if (isSubclass(chars->cls, str_cls)) {
return new BoxedString(llvm::StringRef(self->s).rtrim(static_cast<BoxedString*>(chars)->s));
} else if (chars->cls == none_cls) {
return new BoxedString(llvm::StringRef(self->s).rtrim(" \t\n\r\f\v"));
......@@ -1678,7 +1689,7 @@ Box* strRStrip(BoxedString* self, Box* chars) {
}
Box* strCapitalize(BoxedString* self) {
assert(self->cls == str_cls);
assert(isSubclass(self->cls, str_cls));
std::string s(self->s);
......@@ -1694,7 +1705,7 @@ Box* strCapitalize(BoxedString* self) {
}
Box* strTitle(BoxedString* self) {
assert(self->cls == str_cls);
assert(isSubclass(self->cls, str_cls));
std::string s(self->s);
bool start_of_word = false;
......@@ -1746,12 +1757,12 @@ Box* strTranslate(BoxedString* self, BoxedString* table, BoxedString* delete_cha
}
Box* strLower(BoxedString* self) {
assert(self->cls == str_cls);
assert(isSubclass(self->cls, str_cls));
return boxString(llvm::StringRef(self->s).lower());
}
Box* strUpper(BoxedString* self) {
assert(self->cls == str_cls);
assert(isSubclass(self->cls, str_cls));
return boxString(llvm::StringRef(self->s).upper());
}
......@@ -1769,7 +1780,7 @@ Box* strSwapcase(BoxedString* self) {
}
Box* strContains(BoxedString* self, Box* elt) {
assert(self->cls == str_cls);
assert(isSubclass(self->cls, str_cls));
if (PyUnicode_Check(elt)) {
int r = PyUnicode_Contains(self, elt);
......@@ -1796,9 +1807,6 @@ Box* strStartswith(BoxedString* self, Box* elt, Box* start, Box** _args) {
raiseExcHelper(TypeError, "descriptor 'startswith' requires a 'str' object but received a '%s'",
getTypeName(self));
if (elt->cls != str_cls)
raiseExcHelper(TypeError, "expected a character buffer object");
Py_ssize_t istart = 0, iend = PY_SSIZE_T_MAX;
if (start) {
int r = _PyEval_SliceIndex(start, &istart);
......@@ -1812,6 +1820,27 @@ Box* strStartswith(BoxedString* self, Box* elt, Box* start, Box** _args) {
throwCAPIException();
}
if (isSubclass(elt->cls, tuple_cls)) {
for (auto e : static_cast<BoxedTuple*>(elt)->elts) {
auto b = strStartswith(self, e, start, _args);
assert(b->cls == bool_cls);
if (b == True)
return True;
}
return False;
}
if (isSubclass(elt->cls, unicode_cls)) {
int r = PyUnicode_Tailmatch(self, elt, istart, iend, -1);
if (r < 0)
throwCAPIException();
assert(r == 0 || r == 1);
return boxBool(r);
}
if (elt->cls != str_cls)
raiseExcHelper(TypeError, "expected a character buffer object");
BoxedString* sub = static_cast<BoxedString*>(elt);
Py_ssize_t n = self->s.size();
......@@ -1841,9 +1870,6 @@ Box* strEndswith(BoxedString* self, Box* elt, Box* start, Box** _args) {
raiseExcHelper(TypeError, "descriptor 'endswith' requires a 'str' object but received a '%s'",
getTypeName(self));
if (elt->cls != str_cls)
raiseExcHelper(TypeError, "expected a character buffer object");
Py_ssize_t istart = 0, iend = PY_SSIZE_T_MAX;
if (start) {
int r = _PyEval_SliceIndex(start, &istart);
......@@ -1857,6 +1883,27 @@ Box* strEndswith(BoxedString* self, Box* elt, Box* start, Box** _args) {
throwCAPIException();
}
if (isSubclass(elt->cls, unicode_cls)) {
int r = PyUnicode_Tailmatch(self, elt, istart, iend, +1);
if (r < 0)
throwCAPIException();
assert(r == 0 || r == 1);
return boxBool(r);
}
if (isSubclass(elt->cls, tuple_cls)) {
for (auto e : static_cast<BoxedTuple*>(elt)->elts) {
auto b = strEndswith(self, e, start, _args);
assert(b->cls == bool_cls);
if (b == True)
return True;
}
return False;
}
if (elt->cls != str_cls)
raiseExcHelper(TypeError, "expected a character buffer object");
BoxedString* sub = static_cast<BoxedString*>(elt);
Py_ssize_t n = self->s.size();
......@@ -1920,7 +1967,7 @@ Box* strEncode(BoxedString* self, Box* encoding, Box* error) {
}
extern "C" Box* strGetitem(BoxedString* self, Box* slice) {
assert(self->cls == str_cls);
assert(isSubclass(self->cls, str_cls));
if (isSubclass(slice->cls, int_cls)) {
BoxedInt* islice = static_cast<BoxedInt*>(slice);
......@@ -1989,12 +2036,12 @@ extern "C" void strIteratorGCHandler(GCVisitor* v, Box* b) {
}
Box* strIter(BoxedString* self) {
assert(self->cls == str_cls);
assert(isSubclass(self->cls, str_cls));
return new BoxedStringIterator(self);
}
int64_t strCount2Unboxed(BoxedString* self, Box* elt) {
assert(self->cls == str_cls);
assert(isSubclass(self->cls, str_cls));
if (elt->cls != str_cls)
raiseExcHelper(TypeError, "expected a character buffer object");
......@@ -2020,7 +2067,7 @@ Box* strCount2(BoxedString* self, Box* elt) {
}
Box* strIndex(BoxedString* self, Box* elt) {
assert(self->cls == str_cls);
assert(isSubclass(self->cls, str_cls));
if (elt->cls != str_cls)
raiseExcHelper(TypeError, "expected a character buffer object");
......@@ -2094,14 +2141,14 @@ extern "C" PyObject* PyString_FromStringAndSize(const char* s, ssize_t n) noexce
}
extern "C" char* PyString_AsString(PyObject* o) noexcept {
RELEASE_ASSERT(o->cls == str_cls, "");
RELEASE_ASSERT(isSubclass(o->cls, str_cls), "");
BoxedString* s = static_cast<BoxedString*>(o);
return getWriteableStringContents(s);
}
extern "C" Py_ssize_t PyString_Size(PyObject* op) noexcept {
if (op->cls == str_cls)
if (isSubclass(op->cls, str_cls))
return static_cast<BoxedString*>(op)->s.size();
char* _s;
......@@ -2115,7 +2162,7 @@ extern "C" int _PyString_Resize(PyObject** pv, Py_ssize_t newsize) noexcept {
// This is only allowed to be called when there is only one user of the string (ie a refcount of 1 in CPython)
assert(pv);
assert((*pv)->cls == str_cls);
assert(isSubclass((*pv)->cls, str_cls));
BoxedString* s = static_cast<BoxedString*>(*pv);
s->s.resize(newsize, '\0');
return 0;
......@@ -2223,7 +2270,7 @@ static Py_ssize_t string_buffer_getreadbuf(PyObject* self, Py_ssize_t index, con
RELEASE_ASSERT(index == 0, "");
// I think maybe this can just be a non-release assert? shouldn't be able to call this with
// the wrong type
RELEASE_ASSERT(self->cls == str_cls, "");
RELEASE_ASSERT(isSubclass(self->cls, str_cls), "");
auto s = static_cast<BoxedString*>(self);
*ptr = s->s.c_str();
......@@ -2232,7 +2279,7 @@ static Py_ssize_t string_buffer_getreadbuf(PyObject* self, Py_ssize_t index, con
static Py_ssize_t string_buffer_getsegcount(PyObject* o, Py_ssize_t* lenp) noexcept {
RELEASE_ASSERT(lenp == NULL, "");
RELEASE_ASSERT(o->cls == str_cls, "");
RELEASE_ASSERT(isSubclass(o->cls, str_cls), "");
return 1;
}
......@@ -2246,7 +2293,7 @@ static Py_ssize_t string_buffer_getcharbuf(PyStringObject* self, Py_ssize_t inde
}
static int string_buffer_getbuffer(BoxedString* self, Py_buffer* view, int flags) noexcept {
assert(self->cls == str_cls);
assert(isSubclass(self->cls, str_cls));
return PyBuffer_FillInfo(view, (PyObject*)self, &self->s[0], self->s.size(), 1, flags);
}
......@@ -2358,7 +2405,7 @@ void setupStr() {
str_cls->giveAttr("join", new BoxedFunction(boxRTFunction((void*)strJoin, STR, 2)));
str_cls->giveAttr("replace",
new BoxedFunction(boxRTFunction((void*)strReplace, STR, 4, 1, false, false), { boxInt(-1) }));
new BoxedFunction(boxRTFunction((void*)strReplace, UNKNOWN, 4, 1, false, false), { boxInt(-1) }));
str_cls->giveAttr(
"split", new BoxedFunction(boxRTFunction((void*)strSplit, LIST, 3, 2, false, false), { None, boxInt(-1) }));
......
......@@ -1159,10 +1159,9 @@ Box* objectStr(Box* obj) {
}
static Box* typeName(Box* b, void*) {
assert(b->cls == type_cls);
RELEASE_ASSERT(isSubclass(b->cls, type_cls), "");
BoxedClass* type = static_cast<BoxedClass*>(b);
// TODO is this predicate right?
if (type->tp_flags & Py_TPFLAGS_HEAPTYPE) {
BoxedHeapClass* et = static_cast<BoxedHeapClass*>(type);
return et->ht_name;
......@@ -1321,6 +1320,8 @@ void setupRuntime() {
tuple_cls->finishInitialization();
list_cls->finishInitialization();
str_cls->tp_flags |= Py_TPFLAGS_HAVE_NEWBUFFER;
module_cls = BoxedHeapClass::create(type_cls, object_cls, NULL, offsetof(BoxedModule, attrs), 0,
......@@ -1516,6 +1517,7 @@ void setupRuntime() {
setupPyston();
PyType_Ready(&PyCapsule_Type);
PyType_Ready(&PyCallIter_Type);
initerrno();
init_sha();
......
......@@ -15,3 +15,10 @@ def f2():
print list(g2)
f2()
# Make sure that the 'ifs' part gets scoped properly
def f3():
b = True
print list(x for x in range(5) if b)
print list(x for x in range(5) if [b for b in xrange(4)])
print b
print f3()
# allow-warning: import level 0 will be treated as -1
import gzip
import io
......
# allow-warning: import level 0 will be treated as -1
import io
filename = "io_test_.txt"
......
# expected: fail
# - not supported yet
class C(object):
def __len__(self):
print "__len__"
......@@ -26,3 +23,20 @@ def f(a, b, c):
print a, b, c
f(**C())
class MyDict(dict):
pass
d = MyDict(a=1, b=2, c=3)
print f(**d)
# Django does this:
class C(object):
pass
c = C()
c.a = 1
c.b = 3
c.c = 7
print f(**c.__dict__)
......@@ -8,7 +8,7 @@ for i in xrange(150):
print t, repr(t)
def test(a, b):
print a, b
print repr(a), repr(b)
print a + b, b + a, a.__add__(b), b.__add__(a)
print a - b, b - a, a.__sub__(b), b.__sub__(a)
print a * b, b * a, a.__mul__(b), b.__mul__(a)
......@@ -26,6 +26,9 @@ for a in [-5, -1, 1, 5, -2L, -1L, 1L, 2L]:
for b in [-5, -1, 1, 5, -2L, -1L, 1L, 2L]:
test(a, b)
test(1L, 2.0)
test(3.0, 2L)
print (2L).__rdiv__(-1)
print (2L).__rdiv__(-1L)
print (-2L).__rdiv__(1L)
......
# allow-warning: import level 0 will be treated as -1
# Simple optparse test, taken from the optparse.py docstring:
from optparse import OptionParser
......
# allow-warning: import level 0 will be treated as -1
import pickle
l = [[], (123,)]
......
# allow-warning: import level 0 will be treated as -1
# skip-if: '-x' in EXTRA_JIT_ARGS
def f(a):
......
# allow-warning: import level 0 will be treated as -1!
def test(string, encoding):
s = string.encode(encoding)
print encoding, s
......
......@@ -139,3 +139,6 @@ except:
print repr("hello\tworld\t".expandtabs())
print repr("hello\tworld\t".expandtabs(12))
print "hello world".startswith(("x", "h"))
print "hello world".endswith(("x", "h"))
class MyStr(str):
pass
s = MyStr(1)
print repr(s)
import sys
sys.stdout.write(s)
# no-collect-stats
import sys
sys.exit(None)
# skip-if: '-x' in EXTRA_JIT_ARGS
# allow-warning: import level 0 will be treated as -1
print repr(unicode())
print repr(unicode('hello world'))
......@@ -81,3 +80,12 @@ f(**{'a':2})
f(**{u'a':3})
print repr('%s' % u'') # this gives a unicode object!
print repr('hello world'.replace(u'hello', u'hi'))
print "hello world".endswith(u'hello')
print "hello world".endswith(u'world')
print "hello world".startswith(u'hello')
print "hello world".startswith(u'world')
print float(u'1.0')
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