bitescript 0.0.8 → 0.0.9
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/bitescript.gemspec +2 -2
- data/examples/fib.bs +20 -11
- data/examples/hello_world_macro.bs +7 -3
- data/examples/invokedynamic.bs +41 -0
- data/lib/bitescript.rb +3 -1
- data/lib/bitescript/asm.rb +8 -1
- data/lib/bitescript/builder.rb +1 -1
- data/lib/bitescript/bytecode.rb +54 -30
- data/test/test_bitescript.rb +8 -1
- metadata +3 -5
- data/examples/hello_world.class +0 -0
- data/nbproject/private/private.xml +0 -4
- data/nbproject/private/rake-d.txt +0 -2
data/History.txt
CHANGED
@@ -1,3 +1,23 @@
|
|
1
|
+
=== 0.0.9 / 2011-07-11
|
2
|
+
|
3
|
+
62a10d2 Update time format in gemspec
|
4
|
+
0d37ff9 Update hello_world_macro.bs example
|
5
|
+
3b24a1d Fix TypeError in bytecode.rb with --1.9
|
6
|
+
96dfbef Merge pull request #5 from baroquebobcat/fixing_test_method_insns_deltas
|
7
|
+
2b06833 Merge pull request #4 from baroquebobcat/fix_bytecode_version_test
|
8
|
+
501863d Merge pull request #6 from baroquebobcat/continue_to_work_when_asm_4.0_is_unavailable
|
9
|
+
a4b82aa only define mh_* if those opcodes are present
|
10
|
+
a556514 rescue + note around MethodHandle java import
|
11
|
+
11472c7 copy and paste of sig_stack_net had a small bug. This fixes it
|
12
|
+
d5a7e4d default is now dynamic depending on java version used
|
13
|
+
7beeb5a Ask ASM to compute frames too.
|
14
|
+
a9e1c61 Fix ASM package juggling for proper pre-1.6.0.RC2 package.
|
15
|
+
c840664 Get invokedynamic support working.
|
16
|
+
801bea4 Add args length checking to fib script, since it's always confusing to get ArrayIndexOutOfBounds.
|
17
|
+
b537df1 Replace Label#set! calls with forward-referencing symbols.
|
18
|
+
3bf6f98 Replace confusing load_time macro with current_time
|
19
|
+
130bda6 Add .redcar to .gitignore.
|
20
|
+
|
1
21
|
=== 0.0.8 / 2011-03-05
|
2
22
|
|
3
23
|
* Support parsing of generic signatures
|
data/bitescript.gemspec
CHANGED
@@ -2,9 +2,9 @@
|
|
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.9"
|
6
6
|
s.authors = ["Charles Oliver Nutter", "Ryan Brown"]
|
7
|
-
s.date = Time.now.strftime('
|
7
|
+
s.date = Time.now.strftime('%Y-%m-%d')
|
8
8
|
s.description = %q{BiteScript is a Ruby DSL for generating Java bytecode and classes.}
|
9
9
|
s.email = ["headius@headius.com", "ribrdb@gmail.com"]
|
10
10
|
s.executables = ["bite", "bitec"]
|
data/examples/fib.bs
CHANGED
@@ -7,23 +7,34 @@ macro :lprintln do |i|
|
|
7
7
|
invokevirtual java.io.PrintStream, "println", [void, long]
|
8
8
|
end
|
9
9
|
|
10
|
-
macro :
|
10
|
+
macro :current_time do
|
11
11
|
invokestatic System, "currentTimeMillis", long
|
12
12
|
end
|
13
13
|
|
14
14
|
macro :start_timing do |i|
|
15
|
-
|
15
|
+
current_time
|
16
16
|
lstore i
|
17
17
|
end
|
18
18
|
|
19
19
|
macro :end_timing do |i|
|
20
|
-
|
20
|
+
current_time
|
21
21
|
lload i
|
22
22
|
lsub
|
23
23
|
lstore i
|
24
24
|
end
|
25
25
|
|
26
|
-
macro :
|
26
|
+
macro :load_iters do
|
27
|
+
# check args length
|
28
|
+
aload 0
|
29
|
+
arraylength
|
30
|
+
ifne :ok_iters
|
31
|
+
ldc "Usage: bite fib.bs <iters>"
|
32
|
+
aprintln
|
33
|
+
ldc 1
|
34
|
+
invokestatic System, 'exit', [void, int]
|
35
|
+
|
36
|
+
# args length ok
|
37
|
+
label :ok_iters
|
27
38
|
aload 0
|
28
39
|
ldc 0
|
29
40
|
aaload # number of times
|
@@ -31,7 +42,7 @@ macro :load_times do
|
|
31
42
|
end
|
32
43
|
|
33
44
|
main do
|
34
|
-
|
45
|
+
load_iters
|
35
46
|
istore 1
|
36
47
|
|
37
48
|
ldc "Raw bytecode fib(45) performance:"
|
@@ -39,8 +50,7 @@ main do
|
|
39
50
|
|
40
51
|
label :top
|
41
52
|
iload 1
|
42
|
-
done
|
43
|
-
ifeq done
|
53
|
+
ifeq :done
|
44
54
|
iinc 1, -1
|
45
55
|
|
46
56
|
start_timing 2
|
@@ -54,18 +64,17 @@ main do
|
|
54
64
|
lprintln 2
|
55
65
|
goto :top
|
56
66
|
|
57
|
-
done
|
67
|
+
label :done
|
58
68
|
returnvoid
|
59
69
|
end
|
60
70
|
|
61
71
|
public_static_method "fib", [], int, int do
|
62
72
|
iload 0
|
63
73
|
ldc 2
|
64
|
-
recurse
|
65
|
-
if_icmpge recurse
|
74
|
+
if_icmpge :recurse
|
66
75
|
iload 0
|
67
76
|
ireturn
|
68
|
-
recurse
|
77
|
+
label :recurse
|
69
78
|
iload 0
|
70
79
|
ldc 1
|
71
80
|
isub
|
@@ -4,20 +4,24 @@ import java.io.PrintStream
|
|
4
4
|
macro :aprintln do
|
5
5
|
getstatic System, :out, PrintStream
|
6
6
|
swap
|
7
|
-
invokevirtual PrintStream, println, [
|
7
|
+
invokevirtual PrintStream, "println", [void, object]
|
8
8
|
end
|
9
9
|
|
10
10
|
macro :aprint do
|
11
11
|
getstatic System, :out, PrintStream
|
12
12
|
swap
|
13
|
-
invokevirtual PrintStream, print, [
|
13
|
+
invokevirtual PrintStream, "print", [void, object]
|
14
14
|
end
|
15
15
|
|
16
16
|
main do
|
17
17
|
ldc "Hello, "
|
18
18
|
aprint
|
19
|
+
|
20
|
+
# Get first argument from command line
|
19
21
|
aload 0
|
20
|
-
|
22
|
+
ldc 0
|
23
|
+
aaload
|
24
|
+
|
21
25
|
aprintln
|
22
26
|
returnvoid
|
23
27
|
end
|
@@ -0,0 +1,41 @@
|
|
1
|
+
import java.lang.invoke.MethodHandle
|
2
|
+
import java.lang.invoke.MethodType
|
3
|
+
import java.lang.invoke.CallSite
|
4
|
+
import java.lang.invoke.ConstantCallSite
|
5
|
+
import java.lang.invoke.MethodHandles::Lookup
|
6
|
+
JClass = java.lang.Class
|
7
|
+
|
8
|
+
# Our main method, which does one invokedynamic
|
9
|
+
main do
|
10
|
+
# handle for our bootstrap, which binds invokedynamic to a CallSite
|
11
|
+
bootstrap = mh_invokestatic this, 'bootstrap', CallSite, Lookup, string, MethodType
|
12
|
+
|
13
|
+
ldc 'Hello, invokedynamic!'
|
14
|
+
invokedynamic 'print', [void, string], bootstrap
|
15
|
+
returnvoid
|
16
|
+
end
|
17
|
+
|
18
|
+
# The method we want to invoke, prints given string
|
19
|
+
public_static_method :print, [], void, string do
|
20
|
+
aload 0
|
21
|
+
aprintln
|
22
|
+
returnvoid
|
23
|
+
end
|
24
|
+
|
25
|
+
# The bootstrap method, which binds our dynamic call
|
26
|
+
public_static_method :bootstrap, [], CallSite, Lookup, string, MethodType do
|
27
|
+
# Constant since we bind just once directly
|
28
|
+
new ConstantCallSite
|
29
|
+
dup
|
30
|
+
|
31
|
+
# Locate the method indicated by name + type on current class
|
32
|
+
aload 0 # Lookup
|
33
|
+
ldc this # this class
|
34
|
+
aload 1 # String
|
35
|
+
aload 2 # MethodType
|
36
|
+
invokevirtual Lookup, 'findStatic', [MethodHandle, JClass, string, MethodType]
|
37
|
+
|
38
|
+
# finish constructing call site and return
|
39
|
+
invokespecial ConstantCallSite, '<init>', [void, MethodHandle]
|
40
|
+
areturn
|
41
|
+
end
|
data/lib/bitescript.rb
CHANGED
@@ -15,6 +15,8 @@ module BiteScript
|
|
15
15
|
class << self
|
16
16
|
attr_accessor :bytecode_version
|
17
17
|
|
18
|
-
|
18
|
+
# Default to JVM version we're running on
|
19
|
+
spec_version = ENV_JAVA['java.specification.version']
|
20
|
+
BiteScript.bytecode_version = BiteScript.const_get("JAVA#{spec_version.gsub('.', '_')}")
|
19
21
|
end
|
20
22
|
end
|
data/lib/bitescript/asm.rb
CHANGED
@@ -17,7 +17,7 @@ module BiteScript
|
|
17
17
|
# no error, proceed with mangled name
|
18
18
|
asm_package = Java::org.jruby.org.objectweb.asm
|
19
19
|
java_import asm_package.Opcodes
|
20
|
-
rescue
|
20
|
+
rescue Exception
|
21
21
|
# fall back on standard names
|
22
22
|
asm_package = org.objectweb.asm
|
23
23
|
java_import asm_package.Opcodes
|
@@ -35,5 +35,12 @@ module BiteScript
|
|
35
35
|
java_import asm_package.signature.SignatureReader
|
36
36
|
java_import asm_package.signature.SignatureVisitor
|
37
37
|
java_import asm_package.signature.SignatureWriter
|
38
|
+
|
39
|
+
# MethodHandle was introduced in ASM 4.0, and is only available to
|
40
|
+
# JRuby > 1.6.1
|
41
|
+
begin
|
42
|
+
java_import asm_package.MethodHandle
|
43
|
+
rescue
|
44
|
+
end
|
38
45
|
end
|
39
46
|
end
|
data/lib/bitescript/builder.rb
CHANGED
@@ -232,7 +232,7 @@ module BiteScript
|
|
232
232
|
flags = Opcodes::ACC_INTERFACE | Opcodes::ACC_ABSTRACT
|
233
233
|
end
|
234
234
|
|
235
|
-
@class_writer = ClassWriter.new(ClassWriter::COMPUTE_MAXS)
|
235
|
+
@class_writer = ClassWriter.new(ClassWriter::COMPUTE_FRAMES | ClassWriter::COMPUTE_MAXS)
|
236
236
|
|
237
237
|
interface_paths = []
|
238
238
|
(@interfaces).each {|interface| interface_paths << path(interface)}
|
data/lib/bitescript/bytecode.rb
CHANGED
@@ -39,7 +39,7 @@ module BiteScript
|
|
39
39
|
|
40
40
|
OpcodeInstructions = {}
|
41
41
|
|
42
|
-
Opcodes.constants.each do |const_name|
|
42
|
+
Opcodes.constants.map(&:to_s).each do |const_name|
|
43
43
|
const_down = const_name.downcase
|
44
44
|
|
45
45
|
case const_name
|
@@ -78,7 +78,7 @@ module BiteScript
|
|
78
78
|
size = push_int value
|
79
79
|
when Float
|
80
80
|
ldc_double(value)
|
81
|
-
when Module
|
81
|
+
when Module, ClassBuilder
|
82
82
|
ldc_class(value)
|
83
83
|
else
|
84
84
|
method_visitor.visit_ldc_insn(value)
|
@@ -98,40 +98,24 @@ module BiteScript
|
|
98
98
|
", b, __FILE__, line
|
99
99
|
OpcodeInstructions[const_name] = const_down
|
100
100
|
|
101
|
-
when "INVOKESTATIC", "INVOKEVIRTUAL", "INVOKEINTERFACE", "INVOKESPECIAL"
|
101
|
+
when "INVOKESTATIC", "INVOKEVIRTUAL", "INVOKEINTERFACE", "INVOKESPECIAL"
|
102
102
|
# method instructions
|
103
103
|
line = __LINE__; eval "
|
104
104
|
def #{const_down}(type, name, call_sig)
|
105
105
|
method_visitor.visit_method_insn(Opcodes::#{const_name}, path(type), name.to_s, sig(*call_sig))
|
106
106
|
|
107
|
-
|
108
|
-
|
109
|
-
|
110
|
-
|
111
|
-
|
112
|
-
|
113
|
-
|
114
|
-
|
115
|
-
|
116
|
-
|
117
|
-
|
118
|
-
this_subtracted = #{const_name == 'INVOKESTATIC' ? 0 : 1}
|
119
|
-
|
120
|
-
args_subtracted = 0
|
121
|
-
[*call_sig][1..-1].each do |param|
|
122
|
-
case param
|
123
|
-
when nil, Java::void, java.lang.Void
|
124
|
-
args_subtracted += 0
|
125
|
-
when Java::boolean, Java::short, Java::char, Java::int, Java::float
|
126
|
-
args_subtracted += 1
|
127
|
-
when Java::long, Java::double
|
128
|
-
args_subtracted += 2
|
129
|
-
else
|
130
|
-
args_subtracted += 1
|
131
|
-
end
|
132
|
-
end
|
107
|
+
sig_stack_net(call_sig, #{const_name == 'INVOKESTATIC' ? 0 : 1})
|
108
|
+
end
|
109
|
+
", b, __FILE__, line
|
110
|
+
OpcodeInstructions[const_name] = const_down
|
111
|
+
|
112
|
+
when "INVOKEDYNAMIC"
|
113
|
+
# invokedynamic instruction
|
114
|
+
line = __LINE__; eval "
|
115
|
+
def #{const_down}(name, call_sig, handle, *args)
|
116
|
+
method_visitor.visit_invoke_dynamic_insn(name.to_s, sig(*call_sig), handle, args.to_java)
|
133
117
|
|
134
|
-
|
118
|
+
sig_stack_net(call_sig, 0)
|
135
119
|
end
|
136
120
|
", b, __FILE__, line
|
137
121
|
OpcodeInstructions[const_name] = const_down
|
@@ -298,6 +282,15 @@ module BiteScript
|
|
298
282
|
end
|
299
283
|
OpcodeInstructions['TABLESWITCH'] = 'tableswitch'
|
300
284
|
|
285
|
+
when "MH_INVOKESPECIAL", "MH_INVOKESTATIC", "MH_PUTSTATIC", "MH_GETSTATIC", "MH_PUTFIELD",
|
286
|
+
"MH_GETFIELD", "MH_INVOKEVIRTUAL", "MH_INVOKEINTERFACE",
|
287
|
+
"MH_NEWINVOKESPECIAL"
|
288
|
+
line = __LINE__; eval "
|
289
|
+
def #{const_down}(cls, name, *call_sig)
|
290
|
+
MethodHandle.new(Opcodes::#{const_name}, path(cls), name, sig(*call_sig))
|
291
|
+
end
|
292
|
+
", b, __FILE__, line
|
293
|
+
OpcodeInstructions[const_name] = const_down
|
301
294
|
when "F_FULL", "ACC_ENUM", "ACC_SYNTHETIC", "ACC_INTERFACE", "ACC_PUBLIC",
|
302
295
|
"ACC_PRIVATE", "ACC_PROTECTED", "ACC_DEPRECATED", "ACC_BRIDGE",
|
303
296
|
"ACC_VARARGS", "ACC_SUPER", "F_CHOP", "F_APPEND", "FLOAT", "F_SAME",
|
@@ -307,6 +300,7 @@ module BiteScript
|
|
307
300
|
"F_SAME1", "ACC_NATIVE", "F_NEW", "T_CHAR", "T_INT", "ACC_VOLATILE",
|
308
301
|
"V1_6", "V1_5", "V1_4", "V1_3", "V1_2", "V1_1", "UNINITIALIZED_THIS",
|
309
302
|
"TOP", "T_SHORT", "INVOKEDYNAMIC_OWNER", "V1_7"
|
303
|
+
|
310
304
|
# non-instructions
|
311
305
|
|
312
306
|
else
|
@@ -429,6 +423,36 @@ module BiteScript
|
|
429
423
|
else
|
430
424
|
ldc_long(num)
|
431
425
|
end
|
426
|
+
end
|
427
|
+
|
428
|
+
def sig_stack_net(call_sig, this_subtracted)
|
429
|
+
case call_sig[0]
|
430
|
+
when nil, Java::void, java.lang.Void
|
431
|
+
added = 0
|
432
|
+
when Java::boolean, Java::short, Java::char, Java::int, Java::float
|
433
|
+
added = 1
|
434
|
+
when Java::long, Java::double
|
435
|
+
added = 2
|
436
|
+
else
|
437
|
+
added = 1
|
438
|
+
end
|
439
|
+
|
440
|
+
args_subtracted = 0
|
441
|
+
[*call_sig][1..-1].each do |param|
|
442
|
+
case param
|
443
|
+
when nil, Java::void, java.lang.Void
|
444
|
+
args_subtracted += 0
|
445
|
+
when Java::boolean, Java::short, Java::char, Java::int, Java::float
|
446
|
+
args_subtracted += 1
|
447
|
+
when Java::long, Java::double
|
448
|
+
args_subtracted += 2
|
449
|
+
else
|
450
|
+
args_subtracted += 1
|
451
|
+
end
|
452
|
+
end
|
453
|
+
|
454
|
+
added - (this_subtracted + args_subtracted)
|
432
455
|
end
|
456
|
+
private :sig_stack_net
|
433
457
|
end
|
434
458
|
end
|
data/test/test_bitescript.rb
CHANGED
@@ -4,8 +4,15 @@ require 'test/unit'
|
|
4
4
|
require 'bitescript'
|
5
5
|
|
6
6
|
class TestBitescript < Test::Unit::TestCase
|
7
|
+
def test_bytecode_defaults_to_current_version
|
8
|
+
spec_version = ENV_JAVA['java.specification.version']
|
9
|
+
expected_version = BiteScript.const_get("JAVA#{spec_version.gsub('.', '_')}")
|
10
|
+
|
11
|
+
assert_equal expected_version, BiteScript.bytecode_version
|
12
|
+
end
|
13
|
+
|
7
14
|
def test_bytecode_version
|
8
|
-
|
15
|
+
|
9
16
|
[BiteScript::JAVA1_4, BiteScript::JAVA1_5, BiteScript::JAVA1_6].each do |ver|
|
10
17
|
BiteScript.bytecode_version = ver
|
11
18
|
assert_equal(ver, BiteScript.bytecode_version)
|
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.0.9
|
6
6
|
platform: ruby
|
7
7
|
authors:
|
8
8
|
- Charles Oliver Nutter
|
@@ -11,7 +11,7 @@ autorequire:
|
|
11
11
|
bindir: bin
|
12
12
|
cert_chain: []
|
13
13
|
|
14
|
-
date: 2011-
|
14
|
+
date: 2011-07-11 00:00:00 -05:00
|
15
15
|
default_executable:
|
16
16
|
dependencies: []
|
17
17
|
|
@@ -34,10 +34,10 @@ files:
|
|
34
34
|
- bin/bitep
|
35
35
|
- examples/fib.bs
|
36
36
|
- examples/hello_world.bs
|
37
|
-
- examples/hello_world.class
|
38
37
|
- examples/hello_world_macro.bs
|
39
38
|
- examples/indy.bs
|
40
39
|
- examples/instanceof.bs
|
40
|
+
- examples/invokedynamic.bs
|
41
41
|
- examples/mixed_bag.rb
|
42
42
|
- examples/simple_loop.rb
|
43
43
|
- examples/using_ruby.bs
|
@@ -49,8 +49,6 @@ files:
|
|
49
49
|
- lib/bitescript/signature.rb
|
50
50
|
- nbproject/project.properties
|
51
51
|
- nbproject/project.xml
|
52
|
-
- nbproject/private/private.xml
|
53
|
-
- nbproject/private/rake-d.txt
|
54
52
|
- test/test_bitescript.rb
|
55
53
|
- test/test_builder.rb
|
56
54
|
- test/test_bytecode.rb
|
data/examples/hello_world.class
DELETED
Binary file
|