001/* 002 * Copyright (c) 2012-2018 Institut National des Sciences Appliquées de Lyon (INSA Lyon) and others 003 * 004 * This program and the accompanying materials are made available under the 005 * terms of the Eclipse Public License 2.0 which is available at 006 * http://www.eclipse.org/legal/epl-2.0. 007 * 008 * SPDX-License-Identifier: EPL-2.0 009 */ 010 011package org.eclipse.golo.runtime; 012 013import gololang.FunctionReference; 014 015import java.lang.invoke.*; 016import java.lang.invoke.MethodHandles.Lookup; 017import java.lang.reflect.Method; 018import java.lang.reflect.Parameter; 019 020import static java.lang.invoke.MethodHandles.constant; 021import static java.lang.invoke.MethodType.genericMethodType; 022 023public final class ClosureReferenceSupport { 024 025 private ClosureReferenceSupport() { 026 throw new UnsupportedOperationException("Don't instantiate invokedynamic bootstrap class"); 027 } 028 029 public static CallSite bootstrap(Lookup caller, String name, MethodType type, String moduleClass, int arity, int varargs) throws Throwable { 030 Class<?> module = caller.lookupClass().getClassLoader().loadClass(moduleClass); 031 Method function = module.getDeclaredMethod(name, genericMethodType(arity, varargs == 1).parameterArray()); 032 function.setAccessible(true); 033 return new ConstantCallSite(constant( 034 FunctionReference.class, 035 new FunctionReference(caller.unreflect(function), parameterNames(function)))); 036 } 037 038 private static String[] parameterNames(Method function) { 039 Parameter[] parameters = function.getParameters(); 040 String[] parameterNames = new String[parameters.length]; 041 for (int i = 0; i < parameters.length; i++) { 042 parameterNames[i] = parameters[i].getName(); 043 } 044 return parameterNames; 045 } 046 047}