Class: RubyVM::RJIT::CPointer::Union

Inherits:
Object
  • Object
show all
Defined in:
lib/ruby_vm/rjit/c_pointer.rb

Overview

Note: We’d like to avoid alphabetic method names to avoid a conflict with member methods. to_i is considered an exception.

Class Method Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(addr, sizeof, members) ⇒ Union

Returns a new instance of Union.

Parameters:

  • _name (String)

    To be used when it starts defining a union pointer class

  • sizeof (Integer)
  • members (Hash{ Symbol => RubyVM::RJIT::CType::* })


107
108
109
110
111
# File 'lib/ruby_vm/rjit/c_pointer.rb', line 107

def initialize(addr, sizeof, members)
  @addr = addr
  @sizeof = sizeof
  @members = members
end

Class Method Details

.define(sizeof, members) ⇒ Object

Parameters:



132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
# File 'lib/ruby_vm/rjit/c_pointer.rb', line 132

def self.define(sizeof, members)
  Class.new(self) do
    # Return the size of this type
    define_singleton_method(:sizeof) { sizeof }

    # Part of Struct's offsetof implementation
    define_singleton_method(:offsetof) do |field, *fields|
      member = members.fetch(field)
      offset = 0
      unless fields.empty?
        offset += member.offsetof(*fields)
      end
      offset
    end

    define_method(:initialize) do |addr|
      super(addr, sizeof, members)
    end

    members.each do |member, type|
      # Intelligent API that does automatic dereference
      define_method(member) do
        value = type.new(@addr)
        if value.respond_to?(:*)
          value = value.*
        end
        value
      end
    end
  end
end

Instance Method Details

#+(index) ⇒ Object

Move addr to access this pointer like an array

Raises:

  • (ArgumentError)


119
120
121
122
# File 'lib/ruby_vm/rjit/c_pointer.rb', line 119

def +(index)
  raise ArgumentError unless index.is_a?(Integer)
  self.class.new(@addr + index * @sizeof)
end

#-(union) ⇒ Object

Pointer diff

Raises:

  • (ArgumentError)


125
126
127
128
# File 'lib/ruby_vm/rjit/c_pointer.rb', line 125

def -(union)
  raise ArgumentError if self.class != union.class
  (@addr - union.instance_variable_get(:@addr)) / @sizeof
end

#to_iObject

Get a raw address



114
115
116
# File 'lib/ruby_vm/rjit/c_pointer.rb', line 114

def to_i
  @addr
end