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 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
@@ -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
- (opts[:interfaces] || []).each {|interface| interface_paths << path(interface)}
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 | Opcodes::ACC_SUPER, class_name, nil, path(superclass), interface_paths.to_java(:string))
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 = MethodBuilder.new(self, Opcodes::ACC_PUBLIC, "<init>", [])
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
- mb = MethodBuilder.new(self, flags, name, signature)
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
- false
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
- @class_writer.visit_method(modifiers, name, sig(*signature), nil, nil)
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
- local_index = @locals[name]
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
- local_index = @locals[name] = @locals.size
489
+ @locals[name] = []
450
490
  end
451
- local_index
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)
@@ -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
- method_visitor.visit_line_number num, ASM::Label.new
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)
@@ -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 || cls == Java::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: " + cls.name
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: " + cls.name
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
@@ -5,7 +5,7 @@ require 'bitescript/bytecode'
5
5
  require 'bitescript/builder'
6
6
 
7
7
  module BiteScript
8
- VERSION = '0.0.3'
8
+ VERSION = '0.0.4'
9
9
 
10
10
  include BiteScript::ASM
11
11
  JAVA1_4 = Opcodes::V1_4
metadata CHANGED
@@ -1,93 +1,93 @@
1
1
  --- !ruby/object:Gem::Specification
2
- required_ruby_version: !ruby/object:Gem::Requirement
3
- requirements:
4
- - - '>='
5
- - !ruby/object:Gem::Version
6
- version: "0"
7
- version:
8
- email:
9
- - charles.nutter@sun.com
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
- summary: BiteScript is a Ruby DSL for generating Java bytecode.
13
- post_install_message:
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
- executables:
30
- - bite
31
- - bitec
32
- description: BiteScript is a Ruby DSL for generating Java bytecode and classes.
33
- specification_version: 3
34
- default_executable:
35
- files:
36
- - History.txt
37
- - LICENSE.txt
38
- - Manifest.txt
39
- - README.txt
40
- - Rakefile
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
- - !ruby/object:Gem::Version
60
- version: "0"
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
- authors:
68
- - charles.nutter@sun.comCharles Oliver Nutter
69
- date: 2009-06-14 05:00:00 +00:00
70
- platform: ruby
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