crystalruby 0.2.3 → 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.
- checksums.yaml +4 -4
- data/CHANGELOG.md +2 -0
- data/README.md +389 -193
- data/Rakefile +4 -3
- data/crystalruby.gemspec +2 -2
- data/exe/crystalruby +1 -0
- data/lib/crystalruby/adapter.rb +131 -65
- data/lib/crystalruby/arc_mutex.rb +47 -0
- data/lib/crystalruby/compilation.rb +32 -3
- data/lib/crystalruby/config.rb +41 -37
- data/lib/crystalruby/function.rb +211 -68
- data/lib/crystalruby/library.rb +153 -48
- data/lib/crystalruby/reactor.rb +40 -23
- data/lib/crystalruby/source_reader.rb +86 -0
- data/lib/crystalruby/template.rb +16 -5
- data/lib/crystalruby/templates/function.cr +11 -10
- data/lib/crystalruby/templates/index.cr +53 -66
- data/lib/crystalruby/templates/inline_chunk.cr +1 -1
- data/lib/crystalruby/templates/ruby_interface.cr +34 -0
- data/lib/crystalruby/templates/top_level_function.cr +62 -0
- data/lib/crystalruby/templates/top_level_ruby_interface.cr +33 -0
- data/lib/crystalruby/typebuilder.rb +11 -55
- data/lib/crystalruby/typemaps.rb +92 -67
- data/lib/crystalruby/types/concerns/allocator.rb +80 -0
- data/lib/crystalruby/types/fixed_width/named_tuple.cr +80 -0
- data/lib/crystalruby/types/fixed_width/named_tuple.rb +86 -0
- data/lib/crystalruby/types/fixed_width/proc.cr +45 -0
- data/lib/crystalruby/types/fixed_width/proc.rb +79 -0
- data/lib/crystalruby/types/fixed_width/tagged_union.cr +53 -0
- data/lib/crystalruby/types/fixed_width/tagged_union.rb +109 -0
- data/lib/crystalruby/types/fixed_width/tuple.cr +82 -0
- data/lib/crystalruby/types/fixed_width/tuple.rb +92 -0
- data/lib/crystalruby/types/fixed_width.cr +138 -0
- data/lib/crystalruby/types/fixed_width.rb +205 -0
- data/lib/crystalruby/types/primitive.cr +21 -0
- data/lib/crystalruby/types/primitive.rb +117 -0
- data/lib/crystalruby/types/primitive_types/bool.cr +34 -0
- data/lib/crystalruby/types/primitive_types/bool.rb +11 -0
- data/lib/crystalruby/types/primitive_types/nil.cr +35 -0
- data/lib/crystalruby/types/primitive_types/nil.rb +16 -0
- data/lib/crystalruby/types/primitive_types/numbers.cr +37 -0
- data/lib/crystalruby/types/primitive_types/numbers.rb +28 -0
- data/lib/crystalruby/types/primitive_types/symbol.cr +55 -0
- data/lib/crystalruby/types/primitive_types/symbol.rb +35 -0
- data/lib/crystalruby/types/primitive_types/time.cr +35 -0
- data/lib/crystalruby/types/primitive_types/time.rb +25 -0
- data/lib/crystalruby/types/type.cr +64 -0
- data/lib/crystalruby/types/type.rb +239 -30
- data/lib/crystalruby/types/variable_width/array.cr +74 -0
- data/lib/crystalruby/types/variable_width/array.rb +88 -0
- data/lib/crystalruby/types/variable_width/hash.cr +146 -0
- data/lib/crystalruby/types/variable_width/hash.rb +117 -0
- data/lib/crystalruby/types/variable_width/string.cr +36 -0
- data/lib/crystalruby/types/variable_width/string.rb +18 -0
- data/lib/crystalruby/types/variable_width.cr +23 -0
- data/lib/crystalruby/types/variable_width.rb +46 -0
- data/lib/crystalruby/types.rb +32 -13
- data/lib/crystalruby/version.rb +2 -2
- data/lib/crystalruby.rb +13 -6
- metadata +41 -19
- data/lib/crystalruby/types/array.rb +0 -15
- data/lib/crystalruby/types/bool.rb +0 -3
- data/lib/crystalruby/types/hash.rb +0 -17
- data/lib/crystalruby/types/named_tuple.rb +0 -28
- data/lib/crystalruby/types/nil.rb +0 -3
- data/lib/crystalruby/types/numbers.rb +0 -5
- data/lib/crystalruby/types/string.rb +0 -3
- data/lib/crystalruby/types/symbol.rb +0 -3
- data/lib/crystalruby/types/time.rb +0 -8
- data/lib/crystalruby/types/tuple.rb +0 -17
- data/lib/crystalruby/types/type_serializer/json.rb +0 -41
- data/lib/crystalruby/types/type_serializer.rb +0 -37
- data/lib/crystalruby/types/typedef.rb +0 -57
- data/lib/crystalruby/types/union_type.rb +0 -43
- data/lib/module.rb +0 -3
@@ -0,0 +1,117 @@
|
|
1
|
+
module CrystalRuby
|
2
|
+
module Types
|
3
|
+
class Primitive < Type
|
4
|
+
# Primitives just store the Ruby value directly
|
5
|
+
# (Or read it from memory if passed a pointer)
|
6
|
+
def initialize(rbval)
|
7
|
+
super(rbval)
|
8
|
+
self.value = rbval.is_a?(FFI::Pointer) ? rbval.send("read_#{ffi_type}") : rbval
|
9
|
+
end
|
10
|
+
|
11
|
+
# Read a value from a pointer at a given index
|
12
|
+
# (Type can be a byte-array, pointer or numeric type)
|
13
|
+
def self.fetch_single(pointer, native: false)
|
14
|
+
# Nothing to fetch for Nils
|
15
|
+
return if memsize.zero?
|
16
|
+
|
17
|
+
if numeric?
|
18
|
+
pointer.send("read_#{ffi_type}")
|
19
|
+
elsif primitive?
|
20
|
+
single = new(pointer.send("read_#{ffi_type}"))
|
21
|
+
if native
|
22
|
+
single.value
|
23
|
+
else
|
24
|
+
single
|
25
|
+
end
|
26
|
+
end
|
27
|
+
end
|
28
|
+
|
29
|
+
# Write a data type into a pointer at a given index
|
30
|
+
# (Type can be a byte-array, pointer or numeric type)
|
31
|
+
def self.write_single(pointer, value)
|
32
|
+
# Dont need to write nils
|
33
|
+
return if memsize.zero?
|
34
|
+
|
35
|
+
pointer.send("write_#{ffi_type}", to_ffi_repr(value))
|
36
|
+
end
|
37
|
+
|
38
|
+
# Fetch an array of a given data type from a list pointer
|
39
|
+
# (Type can be a byte-array, pointer or numeric type)
|
40
|
+
def self.fetch_multi(pointer, size, native: false)
|
41
|
+
if numeric?
|
42
|
+
pointer.send("get_array_of_#{ffi_type}", 0, size)
|
43
|
+
elsif primitive?
|
44
|
+
pointer.send("get_array_of_#{ffi_type}", 0, size).map(&method(:from_ffi_array_repr))
|
45
|
+
end
|
46
|
+
end
|
47
|
+
|
48
|
+
def self.decrement_ref_count!(pointer)
|
49
|
+
# Do nothing
|
50
|
+
end
|
51
|
+
|
52
|
+
# Define a new primitive type
|
53
|
+
# Primitive types are stored by value
|
54
|
+
# and efficiently copied using native FFI types
|
55
|
+
# They are written directly into the memory of a container type
|
56
|
+
# (No indirection)
|
57
|
+
def self.build(
|
58
|
+
typename = nil,
|
59
|
+
ffi_type: :uint8,
|
60
|
+
memsize: FFI.type_size(ffi_type),
|
61
|
+
convert_if: [],
|
62
|
+
error: nil,
|
63
|
+
superclass: Primitive,
|
64
|
+
&block
|
65
|
+
)
|
66
|
+
Class.new(superclass) do
|
67
|
+
%w[typename ffi_type memsize convert_if error].each do |name|
|
68
|
+
define_singleton_method(name) { binding.local_variable_get("#{name}") }
|
69
|
+
define_method(name) { binding.local_variable_get("#{name}") }
|
70
|
+
end
|
71
|
+
|
72
|
+
class_eval(&block) if block_given?
|
73
|
+
|
74
|
+
# Primitives are stored directly in memory as a raw numeric value
|
75
|
+
def self.to_ffi_repr(value)
|
76
|
+
new(value).inner_value
|
77
|
+
end
|
78
|
+
|
79
|
+
def self.refsize
|
80
|
+
memsize
|
81
|
+
end
|
82
|
+
|
83
|
+
# Primiives are anonymous (Shouldn't be subclassed)
|
84
|
+
def self.anonymous?
|
85
|
+
true
|
86
|
+
end
|
87
|
+
|
88
|
+
def self.copy_to!(rbval, memory:)
|
89
|
+
memory.send("write_#{self.ffi_type}", to_ffi_repr(rbval))
|
90
|
+
end
|
91
|
+
|
92
|
+
def self.primitive?
|
93
|
+
true
|
94
|
+
end
|
95
|
+
|
96
|
+
def self.inspect
|
97
|
+
inspect_name
|
98
|
+
end
|
99
|
+
|
100
|
+
def memory
|
101
|
+
@value
|
102
|
+
end
|
103
|
+
|
104
|
+
def self.crystal_supertype
|
105
|
+
"CrystalRuby::Types::Primitive"
|
106
|
+
end
|
107
|
+
end
|
108
|
+
end
|
109
|
+
end
|
110
|
+
end
|
111
|
+
end
|
112
|
+
|
113
|
+
require_relative "primitive_types/time"
|
114
|
+
require_relative "primitive_types/symbol"
|
115
|
+
require_relative "primitive_types/numbers"
|
116
|
+
require_relative "primitive_types/nil"
|
117
|
+
require_relative "primitive_types/bool"
|
@@ -0,0 +1,34 @@
|
|
1
|
+
class <%= base_crystal_class_name %> < CrystalRuby::Types::Primitive
|
2
|
+
|
3
|
+
def initialize(value : ::Bool)
|
4
|
+
@value = value ? 1_u8 : 0_u8
|
5
|
+
end
|
6
|
+
|
7
|
+
def initialize(ptr : Pointer(::UInt8))
|
8
|
+
@value = ptr[0]
|
9
|
+
end
|
10
|
+
|
11
|
+
def initialize(value : UInt8)
|
12
|
+
@value = value
|
13
|
+
end
|
14
|
+
|
15
|
+
def value=(value : ::Bool)
|
16
|
+
@value = value ? 1_u8 : 0_u8
|
17
|
+
end
|
18
|
+
|
19
|
+
def value : <%= native_type_expr %>
|
20
|
+
@value == 1_u8
|
21
|
+
end
|
22
|
+
|
23
|
+
def ==(other : ::Bool)
|
24
|
+
value == other
|
25
|
+
end
|
26
|
+
|
27
|
+
def self.memsize
|
28
|
+
<%= memsize %>
|
29
|
+
end
|
30
|
+
|
31
|
+
def self.write_single(pointer : Pointer(::UInt8), value)
|
32
|
+
pointer.as(Pointer(::UInt8)).value = value ? 1_u8 : 0_u8
|
33
|
+
end
|
34
|
+
end
|
@@ -0,0 +1,11 @@
|
|
1
|
+
module CrystalRuby::Types
|
2
|
+
Bool = Primitive.build(:Bool, convert_if: [::TrueClass, ::FalseClass], ffi_type: :uint8, memsize: 1) do
|
3
|
+
def value(native: false)
|
4
|
+
super == 1
|
5
|
+
end
|
6
|
+
|
7
|
+
def value=(val)
|
8
|
+
!!val && val != 0 ? super(1) : super(0)
|
9
|
+
end
|
10
|
+
end
|
11
|
+
end
|
@@ -0,0 +1,35 @@
|
|
1
|
+
class <%= base_crystal_class_name %> < CrystalRuby::Types::Primitive
|
2
|
+
|
3
|
+
property value : ::Nil = nil
|
4
|
+
|
5
|
+
def initialize(nilval : ::Nil)
|
6
|
+
end
|
7
|
+
|
8
|
+
def initialize(ptr : Pointer(::UInt8))
|
9
|
+
end
|
10
|
+
|
11
|
+
def initialize(raw : UInt8)
|
12
|
+
end
|
13
|
+
|
14
|
+
def value : ::Nil
|
15
|
+
nil
|
16
|
+
end
|
17
|
+
|
18
|
+
def ==(other : ::Nil)
|
19
|
+
value.nil?
|
20
|
+
end
|
21
|
+
|
22
|
+
def value=(val : ::Nil)
|
23
|
+
end
|
24
|
+
|
25
|
+
def self.memsize
|
26
|
+
0
|
27
|
+
end
|
28
|
+
|
29
|
+
def return_value
|
30
|
+
0_u8
|
31
|
+
end
|
32
|
+
|
33
|
+
def self.write_single(pointer : Pointer(::UInt8), value)
|
34
|
+
end
|
35
|
+
end
|
@@ -0,0 +1,37 @@
|
|
1
|
+
class <%= base_crystal_class_name %> < CrystalRuby::Types::Primitive
|
2
|
+
|
3
|
+
def initialize(value : <%= native_type_expr %>)
|
4
|
+
@value = value
|
5
|
+
end
|
6
|
+
|
7
|
+
def initialize(ptr : Pointer(::UInt8))
|
8
|
+
@value = ptr.as(Pointer( <%= native_type_expr %>))[0]
|
9
|
+
end
|
10
|
+
|
11
|
+
def value
|
12
|
+
@value
|
13
|
+
end
|
14
|
+
|
15
|
+
def ==(other : <%= native_type_expr %>)
|
16
|
+
value == other
|
17
|
+
end
|
18
|
+
|
19
|
+
def self.memsize
|
20
|
+
<%= memsize %>
|
21
|
+
end
|
22
|
+
|
23
|
+
def value=(value : <%= native_type_expr %>)
|
24
|
+
@value = value
|
25
|
+
end
|
26
|
+
|
27
|
+
def self.copy_to!(value : <%= native_type_expr %>, ptr : Pointer(::UInt8))
|
28
|
+
ptr.as(Pointer( <%= native_type_expr %>))[0] = value
|
29
|
+
end
|
30
|
+
|
31
|
+
# Write a data type into a pointer at a given index
|
32
|
+
# (Type can be a byte-array, pointer or numeric type)
|
33
|
+
def self.write_single(pointer : Pointer(::UInt8), value)
|
34
|
+
pointer.as(Pointer( <%= native_type_expr %>)).value = value
|
35
|
+
end
|
36
|
+
|
37
|
+
end
|
@@ -0,0 +1,28 @@
|
|
1
|
+
module CrystalRuby::Types
|
2
|
+
%i[UInt8 UInt16 UInt32 UInt64 Int8 Int16 Int32 Int64 Float32 Float64].each do |type_name|
|
3
|
+
ffi_type = CrystalRuby::Typemaps::FFI_TYPE_MAP.fetch(type_name.to_s)
|
4
|
+
const_set(type_name, Primitive.build(type_name, convert_if: [::Numeric], ffi_type: ffi_type) do
|
5
|
+
def value=(val)
|
6
|
+
raise "Expected a numeric value, got #{val}" unless val.is_a?(::Numeric)
|
7
|
+
|
8
|
+
super(typename.to_s.start_with?("Float") ? val.to_f : val.to_i)
|
9
|
+
end
|
10
|
+
|
11
|
+
def value(native: false)
|
12
|
+
@value
|
13
|
+
end
|
14
|
+
|
15
|
+
def self.from_ffi_array_repr(value)
|
16
|
+
value
|
17
|
+
end
|
18
|
+
|
19
|
+
def self.numeric?
|
20
|
+
true
|
21
|
+
end
|
22
|
+
|
23
|
+
def self.template_name
|
24
|
+
"Numbers"
|
25
|
+
end
|
26
|
+
end)
|
27
|
+
end
|
28
|
+
end
|
@@ -0,0 +1,55 @@
|
|
1
|
+
class <%= base_crystal_class_name %> < CrystalRuby::Types::Primitive
|
2
|
+
|
3
|
+
def initialize(value : ::Symbol)
|
4
|
+
@value = 0.to_u32
|
5
|
+
self.value = value
|
6
|
+
end
|
7
|
+
|
8
|
+
def initialize(value : UInt32)
|
9
|
+
@value = value
|
10
|
+
end
|
11
|
+
|
12
|
+
def initialize(ptr : Pointer(::UInt8))
|
13
|
+
initialize(ptr.as(Pointer(::UInt32))[0])
|
14
|
+
end
|
15
|
+
|
16
|
+
def ==(other : ::Symbol)
|
17
|
+
value == other
|
18
|
+
end
|
19
|
+
|
20
|
+
def value=(value : ::Symbol)
|
21
|
+
case value
|
22
|
+
<% allowed_values.each_with_index do |v, i| %>
|
23
|
+
when :<%= v %> then @value = <%= i %>.to_u32
|
24
|
+
<% end %>
|
25
|
+
else raise "Symbol must be one of <%= allowed_values %>. Got #{value}"
|
26
|
+
end
|
27
|
+
end
|
28
|
+
|
29
|
+
def value : ::Symbol
|
30
|
+
case @value
|
31
|
+
<% allowed_values.each_with_index do |v, i| %>
|
32
|
+
when <%= i %> then :<%= v %>
|
33
|
+
<% end %>
|
34
|
+
else raise "Symbol must be one of <%= allowed_values %>. Got #{value}"
|
35
|
+
end
|
36
|
+
end
|
37
|
+
|
38
|
+
def self.copy_to!(value : ::Symbol, ptr : Pointer(::UInt8))
|
39
|
+
ptr.as(Pointer(::UInt32))[0] = new(value).return_value
|
40
|
+
end
|
41
|
+
|
42
|
+
def self.memsize
|
43
|
+
<%= memsize %>
|
44
|
+
end
|
45
|
+
|
46
|
+
def self.write_single(pointer : Pointer(::UInt8), value)
|
47
|
+
as_uint32 = case value
|
48
|
+
<% allowed_values.each_with_index do |v, i| %>
|
49
|
+
when :<%= v %> then <%= i %>.to_u32
|
50
|
+
<% end %>
|
51
|
+
else raise "Symbol must be one of <%= allowed_values %>. Got #{value}"
|
52
|
+
end
|
53
|
+
pointer.as(Pointer(::UInt32)).value = as_uint32
|
54
|
+
end
|
55
|
+
end
|
@@ -0,0 +1,35 @@
|
|
1
|
+
module CrystalRuby::Types
|
2
|
+
Symbol = Primitive.build(
|
3
|
+
error: "Symbol CrystalRuby types should indicate a list of possible values shared between Crystal and Ruby. "\
|
4
|
+
"E.g. Symbol(:green, :blue, :orange). If this list is not known at compile time, you should use a String instead."
|
5
|
+
)
|
6
|
+
|
7
|
+
def self.Symbol(*allowed_values)
|
8
|
+
raise "Symbol must have at least one value" if allowed_values.empty?
|
9
|
+
|
10
|
+
allowed_values.flatten!
|
11
|
+
raise "Symbol allowed values must all be symbols" unless allowed_values.all? { |v| v.is_a?(::Symbol) }
|
12
|
+
|
13
|
+
Primitive.build(:Symbol, ffi_type: :uint32, convert_if: [Root::String, Root::Symbol], memsize: 4) do
|
14
|
+
bind_local_vars!(%i[allowed_values], binding)
|
15
|
+
define_method(:value=) do |val|
|
16
|
+
val = allowed_values[val] if val.is_a?(::Integer) && val >= 0 && val < allowed_values.size
|
17
|
+
raise "Symbol must be one of #{allowed_values}" unless allowed_values.include?(val)
|
18
|
+
|
19
|
+
super(allowed_values.index(val))
|
20
|
+
end
|
21
|
+
|
22
|
+
define_singleton_method(:valid_cast?) do |raw|
|
23
|
+
super(raw) && allowed_values.include?(raw)
|
24
|
+
end
|
25
|
+
|
26
|
+
define_method(:value) do |native: false|
|
27
|
+
allowed_values[super()]
|
28
|
+
end
|
29
|
+
|
30
|
+
define_singleton_method(:type_digest) do
|
31
|
+
Digest::MD5.hexdigest(native_type_expr.to_s + allowed_values.map(&:to_s).join(","))
|
32
|
+
end
|
33
|
+
end
|
34
|
+
end
|
35
|
+
end
|
@@ -0,0 +1,35 @@
|
|
1
|
+
class <%= base_crystal_class_name %> < CrystalRuby::Types::Primitive
|
2
|
+
|
3
|
+
def initialize(time : ::Time)
|
4
|
+
@value = time.to_unix_ns / 1000_000_000.0
|
5
|
+
end
|
6
|
+
|
7
|
+
def initialize(ptr : Pointer(::UInt8))
|
8
|
+
@value = ptr.as(Pointer(::Float64)).value
|
9
|
+
end
|
10
|
+
|
11
|
+
def initialize(@value : ::Float64)
|
12
|
+
end
|
13
|
+
|
14
|
+
def ==(other : ::Time)
|
15
|
+
value == other
|
16
|
+
end
|
17
|
+
|
18
|
+
def value=(time : ::Time)
|
19
|
+
@value = time.to_unix_ns / 1000_000_000.0
|
20
|
+
end
|
21
|
+
|
22
|
+
def value : ::Time
|
23
|
+
::Time.unix_ns((@value * 1000_000_000).to_i128)
|
24
|
+
end
|
25
|
+
|
26
|
+
def self.memsize
|
27
|
+
<%= memsize %>
|
28
|
+
end
|
29
|
+
|
30
|
+
|
31
|
+
def self.write_single(pointer : Pointer(::UInt8), time)
|
32
|
+
pointer.as(Pointer(::Float64)).value = time.to_unix_ns / 1000_000_000.0
|
33
|
+
end
|
34
|
+
|
35
|
+
end
|
@@ -0,0 +1,25 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require "date"
|
4
|
+
|
5
|
+
module CrystalRuby::Types
|
6
|
+
Time = Primitive.build(:Time, convert_if: [Root::Time, Root::String, DateTime], ffi_type: :double) do
|
7
|
+
def initialize(val = Root::Time.now)
|
8
|
+
super
|
9
|
+
end
|
10
|
+
|
11
|
+
def value=(val)
|
12
|
+
super(
|
13
|
+
if val.respond_to?(:to_time)
|
14
|
+
val.to_time.to_f
|
15
|
+
else
|
16
|
+
val.respond_to?(:to_f) ? val.to_f : 0
|
17
|
+
end
|
18
|
+
)
|
19
|
+
end
|
20
|
+
|
21
|
+
def value(native: false)
|
22
|
+
::Time.at(super)
|
23
|
+
end
|
24
|
+
end
|
25
|
+
end
|
@@ -0,0 +1,64 @@
|
|
1
|
+
module CrystalRuby
|
2
|
+
module Types
|
3
|
+
class Type
|
4
|
+
property memory : Pointer(::UInt8) = Pointer(::UInt8).null
|
5
|
+
|
6
|
+
macro method_missing(call)
|
7
|
+
current_value = self.native
|
8
|
+
current_hash = current_value.hash
|
9
|
+
return_value = current_value.{{ call }}
|
10
|
+
|
11
|
+
if current_hash != current_value.hash
|
12
|
+
self.value = current_value
|
13
|
+
end
|
14
|
+
return_value
|
15
|
+
end
|
16
|
+
|
17
|
+
def to_s
|
18
|
+
native.to_s
|
19
|
+
end
|
20
|
+
|
21
|
+
def synchronize
|
22
|
+
CrystalRuby.synchronize do
|
23
|
+
yield
|
24
|
+
end
|
25
|
+
end
|
26
|
+
|
27
|
+
def self.synchronize
|
28
|
+
yield
|
29
|
+
end
|
30
|
+
|
31
|
+
def variable_width?
|
32
|
+
false
|
33
|
+
end
|
34
|
+
|
35
|
+
def return_value
|
36
|
+
memory
|
37
|
+
end
|
38
|
+
|
39
|
+
def self.free(memory : Pointer(::UInt8))
|
40
|
+
LibC.free(memory)
|
41
|
+
end
|
42
|
+
|
43
|
+
def self.malloc(size : Int) : Pointer(::UInt8)
|
44
|
+
LibC.calloc(size, 1).as(Pointer(::UInt8))
|
45
|
+
end
|
46
|
+
|
47
|
+
def malloc(memsize)
|
48
|
+
self.class.malloc(memsize)
|
49
|
+
end
|
50
|
+
|
51
|
+
def self.each_child_address(pointer : Pointer(::UInt8), &block : Pointer(::UInt8) -> Nil)
|
52
|
+
# Do nothing
|
53
|
+
end
|
54
|
+
|
55
|
+
def self.fetch_multi!(pointer : Pointer(::UInt8), size)
|
56
|
+
size.times.map { |i| fetch_single(pointer + i * refsize) }.to_a
|
57
|
+
end
|
58
|
+
|
59
|
+
def self.fetch_multi_native!(pointer : Pointer(::UInt8), size)
|
60
|
+
size.times.map { |i| fetch_single(pointer + i * refsize).native }.to_a
|
61
|
+
end
|
62
|
+
end
|
63
|
+
end
|
64
|
+
end
|