bitescript 0.0.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,429 @@
1
+ require 'test/unit'
2
+ require 'bitescript'
3
+ require 'bitescript/builder'
4
+
5
+ class TestBuilder < Test::Unit::TestCase
6
+ JLong = java.lang.Long
7
+ JString = java.lang.String
8
+ System = java.lang.System
9
+ JRubyMethod = org.jruby.anno.JRubyMethod
10
+
11
+ def new_class_name
12
+ "Foo" + (System.nano_time + rand(JLong::MAX_VALUE)).to_s
13
+ end
14
+
15
+ def setup
16
+ # Java 1.5 compat required for annotation tests
17
+ BiteScript.bytecode_version = BiteScript::JAVA1_5
18
+ @builder = BiteScript::FileBuilder.build('somefile.source')
19
+ @class_name = new_class_name
20
+ end
21
+
22
+ def dummy_constructor(class_builder)
23
+ class_builder.public_constructor do
24
+ aload local 'this'
25
+ invokespecial object, '<init>', [void]
26
+ returnvoid
27
+ end
28
+ end
29
+
30
+ def load_and_construct(name, class_builder)
31
+ class_bytes = class_builder.generate
32
+ File.open(name + ".class", 'w') {|f| f.write(class_bytes)}
33
+ cls = JRuby.runtime.jruby_class_loader.define_class(name, class_bytes.to_java_bytes)
34
+
35
+ cls.new_instance
36
+ end
37
+
38
+ def load(name, builder)
39
+ bytes = builder.generate
40
+ JRuby.runtime.jruby_class_loader.define_class(name, bytes.to_java_bytes)
41
+ JavaUtilities.get_proxy_class(name)
42
+ end
43
+
44
+ def try(return_type, &b)
45
+ class_name = new_class_name
46
+ cb = @builder.public_class(class_name, @builder.object);
47
+ cb.public_static_method("foo", return_type, &b)
48
+ dummy_constructor(cb)
49
+ cls = load(class_name, cb)
50
+ cls.foo
51
+ end
52
+
53
+ def test_static_method
54
+ assert_equal 'ok', try(JString) {ldc 'ok'; areturn}
55
+ end
56
+
57
+ def test_field_ops
58
+ # TODO
59
+ end
60
+
61
+ def test_sync_ops
62
+ # TODO figure out what's wrong with this and add error cases
63
+ assert_equal 'ok', try(JString) {
64
+ after = label
65
+ ldc 'ok'
66
+ astore 0
67
+ ldc 'ok'
68
+ astore 1
69
+ aload 0
70
+ # monitorenter
71
+ label :begin
72
+ ldc 'ok'
73
+ astore 1
74
+ goto after
75
+ label :finally
76
+ pop
77
+ aload 0
78
+ # monitorexit
79
+ label :end
80
+ trycatch(:begin, :finally, :finally, nil)
81
+ trycatch(:finally, :end, :finally, nil)
82
+ after.set!
83
+ aload 1
84
+ areturn
85
+ }
86
+ end
87
+
88
+ def test_stack_ops
89
+ # TODO
90
+ end
91
+
92
+ def test_constants
93
+ assert_equal false, try(Java::boolean) {ldc false; ireturn}
94
+ assert_equal 1, try(Java::byte) {ldc 1; ireturn}
95
+ assert_equal 1, try(Java::short) {ldc 1; ireturn}
96
+ assert_equal 1, try(Java::char) {ldc 1; ireturn}
97
+ assert_equal 1, try(Java::int) {ldc 1; ireturn}
98
+ assert_equal 1, try(Java::long) {ldc_long 1; lreturn}
99
+ assert_equal 1.0, try(Java::float) {ldc_float 1.0; freturn}
100
+ assert_equal 1.0, try(Java::double) {ldc 1.0; dreturn}
101
+ assert_equal 'foo', try(JString) {ldc 'foo'; areturn}
102
+
103
+ assert_equal(-1, try(Java::int) {iconst_m1; ireturn})
104
+ assert_equal 0, try(Java::int) {iconst_0; ireturn}
105
+ assert_equal 1, try(Java::int) {iconst_1; ireturn}
106
+ assert_equal 2, try(Java::int) {iconst_2; ireturn}
107
+ assert_equal 3, try(Java::int) {iconst_3; ireturn}
108
+ assert_equal 4, try(Java::int) {iconst_4; ireturn}
109
+ assert_equal 5, try(Java::int) {iconst_5; ireturn}
110
+ assert_equal 0, try(Java::long) {lconst_0; lreturn}
111
+ assert_equal 1, try(Java::long) {lconst_1; lreturn}
112
+ assert_equal 0.0, try(Java::float) {fconst_0; freturn}
113
+ assert_equal 1.0, try(Java::float) {fconst_1; freturn}
114
+ assert_equal 2.0, try(Java::float) {fconst_2; freturn}
115
+ assert_equal 0.0, try(Java::double) {dconst_0; dreturn}
116
+ assert_equal 1.0, try(Java::double) {dconst_1; dreturn}
117
+ assert_equal nil, try(JString) {aconst_null; areturn}
118
+ end
119
+
120
+ def test_math
121
+ assert_equal 2, try(Java::int) {ldc 1; ldc 1; iadd; ireturn}
122
+ assert_equal 0, try(Java::int) {ldc 1; ldc 1; isub; ireturn}
123
+ assert_equal 4, try(Java::int) {ldc 2; ldc 2; imul; ireturn}
124
+ assert_equal 2, try(Java::int) {ldc 4; ldc 2; idiv; ireturn}
125
+ assert_equal 2, try(Java::int) {ldc 1; ldc 1; iadd; ireturn}
126
+ assert_equal 2, try(Java::int) {ldc 1; istore 0; iinc 0, 1; iload 0; ireturn}
127
+ assert_equal 0, try(Java::int) {ldc 1; istore 0; iinc 0, -1; iload 0; ireturn}
128
+ assert_equal 5, try(Java::int) {ldc 1; ldc 4; ior; ireturn}
129
+ assert_equal 5, try(Java::int) {ldc 7; ldc 13; iand; ireturn}
130
+ assert_equal 5, try(Java::int) {ldc 10; ldc 15; ixor; ireturn}
131
+ assert_equal(-5, try(Java::int) {ldc 5; ineg; ireturn})
132
+ assert_equal(2147483643, try(Java::int) {ldc(-10); ldc 1; iushr; ireturn})
133
+ assert_equal(-5, try(Java::int) {ldc(-10); ldc 1; ishr; ireturn})
134
+ assert_equal(8, try(Java::int) {ldc 4; ldc 1; ishl; ireturn})
135
+ assert_equal(3, try(Java::int) {ldc 15; ldc 4; irem; ireturn})
136
+
137
+ assert_equal 2, try(Java::long) {ldc_long 1; ldc_long 1; ladd; lreturn}
138
+ assert_equal 0, try(Java::long) {ldc_long 1; ldc_long 1; lsub; lreturn}
139
+ assert_equal 4, try(Java::long) {ldc_long 2; ldc_long 2; lmul; lreturn}
140
+ assert_equal 2, try(Java::long) {ldc_long 4; ldc_long 2; ldiv; lreturn}
141
+ assert_equal 5, try(Java::long) {ldc_long 1; ldc_long 4; lor; lreturn}
142
+ assert_equal 5, try(Java::long) {ldc_long 7; ldc_long 13; land; lreturn}
143
+ assert_equal 5, try(Java::long) {ldc_long 10; ldc_long 15; lxor; lreturn}
144
+ assert_equal(-5, try(Java::long) {ldc_long 5; lneg; lreturn})
145
+ assert_equal(9223372036854775803, try(Java::long) {ldc_long(-10); ldc 1; lushr; lreturn})
146
+ assert_equal(-5, try(Java::long) {ldc_long(-10); ldc 1; lshr; lreturn})
147
+ assert_equal(8, try(Java::long) {ldc_long 4; ldc 1; lshl; lreturn})
148
+ assert_equal(3, try(Java::long) {ldc_long 15; ldc_long 4; lrem; lreturn})
149
+
150
+ assert_equal 2.0, try(Java::float) {ldc_float 1; ldc_float 1; fadd; freturn}
151
+ assert_equal 0.0, try(Java::float) {ldc_float 1; ldc_float 1; fsub; freturn}
152
+ assert_equal 4.0, try(Java::float) {ldc_float 2; ldc_float 2; fmul; freturn}
153
+ assert_equal 2.0, try(Java::float) {ldc_float 4; ldc_float 2; fdiv; freturn}
154
+ assert_equal(-5.0, try(Java::float) {ldc_float 5; fneg; freturn})
155
+ assert_equal(3.0, try(Java::float) {ldc_float 15; ldc_float 4; frem; freturn})
156
+
157
+ assert_equal 2.0, try(Java::double) {ldc_double 1; ldc_double 1; dadd; dreturn}
158
+ assert_equal 0.0, try(Java::double) {ldc_double 1; ldc_double 1; dsub; dreturn}
159
+ assert_equal 4.0, try(Java::double) {ldc_double 2; ldc_double 2; dmul; dreturn}
160
+ assert_equal 2.0, try(Java::double) {ldc_double 4; ldc_double 2; ddiv; dreturn}
161
+ assert_equal(-5.0, try(Java::double) {ldc_double 5; dneg; dreturn})
162
+ assert_equal(3.0, try(Java::double) {ldc_double 15; ldc_double 4; drem; dreturn})
163
+ end
164
+
165
+ def test_trycatch
166
+ assert_equal 2, try(Java::int) {
167
+ label :begin
168
+ new java.lang.Exception
169
+ dup
170
+ invokespecial java.lang.Exception, '<init>', [void]
171
+ athrow
172
+ label :catch
173
+ ldc 2
174
+ ireturn
175
+ label :end
176
+ trycatch(:begin, :catch, :catch, java.lang.Exception)
177
+ }
178
+ end
179
+
180
+ def test_jumps
181
+ assert_equal 2, try(Java::int) {after = label; goto after; ldc 1; ireturn; after.set!; ldc 2; ireturn}
182
+ assert_equal 2, try(Java::int) {after = label; ldc 0; ifeq after; ldc 1; ireturn; after.set!; ldc 2; ireturn}
183
+ assert_equal 2, try(Java::int) {after = label; ldc 1; ifne after; ldc 1; ireturn; after.set!; ldc 2; ireturn}
184
+ assert_equal 2, try(Java::int) {after = label; ldc -1; iflt after; ldc 1; ireturn; after.set!; ldc 2; ireturn}
185
+ assert_equal 2, try(Java::int) {after = label; ldc 1; ifgt after; ldc 1; ireturn; after.set!; ldc 2; ireturn}
186
+ assert_equal 2, try(Java::int) {after = label; aconst_null; ifnull after; ldc 1; ireturn; after.set!; ldc 2; ireturn}
187
+ assert_equal 2, try(Java::int) {after = label; getstatic System, 'out', java.io.PrintStream; ifnonnull after; ldc 1; ireturn; after.set!; ldc 2; ireturn}
188
+ assert_equal 2, try(Java::int) {after = label; aconst_null; aconst_null; if_acmpeq after; ldc 1; ireturn; after.set!; ldc 2; ireturn}
189
+ assert_equal 2, try(Java::int) {after = label; aconst_null; getstatic System, 'out', java.io.PrintStream; if_acmpne after; ldc 1; ireturn; after.set!; ldc 2; ireturn}
190
+ assert_equal 2, try(Java::int) {after = label; ldc 1; ldc 2; if_icmplt after; ldc 1; ireturn; after.set!; ldc 2; ireturn}
191
+ assert_equal 2, try(Java::int) {after = label; ldc 1; ldc 1; if_icmple after; ldc 1; ireturn; after.set!; ldc 2; ireturn}
192
+ assert_equal 2, try(Java::int) {after = label; ldc 2; ldc 1; if_icmpgt after; ldc 1; ireturn; after.set!; ldc 2; ireturn}
193
+ assert_equal 2, try(Java::int) {after = label; ldc 2; ldc 2; if_icmpge after; ldc 1; ireturn; after.set!; ldc 2; ireturn}
194
+ # TODO: jsr and ret
195
+ end
196
+
197
+ def test_multianewaray
198
+ # TODO
199
+ end
200
+
201
+ def test_switches
202
+ assert_equal 3, try(Java::int) {
203
+ one, two, three, four, default = label, label, label, label, label
204
+ ldc 3
205
+ lookupswitch default, [1,2,3,4], [one, two, three, four]
206
+ one.set!; ldc 1; ireturn
207
+ two.set!; ldc 2; ireturn
208
+ three.set!; ldc 3; ireturn
209
+ four.set!; ldc 4; ireturn
210
+ default.set!; ldc 0; ireturn
211
+ }
212
+ assert_equal 3, try(Java::int) {
213
+ one, two, three, four, default = label, label, label, label, label
214
+ ldc 3
215
+ tableswitch 1, 4, default, [one, two, three, four]
216
+ one.set!; ldc 1; ireturn
217
+ two.set!; ldc 2; ireturn
218
+ three.set!; ldc 3; ireturn
219
+ four.set!; ldc 4; ireturn
220
+ default.set!; ldc 0; ireturn
221
+ }
222
+ end
223
+
224
+ def test_casts
225
+ assert_equal 1.0, try(Java::float) {ldc 1; i2f; freturn}
226
+ assert_equal 1, try(Java::int) {ldc_float 1.0; f2i; ireturn}
227
+
228
+ assert_equal 1.0, try(Java::double) {ldc 1; i2d; dreturn}
229
+ assert_equal 1, try(Java::int) {ldc 1.0; d2i; ireturn}
230
+
231
+ assert_equal -1, try(Java::int) {ldc_long java.lang.Long::MAX_VALUE; l2i; ireturn}
232
+ assert_equal 2147483648, try(Java::long) {ldc java.lang.Integer::MAX_VALUE; i2l; ldc_long 1; ladd; lreturn}
233
+
234
+ assert_equal 9.223372036854776e+18, try(Java::float) {ldc_long java.lang.Long::MAX_VALUE; l2f; freturn}
235
+ assert_equal -9223372036854775808, try(Java::long) {ldc_float java.lang.Float::MAX_VALUE; f2l; ldc_long 1; ladd; lreturn}
236
+
237
+ assert_equal 9.223372036854776e+18, try(Java::double) {ldc_long java.lang.Long::MAX_VALUE; l2d; dreturn}
238
+ assert_equal -9223372036854775808, try(Java::long) {ldc java.lang.Double::MAX_VALUE; d2l; ldc_long 1; ladd; lreturn}
239
+ end
240
+
241
+ def test_locals
242
+ assert_equal true, try(Java::boolean) {ldc true; istore 0; iload 0; ireturn}
243
+ assert_equal 1, try(Java::int) {ldc 1; istore 0; iload 0; ireturn}
244
+ assert_equal 1, try(Java::long) {ldc_long 1; lstore 0; lload 0; lreturn}
245
+ assert_equal 1.0, try(Java::float) {ldc_float 1.0; fstore 0; fload 0; freturn}
246
+ assert_equal 1.0, try(Java::double) {ldc_double 1.0; dstore 0; dload 0; dreturn}
247
+ assert_equal 'foo', try(JString) {ldc 'foo'; astore 0; aload 0; areturn}
248
+ end
249
+
250
+ def test_instance_method_this
251
+ cb = @builder.public_class(@class_name, @builder.object);
252
+ method = cb.public_method("foo", cb.this) {aload local 'this'; areturn}
253
+
254
+ # ensure "this" is taking slot zero
255
+ method.local('another')
256
+ assert_equal(method.local('this'), 0)
257
+ assert_equal(method.local('another'), 1)
258
+
259
+ dummy_constructor(cb)
260
+ obj = load_and_construct(@class_name, cb)
261
+
262
+ assert_equal(obj, obj.foo)
263
+ end
264
+
265
+ def test_constructor_this
266
+ cb = @builder.public_class(@class_name, @builder.object);
267
+ cb.private_field "self", cb.this
268
+ constructor = cb.public_constructor do
269
+ aload 0
270
+ dup
271
+ invokespecial object, "<init>", [void]
272
+ dup
273
+ putfield this, "self", this
274
+ returnvoid
275
+ end
276
+
277
+ cb.public_method "get_self", cb.this do
278
+ aload 0
279
+ getfield this, "self", this
280
+ areturn
281
+ end
282
+
283
+ # ensure "this" is taking slot zero
284
+ constructor.local('another')
285
+ assert_equal(constructor.local('this'), 0)
286
+ assert_equal(constructor.local('another'), 1)
287
+
288
+ obj = load_and_construct(@class_name, cb)
289
+ assert_equal(obj, obj.get_self)
290
+ end
291
+
292
+ def test_native_method
293
+ cb = @builder.public_class(@class_name, @builder.object);
294
+
295
+ body_called = false
296
+ cb.public_native_method("yoohoo") {body_called = true}
297
+
298
+ assert !body_called
299
+
300
+ dummy_constructor(cb)
301
+ obj = load_and_construct(@class_name, cb);
302
+
303
+ # expect NativeException (UnsatisfiedLinkError)
304
+ assert_raises(NativeException) {obj.yoohoo}
305
+ end
306
+
307
+ def test_fields
308
+ cb = @builder.public_class(@class_name, @builder.object);
309
+
310
+ cb.public_field('inst_field', JString)
311
+ cb.public_static_field('static_field', JString)
312
+
313
+ cb.public_method('set_inst', cb.void) {aload 0; ldc 'instance'; putfield this, 'inst_field', JString; returnvoid}
314
+ cb.public_method('set_static', cb.void) {ldc 'static'; putstatic this, 'static_field', JString; returnvoid}
315
+ cb.public_method('get_inst', JString) {aload 0; getfield this, 'inst_field', JString; areturn}
316
+ cb.public_method('get_static', JString) {getstatic this, 'static_field', JString; areturn}
317
+
318
+ dummy_constructor(cb)
319
+ obj = load_and_construct(@class_name, cb);
320
+
321
+ assert_equal nil, obj.get_inst
322
+ assert_equal nil, obj.get_static
323
+ obj.set_inst
324
+ obj.set_static
325
+ assert_equal 'instance', obj.get_inst
326
+ assert_equal 'static', obj.get_static
327
+ end
328
+
329
+ def test_arrays
330
+ cb = @builder.public_class(@class_name, @builder.object);
331
+
332
+ cb.public_method("newbooleanarray", cb.boolean[]) {ldc 5; newbooleanarray; dup; ldc 1; ldc true; bastore; dup; dup; ldc 2; swap; ldc 1; baload; bastore; areturn}
333
+ cb.public_method("newbytearray", cb.byte[]) {ldc 5; newbytearray; dup; ldc 1; ldc 1; bastore; dup; dup; ldc 2; swap; ldc 1; baload; bastore; areturn}
334
+ cb.public_method("newshortarray", cb.short[]) {ldc 5; newshortarray; dup; ldc 1; ldc 1; sastore; dup; dup; ldc 2; swap; ldc 1; saload; sastore; areturn}
335
+ cb.public_method("newchararray", cb.char[]) {ldc 5; newchararray; dup; ldc 1; ldc 1; castore; dup; dup; ldc 2; swap; ldc 1; caload; castore; areturn}
336
+ cb.public_method("newintarray", cb.int[]) {ldc 5; newintarray; dup; ldc 1; ldc 1; iastore; dup; dup; ldc 2; swap; ldc 1; iaload; iastore; areturn}
337
+ cb.public_method("newlongarray", cb.long[]) {ldc 5; newlongarray; dup; ldc 1; ldc_long 1; lastore; dup; dup; ldc 2; swap; ldc 1; laload; lastore; areturn}
338
+ cb.public_method("newfloatarray", cb.float[]) {ldc 5; newfloatarray; dup; ldc 1; ldc_float 1.0; fastore; dup; dup; ldc 2; swap; ldc 1; faload; fastore; areturn}
339
+ cb.public_method("newdoublearray", cb.double[]) {ldc 5; newdoublearray; dup; ldc 1; ldc 1.0; dastore; dup; dup; ldc 2; swap; ldc 1; daload; dastore; areturn}
340
+ cb.public_method("anewarray", cb.string[]) {ldc 5; anewarray JString; dup; ldc 1; ldc 'foo'; aastore; dup; dup; ldc 2; swap; ldc 1; aaload; aastore; areturn}
341
+
342
+ dummy_constructor(cb)
343
+ obj = load_and_construct(@class_name, cb);
344
+
345
+ ary = obj.newbooleanarray
346
+ assert_equal(Java::boolean.java_class, ary.class.java_class.component_type)
347
+ assert_equal(5, ary.size)
348
+ assert_equal([false,true,true,false,false], ary.to_a)
349
+
350
+ ary = obj.newbytearray
351
+ assert_equal(Java::byte.java_class, ary.class.java_class.component_type)
352
+ assert_equal(5, ary.size)
353
+ assert_equal([0,1,1,0,0], ary.to_a)
354
+
355
+ ary = obj.newshortarray
356
+ assert_equal(Java::short.java_class, ary.class.java_class.component_type)
357
+ assert_equal(5, ary.size)
358
+ assert_equal([0,1,1,0,0], ary.to_a)
359
+
360
+ ary = obj.newchararray
361
+ assert_equal(Java::char.java_class, ary.class.java_class.component_type)
362
+ assert_equal(5, ary.size)
363
+ assert_equal([0,1,1,0,0], ary.to_a)
364
+
365
+ ary = obj.newintarray
366
+ assert_equal(Java::int.java_class, ary.class.java_class.component_type)
367
+ assert_equal(5, ary.size)
368
+ assert_equal([0,1,1,0,0], ary.to_a)
369
+
370
+ ary = obj.newlongarray
371
+ assert_equal(Java::long.java_class, ary.class.java_class.component_type)
372
+ assert_equal(5, ary.size)
373
+ assert_equal([0,1,1,0,0], ary.to_a)
374
+
375
+ ary = obj.newfloatarray
376
+ assert_equal(Java::float.java_class, ary.class.java_class.component_type)
377
+ assert_equal(5, ary.size)
378
+ assert_equal([0.0,1.0,1.0,0.0,0.0], ary.to_a)
379
+
380
+ ary = obj.newdoublearray
381
+ assert_equal(Java::double.java_class, ary.class.java_class.component_type)
382
+ assert_equal(5, ary.size)
383
+ assert_equal([0.0,1.0,1.0,0.0,0.0], ary.to_a)
384
+
385
+ ary = obj.anewarray
386
+ assert_equal(java.lang.String.java_class, ary.class.java_class.component_type)
387
+ assert_equal(5, ary.size)
388
+ assert_equal([nil,'foo','foo',nil,nil], ary.to_a)
389
+
390
+ assert_equal 5, try(Java::int) {ldc 5; newintarray; arraylength; ireturn}
391
+ end
392
+
393
+ def test_static_init
394
+ cb = @builder.public_class(@class_name, @builder.object);
395
+
396
+ cb.public_static_field('static_field', JString)
397
+ cb.static_init {ldc "hello world"; putstatic this, "static_field", string; returnvoid}
398
+
399
+ dummy_constructor(cb)
400
+ obj = load_and_construct(@class_name, cb);
401
+
402
+ assert_equal("hello world", obj.class.static_field)
403
+ end
404
+
405
+ def test_annotation
406
+ cb = @builder.public_class(@class_name, @builder.object);
407
+
408
+ cb.public_method("annotated", cb.void) do
409
+ annotate(JRubyMethod, true) do |anno|
410
+ anno.name = ["foo"]
411
+ anno.required = 1
412
+ anno.optional = 1
413
+ anno.rest = true
414
+ anno.meta = true
415
+ anno.module = true
416
+ anno.frame = true
417
+ anno.scope = true
418
+ end
419
+ returnvoid
420
+ end
421
+
422
+ dummy_constructor(cb)
423
+ obj = load_and_construct(@class_name, cb);
424
+
425
+ method = obj.class.java_class.declared_method("annotated")
426
+ anno = method.annotation(JRubyMethod.java_class)
427
+ assert anno
428
+ end
429
+ end