bitescript 0.0.1
Sign up to get free protection for your applications and to get access to all the features.
- data/History.txt +6 -0
- data/LICENSE.txt +9 -0
- data/Manifest.txt +20 -0
- data/README.txt +56 -0
- data/Rakefile +22 -0
- data/bin/bite +32 -0
- data/bin/bitec +22 -0
- data/examples/fib.bs +79 -0
- data/examples/mixed_bag.rb +73 -0
- data/examples/simple_loop.rb +24 -0
- data/lib/bitescript/asm.rb +17 -0
- data/lib/bitescript/builder.rb +459 -0
- data/lib/bitescript/bytecode.rb +415 -0
- data/lib/bitescript/signature.rb +117 -0
- data/lib/bitescript.rb +20 -0
- data/test/test_bitescript.rb +14 -0
- data/test/test_builder.rb +429 -0
- data/test/test_bytecode.rb +674 -0
- data/test/test_java_class.rb +58 -0
- data/test/test_signature.rb +68 -0
- metadata +91 -0
data/History.txt
ADDED
data/LICENSE.txt
ADDED
@@ -0,0 +1,9 @@
|
|
1
|
+
Copyright (c) 2009, Charles Oliver Nutter
|
2
|
+
All rights reserved.
|
3
|
+
|
4
|
+
Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:
|
5
|
+
|
6
|
+
Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.
|
7
|
+
Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution.
|
8
|
+
Neither the name of BiteScript nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission.
|
9
|
+
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
data/Manifest.txt
ADDED
@@ -0,0 +1,20 @@
|
|
1
|
+
History.txt
|
2
|
+
LICENSE.txt
|
3
|
+
Manifest.txt
|
4
|
+
README.txt
|
5
|
+
Rakefile
|
6
|
+
bin/bite
|
7
|
+
bin/bitec
|
8
|
+
examples/fib.bs
|
9
|
+
examples/mixed_bag.rb
|
10
|
+
examples/simple_loop.rb
|
11
|
+
lib/bitescript.rb
|
12
|
+
lib/bitescript/asm.rb
|
13
|
+
lib/bitescript/builder.rb
|
14
|
+
lib/bitescript/bytecode.rb
|
15
|
+
lib/bitescript/signature.rb
|
16
|
+
test/test_bitescript.rb
|
17
|
+
test/test_builder.rb
|
18
|
+
test/test_bytecode.rb
|
19
|
+
test/test_java_class.rb
|
20
|
+
test/test_signature.rb
|
data/README.txt
ADDED
@@ -0,0 +1,56 @@
|
|
1
|
+
= bitescript
|
2
|
+
|
3
|
+
http://kenai.com/projects/jvmscript
|
4
|
+
|
5
|
+
== DESCRIPTION:
|
6
|
+
|
7
|
+
BiteScript is a Ruby DSL for generating Java bytecode and classes.
|
8
|
+
|
9
|
+
== FEATURES/PROBLEMS:
|
10
|
+
|
11
|
+
== SYNOPSIS:
|
12
|
+
|
13
|
+
require 'bitescript'
|
14
|
+
|
15
|
+
include BiteScript
|
16
|
+
|
17
|
+
fb = FileBuilder.build(__FILE__) do
|
18
|
+
public_class "SimpleLoop" do
|
19
|
+
public_static_method "main", void, string[] do
|
20
|
+
aload 0
|
21
|
+
push_int 0
|
22
|
+
aaload
|
23
|
+
label :top
|
24
|
+
dup
|
25
|
+
aprintln
|
26
|
+
goto :top
|
27
|
+
returnvoid
|
28
|
+
end
|
29
|
+
end
|
30
|
+
end
|
31
|
+
|
32
|
+
fb.generate do |filename, class_builder|
|
33
|
+
File.open(filename, 'w') do |file|
|
34
|
+
file.write(class_builder.generate)
|
35
|
+
end
|
36
|
+
end
|
37
|
+
|
38
|
+
== REQUIREMENTS:
|
39
|
+
|
40
|
+
JRuby 1.2 or higher.
|
41
|
+
|
42
|
+
== INSTALL:
|
43
|
+
|
44
|
+
gem install bitescript
|
45
|
+
|
46
|
+
== LICENSE:
|
47
|
+
|
48
|
+
Copyright (c) 2009, Charles Oliver Nutter
|
49
|
+
All rights reserved.
|
50
|
+
|
51
|
+
Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:
|
52
|
+
|
53
|
+
Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.
|
54
|
+
Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution.
|
55
|
+
Neither the name of BiteScript nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission.
|
56
|
+
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
data/Rakefile
ADDED
@@ -0,0 +1,22 @@
|
|
1
|
+
require 'rake'
|
2
|
+
require 'rake/testtask'
|
3
|
+
require 'rake/rdoctask'
|
4
|
+
require 'hoe'
|
5
|
+
$: << './lib'
|
6
|
+
require 'bitescript.rb'
|
7
|
+
|
8
|
+
Hoe.new('bitescript', BiteScript::VERSION) do |p|
|
9
|
+
p.rubyforge_name = 'jruby-extras'
|
10
|
+
p.url = "http://kenai.com/projects/jvmscript"
|
11
|
+
p.author = "charles.nutter@sun.com"
|
12
|
+
p.summary = "BiteScript is a Ruby DSL for generating Java bytecode."
|
13
|
+
p.changes = p.paragraphs_of('History.txt', 0..1).join("\n\n")
|
14
|
+
p.developer('Charles Oliver Nutter', 'charles.nutter@sun.com')
|
15
|
+
end
|
16
|
+
|
17
|
+
task :default => :test
|
18
|
+
|
19
|
+
Rake::TestTask.new do |t|
|
20
|
+
t.libs << "lib"
|
21
|
+
t.test_files = FileList["test/**/*.rb"]
|
22
|
+
end
|
data/bin/bite
ADDED
@@ -0,0 +1,32 @@
|
|
1
|
+
#!/usr/bin/env jruby
|
2
|
+
|
3
|
+
$: << File.dirname(File.dirname(__FILE__)) + "/lib"
|
4
|
+
|
5
|
+
require 'bitescript'
|
6
|
+
|
7
|
+
file = ARGV[0]
|
8
|
+
|
9
|
+
raise "usage: bite <script>" unless file
|
10
|
+
|
11
|
+
content = File.read(file)
|
12
|
+
fb = BiteScript::FileBuilder.build(file) do
|
13
|
+
public_class "BiteScriptCLI" do
|
14
|
+
eval content, binding, file, 1
|
15
|
+
end
|
16
|
+
end
|
17
|
+
|
18
|
+
fb.generate do |filename, classbuilder|
|
19
|
+
bytes = classbuilder.generate
|
20
|
+
|
21
|
+
cl = org.jruby.util.JRubyClassLoader.new(java.lang.ClassLoader.system_class_loader)
|
22
|
+
cls = cl.define_class(filename[0, -7], bytes.to_java_bytes)
|
23
|
+
|
24
|
+
begin
|
25
|
+
main = cls.get_method("main", [java.lang.String[]].to_java(java.lang.Class))
|
26
|
+
args = ARGV[1..-1] || []
|
27
|
+
main.invoke(nil, [args.to_java(:string)].to_java)
|
28
|
+
rescue NativeException => x
|
29
|
+
x = x.cause while x.cause
|
30
|
+
x.print_stack_trace
|
31
|
+
end
|
32
|
+
end
|
data/bin/bitec
ADDED
@@ -0,0 +1,22 @@
|
|
1
|
+
#!/usr/bin/env jruby
|
2
|
+
|
3
|
+
$: << File.dirname(File.dirname(__FILE__)) + "/lib"
|
4
|
+
|
5
|
+
require 'bitescript'
|
6
|
+
|
7
|
+
file = ARGV[0]
|
8
|
+
|
9
|
+
raise "usage: bite <script>" unless file
|
10
|
+
|
11
|
+
content = File.read(file)
|
12
|
+
fb = BiteScript::FileBuilder.build(file) do
|
13
|
+
name = file[0..file.rindex('.') - 1]
|
14
|
+
public_class name do
|
15
|
+
eval content, binding, file, 1
|
16
|
+
end
|
17
|
+
end
|
18
|
+
|
19
|
+
fb.generate do |filename, classbuilder|
|
20
|
+
bytes = classbuilder.generate
|
21
|
+
File.open(filename, 'w') {|f| f.write(bytes)}
|
22
|
+
end
|
data/examples/fib.bs
ADDED
@@ -0,0 +1,79 @@
|
|
1
|
+
System = java.lang.System
|
2
|
+
JInteger = java.lang.Integer
|
3
|
+
|
4
|
+
macro :lprintln do |i|
|
5
|
+
getstatic System, "out", java.io.PrintStream
|
6
|
+
lload i
|
7
|
+
invokevirtual java.io.PrintStream, "println", [void, long]
|
8
|
+
end
|
9
|
+
|
10
|
+
macro :load_time do
|
11
|
+
invokestatic System, "currentTimeMillis", long
|
12
|
+
end
|
13
|
+
|
14
|
+
macro :start_timing do |i|
|
15
|
+
load_time
|
16
|
+
lstore i
|
17
|
+
end
|
18
|
+
|
19
|
+
macro :end_timing do |i|
|
20
|
+
load_time
|
21
|
+
lload 2
|
22
|
+
lsub
|
23
|
+
lstore 2
|
24
|
+
end
|
25
|
+
|
26
|
+
macro :load_times do
|
27
|
+
aload 0
|
28
|
+
ldc 0
|
29
|
+
aaload # number of times
|
30
|
+
invokestatic JInteger, 'parseInt', [int, string]
|
31
|
+
end
|
32
|
+
|
33
|
+
main do
|
34
|
+
load_times
|
35
|
+
istore 1
|
36
|
+
|
37
|
+
ldc "Raw bytecode fib(45) performance:"
|
38
|
+
aprintln
|
39
|
+
|
40
|
+
label :top
|
41
|
+
iload 1
|
42
|
+
done = label
|
43
|
+
ifeq done
|
44
|
+
iinc 1, -1
|
45
|
+
|
46
|
+
start_timing 2
|
47
|
+
ldc 45
|
48
|
+
invokestatic this, "fib", [int, int]
|
49
|
+
pop
|
50
|
+
end_timing 2
|
51
|
+
|
52
|
+
ldc "Time: "
|
53
|
+
aprintln
|
54
|
+
lprintln 2
|
55
|
+
goto :top
|
56
|
+
|
57
|
+
done.set!
|
58
|
+
returnvoid
|
59
|
+
end
|
60
|
+
|
61
|
+
public_static_method "fib", int, int do
|
62
|
+
iload 0
|
63
|
+
ldc 2
|
64
|
+
recurse = label
|
65
|
+
if_icmpge recurse
|
66
|
+
iload 0
|
67
|
+
ireturn
|
68
|
+
recurse.set!
|
69
|
+
iload 0
|
70
|
+
ldc 1
|
71
|
+
isub
|
72
|
+
invokestatic this, "fib", [int, int]
|
73
|
+
iload 0
|
74
|
+
ldc 2
|
75
|
+
isub
|
76
|
+
invokestatic this, "fib", [int, int]
|
77
|
+
iadd
|
78
|
+
ireturn
|
79
|
+
end
|
@@ -0,0 +1,73 @@
|
|
1
|
+
require 'java'
|
2
|
+
require 'jruby'
|
3
|
+
require 'bitescript'
|
4
|
+
|
5
|
+
import java.util.ArrayList
|
6
|
+
|
7
|
+
# Construct a class that uses several JVM opcodes and method types
|
8
|
+
builder = BiteScript::FileBuilder.build("somefile.source") do
|
9
|
+
package "org.awesome", "stuff" do
|
10
|
+
public_class "MyClass", object do
|
11
|
+
public_field "list", ArrayList
|
12
|
+
|
13
|
+
public_constructor string, ArrayList do
|
14
|
+
aload 0
|
15
|
+
invokespecial object, "<init>", [void]
|
16
|
+
aload 0
|
17
|
+
aload 1
|
18
|
+
aload 2
|
19
|
+
invokevirtual this, "bar", [ArrayList, string, ArrayList]
|
20
|
+
aload 0
|
21
|
+
swap
|
22
|
+
putfield this, "list", ArrayList
|
23
|
+
returnvoid
|
24
|
+
end
|
25
|
+
|
26
|
+
public_static_method "foo", this, string do
|
27
|
+
new this
|
28
|
+
dup
|
29
|
+
aload 0
|
30
|
+
new ArrayList
|
31
|
+
dup
|
32
|
+
invokespecial ArrayList, "<init>", [void]
|
33
|
+
invokespecial this, "<init>", [void, string, ArrayList]
|
34
|
+
areturn
|
35
|
+
end
|
36
|
+
|
37
|
+
public_method "bar", ArrayList, string, ArrayList do
|
38
|
+
aload 1
|
39
|
+
invokevirtual(string, "toLowerCase", string)
|
40
|
+
aload 2
|
41
|
+
swap
|
42
|
+
invokevirtual(ArrayList, "add", [boolean, object])
|
43
|
+
aload 2
|
44
|
+
areturn
|
45
|
+
end
|
46
|
+
|
47
|
+
public_method("getList", ArrayList) do
|
48
|
+
aload 0
|
49
|
+
getfield this, "list", ArrayList
|
50
|
+
areturn
|
51
|
+
end
|
52
|
+
|
53
|
+
public_static_method("main", void, string[]) do
|
54
|
+
aload 0
|
55
|
+
ldc_int 0
|
56
|
+
aaload
|
57
|
+
invokestatic this, "foo", [this, string]
|
58
|
+
invokevirtual this, "getList", ArrayList
|
59
|
+
aprintln
|
60
|
+
returnvoid
|
61
|
+
end
|
62
|
+
end
|
63
|
+
end
|
64
|
+
end
|
65
|
+
|
66
|
+
# Load and instantiate using JRuby's class loader
|
67
|
+
loader = JRuby.runtime.jruby_class_loader
|
68
|
+
builder.generate do |name, builder|
|
69
|
+
bytes = builder.generate
|
70
|
+
cls = loader.define_class(name[0..-7].gsub('/', '.'), bytes.to_java_bytes)
|
71
|
+
MyClass = JavaUtilities.get_proxy_class(cls.name)
|
72
|
+
MyClass.main(['hello, BiteScript'].to_java :string)
|
73
|
+
end
|
@@ -0,0 +1,24 @@
|
|
1
|
+
require 'bitescript'
|
2
|
+
|
3
|
+
include BiteScript
|
4
|
+
|
5
|
+
fb = FileBuilder.build(__FILE__) do
|
6
|
+
public_class "SimpleLoop" do
|
7
|
+
public_static_method "main", void, string[] do
|
8
|
+
aload 0
|
9
|
+
push_int 0
|
10
|
+
aaload
|
11
|
+
label :top
|
12
|
+
dup
|
13
|
+
aprintln
|
14
|
+
goto :top
|
15
|
+
returnvoid
|
16
|
+
end
|
17
|
+
end
|
18
|
+
end
|
19
|
+
|
20
|
+
fb.generate do |filename, class_builder|
|
21
|
+
File.open(filename, 'w') do |file|
|
22
|
+
file.write(class_builder.generate)
|
23
|
+
end
|
24
|
+
end
|
@@ -0,0 +1,17 @@
|
|
1
|
+
require 'java'
|
2
|
+
|
3
|
+
module BiteScript
|
4
|
+
module ASM
|
5
|
+
begin
|
6
|
+
# try mangled names for the version included with JRuby
|
7
|
+
asm_package = Java::jruby.objectweb.asm
|
8
|
+
java_import asm_package.Opcodes
|
9
|
+
rescue Exception
|
10
|
+
# fall back on standard names
|
11
|
+
asm_package = org.objectweb.asm
|
12
|
+
java_import asm_package.Opcodes
|
13
|
+
end
|
14
|
+
java_import asm_package.Label
|
15
|
+
java_import asm_package.Type
|
16
|
+
end
|
17
|
+
end
|