lldb 0.1.0 → 0.3.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (66) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +47 -3
  3. data/README.md +86 -2
  4. data/Rakefile +36 -0
  5. data/bindings/constants.yml +137 -0
  6. data/bindings/surface.yml +3072 -0
  7. data/ext/lldb/discovery.rb +101 -0
  8. data/ext/lldb/extconf.rb +206 -88
  9. data/ext/lldb/lldb_wrapper.cpp +7977 -856
  10. data/ext/lldb/lldb_wrapper.h +599 -324
  11. data/lib/lldb/address.rb +81 -0
  12. data/lib/lldb/api_support.rb +91 -0
  13. data/lib/lldb/attach_info.rb +122 -0
  14. data/lib/lldb/block.rb +121 -0
  15. data/lib/lldb/breakpoint.rb +11 -6
  16. data/lib/lldb/breakpoint_location.rb +20 -5
  17. data/lib/lldb/broadcaster.rb +79 -0
  18. data/lib/lldb/command_interpreter.rb +9 -4
  19. data/lib/lldb/command_return_object.rb +24 -5
  20. data/lib/lldb/compile_unit.rb +64 -0
  21. data/lib/lldb/context.rb +81 -0
  22. data/lib/lldb/debugger.rb +55 -12
  23. data/lib/lldb/error.rb +51 -3
  24. data/lib/lldb/event.rb +109 -0
  25. data/lib/lldb/expression_options.rb +124 -0
  26. data/lib/lldb/ffi_bindings.rb +326 -31
  27. data/lib/lldb/file_spec.rb +90 -0
  28. data/lib/lldb/file_spec_list.rb +78 -0
  29. data/lib/lldb/frame.rb +113 -18
  30. data/lib/lldb/function.rb +121 -0
  31. data/lib/lldb/instruction.rb +83 -0
  32. data/lib/lldb/instruction_list.rb +68 -0
  33. data/lib/lldb/launch_info.rb +145 -19
  34. data/lib/lldb/line_entry.rb +75 -0
  35. data/lib/lldb/listener.rb +96 -0
  36. data/lib/lldb/memory_region_info.rb +109 -0
  37. data/lib/lldb/module.rb +46 -5
  38. data/lib/lldb/native.rb +36 -0
  39. data/lib/lldb/native_buffer.rb +32 -0
  40. data/lib/lldb/native_handle.rb +60 -0
  41. data/lib/lldb/native_lifecycle.rb +64 -0
  42. data/lib/lldb/native_string_array.rb +34 -0
  43. data/lib/lldb/process.rb +121 -38
  44. data/lib/lldb/symbol.rb +117 -0
  45. data/lib/lldb/symbol_context.rb +9 -4
  46. data/lib/lldb/target.rb +73 -67
  47. data/lib/lldb/thread.rb +56 -19
  48. data/lib/lldb/type.rb +40 -3
  49. data/lib/lldb/type_member.rb +67 -0
  50. data/lib/lldb/types.rb +69 -4
  51. data/lib/lldb/value.rb +27 -17
  52. data/lib/lldb/value_list.rb +9 -5
  53. data/lib/lldb/version.rb +1 -1
  54. data/lib/lldb/watchpoint.rb +26 -9
  55. data/lib/lldb.rb +80 -10
  56. data/lldb.gemspec +4 -1
  57. data/rbs_collection.yaml +1 -1
  58. data/script/check_bindings +259 -0
  59. data/script/guard_c_exports +139 -0
  60. data/sig/lldb/ffi_bindings.rbs +258 -21
  61. data/sig/lldb/weak_ref.rbs +7 -0
  62. metadata +32 -6
  63. data/ext/lldb/Makefile +0 -24
  64. data/ext/lldb/liblldb_wrapper.dylib +0 -0
  65. data/ext/lldb/lldb_wrapper.o +0 -0
  66. data/ext/lldb/mkmf.log +0 -24
