Path: blob/jdk8u272-b10-aarch32-20201026/jdk/test/java/lang/invoke/LFCaching/TestMethods.java
48795 views
/*1* Copyright (c) 2014, 2015, Oracle and/or its affiliates. All rights reserved.2* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.3*4* This code is free software; you can redistribute it and/or modify it5* under the terms of the GNU General Public License version 2 only, as6* published by the Free Software Foundation.7*8* This code is distributed in the hope that it will be useful, but WITHOUT9* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or10* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License11* version 2 for more details (a copy is included in the LICENSE file that12* accompanied this code).13*14* You should have received a copy of the GNU General Public License version15* 2 along with this work; if not, write to the Free Software Foundation,16* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.17*18* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA19* or visit www.oracle.com if you need additional information or have any20* questions.21*/2223import com.oracle.testlibrary.jsr292.Helper;24import java.lang.invoke.MethodHandle;25import java.lang.invoke.MethodHandles;26import java.lang.invoke.MethodType;27import java.lang.reflect.Array;28import java.util.ArrayList;29import java.util.HashMap;30import java.util.List;31import java.util.Map;3233/**34* Enumeration containing information about methods from35* {@code j.l.i.MethodHandles} class that are used for testing lambda forms36* caching.37*38* @author kshefov39*/40public enum TestMethods {4142FOLD_ARGUMENTS("foldArguments") {43@Override44public Map<String, Object> getTestCaseData() {45Map<String, Object> data = new HashMap<>();46int desiredArity = Helper.RNG.nextInt(super.maxArity);47MethodType mtTarget = TestMethods.randomMethodTypeGenerator(desiredArity);48data.put("mtTarget", mtTarget);49// Arity after reducing because of long and double take 2 slots.50int realArity = mtTarget.parameterCount();51int modifierMHArgNum = Helper.RNG.nextInt(realArity + 1);52data.put("modifierMHArgNum", modifierMHArgNum);53Class<?> combinerReturnType;54if (realArity == 0) {55combinerReturnType = void.class;56} else {57combinerReturnType = Helper.RNG.nextBoolean() ? void.class : mtTarget.parameterType(0);58}59data.put("combinerReturnType", combinerReturnType);60return data;61}6263@Override64protected MethodHandle getMH(Map<String, Object> data, TestMethods.Kind kind) throws NoSuchMethodException, IllegalAccessException {65MethodType mtTarget = (MethodType) data.get("mtTarget");66Class<?> combinerReturnType = (Class) data.get("combinerReturnType");67int modifierMHArgNum = (int) data.get("modifierMHArgNum");68MethodHandle target = TestMethods.methodHandleGenerator(mtTarget.returnType(),69mtTarget.parameterList(), kind);70Class<?> rType = mtTarget.returnType();71int combListStart = (combinerReturnType == void.class) ? 0 : 1;72if (modifierMHArgNum < combListStart) {73modifierMHArgNum = combListStart;74}75MethodHandle combiner = TestMethods.methodHandleGenerator(combinerReturnType,76mtTarget.parameterList().subList(combListStart,77modifierMHArgNum), kind);78return MethodHandles.foldArguments(target, combiner);79}80},81DROP_ARGUMENTS("dropArguments") {82@Override83public Map<String, Object> getTestCaseData() {84Map<String, Object> data = new HashMap<>();85int desiredArity = Helper.RNG.nextInt(super.maxArity);86MethodType mtTarget = TestMethods.randomMethodTypeGenerator(desiredArity);87data.put("mtTarget", mtTarget);88// Arity after reducing because of long and double take 2 slots.89int realArity = mtTarget.parameterCount();90int dropArgsPos = Helper.RNG.nextInt(realArity + 1);91data.put("dropArgsPos", dropArgsPos);92MethodType mtDropArgs = TestMethods.randomMethodTypeGenerator(93Helper.RNG.nextInt(super.maxArity - realArity));94data.put("mtDropArgs", mtDropArgs);95return data;96}9798@Override99protected MethodHandle getMH(Map<String, Object> data, TestMethods.Kind kind) throws NoSuchMethodException, IllegalAccessException {100MethodType mtTarget = (MethodType) data.get("mtTarget");101MethodType mtDropArgs = (MethodType) data.get("mtDropArgs");102int dropArgsPos = (int) data.get("dropArgsPos");103MethodHandle target = TestMethods.methodHandleGenerator(mtTarget.returnType(),104mtTarget.parameterList(), kind);105int mtTgtSlotsCount = TestMethods.argSlotsCount(mtTarget);106int mtDASlotsCount = TestMethods.argSlotsCount(mtDropArgs);107List<Class<?>> fakeParList;108if (mtTgtSlotsCount + mtDASlotsCount > super.maxArity - 1) {109fakeParList = TestMethods.reduceArgListToSlotsCount(mtDropArgs.parameterList(),110super.maxArity - mtTgtSlotsCount - 1);111} else {112fakeParList = mtDropArgs.parameterList();113}114return MethodHandles.dropArguments(target, dropArgsPos, fakeParList);115}116},117EXPLICIT_CAST_ARGUMENTS("explicitCastArguments", Helper.MAX_ARITY / 2) {118@Override119public Map<String, Object> getTestCaseData() {120Map<String, Object> data = new HashMap<>();121int desiredArity = Helper.RNG.nextInt(super.maxArity);122MethodType mtTarget = TestMethods.randomMethodTypeGenerator(desiredArity);123data.put("mtTarget", mtTarget);124// Arity after reducing because of long and double take 2 slots.125int realArity = mtTarget.parameterCount();126MethodType mtExcplCastArgs = TestMethods.randomMethodTypeGenerator(realArity);127if (mtTarget.returnType() == void.class) {128mtExcplCastArgs = MethodType.methodType(void.class,129mtExcplCastArgs.parameterArray());130}131if (mtExcplCastArgs.returnType() == void.class) {132mtExcplCastArgs = MethodType.methodType(mtTarget.returnType(),133mtExcplCastArgs.parameterArray());134}135data.put("mtExcplCastArgs", mtExcplCastArgs);136return data;137}138139@Override140protected MethodHandle getMH(Map<String, Object> data, TestMethods.Kind kind) throws NoSuchMethodException, IllegalAccessException {141MethodType mtTarget = (MethodType) data.get("mtTarget");142MethodType mtExcplCastArgs = (MethodType) data.get("mtExcplCastArgs");143MethodHandle target = TestMethods.methodHandleGenerator(mtTarget.returnType(),144mtTarget.parameterList(), kind);145return MethodHandles.explicitCastArguments(target, mtExcplCastArgs);146}147},148FILTER_ARGUMENTS("filterArguments", Helper.MAX_ARITY / 2) {149@Override150public Map<String, Object> getTestCaseData() {151Map<String, Object> data = new HashMap<>();152int desiredArity = Helper.RNG.nextInt(super.maxArity);153MethodType mtTarget = TestMethods.randomMethodTypeGenerator(desiredArity);154data.put("mtTarget", mtTarget);155// Arity after reducing because of long and double take 2 slots.156int realArity = mtTarget.parameterCount();157int filterArgsPos = Helper.RNG.nextInt(realArity + 1);158data.put("filterArgsPos", filterArgsPos);159int filtersArgsArrayLength = Helper.RNG.nextInt(realArity + 1 - filterArgsPos);160data.put("filtersArgsArrayLength", filtersArgsArrayLength);161MethodType mtFilter = TestMethods.randomMethodTypeGenerator(filtersArgsArrayLength);162data.put("mtFilter", mtFilter);163return data;164}165166@Override167protected MethodHandle getMH(Map<String, Object> data, TestMethods.Kind kind) throws NoSuchMethodException, IllegalAccessException {168MethodType mtTarget = (MethodType) data.get("mtTarget");169MethodType mtFilter = (MethodType) data.get("mtFilter");170int filterArgsPos = (int) data.get("filterArgsPos");171int filtersArgsArrayLength = (int) data.get("filtersArgsArrayLength");172MethodHandle target = TestMethods.methodHandleGenerator(mtTarget.returnType(),173mtTarget.parameterList(), kind);174MethodHandle[] filters = new MethodHandle[filtersArgsArrayLength];175for (int i = 0; i < filtersArgsArrayLength; i++) {176filters[i] = TestMethods.filterGenerator(mtFilter.parameterType(i),177mtTarget.parameterType(filterArgsPos + i), kind);178}179return MethodHandles.filterArguments(target, filterArgsPos, filters);180}181},182FILTER_RETURN_VALUE("filterReturnValue") {183@Override184public Map<String, Object> getTestCaseData() {185Map<String, Object> data = new HashMap<>();186int desiredArity = Helper.RNG.nextInt(super.maxArity);187MethodType mtTarget = TestMethods.randomMethodTypeGenerator(desiredArity);188data.put("mtTarget", mtTarget);189// Arity after reducing because of long and double take 2 slots.190int realArity = mtTarget.parameterCount();191int filterArgsPos = Helper.RNG.nextInt(realArity + 1);192int filtersArgsArrayLength = Helper.RNG.nextInt(realArity + 1 - filterArgsPos);193MethodType mtFilter = TestMethods.randomMethodTypeGenerator(filtersArgsArrayLength);194data.put("mtFilter", mtFilter);195return data;196}197198@Override199protected MethodHandle getMH(Map<String, Object> data, TestMethods.Kind kind) throws NoSuchMethodException, IllegalAccessException {200MethodType mtTarget = (MethodType) data.get("mtTarget");201MethodType mtFilter = (MethodType) data.get("mtFilter");202MethodHandle target = TestMethods.methodHandleGenerator(mtTarget.returnType(),203mtTarget.parameterList(), kind);204MethodHandle filter = TestMethods.filterGenerator(mtTarget.returnType(),205mtFilter.returnType(), kind);206return MethodHandles.filterReturnValue(target, filter);207}208},209INSERT_ARGUMENTS("insertArguments", Helper.MAX_ARITY - 3) {210@Override211public Map<String, Object> getTestCaseData() {212Map<String, Object> data = new HashMap<>();213int desiredArity = Helper.RNG.nextInt(super.maxArity);214MethodType mtTarget = TestMethods.randomMethodTypeGenerator(desiredArity);215data.put("mtTarget", mtTarget);216// Arity after reducing because of long and double take 2 slots.217int realArity = mtTarget.parameterCount();218int insertArgsPos = Helper.RNG.nextInt(realArity + 1);219data.put("insertArgsPos", insertArgsPos);220int insertArgsArrayLength = Helper.RNG.nextInt(realArity + 1 - insertArgsPos);221MethodType mtInsertArgs = MethodType.methodType(void.class, mtTarget.parameterList()222.subList(insertArgsPos, insertArgsPos + insertArgsArrayLength));223data.put("mtInsertArgs", mtInsertArgs);224return data;225}226227@Override228protected MethodHandle getMH(Map<String, Object> data, TestMethods.Kind kind) throws NoSuchMethodException, IllegalAccessException {229MethodType mtTarget = (MethodType) data.get("mtTarget");230MethodType mtInsertArgs = (MethodType) data.get("mtInsertArgs");231int insertArgsPos = (int) data.get("insertArgsPos");232MethodHandle target = TestMethods.methodHandleGenerator(mtTarget.returnType(),233mtTarget.parameterList(), kind);234Object[] insertList = Helper.randomArgs(mtInsertArgs.parameterList());235return MethodHandles.insertArguments(target, insertArgsPos, insertList);236}237},238PERMUTE_ARGUMENTS("permuteArguments", Helper.MAX_ARITY / 2) {239@Override240public Map<String, Object> getTestCaseData() {241Map<String, Object> data = new HashMap<>();242int desiredArity = Helper.RNG.nextInt(super.maxArity);243MethodType mtTarget = TestMethods.randomMethodTypeGenerator(desiredArity);244// Arity after reducing because of long and double take 2 slots.245int realArity = mtTarget.parameterCount();246int[] permuteArgsReorderArray = new int[realArity];247int mtPermuteArgsNum = Helper.RNG.nextInt(Helper.MAX_ARITY);248mtPermuteArgsNum = mtPermuteArgsNum == 0 ? 1 : mtPermuteArgsNum;249MethodType mtPermuteArgs = TestMethods.randomMethodTypeGenerator(mtPermuteArgsNum);250mtTarget = mtTarget.changeReturnType(mtPermuteArgs.returnType());251for (int i = 0; i < realArity; i++) {252int mtPermuteArgsParNum = Helper.RNG.nextInt(mtPermuteArgs.parameterCount());253permuteArgsReorderArray[i] = mtPermuteArgsParNum;254mtTarget = mtTarget.changeParameterType(255i, mtPermuteArgs.parameterType(mtPermuteArgsParNum));256}257data.put("mtTarget", mtTarget);258data.put("permuteArgsReorderArray", permuteArgsReorderArray);259data.put("mtPermuteArgs", mtPermuteArgs);260return data;261}262263@Override264protected MethodHandle getMH(Map<String, Object> data, TestMethods.Kind kind) throws NoSuchMethodException, IllegalAccessException {265MethodType mtTarget = (MethodType) data.get("mtTarget");266MethodType mtPermuteArgs = (MethodType) data.get("mtPermuteArgs");267int[] permuteArgsReorderArray = (int[]) data.get("permuteArgsReorderArray");268MethodHandle target = TestMethods.methodHandleGenerator(mtTarget.returnType(),269mtTarget.parameterList(), kind);270return MethodHandles.permuteArguments(target, mtPermuteArgs, permuteArgsReorderArray);271}272},273THROW_EXCEPTION("throwException") {274@Override275public Map<String, Object> getTestCaseData() {276Map<String, Object> data = new HashMap<>();277int desiredArity = Helper.RNG.nextInt(super.maxArity);278MethodType mtTarget = TestMethods.randomMethodTypeGenerator(desiredArity);279data.put("mtTarget", mtTarget);280return data;281}282283@Override284protected MethodHandle getMH(Map<String, Object> data, TestMethods.Kind kind) {285MethodType mtTarget = (MethodType) data.get("mtTarget");286Class<?> rType = mtTarget.returnType();287return MethodHandles.throwException(rType, Exception.class288);289}290},291GUARD_WITH_TEST("guardWithTest") {292@Override293public Map<String, Object> getTestCaseData() {294Map<String, Object> data = new HashMap<>();295int desiredArity = Helper.RNG.nextInt(super.maxArity);296MethodType mtTarget = TestMethods.randomMethodTypeGenerator(desiredArity);297data.put("mtTarget", mtTarget);298// Arity after reducing because of long and double take 2 slots.299int realArity = mtTarget.parameterCount();300int modifierMHArgNum = Helper.RNG.nextInt(realArity + 1);301data.put("modifierMHArgNum", modifierMHArgNum);302return data;303}304305@Override306protected MethodHandle getMH(Map<String, Object> data, TestMethods.Kind kind) throws NoSuchMethodException, IllegalAccessException {307MethodType mtTarget = (MethodType) data.get("mtTarget");308int modifierMHArgNum = (int) data.get("modifierMHArgNum");309TestMethods.Kind targetKind;310TestMethods.Kind fallbackKind;311if (kind.equals(TestMethods.Kind.ONE)) {312targetKind = TestMethods.Kind.ONE;313fallbackKind = TestMethods.Kind.TWO;314} else {315targetKind = TestMethods.Kind.TWO;316fallbackKind = TestMethods.Kind.ONE;317}318MethodHandle target = TestMethods.methodHandleGenerator(mtTarget.returnType(),319mtTarget.parameterList(), targetKind);320MethodHandle fallback = TestMethods.methodHandleGenerator(mtTarget.returnType(),321mtTarget.parameterList(), fallbackKind);322MethodHandle test = TestMethods.methodHandleGenerator(boolean.class,323mtTarget.parameterList().subList(0, modifierMHArgNum), kind);324return MethodHandles.guardWithTest(test, target, fallback);325}326},327CATCH_EXCEPTION("catchException") {328@Override329public Map<String, Object> getTestCaseData() {330Map<String, Object> data = new HashMap<>();331int desiredArity = Helper.RNG.nextInt(super.maxArity);332MethodType mtTarget = TestMethods.randomMethodTypeGenerator(desiredArity);333data.put("mtTarget", mtTarget);334// Arity after reducing because of long and double take 2 slots.335int realArity = mtTarget.parameterCount();336int modifierMHArgNum = Helper.RNG.nextInt(realArity + 1);337data.put("modifierMHArgNum", modifierMHArgNum);338return data;339}340341@Override342protected MethodHandle getMH(Map<String, Object> data, TestMethods.Kind kind) throws NoSuchMethodException, IllegalAccessException {343MethodType mtTarget = (MethodType) data.get("mtTarget");344int modifierMHArgNum = (int) data.get("modifierMHArgNum");345MethodHandle target;346if (kind.equals(TestMethods.Kind.ONE)) {347target = TestMethods.methodHandleGenerator(mtTarget.returnType(),348mtTarget.parameterList(), TestMethods.Kind.ONE);349} else {350target = TestMethods.methodHandleGenerator(mtTarget.returnType(),351mtTarget.parameterList(), TestMethods.Kind.EXCEPT);352}353List<Class<?>> handlerParamList = new ArrayList<>(mtTarget.parameterCount() + 1);354handlerParamList.add(Exception.class);355handlerParamList.addAll(mtTarget.parameterList().subList(0, modifierMHArgNum));356MethodHandle handler = TestMethods.methodHandleGenerator(357mtTarget.returnType(), handlerParamList, TestMethods.Kind.TWO);358return MethodHandles.catchException(target, Exception.class, handler);359}360},361INVOKER("invoker", Helper.MAX_ARITY - 1) {362@Override363public Map<String, Object> getTestCaseData() {364Map<String, Object> data = new HashMap<>();365int desiredArity = Helper.RNG.nextInt(super.maxArity);366MethodType mtTarget = TestMethods.randomMethodTypeGenerator(desiredArity);367data.put("mtTarget", mtTarget);368return data;369}370371@Override372protected MethodHandle getMH(Map<String, Object> data, TestMethods.Kind kind) {373MethodType mtTarget = (MethodType) data.get("mtTarget");374return MethodHandles.invoker(mtTarget);375}376},377EXACT_INVOKER("exactInvoker", Helper.MAX_ARITY - 1) {378@Override379public Map<String, Object> getTestCaseData() {380Map<String, Object> data = new HashMap<>();381int desiredArity = Helper.RNG.nextInt(super.maxArity);382MethodType mtTarget = TestMethods.randomMethodTypeGenerator(desiredArity);383data.put("mtTarget", mtTarget);384return data;385}386387@Override388protected MethodHandle getMH(Map<String, Object> data, TestMethods.Kind kind) {389MethodType mtTarget = (MethodType) data.get("mtTarget");390return MethodHandles.exactInvoker(mtTarget);391}392},393SPREAD_INVOKER("spreadInvoker", Helper.MAX_ARITY - 1) {394@Override395public Map<String, Object> getTestCaseData() {396Map<String, Object> data = new HashMap<>();397int desiredArity = Helper.RNG.nextInt(super.maxArity);398MethodType mtTarget = TestMethods.randomMethodTypeGenerator(desiredArity);399data.put("mtTarget", mtTarget);400// Arity after reducing because of long and double take 2 slots.401int realArity = mtTarget.parameterCount();402int modifierMHArgNum = Helper.RNG.nextInt(realArity + 1);403data.put("modifierMHArgNum", modifierMHArgNum);404return data;405}406407@Override408protected MethodHandle getMH(Map<String, Object> data, TestMethods.Kind kind) {409MethodType mtTarget = (MethodType) data.get("mtTarget");410int modifierMHArgNum = (int) data.get("modifierMHArgNum");411return MethodHandles.spreadInvoker(mtTarget, modifierMHArgNum);412}413},414ARRAY_ELEMENT_GETTER("arrayElementGetter") {415@Override416public Map<String, Object> getTestCaseData() {417Map<String, Object> data = new HashMap<>();418int desiredArity = Helper.RNG.nextInt(super.maxArity);419MethodType mtTarget = TestMethods.randomMethodTypeGenerator(desiredArity);420data.put("mtTarget", mtTarget);421return data;422}423424@Override425protected MethodHandle getMH(Map<String, Object> data, TestMethods.Kind kind) {426MethodType mtTarget = (MethodType) data.get("mtTarget");427Class<?> rType = mtTarget.returnType();428if (rType == void.class) {429rType = Object.class;430}431return MethodHandles.arrayElementGetter(Array.newInstance(rType, 2).getClass());432}433},434ARRAY_ELEMENT_SETTER("arrayElementSetter") {435@Override436public Map<String, Object> getTestCaseData() {437Map<String, Object> data = new HashMap<>();438int desiredArity = Helper.RNG.nextInt(super.maxArity);439MethodType mtTarget = TestMethods.randomMethodTypeGenerator(desiredArity);440data.put("mtTarget", mtTarget);441return data;442}443444@Override445protected MethodHandle getMH(Map<String, Object> data, TestMethods.Kind kind) {446MethodType mtTarget = (MethodType) data.get("mtTarget");447Class<?> rType = mtTarget.returnType();448if (rType == void.class) {449rType = Object.class;450}451return MethodHandles.arrayElementSetter(Array.newInstance(rType, 2).getClass());452}453},454CONSTANT("constant") {455@Override456public Map<String, Object> getTestCaseData() {457Map<String, Object> data = new HashMap<>();458int desiredArity = Helper.RNG.nextInt(super.maxArity);459MethodType mtTarget = TestMethods.randomMethodTypeGenerator(desiredArity);460data.put("mtTarget", mtTarget);461return data;462}463464@Override465protected MethodHandle getMH(Map<String, Object> data, TestMethods.Kind kind) {466MethodType mtTarget = (MethodType) data.get("mtTarget");467Class<?> rType = mtTarget.returnType();468if (rType == void.class) {469rType = Object.class;470}471if (rType.equals(boolean.class)) {472// There should be the same return values because for default values there are special "zero" forms473return MethodHandles.constant(rType, true);474} else {475return MethodHandles.constant(rType, kind.getValue(rType));476}477}478},479IDENTITY("identity") {480@Override481public Map<String, Object> getTestCaseData() {482Map<String, Object> data = new HashMap<>();483int desiredArity = Helper.RNG.nextInt(super.maxArity);484MethodType mtTarget = TestMethods.randomMethodTypeGenerator(desiredArity);485data.put("mtTarget", mtTarget);486return data;487}488489@Override490protected MethodHandle getMH(Map<String, Object> data, TestMethods.Kind kind) {491MethodType mtTarget = (MethodType) data.get("mtTarget");492Class<?> rType = mtTarget.returnType();493if (rType == void.class) {494rType = Object.class;495}496return MethodHandles.identity(rType);497}498};499500/**501* Test method's name.502*/503public final String name;504505private final int maxArity;506507private TestMethods(String name, int maxArity) {508this.name = name;509this.maxArity = maxArity;510}511512private TestMethods(String name) {513this(name, Helper.MAX_ARITY);514}515516protected MethodHandle getMH(Map<String, Object> data, TestMethods.Kind kind) throws NoSuchMethodException, IllegalAccessException {517throw new UnsupportedOperationException("TESTBUG: getMH method is not implemented for test method " + this);518}519520/**521* Creates an adapter method handle depending on a test method from522* MethodHandles class. Adapter is what is returned by the test method. This523* method is able to create two kinds of adapters, their type will be the524* same, but return values are different.525*526* @param data a Map containing data to create a method handle, can be527* obtained by {@link #getTestCaseData} method528* @param kind defines whether adapter ONE or adapter TWO will be529* initialized. Should be equal to TestMethods.Kind.ONE or530* TestMethods.Kind.TWO531* @return Method handle adapter that behaves according to532* TestMethods.Kind.ONE or TestMethods.Kind.TWO533* @throws java.lang.NoSuchMethodException534* @throws java.lang.IllegalAccessException535*/536public MethodHandle getTestCaseMH(Map<String, Object> data, TestMethods.Kind kind)537throws NoSuchMethodException, IllegalAccessException {538if (data == null) {539throw new Error(String.format("TESTBUG: Data for test method %s is not prepared",540this.name));541}542if (!kind.equals(TestMethods.Kind.ONE) && !kind.equals(TestMethods.Kind.TWO)) {543throw new IllegalArgumentException("TESTBUG: Wrong \"kind\" (" + kind544+ ") arg to getTestCaseMH function."545+ " Should be Kind.ONE or Kind.TWO");546}547return getMH(data, kind);548}549550/**551* Returns a data Map needed for {@link #getTestCaseMH} method.552*553* @return data Map needed for {@link #getTestCaseMH} method554*/555public Map<String, Object> getTestCaseData() {556throw new UnsupportedOperationException(557"TESTBUG: getTestCaseData method is not implemented for test method " + this);558}559560/**561* Enumeration used in methodHandleGenerator to define whether a MH returned562* by this method returns "2" in different type representations, "4", or563* throw an Exception.564*/565public static enum Kind {566567ONE(2),568TWO(4),569EXCEPT(0);570571private final int value;572573private Object getValue(Class<?> cl) {574return Helper.castToWrapper(value, cl);575}576577private MethodHandle getBasicMH(Class<?> rType) throws NoSuchMethodException, IllegalAccessException {578MethodHandle result = null;579switch (this) {580case ONE:581case TWO:582if (rType.equals(void.class)) {583result = MethodHandles.lookup().findVirtual(Kind.class, "returnVoid", MethodType.methodType(void.class));584result = MethodHandles.insertArguments(result, 0, this);585} else {586result = MethodHandles.constant(rType, getValue(rType));587}588break;589case EXCEPT:590result = MethodHandles.throwException(rType, Exception.class);591result = MethodHandles.insertArguments(result, 0, new Exception());592break;593}594return result;595}596597private void returnVoid() {598}599600private Kind(int value) {601this.value = value;602}603}604605/**606* Routine used to obtain a randomly generated method type.607*608* @param arity Arity of returned method type.609* @return MethodType generated randomly.610*/611private static MethodType randomMethodTypeGenerator(int arity) {612return Helper.randomMethodTypeGenerator(arity);613}614615/**616* Routine used to obtain a method handles of a given type an kind (return617* value).618*619* @param returnType Type of MH return value.620* @param argTypes Types of MH args.621* @param kind Defines whether the obtained MH returns "1" or "2".622* @return Method handle of the given type.623* @throws NoSuchMethodException624* @throws IllegalAccessException625*/626private static MethodHandle methodHandleGenerator(Class<?> returnType,627List<Class<?>> argTypes, TestMethods.Kind kind)628throws NoSuchMethodException, IllegalAccessException {629MethodHandle result;630result = kind.getBasicMH(returnType);631return Helper.addTrailingArgs(result, argTypes.size(), argTypes);632}633634/**635* Routine that generates filter method handles to test636* MethodHandles.filterArguments method.637*638* @param inputType Filter's argument type.639* @param returnType Filter's return type.640* @param kind Filter's return value definer.641* @return A filter method handle, that takes one argument.642* @throws NoSuchMethodException643* @throws IllegalAccessException644*/645private static MethodHandle filterGenerator(Class<?> inputType, Class<?> returnType,646TestMethods.Kind kind) throws NoSuchMethodException, IllegalAccessException {647MethodHandle tmpMH = kind.getBasicMH(returnType);648if (inputType.equals(void.class)) {649return tmpMH;650}651ArrayList<Class<?>> inputTypeList = new ArrayList<>(1);652inputTypeList.add(inputType);653return Helper.addTrailingArgs(tmpMH, 1, inputTypeList);654}655656private static int argSlotsCount(MethodType mt) {657int result = 0;658for (Class cl : mt.parameterArray()) {659if (cl.equals(long.class) || cl.equals(double.class)) {660result += 2;661} else {662result++;663}664}665return result;666}667668private static List<Class<?>> reduceArgListToSlotsCount(List<Class<?>> list,669int desiredSlotCount) {670List<Class<?>> result = new ArrayList<>(desiredSlotCount);671int count = 0;672for (Class<?> cl : list) {673if (count >= desiredSlotCount) {674break;675}676if (cl.equals(long.class) || cl.equals(double.class)) {677count += 2;678} else {679count++;680}681result.add(cl);682}683return result;684}685}686687688