Line 0
Link Here
|
|
|
1 |
package com.sun.tools.hc; |
2 |
|
3 |
import java.io.UnsupportedEncodingException; |
4 |
import java.lang.invoke.CallSite; |
5 |
import java.lang.invoke.LambdaConversionException; |
6 |
import java.lang.invoke.MethodHandle; |
7 |
import java.lang.invoke.MethodHandles; |
8 |
import java.lang.invoke.MethodType; |
9 |
import java.lang.reflect.Array; |
10 |
|
11 |
|
12 |
|
13 |
/** |
14 |
* |
15 |
* @author Tomas Zezula |
16 |
*/ |
17 |
public class LambdaMetafactory { |
18 |
|
19 |
public static final int FLAG_SERIALIZABLE = 1 << 0; |
20 |
public static final int FLAG_MARKERS = 1 << 1; |
21 |
public static final int FLAG_BRIDGES = 1 << 2; |
22 |
|
23 |
private static final byte[] PATTERN; |
24 |
private static final byte[] REPLACE; |
25 |
static { |
26 |
try { |
27 |
PATTERN = "java/lang/invoke/LambdaMetafactory".getBytes("UTF-8"); //NOI18N |
28 |
REPLACE = "com/sun/tools/hc/LambdaMetafactory".getBytes("UTF-8"); //NOI18N |
29 |
} catch (UnsupportedEncodingException e) { |
30 |
throw new RuntimeException(e); |
31 |
} |
32 |
} |
33 |
|
34 |
public static CallSite metafactory(MethodHandles.Lookup caller, |
35 |
String invokedName, |
36 |
MethodType invokedType, |
37 |
MethodType samMethodType, |
38 |
MethodHandle implMethod, |
39 |
MethodType instantiatedMethodType) throws LambdaConversionException { |
40 |
return java.lang.invoke.LambdaMetafactory.metafactory( |
41 |
caller, |
42 |
invokedName, |
43 |
translate(invokedType), |
44 |
samMethodType, |
45 |
implMethod, |
46 |
instantiatedMethodType); |
47 |
} |
48 |
|
49 |
public static CallSite altMetafactory(MethodHandles.Lookup caller, |
50 |
String invokedName, |
51 |
MethodType invokedType, |
52 |
Object... args) throws LambdaConversionException { |
53 |
return java.lang.invoke.LambdaMetafactory.altMetafactory( |
54 |
caller, |
55 |
invokedName, |
56 |
translate(invokedType), |
57 |
args); |
58 |
} |
59 |
|
60 |
public static byte[] translateClassFile( |
61 |
final byte[] data, |
62 |
final int start, |
63 |
final int end) { |
64 |
for (int index = find(data,start,end,PATTERN); |
65 |
index >= 0; |
66 |
index = find(data,index+PATTERN.length, end, PATTERN)) { |
67 |
System.arraycopy(REPLACE, 0, data, index, REPLACE.length); |
68 |
} |
69 |
return data; |
70 |
} |
71 |
|
72 |
private static int find( |
73 |
final byte[] data, |
74 |
final int start, |
75 |
final int end, |
76 |
final byte[] pattern) { |
77 |
int i = start; |
78 |
int j = 0; |
79 |
for (; i < end && j < pattern.length; i++) { |
80 |
if (data[i] == pattern[j]) { |
81 |
j++; |
82 |
} else { |
83 |
j=0; |
84 |
} |
85 |
} |
86 |
return j == pattern.length ? |
87 |
i - j : |
88 |
-1; |
89 |
} |
90 |
|
91 |
private static MethodType translate(MethodType mt) { |
92 |
final Class<?> rt = translate(mt.returnType()); |
93 |
final Class<?>[] ptypes = new Class<?>[mt.parameterCount()]; |
94 |
for (int i = 0; i < ptypes.length; i++) { |
95 |
ptypes[i] = translate(mt.parameterType(i)); |
96 |
} |
97 |
return MethodType.methodType(rt, ptypes); |
98 |
} |
99 |
|
100 |
private static Class<?> translate(Class<?> clz) { |
101 |
if (clz.isPrimitive()) { |
102 |
return clz; |
103 |
} else if (clz.isArray()) { |
104 |
final Class<?> oldCompType = clz.getComponentType(); |
105 |
final Class<?> newCompType = translate(oldCompType); |
106 |
if (oldCompType != newCompType) { |
107 |
clz = Array.newInstance(newCompType, 0).getClass(); |
108 |
} |
109 |
return clz; |
110 |
} else { |
111 |
try { |
112 |
final String fqn = clz.getName(); |
113 |
return LambdaMetafactory.class.getClassLoader().loadClass(fqn); |
114 |
} catch (ClassNotFoundException cnf) { |
115 |
return clz; |
116 |
} |
117 |
} |
118 |
} |
119 |
} |