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.ConstantMethodref;
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 * INVOKESTATIC <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 INVOKESTATIC extends InvokeOperation
41 {
42 /*** OP refers to the operand code */
43 public static final int OP = 184;
44
45 /*** the index to load */
46 protected int index = -1;
47
48 /***
49 * constructs a new INVOKESTATIC
50 *
51 * @param dataInput the dataInput
52 * @throws IOException on IOfailure
53 */
54 public INVOKESTATIC(final DataInput dataInput) throws IOException
55 {
56 super();
57 this.index = dataInput.readUnsignedShort();
58 }
59
60 /***
61 * @see nl.tudelft.simulation.dsol.interpreter.operations.InvokeOperation
62 * #execute(nl.tudelft.simulation.dsol.interpreter.Frame)
63 */
64 public Frame execute(final Frame frame)
65 {
66 try
67 {
68 ConstantMethodref constantMethodref = (ConstantMethodref) frame
69 .getConstantPool()[this.index];
70 Class referenceClass = constantMethodref.getConstantClass()
71 .getValue().getClassValue();
72 Class[] parameterTypes = new MethodSignature(constantMethodref
73 .getConstantNameAndType().getDescriptor())
74 .getParameterTypes();
75
76 String methodName = constantMethodref.getConstantNameAndType()
77 .getName();
78 Method method = ClassUtil.resolveMethod(referenceClass, methodName,
79 parameterTypes);
80
81 synchronized (frame.getOperandStack())
82 {
83
84 Object[] args = new Object[parameterTypes.length];
85 for (int i = args.length - 1; i > -1; i--)
86 {
87 args[i] = Primitive.cast(parameterTypes[i], frame
88 .getOperandStack().pop());
89 }
90 return this.execute(frame, referenceClass, method, args);
91 }
92 } catch (Exception exception)
93 {
94 throw new InterpreterException(exception);
95 }
96 }
97
98 /***
99 * executes the method on the objectRef
100 *
101 * @param frame the frame
102 * @param objectRef the objectRef
103 * @param method the method
104 * @param arguments the arguments
105 * @return the resulting Frame
106 * @throws Exception on reflection exception
107 */
108 public Frame execute(final Frame frame, final Object objectRef,
109 final Method method, final Object[] arguments) throws Exception
110 {
111 method.setAccessible(true);
112 Object result = method.invoke(objectRef, arguments);
113
114
115 if (!method.getReturnType().equals(void.class))
116 {
117 frame.getOperandStack().push(result);
118 }
119 return null;
120 }
121
122 /***
123 * @see nl.tudelft.simulation.dsol.interpreter.Operation#getByteLength()
124 */
125 public int getByteLength()
126 {
127 return OPCODE_BYTE_LENGTH + 2;
128 }
129
130 /***
131 * @see nl.tudelft.simulation.dsol.interpreter.Operation#getOpcode()
132 */
133 public int getOpcode()
134 {
135 return INVOKESTATIC.OP;
136 }
137 }