bitescript 0.0.3 → 0.0.4
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.
- data/History.txt +20 -0
- data/lib/bitescript/builder.rb +84 -27
- data/lib/bitescript/bytecode.rb +10 -1
- data/lib/bitescript/signature.rb +5 -3
- data/lib/bitescript.rb +1 -1
- metadata +80 -80
data/History.txt
CHANGED
@@ -1,3 +1,23 @@
|
|
1
|
+
=== 0.0.4 / 2009-10-27
|
2
|
+
|
3
|
+
* Multiple improvements to support Duby (thanks to Ryan Brown!):
|
4
|
+
* Add support for shadowing local variables
|
5
|
+
* Interface and "throws" support.
|
6
|
+
* Add an accessor for ClassBuilder.interfaces
|
7
|
+
* ignore nil line numbers
|
8
|
+
* Fix typo in line numbering
|
9
|
+
* Improve debug info support
|
10
|
+
* Fix class.stop to generate a valid constructor when one is not defined.
|
11
|
+
* Fix void comparison bugs
|
12
|
+
* Fix string concat
|
13
|
+
* Allow custom classes to represent primitive types
|
14
|
+
* Add support for big locals (long/double)
|
15
|
+
* Add a static? accessor to MethodBuilder.
|
16
|
+
|
17
|
+
=== 0.0.3 / 2009-06-14
|
18
|
+
|
19
|
+
* Support for Java 1.7 and invokedynamic
|
20
|
+
|
1
21
|
=== 0.0.2 / 2009-05-14
|
2
22
|
|
3
23
|
* Improve use support for packages, make it more API-friendly
|
data/lib/bitescript/builder.rb
CHANGED
@@ -114,6 +114,10 @@ module BiteScript
|
|
114
114
|
define_class(class_name, :visibility => :public, :superclass => superclass, :interfaces => interfaces, &block)
|
115
115
|
end
|
116
116
|
|
117
|
+
def public_interface(class_name, *interfaces, &block)
|
118
|
+
define_class(class_name, :visibility => :public, :interface => true, :interfaces => interfaces, &block)
|
119
|
+
end
|
120
|
+
|
117
121
|
def protected_class(class_name, superclass = java.lang.Object, *interfaces, &block)
|
118
122
|
define_class(class_name, :visibility => :protected, :superclass => superclass, :interfaces => interfaces, &block)
|
119
123
|
end
|
@@ -188,16 +192,23 @@ module BiteScript
|
|
188
192
|
attr_accessor :methods
|
189
193
|
attr_accessor :imports
|
190
194
|
attr_accessor :fields
|
195
|
+
attr_accessor :interfaces
|
191
196
|
|
192
197
|
def initialize(file_builder, class_name, file_name, opts)
|
193
198
|
@parent = file_builder
|
194
199
|
@class_name = class_name
|
195
200
|
@superclass = opts[:superclass] || Object
|
201
|
+
@interfaces = opts[:interfaces] || []
|
202
|
+
@interface = opts[:interface]
|
203
|
+
flags = Opcodes::ACC_SUPER
|
204
|
+
if @interface
|
205
|
+
flags |= Opcodes::ACC_INTERFACE | Opcodes::ACC_ABSTRACT
|
206
|
+
end
|
196
207
|
|
197
208
|
@class_writer = ClassWriter.new(ClassWriter::COMPUTE_MAXS)
|
198
209
|
|
199
210
|
interface_paths = []
|
200
|
-
(
|
211
|
+
(@interfaces).each {|interface| interface_paths << path(interface)}
|
201
212
|
|
202
213
|
visibility = case (opts[:visibility] && opts[:visibility].to_sym)
|
203
214
|
when nil
|
@@ -214,7 +225,7 @@ module BiteScript
|
|
214
225
|
raise "Unknown visibility: #{opts[:visibility]}"
|
215
226
|
end
|
216
227
|
|
217
|
-
@class_writer.visit(BiteScript.bytecode_version, visibility |
|
228
|
+
@class_writer.visit(BiteScript.bytecode_version, visibility | flags, class_name, nil, path(superclass), interface_paths.to_java(:string))
|
218
229
|
@class_writer.visit_source(file_name, nil)
|
219
230
|
|
220
231
|
@constructor = nil
|
@@ -231,11 +242,11 @@ module BiteScript
|
|
231
242
|
|
232
243
|
def stop
|
233
244
|
# if we haven't seen a constructor, generate a default one
|
234
|
-
unless @constructor
|
235
|
-
method =
|
245
|
+
unless @constructor || @interface
|
246
|
+
method = public_constructor([])
|
236
247
|
method.start
|
237
248
|
method.aload 0
|
238
|
-
method.invokespecial @superclass, "<init>", Void::TYPE
|
249
|
+
method.invokespecial @superclass, "<init>", [Void::TYPE]
|
239
250
|
method.returnvoid
|
240
251
|
method.stop
|
241
252
|
end
|
@@ -260,26 +271,26 @@ module BiteScript
|
|
260
271
|
", binding, __FILE__, __LINE__
|
261
272
|
# instance methods; also defines a "this" local at index 0
|
262
273
|
eval "
|
263
|
-
def #{modifier}_method(name, *signature, &block)
|
264
|
-
method(Opcodes::ACC_#{modifier.upcase}, name, signature, &block)
|
274
|
+
def #{modifier}_method(name, exceptions, *signature, &block)
|
275
|
+
method(Opcodes::ACC_#{modifier.upcase}, name, signature, exceptions, &block)
|
265
276
|
end
|
266
277
|
", binding, __FILE__, __LINE__
|
267
278
|
# static methods
|
268
279
|
eval "
|
269
|
-
def #{modifier}_static_method(name, *signature, &block)
|
270
|
-
method(Opcodes::ACC_STATIC | Opcodes::ACC_#{modifier.upcase}, name, signature, &block)
|
280
|
+
def #{modifier}_static_method(name, exceptions, *signature, &block)
|
281
|
+
method(Opcodes::ACC_STATIC | Opcodes::ACC_#{modifier.upcase}, name, signature, exceptions, &block)
|
271
282
|
end
|
272
283
|
", binding, __FILE__, __LINE__
|
273
284
|
# native methods
|
274
285
|
eval "
|
275
|
-
def #{modifier}_native_method(name, *signature)
|
276
|
-
method(Opcodes::ACC_NATIVE | Opcodes::ACC_#{modifier.upcase}, name, signature)
|
286
|
+
def #{modifier}_native_method(name, exceptions, *signature)
|
287
|
+
method(Opcodes::ACC_NATIVE | Opcodes::ACC_#{modifier.upcase}, name, signature, exceptions)
|
277
288
|
end
|
278
289
|
", binding, __FILE__, __LINE__
|
279
290
|
# constructors; also defines a "this" local at index 0
|
280
291
|
eval "
|
281
|
-
def #{modifier}_constructor(*signature, &block)
|
282
|
-
method(Opcodes::ACC_#{modifier.upcase}, \"<init>\", [nil, *signature], &block)
|
292
|
+
def #{modifier}_constructor(exceptions, *signature, &block)
|
293
|
+
@constructor = method(Opcodes::ACC_#{modifier.upcase}, \"<init>\", [nil, *signature], exceptions, &block)
|
283
294
|
end
|
284
295
|
", binding, __FILE__, __LINE__
|
285
296
|
end
|
@@ -288,8 +299,9 @@ module BiteScript
|
|
288
299
|
method(Opcodes::ACC_STATIC, "<clinit>", [void], &block)
|
289
300
|
end
|
290
301
|
|
291
|
-
def method(flags, name, signature, &block)
|
292
|
-
|
302
|
+
def method(flags, name, signature, exceptions, &block)
|
303
|
+
flags |= Opcodes::ACC_ABSTRACT if interface?
|
304
|
+
mb = MethodBuilder.new(self, flags, name, exceptions, signature)
|
293
305
|
|
294
306
|
if name == "<init>"
|
295
307
|
constructors[signature[1..-1]] = mb
|
@@ -299,9 +311,9 @@ module BiteScript
|
|
299
311
|
end
|
300
312
|
|
301
313
|
# non-static methods reserve index 0 for 'this'
|
302
|
-
mb.local 'this' if (flags & Opcodes::ACC_STATIC) == 0
|
314
|
+
mb.local 'this', self if (flags & Opcodes::ACC_STATIC) == 0
|
303
315
|
|
304
|
-
if block_given?
|
316
|
+
if block_given? && !interface?
|
305
317
|
mb.start
|
306
318
|
if block.arity == 1
|
307
319
|
block.call(mb)
|
@@ -325,7 +337,7 @@ module BiteScript
|
|
325
337
|
def main(&b)
|
326
338
|
raise "already defined main" if methods[name]
|
327
339
|
|
328
|
-
public_static_method "main", void, string[], &b
|
340
|
+
public_static_method "main", [], void, string[], &b
|
329
341
|
end
|
330
342
|
|
331
343
|
def constructor(*params)
|
@@ -334,7 +346,7 @@ module BiteScript
|
|
334
346
|
|
335
347
|
def interface?
|
336
348
|
# TODO: interface types
|
337
|
-
|
349
|
+
@interface
|
338
350
|
end
|
339
351
|
|
340
352
|
def field(flags, name, type)
|
@@ -360,8 +372,11 @@ module BiteScript
|
|
360
372
|
self
|
361
373
|
end
|
362
374
|
|
363
|
-
def new_method(modifiers, name, signature)
|
364
|
-
|
375
|
+
def new_method(modifiers, name, signature, exceptions)
|
376
|
+
exceptions ||= []
|
377
|
+
raise ArgumentError unless exceptions.kind_of?(Array)
|
378
|
+
exceptions = exceptions.map {|e| path(e)}
|
379
|
+
@class_writer.visit_method(modifiers, name, sig(*signature), nil, exceptions.to_java(:string))
|
365
380
|
end
|
366
381
|
|
367
382
|
def macro(name, &b)
|
@@ -381,21 +396,26 @@ module BiteScript
|
|
381
396
|
|
382
397
|
attr_reader :method_visitor
|
383
398
|
attr_reader :static
|
399
|
+
alias :static? :static
|
384
400
|
attr_reader :signature
|
385
401
|
attr_reader :name
|
386
402
|
attr_reader :class_builder
|
387
403
|
|
388
|
-
def initialize(class_builder, modifiers, name, signature)
|
404
|
+
def initialize(class_builder, modifiers, name, exceptions, signature)
|
389
405
|
@class_builder = class_builder
|
390
406
|
@modifiers = modifiers
|
391
407
|
@name = name
|
392
408
|
@signature = signature
|
393
409
|
|
394
|
-
@method_visitor = class_builder.new_method(modifiers, name, signature)
|
410
|
+
@method_visitor = class_builder.new_method(modifiers, name, signature, exceptions)
|
395
411
|
|
396
412
|
@locals = {}
|
413
|
+
@next_local = 0
|
397
414
|
|
398
415
|
@static = (modifiers & Opcodes::ACC_STATIC) != 0
|
416
|
+
@start_label = labels[:start] = self.label
|
417
|
+
@end_label = labels[:end] = self.label
|
418
|
+
@exceptions = exceptions || []
|
399
419
|
end
|
400
420
|
|
401
421
|
def parameter_types
|
@@ -438,17 +458,54 @@ module BiteScript
|
|
438
458
|
@class_builder
|
439
459
|
end
|
440
460
|
|
441
|
-
def local(name)
|
461
|
+
def local(name, type)
|
442
462
|
if name == "this" && @static
|
443
463
|
raise "'this' attempted to load from static method"
|
444
464
|
end
|
445
465
|
|
446
466
|
if @locals[name]
|
447
|
-
|
467
|
+
return @locals[name][-1][0]
|
468
|
+
else
|
469
|
+
return push_local(name, type, @start_label)
|
470
|
+
end
|
471
|
+
end
|
472
|
+
|
473
|
+
def push_local(name, type, start=nil)
|
474
|
+
start ||= self.label.set!
|
475
|
+
type = ci(type)
|
476
|
+
big = "JD".include? type
|
477
|
+
match = @locals[name].find {|local| !big || local[1]} if @locals[name]
|
478
|
+
if match
|
479
|
+
index = match[0]
|
480
|
+
else
|
481
|
+
index = @next_local
|
482
|
+
@next_local += 1
|
483
|
+
@next_local += 1 if big
|
484
|
+
end
|
485
|
+
|
486
|
+
if @locals[name] && @locals[name].size > 0
|
487
|
+
local_debug_info(name, @locals[name][-1])
|
448
488
|
else
|
449
|
-
|
489
|
+
@locals[name] = []
|
450
490
|
end
|
451
|
-
|
491
|
+
@locals[name] << [index, big, type, start]
|
492
|
+
index
|
493
|
+
end
|
494
|
+
|
495
|
+
def local_debug_info(name, local, end_label=nil)
|
496
|
+
return unless local
|
497
|
+
index, big, type, start = local
|
498
|
+
end_label ||= self.label.set!
|
499
|
+
method_visitor.visit_local_variable(name, type, nil,
|
500
|
+
start.label,
|
501
|
+
end_label.label,
|
502
|
+
index)
|
503
|
+
end
|
504
|
+
|
505
|
+
def pop_local(name)
|
506
|
+
here = self.label.set!
|
507
|
+
local_debug_info(name, @locals[name].pop, here)
|
508
|
+
@locals[name][-1][-1] = here if @locals[name].size > 0
|
452
509
|
end
|
453
510
|
|
454
511
|
def annotate(cls, runtime = false)
|
data/lib/bitescript/bytecode.rb
CHANGED
@@ -319,9 +319,14 @@ module BiteScript
|
|
319
319
|
|
320
320
|
def start
|
321
321
|
method_visitor.visit_code
|
322
|
+
@start_label.set!
|
322
323
|
end
|
323
324
|
|
324
325
|
def stop
|
326
|
+
@end_label.set!
|
327
|
+
@locals.each do |name, locals|
|
328
|
+
local_debug_info(name, locals[-1], @end_label)
|
329
|
+
end
|
325
330
|
method_visitor.visit_maxs(1,1)
|
326
331
|
method_visitor.visit_end
|
327
332
|
end
|
@@ -344,6 +349,7 @@ module BiteScript
|
|
344
349
|
|
345
350
|
def set!
|
346
351
|
@method_visitor.visit_label(@label)
|
352
|
+
self
|
347
353
|
end
|
348
354
|
end
|
349
355
|
|
@@ -385,7 +391,10 @@ module BiteScript
|
|
385
391
|
end
|
386
392
|
|
387
393
|
def line(num)
|
388
|
-
|
394
|
+
if num && num != @line_num
|
395
|
+
method_visitor.visit_line_number(num, label.set!.label)
|
396
|
+
end
|
397
|
+
@line_num = num
|
389
398
|
end
|
390
399
|
|
391
400
|
def push_int(num)
|
data/lib/bitescript/signature.rb
CHANGED
@@ -35,7 +35,7 @@ module BiteScript
|
|
35
35
|
def class_id(cls)
|
36
36
|
cls = cls.java_class if Class === cls
|
37
37
|
|
38
|
-
if !cls || cls == java.lang.Void ||
|
38
|
+
if !cls || cls == java.lang.Void.java_class || Java::void == cls
|
39
39
|
return "V"
|
40
40
|
end
|
41
41
|
|
@@ -46,6 +46,7 @@ module BiteScript
|
|
46
46
|
if cls.array?
|
47
47
|
cls = cls.component_type
|
48
48
|
if cls.primitive?
|
49
|
+
cls = cls.primitive_type if cls.respond_to? :primitive_type
|
49
50
|
case cls
|
50
51
|
when JavaTypes::Byte::TYPE
|
51
52
|
return "[B"
|
@@ -64,13 +65,14 @@ module BiteScript
|
|
64
65
|
when JavaTypes::Double::TYPE
|
65
66
|
return "[D"
|
66
67
|
else
|
67
|
-
raise "Unknown type in compiler:
|
68
|
+
raise "Unknown type in compiler: #{cls.name}"
|
68
69
|
end
|
69
70
|
else
|
70
71
|
return "[#{class_id(cls)}"
|
71
72
|
end
|
72
73
|
else
|
73
74
|
if cls.primitive?
|
75
|
+
cls = cls.primitive_type if cls.respond_to? :primitive_type
|
74
76
|
case cls
|
75
77
|
when JavaTypes::Byte::TYPE
|
76
78
|
return "B"
|
@@ -91,7 +93,7 @@ module BiteScript
|
|
91
93
|
when JavaTypes::Void::TYPE, java.lang.Void
|
92
94
|
return "V"
|
93
95
|
else
|
94
|
-
raise "Unknown type in compiler:
|
96
|
+
raise "Unknown type in compiler: #{cls.name}"
|
95
97
|
end
|
96
98
|
else
|
97
99
|
return "L#{path(cls)};"
|
data/lib/bitescript.rb
CHANGED
metadata
CHANGED
@@ -1,93 +1,93 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
|
-
|
3
|
-
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
2
|
+
name: bitescript
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.0.4
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- charles.nutter@sun.comCharles Oliver Nutter
|
8
|
+
autorequire:
|
9
|
+
bindir: bin
|
10
10
|
cert_chain: []
|
11
11
|
|
12
|
-
|
13
|
-
|
12
|
+
date: 2009-10-27 00:00:00 -05:00
|
13
|
+
default_executable:
|
14
|
+
dependencies:
|
15
|
+
- !ruby/object:Gem::Dependency
|
16
|
+
name: hoe
|
17
|
+
type: :development
|
18
|
+
version_requirement:
|
19
|
+
version_requirements: !ruby/object:Gem::Requirement
|
20
|
+
requirements:
|
21
|
+
- - ">="
|
22
|
+
- !ruby/object:Gem::Version
|
23
|
+
version: 2.3.3
|
24
|
+
version:
|
25
|
+
description: BiteScript is a Ruby DSL for generating Java bytecode and classes.
|
26
|
+
email:
|
27
|
+
- charles.nutter@sun.com
|
28
|
+
executables:
|
29
|
+
- bite
|
30
|
+
- bitec
|
31
|
+
extensions: []
|
32
|
+
|
14
33
|
extra_rdoc_files:
|
15
|
-
- History.txt
|
16
|
-
- LICENSE.txt
|
17
|
-
- Manifest.txt
|
18
|
-
- README.txt
|
34
|
+
- History.txt
|
35
|
+
- LICENSE.txt
|
36
|
+
- Manifest.txt
|
37
|
+
- README.txt
|
38
|
+
files:
|
39
|
+
- History.txt
|
40
|
+
- LICENSE.txt
|
41
|
+
- Manifest.txt
|
42
|
+
- README.txt
|
43
|
+
- Rakefile
|
44
|
+
- bin/bite
|
45
|
+
- bin/bitec
|
46
|
+
- examples/fib.bs
|
47
|
+
- examples/mixed_bag.rb
|
48
|
+
- examples/simple_loop.rb
|
49
|
+
- lib/bitescript.rb
|
50
|
+
- lib/bitescript/asm.rb
|
51
|
+
- lib/bitescript/builder.rb
|
52
|
+
- lib/bitescript/bytecode.rb
|
53
|
+
- lib/bitescript/signature.rb
|
54
|
+
- test/test_bitescript.rb
|
55
|
+
- test/test_builder.rb
|
56
|
+
- test/test_bytecode.rb
|
57
|
+
- test/test_java_class.rb
|
58
|
+
- test/test_signature.rb
|
59
|
+
has_rdoc: true
|
19
60
|
homepage: http://kenai.com/projects/jvmscript
|
20
|
-
signing_key:
|
21
|
-
name: bitescript
|
22
|
-
rdoc_options:
|
23
|
-
- --main
|
24
|
-
- README.txt
|
25
|
-
rubyforge_project: jruby-extras
|
26
|
-
autorequire:
|
27
61
|
licenses: []
|
28
62
|
|
29
|
-
|
30
|
-
|
31
|
-
-
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
-
|
38
|
-
-
|
39
|
-
|
40
|
-
|
41
|
-
- bin/bite
|
42
|
-
- bin/bitec
|
43
|
-
- examples/fib.bs
|
44
|
-
- examples/mixed_bag.rb
|
45
|
-
- examples/simple_loop.rb
|
46
|
-
- lib/bitescript.rb
|
47
|
-
- lib/bitescript/asm.rb
|
48
|
-
- lib/bitescript/builder.rb
|
49
|
-
- lib/bitescript/bytecode.rb
|
50
|
-
- lib/bitescript/signature.rb
|
51
|
-
- test/test_bitescript.rb
|
52
|
-
- test/test_builder.rb
|
53
|
-
- test/test_bytecode.rb
|
54
|
-
- test/test_java_class.rb
|
55
|
-
- test/test_signature.rb
|
63
|
+
post_install_message:
|
64
|
+
rdoc_options:
|
65
|
+
- --main
|
66
|
+
- README.txt
|
67
|
+
require_paths:
|
68
|
+
- lib
|
69
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
70
|
+
requirements:
|
71
|
+
- - ">="
|
72
|
+
- !ruby/object:Gem::Version
|
73
|
+
version: "0"
|
74
|
+
version:
|
56
75
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
57
76
|
requirements:
|
58
|
-
|
59
|
-
|
60
|
-
|
77
|
+
- - ">="
|
78
|
+
- !ruby/object:Gem::Version
|
79
|
+
version: "0"
|
61
80
|
version:
|
62
|
-
extensions: []
|
63
|
-
|
64
|
-
rubygems_version: 1.3.3
|
65
81
|
requirements: []
|
66
82
|
|
67
|
-
|
68
|
-
|
69
|
-
|
70
|
-
|
83
|
+
rubyforge_project: jruby-extras
|
84
|
+
rubygems_version: 1.3.5
|
85
|
+
signing_key:
|
86
|
+
specification_version: 3
|
87
|
+
summary: BiteScript is a Ruby DSL for generating Java bytecode.
|
71
88
|
test_files:
|
72
|
-
- test/test_bitescript.rb
|
73
|
-
- test/test_builder.rb
|
74
|
-
- test/test_bytecode.rb
|
75
|
-
- test/test_java_class.rb
|
76
|
-
- test/test_signature.rb
|
77
|
-
version: !ruby/object:Gem::Version
|
78
|
-
version: 0.0.3
|
79
|
-
require_paths:
|
80
|
-
- lib
|
81
|
-
dependencies:
|
82
|
-
- !ruby/object:Gem::Dependency
|
83
|
-
version_requirements: !ruby/object:Gem::Requirement
|
84
|
-
requirements:
|
85
|
-
- - '>='
|
86
|
-
- !ruby/object:Gem::Version
|
87
|
-
version: 1.12.1
|
88
|
-
version:
|
89
|
-
type: :development
|
90
|
-
version_requirement:
|
91
|
-
name: hoe
|
92
|
-
bindir: bin
|
93
|
-
has_rdoc: true
|
89
|
+
- test/test_bitescript.rb
|
90
|
+
- test/test_builder.rb
|
91
|
+
- test/test_bytecode.rb
|
92
|
+
- test/test_java_class.rb
|
93
|
+
- test/test_signature.rb
|