Commit 3948fb95 authored by Marius Wachtler's avatar Marius Wachtler

callattr: Embed the ArgPassSpec arg into the CallattrFlags struct

in order to save one register.
This makes it possible to pass up to 3 args to a runtimc IC callattr
(Runtime ICs currently don't support passing args on the stack)
parent 79505a1a
......@@ -1150,10 +1150,10 @@ Value ASTInterpreter::visit_call(AST_Call* node) {
ArgPassSpec argspec(node->args.size(), node->keywords.size(), node->starargs, node->kwargs);
if (is_callattr) {
return callattr(func.o, attr.getBox(),
CallattrFlags({.cls_only = callattr_clsonly, .null_on_nonexistent = false }), argspec,
args.size() > 0 ? args[0] : 0, args.size() > 1 ? args[1] : 0, args.size() > 2 ? args[2] : 0,
args.size() > 3 ? &args[3] : 0, &keywords);
CallattrFlags callattr_flags{.cls_only = callattr_clsonly, .null_on_nonexistent = false, .argspec = argspec };
return callattr(func.o, attr.getBox(), callattr_flags, args.size() > 0 ? args[0] : 0,
args.size() > 1 ? args[1] : 0, args.size() > 2 ? args[2] : 0, args.size() > 3 ? &args[3] : 0,
&keywords);
} else {
return runtimeCall(func.o, argspec, args.size() > 0 ? args[0] : 0, args.size() > 1 ? args[1] : 0,
args.size() > 2 ? args[2] : 0, args.size() > 3 ? &args[3] : 0, &keywords);
......
......@@ -236,7 +236,7 @@ public:
const std::vector<CompilerVariable*>& args,
const std::vector<BoxedString*>* keyword_names) override;
CompilerVariable* callattr(IREmitter& emitter, const OpInfo& info, ConcreteCompilerVariable* var, BoxedString* attr,
CallattrFlags flags, ArgPassSpec argspec, const std::vector<CompilerVariable*>& args,
CallattrFlags flags, const std::vector<CompilerVariable*>& args,
const std::vector<BoxedString*>* keyword_names) override;
ConcreteCompilerVariable* nonzero(IREmitter& emitter, const OpInfo& info, ConcreteCompilerVariable* var) override;
ConcreteCompilerVariable* hasnext(IREmitter& emitter, const OpInfo& info, ConcreteCompilerVariable* var) override;
......@@ -359,8 +359,8 @@ public:
CompilerVariable* getPystonIter(IREmitter& emitter, const OpInfo& info, ConcreteCompilerVariable* var) override {
static BoxedString* iter_box = static_cast<BoxedString*>(PyString_InternFromString("__iter__"));
CallattrFlags flags = {.cls_only = true, .null_on_nonexistent = true };
CompilerVariable* iter_call = var->callattr(emitter, info, iter_box, flags, ArgPassSpec(0), {}, 0);
CallattrFlags flags = {.cls_only = true, .null_on_nonexistent = true, .argspec = ArgPassSpec(0) };
CompilerVariable* iter_call = var->callattr(emitter, info, iter_box, flags, {}, 0);
ConcreteCompilerVariable* converted_iter_call = iter_call->makeConverted(emitter, iter_call->getBoxType());
// If the type analysis could determine the iter type is a valid pyston iter (has 'hasnext') we are finished.
......@@ -657,11 +657,11 @@ CompilerVariable* UnknownType::call(IREmitter& emitter, const OpInfo& info, Conc
}
CompilerVariable* UnknownType::callattr(IREmitter& emitter, const OpInfo& info, ConcreteCompilerVariable* var,
BoxedString* attr, CallattrFlags flags, ArgPassSpec argspec,
BoxedString* attr, CallattrFlags flags,
const std::vector<CompilerVariable*>& args,
const std::vector<BoxedString*>* keyword_names) {
bool pass_keywords = (argspec.num_keywords != 0);
int npassed_args = argspec.totalPassed();
bool pass_keywords = (flags.argspec.num_keywords != 0);
int npassed_args = flags.argspec.totalPassed();
llvm::Value* func;
if (pass_keywords)
......@@ -680,11 +680,8 @@ CompilerVariable* UnknownType::callattr(IREmitter& emitter, const OpInfo& info,
std::vector<llvm::Value*> other_args;
other_args.push_back(var->getValue());
other_args.push_back(embedRelocatablePtr(attr, g.llvm_boxedstring_type_ptr));
other_args.push_back(getConstantInt(flags.asInt(), g.i8));
llvm::Value* llvm_argspec = llvm::ConstantInt::get(g.i32, argspec.asInt(), false);
other_args.push_back(llvm_argspec);
return _call(emitter, info, func, (void*)pyston::callattr, other_args, argspec, args, keyword_names, UNKNOWN);
other_args.push_back(getConstantInt(flags.asInt(), g.i64));
return _call(emitter, info, func, (void*)pyston::callattr, other_args, flags.argspec, args, keyword_names, UNKNOWN);
}
ConcreteCompilerVariable* UnknownType::nonzero(IREmitter& emitter, const OpInfo& info, ConcreteCompilerVariable* var) {
......@@ -917,10 +914,10 @@ public:
}
CompilerVariable* callattr(IREmitter& emitter, const OpInfo& info, ConcreteCompilerVariable* var, BoxedString* attr,
CallattrFlags flags, ArgPassSpec argspec, const std::vector<CompilerVariable*>& args,
CallattrFlags flags, const std::vector<CompilerVariable*>& args,
const std::vector<BoxedString*>* keyword_names) override {
ConcreteCompilerVariable* converted = var->makeConverted(emitter, BOXED_INT);
CompilerVariable* rtn = converted->callattr(emitter, info, attr, flags, argspec, args, keyword_names);
CompilerVariable* rtn = converted->callattr(emitter, info, attr, flags, args, keyword_names);
converted->decvref(emitter);
return rtn;
}
......@@ -1161,10 +1158,10 @@ public:
}
CompilerVariable* callattr(IREmitter& emitter, const OpInfo& info, ConcreteCompilerVariable* var, BoxedString* attr,
CallattrFlags flags, ArgPassSpec argspec, const std::vector<CompilerVariable*>& args,
CallattrFlags flags, const std::vector<CompilerVariable*>& args,
const std::vector<BoxedString*>* keyword_names) override {
ConcreteCompilerVariable* converted = var->makeConverted(emitter, BOXED_FLOAT);
CompilerVariable* rtn = converted->callattr(emitter, info, attr, flags, argspec, args, keyword_names);
CompilerVariable* rtn = converted->callattr(emitter, info, attr, flags, args, keyword_names);
converted->decvref(emitter);
return rtn;
}
......@@ -1645,15 +1642,15 @@ public:
}
CompilerVariable* callattr(IREmitter& emitter, const OpInfo& info, ConcreteCompilerVariable* var, BoxedString* attr,
CallattrFlags flags, ArgPassSpec argspec, const std::vector<CompilerVariable*>& args,
CallattrFlags flags, const std::vector<CompilerVariable*>& args,
const std::vector<BoxedString*>* keyword_names) override {
ConcreteCompilerVariable* called_constant
= tryCallattrConstant(emitter, info, var, attr, flags.cls_only, argspec, args, keyword_names);
= tryCallattrConstant(emitter, info, var, attr, flags.cls_only, flags.argspec, args, keyword_names);
if (called_constant)
return called_constant;
ConcreteCompilerVariable* converted = var->makeConverted(emitter, UNKNOWN);
CompilerVariable* rtn = converted->callattr(emitter, info, attr, flags, argspec, args, keyword_names);
CompilerVariable* rtn = converted->callattr(emitter, info, attr, flags, args, keyword_names);
converted->decvref(emitter);
return rtn;
}
......@@ -1902,10 +1899,10 @@ public:
}
CompilerVariable* callattr(IREmitter& emitter, const OpInfo& info, VAR* var, BoxedString* attr, CallattrFlags flags,
ArgPassSpec argspec, const std::vector<CompilerVariable*>& args,
const std::vector<CompilerVariable*>& args,
const std::vector<BoxedString*>* keyword_names) override {
ConcreteCompilerVariable* converted = var->makeConverted(emitter, STR);
CompilerVariable* rtn = converted->callattr(emitter, info, attr, flags, argspec, args, keyword_names);
CompilerVariable* rtn = converted->callattr(emitter, info, attr, flags, args, keyword_names);
converted->decvref(emitter);
return rtn;
}
......@@ -2036,10 +2033,10 @@ public:
}
CompilerVariable* callattr(IREmitter& emitter, const OpInfo& info, ConcreteCompilerVariable* var, BoxedString* attr,
CallattrFlags flags, ArgPassSpec argspec, const std::vector<CompilerVariable*>& args,
CallattrFlags flags, const std::vector<CompilerVariable*>& args,
const std::vector<BoxedString*>* keyword_names) override {
ConcreteCompilerVariable* converted = var->makeConverted(emitter, BOXED_BOOL);
CompilerVariable* rtn = converted->callattr(emitter, info, attr, flags, argspec, args, keyword_names);
CompilerVariable* rtn = converted->callattr(emitter, info, attr, flags, args, keyword_names);
converted->decvref(emitter);
return rtn;
}
......@@ -2216,10 +2213,10 @@ public:
}
CompilerVariable* callattr(IREmitter& emitter, const OpInfo& info, VAR* var, BoxedString* attr, CallattrFlags flags,
ArgPassSpec argspec, const std::vector<CompilerVariable*>& args,
const std::vector<CompilerVariable*>& args,
const std::vector<BoxedString*>* keyword_names) override {
return makeConverted(emitter, var, getConcreteType())
->callattr(emitter, info, attr, flags, argspec, args, keyword_names);
->callattr(emitter, info, attr, flags, args, keyword_names);
}
void serializeToFrame(VAR* var, std::vector<llvm::Value*>& stackmap_args) override {
......@@ -2320,7 +2317,7 @@ public:
}
CompilerVariable* callattr(IREmitter& emitter, const OpInfo& info, VAR* var, BoxedString* attr, CallattrFlags flags,
ArgPassSpec argspec, const std::vector<CompilerVariable*>& args,
const std::vector<CompilerVariable*>& args,
const std::vector<BoxedString*>* keyword_names) override {
return undefVariable();
}
......
......@@ -124,8 +124,7 @@ public:
}
virtual CompilerVariable* callattr(IREmitter& emitter, const OpInfo& info, VAR* var, BoxedString* attr,
CallattrFlags flags, struct ArgPassSpec argspec,
const std::vector<CompilerVariable*>& args,
CallattrFlags flags, const std::vector<CompilerVariable*>& args,
const std::vector<BoxedString*>* keyword_names) {
printf("callattr not defined for %s\n", debugName().c_str());
abort();
......@@ -268,7 +267,7 @@ public:
virtual void setattr(IREmitter& emitter, const OpInfo& info, BoxedString* attr, CompilerVariable* v) = 0;
virtual void delattr(IREmitter& emitter, const OpInfo& info, BoxedString* attr) = 0;
virtual CompilerVariable* callattr(IREmitter& emitter, const OpInfo& info, BoxedString* attr, CallattrFlags flags,
struct ArgPassSpec argspec, const std::vector<CompilerVariable*>& args,
const std::vector<CompilerVariable*>& args,
const std::vector<BoxedString*>* keyword_names) = 0;
virtual CompilerVariable* call(IREmitter& emitter, const OpInfo& info, struct ArgPassSpec argspec,
const std::vector<CompilerVariable*>& args,
......@@ -348,9 +347,9 @@ public:
}
CompilerVariable* callattr(IREmitter& emitter, const OpInfo& info, BoxedString* attr, CallattrFlags flags,
struct ArgPassSpec argspec, const std::vector<CompilerVariable*>& args,
const std::vector<CompilerVariable*>& args,
const std::vector<BoxedString*>* keyword_names) override {
return type->callattr(emitter, info, this, attr, flags, argspec, args, keyword_names);
return type->callattr(emitter, info, this, attr, flags, args, keyword_names);
}
CompilerVariable* call(IREmitter& emitter, const OpInfo& info, struct ArgPassSpec argspec,
const std::vector<CompilerVariable*>& args,
......
......@@ -873,9 +873,8 @@ private:
CompilerVariable* rtn;
if (is_callattr) {
CallattrFlags flags = {.cls_only = callattr_clsonly, .null_on_nonexistent = false };
rtn = func->callattr(emitter, getOpInfoForNode(node, unw_info), attr.getBox(), flags, argspec, args,
keyword_names);
CallattrFlags flags = {.cls_only = callattr_clsonly, .null_on_nonexistent = false, .argspec = argspec };
rtn = func->callattr(emitter, getOpInfoForNode(node, unw_info), attr.getBox(), flags, args, keyword_names);
} else {
rtn = func->call(emitter, getOpInfoForNode(node, unw_info), argspec, args, keyword_names);
}
......@@ -1138,9 +1137,9 @@ private:
for (int i = 0; i < node->elts.size(); i++) {
CompilerVariable* elt = elts[i];
CallattrFlags flags = {.cls_only = true, .null_on_nonexistent = false };
CompilerVariable* r = rtn->callattr(emitter, getOpInfoForNode(node, unw_info), add_str, flags,
ArgPassSpec(1), { elt }, NULL);
CallattrFlags flags = {.cls_only = true, .null_on_nonexistent = false, .argspec = ArgPassSpec(1) };
CompilerVariable* r
= rtn->callattr(emitter, getOpInfoForNode(node, unw_info), add_str, flags, { elt }, NULL);
r->decvref(emitter);
elt->decvref(emitter);
}
......@@ -1907,9 +1906,9 @@ private:
curblock = ss_block;
emitter.getBuilder()->SetInsertPoint(ss_block);
CallattrFlags flags = {.cls_only = false, .null_on_nonexistent = false };
auto r = dest->callattr(emitter, getOpInfoForNode(node, unw_info), write_str, flags, ArgPassSpec(1),
{ makeStr(space_str) }, NULL);
CallattrFlags flags = {.cls_only = false, .null_on_nonexistent = false, .argspec = ArgPassSpec(1) };
auto r = dest->callattr(emitter, getOpInfoForNode(node, unw_info), write_str, flags, { makeStr(space_str) },
NULL);
r->decvref(emitter);
emitter.getBuilder()->CreateBr(join_block);
......@@ -1921,16 +1920,15 @@ private:
llvm::Value* v = emitter.createCall(unw_info, g.funcs.strOrUnicode, converted->getValue());
v = emitter.getBuilder()->CreateBitCast(v, g.llvm_value_type_ptr);
auto s = new ConcreteCompilerVariable(STR, v, true);
r = dest->callattr(emitter, getOpInfoForNode(node, unw_info), write_str, flags, ArgPassSpec(1), { s },
NULL);
r = dest->callattr(emitter, getOpInfoForNode(node, unw_info), write_str, flags, { s }, NULL);
s->decvref(emitter);
r->decvref(emitter);
converted->decvref(emitter);
}
if (node->nl) {
CallattrFlags flags = {.cls_only = false, .null_on_nonexistent = false };
auto r = dest->callattr(emitter, getOpInfoForNode(node, unw_info), write_str, flags, ArgPassSpec(1),
CallattrFlags flags = {.cls_only = false, .null_on_nonexistent = false, .argspec = ArgPassSpec(1) };
auto r = dest->callattr(emitter, getOpInfoForNode(node, unw_info), write_str, flags,
{ makeStr(newline_str) }, NULL);
r->decvref(emitter);
......
......@@ -249,17 +249,17 @@ void initGlobalFuncs(GlobalState& g) {
g.llvm_value_type_ptr, g.llvm_value_type_ptr, g.llvm_value_type_ptr->getPointerTo());
g.funcs.callattr = getFunc((void*)callattr, "callattr");
g.funcs.callattr0 = addFunc((void*)callattr, g.llvm_value_type_ptr, g.llvm_value_type_ptr,
g.llvm_boxedstring_type_ptr, g.i1, g.i32);
g.funcs.callattr0
= addFunc((void*)callattr, g.llvm_value_type_ptr, g.llvm_value_type_ptr, g.llvm_boxedstring_type_ptr, g.i64);
g.funcs.callattr1 = addFunc((void*)callattr, g.llvm_value_type_ptr, g.llvm_value_type_ptr,
g.llvm_boxedstring_type_ptr, g.i1, g.i32, g.llvm_value_type_ptr);
g.llvm_boxedstring_type_ptr, g.i64, g.llvm_value_type_ptr);
g.funcs.callattr2 = addFunc((void*)callattr, g.llvm_value_type_ptr, g.llvm_value_type_ptr,
g.llvm_boxedstring_type_ptr, g.i1, g.i32, g.llvm_value_type_ptr, g.llvm_value_type_ptr);
g.llvm_boxedstring_type_ptr, g.i64, g.llvm_value_type_ptr, g.llvm_value_type_ptr);
g.funcs.callattr3
= addFunc((void*)callattr, g.llvm_value_type_ptr, g.llvm_value_type_ptr, g.llvm_boxedstring_type_ptr, g.i1,
g.i32, g.llvm_value_type_ptr, g.llvm_value_type_ptr, g.llvm_value_type_ptr);
= addFunc((void*)callattr, g.llvm_value_type_ptr, g.llvm_value_type_ptr, g.llvm_boxedstring_type_ptr, g.i64,
g.llvm_value_type_ptr, g.llvm_value_type_ptr, g.llvm_value_type_ptr);
g.funcs.callattrN = addFunc((void*)callattr, g.llvm_value_type_ptr, g.llvm_value_type_ptr,
g.llvm_boxedstring_type_ptr, g.i1, g.i32, g.llvm_value_type_ptr, g.llvm_value_type_ptr,
g.llvm_boxedstring_type_ptr, g.i64, g.llvm_value_type_ptr, g.llvm_value_type_ptr,
g.llvm_value_type_ptr, g.llvm_value_type_ptr->getPointerTo());
g.funcs.reoptCompiledFunc = addFunc((void*)reoptCompiledFunc, g.i8_ptr, g.i8_ptr);
......
......@@ -745,9 +745,11 @@ struct FrameInfo {
struct CallattrFlags {
bool cls_only : 1;
bool null_on_nonexistent : 1;
ArgPassSpec argspec;
char asInt() { return (cls_only << 0) + (null_on_nonexistent << 1); }
uint64_t asInt() { return (uint64_t(argspec.asInt()) << 32) | (cls_only << 0) | (null_on_nonexistent << 1); }
};
static_assert(sizeof(CallattrFlags) == sizeof(uint64_t), "");
}
namespace std {
......
......@@ -95,15 +95,15 @@ extern "C" Box* abs_(Box* x) {
return longAbs(static_cast<BoxedLong*>(x));
} else {
static BoxedString* abs_str = static_cast<BoxedString*>(PyString_InternFromString("__abs__"));
return callattr(x, abs_str, CallattrFlags({.cls_only = true, .null_on_nonexistent = false }), ArgPassSpec(0),
NULL, NULL, NULL, NULL, NULL);
CallattrFlags callattr_flags{.cls_only = true, .null_on_nonexistent = false, .argspec = ArgPassSpec(0) };
return callattr(x, abs_str, callattr_flags, NULL, NULL, NULL, NULL, NULL);
}
}
extern "C" Box* hexFunc(Box* x) {
static BoxedString* hex_str = static_cast<BoxedString*>(PyString_InternFromString("__hex__"));
Box* r = callattr(x, hex_str, CallattrFlags({.cls_only = true, .null_on_nonexistent = true }), ArgPassSpec(0), NULL,
NULL, NULL, NULL, NULL);
CallattrFlags callattr_flags{.cls_only = true, .null_on_nonexistent = true, .argspec = ArgPassSpec(0) };
Box* r = callattr(x, hex_str, callattr_flags, NULL, NULL, NULL, NULL, NULL);
if (!r)
raiseExcHelper(TypeError, "hex() argument can't be converted to hex");
......@@ -115,8 +115,8 @@ extern "C" Box* hexFunc(Box* x) {
extern "C" Box* octFunc(Box* x) {
static BoxedString* oct_str = static_cast<BoxedString*>(PyString_InternFromString("__oct__"));
Box* r = callattr(x, oct_str, CallattrFlags({.cls_only = true, .null_on_nonexistent = true }), ArgPassSpec(0), NULL,
NULL, NULL, NULL, NULL);
CallattrFlags callattr_flags{.cls_only = true, .null_on_nonexistent = true, .argspec = ArgPassSpec(0) };
Box* r = callattr(x, oct_str, callattr_flags, NULL, NULL, NULL, NULL, NULL);
if (!r)
raiseExcHelper(TypeError, "oct() argument can't be converted to oct");
......@@ -209,8 +209,8 @@ extern "C" Box* max(Box* arg0, BoxedTuple* args) {
extern "C" Box* next(Box* iterator, Box* _default) {
try {
static BoxedString* next_str = static_cast<BoxedString*>(PyString_InternFromString("next"));
return callattr(iterator, next_str, CallattrFlags({.cls_only = true, .null_on_nonexistent = false }),
ArgPassSpec(0), NULL, NULL, NULL, NULL, NULL);
CallattrFlags callattr_flags{.cls_only = true, .null_on_nonexistent = false, .argspec = ArgPassSpec(0) };
return callattr(iterator, next_str, callattr_flags, NULL, NULL, NULL, NULL, NULL);
} catch (ExcInfo e) {
if (_default && e.matches(StopIteration))
return _default;
......@@ -882,27 +882,23 @@ Box* print(BoxedTuple* args, BoxedDict* kwargs) {
RELEASE_ASSERT(kwargs->d.size() == 0, "print() got unexpected keyword arguments");
static BoxedString* write_str = static_cast<BoxedString*>(PyString_InternFromString("write"));
CallattrFlags callattr_flags{.cls_only = false, .null_on_nonexistent = false, .argspec = ArgPassSpec(1) };
// TODO softspace handling?
// TODO: duplicates code with ASTInterpreter::visit_print()
bool first = true;
for (auto e : *args) {
BoxedString* s = str(e);
if (!first) {
Box* r = callattr(dest, write_str, CallattrFlags({.cls_only = false, .null_on_nonexistent = false }),
ArgPassSpec(1), space_str, NULL, NULL, NULL, NULL);
Box* r = callattr(dest, write_str, callattr_flags, space_str, NULL, NULL, NULL, NULL);
RELEASE_ASSERT(r, "");
}
first = false;
Box* r = callattr(dest, write_str, CallattrFlags({.cls_only = false, .null_on_nonexistent = false }),
ArgPassSpec(1), s, NULL, NULL, NULL, NULL);
Box* r = callattr(dest, write_str, callattr_flags, s, NULL, NULL, NULL, NULL);
RELEASE_ASSERT(r, "");
}
Box* r = callattr(dest, write_str, CallattrFlags({.cls_only = false, .null_on_nonexistent = false }),
ArgPassSpec(1), end, NULL, NULL, NULL, NULL);
Box* r = callattr(dest, write_str, callattr_flags, end, NULL, NULL, NULL, NULL);
RELEASE_ASSERT(r, "");
return None;
......@@ -912,8 +908,8 @@ Box* getreversed(Box* o) {
static BoxedString* reversed_str = static_cast<BoxedString*>(PyString_InternFromString("__reversed__"));
// TODO add rewriting to this? probably want to try to avoid this path though
Box* r = callattr(o, reversed_str, CallattrFlags({.cls_only = true, .null_on_nonexistent = true }), ArgPassSpec(0),
NULL, NULL, NULL, NULL, NULL);
CallattrFlags callattr_flags{.cls_only = true, .null_on_nonexistent = true, .argspec = ArgPassSpec(0) };
Box* r = callattr(o, reversed_str, callattr_flags, NULL, NULL, NULL, NULL, NULL);
if (r)
return r;
......
......@@ -205,8 +205,8 @@ void appendToSysPath(llvm::StringRef path) {
void prependToSysPath(llvm::StringRef path) {
BoxedList* sys_path = getSysPath();
static BoxedString* insert_str = static_cast<BoxedString*>(PyString_InternFromString("insert"));
callattr(sys_path, insert_str, CallattrFlags({.cls_only = false, .null_on_nonexistent = false }), ArgPassSpec(2),
boxInt(0), boxString(path), NULL, NULL, NULL);
CallattrFlags callattr_flags{.cls_only = false, .null_on_nonexistent = false, .argspec = ArgPassSpec(2) };
callattr(sys_path, insert_str, callattr_flags, boxInt(0), boxString(path), NULL, NULL, NULL);
}
static BoxedClass* sys_flags_cls;
......
......@@ -657,8 +657,8 @@ static Box* instanceHash(BoxedInstance* inst) {
res = runtimeCall(func, ArgPassSpec(0), NULL, NULL, NULL, NULL, NULL);
if (PyInt_Check(res) || PyLong_Check(res)) {
return callattr(res, hash_str, CallattrFlags({.cls_only = true, .null_on_nonexistent = false }), ArgPassSpec(0),
nullptr, nullptr, nullptr, nullptr, nullptr);
CallattrFlags callattr_flags{.cls_only = true, .null_on_nonexistent = false, .argspec = ArgPassSpec(0) };
return callattr(res, hash_str, callattr_flags, nullptr, nullptr, nullptr, nullptr, nullptr);
} else {
raiseExcHelper(TypeError, "__hash__() should return an int");
}
......
......@@ -192,8 +192,8 @@ Box* dictGetitem(BoxedDict* self, Box* k) {
// Try calling __missing__ if this is a subclass
if (self->cls != dict_cls) {
static BoxedString* missing_str = static_cast<BoxedString*>(PyString_InternFromString("__missing__"));
Box* r = callattr(self, missing_str, CallattrFlags({.cls_only = true, .null_on_nonexistent = true }),
ArgPassSpec(1), k, NULL, NULL, NULL, NULL);
CallattrFlags callattr_flags{.cls_only = true, .null_on_nonexistent = true, .argspec = ArgPassSpec(1) };
Box* r = callattr(self, missing_str, callattr_flags, k, NULL, NULL, NULL, NULL);
if (r)
return r;
}
......@@ -519,8 +519,8 @@ void dictMerge(BoxedDict* self, Box* other) {
}
static BoxedString* keys_str = static_cast<BoxedString*>(PyString_InternFromString("keys"));
Box* keys = callattr(other, keys_str, CallattrFlags({.cls_only = false, .null_on_nonexistent = true }),
ArgPassSpec(0), NULL, NULL, NULL, NULL, NULL);
CallattrFlags callattr_flags{.cls_only = false, .null_on_nonexistent = true, .argspec = ArgPassSpec(0) };
Box* keys = callattr(other, keys_str, callattr_flags, NULL, NULL, NULL, NULL, NULL);
assert(keys);
for (Box* k : keys->pyElements()) {
......
......@@ -652,8 +652,8 @@ BoxedFloat* _floatNew(Box* a) {
return new BoxedFloat(r);
} else {
static BoxedString* float_str = static_cast<BoxedString*>(PyString_InternFromString("__float__"));
Box* r = callattr(a, float_str, CallattrFlags({.cls_only = true, .null_on_nonexistent = true }), ArgPassSpec(0),
NULL, NULL, NULL, NULL, NULL);
CallattrFlags callattr_flags{.cls_only = true, .null_on_nonexistent = true, .argspec = ArgPassSpec(0) };
Box* r = callattr(a, float_str, callattr_flags, NULL, NULL, NULL, NULL, NULL);
if (!r) {
fprintf(stderr, "TypeError: float() argument must be a string or a number, not '%s'\n", getTypeName(a));
......
......@@ -70,9 +70,9 @@ class CallattrIC : public RuntimeIC {
public:
CallattrIC() : RuntimeIC((void*)callattr, 1, 160) {}
Box* call(Box* obj, BoxedString* attr, CallattrFlags flags, ArgPassSpec spec, Box* arg0, Box* arg1, Box* arg2,
Box** args, const std::vector<BoxedString*>* keyword_names) {
return (Box*)call_ptr(obj, attr, flags, spec, arg0, arg1, arg2, args, keyword_names);
Box* call(Box* obj, BoxedString* attr, CallattrFlags flags, Box* arg0, Box* arg1, Box* arg2, Box** args,
const std::vector<BoxedString*>* keyword_names) {
return (Box*)call_ptr(obj, attr, flags, arg0, arg1, arg2, args, keyword_names);
}
};
......
......@@ -192,9 +192,9 @@ SearchResult findModule(const std::string& name, const std::string& full_name, B
Box* finder = meta_path->elts->elts[i];
auto path_pass = path_list ? path_list : None;
CallattrFlags callattr_flags{.cls_only = false, .null_on_nonexistent = false, .argspec = ArgPassSpec(2) };
Box* loader
= callattr(finder, findmodule_str, CallattrFlags({.cls_only = false, .null_on_nonexistent = false }),
ArgPassSpec(2), boxString(full_name), path_pass, NULL, NULL, NULL);
= callattr(finder, findmodule_str, callattr_flags, boxString(full_name), path_pass, NULL, NULL, NULL);
if (loader != None)
return SearchResult(loader);
......@@ -234,9 +234,9 @@ SearchResult findModule(const std::string& name, const std::string& full_name, B
return SearchResult("", SearchResult::SEARCH_ERROR);
if (importer != None) {
CallattrFlags callattr_flags{.cls_only = false, .null_on_nonexistent = false, .argspec = ArgPassSpec(1) };
Box* loader
= callattr(importer, findmodule_str, CallattrFlags({.cls_only = false, .null_on_nonexistent = false }),
ArgPassSpec(1), boxString(full_name), NULL, NULL, NULL, NULL);
= callattr(importer, findmodule_str, callattr_flags, boxString(full_name), NULL, NULL, NULL, NULL);
if (loader != None)
return SearchResult(loader);
}
......@@ -399,9 +399,11 @@ static Box* importSub(const std::string& name, const std::string& full_name, Box
else if (sr.type == SearchResult::IMP_HOOK) {
static BoxedString* loadmodule_str
= static_cast<BoxedString*>(PyString_InternFromString("load_module"));
module = callattr(sr.loader, loadmodule_str,
CallattrFlags({.cls_only = false, .null_on_nonexistent = false }), ArgPassSpec(1),
boxString(full_name), NULL, NULL, NULL, NULL);
CallattrFlags callattr_flags{.cls_only = false,
.null_on_nonexistent = false,
.argspec = ArgPassSpec(1) };
module
= callattr(sr.loader, loadmodule_str, callattr_flags, boxString(full_name), NULL, NULL, NULL, NULL);
} else
RELEASE_ASSERT(0, "%d", sr.type);
} catch (ExcInfo e) {
......
......@@ -895,8 +895,8 @@ static Box* _intNew(Box* val, Box* base) {
} else {
RELEASE_ASSERT(!base, "");
static BoxedString* int_str = static_cast<BoxedString*>(PyString_InternFromString("__int__"));
Box* r = callattr(val, int_str, CallattrFlags({.cls_only = true, .null_on_nonexistent = true }), ArgPassSpec(0),
NULL, NULL, NULL, NULL, NULL);
CallattrFlags callattr_flags{.cls_only = true, .null_on_nonexistent = true, .argspec = ArgPassSpec(0) };
Box* r = callattr(val, int_str, callattr_flags, NULL, NULL, NULL, NULL, NULL);
if (!r) {
fprintf(stderr, "TypeError: int() argument must be a string or a number, not '%s'\n", getTypeName(val));
......
......@@ -135,8 +135,8 @@ bool iterwrapperHasnextUnboxed(Box* s) {
static BoxedString* next_str = static_cast<BoxedString*>(PyString_InternFromString("next"));
Box* next;
try {
next = callattr(self->iter, next_str, CallattrFlags({.cls_only = true, .null_on_nonexistent = false }),
ArgPassSpec(0), NULL, NULL, NULL, NULL, NULL);
CallattrFlags callattr_flags{.cls_only = true, .null_on_nonexistent = false, .argspec = ArgPassSpec(0) };
next = callattr(self->iter, next_str, callattr_flags, NULL, NULL, NULL, NULL, NULL);
} catch (ExcInfo e) {
if (e.matches(StopIteration)) {
self->next = NULL;
......
......@@ -635,8 +635,8 @@ BoxedLong* _longNew(Box* val, Box* _base) {
mpz_init_set_si(rtn->n, static_cast<BoxedFloat*>(val)->d);
} else {
static BoxedString* long_str = static_cast<BoxedString*>(PyString_InternFromString("__long__"));
Box* r = callattr(val, long_str, CallattrFlags({.cls_only = true, .null_on_nonexistent = true }),
ArgPassSpec(0), NULL, NULL, NULL, NULL, NULL);
CallattrFlags callattr_flags{.cls_only = true, .null_on_nonexistent = true, .argspec = ArgPassSpec(0) };
Box* r = callattr(val, long_str, callattr_flags, NULL, NULL, NULL, NULL, NULL);
if (!r) {
fprintf(stderr, "TypeError: long() argument must be a string or a number, not '%s'\n",
......
......@@ -2720,8 +2720,8 @@ extern "C" Box* callattrInternal(Box* obj, BoxedString* attr, LookupScope scope,
}
}
extern "C" Box* callattr(Box* obj, BoxedString* attr, CallattrFlags flags, ArgPassSpec argspec, Box* arg1, Box* arg2,
Box* arg3, Box** args, const std::vector<BoxedString*>* keyword_names) {
extern "C" Box* callattr(Box* obj, BoxedString* attr, CallattrFlags flags, Box* arg1, Box* arg2, Box* arg3, Box** args,
const std::vector<BoxedString*>* keyword_names) {
STAT_TIMER(t0, "us_timer_slowpath_callattr", 10);
#if 0
static uint64_t* st_id = Stats::getStatCounter("us_timer_slowpath_callattr_patchable");
......@@ -2732,6 +2732,7 @@ extern "C" Box* callattr(Box* obj, BoxedString* attr, CallattrFlags flags, ArgPa
ASSERT(gc::isValidGCObject(obj), "%p", obj);
ArgPassSpec argspec(flags.argspec);
int npassed_args = argspec.totalPassed();
static StatCounter slowpath_callattr("slowpath_callattr");
......@@ -2765,13 +2766,13 @@ extern "C" Box* callattr(Box* obj, BoxedString* attr, CallattrFlags flags, ArgPa
CallRewriteArgs rewrite_args(rewriter.get(), rewriter->getArg(0), rewriter->getReturnDestination());
if (npassed_args >= 1)
rewrite_args.arg1 = rewriter->getArg(4);
rewrite_args.arg1 = rewriter->getArg(3);
if (npassed_args >= 2)
rewrite_args.arg2 = rewriter->getArg(5);
rewrite_args.arg2 = rewriter->getArg(4);
if (npassed_args >= 3)
rewrite_args.arg3 = rewriter->getArg(6);
rewrite_args.arg3 = rewriter->getArg(5);
if (npassed_args >= 4)
rewrite_args.args = rewriter->getArg(7);
rewrite_args.args = rewriter->getArg(6);
rtn = callattrInternal(obj, attr, scope, &rewrite_args, argspec, arg1, arg2, arg3, args, keyword_names);
if (!rewrite_args.out_success) {
......@@ -4586,8 +4587,9 @@ Box* typeNew(Box* _cls, Box* arg1, Box* arg2, Box** _args) {
static BoxedString* new_box = static_cast<BoxedString*>(PyString_InternFromString(new_str.c_str()));
if (winner != metatype) {
if (getattr(winner, new_box) != getattr(type_cls, new_box)) {
return callattr(winner, new_box, CallattrFlags({.cls_only = false, .null_on_nonexistent = false }),
ArgPassSpec(4), winner, arg1, arg2, _args, NULL);
CallattrFlags callattr_flags
= {.cls_only = false, .null_on_nonexistent = false, .argspec = ArgPassSpec(4) };
return callattr(winner, new_box, callattr_flags, winner, arg1, arg2, _args, NULL);
}
metatype = winner;
}
......
......@@ -58,8 +58,7 @@ extern "C" void delattrMaybeNonstring(Box* obj, Box* attr);
extern "C" void delattrGeneric(Box* obj, BoxedString* attr, DelattrRewriteArgs* rewrite_args);
extern "C" bool nonzero(Box* obj);
extern "C" Box* runtimeCall(Box*, ArgPassSpec, Box*, Box*, Box*, Box**, const std::vector<BoxedString*>*);
extern "C" Box* callattr(Box*, BoxedString*, CallattrFlags, ArgPassSpec, Box*, Box*, Box*, Box**,
const std::vector<BoxedString*>*);
extern "C" Box* callattr(Box*, BoxedString*, CallattrFlags, Box*, Box*, Box*, Box**, const std::vector<BoxedString*>*);
extern "C" BoxedString* str(Box* obj);
extern "C" BoxedString* repr(Box* obj);
extern "C" BoxedString* reprOrNull(Box* obj); // similar to repr, but returns NULL on exception
......
......@@ -234,8 +234,9 @@ Box* BoxedClass::callHasnextIC(Box* obj, bool null_on_nonexistent) {
}
static BoxedString* hasnext_str = static_cast<BoxedString*>(PyString_InternFromString("__hasnext__"));
return ic->call(obj, hasnext_str, CallattrFlags({.cls_only = true, .null_on_nonexistent = null_on_nonexistent }),
ArgPassSpec(0), nullptr, nullptr, nullptr, nullptr, nullptr);
CallattrFlags callattr_flags
= {.cls_only = true, .null_on_nonexistent = null_on_nonexistent, .argspec = ArgPassSpec(0) };
return ic->call(obj, hasnext_str, callattr_flags, nullptr, nullptr, nullptr, nullptr, nullptr);
}
Box* BoxedClass::callNextIC(Box* obj) {
......@@ -248,8 +249,8 @@ Box* BoxedClass::callNextIC(Box* obj) {
}
static BoxedString* next_str = static_cast<BoxedString*>(PyString_InternFromString("next"));
return ic->call(obj, next_str, CallattrFlags({.cls_only = true, .null_on_nonexistent = false }), ArgPassSpec(0),
nullptr, nullptr, nullptr, nullptr, nullptr);
CallattrFlags callattr_flags{.cls_only = true, .null_on_nonexistent = false, .argspec = ArgPassSpec(0) };
return ic->call(obj, next_str, callattr_flags, nullptr, nullptr, nullptr, nullptr, nullptr);
}
Box* BoxedClass::callReprIC(Box* obj) {
......@@ -262,8 +263,8 @@ Box* BoxedClass::callReprIC(Box* obj) {
}
static BoxedString* repr_str = static_cast<BoxedString*>(PyString_InternFromString("__repr__"));
return ic->call(obj, repr_str, CallattrFlags({.cls_only = true, .null_on_nonexistent = false }), ArgPassSpec(0),
nullptr, nullptr, nullptr, nullptr, nullptr);
CallattrFlags callattr_flags{.cls_only = true, .null_on_nonexistent = false, .argspec = ArgPassSpec(0) };
return ic->call(obj, repr_str, callattr_flags, nullptr, nullptr, nullptr, nullptr, nullptr);
}
bool BoxedClass::callNonzeroIC(Box* obj) {
......
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