Commit ef27d6cb authored by Kevin Modzelewski's avatar Kevin Modzelewski

Convert many runtime functions to take llvm::StringRef

Should hopefully cut down on allocations to pass around
'const std::string&' objects (since we don't always store things
as std::strings anymore), or to calls to strlen if we pass around
const char*s.

Haven't looked yet at the calls that we embed in the llvm IR.

Here are the perf results:
  pyston django_migrate.py                  :    2.3s baseline: 2.3 (-1.7%)
  pyston django-template.py                 :   15.1s baseline: 15.4 (-1.6%)
  pyston interp2.py                         :    5.3s baseline: 6.3 (-15.1%)
  pyston raytrace.py                        :    6.1s baseline: 6.2 (-0.7%)
  pyston nbody.py                           :    8.4s baseline: 8.1 (+4.1%)
  pyston fannkuch.py                        :    7.5s baseline: 7.5 (+0.2%)
  pyston chaos.py                           :   20.2s baseline: 20.0 (+0.7%)
  pyston fasta.py                           :    5.4s baseline: 5.4 (+0.3%)
  pyston pidigits.py                        :    5.7s baseline: 5.7 (+0.0%)
  pyston richards.py                        :    2.5s baseline: 2.7 (-6.2%)
  pyston deltablue.py                       :    1.8s baseline: 1.8 (-0.0%)
  pyston (geomean-3424)                     :    5.7s baseline: 5.8 (-2.0%)

