Commit 375d4fa3 authored by Travis Hance's avatar Travis Hance

add 1 to str_cls->tp_basicsize for the null byte

parent 2489e96f
...@@ -32,14 +32,14 @@ extern "C" Box* createList() { ...@@ -32,14 +32,14 @@ extern "C" Box* createList() {
BoxedString* _boxStrConstant(const char* chars) { BoxedString* _boxStrConstant(const char* chars) {
size_t len = strlen(chars); size_t len = strlen(chars);
return new (len + 1) BoxedString(chars, len); return new (len) BoxedString(chars, len);
} }
extern "C" BoxedString* boxStrConstant(const char* chars) { extern "C" BoxedString* boxStrConstant(const char* chars) {
return _boxStrConstant(chars); return _boxStrConstant(chars);
} }
BoxedString* _boxStrConstantSize(const char* chars, size_t n) { BoxedString* _boxStrConstantSize(const char* chars, size_t n) {
return new (n + 1) BoxedString(chars, n); return new (n) BoxedString(chars, n);
} }
extern "C" BoxedString* boxStrConstantSize(const char* chars, size_t n) { extern "C" BoxedString* boxStrConstantSize(const char* chars, size_t n) {
...@@ -47,18 +47,18 @@ extern "C" BoxedString* boxStrConstantSize(const char* chars, size_t n) { ...@@ -47,18 +47,18 @@ extern "C" BoxedString* boxStrConstantSize(const char* chars, size_t n) {
} }
extern "C" Box* boxStringPtr(const std::string* s) { extern "C" Box* boxStringPtr(const std::string* s) {
return new (s->size() + 1) BoxedString(s->c_str(), s->size()); return new (s->size()) BoxedString(s->c_str(), s->size());
} }
Box* boxStringRef(llvm::StringRef s) { Box* boxStringRef(llvm::StringRef s) {
return new (s.size() + 1) BoxedString(s); return new (s.size()) BoxedString(s);
} }
Box* boxString(const std::string& s) { Box* boxString(const std::string& s) {
return new (s.size() + 1) BoxedString(s.c_str(), s.size()); return new (s.size()) BoxedString(s.c_str(), s.size());
} }
Box* boxString(std::string&& s) { Box* boxString(std::string&& s) {
return new (s.size() + 1) BoxedString(s.c_str(), s.size()); return new (s.size()) BoxedString(s.c_str(), s.size());
} }
Box* boxStringTwine(const llvm::Twine& t) { Box* boxStringTwine(const llvm::Twine& t) {
......
...@@ -369,7 +369,6 @@ BoxedClass::BoxedClass(BoxedClass* base, gcvisit_func gc_visit, int attrs_offset ...@@ -369,7 +369,6 @@ BoxedClass::BoxedClass(BoxedClass* base, gcvisit_func gc_visit, int attrs_offset
if (base && cls && str_cls) if (base && cls && str_cls)
giveAttr("__base__", base); giveAttr("__base__", base);
assert(tp_basicsize % sizeof(void*) == 0); // Not critical I suppose, but probably signals a bug
if (attrs_offset) { if (attrs_offset) {
assert(tp_basicsize >= attrs_offset + sizeof(HCAttrs)); assert(tp_basicsize >= attrs_offset + sizeof(HCAttrs));
assert(attrs_offset % sizeof(void*) == 0); // Not critical I suppose, but probably signals a bug assert(attrs_offset % sizeof(void*) == 0); // Not critical I suppose, but probably signals a bug
......
...@@ -341,7 +341,7 @@ extern "C" Box* strAdd(BoxedString* lhs, Box* _rhs) { ...@@ -341,7 +341,7 @@ extern "C" Box* strAdd(BoxedString* lhs, Box* _rhs) {
} }
BoxedString* rhs = static_cast<BoxedString*>(_rhs); BoxedString* rhs = static_cast<BoxedString*>(_rhs);
return new (lhs->size() + rhs->size() + 1) BoxedString(lhs->s, rhs->s); return new (lhs->size() + rhs->size()) BoxedString(lhs->s, rhs->s);
} }
static llvm::StringMap<Box*> interned_strings; static llvm::StringMap<Box*> interned_strings;
...@@ -1547,7 +1547,7 @@ extern "C" Box* strNew(BoxedClass* cls, Box* obj) { ...@@ -1547,7 +1547,7 @@ extern "C" Box* strNew(BoxedClass* cls, Box* obj) {
BoxedString* _rtn = static_cast<BoxedString*>(rtn); BoxedString* _rtn = static_cast<BoxedString*>(rtn);
return new (cls, _rtn->size() + 1) BoxedString(_rtn->s); return new (cls, _rtn->size()) BoxedString(_rtn->s);
} }
extern "C" Box* basestringNew(BoxedClass* cls, Box* args, Box* kwargs) { extern "C" Box* basestringNew(BoxedClass* cls, Box* args, Box* kwargs) {
...@@ -1571,7 +1571,7 @@ Box* _strSlice(BoxedString* self, i64 start, i64 stop, i64 step, i64 length) { ...@@ -1571,7 +1571,7 @@ Box* _strSlice(BoxedString* self, i64 start, i64 stop, i64 step, i64 length) {
if (length == 0) if (length == 0)
return EmptyString; return EmptyString;
BoxedString* bs = new (length + 1) BoxedString(nullptr, length); BoxedString* bs = new (length) BoxedString(nullptr, length);
copySlice(bs->data(), s.data(), start, step, length); copySlice(bs->data(), s.data(), start, step, length);
return bs; return bs;
} }
...@@ -2289,7 +2289,7 @@ extern "C" int PyString_AsStringAndSize(register PyObject* obj, register char** ...@@ -2289,7 +2289,7 @@ extern "C" int PyString_AsStringAndSize(register PyObject* obj, register char**
BoxedString* createUninitializedString(ssize_t n) { BoxedString* createUninitializedString(ssize_t n) {
// I *think* this should avoid doing any copies, by using move constructors: // I *think* this should avoid doing any copies, by using move constructors:
return new (n + 1) BoxedString(n, 0); return new (n) BoxedString(n, 0);
} }
char* getWriteableStringContents(BoxedString* s) { char* getWriteableStringContents(BoxedString* s) {
...@@ -2340,7 +2340,7 @@ extern "C" int _PyString_Resize(PyObject** pv, Py_ssize_t newsize) noexcept { ...@@ -2340,7 +2340,7 @@ extern "C" int _PyString_Resize(PyObject** pv, Py_ssize_t newsize) noexcept {
BoxedString* resized; BoxedString* resized;
if (s->cls == str_cls) if (s->cls == str_cls)
resized = new (newsize + 1) BoxedString(newsize, 0); // we need an uninitialized string, but this will memset resized = new (newsize) BoxedString(newsize, 0); // we need an uninitialized string, but this will memset
else else
resized = new (s->cls, newsize) resized = new (s->cls, newsize)
BoxedString(newsize, 0); // we need an uninitialized string, but this will memset BoxedString(newsize, 0); // we need an uninitialized string, but this will memset
......
...@@ -2033,7 +2033,8 @@ void setupRuntime() { ...@@ -2033,7 +2033,8 @@ void setupRuntime() {
// You can't actually have an instance of basestring // You can't actually have an instance of basestring
basestring_cls = new (0) BoxedHeapClass(object_cls, NULL, 0, 0, sizeof(Box), false, NULL); basestring_cls = new (0) BoxedHeapClass(object_cls, NULL, 0, 0, sizeof(Box), false, NULL);
str_cls = new (0) BoxedHeapClass(basestring_cls, NULL, 0, 0, sizeof(BoxedString), false, NULL); // We add 1 to the tp_basicsize of the BoxedString in order to hold the null byte at the end.
str_cls = new (0) BoxedHeapClass(basestring_cls, NULL, 0, 0, sizeof(BoxedString) + 1, false, NULL);
str_cls->tp_flags |= Py_TPFLAGS_STRING_SUBCLASS; str_cls->tp_flags |= Py_TPFLAGS_STRING_SUBCLASS;
str_cls->tp_itemsize = sizeof(char); str_cls->tp_itemsize = sizeof(char);
......
...@@ -416,7 +416,26 @@ public: ...@@ -416,7 +416,26 @@ public:
char* data() { return const_cast<char*>(s.data()); } char* data() { return const_cast<char*>(s.data()); }
size_t size() { return s.size(); } size_t size() { return s.size(); }
DEFAULT_CLASS_VAR_SIMPLE(str_cls, sizeof(char)); // DEFAULT_CLASS_VAR_SIMPLE doesn't work because of the +1 for the null byte
void* operator new(size_t size, BoxedClass* cls, size_t nitems) __attribute__((visibility("default"))) {
assert(cls->tp_itemsize == sizeof(char));
return BoxVar::operator new(size, cls, nitems);
}
void* operator new(size_t size, size_t nitems) __attribute__((visibility("default"))) {
assert(str_cls->tp_alloc == PystonType_GenericAlloc);
assert(str_cls->tp_itemsize == 1);
assert(str_cls->tp_basicsize == sizeof(BoxedString) + 1);
assert(str_cls->is_pyston_class);
assert(str_cls->attrs_offset == 0);
void* mem = gc_alloc(sizeof(BoxedString) + 1 + nitems, gc::GCKind::PYTHON);
assert(mem);
BoxVar* rtn = static_cast<BoxVar*>(mem);
rtn->cls = str_cls;
rtn->ob_size = nitems;
return rtn;
}
// these should be private, but strNew needs them // these should be private, but strNew needs them
BoxedString(const char* s, size_t n) __attribute__((visibility("default"))); BoxedString(const char* s, size_t n) __attribute__((visibility("default")));
...@@ -426,6 +445,7 @@ public: ...@@ -426,6 +445,7 @@ public:
private: private:
// used only in ctors to give our llvm::StringRef the proper pointer // used only in ctors to give our llvm::StringRef the proper pointer
// Note: sizeof(BoxedString) = str_cls->tp_basicsize - 1
char* storage() { return (char*)this + sizeof(BoxedString); } char* storage() { return (char*)this + sizeof(BoxedString); }
void* operator new(size_t size) = delete; void* operator new(size_t size) = delete;
......
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