jdk/src/share/classes/com/sun/tools/example/debug/expr/LValue.java
author alanb
Fri, 02 Nov 2012 15:50:11 +0000
changeset 14342 8435a30053c1
parent 10292 ed7db6a12c2a
child 22050 72e7501ac569
permissions -rw-r--r--
7197491: update copyright year to match last edit in jdk8 jdk repository Reviewed-by: chegar, ksrini
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
     1
/*
14342
8435a30053c1 7197491: update copyright year to match last edit in jdk8 jdk repository
alanb
parents: 10292
diff changeset
     2
 * Copyright (c) 1998, 2011, Oracle and/or its affiliates. All rights reserved.
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
     3
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
90ce3da70b43 Initial load
duke
parents:
diff changeset
     4
 *
90ce3da70b43 Initial load
duke
parents:
diff changeset
     5
 * This code is free software; you can redistribute it and/or modify it
90ce3da70b43 Initial load
duke
parents:
diff changeset
     6
 * under the terms of the GNU General Public License version 2 only, as
5506
202f599c92aa 6943119: Rebrand source copyright notices
ohair
parents: 715
diff changeset
     7
 * published by the Free Software Foundation.  Oracle designates this
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
     8
 * particular file as subject to the "Classpath" exception as provided
5506
202f599c92aa 6943119: Rebrand source copyright notices
ohair
parents: 715
diff changeset
     9
 * by Oracle in the LICENSE file that accompanied this code.
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
    10
 *
90ce3da70b43 Initial load
duke
parents:
diff changeset
    11
 * This code is distributed in the hope that it will be useful, but WITHOUT
90ce3da70b43 Initial load
duke
parents:
diff changeset
    12
 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
90ce3da70b43 Initial load
duke
parents:
diff changeset
    13
 * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
90ce3da70b43 Initial load
duke
parents:
diff changeset
    14
 * version 2 for more details (a copy is included in the LICENSE file that
90ce3da70b43 Initial load
duke
parents:
diff changeset
    15
 * accompanied this code).
90ce3da70b43 Initial load
duke
parents:
diff changeset
    16
 *
90ce3da70b43 Initial load
duke
parents:
diff changeset
    17
 * You should have received a copy of the GNU General Public License version
90ce3da70b43 Initial load
duke
parents:
diff changeset
    18
 * 2 along with this work; if not, write to the Free Software Foundation,
90ce3da70b43 Initial load
duke
parents:
diff changeset
    19
 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
90ce3da70b43 Initial load
duke
parents:
diff changeset
    20
 *
5506
202f599c92aa 6943119: Rebrand source copyright notices
ohair
parents: 715
diff changeset
    21
 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
202f599c92aa 6943119: Rebrand source copyright notices
ohair
parents: 715
diff changeset
    22
 * or visit www.oracle.com if you need additional information or have any
202f599c92aa 6943119: Rebrand source copyright notices
ohair
parents: 715
diff changeset
    23
 * questions.
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
    24
 */
90ce3da70b43 Initial load
duke
parents:
diff changeset
    25
10292
ed7db6a12c2a 7067811: Update demo/sample code to state it should not be used for production
nloodin
parents: 9520
diff changeset
    26
/*
ed7db6a12c2a 7067811: Update demo/sample code to state it should not be used for production
nloodin
parents: 9520
diff changeset
    27
 * This source code is provided to illustrate the usage of a given feature
ed7db6a12c2a 7067811: Update demo/sample code to state it should not be used for production
nloodin
parents: 9520
diff changeset
    28
 * or technique and has been deliberately simplified. Additional steps
ed7db6a12c2a 7067811: Update demo/sample code to state it should not be used for production
nloodin
parents: 9520
diff changeset
    29
 * required for a production-quality application, such as security checks,
ed7db6a12c2a 7067811: Update demo/sample code to state it should not be used for production
nloodin
parents: 9520
diff changeset
    30
 * input validation and proper error handling, might not be present in
ed7db6a12c2a 7067811: Update demo/sample code to state it should not be used for production
nloodin
parents: 9520
diff changeset
    31
 * this sample code.
ed7db6a12c2a 7067811: Update demo/sample code to state it should not be used for production
nloodin
parents: 9520
diff changeset
    32
 */
ed7db6a12c2a 7067811: Update demo/sample code to state it should not be used for production
nloodin
parents: 9520
diff changeset
    33
ed7db6a12c2a 7067811: Update demo/sample code to state it should not be used for production
nloodin
parents: 9520
diff changeset
    34
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
    35
package com.sun.tools.example.debug.expr;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    36
90ce3da70b43 Initial load
duke
parents:
diff changeset
    37
import com.sun.jdi.*;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    38
import java.util.*;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    39
90ce3da70b43 Initial load
duke
parents:
diff changeset
    40
