Commit 8d9e1bb8 authored by Kevin Modzelewski's avatar Kevin Modzelewski

Merge branch 'pickle'

parents 05774ca0 23784905
......@@ -290,7 +290,7 @@ SRCS := $(MAIN_SRCS) $(STDLIB_SRCS)
STDLIB_OBJS := stdlib.bc.o stdlib.stripped.bc.o
STDLIB_RELEASE_OBJS := stdlib.release.bc.o
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 $(EXTRA_STDMODULE_SRCS)
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 $(EXTRA_STDMODULE_SRCS)
STDOBJECT_SRCS := structseq.c capsule.c stringobject.c $(EXTRA_STDOBJECT_SRCS)
STDPYTHON_SRCS := pyctype.c getargs.c formatter_string.c pystrtod.c dtoa.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))
......
......@@ -15,7 +15,7 @@ endforeach(STDLIB_FILE)
add_custom_target(copy_stdlib ALL DEPENDS ${STDLIB_TARGETS})
# compile specified files in from_cpython/Modules
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)
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)
# compile specified files in from_cpython/Objects
file(GLOB_RECURSE STDOBJECT_SRCS Objects structseq.c capsule.c stringobject.c)
......
......@@ -36,11 +36,11 @@ PyAPI_DATA(int) Py_HashRandomizationFlag;
// Pyston change: make Py_FatalError a macro so that it can access linenumber info, similar to assert:
//PyAPI_FUNC(void) Py_FatalError(const char *message) __attribute__((__noreturn__));
#define _STRINGIFY(N) #N
#define STRINGIFY(N) _STRINGIFY(N)
#define _PYSTON_STRINGIFY(N) #N
#define PYSTON_STRINGIFY(N) _PYSTON_STRINGIFY(N)
#define Py_FatalError(message) \
do { \
fprintf(stderr, __FILE__ ":" STRINGIFY(__LINE__) ": %s: Fatal Python error: %s\n", __PRETTY_FUNCTION__, message); \
fprintf(stderr, __FILE__ ":" PYSTON_STRINGIFY(__LINE__) ": %s: Fatal Python error: %s\n", __PRETTY_FUNCTION__, message); \
abort(); \
} while (0)
......
from pickle import *
# Very simple stub for the marshal module.
# - pickle imports marshal
def loads(*args, **kw):
raise NotImplementedError()
......@@ -26,7 +26,61 @@
namespace pyston {
static PyObject* type_error(const char* msg, PyObject* obj) noexcept {
PyErr_Format(PyExc_TypeError, msg, Py_TYPE(obj)->tp_name);
return NULL;
}
static PyObject* null_error(void) noexcept {
if (!PyErr_Occurred())
PyErr_SetString(PyExc_SystemError, "null argument to internal routine");
return NULL;
}
static PyObject* objargs_mktuple(va_list va) noexcept {
int i, n = 0;
va_list countva;
PyObject* result, *tmp;
#ifdef VA_LIST_IS_ARRAY
memcpy(countva, va, sizeof(va_list));
#else
#ifdef __va_copy
__va_copy(countva, va);
#else
countva = va;
#endif
#endif
while (((PyObject*)va_arg(countva, PyObject*)) != NULL)
++n;
result = PyTuple_New(n);
if (result != NULL && n > 0) {
for (i = 0; i < n; ++i) {
tmp = (PyObject*)va_arg(va, PyObject*);
PyTuple_SET_ITEM(result, i, tmp);
Py_INCREF(tmp);
}
}
return result;
}
extern "C" PyObject* PyObject_CallFunctionObjArgs(PyObject* callable, ...) {
Py_FatalError("unimplemented");
PyObject* args, *tmp;
va_list vargs;
if (callable == NULL)
return null_error();
/* count the args */
va_start(vargs, callable);
args = objargs_mktuple(vargs);
va_end(vargs);
if (args == NULL)
return NULL;
tmp = PyObject_Call(callable, args, NULL);
Py_DECREF(args);
return tmp;
}
}
// Copyright (c) 2014-2015 Dropbox, Inc.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
// This file is mostly copied from CPython
#include "Python.h"
#include "core/types.h"
#include "runtime/types.h"
namespace pyston {
extern "C" {
typedef enum { unknown_format, ieee_big_endian_format, ieee_little_endian_format } float_format_type;
static float_format_type double_format, float_format;
static float_format_type detected_double_format, detected_float_format;
static PyObject* float_getformat(PyTypeObject* v, PyObject* arg) {
char* s;
float_format_type r;
if (!PyString_Check(arg)) {
PyErr_Format(PyExc_TypeError, "__getformat__() argument must be string, not %.500s", Py_TYPE(arg)->tp_name);
return NULL;
}
s = PyString_AS_STRING(arg);
if (strcmp(s, "double") == 0) {
r = double_format;
} else if (strcmp(s, "float") == 0) {
r = float_format;
} else {
PyErr_SetString(PyExc_ValueError, "__getformat__() argument 1 must be "
"'double' or 'float'");
return NULL;
}
switch (r) {
case unknown_format:
return PyString_FromString("unknown");
case ieee_little_endian_format:
return PyString_FromString("IEEE, little-endian");
case ieee_big_endian_format:
return PyString_FromString("IEEE, big-endian");
default:
Py_FatalError("insane float_format or double_format");
return NULL;
}
}
PyDoc_STRVAR(float_getformat_doc, "float.__getformat__(typestr) -> string\n"
"\n"
"You probably don't want to use this function. It exists mainly to be\n"
"used in Python's test suite.\n"
"\n"
"typestr must be 'double' or 'float'. This function returns whichever of\n"
"'unknown', 'IEEE, big-endian' or 'IEEE, little-endian' best describes the\n"
"format of floating point numbers used by the C type named by typestr.");
static PyObject* float_setformat(PyTypeObject* v, PyObject* args) {
char* typestr;
char* format;
float_format_type f;
float_format_type detected;
float_format_type* p;
if (!PyArg_ParseTuple(args, "ss:__setformat__", &typestr, &format))
return NULL;
if (strcmp(typestr, "double") == 0) {
p = &double_format;
detected = detected_double_format;
} else if (strcmp(typestr, "float") == 0) {
p = &float_format;
detected = detected_float_format;
} else {
PyErr_SetString(PyExc_ValueError, "__setformat__() argument 1 must "
"be 'double' or 'float'");
return NULL;
}
if (strcmp(format, "unknown") == 0) {
f = unknown_format;
} else if (strcmp(format, "IEEE, little-endian") == 0) {
f = ieee_little_endian_format;
} else if (strcmp(format, "IEEE, big-endian") == 0) {
f = ieee_big_endian_format;
} else {
PyErr_SetString(PyExc_ValueError, "__setformat__() argument 2 must be "
"'unknown', 'IEEE, little-endian' or "
"'IEEE, big-endian'");
return NULL;
}
if (f != unknown_format && f != detected) {
PyErr_Format(PyExc_ValueError, "can only set %s format to 'unknown' or the "
"detected platform value",
typestr);
return NULL;
}
*p = f;
Py_RETURN_NONE;
}
/*----------------------------------------------------------------------------
* _PyFloat_{Pack,Unpack}{4,8}. See floatobject.h.
*/
extern "C" int _PyFloat_Pack4(double x, unsigned char* p, int le) {
if (float_format == unknown_format) {
unsigned char sign;
int e;
double f;
unsigned int fbits;
int incr = 1;
if (le) {
p += 3;
incr = -1;
}
if (x < 0) {
sign = 1;
x = -x;
} else
sign = 0;
f = frexp(x, &e);
/* Normalize f to be in the range [1.0, 2.0) */
if (0.5 <= f && f < 1.0) {
f *= 2.0;
e--;
} else if (f == 0.0)
e = 0;
else {
PyErr_SetString(PyExc_SystemError, "frexp() result out of range");
return -1;
}
if (e >= 128)
goto Overflow;
else if (e < -126) {
/* Gradual underflow */
f = ldexp(f, 126 + e);
e = 0;
} else if (!(e == 0 && f == 0.0)) {
e += 127;
f -= 1.0; /* Get rid of leading 1 */
}
f *= 8388608.0; /* 2**23 */
fbits = (unsigned int)(f + 0.5); /* Round */
assert(fbits <= 8388608);
if (fbits >> 23) {
/* The carry propagated out of a string of 23 1 bits. */
fbits = 0;
++e;
if (e >= 255)
goto Overflow;
}
/* First byte */
*p = (sign << 7) | (e >> 1);
p += incr;
/* Second byte */
*p = (char)(((e & 1) << 7) | (fbits >> 16));
p += incr;
/* Third byte */
*p = (fbits >> 8) & 0xFF;
p += incr;
/* Fourth byte */
*p = fbits & 0xFF;
/* Done */
return 0;
} else {
float y = (float)x;
const char* s = (char*)&y;
int i, incr = 1;
if (Py_IS_INFINITY(y) && !Py_IS_INFINITY(x))
goto Overflow;
if ((float_format == ieee_little_endian_format && !le) || (float_format == ieee_big_endian_format && le)) {
p += 3;
incr = -1;
}
for (i = 0; i < 4; i++) {
*p = *s++;
p += incr;
}
return 0;
}
Overflow:
PyErr_SetString(PyExc_OverflowError, "float too large to pack with f format");
return -1;
}
extern "C" int _PyFloat_Pack8(double x, unsigned char* p, int le) {
if (double_format == unknown_format) {
unsigned char sign;
int e;
double f;
unsigned int fhi, flo;
int incr = 1;
if (le) {
p += 7;
incr = -1;
}
if (x < 0) {
sign = 1;
x = -x;
} else
sign = 0;
f = frexp(x, &e);
/* Normalize f to be in the range [1.0, 2.0) */
if (0.5 <= f && f < 1.0) {
f *= 2.0;
e--;
} else if (f == 0.0)
e = 0;
else {
PyErr_SetString(PyExc_SystemError, "frexp() result out of range");
return -1;
}
if (e >= 1024)
goto Overflow;
else if (e < -1022) {
/* Gradual underflow */
f = ldexp(f, 1022 + e);
e = 0;
} else if (!(e == 0 && f == 0.0)) {
e += 1023;
f -= 1.0; /* Get rid of leading 1 */
}
/* fhi receives the high 28 bits; flo the low 24 bits (== 52 bits) */
f *= 268435456.0; /* 2**28 */
fhi = (unsigned int)f; /* Truncate */
assert(fhi < 268435456);
f -= (double)fhi;
f *= 16777216.0; /* 2**24 */
flo = (unsigned int)(f + 0.5); /* Round */
assert(flo <= 16777216);
if (flo >> 24) {
/* The carry propagated out of a string of 24 1 bits. */
flo = 0;
++fhi;
if (fhi >> 28) {
/* And it also progagated out of the next 28 bits. */
fhi = 0;
++e;
if (e >= 2047)
goto Overflow;
}
}
/* First byte */
*p = (sign << 7) | (e >> 4);
p += incr;
/* Second byte */
*p = (unsigned char)(((e & 0xF) << 4) | (fhi >> 24));
p += incr;
/* Third byte */
*p = (fhi >> 16) & 0xFF;
p += incr;
/* Fourth byte */
*p = (fhi >> 8) & 0xFF;
p += incr;
/* Fifth byte */
*p = fhi & 0xFF;
p += incr;
/* Sixth byte */
*p = (flo >> 16) & 0xFF;
p += incr;
/* Seventh byte */
*p = (flo >> 8) & 0xFF;
p += incr;
/* Eighth byte */
*p = flo & 0xFF;
/* p += incr; Unneeded (for now) */
/* Done */
return 0;
Overflow:
PyErr_SetString(PyExc_OverflowError, "float too large to pack with d format");
return -1;
} else {
const char* s = (char*)&x;
int i, incr = 1;
if ((double_format == ieee_little_endian_format && !le) || (double_format == ieee_big_endian_format && le)) {
p += 7;
incr = -1;
}
for (i = 0; i < 8; i++) {
*p = *s++;
p += incr;
}
return 0;
}
}
double _PyFloat_Unpack4(const unsigned char* p, int le) {
if (float_format == unknown_format) {
unsigned char sign;
int e;
unsigned int f;
double x;
int incr = 1;
if (le) {
p += 3;
incr = -1;
}
/* First byte */
sign = (*p >> 7) & 1;
e = (*p & 0x7F) << 1;
p += incr;
/* Second byte */
e |= (*p >> 7) & 1;
f = (*p & 0x7F) << 16;
p += incr;
if (e == 255) {
PyErr_SetString(PyExc_ValueError, "can't unpack IEEE 754 special value "
"on non-IEEE platform");
return -1;
}
/* Third byte */
f |= *p << 8;
p += incr;
/* Fourth byte */
f |= *p;
x = (double)f / 8388608.0;
/* XXX This sadly ignores Inf/NaN issues */
if (e == 0)
e = -126;
else {
x += 1.0;
e -= 127;
}
x = ldexp(x, e);
if (sign)
x = -x;
return x;
} else {
float x;
if ((float_format == ieee_little_endian_format && !le) || (float_format == ieee_big_endian_format && le)) {
char buf[4];
char* d = &buf[3];
int i;
for (i = 0; i < 4; i++) {
*d-- = *p++;
}
memcpy(&x, buf, 4);
} else {
memcpy(&x, p, 4);
}
return x;
}
}
double _PyFloat_Unpack8(const unsigned char* p, int le) {
if (double_format == unknown_format) {
unsigned char sign;
int e;
unsigned int fhi, flo;
double x;
int incr = 1;
if (le) {
p += 7;
incr = -1;
}
/* First byte */
sign = (*p >> 7) & 1;
e = (*p & 0x7F) << 4;
p += incr;
/* Second byte */
e |= (*p >> 4) & 0xF;
fhi = (*p & 0xF) << 24;
p += incr;
if (e == 2047) {
PyErr_SetString(PyExc_ValueError, "can't unpack IEEE 754 special value "
"on non-IEEE platform");
return -1.0;
}
/* Third byte */
fhi |= *p << 16;
p += incr;
/* Fourth byte */
fhi |= *p << 8;
p += incr;
/* Fifth byte */
fhi |= *p;
p += incr;
/* Sixth byte */
flo = *p << 16;
p += incr;
/* Seventh byte */
flo |= *p << 8;
p += incr;
/* Eighth byte */
flo |= *p;
x = (double)fhi + (double)flo / 16777216.0; /* 2**24 */
x /= 268435456.0; /* 2**28 */
if (e == 0)
e = -1022;
else {
x += 1.0;
e -= 1023;
}
x = ldexp(x, e);
if (sign)
x = -x;
return x;
} else {
double x;
if ((double_format == ieee_little_endian_format && !le) || (double_format == ieee_big_endian_format && le)) {
char buf[8];
char* d = &buf[7];
int i;
for (i = 0; i < 8; i++) {
*d-- = *p++;
}
memcpy(&x, buf, 8);
} else {
memcpy(&x, p, 8);
}
return x;
}
}
}
}
......@@ -67,4 +67,12 @@ extern "C" PyObject* PyObject_Str(PyObject* v) {
extern "C" PyObject* PyObject_SelfIter(PyObject* obj) {
Py_FatalError("unimplemented");
}
extern "C" int PyObject_GenericSetAttr(PyObject* obj, PyObject* name, PyObject* value) {
Py_FatalError("unimplemented");
}
extern "C" int PyObject_AsWriteBuffer(PyObject* obj, void** buffer, Py_ssize_t* buffer_len) {
Py_FatalError("unimplemented");
}
}
......@@ -27,7 +27,7 @@ extern "C" void conservativeGCHandler(GCVisitor* v, Box* b) {
v->visitPotentialRange((void* const*)b, (void* const*)((char*)b + b->cls->tp_basicsize));
}
static int check_num_args(PyObject* ob, int n) {
static int check_num_args(PyObject* ob, int n) noexcept {
if (!PyTuple_CheckExact(ob)) {
PyErr_SetString(PyExc_SystemError, "PyArg_UnpackTuple() argument list is not a tuple");
return 0;
......@@ -38,7 +38,7 @@ static int check_num_args(PyObject* ob, int n) {
return 0;
}
static PyObject* wrap_hashfunc(PyObject* self, PyObject* args, void* wrapped) {
static PyObject* wrap_hashfunc(PyObject* self, PyObject* args, void* wrapped) noexcept {
hashfunc func = (hashfunc)wrapped;
long res;
......@@ -50,13 +50,13 @@ static PyObject* wrap_hashfunc(PyObject* self, PyObject* args, void* wrapped) {
return PyInt_FromLong(res);
}
static PyObject* wrap_call(PyObject* self, PyObject* args, void* wrapped, PyObject* kwds) {
static PyObject* wrap_call(PyObject* self, PyObject* args, void* wrapped, PyObject* kwds) noexcept {
ternaryfunc func = (ternaryfunc)wrapped;
return (*func)(self, args, kwds);
}
static PyObject* wrap_richcmpfunc(PyObject* self, PyObject* args, void* wrapped, int op) {
static PyObject* wrap_richcmpfunc(PyObject* self, PyObject* args, void* wrapped, int op) noexcept {
richcmpfunc func = (richcmpfunc)wrapped;
PyObject* other;
......@@ -79,7 +79,7 @@ RICHCMP_WRAPPER(ne, Py_NE)
RICHCMP_WRAPPER(gt, Py_GT)
RICHCMP_WRAPPER(ge, Py_GE)
static PyObject* wrap_unaryfunc(PyObject* self, PyObject* args, void* wrapped) {
static PyObject* wrap_unaryfunc(PyObject* self, PyObject* args, void* wrapped) noexcept {
unaryfunc func = (unaryfunc)wrapped;
if (!check_num_args(args, 0))
......@@ -87,7 +87,7 @@ static PyObject* wrap_unaryfunc(PyObject* self, PyObject* args, void* wrapped) {
return (*func)(self);
}
static PyObject* wrap_binaryfunc(PyObject* self, PyObject* args, void* wrapped) {
static PyObject* wrap_binaryfunc(PyObject* self, PyObject* args, void* wrapped) noexcept {
binaryfunc func = (binaryfunc)wrapped;
PyObject* other;
......@@ -115,7 +115,7 @@ static Py_ssize_t getindex(PyObject* self, PyObject* arg) noexcept {
return i;
}
static PyObject* wrap_lenfunc(PyObject* self, PyObject* args, void* wrapped) {
static PyObject* wrap_lenfunc(PyObject* self, PyObject* args, void* wrapped) noexcept {
lenfunc func = (lenfunc)wrapped;
Py_ssize_t res;
......@@ -127,7 +127,7 @@ static PyObject* wrap_lenfunc(PyObject* self, PyObject* args, void* wrapped) {
return PyInt_FromLong((long)res);
}
static PyObject* wrap_indexargfunc(PyObject* self, PyObject* args, void* wrapped) {
static PyObject* wrap_indexargfunc(PyObject* self, PyObject* args, void* wrapped) noexcept {
ssizeargfunc func = (ssizeargfunc)wrapped;
PyObject* o;
Py_ssize_t i;
......@@ -157,7 +157,7 @@ static PyObject* wrap_sq_item(PyObject* self, PyObject* args, void* wrapped) noe
return NULL;
}
static PyObject* wrap_ssizessizeargfunc(PyObject* self, PyObject* args, void* wrapped) {
static PyObject* wrap_ssizessizeargfunc(PyObject* self, PyObject* args, void* wrapped) noexcept {
ssizessizeargfunc func = (ssizessizeargfunc)wrapped;
Py_ssize_t i, j;
......@@ -166,7 +166,7 @@ static PyObject* wrap_ssizessizeargfunc(PyObject* self, PyObject* args, void* wr
return (*func)(self, i, j);
}
static PyObject* wrap_sq_setitem(PyObject* self, PyObject* args, void* wrapped) {
static PyObject* wrap_sq_setitem(PyObject* self, PyObject* args, void* wrapped) noexcept {
ssizeobjargproc func = (ssizeobjargproc)wrapped;
Py_ssize_t i;
int res;
......@@ -184,7 +184,7 @@ static PyObject* wrap_sq_setitem(PyObject* self, PyObject* args, void* wrapped)
return Py_None;
}
static PyObject* wrap_sq_delitem(PyObject* self, PyObject* args, void* wrapped) {
static PyObject* wrap_sq_delitem(PyObject* self, PyObject* args, void* wrapped) noexcept {
ssizeobjargproc func = (ssizeobjargproc)wrapped;
Py_ssize_t i;
int res;
......@@ -203,7 +203,7 @@ static PyObject* wrap_sq_delitem(PyObject* self, PyObject* args, void* wrapped)
return Py_None;
}
static PyObject* wrap_ssizessizeobjargproc(PyObject* self, PyObject* args, void* wrapped) {
static PyObject* wrap_ssizessizeobjargproc(PyObject* self, PyObject* args, void* wrapped) noexcept {
ssizessizeobjargproc func = (ssizessizeobjargproc)wrapped;
Py_ssize_t i, j;
int res;
......@@ -218,7 +218,7 @@ static PyObject* wrap_ssizessizeobjargproc(PyObject* self, PyObject* args, void*
return Py_None;
}
static PyObject* wrap_delslice(PyObject* self, PyObject* args, void* wrapped) {
static PyObject* wrap_delslice(PyObject* self, PyObject* args, void* wrapped) noexcept {
ssizessizeobjargproc func = (ssizessizeobjargproc)wrapped;
Py_ssize_t i, j;
int res;
......@@ -233,7 +233,7 @@ static PyObject* wrap_delslice(PyObject* self, PyObject* args, void* wrapped) {
}
/* XXX objobjproc is a misnomer; should be objargpred */
static PyObject* wrap_objobjproc(PyObject* self, PyObject* args, void* wrapped) {
static PyObject* wrap_objobjproc(PyObject* self, PyObject* args, void* wrapped) noexcept {
objobjproc func = (objobjproc)wrapped;
int res;
PyObject* value;
......@@ -248,7 +248,7 @@ static PyObject* wrap_objobjproc(PyObject* self, PyObject* args, void* wrapped)
return PyBool_FromLong(res);
}
static PyObject* wrap_objobjargproc(PyObject* self, PyObject* args, void* wrapped) {
static PyObject* wrap_objobjargproc(PyObject* self, PyObject* args, void* wrapped) noexcept {
objobjargproc func = (objobjargproc)wrapped;
int res;
PyObject* key, *value;
......@@ -262,7 +262,7 @@ static PyObject* wrap_objobjargproc(PyObject* self, PyObject* args, void* wrappe
return Py_None;
}
static PyObject* wrap_delitem(PyObject* self, PyObject* args, void* wrapped) {
static PyObject* wrap_delitem(PyObject* self, PyObject* args, void* wrapped) noexcept {
objobjargproc func = (objobjargproc)wrapped;
int res;
PyObject* key;
......@@ -277,6 +277,15 @@ static PyObject* wrap_delitem(PyObject* self, PyObject* args, void* wrapped) {
return Py_None;
}
static PyObject* wrap_init(PyObject* self, PyObject* args, void* wrapped, PyObject* kwds) noexcept {
initproc func = (initproc)wrapped;
if (func(self, args, kwds) < 0)
return NULL;
Py_INCREF(Py_None);
return Py_None;
}
static PyObject* lookup_maybe(PyObject* self, const char* attrstr, PyObject** attrobj) noexcept {
......@@ -395,7 +404,7 @@ static const char* name_op[] = {
"__lt__", "__le__", "__eq__", "__ne__", "__gt__", "__ge__",
};
static PyObject* half_richcompare(PyObject* self, PyObject* other, int op) {
static PyObject* half_richcompare(PyObject* self, PyObject* other, int op) noexcept {
PyObject* func, *args, *res;
static PyObject* op_str[6];
......@@ -416,7 +425,7 @@ static PyObject* half_richcompare(PyObject* self, PyObject* other, int op) {
return res;
}
static PyObject* slot_tp_richcompare(PyObject* self, PyObject* other, int op) {
static PyObject* slot_tp_richcompare(PyObject* self, PyObject* other, int op) noexcept {
PyObject* res;
if (Py_TYPE(self)->tp_richcompare == slot_tp_richcompare) {
......@@ -449,6 +458,26 @@ PyObject* slot_tp_new(PyTypeObject* self, PyObject* args, PyObject* kwds) noexce
}
}
static int slot_tp_init(PyObject* self, PyObject* args, PyObject* kwds) noexcept {
static PyObject* init_str;
PyObject* meth = lookup_method(self, "__init__", &init_str);
PyObject* res;
if (meth == NULL)
return -1;
res = PyObject_Call(meth, args, kwds);
Py_DECREF(meth);
if (res == NULL)
return -1;
if (res != Py_None) {
PyErr_Format(PyExc_TypeError, "__init__() should return None, not '%.200s'", Py_TYPE(res)->tp_name);
Py_DECREF(res);
return -1;
}
Py_DECREF(res);
return 0;
}
PyObject* slot_sq_item(PyObject* self, Py_ssize_t i) noexcept {
try {
return getitem(self, boxInt(i));
......@@ -457,7 +486,7 @@ PyObject* slot_sq_item(PyObject* self, Py_ssize_t i) noexcept {
}
}
static Py_ssize_t slot_sq_length(PyObject* self) {
static Py_ssize_t slot_sq_length(PyObject* self) noexcept {
static PyObject* len_str;
PyObject* res = call_method(self, "__len__", &len_str, "()");
Py_ssize_t len;
......@@ -474,7 +503,7 @@ static Py_ssize_t slot_sq_length(PyObject* self) {
return len;
}
static PyObject* slot_sq_slice(PyObject* self, Py_ssize_t i, Py_ssize_t j) {
static PyObject* slot_sq_slice(PyObject* self, Py_ssize_t i, Py_ssize_t j) noexcept {
static PyObject* getslice_str;
if (PyErr_WarnPy3k("in 3.x, __getslice__ has been removed; "
......@@ -664,6 +693,10 @@ static slotdef slotdefs[] = {
TPSLOT("__ne__", tp_richcompare, slot_tp_richcompare, richcmp_ne, "x.__ne__(y) <==> x!=y"),
TPSLOT("__gt__", tp_richcompare, slot_tp_richcompare, richcmp_gt, "x.__gt__(y) <==> x>y"),
TPSLOT("__ge__", tp_richcompare, slot_tp_richcompare, richcmp_ge, "x.__ge__(y) <==> x>=y"),
FLSLOT("__init__", tp_init, slot_tp_init, (wrapperfunc)wrap_init, "x.__init__(...) initializes x; "
"see help(type(x)) for signature",
PyWrapperFlag_KEYWORDS),
TPSLOT("__new__", tp_new, slot_tp_new, NULL, ""),
MPSLOT("__len__", mp_length, slot_mp_length, wrap_lenfunc, "x.__len__() <==> len(x)"),
......@@ -809,7 +842,7 @@ extern "C" int PyType_Ready(PyTypeObject* cls) {
RELEASE_ASSERT(cls->tp_as_number == NULL, "");
RELEASE_ASSERT(cls->tp_str == NULL, "");
RELEASE_ASSERT(cls->tp_getattro == NULL || cls->tp_getattro == PyObject_GenericGetAttr, "");
RELEASE_ASSERT(cls->tp_setattro == NULL, "");
RELEASE_ASSERT(cls->tp_setattro == NULL || cls->tp_setattro == PyObject_GenericSetAttr, "");
RELEASE_ASSERT(cls->tp_as_buffer == NULL, "");
int ALLOWABLE_FLAGS = Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE | Py_TPFLAGS_HAVE_GC;
......@@ -820,8 +853,7 @@ extern "C" int PyType_Ready(PyTypeObject* cls) {
RELEASE_ASSERT(cls->tp_base == NULL, "");
RELEASE_ASSERT(cls->tp_descr_get == NULL, "");
RELEASE_ASSERT(cls->tp_descr_set == NULL, "");
RELEASE_ASSERT(cls->tp_init == NULL, "");
RELEASE_ASSERT(cls->tp_alloc == NULL, "");
RELEASE_ASSERT(cls->tp_alloc == NULL || cls->tp_alloc == PyType_GenericAlloc, "");
RELEASE_ASSERT(cls->tp_free == NULL || cls->tp_free == PyObject_Del, "");
RELEASE_ASSERT(cls->tp_is_gc == NULL, "");
RELEASE_ASSERT(cls->tp_base == NULL, "");
......
......@@ -127,6 +127,11 @@ extern "C" Py_ssize_t PyDict_Size(PyObject* op) {
return static_cast<BoxedDict*>(op)->d.size();
}
extern "C" void PyDict_Clear(PyObject* op) {
RELEASE_ASSERT(PyDict_Check(op), "");
static_cast<BoxedDict*>(op)->d.clear();
}
Box* dictGetitem(BoxedDict* self, Box* k) {
assert(self->cls == dict_cls);
......
......@@ -32,6 +32,32 @@ namespace pyston {
BoxedClass* long_cls;
#define IS_LITTLE_ENDIAN (int)*(unsigned char*)&one
#define PY_ABS_LLONG_MIN (0 - (unsigned PY_LONG_LONG)PY_LLONG_MIN)
extern "C" int _PyLong_Sign(PyObject* l) {
return mpz_sgn(static_cast<BoxedLong*>(l)->n);
}
extern "C" unsigned PY_LONG_LONG PyLong_AsUnsignedLongLong(PyObject* vv) {
unsigned PY_LONG_LONG bytes;
int one = 1;
int res;
if (vv == NULL || !PyLong_Check(vv)) {
PyErr_BadInternalCall();
return (unsigned PY_LONG_LONG) - 1;
}
res = _PyLong_AsByteArray((PyLongObject*)vv, (unsigned char*)&bytes, SIZEOF_LONG_LONG, IS_LITTLE_ENDIAN, 0);
/* Plan 9 can't handle PY_LONG_LONG in ? : expressions */
if (res < 0)
return (unsigned PY_LONG_LONG)res;
else
return bytes;
}
extern "C" unsigned long PyLong_AsUnsignedLongMask(PyObject* op) {
Py_FatalError("unimplemented");
}
......@@ -133,9 +159,6 @@ extern "C" PyObject* PyLong_FromUnsignedLong(unsigned long ival) {
return rtn;
}
#define IS_LITTLE_ENDIAN (int)*(unsigned char*)&one
#define PY_ABS_LLONG_MIN (0 - (unsigned PY_LONG_LONG)PY_LLONG_MIN)
extern "C" PyObject* PyLong_FromSsize_t(Py_ssize_t ival) {
Py_ssize_t bytes = ival;
int one = 1;
......@@ -154,6 +177,73 @@ extern "C" double _PyLong_Frexp(PyLongObject* a, Py_ssize_t* e) {
Py_FatalError("unimplemented");
}
/* Create a new long (or int) object from a C pointer */
extern "C" PyObject* PyLong_FromVoidPtr(void* p) {
#if SIZEOF_VOID_P <= SIZEOF_LONG
if ((long)p < 0)
return PyLong_FromUnsignedLong((unsigned long)p);
return PyInt_FromLong((long)p);
#else
#ifndef HAVE_LONG_LONG
#error "PyLong_FromVoidPtr: sizeof(void*) > sizeof(long), but no long long"
#endif
#if SIZEOF_LONG_LONG < SIZEOF_VOID_P
#error "PyLong_FromVoidPtr: sizeof(PY_LONG_LONG) < sizeof(void*)"
#endif
/* optimize null pointers */
if (p == NULL)
return PyInt_FromLong(0);
return PyLong_FromUnsignedLongLong((unsigned PY_LONG_LONG)p);
#endif /* SIZEOF_VOID_P <= SIZEOF_LONG */
}
/* Get a C pointer from a long object (or an int object in some cases) */
extern "C" void* PyLong_AsVoidPtr(PyObject* vv) {
/* This function will allow int or long objects. If vv is neither,
then the PyLong_AsLong*() functions will raise the exception:
PyExc_SystemError, "bad argument to internal function"
*/
#if SIZEOF_VOID_P <= SIZEOF_LONG
long x;
if (PyInt_Check(vv))
x = PyInt_AS_LONG(vv);
else if (PyLong_Check(vv) && _PyLong_Sign(vv) < 0)
x = PyLong_AsLong(vv);
else
x = PyLong_AsUnsignedLong(vv);
#else
#ifndef HAVE_LONG_LONG
#error "PyLong_AsVoidPtr: sizeof(void*) > sizeof(long), but no long long"
#endif
#if SIZEOF_LONG_LONG < SIZEOF_VOID_P
#error "PyLong_AsVoidPtr: sizeof(PY_LONG_LONG) < sizeof(void*)"
#endif
PY_LONG_LONG x;
if (PyInt_Check(vv))
x = PyInt_AS_LONG(vv);
else if (PyLong_Check(vv) && _PyLong_Sign(vv) < 0)
x = PyLong_AsLongLong(vv);
else
x = PyLong_AsUnsignedLongLong(vv);
#endif /* SIZEOF_VOID_P <= SIZEOF_LONG */
if (x == -1 && PyErr_Occurred())
return NULL;
return (void*)x;
}
extern "C" int _PyLong_AsByteArray(PyLongObject* v, unsigned char* bytes, size_t n, int little_endian, int is_signed) {
Py_FatalError("unimplemented");
}
extern "C" PyObject* _PyLong_FromByteArray(const unsigned char* bytes, size_t n, int little_endian, int is_signed) {
if (n == 0)
return PyLong_FromLong(0);
......
......@@ -46,6 +46,7 @@ extern "C" void initoperator();
extern "C" void initbinascii();
extern "C" void initpwd();
extern "C" void initposix();
extern "C" void init_struct();
namespace pyston {
......@@ -995,6 +996,7 @@ void setupRuntime() {
initbinascii();
initpwd();
initposix();
init_struct();
setupSysEnd();
......
......@@ -18,16 +18,26 @@ slots_tester_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
if (!PyArg_ParseTuple(args, "i", &n))
return NULL;
printf("slots_tester_seq.__new__, %d\n", n);
/* create attrgetterobject structure */
obj = PyObject_New(slots_tester_object, type);
if (obj == NULL)
return NULL;
obj->n = n;
obj->n = n - 1;
return (PyObject *)obj;
}
static int
slots_tester_init(PyObject *self, PyObject *args, PyObject *kwds)
{
printf("slots_tester_seq.__init__, %d\n", ((slots_tester_object*)self)->n);
return 0;
}
static long slots_tester_seq_hash(slots_tester_object* obj) {
printf("slots_tester_seq.__hash__\n");
return obj->n ^ 1;
......@@ -121,7 +131,7 @@ static PyTypeObject slots_tester_seq = {
0, /* tp_descr_get */
0, /* tp_descr_set */
0, /* tp_dictoffset */
0, /* tp_init */
slots_tester_init, /* tp_init */
0, /* tp_alloc */
slots_tester_new, /* tp_new */
0, /* tp_free */
......@@ -216,6 +226,18 @@ call_funcs(PyObject* _module, PyObject* args) {
Py_DECREF(rtn);
}
if (cls->tp_new) {
printf("tp_new exists\n");
} else {
printf("tp_new doesnt exist\n");
}
if (cls->tp_init) {
printf("tp_init exists\n");
} else {
printf("tp_init doesnt exist\n");
}
if (cls->tp_call) {
printf("tp_call exists\n");
} else {
......
import pickle
l = [[], (123,)]
l.append(l)
s = pickle.dumps(l)
print repr(s)
l2 = pickle.loads(s)
l3 = l2.pop()
print l2, l3, l2 is l3
# This doesn't work yet; we need str.decode("string-escape")
# print pickle.loads(pickle.dumps("hello world"))
import struct
s = struct.pack("II", 1, 1234)
print repr(s)
print struct.unpack("II", s)
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