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}