class RubyVM::RJIT::CPointer::Struct

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

Public Class Methods

new(addr, sizeof, members) click to toggle source

@param name [String] @param sizeof [Integer] @param members [Hash{ Symbol => [RubyVM::RJIT::CType::*, Integer, TrueClass] }]

# File ruby_vm/rjit/c_pointer.rb, line 11
def initialize(addr, sizeof, members)
  @addr = addr
  @sizeof = sizeof
  @members = members
end

Private Class Methods

define(size, members) click to toggle source

@param size [Integer] @param members [Hash{ Symbol => [Integer, RubyVM::RJIT::CType::*] }]

Calls superclass method
# File ruby_vm/rjit/c_pointer.rb, line 52
def self.define(size, members)
  Class.new(self) do
    # Return the size of this type
    define_singleton_method(:size) { size }

    # Return the offset to a field
    define_singleton_method(:offsetof) do |field, *fields|
      member, offset = members.fetch(field)
      offset /= 8
      unless fields.empty?
        offset += member.offsetof(*fields)
      end
      offset
    end

    # Return member names
    define_singleton_method(:members) { members.keys }

    define_method(:initialize) do |addr = nil|
      if addr.nil? # TODO: get rid of this feature later
        addr = Fiddle.malloc(size)
      end
      super(addr, size, members)
    end

    members.each do |member, (type, offset, to_ruby)|
      # Intelligent API that does automatic dereference
      define_method(member) do
        value = self[member]
        if value.respond_to?(:*)
          value = value.*
        end
        if to_ruby
          value = C.to_ruby(value)
        end
        value
      end

      define_method("#{member}=") do |value|
        if to_ruby
          value = C.to_value(value)
        end
        self[member] = value
      end
    end
  end
end

Public Instance Methods

-(struct) click to toggle source

Pointer diff

# File ruby_vm/rjit/c_pointer.rb, line 28
def -(struct)
  raise ArgumentError if self.class != struct.class
  (@addr - struct.to_i) / @sizeof
end
[](member) click to toggle source

Primitive API that does no automatic dereference TODO: remove this? @param member [Symbol]

# File ruby_vm/rjit/c_pointer.rb, line 36
def [](member)
  type, offset = @members.fetch(member)
  type.new(@addr + offset / 8)
end
to_i() click to toggle source

Get a raw address

# File ruby_vm/rjit/c_pointer.rb, line 18
def to_i
  @addr
end
to_s() click to toggle source

Serialized address for generated code

# File ruby_vm/rjit/c_pointer.rb, line 23
def to_s
  "0x#{@addr.to_s(16)}"
end

Private Instance Methods

[]=(member, value) click to toggle source

@param member [Symbol] @param value [Object]

# File ruby_vm/rjit/c_pointer.rb, line 45
def []=(member, value)
  type, offset = @members.fetch(member)
  type[@addr + offset / 8] = value
end