8 * particular file as subject to the "Classpath" exception as provided
9 * by Oracle in the LICENSE file that accompanied this code.
10 *
11 * This code is distributed in the hope that it will be useful, but WITHOUT
12 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
13 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
14 * version 2 for more details (a copy is included in the LICENSE file that
15 * accompanied this code).
16 *
17 * You should have received a copy of the GNU General Public License version
18 * 2 along with this work; if not, write to the Free Software Foundation,
19 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
20 *
21 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
22 * or visit www.oracle.com if you need additional information or have any
23 * questions.
24 */
25
26 package jdk.experimental.bytecode;
27
28 import java.lang.invoke.MethodHandle;
29 import java.lang.invoke.MethodType;
30 import java.util.ArrayList;
31 import java.util.HashMap;
32 import java.util.Iterator;
33 import java.util.List;
34 import java.util.Map;
35 import java.util.Map.Entry;
36 import java.util.Vector;
37 import java.util.function.Consumer;
38 import java.util.function.Supplier;
39
40 public class TypedCodeBuilder<S, T, E, C extends TypedCodeBuilder<S, T, E, C>> extends MacroCodeBuilder<S, T, E, C> {
41
42 State lastStackMapState;
43 int lastStackMapPc = -1;
44 Map<CharSequence, LocalVarInfo> lvarOffsets = new HashMap<>();
45 protected State state;
46 int depth = 0;
47 int currLocalOffset = 0;
48
49 class StatefulPendingJump extends PendingJump {
50
51 State state;
52
53 StatefulPendingJump(CharSequence label, int pc, State state) {
54 super(label, pc);
55 this.state = state;
56 }
57
58 @Override
59 boolean resolve(CharSequence label, int pc) {
60 boolean b = super.resolve(label, pc);
61 if (b) {
62 TypedCodeBuilder.this.state = TypedCodeBuilder.this.state.merge(state);
63 }
64 return b;
65 }
66 }
67
68 class LocalVarInfo {
225 state.pop(tag);
226 state.push(typeHelper.nullType());
227 state.push(typeHelper.nullType());
228 return op.get();
229 }
230 }
231
232 public class State {
233 public final ArrayList<T> stack;
234 public final Vector<T> locals;
235
236 State(ArrayList<T> stack, Vector<T> locals) {
237 this.stack = stack;
238 this.locals = locals;
239 }
240
241 State() {
242 this(new ArrayList<>(), new Vector<>());
243 }
244
245 void push(TypeTag tag) {
246 switch (tag) {
247 case A:
248 case V:
249 throw new IllegalStateException("Bad type tag");
250 default:
251 push(typeHelper.fromTag(tag));
252 }
253 }
254
255 void push(T t) {
256 stack.add(t);
257 if (width(t) == 2) {
258 stack.add(null);
259 }
260 if (stack.size() > stacksize) {
261 stacksize = stack.size();
262 }
263 }
264
265 T peek() {
266 return stack.get(stack.size() - 1);
267 }
268
269 T tosType() {
270 T tos = peek();
271 if (tos == null) {
272 //double slot
273 tos = stack.get(stack.size() - 2);
274 }
275 return tos;
276 }
277
278 T popInternal() {
279 return stack.remove(stack.size() - 1);
280 }
281
282 @SuppressWarnings("unchecked")
283 T pop() {
284 if (stack.size() == 0 || peek() == null) throw new IllegalStateException();
285 return popInternal();
286 }
287
288 T pop2() {
289 T o = stack.get(stack.size() - 2);
290 TypeTag t = typeHelper.tag(o);
291 if (t.width != 2) throw new IllegalStateException();
292 popInternal();
293 popInternal();
294 return o;
295 }
296
297 T pop(TypeTag t) {
298 return (t.width() == 2) ?
299 pop2() : pop();
300 }
301
302 void load(TypeTag tag, int index) {
303 if (tag == TypeTag.A) throw new IllegalStateException("Bad type tag");
955 }
956
957 T ldcType(Object o) {
958 if (o instanceof Double) {
959 return typeHelper.fromTag(TypeTag.D);
960 } else if (o instanceof Long) {
961 return typeHelper.fromTag(TypeTag.J);
962 } else if (o instanceof Float) {
963 return typeHelper.fromTag(TypeTag.F);
964 } else if (o instanceof Integer) {
965 return typeHelper.fromTag(TypeTag.I);
966 } else if (o instanceof Class<?>) {
967 return typeHelper.type(typeHelper.symbolFrom("java/lang/Class"));
968 } else if (o instanceof String) {
969 return typeHelper.type(typeHelper.symbolFrom("java/lang/String"));
970 } else if (o instanceof MethodHandle) {
971 return typeHelper.type(typeHelper.symbolFrom("java/lang/invoke/MethodHandle"));
972 } else if (o instanceof MethodType) {
973 return typeHelper.type(typeHelper.symbolFrom("java/lang/invoke/MethodType"));
974 } else {
975 throw new IllegalStateException();
976 }
977 }
978
979 public C load(int index) {
980 return load(typeHelper.tag(state.locals.get(index)), index);
981 }
982
983 public C store(int index) {
984 return store(typeHelper.tag(state.tosType()), index);
985 }
986
987 @Override
988 public C withLocalSize(int localsize) {
989 throw new IllegalStateException("Local size automatically computed");
990 }
991
992 @Override
993 public C withStackSize(int stacksize) {
994 throw new IllegalStateException("Stack size automatically computed");
995 }
|
8 * particular file as subject to the "Classpath" exception as provided
9 * by Oracle in the LICENSE file that accompanied this code.
10 *
11 * This code is distributed in the hope that it will be useful, but WITHOUT
12 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
13 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
14 * version 2 for more details (a copy is included in the LICENSE file that
15 * accompanied this code).
16 *
17 * You should have received a copy of the GNU General Public License version
18 * 2 along with this work; if not, write to the Free Software Foundation,
19 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
20 *
21 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
22 * or visit www.oracle.com if you need additional information or have any
23 * questions.
24 */
25
26 package jdk.experimental.bytecode;
27
28 import jdk.experimental.value.MethodHandleBuilder;
29
30 import java.lang.invoke.MethodHandle;
31 import java.lang.invoke.MethodType;
32 import java.util.ArrayList;
33 import java.util.HashMap;
34 import java.util.Iterator;
35 import java.util.List;
36 import java.util.Map;
37 import java.util.Map.Entry;
38 import java.util.Vector;
39 import java.util.function.Consumer;
40 import java.util.function.Supplier;
41
42 public class TypedCodeBuilder<S, T, E, C extends TypedCodeBuilder<S, T, E, C>> extends MacroCodeBuilder<S, T, E, C> {
43
44 State lastStackMapState;
45 int lastStackMapPc = -1;
46 Map<CharSequence, LocalVarInfo> lvarOffsets = new HashMap<>();
47 protected State state;
48 int depth = 0;
49 int currLocalOffset = 0;
50
51 public State state() {
52 return state;
53 }
54
55 class StatefulPendingJump extends PendingJump {
56
57 State state;
58
59 StatefulPendingJump(CharSequence label, int pc, State state) {
60 super(label, pc);
61 this.state = state;
62 }
63
64 @Override
65 boolean resolve(CharSequence label, int pc) {
66 boolean b = super.resolve(label, pc);
67 if (b) {
68 TypedCodeBuilder.this.state = TypedCodeBuilder.this.state.merge(state);
69 }
70 return b;
71 }
72 }
73
74 class LocalVarInfo {
231 state.pop(tag);
232 state.push(typeHelper.nullType());
233 state.push(typeHelper.nullType());
234 return op.get();
235 }
236 }
237
238 public class State {
239 public final ArrayList<T> stack;
240 public final Vector<T> locals;
241
242 State(ArrayList<T> stack, Vector<T> locals) {
243 this.stack = stack;
244 this.locals = locals;
245 }
246
247 State() {
248 this(new ArrayList<>(), new Vector<>());
249 }
250
251 // FIXME should be package-private
252 public void push(TypeTag tag) {
253 switch (tag) {
254 case A:
255 case V:
256 throw new IllegalStateException("Bad type tag");
257 default:
258 push(typeHelper.fromTag(tag));
259 }
260 }
261
262 // FIXME should be package-private
263 public void push(T t) {
264 stack.add(t);
265 if (width(t) == 2) {
266 stack.add(null);
267 }
268 if (stack.size() > stacksize) {
269 stacksize = stack.size();
270 }
271 }
272
273 T peek() {
274 return stack.get(stack.size() - 1);
275 }
276
277 T tosType() {
278 T tos = peek();
279 if (tos == null) {
280 //double slot
281 tos = stack.get(stack.size() - 2);
282 }
283 return tos;
284 }
285
286 T popInternal() {
287 return stack.remove(stack.size() - 1);
288 }
289
290 // FIXME should be package-private
291 @SuppressWarnings("unchecked")
292 public T pop() {
293 if (stack.size() == 0 || peek() == null) throw new IllegalStateException();
294 return popInternal();
295 }
296
297 T pop2() {
298 T o = stack.get(stack.size() - 2);
299 TypeTag t = typeHelper.tag(o);
300 if (t.width != 2) throw new IllegalStateException();
301 popInternal();
302 popInternal();
303 return o;
304 }
305
306 T pop(TypeTag t) {
307 return (t.width() == 2) ?
308 pop2() : pop();
309 }
310
311 void load(TypeTag tag, int index) {
312 if (tag == TypeTag.A) throw new IllegalStateException("Bad type tag");
964 }
965
966 T ldcType(Object o) {
967 if (o instanceof Double) {
968 return typeHelper.fromTag(TypeTag.D);
969 } else if (o instanceof Long) {
970 return typeHelper.fromTag(TypeTag.J);
971 } else if (o instanceof Float) {
972 return typeHelper.fromTag(TypeTag.F);
973 } else if (o instanceof Integer) {
974 return typeHelper.fromTag(TypeTag.I);
975 } else if (o instanceof Class<?>) {
976 return typeHelper.type(typeHelper.symbolFrom("java/lang/Class"));
977 } else if (o instanceof String) {
978 return typeHelper.type(typeHelper.symbolFrom("java/lang/String"));
979 } else if (o instanceof MethodHandle) {
980 return typeHelper.type(typeHelper.symbolFrom("java/lang/invoke/MethodHandle"));
981 } else if (o instanceof MethodType) {
982 return typeHelper.type(typeHelper.symbolFrom("java/lang/invoke/MethodType"));
983 } else {
984 return typeHelper.type(typeHelper.symbolFrom("java/lang/Object")); // CP patching support
985 }
986 }
987
988 public C load(int index) {
989 return load(typeHelper.tag(state.locals.get(index)), index);
990 }
991
992 public C store(int index) {
993 return store(typeHelper.tag(state.tosType()), index);
994 }
995
996 @Override
997 public C withLocalSize(int localsize) {
998 throw new IllegalStateException("Local size automatically computed");
999 }
1000
1001 @Override
1002 public C withStackSize(int stacksize) {
1003 throw new IllegalStateException("Stack size automatically computed");
1004 }
|