1
2
3
4
5
6
7
8
9
10 package nl.tudelft.simulation.dsol.interpreter.operations.reflection;
11
12 import java.io.DataInput;
13 import java.io.IOException;
14 import java.lang.reflect.Method;
15
16 import nl.tudelft.simulation.dsol.interpreter.Frame;
17 import nl.tudelft.simulation.dsol.interpreter.InterpreterException;
18 import nl.tudelft.simulation.dsol.interpreter.classfile.ConstantInterfaceMethodref;
19 import nl.tudelft.simulation.dsol.interpreter.operations.InvokeOperation;
20 import nl.tudelft.simulation.language.primitives.Primitive;
21 import nl.tudelft.simulation.language.reflection.ClassUtil;
22 import nl.tudelft.simulation.language.reflection.MethodSignature;
23
24 /***
25 * INVOKEINTERFACE <br>
26 * (c) copyright 2003 <a href="http://www.simulation.tudelft.nl">Delft
27 * University of Technology </a>, the Netherlands. <br>
28 * See for project information <a
29 * href="http://www.simulation.tudelft.nl">www.simulation.tudelft.nl </a> <br>
30 * License of use: <a href="http://www.gnu.org/copyleft/gpl.html">General Public
31 * License (GPL) </a>, no warranty <br>
32 *
33 * @version 1.0 Jan 8, 2004 <br>
34 * @author <a href="http://www.tbm.tudelft.nl/webstaf/peterja/index.htm">Peter
35 * Jacobs </a> <br>
36 * <a
37 * href="http://www.tbm.tudelft.nl/webstaf/alexandv/index.htm">Alexander
38 * Verbraeck </a>
39 */
40 public class INVOKEINTERFACE extends InvokeOperation
41 {
42 /*** OP refers to the operand code */
43 public static final int OP = 185;
44
45 /*** the index to load */
46 protected int index = -1;
47
48 /***
49 * constructs a new INVOKEINTERFACE
50 *
51 * @param dataInput the dataInput
52 * @throws IOException on IOfailure
53 */
54 public INVOKEINTERFACE(final DataInput dataInput) throws IOException
55 {
56 super();
57 this.index = dataInput.readUnsignedShort();
58 dataInput.skipBytes(2);
59 }
60
61 /***
62 * @see nl.tudelft.simulation.dsol.interpreter.operations.InvokeOperation
63 * #execute(nl.tudelft.simulation.dsol.interpreter.Frame)
64 */
65 public Frame execute(final Frame frame)
66 {
67 try
68 {
69
70
71 ConstantInterfaceMethodref constantInterfaceMethodref = (ConstantInterfaceMethodref) frame
72 .getConstantPool()[this.index];
73 Class[] parameterTypes = new MethodSignature(
74 constantInterfaceMethodref.getConstantNameAndType()
75 .getDescriptor()).getParameterTypes();
76
77 synchronized (frame.getOperandStack())
78 {
79
80 Object objectRef = frame.getOperandStack().peek(
81 parameterTypes.length);
82
83 Method method = ClassUtil.resolveMethod(objectRef,
84 constantInterfaceMethodref.getConstantNameAndType()
85 .getName(), parameterTypes);
86
87
88 Object[] arguments = new Object[parameterTypes.length];
89 for (int i = arguments.length - 1; i > -1; i--)
90 {
91 arguments[i] = Primitive.cast(parameterTypes[i], frame
92 .getOperandStack().pop());
93 }
94 frame.getOperandStack().pop();
95 return this.execute(frame, objectRef, method, arguments);
96 }
97 } catch (Exception exception)
98 {
99 throw new InterpreterException(exception);
100 }
101 }
102
103 /***
104 * executes the method on the objectRef
105 *
106 * @param frame the frame
107 * @param objectRef the objectRef
108 * @param method the method
109 * @param arguments the arguments
110 * @return the resulting Frame
111 * @throws Exception on reflection exception
112 */
113 public Frame execute(final Frame frame, final Object objectRef,
114 final Method method, final Object[] arguments) throws Exception
115 {
116 method.setAccessible(true);
117 Object result = method.invoke(objectRef, arguments);
118
119
120 if (!method.getReturnType().equals(void.class))
121 {
122 frame.getOperandStack().push(result);
123 }
124 return null;
125 }
126
127 /***
128 * @see nl.tudelft.simulation.dsol.interpreter.Operation#getByteLength()
129 */
130 public int getByteLength()
131 {
132 return OPCODE_BYTE_LENGTH + 4;
133 }
134
135 /***
136 * @see nl.tudelft.simulation.dsol.interpreter.Operation#getOpcode()
137 */
138 public int getOpcode()
139 {
140 return INVOKEINTERFACE.OP;
141 }
142 }