Class: Rasm::Java::Bytecode

Inherits:
Object
  • Object
show all
Includes:
Accessable
Defined in:
lib/rasm/java/bytecode.rb

Overview

ClassFile

u4 magic;
u2 minor_version;
u2 major_version;
u2 constant_pool_count;
cp_info constant_pool[constant_pool_count-1];
u2 access_flags;
u2 this_class;
u2 super_class;
u2 interfaces_count;
u2 interfaces[interfaces_count];
u2 fields_count;
field_info fields[fields_count];
u2 methods_count;
method_info methods[methods_count];
u2 attributes_count;
attribute_info attributes[attributes_count];

Constant Summary

Constants included from Accessable

Accessable::ACC_ABSTRACT, Accessable::ACC_ANNOTATION, Accessable::ACC_BRIDGE, Accessable::ACC_DEPRECATED, Accessable::ACC_ENUM, Accessable::ACC_FINAL, Accessable::ACC_INTERFACE, Accessable::ACC_NATIVE, Accessable::ACC_PRIVATE, Accessable::ACC_PROTECTED, Accessable::ACC_PUBLIC, Accessable::ACC_STATIC, Accessable::ACC_STRICT, Accessable::ACC_SUPER, Accessable::ACC_SYNCHRONIZED, Accessable::ACC_SYNTHETIC, Accessable::ACC_TRANSIENT, Accessable::ACC_VARARGS, Accessable::ACC_VOLATILE, Accessable::TYPEPATTERN, Accessable::TYPES

Instance Attribute Summary collapse

Attributes included from Accessable

#access_flags, #name

Instance Method Summary collapse

Methods included from Accessable

#access_desc, #typeof

Constructor Details

#initialize(class_file) ⇒ Bytecode

Returns a new instance of Bytecode.



33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
# File 'lib/rasm/java/bytecode.rb', line 33

def initialize(class_file)
  open class_file, 'rb' do|io|
    magic = io.read(4).unpack('N')[0]
    if magic == 0xCAFEBABE
      @version = io.read(4).unpack('nn').reverse.join('.')
      pull_cp_info(io)
      self.access_flags, this_class, super_class, interfaces_count = io.read(8).unpack('n*')
      @interfaces = interfaces_count > 0 ? io.read(2 * interfaces_count).unpack('n*').map{|item| constant_pool[item].val} : []
      self.name, @super_class = constant_pool[this_class].val, constant_pool[super_class].val

      @fields = pull_list(io, FieldInfo)
      @methods = pull_list(io, MethodInfo)
      @attributes = pull_attributes(io)
    else
      raise "magic #{magic} is not valid java class file."
    end
  end
end

Instance Attribute Details

#attributesObject (readonly)

Returns the value of attribute attributes.



31
32
33
# File 'lib/rasm/java/bytecode.rb', line 31

def attributes
  @attributes
end

#fieldsObject (readonly)

Returns the value of attribute fields.



31
32
33
# File 'lib/rasm/java/bytecode.rb', line 31

def fields
  @fields
end

#interfacesObject (readonly)

Returns the value of attribute interfaces.



31
32
33
# File 'lib/rasm/java/bytecode.rb', line 31

def interfaces
  @interfaces
end

#methodsObject (readonly)

Returns the value of attribute methods.



31
32
33
# File 'lib/rasm/java/bytecode.rb', line 31

def methods
  @methods
end

#super_classObject (readonly)

Returns the value of attribute super_class.



31
32
33
# File 'lib/rasm/java/bytecode.rb', line 31

def super_class
  @super_class
end

#versionObject (readonly)

Returns the value of attribute version.



31
32
33
# File 'lib/rasm/java/bytecode.rb', line 31

def version
  @version
end

Instance Method Details

#constant_poolObject



78
79
80
# File 'lib/rasm/java/bytecode.rb', line 78

def constant_pool
  @constant_pool ||= {}
end

#cp_infoObject



82
83
84
85
86
87
88
89
90
91
92
93
# File 'lib/rasm/java/bytecode.rb', line 82

def cp_info
  str = "cp_info (#{@constant_pool_count}) \n"
  constant_pool.each do|i, e|
    if e.is_a? Ref
      str << "#%02d = %-16s %-20s %s\n" % [i, e.name, e, ("//#{e.val}" if e.is_a?(Ref))]
    else
      str << "#%02d = %-16s %-20s\n" % [i, e.name, e.val]
    end

  end
  str
end

#to_sObject



52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
# File 'lib/rasm/java/bytecode.rb', line 52

def to_s
  access = access_flags
  str = ''
  if access & ACC_DEPRECATED != 0
    str << "//DEPRECATED\n"
  end
  str << "// access flags 0x%x\n" % access
  str << access_desc
  if (access & ACC_ANNOTATION) != 0
    str << '@interface '
  elsif (access & ACC_INTERFACE) != 0
    str << 'interface ';
  elsif (access & ACC_ENUM) == 0
    str << 'class '
  end
  str << name
  str << " extends #{super_class} " if super_class && super_class != 'java/lang/Object'
  str << " implements %s {\n" % interfaces.join(',') unless interfaces.empty?
  fields.each do|f|
    str << "#{f}\n"
  end
  str << "\n}"
  str
end