1 /*
   2  * Copyright (c) 2001, 2015, 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.
   8  *
   9  * This code is distributed in the hope that it will be useful, but WITHOUT
  10  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
  11  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
  12  * version 2 for more details (a copy is included in the LICENSE file that
  13  * accompanied this code).
  14  *
  15  * You should have received a copy of the GNU General Public License version
  16  * 2 along with this work; if not, write to the Free Software Foundation,
  17  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
  18  *
  19  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
  20  * or visit www.oracle.com if you need additional information or have any
  21  * questions.
  22  */
  23 
  24 /**
  25  * @test
  26  * @bug 4451941 4527072
  27  * @summary Test argument types for invoke
  28  * @author Robert Field
  29  *
  30  * @library ..
  31  *
  32  * @run build  TestScaffold VMConnection TargetListener TargetAdapter
  33  * @run compile -g InvokeTest.java
  34  * @run driver InvokeTest
  35  */
  36 import com.sun.jdi.*;
  37 import com.sun.jdi.event.*;
  38 import com.sun.jdi.request.*;
  39 
  40 import java.util.*;
  41 
  42     /********** target program **********/
  43 
  44 class InvokeTarg {
  45     static InvokeTarg myself = null;
  46 
  47     boolean[] aBooleanArray = new boolean[] {true, true};
  48     byte[] aByteArray = new byte[] {4, 2};
  49     char[] aCharArray = new char[] {'k', 'p'};
  50     short[] aShortArray = new short[] {55,12, 12};
  51     int[] aIntArray = new int[] {6, 3, 1};
  52     long[] aLongArray = new long[] {3423423};
  53     float[] aFloatArray = new float[] {(float)2.1};
  54     double[] aDoubleArray = new double[] {3.141595358979};
  55 
  56     boolean[][] aBoolean2DArray = new boolean[][]
  57                                    {{true, false}, {false, true}};
  58     byte[][] aByte2DArray = new byte[][] {{22,66}, {8,9}};
  59     char[][] aChar2DArray = new char[][] {{22,66}, {8,9}};
  60     short[][] aShort2DArray = new short[][] {{22,66}, {8,9}};
  61     int[][] aInt2DArray = new int[][] {{22,66}, {8,9}};
  62     long[][] aLong2DArray = new long[][] {{22,66}, {8,9}};
  63     float[][] aFloat2DArray = new float[][] {{22,66}, {8,9}};
  64     double[][] aDouble2DArray = new double[][] {{22,66}, {8,9}};
  65 
  66     String[] aStringArray = new String[] {"testing"};
  67     String[][] aString2DArray = new String[][]
  68                                      {{"hi", "there"}, {"oh"}};
  69     Date aDate = new Date();
  70     Date[] aDateArray = new Date[] {};
  71     Date[][] aDate2DArray = new Date[][] {{}};
  72 
  73     String aString = "jjxx";
  74     long longCheck = 0;
  75     boolean booleanCheck = false;
  76     boolean voidCheck = false;
  77     Object objectCheck = null;
  78 
  79     public static void main(String[] args){
  80         System.out.println("Howdy!");
  81         (new InvokeTarg()).sayHi();
  82     }
  83 
  84     void sayHi() {
  85     }
  86 
  87     void checkIn() {
  88     }
  89 
  90     boolean invokeVoid() {
  91         voidCheck = true;
  92         checkIn();
  93         return true;
  94     }
  95 
  96     boolean invokeBoolean(boolean val) {
  97         booleanCheck = val;
  98         checkIn();
  99         return val;
 100     }
 101 
 102     byte invokeByte(byte val) {
 103         longCheck = val;
 104         checkIn();
 105         return val;
 106     }
 107 
 108     char invokeChar(char val) {
 109         longCheck = val;
 110         checkIn();
 111         return val;
 112     }
 113 
 114     short invokeShort(short val) {
 115         longCheck = val;
 116         checkIn();
 117         return val;
 118     }
 119 
 120     int invokeInt(int val) {
 121         longCheck = val;
 122         checkIn();
 123         return val;
 124     }
 125 
 126     long invokeLong(long val) {
 127         longCheck = val;
 128         checkIn();
 129         return val;
 130     }
 131 
 132     float invokeFloat(float val) {
 133         longCheck = (long)val;
 134         checkIn();
 135         return val;
 136     }
 137 
 138     double invokeDouble(double val) {
 139         longCheck = (long)val;
 140         checkIn();
 141         return val;
 142     }
 143 
 144     boolean[] invokeBooleanArray(boolean[] val) {
 145         objectCheck = val;
 146         checkIn();
 147         return val;
 148     }
 149 
 150     byte[] invokeByteArray(byte[] val) {
 151         objectCheck = val;
 152         checkIn();
 153         return val;
 154     }
 155 
 156     char[] invokeCharArray(char[] val) {
 157         objectCheck = val;
 158         checkIn();
 159         return val;
 160     }
 161 
 162     short[] invokeShortArray(short[] val) {
 163         objectCheck = val;
 164         checkIn();
 165         return val;
 166     }
 167 
 168     int[] invokeIntArray(int[] val) {
 169         objectCheck = val;
 170         checkIn();
 171         return val;
 172     }
 173 
 174     long[] invokeLongArray(long[] val) {
 175         objectCheck = val;
 176         checkIn();
 177         return val;
 178     }
 179 
 180     float[] invokeFloatArray(float[] val) {
 181         objectCheck = val;
 182         checkIn();
 183         return val;
 184     }
 185 
 186     double[] invokeDoubleArray(double[] val) {
 187         objectCheck = val;
 188         checkIn();
 189         return val;
 190     }
 191 
 192     boolean[][] invokeBoolean2DArray(boolean[][] val) {
 193         objectCheck = val;
 194         checkIn();
 195         return val;
 196     }
 197 
 198     byte[][] invokeByte2DArray(byte[][] val) {
 199         objectCheck = val;
 200         checkIn();
 201         return val;
 202     }
 203 
 204     char[][] invokeChar2DArray(char[][] val) {
 205         objectCheck = val;
 206         checkIn();
 207         return val;
 208     }
 209 
 210     short[][] invokeShort2DArray(short[][] val) {
 211         objectCheck = val;
 212         checkIn();
 213         return val;
 214     }
 215 
 216     int[][] invokeInt2DArray(int[][] val) {
 217         objectCheck = val;
 218         checkIn();
 219         return val;
 220     }
 221 
 222     long[][] invokeLong2DArray(long[][] val) {
 223         objectCheck = val;
 224         checkIn();
 225         return val;
 226     }
 227 
 228     float[][] invokeFloat2DArray(float[][] val) {
 229         objectCheck = val;
 230         checkIn();
 231         return val;
 232     }
 233 
 234     double[][] invokeDouble2DArray(double[][] val) {
 235         objectCheck = val;
 236         checkIn();
 237         return val;
 238     }
 239 
 240     String invokeString(String val) {
 241         objectCheck = val;
 242         checkIn();
 243         return val;
 244     }
 245 
 246     String[] invokeStringArray(String[] val) {
 247         objectCheck = val;
 248         checkIn();
 249         return val;
 250     }
 251 
 252     String[][] invokeString2DArray(String[][] val) {
 253         objectCheck = val;
 254         checkIn();
 255         return val;
 256     }
 257 
 258     Date invokeDate(Date val) {
 259         objectCheck = val;
 260         checkIn();
 261         return val;
 262     }
 263 
 264     Date[] invokeDateArray(Date[] val) {
 265         objectCheck = val;
 266         checkIn();
 267         return val;
 268     }
 269 
 270     Date[][] invokeDate2DArray(Date[][] val) {
 271         objectCheck = val;
 272         checkIn();
 273         return val;
 274     }
 275 
 276     String invokeCombo(int[][] arr, String val) {
 277         objectCheck = val;
 278         checkIn();
 279         return val;
 280     }
 281 
 282     int[][] invokeCombo2(int[][] val, String str) {
 283         objectCheck = val;
 284         checkIn();
 285         return val;
 286     }
 287 }
 288 
 289     /********** test program **********/
 290 
 291 public class InvokeTest extends TestScaffold {
 292     ReferenceType targetClass;
 293     ThreadReference mainThread;
 294     ObjectReference thisObject;
 295     Field longCheckField;
 296     Field booleanCheckField;
 297     Field voidCheckField;
 298     Field objectCheckField;
 299     Value longValue;
 300     Value booleanValue;
 301     Value objectValue;
 302     Value voidValue;
 303 
 304     InvokeTest (String args[]) {
 305         super(args);
 306     }
 307 
 308     public static void main(String[] args)      throws Exception {
 309         new InvokeTest(args).startTests();
 310     }
 311 
 312     /********** event handlers **********/
 313 
 314     // not use now
 315     public void breakpointReached(BreakpointEvent event) {
 316         println("Got BreakpointEvent");
 317         longValue = thisObject.getValue(longCheckField);
 318         booleanValue = thisObject.getValue(booleanCheckField);
 319         objectValue = thisObject.getValue(objectCheckField);
 320         voidValue = thisObject.getValue(voidCheckField);
 321     }
 322 
 323     /********** test assist **********/
 324 
 325     void invoke(Method method, List args, Value value) {
 326         Value returnValue = null;
 327 
 328         try {
 329             returnValue = thisObject.invokeMethod(mainThread,
 330                                                     method, args, 0);
 331         } catch ( Exception ee) {
 332             println("Got Exception: " + ee);
 333             ee.printStackTrace();
 334         }
 335         println("        return val = " + returnValue);
 336         // It has to be the same value as what we passed in!
 337         if (returnValue.equals(value)) {
 338             println("         " + method.name() + " return value matches: "
 339                     + value);
 340         } else {
 341             if (value != null) {
 342                 failure("FAIL: " + method.name() + " returned: " + returnValue +
 343                         " expected: " + value );
 344             } else {
 345                 println("         " + method.name() + " return value : " + returnValue);
 346             }
 347 
 348         }
 349         Value checkValue = (value instanceof PrimitiveValue)?
 350                               ((value instanceof BooleanValue)?
 351                                         booleanValue : longValue) :
 352                               objectValue;
 353     }
 354 
 355 
 356     void invoke(String methodName, String methodSig,
 357                 List args, Value value)
 358         throws Exception {
 359         Method method = findMethod(targetClass, methodName, methodSig);
 360         if ( method == null) {
 361             failure("FAILED: Can't find method: " + methodName  + " for class = " + targetClass);
 362             return;
 363         }
 364         invoke(method, args, value);
 365     }
 366 
 367     void invoke(String methodName, String methodSig, Value value)
 368                                            throws Exception {
 369         List args = new ArrayList(1);
 370         args.add(value);
 371         invoke(methodName, methodSig, args, value);
 372     }
 373 
 374 
 375     void invoke(String methodName, String methodSig, String fieldName)
 376                                            throws Exception {
 377         invoke(methodName, methodSig, fieldValue(fieldName));
 378     }
 379 
 380     private Method toStringMethod;
 381     Method gettoStringMethod() {
 382         if ( toStringMethod != null) {
 383             return toStringMethod;
 384         }
 385 
 386         // We have to find it.  First find java.lang.Object
 387         List myClasses = vm().allClasses();
 388         Iterator iter = myClasses.iterator();
 389         ReferenceType objectMirror = null;
 390         while (iter.hasNext()) {
 391             ReferenceType xx = (ReferenceType)iter.next();
 392             if (xx.name().equals("java.lang.Object")) {
 393                 objectMirror = xx;
 394                 break;
 395             }
 396         }
 397 
 398         if (objectMirror == null) {
 399             return null;
 400         }
 401 
 402         // Then find toSting
 403         List meths = objectMirror.methods();
 404         iter = meths.iterator();
 405         while (iter.hasNext()) {
 406             toStringMethod = (Method)iter.next();
 407             if (toStringMethod.name().equals("toString")) {
 408                 return toStringMethod;
 409            }
 410        }
 411        toStringMethod = null;
 412        return null;
 413     }
 414 
 415     // This calls toString on a field
 416     protected void callToString(String fieldName) throws Exception {
 417         // Sorry for this kludgy use of global vars.
 418         ObjectReference saveObject = thisObject;
 419         Method toStringMethod = gettoStringMethod();
 420 
 421         Field theField = targetClass.fieldByName(fieldName);
 422         thisObject = (ObjectReference)thisObject.getValue( theField);
 423         invoke(toStringMethod, new ArrayList(0), null);
 424         thisObject = saveObject;
 425     }
 426 
 427     Value fieldValue(String fieldName) {
 428         Field field = targetClass.fieldByName(fieldName);
 429         return thisObject.getValue(field);
 430     }
 431 
 432 
 433     /********** test core **********/
 434 
 435     protected void runTests() throws Exception {
 436         /*
 437          * Get to the top of sayHi()
 438          * to determine targetClass and mainThread
 439          */
 440         BreakpointEvent bpe = startTo("InvokeTarg", "sayHi", "()V");
 441         targetClass = bpe.location().declaringType();
 442 
 443         mainThread = bpe.thread();
 444 
 445         StackFrame frame = mainThread.frame(0);
 446         thisObject = frame.thisObject();
 447         longCheckField = targetClass.fieldByName("longCheck");
 448         booleanCheckField = targetClass.fieldByName("booleanCheck");
 449         objectCheckField = targetClass.fieldByName("objectCheck");
 450         voidCheckField = targetClass.fieldByName("voidCheck");
 451         callToString("aBooleanArray");
 452 
 453         invoke("invokeVoid",    "()Z",  new ArrayList(0), vm().mirrorOf(true));
 454 
 455         invoke("invokeBoolean", "(Z)Z", vm().mirrorOf(true));
 456         invoke("invokeByte",    "(B)B", vm().mirrorOf((byte)14));
 457         invoke("invokeChar",    "(C)C", vm().mirrorOf('h'));
 458         invoke("invokeShort",   "(S)S", vm().mirrorOf((short)54));
 459         invoke("invokeInt",     "(I)I", vm().mirrorOf((int)414));
 460         invoke("invokeLong",    "(J)J", vm().mirrorOf((long)140000));
 461         invoke("invokeFloat",   "(F)F", vm().mirrorOf((float)315));
 462         invoke("invokeDouble",  "(D)D", vm().mirrorOf((double)181818));
 463 
 464         invoke("invokeBooleanArray",    "([Z)[Z", "aBooleanArray");
 465         invoke("invokeByteArray",    "([B)[B", "aByteArray");
 466         invoke("invokeCharArray",    "([C)[C", "aCharArray");
 467         invoke("invokeShortArray",   "([S)[S", "aShortArray");
 468         invoke("invokeIntArray",     "([I)[I", "aIntArray");
 469         invoke("invokeLongArray",    "([J)[J", "aLongArray");
 470         invoke("invokeFloatArray",   "([F)[F", "aFloatArray");
 471         invoke("invokeDoubleArray",  "([D)[D", "aDoubleArray");
 472 
 473         invoke("invokeBoolean2DArray",    "([[Z)[[Z", "aBoolean2DArray");
 474         invoke("invokeByte2DArray",    "([[B)[[B", "aByte2DArray");
 475         invoke("invokeChar2DArray",    "([[C)[[C", "aChar2DArray");
 476         invoke("invokeShort2DArray",   "([[S)[[S", "aShort2DArray");
 477         invoke("invokeInt2DArray",     "([[I)[[I", "aInt2DArray");
 478         invoke("invokeLong2DArray",    "([[J)[[J", "aLong2DArray");
 479         invoke("invokeFloat2DArray",   "([[F)[[F", "aFloat2DArray");
 480         invoke("invokeDouble2DArray",  "([[D)[[D", "aDouble2DArray");
 481 
 482         invoke("invokeString",    "(Ljava/lang/String;)Ljava/lang/String;",
 483                                   vm().mirrorOf("Howdy"));
 484         invoke("invokeStringArray",    "([Ljava/lang/String;)[Ljava/lang/String;",
 485                                   "aStringArray");
 486         invoke("invokeString2DArray",    "([[Ljava/lang/String;)[[Ljava/lang/String;",
 487                                   "aString2DArray");
 488 
 489         invoke("invokeDate",    "(Ljava/util/Date;)Ljava/util/Date;",
 490                                   "aDate");
 491         invoke("invokeDateArray",  "([Ljava/util/Date;)[Ljava/util/Date;",
 492                                   "aDateArray");
 493         invoke("invokeDate2DArray", "([[Ljava/util/Date;)[[Ljava/util/Date;",
 494                                   "aDate2DArray");
 495 
 496         Value i2 = fieldValue("aInt2DArray");
 497         Value str = vm().mirrorOf("Later");
 498         List args = new ArrayList(2);
 499         args.add(i2);
 500         args.add(str);
 501         invoke("invokeCombo",
 502                "([[ILjava/lang/String;)Ljava/lang/String;",
 503                args, str);
 504         invoke("invokeCombo2",
 505                "([[ILjava/lang/String;)[[I",
 506                args, i2);
 507         /*
 508          * resume the target listening for events
 509          */
 510         listenUntilVMDisconnect();
 511 
 512         /*
 513          * deal with results of test
 514          * if anything has called failure("foo") testFailed will be true
 515          */
 516         if (!testFailed) {
 517             println("InvokeTest: passed");
 518         } else {
 519             throw new Exception("InvokeTest: failed");
 520         }
 521     }
 522 }