1 /*
2 * Copyright (c) 2012, 2019, Oracle and/or its affiliates. All rights reserved.
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4 *
5 * This code is free software; you can redistribute it and/or modify it
6 * under the terms of the GNU General Public License version 2 only, as
7 * published by the Free Software Foundation. Oracle designates this
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
1134 mv.visitJumpInsn(Opcodes.GOTO, L_done);
1135
1136 // L_fallback:
1137 mv.visitLabel(L_fallback);
1138
1139 // invoke selectAlternativeName.arguments[2]
1140 System.arraycopy(preForkClasses, 0, localClasses, 0, preForkClasses.length);
1141 emitPushArgument(selectAlternativeName, 2); // get 3rd argument of selectAlternative
1142 emitAstoreInsn(receiver.index()); // store the MH in the receiver slot
1143 emitStaticInvoke(invokeBasicName);
1144
1145 // L_done:
1146 mv.visitLabel(L_done);
1147 // for now do not bother to merge typestate; just reset to the dominator state
1148 System.arraycopy(preForkClasses, 0, localClasses, 0, preForkClasses.length);
1149
1150 return invokeBasicName; // return what's on stack
1151 }
1152
1153 /**
1154 * Emit bytecode for the guardWithCatch idiom.
1155 *
1156 * The pattern looks like (Cf. MethodHandleImpl.makeGuardWithCatch):
1157 * <blockquote><pre>{@code
1158 * guardWithCatch=Lambda(a0:L,a1:L,a2:L,a3:L,a4:L,a5:L,a6:L,a7:L)=>{
1159 * t8:L=MethodHandle.invokeBasic(a4:L,a6:L,a7:L);
1160 * t9:L=MethodHandleImpl.guardWithCatch(a1:L,a2:L,a3:L,t8:L);
1161 * t10:I=MethodHandle.invokeBasic(a5:L,t9:L);t10:I}
1162 * }</pre></blockquote>
1163 *
1164 * It is compiled into bytecode equivalent of the following code:
1165 * <blockquote><pre>{@code
1166 * try {
1167 * return a1.invokeBasic(a6, a7);
1168 * } catch (Throwable e) {
1169 * if (!a2.isInstance(e)) throw e;
1170 * return a3.invokeBasic(ex, a6, a7);
1171 * }}</pre></blockquote>
1172 */
1173 private Name emitGuardWithCatch(int pos) {
1174 Name args = lambdaForm.names[pos];
1175 Name invoker = lambdaForm.names[pos+1];
1176 Name result = lambdaForm.names[pos+2];
1177
1178 Label L_startBlock = new Label();
1179 Label L_endBlock = new Label();
1180 Label L_handler = new Label();
1181 Label L_done = new Label();
1182
1183 Class<?> returnType = result.function.resolvedHandle().type().returnType();
1184 MethodType type = args.function.resolvedHandle().type()
1185 .dropParameterTypes(0,1)
1186 .changeReturnType(returnType);
1187
1188 mv.visitTryCatchBlock(L_startBlock, L_endBlock, L_handler, "java/lang/Throwable");
1189
1190 // Normal case
1191 mv.visitLabel(L_startBlock);
1192 // load target
|
1 /*
2 * Copyright (c) 2012, 2020, Oracle and/or its affiliates. All rights reserved.
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4 *
5 * This code is free software; you can redistribute it and/or modify it
6 * under the terms of the GNU General Public License version 2 only, as
7 * published by the Free Software Foundation. Oracle designates this
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
1134 mv.visitJumpInsn(Opcodes.GOTO, L_done);
1135
1136 // L_fallback:
1137 mv.visitLabel(L_fallback);
1138
1139 // invoke selectAlternativeName.arguments[2]
1140 System.arraycopy(preForkClasses, 0, localClasses, 0, preForkClasses.length);
1141 emitPushArgument(selectAlternativeName, 2); // get 3rd argument of selectAlternative
1142 emitAstoreInsn(receiver.index()); // store the MH in the receiver slot
1143 emitStaticInvoke(invokeBasicName);
1144
1145 // L_done:
1146 mv.visitLabel(L_done);
1147 // for now do not bother to merge typestate; just reset to the dominator state
1148 System.arraycopy(preForkClasses, 0, localClasses, 0, preForkClasses.length);
1149
1150 return invokeBasicName; // return what's on stack
1151 }
1152
1153 /**
1154 * Emit bytecode for the guardWithCatch idiom.
1155 *
1156 * The pattern looks like (Cf. MethodHandleImpl.makeGuardWithCatch):
1157 * <blockquote><pre>{@code
1158 * guardWithCatch=Lambda(a0:L,a1:L,a2:L,a3:L,a4:L,a5:L,a6:L,a7:L)=>{
1159 * t8:L=MethodHandle.invokeBasic(a4:L,a6:L,a7:L);
1160 * t9:L=MethodHandleImpl.guardWithCatch(a1:L,a2:L,a3:L,t8:L);
1161 * t10:I=MethodHandle.invokeBasic(a5:L,t9:L);t10:I}
1162 * }</pre></blockquote>
1163 *
1164 * It is compiled into bytecode equivalent of the following code:
1165 * <blockquote><pre>{@code
1166 * try {
1167 * return a1.invokeBasic(a6, a7);
1168 * } catch (Throwable e) {
1169 * if (!a2.isInstance(e)) throw e;
1170 * return a3.invokeBasic(ex, a6, a7);
1171 * }}</pre></blockquote>
1172 */
1173 private Name emitGuardWithCatch(int pos) {
1174 Name args = lambdaForm.names[pos];
1175 Name invoker = lambdaForm.names[pos+1];
1176 Name result = lambdaForm.names[pos+2];
1177
1178 Label L_startBlock = new Label();
1179 Label L_endBlock = new Label();
1180 Label L_handler = new Label();
1181 Label L_done = new Label();
1182
1183 Class<?> returnType = result.function.resolvedHandle().type().returnType();
1184 MethodType type = args.function.resolvedHandle().type()
1185 .dropParameterTypes(0,1)
1186 .changeReturnType(returnType);
1187
1188 mv.visitTryCatchBlock(L_startBlock, L_endBlock, L_handler, "java/lang/Throwable");
1189
1190 // Normal case
1191 mv.visitLabel(L_startBlock);
1192 // load target
|