ciri 0.0.0 → 0.0.1
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/.gitmodules +14 -0
- data/.rspec +2 -1
- data/.travis.yml +11 -4
- data/Gemfile.lock +3 -0
- data/README.md +44 -34
- data/Rakefile +47 -4
- data/ciri.gemspec +13 -12
- data/docker/Base +34 -0
- data/lib/ciri/actor.rb +223 -0
- data/lib/ciri/chain.rb +293 -0
- data/lib/ciri/chain/block.rb +47 -0
- data/lib/ciri/chain/header.rb +62 -0
- data/lib/ciri/chain/transaction.rb +145 -0
- data/lib/ciri/crypto.rb +58 -5
- data/lib/ciri/db/backend/memory.rb +68 -0
- data/lib/ciri/db/backend/rocks.rb +104 -0
- data/lib/ciri/db/backend/rocks_db.rb +278 -0
- data/lib/ciri/devp2p/peer.rb +10 -2
- data/lib/ciri/devp2p/protocol.rb +11 -3
- data/lib/ciri/devp2p/protocol_io.rb +6 -3
- data/lib/ciri/devp2p/rlpx.rb +1 -0
- data/lib/ciri/devp2p/rlpx/encryption_handshake.rb +1 -1
- data/lib/ciri/devp2p/rlpx/frame_io.rb +1 -1
- data/lib/ciri/devp2p/rlpx/message.rb +4 -4
- data/lib/ciri/devp2p/server.rb +14 -13
- data/lib/ciri/eth.rb +33 -0
- data/lib/ciri/eth/peer.rb +64 -0
- data/lib/ciri/eth/protocol_manage.rb +122 -0
- data/lib/ciri/eth/protocol_messages.rb +158 -0
- data/lib/ciri/eth/synchronizer.rb +188 -0
- data/lib/ciri/ethash.rb +123 -0
- data/lib/ciri/evm.rb +140 -0
- data/lib/ciri/evm/account.rb +50 -0
- data/lib/ciri/evm/block_info.rb +31 -0
- data/lib/ciri/evm/forks/frontier.rb +183 -0
- data/lib/ciri/evm/instruction.rb +92 -0
- data/lib/ciri/evm/machine_state.rb +81 -0
- data/lib/ciri/evm/op.rb +536 -0
- data/lib/ciri/evm/serialize.rb +60 -0
- data/lib/ciri/evm/sub_state.rb +64 -0
- data/lib/ciri/evm/vm.rb +379 -0
- data/lib/ciri/forks.rb +38 -0
- data/lib/ciri/forks/frontier.rb +43 -0
- data/lib/ciri/key.rb +7 -1
- data/lib/ciri/pow.rb +95 -0
- data/lib/ciri/rlp.rb +3 -53
- data/lib/ciri/rlp/decode.rb +100 -40
- data/lib/ciri/rlp/encode.rb +95 -34
- data/lib/ciri/rlp/serializable.rb +61 -91
- data/lib/ciri/types/address.rb +70 -0
- data/lib/ciri/types/errors.rb +36 -0
- data/lib/ciri/utils.rb +45 -13
- data/lib/ciri/utils/lib_c.rb +46 -0
- data/lib/ciri/utils/logger.rb +99 -0
- data/lib/ciri/utils/number.rb +67 -0
- data/lib/ciri/version.rb +1 -1
- metadata +67 -7
- data/lib/ciri/devp2p/actor.rb +0 -224
@@ -29,7 +29,11 @@ module Ciri
|
|
29
29
|
# represent bool types: true | false
|
30
30
|
class Bool
|
31
31
|
ENCODED_TRUE = Ciri::Utils.big_endian_encode(0x01)
|
32
|
-
ENCODED_FALSE = Ciri::Utils.big_endian_encode(
|
32
|
+
ENCODED_FALSE = Ciri::Utils.big_endian_encode(0x80)
|
33
|
+
end
|
34
|
+
|
35
|
+
# represent RLP raw types, binary or array
|
36
|
+
class Raw
|
33
37
|
end
|
34
38
|
|
35
39
|
# Serializable module allow ruby objects serialize/deserialize to or from RLP encoding.
|
@@ -71,26 +75,38 @@ module Ciri
|
|
71
75
|
#
|
72
76
|
module Serializable
|
73
77
|
# nil represent RLP raw value(string or array of string)
|
74
|
-
TYPES = [
|
78
|
+
TYPES = [Raw, Integer, Bool].map {|key| [key, true]}.to_h.freeze
|
75
79
|
|
76
80
|
# Schema specific columns types of classes, normally you should not use Serializable::Schema directly
|
77
81
|
#
|
78
82
|
class Schema
|
83
|
+
include Encode
|
84
|
+
include Decode
|
85
|
+
|
79
86
|
class InvalidSchemaError < StandardError
|
80
87
|
end
|
81
88
|
|
82
89
|
# keys return data columns array
|
83
90
|
attr_reader :keys
|
84
91
|
|
92
|
+
KeySchema = Struct.new(:type, :options, keyword_init: true)
|
93
|
+
|
85
94
|
def initialize(schema)
|
86
95
|
keys = []
|
87
96
|
@_schema = {}
|
88
97
|
|
89
98
|
schema.each do |key|
|
90
|
-
|
99
|
+
if key.is_a?(Hash)
|
100
|
+
options = [:optional].map {|o| [o, key.delete(o)]}.to_h
|
101
|
+
raise InvalidSchemaError.new("include unknown options #{key}") unless key.size == 1
|
102
|
+
key, type = key.to_a[0]
|
103
|
+
else
|
104
|
+
options = {}
|
105
|
+
type = Raw
|
106
|
+
end
|
91
107
|
raise InvalidSchemaError.new("missing type #{type} for key #{key}") unless check_key_type(type)
|
92
108
|
keys << key
|
93
|
-
@_schema[key] = type
|
109
|
+
@_schema[key] = KeySchema.new(type: type, options: options)
|
94
110
|
end
|
95
111
|
|
96
112
|
@_schema.freeze
|
@@ -109,25 +125,38 @@ module Ciri
|
|
109
125
|
end
|
110
126
|
end
|
111
127
|
|
112
|
-
def rlp_encode!(data,
|
128
|
+
def rlp_encode!(data, skip_keys: nil, white_list_keys: nil)
|
113
129
|
# pre-encode, encode data to rlp compatible format(only string or array)
|
114
|
-
|
115
|
-
|
130
|
+
used_keys = if white_list_keys
|
131
|
+
white_list_keys
|
132
|
+
elsif skip_keys
|
133
|
+
keys - skip_keys
|
134
|
+
else
|
135
|
+
keys
|
136
|
+
end
|
137
|
+
data_list = []
|
138
|
+
used_keys.each do |key|
|
139
|
+
value = data[key]
|
140
|
+
next if value.nil? && self[key].options[:optional]
|
141
|
+
data_list << encode_with_type(value, self[key].type)
|
116
142
|
end
|
117
|
-
|
143
|
+
encode_list(data_list)
|
118
144
|
end
|
119
145
|
|
120
|
-
def rlp_decode!(input
|
121
|
-
|
122
|
-
|
123
|
-
|
124
|
-
|
125
|
-
|
126
|
-
|
146
|
+
def rlp_decode!(input)
|
147
|
+
values = decode_list(input) do |list, stream|
|
148
|
+
keys.each do |key|
|
149
|
+
# decode data by type
|
150
|
+
next if stream.eof? && self[key].options[:optional]
|
151
|
+
list << decode_with_type(stream, self[key].type)
|
152
|
+
end
|
153
|
+
end
|
154
|
+
# convert to key value hash
|
155
|
+
keys.zip(values).to_h
|
127
156
|
end
|
128
157
|
|
129
|
-
|
130
158
|
private
|
159
|
+
|
131
160
|
def check_key_type(type)
|
132
161
|
return true if TYPES.key?(type)
|
133
162
|
return true if type.is_a?(Class) && type < Serializable
|
@@ -142,8 +171,8 @@ module Ciri
|
|
142
171
|
|
143
172
|
module ClassMethods
|
144
173
|
# Decode object from input
|
145
|
-
def rlp_decode(input
|
146
|
-
data = schema.rlp_decode!(input
|
174
|
+
def rlp_decode(input)
|
175
|
+
data = schema.rlp_decode!(input)
|
147
176
|
self.new(data)
|
148
177
|
end
|
149
178
|
|
@@ -161,15 +190,16 @@ module Ciri
|
|
161
190
|
end
|
162
191
|
|
163
192
|
private
|
193
|
+
|
164
194
|
def define_attributes(schema)
|
165
195
|
schema.keys.each do |attribute|
|
166
196
|
module_eval <<-ATTR_METHODS
|
167
197
|
def #{attribute}
|
168
|
-
|
198
|
+
serializable_attributes[:"#{attribute}"]
|
169
199
|
end
|
170
200
|
|
171
201
|
def #{attribute}=(value)
|
172
|
-
|
202
|
+
serializable_attributes[:"#{attribute}"] = value
|
173
203
|
end
|
174
204
|
ATTR_METHODS
|
175
205
|
end
|
@@ -180,87 +210,27 @@ module Ciri
|
|
180
210
|
def included(base)
|
181
211
|
base.send :extend, ClassMethods
|
182
212
|
end
|
183
|
-
|
184
|
-
# use this method before RLP.encode
|
185
|
-
# encode item to string or array
|
186
|
-
def encode_with_type(item, type, zero: '')
|
187
|
-
if type == Integer
|
188
|
-
if item == 0
|
189
|
-
"\x80".b
|
190
|
-
elsif item < 128
|
191
|
-
Ciri::Utils.big_endian_encode(item, zero)
|
192
|
-
else
|
193
|
-
buf = Ciri::Utils.big_endian_encode(item, zero)
|
194
|
-
[0x80 + buf.size].pack("c*") + buf
|
195
|
-
end
|
196
|
-
elsif type == Bool
|
197
|
-
item ? Bool::ENCODED_TRUE : Bool::ENCODED_FALSE
|
198
|
-
elsif type.is_a?(Class) && type < Serializable
|
199
|
-
item.rlp_encode!(raw: false)
|
200
|
-
elsif type.is_a?(Array)
|
201
|
-
if type.size == 1 # array type
|
202
|
-
item.map {|i| encode_with_type(i, type[0])}
|
203
|
-
else # unknown
|
204
|
-
raise InvalidValueError.new "type size should be 1, got #{type}"
|
205
|
-
end
|
206
|
-
else
|
207
|
-
raise InvalidValueError.new "unknown type #{type}" unless TYPES.key?(type)
|
208
|
-
item
|
209
|
-
end
|
210
|
-
end
|
211
|
-
|
212
|
-
# Use this method after RLP.decode, decode values from string or array to specific types
|
213
|
-
# see Ciri::RLP::Serializable::TYPES for supported types
|
214
|
-
#
|
215
|
-
# Examples:
|
216
|
-
#
|
217
|
-
# item = Ciri::RLP.decode(encoded_text)
|
218
|
-
# decode_with_type(item, Integer)
|
219
|
-
#
|
220
|
-
def decode_with_type(item, type)
|
221
|
-
if type == Integer
|
222
|
-
if item == "\x80".b || item.empty?
|
223
|
-
0
|
224
|
-
elsif item[0].ord < 0x80
|
225
|
-
Ciri::Utils.big_endian_decode(item)
|
226
|
-
else
|
227
|
-
size = item[0].ord - 0x80
|
228
|
-
Ciri::Utils.big_endian_decode(item[1..size])
|
229
|
-
end
|
230
|
-
elsif type == Bool
|
231
|
-
if item == Bool::ENCODED_TRUE
|
232
|
-
true
|
233
|
-
elsif item == Bool::ENCODED_FALSE
|
234
|
-
false
|
235
|
-
else
|
236
|
-
raise InvalidValueError.new "invalid bool value #{item}"
|
237
|
-
end
|
238
|
-
elsif type.is_a?(Class) && type < Serializable
|
239
|
-
# already decoded from RLP encoding
|
240
|
-
type.rlp_decode!(item, raw: false)
|
241
|
-
elsif type.is_a?(Array)
|
242
|
-
item.map {|i| decode_with_type(i, type[0])}
|
243
|
-
else
|
244
|
-
raise InvalidValueError.new "unknown type #{type}" unless TYPES.key?(type)
|
245
|
-
item
|
246
|
-
end
|
247
|
-
end
|
248
213
|
end
|
249
214
|
|
250
|
-
attr_reader :
|
215
|
+
attr_reader :serializable_attributes
|
251
216
|
|
252
217
|
def initialize(**data)
|
253
|
-
@
|
254
|
-
self.class.schema.validate!(@
|
218
|
+
@serializable_attributes = (self.class.default_data || {}).merge(data)
|
219
|
+
self.class.schema.validate!(@serializable_attributes)
|
220
|
+
end
|
221
|
+
|
222
|
+
def initialize_copy(orig)
|
223
|
+
super
|
224
|
+
@serializable_attributes = orig.serializable_attributes.dup
|
255
225
|
end
|
256
226
|
|
257
227
|
# Encode object to rlp encoding string
|
258
|
-
def rlp_encode!(
|
259
|
-
self.class.schema.rlp_encode!(
|
228
|
+
def rlp_encode!(skip_keys: nil, white_list_keys: nil)
|
229
|
+
self.class.schema.rlp_encode!(serializable_attributes, skip_keys: skip_keys, white_list_keys: white_list_keys)
|
260
230
|
end
|
261
231
|
|
262
232
|
def ==(other)
|
263
|
-
self.class == other.class &&
|
233
|
+
self.class == other.class && serializable_attributes == other.serializable_attributes
|
264
234
|
end
|
265
235
|
|
266
236
|
end
|
@@ -0,0 +1,70 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
# Copyright (c) 2018, by Jiang Jinyang. <https://justjjy.com>
|
4
|
+
#
|
5
|
+
# Permission is hereby granted, free of charge, to any person obtaining a copy
|
6
|
+
# of this software and associated documentation files (the "Software"), to deal
|
7
|
+
# in the Software without restriction, including without limitation the rights
|
8
|
+
# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
9
|
+
# copies of the Software, and to permit persons to whom the Software is
|
10
|
+
# furnished to do so, subject to the following conditions:
|
11
|
+
#
|
12
|
+
# The above copyright notice and this permission notice shall be included in
|
13
|
+
# all copies or substantial portions of the Software.
|
14
|
+
#
|
15
|
+
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
16
|
+
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
17
|
+
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
18
|
+
# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
19
|
+
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
20
|
+
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
21
|
+
# THE SOFTWARE.
|
22
|
+
|
23
|
+
|
24
|
+
require_relative 'errors'
|
25
|
+
require 'ciri/rlp'
|
26
|
+
|
27
|
+
module Ciri
|
28
|
+
module Types
|
29
|
+
class Address
|
30
|
+
|
31
|
+
include RLP::Serializable
|
32
|
+
include Errors
|
33
|
+
|
34
|
+
def initialize(address)
|
35
|
+
@address = address.to_s
|
36
|
+
end
|
37
|
+
|
38
|
+
def rlp_encode!
|
39
|
+
RLP.encode(@address)
|
40
|
+
end
|
41
|
+
|
42
|
+
def self.rlp_decode!(data)
|
43
|
+
address = self.new(RLP.decode(data))
|
44
|
+
address.validate
|
45
|
+
address
|
46
|
+
end
|
47
|
+
|
48
|
+
def to_s
|
49
|
+
@address
|
50
|
+
end
|
51
|
+
|
52
|
+
alias to_str to_s
|
53
|
+
|
54
|
+
def to_hex
|
55
|
+
Utils.data_to_hex to_s
|
56
|
+
end
|
57
|
+
|
58
|
+
def empty?
|
59
|
+
@address.empty?
|
60
|
+
end
|
61
|
+
|
62
|
+
def validate
|
63
|
+
# empty address is valid
|
64
|
+
return if empty?
|
65
|
+
raise InvalidError.new("address must be 20 size, got #{@address.size}") unless @address.size == 20
|
66
|
+
end
|
67
|
+
|
68
|
+
end
|
69
|
+
end
|
70
|
+
end
|
@@ -0,0 +1,36 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
# Copyright (c) 2018, by Jiang Jinyang. <https://justjjy.com>
|
4
|
+
#
|
5
|
+
# Permission is hereby granted, free of charge, to any person obtaining a copy
|
6
|
+
# of this software and associated documentation files (the "Software"), to deal
|
7
|
+
# in the Software without restriction, including without limitation the rights
|
8
|
+
# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
9
|
+
# copies of the Software, and to permit persons to whom the Software is
|
10
|
+
# furnished to do so, subject to the following conditions:
|
11
|
+
#
|
12
|
+
# The above copyright notice and this permission notice shall be included in
|
13
|
+
# all copies or substantial portions of the Software.
|
14
|
+
#
|
15
|
+
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
16
|
+
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
17
|
+
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
18
|
+
# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
19
|
+
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
20
|
+
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
21
|
+
# THE SOFTWARE.
|
22
|
+
|
23
|
+
|
24
|
+
module Ciri
|
25
|
+
module Types
|
26
|
+
module Errors
|
27
|
+
|
28
|
+
class Error < StandardError
|
29
|
+
end
|
30
|
+
|
31
|
+
class InvalidError < Error
|
32
|
+
end
|
33
|
+
|
34
|
+
end
|
35
|
+
end
|
36
|
+
end
|
data/lib/ciri/utils.rb
CHANGED
@@ -22,11 +22,15 @@
|
|
22
22
|
|
23
23
|
|
24
24
|
require 'digest/sha3'
|
25
|
+
require_relative 'utils/number'
|
25
26
|
|
26
27
|
module Ciri
|
27
28
|
module Utils
|
28
29
|
|
29
30
|
class << self
|
31
|
+
include Utils::Number
|
32
|
+
|
33
|
+
|
30
34
|
def sha3(*data)
|
31
35
|
s = Digest::SHA3.new(256)
|
32
36
|
data.each {|i| s.update(i)}
|
@@ -37,24 +41,24 @@ module Ciri
|
|
37
41
|
s1.size == s2.size && s1.each_byte.each_with_index.map {|b, i| b ^ s2[i].ord}.reduce(0, :+) == 0
|
38
42
|
end
|
39
43
|
|
40
|
-
def
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
big_endian_encode(n / 256) + (n % 256).chr
|
45
|
-
end
|
44
|
+
def hex_to_data(hex)
|
45
|
+
data = [hex].pack("H*")
|
46
|
+
data = data[1..-1] if data.size > 0 && data[0].ord == 1
|
47
|
+
data
|
46
48
|
end
|
47
49
|
|
48
|
-
def
|
49
|
-
|
50
|
+
def hex_to_number(hex)
|
51
|
+
big_endian_decode hex_to_data(hex)
|
50
52
|
end
|
51
53
|
|
52
|
-
def
|
53
|
-
|
54
|
+
def data_to_hex(data)
|
55
|
+
hex = data.to_s.unpack("H*").first
|
56
|
+
hex[0..1] = '0x' if hex.start_with?('01')
|
57
|
+
hex
|
54
58
|
end
|
55
59
|
|
56
|
-
def
|
57
|
-
|
60
|
+
def number_to_hex(number)
|
61
|
+
data_to_hex big_endian_encode(number)
|
58
62
|
end
|
59
63
|
|
60
64
|
def create_ec_pk(raw_pubkey: nil, raw_privkey: nil)
|
@@ -69,7 +73,35 @@ module Ciri
|
|
69
73
|
key.private_key = OpenSSL::BN.new(raw_privkey, 2) if raw_privkey
|
70
74
|
end
|
71
75
|
end
|
76
|
+
|
77
|
+
def to_underscore(str)
|
78
|
+
str.gsub(/[A-Z]/) {|a| "_" + a.downcase}
|
79
|
+
end
|
80
|
+
|
81
|
+
def blank_binary?(item)
|
82
|
+
return true if item.is_a?(String) && item.each_byte.all?(&:zero?)
|
83
|
+
blank?(item)
|
84
|
+
end
|
85
|
+
|
86
|
+
def blank?(item)
|
87
|
+
if item.nil?
|
88
|
+
true
|
89
|
+
elsif item.is_a? Integer
|
90
|
+
item.zero?
|
91
|
+
elsif item.is_a? String
|
92
|
+
item.empty?
|
93
|
+
else
|
94
|
+
false
|
95
|
+
end
|
96
|
+
end
|
97
|
+
|
98
|
+
def present?(item)
|
99
|
+
!blank?(item)
|
100
|
+
end
|
101
|
+
|
72
102
|
end
|
73
103
|
|
104
|
+
BLANK_SHA3 = Utils.sha3(''.b).freeze
|
105
|
+
|
74
106
|
end
|
75
|
-
end
|
107
|
+
end
|
@@ -0,0 +1,46 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
# Copyright (c) 2018, by Jiang Jinyang. <https://justjjy.com>
|
4
|
+
#
|
5
|
+
# Permission is hereby granted, free of charge, to any person obtaining a copy
|
6
|
+
# of this software and associated documentation files (the "Software"), to deal
|
7
|
+
# in the Software without restriction, including without limitation the rights
|
8
|
+
# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
9
|
+
# copies of the Software, and to permit persons to whom the Software is
|
10
|
+
# furnished to do so, subject to the following conditions:
|
11
|
+
#
|
12
|
+
# The above copyright notice and this permission notice shall be included in
|
13
|
+
# all copies or substantial portions of the Software.
|
14
|
+
#
|
15
|
+
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
16
|
+
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
17
|
+
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
18
|
+
# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
19
|
+
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
20
|
+
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
21
|
+
# THE SOFTWARE.
|
22
|
+
|
23
|
+
|
24
|
+
require 'ffi'
|
25
|
+
|
26
|
+
module Ciri
|
27
|
+
module Utils
|
28
|
+
|
29
|
+
module LibC
|
30
|
+
extend FFI::Library
|
31
|
+
ffi_lib FFI::Library::LIBC
|
32
|
+
|
33
|
+
# memory allocators
|
34
|
+
attach_function :malloc, [:size_t], :pointer
|
35
|
+
attach_function :calloc, [:size_t], :pointer
|
36
|
+
attach_function :valloc, [:size_t], :pointer
|
37
|
+
attach_function :realloc, [:pointer, :size_t], :pointer
|
38
|
+
attach_function :free, [:pointer], :void
|
39
|
+
|
40
|
+
# memory movers
|
41
|
+
attach_function :memcpy, [:pointer, :pointer, :size_t], :pointer
|
42
|
+
attach_function :bcopy, [:pointer, :pointer, :size_t], :void
|
43
|
+
end
|
44
|
+
|
45
|
+
end
|
46
|
+
end
|