History

My first initial commit with all of mine experimental changes.

Dmitry Kabak (userdima committed 13 years ago

Commit d37b88d1 parent 3f5b46618352 files · +2598093 −-8690Browse files

Showing the changes to java/pkg/java/lang/reflect/reflect.b (1 of 18352 files). Show all

Unified · Split

java/pkg/java/lang/reflect/reflect.b+327−0
@@ -0,0 +1,327 @@
1implement Reflect;
2
3include "jni.m";
4 jni : JNI;
5 cast : Cast;
6
7 JObject,
8 JClass,
9 JArrayJClass,
10 JArrayJObject,
11 Value : import jni;
12 OK,
13 ERR,
14 TRUE,
15 FALSE,
16 #T_OBJECT, T_ARRAY,
17 T_BOOLEAN,
18 T_BYTE,
19 T_CHAR,
20 T_SHORT,
21 T_INT,
22 T_LONG,
23 T_FLOAT,
24 T_DOUBLE : import JNI;
25
26 ClassData : import JNI;
27
28include "reflect.m";
29
30wrapper_class := array[T_LONG-T_BOOLEAN+1] of ClassData;
31wrapper_name := array[] of { "Boolean",
32 "Character",
33 "Float",
34 "Double",
35 "Byte",
36 "Short",
37 "Integer",
38 "Long" };
39type_string := "ZCFDBSIJ";
40
41illegalarg := "java.lang.IllegalArgumentException";
42nullptr := "java.lang.NullPointerException";
43
44init(jni_m : JNI) {
45 jni = jni_m;
46 for ( i := 0; i <= T_LONG - T_BOOLEAN; i++ )
47 wrapper_class[i] = jni->FindClass("java/lang/" + wrapper_name[i]);
48 cast = jni->CastMod();
49}
50
51widen(have, want : int, val : ref Value) : ref Value
52{
53 if ( have == want )
54 return val;
55 havetype := have;
56 wanttype := want;
57 valint : int;
58 valbig : big;
59 valreal : real;
60 if ( havetype == 0 || wanttype == 0 )
61 return nil;
62 pick sw := val {
63 TByte =>
64 valint = int sw.jbyte;
65 valbig = big valint;
66 valreal = real valint;
67 TShort =>
68 valint = sw.jshort;
69 valbig = big valint;
70 valreal = real valint;
71 TChar =>
72 valint = sw.jchar;
73 valbig = big valint;
74 valreal = real valint;
75 TInt =>
76 valint = sw.jint;
77 valbig = big valint;
78 valreal = real valint;
79 TLong =>
80 valbig = sw.jlong;
81 valreal = real valbig;
82 TFloat =>
83 valreal = sw.jfloat;
84 }
85 case ( wanttype ) {
86 T_BOOLEAN or T_BYTE or T_CHAR =>
87 return nil;
88 T_SHORT =>
89 case ( havetype ) {
90 T_BYTE =>
91 sw := ref Value.TShort;
92 sw.jshort = valint;
93 val = sw;
94 * =>
95 return nil;
96 }
97 T_INT =>
98 case ( havetype ) {
99 T_BYTE or T_SHORT or T_CHAR =>
100 sw := ref Value.TInt;
101 sw.jint = valint;
102 val = sw;
103 * =>
104 return nil;
105 }
106 T_LONG =>
107 case ( havetype ) {
108 T_BYTE or T_SHORT or T_CHAR or T_INT =>
109 sw := ref Value.TLong;
110 sw.jlong = valbig;
111 val = sw;
112 * =>
113 return nil;
114 }
115 T_FLOAT =>
116 case ( havetype ) {
117 T_BYTE or T_SHORT or T_CHAR or T_INT or T_LONG =>
118 sw := ref Value.TFloat;
119 sw.jfloat = valreal;
120 val = sw;
121 * =>
122 return nil;
123 }
124 T_DOUBLE =>
125 case ( havetype ) {
126 T_BYTE or T_SHORT or T_CHAR or T_INT or T_LONG or T_FLOAT =>
127 sw := ref Value.TDouble;
128 sw.jdouble = valreal;
129 val = sw;
130 * =>
131 return nil;
132 }
133 }
134 return val;
135}
136BuildArgList(parms : JArrayJClass, arg : JArrayJObject) : array of ref Value
137{
138 #
139 # First do some checking.
140 #
141 l := 0;
142 formal: array of JClass;
143 actual: array of JObject;
144 args: array of ref Value;
145 if ( parms != nil ) {
146 if ( arg == nil )
147 jni->ThrowException(nullptr, "constructor requires parameters");
148 if ( len parms.ary != len arg.ary )
149 jni->ThrowException(illegalarg, "Wrong number of args");
150 l = len parms.ary;
151 formal = parms.ary; # array of JClass
152 actual = arg.ary; # array of JObject
153 args = array[l] of ref Value;
154 }
155 else # There are no formal parameters
156 if ( arg != nil && len arg.ary != 0 ) # But there are actual arguments
157 jni->ThrowException(illegalarg, "Wrong number of args");
158
159 #
160 # March through the arguments, checking for type as we go.
161 #
162 for ( i := 0; i < l; i++ ) {
163 #
164 # Is the formal parameter a primitive?
165 #
166 if ( (want := jni->PrimitiveIndex(formal[i], 1)) > 0 ) {
167 #
168 # Actual parameter should be (derived from) a wrapper, and
169 # be able to be widened to the formal parameter type.
170 #
171 (typ, parmval) := GetVal(actual[i]);
172 if ( (val := widen(want, typ, parmval)) != nil )
173 args[i] = val;
174 else
175 jni->ThrowException(illegalarg, "Argument " + string (i+1) +
176 ", can't cast");
177 }
178 else if ( jni->IsInstanceOf(actual[i], formal[i].class) == JNI->TRUE ) {
179 val := ref Value.TObject;
180 val.jobj = actual[i];
181 args[i] = val;
182 }
183 else
184 jni->ThrowException(illegalarg, "Argument " + string (i+1) +
185 " wrong type");
186 }
187 return args;
188}
189#
190# Return a JClass corresponding to the Java type t.
191#
192Class(t : int) : JClass
193{
194 if ( t < T_BOOLEAN || t > T_LONG )
195 return nil;
196 return jni->GetClassObject(wrapper_class[t - T_BOOLEAN]);
197}
198#
199# Return a Class Object corresponding to the Java type t.
200#
201ClassObject(t : int) : JObject
202{
203 return cast->FromJClass(Class(t));
204}
205#
206# Given the java type, get the Class object representing this
207# type, and return as a Value.
208#
209GetPrimitiveClass(typ : int) : ref Value
210{
211 return jni->GetStaticField(wrapper_class[typ - T_BOOLEAN], "TYPE",
212 "Ljava/lang/Class;");
213}
214#
215# If the Object o is a wrapper for a Java primitive type, return the
216# primitive value (in a Value adt) and the type index.
217# Otherwise, return 0 and a nil Value.
218#
219GetVal(o : JObject) : (int, ref Value)
220{
221 j := T_BOOLEAN;
222 for ( i := j; i <= T_LONG; i++ ) {
223 if ( jni->IsInstanceOf(o, wrapper_class[i-j]) == TRUE ) {
224 val := jni->GetObjField(o, "value", type_string[i-j:i-j+1]);
225 return (i, val);
226 }
227 }
228 return (0, nil);
229}
230#
231# Convert a signature to a java type index.
232#
233SigToType(sig : string) : int
234{
235 index : int;
236 case sig[0] {
237 'Z' =>
238 index = T_BOOLEAN;
239 'B' =>
240 index = T_BYTE;
241 'C' =>
242 index = T_CHAR;
243 'S' =>
244 index = T_SHORT;
245 'I' =>
246 index = T_INT;
247 'J' =>
248 index = T_LONG;
249 'F' =>
250 index = T_FLOAT;
251 'D' =>
252 index = T_DOUBLE;
253 * =>
254 index = 0;
255 }
256 return index;
257}
258#
259# Convert a java type index to a signature.
260#
261TypeToSig(typ : int) : string
262{
263 if ( typ < T_BOOLEAN || typ > T_LONG )
264 return nil;
265 return type_string[typ-T_BOOLEAN:typ-T_BOOLEAN+1];
266}
267#
268# Convert a Java type character to its corresponding type name.
269#
270TypeCharToName(c : int) : string
271{
272 tname : string;
273 case c {
274 'Z' =>
275 tname = "boolean";
276 'B' =>
277 tname = "byte";
278 'C' =>
279 tname = "char";
280 'S' =>
281 tname = "short";
282 'I' =>
283 tname = "int";
284 'J' =>
285 tname = "long";
286 'F' =>
287 tname = "float";
288 'D' =>
289 tname = "double";
290 * =>
291 tname = "blah";
292 }
293 return tname;
294}
295#
296# Calculate the type index of the quantity in val. If it isn't a
297# Java primitive type, return 0;
298#
299ValType(val : ref Value) : int
300{
301 pick sw := val {
302 TBoolean => return T_BOOLEAN;
303 TByte => return T_BYTE;
304 TChar => return T_CHAR;
305 TShort => return T_SHORT;
306 TInt => return T_INT;
307 TLong => return T_LONG;
308 TFloat => return T_FLOAT;
309 TDouble => return T_DOUBLE;
310 * => return 0;
311 }
312}
313#
314# Create a wrapper Object for the primitive Java value corresponding
315# to the argument.
316#
317ValueToObject(val : ref Value) : JObject
318{
319 typ := ValType(val);
320 j := T_BOOLEAN;
321 jobj := jni->AllocObject(wrapper_class[typ - j]);
322 sig := "(" + type_string[typ-j:typ-j+1] + ")V";
323 (nil, ok) := jni->CallMethod(jobj, "<init>", sig, array[] of { val });
324 if ( ok == OK )
325 return jobj;
326 return nil;
327}

Keyboard shortcuts

General

Show keyboard shortcuts
?
Focus the current search
/

Issues and pull requests

Open filters
f

Issues, pull requests and Inbox

Select next item
j↓
Select previous item
k↑
Open selected item
Enter
Dismiss filters or clear selection
Esc

Repository code

Go to file
t