Commit 4c729f7b authored by Kevin Modzelewski's avatar Kevin Modzelewski

Make str more subclassing friendly

Also, try to set the HAVE_NEWBUFFER flag more accurately
parent 7de279c8
...@@ -135,7 +135,9 @@ extern "C" void PyBuffer_Release(Py_buffer* view) noexcept { ...@@ -135,7 +135,9 @@ extern "C" void PyBuffer_Release(Py_buffer* view) noexcept {
PyObject* obj = view->obj; PyObject* obj = view->obj;
if (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) 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_TYPE(obj)->tp_as_buffer->bf_releasebuffer(obj, view);
Py_XDECREF(obj); Py_XDECREF(obj);
......
...@@ -304,6 +304,9 @@ BoxedClass::BoxedClass(BoxedClass* base, gcvisit_func gc_visit, int attrs_offset ...@@ -304,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_GC;
tp_flags |= Py_TPFLAGS_HAVE_WEAKREFS; tp_flags |= Py_TPFLAGS_HAVE_WEAKREFS;
if (base && (base->tp_flags & Py_TPFLAGS_HAVE_NEWBUFFER))
tp_flags |= Py_TPFLAGS_HAVE_NEWBUFFER;
tp_base = base; tp_base = base;
if (tp_base) { if (tp_base) {
......
...@@ -296,7 +296,7 @@ extern "C" PyObject* PyString_FromFormat(const char* format, ...) noexcept { ...@@ -296,7 +296,7 @@ extern "C" PyObject* PyString_FromFormat(const char* format, ...) noexcept {
} }
extern "C" Box* strAdd(BoxedString* lhs, Box* _rhs) { extern "C" Box* strAdd(BoxedString* lhs, Box* _rhs) {
assert(lhs->cls == str_cls); assert(isSubclass(lhs->cls, str_cls));
if (_rhs->cls == unicode_cls) { if (_rhs->cls == unicode_cls) {
Box* rtn = PyUnicode_Concat(lhs, _rhs); Box* rtn = PyUnicode_Concat(lhs, _rhs);
...@@ -934,7 +934,7 @@ extern "C" Box* strMod(BoxedString* lhs, Box* rhs) { ...@@ -934,7 +934,7 @@ extern "C" Box* strMod(BoxedString* lhs, Box* rhs) {
} }
extern "C" Box* strMul(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; int n;
if (isSubclass(rhs->cls, int_cls)) if (isSubclass(rhs->cls, int_cls))
...@@ -952,7 +952,7 @@ extern "C" Box* strMul(BoxedString* lhs, Box* rhs) { ...@@ -952,7 +952,7 @@ extern "C" Box* strMul(BoxedString* lhs, Box* rhs) {
} }
extern "C" Box* strLt(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) if (rhs->cls != str_cls)
return NotImplemented; return NotImplemented;
...@@ -962,7 +962,7 @@ extern "C" Box* strLt(BoxedString* lhs, Box* rhs) { ...@@ -962,7 +962,7 @@ extern "C" Box* strLt(BoxedString* lhs, Box* rhs) {
} }
extern "C" Box* strLe(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) if (rhs->cls != str_cls)
return NotImplemented; return NotImplemented;
...@@ -972,7 +972,7 @@ extern "C" Box* strLe(BoxedString* lhs, Box* rhs) { ...@@ -972,7 +972,7 @@ extern "C" Box* strLe(BoxedString* lhs, Box* rhs) {
} }
extern "C" Box* strGt(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) if (rhs->cls != str_cls)
return NotImplemented; return NotImplemented;
...@@ -982,7 +982,7 @@ extern "C" Box* strGt(BoxedString* lhs, Box* rhs) { ...@@ -982,7 +982,7 @@ extern "C" Box* strGt(BoxedString* lhs, Box* rhs) {
} }
extern "C" Box* strGe(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) if (rhs->cls != str_cls)
return NotImplemented; return NotImplemented;
...@@ -992,7 +992,7 @@ extern "C" Box* strGe(BoxedString* lhs, Box* rhs) { ...@@ -992,7 +992,7 @@ extern "C" Box* strGe(BoxedString* lhs, Box* rhs) {
} }
extern "C" Box* strEq(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) if (rhs->cls != str_cls)
return NotImplemented; return NotImplemented;
...@@ -1002,7 +1002,7 @@ extern "C" Box* strEq(BoxedString* lhs, Box* rhs) { ...@@ -1002,7 +1002,7 @@ extern "C" Box* strEq(BoxedString* lhs, Box* rhs) {
} }
extern "C" Box* strNe(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) if (rhs->cls != str_cls)
return NotImplemented; return NotImplemented;
...@@ -1016,7 +1016,7 @@ extern "C" Box* strNe(BoxedString* lhs, Box* rhs) { ...@@ -1016,7 +1016,7 @@ extern "C" Box* strNe(BoxedString* lhs, Box* rhs) {
#define JUST_CENTER 2 #define JUST_CENTER 2
static Box* pad(BoxedString* self, Box* width, Box* fillchar, int justType) { static Box* pad(BoxedString* self, Box* width, Box* fillchar, int justType) {
assert(width->cls == int_cls); assert(width->cls == int_cls);
assert(fillchar->cls == str_cls); assert(isSubclass(fillchar->cls, str_cls));
assert(static_cast<BoxedString*>(fillchar)->s.size() == 1); assert(static_cast<BoxedString*>(fillchar)->s.size() == 1);
int64_t curWidth = self->s.size(); int64_t curWidth = self->s.size();
int64_t targetWidth = static_cast<BoxedInt*>(width)->n; int64_t targetWidth = static_cast<BoxedInt*>(width)->n;
...@@ -1067,13 +1067,13 @@ extern "C" Box* strCenter(BoxedString* lhs, Box* width, Box* fillchar) { ...@@ -1067,13 +1067,13 @@ extern "C" Box* strCenter(BoxedString* lhs, Box* width, Box* fillchar) {
} }
extern "C" Box* strLen(BoxedString* self) { extern "C" Box* strLen(BoxedString* self) {
assert(self->cls == str_cls); assert(isSubclass(self->cls, str_cls));
return boxInt(self->s.size()); return boxInt(self->s.size());
} }
extern "C" Box* strStr(BoxedString* self) { extern "C" Box* strStr(BoxedString* self) {
assert(self->cls == str_cls); assert(isSubclass(self->cls, str_cls));
return self; return self;
} }
...@@ -1099,7 +1099,7 @@ static char _hex[17] = "0123456789abcdef"; // really only needs to be 16 but cla ...@@ -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 { extern "C" PyObject* PyString_Repr(PyObject* obj, int smartquotes) noexcept {
BoxedString* self = (BoxedString*)obj; BoxedString* self = (BoxedString*)obj;
assert(self->cls == str_cls); assert(isSubclass(self->cls, str_cls));
std::ostringstream os(""); std::ostringstream os("");
...@@ -1333,22 +1333,28 @@ failed: ...@@ -1333,22 +1333,28 @@ failed:
} }
extern "C" Box* strHash(BoxedString* self) { extern "C" Box* strHash(BoxedString* self) {
assert(self->cls == str_cls); assert(isSubclass(self->cls, str_cls));
std::hash<std::string> H; std::hash<std::string> H;
return boxInt(H(self->s)); return boxInt(H(self->s));
} }
extern "C" Box* strNonzero(BoxedString* self) { 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); return boxBool(self->s.size() != 0);
} }
extern "C" Box* strNew(BoxedClass* cls, Box* obj) { 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) { extern "C" Box* basestringNew(BoxedClass* cls, Box* args, Box* kwargs) {
...@@ -1356,7 +1362,7 @@ 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) { 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; const std::string& s = self->s;
...@@ -1378,7 +1384,7 @@ Box* _strSlice(BoxedString* self, i64 start, i64 stop, i64 step, i64 length) { ...@@ -1378,7 +1384,7 @@ Box* _strSlice(BoxedString* self, i64 start, i64 stop, i64 step, i64 length) {
} }
Box* strIsAlpha(BoxedString* self) { Box* strIsAlpha(BoxedString* self) {
assert(self->cls == str_cls); assert(isSubclass(self->cls, str_cls));
const std::string& str(self->s); const std::string& str(self->s);
if (str.empty()) if (str.empty())
...@@ -1393,7 +1399,7 @@ Box* strIsAlpha(BoxedString* self) { ...@@ -1393,7 +1399,7 @@ Box* strIsAlpha(BoxedString* self) {
} }
Box* strIsDigit(BoxedString* self) { Box* strIsDigit(BoxedString* self) {
assert(self->cls == str_cls); assert(isSubclass(self->cls, str_cls));
const std::string& str(self->s); const std::string& str(self->s);
if (str.empty()) if (str.empty())
...@@ -1408,7 +1414,7 @@ Box* strIsDigit(BoxedString* self) { ...@@ -1408,7 +1414,7 @@ Box* strIsDigit(BoxedString* self) {
} }
Box* strIsAlnum(BoxedString* self) { Box* strIsAlnum(BoxedString* self) {
assert(self->cls == str_cls); assert(isSubclass(self->cls, str_cls));
const std::string& str(self->s); const std::string& str(self->s);
if (str.empty()) if (str.empty())
...@@ -1423,7 +1429,7 @@ Box* strIsAlnum(BoxedString* self) { ...@@ -1423,7 +1429,7 @@ Box* strIsAlnum(BoxedString* self) {
} }
Box* strIsLower(BoxedString* self) { Box* strIsLower(BoxedString* self) {
assert(self->cls == str_cls); assert(isSubclass(self->cls, str_cls));
const std::string& str(self->s); const std::string& str(self->s);
bool lowered = false; bool lowered = false;
...@@ -1445,7 +1451,7 @@ Box* strIsLower(BoxedString* self) { ...@@ -1445,7 +1451,7 @@ Box* strIsLower(BoxedString* self) {
} }
Box* strIsUpper(BoxedString* self) { Box* strIsUpper(BoxedString* self) {
assert(self->cls == str_cls); assert(isSubclass(self->cls, str_cls));
const std::string& str(self->s); const std::string& str(self->s);
bool uppered = false; bool uppered = false;
...@@ -1467,7 +1473,7 @@ Box* strIsUpper(BoxedString* self) { ...@@ -1467,7 +1473,7 @@ Box* strIsUpper(BoxedString* self) {
} }
Box* strIsSpace(BoxedString* self) { Box* strIsSpace(BoxedString* self) {
assert(self->cls == str_cls); assert(isSubclass(self->cls, str_cls));
const std::string& str(self->s); const std::string& str(self->s);
if (str.empty()) if (str.empty())
...@@ -1482,7 +1488,7 @@ Box* strIsSpace(BoxedString* self) { ...@@ -1482,7 +1488,7 @@ Box* strIsSpace(BoxedString* self) {
} }
Box* strIsTitle(BoxedString* self) { Box* strIsTitle(BoxedString* self) {
assert(self->cls == str_cls); assert(isSubclass(self->cls, str_cls));
const std::string& str(self->s); const std::string& str(self->s);
...@@ -1517,7 +1523,7 @@ Box* strIsTitle(BoxedString* self) { ...@@ -1517,7 +1523,7 @@ Box* strIsTitle(BoxedString* self) {
} }
Box* strJoin(BoxedString* self, Box* rhs) { Box* strJoin(BoxedString* self, Box* rhs) {
assert(self->cls == str_cls); assert(isSubclass(self->cls, str_cls));
std::string output_str; std::string output_str;
llvm::raw_string_ostream os(output_str); llvm::raw_string_ostream os(output_str);
...@@ -1534,7 +1540,7 @@ Box* strJoin(BoxedString* self, Box* rhs) { ...@@ -1534,7 +1540,7 @@ Box* strJoin(BoxedString* self, Box* rhs) {
extern "C" PyObject* _PyString_Join(PyObject* sep, PyObject* x) noexcept { extern "C" PyObject* _PyString_Join(PyObject* sep, PyObject* x) noexcept {
try { try {
RELEASE_ASSERT(sep->cls == str_cls, ""); RELEASE_ASSERT(isSubclass(sep->cls, str_cls), "");
return strJoin((BoxedString*)sep, x); return strJoin((BoxedString*)sep, x);
} catch (ExcInfo e) { } catch (ExcInfo e) {
setCAPIException(e); setCAPIException(e);
...@@ -1579,8 +1585,8 @@ Box* strReplace(Box* _self, Box* _old, Box* _new, Box** _args) { ...@@ -1579,8 +1585,8 @@ Box* strReplace(Box* _self, Box* _old, Box* _new, Box** _args) {
} }
Box* strPartition(BoxedString* self, BoxedString* sep) { Box* strPartition(BoxedString* self, BoxedString* sep) {
RELEASE_ASSERT(self->cls == str_cls, ""); RELEASE_ASSERT(isSubclass(self->cls, str_cls), "");
RELEASE_ASSERT(sep->cls == str_cls, ""); RELEASE_ASSERT(isSubclass(sep->cls, str_cls), "");
size_t found_idx = self->s.find(sep->s); size_t found_idx = self->s.find(sep->s);
if (found_idx == std::string::npos) if (found_idx == std::string::npos)
...@@ -1606,11 +1612,11 @@ Box* strFormat(BoxedString* self, BoxedTuple* args, BoxedDict* kwargs) { ...@@ -1606,11 +1612,11 @@ Box* strFormat(BoxedString* self, BoxedTuple* args, BoxedDict* kwargs) {
} }
Box* strSplit(BoxedString* self, BoxedString* sep, BoxedInt* _max_split) { 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) if (_max_split->cls != int_cls)
raiseExcHelper(TypeError, "an integer is required"); raiseExcHelper(TypeError, "an integer is required");
if (sep->cls == str_cls) { if (isSubclass(sep->cls, str_cls)) {
if (!sep->s.empty()) { if (!sep->s.empty()) {
llvm::SmallVector<llvm::StringRef, 16> parts; llvm::SmallVector<llvm::StringRef, 16> parts;
llvm::StringRef(self->s).split(parts, sep->s, _max_split->n); llvm::StringRef(self->s).split(parts, sep->s, _max_split->n);
...@@ -1647,9 +1653,9 @@ Box* strSplit(BoxedString* self, BoxedString* sep, BoxedInt* _max_split) { ...@@ -1647,9 +1653,9 @@ Box* strSplit(BoxedString* self, BoxedString* sep, BoxedInt* _max_split) {
} }
Box* strStrip(BoxedString* self, Box* chars) { 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)); return new BoxedString(llvm::StringRef(self->s).trim(static_cast<BoxedString*>(chars)->s));
} else if (chars->cls == none_cls) { } else if (chars->cls == none_cls) {
return new BoxedString(llvm::StringRef(self->s).trim(" \t\n\r\f\v")); return new BoxedString(llvm::StringRef(self->s).trim(" \t\n\r\f\v"));
...@@ -1659,9 +1665,9 @@ Box* strStrip(BoxedString* self, Box* chars) { ...@@ -1659,9 +1665,9 @@ Box* strStrip(BoxedString* self, Box* chars) {
} }
Box* strLStrip(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)); return new BoxedString(llvm::StringRef(self->s).ltrim(static_cast<BoxedString*>(chars)->s));
} else if (chars->cls == none_cls) { } else if (chars->cls == none_cls) {
return new BoxedString(llvm::StringRef(self->s).ltrim(" \t\n\r\f\v")); return new BoxedString(llvm::StringRef(self->s).ltrim(" \t\n\r\f\v"));
...@@ -1671,9 +1677,9 @@ Box* strLStrip(BoxedString* self, Box* chars) { ...@@ -1671,9 +1677,9 @@ Box* strLStrip(BoxedString* self, Box* chars) {
} }
Box* strRStrip(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)); return new BoxedString(llvm::StringRef(self->s).rtrim(static_cast<BoxedString*>(chars)->s));
} else if (chars->cls == none_cls) { } else if (chars->cls == none_cls) {
return new BoxedString(llvm::StringRef(self->s).rtrim(" \t\n\r\f\v")); return new BoxedString(llvm::StringRef(self->s).rtrim(" \t\n\r\f\v"));
...@@ -1683,7 +1689,7 @@ Box* strRStrip(BoxedString* self, Box* chars) { ...@@ -1683,7 +1689,7 @@ Box* strRStrip(BoxedString* self, Box* chars) {
} }
Box* strCapitalize(BoxedString* self) { Box* strCapitalize(BoxedString* self) {
assert(self->cls == str_cls); assert(isSubclass(self->cls, str_cls));
std::string s(self->s); std::string s(self->s);
...@@ -1699,7 +1705,7 @@ Box* strCapitalize(BoxedString* self) { ...@@ -1699,7 +1705,7 @@ Box* strCapitalize(BoxedString* self) {
} }
Box* strTitle(BoxedString* self) { Box* strTitle(BoxedString* self) {
assert(self->cls == str_cls); assert(isSubclass(self->cls, str_cls));
std::string s(self->s); std::string s(self->s);
bool start_of_word = false; bool start_of_word = false;
...@@ -1751,12 +1757,12 @@ Box* strTranslate(BoxedString* self, BoxedString* table, BoxedString* delete_cha ...@@ -1751,12 +1757,12 @@ Box* strTranslate(BoxedString* self, BoxedString* table, BoxedString* delete_cha
} }
Box* strLower(BoxedString* self) { Box* strLower(BoxedString* self) {
assert(self->cls == str_cls); assert(isSubclass(self->cls, str_cls));
return boxString(llvm::StringRef(self->s).lower()); return boxString(llvm::StringRef(self->s).lower());
} }
Box* strUpper(BoxedString* self) { Box* strUpper(BoxedString* self) {
assert(self->cls == str_cls); assert(isSubclass(self->cls, str_cls));
return boxString(llvm::StringRef(self->s).upper()); return boxString(llvm::StringRef(self->s).upper());
} }
...@@ -1774,7 +1780,7 @@ Box* strSwapcase(BoxedString* self) { ...@@ -1774,7 +1780,7 @@ Box* strSwapcase(BoxedString* self) {
} }
Box* strContains(BoxedString* self, Box* elt) { Box* strContains(BoxedString* self, Box* elt) {
assert(self->cls == str_cls); assert(isSubclass(self->cls, str_cls));
if (PyUnicode_Check(elt)) { if (PyUnicode_Check(elt)) {
int r = PyUnicode_Contains(self, elt); int r = PyUnicode_Contains(self, elt);
...@@ -1961,7 +1967,7 @@ Box* strEncode(BoxedString* self, Box* encoding, Box* error) { ...@@ -1961,7 +1967,7 @@ Box* strEncode(BoxedString* self, Box* encoding, Box* error) {
} }
extern "C" Box* strGetitem(BoxedString* self, Box* slice) { 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)) { if (isSubclass(slice->cls, int_cls)) {
BoxedInt* islice = static_cast<BoxedInt*>(slice); BoxedInt* islice = static_cast<BoxedInt*>(slice);
...@@ -2030,12 +2036,12 @@ extern "C" void strIteratorGCHandler(GCVisitor* v, Box* b) { ...@@ -2030,12 +2036,12 @@ extern "C" void strIteratorGCHandler(GCVisitor* v, Box* b) {
} }
Box* strIter(BoxedString* self) { Box* strIter(BoxedString* self) {
assert(self->cls == str_cls); assert(isSubclass(self->cls, str_cls));
return new BoxedStringIterator(self); return new BoxedStringIterator(self);
} }
int64_t strCount2Unboxed(BoxedString* self, Box* elt) { int64_t strCount2Unboxed(BoxedString* self, Box* elt) {
assert(self->cls == str_cls); assert(isSubclass(self->cls, str_cls));
if (elt->cls != str_cls) if (elt->cls != str_cls)
raiseExcHelper(TypeError, "expected a character buffer object"); raiseExcHelper(TypeError, "expected a character buffer object");
...@@ -2061,7 +2067,7 @@ Box* strCount2(BoxedString* self, Box* elt) { ...@@ -2061,7 +2067,7 @@ Box* strCount2(BoxedString* self, Box* elt) {
} }
Box* strIndex(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) if (elt->cls != str_cls)
raiseExcHelper(TypeError, "expected a character buffer object"); raiseExcHelper(TypeError, "expected a character buffer object");
...@@ -2135,14 +2141,14 @@ extern "C" PyObject* PyString_FromStringAndSize(const char* s, ssize_t n) noexce ...@@ -2135,14 +2141,14 @@ extern "C" PyObject* PyString_FromStringAndSize(const char* s, ssize_t n) noexce
} }
extern "C" char* PyString_AsString(PyObject* o) noexcept { 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); BoxedString* s = static_cast<BoxedString*>(o);
return getWriteableStringContents(s); return getWriteableStringContents(s);
} }
extern "C" Py_ssize_t PyString_Size(PyObject* op) noexcept { 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(); return static_cast<BoxedString*>(op)->s.size();
char* _s; char* _s;
...@@ -2156,7 +2162,7 @@ extern "C" int _PyString_Resize(PyObject** pv, Py_ssize_t newsize) noexcept { ...@@ -2156,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) // 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);
assert((*pv)->cls == str_cls); assert(isSubclass((*pv)->cls, str_cls));
BoxedString* s = static_cast<BoxedString*>(*pv); BoxedString* s = static_cast<BoxedString*>(*pv);
s->s.resize(newsize, '\0'); s->s.resize(newsize, '\0');
return 0; return 0;
...@@ -2264,7 +2270,7 @@ static Py_ssize_t string_buffer_getreadbuf(PyObject* self, Py_ssize_t index, con ...@@ -2264,7 +2270,7 @@ static Py_ssize_t string_buffer_getreadbuf(PyObject* self, Py_ssize_t index, con
RELEASE_ASSERT(index == 0, ""); RELEASE_ASSERT(index == 0, "");
// I think maybe this can just be a non-release assert? shouldn't be able to call this with // I think maybe this can just be a non-release assert? shouldn't be able to call this with
// the wrong type // the wrong type
RELEASE_ASSERT(self->cls == str_cls, ""); RELEASE_ASSERT(isSubclass(self->cls, str_cls), "");
auto s = static_cast<BoxedString*>(self); auto s = static_cast<BoxedString*>(self);
*ptr = s->s.c_str(); *ptr = s->s.c_str();
...@@ -2273,7 +2279,7 @@ static Py_ssize_t string_buffer_getreadbuf(PyObject* self, Py_ssize_t index, con ...@@ -2273,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 { static Py_ssize_t string_buffer_getsegcount(PyObject* o, Py_ssize_t* lenp) noexcept {
RELEASE_ASSERT(lenp == NULL, ""); RELEASE_ASSERT(lenp == NULL, "");
RELEASE_ASSERT(o->cls == str_cls, ""); RELEASE_ASSERT(isSubclass(o->cls, str_cls), "");
return 1; return 1;
} }
...@@ -2287,7 +2293,7 @@ static Py_ssize_t string_buffer_getcharbuf(PyStringObject* self, Py_ssize_t inde ...@@ -2287,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 { 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); return PyBuffer_FillInfo(view, (PyObject*)self, &self->s[0], self->s.size(), 1, flags);
} }
......
...@@ -1320,6 +1320,8 @@ void setupRuntime() { ...@@ -1320,6 +1320,8 @@ void setupRuntime() {
tuple_cls->finishInitialization(); tuple_cls->finishInitialization();
list_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, module_cls = BoxedHeapClass::create(type_cls, object_cls, NULL, offsetof(BoxedModule, attrs), 0,
......
class MyStr(str):
pass
s = MyStr(1)
print repr(s)
import sys
sys.stdout.write(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