Commit 5a81a329 authored by Kevin Modzelewski's avatar Kevin Modzelewski

Consolidate param info into ParamReceiveSpec

Similar to ArgPassSpec.  Previously we kept them on the CLFunction,
but there are places where we want to specify a certain parameter
signature without having a clfunction available.
parent 52924ca9
...@@ -828,7 +828,7 @@ public: ...@@ -828,7 +828,7 @@ public:
Sig* type_sig = new Sig(); Sig* type_sig = new Sig();
type_sig->rtn_type = fspec->rtn_type; type_sig->rtn_type = fspec->rtn_type;
type_sig->ndefaults = clf->num_defaults; type_sig->ndefaults = clf->paramspec.num_defaults;
if (stripfirst) { if (stripfirst) {
assert(fspec->arg_types.size() >= 1); assert(fspec->arg_types.size() >= 1);
...@@ -1545,12 +1545,14 @@ public: ...@@ -1545,12 +1545,14 @@ public:
CLFunction* cl = rtattr_func->f; CLFunction* cl = rtattr_func->f;
assert(cl); assert(cl);
if (cl->takes_varargs || cl->takes_kwargs) ParamReceiveSpec paramspec = cl->paramspec;
if (paramspec.takes_varargs || paramspec.takes_kwargs)
return NULL; return NULL;
RELEASE_ASSERT(cl->num_args == cl->numReceivedArgs(), ""); RELEASE_ASSERT(paramspec.num_args == cl->numReceivedArgs(), "");
RELEASE_ASSERT(args.size() + 1 >= cl->num_args - cl->num_defaults && args.size() + 1 <= cl->num_args, "%d", RELEASE_ASSERT(args.size() + 1 >= paramspec.num_args - paramspec.num_defaults
info.unw_info.current_stmt->lineno); && args.size() + 1 <= paramspec.num_args,
"%d", info.unw_info.current_stmt->lineno);
CompiledFunction* cf = NULL; CompiledFunction* cf = NULL;
bool found = false; bool found = false;
...@@ -1578,8 +1580,8 @@ public: ...@@ -1578,8 +1580,8 @@ public:
assert(cf->code); assert(cf->code);
std::vector<llvm::Type*> arg_types; std::vector<llvm::Type*> arg_types;
RELEASE_ASSERT(cl->num_args == cl->numReceivedArgs(), ""); RELEASE_ASSERT(paramspec.num_args == cl->numReceivedArgs(), "");
for (int i = 0; i < cl->num_args; i++) { for (int i = 0; i < paramspec.num_args; i++) {
// TODO support passing unboxed values as arguments // TODO support passing unboxed values as arguments
assert(cf->spec->arg_types[i]->llvmType() == g.llvm_value_type_ptr); assert(cf->spec->arg_types[i]->llvmType() == g.llvm_value_type_ptr);
...@@ -1602,9 +1604,9 @@ public: ...@@ -1602,9 +1604,9 @@ public:
new_args.push_back(var); new_args.push_back(var);
new_args.insert(new_args.end(), args.begin(), args.end()); new_args.insert(new_args.end(), args.begin(), args.end());
for (int i = args.size() + 1; i < cl->num_args; i++) { for (int i = args.size() + 1; i < paramspec.num_args; i++) {
// TODO should _call() be able to take llvm::Value's directly? // TODO should _call() be able to take llvm::Value's directly?
auto value = rtattr_func->defaults->elts[i - cl->num_args + cl->num_defaults]; auto value = rtattr_func->defaults->elts[i - paramspec.num_args + paramspec.num_defaults];
llvm::Value* llvm_value; llvm::Value* llvm_value;
if (value) if (value)
llvm_value = embedRelocatablePtr(value, g.llvm_value_type_ptr); llvm_value = embedRelocatablePtr(value, g.llvm_value_type_ptr);
......
...@@ -38,44 +38,6 @@ class Value; ...@@ -38,44 +38,6 @@ class Value;
namespace pyston { namespace pyston {
struct ArgPassSpec {
bool has_starargs : 1;
bool has_kwargs : 1;
unsigned int num_keywords : 14;
unsigned int num_args : 16;
static const int MAX_ARGS = (1 << 16) - 1;
static const int MAX_KEYWORDS = (1 << 14) - 1;
explicit ArgPassSpec(int num_args) : has_starargs(false), has_kwargs(false), num_keywords(0), num_args(num_args) {
assert(num_args <= MAX_ARGS);
assert(num_keywords <= MAX_KEYWORDS);
}
explicit ArgPassSpec(int num_args, int num_keywords, bool has_starargs, bool has_kwargs)
: has_starargs(has_starargs), has_kwargs(has_kwargs), num_keywords(num_keywords), num_args(num_args) {
assert(num_args <= MAX_ARGS);
assert(num_keywords <= MAX_KEYWORDS);
}
bool operator==(ArgPassSpec rhs) {
return has_starargs == rhs.has_starargs && has_kwargs == rhs.has_kwargs && num_keywords == rhs.num_keywords
&& num_args == rhs.num_args;
}
bool operator!=(ArgPassSpec rhs) { return !(*this == rhs); }
int totalPassed() { return num_args + num_keywords + (has_starargs ? 1 : 0) + (has_kwargs ? 1 : 0); }
uint32_t asInt() const { return *reinterpret_cast<const uint32_t*>(this); }
void dump() {
printf("(has_starargs=%s, has_kwargs=%s, num_keywords=%d, num_args=%d)\n", has_starargs ? "true" : "false",
has_kwargs ? "true" : "false", num_keywords, num_args);
}
};
static_assert(sizeof(ArgPassSpec) <= sizeof(void*), "ArgPassSpec doesn't fit in register! (CC is probably wrong)");
static_assert(sizeof(ArgPassSpec) == sizeof(uint32_t), "ArgPassSpec::asInt needs to be updated");
namespace gc { namespace gc {
class TraceStack; class TraceStack;
...@@ -144,6 +106,92 @@ class ScopingAnalysis; ...@@ -144,6 +106,92 @@ class ScopingAnalysis;
class CLFunction; class CLFunction;
class OSREntryDescriptor; class OSREntryDescriptor;
struct ArgPassSpec {
bool has_starargs : 1;
bool has_kwargs : 1;
unsigned int num_keywords : 14;
unsigned int num_args : 16;
static const int MAX_ARGS = (1 << 16) - 1;
static const int MAX_KEYWORDS = (1 << 14) - 1;
explicit ArgPassSpec(int num_args) : has_starargs(false), has_kwargs(false), num_keywords(0), num_args(num_args) {
assert(num_args <= MAX_ARGS);
assert(num_keywords <= MAX_KEYWORDS);
}
explicit ArgPassSpec(int num_args, int num_keywords, bool has_starargs, bool has_kwargs)
: has_starargs(has_starargs), has_kwargs(has_kwargs), num_keywords(num_keywords), num_args(num_args) {
assert(num_args <= MAX_ARGS);
assert(num_keywords <= MAX_KEYWORDS);
}
bool operator==(ArgPassSpec rhs) {
return has_starargs == rhs.has_starargs && has_kwargs == rhs.has_kwargs && num_keywords == rhs.num_keywords
&& num_args == rhs.num_args;
}
bool operator!=(ArgPassSpec rhs) { return !(*this == rhs); }
int totalPassed() { return num_args + num_keywords + (has_starargs ? 1 : 0) + (has_kwargs ? 1 : 0); }
uint32_t asInt() const { return *reinterpret_cast<const uint32_t*>(this); }
void dump() {
printf("(has_starargs=%s, has_kwargs=%s, num_keywords=%d, num_args=%d)\n", has_starargs ? "true" : "false",
has_kwargs ? "true" : "false", num_keywords, num_args);
}
};
static_assert(sizeof(ArgPassSpec) <= sizeof(void*), "ArgPassSpec doesn't fit in register! (CC is probably wrong)");
static_assert(sizeof(ArgPassSpec) == sizeof(uint32_t), "ArgPassSpec::asInt needs to be updated");
struct ParamNames {
bool takes_param_names;
std::vector<llvm::StringRef> args;
llvm::StringRef vararg, kwarg;
explicit ParamNames(AST* ast, InternedStringPool& pool);
ParamNames(const std::vector<llvm::StringRef>& args, llvm::StringRef vararg, llvm::StringRef kwarg);
static ParamNames empty() { return ParamNames(); }
int totalParameters() const {
return args.size() + (vararg.str().size() == 0 ? 0 : 1) + (kwarg.str().size() == 0 ? 0 : 1);
}
private:
ParamNames() : takes_param_names(false) {}
};
// Probably overkill to copy this from ArgPassSpec
struct ParamReceiveSpec {
bool takes_varargs : 1;
bool takes_kwargs : 1;
unsigned int num_defaults : 14;
unsigned int num_args : 16;
static const int MAX_ARGS = (1 << 16) - 1;
static const int MAX_DEFAULTS = (1 << 14) - 1;
explicit ParamReceiveSpec(int num_args)
: takes_varargs(false), takes_kwargs(false), num_defaults(0), num_args(num_args) {
assert(num_args <= MAX_ARGS);
assert(num_defaults <= MAX_DEFAULTS);
}
explicit ParamReceiveSpec(int num_args, int num_defaults, bool takes_varargs, bool takes_kwargs)
: takes_varargs(takes_varargs), takes_kwargs(takes_kwargs), num_defaults(num_defaults), num_args(num_args) {
assert(num_args <= MAX_ARGS);
assert(num_defaults <= MAX_DEFAULTS);
}
bool operator==(ParamReceiveSpec rhs) {
return takes_varargs == rhs.takes_varargs && takes_kwargs == rhs.takes_kwargs
&& num_defaults == rhs.num_defaults && num_args == rhs.num_args;
}
bool operator!=(ParamReceiveSpec rhs) { return !(*this == rhs); }
int totalReceived() { return num_args + (takes_varargs ? 1 : 0) + (takes_kwargs ? 1 : 0); }
};
class ICInvalidator { class ICInvalidator {
private: private:
int64_t cur_version; int64_t cur_version;
...@@ -229,23 +277,6 @@ public: ...@@ -229,23 +277,6 @@ public:
void speculationFailed(); void speculationFailed();
}; };
struct ParamNames {
bool takes_param_names;
std::vector<llvm::StringRef> args;
llvm::StringRef vararg, kwarg;
explicit ParamNames(AST* ast, InternedStringPool& pool);
ParamNames(const std::vector<llvm::StringRef>& args, llvm::StringRef vararg, llvm::StringRef kwarg);
static ParamNames empty() { return ParamNames(); }
int totalParameters() const {
return args.size() + (vararg.str().size() == 0 ? 0 : 1) + (kwarg.str().size() == 0 ? 0 : 1);
}
private:
ParamNames() : takes_param_names(false) {}
};
typedef int FutureFlags; typedef int FutureFlags;
class BoxedModule; class BoxedModule;
...@@ -283,9 +314,7 @@ struct CallRewriteArgs; ...@@ -283,9 +314,7 @@ struct CallRewriteArgs;
class BoxedCode; class BoxedCode;
class CLFunction { class CLFunction {
public: public:
int num_args; ParamReceiveSpec paramspec;
int num_defaults;
bool takes_varargs, takes_kwargs;
std::unique_ptr<SourceInfo> source; std::unique_ptr<SourceInfo> source;
ParamNames param_names; ParamNames param_names;
...@@ -308,10 +337,7 @@ public: ...@@ -308,10 +337,7 @@ public:
CLFunction(int num_args, int num_defaults, bool takes_varargs, bool takes_kwargs, CLFunction(int num_args, int num_defaults, bool takes_varargs, bool takes_kwargs,
std::unique_ptr<SourceInfo> source) std::unique_ptr<SourceInfo> source)
: num_args(num_args), : paramspec(num_args, num_defaults, takes_varargs, takes_kwargs),
num_defaults(num_defaults),
takes_varargs(takes_varargs),
takes_kwargs(takes_kwargs),
source(std::move(source)), source(std::move(source)),
param_names(this->source->ast, this->source->getInternedStrings()), param_names(this->source->ast, this->source->getInternedStrings()),
always_use_version(NULL), always_use_version(NULL),
...@@ -319,10 +345,7 @@ public: ...@@ -319,10 +345,7 @@ public:
assert(num_args >= num_defaults); assert(num_args >= num_defaults);
} }
CLFunction(int num_args, int num_defaults, bool takes_varargs, bool takes_kwargs, const ParamNames& param_names) CLFunction(int num_args, int num_defaults, bool takes_varargs, bool takes_kwargs, const ParamNames& param_names)
: num_args(num_args), : paramspec(num_args, num_defaults, takes_varargs, takes_kwargs),
num_defaults(num_defaults),
takes_varargs(takes_varargs),
takes_kwargs(takes_kwargs),
source(nullptr), source(nullptr),
param_names(param_names), param_names(param_names),
always_use_version(NULL), always_use_version(NULL),
...@@ -330,7 +353,7 @@ public: ...@@ -330,7 +353,7 @@ public:
assert(num_args >= num_defaults); assert(num_args >= num_defaults);
} }
int numReceivedArgs() { return num_args + (takes_varargs ? 1 : 0) + (takes_kwargs ? 1 : 0); } int numReceivedArgs() { return paramspec.totalReceived(); }
void addVersion(CompiledFunction* compiled) { void addVersion(CompiledFunction* compiled) {
assert(compiled); assert(compiled);
...@@ -344,7 +367,7 @@ public: ...@@ -344,7 +367,7 @@ public:
&& compiled->spec->boxed_return_value) && compiled->spec->boxed_return_value)
always_use_version = compiled; always_use_version = compiled;
assert(compiled->spec->arg_types.size() == num_args + (takes_varargs ? 1 : 0) + (takes_kwargs ? 1 : 0)); assert(compiled->spec->arg_types.size() == paramspec.totalReceived());
versions.push_back(compiled); versions.push_back(compiled);
} else { } else {
osr_versions[compiled->entry_descriptor] = compiled; osr_versions[compiled->entry_descriptor] = compiled;
......
...@@ -72,7 +72,7 @@ public: ...@@ -72,7 +72,7 @@ public:
static Box* argcount(Box* b, void*) { static Box* argcount(Box* b, void*) {
RELEASE_ASSERT(b->cls == code_cls, ""); RELEASE_ASSERT(b->cls == code_cls, "");
return boxInt(static_cast<BoxedCode*>(b)->f->num_args); return boxInt(static_cast<BoxedCode*>(b)->f->paramspec.num_args);
} }
static Box* varnames(Box* b, void*) { static Box* varnames(Box* b, void*) {
......
...@@ -310,7 +310,7 @@ extern "C" BoxedGenerator::BoxedGenerator(BoxedFunctionBase* function, Box* arg1 ...@@ -310,7 +310,7 @@ extern "C" BoxedGenerator::BoxedGenerator(BoxedFunctionBase* function, Box* arg1
#endif #endif
{ {
int numArgs = function->f->num_args; int numArgs = function->f->numReceivedArgs();
if (numArgs > 3) { if (numArgs > 3) {
numArgs -= 3; numArgs -= 3;
this->args = new (numArgs) GCdArray(); this->args = new (numArgs) GCdArray();
...@@ -384,7 +384,7 @@ extern "C" void generatorGCHandler(GCVisitor* v, Box* b) { ...@@ -384,7 +384,7 @@ extern "C" void generatorGCHandler(GCVisitor* v, Box* b) {
BoxedGenerator* g = (BoxedGenerator*)b; BoxedGenerator* g = (BoxedGenerator*)b;
v->visit(g->function); v->visit(g->function);
int num_args = g->function->f->num_args; int num_args = g->function->f->numReceivedArgs();
if (num_args >= 1) if (num_args >= 1)
v->visit(g->arg1); v->visit(g->arg1);
if (num_args >= 2) if (num_args >= 2)
......
...@@ -2977,7 +2977,7 @@ enum class KeywordDest { ...@@ -2977,7 +2977,7 @@ enum class KeywordDest {
POSITIONAL, POSITIONAL,
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,
BoxedString* kw_name, Box* kw_val, Box*& oarg1, Box*& oarg2, Box*& oarg3, Box** oargs, BoxedString* kw_name, Box* kw_val, Box*& oarg1, Box*& oarg2, Box*& oarg3, Box** oargs,
BoxedDict* okwargs, CLFunction* cl) { BoxedDict* okwargs, CLFunction* cl) {
assert(kw_val); assert(kw_val);
...@@ -2985,8 +2985,8 @@ static KeywordDest placeKeyword(const ParamNames& param_names, llvm::SmallVector ...@@ -2985,8 +2985,8 @@ static KeywordDest placeKeyword(const ParamNames& param_names, llvm::SmallVector
assert(kw_name); assert(kw_name);
assert(gc::isValidGCObject(kw_name)); assert(gc::isValidGCObject(kw_name));
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] == kw_name->s() && kw_name->size() > 0) { if (param_names->args[j] == kw_name->s() && 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->c_str());
...@@ -3040,6 +3040,8 @@ Box* callFunc(BoxedFunctionBase* func, CallRewriteArgs* rewrite_args, ArgPassSpe ...@@ -3040,6 +3040,8 @@ Box* callFunc(BoxedFunctionBase* func, CallRewriteArgs* rewrite_args, ArgPassSpe
BoxedClosure* closure = func->closure; BoxedClosure* closure = func->closure;
CLFunction* f = func->f; CLFunction* f = func->f;
ParamReceiveSpec paramspec = f->paramspec;
slowpath_callfunc.log(); slowpath_callfunc.log();
int num_output_args = f->numReceivedArgs(); int num_output_args = f->numReceivedArgs();
...@@ -3079,8 +3081,8 @@ Box* callFunc(BoxedFunctionBase* func, CallRewriteArgs* rewrite_args, ArgPassSpe ...@@ -3079,8 +3081,8 @@ Box* callFunc(BoxedFunctionBase* func, CallRewriteArgs* rewrite_args, ArgPassSpe
// Fast path: if it's a simple-enough call, we don't have to do anything special. On a simple // Fast path: if it's a simple-enough call, we don't have to do anything special. On a simple
// django-admin test this covers something like 93% of all calls to callFunc. // django-admin test this covers something like 93% of all calls to callFunc.
if (!f->isGenerator()) { if (!f->isGenerator()) {
if (argspec.num_keywords == 0 && argspec.has_starargs == f->takes_varargs && !argspec.has_kwargs if (argspec.num_keywords == 0 && argspec.has_starargs == paramspec.takes_varargs && !argspec.has_kwargs
&& !f->takes_kwargs && argspec.num_args == f->num_args) { && !paramspec.takes_kwargs && argspec.num_args == paramspec.num_args) {
// If the caller passed starargs, we can only pass those directly to the callee if it's a tuple, // If the caller passed starargs, we can only pass those directly to the callee if it's a tuple,
// since otherwise modifications by the callee would be visible to the caller (hence why varargs // since otherwise modifications by the callee would be visible to the caller (hence why varargs
// received by the caller are always tuples). // received by the caller are always tuples).
...@@ -3121,8 +3123,8 @@ Box* callFunc(BoxedFunctionBase* func, CallRewriteArgs* rewrite_args, ArgPassSpe ...@@ -3121,8 +3123,8 @@ Box* callFunc(BoxedFunctionBase* func, CallRewriteArgs* rewrite_args, ArgPassSpe
#if 0 #if 0
char buf[80]; char buf[80];
snprintf(buf, sizeof(buf), "zzz_aborted_%d_args_%d_%d_%d_%d_params_%d_%d_%d_%d", f->isGenerator(), snprintf(buf, sizeof(buf), "zzz_aborted_%d_args_%d_%d_%d_%d_params_%d_%d_%d_%d", f->isGenerator(),
argspec.num_args, argspec.num_keywords, argspec.has_starargs, argspec.has_kwargs, f->num_args, argspec.num_args, argspec.num_keywords, argspec.has_starargs, argspec.has_kwargs, paramspec.num_args,
f->num_defaults, f->takes_varargs, f->takes_kwargs); paramspec.num_defaults, paramspec.takes_varargs, paramspec.takes_kwargs);
uint64_t* counter = Stats::getStatCounter(buf); uint64_t* counter = Stats::getStatCounter(buf);
Stats::log(counter); Stats::log(counter);
#endif #endif
...@@ -3207,14 +3209,14 @@ Box* callFunc(BoxedFunctionBase* func, CallRewriteArgs* rewrite_args, ArgPassSpe ...@@ -3207,14 +3209,14 @@ Box* callFunc(BoxedFunctionBase* func, CallRewriteArgs* rewrite_args, ArgPassSpe
//// ////
// First, match up positional parameters to positional/varargs: // First, match up positional parameters to positional/varargs:
int positional_to_positional = std::min((int)argspec.num_args, f->num_args); int positional_to_positional = std::min(argspec.num_args, paramspec.num_args);
for (int i = 0; i < positional_to_positional; i++) { for (int i = 0; i < positional_to_positional; i++) {
getArg(i, oarg1, oarg2, oarg3, oargs) = getArg(i, arg1, arg2, arg3, args); getArg(i, oarg1, oarg2, oarg3, oargs) = getArg(i, arg1, arg2, arg3, args);
// we already moved the positional args into position // we already moved the positional args into position
} }
int varargs_to_positional = std::min((int)varargs.size(), f->num_args - positional_to_positional); int varargs_to_positional = std::min((int)varargs.size(), paramspec.num_args - positional_to_positional);
for (int i = 0; i < varargs_to_positional; i++) { for (int i = 0; i < varargs_to_positional; i++) {
assert(!rewrite_args && "would need to be handled here"); assert(!rewrite_args && "would need to be handled here");
getArg(i + positional_to_positional, oarg1, oarg2, oarg3, oargs) = varargs[i]; getArg(i + positional_to_positional, oarg1, oarg2, oarg3, oargs) = varargs[i];
...@@ -3246,8 +3248,8 @@ Box* callFunc(BoxedFunctionBase* func, CallRewriteArgs* rewrite_args, ArgPassSpe ...@@ -3246,8 +3248,8 @@ Box* callFunc(BoxedFunctionBase* func, CallRewriteArgs* rewrite_args, ArgPassSpe
unused_positional.push_back(varargs[i]); unused_positional.push_back(varargs[i]);
} }
if (f->takes_varargs) { if (paramspec.takes_varargs) {
int varargs_idx = f->num_args; int varargs_idx = paramspec.num_args;
if (rewrite_args) { if (rewrite_args) {
assert(!varargs.size()); assert(!varargs.size());
assert(!argspec.has_starargs); assert(!argspec.has_starargs);
...@@ -3289,7 +3291,7 @@ Box* callFunc(BoxedFunctionBase* func, CallRewriteArgs* rewrite_args, ArgPassSpe ...@@ -3289,7 +3291,7 @@ Box* callFunc(BoxedFunctionBase* func, CallRewriteArgs* rewrite_args, ArgPassSpe
getArg(varargs_idx, oarg1, oarg2, oarg3, oargs) = ovarargs; getArg(varargs_idx, oarg1, oarg2, oarg3, oargs) = ovarargs;
} else if (unused_positional.size()) { } else if (unused_positional.size()) {
raiseExcHelper(TypeError, "%s() takes at most %d argument%s (%d given)", getFunctionName(f).c_str(), raiseExcHelper(TypeError, "%s() takes at most %d argument%s (%d given)", getFunctionName(f).c_str(),
f->num_args, (f->num_args == 1 ? "" : "s"), paramspec.num_args, (paramspec.num_args == 1 ? "" : "s"),
argspec.num_args + argspec.num_keywords + varargs.size()); argspec.num_args + argspec.num_keywords + varargs.size());
} }
...@@ -3297,8 +3299,8 @@ Box* callFunc(BoxedFunctionBase* func, CallRewriteArgs* rewrite_args, ArgPassSpe ...@@ -3297,8 +3299,8 @@ Box* callFunc(BoxedFunctionBase* func, CallRewriteArgs* rewrite_args, ArgPassSpe
// Second, apply any keywords: // Second, apply any keywords:
BoxedDict* okwargs = NULL; BoxedDict* okwargs = NULL;
if (f->takes_kwargs) { if (paramspec.takes_kwargs) {
int kwargs_idx = f->num_args + (f->takes_varargs ? 1 : 0); int kwargs_idx = paramspec.num_args + (paramspec.takes_varargs ? 1 : 0);
if (rewrite_args) { if (rewrite_args) {
RewriterVar* r_kwargs = rewrite_args->rewriter->call(true, (void*)createDict); RewriterVar* r_kwargs = rewrite_args->rewriter->call(true, (void*)createDict);
...@@ -3316,8 +3318,8 @@ Box* callFunc(BoxedFunctionBase* func, CallRewriteArgs* rewrite_args, ArgPassSpe ...@@ -3316,8 +3318,8 @@ Box* callFunc(BoxedFunctionBase* func, CallRewriteArgs* rewrite_args, ArgPassSpe
getArg(kwargs_idx, oarg1, oarg2, oarg3, oargs) = okwargs; getArg(kwargs_idx, oarg1, oarg2, oarg3, oargs) = okwargs;
} }
const ParamNames& param_names = f->param_names; const ParamNames* param_names = &f->param_names;
if (!param_names.takes_param_names && argspec.num_keywords && !f->takes_kwargs) { if ((!param_names || !param_names->takes_param_names) && argspec.num_keywords && !paramspec.takes_kwargs) {
raiseExcHelper(TypeError, "%s() doesn't take keyword arguments", getFunctionName(f).c_str()); raiseExcHelper(TypeError, "%s() doesn't take keyword arguments", getFunctionName(f).c_str());
} }
...@@ -3330,7 +3332,7 @@ Box* callFunc(BoxedFunctionBase* func, CallRewriteArgs* rewrite_args, ArgPassSpe ...@@ -3330,7 +3332,7 @@ Box* callFunc(BoxedFunctionBase* func, CallRewriteArgs* rewrite_args, ArgPassSpe
int arg_idx = i + argspec.num_args; int arg_idx = i + argspec.num_args;
Box* kw_val = getArg(arg_idx, arg1, arg2, arg3, args); Box* kw_val = getArg(arg_idx, arg1, arg2, arg3, args);
if (!param_names.takes_param_names) { if (!param_names || !param_names->takes_param_names) {
assert(okwargs); assert(okwargs);
rewrite_args = NULL; // would need to add it to r_kwargs rewrite_args = NULL; // would need to add it to r_kwargs
okwargs->d[(*keyword_names)[i]] = kw_val; okwargs->d[(*keyword_names)[i]] = kw_val;
...@@ -3364,7 +3366,7 @@ Box* callFunc(BoxedFunctionBase* func, CallRewriteArgs* rewrite_args, ArgPassSpe ...@@ -3364,7 +3366,7 @@ Box* callFunc(BoxedFunctionBase* func, CallRewriteArgs* rewrite_args, ArgPassSpe
BoxedString* s = static_cast<BoxedString*>(k); BoxedString* s = static_cast<BoxedString*>(k);
if (param_names.takes_param_names) { if (param_names && param_names->takes_param_names) {
assert(!rewrite_args && "would need to make sure that this didn't need to go into r_kwargs"); assert(!rewrite_args && "would need to make sure that this didn't need to go into r_kwargs");
placeKeyword(param_names, params_filled, s, p.second, oarg1, oarg2, oarg3, oargs, okwargs, f); placeKeyword(param_names, params_filled, s, p.second, oarg1, oarg2, oarg3, oargs, okwargs, f);
} else { } else {
...@@ -3384,7 +3386,7 @@ Box* callFunc(BoxedFunctionBase* func, CallRewriteArgs* rewrite_args, ArgPassSpe ...@@ -3384,7 +3386,7 @@ Box* callFunc(BoxedFunctionBase* func, CallRewriteArgs* rewrite_args, ArgPassSpe
// Fill with defaults: // Fill with defaults:
for (int i = 0; i < f->num_args - f->num_defaults; i++) { for (int i = 0; i < paramspec.num_args - paramspec.num_defaults; i++) {
if (params_filled[i]) if (params_filled[i])
continue; continue;
// TODO not right error message // TODO not right error message
...@@ -3396,11 +3398,11 @@ Box* callFunc(BoxedFunctionBase* func, CallRewriteArgs* rewrite_args, ArgPassSpe ...@@ -3396,11 +3398,11 @@ Box* callFunc(BoxedFunctionBase* func, CallRewriteArgs* rewrite_args, ArgPassSpe
r_defaults_array = rewrite_args->obj->getAttr(offsetof(BoxedFunctionBase, defaults), Location::any()); r_defaults_array = rewrite_args->obj->getAttr(offsetof(BoxedFunctionBase, defaults), Location::any());
} }
for (int i = f->num_args - f->num_defaults; i < f->num_args; i++) { for (int i = paramspec.num_args - paramspec.num_defaults; i < paramspec.num_args; i++) {
if (params_filled[i]) if (params_filled[i])
continue; continue;
int default_idx = i + f->num_defaults - f->num_args; int default_idx = i + paramspec.num_defaults - paramspec.num_args;
Box* default_obj = func->defaults->elts[default_idx]; Box* default_obj = func->defaults->elts[default_idx];
if (rewrite_args) { if (rewrite_args) {
......
...@@ -316,7 +316,7 @@ extern "C" BoxedFunctionBase::BoxedFunctionBase(CLFunction* f) ...@@ -316,7 +316,7 @@ extern "C" BoxedFunctionBase::BoxedFunctionBase(CLFunction* f)
this->doc = None; this->doc = None;
} }
assert(f->num_defaults == ndefaults); assert(f->paramspec.num_defaults == ndefaults);
} }
extern "C" BoxedFunctionBase::BoxedFunctionBase(CLFunction* f, std::initializer_list<Box*> defaults, extern "C" BoxedFunctionBase::BoxedFunctionBase(CLFunction* f, std::initializer_list<Box*> defaults,
...@@ -338,7 +338,7 @@ extern "C" BoxedFunctionBase::BoxedFunctionBase(CLFunction* f, std::initializer_ ...@@ -338,7 +338,7 @@ extern "C" BoxedFunctionBase::BoxedFunctionBase(CLFunction* f, std::initializer_
this->doc = None; this->doc = None;
} }
assert(f->num_defaults == ndefaults); assert(f->paramspec.num_defaults == ndefaults);
} }
BoxedFunction::BoxedFunction(CLFunction* f) : BoxedFunction(f, {}) { BoxedFunction::BoxedFunction(CLFunction* f) : BoxedFunction(f, {}) {
......
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