-
Notifications
You must be signed in to change notification settings - Fork 5.4k
/
Copy pathc_type.rb
99 lines (87 loc) · 2.65 KB
/
c_type.rb
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
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
99
require 'fiddle'
require 'fiddle/pack'
require_relative 'c_pointer'
module RubyVM::RJIT
module CType
module Struct
# @param name [String]
# @param members [Hash{ Symbol => [Integer, RubyVM::RJIT::CType::*] }]
def self.new(name, sizeof, **members)
name = members.keys.join('_') if name.empty?
CPointer.with_class_name('Struct', name) do
CPointer::Struct.define(sizeof, members)
end
end
end
module Union
# @param name [String]
# @param members [Hash{ Symbol => RubyVM::RJIT::CType::* }]
def self.new(name, sizeof, **members)
name = members.keys.join('_') if name.empty?
CPointer.with_class_name('Union', name) do
CPointer::Union.define(sizeof, members)
end
end
end
module Immediate
# @param fiddle_type [Integer]
def self.new(fiddle_type)
name = Fiddle.constants.find do |const|
const.start_with?('TYPE_') && Fiddle.const_get(const) == fiddle_type.abs
end&.to_s
name.delete_prefix!('TYPE_')
if fiddle_type.negative?
name.prepend('U')
end
CPointer.with_class_name('Immediate', name, cache: true) do
CPointer::Immediate.define(fiddle_type)
end
end
# @param type [String]
def self.parse(ctype)
new(Fiddle::Importer.parse_ctype(ctype))
end
def self.find(size, signed)
fiddle_type = TYPE_MAP.fetch(size)
fiddle_type = -fiddle_type unless signed
new(fiddle_type)
end
TYPE_MAP = Fiddle::PackInfo::SIZE_MAP.map { |type, size| [size, type.abs] }.to_h
private_constant :TYPE_MAP
end
module Bool
def self.new
CPointer::Bool
end
end
class Array
def self.new(&block)
CPointer.with_class_name('Array', block.object_id.to_s) do
CPointer::Array.define(block)
end
end
end
class Pointer
# This takes a block to avoid "stack level too deep" on a cyclic reference
# @param block [Proc]
def self.new(&block)
CPointer.with_class_name('Pointer', block.object_id.to_s) do
CPointer::Pointer.define(block)
end
end
end
module BitField
# @param width [Integer]
# @param offset [Integer]
def self.new(width, offset)
CPointer.with_class_name('BitField', "#{offset}_#{width}") do
CPointer::BitField.define(width, offset)
end
end
end
# Types that are referenced but not part of code generation targets
Stub = ::Struct.new(:name)
# Types that it failed to figure out from the header
Unknown = Module.new
end
end