class RubyVM::RJIT::CPointer::Struct

注意:我们希望避免使用字母方法名称,以避免与成员方法冲突。to_ito_s 被认为是例外。

公共类方法

new(addr, sizeof, members) 点击以切换源

@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

私有类方法

define(size, members) 点击以切换源

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

调用父类方法
# 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

公共实例方法

-(struct) 点击以切换源

Pointer 差异

# 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) 点击以切换源

不进行自动解引用的原始 API。TODO:删除此项?@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() 点击以切换源

获取原始地址

# File ruby_vm/rjit/c_pointer.rb, line 18
def to_i
  @addr
end
to_s() 点击以切换源

为生成的代码序列化地址

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

私有实例方法

[]=(member, value) 点击以切换源

@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