Skip to main content

luaur_bytecode/methods/
bytecode_builder_constant_key_hash_operator_call.rs

1use crate::records::constant_key::ConstantKey;
2use crate::records::constant_key_hash::ConstantKeyHash;
3
4#[allow(non_snake_case)]
5impl ConstantKeyHash {
6    pub fn call(&self, key: &ConstantKey) -> usize {
7        // Constant::Type_Vector is 4 based on Luau bytecode specification
8        if key.r#type as u8 == 4 {
9            let mut i = [0u32; 4];
10            // Safety: ConstantKey.value and ConstantKey.extra are both u64, totaling 16 bytes.
11            // [u32; 4] is also 16 bytes.
12            unsafe {
13                let src_ptr = &key.value as *const u64 as *const u8;
14                core::ptr::copy_nonoverlapping(src_ptr, i.as_mut_ptr() as *mut u8, 16);
15            }
16
17            // scramble bits to make sure that integer coordinates have entropy in lower bits
18            i[0] ^= i[0] >> 17;
19            i[1] ^= i[1] >> 17;
20            i[2] ^= i[2] >> 17;
21            i[3] ^= i[3] >> 17;
22
23            // Optimized Spatial Hashing for Collision Detection of Deformable Objects
24            let h = (i[0].wrapping_mul(73856093))
25                ^ (i[1].wrapping_mul(19349663))
26                ^ (i[2].wrapping_mul(83492791))
27                ^ (i[3].wrapping_mul(39916801));
28
29            h as usize
30        } else {
31            // finalizer from MurmurHash64B
32            const M: u32 = 0x5bd1e995;
33
34            let mut h1 = key.value as u32;
35            let mut h2 = (key.value >> 32) as u32 ^ ((key.r#type as u32).wrapping_mul(M));
36
37            h1 ^= h2 >> 18;
38            h1 = h1.wrapping_mul(M);
39            h2 ^= h1 >> 22;
40            h2 = h2.wrapping_mul(M);
41            h1 ^= h2 >> 17;
42            h1 = h1.wrapping_mul(M);
43            h2 ^= h1 >> 19;
44            h2 = h2.wrapping_mul(M);
45
46            // ... truncated to 32-bit output
47            h2 as usize
48        }
49    }
50}