Friday, September 23, 2011

More JRuby + asm

Turns out you can get this jruby from yesterday's post even more concise:
require 'java'
require 'asm-3.3.1'
require 'pp'

# This lets me type org.objectweb.asm::... instead of Java::OrgObjectwebAsm::...
def org
  Java::Org
end

class SampleVisitor
  include org.objectweb.asm::MethodVisitor
  include org.objectweb.asm::ClassVisitor
  include org.objectweb.asm::FieldVisitor
  include org.objectweb.asm::AnnotationVisitor
  include org.objectweb.asm.signature::SignatureVisitor

  def method_missing name, *args
    name_string = name.to_s
    if name_string =~ /visit.*/
      puts "#{name}\t#{args}"
      self
    else
      super
    end
  end
end

# Loop through each .class file given on the command line
ARGV.each do |classfile|
  puts " ---------------- Reading file #{classfile}"
  f = java.io.File.new classfile
  fis = java.io.FileInputStream.new f
  
  class_reader = org.objectweb.asm::ClassReader.new fis
  
  v = SampleVisitor.new
  
  class_reader.accept v, 0
  
  puts
end
And the output is:
---------------- Reading file /Users/james/experimements/AsmSample/bin/com/restphone/classSignature/SampleOne.class
visit   [50, 33, "com/restphone/classSignature/SampleOne", nil, "java/lang/Object", #<#<Class:0x1144f3ba2>:0x2f6a23cf>]
visitSource     ["SampleOne.java", nil]
visitField      [9, "x", "Ljava/lang/Integer;", nil, nil]
visitEnd        []
visitMethod     [8, "<clinit>", "()V", nil, nil]
visitCode       []
visitLabel      [#<Java::OrgObjectwebAsm::Label:0x2b071e12>]
visitLineNumber [4, #<Java::OrgObjectwebAsm::Label:0x2b071e12>]
visitFieldInsn  [178, "com/restphone/classSignature/SampleTwo", "y", "Ljava/lang/Integer;"]
visitFieldInsn  [179, "com/restphone/classSignature/SampleOne", "x", "Ljava/lang/Integer;"]
visitLabel      [#<Java::OrgObjectwebAsm::Label:0x575c13ef>]
visitLineNumber [3, #<Java::OrgObjectwebAsm::Label:0x575c13ef>]
visitInsn       [177]
visitMaxs       [1, 0]
visitEnd        []
visitMethod     [1, "<init>", "()V", nil, nil]
visitCode       []
visitLabel      [#<Java::OrgObjectwebAsm::Label:0xc303a60>]
visitLineNumber [3, #<Java::OrgObjectwebAsm::Label:0xc303a60>]
visitVarInsn    [25, 0]
visitMethodInsn [183, "java/lang/Object", "<init>", "()V"]
visitInsn       [177]
visitLabel      [#<Java::OrgObjectwebAsm::Label:0x66869470>]
visitLocalVariable      ["this", "Lcom/restphone/classSignature/SampleOne;", nil, #<Java::OrgObjectwebAsm::Label:0xc303a60>, #<Java::OrgObjectwebAsm::Label:0x66869470>, 0]
visitMaxs       [1, 1]
visitEnd        []
visitMethod     [1, "doubleTheValue", "(Ljava/lang/Integer;)Ljava/lang/Integer;", nil, nil]
visitCode       []
visitLabel      [#<Java::OrgObjectwebAsm::Label:0x10fa706d>]
visitLineNumber [7, #<Java::OrgObjectwebAsm::Label:0x10fa706d>]
visitVarInsn    [25, 1]
visitMethodInsn [182, "java/lang/Integer", "intValue", "()I"]
visitInsn       [5]
visitInsn       [104]
visitMethodInsn [184, "java/lang/Integer", "valueOf", "(I)Ljava/lang/Integer;"]
visitInsn       [176]
visitLabel      [#<Java::OrgObjectwebAsm::Label:0x629a99eb>]
visitLocalVariable      ["this", "Lcom/restphone/classSignature/SampleOne;", nil, #<Java::OrgObjectwebAsm::Label:0x10fa706d>, #<Java::OrgObjectwebAsm::Label:0x629a99eb>, 0]
visitLocalVariable      ["x", "Ljava/lang/Integer;", nil, #<Java::OrgObjectwebAsm::Label:0x10fa706d>, #<Java::OrgObjectwebAsm::Label:0x629a99eb>, 1]
visitMaxs       [2, 2]
visitEnd        []
visitEnd        []
I'm including the jars on the command line:
jruby -I /Users/james/experimements/AsmSample/libs --1.9 asm_support.rb /Users/james/experimements/AsmSample/bin/com/restphone/classSignature/SampleOne.class  | less

No comments: