package com.oracle.truffle.js.nodes.unary;
import com.oracle.truffle.api.dsl.Cached;
import com.oracle.truffle.api.dsl.GenerateUncached;
import com.oracle.truffle.api.dsl.ImportStatic;
import com.oracle.truffle.api.dsl.Specialization;
import com.oracle.truffle.api.interop.InteropLibrary;
import com.oracle.truffle.api.library.CachedLibrary;
import com.oracle.truffle.api.object.DynamicObject;
import com.oracle.truffle.api.object.Shape;
import com.oracle.truffle.js.nodes.JavaScriptBaseNode;
import com.oracle.truffle.js.runtime.BigInt;
import com.oracle.truffle.js.runtime.JSConfig;
import com.oracle.truffle.js.runtime.JSRuntime;
import com.oracle.truffle.js.runtime.Symbol;
@ImportStatic({JSConfig.class})
@GenerateUncached
public abstract class IsCallableNode extends JavaScriptBaseNode {
protected IsCallableNode() {
}
public abstract boolean executeBoolean(Object operand);
@SuppressWarnings("unused")
@Specialization(guards = {"shape.check(function)", "isJSFunctionShape(shape)"}, limit = "1")
protected static boolean doJSFunctionShape(DynamicObject function,
@Cached("function.getShape()") Shape shape) {
return true;
}
@SuppressWarnings("unused")
@Specialization(guards = "isJSFunction(function)", replaces = "doJSFunctionShape")
protected static boolean doJSFunction(DynamicObject function) {
return true;
}
@Specialization(guards = "isJSProxy(proxy)")
protected static boolean doJSProxy(DynamicObject proxy) {
return JSRuntime.isCallableProxy(proxy);
}
@Specialization(guards = {"isJSDynamicObject(object)", "!isJSFunction(object)", "!isJSProxy(object)"})
protected static boolean doJSTypeOther(@SuppressWarnings("unused") DynamicObject object) {
return false;
}
@Specialization(guards = "isForeignObject(obj)", limit = "InteropLibraryLimit")
protected static boolean doTruffleObject(Object obj,
@CachedLibrary("obj") InteropLibrary interop) {
return interop.isExecutable(obj) || interop.isInstantiable(obj);
}
@Specialization
protected static boolean doCharSequence(@SuppressWarnings("unused") CharSequence charSequence) {
return false;
}
@Specialization
protected static boolean doNumber(@SuppressWarnings("unused") Number number) {
return false;
}
@Specialization
protected static boolean doBoolean(@SuppressWarnings("unused") boolean value) {
return false;
}
@Specialization
protected static boolean doSymbol(@SuppressWarnings("unused") Symbol symbol) {
return false;
}
@Specialization
protected static boolean doBigInt(@SuppressWarnings("unused") BigInt bigInt) {
return false;
}
public static IsCallableNode create() {
return IsCallableNodeGen.create();
}
}