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
//! Basic utilities for working with memory and objects.
// ──────────────────────────────────────────────────────────────────────────────
// PORT NOTE: `exemptedFromDeinit`, `deinitIsVoid`, and `deinit` are intentionally
// NOT ported as functions.
//
// Zig's `bun.memory.deinit(ptr_or_slice)` walked `@typeInfo` to:
// - recurse into slices/arrays/optionals/error-unions,
// - call `.deinit()` on struct / tagged-union pointees (unless the type set
// `pub const deinit = void;` or was in an exemption list), and
// - finally write `undefined` over the memory if the pointer was mutable.
//
// Rust's `Drop` already does the recursive part automatically: dropping a value
// drops every field, every `Vec`/`Box` element, every `Option`/`Result` payload.
// The "write undefined" poisoning has no safe Rust equivalent (and is a debug aid,
// not semantics).
//
// Call sites:
// - `bun.memory.deinit(&x)` → delete (let `x` drop at scope exit).
// - `bun.memory.deinit(slice)` → delete (slice elements drop with their owner).
// - explicit early release → `drop(x)` or a type-specific `close(self)`.
//
// `@typeInfo` has no Rust equivalent (§Comptime reflection), so a faithful generic
// port is not possible — and per §Idiom map, `deinit` definitions become `impl Drop`
// on the target type, not a free function here.
//
// TODO(port): if any caller relied on the `*x = undefined` poisoning to catch UAF in
// debug, add `#[cfg(debug_assertions)] unsafe { ptr::write_bytes(p, 0xAA, 1) }` at
// that call site.
// ──────────────────────────────────────────────────────────────────────────────
/// Rebase a slice from one memory buffer to another buffer.
///
/// Given a slice which points into a memory buffer with base `old_base`, return a
/// slice which points to the same offset in a new memory buffer with base `new_base`,
/// preserving the length of the slice.
///
/// ```text
/// const old_base = [6]u8{};
/// assert(@ptrToInt(&old_base) == 0x32);
///
/// 0x32 0x33 0x34 0x35 0x36 0x37
/// old_base |????|????|????|????|????|????|
/// ^
/// |<-- slice --->|
///
/// const new_base = [6]u8{};
/// assert(@ptrToInt(&new_base) == 0x74);
/// const output = rebaseSlice(slice, old_base, new_base)
///
/// 0x74 0x75 0x76 0x77 0x78 0x79
/// new_base |????|????|????|????|????|????|
/// ^
/// |<-- output -->|
/// ```
///
/// # Safety
/// - `slice` must point into the allocation starting at `old_base`.
/// - `new_base` must point to a valid allocation of at least
/// `(slice.as_ptr() - old_base) + slice.len()` bytes.
/// - The returned lifetime `'a` must not outlive the allocation at `new_base`.
pub unsafe
// ported from: src/bun_alloc/memory.zig