@@ -0,0 +1,78 @@
1
+ # frozen_string_literal: true
2
+
3
+ # rbs_inline: enabled
4
+
5
+ module LLDB
6
+ class FileSpecList
7
+ prepend NativeLifecycle
8
+
9
+ # @rbs context: Context?
10
+ # @rbs return: void
11
+ def initialize(context: nil)
12
+ initialize_native_object(
13
+ FFIBindings.lldb_file_spec_list_create,
14
+ release: ->(released) { FFIBindings.lldb_file_spec_list_destroy(released) },
15
+ context: context
16
+ )
17
+ end
18
+
19
+ # @rbs return: bool
20
+ def valid?
21
+ !@ptr.null? && FFIBindings.lldb_file_spec_list_is_valid(@ptr) != 0
22
+ end
23
+
24
+ # @rbs return: Integer
25
+ def size
26
+ return 0 unless valid?
27
+
28
+ FFIBindings.lldb_file_spec_list_get_size(@ptr)
29
+ end
30
+
31
+ alias length size
32
+
33
+ # @rbs file_spec: FileSpec
34
+ # @rbs return: void
35
+ def append(file_spec)
36
+ ensure_open!
37
+ raise ArgumentError, 'file_spec must be a FileSpec' unless file_spec.is_a?(FileSpec)
38
+
39
+ FFIBindings.lldb_file_spec_list_append(@ptr, file_spec.to_ptr)
40
+ end
41
+
42
+ # @rbs file_spec: FileSpec
43
+ # @rbs return: bool
44
+ def append_if_unique(file_spec)
45
+ ensure_open!
46
+ raise ArgumentError, 'file_spec must be a FileSpec' unless file_spec.is_a?(FileSpec)
47
+
48
+ FFIBindings.lldb_file_spec_list_append_if_unique(@ptr, file_spec.to_ptr) != 0
49
+ end
50
+
51
+ # @rbs return: void
52
+ def clear
53
+ ensure_open!
54
+ FFIBindings.lldb_file_spec_list_clear(@ptr)
55
+ end
56
+
57
+ # @rbs index: Integer
58
+ # @rbs return: FileSpec?
59
+ def [](index)
60
+ return nil unless valid?
61
+
62
+ ptr = FFIBindings.lldb_file_spec_list_get_file_spec_at_index(@ptr, index)
63
+ return nil if ptr.nil? || ptr.null?
64
+
65
+ FileSpec.from_ptr(ptr, context: context)
66
+ end
67
+
68
+ # @rbs return: Array[FileSpec]
69
+ def to_a
70
+ (0...size).map { |index| self[index] }.compact
71
+ end
72
+
73
+ # @rbs return: FFI::Pointer
74
+ def to_ptr
75
+ @ptr
76
+ end
77
+ end
78
+ end
data/lib/lldb/frame.rb CHANGED
@@ -4,16 +4,21 @@
4
4
 
5
5
  module LLDB
6
6
  class Frame
7
+ prepend NativeLifecycle
8
+
7
9
  # @rbs return: Thread
8
10
  attr_reader :thread
9
11
 
10
12
  # @rbs ptr: FFI::Pointer
11
13
  # @rbs thread: Thread
12
14
  # @rbs return: void
13
- def initialize(ptr, thread:)
14
- @ptr = ptr # : FFI::Pointer
15
+ def initialize(ptr, thread:, context: thread.context)
15
16
  @thread = thread
16
- ObjectSpace.define_finalizer(self, self.class.release(@ptr))
17
+ initialize_native_object(
18
+ ptr,
19
+ release: ->(released) { FFIBindings.lldb_frame_destroy(released) },
20
+ context: context
21
+ )
17
22
  end
18
23
 
19
24
  # @rbs ptr: FFI::Pointer
@@ -52,7 +57,68 @@ module LLDB
52
57
  def file_path
53
58
  raise InvalidObjectError, 'Frame is not valid' unless valid?
54
59
 
