ciri 0.0.0 → 0.0.1
Sign up to get free protection for your applications and to get access to all the features.
- 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
|