abstract class LValue {
90ce3da70b43 Initial load
duke
parents:
diff changeset
    41
90ce3da70b43 Initial load
duke
parents:
diff changeset
    42
    // The JDI Value object for this LValue.  Once we have this Value,
90ce3da70b43 Initial load
duke
parents:
diff changeset
    43
    // we have to remember it since after we return the LValue object
90ce3da70b43 Initial load
duke
parents:
diff changeset
    44
    // to the ExpressionParser, it might decide that it needs
90ce3da70b43 Initial load
duke
parents:
diff changeset
    45
    // the 'toString' value for the LValue in which case it will
90ce3da70b43 Initial load
duke
parents:
diff changeset
    46
    // call getMassagedValue to get this toString value.  At that
90ce3da70b43 Initial load
duke
parents:
diff changeset
    47
    // point, we don't want to call JDI a 2nd time to get the Value
90ce3da70b43 Initial load
duke
parents:
diff changeset
    48
    // for the LValue.  This is especially wrong when the LValue
90ce3da70b43 Initial load
duke
parents:
diff changeset
    49
    // represents a member function.  We would end up calling it
90ce3da70b43 Initial load
duke
parents:
diff changeset
    50
    // a 2nd time.
90ce3da70b43 Initial load
duke
parents:
diff changeset
    51
    //
90ce3da70b43 Initial load
duke
parents:
diff changeset
    52
    // Unfortunately, there are several levels of calls to
90ce3da70b43 Initial load
duke
parents:
diff changeset
    53
    // get/set values in this file.  To minimize confusion,
90ce3da70b43 Initial load
duke
parents:
diff changeset
    54
    // jdiValue is set/tested at the lowest level - right
90ce3da70b43 Initial load
duke
parents:
diff changeset
    55
    // next to the actual calls to JDI methods to get/set the
90ce3da70b43 Initial load
duke
parents:
diff changeset
    56
    // value in the debuggee.
90ce3da70b43 Initial load
duke
parents:
diff changeset
    57
    protected Value jdiValue;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    58
90ce3da70b43 Initial load
duke
parents:
diff changeset
    59
    abstract Value getValue() throws InvocationException,
90ce3da70b43 Initial load
duke
parents:
diff changeset
    60
                                     IncompatibleThreadStateException,
90ce3da70b43 Initial load
duke
parents:
diff changeset
    61
                                     InvalidTypeException,
90ce3da70b43 Initial load
duke
parents:
diff changeset
    62
                                     ClassNotLoadedException,
90ce3da70b43 Initial load
duke
parents:
diff changeset
    63
                                     ParseException;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    64
90ce3da70b43 Initial load
duke
parents:
diff changeset
    65
    abstract void setValue0(Value value)
90ce3da70b43 Initial load
duke
parents:
diff changeset
    66
                   throws ParseException, InvalidTypeException,
90ce3da70b43 Initial load
duke
parents:
diff changeset
    67
                          ClassNotLoadedException;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    68
90ce3da70b43 Initial load
duke
parents:
diff changeset
    69
    abstract void invokeWith(List<Value> arguments) throws ParseException;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    70
90ce3da70b43 Initial load
duke
parents:
diff changeset
    71
    void setValue(Value value) throws ParseException {
90ce3da70b43 Initial load
duke
parents:
diff changeset
    72
        try {
90ce3da70b43 Initial load
duke
parents:
diff changeset
    73
            setValue0(value);
90ce3da70b43 Initial load
duke
parents:
diff changeset
    74
        } catch (InvalidTypeException exc) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
    75
            throw new ParseException(
90ce3da70b43 Initial load
duke
parents:
diff changeset
    76
                "Attempt to set value of incorrect type" +
90ce3da70b43 Initial load
duke
parents:
diff changeset
    77
                exc);
90ce3da70b43 Initial load
duke
parents:
diff changeset
    78
        } catch (ClassNotLoadedException exc) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
    79
            throw new ParseException(
90ce3da70b43 Initial load
duke
parents:
diff changeset
    80
                "Attempt to set value before " + exc.className() + " was loaded" +
90ce3da70b43 Initial load
duke
parents:
diff changeset
    81
                exc);
90ce3da70b43 Initial load
duke
parents:
diff changeset
    82
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
    83
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
    84
90ce3da70b43 Initial load
duke
parents:
diff changeset
    85
    void setValue(LValue lval) throws ParseException {
90ce3da70b43 Initial load
duke
parents:
diff changeset
    86
        setValue(lval.interiorGetValue());
90ce3da70b43 Initial load
duke
parents:
diff changeset
    87
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
    88
90ce3da70b43 Initial load
duke
parents:
diff changeset
    89
    LValue memberLValue(ExpressionParser.GetFrame frameGetter,
90ce3da70b43 Initial load
duke
parents:
diff changeset
    90
                        String fieldName) throws ParseException {
90ce3da70b43 Initial load
duke
parents:
diff changeset
    91
        try {
90ce3da70b43 Initial load
duke
parents:
diff changeset
    92
            return memberLValue(fieldName, frameGetter.get().thread());
90ce3da70b43 Initial load
duke
parents:
diff changeset
    93
        } catch (IncompatibleThreadStateException exc) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
    94
            throw new ParseException("Thread not suspended");
90ce3da70b43 Initial load
duke
parents:
diff changeset
    95
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
    96
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
    97
90ce3da70b43 Initial load
duke
parents:
diff changeset
    98
    LValue memberLValue(String fieldName, ThreadReference thread) throws ParseException {
90ce3da70b43 Initial load
duke
parents:
diff changeset
    99
90ce3da70b43 Initial load
duke
parents:
diff changeset
   100
        Value val = interiorGetValue();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   101
        if ((val instanceof ArrayReference) &&
90ce3da70b43 Initial load
duke
parents:
diff changeset
   102
            "length".equals(fieldName)){
90ce3da70b43 Initial load
duke
parents:
diff changeset
   103
            return new LValueArrayLength((ArrayReference)val);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   104
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   105
        return new LValueInstanceMember(val, fieldName, thread);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   106
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   107
90ce3da70b43 Initial load
duke
parents:
diff changeset
   108
    // Return the Value for this LValue that would be used to concatenate
90ce3da70b43 Initial load
duke
parents:
diff changeset
   109
    // to a String.  IE, if it is an Object, call toString in the debuggee.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   110
    Value getMassagedValue(ExpressionParser.GetFrame frameGetter) throws ParseException {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   111
        Value vv = interiorGetValue();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   112
90ce3da70b43 Initial load
duke
parents:
diff changeset
   113
        // If vv is an ObjectReference, then we have to
90ce3da70b43 Initial load
duke
parents:
diff changeset
   114
        // do the implicit call to toString().
90ce3da70b43 Initial load
duke
parents:
diff changeset
   115
        if (vv instanceof ObjectReference &&
90ce3da70b43 Initial load
duke
parents:
diff changeset
   116
            !(vv instanceof StringReference) &&
90ce3da70b43 Initial load
duke
parents:
diff changeset
   117
            !(vv instanceof ArrayReference)) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   118
            StackFrame frame;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   119
            try {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   120
                frame = frameGetter.get();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   121
            } catch (IncompatibleThreadStateException exc) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   122
                throw new ParseException("Thread not suspended");
90ce3da70b43 Initial load
duke
parents:
diff changeset
   123
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   124
90ce3da70b43 Initial load
duke
parents:
diff changeset
   125
            ThreadReference thread = frame.thread();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   126
            LValue toStringMember = memberLValue("toString", thread);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   127
            toStringMember.invokeWith(new ArrayList<Value>());
90ce3da70b43 Initial load
duke
parents:
diff changeset
   128
            return toStringMember.interiorGetValue();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   129
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   130
        return vv;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   131
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   132
90ce3da70b43 Initial load
duke
parents:
diff changeset
   133
    Value interiorGetValue() throws ParseException {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   134
        Value value;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   135
        try {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   136
            value = getValue();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   137
        } catch (InvocationException e) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   138
            throw new ParseException("Unable to complete expression. Exception " +
90ce3da70b43 Initial load
duke
parents:
diff changeset
   139
                                     e.exception() + " thrown");
90ce3da70b43 Initial load
duke
parents:
diff changeset
   140
        } catch (IncompatibleThreadStateException itse) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   141
            throw new ParseException("Unable to complete expression. Thread " +
90ce3da70b43 Initial load
duke
parents:
diff changeset
   142
                                     "not suspended for method invoke");
90ce3da70b43 Initial load
duke
parents:
diff changeset
   143
        } catch (InvalidTypeException ite) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   144
            throw new ParseException("Unable to complete expression. Method " +
90ce3da70b43 Initial load
duke
parents:
diff changeset
   145
                                     "argument type mismatch");
90ce3da70b43 Initial load
duke
parents:
diff changeset
   146
        } catch (ClassNotLoadedException tnle) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   147
            throw new ParseException("Unable to complete expression. Method " +
90ce3da70b43 Initial load
duke
parents:
diff changeset
   148
                                     "argument type " + tnle.className() +
90ce3da70b43 Initial load
duke
parents:
diff changeset
   149
                                     " not yet loaded");
90ce3da70b43 Initial load
duke
parents:
diff changeset
   150
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   151
        return value;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   152
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   153
90ce3da70b43 Initial load
duke
parents:
diff changeset
   154
    LValue arrayElementLValue(LValue lval) throws ParseException {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   155
        Value indexValue = lval.interiorGetValue();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   156
        int index;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   157
        if ( (indexValue instanceof IntegerValue) ||
90ce3da70b43 Initial load
duke
parents:
diff changeset
   158
             (indexValue instanceof ShortValue) ||
90ce3da70b43 Initial load
duke
parents:
diff changeset
   159
             (indexValue instanceof ByteValue) ||
90ce3da70b43 Initial load
duke
parents:
diff changeset
   160
             (indexValue instanceof CharValue) ) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   161
            index = ((PrimitiveValue)indexValue).intValue();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   162
        } else {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   163
            throw new ParseException("Array index must be a integer type");
90ce3da70b43 Initial load
duke
parents:
diff changeset
   164
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   165
        return new LValueArrayElement(interiorGetValue(), index);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   166
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   167
9520
99d378796e54 7029383: Refresh of non-client demos
nloodin
parents: 5506
diff changeset
   168
   @Override
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   169
    public String toString() {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   170
        try {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   171
            return interiorGetValue().toString();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   172
        } catch (ParseException e) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   173
            return "<Parse Exception>";
90ce3da70b43 Initial load
duke
parents:
diff changeset
   174
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   175
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   176
90ce3da70b43 Initial load
duke
parents:
diff changeset
   177
    static final int STATIC = 0;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   178
    static final int INSTANCE = 1;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   179
90ce3da70b43 Initial load
duke
parents:
diff changeset
   180
    static Field fieldByName(ReferenceType refType, String name, int kind) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   181
        /*
90ce3da70b43 Initial load
duke
parents:
diff changeset
   182
         * TO DO: Note that this currently fails to find superclass
90ce3da70b43 Initial load
duke
parents:
diff changeset
   183
         * or implemented interface fields. This is due to a temporary
90ce3da70b43 Initial load
duke
parents:
diff changeset
   184
         * limititation of RefType.fieldByName. Once that method is
90ce3da70b43 Initial load
duke
parents:
diff changeset
   185
         * fixed, superclass fields will be found.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   186
         */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   187
        Field field = refType.fieldByName(name);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   188
        if (field != null) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   189
            boolean isStatic = field.isStatic();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   190
            if (((kind == STATIC) && !isStatic) ||
90ce3da70b43 Initial load
duke
parents:
diff changeset
   191
                ((kind == INSTANCE) && isStatic)) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   192
                field = null;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   193
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   194
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   195
/***
90ce3da70b43 Initial load
duke
parents:
diff changeset
   196
        System.err.println("fieldByName: " + refType.name() + " " +
90ce3da70b43 Initial load
duke
parents:
diff changeset
   197
                                             name + " " +
90ce3da70b43 Initial load
duke
parents:
diff changeset
   198
                                             kind + " " +
90ce3da70b43 Initial load
duke
parents:
diff changeset
   199
                                             (field != null));
90ce3da70b43 Initial load
duke
parents:
diff changeset
   200
***/
90ce3da70b43 Initial load
duke
parents:
diff changeset
   201
        return field;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   202
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   203
51
6fe31bc95bbc 6600143: Remove another 450 unnecessary casts
martin
parents: 2
diff changeset
   204
    static List<Method> methodsByName(ReferenceType refType,
6fe31bc95bbc 6600143: Remove another 450 unnecessary casts
martin
parents: 2
diff changeset
   205
                                      String name, int kind) {
6fe31bc95bbc 6600143: Remove another 450 unnecessary casts
martin
parents: 2
diff changeset
   206
        List<Method> list = refType.methodsByName(name);
6fe31bc95bbc 6600143: Remove another 450 unnecessary casts
martin
parents: 2
diff changeset
   207
        Iterator<Method> iter = list.iterator();
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   208
        while (iter.hasNext()) {
51
6fe31bc95bbc 6600143: Remove another 450 unnecessary casts
martin
parents: 2
diff changeset
   209
            Method method = iter.next();
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   210
            boolean isStatic = method.isStatic();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   211
            if (((kind == STATIC) && !isStatic) ||
90ce3da70b43 Initial load
duke
parents:
diff changeset
   212
                ((kind == INSTANCE) && isStatic)) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   213
                iter.remove();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   214
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   215
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   216
        return list;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   217
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   218
90ce3da70b43 Initial load
duke
parents:
diff changeset
   219
    static List<String> primitiveTypeNames = new ArrayList<String>();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   220
    static {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   221
        primitiveTypeNames.add("boolean");
90ce3da70b43 Initial load
duke
parents:
diff changeset
   222
        primitiveTypeNames.add("byte");
90ce3da70b43 Initial load
duke
parents:
diff changeset
   223
        primitiveTypeNames.add("char");
90ce3da70b43 Initial load
duke
parents:
diff changeset
   224
        primitiveTypeNames.add("short");
90ce3da70b43 Initial load
duke
parents:
diff changeset
   225
        primitiveTypeNames.add("int");
90ce3da70b43 Initial load
duke
parents:
diff changeset
   226
        primitiveTypeNames.add("long");
90ce3da70b43 Initial load
duke
parents:
diff changeset
   227
        primitiveTypeNames.add("float");
90ce3da70b43 Initial load
duke
parents:
diff changeset
   228
        primitiveTypeNames.add("double");
90ce3da70b43 Initial load
duke
parents:
diff changeset
   229
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   230
90ce3da70b43 Initial load
duke
parents:
diff changeset
   231
90ce3da70b43 Initial load
duke
parents:
diff changeset
   232
    static final int SAME = 0;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   233
    static final int ASSIGNABLE = 1;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   234
    static final int DIFFERENT = 2;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   235
    /*
90ce3da70b43 Initial load
duke
parents:
diff changeset
   236
     * Return SAME, DIFFERENT or ASSIGNABLE.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   237
     * SAME means each arg type is the same as type of the corr. arg.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   238
     * ASSIGNABLE means that not all the pairs are the same, but
90ce3da70b43 Initial load
duke
parents:
diff changeset
   239
     * for those that aren't, at least the argType is assignable
90ce3da70b43 Initial load
duke
parents:
diff changeset
   240
     * from the type of the argument value.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   241
     * DIFFERENT means that in at least one pair, the
90ce3da70b43 Initial load
duke
parents:
diff changeset
   242
     * argType is not assignable from the type of the argument value.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   243
     * IE, one is an Apple and the other is an Orange.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   244
     */
51
6fe31bc95bbc 6600143: Remove another 450 unnecessary casts
martin
parents: 2
diff changeset
   245
    static int argumentsMatch(List<Type> argTypes, List<Value> arguments) {
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   246
        if (argTypes.size() != arguments.size()) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   247
            return DIFFERENT;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   248
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   249
51
6fe31bc95bbc 6600143: Remove another 450 unnecessary casts
martin
parents: 2
diff changeset
   250
        Iterator<Type> typeIter = argTypes.iterator();
6fe31bc95bbc 6600143: Remove another 450 unnecessary casts
martin
parents: 2
diff changeset
   251
        Iterator<Value> valIter = arguments.iterator();
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   252
        int result = SAME;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   253
90ce3da70b43 Initial load
duke
parents:
diff changeset
   254
        // If any pair aren't the same, change the
90ce3da70b43 Initial load
duke
parents:
diff changeset
   255
        // result to ASSIGNABLE.  If any pair aren't
90ce3da70b43 Initial load
duke
parents:
diff changeset
   256
        // assignable, return DIFFERENT
90ce3da70b43 Initial load
duke
parents:
diff changeset
   257
        while (typeIter.hasNext()) {
51
6fe31bc95bbc 6600143: Remove another 450 unnecessary casts
martin
parents: 2
diff changeset
   258
            Type argType = typeIter.next();
6fe31bc95bbc 6600143: Remove another 450 unnecessary casts
martin
parents: 2
diff changeset
   259
            Value value = valIter.next();
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   260
            if (value == null) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   261
                // Null values can be passed to any non-primitive argument
90ce3da70b43 Initial load
duke
parents:
diff changeset
   262
                if (primitiveTypeNames.contains(argType.name())) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   263
                    return DIFFERENT;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   264
                }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   265
                // Else, we will assume that a null value
90ce3da70b43 Initial load
duke
parents:
diff changeset
   266
                // exactly matches an object type.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   267
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   268
            if (!value.type().equals(argType)) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   269
                if (isAssignableTo(value.type(), argType)) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   270
                    result = ASSIGNABLE;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   271
                } else {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   272
                    return DIFFERENT;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   273
                }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   274
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   275
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   276
        return result;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   277
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   278
90ce3da70b43 Initial load
duke
parents:
diff changeset
   279
90ce3da70b43 Initial load
duke
parents:
diff changeset
   280
    // These is...AssignableTo methods are based on similar code in the JDI
90ce3da70b43 Initial load
duke
parents:
diff changeset
   281
    // implementations of ClassType, ArrayType, and InterfaceType
90ce3da70b43 Initial load
duke
parents:
diff changeset
   282
90ce3da70b43 Initial load
duke
parents:
diff changeset
   283
    static boolean isComponentAssignable(Type fromType, Type toType) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   284
        if (fromType instanceof PrimitiveType) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   285
            // Assignment of primitive arrays requires identical
90ce3da70b43 Initial load
duke
parents:
diff changeset
   286
            // component types.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   287
            return fromType.equals(toType);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   288
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   289
        if (toType instanceof PrimitiveType) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   290
            return false;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   291
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   292
        // Assignment of object arrays requires availability
90ce3da70b43 Initial load
duke
parents:
diff changeset
   293
        // of widening conversion of component types
90ce3da70b43 Initial load
duke
parents:
diff changeset
   294
        return isAssignableTo(fromType, toType);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   295
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   296
90ce3da70b43 Initial load
duke
parents:
diff changeset
   297
    static boolean isArrayAssignableTo(ArrayType fromType, Type toType) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   298
        if (toType instanceof ArrayType) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   299
            try {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   300
                Type toComponentType = ((ArrayType)toType).componentType();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   301
                return isComponentAssignable(fromType.componentType(), toComponentType);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   302
            } catch (ClassNotLoadedException e) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   303
                // One or both component types has not yet been
90ce3da70b43 Initial load
duke
parents:
diff changeset
   304
                // loaded => can't assign
90ce3da70b43 Initial load
duke
parents:
diff changeset
   305
                return false;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   306
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   307
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   308
        if (toType instanceof InterfaceType) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   309
            // Only valid InterfaceType assignee is Cloneable
90ce3da70b43 Initial load
duke
parents:
diff changeset
   310
            return toType.name().equals("java.lang.Cloneable");
90ce3da70b43 Initial load
duke
parents:
diff changeset
   311
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   312
        // Only valid ClassType assignee is Object
90ce3da70b43 Initial load
duke
parents:
diff changeset
   313
        return toType.name().equals("java.lang.Object");
90ce3da70b43 Initial load
duke
parents:
diff changeset
   314
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   315
90ce3da70b43 Initial load
duke
parents:
diff changeset
   316
    static boolean isAssignableTo(Type fromType, Type toType) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   317
        if (fromType.equals(toType)) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   318
            return true;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   319
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   320
90ce3da70b43 Initial load
duke
parents:
diff changeset
   321
        // If one is boolean, so must be the other.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   322
        if (fromType instanceof BooleanType) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   323
            if (toType instanceof BooleanType) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   324
                return true;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   325
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   326
            return false;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   327
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   328
        if (toType instanceof BooleanType) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   329
            return false;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   330
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   331
90ce3da70b43 Initial load
duke
parents:
diff changeset
   332
        // Other primitive types are intermixable only with each other.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   333
        if (fromType instanceof PrimitiveType) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   334
            if (toType instanceof PrimitiveType) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   335
                return true;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   336
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   337
            return false;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   338
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   339
        if (toType instanceof PrimitiveType) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   340
            return false;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   341
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   342
90ce3da70b43 Initial load
duke
parents:
diff changeset
   343
        // neither one is primitive.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   344
        if (fromType instanceof ArrayType) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   345
            return isArrayAssignableTo((ArrayType)fromType, toType);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   346
        }
51
6fe31bc95bbc 6600143: Remove another 450 unnecessary casts
martin
parents: 2
diff changeset
   347
        List<InterfaceType> interfaces;
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   348
        if (fromType instanceof ClassType) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   349
            ClassType superclazz = ((ClassType)fromType).superclass();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   350
            if ((superclazz != null) && isAssignableTo(superclazz, toType)) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   351
                return true;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   352
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   353
            interfaces = ((ClassType)fromType).interfaces();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   354
        } else {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   355
            // fromType must be an InterfaceType
90ce3da70b43 Initial load
duke
parents:
diff changeset
   356
            interfaces = ((InterfaceType)fromType).superinterfaces();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   357
        }
51
6fe31bc95bbc 6600143: Remove another 450 unnecessary casts
martin
parents: 2
diff changeset
   358
        for (InterfaceType interfaze : interfaces) {
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   359
            if (isAssignableTo(interfaze, toType)) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   360
                return true;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   361
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   362
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   363
        return false;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   364
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   365
51
6fe31bc95bbc 6600143: Remove another 450 unnecessary casts
martin
parents: 2
diff changeset
   366
    static Method resolveOverload(List<Method> overloads,
6fe31bc95bbc 6600143: Remove another 450 unnecessary casts
martin
parents: 2
diff changeset
   367
                                  List<Value> arguments)
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   368
                                       throws ParseException {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   369
90ce3da70b43 Initial load
duke
parents:
diff changeset
   370
        // If there is only one method to call, we'll just choose
90ce3da70b43 Initial load
duke
parents:
diff changeset
   371
        // that without looking at the args.  If they aren't right
90ce3da70b43 Initial load
duke
parents:
diff changeset
   372
        // the invoke will return a better error message than we
90ce3da70b43 Initial load
duke
parents:
diff changeset
   373
        // could generate here.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   374
        if (overloads.size() == 1) {
51
6fe31bc95bbc 6600143: Remove another 450 unnecessary casts
martin
parents: 2
diff changeset
   375
            return overloads.get(0);
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   376
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   377
90ce3da70b43 Initial load
duke
parents:
diff changeset
   378
        // Resolving overloads is beyond the scope of this exercise.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   379
        // So, we will look for a method that matches exactly the
90ce3da70b43 Initial load
duke
parents:
diff changeset
   380
        // types of the arguments.  If we can't find one, then
90ce3da70b43 Initial load
duke
parents:
diff changeset
   381
        // if there is exactly one method whose param types are assignable
90ce3da70b43 Initial load
duke
parents:
diff changeset
   382
        // from the arg types, we will use that.  Otherwise,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   383
        // it is an error.  We won't guess which of multiple possible
90ce3da70b43 Initial load
duke
parents:
diff changeset
   384
        // methods to call. And, since casts aren't implemented,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   385
        // the user can't use them to pick a particular overload to call.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   386
        // IE, the user is out of luck in this case.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   387
        Method retVal = null;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   388
        int assignableCount = 0;
51
6fe31bc95bbc 6600143: Remove another 450 unnecessary casts
martin
parents: 2
diff changeset
   389
        for (Method mm : overloads) {
6fe31bc95bbc 6600143: Remove another 450 unnecessary casts
martin
parents: 2
diff changeset
   390
            List<Type> argTypes;
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   391
            try {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   392
                argTypes = mm.argumentTypes();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   393
            } catch (ClassNotLoadedException ee) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   394
                // This probably won't happen for the
90ce3da70b43 Initial load
duke
parents:
diff changeset
   395
                // method that we are really supposed to
90ce3da70b43 Initial load
duke
parents:
diff changeset
   396
                // call.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   397
                continue;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   398
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   399
            int compare = argumentsMatch(argTypes, arguments);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   400
            if (compare == SAME) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   401
                return mm;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   402
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   403
            if (compare == DIFFERENT) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   404
                continue;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   405
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   406
            // Else, it is assignable.  Remember it.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   407
            retVal = mm;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   408
            assignableCount++;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   409
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   410
90ce3da70b43 Initial load
duke
parents:
diff changeset
   411
        // At this point, we didn't find an exact match,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   412
        // but we found one for which the args are assignable.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   413
        //
90ce3da70b43 Initial load
duke
parents:
diff changeset
   414
        if (retVal != null) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   415
            if (assignableCount == 1) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   416
                return retVal;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   417
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   418
            throw new ParseException("Arguments match multiple methods");
90ce3da70b43 Initial load
duke
parents:
diff changeset
   419
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   420
        throw new ParseException("Arguments match no method");
90ce3da70b43 Initial load
duke
parents:
diff changeset
   421
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   422
90ce3da70b43 Initial load
duke
parents:
diff changeset
   423
    private static class LValueLocal extends LValue {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   424
        final StackFrame frame;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   425
        final LocalVariable var;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   426
90ce3da70b43 Initial load
duke
parents:
diff changeset
   427
        LValueLocal(StackFrame frame, LocalVariable var) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   428
            this.frame = frame;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   429
            this.var = var;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   430
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   431
9520
99d378796e54 7029383: Refresh of non-client demos
nloodin
parents: 5506
diff changeset
   432
      @Override
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   433
        Value getValue() {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   434
            if (jdiValue == null) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   435
                jdiValue = frame.getValue(var);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   436
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   437
            return jdiValue;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   438
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   439
9520
99d378796e54 7029383: Refresh of non-client demos
nloodin
parents: 5506
diff changeset
   440
      @Override
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   441
        void setValue0(Value val) throws InvalidTypeException,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   442
                                         ClassNotLoadedException {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   443
            frame.setValue(var, val);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   444
            jdiValue = val;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   445
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   446
9520
99d378796e54 7029383: Refresh of non-client demos
nloodin
parents: 5506
diff changeset
   447
      @Override
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   448
        void invokeWith(List<Value> arguments) throws ParseException {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   449
            throw new ParseException(var.name() + " is not a method");
90ce3da70b43 Initial load
duke
parents:
diff changeset
   450
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   451
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   452
90ce3da70b43 Initial load
duke
parents:
diff changeset
   453
    private static class LValueInstanceMember extends LValue {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   454
        final ObjectReference obj;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   455
        final ThreadReference thread;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   456
        final Field matchingField;
51
6fe31bc95bbc 6600143: Remove another 450 unnecessary casts
martin
parents: 2
diff changeset
   457
        final List<Method> overloads;
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   458
        Method matchingMethod = null;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   459
        List<Value> methodArguments = null;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   460
90ce3da70b43 Initial load
duke
parents:
diff changeset
   461
        LValueInstanceMember(Value value,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   462
                            String memberName,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   463
                            ThreadReference thread) throws ParseException {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   464
            if (!(value instanceof ObjectReference)) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   465
                throw new ParseException(
90ce3da70b43 Initial load
duke
parents:
diff changeset
   466
                       "Cannot access field of primitive type: " + value);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   467
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   468
            this.obj = (ObjectReference)value;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   469
            this.thread = thread;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   470
            ReferenceType refType = obj.referenceType();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   471
            /*
90ce3da70b43 Initial load
duke
parents:
diff changeset
   472
             * Can't tell yet whether this LValue will be accessed as a
90ce3da70b43 Initial load
duke
parents:
diff changeset
   473
             * field or method, so we keep track of all the possibilities
90ce3da70b43 Initial load
duke
parents:
diff changeset
   474
             */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   475
            matchingField = LValue.fieldByName(refType, memberName,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   476
                                               LValue.INSTANCE);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   477
            overloads = LValue.methodsByName(refType, memberName,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   478
                                              LValue.INSTANCE);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   479
            if ((matchingField == null) && overloads.size() == 0) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   480
                throw new ParseException("No instance field or method with the name "
90ce3da70b43 Initial load
duke
parents:
diff changeset
   481
                               + memberName + " in " + refType.name());
90ce3da70b43 Initial load
duke
parents:
diff changeset
   482
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   483
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   484
9520
99d378796e54 7029383: Refresh of non-client demos
nloodin
parents: 5506
diff changeset
   485
      @Override
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   486
        Value getValue() throws InvocationException, InvalidTypeException,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   487
                                ClassNotLoadedException, IncompatibleThreadStateException,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   488
                                ParseException {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   489
            if (jdiValue != null) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   490
                return jdiValue;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   491
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   492
            if (matchingMethod == null) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   493
                if (matchingField == null) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   494
                    throw new ParseException("No such field in " + obj.referenceType().name());
90ce3da70b43 Initial load
duke
parents:
diff changeset
   495
                }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   496
                return jdiValue = obj.getValue(matchingField);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   497
            } else {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   498
                return jdiValue = obj.invokeMethod(thread, matchingMethod, methodArguments, 0);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   499
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   500
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   501
9520
99d378796e54 7029383: Refresh of non-client demos
nloodin
parents: 5506
diff changeset
   502
        @Override
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   503
        void setValue0(Value val) throws ParseException,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   504
                                         InvalidTypeException,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   505
                                        ClassNotLoadedException {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   506
            if (matchingMethod != null) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   507
                throw new ParseException("Cannot assign to a method invocation");
90ce3da70b43 Initial load
duke
parents:
diff changeset
   508
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   509
            obj.setValue(matchingField, val);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   510
            jdiValue = val;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   511
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   512
9520
99d378796e54 7029383: Refresh of non-client demos
nloodin
parents: 5506
diff changeset
   513
        @Override
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   514
        void invokeWith(List<Value> arguments) throws ParseException {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   515
            if (matchingMethod != null) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   516
                throw new ParseException("Invalid consecutive invocations");
90ce3da70b43 Initial load
duke
parents:
diff changeset
   517
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   518
            methodArguments = arguments;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   519
            matchingMethod = LValue.resolveOverload(overloads, arguments);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   520
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   521
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   522
90ce3da70b43 Initial load
duke
parents:
diff changeset
   523
    private static class LValueStaticMember extends LValue {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   524
        final ReferenceType refType;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   525
        final ThreadReference thread;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   526
        final Field matchingField;
51
6fe31bc95bbc 6600143: Remove another 450 unnecessary casts
martin
parents: 2
diff changeset
   527
        final List<Method> overloads;
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   528
        Method matchingMethod = null;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   529
        List<Value> methodArguments = null;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   530
90ce3da70b43 Initial load
duke
parents:
diff changeset
   531
        LValueStaticMember(ReferenceType refType,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   532
                          String memberName,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   533
                          ThreadReference thread) throws ParseException {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   534
            this.refType = refType;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   535
            this.thread = thread;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   536
            /*
90ce3da70b43 Initial load
duke
parents:
diff changeset
   537
             * Can't tell yet whether this LValue will be accessed as a
90ce3da70b43 Initial load
duke
parents:
diff changeset
   538
             * field or method, so we keep track of all the possibilities
90ce3da70b43 Initial load
duke
parents:
diff changeset
   539
             */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   540
            matchingField = LValue.fieldByName(refType, memberName,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   541
                                               LValue.STATIC);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   542
            overloads = LValue.methodsByName(refType, memberName,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   543
                                              LValue.STATIC);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   544
            if ((matchingField == null) && overloads.size() == 0) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   545
                throw new ParseException("No static field or method with the name "
90ce3da70b43 Initial load
duke
parents:
diff changeset
   546
                               + memberName + " in " + refType.name());
90ce3da70b43 Initial load
duke
parents:
diff changeset
   547
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   548
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   549
9520
99d378796e54 7029383: Refresh of non-client demos
nloodin
parents: 5506
diff changeset
   550
        @Override
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   551
        Value getValue() throws InvocationException, InvalidTypeException,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   552
                                ClassNotLoadedException, IncompatibleThreadStateException,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   553
                                ParseException {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   554
            if (jdiValue != null) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   555
                return jdiValue;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   556
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   557
            if (matchingMethod == null) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   558
                return jdiValue = refType.getValue(matchingField);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   559
            } else if (refType instanceof ClassType) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   560
                ClassType clazz = (ClassType)refType;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   561
                return jdiValue = clazz.invokeMethod(thread, matchingMethod, methodArguments, 0);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   562
            } else {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   563
                throw new InvalidTypeException("Cannot invoke static method on " +
90ce3da70b43 Initial load
duke
parents:
diff changeset
   564
                                         refType.name());
90ce3da70b43 Initial load
duke
parents:
diff changeset
   565
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   566
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   567
9520
99d378796e54 7029383: Refresh of non-client demos
nloodin
parents: 5506
diff changeset
   568
        @Override
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   569
        void setValue0(Value val)
90ce3da70b43 Initial load
duke
parents:
diff changeset
   570
                           throws ParseException, InvalidTypeException,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   571
                                  ClassNotLoadedException {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   572
            if (matchingMethod != null) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   573
                throw new ParseException("Cannot assign to a method invocation");
90ce3da70b43 Initial load
duke
parents:
diff changeset
   574
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   575
            if (!(refType instanceof ClassType)) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   576
                throw new ParseException(
90ce3da70b43 Initial load
duke
parents:
diff changeset
   577
                       "Cannot set interface field: " + refType);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   578
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   579
            ((ClassType)refType).setValue(matchingField, val);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   580
            jdiValue = val;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   581
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   582
9520
99d378796e54 7029383: Refresh of non-client demos
nloodin
parents: 5506
diff changeset
   583
        @Override
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   584
        void invokeWith(List<Value> arguments) throws ParseException {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   585
            if (matchingMethod != null) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   586
                throw new ParseException("Invalid consecutive invocations");
90ce3da70b43 Initial load
duke
parents:
diff changeset
   587
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   588
            methodArguments = arguments;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   589
            matchingMethod = LValue.resolveOverload(overloads, arguments);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   590
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   591
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   592
90ce3da70b43 Initial load
duke
parents:
diff changeset
   593
    private static class LValueArrayLength extends LValue {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   594
        /*
90ce3da70b43 Initial load
duke
parents:
diff changeset
   595
         * Since one can code "int myLen = myArray.length;",
90ce3da70b43 Initial load
duke
parents:
diff changeset
   596
         * one might expect that these JDI calls would get a Value
90ce3da70b43 Initial load
duke
parents:
diff changeset
   597
         * object for the length of an array in the debugee:
90ce3da70b43 Initial load
duke
parents:
diff changeset
   598
         *    Field xxx = ArrayType.fieldByName("length")
90ce3da70b43 Initial load
duke
parents:
diff changeset
   599
         *    Value lenVal= ArrayReference.getValue(xxx)
90ce3da70b43 Initial load
duke
parents:
diff changeset
   600
         *
90ce3da70b43 Initial load
duke
parents:
diff changeset
   601
         * However, this doesn't work because the array length isn't
90ce3da70b43 Initial load
duke
parents:
diff changeset
   602
         * really stored as a field, and can't be accessed as such
90ce3da70b43 Initial load
duke
parents:
diff changeset
   603
         * via JDI.  Instead, the arrayRef.length() method has to be
90ce3da70b43 Initial load
duke
parents:
diff changeset
   604
         * used.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   605
         */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   606
        final ArrayReference arrayRef;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   607
        LValueArrayLength (ArrayReference value) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   608
            this.arrayRef = value;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   609
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   610
9520
99d378796e54 7029383: Refresh of non-client demos
nloodin
parents: 5506
diff changeset
   611
        @Override
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   612
        Value getValue() {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   613
            if (jdiValue == null) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   614
                jdiValue = arrayRef.virtualMachine().mirrorOf(arrayRef.length());
90ce3da70b43 Initial load
duke
parents:
diff changeset
   615
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   616
            return jdiValue;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   617
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   618
9520
99d378796e54 7029383: Refresh of non-client demos
nloodin
parents: 5506
diff changeset
   619
        @Override
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   620
        void setValue0(Value value) throws ParseException  {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   621
            throw new ParseException("Cannot set constant: " + value);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   622
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   623
9520
99d378796e54 7029383: Refresh of non-client demos
nloodin
parents: 5506
diff changeset
   624
        @Override
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   625
        void invokeWith(List<Value> arguments) throws ParseException {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   626
            throw new ParseException("Array element is not a method");
90ce3da70b43 Initial load
duke
parents:
diff changeset
   627
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   628
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   629
90ce3da70b43 Initial load
duke
parents:
diff changeset
   630
    private static class LValueArrayElement extends LValue {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   631
        final ArrayReference array;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   632
        final int index;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   633
90ce3da70b43 Initial load
duke
parents:
diff changeset
   634
        LValueArrayElement(Value value, int index) throws ParseException {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   635
            if (!(value instanceof ArrayReference)) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   636
                throw new ParseException(
90ce3da70b43 Initial load
duke
parents:
diff changeset
   637
                       "Must be array type: " + value);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   638
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   639
            this.array = (ArrayReference)value;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   640
            this.index = index;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   641
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   642
9520
99d378796e54 7029383: Refresh of non-client demos
nloodin
parents: 5506
diff changeset
   643
        @Override
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   644
        Value getValue() {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   645
            if (jdiValue == null) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   646
                jdiValue = array.getValue(index);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   647
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   648
            return jdiValue;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   649
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   650
9520
99d378796e54 7029383: Refresh of non-client demos
nloodin
parents: 5506
diff changeset
   651
        @Override
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   652
        void setValue0(Value val) throws InvalidTypeException,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   653
                                         ClassNotLoadedException  {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   654
            array.setValue(index, val);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   655
            jdiValue = val;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   656
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   657
9520
99d378796e54 7029383: Refresh of non-client demos
nloodin
parents: 5506
diff changeset
   658
        @Override
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   659
        void invokeWith(List<Value> arguments) throws ParseException {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   660
            throw new ParseException("Array element is not a method");
90ce3da70b43 Initial load
duke
parents:
diff changeset
   661
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   662
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   663
90ce3da70b43 Initial load
duke
parents:
diff changeset
   664
    private static class LValueConstant extends LValue {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   665
        final Value value;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   666
90ce3da70b43 Initial load
duke
parents:
diff changeset
   667
        LValueConstant(Value value) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   668
            this.value = value;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   669
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   670
9520
99d378796e54 7029383: Refresh of non-client demos
nloodin
parents: 5506
diff changeset
   671
        @Override
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   672
        Value getValue() {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   673
            if (jdiValue == null) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   674
                jdiValue = value;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   675
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   676
            return jdiValue;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   677
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   678
9520
99d378796e54 7029383: Refresh of non-client demos
nloodin
parents: 5506
diff changeset
   679
        @Override
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   680
        void setValue0(Value val) throws ParseException {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   681
            throw new ParseException("Cannot set constant: " + value);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   682
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   683
9520
99d378796e54 7029383: Refresh of non-client demos
nloodin
parents: 5506
diff changeset
   684
        @Override
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   685
        void invokeWith(List<Value> arguments) throws ParseException {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   686
            throw new ParseException("Constant is not a method");
90ce3da70b43 Initial load
duke
parents:
diff changeset
   687
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   688
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   689
90ce3da70b43 Initial load
duke
parents:
diff changeset
   690
    static LValue make(VirtualMachine vm, boolean val) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   691
        return new LValueConstant(vm.mirrorOf(val));
90ce3da70b43 Initial load
duke
parents:
diff changeset
   692
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   693
90ce3da70b43 Initial load
duke
parents:
diff changeset
   694
    static LValue make(VirtualMachine vm, byte val) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   695
        return new LValueConstant(vm.mirrorOf(val));
90ce3da70b43 Initial load
duke
parents:
diff changeset
   696
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   697
90ce3da70b43 Initial load
duke
parents:
diff changeset
   698
    static LValue make(VirtualMachine vm, char val) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   699
        return new LValueConstant(vm.mirrorOf(val));
90ce3da70b43 Initial load
duke
parents:
diff changeset
   700
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   701
90ce3da70b43 Initial load
duke
parents:
diff changeset
   702
    static LValue make(VirtualMachine vm, short val) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   703
        return new LValueConstant(vm.mirrorOf(val));
90ce3da70b43 Initial load
duke
parents:
diff changeset
   704
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   705
90ce3da70b43 Initial load
duke
parents:
diff changeset
   706
    static LValue make(VirtualMachine vm, int val) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   707
        return new LValueConstant(vm.mirrorOf(val));
90ce3da70b43 Initial load
duke
parents:
diff changeset
   708
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   709
90ce3da70b43 Initial load
duke
parents:
diff changeset
   710
    static LValue make(VirtualMachine vm, long val) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   711
        return new LValueConstant(vm.mirrorOf(val));
90ce3da70b43 Initial load
duke
parents:
diff changeset
   712
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   713
90ce3da70b43 Initial load
duke
parents:
diff changeset
   714
    static LValue make(VirtualMachine vm, float val) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   715
        return new LValueConstant(vm.mirrorOf(val));
90ce3da70b43 Initial load
duke
parents:
diff changeset
   716
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   717
90ce3da70b43 Initial load
duke
parents:
diff changeset
   718
    static LValue make(VirtualMachine vm, double val) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   719
        return new LValueConstant(vm.mirrorOf(val));
90ce3da70b43 Initial load
duke
parents:
diff changeset
   720
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   721
90ce3da70b43 Initial load
duke
parents:
diff changeset
   722
    static LValue make(VirtualMachine vm, String val) throws ParseException {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   723
        return new LValueConstant(vm.mirrorOf(val));
90ce3da70b43 Initial load
duke
parents:
diff changeset
   724
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   725
90ce3da70b43 Initial load
duke
parents:
diff changeset
   726
    static LValue makeBoolean(VirtualMachine vm, Token token) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   727
        return make(vm, token.image.charAt(0) == 't');
90ce3da70b43 Initial load
duke
parents:
diff changeset
   728
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   729
90ce3da70b43 Initial load
duke
parents:
diff changeset
   730
    static LValue makeCharacter(VirtualMachine vm, Token token) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   731
        return make(vm, token.image.charAt(1));
90ce3da70b43 Initial load
duke
parents:
diff changeset
   732
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   733
90ce3da70b43 Initial load
duke
parents:
diff changeset
   734
    static LValue makeFloat(VirtualMachine vm, Token token) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   735
        return make(vm, Float.valueOf(token.image).floatValue());
90ce3da70b43 Initial load
duke
parents:
diff changeset
   736
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   737
90ce3da70b43 Initial load
duke
parents:
diff changeset
   738
    static LValue makeDouble(VirtualMachine vm, Token token) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   739
        return make(vm, Double.valueOf(token.image).doubleValue());
90ce3da70b43 Initial load
duke
parents:
diff changeset
   740
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   741
90ce3da70b43 Initial load
duke
parents:
diff changeset
   742
    static LValue makeInteger(VirtualMachine vm, Token token) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   743
        return make(vm, Integer.parseInt(token.image));
90ce3da70b43 Initial load
duke
parents:
diff changeset
   744
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   745
90ce3da70b43 Initial load
duke
parents:
diff changeset
   746
    static LValue makeShort(VirtualMachine vm, Token token) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   747
        return make(vm, Short.parseShort(token.image));
90ce3da70b43 Initial load
duke
parents:
diff changeset
   748
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   749
90ce3da70b43 Initial load
duke
parents:
diff changeset
   750
    static LValue makeLong(VirtualMachine vm, Token token) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   751
        return make(vm, Long.parseLong(token.image));
90ce3da70b43 Initial load
duke
parents:
diff changeset
   752
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   753
90ce3da70b43 Initial load
duke
parents:
diff changeset
   754
    static LValue makeByte(VirtualMachine vm, Token token) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   755
        return make(vm, Byte.parseByte(token.image));
90ce3da70b43 Initial load
duke
parents:
diff changeset
   756
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   757
90ce3da70b43 Initial load
duke
parents:
diff changeset
   758
    static LValue makeString(VirtualMachine vm,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   759
                             Token token) throws ParseException {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   760
        int len = token.image.length();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   761
        return make(vm, token.image.substring(1,len-1));
90ce3da70b43 Initial load
duke
parents:
diff changeset
   762
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   763
90ce3da70b43 Initial load
duke
parents:
diff changeset
   764
    static LValue makeNull(VirtualMachine vm,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   765
                           Token token) throws ParseException {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   766
        return new LValueConstant(null);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   767
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   768
90ce3da70b43 Initial load
duke
parents:
diff changeset
   769
    static LValue makeThisObject(VirtualMachine vm,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   770
                                 ExpressionParser.GetFrame frameGetter,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   771
                                 Token token) throws ParseException {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   772
        if (frameGetter == null) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   773
            throw new ParseException("No current thread");
90ce3da70b43 Initial load
duke
parents:
diff changeset
   774
        } else {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   775
            try {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   776
                StackFrame frame = frameGetter.get();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   777
                ObjectReference thisObject = frame.thisObject();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   778
90ce3da70b43 Initial load
duke
parents:
diff changeset
   779
                if (thisObject==null) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   780
                        throw new ParseException(
90ce3da70b43 Initial load
duke
parents:
diff changeset
   781
                            "No 'this'.  In native or static method");
90ce3da70b43 Initial load
duke
parents:
diff changeset
   782
                } else {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   783
                        return new LValueConstant(thisObject);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   784
                }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   785
            } catch (IncompatibleThreadStateException exc) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   786
                throw new ParseException("Thread not suspended");
90ce3da70b43 Initial load
duke
parents:
diff changeset
   787
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   788
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   789
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   790
90ce3da70b43 Initial load
duke
parents:
diff changeset
   791
    static LValue makeNewObject(VirtualMachine vm,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   792
                                 ExpressionParser.GetFrame frameGetter,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   793
                                String className, List<Value> arguments) throws ParseException {
51
6fe31bc95bbc 6600143: Remove another 450 unnecessary casts
martin
parents: 2
diff changeset
   794
        List<ReferenceType> classes = vm.classesByName(className);
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   795
        if (classes.size() == 0) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   796
            throw new ParseException("No class named: " + className);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   797
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   798
90ce3da70b43 Initial load
duke
parents:
diff changeset
   799
        if (classes.size() > 1) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   800
            throw new ParseException("More than one class named: " +
90ce3da70b43 Initial load
duke
parents:
diff changeset
   801
                                     className);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   802
        }
51
6fe31bc95bbc 6600143: Remove another 450 unnecessary casts
martin
parents: 2
diff changeset
   803
        ReferenceType refType = classes.get(0);
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   804
90ce3da70b43 Initial load
duke
parents:
diff changeset
   805
90ce3da70b43 Initial load
duke
parents:
diff changeset
   806
        if (!(refType instanceof ClassType)) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   807
            throw new ParseException("Cannot create instance of interface " +
90ce3da70b43 Initial load
duke
parents:
diff changeset
   808
                                     className);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   809
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   810
90ce3da70b43 Initial load
duke
parents:
diff changeset
   811
        ClassType classType = (ClassType)refType;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   812
        List<Method> methods = new ArrayList<Method>(classType.methods()); // writable
51
6fe31bc95bbc 6600143: Remove another 450 unnecessary casts
martin
parents: 2
diff changeset
   813
        Iterator<Method> iter = methods.iterator();
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   814
        while (iter.hasNext()) {
51
6fe31bc95bbc 6600143: Remove another 450 unnecessary casts
martin
parents: 2
diff changeset
   815
            Method method = iter.next();
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   816
            if (!method.isConstructor()) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   817
                iter.remove();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   818
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   819
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   820
        Method constructor = LValue.resolveOverload(methods, arguments);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   821
90ce3da70b43 Initial load
duke
parents:
diff changeset
   822
        ObjectReference newObject;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   823
        try {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   824
            ThreadReference thread = frameGetter.get().thread();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   825
            newObject = classType.newInstance(thread, constructor, arguments, 0);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   826
        } catch (InvocationException ie) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   827
            throw new ParseException("Exception in " + className + " constructor: " +
90ce3da70b43 Initial load
duke
parents:
diff changeset
   828
                                     ie.exception().referenceType().name());
90ce3da70b43 Initial load
duke
parents:
diff changeset
   829
        } catch (IncompatibleThreadStateException exc) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   830
            throw new ParseException("Thread not suspended");
90ce3da70b43 Initial load
duke
parents:
diff changeset
   831
        } catch (Exception e) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   832
            /*
90ce3da70b43 Initial load
duke
parents:
diff changeset
   833
             * TO DO: Better error handling
90ce3da70b43 Initial load
duke
parents:
diff changeset
   834
             */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   835
            throw new ParseException("Unable to create " + className + " instance");
90ce3da70b43 Initial load
duke
parents:
diff changeset
   836
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   837
        return new LValueConstant(newObject);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   838
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   839
90ce3da70b43 Initial load
duke
parents:
diff changeset
   840
    private static LValue nFields(LValue lval,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   841
                                  StringTokenizer izer,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   842
                                  ThreadReference thread)
90ce3da70b43 Initial load
duke
parents:
diff changeset
   843
                                          throws ParseException {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   844
        if (!izer.hasMoreTokens()) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   845
            return lval;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   846
        } else {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   847
            return nFields(lval.memberLValue(izer.nextToken(), thread), izer, thread);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   848
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   849
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   850
90ce3da70b43 Initial load
duke
parents:
diff changeset
   851
    static LValue makeName(VirtualMachine vm,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   852
                           ExpressionParser.GetFrame frameGetter,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   853
                           String name) throws ParseException {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   854
        StringTokenizer izer = new StringTokenizer(name, ".");
90ce3da70b43 Initial load
duke
parents:
diff changeset
   855
        String first = izer.nextToken();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   856
        // check local variables
90ce3da70b43 Initial load
duke
parents:
diff changeset
   857
        if (frameGetter != null) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   858
            try {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   859
                StackFrame frame = frameGetter.get();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   860
                ThreadReference thread = frame.thread();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   861
                LocalVariable var;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   862
                try {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   863
                    var = frame.visibleVariableByName(first);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   864
                } catch (AbsentInformationException e) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   865
                    var = null;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   866
                }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   867
                if (var != null) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   868
                    return nFields(new LValueLocal(frame, var), izer, thread);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   869
                } else {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   870
                    ObjectReference thisObject = frame.thisObject();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   871
                    if (thisObject != null) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   872
                        // check if it is a field of 'this'
90ce3da70b43 Initial load
duke
parents:
diff changeset
   873
                        LValue thisLValue = new LValueConstant(thisObject);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   874
                        LValue fv;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   875
                        try {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   876
                            fv = thisLValue.memberLValue(first, thread);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   877
                        } catch (ParseException exc) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   878
                            fv = null;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   879
                        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   880
                        if (fv != null) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   881
                            return nFields(fv, izer, thread);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   882
                        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   883
                    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   884
                }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   885
                // check for class name
90ce3da70b43 Initial load
duke
parents:
diff changeset
   886
                while (izer.hasMoreTokens()) {
51
6fe31bc95bbc 6600143: Remove another 450 unnecessary casts
martin
parents: 2
diff changeset
   887
                    List<ReferenceType> classes = vm.classesByName(first);
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   888
                    if (classes.size() > 0) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   889
                        if (classes.size() > 1) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   890
                            throw new ParseException("More than one class named: " +
90ce3da70b43 Initial load
duke
parents:
diff changeset
   891
                                                     first);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   892
                        } else {
51
6fe31bc95bbc 6600143: Remove another 450 unnecessary casts
martin
parents: 2
diff changeset
   893
                            ReferenceType refType = classes.get(0);
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   894
                            LValue lval = new LValueStaticMember(refType,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   895
                                                            izer.nextToken(), thread);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   896
                            return nFields(lval, izer, thread);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   897
                        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   898
                    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   899
                    first = first + '.' + izer.nextToken();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   900
                }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   901
            } catch (IncompatibleThreadStateException exc) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   902
                throw new ParseException("Thread not suspended");
90ce3da70b43 Initial load
duke
parents:
diff changeset
   903
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   904
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   905
        throw new ParseException("Name unknown: " + name);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   906
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   907
90ce3da70b43 Initial load
duke
parents:
diff changeset
   908
    static String stringValue(LValue lval, ExpressionParser.GetFrame frameGetter
90ce3da70b43 Initial load
duke
parents:
diff changeset
   909
                              ) throws ParseException {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   910
        Value val = lval.getMassagedValue(frameGetter);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   911
        if (val == null) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   912
            return "null";
90ce3da70b43 Initial load
duke
parents:
diff changeset
   913
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   914
        if (val instanceof StringReference) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   915
            return ((StringReference)val).value();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   916
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   917
        return val.toString();  // is this correct in all cases?
90ce3da70b43 Initial load
duke
parents:
diff changeset
   918
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   919
90ce3da70b43 Initial load
duke
parents:
diff changeset
   920
    static LValue booleanOperation(VirtualMachine vm, Token token,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   921
                            LValue rightL,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   922
                            LValue leftL) throws ParseException {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   923
        String op = token.image;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   924
        Value right = rightL.interiorGetValue();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   925
        Value left = leftL.interiorGetValue();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   926
        if ( !(right instanceof PrimitiveValue) ||
90ce3da70b43 Initial load
duke
parents:
diff changeset
   927
             !(left instanceof PrimitiveValue) ) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   928
            if (op.equals("==")) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   929
                return make(vm, right.equals(left));
90ce3da70b43 Initial load
duke
parents:
diff changeset
   930
            } else if (op.equals("!=")) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   931
                return make(vm, !right.equals(left));
90ce3da70b43 Initial load
duke
parents:
diff changeset
   932
            } else {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   933
                throw new ParseException("Operands or '" + op +
90ce3da70b43 Initial load
duke
parents:
diff changeset
   934
                                     "' must be primitive");
90ce3da70b43 Initial load
duke
parents:
diff changeset
   935
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   936
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   937
        // can compare any numeric doubles
90ce3da70b43 Initial load
duke
parents:
diff changeset
   938
        double rr = ((PrimitiveValue)right).doubleValue();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   939
        double ll = ((PrimitiveValue)left).doubleValue();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   940
        boolean res;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   941
        if (op.equals("<")) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   942
            res = rr < ll;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   943
        } else if (op.equals(">")) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   944
            res = rr > ll;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   945
        } else if (op.equals("<=")) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   946
            res = rr <= ll;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   947
        } else if (op.equals(">=")) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   948
            res = rr >= ll;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   949
        } else if (op.equals("==")) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   950
            res = rr == ll;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   951
        } else if (op.equals("!=")) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   952
            res = rr != ll;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   953
        } else {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   954
            throw new ParseException("Unknown operation: " + op);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   955
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   956
        return make(vm, res);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   957
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   958
90ce3da70b43 Initial load
duke
parents:
diff changeset
   959
    static LValue operation(VirtualMachine vm, Token token,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   960
                            LValue rightL, LValue leftL,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   961
                            ExpressionParser.GetFrame frameGetter
90ce3da70b43 Initial load
duke
parents:
diff changeset
   962
                            ) throws ParseException {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   963
        String op = token.image;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   964
        Value right = rightL.interiorGetValue();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   965
        Value left = leftL.interiorGetValue();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   966
        if ((right instanceof StringReference) ||
90ce3da70b43 Initial load
duke
parents:
diff changeset
   967
                              (left instanceof StringReference)) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   968
            if (op.equals("+")) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   969
                // If one is an ObjectRef, we will need to invoke
90ce3da70b43 Initial load
duke
parents:
diff changeset
   970
                // toString on it, so we need the thread.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   971
                return make(vm, stringValue(rightL, frameGetter) +
90ce3da70b43 Initial load
duke
parents:
diff changeset
   972
                            stringValue(leftL, frameGetter));
90ce3da70b43 Initial load
duke
parents:
diff changeset
   973
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   974
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   975
        if ((right instanceof ObjectReference) ||
90ce3da70b43 Initial load
duke
parents:
diff changeset
   976
                              (left instanceof ObjectReference)) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   977
            if (op.equals("==")) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   978
                return make(vm, right.equals(left));
90ce3da70b43 Initial load
duke
parents:
diff changeset
   979
            } else if (op.equals("!=")) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   980
                return make(vm, !right.equals(left));
90ce3da70b43 Initial load
duke
parents:
diff changeset
   981
            } else {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   982
                throw new ParseException("Invalid operation '" +
90ce3da70b43 Initial load
duke
parents:
diff changeset
   983
                                         op + "' on an Object");
90ce3da70b43 Initial load
duke
parents:
diff changeset
   984
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   985
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   986
        if ((right instanceof BooleanValue) ||
90ce3da70b43 Initial load
duke
parents:
diff changeset
   987
                              (left instanceof BooleanValue)) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   988
            throw new ParseException("Invalid operation '" +
90ce3da70b43 Initial load
duke
parents:
diff changeset
   989
                                     op + "' on a Boolean");
90ce3da70b43 Initial load
duke
parents:
diff changeset
   990
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   991
        // from here on, we know it is a integer kind of type
90ce3da70b43 Initial load
duke
parents:
diff changeset
   992
        PrimitiveValue primRight = (PrimitiveValue)right;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   993
        PrimitiveValue primLeft = (PrimitiveValue)left;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   994
        if ((primRight instanceof DoubleValue) ||
90ce3da70b43 Initial load
duke
parents:
diff changeset
   995
                              (primLeft instanceof DoubleValue)) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   996
            double rr = primRight.doubleValue();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   997
            double ll = primLeft.doubleValue();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   998
            double res;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   999
            if (op.equals("+")) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1000
                res = rr + ll;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1001
            } else if (op.equals("-")) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1002
                res = rr - ll;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1003
            } else if (op.equals("*")) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1004
                res = rr * ll;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1005
            } else if (op.equals("/")) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1006
                res = rr / ll;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1007
            } else {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1008
                throw new ParseException("Unknown operation: " + op);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1009
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1010
            return make(vm, res);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1011
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1012
        if ((primRight instanceof FloatValue) ||
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1013
                              (primLeft instanceof FloatValue)) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1014
            float rr = primRight.floatValue();
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1015
            float ll = primLeft.floatValue();
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1016
            float res;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1017
            if (op.equals("+")) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1018
                res = rr + ll;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1019
            } else if (op.equals("-")) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1020
                res = rr - ll;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1021
            } else if (op.equals("*")) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1022
                res = rr * ll;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1023
            } else if (op.equals("/")) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1024
                res = rr / ll;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1025
            } else {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1026
                throw new ParseException("Unknown operation: " + op);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1027
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1028
            return make(vm, res);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1029
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1030
        if ((primRight instanceof LongValue) ||
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1031
                              (primLeft instanceof LongValue)) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1032
            long rr = primRight.longValue();
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1033
            long ll = primLeft.longValue();
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1034
            long res;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1035
            if (op.equals("+")) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1036
                res = rr + ll;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1037
            } else if (op.equals("-")) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1038
                res = rr - ll;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1039
            } else if (op.equals("*")) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1040
                res = rr * ll;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1041
            } else if (op.equals("/")) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1042
                res = rr / ll;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1043
            } else {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1044
                throw new ParseException("Unknown operation: " + op);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1045
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1046
            return make(vm, res);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1047
        } else {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1048
            int rr = primRight.intValue();
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1049
            int ll = primLeft.intValue();
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1050
            int res;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1051
            if (op.equals("+")) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1052
                res = rr + ll;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1053
            } else if (op.equals("-")) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1054
                res = rr - ll;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1055
            } else if (op.equals("*")) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1056
                res = rr * ll;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1057
            } else if (op.equals("/")) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1058
                res = rr / ll;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1059
            } else {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1060
                throw new ParseException("Unknown operation: " + op);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1061
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1062
            return make(vm, res);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1063
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1064
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1065
}