/** * Auto-boxes or un-boxes arguments of a method. */ static void autoboxArguments(List<Type> types, List<Value> argVals, ThreadReference evaluationThread, EvaluationContext evaluationContext) throws InvalidTypeException, ClassNotLoadedException, IncompatibleThreadStateException, InvocationException { if (types.size() != argVals.size()) { return ; } int n = types.size(); for (int i = 0; i < n; i++) { Type t = types.get(i); Value v = argVals.get(i); if (v instanceof ObjectReference && t instanceof PrimitiveType) { argVals.set(i, unbox((ObjectReference) v, (PrimitiveType) t, evaluationThread, evaluationContext)); } if (v instanceof PrimitiveValue && t instanceof ReferenceType) { argVals.set(i, box((PrimitiveValue) v, (ReferenceType) t, evaluationThread, evaluationContext)); } } }
@Override public void setValue(Value value) { try { if (fieldObject != null) { fieldObject.setValue(field, value); } else { ((ClassType) field.declaringType()).setValue(field, value); } } catch (IllegalArgumentException iaex) { throw new IllegalStateException(new InvalidExpressionException (iaex)); } catch (InvalidTypeException itex) { throw new IllegalStateException(new InvalidExpressionException (itex)); } catch (ClassNotLoadedException cnlex) { throw new IllegalStateException(cnlex); } }
public void stop(ObjectReference throwable) throws InvalidTypeException { validateMirrorOrNull(throwable); // Verify that the given object is a Throwable instance List<ReferenceType> list = vm.classesByName("java.lang.Throwable"); ClassTypeImpl throwableClass = (ClassTypeImpl)list.get(0); if ((throwable == null) || !throwableClass.isAssignableFrom(throwable)) { throw new InvalidTypeException("Not an instance of Throwable"); } try { JDWP.ThreadReference.Stop.process(vm, this, (ObjectReferenceImpl)throwable); } catch (JDWPException exc) { throw exc.toJDIException(); } }
char checkedCharValue() throws InvalidTypeException { if ((value > Character.MAX_VALUE) || (value < Character.MIN_VALUE)) { throw new InvalidTypeException("Can't convert " + value + " to char"); } else { return super.checkedCharValue(); } }
void writeUntaggedValueChecked(Value val) throws InvalidTypeException { byte tag = ValueImpl.typeValueKey(val); if (isObjectTag(tag)) { if (val == null) { writeObjectRef(0); } else { if (!(val instanceof ObjectReference)) { throw new InvalidTypeException(); } writeObjectRef(((ObjectReferenceImpl)val).ref()); } } else { switch (tag) { case JDWP.Tag.BYTE: if(!(val instanceof ByteValue)) throw new InvalidTypeException(); writeByte(((PrimitiveValue)val).byteValue()); break; case JDWP.Tag.CHAR: if(!(val instanceof CharValue)) throw new InvalidTypeException(); writeChar(((PrimitiveValue)val).charValue()); break; case JDWP.Tag.FLOAT: if(!(val instanceof FloatValue)) throw new InvalidTypeException(); writeFloat(((PrimitiveValue)val).floatValue()); break; case JDWP.Tag.DOUBLE: if(!(val instanceof DoubleValue)) throw new InvalidTypeException(); writeDouble(((PrimitiveValue)val).doubleValue()); break; case JDWP.Tag.INT: if(!(val instanceof IntegerValue)) throw new InvalidTypeException(); writeInt(((PrimitiveValue)val).intValue()); break; case JDWP.Tag.LONG: if(!(val instanceof LongValue)) throw new InvalidTypeException(); writeLong(((PrimitiveValue)val).longValue()); break; case JDWP.Tag.SHORT: if(!(val instanceof ShortValue)) throw new InvalidTypeException(); writeShort(((PrimitiveValue)val).shortValue()); break; case JDWP.Tag.BOOLEAN: if(!(val instanceof BooleanValue)) throw new InvalidTypeException(); writeBoolean(((PrimitiveValue)val).booleanValue()); break; } } }
void validateMethodInvocation(Method method, int options) throws InvalidTypeException, InvocationException { /* * Method must be in this object's class, a superclass, or * implemented interface */ ReferenceTypeImpl declType = (ReferenceTypeImpl)method.declaringType(); if (!declType.isAssignableFrom(this)) { throw new IllegalArgumentException("Invalid method"); } if (declType instanceof ClassTypeImpl) { validateClassMethodInvocation(method, options); } else if (declType instanceof InterfaceTypeImpl) { validateIfaceMethodInvocation(method, options); } else { throw new InvalidTypeException(); } }
void validateClassMethodInvocation(Method method, int options) throws InvalidTypeException, InvocationException { /* * Method must be a non-constructor */ if (method.isConstructor()) { throw new IllegalArgumentException("Cannot invoke constructor"); } /* * For nonvirtual invokes, method must have a body */ if (isNonVirtual(options)) { if (method.isAbstract()) { throw new IllegalArgumentException("Abstract method"); } } }
ValueImpl convertForAssignmentTo(ValueContainer destination) throws InvalidTypeException { /* * TO DO: Centralize JNI signature knowledge */ if (destination.signature().length() > 1) { throw new InvalidTypeException("Can't assign primitive value to object"); } if ((destination.signature().charAt(0) == 'Z') && (type().signature().charAt(0) != 'Z')) { throw new InvalidTypeException("Can't assign non-boolean value to a boolean"); } if ((destination.signature().charAt(0) != 'Z') && (type().signature().charAt(0) == 'Z')) { throw new InvalidTypeException("Can't assign boolean value to an non-boolean"); } if ("void".equals(destination.typeName())) { throw new InvalidTypeException("Can't assign primitive value to a void"); } try { PrimitiveTypeImpl primitiveType = (PrimitiveTypeImpl)destination.type(); return (ValueImpl)(primitiveType.convert(this)); } catch (ClassNotLoadedException e) { throw new InternalException("Signature and type inconsistent for: " + destination.typeName()); } }
static ValueImpl prepareForAssignment(Value value, ValueContainer destination) throws InvalidTypeException, ClassNotLoadedException { if (value == null) { /* * TO DO: Centralize JNI signature knowledge */ if (destination.signature().length() == 1) { throw new InvalidTypeException("Can't set a primitive type to null"); } return null; // no further checking or conversion necessary } else { return ((ValueImpl)value).prepareForAssignmentTo(destination); } }
void validateConstructorInvocation(Method method) throws InvalidTypeException, InvocationException { /* * Method must be in this class. */ ReferenceTypeImpl declType = (ReferenceTypeImpl)method.declaringType(); if (!declType.equals(this)) { throw new IllegalArgumentException("Invalid constructor"); } /* * Method must be a constructor */ if (!method.isConstructor()) { throw new IllegalArgumentException("Cannot create instance with non-constructor"); } }
private Value handleSetValueForObject(String name, String belongToClass, String valueString, ObjectReference container, Map<String, Object> options) throws InvalidTypeException, ClassNotLoadedException { Value newValue; if (container instanceof ArrayReference) { ArrayReference array = (ArrayReference) container; Type eleType = ((ArrayType) array.referenceType()).componentType(); newValue = setArrayValue(array, eleType, Integer.parseInt(name), valueString, options); } else { if (StringUtils.isBlank(belongToClass)) { Field field = container.referenceType().fieldByName(name); if (field != null) { if (field.isStatic()) { newValue = this.setStaticFieldValue(container.referenceType(), field, name, valueString, options); } else { newValue = this.setObjectFieldValue(container, field, name, valueString, options); } } else { throw new IllegalArgumentException( String.format("SetVariableRequest: Variable %s cannot be found.", name)); } } else { newValue = setFieldValueWithConflict(container, container.referenceType().allFields(), name, belongToClass, valueString, options); } } return newValue; }
private Value setFieldValueWithConflict(ObjectReference obj, List<Field> fields, String name, String belongToClass, String value, Map<String, Object> options) throws ClassNotLoadedException, InvalidTypeException { Field field; // first try to resolve field by fully qualified name List<Field> narrowedFields = fields.stream().filter(TypeComponent::isStatic) .filter(t -> t.name().equals(name) && t.declaringType().name().equals(belongToClass)) .collect(Collectors.toList()); if (narrowedFields.isEmpty()) { // second try to resolve field by formatted name narrowedFields = fields.stream().filter(TypeComponent::isStatic) .filter(t -> t.name().equals(name) && context.getVariableFormatter().typeToString(t.declaringType(), options).equals(belongToClass)) .collect(Collectors.toList()); } if (narrowedFields.size() == 1) { field = narrowedFields.get(0); } else { throw new UnsupportedOperationException(String.format("SetVariableRequest: Name conflicted for %s.", name)); } return field.isStatic() ? setStaticFieldValue(field.declaringType(), field, name, value, options) : this.setObjectFieldValue(obj, field, name, value, options); }
public void doEffect(RVal preVal, RVal postVal) throws InvalidTypeException, ClassNotLoadedException { if (postVal instanceof ArrayValue) { ArrayValue postArrVal = ((ArrayValue)postVal); if (preVal.getValue() instanceof ArrayReference) { ArrayReference preArrVal = (ArrayReference)preVal.getValue(); if (postArrVal.getValue() instanceof ArrayReference && ((ArrayReference)postArrVal.getValue()).uniqueID() == preArrVal.uniqueID()) { // If it's the same array just with different values, we can reset the values directly. postArrVal.resetTo(preArrVal); return; } } // We must reset the original array's values and reset to it. postArrVal.resetTo((ArrayReference)postArrVal.getValue()); } lval.setValue(postVal.getValue()); }
private static void pauseMedia(ThreadReference tr, VirtualMachine vm) throws InvalidTypeException, ClassNotLoadedException, IncompatibleThreadStateException, InvocationException { final ClassType audioClipClass = getClass(vm, tr, "com.sun.media.jfxmedia.AudioClip"); final ClassType mediaManagerClass = getClass(vm, tr, "com.sun.media.jfxmedia.MediaManager"); final InterfaceType mediaPlayerClass = getInterface(vm, tr, "com.sun.media.jfxmedia.MediaPlayer"); final ClassType playerStateEnum = getClass(vm, tr, "com.sun.media.jfxmedia.events.PlayerStateEvent$PlayerState"); if (audioClipClass != null) { Method stopAllClips = audioClipClass.concreteMethodByName("stopAllClips", "()V"); audioClipClass.invokeMethod(tr, stopAllClips, Collections.EMPTY_LIST, ObjectReference.INVOKE_SINGLE_THREADED); } if (mediaManagerClass != null && mediaPlayerClass != null && playerStateEnum != null) { Method getAllPlayers = mediaManagerClass.concreteMethodByName("getAllMediaPlayers", "()Ljava/util/List;"); ObjectReference plList = (ObjectReference)mediaManagerClass.invokeMethod(tr, getAllPlayers, Collections.EMPTY_LIST, ObjectReference.INVOKE_SINGLE_THREADED); if (plList != null) { ClassType listType = (ClassType)plList.referenceType(); Method iterator = listType.concreteMethodByName("iterator", "()Ljava/util/Iterator;"); ObjectReference plIter = (ObjectReference)plList.invokeMethod(tr, iterator, Collections.EMPTY_LIST, ObjectReference.INVOKE_SINGLE_THREADED); ClassType iterType = (ClassType)plIter.referenceType(); Method hasNext = iterType.concreteMethodByName("hasNext", "()Z"); Method next = iterType.concreteMethodByName("next", "()Ljava/lang/Object;"); Field playingState = playerStateEnum.fieldByName("PLAYING"); Method getState = mediaPlayerClass.methodsByName("getState", "()Lcom/sun/media/jfxmedia/events/PlayerStateEvent$PlayerState;").get(0); Method pausePlayer = mediaPlayerClass.methodsByName("pause", "()V").get(0); boolean hasNextFlag = false; do { BooleanValue v = (BooleanValue)plIter.invokeMethod(tr, hasNext, Collections.EMPTY_LIST, ObjectReference.INVOKE_SINGLE_THREADED); hasNextFlag = v.booleanValue(); if (hasNextFlag) { ObjectReference player = (ObjectReference)plIter.invokeMethod(tr, next, Collections.EMPTY_LIST, ObjectReference.INVOKE_SINGLE_THREADED); ObjectReference curState = (ObjectReference)player.invokeMethod(tr, getState, Collections.EMPTY_LIST, ObjectReference.INVOKE_SINGLE_THREADED); if (playingState.equals(curState)) { player.invokeMethod(tr, pausePlayer, Collections.EMPTY_LIST, ObjectReference.INVOKE_SINGLE_THREADED); pausedPlayers.add(player); } } } while (hasNextFlag); } } }
private static void resumeMedia(ThreadReference tr, VirtualMachine vm) throws InvalidTypeException, ClassNotLoadedException, IncompatibleThreadStateException, InvocationException { if (!pausedPlayers.isEmpty()) { final InterfaceType mediaPlayerClass = getInterface(vm, tr, "com.sun.media.jfxmedia.MediaPlayer"); List<Method> play = mediaPlayerClass.methodsByName("play", "()V"); if (play.isEmpty()) { return; } Method p = play.iterator().next(); for(ObjectReference pR : pausedPlayers) { pR.invokeMethod(tr, p, Collections.EMPTY_LIST, ObjectReference.INVOKE_SINGLE_THREADED); } } }
private static ReferenceType getType(VirtualMachine vm, ThreadReference tr, String name) { List<ReferenceType> classList = VirtualMachineWrapper.classesByName0(vm, name); if (!classList.isEmpty()) { return classList.iterator().next(); } List<ReferenceType> classClassList = VirtualMachineWrapper.classesByName0(vm, "java.lang.Class"); // NOI18N if (classClassList.isEmpty()) { throw new IllegalStateException("Cannot load class Class"); // NOI18N } ClassType cls = (ClassType) classClassList.iterator().next(); try { Method m = ClassTypeWrapper.concreteMethodByName(cls, "forName", "(Ljava/lang/String;)Ljava/lang/Class;"); // NOI18N StringReference mirrorOfName = VirtualMachineWrapper.mirrorOf(vm, name); ClassTypeWrapper.invokeMethod(cls, tr, m, Collections.singletonList(mirrorOfName), ObjectReference.INVOKE_SINGLE_THREADED); List<ReferenceType> classList2 = VirtualMachineWrapper.classesByName0(vm, name); if (!classList2.isEmpty()) { return classList2.iterator().next(); } } catch (ClassNotLoadedException | ClassNotPreparedExceptionWrapper | IncompatibleThreadStateException | InvalidTypeException | InvocationException | InternalExceptionWrapper | ObjectCollectedExceptionWrapper | UnsupportedOperationExceptionWrapper | VMDisconnectedExceptionWrapper ex) { logger.log(Level.FINE, "Cannot load class " + name, ex); // NOI18N } return null; }
private static ArrayReference createTargetBytes(VirtualMachine vm, byte[] bytes, ByteValue[] mirrorBytesCache) throws InvalidTypeException, ClassNotLoadedException, InternalExceptionWrapper, VMDisconnectedExceptionWrapper, ObjectCollectedExceptionWrapper, UnsupportedOperationExceptionWrapper { ArrayType bytesArrayClass = getArrayClass(vm, "byte[]"); ArrayReference array = null; boolean disabledCollection = false; while (!disabledCollection) { array = ArrayTypeWrapper.newInstance(bytesArrayClass, bytes.length); try { ObjectReferenceWrapper.disableCollection(array); disabledCollection = true; } catch (ObjectCollectedExceptionWrapper ocex) { // Collected too soon, try again... } } List<Value> values = new ArrayList<Value>(bytes.length); for (int i = 0; i < bytes.length; i++) { byte b = bytes[i]; ByteValue mb = mirrorBytesCache[128 + b]; if (mb == null) { mb = VirtualMachineWrapper.mirrorOf(vm, b); mirrorBytesCache[128 + b] = mb; } values.add(mb); } ArrayReferenceWrapper.setValues(array, values); return array; }
public boolean sendStopUserCode() throws IllegalStateException { if (closed) { return false; } vm.suspend(); try { ObjectReference myRef = getAgentObjectReference(); OUTER: for (ThreadReference thread : vm.allThreads()) { // could also tag the thread (e.g. using name), to find it easier AGENT: for (StackFrame frame : thread.frames()) { if (REMOTE_AGENT_CLASS.equals(frame.location().declaringType().name())) { String n = frame.location().method().name(); if (AGENT_INVOKE_METHOD.equals(n) || AGENT_VARVALUE_METHOD.equals(n)) { ObjectReference thiz = frame.thisObject(); if (myRef != null && myRef != thiz) { break AGENT; } if (((BooleanValue) thiz.getValue(thiz.referenceType().fieldByName("inClientCode"))).value()) { thiz.setValue(thiz.referenceType().fieldByName("expectingStop"), vm.mirrorOf(true)); ObjectReference stopInstance = (ObjectReference) thiz.getValue(thiz.referenceType().fieldByName("stopException")); vm.resume(); thread.stop(stopInstance); thiz.setValue(thiz.referenceType().fieldByName("expectingStop"), vm.mirrorOf(false)); } return true; } } } } } catch (ClassNotLoadedException | IncompatibleThreadStateException | InvalidTypeException ex) { throw new IllegalStateException(ex); } finally { vm.resume(); } return false; }
private static void setValueToFinalField(ObjectReference obj, String name, ClassType clazz, Value fv, VirtualMachine vm, ThreadReference thread) throws InternalExceptionWrapper, VMDisconnectedExceptionWrapper, ClassNotPreparedExceptionWrapper, ClassNotLoadedException, ObjectCollectedExceptionWrapper, IncompatibleThreadStateException, UnsupportedOperationExceptionWrapper, InvalidTypeException, InvalidObjectException { ObjectReference fieldRef = getDeclaredOrInheritedField(clazz, name, vm, thread); if (fieldRef == null) { InvalidObjectException ioex = new InvalidObjectException("No field "+name+" of class "+clazz); throw ioex; } // field.setAccessible(true); ClassType fieldClassType = (ClassType) ValueWrapper.type(fieldRef); com.sun.jdi.Method setAccessibleMethod = ClassTypeWrapper.concreteMethodByName( fieldClassType, "setAccessible", "(Z)V"); try { ObjectReferenceWrapper.invokeMethod(fieldRef, thread, setAccessibleMethod, Collections.singletonList(vm.mirrorOf(true)), ClassType.INVOKE_SINGLE_THREADED); // field.set(newInstance, fv); com.sun.jdi.Method setMethod = ClassTypeWrapper.concreteMethodByName( fieldClassType, "set", "(Ljava/lang/Object;Ljava/lang/Object;)V"); if (fv instanceof PrimitiveValue) { PrimitiveType pt = (PrimitiveType) ValueWrapper.type(fv); ReferenceType fieldBoxingClass = EvaluatorVisitor.adjustBoxingType(clazz, pt, null); fv = EvaluatorVisitor.box((PrimitiveValue) fv, fieldBoxingClass, thread, null); } List<Value> args = Arrays.asList(new Value[] { obj, fv }); ObjectReferenceWrapper.invokeMethod(fieldRef, thread, setMethod, args, ClassType.INVOKE_SINGLE_THREADED); } catch (InvocationException iex) { throw new InvalidObjectException( "Problem setting value "+fv+" to field "+name+" of class "+clazz+ " : "+iex.exception()); } }
private static ObjectReference getDeclaredOrInheritedField(ClassType clazz, String name, VirtualMachine vm, ThreadReference thread) throws InternalExceptionWrapper, VMDisconnectedExceptionWrapper, ClassNotPreparedExceptionWrapper, ClassNotLoadedException, ObjectCollectedExceptionWrapper, IncompatibleThreadStateException, UnsupportedOperationExceptionWrapper, InvalidTypeException { //try { // java.lang.reflect.Field field = clazz.getDeclaredField(name); // return field; //} catch (NoSuchFieldException ex) {} ClassType classType = (ClassType) getOrLoadClass(vm, "java.lang.Class"); com.sun.jdi.Method getDeclaredFieldMethod = ClassTypeWrapper.concreteMethodByName( classType, "getDeclaredField", "(Ljava/lang/String;)Ljava/lang/reflect/Field;"); try { ObjectReference fieldRef = (ObjectReference) ObjectReferenceWrapper.invokeMethod(ReferenceTypeWrapper.classObject(clazz), thread, getDeclaredFieldMethod, Collections.singletonList(vm.mirrorOf(name)), ClassType.INVOKE_SINGLE_THREADED); return fieldRef; } catch (InvocationException ex) { // Likely NoSuchFieldException, try the super class... } //Class superClass = clazz.getSuperclass(); ClassType superClass = ClassTypeWrapper.superclass(clazz); if (superClass != null) { return getDeclaredOrInheritedField(superClass, name, vm, thread); } else { return null; } }
private static ArrayReference createTargetBytes(VirtualMachine vm, byte[] bytes, ByteValue[] mirrorBytesCache) throws InvalidTypeException, ClassNotLoadedException, InternalExceptionWrapper, VMDisconnectedExceptionWrapper, ObjectCollectedExceptionWrapper { ArrayType bytesArrayClass = getArrayClass(vm, "byte[]"); ArrayReference array = null; boolean disabledCollection = false; while (!disabledCollection) { array = ArrayTypeWrapper.newInstance(bytesArrayClass, bytes.length); try { ObjectReferenceWrapper.disableCollection(array); disabledCollection = true; } catch (ObjectCollectedExceptionWrapper ocex) { // Collected too soon, try again... } catch (UnsupportedOperationExceptionWrapper uex) { // Hope it will not be GC'ed... disabledCollection = true; } } List<Value> values = new ArrayList<Value>(bytes.length); for (int i = 0; i < bytes.length; i++) { byte b = bytes[i]; ByteValue mb = mirrorBytesCache[128 + b]; if (mb == null) { mb = VirtualMachineWrapper.mirrorOf(vm, b); mirrorBytesCache[128 + b] = mb; } values.add(mb); } ArrayReferenceWrapper.setValues(array, values); return array; }
@Override public void setValue(Value value) { try { context.getFrame().setValue(var, value); } catch (InvalidTypeException itex) { throw new IllegalStateException(new InvalidExpressionException (itex)); } catch (ClassNotLoadedException cnlex) { throw new IllegalStateException(cnlex); } }
/** * Method invocation support. * Shared by ClassType and InterfaceType * @param threadIntf the thread in which to invoke. * @param methodIntf method the {@link Method} to invoke. * @param origArguments the list of {@link Value} arguments bound to the * invoked method. Values from the list are assigned to arguments * in the order they appear in the method signature. * @param options the integer bit flag options. * @return a {@link Value} mirror of the invoked method's return value. * @throws java.lang.IllegalArgumentException if the method is not * a member of this type, if the size of the argument list * does not match the number of declared arguments for the method, or * if the method is not static or is a static initializer. * @throws {@link InvalidTypeException} if any argument in the * argument list is not assignable to the corresponding method argument * type. * @throws ClassNotLoadedException if any argument type has not yet been loaded * through the appropriate class loader. * @throws IncompatibleThreadStateException if the specified thread has not * been suspended by an event. * @throws InvocationException if the method invocation resulted in * an exception in the target VM. * @throws InvalidTypeException If the arguments do not meet this requirement -- * Object arguments must be assignment compatible with the argument * type. This implies that the argument type must be * loaded through the enclosing class's class loader. * Primitive arguments must be either assignment compatible with the * argument type or must be convertible to the argument type without loss * of information. See JLS section 5.2 for more information on assignment * compatibility. * @throws VMCannotBeModifiedException if the VirtualMachine is read-only - see {@link VirtualMachine#canBeModified()}. */ final public Value invokeMethod(ThreadReference threadIntf, Method methodIntf, List<? extends Value> origArguments, int options) throws InvalidTypeException, ClassNotLoadedException, IncompatibleThreadStateException, InvocationException { validateMirror(threadIntf); validateMirror(methodIntf); validateMirrorsOrNulls(origArguments); MethodImpl method = (MethodImpl) methodIntf; ThreadReferenceImpl thread = (ThreadReferenceImpl) threadIntf; validateMethodInvocation(method); List<? extends Value> arguments = method.validateAndPrepareArgumentsForInvoke(origArguments); ValueImpl[] args = arguments.toArray(new ValueImpl[0]); InvocationResult ret; try { PacketStream stream = sendInvokeCommand(thread, method, args, options); ret = waitForReply(stream); } catch (JDWPException exc) { if (exc.errorCode() == JDWP.Error.INVALID_THREAD) { throw new IncompatibleThreadStateException(); } else { throw exc.toJDIException(); } } /* * There is an implict VM-wide suspend at the conclusion * of a normal (non-single-threaded) method invoke */ if ((options & ClassType.INVOKE_SINGLE_THREADED) == 0) { vm.notifySuspend(); } if (ret.getException() != null) { throw new InvocationException(ret.getException()); } else { return ret.getResult(); } }
private void validateMethodInvocation(Method method) throws InvalidTypeException, InvocationException { if (!canInvoke(method)) { throw new IllegalArgumentException("Invalid method"); } /* * Method must be a static and not a static initializer */ if (!method.isStatic()) { throw new IllegalArgumentException("Cannot invoke instance method on a class/interface type"); } else if (method.isStaticInitializer()) { throw new IllegalArgumentException("Cannot invoke static initializer"); } }
List<Value> validateAndPrepareArgumentsForInvoke(List<? extends Value> origArguments) throws ClassNotLoadedException, InvalidTypeException { List<Value> arguments = new ArrayList<>(origArguments); if (isVarArgs()) { handleVarArgs(arguments); } int argSize = arguments.size(); JNITypeParser parser = new JNITypeParser(signature()); List<String> signatures = parser.argumentSignatures(); if (signatures.size() != argSize) { throw new IllegalArgumentException("Invalid argument count: expected " + signatures.size() + ", received " + arguments.size()); } for (int i = 0; i < argSize; i++) { Value value = arguments.get(i); value = ValueImpl.prepareForAssignment(value, new ArgumentContainer(i)); arguments.set(i, value); } return arguments; }
byte checkedByteValue() throws InvalidTypeException { if ((value > Byte.MAX_VALUE) || (value < Byte.MIN_VALUE)) { throw new InvalidTypeException("Can't convert " + value + " to byte"); } else { return super.checkedByteValue(); } }
short checkedShortValue() throws InvalidTypeException { if ((value > Short.MAX_VALUE) || (value < Short.MIN_VALUE)) { throw new InvalidTypeException("Can't convert " + value + " to short"); } else { return super.checkedShortValue(); } }
int checkedIntValue() throws InvalidTypeException { int intValue = (int)value; if (intValue != value) { throw new InvalidTypeException("Can't convert " + value + " to int"); } else { return super.checkedIntValue(); } }
long checkedLongValue() throws InvalidTypeException { long longValue = (long)value; if (longValue != value) { throw new InvalidTypeException("Can't convert " + value + " to long"); } else { return super.checkedLongValue(); } }
/** * Method invocation support. * Shared by ClassType and InterfaceType * @param threadIntf the thread in which to invoke. * @param methodIntf method the {@link Method} to invoke. * @param origArguments the list of {@link Value} arguments bound to the * invoked method. Values from the list are assigned to arguments * in the order they appear in the method signature. * @param options the integer bit flag options. * @return a {@link Value} mirror of the invoked method's return value. * @throws java.lang.IllegalArgumentException if the method is not * a member of this type, if the size of the argument list * does not match the number of declared arguments for the method, or * if the method is not static or is a static initializer. * @throws InvalidTypeException if any argument in the * argument list is not assignable to the corresponding method argument * type. * @throws ClassNotLoadedException if any argument type has not yet been loaded * through the appropriate class loader. * @throws IncompatibleThreadStateException if the specified thread has not * been suspended by an event. * @throws InvocationException if the method invocation resulted in * an exception in the target VM. * @throws InvalidTypeException If the arguments do not meet this requirement -- * Object arguments must be assignment compatible with the argument * type. This implies that the argument type must be * loaded through the enclosing class's class loader. * Primitive arguments must be either assignment compatible with the * argument type or must be convertible to the argument type without loss * of information. See JLS section 5.2 for more information on assignment * compatibility. * @throws VMCannotBeModifiedException if the VirtualMachine is read-only - see {@link VirtualMachine#canBeModified()}. */ final public Value invokeMethod(ThreadReference threadIntf, Method methodIntf, List<? extends Value> origArguments, int options) throws InvalidTypeException, ClassNotLoadedException, IncompatibleThreadStateException, InvocationException { validateMirror(threadIntf); validateMirror(methodIntf); validateMirrorsOrNulls(origArguments); MethodImpl method = (MethodImpl) methodIntf; ThreadReferenceImpl thread = (ThreadReferenceImpl) threadIntf; validateMethodInvocation(method); List<? extends Value> arguments = method.validateAndPrepareArgumentsForInvoke(origArguments); ValueImpl[] args = arguments.toArray(new ValueImpl[0]); InvocationResult ret; try { PacketStream stream = sendInvokeCommand(thread, method, args, options); ret = waitForReply(stream); } catch (JDWPException exc) { if (exc.errorCode() == JDWP.Error.INVALID_THREAD) { throw new IncompatibleThreadStateException(); } else { throw exc.toJDIException(); } } /* * There is an implict VM-wide suspend at the conclusion * of a normal (non-single-threaded) method invoke */ if ((options & ClassType.INVOKE_SINGLE_THREADED) == 0) { vm.notifySuspend(); } if (ret.getException() != null) { throw new InvocationException(ret.getException()); } else { return ret.getResult(); } }
void writeValue(Value val) { try { writeValueChecked(val); } catch (InvalidTypeException exc) { // should never happen throw new RuntimeException( "Internal error: Invalid Tag/Type pair"); } }
void writeUntaggedValue(Value val) { try { writeUntaggedValueChecked(val); } catch (InvalidTypeException exc) { // should never happen throw new RuntimeException( "Internal error: Invalid Tag/Type pair"); } }
PrimitiveValue convert(PrimitiveValue value) throws InvalidTypeException { return vm.mirrorOf(((PrimitiveValueImpl)value).checkedDoubleValue()); }
void validateIfaceMethodInvocation(Method method, int options) throws InvalidTypeException, InvocationException { /* * For nonvirtual invokes, method must have a body */ if (isNonVirtual(options)) { if (method.isAbstract()) { throw new IllegalArgumentException("Abstract method"); } } }