Commit 801dec8c authored by Kevin Modzelewski's avatar Kevin Modzelewski

Merge pull request #504 from kmod/pr492

delete capi/float.cpp
parents 0defcec2 8aa08824
......@@ -27,6 +27,8 @@
#define SIZEOF_INT 4
#define SIZEOF_LONG 8
#define SIZEOF_LONG_LONG 8
#define SIZEOF_DOUBLE 8
#define SIZEOF_FLOAT 4
#define SIZEOF_OFF_T 8
#define SIZEOF_PTHREAD_T 8
#define HAVE_COPYSIGN 1
......
......@@ -55,7 +55,9 @@ typedef struct BLOCK {
struct BLOCK *leftlink;
} block;
#define MAXFREEBLOCKS 10
// Pyston change: disable free block cache
// #define MAXFREEBLOCKS 10
#define MAXFREEBLOCKS 0
static Py_ssize_t numfreeblocks = 0;
static block *freeblocks[MAXFREEBLOCKS];
......
......@@ -30,7 +30,6 @@ add_library(PYSTON_OBJECTS OBJECT ${OPTIONAL_SRCS}
capi/codecs.cpp
capi/descrobject.cpp
capi/errors.cpp
capi/float.cpp
capi/modsupport.cpp
capi/object.cpp
capi/typeobject.cpp
......
......@@ -557,8 +557,29 @@ extern "C" int PyObject_CheckReadBuffer(PyObject* obj) noexcept {
}
extern "C" int PyObject_AsReadBuffer(PyObject* obj, const void** buffer, Py_ssize_t* buffer_len) noexcept {
fatalOrError(PyExc_NotImplementedError, "unimplemented");
return -1;
PyBufferProcs* pb;
void* pp;
Py_ssize_t len;
if (obj == NULL || buffer == NULL || buffer_len == NULL) {
null_error();
return -1;
}
pb = obj->cls->tp_as_buffer;
if (pb == NULL || pb->bf_getreadbuffer == NULL || pb->bf_getsegcount == NULL) {
PyErr_SetString(PyExc_TypeError, "expected a readable buffer object");
return -1;
}
if ((*pb->bf_getsegcount)(obj, NULL) != 1) {
PyErr_SetString(PyExc_TypeError, "expected a single-segment buffer object");
return -1;
}
len = (*pb->bf_getreadbuffer)(obj, 0, &pp);
if (len < 0)
return -1;
*buffer = pp;
*buffer_len = len;
return 0;
}
static PyObject* call_function_tail(PyObject* callable, PyObject* args) {
......@@ -1818,6 +1839,21 @@ extern "C" PyObject* PyNumber_Long(PyObject* o) noexcept {
}
extern "C" PyObject* PyNumber_Float(PyObject* o) noexcept {
if (o == NULL)
return null_error();
if (o->cls == float_cls)
return o;
if (PyInt_Check(o))
return boxFloat(((BoxedInt*)o)->n);
else if (PyLong_Check(o)) {
double result = PyLong_AsDouble(o);
if (result == -1.0 && PyErr_Occurred())
return NULL;
return boxFloat(result);
}
fatalOrError(PyExc_NotImplementedError, "unimplemented");
return nullptr;
}
......
This diff is collapsed.
......@@ -13,6 +13,7 @@
// limitations under the License.
#include <algorithm>
#include <cfloat>
#include <cstddef>
#include <err.h>
......@@ -375,6 +376,14 @@ Box* issubclass_func(Box* child, Box* parent) {
return boxBool(rtn);
}
Box* intern_func(Box* str) {
if (!PyString_CheckExact(str)) // have to use exact check!
raiseExcHelper(TypeError, "can't intern subclass of string");
PyString_InternInPlace(&str);
checkAndThrowCAPIException();
return str;
}
Box* bltinImport(Box* name, Box* globals, Box* locals, Box** args) {
Box* fromlist = args[0];
Box* level = args[1];
......@@ -590,7 +599,6 @@ public:
static Box* __reduce__(Box* self) {
RELEASE_ASSERT(isSubclass(self->cls, BaseException), "");
BoxedException* exc = static_cast<BoxedException*>(self);
return BoxedTuple::create({ self->cls, EmptyTuple, self->getAttrWrapper() });
}
};
......@@ -967,16 +975,38 @@ Box* builtinRound(Box* _number, Box* _ndigits) {
raiseExcHelper(TypeError, "a float is required");
BoxedFloat* number = (BoxedFloat*)_number;
double x = number->d;
if (isSubclass(_ndigits->cls, int_cls)) {
BoxedInt* ndigits = (BoxedInt*)_ndigits;
/* interpret 2nd argument as a Py_ssize_t; clip on overflow */
Py_ssize_t ndigits = PyNumber_AsSsize_t(_ndigits, NULL);
if (ndigits == -1 && PyErr_Occurred())
throwCAPIException();
if (ndigits->n == 0)
return boxFloat(round(number->d));
/* nans, infinities and zeros round to themselves */
if (!std::isfinite(x) || x == 0.0)
return boxFloat(x);
/* Deal with extreme values for ndigits. For ndigits > NDIGITS_MAX, x
always rounds to itself. For ndigits < NDIGITS_MIN, x always
rounds to +-0.0. Here 0.30103 is an upper bound for log10(2). */
#define NDIGITS_MAX ((int)((DBL_MANT_DIG - DBL_MIN_EXP) * 0.30103))
#define NDIGITS_MIN (-(int)((DBL_MAX_EXP + 1) * 0.30103))
if (ndigits > NDIGITS_MAX)
/* return x */
return boxFloat(x);
else if (ndigits < NDIGITS_MIN)
/* return 0.0, but with sign of x */
return boxFloat(0.0 * x);
else {
/* finite x, and ndigits is not unreasonably large */
/* _Py_double_round is defined in floatobject.c */
Box* rtn = _Py_double_round(x, (int)ndigits);
if (!rtn)
throwCAPIException();
return rtn;
}
fatalOrError(PyExc_NotImplementedError, "unimplemented");
throwCAPIException();
#undef NDIGITS_MAX
#undef NDIGITS_MIN
}
Box* builtinCmp(Box* a, Box* b) {
......@@ -1103,6 +1133,9 @@ void setupBuiltins() {
= new BoxedBuiltinFunctionOrMethod(boxRTFunction((void*)issubclass_func, BOXED_BOOL, 2), "issubclass");
builtins_module->giveAttr("issubclass", issubclass_obj);
Box* intern_obj = new BoxedBuiltinFunctionOrMethod(boxRTFunction((void*)intern_func, UNKNOWN, 1), "intern");
builtins_module->giveAttr("intern", intern_obj);
CLFunction* import_func = boxRTFunction((void*)bltinImport, UNKNOWN, 5, 4, false, false,
ParamNames({ "name", "globals", "locals", "fromlist", "level" }, "", ""));
builtins_module->giveAttr("__import__", new BoxedBuiltinFunctionOrMethod(import_func, "__import__",
......
This diff is collapsed.
......@@ -200,7 +200,7 @@ extern "C" PyObject* PyInt_FromString(const char* s, char** pend, int base) noex
if (x < 0)
return PyLong_FromString(s, pend, base);
} else
x = strtoul(s, &end, base);
x = strtol(s, &end, base);
if (end == s || !isalnum(Py_CHARMASK(end[-1])))
goto bad;
while (*end && isspace(Py_CHARMASK(*end)))
......@@ -672,8 +672,13 @@ extern "C" Box* intLShiftInt(BoxedInt* lhs, BoxedInt* rhs) {
if (rhs->n < 0)
raiseExcHelper(ValueError, "negative shift count");
// TODO overflow?
return boxInt(lhs->n << rhs->n);
bool undefined = rhs->n >= sizeof(rhs->n) * 8;
if (!undefined) {
int64_t res = lhs->n << rhs->n;
if ((res >> rhs->n) == lhs->n)
return boxInt(lhs->n << rhs->n);
}
return longLshift(boxLong(lhs->n), rhs);
}
extern "C" Box* intLShift(BoxedInt* lhs, Box* rhs) {
......
......@@ -109,7 +109,7 @@ Box* seqiterNext(Box* s) {
}
static void seqiterGCVisit(GCVisitor* v, Box* b) {
assert(b->cls == seqiter_cls);
assert(b->cls == seqiter_cls || b->cls == seqreviter_cls);
boxGCHandler(v, b);
BoxedSeqIter* si = static_cast<BoxedSeqIter*>(b);
......@@ -182,7 +182,8 @@ void setupIter() {
seqiter_cls->freeze();
seqiter_cls->tpp_hasnext = seqiterHasnextUnboxed;
seqreviter_cls = BoxedHeapClass::create(type_cls, object_cls, NULL, 0, 0, sizeof(BoxedSeqIter), false, "reversed");
seqreviter_cls
= BoxedHeapClass::create(type_cls, object_cls, seqiterGCVisit, 0, 0, sizeof(BoxedSeqIter), false, "reversed");
seqreviter_cls->giveAttr("next", new BoxedFunction(boxRTFunction((void*)seqiterNext, UNKNOWN, 1)));
seqreviter_cls->giveAttr("__hasnext__", new BoxedFunction(boxRTFunction((void*)seqreviterHasnext, BOXED_BOOL, 1)));
......
......@@ -25,6 +25,7 @@
#include "core/stats.h"
#include "core/types.h"
#include "gc/collector.h"
#include "gc/roots.h"
#include "runtime/objmodel.h"
#include "runtime/types.h"
#include "runtime/util.h"
......@@ -423,23 +424,21 @@ extern "C" Box* listSetitemSlice(BoxedList* self, BoxedSlice* slice, Box* v) {
size_t v_size;
Box** v_elts;
RootedBox v_as_seq((Box*)nullptr);
if (!v) {
v_size = 0;
v_elts = NULL;
} else if (v->cls == list_cls || isSubclass(v->cls, list_cls)) {
BoxedList* lv = static_cast<BoxedList*>(v);
v_size = lv->size;
} else {
v_as_seq = RootedBox(PySequence_Fast(v, "can only assign an iterable"));
if (v_as_seq == NULL)
throwCAPIException();
v_size = PySequence_Fast_GET_SIZE(v_as_seq);
// If lv->size is 0, lv->elts->elts is garbage
if (v_size)
v_elts = lv->elts->elts;
v_elts = PySequence_Fast_ITEMS(v_as_seq);
else
v_elts = NULL;
} else if (v->cls == tuple_cls || isSubclass(v->cls, tuple_cls)) {
BoxedTuple* tv = static_cast<BoxedTuple*>(v);
v_size = tv->size();
v_elts = &tv->elts[0];
} else {
RELEASE_ASSERT(0, "unsupported type for list slice assignment: '%s'", getTypeName(v));
}
// If self->size is 0, self->elts->elts is garbage
......
......@@ -116,7 +116,48 @@ extern "C" unsigned PY_LONG_LONG PyLong_AsUnsignedLongLongMask(PyObject* vv) noe
}
extern "C" PY_LONG_LONG PyLong_AsLongLong(PyObject* vv) noexcept {
Py_FatalError("unimplemented");
PY_LONG_LONG bytes;
int one = 1;
int res;
if (vv == NULL) {
PyErr_BadInternalCall();
return -1;
}
if (!PyLong_Check(vv)) {
PyNumberMethods* nb;
PyObject* io;
if (PyInt_Check(vv))
return (PY_LONG_LONG)PyInt_AsLong(vv);
if ((nb = vv->cls->tp_as_number) == NULL || nb->nb_int == NULL) {
PyErr_SetString(PyExc_TypeError, "an integer is required");
return -1;
}
io = (*nb->nb_int)(vv);
if (io == NULL)
return -1;
if (PyInt_Check(io)) {
bytes = PyInt_AsLong(io);
Py_DECREF(io);
return bytes;
}
if (PyLong_Check(io)) {
bytes = PyLong_AsLongLong(io);
Py_DECREF(io);
return bytes;
}
Py_DECREF(io);
PyErr_SetString(PyExc_TypeError, "integer conversion failed");
return -1;
}
res = _PyLong_AsByteArray((PyLongObject*)vv, (unsigned char*)&bytes, SIZEOF_LONG_LONG, IS_LITTLE_ENDIAN, 1);
/* Plan 9 can't handle PY_LONG_LONG in ? : expressions */
if (res < 0)
return (PY_LONG_LONG)-1;
else
return bytes;
}
extern "C" PY_LONG_LONG PyLong_AsLongLongAndOverflow(PyObject* obj, int* overflow) noexcept {
......@@ -442,7 +483,12 @@ extern "C" void* PyLong_AsVoidPtr(PyObject* vv) noexcept {
extern "C" int _PyLong_AsByteArray(PyLongObject* v, unsigned char* bytes, size_t n, int little_endian,
int is_signed) noexcept {
Py_FatalError("unimplemented");
RELEASE_ASSERT(little_endian == 1, "not implemented");
RELEASE_ASSERT(n == 8, "did not yet check if the behaviour is correct for sizes other than 8");
size_t count = 0;
mpz_export(bytes, &count, -1, n, 0, 0, ((BoxedLong*)v)->n);
RELEASE_ASSERT(count <= n, "overflow handling is not yet implemented");
return 0;
}
extern "C" PyObject* _PyLong_FromByteArray(const unsigned char* bytes, size_t n, int little_endian,
......
......@@ -2305,8 +2305,17 @@ extern "C" PyObject* PyString_FromStringAndSize(const char* s, ssize_t n) noexce
return boxStrConstantSize(s, n);
}
static /*const*/ char* string_getbuffer(register PyObject* op) noexcept {
char* s;
Py_ssize_t len;
if (PyString_AsStringAndSize(op, &s, &len))
return NULL;
return s;
}
extern "C" char* PyString_AsString(PyObject* o) noexcept {
RELEASE_ASSERT(isSubclass(o->cls, str_cls), "");
if (!PyString_Check(o))
return string_getbuffer(o);
BoxedString* s = static_cast<BoxedString*>(o);
return getWriteableStringContents(s);
......
......@@ -978,7 +978,39 @@ Box* sliceRepr(BoxedSlice* self) {
extern "C" int PySlice_GetIndices(PySliceObject* r, Py_ssize_t length, Py_ssize_t* start, Py_ssize_t* stop,
Py_ssize_t* step) noexcept {
Py_FatalError("unimplemented");
/* XXX support long ints */
if (r->step == Py_None) {
*step = 1;
} else {
if (!PyInt_Check(r->step) && !PyLong_Check(r->step))
return -1;
*step = PyInt_AsSsize_t(r->step);
}
if (r->start == Py_None) {
*start = *step < 0 ? length - 1 : 0;
} else {
if (!PyInt_Check(r->start) && !PyLong_Check(r->step))
return -1;
*start = PyInt_AsSsize_t(r->start);
if (*start < 0)
*start += length;
}
if (r->stop == Py_None) {
*stop = *step < 0 ? -1 : length;
} else {
if (!PyInt_Check(r->stop) && !PyLong_Check(r->step))
return -1;
*stop = PyInt_AsSsize_t(r->stop);
if (*stop < 0)
*stop += length;
}
if (*stop > length)
return -1;
if (*start >= length)
return -1;
if (*step == 0)
return -1;
return 0;
}
extern "C" int PySlice_GetIndicesEx(PySliceObject* _r, Py_ssize_t length, Py_ssize_t* start, Py_ssize_t* stop,
......
......@@ -105,8 +105,8 @@ print callable(lambda: 1)
print range(5L, 7L)
print round(-1.1), round(-1.9)
print round(0.5), round(-0.5)
for n in [0, 1, 2, 3, 4, 5]:
print round(-1.1, n), round(-1.9, n), round(0.5, n), round(-0.5, n), round(-0.123456789, n)
print list(iter(xrange(100).__iter__().next, 20))
......
......@@ -66,6 +66,9 @@ class L(object):
print type(int(L()))
print int(u'123')
print int("9223372036854775808", 0)
print 1 << 63, 1 << 64, -1 << 63, -1 << 64, 2 << 63
print type(1 << 63), type(1 << 64), type(-1 << 63), type(-1 << 64), type(2 << 63)
for b in range(26):
try:
......
......@@ -124,7 +124,13 @@ for i in xrange(3):
l[j:k] = ["added"]
print i, j, k, l
def G():
yield "a"
yield "b"
yield "c"
l = [0, 1, 2, 3, 4, 5]
l[1:] = G()
print l
l = [1, 3, 5, 7, 2, 4]
print l.sort(key=lambda x:x%3)
......
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