55
- FFIBindings.lldb_frame_get_file_path(@ptr)
60
+ file_spec&.path
61
+ end
62
+
63
+ # @rbs return: FileSpec?
64
+ def file_spec
65
+ raise InvalidObjectError, 'Frame is not valid' unless valid?
66
+
67
+ file_ptr = FFIBindings.lldb_frame_get_file_spec(@ptr)
68
+ return nil if file_ptr.nil? || file_ptr.null?
69
+
70
+ FileSpec.from_ptr(file_ptr, context: context)
71
+ end
72
+
73
+ # @rbs return: LineEntry?
74
+ def line_entry
75
+ raise InvalidObjectError, 'Frame is not valid' unless valid?
76
+
77
+ line_ptr = FFIBindings.lldb_frame_get_line_entry(@ptr)
78
+ return nil if line_ptr.nil? || line_ptr.null?
79
+
80
+ target = @thread.process.target
81
+ LineEntry.new(line_ptr, target: target, context: context)
82
+ end
83
+
84
+ # @rbs return: Function?
85
+ def function
86
+ raise InvalidObjectError, 'Frame is not valid' unless valid?
87
+
88
+ function_ptr = FFIBindings.lldb_frame_get_function(@ptr)
89
+ return nil if function_ptr.nil? || function_ptr.null?
90
+
91
+ Function.new(function_ptr, target: @thread.process.target, context: context)
92
+ end
93
+
94
+ # @rbs return: Symbol?
95
+ def symbol
96
+ raise InvalidObjectError, 'Frame is not valid' unless valid?
97
+
98
+ symbol_ptr = FFIBindings.lldb_frame_get_symbol(@ptr)
99
+ return nil if symbol_ptr.nil? || symbol_ptr.null?
100
+
101
+ Symbol.new(symbol_ptr, target: @thread.process.target, context: context)
102
+ end
103
+
104
+ # @rbs return: CompileUnit?
105
+ def compile_unit
106
+ raise InvalidObjectError, 'Frame is not valid' unless valid?
107
+
108
+ unit_ptr = FFIBindings.lldb_frame_get_compile_unit(@ptr)
109
+ return nil if unit_ptr.nil? || unit_ptr.null?
110
+
111
+ CompileUnit.new(unit_ptr, target: @thread.process.target, context: context)
112
+ end
113
+
114
+ # @rbs return: Block?
115
+ def block
116
+ raise InvalidObjectError, 'Frame is not valid' unless valid?
117
+
118
+ block_ptr = FFIBindings.lldb_frame_get_block(@ptr)
119
+ return nil if block_ptr.nil? || block_ptr.null?
120
+
121
+ Block.new(block_ptr, target: @thread.process.target, context: context)
56
122
  end
57
123
 
58
124
  # @rbs return: Integer
@@ -64,21 +130,21 @@ module LLDB
64
130
 
65
131
  # @rbs return: Integer
66
132
  def pc
67
- return 0 unless valid?
133
+ return INVALID_ADDRESS unless valid?
68
134
 
69
135
  FFIBindings.lldb_frame_get_pc(@ptr)
70
136
  end
71
137
 
72
138
  # @rbs return: Integer
73
139
  def sp
74
- return 0 unless valid?
140
+ return INVALID_ADDRESS unless valid?
75
141
 
76
142
  FFIBindings.lldb_frame_get_sp(@ptr)
77
143
  end
78
144
 
79
145
  # @rbs return: Integer
80
146
  def fp
81
- return 0 unless valid?
147
+ return INVALID_ADDRESS unless valid?
82
148
 
83
149
  FFIBindings.lldb_frame_get_fp(@ptr)
84
150
  end
@@ -96,22 +162,35 @@ module LLDB
96
162
  # @rbs return: Value?
97
163
  def find_variable(name)
98
164
  raise InvalidObjectError, 'Frame is not valid' unless valid?
165
+ APISupport.require_method!(:lldb_frame_find_variable, 'find_variable')
99
166
 
100
167
  value_ptr = FFIBindings.lldb_frame_find_variable(@ptr, name)
101
168
  return nil if value_ptr.nil? || value_ptr.null?
102
169
 
103
- Value.new(value_ptr, parent: self)
170
+ Value.new(value_ptr, parent: self, context: context)
104
171
  end
105
172
 
106
173
  # @rbs expression: String
174
+ # @rbs options: ExpressionOptions?
107
175
  # @rbs return: Value?
108
- def evaluate_expression(expression)
176
+ def evaluate_expression(expression, options: nil)
109
177
  raise InvalidObjectError, 'Frame is not valid' unless valid?
110
-
111
- value_ptr = FFIBindings.lldb_frame_evaluate_expression(@ptr, expression)
178
+ APISupport.require_method!(:lldb_frame_evaluate_expression, 'evaluate_expression')
179
+
180
+ value_ptr = if options
181
+ unless options.is_a?(ExpressionOptions)
182
+ raise ArgumentError, 'options must be an ExpressionOptions'
183
+ end
184
+
185
+ FFIBindings.lldb_frame_evaluate_expression_with_options(
186
+ @ptr, expression, options.to_ptr
187
+ )
188
+ else
189
+ FFIBindings.lldb_frame_evaluate_expression(@ptr, expression)
190
+ end
112
191
  return nil if value_ptr.nil? || value_ptr.null?
