|
精华帖 (0) :: 良好帖 (7) :: 新手帖 (0) :: 隐藏帖 (2)
|
|
|---|---|
| 作者 | 正文 |
|
时间:2008-02-05
DynamicStruct,是我最近自己在鼓捣的一个ruby项目,这是一个更大的计划的一部分。
当他完成之后,应该是这样的一个结构: Aurum | V RubyBCL | V DynamicStruct Aurum是目前徐昊正在做的一个项目,简单的介绍可以看这里:《A very brief introduction to Aurum》 通过aurum,可以更加方便的定义新的语言。 但是,仅仅依靠aurum,只能让新设计出来的语言,运行于aurum的解释环境中,ruby就已经是够慢的解释语言了,这样的解释执行方式,可以说完全无法得到具有实用价值的语言。但是,如果可以通过aurum,将一种语言编译成Java Bytecode,那么,美好的未来就会是:“能够快速的定义,具有实用价值的,新语言!而且,各种新语言,都能够基于JVM,互联互通。” RubyBCL,现在还没有出现。仅有的灵感,来自Charles Nutter的一篇blog:《Bytecode Tools in Ruby: A Low-level DSL》。这篇blog可能无法在国内访问。转贴一点过来吧: cb = Compiler::ClassBuilder.build("MyClass", "MyClass.java") do
field :list, ArrayList
constructor(String, ArrayList) do
aload 0
invokespecial Object, "<init>", Void::TYPE
aload 0
aload 1
aload 2
invokevirtual this, :bar, [ArrayList, String, ArrayList]
aload 0
swap
putfield this, :list, ArrayList
returnvoid
end
static_method(:foo, this, String) do
new this
dup
aload 0
new ArrayList
dup
invokespecial ArrayList, "<init>", Void::TYPE
invokespecial this, "<init>", [Void::TYPE, String, ArrayList]
areturn
end
method(:bar, ArrayList, String, ArrayList) do
aload 1
invokevirtual(String, :toLowerCase, String)
aload 2
swap
invokevirtual(ArrayList, :add, [Boolean::TYPE, Object])
aload 2
areturn
end
method(:getList, ArrayList) do
aload 0
getfield this, :list, ArrayList
areturn
end
static_method(:main, Void::TYPE, String[]) do
aload 0
ldc_int 0
aaload
invokestatic this, :foo, [this, String]
invokevirtual this, :getList, ArrayList
aprintln
returnvoid
end
end
cb.write("MyClass.class")
这样一段代码,就能够得到一个MyClass.class。这个class,也可以用下面的java代码编译得到。 import java.util.ArrayList;
public class MyClass {
public ArrayList list;
public MyClass(String a, ArrayList b) {
list = bar(a, b);
}
public static MyClass foo(String a) {
return new MyClass(a, new ArrayList());
}
public ArrayList bar(String a, ArrayList b) {
b.add(a.toLowerCase());
return b;
}
public ArrayList getList() {
return list;
}
public static void main(String[] args) {
System.out.println(foo(args[0]).getList());
}
}
非常漂亮的DSL,但是,在看过Charles Nutter放在svn里的代码之后,我才发现,这家伙太讨巧了,事实上他上面的那些DSL,最后还是利用JRuby,调用了ASM这个java类库。所以,我打算,仅仅借鉴他的DSL设计,但是却用纯粹的ruby,来实现一个生成Java Bytecode的lib。 至于DynamicStruct,要从BitStruct说起,由于ruby没有一个很方便的处理二进制文件的类库,所以我找到了bit-struct,还有一篇不错的中文介绍:《用bit-struct处理结构化(二进制)数据》 但是,后来我发现,这个bit-struct,存在绝大的问题,甚至不能仅仅在他的基础上进行修改。因为他只能支持定长的数据结构,而不是可变长度的array list,变长的string,或者switch结构。因此,只能推倒重写。 我现在的工作,就是一个初步的二进制文件读写类库的实现。 简单的看看其中的测试代码吧: require "dynamic-struct"
class ClassFile<DynamicStruct
u4 :magic
u2 :file
field_type :clsf
end
class Temp<DynamicStruct
u2 :t_file
clsf :cf
field_type :temp
end
class Temp2<DynamicStruct
u2 :t_file
clsf :cf
temp :ttt
u1 :uu1
u2 :uu2
end
a=Temp2.new
a.t_file=1
a.cf.magic=2
a.cf.file=3
a.ttt.t_file=4
a.ttt.cf.magic=5
a.ttt.cf.file=6
a.uu1=444
a.uu2=888
f=open("C:\\test1.class","wb")
a.write(f)
f.close
f = File.new("C:\\test1.class")
b=Temp2.new
b.read(f)
f.close
puts b.to_s
这个test1,基本完成了与bit-struct类似的工作。 require "dynamic-struct"
class Temp<DynamicStruct
string :str,1
end
a=Temp.new
a.str='String Test!'
f=open("C:\\test2.class","wb")
a.write(f)
f.close
f = File.new("C:\\test2.class")
b=Temp.new
b.read(f)
f.close
puts b.to_s
这是动态字符串的效果。 require "dynamic-struct"
class TempArray<ArrayField
size_byte 1
item_type :u2
field_type :u2array
end
class TempStruct<DynamicStruct
u2array :ua
end
ts=TempStruct.new
ts.ua.add(1)
ts.ua.add(2)
ts.ua.add(3)
ts.ua[2]=4
puts ts.to_s
f=open("C:\\test3.class","wb")
ts.write(f)
f.close
f = File.new("C:\\test3.class")
b=TempStruct.new
b.read(f)
f.close
puts b.to_s
这是array list的效果。 require "dynamic-struct"
class TempSwitch<SwitchField
size_byte 1
item_type_list({1=>:u1,2=>:u2,3=>:u4,4=>:u8})
field_type :temps
end
class TempStruct<DynamicStruct
temps :tus
end
ts=TempStruct.new
u=UnsignedField.new
u.field_type_name="u4"
u.value=33
ts.tus.value=u
puts ts.to_s
f=open("C:\\test4.class","wb")
ts.write(f)
f.close
f = File.new("C:\\test4.class")
b=TempStruct.new
b.read(f)
f.close
puts b.to_s
这是switch的效果。 附上源代码,欢迎多多批评! 声明:JavaEye文章版权属于作者,受法律保护。没有作者书面许可不得转载。
推荐链接
|
|
| 返回顶楼 | |
|
时间:2008-02-05
刚才google搜索才发现,已经有人做了与我这个很类似的工作。而且就是JavaEye的朋友~~~
为BitStruct添加list类型 不过他这样的扩展,正如我所说的,受限于bit-struct,而无法实现真正的可变长数组~~~ |
|
| 返回顶楼 | |
|
时间:2008-02-09
我没有搞明白这个类库是干什么用的。从你写的测试代码来看,貌似是用来读取Java的class文件,可以从class文件当中提取Java的类结构和数据的,是这么回事吗?
那这样做的意义何在?用ruby编写Java的DSL源代码,然后再编译为class,这不是多此一举吗?我直接写Java源代码,然后编译不就可以了吗? |
|
| 返回顶楼 | |
|
时间:2008-02-09
按我的理解是方便地实现DSL语言并且在JVM上运行吧
|
|
| 返回顶楼 | |
|
时间:2008-02-09
neodoxy 写道 按我的理解是方便地实现DSL语言并且在JVM上运行吧 直接用ruby做DSL,然后用jruby来跑,不是更直接? |
|
| 返回顶楼 | |
|
时间:2008-02-09
JRuby之所以可能,是因为通过Antlr,将ruby语言,解释为了JVM能够理解的字节码。
而aurum,就可以认为是一个ruby版的antlr,而且,可以期待的是,借助于ruby强大的DSL能力,这个ruby的版本,会远比java的版本,更为方便好用。 因此,aurum不是一个DSL支持框架,而是任意语言的快速实现平台。 但是,aurum在开发之初,并没有考虑过有关效率的任何问题。因此,如果有一组支撑类库,能够帮助aurum,将他所能够解释出来的语言,直接编译为java的Bytecode,则这条道路,就会比antlr+asm,更为快捷。 至于读取bytecode的结构化数据,则是独立于我上面所说的需求之外的能力。毕竟我已经可能很方便的实现结构化的二进制数据写入,为什么不顺便实现一个读取呢? 让ruby,拥有对于class文件的读取、分析、修改的能力,不是也很棒吗? |
|
| 返回顶楼 | |
|
时间:2008-02-10
庄表伟 写道 JRuby之所以可能,是因为通过Antlr,将ruby语言,解释为了JVM能够理解的字节码。
而aurum,就可以认为是一个ruby版的antlr,而且,可以期待的是,借助于ruby强大的DSL能力,这个ruby的版本,会远比java的版本,更为方便好用。 因此,aurum不是一个DSL支持框架,而是任意语言的快速实现平台。 但是,aurum在开发之初,并没有考虑过有关效率的任何问题。因此,如果有一组支撑类库,能够帮助aurum,将他所能够解释出来的语言,直接编译为java的Bytecode,则这条道路,就会比antlr+asm,更为快捷。 至于读取bytecode的结构化数据,则是独立于我上面所说的需求之外的能力。毕竟我已经可能很方便的实现结构化的二进制数据写入,为什么不顺便实现一个读取呢? 让ruby,拥有对于class文件的读取、分析、修改的能力,不是也很棒吗? 但是没有人会通过ruby-java这个途径再去创造一种新的通用语言,我相信主要用途还是DSL方面的 |
|
| 返回顶楼 | |
|
时间:2008-02-15
正是我所需要的,BitStruct无法处理变长字符串已经让我抓狂了。抛开未来计划不谈,这个东东对使用ruby处理二进制是福音啊,希望老大继续发展。
|
|
| 返回顶楼 | |
|
时间:2008-03-12
C:\Real.java
class Real {
public static void main(String[] args) throws Exception {
System.out.println("Hello World!");
}
}
在运行了如下一段程序之后 require 'bytecode-struct'
f = File.open("C:\\Real.class","rb")
b=ClassFile.new
b.read(f)
f.close
b.constant_pool[19].value='Hello World!你好,我好,大家好!'
f = File.new("D:\\Real.class","wb")
b.write(f)
f.close
在D:\下执行 引用 java Real
就会得到: Hello World!你好,我好,大家好! 纯ruby实现的,读写Java Class,初步实现! 源代码在: http://svn.w18.net/svn/rds/ |
|
| 返回顶楼 | |
|
时间:2008-03-12
补充:
不同的javac,编译出来的Class,Hello World的String,未必在第20个,所以我这段代码,不一定能够正确运行的 |
|
| 返回顶楼 | |









