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
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
# An abstraction for a fixed-length array type.
#
# Example usage:
#
# array_type = JIT::Array.new(JIT::Type::INT, 4)
#
# JIT::Context.build do |context|
# signature = JIT::Type.create_signature(
# JIT::ABI::CDECL, JIT::Type::INT, [ ])
#
# function = JIT::Function.compile(context, signature) do |f|
# array_instance = array_type.create(f)
# array_instance[0] = f.const(JIT::Type::INT, 42)
# f.insn_return(array_instance[0])
# end
#
# end
#
attr_reader :type
attr_reader :length
# Create a new JIT array type.
#
# +type+:: The type of the elements in the array.
# +length+:: The number of elements in the array.
#
array = self.create_struct([ type ] * length)
array.instance_eval do
@type = type
@length = length
end
return array
end
# Wrap an existing array.
#
# +ptr+:: A pointer to the first element in the array.
#
return Instance.wrap(self, ptr)
end
# Create a new array.
#
# +function+:: The JIT::Function this array will be used in.
#
instance = function.value(self)
ptr = function.insn_address_of(instance)
return wrap(ptr)
end
# Return the offset (in bytes) of the element at the given +index+.
#
# +index+:: The index of the desired element.
#
return self.get_offset(index)
end
# Return the type of the element at the given +index+.
#
# +index+:: The index of the desired element.
#
return @type
end
# An abstraction for an instance of a fixed-length array.
#
attr_reader :array_type
attr_reader :type
# A pointer to the first element of the array. Note that this
# differs from +address+, which returns the address of a pointer
# to the array.
attr_reader :ptr
# TODO: This breaks code below?
# attr_reader :function
# Wrap an existing array.
#
# +array_type+:: The JIT::Array type to wrap.
# +ptr+:: A pointer to the first element in the array.
#
pointer_type = JIT::Type.create_pointer(array_type)
value = self.new_value(ptr.function, pointer_type)
value.store(ptr)
value.instance_eval do
@array_type = array_type
@type = array_type.type
@function = ptr.function
@ptr = ptr
end
return value
end
# Generate JIT code to retrieve the element at the given +index+.
#
# +index+:: The index of the desired element. The value of the
# index must be known at compile-time.
#
@function.insn_load_relative(
@ptr,
@array_type.offset_of(index),
@array_type.type_of(index))
end
# Generate JIT code to assign to the element at the given +index+.
#
# +index+:: The index of the desired element. The value of the
# index must be known at compile-time.
# +value+:: The JIT::Value to assign to the element.
#
@function.insn_store_relative(
@ptr,
@array_type.offset_of(index),
value)
end
end
end
end