113
192
 
114
- Value.new(value_ptr, parent: self)
193
+ Value.new(value_ptr, parent: self, context: context)
115
194
  end
116
195
 
117
196
  # @rbs path: String
@@ -122,7 +201,7 @@ module LLDB
122
201
  value_ptr = FFIBindings.lldb_frame_get_value_for_variable_path(@ptr, path)
123
202
  return nil if value_ptr.nil? || value_ptr.null?
124
203
 
125
- Value.new(value_ptr, parent: self)
204
+ Value.new(value_ptr, parent: self, context: context)
126
205
  end
127
206
 
128
207
  # @rbs scope: Integer
@@ -133,7 +212,7 @@ module LLDB
133
212
  ctx_ptr = FFIBindings.lldb_frame_get_symbol_context(@ptr, scope)
134
213
  return nil if ctx_ptr.nil? || ctx_ptr.null?
135
214
 
136
- SymbolContext.new(ctx_ptr, parent: self)
215
+ SymbolContext.new(ctx_ptr, parent: self, context: context)
137
216
  end
138
217
 
139
218
  # @rbs return: String
@@ -171,17 +250,18 @@ module LLDB
171
250
  )
172
251
  raise LLDBError, 'Failed to get variables' if list_ptr.nil? || list_ptr.null?
173
252
 
174
- ValueList.new(list_ptr, parent: self)
253
+ ValueList.new(list_ptr, parent: self, context: context)
175
254
  end
176
255
 
177
256
  # @rbs return: ValueList
178
257
  def get_registers
179
258
  raise InvalidObjectError, 'Frame is not valid' unless valid?
259
+ APISupport.require_method!(:lldb_frame_get_registers, 'get_registers')
180
260
 
181
261
  list_ptr = FFIBindings.lldb_frame_get_registers(@ptr)
182
262
  raise LLDBError, 'Failed to get registers' if list_ptr.nil? || list_ptr.null?
183
263
 
184
- ValueList.new(list_ptr, parent: self)
264
+ ValueList.new(list_ptr, parent: self, context: context)
185
265
  end
186
266
 
187
267
  # @rbs return: bool
@@ -198,6 +278,21 @@ module LLDB
198
278
  FFIBindings.lldb_frame_disassemble(@ptr)
199
279
  end
200
280
 
281
+ # @rbs return: InstructionList?
282
+ def instruction_list
283
+ raise InvalidObjectError, 'Frame is not valid' unless valid?
284
+
285
+ target = @thread.process.target
286
+ return nil unless target
287
+
288
+ list_ptr = FFIBindings.lldb_frame_get_instruction_list(@ptr, target.to_ptr)
289
+ return nil if list_ptr.nil? || list_ptr.null?
290
+
291
+ InstructionList.new(list_ptr, target: target, context: context)
292
+ end
293
+
294
+ alias instructions instruction_list
295
+
201
296
  # @rbs return: Module?
202
297
  def get_module
203
298
  raise InvalidObjectError, 'Frame is not valid' unless valid?
@@ -205,7 +300,7 @@ module LLDB
205
300
  mod_ptr = FFIBindings.lldb_frame_get_module(@ptr)
206
301
  return nil if mod_ptr.nil? || mod_ptr.null?
207
302
 
208
- Module.new(mod_ptr, target: @thread.process.target)
303
+ Module.new(mod_ptr, target: @thread.process.target, context: context)
209
304
  end
210
305
 
211
306
  # @rbs return: Thread?
@@ -215,7 +310,7 @@ module LLDB
215
310
  thread_ptr = FFIBindings.lldb_frame_get_thread(@ptr)
216
311
  return nil if thread_ptr.nil? || thread_ptr.null?
217
312
 
218
- Thread.new(thread_ptr, process: @thread.process)
313
+ Thread.new(thread_ptr, process: @thread.process, context: context)
219
314
  end
220
315
 
221
316
  # @rbs return: FFI::Pointer
