bitescript 0.0.9 → 0.1.0
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 +8 -0
- data/bitescript.gemspec +1 -1
- data/examples/invokedynamic.bs +1 -1
- data/examples/simple_loop.rb +9 -0
- data/lib/bitescript.rb +14 -5
- data/lib/bitescript/asm.rb +9 -7
- data/lib/bitescript/asm3/asm.rb +46 -0
- data/lib/bitescript/asm3/builder.rb +624 -0
- data/lib/bitescript/asm3/bytecode.rb +458 -0
- data/lib/bitescript/asm3/mirror.rb +649 -0
- data/lib/bitescript/asm3/signature.rb +133 -0
- data/lib/bitescript/builder.rb +10 -0
- data/lib/bitescript/bytecode.rb +5 -5
- data/lib/bitescript/mirror.rb +50 -18
- data/test/test_builder.rb +6 -0
- metadata +8 -5
@@ -0,0 +1,133 @@
|
|
1
|
+
require 'java'
|
2
|
+
|
3
|
+
module BiteScript
|
4
|
+
module JavaTypes
|
5
|
+
java_import java.lang.Object
|
6
|
+
java_import java.lang.Byte
|
7
|
+
java_import java.lang.Boolean
|
8
|
+
java_import java.lang.Short
|
9
|
+
java_import java.lang.Character
|
10
|
+
java_import java.lang.Integer
|
11
|
+
java_import java.lang.Long
|
12
|
+
java_import java.lang.Float
|
13
|
+
java_import java.lang.Double
|
14
|
+
java_import java.lang.Void
|
15
|
+
end
|
16
|
+
module Signature
|
17
|
+
def classname(path)
|
18
|
+
path.gsub('/', '.')
|
19
|
+
end
|
20
|
+
module_function :classname
|
21
|
+
|
22
|
+
def type_insn_path(cls)
|
23
|
+
descriptor = class_id(cls)
|
24
|
+
if descriptor[0, 1] == '['
|
25
|
+
descriptor
|
26
|
+
else
|
27
|
+
path(cls)
|
28
|
+
end
|
29
|
+
end
|
30
|
+
alias tipath type_insn_path
|
31
|
+
module_function :type_insn_path, :tipath
|
32
|
+
|
33
|
+
def path(cls)
|
34
|
+
case cls
|
35
|
+
when Symbol
|
36
|
+
return cls
|
37
|
+
when Class, Module
|
38
|
+
cls_name = cls.java_class.to_s || cls.java_class.name
|
39
|
+
else
|
40
|
+
cls_name = cls.name
|
41
|
+
end
|
42
|
+
cls_name.gsub('.', '/')
|
43
|
+
end
|
44
|
+
module_function :path
|
45
|
+
|
46
|
+
def class_id(cls)
|
47
|
+
return cls.descriptor if cls.kind_of?(BiteScript::ASM::Type)
|
48
|
+
return cls.type.descriptor if cls.kind_of?(BiteScript::ASM::ClassMirror)
|
49
|
+
|
50
|
+
cls = cls.java_class if Class === cls
|
51
|
+
|
52
|
+
if !cls || cls == java.lang.Void.java_class || Java::void == cls
|
53
|
+
return "V"
|
54
|
+
end
|
55
|
+
|
56
|
+
if Module === cls || Symbol === cls
|
57
|
+
return "L#{path(cls)};"
|
58
|
+
end
|
59
|
+
|
60
|
+
if cls.array?
|
61
|
+
cls = cls.component_type
|
62
|
+
if cls.primitive?
|
63
|
+
cls = cls.primitive_type if cls.respond_to? :primitive_type
|
64
|
+
case cls
|
65
|
+
when JavaTypes::Byte::TYPE
|
66
|
+
return "[B"
|
67
|
+
when JavaTypes::Boolean::TYPE
|
68
|
+
return "[Z"
|
69
|
+
when JavaTypes::Short::TYPE
|
70
|
+
return "[S"
|
71
|
+
when JavaTypes::Character::TYPE
|
72
|
+
return "[C"
|
73
|
+
when JavaTypes::Integer::TYPE
|
74
|
+
return "[I"
|
75
|
+
when JavaTypes::Long::TYPE
|
76
|
+
return "[J"
|
77
|
+
when JavaTypes::Float::TYPE
|
78
|
+
return "[F"
|
79
|
+
when JavaTypes::Double::TYPE
|
80
|
+
return "[D"
|
81
|
+
else
|
82
|
+
raise "Unknown type in compiler: #{cls.name}"
|
83
|
+
end
|
84
|
+
else
|
85
|
+
return "[#{class_id(cls)}"
|
86
|
+
end
|
87
|
+
else
|
88
|
+
if cls.primitive?
|
89
|
+
cls = cls.primitive_type if cls.respond_to? :primitive_type
|
90
|
+
case cls
|
91
|
+
when JavaTypes::Byte::TYPE
|
92
|
+
return "B"
|
93
|
+
when JavaTypes::Boolean::TYPE
|
94
|
+
return "Z"
|
95
|
+
when JavaTypes::Short::TYPE
|
96
|
+
return "S"
|
97
|
+
when JavaTypes::Character::TYPE
|
98
|
+
return "C"
|
99
|
+
when JavaTypes::Integer::TYPE
|
100
|
+
return "I"
|
101
|
+
when JavaTypes::Long::TYPE
|
102
|
+
return "J"
|
103
|
+
when JavaTypes::Float::TYPE
|
104
|
+
return "F"
|
105
|
+
when JavaTypes::Double::TYPE
|
106
|
+
return "D"
|
107
|
+
when JavaTypes::Void::TYPE, java.lang.Void
|
108
|
+
return "V"
|
109
|
+
else
|
110
|
+
raise "Unknown type in compiler: #{cls.name}"
|
111
|
+
end
|
112
|
+
else
|
113
|
+
return "L#{path(cls)};"
|
114
|
+
end
|
115
|
+
end
|
116
|
+
end
|
117
|
+
alias ci class_id
|
118
|
+
module_function :class_id, :ci
|
119
|
+
|
120
|
+
def signature(*sig_classes)
|
121
|
+
if sig_classes.size == 0
|
122
|
+
return "()V"
|
123
|
+
end
|
124
|
+
|
125
|
+
return_class = sig_classes.shift
|
126
|
+
sig_string = "("
|
127
|
+
sig_classes.each {|arg_class| sig_string << class_id(arg_class)}
|
128
|
+
sig_string << ")#{class_id(return_class)}"
|
129
|
+
end
|
130
|
+
alias sig signature
|
131
|
+
module_function :signature, :sig
|
132
|
+
end
|
133
|
+
end
|
data/lib/bitescript/builder.rb
CHANGED
@@ -298,12 +298,22 @@ module BiteScript
|
|
298
298
|
field(Opcodes::ACC_#{modifier.upcase}, name, type)
|
299
299
|
end
|
300
300
|
", binding, __FILE__, __LINE__
|
301
|
+
eval "
|
302
|
+
def #{modifier}_final_field(name, type)
|
303
|
+
field(Opcodes::ACC_#{modifier.upcase} | Opcodes::ACC_FINAL, name, type)
|
304
|
+
end
|
305
|
+
", binding, __FILE__, __LINE__
|
301
306
|
# static fields
|
302
307
|
eval "
|
303
308
|
def #{modifier}_static_field(name, type)
|
304
309
|
field(Opcodes::ACC_STATIC | Opcodes::ACC_#{modifier.upcase}, name, type)
|
305
310
|
end
|
306
311
|
", binding, __FILE__, __LINE__
|
312
|
+
eval "
|
313
|
+
def #{modifier}_static_final_field(name, type)
|
314
|
+
field(Opcodes::ACC_STATIC | Opcodes::ACC_#{modifier.upcase} | Opcodes::ACC_FINAL, name, type)
|
315
|
+
end
|
316
|
+
", binding, __FILE__, __LINE__
|
307
317
|
# instance methods; also defines a "this" local at index 0
|
308
318
|
eval "
|
309
319
|
def #{modifier}_method(name, exceptions=[], *signature, &block)
|
data/lib/bitescript/bytecode.rb
CHANGED
@@ -282,12 +282,12 @@ module BiteScript
|
|
282
282
|
end
|
283
283
|
OpcodeInstructions['TABLESWITCH'] = 'tableswitch'
|
284
284
|
|
285
|
-
when "
|
286
|
-
"
|
287
|
-
"
|
285
|
+
when "H_INVOKESPECIAL", "H_INVOKESTATIC", "H_PUTSTATIC", "H_GETSTATIC", "H_PUTFIELD",
|
286
|
+
"H_GETFIELD", "H_INVOKEVIRTUAL", "H_INVOKEINTERFACE",
|
287
|
+
"H_NEWINVOKESPECIAL"
|
288
288
|
line = __LINE__; eval "
|
289
289
|
def #{const_down}(cls, name, *call_sig)
|
290
|
-
|
290
|
+
Handle.new(Opcodes::#{const_name}, path(cls), name, sig(*call_sig))
|
291
291
|
end
|
292
292
|
", b, __FILE__, line
|
293
293
|
OpcodeInstructions[const_name] = const_down
|
@@ -299,7 +299,7 @@ module BiteScript
|
|
299
299
|
"T_DOUBLE", "DOUBLE", "ACC_STRICT", "NULL", "T_FLOAT", "ACC_FINAL",
|
300
300
|
"F_SAME1", "ACC_NATIVE", "F_NEW", "T_CHAR", "T_INT", "ACC_VOLATILE",
|
301
301
|
"V1_6", "V1_5", "V1_4", "V1_3", "V1_2", "V1_1", "UNINITIALIZED_THIS",
|
302
|
-
"TOP", "T_SHORT", "INVOKEDYNAMIC_OWNER", "V1_7"
|
302
|
+
"TOP", "T_SHORT", "INVOKEDYNAMIC_OWNER", "V1_7", "ASM4"
|
303
303
|
|
304
304
|
# non-instructions
|
305
305
|
|
data/lib/bitescript/mirror.rb
CHANGED
@@ -58,7 +58,7 @@ module BiteScript::ASM
|
|
58
58
|
end
|
59
59
|
end
|
60
60
|
|
61
|
-
class Builder
|
61
|
+
class Builder < BiteScript::ASM::AnnotationVisitor
|
62
62
|
class ValueArray
|
63
63
|
attr_reader :parent
|
64
64
|
def initialize(annotation, array)
|
@@ -71,10 +71,9 @@ module BiteScript::ASM
|
|
71
71
|
end
|
72
72
|
end
|
73
73
|
|
74
|
-
include BiteScript::ASM::AnnotationVisitor
|
75
|
-
|
76
74
|
attr_reader :annotation
|
77
75
|
def initialize(desc, visible)
|
76
|
+
super(BiteScript::ASM::Opcodes::ASM4)
|
78
77
|
@current = @annotation = AnnotationMirror.new(Type.getType(desc))
|
79
78
|
end
|
80
79
|
|
@@ -289,10 +288,11 @@ module BiteScript::ASM
|
|
289
288
|
result << "}"
|
290
289
|
end
|
291
290
|
|
292
|
-
class Builder
|
293
|
-
|
294
|
-
|
295
|
-
|
291
|
+
class Builder < BiteScript::ASM::ClassVisitor
|
292
|
+
|
293
|
+
def initialize
|
294
|
+
super(BiteScript::ASM::Opcodes::ASM4)
|
295
|
+
end
|
296
296
|
|
297
297
|
def visit(version, access, name, signature, super_name, interfaces)
|
298
298
|
@current = @class = ClassMirror.new(Type.getObjectType(name), access)
|
@@ -323,9 +323,9 @@ module BiteScript::ASM
|
|
323
323
|
|
324
324
|
def visitField(flags, name, desc, signature, value)
|
325
325
|
signature = GenericTypeBuilder.read(signature)
|
326
|
-
|
327
|
-
@class.addField(
|
328
|
-
|
326
|
+
mirror = FieldMirror.new(@class.type, flags, name, Type.getType(desc), signature, value)
|
327
|
+
@class.addField(mirror)
|
328
|
+
FieldMirror::Builder.new(mirror)
|
329
329
|
end
|
330
330
|
|
331
331
|
def visitMethod(flags, name, desc, signature, exceptions)
|
@@ -333,11 +333,11 @@ module BiteScript::ASM
|
|
333
333
|
parameters = Type.getArgumentTypes(desc).to_a
|
334
334
|
exceptions = (exceptions || []).map {|e| Type.getObjectType(e)}
|
335
335
|
signature = SignatureMirror.new(signature) if signature
|
336
|
-
|
336
|
+
mirror = MethodMirror.new(
|
337
337
|
@class.type, flags, return_type, name, parameters, exceptions, signature)
|
338
|
-
@class.addMethod(
|
338
|
+
@class.addMethod(mirror)
|
339
339
|
# TODO parameter annotations, default value, etc.
|
340
|
-
|
340
|
+
MethodMirror::Builder.new(mirror)
|
341
341
|
end
|
342
342
|
|
343
343
|
def visitAnnotationDefault(*args);end
|
@@ -347,7 +347,7 @@ module BiteScript::ASM
|
|
347
347
|
end
|
348
348
|
end
|
349
349
|
end
|
350
|
-
|
350
|
+
|
351
351
|
class FieldMirror
|
352
352
|
include Modifiers
|
353
353
|
include Annotated
|
@@ -369,6 +369,21 @@ module BiteScript::ASM
|
|
369
369
|
def inspect
|
370
370
|
inspect_annotations + "#{modifier_string}#{type.getClassName} #{name};"
|
371
371
|
end
|
372
|
+
|
373
|
+
class Builder < BiteScript::ASM::FieldVisitor
|
374
|
+
def initialize(mirror)
|
375
|
+
super(BiteScript::ASM::Opcodes::ASM4)
|
376
|
+
@current = @mirror
|
377
|
+
end
|
378
|
+
|
379
|
+
def mirror
|
380
|
+
@current
|
381
|
+
end
|
382
|
+
|
383
|
+
def to_s
|
384
|
+
"FieldBuilder(#{type.class_name})"
|
385
|
+
end
|
386
|
+
end
|
372
387
|
end
|
373
388
|
|
374
389
|
class MethodMirror
|
@@ -412,10 +427,26 @@ module BiteScript::ASM
|
|
412
427
|
argument_types.map {|x| x.class_name}.join(', '),
|
413
428
|
]
|
414
429
|
end
|
430
|
+
|
431
|
+
class Builder < BiteScript::ASM::MethodVisitor
|
432
|
+
|
433
|
+
def initialize(mirror)
|
434
|
+
super(BiteScript::ASM::Opcodes::ASM4)
|
435
|
+
@current = mirror
|
436
|
+
end
|
437
|
+
|
438
|
+
def mirror
|
439
|
+
@current
|
440
|
+
end
|
441
|
+
|
442
|
+
def to_s
|
443
|
+
"MethodBuilder(#{type.class_name})"
|
444
|
+
end
|
445
|
+
end
|
446
|
+
|
415
447
|
end
|
416
448
|
|
417
|
-
class SignatureMirror
|
418
|
-
include BiteScript::ASM::SignatureVisitor
|
449
|
+
class SignatureMirror < BiteScript::ASM::SignatureVisitor
|
419
450
|
|
420
451
|
attr_reader :type_parameters
|
421
452
|
attr_reader :parameter_types, :return_type, :exception_types
|
@@ -430,6 +461,7 @@ module BiteScript::ASM
|
|
430
461
|
end
|
431
462
|
|
432
463
|
def initialize(signature=nil)
|
464
|
+
super(BiteScript::ASM::Opcodes::ASM4)
|
433
465
|
@type_parameters = []
|
434
466
|
@parameter_types = []
|
435
467
|
@exception_types = []
|
@@ -570,8 +602,7 @@ module BiteScript::ASM
|
|
570
602
|
end
|
571
603
|
end
|
572
604
|
|
573
|
-
class GenericTypeBuilder
|
574
|
-
include BiteScript::ASM::SignatureVisitor
|
605
|
+
class GenericTypeBuilder < BiteScript::ASM::SignatureVisitor
|
575
606
|
attr_reader :result
|
576
607
|
|
577
608
|
def self.read(signature)
|
@@ -584,6 +615,7 @@ module BiteScript::ASM
|
|
584
615
|
end
|
585
616
|
|
586
617
|
def initialize(&block)
|
618
|
+
super(BiteScript::ASM::Opcodes::ASM4)
|
587
619
|
@block = block
|
588
620
|
end
|
589
621
|
|
data/test/test_builder.rb
CHANGED
@@ -305,21 +305,27 @@ class TestBuilder < Test::Unit::TestCase
|
|
305
305
|
|
306
306
|
cb.public_field('inst_field', JString)
|
307
307
|
cb.public_static_field('static_field', JString)
|
308
|
+
cb.public_static_final_field('static_final_field', JString)
|
308
309
|
|
309
310
|
cb.public_method('set_inst', [], cb.void) {aload 0; ldc 'instance'; putfield this, 'inst_field', JString; returnvoid}
|
310
311
|
cb.public_method('set_static', [], cb.void) {ldc 'static'; putstatic this, 'static_field', JString; returnvoid}
|
312
|
+
cb.public_method('set_static_final', [], cb.void){ldc 'static final'; putstatic this, 'static_final_field', JString; returnvoid}
|
311
313
|
cb.public_method('get_inst', [], JString) {aload 0; getfield this, 'inst_field', JString; areturn}
|
312
314
|
cb.public_method('get_static', [], JString) {getstatic this, 'static_field', JString; areturn}
|
315
|
+
cb.public_method('get_static_final', [], JString) {getstatic this, 'static_final_field', JString; areturn}
|
313
316
|
|
314
317
|
dummy_constructor(cb)
|
315
318
|
obj = load_and_construct(@class_name, cb);
|
316
319
|
|
317
320
|
assert_equal nil, obj.get_inst
|
318
321
|
assert_equal nil, obj.get_static
|
322
|
+
assert_equal nil, obj.get_static_final
|
319
323
|
obj.set_inst
|
320
324
|
obj.set_static
|
325
|
+
obj.set_static_final
|
321
326
|
assert_equal 'instance', obj.get_inst
|
322
327
|
assert_equal 'static', obj.get_static
|
328
|
+
assert_equal 'static final', obj.get_static_final
|
323
329
|
end
|
324
330
|
|
325
331
|
def test_arrays
|
metadata
CHANGED
@@ -2,7 +2,7 @@
|
|
2
2
|
name: bitescript
|
3
3
|
version: !ruby/object:Gem::Version
|
4
4
|
prerelease:
|
5
|
-
version: 0.0
|
5
|
+
version: 0.1.0
|
6
6
|
platform: ruby
|
7
7
|
authors:
|
8
8
|
- Charles Oliver Nutter
|
@@ -11,8 +11,7 @@ autorequire:
|
|
11
11
|
bindir: bin
|
12
12
|
cert_chain: []
|
13
13
|
|
14
|
-
date: 2011-
|
15
|
-
default_executable:
|
14
|
+
date: 2011-12-21 00:00:00 Z
|
16
15
|
dependencies: []
|
17
16
|
|
18
17
|
description: BiteScript is a Ruby DSL for generating Java bytecode and classes.
|
@@ -47,6 +46,11 @@ files:
|
|
47
46
|
- lib/bitescript/bytecode.rb
|
48
47
|
- lib/bitescript/mirror.rb
|
49
48
|
- lib/bitescript/signature.rb
|
49
|
+
- lib/bitescript/asm3/asm.rb
|
50
|
+
- lib/bitescript/asm3/builder.rb
|
51
|
+
- lib/bitescript/asm3/bytecode.rb
|
52
|
+
- lib/bitescript/asm3/mirror.rb
|
53
|
+
- lib/bitescript/asm3/signature.rb
|
50
54
|
- nbproject/project.properties
|
51
55
|
- nbproject/project.xml
|
52
56
|
- test/test_bitescript.rb
|
@@ -60,7 +64,6 @@ files:
|
|
60
64
|
- README.txt
|
61
65
|
- bitescript.gemspec
|
62
66
|
- Rakefile
|
63
|
-
has_rdoc: true
|
64
67
|
homepage: http://github.com/headius/bitescript
|
65
68
|
licenses: []
|
66
69
|
|
@@ -85,7 +88,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
85
88
|
requirements: []
|
86
89
|
|
87
90
|
rubyforge_project: jruby-extras
|
88
|
-
rubygems_version: 1.
|
91
|
+
rubygems_version: 1.8.12
|
89
92
|
signing_key:
|
90
93
|
specification_version: 3
|
91
94
|
summary: BiteScript is a Ruby DSL for generating Java bytecode.
|