1/*
2 * Copyright (c) 2007, 2017, 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//    THIS TEST IS LINE NUMBER SENSITIVE
25
26/**
27 * @test
28 * @bug 4300412
29 * @summary Test GetLocal* and SetLocal* functions
30 * @author Serguei Spitsyn
31 *
32 * @run build TestScaffold VMConnection TargetListener TargetAdapter
33 * @run compile -g GetSetLocalTest.java
34 * @run driver GetSetLocalTest
35 */
36import com.sun.jdi.*;
37import com.sun.jdi.event.*;
38import com.sun.jdi.request.*;
39
40import java.util.*;
41
42    /********** target program **********/
43
44class GetSetLocalTarg {
45    public static void main(String[] args){
46        int intVar = 10;
47        System.out.println("GetSetLocalTarg: Started");
48        intVar = staticMeth(intVar);
49        System.out.println("GetSetLocalTarg: Finished");
50    }
51
52    /*
53     * The line numbers of this method *MUST NOT* be changed
54     * because the testing algorithm counts on this layout!
55     * It's in calls to resumeTo("GetSetLocalTarg", line).
56     */
57    public static int staticMeth(int intArg) {
58        System.out.println("staticMeth: Started");
59        int result;
60        {
61             { boolean bool_1 = false;
62               intArg++; // START_LINE
63             }
64
65             boolean bool_2 = true;
66             intArg++;
67        }
68        {
69             { byte byte_1 = 1;
70               intArg++;
71             }
72
73             byte byte_2 = 2;
74             intArg++;
75        }
76        {
77             { char   char_1 = '1';
78               intArg++;
79             }
80
81             char   char_2 = '2';
82             intArg++;
83        }
84        {
85             { short  short_1 = 1;
86               intArg++;
87             }
88
89             short  short_2 = 2;
90             intArg++;
91        }
92        {
93             { int    int_1 = 1;
94               intArg++;
95             }
96
97             int int_2 = 2;
98             intArg++;
99        }
100        {
101             { long long_1 = 1;
102               intArg++;
103             }
104
105             long long_2 = 2;
106             intArg++;
107        }
108        {
109             { float  float_1 = 1;
110               intArg++;
111             }
112
113             float float_2 = 2;
114             intArg++;
115        }
116        {
117             { double double_1 = 1;
118               intArg++;
119             }
120
121             double double_2 = 2;
122             intArg++;
123        }
124        {
125             { String string_1 = "1";
126               intArg++;
127             }
128
129             String string_2 = "2";
130             intArg++;
131        }
132        {
133             { Object obj_1 = new Object();
134               intArg++;
135             }
136
137             Object obj_2 = new Object();
138             intArg++;  // STOP_LINE. Last stop is at this point.
139                        //     Only obj_2 and intArg are valid
140                        // Note: even result is not valid here!
141        }
142        result = 10;    // <- This is first init of result var
143        System.out.println("staticMeth: Finished");
144        return result;
145    }
146}
147
148
149    /********** test program **********/
150
151public class GetSetLocalTest extends TestScaffold {
152    static final int START_LINE = 62;
153    static final int STOP_LINE = 138;
154    ReferenceType targetClass;
155    ThreadReference mainThread;
156
157    GetSetLocalTest (String args[]) {
158        super(args);
159    }
160
161    public static void main(String[] args) throws Exception {
162        new GetSetLocalTest(args).startTests();
163    }
164
165    /********** test assist **********/
166
167    Method getMethod(String className, String methodName) {
168        List refs = vm().classesByName(className);
169        if (refs.size() != 1) {
170            failure(" Failure: " + refs.size() +
171                    " ReferenceTypes named: " + className);
172            return null;
173        }
174        ReferenceType refType = (ReferenceType)refs.get(0);
175        List meths = refType.methodsByName(methodName);
176        if (meths.size() != 1) {
177            failure(" Failure: " + meths.size() +
178                    " methods named: " + methodName);
179            return null;
180        }
181        return (Method)meths.get(0);
182    }
183
184    List printAllVariables(String className, String methodName) throws Exception {
185        println("printAllVariables for method: " + className + "." + methodName);
186        Method method = getMethod(className, methodName);
187        List localVars;
188        try {
189            localVars = method.variables();
190            println(" Success: got a list of all method variables: " + methodName);
191        }
192        catch (com.sun.jdi.AbsentInformationException ex) {
193            failure(" Failure: AbsentInformationException has been thrown");
194            return null;
195        }
196
197        int index = 0;
198        for (Iterator it = localVars.iterator(); it.hasNext();) {
199            LocalVariable lv = (LocalVariable) it.next();
200            printOneVariable(lv, index++);
201        }
202        println("");
203        return localVars;
204    }
205
206    void checkGetSetAllVariables(List localVars, StackFrame frame) throws Exception {
207        println("\n checkGetSetAllVariables for method at particular frame location: ");
208        int index = 0;
209        for (Iterator it = localVars.iterator(); it.hasNext();) {
210            LocalVariable lv = (LocalVariable) it.next();
211            String lv_name = lv.name();
212            print(" Variable " + lv_name);
213            try {
214                Value val = frame.getValue(lv);
215                frame.setValue(lv, val);
216                println(" has been get/set");
217                if (lv_name.compareTo("intArg") != 0 &&
218                    lv_name.compareTo("obj_2")  != 0) {
219                    failure(" Failure: AbsentInformationException is expected");
220                }
221            } catch (java.lang.IllegalArgumentException ex) {
222                println(" is not valid");
223                if (lv_name.compareTo("intArg") == 0 &&
224                    lv_name.compareTo("obj_2")  == 0) {
225                    failure(" Failure: AbsentInformationException was not expected");
226                }
227            }
228        }
229        println("");
230    }
231
232    void printOneVariable(LocalVariable lv, int index) throws Exception {
233        String tyname = lv.typeName();
234        println("");
235        println(" Var  name: " + lv.name());
236        println(" Var  type: " + tyname);
237        println(" Var index: " + index);
238        println(" Signature: " + lv.type().signature());
239        // Sorry, there is no way to get (and print)
240        // a local variable slot numbers using JDI!
241    }
242
243    void printFrameVariables(StackFrame frame) throws Exception {
244        int index = 0;
245        List localVars = frame.visibleVariables();
246        println("\n Visible variables at this point are: ");
247
248        for (Iterator it = localVars.iterator(); it.hasNext();) {
249            LocalVariable lv = (LocalVariable) it.next();
250            printOneVariable(lv, index++);
251            println(" Var value: " + frame.getValue(lv));
252        }
253    }
254
255    BooleanValue incrValue(BooleanValue val) {
256        boolean value = val.value();
257        return vm().mirrorOf(!value);
258    }
259
260    ByteValue incrValue(ByteValue val) {
261        byte value = val.value();
262        return vm().mirrorOf(++value);
263    }
264
265    CharValue incrValue(CharValue val) {
266        char value = val.value();
267        return vm().mirrorOf(++value);
268    }
269
270    ShortValue incrValue(ShortValue val) {
271        short value = val.value();
272        return vm().mirrorOf(++value);
273    }
274
275    IntegerValue incrValue(IntegerValue val) {
276        int value = val.value();
277        return vm().mirrorOf(++value);
278    }
279
280    LongValue incrValue(LongValue val) {
281        long value = val.value();
282        return vm().mirrorOf(++value);
283    }
284
285    FloatValue incrValue(FloatValue val) {
286        float value = val.value();
287        return  vm().mirrorOf(++value);
288    }
289
290    DoubleValue incrValue(DoubleValue val) {
291        double value = val.value();
292        return vm().mirrorOf(++value);
293    }
294
295    StringReference incrValue(StringReference val) {
296        String newstr = new String("Set String ").concat(val.value());
297        return vm().mirrorOf(newstr);
298    }
299
300    void checkSetBooleanTypes(StackFrame frame, LocalVariable lv) throws Exception {
301        BooleanValue get = (BooleanValue) frame.getValue(lv);
302        BooleanValue set = incrValue(get);
303        frame.setValue(lv, set);
304
305        // To get the new value which has been set
306        get = (BooleanValue) frame.getValue(lv);
307        println(" Var  Set: " + set);
308        println(" Var  Get: " + get);
309        println("");
310        boolean v1 = get.value();
311        boolean v2 = set.value();
312
313        // Check if set was done properly
314        if (v1 == v2) {
315            println(" Success: Value was set correctly!");
316        } else {
317            failure(" Failure: Value was NOT set correctly!");
318        }
319        println("");
320    }
321
322    void checkSetByteTypes(StackFrame frame, LocalVariable lv) throws Exception {
323        ByteValue get = (ByteValue) frame.getValue(lv);
324        ByteValue set = incrValue(get);
325        frame.setValue(lv, set);
326
327        // To get the new value which has been set
328        get = (ByteValue) frame.getValue(lv);
329        println(" Var  Set: " + set);
330        println(" Var  Get: " + get);
331        println("");
332        byte v1 = get.value();
333        byte v2 = set.value();
334
335        // Check if set was done properly
336        if (v1 == v2) {
337            println(" Success: Value was set correctly!");
338        } else {
339            failure(" Failure: Value was NOT set correctly!");
340        }
341        println("");
342    }
343
344    void checkSetCharTypes(StackFrame frame, LocalVariable lv) throws Exception {
345        CharValue get = (CharValue) frame.getValue(lv);
346        CharValue set = incrValue(get);
347        frame.setValue(lv, set);
348
349        // To get the new value which has been set
350        get = (CharValue) frame.getValue(lv);
351        println(" Var  Set: " + set);
352        println(" Var  Get: " + get);
353        println("");
354        char v1 = get.value();
355        char v2 = set.value();
356
357        // Check if set was done properly
358        if (v1 == v2) {
359            println(" Success: Value was set correctly!");
360        } else {
361            failure(" Failure: Value was NOT set correctly!");
362        }
363        println("");
364    }
365
366    void checkSetShortTypes(StackFrame frame, LocalVariable lv) throws Exception {
367        ShortValue get = (ShortValue) frame.getValue(lv);
368        ShortValue set = incrValue(get);
369        frame.setValue(lv, set);
370
371        // To get the new value which has been set
372        get = (ShortValue) frame.getValue(lv);
373        println(" Var  Set: " + set);
374        println(" Var  Get: " + get);
375        println("");
376        short v1 = get.value();
377        short v2 = set.value();
378
379        // Check if set was done properly
380        if (v1 == v2) {
381            println(" Success: Value was set correctly!");
382        } else {
383            failure(" Failure: Value was NOT set correctly!");
384        }
385        println("");
386    }
387
388    void checkSetIntegerTypes(StackFrame frame, LocalVariable lv) throws Exception {
389        IntegerValue get = (IntegerValue) frame.getValue(lv);
390        IntegerValue set = incrValue(get);
391        frame.setValue(lv, set);
392
393        // To get the new value which has been set
394        get = (IntegerValue) frame.getValue(lv);
395        println(" Var  Set: " + set);
396        println(" Var  Get: " + get);
397        println("");
398        int v1 = get.value();
399        int v2 = set.value();
400
401        // Check if set was done properly
402        if (v1 == v2) {
403            println(" Success: Value was set correctly!");
404        } else {
405            failure(" Failure: Value was NOT set correctly!");
406        }
407        println("");
408    }
409
410    void checkSetLongTypes(StackFrame frame, LocalVariable lv) throws Exception {
411        LongValue get = (LongValue) frame.getValue(lv);
412        LongValue set = incrValue(get);
413        frame.setValue(lv, set);
414
415        // To get the new value which has been set
416        get = (LongValue) frame.getValue(lv);
417        println(" Var  Set: " + set);
418        println(" Var  Get: " + get);
419        println("");
420        long v1 = get.value();
421        long v2 = set.value();
422
423        // Check if set was done properly
424        if (v1 == v2) {
425            println(" Success: Value was set correctly!");
426        } else {
427            failure(" Failure: Value was NOT set correctly!");
428        }
429        println("");
430    }
431
432    void checkSetFloatTypes(StackFrame frame, LocalVariable lv) throws Exception {
433        FloatValue get = (FloatValue) frame.getValue(lv);
434        FloatValue set = incrValue(get);
435        frame.setValue(lv, set);
436
437        // To get the new value which has been set
438        get = (FloatValue) frame.getValue(lv);
439        println(" Var  Set: " + set);
440        println(" Var  Get: " + get);
441        println("");
442        float v1 = get.value();
443        float v2 = set.value();
444
445        // Check if set was done properly
446        if (v1 == v2) {
447            println(" Success: Value was set correctly!");
448        } else {
449            failure(" Failure: Value was NOT set correctly!");
450        }
451        println("");
452    }
453
454    void checkSetDoubleTypes(StackFrame frame, LocalVariable lv) throws Exception {
455        DoubleValue get = (DoubleValue) frame.getValue(lv);
456        DoubleValue set = incrValue(get);
457        frame.setValue(lv, set);
458
459        // To get the new value which has been set
460        get = (DoubleValue) frame.getValue(lv);
461        println(" Var  Set: " + set);
462        println(" Var  Get: " + get);
463        println("");
464        double v1 = get.value();
465        double v2 = set.value();
466
467        // Check if set was done properly
468        if (v1 == v2) {
469            println(" Success: Value was set correctly!");
470        } else {
471            failure(" Failure: Value was NOT set correctly!");
472        }
473        println("");
474    }
475
476    void checkSetStringTypes(StackFrame frame, LocalVariable lv) throws Exception {
477        StringReference get = (StringReference) frame.getValue(lv);
478        StringReference set = incrValue((StringReference) frame.getValue(lv));
479        frame.setValue(lv, set);
480
481        // To get the new value which has been set
482        get = (StringReference) frame.getValue(lv);
483        println(" Var  Set: " + set);
484        println(" Var  Get: " + get);
485        println("");
486        String str1 = get.value();
487        String str2 = set.value();
488
489        // Check if set was done properly
490        if (str1.compareTo(str2) == 0) {
491            println(" Success: String was set correctly!");
492        } else {
493            failure(" Failure: String was NOT set correctly!");
494        }
495        println("");
496    }
497
498    void checkSetObjectTypes(StackFrame frame, LocalVariable lv) throws Exception {
499        ObjectReference get = (ObjectReference) frame.getValue(lv);
500        ObjectReference set = get; // FIXME: Don't know how to create a mirror of Object
501        frame.setValue(lv, set);
502
503        // To get the new value which has been set
504        get = (ObjectReference) frame.getValue(lv);
505        println(" Var  Set: " + set);
506        println(" Var  Get: " + get);
507        println("");
508
509        if (set.uniqueID() == get.uniqueID()) {
510            println(" Success: Object was set correctly!");
511        } else {
512            failure(" Failure: Object was NOT set correctly!");
513        }
514        println("");
515    }
516
517    void negativeIntegerCheck(StackFrame frame, LocalVariable lv) throws Exception {
518        try {
519            IntegerValue get = (IntegerValue) frame.getValue(lv);
520            println(" Get: No ClassCastException error!");
521        } catch(java.lang.ClassCastException ex) {
522            println(" Success: Get: ClassCastException error has cought as expected!");
523        }
524        try {
525            IntegerValue set = vm().mirrorOf((int) 0x3F);
526            frame.setValue(lv, set);
527            println(" Set: No InvalidTypeException with Integer error!");
528        } catch(com.sun.jdi.InvalidTypeException ex) {
529            println(" Success: Set: InvalidTypeException with Integer error has cought as expected!");
530        }
531    }
532
533    void negativeFloatCheck(StackFrame frame, LocalVariable lv) throws Exception {
534        try {
535            FloatValue get = (FloatValue) frame.getValue(lv);
536            println(" Get: No ClassCastException error!");
537        } catch(java.lang.ClassCastException ex) {
538            println(" Success: Get: ClassCastException with Float error has cought as expected!");
539        }
540        try {
541            FloatValue set = vm().mirrorOf(1.2345f);
542            frame.setValue(lv, set);
543            println(" Set: No InvalidTypeException with Float error!");
544        } catch(com.sun.jdi.InvalidTypeException ex) {
545            println(" Success: Set: InvalidTypeException error has cought as expected!");
546        }
547    }
548
549    void negativeDoubleCheck(StackFrame frame, LocalVariable lv) throws Exception {
550        try {
551            DoubleValue get = (DoubleValue) frame.getValue(lv);
552            println(" Get: No ClassCastException error!");
553        } catch(java.lang.ClassCastException ex) {
554            println(" Success: Get: ClassCastException  with Double error has cought as expected!");
555        }
556        try {
557            DoubleValue set = vm().mirrorOf(1.2345E02);
558            frame.setValue(lv, set);
559            println(" Set: No InvalidTypeException with Double error!");
560        } catch(com.sun.jdi.InvalidTypeException ex) {
561            println(" Success: Set: InvalidTypeException error has cought as expected!");
562        }
563    }
564
565    void checkSetFrameVariables(StackFrame frame) throws Exception {
566        List localVars = frame.visibleVariables();
567        int index = 0;
568        println("\n Set variable values:");
569
570        for (Iterator it = localVars.iterator(); it.hasNext();index++) {
571            LocalVariable lv = (LocalVariable) it.next();
572            String signature = lv.type().signature();
573
574            switch (signature.charAt(0)) {
575            case 'Z': // Boolean Type
576                checkSetBooleanTypes(frame, lv);
577                negativeIntegerCheck(frame, lv);
578                negativeFloatCheck(frame, lv);
579                negativeDoubleCheck(frame, lv);
580                break;
581            case 'B': // Byte Type
582                checkSetByteTypes(frame, lv);
583                negativeIntegerCheck(frame, lv);
584                negativeFloatCheck(frame, lv);
585                negativeDoubleCheck(frame, lv);
586                break;
587            case 'C': // Char Type
588                checkSetCharTypes(frame, lv);
589                negativeIntegerCheck(frame, lv);
590                negativeFloatCheck(frame, lv);
591                negativeDoubleCheck(frame, lv);
592                break;
593            case 'S': // Short Type
594                checkSetShortTypes(frame, lv);
595                negativeIntegerCheck(frame, lv);
596                negativeFloatCheck(frame, lv);
597                negativeDoubleCheck(frame, lv);
598                break;
599            case 'I': // Integer Type
600                checkSetIntegerTypes(frame, lv);
601                if (index > 0) { // To skip integer method parameter
602                    negativeFloatCheck(frame, lv);
603                    negativeDoubleCheck(frame, lv);
604                }
605                break;
606            case 'J': // Long Type
607                checkSetLongTypes(frame, lv);
608                negativeIntegerCheck(frame, lv);
609                negativeFloatCheck(frame, lv);
610                negativeDoubleCheck(frame, lv);
611                break;
612            case 'F': // Float Type
613                checkSetFloatTypes(frame, lv);
614                negativeIntegerCheck(frame, lv);
615                negativeDoubleCheck(frame, lv);
616                break;
617            case 'D': // Double Type
618                checkSetDoubleTypes(frame, lv);
619                negativeIntegerCheck(frame, lv);
620                negativeFloatCheck(frame, lv);
621                break;
622            case 'L':
623                if (signature.compareTo("Ljava/lang/String;") == 0) {
624                    checkSetStringTypes(frame, lv);
625                    negativeIntegerCheck(frame, lv);
626                    negativeFloatCheck(frame, lv);
627                }
628                if (signature.compareTo("Ljava/lang/Object;") == 0) {
629                    checkSetObjectTypes(frame, lv);
630                    negativeIntegerCheck(frame, lv);
631                    negativeFloatCheck(frame, lv);
632                }
633                break;
634            default:
635                printOneVariable(lv, index);
636                failure(" Failure: List of local variables has a wrong entry!");
637            };
638        }
639    }
640
641
642    /********** test core **********/
643
644    protected void runTests() throws Exception {
645
646        /*
647         * Get to the top of main() to determine targetClass and mainThread
648         */
649        BreakpointEvent bpe = startToMain("GetSetLocalTarg");
650        println("startToMain(GetSetLocalTarg)");
651
652        List localVars = printAllVariables("GetSetLocalTarg", "staticMeth");
653
654        targetClass = bpe.location().declaringType();
655        println("targetClass");
656
657        mainThread = bpe.thread();
658        println("mainThread");
659
660        EventRequestManager erm = vm().eventRequestManager();
661        println("EventRequestManager");
662        StackFrame frame = null;
663
664        for (int line = START_LINE; line <= STOP_LINE; line += 4) {
665            println("\n resumeTo(GetSetLocalTarg, " + line + ")");
666            bpe = resumeTo("GetSetLocalTarg", line);
667            frame = bpe.thread().frame(0);
668            printFrameVariables(frame);
669            checkSetFrameVariables(frame);
670        }
671        // Check if we can Get/Set all local vars using last frame state
672        checkGetSetAllVariables(localVars, frame);
673
674        /*
675         * resume until the end
676         */
677        listenUntilVMDisconnect();
678
679        /*
680         * deal with results of test
681         * if anything has called failure("foo") testFailed will be true
682         */
683        if (!testFailed) {
684            println("GetSetLocalTest: passed");
685        } else {
686            throw new Exception("GetSetLocalTest: failed");
687        }
688    }
689}
690