context.pollThreadEvents();
}
}
public void compileFCall(Node node, BodyCompiler context, boolean expr) {
final FCallNode fcallNode = (FCallNode) node;
ArgumentsCallback argsCallback = getArgsCallback(fcallNode.getArgsNode());
CompilerCallback closureArg = getBlock(fcallNode.getIterNode());
DYNOPT: if (RubyInstanceConfig.DYNOPT_COMPILE_ENABLED) {
// dynopt does not handle non-local block flow control yet, so we bail out
if (fcallNode.getIterNode() != null) break DYNOPT;
if (fcallNode.callAdapter instanceof CachingCallSite) {
CachingCallSite cacheSite = (CachingCallSite)fcallNode.callAdapter;
if (cacheSite.isOptimizable()) {
CacheEntry entry = cacheSite.getCache();
if (closureArg == null && (argsCallback == null || (argsCallback.getArity() >= 0 && argsCallback.getArity() <= 3))) {
// recursive calls
if (compileRecursiveCall(fcallNode.getName(), entry.token, CallType.FUNCTIONAL, fcallNode.getIterNode() instanceof IterNode, entry.method, context, argsCallback, closureArg, expr)) return;
// peephole inlining for trivial targets
if (closureArg == null &&
argsCallback == null &&
compileTrivialCall(fcallNode.getName(), entry.method, entry.token, context, expr)) return;
}
}
}
}
if (fcallNode instanceof SpecialArgs) {
context.getInvocationCompiler().invokeDynamicVarargs(fcallNode.getName(), null, argsCallback, CallType.FUNCTIONAL, closureArg, fcallNode.getIterNode() instanceof IterNode);
} else {
context.getInvocationCompiler().invokeDynamic(fcallNode.getName(), null, argsCallback, CallType.FUNCTIONAL, closureArg, fcallNode.getIterNode() instanceof IterNode);
}
// TODO: don't require pop
if (!expr) context.consumeCurrentValue();
}