Skip to main content

shape_jit/ffi/object/
pattern.rs

1// Heap allocation audit (PR-9 V8 Gap Closure):
2//   Category A (NaN-boxed returns): 0 sites
3//   Category B (intermediate/consumed): 0 sites
4//   Category C (heap islands): 0 sites
5//     (pattern matching reads existing objects, no allocations)
6//!
7//! Pattern Matching Helpers
8//!
9//! Functions for pattern matching on Result (Ok/Err) and Option (Some/None) types.
10
11use std::collections::HashMap;
12
13use super::super::super::nan_boxing::*;
14
15// ============================================================================
16// Pattern Matching Helpers
17// ============================================================================
18
19/// Check if object matches Ok/Err constructor pattern
20/// mode: 0 = Ok (check "Ok" or "value" key), 1 = Err (check "Err" or "error" key)
21/// Returns TAG_BOOL_TRUE if matches, TAG_BOOL_FALSE otherwise
22#[inline(always)]
23pub extern "C" fn jit_pattern_check_constructor(obj_bits: u64, mode: u64) -> u64 {
24    unsafe {
25        if !is_heap_kind(obj_bits, HK_JIT_OBJECT) {
26            return TAG_BOOL_FALSE;
27        }
28
29        let obj = jit_unbox::<HashMap<String, u64>>(obj_bits);
30
31        let (primary, fallback) = if mode == 0 {
32            ("Ok", "value")
33        } else {
34            ("Err", "error")
35        };
36
37        if obj.contains_key(primary) || obj.contains_key(fallback) {
38            TAG_BOOL_TRUE
39        } else {
40            TAG_BOOL_FALSE
41        }
42    }
43}
44
45/// Extract value from Ok/Err constructor pattern
46/// mode: 0 = Ok (try "Ok" then "value"), 1 = Err (try "Err" then "error")
47/// Returns the extracted value or TAG_NULL if not found
48#[inline(always)]
49pub extern "C" fn jit_pattern_extract_constructor(obj_bits: u64, mode: u64) -> u64 {
50    unsafe {
51        if !is_heap_kind(obj_bits, HK_JIT_OBJECT) {
52            return TAG_NULL;
53        }
54
55        let obj = jit_unbox::<HashMap<String, u64>>(obj_bits);
56
57        let (primary, fallback) = if mode == 0 {
58            ("Ok", "value")
59        } else {
60            ("Err", "error")
61        };
62
63        // Try primary key first, then fallback
64        if let Some(&val) = obj.get(primary) {
65            val
66        } else if let Some(&val) = obj.get(fallback) {
67            val
68        } else {
69            TAG_NULL
70        }
71    }
72}