`
庄表伟
  • 浏览: 1151857 次
  • 性别: Icon_minigender_1
  • 来自: 上海
社区版块
存档分类
最新评论

发布DynamicStruct-0.2 and BytecodeStruct-0.1

阅读更多
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的效果。

附上源代码,欢迎多多批评!
分享到:
评论
11 楼 庄表伟 2008-03-13  
代码还没整理好,不好意思见人。
再说也还没有想好是申请一个项目,还是两个项目。
10 楼 dennis_zane 2008-03-13  
为什么不去RubyForge上申请个项目呢?还是挺容易申请的。
9 楼 庄表伟 2008-03-12  
补充:

不同的javac,编译出来的Class,Hello World的String,未必在第20个,所以我这段代码,不一定能够正确运行的

8 楼 庄表伟 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/
7 楼 dennis_zane 2008-02-15  
正是我所需要的,BitStruct无法处理变长字符串已经让我抓狂了。抛开未来计划不谈,这个东东对使用ruby处理二进制是福音啊,希望老大继续发展。
6 楼 neodoxy 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方面的
5 楼 庄表伟 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文件的读取、分析、修改的能力,不是也很棒吗?
4 楼 robbin 2008-02-09  
neodoxy 写道
按我的理解是方便地实现DSL语言并且在JVM上运行吧

直接用ruby做DSL,然后用jruby来跑,不是更直接?
3 楼 neodoxy 2008-02-09  
按我的理解是方便地实现DSL语言并且在JVM上运行吧
2 楼 robbin 2008-02-09  
我没有搞明白这个类库是干什么用的。从你写的测试代码来看,貌似是用来读取Java的class文件,可以从class文件当中提取Java的类结构和数据的,是这么回事吗?

那这样做的意义何在?用ruby编写Java的DSL源代码,然后再编译为class,这不是多此一举吗?我直接写Java源代码,然后编译不就可以了吗?
1 楼 庄表伟 2008-02-05  
刚才google搜索才发现,已经有人做了与我这个很类似的工作。而且就是JavaEye的朋友~~~

为BitStruct添加list类型

不过他这样的扩展,正如我所说的,受限于bit-struct,而无法实现真正的可变长数组~~~

相关推荐

    lpeg-0.12.2-struct-0.2

    《深入理解LPEG与Struct:解析lpeg-0.12.2-struct-0.2组合包》 在IT领域,高效的文本处理和解析能力是至关重要的,尤其是在编程语言和编译器设计中。LPEG(Lua Pattern Grammar)和Struct就是这样的两个工具,它们...

    javaStruct-0.2.jar.zip

    JavaStruct-0.2.jar.zip 是一个包含JavaStruct-0.2.jar的压缩文件,它标志着这个是一个针对Java平台的软件组件或者库的稳定版本。JavaStruct这个名字暗示它可能是一个框架或者工具集,专注于结构化数据处理或者软件...

    Python库 | jsonstruct-0.2a1.linux-x86_64.tar.gz

    资源分类:Python库 所属语言:Python 资源全名:jsonstruct-0.2a1.linux-x86_64.tar.gz 资源来源:官方 安装方法:https://lanzao.blog.csdn.net/article/details/101784059

    javaStruct-0.2.jar

    javaStruct结构体的代码

    mapstruct-jdk8-1.2.0.Final-API文档-中英对照版.zip

    赠送jar包:mapstruct-jdk8-1.2.0.Final.jar; 赠送原API文档:mapstruct-jdk8-1.2.0.Final-javadoc.jar; 赠送源代码:mapstruct-jdk8-1.2.0.Final-sources.jar; 赠送Maven依赖信息文件:mapstruct-jdk8-1.2.0....

    mapstruct-jdk8-1.2.0.Final-API文档-中文版.zip

    赠送jar包:mapstruct-jdk8-1.2.0.Final.jar; 赠送原API文档:mapstruct-jdk8-1.2.0.Final-javadoc.jar; 赠送源代码:mapstruct-jdk8-1.2.0.Final-sources.jar; 赠送Maven依赖信息文件:mapstruct-jdk8-1.2.0....

    mapstruct-1.3.1.Final-API文档-中文版.zip

    赠送jar包:mapstruct-1.3.1.Final.jar; 赠送原API文档:mapstruct-1.3.1.Final-javadoc.jar; 赠送源代码:mapstruct-1.3.1.Final-sources.jar; 赠送Maven依赖信息文件:mapstruct-1.3.1.Final.pom; 包含翻译后...

    mapstruct-1.1.0.Final-API文档-中文版.zip

    赠送jar包:mapstruct-1.1.0.Final.jar; 赠送原API文档:mapstruct-1.1.0.Final-javadoc.jar; 赠送源代码:mapstruct-1.1.0.Final-sources.jar; 赠送Maven依赖信息文件:mapstruct-1.1.0.Final.pom; 包含翻译后...

    mapstruct-processor-1.2.0.Final-API文档-中文版.zip

    赠送jar包:mapstruct-processor-1.2.0.Final.jar; 赠送原API文档:mapstruct-processor-1.2.0.Final-javadoc.jar; 赠送源代码:mapstruct-processor-1.2.0.Final-sources.jar; 赠送Maven依赖信息文件:mapstruct...

    mapstruct-1.3.1.Final-API文档-中英对照版.zip

    赠送jar包:mapstruct-1.3.1.Final.jar; 赠送原API文档:mapstruct-1.3.1.Final-javadoc.jar; 赠送源代码:mapstruct-1.3.1.Final-sources.jar; 赠送Maven依赖信息文件:mapstruct-1.3.1.Final.pom; 包含翻译后...

    Python库 | construct-hub-0.2.48.tar.gz

    2. **组合构造器**:通过使用`Sequence`、`Struct`和`Choice`等构造器,可以组合多个子构造器,定义复杂的数据结构。 3. **解析和构造操作**:使用`.parse()`方法对二进制数据进行解析,使用`.build()`方法将数据...

    mapstruct-1.0.0.Final.jar

    mapstruct-1.0.0.Final.jarmapstruct-1.0.0.Final.jar

    mapstruct-1.1.0.Final.jar

    mapstruct-1.1.0.Final.jarmapstruct-1.1.0.Final.jar

    mapstruct-processor-1.2.0.Final-API文档-中英对照版.zip

    赠送jar包:mapstruct-processor-1.2.0.Final.jar; 赠送原API文档:mapstruct-processor-1.2.0.Final-javadoc.jar; 赠送源代码:mapstruct-processor-1.2.0.Final-sources.jar; 赠送Maven依赖信息文件:mapstruct...

    mapstruct-1.2.0.Final-API文档-中文版.zip

    赠送jar包:mapstruct-1.2.0.Final.jar; 赠送原API文档:mapstruct-1.2.0.Final-javadoc.jar; 赠送源代码:mapstruct-1.2.0.Final-sources.jar; 赠送Maven依赖信息文件:mapstruct-1.2.0.Final.pom; 包含翻译后...

    mapstruct-plus-main.zip

    这个名为"mapstruct-plus-main.zip"的压缩包很可能是MapStruct的一个扩展或增强版本,可能是某个开发者或团队为了提高映射效率或添加额外功能而创建的。下面将详细讨论MapStruct的基本概念、其工作原理以及可能包含...

    java struts2 jar

    Struts2是一个基于MVC(Model-View-Controller)设计模式的Java web应用程序框架,它在Java社区中广泛使用,特别是在构建企业级应用时。这个压缩包“Struts2jar”很可能包含了Struts2框架所需的各类JAR文件,这些...

    JavaStruct.jar稳定版

    之前在csdn下了个javastruct.jar结果用完有bug(大端转换失效), 于是把源码搞下来自己生成了一个, 很稳定, 已应用到项目

    mapstruct-1.2.0.Final-API文档-中英对照版.zip

    赠送jar包:mapstruct-1.2.0.Final.jar; 赠送原API文档:mapstruct-1.2.0.Final-javadoc.jar; 赠送源代码:mapstruct-1.2.0.Final-sources.jar; 赠送Maven依赖信息文件:mapstruct-1.2.0.Final.pom; 包含翻译后...

    mapstruct-1.1.0.Final-API文档-中英对照版.zip

    赠送jar包:mapstruct-1.1.0.Final.jar; 赠送原API文档:mapstruct-1.1.0.Final-javadoc.jar; 赠送源代码:mapstruct-1.1.0.Final-sources.jar; 赠送Maven依赖信息文件:mapstruct-1.1.0.Final.pom; 包含翻译后...

Global site tag (gtag.js) - Google Analytics