@Specialization void doTruffleObject(VirtualFrame frame, TruffleObject input, int fromIndex, int index, int maxIndex, @Cached("createClassProfile()") ValueProfile inputClassProfile) { executor.setInput(frame, inputClassProfile.profile(input)); executor.setFromIndex(frame, fromIndex); executor.setIndex(frame, index); executor.setMaxIndex(frame, maxIndex); // conservatively disable compact string optimizations. // TODO: maybe add an interface for TruffleObjects to announce if they are compact / ascii // strings? executor.execute(frame, false); }
@Override public Object call(CallTarget target, Object[] arguments) { try { return OptimizedDirectCallNode.callProxy(this, target, arguments, false); } catch (Throwable t) { if (exceptionProfile == null) { CompilerDirectives.transferToInterpreterAndInvalidate(); exceptionProfile = ValueProfile.createClassProfile(); } Throwable profiledT = exceptionProfile.profile(t); OptimizedCallTarget.runtime().getTvmci().onThrowable(this, null, profiledT, null); throw OptimizedCallTarget.rethrow(profiledT); } } }
@Override public Object call(Object[] arguments) { if (CompilerDirectives.inInterpreter()) { onInterpreterCall(); } try { return callProxy(this, getCurrentCallTarget(), arguments, true); } catch (Throwable t) { if (exceptionProfile == null) { CompilerDirectives.transferToInterpreterAndInvalidate(); exceptionProfile = ValueProfile.createClassProfile(); } Throwable profiledT = exceptionProfile.profile(t); OptimizedCallTarget.runtime().getTvmci().onThrowable(this, null, profiledT, null); throw OptimizedCallTarget.rethrow(profiledT); } }
@SuppressWarnings("unused") @ExplodeLoop @Specialization(guards = {"!method.isVarArgs()", "method == cachedMethod"}, limit = "LIMIT") Object doFixed(SingleMethod method, Object obj, Object[] args, PolyglotLanguageContext languageContext, @Cached("method") SingleMethod cachedMethod, @Cached("createToHost(method.getParameterCount())") ToHostNode[] toJavaNodes, @Cached("createClassProfile()") ValueProfile receiverProfile) { int arity = cachedMethod.getParameterCount(); if (args.length != arity) { throw ArityException.raise(arity, args.length); } Class<?>[] types = cachedMethod.getParameterTypes(); Type[] genericTypes = cachedMethod.getGenericParameterTypes(); Object[] convertedArguments = new Object[args.length]; for (int i = 0; i < toJavaNodes.length; i++) { convertedArguments[i] = toJavaNodes[i].execute(args[i], types[i], genericTypes[i], languageContext); } return doInvoke(cachedMethod, receiverProfile.profile(obj), convertedArguments, languageContext); }
@SuppressWarnings("unused") @ExplodeLoop @Specialization(guards = {"!method.isVarArgs()", "method == cachedMethod"}, limit = "LIMIT") Object doFixed(SingleMethodDesc method, Object obj, Object[] args, Object languageContext, @Cached("method") SingleMethodDesc cachedMethod, @Cached("createToJava(method.getParameterCount())") ToJavaNode[] toJavaNodes, @Cached("createClassProfile()") ValueProfile receiverProfile) { int arity = cachedMethod.getParameterCount(); if (args.length != arity) { throw ArityException.raise(arity, args.length); } Class<?>[] types = cachedMethod.getParameterTypes(); Type[] genericTypes = cachedMethod.getGenericParameterTypes(); Object[] convertedArguments = new Object[args.length]; for (int i = 0; i < toJavaNodes.length; i++) { convertedArguments[i] = toJavaNodes[i].execute(args[i], types[i], genericTypes[i], languageContext); } return doInvoke(cachedMethod, receiverProfile.profile(obj), convertedArguments, languageContext); }
@SuppressWarnings("unused") @Specialization(guards = {"method.isVarArgs()", "method == cachedMethod"}, limit = "LIMIT") Object doVarArgs(SingleMethodDesc method, Object obj, Object[] args, Object languageContext, @Cached("method") SingleMethodDesc cachedMethod, @Cached("create()") ToJavaNode toJavaNode, @Cached("createClassProfile()") ValueProfile receiverProfile) { int parameterCount = cachedMethod.getParameterCount(); int minArity = parameterCount - 1; if (args.length < minArity) { throw ArityException.raise(minArity, args.length); } Class<?>[] types = cachedMethod.getParameterTypes(); Type[] genericTypes = cachedMethod.getGenericParameterTypes(); Object[] convertedArguments = new Object[args.length]; for (int i = 0; i < minArity; i++) { convertedArguments[i] = toJavaNode.execute(args[i], types[i], genericTypes[i], languageContext); } if (asVarArgs(args, cachedMethod)) { for (int i = minArity; i < args.length; i++) { Class<?> expectedType = types[minArity].getComponentType(); Type expectedGenericType = getGenericComponentType(genericTypes[minArity]); convertedArguments[i] = toJavaNode.execute(args[i], expectedType, expectedGenericType, languageContext); } convertedArguments = createVarArgsArray(cachedMethod, convertedArguments, parameterCount); } else { convertedArguments[minArity] = toJavaNode.execute(args[minArity], types[minArity], genericTypes[minArity], languageContext); } return doInvoke(cachedMethod, receiverProfile.profile(obj), convertedArguments, languageContext); }
@SuppressWarnings("unused") @Specialization(guards = {"method.isVarArgs()", "method == cachedMethod"}, limit = "LIMIT") Object doVarArgs(SingleMethod method, Object obj, Object[] args, PolyglotLanguageContext languageContext, @Cached("method") SingleMethod cachedMethod, @Cached("create()") ToHostNode toJavaNode, @Cached("createClassProfile()") ValueProfile receiverProfile) { int parameterCount = cachedMethod.getParameterCount(); int minArity = parameterCount - 1; if (args.length < minArity) { throw ArityException.raise(minArity, args.length); } Class<?>[] types = cachedMethod.getParameterTypes(); Type[] genericTypes = cachedMethod.getGenericParameterTypes(); Object[] convertedArguments = new Object[args.length]; for (int i = 0; i < minArity; i++) { convertedArguments[i] = toJavaNode.execute(args[i], types[i], genericTypes[i], languageContext); } if (asVarArgs(args, cachedMethod, languageContext, toJavaNode)) { for (int i = minArity; i < args.length; i++) { Class<?> expectedType = types[minArity].getComponentType(); Type expectedGenericType = getGenericComponentType(genericTypes[minArity]); convertedArguments[i] = toJavaNode.execute(args[i], expectedType, expectedGenericType, languageContext); } convertedArguments = createVarArgsArray(cachedMethod, convertedArguments, parameterCount); } else { convertedArguments[minArity] = toJavaNode.execute(args[minArity], types[minArity], genericTypes[minArity], languageContext); } return doInvoke(cachedMethod, receiverProfile.profile(obj), convertedArguments, languageContext); }
@SuppressWarnings("unused") @ExplodeLoop @Specialization(guards = {"method == cachedMethod", "checkArgTypes(args, cachedArgTypes, toJavaNode, asVarArgs)"}, limit = "LIMIT") Object doOverloadedCached(OverloadedMethod method, Object obj, Object[] args, PolyglotLanguageContext languageContext, @Cached("method") OverloadedMethod cachedMethod, @Cached("create()") ToHostNode toJavaNode, @Cached(value = "createArgTypesArray(args)", dimensions = 1) Type[] cachedArgTypes, @Cached("selectOverload(method, args, languageContext, cachedArgTypes)") SingleMethod overload, @Cached("asVarArgs(args, overload, languageContext, toJavaNode)") boolean asVarArgs, @Cached("createClassProfile()") ValueProfile receiverProfile) { assert overload == selectOverload(method, args, languageContext); Class<?>[] types = overload.getParameterTypes(); Type[] genericTypes = overload.getGenericParameterTypes(); Object[] convertedArguments = new Object[cachedArgTypes.length]; if (asVarArgs) { assert overload.isVarArgs(); int parameterCount = overload.getParameterCount(); for (int i = 0; i < cachedArgTypes.length; i++) { Class<?> expectedType = i < parameterCount - 1 ? types[i] : types[parameterCount - 1].getComponentType(); Type expectedGenericType = i < parameterCount - 1 ? genericTypes[i] : getGenericComponentType(genericTypes[parameterCount - 1]); convertedArguments[i] = toJavaNode.execute(args[i], expectedType, expectedGenericType, languageContext); } convertedArguments = createVarArgsArray(overload, convertedArguments, parameterCount); } else { for (int i = 0; i < cachedArgTypes.length; i++) { convertedArguments[i] = toJavaNode.execute(args[i], types[i], genericTypes[i], languageContext); } } return doInvoke(overload, receiverProfile.profile(obj), convertedArguments, languageContext); }
@SuppressWarnings("unused") @ExplodeLoop @Specialization(guards = {"method == cachedMethod", "checkArgTypes(args, cachedArgTypes, toJavaNode, asVarArgs)"}, limit = "LIMIT") Object doOverloadedCached(OverloadedMethodDesc method, Object obj, Object[] args, Object languageContext, @Cached("method") OverloadedMethodDesc cachedMethod, @Cached("create()") ToJavaNode toJavaNode, @Cached(value = "createArgTypesArray(args)", dimensions = 1) Type[] cachedArgTypes, @Cached("selectOverload(method, args, languageContext, toJavaNode, cachedArgTypes)") SingleMethodDesc overload, @Cached("asVarArgs(args, overload)") boolean asVarArgs, @Cached("createClassProfile()") ValueProfile receiverProfile) { assert overload == selectOverload(method, args, languageContext, toJavaNode); Class<?>[] types = overload.getParameterTypes(); Type[] genericTypes = overload.getGenericParameterTypes(); Object[] convertedArguments = new Object[cachedArgTypes.length]; if (asVarArgs) { assert overload.isVarArgs(); int parameterCount = overload.getParameterCount(); for (int i = 0; i < cachedArgTypes.length; i++) { Class<?> expectedType = i < parameterCount - 1 ? types[i] : types[parameterCount - 1].getComponentType(); Type expectedGenericType = i < parameterCount - 1 ? genericTypes[i] : getGenericComponentType(genericTypes[parameterCount - 1]); convertedArguments[i] = toJavaNode.execute(args[i], expectedType, expectedGenericType, languageContext); } convertedArguments = createVarArgsArray(overload, convertedArguments, parameterCount); } else { for (int i = 0; i < cachedArgTypes.length; i++) { convertedArguments[i] = toJavaNode.execute(args[i], types[i], genericTypes[i], languageContext); } } return doInvoke(overload, receiverProfile.profile(obj), convertedArguments, languageContext); }