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