static String jniName(Method m) { StringBuilder sb = new StringBuilder(); noUnderscore(sb, m.getName()).append("__"); appendType(sb, m.getReturnType()); Class<?>[] arr = m.getParameterTypes(); for (int i = 0; i < arr.length; i++) { appendType(sb, arr[i]); } return sb.toString(); }
/** * Takes a functional interface and its implementation (for example lambda function) and * converts it into object executable by <em>Truffle</em> languages. Here is a definition of * function returning the meaning of life as lambda expression, converting it back to * <b>Java</b> and using it: * * <pre> * TruffleObject to = JavaInterop.asTruffleFunction(Callable.<b>class</b>, () -> 42); * Callable c = JavaInterop.{@link #asJavaFunction(java.lang.Class, com.oracle.truffle.api.interop.TruffleObject) asJavaFunction}(Callable.<b>class</b>, to); * <b>assert</b> c.call() == 42; * </pre> * * @param <T> requested interface and implementation * @param functionalType interface with a single defined method - so called <em>functional * interface</em> * @param implementation implementation of the interface, or directly a lambda expression * defining the required behavior * @return an {@link Message#IS_EXECUTABLE executable} {@link TruffleObject} ready to be used in * any <em>Truffle</em> language * @since 0.9 */ public static <T> TruffleObject asTruffleFunction(Class<T> functionalType, T implementation) { if (TruffleOptions.AOT) { throw new IllegalArgumentException(); } return JavaInteropReflect.asTruffleFunction(functionalType, implementation, currentPolyglotContext()); }
static TruffleObject asTruffleViaReflection(Object obj, Object languageContext) { if (obj instanceof Proxy) { return asTruffleObjectProxy(obj, languageContext); } return JavaObject.forObject(obj, languageContext); }
readable = true; invocable = true; } else if (isJNIName(name)) { foundMethod = classDesc.lookupMethodByJNIName(name, onlyStatic); if (foundMethod != null) { Class<?> innerClass = findInnerClass(clazz, name); if (innerClass != null) { readable = true;
obj = TruffleFunction.create(languageContext, truffleObject, returnType.clazz, returnType.type); } else if (!TruffleOptions.AOT && ForeignAccess.sendHasKeys(hasKeysNode, truffleObject)) { obj = JavaInteropReflect.newProxyInstance(targetType, truffleObject, languageContext); } else { throw JavaInteropErrors.cannotConvert(languageContext, truffleObject, targetType, "Value must be executable or instantiable."); obj = JavaInteropReflect.asJavaFunction(targetType, truffleObject, languageContext); } else if (ForeignAccess.sendHasKeys(hasKeysNode, truffleObject)) { obj = JavaInteropReflect.newProxyInstance(targetType, truffleObject, languageContext); } else { if (languageContext == null) { obj = JavaInteropReflect.newProxyInstance(targetType, truffleObject, languageContext); } else { throw JavaInteropErrors.cannotConvert(languageContext, truffleObject, targetType, "Value must have members.");
@Specialization(replaces = "doCached") static Class<?> doUncached(Class<?> clazz, String name) { return JavaInteropReflect.findInnerClass(clazz, name); } }
@Specialization(replaces = "doCached") static JavaMethodDesc doUncached(Class<?> clazz, String name, boolean onlyStatic) { return JavaInteropReflect.findMethod(clazz, name, onlyStatic); } }
@Specialization(replaces = "doCached") static JavaFieldDesc doUncached(Class<?> clazz, String name, boolean onlyStatic) { return JavaInteropReflect.findField(clazz, name, onlyStatic); } }
@Specialization(replaces = "doCached") static int doUncached(Class<?> clazz, String name, boolean onlyStatic) { return JavaInteropReflect.findKeyInfo(clazz, name, onlyStatic); } }
return JavaObject.forObject(obj, languageContext); } else { return JavaInteropReflect.asTruffleViaReflection(obj, languageContext);
@TruffleBoundary public Object access(JavaObject receiver, boolean includeInternal) { if (receiver.isNull()) { throw UnsupportedMessageException.raise(Message.KEYS); } String[] fields = TruffleOptions.AOT ? new String[0] : JavaInteropReflect.findUniquePublicMemberNames(receiver.getLookupClass(), receiver.isStaticClass(), includeInternal); return JavaObject.forObject(fields, receiver.languageContext); } }
@SuppressWarnings("unused") @Specialization(guards = {"clazz == cachedClazz", "cachedName.equals(name)"}, limit = "LIMIT") static Class<?> doCached(Class<?> clazz, String name, @Cached("clazz") Class<?> cachedClazz, @Cached("name") String cachedName, @Cached("doUncached(clazz, name)") Class<?> cachedInnerClass) { assert cachedInnerClass == JavaInteropReflect.findInnerClass(clazz, name); return cachedInnerClass; }
@SuppressWarnings("unused") @Specialization(guards = {"onlyStatic == cachedStatic", "clazz == cachedClazz", "cachedName.equals(name)"}, limit = "LIMIT") static JavaMethodDesc doCached(Class<?> clazz, String name, boolean onlyStatic, @Cached("onlyStatic") boolean cachedStatic, @Cached("clazz") Class<?> cachedClazz, @Cached("name") String cachedName, @Cached("doUncached(clazz, name, onlyStatic)") JavaMethodDesc cachedMethod) { assert cachedMethod == JavaInteropReflect.findMethod(clazz, name, onlyStatic); return cachedMethod; }
@SuppressWarnings("unused") @Specialization(guards = {"onlyStatic == cachedStatic", "clazz == cachedClazz", "cachedName.equals(name)"}, limit = "LIMIT") static JavaFieldDesc doCached(Class<?> clazz, String name, boolean onlyStatic, @Cached("onlyStatic") boolean cachedStatic, @Cached("clazz") Class<?> cachedClazz, @Cached("name") String cachedName, @Cached("doUncached(clazz, name, onlyStatic)") JavaFieldDesc cachedField) { assert cachedField == JavaInteropReflect.findField(clazz, name, onlyStatic); return cachedField; }
appendType(sb, type.getComponentType()); return; noUnderscore(sb.append('L'), type.getName()); sb.append("_2");