@@ -0,0 +1,121 @@
1
+ # frozen_string_literal: true
2
+
3
+ # rbs_inline: enabled
4
+
5
+ module LLDB
6
+ class Function
7
+ prepend NativeLifecycle
8
+
9
+ # @rbs target: Target?
10
+ # @rbs context: Context?
11
+ # @rbs return: void
12
+ def initialize(ptr, target: nil, context: nil)
13
+ @target = target
14
+ initialize_native_object(
15
+ ptr,
16
+ release: ->(released) { FFIBindings.lldb_function_destroy(released) },
17
+ context: context || target&.context
18
+ )
19
+ end
20
+
21
+ # @rbs return: bool
22
+ def valid?
23
+ !@ptr.null? && FFIBindings.lldb_function_is_valid(@ptr) != 0
24
+ end
25
+
26
+ # @rbs return: String?
27
+ def name
28
+ return nil unless valid?
29
+
30
+ FFIBindings.lldb_function_get_name(@ptr)
31
+ end
32
+
33
+ # @rbs return: String?
34
+ def display_name
35
+ return nil unless valid?
36
+
37
+ FFIBindings.lldb_function_get_display_name(@ptr)
38
+ end
39
+
40
+ # @rbs return: String?
41
+ def mangled_name
42
+ return nil unless valid?
43
+
44
+ FFIBindings.lldb_function_get_mangled_name(@ptr)
45
+ end
46
+
47
+ # @rbs return: String?
48
+ def base_name
49
+ return nil unless valid?
50
+
51
+ FFIBindings.lldb_function_get_base_name(@ptr)
52
+ end
53
+
54
+ # @rbs return: Address?
55
+ def start_address
56
+ address_at(:lldb_function_get_start_address)
57
+ end
58
+
59
+ # @rbs return: Address?
60
+ def end_address
61
+ address_at(:lldb_function_get_end_address)
62
+ end
63
+
64
+ # @rbs return: Integer
65
+ def prologue_byte_size
66
+ return 0 unless valid?
67
+
68
+ FFIBindings.lldb_function_get_prologue_byte_size(@ptr)
69
+ end
70
+
71
+ # @rbs return: Type?
72
+ def type
73
+ return nil unless valid?
74
+
75
+ ptr = FFIBindings.lldb_function_get_type(@ptr)
76
+ return nil if ptr.nil? || ptr.null?
77
+
78
+ Type.new(ptr, context: context)
79
+ end
80
+
81
+ # @rbs return: Block?
82
+ def block
83
+ return nil unless valid?
84
+
85
+ ptr = FFIBindings.lldb_function_get_block(@ptr)
86
+ return nil if ptr.nil? || ptr.null?
87
+
88
+ Block.new(ptr, target: @target, context: context)
89
+ end
90
+
91
+ # @rbs return: bool
92
+ def optimized?
93
+ valid? && FFIBindings.lldb_function_is_optimized(@ptr) != 0
94
+ end
95
+
96
+ # @rbs return: Integer
97
+ def language
98
+ return 0 unless valid?
99
+
100
+ FFIBindings.lldb_function_get_language(@ptr)
101
+ end
102
+
103
+ # @rbs return: FFI::Pointer
104
+ def to_ptr
105
+ @ptr
106
+ end
107
+
108
+ private
109
+
110
+ # @rbs method_name: ::Symbol
111
+ # @rbs return: Address?
112
+ def address_at(method_name)
113
+ return nil unless valid?
114
+
115
+ ptr = FFIBindings.public_send(method_name, @ptr)
116
+ return nil if ptr.nil? || ptr.null?
117
+
118
+ Address.from_ptr(ptr, target: @target, context: context)
119
+ end
120
+ end
121
+ end
@@ -0,0 +1,83 @@
1
+ # frozen_string_literal: true
2
+
3
+ # rbs_inline: enabled
4
+
5
+ module LLDB
6
+ class Instruction
7
+ prepend NativeLifecycle
8
+
9
+ # @rbs target: Target?
10
+ # @rbs context: Context?
11
+ # @rbs return: void
12
+ def initialize(ptr, target: nil, context: nil)
13
+ @target = target
14
+ initialize_native_object(
15
+ ptr,
16
+ release: ->(released) { FFIBindings.lldb_instruction_destroy(released) },
17
+ context: context || target&.context
18
+ )
19
+ end
20
+
21
+ # @rbs return: bool
22
+ def valid?
23
+ !@ptr.null? && FFIBindings.lldb_instruction_is_valid(@ptr) != 0
24
+ end
25
+
26
+ # @rbs return: Address?
27
+ def address
28
+ return nil unless valid?
29
+
30
+ ptr = FFIBindings.lldb_instruction_get_address(@ptr)
31
+ return nil if ptr.nil? || ptr.null?
32
+
33
+ Address.from_ptr(ptr, target: @target, context: context)
34
+ end
35
+
36
+ # @rbs return: String?
37
+ def mnemonic
38
+ return nil unless valid? && @target
39
+
40
+ FFIBindings.lldb_instruction_get_mnemonic(@ptr, @target.to_ptr)
41
+ end
42
+
43
+ # @rbs return: String?
44
+ def operands
45
+ return nil unless valid? && @target
46
+
47
+ FFIBindings.lldb_instruction_get_operands(@ptr, @target.to_ptr)
48
+ end
49
+
50
+ # @rbs return: String?
51
+ def comment
52
+ return nil unless valid? && @target
53
+
54
+ FFIBindings.lldb_instruction_get_comment(@ptr, @target.to_ptr)
55
+ end
56
+
57
+ # @rbs return: Integer
58
+ def byte_size
59
+ return 0 unless valid?
60
+
61
+ FFIBindings.lldb_instruction_get_byte_size(@ptr)
62
+ end
63
+
64
+ # @rbs return: String
65
+ def bytes
66
+ return ''.b unless valid? && @target
67
+
68
+ length = byte_size
69
+ return ''.b if length.zero?
70
+
71
+ buffer = FFI::MemoryPointer.new(:uint8, length)
72
+ written = FFIBindings.lldb_instruction_get_bytes(
73
+ @ptr, @target.to_ptr, buffer, length
74
+ )
75
+ buffer.get_bytes(0, [written, length].min).b
76
+ end
77
+
78
+ # @rbs return: FFI::Pointer
79
+ def to_ptr
80
+ @ptr
81
+ end
82
+ end
83
+ end
@@ -0,0 +1,68 @@
1
+ # frozen_string_literal: true
2
+
3
+ # rbs_inline: enabled
4
+
5
+ module LLDB
6
+ class InstructionList
7
+ prepend NativeLifecycle
8
+ include Enumerable #[Instruction]
9
+
10
+ # @rbs target: Target?
11
+ # @rbs context: Context?
12
+ # @rbs return: void
13
+ def initialize(ptr, target: nil, context: nil)
14
+ @target = target
15
+ initialize_native_object(
16
+ ptr,
17
+ release: ->(released) { FFIBindings.lldb_instruction_list_destroy(released) },
18
+ context: context || target&.context
19
+ )
20
+ end
21
+
22
+ # @rbs return: bool
23
+ def valid?
24
+ !@ptr.null? && FFIBindings.lldb_instruction_list_is_valid(@ptr) != 0
25
+ end
26
+
27
+ # @rbs return: Integer
28
+ def size
29
+ return 0 unless valid?
30
+
31
+ FFIBindings.lldb_instruction_list_get_size(@ptr)
32
+ end
33
+
34
+ alias length size
35
+
36
+ # @rbs index: Integer
37
+ # @rbs return: Instruction?
38
+ def [](index)
39
+ return nil unless valid?
40
+
41
+ ptr = FFIBindings.lldb_instruction_list_get_instruction_at_index(@ptr, index)
42
+ return nil if ptr.nil? || ptr.null?
43
+
44
+ Instruction.new(ptr, target: @target, context: context)
45
+ end
46
+
47
+ # @rbs &block: (Instruction) -> void
48
+ # @rbs return: Enumerator[Instruction, void] | void
49
+ def each(&block)
50
+ return enum_for(:each) unless block_given?
51
+
52
+ (0...size).each do |index|
53
+ instruction = self[index]
54
+ block.call(instruction) if instruction
55
+ end
56
+ end
57
+
58
+ # @rbs return: Array[Instruction]
59
+ def to_a
60
+ (0...size).map { |index| self[index] }.compact
61
+ end
62
+
63
+ # @rbs return: FFI::Pointer
64
+ def to_ptr
65
+ @ptr
66
+ end
67
+ end
68
+ end