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 crate::ffi::jit_kinds::*;
14use crate::ffi::value_ffi::*;
15
16// ============================================================================
17// Pattern Matching Helpers
18// ============================================================================
19
20/// Check if object matches Ok/Err constructor pattern
21/// mode: 0 = Ok (check "Ok" or "value" key), 1 = Err (check "Err" or "error" key)
22/// Returns TAG_BOOL_TRUE if matches, TAG_BOOL_FALSE otherwise
23#[inline(always)]
24pub extern "C" fn jit_pattern_check_constructor(obj_bits: u64, mode: u64) -> u64 {
25    unsafe {
26        if !is_heap_kind(obj_bits, HK_JIT_OBJECT) {
27            return TAG_BOOL_FALSE;
28        }
29
30        let obj = unified_unbox::<HashMap<String, u64>>(obj_bits);
31
32        let (primary, fallback) = if mode == 0 {
33            ("Ok", "value")
34        } else {
35            ("Err", "error")
36        };
37
38        if obj.contains_key(primary) || obj.contains_key(fallback) {
39            TAG_BOOL_TRUE
40        } else {
41            TAG_BOOL_FALSE
42        }
43    }
44}
45
46/// Extract value from Ok/Err constructor pattern
47/// mode: 0 = Ok (try "Ok" then "value"), 1 = Err (try "Err" then "error")
48/// Returns the extracted value or TAG_NULL if not found
49#[inline(always)]
50pub extern "C" fn jit_pattern_extract_constructor(obj_bits: u64, mode: u64) -> u64 {
51    unsafe {
52        if !is_heap_kind(obj_bits, HK_JIT_OBJECT) {
53            return TAG_NULL;
54        }
55
56        let obj = unified_unbox::<HashMap<String, u64>>(obj_bits);
57
58        let (primary, fallback) = if mode == 0 {
59            ("Ok", "value")
60        } else {
61            ("Err", "error")
62        };
63
64        // Try primary key first, then fallback
65        if let Some(&val) = obj.get(primary) {
66            val
67        } else if let Some(&val) = obj.get(fallback) {
68            val
69        } else {
70            TAG_NULL
71        }
72    }
73}