Commit b44b06f9 authored by Chris Toshok's avatar Chris Toshok

colocate string and tuple contents with the object, and share a single allocation.

Tuples now contain a pointer to their storage (Box**) + size, and strings contain
an llvm::StringRef which contains the pointer+size.
parent 3486e84c
...@@ -43,7 +43,7 @@ Box* BoxedMethodDescriptor::__call__(BoxedMethodDescriptor* self, Box* obj, Boxe ...@@ -43,7 +43,7 @@ Box* BoxedMethodDescriptor::__call__(BoxedMethodDescriptor* self, Box* obj, Boxe
Box* rtn; Box* rtn;
if (call_flags == METH_NOARGS) { if (call_flags == METH_NOARGS) {
assert(varargs->elts.size() == 0); assert(varargs->size() == 0);
assert(kwargs->d.size() == 0); assert(kwargs->d.size() == 0);
rtn = (Box*)self->method->ml_meth(obj, NULL); rtn = (Box*)self->method->ml_meth(obj, NULL);
} else if (call_flags == METH_VARARGS) { } else if (call_flags == METH_VARARGS) {
...@@ -53,7 +53,7 @@ Box* BoxedMethodDescriptor::__call__(BoxedMethodDescriptor* self, Box* obj, Boxe ...@@ -53,7 +53,7 @@ Box* BoxedMethodDescriptor::__call__(BoxedMethodDescriptor* self, Box* obj, Boxe
rtn = (Box*)((PyCFunctionWithKeywords)self->method->ml_meth)(obj, varargs, kwargs); rtn = (Box*)((PyCFunctionWithKeywords)self->method->ml_meth)(obj, varargs, kwargs);
} else if (call_flags == METH_O) { } else if (call_flags == METH_O) {
assert(kwargs->d.size() == 0); assert(kwargs->d.size() == 0);
assert(varargs->elts.size() == 1); assert(varargs->size() == 1);
rtn = (Box*)self->method->ml_meth(obj, varargs->elts[0]); rtn = (Box*)self->method->ml_meth(obj, varargs->elts[0]);
} else { } else {
RELEASE_ASSERT(0, "0x%x", call_flags); RELEASE_ASSERT(0, "0x%x", call_flags);
......
...@@ -29,17 +29,17 @@ static float_format_type double_format, float_format; ...@@ -29,17 +29,17 @@ static float_format_type double_format, float_format;
static float_format_type detected_double_format, detected_float_format; static float_format_type detected_double_format, detected_float_format;
static PyObject* float_getformat(PyTypeObject* v, PyObject* arg) noexcept { static PyObject* float_getformat(PyTypeObject* v, PyObject* arg) noexcept {
char* s;
float_format_type r; float_format_type r;
BoxedString* str = static_cast<BoxedString*>(arg);
if (!PyString_Check(arg)) { if (!PyString_Check(arg)) {
PyErr_Format(PyExc_TypeError, "__getformat__() argument must be string, not %.500s", Py_TYPE(arg)->tp_name); PyErr_Format(PyExc_TypeError, "__getformat__() argument must be string, not %.500s", Py_TYPE(arg)->tp_name);
return NULL; return NULL;
} }
s = PyString_AS_STRING(arg); if (str->s == "double") {
if (strcmp(s, "double") == 0) {
r = double_format; r = double_format;
} else if (strcmp(s, "float") == 0) { } else if (str->s == "float") {
r = float_format; r = float_format;
} else { } else {
PyErr_SetString(PyExc_ValueError, "__getformat__() argument 1 must be " PyErr_SetString(PyExc_ValueError, "__getformat__() argument 1 must be "
...@@ -49,11 +49,11 @@ static PyObject* float_getformat(PyTypeObject* v, PyObject* arg) noexcept { ...@@ -49,11 +49,11 @@ static PyObject* float_getformat(PyTypeObject* v, PyObject* arg) noexcept {
switch (r) { switch (r) {
case unknown_format: case unknown_format:
return PyString_FromString("unknown"); return static_cast<PyObject*>(boxStrConstant("unknown"));
case ieee_little_endian_format: case ieee_little_endian_format:
return PyString_FromString("IEEE, little-endian"); return static_cast<PyObject*>(boxStrConstant("IEEE, little-endian"));
case ieee_big_endian_format: case ieee_big_endian_format:
return PyString_FromString("IEEE, big-endian"); return static_cast<PyObject*>(boxStrConstant("IEEE, big-endian"));
default: default:
Py_FatalError("insane float_format or double_format"); Py_FatalError("insane float_format or double_format");
return NULL; return NULL;
......
...@@ -421,9 +421,9 @@ extern "C" PyObject* PyObject_SelfIter(PyObject* obj) noexcept { ...@@ -421,9 +421,9 @@ extern "C" PyObject* PyObject_SelfIter(PyObject* obj) noexcept {
extern "C" int PyObject_GenericSetAttr(PyObject* obj, PyObject* name, PyObject* value) noexcept { extern "C" int PyObject_GenericSetAttr(PyObject* obj, PyObject* name, PyObject* value) noexcept {
try { try {
if (value == NULL) if (value == NULL)
delattrGeneric(obj, static_cast<BoxedString*>(name)->s, NULL); delattrGeneric(obj, std::string(static_cast<BoxedString*>(name)->s), NULL);
else else
setattrGeneric(obj, static_cast<BoxedString*>(name)->s.c_str(), value, NULL); setattrGeneric(obj, std::string(static_cast<BoxedString*>(name)->s), value, NULL);
} catch (ExcInfo e) { } catch (ExcInfo e) {
setCAPIException(e); setCAPIException(e);
return -1; return -1;
......
...@@ -1577,7 +1577,7 @@ bool update_slot(BoxedClass* type, const std::string& attr) noexcept { ...@@ -1577,7 +1577,7 @@ bool update_slot(BoxedClass* type, const std::string& attr) noexcept {
} }
if (ptrs[0] == NULL) if (ptrs[0] == NULL)
return false; /* Not an attribute that affects any slots */ return false; /* Not an attribute that affects any slots */
int r = update_subclasses(type, new BoxedString(attr), update_slots_callback, (void*)ptrs); int r = update_subclasses(type, boxString(attr), update_slots_callback, (void*)ptrs);
// TODO this is supposed to be a CAPI function! // TODO this is supposed to be a CAPI function!
if (r) if (r)
...@@ -1634,13 +1634,13 @@ static PyObject* tp_new_wrapper(PyTypeObject* self, BoxedTuple* args, Box* kwds) ...@@ -1634,13 +1634,13 @@ static PyObject* tp_new_wrapper(PyTypeObject* self, BoxedTuple* args, Box* kwds)
RELEASE_ASSERT(args->cls == tuple_cls, ""); RELEASE_ASSERT(args->cls == tuple_cls, "");
RELEASE_ASSERT(kwds->cls == dict_cls, ""); RELEASE_ASSERT(kwds->cls == dict_cls, "");
RELEASE_ASSERT(args->elts.size() >= 1, ""); RELEASE_ASSERT(args->size() >= 1, "");
BoxedClass* subtype = static_cast<BoxedClass*>(args->elts[0]); BoxedClass* subtype = static_cast<BoxedClass*>(args->elts[0]);
RELEASE_ASSERT(isSubclass(subtype->cls, type_cls), ""); RELEASE_ASSERT(isSubclass(subtype->cls, type_cls), "");
RELEASE_ASSERT(isSubclass(subtype, self), ""); RELEASE_ASSERT(isSubclass(subtype, self), "");
BoxedTuple* new_args = new BoxedTuple(BoxedTuple::GCVector(args->elts.begin() + 1, args->elts.end())); BoxedTuple* new_args = BoxedTuple::create(args->size() - 1, &args->elts[1]);
return self->tp_new(subtype, new_args, kwds); return self->tp_new(subtype, new_args, kwds);
} }
...@@ -2553,13 +2553,13 @@ static void remove_subclass(PyTypeObject* base, PyTypeObject* type) noexcept { ...@@ -2553,13 +2553,13 @@ static void remove_subclass(PyTypeObject* base, PyTypeObject* type) noexcept {
void commonClassSetup(BoxedClass* cls) { void commonClassSetup(BoxedClass* cls) {
if (cls->tp_bases == NULL) { if (cls->tp_bases == NULL) {
if (cls->tp_base) if (cls->tp_base)
cls->tp_bases = new BoxedTuple({ cls->tp_base }); cls->tp_bases = BoxedTuple::create({ cls->tp_base });
else else
cls->tp_bases = new BoxedTuple({}); cls->tp_bases = BoxedTuple::create({});
} }
/* Link into each base class's list of subclasses */ /* Link into each base class's list of subclasses */
for (PyObject* b : static_cast<BoxedTuple*>(cls->tp_bases)->elts) { for (PyObject* b : *static_cast<BoxedTuple*>(cls->tp_bases)) {
if (PyType_Check(b) && add_subclass((PyTypeObject*)b, cls) < 0) if (PyType_Check(b) && add_subclass((PyTypeObject*)b, cls) < 0)
throwCAPIException(); throwCAPIException();
} }
...@@ -2573,7 +2573,8 @@ void commonClassSetup(BoxedClass* cls) { ...@@ -2573,7 +2573,8 @@ void commonClassSetup(BoxedClass* cls) {
assert(cls->tp_mro); assert(cls->tp_mro);
assert(cls->tp_mro->cls == tuple_cls); assert(cls->tp_mro->cls == tuple_cls);
for (auto b : static_cast<BoxedTuple*>(cls->tp_mro)->elts) {
for (auto b : *static_cast<BoxedTuple*>(cls->tp_mro)) {
if (b == cls) if (b == cls)
continue; continue;
if (PyType_Check(b)) if (PyType_Check(b))
......
...@@ -68,11 +68,11 @@ public: ...@@ -68,11 +68,11 @@ public:
rtn = (Box*)((PyCFunctionWithKeywords)self->func)(self->passthrough, varargs, kwargs); rtn = (Box*)((PyCFunctionWithKeywords)self->func)(self->passthrough, varargs, kwargs);
} else if (self->ml_flags == METH_NOARGS) { } else if (self->ml_flags == METH_NOARGS) {
assert(kwargs->d.size() == 0); assert(kwargs->d.size() == 0);
assert(varargs->elts.size() == 0); assert(varargs->size() == 0);
rtn = (Box*)self->func(self->passthrough, NULL); rtn = (Box*)self->func(self->passthrough, NULL);
} else if (self->ml_flags == METH_O) { } else if (self->ml_flags == METH_O) {
assert(kwargs->d.size() == 0); assert(kwargs->d.size() == 0);
assert(varargs->elts.size() == 1); assert(varargs->size() == 1);
rtn = (Box*)self->func(self->passthrough, varargs->elts[0]); rtn = (Box*)self->func(self->passthrough, varargs->elts[0]);
} else { } else {
RELEASE_ASSERT(0, "0x%x", self->ml_flags); RELEASE_ASSERT(0, "0x%x", self->ml_flags);
......
...@@ -580,7 +580,7 @@ Value ASTInterpreter::visit_langPrimitive(AST_LangPrimitive* node) { ...@@ -580,7 +580,7 @@ Value ASTInterpreter::visit_langPrimitive(AST_LangPrimitive* node) {
Box* type = last_exception.type; Box* type = last_exception.type;
Box* value = last_exception.value ? last_exception.value : None; Box* value = last_exception.value ? last_exception.value : None;
Box* traceback = last_exception.traceback ? last_exception.traceback : None; Box* traceback = last_exception.traceback ? last_exception.traceback : None;
v = new BoxedTuple({ type, value, traceback }); v = BoxedTuple::create({ type, value, traceback });
last_exception = ExcInfo(NULL, NULL, NULL); last_exception = ExcInfo(NULL, NULL, NULL);
} else if (node->opcode == AST_LangPrimitive::CHECK_EXC_MATCH) { } else if (node->opcode == AST_LangPrimitive::CHECK_EXC_MATCH) {
assert(node->args.size() == 2); assert(node->args.size() == 2);
...@@ -747,11 +747,11 @@ Value ASTInterpreter::visit_makeClass(AST_MakeClass* mkclass) { ...@@ -747,11 +747,11 @@ Value ASTInterpreter::visit_makeClass(AST_MakeClass* mkclass) {
ScopeInfo* scope_info = source_info->scoping->getScopeInfoForNode(node); ScopeInfo* scope_info = source_info->scoping->getScopeInfoForNode(node);
assert(scope_info); assert(scope_info);
BoxedTuple::GCVector bases; BoxedTuple* basesTuple = BoxedTuple::create(node->bases.size());
for (AST_expr* b : node->bases) int base_idx = 0;
bases.push_back(visit_expr(b).o); for (AST_expr* b : node->bases) {
basesTuple->elts[base_idx++] = visit_expr(b).o;
BoxedTuple* basesTuple = new BoxedTuple(std::move(bases)); }
std::vector<Box*, StlCompatAllocator<Box*>> decorators; std::vector<Box*, StlCompatAllocator<Box*>> decorators;
for (AST_expr* d : node->decorator_list) for (AST_expr* d : node->decorator_list)
...@@ -1132,10 +1132,11 @@ Value ASTInterpreter::visit_list(AST_List* node) { ...@@ -1132,10 +1132,11 @@ Value ASTInterpreter::visit_list(AST_List* node) {
} }
Value ASTInterpreter::visit_tuple(AST_Tuple* node) { Value ASTInterpreter::visit_tuple(AST_Tuple* node) {
BoxedTuple::GCVector elts; BoxedTuple* rtn = BoxedTuple::create(node->elts.size());
int rtn_idx = 0;
for (AST_expr* e : node->elts) for (AST_expr* e : node->elts)
elts.push_back(visit_expr(e).o); rtn->elts[rtn_idx++] = visit_expr(e).o;
return new BoxedTuple(std::move(elts)); return rtn;
} }
Value ASTInterpreter::visit_attribute(AST_Attribute* node) { Value ASTInterpreter::visit_attribute(AST_Attribute* node) {
...@@ -1194,7 +1195,7 @@ Box* astInterpretFrom(CompiledFunction* cf, AST_expr* after_expr, AST_stmt* encl ...@@ -1194,7 +1195,7 @@ Box* astInterpretFrom(CompiledFunction* cf, AST_expr* after_expr, AST_stmt* encl
for (const auto& p : frame_state.locals->d) { for (const auto& p : frame_state.locals->d) {
assert(p.first->cls == str_cls); assert(p.first->cls == str_cls);
std::string name = static_cast<BoxedString*>(p.first)->s; auto& name = static_cast<BoxedString*>(p.first)->s;
if (name == PASSED_GENERATOR_NAME) { if (name == PASSED_GENERATOR_NAME) {
interpreter.setGenerator(p.second); interpreter.setGenerator(p.second);
} else if (name == PASSED_CLOSURE_NAME) { } else if (name == PASSED_CLOSURE_NAME) {
......
...@@ -2203,20 +2203,20 @@ public: ...@@ -2203,20 +2203,20 @@ public:
Box* deserializeFromFrame(const FrameVals& vals) override { Box* deserializeFromFrame(const FrameVals& vals) override {
assert(vals.size() == numFrameArgs()); assert(vals.size() == numFrameArgs());
BoxedTuple::GCVector elts; BoxedTuple* rtn = BoxedTuple::create(elt_types.size());
int rtn_idx = 0;
int cur_idx = 0; int cur_idx = 0;
for (auto e : elt_types) { for (auto e : elt_types) {
int num_args = e->numFrameArgs(); int num_args = e->numFrameArgs();
// TODO: inefficient to make these copies // TODO: inefficient to make these copies
FrameVals sub_vals(vals.begin() + cur_idx, vals.begin() + cur_idx + num_args); FrameVals sub_vals(vals.begin() + cur_idx, vals.begin() + cur_idx + num_args);
elts.push_back(e->deserializeFromFrame(sub_vals)); rtn->elts[rtn_idx++] = e->deserializeFromFrame(sub_vals);
cur_idx += num_args; cur_idx += num_args;
} }
assert(cur_idx == vals.size()); assert(cur_idx == vals.size());
return rtn;
return new BoxedTuple(std::move(elts));
} }
int numFrameArgs() override { int numFrameArgs() override {
......
...@@ -364,7 +364,7 @@ Box* eval(Box* boxedCode) { ...@@ -364,7 +364,7 @@ Box* eval(Box* boxedCode) {
// TODO should have a cleaner interface that can parse the Expression directly // TODO should have a cleaner interface that can parse the Expression directly
// TODO this memory leaks // TODO this memory leaks
RELEASE_ASSERT(boxedCode->cls == str_cls, ""); RELEASE_ASSERT(boxedCode->cls == str_cls, "");
const char* code = static_cast<BoxedString*>(boxedCode)->s.c_str(); const char* code = static_cast<BoxedString*>(boxedCode)->s.data();
AST_Module* parsedModule = parse_string(code); AST_Module* parsedModule = parse_string(code);
RELEASE_ASSERT(parsedModule->body[0]->type == AST_TYPE::Expr, ""); RELEASE_ASSERT(parsedModule->body[0]->type == AST_TYPE::Expr, "");
AST_Expression* parsedExpr = new AST_Expression(std::move(parsedModule->interned_strings)); AST_Expression* parsedExpr = new AST_Expression(std::move(parsedModule->interned_strings));
...@@ -385,7 +385,7 @@ Box* exec(Box* boxedCode) { ...@@ -385,7 +385,7 @@ Box* exec(Box* boxedCode) {
// TODO same issues as in `eval` // TODO same issues as in `eval`
RELEASE_ASSERT(boxedCode->cls == str_cls, ""); RELEASE_ASSERT(boxedCode->cls == str_cls, "");
const char* code = static_cast<BoxedString*>(boxedCode)->s.c_str(); const char* code = static_cast<BoxedString*>(boxedCode)->s.data();
AST_Module* parsedModule = parse_string(code); AST_Module* parsedModule = parse_string(code);
AST_Suite* parsedSuite = new AST_Suite(std::move(parsedModule->interned_strings)); AST_Suite* parsedSuite = new AST_Suite(std::move(parsedModule->interned_strings));
parsedSuite->body = parsedModule->body; parsedSuite->body = parsedModule->body;
......
...@@ -850,12 +850,12 @@ pypa::String pypaUnicodeEscapeDecoder(pypa::String s, bool raw_prefix, bool& err ...@@ -850,12 +850,12 @@ pypa::String pypaUnicodeEscapeDecoder(pypa::String s, bool raw_prefix, bool& err
checkAndThrowCAPIException(); checkAndThrowCAPIException();
BoxedString* str_utf8 = (BoxedString*)PyUnicode_AsUTF8String(unicode); BoxedString* str_utf8 = (BoxedString*)PyUnicode_AsUTF8String(unicode);
checkAndThrowCAPIException(); checkAndThrowCAPIException();
return str_utf8->s; return std::string(str_utf8->s);
} catch (ExcInfo e) { } catch (ExcInfo e) {
error = true; error = true;
BoxedString* error_message = str(e.value); BoxedString* error_message = str(e.value);
if (error_message && error_message->cls == str_cls) if (error_message && error_message->cls == str_cls)
return error_message->s; return std::string(error_message->s);
return "Encountered an unknown error inside pypaUnicodeEscapeDecoder"; return "Encountered an unknown error inside pypaUnicodeEscapeDecoder";
} }
} }
......
...@@ -166,7 +166,7 @@ static int main(int argc, char** argv) { ...@@ -166,7 +166,7 @@ static int main(int argc, char** argv) {
if (!Py_NoSiteFlag) { if (!Py_NoSiteFlag) {
try { try {
std::string module_name = "site"; std::string module_name = "site";
importModuleLevel(&module_name, None, None, 0); importModuleLevel(module_name, None, None, 0);
} catch (ExcInfo e) { } catch (ExcInfo e) {
e.printExcAndTraceback(); e.printExcAndTraceback();
return 1; return 1;
......
...@@ -148,7 +148,7 @@ extern "C" Box* min(Box* arg0, BoxedTuple* args) { ...@@ -148,7 +148,7 @@ extern "C" Box* min(Box* arg0, BoxedTuple* args) {
Box* minElement; Box* minElement;
Box* container; Box* container;
if (args->elts.size() == 0) { if (args->size() == 0) {
minElement = nullptr; minElement = nullptr;
container = arg0; container = arg0;
} else { } else {
...@@ -178,7 +178,7 @@ extern "C" Box* max(Box* arg0, BoxedTuple* args) { ...@@ -178,7 +178,7 @@ extern "C" Box* max(Box* arg0, BoxedTuple* args) {
Box* maxElement; Box* maxElement;
Box* container; Box* container;
if (args->elts.size() == 0) { if (args->size() == 0) {
maxElement = nullptr; maxElement = nullptr;
container = arg0; container = arg0;
} else { } else {
...@@ -250,7 +250,8 @@ extern "C" Box* chr(Box* arg) { ...@@ -250,7 +250,8 @@ extern "C" Box* chr(Box* arg) {
raiseExcHelper(ValueError, "chr() arg not in range(256)"); raiseExcHelper(ValueError, "chr() arg not in range(256)");
} }
return boxString(std::string(1, (char)n)); char c = (char)n;
return boxStringRef(llvm::StringRef(&c, 1));
} }
extern "C" Box* unichr(Box* arg) { extern "C" Box* unichr(Box* arg) {
...@@ -382,7 +383,8 @@ Box* bltinImport(Box* name, Box* globals, Box* locals, Box** args) { ...@@ -382,7 +383,8 @@ Box* bltinImport(Box* name, Box* globals, Box* locals, Box** args) {
raiseExcHelper(TypeError, "an integer is required"); raiseExcHelper(TypeError, "an integer is required");
} }
return importModuleLevel(&static_cast<BoxedString*>(name)->s, globals, fromlist, ((BoxedInt*)level)->n); std::string _name = static_cast<BoxedString*>(name)->s;
return importModuleLevel(_name, globals, fromlist, ((BoxedInt*)level)->n);
} }
Box* delattrFunc(Box* obj, Box* _str) { Box* delattrFunc(Box* obj, Box* _str) {
...@@ -391,7 +393,7 @@ Box* delattrFunc(Box* obj, Box* _str) { ...@@ -391,7 +393,7 @@ Box* delattrFunc(Box* obj, Box* _str) {
if (_str->cls != str_cls) if (_str->cls != str_cls)
raiseExcHelper(TypeError, "attribute name must be string, not '%s'", getTypeName(_str)); raiseExcHelper(TypeError, "attribute name must be string, not '%s'", getTypeName(_str));
BoxedString* str = static_cast<BoxedString*>(_str); BoxedString* str = static_cast<BoxedString*>(_str);
delattr(obj, str->s.c_str()); delattr(obj, str->s.data());
return None; return None;
} }
...@@ -406,7 +408,7 @@ Box* getattrFunc(Box* obj, Box* _str, Box* default_value) { ...@@ -406,7 +408,7 @@ Box* getattrFunc(Box* obj, Box* _str, Box* default_value) {
Box* rtn = NULL; Box* rtn = NULL;
try { try {
rtn = getattr(obj, str->s.c_str()); rtn = getattr(obj, str->s.data());
} catch (ExcInfo e) { } catch (ExcInfo e) {
if (!e.matches(AttributeError)) if (!e.matches(AttributeError))
throw e; throw e;
...@@ -416,7 +418,7 @@ Box* getattrFunc(Box* obj, Box* _str, Box* default_value) { ...@@ -416,7 +418,7 @@ Box* getattrFunc(Box* obj, Box* _str, Box* default_value) {
if (default_value) if (default_value)
return default_value; return default_value;
else else
raiseExcHelper(AttributeError, "'%s' object has no attribute '%s'", getTypeName(obj), str->s.c_str()); raiseExcHelper(AttributeError, "'%s' object has no attribute '%s'", getTypeName(obj), str->s.data());
} }
return rtn; return rtn;
...@@ -430,7 +432,7 @@ Box* setattrFunc(Box* obj, Box* _str, Box* value) { ...@@ -430,7 +432,7 @@ Box* setattrFunc(Box* obj, Box* _str, Box* value) {
} }
BoxedString* str = static_cast<BoxedString*>(_str); BoxedString* str = static_cast<BoxedString*>(_str);
setattr(obj, str->s.c_str(), value); setattr(obj, str->s.data(), value);
return None; return None;
} }
...@@ -465,7 +467,7 @@ Box* map2(Box* f, Box* container) { ...@@ -465,7 +467,7 @@ Box* map2(Box* f, Box* container) {
Box* map(Box* f, BoxedTuple* args) { Box* map(Box* f, BoxedTuple* args) {
assert(args->cls == tuple_cls); assert(args->cls == tuple_cls);
auto num_iterable = args->elts.size(); auto num_iterable = args->size();
if (num_iterable < 1) if (num_iterable < 1)
raiseExcHelper(TypeError, "map() requires at least two args"); raiseExcHelper(TypeError, "map() requires at least two args");
...@@ -475,7 +477,8 @@ Box* map(Box* f, BoxedTuple* args) { ...@@ -475,7 +477,8 @@ Box* map(Box* f, BoxedTuple* args) {
std::vector<BoxIterator> args_it; std::vector<BoxIterator> args_it;
std::vector<BoxIterator> args_end; std::vector<BoxIterator> args_end;
for (auto& e : args->elts) {
for (auto e : *args) {
auto range = e->pyElements(); auto range = e->pyElements();
args_it.emplace_back(range.begin()); args_it.emplace_back(range.begin());
args_end.emplace_back(range.end()); args_end.emplace_back(range.end());
...@@ -559,8 +562,7 @@ Box* zip2(Box* container1, Box* container2) { ...@@ -559,8 +562,7 @@ Box* zip2(Box* container1, Box* container2) {
BoxIterator it2 = range2.begin(); BoxIterator it2 = range2.begin();
for (; it1 != range1.end() && it2 != range2.end(); ++it1, ++it2) { for (; it1 != range1.end() && it2 != range2.end(); ++it1, ++it2) {
BoxedTuple::GCVector elts{ *it1, *it2 }; listAppendInternal(rtn, BoxedTuple::create({ *it1, *it2 }));
listAppendInternal(rtn, new BoxedTuple(std::move(elts)));
} }
return rtn; return rtn;
} }
...@@ -583,7 +585,7 @@ public: ...@@ -583,7 +585,7 @@ public:
RELEASE_ASSERT(isSubclass(self->cls, BaseException), ""); RELEASE_ASSERT(isSubclass(self->cls, BaseException), "");
BoxedException* exc = static_cast<BoxedException*>(self); BoxedException* exc = static_cast<BoxedException*>(self);
return new BoxedTuple({ self->cls, EmptyTuple, makeAttrWrapper(self) }); return BoxedTuple::create({ self->cls, EmptyTuple, makeAttrWrapper(self) });
} }
}; };
...@@ -598,7 +600,7 @@ Box* exceptionNew(BoxedClass* cls, BoxedTuple* args) { ...@@ -598,7 +600,7 @@ Box* exceptionNew(BoxedClass* cls, BoxedTuple* args) {
BoxedException* rtn = new (cls) BoxedException(); BoxedException* rtn = new (cls) BoxedException();
// TODO: this should be a MemberDescriptor and set during init // TODO: this should be a MemberDescriptor and set during init
if (args->elts.size() == 1) if (args->size() == 1)
rtn->giveAttr("message", args->elts[0]); rtn->giveAttr("message", args->elts[0]);
else else
rtn->giveAttr("message", boxStrConstant("")); rtn->giveAttr("message", boxStrConstant(""));
...@@ -623,7 +625,7 @@ Box* exceptionRepr(Box* b) { ...@@ -623,7 +625,7 @@ Box* exceptionRepr(Box* b) {
assert(message->cls == str_cls); assert(message->cls == str_cls);
BoxedString* message_s = static_cast<BoxedString*>(message); BoxedString* message_s = static_cast<BoxedString*>(message);
return boxString(std::string(getTypeName(b)) + "(" + message_s->s + ",)"); return boxStringTwine(llvm::Twine(getTypeName(b)) + "(" + message_s->s + ",)");
} }
static BoxedClass* makeBuiltinException(BoxedClass* base, const char* name, int size = 0) { static BoxedClass* makeBuiltinException(BoxedClass* base, const char* name, int size = 0) {
...@@ -667,7 +669,7 @@ extern "C" PyObject* PyErr_NewException(char* name, PyObject* _base, PyObject* d ...@@ -667,7 +669,7 @@ extern "C" PyObject* PyErr_NewException(char* name, PyObject* _base, PyObject* d
} }
checkAndThrowCAPIException(); checkAndThrowCAPIException();
Box* cls = runtimeCall(type_cls, ArgPassSpec(3), boxedName, new BoxedTuple({ base }), dict, NULL, NULL); Box* cls = runtimeCall(type_cls, ArgPassSpec(3), boxedName, BoxedTuple::create({ base }), dict, NULL, NULL);
return cls; return cls;
} catch (ExcInfo e) { } catch (ExcInfo e) {
abort(); abort();
...@@ -706,7 +708,7 @@ public: ...@@ -706,7 +708,7 @@ public:
BoxedEnumerate* self = static_cast<BoxedEnumerate*>(_self); BoxedEnumerate* self = static_cast<BoxedEnumerate*>(_self);
Box* val = *self->iterator; Box* val = *self->iterator;
++self->iterator; ++self->iterator;
return new BoxedTuple({ boxInt(self->idx++), val }); return BoxedTuple::create({ boxInt(self->idx++), val });
} }
static Box* hasnext(Box* _self) { static Box* hasnext(Box* _self) {
...@@ -766,14 +768,14 @@ Box* execfile(Box* _fn) { ...@@ -766,14 +768,14 @@ Box* execfile(Box* _fn) {
#endif #endif
#else #else
bool exists = llvm::sys::fs::exists(fn->s); bool exists = llvm::sys::fs::exists(std::string(fn->s));
#endif #endif
if (!exists) if (!exists)
raiseExcHelper(IOError, "No such file or directory: '%s'", fn->s.c_str()); raiseExcHelper(IOError, "No such file or directory: '%s'", fn->s.data());
// Run directly inside the current module: // Run directly inside the current module:
AST_Module* ast = caching_parse_file(fn->s.c_str()); AST_Module* ast = caching_parse_file(fn->s.data());
compileAndRunModule(ast, getCurrentModule()); compileAndRunModule(ast, getCurrentModule());
return None; return None;
...@@ -785,7 +787,7 @@ Box* print(BoxedTuple* args, BoxedDict* kwargs) { ...@@ -785,7 +787,7 @@ Box* print(BoxedTuple* args, BoxedDict* kwargs) {
Box* dest, *end; Box* dest, *end;
auto it = kwargs->d.find(new BoxedString("file")); auto it = kwargs->d.find(boxStrConstant("file"));
if (it != kwargs->d.end()) { if (it != kwargs->d.end()) {
dest = it->second; dest = it->second;
kwargs->d.erase(it); kwargs->d.erase(it);
...@@ -793,23 +795,23 @@ Box* print(BoxedTuple* args, BoxedDict* kwargs) { ...@@ -793,23 +795,23 @@ Box* print(BoxedTuple* args, BoxedDict* kwargs) {
dest = getSysStdout(); dest = getSysStdout();
} }
it = kwargs->d.find(new BoxedString("end")); it = kwargs->d.find(boxStrConstant("end"));
if (it != kwargs->d.end()) { if (it != kwargs->d.end()) {
end = it->second; end = it->second;
kwargs->d.erase(it); kwargs->d.erase(it);
} else { } else {
end = new BoxedString("\n"); end = boxStrConstant("\n");
} }
RELEASE_ASSERT(kwargs->d.size() == 0, "print() got unexpected keyword arguments"); RELEASE_ASSERT(kwargs->d.size() == 0, "print() got unexpected keyword arguments");
static const std::string write_str("write"); static const std::string write_str("write");
Box* space_box = new BoxedString(" "); Box* space_box = boxStrConstant(" ");
// TODO softspace handling? // TODO softspace handling?
bool first = true; bool first = true;
for (auto e : args->elts) { for (auto e : *args) {
BoxedString* s = str(e); BoxedString* s = str(e);
if (!first) { if (!first) {
......
...@@ -43,7 +43,7 @@ static Box* setOption(Box* option, Box* value) { ...@@ -43,7 +43,7 @@ static Box* setOption(Box* option, Box* value) {
else CHECK(REOPT_THRESHOLD_BASELINE); else CHECK(REOPT_THRESHOLD_BASELINE);
else CHECK(OSR_THRESHOLD_BASELINE); else CHECK(OSR_THRESHOLD_BASELINE);
else CHECK(SPECULATION_THRESHOLD); else CHECK(SPECULATION_THRESHOLD);
else raiseExcHelper(ValueError, "unknown option name '%s", option_string->s.c_str()); else raiseExcHelper(ValueError, "unknown option name '%s", option_string->s.data());
return None; return None;
} }
......
...@@ -43,7 +43,7 @@ Box* sysExcInfo() { ...@@ -43,7 +43,7 @@ Box* sysExcInfo() {
assert(exc->type); assert(exc->type);
assert(exc->value); assert(exc->value);
assert(exc->traceback); assert(exc->traceback);
return new BoxedTuple({ exc->type, exc->value, exc->traceback }); return BoxedTuple::create({ exc->type, exc->value, exc->traceback });
} }
Box* sysExcClear() { Box* sysExcClear() {
...@@ -184,7 +184,7 @@ void prependToSysPath(const std::string& path) { ...@@ -184,7 +184,7 @@ void prependToSysPath(const std::string& path) {
BoxedList* sys_path = getSysPath(); BoxedList* sys_path = getSysPath();
static std::string attr = "insert"; static std::string attr = "insert";
callattr(sys_path, &attr, CallattrFlags({.cls_only = false, .null_on_nonexistent = false }), ArgPassSpec(2), callattr(sys_path, &attr, CallattrFlags({.cls_only = false, .null_on_nonexistent = false }), ArgPassSpec(2),
boxInt(0), new BoxedString(path), NULL, NULL, NULL); boxInt(0), boxString(path), NULL, NULL, NULL);
} }
static BoxedClass* sys_flags_cls; static BoxedClass* sys_flags_cls;
...@@ -258,7 +258,7 @@ void setupSys() { ...@@ -258,7 +258,7 @@ void setupSys() {
sys_module->giveAttr("warnoptions", new BoxedList()); sys_module->giveAttr("warnoptions", new BoxedList());
sys_module->giveAttr("py3kwarning", False); sys_module->giveAttr("py3kwarning", False);
sys_module->giveAttr("byteorder", new BoxedString(isLittleEndian() ? "little" : "big")); sys_module->giveAttr("byteorder", boxStrConstant(isLittleEndian() ? "little" : "big"));
sys_module->giveAttr("platform", boxStrConstant("unknown")); // seems like a reasonable, if poor, default sys_module->giveAttr("platform", boxStrConstant("unknown")); // seems like a reasonable, if poor, default
...@@ -293,14 +293,14 @@ void setupSys() { ...@@ -293,14 +293,14 @@ void setupSys() {
sys_module->giveAttr("hexversion", boxInt(PY_VERSION_HEX)); sys_module->giveAttr("hexversion", boxInt(PY_VERSION_HEX));
// TODO: this should be a "sys.version_info" object, not just a tuple (ie can access fields by name) // TODO: this should be a "sys.version_info" object, not just a tuple (ie can access fields by name)
sys_module->giveAttr("version_info", sys_module->giveAttr("version_info",
new BoxedTuple({ boxInt(PYTHON_VERSION_MAJOR), boxInt(PYTHON_VERSION_MINOR), BoxedTuple::create({ boxInt(PYTHON_VERSION_MAJOR), boxInt(PYTHON_VERSION_MINOR),
boxInt(PYTHON_VERSION_MICRO), boxStrConstant("beta"), boxInt(0) })); boxInt(PYTHON_VERSION_MICRO), boxStrConstant("beta"), boxInt(0) }));
sys_module->giveAttr("maxint", boxInt(PYSTON_INT_MAX)); sys_module->giveAttr("maxint", boxInt(PYSTON_INT_MAX));
sys_module->giveAttr("maxsize", boxInt(PY_SSIZE_T_MAX)); sys_module->giveAttr("maxsize", boxInt(PY_SSIZE_T_MAX));
sys_flags_cls = new BoxedHeapClass(object_cls, BoxedSysFlags::gcHandler, 0, 0, sizeof(BoxedSysFlags), false, sys_flags_cls = new BoxedHeapClass(object_cls, BoxedSysFlags::gcHandler, 0, 0, sizeof(BoxedSysFlags), false,
new BoxedString("flags")); static_cast<BoxedString*>(boxString("flags")));
sys_flags_cls->giveAttr("__new__", sys_flags_cls->giveAttr("__new__",
new BoxedFunction(boxRTFunction((void*)BoxedSysFlags::__new__, UNKNOWN, 1, 0, true, true))); new BoxedFunction(boxRTFunction((void*)BoxedSysFlags::__new__, UNKNOWN, 1, 0, true, true)));
#define ADD(name) \ #define ADD(name) \
...@@ -311,7 +311,7 @@ void setupSys() { ...@@ -311,7 +311,7 @@ void setupSys() {
ADD(no_user_site); ADD(no_user_site);
#undef ADD #undef ADD
sys_flags_cls->tp_mro = new BoxedTuple({ sys_flags_cls, object_cls }); sys_flags_cls->tp_mro = BoxedTuple::create({ sys_flags_cls, object_cls });
sys_flags_cls->freeze(); sys_flags_cls->freeze();
sys_module->giveAttr("flags", new BoxedSysFlags()); sys_module->giveAttr("flags", new BoxedSysFlags());
...@@ -326,7 +326,8 @@ void setupSysEnd() { ...@@ -326,7 +326,8 @@ void setupSysEnd() {
std::sort<decltype(builtin_module_names)::iterator, PyLt>(builtin_module_names.begin(), builtin_module_names.end(), std::sort<decltype(builtin_module_names)::iterator, PyLt>(builtin_module_names.begin(), builtin_module_names.end(),
PyLt()); PyLt());
sys_module->giveAttr("builtin_module_names", new BoxedTuple(std::move(builtin_module_names))); sys_module->giveAttr("builtin_module_names",
BoxedTuple::create(builtin_module_names.size(), &builtin_module_names[0]));
sys_flags_cls->finishInitialization(); sys_flags_cls->finishInitialization();
} }
} }
...@@ -250,7 +250,7 @@ extern "C" PyObject* PyObject_GetAttr(PyObject* o, PyObject* attr_name) noexcept ...@@ -250,7 +250,7 @@ extern "C" PyObject* PyObject_GetAttr(PyObject* o, PyObject* attr_name) noexcept
} }
try { try {
return getattr(o, static_cast<BoxedString*>(attr_name)->s.c_str()); return getattr(o, static_cast<BoxedString*>(attr_name)->data());
} catch (ExcInfo e) { } catch (ExcInfo e) {
setCAPIException(e); setCAPIException(e);
return NULL; return NULL;
...@@ -258,7 +258,7 @@ extern "C" PyObject* PyObject_GetAttr(PyObject* o, PyObject* attr_name) noexcept ...@@ -258,7 +258,7 @@ extern "C" PyObject* PyObject_GetAttr(PyObject* o, PyObject* attr_name) noexcept
} }
extern "C" PyObject* PyObject_GenericGetAttr(PyObject* o, PyObject* name) noexcept { extern "C" PyObject* PyObject_GenericGetAttr(PyObject* o, PyObject* name) noexcept {
Box* r = getattrInternalGeneric(o, static_cast<BoxedString*>(name)->s.c_str(), NULL, false, false, NULL, NULL); Box* r = getattrInternalGeneric(o, static_cast<BoxedString*>(name)->data(), NULL, false, false, NULL, NULL);
if (!r) if (!r)
PyErr_Format(PyExc_AttributeError, "'%.50s' object has no attribute '%.400s'", o->cls->tp_name, PyErr_Format(PyExc_AttributeError, "'%.50s' object has no attribute '%.400s'", o->cls->tp_name,
PyString_AS_STRING(name)); PyString_AS_STRING(name));
...@@ -879,7 +879,8 @@ extern "C" PyObject* PyImport_Import(PyObject* module_name) noexcept { ...@@ -879,7 +879,8 @@ extern "C" PyObject* PyImport_Import(PyObject* module_name) noexcept {
RELEASE_ASSERT(module_name->cls == str_cls, ""); RELEASE_ASSERT(module_name->cls == str_cls, "");
try { try {
return importModuleLevel(&static_cast<BoxedString*>(module_name)->s, None, None, -1); std::string _module_name = static_cast<BoxedString*>(module_name)->s;
return importModuleLevel(_module_name, None, None, -1);
} catch (ExcInfo e) { } catch (ExcInfo e) {
Py_FatalError("unimplemented"); Py_FatalError("unimplemented");
} }
......
...@@ -33,7 +33,7 @@ static Box* classLookup(BoxedClassobj* cls, const std::string& attr) { ...@@ -33,7 +33,7 @@ static Box* classLookup(BoxedClassobj* cls, const std::string& attr) {
if (r) if (r)
return r; return r;
for (auto b : cls->bases->elts) { for (auto b : *cls->bases) {
RELEASE_ASSERT(b->cls == classobj_cls, ""); RELEASE_ASSERT(b->cls == classobj_cls, "");
Box* r = classLookup(static_cast<BoxedClassobj*>(b), attr); Box* r = classLookup(static_cast<BoxedClassobj*>(b), attr);
if (r) if (r)
...@@ -88,7 +88,7 @@ Box* classobjNew(Box* _cls, Box* _name, Box* _bases, Box** _args) { ...@@ -88,7 +88,7 @@ Box* classobjNew(Box* _cls, Box* _name, Box* _bases, Box** _args) {
raiseExcHelper(TypeError, "PyClass_New: bases must be a tuple"); raiseExcHelper(TypeError, "PyClass_New: bases must be a tuple");
BoxedTuple* bases = static_cast<BoxedTuple*>(_bases); BoxedTuple* bases = static_cast<BoxedTuple*>(_bases);
for (auto base : bases->elts) { for (auto base : *bases) {
if (!PyClass_Check(base) && PyCallable_Check(base->cls)) { if (!PyClass_Check(base) && PyCallable_Check(base->cls)) {
Box* r = PyObject_CallFunctionObjArgs(base->cls, name, bases, dict, NULL); Box* r = PyObject_CallFunctionObjArgs(base->cls, name, bases, dict, NULL);
if (!r) if (!r)
...@@ -104,7 +104,7 @@ Box* classobjNew(Box* _cls, Box* _name, Box* _bases, Box** _args) { ...@@ -104,7 +104,7 @@ Box* classobjNew(Box* _cls, Box* _name, Box* _bases, Box** _args) {
for (auto& p : dict->d) { for (auto& p : dict->d) {
RELEASE_ASSERT(p.first->cls == str_cls, ""); RELEASE_ASSERT(p.first->cls == str_cls, "");
made->setattr(static_cast<BoxedString*>(p.first)->s, p.second, NULL); made->setattr(std::string(static_cast<BoxedString*>(p.first)->s), p.second, NULL);
} }
// Note: make sure to do this after assigning the attrs, since it will overwrite any defined __name__ // Note: make sure to do this after assigning the attrs, since it will overwrite any defined __name__
...@@ -134,7 +134,7 @@ Box* classobjCall(Box* _cls, Box* _args, Box* _kwargs) { ...@@ -134,7 +134,7 @@ Box* classobjCall(Box* _cls, Box* _args, Box* _kwargs) {
if (init_rtn != None) if (init_rtn != None)
raiseExcHelper(TypeError, "__init__() should return None"); raiseExcHelper(TypeError, "__init__() should return None");
} else { } else {
if (args->elts.size() || kwargs->d.size()) if (args->size() || kwargs->d.size())
raiseExcHelper(TypeError, "this constructor takes no arguments"); raiseExcHelper(TypeError, "this constructor takes no arguments");
} }
return made; return made;
...@@ -162,9 +162,9 @@ static Box* classobjGetattribute(Box* _cls, Box* _attr) { ...@@ -162,9 +162,9 @@ static Box* classobjGetattribute(Box* _cls, Box* _attr) {
} }
} }
Box* r = classLookup(cls, attr->s); Box* r = classLookup(cls, std::string(attr->s));
if (!r) if (!r)
raiseExcHelper(AttributeError, "class %s has no attribute '%s'", cls->name->s.c_str(), attr->s.c_str()); raiseExcHelper(AttributeError, "class %s has no attribute '%s'", cls->name->data(), attr->data());
r = processDescriptor(r, None, cls); r = processDescriptor(r, None, cls);
return r; return r;
...@@ -242,7 +242,7 @@ Box* classobjStr(Box* _obj) { ...@@ -242,7 +242,7 @@ Box* classobjStr(Box* _obj) {
Box* _mod = cls->getattr("__module__"); Box* _mod = cls->getattr("__module__");
RELEASE_ASSERT(_mod, ""); RELEASE_ASSERT(_mod, "");
RELEASE_ASSERT(_mod->cls == str_cls, ""); RELEASE_ASSERT(_mod->cls == str_cls, "");
return boxString(static_cast<BoxedString*>(_mod)->s + "." + cls->name->s); return boxStringTwine(llvm::Twine(static_cast<BoxedString*>(_mod)->s) + "." + cls->name->s);
} }
static Box* _instanceGetattribute(Box* _inst, Box* _attr, bool raise_on_missing) { static Box* _instanceGetattribute(Box* _inst, Box* _attr, bool raise_on_missing) {
...@@ -282,8 +282,7 @@ static Box* _instanceGetattribute(Box* _inst, Box* _attr, bool raise_on_missing) ...@@ -282,8 +282,7 @@ static Box* _instanceGetattribute(Box* _inst, Box* _attr, bool raise_on_missing)
if (!raise_on_missing) if (!raise_on_missing)
return NULL; return NULL;
raiseExcHelper(AttributeError, "%s instance has no attribute '%s'", inst->inst_cls->name->s.c_str(), raiseExcHelper(AttributeError, "%s instance has no attribute '%s'", inst->inst_cls->name->data(), attr->data());
attr->s.c_str());
} }
Box* instanceGetattribute(Box* _inst, Box* _attr) { Box* instanceGetattribute(Box* _inst, Box* _attr) {
...@@ -361,7 +360,7 @@ Box* instanceRepr(Box* _inst) { ...@@ -361,7 +360,7 @@ Box* instanceRepr(Box* _inst) {
assert(class_str->cls == str_cls); assert(class_str->cls == str_cls);
char buf[80]; char buf[80];
snprintf(buf, 80, "<%s instance at %p>", static_cast<BoxedString*>(class_str)->s.c_str(), inst); snprintf(buf, 80, "<%s instance at %p>", static_cast<BoxedString*>(class_str)->data(), inst);
return boxStrConstant(buf); return boxStrConstant(buf);
} }
} }
...@@ -495,7 +494,7 @@ Box* instanceCall(Box* _inst, Box* _args, Box* _kwargs) { ...@@ -495,7 +494,7 @@ Box* instanceCall(Box* _inst, Box* _args, Box* _kwargs) {
Box* call_func = _instanceGetattribute(inst, boxStrConstant("__call__"), false); Box* call_func = _instanceGetattribute(inst, boxStrConstant("__call__"), false);
if (!call_func) if (!call_func)
raiseExcHelper(AttributeError, "%s instance has no __call__ method", inst->inst_cls->name->s.c_str()); raiseExcHelper(AttributeError, "%s instance has no __call__ method", inst->inst_cls->name->data());
return runtimeCall(call_func, ArgPassSpec(0, 0, true, true), _args, _kwargs, NULL, NULL, NULL); return runtimeCall(call_func, ArgPassSpec(0, 0, true, true), _args, _kwargs, NULL, NULL, NULL);
} }
......
...@@ -55,12 +55,12 @@ public: ...@@ -55,12 +55,12 @@ public:
BoxedTuple::GCVector elts; BoxedTuple::GCVector elts;
for (auto sr : param_names.args) for (auto sr : param_names.args)
elts.push_back(new BoxedString(sr)); elts.push_back(boxString(sr));
if (param_names.vararg.size()) if (param_names.vararg.size())
elts.push_back(new BoxedString(param_names.vararg)); elts.push_back(boxString(param_names.vararg));
if (param_names.kwarg.size()) if (param_names.kwarg.size())
elts.push_back(new BoxedString(param_names.kwarg)); elts.push_back(boxString(param_names.kwarg));
return new BoxedTuple(std::move(elts)); return BoxedTuple::create(elts.size(), &elts[0]);
} }
static Box* flags(Box* b, void*) { static Box* flags(Box* b, void*) {
......
...@@ -44,7 +44,7 @@ Box* dictRepr(BoxedDict* self) { ...@@ -44,7 +44,7 @@ Box* dictRepr(BoxedDict* self) {
chars.insert(chars.end(), v->s.begin(), v->s.end()); chars.insert(chars.end(), v->s.begin(), v->s.end());
} }
chars.push_back('}'); chars.push_back('}');
return boxString(std::string(chars.begin(), chars.end())); return boxString(llvm::StringRef(&chars[0], chars.size()));
} }
Box* dictClear(BoxedDict* self) { Box* dictClear(BoxedDict* self) {
...@@ -69,10 +69,7 @@ Box* dictItems(BoxedDict* self) { ...@@ -69,10 +69,7 @@ Box* dictItems(BoxedDict* self) {
rtn->ensure(self->d.size()); rtn->ensure(self->d.size());
for (const auto& p : self->d) { for (const auto& p : self->d) {
BoxedTuple::GCVector elts; BoxedTuple* t = BoxedTuple::create({ p.first, p.second });
elts.push_back(p.first);
elts.push_back(p.second);
BoxedTuple* t = new BoxedTuple(std::move(elts));
listAppendInternal(rtn, t); listAppendInternal(rtn, t);
} }
...@@ -378,7 +375,7 @@ Box* dictPopitem(BoxedDict* self) { ...@@ -378,7 +375,7 @@ Box* dictPopitem(BoxedDict* self) {
Box* value = it->second; Box* value = it->second;
self->d.erase(it); self->d.erase(it);
auto rtn = new BoxedTuple({ key, value }); auto rtn = BoxedTuple::create({ key, value });
return rtn; return rtn;
} }
...@@ -506,9 +503,9 @@ void dictMergeFromSeq2(BoxedDict* self, Box* other) { ...@@ -506,9 +503,9 @@ void dictMergeFromSeq2(BoxedDict* self, Box* other) {
self->d[list->elts->elts[0]] = list->elts->elts[1]; self->d[list->elts->elts[0]] = list->elts->elts[1];
} else if (element->cls == tuple_cls) { } else if (element->cls == tuple_cls) {
BoxedTuple* tuple = static_cast<BoxedTuple*>(element); BoxedTuple* tuple = static_cast<BoxedTuple*>(element);
if (tuple->elts.size() != 2) if (tuple->size() != 2)
raiseExcHelper(ValueError, "dictionary update sequence element #%d has length %d; 2 is required", idx, raiseExcHelper(ValueError, "dictionary update sequence element #%d has length %d; 2 is required", idx,
tuple->elts.size()); tuple->size());
self->d[tuple->elts[0]] = tuple->elts[1]; self->d[tuple->elts[0]] = tuple->elts[1];
} else } else
...@@ -541,8 +538,8 @@ Box* dictUpdate(BoxedDict* self, BoxedTuple* args, BoxedDict* kwargs) { ...@@ -541,8 +538,8 @@ Box* dictUpdate(BoxedDict* self, BoxedTuple* args, BoxedDict* kwargs) {
assert(kwargs); assert(kwargs);
assert(kwargs->cls == dict_cls); assert(kwargs->cls == dict_cls);
RELEASE_ASSERT(args->elts.size() <= 1, ""); // should throw a TypeError RELEASE_ASSERT(args->size() <= 1, ""); // should throw a TypeError
if (args->elts.size()) { if (args->size()) {
Box* arg = args->elts[0]; Box* arg = args->elts[0];
if (getattrInternal(arg, "keys", NULL)) { if (getattrInternal(arg, "keys", NULL)) {
dictMerge(self, arg); dictMerge(self, arg);
...@@ -558,7 +555,7 @@ Box* dictUpdate(BoxedDict* self, BoxedTuple* args, BoxedDict* kwargs) { ...@@ -558,7 +555,7 @@ Box* dictUpdate(BoxedDict* self, BoxedTuple* args, BoxedDict* kwargs) {
} }
extern "C" Box* dictInit(BoxedDict* self, BoxedTuple* args, BoxedDict* kwargs) { extern "C" Box* dictInit(BoxedDict* self, BoxedTuple* args, BoxedDict* kwargs) {
int args_sz = args->elts.size(); int args_sz = args->size();
int kwargs_sz = kwargs->d.size(); int kwargs_sz = kwargs->d.size();
// CPython accepts a single positional and keyword arguments, in any combination // CPython accepts a single positional and keyword arguments, in any combination
......
...@@ -195,7 +195,7 @@ BoxedFile::BoxedFile(FILE* f, std::string fname, const char* fmode, int (*close) ...@@ -195,7 +195,7 @@ BoxedFile::BoxedFile(FILE* f, std::string fname, const char* fmode, int (*close)
f_bufptr(0), f_bufptr(0),
f_setbuf(0), f_setbuf(0),
unlocked_count(0) { unlocked_count(0) {
Box* r = fill_file_fields(this, f, new BoxedString(fname), fmode, close); Box* r = fill_file_fields(this, f, boxString(fname), fmode, close);
checkAndThrowCAPIException(); checkAndThrowCAPIException();
assert(r == this); assert(r == this);
} }
...@@ -823,17 +823,17 @@ Box* fileNew(BoxedClass* cls, Box* s, Box* m) { ...@@ -823,17 +823,17 @@ Box* fileNew(BoxedClass* cls, Box* s, Box* m) {
raiseExcHelper(TypeError, ""); raiseExcHelper(TypeError, "");
} }
const std::string& fn = static_cast<BoxedString*>(s)->s; auto fn = static_cast<BoxedString*>(s);
const std::string& mode = static_cast<BoxedString*>(m)->s; auto mode = static_cast<BoxedString*>(m);
FILE* f = fopen(fn.c_str(), mode.c_str()); FILE* f = fopen(fn->data(), mode->data());
if (!f) { if (!f) {
PyErr_SetFromErrnoWithFilename(IOError, fn.c_str()); PyErr_SetFromErrnoWithFilename(IOError, fn->data());
throwCAPIException(); throwCAPIException();
abort(); // unreachable; abort(); // unreachable;
} }
return new BoxedFile(f, fn, PyString_AsString(m)); return new BoxedFile(f, fn->s, PyString_AsString(m));
} }
static PyObject* file_readlines(BoxedFile* f, PyObject* args) noexcept { static PyObject* file_readlines(BoxedFile* f, PyObject* args) noexcept {
......
...@@ -166,7 +166,7 @@ SearchResult findModule(const std::string& name, const std::string& full_name, B ...@@ -166,7 +166,7 @@ SearchResult findModule(const std::string& name, const std::string& full_name, B
auto path_pass = path_list ? path_list : None; auto path_pass = path_list ? path_list : None;
Box* loader Box* loader
= callattr(finder, &find_module_str, CallattrFlags({.cls_only = false, .null_on_nonexistent = false }), = callattr(finder, &find_module_str, CallattrFlags({.cls_only = false, .null_on_nonexistent = false }),
ArgPassSpec(2), new BoxedString(full_name), path_pass, NULL, NULL, NULL); ArgPassSpec(2), boxString(full_name), path_pass, NULL, NULL, NULL);
if (loader != None) if (loader != None)
return SearchResult(loader); return SearchResult(loader);
...@@ -195,7 +195,7 @@ SearchResult findModule(const std::string& name, const std::string& full_name, B ...@@ -195,7 +195,7 @@ SearchResult findModule(const std::string& name, const std::string& full_name, B
BoxedString* p = static_cast<BoxedString*>(_p); BoxedString* p = static_cast<BoxedString*>(_p);
joined_path.clear(); joined_path.clear();
llvm::sys::path::append(joined_path, p->s, name); llvm::sys::path::append(joined_path, std::string(p->s), name);
std::string dn(joined_path.str()); std::string dn(joined_path.str());
llvm::sys::path::append(joined_path, "__init__.py"); llvm::sys::path::append(joined_path, "__init__.py");
...@@ -209,7 +209,7 @@ SearchResult findModule(const std::string& name, const std::string& full_name, B ...@@ -209,7 +209,7 @@ SearchResult findModule(const std::string& name, const std::string& full_name, B
auto path_pass = path_list ? path_list : None; auto path_pass = path_list ? path_list : None;
Box* loader = callattr(importer, &find_module_str, Box* loader = callattr(importer, &find_module_str,
CallattrFlags({.cls_only = false, .null_on_nonexistent = false }), ArgPassSpec(2), CallattrFlags({.cls_only = false, .null_on_nonexistent = false }), ArgPassSpec(2),
new BoxedString(full_name), path_pass, NULL, NULL, NULL); boxString(full_name), path_pass, NULL, NULL, NULL);
if (loader != None) if (loader != None)
return SearchResult(loader); return SearchResult(loader);
} }
...@@ -218,7 +218,7 @@ SearchResult findModule(const std::string& name, const std::string& full_name, B ...@@ -218,7 +218,7 @@ SearchResult findModule(const std::string& name, const std::string& full_name, B
return SearchResult(std::move(dn), SearchResult::PKG_DIRECTORY); return SearchResult(std::move(dn), SearchResult::PKG_DIRECTORY);
joined_path.clear(); joined_path.clear();
llvm::sys::path::append(joined_path, p->s, name + ".py"); llvm::sys::path::append(joined_path, std::string(p->s), name + ".py");
fn = joined_path.str(); fn = joined_path.str();
if (pathExists(fn)) if (pathExists(fn))
...@@ -250,7 +250,7 @@ static Box* getParent(Box* globals, int level, std::string& buf) { ...@@ -250,7 +250,7 @@ static Box* getParent(Box* globals, int level, std::string& buf) {
if (pkgname->cls != str_cls) { if (pkgname->cls != str_cls) {
raiseExcHelper(ValueError, "__package__ set to non-string"); raiseExcHelper(ValueError, "__package__ set to non-string");
} }
size_t len = pkgname->s.size(); size_t len = pkgname->size();
if (len == 0) { if (len == 0) {
if (level > 0) { if (level > 0) {
raiseExcHelper(ValueError, "Attempted relative import in non-package"); raiseExcHelper(ValueError, "Attempted relative import in non-package");
...@@ -270,7 +270,7 @@ static Box* getParent(Box* globals, int level, std::string& buf) { ...@@ -270,7 +270,7 @@ static Box* getParent(Box* globals, int level, std::string& buf) {
Box* modpath = getattrInternal(globals, path_str, NULL); Box* modpath = getattrInternal(globals, path_str, NULL);
if (modpath != NULL) { if (modpath != NULL) {
/* __path__ is set, so modname is already the package name */ /* __path__ is set, so modname is already the package name */
if (modname->s.size() > PATH_MAX) { if (modname->size() > PATH_MAX) {
raiseExcHelper(ValueError, "Module name too long"); raiseExcHelper(ValueError, "Module name too long");
} }
buf += modname->s; buf += modname->s;
...@@ -357,7 +357,7 @@ static Box* importSub(const std::string& name, const std::string& full_name, Box ...@@ -357,7 +357,7 @@ static Box* importSub(const std::string& name, const std::string& full_name, Box
const static std::string load_module_str("load_module"); const static std::string load_module_str("load_module");
module = callattr(sr.loader, &load_module_str, module = callattr(sr.loader, &load_module_str,
CallattrFlags({.cls_only = false, .null_on_nonexistent = false }), ArgPassSpec(1), CallattrFlags({.cls_only = false, .null_on_nonexistent = false }), ArgPassSpec(1),
new BoxedString(full_name), NULL, NULL, NULL, NULL); boxString(full_name), NULL, NULL, NULL, NULL);
} else } else
RELEASE_ASSERT(0, "%d", sr.type); RELEASE_ASSERT(0, "%d", sr.type);
...@@ -441,9 +441,8 @@ static bool loadNext(Box* mod, Box* altmod, std::string& name, std::string& buf, ...@@ -441,9 +441,8 @@ static bool loadNext(Box* mod, Box* altmod, std::string& name, std::string& buf,
} }
static void ensureFromlist(Box* module, Box* fromlist, std::string& buf, bool recursive); static void ensureFromlist(Box* module, Box* fromlist, std::string& buf, bool recursive);
Box* importModuleLevel(std::string* name, Box* globals, Box* from_imports, int level) { Box* importModuleLevel(const std::string& name, Box* globals, Box* from_imports, int level) {
bool return_first = from_imports == None; bool return_first = from_imports == None;
assert(name);
static StatCounter slowpath_import("slowpath_import"); static StatCounter slowpath_import("slowpath_import");
slowpath_import.log(); slowpath_import.log();
...@@ -453,7 +452,9 @@ Box* importModuleLevel(std::string* name, Box* globals, Box* from_imports, int l ...@@ -453,7 +452,9 @@ Box* importModuleLevel(std::string* name, Box* globals, Box* from_imports, int l
if (!parent) if (!parent)
return NULL; return NULL;
std::string _name = *name; // make a copy of the string we pass in, since loadNext while
// modify the string as we load the modules along the path.
std::string _name = name;
Box* head; Box* head;
bool again = loadNext(parent, level < 0 ? NULL : parent, _name, buf, &head); bool again = loadNext(parent, level < 0 ? NULL : parent, _name, buf, &head);
...@@ -505,7 +506,7 @@ extern "C" PyObject* PyImport_ImportModuleLevel(const char* name, PyObject* glob ...@@ -505,7 +506,7 @@ extern "C" PyObject* PyImport_ImportModuleLevel(const char* name, PyObject* glob
PyObject* fromlist, int level) noexcept { PyObject* fromlist, int level) noexcept {
try { try {
std::string module_name = name; std::string module_name = name;
return importModuleLevel(&module_name, globals, fromlist ? fromlist : None, level); return importModuleLevel(module_name, globals, fromlist ? fromlist : None, level);
} catch (ExcInfo e) { } catch (ExcInfo e) {
setCAPIException(e); setCAPIException(e);
return NULL; return NULL;
...@@ -539,7 +540,7 @@ static void ensureFromlist(Box* module, Box* fromlist, std::string& buf, bool re ...@@ -539,7 +540,7 @@ static void ensureFromlist(Box* module, Box* fromlist, std::string& buf, bool re
continue; continue;
// Just want to import it and add it to the modules list for now: // Just want to import it and add it to the modules list for now:
importSub(s->s, buf + '.' + s->s, module); importSub(s->s, (llvm::Twine(buf) + "." + s->s).str(), module);
} }
} }
...@@ -586,7 +587,7 @@ extern "C" PyObject* PyImport_ExecCodeModuleEx(char* name, PyObject* co, char* p ...@@ -586,7 +587,7 @@ extern "C" PyObject* PyImport_ExecCodeModuleEx(char* name, PyObject* co, char* p
if (module == NULL) if (module == NULL)
return NULL; return NULL;
AST_Module* ast = parse_string(code->s.c_str()); AST_Module* ast = parse_string(code->data());
compileAndRunModule(ast, module); compileAndRunModule(ast, module);
module->setattr("__file__", boxString(pathname), NULL); module->setattr("__file__", boxString(pathname), NULL);
return module; return module;
...@@ -611,7 +612,7 @@ Box* nullImporterInit(Box* self, Box* _path) { ...@@ -611,7 +612,7 @@ Box* nullImporterInit(Box* self, Box* _path) {
if (path->s.empty()) if (path->s.empty())
raiseExcHelper(ImportError, "empty pathname"); raiseExcHelper(ImportError, "empty pathname");
if (isdir(path->s.c_str())) if (isdir(path->data()))
raiseExcHelper(ImportError, "existing directory"); raiseExcHelper(ImportError, "existing directory");
return None; return None;
...@@ -623,7 +624,7 @@ Box* nullImporterFindModule(Box* self, Box* fullname, Box* path) { ...@@ -623,7 +624,7 @@ Box* nullImporterFindModule(Box* self, Box* fullname, Box* path) {
extern "C" Box* import(int level, Box* from_imports, const std::string* module_name) { extern "C" Box* import(int level, Box* from_imports, const std::string* module_name) {
std::string _module_name(*module_name); std::string _module_name(*module_name);
return importModuleLevel(&_module_name, getCurrentModule(), from_imports, level); return importModuleLevel(_module_name, getCurrentModule(), from_imports, level);
} }
Box* impFindModule(Box* _name, BoxedList* path) { Box* impFindModule(Box* _name, BoxedList* path) {
...@@ -635,19 +636,19 @@ Box* impFindModule(Box* _name, BoxedList* path) { ...@@ -635,19 +636,19 @@ Box* impFindModule(Box* _name, BoxedList* path) {
SearchResult sr = findModule(name->s, name->s, path_list); SearchResult sr = findModule(name->s, name->s, path_list);
if (sr.type == SearchResult::SEARCH_ERROR) if (sr.type == SearchResult::SEARCH_ERROR)
raiseExcHelper(ImportError, "%s", name->s.c_str()); raiseExcHelper(ImportError, "%s", name->data());
if (sr.type == SearchResult::PY_SOURCE) { if (sr.type == SearchResult::PY_SOURCE) {
Box* path = boxString(sr.path); Box* path = boxString(sr.path);
Box* mode = boxStrConstant("r"); Box* mode = boxStrConstant("r");
Box* f = runtimeCall(file_cls, ArgPassSpec(2), path, mode, NULL, NULL, NULL); Box* f = runtimeCall(file_cls, ArgPassSpec(2), path, mode, NULL, NULL, NULL);
return new BoxedTuple({ f, path, new BoxedTuple({ boxStrConstant(".py"), mode, boxInt(sr.type) }) }); return BoxedTuple::create({ f, path, BoxedTuple::create({ boxStrConstant(".py"), mode, boxInt(sr.type) }) });
} }
if (sr.type == SearchResult::PKG_DIRECTORY) { if (sr.type == SearchResult::PKG_DIRECTORY) {
Box* path = boxString(sr.path); Box* path = boxString(sr.path);
Box* mode = boxStrConstant(""); Box* mode = EmptyString;
return new BoxedTuple({ None, path, new BoxedTuple({ mode, mode, boxInt(sr.type) }) }); return BoxedTuple::create({ None, path, BoxedTuple::create({ mode, mode, boxInt(sr.type) }) });
} }
Py_FatalError("unimplemented"); Py_FatalError("unimplemented");
...@@ -665,7 +666,7 @@ Box* impLoadModule(Box* _name, Box* _file, Box* _pathname, Box** args) { ...@@ -665,7 +666,7 @@ Box* impLoadModule(Box* _name, Box* _file, Box* _pathname, Box** args) {
BoxedString* pathname = (BoxedString*)_pathname; BoxedString* pathname = (BoxedString*)_pathname;
BoxedTuple* description = (BoxedTuple*)_description; BoxedTuple* description = (BoxedTuple*)_description;
RELEASE_ASSERT(description->elts.size() == 3, ""); RELEASE_ASSERT(description->size() == 3, "");
BoxedString* suffix = (BoxedString*)description->elts[0]; BoxedString* suffix = (BoxedString*)description->elts[0];
BoxedString* mode = (BoxedString*)description->elts[1]; BoxedString* mode = (BoxedString*)description->elts[1];
BoxedInt* type = (BoxedInt*)description->elts[2]; BoxedInt* type = (BoxedInt*)description->elts[2];
...@@ -678,7 +679,7 @@ Box* impLoadModule(Box* _name, Box* _file, Box* _pathname, Box** args) { ...@@ -678,7 +679,7 @@ Box* impLoadModule(Box* _name, Box* _file, Box* _pathname, Box** args) {
RELEASE_ASSERT(mode->s.empty(), ""); RELEASE_ASSERT(mode->s.empty(), "");
if (type->n == SearchResult::PKG_DIRECTORY) { if (type->n == SearchResult::PKG_DIRECTORY) {
return createAndRunModule(name->s, pathname->s + "/__init__.py", pathname->s); return createAndRunModule(name->s, (llvm::Twine(pathname->s) + "/__init__.py").str(), pathname->s);
} }
Py_FatalError("unimplemented"); Py_FatalError("unimplemented");
...@@ -688,7 +689,7 @@ Box* impGetSuffixes() { ...@@ -688,7 +689,7 @@ Box* impGetSuffixes() {
BoxedList* list = new BoxedList; BoxedList* list = new BoxedList;
// For now only add *.py // For now only add *.py
listAppendInternal( listAppendInternal(
list, new BoxedTuple({ new BoxedString(".py"), new BoxedString("U"), boxInt(SearchResult::PY_SOURCE) })); list, BoxedTuple::create({ boxStrConstant(".py"), boxStrConstant("U"), boxInt(SearchResult::PY_SOURCE) }));
return list; return list;
} }
......
...@@ -20,7 +20,7 @@ ...@@ -20,7 +20,7 @@
namespace pyston { namespace pyston {
extern "C" Box* import(int level, Box* from_imports, const std::string* module_name); extern "C" Box* import(int level, Box* from_imports, const std::string* module_name);
extern Box* importModuleLevel(std::string* module_name, Box* globals, Box* from_imports, int level); extern Box* importModuleLevel(const std::string& module_name, Box* globals, Box* from_imports, int level);
} }
#endif #endif
...@@ -14,6 +14,8 @@ ...@@ -14,6 +14,8 @@
#include "runtime/inline/boxing.h" #include "runtime/inline/boxing.h"
#include "llvm/ADT/SmallString.h"
#include "runtime/int.h" #include "runtime/int.h"
#include "runtime/objmodel.h" #include "runtime/objmodel.h"
#include "runtime/types.h" #include "runtime/types.h"
...@@ -28,25 +30,43 @@ extern "C" Box* createList() { ...@@ -28,25 +30,43 @@ extern "C" Box* createList() {
return new BoxedList(); return new BoxedList();
} }
BoxedString* _boxStrConstant(const char* chars) {
size_t len = strlen(chars);
return new (len) BoxedString(chars, len);
}
extern "C" BoxedString* boxStrConstant(const char* chars) { extern "C" BoxedString* boxStrConstant(const char* chars) {
return new BoxedString(chars); return _boxStrConstant(chars);
}
BoxedString* _boxStrConstantSize(const char* chars, size_t 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) {
return new BoxedString(chars, n); return _boxStrConstantSize(chars, n);
} }
extern "C" Box* boxStringPtr(const std::string* s) { extern "C" Box* boxStringPtr(const std::string* s) {
return new BoxedString(*s); return new (s->size()) BoxedString(s->c_str(), s->size());
}
Box* boxStringRef(llvm::StringRef s) {
return new (s.size()) BoxedString(s);
} }
Box* boxString(const std::string& s) { Box* boxString(const std::string& s) {
return new BoxedString(s); return new (s.size()) BoxedString(s.c_str(), s.size());
} }
Box* boxString(std::string&& s) { Box* boxString(std::string&& s) {
return new BoxedString(std::move(s)); return new (s.size()) BoxedString(s.c_str(), s.size());
}
Box* boxStringTwine(const llvm::Twine& t) {
llvm::SmallString<256> Vec;
return boxString(t.toStringRef(Vec));
} }
extern "C" double unboxFloat(Box* b) { extern "C" double unboxFloat(Box* b) {
ASSERT(b->cls == float_cls, "%s", getTypeName(b)); ASSERT(b->cls == float_cls, "%s", getTypeName(b));
BoxedFloat* f = (BoxedFloat*)b; BoxedFloat* f = (BoxedFloat*)b;
......
...@@ -66,8 +66,7 @@ Box* dictIterNext(Box* s) { ...@@ -66,8 +66,7 @@ Box* dictIterNext(Box* s) {
} else if (self->type == BoxedDictIterator::ValueIterator) { } else if (self->type == BoxedDictIterator::ValueIterator) {
rtn = self->it->second; rtn = self->it->second;
} else if (self->type == BoxedDictIterator::ItemIterator) { } else if (self->type == BoxedDictIterator::ItemIterator) {
BoxedTuple::GCVector elts{ self->it->first, self->it->second }; rtn = BoxedTuple::create({ self->it->first, self->it->second });
rtn = new BoxedTuple(std::move(elts));
} }
++self->it; ++self->it;
return rtn; return rtn;
......
...@@ -40,14 +40,14 @@ i1 tupleiterHasnextUnboxed(Box* s) { ...@@ -40,14 +40,14 @@ i1 tupleiterHasnextUnboxed(Box* s) {
assert(s->cls == tuple_iterator_cls); assert(s->cls == tuple_iterator_cls);
BoxedTupleIterator* self = static_cast<BoxedTupleIterator*>(s); BoxedTupleIterator* self = static_cast<BoxedTupleIterator*>(s);
return self->pos < self->t->elts.size(); return self->pos < self->t->size();
} }
Box* tupleiterNext(Box* s) { Box* tupleiterNext(Box* s) {
assert(s->cls == tuple_iterator_cls); assert(s->cls == tuple_iterator_cls);
BoxedTupleIterator* self = static_cast<BoxedTupleIterator*>(s); BoxedTupleIterator* self = static_cast<BoxedTupleIterator*>(s);
if (!(self->pos >= 0 && self->pos < self->t->elts.size())) { if (!(self->pos >= 0 && self->pos < self->t->size())) {
raiseExcHelper(StopIteration, ""); raiseExcHelper(StopIteration, "");
} }
......
...@@ -873,7 +873,7 @@ extern "C" BoxedString* intRepr(BoxedInt* v) { ...@@ -873,7 +873,7 @@ extern "C" BoxedString* intRepr(BoxedInt* v) {
char buf[80]; char buf[80];
int len = snprintf(buf, 80, "%ld", v->n); int len = snprintf(buf, 80, "%ld", v->n);
return new BoxedString(std::string(buf, len)); return static_cast<BoxedString*>(boxString(llvm::StringRef(buf, len)));
} }
extern "C" Box* intHash(BoxedInt* self) { extern "C" Box* intHash(BoxedInt* self) {
...@@ -898,7 +898,7 @@ extern "C" Box* intHex(BoxedInt* self) { ...@@ -898,7 +898,7 @@ extern "C" Box* intHex(BoxedInt* self) {
len = snprintf(buf, sizeof(buf), "-0x%lx", std::abs(self->n)); len = snprintf(buf, sizeof(buf), "-0x%lx", std::abs(self->n));
else else
len = snprintf(buf, sizeof(buf), "0x%lx", self->n); len = snprintf(buf, sizeof(buf), "0x%lx", self->n);
return new BoxedString(std::string(buf, len)); return boxStringRef(llvm::StringRef(buf, len));
} }
extern "C" Box* intOct(BoxedInt* self) { extern "C" Box* intOct(BoxedInt* self) {
...@@ -913,7 +913,7 @@ extern "C" Box* intOct(BoxedInt* self) { ...@@ -913,7 +913,7 @@ extern "C" Box* intOct(BoxedInt* self) {
len = snprintf(buf, sizeof(buf), "-%#lo", std::abs(self->n)); len = snprintf(buf, sizeof(buf), "-%#lo", std::abs(self->n));
else else
len = snprintf(buf, sizeof(buf), "%#lo", self->n); len = snprintf(buf, sizeof(buf), "%#lo", self->n);
return new BoxedString(std::string(buf, len)); return boxString(llvm::StringRef(buf, len));
} }
extern "C" Box* intTrunc(BoxedInt* self) { extern "C" Box* intTrunc(BoxedInt* self) {
...@@ -942,8 +942,8 @@ static Box* _intNew(Box* val, Box* base) { ...@@ -942,8 +942,8 @@ static Box* _intNew(Box* val, Box* base) {
BoxedString* s = static_cast<BoxedString*>(val); BoxedString* s = static_cast<BoxedString*>(val);
RELEASE_ASSERT(s->s.size() == strlen(s->s.c_str()), ""); RELEASE_ASSERT(s->size() == strlen(s->data()), "");
Box* r = PyInt_FromString(s->s.c_str(), NULL, base_n); Box* r = PyInt_FromString(s->data(), NULL, base_n);
if (!r) if (!r)
throwCAPIException(); throwCAPIException();
return r; return r;
......
...@@ -80,11 +80,11 @@ private: ...@@ -80,11 +80,11 @@ private:
static bool hasnext(BoxedList* o, uint64_t i) { return i < o->size; } static bool hasnext(BoxedList* o, uint64_t i) { return i < o->size; }
static Box* getValue(BoxedList* o, uint64_t i) { return o->elts->elts[i]; } static Box* getValue(BoxedList* o, uint64_t i) { return o->elts->elts[i]; }
static bool hasnext(BoxedTuple* o, uint64_t i) { return i < o->elts.size(); } static bool hasnext(BoxedTuple* o, uint64_t i) { return i < o->size(); }
static Box* getValue(BoxedTuple* o, uint64_t i) { return o->elts[i]; } static Box* getValue(BoxedTuple* o, uint64_t i) { return o->elts[i]; }
static bool hasnext(BoxedString* o, uint64_t i) { return i < o->s.size(); } static bool hasnext(BoxedString* o, uint64_t i) { return i < o->size(); }
static Box* getValue(BoxedString* o, uint64_t i) { return new BoxedString(std::string(1, o->s[i])); } static Box* getValue(BoxedString* o, uint64_t i) { return boxString(llvm::StringRef(o->data() + i, 1)); }
public: public:
BoxIteratorIndex(T* obj) : obj(obj), index(0) { BoxIteratorIndex(T* obj) : obj(obj), index(0) {
......
...@@ -16,7 +16,8 @@ ...@@ -16,7 +16,8 @@
#include <algorithm> #include <algorithm>
#include <cstring> #include <cstring>
#include <sstream>
#include "llvm/Support/raw_ostream.h"
#include "capi/types.h" #include "capi/types.h"
#include "core/ast.h" #include "core/ast.h"
...@@ -55,14 +56,16 @@ extern "C" PyObject* PyList_AsTuple(PyObject* v) noexcept { ...@@ -55,14 +56,16 @@ extern "C" PyObject* PyList_AsTuple(PyObject* v) noexcept {
} }
auto l = static_cast<BoxedList*>(v); auto l = static_cast<BoxedList*>(v);
return new BoxedTuple(BoxedTuple::GCVector(l->elts->elts, l->elts->elts + l->size)); return BoxedTuple::create(l->size, &l->elts->elts[0]);
} }
extern "C" Box* listRepr(BoxedList* self) { extern "C" Box* listRepr(BoxedList* self) {
LOCK_REGION(self->lock.asRead()); LOCK_REGION(self->lock.asRead());
// TODO highly inefficient with all the string copying // TODO highly inefficient with all the string copying
std::ostringstream os;
std::string O("");
llvm::raw_string_ostream os(O);
os << '['; os << '[';
for (int i = 0; i < self->size; i++) { for (int i = 0; i < self->size; i++) {
if (i > 0) if (i > 0)
...@@ -75,7 +78,7 @@ extern "C" Box* listRepr(BoxedList* self) { ...@@ -75,7 +78,7 @@ extern "C" Box* listRepr(BoxedList* self) {
os << s->s; os << s->s;
} }
os << ']'; os << ']';
return new BoxedString(os.str()); return boxString(os.str());
} }
extern "C" Box* listNonzero(BoxedList* self) { extern "C" Box* listNonzero(BoxedList* self) {
...@@ -282,7 +285,7 @@ extern "C" Box* listSetitemSlice(BoxedList* self, BoxedSlice* slice, Box* v) { ...@@ -282,7 +285,7 @@ extern "C" Box* listSetitemSlice(BoxedList* self, BoxedSlice* slice, Box* v) {
if (!v) { if (!v) {
v_size = 0; v_size = 0;
v_elts = NULL; v_elts = NULL;
} else if (isSubclass(v->cls, list_cls)) { } else if (v->cls == list_cls || isSubclass(v->cls, list_cls)) {
BoxedList* lv = static_cast<BoxedList*>(v); BoxedList* lv = static_cast<BoxedList*>(v);
v_size = lv->size; v_size = lv->size;
// If lv->size is 0, lv->elts->elts is garbage // If lv->size is 0, lv->elts->elts is garbage
...@@ -290,9 +293,9 @@ extern "C" Box* listSetitemSlice(BoxedList* self, BoxedSlice* slice, Box* v) { ...@@ -290,9 +293,9 @@ extern "C" Box* listSetitemSlice(BoxedList* self, BoxedSlice* slice, Box* v) {
v_elts = lv->elts->elts; v_elts = lv->elts->elts;
else else
v_elts = NULL; v_elts = NULL;
} else if (isSubclass(v->cls, tuple_cls)) { } else if (v->cls == tuple_cls || isSubclass(v->cls, tuple_cls)) {
BoxedTuple* tv = static_cast<BoxedTuple*>(v); BoxedTuple* tv = static_cast<BoxedTuple*>(v);
v_size = tv->elts.size(); v_size = tv->size();
v_elts = &tv->elts[0]; v_elts = &tv->elts[0];
} else { } else {
RELEASE_ASSERT(0, "unsupported type for list slice assignment: '%s'", getTypeName(v)); RELEASE_ASSERT(0, "unsupported type for list slice assignment: '%s'", getTypeName(v));
...@@ -517,7 +520,7 @@ void listSort(BoxedList* self, Box* cmp, Box* key, Box* reverse) { ...@@ -517,7 +520,7 @@ void listSort(BoxedList* self, Box* cmp, Box* key, Box* reverse) {
// original object. // original object.
// TODO we could potentially make this faster by copying the CPython approach of // TODO we could potentially make this faster by copying the CPython approach of
// creating special sortwrapper objects that compare only based on the key. // creating special sortwrapper objects that compare only based on the key.
Box* new_obj = new BoxedTuple({ key_val, boxInt(i), *obj_loc }); Box* new_obj = BoxedTuple::create({ key_val, boxInt(i), *obj_loc });
*obj_loc = new_obj; *obj_loc = new_obj;
num_keys_added++; num_keys_added++;
...@@ -629,7 +632,7 @@ Box* listIndex(BoxedList* self, Box* elt, BoxedInt* _start, Box** args) { ...@@ -629,7 +632,7 @@ Box* listIndex(BoxedList* self, Box* elt, BoxedInt* _start, Box** args) {
} }
BoxedString* tostr = static_cast<BoxedString*>(repr(elt)); BoxedString* tostr = static_cast<BoxedString*>(repr(elt));
raiseExcHelper(ValueError, "%s is not in list", tostr->s.c_str()); raiseExcHelper(ValueError, "%s is not in list", tostr->data());
} }
Box* listRemove(BoxedList* self, Box* elt) { Box* listRemove(BoxedList* self, Box* elt) {
......
...@@ -268,7 +268,7 @@ extern "C" PyAPI_FUNC(PyObject*) _PyLong_Format(PyObject* aa, int base, int addL ...@@ -268,7 +268,7 @@ extern "C" PyAPI_FUNC(PyObject*) _PyLong_Format(PyObject* aa, int base, int addL
os << "L"; os << "L";
os.flush(); os.flush();
auto rtn = new BoxedString(std::move(str)); auto rtn = boxString(str);
free(buf); free(buf);
return rtn; return rtn;
} }
...@@ -451,7 +451,7 @@ BoxedLong* _longNew(Box* val, Box* _base) { ...@@ -451,7 +451,7 @@ BoxedLong* _longNew(Box* val, Box* _base) {
raiseExcHelper(TypeError, "long() arg2 must be >= 2 and <= 36"); raiseExcHelper(TypeError, "long() arg2 must be >= 2 and <= 36");
} }
int r = mpz_init_set_str(rtn->n, s->s.c_str(), base); int r = mpz_init_set_str(rtn->n, s->data(), base);
RELEASE_ASSERT(r == 0, ""); RELEASE_ASSERT(r == 0, "");
} else { } else {
if (isSubclass(val->cls, long_cls)) { if (isSubclass(val->cls, long_cls)) {
...@@ -936,7 +936,7 @@ extern "C" Box* longDivmod(BoxedLong* lhs, Box* _rhs) { ...@@ -936,7 +936,7 @@ extern "C" Box* longDivmod(BoxedLong* lhs, Box* _rhs) {
mpz_init(q->n); mpz_init(q->n);
mpz_init(r->n); mpz_init(r->n);
mpz_fdiv_qr(q->n, r->n, lhs->n, rhs->n); mpz_fdiv_qr(q->n, r->n, lhs->n, rhs->n);
return new BoxedTuple({ q, r }); return BoxedTuple::create({ q, r });
} else if (isSubclass(_rhs->cls, int_cls)) { } else if (isSubclass(_rhs->cls, int_cls)) {
BoxedInt* rhs = static_cast<BoxedInt*>(_rhs); BoxedInt* rhs = static_cast<BoxedInt*>(_rhs);
...@@ -948,7 +948,7 @@ extern "C" Box* longDivmod(BoxedLong* lhs, Box* _rhs) { ...@@ -948,7 +948,7 @@ extern "C" Box* longDivmod(BoxedLong* lhs, Box* _rhs) {
mpz_init(q->n); mpz_init(q->n);
mpz_init_set_si(r->n, rhs->n); mpz_init_set_si(r->n, rhs->n);
mpz_fdiv_qr(q->n, r->n, lhs->n, r->n); mpz_fdiv_qr(q->n, r->n, lhs->n, r->n);
return new BoxedTuple({ q, r }); return BoxedTuple::create({ q, r });
} else { } else {
return NotImplemented; return NotImplemented;
} }
......
...@@ -128,8 +128,9 @@ static Box* (*callattrInternal3)(Box*, const std::string*, LookupScope, CallRewr ...@@ -128,8 +128,9 @@ static Box* (*callattrInternal3)(Box*, const std::string*, LookupScope, CallRewr
size_t PyHasher::operator()(Box* b) const { size_t PyHasher::operator()(Box* b) const {
if (b->cls == str_cls) { if (b->cls == str_cls) {
StringHash<std::string> H; StringHash<char> H;
return H(static_cast<BoxedString*>(b)->s); auto s = static_cast<BoxedString*>(b);
return H(s->data(), s->size());
} }
BoxedInt* i = hash(b); BoxedInt* i = hash(b);
...@@ -218,7 +219,7 @@ extern "C" bool isSubclass(BoxedClass* child, BoxedClass* parent) { ...@@ -218,7 +219,7 @@ extern "C" bool isSubclass(BoxedClass* child, BoxedClass* parent) {
extern "C" void assertFail(BoxedModule* inModule, Box* msg) { extern "C" void assertFail(BoxedModule* inModule, Box* msg) {
if (msg) { if (msg) {
BoxedString* tostr = str(msg); BoxedString* tostr = str(msg);
raiseExcHelper(AssertionError, "%s", tostr->s.c_str()); raiseExcHelper(AssertionError, "%s", tostr->data());
} else { } else {
raiseExcHelper(AssertionError, ""); raiseExcHelper(AssertionError, "");
} }
...@@ -272,7 +273,7 @@ static void _checkUnpackingLength(i64 expected, i64 given) { ...@@ -272,7 +273,7 @@ static void _checkUnpackingLength(i64 expected, i64 given) {
extern "C" Box** unpackIntoArray(Box* obj, int64_t expected_size) { extern "C" Box** unpackIntoArray(Box* obj, int64_t expected_size) {
if (obj->cls == tuple_cls) { if (obj->cls == tuple_cls) {
BoxedTuple* t = static_cast<BoxedTuple*>(obj); BoxedTuple* t = static_cast<BoxedTuple*>(obj);
_checkUnpackingLength(expected_size, t->elts.size()); _checkUnpackingLength(expected_size, t->size());
return &t->elts[0]; return &t->elts[0];
} }
...@@ -413,7 +414,7 @@ BoxedHeapClass::BoxedHeapClass(BoxedClass* base, gcvisit_func gc_visit, int attr ...@@ -413,7 +414,7 @@ BoxedHeapClass::BoxedHeapClass(BoxedClass* base, gcvisit_func gc_visit, int attr
if (!ht_name) if (!ht_name)
assert(str_cls == NULL); assert(str_cls == NULL);
else else
tp_name = ht_name->s.c_str(); tp_name = ht_name->data();
memset(&as_number, 0, sizeof(as_number)); memset(&as_number, 0, sizeof(as_number));
memset(&as_mapping, 0, sizeof(as_mapping)); memset(&as_mapping, 0, sizeof(as_mapping));
...@@ -425,7 +426,7 @@ BoxedHeapClass* BoxedHeapClass::create(BoxedClass* metaclass, BoxedClass* base, ...@@ -425,7 +426,7 @@ BoxedHeapClass* BoxedHeapClass::create(BoxedClass* metaclass, BoxedClass* base,
int weaklist_offset, int instance_size, bool is_user_defined, int weaklist_offset, int instance_size, bool is_user_defined,
const std::string& name) { const std::string& name) {
return create(metaclass, base, gc_visit, attrs_offset, weaklist_offset, instance_size, is_user_defined, return create(metaclass, base, gc_visit, attrs_offset, weaklist_offset, instance_size, is_user_defined,
new BoxedString(name), NULL); static_cast<BoxedString*>(boxString(name)), NULL);
} }
BoxedHeapClass* BoxedHeapClass::create(BoxedClass* metaclass, BoxedClass* base, gcvisit_func gc_visit, int attrs_offset, BoxedHeapClass* BoxedHeapClass::create(BoxedClass* metaclass, BoxedClass* base, gcvisit_func gc_visit, int attrs_offset,
...@@ -458,7 +459,7 @@ std::string getFullNameOfClass(BoxedClass* cls) { ...@@ -458,7 +459,7 @@ std::string getFullNameOfClass(BoxedClass* cls) {
BoxedString* module = static_cast<BoxedString*>(b); BoxedString* module = static_cast<BoxedString*>(b);
return module->s + "." + cls->tp_name; return (llvm::Twine(module->s) + "." + cls->tp_name).str();
} }
std::string getFullTypeName(Box* o) { std::string getFullTypeName(Box* o) {
...@@ -782,7 +783,7 @@ Box* typeLookup(BoxedClass* cls, const std::string& attr, GetattrRewriteArgs* re ...@@ -782,7 +783,7 @@ Box* typeLookup(BoxedClass* cls, const std::string& attr, GetattrRewriteArgs* re
// address. // address.
obj_saved->addAttrGuard(offsetof(BoxedClass, tp_mro), (intptr_t)mro); obj_saved->addAttrGuard(offsetof(BoxedClass, tp_mro), (intptr_t)mro);
for (auto base : mro->elts) { for (auto base : *mro) {
rewrite_args->out_success = false; rewrite_args->out_success = false;
if (base == cls) { if (base == cls) {
// Small optimization: don't have to load the class again since it was given to us in // Small optimization: don't have to load the class again since it was given to us in
...@@ -801,7 +802,7 @@ Box* typeLookup(BoxedClass* cls, const std::string& attr, GetattrRewriteArgs* re ...@@ -801,7 +802,7 @@ Box* typeLookup(BoxedClass* cls, const std::string& attr, GetattrRewriteArgs* re
} else { } else {
assert(cls->tp_mro); assert(cls->tp_mro);
assert(cls->tp_mro->cls == tuple_cls); assert(cls->tp_mro->cls == tuple_cls);
for (auto b : static_cast<BoxedTuple*>(cls->tp_mro)->elts) { for (auto b : *static_cast<BoxedTuple*>(cls->tp_mro)) {
val = b->getattr(attr, NULL); val = b->getattr(attr, NULL);
if (val) if (val)
return val; return val;
...@@ -952,7 +953,7 @@ Box* descriptorClsSpecialCases(GetattrRewriteArgs* rewrite_args, BoxedClass* cls ...@@ -952,7 +953,7 @@ Box* descriptorClsSpecialCases(GetattrRewriteArgs* rewrite_args, BoxedClass* cls
Box* boxChar(char c) { Box* boxChar(char c) {
char d[1]; char d[1];
d[0] = c; d[0] = c;
return new BoxedString(std::string(d, 1)); return boxStringRef(llvm::StringRef(d, 1));
} }
static Box* noneIfNull(Box* b) { static Box* noneIfNull(Box* b) {
...@@ -967,12 +968,12 @@ static Box* boxStringOrNone(const char* s) { ...@@ -967,12 +968,12 @@ static Box* boxStringOrNone(const char* s) {
if (s == NULL) { if (s == NULL) {
return None; return None;
} else { } else {
return boxString(std::string(s)); return boxStrConstant(s);
} }
} }
static Box* boxStringFromCharPtr(const char* s) { static Box* boxStringFromCharPtr(const char* s) {
return boxString(std::string(s)); return boxStrConstant(s);
} }
Box* dataDescriptorInstanceSpecialCases(GetattrRewriteArgs* rewrite_args, const std::string& attr_name, Box* obj, Box* dataDescriptorInstanceSpecialCases(GetattrRewriteArgs* rewrite_args, const std::string& attr_name, Box* obj,
...@@ -1100,7 +1101,7 @@ Box* dataDescriptorInstanceSpecialCases(GetattrRewriteArgs* rewrite_args, const ...@@ -1100,7 +1101,7 @@ Box* dataDescriptorInstanceSpecialCases(GetattrRewriteArgs* rewrite_args, const
rewrite_args = NULL; rewrite_args = NULL;
REWRITE_ABORTED(""); REWRITE_ABORTED("");
char* rtn = reinterpret_cast<char*>((char*)obj + member_desc->offset); char* rtn = reinterpret_cast<char*>((char*)obj + member_desc->offset);
return boxString(std::string(rtn)); return boxStringRef(llvm::StringRef(rtn));
} }
default: default:
...@@ -1164,7 +1165,7 @@ Box* getattrInternalEx(Box* obj, const std::string& attr, GetattrRewriteArgs* re ...@@ -1164,7 +1165,7 @@ Box* getattrInternalEx(Box* obj, const std::string& attr, GetattrRewriteArgs* re
if (!cls_only) { if (!cls_only) {
BoxedClass* cls = obj->cls; BoxedClass* cls = obj->cls;
if (obj->cls->tp_getattro && obj->cls->tp_getattro != PyObject_GenericGetAttr) { if (obj->cls->tp_getattro && obj->cls->tp_getattro != PyObject_GenericGetAttr) {
Box* r = obj->cls->tp_getattro(obj, new BoxedString(attr)); Box* r = obj->cls->tp_getattro(obj, boxString(attr));
if (!r) if (!r)
throwCAPIException(); throwCAPIException();
return r; return r;
...@@ -2205,7 +2206,7 @@ extern "C" void dump(void* p) { ...@@ -2205,7 +2206,7 @@ extern "C" void dump(void* p) {
if (cls->tp_mro && cls->tp_mro->cls == tuple_cls) { if (cls->tp_mro && cls->tp_mro->cls == tuple_cls) {
bool first = true; bool first = true;
for (auto b : static_cast<BoxedTuple*>(cls->tp_mro)->elts) { for (auto b : *static_cast<BoxedTuple*>(cls->tp_mro)) {
if (!first) if (!first)
printf(" ->"); printf(" ->");
first = false; first = false;
...@@ -2216,11 +2217,11 @@ extern "C" void dump(void* p) { ...@@ -2216,11 +2217,11 @@ extern "C" void dump(void* p) {
} }
if (isSubclass(b->cls, str_cls)) { if (isSubclass(b->cls, str_cls)) {
printf("String value: %s\n", static_cast<BoxedString*>(b)->s.c_str()); printf("String value: %s\n", static_cast<BoxedString*>(b)->data());
} }
if (isSubclass(b->cls, tuple_cls)) { if (isSubclass(b->cls, tuple_cls)) {
printf("%ld elements\n", static_cast<BoxedTuple*>(b)->elts.size()); printf("%ld elements\n", static_cast<BoxedTuple*>(b)->size());
} }
if (isSubclass(b->cls, int_cls)) { if (isSubclass(b->cls, int_cls)) {
...@@ -2760,7 +2761,7 @@ Box* callFunc(BoxedFunctionBase* func, CallRewriteArgs* rewrite_args, ArgPassSpe ...@@ -2760,7 +2761,7 @@ Box* callFunc(BoxedFunctionBase* func, CallRewriteArgs* rewrite_args, ArgPassSpe
rewrite_args->args->setAttr((varargs_idx - 3) * sizeof(Box*), emptyTupleConst); rewrite_args->args->setAttr((varargs_idx - 3) * sizeof(Box*), emptyTupleConst);
} }
Box* ovarargs = new BoxedTuple(BoxedTuple::GCVector(unused_positional.begin(), unused_positional.end())); Box* ovarargs = BoxedTuple::create(unused_positional.size(), &unused_positional[0]);
getArg(varargs_idx, oarg1, oarg2, oarg3, oargs) = ovarargs; getArg(varargs_idx, oarg1, oarg2, oarg3, oargs) = ovarargs;
} else if (unused_positional.size()) { } else if (unused_positional.size()) {
raiseExcHelper(TypeError, "%s() takes at most %d argument%s (%d given)", getFunctionName(f).c_str(), raiseExcHelper(TypeError, "%s() takes at most %d argument%s (%d given)", getFunctionName(f).c_str(),
...@@ -2851,7 +2852,7 @@ Box* callFunc(BoxedFunctionBase* func, CallRewriteArgs* rewrite_args, ArgPassSpe ...@@ -2851,7 +2852,7 @@ Box* callFunc(BoxedFunctionBase* func, CallRewriteArgs* rewrite_args, ArgPassSpe
Box*& v = okwargs->d[p.first]; Box*& v = okwargs->d[p.first];
if (v) { if (v) {
raiseExcHelper(TypeError, "%s() got multiple values for keyword argument '%s'", raiseExcHelper(TypeError, "%s() got multiple values for keyword argument '%s'",
getFunctionName(f).c_str(), s->s.c_str()); getFunctionName(f).c_str(), s->data());
} }
v = p.second; v = p.second;
} }
...@@ -3840,14 +3841,15 @@ Box* typeNew(Box* _cls, Box* arg1, Box* arg2, Box** _args) { ...@@ -3840,14 +3841,15 @@ Box* typeNew(Box* _cls, Box* arg1, Box* arg2, Box** _args) {
RELEASE_ASSERT(arg1->cls == str_cls, ""); RELEASE_ASSERT(arg1->cls == str_cls, "");
BoxedString* name = static_cast<BoxedString*>(arg1); BoxedString* name = static_cast<BoxedString*>(arg1);
if (bases->elts.size() == 0) { if (bases->size() == 0) {
bases = new BoxedTuple({ object_cls }); bases = BoxedTuple::create({ object_cls });
} }
// Ported from CPython: // Ported from CPython:
int nbases = bases->elts.size(); int nbases = bases->size();
BoxedClass* winner = metatype; BoxedClass* winner = metatype;
for (auto tmp : bases->elts) {
for (auto tmp : *bases) {
auto tmptype = tmp->cls; auto tmptype = tmp->cls;
if (tmptype == classobj_cls) if (tmptype == classobj_cls)
continue; continue;
...@@ -3926,7 +3928,7 @@ Box* typeNew(Box* _cls, Box* arg1, Box* arg2, Box** _args) { ...@@ -3926,7 +3928,7 @@ Box* typeNew(Box* _cls, Box* arg1, Box* arg2, Box** _args) {
made->tp_alloc = PyType_GenericAlloc; made->tp_alloc = PyType_GenericAlloc;
assert(!made->simple_destructor); assert(!made->simple_destructor);
for (auto b : bases->elts) { for (auto b : *bases) {
if (!isSubclass(b->cls, type_cls)) if (!isSubclass(b->cls, type_cls))
continue; continue;
BoxedClass* b_cls = static_cast<BoxedClass*>(b); BoxedClass* b_cls = static_cast<BoxedClass*>(b);
...@@ -4228,7 +4230,7 @@ Box* typeCallInternal(BoxedFunctionBase* f, CallRewriteArgs* rewrite_args, ArgPa ...@@ -4228,7 +4230,7 @@ Box* typeCallInternal(BoxedFunctionBase* f, CallRewriteArgs* rewrite_args, ArgPa
Box* typeCall(Box* obj, BoxedTuple* vararg, BoxedDict* kwargs) { Box* typeCall(Box* obj, BoxedTuple* vararg, BoxedDict* kwargs) {
assert(vararg->cls == tuple_cls); assert(vararg->cls == tuple_cls);
int n = vararg->elts.size(); int n = vararg->size();
int args_to_pass = n + 2; // 1 for obj, 1 for kwargs int args_to_pass = n + 2; // 1 for obj, 1 for kwargs
Box** args = NULL; Box** args = NULL;
...@@ -4371,7 +4373,7 @@ extern "C" Box* importStar(Box* _from_module, BoxedModule* to_module) { ...@@ -4371,7 +4373,7 @@ extern "C" Box* importStar(Box* _from_module, BoxedModule* to_module) {
Box* attr_value = from_module->getattr(casted_attr_name->s); Box* attr_value = from_module->getattr(casted_attr_name->s);
if (!attr_value) if (!attr_value)
raiseExcHelper(AttributeError, "'module' object has no attribute '%s'", casted_attr_name->s.c_str()); raiseExcHelper(AttributeError, "'module' object has no attribute '%s'", casted_attr_name->data());
to_module->setattr(casted_attr_name->s, attr_value, NULL); to_module->setattr(casted_attr_name->s, attr_value, NULL);
} }
......
...@@ -14,7 +14,7 @@ ...@@ -14,7 +14,7 @@
#include "runtime/set.h" #include "runtime/set.h"
#include <sstream> #include <llvm/Support/raw_ostream.h>
#include "gc/collector.h" #include "gc/collector.h"
#include "runtime/objmodel.h" #include "runtime/objmodel.h"
...@@ -97,7 +97,8 @@ Box* setNew(Box* _cls, Box* container) { ...@@ -97,7 +97,8 @@ Box* setNew(Box* _cls, Box* container) {
} }
static Box* _setRepr(BoxedSet* self, const char* type_name) { static Box* _setRepr(BoxedSet* self, const char* type_name) {
std::ostringstream os(""); std::string O("");
llvm::raw_string_ostream os(O);
os << type_name << "(["; os << type_name << "([";
bool first = true; bool first = true;
...@@ -232,7 +233,7 @@ Box* setUpdate(BoxedSet* self, BoxedTuple* args) { ...@@ -232,7 +233,7 @@ Box* setUpdate(BoxedSet* self, BoxedTuple* args) {
assert(self->cls == set_cls); assert(self->cls == set_cls);
assert(args->cls == tuple_cls); assert(args->cls == tuple_cls);
for (auto l : args->elts) { for (auto l : *args) {
if (l->cls == set_cls) { if (l->cls == set_cls) {
BoxedSet* s2 = static_cast<BoxedSet*>(l); BoxedSet* s2 = static_cast<BoxedSet*>(l);
self->s.insert(s2->s.begin(), s2->s.end()); self->s.insert(s2->s.begin(), s2->s.end());
......
This diff is collapsed.
...@@ -51,7 +51,7 @@ public: ...@@ -51,7 +51,7 @@ public:
} }
}; };
static const std::string class_str("__class__"); static const char* class_str = "__class__";
Box* superGetattribute(Box* _s, Box* _attr) { Box* superGetattribute(Box* _s, Box* _attr) {
RELEASE_ASSERT(_s->cls == super_cls, ""); RELEASE_ASSERT(_s->cls == super_cls, "");
...@@ -101,7 +101,7 @@ Box* superGetattribute(Box* _s, Box* _attr) { ...@@ -101,7 +101,7 @@ Box* superGetattribute(Box* _s, Box* _attr) {
continue; continue;
res = PyDict_GetItem(dict, name); res = PyDict_GetItem(dict, name);
#endif #endif
res = tmp->getattr(attr->s); res = tmp->getattr(std::string(attr->s));
if (res != NULL) { if (res != NULL) {
// Pyston change: // Pyston change:
...@@ -128,7 +128,7 @@ Box* superGetattribute(Box* _s, Box* _attr) { ...@@ -128,7 +128,7 @@ Box* superGetattribute(Box* _s, Box* _attr) {
} }
} }
Box* r = typeLookup(s->cls, attr->s, NULL); Box* r = typeLookup(s->cls, std::string(attr->s), NULL);
// TODO implement this // TODO implement this
RELEASE_ASSERT(r, "should call the equivalent of objectGetattr here"); RELEASE_ASSERT(r, "should call the equivalent of objectGetattr here");
return processDescriptor(r, s, s->cls); return processDescriptor(r, s, s->cls);
...@@ -139,10 +139,11 @@ Box* superRepr(Box* _s) { ...@@ -139,10 +139,11 @@ Box* superRepr(Box* _s) {
BoxedSuper* s = static_cast<BoxedSuper*>(_s); BoxedSuper* s = static_cast<BoxedSuper*>(_s);
if (s->obj_type) { if (s->obj_type) {
return boxString("<super: <class '" + std::string(s->type ? getNameOfClass(s->type) : "NULL") + "'>, <" return boxStringTwine(llvm::Twine("<super: <class '") + (s->type ? getNameOfClass(s->type) : "NULL") + "'>, <"
+ std::string(getNameOfClass(s->obj_type)) + " object>>"); + getNameOfClass(s->obj_type) + " object>>");
} else { } else {
return boxString("<super: <class '" + std::string(s->type ? getNameOfClass(s->type) : "NULL") + "'>, <NULL>>"); return boxStringTwine(llvm::Twine("<super: <class '") + (s->type ? getNameOfClass(s->type) : "NULL")
+ "'>, <NULL>>");
} }
} }
......
...@@ -98,7 +98,7 @@ Box* BoxedTraceback::getLines(Box* b) { ...@@ -98,7 +98,7 @@ Box* BoxedTraceback::getLines(Box* b) {
BoxedList* lines = new BoxedList(); BoxedList* lines = new BoxedList();
lines->ensure(tb->lines.size()); lines->ensure(tb->lines.size());
for (auto line : tb->lines) { for (auto line : tb->lines) {
auto l = new BoxedTuple({ boxString(line->file), boxString(line->func), boxInt(line->line) }); auto l = BoxedTuple::create({ boxString(line->file), boxString(line->func), boxInt(line->line) });
listAppendInternal(lines, l); listAppendInternal(lines, l);
} }
tb->py_lines = lines; tb->py_lines = lines;
......
...@@ -15,7 +15,8 @@ ...@@ -15,7 +15,8 @@
#include "runtime/tuple.h" #include "runtime/tuple.h"
#include <algorithm> #include <algorithm>
#include <sstream>
#include "llvm/Support/raw_ostream.h"
#include "core/ast.h" #include "core/ast.h"
#include "core/common.h" #include "core/common.h"
...@@ -29,13 +30,12 @@ ...@@ -29,13 +30,12 @@
namespace pyston { namespace pyston {
extern "C" Box* createTuple(int64_t nelts, Box** elts) { extern "C" Box* createTuple(int64_t nelts, Box** elts) {
BoxedTuple::GCVector velts(elts, elts + nelts); return BoxedTuple::create(nelts, elts);
return new BoxedTuple(std::move(velts));
} }
Box* _tupleSlice(BoxedTuple* self, i64 start, i64 stop, i64 step, i64 length) { Box* _tupleSlice(BoxedTuple* self, i64 start, i64 stop, i64 step, i64 length) {
i64 size = self->elts.size(); i64 size = self->size();
assert(step != 0); assert(step != 0);
if (step > 0) { if (step > 0) {
assert(0 <= start); assert(0 <= start);
...@@ -45,15 +45,15 @@ Box* _tupleSlice(BoxedTuple* self, i64 start, i64 stop, i64 step, i64 length) { ...@@ -45,15 +45,15 @@ Box* _tupleSlice(BoxedTuple* self, i64 start, i64 stop, i64 step, i64 length) {
assert(-1 <= stop); assert(-1 <= stop);
} }
// FIXME: No need to initialize with 0. // FIXME: No need to initialize with NULL, since we're going to fill it in
BoxedTuple::GCVector velts(length, 0); auto rtn = BoxedTuple::create(length);
if (length > 0) if (length > 0)
copySlice(&velts[0], &self->elts[0], start, step, length); copySlice(&rtn->elts[0], &self->elts[0], start, step, length);
return new BoxedTuple(std::move(velts)); return rtn;
} }
Box* tupleGetitemUnboxed(BoxedTuple* self, i64 n) { Box* tupleGetitemUnboxed(BoxedTuple* self, i64 n) {
i64 size = self->elts.size(); i64 size = self->size();
if (n < 0) if (n < 0)
n = size + n; n = size + n;
...@@ -89,7 +89,7 @@ Box* tupleGetitemSlice(BoxedTuple* self, BoxedSlice* slice) { ...@@ -89,7 +89,7 @@ Box* tupleGetitemSlice(BoxedTuple* self, BoxedSlice* slice) {
assert(slice->cls == slice_cls); assert(slice->cls == slice_cls);
i64 start, stop, step, length; i64 start, stop, step, length;
parseSlice(slice, self->elts.size(), &start, &stop, &step, &length); parseSlice(slice, self->size(), &start, &stop, &step, &length);
return _tupleSlice(self, start, stop, step, length); return _tupleSlice(self, start, stop, step, length);
} }
...@@ -97,7 +97,7 @@ extern "C" PyObject* PyTuple_GetSlice(PyObject* p, Py_ssize_t low, Py_ssize_t hi ...@@ -97,7 +97,7 @@ extern "C" PyObject* PyTuple_GetSlice(PyObject* p, Py_ssize_t low, Py_ssize_t hi
RELEASE_ASSERT(isSubclass(p->cls, tuple_cls), ""); RELEASE_ASSERT(isSubclass(p->cls, tuple_cls), "");
BoxedTuple* t = static_cast<BoxedTuple*>(p); BoxedTuple* t = static_cast<BoxedTuple*>(p);
Py_ssize_t n = t->elts.size(); Py_ssize_t n = t->size();
if (low < 0) if (low < 0)
low = 0; low = 0;
if (high > n) if (high > n)
...@@ -108,7 +108,39 @@ extern "C" PyObject* PyTuple_GetSlice(PyObject* p, Py_ssize_t low, Py_ssize_t hi ...@@ -108,7 +108,39 @@ extern "C" PyObject* PyTuple_GetSlice(PyObject* p, Py_ssize_t low, Py_ssize_t hi
if (low == 0 && high == n) if (low == 0 && high == n)
return p; return p;
return new BoxedTuple(BoxedTuple::GCVector(&t->elts[low], &t->elts[high])); return BoxedTuple::create(high - low, &t->elts[low]);
}
extern "C" int _PyTuple_Resize(PyObject** pv, Py_ssize_t newsize) noexcept {
// This is only allowed to be called when there is only one user of the tuple (ie a refcount of 1 in CPython)
assert(pv);
return BoxedTuple::Resize((BoxedTuple**)pv, newsize);
}
int BoxedTuple::Resize(BoxedTuple** pv, size_t newsize) noexcept {
assert(isSubclass((*pv)->cls, tuple_cls));
BoxedTuple* t = static_cast<BoxedTuple*>(*pv);
if (newsize == t->size())
return 0;
if (newsize < t->size()) {
// XXX resize the box (by reallocating) smaller if it makes sense
t->nelts = newsize;
return 0;
}
BoxedTuple* resized;
if (t->cls == tuple_cls)
resized = new (newsize) BoxedTuple(newsize); // we want an uninitialized tuple, but this will memset it with 0.
else
resized = new (t->cls, newsize) BoxedTuple(newsize); // we need an uninitialized string, but this will memset
memmove(resized->elts, t->elts, t->size());
*pv = resized;
return 0;
} }
Box* tupleGetitem(BoxedTuple* self, Box* slice) { Box* tupleGetitem(BoxedTuple* self, Box* slice) {
...@@ -128,10 +160,11 @@ Box* tupleAdd(BoxedTuple* self, Box* rhs) { ...@@ -128,10 +160,11 @@ Box* tupleAdd(BoxedTuple* self, Box* rhs) {
} }
BoxedTuple* _rhs = static_cast<BoxedTuple*>(rhs); BoxedTuple* _rhs = static_cast<BoxedTuple*>(rhs);
BoxedTuple::GCVector velts;
velts.insert(velts.end(), self->elts.begin(), self->elts.end()); BoxedTuple* rtn = BoxedTuple::create(self->size() + _rhs->size());
velts.insert(velts.end(), _rhs->elts.begin(), _rhs->elts.end()); memmove(&rtn->elts[0], &self->elts[0], self->size() * sizeof(Box*));
return new BoxedTuple(std::move(velts)); memmove(&rtn->elts[self->size()], &_rhs->elts[0], _rhs->size() * sizeof(Box*));
return rtn;
} }
Box* tupleMul(BoxedTuple* self, Box* rhs) { Box* tupleMul(BoxedTuple* self, Box* rhs) {
...@@ -140,7 +173,7 @@ Box* tupleMul(BoxedTuple* self, Box* rhs) { ...@@ -140,7 +173,7 @@ Box* tupleMul(BoxedTuple* self, Box* rhs) {
} }
int n = static_cast<BoxedInt*>(rhs)->n; int n = static_cast<BoxedInt*>(rhs)->n;
int s = self->elts.size(); int s = self->size();
if (n < 0) if (n < 0)
n = 0; n = 0;
...@@ -148,33 +181,34 @@ Box* tupleMul(BoxedTuple* self, Box* rhs) { ...@@ -148,33 +181,34 @@ Box* tupleMul(BoxedTuple* self, Box* rhs) {
if (s == 0 || n == 1) { if (s == 0 || n == 1) {
return self; return self;
} else { } else {
BoxedTuple::GCVector velts(n * s); BoxedTuple* rtn = BoxedTuple::create(n * s);
auto iter = velts.begin(); int rtn_i = 0;
for (int i = 0; i < n; ++i) { for (int i = 0; i < n; ++i) {
std::copy(self->elts.begin(), self->elts.end(), iter); memmove(&rtn->elts[rtn_i], &self->elts[0], sizeof(Box*) * s);
iter += s; rtn_i += s;
} }
return new BoxedTuple(std::move(velts)); return rtn;
} }
} }
Box* tupleLen(BoxedTuple* t) { Box* tupleLen(BoxedTuple* t) {
assert(isSubclass(t->cls, tuple_cls)); assert(isSubclass(t->cls, tuple_cls));
return boxInt(t->elts.size()); return boxInt(t->size());
} }
extern "C" Py_ssize_t PyTuple_Size(PyObject* op) noexcept { extern "C" Py_ssize_t PyTuple_Size(PyObject* op) noexcept {
RELEASE_ASSERT(PyTuple_Check(op), ""); RELEASE_ASSERT(PyTuple_Check(op), "");
return static_cast<BoxedTuple*>(op)->elts.size(); return static_cast<BoxedTuple*>(op)->size();
} }
Box* tupleRepr(BoxedTuple* t) { Box* tupleRepr(BoxedTuple* t) {
assert(isSubclass(t->cls, tuple_cls)); assert(isSubclass(t->cls, tuple_cls));
std::ostringstream os(""); std::string O("");
llvm::raw_string_ostream os(O);
os << "("; os << "(";
int n = t->elts.size(); int n = t->size();
for (int i = 0; i < n; i++) { for (int i = 0; i < n; i++) {
if (i) if (i)
os << ", "; os << ", ";
...@@ -190,8 +224,8 @@ Box* tupleRepr(BoxedTuple* t) { ...@@ -190,8 +224,8 @@ Box* tupleRepr(BoxedTuple* t) {
} }
Box* _tupleCmp(BoxedTuple* lhs, BoxedTuple* rhs, AST_TYPE::AST_TYPE op_type) { Box* _tupleCmp(BoxedTuple* lhs, BoxedTuple* rhs, AST_TYPE::AST_TYPE op_type) {
int lsz = lhs->elts.size(); int lsz = lhs->size();
int rsz = rhs->elts.size(); int rsz = rhs->size();
bool is_order bool is_order
= (op_type == AST_TYPE::Lt || op_type == AST_TYPE::LtE || op_type == AST_TYPE::Gt || op_type == AST_TYPE::GtE); = (op_type == AST_TYPE::Lt || op_type == AST_TYPE::LtE || op_type == AST_TYPE::Gt || op_type == AST_TYPE::GtE);
...@@ -274,11 +308,11 @@ Box* tupleNe(BoxedTuple* self, Box* rhs) { ...@@ -274,11 +308,11 @@ Box* tupleNe(BoxedTuple* self, Box* rhs) {
Box* tupleNonzero(BoxedTuple* self) { Box* tupleNonzero(BoxedTuple* self) {
RELEASE_ASSERT(isSubclass(self->cls, tuple_cls), ""); RELEASE_ASSERT(isSubclass(self->cls, tuple_cls), "");
return boxBool(self->elts.size() != 0); return boxBool(self->size() != 0);
} }
Box* tupleContains(BoxedTuple* self, Box* elt) { Box* tupleContains(BoxedTuple* self, Box* elt) {
int size = self->elts.size(); int size = self->size();
for (int i = 0; i < size; i++) { for (int i = 0; i < size; i++) {
Box* e = self->elts[i]; Box* e = self->elts[i];
Box* cmp = compareInternal(e, elt, AST_TYPE::Eq, NULL); Box* cmp = compareInternal(e, elt, AST_TYPE::Eq, NULL);
...@@ -290,7 +324,7 @@ Box* tupleContains(BoxedTuple* self, Box* elt) { ...@@ -290,7 +324,7 @@ Box* tupleContains(BoxedTuple* self, Box* elt) {
} }
Box* tupleIndex(BoxedTuple* self, Box* elt) { Box* tupleIndex(BoxedTuple* self, Box* elt) {
int size = self->elts.size(); int size = self->size();
for (int i = 0; i < size; i++) { for (int i = 0; i < size; i++) {
Box* e = self->elts[i]; Box* e = self->elts[i];
Box* cmp = compareInternal(e, elt, AST_TYPE::Eq, NULL); Box* cmp = compareInternal(e, elt, AST_TYPE::Eq, NULL);
...@@ -306,7 +340,7 @@ Box* tupleHash(BoxedTuple* self) { ...@@ -306,7 +340,7 @@ Box* tupleHash(BoxedTuple* self) {
assert(isSubclass(self->cls, tuple_cls)); assert(isSubclass(self->cls, tuple_cls));
int64_t rtn = 3527539; int64_t rtn = 3527539;
for (Box* e : self->elts) { for (auto e : *self) {
BoxedInt* h = hash(e); BoxedInt* h = hash(e);
assert(isSubclass(h->cls, int_cls)); assert(isSubclass(h->cls, int_cls));
rtn ^= h->n + 0x9e3779b9 + (rtn << 6) + (rtn >> 2); rtn ^= h->n + 0x9e3779b9 + (rtn << 6) + (rtn >> 2);
...@@ -324,16 +358,14 @@ extern "C" Box* tupleNew(Box* _cls, BoxedTuple* args, BoxedDict* kwargs) { ...@@ -324,16 +358,14 @@ extern "C" Box* tupleNew(Box* _cls, BoxedTuple* args, BoxedDict* kwargs) {
raiseExcHelper(TypeError, "tuple.__new__(%s): %s is not a subtype of tuple", getNameOfClass(cls), raiseExcHelper(TypeError, "tuple.__new__(%s): %s is not a subtype of tuple", getNameOfClass(cls),
getNameOfClass(cls)); getNameOfClass(cls));
int args_sz = args->elts.size(); int args_sz = args->size();
int kwargs_sz = kwargs->d.size(); int kwargs_sz = kwargs->d.size();
if (args_sz + kwargs_sz > 1) if (args_sz + kwargs_sz > 1)
raiseExcHelper(TypeError, "tuple() takes at most 1 argument (%d given)", args_sz + kwargs_sz); raiseExcHelper(TypeError, "tuple() takes at most 1 argument (%d given)", args_sz + kwargs_sz);
BoxedTuple::GCVector velts;
Box* elements;
if (args_sz || kwargs_sz) { if (args_sz || kwargs_sz) {
Box* elements;
// if initializing from iterable argument, check common case positional args first // if initializing from iterable argument, check common case positional args first
if (args_sz) { if (args_sz) {
elements = args->elts[0]; elements = args->elts[0];
...@@ -345,21 +377,24 @@ extern "C" Box* tupleNew(Box* _cls, BoxedTuple* args, BoxedDict* kwargs) { ...@@ -345,21 +377,24 @@ extern "C" Box* tupleNew(Box* _cls, BoxedTuple* args, BoxedDict* kwargs) {
if (kw->s == "sequence") if (kw->s == "sequence")
elements = seq.second; elements = seq.second;
else else
raiseExcHelper(TypeError, "'%s' is an invalid keyword argument for this function", kw->s.c_str()); raiseExcHelper(TypeError, "'%s' is an invalid keyword argument for this function", kw->data());
} }
std::vector<Box*, StlCompatAllocator<Box*>> elts;
for (auto e : elements->pyElements()) for (auto e : elements->pyElements())
velts.push_back(e); elts.push_back(e);
}
return new (cls) BoxedTuple(std::move(velts)); return BoxedTuple::create(elts.size(), &elts[0], cls);
} else {
return BoxedTuple::create(0, cls);
}
} }
extern "C" int PyTuple_SetItem(PyObject* op, Py_ssize_t i, PyObject* newitem) noexcept { extern "C" int PyTuple_SetItem(PyObject* op, Py_ssize_t i, PyObject* newitem) noexcept {
RELEASE_ASSERT(PyTuple_Check(op), ""); RELEASE_ASSERT(PyTuple_Check(op), "");
BoxedTuple* t = static_cast<BoxedTuple*>(op); BoxedTuple* t = static_cast<BoxedTuple*>(op);
RELEASE_ASSERT(i >= 0 && i < t->elts.size(), ""); RELEASE_ASSERT(i >= 0 && i < t->size(), "");
t->elts[i] = newitem; t->elts[i] = newitem;
return 0; return 0;
} }
...@@ -386,7 +421,7 @@ extern "C" PyObject* PyTuple_Pack(Py_ssize_t n, ...) noexcept { ...@@ -386,7 +421,7 @@ extern "C" PyObject* PyTuple_Pack(Py_ssize_t n, ...) noexcept {
extern "C" PyObject* PyTuple_New(Py_ssize_t size) noexcept { extern "C" PyObject* PyTuple_New(Py_ssize_t size) noexcept {
RELEASE_ASSERT(size >= 0, ""); RELEASE_ASSERT(size >= 0, "");
return new BoxedTuple(BoxedTuple::GCVector(size, NULL)); return BoxedTuple::create(size);
} }
......
This diff is collapsed.
...@@ -16,6 +16,7 @@ ...@@ -16,6 +16,7 @@
#define PYSTON_RUNTIME_TYPES_H #define PYSTON_RUNTIME_TYPES_H
#include <llvm/ADT/StringMap.h> #include <llvm/ADT/StringMap.h>
#include <llvm/ADT/Twine.h>
#include <ucontext.h> #include <ucontext.h>
#include "Python.h" #include "Python.h"
...@@ -110,6 +111,9 @@ extern "C" Box* boxUnboundInstanceMethod(Box* func); ...@@ -110,6 +111,9 @@ extern "C" Box* boxUnboundInstanceMethod(Box* func);
extern "C" Box* boxStringPtr(const std::string* s); extern "C" Box* boxStringPtr(const std::string* s);
Box* boxString(const std::string& s); Box* boxString(const std::string& s);
Box* boxString(std::string&& s); Box* boxString(std::string&& s);
Box* boxStringRef(llvm::StringRef s);
Box* boxStringTwine(const llvm::Twine& s);
extern "C" BoxedString* boxStrConstant(const char* chars); extern "C" BoxedString* boxStrConstant(const char* chars);
extern "C" BoxedString* boxStrConstantSize(const char* chars, size_t n); extern "C" BoxedString* boxStrConstantSize(const char* chars, size_t n);
extern "C" Box* decodeUTF8StringPtr(const std::string* s); extern "C" Box* decodeUTF8StringPtr(const std::string* s);
...@@ -371,14 +375,34 @@ public: ...@@ -371,14 +375,34 @@ public:
class BoxedString : public Box { class BoxedString : public Box {
public: public:
// const std::basic_string<char, std::char_traits<char>, StlCompatAllocator<char> > s; llvm::StringRef s;
std::string s;
char* data() { return const_cast<char*>(s.data()); }
size_t size() { return s.size(); }
void* operator new(size_t size, size_t ssize) __attribute__((visibility("default"))) {
Box* rtn = static_cast<Box*>(gc_alloc(str_cls->tp_basicsize + ssize + 1, gc::GCKind::PYTHON));
rtn->cls = str_cls;
return rtn;
}
void* operator new(size_t size, BoxedClass* cls, size_t ssize) __attribute__((visibility("default"))) {
Box* rtn = static_cast<Box*>(cls->tp_alloc(cls, ssize + 1));
rtn->cls = cls;
return rtn;
}
// 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")));
BoxedString(std::string&& s) __attribute__((visibility("default"))); explicit BoxedString(size_t n, char c) __attribute__((visibility("default")));
BoxedString(const std::string& s) __attribute__((visibility("default"))); explicit BoxedString(llvm::StringRef s) __attribute__((visibility("default")));
explicit BoxedString(llvm::StringRef lhs, llvm::StringRef rhs) __attribute__((visibility("default")));
private:
// used only in ctors to give our llvm::StringRef the proper pointer
char* storage() { return (char*)this + cls->tp_basicsize; }
DEFAULT_CLASS_SIMPLE(str_cls); void* operator new(size_t size) = delete;
}; };
class BoxedUnicode : public Box { class BoxedUnicode : public Box {
...@@ -464,14 +488,65 @@ public: ...@@ -464,14 +488,65 @@ public:
class BoxedTuple : public Box { class BoxedTuple : public Box {
public: public:
typedef std::vector<Box*, StlCompatAllocator<Box*>> GCVector; typedef std::vector<Box*, StlCompatAllocator<Box*>> GCVector;
GCVector elts;
BoxedTuple(GCVector& elts) __attribute__((visibility("default"))) : elts(elts) {} Box** elts;
BoxedTuple(GCVector&& elts) __attribute__((visibility("default"))) : elts(std::move(elts)) {}
void* operator new(size_t size, size_t nelts) __attribute__((visibility("default"))) {
Box* rtn = static_cast<Box*>(gc_alloc(_PyObject_VAR_SIZE(tuple_cls, nelts + 1), gc::GCKind::PYTHON));
rtn->cls = tuple_cls;
return rtn;
}
void* operator new(size_t size, BoxedClass* cls, size_t nelts) __attribute__((visibility("default"))) {
Box* rtn = static_cast<Box*>(cls->tp_alloc(cls, nelts));
rtn->cls = cls;
return rtn;
}
static BoxedTuple* create(int64_t size) { return new (size) BoxedTuple(size); }
static BoxedTuple* create(int64_t nelts, Box** elts) {
BoxedTuple* rtn = new (nelts) BoxedTuple(nelts);
memmove(&rtn->elts[0], elts, sizeof(Box*) * nelts);
return rtn;
}
static BoxedTuple* create(std::initializer_list<Box*> members) { return new (members.size()) BoxedTuple(members); }
static BoxedTuple* create(int64_t size, BoxedClass* cls) { return new (cls, size) BoxedTuple(size); }
static BoxedTuple* create(int64_t nelts, Box** elts, BoxedClass* cls) {
BoxedTuple* rtn = new (cls, nelts) BoxedTuple(nelts);
memmove(&rtn->elts[0], elts, sizeof(Box*) * nelts);
return rtn;
}
static BoxedTuple* create(std::initializer_list<Box*> members, BoxedClass* cls) {
return new (cls, members.size()) BoxedTuple(members);
}
static int Resize(BoxedTuple** pt, size_t newsize) noexcept;
Box** begin() const { return &elts[0]; }
Box** end() const { return &elts[nelts]; }
size_t size() const { return nelts; }
DEFAULT_CLASS_SIMPLE(tuple_cls); private:
size_t nelts;
BoxedTuple(size_t size) : elts(reinterpret_cast<Box**>((char*)this + this->cls->tp_basicsize)), nelts(size) {
memset(elts, 0, sizeof(Box*) * size);
}
BoxedTuple(std::initializer_list<Box*>& members)
: elts(reinterpret_cast<Box**>((char*)this + this->cls->tp_basicsize)), nelts(members.size()) {
// by the time we make it here elts[] is big enough to contain members
Box** p = &elts[0];
for (auto b : members) {
*p++ = b;
}
}
}; };
extern "C" BoxedTuple* EmptyTuple; extern "C" BoxedTuple* EmptyTuple;
extern "C" BoxedString* EmptyString;
struct PyHasher { struct PyHasher {
size_t operator()(Box*) const; size_t operator()(Box*) const;
...@@ -735,4 +810,5 @@ extern Box* dict_descr; ...@@ -735,4 +810,5 @@ extern Box* dict_descr;
Box* codeForFunction(BoxedFunction*); Box* codeForFunction(BoxedFunction*);
} }
#endif #endif
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