1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22 package org.millscript.millscript.functions;
23
24 import org.millscript.commons.alert.Alert;
25 import org.millscript.millscript.alert.Alerts;
26 import org.millscript.millscript.vm.Machine;
27
28 import java.lang.reflect.Constructor;
29 import java.lang.reflect.InvocationTargetException;
30
31 /**
32 * This class implements a function which invokes a Java constructor to create
33 * a new instance of a Java class.
34 */
35 public final class JConstructor extends Function {
36
37 /**
38 * The Java constructor to invoke.
39 */
40 private final Constructor con;
41
42 /**
43 * The type of the parameters this constructor requires.
44 */
45 private final Class[] ptypes;
46
47 /**
48 * The number of arguments this function requires.
49 */
50 private final int numArgs;
51
52 /**
53 * A buffer to use for storing the arguments prior to invoking the
54 * underlying contsructor.
55 */
56 private final Object[] buffer;
57
58 /**
59 * Constructs a new <code>JConstructor</code> function to invoke the
60 * specified Java constructor.
61 *
62 * @param c the Java constructor to invoke
63 */
64 public JConstructor( final Constructor c ) {
65 this.con = c;
66 ptypes = con.getParameterTypes();
67 numArgs = ptypes.length;
68 buffer = new Object[ numArgs ];
69 }
70
71 /**
72 * @see org.millscript.millscript.functions.Function#apply(org.millscript.millscript.vm.Machine, int)
73 */
74 @Override
75 public void apply( final Machine mc, final int nargs ) {
76 checkNargs( mc, numArgs, nargs );
77 mc.popArgsIntoArray( buffer );
78 try {
79 mc.pushObject( con.newInstance( buffer ) );
80 } catch ( InvocationTargetException ex ) {
81 final Throwable cause = ex.getCause();
82 if ( cause instanceof NoClassDefFoundError ) {
83 throw(
84 Alerts.eval(
85 "Cannot construct instance",
86 "A required class could not be found"
87 ).
88 culprit( "Missing class", cause.getMessage() ).
89 mishap()
90 );
91 } else if ( cause instanceof Alert ) {
92 throw (Alert) cause;
93 } else {
94 throw(
95 Alerts.eval(
96 "Cannot construct instance",
97 "An invocation target exception was thrown"
98 ).culprit( "reason", ex.getMessage() ).
99 culprit( "exception", cause ).
100 mishap()
101 );
102 }
103 } catch ( InstantiationException ex ) {
104 throw(
105 Alerts.eval(
106 "Cannot construct instance",
107 "An instantiation exception was thrown"
108 ).culprit( "reason", ex.getMessage() ).mishap()
109 );
110 } catch ( IllegalAccessException ex ) {
111 throw(
112 Alerts.eval(
113 "Cannot construct instance",
114 "An illegal access exception was thrown"
115 ).culprit( "reason", ex.getMessage() ).mishap()
116 );
117 } catch ( IllegalArgumentException ex ) {
118 throw(
119 Alerts.eval(
120 "Cannot construct instance",
121 "An illegal argument exception was thrown"
122 ).culprit( "reason", ex.getMessage() ).mishap()
123 );
124 }
125 }
126
127 }