Class: JvmBytecode::ClassFile
- Inherits:
-
Object
- Object
- JvmBytecode::ClassFile
show all
- Includes:
- AccessFlag
- Defined in:
- lib/jvm_bytecode/class_file.rb
Constant Summary
collapse
- MAGIC_NUMBER =
[0xCA, 0xFE, 0xBA, 0xBE].pack('C4').freeze
- ACCESS_FLAGS =
{
public: 0x0001,
final: 0x0010,
super: 0x0020,
interface: 0x0200,
abstract: 0x0400,
synthetic: 0x1000,
anotation: 0x2000,
enum: 0x4000
}.freeze
Class Method Summary
collapse
Instance Method Summary
collapse
Methods included from AccessFlag
#access_flag, #all_access_flag, #readable_access_flag, #set_access_flag
Constructor Details
#initialize(&block) ⇒ ClassFile
Returns a new instance of ClassFile.
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
|
# File 'lib/jvm_bytecode/class_file.rb', line 22
def initialize(&block)
@cp = ConstantPool.new
@minor_ver = 0
@major_ver = 52
@this_class = nil
@super_class = nil
@interfaces = []
@fields = []
@methods = []
@attributes = []
self.instance_eval(&block) if block_given?
end
|
Class Method Details
.decode(io) ⇒ Object
18
19
20
|
# File 'lib/jvm_bytecode/class_file.rb', line 18
def self.decode(io)
new.tap { |cf| cf.decode(io) }
end
|
Instance Method Details
#add_method(m) ⇒ Object
63
64
65
|
# File 'lib/jvm_bytecode/class_file.rb', line 63
def add_method(m)
@methods.push(m).last
end
|
#bytecode ⇒ Object
77
78
79
80
81
82
83
84
85
86
|
# File 'lib/jvm_bytecode/class_file.rb', line 77
def bytecode
version = [@minor_ver, @major_ver].pack('S>*')
classes = [access_flag, @this_class, @super_class].pack('S>*')
interfaces = ([@interfaces.length] + @interfaces).pack("S>*")
fields = @fields.join_bytecodes
methods = @methods.join_bytecodes
attributes = @attributes.join_bytecodes
MAGIC_NUMBER + version + @cp.bytecode + classes + interfaces + fields + methods + attributes
end
|
#constant_pool(&block) ⇒ Object
39
40
41
|
# File 'lib/jvm_bytecode/class_file.rb', line 39
def constant_pool(&block)
@cp.tap { |cp| cp.instance_eval(&block) if block_given? }
end
|
#decode(io) ⇒ Object
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
|
# File 'lib/jvm_bytecode/class_file.rb', line 88
def decode(io)
raise Errors::DecodeError, 'Not class file' if io.read(4) != MAGIC_NUMBER
@minor_ver, @major_ver = io.read(4).unpack('S>2')
@cp.decode(io)
acc_flag, @this_class, @super_class = io.read(6).unpack('S>3')
set_access_flag(acc_flag)
if_count = io.read(2).unpack('S>').first
@interfaces = io.read(if_count * 2).unpack("S>#{if_count}")
@fields = Field.decode_serial(@cp, io)
@methods = Method.decode_serial(@cp, io)
end
|
#major_version(v) ⇒ Object
47
48
49
|
# File 'lib/jvm_bytecode/class_file.rb', line 47
def major_version(v)
@major_ver = v
end
|
#method_definition(&block) ⇒ Object
67
68
69
|
# File 'lib/jvm_bytecode/class_file.rb', line 67
def method_definition(&block)
add_method(new_method).tap { |m| m.instance_eval(&block) if block_given?}
end
|
#minor_version(v) ⇒ Object
43
44
45
|
# File 'lib/jvm_bytecode/class_file.rb', line 43
def minor_version(v)
@minor_ver = v
end
|
#new_method ⇒ Object
59
60
61
|
# File 'lib/jvm_bytecode/class_file.rb', line 59
def new_method
Method.new(@cp)
end
|
#source_file(filename) ⇒ Object
71
72
73
74
75
|
# File 'lib/jvm_bytecode/class_file.rb', line 71
def source_file(filename)
@attributes << Attributes::SourceFile.new(@cp).tap do |a|
a.filename(filename)
end
end
|
#super_class(name) ⇒ Object
55
56
57
|
# File 'lib/jvm_bytecode/class_file.rb', line 55
def super_class(name)
@super_class = @cp.class_index(name)
end
|
#this_class(name) ⇒ Object
51
52
53
|
# File 'lib/jvm_bytecode/class_file.rb', line 51
def this_class(name)
@this_class = @cp.class_index(name)
end
|
#to_hash ⇒ Object
105
106
107
108
109
110
111
112
113
114
115
|
# File 'lib/jvm_bytecode/class_file.rb', line 105
def to_hash
{
minor_version: @minor_ver,
major_version: @major_ver,
constant_pool: @cp.to_hash,
access_flag: readable_access_flag,
this_class: @this_class,
super_class: @super_class,
methods: @methods.map(&:to_hash)
}
end
|