Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
bytecodealliance
GitHub Repository: bytecodealliance/wasmtime
Path: blob/main/crates/environ/src/fact/transcode.rs
1692 views
1
use crate::MemoryIndex;
2
use crate::component::Transcode;
3
use crate::fact::core_types::CoreTypes;
4
use crate::prelude::*;
5
use wasm_encoder::{EntityType, ValType};
6
7
#[derive(Copy, Clone, Hash, Eq, PartialEq)]
8
pub struct Transcoder {
9
pub from_memory: MemoryIndex,
10
pub from_memory64: bool,
11
pub to_memory: MemoryIndex,
12
pub to_memory64: bool,
13
pub op: Transcode,
14
}
15
16
impl Transcoder {
17
pub fn name(&self) -> String {
18
format!(
19
"{} (mem{} => mem{})",
20
self.op.desc(),
21
self.from_memory.as_u32(),
22
self.to_memory.as_u32(),
23
)
24
}
25
26
pub fn ty(&self, types: &mut CoreTypes) -> EntityType {
27
let from_ptr = if self.from_memory64 {
28
ValType::I64
29
} else {
30
ValType::I32
31
};
32
let to_ptr = if self.to_memory64 {
33
ValType::I64
34
} else {
35
ValType::I32
36
};
37
38
let ty = match self.op {
39
// These direct transcodings take the source pointer, the source
40
// code units, and the destination pointer.
41
//
42
// The memories being copied between are part of each intrinsic and
43
// the destination code units are the same as the source.
44
// Note that the pointers are dynamically guaranteed to be aligned
45
// and in-bounds for the code units length as defined by the string
46
// encoding.
47
Transcode::Copy(_) | Transcode::Latin1ToUtf16 => {
48
types.function(&[from_ptr, from_ptr, to_ptr], &[])
49
}
50
51
// Transcoding from utf8 to utf16 takes the from ptr/len as well as
52
// a destination. The destination is valid for len*2 bytes. The
53
// return value is how many code units were written to the
54
// destination.
55
Transcode::Utf8ToUtf16 => types.function(&[from_ptr, from_ptr, to_ptr], &[to_ptr]),
56
57
// Transcoding to utf8 as a smaller format takes all the parameters
58
// and returns the amount of space consumed in the src/destination
59
Transcode::Utf16ToUtf8 | Transcode::Latin1ToUtf8 => {
60
types.function(&[from_ptr, from_ptr, to_ptr, to_ptr], &[from_ptr, to_ptr])
61
}
62
63
// The return type is a tagged length which indicates which was
64
// used
65
Transcode::Utf16ToCompactProbablyUtf16 => {
66
types.function(&[from_ptr, from_ptr, to_ptr], &[to_ptr])
67
}
68
69
// The initial step of transcoding from a fixed format to a compact
70
// format. Takes the ptr/len of the source the destination
71
// pointer. The destination length is implicitly the same. Returns
72
// how many code units were consumed in the source, which is also
73
// how many bytes were written to the destination.
74
Transcode::Utf8ToLatin1 | Transcode::Utf16ToLatin1 => {
75
types.function(&[from_ptr, from_ptr, to_ptr], &[from_ptr, to_ptr])
76
}
77
78
// The final step of transcoding to a compact format when the fixed
79
// transcode has failed. This takes the ptr/len of the source that's
80
// remaining to transcode. Then this takes the destination ptr/len
81
// as well as the destination bytes written so far with latin1.
82
// Finally this returns the number of code units written to the
83
// destination.
84
Transcode::Utf8ToCompactUtf16 | Transcode::Utf16ToCompactUtf16 => {
85
types.function(&[from_ptr, from_ptr, to_ptr, to_ptr, to_ptr], &[to_ptr])
86
}
87
};
88
EntityType::Function(ty)
89
}
90
}
91
92