package org.jruby.runtime.invokedynamic;
import com.headius.invokebinder.Signature;
import java.lang.invoke.MethodHandle;
import java.lang.invoke.MethodHandles.Lookup;
import java.lang.invoke.MethodType;
import java.lang.invoke.MutableCallSite;
import java.util.concurrent.atomic.AtomicLong;
import org.jruby.RubyClass;
import org.jruby.runtime.Block;
import org.jruby.runtime.CallType;
import org.jruby.runtime.ThreadContext;
import org.jruby.runtime.builtin.IRubyObject;
import org.jruby.runtime.callsite.CacheEntry;
public class JRubyCallSite extends MutableCallSite {
private static final AtomicLong SITE_ID = new AtomicLong(1);
final long siteID = SITE_ID.getAndIncrement();
final CallType callType;
final String name;
private final String file;
private final int line;
private final Signature signature;
private final Signature fullSignature;
private final int arity;
CacheEntry entry = CacheEntry.NULL_CACHE;
JRubyCallSite(Lookup lookup, MethodType type, CallType callType, String file, int line, String name) {
super(type);
this.name = name;
this.callType = callType;
Signature startSig;
int argOffset;
if (callType == CallType.SUPER) {
startSig = JRubyCallSite.STANDARD_SUPER_SIG;
argOffset = 4;
} else {
startSig = JRubyCallSite.STANDARD_SITE_SIG;
argOffset = 3;
}
int arity;
if (type.parameterType(type.parameterCount() - 1) == Block.class) {
arity = type.parameterCount() - (argOffset + 1);
if (arity == 1 && type.parameterType(argOffset) == IRubyObject[].class) {
arity = -1;
startSig = startSig.appendArg("args", IRubyObject[].class);
} else {
for (int i = 0; i < arity; i++) {
startSig = startSig.appendArg("arg" + i, IRubyObject.class);
}
}
startSig = startSig.appendArg("block", Block.class);
fullSignature = signature = startSig;
} else {
arity = type.parameterCount() - argOffset;
if (arity == 1 && type.parameterType(argOffset) == IRubyObject[].class) {
arity = -1;
startSig = startSig.appendArg("args", IRubyObject[].class);
} else {
for (int i = 0; i < arity; i++) {
startSig = startSig.appendArg("arg" + i, IRubyObject.class);
}
}
signature = startSig;
fullSignature = startSig.appendArg("block", Block.class);
}
this.arity = arity;
this.file = file;
this.line = line;
}
public int arity() {
return arity;
}
public CallType callType() {
return callType;
}
public String file() {
return file;
}
public int line() {
return line;
}
public void setInitialTarget(MethodHandle target) {
super.setTarget(target);
}
public Signature signature() {
return signature;
}
public Signature fullSignature() {
return fullSignature;
}
public static final Signature STANDARD_SITE_SIG = Signature
.returning(IRubyObject.class)
.appendArg("context", ThreadContext.class)
.appendArg("caller", IRubyObject.class)
.appendArg("self", IRubyObject.class);
public static final Signature STANDARD_SITE_SIG_1ARG = STANDARD_SITE_SIG.appendArg("arg0", IRubyObject.class);
public static final Signature STANDARD_SITE_SIG_2ARG = STANDARD_SITE_SIG_1ARG.appendArg("arg1", IRubyObject.class);
public static final Signature STANDARD_SITE_SIG_3ARG = STANDARD_SITE_SIG_2ARG.appendArg("arg2", IRubyObject.class);
public static final Signature STANDARD_SITE_SIG_NARG = STANDARD_SITE_SIG.appendArg("args", IRubyObject[].class);
public static final Signature[] STANDARD_SITE_SIGS = {
STANDARD_SITE_SIG,
STANDARD_SITE_SIG_1ARG,
STANDARD_SITE_SIG_2ARG,
STANDARD_SITE_SIG_3ARG,
STANDARD_SITE_SIG_NARG,
};
public static final Signature STANDARD_SITE_SIG_BLOCK = STANDARD_SITE_SIG.appendArg("block", Block.class);
public static final Signature STANDARD_SITE_SIG_1ARG_BLOCK = STANDARD_SITE_SIG_1ARG.appendArg("block", Block.class);
public static final Signature STANDARD_SITE_SIG_2ARG_BLOCK = STANDARD_SITE_SIG_2ARG.appendArg("block", Block.class);
public static final Signature STANDARD_SITE_SIG_3ARG_BLOCK = STANDARD_SITE_SIG_3ARG.appendArg("block", Block.class);
public static final Signature STANDARD_SITE_SIG_NARG_BLOCK = STANDARD_SITE_SIG_NARG.appendArg("block", Block.class);
public static final Signature[] STANDARD_SITE_SIGS_BLOCK = {
STANDARD_SITE_SIG_BLOCK,
STANDARD_SITE_SIG_1ARG_BLOCK,
STANDARD_SITE_SIG_2ARG_BLOCK,
STANDARD_SITE_SIG_3ARG_BLOCK,
STANDARD_SITE_SIG_NARG_BLOCK,
};
public static final Signature STANDARD_SUPER_SIG = Signature
.returning(IRubyObject.class)
.appendArg("context", ThreadContext.class)
.appendArg("caller", IRubyObject.class)
.appendArg("self", IRubyObject.class)
.appendArg("class", RubyClass.class);
}