View Javadoc

1   /*
2    * @(#) INVOKESPECIAL.java Jan 8, 2004
3    * 
4    * Copyright (c) 2003 Delft University of Technology Jaffalaan 5, 2628 BX Delft,
5    * the Netherlands All rights reserved.
6    * 
7    * This software is proprietary information of Delft University of Technology
8    * The code is published under the General Public License
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 			//Now the normal methods
105 			Method method = null;
106 
107 			// look if we need to resolve a super() method
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 				//Let's create the arguments
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 		//	Let's see what to do with the stack
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 }