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.Constructor;
15 import java.lang.reflect.Method;
16
17 import nl.tudelft.simulation.dsol.interpreter.Frame;
18 import nl.tudelft.simulation.dsol.interpreter.InterpreterException;
19 import nl.tudelft.simulation.dsol.interpreter.LocalVariable;
20 import nl.tudelft.simulation.dsol.interpreter.classfile.ConstantMethodref;
21 import nl.tudelft.simulation.dsol.interpreter.operations.InvokeOperation;
22 import nl.tudelft.simulation.dsol.interpreter.operations.NEW;
23 import nl.tudelft.simulation.language.primitives.Primitive;
24 import nl.tudelft.simulation.language.reflection.ClassUtil;
25 import nl.tudelft.simulation.language.reflection.MethodSignature;
26
27 /***
28 * INVOKESPECIAL <br>
29 * (c) copyright 2003 <a href="http://www.simulation.tudelft.nl">Delft
30 * University of Technology </a>, the Netherlands. <br>
31 * See for project information <a
32 * href="http://www.simulation.tudelft.nl">www.simulation.tudelft.nl </a> <br>
33 * License of use: <a href="http://www.gnu.org/copyleft/gpl.html">General Public
34 * License (GPL) </a>, no warranty <br>
35 *
36 * @version 1.0 Jan 8, 2004 <br>
37 * @author <a href="http://www.tbm.tudelft.nl/webstaf/peterja/index.htm">Peter
38 * Jacobs </a> <br>
39 * <a
40 * href="http://www.tbm.tudelft.nl/webstaf/alexandv/index.htm">Alexander
41 * Verbraeck </a>
42 */
43 public class INVOKESPECIAL extends InvokeOperation
44 {
45 /*** OP refers to the operand code */
46 public static final int OP = 183;
47
48 /*** the index to load */
49 protected int index = -1;
50
51 /***
52 * constructs a new INVOKESPECIAL
53 *
54 * @param dataInput the dataInput
55 * @throws IOException on IOfailure
56 */
57 public INVOKESPECIAL(final DataInput dataInput) throws IOException
58 {
59 super();
60 this.index = dataInput.readUnsignedShort();
61 }
62
63
64 /***
65 * @see nl.tudelft.simulation.dsol.interpreter.operations.InvokeOperation
66 * #execute(nl.tudelft.simulation.dsol.interpreter.Frame)
67 */
68 public Frame execute(final Frame frame)
69 {
70 try
71 {
72 ConstantMethodref constantMethodref = (ConstantMethodref) frame
73 .getConstantPool()[this.index];
74 Class[] parameterTypes = new MethodSignature(constantMethodref
75 .getConstantNameAndType().getDescriptor())
76 .getParameterTypes();
77 String methodName = constantMethodref.getConstantNameAndType()
78 .getName();
79
80 if (methodName.equals("<init>"))
81 {
82 Object[] args = new Object[parameterTypes.length];
83 for (int i = args.length - 1; i > -1; i--)
84 {
85 args[i] = Primitive.cast(parameterTypes[i], frame
86 .getOperandStack().pop());
87 }
88 Object objectRef = frame.getOperandStack().pop();
89 Class instanceClass = ((NEW.UninitializedInstance) objectRef)
90 .getInstanceClass();
91 Constructor constructor = ClassUtil.resolveConstructor(
92 instanceClass, parameterTypes);
93 constructor.setAccessible(true);
94 Object result = constructor.newInstance(args);
95 frame.getOperandStack().replace(objectRef, result);
96 LocalVariable.replace(frame.getLocalVariables(), objectRef,
97 result);
98 return null;
99 }
100
101 Object objectRef = frame.getOperandStack().peek(
102 parameterTypes.length);
103
104
105 Method method = null;
106
107
108 Class referenceClass = constantMethodref.getConstantClass()
109 .getValue().getClassValue();
110 if (objectRef.getClass().getSuperclass().equals(referenceClass))
111 {
112 method = ClassUtil.resolveMethod(objectRef.getClass()
113 .getSuperclass(), methodName, parameterTypes);
114 } else
115 {
116 method = ClassUtil.resolveMethod(objectRef, methodName,
117 parameterTypes);
118 }
119
120 synchronized (frame.getOperandStack())
121 {
122
123 Object[] args = new Object[parameterTypes.length];
124 for (int i = args.length - 1; i > -1; i--)
125 {
126 args[i] = Primitive.cast(parameterTypes[i], frame
127 .getOperandStack().pop());
128 }
129 frame.getOperandStack().pop();
130 return this.execute(frame, objectRef, method, args);
131 }
132 } catch (Exception exception)
133 {
134 throw new InterpreterException(exception);
135 }
136 }
137
138 /***
139 * executes the method on the objectRef
140 *
141 * @param frame the frame
142 * @param objectRef the objectRef
143 * @param method the method
144 * @param arguments the arguments
145 * @return the resulting Frame
146 * @throws Exception on reflection exception
147 */
148 public Frame execute(final Frame frame, final Object objectRef,
149 final Method method, final Object[] arguments) throws Exception
150 {
151 method.setAccessible(true);
152 Object result = method.invoke(objectRef, arguments);
153
154
155 if (!method.getReturnType().equals(void.class))
156 {
157 frame.getOperandStack().push(result);
158 }
159 return null;
160 }
161
162 /***
163 * @see nl.tudelft.simulation.dsol.interpreter.Operation#getByteLength()
164 */
165 public int getByteLength()
166 {
167 return OPCODE_BYTE_LENGTH + 2;
168 }
169
170 /***
171 * @see nl.tudelft.simulation.dsol.interpreter.Operation#getOpcode()
172 */
173 public int getOpcode()
174 {
175 return INVOKESPECIAL.OP;
176 }
177 }