Commit 88b62b62 authored by Kevin Modzelewski's avatar Kevin Modzelewski

try to simplify things using bindObjIntoArgs

parent 4f95e1cc
...@@ -1232,6 +1232,15 @@ int Rewriter::_allocate(RewriterVar* result, int n) { ...@@ -1232,6 +1232,15 @@ int Rewriter::_allocate(RewriterVar* result, int n) {
if (consec == n) { if (consec == n) {
int a = i / 8 - n + 1; int a = i / 8 - n + 1;
int b = i / 8; int b = i / 8;
// Put placeholders in so the array space doesn't get re-allocated.
// This won't get collected, but that's fine.
// Note: make sure to do this marking before the initializeInReg call
for (int j = a; j <= b; j++) {
Location m(Location::Scratch, j * 8);
assert(vars_by_location.count(m) == 0);
vars_by_location[m] = LOCATION_PLACEHOLDER;
}
assembler::Register r = result->initializeInReg(); assembler::Register r = result->initializeInReg();
// TODO should be a LEA instruction // TODO should be a LEA instruction
...@@ -1240,13 +1249,6 @@ int Rewriter::_allocate(RewriterVar* result, int n) { ...@@ -1240,13 +1249,6 @@ int Rewriter::_allocate(RewriterVar* result, int n) {
assembler->mov(assembler::RSP, r); assembler->mov(assembler::RSP, r);
assembler->add(assembler::Immediate(8 * a + rewrite->getScratchRspOffset()), r); assembler->add(assembler::Immediate(8 * a + rewrite->getScratchRspOffset()), r);
// Put placeholders in so the array space doesn't get re-allocated.
// This won't get collected, but that's fine.
for (int j = a; j <= b; j++) {
Location m(Location::Scratch, j * 8);
vars_by_location[m] = LOCATION_PLACEHOLDER;
}
assertConsistent(); assertConsistent();
result->releaseIfNoUses(); result->releaseIfNoUses();
return a; return a;
......
...@@ -2662,6 +2662,8 @@ extern "C" Box* callattrInternal(Box* obj, BoxedString* attr, LookupScope scope, ...@@ -2662,6 +2662,8 @@ extern "C" Box* callattrInternal(Box* obj, BoxedString* attr, LookupScope scope,
v->addAttrGuard(BOX_CLS_OFFSET, (intptr_t)args[i - 3]->cls); v->addAttrGuard(BOX_CLS_OFFSET, (intptr_t)args[i - 3]->cls);
} }
} }
rewrite_args->args_guarded = true;
} }
// right now I don't think this is ever called with INST_ONLY? // right now I don't think this is ever called with INST_ONLY?
...@@ -2670,7 +2672,7 @@ extern "C" Box* callattrInternal(Box* obj, BoxedString* attr, LookupScope scope, ...@@ -2670,7 +2672,7 @@ extern "C" Box* callattrInternal(Box* obj, BoxedString* attr, LookupScope scope,
// Look up the argument. Pass in the arguments to getattrInternalGeneral or getclsattr_general // Look up the argument. Pass in the arguments to getattrInternalGeneral or getclsattr_general
// that will shortcut functions by not putting them into instancemethods // that will shortcut functions by not putting them into instancemethods
Box* bind_obj = NULL; // Initialize this to NULL to allow getattrInternalEx to ignore it Box* bind_obj = NULL; // Initialize this to NULL to allow getattrInternalEx to ignore it
RewriterVar* r_bind_obj; RewriterVar* r_bind_obj = NULL;
Box* val; Box* val;
RewriterVar* r_val = NULL; RewriterVar* r_val = NULL;
if (rewrite_args) { if (rewrite_args) {
...@@ -2692,114 +2694,28 @@ extern "C" Box* callattrInternal(Box* obj, BoxedString* attr, LookupScope scope, ...@@ -2692,114 +2694,28 @@ extern "C" Box* callattrInternal(Box* obj, BoxedString* attr, LookupScope scope,
} }
if (bind_obj != NULL) { if (bind_obj != NULL) {
Box** new_args = NULL;
if (npassed_args >= 3) {
new_args = (Box**)alloca(sizeof(Box*) * (npassed_args + 1 - 3));
}
if (rewrite_args) { if (rewrite_args) {
r_val->addGuard((int64_t)val); r_val->addGuard((int64_t)val);
rewrite_args->obj = r_val;
rewrite_args->func_guarded = true;
} }
// TODO copy from runtimeCall
// TODO these two branches could probably be folded together (the first one is becoming
// a subset of the second)
if (npassed_args <= 2) {
Box* rtn;
if (rewrite_args) {
CallRewriteArgs srewrite_args(rewrite_args->rewriter, r_val, rewrite_args->destination);
srewrite_args.arg1 = r_bind_obj;
// should be no-ops:
if (npassed_args >= 1)
srewrite_args.arg2 = rewrite_args->arg1;
if (npassed_args >= 2)
srewrite_args.arg3 = rewrite_args->arg2;
srewrite_args.func_guarded = true;
srewrite_args.args_guarded = true;
rtn = runtimeCallInternal(val, &srewrite_args, ArgPassSpec(argspec.num_args + 1, argspec.num_keywords,
argspec.has_starargs, argspec.has_kwargs),
bind_obj, arg1, arg2, NULL, keyword_names);
if (!srewrite_args.out_success) {
rewrite_args = NULL;
} else {
rewrite_args->out_rtn = srewrite_args.out_rtn;
}
} else {
rtn = runtimeCallInternal(val, NULL, ArgPassSpec(argspec.num_args + 1, argspec.num_keywords,
argspec.has_starargs, argspec.has_kwargs),
bind_obj, arg1, arg2, NULL, keyword_names);
}
if (rewrite_args)
rewrite_args->out_success = true;
return rtn;
} else {
int alloca_size = sizeof(Box*) * (npassed_args + 1 - 3);
Box** new_args = (Box**)alloca(alloca_size);
new_args[0] = arg3;
memcpy(new_args + 1, args, (npassed_args - 3) * sizeof(Box*));
Box* rtn;
if (rewrite_args) {
CallRewriteArgs srewrite_args(rewrite_args->rewriter, r_val, rewrite_args->destination);
srewrite_args.arg1 = r_bind_obj;
srewrite_args.arg2 = rewrite_args->arg1;
srewrite_args.arg3 = rewrite_args->arg2;
srewrite_args.args = rewrite_args->rewriter->allocateAndCopyPlus1(
rewrite_args->arg3, npassed_args == 3 ? NULL : rewrite_args->args, npassed_args - 3);
srewrite_args.args_guarded = true;
srewrite_args.func_guarded = true;
rtn = runtimeCallInternal(val, &srewrite_args, ArgPassSpec(argspec.num_args + 1, argspec.num_keywords,
argspec.has_starargs, argspec.has_kwargs),
bind_obj, arg1, arg2, new_args, keyword_names);
if (!srewrite_args.out_success) {
rewrite_args = NULL;
} else {
rewrite_args->out_rtn = srewrite_args.out_rtn;
rewrite_args->out_success = true;
}
} else {
rtn = runtimeCallInternal(val, NULL, ArgPassSpec(argspec.num_args + 1, argspec.num_keywords,
argspec.has_starargs, argspec.has_kwargs),
bind_obj, arg1, arg2, new_args, keyword_names);
}
return rtn;
}
} else {
Box* rtn; Box* rtn;
ArgPassSpec new_argspec
= bindObjIntoArgs(bind_obj, r_bind_obj, rewrite_args, argspec, arg1, arg2, arg3, args, new_args);
return runtimeCallInternal(val, rewrite_args, new_argspec, arg1, arg2, arg3, new_args, keyword_names);
} else {
if (rewrite_args) { if (rewrite_args) {
CallRewriteArgs srewrite_args(rewrite_args->rewriter, r_val, rewrite_args->destination); rewrite_args->obj = r_val;
if (npassed_args >= 1)
srewrite_args.arg1 = rewrite_args->arg1;
if (npassed_args >= 2)
srewrite_args.arg2 = rewrite_args->arg2;
if (npassed_args >= 3)
srewrite_args.arg3 = rewrite_args->arg3;
if (npassed_args >= 4)
srewrite_args.args = rewrite_args->args;
srewrite_args.args_guarded = true;
rtn = runtimeCallInternal(val, &srewrite_args, argspec, arg1, arg2, arg3, args, keyword_names);
if (!srewrite_args.out_success) {
rewrite_args = NULL;
} else {
rewrite_args->out_rtn = srewrite_args.out_rtn;
}
} else {
rtn = runtimeCallInternal(val, NULL, argspec, arg1, arg2, arg3, args, keyword_names);
} }
if (!rtn) { Box* rtn = runtimeCallInternal(val, rewrite_args, argspec, arg1, arg2, arg3, args, keyword_names);
raiseExcHelper(TypeError, "'%s' object is not callable", getTypeName(val)); assert(rtn); // not sure why we have this here
}
if (rewrite_args)
rewrite_args->out_success = true;
return rtn; return rtn;
} }
} }
...@@ -3012,8 +2928,8 @@ static Box* _callFuncHelper(BoxedFunctionBase* func, ArgPassSpec argspec, Box* a ...@@ -3012,8 +2928,8 @@ static Box* _callFuncHelper(BoxedFunctionBase* func, ArgPassSpec argspec, Box* a
typedef std::function<Box*(int, int, RewriterVar*&)> GetDefaultFunc; typedef std::function<Box*(int, int, RewriterVar*&)> GetDefaultFunc;
ArgPassSpec bindObjIntoArgs(Box* obj, CallRewriteArgs* rewrite_args, ArgPassSpec argspec, Box*& arg1, Box*& arg2, ArgPassSpec bindObjIntoArgs(Box* bind_obj, RewriterVar* r_bind_obj, CallRewriteArgs* rewrite_args, ArgPassSpec argspec,
Box*& arg3, Box** args, Box** new_args) { Box*& arg1, Box*& arg2, Box*& arg3, Box** args, Box** new_args) {
int npassed_args = argspec.totalPassed(); int npassed_args = argspec.totalPassed();
assert((new_args != NULL) == (npassed_args >= 3)); assert((new_args != NULL) == (npassed_args >= 3));
...@@ -3025,7 +2941,7 @@ ArgPassSpec bindObjIntoArgs(Box* obj, CallRewriteArgs* rewrite_args, ArgPassSpec ...@@ -3025,7 +2941,7 @@ ArgPassSpec bindObjIntoArgs(Box* obj, CallRewriteArgs* rewrite_args, ArgPassSpec
arg3 = arg2; arg3 = arg2;
arg2 = arg1; arg2 = arg1;
arg1 = obj; arg1 = bind_obj;
if (rewrite_args) { if (rewrite_args) {
if (npassed_args >= 3) { if (npassed_args >= 3) {
...@@ -3034,7 +2950,7 @@ ArgPassSpec bindObjIntoArgs(Box* obj, CallRewriteArgs* rewrite_args, ArgPassSpec ...@@ -3034,7 +2950,7 @@ ArgPassSpec bindObjIntoArgs(Box* obj, CallRewriteArgs* rewrite_args, ArgPassSpec
} }
rewrite_args->arg3 = rewrite_args->arg2; rewrite_args->arg3 = rewrite_args->arg2;
rewrite_args->arg2 = rewrite_args->arg1; rewrite_args->arg2 = rewrite_args->arg1;
rewrite_args->arg1 = rewrite_args->obj; rewrite_args->arg1 = r_bind_obj;
} }
return ArgPassSpec(argspec.num_args + 1, argspec.num_keywords, argspec.has_starargs, argspec.has_kwargs); return ArgPassSpec(argspec.num_args + 1, argspec.num_keywords, argspec.has_starargs, argspec.has_kwargs);
...@@ -3681,6 +3597,7 @@ Box* runtimeCallInternal(Box* obj, CallRewriteArgs* rewrite_args, ArgPassSpec ar ...@@ -3681,6 +3597,7 @@ Box* runtimeCallInternal(Box* obj, CallRewriteArgs* rewrite_args, ArgPassSpec ar
if (rewrite_args && !rewrite_args->func_guarded) { if (rewrite_args && !rewrite_args->func_guarded) {
r_im_func->addGuard((intptr_t)im->func); r_im_func->addGuard((intptr_t)im->func);
rewrite_args->func_guarded = true;
} }
// Guard on which type of instancemethod (bound or unbound) // Guard on which type of instancemethod (bound or unbound)
...@@ -3693,54 +3610,26 @@ Box* runtimeCallInternal(Box* obj, CallRewriteArgs* rewrite_args, ArgPassSpec ar ...@@ -3693,54 +3610,26 @@ Box* runtimeCallInternal(Box* obj, CallRewriteArgs* rewrite_args, ArgPassSpec ar
if (im->obj == NULL) { if (im->obj == NULL) {
Box* f = im->func; Box* f = im->func;
if (rewrite_args) { if (rewrite_args) {
rewrite_args->func_guarded = true;
rewrite_args->args_guarded = true;
rewrite_args->obj = r_im_func; rewrite_args->obj = r_im_func;
} }
Box* res = runtimeCallInternal(f, rewrite_args, argspec, arg1, arg2, arg3, args, keyword_names); Box* res = runtimeCallInternal(f, rewrite_args, argspec, arg1, arg2, arg3, args, keyword_names);
return res; return res;
} }
if (npassed_args <= 2) { Box** new_args = NULL;
Box* rtn; if (npassed_args >= 3) {
if (rewrite_args) { new_args = (Box**)alloca(sizeof(Box*) * (npassed_args + 1 - 3));
CallRewriteArgs srewrite_args(rewrite_args->rewriter, r_im_func, rewrite_args->destination);
srewrite_args.arg1 = rewrite_args->obj->getAttr(INSTANCEMETHOD_OBJ_OFFSET, Location::any());
srewrite_args.func_guarded = true;
srewrite_args.args_guarded = true;
if (npassed_args >= 1)
srewrite_args.arg2 = rewrite_args->arg1;
if (npassed_args >= 2)
srewrite_args.arg3 = rewrite_args->arg2;
rtn = runtimeCallInternal(
im->func, &srewrite_args,
ArgPassSpec(argspec.num_args + 1, argspec.num_keywords, argspec.has_starargs, argspec.has_kwargs),
im->obj, arg1, arg2, NULL, keyword_names);
if (!srewrite_args.out_success) {
rewrite_args = NULL;
} else {
rewrite_args->out_rtn = srewrite_args.out_rtn;
}
} else {
rtn = runtimeCallInternal(im->func, NULL, ArgPassSpec(argspec.num_args + 1, argspec.num_keywords,
argspec.has_starargs, argspec.has_kwargs),
im->obj, arg1, arg2, NULL, keyword_names);
}
if (rewrite_args)
rewrite_args->out_success = true;
return rtn;
} else {
Box** new_args = (Box**)alloca(sizeof(Box*) * (npassed_args + 1 - 3));
new_args[0] = arg3;
memcpy(new_args + 1, args, (npassed_args - 3) * sizeof(Box*));
Box* rtn = runtimeCallInternal(im->func, NULL, ArgPassSpec(argspec.num_args + 1, argspec.num_keywords,
argspec.has_starargs, argspec.has_kwargs),
im->obj, arg1, arg2, new_args, keyword_names);
return rtn;
} }
RewriterVar* r_bind_obj = NULL;
if (rewrite_args) {
r_bind_obj = rewrite_args->obj->getAttr(INSTANCEMETHOD_OBJ_OFFSET);
rewrite_args->obj = r_im_func;
}
ArgPassSpec new_argspec
= bindObjIntoArgs(im->obj, r_bind_obj, rewrite_args, argspec, arg1, arg2, arg3, args, new_args);
return runtimeCallInternal(im->func, rewrite_args, new_argspec, arg1, arg2, arg3, new_args, keyword_names);
} }
assert(0); assert(0);
abort(); abort();
......
...@@ -131,9 +131,10 @@ void rearrangeArguments(ParamReceiveSpec paramspec, const ParamNames* param_name ...@@ -131,9 +131,10 @@ void rearrangeArguments(ParamReceiveSpec paramspec, const ParamNames* param_name
Box* arg1, Box* arg2, Box* arg3, Box** args, const std::vector<BoxedString*>* keyword_names, Box* arg1, Box* arg2, Box* arg3, Box** args, const std::vector<BoxedString*>* keyword_names,
Box*& oarg1, Box*& oarg2, Box*& oarg3, Box** oargs); Box*& oarg1, Box*& oarg2, Box*& oarg3, Box** oargs);
// new_args should be allocated by the caller if at least three args get passed in // new_args should be allocated by the caller if at least three args get passed in.
ArgPassSpec bindObjIntoArgs(Box* obj, CallRewriteArgs* rewrite_args, ArgPassSpec argspec, Box*& arg1, Box*& arg2, // rewrite_args will get modified in place.
Box*& arg3, Box** args, Box** new_args); ArgPassSpec bindObjIntoArgs(Box* bind_obj, RewriterVar* r_bind_obj, CallRewriteArgs* rewrite_args, ArgPassSpec argspec,
Box*& arg1, Box*& arg2, Box*& arg3, Box** args, Box** new_args);
} // namespace pyston } // namespace pyston
#endif #endif
...@@ -547,7 +547,15 @@ static Box* typeTppCall(Box* self, CallRewriteArgs* rewrite_args, ArgPassSpec ar ...@@ -547,7 +547,15 @@ static Box* typeTppCall(Box* self, CallRewriteArgs* rewrite_args, ArgPassSpec ar
new_args = (Box**)alloca(sizeof(Box*) * (npassed_args + 1 - 3)); new_args = (Box**)alloca(sizeof(Box*) * (npassed_args + 1 - 3));
} }
ArgPassSpec new_argspec = bindObjIntoArgs(self, rewrite_args, argspec, arg1, arg2, arg3, args, new_args); RewriterVar* r_bind_obj = NULL;
if (rewrite_args) {
r_bind_obj = rewrite_args->obj;
rewrite_args->obj = NULL;
}
ArgPassSpec new_argspec
= bindObjIntoArgs(self, r_bind_obj, rewrite_args, argspec, arg1, arg2, arg3, args, new_args);
return typeCallInner(rewrite_args, new_argspec, arg1, arg2, arg3, new_args, keyword_names); return typeCallInner(rewrite_args, new_argspec, arg1, arg2, arg3, new_args, keyword_names);
} }
......
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