Class: RubyVM::RJIT::CPointer::Struct

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 and to_s are considered an exception.

Class Method Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(addr, sizeof, members) ⇒ Struct

Returns a new instance of Struct.

Parameters:

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


11
12
13
14
15
# File 'lib/ruby_vm/rjit/c_pointer.rb', line 11

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

Class Method Details

.define(size, members) ⇒ Object

Parameters:

  • size (Integer)
  • members (Hash{ Symbol => [Integer, RubyVM::RJIT::CType::*] })


52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
# File 'lib/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

Instance Method Details

#-(struct) ⇒ Object

Pointer diff

Raises:

  • (ArgumentError)


28
29
30
31
# File 'lib/ruby_vm/rjit/c_pointer.rb', line 28

def -(struct)
  raise ArgumentError if self.class != struct.class
  (@addr - struct.to_i) / @sizeof
end

#[](member) ⇒ Object

Primitive API that does no automatic dereference TODO: remove this?

Parameters:

  • member (Symbol)


36
37
38
39
# File 'lib/ruby_vm/rjit/c_pointer.rb', line 36

def [](member)
  type, offset = @members.fetch(member)
  type.new(@addr + offset / 8)
end

#to_i ⇒ Object

Get a raw address



18
19
20
# File 'lib/ruby_vm/rjit/c_pointer.rb', line 18

def to_i
  @addr
end

#to_s ⇒ Object

Serialized address for generated code



23
24
25
# File 'lib/ruby_vm/rjit/c_pointer.rb', line 23

def to_s
  "0x#{@addr.to_s(16)}"
end