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