forked from CosmWasm/wasmvm
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathmemory.go
98 lines (87 loc) · 3.01 KB
/
memory.go
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
package api
/*
#include "bindings.h"
*/
import "C"
import "unsafe"
// makeView creates a view into the given byte slice what allows Rust code to read it.
// The byte slice is managed by Go and will be garbage collected. Use runtime.KeepAlive
// to ensure the byte slice lives long enough.
func makeView(s []byte) C.ByteSliceView {
if s == nil {
return C.ByteSliceView{is_nil: true, ptr: cu8_ptr(nil), len: cusize(0)}
}
// In Go, accessing the 0-th element of an empty array triggers a panic. That is why in the case
// of an empty `[]byte` we can't get the internal heap pointer to the underlying array as we do
// below with `&data[0]`. https://play.golang.org/p/xvDY3g9OqUk
if len(s) == 0 {
return C.ByteSliceView{is_nil: false, ptr: cu8_ptr(nil), len: cusize(0)}
}
return C.ByteSliceView{
is_nil: false,
ptr: cu8_ptr(unsafe.Pointer(&s[0])),
len: cusize(len(s)),
}
}
// Creates a C.UnmanagedVector, which cannot be done in test files directly
func constructUnmanagedVector(is_none cbool, ptr cu8_ptr, len cusize, cap cusize) C.UnmanagedVector {
return C.UnmanagedVector{
is_none: is_none,
ptr: ptr,
len: len,
cap: cap,
}
}
// uninitializedUnmanagedVector returns an invalid C.UnmanagedVector
// instance. Only use then after someone wrote an instance to it.
func uninitializedUnmanagedVector() C.UnmanagedVector {
return C.UnmanagedVector{}
}
func newUnmanagedVector(data []byte) C.UnmanagedVector {
if data == nil {
return C.new_unmanaged_vector(cbool(true), cu8_ptr(nil), cusize(0))
} else if len(data) == 0 {
// in Go, accessing the 0-th element of an empty array triggers a panic. That is why in the case
// of an empty `[]byte` we can't get the internal heap pointer to the underlying array as we do
// below with `&data[0]`.
// https://play.golang.org/p/xvDY3g9OqUk
return C.new_unmanaged_vector(cbool(false), cu8_ptr(nil), cusize(0))
} else {
// This will allocate a proper vector with content and return a description of it
return C.new_unmanaged_vector(cbool(false), cu8_ptr(unsafe.Pointer(&data[0])), cusize(len(data)))
}
}
func copyAndDestroyUnmanagedVector(v C.UnmanagedVector) []byte {
var out []byte
if v.is_none {
out = nil
} else if v.cap == cusize(0) {
// There is no allocation we can copy
out = []byte{}
} else {
// C.GoBytes create a copy (https://stackoverflow.com/a/40950744/2013738)
out = C.GoBytes(unsafe.Pointer(v.ptr), cint(v.len))
}
C.destroy_unmanaged_vector(v)
return out
}
func optionalU64ToPtr(val C.OptionalU64) *uint64 {
if val.is_some {
return (*uint64)(&val.value)
}
return nil
}
// copyU8Slice copies the contents of an Option<&[u8]> that was allocated on the Rust side.
// Returns nil if and only if the source is None.
func copyU8Slice(view C.U8SliceView) []byte {
if view.is_none {
return nil
}
if view.len == 0 {
// In this case, we don't want to look into the ptr
return []byte{}
}
// C.GoBytes create a copy (https://stackoverflow.com/a/40950744/2013738)
res := C.GoBytes(unsafe.Pointer(view.ptr), cint(view.len))
return res
}