bitescript 0.0.5 → 0.0.6
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 +6 -0
- data/bin/bitep +13 -0
- data/bitescript.gemspec +1 -1
- data/examples/fib.bs +2 -2
- data/lib/bitescript.rb +1 -0
- data/lib/bitescript/asm.rb +6 -0
- data/lib/bitescript/builder.rb +28 -13
- data/lib/bitescript/bytecode.rb +15 -8
- data/lib/bitescript/mirror.rb +367 -0
- data/lib/bitescript/signature.rb +3 -0
- data/nbproject/private/rake-d.txt +2 -0
- data/test/test_bytecode.rb +62 -2
- metadata +17 -7
- data/nbproject/private/config.properties +0 -0
- data/nbproject/private/private.properties +0 -3
data/History.txt
CHANGED
@@ -1,3 +1,9 @@
|
|
1
|
+
=== 0.0.6 / 2010-06-09
|
2
|
+
|
3
|
+
* Move to a class mirror API rather than loading and walking real classes
|
4
|
+
* Bug fixes for annotations
|
5
|
+
* Allow forward references to labels for easier branch logic
|
6
|
+
|
1
7
|
=== 0.0.5 / 2010-02-04
|
2
8
|
|
3
9
|
* Get tests and examples all working nicely again
|
data/bin/bitep
ADDED
@@ -0,0 +1,13 @@
|
|
1
|
+
#!/usr/bin/env jruby
|
2
|
+
begin
|
3
|
+
require 'bitescript'
|
4
|
+
rescue LoadError
|
5
|
+
$: << File.dirname(File.dirname(__FILE__)) + '/lib'
|
6
|
+
require 'bitescript'
|
7
|
+
end
|
8
|
+
|
9
|
+
file = ARGV[0]
|
10
|
+
|
11
|
+
raise "usage: bitep <class_name>" unless file
|
12
|
+
|
13
|
+
puts BiteScript::ASM::ClassMirror.load(file).inspect
|
data/bitescript.gemspec
CHANGED
@@ -2,7 +2,7 @@
|
|
2
2
|
|
3
3
|
Gem::Specification.new do |s|
|
4
4
|
s.name = %q{bitescript}
|
5
|
-
s.version = "0.0.
|
5
|
+
s.version = "0.0.6"
|
6
6
|
s.authors = ["Charles Oliver Nutter", "Ryan Brown"]
|
7
7
|
s.date = Time.now.strftime('YYYY-MM-DD')
|
8
8
|
s.description = %q{BiteScript is a Ruby DSL for generating Java bytecode and classes.}
|
data/examples/fib.bs
CHANGED
data/lib/bitescript.rb
CHANGED
data/lib/bitescript/asm.rb
CHANGED
@@ -16,6 +16,12 @@ module BiteScript
|
|
16
16
|
end
|
17
17
|
java_import asm_package.Label
|
18
18
|
java_import asm_package.Type
|
19
|
+
java_import asm_package.AnnotationVisitor
|
20
|
+
java_import asm_package.ClassVisitor
|
21
|
+
java_import asm_package.FieldVisitor
|
22
|
+
java_import asm_package.MethodVisitor
|
23
|
+
java_import asm_package.ClassReader
|
19
24
|
java_import asm_package.ClassWriter
|
25
|
+
java_import asm_package.util.CheckClassAdapter
|
20
26
|
end
|
21
27
|
end
|
data/lib/bitescript/builder.rb
CHANGED
@@ -62,24 +62,30 @@ module BiteScript
|
|
62
62
|
module Annotatable
|
63
63
|
java_import "java.lang.annotation.Retention"
|
64
64
|
def annotate(cls, runtime=nil)
|
65
|
-
if Java::JavaClass === cls
|
66
|
-
java_class = cls
|
67
|
-
else
|
68
|
-
java_class = cls.java_class
|
69
|
-
end
|
70
|
-
|
71
65
|
if runtime.nil?
|
72
|
-
retention =
|
73
|
-
return if retention
|
74
|
-
runtime = retention
|
66
|
+
retention = find_retention(cls)
|
67
|
+
return if retention == 'SOURCE'
|
68
|
+
runtime = retention == 'RUNTIME'
|
75
69
|
end
|
76
70
|
|
77
|
-
annotation = visit_annotation(Signature.ci(
|
71
|
+
annotation = visit_annotation(Signature.ci(cls), runtime)
|
78
72
|
annotation.extend AnnotationBuilder
|
79
73
|
|
80
74
|
yield annotation
|
81
75
|
annotation.visit_end
|
82
76
|
end
|
77
|
+
|
78
|
+
def find_retention(cls)
|
79
|
+
if cls.kind_of?(BiteScript::ASM::ClassMirror)
|
80
|
+
retention = cls.getDeclaredAnnotation('java.lang.annotation.Retention')
|
81
|
+
elsif Java::JavaClass === cls
|
82
|
+
retention = cls.annotation(Retention.java_class)
|
83
|
+
else
|
84
|
+
retention = cls.java_class.annotation(Retention.java_class)
|
85
|
+
end
|
86
|
+
return 'CLASS' if retention.nil?
|
87
|
+
return retention.value.name
|
88
|
+
end
|
83
89
|
end
|
84
90
|
|
85
91
|
class FileBuilder
|
@@ -221,8 +227,12 @@ module BiteScript
|
|
221
227
|
if @interface
|
222
228
|
flags = Opcodes::ACC_INTERFACE | Opcodes::ACC_ABSTRACT
|
223
229
|
end
|
224
|
-
|
230
|
+
|
225
231
|
@class_writer = ClassWriter.new(ClassWriter::COMPUTE_MAXS)
|
232
|
+
if ENV['BS_CHECK_CLASSES']
|
233
|
+
@real_class_writer = @class_writer
|
234
|
+
@class_writer = CheckClassAdapter.new(@class_writer)
|
235
|
+
end
|
226
236
|
|
227
237
|
interface_paths = []
|
228
238
|
(@interfaces).each {|interface| interface_paths << path(interface)}
|
@@ -270,7 +280,12 @@ module BiteScript
|
|
270
280
|
end
|
271
281
|
|
272
282
|
def generate
|
273
|
-
|
283
|
+
if ENV['BS_CHECK_CLASSES']
|
284
|
+
class_writer = @real_class_writer
|
285
|
+
else
|
286
|
+
class_writer = @class_writer
|
287
|
+
end
|
288
|
+
String.from_java_bytes(class_writer.to_byte_array)
|
274
289
|
end
|
275
290
|
|
276
291
|
%w[public private protected].each do |modifier|
|
@@ -555,7 +570,7 @@ module BiteScript
|
|
555
570
|
visit k, v
|
556
571
|
end
|
557
572
|
def annotation(name, cls)
|
558
|
-
if Java::JavaClass === cls
|
573
|
+
if Java::JavaClass === cls || BiteScript::ASM::Type === cls
|
559
574
|
java_class = cls
|
560
575
|
else
|
561
576
|
java_class = cls.java_class
|
data/lib/bitescript/bytecode.rb
CHANGED
@@ -345,12 +345,19 @@ module BiteScript
|
|
345
345
|
def initialize(method_visitor)
|
346
346
|
@method_visitor = method_visitor
|
347
347
|
@label = ASM::Label.new
|
348
|
+
@set = false
|
348
349
|
end
|
349
350
|
|
350
351
|
def set!
|
352
|
+
raise "label set twice" if @set
|
353
|
+
@set = true
|
351
354
|
@method_visitor.visit_label(@label)
|
352
355
|
self
|
353
356
|
end
|
357
|
+
|
358
|
+
def set?
|
359
|
+
@set
|
360
|
+
end
|
354
361
|
end
|
355
362
|
|
356
363
|
def labels
|
@@ -358,18 +365,18 @@ module BiteScript
|
|
358
365
|
end
|
359
366
|
|
360
367
|
def sym_to_label(id)
|
361
|
-
lbl = labels[id]
|
368
|
+
lbl = labels[id]
|
369
|
+
unless lbl
|
370
|
+
lbl = labels[id] = label
|
371
|
+
end
|
372
|
+
lbl
|
362
373
|
end
|
363
374
|
|
364
375
|
def label(id = nil)
|
365
376
|
if id
|
366
|
-
|
367
|
-
|
368
|
-
|
369
|
-
end
|
370
|
-
label = labels[id] = SmartLabel.new(method_visitor)
|
371
|
-
label.set!
|
372
|
-
label
|
377
|
+
lbl = sym_to_label(id)
|
378
|
+
lbl.set!
|
379
|
+
lbl
|
373
380
|
else
|
374
381
|
return SmartLabel.new(method_visitor)
|
375
382
|
end
|
@@ -0,0 +1,367 @@
|
|
1
|
+
module BiteScript::ASM
|
2
|
+
class EnumValue
|
3
|
+
attr_reader :declaring_type, :name
|
4
|
+
|
5
|
+
def initialize(declaring_type, name)
|
6
|
+
@declaring_type = declaring_type
|
7
|
+
@name = name
|
8
|
+
end
|
9
|
+
end
|
10
|
+
|
11
|
+
class AnnotationMirror
|
12
|
+
attr_reader :type, :parent
|
13
|
+
def initialize(type, parent=nil)
|
14
|
+
@type = type
|
15
|
+
@parent = parent
|
16
|
+
@values = {}
|
17
|
+
end
|
18
|
+
|
19
|
+
def value
|
20
|
+
@values['value']
|
21
|
+
end
|
22
|
+
|
23
|
+
def value=(value)
|
24
|
+
@values['value'] = value
|
25
|
+
end
|
26
|
+
|
27
|
+
def [](name)
|
28
|
+
@values[name]
|
29
|
+
end
|
30
|
+
|
31
|
+
def []=(name, value)
|
32
|
+
@values[name] = value
|
33
|
+
end
|
34
|
+
|
35
|
+
def inspect
|
36
|
+
unless @values.empty?
|
37
|
+
values = []
|
38
|
+
@values.each do |k, v|
|
39
|
+
values << "#{k}=#{inspect_value(v)}"
|
40
|
+
end
|
41
|
+
values = "(#{values.join ', '})"
|
42
|
+
end
|
43
|
+
"@#{type.class_name}#{values}\n"
|
44
|
+
end
|
45
|
+
|
46
|
+
def inspect_value(v)
|
47
|
+
case v
|
48
|
+
when Type
|
49
|
+
v.class_name + ".class"
|
50
|
+
when Array
|
51
|
+
"{#{v.map{|x| inspect_value(x)}.join(', ')}}"
|
52
|
+
when EnumValue
|
53
|
+
"#{v.declaring_type.class_name}.#{v.name}"
|
54
|
+
else
|
55
|
+
v.inspect
|
56
|
+
end
|
57
|
+
end
|
58
|
+
|
59
|
+
class Builder
|
60
|
+
class ValueArray
|
61
|
+
attr_reader :parent
|
62
|
+
def initialize(annotation, array)
|
63
|
+
@parent = annotation
|
64
|
+
@array = array
|
65
|
+
end
|
66
|
+
|
67
|
+
def []=(name, value)
|
68
|
+
@array << value
|
69
|
+
end
|
70
|
+
end
|
71
|
+
|
72
|
+
include BiteScript::ASM::AnnotationVisitor
|
73
|
+
|
74
|
+
attr_reader :annotation
|
75
|
+
def initialize(desc, visible)
|
76
|
+
@current = @annotation = AnnotationMirror.new(Type.getType(desc))
|
77
|
+
end
|
78
|
+
|
79
|
+
|
80
|
+
def visit(name, value)
|
81
|
+
case value
|
82
|
+
when ArrayJavaProxy
|
83
|
+
visitArray(name)
|
84
|
+
value.each {|x| visit(name, x)}
|
85
|
+
visitEnd
|
86
|
+
else
|
87
|
+
@current[name] = value
|
88
|
+
end
|
89
|
+
end
|
90
|
+
|
91
|
+
def visitAnnotation(name, desc)
|
92
|
+
child = AnnotationMirror.new(Type.getType(desc), @current)
|
93
|
+
@current[name] = child
|
94
|
+
@current = child
|
95
|
+
self
|
96
|
+
end
|
97
|
+
|
98
|
+
def visitArray(name)
|
99
|
+
array = @current[name] = []
|
100
|
+
@current = ValueArray.new(@current, array)
|
101
|
+
self
|
102
|
+
end
|
103
|
+
|
104
|
+
def visitEnum(name, desc, value)
|
105
|
+
@current[name] = EnumValue.new(Type.getType(desc), value)
|
106
|
+
end
|
107
|
+
|
108
|
+
def visitEnd
|
109
|
+
@current = @current.parent
|
110
|
+
end
|
111
|
+
end
|
112
|
+
end
|
113
|
+
|
114
|
+
module Annotated
|
115
|
+
def annotations
|
116
|
+
@annotations ||= {}
|
117
|
+
end
|
118
|
+
|
119
|
+
def addAnnotation(annotation)
|
120
|
+
annotations[annotation.type.class_name] = annotation
|
121
|
+
end
|
122
|
+
|
123
|
+
def getDeclaredAnnotation(name)
|
124
|
+
annotations[name]
|
125
|
+
end
|
126
|
+
|
127
|
+
def declaredAnnotations
|
128
|
+
annotations.values
|
129
|
+
end
|
130
|
+
|
131
|
+
def inspect_annotations
|
132
|
+
declaredAnnotations.map {|a| a.inspect}.join('')
|
133
|
+
end
|
134
|
+
end
|
135
|
+
|
136
|
+
module Modifiers
|
137
|
+
attr_accessor :flags
|
138
|
+
def self.add_modifier(name)
|
139
|
+
class_eval <<-EOF
|
140
|
+
def #{name.downcase}?
|
141
|
+
(flags & Opcodes.ACC_#{name.upcase}) != 0
|
142
|
+
end
|
143
|
+
EOF
|
144
|
+
end
|
145
|
+
%w(annotation bridge deprecated enum interface synthetic).each do |name|
|
146
|
+
add_modifier(name)
|
147
|
+
end
|
148
|
+
code = ''
|
149
|
+
%w(Public Private Protected Final Native Abstract
|
150
|
+
Static Strict Synchronized Transient Volatile).each do |name|
|
151
|
+
add_modifier(name)
|
152
|
+
code << "modifiers << '#{name.downcase} ' if #{name.downcase}?\n"
|
153
|
+
end
|
154
|
+
|
155
|
+
class_eval <<-EOF
|
156
|
+
def modifier_string
|
157
|
+
modifiers = ''
|
158
|
+
#{code}
|
159
|
+
modifiers
|
160
|
+
end
|
161
|
+
EOF
|
162
|
+
end
|
163
|
+
|
164
|
+
class ClassMirror
|
165
|
+
include Annotated
|
166
|
+
include Modifiers
|
167
|
+
|
168
|
+
attr_reader :type, :interfaces
|
169
|
+
attr_accessor :superclass
|
170
|
+
|
171
|
+
def initialize(type, flags)
|
172
|
+
super()
|
173
|
+
@type = type
|
174
|
+
@flags = flags
|
175
|
+
@methods = Hash.new {|h, k| h[k] = {}}
|
176
|
+
@constructors = {}
|
177
|
+
@fields = {}
|
178
|
+
@interfaces = []
|
179
|
+
end
|
180
|
+
|
181
|
+
def self.load(name_or_bytes)
|
182
|
+
builder = BiteScript::ASM::ClassMirror::Builder.new
|
183
|
+
BiteScript::ASM::ClassReader.new(name_or_bytes).accept(builder, 3)
|
184
|
+
builder.mirror
|
185
|
+
end
|
186
|
+
alias for_name load
|
187
|
+
|
188
|
+
def getConstructor(*arg_types)
|
189
|
+
@constructors[arg_types]
|
190
|
+
end
|
191
|
+
|
192
|
+
def getConstructors
|
193
|
+
@constructors.values
|
194
|
+
end
|
195
|
+
|
196
|
+
def addConstructor(constructor)
|
197
|
+
@constructors[constructor.parameters] = constructor
|
198
|
+
end
|
199
|
+
|
200
|
+
def getDeclaredMethod(name, *args)
|
201
|
+
if args[0].kind_of?(Array)
|
202
|
+
args = args[0]
|
203
|
+
end
|
204
|
+
@methods[name][args]
|
205
|
+
end
|
206
|
+
|
207
|
+
def getDeclaredMethods(name=nil)
|
208
|
+
if name
|
209
|
+
@methods[name].values
|
210
|
+
else
|
211
|
+
@methods.values.map {|m| m.values}.flatten
|
212
|
+
end
|
213
|
+
end
|
214
|
+
|
215
|
+
def addMethod(method)
|
216
|
+
# TODO this is a hack to fix resolution of covariant returns.
|
217
|
+
# We should properly support methods that only differ by return type.
|
218
|
+
return if method.synthetic?
|
219
|
+
type_names = method.argument_types.map {|type| type.descriptor}
|
220
|
+
if method.name == '<init>'
|
221
|
+
@constructors[type_names] = method
|
222
|
+
else
|
223
|
+
@methods[method.name][type_names] = method
|
224
|
+
end
|
225
|
+
end
|
226
|
+
|
227
|
+
def getField(name)
|
228
|
+
@fields[name]
|
229
|
+
end
|
230
|
+
|
231
|
+
def getDeclaredFields
|
232
|
+
@fields.values
|
233
|
+
end
|
234
|
+
|
235
|
+
def addField(field)
|
236
|
+
@fields[field.name] = field
|
237
|
+
end
|
238
|
+
|
239
|
+
def inspect
|
240
|
+
if annotation?
|
241
|
+
kind = "@interface"
|
242
|
+
elsif interface?
|
243
|
+
kind = "interface"
|
244
|
+
elsif enum?
|
245
|
+
kind = "enum"
|
246
|
+
else
|
247
|
+
kind = "class"
|
248
|
+
end
|
249
|
+
if superclass && !enum? && !interface?
|
250
|
+
extends = "extends #{superclass.getClassName} "
|
251
|
+
end
|
252
|
+
if self.interfaces && !self.interfaces.empty?
|
253
|
+
interfaces = self.interfaces.map{|i| i.class_name}.join(', ')
|
254
|
+
if interface?
|
255
|
+
extends = "extends #{interfaces} "
|
256
|
+
else
|
257
|
+
implements = "implements #{interfaces} "
|
258
|
+
end
|
259
|
+
end
|
260
|
+
result = "#{inspect_annotations}#{modifier_string}#{kind} "
|
261
|
+
result << "#{type.class_name} #{extends}{\n"
|
262
|
+
(getDeclaredFields + getConstructors + getDeclaredMethods).each do |f|
|
263
|
+
result << f.inspect << "\n"
|
264
|
+
end
|
265
|
+
result << "}"
|
266
|
+
end
|
267
|
+
|
268
|
+
class Builder
|
269
|
+
include BiteScript::ASM::ClassVisitor
|
270
|
+
include BiteScript::ASM::FieldVisitor
|
271
|
+
include BiteScript::ASM::MethodVisitor
|
272
|
+
|
273
|
+
def visit(version, access, name, signature, super_name, interfaces)
|
274
|
+
@current = @class = ClassMirror.new(Type.getObjectType(name), access)
|
275
|
+
@class.superclass = Type.getObjectType(super_name) if super_name
|
276
|
+
if interfaces
|
277
|
+
interfaces.each do |i|
|
278
|
+
@class.interfaces << Type.getObjectType(i)
|
279
|
+
end
|
280
|
+
end
|
281
|
+
end
|
282
|
+
|
283
|
+
def mirror
|
284
|
+
@class
|
285
|
+
end
|
286
|
+
|
287
|
+
def visitSource(source, debug); end
|
288
|
+
def visitOuterClass(owner, name, desc); end
|
289
|
+
def visitAttribute(attribute); end
|
290
|
+
def visitInnerClass(name, outer, inner, access); end
|
291
|
+
def visitEnd; end
|
292
|
+
|
293
|
+
def visitAnnotation(desc, visible)
|
294
|
+
builder = AnnotationMirror::Builder.new(desc, visible)
|
295
|
+
@current.addAnnotation(builder.annotation)
|
296
|
+
builder
|
297
|
+
end
|
298
|
+
|
299
|
+
def visitField(flags, name, desc, signature, value)
|
300
|
+
@current = FieldMirror.new(@class.type, flags, name, Type.getType(desc), value)
|
301
|
+
@class.addField(@current)
|
302
|
+
self
|
303
|
+
end
|
304
|
+
|
305
|
+
def visitMethod(flags, name, desc, signature, exceptions)
|
306
|
+
return_type = Type.getReturnType(desc)
|
307
|
+
parameters = Type.getArgumentTypes(desc).to_a
|
308
|
+
exceptions = (exceptions || []).map {|e| Type.getObjectType(e)}
|
309
|
+
@current = MethodMirror.new(
|
310
|
+
@class.type, flags, return_type, name, parameters, exceptions)
|
311
|
+
@class.addMethod(@current)
|
312
|
+
# TODO parameter annotations, default value, etc.
|
313
|
+
self # This isn't legal is it?
|
314
|
+
end
|
315
|
+
|
316
|
+
def visitAnnotationDefault(*args);end
|
317
|
+
|
318
|
+
def to_s
|
319
|
+
"ClassMirror(#{type.class_name})"
|
320
|
+
end
|
321
|
+
end
|
322
|
+
end
|
323
|
+
|
324
|
+
class FieldMirror
|
325
|
+
include Modifiers
|
326
|
+
include Annotated
|
327
|
+
|
328
|
+
attr_reader :declaring_class, :name, :type, :value
|
329
|
+
def initialize(klass, flags, name, type, value)
|
330
|
+
@declaring_class = klass
|
331
|
+
@flags = flags
|
332
|
+
@name = name
|
333
|
+
@type = type
|
334
|
+
@value = value
|
335
|
+
end
|
336
|
+
|
337
|
+
def inspect
|
338
|
+
inspect_annotations + "#{modifier_string}#{type.getClassName} #{name};"
|
339
|
+
end
|
340
|
+
end
|
341
|
+
|
342
|
+
class MethodMirror
|
343
|
+
include Modifiers
|
344
|
+
include Annotated
|
345
|
+
|
346
|
+
attr_reader :declaring_class, :name, :return_type
|
347
|
+
attr_reader :argument_types, :exception_types
|
348
|
+
def initialize(klass, flags, return_type, name, parameters, exceptions)
|
349
|
+
@flags = flags
|
350
|
+
@declaring_class = klass
|
351
|
+
@name = name
|
352
|
+
@return_type = return_type
|
353
|
+
@argument_types = parameters
|
354
|
+
@exception_types = exceptions
|
355
|
+
end
|
356
|
+
|
357
|
+
def inspect
|
358
|
+
"%s%s%s %s(%s);" % [
|
359
|
+
inspect_annotations,
|
360
|
+
modifier_string,
|
361
|
+
return_type.class_name,
|
362
|
+
name,
|
363
|
+
argument_types.map {|x| x.class_name}.join(', '),
|
364
|
+
]
|
365
|
+
end
|
366
|
+
end
|
367
|
+
end
|
data/lib/bitescript/signature.rb
CHANGED
@@ -33,6 +33,9 @@ module BiteScript
|
|
33
33
|
module_function :path
|
34
34
|
|
35
35
|
def class_id(cls)
|
36
|
+
return cls.descriptor if cls.kind_of?(BiteScript::ASM::Type)
|
37
|
+
return cls.type.descriptor if cls.kind_of?(BiteScript::ASM::ClassMirror)
|
38
|
+
|
36
39
|
cls = cls.java_class if Class === cls
|
37
40
|
|
38
41
|
if !cls || cls == java.lang.Void.java_class || Java::void == cls
|
data/test/test_bytecode.rb
CHANGED
@@ -311,7 +311,7 @@ class TestBytecode < Test::Unit::TestCase
|
|
311
311
|
assert_equal([:visit_try_catch_block, a_lbl.label, b_lbl.label, c_lbl.label, "java/lang/Integer"], @dummy.single {trycatch a_lbl, b_lbl, c_lbl, Integer})
|
312
312
|
end
|
313
313
|
|
314
|
-
def
|
314
|
+
def test_backward_jump_insns
|
315
315
|
a_lbl = label :a
|
316
316
|
assert_equal([:visit_jump_insn, Opcodes::GOTO, a_lbl.label], @dummy.single {goto a_lbl})
|
317
317
|
assert_equal([:visit_jump_insn, Opcodes::IFEQ, a_lbl.label], @dummy.single {ifeq a_lbl})
|
@@ -350,8 +350,68 @@ class TestBytecode < Test::Unit::TestCase
|
|
350
350
|
assert_equal([:visit_jump_insn, Opcodes::IFNULL, a_lbl.label], @dummy.single {ifnull :a})
|
351
351
|
assert_equal([:visit_jump_insn, Opcodes::IFNONNULL, a_lbl.label], @dummy.single {ifnonnull :a})
|
352
352
|
assert_equal([:visit_jump_insn, Opcodes::JSR, a_lbl.label], @dummy.single {jsr :a})
|
353
|
+
|
354
|
+
# should already have been set above at label :a
|
355
|
+
assert_raises(RuntimeError) {a_lbl.set!}
|
356
|
+
end
|
353
357
|
|
354
|
-
|
358
|
+
def test_forward_jump_insns
|
359
|
+
# allow forward references to as-yet-unset labels
|
360
|
+
lbl = nil
|
361
|
+
result = @dummy.single {goto :a1; lbl = labels[:a1]}
|
362
|
+
assert_equal([:visit_jump_insn, Opcodes::GOTO, lbl.label], result)
|
363
|
+
assert_equal([:visit_label, lbl.label], @dummy.single {label :a1})
|
364
|
+
result = @dummy.single {ifeq :a2; lbl = labels[:a2]}
|
365
|
+
assert_equal([:visit_jump_insn, Opcodes::IFEQ, lbl.label], result)
|
366
|
+
assert_equal([:visit_label, lbl.label], @dummy.single {label :a2})
|
367
|
+
result = @dummy.single {ifne :a3; lbl = labels[:a3]}
|
368
|
+
assert_equal([:visit_jump_insn, Opcodes::IFNE, lbl.label], result)
|
369
|
+
assert_equal([:visit_label, lbl.label], @dummy.single {label :a3})
|
370
|
+
result = @dummy.single {ifle :a4; lbl = labels[:a4]}
|
371
|
+
assert_equal([:visit_jump_insn, Opcodes::IFLE, lbl.label], result)
|
372
|
+
assert_equal([:visit_label, lbl.label], @dummy.single {label :a4})
|
373
|
+
result = @dummy.single {iflt :a5; lbl = labels[:a5]}
|
374
|
+
assert_equal([:visit_jump_insn, Opcodes::IFLT, lbl.label], result)
|
375
|
+
assert_equal([:visit_label, lbl.label], @dummy.single {label :a5})
|
376
|
+
result = @dummy.single {ifge :a6; lbl = labels[:a6]}
|
377
|
+
assert_equal([:visit_jump_insn, Opcodes::IFGE, lbl.label], result)
|
378
|
+
assert_equal([:visit_label, lbl.label], @dummy.single {label :a6})
|
379
|
+
result = @dummy.single {ifgt :a7; lbl = labels[:a7]}
|
380
|
+
assert_equal([:visit_jump_insn, Opcodes::IFGT, lbl.label], result)
|
381
|
+
assert_equal([:visit_label, lbl.label], @dummy.single {label :a7})
|
382
|
+
result = @dummy.single {if_acmpeq :a8; lbl = labels[:a8]}
|
383
|
+
assert_equal([:visit_jump_insn, Opcodes::IF_ACMPEQ, lbl.label], result)
|
384
|
+
assert_equal([:visit_label, lbl.label], @dummy.single {label :a8})
|
385
|
+
result = @dummy.single {if_acmpne :a9; lbl = labels[:a9]}
|
386
|
+
assert_equal([:visit_jump_insn, Opcodes::IF_ACMPNE, lbl.label], result)
|
387
|
+
assert_equal([:visit_label, lbl.label], @dummy.single {label :a9})
|
388
|
+
result = @dummy.single {if_icmpeq :a10; lbl = labels[:a10]}
|
389
|
+
assert_equal([:visit_jump_insn, Opcodes::IF_ICMPEQ, lbl.label], result)
|
390
|
+
assert_equal([:visit_label, lbl.label], @dummy.single {label :a10})
|
391
|
+
result = @dummy.single {if_icmpne :a11; lbl = labels[:a11]}
|
392
|
+
assert_equal([:visit_jump_insn, Opcodes::IF_ICMPNE, lbl.label], result)
|
393
|
+
assert_equal([:visit_label, lbl.label], @dummy.single {label :a11})
|
394
|
+
result = @dummy.single {if_icmplt :a12; lbl = labels[:a12]}
|
395
|
+
assert_equal([:visit_jump_insn, Opcodes::IF_ICMPLT, lbl.label], result)
|
396
|
+
assert_equal([:visit_label, lbl.label], @dummy.single {label :a12})
|
397
|
+
result = @dummy.single {if_icmpgt :a13; lbl = labels[:a13]}
|
398
|
+
assert_equal([:visit_jump_insn, Opcodes::IF_ICMPGT, lbl.label], result)
|
399
|
+
assert_equal([:visit_label, lbl.label], @dummy.single {label :a13})
|
400
|
+
result = @dummy.single {if_icmple :a14; lbl = labels[:a14]}
|
401
|
+
assert_equal([:visit_jump_insn, Opcodes::IF_ICMPLE, lbl.label], result)
|
402
|
+
assert_equal([:visit_label, lbl.label], @dummy.single {label :a14})
|
403
|
+
result = @dummy.single {if_icmpge :a15; lbl = labels[:a15]}
|
404
|
+
assert_equal([:visit_jump_insn, Opcodes::IF_ICMPGE, lbl.label], result)
|
405
|
+
assert_equal([:visit_label, lbl.label], @dummy.single {label :a15})
|
406
|
+
result = @dummy.single {ifnull :a16; lbl = labels[:a16]}
|
407
|
+
assert_equal([:visit_jump_insn, Opcodes::IFNULL, lbl.label], result)
|
408
|
+
assert_equal([:visit_label, lbl.label], @dummy.single {label :a16})
|
409
|
+
result = @dummy.single {ifnonnull :a17; lbl = labels[:a17]}
|
410
|
+
assert_equal([:visit_jump_insn, Opcodes::IFNONNULL, lbl.label], result)
|
411
|
+
assert_equal([:visit_label, lbl.label], @dummy.single {label :a17})
|
412
|
+
result = @dummy.single {jsr :a18; lbl = labels[:a18]}
|
413
|
+
assert_equal([:visit_jump_insn, Opcodes::JSR, lbl.label], result)
|
414
|
+
assert_equal([:visit_label, lbl.label], @dummy.single {label :a18})
|
355
415
|
end
|
356
416
|
|
357
417
|
def test_multidim_array
|
metadata
CHANGED
@@ -1,7 +1,12 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: bitescript
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
|
4
|
+
prerelease: false
|
5
|
+
segments:
|
6
|
+
- 0
|
7
|
+
- 0
|
8
|
+
- 6
|
9
|
+
version: 0.0.6
|
5
10
|
platform: ruby
|
6
11
|
authors:
|
7
12
|
- Charles Oliver Nutter
|
@@ -10,7 +15,7 @@ autorequire:
|
|
10
15
|
bindir: bin
|
11
16
|
cert_chain: []
|
12
17
|
|
13
|
-
date: 2010-
|
18
|
+
date: 2010-06-09 09:15:57.264000 -04:00
|
14
19
|
default_executable:
|
15
20
|
dependencies: []
|
16
21
|
|
@@ -30,6 +35,7 @@ extra_rdoc_files:
|
|
30
35
|
files:
|
31
36
|
- bin/bite
|
32
37
|
- bin/bitec
|
38
|
+
- bin/bitep
|
33
39
|
- examples/fib.bs
|
34
40
|
- examples/hello_world.bs
|
35
41
|
- examples/hello_world_macro.bs
|
@@ -41,12 +47,12 @@ files:
|
|
41
47
|
- lib/bitescript/asm.rb
|
42
48
|
- lib/bitescript/builder.rb
|
43
49
|
- lib/bitescript/bytecode.rb
|
50
|
+
- lib/bitescript/mirror.rb
|
44
51
|
- lib/bitescript/signature.rb
|
45
52
|
- nbproject/project.properties
|
46
53
|
- nbproject/project.xml
|
47
|
-
- nbproject/private/config.properties
|
48
|
-
- nbproject/private/private.properties
|
49
54
|
- nbproject/private/private.xml
|
55
|
+
- nbproject/private/rake-d.txt
|
50
56
|
- test/test_bitescript.rb
|
51
57
|
- test/test_builder.rb
|
52
58
|
- test/test_bytecode.rb
|
@@ -68,21 +74,25 @@ rdoc_options:
|
|
68
74
|
require_paths:
|
69
75
|
- lib
|
70
76
|
required_ruby_version: !ruby/object:Gem::Requirement
|
77
|
+
none: false
|
71
78
|
requirements:
|
72
79
|
- - ">="
|
73
80
|
- !ruby/object:Gem::Version
|
81
|
+
segments:
|
82
|
+
- 0
|
74
83
|
version: "0"
|
75
|
-
version:
|
76
84
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
85
|
+
none: false
|
77
86
|
requirements:
|
78
87
|
- - ">="
|
79
88
|
- !ruby/object:Gem::Version
|
89
|
+
segments:
|
90
|
+
- 0
|
80
91
|
version: "0"
|
81
|
-
version:
|
82
92
|
requirements: []
|
83
93
|
|
84
94
|
rubyforge_project: jruby-extras
|
85
|
-
rubygems_version: 1.3.
|
95
|
+
rubygems_version: 1.3.7
|
86
96
|
signing_key:
|
87
97
|
specification_version: 3
|
88
98
|
summary: BiteScript is a Ruby DSL for generating Java bytecode.
|
File without changes
|