/* * Copyright 2010 Sun Microsystems, Inc. All Rights Reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License version 2 only, as * published by the Free Software Foundation. * * This code is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License * version 2 for more details (a copy is included in the LICENSE file that * accompanied this code). * * You should have received a copy of the GNU General Public License version * 2 along with this work; if not, write to the Free Software Foundation, * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. * * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, * CA 95054 USA or visit www.sun.com if you need additional information or * have any questions. */ package org.visage.jdi; import org.visage.jdi.event.VisageEventQueue; import org.visage.jdi.request.VisageEventRequestManager; import com.sun.jdi.ArrayReference; import com.sun.jdi.ArrayType; import com.sun.jdi.BooleanType; import com.sun.jdi.BooleanValue; import com.sun.jdi.ByteType; import com.sun.jdi.ByteValue; import com.sun.jdi.CharType; import com.sun.jdi.CharValue; import com.sun.jdi.ClassLoaderReference; import com.sun.jdi.ClassObjectReference; import com.sun.jdi.ClassType; import com.sun.jdi.DoubleType; import com.sun.jdi.DoubleValue; import com.sun.jdi.Field; import com.sun.jdi.FloatType; import com.sun.jdi.FloatValue; import com.sun.jdi.IntegerType; import com.sun.jdi.IntegerValue; import com.sun.jdi.InterfaceType; import com.sun.jdi.LocalVariable; import com.sun.jdi.Location; import com.sun.jdi.LongType; import com.sun.jdi.LongValue; import com.sun.jdi.Method; import com.sun.jdi.MonitorInfo; import com.sun.jdi.ObjectReference; import com.sun.jdi.PrimitiveType; import com.sun.jdi.PrimitiveValue; import com.sun.jdi.ReferenceType; import com.sun.jdi.ShortType; import com.sun.jdi.ShortValue; import com.sun.jdi.StackFrame; import com.sun.jdi.StringReference; import com.sun.jdi.ThreadGroupReference; import com.sun.jdi.ThreadReference; import com.sun.jdi.Type; import com.sun.jdi.Value; import com.sun.jdi.VirtualMachine; import com.sun.jdi.VoidType; import com.sun.jdi.VoidValue; import com.sun.jdi.event.EventQueue; import com.sun.jdi.request.EventRequestManager; import java.util.ArrayList; import java.util.List; /** * * @author sundar */ public class VisageWrapper { public static VisageVirtualMachine wrap(VirtualMachine vm) { return (vm == null)? null : new VisageVirtualMachine(vm); } public static List<VirtualMachine> wrapVirtualMachines(List<VirtualMachine> vms) { List<VirtualMachine> res = new ArrayList<VirtualMachine>(vms.size()); for (VirtualMachine vm : vms) { res.add(wrap(vm)); } return res; } public static VisageType wrap(VisageVirtualMachine visagevm, Type type) { if (type == null) { return null; } if (type instanceof VoidType) { return visagevm.voidType((VoidType)type); } else if (type instanceof PrimitiveType) { if (type instanceof BooleanType) { return visagevm.booleanType((BooleanType)type); } else if (type instanceof CharType) { return visagevm.charType((CharType)type); } else if (type instanceof ByteType) { return visagevm.byteType((ByteType)type); } else if (type instanceof ShortType) { return visagevm.shortType((ShortType)type); } else if (type instanceof IntegerType) { return visagevm.integerType((IntegerType)type); } else if (type instanceof LongType) { return visagevm.longType((LongType)type); } else if (type instanceof FloatType) { return visagevm.floatType((FloatType)type); } else if (type instanceof DoubleType) { return visagevm.doubleType((DoubleType)type); } else { throw new IllegalArgumentException("illegal primitive type : " + type); } } else if (type instanceof ReferenceType) { return wrap(visagevm, (ReferenceType)type); } else { throw new IllegalArgumentException("illegal type: " + type); } } public static List<Type> wrapTypes(VisageVirtualMachine visagevm, List<Type> types) { if (types == null) { return null; } List<Type> result = new ArrayList<Type>(types.size()); for (Type type : types) { result.add(wrap(visagevm, type)); } return result; } public static VisageReferenceType wrap(VisageVirtualMachine visagevm, ReferenceType rt) { if (rt == null) { return null; } else if (rt instanceof ClassType) { return visagevm.classType((ClassType)rt); } else if (rt instanceof InterfaceType) { return visagevm.interfaceType((InterfaceType)rt); } else if (rt instanceof ArrayType) { return visagevm.arrayType((ArrayType)rt); } else { return visagevm.referenceType(rt); } } public static VisageClassType wrap(VisageVirtualMachine visagevm, ClassType ct) { return (ct == null)? null : visagevm.classType(ct); } public static VisageInterfaceType wrap(VisageVirtualMachine visagevm, InterfaceType it) { return (it == null)? null : visagevm.interfaceType(it); } public static VisageArrayType wrap(VisageVirtualMachine visagevm, ArrayType at) { return (at == null)? null : visagevm.arrayType(at); } public static List<ReferenceType> wrapReferenceTypes(VisageVirtualMachine visagevm, List<ReferenceType> refTypes) { // Note that VirtualMachineImpl caches the list, and returns an unmodifiable wrapped list. // Classes that get loaded in the future are added to its list by an EventListener on ClassPrepared // events. If we cache our wrapped list, they we would have to do the same thing, or be able // to update our cached list when this method is called again. So for the time being, // we won't cache and thus don't have to return an unmodifiable list. if (refTypes == null) { return null; } List<ReferenceType> result = new ArrayList<ReferenceType>(refTypes.size()); for (ReferenceType rt : refTypes) { String className = rt.name(); // visage generated clases contain $[1-9]Local$ or $ObjLit$ if (className.indexOf('$') != -1) { if (className.indexOf("$ObjLit$") != -1) { continue; } if (className.matches(".*\\$[0-9]+Local\\$.*")) { continue; } } result.add(VisageWrapper.wrap(visagevm, rt)); } return result; } public static List<ClassType> wrapClassTypes(VisageVirtualMachine visagevm, List<ClassType> classes) { if (classes == null) { return null; } List<ClassType> result = new ArrayList<ClassType>(classes.size()); for (ClassType ct : classes) { result.add(VisageWrapper.wrap(visagevm, ct)); } return result; } public static List<InterfaceType> wrapInterfaceTypes(VisageVirtualMachine visagevm, List<InterfaceType> interfaces) { if (interfaces == null) { return null; } List<InterfaceType> result = new ArrayList<InterfaceType>(interfaces.size()); for (InterfaceType it : interfaces) { result.add(VisageWrapper.wrap(visagevm, it)); } return result; } public static VisageLocation wrap(VisageVirtualMachine visagevm, Location loc) { return (loc == null)? null : visagevm.location(loc); } public static List<Location> wrapLocations(VisageVirtualMachine visagevm, List<Location> locations) { if (locations == null) { return null; } List<Location> result = new ArrayList<Location>(locations.size()); for (Location loc: locations) { result.add(wrap(visagevm, loc)); } return result; } public static VisageField wrap(VisageVirtualMachine visagevm, Field field) { return (field == null)? null : visagevm.field(field); } /* * The fields are JDI Fields. * Each field can be a user field of an Visage class, an internal field of an Visage class, * or a field of a Java class. */ public static List<Field> wrapFields(VisageVirtualMachine visagevm, List<Field> fields) { // Create VisageField wrappers for each field that is a valid Visage field. if (fields == null) { return null; } // We will have far fewer fields than fields.size() due to all the VFLGS etc // fields we will discard , so start with some small random amount List<Field> result = new ArrayList<Field>(20); for (Field fld : fields) { String fldName = fld.name(); int firstDollar = fldName.indexOf('$'); // java names do not start with $. // Visage user names start with a $ but so do various internal names // mixin vars are mangled with the mixin classname, et, $MixinClassName$fieldName if (firstDollar != -1) { if ((fldName.indexOf("_$",1) != -1) || (fldName.indexOf("$$") != -1) || (fldName.indexOf("$helper$") == 0) || (fldName.indexOf("$script$") == 0) || (fldName.indexOf("$ol$") != -1)) { // $ol$ means it is a shredded name from a bound obj lit (see VisageLower.java) // _$ means it is a synth var (see VisagePreTranslationSupport.java) // $helper$ is in VisageDefs.java continue; } } if (fldName.equals("$assertionsDisabled") && fld.declaringType().name().equals("org.visage.runtime.VisageBase")) { continue; } /* - mixin fields are named $MixinClassName$fieldName - a private script field is java private, and is named with its normal name UNLESS it is referenced in a subclass. In this case it is java public and its name is $ClassName$fieldName. This mangling in of the classname is not yet handled. */ if (firstDollar <= 0) { result.add(visagevm.field(fld)); } } return result; } public static VisageMethod wrap(VisageVirtualMachine visagevm, Method method) { return (method == null)? null : visagevm.method(method); } public static List<Method> wrapMethods(VisageVirtualMachine visagevm, List<Method> methods) { if (methods == null) { return null; } List<Method> result = new ArrayList<Method>(20); for (Method mth : methods) { VisageMethod visagem = visagevm.method(mth); if (!visagem.isVisageInternalMethod()) { result.add(visagem); } } return result; } public static VisageMonitorInfo wrap(VisageVirtualMachine visagevm, MonitorInfo monitorInfo) { return (monitorInfo == null)? null : visagevm.monitorInfo(monitorInfo); } public static List<MonitorInfo> wrapMonitorInfos(VisageVirtualMachine visagevm, List<MonitorInfo> monInfos) { if (monInfos == null) { return null; } List<MonitorInfo> result = new ArrayList<MonitorInfo>(monInfos.size()); for (MonitorInfo mi : monInfos) { result.add(wrap(visagevm, mi)); } return result; } public static VisageStackFrame wrap(VisageVirtualMachine visagevm, StackFrame frame) { return (frame == null)? null : visagevm.stackFrame(frame); } public static List<StackFrame> wrapFrames(VisageVirtualMachine visagevm, List<StackFrame> frames) { if (frames == null) { return null; } List<StackFrame> result = new ArrayList<StackFrame>(frames.size()); for (StackFrame fr : frames) { result.add(wrap(visagevm, fr)); } return result; } public static VisageLocalVariable wrap(VisageVirtualMachine visagevm, LocalVariable var) { return (var == null)? null : visagevm.localVariable(var); } public static List<LocalVariable> wrapLocalVariables(VisageVirtualMachine visagevm, List<LocalVariable> locals) { if (locals == null) { return null; } List<LocalVariable> result = new ArrayList<LocalVariable>(locals.size()); for (LocalVariable var: locals) { result.add(wrap(visagevm, var)); } return result; } public static VisageValue wrap(VisageVirtualMachine visagevm, Value value) { if (value == null) { return null; } if (value instanceof PrimitiveValue) { if (value instanceof BooleanValue) { return visagevm.booleanValue((BooleanValue)value); } else if (value instanceof CharValue) { return visagevm.charValue((CharValue)value); } else if (value instanceof ByteValue) { return visagevm.byteValue((ByteValue)value); } else if (value instanceof ShortValue) { return visagevm.shortValue((ShortValue)value); } else if (value instanceof IntegerValue) { return visagevm.integerValue((IntegerValue)value); } else if (value instanceof LongValue) { return visagevm.longValue((LongValue)value); } else if (value instanceof FloatValue) { return visagevm.floatValue((FloatValue)value); } else if (value instanceof DoubleValue) { return visagevm.doubleValue((DoubleValue)value); } else { throw new IllegalArgumentException("illegal primitive value : " + value); } } else if (value instanceof VoidValue) { return visagevm.voidValue(); } else if (value instanceof ObjectReference) { return wrap(visagevm, (ObjectReference)value); } else { throw new IllegalArgumentException("illegal value: " + value); } } public static List<ObjectReference> wrapObjectReferences(VisageVirtualMachine visagevm, List<ObjectReference> refs) { if (refs == null) { return null; } List<ObjectReference> result = new ArrayList<ObjectReference>(refs.size()); for (ObjectReference ref : refs) { result.add(wrap(visagevm, ref)); } return result; } public static VisageObjectReference wrap(VisageVirtualMachine visagevm, ObjectReference ref) { if (ref == null) { return null; } else if (ref instanceof ArrayReference) { return visagevm.arrayReference((ArrayReference)ref); } else if (ref instanceof StringReference) { return visagevm.stringReference((StringReference)ref); } else if (ref instanceof ThreadReference) { return visagevm.threadReference((ThreadReference)ref); } else if (ref instanceof ThreadGroupReference) { return visagevm.threadGroupReference((ThreadGroupReference)ref); } else if (ref instanceof ClassLoaderReference) { return visagevm.classLoaderReference((ClassLoaderReference)ref); } else if (ref instanceof ClassObjectReference) { return visagevm.classObjectReference((ClassObjectReference)ref); } else { return visagevm.objectReference(ref); } } public static VisageArrayReference wrap(VisageVirtualMachine visagevm, ArrayReference ref) { return (ref == null)? null : visagevm.arrayReference(ref); } public static VisageThreadReference wrap(VisageVirtualMachine visagevm, ThreadReference ref) { return (ref == null)? null : visagevm.threadReference(ref); } public static VisageThreadGroupReference wrap(VisageVirtualMachine visagevm, ThreadGroupReference ref) { return (ref == null)? null : visagevm.threadGroupReference(ref); } public static List<ThreadReference> wrapThreads(VisageVirtualMachine visagevm, List<ThreadReference> threads) { if (threads == null) { return null; } List<ThreadReference> result = new ArrayList<ThreadReference>(threads.size()); for (ThreadReference tref : threads) { result.add(wrap(visagevm, tref)); } return result; } public static List<ThreadGroupReference> wrapThreadGroups(VisageVirtualMachine visagevm, List<ThreadGroupReference> threadGroups) { if (threadGroups == null) { return null; } List<ThreadGroupReference> result = new ArrayList<ThreadGroupReference>(threadGroups.size()); for (ThreadGroupReference tref : threadGroups) { result.add(wrap(visagevm, tref)); } return result; } public static VisageClassLoaderReference wrap(VisageVirtualMachine visagevm, ClassLoaderReference ref) { return (ref == null)? null : visagevm.classLoaderReference(ref); } public static VisageClassObjectReference wrap(VisageVirtualMachine visagevm, ClassObjectReference ref) { return (ref == null)? null : visagevm.classObjectReference(ref); } public static List<Value> wrapValues(VisageVirtualMachine visagevm, List<Value> values) { if (values == null) { return null; } List<Value> result = new ArrayList<Value>(values.size()); for (Value v : values) { result.add(wrap(visagevm, v)); } return result; } public static Location unwrap(Location loc) { return (loc instanceof VisageLocation)? ((VisageLocation)loc).underlying() : loc; } public static StackFrame unwrap(StackFrame frame) { return (frame instanceof VisageStackFrame)? ((VisageStackFrame)frame).underlying() : frame; } public static LocalVariable unwrap(LocalVariable var) { return (var instanceof VisageLocalVariable)? ((VisageLocalVariable)var).underlying() : var; } public static Value unwrap(Value value) { return (value instanceof VisageValue)? ((VisageValue)value).underlying() : value; } public static List<? extends Value> unwrapValues(List<? extends Value> values) { if (values == null) { return null; } List<Value> result = new ArrayList<Value>(values.size()); for (Value v : values) { result.add(unwrap(v)); } return result; } public static Field unwrap(Field field) { return (field instanceof VisageField)? ((VisageField)field).underlying() : field; } public static Method unwrap(Method method) { return (method instanceof VisageMethod)? ((VisageMethod)method).underlying() : method; } public static ObjectReference unwrap(ObjectReference ref) { return (ref instanceof VisageObjectReference)? ((VisageObjectReference)ref).underlying() : ref; } public static ThreadReference unwrap(ThreadReference ref) { return (ref instanceof VisageThreadReference)? ((VisageThreadReference)ref).underlying() : ref; } public static ReferenceType unwrap(ReferenceType rt) { return (rt instanceof VisageReferenceType)? ((VisageReferenceType)rt).underlying() : rt; } public static List<? extends ReferenceType> unwrapReferenceTypes(List<? extends ReferenceType> refTypes) { if (refTypes == null) { return null; } List<ReferenceType> result = new ArrayList<ReferenceType>(refTypes.size()); for (ReferenceType rt : refTypes) { result.add(unwrap(rt)); } return result; } // event requests public static VisageEventRequestManager wrap(VisageVirtualMachine visagevm, EventRequestManager man) { return (man == null)? null : new VisageEventRequestManager(visagevm, man); } // event queue public static VisageEventQueue wrap(VisageVirtualMachine visagevm, EventQueue evtQueue) { return (evtQueue == null)? null : new VisageEventQueue(visagevm, evtQueue); } }