Commit 732bbc40 authored by Marius Wachtler's avatar Marius Wachtler

Move PyNumber_* funcs from capi.cpp to abstract.cpp

parent 2470ef9f
......@@ -309,6 +309,32 @@ extern "C" PyObject* PyObject_CallObject(PyObject* obj, PyObject* args) noexcept
}
}
extern "C" int PyObject_AsCharBuffer(PyObject* obj, const char** buffer, Py_ssize_t* buffer_len) noexcept {
PyBufferProcs* pb;
char* 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_getcharbuffer == NULL || pb->bf_getsegcount == NULL) {
PyErr_SetString(PyExc_TypeError, "expected a character 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_getcharbuffer)(obj, 0, &pp);
if (len < 0)
return -1;
*buffer = pp;
*buffer_len = len;
return 0;
}
extern "C" int PyObject_AsReadBuffer(PyObject* obj, const void** buffer, Py_ssize_t* buffer_len) noexcept {
Py_FatalError("unimplemented");
}
......@@ -852,4 +878,285 @@ extern "C" PyObject* PyMapping_GetItemString(PyObject* o, char* key) noexcept {
extern "C" int PyMapping_SetItemString(PyObject* o, char* key, PyObject* v) noexcept {
Py_FatalError("unimplemented");
}
extern "C" int PyNumber_Check(PyObject* obj) noexcept {
assert(obj && obj->cls);
// Our check, since we don't currently fill in tp_as_number:
if (isSubclass(obj->cls, int_cls) || isSubclass(obj->cls, long_cls))
return true;
// The CPython check:
return obj->cls->tp_as_number && (obj->cls->tp_as_number->nb_int || obj->cls->tp_as_number->nb_float);
}
extern "C" PyObject* PyNumber_Add(PyObject* lhs, PyObject* rhs) noexcept {
try {
return binop(lhs, rhs, AST_TYPE::Add);
} catch (ExcInfo e) {
setCAPIException(e);
return NULL;
}
}
extern "C" PyObject* PyNumber_Subtract(PyObject* lhs, PyObject* rhs) noexcept {
try {
return binop(lhs, rhs, AST_TYPE::Sub);
} catch (ExcInfo e) {
Py_FatalError("unimplemented");
}
}
extern "C" PyObject* PyNumber_Multiply(PyObject* lhs, PyObject* rhs) noexcept {
try {
return binop(lhs, rhs, AST_TYPE::Mult);
} catch (ExcInfo e) {
Py_FatalError("unimplemented");
}
}
extern "C" PyObject* PyNumber_Divide(PyObject* lhs, PyObject* rhs) noexcept {
try {
return binop(lhs, rhs, AST_TYPE::Div);
} catch (ExcInfo e) {
Py_FatalError("unimplemented");
}
}
extern "C" PyObject* PyNumber_FloorDivide(PyObject*, PyObject*) noexcept {
Py_FatalError("unimplemented");
}
extern "C" PyObject* PyNumber_TrueDivide(PyObject*, PyObject*) noexcept {
Py_FatalError("unimplemented");
}
extern "C" PyObject* PyNumber_Remainder(PyObject* lhs, PyObject* rhs) noexcept {
try {
return binop(lhs, rhs, AST_TYPE::Mod);
} catch (ExcInfo e) {
Py_FatalError("unimplemented");
}
}
extern "C" PyObject* PyNumber_Divmod(PyObject*, PyObject*) noexcept {
Py_FatalError("unimplemented");
}
extern "C" PyObject* PyNumber_Power(PyObject*, PyObject*, PyObject* o3) noexcept {
Py_FatalError("unimplemented");
}
extern "C" PyObject* PyNumber_Negative(PyObject* o) noexcept {
Py_FatalError("unimplemented");
}
extern "C" PyObject* PyNumber_Positive(PyObject* o) noexcept {
Py_FatalError("unimplemented");
}
extern "C" PyObject* PyNumber_Absolute(PyObject* o) noexcept {
try {
return abs_(o);
} catch (ExcInfo e) {
Py_FatalError("unimplemented");
}
}
extern "C" PyObject* PyNumber_Invert(PyObject* o) noexcept {
Py_FatalError("unimplemented");
}
extern "C" PyObject* PyNumber_Lshift(PyObject*, PyObject*) noexcept {
Py_FatalError("unimplemented");
}
extern "C" PyObject* PyNumber_Rshift(PyObject* lhs, PyObject* rhs) noexcept {
try {
return binop(lhs, rhs, AST_TYPE::RShift);
} catch (ExcInfo e) {
Py_FatalError("unimplemented");
}
}
extern "C" PyObject* PyNumber_And(PyObject* lhs, PyObject* rhs) noexcept {
try {
return binop(lhs, rhs, AST_TYPE::BitAnd);
} catch (ExcInfo e) {
Py_FatalError("unimplemented");
}
}
extern "C" PyObject* PyNumber_Xor(PyObject*, PyObject*) noexcept {
Py_FatalError("unimplemented");
}
extern "C" PyObject* PyNumber_Or(PyObject*, PyObject*) noexcept {
Py_FatalError("unimplemented");
}
extern "C" PyObject* PyNumber_InPlaceAdd(PyObject*, PyObject*) noexcept {
Py_FatalError("unimplemented");
}
extern "C" PyObject* PyNumber_InPlaceSubtract(PyObject*, PyObject*) noexcept {
Py_FatalError("unimplemented");
}
extern "C" PyObject* PyNumber_InPlaceMultiply(PyObject*, PyObject*) noexcept {
Py_FatalError("unimplemented");
}
extern "C" PyObject* PyNumber_InPlaceDivide(PyObject*, PyObject*) noexcept {
Py_FatalError("unimplemented");
}
extern "C" PyObject* PyNumber_InPlaceFloorDivide(PyObject*, PyObject*) noexcept {
Py_FatalError("unimplemented");
}
extern "C" PyObject* PyNumber_InPlaceTrueDivide(PyObject*, PyObject*) noexcept {
Py_FatalError("unimplemented");
}
extern "C" PyObject* PyNumber_InPlaceRemainder(PyObject*, PyObject*) noexcept {
Py_FatalError("unimplemented");
}
extern "C" PyObject* PyNumber_InPlacePower(PyObject*, PyObject*, PyObject* o3) noexcept {
Py_FatalError("unimplemented");
}
extern "C" PyObject* PyNumber_InPlaceLshift(PyObject*, PyObject*) noexcept {
Py_FatalError("unimplemented");
}
extern "C" PyObject* PyNumber_InPlaceRshift(PyObject*, PyObject*) noexcept {
Py_FatalError("unimplemented");
}
extern "C" PyObject* PyNumber_InPlaceAnd(PyObject*, PyObject*) noexcept {
Py_FatalError("unimplemented");
}
extern "C" PyObject* PyNumber_InPlaceXor(PyObject*, PyObject*) noexcept {
Py_FatalError("unimplemented");
}
extern "C" PyObject* PyNumber_InPlaceOr(PyObject*, PyObject*) noexcept {
Py_FatalError("unimplemented");
}
extern "C" int PyNumber_Coerce(PyObject**, PyObject**) noexcept {
Py_FatalError("unimplemented");
}
extern "C" int PyNumber_CoerceEx(PyObject**, PyObject**) noexcept {
Py_FatalError("unimplemented");
}
extern "C" PyObject* PyNumber_Int(PyObject* o) noexcept {
PyNumberMethods* m;
const char* buffer;
Py_ssize_t buffer_len;
if (o == NULL) {
PyErr_SetString(PyExc_SystemError, "null argument to internal routing");
return NULL;
}
if (PyInt_CheckExact(o)) {
Py_INCREF(o);
return o;
}
m = o->cls->tp_as_number;
if (m && m->nb_int) { /* This should include subclasses of int */
/* Classic classes always take this branch. */
PyObject* res = m->nb_int(o);
if (res && (!PyInt_Check(res) && !PyLong_Check(res))) {
PyErr_Format(PyExc_TypeError, "__int__ returned non-int (type %.200s)", res->cls->tp_name);
Py_DECREF(res);
return NULL;
}
return res;
}
if (PyInt_Check(o)) { /* A int subclass without nb_int */
BoxedInt* io = (BoxedInt*)o;
return PyInt_FromLong(io->n);
}
Py_FatalError("unimplemented __trunc__ and string -> int conversion");
// the remainder of PyNumber_Int deals with __trunc__ usage, and converting from unicode/string to int
#if 0
PyObject* trunc_func = getattr(o, "__trunc__");
if (trunc_func) {
PyObject *truncated = PyEval_CallObject(trunc_func, NULL);
Py_DECREF(trunc_func);
/* __trunc__ is specified to return an Integral type, but
int() needs to return an int. */
return _PyNumber_ConvertIntegralToInt(
truncated,
"__trunc__ returned non-Integral (type %.200s)");
}
PyErr_Clear(); /* It's not an error if o.__trunc__ doesn't exist. */
if (PyString_Check(o))
return int_from_string(PyString_AS_STRING(o),
PyString_GET_SIZE(o));
#ifdef Py_USING_UNICODE
if (PyUnicode_Check(o))
return PyInt_FromUnicode(PyUnicode_AS_UNICODE(o),
PyUnicode_GET_SIZE(o),
10);
#endif
if (!PyObject_AsCharBuffer(o, &buffer, &buffer_len))
return int_from_string((char*)buffer, buffer_len);
return type_error("int() argument must be a string or a "
"number, not '%.200s'", o);
#endif
}
extern "C" PyObject* PyNumber_Long(PyObject* o) noexcept {
// This method should do quite a bit more, including checking tp_as_number->nb_long or calling __trunc__
if (o->cls == long_cls)
return o;
if (o->cls == float_cls)
return PyLong_FromDouble(PyFloat_AsDouble(o));
Py_FatalError("unimplemented");
}
extern "C" PyObject* PyNumber_Float(PyObject* o) noexcept {
Py_FatalError("unimplemented");
}
extern "C" PyObject* PyNumber_Index(PyObject* o) noexcept {
PyObject* result = NULL;
if (o == NULL)
return null_error();
if (PyInt_Check(o) || PyLong_Check(o)) {
return o;
}
Py_FatalError("unimplemented");
}
extern "C" PyObject* PyNumber_ToBase(PyObject* n, int base) noexcept {
Py_FatalError("unimplemented");
}
extern "C" Py_ssize_t PyNumber_AsSsize_t(PyObject* o, PyObject* exc) noexcept {
if (isSubclass(o->cls, int_cls)) {
int64_t n = static_cast<BoxedInt*>(o)->n;
static_assert(sizeof(n) == sizeof(Py_ssize_t), "");
return n;
} else if (isSubclass(o->cls, long_cls)) {
return PyLong_AsSsize_t(o);
}
Py_FatalError("unimplemented");
}
}
......@@ -86,38 +86,6 @@ Box* BoxedWrapperDescriptor::__get__(BoxedWrapperDescriptor* self, Box* inst, Bo
return new BoxedWrapperObject(self, inst);
}
static PyObject* null_error(void) {
if (!PyErr_Occurred())
PyErr_SetString(PyExc_SystemError, "null argument to internal routine");
return NULL;
}
extern "C" int PyObject_AsCharBuffer(PyObject* obj, const char** buffer, Py_ssize_t* buffer_len) noexcept {
PyBufferProcs* pb;
char* 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_getcharbuffer == NULL || pb->bf_getsegcount == NULL) {
PyErr_SetString(PyExc_TypeError, "expected a character 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_getcharbuffer)(obj, 0, &pp);
if (len < 0)
return -1;
*buffer = pp;
*buffer_len = len;
return 0;
}
// copied from CPython's getargs.c:
extern "C" int PyBuffer_FillInfo(Py_buffer* view, PyObject* obj, void* buf, Py_ssize_t len, int readonly,
int flags) noexcept {
......@@ -957,286 +925,7 @@ extern "C" void PyMem_Free(void* ptr) noexcept {
gc_compat_free(ptr);
}
extern "C" int PyNumber_Check(PyObject* obj) noexcept {
assert(obj && obj->cls);
// Our check, since we don't currently fill in tp_as_number:
if (isSubclass(obj->cls, int_cls) || isSubclass(obj->cls, long_cls))
return true;
// The CPython check:
return obj->cls->tp_as_number && (obj->cls->tp_as_number->nb_int || obj->cls->tp_as_number->nb_float);
}
extern "C" PyObject* PyNumber_Add(PyObject* lhs, PyObject* rhs) noexcept {
try {
return binop(lhs, rhs, AST_TYPE::Add);
} catch (ExcInfo e) {
setCAPIException(e);
return NULL;
}
}
extern "C" PyObject* PyNumber_Subtract(PyObject* lhs, PyObject* rhs) noexcept {
try {
return binop(lhs, rhs, AST_TYPE::Sub);
} catch (ExcInfo e) {
Py_FatalError("unimplemented");
}
}
extern "C" PyObject* PyNumber_Multiply(PyObject* lhs, PyObject* rhs) noexcept {
try {
return binop(lhs, rhs, AST_TYPE::Mult);
} catch (ExcInfo e) {
Py_FatalError("unimplemented");
}
}
extern "C" PyObject* PyNumber_Divide(PyObject* lhs, PyObject* rhs) noexcept {
try {
return binop(lhs, rhs, AST_TYPE::Div);
} catch (ExcInfo e) {
Py_FatalError("unimplemented");
}
}
extern "C" PyObject* PyNumber_FloorDivide(PyObject*, PyObject*) noexcept {
Py_FatalError("unimplemented");
}
extern "C" PyObject* PyNumber_TrueDivide(PyObject*, PyObject*) noexcept {
Py_FatalError("unimplemented");
}
extern "C" PyObject* PyNumber_Remainder(PyObject* lhs, PyObject* rhs) noexcept {
try {
return binop(lhs, rhs, AST_TYPE::Mod);
} catch (ExcInfo e) {
Py_FatalError("unimplemented");
}
}
extern "C" PyObject* PyNumber_Divmod(PyObject*, PyObject*) noexcept {
Py_FatalError("unimplemented");
}
extern "C" PyObject* PyNumber_Power(PyObject*, PyObject*, PyObject* o3) noexcept {
Py_FatalError("unimplemented");
}
extern "C" PyObject* PyNumber_Negative(PyObject* o) noexcept {
Py_FatalError("unimplemented");
}
extern "C" PyObject* PyNumber_Positive(PyObject* o) noexcept {
Py_FatalError("unimplemented");
}
extern "C" PyObject* PyNumber_Absolute(PyObject* o) noexcept {
try {
return abs_(o);
} catch (ExcInfo e) {
Py_FatalError("unimplemented");
}
}
extern "C" PyObject* PyNumber_Invert(PyObject* o) noexcept {
Py_FatalError("unimplemented");
}
extern "C" PyObject* PyNumber_Lshift(PyObject*, PyObject*) noexcept {
Py_FatalError("unimplemented");
}
extern "C" PyObject* PyNumber_Rshift(PyObject* lhs, PyObject* rhs) noexcept {
try {
return binop(lhs, rhs, AST_TYPE::RShift);
} catch (ExcInfo e) {
Py_FatalError("unimplemented");
}
}
extern "C" PyObject* PyNumber_And(PyObject* lhs, PyObject* rhs) noexcept {
try {
return binop(lhs, rhs, AST_TYPE::BitAnd);
} catch (ExcInfo e) {
Py_FatalError("unimplemented");
}
}
extern "C" PyObject* PyNumber_Xor(PyObject*, PyObject*) noexcept {
Py_FatalError("unimplemented");
}
extern "C" PyObject* PyNumber_Or(PyObject*, PyObject*) noexcept {
Py_FatalError("unimplemented");
}
extern "C" PyObject* PyNumber_InPlaceAdd(PyObject*, PyObject*) noexcept {
Py_FatalError("unimplemented");
}
extern "C" PyObject* PyNumber_InPlaceSubtract(PyObject*, PyObject*) noexcept {
Py_FatalError("unimplemented");
}
extern "C" PyObject* PyNumber_InPlaceMultiply(PyObject*, PyObject*) noexcept {
Py_FatalError("unimplemented");
}
extern "C" PyObject* PyNumber_InPlaceDivide(PyObject*, PyObject*) noexcept {
Py_FatalError("unimplemented");
}
extern "C" PyObject* PyNumber_InPlaceFloorDivide(PyObject*, PyObject*) noexcept {
Py_FatalError("unimplemented");
}
extern "C" PyObject* PyNumber_InPlaceTrueDivide(PyObject*, PyObject*) noexcept {
Py_FatalError("unimplemented");
}
extern "C" PyObject* PyNumber_InPlaceRemainder(PyObject*, PyObject*) noexcept {
Py_FatalError("unimplemented");
}
extern "C" PyObject* PyNumber_InPlacePower(PyObject*, PyObject*, PyObject* o3) noexcept {
Py_FatalError("unimplemented");
}
extern "C" PyObject* PyNumber_InPlaceLshift(PyObject*, PyObject*) noexcept {
Py_FatalError("unimplemented");
}
extern "C" PyObject* PyNumber_InPlaceRshift(PyObject*, PyObject*) noexcept {
Py_FatalError("unimplemented");
}
extern "C" PyObject* PyNumber_InPlaceAnd(PyObject*, PyObject*) noexcept {
Py_FatalError("unimplemented");
}
extern "C" PyObject* PyNumber_InPlaceXor(PyObject*, PyObject*) noexcept {
Py_FatalError("unimplemented");
}
extern "C" PyObject* PyNumber_InPlaceOr(PyObject*, PyObject*) noexcept {
Py_FatalError("unimplemented");
}
extern "C" int PyNumber_Coerce(PyObject**, PyObject**) noexcept {
Py_FatalError("unimplemented");
}
extern "C" int PyNumber_CoerceEx(PyObject**, PyObject**) noexcept {
Py_FatalError("unimplemented");
}
extern "C" PyObject* PyNumber_Int(PyObject* o) noexcept {
PyNumberMethods* m;
const char* buffer;
Py_ssize_t buffer_len;
if (o == NULL) {
PyErr_SetString(PyExc_SystemError, "null argument to internal routing");
return NULL;
}
if (PyInt_CheckExact(o)) {
Py_INCREF(o);
return o;
}
m = o->cls->tp_as_number;
if (m && m->nb_int) { /* This should include subclasses of int */
/* Classic classes always take this branch. */
PyObject* res = m->nb_int(o);
if (res && (!PyInt_Check(res) && !PyLong_Check(res))) {
PyErr_Format(PyExc_TypeError, "__int__ returned non-int (type %.200s)", res->cls->tp_name);
Py_DECREF(res);
return NULL;
}
return res;
}
if (PyInt_Check(o)) { /* A int subclass without nb_int */
BoxedInt* io = (BoxedInt*)o;
return PyInt_FromLong(io->n);
}
Py_FatalError("unimplemented __trunc__ and string -> int conversion");
// the remainder of PyNumber_Int deals with __trunc__ usage, and converting from unicode/string to int
#if 0
PyObject* trunc_func = getattr(o, "__trunc__");
if (trunc_func) {
PyObject *truncated = PyEval_CallObject(trunc_func, NULL);
Py_DECREF(trunc_func);
/* __trunc__ is specified to return an Integral type, but
int() needs to return an int. */
return _PyNumber_ConvertIntegralToInt(
truncated,
"__trunc__ returned non-Integral (type %.200s)");
}
PyErr_Clear(); /* It's not an error if o.__trunc__ doesn't exist. */
if (PyString_Check(o))
return int_from_string(PyString_AS_STRING(o),
PyString_GET_SIZE(o));
#ifdef Py_USING_UNICODE
if (PyUnicode_Check(o))
return PyInt_FromUnicode(PyUnicode_AS_UNICODE(o),
PyUnicode_GET_SIZE(o),
10);
#endif
if (!PyObject_AsCharBuffer(o, &buffer, &buffer_len))
return int_from_string((char*)buffer, buffer_len);
return type_error("int() argument must be a string or a "
"number, not '%.200s'", o);
#endif
}
extern "C" PyObject* PyNumber_Long(PyObject* o) noexcept {
// This method should do quite a bit more, including checking tp_as_number->nb_long or calling __trunc__
if (o->cls == long_cls)
return o;
if (o->cls == float_cls)
return PyLong_FromDouble(PyFloat_AsDouble(o));
Py_FatalError("unimplemented");
}
extern "C" PyObject* PyNumber_Float(PyObject* o) noexcept {
Py_FatalError("unimplemented");
}
extern "C" PyObject* PyNumber_Index(PyObject* o) noexcept {
PyObject* result = NULL;
if (o == NULL)
return null_error();
if (PyInt_Check(o) || PyLong_Check(o)) {
return o;
}
Py_FatalError("unimplemented");
}
extern "C" PyObject* PyNumber_ToBase(PyObject* n, int base) noexcept {
Py_FatalError("unimplemented");
}
extern "C" Py_ssize_t PyNumber_AsSsize_t(PyObject* o, PyObject* exc) noexcept {
if (isSubclass(o->cls, int_cls)) {
int64_t n = static_cast<BoxedInt*>(o)->n;
static_assert(sizeof(n) == sizeof(Py_ssize_t), "");
return n;
} else if (isSubclass(o->cls, long_cls)) {
return PyLong_AsSsize_t(o);
}
Py_FatalError("unimplemented");
}
static int _IsFortranContiguous(Py_buffer* view) {
Py_ssize_t sd, dim;
......
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