I looked into the regression in nbody.py, and it is in an unrelated piece of
code (list unpacking) that has the same assembly and gets called the same number
of times.  Maybe there's some weird cache collision.  It's an extremely small
benchmark (a single 13-line loop) so I'm happy to write it off as microbenchmark
sensitivity.  We can also optimize this if we want to; we could speculate on the
type that we are unpacking and inline the parts of the unpacking code we need.
parent 925c13d5
...@@ -959,15 +959,15 @@ Value ASTInterpreter::visit_print(AST_Print* node) { ...@@ -959,15 +959,15 @@ Value ASTInterpreter::visit_print(AST_Print* node) {
// begin code for handling of softspace // begin code for handling of softspace
bool new_softspace = (i < nvals - 1) || (!node->nl); bool new_softspace = (i < nvals - 1) || (!node->nl);
if (softspace(dest, new_softspace)) { if (softspace(dest, new_softspace)) {
callattrInternal(dest, &write_str, CLASS_OR_INST, 0, ArgPassSpec(1), boxString(space_str), 0, 0, 0, 0); callattrInternal(dest, write_str, CLASS_OR_INST, 0, ArgPassSpec(1), boxString(space_str), 0, 0, 0, 0);
} }
Box* str_or_unicode_var = (var->cls == unicode_cls) ? var : str(var); Box* str_or_unicode_var = (var->cls == unicode_cls) ? var : str(var);
callattrInternal(dest, &write_str, CLASS_OR_INST, 0, ArgPassSpec(1), str_or_unicode_var, 0, 0, 0, 0); callattrInternal(dest, write_str, CLASS_OR_INST, 0, ArgPassSpec(1), str_or_unicode_var, 0, 0, 0, 0);
} }
if (node->nl) { if (node->nl) {
callattrInternal(dest, &write_str, CLASS_OR_INST, 0, ArgPassSpec(1), boxString(newline_str), 0, 0, 0, 0); callattrInternal(dest, write_str, CLASS_OR_INST, 0, ArgPassSpec(1), boxString(newline_str), 0, 0, 0, 0);
if (nvals == 0) { if (nvals == 0) {
softspace(dest, false); softspace(dest, false);
} }
......
...@@ -480,18 +480,18 @@ public: ...@@ -480,18 +480,18 @@ public:
BoxedDict* getDict(); BoxedDict* getDict();
void setattr(const std::string& attr, Box* val, SetattrRewriteArgs* rewrite_args); void setattr(llvm::StringRef attr, Box* val, SetattrRewriteArgs* rewrite_args);
void giveAttr(const std::string& attr, Box* val) { void giveAttr(llvm::StringRef attr, Box* val) {
assert(!this->hasattr(attr)); assert(!this->hasattr(attr));
this->setattr(attr, val, NULL); this->setattr(attr, val, NULL);
} }
// getattr() does the equivalent of PyDict_GetItem(obj->dict, attr): it looks up the attribute's value on the // getattr() does the equivalent of PyDict_GetItem(obj->dict, attr): it looks up the attribute's value on the
// object's attribute storage. it doesn't look at other objects or do any descriptor logic. // object's attribute storage. it doesn't look at other objects or do any descriptor logic.
Box* getattr(const std::string& attr, GetattrRewriteArgs* rewrite_args); Box* getattr(llvm::StringRef attr, GetattrRewriteArgs* rewrite_args);
Box* getattr(const std::string& attr) { return getattr(attr, NULL); } Box* getattr(llvm::StringRef attr) { return getattr(attr, NULL); }
bool hasattr(const std::string& attr) { return getattr(attr) != NULL; } bool hasattr(llvm::StringRef attr) { return getattr(attr) != NULL; }
void delattr(const std::string& attr, DelattrRewriteArgs* rewrite_args); void delattr(llvm::StringRef attr, DelattrRewriteArgs* rewrite_args);
// Only valid for hc-backed instances: // Only valid for hc-backed instances:
Box* getAttrWrapper(); Box* getAttrWrapper();
......
...@@ -114,15 +114,14 @@ bool checkClass(LookupScope scope) { ...@@ -114,15 +114,14 @@ bool checkClass(LookupScope scope) {
bool checkInst(LookupScope scope) { bool checkInst(LookupScope scope) {
return (scope & INST_ONLY) != 0; return (scope & INST_ONLY) != 0;
} }
static Box* (*callattrInternal0)(Box*, const std::string*, LookupScope, CallRewriteArgs*, ArgPassSpec) static Box* (*callattrInternal0)(Box*, llvm::StringRef, LookupScope, CallRewriteArgs*, ArgPassSpec)
= (Box * (*)(Box*, const std::string*, LookupScope, CallRewriteArgs*, ArgPassSpec))callattrInternal; = (Box * (*)(Box*, llvm::StringRef, LookupScope, CallRewriteArgs*, ArgPassSpec))callattrInternal;
static Box* (*callattrInternal1)(Box*, const std::string*, LookupScope, CallRewriteArgs*, ArgPassSpec, Box*) static Box* (*callattrInternal1)(Box*, llvm::StringRef, LookupScope, CallRewriteArgs*, ArgPassSpec, Box*)
= (Box * (*)(Box*, const std::string*, LookupScope, CallRewriteArgs*, ArgPassSpec, Box*))callattrInternal; = (Box * (*)(Box*, llvm::StringRef, LookupScope, CallRewriteArgs*, ArgPassSpec, Box*))callattrInternal;
static Box* (*callattrInternal2)(Box*, const std::string*, LookupScope, CallRewriteArgs*, ArgPassSpec, Box*, Box*) static Box* (*callattrInternal2)(Box*, llvm::StringRef, LookupScope, CallRewriteArgs*, ArgPassSpec, Box*, Box*)
= (Box * (*)(Box*, const std::string*, LookupScope, CallRewriteArgs*, ArgPassSpec, Box*, Box*))callattrInternal; = (Box * (*)(Box*, llvm::StringRef, LookupScope, CallRewriteArgs*, ArgPassSpec, Box*, Box*))callattrInternal;
static Box* (*callattrInternal3)(Box*, const std::string*, LookupScope, CallRewriteArgs*, ArgPassSpec, Box*, Box*, Box*) static Box* (*callattrInternal3)(Box*, llvm::StringRef, LookupScope, CallRewriteArgs*, ArgPassSpec, Box*, Box*, Box*)
= (Box = (Box * (*)(Box*, llvm::StringRef, LookupScope, CallRewriteArgs*, ArgPassSpec, Box*, Box*, Box*))callattrInternal;
* (*)(Box*, const std::string*, LookupScope, CallRewriteArgs*, ArgPassSpec, Box*, Box*, Box*))callattrInternal;
size_t PyHasher::operator()(Box* b) const { size_t PyHasher::operator()(Box* b) const {
STAT_TIMER(t0, "us_timer_PyHasher"); STAT_TIMER(t0, "us_timer_PyHasher");
...@@ -429,7 +428,7 @@ BoxedHeapClass::BoxedHeapClass(BoxedClass* base, gcvisit_func gc_visit, int attr ...@@ -429,7 +428,7 @@ BoxedHeapClass::BoxedHeapClass(BoxedClass* base, gcvisit_func gc_visit, int attr
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,
int weaklist_offset, int instance_size, bool is_user_defined, int weaklist_offset, int instance_size, bool is_user_defined,
const std::string& name) { llvm::StringRef 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,
static_cast<BoxedString*>(boxString(name)), NULL, 0); static_cast<BoxedString*>(boxString(name)), NULL, 0);
} }
...@@ -516,7 +515,7 @@ void HiddenClass::addDependence(Rewriter* rewriter) { ...@@ -516,7 +515,7 @@ void HiddenClass::addDependence(Rewriter* rewriter) {
rewriter->addDependenceOn(dependent_getattrs); rewriter->addDependenceOn(dependent_getattrs);
} }
HiddenClass* HiddenClass::getOrMakeChild(const std::string& attr) { HiddenClass* HiddenClass::getOrMakeChild(llvm::StringRef attr) {
STAT_TIMER(t0, "us_timer_hiddenclass_getOrMakeChild"); STAT_TIMER(t0, "us_timer_hiddenclass_getOrMakeChild");
assert(type == NORMAL); assert(type == NORMAL);
...@@ -550,7 +549,7 @@ HiddenClass* HiddenClass::getAttrwrapperChild() { ...@@ -550,7 +549,7 @@ HiddenClass* HiddenClass::getAttrwrapperChild() {
/** /**
* del attr from current HiddenClass, maintaining the order of the remaining attrs * del attr from current HiddenClass, maintaining the order of the remaining attrs
*/ */
HiddenClass* HiddenClass::delAttrToMakeHC(const std::string& attr) { HiddenClass* HiddenClass::delAttrToMakeHC(llvm::StringRef attr) {
STAT_TIMER(t0, "us_timer_hiddenclass_delAttrToMakeHC"); STAT_TIMER(t0, "us_timer_hiddenclass_delAttrToMakeHC");
assert(type == NORMAL); assert(type == NORMAL);
...@@ -639,7 +638,7 @@ BoxedDict* Box::getDict() { ...@@ -639,7 +638,7 @@ BoxedDict* Box::getDict() {
} }
static StatCounter box_getattr_slowpath("slowpath_box_getattr"); static StatCounter box_getattr_slowpath("slowpath_box_getattr");
Box* Box::getattr(const std::string& attr, GetattrRewriteArgs* rewrite_args) { Box* Box::getattr(llvm::StringRef attr, GetattrRewriteArgs* rewrite_args) {
if (rewrite_args) if (rewrite_args)
rewrite_args->obj->addAttrGuard(BOX_CLS_OFFSET, (intptr_t)cls); rewrite_args->obj->addAttrGuard(BOX_CLS_OFFSET, (intptr_t)cls);
...@@ -678,7 +677,8 @@ Box* Box::getattr(const std::string& attr, GetattrRewriteArgs* rewrite_args) { ...@@ -678,7 +677,8 @@ Box* Box::getattr(const std::string& attr, GetattrRewriteArgs* rewrite_args) {
rewrite_args = NULL; rewrite_args = NULL;
Box* d = attrs->attr_list->attrs[0]; Box* d = attrs->attr_list->attrs[0];
assert(d); assert(d);
Box* r = PyDict_GetItemString(d, attr.c_str()); assert(attr.data()[attr.size()] == '\0');
Box* r = PyDict_GetItemString(d, attr.data());
// r can be NULL if the item didn't exist // r can be NULL if the item didn't exist
return r; return r;
} }
...@@ -789,7 +789,7 @@ void Box::appendNewHCAttr(Box* new_attr, SetattrRewriteArgs* rewrite_args) { ...@@ -789,7 +789,7 @@ void Box::appendNewHCAttr(Box* new_attr, SetattrRewriteArgs* rewrite_args) {
attrs->attr_list->attrs[numattrs] = new_attr; attrs->attr_list->attrs[numattrs] = new_attr;
} }
void Box::setattr(const std::string& attr, Box* val, SetattrRewriteArgs* rewrite_args) { void Box::setattr(llvm::StringRef attr, Box* val, SetattrRewriteArgs* rewrite_args) {
assert(gc::isValidGCObject(val)); assert(gc::isValidGCObject(val));
// Have to guard on the memory layout of this object. // Have to guard on the memory layout of this object.
...@@ -816,7 +816,8 @@ void Box::setattr(const std::string& attr, Box* val, SetattrRewriteArgs* rewrite ...@@ -816,7 +816,8 @@ void Box::setattr(const std::string& attr, Box* val, SetattrRewriteArgs* rewrite
rewrite_args = NULL; rewrite_args = NULL;
Box* d = attrs->attr_list->attrs[0]; Box* d = attrs->attr_list->attrs[0];
assert(d); assert(d);
PyDict_SetItemString(d, attr.c_str(), val); assert(attr.data()[attr.size()] == '\0');
PyDict_SetItemString(d, attr.data(), val);
checkAndThrowCAPIException(); checkAndThrowCAPIException();
return; return;
} }
...@@ -911,7 +912,7 @@ extern "C" PyObject* _PyType_Lookup(PyTypeObject* type, PyObject* name) noexcept ...@@ -911,7 +912,7 @@ extern "C" PyObject* _PyType_Lookup(PyTypeObject* type, PyObject* name) noexcept
} }
} }
Box* typeLookup(BoxedClass* cls, const std::string& attr, GetattrRewriteArgs* rewrite_args) { Box* typeLookup(BoxedClass* cls, llvm::StringRef attr, GetattrRewriteArgs* rewrite_args) {
Box* val; Box* val;
if (rewrite_args) { if (rewrite_args) {
...@@ -1142,7 +1143,7 @@ static Box* boxStringFromCharPtr(const char* s) { ...@@ -1142,7 +1143,7 @@ static Box* boxStringFromCharPtr(const char* s) {
return boxStrConstant(s); return boxStrConstant(s);
} }
Box* dataDescriptorInstanceSpecialCases(GetattrRewriteArgs* rewrite_args, const std::string& attr_name, Box* obj, Box* dataDescriptorInstanceSpecialCases(GetattrRewriteArgs* rewrite_args, llvm::StringRef attr_name, Box* obj,
Box* descr, RewriterVar* r_descr, bool for_call, Box** bind_obj_out, Box* descr, RewriterVar* r_descr, bool for_call, Box** bind_obj_out,
RewriterVar** r_bind_obj_out) { RewriterVar** r_bind_obj_out) {
// Special case: data descriptor: member descriptor // Special case: data descriptor: member descriptor
...@@ -1177,7 +1178,7 @@ Box* dataDescriptorInstanceSpecialCases(GetattrRewriteArgs* rewrite_args, const ...@@ -1177,7 +1178,7 @@ Box* dataDescriptorInstanceSpecialCases(GetattrRewriteArgs* rewrite_args, const
Box* rtn = *reinterpret_cast<Box**>((char*)obj + member_desc->offset); Box* rtn = *reinterpret_cast<Box**>((char*)obj + member_desc->offset);
if (rtn == NULL) { if (rtn == NULL) {
raiseExcHelper(AttributeError, "%s", attr_name.c_str()); raiseExcHelper(AttributeError, "%.*s", attr_name.size(), attr_name.data());
} }
return rtn; return rtn;
} }
...@@ -1296,8 +1297,8 @@ Box* dataDescriptorInstanceSpecialCases(GetattrRewriteArgs* rewrite_args, const ...@@ -1296,8 +1297,8 @@ Box* dataDescriptorInstanceSpecialCases(GetattrRewriteArgs* rewrite_args, const
// is of that type. // is of that type.
if (getset_descr->get == NULL) { if (getset_descr->get == NULL) {
raiseExcHelper(AttributeError, "attribute '%s' of '%s' object is not readable", attr_name.c_str(), raiseExcHelper(AttributeError, "attribute '%.*s' of '%s' object is not readable", attr_name.size(),
getTypeName(getset_descr)); attr_name.data(), getTypeName(getset_descr));
} }
// Abort because right now we can't call twice in a rewrite // Abort because right now we can't call twice in a rewrite
...@@ -1326,8 +1327,8 @@ Box* dataDescriptorInstanceSpecialCases(GetattrRewriteArgs* rewrite_args, const ...@@ -1326,8 +1327,8 @@ Box* dataDescriptorInstanceSpecialCases(GetattrRewriteArgs* rewrite_args, const
return NULL; return NULL;
} }
Box* getattrInternalEx(Box* obj, const std::string& attr, GetattrRewriteArgs* rewrite_args, bool cls_only, Box* getattrInternalEx(Box* obj, llvm::StringRef attr, GetattrRewriteArgs* rewrite_args, bool cls_only, bool for_call,
bool for_call, Box** bind_obj_out, RewriterVar** r_bind_obj_out) { Box** bind_obj_out, RewriterVar** r_bind_obj_out) {
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) {
...@@ -1342,7 +1343,8 @@ Box* getattrInternalEx(Box* obj, const std::string& attr, GetattrRewriteArgs* re ...@@ -1342,7 +1343,8 @@ Box* getattrInternalEx(Box* obj, const std::string& attr, GetattrRewriteArgs* re
if (obj->cls->tp_getattr) { if (obj->cls->tp_getattr) {
STAT_TIMER(t0, "us_timer_tp_getattr"); STAT_TIMER(t0, "us_timer_tp_getattr");
Box* r = obj->cls->tp_getattr(obj, const_cast<char*>(attr.c_str())); assert(attr.data()[attr.size()] == '\0');
Box* r = obj->cls->tp_getattr(obj, const_cast<char*>(attr.data()));
if (!r) if (!r)
throwCAPIException(); throwCAPIException();
return r; return r;
...@@ -1359,7 +1361,7 @@ Box* getattrInternalEx(Box* obj, const std::string& attr, GetattrRewriteArgs* re ...@@ -1359,7 +1361,7 @@ Box* getattrInternalEx(Box* obj, const std::string& attr, GetattrRewriteArgs* re
return getattrInternalGeneric(obj, attr, rewrite_args, cls_only, for_call, bind_obj_out, r_bind_obj_out); return getattrInternalGeneric(obj, attr, rewrite_args, cls_only, for_call, bind_obj_out, r_bind_obj_out);
} }
inline Box* getclsattrInternal(Box* obj, const std::string& attr, GetattrRewriteArgs* rewrite_args) { inline Box* getclsattrInternal(Box* obj, llvm::StringRef attr, GetattrRewriteArgs* rewrite_args) {
return getattrInternalEx(obj, attr, rewrite_args, return getattrInternalEx(obj, attr, rewrite_args,
/* cls_only */ true, /* cls_only */ true,
/* for_call */ false, NULL, NULL); /* for_call */ false, NULL, NULL);
...@@ -1438,7 +1440,7 @@ Box* processDescriptor(Box* obj, Box* inst, Box* owner) { ...@@ -1438,7 +1440,7 @@ Box* processDescriptor(Box* obj, Box* inst, Box* owner) {
} }
Box* getattrInternalGeneric(Box* obj, const std::string& attr, GetattrRewriteArgs* rewrite_args, bool cls_only, Box* getattrInternalGeneric(Box* obj, llvm::StringRef attr, GetattrRewriteArgs* rewrite_args, bool cls_only,
bool for_call, Box** bind_obj_out, RewriterVar** r_bind_obj_out) { bool for_call, Box** bind_obj_out, RewriterVar** r_bind_obj_out) {
if (for_call) { if (for_call) {
*bind_obj_out = NULL; *bind_obj_out = NULL;
...@@ -1748,7 +1750,7 @@ Box* getattrInternalGeneric(Box* obj, const std::string& attr, GetattrRewriteArg ...@@ -1748,7 +1750,7 @@ Box* getattrInternalGeneric(Box* obj, const std::string& attr, GetattrRewriteArg
return NULL; return NULL;
} }
Box* getattrInternal(Box* obj, const std::string& attr, GetattrRewriteArgs* rewrite_args) { Box* getattrInternal(Box* obj, llvm::StringRef attr, GetattrRewriteArgs* rewrite_args) {
return getattrInternalEx(obj, attr, rewrite_args, return getattrInternalEx(obj, attr, rewrite_args,
/* cls_only */ false, /* cls_only */ false,
/* for_call */ false, NULL, NULL); /* for_call */ false, NULL, NULL);
...@@ -1809,7 +1811,7 @@ extern "C" Box* getattr(Box* obj, const char* attr) { ...@@ -1809,7 +1811,7 @@ extern "C" Box* getattr(Box* obj, const char* attr) {
} }
bool dataDescriptorSetSpecialCases(Box* obj, Box* val, Box* descr, SetattrRewriteArgs* rewrite_args, bool dataDescriptorSetSpecialCases(Box* obj, Box* val, Box* descr, SetattrRewriteArgs* rewrite_args,
RewriterVar* r_descr, const std::string& attr_name) { RewriterVar* r_descr, llvm::StringRef attr_name) {
// Special case: getset descriptor // Special case: getset descriptor
if (descr->cls == pyston_getset_cls || descr->cls == capi_getset_cls) { if (descr->cls == pyston_getset_cls || descr->cls == capi_getset_cls) {
...@@ -1817,8 +1819,8 @@ bool dataDescriptorSetSpecialCases(Box* obj, Box* val, Box* descr, SetattrRewrit ...@@ -1817,8 +1819,8 @@ bool dataDescriptorSetSpecialCases(Box* obj, Box* val, Box* descr, SetattrRewrit
// TODO type checking goes here // TODO type checking goes here
if (getset_descr->set == NULL) { if (getset_descr->set == NULL) {
raiseExcHelper(AttributeError, "attribute '%s' of '%s' objects is not writable", attr_name.c_str(), raiseExcHelper(AttributeError, "attribute '%.*s' of '%s' objects is not writable", attr_name.size(),
getTypeName(obj)); attr_name.data(), getTypeName(obj));
} }
if (rewrite_args) { if (rewrite_args) {
...@@ -1860,7 +1862,7 @@ bool dataDescriptorSetSpecialCases(Box* obj, Box* val, Box* descr, SetattrRewrit ...@@ -1860,7 +1862,7 @@ bool dataDescriptorSetSpecialCases(Box* obj, Box* val, Box* descr, SetattrRewrit
return false; return false;
} }
void setattrGeneric(Box* obj, const std::string& attr, Box* val, SetattrRewriteArgs* rewrite_args) { void setattrGeneric(Box* obj, llvm::StringRef attr, Box* val, SetattrRewriteArgs* rewrite_args) {
assert(val); assert(val);
assert(gc::isValidGCObject(val)); assert(gc::isValidGCObject(val));
...@@ -1934,8 +1936,10 @@ void setattrGeneric(Box* obj, const std::string& attr, Box* val, SetattrRewriteA ...@@ -1934,8 +1936,10 @@ void setattrGeneric(Box* obj, const std::string& attr, Box* val, SetattrRewriteA
// We don't need to to the invalidation stuff in this case. // We don't need to to the invalidation stuff in this case.
return; return;
} else { } else {
if (!obj->cls->instancesHaveHCAttrs() && !obj->cls->instancesHaveDictAttrs()) if (!obj->cls->instancesHaveHCAttrs() && !obj->cls->instancesHaveDictAttrs()) {
raiseAttributeError(obj, attr.c_str()); assert(attr.data()[attr.size()] == '\0');
raiseAttributeError(obj, attr.data());
}
obj->setattr(attr, val, rewrite_args); obj->setattr(attr, val, rewrite_args);
} }
...@@ -2121,7 +2125,7 @@ extern "C" bool nonzero(Box* obj) { ...@@ -2121,7 +2125,7 @@ extern "C" bool nonzero(Box* obj) {
|| isSubclass(obj->cls, Exception) || obj->cls == file_cls || obj->cls == traceback_cls || isSubclass(obj->cls, Exception) || obj->cls == file_cls || obj->cls == traceback_cls
|| obj->cls == instancemethod_cls || obj->cls == module_cls || obj->cls == capifunc_cls || obj->cls == instancemethod_cls || obj->cls == module_cls || obj->cls == capifunc_cls
|| obj->cls == builtin_function_or_method_cls || obj->cls == method_cls || obj->cls == frame_cls || obj->cls == builtin_function_or_method_cls || obj->cls == method_cls || obj->cls == frame_cls
|| obj->cls == capi_getset_cls || obj->cls == pyston_getset_cls, || obj->cls == capi_getset_cls || obj->cls == pyston_getset_cls || obj->cls == wrapperdescr_cls,
"%s.__nonzero__", getTypeName(obj)); // TODO "%s.__nonzero__", getTypeName(obj)); // TODO
// TODO should rewrite these? // TODO should rewrite these?
...@@ -2151,7 +2155,7 @@ extern "C" BoxedString* str(Box* obj) { ...@@ -2151,7 +2155,7 @@ extern "C" BoxedString* str(Box* obj) {
if (obj->cls != str_cls) { if (obj->cls != str_cls) {
// TODO could do an IC optimization here (once we do rewrites here at all): // TODO could do an IC optimization here (once we do rewrites here at all):
// if __str__ is objectStr, just guard on that and call repr directly. // if __str__ is objectStr, just guard on that and call repr directly.
obj = callattrInternal(obj, &str_str, CLASS_ONLY, NULL, ArgPassSpec(0), NULL, NULL, NULL, NULL, NULL); obj = callattrInternal(obj, str_str, CLASS_ONLY, NULL, ArgPassSpec(0), NULL, NULL, NULL, NULL, NULL);
} }
if (isSubclass(obj->cls, unicode_cls)) { if (isSubclass(obj->cls, unicode_cls)) {
...@@ -2179,7 +2183,7 @@ extern "C" BoxedString* repr(Box* obj) { ...@@ -2179,7 +2183,7 @@ extern "C" BoxedString* repr(Box* obj) {
static StatCounter slowpath_repr("slowpath_repr"); static StatCounter slowpath_repr("slowpath_repr");
slowpath_repr.log(); slowpath_repr.log();
obj = callattrInternal(obj, &repr_str, CLASS_ONLY, NULL, ArgPassSpec(0), NULL, NULL, NULL, NULL, NULL); obj = callattrInternal(obj, repr_str, CLASS_ONLY, NULL, ArgPassSpec(0), NULL, NULL, NULL, NULL, NULL);
if (isSubclass(obj->cls, unicode_cls)) { if (isSubclass(obj->cls, unicode_cls)) {
obj = PyUnicode_AsASCIIString(obj); obj = PyUnicode_AsASCIIString(obj);
...@@ -2250,13 +2254,13 @@ extern "C" BoxedInt* lenInternal(Box* obj, LenRewriteArgs* rewrite_args) { ...@@ -2250,13 +2254,13 @@ extern "C" BoxedInt* lenInternal(Box* obj, LenRewriteArgs* rewrite_args) {
Box* rtn; Box* rtn;
if (rewrite_args) { if (rewrite_args) {
CallRewriteArgs crewrite_args(rewrite_args->rewriter, rewrite_args->obj, rewrite_args->destination); CallRewriteArgs crewrite_args(rewrite_args->rewriter, rewrite_args->obj, rewrite_args->destination);
rtn = callattrInternal0(obj, &attr_str, CLASS_ONLY, &crewrite_args, ArgPassSpec(0)); rtn = callattrInternal0(obj, attr_str, CLASS_ONLY, &crewrite_args, ArgPassSpec(0));
if (!crewrite_args.out_success) if (!crewrite_args.out_success)
rewrite_args = NULL; rewrite_args = NULL;
else if (rtn) else if (rtn)
rewrite_args->out_rtn = crewrite_args.out_rtn; rewrite_args->out_rtn = crewrite_args.out_rtn;
} else { } else {
rtn = callattrInternal0(obj, &attr_str, CLASS_ONLY, NULL, ArgPassSpec(0)); rtn = callattrInternal0(obj, attr_str, CLASS_ONLY, NULL, ArgPassSpec(0));
} }
if (rtn == NULL) { if (rtn == NULL) {
...@@ -2483,7 +2487,7 @@ extern "C" void dump(void* p) { ...@@ -2483,7 +2487,7 @@ extern "C" void dump(void* p) {
// For rewriting purposes, this function assumes that nargs will be constant. // For rewriting purposes, this function assumes that nargs will be constant.
// That's probably fine for some uses (ex binops), but otherwise it should be guarded on beforehand. // That's probably fine for some uses (ex binops), but otherwise it should be guarded on beforehand.
extern "C" Box* callattrInternal(Box* obj, const std::string* attr, LookupScope scope, CallRewriteArgs* rewrite_args, extern "C" Box* callattrInternal(Box* obj, llvm::StringRef attr, LookupScope scope, CallRewriteArgs* rewrite_args,
ArgPassSpec argspec, Box* arg1, Box* arg2, Box* arg3, Box** args, ArgPassSpec argspec, Box* arg1, Box* arg2, Box* arg3, Box** args,
const std::vector<const std::string*>* keyword_names) { const std::vector<const std::string*>* keyword_names) {
int npassed_args = argspec.totalPassed(); int npassed_args = argspec.totalPassed();
...@@ -2522,14 +2526,14 @@ extern "C" Box* callattrInternal(Box* obj, const std::string* attr, LookupScope ...@@ -2522,14 +2526,14 @@ extern "C" Box* callattrInternal(Box* obj, const std::string* attr, LookupScope
RewriterVar* r_val = NULL; RewriterVar* r_val = NULL;
if (rewrite_args) { if (rewrite_args) {
GetattrRewriteArgs grewrite_args(rewrite_args->rewriter, rewrite_args->obj, Location::any()); GetattrRewriteArgs grewrite_args(rewrite_args->rewriter, rewrite_args->obj, Location::any());
val = getattrInternalEx(obj, *attr, &grewrite_args, scope == CLASS_ONLY, true, &bind_obj, &r_bind_obj); val = getattrInternalEx(obj, attr, &grewrite_args, scope == CLASS_ONLY, true, &bind_obj, &r_bind_obj);
if (!grewrite_args.out_success) { if (!grewrite_args.out_success) {
rewrite_args = NULL; rewrite_args = NULL;
} else if (val) { } else if (val) {
r_val = grewrite_args.out_rtn; r_val = grewrite_args.out_rtn;
} }
} else { } else {
val = getattrInternalEx(obj, *attr, NULL, scope == CLASS_ONLY, true, &bind_obj, &r_bind_obj); val = getattrInternalEx(obj, attr, NULL, scope == CLASS_ONLY, true, &bind_obj, &r_bind_obj);
} }
if (val == NULL) { if (val == NULL) {
...@@ -2697,7 +2701,7 @@ extern "C" Box* callattr(Box* obj, const std::string* attr, CallattrFlags flags, ...@@ -2697,7 +2701,7 @@ extern "C" Box* callattr(Box* obj, const std::string* attr, CallattrFlags flags,
rewrite_args.arg3 = rewriter->getArg(6); rewrite_args.arg3 = rewriter->getArg(6);
if (npassed_args >= 4) if (npassed_args >= 4)
rewrite_args.args = rewriter->getArg(7); rewrite_args.args = rewriter->getArg(7);
rtn = callattrInternal(obj, attr, scope, &rewrite_args, argspec, arg1, arg2, arg3, args, keyword_names); rtn = callattrInternal(obj, *attr, scope, &rewrite_args, argspec, arg1, arg2, arg3, args, keyword_names);
if (!rewrite_args.out_success) { if (!rewrite_args.out_success) {
rewriter.reset(NULL); rewriter.reset(NULL);
...@@ -2705,7 +2709,7 @@ extern "C" Box* callattr(Box* obj, const std::string* attr, CallattrFlags flags, ...@@ -2705,7 +2709,7 @@ extern "C" Box* callattr(Box* obj, const std::string* attr, CallattrFlags flags,
rewriter->commitReturning(rewrite_args.out_rtn); rewriter->commitReturning(rewrite_args.out_rtn);
} }
} else { } else {
rtn = callattrInternal(obj, attr, scope, NULL, argspec, arg1, arg2, arg3, args, keyword_names); rtn = callattrInternal(obj, *attr, scope, NULL, argspec, arg1, arg2, arg3, args, keyword_names);
} }
if (rtn == NULL && !flags.null_on_nonexistent) { if (rtn == NULL && !flags.null_on_nonexistent) {
...@@ -2807,15 +2811,15 @@ enum class KeywordDest { ...@@ -2807,15 +2811,15 @@ enum class KeywordDest {
KWARGS, KWARGS,
}; };
static KeywordDest placeKeyword(const ParamNames& param_names, llvm::SmallVector<bool, 8>& params_filled, static KeywordDest placeKeyword(const ParamNames& param_names, llvm::SmallVector<bool, 8>& params_filled,
const std::string& kw_name, Box* kw_val, Box*& oarg1, Box*& oarg2, Box*& oarg3, llvm::StringRef kw_name, Box* kw_val, Box*& oarg1, Box*& oarg2, Box*& oarg3,
Box** oargs, BoxedDict* okwargs, CLFunction* cl) { Box** oargs, BoxedDict* okwargs, CLFunction* cl) {
assert(kw_val); assert(kw_val);
for (int j = 0; j < param_names.args.size(); j++) { for (int j = 0; j < param_names.args.size(); j++) {
if (param_names.args[j].str() == kw_name && kw_name.size() > 0) { if (param_names.args[j].str() == kw_name && kw_name.size() > 0) {
if (params_filled[j]) { if (params_filled[j]) {
raiseExcHelper(TypeError, "%.200s() got multiple values for keyword argument '%s'", raiseExcHelper(TypeError, "%.200s() got multiple values for keyword argument '%.*s'",
getFunctionName(cl).c_str(), kw_name.c_str()); getFunctionName(cl).c_str(), kw_name.size(), kw_name.data());
} }
getArg(j, oarg1, oarg2, oarg3, oargs) = kw_val; getArg(j, oarg1, oarg2, oarg3, oargs) = kw_val;
...@@ -2828,14 +2832,14 @@ static KeywordDest placeKeyword(const ParamNames& param_names, llvm::SmallVector ...@@ -2828,14 +2832,14 @@ static KeywordDest placeKeyword(const ParamNames& param_names, llvm::SmallVector
if (okwargs) { if (okwargs) {
Box*& v = okwargs->d[boxString(kw_name)]; Box*& v = okwargs->d[boxString(kw_name)];
if (v) { if (v) {
raiseExcHelper(TypeError, "%.200s() got multiple values for keyword argument '%s'", raiseExcHelper(TypeError, "%.200s() got multiple values for keyword argument '%.*s'",
getFunctionName(cl).c_str(), kw_name.c_str()); getFunctionName(cl).c_str(), kw_name.size(), kw_name.data());
} }
v = kw_val; v = kw_val;
return KeywordDest::KWARGS; return KeywordDest::KWARGS;
} else { } else {
raiseExcHelper(TypeError, "%.200s() got an unexpected keyword argument '%s'", getFunctionName(cl).c_str(), raiseExcHelper(TypeError, "%.200s() got an unexpected keyword argument '%.*s'", getFunctionName(cl).c_str(),
kw_name.c_str()); kw_name.size(), kw_name.data());
} }
} }
...@@ -3272,10 +3276,10 @@ Box* runtimeCallInternal(Box* obj, CallRewriteArgs* rewrite_args, ArgPassSpec ar ...@@ -3272,10 +3276,10 @@ Box* runtimeCallInternal(Box* obj, CallRewriteArgs* rewrite_args, ArgPassSpec ar
} }
if (rewrite_args) { if (rewrite_args) {
rtn = callattrInternal(obj, &call_str, CLASS_ONLY, rewrite_args, argspec, arg1, arg2, arg3, args, rtn = callattrInternal(obj, call_str, CLASS_ONLY, rewrite_args, argspec, arg1, arg2, arg3, args,
keyword_names); keyword_names);
} else { } else {
rtn = callattrInternal(obj, &call_str, CLASS_ONLY, NULL, argspec, arg1, arg2, arg3, args, keyword_names); rtn = callattrInternal(obj, call_str, CLASS_ONLY, NULL, argspec, arg1, arg2, arg3, args, keyword_names);
} }
if (!rtn) if (!rtn)
raiseExcHelper(TypeError, "'%s' object is not callable", getTypeName(obj)); raiseExcHelper(TypeError, "'%s' object is not callable", getTypeName(obj));
...@@ -3464,7 +3468,7 @@ extern "C" Box* binopInternal(Box* lhs, Box* rhs, int op_type, bool inplace, Bin ...@@ -3464,7 +3468,7 @@ extern "C" Box* binopInternal(Box* lhs, Box* rhs, int op_type, bool inplace, Bin
CallRewriteArgs srewrite_args(rewrite_args->rewriter, rewrite_args->lhs, rewrite_args->destination); CallRewriteArgs srewrite_args(rewrite_args->rewriter, rewrite_args->lhs, rewrite_args->destination);
srewrite_args.arg1 = rewrite_args->rhs; srewrite_args.arg1 = rewrite_args->rhs;
srewrite_args.args_guarded = true; srewrite_args.args_guarded = true;
irtn = callattrInternal1(lhs, &iop_name, CLASS_ONLY, &srewrite_args, ArgPassSpec(1), rhs); irtn = callattrInternal1(lhs, iop_name, CLASS_ONLY, &srewrite_args, ArgPassSpec(1), rhs);
if (!srewrite_args.out_success) { if (!srewrite_args.out_success) {
rewrite_args = NULL; rewrite_args = NULL;
...@@ -3473,7 +3477,7 @@ extern "C" Box* binopInternal(Box* lhs, Box* rhs, int op_type, bool inplace, Bin ...@@ -3473,7 +3477,7 @@ extern "C" Box* binopInternal(Box* lhs, Box* rhs, int op_type, bool inplace, Bin
rewrite_args->out_rtn = srewrite_args.out_rtn; rewrite_args->out_rtn = srewrite_args.out_rtn;
} }
} else { } else {
irtn = callattrInternal1(lhs, &iop_name, CLASS_ONLY, NULL, ArgPassSpec(1), rhs); irtn = callattrInternal1(lhs, iop_name, CLASS_ONLY, NULL, ArgPassSpec(1), rhs);
} }
if (irtn) { if (irtn) {
...@@ -3491,7 +3495,7 @@ extern "C" Box* binopInternal(Box* lhs, Box* rhs, int op_type, bool inplace, Bin ...@@ -3491,7 +3495,7 @@ extern "C" Box* binopInternal(Box* lhs, Box* rhs, int op_type, bool inplace, Bin
if (rewrite_args) { if (rewrite_args) {
CallRewriteArgs srewrite_args(rewrite_args->rewriter, rewrite_args->lhs, rewrite_args->destination); CallRewriteArgs srewrite_args(rewrite_args->rewriter, rewrite_args->lhs, rewrite_args->destination);
srewrite_args.arg1 = rewrite_args->rhs; srewrite_args.arg1 = rewrite_args->rhs;
lrtn = callattrInternal1(lhs, &op_name, CLASS_ONLY, &srewrite_args, ArgPassSpec(1), rhs); lrtn = callattrInternal1(lhs, op_name, CLASS_ONLY, &srewrite_args, ArgPassSpec(1), rhs);
if (!srewrite_args.out_success) if (!srewrite_args.out_success)
rewrite_args = NULL; rewrite_args = NULL;
...@@ -3500,7 +3504,7 @@ extern "C" Box* binopInternal(Box* lhs, Box* rhs, int op_type, bool inplace, Bin ...@@ -3500,7 +3504,7 @@ extern "C" Box* binopInternal(Box* lhs, Box* rhs, int op_type, bool inplace, Bin
rewrite_args->out_rtn = srewrite_args.out_rtn; rewrite_args->out_rtn = srewrite_args.out_rtn;
} }
} else { } else {
lrtn = callattrInternal1(lhs, &op_name, CLASS_ONLY, NULL, ArgPassSpec(1), rhs); lrtn = callattrInternal1(lhs, op_name, CLASS_ONLY, NULL, ArgPassSpec(1), rhs);
} }
...@@ -3521,7 +3525,7 @@ extern "C" Box* binopInternal(Box* lhs, Box* rhs, int op_type, bool inplace, Bin ...@@ -3521,7 +3525,7 @@ extern "C" Box* binopInternal(Box* lhs, Box* rhs, int op_type, bool inplace, Bin
} }
std::string rop_name = getReverseOpName(op_type); std::string rop_name = getReverseOpName(op_type);
Box* rrtn = callattrInternal1(rhs, &rop_name, CLASS_ONLY, NULL, ArgPassSpec(1), lhs); Box* rrtn = callattrInternal1(rhs, rop_name, CLASS_ONLY, NULL, ArgPassSpec(1), lhs);
if (rrtn != NULL && rrtn != NotImplemented) if (rrtn != NULL && rrtn != NotImplemented)
return rrtn; return rrtn;
...@@ -3669,7 +3673,7 @@ Box* compareInternal(Box* lhs, Box* rhs, int op_type, CompareRewriteArgs* rewrit ...@@ -3669,7 +3673,7 @@ Box* compareInternal(Box* lhs, Box* rhs, int op_type, CompareRewriteArgs* rewrit
if (op_type == AST_TYPE::In || op_type == AST_TYPE::NotIn) { if (op_type == AST_TYPE::In || op_type == AST_TYPE::NotIn) {
// TODO do rewrite // TODO do rewrite
Box* contained = callattrInternal1(rhs, &contains_str, CLASS_ONLY, NULL, ArgPassSpec(1), lhs); Box* contained = callattrInternal1(rhs, contains_str, CLASS_ONLY, NULL, ArgPassSpec(1), lhs);
if (contained == NULL) { if (contained == NULL) {
int result = _PySequence_IterSearch(rhs, lhs, PY_ITERSEARCH_CONTAINS); int result = _PySequence_IterSearch(rhs, lhs, PY_ITERSEARCH_CONTAINS);
if (result < 0) if (result < 0)
...@@ -3702,14 +3706,14 @@ Box* compareInternal(Box* lhs, Box* rhs, int op_type, CompareRewriteArgs* rewrit ...@@ -3702,14 +3706,14 @@ Box* compareInternal(Box* lhs, Box* rhs, int op_type, CompareRewriteArgs* rewrit
if (rewrite_args) { if (rewrite_args) {
CallRewriteArgs crewrite_args(rewrite_args->rewriter, rewrite_args->lhs, rewrite_args->destination); CallRewriteArgs crewrite_args(rewrite_args->rewriter, rewrite_args->lhs, rewrite_args->destination);
crewrite_args.arg1 = rewrite_args->rhs; crewrite_args.arg1 = rewrite_args->rhs;
lrtn = callattrInternal1(lhs, &op_name, CLASS_ONLY, &crewrite_args, ArgPassSpec(1), rhs); lrtn = callattrInternal1(lhs, op_name, CLASS_ONLY, &crewrite_args, ArgPassSpec(1), rhs);
if (!crewrite_args.out_success) if (!crewrite_args.out_success)
rewrite_args = NULL; rewrite_args = NULL;
else if (lrtn) else if (lrtn)
rewrite_args->out_rtn = crewrite_args.out_rtn; rewrite_args->out_rtn = crewrite_args.out_rtn;
} else { } else {
lrtn = callattrInternal1(lhs, &op_name, CLASS_ONLY, NULL, ArgPassSpec(1), rhs); lrtn = callattrInternal1(lhs, op_name, CLASS_ONLY, NULL, ArgPassSpec(1), rhs);
} }
if (lrtn) { if (lrtn) {
...@@ -3732,16 +3736,16 @@ Box* compareInternal(Box* lhs, Box* rhs, int op_type, CompareRewriteArgs* rewrit ...@@ -3732,16 +3736,16 @@ Box* compareInternal(Box* lhs, Box* rhs, int op_type, CompareRewriteArgs* rewrit
} }
std::string rop_name = getReverseOpName(op_type); std::string rop_name = getReverseOpName(op_type);
Box* rrtn = callattrInternal1(rhs, &rop_name, CLASS_ONLY, NULL, ArgPassSpec(1), lhs); Box* rrtn = callattrInternal1(rhs, rop_name, CLASS_ONLY, NULL, ArgPassSpec(1), lhs);
if (rrtn != NULL && rrtn != NotImplemented) if (rrtn != NULL && rrtn != NotImplemented)
return rrtn; return rrtn;
std::string cmp_name = "__cmp__"; std::string cmp_name = "__cmp__";
lrtn = callattrInternal1(lhs, &cmp_name, CLASS_ONLY, NULL, ArgPassSpec(1), rhs); lrtn = callattrInternal1(lhs, cmp_name, CLASS_ONLY, NULL, ArgPassSpec(1), rhs);
if (lrtn && lrtn != NotImplemented) { if (lrtn && lrtn != NotImplemented) {
return boxBool(convert3wayCompareResultToBool(lrtn, op_type)); return boxBool(convert3wayCompareResultToBool(lrtn, op_type));
} }
rrtn = callattrInternal1(rhs, &cmp_name, CLASS_ONLY, NULL, ArgPassSpec(1), lhs); rrtn = callattrInternal1(rhs, cmp_name, CLASS_ONLY, NULL, ArgPassSpec(1), lhs);
if (rrtn && rrtn != NotImplemented) { if (rrtn && rrtn != NotImplemented) {
bool success = false; bool success = false;
int reversed_op = getReverseCmpOp(op_type, success); int reversed_op = getReverseCmpOp(op_type, success);
...@@ -3857,14 +3861,14 @@ extern "C" Box* getitem(Box* value, Box* slice) { ...@@ -3857,14 +3861,14 @@ extern "C" Box* getitem(Box* value, Box* slice) {
CallRewriteArgs rewrite_args(rewriter.get(), rewriter->getArg(0), rewriter->getReturnDestination()); CallRewriteArgs rewrite_args(rewriter.get(), rewriter->getArg(0), rewriter->getReturnDestination());
rewrite_args.arg1 = rewriter->getArg(1); rewrite_args.arg1 = rewriter->getArg(1);
rtn = callattrInternal1(value, &getitem_str, CLASS_ONLY, &rewrite_args, ArgPassSpec(1), slice); rtn = callattrInternal1(value, getitem_str, CLASS_ONLY, &rewrite_args, ArgPassSpec(1), slice);
if (!rewrite_args.out_success) { if (!rewrite_args.out_success) {
rewriter.reset(NULL); rewriter.reset(NULL);
} else if (rtn) } else if (rtn)
rewriter->commitReturning(rewrite_args.out_rtn); rewriter->commitReturning(rewrite_args.out_rtn);
} else { } else {
rtn = callattrInternal1(value, &getitem_str, CLASS_ONLY, NULL, ArgPassSpec(1), slice); rtn = callattrInternal1(value, getitem_str, CLASS_ONLY, NULL, ArgPassSpec(1), slice);
} }
if (rtn == NULL) { if (rtn == NULL) {
...@@ -3899,13 +3903,13 @@ extern "C" void setitem(Box* target, Box* slice, Box* value) { ...@@ -3899,13 +3903,13 @@ extern "C" void setitem(Box* target, Box* slice, Box* value) {
rewrite_args.arg1 = rewriter->getArg(1); rewrite_args.arg1 = rewriter->getArg(1);
rewrite_args.arg2 = rewriter->getArg(2); rewrite_args.arg2 = rewriter->getArg(2);
rtn = callattrInternal2(target, &setitem_str, CLASS_ONLY, &rewrite_args, ArgPassSpec(2), slice, value); rtn = callattrInternal2(target, setitem_str, CLASS_ONLY, &rewrite_args, ArgPassSpec(2), slice, value);
if (!rewrite_args.out_success) { if (!rewrite_args.out_success) {
rewriter.reset(NULL); rewriter.reset(NULL);
} }
} else { } else {
rtn = callattrInternal2(target, &setitem_str, CLASS_ONLY, NULL, ArgPassSpec(2), slice, value); rtn = callattrInternal2(target, setitem_str, CLASS_ONLY, NULL, ArgPassSpec(2), slice, value);
} }
if (rtn == NULL) { if (rtn == NULL) {
...@@ -3932,14 +3936,14 @@ extern "C" void delitem(Box* target, Box* slice) { ...@@ -3932,14 +3936,14 @@ extern "C" void delitem(Box* target, Box* slice) {
CallRewriteArgs rewrite_args(rewriter.get(), rewriter->getArg(0), rewriter->getReturnDestination()); CallRewriteArgs rewrite_args(rewriter.get(), rewriter->getArg(0), rewriter->getReturnDestination());
rewrite_args.arg1 = rewriter->getArg(1); rewrite_args.arg1 = rewriter->getArg(1);
rtn = callattrInternal1(target, &delitem_str, CLASS_ONLY, &rewrite_args, ArgPassSpec(1), slice); rtn = callattrInternal1(target, delitem_str, CLASS_ONLY, &rewrite_args, ArgPassSpec(1), slice);
if (!rewrite_args.out_success) { if (!rewrite_args.out_success) {
rewriter.reset(NULL); rewriter.reset(NULL);
} }
} else { } else {
rtn = callattrInternal1(target, &delitem_str, CLASS_ONLY, NULL, ArgPassSpec(1), slice); rtn = callattrInternal1(target, delitem_str, CLASS_ONLY, NULL, ArgPassSpec(1), slice);
} }
if (rtn == NULL) { if (rtn == NULL) {
...@@ -3951,7 +3955,7 @@ extern "C" void delitem(Box* target, Box* slice) { ...@@ -3951,7 +3955,7 @@ extern "C" void delitem(Box* target, Box* slice) {
} }
} }
void Box::delattr(const std::string& attr, DelattrRewriteArgs* rewrite_args) { void Box::delattr(llvm::StringRef attr, DelattrRewriteArgs* rewrite_args) {
if (cls->instancesHaveHCAttrs()) { if (cls->instancesHaveHCAttrs()) {
// as soon as the hcls changes, the guard on hidden class won't pass. // as soon as the hcls changes, the guard on hidden class won't pass.
HCAttrs* attrs = getHCAttrsPtr(); HCAttrs* attrs = getHCAttrsPtr();
...@@ -3963,7 +3967,8 @@ void Box::delattr(const std::string& attr, DelattrRewriteArgs* rewrite_args) { ...@@ -3963,7 +3967,8 @@ void Box::delattr(const std::string& attr, DelattrRewriteArgs* rewrite_args) {
rewrite_args = NULL; rewrite_args = NULL;
Box* d = attrs->attr_list->attrs[0]; Box* d = attrs->attr_list->attrs[0];
assert(d); assert(d);
PyDict_DelItemString(d, attr.c_str()); assert(attr.data()[attr.size()] == '\0');
PyDict_DelItemString(d, attr.data());
checkAndThrowCAPIException(); checkAndThrowCAPIException();
return; return;
} }
...@@ -4000,7 +4005,7 @@ void Box::delattr(const std::string& attr, DelattrRewriteArgs* rewrite_args) { ...@@ -4000,7 +4005,7 @@ void Box::delattr(const std::string& attr, DelattrRewriteArgs* rewrite_args) {
abort(); abort();
} }
extern "C" void delattrGeneric(Box* obj, const std::string& attr, DelattrRewriteArgs* rewrite_args) { extern "C" void delattrGeneric(Box* obj, llvm::StringRef attr, DelattrRewriteArgs* rewrite_args) {
// first check whether the deleting attribute is a descriptor // first check whether the deleting attribute is a descriptor
Box* clsAttr = typeLookup(obj->cls, attr, NULL); Box* clsAttr = typeLookup(obj->cls, attr, NULL);
if (clsAttr != NULL) { if (clsAttr != NULL) {
...@@ -4020,9 +4025,11 @@ extern "C" void delattrGeneric(Box* obj, const std::string& attr, DelattrRewrite ...@@ -4020,9 +4025,11 @@ extern "C" void delattrGeneric(Box* obj, const std::string& attr, DelattrRewrite
} else { } else {
// the exception cpthon throws is different when the class contains the attribute // the exception cpthon throws is different when the class contains the attribute
if (clsAttr != NULL) { if (clsAttr != NULL) {
raiseExcHelper(AttributeError, "'%s' object attribute '%s' is read-only", getTypeName(obj), attr.c_str()); raiseExcHelper(AttributeError, "'%s' object attribute '%.*s' is read-only", getTypeName(obj), attr.size(),
attr.data());
} else { } else {
raiseAttributeError(obj, attr.c_str()); assert(attr.data()[attr.size()] == '\0');
raiseAttributeError(obj, attr.data());
} }
} }
...@@ -4044,7 +4051,7 @@ extern "C" void delattrGeneric(Box* obj, const std::string& attr, DelattrRewrite ...@@ -4044,7 +4051,7 @@ extern "C" void delattrGeneric(Box* obj, const std::string& attr, DelattrRewrite
(void)rewrite_args; (void)rewrite_args;
} }
extern "C" void delattrInternal(Box* obj, const std::string& attr, DelattrRewriteArgs* rewrite_args) { extern "C" void delattrInternal(Box* obj, llvm::StringRef attr, DelattrRewriteArgs* rewrite_args) {
Box* delAttr = typeLookup(obj->cls, delattr_str, NULL); Box* delAttr = typeLookup(obj->cls, delattr_str, NULL);
if (delAttr != NULL) { if (delAttr != NULL) {
Box* boxstr = boxString(attr); Box* boxstr = boxString(attr);
...@@ -4129,7 +4136,7 @@ extern "C" Box* getiterHelper(Box* o) { ...@@ -4129,7 +4136,7 @@ extern "C" Box* getiterHelper(Box* o) {
Box* getiter(Box* o) { Box* getiter(Box* o) {
// TODO add rewriting to this? probably want to try to avoid this path though // TODO add rewriting to this? probably want to try to avoid this path though
Box* r = callattrInternal0(o, &iter_str, LookupScope::CLASS_ONLY, NULL, ArgPassSpec(0)); Box* r = callattrInternal0(o, iter_str, LookupScope::CLASS_ONLY, NULL, ArgPassSpec(0));
if (r) if (r)
return r; return r;
return getiterHelper(o); return getiterHelper(o);
...@@ -4669,7 +4676,7 @@ Box* typeCallInternal(BoxedFunctionBase* f, CallRewriteArgs* rewrite_args, ArgPa ...@@ -4669,7 +4676,7 @@ Box* typeCallInternal(BoxedFunctionBase* f, CallRewriteArgs* rewrite_args, ArgPa
srewrite_args.args_guarded = true; srewrite_args.args_guarded = true;
srewrite_args.func_guarded = true; srewrite_args.func_guarded = true;
// initrtn = callattrInternal(cls, &_init_str, INST_ONLY, &srewrite_args, argspec, made, arg2, arg3, args, // initrtn = callattrInternal(cls, _init_str, INST_ONLY, &srewrite_args, argspec, made, arg2, arg3, args,
// keyword_names); // keyword_names);
initrtn = runtimeCallInternal(init_attr, &srewrite_args, argspec, made, arg2, arg3, args, keyword_names); initrtn = runtimeCallInternal(init_attr, &srewrite_args, argspec, made, arg2, arg3, args, keyword_names);
......
...@@ -53,7 +53,7 @@ extern "C" void my_assert(bool b); ...@@ -53,7 +53,7 @@ extern "C" void my_assert(bool b);
extern "C" Box* getattr(Box* obj, const char* attr); extern "C" Box* getattr(Box* obj, const char* attr);
extern "C" void setattr(Box* obj, const char* attr, Box* attr_val); extern "C" void setattr(Box* obj, const char* attr, Box* attr_val);
extern "C" void delattr(Box* obj, const char* attr); extern "C" void delattr(Box* obj, const char* attr);
extern "C" void delattrGeneric(Box* obj, const std::string& attr, DelattrRewriteArgs* rewrite_args); extern "C" void delattrGeneric(Box* obj, llvm::StringRef attr, DelattrRewriteArgs* rewrite_args);
extern "C" bool nonzero(Box* obj); extern "C" bool nonzero(Box* obj);
extern "C" Box* runtimeCall(Box*, ArgPassSpec, Box*, Box*, Box*, Box**, const std::vector<const std::string*>*); extern "C" Box* runtimeCall(Box*, ArgPassSpec, Box*, Box*, Box*, Box**, const std::vector<const std::string*>*);
extern "C" Box* callattr(Box*, const std::string*, CallattrFlags, ArgPassSpec, Box*, Box*, Box*, Box**, extern "C" Box* callattr(Box*, const std::string*, CallattrFlags, ArgPassSpec, Box*, Box*, Box*, Box**,
...@@ -97,7 +97,7 @@ extern "C" void dump(void* p); ...@@ -97,7 +97,7 @@ extern "C" void dump(void* p);
extern "C" void dumpEx(void* p, int levels = 0); extern "C" void dumpEx(void* p, int levels = 0);
struct SetattrRewriteArgs; struct SetattrRewriteArgs;
void setattrGeneric(Box* obj, const std::string& attr, Box* val, SetattrRewriteArgs* rewrite_args); void setattrGeneric(Box* obj, llvm::StringRef attr, Box* val, SetattrRewriteArgs* rewrite_args);
struct BinopRewriteArgs; struct BinopRewriteArgs;
extern "C" Box* binopInternal(Box* lhs, Box* rhs, int op_type, bool inplace, BinopRewriteArgs* rewrite_args); extern "C" Box* binopInternal(Box* lhs, Box* rhs, int op_type, bool inplace, BinopRewriteArgs* rewrite_args);
...@@ -119,27 +119,26 @@ enum LookupScope { ...@@ -119,27 +119,26 @@ enum LookupScope {
INST_ONLY = 2, INST_ONLY = 2,
CLASS_OR_INST = 3, CLASS_OR_INST = 3,
}; };
extern "C" Box* callattrInternal(Box* obj, const std::string* attr, LookupScope, CallRewriteArgs* rewrite_args, extern "C" Box* callattrInternal(Box* obj, llvm::StringRef attr, LookupScope, CallRewriteArgs* rewrite_args,
ArgPassSpec argspec, Box* arg1, Box* arg2, Box* arg3, Box** args, ArgPassSpec argspec, Box* arg1, Box* arg2, Box* arg3, Box** args,
const std::vector<const std::string*>* keyword_names); const std::vector<const std::string*>* keyword_names);
extern "C" void delattr_internal(Box* obj, const std::string& attr, bool allow_custom, extern "C" void delattr_internal(Box* obj, llvm::StringRef attr, bool allow_custom, DelattrRewriteArgs* rewrite_args);
DelattrRewriteArgs* rewrite_args);
struct CompareRewriteArgs; struct CompareRewriteArgs;
Box* compareInternal(Box* lhs, Box* rhs, int op_type, CompareRewriteArgs* rewrite_args); Box* compareInternal(Box* lhs, Box* rhs, int op_type, CompareRewriteArgs* rewrite_args);
// This is the equivalent of PyObject_GetAttr. Unlike getattrInternalGeneric, it checks for custom __getattr__ or // This is the equivalent of PyObject_GetAttr. Unlike getattrInternalGeneric, it checks for custom __getattr__ or
// __getattribute__ methods. // __getattribute__ methods.
Box* getattrInternal(Box* obj, const std::string& attr, GetattrRewriteArgs* rewrite_args); Box* getattrInternal(Box* obj, llvm::StringRef attr, GetattrRewriteArgs* rewrite_args);
// This is the equivalent of PyObject_GenericGetAttr, which performs the default lookup rules for getattr() (check for // This is the equivalent of PyObject_GenericGetAttr, which performs the default lookup rules for getattr() (check for
// data descriptor, check for instance attribute, check for non-data descriptor). It does not check for __getattr__ or // data descriptor, check for instance attribute, check for non-data descriptor). It does not check for __getattr__ or
// __getattribute__. // __getattribute__.
Box* getattrInternalGeneric(Box* obj, const std::string& attr, GetattrRewriteArgs* rewrite_args, bool cls_only, Box* getattrInternalGeneric(Box* obj, llvm::StringRef attr, GetattrRewriteArgs* rewrite_args, bool cls_only,
bool for_call, Box** bind_obj_out, RewriterVar** r_bind_obj_out); bool for_call, Box** bind_obj_out, RewriterVar** r_bind_obj_out);
// This is the equivalent of _PyType_Lookup(), which calls Box::getattr() on each item in the object's MRO in the // This is the equivalent of _PyType_Lookup(), which calls Box::getattr() on each item in the object's MRO in the
// appropriate order. It does not do any descriptor logic. // appropriate order. It does not do any descriptor logic.
Box* typeLookup(BoxedClass* cls, const std::string& attr, GetattrRewriteArgs* rewrite_args); Box* typeLookup(BoxedClass* cls, llvm::StringRef attr, GetattrRewriteArgs* rewrite_args);
extern "C" void raiseAttributeErrorStr(const char* typeName, const char* attr) __attribute__((__noreturn__)); extern "C" void raiseAttributeErrorStr(const char* typeName, const char* attr) __attribute__((__noreturn__));
extern "C" void raiseAttributeError(Box* obj, const char* attr) __attribute__((__noreturn__)); extern "C" void raiseAttributeError(Box* obj, const char* attr) __attribute__((__noreturn__));
......
...@@ -1653,7 +1653,7 @@ public: ...@@ -1653,7 +1653,7 @@ public:
BoxedDict* dict = (BoxedDict*)AttrWrapper::copy(_self); BoxedDict* dict = (BoxedDict*)AttrWrapper::copy(_self);
assert(dict->cls == dict_cls); assert(dict->cls == dict_cls);
const std::string eq_str = "__eq__"; const std::string eq_str = "__eq__";
return callattrInternal(dict, &eq_str, LookupScope::CLASS_ONLY, NULL, ArgPassSpec(1), _other, NULL, NULL, NULL, return callattrInternal(dict, eq_str, LookupScope::CLASS_ONLY, NULL, ArgPassSpec(1), _other, NULL, NULL, NULL,
NULL); NULL);
} }
......
...@@ -239,8 +239,7 @@ public: ...@@ -239,8 +239,7 @@ public:
int weaklist_offset, int instance_size, bool is_user_defined, BoxedString* name, int weaklist_offset, int instance_size, bool is_user_defined, BoxedString* name,
BoxedTuple* bases, size_t nslots); BoxedTuple* bases, size_t nslots);
static BoxedHeapClass* create(BoxedClass* metatype, BoxedClass* base, gcvisit_func gc_visit, int attrs_offset, static BoxedHeapClass* create(BoxedClass* metatype, BoxedClass* base, gcvisit_func gc_visit, int attrs_offset,
int weaklist_offset, int instance_size, bool is_user_defined, int weaklist_offset, int instance_size, bool is_user_defined, llvm::StringRef name);
const std::string& name);
private: private:
// These functions are not meant for external callers and will mostly just be called // These functions are not meant for external callers and will mostly just be called
...@@ -354,10 +353,10 @@ public: ...@@ -354,10 +353,10 @@ public:
} }
// Only valid for NORMAL hidden classes: // Only valid for NORMAL hidden classes:
HiddenClass* getOrMakeChild(const std::string& attr); HiddenClass* getOrMakeChild(llvm::StringRef attr);
// Only valid for NORMAL or SINGLETON hidden classes: // Only valid for NORMAL or SINGLETON hidden classes:
int getOffset(const std::string& attr) { int getOffset(llvm::StringRef attr) {
assert(type == NORMAL || type == SINGLETON); assert(type == NORMAL || type == SINGLETON);
auto it = attr_offsets.find(attr); auto it = attr_offsets.find(attr);
if (it == attr_offsets.end()) if (it == attr_offsets.end())
...@@ -380,7 +379,7 @@ public: ...@@ -380,7 +379,7 @@ public:
HiddenClass* getAttrwrapperChild(); HiddenClass* getAttrwrapperChild();
// Only valid for NORMAL hidden classes: // Only valid for NORMAL hidden classes:
HiddenClass* delAttrToMakeHC(const std::string& attr); HiddenClass* delAttrToMakeHC(llvm::StringRef attr);
}; };
class BoxedInt : public Box { class BoxedInt : public Box {
......
...@@ -6,7 +6,7 @@ def tally(fn): ...@@ -6,7 +6,7 @@ def tally(fn):
for l in open(fn): for l in open(fn):
samples = int(l.split()[3]) samples = int(l.split()[3])
func = l.split()[-1] func = l.split()[-1]
counts[func] = samples counts[func] = counts.get(func, 0) + samples
return counts return counts
......
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