Class: JavaClass::ClassFile::ConstantPool

Inherits:
Object
  • Object
show all
Defined in:
lib/javaclass/classfile/constant_pool.rb

Overview

Container of the constant pool’s constants.

Author

Peter Kofler

Constant Summary collapse

CONSTANT_TYPE_TAGS =

Types of constants by their tag.

{
  CLASS_TAG           = 7 => Constants::ConstantClass,
  FIELD_TAG           = 9 => Constants::ConstantField,
  METHOD_TAG          = 10 => Constants::ConstantMethod,
  INTERFACE_METHOD_TAG = 11 => Constants::ConstantInterfaceMethod,
  STRING_TAG          = 8 => Constants::ConstantString,
  INT_TAG             = 3 => Constants::ConstantInt,
  FLOAT_TAG           = 4 => Constants::ConstantFloat,
  LONG_TAG            = 5 => Constants::ConstantLong,
  DOUBLE_TAG          = 6 => Constants::ConstantDouble,
  NAME_AND_TYPE_TAG   = 12 => Constants::ConstantNameAndType,
  ASCIZ_TAG           = 1 => Constants::ConstantAsciz,
  # Java 1.7
  METHOD_HANDLE_TAG   = 15 => Constants::ConstantMethodHandle,
  METHOD_TYPE_TAG     = 16 => Constants::ConstantMethodType,
  INVOKE_DYNAMIC_TAG  = 18 => Constants::ConstantInvokeDynamic,
  # Java 9
  MODULE_TAG          = 19 => Constants::ConstantModule,
  PACKAGE_TAG         = 20 => Constants::ConstantPackage,
}

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(data, start = 8) ⇒ ConstantPool

Parse the constant pool from the bytes data beginning at position start (which is usually 8).



40
41
42
43
44
45
46
47
48
# File 'lib/javaclass/classfile/constant_pool.rb', line 40

def initialize(data, start=8)
  creator = PoolCreator.new(data, start)
  creator.create!
  
  @pool = creator.pool # cnt (Fixnum) => constant class
  @item_count = creator.item_count
  
  @size = @pool.values.inject(0) { |sum, constant| sum + constant.size } + 2
end

Instance Attribute Details

#sizeObject (readonly)

Size of the whole constant pool in bytes.



37
38
39
# File 'lib/javaclass/classfile/constant_pool.rb', line 37

def size
  @size
end

Instance Method Details

#[](index) ⇒ Object

Return the index’th pool item. index is the real index in the pool which may skip numbers.



57
58
59
60
# File 'lib/javaclass/classfile/constant_pool.rb', line 57

def[](index)
  check_index(index)
  @pool[index]
end

#class_item(index) ⇒ Object

Return the constant class from index’th pool item.



90
91
92
93
94
95
# File 'lib/javaclass/classfile/constant_pool.rb', line 90

def class_item(index)
  if self[index] && !self[index].const_class?
    raise ClassFormatError, "inconsistent constant pool entry #{index} for class, should be Constant Class"
  end
  self[index]
end

#dumpObject

Return a debug output of the whole pool.



85
86
87
# File 'lib/javaclass/classfile/constant_pool.rb', line 85

def dump
  ["  Constant pool:"] + @pool.keys.sort.collect { |k| "const ##{k} = #{self[k].dump}"}
end

#field_item(index) ⇒ Object

Return the constant field from index’th pool item.



98
99
100
101
102
103
# File 'lib/javaclass/classfile/constant_pool.rb', line 98

def field_item(index)
  if self[index] && !self[index].const_field?
    raise ClassFormatError, "inconsistent constant pool entry #{index} for field, should be Constant Field"
  end
  self[index]
end

#find(*tags) ⇒ Object

Return an array of all constants of the given tags types.



75
76
77
# File 'lib/javaclass/classfile/constant_pool.rb', line 75

def find(*tags)
  items.find_all { |item| tags.include? item.tag }
end

#item_countObject

Return the number of pool items. This number might be larger than items available, because long and double constants take two slots.



52
53
54
# File 'lib/javaclass/classfile/constant_pool.rb', line 52

def item_count
  @item_count - 1
end

#itemsObject

Return an array of the ordered list of constants.



70
71
72
# File 'lib/javaclass/classfile/constant_pool.rb', line 70

def items
  @pool.keys.sort.collect { |k| self[k] }
end

#method_item(index) ⇒ Object

Return the constant method from index’th pool item.



106
107
108
109
110
111
# File 'lib/javaclass/classfile/constant_pool.rb', line 106

def method_item(index)
  if self[index] && !self[index].const_method?
    raise ClassFormatError, "inconsistent constant pool entry #{index} for method, should be Constant Method"
  end
  self[index]
end

#stringsObject

Return all string constants.



80
81
82
# File 'lib/javaclass/classfile/constant_pool.rb', line 80

def strings
  find(STRING_TAG)
end