Commit 0edbf989 authored by Kevin Modzelewski's avatar Kevin Modzelewski

Rewrite exception-mismatched function calls

Previously, if a CAPI-style callsite tried to call a function but
only CXX versions were available (and visa versa), it would bail
on rewriting.  Now enable CAPI rewrites of CXX functions by using
a helper function, and enable CXX rewrites of CAPI functions by
just calling checkAndThrowCAPIException like we normally do.
parent a44f1c81
...@@ -3526,6 +3526,18 @@ static Box* astInterpretHelper(CLFunction* f, int num_args, BoxedClosure* closur ...@@ -3526,6 +3526,18 @@ static Box* astInterpretHelper(CLFunction* f, int num_args, BoxedClosure* closur
return astInterpretFunction(f, num_args, closure, generator, globals, arg1, arg2, arg3, (Box**)args); return astInterpretFunction(f, num_args, closure, generator, globals, arg1, arg2, arg3, (Box**)args);
} }
// TODO: is it better to take the func_ptr last (requiring passing all the args), or is it better to put it
// first (requiring moving all the args)?
static Box* capiCallCxxHelper(Box* (*func_ptr)(void*, void*, void*, void*, void*), void* a, void* b, void* c, void* d,
void* e) noexcept {
try {
return func_ptr(a, b, c, d, e);
} catch (ExcInfo e) {
setCAPIException(e);
return NULL;
}
}
template <ExceptionStyle S> template <ExceptionStyle S>
Box* callCLFunc(CLFunction* f, CallRewriteArgs* rewrite_args, int num_output_args, BoxedClosure* closure, Box* callCLFunc(CLFunction* f, CallRewriteArgs* rewrite_args, int num_output_args, BoxedClosure* closure,
BoxedGenerator* generator, Box* globals, Box* oarg1, Box* oarg2, Box* oarg3, BoxedGenerator* generator, Box* globals, Box* oarg1, Box* oarg2, Box* oarg3,
...@@ -3580,14 +3592,19 @@ Box* callCLFunc(CLFunction* f, CallRewriteArgs* rewrite_args, int num_output_arg ...@@ -3580,14 +3592,19 @@ Box* callCLFunc(CLFunction* f, CallRewriteArgs* rewrite_args, int num_output_arg
ASSERT(!globals, "need to update the calling conventions if we want to pass globals"); ASSERT(!globals, "need to update the calling conventions if we want to pass globals");
if (rewrite_args && chosen_cf->exception_style == S) { if (rewrite_args) {
rewrite_args->rewriter->addDependenceOn(chosen_cf->dependent_callsites); rewrite_args->rewriter->addDependenceOn(chosen_cf->dependent_callsites);
assert(!generator); assert(!generator);
RewriterVar::SmallVector arg_vec; RewriterVar::SmallVector arg_vec;
// TODO this kind of embedded reference needs to be tracked by the GC somehow?
// Or maybe it's ok, since we've guarded on the function object? void* func_ptr = (void*)chosen_cf->call;
if (S == CAPI && chosen_cf->exception_style == CXX) {
arg_vec.push_back(rewrite_args->rewriter->loadConst((intptr_t)func_ptr, Location::forArg(0)));
func_ptr = (void*)capiCallCxxHelper;
}
if (closure) if (closure)
arg_vec.push_back(rewrite_args->rewriter->loadConst((intptr_t)closure, Location::forArg(0))); arg_vec.push_back(rewrite_args->rewriter->loadConst((intptr_t)closure, Location::forArg(0)));
if (num_output_args >= 1) if (num_output_args >= 1)
...@@ -3599,8 +3616,10 @@ Box* callCLFunc(CLFunction* f, CallRewriteArgs* rewrite_args, int num_output_arg ...@@ -3599,8 +3616,10 @@ Box* callCLFunc(CLFunction* f, CallRewriteArgs* rewrite_args, int num_output_arg
if (num_output_args >= 4) if (num_output_args >= 4)
arg_vec.push_back(rewrite_args->args); arg_vec.push_back(rewrite_args->args);
assert(S == chosen_cf->exception_style); rewrite_args->out_rtn = rewrite_args->rewriter->call(true, func_ptr, arg_vec);
rewrite_args->out_rtn = rewrite_args->rewriter->call(true, (void*)chosen_cf->call, arg_vec); if (S == CXX && chosen_cf->exception_style == CAPI)
rewrite_args->rewriter->call(true, (void*)checkAndThrowCAPIException);
rewrite_args->out_success = true; rewrite_args->out_success = true;
} }
......
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