bitescript 0.0.3 → 0.0.4

Sign up to get free protection for your applications and to get access to all the features.
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