MCPcopy Index your code
hub / github.com/aiscriptdev/aiscript / from_slice

Method from_slice

aiscript-vm/src/string/interned.rs:77–120  ·  view source on GitHub ↗
(mc: &Mutation<'gc>, s: impl AsRef<[u8]>)

Source from the content-addressed store, hash-verified

75 }
76
77 pub fn from_slice(mc: &Mutation<'gc>, s: impl AsRef<[u8]>) -> InternedString<'gc> {
78 // TODO: This is an extremely silly way to allocate a dynamically sized, inline string.
79 // Since gc-arena does not support variable sized allocations, we try a set of static
80 // sizes to inline small strings. All larger strings are instead allocated with an indirect
81 // buffer. This can be improved when gc-arena learns to allocate variable sizes.
82
83 fn create<'gc, const N: usize>(mc: &Mutation<'gc>, s: &[u8]) -> InternedString<'gc> {
84 #[derive(Collect)]
85 #[collect(require_static)]
86 #[repr(C)]
87 struct InlineString<const N: usize> {
88 header: StringInner,
89 array: [u8; N],
90 }
91
92 assert!(s.len() <= N);
93 let mut string = InlineString {
94 header: StringInner {
95 hash: str_hash(s),
96 buffer: Buffer::Inline(s.len()),
97 },
98 array: [0; N],
99 };
100 string.array[0..s.len()].copy_from_slice(s);
101
102 let string = Gc::new(mc, string);
103 // SAFETY: We know we can cast to `StringInner` because `InlineString` is `#[repr(C)]`
104 // and `header` is the first field.
105 unsafe { InternedString(Gc::cast::<StringInner>(string)) }
106 }
107
108 let s = s.as_ref();
109
110 macro_rules! try_sizes {
111 ($($size:expr),*) => {
112 $(if s.len() <= $size {
113 return create::<$size>(mc, s);
114 })*
115 };
116 }
117 try_sizes!(0, 2, 4, 8, 12, 16, 24, 32, 48, 64, 96, 128, 192, 256);
118
119 Self::from_buffer(mc, s.into())
120 }
121
122 pub fn from_static<S: ?Sized + AsRef<[u8]>>(
123 mc: &Mutation<'gc>,

Callers

nothing calls this directly

Calls 1

as_refMethod · 0.45

Tested by

no test coverage detected