diff --git a/Cargo.lock b/Cargo.lock index 31e951a4bd..0b2bdd6537 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -3882,6 +3882,30 @@ dependencies = [ "web-time", ] +[[package]] +name = "inkwell" +version = "0.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7decbc9dfa45a4a827a6ff7b822c113b1285678a937e84213417d4ca8a095782" +dependencies = [ + "bitflags 2.12.1", + "inkwell_internals", + "libc", + "llvm-sys", + "thiserror 2.0.18", +] + +[[package]] +name = "inkwell_internals" +version = "0.14.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6cfe97ee860815a90ed17e09639513269e39420a7440f3f4c996f238c514cf8d" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.117", +] + [[package]] name = "inotify" version = "0.9.6" @@ -4428,6 +4452,20 @@ version = "1.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "11d3d7f243d5c5a8b9bb5d6dd2b1602c0cb0b9db1621bafc7ed66e35ff9fe092" +[[package]] +name = "llvm-sys" +version = "221.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2abcc34a3b190f03c2a61b555f218f529589ff13657bdd2ff8ac3e85f2abe6bb" +dependencies = [ + "anyhow", + "cc", + "lazy_static", + "libc", + "regex-lite", + "semver", +] + [[package]] name = "lock_api" version = "0.4.14" @@ -5581,6 +5619,8 @@ name = "perry-codegen" version = "0.5.1279" dependencies = [ "anyhow", + "inkwell", + "llvm-sys", "log", "perry-api-manifest", "perry-dispatch", @@ -7336,6 +7376,12 @@ dependencies = [ "regex-syntax", ] +[[package]] +name = "regex-lite" +version = "0.1.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cab834c73d247e67f4fae452806d17d3c7501756d98c8808d7c9c7aa7d18f973" + [[package]] name = "regex-syntax" version = "0.8.11" diff --git a/changelog.d/7241-inprocess-llvm-native-construction.md b/changelog.d/7241-inprocess-llvm-native-construction.md new file mode 100644 index 0000000000..7573eea0a0 --- /dev/null +++ b/changelog.d/7241-inprocess-llvm-native-construction.md @@ -0,0 +1,18 @@ +Opt-in in-process LLVM backend (#7241, engine-plan layer 0): with the +`llvm-inprocess` cargo feature built in and `PERRY_LLVM_INPROCESS=native`, +Perry constructs LLVM modules through the C API against pinned LLVM 22 — no +module-scale IR text, no `.ll` on disk, no `clang` subprocess, no dependence +on the user's toolchain. All 68 `LlBlock` semantic methods emit typed +instructions that build directly (`inst.rs`/`dialect.rs`); codegen-unit +splits build per-unit native modules and partial-link as before; `=diff` +mode byte-compares the two backends' objects (both corpora byte-identical); +`PERRY_SAVE_LL`/`--trace llvm`/`PERRY_LLVM_KEEP_IR` print the constructed +module as the debug view. `=1` selects the transport-only mode (whole-module +text parsed in-process). The flag participates in the build- and +object-cache keys; a build without the feature fails loudly if the flag is +set. The default build is unchanged: no LLVM link dependency, and emitted +IR is byte-identical to the merge-base (verified over a 12-file corpus; the +only divergence class is a pre-existing run-to-run closure-name +registration ordering coin that flips within a single binary). +`RewriteStatepointsForGC` scheduling in-process is pinned by test — +the layer-2 (#7174) unblock this branch exists for. diff --git a/crates/perry-codegen/Cargo.toml b/crates/perry-codegen/Cargo.toml index c3fddb40ba..5e3006bf96 100644 --- a/crates/perry-codegen/Cargo.toml +++ b/crates/perry-codegen/Cargo.toml @@ -8,6 +8,15 @@ description = "LLVM code generation backend for Perry" [lints] workspace = true +[features] +# exp/llvm-inprocess: compile `.ll -> .o` through the LLVM C API inside this +# process instead of shelling out to a user-supplied `clang -c`. Off by +# default — the default build has no LLVM link dependency and the text path +# is byte-for-byte untouched. Building with this feature requires LLVM 22 +# (`brew install llvm`; set LLVM_SYS_221_PREFIX if llvm-config is not on +# PATH). The backend still only runs when PERRY_LLVM_INPROCESS=1 at runtime. +llvm-inprocess = ["dep:inkwell", "dep:llvm-sys"] + [dependencies] perry-hir.workspace = true perry-dispatch.workspace = true @@ -18,3 +27,6 @@ thiserror.workspace = true log.workspace = true serde.workspace = true serde_json.workspace = true + +inkwell = { version = "0.9.0", features = ["llvm22-1"], optional = true } +llvm-sys = { version = "221", optional = true } diff --git a/crates/perry-codegen/src/block.rs b/crates/perry-codegen/src/block.rs index 26614a2ea1..6cbab38e7a 100644 --- a/crates/perry-codegen/src/block.rs +++ b/crates/perry-codegen/src/block.rs @@ -109,6 +109,17 @@ impl RegCounter { self.try_region_stores.borrow() } + /// Typed twin of [`note_emitted`] for `LlInst::Store` pushes: record the + /// store destination if we are inside a setjmp-protected region. + pub(crate) fn note_store_ptr(&self, ptr: &str) { + if self.try_region_depth.get() == 0 { + return; + } + if ptr.starts_with('%') { + self.try_region_stores.borrow_mut().insert(ptr.to_string()); + } + } + /// Record `line`'s store destination if we are inside a try region. /// Called from [`LlBlock::emit`], the single choke point every emitter /// (including `emit_raw`) funnels through. @@ -126,7 +137,7 @@ impl RegCounter { pub struct LlBlock { pub label: String, - instructions: Vec, + instructions: Vec, terminated: bool, counter: Rc, fp_flags: FpFlags, @@ -178,13 +189,7 @@ impl LlBlock { /// check cannot be invalidated mid-loop). Intrinsic/libm-style calls /// never enter the perry runtime, so they cannot trigger a collection. pub fn contains_gc_unsafe_call(&self) -> bool { - self.instructions.iter().any(|line| { - let Some(pos) = line.find("call ") else { - return false; - }; - let callee = &line[pos..]; - !callee.contains("@llvm.") && !callee.contains(" asm ") - }) + self.instructions.iter().any(|i| i.is_gc_unsafe_call()) } /// Allocate a fresh SSA register name in the enclosing function's @@ -197,6 +202,18 @@ impl LlBlock { self.reg() } + /// Typed twin of [`emit`]: same terminator discipline, same try-region + /// store tracking, no line formatting. + fn push_inst(&mut self, inst: crate::inst::LlInst) { + if self.terminated { + return; + } + if let crate::inst::LlInst::Store { ptr, .. } = &inst { + self.counter.note_store_ptr(ptr); + } + self.instructions.push(inst); + } + fn emit(&mut self, line: impl Into) { // Never emit instructions after a terminator — LLVM rejects them and // the symptom is a confusing `clang` parse error many lines later. @@ -210,7 +227,8 @@ impl LlBlock { // #6385: note stores emitted inside a setjmp-protected region so // `LlFunction::to_ir` can make the backing allocas volatile. self.counter.note_emitted(&line); - self.instructions.push(format!(" {}", line)); + self.instructions + .push(crate::inst::LlInst::Raw(format!(" {}", line))); } fn reg(&self) -> String { @@ -235,12 +253,12 @@ impl LlBlock { self.instructions.len() } - /// Iterate over the raw instruction strings (each already prefixed - /// with two leading spaces, no trailing newline). Used by - /// `LlFunction::to_ir` when it needs to splice hoisted setup into - /// the entry block at a specific boundary. - pub fn instructions_iter(&self) -> impl Iterator { - self.instructions.iter().map(|s| s.as_str()) + /// The block's instructions. Used by `LlFunction::to_ir` (entry-block + /// boundary splice) and `estimated_ir_bytes`; renders happen through + /// [`crate::inst::LlInst::render_into`] so typed variants need no + /// intermediate `String` per line. + pub fn insts(&self) -> &[crate::inst::LlInst] { + &self.instructions } // -------- Arithmetic (double) -------- @@ -288,72 +306,76 @@ impl LlBlock { pub fn fadd(&mut self, a: &str, b: &str) -> String { let r = self.reg(); - self.emit(format!( - "{} = fadd {}double {}, {}", - r, - self.fp_flags.fmf_prefix(), - a, - b - )); + self.push_inst(crate::inst::LlInst::Bin { + dst: r.clone(), + op: "fadd", + pre: self.fp_flags.fmf_prefix(), + ty: "double", + a: a.to_string(), + b: b.to_string(), + }); r } pub fn fsub(&mut self, a: &str, b: &str) -> String { let r = self.reg(); - self.emit(format!( - "{} = fsub {}double {}, {}", - r, - self.fp_flags.fmf_prefix(), - a, - b - )); + self.push_inst(crate::inst::LlInst::Bin { + dst: r.clone(), + op: "fsub", + pre: self.fp_flags.fmf_prefix(), + ty: "double", + a: a.to_string(), + b: b.to_string(), + }); r } pub fn fmul(&mut self, a: &str, b: &str) -> String { let r = self.reg(); - self.emit(format!( - "{} = fmul {}double {}, {}", - r, - self.fp_flags.fmf_prefix(), - a, - b - )); + self.push_inst(crate::inst::LlInst::Bin { + dst: r.clone(), + op: "fmul", + pre: self.fp_flags.fmf_prefix(), + ty: "double", + a: a.to_string(), + b: b.to_string(), + }); r } pub fn fdiv(&mut self, a: &str, b: &str) -> String { let r = self.reg(); - self.emit(format!( - "{} = fdiv {}double {}, {}", - r, - self.fp_flags.fmf_prefix(), - a, - b - )); + self.push_inst(crate::inst::LlInst::Bin { + dst: r.clone(), + op: "fdiv", + pre: self.fp_flags.fmf_prefix(), + ty: "double", + a: a.to_string(), + b: b.to_string(), + }); r } pub fn frem(&mut self, a: &str, b: &str) -> String { let r = self.reg(); - self.emit(format!( - "{} = frem {}double {}, {}", - r, - self.fp_flags.fmf_prefix(), - a, - b - )); + self.push_inst(crate::inst::LlInst::Bin { + dst: r.clone(), + op: "frem", + pre: self.fp_flags.fmf_prefix(), + ty: "double", + a: a.to_string(), + b: b.to_string(), + }); r } pub fn fneg(&mut self, a: &str) -> String { let r = self.reg(); - self.emit(format!( - "{} = fneg {}double {}", - r, - self.fp_flags.fmf_prefix(), - a - )); + self.push_inst(crate::inst::LlInst::FNeg { + dst: r.clone(), + pre: self.fp_flags.fmf_prefix(), + a: a.to_string(), + }); r } @@ -363,61 +385,120 @@ impl LlBlock { /// `ogt`, `oge`, `oeq`, `one`, `ord`, `uno`, … pub fn fcmp(&mut self, cond: &str, a: &str, b: &str) -> String { let r = self.reg(); - self.emit(format!("{} = fcmp {} double {}, {}", r, cond, a, b)); + self.push_inst(crate::inst::LlInst::FCmp { + dst: r.clone(), + pred: cond.to_string(), + a: a.to_string(), + b: b.to_string(), + }); r } pub fn icmp_eq(&mut self, ty: LlvmType, a: &str, b: &str) -> String { let r = self.reg(); - self.emit(format!("{} = icmp eq {} {}, {}", r, ty, a, b)); + self.push_inst(crate::inst::LlInst::ICmp { + dst: r.clone(), + pred: "eq", + ty, + a: a.to_string(), + b: b.to_string(), + }); r } pub fn icmp_ne(&mut self, ty: LlvmType, a: &str, b: &str) -> String { let r = self.reg(); - self.emit(format!("{} = icmp ne {} {}, {}", r, ty, a, b)); + self.push_inst(crate::inst::LlInst::ICmp { + dst: r.clone(), + pred: "ne", + ty, + a: a.to_string(), + b: b.to_string(), + }); r } pub fn icmp_slt(&mut self, ty: LlvmType, a: &str, b: &str) -> String { let r = self.reg(); - self.emit(format!("{} = icmp slt {} {}, {}", r, ty, a, b)); + self.push_inst(crate::inst::LlInst::ICmp { + dst: r.clone(), + pred: "slt", + ty, + a: a.to_string(), + b: b.to_string(), + }); r } pub fn icmp_sgt(&mut self, ty: LlvmType, a: &str, b: &str) -> String { let r = self.reg(); - self.emit(format!("{} = icmp sgt {} {}, {}", r, ty, a, b)); + self.push_inst(crate::inst::LlInst::ICmp { + dst: r.clone(), + pred: "sgt", + ty, + a: a.to_string(), + b: b.to_string(), + }); r } pub fn icmp_sle(&mut self, ty: LlvmType, a: &str, b: &str) -> String { let r = self.reg(); - self.emit(format!("{} = icmp sle {} {}, {}", r, ty, a, b)); + self.push_inst(crate::inst::LlInst::ICmp { + dst: r.clone(), + pred: "sle", + ty, + a: a.to_string(), + b: b.to_string(), + }); r } pub fn icmp_ult(&mut self, ty: LlvmType, a: &str, b: &str) -> String { let r = self.reg(); - self.emit(format!("{} = icmp ult {} {}, {}", r, ty, a, b)); + self.push_inst(crate::inst::LlInst::ICmp { + dst: r.clone(), + pred: "ult", + ty, + a: a.to_string(), + b: b.to_string(), + }); r } pub fn icmp_ule(&mut self, ty: LlvmType, a: &str, b: &str) -> String { let r = self.reg(); - self.emit(format!("{} = icmp ule {} {}, {}", r, ty, a, b)); + self.push_inst(crate::inst::LlInst::ICmp { + dst: r.clone(), + pred: "ule", + ty, + a: a.to_string(), + b: b.to_string(), + }); r } pub fn icmp_ugt(&mut self, ty: LlvmType, a: &str, b: &str) -> String { let r = self.reg(); - self.emit(format!("{} = icmp ugt {} {}, {}", r, ty, a, b)); + self.push_inst(crate::inst::LlInst::ICmp { + dst: r.clone(), + pred: "ugt", + ty, + a: a.to_string(), + b: b.to_string(), + }); r } pub fn icmp_sge(&mut self, ty: LlvmType, a: &str, b: &str) -> String { let r = self.reg(); - self.emit(format!("{} = icmp sge {} {}, {}", r, ty, a, b)); + self.push_inst(crate::inst::LlInst::ICmp { + dst: r.clone(), + pred: "sge", + ty, + a: a.to_string(), + b: b.to_string(), + }); r } @@ -425,22 +506,29 @@ impl LlBlock { pub fn alloca(&mut self, ty: LlvmType) -> String { let r = self.reg(); - self.emit(format!("{} = alloca {}", r, ty)); + self.push_inst(crate::inst::LlInst::Alloca { dst: r.clone(), ty }); r } pub fn load(&mut self, ty: LlvmType, ptr: &str) -> String { let r = self.reg(); - self.emit(format!("{} = load {}, ptr {}", r, ty, ptr)); + self.push_inst(crate::inst::LlInst::Load { + dst: r.clone(), + ty, + ptr: ptr.to_string(), + flavor: crate::inst::LoadFlavor::Plain, + }); r } pub fn load_aligned(&mut self, ty: LlvmType, ptr: &str, alignment: u32) -> String { let r = self.reg(); - self.emit(format!( - "{} = load {}, ptr {}, align {}", - r, ty, ptr, alignment - )); + self.push_inst(crate::inst::LlInst::Load { + dst: r.clone(), + ty, + ptr: ptr.to_string(), + flavor: crate::inst::LoadFlavor::Aligned(alignment), + }); r } @@ -449,7 +537,12 @@ impl LlBlock { /// that may be written by `optnone` functions. pub fn load_volatile(&mut self, ty: LlvmType, ptr: &str) -> String { let r = self.reg(); - self.emit(format!("{} = load volatile {}, ptr {}", r, ty, ptr)); + self.push_inst(crate::inst::LlInst::Load { + dst: r.clone(), + ty, + ptr: ptr.to_string(), + flavor: crate::inst::LoadFlavor::Volatile, + }); r } @@ -457,10 +550,12 @@ impl LlBlock { /// atomics. The explicit alignment is required by LLVM atomic loads. pub fn load_atomic_seq_cst(&mut self, ty: LlvmType, ptr: &str, alignment: u32) -> String { let r = self.reg(); - self.emit(format!( - "{} = load atomic {}, ptr {} seq_cst, align {}", - r, ty, ptr, alignment - )); + self.push_inst(crate::inst::LlInst::Load { + dst: r.clone(), + ty, + ptr: ptr.to_string(), + flavor: crate::inst::LoadFlavor::AtomicSeqCst(alignment), + }); r } @@ -477,28 +572,45 @@ impl LlBlock { /// memory changes. pub fn load_invariant(&mut self, ty: LlvmType, ptr: &str) -> String { let r = self.reg(); - self.emit(format!( - "{} = load {}, ptr {}, !invariant.load !0", - r, ty, ptr - )); + self.push_inst(crate::inst::LlInst::Load { + dst: r.clone(), + ty, + ptr: ptr.to_string(), + flavor: crate::inst::LoadFlavor::Invariant, + }); r } pub fn store(&mut self, ty: LlvmType, val: &str, ptr: &str) { - self.emit(format!("store {} {}, ptr {}", ty, val, ptr)); + self.push_inst(crate::inst::LlInst::Store { + ty, + val: val.to_string(), + ptr: ptr.to_string(), + volatile: false, + align: None, + }); } pub fn store_aligned(&mut self, ty: LlvmType, val: &str, ptr: &str, alignment: u32) { - self.emit(format!( - "store {} {}, ptr {}, align {}", - ty, val, ptr, alignment - )); + self.push_inst(crate::inst::LlInst::Store { + ty, + val: val.to_string(), + ptr: ptr.to_string(), + volatile: false, + align: Some(alignment), + }); } /// Store with `volatile` — prevents optimizer from eliminating or /// reordering. Used for module globals. pub fn store_volatile(&mut self, ty: LlvmType, val: &str, ptr: &str) { - self.emit(format!("store volatile {} {}, ptr {}", ty, val, ptr)); + self.push_inst(crate::inst::LlInst::Store { + ty, + val: val.to_string(), + ptr: ptr.to_string(), + volatile: true, + align: None, + }); } // -------- Conversions / bitcasts -------- @@ -511,7 +623,13 @@ impl LlBlock { return src.clone(); } let r = self.reg(); - self.emit(format!("{} = bitcast i64 {} to double", r, val)); + self.push_inst(crate::inst::LlInst::Cast { + dst: r.clone(), + op: "bitcast", + from: "i64", + v: val.to_string(), + to: "double", + }); if !self.terminated { self.double_from_i64.insert(r.clone(), val.to_string()); } @@ -525,7 +643,13 @@ impl LlBlock { return src.clone(); } let r = self.reg(); - self.emit(format!("{} = bitcast double {} to i64", r, val)); + self.push_inst(crate::inst::LlInst::Cast { + dst: r.clone(), + op: "bitcast", + from: "double", + v: val.to_string(), + to: "i64", + }); if !self.terminated { self.i64_from_double.insert(r.clone(), val.to_string()); } @@ -534,37 +658,73 @@ impl LlBlock { pub fn sitofp(&mut self, from_ty: LlvmType, val: &str, to_ty: LlvmType) -> String { let r = self.reg(); - self.emit(format!("{} = sitofp {} {} to {}", r, from_ty, val, to_ty)); + self.push_inst(crate::inst::LlInst::Cast { + dst: r.clone(), + op: "sitofp", + from: from_ty, + v: val.to_string(), + to: to_ty, + }); r } pub fn uitofp(&mut self, from_ty: LlvmType, val: &str, to_ty: LlvmType) -> String { let r = self.reg(); - self.emit(format!("{} = uitofp {} {} to {}", r, from_ty, val, to_ty)); + self.push_inst(crate::inst::LlInst::Cast { + dst: r.clone(), + op: "uitofp", + from: from_ty, + v: val.to_string(), + to: to_ty, + }); r } pub fn fpext(&mut self, from_ty: LlvmType, val: &str, to_ty: LlvmType) -> String { let r = self.reg(); - self.emit(format!("{} = fpext {} {} to {}", r, from_ty, val, to_ty)); + self.push_inst(crate::inst::LlInst::Cast { + dst: r.clone(), + op: "fpext", + from: from_ty, + v: val.to_string(), + to: to_ty, + }); r } pub fn fptrunc(&mut self, from_ty: LlvmType, val: &str, to_ty: LlvmType) -> String { let r = self.reg(); - self.emit(format!("{} = fptrunc {} {} to {}", r, from_ty, val, to_ty)); + self.push_inst(crate::inst::LlInst::Cast { + dst: r.clone(), + op: "fptrunc", + from: from_ty, + v: val.to_string(), + to: to_ty, + }); r } pub fn fptosi(&mut self, from_ty: LlvmType, val: &str, to_ty: LlvmType) -> String { let r = self.reg(); - self.emit(format!("{} = fptosi {} {} to {}", r, from_ty, val, to_ty)); + self.push_inst(crate::inst::LlInst::Cast { + dst: r.clone(), + op: "fptosi", + from: from_ty, + v: val.to_string(), + to: to_ty, + }); r } pub fn fptoui(&mut self, from_ty: LlvmType, val: &str, to_ty: LlvmType) -> String { let r = self.reg(); - self.emit(format!("{} = fptoui {} {} to {}", r, from_ty, val, to_ty)); + self.push_inst(crate::inst::LlInst::Cast { + dst: r.clone(), + op: "fptoui", + from: from_ty, + v: val.to_string(), + to: to_ty, + }); r } @@ -612,10 +772,12 @@ impl LlBlock { // have it (all Apple Silicon); the tower remains the portable path. if crate::codegen::helpers::jscvt_enabled() { let r = self.reg(); - self.emit(format!( - "{} = call i32 @llvm.aarch64.fjcvtzs(double {})", - r, val - )); + self.push_inst(crate::inst::LlInst::Call { + dst: Some(r.clone()), + ret: "i32", + callee: "llvm.aarch64.fjcvtzs".to_string(), + args: vec![("double", val.to_string())], + }); return r; } let bits = self.bitcast_double_to_i64(val); @@ -660,25 +822,49 @@ impl LlBlock { pub fn trunc(&mut self, from_ty: LlvmType, val: &str, to_ty: LlvmType) -> String { let r = self.reg(); - self.emit(format!("{} = trunc {} {} to {}", r, from_ty, val, to_ty)); + self.push_inst(crate::inst::LlInst::Cast { + dst: r.clone(), + op: "trunc", + from: from_ty, + v: val.to_string(), + to: to_ty, + }); r } pub fn zext(&mut self, from_ty: LlvmType, val: &str, to_ty: LlvmType) -> String { let r = self.reg(); - self.emit(format!("{} = zext {} {} to {}", r, from_ty, val, to_ty)); + self.push_inst(crate::inst::LlInst::Cast { + dst: r.clone(), + op: "zext", + from: from_ty, + v: val.to_string(), + to: to_ty, + }); r } pub fn sext(&mut self, from_ty: LlvmType, val: &str, to_ty: LlvmType) -> String { let r = self.reg(); - self.emit(format!("{} = sext {} {} to {}", r, from_ty, val, to_ty)); + self.push_inst(crate::inst::LlInst::Cast { + dst: r.clone(), + op: "sext", + from: from_ty, + v: val.to_string(), + to: to_ty, + }); r } pub fn inttoptr(&mut self, from_ty: LlvmType, val: &str) -> String { let r = self.reg(); - self.emit(format!("{} = inttoptr {} {} to ptr", r, from_ty, val)); + self.push_inst(crate::inst::LlInst::Cast { + dst: r.clone(), + op: "inttoptr", + from: from_ty, + v: val.to_string(), + to: "ptr", + }); r } @@ -708,10 +894,14 @@ impl LlBlock { // Map bad pointers to a known-safe global that contains 0. let safe_ptr = { let r = self.reg(); - self.emit(format!( - "{} = select i1 {}, ptr @perry_null_guard_zero, ptr {}", - r, is_bad, handle_ptr - )); + self.push_inst(crate::inst::LlInst::Select { + dst: r.clone(), + cond_ty: "i1", + cond: is_bad.clone(), + ty: "ptr", + a: "@perry_null_guard_zero".to_string(), + b: handle_ptr.clone(), + }); r }; // NOTE: must NOT use `!invariant.load` here. This helper is the @@ -730,7 +920,13 @@ impl LlBlock { pub fn ptrtoint(&mut self, val: &str, to_ty: LlvmType) -> String { let r = self.reg(); - self.emit(format!("{} = ptrtoint ptr {} to {}", r, val, to_ty)); + self.push_inst(crate::inst::LlInst::Cast { + dst: r.clone(), + op: "ptrtoint", + from: "ptr", + v: val.to_string(), + to: to_ty, + }); r } @@ -738,19 +934,40 @@ impl LlBlock { pub fn add(&mut self, ty: LlvmType, a: &str, b: &str) -> String { let r = self.reg(); - self.emit(format!("{} = add {} {}, {}", r, ty, a, b)); + self.push_inst(crate::inst::LlInst::Bin { + dst: r.clone(), + op: "add", + pre: "", + ty, + a: a.to_string(), + b: b.to_string(), + }); r } pub fn sub(&mut self, ty: LlvmType, a: &str, b: &str) -> String { let r = self.reg(); - self.emit(format!("{} = sub {} {}, {}", r, ty, a, b)); + self.push_inst(crate::inst::LlInst::Bin { + dst: r.clone(), + op: "sub", + pre: "", + ty, + a: a.to_string(), + b: b.to_string(), + }); r } pub fn mul(&mut self, ty: LlvmType, a: &str, b: &str) -> String { let r = self.reg(); - self.emit(format!("{} = mul {} {}, {}", r, ty, a, b)); + self.push_inst(crate::inst::LlInst::Bin { + dst: r.clone(), + op: "mul", + pre: "", + ty, + a: a.to_string(), + b: b.to_string(), + }); r } @@ -759,7 +976,14 @@ impl LlBlock { /// `frem double` lowers to on ARM. pub fn srem(&mut self, ty: LlvmType, a: &str, b: &str) -> String { let r = self.reg(); - self.emit(format!("{} = srem {} {}, {}", r, ty, a, b)); + self.push_inst(crate::inst::LlInst::Bin { + dst: r.clone(), + op: "srem", + pre: "", + ty, + a: a.to_string(), + b: b.to_string(), + }); r } @@ -767,43 +991,92 @@ impl LlBlock { /// division paths; JS `/` currently lowers through double division. pub fn sdiv(&mut self, ty: LlvmType, a: &str, b: &str) -> String { let r = self.reg(); - self.emit(format!("{} = sdiv {} {}, {}", r, ty, a, b)); + self.push_inst(crate::inst::LlInst::Bin { + dst: r.clone(), + op: "sdiv", + pre: "", + ty, + a: a.to_string(), + b: b.to_string(), + }); r } pub fn and(&mut self, ty: LlvmType, a: &str, b: &str) -> String { let r = self.reg(); - self.emit(format!("{} = and {} {}, {}", r, ty, a, b)); + self.push_inst(crate::inst::LlInst::Bin { + dst: r.clone(), + op: "and", + pre: "", + ty, + a: a.to_string(), + b: b.to_string(), + }); r } pub fn or(&mut self, ty: LlvmType, a: &str, b: &str) -> String { let r = self.reg(); - self.emit(format!("{} = or {} {}, {}", r, ty, a, b)); + self.push_inst(crate::inst::LlInst::Bin { + dst: r.clone(), + op: "or", + pre: "", + ty, + a: a.to_string(), + b: b.to_string(), + }); r } pub fn xor(&mut self, ty: LlvmType, a: &str, b: &str) -> String { let r = self.reg(); - self.emit(format!("{} = xor {} {}, {}", r, ty, a, b)); + self.push_inst(crate::inst::LlInst::Bin { + dst: r.clone(), + op: "xor", + pre: "", + ty, + a: a.to_string(), + b: b.to_string(), + }); r } pub fn shl(&mut self, ty: LlvmType, a: &str, b: &str) -> String { let r = self.reg(); - self.emit(format!("{} = shl {} {}, {}", r, ty, a, b)); + self.push_inst(crate::inst::LlInst::Bin { + dst: r.clone(), + op: "shl", + pre: "", + ty, + a: a.to_string(), + b: b.to_string(), + }); r } pub fn ashr(&mut self, ty: LlvmType, a: &str, b: &str) -> String { let r = self.reg(); - self.emit(format!("{} = ashr {} {}, {}", r, ty, a, b)); + self.push_inst(crate::inst::LlInst::Bin { + dst: r.clone(), + op: "ashr", + pre: "", + ty, + a: a.to_string(), + b: b.to_string(), + }); r } pub fn lshr(&mut self, ty: LlvmType, a: &str, b: &str) -> String { let r = self.reg(); - self.emit(format!("{} = lshr {} {}, {}", r, ty, a, b)); + self.push_inst(crate::inst::LlInst::Bin { + dst: r.clone(), + op: "lshr", + pre: "", + ty, + a: a.to_string(), + b: b.to_string(), + }); r } @@ -818,10 +1091,14 @@ impl LlBlock { false_val: &str, ) -> String { let r = self.reg(); - self.emit(format!( - "{} = select {} {}, {} {}, {} {}", - r, cond_ty, cond, ty, true_val, ty, false_val - )); + self.push_inst(crate::inst::LlInst::Select { + dst: r.clone(), + cond_ty, + cond: cond.to_string(), + ty, + a: true_val.to_string(), + b: false_val.to_string(), + }); r } @@ -833,19 +1110,24 @@ impl LlBlock { // codegen finishes to auto-link the providing crate. crate::ext_registry::record_ffi_call(func_name); let r = self.reg(); - let arg_str = format_args(args); - self.emit(format!( - "{} = call {} @{}({})", - r, ret_ty, func_name, arg_str - )); + self.push_inst(crate::inst::LlInst::Call { + dst: Some(r.clone()), + ret: ret_ty, + callee: func_name.to_string(), + args: args.iter().map(|(t, v)| (*t, v.to_string())).collect(), + }); r } pub fn call_void(&mut self, func_name: &str, args: &[(LlvmType, &str)]) { // #835 + #846: same registry hook as `call` — see comment there. crate::ext_registry::record_ffi_call(func_name); - let arg_str = format_args(args); - self.emit(format!("call void @{}({})", func_name, arg_str)); + self.push_inst(crate::inst::LlInst::Call { + dst: None, + ret: "void", + callee: func_name.to_string(), + args: args.iter().map(|(t, v)| (*t, v.to_string())).collect(), + }); } /// Empty inline-asm barrier (`call void asm sideeffect "", ""()`). @@ -857,7 +1139,7 @@ impl LlBlock { /// `for (let i=0;i String { let r = self.reg(); - let arg_str = format_args(args); - let param_types: Vec<&str> = args.iter().map(|(t, _)| *t).collect(); - self.emit(format!( - "{} = call {} ({})* {}({})", - r, - ret_ty, - param_types.join(", "), - fn_ptr, - arg_str - )); + self.push_inst(crate::inst::LlInst::CallIndirect { + dst: r.clone(), + ret: ret_ty, + fptr: fn_ptr.to_string(), + args: args.iter().map(|(t, v)| (*t, v.to_string())).collect(), + }); r } // -------- Control flow -------- pub fn br(&mut self, target: &str) { - self.emit(format!("br label %{}", target)); + self.push_inst(crate::inst::LlInst::Br { + label: target.to_string(), + }); self.terminated = true; } pub fn cond_br(&mut self, cond: &str, true_label: &str, false_label: &str) { - self.emit(format!( - "br i1 {}, label %{}, label %{}", - cond, true_label, false_label - )); + self.push_inst(crate::inst::LlInst::CondBr { + cond: cond.to_string(), + t: true_label.to_string(), + f: false_label.to_string(), + }); self.terminated = true; } pub fn ret(&mut self, ty: LlvmType, val: &str) { - self.emit(format!("ret {} {}", ty, val)); + self.push_inst(crate::inst::LlInst::Ret { + ty, + val: val.to_string(), + }); self.terminated = true; } pub fn ret_void(&mut self) { - self.emit("ret void"); + self.push_inst(crate::inst::LlInst::RetVoid); self.terminated = true; } pub fn unreachable(&mut self) { - self.emit("unreachable"); + self.push_inst(crate::inst::LlInst::Unreachable); self.terminated = true; } @@ -914,15 +1198,13 @@ impl LlBlock { pub fn gep(&mut self, base_ty: LlvmType, ptr: &str, indices: &[(LlvmType, &str)]) -> String { let r = self.reg(); - let idx_str = indices - .iter() - .map(|(t, v)| format!("{} {}", t, v)) - .collect::>() - .join(", "); - self.emit(format!( - "{} = getelementptr {}, ptr {}, {}", - r, base_ty, ptr, idx_str - )); + self.push_inst(crate::inst::LlInst::Gep { + dst: r.clone(), + inbounds: false, + ty: base_ty, + ptr: ptr.to_string(), + idxs: indices.iter().map(|(t, v)| (*t, v.to_string())).collect(), + }); r } @@ -938,36 +1220,46 @@ impl LlBlock { indices: &[(LlvmType, &str)], ) -> String { let r = self.reg(); - let idx_str = indices - .iter() - .map(|(t, v)| format!("{} {}", t, v)) - .collect::>() - .join(", "); - self.emit(format!( - "{} = getelementptr inbounds {}, ptr {}, {}", - r, base_ty, ptr, idx_str - )); + self.push_inst(crate::inst::LlInst::Gep { + dst: r.clone(), + inbounds: true, + ty: base_ty, + ptr: ptr.to_string(), + idxs: indices.iter().map(|(t, v)| (*t, v.to_string())).collect(), + }); r } pub fn phi(&mut self, ty: LlvmType, incoming: &[(&str, &str)]) -> String { let r = self.reg(); - let pairs = incoming - .iter() - .map(|(val, label)| format!("[ {}, %{} ]", val, label)) - .collect::>() - .join(", "); - self.emit(format!("{} = phi {} {}", r, ty, pairs)); + self.push_inst(crate::inst::LlInst::Phi { + dst: r.clone(), + ty, + pairs: incoming + .iter() + .map(|(v, l)| (v.to_string(), l.to_string())) + .collect(), + }); r } pub fn to_ir(&self) -> String { let mut out = String::with_capacity( - self.instructions.iter().map(|l| l.len() + 1).sum::() + self.label.len() + 2, + self.instructions + .iter() + .map(|l| l.text_len() + 1) + .sum::() + + self.label.len() + + 2, ); out.push_str(&self.label); out.push_str(":\n"); - out.push_str(&self.instructions.join("\n")); + for (i, inst) in self.instructions.iter().enumerate() { + if i > 0 { + out.push('\n'); + } + inst.render_into(&mut out); + } out } } diff --git a/crates/perry-codegen/src/codegen/mod.rs b/crates/perry-codegen/src/codegen/mod.rs index d192c9b864..3f41e6135f 100644 --- a/crates/perry-codegen/src/codegen/mod.rs +++ b/crates/perry-codegen/src/codegen/mod.rs @@ -2589,6 +2589,11 @@ pub fn compile_module(hir: &HirModule, opts: CompileOptions) -> Result> decide_codegen_units(module_callable_count(hir)) }; if n_units > 1 { + if let Some(result) = + try_native_units(&llmod, n_units, opts.target.as_deref(), &module_prefix) + { + return result; + } let units = llmod.render_codegen_units(n_units); log::debug!( "perry-codegen: split '{}' into {} codegen units", @@ -2613,6 +2618,15 @@ pub fn compile_module(hir: &HirModule, opts: CompileOptions) -> Result> return crate::linker::compile_units_to_object(&units, opts.target.as_deref()); } + // exp/llvm-inprocess Phase 2: `PERRY_LLVM_INPROCESS=native` constructs + // function bodies through the LLVM C API (only the module skeleton is + // textual); `=diff` builds both arms and diffs them. Unit-split and + // emit_ir_only paths above stay textual (they fall into the in-process + // *transport* under these values, so no clang subprocess either way). + if let Some(result) = try_native_construction(&llmod, opts.target.as_deref(), &module_prefix) { + return result; + } + let ll_text = llmod.to_ir(); log::debug!( "perry-codegen: emitted {} bytes of LLVM IR for '{}' ({} interned strings)", @@ -2631,3 +2645,67 @@ pub fn compile_module(hir: &HirModule, opts: CompileOptions) -> Result> crate::linker::compile_ll_to_object(&ll_text, opts.target.as_deref()) } } + +/// exp/llvm-inprocess: unit-split twin of [`try_native_construction`]. +#[cfg(feature = "llvm-inprocess")] +fn try_native_units( + llmod: &crate::module::LlModule, + n_units: usize, + target: Option<&str>, + module_prefix: &str, +) -> Option>> { + match crate::native_emit::native_mode() { + crate::native_emit::NativeMode::Off => None, + crate::native_emit::NativeMode::Native => Some( + crate::native_emit::compile_module_units_native(llmod, n_units, target, module_prefix), + ), + crate::native_emit::NativeMode::Diff => Some( + crate::native_emit::compile_module_units_diff(llmod, n_units, target, module_prefix), + ), + } +} + +#[cfg(not(feature = "llvm-inprocess"))] +fn try_native_units( + _llmod: &crate::module::LlModule, + _n_units: usize, + _target: Option<&str>, + _module_prefix: &str, +) -> Option>> { + None +} + +/// exp/llvm-inprocess Phase 2 dispatch. `None` = native construction not +/// requested (or not compiled in) — continue on the text path. The +/// feature-off twin returns `None` unconditionally; a build without the +/// feature still fails loudly downstream in `compile_ll_to_object` when any +/// in-process mode is requested, so the flag can never silently no-op. +#[cfg(feature = "llvm-inprocess")] +fn try_native_construction( + llmod: &crate::module::LlModule, + target: Option<&str>, + module_prefix: &str, +) -> Option>> { + match crate::native_emit::native_mode() { + crate::native_emit::NativeMode::Off => None, + crate::native_emit::NativeMode::Native => Some(crate::native_emit::compile_module_native( + llmod, + target, + module_prefix, + )), + crate::native_emit::NativeMode::Diff => Some(crate::native_emit::compile_module_diff( + llmod, + target, + module_prefix, + )), + } +} + +#[cfg(not(feature = "llvm-inprocess"))] +fn try_native_construction( + _llmod: &crate::module::LlModule, + _target: Option<&str>, + _module_prefix: &str, +) -> Option>> { + None +} diff --git a/crates/perry-codegen/src/dialect.rs b/crates/perry-codegen/src/dialect.rs new file mode 100644 index 0000000000..c6e81dad96 --- /dev/null +++ b/crates/perry-codegen/src/dialect.rs @@ -0,0 +1,1988 @@ +//! Reader for Perry's LLVM-IR dialect: consumes one finalized function's +//! text (`LlFunction::to_ir()` output) and constructs it natively in an +//! inkwell module. See `native_emit.rs` for where this sits in Phase 2. +//! +//! This is NOT a general LLVM parser — it accepts the closed set of +//! instruction, type, and operand forms perry-codegen emits (bounded by the +//! corpus census in the experiment doc) and errors on anything else, so a +//! new emission form fails loudly at construction instead of silently +//! diverging. The LLVM verifier and `PERRY_LLVM_INPROCESS=diff` are the +//! nets behind it. +//! +//! Instructions keep their textual `%names`, so a natively-built function +//! prints comparably to the text-parsed arm in diff mode. + +use std::collections::HashMap; + +use anyhow::{anyhow, bail, Context as AnyhowContext, Result}; +use inkwell::basic_block::BasicBlock; +use inkwell::builder::Builder; +use inkwell::context::Context; +use inkwell::module::{Linkage, Module}; +use inkwell::types::{BasicType, BasicTypeEnum, FunctionType}; +use inkwell::values::{ + AsValueRef, BasicMetadataValueEnum, BasicValue, BasicValueEnum, FunctionValue, + InstructionValue, PhiValue, +}; +use inkwell::{AddressSpace, FloatPredicate, IntPredicate}; + +/// Create (only) the function declaration for `fn_text`'s define header, so +/// later-defined functions are callable while earlier bodies are read. The +/// native path pre-declares every define before reading any body — calls to +/// module-internal functions are forward references at module scope, exactly +/// like registers are at function scope. +pub(crate) fn predeclare_function_from_text<'ctx>( + context: &'ctx Context, + module: &Module<'ctx>, + fn_text: &str, +) -> Result<()> { + let header = fn_text + .lines() + .next() + .ok_or_else(|| anyhow!("empty function text"))?; + FnReader::declare_from_header(context, module, header)?; + Ok(()) +} + +/// Streaming construction: begin from a define header, feed finalized body +/// lines one at a time (the `LlFunction::for_each_final_line` seam — no +/// per-function text materialization), then `finish`. +pub(crate) struct FnStream<'ctx, 'm> { + inner: FnReader<'ctx, 'm>, +} + +impl<'ctx, 'm> FnStream<'ctx, 'm> { + pub(crate) fn begin( + context: &'ctx Context, + module: &'m Module<'ctx>, + header: &str, + ) -> Result { + Ok(Self { + inner: FnReader::begin(context, module, header)?, + }) + } + + pub(crate) fn line(&mut self, line: &str) -> Result<()> { + let t = line.trim(); + if t.is_empty() || t.starts_with(';') || t == "}" { + return Ok(()); + } + if let Some(label) = t.strip_suffix(':') { + // Block label lines are never indented instructions. + if !line.starts_with(' ') { + return self.inner.enter_block(label); + } + } + self.inner + .instruction(t) + .with_context(|| format!("in line: {t}")) + } + + /// Consume one finalized item — the native fast path. Typed + /// instructions construct directly; only labels, splices, and `Raw` + /// payloads go through the line reader. + pub(crate) fn item(&mut self, item: &crate::function::FinalItem<'_>) -> Result<()> { + use crate::function::FinalItem as FI; + match item { + FI::Label(l) => self.inner.enter_block(l), + FI::Blank => Ok(()), + FI::Text(t) => self.line(t), + FI::Inst(crate::inst::LlInst::Raw(s)) => self.line(s), + FI::Inst(i) => self.inner.typed(i), + } + } + + /// Returns `(typed, raw)` instruction counts — the migration ratchet. + pub(crate) fn finish(self) -> Result<(usize, usize)> { + self.inner.finish() + } +} + +/// Parse `fn_text` (a complete `define ... { ... }`) and build it into +/// `module`. Returns the number of instructions constructed. +pub(crate) fn add_function_from_text<'ctx>( + context: &'ctx Context, + module: &Module<'ctx>, + fn_text: &str, +) -> Result { + let mut lines = fn_text.lines(); + let header = lines.next().ok_or_else(|| anyhow!("empty function text"))?; + let mut stream = FnStream::begin(context, module, header)?; + for line in lines { + stream.line(line)?; + } + stream.finish().map(|(t, r)| t + r) +} + +struct FnReader<'ctx, 'm> { + ctx: &'ctx Context, + module: &'m Module<'ctx>, + builder: Builder<'ctx>, + func: FunctionValue<'ctx>, + /// label -> basic block (created lazily on first reference). + blocks: HashMap>, + /// `%name` -> value. + vals: HashMap>, + /// Phi incomings deferred until every register is defined + /// (loop-carried values are forward references at phi-build time). + pending_phis: Vec<(PhiValue<'ctx>, BasicTypeEnum<'ctx>, Vec<(String, String)>)>, + /// Non-phi forward references (measured in the corpus: the megamorphic + /// `idispatch.tower` shape uses a register before its defining block + /// appears in the text). Each unresolved `%reg` use gets a placeholder + /// that is RAUW'd and erased when the real definition arrives — the + /// same strategy LLVM's own `.ll` parser uses. + /// + /// The placeholder is a `load` from a scratch `alloca` — real + /// instructions the builder can never constant-fold. The first version + /// used `select true, undef, undef`, which the C-API builder folds to + /// the uniqued constant `undef`: un-RAUW-able, verifier-clean, and it + /// silently turned every non-phi forward reference into `undef` (caught + /// as the class-family miscompile: `(number).set is not a function`). + placeholders: HashMap, inkwell::values::PointerValue<'ctx>)>, + /// Most recently *entered* (label line) block, used to keep the + /// function's block order equal to textual order even when a forward + /// branch created the block object earlier. + last_entered: Option>, + positioned: bool, + raw_count: usize, + typed_count: usize, +} + +/// Pieces of a `define [linkage] RET @NAME(T %p, ...) [attrs] {` line. +struct ParsedHeader { + linkage: Option, + ret_tok: String, + name: String, + /// (type token, `%name`) per parameter. + params: Vec<(String, String)>, + attr_str: String, +} + +fn parse_header(header: &str) -> Result { + let rest = header + .strip_prefix("define ") + .ok_or_else(|| anyhow!("not a define line: {header}"))?; + let rest = rest + .strip_suffix('{') + .ok_or_else(|| anyhow!("define line missing open brace"))? + .trim_end(); + + let mut toks = rest.split_whitespace().peekable(); + let mut linkage = None; + if let Some(&t) = toks.peek() { + match t { + "internal" => { + linkage = Some(Linkage::Internal); + toks.next(); + } + "private" => { + linkage = Some(Linkage::Private); + toks.next(); + } + // Explicit default linkage (init_body functions carry it). + "external" => { + toks.next(); + } + _ => {} + } + } + let ret_tok = toks + .next() + .ok_or_else(|| anyhow!("define line missing return type"))? + .to_string(); + + let at = rest + .find('@') + .ok_or_else(|| anyhow!("define line missing @name"))?; + let after = &rest[at + 1..]; + let paren = after + .find('(') + .ok_or_else(|| anyhow!("define line missing param list"))?; + let name = unquote(&after[..paren]); + let close = rmatch_paren(after, paren)?; + let params_str = &after[paren + 1..close]; + let attr_str = after[close + 1..].trim().to_string(); + + let mut params = Vec::new(); + for p in split_top_level(params_str) { + let p = p.trim(); + if p.is_empty() { + continue; + } + let (ty_tok, name_tok) = p + .rsplit_once(' ') + .ok_or_else(|| anyhow!("bad param: {p}"))?; + params.push((ty_tok.trim().to_string(), name_tok.trim().to_string())); + } + Ok(ParsedHeader { + linkage, + ret_tok, + name, + params, + attr_str, + }) +} + +impl<'ctx, 'm> FnReader<'ctx, 'm> { + /// Find-or-create the function for a define header, with its real + /// signature and linkage. Idempotent: pre-declaration and body reading + /// both land here. + fn declare_from_header( + ctx: &'ctx Context, + module: &Module<'ctx>, + header: &str, + ) -> Result> { + let h = parse_header(header)?; + let mut mtypes: Vec = Vec::new(); + for (ty_tok, _) in &h.params { + mtypes.push(basic_type(ctx, ty_tok)?.into()); + } + let fn_type = fn_type_of(ctx, &h.ret_tok, &mtypes)?; + let func = match module.get_function(&h.name) { + Some(f) => f, + None => module.add_function(&h.name, fn_type, None), + }; + if let Some(l) = h.linkage { + func.set_linkage(l); + } + Ok(func) + } + + fn begin(ctx: &'ctx Context, module: &'m Module<'ctx>, header: &str) -> Result { + let h = parse_header(header)?; + let func = Self::declare_from_header(ctx, module, header)?; + // The skeleton never declares defined names (`skeleton_ir` filters + // them), so a body on the function here means a duplicate define. + if func.count_basic_blocks() > 0 { + bail!("duplicate define of @{}", h.name); + } + let param_names: Vec = h.params.iter().map(|(_, n)| n.clone()).collect(); + let attr_str = h.attr_str; + for a in attr_str.split_whitespace() { + match a { + // Attribute-group references: the only group perry stamps on + // defines is #1 (noinline, the setjmp boundary). Group + // contents live in the skeleton for *declares*; for defines + // we apply the concrete attribute. + "#1" => add_enum_attr(ctx, func, "noinline"), + "alwaysinline" | "inlinehint" | "noinline" => add_enum_attr(ctx, func, a), + other => bail!("unknown define attribute `{other}`"), + } + } + for (i, pname) in param_names.iter().enumerate() { + let pv = func + .get_nth_param(i as u32) + .ok_or_else(|| anyhow!("param {i} missing"))?; + pv.set_name(pname.trim_start_matches('%')); + // Params are registered under their `%name`. + } + + let builder = ctx.create_builder(); + let mut vals = HashMap::new(); + for (i, pname) in param_names.iter().enumerate() { + vals.insert(pname.clone(), func.get_nth_param(i as u32).unwrap()); + } + Ok(Self { + ctx, + module, + builder, + func, + blocks: HashMap::new(), + vals, + pending_phis: Vec::new(), + placeholders: HashMap::new(), + last_entered: None, + positioned: false, + raw_count: 0, + typed_count: 0, + }) + } + + fn block(&mut self, label: &str) -> BasicBlock<'ctx> { + if let Some(b) = self.blocks.get(label) { + return *b; + } + let b = self.ctx.append_basic_block(self.func, label); + self.blocks.insert(label.to_string(), b); + b + } + + fn enter_block(&mut self, label: &str) -> Result<()> { + let b = self.block(label); + if let Some(prev) = self.last_entered { + // A forward branch may have created this block before blocks + // that textually precede it; re-anchor to textual order (block + // order is semantically free but affects layout and makes the + // diff harness exact). + let _ = b.move_after(prev); + } + self.last_entered = Some(b); + self.builder.position_at_end(b); + self.positioned = true; + Ok(()) + } + + fn def(&mut self, name: &str, v: BasicValueEnum<'ctx>) -> Result<()> { + if let Some((ph, scratch)) = self.placeholders.remove(name) { + rauw(name, ph, v)?; + if let Some(inst) = ph.as_instruction_value() { + let _ = inst.erase_from_basic_block(); + } + if let Some(inst) = scratch.as_instruction_value() { + let _ = inst.erase_from_basic_block(); + } + } + self.vals.insert(name.to_string(), v); + Ok(()) + } + + /// Resolve `(type, token)` to a value. An undefined `%reg` becomes a + /// typed placeholder resolved by a later `def` (see `placeholders`). + fn val(&mut self, ty: BasicTypeEnum<'ctx>, tok: &str) -> Result> { + let tok = tok.trim(); + if let Some(v) = self.vals.get(tok) { + return Ok(*v); + } + if tok.starts_with('%') { + // Non-foldable placeholder: load from a scratch alloca. Both + // instructions are erased when the definition arrives. + let reg = tok.trim_start_matches('%'); + let scratch = self + .builder + .build_alloca(ty, &format!("fwdslot.{reg}")) + .map_err(be)?; + let ph = self + .builder + .build_load(ty, scratch, &format!("fwd.{reg}")) + .map_err(be)?; + debug_assert!( + ph.as_instruction_value().is_some(), + "placeholder must be a real instruction" + ); + self.placeholders.insert(tok.to_string(), (ph, scratch)); + self.vals.insert(tok.to_string(), ph); + return Ok(ph); + } + constant(self.ctx, self.module, ty, tok) + } + + fn instruction(&mut self, t: &str) -> Result<()> { + if !self.positioned { + bail!("instruction before first block label"); + } + self.raw_count += 1; + // `%r = op ...` vs bare op. + if let Some((lhs, rhs)) = t.split_once(" = ") { + let (op, rest) = rhs + .split_once(' ') + .ok_or_else(|| anyhow!("malformed instruction"))?; + self.value_inst(lhs.trim(), op, rest.trim()) + } else { + let (op, rest) = t.split_once(' ').unwrap_or((t, "")); + self.bare_inst(op, rest.trim()) + } + } + + fn value_inst(&mut self, dst: &str, op: &str, rest: &str) -> Result<()> { + let v: BasicValueEnum = match op { + "alloca" => { + // `alloca T[, align N]` + let ty_tok = rest.split(',').next().unwrap_or(rest).trim(); + let ty = basic_type(self.ctx, ty_tok)?; + let p = self + .builder + .build_alloca(ty, dst.trim_start_matches('%')) + .map_err(be)?; + set_alignment_if_any(p.as_instruction_value(), rest); + p.into() + } + "load" => { + let mut rest2 = rest; + let mut volatile = false; + let mut atomic = false; + loop { + if let Some(r) = rest2.strip_prefix("volatile ") { + volatile = true; + rest2 = r; + } else if let Some(r) = rest2.strip_prefix("atomic ") { + atomic = true; + rest2 = r; + } else { + break; + } + } + self.load(dst, volatile, atomic, rest2)? + } + "fneg" => { + let (ty_tok, vtok) = ty_and_val(rest)?; + let v = self.val(basic_type(self.ctx, ty_tok)?, vtok)?; + self.builder + .build_float_neg(v.into_float_value(), dst.trim_start_matches('%')) + .map_err(be)? + .into() + } + "phi" => return self.phi(dst, rest), + "call" | "tail call" => self + .call(Some(dst), rest)? + .ok_or_else(|| anyhow!("call with result had void type"))?, + "getelementptr" => self.gep(dst, rest)?, + "select" => { + // `select i1 C, T A, T B` + let parts = split_top_level(rest); + if parts.len() != 3 { + bail!("bad select"); + } + let (cty, ctok) = ty_and_val(&parts[0])?; + let cond = self.val(basic_type(self.ctx, cty)?, ctok)?; + let (aty, atok) = ty_and_val(&parts[1])?; + let ty = basic_type(self.ctx, aty)?; + let a = self.val(ty, atok)?; + let (_bty, btok) = ty_and_val(&parts[2])?; + let bv = self.val(ty, btok)?; + self.builder + .build_select(cond.into_int_value(), a, bv, dst.trim_start_matches('%')) + .map_err(be)? + } + _ => self.binary_or_cast(dst, op, rest)?, + }; + self.def(dst, v)?; + Ok(()) + } + + fn bare_inst(&mut self, op: &str, rest: &str) -> Result<()> { + match op { + "store" => { + let volatile = rest.starts_with("volatile "); + let rest = rest.strip_prefix("volatile ").unwrap_or(rest); + // `store T V, ptr P[, align N]` + let parts = split_top_level(rest); + if parts.len() < 2 { + bail!("bad store"); + } + let (vty, vtok) = ty_and_val(&parts[0])?; + let ty = basic_type(self.ctx, vty)?; + let v = self.val(ty, vtok)?; + let (_pty, ptok) = ty_and_val(&parts[1])?; + let p = self.val(self.ctx.ptr_type(AddressSpace::default()).into(), ptok)?; + let inst = self + .builder + .build_store(p.into_pointer_value(), v) + .map_err(be)?; + if volatile { + let _ = inst.set_volatile(true); + } + set_alignment_if_any(Some(inst), rest); + Ok(()) + } + "br" => { + if let Some(lbl) = rest.strip_prefix("label %") { + let b = self.block(lbl.trim()); + self.builder.build_unconditional_branch(b).map_err(be)?; + } else { + // `br i1 C, label %A, label %B` + let parts = split_top_level(rest); + if parts.len() != 3 { + bail!("bad conditional br"); + } + let (cty, ctok) = ty_and_val(&parts[0])?; + let c = self.val(basic_type(self.ctx, cty)?, ctok)?; + let a = self.block(strip_label(&parts[1])?); + let b = self.block(strip_label(&parts[2])?); + self.builder + .build_conditional_branch(c.into_int_value(), a, b) + .map_err(be)?; + } + Ok(()) + } + "ret" => { + if rest == "void" { + self.builder.build_return(None).map_err(be)?; + } else { + let (ty_tok, vtok) = ty_and_val(rest)?; + let ty = basic_type(self.ctx, ty_tok)?; + let v = self.val(ty, vtok)?; + self.builder.build_return(Some(&v)).map_err(be)?; + } + Ok(()) + } + "call" | "tail call" => self.call(None, rest).map(|_| ()), + "switch" => self.switch(rest), + "unreachable" => { + self.builder.build_unreachable().map_err(be)?; + Ok(()) + } + other => bail!("unknown instruction `{other}`"), + } + } + + fn load( + &mut self, + dst: &str, + volatile: bool, + atomic: bool, + rest: &str, + ) -> Result> { + // `T, ptr P[ ][, align N]` + let parts = split_top_level(rest); + if parts.len() < 2 { + bail!("bad load"); + } + let ty = basic_type(self.ctx, parts[0].trim())?; + let (_pty, pval) = ty_and_val(&parts[1])?; + // An atomic load's ordering keyword trails the pointer operand + // (`ptr @g seq_cst`), measured in the corpus census. + let mut ptoks = pval.split_whitespace(); + let ptok = ptoks.next().ok_or_else(|| anyhow!("bad load pointer"))?; + let ordering = ptoks.next(); + let p = self.val(self.ctx.ptr_type(AddressSpace::default()).into(), ptok)?; + let v = self + .builder + .build_load(ty, p.into_pointer_value(), dst.trim_start_matches('%')) + .map_err(be)?; + if volatile { + let _ = v.as_instruction_value().map(|i| i.set_volatile(true)); + } + if rest.contains("!invariant.load") { + if let Some(i) = v.as_instruction_value() { + set_invariant_load(self.ctx, i); + } + } + if atomic { + let ord = match ordering { + Some("seq_cst") => { + llvm_sys::LLVMAtomicOrdering::LLVMAtomicOrderingSequentiallyConsistent + } + Some("acquire") => llvm_sys::LLVMAtomicOrdering::LLVMAtomicOrderingAcquire, + Some("monotonic") => llvm_sys::LLVMAtomicOrdering::LLVMAtomicOrderingMonotonic, + Some("unordered") => llvm_sys::LLVMAtomicOrdering::LLVMAtomicOrderingUnordered, + other => bail!("unsupported atomic ordering {other:?}"), + }; + if let Some(inst) = v.as_instruction_value() { + unsafe { llvm_sys::core::LLVMSetOrdering(inst.as_value_ref(), ord) }; + } + } + set_alignment_if_any(v.as_instruction_value(), rest); + Ok(v) + } + + fn phi(&mut self, dst: &str, rest: &str) -> Result<()> { + // `T [ V, %B ], [ V2, %B2 ], ...` + let (ty_tok, incs) = rest.split_once('[').ok_or_else(|| anyhow!("bad phi"))?; + let ty = basic_type(self.ctx, ty_tok.trim())?; + let phi = self + .builder + .build_phi(ty, dst.trim_start_matches('%')) + .map_err(be)?; + let mut pending = Vec::new(); + for pair in format!("[{incs}").split(']') { + let pair = pair.trim().trim_start_matches(',').trim(); + let Some(body) = pair.strip_prefix('[') else { + continue; + }; + let (v, b) = body + .split_once(',') + .ok_or_else(|| anyhow!("bad phi incoming: {body}"))?; + pending.push(( + v.trim().to_string(), + b.trim().trim_start_matches('%').to_string(), + )); + } + self.def(dst, phi.as_basic_value())?; + self.pending_phis.push((phi, ty, pending)); + Ok(()) + } + + fn gep(&mut self, dst: &str, rest: &str) -> Result> { + let (inbounds, rest) = match rest.strip_prefix("inbounds ") { + Some(r) => (true, r), + None => (false, rest), + }; + let parts = split_top_level(rest); + if parts.len() < 2 { + bail!("bad getelementptr"); + } + let pointee = basic_type(self.ctx, parts[0].trim())?; + let (_pty, ptok) = ty_and_val(&parts[1])?; + let p = self + .val(self.ctx.ptr_type(AddressSpace::default()).into(), ptok)? + .into_pointer_value(); + let mut idx = Vec::new(); + for part in &parts[2..] { + let (ity, itok) = ty_and_val(part)?; + idx.push(self.val(basic_type(self.ctx, ity)?, itok)?.into_int_value()); + } + let name = dst.trim_start_matches('%'); + let v = unsafe { + if inbounds { + self.builder.build_in_bounds_gep(pointee, p, &idx, name) + } else { + self.builder.build_gep(pointee, p, &idx, name) + } + } + .map_err(be)?; + Ok(v.into()) + } + + fn switch(&mut self, rest: &str) -> Result<()> { + // `switch T V, label %DEF [ T C1, label %B1 T C2, label %B2 ... ]` + // (zero occurrences in the corpus census; kept because the semantic + // surface can emit it and losing it would fail loudly anyway). + let (head, cases) = rest.split_once('[').ok_or_else(|| anyhow!("bad switch"))?; + let head_parts = split_top_level(head.trim()); + if head_parts.len() != 2 { + bail!("bad switch head"); + } + let (vty, vtok) = ty_and_val(&head_parts[0])?; + let ty = basic_type(self.ctx, vty)?; + let v = self.val(ty, vtok)?.into_int_value(); + let def = self.block(strip_label(&head_parts[1])?); + // Case list: `T C, label %B` repeated, whitespace-separated. + let mut pairs = Vec::new(); + let toks: Vec<&str> = cases + .trim() + .trim_end_matches(']') + .split_whitespace() + .collect(); + let mut i = 0; + while i + 3 < toks.len() + 1 { + if i + 4 > toks.len() { + break; + } + let cty = toks[i]; + let ctok = toks[i + 1].trim_end_matches(','); + if toks[i + 2] != "label" { + bail!("bad switch case near `{}`", toks[i..].join(" ")); + } + let bb = self.block(toks[i + 3].trim_start_matches('%')); + let cv = self.val(basic_type(self.ctx, cty)?, ctok)?.into_int_value(); + pairs.push((cv, bb)); + i += 4; + } + self.builder.build_switch(v, def, &pairs).map_err(be)?; + Ok(()) + } + + /// Calls: direct `@f(...)`, indirect `%fp(...)` (with or without a + /// pre-opaque `(sig)*` type), and the inline-asm barrier. + fn call(&mut self, dst: Option<&str>, rest: &str) -> Result>> { + // Optional fast-math prefix tokens on float-returning calls. + let rest = rest + .trim_start_matches("reassoc ") + .trim_start_matches("contract ") + .trim_start(); + + // Inline asm: `void asm sideeffect "ASM", "CONSTRAINTS"(ARGS)` + if let Some(asm_rest) = rest.strip_prefix("void asm ") { + return self.call_asm(asm_rest).map(|_| None); + } + + // Return type is the first top-level token; everything from the + // callee marker on is `CALLEE(ARGS)[ #attrs]`. + let callee_pos = rest + .find(['@', '%']) + .ok_or_else(|| anyhow!("call without callee"))?; + let sig_str = rest[..callee_pos].trim().trim_end_matches('*').trim(); + let after = &rest[callee_pos..]; + let paren = after + .find('(') + .ok_or_else(|| anyhow!("call missing arg list"))?; + let callee = &after[..paren]; + let close = rmatch_paren(after, paren)?; + let args_str = &after[paren + 1..close]; + // Trailing callsite attribute-group ref. Only `#0` (returns_twice, + // on setjmp calls) exists in the dialect; the declare carries it too, + // so this is fidelity, not correctness. + let trailing_attr = after[close + 1..].trim(); + + let mut args: Vec = Vec::new(); + let mut arg_types: Vec = Vec::new(); + for a in split_top_level(args_str) { + let (aty, atok) = ty_and_val(&a)?; + let ty = basic_type(self.ctx, aty)?; + args.push(self.val(ty, atok)?.into()); + arg_types.push(ty.into()); + } + + let name = dst.map(|d| d.trim_start_matches('%')).unwrap_or(""); + // The call's function type is the CALLSITE's, not the callee's + // declared signature — under opaque pointers LLVM accepts (and Perry + // emits) direct calls whose argument types differ from the declare + // (measured: `js_native_call_value` declared `(double, i64, i64)`, + // called with `(double, ptr, i64)`). Deriving the type from the + // callsite and calling through the callee *pointer* reproduces the + // text parser's semantics exactly; LLVM still prints it as a direct + // call. + let fn_ty = indirect_fn_type(self.ctx, sig_str, &arg_types)?; + let callee_ptr = if let Some(fname) = callee.strip_prefix('@') { + let name = unquote(fname); + let f = match self.module.get_function(&name) { + Some(f) => f, + // LLVM's own .ll parser auto-declares `@llvm.*` intrinsics at + // their first use (perry's clamp lowering emits smax/smin + // calls with no textual declare). Mirror that — for + // intrinsics ONLY; anything else undeclared stays a loud + // error. + None if name.starts_with("llvm.") => self.module.add_function(&name, fn_ty, None), + None => bail!("call to undeclared @{name}"), + }; + f.as_global_value().as_pointer_value() + } else { + self.val(self.ctx.ptr_type(AddressSpace::default()).into(), callee)? + .into_pointer_value() + }; + let site = self + .builder + .build_indirect_call(fn_ty, callee_ptr, &args, name) + .map_err(be)?; + match trailing_attr { + "" => {} + "#0" => { + let kind = inkwell::attributes::Attribute::get_named_enum_kind_id("returns_twice"); + if kind != 0 { + site.add_attribute( + inkwell::attributes::AttributeLoc::Function, + self.ctx.create_enum_attribute(kind, 0), + ); + } + } + other => bail!("unknown callsite attribute `{other}`"), + } + match site.try_as_basic_value() { + inkwell::values::ValueKind::Basic(v) => Ok(Some(v)), + _ => Ok(None), + } + } + + fn call_asm(&mut self, rest: &str) -> Result<()> { + // `sideeffect "ASM", "CONSTR"()` — the only asm perry emits is the + // empty barrier, but parse the strings properly anyway. + let sideeffect = rest.trim_start().starts_with("sideeffect"); + let mut strings = rest.split('"'); + let asm = strings.nth(1).unwrap_or("").to_string(); + let constraints = strings.nth(1).unwrap_or("").to_string(); + let void_fn = self.ctx.void_type().fn_type(&[], false); + let ptr = + self.ctx + .create_inline_asm(void_fn, asm, constraints, sideeffect, false, None, false); + self.builder + .build_indirect_call(void_fn, ptr, &[], "") + .map_err(be)?; + Ok(()) + } + + fn binary_or_cast(&mut self, dst: &str, op: &str, rest: &str) -> Result> { + let name = dst.trim_start_matches('%'); + // Casts: `OP T V to T2` + if let Some((src, dst_ty_tok)) = rest.rsplit_once(" to ") { + let (sty, stok) = ty_and_val(src)?; + let sty_t = basic_type(self.ctx, sty)?; + let v = self.val(sty_t, stok)?; + let dty = basic_type(self.ctx, dst_ty_tok.trim())?; + let out = match op { + "bitcast" => self.builder.build_bit_cast(v, dty, name).map_err(be)?, + "zext" => self + .builder + .build_int_z_extend(v.into_int_value(), dty.into_int_type(), name) + .map_err(be)? + .into(), + "sext" => self + .builder + .build_int_s_extend(v.into_int_value(), dty.into_int_type(), name) + .map_err(be)? + .into(), + "trunc" => self + .builder + .build_int_truncate(v.into_int_value(), dty.into_int_type(), name) + .map_err(be)? + .into(), + "fptosi" => self + .builder + .build_float_to_signed_int(v.into_float_value(), dty.into_int_type(), name) + .map_err(be)? + .into(), + "fptoui" => self + .builder + .build_float_to_unsigned_int(v.into_float_value(), dty.into_int_type(), name) + .map_err(be)? + .into(), + "sitofp" => self + .builder + .build_signed_int_to_float(v.into_int_value(), dty.into_float_type(), name) + .map_err(be)? + .into(), + "uitofp" => self + .builder + .build_unsigned_int_to_float(v.into_int_value(), dty.into_float_type(), name) + .map_err(be)? + .into(), + "fpext" => self + .builder + .build_float_ext(v.into_float_value(), dty.into_float_type(), name) + .map_err(be)? + .into(), + "fptrunc" => self + .builder + .build_float_trunc(v.into_float_value(), dty.into_float_type(), name) + .map_err(be)? + .into(), + "ptrtoint" => self + .builder + .build_ptr_to_int(v.into_pointer_value(), dty.into_int_type(), name) + .map_err(be)? + .into(), + "inttoptr" => self + .builder + .build_int_to_ptr(v.into_int_value(), dty.into_pointer_type(), name) + .map_err(be)? + .into(), + other => bail!("unknown cast `{other}`"), + }; + return Ok(out); + } + + // icmp / fcmp + if op == "icmp" || op == "fcmp" { + let (pred, rest2) = rest.split_once(' ').ok_or_else(|| anyhow!("bad {op}"))?; + let parts = split_top_level(rest2); + if parts.len() != 2 { + bail!("bad {op} operands"); + } + let (ty_tok, atok) = ty_and_val(&parts[0])?; + let ty = basic_type(self.ctx, ty_tok)?; + let a = self.val(ty, atok)?; + let b2 = self.val(ty, parts[1].trim())?; + let out: BasicValueEnum = if op == "icmp" { + // `icmp eq ptr %x, null` is common (null checks) — pointers + // compare directly, same as the text form. + if a.is_pointer_value() { + self.builder + .build_int_compare( + int_pred(pred)?, + a.into_pointer_value(), + b2.into_pointer_value(), + name, + ) + .map_err(be)? + .into() + } else { + self.builder + .build_int_compare( + int_pred(pred)?, + a.into_int_value(), + b2.into_int_value(), + name, + ) + .map_err(be)? + .into() + } + } else { + self.builder + .build_float_compare( + float_pred(pred)?, + a.into_float_value(), + b2.into_float_value(), + name, + ) + .map_err(be)? + .into() + }; + return Ok(out); + } + + // Binary ops: `[flags] T A, B` where op may carry nsw/nuw/fmf tokens. + let op_base = op; + let mut rest2 = rest; + let mut flag_tokens: Vec<&str> = Vec::new(); + loop { + let (first, r) = rest2.split_once(' ').unwrap_or((rest2, "")); + match first { + "nsw" | "nuw" | "reassoc" | "contract" | "arcp" | "afn" | "fast" | "nnan" + | "ninf" | "nsz" | "exact" | "disjoint" => { + flag_tokens.push(first); + rest2 = r; + } + _ => break, + } + } + let parts = split_top_level(rest2); + if parts.len() != 2 { + bail!("bad binary op `{op}` operands: {rest}"); + } + let (ty_tok, atok) = ty_and_val(&parts[0])?; + let ty = basic_type(self.ctx, ty_tok)?; + let a = self.val(ty, atok)?; + let b2 = self.val(ty, parts[1].trim())?; + let nm = name; + let out: BasicValueEnum = match op_base { + "add" => self + .builder + .build_int_add(a.into_int_value(), b2.into_int_value(), nm) + .map_err(be)? + .into(), + "sub" => self + .builder + .build_int_sub(a.into_int_value(), b2.into_int_value(), nm) + .map_err(be)? + .into(), + "mul" => self + .builder + .build_int_mul(a.into_int_value(), b2.into_int_value(), nm) + .map_err(be)? + .into(), + "sdiv" => self + .builder + .build_int_signed_div(a.into_int_value(), b2.into_int_value(), nm) + .map_err(be)? + .into(), + "udiv" => self + .builder + .build_int_unsigned_div(a.into_int_value(), b2.into_int_value(), nm) + .map_err(be)? + .into(), + "srem" => self + .builder + .build_int_signed_rem(a.into_int_value(), b2.into_int_value(), nm) + .map_err(be)? + .into(), + "urem" => self + .builder + .build_int_unsigned_rem(a.into_int_value(), b2.into_int_value(), nm) + .map_err(be)? + .into(), + "and" => self + .builder + .build_and(a.into_int_value(), b2.into_int_value(), nm) + .map_err(be)? + .into(), + "or" => self + .builder + .build_or(a.into_int_value(), b2.into_int_value(), nm) + .map_err(be)? + .into(), + "xor" => self + .builder + .build_xor(a.into_int_value(), b2.into_int_value(), nm) + .map_err(be)? + .into(), + "shl" => self + .builder + .build_left_shift(a.into_int_value(), b2.into_int_value(), nm) + .map_err(be)? + .into(), + "lshr" => self + .builder + .build_right_shift(a.into_int_value(), b2.into_int_value(), false, nm) + .map_err(be)? + .into(), + "ashr" => self + .builder + .build_right_shift(a.into_int_value(), b2.into_int_value(), true, nm) + .map_err(be)? + .into(), + "fadd" => self + .builder + .build_float_add(a.into_float_value(), b2.into_float_value(), nm) + .map_err(be)? + .into(), + "fsub" => self + .builder + .build_float_sub(a.into_float_value(), b2.into_float_value(), nm) + .map_err(be)? + .into(), + "fmul" => self + .builder + .build_float_mul(a.into_float_value(), b2.into_float_value(), nm) + .map_err(be)? + .into(), + "fdiv" => self + .builder + .build_float_div(a.into_float_value(), b2.into_float_value(), nm) + .map_err(be)? + .into(), + "frem" => self + .builder + .build_float_rem(a.into_float_value(), b2.into_float_value(), nm) + .map_err(be)? + .into(), + other => bail!("unknown instruction `{other}`"), + }; + apply_flags(out.as_instruction_value(), &flag_tokens); + Ok(out) + } + + /// Construct one typed instruction directly — the no-text fast path. + /// Each arm mirrors the corresponding string-parser arm exactly; the + /// parser remains authoritative for `Raw` lines and the corpus tests. + fn typed(&mut self, inst: &crate::inst::LlInst) -> Result<()> { + use crate::inst::{LlInst as I, LoadFlavor as LF}; + if !self.positioned { + bail!("instruction before first block label"); + } + self.typed_count += 1; + match inst { + I::Raw(_) => unreachable!("Raw goes through the line reader"), + I::Bin { + dst, + op, + pre, + ty, + a, + b, + } => { + let t = basic_type(self.ctx, ty)?; + let av = self.val(t, a)?; + let bv = self.val(t, b)?; + let name = dst.trim_start_matches('%'); + let out: BasicValueEnum = match *op { + "add" => self + .builder + .build_int_add(av.into_int_value(), bv.into_int_value(), name) + .map_err(be)? + .into(), + "sub" => self + .builder + .build_int_sub(av.into_int_value(), bv.into_int_value(), name) + .map_err(be)? + .into(), + "mul" => self + .builder + .build_int_mul(av.into_int_value(), bv.into_int_value(), name) + .map_err(be)? + .into(), + "sdiv" => self + .builder + .build_int_signed_div(av.into_int_value(), bv.into_int_value(), name) + .map_err(be)? + .into(), + "srem" => self + .builder + .build_int_signed_rem(av.into_int_value(), bv.into_int_value(), name) + .map_err(be)? + .into(), + "and" => self + .builder + .build_and(av.into_int_value(), bv.into_int_value(), name) + .map_err(be)? + .into(), + "or" => self + .builder + .build_or(av.into_int_value(), bv.into_int_value(), name) + .map_err(be)? + .into(), + "xor" => self + .builder + .build_xor(av.into_int_value(), bv.into_int_value(), name) + .map_err(be)? + .into(), + "shl" => self + .builder + .build_left_shift(av.into_int_value(), bv.into_int_value(), name) + .map_err(be)? + .into(), + "lshr" => self + .builder + .build_right_shift(av.into_int_value(), bv.into_int_value(), false, name) + .map_err(be)? + .into(), + "ashr" => self + .builder + .build_right_shift(av.into_int_value(), bv.into_int_value(), true, name) + .map_err(be)? + .into(), + "fadd" => self + .builder + .build_float_add(av.into_float_value(), bv.into_float_value(), name) + .map_err(be)? + .into(), + "fsub" => self + .builder + .build_float_sub(av.into_float_value(), bv.into_float_value(), name) + .map_err(be)? + .into(), + "fmul" => self + .builder + .build_float_mul(av.into_float_value(), bv.into_float_value(), name) + .map_err(be)? + .into(), + "fdiv" => self + .builder + .build_float_div(av.into_float_value(), bv.into_float_value(), name) + .map_err(be)? + .into(), + "frem" => self + .builder + .build_float_rem(av.into_float_value(), bv.into_float_value(), name) + .map_err(be)? + .into(), + other => bail!("typed Bin: unknown op `{other}`"), + }; + if !pre.is_empty() { + let toks: Vec<&str> = pre.split_whitespace().collect(); + apply_flags(out.as_instruction_value(), &toks); + } + self.def(dst, out) + } + I::FNeg { dst, pre, a } => { + let t = basic_type(self.ctx, "double")?; + let av = self.val(t, a)?; + let out: BasicValueEnum = self + .builder + .build_float_neg(av.into_float_value(), dst.trim_start_matches('%')) + .map_err(be)? + .into(); + if !pre.is_empty() { + let toks: Vec<&str> = pre.split_whitespace().collect(); + apply_flags(out.as_instruction_value(), &toks); + } + self.def(dst, out) + } + I::FCmp { dst, pred, a, b } => { + let t = basic_type(self.ctx, "double")?; + let av = self.val(t, a)?; + let bv = self.val(t, b)?; + let out: BasicValueEnum = self + .builder + .build_float_compare( + float_pred(pred)?, + av.into_float_value(), + bv.into_float_value(), + dst.trim_start_matches('%'), + ) + .map_err(be)? + .into(); + self.def(dst, out) + } + I::ICmp { + dst, + pred, + ty, + a, + b, + } => { + let t = basic_type(self.ctx, ty)?; + let av = self.val(t, a)?; + let bv = self.val(t, b)?; + let name = dst.trim_start_matches('%'); + let out: BasicValueEnum = if av.is_pointer_value() { + self.builder + .build_int_compare( + int_pred(pred)?, + av.into_pointer_value(), + bv.into_pointer_value(), + name, + ) + .map_err(be)? + .into() + } else { + self.builder + .build_int_compare( + int_pred(pred)?, + av.into_int_value(), + bv.into_int_value(), + name, + ) + .map_err(be)? + .into() + }; + self.def(dst, out) + } + I::Alloca { dst, ty } => { + let t = basic_type(self.ctx, ty)?; + let out = self + .builder + .build_alloca(t, dst.trim_start_matches('%')) + .map_err(be)?; + self.def(dst, out.into()) + } + I::Load { + dst, + ty, + ptr, + flavor, + } => { + let t = basic_type(self.ctx, ty)?; + let p = self + .val(self.ctx.ptr_type(AddressSpace::default()).into(), ptr)? + .into_pointer_value(); + let v = self + .builder + .build_load(t, p, dst.trim_start_matches('%')) + .map_err(be)?; + match flavor { + LF::Plain => {} + LF::Aligned(n) => { + let _ = v.as_instruction_value().map(|i| i.set_alignment(*n)); + } + LF::Volatile => { + let _ = v.as_instruction_value().map(|i| i.set_volatile(true)); + } + LF::AtomicSeqCst(n) => { + if let Some(i) = v.as_instruction_value() { + unsafe { + llvm_sys::core::LLVMSetOrdering( + i.as_value_ref(), + llvm_sys::LLVMAtomicOrdering::LLVMAtomicOrderingSequentiallyConsistent, + ) + }; + let _ = i.set_alignment(*n); + } + } + LF::Invariant => { + if let Some(i) = v.as_instruction_value() { + set_invariant_load(self.ctx, i); + } + } + } + self.def(dst, v) + } + I::Store { + ty, + val, + ptr, + volatile, + align, + } => { + let t = basic_type(self.ctx, ty)?; + let v = self.val(t, val)?; + let p = self + .val(self.ctx.ptr_type(AddressSpace::default()).into(), ptr)? + .into_pointer_value(); + let inst = self.builder.build_store(p, v).map_err(be)?; + if *volatile { + let _ = inst.set_volatile(true); + } + if let Some(n) = align { + let _ = inst.set_alignment(*n); + } + Ok(()) + } + I::Cast { + dst, + op, + from, + v, + to, + } => { + let sty = basic_type(self.ctx, from)?; + let sv = self.val(sty, v)?; + let dty = basic_type(self.ctx, to)?; + let name = dst.trim_start_matches('%'); + let out: BasicValueEnum = match *op { + "bitcast" => self.builder.build_bit_cast(sv, dty, name).map_err(be)?, + "zext" => self + .builder + .build_int_z_extend(sv.into_int_value(), dty.into_int_type(), name) + .map_err(be)? + .into(), + "sext" => self + .builder + .build_int_s_extend(sv.into_int_value(), dty.into_int_type(), name) + .map_err(be)? + .into(), + "trunc" => self + .builder + .build_int_truncate(sv.into_int_value(), dty.into_int_type(), name) + .map_err(be)? + .into(), + "fptosi" => self + .builder + .build_float_to_signed_int(sv.into_float_value(), dty.into_int_type(), name) + .map_err(be)? + .into(), + "fptoui" => self + .builder + .build_float_to_unsigned_int( + sv.into_float_value(), + dty.into_int_type(), + name, + ) + .map_err(be)? + .into(), + "sitofp" => self + .builder + .build_signed_int_to_float(sv.into_int_value(), dty.into_float_type(), name) + .map_err(be)? + .into(), + "uitofp" => self + .builder + .build_unsigned_int_to_float( + sv.into_int_value(), + dty.into_float_type(), + name, + ) + .map_err(be)? + .into(), + "fpext" => self + .builder + .build_float_ext(sv.into_float_value(), dty.into_float_type(), name) + .map_err(be)? + .into(), + "fptrunc" => self + .builder + .build_float_trunc(sv.into_float_value(), dty.into_float_type(), name) + .map_err(be)? + .into(), + "ptrtoint" => self + .builder + .build_ptr_to_int(sv.into_pointer_value(), dty.into_int_type(), name) + .map_err(be)? + .into(), + "inttoptr" => self + .builder + .build_int_to_ptr(sv.into_int_value(), dty.into_pointer_type(), name) + .map_err(be)? + .into(), + other => bail!("typed Cast: unknown op `{other}`"), + }; + self.def(dst, out) + } + I::Select { + dst, + cond_ty, + cond, + ty, + a, + b, + } => { + let ct = basic_type(self.ctx, cond_ty)?; + let cv = self.val(ct, cond)?; + let t = basic_type(self.ctx, ty)?; + let av = self.val(t, a)?; + let bv = self.val(t, b)?; + let out = self + .builder + .build_select(cv.into_int_value(), av, bv, dst.trim_start_matches('%')) + .map_err(be)?; + self.def(dst, out) + } + I::Call { + dst, + ret, + callee, + args, + } => { + let mut argv: Vec = Vec::with_capacity(args.len()); + let mut argtys: Vec = + Vec::with_capacity(args.len()); + for (t, v) in args { + let bt = basic_type(self.ctx, t)?; + argv.push(self.val(bt, v)?.into()); + argtys.push(bt.into()); + } + let fn_ty = fn_type_of(self.ctx, ret, &argtys)?; + let f = match self.module.get_function(callee) { + Some(f) => f, + None if callee.starts_with("llvm.") => { + self.module.add_function(callee, fn_ty, None) + } + None => bail!("call to undeclared @{callee}"), + }; + let site = self + .builder + .build_indirect_call( + fn_ty, + f.as_global_value().as_pointer_value(), + &argv, + dst.as_deref() + .map(|d| d.trim_start_matches('%')) + .unwrap_or(""), + ) + .map_err(be)?; + if let Some(d) = dst { + match site.try_as_basic_value() { + inkwell::values::ValueKind::Basic(v) => self.def(d, v)?, + other => bail!("typed call expected a value, got {other:?}"), + } + } + Ok(()) + } + I::CallIndirect { + dst, + ret, + fptr, + args, + } => { + let mut argv: Vec = Vec::with_capacity(args.len()); + let mut argtys: Vec = + Vec::with_capacity(args.len()); + for (t, v) in args { + let bt = basic_type(self.ctx, t)?; + argv.push(self.val(bt, v)?.into()); + argtys.push(bt.into()); + } + let fn_ty = fn_type_of(self.ctx, ret, &argtys)?; + let fp = self + .val(self.ctx.ptr_type(AddressSpace::default()).into(), fptr)? + .into_pointer_value(); + let site = self + .builder + .build_indirect_call(fn_ty, fp, &argv, dst.trim_start_matches('%')) + .map_err(be)?; + match site.try_as_basic_value() { + inkwell::values::ValueKind::Basic(v) => self.def(dst, v), + other => bail!("typed indirect call expected a value, got {other:?}"), + } + } + I::AsmBarrier => { + let void_fn = self.ctx.void_type().fn_type(&[], false); + let ptr = self.ctx.create_inline_asm( + void_fn, + String::new(), + String::new(), + true, + false, + None, + false, + ); + self.builder + .build_indirect_call(void_fn, ptr, &[], "") + .map_err(be)?; + Ok(()) + } + I::Br { label } => { + let b = self.block(label); + self.builder.build_unconditional_branch(b).map_err(be)?; + Ok(()) + } + I::CondBr { cond, t, f } => { + let cv = self.val(self.ctx.bool_type().into(), cond)?; + let tb = self.block(t); + let fb = self.block(f); + self.builder + .build_conditional_branch(cv.into_int_value(), tb, fb) + .map_err(be)?; + Ok(()) + } + I::Ret { ty, val } => { + let t = basic_type(self.ctx, ty)?; + let v = self.val(t, val)?; + self.builder.build_return(Some(&v)).map_err(be)?; + Ok(()) + } + I::RetVoid => { + self.builder.build_return(None).map_err(be)?; + Ok(()) + } + I::Unreachable => { + self.builder.build_unreachable().map_err(be)?; + Ok(()) + } + I::Gep { + dst, + inbounds, + ty, + ptr, + idxs, + } => { + let pointee = basic_type(self.ctx, ty)?; + let p = self + .val(self.ctx.ptr_type(AddressSpace::default()).into(), ptr)? + .into_pointer_value(); + let mut iv = Vec::with_capacity(idxs.len()); + for (t, v) in idxs { + iv.push(self.val(basic_type(self.ctx, t)?, v)?.into_int_value()); + } + let name = dst.trim_start_matches('%'); + let out = unsafe { + if *inbounds { + self.builder.build_in_bounds_gep(pointee, p, &iv, name) + } else { + self.builder.build_gep(pointee, p, &iv, name) + } + } + .map_err(be)?; + self.def(dst, out.into()) + } + I::Phi { dst, ty, pairs } => { + let t = basic_type(self.ctx, ty)?; + let phi = self + .builder + .build_phi(t, dst.trim_start_matches('%')) + .map_err(be)?; + self.def(dst, phi.as_basic_value())?; + self.pending_phis.push((phi, t, pairs.clone())); + Ok(()) + } + } + } + + fn finish(mut self) -> Result<(usize, usize)> { + // Phi incomings resolve against the COMPLETE value map — no + // placeholders here; an unknown register at this point is a bug. + for (phi, ty, incs) in std::mem::take(&mut self.pending_phis) { + for (vtok, btok) in incs { + let block = *self + .blocks + .get(&btok) + .ok_or_else(|| anyhow!("phi references unknown block %{btok}"))?; + let v = if vtok.starts_with('%') { + *self + .vals + .get(&vtok) + .ok_or_else(|| anyhow!("phi references undefined register {vtok}"))? + } else { + constant(self.ctx, self.module, ty, &vtok)? + }; + phi.add_incoming(&[(&v as &dyn BasicValue, block)]); + } + } + if let Some(name) = self.placeholders.keys().next() { + bail!("register {name} was used but never defined"); + } + Ok((self.typed_count, self.raw_count)) + } +} + +/// Tag a load with `!invariant.load !0` (issue #52 semantics). Kind id via +/// llvm-sys; the node is the empty MDNode, same as the textual `!0 = !{}`. +fn set_invariant_load(ctx: &Context, inst: InstructionValue<'_>) { + use inkwell::context::AsContextRef; + let kind = unsafe { + llvm_sys::core::LLVMGetMDKindIDInContext( + ctx.as_ctx_ref(), + b"invariant.load".as_ptr() as *const std::os::raw::c_char, + 14, + ) + }; + let node = ctx.metadata_node(&[]); + let _ = inst.set_metadata(node, kind); +} + +/// Replace every use of a placeholder with the real definition. A type +/// mismatch means the operand-context type at the USE disagreed with the +/// defining instruction — always a reader bug, and silently leaving the +/// placeholder in place is exactly how the select-undef version shipped a +/// miscompile, so it is a hard error. +fn rauw<'ctx>(name: &str, ph: BasicValueEnum<'ctx>, real: BasicValueEnum<'ctx>) -> Result<()> { + match (ph, real) { + (BasicValueEnum::IntValue(a), BasicValueEnum::IntValue(b)) => a.replace_all_uses_with(b), + (BasicValueEnum::FloatValue(a), BasicValueEnum::FloatValue(b)) => { + a.replace_all_uses_with(b) + } + (BasicValueEnum::PointerValue(a), BasicValueEnum::PointerValue(b)) => { + a.replace_all_uses_with(b) + } + (a, b) => bail!( + "forward reference {name} used as {:?} but defined as {:?}", + a.get_type(), + b.get_type() + ), + } + Ok(()) +} + +// --------------------------------------------------------------------------- +// Small helpers +// --------------------------------------------------------------------------- + +fn be(e: inkwell::builder::BuilderError) -> anyhow::Error { + anyhow!("builder error: {e}") +} + +fn unquote(s: &str) -> String { + s.trim_matches('"').to_string() +} + +/// Find the matching `)` for the `(` at `open` in `s`. +fn rmatch_paren(s: &str, open: usize) -> Result { + let mut depth = 0usize; + for (i, c) in s.char_indices().skip(open) { + match c { + '(' => depth += 1, + ')' => { + depth -= 1; + if depth == 0 { + return Ok(i); + } + } + _ => {} + } + } + bail!("unbalanced parens") +} + +/// Split on top-level commas (not inside (), [], <>, {}). +fn split_top_level(s: &str) -> Vec { + let mut out = Vec::new(); + let mut depth = 0i32; + let mut cur = String::new(); + for c in s.chars() { + match c { + '(' | '[' | '{' | '<' => { + depth += 1; + cur.push(c); + } + ')' | ']' | '}' | '>' => { + depth -= 1; + cur.push(c); + } + ',' if depth == 0 => { + out.push(cur.trim().to_string()); + cur = String::new(); + } + _ => cur.push(c), + } + } + if !cur.trim().is_empty() { + out.push(cur.trim().to_string()); + } + out +} + +/// `"i64 %r5"` -> `("i64", "%r5")`, honoring types with spaces (`[4 x i8]`, +/// `<4 x i32>`) and bracketed values (`<4 x i32> `): the +/// TYPE is parsed greedily from the left (balanced brackets, then trailing +/// `*`s), the remainder is the value. +fn ty_and_val(s: &str) -> Result<(&str, &str)> { + let s = s.trim(); + let bytes = s.as_bytes(); + let ty_end = if bytes[0] == b'[' || bytes[0] == b'<' || bytes[0] == b'{' { + let (open, close) = match bytes[0] { + b'[' => (b'[', b']'), + b'<' => (b'<', b'>'), + _ => (b'{', b'}'), + }; + let mut depth = 0usize; + let mut end = 0usize; + for (i, &c) in bytes.iter().enumerate() { + if c == open { + depth += 1; + } else if c == close { + depth -= 1; + if depth == 0 { + end = i + 1; + break; + } + } + } + if end == 0 { + bail!("unbalanced type brackets in `{s}`"); + } + // Trailing pointer stars (pre-opaque spellings). + while end < bytes.len() && bytes[end] == b'*' { + end += 1; + } + end + } else { + s.find(' ') + .ok_or_else(|| anyhow!("expected `type value`, got `{s}`"))? + }; + Ok((s[..ty_end].trim(), s[ty_end..].trim())) +} + +fn strip_label(s: &str) -> Result<&str> { + s.trim() + .strip_prefix("label %") + .map(str::trim) + .ok_or_else(|| anyhow!("expected `label %...`, got `{s}`")) +} + +fn basic_type<'ctx>(ctx: &'ctx Context, tok: &str) -> Result> { + let tok = tok.trim(); + Ok(match tok { + "double" => ctx.f64_type().into(), + "float" => ctx.f32_type().into(), + "i64" => ctx.i64_type().into(), + "i32" => ctx.i32_type().into(), + "i16" => ctx.i16_type().into(), + "i8" => ctx.i8_type().into(), + "i1" => ctx.bool_type().into(), + "i128" => ctx.i128_type().into(), + "ptr" => ctx.ptr_type(AddressSpace::default()).into(), + _ => { + // `[N x T]` + if let Some(body) = tok.strip_prefix('[').and_then(|t| t.strip_suffix(']')) { + let (n, elem) = body + .split_once(" x ") + .ok_or_else(|| anyhow!("bad array type `{tok}`"))?; + let n: u32 = n.trim().parse()?; + let elem_ty = basic_type(ctx, elem)?; + return Ok(elem_ty.array_type(n).into()); + } + // `` (SIMD in expr/channel.rs) + if let Some(body) = tok.strip_prefix('<').and_then(|t| t.strip_suffix('>')) { + let (n, elem) = body + .split_once(" x ") + .ok_or_else(|| anyhow!("bad vector type `{tok}`"))?; + let n: u32 = n.trim().parse()?; + return Ok(match basic_type(ctx, elem)? { + BasicTypeEnum::IntType(t) => t.vec_type(n).into(), + BasicTypeEnum::FloatType(t) => t.vec_type(n).into(), + BasicTypeEnum::PointerType(t) => t.vec_type(n).into(), + other => bail!("unsupported vector element {other:?}"), + }); + } + // Pre-opaque pointer spellings (`i8*`, `double**`, `(sig)*`) all + // collapse to `ptr` under LLVM 15+ semantics. + if tok.ends_with('*') { + return Ok(ctx.ptr_type(AddressSpace::default()).into()); + } + bail!("unknown type `{tok}`") + } + }) +} + +fn fn_type_of<'ctx>( + ctx: &'ctx Context, + ret_tok: &str, + params: &[inkwell::types::BasicMetadataTypeEnum<'ctx>], +) -> Result> { + Ok(match ret_tok { + "void" => ctx.void_type().fn_type(params, false), + _ => basic_type(ctx, ret_tok)?.fn_type(params, false), + }) +} + +/// Function type for an indirect call site. `sig_str` is either just the +/// return type (`double`) or `RET (T1, T2, ...)`; when only the return type +/// is present the parameter types are taken from the argument list. +fn indirect_fn_type<'ctx>( + ctx: &'ctx Context, + sig_str: &str, + arg_types: &[inkwell::types::BasicMetadataTypeEnum<'ctx>], +) -> Result> { + let sig_str = sig_str.trim(); + if let Some(open) = sig_str.find('(') { + let ret_tok = sig_str[..open].trim(); + let close = rmatch_paren(sig_str, open)?; + let params_str = &sig_str[open + 1..close]; + let mut params: Vec = Vec::new(); + let mut varargs = false; + for p in split_top_level(params_str) { + if p.trim() == "..." { + varargs = true; + continue; + } + params.push(basic_type(ctx, p.trim())?.into()); + } + Ok(match ret_tok { + "void" => ctx.void_type().fn_type(¶ms, varargs), + _ => basic_type(ctx, ret_tok)?.fn_type(¶ms, varargs), + }) + } else { + fn_type_of(ctx, sig_str, arg_types) + } +} + +fn constant<'ctx>( + ctx: &'ctx Context, + module: &Module<'ctx>, + ty: BasicTypeEnum<'ctx>, + tok: &str, +) -> Result> { + if let Some(g) = tok.strip_prefix('@') { + let name = unquote(g); + if let Some(f) = module.get_function(&name) { + return Ok(f.as_global_value().as_pointer_value().into()); + } + if let Some(gv) = module.get_global(&name) { + return Ok(gv.as_pointer_value().into()); + } + bail!("reference to unknown global @{name}"); + } + Ok(match tok { + "null" => ctx.ptr_type(AddressSpace::default()).const_null().into(), + "undef" => match ty { + BasicTypeEnum::FloatType(t) => t.get_undef().into(), + BasicTypeEnum::IntType(t) => t.get_undef().into(), + BasicTypeEnum::PointerType(t) => t.get_undef().into(), + other => bail!("undef of unsupported type {other:?}"), + }, + "poison" => match ty { + BasicTypeEnum::FloatType(t) => t.get_poison().into(), + BasicTypeEnum::IntType(t) => t.get_poison().into(), + BasicTypeEnum::PointerType(t) => t.get_poison().into(), + other => bail!("poison of unsupported type {other:?}"), + }, + "true" => ctx.bool_type().const_int(1, false).into(), + "false" => ctx.bool_type().const_int(0, false).into(), + "zeroinitializer" => match ty { + BasicTypeEnum::FloatType(t) => t.const_zero().into(), + BasicTypeEnum::IntType(t) => t.const_zero().into(), + BasicTypeEnum::ArrayType(t) => t.const_zero().into(), + BasicTypeEnum::PointerType(t) => t.const_null().into(), + other => bail!("zeroinitializer of unsupported type {other:?}"), + }, + _ => match ty { + BasicTypeEnum::FloatType(t) => { + // LLVM hex-float form is raw IEEE-754 bits — exactly how + // NaN-boxed constants must survive. + if let Some(hex) = tok.strip_prefix("0x") { + let bits = u64::from_str_radix(hex, 16) + .map_err(|_| anyhow!("bad hex float `{tok}`"))?; + t.const_float(f64::from_bits(bits)).into() + } else { + t.const_float( + tok.parse::() + .map_err(|_| anyhow!("bad float `{tok}`"))?, + ) + .into() + } + } + BasicTypeEnum::IntType(t) => { + let v: i128 = tok.parse().map_err(|_| anyhow!("bad integer `{tok}`"))?; + t.const_int(v as u64, v < 0).into() + } + other => bail!("cannot materialize `{tok}` as {other:?}"), + }, + }) +} + +fn int_pred(p: &str) -> Result { + Ok(match p { + "eq" => IntPredicate::EQ, + "ne" => IntPredicate::NE, + "slt" => IntPredicate::SLT, + "sle" => IntPredicate::SLE, + "sgt" => IntPredicate::SGT, + "sge" => IntPredicate::SGE, + "ult" => IntPredicate::ULT, + "ule" => IntPredicate::ULE, + "ugt" => IntPredicate::UGT, + "uge" => IntPredicate::UGE, + other => bail!("unknown icmp predicate `{other}`"), + }) +} + +fn float_pred(p: &str) -> Result { + Ok(match p { + "oeq" => FloatPredicate::OEQ, + "one" => FloatPredicate::ONE, + "olt" => FloatPredicate::OLT, + "ole" => FloatPredicate::OLE, + "ogt" => FloatPredicate::OGT, + "oge" => FloatPredicate::OGE, + "ord" => FloatPredicate::ORD, + "ueq" => FloatPredicate::UEQ, + "une" => FloatPredicate::UNE, + "ult" => FloatPredicate::ULT, + "ule" => FloatPredicate::ULE, + "ugt" => FloatPredicate::UGT, + "uge" => FloatPredicate::UGE, + "uno" => FloatPredicate::UNO, + other => bail!("unknown fcmp predicate `{other}`"), + }) +} + +fn add_enum_attr(ctx: &Context, func: FunctionValue<'_>, name: &str) { + let kind = inkwell::attributes::Attribute::get_named_enum_kind_id(name); + if kind != 0 { + let attr = ctx.create_enum_attribute(kind, 0); + func.add_attribute(inkwell::attributes::AttributeLoc::Function, attr); + } +} + +fn set_alignment_if_any(inst: Option>, rest: &str) { + if let (Some(inst), Some(idx)) = (inst, rest.rfind(", align ")) { + if let Ok(align) = rest[idx + ", align ".len()..].trim().parse::() { + let _ = inst.set_alignment(align); + } + } +} + +fn apply_flags(inst: Option>, flags: &[&str]) { + let Some(inst) = inst else { return }; + let mut fmf: u32 = 0; + for f in flags { + match *f { + "reassoc" => fmf |= llvm_sys::LLVMFastMathAllowReassoc, + "contract" => fmf |= llvm_sys::LLVMFastMathAllowContract, + "arcp" => fmf |= llvm_sys::LLVMFastMathAllowReciprocal, + "afn" => fmf |= llvm_sys::LLVMFastMathApproxFunc, + "nnan" => fmf |= llvm_sys::LLVMFastMathNoNaNs, + "ninf" => fmf |= llvm_sys::LLVMFastMathNoInfs, + "nsz" => fmf |= llvm_sys::LLVMFastMathNoSignedZeros, + "fast" => fmf |= llvm_sys::LLVMFastMathAll, + "nsw" => unsafe { + llvm_sys::core::LLVMSetNSW(inst.as_value_ref(), 1); + }, + "nuw" => unsafe { + llvm_sys::core::LLVMSetNUW(inst.as_value_ref(), 1); + }, + "exact" => unsafe { + llvm_sys::core::LLVMSetExact(inst.as_value_ref(), 1); + }, + _ => {} + } + } + if fmf != 0 { + unsafe { llvm_sys::core::LLVMSetFastMathFlags(inst.as_value_ref(), fmf) }; + } +} + +#[cfg(test)] +mod tests { + use super::*; + + fn split_corpus(text: &str) -> (String, Vec) { + let mut skeleton = String::new(); + let mut fns = Vec::new(); + let mut cur: Option = None; + for line in text.lines() { + if line.starts_with("define ") { + cur = Some(String::new()); + } + match cur.as_mut() { + Some(f) => { + f.push_str(line); + f.push('\n'); + if line == "}" { + fns.push(cur.take().unwrap()); + } + } + None => { + skeleton.push_str(line); + skeleton.push('\n'); + } + } + } + (skeleton, fns) + } + + /// Every function in a real perry-emitted corpus file must construct + /// natively and pass the LLVM verifier. This is the reader's primary + /// gate: a form it cannot express fails here, not in a user build. + fn corpus_roundtrip(path: &str) { + // The corpora are tracked in-tree alongside this reader, so a missing + // file is a broken checkout, not a branch without artifacts. Skipping + // would make the reader's primary gate pass vacuously — precisely the + // failure mode the Linux bring-up had to rule out by hand. + let text = std::fs::read_to_string(path) + .unwrap_or_else(|e| panic!("corpus file {path} is not readable: {e}")); + let (skeleton, fns) = split_corpus(&text); + let ctx = Context::create(); + let module = crate::inprocess::parse_ir_text(&ctx, &skeleton, "corpus_skel") + .expect("skeleton parses"); + for f in &fns { + predeclare_function_from_text(&ctx, &module, f) + .unwrap_or_else(|e| panic!("predeclare: {e:#}")); + } + let mut n = 0usize; + for f in &fns { + n += add_function_from_text(&ctx, &module, f).unwrap_or_else(|e| panic!("{e:#}")); + } + assert!( + n > 1000, + "expected a real corpus, built only {n} instructions" + ); + module + .verify() + .unwrap_or_else(|e| panic!("verifier rejected native module:\n{}", e.to_string())); + } + + #[test] + fn corpus_spike() { + corpus_roundtrip(concat!( + env!("CARGO_MANIFEST_DIR"), + "/../../experiments/llvm-inprocess-spike/spike_text.ll" + )); + } + + #[test] + fn corpus_batch_kernel() { + corpus_roundtrip(concat!( + env!("CARGO_MANIFEST_DIR"), + "/../../experiments/llvm-inprocess-spike/batch_kernel.ll" + )); + } +} diff --git a/crates/perry-codegen/src/function.rs b/crates/perry-codegen/src/function.rs index 5f55a76c45..dd2af748fe 100644 --- a/crates/perry-codegen/src/function.rs +++ b/crates/perry-codegen/src/function.rs @@ -580,7 +580,7 @@ impl LlFunction { let body: usize = self .blocks .iter() - .map(|b| b.instructions_iter().map(|i| i.len() + 1).sum::() + b.label.len() + 4) + .map(|b| b.insts().iter().map(|i| i.text_len() + 1).sum::() + b.label.len() + 4) .sum(); let allocas: usize = self.entry_allocas.iter().map(|a| a.len() + 1).sum(); body + allocas + self.name.len() + 64 @@ -616,120 +616,202 @@ impl LlFunction { "define {}{} @{}({}){} {{\n", linkage, self.return_type, self.name, param_str, attrs ); + self.for_each_final_line::(&mut |line| { + ir.push_str(line); + ir.push('\n'); + Ok(()) + }) + .unwrap_or_else(|e| match e {}); + ir.push_str("}\n"); + // setjmp volatile promotion (#6385). + // + // Runs LAST so it sees every instruction, including the return-site + // rewrites the visitor just streamed in. Any alloca this function + // stores into between a `setjmp` and its `longjmp` (recorded by + // `LlBlock::emit` while a try region was open) gets `volatile` loads + // and stores, which is what stops mem2reg/SROA from promoting it into + // a register that `longjmp` would revert. + if self.has_try { + let try_stores = self.reg_counter.try_region_stores(); + if !try_stores.is_empty() { + return crate::volatile_setjmp::apply_setjmp_volatile(&ir, &try_stores); + } + } + + ir + } + + /// Stream every finalized BODY line of this function (block labels, + /// entry-alloca and post-init splices, instructions, return-site + /// rewrites; blank separator lines between blocks) in exactly the order + /// [`to_ir`] renders them — `to_ir` IS this visitor plus the define + /// header, closing brace, and the setjmp volatile pass (which needs + /// whole-function analysis and therefore text; native construction + /// falls back to `to_ir` for `has_try` functions). + /// + /// This is the seam the native backend consumes: per finalized line, + /// no per-function text materialization. + pub fn for_each_final_line( + &self, + sink: &mut dyn FnMut(&str) -> Result<(), E>, + ) -> Result<(), E> { + let mut buf = String::new(); + self.for_each_final_item::(&mut |item| { + buf.clear(); + match item { + FinalItem::Label(l) => { + buf.push_str(l); + buf.push(':'); + } + FinalItem::Blank => {} + FinalItem::Text(t) => buf.push_str(t), + FinalItem::Inst(i) => i.render_into(&mut buf), + } + sink(&buf) + }) + } + + /// Item-granular twin of [`for_each_final_line`], and the seam the native + /// backend consumes: typed instructions arrive as [`FinalItem::Inst`] and + /// are constructed directly, with no per-line text; only labels, entry + /// splices, synthesized return-site rewrites, and `Raw` payload splits + /// arrive as text. The two visitors cannot drift: the line visitor is a + /// rendering adapter over this one. + pub fn for_each_final_item( + &self, + sink: &mut dyn FnMut(FinalItem<'_>) -> Result<(), E>, + ) -> Result<(), E> { + let rewrite_rets = + self.shadow_frame_slot.is_some() || !self.pre_return_void_calls.is_empty(); + let mut seq: u32 = 0; for (i, blk) in self.blocks.iter().enumerate() { if i > 0 { - ir.push('\n'); + sink(FinalItem::Blank)?; } - // Block 0 (entry) gets two splices in its body: - // 1. `entry_allocas`: hoisted allocas + a few simple init - // sequences. These go at the very top, between the - // label line and any block instructions, so they - // dominate every reachable use in the function. - // 2. `entry_post_init_setup`: hoisted setup that must - // run AFTER the init prelude (gc_init / init_strings - // calls) so it sees the up-to-date module state. The - // splice point is `entry_init_boundary`, which the - // codegen marks immediately after emitting the - // prelude. - // Both splices are textual: we re-render the block label, - // the prefix instructions (up to the boundary), the - // post-init setup, and then the rest of the block body. - if i == 0 && (!self.entry_allocas.is_empty() || !self.entry_post_init_setup.is_empty()) - { - ir.push_str(&blk.label); - ir.push_str(":\n"); - // 1. Allocas + simple inits at the very top. + sink(FinalItem::Label(&blk.label))?; + let is_entry = i == 0; + if is_entry { for alloca in &self.entry_allocas { - ir.push_str(alloca); - ir.push('\n'); + self.text_item(alloca, rewrite_rets, &mut seq, sink)?; } - // 2. Render the block instructions, with the post-init - // splice at the boundary index. - let boundary = self - .entry_init_boundary + } + let boundary = if is_entry { + self.entry_init_boundary .unwrap_or(0) - .min(blk.instruction_count()); - let mut idx = 0; - for inst in blk.instructions_iter() { - if idx == boundary { - for line in &self.entry_post_init_setup { - ir.push_str(line); - ir.push('\n'); - } - } - ir.push_str(inst); - ir.push('\n'); - idx += 1; - } - // Boundary at end-of-block (or empty block). + .min(blk.instruction_count()) + } else { + usize::MAX + }; + let mut idx = 0usize; + for inst in blk.insts() { if idx == boundary { for line in &self.entry_post_init_setup { - ir.push_str(line); - ir.push('\n'); + self.text_item(line, rewrite_rets, &mut seq, sink)?; } } - } else { - ir.push_str(&blk.to_ir()); - ir.push('\n'); + self.inst_item(inst, rewrite_rets, &mut seq, sink)?; + idx += 1; + } + if is_entry && idx == boundary { + for line in &self.entry_post_init_setup { + self.text_item(line, rewrite_rets, &mut seq, sink)?; + } } } + Ok(()) + } - ir.push_str("}\n"); - - // Return-site rewrite hooks. - // - // Shadow-stack pop (gen-GC Phase A sub-phase 2) and entry - // diagnostics both need to run before every normal return, - // regardless of which lowering path emitted it. Textual rewrite - // on the full IR catches implicit returns, Stmt::Return, and any - // hand-emitted `ret`. - let ir = if self.shadow_frame_slot.is_some() || !self.pre_return_void_calls.is_empty() { - let mut out = String::with_capacity(ir.len() + 512); - let mut seq: u32 = 0; - for line in ir.lines() { - let trimmed = line.trim_start(); - if (trimmed.starts_with("ret ") || trimmed == "ret void") - && !trimmed.starts_with("ret ptr ") - // skip rare ptr rets - { - for func_name in &self.pre_return_void_calls { - out.push_str(&format!(" call void @{}()\n", func_name)); - } - if let Some(handle_slot) = &self.shadow_frame_slot { - let load_reg = format!("%shadow_pop_l_{}", seq); - seq += 1; - out.push_str(&format!(" {} = load i64, ptr {}\n", load_reg, handle_slot)); - out.push_str(&format!( - " call void @js_shadow_frame_pop(i64 {})\n", - load_reg - )); - } + fn inst_item( + &self, + inst: &crate::inst::LlInst, + rewrite_rets: bool, + seq: &mut u32, + sink: &mut dyn FnMut(FinalItem<'_>) -> Result<(), E>, + ) -> Result<(), E> { + use crate::inst::LlInst; + // Multi-line raw payloads split exactly like text rendering followed + // by the line-based rewrite pass would. + if let LlInst::Raw(s) = inst { + if s.contains('\n') { + for l in s.split('\n') { + self.text_item(l, rewrite_rets, seq, sink)?; } - out.push_str(line); - out.push('\n'); + return Ok(()); } - out - } else { - ir - }; + } + if rewrite_rets { + let is_rewritable_ret = match inst { + LlInst::Ret { ty, .. } => *ty != "ptr", + LlInst::RetVoid => true, + LlInst::Raw(s) => { + let t = s.trim_start(); + (t.starts_with("ret ") || t == "ret void") && !t.starts_with("ret ptr ") + } + _ => false, + }; + if is_rewritable_ret { + self.yield_ret_prologue(seq, sink)?; + } + } + sink(FinalItem::Inst(inst)) + } - // setjmp volatile promotion (#6385). - // - // Runs LAST so it sees every instruction, including the ones the - // return-site rewrite above just spliced in. Any alloca this function - // stores into between a `setjmp` and its `longjmp` (recorded by - // `LlBlock::emit` while a try region was open) gets `volatile` loads - // and stores, which is what stops mem2reg/SROA from promoting it into - // a register that `longjmp` would revert. This replaces the old - // `optnone`-the-whole-function hammer. - if self.has_try { - let try_stores = self.reg_counter.try_region_stores(); - if !try_stores.is_empty() { - return crate::volatile_setjmp::apply_setjmp_volatile(&ir, &try_stores); + /// Return-site rewrite, streamed: before every `ret` (except `ret ptr`), + /// inject the pre-return void calls and the shadow-frame pop. Byte-equal + /// to the old whole-text line scan. + fn text_item( + &self, + line: &str, + rewrite_rets: bool, + seq: &mut u32, + sink: &mut dyn FnMut(FinalItem<'_>) -> Result<(), E>, + ) -> Result<(), E> { + if rewrite_rets { + let trimmed = line.trim_start(); + if (trimmed.starts_with("ret ") || trimmed == "ret void") + && !trimmed.starts_with("ret ptr ") + { + self.yield_ret_prologue(seq, sink)?; } } + sink(FinalItem::Text(line)) + } - ir + fn yield_ret_prologue( + &self, + seq: &mut u32, + sink: &mut dyn FnMut(FinalItem<'_>) -> Result<(), E>, + ) -> Result<(), E> { + for func_name in &self.pre_return_void_calls { + sink(FinalItem::Text(&format!(" call void @{}()", func_name)))?; + } + if let Some(handle_slot) = &self.shadow_frame_slot { + let load_reg = format!("%shadow_pop_l_{}", seq); + *seq += 1; + sink(FinalItem::Text(&format!( + " {} = load i64, ptr {}", + load_reg, handle_slot + )))?; + sink(FinalItem::Text(&format!( + " call void @js_shadow_frame_pop(i64 {})", + load_reg + )))?; + } + Ok(()) } } + +/// One finalized item of a function body. See +/// [`LlFunction::for_each_final_item`]. +pub enum FinalItem<'a> { + /// Block label (no trailing colon). + Label(&'a str), + /// Blank separator line between blocks. + Blank, + /// A pre-rendered text line (entry splices, return-site rewrites, + /// multi-line raw payload splits). + Text(&'a str), + /// A typed instruction — the native backend constructs it directly. + Inst(&'a crate::inst::LlInst), +} diff --git a/crates/perry-codegen/src/inprocess.rs b/crates/perry-codegen/src/inprocess.rs new file mode 100644 index 0000000000..3bc870e6d6 --- /dev/null +++ b/crates/perry-codegen/src/inprocess.rs @@ -0,0 +1,304 @@ +//! In-process `.ll -> .o` compilation through the LLVM C API (exp/llvm-inprocess). +//! +//! Feature-gated (`llvm-inprocess`) and flag-gated (`PERRY_LLVM_INPROCESS=1`): +//! the default build does not link LLVM, and a build that has the feature +//! still uses the `clang -c` subprocess unless the flag is set. Selection and +//! the flag's cache-key participation live in `linker.rs` / +//! `perry/src/commands/compile/{build_cache,object_cache}.rs`. +//! +//! Decision parity by construction: this module does not re-derive opt levels +//! or CPU tuning. It interprets the *same* argv `build_clang_compile_plan` +//! produces for clang (`-O3`/`-Os`/`-O0`, `-mcpu=native`, `-mllvm +//! -inlinehint-threshold=N`, `-target `), so the two backends cannot +//! drift on a decision without drifting on the plan — which the plan's own +//! tests pin. +//! +//! Measured in Phase 0 (see `docs/llvm-inprocess-experiment.md`): on the same +//! IR and flags this pipeline produces objects byte-identical to Homebrew +//! clang 22's `clang -c`. + +use std::ffi::CString; +use std::sync::Once; + +use anyhow::{anyhow, Result}; +use inkwell::context::Context; +use inkwell::memory_buffer::MemoryBuffer; +use inkwell::passes::PassBuilderOptions; +use inkwell::targets::{ + CodeModel, FileType, InitializationConfig, RelocMode, Target, TargetMachine, TargetTriple, +}; +use inkwell::OptimizationLevel; + +/// One-time process-global LLVM setup: target registration and `-mllvm` +/// pass-through flags. Both are process-global in LLVM itself, which is why +/// they are applied under a `Once` and not per compile. The `-mllvm` value is +/// captured from the first compile that carries one; Perry only ever passes a +/// single, env-derived `-inlinehint-threshold` value per process, so +/// first-wins is not a narrowing. (A future per-function-opt backend must +/// replace the cl::opt mechanism entirely — noted in the experiment doc.) +static LLVM_GLOBAL_INIT: Once = Once::new(); +static ANNOUNCE: Once = Once::new(); + +fn global_init(mllvm: &[String]) { + LLVM_GLOBAL_INIT.call_once(|| { + Target::initialize_all(&InitializationConfig::default()); + if !mllvm.is_empty() { + let mut argv: Vec = vec![CString::new("perry-llvm-inprocess").unwrap()]; + for flag in mllvm { + if let Ok(c) = CString::new(flag.as_str()) { + argv.push(c); + } + } + let ptrs: Vec<*const std::os::raw::c_char> = argv.iter().map(|c| c.as_ptr()).collect(); + unsafe { + llvm_sys::support::LLVMParseCommandLineOptions( + ptrs.len() as i32, + ptrs.as_ptr(), + std::ptr::null(), + ); + } + } + }); +} + +/// The liveness witness ("never trust a green that cannot fail"): an A/B arm +/// claiming to be in-process must show this line on stderr. +fn announce() { + ANNOUNCE.call_once(|| { + let (mut major, mut minor, mut patch) = (0u32, 0u32, 0u32); + unsafe { llvm_sys::core::LLVMGetVersion(&mut major, &mut minor, &mut patch) }; + eprintln!("perry: in-process LLVM backend active (LLVM {major}.{minor}.{patch})"); + }); +} + +/// Compile IR text to object bytes in-process, honoring the clang-style argv +/// from `build_clang_compile_plan`. `module_name` becomes the module +/// identifier (the deterministic content-addressed basename, mirroring #7131's +/// contract that only the IR bytes decide what lands in the object). +pub fn compile_ll_to_object_inprocess( + ll_text: &str, + effective_target: &str, + clang_style_args: &[String], + module_name: &str, +) -> Result> { + let (opt, mcpu_native, explicit_cpu, mllvm) = interpret_plan_args(clang_style_args)?; + let context = Context::create(); + let module = parse_ir_text(&context, ll_text, module_name)?; + optimize_and_emit( + &module, + effective_target, + opt, + mcpu_native, + explicit_cpu.as_deref(), + &mllvm, + ) +} + +/// Interpret the plan argv. Unknown dash-flags are an error on purpose: +/// silently ignoring a flag clang would have honored is how the two +/// backends drift apart without anyone noticing. +#[allow(clippy::type_complexity)] +fn interpret_plan_args( + clang_style_args: &[String], +) -> Result<(char, bool, Option, Vec)> { + let mut opt = '0'; + let mut mcpu_native = false; + let mut explicit_cpu: Option = None; + let mut mllvm: Vec = Vec::new(); + let mut it = clang_style_args.iter().peekable(); + while let Some(a) = it.next() { + match a.as_str() { + // `-g` is a measured no-op on Perry IR (no DI metadata; see the + // TEMP_NONCE_COUNTER doc block in linker.rs), matching clang. + "-c" | "-fno-math-errno" | "-g" => {} + "-o" | "-target" => { + it.next(); + } + "-mllvm" => { + if let Some(f) = it.next() { + mllvm.push(f.clone()); + } + } + "-mcpu=native" | "-march=native" => mcpu_native = true, + s if s.starts_with("-mcpu=") => explicit_cpu = Some(s["-mcpu=".len()..].to_string()), + s if s.starts_with("-march=") => explicit_cpu = Some(s["-march=".len()..].to_string()), + s if s.starts_with("-O") => opt = s.chars().nth(2).unwrap_or('0'), + s if !s.starts_with('-') => {} // input/output paths from the plan + other => { + return Err(anyhow!( + "in-process backend does not understand clang arg `{other}`; \ + refusing to silently drop it" + )) + } + } + } + Ok((opt, mcpu_native, explicit_cpu, mllvm)) +} + +/// Parse IR text into a module in `context`. Shared by the transport path +/// (whole-module text) and the native-construction path (the few-KB module +/// skeleton from `LlModule::skeleton_ir`). +pub(crate) fn parse_ir_text<'ctx>( + context: &'ctx Context, + ll_text: &str, + module_name: &str, +) -> Result> { + // inkwell 0.9's copy constructor requires (and then strips) a trailing + // NUL. One extra copy of the IR text; fine for the transport phase. + let mut ir = Vec::with_capacity(ll_text.len() + 1); + ir.extend_from_slice(ll_text.as_bytes()); + ir.push(0); + let buf = MemoryBuffer::create_from_memory_range_copy(&ir, module_name); + context + .create_module_from_ir(buf) + .map_err(|e| anyhow!("LLVM IR parse error:\n{}", e.to_string())) +} + +/// Interpret plan argv (same grammar as `compile_ll_to_object_inprocess`) and +/// run verify -> pass pipeline -> object emission on an already-built module. +/// The native construction path calls this directly. +pub(crate) fn optimize_and_emit_module( + module: &inkwell::module::Module<'_>, + effective_target: &str, + clang_style_args: &[String], +) -> Result> { + let (opt, mcpu_native, explicit_cpu, mllvm) = interpret_plan_args(clang_style_args)?; + optimize_and_emit( + module, + effective_target, + opt, + mcpu_native, + explicit_cpu.as_deref(), + &mllvm, + ) +} + +fn optimize_and_emit( + module: &inkwell::module::Module<'_>, + effective_target: &str, + opt: char, + mcpu_native: bool, + explicit_cpu: Option<&str>, + mllvm: &[String], +) -> Result> { + global_init(mllvm); + announce(); + + module + .verify() + .map_err(|e| anyhow!("LLVM verifier rejected module:\n{}", e.to_string()))?; + + let triple = TargetTriple::create(effective_target); + let target = Target::from_triple(&triple) + .map_err(|e| anyhow!("no LLVM target for `{effective_target}`: {e}"))?; + let (cpu, features) = if mcpu_native { + ( + TargetMachine::get_host_cpu_name() + .to_string_lossy() + .into_owned(), + TargetMachine::get_host_cpu_features() + .to_string_lossy() + .into_owned(), + ) + } else if let Some(cpu) = explicit_cpu { + (cpu.to_string(), String::new()) + } else { + (String::new(), String::new()) + }; + let opt_level = match opt { + '0' => OptimizationLevel::None, + '1' => OptimizationLevel::Less, + '2' | 's' | 'z' => OptimizationLevel::Default, + _ => OptimizationLevel::Aggressive, + }; + let tm = target + .create_target_machine( + &triple, + &cpu, + &features, + opt_level, + RelocMode::PIC, + CodeModel::Default, + ) + .ok_or_else(|| anyhow!("failed to create TargetMachine for `{effective_target}`"))?; + + // Same trust order as the subprocess path: `-target` wins over whatever + // triple the module text states, and the module optimizes under the + // machine's real datalayout. + module.set_triple(&triple); + module.set_data_layout(&tm.get_target_data().get_data_layout()); + + let pipeline = match opt { + '0' => "default", + '1' => "default", + '2' => "default", + 's' => "default", + 'z' => "default", + _ => "default", + }; + module + .run_passes(pipeline, &tm, PassBuilderOptions::create()) + .map_err(|e| anyhow!("pass pipeline `{pipeline}` failed:\n{}", e.to_string()))?; + + let obj = tm + .write_to_memory_buffer(&module, FileType::Object) + .map_err(|e| anyhow!("object emission failed:\n{}", e.to_string()))?; + Ok(obj.as_slice().to_vec()) +} + +#[cfg(test)] +mod tests { + use super::*; + + /// Layer-2 readiness (#7174, engine-plan layer 0 -> 2): the in-process + /// pipeline can schedule `RewriteStatepointsForGC` at the pinned LLVM — + /// no `opt` subprocess, no version-skewed toolchain. This is the exact + /// mechanism #7108 measured as viable-but-blocked under text-plus-clang. + /// A statepoint lands at the may-GC call and the live GC pointer is + /// relocated across it — the property that makes the register-held- + /// pointer bug class unrepresentable. + #[test] + fn rs4gc_schedules_in_process() { + let context = Context::create(); + let ir = r#" +declare ptr addrspace(1) @alloc() + +define ptr addrspace(1) @f(ptr addrspace(1) %p) gc "statepoint-example" { +entry: + %q = call ptr addrspace(1) @alloc() + ret ptr addrspace(1) %p +} +"#; + let module = parse_ir_text(&context, ir, "rs4gc_probe").expect("probe parses"); + global_init(&[]); + let triple = TargetMachine::get_default_triple(); + let target = Target::from_triple(&triple).expect("host target"); + let tm = target + .create_target_machine( + &triple, + "", + "", + OptimizationLevel::None, + RelocMode::PIC, + CodeModel::Default, + ) + .expect("target machine"); + module + .run_passes( + "rewrite-statepoints-for-gc", + &tm, + PassBuilderOptions::create(), + ) + .expect("RS4GC pipeline runs in-process"); + let printed = module.print_to_string().to_string(); + assert!( + printed.contains("gc.statepoint"), + "no statepoint emitted:\n{printed}" + ); + assert!( + printed.contains("gc.relocate"), + "live GC pointer not relocated across the call:\n{printed}" + ); + module.verify().expect("statepoint IR verifies"); + } +} diff --git a/crates/perry-codegen/src/inst.rs b/crates/perry-codegen/src/inst.rs new file mode 100644 index 0000000000..1ada483767 --- /dev/null +++ b/crates/perry-codegen/src/inst.rs @@ -0,0 +1,366 @@ +//! Typed instruction storage for `LlBlock` (exp/llvm-inprocess, Phase 2b). +//! +//! Every variant renders byte-identically to the `format!` string the +//! corresponding `block.rs` semantic method used to emit — the migration +//! gate is the full unit suite (which pins exact rendered IR) plus +//! `PERRY_LLVM_INPROCESS=diff`'s object-byte verdict. `Raw` remains the +//! carrier for the `emit_raw` escape hatch (89 call sites of bespoke +//! shapes); typed variants are constructed natively by `dialect.rs` without +//! any per-line text, and the per-module raw-vs-typed counts are the +//! migration ratchet. +//! +//! Operands stay in the emitter's existing currency — register-name / +//! literal token strings — so lowering code is untouched by the migration; +//! what disappears is the line formatting and the line re-parsing. + +use crate::types::LlvmType; + +pub enum LoadFlavor { + Plain, + Aligned(u32), + Volatile, + AtomicSeqCst(u32), + /// `!invariant.load !0` tagged (issue #52). + Invariant, +} + +pub enum LlInst { + /// Pre-rendered instruction line, two-space indent included. + Raw(String), + /// Binary op: `dst =
 a, b`. `pre` is the fast-math
+    /// prefix for fp ops (`"reassoc contract "` etc., trailing space
+    /// included) and `""` for integer/bit ops.
+    Bin {
+        dst: String,
+        op: &'static str,
+        pre: &'static str,
+        ty: LlvmType,
+        a: String,
+        b: String,
+    },
+    FNeg {
+        dst: String,
+        pre: &'static str,
+        a: String,
+    },
+    FCmp {
+        dst: String,
+        pred: String,
+        a: String,
+        b: String,
+    },
+    ICmp {
+        dst: String,
+        pred: &'static str,
+        ty: LlvmType,
+        a: String,
+        b: String,
+    },
+    Alloca {
+        dst: String,
+        ty: LlvmType,
+    },
+    Load {
+        dst: String,
+        ty: LlvmType,
+        ptr: String,
+        flavor: LoadFlavor,
+    },
+    Store {
+        ty: LlvmType,
+        val: String,
+        ptr: String,
+        volatile: bool,
+        align: Option,
+    },
+    /// All `X to Y` conversions: bitcast, trunc/zext/sext, fp<->int, ptr<->int.
+    Cast {
+        dst: String,
+        op: &'static str,
+        from: LlvmType,
+        v: String,
+        to: LlvmType,
+    },
+    Select {
+        dst: String,
+        cond_ty: LlvmType,
+        cond: String,
+        ty: LlvmType,
+        a: String,
+        b: String,
+    },
+    /// Direct call `@callee` (name WITHOUT the `@`). `dst: None` renders the
+    /// value-less form (`call void ...` and friends).
+    Call {
+        dst: Option,
+        ret: LlvmType,
+        callee: String,
+        args: Vec<(LlvmType, String)>,
+    },
+    /// Pre-opaque-pointer indirect call, rendered `(T1, T2)*` exactly as the
+    /// text emitter always has.
+    CallIndirect {
+        dst: String,
+        ret: LlvmType,
+        fptr: String,
+        args: Vec<(LlvmType, String)>,
+    },
+    /// `call void asm sideeffect "", ""()` — the loop-preservation barrier.
+    AsmBarrier,
+    Br {
+        label: String,
+    },
+    CondBr {
+        cond: String,
+        t: String,
+        f: String,
+    },
+    Ret {
+        ty: LlvmType,
+        val: String,
+    },
+    RetVoid,
+    Unreachable,
+    Gep {
+        dst: String,
+        inbounds: bool,
+        ty: LlvmType,
+        ptr: String,
+        idxs: Vec<(LlvmType, String)>,
+    },
+    Phi {
+        dst: String,
+        ty: LlvmType,
+        /// (value, block-label-without-%) pairs.
+        pairs: Vec<(String, String)>,
+    },
+}
+
+impl LlInst {
+    /// Append the rendered line (no trailing newline) to `out`. Must stay
+    /// byte-identical to the `format!` the emitting method used — the unit
+    /// suite pins this.
+    pub fn render_into(&self, out: &mut String) {
+        use std::fmt::Write;
+        match self {
+            LlInst::Raw(s) => out.push_str(s),
+            LlInst::Bin {
+                dst,
+                op,
+                pre,
+                ty,
+                a,
+                b,
+            } => {
+                let _ = write!(out, "  {dst} = {op} {pre}{ty} {a}, {b}");
+            }
+            LlInst::FNeg { dst, pre, a } => {
+                let _ = write!(out, "  {dst} = fneg {pre}double {a}");
+            }
+            LlInst::FCmp { dst, pred, a, b } => {
+                let _ = write!(out, "  {dst} = fcmp {pred} double {a}, {b}");
+            }
+            LlInst::ICmp {
+                dst,
+                pred,
+                ty,
+                a,
+                b,
+            } => {
+                let _ = write!(out, "  {dst} = icmp {pred} {ty} {a}, {b}");
+            }
+            LlInst::Alloca { dst, ty } => {
+                let _ = write!(out, "  {dst} = alloca {ty}");
+            }
+            LlInst::Load {
+                dst,
+                ty,
+                ptr,
+                flavor,
+            } => match flavor {
+                LoadFlavor::Plain => {
+                    let _ = write!(out, "  {dst} = load {ty}, ptr {ptr}");
+                }
+                LoadFlavor::Aligned(n) => {
+                    let _ = write!(out, "  {dst} = load {ty}, ptr {ptr}, align {n}");
+                }
+                LoadFlavor::Volatile => {
+                    let _ = write!(out, "  {dst} = load volatile {ty}, ptr {ptr}");
+                }
+                LoadFlavor::AtomicSeqCst(n) => {
+                    let _ = write!(
+                        out,
+                        "  {dst} = load atomic {ty}, ptr {ptr} seq_cst, align {n}"
+                    );
+                }
+                LoadFlavor::Invariant => {
+                    let _ = write!(out, "  {dst} = load {ty}, ptr {ptr}, !invariant.load !0");
+                }
+            },
+            LlInst::Store {
+                ty,
+                val,
+                ptr,
+                volatile,
+                align,
+            } => {
+                if *volatile {
+                    let _ = write!(out, "  store volatile {ty} {val}, ptr {ptr}");
+                } else {
+                    let _ = write!(out, "  store {ty} {val}, ptr {ptr}");
+                }
+                if let Some(n) = align {
+                    let _ = write!(out, ", align {n}");
+                }
+            }
+            LlInst::Cast {
+                dst,
+                op,
+                from,
+                v,
+                to,
+            } => {
+                let _ = write!(out, "  {dst} = {op} {from} {v} to {to}");
+            }
+            LlInst::Select {
+                dst,
+                cond_ty,
+                cond,
+                ty,
+                a,
+                b,
+            } => {
+                let _ = write!(out, "  {dst} = select {cond_ty} {cond}, {ty} {a}, {ty} {b}");
+            }
+            LlInst::Call {
+                dst,
+                ret,
+                callee,
+                args,
+            } => {
+                out.push_str("  ");
+                if let Some(d) = dst {
+                    let _ = write!(out, "{d} = ");
+                }
+                let _ = write!(out, "call {ret} @{callee}(");
+                push_args(out, args);
+                out.push(')');
+            }
+            LlInst::CallIndirect {
+                dst,
+                ret,
+                fptr,
+                args,
+            } => {
+                let _ = write!(out, "  {dst} = call {ret} (");
+                for (i, (t, _)) in args.iter().enumerate() {
+                    if i > 0 {
+                        out.push_str(", ");
+                    }
+                    out.push_str(t);
+                }
+                let _ = write!(out, ")* {fptr}(");
+                push_args(out, args);
+                out.push(')');
+            }
+            LlInst::AsmBarrier => {
+                out.push_str("  call void asm sideeffect \"\", \"\"()");
+            }
+            LlInst::Br { label } => {
+                let _ = write!(out, "  br label %{label}");
+            }
+            LlInst::CondBr { cond, t, f } => {
+                let _ = write!(out, "  br i1 {cond}, label %{t}, label %{f}");
+            }
+            LlInst::Ret { ty, val } => {
+                let _ = write!(out, "  ret {ty} {val}");
+            }
+            LlInst::RetVoid => out.push_str("  ret void"),
+            LlInst::Unreachable => out.push_str("  unreachable"),
+            LlInst::Gep {
+                dst,
+                inbounds,
+                ty,
+                ptr,
+                idxs,
+            } => {
+                let kw = if *inbounds {
+                    "getelementptr inbounds"
+                } else {
+                    "getelementptr"
+                };
+                let _ = write!(out, "  {dst} = {kw} {ty}, ptr {ptr}, ");
+                push_args(out, idxs);
+            }
+            LlInst::Phi { dst, ty, pairs } => {
+                let _ = write!(out, "  {dst} = phi {ty} ");
+                for (i, (v, l)) in pairs.iter().enumerate() {
+                    if i > 0 {
+                        out.push_str(", ");
+                    }
+                    let _ = write!(out, "[ {v}, %{l} ]");
+                }
+            }
+        }
+    }
+
+    /// Rendered byte length, excluding the trailing newline. Exact — the
+    /// codegen-unit balancer (#5391) partitions on these sums, and an
+    /// estimate that drifted would change the DEFAULT path's unit split.
+    pub fn text_len(&self) -> usize {
+        match self {
+            LlInst::Raw(s) => s.len(),
+            _ => {
+                thread_local! {
+                    static SCRATCH: std::cell::RefCell =
+                        std::cell::RefCell::new(String::with_capacity(128));
+                }
+                SCRATCH.with(|s| {
+                    let mut s = s.borrow_mut();
+                    s.clear();
+                    self.render_into(&mut s);
+                    s.len()
+                })
+            }
+        }
+    }
+
+    /// The rendered line for text-scanning consumers that only make sense
+    /// on raw lines. Typed variants answer predicates structurally
+    /// (see `LlBlock::contains_gc_unsafe_call`).
+    pub fn scan_str(&self) -> &str {
+        match self {
+            LlInst::Raw(s) => s,
+            _ => "",
+        }
+    }
+
+    /// True if this is a call into the perry runtime (anything that could
+    /// allocate / trigger GC): not an `@llvm.*` intrinsic, not the inline-asm
+    /// barrier. Mirrors the historical string scan in
+    /// `contains_gc_unsafe_call` exactly.
+    pub fn is_gc_unsafe_call(&self) -> bool {
+        match self {
+            LlInst::Raw(s) => {
+                let Some(pos) = s.find("call ") else {
+                    return false;
+                };
+                let callee = &s[pos..];
+                !callee.contains("@llvm.") && !callee.contains(" asm ")
+            }
+            LlInst::Call { callee, .. } => !callee.starts_with("llvm."),
+            LlInst::CallIndirect { .. } => true,
+            _ => false,
+        }
+    }
+}
+
+fn push_args(out: &mut String, args: &[(LlvmType, String)]) {
+    use std::fmt::Write;
+    for (i, (t, v)) in args.iter().enumerate() {
+        if i > 0 {
+            out.push_str(", ");
+        }
+        let _ = write!(out, "{t} {v}");
+    }
+}
diff --git a/crates/perry-codegen/src/lib.rs b/crates/perry-codegen/src/lib.rs
index 6d87dde4fe..7b1d52972f 100644
--- a/crates/perry-codegen/src/lib.rs
+++ b/crates/perry-codegen/src/lib.rs
@@ -8,9 +8,14 @@ pub mod block;
 pub(crate) mod boxed_vars;
 pub mod codegen;
 pub(crate) mod collectors;
+#[cfg(feature = "llvm-inprocess")]
+pub(crate) mod dialect;
 pub mod expr;
 pub mod ext_registry;
 pub mod function;
+#[cfg(feature = "llvm-inprocess")]
+pub mod inprocess;
+pub mod inst;
 pub mod linker;
 pub(crate) mod loop_purity;
 pub(crate) mod lower_array_method;
@@ -19,6 +24,8 @@ pub(crate) mod lower_conditional;
 pub(crate) mod lower_string_method;
 pub mod module;
 pub mod nanbox;
+#[cfg(feature = "llvm-inprocess")]
+pub mod native_emit;
 pub(crate) mod native_value;
 pub(crate) mod nm_install;
 pub mod opt_report;
diff --git a/crates/perry-codegen/src/linker.rs b/crates/perry-codegen/src/linker.rs
index ef12529cc2..a0429d2821 100644
--- a/crates/perry-codegen/src/linker.rs
+++ b/crates/perry-codegen/src/linker.rs
@@ -482,12 +482,134 @@ pub fn compile_ll_to_object(ll_text: &str, target_triple: Option<&str>) -> Resul
 /// * **`PERRY_DEBUG_SYMBOLS`**: no effect on any of the above. It was believed
 ///   to put the `.ll`'s absolute path into DWARF; measured, it does not put
 ///   anything there at all. See `TEMP_NONCE_COUNTER`.
+/// exp/llvm-inprocess Phase 2: plan argv for a natively-constructed module,
+/// produced by the SAME decision code as the clang path so opt levels
+/// (incl. the #4880 oversized fallback) and CPU tuning cannot drift. The
+/// byte-size input is the render-free estimate (`estimated_ir_bytes`), since
+/// a native module never renders; the paths in the argv are placeholders the
+/// in-process interpreter skips.
+#[cfg(feature = "llvm-inprocess")]
+pub(crate) fn native_plan_args(
+    target_triple: Option<&str>,
+    est_ll_bytes: usize,
+    ll_fn_count: usize,
+) -> (String, Vec) {
+    let plan = build_clang_compile_plan(
+        PathBuf::from("(in-process)"),
+        PathBuf::from("(native-module)"),
+        PathBuf::from("(native-object)"),
+        target_triple,
+        est_ll_bytes,
+        ll_fn_count,
+        env::var_os("PERRY_DEBUG_SYMBOLS").is_some(),
+    );
+    (plan.effective_target, plan.clang_args)
+}
+
+/// exp/llvm-inprocess: truthy `PERRY_LLVM_INPROCESS` routes `.ll -> .o`
+/// through the LLVM C API inside this process (no clang subprocess, no `.ll`
+/// on disk). The flag participates in both the build cache and the object
+/// cache keys, so the two backends can never share a cached object.
+fn inprocess_requested() -> bool {
+    match env::var("PERRY_LLVM_INPROCESS").as_deref() {
+        Ok("") | Ok("0") | Ok("off") | Ok("false") | Err(_) => false,
+        Ok(_) => true,
+    }
+}
+
+#[cfg(feature = "llvm-inprocess")]
+fn compile_ll_inprocess_in(
+    tmp_dir: &Path,
+    ll_text: &str,
+    target_triple: Option<&str>,
+    policy: TempFilePolicy,
+) -> Result> {
+    let (paths, _pid, _nonce) = llvm_temp_paths(tmp_dir, ll_text);
+    // Same decision inputs as the clang path — opt level (#4880 fallback
+    // included), CPU tuning, inlinehint threshold — via the same plan
+    // constructor, so the backends cannot drift on a decision independently.
+    let plan = build_clang_compile_plan(
+        PathBuf::from("(in-process)"),
+        paths.ll_path.clone(),
+        paths.obj_path.clone(),
+        target_triple,
+        ll_text.len(),
+        count_ll_functions(ll_text),
+        policy.debug_symbols,
+    );
+    // #7131 parity: the module identifier is the content-addressed basename,
+    // the only name that can reach the object bytes.
+    let module_name = paths
+        .ll_path
+        .file_name()
+        .map(|n| n.to_string_lossy().into_owned())
+        .unwrap_or_else(|| "perry_module.ll".to_string());
+    if policy.keep {
+        fs::create_dir_all(&paths.scratch_dir)
+            .with_context(|| format!("Failed to create {}", paths.scratch_dir.display()))?;
+        fs::write(&paths.ll_path, ll_text)
+            .with_context(|| format!("Failed to write {}", paths.ll_path.display()))?;
+        let metadata_path = PathBuf::from(format!("{}.compile-plan.json", plan.obj_path.display()));
+        write_compile_plan_metadata(&plan, &metadata_path)?;
+        eprintln!("[perry-codegen] kept LLVM IR: {}", paths.ll_path.display());
+        eprintln!(
+            "[perry-codegen] kept compile metadata: {}",
+            metadata_path.display()
+        );
+    }
+    match crate::inprocess::compile_ll_to_object_inprocess(
+        ll_text,
+        &plan.effective_target,
+        &plan.clang_args,
+        &module_name,
+    ) {
+        Ok(bytes) => Ok(bytes),
+        Err(e) => {
+            // Same contract as a failed clang compile: the IR that produced
+            // the failure is left on disk and named in the error.
+            let _ = fs::create_dir_all(&paths.scratch_dir);
+            let _ = fs::write(&paths.ll_path, ll_text);
+            Err(anyhow!(
+                "in-process LLVM compile failed (PERRY_LLVM_INPROCESS).\n\
+                 requested -target: {}\n\
+                 LLVM IR left at: {}\n\
+                 \n\
+                 {}",
+                plan.effective_target,
+                paths.ll_path.display(),
+                e
+            ))
+        }
+    }
+}
+
+#[cfg(not(feature = "llvm-inprocess"))]
+fn compile_ll_inprocess_in(
+    _tmp_dir: &Path,
+    _ll_text: &str,
+    _target_triple: Option<&str>,
+    _policy: TempFilePolicy,
+) -> Result> {
+    // Fail loudly rather than silently falling back: an A/B arm that asked
+    // for the in-process backend must never be served the text path.
+    bail!(
+        "PERRY_LLVM_INPROCESS is set, but this perry was built without the \
+         `llvm-inprocess` cargo feature. Rebuild with \
+         `cargo build -p perry --features llvm-inprocess` (needs LLVM 22: \
+         `brew install llvm`, and LLVM_SYS_221_PREFIX if llvm-config is not \
+         on PATH), or unset PERRY_LLVM_INPROCESS."
+    )
+}
+
 fn compile_ll_to_object_in(
     tmp_dir: &Path,
     ll_text: &str,
     target_triple: Option<&str>,
     policy: TempFilePolicy,
 ) -> Result> {
+    if inprocess_requested() {
+        return compile_ll_inprocess_in(tmp_dir, ll_text, target_triple, policy);
+    }
     // Validate the toolchain before creating the potentially large `.ll`
     // scratch file. Unsupported clang releases should fail without leaving
     // an artifact that was never passed to the compiler.
@@ -658,16 +780,27 @@ pub fn compile_units_to_object(units: &[String], target_triple: Option<&str>) ->
         _ => {}
     }
 
+    let mut objs: Vec> = Vec::with_capacity(units.len());
+    for (i, unit) in units.iter().enumerate() {
+        objs.push(compile_ll_to_object(unit, target_triple).with_context(|| {
+            format!("codegen unit {}/{} failed to compile", i + 1, units.len())
+        })?);
+    }
+    merge_unit_objects(&objs)
+}
+
+/// Partial-link (`ld -r`) already-compiled codegen-unit objects into one
+/// object. Shared by the text path above and the native construction path
+/// (`native_emit::compile_module_units_native`).
+pub(crate) fn merge_unit_objects(objs: &[Vec]) -> Result> {
     let tmp_dir = env::temp_dir();
     let pid = std::process::id();
     let nonce = TEMP_NONCE_COUNTER.fetch_add(1, Ordering::Relaxed);
 
-    let mut obj_paths: Vec = Vec::with_capacity(units.len());
-    for (i, unit) in units.iter().enumerate() {
-        let bytes = compile_ll_to_object(unit, target_triple)
-            .with_context(|| format!("codegen unit {}/{} failed to compile", i + 1, units.len()))?;
+    let mut obj_paths: Vec = Vec::with_capacity(objs.len());
+    for (i, bytes) in objs.iter().enumerate() {
         let p = tmp_dir.join(format!("perry_cgu_{}_{}_{}.o", pid, nonce, i));
-        fs::write(&p, &bytes)
+        fs::write(&p, bytes)
             .with_context(|| format!("failed to write codegen-unit object {}", p.display()))?;
         obj_paths.push(p);
     }
@@ -689,7 +822,7 @@ pub fn compile_units_to_object(units: &[String], target_triple: Option<&str>) ->
         Err(anyhow!(
             "partial link `{} -r` of {} codegen units failed (status={}).\nstderr:\n{}",
             ld,
-            units.len(),
+            objs.len(),
             out.status,
             String::from_utf8_lossy(&out.stderr)
         ))
diff --git a/crates/perry-codegen/src/module.rs b/crates/perry-codegen/src/module.rs
index 297d1642f7..3ee9c164bf 100644
--- a/crates/perry-codegen/src/module.rs
+++ b/crates/perry-codegen/src/module.rs
@@ -159,7 +159,7 @@ fn helper_decl_attrs(name: &str) -> &'static str {
 /// Synthesize an external `declare` line matching a locally-defined function's
 /// signature, so a codegen unit that calls it (but does not define it) resolves
 /// the call at link time.
-fn declare_line_for(f: &LlFunction) -> String {
+pub(crate) fn declare_line_for(f: &LlFunction) -> String {
     let params = f
         .params
         .iter()
@@ -435,7 +435,7 @@ impl LlModule {
     /// dispatch ambiguity limited to genuinely name-colliding members — proper
     /// disambiguation by class id is a separate concern). Shared by [`to_ir`]
     /// and [`render_codegen_units`] so both paths agree on the symbol set.
-    fn deduped_function_refs(&self) -> Vec<&LlFunction> {
+    pub(crate) fn deduped_function_refs(&self) -> Vec<&LlFunction> {
         let mut seen: HashSet<&str> = HashSet::with_capacity(self.functions.len());
         self.functions
             .iter()
@@ -443,6 +443,49 @@ impl LlModule {
             .collect()
     }
 
+    /// The module *skeleton*: everything [`to_ir`] emits EXCEPT function
+    /// definitions — header, string constants, globals, declarations (still
+    /// filtered against defined names, which the native path adds via the C
+    /// API), attribute groups and metadata.
+    ///
+    /// This is the only text the native construction path
+    /// (`PERRY_LLVM_INPROCESS=native`) still parses: a few KB of module
+    /// scaffolding, while every function body is built in memory. It must
+    /// stay in lockstep with [`to_ir`] — both are thin loops over the same
+    /// fields, and `native_emit`'s differential mode diffs the two paths'
+    /// printed modules to catch drift.
+    #[cfg(feature = "llvm-inprocess")]
+    pub(crate) fn skeleton_ir(&self) -> String {
+        let mut ir = String::new();
+        ir.push_str("; Generated by perry-codegen\n");
+        ir.push_str(&format!("target triple = \"{}\"\n\n", self.target_triple));
+        for sc in &self.string_constants {
+            ir.push_str(sc);
+            ir.push('\n');
+        }
+        ir.push('\n');
+        for g in &self.globals {
+            ir.push_str(g);
+            ir.push('\n');
+        }
+        ir.push('\n');
+        let defined: HashSet<&str> = self
+            .deduped_function_refs()
+            .iter()
+            .map(|f| f.name.as_str())
+            .collect();
+        for (name, decl) in &self.declarations {
+            if defined.contains(name.as_str()) {
+                continue;
+            }
+            ir.push_str(decl);
+            ir.push('\n');
+        }
+        ir.push('\n');
+        self.push_attrs_and_metadata(&mut ir);
+        ir
+    }
+
     /// Serialize the module to a complete `.ll` file.
     pub fn to_ir(&self) -> String {
         let mut ir = String::new();
@@ -569,13 +612,18 @@ impl LlModule {
     ///     `internal` init/wrapper is promoted so cross-unit calls bind);
     ///   * the shared attribute groups + metadata (so `#N`/`!N` refs resolve).
     ///
-    /// `n <= 1` (or a single-function module) returns one text identical to
-    /// [`to_ir`]. The caller compiles each text to an object and combines them
-    /// (`ld -r`) into one object, keeping `compile_module`'s single-object API.
-    pub fn render_codegen_units(&self, n: usize) -> Vec {
+    /// `n <= 1` (or a single-function module) returns a single part whose
+    /// `funcs` are all functions (callers use the whole-module path). The
+    /// text caller compiles each rendered part and combines them (`ld -r`)
+    /// into one object, keeping `compile_module`'s single-object API.
+    pub(crate) fn codegen_unit_parts(&self, n: usize) -> Vec> {
         let funcs = self.deduped_function_refs();
         if n <= 1 || funcs.len() <= 1 {
-            return vec![self.to_ir()];
+            return vec![CodegenUnitPart {
+                pre: String::new(),
+                post: String::new(),
+                funcs,
+            }];
         }
         let n = n.min(funcs.len());
 
@@ -628,46 +676,79 @@ impl LlModule {
                 .or_insert_with(|| declare_line_for(f));
         }
 
-        let mut units = Vec::with_capacity(n);
-        for bucket in &buckets {
+        let mut post = String::new();
+        self.push_attrs_and_metadata(&mut post);
+
+        let mut parts = Vec::with_capacity(n);
+        for bucket in buckets {
             let defined: HashSet<&str> = bucket.iter().map(|f| f.name.as_str()).collect();
-            let mut ir = String::new();
-            ir.push_str("; Generated by perry-codegen (codegen unit)\n");
-            ir.push_str(&format!("target triple = \"{}\"\n\n", self.target_triple));
+            let mut pre = String::new();
+            pre.push_str("; Generated by perry-codegen (codegen unit)\n");
+            pre.push_str(&format!("target triple = \"{}\"\n\n", self.target_triple));
 
             for sc in &shared_strings {
-                ir.push_str(sc);
-                ir.push('\n');
+                pre.push_str(sc);
+                pre.push('\n');
             }
-            ir.push('\n');
+            pre.push('\n');
             for g in &shared_globals {
-                ir.push_str(g);
-                ir.push('\n');
+                pre.push_str(g);
+                pre.push('\n');
             }
-            ir.push('\n');
+            pre.push('\n');
 
             // Declares for everything this unit references but does not define.
             for (name, decl) in &decl_by_name {
                 if defined.contains(name) {
                     continue;
                 }
-                ir.push_str(decl);
-                ir.push('\n');
+                pre.push_str(decl);
+                pre.push('\n');
             }
-            ir.push('\n');
+            pre.push('\n');
 
-            for func in bucket {
-                ir.push_str(&render_fn_external(func));
-                ir.push('\n');
-            }
+            parts.push(CodegenUnitPart {
+                pre,
+                post: post.clone(),
+                funcs: bucket,
+            });
+        }
+        parts
+    }
 
-            self.push_attrs_and_metadata(&mut ir);
-            units.push(ir);
+    /// Render this module as `n` independent codegen-unit `.ll` texts (#5391).
+    /// Thin text renderer over [`codegen_unit_parts`]; the native construction
+    /// path consumes the parts directly.
+    pub fn render_codegen_units(&self, n: usize) -> Vec {
+        let parts = self.codegen_unit_parts(n);
+        if parts.len() == 1 {
+            return vec![self.to_ir()];
         }
-        units
+        parts
+            .into_iter()
+            .map(|part| {
+                let mut ir = part.pre;
+                for func in &part.funcs {
+                    ir.push_str(&render_fn_external(func));
+                    ir.push('\n');
+                }
+                ir.push_str(&part.post);
+                ir
+            })
+            .collect()
     }
 }
 
+/// One codegen unit, pre-render: the textual skeleton around the functions
+/// (`pre` = header/strings/globals/cross-unit declares; `post` = shared
+/// attribute groups + metadata) plus the functions themselves, un-rendered so
+/// the native backend can construct them directly.
+pub(crate) struct CodegenUnitPart<'m> {
+    pub pre: String,
+    pub post: String,
+    pub funcs: Vec<&'m LlFunction>,
+}
+
 #[cfg(test)]
 mod tests {
     use super::*;
diff --git a/crates/perry-codegen/src/native_emit.rs b/crates/perry-codegen/src/native_emit.rs
new file mode 100644
index 0000000000..2dd7e77f52
--- /dev/null
+++ b/crates/perry-codegen/src/native_emit.rs
@@ -0,0 +1,374 @@
+//! Phase 2 of exp/llvm-inprocess: **native module construction** — function
+//! bodies are built in memory through the LLVM C API instead of being
+//! concatenated into module-scale IR text and re-parsed.
+//!
+//! Mode selection reuses the `PERRY_LLVM_INPROCESS` env var (already part of
+//! both cache keys):
+//!
+//! * `1`/`on`/`true` — transport mode: whole-module text parsed in-process
+//!   (`inprocess.rs`).
+//! * `native` — this module: only the module *skeleton* (globals, declares,
+//!   attribute groups, metadata — a few KB) is textual; every function body
+//!   is constructed natively from the finalized per-function line stream.
+//! * `diff` — the migration harness: builds the module BOTH ways in the same
+//!   LLVM, prints both, diffs the normalized prints per function, and returns
+//!   the text-parsed arm's object. Any non-cosmetic difference is a
+//!   construction bug — report it, never normalize it away silently.
+//!
+//! Codegen-unit splitting is ported (`compile_module_units_native`): each
+//! unit is its own context+module, functions stream with external linkage
+//! forced, and unit objects partial-link exactly like the text path. The
+//! only remaining text fallthrough is `emit_ir_only` (bitcode-link mode),
+//! which by definition WANTS the whole-module text.
+//!
+//! Construction consumes `LlFunction::for_each_final_line` — the finalized
+//! per-line stream including entry-alloca hoists, boundary splices and
+//! return-site rewrites, shared with `to_ir` so those transforms have
+//! exactly one implementation. No per-function text is materialized on this
+//! path; the exception is `has_try` functions, whose setjmp volatile pass
+//! needs whole-function analysis and therefore still renders text. What
+//! stops existing everywhere is the module-scale concatenation and the
+//! full-grammar LLVM parse. The follow-up (typed `LlInst` variants) removes
+//! the remaining per-LINE formatting; the `instructions=` counter logged per
+//! module is that migration's ratchet.
+
+use anyhow::{anyhow, Result};
+use inkwell::context::Context;
+use inkwell::module::Module;
+
+use crate::module::LlModule;
+
+#[derive(Debug, Clone, Copy, PartialEq, Eq)]
+pub enum NativeMode {
+    Off,
+    Native,
+    Diff,
+}
+
+pub fn native_mode() -> NativeMode {
+    match std::env::var("PERRY_LLVM_INPROCESS").as_deref() {
+        Ok("native") => NativeMode::Native,
+        Ok("diff") => NativeMode::Diff,
+        _ => NativeMode::Off,
+    }
+}
+
+/// Build the module natively: parse the skeleton text, then construct every
+/// function body through the C API via the dialect reader.
+fn build_native_module<'ctx>(context: &'ctx Context, llmod: &LlModule) -> Result> {
+    let mut skeleton = llmod.skeleton_ir();
+    let funcs = llmod.deduped_function_refs();
+    // Append a declare for every define: the skeleton's globals can
+    // reference defined functions (extern-closure descriptors hold wrapper
+    // function addresses), and calls to functions defined later in the
+    // module are module-scope forward references. Parsing declares with the
+    // define's real signature covers both; `declare_from_header` upgrades
+    // linkage when the body is read.
+    for f in &funcs {
+        let tys = f
+            .params
+            .iter()
+            .map(|(t, _)| t.to_string())
+            .collect::>()
+            .join(", ");
+        skeleton.push_str(&format!("declare {} @{}({})\n", f.return_type, f.name, tys));
+    }
+    let module = crate::inprocess::parse_ir_text(context, &skeleton, "perry_native_module")?;
+    let (typed_insts, raw_insts) = stream_functions(context, &module, &funcs, false)?;
+    log::debug!(
+        "perry-codegen: native construction built {} functions, {} typed + {} raw instructions \
+         (ratchet: raw -> 0), skeleton {} bytes",
+        funcs.len(),
+        typed_insts,
+        raw_insts,
+        skeleton.len()
+    );
+    Ok(module)
+}
+
+/// Stream every function's finalized items into the module. Returns
+/// `(typed, raw)` instruction totals — the migration ratchet.
+fn stream_functions<'ctx>(
+    context: &'ctx Context,
+    module: &Module<'ctx>,
+    funcs: &[&crate::function::LlFunction],
+    force_external: bool,
+) -> Result<(usize, usize)> {
+    let mut typed_insts = 0usize;
+    let mut raw_insts = 0usize;
+    for f in funcs {
+        let header = synth_define_header(f, force_external);
+        let mut stream = crate::dialect::FnStream::begin(context, module, &header)
+            .map_err(|e| anyhow!("native IR construction failed in @{}: {:#}", f.name, e))?;
+        if f.has_try {
+            // The setjmp volatile pass needs whole-function analysis; keep
+            // the materialized-text path for try-containing functions.
+            let fn_text = f.to_ir();
+            for line in fn_text.lines().skip(1) {
+                stream.line(line).map_err(|e| {
+                    anyhow!(
+                        "native IR construction failed in @{}:\n{}\n--- function IR ---\n{}",
+                        f.name,
+                        e,
+                        fn_text
+                    )
+                })?;
+            }
+        } else {
+            // The common case: finalized items stream straight into the
+            // C-API builder — typed instructions carry no text at all.
+            f.for_each_final_item::(&mut |item| stream.item(&item))
+                .map_err(|e| anyhow!("native IR construction failed in @{}: {:#}", f.name, e))?;
+        }
+        let (t, r) = stream
+            .finish()
+            .map_err(|e| anyhow!("native IR construction failed in @{}: {:#}", f.name, e))?;
+        typed_insts += t;
+        raw_insts += r;
+    }
+    Ok((typed_insts, raw_insts))
+}
+
+/// Native construction for a module large enough to split into codegen
+/// units (#5391): each unit is its own context+module (peak RSS stays
+/// ~whole/n, same bound as the per-unit clang model), functions stream with
+/// external linkage forced (mirror of `render_fn_external`), and the unit
+/// objects partial-link exactly like the text path.
+pub fn compile_module_units_native(
+    llmod: &LlModule,
+    n: usize,
+    target: Option<&str>,
+    module_prefix: &str,
+) -> Result> {
+    let parts = llmod.codegen_unit_parts(n);
+    if parts.len() == 1 {
+        return compile_module_native(llmod, target, module_prefix);
+    }
+    let mut objs = Vec::with_capacity(parts.len());
+    for (i, part) in parts.iter().enumerate() {
+        let context = Context::create();
+        let mut skeleton = format!("{}{}", part.pre, part.post);
+        for f in &part.funcs {
+            skeleton.push_str(&crate::module::declare_line_for(f));
+            skeleton.push('\n');
+        }
+        let module = crate::inprocess::parse_ir_text(&context, &skeleton, "perry_native_module")
+            .map_err(|e| anyhow!("unit {i} skeleton: {e:#}"))?;
+        let (t, r) = stream_functions(&context, &module, &part.funcs, true)
+            .map_err(|e| anyhow!("unit {i}: {e:#}"))?;
+        debug_dump(&module, &format!("{module_prefix}.unit{i}"));
+        let est: usize = part
+            .funcs
+            .iter()
+            .map(|f| f.estimated_ir_bytes())
+            .sum::()
+            + skeleton.len();
+        let (effective_target, args) =
+            crate::linker::native_plan_args(target, est, part.funcs.len());
+        objs.push(
+            crate::inprocess::optimize_and_emit_module(&module, &effective_target, &args)
+                .map_err(|e| anyhow!("unit {i}: {e:#}"))?,
+        );
+        log::debug!(
+            "perry-codegen: native unit {i}: {} fns, {t} typed + {r} raw insts",
+            part.funcs.len()
+        );
+    }
+    crate::linker::merge_unit_objects(&objs)
+}
+
+/// Unit-split differential harness: text-rendered units through the
+/// in-process transport vs natively-constructed units, merged objects
+/// byte-compared. Returns the text arm (the trusted reference).
+pub fn compile_module_units_diff(
+    llmod: &LlModule,
+    n: usize,
+    target: Option<&str>,
+    module_prefix: &str,
+) -> Result> {
+    let units = llmod.render_codegen_units(n);
+    let bytes_text = crate::linker::compile_units_to_object(&units, target)?;
+    match compile_module_units_native(llmod, n, target, module_prefix) {
+        Err(e) => {
+            eprintln!("perry: [ir-diff] native unit construction FAILED (text arm used): {e:#}");
+        }
+        Ok(bytes_native) => {
+            if bytes_text == bytes_native {
+                eprintln!(
+                    "perry: [ir-diff] OK — native and text unit arms emit byte-identical merged \
+                     objects ({} bytes, {} units)",
+                    bytes_text.len(),
+                    units.len()
+                );
+            } else {
+                eprintln!(
+                    "perry: [ir-diff] MISMATCH — merged unit objects differ (text {} vs native {})",
+                    bytes_text.len(),
+                    bytes_native.len()
+                );
+            }
+        }
+    }
+    Ok(bytes_text)
+}
+
+/// The plan argv for a natively-built module. Same decision code as the text
+/// path (`build_clang_compile_plan`), with the byte-size input taken from the
+/// render-free size estimate the codegen-unit balancer already uses.
+fn plan_for(llmod: &LlModule, target: Option<&str>) -> (String, Vec) {
+    let est_bytes: usize = llmod
+        .deduped_function_refs()
+        .iter()
+        .map(|f| f.estimated_ir_bytes())
+        .sum();
+    let fn_count = llmod.deduped_function_refs().len();
+    crate::linker::native_plan_args(target, est_bytes, fn_count)
+}
+
+pub fn compile_module_native(
+    llmod: &LlModule,
+    target: Option<&str>,
+    module_prefix: &str,
+) -> Result> {
+    let context = Context::create();
+    let module = build_native_module(&context, llmod)?;
+    debug_dump(&module, module_prefix);
+    let (effective_target, args) = plan_for(llmod, target);
+    crate::inprocess::optimize_and_emit_module(&module, &effective_target, &args)
+}
+
+/// The debug view under native construction: `PERRY_SAVE_LL=` (which
+/// `--trace llvm` sets, #7154) and `PERRY_LLVM_KEEP_IR` both print the
+/// CONSTRUCTED module — exactly what LLVM will verify and optimize,
+/// including construction-time constant folds — rather than re-rendering
+/// the emitter's text. Filenames mirror the text path's so tooling that
+/// greps the trace dir keeps working; the `.native` infix says which
+/// pipeline produced them.
+fn debug_dump(module: &Module<'_>, module_prefix: &str) {
+    let keep = std::env::var_os("PERRY_LLVM_KEEP_IR").is_some();
+    let save_dir = std::env::var("PERRY_SAVE_LL").ok();
+    if !keep && save_dir.is_none() {
+        return;
+    }
+    let printed = module.print_to_string().to_string();
+    if let Some(dir) = save_dir {
+        let path = format!("{}/{}.native.ll", dir, module_prefix);
+        if std::fs::write(&path, &printed).is_ok() {
+            eprintln!("[perry-codegen] saved native-construction IR: {path}");
+        }
+    }
+    if keep {
+        let path = std::env::temp_dir().join(format!(
+            "perry_native_{}_{}.ll",
+            module_prefix,
+            std::process::id()
+        ));
+        if std::fs::write(&path, &printed).is_ok() {
+            eprintln!(
+                "[perry-codegen] kept LLVM IR (native construction): {}",
+                path.display()
+            );
+        }
+    }
+}
+
+/// Differential harness: text-parsed arm vs natively-built arm, same LLVM,
+/// same plan. The verdict is **emitted object bytes** — the C-API builder
+/// constant-folds at construction (`zext i1 false`, `select i1 false, ...`),
+/// so pre-optimization prints legitimately differ in a way that vanishes
+/// under the pass pipeline; byte-compared objects are the ground truth (the
+/// same methodology that proved the Phase 0 transport byte-identical).
+/// Returns the text arm's object (the trusted reference) so a diff run is
+/// safe for real builds while surfacing every divergence.
+pub fn compile_module_diff(
+    llmod: &LlModule,
+    target: Option<&str>,
+    module_prefix: &str,
+) -> Result> {
+    let text = llmod.to_ir();
+    let ctx_text = Context::create();
+    let m_text = crate::inprocess::parse_ir_text(&ctx_text, &text, "perry_native_module")?;
+    let (effective_target, args) = plan_for(llmod, target);
+
+    let ctx_native = Context::create();
+    let native = build_native_module(&ctx_native, llmod);
+    match native {
+        Err(e) => {
+            eprintln!("perry: [ir-diff] native construction FAILED (text arm still used): {e:#}");
+            crate::inprocess::optimize_and_emit_module(&m_text, &effective_target, &args)
+        }
+        Ok(m_native) => {
+            debug_dump(&m_native, module_prefix);
+            // Capture pre-opt prints BEFORE optimization mutates the modules;
+            // they are the localization artifact when bytes mismatch.
+            let dump_dir = std::env::var("PERRY_LLVM_DIFF_DIR").ok();
+            let (pre_text, pre_native) = if dump_dir.is_some() {
+                (
+                    m_text.print_to_string().to_string(),
+                    m_native.print_to_string().to_string(),
+                )
+            } else {
+                (String::new(), String::new())
+            };
+            let bytes_native =
+                crate::inprocess::optimize_and_emit_module(&m_native, &effective_target, &args)?;
+            let bytes_text =
+                crate::inprocess::optimize_and_emit_module(&m_text, &effective_target, &args)?;
+            if bytes_text == bytes_native {
+                eprintln!(
+                    "perry: [ir-diff] OK — native and text arms emit byte-identical objects \
+                     ({} bytes)",
+                    bytes_text.len()
+                );
+            } else {
+                eprintln!(
+                    "perry: [ir-diff] MISMATCH — object bytes differ (text {} vs native {}); \
+                     set PERRY_LLVM_DIFF_DIR to dump both arms' pre-opt IR",
+                    bytes_text.len(),
+                    bytes_native.len()
+                );
+                if let Some(dir) = &dump_dir {
+                    let _ = std::fs::create_dir_all(dir);
+                    let _ = std::fs::write(format!("{dir}/text_arm.ll"), &pre_text);
+                    let _ = std::fs::write(format!("{dir}/native_arm.ll"), &pre_native);
+                    let _ = std::fs::write(format!("{dir}/text_arm.o"), &bytes_text);
+                    let _ = std::fs::write(format!("{dir}/native_arm.o"), &bytes_native);
+                    eprintln!("perry: [ir-diff] arms dumped under {dir}");
+                }
+            }
+            Ok(bytes_text)
+        }
+    }
+}
+
+/// The one-line define header for `f`, matching `LlFunction::to_ir`'s
+/// rendering (linkage, return type, params, inline/try attributes) so the
+/// reader applies identical linkage and function attributes.
+fn synth_define_header(f: &crate::function::LlFunction, force_external: bool) -> String {
+    let params = f
+        .params
+        .iter()
+        .map(|(t, n)| format!("{t} {n}"))
+        .collect::>()
+        .join(", ");
+    // Codegen units promote internal/private definitions so cross-unit
+    // calls bind — mirror of `render_fn_external`.
+    let linkage = if f.linkage.is_empty() || force_external {
+        String::new()
+    } else {
+        format!("{} ", f.linkage)
+    };
+    let attrs = if f.has_try {
+        " #1"
+    } else if f.force_inline {
+        " alwaysinline"
+    } else if f.inline_hint {
+        " inlinehint"
+    } else {
+        ""
+    };
+    format!(
+        "define {}{} @{}({}){} {{",
+        linkage, f.return_type, f.name, params, attrs
+    )
+}
diff --git a/crates/perry/Cargo.toml b/crates/perry/Cargo.toml
index 3775f589b5..161f9457d1 100644
--- a/crates/perry/Cargo.toml
+++ b/crates/perry/Cargo.toml
@@ -140,6 +140,12 @@ audit-cli = []
 updater-cli = ["dep:ed25519-dalek", "dep:rand"]
 native-cli = []
 
+# exp/llvm-inprocess: compile .ll -> .o through the LLVM C API in-process
+# instead of a `clang -c` subprocess. Off by default (no LLVM link dependency);
+# even when built in, it only runs under PERRY_LLVM_INPROCESS=1. Requires
+# LLVM 22 at build time (LLVM_SYS_221_PREFIX or llvm-config on PATH).
+llvm-inprocess = ["perry-codegen/llvm-inprocess"]
+
 # Codegen backends for non-native targets. Each enables one backend crate;
 # `all-codegen-backends` (in full-cli) turns them all on so the default build is
 # unchanged. A slim CLI without a backend rejects its `--target` with a clear
diff --git a/crates/perry/src/commands/compile/build_cache.rs b/crates/perry/src/commands/compile/build_cache.rs
index d31651a752..d40c6e259c 100644
--- a/crates/perry/src/commands/compile/build_cache.rs
+++ b/crates/perry/src/commands/compile/build_cache.rs
@@ -33,6 +33,9 @@ const BUILD_CACHE_ENV_VARS: &[&str] = &[
     "PERRY_DEBUG_INIT",
     "PERRY_DEBUG_SYMBOLS",
     "PERRY_LLVM_CLANG",
+    // exp/llvm-inprocess: selects the in-process LLVM backend for .ll -> .o;
+    // a different backend means different object bytes.
+    "PERRY_LLVM_INPROCESS",
     "PERRY_WRITE_BARRIERS",
     "PERRY_SHADOW_STACK",
     "PERRY_INLINE_SHADOW_SLOT",
diff --git a/crates/perry/src/commands/compile/object_cache.rs b/crates/perry/src/commands/compile/object_cache.rs
index 2194ce4fbb..1c333afd95 100644
--- a/crates/perry/src/commands/compile/object_cache.rs
+++ b/crates/perry/src/commands/compile/object_cache.rs
@@ -786,6 +786,13 @@ fn compute_object_cache_key_with_env(
         "env_llvm_clang",
         env_var("PERRY_LLVM_CLANG").as_deref().unwrap_or(""),
     );
+    // exp/llvm-inprocess: the in-process backend emits with its own pinned
+    // LLVM; sharing objects with the clang subprocess path would make every
+    // A/B between the backends vacuous.
+    h.field(
+        "env_llvm_inprocess",
+        env_var("PERRY_LLVM_INPROCESS").as_deref().unwrap_or(""),
+    );
     h.field(
         "env_write_barriers",
         env_var("PERRY_WRITE_BARRIERS").as_deref().unwrap_or(""),
diff --git a/crates/perry/src/commands/compile/object_cache/object_cache_tests.rs b/crates/perry/src/commands/compile/object_cache/object_cache_tests.rs
index f8320f7af5..d36aa631fa 100644
--- a/crates/perry/src/commands/compile/object_cache/object_cache_tests.rs
+++ b/crates/perry/src/commands/compile/object_cache/object_cache_tests.rs
@@ -581,6 +581,7 @@ fn key_changes_with_codegen_env_vars() {
         "PERRY_DEBUG_INIT",
         "PERRY_DEBUG_SYMBOLS",
         "PERRY_LLVM_CLANG",
+        "PERRY_LLVM_INPROCESS",
         "PERRY_WRITE_BARRIERS",
         "PERRY_SHADOW_STACK",
         "PERRY_DISABLE_BUFFER_FAST_PATH",
diff --git a/docs/llvm-inprocess-experiment.md b/docs/llvm-inprocess-experiment.md
new file mode 100644
index 0000000000..da7da578d1
--- /dev/null
+++ b/docs/llvm-inprocess-experiment.md
@@ -0,0 +1,415 @@
+# In-process LLVM backend experiment (`exp/llvm-inprocess`)
+
+**Status: native construction COMPLETE, opt-in, validated on macOS/arm64
+and Linux/x86_64.** Under
+`PERRY_LLVM_INPROCESS=native` (with the `llvm-inprocess` cargo feature),
+every construction path is native: all 68 `LlBlock` semantic methods emit
+typed instructions that build straight through the C API (no per-line text),
+codegen-unit splits build per-unit native modules and partial-link, and the
+debug knobs (`PERRY_SAVE_LL` / `--trace llvm` / `PERRY_LLVM_KEEP_IR`) print
+the constructed module. `Raw` text remains only for the 89 `emit_raw`
+bespoke sites and the `LlFunction` entry-splice strings (streamed through
+the bounded line reader; the `(typed, raw)` counts are the ratchet), plus
+`has_try` functions whose setjmp volatile pass needs whole-function text.
+`rewrite-statepoints-for-gc` scheduling in-process is pinned by test
+(`rs4gc_schedules_in_process`) — the #7174 / engine-plan layer-2 unblock.
+The default path is untouched: the default build links no LLVM, and emitted
+IR is byte-identical to the merge-base over a 12-file proof corpus (the
+only divergence class is a PRE-EXISTING run-to-run coin in closure-name
+registration order — it flips between two runs of a single binary; a
+side-finding for the #7131 determinism work, not a branch effect).
+
+## Phase 2: native construction (`=native` / `=diff`)
+
+The owner's directive after Phase 0: the lever is not the transport, it is
+making generated `.ll` text *optional*. Two audits drove the design (both
+reproduced below): 96.4% of instruction emission (6,097 call sites) already
+flows through ~40 semantic methods on `LlBlock`; the bypasses are 89
+`emit_raw` sites, the `LlFunction` entry-splice mechanism (136 sites), and
+`to_ir`'s post-render passes (ret rewrites, setjmp volatile promotion). A
+grammar census over two real corpora (9,110+ instructions) bounded the
+dialect: ~30 opcodes, scalar + `[N x T]` types, six operand forms — plus two
+traps a naive builder dies on: **non-phi cross-block forward references**
+(the `idispatch` tower) and phis where 73% of incomings are forward.
+
+Architecture (deliberately different from the brief's instruction-level
+builder-trait): the port point is the **finalized function**, not the emit
+stream. `LlFunction::to_ir()` output — including entry-alloca hoists,
+boundary splices, return-site rewrites, and volatile promotion, so those
+transforms keep exactly one implementation — is consumed per function by a
+bounded dialect reader (`dialect.rs`) that constructs it through the C API:
+typed operand resolution against a per-function `%name` map,
+placeholder-RAUW for forward references (LLParser's own strategy), deferred
+phi incomings, callsite-derived call types (opaque-pointer semantics,
+measured: a direct call's function type is the *callsite's*, not the
+declare's), pre-declaration of all module-internal defines. Only the module
+*skeleton* (globals, declares, attribute groups — a few KB) is still parsed
+as text. Per-function text remains transient scaffolding (dropped
+immediately); the follow-up that removes it is typed `LlInst` variants
+inside `LlBlock` behind the same reader interface, migrating the ~40
+semantic methods opcode-by-opcode with `=diff` as the gate.
+
+Results so far:
+
+- Corpus gate (unit tests `dialect::tests::corpus_*`): every function of
+  both corpora constructs natively and passes the LLVM verifier.
+- `spike.ts`: text-parsed arm and natively-constructed arm emit
+  **byte-identical objects**; the native-mode binary matches the pinned Node
+  oracle.
+- `batch.ts` and `spike.ts`: after the placeholder fix below, both corpora
+  emit **byte-identical objects** from the two construction paths. The
+  pre-opt representations still differ in exactly one class — the C-API
+  builder constant-folds at construction (`zext i1 false`, `select i1
+  false`, constant GEPs) — which is why `=diff`'s verdict is emitted object
+  bytes, not pre-opt prints. There is no "benign object divergence" class:
+  a byte mismatch is a bug.
+- **The bug the full gap sweep caught (and the sampled slices missed):**
+  the original forward-reference placeholder was `select true, undef,
+  undef`, which the C-API builder constant-folds to the uniqued constant
+  `undef` — un-RAUW-able, verifier-clean, and silently substituting `undef`
+  for every non-phi forward reference. Symptom: a class/prototype test
+  family failing with `(number).set is not a function`; the earlier
+  "336-byte tighter native code" on `batch.ts` was the same bug deleting
+  real (never-executed-in-that-kernel) code, initially misread as benign
+  regalloc divergence. Fix: the placeholder is now a `load` from a scratch
+  `alloca` (real instructions, never foldable, erased on resolution), and a
+  use/def type mismatch is a hard error instead of a silent leak. Lesson
+  encoded in the harness: the byte verdict was right; explanations of red
+  are not.
+- Behavior: 26-test slices passed 25/25+26/26; the authoritative full
+  466-test sweep result under `=native` is recorded in the tracking issue.
+  Earlier slice findings: a multi-module test exposed two reader bugs
+  (explicit `external` linkage; skeleton globals referencing defined
+  wrapper functions — fixed by synthesized declares for every define).
+
+Modes: `PERRY_LLVM_INPROCESS=1` transport (parse whole text in-process),
+`=native` construction, `=diff` both-arms harness (returns the text arm's
+object; prints `[ir-diff] OK/MISMATCH`; `PERRY_LLVM_DIFF_DIR` dumps both
+arms' pre-opt IR + objects). All values share the env var already keyed into
+both caches. Unit-split and `emit_ir_only` paths fall through to transport.
+
+Companion artifacts:
+
+- `experiments/llvm-inprocess-spike/` — the Phase 0 spike binary (see below).
+- `crates/perry-codegen/src/inprocess.rs` — the integrated backend
+  (`llvm-inprocess` cargo feature).
+- Tracking issue: PerryTS/perry#7241 (Phase 0 answers in the opening post).
+
+## Thesis (from the experiment brief)
+
+Perry builds LLVM IR as strings, writes a `.ll`, and shells out to a
+user-supplied `clang -c`. That is an LLVM dependency that is *runtime,
+unpinned, and owned by the user's machine*: 1,376 MB of transient IR text on
+the Claude Code bundle, the #4880 whole-module `-Os` demotion, Apple clang 21
+unable to parse LLVM 22 attribute output, and errors reported as line numbers
+in gigabyte files. The experiment: own the pipeline via the LLVM C API, make
+textual `.ll` a debug view instead of the transport.
+
+## Phase 0 answers (the questions the brief required)
+
+**Which crate?** `inkwell 0.9.0` (safe wrapper) with `llvm-sys 221` alongside
+for the C-API calls inkwell does not wrap. inkwell's typed builder API held up
+for real construction work, and its `Context::create_module_from_ir` +
+`run_passes` + `write_to_memory_buffer` cover the whole transport path with no
+disk I/O. Raw `llvm-sys` alone would also work but buys nothing at this stage;
+the escape hatch composes cleanly (`AsValueRef`), so this is not an
+either/or.
+
+**Which LLVM version?** 22 (`llvm22-1` feature / `llvm-sys 221.0.1`), matching
+Homebrew's current `llvm` formula (22.1.4 on the dev box). Choosing 22 rather
+than 20 *eliminates* the version-skew problem from the brief: the
+statepoint/RS4GC work needs LLVM 22 output that Apple clang 21 cannot parse —
+in-process, there is no parse and no second toolchain. inkwell 0.9 supports
+llvm11-0 through llvm22-1, so pinning back is trivial if needed.
+
+**How is it discovered at build time?** `llvm-sys` reads
+`LLVM_SYS_221_PREFIX` (or falls back to `llvm-config` on `PATH`). The build on
+this branch was done with `LLVM_SYS_221_PREFIX=/opt/homebrew/opt/llvm`.
+
+**What must a contributor install?** Nothing new, by default. The
+`llvm-inprocess` feature is off; the default build has zero LLVM link
+dependency and byte-identical behavior. A contributor who wants the in-process
+backend needs `brew install llvm` (macOS) / LLVM 22 dev packages (Linux) and
+the env var above. Static-link cost is real (see the binary-size row) and is a
+distribution decision to make only if this graduates.
+
+**Could the bindings express what Perry needs?** Yes — everything on the
+brief's worry list, verified by construction in the spike's `demo` mode:
+
+| Construct | Result |
+|---|---|
+| NaN-box constants (`0x7FFC_0000_0000_0001` payloads in `double`) | `f64::from_bits` → `const_float` preserved bit patterns exactly, verified end-to-end by running the compiled artifact |
+| `f64` ↔ `i64` bitcasts, tag-check ladders | plain `build_bit_cast` / icmp; no friction |
+| Inline asm with exact constraint strings (`call void asm sideeffect "", ""()` — Perry's loop barrier) | `context.create_inline_asm` + `build_indirect_call` |
+| Module-level asm | `module.set_inline_assembly` (symbol verified present in the emitted object) |
+| Appending globals / `@llvm.used` (the Mach-O no-dead-strip mechanism) | `Linkage::Appending` + `llvm.metadata` section |
+| `gc "statepoint-example"` function attribute | not wrapped by inkwell — one-line `llvm_sys::core::LLVMSetGC` via `AsValueRef` |
+| `-mllvm -inlinehint-threshold=N` passthrough | not a C-API option — `LLVMParseCommandLineOptions` (process-global; see Constraints) |
+| Varargs extern declarations (runtime helper calls) | `fn_type(..., true)` |
+
+Notably, `main`'s generated IR needs *less* than the brief feared: no
+`llvm.used`, no module asm, no statepoints today (those live on
+`exp/stackmap-viability`). The empty-constraint asm barrier is the only asm.
+
+## What was built
+
+### 1. Spike binary (`experiments/llvm-inprocess-spike/`, standalone workspace)
+
+- `demo` mode: builds the table above through the builder API, verifies, runs
+  `default`, emits a `.o`, links with `cc`, executes, and checks the
+  program's own output (including the NaN-box bit patterns).
+- **clang-shim mode**: accepts the exact argv Perry's
+  `build_clang_compile_plan` produces and compiles in-process. Because both
+  Perry caches already key on `PERRY_LLVM_CLANG`, pointing that variable at
+  the shim A/Bs the whole backend through an **unmodified perry** with no
+  possibility of cross-arm cache reuse. Liveness is proven by a per-compile
+  log (`PERRY_LLVMC_SPIKE_LOG`), not inferred from the absence of errors.
+
+### 2. Integrated transport backend (`llvm-inprocess` feature)
+
+`compile_ll_to_object` in `perry-codegen/src/linker.rs` — whose own doc
+header has always called it "the seam" — gets a second implementation:
+parse-from-memory → verify → `default` → `TargetMachine`
+object-to-memory. No `.ll` touches disk (KEEP_IR and on-failure debugging
+still write one). Decision parity is by construction: the in-process path
+interprets the *same* plan argv the clang path builds (`-O3`/`-Os`/`-O0`
+incl. the #4880 oversized fallback, `-mcpu=native`, inlinehint), so the
+backends cannot drift on a decision without the plan's own tests catching it.
+Unknown flags are a hard error, never silently dropped. `PERRY_LLVM_INPROCESS`
+joins both the build-cache and object-cache keys (vacuous-A/B defense), a
+build without the feature **fails loudly** if the flag is set, and the first
+in-process compile prints a liveness witness:
+`perry: in-process LLVM backend active (LLVM 22.1.4)`.
+
+## Differential parity results
+
+**Object-level:** on the same 245 KB Perry module with identical flags, the
+in-process pipeline produced an object **byte-identical** to Homebrew
+`clang -c` (LLVM 22). Apple clang 21's object differs (8562 vs 8554 bytes of
+`__text`) — that is precisely the cross-version skew the in-process backend
+removes from user machines.
+
+**Corpus A/B (through unmodified perry, via the shim):** every 6th gap test,
+77 tests, both arms compiled by the same perry binary and same runtime `.a`:
+
+- 76/77: stdout, stderr, and exit status byte-identical.
+- 1/77 (`test_gap_http_res_socket_writable_onfinished`): both arms SIGABRT
+  with the same pre-existing `perry-ext-http` panic; the only stderr delta is
+  the OS thread id, which also differs between two runs of the *same* arm.
+  Not backend-attributable.
+- 0 compile failures on either arm; 82 in-process compiles proven live via
+  the log.
+
+**Corpus A/B (integrated backend, one binary, flag-gated):** a different
+26-test slice (stride 18, offset 3) through the same perry built with the
+feature, `PERRY_LLVM_INPROCESS=1` as the only arm difference: 25/26
+byte-identical; 26/26 compiles carried the liveness line (the harness fails
+any arm that compiled without announcing); the 1 DIFF is the same
+pre-existing `perry-ext-http` panic family, delta = OS thread id only.
+
+**Single-module end-to-end:** `spike.ts` output byte-identical across
+text arm, in-process arm (both shim and integrated), and the pinned Node
+oracle (26.5.1). A featureless build with `PERRY_LLVM_INPROCESS=1` fails
+loudly with a rebuild hint rather than silently serving the text path
+(verified), and the featureless build's normal path is unaffected
+(verified).
+
+**Textual round-trip (`.ll` → parse → print):** classes of difference, each
+mechanical: explicit default alignment (`alloca i64` → `alloca i64, align 8`),
+attribute-group renumbering (`#2` → `#0`), float formatting (`0.0` →
+`0.000000e+00`; NaN-box hex doubles print identically), `ModuleID`/
+`source_filename` headers, empty-metadata placement. Zero semantic diffs.
+This is the normalization catalogue a Phase 2 construction-parity harness
+must account for.
+
+**`-fno-math-errno`:** the C API has no equivalent knob, so it was measured
+instead of assumed: on macOS/arm64 the flag produces a byte-identical object
+on Perry IR (Darwin already defaults to errno-free math). Now also measured on
+Linux/glibc and **closed** — see below.
+
+## Linux results (Fedora 43, x86_64, glibc, LLVM 22.1.8, ELF)
+
+The macOS conclusions reproduce on a second OS, architecture and object format.
+Measured at `89b7dd191` — i.e. *before* the typed-`LlInst` migration, the
+unit-split native path and in-process RS4GC landed. Those five commits change
+what the native path covers, so the sweep below is evidence about the
+construction reader as it stood, not about branch HEAD; re-running it on
+Linux is the first item in "still open".
+
+- **Unit gate**: 528/528 `perry-codegen --features llvm-inprocess`, both
+  corpus gates confirmed constructing (not skipping — that branch is now a
+  hard error).
+- **`=diff` byte verdict**: `[ir-diff] OK` on `spike.ts` (31,929 B) and
+  `batch.ts` (84,345 B). The two construction paths are byte-identical on
+  ELF/x86-64, not only Mach-O/arm64.
+- **Full 466-test gap A/B under `=native`** (one binary, flag-only arm
+  difference): **459 SAME, 7 DIFF, 0 compile failures on either arm, 466/466
+  compiles carrying the liveness line, 0 NOT_LIVE.** 71 min wall.
+- **The 7 residuals are the same three families as macOS, and each was proven
+  by re-running one arm's binary twice**: all 7 differ against *themselves*.
+  5× `perry-ext-http` `server.rs:911` SIGABRT and 1× tokio `listener.rs:304`
+  panic (stderr embeds the OS thread id), 1× `console.time()` wall-clock
+  jitter. None is backend-attributable.
+- **Peak RSS per compile**: 244 MB text arm, 273 MB native arm — the
+  in-process context costs ~29 MB at gap-test scale. The bundle-scale RSS
+  question is untouched by this.
+
+**`-fno-math-errno` on Linux: measured no-op, question closed.** The flag only
+governs whether LLVM may treat a call to a *named* libm function as
+errno-free, and Perry never emits one. Math lowers either to `llvm.*`
+intrinsics (errno-free by definition) or to `js_math_*` runtime helpers, whose
+libm behavior lives inside `libperry_runtime.a` and is not produced by this
+compile at all. Verified on a 431 KB real module and on a purpose-built probe
+exercising every `Math.*` entry point plus `frem`: 10 intrinsic call sites, 6
+`frem`s, **zero** named libm callees; objects byte-identical with and without
+the flag under both clang 22.1.8 and clang 19. The in-process backend needs no
+equivalent knob on glibc. (The property that makes this true is "no named libm
+callee in emitted IR" — if the emitter ever gains one, this must be re-measured.)
+
+Scope limits of the Linux run, stated plainly: `PERRY_NO_AUTO_OPTIMIZE=1` on
+both arms; the box's node is v22.22.2 against a 26.5.1 pin, which does not
+affect a perry-vs-perry A/B but means this run makes no oracle-parity claim;
+at `89b7dd191` codegen-unit-split modules still fell through to transport, so
+the sweep did not exercise native construction on them (`e370f5554` has since
+ported that path — unvalidated on Linux).
+
+## Measurements (honest scope)
+
+Environment caveats, stated up front: dev box under heavy load (loadavg
+29–50 from concurrent builds — every number below is *indicative only*),
+perry built at `perry-dev` profile, spike at `opt-level=1`. Nothing here is a
+quotable benchmark; the quotable run needs a quiet box and the big corpus.
+
+| Metric | Text path (clang subprocess) | In-process | Note |
+|---|---|---|---|
+| 245 KB module, `-O3` avg of 5 | Apple 21: 123 ms · Brew 22: 147 ms | 171 ms | subprocess spawn is **not** the bottleneck at this scale |
+| 421 KB module (`batch.ts` kernel), avg of 3 | Apple 21: 241 ms | 434 ms | same conclusion; O3 dominates |
+| Transient IR on disk | full module text per compile | **0 bytes** (memory buffer both directions) | eliminated by construction |
+| Object bytes vs same-version clang | — | **byte-identical** | strongest possible parity |
+| Error reporting | text positions in the temp file | verifier/parse errors from the live module | construction-site errors need Phase 2 |
+| `perry` binary (perry-dev) | 53 MB | 224 MB with static LLVM 22 feature build | distribution cost if ever default |
+
+The compile-time *win* thesis was **not** demonstrated at small scale — and
+that is a real Phase 0 result: the payoffs that justified the experiment live
+at the 1.4 GB-of-IR scale (parse + disk transit), in version control, and in
+what the seam unlocks (per-function opt levels instead of #4880's
+whole-module demotion, DWARF via `DIBuilder`, in-process RS4GC). Those are
+Phase 2/3 measurements, gated on a quiet box, ≥25 GB free disk, and the gap
+suite green under the flag.
+
+## The seam finding (differs from the brief's assumption)
+
+The brief's Phase 1 places the seam "between lowering and IR construction"
+with two builder implementations. The codebase disagrees: perry-codegen is
+~189k lines of *string-oriented* emission (`LlModule` holds functions as
+rendered text lines), so an instruction-level builder interface is not a
+seam, it is a rewrite of the whole emitter. The seam this codebase already
+has — and documents as such — is `compile_ll_to_object(ll_text) -> Vec`.
+Swapping the transport there delivers the operational wins now (no
+subprocess, no version skew, no disk transit, pinned LLVM, exact-version
+`opt`-less RS4GC scheduling for #7174) at ~250 lines, byte-identical-proven.
+The construction-level seam remains the right *eventual* target — it is what
+kills the string-building CPU/RSS at scale and enables `DIBuilder` — but it
+should be motivated by a measured profile of string-build cost, taken through
+this transport, not assumed.
+
+## Constraints and open risks
+
+- **`cl::opt` state is process-global** (`LLVMParseCommandLineOptions`).
+  Fine today (one env-derived value per process, applied under `Once`), but a
+  per-function-opt future must use per-pipeline mechanisms instead.
+- **Parallelism**: one `Context` per rayon worker compile (LLVM contexts are
+  not thread-safe; separate contexts on separate threads are). This mirrors
+  the parallel `clang -c` model, so peak-RSS behavior needs measuring at
+  scale — a subprocess returns its memory to the OS at exit, an in-process
+  context returns it to the allocator.
+- **bindings lag**: llvm-sys tracked LLVM 22 within the release cycle
+  (221.0.1 published; inkwell 0.9 already has `llvm22-1`), but a future LLVM
+  bump waits on both crates. The subprocess path has the inverse problem
+  (whatever clang the user has). Pinning wins, but it is a pin *we* must
+  maintain.
+- **Windows / cross targets**: untested. `Target::initialize_all` registers
+  everything, and `-target` handling mirrors the clang path, but COFF and the
+  MSVC/MinGW distinction (see `probe_clang_default_triple`) need their own
+  A/B before any claim.
+- ~~**`-fno-math-errno` on Linux**~~: **closed — measured, no-op.** See the
+  Linux results section.
+
+## Recommendation, with its price
+
+**Adopt the transport seam** (this branch's `llvm-inprocess` feature) as the
+vehicle for the remaining phases; keep it opt-in until the gap suite has run
+green under `PERRY_LLVM_INPROCESS=1` on macOS *and* Linux and the Claude
+Code bundle has been compiled through it with the measurement table filled on
+a quiet box. Price: LLVM 22 as a build-time dependency *for those who enable
+it* (+171 MB on a perry-dev binary with static linking; dynamic linking
+against `libLLVM.dylib` is the dev-loop alternative), llvm-sys/inkwell as
+maintained pins, and the process-global constraints above. Do **not** start
+the instruction-level builder until the string-build cost has been profiled
+through this transport at bundle scale — if parse+build turns out to be a
+minor fraction of `default` even at 1.4 GB, the rewrite's payoff is
+DIBuilder and error locality only, and that should be decided with the number
+on the table.
+
+## Reproducing
+
+```bash
+# Spike (standalone, no Perry workspace impact)
+cd experiments/llvm-inprocess-spike
+LLVM_SYS_221_PREFIX=/opt/homebrew/opt/llvm cargo build --release
+./target/release/perry-llvmc-spike demo demo-out
+
+# A/B through unmodified perry (shim as PERRY_LLVM_CLANG)
+PERRY_LLVM_CLANG=$PWD/target/release/perry-llvmc-spike \
+PERRY_LLVMC_SPIKE_LOG=/tmp/live.log \
+  perry spike.ts -o spike_inproc
+
+# Integrated backend (one binary, flag-gated A/B)
+LLVM_SYS_221_PREFIX=/opt/homebrew/opt/llvm \
+  cargo build --profile perry-dev -p perry -p perry-runtime-static \
+  -p perry-stdlib-static --features perry/llvm-inprocess
+PERRY_LLVM_INPROCESS=1 perry file.ts -o out   # stderr must show the liveness line
+
+# Corpus A/B (resumable; re-running skips tests already in results.txt)
+experiments/llvm-inprocess-spike/batch_ab.sh /tmp/batch-ab
+```
+
+### Linux: getting LLVM 22 where the distro has none
+
+The handoff's `apt.llvm.org` recipe covers Debian/Ubuntu. On a distro with no
+LLVM 22 package at all (Fedora 43 stops at `llvm20-devel`; its system libs are
+21), use the upstream release tarball, which ships headers, `llvm-config`, the
+static `libLLVM*.a` set and a matching clang:
+
+```bash
+curl -LO https://github.com/llvm/llvm-project/releases/download/llvmorg-22.1.8/LLVM-22.1.8-Linux-X64.tar.xz
+tar -xf LLVM-22.1.8-Linux-X64.tar.xz -C ~/opt      # ~12 GB unpacked
+```
+
+One trap: that tarball is built on Ubuntu, so its baked-in
+`llvm-config --system-libs` answer names the *build host's* static system libs
+by absolute path (`/usr/lib/x86_64-linux-gnu/libzstd.a`). llvm-sys panics on
+any `--system-libs` entry that is neither `-lfoo` nor an existing file, so on
+any other distro the build dies before it compiles anything:
+
+```
+Unable to parse result of llvm-config --system-libs: /usr/.../libzstd.a
+```
+
+`mk_llvm_sys_shim.sh` generates the prefix that fixes it — a single wrapper
+`llvm-config` that rewrites *dangling* absolute paths to plain `-lname` and
+forwards everything else, including every path query (the real binary answers
+those relative to its own prefix, so the shim needs no `lib/` or `include/`):
+
+```bash
+experiments/llvm-inprocess-spike/mk_llvm_sys_shim.sh \
+  ~/opt/LLVM-22.1.8-Linux-X64 ~/opt/llvm22-shim
+export LLVM_SYS_221_PREFIX=~/opt/llvm22-shim
+```
+
+Entries that *do* exist are left alone: llvm-sys handles a real absolute path
+fine, and quietly turning a deliberate static link into a dynamic one would be
+a change nobody asked for.
+
+Measured cost of the feature build on this host: `perry` 199 MB (vs 53 MB
+default), `cargo build --profile perry-dev` 2m49s warm-registry cold-target.
diff --git a/experiments/llvm-inprocess-spike/.gitignore b/experiments/llvm-inprocess-spike/.gitignore
new file mode 100644
index 0000000000..2dc3aa0399
--- /dev/null
+++ b/experiments/llvm-inprocess-spike/.gitignore
@@ -0,0 +1,10 @@
+target/
+demo-out/
+*.o
+*.out
+*.err
+*.log
+spike_text
+spike_inproc
+spike_roundtrip.ll
+roundtrip.diff
diff --git a/experiments/llvm-inprocess-spike/Cargo.lock b/experiments/llvm-inprocess-spike/Cargo.lock
new file mode 100644
index 0000000000..a6ea3bb4d4
--- /dev/null
+++ b/experiments/llvm-inprocess-spike/Cargo.lock
@@ -0,0 +1,173 @@
+# This file is automatically @generated by Cargo.
+# It is not intended for manual editing.
+version = 4
+
+[[package]]
+name = "anyhow"
+version = "1.0.104"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "330a5ed07fa54e4702c9d6c4174f74427fc0ef6e214bbd677ae50a5099946470"
+
+[[package]]
+name = "bitflags"
+version = "2.13.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "b588b76d00fde79687d7646a9b5bdf3cc0f655e0bbd080335a95d7e96f3587da"
+
+[[package]]
+name = "cc"
+version = "1.4.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "5add81bb678e6cb321aff7fa0dc7689ad82b112dbc032cea19f91d6b8e3582b9"
+dependencies = [
+ "find-msvc-tools",
+ "shlex",
+]
+
+[[package]]
+name = "find-msvc-tools"
+version = "0.1.9"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "5baebc0774151f905a1a2cc41989300b1e6fbb29aff0ceffa1064fdd3088d582"
+
+[[package]]
+name = "inkwell"
+version = "0.9.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "7decbc9dfa45a4a827a6ff7b822c113b1285678a937e84213417d4ca8a095782"
+dependencies = [
+ "bitflags",
+ "inkwell_internals",
+ "libc",
+ "llvm-sys",
+ "thiserror",
+]
+
+[[package]]
+name = "inkwell_internals"
+version = "0.14.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "6cfe97ee860815a90ed17e09639513269e39420a7440f3f4c996f238c514cf8d"
+dependencies = [
+ "proc-macro2",
+ "quote",
+ "syn 2.0.119",
+]
+
+[[package]]
+name = "lazy_static"
+version = "1.5.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "bbd2bcb4c963f2ddae06a2efc7e9f3591312473c50c6685e1f298068316e66fe"
+
+[[package]]
+name = "libc"
+version = "0.2.189"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "3eaf3ede3fee6db1a4c2ee091bf8a8b4dccdc6d17f656fb07896ee72867612f2"
+
+[[package]]
+name = "llvm-sys"
+version = "221.0.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "2abcc34a3b190f03c2a61b555f218f529589ff13657bdd2ff8ac3e85f2abe6bb"
+dependencies = [
+ "anyhow",
+ "cc",
+ "lazy_static",
+ "libc",
+ "regex-lite",
+ "semver",
+]
+
+[[package]]
+name = "perry-llvmc-spike"
+version = "0.1.0"
+dependencies = [
+ "inkwell",
+ "llvm-sys",
+]
+
+[[package]]
+name = "proc-macro2"
+version = "1.0.107"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "985e7ec9bb745e6ce6535b544d84d6cd6f7ad8bd711c398938ae983b91a766d9"
+dependencies = [
+ "unicode-ident",
+]
+
+[[package]]
+name = "quote"
+version = "1.0.47"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "1fbf4db142a473a8d80c26bbf18454ed458bf8d26c8219c331daecfdbd079001"
+dependencies = [
+ "proc-macro2",
+]
+
+[[package]]
+name = "regex-lite"
+version = "0.1.9"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "cab834c73d247e67f4fae452806d17d3c7501756d98c8808d7c9c7aa7d18f973"
+
+[[package]]
+name = "semver"
+version = "1.0.28"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "8a7852d02fc848982e0c167ef163aaff9cd91dc640ba85e263cb1ce46fae51cd"
+
+[[package]]
+name = "shlex"
+version = "2.0.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "f8fadd59c855ef2080decdef8ff161eb6661b86933c9d82e5ba29dc602a55aba"
+
+[[package]]
+name = "syn"
+version = "2.0.119"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "872831b642d1a07999a962a351ed35b955ea2cfc8f3862091e2a240a84f17297"
+dependencies = [
+ "proc-macro2",
+ "quote",
+ "unicode-ident",
+]
+
+[[package]]
+name = "syn"
+version = "3.0.3"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "53e9bae58849f64dfa4f5d5ae372c8341f7305f82a3868709269343628b659a3"
+dependencies = [
+ "proc-macro2",
+ "quote",
+ "unicode-ident",
+]
+
+[[package]]
+name = "thiserror"
+version = "2.0.19"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "09a43598840e33d5b0331f38c5e30d13bb11c11210a4b58f0d9b18a5a5eefcd9"
+dependencies = [
+ "thiserror-impl",
+]
+
+[[package]]
+name = "thiserror-impl"
+version = "2.0.19"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "43cbfe0cf76104d42a574802844187e84a305e531ed54455f11fbde0f10541cd"
+dependencies = [
+ "proc-macro2",
+ "quote",
+ "syn 3.0.3",
+]
+
+[[package]]
+name = "unicode-ident"
+version = "1.0.24"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "e6e4313cd5fcd3dad5cafa179702e2b244f760991f45397d14d4ebf38247da75"
diff --git a/experiments/llvm-inprocess-spike/Cargo.toml b/experiments/llvm-inprocess-spike/Cargo.toml
new file mode 100644
index 0000000000..d93456a04f
--- /dev/null
+++ b/experiments/llvm-inprocess-spike/Cargo.toml
@@ -0,0 +1,17 @@
+[package]
+name = "perry-llvmc-spike"
+version = "0.1.0"
+edition = "2021"
+
+# Deliberately its own workspace: Phase 0 must not touch the Perry workspace
+# build graph. Integration (Phase 1+) will add a feature-gated crate instead.
+[workspace]
+
+[dependencies]
+inkwell = { version = "0.9.0", features = ["llvm22-1"] }
+# Same LLVM major as inkwell's feature; used for the handful of C-API calls
+# inkwell does not wrap (LLVMSetGC, LLVMParseCommandLineOptions).
+llvm-sys = "221"
+
+[profile.release]
+opt-level = 1
diff --git a/experiments/llvm-inprocess-spike/batch_ab.sh b/experiments/llvm-inprocess-spike/batch_ab.sh
new file mode 100755
index 0000000000..4d73458ffb
--- /dev/null
+++ b/experiments/llvm-inprocess-spike/batch_ab.sh
@@ -0,0 +1,127 @@
+#!/bin/bash
+# Phase 0 corpus A/B: every 6th gap test, text backend vs in-process backend.
+# For each test both arms compile with the SAME perry binary; only
+# PERRY_LLVM_CLANG differs (default /usr/bin/clang vs the in-process shim).
+# Divergence classes reported: SAME, DIFF (output/exit differs), CFAIL_T/CFAIL_P
+# (one arm's compile failed), CFAIL_BOTH (pre-existing, not backend-related).
+set -u
+# Worktree root: derived from this script's own location so a fresh clone on
+# any host works unmodified; override with WT=... for an out-of-tree layout.
+WT=${WT:-$(cd "$(dirname "${BASH_SOURCE[0]}")/../.." && pwd)}
+SPIKE=$WT/experiments/llvm-inprocess-spike/target/release/perry-llvmc-spike
+PERRY=$WT/target/perry-dev/perry
+WORK=${1:?usage: batch_ab.sh  [shim|flag] [stride] [offset]}
+# Arm P mechanism: "shim" = PERRY_LLVM_CLANG= through an
+# unmodified perry; "flag" = PERRY_LLVM_INPROCESS=1 through a perry built
+# with the llvm-inprocess feature.
+MODE=${2:-shim}
+STRIDE=${3:-6}
+OFFSET=${4:-0}
+# Portability: coreutils installs `gtimeout` on macOS (brew), `timeout` on Linux.
+TIMEOUT=$(command -v gtimeout || command -v timeout)
+# Probe the filesystem the work dir actually lives on, not "/" — on a typical
+# Linux box /home is a separate (and much larger) filesystem than /.
+free_gb_now() {
+  if [ "$(uname)" = "Darwin" ]; then
+    df -g "$WORK" | awk 'NR==2{print $4}'
+  else
+    df -BG --output=avail "$WORK" | awk 'NR==2{gsub("G","",$1); print $1}'
+  fi
+}
+mkdir -p "$WORK"
+export PERRY_RUNTIME_DIR=$WT/target/perry-dev
+export PERRY_NO_AUTO_OPTIMIZE=1
+export PERRY_LLVMC_SPIKE_LOG=$WORK/liveness.log
+: > "$WORK/liveness.log"
+touch "$WORK/results.txt"
+
+# A full-suite run is ~100 minutes of a developer workstation's life, so it has
+# to survive that workstation being used. Two guards, learned the hard way when
+# a concurrent cargo build pushed the box into the OOM killer and six compiles
+# died mid-link — recorded as CFAIL_BOTH, which reads exactly like a real
+# pre-existing failure:
+#
+#   1. Re-running skips tests already recorded, so an interrupted run resumes
+#      instead of starting over (delete results.txt for a clean run).
+#   2. A compile killed by a signal (128+n; the OOM killer's SIGKILL is 137) is
+#      never scored. It waits for memory, retries once, and if it dies again it
+#      is recorded as OOM/INFRA — a category no backend conclusion may be drawn
+#      from, and one the summary reports separately.
+free_mb_now() {
+  if [ "$(uname)" = "Darwin" ]; then
+    vm_stat | awk '/page size of/{p=$8} /Pages free/{f=$3} END{print int(f*p/1048576)}'
+  else
+    awk '/MemAvailable/{print int($2/1024)}' /proc/meminfo
+  fi
+}
+MIN_FREE_MB=${MIN_FREE_MB:-2048}
+wait_for_memory() {
+  local waited=0
+  while [ "$(free_mb_now)" -lt "$MIN_FREE_MB" ] && [ $waited -lt 600 ]; do
+    sleep 10; waited=$((waited+10))
+  done
+}
+# A compile that exits 128+n died on signal n rather than failing to compile.
+# (`timeout`'s own 124 is deliberately NOT in this class: a compile that hangs
+# for 180s is a result worth seeing, not infrastructure noise.)
+killed_by_signal() { [ "$1" -gt 128 ]; }
+
+i=0 same=0 diff=0 cfail_t=0 cfail_p=0 cfail_both=0 skipped=0 infra=0
+for t in $(ls "$WT"/test-files/test_gap_*.ts | sort); do
+  i=$((i+1))
+  [ $((i % STRIDE)) -ne $OFFSET ] && continue
+  name=$(basename "$t" .ts)
+  if grep -q " $name\$\| $name " "$WORK/results.txt"; then skipped=$((skipped+1)); continue; fi
+  free_gb=$(free_gb_now)
+  if [ "$free_gb" -lt 6 ]; then echo "ABORT: only ${free_gb}GB free" | tee -a "$WORK/summary.txt"; exit 2; fi
+  wait_for_memory
+
+  compile_arms() {
+    "$TIMEOUT" 180 "$PERRY" "$t" -o "$WORK/$name.t" >"$WORK/$name.t.compile" 2>&1
+    ct=$?
+    if [ "$MODE" = "flag" ]; then
+      PERRY_LLVM_INPROCESS=${INPROCESS_VALUE:-1} "$TIMEOUT" 180 "$PERRY" "$t" -o "$WORK/$name.p" >"$WORK/$name.p.compile" 2>&1
+      cp=$?
+      # Liveness: the arm must have announced the in-process backend.
+      if [ $cp -eq 0 ] && ! grep -q "in-process LLVM backend active" "$WORK/$name.p.compile"; then
+        echo "NOT_LIVE $name" >> "$WORK/results.txt"; cp=97
+      fi
+    else
+      PERRY_LLVM_CLANG=$SPIKE "$TIMEOUT" 180 "$PERRY" "$t" -o "$WORK/$name.p" >"$WORK/$name.p.compile" 2>&1
+      cp=$?
+    fi
+  }
+  compile_arms
+  if killed_by_signal $ct || killed_by_signal $cp; then
+    wait_for_memory
+    compile_arms
+    if killed_by_signal $ct || killed_by_signal $cp; then
+      infra=$((infra+1)); echo "OOM_INFRA $name (signal t=$ct p=$cp — NOT a backend result)" >> "$WORK/results.txt"
+      rm -f "$WORK/$name".[tp]; continue
+    fi
+  fi
+
+  if [ $ct -ne 0 ] && [ $cp -ne 0 ]; then cfail_both=$((cfail_both+1)); echo "CFAIL_BOTH $name" >> "$WORK/results.txt"; rm -f "$WORK/$name".[tp]; continue; fi
+  if [ $ct -ne 0 ]; then cfail_t=$((cfail_t+1)); echo "CFAIL_T $name" >> "$WORK/results.txt"; rm -f "$WORK/$name".[tp]; continue; fi
+  if [ $cp -ne 0 ]; then cfail_p=$((cfail_p+1)); echo "CFAIL_P $name" >> "$WORK/results.txt"; rm -f "$WORK/$name".[tp]; continue; fi
+
+  "$TIMEOUT" 20 "$WORK/$name.t" >"$WORK/$name.t.out" 2>"$WORK/$name.t.err"; rt=$?
+  "$TIMEOUT" 20 "$WORK/$name.p" >"$WORK/$name.p.out" 2>"$WORK/$name.p.err"; rp=$?
+  if [ $rt -eq $rp ] && cmp -s "$WORK/$name.t.out" "$WORK/$name.p.out" && cmp -s "$WORK/$name.t.err" "$WORK/$name.p.err"; then
+    same=$((same+1)); echo "SAME $name (exit=$rt)" >> "$WORK/results.txt"
+  else
+    diff=$((diff+1)); echo "DIFF $name (exit t=$rt p=$rp)" >> "$WORK/results.txt"
+  fi
+  rm -f "$WORK/$name.t" "$WORK/$name.p"
+done
+if [ "$MODE" = "flag" ]; then
+  compiles=$(grep -l "in-process LLVM backend active" "$WORK"/*.p.compile 2>/dev/null | wc -l | tr -d ' ')
+else
+  compiles=$(grep -c . "$WORK/liveness.log" || true)
+fi
+{
+  echo "batch A/B complete: same=$same diff=$diff cfail_t=$cfail_t cfail_p=$cfail_p cfail_both=$cfail_both"
+  echo "resumed (already recorded, not re-run): $skipped"
+  echo "OOM/INFRA (killed by signal twice — excluded from every conclusion): $infra"
+  echo "in-process compiles proven live: $compiles"
+} | tee "$WORK/summary.txt"
diff --git a/experiments/llvm-inprocess-spike/batch_kernel.ll b/experiments/llvm-inprocess-spike/batch_kernel.ll
new file mode 100644
index 0000000000..d185e937b8
--- /dev/null
+++ b/experiments/llvm-inprocess-spike/batch_kernel.ll
@@ -0,0 +1,10658 @@
+; Generated by perry-codegen
+target triple = "arm64-apple-macosx15.0.0"
+
+@batch_ts_.str.0.bytes = private unnamed_addr constant [4 x i8] c"acc\00"
+@batch_ts_.str.1.bytes = private unnamed_addr constant [6 x i8] c"total\00"
+@batch_ts_.str.2.bytes = private unnamed_addr constant [7 x i8] c"weight\00"
+@batch_ts_.str.3.bytes = private unnamed_addr constant [5 x i8] c"peak\00"
+@batch_ts_.str.4.bytes = private unnamed_addr constant [6 x i8] c"score\00"
+@batch_ts_.str.5.bytes = private unnamed_addr constant [7 x i8] c"bucket\00"
+@batch_ts_.str.6.bytes = private unnamed_addr constant [2 x i8] c":\00"
+@batch_ts_.str.7.bytes = private unnamed_addr constant [3 x i8] c"id\00"
+@batch_ts_.str.8.bytes = private unnamed_addr constant [8 x i8] c"rescore\00"
+@batch_ts_.str.9.bytes = private unnamed_addr constant [5 x i8] c"even\00"
+@batch_ts_.str.10.bytes = private unnamed_addr constant [4 x i8] c"odd\00"
+@batch_ts_.str.11.bytes = private unnamed_addr constant [6 x i8] c"value\00"
+@batch_ts_.str.12.bytes = private unnamed_addr constant [4 x i8] c"key\00"
+@batch_ts_.str.13.bytes = private unnamed_addr constant [6 x i8] c"count\00"
+@batch_ts_.str.14.bytes = private unnamed_addr constant [4 x i8] c"tag\00"
+@batch_ts_.str.15.bytes = private unnamed_addr constant [6 x i8] c"alpha\00"
+@batch_ts_.str.16.bytes = private unnamed_addr constant [5 x i8] c"beta\00"
+@batch_ts_.str.17.bytes = private unnamed_addr constant [6 x i8] c"gamma\00"
+@batch_ts_.str.18.bytes = private unnamed_addr constant [6 x i8] c"delta\00"
+@batch_ts_.str.19.bytes = private unnamed_addr constant [11 x i8] c"checksum: \00"
+@perry_class_keys_packed_batch_ts__0 = private unnamed_addr constant [24 x i8] c"id\00bucket\00weight\00score\00\00"
+@perry_class_keys_packed_batch_ts__1 = private unnamed_addr constant [15 x i8] c"key\00value\00tag\00\00"
+@perry_class_keys_packed_batch_ts__2 = private unnamed_addr constant [25 x i8] c"bucket\00count\00total\00peak\00\00"
+@.str.0 = private unnamed_addr constant [10 x i8] c"buildRows\00"
+@.str.1 = private unnamed_addr constant [6 x i8] c"shape\00"
+@.str.2 = private unnamed_addr constant [7 x i8] c"ranked\00"
+@.str.3 = private unnamed_addr constant [10 x i8] c"summarize\00"
+@.str.4 = private unnamed_addr constant [10 x i8] c"totalsRow\00"
+@.str.5 = private unnamed_addr constant [214 x i8] c"function buildRows(n: number): Row[] {\0A    const rows: Row[] = [];\0A    for (let i = 0; i < n; i++) {\0A        const row = new Row(i, BUCKETS[i % 4], (i % 97) * 0.5);\0A        rows.push(row);\0A    }\0A    return rows;\0A}\00"
+@.str.6 = private unnamed_addr constant [194 x i8] c"function shape(rows: Row[]): Shaped[] {\0A    return rows.map((r) => ({\0A        key: r.bucket + \22:\22 + r.id,\0A        value: r.rescore(1.5),\0A        tag: r.id % 2 === 0 ? \22even\22 : \22odd\22,\0A    }));\0A}\00"
+@.str.7 = private unnamed_addr constant [272 x i8] c"function ranked(items: Shaped[]): Shaped[] {\0A    const copy = items.slice();\0A    copy.sort((a, b) => {\0A        if (a.value !== b.value) {\0A            return b.value - a.value;\0A        }\0A        return a.key < b.key ? -1 : a.key > b.key ? 1 : 0;\0A    });\0A    return copy;\0A}\00"
+@.str.8 = private unnamed_addr constant [640 x i8] c"function summarize(rows: Row[]): Summary[] {\0A    const byBucket: Summary[] = [];\0A    for (let b = 0; b < BUCKETS.length; b++) {\0A        const s: Summary = {\0A            bucket: BUCKETS[b],\0A            count: 0,\0A            total: 0,\0A            peak: 0,\0A        };\0A        byBucket.push(s);\0A    }\0A    rows.reduce((acc: Summary[], r: Row) => {\0A        const idx = BUCKETS.indexOf(r.bucket);\0A        const slot = acc[idx];\0A        slot.count = slot.count + 1;\0A        slot.total = slot.total + r.score;\0A        if (r.score > slot.peak) {\0A            slot.peak = r.score;\0A        }\0A        return acc;\0A    }, byBucket);\0A    return byBucket;\0A}\00"
+@.str.9 = private unnamed_addr constant [264 x i8] c"function totalsRow(summaries: Summary[]): Row {\0A    const acc = new Row(0, \22acc\22, 0);\0A    for (let i = 0; i < summaries.length; i++) {\0A        acc.weight = acc.weight + summaries[i].total;\0A        acc.score = acc.score + summaries[i].peak;\0A    }\0A    return acc;\0A}\00"
+@.str.10 = private unnamed_addr constant [130 x i8] c"(r) => ({\0A        key: r.bucket + \22:\22 + r.id,\0A        value: r.rescore(1.5),\0A        tag: r.id % 2 === 0 ? \22even\22 : \22odd\22,\0A    })\00"
+@.str.11 = private unnamed_addr constant [160 x i8] c"(a, b) => {\0A        if (a.value !== b.value) {\0A            return b.value - a.value;\0A        }\0A        return a.key < b.key ? -1 : a.key > b.key ? 1 : 0;\0A    }\00"
+@.str.12 = private unnamed_addr constant [292 x i8] c"(acc: Summary[], r: Row) => {\0A        const idx = BUCKETS.indexOf(r.bucket);\0A        const slot = acc[idx];\0A        slot.count = slot.count + 1;\0A        slot.total = slot.total + r.score;\0A        if (r.score > slot.peak) {\0A            slot.peak = r.score;\0A        }\0A        return acc;\0A    }\00"
+@.str.13 = private unnamed_addr constant [4 x i8] c"Row\00"
+
+@perry_null_guard_zero = internal global i32 0
+@PERRY_CLASS_FIELD_INLINE_GUARD_DISABLED = external global i8
+@PERRY_ARRAY_INDEX_FAST_PATH_INVALIDATED = external global i8
+@PERRY_INCREMENTAL_MARK_BARRIER_ACTIVE_COUNT = external global i32
+@PERRY_TA_KIND_CACHE = external global [64 x i64]
+@PERRY_TA_VIEW_GUARD = external global i64
+@perry_class_keys_batch_ts__Row = internal global i64 0
+@perry_class_keys_batch_ts____AnonShape_e75d7e32e87dc826 = internal global i64 0
+@perry_class_keys_batch_ts____AnonShape_c33c4204c28b9430 = internal global i64 0
+@perry_global_batch_ts__1 = global double 0x7FFC000000000001
+@perry_ic_2 = private global [8 x i64] zeroinitializer
+@perry_ic_5 = private global [8 x i64] zeroinitializer
+@perry_ic_8 = private global [8 x i64] zeroinitializer
+@perry_ic_10 = private global [8 x i64] zeroinitializer
+@perry_ic_12 = private global [8 x i64] zeroinitializer
+@perry_ic_14 = private global [8 x i64] zeroinitializer
+@perry_ic_16 = private global [8 x i64] zeroinitializer
+@perry_ic_18 = private global [8 x i64] zeroinitializer
+@perry_ic_20 = private global [8 x i64] zeroinitializer
+@perry_ic_22 = private global [8 x i64] zeroinitializer
+@perry_ic_24 = private global [8 x i64] zeroinitializer
+@perry_ic_26 = private global [8 x i64] zeroinitializer
+@perry_ic_28 = private global [8 x i64] zeroinitializer
+@perry_ic_31 = private global [8 x i64] zeroinitializer
+@perry_ic_32 = private global [8 x i64] zeroinitializer
+@perry_ic_34 = private global [8 x i64] zeroinitializer
+@perry_ic_36 = private global [8 x i64] zeroinitializer
+@perry_ic_39 = private global [8 x i64] zeroinitializer
+@perry_ic_41 = private global [8 x i64] zeroinitializer
+@perry_ic_71 = private global [8 x i64] zeroinitializer
+@perry_ic_74 = private global [8 x i64] zeroinitializer
+@perry_ic_77 = private global [8 x i64] zeroinitializer
+@batch_ts_.str.0.handle = internal global double 0.0
+@batch_ts_.str.1.handle = internal global double 0.0
+@batch_ts_.str.2.handle = internal global double 0.0
+@batch_ts_.str.3.handle = internal global double 0.0
+@batch_ts_.str.4.handle = internal global double 0.0
+@batch_ts_.str.5.handle = internal global double 0.0
+@batch_ts_.str.6.handle = internal global double 0.0
+@batch_ts_.str.7.handle = internal global double 0.0
+@batch_ts_.str.8.dispatch = private unnamed_addr constant { i32, i32, i64, ptr } { i32 7, i32 0, i64 3167274721163222882, ptr @batch_ts_.str.8.bytes }
+@batch_ts_.str.8.handle = internal global double 0.0
+@batch_ts_.str.9.handle = internal global double 0.0
+@batch_ts_.str.10.handle = internal global double 0.0
+@batch_ts_.str.11.handle = internal global double 0.0
+@batch_ts_.str.12.handle = internal global double 0.0
+@batch_ts_.str.13.handle = internal global double 0.0
+@batch_ts_.str.14.handle = internal global double 0.0
+@batch_ts_.str.15.handle = internal global double 0.0
+@batch_ts_.str.16.handle = internal global double 0.0
+@batch_ts_.str.17.handle = internal global double 0.0
+@batch_ts_.str.18.handle = internal global double 0.0
+@batch_ts_.str.19.handle = internal global double 0.0
+@perry_typed_shape_raw_f64_mask_batch_ts__Row = private unnamed_addr constant [1 x i64] [i64 13]
+@perry_typed_shape_mask_batch_ts__Row = private unnamed_addr constant [1 x i64] [i64 2]
+@perry_typed_shape_mask_batch_ts____AnonShape_e75d7e32e87dc826 = private unnamed_addr constant [1 x i64] [i64 7]
+@perry_typed_shape_raw_f64_mask_batch_ts____AnonShape_c33c4204c28b9430 = private unnamed_addr constant [1 x i64] [i64 14]
+@perry_typed_shape_mask_batch_ts____AnonShape_c33c4204c28b9430 = private unnamed_addr constant [1 x i64] [i64 1]
+
+declare void @js_gc_init()
+declare void @js_typed_feedback_maybe_dump_trace()
+declare void @js_stdlib_init_dispatch()
+declare void @perry_app_group_init(ptr, i32)
+declare void @perry_macos_bundle_chdir()
+declare i32 @perry_i18n_locale_index_for(i64, i32)
+declare void @perry_i18n_init(ptr, ptr, i32, i32)
+declare void @perry_i18n_set_currencies(ptr, i32)
+declare i32 @perry_i18n_plural_category(i32, double)
+declare void @js_register_function_name(ptr, ptr, i32)
+declare void @js_register_function_source(ptr, ptr, i32)
+declare void @js_console_log_dynamic(double)
+declare void @js_console_log_number(double)
+declare void @js_console_error_dynamic(double)
+declare void @js_console_error_number(double)
+declare void @js_console_warn_dynamic(double)
+declare void @js_console_warn_number(double)
+declare void @js_console_dir_with_options(double, double)
+declare double @js_console_method_by_value(double)
+declare double @js_nanbox_string(i64)
+declare double @js_nanbox_pointer(i64) #2
+declare i64 @js_nanbox_get_pointer(double) #2
+declare double @js_native_handle_new_owned(i64, i64, i32, i32, ptr, ptr, i64)
+declare double @js_native_handle_new_borrowed(i64, i64, i32, i32, ptr, i64)
+declare i64 @js_native_handle_unwrap(double, i64, i32, i32, i32)
+declare i64 @js_string_from_bytes(ptr, i32)
+declare i64 @js_string_from_wtf8_bytes(ptr, i32)
+declare i32 @js_is_truthy(double) #3
+declare double @js_native_abi_check_f64(double)
+declare i32 @js_typed_f64_arg_guard(double) #2
+declare double @js_typed_f64_arg_to_raw(double)
+declare i32 @js_typed_i32_arg_guard(double) #2
+declare i32 @js_typed_i32_arg_to_raw(double) #2
+declare i32 @js_typed_i1_arg_guard(double) #2
+declare i32 @js_typed_i1_arg_to_raw(double) #2
+declare i32 @js_typed_string_arg_guard(double) #2
+declare i64 @js_typed_string_arg_to_raw(double)
+declare float @js_native_abi_check_f32(double)
+declare i32 @js_native_abi_check_i32(double)
+declare i64 @js_native_abi_check_i64(double)
+declare i32 @js_native_abi_check_u32(double)
+declare i64 @js_native_abi_check_u64(double)
+declare i64 @js_native_abi_check_usize(double)
+declare i64 @js_native_abi_check_string_ptr(double)
+declare i64 @js_native_abi_check_ptr(double)
+declare ptr @js_native_abi_check_buffer_data_ptr(double)
+declare i64 @js_native_abi_check_buffer_byte_len(double)
+declare i64 @js_native_abi_check_promise(double)
+declare i64 @js_native_abi_check_pod_object(double)
+declare double @js_date_now()
+declare void @js_gc_register_global_root(i64)
+declare i64 @js_string_concat(i64, i64)
+declare double @js_string_concat_box(double, double)
+declare i64 @js_jsvalue_to_string(double)
+declare i64 @js_jsvalue_to_string_method(double)
+declare i64 @js_jsvalue_to_string_coerce(double)
+declare i64 @js_string_concat_value(i64, double)
+declare i64 @js_value_concat_string(double, i64)
+declare i64 @js_string_concat_chain(i64, i32)
+declare i64 @js_string_append(i64, i64)
+declare i32 @js_string_index_of(i64, i64)
+declare i32 @js_string_index_of_from(i64, i64, i32)
+declare i32 @js_string_position_to_index(double)
+declare i64 @js_string_slice(i64, i32, i32)
+declare i64 @js_string_substring(i64, i32, i32)
+declare i64 @js_string_substr(i64, double, double)
+declare i64 @js_string_split(i64, i64)
+declare i64 @js_string_split_n(i64, i64, i32)
+declare double @js_string_split_part_value(i64, i64, i32)
+declare double @js_string_split_part_utf16_length(i64, i64, i32)
+declare double @js_string_to_upper_case_split_part_utf16_length(i64, i64, i32)
+declare i32 @js_string_to_upper_case_index_of(i64, i64)
+declare i64 @js_string_split_value(i64, double, double)
+declare double @js_math_trunc(double)
+declare double @js_math_round(double)
+declare double @js_math_sign(double)
+declare double @js_math_imul(double, double)
+declare double @js_math_pow(double, double)
+declare double @llvm.sqrt.f64(double)
+declare double @llvm.floor.f64(double)
+declare double @llvm.ceil.f64(double)
+declare double @llvm.fabs.f64(double)
+declare double @llvm.copysign.f64(double, double)
+declare void @llvm.assume(i1)
+declare i16 @llvm.bswap.i16(i16)
+declare i32 @llvm.bswap.i32(i32)
+declare i64 @llvm.bswap.i64(i64)
+declare i32 @llvm.aarch64.fjcvtzs(double)
+declare void @llvm.memset.p0.i64(ptr, i8, i64, i1)
+declare void @llvm.memmove.p0.p0.i64(ptr, ptr, i64, i1)
+declare i64 @js_json_stringify(double, i32)
+declare i64 @js_map_alloc(i32)
+declare i64 @js_text_encoder_encode_into_llvm(double, double)
+declare i64 @js_value_typeof(double)
+declare i32 @js_string_starts_with(i64, i64)
+declare i32 @js_string_ends_with(i64, i64)
+declare i64 @js_string_search_value_to_string(double, i32)
+declare i32 @js_string_starts_with_at(i64, i64, i32)
+declare i32 @js_string_ends_with_at(i64, i64, i32)
+declare i64 @js_closure_alloc(ptr, i32)
+declare i64 @js_closure_alloc_singleton(ptr)
+declare i64 @js_closure_alloc_with_captures_singleton(ptr, i32, ptr)
+declare void @js_closure_set_capture_bits(i64, i32, i64)
+declare i64 @js_closure_get_capture_bits(i64, i32)
+declare void @js_closure_set_capture_f64(i64, i32, double)
+declare double @js_closure_get_capture_f64(i64, i32)
+declare void @js_register_closure_rest(ptr, i32)
+declare void @js_register_closure_synthetic_arguments(ptr, i32)
+declare void @js_register_closure_rest_and_arguments(ptr, i32)
+declare void @js_register_closure_arity(ptr, i32)
+declare void @js_register_closure_length(ptr, i32)
+declare void @js_register_closure_arrow_function(ptr)
+declare void @js_register_closure_strict_function(ptr)
+declare void @js_register_closure_async_function(ptr)
+declare void @js_register_closure_generator_function(ptr)
+declare void @js_register_closure_async_generator_function(ptr)
+declare i64 @js_closure_unbox_callee_checked(double)
+declare i64 @js_closure_unbox_callee_checked_rebind(double, double)
+declare double @js_closure_call0(i64)
+declare double @js_closure_call1(i64, double)
+declare double @js_closure_call2(i64, double, double)
+declare double @js_closure_call3(i64, double, double, double)
+declare double @js_closure_call4(i64, double, double, double, double)
+declare double @js_closure_call5(i64, double, double, double, double, double)
+declare double @js_closure_call6(i64, double, double, double, double, double, double)
+declare double @js_closure_call7(i64, double, double, double, double, double, double, double)
+declare double @js_closure_call8(i64, double, double, double, double, double, double, double, double)
+declare double @js_closure_call9(i64, double, double, double, double, double, double, double, double, double)
+declare double @js_closure_call10(i64, double, double, double, double, double, double, double, double, double, double)
+declare double @js_closure_call11(i64, double, double, double, double, double, double, double, double, double, double, double)
+declare double @js_closure_call12(i64, double, double, double, double, double, double, double, double, double, double, double, double)
+declare double @js_closure_call13(i64, double, double, double, double, double, double, double, double, double, double, double, double, double)
+declare double @js_closure_call14(i64, double, double, double, double, double, double, double, double, double, double, double, double, double, double)
+declare double @js_closure_call15(i64, double, double, double, double, double, double, double, double, double, double, double, double, double, double, double)
+declare double @js_closure_call16(i64, double, double, double, double, double, double, double, double, double, double, double, double, double, double, double, double)
+declare i64 @js_array_map(i64, i64)
+declare void @js_array_map_discard(i64, i64)
+declare i64 @js_array_filter(i64, i64)
+declare i64 @js_array_concat(i64, i64)
+declare i64 @js_array_concat_new(i64, i64)
+declare i64 @js_error_new()
+declare i64 @js_error_new_with_message(i64)
+declare i64 @js_error_new_from_value(double)
+declare i64 @js_error_new_kind_from_value(i32, double)
+declare i64 @js_error_new_with_cause_from_value(double, double)
+declare i64 @js_error_new_kind_with_options_from_value(i32, double, double)
+declare double @js_assert_assertion_error_ctor(double)
+declare double @js_assert_assert_ctor(double)
+declare void @js_throw_type_error_property_access(i32, ptr, i64)
+declare void @js_throw_type_error_not_a_function(ptr, i64, ptr, i64)
+declare void @js_throw_error_with_code(ptr, i64, ptr, i64, i32)
+declare i64 @js_map_set(i64, double, double)
+declare i64 @js_map_set_string_number(i64, i64, double)
+declare i64 @js_map_set_string_key(i64, i64, double)
+declare i64 @js_map_set_string_i32(i64, i64, i32)
+declare i64 @js_map_set_string_u32(i64, i64, i32)
+declare i64 @js_map_set_string_f32(i64, i64, float)
+declare i64 @js_map_set_string_bool(i64, i64, i32)
+declare i64 @js_map_set_string_string(i64, i64, i64)
+declare i64 @js_map_set_number_key(i64, double, double)
+declare double @js_map_get(i64, double)
+declare double @js_map_get_string_key(i64, i64)
+declare double @js_map_get_number_key(i64, double)
+declare i32 @js_map_has(i64, double)
+declare i32 @js_map_has_string_key(i64, i64)
+declare i32 @js_map_has_number_key(i64, double)
+declare i32 @js_map_delete(i64, double)
+declare i32 @js_map_delete_string_key(i64, i64)
+declare i32 @js_map_delete_number_key(i64, double)
+declare i64 @js_object_keys(i64)
+declare i64 @js_object_keys_value(double)
+declare i64 @js_for_in_keys_value(double)
+declare double @js_is_finite(double)
+declare i32 @js_is_undefined_or_bare_nan(double)
+declare double @js_math_min_array(i64)
+declare double @js_math_max_array(i64)
+declare double @js_math_min2(double, double)
+declare double @js_math_max2(double, double)
+declare i64 @js_string_coerce(double)
+declare i64 @js_string_coerce_method_this(double, ptr, i64)
+declare i64 @js_array_slice(i64, i32, i32)
+declare i64 @js_array_slice_values(i64, double, double)
+declare double @js_array_shift_f64(i64)
+declare i64 @js_set_alloc(i32)
+declare i64 @js_set_from_array(i64)
+declare i64 @js_set_from_iterable(double)
+declare i64 @js_map_from_array(i64)
+declare i64 @js_map_from_iterable(double)
+declare double @js_object_has_property(double, double)
+declare double @js_in_operator(double, double)
+declare double @js_private_brand_check(double, i32, ptr, i32)
+declare double @js_private_guard(double, i32, ptr, i32, i32, i32)
+declare double @js_fs_to_unix_timestamp(double)
+declare i32 @js_fs_write_file_sync(double, double)
+declare i32 @js_fs_write_file_sync_options(double, double, double)
+declare i32 @js_fs_append_file_sync(double, double)
+declare i32 @js_fs_append_file_sync_options(double, double, double)
+declare i32 @js_fs_exists_sync(double)
+declare i64 @js_fs_read_file_sync(double)
+declare double @js_fs_read_file_dispatch(double, double)
+declare double @js_fs_open_as_blob(double, double)
+declare double @js_fs_promises_read_file(double, double)
+declare double @js_fs_promises_write_file(double, double, double)
+declare double @js_fs_promises_append_file(double, double, double)
+declare double @js_fs_promises_mkdir(double, double)
+declare double @js_fs_promises_rmdir(double, double)
+declare i32 @js_fs_mkdir_sync(double)
+declare i32 @js_fs_mkdir_sync_options(double, double)
+declare i32 @js_fs_unlink_sync(double)
+declare double @js_fs_readdir_sync(double, double)
+declare double @js_fs_stat_sync(double)
+declare double @js_fs_stat_sync_options(double, double)
+declare double @js_fs_lstat_sync(double)
+declare double @js_fs_lstat_sync_options(double, double)
+declare i32 @js_fs_rename_sync(double, double)
+declare i32 @js_fs_copy_file_sync(double, double)
+declare i32 @js_fs_copy_file_sync_flags(double, double, double)
+declare i32 @js_fs_cp_sync(double, double)
+declare i32 @js_fs_cp_sync_options(double, double, double)
+declare i32 @js_fs_chmod_sync(double, double)
+declare i32 @js_fs_chown_sync(double, double, double)
+declare i32 @js_fs_lchown_sync(double, double, double)
+declare i32 @js_fs_lchmod_sync(double, double)
+declare i32 @js_fs_truncate_sync(double, double)
+declare i32 @js_fs_ftruncate_sync(double, double)
+declare i32 @js_fs_fsync_sync(double)
+declare i32 @js_fs_fdatasync_sync(double)
+declare i32 @js_fs_fchmod_sync(double, double)
+declare i32 @js_fs_fchown_sync(double, double, double)
+declare double @js_fs_fstat_sync(double)
+declare double @js_fs_fstat_sync_options(double, double)
+declare i32 @js_fs_utimes_sync(double, double, double)
+declare i32 @js_fs_lutimes_sync(double, double, double)
+declare i32 @js_fs_futimes_sync(double, double, double)
+declare double @js_fs_readv_sync(double, double, double)
+declare double @js_fs_writev_sync(double, double, double)
+declare double @js_fs_statfs_sync(double)
+declare double @js_fs_statfs_sync_options(double, double)
+declare double @js_fs_opendir_sync(double)
+declare double @js_fs_glob_sync(double)
+declare double @js_fs_glob_sync_options(double, double)
+declare i32 @js_fs_link_sync(double, double)
+declare i32 @js_fs_symlink_sync(double, double)
+declare double @js_fs_symlink_callback(double, double, double, double)
+declare i64 @js_fs_readlink_sync(double)
+declare i64 @js_fs_readlink_sync_options(double, double)
+declare double @js_fs_readlink_dispatch(double, double)
+declare double @js_fs_open_sync(double, double)
+declare i32 @js_fs_close_sync(double)
+declare double @js_fs_read_sync(double, double, double, double, double)
+declare double @js_fs_read_sync_options(double, double, double)
+declare double @js_fs_write_sync(double, double)
+declare double @js_fs_write_string_sync_options(double, double, double)
+declare double @js_fs_write_buffer_sync(double, double, double, double, double)
+declare double @js_fs_write_sync_options_dispatch(double, double, double)
+declare i32 @js_fs_access_sync(double)
+declare i32 @js_fs_access_sync_mode(double, double)
+declare double @js_fs_access_sync_throw(double)
+declare double @js_fs_access_sync_throw_mode(double, double)
+declare i64 @js_fs_realpath_sync(double)
+declare double @js_fs_realpath_dispatch(double, double)
+declare i64 @js_fs_mkdtemp_sync(double)
+declare i64 @js_fs_mkdtemp_sync_options(double, double)
+declare double @js_fs_mkdtemp_dispatch(double, double)
+declare double @js_fs_mkdtemp_disposable_sync(double, double)
+declare i32 @js_fs_rmdir_sync(double)
+declare i32 @js_fs_rmdir_sync_options(double, double)
+declare i32 @js_fs_rm_recursive(double)
+declare i32 @js_fs_rm_recursive_options(double, double)
+declare double @js_fs_create_write_stream(double, double)
+declare double @js_fs_create_read_stream(double, double)
+declare double @js_fs_utf8_stream_new(double)
+declare double @js_fs_utf8_stream_call_without_new(double)
+declare double @js_fs_utf8_stream_write(double, double)
+declare double @js_fs_utf8_stream_flush(double, double)
+declare double @js_fs_utf8_stream_flush_sync(double)
+declare double @js_fs_utf8_stream_end(double, double)
+declare double @js_fs_utf8_stream_destroy(double)
+declare double @js_fs_utf8_stream_reopen(double, double)
+declare double @js_fs_utf8_stream_on(double, double, double)
+declare double @js_fs_utf8_stream_once(double, double, double)
+declare double @js_fs_utf8_stream_off(double, double, double)
+declare double @js_fs_utf8_stream_remove_all(double, double)
+declare double @js_fs_utf8_stream_listener_count(double, double)
+declare double @js_fs_utf8_stream_emit(double, double, double)
+declare double @js_fs_read_file_callback(double, double, double)
+declare double @js_fs_stats_is_file(double)
+declare double @js_fs_stats_is_directory(double)
+declare i64 @js_fs_read_file_binary(double)
+declare double @js_number_coerce(double)
+declare double @js_math_to_number(double)
+declare i64 @js_set_add(i64, double)
+declare i64 @js_set_add_string(i64, i64)
+declare i64 @js_set_add_number(i64, double)
+declare i64 @js_set_add_i32(i64, i32)
+declare i64 @js_set_add_u32(i64, i32)
+declare i64 @js_set_add_f32(i64, float)
+declare i64 @js_set_add_bool(i64, i32)
+declare i32 @js_set_has(i64, double)
+declare i32 @js_set_has_string(i64, i64)
+declare i32 @js_set_has_number(i64, double)
+declare i32 @js_set_has_i32(i64, i32)
+declare i32 @js_set_has_u32(i64, i32)
+declare i32 @js_set_has_f32(i64, float)
+declare i32 @js_set_has_bool(i64, i32)
+declare i32 @js_set_delete(i64, double)
+declare i32 @js_set_delete_string(i64, i64)
+declare i32 @js_set_delete_number(i64, double)
+declare i32 @js_set_delete_i32(i64, i32)
+declare i32 @js_set_delete_u32(i64, i32)
+declare i32 @js_set_delete_f32(i64, float)
+declare i32 @js_set_delete_bool(i64, i32)
+declare i32 @js_set_size(i64)
+declare i64 @js_set_union(i64, double)
+declare i64 @js_set_intersection(i64, double)
+declare i64 @js_set_difference(i64, double)
+declare i64 @js_set_symmetric_difference(i64, double)
+declare i32 @js_set_is_subset_of(i64, double)
+declare i32 @js_set_is_superset_of(i64, double)
+declare i32 @js_set_is_disjoint_from(i64, double)
+declare i64 @js_string_to_lower_case(i64)
+declare i64 @js_string_to_upper_case(i64)
+declare i64 @js_string_to_locale_lower_case(i64, double)
+declare i64 @js_string_to_locale_upper_case(i64, double)
+declare void @js_string_validate_collator_args(double, double)
+declare i64 @js_string_trim(i64)
+declare i64 @js_string_trim_start(i64)
+declare i64 @js_string_trim_end(i64)
+declare i64 @js_string_big(i64)
+declare i64 @js_string_blink(i64)
+declare i64 @js_string_bold(i64)
+declare i64 @js_string_fixed(i64)
+declare i64 @js_string_italics(i64)
+declare i64 @js_string_small(i64)
+declare i64 @js_string_strike(i64)
+declare i64 @js_string_sub(i64)
+declare i64 @js_string_sup(i64)
+declare i64 @js_string_anchor(i64, i64)
+declare i64 @js_string_link(i64, i64)
+declare i64 @js_string_fontcolor(i64, i64)
+declare i64 @js_string_fontsize(i64, i64)
+declare i64 @js_string_char_at(i64, i32)
+declare double @js_string_index_get(i64, double)
+declare double @js_string_index_get_boxed(double, double)
+declare i32 @js_string_index_to_i32(double)
+declare i32 @js_string_end_index_to_i32(double, i32)
+declare double @js_dyn_index_get(double, double)
+declare double @js_dyn_index_set(double, double, double)
+declare i64 @js_string_to_char_array(i64)
+declare i64 @js_string_repeat(i64, double)
+declare i64 @js_string_replace_string(i64, i64, i64)
+declare i64 @js_string_replace_all_string(i64, i64, i64)
+declare i32 @js_string_equals(i64, i64)
+declare i32 @js_string_compare(i64, i64)
+declare i32 @js_jsvalue_equals(double, double)
+declare i32 @js_string_compare_value(double, double)
+declare i64 @js_jsvalue_to_string_radix(double, double)
+declare double @js_math_random()
+declare double @js_webassembly_validate(double)
+declare double @js_webassembly_compile(double)
+declare double @js_webassembly_module_new(double)
+declare double @js_webassembly_module_exports(double)
+declare double @js_webassembly_module_imports(double)
+declare double @js_webassembly_module_custom_sections(double, double)
+declare double @js_webassembly_instantiate(double, double)
+declare double @js_wasi_emit_warning()
+declare double @js_webassembly_call_export_0(double, double)
+declare double @js_webassembly_call_export_1(double, double, double)
+declare double @js_webassembly_call_export_2(double, double, double, double)
+declare double @js_webassembly_call_export_3(double, double, double, double, double)
+declare double @js_webassembly_call_export_4(double, double, double, double, double, double)
+declare void @js_console_log_spread(i64)
+declare void @js_console_info_spread(i64)
+declare void @js_console_debug_spread(i64)
+declare void @js_console_error_spread(i64)
+declare void @js_console_warn_spread(i64)
+declare double @js_util_format(i64)
+declare double @js_util_format_with_options(double, i64)
+declare double @js_util_inspect(double, double)
+declare double @js_util_debuglog(double, double)
+declare double @js_util_diff(double, double)
+declare double @js_util_inherits(double, double)
+declare double @js_util_is_deep_strict_equal(double, double)
+declare double @js_util_strip_vt_control_characters(double)
+declare double @js_util_style_text(double, double, double)
+declare double @js_util_get_call_sites(double, double)
+declare double @js_util_promisify(double)
+declare double @js_util_callbackify(double)
+declare double @js_util_deprecate(double, double, double)
+declare double @js_util_aborted(double, double)
+declare double @js_util_transferable_abort_controller()
+declare double @js_util_transferable_abort_signal(double)
+declare double @js_util_parse_args(double)
+declare double @js_boxed_number_new(double)
+declare double @js_boxed_string_new(double, i32)
+declare double @js_boxed_boolean_new(double)
+declare double @js_util_types_is_arguments_object(double)
+declare double @js_util_types_is_promise(double)
+declare double @js_util_types_is_big_int_object(double)
+declare double @js_util_types_is_symbol_object(double)
+declare double @js_util_types_is_array_buffer(double)
+declare double @js_util_types_is_shared_array_buffer(double)
+declare double @js_util_types_is_any_array_buffer(double)
+declare double @js_util_types_is_array_buffer_view(double)
+declare double @js_util_types_is_data_view(double)
+declare double @js_util_types_is_typed_array(double)
+declare double @js_util_types_is_uint8_array(double)
+declare double @js_util_types_is_int8_array(double)
+declare double @js_util_types_is_int16_array(double)
+declare double @js_util_types_is_uint16_array(double)
+declare double @js_util_types_is_int32_array(double)
+declare double @js_util_types_is_uint32_array(double)
+declare double @js_util_types_is_float16_array(double)
+declare double @js_util_types_is_float32_array(double)
+declare double @js_util_types_is_float64_array(double)
+declare double @js_util_types_is_uint8_clamped_array(double)
+declare double @js_util_types_is_big_int64_array(double)
+declare double @js_util_types_is_big_uint64_array(double)
+declare double @js_util_types_is_map(double)
+declare double @js_util_types_is_weak_map(double)
+declare double @js_util_types_is_set(double)
+declare double @js_util_types_is_weak_set(double)
+declare double @js_util_types_is_date(double)
+declare double @js_util_types_is_reg_exp(double)
+declare double @js_util_types_is_async_function(double)
+declare double @js_util_types_is_generator_function(double)
+declare double @js_util_types_is_generator_object(double)
+declare double @js_util_types_is_native_error(double)
+declare double @js_util_types_is_number_object(double)
+declare double @js_util_types_is_string_object(double)
+declare double @js_util_types_is_boolean_object(double)
+declare double @js_util_types_is_boxed_primitive(double)
+declare double @js_util_types_is_external(double)
+declare double @js_util_types_is_module_namespace_object(double)
+declare double @js_util_types_is_key_object(double)
+declare double @js_util_types_is_crypto_key(double)
+declare double @js_util_types_is_proxy(double)
+declare double @js_util_types_is_map_iterator(double)
+declare double @js_util_types_is_set_iterator(double)
+declare double @js_data_view_new(double, double, double)
+declare double @js_data_view_get_direct(double, double, double, i32, i32)
+declare double @js_data_view_set_direct(double, double, double, double, i32, i32)
+declare i64 @js_getenv(i64)
+declare double @js_getenv_value(i64)
+declare void @js_setenv(i64, double)
+declare void @js_removeenv(i64)
+declare double @js_process_exit_code_get()
+declare double @js_process_exit_code_set(double)
+declare void @js_console_table(double)
+declare void @js_console_table_with_properties(double, double)
+declare void @js_console_trace(double)
+declare void @js_console_trace_spread(i64)
+declare i64 @js_process_cwd()
+declare i64 @js_process_argv()
+declare double @js_process_pid()
+declare double @js_process_ppid()
+declare double @js_process_uptime()
+declare i64 @js_process_version()
+declare double @js_process_versions()
+declare double @js_process_memory_usage()
+declare double @js_bigint_as_int_n_call(double, double)
+declare double @js_bigint_as_uint_n_call(double, double)
+declare double @js_v8_serialize(double)
+declare double @js_v8_deserialize(double)
+declare double @js_v8_get_heap_statistics()
+declare double @js_v8_get_heap_code_statistics()
+declare double @js_v8_get_heap_space_statistics()
+declare double @js_v8_cached_data_version_tag()
+declare double @js_v8_get_heap_snapshot(double)
+declare double @js_v8_write_heap_snapshot(double, double)
+declare double @js_v8_gc_profiler_new()
+declare double @js_v8_gc_profiler_start(double)
+declare double @js_v8_gc_profiler_stop(double)
+declare double @js_v8_gc_profiler_report()
+declare double @js_v8_serializer_new(double)
+declare double @js_v8_deserializer_new(double)
+declare double @js_v8_noop_undefined()
+declare double @js_v8_is_building_snapshot()
+declare double @js_v8_namespace(ptr, i64)
+declare double @js_v8_throw_not_building_snapshot()
+declare double @js_v8_promise_hook_register()
+declare double @js_v8_promise_hooks_on_init(double)
+declare double @js_v8_promise_hooks_on_before(double)
+declare double @js_v8_promise_hooks_on_after(double)
+declare double @js_v8_promise_hooks_on_settled(double)
+declare double @js_v8_promise_hooks_create_hook(double)
+declare double @js_process_thread_cpu_usage(double)
+declare double @js_process_available_memory()
+declare double @js_process_constrained_memory()
+declare double @js_process_source_maps_enabled()
+declare double @js_process_set_source_maps_enabled(double)
+declare double @js_process_has_uncaught_exception_capture_callback()
+declare double @js_process_set_uncaught_exception_capture_callback(double)
+declare double @js_process_add_uncaught_exception_capture_callback(double)
+declare double @js_process_getuid()
+declare double @js_process_geteuid()
+declare double @js_process_getgid()
+declare double @js_process_getegid()
+declare void @js_process_emit_warning(double, double, double)
+declare double @js_process_cpu_usage(double)
+declare double @js_process_resource_usage()
+declare double @js_process_active_resources_info()
+declare double @js_process_env()
+declare double @js_process_hrtime_bigint()
+declare double @js_process_hrtime(double)
+declare double @js_process_title()
+declare void @js_process_set_title(double)
+declare void @js_process_chdir(i64)
+declare void @js_process_chdir_jsv(double)
+declare double @js_process_kill(double, double)
+declare void @js_process_exit(double)
+declare void @js_process_abort()
+declare double @js_process_umask()
+declare double @js_process_umask_set(double)
+declare double @js_process_on(i64, i64)
+declare double @js_process_add_listener(i64, i64)
+declare double @js_process_once(i64, i64)
+declare double @js_process_prepend_listener(i64, i64)
+declare double @js_process_prepend_once_listener(i64, i64)
+declare double @js_process_emit(i64, i64)
+declare void @js_process_emit_before_exit(double)
+declare void @js_process_run_finalization_exit()
+declare void @js_trace_events_flush_output()
+declare void @js_promise_report_unhandled_rejections()
+declare i32 @js_process_pending_exit_code()
+declare void @js_gc_release_current_thread_collection_side_allocations()
+declare double @js_process_remove_listener(i64, i64)
+declare double @js_process_off(i64, i64)
+declare double @js_process_remove_all_listeners(i64)
+declare double @js_process_listener_count(i64, i64)
+declare i64 @js_process_listeners(i64)
+declare i64 @js_process_raw_listeners(i64)
+declare i64 @js_process_event_names()
+declare double @js_process_set_max_listeners(double)
+declare double @js_process_get_max_listeners()
+declare double @js_process_get_builtin_module(double)
+declare double @js_process_get_builtin_module_devirt(double)
+declare double @js_process_execve(double, double, double)
+declare double @js_module_is_builtin(double)
+declare double @js_module_find_package_json(double, double)
+declare double @js_module_register(double, double, double)
+declare double @js_module_register_hooks(double)
+declare void @js_process_next_tick(i64, i64)
+declare double @js_process_stdin()
+declare double @js_process_stdout()
+declare double @js_process_stderr()
+declare double @js_readline_set_raw_mode(double)
+declare void @js_readline_stdin_on(i64, i64)
+declare double @js_readline_stdin_remove_listener(i64, i64)
+declare double @js_readline_stdin_pause()
+declare double @js_readline_stdin_resume()
+declare double @js_readline_stdin_unref()
+declare double @js_readline_stdin_ref()
+declare double @js_readline_stdin_destroy()
+declare double @js_tty_isatty(double)
+declare double @js_tty_read_stream_new(double)
+declare double @js_tty_write_stream_new(double)
+declare double @js_wasi_constructor_call(double)
+declare double @js_process_stdin_isatty()
+declare double @js_process_stdout_isatty()
+declare double @js_process_stderr_isatty()
+declare double @js_process_stdout_columns()
+declare double @js_process_stdout_rows()
+declare double @js_process_stdout_on(i64, i64)
+declare i64 @js_os_platform()
+declare i64 @js_os_arch()
+declare i64 @js_os_type()
+declare i64 @js_os_release()
+declare i64 @js_os_hostname()
+declare i64 @js_os_eol()
+declare double @js_os_available_parallelism()
+declare i64 @js_os_endianness()
+declare i64 @js_os_dev_null()
+declare i64 @js_os_machine()
+declare i64 @js_os_loadavg()
+declare i64 @js_os_version()
+declare i64 @js_box_alloc_bits(i64)
+declare i64 @js_box_get_bits(i64)
+declare void @js_box_set_bits(i64, i64)
+declare i64 @js_box_alloc(double)
+declare double @js_box_get(i64)
+declare void @js_box_set(i64, double)
+declare i64 @js_i32_box_alloc(i32)
+declare i32 @js_i32_box_get(i64)
+declare void @js_i32_box_set(i64, i32)
+declare i64 @js_bool_box_alloc(i32)
+declare i32 @js_bool_box_get(i64)
+declare void @js_bool_box_set(i64, i32)
+declare i64 @js_arguments_object_alloc(double, double, i32)
+declare void @js_arguments_object_map_index(i64, i32, i64)
+declare i64 @js_array_like_to_array(double)
+declare i32 @js_object_get_class_id(i64)
+declare i64 @js_object_alloc_with_parent(i32, i32, i32)
+declare i64 @js_object_alloc_class_with_keys(i32, i32, i32, ptr, i32)
+declare i64 @js_object_alloc_class_dynamic_parent(i32, i32, ptr, i32)
+declare i64 @js_object_alloc_class_inline_keys(i32, i32, i32, i64)
+declare i64 @js_build_class_keys_array(i32, i32, ptr, i32)
+declare ptr @js_inline_arena_state()
+declare ptr @js_inline_arena_slow_alloc(ptr, i64, i64)
+declare i32 @js_object_delete_field(i64, i64)
+declare i32 @js_object_delete_field_value(double, i64)
+declare i32 @js_object_delete_dynamic_value(double, double)
+declare double @js_delete_result(i32, i32)
+declare i64 @js_eq(i64, i64)
+declare i64 @js_loose_eq(i64, i64)
+declare i64 @js_number_to_fixed(double, double)
+declare i64 @js_string_replace_regex(i64, i64, i64)
+declare i64 @js_string_replace_all_regex(i64, i64, i64)
+declare double @js_array_at(i64, double)
+declare double @js_date_get_time(double)
+declare double @js_date_get_full_year(double)
+declare double @js_date_get_month(double)
+declare double @js_date_get_date(double)
+declare double @js_date_get_day(double)
+declare double @js_date_get_hours(double)
+declare double @js_date_get_minutes(double)
+declare double @js_date_get_seconds(double)
+declare double @js_date_get_milliseconds(double)
+declare double @js_date_get_utc_day(double)
+declare double @js_date_get_utc_full_year(double)
+declare double @js_date_get_utc_month(double)
+declare double @js_date_get_utc_date(double)
+declare double @js_date_get_utc_hours(double)
+declare double @js_date_get_utc_minutes(double)
+declare double @js_date_get_utc_seconds(double)
+declare double @js_date_get_utc_milliseconds(double)
+declare double @js_date_value_of(double)
+declare double @js_date_get_timezone_offset(double)
+declare double @js_date_coerce_number(double)
+declare double @js_rel_lt(double, double)
+declare double @js_rel_le(double, double)
+declare double @js_rel_gt(double, double)
+declare double @js_rel_ge(double, double)
+declare i64 @js_date_to_string(double)
+declare i64 @js_date_to_iso_string(double)
+declare i64 @js_date_to_iso_string_or_throw(double)
+declare double @js_date_new_from_timestamp(double)
+declare double @js_date_new_from_value(double)
+declare i32 @js_array_indexOf_f64(i64, double)
+declare i64 @js_array_indexOf_jsvalue(i64, double, double, i32)
+declare i64 @js_array_last_index_of_jsvalue(i64, double, double, i32)
+declare i32 @js_array_includes_f64(i64, double)
+declare i32 @js_array_includes_jsvalue(i64, double, double, i32)
+declare i32 @js_map_size(i64)
+declare void @js_map_clear(i64)
+declare void @js_set_clear(i64)
+declare i64 @js_map_entries(i64)
+declare i64 @js_map_keys(i64)
+declare i64 @js_map_values(i64)
+declare double @js_map_entry_key_at(i64, i32)
+declare double @js_map_entry_value_at(i64, i32)
+declare double @js_map_find_key_index(double, double)
+declare double @js_set_find_value_index(double, double)
+declare void @js_map_foreach(i64, double, double)
+declare void @js_set_foreach(i64, double, double)
+declare i64 @js_map_entries_iter_obj(i64)
+declare i64 @js_map_keys_iter_obj(i64)
+declare i64 @js_map_values_iter_obj(i64)
+declare i64 @js_set_values_iter_obj(i64)
+declare i64 @js_set_keys_iter_obj(i64)
+declare i64 @js_set_entries_iter_obj(i64)
+declare i64 @js_set_to_array(i64)
+declare double @js_set_value_at(i64, i32)
+declare i64 @js_array_splice(i64, i32, i32, ptr, i32, ptr)
+declare i32 @js_array_splice_delete_count(double)
+declare double @js_parse_int(i64, double)
+declare double @js_parse_float(i64)
+declare double @js_array_reduce(i64, i64, i32, double)
+declare double @js_array_reduce_right(i64, i64, i32, double)
+declare i64 @js_array_sort_default(i64)
+declare i64 @js_array_reverse(i64)
+declare double @js_array_reverse_value(double)
+declare i64 @js_array_flat(i64)
+declare i64 @js_array_flat_depth(i64, double)
+declare i64 @js_array_flatMap(i64, i64)
+declare i64 @js_array_sort_with_comparator(i64, i64)
+declare i64 @js_validate_array_comparator(double)
+declare i64 @js_validate_array_callback(double)
+declare i64 @js_validate_array_map_callback(i64, double)
+declare i64 @js_array_to_reversed(i64)
+declare i64 @js_array_to_sorted_default(i64)
+declare i64 @js_array_to_sorted_with_comparator(i64, i64)
+declare i64 @js_array_to_spliced(i64, double, double, ptr, i32)
+declare i64 @js_array_with(i64, double, double)
+declare i64 @js_array_copy_within(i64, double, double, i32, double)
+declare double @js_array_copy_within_value(double, double, double, i32, double)
+declare i64 @js_regexp_new(i64, i64)
+declare i64 @js_regexp_construct(double, double)
+declare i64 @js_regexp_construct_call(double, double)
+declare i32 @js_regexp_test(i64, i64)
+declare double @js_regexp_escape(double)
+declare i64 @js_get_string_pointer_unified(double)
+declare i32 @js_switch_strict_equals(double, double)
+declare i64 @js_value_to_str_ptr_for_ffi(double)
+declare void @js_string_addref(i64)
+declare void @js_string_addref_if_heap_string(double)
+declare i64 @js_bigint_from_string(ptr, i32)
+declare i64 @js_bigint_from_f64(double)
+declare i64 @js_bigint_from_i128_parts(i64, i64)
+declare i32 @js_bigint_cmp(i64, i64)
+declare double @js_dynamic_add(double, double)
+declare double @js_to_numeric(double)
+declare double @js_numeric_step(double, i32)
+declare double @js_dynamic_string_or_number_add(double, double)
+declare double @js_dynamic_sub(double, double)
+declare double @js_dynamic_mul(double, double)
+declare double @js_dynamic_div(double, double)
+declare double @js_dynamic_mod(double, double)
+declare double @js_dynamic_bitand(double, double)
+declare double @js_dynamic_bitor(double, double)
+declare double @js_dynamic_bitxor(double, double)
+declare double @js_dynamic_shl(double, double)
+declare double @js_dynamic_shr(double, double)
+declare double @js_dynamic_bitnot(double)
+declare double @js_dynamic_pow(double, double)
+declare double @js_dynamic_ushr(double, double)
+declare double @js_instanceof(double, i32)
+declare double @js_instanceof_dynamic(double, double)
+declare double @js_instanceof_noncallable_rhs()
+declare void @js_register_class_extends_error(i32)
+declare void @js_register_class_extends_data_view(i32)
+declare void @js_register_class_id(i32)
+declare void @js_register_class_name(i32, ptr, i32)
+declare void @js_register_anon_shape_class_id(i32)
+declare double @js_get_global_this_builtin_value(ptr, i64)
+declare double @js_promise_static_function_value(ptr, i64)
+declare double @js_builtin_prototype_method_value(ptr, i64, ptr, i64)
+declare void @js_register_class_parent(i32, i32)
+declare void @js_register_class_parent_dynamic(i32, double)
+declare double @js_get_dynamic_parent_value(i32)
+declare void @js_class_register_capture_values(i32, ptr, i64)
+declare void @js_class_object_refresh_capture_values(double, i64, double)
+declare void @js_tdz_suppress_begin()
+declare void @js_tdz_suppress_end()
+declare double @js_class_capture_value(i32, i32)
+declare double @js_class_capture_value_for_receiver(double, i32, i32)
+declare double @js_class_capture_value_or(i32, i32, double)
+declare double @js_param_or_class_capture_value(double, i32, i32)
+declare void @js_super_construct_apply(i32, double, double)
+declare double @js_super_method_call_dynamic(i32, ptr, i64, double, ptr, i64)
+declare double @js_super_method_call_dynamic_apply(i32, ptr, i64, double, double)
+declare i64 @js_array_push_spread_any(i64, double)
+declare i32 @js_set_function_prototype(double, double)
+declare void @js_register_prototype_method(i32, ptr, i64, double)
+declare i32 @js_register_function_prototype_method(double, ptr, i64, double)
+declare double @js_new_function_construct(double, ptr, i64)
+declare double @js_function_ctor_from_strings(ptr, i64)
+declare double @js_new_function_construct_apply(double, double)
+declare double @js_throw_not_a_constructor()
+declare double @js_new_target_value()
+declare double @js_get_function_prototype_method(double, ptr, i64)
+declare double @js_function_prototype_value_for_read(double)
+declare i64 @js_typeerror_new(i64)
+declare i64 @js_rangeerror_new(i64)
+declare i64 @js_syntaxerror_new(i64)
+declare i64 @js_referenceerror_new(i64)
+declare double @js_throw_symbol_constructor_type_error()
+declare double @js_throw_bigint_constructor_type_error()
+declare double @js_throw_strict_eval_arguments_syntax_error()
+declare double @js_throw_eval_syntax_error(double)
+declare double @js_throw_restricted_function_property_assignment()
+declare double @js_throw_math_constructor_type_error()
+declare double @js_throw_json_constructor_type_error()
+declare double @js_webcrypto_illegal_constructor()
+declare double @js_throw_type_error_const_assignment(double)
+declare double @js_throw_reference_error_unresolvable_assignment(double)
+declare double @js_throw_reference_error_unresolved_get()
+declare double @js_with_implicit_unset()
+declare double @js_with_implicit_read(double, double)
+declare double @js_iterator_result_validate(double)
+declare double @js_global_get_or_throw_unresolved(double)
+declare double @js_module_ambient_require()
+declare double @js_module_ambient_require_apply(double)
+declare double @js_module_dynamic_import_fallback(double)
+declare double @js_module_dynamic_import_deferred(double, double)
+declare double @js_module_create_require_devirt(double)
+declare double @js_global_get_optional(double)
+declare double @js_global_update(double, double, double)
+declare double @js_global_assign_existing_or_throw(double, double)
+declare double @js_throw_reference_error_this_before_super()
+declare double @js_throw_reference_error_super_delete()
+declare double @js_throw_reference_error_unresolved_assignment()
+declare i64 @js_evalerror_new(i64)
+declare i64 @js_urierror_new(i64)
+declare i64 @js_weakmap_new()
+declare i64 @js_weakset_new()
+declare double @js_weakmap_init_iterable(double, double)
+declare double @js_weakset_init_iterable(double, double)
+declare double @js_weakmap_set(double, double, double)
+declare double @js_weakmap_get(double, double)
+declare double @js_weakmap_has(double, double)
+declare double @js_weakmap_delete(double, double)
+declare double @js_weakset_add(double, double)
+declare double @js_weakset_has(double, double)
+declare double @js_weakset_delete(double, double)
+declare double @js_weak_throw_primitive()
+declare i64 @js_buffer_from_string(i64, i32)
+declare i32 @js_encoding_tag_from_value(double)
+declare i64 @js_value_to_string_with_encoding(double, i32)
+declare i64 @js_value_to_string_with_encoding_or_radix(double, i32, double)
+declare i64 @js_object_values(i64)
+declare i64 @js_object_values_value(double)
+declare i64 @js_object_entries(i64)
+declare i64 @js_object_entries_value(double)
+declare i64 @js_path_join(i64, i64)
+declare i64 @js_path_win32_join(i64, i64)
+declare i64 @js_path_win32_dirname(i64)
+declare i64 @js_path_win32_basename(i64)
+declare i64 @js_path_win32_basename_ext(i64, i64)
+declare i64 @js_path_win32_extname(i64)
+declare i32 @js_path_win32_is_absolute(i64)
+declare i64 @js_path_win32_normalize(i64)
+declare i64 @js_path_win32_parse(i64)
+declare i64 @js_path_win32_format(double)
+declare i64 @js_path_win32_relative(i64, i64)
+declare i64 @js_path_win32_relative_checked(double, double)
+declare i64 @js_path_win32_resolve(i64)
+declare i64 @js_path_win32_resolve_join(i64, i64)
+declare i64 @js_path_win32_to_namespaced_path(i64)
+declare double @js_path_win32_to_namespaced_path_value(double)
+declare i32 @js_path_win32_matches_glob(i64, i64)
+declare i64 @js_path_win32_sep_get()
+declare i64 @js_path_win32_delimiter_get()
+declare i64 @js_path_dirname(i64)
+declare i64 @js_path_resolve(i64)
+declare i64 @js_path_relative(i64, i64)
+declare i64 @js_path_relative_checked(double, double)
+declare i64 @js_path_to_namespaced_path(i64)
+declare double @js_path_to_namespaced_path_value(double)
+declare i32 @js_path_matches_glob(i64, i64)
+declare i64 @js_path_resolve_join(i64, i64)
+declare double @js_object_from_entries(double)
+declare i64 @js_string_match(i64, i64)
+declare i64 @js_string_match_all(i64, i64)
+declare i64 @js_string_match_all_value(i64, double)
+declare double @llvm.log.f64(double)
+declare double @llvm.log2.f64(double)
+declare double @llvm.log10.f64(double)
+declare double @llvm.exp.f64(double)
+declare double @llvm.sin.f64(double)
+declare double @llvm.cos.f64(double)
+declare i64 @js_path_basename(i64)
+declare i64 @js_path_basename_ext(i64, i64)
+declare i64 @js_path_extname(i64)
+declare i64 @js_path_sep_get()
+declare i64 @js_path_delimiter_get()
+declare i64 @js_path_parse(i64)
+declare i64 @js_json_parse(i64)
+declare i64 @js_json_text_to_string(double)
+declare double @js_json_raw_json(double)
+declare double @js_json_is_raw_json(double)
+declare i64 @js_json_parse_or_null(i64)
+declare i64 @js_json_parse_typed_array(i64, i64, i32, i32)
+declare i64 @js_date_to_date_string(double)
+declare i64 @js_date_to_time_string(double)
+declare i64 @js_date_to_utc_string(double)
+declare i64 @js_date_to_locale_date_string(double)
+declare i64 @js_date_to_locale_time_string(double)
+declare i64 @js_date_to_json(double)
+declare i64 @js_regexp_exec(i64, i64)
+declare i64 @js_number_to_precision(double, double)
+declare i64 @js_number_to_exponential(double, double)
+declare double @js_date_new()
+declare double @js_number_is_integer(double)
+declare double @js_number_is_nan(double)
+declare double @js_number_is_safe_integer(double)
+declare double @js_date_parse(i64)
+declare double @js_date_utc(ptr, i32)
+declare double @js_date_new_local_components(double, double, double, double, double, double, double)
+declare double @js_date_apply_setter(double, i32, i32, ptr, i32)
+declare double @js_math_clz32(double)
+declare double @js_math_cbrt(double)
+declare double @js_math_fround(double)
+declare double @js_math_f16round(double)
+declare double @js_math_sinh(double)
+declare double @js_math_cosh(double)
+declare double @js_math_tanh(double)
+declare double @js_math_asinh(double)
+declare double @js_math_acosh(double)
+declare double @js_math_atanh(double)
+declare double @js_math_hypot(double, double)
+declare double @js_object_is(double, double)
+declare i64 @js_path_normalize(i64)
+declare i64 @js_path_format(double)
+declare i32 @js_path_is_absolute(i64)
+declare i64 @js_encode_uri(double)
+declare i64 @js_decode_uri(double)
+declare i64 @js_encode_uri_component(double)
+declare i64 @js_decode_uri_component(double)
+declare i64 @js_text_encoder_new()
+declare i64 @js_text_decoder_new(double, double, double)
+declare i64 @js_text_encoder_encode_llvm(double)
+declare i64 @js_text_decoder_decode_llvm(double, double)
+declare i64 @js_text_decoder_encoding(double)
+declare double @js_text_decoder_fatal(double)
+declare double @js_text_decoder_ignore_bom(double)
+declare void @js_queue_microtask(i64)
+declare void @js_queue_next_tick(i64)
+declare void @js_queue_next_tick_args(i64, ptr, i32)
+declare void @js_drain_queued_microtasks()
+declare i64 @js_uint8array_from_array(i64)
+declare i64 @js_uint8array_alloc(i32)
+declare i64 @js_uint8array_new(double)
+declare i64 @js_uint8array_view(double, double, double)
+declare i64 @js_typed_array_new_empty(i32, i32)
+declare i64 @js_typed_array_new_from_array(i32, i64)
+declare i64 @js_typed_array_new(i32, double)
+declare i64 @js_typed_array_view(i32, double, double, double)
+declare i32 @js_typed_array_length(i64)
+declare double @js_typed_array_get(i64, i32)
+declare i32 @js_typed_array_read_int32(i64, i32)
+declare double @js_typed_array_read_f64(i64, i32)
+declare double @js_typed_array_index_get_dynamic(i64, double)
+declare double @js_typed_array_at(i64, double)
+declare void @js_typed_array_set(i64, i32, double)
+declare double @js_typed_array_index_set_dynamic(i64, double, double)
+declare i32 @js_uint8array_get(i64, i32)
+declare double @js_uint8array_index_get_value(i64, i32)
+declare void @js_uint8array_set(i64, i32, i32)
+declare i64 @js_native_arena_alloc(i64)
+declare i64 @js_native_arena_view(i64, i32, i64, i64)
+declare i64 @js_native_pod_view(i64, i64, i64, i64, i64, i64)
+declare ptr @js_native_abi_check_pod_view_data_ptr(double, i64)
+declare i64 @js_native_abi_check_pod_view_record_count(double, i64)
+declare void @js_native_arena_dispose(i64)
+declare void @js_native_memory_fill_u32(i64, double)
+declare void @js_native_memory_copy(i64, i64)
+declare i64 @js_typed_array_to_reversed(i64)
+declare i64 @js_typed_array_to_sorted_default(i64)
+declare i64 @js_typed_array_to_sorted_with_comparator(i64, i64)
+declare i64 @js_typed_array_with(i64, double, double)
+declare double @js_typed_array_find_last(i64, i64)
+declare double @js_typed_array_find_last_index(i64, i64)
+declare double @js_typed_array_set_from(i64, double, double)
+declare i64 @js_typed_array_subarray(i64, i32, double, i32, double)
+declare double @js_object_has_own(double, double)
+declare double @js_object_property_is_enumerable(double, double)
+declare double @js_object_define_getter(double, double, double)
+declare double @js_object_define_setter(double, double, double)
+declare double @js_object_lookup_getter(double, double)
+declare double @js_object_lookup_setter(double, double)
+declare double @js_object_get_own_field_or_undef(double, ptr, i64)
+declare double @js_unresolved_namespace_stub()
+declare double @js_node_submodule_export_as_function(ptr, i32, ptr, i32)
+declare double @js_node_submodule_namespace_member(ptr, i32, ptr, i32)
+declare double @js_node_submodule_namespace(ptr, i32)
+declare void @js_node_submod_install_vm()
+declare void @js_node_submod_install_timers()
+declare void @js_node_submod_install_timers_promises()
+declare void @js_node_submod_install_fs_promises()
+declare void @js_node_submod_install_readline_promises()
+declare void @js_node_submod_install_stream_promises()
+declare void @js_node_submod_install_stream_consumers()
+declare void @js_node_submod_install_stream_web()
+declare void @js_node_submod_install_hono_jsx_server()
+declare void @js_node_submod_install_hono_jsx_streaming()
+declare void @js_node_submod_install_sys()
+declare void @js_node_submod_install_diagnostics_channel()
+declare void @js_node_submod_install_trace_events()
+declare void @js_node_submod_install_test()
+declare void @js_node_submod_install_test_reporters()
+declare void @js_node_submod_install_all()
+declare void @js_node_submod_enable_install_all()
+declare double @js_unresolved_default_call()
+declare double @js_get_global_this()
+declare double @js_module_top_this()
+declare double @js_global_or_console_property_by_name(i64)
+declare void @js_class_register_static_symbol(i32, double, double)
+declare void @js_register_class_computed_method(i64, double, i64, i64, i64, i64)
+declare void @js_register_class_computed_accessor(i64, double, i64, i64, i64)
+declare void @js_class_register_static_field(i32, ptr, i64, double)
+declare double @js_object_define_property(double, double, double)
+declare double @js_object_get_own_property_descriptor(double, double)
+declare double @js_object_get_own_property_descriptors(double)
+declare double @js_object_get_own_property_names(double)
+declare double @js_symbol_new(double)
+declare double @js_symbol_new_empty()
+declare double @js_symbol_for(double)
+declare double @js_symbol_computed_member(double, double)
+declare double @js_symbol_key_for(double)
+declare double @js_symbol_description(double)
+declare i64 @js_symbol_to_string(double)
+declare i32 @js_symbol_equals(double, double)
+declare i32 @js_is_symbol(double)
+declare i64 @js_object_get_own_property_symbols(double)
+declare double @js_object_set_symbol_property(double, double, double)
+declare double @js_to_property_key(double)
+declare double @js_object_set_property_key(double, double, double)
+declare double @js_object_get_property_key(double, double)
+declare double @js_object_set_property_key_method(double, double, double)
+declare double @js_object_super_get(double, double, double)
+declare double @js_object_super_put_value_set(double, double, double, double, i32)
+declare double @js_object_super_call(double, double, double, ptr, i64)
+declare double @js_object_literal_infer_computed_function_name(double, double)
+declare double @js_object_get_symbol_property(double, double)
+declare double @js_object_create(double)
+declare double @js_object_create_with_props(double, double)
+declare double @js_object_freeze(double)
+declare double @js_object_seal(double)
+declare double @js_object_prevent_extensions(double)
+declare void @js_object_copy_own_fields(i64, double)
+declare double @js_object_assign_validate_target(double)
+declare double @js_object_assign_one(double, double)
+declare double @js_string_at(i64, i32)
+declare double @js_string_code_point_at(i64, i32)
+declare i64 @js_string_from_code_point(double)
+declare i64 @js_string_raw(double, double)
+declare i64 @js_string_from_char_code(double)
+declare i64 @js_string_from_char_code_array(double)
+declare double @js_string_char_code_at(i64, i32)
+declare i32 @js_string_last_index_of(i64, i64)
+declare i32 @js_string_last_index_of_from(i64, i64, double, i32)
+declare double @js_string_locale_compare(i64, i64)
+declare double @js_string_locale_compare_opts(i64, i64, double)
+declare i64 @js_string_normalize(i64, double)
+declare i64 @js_string_pad_start(i64, double, i64)
+declare i64 @js_string_pad_end(i64, double, i64)
+declare i64 @js_string_pad_fill(double)
+declare double @js_string_is_well_formed(i64)
+declare i64 @js_string_to_well_formed(i64)
+declare i32 @js_string_search_regex(i64, i64)
+declare i32 @js_string_search_value(i64, double)
+declare i64 @js_string_match_value(i64, double)
+declare double @js_regexp_exec_get_index()
+declare i64 @js_regexp_exec_get_groups()
+declare double @js_regexp_get_last_index(i64)
+declare void @js_regexp_set_last_index(i64, double)
+declare i64 @js_regexp_get_source(i64)
+declare i64 @js_regexp_get_flags(i64)
+declare i64 @js_string_replace_regex_named(i64, i64, i64)
+declare i64 @js_string_replace_all_regex_named(i64, i64, i64)
+declare i64 @js_string_replace_string_fn(i64, i64, double)
+declare i64 @js_string_replace_string_dyn(i64, i64, double)
+declare i64 @js_string_replace_all_string_dyn(i64, i64, double)
+declare i64 @js_string_replace_regex_dyn(i64, i64, double)
+declare i64 @js_string_replace_all_regex_dyn(i64, i64, double)
+declare i64 @js_string_replace_search_dyn(i64, double, double)
+declare i64 @js_string_replace_all_search_dyn(i64, double, double)
+declare i64 @js_string_replace_all_string_fn(i64, i64, double)
+declare i64 @js_string_replace_regex_fn(i64, i64, double)
+declare i64 @js_string_replace_all_regex_fn(i64, i64, double)
+declare double @js_structured_clone(double)
+declare double @js_structured_clone_with_options(double, double)
+declare double @js_generator_attach_prototype(double, i32)
+declare double @js_generator_attach_closure_prototype(double, i64)
+declare i64 @js_weakref_new(double)
+declare double @js_weakref_deref(double)
+declare i64 @js_finreg_new(double)
+declare double @js_finreg_register(double, double, double, double)
+declare double @js_finreg_unregister(double, double)
+declare i64 @js_atob(double)
+declare i64 @js_btoa(double)
+declare double @js_object_is_frozen(double)
+declare double @js_object_is_sealed(double)
+declare double @js_object_is_extensible(double)
+declare i64 @js_aggregateerror_new(i64, i64)
+declare i64 @js_error_new_with_cause(i64, double)
+declare i64 @js_aggregateerror_new_full(double, i64, double)
+declare i64 @js_error_new_kind_with_options(i32, i64, double)
+declare double @js_error_is_error(double)
+declare i64 @js_error_get_errors(i64)
+declare i64 @js_crypto_sha256(i64)
+declare i64 @js_crypto_sha256_bytes(i64)
+declare i64 @js_crypto_md5(i64)
+declare i64 @js_crypto_hmac_sha256(i64, i64)
+declare i64 @js_crypto_hmac_sha256_bytes(i64, i64)
+declare void @js_runtime_validate_string_arg(double, ptr, i32)
+declare void @js_set_call_location(ptr, i64, i32)
+declare void @js_runtime_validate_crypto_key_arg(double, ptr, i32)
+declare void @js_runtime_validate_integer_arg(double, ptr, i32, double, double)
+declare i64 @js_crypto_pbkdf2_bytes(i64, i64, double, double, i64)
+declare double @js_crypto_pbkdf2_async_alg(i64, i64, double, double, i64, double)
+declare i64 @js_crypto_argon2_sync(i64, double)
+declare double @js_crypto_argon2_async(i64, double, double)
+declare i64 @js_crypto_encapsulate(double)
+declare double @js_crypto_encapsulate_async(double, double)
+declare i64 @js_crypto_decapsulate(double, double)
+declare double @js_crypto_decapsulate_async(double, double, double)
+declare i64 @js_crypto_hkdf_bytes_alg(i64, i64, i64, i64, double)
+declare double @js_crypto_hkdf_async_alg(i64, i64, i64, i64, double, double)
+declare i64 @js_crypto_scrypt_bytes(i64, i64, double, i64)
+declare double @js_crypto_scrypt_async(i64, i64, double, double)
+declare i64 @js_crypto_sign_rsa_sha256(i64, i64, double)
+declare double @js_crypto_sign_async(i64, i64, double, double)
+declare double @js_crypto_verify_rsa_sha256(i64, i64, double, i64)
+declare double @js_crypto_verify_async(i64, i64, double, i64, double)
+declare i64 @js_crypto_public_encrypt(i64, i64)
+declare i64 @js_crypto_private_decrypt(i64, i64)
+declare i64 @js_crypto_private_encrypt(i64, i64)
+declare i64 @js_crypto_public_decrypt(i64, i64)
+declare i64 @js_crypto_create_public_key(i64)
+declare i64 @js_crypto_create_private_key_value(double)
+declare i64 @js_crypto_create_public_key_value(double)
+declare i64 @js_crypto_generate_key_pair_sync_rsa(double)
+declare i64 @js_crypto_generate_key_pair_sync_ec_p256(double)
+declare i64 @js_crypto_generate_key_pair_sync_ed25519(double)
+declare i64 @js_crypto_generate_key_pair_sync_x25519(double)
+declare double @js_crypto_generate_key_pair_async(i64, double, double)
+declare i64 @js_crypto_diffie_hellman(double)
+declare double @js_crypto_get_cipher_info(double, double)
+declare i64 @js_crypto_get_curves()
+declare i64 @js_crypto_secure_heap_used()
+declare i64 @js_crypto_random_bytes_buffer(double)
+declare double @js_crypto_random_bytes_async(double, double)
+declare i64 @js_crypto_random_uuid(double)
+declare i64 @js_crypto_random_uuidv7()
+declare double @js_crypto_random_int(double, double)
+declare double @js_crypto_random_int_async(double, double, double)
+declare double @js_crypto_timing_safe_equal(double, double)
+declare i64 @js_crypto_get_hashes()
+declare i64 @js_crypto_get_ciphers()
+declare double @js_crypto_generate_prime_sync(double, double)
+declare double @js_crypto_generate_prime_async(double, double, double)
+declare double @js_crypto_check_prime_sync(double, double)
+declare double @js_crypto_check_prime_async(double, double, double)
+declare i64 @js_crypto_create_secret_key(i64, i64)
+declare i64 @js_crypto_generate_key_sync(i64, double)
+declare double @js_crypto_generate_key_async(i64, double, double)
+declare i64 @js_webcrypto_digest(double, double)
+declare i64 @js_webcrypto_import_key(double, double, double, double, double)
+declare i64 @js_webcrypto_export_key(double, double)
+declare i64 @js_webcrypto_sign(double, double, double)
+declare i64 @js_webcrypto_verify(double, double, double, double)
+declare i64 @js_webcrypto_derive_bits(double, double, double)
+declare i64 @js_webcrypto_derive_key(double, double, double, double, double)
+declare i64 @js_webcrypto_encrypt(double, double, double)
+declare i64 @js_webcrypto_decrypt(double, double, double)
+declare i64 @js_webcrypto_generate_key(double, double, double)
+declare i64 @js_webcrypto_wrap_key(double, double, double, double)
+declare i64 @js_webcrypto_unwrap_key(double, double, double, double, double, double, double)
+declare i64 @js_zlib_create_brotli_decompress(double)
+declare double @js_crypto_random_fill_sync(double, double, double)
+declare double @js_crypto_random_fill_async(double, double, double, double)
+declare double @js_crypto_create_hash(i64)
+declare double @js_crypto_create_hash_options(i64, double)
+declare double @js_crypto_x509_new(i64)
+declare double @js_crypto_certificate_verify_spkac(double)
+declare double @js_crypto_certificate_export_public_key(double)
+declare double @js_crypto_certificate_export_challenge(double)
+declare double @js_crypto_create_sign(i64)
+declare double @js_crypto_create_verify(i64)
+declare double @js_crypto_create_ecdh(i64)
+declare double @js_crypto_create_diffie_hellman(double, double, double)
+declare double @js_crypto_get_diffie_hellman(double)
+declare double @js_crypto_ecdh_convert_key(double, double, double, double, double)
+declare double @js_crypto_create_hmac(i64, i64)
+declare i64 @js_buffer_alloc(i32, i32)
+declare i64 @js_buffer_alloc_fill_value(i32, double, i32)
+declare i64 @js_array_buffer_new(i32)
+declare i64 @js_shared_array_buffer_new(i32)
+declare i64 @js_array_buffer_new_value(double)
+declare i64 @js_shared_array_buffer_new_value(double)
+declare i64 @js_json_stringify_full(double, double, double)
+declare i64 @js_json_parse_with_reviver(i64, i64)
+declare double @js_array_find(i64, i64)
+declare i32 @js_array_findIndex(i64, i64)
+declare double @js_array_find_last(i64, i64)
+declare i32 @js_array_find_last_index(i64, i64)
+declare double @js_array_some(i64, i64)
+declare double @js_array_every(i64, i64)
+declare i32 @js_promise_state(i64)
+declare double @js_promise_value(i64)
+declare double @js_promise_reason(i64)
+declare i32 @js_value_is_promise(double)
+declare double @js_assimilate_thenable(double)
+declare i32 @js_promise_run_microtasks()
+declare i32 @js_promise_run_microtasks_event_loop()
+declare i32 @js_promise_run_microtasks_await_loop()
+declare i32 @js_await_loop_tick_timers()
+declare void @js_mark_entry_module_esm()
+declare i32 @js_promise_run_promise_jobs()
+declare void @js_run_stdlib_pump()
+declare void @js_sleep_ms(double)
+declare void @js_wait_for_event()
+declare i32 @js_event_loop_host_driven()
+declare void @js_unsettled_top_level_await_exit()
+declare void @js_throw(double)
+declare ptr @js_try_push()
+declare i32 @_setjmp(ptr) #0
+declare void @js_try_end()
+declare double @js_get_exception()
+declare void @js_clear_exception()
+declare i32 @js_has_exception()
+declare void @js_enter_finally()
+declare void @js_leave_finally()
+declare double @js_await_any_promise(double)
+declare i64 @js_promise_new()
+declare i64 @js_promise_new_with_executor(i64)
+declare i32 @js_timer_tick()
+declare i32 @js_timer_tick_if_refed()
+declare i32 @js_callback_timer_tick()
+declare i32 @js_interval_timer_tick()
+declare i32 @js_timer_has_pending()
+declare i32 @js_callback_timer_has_pending()
+declare i32 @js_interval_timer_has_pending()
+declare i32 @js_stdlib_has_active_handles()
+declare i32 @js_microtasks_pending()
+declare i64 @js_timer_validate_callback(double, i32)
+declare i64 @js_set_timeout_callback(i64, double)
+declare i64 @js_set_timeout_callback_args(i64, double, ptr, i32)
+declare i64 @js_set_immediate_callback(i64)
+declare i64 @js_set_immediate_callback_args(i64, ptr, i32)
+declare i64 @setInterval(i64, double)
+declare i64 @js_set_interval_callback_args(i64, double, ptr, i32)
+declare void @clearTimeout(i64)
+declare void @clearInterval(i64)
+declare void @clearImmediate(i64)
+declare void @js_clear_timeout_value(double)
+declare void @js_clear_interval_value(double)
+declare void @js_clear_immediate_value(double)
+declare i64 @js_buffer_from_array(i64)
+declare i64 @js_buffer_from_arraybuffer_slice(i64, i32, i32)
+declare i32 @js_buffer_length(i64)
+declare i32 @js_buffer_get(i64, i32)
+declare double @js_buffer_index_get_value(i64, i32)
+declare ptr @js_native_buffer_data_ptr(double)
+declare i64 @js_native_buffer_byte_len(double)
+declare void @js_console_time(i64)
+declare void @js_console_time_end(i64)
+declare void @js_console_time_log(i64)
+declare void @js_console_time_value(double)
+declare void @js_console_time_end_value(double)
+declare void @js_console_time_log_value(double)
+declare void @js_console_time_log_spread(double, i64)
+declare void @js_console_count(i64)
+declare void @js_console_count_reset(i64)
+declare void @js_console_count_value(double)
+declare void @js_console_count_reset_value(double)
+declare double @js_console_new(double)
+declare double @js_console_new2(double, double)
+declare void @js_console_group_begin()
+declare void @js_console_group_end()
+declare void @js_console_clear()
+declare void @js_console_noop()
+declare double @js_native_call_method(double, ptr, i64, ptr, i64)
+declare double @js_native_call_method_by_id(double, i64, ptr, i64)
+declare double @js_native_call_method_apply(double, ptr, i64, i64)
+declare double @js_native_call_method_apply_by_id(double, i64, i64)
+declare double @js_native_call_method_str_key(double, i64, ptr, i64)
+declare double @js_native_call_method_value(double, double, ptr, i64)
+declare double @js_native_call_method_value_apply(double, double, i64)
+declare void @js_promise_resolve(i64, double)
+declare void @js_promise_reject(i64, double)
+declare void @js_promise_mark_internally_handled(i64)
+declare i64 @js_promise_resolved(double)
+declare i64 @js_async_fn_result(double)
+declare i64 @js_promise_rejected(double)
+declare double @js_create_namespace(i32, ptr, ptr, ptr)
+declare i64 @js_promise_then(i64, i64, i64)
+declare i64 @js_promise_resolved_then(double, i64, i64)
+declare i64 @js_promise_finally(i64, i64)
+declare double @js_promise_then_checked(double, double, double)
+declare double @js_promise_catch_checked(double, double)
+declare double @js_promise_finally_checked(double, double)
+declare i64 @js_promise_closure_arg(double)
+declare i64 @js_promise_all(i64)
+declare i64 @js_promise_race(i64)
+declare i64 @js_promise_any(i64)
+declare i64 @js_promise_all_settled(i64)
+declare i64 @js_promise_all_iterable(double)
+declare i64 @js_promise_race_iterable(double)
+declare i64 @js_promise_any_iterable(double)
+declare i64 @js_promise_all_settled_iterable(double)
+declare i64 @js_promise_with_resolvers()
+declare i64 @js_promise_try(double, i64)
+declare i64 @js_array_unshift_f64(i64, double)
+declare i64 @js_array_unshift_variadic(i64, ptr, i32)
+declare i64 @js_array_entries(i64)
+declare i64 @js_array_keys(i64)
+declare i64 @js_array_values(i64)
+declare i64 @js_array_entries_iter_obj(i64)
+declare i64 @js_array_keys_iter_obj(i64)
+declare i64 @js_array_values_iter_obj(i64)
+declare double @js_response_new(i64, double, i64, double)
+declare i64 @js_response_body_init_ptr(double)
+declare double @js_headers_new()
+declare double @js_headers_set(double, i64, i64)
+declare double @js_headers_append(double, i64, i64)
+declare i64 @js_headers_get(double, i64)
+declare double @js_headers_get_set_cookie(double)
+declare double @js_headers_has(double, i64)
+declare double @js_headers_delete(double, i64)
+declare double @js_headers_for_each(double, double)
+declare double @js_headers_keys(double)
+declare double @js_headers_values(double)
+declare double @js_headers_entries(double)
+declare double @js_headers_init_from_value(double, double)
+declare double @js_headers_method_value(double, i64, i64)
+declare double @js_request_new(i64, i64, i64, double, i64, i64, i64, i64, i64, i64, i64, double, i64, double)
+declare double @js_request_new_from_init(i64, double)
+declare i64 @js_request_get_url(double)
+declare i64 @js_request_input_to_url(double)
+declare i64 @js_request_get_method(double)
+declare double @js_request_get_body(double)
+declare double @js_request_body_used(double)
+declare i64 @js_request_get_destination(double)
+declare i64 @js_request_get_referrer(double)
+declare i64 @js_request_get_referrer_policy(double)
+declare i64 @js_request_get_mode(double)
+declare i64 @js_request_get_credentials(double)
+declare i64 @js_request_get_cache(double)
+declare i64 @js_request_get_redirect(double)
+declare i64 @js_request_get_integrity(double)
+declare double @js_request_get_keepalive(double)
+declare i64 @js_request_get_duplex(double)
+declare double @js_request_get_signal(double)
+declare double @js_request_get_headers(double)
+declare i64 @js_request_text(double)
+declare i64 @js_request_json(double)
+declare i64 @js_request_array_buffer(double)
+declare i64 @js_request_blob(double)
+declare i64 @js_request_bytes(double)
+declare i64 @js_request_form_data(double)
+declare double @js_request_clone(double)
+declare double @js_fetch_response_status(double)
+declare i64 @js_fetch_response_status_text(double)
+declare double @js_fetch_response_ok(double)
+declare i64 @js_fetch_response_type(double)
+declare i64 @js_fetch_response_url(double)
+declare double @js_fetch_response_redirected(double)
+declare double @js_response_body_used(double)
+declare i64 @js_fetch_response_text(double)
+declare i64 @js_fetch_response_json(double)
+declare double @js_response_get_headers(double)
+declare double @js_response_clone(double)
+declare i64 @js_response_array_buffer(double)
+declare i64 @js_response_blob(double)
+declare i64 @js_response_bytes(double)
+declare i64 @js_response_form_data(double)
+declare double @js_form_data_new()
+declare double @js_form_data_append(double, double, double)
+declare double @js_form_data_set(double, double, double)
+declare double @js_form_data_delete(double, i64)
+declare double @js_form_data_get(double, i64)
+declare double @js_form_data_get_all(double, i64)
+declare double @js_form_data_has(double, i64)
+declare double @js_form_data_entries(double)
+declare double @js_form_data_keys(double)
+declare double @js_form_data_values(double)
+declare double @js_form_data_for_each(double, double)
+declare double @js_blob_size(double)
+declare i64 @js_blob_type(double)
+declare i64 @js_blob_array_buffer(double)
+declare i64 @js_blob_bytes(double)
+declare i64 @js_blob_text(double)
+declare double @js_blob_slice(double, double, double, i64)
+declare double @js_blob_new(double, double)
+declare double @js_file_new(double, double, double, double)
+declare i64 @js_file_name(double)
+declare double @js_file_last_modified(double)
+declare i64 @js_url_create_object_url(double)
+declare void @js_url_revoke_object_url(double)
+declare double @js_buffer_resolve_object_url(double)
+declare double @js_response_static_json(double, double, i64, double)
+declare double @js_response_static_redirect(i64, double)
+declare double @js_response_static_error()
+declare double @js_blob_stream(double)
+declare double @js_response_body(double)
+declare double @js_readable_stream_new(double, double, double, double)
+declare double @js_readable_stream_new_with_source_type(double, double, double, double, double)
+declare double @js_readable_stream_new_with_strategy_and_source_type(double, double, double, double, double)
+declare double @js_readable_stream_new_from_source_object(double, double)
+declare double @js_readable_stream_get_reader(double)
+declare double @js_readable_stream_get_reader_with_options(double, double)
+declare double @js_readable_stream_get_byob_reader(double)
+declare double @js_readable_stream_controller_byob_request(double)
+declare double @js_readable_stream_from_iterable(double)
+declare double @js_readable_stream_locked(double)
+declare i64 @js_readable_stream_cancel(double, double)
+declare double @js_readable_stream_tee(double)
+declare i64 @js_readable_stream_pipe_to(double, double, double)
+declare double @js_readable_stream_pipe_through(double, double, double)
+declare double @js_readable_stream_pipe_through_validate(double, double, double, double)
+declare double @js_readable_stream_controller_enqueue(double, double)
+declare double @js_readable_stream_controller_close(double)
+declare double @js_readable_stream_controller_error(double, double)
+declare double @js_readable_stream_controller_desired_size(double)
+declare i64 @js_reader_read(double)
+declare i64 @js_reader_read_with_view(double, double)
+declare double @js_reader_release_lock(double)
+declare i64 @js_reader_closed(double)
+declare i64 @js_reader_cancel(double, double)
+declare double @js_writable_stream_new(double, double, double, double, double)
+declare double @js_writable_stream_new_with_sink_type(double, double, double, double, double, double)
+declare double @js_writable_stream_new_from_sink_object(double, double)
+declare double @js_writable_stream_throw_invalid_sink()
+declare double @js_writable_stream_get_writer(double)
+declare double @js_writable_stream_locked(double)
+declare i64 @js_writable_stream_close(double)
+declare i64 @js_writable_stream_abort(double, double)
+declare i64 @js_writer_write(double, double)
+declare i64 @js_writer_close(double)
+declare i64 @js_writer_abort(double, double)
+declare double @js_writer_release_lock(double)
+declare i64 @js_writer_closed(double)
+declare i64 @js_writer_ready(double)
+declare double @js_writer_desired_size(double)
+declare double @js_transform_stream_new(double, double, double, double, double)
+declare double @js_transform_stream_new_from_transformer_object(double, double, double)
+declare double @js_transform_stream_readable(double)
+declare double @js_transform_stream_writable(double)
+declare double @js_text_encoding_stream_new()
+declare double @js_text_encoder_stream_new()
+declare double @js_text_decoder_stream_new()
+declare double @js_stream_web_text_encoder_stream_new()
+declare double @js_stream_web_text_decoder_stream_new(double, double)
+declare double @js_stream_web_compression_stream_new(double)
+declare double @js_stream_web_decompression_stream_new(double)
+declare double @js_streams_strategy_high_water_mark(double)
+declare double @js_count_queuing_strategy_new(double)
+declare double @js_byte_length_queuing_strategy_new(double)
+declare double @js_stream_unwrap_handle(double)
+declare double @js_readable_stream_subclass_init(double, double, double, double, double)
+declare double @js_writable_stream_subclass_init(double, double, double, double, double)
+declare double @js_transform_stream_subclass_init(double, double, double, double)
+declare double @js_request_subclass_init(double, double, double)
+declare double @js_response_subclass_init(double, double, double)
+declare double @js_fetch_or_value_super(double, double, ptr, i64)
+declare i64 @js_abort_controller_new()
+declare i64 @js_abort_controller_signal(i64)
+declare void @js_abort_controller_abort(i64)
+declare void @js_abort_controller_abort_reason(i64, double)
+declare void @js_abort_signal_add_listener(i64, double, double)
+declare i64 @js_abort_signal_timeout(double)
+declare i64 @js_abort_signal_abort(double)
+declare i64 @js_abort_signal_any(i64)
+declare double @js_abort_signal_throw_if_aborted(i64)
+declare i64 @js_event_target_new()
+declare i64 @js_event_new(double, double, i32)
+declare double @js_event_subclass_init(double, double, double, i32, i32)
+declare i64 @js_custom_event_new(double, double, i32)
+declare i64 @js_dom_exception_new(double, double)
+declare double @js_dom_exception_subclass_init(double, double, double)
+declare void @js_event_target_add_event_listener(i64, i64, i64)
+declare void @js_event_target_add_event_listener_with_options(i64, i64, i64, double)
+declare void @js_event_target_remove_event_listener(i64, i64, i64)
+declare void @js_event_target_remove_event_listener_with_options(i64, i64, i64, double)
+declare double @js_event_target_dispatch_event(i64, double)
+declare i32 @js_event_target_is_event_target(i64)
+declare i64 @js_event_target_get_event_listeners(i64, i64)
+declare double @js_event_target_get_max_listeners(i64)
+declare i32 @js_event_target_set_max_listeners(i64, double)
+declare double @js_message_channel_new()
+declare double @js_message_port_constructor_error()
+declare double @js_broadcast_channel_new(double)
+declare i64 @js_array_alloc(i32)
+declare i64 @js_tagged_template_register_raw(i64, i64)
+declare i64 @js_tagged_template_get_or_init(i64, i64, i64)
+declare i64 @js_template_raw(i64)
+declare i64 @js_array_create()
+declare i64 @js_array_constructor_single(double)
+declare i64 @js_array_alloc_literal(i32)
+declare i64 @js_array_from_values(ptr, i32)
+declare i64 @js_array_push_f64(i64, double)
+declare void @js_array_push_guard(i64)
+declare i64 @js_array_push_hole(i64)
+declare i64 @js_array_numeric_push_f64_unboxed(i64, double)
+declare i64 @js_array_push_spread_f64(i64, i64)
+declare double @js_array_get_f64(i64, i32)
+declare double @js_array_get_index_or_string(i64, double)
+declare double @js_array_numeric_get_f64_unboxed(i64, i32)
+declare void @js_array_set_f64(i64, i32, double)
+declare i32 @js_array_numeric_set_f64_unboxed(i64, i32, double)
+declare i64 @js_array_set_f64_extend(i64, i32, double)
+declare i64 @js_array_set_f64_extend_strict(i64, i32, double)
+declare i64 @js_array_fill_f64_const_extend(i64, i32, double)
+declare i64 @js_array_fill_f64_iota_extend(i64, i32)
+declare i64 @js_array_fill_f64_const_len_extend(i64, double)
+declare i64 @js_array_fill_f64_iota_len_extend(i64)
+declare i64 @js_array_numeric_range_add(double, double, double, double)
+declare i64 @js_array_numeric_range_add_len(double, double, double)
+declare i64 @js_array_set_string_key(i64, i64, double)
+declare i64 @js_array_set_index_or_string(i64, double, double)
+declare i64 @js_array_mark_arguments_object(i64)
+declare i32 @js_array_mark_numeric_f64_layout(i64)
+declare i32 @js_array_is_numeric_f64_layout(i64)
+declare void @js_array_clear_numeric_layout(i64)
+declare double @js_array_numeric_value_to_raw_f64(double) #4
+declare double @js_array_refresh_local_head(double)
+declare void @js_array_note_numeric_write(i64, i64)
+declare i32 @js_array_length(i64)
+declare double @js_array_is_array(double)
+declare double @js_value_length_f64(double)
+declare nonnull ptr @js_shadow_frame_enter(i32)
+declare i64 @js_shadow_frame_push(i32)
+declare void @js_shadow_frame_pop(i64)
+declare void @js_shadow_slot_set(i32, i64)
+declare void @js_shadow_slot_bind(i32, ptr)
+declare void @js_gc_write_barriers_emitted(i32)
+declare i32 @js_gc_temp_root_push(i64)
+declare i64 @js_gc_temp_root_get(i32)
+declare void @js_gc_temp_root_set(i32, i64)
+declare void @js_gc_temp_root_truncate(i32)
+declare void @js_array_push_f64_temp_rooted(i32, double)
+declare void @js_gc_loop_safepoint()
+declare void @js_write_barrier(i64, i64)
+declare void @js_write_barrier_slot(i64, i64, i64)
+declare void @js_write_barrier_root_nanbox(i64)
+declare void @js_write_barrier_root_heap_word(i64)
+declare void @js_gc_note_slot_layout(i64, i32, i64)
+declare void @js_gc_note_slot_layout_aware(i64, i32, i64, i64)
+declare void @js_gc_init_typed_shape_layout(i64, i32, ptr, i32, ptr, i32)
+declare void @js_gc_init_unboxed_object_layout(i64, i32, i64, i64)
+declare double @js_array_pop_f64(i64)
+declare i64 @js_array_join(i64, i64)
+declare i64 @js_array_join_value(i64, double)
+declare void @js_array_forEach(i64, i64)
+declare i64 @js_array_fill(i64, double)
+declare i64 @js_array_fill_range(i64, double, double, double)
+declare double @js_array_fill_generic(double, double, i32, double, i32, double)
+declare i32 @js_array_delete(i64, i32)
+declare void @js_array_set_length(i64, double)
+declare void @js_array_set_length_strict(i64, double)
+declare i64 @js_array_clone(i64)
+declare i64 @js_array_from_value(double)
+declare i64 @js_array_from_arraylike_holey_value(double)
+declare double @js_iterator_from(double)
+declare i64 @js_array_from_mapped(double, double, double)
+declare i64 @js_array_concat_variadic(i64, ptr, i32)
+declare double @js_arraylike_forEach(double, double, double)
+declare double @js_arraylike_map(double, double, double)
+declare double @js_arraylike_filter(double, double, double)
+declare double @js_arraylike_some(double, double, double)
+declare double @js_arraylike_every(double, double, double)
+declare double @js_arraylike_find(double, double, double)
+declare double @js_arraylike_findIndex(double, double, double)
+declare double @js_arraylike_findLast(double, double, double)
+declare double @js_arraylike_findLastIndex(double, double, double)
+declare double @js_arraylike_reduce(double, double, i32, double)
+declare double @js_arraylike_reduceRight(double, double, i32, double)
+declare double @js_arraylike_indexOf(double, double, double, i32)
+declare double @js_arraylike_lastIndexOf(double, double, double, i32)
+declare double @js_arraylike_includes(double, double, double, i32)
+declare double @js_arraylike_at(double, double)
+declare double @js_arraylike_join(double, double)
+declare double @js_arraylike_slice(double, double, i32, double, i32)
+declare double @js_arraylike_sort(double, double)
+declare double @js_arraylike_splice(double, ptr, i32)
+declare double @js_arraylike_concat(double, ptr, i32)
+declare double @js_arraylike_pop(double)
+declare double @js_arraylike_shift(double)
+declare double @js_arraylike_push(double, ptr, i32)
+declare double @js_arraylike_unshift(double, ptr, i32)
+declare i64 @js_array_clone_for_spread(double)
+declare i64 @js_array_spread_append(i64, double)
+declare i64 @js_iterator_to_array(double)
+declare double @js_iterator_next_result(double)
+declare double @js_iterator_close_if_not_done(double, double)
+declare double @js_iterator_rest_to_array(double, double)
+declare double @js_get_iterator(double)
+declare double @js_get_async_iterator(double)
+declare double @js_for_of_to_array(double)
+declare i64 @js_object_alloc(i32, i32)
+declare double @js_object_coerce(double)
+declare void @js_object_mark_class(i64)
+declare void @js_class_object_pin_parent(i64, i32)
+declare i64 @js_object_alloc_with_shape(i32, i32, ptr, i32)
+declare void @js_object_set_field(i64, i32, i64)
+declare void @js_object_set_unboxed_f64_field(i64, i32, double)
+declare double @js_object_get_unboxed_f64_field(i64, i32)
+declare void @js_object_set_field_by_name(i64, i64, double)
+declare void @js_object_set_field_by_property_id(i64, i64, double)
+declare void @js_object_set_field_by_name_nonenum(i64, i64, double)
+declare void @js_error_subclass_default_init(double, double, i64)
+declare void @js_object_set_field_by_name_nonconfigurable(i64, i64, double)
+declare void @js_error_apply_cause_to_object(i64, double)
+declare i32 @js_with_has_binding(double, i64)
+declare double @js_with_get_binding(double, i64)
+declare double @js_with_set_binding(double, i64, double, i32)
+declare i32 @js_with_delete_binding(double, i64)
+declare i32 @js_pod_scalar_write_compatible(double, i32)
+declare void @js_typed_feedback_register_site(i64, i32, ptr, i64, ptr, i64, ptr, i64, ptr, i64, ptr, i64, ptr, i64)
+declare void @js_typed_feedback_record_guard_pass(i64)
+declare void @js_typed_feedback_record_guard_fail(i64)
+declare void @js_typed_feedback_record_fallback_call(i64)
+declare void @js_typed_feedback_observe_property_get(i64, i64, i64)
+declare void @js_typed_feedback_observe_property_set(i64, i64, i64)
+declare double @js_typed_feedback_object_get_field_by_name_f64(i64, i64, i64)
+declare void @js_typed_feedback_object_set_field_by_name(i64, i64, i64, double)
+declare void @js_typed_feedback_object_set_field_by_name_fast(i64, i64, i64, double)
+declare i32 @js_typed_feedback_class_field_set_guard(i64, double, i32, i64, i64, i32, double, i32)
+declare void @js_class_field_set_fallback(i64, i64, i64, double)
+declare void @js_class_field_set_ic(i64, double, i32, i64, i64, i32, double, i32)
+declare i32 @js_typed_feedback_class_field_get_guard(i64, double, i32, i64, i64, i32, i32)
+declare double @js_class_field_get_ic(i64, double, i32, i64, i64, i32, i32)
+declare double @js_typed_feedback_native_call_method(i64, double, ptr, i64, ptr, i64)
+declare double @js_typed_feedback_native_call_method_by_id(i64, double, i64, ptr, i64)
+declare double @js_typed_feedback_native_call_method_apply(i64, double, ptr, i64, i64)
+declare double @js_typed_feedback_native_call_method_apply_by_id(i64, double, i64, i64)
+declare i32 @js_typed_feedback_method_direct_call_guard(i64, double, i32, i64, ptr, i64, ptr)
+declare i32 @js_method_direct_shape_guard(double, i32, i64)
+declare i32 @js_typed_feedback_closure_direct_call_guard(i64, double, ptr, i32, i32)
+declare void @js_typed_feedback_object_set_unboxed_f64_field(i64, i64, i32, i64, double)
+declare double @js_typed_feedback_observe_helper_return(i64, double)
+declare void @js_object_set_index_polymorphic(i64, double, double)
+declare double @js_object_get_index_polymorphic(i64, double)
+declare double @js_object_get_field_by_name_f64(i64, i64)
+declare double @js_object_get_field_by_name_boxed(double, i64)
+declare double @js_object_get_field_by_property_id_f64(i64, i64)
+declare double @js_native_module_property_by_name(ptr, i64, ptr, i64)
+declare double @js_create_native_module_namespace(ptr, i64)
+declare void @js_nm_install_assert()
+declare void @js_nm_install_async_hooks()
+declare void @js_nm_install_bigint()
+declare void @js_nm_install_buffer()
+declare void @js_nm_install_bun()
+declare void @js_nm_install_bun_ffi()
+declare void @js_nm_install_child_process()
+declare void @js_nm_install_cluster()
+declare void @js_nm_install_console()
+declare void @js_nm_install_crypto()
+declare void @js_nm_install_dgram()
+declare void @js_nm_install_dns()
+declare void @js_nm_install_domain()
+declare void @js_nm_install_events()
+declare void @js_nm_install_fs()
+declare void @js_nm_install_http()
+declare void @js_nm_install_inspector()
+declare void @js_nm_install_module()
+declare void @js_nm_install_net()
+declare void @js_nm_install_node_pty()
+declare void @js_nm_install_os()
+declare void @js_nm_install_path()
+declare void @js_nm_install_perf()
+declare void @js_nm_install_process()
+declare void @js_nm_install_punycode()
+declare void @js_nm_install_querystring()
+declare void @js_nm_install_readline()
+declare void @js_nm_install_repl()
+declare void @js_nm_install_sea()
+declare void @js_nm_install_sqlite()
+declare void @js_nm_install_stream()
+declare void @js_nm_install_timers()
+declare void @js_nm_install_tls()
+declare void @js_nm_install_tty()
+declare void @js_nm_install_url()
+declare void @js_nm_install_util()
+declare void @js_nm_install_v8()
+declare void @js_nm_install_vm()
+declare void @js_nm_install_wasi()
+declare void @js_nm_install_zlib()
+declare void @js_nm_install_all()
+declare double @js_object_get_field_ic_miss(i64, i64, ptr)
+declare double @js_object_get_field_ic(i64, i64, i64, ptr)
+declare i64 @js_object_rest(i64, i64)
+declare double @js_require_object_coercible(double)
+declare double @js_require_json_disk(double)
+declare double @js_require_resolve_node_modules(double, double)
+declare void @js_globalthis_seed_async_local_storage()
+declare void @js_register_path_module(double, double)
+declare double @js_require_path_module(double)
+declare void @js_register_path_init(ptr, i64, i64)
+declare i64 @js_array_alloc_with_length(i32)
+declare void @js_array_set_f64_unchecked(i64, i32, double)
+declare double @js_typed_feedback_array_get_f64(i64, i64, i32)
+declare i32 @js_typed_feedback_plain_array_index_get_guard(i64, double, i32, i32) #4
+declare i32 @js_typed_feedback_numeric_array_index_get_guard(i64, double, i32, i32) #4
+declare i32 @js_typed_feedback_packed_f64_array_loop_guard(i64, double)
+declare i32 @js_typed_feedback_packed_f64_range_loop_guard(i64, double, i32, i32)
+declare i32 @js_typed_feedback_packed_f64_range_loop_guard_dense(i64, double, i32, i32)
+declare i32 @js_typed_feedback_packed_f64_range_loop_guard_dense_i32(i64, double, i32, i32)
+declare i32 @js_typed_feedback_masked_window_ta_kind(i64, double, i32, i32)
+declare i64 @js_typed_array_masked_window_data_ptr(double)
+declare i32 @js_typed_feedback_packed_u32_array_loop_guard(i64, double)
+declare double @js_typed_feedback_array_index_get_fallback_boxed(i64, double, double)
+declare void @js_typed_feedback_array_set_f64(i64, i64, i32, double)
+declare i64 @js_typed_feedback_array_set_f64_extend(i64, i64, i32, double)
+declare i32 @js_typed_feedback_plain_array_index_set_guard(i64, double, i32, double, i32) #4
+declare i32 @js_typed_feedback_numeric_array_index_set_guard(i64, double, i32, double, i32) #4
+declare i32 @js_typed_feedback_numeric_array_push_guard(i64, double, double) #4
+declare double @js_typed_feedback_array_index_set_fallback_boxed(i64, double, double, double)
+declare void @js_typed_feedback_observe_array_element(i64, i64, i32)
+declare i64 @js_typed_feedback_array_set_string_key(i64, i64, i64, double)
+declare i64 @js_typed_feedback_array_set_index_or_string(i64, i64, double, double)
+declare void @js_typed_feedback_object_set_index_polymorphic(i64, i64, double, double)
+declare double @js_proxy_new(double, double)
+declare double @js_proxy_revocable(double, double)
+declare void @js_proxy_revoke(double)
+declare i32 @js_proxy_is_revoked(double)
+declare i32 @js_proxy_is_proxy(double)
+declare double @js_proxy_target(double)
+declare double @js_proxy_get(double, double)
+declare double @js_proxy_set(double, double, double)
+declare double @js_proxy_has(double, double)
+declare double @js_proxy_delete(double, double)
+declare double @js_proxy_apply(double, double, double)
+declare double @js_proxy_construct(double, double, double)
+declare double @js_reflect_construct(double, double, double)
+declare double @js_reflect_get(double, double, double)
+declare double @js_reflect_set(double, double, double, double)
+declare double @js_put_value_set(double, double, double, double, i32)
+declare double @js_put_value_set_dyn_ic(ptr, double, double, double, i32)
+declare double @js_put_value_set_ic_miss(double, i64, double, i32, ptr)
+declare i64 @js_object_array_numeric_write_guard(double, double, double, double, double, i32, i32)
+declare double @js_super_put_value_set(i32, double, double, double, i32)
+declare double @js_super_accessor_get(i32, double, double)
+declare double @js_reflect_has(double, double)
+declare double @js_reflect_delete(double, double)
+declare double @js_reflect_own_keys(double)
+declare double @js_reflect_apply(double, double, double)
+declare double @js_reflect_define_property(double, double, double)
+declare double @js_reflect_get_own_property_descriptor(double, double)
+declare double @js_reflect_get_prototype_of(double)
+declare double @js_reflect_set_prototype_of(double, double)
+declare double @js_reflect_is_extensible(double)
+declare double @js_reflect_prevent_extensions(double)
+declare double @js_reflect_define_metadata(double, double, double, double)
+declare double @js_reflect_get_metadata(double, double, double)
+declare double @js_reflect_get_own_metadata(double, double, double)
+declare double @js_reflect_has_metadata(double, double, double)
+declare double @js_reflect_has_own_metadata(double, double, double)
+declare double @js_reflect_get_metadata_keys(double, double)
+declare double @js_reflect_get_own_metadata_keys(double, double)
+declare double @js_reflect_delete_metadata(double, double, double)
+declare double @js_http_server_construct_with_this(double, double, double)
+declare double @js_https_server_construct_with_this(double, double, double)
+declare i64 @js_net_socket_set_encoding(i64, i64)
+declare double @js_vm_create_context(double)
+declare double @js_vm_module_call()
+declare double @js_vm_module_constructor_error()
+declare double @js_repl_start(double)
+declare double @js_repl_repl_server_new(double)
+declare double @js_repl_recoverable_new(double)
+declare double @js_worker_threads_worker_new(i64, double)
+declare double @js_worker_threads_worker_post_message(i64, double)
+declare double @js_worker_threads_worker_on(i64, double, i64)
+declare double @js_worker_threads_worker_once(i64, double, i64)
+declare double @js_worker_threads_worker_off(i64, double, i64)
+declare double @js_worker_threads_worker_add_event_listener(i64, double, i64)
+declare double @js_worker_threads_worker_remove_event_listener(i64, double, i64)
+declare double @js_worker_threads_worker_terminate(i64)
+declare double @js_worker_threads_worker_ref(i64)
+declare double @js_worker_threads_worker_unref(i64)
+declare double @js_worker_threads_worker_get_heap_statistics(i64)
+declare double @js_worker_threads_worker_cpu_usage(i64, double)
+declare double @js_worker_threads_worker_get_heap_snapshot(i64, double)
+declare double @js_worker_threads_worker_start_cpu_profile(i64)
+declare double @js_worker_threads_worker_start_heap_profile(i64)
+declare i64 @js_http_client_request_end(i64, double)
+declare i64 @js_http_client_request_write(i64, double)
+declare i64 @js_http_client_request_end_full(i64, double, i64, i64)
+declare double @js_http_client_request_write_full(i64, double, i64, i64)
+declare i64 @js_http_set_timeout_full(i64, double, i64)
+declare i64 @js_http_client_request_method(i64)
+declare i64 @js_http_client_request_protocol(i64)
+declare i64 @js_http_client_request_host(i64)
+declare i64 @js_http_client_request_path(i64)
+declare double @js_http_client_request_listener_count(i64, i64)
+declare double @js_http_client_request_get_header(i64, i64)
+declare double @js_http_client_request_has_header(i64, i64)
+declare double @js_http_client_request_remove_header(i64, i64)
+declare double @js_http_client_request_get_header_names(i64)
+declare double @js_http_client_request_get_headers(i64)
+declare double @js_http_client_request_get_raw_header_names(i64)
+declare double @js_http_client_request_abort(i64)
+declare i64 @js_http_client_request_destroy(i64, double)
+declare double @js_http_client_request_noop_undefined(i64, double, double)
+declare double @js_http_client_request_aborted(i64)
+declare double @js_http_client_request_destroyed(i64)
+declare double @js_http_client_request_finished(i64)
+declare double @js_http_client_request_reused_socket(i64)
+declare double @js_http_client_request_max_headers_count(i64)
+declare double @js_http_client_request_writable_ended(i64)
+declare double @js_http_client_request_writable_finished(i64)
+declare double @js_http_client_request_socket(i64)
+declare i64 @js_http_get(double, i64)
+declare i64 @js_http_get_overload(i64)
+declare i64 @js_http_request_overload(i64)
+declare i64 @js_https_get_overload(i64)
+declare i64 @js_https_request_overload(i64)
+declare i64 @js_http_on(i64, i64, i64)
+declare i64 @js_http_request(double, i64)
+declare i64 @js_http_request_body(i64)
+declare double @js_http_request_body_length(i64)
+declare i64 @js_http_request_content_type(i64)
+declare double @js_http_request_has_header(i64, i64)
+declare i64 @js_http_request_header(i64, i64)
+declare i64 @js_http_request_headers_all(i64)
+declare double @js_http_request_id(i64)
+declare double @js_http_request_is_method(i64, i64)
+declare i64 @js_http_request_method(i64)
+declare i64 @js_http_request_path(i64)
+declare i64 @js_http_request_query(i64)
+declare i64 @js_http_request_query_all(i64)
+declare i64 @js_http_request_query_param(i64, i64)
+declare double @js_http_respond_error(i64, double, i64)
+declare double @js_http_respond_html(i64, double, i64)
+declare double @js_http_respond_json(i64, double, i64)
+declare double @js_http_respond_not_found(i64)
+declare double @js_http_respond_redirect(i64, i64, double)
+declare i64 @js_http_respond_status_text(double)
+declare double @js_http_respond_text(i64, double, i64)
+declare double @js_http_respond_with_headers(i64, double, i64, i64)
+declare double @js_http_response_headers(i64)
+declare double @js_http_response_trailers(i64)
+declare i64 @js_http_incoming_message_set_encoding(i64, i64)
+declare i64 @js_http_server_accept_v2(i64)
+declare double @js_http_server_close(i64)
+declare i64 @js_http_server_create(double)
+declare i64 @js_http_set_header(i64, i64, i64)
+declare i64 @js_http_set_timeout(i64, double)
+declare double @js_http_status_code(i64)
+declare i64 @js_http_status_message(i64)
+declare i64 @js_http_agent_new(double)
+declare i64 @js_https_agent_new(double)
+declare i64 @js_http_agent_get_name(i64, double)
+declare i64 @js_http_agent_noop_self(i64)
+declare double @js_http_agent_max_sockets(i64)
+declare double @js_http_agent_max_free_sockets(i64)
+declare double @js_http_agent_max_total_sockets(i64)
+declare double @js_http_agent_keep_alive_msecs(i64)
+declare double @js_http_agent_keep_alive(i64)
+declare i64 @js_http_agent_protocol(i64)
+declare double @js_http_agent_default_port(i64)
+declare void @js_http_agent_set_protocol(i64, i64)
+declare i64 @js_http_agent_destroy(i64)
+declare double @js_http_agent_destroyed(i64)
+declare double @js_http_agent_sockets(i64)
+declare double @js_http_agent_free_sockets(i64)
+declare double @js_http_agent_requests(i64)
+declare void @js_http_agent_set_max_sockets(i64, double)
+declare void @js_http_agent_set_max_free_sockets(i64, double)
+declare void @js_http_agent_set_max_total_sockets(i64, double)
+declare void @js_http_agent_set_keep_alive(i64, double)
+declare void @js_http_agent_set_keep_alive_msecs(i64, double)
+declare void @js_http_agent_set_create_connection(i64, i64)
+declare void @js_http_agent_set_create_socket(i64, i64)
+declare i64 @js_http_agent_create_connection(i64)
+declare i64 @js_http_agent_create_socket(i64)
+declare i64 @js_https_get(double, i64)
+declare i64 @js_https_request(double, i64)
+declare i64 @js_node_http_create_server(i64)
+declare i64 @js_node_http_server_listen(i64, i64)
+declare void @js_node_http_server_close(i64, i64)
+declare void @js_node_http_server_close_all_connections(i64)
+declare void @js_node_http_server_close_idle_connections(i64)
+declare i64 @js_node_http_server_address_json(i64)
+declare i32 @js_node_http_server_listening(i64)
+declare double @js_node_http_server_listening_value(i64)
+declare double @js_node_http_server_on(i64, i64, i64)
+declare i64 @js_node_http_im_method(i64)
+declare i64 @js_node_http_im_url(i64)
+declare i64 @js_node_http_im_http_version(i64)
+declare i64 @js_node_http_im_headers_json(i64)
+declare i64 @js_node_http_im_raw_headers_json(i64)
+declare i64 @js_node_http_im_headers_distinct_json(i64)
+declare i64 @js_node_http_im_trailers_json(i64)
+declare i64 @js_node_http_im_raw_trailers_json(i64)
+declare i64 @js_node_http_im_trailers_distinct_json(i64)
+declare i32 @js_node_http_im_complete(i64)
+declare i32 @js_node_http_im_aborted(i64)
+declare i32 @js_node_http_im_destroyed(i64)
+declare i64 @js_node_http_im_remote_address(i64)
+declare double @js_node_http_im_remote_port(i64)
+declare void @js_node_http_im_pause(i64)
+declare void @js_node_http_im_resume(i64)
+declare void @js_node_http_im_destroy(i64)
+declare double @js_node_http_im_on(i64, i64, i64)
+declare double @js_node_http_im_read(i64)
+declare i64 @js_node_http_im_set_timeout(i64, double, i64)
+declare void @js_node_http_res_set_status(i64, double)
+declare double @js_node_http_res_get_status(i64)
+declare void @js_node_http_res_set_status_message(i64, i64)
+declare void @js_node_http_res_set_header(i64, i64, double)
+declare i64 @js_node_http_res_set_header_self(i64, i64, double)
+declare double @js_node_http_res_get_header(i64, i64)
+declare void @js_node_http_res_remove_header(i64, i64)
+declare i32 @js_node_http_res_has_header(i64, i64)
+declare double @js_node_http_res_has_header_value(i64, i64)
+declare i64 @js_node_http_res_get_headers_json(i64)
+declare i64 @js_node_http_res_get_header_names_json(i64)
+declare i64 @js_node_http_res_append_header(i64, i64, i64)
+declare i64 @js_node_http_res_set_headers(i64, double)
+declare double @js_node_http_res_get_status_message(i64)
+declare i32 @js_node_http_res_headers_sent(i64)
+declare i32 @js_node_http_res_writable_ended(i64)
+declare i32 @js_node_http_res_writable_finished(i64)
+declare i32 @js_node_http_res_finished(i64)
+declare i32 @js_node_http_res_send_date(i64)
+declare void @js_node_http_res_set_send_date(i64, double)
+declare i32 @js_node_http_res_strict_content_length(i64)
+declare void @js_node_http_res_set_strict_content_length(i64, double)
+declare i64 @js_node_http_res_req_handle(i64)
+declare void @js_node_http_res_write_head(i64, double, i64, i64)
+declare i32 @js_node_http_res_write(i64, double)
+declare double @js_node_http_res_write_full(i64, double, i64, i64)
+declare void @js_node_http_res_add_trailers(i64, double)
+declare void @js_node_http_res_end(i64, double)
+declare void @js_node_http_res_end_full(i64, double, i64, i64)
+declare void @js_node_http_res_flush_headers(i64)
+declare void @js_node_http_res_cork(i64)
+declare void @js_node_http_res_uncork(i64)
+declare i64 @js_node_http_res_set_timeout(i64, double, i64)
+declare void @js_node_http_res_write_early_hints(i64, double, i64)
+declare void @js_node_http_res_write_continue(i64)
+declare void @js_node_http_res_write_processing(i64)
+declare double @js_node_http_res_on(i64, i64, i64)
+declare i64 @js_node_https_create_server(double, i64)
+declare i64 @js_node_https_server_listen(i64, i64)
+declare void @js_node_https_server_close(i64, i64)
+declare void @js_node_https_server_close_all_connections(i64)
+declare void @js_node_https_server_close_idle_connections(i64)
+declare i64 @js_node_https_server_address_json(i64)
+declare double @js_node_https_server_on(i64, i64, i64)
+declare double @js_node_https_server_listening_value(i64)
+declare double @js_node_https_server_headers_timeout(i64)
+declare double @js_node_https_server_set_headers_timeout(i64, double)
+declare double @js_node_https_server_keep_alive_timeout(i64)
+declare double @js_node_https_server_set_keep_alive_timeout(i64, double)
+declare double @js_node_https_server_keep_alive_timeout_buffer(i64)
+declare double @js_node_https_server_set_keep_alive_timeout_buffer(i64, double)
+declare double @js_node_https_server_request_timeout(i64)
+declare double @js_node_https_server_set_request_timeout(i64, double)
+declare double @js_node_https_server_idle_timeout(i64)
+declare double @js_node_https_server_set_idle_timeout(i64, double)
+declare double @js_node_https_server_max_headers_count(i64)
+declare double @js_node_https_server_set_max_headers_count(i64, double)
+declare double @js_node_https_server_max_requests_per_socket(i64)
+declare double @js_node_https_server_set_max_requests_per_socket(i64, double)
+declare i64 @js_node_https_server_set_timeout_method(i64, double, i64)
+declare i64 @js_node_http2_create_server(double, double)
+declare i64 @js_node_http2_create_secure_server(double, i64)
+declare i64 @js_node_http2_connect(double, double, i64)
+declare i64 @js_node_http2_server_listen(i64, i64)
+declare void @js_node_http2_server_close(i64, i64)
+declare i64 @js_node_http2_server_address_json(i64)
+declare double @js_node_http2_server_on(i64, i64, i64)
+declare i64 @js_node_http2_get_default_settings()
+declare i64 @js_node_http2_get_packed_settings(i64)
+declare i64 @js_node_http2_get_unpacked_settings(i64)
+declare i64 @js_pg_client_connect(i64)
+declare i64 @js_pg_client_end(i64)
+declare i64 @js_pg_client_new(i64)
+declare i64 @js_pg_client_query(i64, i64)
+declare i64 @js_pg_client_query_params(i64, i64, i64)
+declare i64 @js_pg_connect(i64)
+declare i64 @js_pg_create_pool(i64)
+declare i64 @js_pg_pool_end(i64)
+declare i64 @js_pg_pool_new(i64)
+declare i64 @js_pg_pool_query(i64, i64)
+declare i64 @js_ioredis_connect(i64)
+declare i64 @js_ioredis_decr(i64, i64)
+declare i64 @js_ioredis_del(i64, i64)
+declare void @js_ioredis_disconnect(i64)
+declare i64 @js_ioredis_exists(i64, i64)
+declare i64 @js_ioredis_expire(i64, i64, double)
+declare i64 @js_ioredis_get(i64, i64)
+declare i64 @js_ioredis_hdel(i64, i64, i64)
+declare i64 @js_ioredis_hget(i64, i64, i64)
+declare i64 @js_ioredis_hgetall(i64, i64)
+declare i64 @js_ioredis_hlen(i64, i64)
+declare i64 @js_ioredis_hset(i64, i64, i64, i64)
+declare i64 @js_ioredis_incr(i64, i64)
+declare i64 @js_ioredis_new(i64)
+declare i64 @js_ioredis_ping(i64)
+declare i64 @js_ioredis_quit(i64)
+declare i64 @js_ioredis_set(i64, i64, i64)
+declare i64 @js_ioredis_setex(i64, i64, double, i64)
+declare i64 @js_mongodb_client_close(i64)
+declare i64 @js_mongodb_client_connect(i64)
+declare i64 @js_mongodb_client_db(i64, i64)
+declare i64 @js_mongodb_client_list_databases(i64)
+declare i64 @js_mongodb_client_new(i64)
+declare i64 @js_mongodb_collection_count_value(i64, double)
+declare i64 @js_mongodb_collection_delete_many_value(i64, double)
+declare i64 @js_mongodb_collection_delete_one_value(i64, double)
+declare i64 @js_mongodb_collection_find_one_value(i64, double)
+declare i64 @js_mongodb_collection_find_value(i64, double)
+declare i64 @js_mongodb_collection_insert_many_value(i64, double)
+declare i64 @js_mongodb_collection_insert_one_value(i64, double)
+declare i64 @js_mongodb_collection_update_many_value(i64, double, double)
+declare i64 @js_mongodb_collection_update_one_value(i64, double, double)
+declare i64 @js_mongodb_collection_count(i64, i64)
+declare i64 @js_mongodb_collection_delete_many(i64, i64)
+declare i64 @js_mongodb_collection_delete_one(i64, i64)
+declare i64 @js_mongodb_collection_find(i64, i64)
+declare i64 @js_mongodb_collection_find_one(i64, i64)
+declare i64 @js_mongodb_collection_insert_many(i64, i64)
+declare i64 @js_mongodb_collection_insert_one(i64, i64)
+declare i64 @js_mongodb_collection_update_many(i64, i64, i64)
+declare i64 @js_mongodb_collection_update_one(i64, i64, i64)
+declare i64 @js_mongodb_connect(i64)
+declare i64 @js_mongodb_db_collection(i64, i64)
+declare i64 @js_mongodb_db_list_collections(i64)
+declare void @js_sqlite_close(i64)
+declare void @js_sqlite_exec(i64, i64)
+declare i64 @js_sqlite_open(i64)
+declare i64 @js_sqlite_pragma(i64, i64, i64)
+declare i64 @js_sqlite_prepare(i64, i64)
+declare i64 @js_sqlite_stmt_all(i64, i64)
+declare i64 @js_sqlite_stmt_columns(i64)
+declare i64 @js_sqlite_stmt_get(i64, i64)
+declare i64 @js_sqlite_stmt_run(i64, i64)
+declare i64 @js_sqlite_transaction(i64, i64)
+declare void @js_sqlite_transaction_commit(i64)
+declare void @js_sqlite_transaction_rollback(i64)
+declare i64 @js_node_sqlite_backup(double, double, double)
+declare i64 @js_node_sqlite_database_sync_call(double, double)
+declare i64 @js_node_sqlite_database_sync_new(double, double)
+declare i32 @js_node_sqlite_database_sync_open(i64)
+declare i32 @js_node_sqlite_database_sync_close(i64)
+declare i32 @js_node_sqlite_database_sync_dispose(i64)
+declare i32 @js_node_sqlite_database_sync_exec(i64, double)
+declare i64 @js_node_sqlite_database_sync_prepare(i64, double, double)
+declare i32 @js_node_sqlite_database_sync_function(i64, double, double, double)
+declare i32 @js_node_sqlite_database_sync_aggregate(i64, double, double)
+declare i32 @js_node_sqlite_database_sync_enable_defensive(i64, double)
+declare i32 @js_node_sqlite_database_sync_set_authorizer(i64, double)
+declare i64 @js_node_sqlite_database_sync_create_tag_store(i64, double)
+declare i64 @js_node_sqlite_database_sync_create_session(i64, double)
+declare double @js_node_sqlite_database_sync_apply_changeset(i64, double, double)
+declare i32 @js_node_sqlite_database_sync_enable_load_extension(i64, double)
+declare i32 @js_node_sqlite_database_sync_load_extension(i64, double)
+declare double @js_node_sqlite_database_sync_location(i64, double)
+declare double @js_node_sqlite_database_sync_is_open(i64)
+declare double @js_node_sqlite_database_sync_is_transaction(i64)
+declare i64 @js_node_sqlite_database_sync_limits(i64)
+declare i64 @js_node_sqlite_statement_sync_call(double, double)
+declare i64 @js_node_sqlite_statement_sync_new(double, double)
+declare i64 @js_node_sqlite_statement_sync_run(i64, i64)
+declare double @js_node_sqlite_statement_sync_get(i64, i64)
+declare i64 @js_node_sqlite_statement_sync_all(i64, i64)
+declare double @js_node_sqlite_statement_sync_iterate(i64, i64)
+declare i64 @js_node_sqlite_statement_sync_columns(i64)
+declare i32 @js_node_sqlite_statement_sync_set_read_bigints(i64, double)
+declare i32 @js_node_sqlite_statement_sync_set_return_arrays(i64, double)
+declare i32 @js_node_sqlite_statement_sync_set_allow_bare_named_parameters(i64, double)
+declare i32 @js_node_sqlite_statement_sync_set_allow_unknown_named_parameters(i64, double)
+declare i64 @js_node_sqlite_statement_sync_source_sql(i64)
+declare i64 @js_node_sqlite_statement_sync_expanded_sql(i64)
+declare i64 @js_node_sqlite_sql_tag_store_run(i64, i64)
+declare double @js_node_sqlite_sql_tag_store_get(i64, i64)
+declare i64 @js_node_sqlite_sql_tag_store_all(i64, i64)
+declare double @js_node_sqlite_sql_tag_store_iterate(i64, i64)
+declare i32 @js_node_sqlite_sql_tag_store_clear(i64)
+declare double @js_node_sqlite_sql_tag_store_size(i64)
+declare double @js_node_sqlite_sql_tag_store_capacity(i64)
+declare i64 @js_node_sqlite_sql_tag_store_db(i64)
+declare i64 @js_node_sqlite_session_call(double, double)
+declare i64 @js_node_sqlite_session_new(double, double)
+declare i64 @js_node_sqlite_session_changeset(i64)
+declare i64 @js_node_sqlite_session_patchset(i64)
+declare i32 @js_node_sqlite_session_close(i64)
+declare i32 @js_node_sqlite_session_dispose(i64)
+declare i64 @js_os_cpus()
+declare double @js_os_freemem()
+declare i64 @js_os_homedir()
+declare i64 @js_os_network_interfaces()
+declare i64 @js_os_tmpdir()
+declare double @js_os_totalmem()
+declare double @js_os_uptime()
+declare i64 @js_os_user_info()
+declare i64 @js_os_user_info_buffer()
+declare i64 @js_os_user_info_options(i64)
+declare i64 @js_crypto_aes256_decrypt(i64, i64, i64)
+declare i64 @js_crypto_aes256_encrypt(i64, i64, i64)
+declare i64 @js_crypto_aes256_gcm_decrypt(i64, i64, i64)
+declare i64 @js_crypto_aes256_gcm_encrypt(i64, i64, i64)
+declare double @js_crypto_create_cipheriv(i64, i64, i64, double)
+declare double @js_crypto_create_decipheriv(i64, i64, i64, double)
+declare i64 @js_crypto_hkdf_sha256(i64, i64, i64, double)
+declare i64 @js_crypto_hkdf_sync(i64, i64, i64, i64, double)
+declare i64 @js_crypto_pbkdf2(i64, i64, double, double)
+declare i64 @js_crypto_random_bytes_hex(double)
+declare i64 @js_crypto_random_nonce()
+declare i64 @js_crypto_scrypt(i64, i64, double)
+declare double @js_crypto_generate_key_pair_sync(i64, i64)
+declare i64 @js_crypto_scrypt_custom(i64, i64, double, double, double, double)
+declare i64 @js_crypto_x25519_keypair()
+declare i64 @js_crypto_x25519_shared_secret(i64, i64)
+declare i64 @js_keccak256_native(i64)
+declare i64 @js_keccak256_native_bytes(i64)
+declare i64 @js_nanoid(double)
+declare i64 @js_nanoid_custom(i64, double)
+declare i64 @js_argon2_hash(i64)
+declare i64 @js_argon2_hash_options(i64, i64)
+declare i64 @js_argon2_verify(i64, i64)
+declare i64 @js_bcrypt_compare(i64, i64)
+declare double @js_bcrypt_compare_sync(i64, i64)
+declare i64 @js_bcrypt_gen_salt(double)
+declare i64 @js_bcrypt_hash(i64, double)
+declare i64 @js_bcrypt_hash_sync(i64, double)
+declare i64 @js_ads_interstitial_load(i64)
+declare i64 @js_ads_interstitial_show()
+declare i64 @js_ads_rewarded_load(i64)
+declare i64 @js_ads_rewarded_show()
+declare double @js_ads_banner_create(i64, i64)
+declare void @js_ads_banner_destroy(double)
+declare i64 @js_ads_request_consent()
+declare i64 @js_perry_read_embedded(double)
+declare i64 @js_perry_embedded_files()
+declare double @js_thread_parallel_map(double, double)
+declare double @js_thread_parallel_filter(double, double)
+declare double @js_thread_spawn(double)
+declare i64 @js_jwt_decode(i64)
+declare i64 @js_jwt_sign(i64, i64, double, i64)
+declare i64 @js_jwt_sign_es256(i64, i64, double, i64)
+declare i64 @js_jwt_sign_rs256(i64, i64, double, i64)
+declare i64 @js_jwt_verify(i64, i64)
+declare i64 @js_jwt_verify_es256(i64, i64)
+declare i64 @js_jwt_verify_rs256(i64, i64)
+declare i64 @js_jwt_sign_dyn(i64, i64, i64, double, i64)
+declare i64 @js_jwt_verify_dyn(i64, i64, i64)
+declare i64 @js_jwt_sign_dyn_opts(i64, i64, double)
+declare i64 @js_jwt_verify_dyn_opts(i64, i64, double)
+declare double @js_axios_create(i64)
+declare i64 @js_axios_delete(i64)
+declare i64 @js_axios_get(i64)
+declare i64 @js_axios_head(i64)
+declare i64 @js_axios_options(i64)
+declare i64 @js_axios_post(i64, double)
+declare i64 @js_axios_put(i64, double)
+declare i64 @js_axios_patch(i64, double)
+declare i64 @js_axios_request(i64)
+declare double @js_axios_response_status(i64)
+declare i64 @js_axios_response_status_text(i64)
+declare i64 @js_axios_response_data(i64)
+declare double @js_axios_response_data_parsed(i64)
+declare i64 @js_sharp_auto_orient(i64)
+declare i64 @js_sharp_avif(i64, double)
+declare i64 @js_sharp_blur(i64, double)
+declare i64 @js_sharp_composite(i64, double)
+declare i64 @js_sharp_extend(i64, double)
+declare i64 @js_sharp_extract(i64, double)
+declare i64 @js_sharp_flip(i64)
+declare i64 @js_sharp_flop(i64)
+declare i64 @js_sharp_from_buffer(i64, double)
+declare i64 @js_sharp_from_file(i64)
+declare i64 @js_sharp_from_input(i64)
+declare i64 @js_sharp_grayscale(i64)
+declare i64 @js_sharp_metadata(i64)
+declare i64 @js_sharp_sharpen(i64)
+declare i64 @js_sharp_trim(i64)
+declare i64 @js_sharp_negate(i64)
+declare i64 @js_sharp_quality(i64, double)
+declare i64 @js_sharp_resize(i64, double, double)
+declare i64 @js_sharp_rotate(i64, double)
+declare i64 @js_sharp_to_buffer(i64)
+declare i64 @js_sharp_to_file(i64, i64)
+declare i64 @js_sharp_to_format(i64, i64)
+declare void @js_cron_clear_interval(i64)
+declare void @js_cron_clear_timeout(i64)
+declare i64 @js_cron_describe(i64)
+declare double @js_cron_job_is_running(i64)
+declare i64 @js_cron_job_new(i64, i64, double)
+declare void @js_cron_job_start(i64)
+declare void @js_cron_job_stop(i64)
+declare i64 @js_cron_next_date(i64)
+declare i64 @js_cron_next_dates(i64, double)
+declare i64 @js_cron_schedule(i64, i64)
+declare i64 @js_cron_set_interval(double, double)
+declare i64 @js_cron_set_timeout(double, double)
+declare i32 @js_cron_timer_has_pending()
+declare i32 @js_cron_timer_tick()
+declare double @js_cron_validate(i64)
+declare i64 @js_async_hooks_create_hook(double)
+declare double @js_async_hooks_execution_async_id()
+declare double @js_async_hooks_trigger_async_id()
+declare double @js_async_hooks_execution_async_resource()
+declare i64 @js_async_hook_enable(i64)
+declare i64 @js_async_hook_disable(i64)
+declare i64 @js_async_resource_new(double, double)
+declare double @js_async_resource_async_id(i64)
+declare double @js_async_resource_trigger_async_id(i64)
+declare i64 @js_async_resource_emit_destroy(i64)
+declare double @js_async_resource_run_in_async_scope(i64, double, double, i64)
+declare i64 @js_async_resource_bind(i64, double, double)
+declare i64 @js_async_resource_static_bind(i64, double)
+declare void @js_async_local_storage_disable(i64)
+declare void @js_async_local_storage_enter_with(i64, double)
+declare double @js_async_local_storage_exit(i64, double, i64)
+declare double @js_async_local_storage_get_store(i64)
+declare i64 @js_async_local_storage_new()
+declare double @js_async_local_storage_run(i64, double, double, i64)
+declare i64 @js_disposable_stack_new()
+declare i64 @js_async_disposable_stack_new()
+declare double @js_suppressed_error_new(double, double, double)
+declare i64 @js_zlib_deflate_sync(i64, double)
+declare void @js_zlib_deflate(double, double)
+declare i64 @js_zlib_gunzip_sync(i64)
+declare void @js_zlib_gunzip(double, double)
+declare i64 @js_zlib_gzip_sync(i64, double)
+declare void @js_zlib_gzip(double, double)
+declare i64 @js_zlib_inflate_sync(i64)
+declare void @js_zlib_inflate(double, double)
+declare i64 @js_zlib_deflate_raw_sync(double, double)
+declare void @js_zlib_deflate_raw(double, double)
+declare i64 @js_zlib_inflate_raw_sync(double)
+declare void @js_zlib_inflate_raw(double, double)
+declare i64 @js_zlib_unzip_sync(double)
+declare void @js_zlib_unzip(double, double)
+declare double @js_zlib_crc32(double, double)
+declare i64 @js_zlib_brotli_compress_sync(i64)
+declare i64 @js_zlib_brotli_decompress_sync(i64)
+declare void @js_zlib_brotli_compress(double, double)
+declare void @js_zlib_brotli_decompress(double, double)
+declare i64 @js_zlib_zstd_compress_sync(double, double)
+declare i64 @js_zlib_zstd_decompress_sync(double, double)
+declare void @js_zlib_zstd_compress(double, double)
+declare void @js_zlib_zstd_decompress(double, double)
+declare i64 @js_zlib_create_gzip(double)
+declare i64 @js_zlib_create_gunzip(double)
+declare i64 @js_zlib_create_deflate(double)
+declare i64 @js_zlib_create_inflate(double)
+declare i64 @js_zlib_create_deflate_raw(double)
+declare i64 @js_zlib_create_inflate_raw(double)
+declare i64 @js_zlib_create_unzip(double)
+declare i64 @js_zlib_create_brotli_compress(double)
+declare i64 @js_zlib_create_zstd_compress(double)
+declare i64 @js_zlib_create_zstd_decompress(double)
+declare i64 @js_buffer_alloc_unsafe(i32)
+declare i32 @js_buffer_byte_length(i64)
+declare i32 @js_buffer_byte_length_value(double, double)
+declare i64 @js_buffer_concat(i64)
+declare i64 @js_buffer_concat_with_length(i64, double)
+declare i32 @js_buffer_validate_size(double)
+declare i64 @js_buffer_validate_concat_list(double)
+declare i32 @js_buffer_copy(i64, i64, i32, i32, i32)
+declare i32 @js_buffer_equals(i64, i64)
+declare i64 @js_buffer_fill(i64, i32)
+declare i64 @js_buffer_from_value(i64, i32)
+declare double @js_buffer_is_ascii(double)
+declare i32 @js_buffer_is_buffer(i64)
+declare i32 @js_buffer_is_encoding(double)
+declare double @js_buffer_is_utf8(double)
+declare void @js_buffer_print(i64)
+declare void @js_buffer_set(i64, i32, i32)
+declare void @js_buffer_set_from(i64, i64, i32)
+declare i64 @js_buffer_slice(i64, i32, i32)
+declare i64 @js_buffer_to_string(i64, i32)
+declare i64 @js_buffer_transcode(double, double, double)
+declare i32 @js_buffer_write(i64, i64, i32, i32)
+declare double @js_child_process_exec_sync(i64, i64)
+declare double @js_child_process_exec(i64, double, double)
+declare i64 @js_child_process_get_process_status(double)
+declare i32 @js_child_process_kill_process(double)
+declare i64 @js_child_process_spawn_background(double, i64, double, double)
+declare i64 @js_child_process_spawn_sync(i64, i64, i64)
+declare double @js_child_process_spawn_streams(i64, i64, i64)
+declare double @js_pty_spawn(i64, i64, i64)
+declare double @js_child_process_fork(i64, i64, i64)
+declare double @js_child_process_exec_file(i64, double, double, double)
+declare double @js_child_process_exec_file_sync(i64, double, double)
+declare double @js_child_process_validate_command(double, ptr, i32)
+declare double @js_child_process_validate_args(double)
+declare double @js_child_process_validate_options(double, i32, i32)
+declare double @js_child_process_validate_fork_module(double)
+declare double @js_child_process_validate_spawn_args(double, i32, i32)
+declare double @js_child_process_new()
+declare i64 @js_cheerio_load(i64)
+declare i64 @js_cheerio_load_fragment(i64)
+declare i64 @js_cheerio_select(i64, i64)
+declare i64 @js_cheerio_selection_attr(i64, i64)
+declare i64 @js_cheerio_selection_attrs(i64, i64)
+declare i64 @js_cheerio_selection_children(i64, i64)
+declare i64 @js_cheerio_selection_eq(i64, double)
+declare i64 @js_cheerio_selection_find(i64, i64)
+declare i64 @js_cheerio_selection_first(i64)
+declare double @js_cheerio_selection_has_class(i64, i64)
+declare i64 @js_cheerio_selection_html(i64)
+declare double @js_cheerio_selection_is(i64, i64)
+declare i64 @js_cheerio_selection_last(i64)
+declare double @js_cheerio_selection_length(i64)
+declare i64 @js_cheerio_selection_parent(i64)
+declare i64 @js_cheerio_selection_text(i64)
+declare i64 @js_cheerio_selection_texts(i64)
+declare i64 @js_cheerio_selection_to_array(i64)
+declare double @js_url_file_url_to_path(double, double)
+declare double @js_url_file_url_to_path_buffer(double, double)
+declare double @js_url_get_hash(i64)
+declare double @js_url_get_host(i64)
+declare double @js_url_get_hostname(i64)
+declare double @js_url_get_href(i64)
+declare double @js_url_get_origin(i64)
+declare double @js_url_get_pathname(i64)
+declare double @js_url_get_port(i64)
+declare double @js_url_get_protocol(i64)
+declare double @js_url_get_search(i64)
+declare double @js_url_get_search_params(i64)
+declare i64 @js_url_new(i64)
+declare i64 @js_url_new_with_base(i64, i64)
+declare i64 @js_url_pattern_new(double, double)
+declare double @js_url_pattern_constructor_call(double, double)
+declare i32 @js_url_can_parse(i64)
+declare i32 @js_url_can_parse_with_base(i64, i64)
+declare i64 @js_url_parse(i64)
+declare i64 @js_url_parse_with_base(i64, i64)
+declare void @js_url_set_pathname(i64, double)
+declare void @js_url_set_search(i64, double)
+declare void @js_url_set_hash(i64, double)
+declare void @js_url_set_protocol(i64, double)
+declare void @js_url_set_hostname(i64, double)
+declare void @js_url_set_port(i64, double)
+declare void @js_url_set_username(i64, double)
+declare void @js_url_set_password(i64, double)
+declare void @js_url_set_href(i64, double)
+declare double @js_url_search_params_has2(i64, double, double)
+declare void @js_url_search_params_delete2(i64, double, double)
+declare double @js_url_search_params_throw_missing_args(i32)
+declare void @js_url_search_params_append(i64, double, double)
+declare void @js_url_search_params_delete(i64, double)
+declare i64 @js_url_search_params_get(i64, double)
+declare double @js_url_search_params_get_all(i64, double)
+declare double @js_url_search_params_has(i64, double)
+declare i64 @js_url_search_params_new(i64)
+declare i64 @js_url_search_params_new_any(double)
+declare i64 @js_url_search_params_new_empty()
+declare double @js_url_search_params_subclass_init(double, double)
+declare void @js_url_search_params_set(i64, double, double)
+declare i64 @js_url_search_params_to_string(i64)
+declare i32 @js_url_search_params_size(i64)
+declare double @js_url_search_params_entries_arr(i64)
+declare double @js_url_search_params_keys_arr(i64)
+declare double @js_url_search_params_values_arr(i64)
+declare void @js_url_search_params_sort(i64)
+declare void @js_url_search_params_for_each(i64, double, double)
+declare i64 @js_url_coerce_string(double)
+declare double @js_url_path_to_file_url(double, double)
+declare double @js_url_domain_to_ascii(double)
+declare double @js_url_domain_to_unicode(double)
+declare double @js_url_to_http_options(double)
+declare double @js_url_legacy_url_new()
+declare double @js_url_format(double, double)
+declare double @js_url_legacy_parse(double, double, double)
+declare double @js_url_legacy_resolve(double, double)
+declare double @js_url_legacy_resolve_object(double, double)
+declare void @js_ws_close(i64)
+declare i64 @js_ws_connect(i64)
+declare double @js_ws_connect_start(double)
+declare i64 @js_ws_handle_to_i64(double)
+declare double @js_ws_is_open(i64)
+declare double @js_ws_message_count(i64)
+declare double @js_ws_ready_state(i64)
+declare i64 @js_ws_on(i64, i64, i64)
+declare i64 @js_ws_receive(i64)
+declare void @js_ws_send(i64, i64)
+declare void @js_ws_send_to_client(double, i64)
+declare void @js_ws_close_client(double)
+declare void @js_ws_send_client_i64(i64, i64)
+declare void @js_ws_close_client_i64(i64)
+declare i64 @js_ws_on_client_i64(i64, i64, i64)
+declare void @js_ws_server_close(i64)
+declare i64 @js_ws_server_new(double)
+declare i64 @js_ws_handle_upgrade(i64, double, double, double, i64)
+declare i64 @js_ws_wait_for_message(i64, double)
+declare i64 @js_pdf_create_pdf(double)
+declare void @js_pdf_add_text(i64, i64, double, double, double)
+declare void @js_pdf_add_line(i64, double, double, double, double)
+declare void @js_pdf_new_page(i64)
+declare void @js_pdf_save(i64)
+declare i64 @js_commander_action(i64, i64)
+declare i64 @js_commander_command(i64, i64)
+declare i64 @js_commander_description(i64, i64)
+declare i64 @js_commander_get_option(i64, i64)
+declare double @js_commander_get_option_bool(i64, i64)
+declare double @js_commander_get_option_number(i64, i64)
+declare i64 @js_commander_name(i64, i64)
+declare i64 @js_commander_new()
+declare i64 @js_commander_option(i64, i64, i64, i64)
+declare i64 @js_commander_opts(i64)
+declare i64 @js_commander_parse(i64, double)
+declare i64 @js_commander_required_option(i64, i64, i64, i64)
+declare i64 @js_commander_version(i64, i64)
+declare double @js_dotenv_config()
+declare double @js_dotenv_config_path(i64)
+declare i64 @js_dotenv_parse(i64)
+declare double @js_datefns_add_days(double, double)
+declare double @js_datefns_add_months(double, double)
+declare double @js_datefns_add_years(double, double)
+declare double @js_datefns_difference_in_days(double, double)
+declare double @js_datefns_difference_in_hours(double, double)
+declare double @js_datefns_difference_in_minutes(double, double)
+declare double @js_datefns_end_of_day(double)
+declare i64 @js_datefns_format(double, i64)
+declare double @js_datefns_is_after(double, double)
+declare double @js_datefns_is_before(double, double)
+declare double @js_datefns_parse_iso(i64)
+declare double @js_datefns_start_of_day(double)
+declare double @js_dayjs_add(i64, double, i64)
+declare double @js_dayjs_date(i64)
+declare double @js_dayjs_day(i64)
+declare double @js_dayjs_diff(i64, i64, i64)
+declare double @js_dayjs_end_of(i64, i64)
+declare double @js_dayjs_factory(i64)
+declare i64 @js_dayjs_format(i64, i64)
+declare double @js_dayjs_from_timestamp(double)
+declare double @js_dayjs_hour(i64)
+declare double @js_dayjs_is_after(i64, i64)
+declare double @js_dayjs_is_before(i64, i64)
+declare double @js_dayjs_is_same(i64, i64)
+declare double @js_dayjs_is_valid(i64)
+declare double @js_dayjs_millisecond(i64)
+declare double @js_dayjs_minute(i64)
+declare double @js_dayjs_month(i64)
+declare double @js_dayjs_now()
+declare double @js_dayjs_parse(i64)
+declare double @js_dayjs_second(i64)
+declare double @js_dayjs_start_of(i64, i64)
+declare double @js_dayjs_subtract(i64, double, i64)
+declare i64 @js_dayjs_to_iso_string(i64)
+declare double @js_dayjs_unix(i64)
+declare double @js_dayjs_value_of(i64)
+declare double @js_dayjs_year(i64)
+declare double @js_moment_add(i64, double, i64)
+declare double @js_moment_clone(i64)
+declare double @js_moment_date(i64)
+declare double @js_moment_day(i64)
+declare double @js_moment_diff(i64, i64, i64)
+declare double @js_moment_end_of(i64, i64)
+declare double @js_moment_factory(i64)
+declare i64 @js_moment_format(i64, i64)
+declare i64 @js_moment_from_now(i64)
+declare double @js_moment_from_timestamp(double)
+declare double @js_moment_hour(i64)
+declare double @js_moment_is_after(i64, i64)
+declare double @js_moment_is_before(i64, i64)
+declare double @js_moment_is_between(i64, i64, i64)
+declare double @js_moment_is_same(i64, i64, i64)
+declare double @js_moment_is_valid(i64)
+declare double @js_moment_millisecond(i64)
+declare double @js_moment_minute(i64)
+declare double @js_moment_month(i64)
+declare double @js_moment_now()
+declare double @js_moment_parse(i64)
+declare double @js_moment_second(i64)
+declare double @js_moment_start_of(i64, i64)
+declare double @js_moment_subtract(i64, double, i64)
+declare double @js_moment_to_date(i64)
+declare i64 @js_moment_to_iso_string(i64)
+declare double @js_moment_unix(i64)
+declare double @js_moment_value_of(i64)
+declare double @js_moment_year(i64)
+declare i64 @js_decimal_abs(i64)
+declare i64 @js_decimal_ceil(i64)
+declare double @js_decimal_cmp(i64, i64)
+declare double @js_decimal_cmp_value(i64, double)
+declare i64 @js_decimal_coerce_to_handle(double)
+declare i64 @js_decimal_div(i64, i64)
+declare i64 @js_decimal_div_number(i64, double)
+declare i64 @js_decimal_div_value(i64, double)
+declare double @js_decimal_eq(i64, i64)
+declare double @js_decimal_eq_value(i64, double)
+declare i64 @js_decimal_floor(i64)
+declare i64 @js_decimal_from_number(double)
+declare i64 @js_decimal_from_string(i64)
+declare double @js_decimal_gt(i64, i64)
+declare double @js_decimal_gt_value(i64, double)
+declare double @js_decimal_gte(i64, i64)
+declare double @js_decimal_gte_value(i64, double)
+declare double @js_decimal_is_negative(i64)
+declare double @js_decimal_is_positive(i64)
+declare double @js_decimal_is_zero(i64)
+declare double @js_decimal_lt(i64, i64)
+declare double @js_decimal_lt_value(i64, double)
+declare double @js_decimal_lte(i64, i64)
+declare double @js_decimal_lte_value(i64, double)
+declare i64 @js_decimal_minus(i64, i64)
+declare i64 @js_decimal_minus_number(i64, double)
+declare i64 @js_decimal_minus_value(i64, double)
+declare i64 @js_decimal_mod(i64, i64)
+declare i64 @js_decimal_mod_value(i64, double)
+declare i64 @js_decimal_neg(i64)
+declare i64 @js_decimal_plus(i64, i64)
+declare i64 @js_decimal_plus_number(i64, double)
+declare i64 @js_decimal_plus_value(i64, double)
+declare i64 @js_decimal_pow(i64, double)
+declare i64 @js_decimal_round(i64)
+declare i64 @js_decimal_sqrt(i64)
+declare i64 @js_decimal_times(i64, i64)
+declare i64 @js_decimal_times_number(i64, double)
+declare i64 @js_decimal_times_value(i64, double)
+declare i64 @js_decimal_to_fixed(i64, double)
+declare double @js_decimal_to_number(i64)
+declare i64 @js_decimal_to_string(i64)
+declare i64 @js_ethers_format_ether(i64)
+declare i64 @js_ethers_format_units(i64, double)
+declare i64 @js_ethers_get_address(i64)
+declare i64 @js_ethers_parse_ether(i64)
+declare i64 @js_ethers_parse_units(i64, double)
+declare i64 @js_lodash_camel_case(i64)
+declare i64 @js_lodash_capitalize(i64)
+declare i64 @js_lodash_chunk(i64, double)
+declare double @js_lodash_clamp(double, double, double)
+declare i64 @js_lodash_compact(i64)
+declare i64 @js_lodash_concat(i64, i64)
+declare i64 @js_lodash_difference(i64, i64)
+declare i64 @js_lodash_drop(i64, double)
+declare i64 @js_lodash_drop_right(i64, double)
+declare double @js_lodash_ends_with(i64, i64)
+declare i64 @js_lodash_escape(i64)
+declare double @js_lodash_first(i64)
+declare i64 @js_lodash_flatten(i64)
+declare double @js_lodash_in_range(double, double, double)
+declare double @js_lodash_includes(i64, i64)
+declare i64 @js_lodash_initial(i64)
+declare i64 @js_lodash_kebab_case(i64)
+declare double @js_lodash_last(i64)
+declare i64 @js_lodash_lower_case(i64)
+declare i64 @js_lodash_lower_first(i64)
+declare double @js_lodash_max(i64)
+declare double @js_lodash_max_by(i64, double)
+declare double @js_lodash_mean(i64)
+declare double @js_lodash_mean_by(i64, double)
+declare double @js_lodash_min(i64)
+declare double @js_lodash_min_by(i64, double)
+declare i64 @js_lodash_pad(i64, double)
+declare i64 @js_lodash_pad_end(i64, double)
+declare i64 @js_lodash_pad_start(i64, double)
+declare double @js_lodash_random(double, double)
+declare i64 @js_lodash_repeat(i64, double)
+declare i64 @js_lodash_replace(i64, i64, i64)
+declare i64 @js_lodash_reverse(i64)
+declare double @js_lodash_size(i64)
+declare i64 @js_lodash_snake_case(i64)
+declare i64 @js_lodash_split(i64, i64)
+declare i64 @js_lodash_start_case(i64)
+declare double @js_lodash_starts_with(i64, i64)
+declare double @js_lodash_sum(i64)
+declare double @js_lodash_sum_by(i64, double)
+declare i64 @js_lodash_tail(i64)
+declare i64 @js_lodash_take(i64, double)
+declare i64 @js_lodash_take_right(i64, double)
+declare i64 @js_lodash_trim(i64)
+declare i64 @js_lodash_trim_end(i64)
+declare i64 @js_lodash_trim_start(i64)
+declare i64 @js_lodash_truncate(i64, double)
+declare i64 @js_lodash_unescape(i64)
+declare i64 @js_lodash_uniq(i64)
+declare i64 @js_lodash_upper_case(i64)
+declare i64 @js_lodash_upper_first(i64)
+declare void @js_lru_cache_clear(i64)
+declare double @js_lru_cache_delete(i64, double)
+declare double @js_lru_cache_get(i64, double)
+declare double @js_lru_cache_has(i64, double)
+declare i64 @js_lru_cache_new(double)
+declare double @js_lru_cache_peek(i64, double)
+declare i64 @js_lru_cache_set(i64, double, double)
+declare double @js_lru_cache_size(i64)
+declare double @js_event_emitter_subclass_init(double)
+declare double @js_array_subclass_init(double, double)
+declare double @js_map_set_subclass_init(double, i32, double)
+declare double @js_promise_subclass_init(double, double)
+declare double @js_node_stream_readable_new(double)
+declare double @js_node_stream_readable_subclass_init(double, double)
+declare double @js_node_stream_writable_new(double)
+declare double @js_node_stream_writable_subclass_init(double, double)
+declare double @js_node_stream_duplex_new(double)
+declare double @js_node_stream_duplex_subclass_init(double, double)
+declare double @js_node_stream_transform_new(double)
+declare double @js_node_stream_transform_subclass_init(double, double)
+declare double @js_node_stream_passthrough_new(double)
+declare double @js_node_stream_readable_from(double)
+declare double @js_node_stream_readable_from_options(double, double)
+declare double @js_node_stream_duplex_from_options(double, double)
+declare double @js_node_stream_is_disturbed(double)
+declare double @js_node_stream_is_errored(double)
+declare double @js_node_stream_is_readable(double)
+declare double @js_node_stream_is_writable(double)
+declare double @js_node_stream_is_array_buffer_view(double)
+declare double @js_node_stream_is_uint8_array(double)
+declare double @js_node_stream_is_destroyed(double)
+declare double @js_node_stream_uint8_array_to_buffer(double)
+declare double @js_node_stream_get_default_hwm(double)
+declare double @js_node_stream_set_default_hwm(double, double)
+declare double @js_node_stream_add_abort_signal(double, double)
+declare double @js_node_stream_compose(i64)
+declare double @js_node_stream_pipeline(i64)
+declare double @js_node_stream_finished(i64)
+declare double @js_node_stream_duplex_pair(double)
+declare double @js_node_stream_readable_to_web(double)
+declare double @js_node_stream_writable_to_web(double)
+declare double @js_node_stream_duplex_to_web(double)
+declare double @js_node_stream_readable_from_web(double, double)
+declare double @js_node_stream_writable_from_web(double, double)
+declare double @js_node_stream_duplex_from_web(double, double)
+declare double @js_node_stream_to_web(double)
+declare double @js_node_stream_from_web(double)
+declare double @js_node_stream_method_readable_aborted(i64)
+declare double @js_node_stream_method_closed(i64)
+declare double @js_node_stream_method_errored(i64)
+declare double @js_node_stream_method_readable_did_read(i64)
+declare double @js_node_stream_method_destroyed(i64)
+declare double @js_node_stream_method_destroy(i64, double)
+declare double @js_node_stream_method_pause(i64)
+declare double @js_node_stream_method_readable(i64)
+declare double @js_node_stream_method_readable_length(i64)
+declare double @js_node_stream_method_readable_flowing(i64)
+declare double @js_node_stream_method_readable_ended(i64)
+declare double @js_node_stream_method_readable_object_mode(i64)
+declare double @js_node_stream_method_pipe(i64, double, double)
+declare double @js_node_stream_method_unpipe(i64, double)
+declare double @js_node_stream_method_is_paused(i64)
+declare double @js_node_stream_method_resume(i64)
+declare double @js_node_stream_method_readable_encoding(i64)
+declare double @js_node_stream_method_cork(i64)
+declare double @js_node_stream_method_uncork(i64)
+declare double @js_node_stream_method_writable_corked(i64)
+declare double @js_node_stream_method_writable_length(i64)
+declare double @js_node_stream_method_writable_need_drain(i64)
+declare double @js_node_stream_method_writable(i64)
+declare double @js_node_stream_method_writable_ended(i64)
+declare double @js_node_stream_method_writable_finished(i64)
+declare double @js_node_stream_method_allow_half_open(i64)
+declare double @js_node_stream_method_set_encoding(i64, double)
+declare double @js_node_stream_method_writable_object_mode(i64)
+declare double @js_event_emitter_emit(i64, i64, i64)
+declare double @js_event_emitter_emit0(i64, i64)
+declare double @js_event_emitter_listener_count(i64, i64, i64)
+declare i64 @js_event_emitter_new()
+declare i64 @js_event_emitter_new_with_options(double)
+declare i64 @js_event_emitter_on(i64, i64, i64)
+declare i64 @js_event_emitter_once(i64, i64, i64)
+declare i64 @js_event_emitter_prepend_listener(i64, i64, i64)
+declare i64 @js_event_emitter_prepend_once_listener(i64, i64, i64)
+declare i64 @js_event_emitter_remove_all_listeners(i64, i64)
+declare i64 @js_event_emitter_remove_listener(i64, i64, i64)
+declare i64 @js_event_emitter_set_max_listeners(i64, double)
+declare double @js_event_emitter_get_max_listeners(i64)
+declare i64 @js_event_emitter_event_names(i64)
+declare i64 @js_event_emitter_listeners(i64, i64)
+declare i64 @js_event_emitter_raw_listeners(i64, i64)
+declare double @js_event_emitter_domain_value(i64)
+declare i64 @js_event_emitter_async_resource_new(double)
+declare double @js_event_emitter_async_resource_call(double)
+declare double @js_event_emitter_async_resource_async_id(i64)
+declare double @js_event_emitter_async_resource_trigger_async_id(i64)
+declare double @js_event_emitter_async_resource_async_resource(i64)
+declare double @js_event_emitter_async_resource_emit_destroy(i64)
+declare i64 @js_events_once(double, i64, double)
+declare i64 @js_events_on(double, i64, double)
+declare i64 @js_events_add_abort_listener(double, double)
+declare i64 @js_events_get_event_listeners(double, i64)
+declare double @js_events_listener_count(double, i64)
+declare double @js_events_get_max_listeners(double)
+declare double @js_events_set_max_listeners(double, i64)
+declare double @js_events_init()
+declare i64 @js_domain_create()
+declare i64 @js_domain_on(i64, i64, i64)
+declare double @js_domain_emit(i64, i64, i64)
+declare double @js_domain_run(i64, double, i64)
+declare double @js_domain_bind(i64, double)
+declare double @js_domain_intercept(i64, double)
+declare i64 @js_domain_add(i64, double)
+declare i64 @js_domain_remove(i64, double)
+declare double @js_domain_enter(i64)
+declare double @js_domain_exit(i64)
+declare i64 @js_string_decoder_new(i64)
+declare double @js_string_decoder_write(i64, double)
+declare double @js_string_decoder_end(i64, double)
+declare double @js_querystring_escape(double)
+declare double @js_querystring_unescape(double)
+declare i64 @js_querystring_unescape_buffer(double, double)
+declare i64 @js_querystring_parse(double, double, double, double)
+declare double @js_querystring_stringify(double, double, double, double)
+declare i32 @js_fastify_add_hook(i64, i64, i64)
+declare i32 @js_fastify_all(i64, i64, i64)
+declare i64 @js_fastify_create()
+declare i64 @js_fastify_create_with_opts(double)
+declare double @js_fastify_ctx_html(i64, i64, double)
+declare double @js_fastify_ctx_json(i64, double, double)
+declare double @js_fastify_ctx_redirect(i64, i64, double)
+declare double @js_fastify_ctx_text(i64, i64, double)
+declare i32 @js_fastify_delete(i64, i64, i64)
+declare i32 @js_fastify_get(i64, i64, i64)
+declare i32 @js_fastify_head(i64, i64, i64)
+declare void @js_fastify_listen(i64, double, i64)
+declare void @js_fastify_app_close(i64)
+declare i64 @js_fastify_app_server(i64)
+declare void @js_fastify_app_on(i64, i64, i64)
+declare i32 @js_fastify_options(i64, i64, i64)
+declare i32 @js_fastify_patch(i64, i64, i64)
+declare i32 @js_fastify_post(i64, i64, i64)
+declare i32 @js_fastify_put(i64, i64, i64)
+declare i32 @js_fastify_register(i64, i64, double)
+declare i64 @js_fastify_reply_header(i64, i64, i64)
+declare i32 @js_fastify_reply_send(i64, double)
+declare i64 @js_fastify_reply_status(i64, double)
+declare i64 @js_fastify_reply_type(i64, i64)
+declare i64 @js_fastify_req_body(i64)
+declare double @js_fastify_req_get_user_data(i64)
+declare i64 @js_fastify_req_header(i64, i64)
+declare i64 @js_fastify_req_headers(i64)
+declare double @js_fastify_req_json(i64)
+declare i64 @js_fastify_req_method(i64)
+declare i64 @js_fastify_req_param(i64, i64)
+declare i64 @js_fastify_req_params(i64)
+declare i64 @js_fastify_req_query(i64)
+declare double @js_fastify_req_query_object(i64)
+declare void @js_fastify_req_set_user_data(i64, double)
+declare i64 @js_fastify_req_url(i64)
+declare i32 @js_fastify_route(i64, i64, i64, i64)
+declare i32 @js_fastify_set_error_handler(i64, i64)
+declare double @js_nodemailer_create_transport(i64)
+declare i64 @js_nodemailer_send_mail(i64, i64)
+declare i64 @js_nodemailer_verify(i64)
+declare i64 @js_ratelimit_block(i64, i64, double)
+declare i64 @js_ratelimit_consume(i64, i64, double)
+declare i64 @js_ratelimit_create(i64)
+declare i64 @js_ratelimit_delete(i64, i64)
+declare i64 @js_ratelimit_get(i64, i64)
+declare i64 @js_ratelimit_new_from_options(i64)
+declare i64 @js_ratelimit_penalty(i64, i64, double)
+declare i64 @js_ratelimit_reward(i64, i64, double)
+declare double @js_validator_contains(i64, i64)
+declare double @js_validator_equals(i64, i64)
+declare double @js_validator_is_alpha(i64)
+declare double @js_validator_is_alphanumeric(i64)
+declare double @js_validator_is_email(i64)
+declare double @js_validator_is_empty(i64)
+declare double @js_validator_is_float(i64)
+declare double @js_validator_is_hexadecimal(i64)
+declare double @js_validator_is_int(i64)
+declare double @js_validator_is_json(i64)
+declare double @js_validator_is_length(i64, double, double)
+declare double @js_validator_is_lowercase(i64)
+declare double @js_validator_is_numeric(i64)
+declare double @js_validator_is_uppercase(i64)
+declare double @js_validator_is_url(i64)
+declare double @js_validator_is_uuid(i64)
+declare i64 @js_date_to_locale_string(double)
+declare i64 @js_number_to_locale_string(double)
+declare double @js_value_to_locale_string(double)
+declare i64 @js_string_split_regex(i64, i64)
+declare i32 @js_object_delete_dynamic(i64, double)
+declare double @js_object_get_prototype_of(double)
+declare double @js_object_set_prototype_of(double, double)
+declare double @js_object_define_properties(double, double)
+declare double @js_math_acos(double)
+declare double @js_math_asin(double)
+declare double @js_math_atan(double)
+declare double @js_math_atan2(double, double)
+declare double @js_math_cos(double)
+declare double @js_math_expm1(double)
+declare double @js_math_log(double)
+declare double @js_math_log10(double)
+declare double @js_math_log1p(double)
+declare double @js_math_log2(double)
+declare double @js_math_sin(double)
+declare double @js_math_tan(double)
+declare double @js_atomics_load(ptr, double, double)
+declare double @js_atomics_is_lock_free(ptr, double)
+declare double @js_atomics_store(ptr, double, double, double)
+declare double @js_atomics_add(ptr, double, double, double)
+declare double @js_atomics_sub(ptr, double, double, double)
+declare double @js_atomics_and(ptr, double, double, double)
+declare double @js_atomics_or(ptr, double, double, double)
+declare double @js_atomics_xor(ptr, double, double, double)
+declare double @js_atomics_exchange(ptr, double, double, double)
+declare double @js_atomics_compare_exchange(ptr, double, double, double, double)
+declare double @js_atomics_notify(ptr, double, double, double)
+declare double @js_atomics_wait(ptr, double, double, double, double)
+declare double @js_atomics_wait_async(ptr, double, double, double, double)
+declare double @js_number_is_finite(double)
+declare double @js_json_get_bool(i64, i64)
+declare double @js_json_get_number(i64, i64)
+declare i64 @js_json_get_string(i64, i64)
+declare double @js_json_is_valid(i64)
+declare i64 @js_json_stringify_bool(double)
+declare i64 @js_json_stringify_null()
+declare i64 @js_json_stringify_number(double)
+declare i64 @js_json_stringify_string(i64)
+declare void @js_set_property(double, i64, i64, double)
+declare i64 @js_error_get_message(i64)
+declare double @js_await_js_promise(double)
+declare i64 @js_text_decoder_decode(i64)
+declare i64 @js_text_encoder_encode(double)
+declare double @js_call_function(i64, i64, i64, i64, i64)
+declare double @js_call_method(double, i64, i64, i64, i64)
+declare double @js_call_value(double, i64, i64)
+declare double @js_closure_call_array(i64, ptr, i64)
+declare double @js_closure_call_apply_with_spread(double, ptr, i64, i64)
+declare double @js_create_callback(i64, i64, i64)
+declare double @js_dynamic_neg(double)
+declare i32 @js_dynamic_string_equals(double, double)
+declare double @js_is_nan(double)
+declare i32 @js_jsvalue_compare(double, double)
+declare i32 @js_jsvalue_loose_equals(double, double)
+declare void @js_gc_collect()
+declare void @js_console_assert(double, i64)
+declare void @js_console_assert_spread(double, i64)
+declare void @js_console_group(i64)
+declare double @js_console_context(double)
+declare double @js_console_create_task(double)
+declare i64 @js_fetch_get(i64)
+declare i64 @js_fetch_get_with_auth(i64, i64)
+declare i64 @js_fetch_post(i64, i64, i64)
+declare i64 @js_fetch_post_with_auth(i64, i64, i64)
+declare double @js_fetch_stream_close(double)
+declare i64 @js_fetch_stream_poll(double)
+declare double @js_fetch_stream_start(i64, i64, i64, i64)
+declare double @js_fetch_stream_status(double)
+declare i64 @js_fetch_text(i64)
+declare i64 @js_fetch_with_options(i64, i64, i64, i64)
+declare void @js_fetch_set_pending_signal(double)
+declare i64 @js_fetch_headers_to_json(double)
+declare double @js_net_create_connection(i32, i64, i64)
+declare i64 @js_net_create_server(i64, i64)
+declare double @js_net_normalize_args(double)
+declare double @js_net_create_server_handle_stub(double, double, double, double, double)
+declare void @js_net_validate_create_server_options(double)
+declare i64 @js_net_socket_set_timeout(i64, double, i64)
+declare void @js_net_server_listen(i64, double, double, double)
+declare void @js_net_server_close(i64, i64)
+declare i64 @js_net_server_address(i64)
+declare void @js_net_server_on(i64, i64, i64)
+declare double @js_net_server_get_listening(i64)
+declare double @js_net_server_get_connections(i64)
+declare double @js_net_server_get_max_connections(i64)
+declare double @js_net_server_set_max_connections(i64, double)
+declare double @js_net_server_get_drop_max_connection(i64)
+declare double @js_net_server_set_drop_max_connection(i64, double)
+declare i64 @js_net_block_list_new()
+declare double @js_net_block_list_is_block_list(double)
+declare double @js_net_block_list_add_address(i64, i64, i64)
+declare double @js_net_block_list_add_range(i64, i64, i64, i64)
+declare double @js_net_block_list_add_subnet(i64, i64, double, i64)
+declare double @js_net_block_list_check(i64, i64, i64)
+declare double @js_net_block_list_to_json(i64)
+declare i64 @js_net_block_list_rules(i64)
+declare double @js_net_block_list_from_json(i64, double)
+declare i64 @js_net_socket_address_new(double)
+declare double @js_net_socket_address_parse(i64)
+declare i64 @js_net_socket_address_get_address(i64)
+declare i64 @js_net_socket_address_get_family(i64)
+declare double @js_net_socket_address_get_port(i64)
+declare double @js_net_socket_address_get_flowlabel(i64)
+declare double @js_net_socket_get_type_of_service(i64)
+declare i64 @js_net_socket_set_type_of_service(i64, double)
+declare i64 @js_net_socket_address(i64)
+declare i64 @js_net_socket_once(i64, i64, i64)
+declare i64 @js_net_socket_remove_listener(i64, i64, i64)
+declare i64 @js_net_socket_remove_all_listeners(i64, i64)
+declare double @js_net_socket_listener_count(i64, i64)
+declare i64 @js_net_socket_event_names(i64)
+declare i64 @js_net_socket_reset_and_destroy(i64)
+declare i64 @js_net_server_once(i64, i64, i64)
+declare i64 @js_net_server_remove_listener(i64, i64, i64)
+declare i64 @js_net_server_remove_all_listeners(i64, i64)
+declare double @js_net_server_listener_count(i64, i64)
+declare i64 @js_net_server_event_names(i64)
+declare double @js_performance_now()
+declare double @js_perf_mark(double, double)
+declare double @js_perf_measure(double, double, double)
+declare double @js_perf_get_entries()
+declare double @js_perf_get_entries_by_type(double)
+declare double @js_perf_get_entries_by_name(double, double)
+declare double @js_perf_clear_marks(double)
+declare double @js_perf_clear_measures(double)
+declare double @js_perf_event_loop_utilization(double, double)
+declare double @js_perf_to_json()
+declare double @js_perf_clear_resource_timings()
+declare double @js_perf_set_resource_timing_buffer_size(double)
+declare double @js_perf_mark_resource_timing(double, double, double, double, double, double, double, double)
+declare double @js_perf_timerify(double, double)
+declare double @js_perf_observer_new(double)
+declare double @js_perf_observer_observe(double, double)
+declare double @js_perf_observer_disconnect(double)
+declare double @js_perf_observer_take_records(double)
+declare double @js_perf_monitor_event_loop_delay(double)
+declare double @js_perf_create_histogram(double)
+declare double @js_perf_histogram_noop()
+declare double @js_perf_histogram_percentile(double)
+declare double @js_iter_result_set(double, i32)
+declare double @js_iter_result_set_f64(double, i32)
+declare double @js_iter_result_set_i32(i32, i32)
+declare double @js_iter_result_set_i1(i32, i32)
+declare double @js_iter_result_get_value()
+declare double @js_iter_result_get_value_f64()
+declare i32 @js_iter_result_get_value_i32()
+declare i32 @js_iter_result_get_value_i1()
+declare double @js_iter_result_get_done()
+declare i64 @js_async_step_chain(double, i64)
+declare i64 @js_async_step_done(double, i64)
+declare i64 @js_get_current_step_closure()
+declare double @js_async_first_call(double)
+declare double @js_async_generator_resume(double, double, double)
+declare i64 @js_slugify(i64)
+declare i64 @js_slugify_strict(i64)
+declare void @js_register_class_getter(i64, i64, i64, i64)
+declare void @js_register_class_setter(i64, i64, i64, i64)
+declare void @js_register_class_method_bind_length(i64, i64, i64, i64)
+declare void @js_register_class_static_method_bind_length(i64, i64, i64, i64)
+declare void @js_register_class_static_getter(i64, i64, i64, i64)
+declare void @js_register_class_static_setter(i64, i64, i64, i64)
+declare void @js_register_class_method(i64, i64, i64, i64, i64, i64, i64)
+declare void @js_register_class_constructor(i64, i64, i64, i64)
+declare void @js_register_class_constructor_flags(i64, i64, i64)
+declare void @js_register_class_static_method(i64, i64, i64, i64, i64, i64)
+declare double @js_class_static_method_call(double, i64, i64, ptr, i64)
+declare double @js_class_method_bind(double, i64, i64)
+declare double @js_class_method_bind_by_id(double, i64)
+declare double @js_class_prototype_method_value(double, double)
+declare double @js_implicit_this_get()
+declare double @js_implicit_this_get_sloppy()
+declare double @js_implicit_this_set(double)
+declare double @js_static_this_resolve(double)
+declare void @js_static_this_arm_classref(i32)
+declare void @js_static_this_arm_value(double)
+declare double @js_ctor_return_override(double, double, i32)
+declare double @js_new_target_get()
+declare double @js_new_target_set(double)
+declare double @js_get_export(i64, i64, i64)
+declare double @js_get_property(double, i64, i64)
+declare i64 @js_load_module(i64, i64)
+declare double @js_module_dynamic_import_apply_hooks(double)
+declare double @js_native_call_method_nullsafe(double, i64, i64, i64, i64)
+declare double @js_native_call_value(double, i64, i64)
+declare double @js_new_from_handle(double, i64, i64)
+declare double @js_new_instance(i64, i64, i64, i64, i64)
+declare void @js_runtime_init()
+declare double @js_object_set_symbol_method(double, double, double)
+declare double @js_object_set_method_by_name(double, double, double)
+declare double @js_object_define_accessor(double, double, double, double)
+declare double @js_object_literal_set_computed(double, double, double)
+declare double @js_object_literal_to_property_key(double)
+declare double @js_object_literal_set_prototype(double, double)
+declare double @js_to_primitive(double, i32)
+declare void @js_register_class_has_instance(i32, i64)
+declare void @js_register_class_to_string_tag(i32, i64)
+declare double @js_object_to_string(double)
+declare double @js_object_group_by(double, double)
+declare double @js_map_group_by(double, double)
+declare double @js_array_from_async(double, double, double)
+declare double @js_jsx(double, double)
+declare double @js_jsxs(double, double)
+declare i64 @js_node_http_server_ref(i64)
+declare i64 @js_node_http_server_unref(i64)
+declare i64 @js_node_https_server_ref(i64)
+declare i64 @js_node_https_server_unref(i64)
+declare double @js_http_client_request_flush_headers(i64, double, double)
+declare double @js_node_http_im_http_version_major(i64)
+declare double @js_node_http_im_http_version_minor(i64)
+declare i64 @js_node_http_im_pause_self(i64)
+declare i64 @js_node_http_im_resume_self(i64)
+declare i64 @js_commander_args_array(i64)
+declare i64 @js_commander_argument(i64, i64)
+declare double @__ic_decl_2()
+declare double @__ic_decl_5()
+declare double @__ic_decl_8()
+declare double @__ic_decl_10()
+declare double @__ic_decl_12()
+declare double @__ic_decl_14()
+declare double @__ic_decl_16()
+declare double @__ic_decl_18()
+declare double @__ic_decl_20()
+declare double @__ic_decl_22()
+declare double @__ic_decl_24()
+declare double @__ic_decl_26()
+declare double @__ic_decl_28()
+declare double @__ic_decl_31()
+declare double @__ic_decl_34()
+declare double @__ic_decl_39()
+declare double @__ic_decl_71()
+declare double @__ic_decl_74()
+declare double @__ic_decl_77()
+
+define double @perry_fn_batch_ts__buildRows(double %arg14, double %arg44) alwaysinline {
+entry.0:
+  %r1 = alloca i64
+  %r2 = alloca ptr
+  store ptr null, ptr %r2
+  %r3 = call ptr @js_shadow_frame_enter(i32 2)
+  store ptr %r3, ptr %r2
+  %r4 = getelementptr inbounds i8, ptr %r3, i64 24
+  %r5 = load i64, ptr %r4
+  %r6 = sub i64 %r5, 1
+  store i64 %r6, ptr %r1
+  %r9 = alloca i32
+  store i32 0, ptr %r9
+  %r10 = alloca i1
+  %r11 = alloca i32
+  %r35 = alloca double
+  store double 0x7FFC000000000001, ptr %r35
+  %r68 = alloca i64
+  %r69 = load i64, ptr @perry_class_keys_batch_ts__Row
+  store i64 %r69, ptr %r68
+  %r7 = alloca double
+  store double %arg14, ptr %r7
+  %r8 = alloca double
+  store double %arg44, ptr %r8
+  call void @js_shadow_slot_bind(i32 0, ptr %r8)
+  store i32 0, ptr %r9
+  store i1 false, ptr %r10
+  store i32 0, ptr %r11
+  %r12 = load double, ptr %r7
+  %r13 = bitcast double %r12 to i64
+  %r14 = and i64 %r13, -281474976710656
+  %r15 = icmp ult i64 %r14, 9221401712017801216
+  %r16 = icmp ugt i64 %r14, 9223090561878065152
+  %r17 = or i1 %r15, %r16
+  br i1 %r17, label %for.bound_i32.number.1, label %for.bound_i32.merge.3
+
+for.bound_i32.number.1:
+  %r18 = fcmp oge double %r12, -2147483648.0
+  %r19 = fcmp ole double %r12, 2147483647.0
+  %r20 = and i1 %r18, %r19
+  br i1 %r20, label %for.bound_i32.convert.2, label %for.bound_i32.merge.3
+
+for.bound_i32.convert.2:
+  %r21 = fptosi double %r12 to i32
+  %r22 = sitofp i32 %r21 to double
+  %r23 = fcmp oeq double %r22, %r12
+  store i32 %r21, ptr %r11
+  store i1 %r23, ptr %r10
+  br label %for.bound_i32.merge.3
+
+for.bound_i32.merge.3:
+  br label %for.cond.4
+
+for.cond.4:
+  %r24 = load i1, ptr %r10
+  br i1 %r24, label %for.cond.fast.8, label %for.cond.slow.9
+
+for.body.5:
+  %r36 = call i32 @js_gc_temp_root_push(i64 0)
+  %r37 = load i32, ptr %r9
+  %r38 = sitofp i32 %r37 to double
+  %r39 = load double, ptr @perry_global_batch_ts__1
+  %r40 = load i32, ptr %r9
+  %r41 = sitofp i32 %r40 to double
+  %r42 = fptosi double %r41 to i64
+  %r43 = fptosi double 4.0 to i64
+  %r44 = srem i64 %r42, %r43
+  %r45 = sitofp i64 %r44 to double
+  %r46 = icmp eq i64 %r44, 0
+  %r47 = fcmp olt double %r41, 0.0
+  %r48 = and i1 %r46, %r47
+  %r49 = fneg double %r45
+  %r50 = select i1 %r48, double %r49, double %r45
+  %r51 = bitcast double %r39 to i64
+  %r52 = and i64 %r51, 281474976710655
+  %r53 = call double @js_array_get_index_or_string(i64 %r52, double %r50)
+  %r54 = bitcast double %r53 to i64
+  %r55 = call i32 @js_gc_temp_root_push(i64 %r54)
+  %r56 = load i32, ptr %r9
+  %r57 = sitofp i32 %r56 to double
+  %r58 = fptosi double %r57 to i64
+  %r59 = fptosi double 97.0 to i64
+  %r60 = srem i64 %r58, %r59
+  %r61 = sitofp i64 %r60 to double
+  %r62 = icmp eq i64 %r60, 0
+  %r63 = fcmp olt double %r57, 0.0
+  %r64 = and i1 %r62, %r63
+  %r65 = fneg double %r61
+  %r66 = select i1 %r64, double %r65, double %r61
+  %r67 = fmul double %r66, 0.5
+  %r70 = load i64, ptr %r68
+  %r71 = call i64 @js_object_alloc_class_inline_keys(i32 1, i32 0, i32 4, i64 %r70)
+  %r72 = call i32 @js_gc_temp_root_push(i64 %r71)
+  %r73 = or i64 %r71, 9222527611924643840
+  %r74 = bitcast i64 %r73 to double
+  %r75 = call i64 @js_gc_temp_root_get(i32 %r55)
+  %r76 = bitcast i64 %r75 to double
+  %r77 = call double @batch_ts__Row_constructor(double %r74, double %r38, double %r76, double %r67)
+  %r78 = call i64 @js_gc_temp_root_get(i32 %r72)
+  %r79 = or i64 %r78, 9222527611924643840
+  %r80 = bitcast i64 %r79 to double
+  call void @js_gc_init_typed_shape_layout(i64 %r78, i32 4, ptr @perry_typed_shape_raw_f64_mask_batch_ts__Row, i32 1, ptr @perry_typed_shape_mask_batch_ts__Row, i32 1)
+  %r81 = call double @js_ctor_return_override(double %r80, double %r77, i32 0)
+  call void @js_gc_temp_root_truncate(i32 %r36)
+  store double %r81, ptr %r35
+  %r82 = load ptr, ptr %r2
+  %r83 = icmp eq ptr %r82, null
+  br i1 %r83, label %ss.slow.10, label %ss.chk_top.11
+
+for.update.6:
+  %r164 = load i32, ptr %r9
+  %r165 = add i32 %r164, 1
+  store i32 %r165, ptr %r9
+  %r166 = sitofp i32 %r164 to double
+  %r167 = sitofp i32 %r165 to double
+  br label %for.cond.4
+
+for.exit.7:
+  %r168 = load ptr, ptr %r2
+  %r169 = icmp eq ptr %r168, null
+  br i1 %r169, label %ss.slow.26, label %ss.chk_top.27
+
+for.cond.fast.8:
+  %r25 = load i32, ptr %r9
+  %r26 = load i32, ptr %r11
+  %r27 = icmp slt i32 %r25, %r26
+  br i1 %r27, label %for.body.5, label %for.exit.7
+
+for.cond.slow.9:
+  %r28 = load i32, ptr %r9
+  %r29 = sitofp i32 %r28 to double
+  %r30 = load double, ptr %r7
+  %r31 = fcmp olt double %r29, %r30
+  %r32 = select i1 %r31, i64 9222246136947933188, i64 9222246136947933187
+  %r33 = bitcast i64 %r32 to double
+  %r34 = icmp eq i64 %r32, 9222246136947933188
+  br i1 %r34, label %for.body.5, label %for.exit.7
+
+ss.slow.10:
+  call void @js_shadow_slot_bind(i32 1, ptr %r35)
+  br label %ss.done.14
+
+ss.chk_top.11:
+  %r84 = getelementptr inbounds i8, ptr %r82, i64 24
+  %r85 = load i64, ptr %r84
+  %r86 = icmp eq i64 %r85, -1
+  br i1 %r86, label %ss.done.14, label %ss.chk_len.12
+
+ss.chk_len.12:
+  %r87 = add i64 %r85, 1
+  %r88 = getelementptr inbounds i8, ptr %r82, i64 8
+  %r89 = load i64, ptr %r88
+  %r90 = icmp ult i64 %r87, %r89
+  br i1 %r90, label %ss.store.13, label %ss.done.14
+
+ss.store.13:
+  %r91 = load ptr, ptr %r82
+  %r92 = shl i64 %r87, 4
+  %r93 = getelementptr inbounds i8, ptr %r91, i64 %r92
+  %r94 = getelementptr inbounds i8, ptr %r93, i64 8
+  %r95 = load i64, ptr %r35
+  %r96 = ptrtoint ptr %r35 to i64
+  %r97 = and i64 %r96, 1
+  %r98 = icmp eq i64 %r97, 0
+  %r99 = select i1 %r98, i64 %r96, i64 0
+  %r100 = or i64 %r99, 1
+  store i64 %r95, ptr %r93
+  store i64 %r100, ptr %r94
+  %r101 = load atomic i32, ptr @PERRY_INCREMENTAL_MARK_BARRIER_ACTIVE_COUNT seq_cst, align 4
+  %r102 = icmp ne i32 %r101, 0
+  br i1 %r102, label %ss.barrier.15, label %ss.done.14
+
+ss.done.14:
+  %r103 = load double, ptr %r35
+  %r104 = bitcast double %r103 to i64
+  %r105 = load double, ptr %r8
+  %r106 = bitcast double %r105 to i64
+  %r107 = and i64 %r106, 281474976710655
+  %r108 = sub i64 %r107, 7
+  %r109 = inttoptr i64 %r108 to ptr
+  %r110 = load i8, ptr %r109
+  %r111 = and i8 %r110, 128
+  %r112 = icmp ne i8 %r111, 0
+  br i1 %r112, label %apush.fwd.16, label %apush.nofwd.17
+
+ss.barrier.15:
+  call void @js_write_barrier_root_nanbox(i64 %r95)
+  br label %ss.done.14
+
+apush.fwd.16:
+  %r113 = call i64 @js_array_push_f64(i64 %r107, double %r103)
+  %r114 = or i64 %r113, 9222527611924643840
+  %r115 = bitcast i64 %r114 to double
+  store double %r115, ptr %r8
+  br label %apush.merge.20
+
+apush.nofwd.17:
+  %r116 = sub i64 %r107, 6
+  %r117 = inttoptr i64 %r116 to ptr
+  %r118 = load i16, ptr %r117
+  %r119 = and i16 %r118, 1031
+  %r120 = icmp eq i16 %r119, 0
+  %r121 = icmp ult i64 %r107, 4096
+  %r122 = inttoptr i64 %r107 to ptr
+  %r123 = select i1 %r121, ptr @perry_null_guard_zero, ptr %r122
+  %r124 = load i32, ptr %r123
+  %r125 = add i64 %r107, 4
+  %r126 = inttoptr i64 %r125 to ptr
+  %r127 = load i32, ptr %r126
+  %r128 = icmp ult i32 %r124, %r127
+  %r129 = and i1 %r128, %r120
+  br i1 %r129, label %apush.inbounds.18, label %apush.realloc.19
+
+apush.inbounds.18:
+  %r130 = icmp ult i64 %r107, 4096
+  %r131 = inttoptr i64 %r107 to ptr
+  %r132 = select i1 %r130, ptr @perry_null_guard_zero, ptr %r131
+  %r133 = load i32, ptr %r132
+  %r134 = zext i32 %r133 to i64
+  %r135 = shl i64 %r134, 3
+  %r136 = add i64 %r135, 8
+  %r137 = add i64 %r107, %r136
+  %r138 = inttoptr i64 %r137 to ptr
+  store double %r103, ptr %r138
+  call void @js_string_addref_if_heap_string(double %r103)
+  call void @js_gc_note_slot_layout(i64 %r107, i32 %r133, i64 %r104)
+  call void @js_write_barrier_slot(i64 %r107, i64 %r137, i64 %r104)
+  call void @js_array_note_numeric_write(i64 %r107, i64 %r104)
+  %r139 = add i32 %r133, 1
+  %r140 = inttoptr i64 %r107 to ptr
+  store i32 %r139, ptr %r140
+  br label %apush.merge.20
+
+apush.realloc.19:
+  %r141 = call i64 @js_array_push_f64(i64 %r107, double %r103)
+  %r142 = or i64 %r141, 9222527611924643840
+  %r143 = bitcast i64 %r142 to double
+  store double %r143, ptr %r8
+  br label %apush.merge.20
+
+apush.merge.20:
+  %r144 = load double, ptr %r8
+  %r145 = bitcast double %r144 to i64
+  %r146 = and i64 %r145, 281474976710655
+  %r147 = call i32 @js_array_length(i64 %r146)
+  %r148 = sitofp i32 %r147 to double
+  %r149 = load ptr, ptr %r2
+  %r150 = icmp eq ptr %r149, null
+  br i1 %r150, label %ss.slow.21, label %ss.chk_top.22
+
+ss.slow.21:
+  call void @js_shadow_slot_set(i32 1, i64 0)
+  br label %ss.done.25
+
+ss.chk_top.22:
+  %r151 = getelementptr inbounds i8, ptr %r149, i64 24
+  %r152 = load i64, ptr %r151
+  %r153 = icmp eq i64 %r152, -1
+  br i1 %r153, label %ss.done.25, label %ss.chk_len.23
+
+ss.chk_len.23:
+  %r154 = add i64 %r152, 1
+  %r155 = getelementptr inbounds i8, ptr %r149, i64 8
+  %r156 = load i64, ptr %r155
+  %r157 = icmp ult i64 %r154, %r156
+  br i1 %r157, label %ss.store.24, label %ss.done.25
+
+ss.store.24:
+  %r158 = load ptr, ptr %r149
+  %r159 = shl i64 %r154, 4
+  %r160 = getelementptr inbounds i8, ptr %r158, i64 %r159
+  %r161 = getelementptr inbounds i8, ptr %r160, i64 8
+  %r162 = load i64, ptr %r161
+  %r163 = and i64 %r162, -2
+  store i64 0, ptr %r160
+  store i64 %r163, ptr %r161
+  br label %ss.done.25
+
+ss.done.25:
+  br label %for.update.6
+
+ss.slow.26:
+  call void @js_shadow_slot_set(i32 0, i64 0)
+  br label %ss.done.30
+
+ss.chk_top.27:
+  %r170 = getelementptr inbounds i8, ptr %r168, i64 24
+  %r171 = load i64, ptr %r170
+  %r172 = icmp eq i64 %r171, -1
+  br i1 %r172, label %ss.done.30, label %ss.chk_len.28
+
+ss.chk_len.28:
+  %r173 = add i64 %r171, 0
+  %r174 = getelementptr inbounds i8, ptr %r168, i64 8
+  %r175 = load i64, ptr %r174
+  %r176 = icmp ult i64 %r173, %r175
+  br i1 %r176, label %ss.store.29, label %ss.done.30
+
+ss.store.29:
+  %r177 = load ptr, ptr %r168
+  %r178 = shl i64 %r173, 4
+  %r179 = getelementptr inbounds i8, ptr %r177, i64 %r178
+  %r180 = getelementptr inbounds i8, ptr %r179, i64 8
+  %r181 = load i64, ptr %r180
+  %r182 = and i64 %r181, -2
+  store i64 0, ptr %r179
+  store i64 %r182, ptr %r180
+  br label %ss.done.30
+
+ss.done.30:
+  %r183 = load ptr, ptr %r2
+  %r184 = icmp eq ptr %r183, null
+  br i1 %r184, label %ss.slow.31, label %ss.chk_top.32
+
+ss.slow.31:
+  call void @js_shadow_slot_set(i32 1, i64 0)
+  br label %ss.done.35
+
+ss.chk_top.32:
+  %r185 = getelementptr inbounds i8, ptr %r183, i64 24
+  %r186 = load i64, ptr %r185
+  %r187 = icmp eq i64 %r186, -1
+  br i1 %r187, label %ss.done.35, label %ss.chk_len.33
+
+ss.chk_len.33:
+  %r188 = add i64 %r186, 1
+  %r189 = getelementptr inbounds i8, ptr %r183, i64 8
+  %r190 = load i64, ptr %r189
+  %r191 = icmp ult i64 %r188, %r190
+  br i1 %r191, label %ss.store.34, label %ss.done.35
+
+ss.store.34:
+  %r192 = load ptr, ptr %r183
+  %r193 = shl i64 %r188, 4
+  %r194 = getelementptr inbounds i8, ptr %r192, i64 %r193
+  %r195 = getelementptr inbounds i8, ptr %r194, i64 8
+  %r196 = load i64, ptr %r195
+  %r197 = and i64 %r196, -2
+  store i64 0, ptr %r194
+  store i64 %r197, ptr %r195
+  br label %ss.done.35
+
+ss.done.35:
+  %shadow_pop_l_0 = load i64, ptr %r1
+  call void @js_shadow_frame_pop(i64 %shadow_pop_l_0)
+  ret double 0x7FFC000000000001
+}
+
+define double @perry_fn_batch_ts__shape(double %arg18) alwaysinline {
+entry.0:
+  %r1 = alloca i64
+  %r2 = alloca ptr
+  store ptr null, ptr %r2
+  %r3 = call ptr @js_shadow_frame_enter(i32 1)
+  store ptr %r3, ptr %r2
+  %r4 = getelementptr inbounds i8, ptr %r3, i64 24
+  %r5 = load i64, ptr %r4
+  %r6 = sub i64 %r5, 1
+  store i64 %r6, ptr %r1
+  %r7 = alloca double
+  store double %arg18, ptr %r7
+  call void @js_shadow_slot_bind(i32 0, ptr %r7)
+  %r8 = load double, ptr %r7
+  %r9 = call i64 @js_closure_alloc_singleton(ptr @perry_closure_batch_ts__7)
+  %r10 = or i64 %r9, 9222527611924643840
+  %r11 = bitcast i64 %r10 to double
+  %r12 = bitcast double %r8 to i64
+  %r13 = and i64 %r12, 281474976710655
+  %r14 = call i64 @js_validate_array_map_callback(i64 %r13, double %r11)
+  %r15 = call i64 @js_array_map(i64 %r13, i64 %r14)
+  %r16 = or i64 %r15, 9222527611924643840
+  %r17 = bitcast i64 %r16 to double
+  %shadow_pop_l_0 = load i64, ptr %r1
+  call void @js_shadow_frame_pop(i64 %shadow_pop_l_0)
+  ret double %r17
+}
+
+define double @perry_fn_batch_ts__ranked(double %arg23) alwaysinline {
+entry.0:
+  %r1 = alloca i64
+  %r2 = alloca ptr
+  store ptr null, ptr %r2
+  %r3 = call ptr @js_shadow_frame_enter(i32 2)
+  store ptr %r3, ptr %r2
+  %r4 = getelementptr inbounds i8, ptr %r3, i64 24
+  %r5 = load i64, ptr %r4
+  %r6 = sub i64 %r5, 1
+  store i64 %r6, ptr %r1
+  %r8 = alloca double
+  store double 0x7FFC000000000001, ptr %r8
+  %r7 = alloca double
+  store double %arg23, ptr %r7
+  call void @js_shadow_slot_bind(i32 0, ptr %r7)
+  %r9 = load double, ptr %r7
+  %r10 = bitcast double %r9 to i64
+  %r11 = and i64 %r10, 281474976710655
+  %r12 = call i64 @js_array_slice_values(i64 %r11, double 0.0, double 0x7FFC000000000001)
+  %r13 = or i64 %r12, 9222527611924643840
+  %r14 = bitcast i64 %r13 to double
+  store double %r14, ptr %r8
+  %r15 = load ptr, ptr %r2
+  %r16 = icmp eq ptr %r15, null
+  br i1 %r16, label %ss.slow.1, label %ss.chk_top.2
+
+ss.slow.1:
+  call void @js_shadow_slot_bind(i32 1, ptr %r8)
+  br label %ss.done.5
+
+ss.chk_top.2:
+  %r17 = getelementptr inbounds i8, ptr %r15, i64 24
+  %r18 = load i64, ptr %r17
+  %r19 = icmp eq i64 %r18, -1
+  br i1 %r19, label %ss.done.5, label %ss.chk_len.3
+
+ss.chk_len.3:
+  %r20 = add i64 %r18, 1
+  %r21 = getelementptr inbounds i8, ptr %r15, i64 8
+  %r22 = load i64, ptr %r21
+  %r23 = icmp ult i64 %r20, %r22
+  br i1 %r23, label %ss.store.4, label %ss.done.5
+
+ss.store.4:
+  %r24 = load ptr, ptr %r15
+  %r25 = shl i64 %r20, 4
+  %r26 = getelementptr inbounds i8, ptr %r24, i64 %r25
+  %r27 = getelementptr inbounds i8, ptr %r26, i64 8
+  %r28 = load i64, ptr %r8
+  %r29 = ptrtoint ptr %r8 to i64
+  %r30 = and i64 %r29, 1
+  %r31 = icmp eq i64 %r30, 0
+  %r32 = select i1 %r31, i64 %r29, i64 0
+  %r33 = or i64 %r32, 1
+  store i64 %r28, ptr %r26
+  store i64 %r33, ptr %r27
+  %r34 = load atomic i32, ptr @PERRY_INCREMENTAL_MARK_BARRIER_ACTIVE_COUNT seq_cst, align 4
+  %r35 = icmp ne i32 %r34, 0
+  br i1 %r35, label %ss.barrier.6, label %ss.done.5
+
+ss.done.5:
+  %r36 = load ptr, ptr %r2
+  %r37 = icmp eq ptr %r36, null
+  br i1 %r37, label %ss.slow.7, label %ss.chk_top.8
+
+ss.barrier.6:
+  call void @js_write_barrier_root_nanbox(i64 %r28)
+  br label %ss.done.5
+
+ss.slow.7:
+  call void @js_shadow_slot_set(i32 0, i64 0)
+  br label %ss.done.11
+
+ss.chk_top.8:
+  %r38 = getelementptr inbounds i8, ptr %r36, i64 24
+  %r39 = load i64, ptr %r38
+  %r40 = icmp eq i64 %r39, -1
+  br i1 %r40, label %ss.done.11, label %ss.chk_len.9
+
+ss.chk_len.9:
+  %r41 = add i64 %r39, 0
+  %r42 = getelementptr inbounds i8, ptr %r36, i64 8
+  %r43 = load i64, ptr %r42
+  %r44 = icmp ult i64 %r41, %r43
+  br i1 %r44, label %ss.store.10, label %ss.done.11
+
+ss.store.10:
+  %r45 = load ptr, ptr %r36
+  %r46 = shl i64 %r41, 4
+  %r47 = getelementptr inbounds i8, ptr %r45, i64 %r46
+  %r48 = getelementptr inbounds i8, ptr %r47, i64 8
+  %r49 = load i64, ptr %r48
+  %r50 = and i64 %r49, -2
+  store i64 0, ptr %r47
+  store i64 %r50, ptr %r48
+  br label %ss.done.11
+
+ss.done.11:
+  %r51 = load double, ptr %r8
+  %r52 = call i64 @js_closure_alloc_singleton(ptr @perry_closure_batch_ts__9)
+  %r53 = or i64 %r52, 9222527611924643840
+  %r54 = bitcast i64 %r53 to double
+  %r55 = bitcast double %r51 to i64
+  %r56 = and i64 %r55, 281474976710655
+  %r57 = call i64 @js_validate_array_comparator(double %r54)
+  %r58 = call i64 @js_array_sort_with_comparator(i64 %r56, i64 %r57)
+  %r59 = or i64 %r58, 9222527611924643840
+  %r60 = bitcast i64 %r59 to double
+  %r61 = load double, ptr %r8
+  %shadow_pop_l_0 = load i64, ptr %r1
+  call void @js_shadow_frame_pop(i64 %shadow_pop_l_0)
+  ret double %r61
+}
+
+define double @perry_fn_batch_ts__summarize(double %arg27) alwaysinline {
+entry.0:
+  %r1 = alloca i64
+  %r2 = alloca ptr
+  store ptr null, ptr %r2
+  %r3 = call ptr @js_shadow_frame_enter(i32 3)
+  store ptr %r3, ptr %r2
+  %r4 = getelementptr inbounds i8, ptr %r3, i64 24
+  %r5 = load i64, ptr %r4
+  %r6 = sub i64 %r5, 1
+  store i64 %r6, ptr %r1
+  %r8 = alloca double
+  store double 0x7FFC000000000001, ptr %r8
+  %r33 = alloca i32
+  store i32 0, ptr %r33
+  %r67 = alloca double
+  store double 0x7FFC000000000001, ptr %r67
+  %r130 = alloca i64
+  %r131 = load i64, ptr @perry_class_keys_batch_ts____AnonShape_c33c4204c28b9430
+  store i64 %r131, ptr %r130
+  %r7 = alloca double
+  store double %arg27, ptr %r7
+  call void @js_shadow_slot_bind(i32 0, ptr %r7)
+  %r9 = call i64 @js_array_alloc(i32 0)
+  %r10 = or i64 %r9, 9222527611924643840
+  %r11 = bitcast i64 %r10 to double
+  store double %r11, ptr %r8
+  %r12 = load ptr, ptr %r2
+  %r13 = icmp eq ptr %r12, null
+  br i1 %r13, label %ss.slow.1, label %ss.chk_top.2
+
+ss.slow.1:
+  call void @js_shadow_slot_bind(i32 1, ptr %r8)
+  br label %ss.done.5
+
+ss.chk_top.2:
+  %r14 = getelementptr inbounds i8, ptr %r12, i64 24
+  %r15 = load i64, ptr %r14
+  %r16 = icmp eq i64 %r15, -1
+  br i1 %r16, label %ss.done.5, label %ss.chk_len.3
+
+ss.chk_len.3:
+  %r17 = add i64 %r15, 1
+  %r18 = getelementptr inbounds i8, ptr %r12, i64 8
+  %r19 = load i64, ptr %r18
+  %r20 = icmp ult i64 %r17, %r19
+  br i1 %r20, label %ss.store.4, label %ss.done.5
+
+ss.store.4:
+  %r21 = load ptr, ptr %r12
+  %r22 = shl i64 %r17, 4
+  %r23 = getelementptr inbounds i8, ptr %r21, i64 %r22
+  %r24 = getelementptr inbounds i8, ptr %r23, i64 8
+  %r25 = load i64, ptr %r8
+  %r26 = ptrtoint ptr %r8 to i64
+  %r27 = and i64 %r26, 1
+  %r28 = icmp eq i64 %r27, 0
+  %r29 = select i1 %r28, i64 %r26, i64 0
+  %r30 = or i64 %r29, 1
+  store i64 %r25, ptr %r23
+  store i64 %r30, ptr %r24
+  %r31 = load atomic i32, ptr @PERRY_INCREMENTAL_MARK_BARRIER_ACTIVE_COUNT seq_cst, align 4
+  %r32 = icmp ne i32 %r31, 0
+  br i1 %r32, label %ss.barrier.6, label %ss.done.5
+
+ss.done.5:
+  store i32 0, ptr %r33
+  br label %for.cond.7
+
+ss.barrier.6:
+  call void @js_write_barrier_root_nanbox(i64 %r25)
+  br label %ss.done.5
+
+for.cond.7:
+  %r34 = load i32, ptr %r33
+  %r35 = sitofp i32 %r34 to double
+  %r36 = load double, ptr @perry_global_batch_ts__1
+  %r37 = bitcast double %r36 to i64
+  %r38 = and i64 %r37, 281474976710655
+  %r39 = lshr i64 %r37, 48
+  %r40 = and i64 %r39, 65533
+  %r41 = icmp eq i64 %r40, 32765
+  %r42 = icmp ugt i64 %r38, 1048575
+  %r43 = and i1 %r41, %r42
+  br i1 %r43, label %plen.check_gc.11, label %plen.slow.13
+
+for.body.8:
+  %r68 = call i32 @js_gc_temp_root_push(i64 0)
+  %r69 = load double, ptr @perry_global_batch_ts__1
+  %r70 = load i32, ptr %r33
+  %r71 = bitcast double %r69 to i64
+  %r72 = and i64 %r71, 281474976710655
+  %r73 = lshr i64 %r71, 48
+  %r74 = icmp eq i64 %r73, 32765
+  %r75 = icmp ugt i64 %r72, 1048575
+  %r76 = and i1 %r74, %r75
+  br i1 %r76, label %arr.guard.deref.18, label %arr.fallback.16
+
+for.update.9:
+  %r226 = load i32, ptr %r33
+  %r227 = add i32 %r226, 1
+  store i32 %r227, ptr %r33
+  %r228 = sitofp i32 %r226 to double
+  %r229 = sitofp i32 %r227 to double
+  br label %for.cond.7
+
+for.exit.10:
+  %r230 = load ptr, ptr %r2
+  %r231 = icmp eq ptr %r230, null
+  br i1 %r231, label %ss.slow.35, label %ss.chk_top.36
+
+plen.check_gc.11:
+  %r44 = sub i64 %r38, 8
+  %r45 = inttoptr i64 %r44 to ptr
+  %r46 = load i8, ptr %r45
+  %r47 = icmp eq i8 %r46, 1
+  %r48 = icmp eq i8 %r46, 3
+  %r49 = or i1 %r47, %r48
+  %r50 = sub i64 %r38, 7
+  %r51 = inttoptr i64 %r50 to ptr
+  %r52 = load i8, ptr %r51
+  %r53 = and i8 %r52, 128
+  %r54 = icmp eq i8 %r53, 0
+  %r55 = and i1 %r49, %r54
+  br i1 %r55, label %plen.fast.12, label %plen.slow.13
+
+plen.fast.12:
+  %r56 = icmp ult i64 %r38, 4096
+  %r57 = inttoptr i64 %r38 to ptr
+  %r58 = select i1 %r56, ptr @perry_null_guard_zero, ptr %r57
+  %r59 = load i32, ptr %r58
+  %r60 = uitofp i32 %r59 to double
+  br label %plen.merge.14
+
+plen.slow.13:
+  %r61 = call double @js_value_length_f64(double %r36)
+  br label %plen.merge.14
+
+plen.merge.14:
+  %r62 = phi double [ %r60, %plen.fast.12 ], [ %r61, %plen.slow.13 ]
+  %r63 = fcmp olt double %r35, %r62
+  %r64 = select i1 %r63, i64 9222246136947933188, i64 9222246136947933187
+  %r65 = bitcast i64 %r64 to double
+  %r66 = icmp eq i64 %r64, 9222246136947933188
+  br i1 %r66, label %for.body.8, label %for.exit.10
+
+arr.fast.15:
+  %r115 = bitcast double %r69 to i64
+  %r116 = and i64 %r115, 281474976710655
+  %r117 = zext i32 %r70 to i64
+  %r118 = shl i64 %r117, 3
+  %r119 = add i64 %r118, 8
+  %r120 = add i64 %r116, %r119
+  %r121 = inttoptr i64 %r120 to ptr
+  %r122 = load double, ptr %r121
+  %r123 = bitcast double %r122 to i64
+  %r124 = icmp eq i64 %r123, 9222246136947933200
+  %r125 = bitcast i64 9222246136947933185 to double
+  %r126 = select i1 %r124, double %r125, double %r122
+  br label %arr.merge.17
+
+arr.fallback.16:
+  %r113 = sitofp i32 %r70 to double
+  %r114 = call double @js_typed_feedback_array_index_get_fallback_boxed(i64 8450987250308612096, double %r69, double %r113)
+  br label %arr.merge.17
+
+arr.merge.17:
+  %r127 = phi double [ %r126, %arr.fast.15 ], [ %r114, %arr.fallback.16 ]
+  %r128 = bitcast double %r127 to i64
+  %r129 = call i32 @js_gc_temp_root_push(i64 %r128)
+  %r132 = load i64, ptr %r130
+  %r133 = call i64 @js_object_alloc_class_inline_keys(i32 3, i32 0, i32 4, i64 %r132)
+  %r134 = call i32 @js_gc_temp_root_push(i64 %r133)
+  %r135 = or i64 %r133, 9222527611924643840
+  %r136 = bitcast i64 %r135 to double
+  %r137 = call i64 @js_gc_temp_root_get(i32 %r129)
+  %r138 = bitcast i64 %r137 to double
+  %r139 = call double @batch_ts____AnonShape_c33c4204c28b9430_constructor(double %r136, double %r138, double 0.0, double 0.0, double 0.0)
+  %r140 = call i64 @js_gc_temp_root_get(i32 %r134)
+  %r141 = or i64 %r140, 9222527611924643840
+  %r142 = bitcast i64 %r141 to double
+  call void @js_gc_init_typed_shape_layout(i64 %r140, i32 4, ptr @perry_typed_shape_raw_f64_mask_batch_ts____AnonShape_c33c4204c28b9430, i32 1, ptr @perry_typed_shape_mask_batch_ts____AnonShape_c33c4204c28b9430, i32 1)
+  %r143 = call double @js_ctor_return_override(double %r142, double %r139, i32 0)
+  call void @js_gc_temp_root_truncate(i32 %r68)
+  store double %r143, ptr %r67
+  %r144 = load ptr, ptr %r2
+  %r145 = icmp eq ptr %r144, null
+  br i1 %r145, label %ss.slow.19, label %ss.chk_top.20
+
+arr.guard.deref.18:
+  %r77 = bitcast double %r69 to i64
+  %r78 = and i64 %r77, 281474976710655
+  %r79 = sub i64 %r78, 8
+  %r80 = inttoptr i64 %r79 to ptr
+  %r81 = load i8, ptr %r80
+  %r82 = icmp eq i8 %r81, 1
+  %r83 = sub i64 %r78, 7
+  %r84 = inttoptr i64 %r83 to ptr
+  %r85 = load i8, ptr %r84
+  %r86 = and i8 %r85, 128
+  %r87 = icmp eq i8 %r86, 0
+  %r88 = sub i64 %r78, 6
+  %r89 = inttoptr i64 %r88 to ptr
+  %r90 = load i16, ptr %r89
+  %r91 = and i16 %r90, 1024
+  %r92 = icmp eq i16 %r91, 0
+  %r93 = load volatile i8, ptr @PERRY_ARRAY_INDEX_FAST_PATH_INVALIDATED
+  %r94 = icmp eq i8 %r93, 0
+  %r95 = inttoptr i64 %r78 to ptr
+  %r96 = load i32, ptr %r95
+  %r97 = getelementptr i8, ptr %r95, i64 4
+  %r98 = load i32, ptr %r97
+  %r99 = icmp slt i32 %r70, 0
+  %r100 = icmp eq i1 %r99, false
+  %r101 = icmp ult i32 %r70, %r96
+  %r102 = icmp ule i32 %r96, 16000000
+  %r103 = icmp ule i32 %r98, 16000000
+  %r104 = icmp ule i32 %r96, %r98
+  %r105 = and i1 %r82, %r87
+  %r106 = and i1 %r105, %r92
+  %r107 = and i1 %r106, %r94
+  %r108 = and i1 %r107, %r100
+  %r109 = and i1 %r108, %r101
+  %r110 = and i1 %r109, %r102
+  %r111 = and i1 %r110, %r103
+  %r112 = and i1 %r111, %r104
+  br i1 %r112, label %arr.fast.15, label %arr.fallback.16
+
+ss.slow.19:
+  call void @js_shadow_slot_bind(i32 2, ptr %r67)
+  br label %ss.done.23
+
+ss.chk_top.20:
+  %r146 = getelementptr inbounds i8, ptr %r144, i64 24
+  %r147 = load i64, ptr %r146
+  %r148 = icmp eq i64 %r147, -1
+  br i1 %r148, label %ss.done.23, label %ss.chk_len.21
+
+ss.chk_len.21:
+  %r149 = add i64 %r147, 2
+  %r150 = getelementptr inbounds i8, ptr %r144, i64 8
+  %r151 = load i64, ptr %r150
+  %r152 = icmp ult i64 %r149, %r151
+  br i1 %r152, label %ss.store.22, label %ss.done.23
+
+ss.store.22:
+  %r153 = load ptr, ptr %r144
+  %r154 = shl i64 %r149, 4
+  %r155 = getelementptr inbounds i8, ptr %r153, i64 %r154
+  %r156 = getelementptr inbounds i8, ptr %r155, i64 8
+  %r157 = load i64, ptr %r67
+  %r158 = ptrtoint ptr %r67 to i64
+  %r159 = and i64 %r158, 1
+  %r160 = icmp eq i64 %r159, 0
+  %r161 = select i1 %r160, i64 %r158, i64 0
+  %r162 = or i64 %r161, 1
+  store i64 %r157, ptr %r155
+  store i64 %r162, ptr %r156
+  %r163 = load atomic i32, ptr @PERRY_INCREMENTAL_MARK_BARRIER_ACTIVE_COUNT seq_cst, align 4
+  %r164 = icmp ne i32 %r163, 0
+  br i1 %r164, label %ss.barrier.24, label %ss.done.23
+
+ss.done.23:
+  %r165 = load double, ptr %r67
+  %r166 = bitcast double %r165 to i64
+  %r167 = load double, ptr %r8
+  %r168 = bitcast double %r167 to i64
+  %r169 = and i64 %r168, 281474976710655
+  %r170 = sub i64 %r169, 7
+  %r171 = inttoptr i64 %r170 to ptr
+  %r172 = load i8, ptr %r171
+  %r173 = and i8 %r172, 128
+  %r174 = icmp ne i8 %r173, 0
+  br i1 %r174, label %apush.fwd.25, label %apush.nofwd.26
+
+ss.barrier.24:
+  call void @js_write_barrier_root_nanbox(i64 %r157)
+  br label %ss.done.23
+
+apush.fwd.25:
+  %r175 = call i64 @js_array_push_f64(i64 %r169, double %r165)
+  %r176 = or i64 %r175, 9222527611924643840
+  %r177 = bitcast i64 %r176 to double
+  store double %r177, ptr %r8
+  br label %apush.merge.29
+
+apush.nofwd.26:
+  %r178 = sub i64 %r169, 6
+  %r179 = inttoptr i64 %r178 to ptr
+  %r180 = load i16, ptr %r179
+  %r181 = and i16 %r180, 1031
+  %r182 = icmp eq i16 %r181, 0
+  %r183 = icmp ult i64 %r169, 4096
+  %r184 = inttoptr i64 %r169 to ptr
+  %r185 = select i1 %r183, ptr @perry_null_guard_zero, ptr %r184
+  %r186 = load i32, ptr %r185
+  %r187 = add i64 %r169, 4
+  %r188 = inttoptr i64 %r187 to ptr
+  %r189 = load i32, ptr %r188
+  %r190 = icmp ult i32 %r186, %r189
+  %r191 = and i1 %r190, %r182
+  br i1 %r191, label %apush.inbounds.27, label %apush.realloc.28
+
+apush.inbounds.27:
+  %r192 = icmp ult i64 %r169, 4096
+  %r193 = inttoptr i64 %r169 to ptr
+  %r194 = select i1 %r192, ptr @perry_null_guard_zero, ptr %r193
+  %r195 = load i32, ptr %r194
+  %r196 = zext i32 %r195 to i64
+  %r197 = shl i64 %r196, 3
+  %r198 = add i64 %r197, 8
+  %r199 = add i64 %r169, %r198
+  %r200 = inttoptr i64 %r199 to ptr
+  store double %r165, ptr %r200
+  call void @js_string_addref_if_heap_string(double %r165)
+  call void @js_gc_note_slot_layout(i64 %r169, i32 %r195, i64 %r166)
+  call void @js_write_barrier_slot(i64 %r169, i64 %r199, i64 %r166)
+  call void @js_array_note_numeric_write(i64 %r169, i64 %r166)
+  %r201 = add i32 %r195, 1
+  %r202 = inttoptr i64 %r169 to ptr
+  store i32 %r201, ptr %r202
+  br label %apush.merge.29
+
+apush.realloc.28:
+  %r203 = call i64 @js_array_push_f64(i64 %r169, double %r165)
+  %r204 = or i64 %r203, 9222527611924643840
+  %r205 = bitcast i64 %r204 to double
+  store double %r205, ptr %r8
+  br label %apush.merge.29
+
+apush.merge.29:
+  %r206 = load double, ptr %r8
+  %r207 = bitcast double %r206 to i64
+  %r208 = and i64 %r207, 281474976710655
+  %r209 = call i32 @js_array_length(i64 %r208)
+  %r210 = sitofp i32 %r209 to double
+  %r211 = load ptr, ptr %r2
+  %r212 = icmp eq ptr %r211, null
+  br i1 %r212, label %ss.slow.30, label %ss.chk_top.31
+
+ss.slow.30:
+  call void @js_shadow_slot_set(i32 2, i64 0)
+  br label %ss.done.34
+
+ss.chk_top.31:
+  %r213 = getelementptr inbounds i8, ptr %r211, i64 24
+  %r214 = load i64, ptr %r213
+  %r215 = icmp eq i64 %r214, -1
+  br i1 %r215, label %ss.done.34, label %ss.chk_len.32
+
+ss.chk_len.32:
+  %r216 = add i64 %r214, 2
+  %r217 = getelementptr inbounds i8, ptr %r211, i64 8
+  %r218 = load i64, ptr %r217
+  %r219 = icmp ult i64 %r216, %r218
+  br i1 %r219, label %ss.store.33, label %ss.done.34
+
+ss.store.33:
+  %r220 = load ptr, ptr %r211
+  %r221 = shl i64 %r216, 4
+  %r222 = getelementptr inbounds i8, ptr %r220, i64 %r221
+  %r223 = getelementptr inbounds i8, ptr %r222, i64 8
+  %r224 = load i64, ptr %r223
+  %r225 = and i64 %r224, -2
+  store i64 0, ptr %r222
+  store i64 %r225, ptr %r223
+  br label %ss.done.34
+
+ss.done.34:
+  br label %for.update.9
+
+ss.slow.35:
+  call void @js_shadow_slot_set(i32 2, i64 0)
+  br label %ss.done.39
+
+ss.chk_top.36:
+  %r232 = getelementptr inbounds i8, ptr %r230, i64 24
+  %r233 = load i64, ptr %r232
+  %r234 = icmp eq i64 %r233, -1
+  br i1 %r234, label %ss.done.39, label %ss.chk_len.37
+
+ss.chk_len.37:
+  %r235 = add i64 %r233, 2
+  %r236 = getelementptr inbounds i8, ptr %r230, i64 8
+  %r237 = load i64, ptr %r236
+  %r238 = icmp ult i64 %r235, %r237
+  br i1 %r238, label %ss.store.38, label %ss.done.39
+
+ss.store.38:
+  %r239 = load ptr, ptr %r230
+  %r240 = shl i64 %r235, 4
+  %r241 = getelementptr inbounds i8, ptr %r239, i64 %r240
+  %r242 = getelementptr inbounds i8, ptr %r241, i64 8
+  %r243 = load i64, ptr %r242
+  %r244 = and i64 %r243, -2
+  store i64 0, ptr %r241
+  store i64 %r244, ptr %r242
+  br label %ss.done.39
+
+ss.done.39:
+  %r245 = load double, ptr %r7
+  %r246 = call i64 @js_closure_alloc_singleton(ptr @perry_closure_batch_ts__11)
+  %r247 = or i64 %r246, 9222527611924643840
+  %r248 = bitcast i64 %r247 to double
+  %r249 = load double, ptr %r8
+  %r250 = bitcast double %r245 to i64
+  %r251 = and i64 %r250, 281474976710655
+  %r252 = call i64 @js_validate_array_callback(double %r248)
+  %r253 = call double @js_array_reduce(i64 %r251, i64 %r252, i32 1, double %r249)
+  %r254 = load ptr, ptr %r2
+  %r255 = icmp eq ptr %r254, null
+  br i1 %r255, label %ss.slow.40, label %ss.chk_top.41
+
+ss.slow.40:
+  call void @js_shadow_slot_set(i32 0, i64 0)
+  br label %ss.done.44
+
+ss.chk_top.41:
+  %r256 = getelementptr inbounds i8, ptr %r254, i64 24
+  %r257 = load i64, ptr %r256
+  %r258 = icmp eq i64 %r257, -1
+  br i1 %r258, label %ss.done.44, label %ss.chk_len.42
+
+ss.chk_len.42:
+  %r259 = add i64 %r257, 0
+  %r260 = getelementptr inbounds i8, ptr %r254, i64 8
+  %r261 = load i64, ptr %r260
+  %r262 = icmp ult i64 %r259, %r261
+  br i1 %r262, label %ss.store.43, label %ss.done.44
+
+ss.store.43:
+  %r263 = load ptr, ptr %r254
+  %r264 = shl i64 %r259, 4
+  %r265 = getelementptr inbounds i8, ptr %r263, i64 %r264
+  %r266 = getelementptr inbounds i8, ptr %r265, i64 8
+  %r267 = load i64, ptr %r266
+  %r268 = and i64 %r267, -2
+  store i64 0, ptr %r265
+  store i64 %r268, ptr %r266
+  br label %ss.done.44
+
+ss.done.44:
+  %r269 = load double, ptr %r8
+  %shadow_pop_l_0 = load i64, ptr %r1
+  call void @js_shadow_frame_pop(i64 %shadow_pop_l_0)
+  ret double %r269
+}
+
+define double @perry_fn_batch_ts__totalsRow(double %arg39) alwaysinline {
+entry.0:
+  %r1 = alloca i64
+  %r2 = alloca ptr
+  store ptr null, ptr %r2
+  %r3 = call ptr @js_shadow_frame_enter(i32 2)
+  store ptr %r3, ptr %r2
+  %r4 = getelementptr inbounds i8, ptr %r3, i64 24
+  %r5 = load i64, ptr %r4
+  %r6 = sub i64 %r5, 1
+  store i64 %r6, ptr %r1
+  %r8 = alloca double
+  store double 0x7FFC000000000001, ptr %r8
+  %r11 = alloca i64
+  %r12 = load i64, ptr @perry_class_keys_batch_ts__Row
+  store i64 %r12, ptr %r11
+  %r45 = alloca i32
+  store i32 0, ptr %r45
+  %r73 = alloca double
+  %r76 = alloca i32
+  %r7 = alloca double
+  store double %arg39, ptr %r7
+  call void @js_shadow_slot_bind(i32 0, ptr %r7)
+  %r9 = call i32 @js_gc_temp_root_push(i64 0)
+  %r10 = load double, ptr @batch_ts_.str.0.handle
+  %r13 = load i64, ptr %r11
+  %r14 = call i64 @js_object_alloc_class_inline_keys(i32 1, i32 0, i32 4, i64 %r13)
+  %r15 = call i32 @js_gc_temp_root_push(i64 %r14)
+  %r16 = or i64 %r14, 9222527611924643840
+  %r17 = bitcast i64 %r16 to double
+  %r18 = load double, ptr @batch_ts_.str.0.handle
+  %r19 = call double @batch_ts__Row_constructor(double %r17, double 0.0, double %r18, double 0.0)
+  %r20 = call i64 @js_gc_temp_root_get(i32 %r15)
+  %r21 = or i64 %r20, 9222527611924643840
+  %r22 = bitcast i64 %r21 to double
+  call void @js_gc_init_typed_shape_layout(i64 %r20, i32 4, ptr @perry_typed_shape_raw_f64_mask_batch_ts__Row, i32 1, ptr @perry_typed_shape_mask_batch_ts__Row, i32 1)
+  %r23 = call double @js_ctor_return_override(double %r22, double %r19, i32 0)
+  call void @js_gc_temp_root_truncate(i32 %r9)
+  store double %r23, ptr %r8
+  %r24 = load ptr, ptr %r2
+  %r25 = icmp eq ptr %r24, null
+  br i1 %r25, label %ss.slow.1, label %ss.chk_top.2
+
+ss.slow.1:
+  call void @js_shadow_slot_bind(i32 1, ptr %r8)
+  br label %ss.done.5
+
+ss.chk_top.2:
+  %r26 = getelementptr inbounds i8, ptr %r24, i64 24
+  %r27 = load i64, ptr %r26
+  %r28 = icmp eq i64 %r27, -1
+  br i1 %r28, label %ss.done.5, label %ss.chk_len.3
+
+ss.chk_len.3:
+  %r29 = add i64 %r27, 1
+  %r30 = getelementptr inbounds i8, ptr %r24, i64 8
+  %r31 = load i64, ptr %r30
+  %r32 = icmp ult i64 %r29, %r31
+  br i1 %r32, label %ss.store.4, label %ss.done.5
+
+ss.store.4:
+  %r33 = load ptr, ptr %r24
+  %r34 = shl i64 %r29, 4
+  %r35 = getelementptr inbounds i8, ptr %r33, i64 %r34
+  %r36 = getelementptr inbounds i8, ptr %r35, i64 8
+  %r37 = load i64, ptr %r8
+  %r38 = ptrtoint ptr %r8 to i64
+  %r39 = and i64 %r38, 1
+  %r40 = icmp eq i64 %r39, 0
+  %r41 = select i1 %r40, i64 %r38, i64 0
+  %r42 = or i64 %r41, 1
+  store i64 %r37, ptr %r35
+  store i64 %r42, ptr %r36
+  %r43 = load atomic i32, ptr @PERRY_INCREMENTAL_MARK_BARRIER_ACTIVE_COUNT seq_cst, align 4
+  %r44 = icmp ne i32 %r43, 0
+  br i1 %r44, label %ss.barrier.6, label %ss.done.5
+
+ss.done.5:
+  store i32 0, ptr %r45
+  %r46 = load double, ptr %r7
+  %r47 = bitcast double %r46 to i64
+  %r48 = and i64 %r47, 281474976710655
+  %r49 = lshr i64 %r47, 48
+  %r50 = and i64 %r49, 65533
+  %r51 = icmp eq i64 %r50, 32765
+  %r52 = icmp ugt i64 %r48, 1048575
+  %r53 = and i1 %r51, %r52
+  br i1 %r53, label %plen.check_gc.7, label %plen.slow.9
+
+ss.barrier.6:
+  call void @js_write_barrier_root_nanbox(i64 %r37)
+  br label %ss.done.5
+
+plen.check_gc.7:
+  %r54 = sub i64 %r48, 8
+  %r55 = inttoptr i64 %r54 to ptr
+  %r56 = load i8, ptr %r55
+  %r57 = icmp eq i8 %r56, 1
+  %r58 = icmp eq i8 %r56, 3
+  %r59 = or i1 %r57, %r58
+  %r60 = sub i64 %r48, 7
+  %r61 = inttoptr i64 %r60 to ptr
+  %r62 = load i8, ptr %r61
+  %r63 = and i8 %r62, 128
+  %r64 = icmp eq i8 %r63, 0
+  %r65 = and i1 %r59, %r64
+  br i1 %r65, label %plen.fast.8, label %plen.slow.9
+
+plen.fast.8:
+  %r66 = icmp ult i64 %r48, 4096
+  %r67 = inttoptr i64 %r48 to ptr
+  %r68 = select i1 %r66, ptr @perry_null_guard_zero, ptr %r67
+  %r69 = load i32, ptr %r68
+  %r70 = uitofp i32 %r69 to double
+  br label %plen.merge.10
+
+plen.slow.9:
+  %r71 = call double @js_value_length_f64(double %r46)
+  br label %plen.merge.10
+
+plen.merge.10:
+  %r72 = phi double [ %r70, %plen.fast.8 ], [ %r71, %plen.slow.9 ]
+  store double %r72, ptr %r73
+  %r74 = load double, ptr %r73
+  %r75 = fptosi double %r74 to i32
+  store i32 %r75, ptr %r76
+  br label %for.cond.11
+
+for.cond.11:
+  %r77 = load i32, ptr %r45
+  %r78 = load i32, ptr %r76
+  %r79 = icmp slt i32 %r77, %r78
+  br i1 %r79, label %for.body.12, label %for.exit.14
+
+for.body.12:
+  %r80 = load double, ptr %r8
+  %r81 = load double, ptr %r8
+  %r82 = bitcast double %r81 to i64
+  %r83 = and i64 %r82, 281474976710655
+  %r84 = inttoptr i64 %r83 to ptr
+  %r85 = getelementptr i8, ptr %r84, i64 32
+  %r86 = getelementptr double, ptr %r85, i64 2
+  %r87 = load double, ptr %r86
+  %r88 = bitcast double %r87 to i64
+  %r89 = call i32 @js_gc_temp_root_push(i64 %r88)
+  %r90 = load double, ptr %r7
+  %r91 = load i32, ptr %r45
+  %r92 = bitcast double %r90 to i64
+  %r93 = and i64 %r92, 281474976710655
+  %r94 = sub i64 %r93, 8
+  %r95 = inttoptr i64 %r94 to ptr
+  %r96 = load i8, ptr %r95
+  %r97 = icmp eq i8 %r96, 9
+  %r98 = sub i64 %r93, 7
+  %r99 = inttoptr i64 %r98 to ptr
+  %r100 = load i8, ptr %r99
+  %r101 = and i8 %r100, 128
+  %r102 = icmp ne i8 %r101, 0
+  %r103 = or i1 %r97, %r102
+  %r104 = sub i64 %r93, 6
+  %r105 = inttoptr i64 %r104 to ptr
+  %r106 = load i16, ptr %r105
+  %r107 = and i16 %r106, 1024
+  %r108 = icmp ne i16 %r107, 0
+  %r109 = or i1 %r103, %r108
+  br i1 %r109, label %bidx.lazy.15, label %bidx.fast.16
+
+for.update.13:
+  %r342 = load i32, ptr %r45
+  %r343 = add i32 %r342, 1
+  store i32 %r343, ptr %r45
+  %r344 = sitofp i32 %r342 to double
+  %r345 = sitofp i32 %r343 to double
+  br label %for.cond.11
+
+for.exit.14:
+  %r346 = load ptr, ptr %r2
+  %r347 = icmp eq ptr %r346, null
+  br i1 %r347, label %ss.slow.53, label %ss.chk_top.54
+
+bidx.lazy.15:
+  %r110 = call double @js_array_get_f64(i64 %r93, i32 %r91)
+  br label %bidx.merge.17
+
+bidx.fast.16:
+  %r111 = zext i32 %r91 to i64
+  %r112 = shl i64 %r111, 3
+  %r113 = add i64 %r112, 8
+  %r114 = add i64 %r93, %r113
+  %r115 = inttoptr i64 %r114 to ptr
+  %r116 = load double, ptr %r115
+  %r117 = bitcast double %r116 to i64
+  %r118 = icmp eq i64 %r117, 9222246136947933200
+  %r119 = bitcast i64 9222246136947933185 to double
+  %r120 = select i1 %r118, double %r119, double %r116
+  br label %bidx.merge.17
+
+bidx.merge.17:
+  %r121 = phi double [ %r120, %bidx.fast.16 ], [ %r110, %bidx.lazy.15 ]
+  %r122 = bitcast double %r121 to i64
+  %r123 = and i64 %r122, 281474976710655
+  %r124 = load double, ptr @batch_ts_.str.1.handle
+  %r125 = bitcast double %r124 to i64
+  %r126 = and i64 %r125, 281474976710655
+  %r127 = lshr i64 %r122, 48
+  %r128 = icmp eq i64 %r127, 32761
+  %r129 = icmp eq i64 %r127, 32766
+  %r130 = and i64 %r127, 65533
+  %r131 = icmp eq i64 %r130, 32765
+  br i1 %r128, label %pget.recv_sso.18, label %pget.check_class_ref.24
+
+pget.recv_sso.18:
+  %r195 = call double @js_object_get_field_by_name_f64(i64 %r122, i64 %r126)
+  br label %pget.recv_merge.22
+
+pget.recv_ok.19:
+  call void @js_typed_feedback_observe_property_get(i64 8450987250308612097, i64 %r123, i64 %r126)
+  %r133 = icmp ugt i64 %r123, 1048575
+  %r134 = ptrtoint ptr @perry_ic_2 to i64
+  %r135 = select i1 %r133, i64 %r123, i64 %r134
+  %r136 = sub i64 %r135, 8
+  %r137 = inttoptr i64 %r136 to ptr
+  %r138 = load i8, ptr %r137
+  %r139 = icmp eq i8 %r138, 2
+  %r140 = and i1 %r133, %r139
+  %r141 = add i64 %r135, 12
+  %r142 = inttoptr i64 %r141 to ptr
+  %r143 = load i32, ptr %r142
+  %r144 = icmp eq i32 %r143, 1129268819
+  %r145 = xor i1 %r144, true
+  %r146 = and i1 %r140, %r145
+  %r147 = inttoptr i64 %r135 to ptr
+  %r148 = load i32, ptr %r147
+  %r149 = icmp eq i32 %r148, 1
+  %r150 = and i1 %r146, %r149
+  %r151 = sub i64 %r135, 6
+  %r152 = inttoptr i64 %r151 to ptr
+  %r153 = load i16, ptr %r152
+  %r154 = and i16 %r153, 2048
+  %r155 = icmp eq i16 %r154, 0
+  %r156 = and i1 %r150, %r155
+  %r157 = add i64 %r135, 16
+  %r158 = inttoptr i64 %r157 to ptr
+  %r159 = load i64, ptr %r158
+  %r160 = add i64 %r135, 8
+  %r161 = inttoptr i64 %r160 to ptr
+  %r162 = load i32, ptr %r161
+  %r163 = add i32 %r162, -2147483648
+  %r164 = icmp ult i32 %r163, 1073741824
+  %r165 = zext i32 %r162 to i64
+  %r166 = or i64 %r165, 4611686018427387904
+  %r167 = select i1 %r164, i64 %r166, i64 %r159
+  %r168 = getelementptr i64, ptr @perry_ic_2, i64 0
+  %r169 = load i64, ptr %r168
+  %r170 = icmp eq i64 %r167, %r169
+  %r171 = icmp ne i64 %r167, 0
+  %r172 = and i1 %r156, %r170
+  %r173 = and i1 %r172, %r171
+  br i1 %r173, label %pic.hit.25, label %pic.miss.26
+
+pget.recv_bad.20:
+  %r190 = icmp eq i64 %r122, 9222246136947933185
+  %r191 = icmp eq i64 %r122, 9222246136947933186
+  %r192 = or i1 %r190, %r191
+  br i1 %r192, label %pget.throw_nullish.29, label %pget.recv_undef_return.30
+
+pget.recv_class_ref.21:
+  %r132 = call double @js_typed_feedback_object_get_field_by_name_f64(i64 8450987250308612097, i64 %r122, i64 %r126)
+  br label %pget.recv_merge.22
+
+pget.recv_merge.22:
+  %r196 = phi double [ %r189, %pic.merge.27 ], [ %r194, %pget.recv_undef_return.30 ], [ %r195, %pget.recv_sso.18 ], [ %r132, %pget.recv_class_ref.21 ]
+  %r197 = call i64 @js_gc_temp_root_get(i32 %r89)
+  %r198 = bitcast i64 %r197 to double
+  %r199 = call double @js_dynamic_string_or_number_add(double %r198, double %r196)
+  call void @js_gc_temp_root_truncate(i32 %r89)
+  %r200 = bitcast double %r80 to i64
+  %r201 = and i64 %r200, 281474976710655
+  %r202 = inttoptr i64 %r201 to ptr
+  %r203 = getelementptr i8, ptr %r202, i64 32
+  %r204 = getelementptr double, ptr %r203, i64 2
+  %r205 = bitcast double %r199 to i64
+  %r206 = and i64 %r205, 9218868437227405312
+  %r207 = icmp ne i64 %r206, 9218868437227405312
+  br i1 %r207, label %ptr_shape_set.raw_store.31, label %ptr_shape_set.downgrade.32
+
+pget.check_ptr.23:
+  br i1 %r131, label %pget.recv_ok.19, label %pget.recv_bad.20
+
+pget.check_class_ref.24:
+  br i1 %r129, label %pget.recv_class_ref.21, label %pget.check_ptr.23
+
+pic.hit.25:
+  %r174 = getelementptr i64, ptr @perry_ic_2, i64 1
+  %r175 = load i64, ptr %r174
+  %r176 = add i64 %r135, 12
+  %r177 = inttoptr i64 %r176 to ptr
+  %r178 = load i32, ptr %r177
+  %r179 = zext i32 %r178 to i64
+  %r180 = icmp ult i64 %r179, 4
+  %r181 = select i1 %r180, i64 4, i64 %r179
+  %r182 = icmp ult i64 %r175, %r181
+  br i1 %r182, label %pic.hit.load.28, label %pic.miss.26
+
+pic.miss.26:
+  call void @js_typed_feedback_record_guard_fail(i64 8450987250308612097)
+  call void @js_typed_feedback_record_fallback_call(i64 8450987250308612097)
+  %r188 = call double @js_object_get_field_ic_miss(i64 %r123, i64 %r126, ptr @perry_ic_2)
+  br label %pic.merge.27
+
+pic.merge.27:
+  %r189 = phi double [ %r187, %pic.hit.load.28 ], [ %r188, %pic.miss.26 ]
+  br label %pget.recv_merge.22
+
+pic.hit.load.28:
+  call void @js_typed_feedback_record_guard_pass(i64 8450987250308612097)
+  %r183 = shl i64 %r175, 3
+  %r184 = add i64 %r123, 32
+  %r185 = add i64 %r184, %r183
+  %r186 = inttoptr i64 %r185 to ptr
+  %r187 = load double, ptr %r186
+  br label %pic.merge.27
+
+pget.throw_nullish.29:
+  %r193 = zext i1 %r191 to i32
+  call void @js_throw_type_error_property_access(i32 %r193, ptr @batch_ts_.str.1.bytes, i64 5)
+  unreachable
+
+pget.recv_undef_return.30:
+  %r194 = call double @js_object_get_field_by_name_f64(i64 %r122, i64 %r126)
+  br label %pget.recv_merge.22
+
+ptr_shape_set.raw_store.31:
+  store double %r199, ptr %r204
+  br label %ptr_shape_set.merge.33
+
+ptr_shape_set.downgrade.32:
+  %r208 = load double, ptr @batch_ts_.str.2.handle
+  %r209 = bitcast double %r208 to i64
+  %r210 = and i64 %r209, 281474976710655
+  call void @js_class_field_set_fallback(i64 8450987250308612099, i64 %r200, i64 %r210, double %r199)
+  br label %ptr_shape_set.merge.33
+
+ptr_shape_set.merge.33:
+  %r211 = load double, ptr %r8
+  %r212 = load double, ptr %r8
+  %r213 = bitcast double %r212 to i64
+  %r214 = and i64 %r213, 281474976710655
+  %r215 = inttoptr i64 %r214 to ptr
+  %r216 = getelementptr i8, ptr %r215, i64 32
+  %r217 = getelementptr double, ptr %r216, i64 3
+  %r218 = load double, ptr %r217
+  %r219 = bitcast double %r218 to i64
+  %r220 = call i32 @js_gc_temp_root_push(i64 %r219)
+  %r221 = load double, ptr %r7
+  %r222 = load i32, ptr %r45
+  %r223 = bitcast double %r221 to i64
+  %r224 = and i64 %r223, 281474976710655
+  %r225 = sub i64 %r224, 8
+  %r226 = inttoptr i64 %r225 to ptr
+  %r227 = load i8, ptr %r226
+  %r228 = icmp eq i8 %r227, 9
+  %r229 = sub i64 %r224, 7
+  %r230 = inttoptr i64 %r229 to ptr
+  %r231 = load i8, ptr %r230
+  %r232 = and i8 %r231, 128
+  %r233 = icmp ne i8 %r232, 0
+  %r234 = or i1 %r228, %r233
+  %r235 = sub i64 %r224, 6
+  %r236 = inttoptr i64 %r235 to ptr
+  %r237 = load i16, ptr %r236
+  %r238 = and i16 %r237, 1024
+  %r239 = icmp ne i16 %r238, 0
+  %r240 = or i1 %r234, %r239
+  br i1 %r240, label %bidx.lazy.34, label %bidx.fast.35
+
+bidx.lazy.34:
+  %r241 = call double @js_array_get_f64(i64 %r224, i32 %r222)
+  br label %bidx.merge.36
+
+bidx.fast.35:
+  %r242 = zext i32 %r222 to i64
+  %r243 = shl i64 %r242, 3
+  %r244 = add i64 %r243, 8
+  %r245 = add i64 %r224, %r244
+  %r246 = inttoptr i64 %r245 to ptr
+  %r247 = load double, ptr %r246
+  %r248 = bitcast double %r247 to i64
+  %r249 = icmp eq i64 %r248, 9222246136947933200
+  %r250 = bitcast i64 9222246136947933185 to double
+  %r251 = select i1 %r249, double %r250, double %r247
+  br label %bidx.merge.36
+
+bidx.merge.36:
+  %r252 = phi double [ %r251, %bidx.fast.35 ], [ %r241, %bidx.lazy.34 ]
+  %r253 = bitcast double %r252 to i64
+  %r254 = and i64 %r253, 281474976710655
+  %r255 = load double, ptr @batch_ts_.str.3.handle
+  %r256 = bitcast double %r255 to i64
+  %r257 = and i64 %r256, 281474976710655
+  %r258 = lshr i64 %r253, 48
+  %r259 = icmp eq i64 %r258, 32761
+  %r260 = icmp eq i64 %r258, 32766
+  %r261 = and i64 %r258, 65533
+  %r262 = icmp eq i64 %r261, 32765
+  br i1 %r259, label %pget.recv_sso.37, label %pget.check_class_ref.43
+
+pget.recv_sso.37:
+  %r326 = call double @js_object_get_field_by_name_f64(i64 %r253, i64 %r257)
+  br label %pget.recv_merge.41
+
+pget.recv_ok.38:
+  call void @js_typed_feedback_observe_property_get(i64 8450987250308612100, i64 %r254, i64 %r257)
+  %r264 = icmp ugt i64 %r254, 1048575
+  %r265 = ptrtoint ptr @perry_ic_5 to i64
+  %r266 = select i1 %r264, i64 %r254, i64 %r265
+  %r267 = sub i64 %r266, 8
+  %r268 = inttoptr i64 %r267 to ptr
+  %r269 = load i8, ptr %r268
+  %r270 = icmp eq i8 %r269, 2
+  %r271 = and i1 %r264, %r270
+  %r272 = add i64 %r266, 12
+  %r273 = inttoptr i64 %r272 to ptr
+  %r274 = load i32, ptr %r273
+  %r275 = icmp eq i32 %r274, 1129268819
+  %r276 = xor i1 %r275, true
+  %r277 = and i1 %r271, %r276
+  %r278 = inttoptr i64 %r266 to ptr
+  %r279 = load i32, ptr %r278
+  %r280 = icmp eq i32 %r279, 1
+  %r281 = and i1 %r277, %r280
+  %r282 = sub i64 %r266, 6
+  %r283 = inttoptr i64 %r282 to ptr
+  %r284 = load i16, ptr %r283
+  %r285 = and i16 %r284, 2048
+  %r286 = icmp eq i16 %r285, 0
+  %r287 = and i1 %r281, %r286
+  %r288 = add i64 %r266, 16
+  %r289 = inttoptr i64 %r288 to ptr
+  %r290 = load i64, ptr %r289
+  %r291 = add i64 %r266, 8
+  %r292 = inttoptr i64 %r291 to ptr
+  %r293 = load i32, ptr %r292
+  %r294 = add i32 %r293, -2147483648
+  %r295 = icmp ult i32 %r294, 1073741824
+  %r296 = zext i32 %r293 to i64
+  %r297 = or i64 %r296, 4611686018427387904
+  %r298 = select i1 %r295, i64 %r297, i64 %r290
+  %r299 = getelementptr i64, ptr @perry_ic_5, i64 0
+  %r300 = load i64, ptr %r299
+  %r301 = icmp eq i64 %r298, %r300
+  %r302 = icmp ne i64 %r298, 0
+  %r303 = and i1 %r287, %r301
+  %r304 = and i1 %r303, %r302
+  br i1 %r304, label %pic.hit.44, label %pic.miss.45
+
+pget.recv_bad.39:
+  %r321 = icmp eq i64 %r253, 9222246136947933185
+  %r322 = icmp eq i64 %r253, 9222246136947933186
+  %r323 = or i1 %r321, %r322
+  br i1 %r323, label %pget.throw_nullish.48, label %pget.recv_undef_return.49
+
+pget.recv_class_ref.40:
+  %r263 = call double @js_typed_feedback_object_get_field_by_name_f64(i64 8450987250308612100, i64 %r253, i64 %r257)
+  br label %pget.recv_merge.41
+
+pget.recv_merge.41:
+  %r327 = phi double [ %r320, %pic.merge.46 ], [ %r325, %pget.recv_undef_return.49 ], [ %r326, %pget.recv_sso.37 ], [ %r263, %pget.recv_class_ref.40 ]
+  %r328 = call i64 @js_gc_temp_root_get(i32 %r220)
+  %r329 = bitcast i64 %r328 to double
+  %r330 = call double @js_dynamic_string_or_number_add(double %r329, double %r327)
+  call void @js_gc_temp_root_truncate(i32 %r220)
+  %r331 = bitcast double %r211 to i64
+  %r332 = and i64 %r331, 281474976710655
+  %r333 = inttoptr i64 %r332 to ptr
+  %r334 = getelementptr i8, ptr %r333, i64 32
+  %r335 = getelementptr double, ptr %r334, i64 3
+  %r336 = bitcast double %r330 to i64
+  %r337 = and i64 %r336, 9218868437227405312
+  %r338 = icmp ne i64 %r337, 9218868437227405312
+  br i1 %r338, label %ptr_shape_set.raw_store.50, label %ptr_shape_set.downgrade.51
+
+pget.check_ptr.42:
+  br i1 %r262, label %pget.recv_ok.38, label %pget.recv_bad.39
+
+pget.check_class_ref.43:
+  br i1 %r260, label %pget.recv_class_ref.40, label %pget.check_ptr.42
+
+pic.hit.44:
+  %r305 = getelementptr i64, ptr @perry_ic_5, i64 1
+  %r306 = load i64, ptr %r305
+  %r307 = add i64 %r266, 12
+  %r308 = inttoptr i64 %r307 to ptr
+  %r309 = load i32, ptr %r308
+  %r310 = zext i32 %r309 to i64
+  %r311 = icmp ult i64 %r310, 4
+  %r312 = select i1 %r311, i64 4, i64 %r310
+  %r313 = icmp ult i64 %r306, %r312
+  br i1 %r313, label %pic.hit.load.47, label %pic.miss.45
+
+pic.miss.45:
+  call void @js_typed_feedback_record_guard_fail(i64 8450987250308612100)
+  call void @js_typed_feedback_record_fallback_call(i64 8450987250308612100)
+  %r319 = call double @js_object_get_field_ic_miss(i64 %r254, i64 %r257, ptr @perry_ic_5)
+  br label %pic.merge.46
+
+pic.merge.46:
+  %r320 = phi double [ %r318, %pic.hit.load.47 ], [ %r319, %pic.miss.45 ]
+  br label %pget.recv_merge.41
+
+pic.hit.load.47:
+  call void @js_typed_feedback_record_guard_pass(i64 8450987250308612100)
+  %r314 = shl i64 %r306, 3
+  %r315 = add i64 %r254, 32
+  %r316 = add i64 %r315, %r314
+  %r317 = inttoptr i64 %r316 to ptr
+  %r318 = load double, ptr %r317
+  br label %pic.merge.46
+
+pget.throw_nullish.48:
+  %r324 = zext i1 %r322 to i32
+  call void @js_throw_type_error_property_access(i32 %r324, ptr @batch_ts_.str.3.bytes, i64 4)
+  unreachable
+
+pget.recv_undef_return.49:
+  %r325 = call double @js_object_get_field_by_name_f64(i64 %r253, i64 %r257)
+  br label %pget.recv_merge.41
+
+ptr_shape_set.raw_store.50:
+  store double %r330, ptr %r335
+  br label %ptr_shape_set.merge.52
+
+ptr_shape_set.downgrade.51:
+  %r339 = load double, ptr @batch_ts_.str.4.handle
+  %r340 = bitcast double %r339 to i64
+  %r341 = and i64 %r340, 281474976710655
+  call void @js_class_field_set_fallback(i64 8450987250308612102, i64 %r331, i64 %r341, double %r330)
+  br label %ptr_shape_set.merge.52
+
+ptr_shape_set.merge.52:
+  br label %for.update.13
+
+ss.slow.53:
+  call void @js_shadow_slot_set(i32 0, i64 0)
+  br label %ss.done.57
+
+ss.chk_top.54:
+  %r348 = getelementptr inbounds i8, ptr %r346, i64 24
+  %r349 = load i64, ptr %r348
+  %r350 = icmp eq i64 %r349, -1
+  br i1 %r350, label %ss.done.57, label %ss.chk_len.55
+
+ss.chk_len.55:
+  %r351 = add i64 %r349, 0
+  %r352 = getelementptr inbounds i8, ptr %r346, i64 8
+  %r353 = load i64, ptr %r352
+  %r354 = icmp ult i64 %r351, %r353
+  br i1 %r354, label %ss.store.56, label %ss.done.57
+
+ss.store.56:
+  %r355 = load ptr, ptr %r346
+  %r356 = shl i64 %r351, 4
+  %r357 = getelementptr inbounds i8, ptr %r355, i64 %r356
+  %r358 = getelementptr inbounds i8, ptr %r357, i64 8
+  %r359 = load i64, ptr %r358
+  %r360 = and i64 %r359, -2
+  store i64 0, ptr %r357
+  store i64 %r360, ptr %r358
+  br label %ss.done.57
+
+ss.done.57:
+  %r361 = load double, ptr %r8
+  %shadow_pop_l_0 = load i64, ptr %r1
+  call void @js_shadow_frame_pop(i64 %shadow_pop_l_0)
+  ret double %r361
+}
+
+define double @perry_closure_batch_ts__7(i64 %this_closure, double %arg19) {
+entry.0:
+  %r1 = alloca i64
+  %r2 = alloca ptr
+  store ptr null, ptr %r2
+  %r3 = call ptr @js_shadow_frame_enter(i32 1)
+  store ptr %r3, ptr %r2
+  %r4 = getelementptr inbounds i8, ptr %r3, i64 24
+  %r5 = load i64, ptr %r4
+  %r6 = sub i64 %r5, 1
+  store i64 %r6, ptr %r1
+  %r174 = alloca [1 x double]
+  %r191 = alloca i64
+  %r192 = load i64, ptr @perry_class_keys_batch_ts__Row
+  store i64 %r192, ptr %r191
+  %r219 = alloca [1 x double]
+  %r313 = alloca i64
+  %r314 = load i64, ptr @perry_class_keys_batch_ts____AnonShape_e75d7e32e87dc826
+  store i64 %r314, ptr %r313
+  %r7 = alloca double
+  store double %arg19, ptr %r7
+  call void @js_shadow_slot_bind(i32 0, ptr %r7)
+  %r8 = call i32 @js_gc_temp_root_push(i64 0)
+  %r9 = load double, ptr %r7
+  %r10 = bitcast double %r9 to i64
+  %r11 = and i64 %r10, 281474976710655
+  %r12 = load double, ptr @batch_ts_.str.5.handle
+  %r13 = bitcast double %r12 to i64
+  %r14 = and i64 %r13, 281474976710655
+  %r15 = lshr i64 %r10, 48
+  %r16 = icmp eq i64 %r15, 32761
+  %r17 = icmp eq i64 %r15, 32766
+  %r18 = and i64 %r15, 65533
+  %r19 = icmp eq i64 %r18, 32765
+  br i1 %r16, label %pget.recv_sso.1, label %pget.check_class_ref.7
+
+pget.recv_sso.1:
+  %r83 = call double @js_object_get_field_by_name_f64(i64 %r10, i64 %r14)
+  br label %pget.recv_merge.5
+
+pget.recv_ok.2:
+  call void @js_typed_feedback_observe_property_get(i64 8450987250308612103, i64 %r11, i64 %r14)
+  %r21 = icmp ugt i64 %r11, 1048575
+  %r22 = ptrtoint ptr @perry_ic_8 to i64
+  %r23 = select i1 %r21, i64 %r11, i64 %r22
+  %r24 = sub i64 %r23, 8
+  %r25 = inttoptr i64 %r24 to ptr
+  %r26 = load i8, ptr %r25
+  %r27 = icmp eq i8 %r26, 2
+  %r28 = and i1 %r21, %r27
+  %r29 = add i64 %r23, 12
+  %r30 = inttoptr i64 %r29 to ptr
+  %r31 = load i32, ptr %r30
+  %r32 = icmp eq i32 %r31, 1129268819
+  %r33 = xor i1 %r32, true
+  %r34 = and i1 %r28, %r33
+  %r35 = inttoptr i64 %r23 to ptr
+  %r36 = load i32, ptr %r35
+  %r37 = icmp eq i32 %r36, 1
+  %r38 = and i1 %r34, %r37
+  %r39 = sub i64 %r23, 6
+  %r40 = inttoptr i64 %r39 to ptr
+  %r41 = load i16, ptr %r40
+  %r42 = and i16 %r41, 2048
+  %r43 = icmp eq i16 %r42, 0
+  %r44 = and i1 %r38, %r43
+  %r45 = add i64 %r23, 16
+  %r46 = inttoptr i64 %r45 to ptr
+  %r47 = load i64, ptr %r46
+  %r48 = add i64 %r23, 8
+  %r49 = inttoptr i64 %r48 to ptr
+  %r50 = load i32, ptr %r49
+  %r51 = add i32 %r50, -2147483648
+  %r52 = icmp ult i32 %r51, 1073741824
+  %r53 = zext i32 %r50 to i64
+  %r54 = or i64 %r53, 4611686018427387904
+  %r55 = select i1 %r52, i64 %r54, i64 %r47
+  %r56 = getelementptr i64, ptr @perry_ic_8, i64 0
+  %r57 = load i64, ptr %r56
+  %r58 = icmp eq i64 %r55, %r57
+  %r59 = icmp ne i64 %r55, 0
+  %r60 = and i1 %r44, %r58
+  %r61 = and i1 %r60, %r59
+  br i1 %r61, label %pic.hit.8, label %pic.miss.9
+
+pget.recv_bad.3:
+  %r78 = icmp eq i64 %r10, 9222246136947933185
+  %r79 = icmp eq i64 %r10, 9222246136947933186
+  %r80 = or i1 %r78, %r79
+  br i1 %r80, label %pget.throw_nullish.12, label %pget.recv_undef_return.13
+
+pget.recv_class_ref.4:
+  %r20 = call double @js_typed_feedback_object_get_field_by_name_f64(i64 8450987250308612103, i64 %r10, i64 %r14)
+  br label %pget.recv_merge.5
+
+pget.recv_merge.5:
+  %r84 = phi double [ %r77, %pic.merge.10 ], [ %r82, %pget.recv_undef_return.13 ], [ %r83, %pget.recv_sso.1 ], [ %r20, %pget.recv_class_ref.4 ]
+  %r85 = load double, ptr @batch_ts_.str.6.handle
+  %r86 = call double @js_dynamic_string_or_number_add(double %r84, double %r85)
+  %r87 = bitcast double %r86 to i64
+  %r88 = call i32 @js_gc_temp_root_push(i64 %r87)
+  %r89 = load double, ptr %r7
+  %r90 = bitcast double %r89 to i64
+  %r91 = and i64 %r90, 281474976710655
+  %r92 = load double, ptr @batch_ts_.str.7.handle
+  %r93 = bitcast double %r92 to i64
+  %r94 = and i64 %r93, 281474976710655
+  %r95 = lshr i64 %r90, 48
+  %r96 = icmp eq i64 %r95, 32761
+  %r97 = icmp eq i64 %r95, 32766
+  %r98 = and i64 %r95, 65533
+  %r99 = icmp eq i64 %r98, 32765
+  br i1 %r96, label %pget.recv_sso.14, label %pget.check_class_ref.20
+
+pget.check_ptr.6:
+  br i1 %r19, label %pget.recv_ok.2, label %pget.recv_bad.3
+
+pget.check_class_ref.7:
+  br i1 %r17, label %pget.recv_class_ref.4, label %pget.check_ptr.6
+
+pic.hit.8:
+  %r62 = getelementptr i64, ptr @perry_ic_8, i64 1
+  %r63 = load i64, ptr %r62
+  %r64 = add i64 %r23, 12
+  %r65 = inttoptr i64 %r64 to ptr
+  %r66 = load i32, ptr %r65
+  %r67 = zext i32 %r66 to i64
+  %r68 = icmp ult i64 %r67, 4
+  %r69 = select i1 %r68, i64 4, i64 %r67
+  %r70 = icmp ult i64 %r63, %r69
+  br i1 %r70, label %pic.hit.load.11, label %pic.miss.9
+
+pic.miss.9:
+  call void @js_typed_feedback_record_guard_fail(i64 8450987250308612103)
+  call void @js_typed_feedback_record_fallback_call(i64 8450987250308612103)
+  %r76 = call double @js_object_get_field_ic_miss(i64 %r11, i64 %r14, ptr @perry_ic_8)
+  br label %pic.merge.10
+
+pic.merge.10:
+  %r77 = phi double [ %r75, %pic.hit.load.11 ], [ %r76, %pic.miss.9 ]
+  br label %pget.recv_merge.5
+
+pic.hit.load.11:
+  call void @js_typed_feedback_record_guard_pass(i64 8450987250308612103)
+  %r71 = shl i64 %r63, 3
+  %r72 = add i64 %r11, 32
+  %r73 = add i64 %r72, %r71
+  %r74 = inttoptr i64 %r73 to ptr
+  %r75 = load double, ptr %r74
+  br label %pic.merge.10
+
+pget.throw_nullish.12:
+  %r81 = zext i1 %r79 to i32
+  call void @js_throw_type_error_property_access(i32 %r81, ptr @batch_ts_.str.5.bytes, i64 6)
+  unreachable
+
+pget.recv_undef_return.13:
+  %r82 = call double @js_object_get_field_by_name_f64(i64 %r10, i64 %r14)
+  br label %pget.recv_merge.5
+
+pget.recv_sso.14:
+  %r163 = call double @js_object_get_field_by_name_f64(i64 %r90, i64 %r94)
+  br label %pget.recv_merge.18
+
+pget.recv_ok.15:
+  call void @js_typed_feedback_observe_property_get(i64 8450987250308612105, i64 %r91, i64 %r94)
+  %r101 = icmp ugt i64 %r91, 1048575
+  %r102 = ptrtoint ptr @perry_ic_10 to i64
+  %r103 = select i1 %r101, i64 %r91, i64 %r102
+  %r104 = sub i64 %r103, 8
+  %r105 = inttoptr i64 %r104 to ptr
+  %r106 = load i8, ptr %r105
+  %r107 = icmp eq i8 %r106, 2
+  %r108 = and i1 %r101, %r107
+  %r109 = add i64 %r103, 12
+  %r110 = inttoptr i64 %r109 to ptr
+  %r111 = load i32, ptr %r110
+  %r112 = icmp eq i32 %r111, 1129268819
+  %r113 = xor i1 %r112, true
+  %r114 = and i1 %r108, %r113
+  %r115 = inttoptr i64 %r103 to ptr
+  %r116 = load i32, ptr %r115
+  %r117 = icmp eq i32 %r116, 1
+  %r118 = and i1 %r114, %r117
+  %r119 = sub i64 %r103, 6
+  %r120 = inttoptr i64 %r119 to ptr
+  %r121 = load i16, ptr %r120
+  %r122 = and i16 %r121, 2048
+  %r123 = icmp eq i16 %r122, 0
+  %r124 = and i1 %r118, %r123
+  %r125 = add i64 %r103, 16
+  %r126 = inttoptr i64 %r125 to ptr
+  %r127 = load i64, ptr %r126
+  %r128 = add i64 %r103, 8
+  %r129 = inttoptr i64 %r128 to ptr
+  %r130 = load i32, ptr %r129
+  %r131 = add i32 %r130, -2147483648
+  %r132 = icmp ult i32 %r131, 1073741824
+  %r133 = zext i32 %r130 to i64
+  %r134 = or i64 %r133, 4611686018427387904
+  %r135 = select i1 %r132, i64 %r134, i64 %r127
+  %r136 = getelementptr i64, ptr @perry_ic_10, i64 0
+  %r137 = load i64, ptr %r136
+  %r138 = icmp eq i64 %r135, %r137
+  %r139 = icmp ne i64 %r135, 0
+  %r140 = and i1 %r124, %r138
+  %r141 = and i1 %r140, %r139
+  br i1 %r141, label %pic.hit.21, label %pic.miss.22
+
+pget.recv_bad.16:
+  %r158 = icmp eq i64 %r90, 9222246136947933185
+  %r159 = icmp eq i64 %r90, 9222246136947933186
+  %r160 = or i1 %r158, %r159
+  br i1 %r160, label %pget.throw_nullish.25, label %pget.recv_undef_return.26
+
+pget.recv_class_ref.17:
+  %r100 = call double @js_typed_feedback_object_get_field_by_name_f64(i64 8450987250308612105, i64 %r90, i64 %r94)
+  br label %pget.recv_merge.18
+
+pget.recv_merge.18:
+  %r164 = phi double [ %r157, %pic.merge.23 ], [ %r162, %pget.recv_undef_return.26 ], [ %r163, %pget.recv_sso.14 ], [ %r100, %pget.recv_class_ref.17 ]
+  %r165 = call i64 @js_gc_temp_root_get(i32 %r88)
+  %r166 = bitcast i64 %r165 to double
+  %r167 = call double @js_dynamic_string_or_number_add(double %r166, double %r164)
+  call void @js_gc_temp_root_truncate(i32 %r88)
+  %r168 = bitcast double %r167 to i64
+  %r169 = call i32 @js_gc_temp_root_push(i64 %r168)
+  %r170 = load double, ptr %r7
+  %r171 = call double @js_object_get_own_field_or_undef(double %r170, ptr @batch_ts_.str.8.bytes, i64 7)
+  %r172 = bitcast double %r171 to i64
+  %r173 = icmp eq i64 %r172, 9222246136947933185
+  br i1 %r173, label %idisp.dispatch.28, label %idisp.override.27
+
+pget.check_ptr.19:
+  br i1 %r99, label %pget.recv_ok.15, label %pget.recv_bad.16
+
+pget.check_class_ref.20:
+  br i1 %r97, label %pget.recv_class_ref.17, label %pget.check_ptr.19
+
+pic.hit.21:
+  %r142 = getelementptr i64, ptr @perry_ic_10, i64 1
+  %r143 = load i64, ptr %r142
+  %r144 = add i64 %r103, 12
+  %r145 = inttoptr i64 %r144 to ptr
+  %r146 = load i32, ptr %r145
+  %r147 = zext i32 %r146 to i64
+  %r148 = icmp ult i64 %r147, 4
+  %r149 = select i1 %r148, i64 4, i64 %r147
+  %r150 = icmp ult i64 %r143, %r149
+  br i1 %r150, label %pic.hit.load.24, label %pic.miss.22
+
+pic.miss.22:
+  call void @js_typed_feedback_record_guard_fail(i64 8450987250308612105)
+  call void @js_typed_feedback_record_fallback_call(i64 8450987250308612105)
+  %r156 = call double @js_object_get_field_ic_miss(i64 %r91, i64 %r94, ptr @perry_ic_10)
+  br label %pic.merge.23
+
+pic.merge.23:
+  %r157 = phi double [ %r155, %pic.hit.load.24 ], [ %r156, %pic.miss.22 ]
+  br label %pget.recv_merge.18
+
+pic.hit.load.24:
+  call void @js_typed_feedback_record_guard_pass(i64 8450987250308612105)
+  %r151 = shl i64 %r143, 3
+  %r152 = add i64 %r91, 32
+  %r153 = add i64 %r152, %r151
+  %r154 = inttoptr i64 %r153 to ptr
+  %r155 = load double, ptr %r154
+  br label %pic.merge.23
+
+pget.throw_nullish.25:
+  %r161 = zext i1 %r159 to i32
+  call void @js_throw_type_error_property_access(i32 %r161, ptr @batch_ts_.str.7.bytes, i64 2)
+  unreachable
+
+pget.recv_undef_return.26:
+  %r162 = call double @js_object_get_field_by_name_f64(i64 %r90, i64 %r94)
+  br label %pget.recv_merge.18
+
+idisp.override.27:
+  %r175 = getelementptr double, ptr %r174, i64 0
+  store double 1.5, ptr %r175
+  %r176 = getelementptr [1 x double], ptr %r174, i64 0, i64 0
+  %r177 = call double @js_implicit_this_set(double %r170)
+  %r178 = bitcast double %r177 to i64
+  %r179 = call i32 @js_gc_temp_root_push(i64 %r178)
+  %r180 = call double @js_native_call_value(double %r171, ptr %r176, i64 1)
+  %r181 = call i64 @js_gc_temp_root_get(i32 %r179)
+  %r182 = bitcast i64 %r181 to double
+  call void @js_gc_temp_root_truncate(i32 %r179)
+  %r183 = call double @js_implicit_this_set(double %r182)
+  br label %idisp.outer_merge.29
+
+idisp.dispatch.28:
+  %r184 = bitcast double %r170 to i64
+  %r185 = lshr i64 %r184, 48
+  %r186 = icmp eq i64 %r185, 32765
+  br i1 %r186, label %idispatch.tower.33, label %idispatch.default.31
+
+idisp.outer_merge.29:
+  %r224 = phi double [ %r180, %idisp.override.27 ], [ %r223, %idispatch.merge.32 ]
+  %r225 = bitcast double %r224 to i64
+  %r226 = call i32 @js_gc_temp_root_push(i64 %r225)
+  %r227 = load double, ptr %r7
+  %r228 = bitcast double %r227 to i64
+  %r229 = and i64 %r228, 281474976710655
+  %r230 = load double, ptr @batch_ts_.str.7.handle
+  %r231 = bitcast double %r230 to i64
+  %r232 = and i64 %r231, 281474976710655
+  %r233 = lshr i64 %r228, 48
+  %r234 = icmp eq i64 %r233, 32761
+  %r235 = icmp eq i64 %r233, 32766
+  %r236 = and i64 %r233, 65533
+  %r237 = icmp eq i64 %r236, 32765
+  br i1 %r234, label %pget.recv_sso.37, label %pget.check_class_ref.43
+
+idispatch.case0.30:
+  %r193 = load i64, ptr %r191
+  %r194 = load volatile i8, ptr @PERRY_CLASS_FIELD_INLINE_GUARD_DISABLED
+  %r195 = icmp eq i8 %r194, 0
+  %r196 = inttoptr i64 %r188 to ptr
+  %r197 = getelementptr i8, ptr %r196, i64 -7
+  %r198 = load i8, ptr %r197
+  %r199 = and i8 %r198, -128
+  %r200 = icmp eq i8 %r199, 0
+  %r201 = getelementptr i8, ptr %r196, i64 -6
+  %r202 = load i16, ptr %r201
+  %r203 = and i16 %r202, 2049
+  %r204 = icmp eq i16 %r203, 0
+  %r205 = load i32, ptr %r196
+  %r206 = icmp eq i32 %r205, 1
+  %r207 = getelementptr i8, ptr %r196, i64 16
+  %r208 = load i64, ptr %r207
+  %r209 = icmp eq i64 %r208, %r193
+  %r210 = and i1 %r195, %r200
+  %r211 = and i1 %r210, %r204
+  %r212 = and i1 %r211, %r206
+  %r213 = and i1 %r212, %r209
+  br i1 %r213, label %idispatch.case0.pshape.34, label %idispatch.case0.generic.35
+
+idispatch.default.31:
+  %r217 = ptrtoint ptr @batch_ts_.str.8.dispatch to i64
+  %r218 = or i64 %r217, 9221120237041090560
+  %r220 = getelementptr double, ptr %r219, i64 0
+  store double 1.5, ptr %r220
+  %r221 = getelementptr [1 x double], ptr %r219, i64 0, i64 0
+  %r222 = call double @js_native_call_method_by_id(double %r170, i64 %r218, ptr %r221, i64 1)
+  br label %idispatch.merge.32
+
+idispatch.merge.32:
+  %r223 = phi double [ %r216, %idispatch.case0.join.36 ], [ %r222, %idispatch.default.31 ]
+  br label %idisp.outer_merge.29
+
+idispatch.tower.33:
+  %r187 = bitcast double %r170 to i64
+  %r188 = and i64 %r187, 281474976710655
+  %r189 = call i32 @js_object_get_class_id(i64 %r188)
+  %r190 = icmp eq i32 %r189, 1
+  br i1 %r190, label %idispatch.case0.30, label %idispatch.default.31
+
+idispatch.case0.pshape.34:
+  %r214 = call double @perry_method_batch_ts__Row__rescore__pshape(double %r170, double 1.5)
+  br label %idispatch.case0.join.36
+
+idispatch.case0.generic.35:
+  %r215 = call double @perry_method_batch_ts__Row__rescore(double %r170, double 1.5)
+  br label %idispatch.case0.join.36
+
+idispatch.case0.join.36:
+  %r216 = phi double [ %r214, %idispatch.case0.pshape.34 ], [ %r215, %idispatch.case0.generic.35 ]
+  br label %idispatch.merge.32
+
+pget.recv_sso.37:
+  %r301 = call double @js_object_get_field_by_name_f64(i64 %r228, i64 %r232)
+  br label %pget.recv_merge.41
+
+pget.recv_ok.38:
+  call void @js_typed_feedback_observe_property_get(i64 8450987250308612107, i64 %r229, i64 %r232)
+  %r239 = icmp ugt i64 %r229, 1048575
+  %r240 = ptrtoint ptr @perry_ic_12 to i64
+  %r241 = select i1 %r239, i64 %r229, i64 %r240
+  %r242 = sub i64 %r241, 8
+  %r243 = inttoptr i64 %r242 to ptr
+  %r244 = load i8, ptr %r243
+  %r245 = icmp eq i8 %r244, 2
+  %r246 = and i1 %r239, %r245
+  %r247 = add i64 %r241, 12
+  %r248 = inttoptr i64 %r247 to ptr
+  %r249 = load i32, ptr %r248
+  %r250 = icmp eq i32 %r249, 1129268819
+  %r251 = xor i1 %r250, true
+  %r252 = and i1 %r246, %r251
+  %r253 = inttoptr i64 %r241 to ptr
+  %r254 = load i32, ptr %r253
+  %r255 = icmp eq i32 %r254, 1
+  %r256 = and i1 %r252, %r255
+  %r257 = sub i64 %r241, 6
+  %r258 = inttoptr i64 %r257 to ptr
+  %r259 = load i16, ptr %r258
+  %r260 = and i16 %r259, 2048
+  %r261 = icmp eq i16 %r260, 0
+  %r262 = and i1 %r256, %r261
+  %r263 = add i64 %r241, 16
+  %r264 = inttoptr i64 %r263 to ptr
+  %r265 = load i64, ptr %r264
+  %r266 = add i64 %r241, 8
+  %r267 = inttoptr i64 %r266 to ptr
+  %r268 = load i32, ptr %r267
+  %r269 = add i32 %r268, -2147483648
+  %r270 = icmp ult i32 %r269, 1073741824
+  %r271 = zext i32 %r268 to i64
+  %r272 = or i64 %r271, 4611686018427387904
+  %r273 = select i1 %r270, i64 %r272, i64 %r265
+  %r274 = getelementptr i64, ptr @perry_ic_12, i64 0
+  %r275 = load i64, ptr %r274
+  %r276 = icmp eq i64 %r273, %r275
+  %r277 = icmp ne i64 %r273, 0
+  %r278 = and i1 %r262, %r276
+  %r279 = and i1 %r278, %r277
+  br i1 %r279, label %pic.hit.44, label %pic.miss.45
+
+pget.recv_bad.39:
+  %r296 = icmp eq i64 %r228, 9222246136947933185
+  %r297 = icmp eq i64 %r228, 9222246136947933186
+  %r298 = or i1 %r296, %r297
+  br i1 %r298, label %pget.throw_nullish.48, label %pget.recv_undef_return.49
+
+pget.recv_class_ref.40:
+  %r238 = call double @js_typed_feedback_object_get_field_by_name_f64(i64 8450987250308612107, i64 %r228, i64 %r232)
+  br label %pget.recv_merge.41
+
+pget.recv_merge.41:
+  %r302 = phi double [ %r295, %pic.merge.46 ], [ %r300, %pget.recv_undef_return.49 ], [ %r301, %pget.recv_sso.37 ], [ %r238, %pget.recv_class_ref.40 ]
+  %r303 = call double @js_dynamic_mod(double %r302, double 2.0)
+  %r304 = fcmp oeq double %r303, 0.0
+  %r305 = select i1 %r304, i64 9222246136947933188, i64 9222246136947933187
+  %r306 = bitcast i64 %r305 to double
+  %r307 = icmp eq i64 %r305, 9222246136947933188
+  br i1 %r307, label %ternary.then.50, label %ternary.else.51
+
+pget.check_ptr.42:
+  br i1 %r237, label %pget.recv_ok.38, label %pget.recv_bad.39
+
+pget.check_class_ref.43:
+  br i1 %r235, label %pget.recv_class_ref.40, label %pget.check_ptr.42
+
+pic.hit.44:
+  %r280 = getelementptr i64, ptr @perry_ic_12, i64 1
+  %r281 = load i64, ptr %r280
+  %r282 = add i64 %r241, 12
+  %r283 = inttoptr i64 %r282 to ptr
+  %r284 = load i32, ptr %r283
+  %r285 = zext i32 %r284 to i64
+  %r286 = icmp ult i64 %r285, 4
+  %r287 = select i1 %r286, i64 4, i64 %r285
+  %r288 = icmp ult i64 %r281, %r287
+  br i1 %r288, label %pic.hit.load.47, label %pic.miss.45
+
+pic.miss.45:
+  call void @js_typed_feedback_record_guard_fail(i64 8450987250308612107)
+  call void @js_typed_feedback_record_fallback_call(i64 8450987250308612107)
+  %r294 = call double @js_object_get_field_ic_miss(i64 %r229, i64 %r232, ptr @perry_ic_12)
+  br label %pic.merge.46
+
+pic.merge.46:
+  %r295 = phi double [ %r293, %pic.hit.load.47 ], [ %r294, %pic.miss.45 ]
+  br label %pget.recv_merge.41
+
+pic.hit.load.47:
+  call void @js_typed_feedback_record_guard_pass(i64 8450987250308612107)
+  %r289 = shl i64 %r281, 3
+  %r290 = add i64 %r229, 32
+  %r291 = add i64 %r290, %r289
+  %r292 = inttoptr i64 %r291 to ptr
+  %r293 = load double, ptr %r292
+  br label %pic.merge.46
+
+pget.throw_nullish.48:
+  %r299 = zext i1 %r297 to i32
+  call void @js_throw_type_error_property_access(i32 %r299, ptr @batch_ts_.str.7.bytes, i64 2)
+  unreachable
+
+pget.recv_undef_return.49:
+  %r300 = call double @js_object_get_field_by_name_f64(i64 %r228, i64 %r232)
+  br label %pget.recv_merge.41
+
+ternary.then.50:
+  %r308 = load double, ptr @batch_ts_.str.9.handle
+  br label %ternary.merge.52
+
+ternary.else.51:
+  %r309 = load double, ptr @batch_ts_.str.10.handle
+  br label %ternary.merge.52
+
+ternary.merge.52:
+  %r310 = phi double [ %r308, %ternary.then.50 ], [ %r309, %ternary.else.51 ]
+  %r311 = bitcast double %r310 to i64
+  %r312 = call i32 @js_gc_temp_root_push(i64 %r311)
+  %r315 = load i64, ptr %r313
+  %r316 = call i64 @js_object_alloc_class_inline_keys(i32 2, i32 0, i32 3, i64 %r315)
+  %r317 = call i32 @js_gc_temp_root_push(i64 %r316)
+  %r318 = or i64 %r316, 9222527611924643840
+  %r319 = bitcast i64 %r318 to double
+  %r320 = call i64 @js_gc_temp_root_get(i32 %r169)
+  %r321 = bitcast i64 %r320 to double
+  %r322 = call i64 @js_gc_temp_root_get(i32 %r226)
+  %r323 = bitcast i64 %r322 to double
+  %r324 = call i64 @js_gc_temp_root_get(i32 %r312)
+  %r325 = bitcast i64 %r324 to double
+  %r326 = call double @batch_ts____AnonShape_e75d7e32e87dc826_constructor(double %r319, double %r321, double %r323, double %r325)
+  %r327 = call i64 @js_gc_temp_root_get(i32 %r317)
+  %r328 = or i64 %r327, 9222527611924643840
+  %r329 = bitcast i64 %r328 to double
+  call void @js_gc_init_typed_shape_layout(i64 %r327, i32 3, ptr null, i32 0, ptr @perry_typed_shape_mask_batch_ts____AnonShape_e75d7e32e87dc826, i32 1)
+  %r330 = call double @js_ctor_return_override(double %r329, double %r326, i32 0)
+  call void @js_gc_temp_root_truncate(i32 %r8)
+  %shadow_pop_l_0 = load i64, ptr %r1
+  call void @js_shadow_frame_pop(i64 %shadow_pop_l_0)
+  ret double %r330
+}
+
+define double @perry_closure_batch_ts__9(i64 %this_closure, double %arg25, double %arg26) {
+entry.0:
+  %r1 = alloca i64
+  %r2 = alloca ptr
+  store ptr null, ptr %r2
+  %r3 = call ptr @js_shadow_frame_enter(i32 2)
+  store ptr %r3, ptr %r2
+  %r4 = getelementptr inbounds i8, ptr %r3, i64 24
+  %r5 = load i64, ptr %r4
+  %r6 = sub i64 %r5, 1
+  store i64 %r6, ptr %r1
+  %r7 = alloca double
+  store double %arg25, ptr %r7
+  call void @js_shadow_slot_bind(i32 0, ptr %r7)
+  %r8 = alloca double
+  store double %arg26, ptr %r8
+  call void @js_shadow_slot_bind(i32 1, ptr %r8)
+  %r9 = load double, ptr %r7
+  %r10 = bitcast double %r9 to i64
+  %r11 = and i64 %r10, 281474976710655
+  %r12 = load double, ptr @batch_ts_.str.11.handle
+  %r13 = bitcast double %r12 to i64
+  %r14 = and i64 %r13, 281474976710655
+  %r15 = lshr i64 %r10, 48
+  %r16 = icmp eq i64 %r15, 32761
+  %r17 = icmp eq i64 %r15, 32766
+  %r18 = and i64 %r15, 65533
+  %r19 = icmp eq i64 %r18, 32765
+  br i1 %r16, label %pget.recv_sso.1, label %pget.check_class_ref.7
+
+pget.recv_sso.1:
+  %r83 = call double @js_object_get_field_by_name_f64(i64 %r10, i64 %r14)
+  br label %pget.recv_merge.5
+
+pget.recv_ok.2:
+  call void @js_typed_feedback_observe_property_get(i64 8450987250308612109, i64 %r11, i64 %r14)
+  %r21 = icmp ugt i64 %r11, 1048575
+  %r22 = ptrtoint ptr @perry_ic_14 to i64
+  %r23 = select i1 %r21, i64 %r11, i64 %r22
+  %r24 = sub i64 %r23, 8
+  %r25 = inttoptr i64 %r24 to ptr
+  %r26 = load i8, ptr %r25
+  %r27 = icmp eq i8 %r26, 2
+  %r28 = and i1 %r21, %r27
+  %r29 = add i64 %r23, 12
+  %r30 = inttoptr i64 %r29 to ptr
+  %r31 = load i32, ptr %r30
+  %r32 = icmp eq i32 %r31, 1129268819
+  %r33 = xor i1 %r32, true
+  %r34 = and i1 %r28, %r33
+  %r35 = inttoptr i64 %r23 to ptr
+  %r36 = load i32, ptr %r35
+  %r37 = icmp eq i32 %r36, 1
+  %r38 = and i1 %r34, %r37
+  %r39 = sub i64 %r23, 6
+  %r40 = inttoptr i64 %r39 to ptr
+  %r41 = load i16, ptr %r40
+  %r42 = and i16 %r41, 2048
+  %r43 = icmp eq i16 %r42, 0
+  %r44 = and i1 %r38, %r43
+  %r45 = add i64 %r23, 16
+  %r46 = inttoptr i64 %r45 to ptr
+  %r47 = load i64, ptr %r46
+  %r48 = add i64 %r23, 8
+  %r49 = inttoptr i64 %r48 to ptr
+  %r50 = load i32, ptr %r49
+  %r51 = add i32 %r50, -2147483648
+  %r52 = icmp ult i32 %r51, 1073741824
+  %r53 = zext i32 %r50 to i64
+  %r54 = or i64 %r53, 4611686018427387904
+  %r55 = select i1 %r52, i64 %r54, i64 %r47
+  %r56 = getelementptr i64, ptr @perry_ic_14, i64 0
+  %r57 = load i64, ptr %r56
+  %r58 = icmp eq i64 %r55, %r57
+  %r59 = icmp ne i64 %r55, 0
+  %r60 = and i1 %r44, %r58
+  %r61 = and i1 %r60, %r59
+  br i1 %r61, label %pic.hit.8, label %pic.miss.9
+
+pget.recv_bad.3:
+  %r78 = icmp eq i64 %r10, 9222246136947933185
+  %r79 = icmp eq i64 %r10, 9222246136947933186
+  %r80 = or i1 %r78, %r79
+  br i1 %r80, label %pget.throw_nullish.12, label %pget.recv_undef_return.13
+
+pget.recv_class_ref.4:
+  %r20 = call double @js_typed_feedback_object_get_field_by_name_f64(i64 8450987250308612109, i64 %r10, i64 %r14)
+  br label %pget.recv_merge.5
+
+pget.recv_merge.5:
+  %r84 = phi double [ %r77, %pic.merge.10 ], [ %r82, %pget.recv_undef_return.13 ], [ %r83, %pget.recv_sso.1 ], [ %r20, %pget.recv_class_ref.4 ]
+  %r85 = load double, ptr %r8
+  %r86 = bitcast double %r85 to i64
+  %r87 = and i64 %r86, 281474976710655
+  %r88 = load double, ptr @batch_ts_.str.11.handle
+  %r89 = bitcast double %r88 to i64
+  %r90 = and i64 %r89, 281474976710655
+  %r91 = lshr i64 %r86, 48
+  %r92 = icmp eq i64 %r91, 32761
+  %r93 = icmp eq i64 %r91, 32766
+  %r94 = and i64 %r91, 65533
+  %r95 = icmp eq i64 %r94, 32765
+  br i1 %r92, label %pget.recv_sso.14, label %pget.check_class_ref.20
+
+pget.check_ptr.6:
+  br i1 %r19, label %pget.recv_ok.2, label %pget.recv_bad.3
+
+pget.check_class_ref.7:
+  br i1 %r17, label %pget.recv_class_ref.4, label %pget.check_ptr.6
+
+pic.hit.8:
+  %r62 = getelementptr i64, ptr @perry_ic_14, i64 1
+  %r63 = load i64, ptr %r62
+  %r64 = add i64 %r23, 12
+  %r65 = inttoptr i64 %r64 to ptr
+  %r66 = load i32, ptr %r65
+  %r67 = zext i32 %r66 to i64
+  %r68 = icmp ult i64 %r67, 4
+  %r69 = select i1 %r68, i64 4, i64 %r67
+  %r70 = icmp ult i64 %r63, %r69
+  br i1 %r70, label %pic.hit.load.11, label %pic.miss.9
+
+pic.miss.9:
+  call void @js_typed_feedback_record_guard_fail(i64 8450987250308612109)
+  call void @js_typed_feedback_record_fallback_call(i64 8450987250308612109)
+  %r76 = call double @js_object_get_field_ic_miss(i64 %r11, i64 %r14, ptr @perry_ic_14)
+  br label %pic.merge.10
+
+pic.merge.10:
+  %r77 = phi double [ %r75, %pic.hit.load.11 ], [ %r76, %pic.miss.9 ]
+  br label %pget.recv_merge.5
+
+pic.hit.load.11:
+  call void @js_typed_feedback_record_guard_pass(i64 8450987250308612109)
+  %r71 = shl i64 %r63, 3
+  %r72 = add i64 %r11, 32
+  %r73 = add i64 %r72, %r71
+  %r74 = inttoptr i64 %r73 to ptr
+  %r75 = load double, ptr %r74
+  br label %pic.merge.10
+
+pget.throw_nullish.12:
+  %r81 = zext i1 %r79 to i32
+  call void @js_throw_type_error_property_access(i32 %r81, ptr @batch_ts_.str.11.bytes, i64 5)
+  unreachable
+
+pget.recv_undef_return.13:
+  %r82 = call double @js_object_get_field_by_name_f64(i64 %r10, i64 %r14)
+  br label %pget.recv_merge.5
+
+pget.recv_sso.14:
+  %r159 = call double @js_object_get_field_by_name_f64(i64 %r86, i64 %r90)
+  br label %pget.recv_merge.18
+
+pget.recv_ok.15:
+  call void @js_typed_feedback_observe_property_get(i64 8450987250308612111, i64 %r87, i64 %r90)
+  %r97 = icmp ugt i64 %r87, 1048575
+  %r98 = ptrtoint ptr @perry_ic_16 to i64
+  %r99 = select i1 %r97, i64 %r87, i64 %r98
+  %r100 = sub i64 %r99, 8
+  %r101 = inttoptr i64 %r100 to ptr
+  %r102 = load i8, ptr %r101
+  %r103 = icmp eq i8 %r102, 2
+  %r104 = and i1 %r97, %r103
+  %r105 = add i64 %r99, 12
+  %r106 = inttoptr i64 %r105 to ptr
+  %r107 = load i32, ptr %r106
+  %r108 = icmp eq i32 %r107, 1129268819
+  %r109 = xor i1 %r108, true
+  %r110 = and i1 %r104, %r109
+  %r111 = inttoptr i64 %r99 to ptr
+  %r112 = load i32, ptr %r111
+  %r113 = icmp eq i32 %r112, 1
+  %r114 = and i1 %r110, %r113
+  %r115 = sub i64 %r99, 6
+  %r116 = inttoptr i64 %r115 to ptr
+  %r117 = load i16, ptr %r116
+  %r118 = and i16 %r117, 2048
+  %r119 = icmp eq i16 %r118, 0
+  %r120 = and i1 %r114, %r119
+  %r121 = add i64 %r99, 16
+  %r122 = inttoptr i64 %r121 to ptr
+  %r123 = load i64, ptr %r122
+  %r124 = add i64 %r99, 8
+  %r125 = inttoptr i64 %r124 to ptr
+  %r126 = load i32, ptr %r125
+  %r127 = add i32 %r126, -2147483648
+  %r128 = icmp ult i32 %r127, 1073741824
+  %r129 = zext i32 %r126 to i64
+  %r130 = or i64 %r129, 4611686018427387904
+  %r131 = select i1 %r128, i64 %r130, i64 %r123
+  %r132 = getelementptr i64, ptr @perry_ic_16, i64 0
+  %r133 = load i64, ptr %r132
+  %r134 = icmp eq i64 %r131, %r133
+  %r135 = icmp ne i64 %r131, 0
+  %r136 = and i1 %r120, %r134
+  %r137 = and i1 %r136, %r135
+  br i1 %r137, label %pic.hit.21, label %pic.miss.22
+
+pget.recv_bad.16:
+  %r154 = icmp eq i64 %r86, 9222246136947933185
+  %r155 = icmp eq i64 %r86, 9222246136947933186
+  %r156 = or i1 %r154, %r155
+  br i1 %r156, label %pget.throw_nullish.25, label %pget.recv_undef_return.26
+
+pget.recv_class_ref.17:
+  %r96 = call double @js_typed_feedback_object_get_field_by_name_f64(i64 8450987250308612111, i64 %r86, i64 %r90)
+  br label %pget.recv_merge.18
+
+pget.recv_merge.18:
+  %r160 = phi double [ %r153, %pic.merge.23 ], [ %r158, %pget.recv_undef_return.26 ], [ %r159, %pget.recv_sso.14 ], [ %r96, %pget.recv_class_ref.17 ]
+  %r161 = bitcast double %r84 to i64
+  %r162 = bitcast double %r160 to i64
+  %r163 = call i64 @js_eq(i64 %r161, i64 %r162)
+  %r164 = bitcast i64 %r163 to double
+  %r165 = icmp eq i64 %r163, 9222246136947933188
+  %r166 = xor i1 %r165, true
+  %r167 = select i1 %r166, i64 9222246136947933188, i64 9222246136947933187
+  %r168 = bitcast i64 %r167 to double
+  %r169 = icmp eq i64 %r167, 9222246136947933188
+  br i1 %r169, label %if.then.27, label %if.else.28
+
+pget.check_ptr.19:
+  br i1 %r95, label %pget.recv_ok.15, label %pget.recv_bad.16
+
+pget.check_class_ref.20:
+  br i1 %r93, label %pget.recv_class_ref.17, label %pget.check_ptr.19
+
+pic.hit.21:
+  %r138 = getelementptr i64, ptr @perry_ic_16, i64 1
+  %r139 = load i64, ptr %r138
+  %r140 = add i64 %r99, 12
+  %r141 = inttoptr i64 %r140 to ptr
+  %r142 = load i32, ptr %r141
+  %r143 = zext i32 %r142 to i64
+  %r144 = icmp ult i64 %r143, 4
+  %r145 = select i1 %r144, i64 4, i64 %r143
+  %r146 = icmp ult i64 %r139, %r145
+  br i1 %r146, label %pic.hit.load.24, label %pic.miss.22
+
+pic.miss.22:
+  call void @js_typed_feedback_record_guard_fail(i64 8450987250308612111)
+  call void @js_typed_feedback_record_fallback_call(i64 8450987250308612111)
+  %r152 = call double @js_object_get_field_ic_miss(i64 %r87, i64 %r90, ptr @perry_ic_16)
+  br label %pic.merge.23
+
+pic.merge.23:
+  %r153 = phi double [ %r151, %pic.hit.load.24 ], [ %r152, %pic.miss.22 ]
+  br label %pget.recv_merge.18
+
+pic.hit.load.24:
+  call void @js_typed_feedback_record_guard_pass(i64 8450987250308612111)
+  %r147 = shl i64 %r139, 3
+  %r148 = add i64 %r87, 32
+  %r149 = add i64 %r148, %r147
+  %r150 = inttoptr i64 %r149 to ptr
+  %r151 = load double, ptr %r150
+  br label %pic.merge.23
+
+pget.throw_nullish.25:
+  %r157 = zext i1 %r155 to i32
+  call void @js_throw_type_error_property_access(i32 %r157, ptr @batch_ts_.str.11.bytes, i64 5)
+  unreachable
+
+pget.recv_undef_return.26:
+  %r158 = call double @js_object_get_field_by_name_f64(i64 %r86, i64 %r90)
+  br label %pget.recv_merge.18
+
+if.then.27:
+  %r170 = load double, ptr %r8
+  %r171 = bitcast double %r170 to i64
+  %r172 = and i64 %r171, 281474976710655
+  %r173 = load double, ptr @batch_ts_.str.11.handle
+  %r174 = bitcast double %r173 to i64
+  %r175 = and i64 %r174, 281474976710655
+  %r176 = lshr i64 %r171, 48
+  %r177 = icmp eq i64 %r176, 32761
+  %r178 = icmp eq i64 %r176, 32766
+  %r179 = and i64 %r176, 65533
+  %r180 = icmp eq i64 %r179, 32765
+  br i1 %r177, label %pget.recv_sso.30, label %pget.check_class_ref.36
+
+if.else.28:
+  br label %if.merge.29
+
+if.merge.29:
+  %r327 = load double, ptr %r7
+  %r328 = bitcast double %r327 to i64
+  %r329 = and i64 %r328, 281474976710655
+  %r330 = load double, ptr @batch_ts_.str.12.handle
+  %r331 = bitcast double %r330 to i64
+  %r332 = and i64 %r331, 281474976710655
+  %r333 = lshr i64 %r328, 48
+  %r334 = icmp eq i64 %r333, 32761
+  %r335 = icmp eq i64 %r333, 32766
+  %r336 = and i64 %r333, 65533
+  %r337 = icmp eq i64 %r336, 32765
+  br i1 %r334, label %pget.recv_sso.56, label %pget.check_class_ref.62
+
+pget.recv_sso.30:
+  %r244 = call double @js_object_get_field_by_name_f64(i64 %r171, i64 %r175)
+  br label %pget.recv_merge.34
+
+pget.recv_ok.31:
+  call void @js_typed_feedback_observe_property_get(i64 8450987250308612113, i64 %r172, i64 %r175)
+  %r182 = icmp ugt i64 %r172, 1048575
+  %r183 = ptrtoint ptr @perry_ic_18 to i64
+  %r184 = select i1 %r182, i64 %r172, i64 %r183
+  %r185 = sub i64 %r184, 8
+  %r186 = inttoptr i64 %r185 to ptr
+  %r187 = load i8, ptr %r186
+  %r188 = icmp eq i8 %r187, 2
+  %r189 = and i1 %r182, %r188
+  %r190 = add i64 %r184, 12
+  %r191 = inttoptr i64 %r190 to ptr
+  %r192 = load i32, ptr %r191
+  %r193 = icmp eq i32 %r192, 1129268819
+  %r194 = xor i1 %r193, true
+  %r195 = and i1 %r189, %r194
+  %r196 = inttoptr i64 %r184 to ptr
+  %r197 = load i32, ptr %r196
+  %r198 = icmp eq i32 %r197, 1
+  %r199 = and i1 %r195, %r198
+  %r200 = sub i64 %r184, 6
+  %r201 = inttoptr i64 %r200 to ptr
+  %r202 = load i16, ptr %r201
+  %r203 = and i16 %r202, 2048
+  %r204 = icmp eq i16 %r203, 0
+  %r205 = and i1 %r199, %r204
+  %r206 = add i64 %r184, 16
+  %r207 = inttoptr i64 %r206 to ptr
+  %r208 = load i64, ptr %r207
+  %r209 = add i64 %r184, 8
+  %r210 = inttoptr i64 %r209 to ptr
+  %r211 = load i32, ptr %r210
+  %r212 = add i32 %r211, -2147483648
+  %r213 = icmp ult i32 %r212, 1073741824
+  %r214 = zext i32 %r211 to i64
+  %r215 = or i64 %r214, 4611686018427387904
+  %r216 = select i1 %r213, i64 %r215, i64 %r208
+  %r217 = getelementptr i64, ptr @perry_ic_18, i64 0
+  %r218 = load i64, ptr %r217
+  %r219 = icmp eq i64 %r216, %r218
+  %r220 = icmp ne i64 %r216, 0
+  %r221 = and i1 %r205, %r219
+  %r222 = and i1 %r221, %r220
+  br i1 %r222, label %pic.hit.37, label %pic.miss.38
+
+pget.recv_bad.32:
+  %r239 = icmp eq i64 %r171, 9222246136947933185
+  %r240 = icmp eq i64 %r171, 9222246136947933186
+  %r241 = or i1 %r239, %r240
+  br i1 %r241, label %pget.throw_nullish.41, label %pget.recv_undef_return.42
+
+pget.recv_class_ref.33:
+  %r181 = call double @js_typed_feedback_object_get_field_by_name_f64(i64 8450987250308612113, i64 %r171, i64 %r175)
+  br label %pget.recv_merge.34
+
+pget.recv_merge.34:
+  %r245 = phi double [ %r238, %pic.merge.39 ], [ %r243, %pget.recv_undef_return.42 ], [ %r244, %pget.recv_sso.30 ], [ %r181, %pget.recv_class_ref.33 ]
+  %r246 = bitcast double %r245 to i64
+  %r247 = call i32 @js_gc_temp_root_push(i64 %r246)
+  %r248 = load double, ptr %r7
+  %r249 = bitcast double %r248 to i64
+  %r250 = and i64 %r249, 281474976710655
+  %r251 = load double, ptr @batch_ts_.str.11.handle
+  %r252 = bitcast double %r251 to i64
+  %r253 = and i64 %r252, 281474976710655
+  %r254 = lshr i64 %r249, 48
+  %r255 = icmp eq i64 %r254, 32761
+  %r256 = icmp eq i64 %r254, 32766
+  %r257 = and i64 %r254, 65533
+  %r258 = icmp eq i64 %r257, 32765
+  br i1 %r255, label %pget.recv_sso.43, label %pget.check_class_ref.49
+
+pget.check_ptr.35:
+  br i1 %r180, label %pget.recv_ok.31, label %pget.recv_bad.32
+
+pget.check_class_ref.36:
+  br i1 %r178, label %pget.recv_class_ref.33, label %pget.check_ptr.35
+
+pic.hit.37:
+  %r223 = getelementptr i64, ptr @perry_ic_18, i64 1
+  %r224 = load i64, ptr %r223
+  %r225 = add i64 %r184, 12
+  %r226 = inttoptr i64 %r225 to ptr
+  %r227 = load i32, ptr %r226
+  %r228 = zext i32 %r227 to i64
+  %r229 = icmp ult i64 %r228, 4
+  %r230 = select i1 %r229, i64 4, i64 %r228
+  %r231 = icmp ult i64 %r224, %r230
+  br i1 %r231, label %pic.hit.load.40, label %pic.miss.38
+
+pic.miss.38:
+  call void @js_typed_feedback_record_guard_fail(i64 8450987250308612113)
+  call void @js_typed_feedback_record_fallback_call(i64 8450987250308612113)
+  %r237 = call double @js_object_get_field_ic_miss(i64 %r172, i64 %r175, ptr @perry_ic_18)
+  br label %pic.merge.39
+
+pic.merge.39:
+  %r238 = phi double [ %r236, %pic.hit.load.40 ], [ %r237, %pic.miss.38 ]
+  br label %pget.recv_merge.34
+
+pic.hit.load.40:
+  call void @js_typed_feedback_record_guard_pass(i64 8450987250308612113)
+  %r232 = shl i64 %r224, 3
+  %r233 = add i64 %r172, 32
+  %r234 = add i64 %r233, %r232
+  %r235 = inttoptr i64 %r234 to ptr
+  %r236 = load double, ptr %r235
+  br label %pic.merge.39
+
+pget.throw_nullish.41:
+  %r242 = zext i1 %r240 to i32
+  call void @js_throw_type_error_property_access(i32 %r242, ptr @batch_ts_.str.11.bytes, i64 5)
+  unreachable
+
+pget.recv_undef_return.42:
+  %r243 = call double @js_object_get_field_by_name_f64(i64 %r171, i64 %r175)
+  br label %pget.recv_merge.34
+
+pget.recv_sso.43:
+  %r322 = call double @js_object_get_field_by_name_f64(i64 %r249, i64 %r253)
+  br label %pget.recv_merge.47
+
+pget.recv_ok.44:
+  call void @js_typed_feedback_observe_property_get(i64 8450987250308612115, i64 %r250, i64 %r253)
+  %r260 = icmp ugt i64 %r250, 1048575
+  %r261 = ptrtoint ptr @perry_ic_20 to i64
+  %r262 = select i1 %r260, i64 %r250, i64 %r261
+  %r263 = sub i64 %r262, 8
+  %r264 = inttoptr i64 %r263 to ptr
+  %r265 = load i8, ptr %r264
+  %r266 = icmp eq i8 %r265, 2
+  %r267 = and i1 %r260, %r266
+  %r268 = add i64 %r262, 12
+  %r269 = inttoptr i64 %r268 to ptr
+  %r270 = load i32, ptr %r269
+  %r271 = icmp eq i32 %r270, 1129268819
+  %r272 = xor i1 %r271, true
+  %r273 = and i1 %r267, %r272
+  %r274 = inttoptr i64 %r262 to ptr
+  %r275 = load i32, ptr %r274
+  %r276 = icmp eq i32 %r275, 1
+  %r277 = and i1 %r273, %r276
+  %r278 = sub i64 %r262, 6
+  %r279 = inttoptr i64 %r278 to ptr
+  %r280 = load i16, ptr %r279
+  %r281 = and i16 %r280, 2048
+  %r282 = icmp eq i16 %r281, 0
+  %r283 = and i1 %r277, %r282
+  %r284 = add i64 %r262, 16
+  %r285 = inttoptr i64 %r284 to ptr
+  %r286 = load i64, ptr %r285
+  %r287 = add i64 %r262, 8
+  %r288 = inttoptr i64 %r287 to ptr
+  %r289 = load i32, ptr %r288
+  %r290 = add i32 %r289, -2147483648
+  %r291 = icmp ult i32 %r290, 1073741824
+  %r292 = zext i32 %r289 to i64
+  %r293 = or i64 %r292, 4611686018427387904
+  %r294 = select i1 %r291, i64 %r293, i64 %r286
+  %r295 = getelementptr i64, ptr @perry_ic_20, i64 0
+  %r296 = load i64, ptr %r295
+  %r297 = icmp eq i64 %r294, %r296
+  %r298 = icmp ne i64 %r294, 0
+  %r299 = and i1 %r283, %r297
+  %r300 = and i1 %r299, %r298
+  br i1 %r300, label %pic.hit.50, label %pic.miss.51
+
+pget.recv_bad.45:
+  %r317 = icmp eq i64 %r249, 9222246136947933185
+  %r318 = icmp eq i64 %r249, 9222246136947933186
+  %r319 = or i1 %r317, %r318
+  br i1 %r319, label %pget.throw_nullish.54, label %pget.recv_undef_return.55
+
+pget.recv_class_ref.46:
+  %r259 = call double @js_typed_feedback_object_get_field_by_name_f64(i64 8450987250308612115, i64 %r249, i64 %r253)
+  br label %pget.recv_merge.47
+
+pget.recv_merge.47:
+  %r323 = phi double [ %r316, %pic.merge.52 ], [ %r321, %pget.recv_undef_return.55 ], [ %r322, %pget.recv_sso.43 ], [ %r259, %pget.recv_class_ref.46 ]
+  %r324 = call i64 @js_gc_temp_root_get(i32 %r247)
+  %r325 = bitcast i64 %r324 to double
+  %r326 = call double @js_dynamic_sub(double %r325, double %r323)
+  call void @js_gc_temp_root_truncate(i32 %r247)
+  %shadow_pop_l_0 = load i64, ptr %r1
+  call void @js_shadow_frame_pop(i64 %shadow_pop_l_0)
+  ret double %r326
+
+pget.check_ptr.48:
+  br i1 %r258, label %pget.recv_ok.44, label %pget.recv_bad.45
+
+pget.check_class_ref.49:
+  br i1 %r256, label %pget.recv_class_ref.46, label %pget.check_ptr.48
+
+pic.hit.50:
+  %r301 = getelementptr i64, ptr @perry_ic_20, i64 1
+  %r302 = load i64, ptr %r301
+  %r303 = add i64 %r262, 12
+  %r304 = inttoptr i64 %r303 to ptr
+  %r305 = load i32, ptr %r304
+  %r306 = zext i32 %r305 to i64
+  %r307 = icmp ult i64 %r306, 4
+  %r308 = select i1 %r307, i64 4, i64 %r306
+  %r309 = icmp ult i64 %r302, %r308
+  br i1 %r309, label %pic.hit.load.53, label %pic.miss.51
+
+pic.miss.51:
+  call void @js_typed_feedback_record_guard_fail(i64 8450987250308612115)
+  call void @js_typed_feedback_record_fallback_call(i64 8450987250308612115)
+  %r315 = call double @js_object_get_field_ic_miss(i64 %r250, i64 %r253, ptr @perry_ic_20)
+  br label %pic.merge.52
+
+pic.merge.52:
+  %r316 = phi double [ %r314, %pic.hit.load.53 ], [ %r315, %pic.miss.51 ]
+  br label %pget.recv_merge.47
+
+pic.hit.load.53:
+  call void @js_typed_feedback_record_guard_pass(i64 8450987250308612115)
+  %r310 = shl i64 %r302, 3
+  %r311 = add i64 %r250, 32
+  %r312 = add i64 %r311, %r310
+  %r313 = inttoptr i64 %r312 to ptr
+  %r314 = load double, ptr %r313
+  br label %pic.merge.52
+
+pget.throw_nullish.54:
+  %r320 = zext i1 %r318 to i32
+  call void @js_throw_type_error_property_access(i32 %r320, ptr @batch_ts_.str.11.bytes, i64 5)
+  unreachable
+
+pget.recv_undef_return.55:
+  %r321 = call double @js_object_get_field_by_name_f64(i64 %r249, i64 %r253)
+  br label %pget.recv_merge.47
+
+pget.recv_sso.56:
+  %r401 = call double @js_object_get_field_by_name_f64(i64 %r328, i64 %r332)
+  br label %pget.recv_merge.60
+
+pget.recv_ok.57:
+  call void @js_typed_feedback_observe_property_get(i64 8450987250308612117, i64 %r329, i64 %r332)
+  %r339 = icmp ugt i64 %r329, 1048575
+  %r340 = ptrtoint ptr @perry_ic_22 to i64
+  %r341 = select i1 %r339, i64 %r329, i64 %r340
+  %r342 = sub i64 %r341, 8
+  %r343 = inttoptr i64 %r342 to ptr
+  %r344 = load i8, ptr %r343
+  %r345 = icmp eq i8 %r344, 2
+  %r346 = and i1 %r339, %r345
+  %r347 = add i64 %r341, 12
+  %r348 = inttoptr i64 %r347 to ptr
+  %r349 = load i32, ptr %r348
+  %r350 = icmp eq i32 %r349, 1129268819
+  %r351 = xor i1 %r350, true
+  %r352 = and i1 %r346, %r351
+  %r353 = inttoptr i64 %r341 to ptr
+  %r354 = load i32, ptr %r353
+  %r355 = icmp eq i32 %r354, 1
+  %r356 = and i1 %r352, %r355
+  %r357 = sub i64 %r341, 6
+  %r358 = inttoptr i64 %r357 to ptr
+  %r359 = load i16, ptr %r358
+  %r360 = and i16 %r359, 2048
+  %r361 = icmp eq i16 %r360, 0
+  %r362 = and i1 %r356, %r361
+  %r363 = add i64 %r341, 16
+  %r364 = inttoptr i64 %r363 to ptr
+  %r365 = load i64, ptr %r364
+  %r366 = add i64 %r341, 8
+  %r367 = inttoptr i64 %r366 to ptr
+  %r368 = load i32, ptr %r367
+  %r369 = add i32 %r368, -2147483648
+  %r370 = icmp ult i32 %r369, 1073741824
+  %r371 = zext i32 %r368 to i64
+  %r372 = or i64 %r371, 4611686018427387904
+  %r373 = select i1 %r370, i64 %r372, i64 %r365
+  %r374 = getelementptr i64, ptr @perry_ic_22, i64 0
+  %r375 = load i64, ptr %r374
+  %r376 = icmp eq i64 %r373, %r375
+  %r377 = icmp ne i64 %r373, 0
+  %r378 = and i1 %r362, %r376
+  %r379 = and i1 %r378, %r377
+  br i1 %r379, label %pic.hit.63, label %pic.miss.64
+
+pget.recv_bad.58:
+  %r396 = icmp eq i64 %r328, 9222246136947933185
+  %r397 = icmp eq i64 %r328, 9222246136947933186
+  %r398 = or i1 %r396, %r397
+  br i1 %r398, label %pget.throw_nullish.67, label %pget.recv_undef_return.68
+
+pget.recv_class_ref.59:
+  %r338 = call double @js_typed_feedback_object_get_field_by_name_f64(i64 8450987250308612117, i64 %r328, i64 %r332)
+  br label %pget.recv_merge.60
+
+pget.recv_merge.60:
+  %r402 = phi double [ %r395, %pic.merge.65 ], [ %r400, %pget.recv_undef_return.68 ], [ %r401, %pget.recv_sso.56 ], [ %r338, %pget.recv_class_ref.59 ]
+  %r403 = load double, ptr %r8
+  %r404 = bitcast double %r403 to i64
+  %r405 = and i64 %r404, 281474976710655
+  %r406 = load double, ptr @batch_ts_.str.12.handle
+  %r407 = bitcast double %r406 to i64
+  %r408 = and i64 %r407, 281474976710655
+  %r409 = lshr i64 %r404, 48
+  %r410 = icmp eq i64 %r409, 32761
+  %r411 = icmp eq i64 %r409, 32766
+  %r412 = and i64 %r409, 65533
+  %r413 = icmp eq i64 %r412, 32765
+  br i1 %r410, label %pget.recv_sso.69, label %pget.check_class_ref.75
+
+pget.check_ptr.61:
+  br i1 %r337, label %pget.recv_ok.57, label %pget.recv_bad.58
+
+pget.check_class_ref.62:
+  br i1 %r335, label %pget.recv_class_ref.59, label %pget.check_ptr.61
+
+pic.hit.63:
+  %r380 = getelementptr i64, ptr @perry_ic_22, i64 1
+  %r381 = load i64, ptr %r380
+  %r382 = add i64 %r341, 12
+  %r383 = inttoptr i64 %r382 to ptr
+  %r384 = load i32, ptr %r383
+  %r385 = zext i32 %r384 to i64
+  %r386 = icmp ult i64 %r385, 4
+  %r387 = select i1 %r386, i64 4, i64 %r385
+  %r388 = icmp ult i64 %r381, %r387
+  br i1 %r388, label %pic.hit.load.66, label %pic.miss.64
+
+pic.miss.64:
+  call void @js_typed_feedback_record_guard_fail(i64 8450987250308612117)
+  call void @js_typed_feedback_record_fallback_call(i64 8450987250308612117)
+  %r394 = call double @js_object_get_field_ic_miss(i64 %r329, i64 %r332, ptr @perry_ic_22)
+  br label %pic.merge.65
+
+pic.merge.65:
+  %r395 = phi double [ %r393, %pic.hit.load.66 ], [ %r394, %pic.miss.64 ]
+  br label %pget.recv_merge.60
+
+pic.hit.load.66:
+  call void @js_typed_feedback_record_guard_pass(i64 8450987250308612117)
+  %r389 = shl i64 %r381, 3
+  %r390 = add i64 %r329, 32
+  %r391 = add i64 %r390, %r389
+  %r392 = inttoptr i64 %r391 to ptr
+  %r393 = load double, ptr %r392
+  br label %pic.merge.65
+
+pget.throw_nullish.67:
+  %r399 = zext i1 %r397 to i32
+  call void @js_throw_type_error_property_access(i32 %r399, ptr @batch_ts_.str.12.bytes, i64 3)
+  unreachable
+
+pget.recv_undef_return.68:
+  %r400 = call double @js_object_get_field_by_name_f64(i64 %r328, i64 %r332)
+  br label %pget.recv_merge.60
+
+pget.recv_sso.69:
+  %r477 = call double @js_object_get_field_by_name_f64(i64 %r404, i64 %r408)
+  br label %pget.recv_merge.73
+
+pget.recv_ok.70:
+  call void @js_typed_feedback_observe_property_get(i64 8450987250308612119, i64 %r405, i64 %r408)
+  %r415 = icmp ugt i64 %r405, 1048575
+  %r416 = ptrtoint ptr @perry_ic_24 to i64
+  %r417 = select i1 %r415, i64 %r405, i64 %r416
+  %r418 = sub i64 %r417, 8
+  %r419 = inttoptr i64 %r418 to ptr
+  %r420 = load i8, ptr %r419
+  %r421 = icmp eq i8 %r420, 2
+  %r422 = and i1 %r415, %r421
+  %r423 = add i64 %r417, 12
+  %r424 = inttoptr i64 %r423 to ptr
+  %r425 = load i32, ptr %r424
+  %r426 = icmp eq i32 %r425, 1129268819
+  %r427 = xor i1 %r426, true
+  %r428 = and i1 %r422, %r427
+  %r429 = inttoptr i64 %r417 to ptr
+  %r430 = load i32, ptr %r429
+  %r431 = icmp eq i32 %r430, 1
+  %r432 = and i1 %r428, %r431
+  %r433 = sub i64 %r417, 6
+  %r434 = inttoptr i64 %r433 to ptr
+  %r435 = load i16, ptr %r434
+  %r436 = and i16 %r435, 2048
+  %r437 = icmp eq i16 %r436, 0
+  %r438 = and i1 %r432, %r437
+  %r439 = add i64 %r417, 16
+  %r440 = inttoptr i64 %r439 to ptr
+  %r441 = load i64, ptr %r440
+  %r442 = add i64 %r417, 8
+  %r443 = inttoptr i64 %r442 to ptr
+  %r444 = load i32, ptr %r443
+  %r445 = add i32 %r444, -2147483648
+  %r446 = icmp ult i32 %r445, 1073741824
+  %r447 = zext i32 %r444 to i64
+  %r448 = or i64 %r447, 4611686018427387904
+  %r449 = select i1 %r446, i64 %r448, i64 %r441
+  %r450 = getelementptr i64, ptr @perry_ic_24, i64 0
+  %r451 = load i64, ptr %r450
+  %r452 = icmp eq i64 %r449, %r451
+  %r453 = icmp ne i64 %r449, 0
+  %r454 = and i1 %r438, %r452
+  %r455 = and i1 %r454, %r453
+  br i1 %r455, label %pic.hit.76, label %pic.miss.77
+
+pget.recv_bad.71:
+  %r472 = icmp eq i64 %r404, 9222246136947933185
+  %r473 = icmp eq i64 %r404, 9222246136947933186
+  %r474 = or i1 %r472, %r473
+  br i1 %r474, label %pget.throw_nullish.80, label %pget.recv_undef_return.81
+
+pget.recv_class_ref.72:
+  %r414 = call double @js_typed_feedback_object_get_field_by_name_f64(i64 8450987250308612119, i64 %r404, i64 %r408)
+  br label %pget.recv_merge.73
+
+pget.recv_merge.73:
+  %r478 = phi double [ %r471, %pic.merge.78 ], [ %r476, %pget.recv_undef_return.81 ], [ %r477, %pget.recv_sso.69 ], [ %r414, %pget.recv_class_ref.72 ]
+  %r479 = call double @js_rel_lt(double %r402, double %r478)
+  %r480 = bitcast double %r479 to i64
+  %r481 = icmp eq i64 %r480, 9222246136947933188
+  br i1 %r481, label %ternary.then.82, label %ternary.else.83
+
+pget.check_ptr.74:
+  br i1 %r413, label %pget.recv_ok.70, label %pget.recv_bad.71
+
+pget.check_class_ref.75:
+  br i1 %r411, label %pget.recv_class_ref.72, label %pget.check_ptr.74
+
+pic.hit.76:
+  %r456 = getelementptr i64, ptr @perry_ic_24, i64 1
+  %r457 = load i64, ptr %r456
+  %r458 = add i64 %r417, 12
+  %r459 = inttoptr i64 %r458 to ptr
+  %r460 = load i32, ptr %r459
+  %r461 = zext i32 %r460 to i64
+  %r462 = icmp ult i64 %r461, 4
+  %r463 = select i1 %r462, i64 4, i64 %r461
+  %r464 = icmp ult i64 %r457, %r463
+  br i1 %r464, label %pic.hit.load.79, label %pic.miss.77
+
+pic.miss.77:
+  call void @js_typed_feedback_record_guard_fail(i64 8450987250308612119)
+  call void @js_typed_feedback_record_fallback_call(i64 8450987250308612119)
+  %r470 = call double @js_object_get_field_ic_miss(i64 %r405, i64 %r408, ptr @perry_ic_24)
+  br label %pic.merge.78
+
+pic.merge.78:
+  %r471 = phi double [ %r469, %pic.hit.load.79 ], [ %r470, %pic.miss.77 ]
+  br label %pget.recv_merge.73
+
+pic.hit.load.79:
+  call void @js_typed_feedback_record_guard_pass(i64 8450987250308612119)
+  %r465 = shl i64 %r457, 3
+  %r466 = add i64 %r405, 32
+  %r467 = add i64 %r466, %r465
+  %r468 = inttoptr i64 %r467 to ptr
+  %r469 = load double, ptr %r468
+  br label %pic.merge.78
+
+pget.throw_nullish.80:
+  %r475 = zext i1 %r473 to i32
+  call void @js_throw_type_error_property_access(i32 %r475, ptr @batch_ts_.str.12.bytes, i64 3)
+  unreachable
+
+pget.recv_undef_return.81:
+  %r476 = call double @js_object_get_field_by_name_f64(i64 %r404, i64 %r408)
+  br label %pget.recv_merge.73
+
+ternary.then.82:
+  br label %ternary.merge.84
+
+ternary.else.83:
+  %r482 = load double, ptr %r7
+  %r483 = bitcast double %r482 to i64
+  %r484 = and i64 %r483, 281474976710655
+  %r485 = load double, ptr @batch_ts_.str.12.handle
+  %r486 = bitcast double %r485 to i64
+  %r487 = and i64 %r486, 281474976710655
+  %r488 = lshr i64 %r483, 48
+  %r489 = icmp eq i64 %r488, 32761
+  %r490 = icmp eq i64 %r488, 32766
+  %r491 = and i64 %r488, 65533
+  %r492 = icmp eq i64 %r491, 32765
+  br i1 %r489, label %pget.recv_sso.85, label %pget.check_class_ref.91
+
+ternary.merge.84:
+  %r638 = phi double [ -1.0, %ternary.then.82 ], [ %r637, %ternary.merge.113 ]
+  %shadow_pop_l_1 = load i64, ptr %r1
+  call void @js_shadow_frame_pop(i64 %shadow_pop_l_1)
+  ret double %r638
+
+pget.recv_sso.85:
+  %r556 = call double @js_object_get_field_by_name_f64(i64 %r483, i64 %r487)
+  br label %pget.recv_merge.89
+
+pget.recv_ok.86:
+  call void @js_typed_feedback_observe_property_get(i64 8450987250308612121, i64 %r484, i64 %r487)
+  %r494 = icmp ugt i64 %r484, 1048575
+  %r495 = ptrtoint ptr @perry_ic_26 to i64
+  %r496 = select i1 %r494, i64 %r484, i64 %r495
+  %r497 = sub i64 %r496, 8
+  %r498 = inttoptr i64 %r497 to ptr
+  %r499 = load i8, ptr %r498
+  %r500 = icmp eq i8 %r499, 2
+  %r501 = and i1 %r494, %r500
+  %r502 = add i64 %r496, 12
+  %r503 = inttoptr i64 %r502 to ptr
+  %r504 = load i32, ptr %r503
+  %r505 = icmp eq i32 %r504, 1129268819
+  %r506 = xor i1 %r505, true
+  %r507 = and i1 %r501, %r506
+  %r508 = inttoptr i64 %r496 to ptr
+  %r509 = load i32, ptr %r508
+  %r510 = icmp eq i32 %r509, 1
+  %r511 = and i1 %r507, %r510
+  %r512 = sub i64 %r496, 6
+  %r513 = inttoptr i64 %r512 to ptr
+  %r514 = load i16, ptr %r513
+  %r515 = and i16 %r514, 2048
+  %r516 = icmp eq i16 %r515, 0
+  %r517 = and i1 %r511, %r516
+  %r518 = add i64 %r496, 16
+  %r519 = inttoptr i64 %r518 to ptr
+  %r520 = load i64, ptr %r519
+  %r521 = add i64 %r496, 8
+  %r522 = inttoptr i64 %r521 to ptr
+  %r523 = load i32, ptr %r522
+  %r524 = add i32 %r523, -2147483648
+  %r525 = icmp ult i32 %r524, 1073741824
+  %r526 = zext i32 %r523 to i64
+  %r527 = or i64 %r526, 4611686018427387904
+  %r528 = select i1 %r525, i64 %r527, i64 %r520
+  %r529 = getelementptr i64, ptr @perry_ic_26, i64 0
+  %r530 = load i64, ptr %r529
+  %r531 = icmp eq i64 %r528, %r530
+  %r532 = icmp ne i64 %r528, 0
+  %r533 = and i1 %r517, %r531
+  %r534 = and i1 %r533, %r532
+  br i1 %r534, label %pic.hit.92, label %pic.miss.93
+
+pget.recv_bad.87:
+  %r551 = icmp eq i64 %r483, 9222246136947933185
+  %r552 = icmp eq i64 %r483, 9222246136947933186
+  %r553 = or i1 %r551, %r552
+  br i1 %r553, label %pget.throw_nullish.96, label %pget.recv_undef_return.97
+
+pget.recv_class_ref.88:
+  %r493 = call double @js_typed_feedback_object_get_field_by_name_f64(i64 8450987250308612121, i64 %r483, i64 %r487)
+  br label %pget.recv_merge.89
+
+pget.recv_merge.89:
+  %r557 = phi double [ %r550, %pic.merge.94 ], [ %r555, %pget.recv_undef_return.97 ], [ %r556, %pget.recv_sso.85 ], [ %r493, %pget.recv_class_ref.88 ]
+  %r558 = load double, ptr %r8
+  %r559 = bitcast double %r558 to i64
+  %r560 = and i64 %r559, 281474976710655
+  %r561 = load double, ptr @batch_ts_.str.12.handle
+  %r562 = bitcast double %r561 to i64
+  %r563 = and i64 %r562, 281474976710655
+  %r564 = lshr i64 %r559, 48
+  %r565 = icmp eq i64 %r564, 32761
+  %r566 = icmp eq i64 %r564, 32766
+  %r567 = and i64 %r564, 65533
+  %r568 = icmp eq i64 %r567, 32765
+  br i1 %r565, label %pget.recv_sso.98, label %pget.check_class_ref.104
+
+pget.check_ptr.90:
+  br i1 %r492, label %pget.recv_ok.86, label %pget.recv_bad.87
+
+pget.check_class_ref.91:
+  br i1 %r490, label %pget.recv_class_ref.88, label %pget.check_ptr.90
+
+pic.hit.92:
+  %r535 = getelementptr i64, ptr @perry_ic_26, i64 1
+  %r536 = load i64, ptr %r535
+  %r537 = add i64 %r496, 12
+  %r538 = inttoptr i64 %r537 to ptr
+  %r539 = load i32, ptr %r538
+  %r540 = zext i32 %r539 to i64
+  %r541 = icmp ult i64 %r540, 4
+  %r542 = select i1 %r541, i64 4, i64 %r540
+  %r543 = icmp ult i64 %r536, %r542
+  br i1 %r543, label %pic.hit.load.95, label %pic.miss.93
+
+pic.miss.93:
+  call void @js_typed_feedback_record_guard_fail(i64 8450987250308612121)
+  call void @js_typed_feedback_record_fallback_call(i64 8450987250308612121)
+  %r549 = call double @js_object_get_field_ic_miss(i64 %r484, i64 %r487, ptr @perry_ic_26)
+  br label %pic.merge.94
+
+pic.merge.94:
+  %r550 = phi double [ %r548, %pic.hit.load.95 ], [ %r549, %pic.miss.93 ]
+  br label %pget.recv_merge.89
+
+pic.hit.load.95:
+  call void @js_typed_feedback_record_guard_pass(i64 8450987250308612121)
+  %r544 = shl i64 %r536, 3
+  %r545 = add i64 %r484, 32
+  %r546 = add i64 %r545, %r544
+  %r547 = inttoptr i64 %r546 to ptr
+  %r548 = load double, ptr %r547
+  br label %pic.merge.94
+
+pget.throw_nullish.96:
+  %r554 = zext i1 %r552 to i32
+  call void @js_throw_type_error_property_access(i32 %r554, ptr @batch_ts_.str.12.bytes, i64 3)
+  unreachable
+
+pget.recv_undef_return.97:
+  %r555 = call double @js_object_get_field_by_name_f64(i64 %r483, i64 %r487)
+  br label %pget.recv_merge.89
+
+pget.recv_sso.98:
+  %r632 = call double @js_object_get_field_by_name_f64(i64 %r559, i64 %r563)
+  br label %pget.recv_merge.102
+
+pget.recv_ok.99:
+  call void @js_typed_feedback_observe_property_get(i64 8450987250308612123, i64 %r560, i64 %r563)
+  %r570 = icmp ugt i64 %r560, 1048575
+  %r571 = ptrtoint ptr @perry_ic_28 to i64
+  %r572 = select i1 %r570, i64 %r560, i64 %r571
+  %r573 = sub i64 %r572, 8
+  %r574 = inttoptr i64 %r573 to ptr
+  %r575 = load i8, ptr %r574
+  %r576 = icmp eq i8 %r575, 2
+  %r577 = and i1 %r570, %r576
+  %r578 = add i64 %r572, 12
+  %r579 = inttoptr i64 %r578 to ptr
+  %r580 = load i32, ptr %r579
+  %r581 = icmp eq i32 %r580, 1129268819
+  %r582 = xor i1 %r581, true
+  %r583 = and i1 %r577, %r582
+  %r584 = inttoptr i64 %r572 to ptr
+  %r585 = load i32, ptr %r584
+  %r586 = icmp eq i32 %r585, 1
+  %r587 = and i1 %r583, %r586
+  %r588 = sub i64 %r572, 6
+  %r589 = inttoptr i64 %r588 to ptr
+  %r590 = load i16, ptr %r589
+  %r591 = and i16 %r590, 2048
+  %r592 = icmp eq i16 %r591, 0
+  %r593 = and i1 %r587, %r592
+  %r594 = add i64 %r572, 16
+  %r595 = inttoptr i64 %r594 to ptr
+  %r596 = load i64, ptr %r595
+  %r597 = add i64 %r572, 8
+  %r598 = inttoptr i64 %r597 to ptr
+  %r599 = load i32, ptr %r598
+  %r600 = add i32 %r599, -2147483648
+  %r601 = icmp ult i32 %r600, 1073741824
+  %r602 = zext i32 %r599 to i64
+  %r603 = or i64 %r602, 4611686018427387904
+  %r604 = select i1 %r601, i64 %r603, i64 %r596
+  %r605 = getelementptr i64, ptr @perry_ic_28, i64 0
+  %r606 = load i64, ptr %r605
+  %r607 = icmp eq i64 %r604, %r606
+  %r608 = icmp ne i64 %r604, 0
+  %r609 = and i1 %r593, %r607
+  %r610 = and i1 %r609, %r608
+  br i1 %r610, label %pic.hit.105, label %pic.miss.106
+
+pget.recv_bad.100:
+  %r627 = icmp eq i64 %r559, 9222246136947933185
+  %r628 = icmp eq i64 %r559, 9222246136947933186
+  %r629 = or i1 %r627, %r628
+  br i1 %r629, label %pget.throw_nullish.109, label %pget.recv_undef_return.110
+
+pget.recv_class_ref.101:
+  %r569 = call double @js_typed_feedback_object_get_field_by_name_f64(i64 8450987250308612123, i64 %r559, i64 %r563)
+  br label %pget.recv_merge.102
+
+pget.recv_merge.102:
+  %r633 = phi double [ %r626, %pic.merge.107 ], [ %r631, %pget.recv_undef_return.110 ], [ %r632, %pget.recv_sso.98 ], [ %r569, %pget.recv_class_ref.101 ]
+  %r634 = call double @js_rel_gt(double %r557, double %r633)
+  %r635 = bitcast double %r634 to i64
+  %r636 = icmp eq i64 %r635, 9222246136947933188
+  br i1 %r636, label %ternary.then.111, label %ternary.else.112
+
+pget.check_ptr.103:
+  br i1 %r568, label %pget.recv_ok.99, label %pget.recv_bad.100
+
+pget.check_class_ref.104:
+  br i1 %r566, label %pget.recv_class_ref.101, label %pget.check_ptr.103
+
+pic.hit.105:
+  %r611 = getelementptr i64, ptr @perry_ic_28, i64 1
+  %r612 = load i64, ptr %r611
+  %r613 = add i64 %r572, 12
+  %r614 = inttoptr i64 %r613 to ptr
+  %r615 = load i32, ptr %r614
+  %r616 = zext i32 %r615 to i64
+  %r617 = icmp ult i64 %r616, 4
+  %r618 = select i1 %r617, i64 4, i64 %r616
+  %r619 = icmp ult i64 %r612, %r618
+  br i1 %r619, label %pic.hit.load.108, label %pic.miss.106
+
+pic.miss.106:
+  call void @js_typed_feedback_record_guard_fail(i64 8450987250308612123)
+  call void @js_typed_feedback_record_fallback_call(i64 8450987250308612123)
+  %r625 = call double @js_object_get_field_ic_miss(i64 %r560, i64 %r563, ptr @perry_ic_28)
+  br label %pic.merge.107
+
+pic.merge.107:
+  %r626 = phi double [ %r624, %pic.hit.load.108 ], [ %r625, %pic.miss.106 ]
+  br label %pget.recv_merge.102
+
+pic.hit.load.108:
+  call void @js_typed_feedback_record_guard_pass(i64 8450987250308612123)
+  %r620 = shl i64 %r612, 3
+  %r621 = add i64 %r560, 32
+  %r622 = add i64 %r621, %r620
+  %r623 = inttoptr i64 %r622 to ptr
+  %r624 = load double, ptr %r623
+  br label %pic.merge.107
+
+pget.throw_nullish.109:
+  %r630 = zext i1 %r628 to i32
+  call void @js_throw_type_error_property_access(i32 %r630, ptr @batch_ts_.str.12.bytes, i64 3)
+  unreachable
+
+pget.recv_undef_return.110:
+  %r631 = call double @js_object_get_field_by_name_f64(i64 %r559, i64 %r563)
+  br label %pget.recv_merge.102
+
+ternary.then.111:
+  br label %ternary.merge.113
+
+ternary.else.112:
+  br label %ternary.merge.113
+
+ternary.merge.113:
+  %r637 = phi double [ 1.0, %ternary.then.111 ], [ 0.0, %ternary.else.112 ]
+  br label %ternary.merge.84
+}
+
+define double @perry_closure_batch_ts__11(i64 %this_closure, double %arg35, double %arg36) {
+entry.0:
+  %r1 = alloca i64
+  %r2 = alloca ptr
+  store ptr null, ptr %r2
+  %r3 = call ptr @js_shadow_frame_enter(i32 3)
+  store ptr %r3, ptr %r2
+  %r4 = getelementptr inbounds i8, ptr %r3, i64 24
+  %r5 = load i64, ptr %r4
+  %r6 = sub i64 %r5, 1
+  store i64 %r6, ptr %r1
+  %r9 = alloca double
+  store double 0x7FFC000000000001, ptr %r9
+  %r66 = alloca double
+  store double 0x7FFC000000000001, ptr %r66
+  call void @js_shadow_slot_bind(i32 2, ptr %r66)
+  %r7 = alloca double
+  store double %arg35, ptr %r7
+  call void @js_shadow_slot_bind(i32 0, ptr %r7)
+  %r8 = alloca double
+  store double %arg36, ptr %r8
+  call void @js_shadow_slot_bind(i32 1, ptr %r8)
+  %r10 = load double, ptr @perry_global_batch_ts__1
+  %r11 = load double, ptr %r8
+  %r12 = bitcast double %r11 to i64
+  %r13 = and i64 %r12, 281474976710655
+  %r14 = load double, ptr @batch_ts_.str.5.handle
+  %r15 = bitcast double %r14 to i64
+  %r16 = and i64 %r15, 281474976710655
+  %r17 = load i64, ptr @perry_class_keys_batch_ts__Row
+  %r18 = load volatile i8, ptr @PERRY_CLASS_FIELD_INLINE_GUARD_DISABLED
+  %r19 = icmp eq i8 %r18, 0
+  %r20 = lshr i64 %r12, 48
+  %r21 = icmp eq i64 %r20, 32765
+  %r22 = icmp ugt i64 %r13, 1048575
+  %r23 = and i1 %r21, %r22
+  %r24 = and i1 %r23, %r19
+  br i1 %r24, label %class_field_inline.deref.4, label %class_field_inline.guardcall.5
+
+class_field_get.fast.1:
+  %r56 = inttoptr i64 %r13 to ptr
+  %r57 = getelementptr i8, ptr %r56, i64 32
+  %r58 = getelementptr double, ptr %r57, i64 1
+  %r59 = load double, ptr %r58
+  br label %class_field_get.merge.3
+
+class_field_get.fallback.2:
+  call void @js_typed_feedback_record_fallback_call(i64 8450987250308612125)
+  %r60 = call double @js_object_get_field_by_name_f64(i64 %r12, i64 %r16)
+  br label %class_field_get.merge.3
+
+class_field_get.merge.3:
+  %r61 = phi double [ %r59, %class_field_get.fast.1 ], [ %r60, %class_field_get.fallback.2 ]
+  %r62 = bitcast double %r10 to i64
+  %r63 = and i64 %r62, 281474976710655
+  %r64 = call i64 @js_array_indexOf_jsvalue(i64 %r63, double %r61, double %r61, i32 0)
+  %r65 = sitofp i64 %r64 to double
+  store double %r65, ptr %r9
+  %r67 = load double, ptr %r7
+  %r68 = load double, ptr %r9
+  %r69 = bitcast double %r67 to i64
+  %r70 = and i64 %r69, 281474976710655
+  %r71 = call double @js_array_get_index_or_string(i64 %r70, double %r68)
+  store double %r71, ptr %r66
+  %r72 = bitcast double %r71 to i64
+  %r73 = load atomic i32, ptr @PERRY_INCREMENTAL_MARK_BARRIER_ACTIVE_COUNT seq_cst, align 4
+  %r74 = icmp ne i32 %r73, 0
+  br i1 %r74, label %shadow.root.barrier.6, label %shadow.root.barrier.done.7
+
+class_field_inline.deref.4:
+  %r25 = inttoptr i64 %r13 to ptr
+  %r26 = getelementptr i8, ptr %r25, i64 -8
+  %r27 = load i8, ptr %r26
+  %r28 = icmp eq i8 %r27, 2
+  %r29 = getelementptr i8, ptr %r25, i64 -7
+  %r30 = load i8, ptr %r29
+  %r31 = and i8 %r30, -128
+  %r32 = icmp eq i8 %r31, 0
+  %r33 = getelementptr i8, ptr %r25, i64 -6
+  %r34 = load i16, ptr %r33
+  %r35 = load i32, ptr %r25
+  %r36 = icmp eq i32 %r35, 1
+  %r37 = getelementptr i8, ptr %r25, i64 4
+  %r38 = load i32, ptr %r37
+  %r39 = icmp eq i32 %r38, 1
+  %r40 = getelementptr i8, ptr %r25, i64 12
+  %r41 = load i32, ptr %r40
+  %r42 = icmp ugt i32 %r41, 1
+  %r43 = getelementptr i8, ptr %r25, i64 16
+  %r44 = load i64, ptr %r43
+  %r45 = icmp eq i64 %r44, %r17
+  %r46 = and i1 %r28, %r32
+  %r47 = and i1 %r46, %r36
+  %r48 = and i1 %r47, %r39
+  %r49 = and i1 %r48, %r42
+  %r50 = and i1 %r49, %r45
+  %r51 = and i16 %r34, 2048
+  %r52 = icmp eq i16 %r51, 0
+  %r53 = and i1 %r50, %r52
+  br i1 %r53, label %class_field_get.fast.1, label %class_field_inline.guardcall.5
+
+class_field_inline.guardcall.5:
+  %r54 = call i32 @js_typed_feedback_class_field_get_guard(i64 8450987250308612125, double %r11, i32 1, i64 %r17, i64 %r16, i32 1, i32 0)
+  %r55 = icmp ne i32 %r54, 0
+  br i1 %r55, label %class_field_get.fast.1, label %class_field_get.fallback.2
+
+shadow.root.barrier.6:
+  call void @js_write_barrier_root_nanbox(i64 %r72)
+  br label %shadow.root.barrier.done.7
+
+shadow.root.barrier.done.7:
+  %r75 = load double, ptr @batch_ts_.str.13.handle
+  %r76 = load double, ptr %r66
+  %r77 = bitcast double %r76 to i64
+  %r78 = and i64 %r77, 281474976710655
+  %r79 = load double, ptr @batch_ts_.str.13.handle
+  %r80 = bitcast double %r79 to i64
+  %r81 = and i64 %r80, 281474976710655
+  %r82 = lshr i64 %r77, 48
+  %r83 = icmp eq i64 %r82, 32761
+  %r84 = icmp eq i64 %r82, 32766
+  %r85 = and i64 %r82, 65533
+  %r86 = icmp eq i64 %r85, 32765
+  br i1 %r83, label %pget.recv_sso.8, label %pget.check_class_ref.14
+
+pget.recv_sso.8:
+  %r150 = call double @js_object_get_field_by_name_f64(i64 %r77, i64 %r81)
+  br label %pget.recv_merge.12
+
+pget.recv_ok.9:
+  call void @js_typed_feedback_observe_property_get(i64 8450987250308612126, i64 %r78, i64 %r81)
+  %r88 = icmp ugt i64 %r78, 1048575
+  %r89 = ptrtoint ptr @perry_ic_31 to i64
+  %r90 = select i1 %r88, i64 %r78, i64 %r89
+  %r91 = sub i64 %r90, 8
+  %r92 = inttoptr i64 %r91 to ptr
+  %r93 = load i8, ptr %r92
+  %r94 = icmp eq i8 %r93, 2
+  %r95 = and i1 %r88, %r94
+  %r96 = add i64 %r90, 12
+  %r97 = inttoptr i64 %r96 to ptr
+  %r98 = load i32, ptr %r97
+  %r99 = icmp eq i32 %r98, 1129268819
+  %r100 = xor i1 %r99, true
+  %r101 = and i1 %r95, %r100
+  %r102 = inttoptr i64 %r90 to ptr
+  %r103 = load i32, ptr %r102
+  %r104 = icmp eq i32 %r103, 1
+  %r105 = and i1 %r101, %r104
+  %r106 = sub i64 %r90, 6
+  %r107 = inttoptr i64 %r106 to ptr
+  %r108 = load i16, ptr %r107
+  %r109 = and i16 %r108, 2048
+  %r110 = icmp eq i16 %r109, 0
+  %r111 = and i1 %r105, %r110
+  %r112 = add i64 %r90, 16
+  %r113 = inttoptr i64 %r112 to ptr
+  %r114 = load i64, ptr %r113
+  %r115 = add i64 %r90, 8
+  %r116 = inttoptr i64 %r115 to ptr
+  %r117 = load i32, ptr %r116
+  %r118 = add i32 %r117, -2147483648
+  %r119 = icmp ult i32 %r118, 1073741824
+  %r120 = zext i32 %r117 to i64
+  %r121 = or i64 %r120, 4611686018427387904
+  %r122 = select i1 %r119, i64 %r121, i64 %r114
+  %r123 = getelementptr i64, ptr @perry_ic_31, i64 0
+  %r124 = load i64, ptr %r123
+  %r125 = icmp eq i64 %r122, %r124
+  %r126 = icmp ne i64 %r122, 0
+  %r127 = and i1 %r111, %r125
+  %r128 = and i1 %r127, %r126
+  br i1 %r128, label %pic.hit.15, label %pic.miss.16
+
+pget.recv_bad.10:
+  %r145 = icmp eq i64 %r77, 9222246136947933185
+  %r146 = icmp eq i64 %r77, 9222246136947933186
+  %r147 = or i1 %r145, %r146
+  br i1 %r147, label %pget.throw_nullish.19, label %pget.recv_undef_return.20
+
+pget.recv_class_ref.11:
+  %r87 = call double @js_typed_feedback_object_get_field_by_name_f64(i64 8450987250308612126, i64 %r77, i64 %r81)
+  br label %pget.recv_merge.12
+
+pget.recv_merge.12:
+  %r151 = phi double [ %r144, %pic.merge.17 ], [ %r149, %pget.recv_undef_return.20 ], [ %r150, %pget.recv_sso.8 ], [ %r87, %pget.recv_class_ref.11 ]
+  %r152 = call double @js_dynamic_string_or_number_add(double %r151, double 1.0)
+  %r153 = load double, ptr @batch_ts_.str.13.handle
+  %r154 = load double, ptr %r66
+  %r155 = bitcast double %r153 to i64
+  %r156 = bitcast double %r152 to i64
+  %r157 = bitcast double %r154 to i64
+  %r158 = and i64 %r157, 281474976710655
+  %r159 = lshr i64 %r157, 48
+  %r160 = icmp eq i64 %r159, 32765
+  %r161 = icmp ugt i64 %r158, 1048575
+  %r162 = lshr i64 %r156, 48
+  %r163 = icmp ne i64 %r162, 32765
+  %r164 = icmp ne i64 %r162, 32767
+  %r165 = icmp ne i64 %r162, 32762
+  %r166 = icmp ne i64 %r155, 0
+  %r167 = and i1 %r160, %r161
+  %r168 = and i1 %r167, %r163
+  %r169 = and i1 %r168, %r164
+  %r170 = and i1 %r169, %r165
+  %r171 = and i1 %r170, %r166
+  br i1 %r171, label %put.dynic.guard.21, label %put.dynic.slow.27
+
+pget.check_ptr.13:
+  br i1 %r86, label %pget.recv_ok.9, label %pget.recv_bad.10
+
+pget.check_class_ref.14:
+  br i1 %r84, label %pget.recv_class_ref.11, label %pget.check_ptr.13
+
+pic.hit.15:
+  %r129 = getelementptr i64, ptr @perry_ic_31, i64 1
+  %r130 = load i64, ptr %r129
+  %r131 = add i64 %r90, 12
+  %r132 = inttoptr i64 %r131 to ptr
+  %r133 = load i32, ptr %r132
+  %r134 = zext i32 %r133 to i64
+  %r135 = icmp ult i64 %r134, 4
+  %r136 = select i1 %r135, i64 4, i64 %r134
+  %r137 = icmp ult i64 %r130, %r136
+  br i1 %r137, label %pic.hit.load.18, label %pic.miss.16
+
+pic.miss.16:
+  call void @js_typed_feedback_record_guard_fail(i64 8450987250308612126)
+  call void @js_typed_feedback_record_fallback_call(i64 8450987250308612126)
+  %r143 = call double @js_object_get_field_ic_miss(i64 %r78, i64 %r81, ptr @perry_ic_31)
+  br label %pic.merge.17
+
+pic.merge.17:
+  %r144 = phi double [ %r142, %pic.hit.load.18 ], [ %r143, %pic.miss.16 ]
+  br label %pget.recv_merge.12
+
+pic.hit.load.18:
+  call void @js_typed_feedback_record_guard_pass(i64 8450987250308612126)
+  %r138 = shl i64 %r130, 3
+  %r139 = add i64 %r78, 32
+  %r140 = add i64 %r139, %r138
+  %r141 = inttoptr i64 %r140 to ptr
+  %r142 = load double, ptr %r141
+  br label %pic.merge.17
+
+pget.throw_nullish.19:
+  %r148 = zext i1 %r146 to i32
+  call void @js_throw_type_error_property_access(i32 %r148, ptr @batch_ts_.str.13.bytes, i64 5)
+  unreachable
+
+pget.recv_undef_return.20:
+  %r149 = call double @js_object_get_field_by_name_f64(i64 %r77, i64 %r81)
+  br label %pget.recv_merge.12
+
+put.dynic.guard.21:
+  %r172 = sub i64 %r158, 8
+  %r173 = inttoptr i64 %r172 to ptr
+  %r174 = load i8, ptr %r173
+  %r175 = icmp eq i8 %r174, 2
+  %r176 = sub i64 %r158, 7
+  %r177 = inttoptr i64 %r176 to ptr
+  %r178 = load i8, ptr %r177
+  %r179 = and i8 %r178, 128
+  %r180 = icmp eq i8 %r179, 0
+  %r181 = sub i64 %r158, 6
+  %r182 = inttoptr i64 %r181 to ptr
+  %r183 = load i16, ptr %r182
+  %r184 = and i16 %r183, 6407
+  %r185 = icmp eq i16 %r184, 0
+  %r186 = inttoptr i64 %r158 to ptr
+  %r187 = load i32, ptr %r186
+  %r188 = icmp eq i32 %r187, 1
+  %r189 = add i64 %r158, 4
+  %r190 = inttoptr i64 %r189 to ptr
+  %r191 = load i32, ptr %r190
+  %r192 = icmp ne i32 %r191, 0
+  %r193 = icmp ne i32 %r191, -2
+  %r194 = add i64 %r158, 16
+  %r195 = inttoptr i64 %r194 to ptr
+  %r196 = load i64, ptr %r195
+  %r197 = add i64 %r158, 8
+  %r198 = inttoptr i64 %r197 to ptr
+  %r199 = load i32, ptr %r198
+  %r200 = add i32 %r199, -2147483648
+  %r201 = icmp ult i32 %r200, 1073741824
+  %r202 = zext i32 %r199 to i64
+  %r203 = or i64 %r202, 4611686018427387904
+  %r204 = select i1 %r201, i64 %r203, i64 %r196
+  %r205 = getelementptr i64, ptr @perry_ic_32, i64 0
+  %r206 = load i64, ptr %r205
+  %r207 = icmp eq i64 %r204, %r206
+  %r208 = icmp ne i64 %r204, 0
+  %r209 = and i1 %r175, %r180
+  %r210 = and i1 %r209, %r185
+  %r211 = and i1 %r210, %r188
+  %r212 = and i1 %r211, %r192
+  %r213 = and i1 %r212, %r193
+  %r214 = and i1 %r213, %r207
+  %r215 = and i1 %r214, %r208
+  br i1 %r215, label %put.dynic.ways.22, label %put.dynic.slow.27
+
+put.dynic.ways.22:
+  %r216 = getelementptr i64, ptr @perry_ic_32, i64 1
+  %r217 = load i64, ptr %r216
+  %r218 = getelementptr i64, ptr @perry_ic_32, i64 2
+  %r219 = load i64, ptr %r218
+  %r220 = icmp eq i64 %r155, %r217
+  br i1 %r220, label %put.dynic.bounds.25, label %put.dynic.way1.23
+
+put.dynic.way1.23:
+  %r221 = getelementptr i64, ptr @perry_ic_32, i64 3
+  %r222 = load i64, ptr %r221
+  %r223 = getelementptr i64, ptr @perry_ic_32, i64 4
+  %r224 = load i64, ptr %r223
+  %r225 = icmp eq i64 %r155, %r222
+  br i1 %r225, label %put.dynic.bounds.25, label %put.dynic.way2.24
+
+put.dynic.way2.24:
+  %r226 = getelementptr i64, ptr @perry_ic_32, i64 5
+  %r227 = load i64, ptr %r226
+  %r228 = getelementptr i64, ptr @perry_ic_32, i64 6
+  %r229 = load i64, ptr %r228
+  %r230 = icmp eq i64 %r155, %r227
+  br i1 %r230, label %put.dynic.bounds.25, label %put.dynic.slow.27
+
+put.dynic.bounds.25:
+  %r231 = phi i64 [ %r219, %put.dynic.ways.22 ], [ %r224, %put.dynic.way1.23 ], [ %r229, %put.dynic.way2.24 ]
+  %r232 = add i64 %r158, 12
+  %r233 = inttoptr i64 %r232 to ptr
+  %r234 = load i32, ptr %r233
+  %r235 = zext i32 %r234 to i64
+  %r236 = icmp ult i64 %r235, 4
+  %r237 = select i1 %r236, i64 4, i64 %r235
+  %r238 = icmp ult i64 %r231, %r237
+  br i1 %r238, label %put.dynic.store.26, label %put.dynic.slow.27
+
+put.dynic.store.26:
+  %r239 = add i64 %r231, 4
+  %r240 = inttoptr i64 %r158 to ptr
+  %r241 = getelementptr inbounds i64, ptr %r240, i64 %r239
+  store double %r152, ptr %r241
+  br label %put.dynic.merge.28
+
+put.dynic.slow.27:
+  %r242 = call double @js_put_value_set_dyn_ic(ptr @perry_ic_32, double %r154, double %r153, double %r152, i32 1)
+  br label %put.dynic.merge.28
+
+put.dynic.merge.28:
+  %r243 = phi double [ %r152, %put.dynic.store.26 ], [ %r242, %put.dynic.slow.27 ]
+  %r244 = load double, ptr @batch_ts_.str.1.handle
+  %r245 = load double, ptr %r66
+  %r246 = bitcast double %r245 to i64
+  %r247 = and i64 %r246, 281474976710655
+  %r248 = load double, ptr @batch_ts_.str.1.handle
+  %r249 = bitcast double %r248 to i64
+  %r250 = and i64 %r249, 281474976710655
+  %r251 = lshr i64 %r246, 48
+  %r252 = icmp eq i64 %r251, 32761
+  %r253 = icmp eq i64 %r251, 32766
+  %r254 = and i64 %r251, 65533
+  %r255 = icmp eq i64 %r254, 32765
+  br i1 %r252, label %pget.recv_sso.29, label %pget.check_class_ref.35
+
+pget.recv_sso.29:
+  %r319 = call double @js_object_get_field_by_name_f64(i64 %r246, i64 %r250)
+  br label %pget.recv_merge.33
+
+pget.recv_ok.30:
+  call void @js_typed_feedback_observe_property_get(i64 8450987250308612129, i64 %r247, i64 %r250)
+  %r257 = icmp ugt i64 %r247, 1048575
+  %r258 = ptrtoint ptr @perry_ic_34 to i64
+  %r259 = select i1 %r257, i64 %r247, i64 %r258
+  %r260 = sub i64 %r259, 8
+  %r261 = inttoptr i64 %r260 to ptr
+  %r262 = load i8, ptr %r261
+  %r263 = icmp eq i8 %r262, 2
+  %r264 = and i1 %r257, %r263
+  %r265 = add i64 %r259, 12
+  %r266 = inttoptr i64 %r265 to ptr
+  %r267 = load i32, ptr %r266
+  %r268 = icmp eq i32 %r267, 1129268819
+  %r269 = xor i1 %r268, true
+  %r270 = and i1 %r264, %r269
+  %r271 = inttoptr i64 %r259 to ptr
+  %r272 = load i32, ptr %r271
+  %r273 = icmp eq i32 %r272, 1
+  %r274 = and i1 %r270, %r273
+  %r275 = sub i64 %r259, 6
+  %r276 = inttoptr i64 %r275 to ptr
+  %r277 = load i16, ptr %r276
+  %r278 = and i16 %r277, 2048
+  %r279 = icmp eq i16 %r278, 0
+  %r280 = and i1 %r274, %r279
+  %r281 = add i64 %r259, 16
+  %r282 = inttoptr i64 %r281 to ptr
+  %r283 = load i64, ptr %r282
+  %r284 = add i64 %r259, 8
+  %r285 = inttoptr i64 %r284 to ptr
+  %r286 = load i32, ptr %r285
+  %r287 = add i32 %r286, -2147483648
+  %r288 = icmp ult i32 %r287, 1073741824
+  %r289 = zext i32 %r286 to i64
+  %r290 = or i64 %r289, 4611686018427387904
+  %r291 = select i1 %r288, i64 %r290, i64 %r283
+  %r292 = getelementptr i64, ptr @perry_ic_34, i64 0
+  %r293 = load i64, ptr %r292
+  %r294 = icmp eq i64 %r291, %r293
+  %r295 = icmp ne i64 %r291, 0
+  %r296 = and i1 %r280, %r294
+  %r297 = and i1 %r296, %r295
+  br i1 %r297, label %pic.hit.36, label %pic.miss.37
+
+pget.recv_bad.31:
+  %r314 = icmp eq i64 %r246, 9222246136947933185
+  %r315 = icmp eq i64 %r246, 9222246136947933186
+  %r316 = or i1 %r314, %r315
+  br i1 %r316, label %pget.throw_nullish.40, label %pget.recv_undef_return.41
+
+pget.recv_class_ref.32:
+  %r256 = call double @js_typed_feedback_object_get_field_by_name_f64(i64 8450987250308612129, i64 %r246, i64 %r250)
+  br label %pget.recv_merge.33
+
+pget.recv_merge.33:
+  %r320 = phi double [ %r313, %pic.merge.38 ], [ %r318, %pget.recv_undef_return.41 ], [ %r319, %pget.recv_sso.29 ], [ %r256, %pget.recv_class_ref.32 ]
+  %r321 = bitcast double %r320 to i64
+  %r322 = call i32 @js_gc_temp_root_push(i64 %r321)
+  %r323 = load double, ptr %r8
+  %r324 = bitcast double %r323 to i64
+  %r325 = and i64 %r324, 281474976710655
+  %r326 = load double, ptr @batch_ts_.str.4.handle
+  %r327 = bitcast double %r326 to i64
+  %r328 = and i64 %r327, 281474976710655
+  %r329 = load i64, ptr @perry_class_keys_batch_ts__Row
+  %r330 = load volatile i8, ptr @PERRY_CLASS_FIELD_INLINE_GUARD_DISABLED
+  %r331 = icmp eq i8 %r330, 0
+  %r332 = lshr i64 %r324, 48
+  %r333 = icmp eq i64 %r332, 32765
+  %r334 = icmp ugt i64 %r325, 1048575
+  %r335 = and i1 %r333, %r334
+  %r336 = and i1 %r335, %r331
+  br i1 %r336, label %class_field_inline.deref.45, label %class_field_inline.guardcall.46
+
+pget.check_ptr.34:
+  br i1 %r255, label %pget.recv_ok.30, label %pget.recv_bad.31
+
+pget.check_class_ref.35:
+  br i1 %r253, label %pget.recv_class_ref.32, label %pget.check_ptr.34
+
+pic.hit.36:
+  %r298 = getelementptr i64, ptr @perry_ic_34, i64 1
+  %r299 = load i64, ptr %r298
+  %r300 = add i64 %r259, 12
+  %r301 = inttoptr i64 %r300 to ptr
+  %r302 = load i32, ptr %r301
+  %r303 = zext i32 %r302 to i64
+  %r304 = icmp ult i64 %r303, 4
+  %r305 = select i1 %r304, i64 4, i64 %r303
+  %r306 = icmp ult i64 %r299, %r305
+  br i1 %r306, label %pic.hit.load.39, label %pic.miss.37
+
+pic.miss.37:
+  call void @js_typed_feedback_record_guard_fail(i64 8450987250308612129)
+  call void @js_typed_feedback_record_fallback_call(i64 8450987250308612129)
+  %r312 = call double @js_object_get_field_ic_miss(i64 %r247, i64 %r250, ptr @perry_ic_34)
+  br label %pic.merge.38
+
+pic.merge.38:
+  %r313 = phi double [ %r311, %pic.hit.load.39 ], [ %r312, %pic.miss.37 ]
+  br label %pget.recv_merge.33
+
+pic.hit.load.39:
+  call void @js_typed_feedback_record_guard_pass(i64 8450987250308612129)
+  %r307 = shl i64 %r299, 3
+  %r308 = add i64 %r247, 32
+  %r309 = add i64 %r308, %r307
+  %r310 = inttoptr i64 %r309 to ptr
+  %r311 = load double, ptr %r310
+  br label %pic.merge.38
+
+pget.throw_nullish.40:
+  %r317 = zext i1 %r315 to i32
+  call void @js_throw_type_error_property_access(i32 %r317, ptr @batch_ts_.str.1.bytes, i64 5)
+  unreachable
+
+pget.recv_undef_return.41:
+  %r318 = call double @js_object_get_field_by_name_f64(i64 %r246, i64 %r250)
+  br label %pget.recv_merge.33
+
+class_field_get.fast.42:
+  %r371 = inttoptr i64 %r325 to ptr
+  %r372 = getelementptr i8, ptr %r371, i64 32
+  %r373 = getelementptr double, ptr %r372, i64 3
+  %r374 = load double, ptr %r373
+  br label %class_field_get.merge.44
+
+class_field_get.fallback.43:
+  call void @js_typed_feedback_record_fallback_call(i64 8450987250308612131)
+  %r375 = call double @js_object_get_field_by_name_f64(i64 %r324, i64 %r328)
+  br label %class_field_get.merge.44
+
+class_field_get.merge.44:
+  %r376 = phi double [ %r374, %class_field_get.fast.42 ], [ %r375, %class_field_get.fallback.43 ]
+  %r377 = call i64 @js_gc_temp_root_get(i32 %r322)
+  %r378 = bitcast i64 %r377 to double
+  %r379 = call double @js_dynamic_string_or_number_add(double %r378, double %r376)
+  call void @js_gc_temp_root_truncate(i32 %r322)
+  %r380 = load double, ptr @batch_ts_.str.1.handle
+  %r381 = load double, ptr %r66
+  %r382 = bitcast double %r380 to i64
+  %r383 = bitcast double %r379 to i64
+  %r384 = bitcast double %r381 to i64
+  %r385 = and i64 %r384, 281474976710655
+  %r386 = lshr i64 %r384, 48
+  %r387 = icmp eq i64 %r386, 32765
+  %r388 = icmp ugt i64 %r385, 1048575
+  %r389 = lshr i64 %r383, 48
+  %r390 = icmp ne i64 %r389, 32765
+  %r391 = icmp ne i64 %r389, 32767
+  %r392 = icmp ne i64 %r389, 32762
+  %r393 = icmp ne i64 %r382, 0
+  %r394 = and i1 %r387, %r388
+  %r395 = and i1 %r394, %r390
+  %r396 = and i1 %r395, %r391
+  %r397 = and i1 %r396, %r392
+  %r398 = and i1 %r397, %r393
+  br i1 %r398, label %put.dynic.guard.47, label %put.dynic.slow.53
+
+class_field_inline.deref.45:
+  %r337 = inttoptr i64 %r325 to ptr
+  %r338 = getelementptr i8, ptr %r337, i64 -8
+  %r339 = load i8, ptr %r338
+  %r340 = icmp eq i8 %r339, 2
+  %r341 = getelementptr i8, ptr %r337, i64 -7
+  %r342 = load i8, ptr %r341
+  %r343 = and i8 %r342, -128
+  %r344 = icmp eq i8 %r343, 0
+  %r345 = getelementptr i8, ptr %r337, i64 -6
+  %r346 = load i16, ptr %r345
+  %r347 = load i32, ptr %r337
+  %r348 = icmp eq i32 %r347, 1
+  %r349 = getelementptr i8, ptr %r337, i64 4
+  %r350 = load i32, ptr %r349
+  %r351 = icmp eq i32 %r350, 1
+  %r352 = getelementptr i8, ptr %r337, i64 12
+  %r353 = load i32, ptr %r352
+  %r354 = icmp ugt i32 %r353, 3
+  %r355 = getelementptr i8, ptr %r337, i64 16
+  %r356 = load i64, ptr %r355
+  %r357 = icmp eq i64 %r356, %r329
+  %r358 = and i1 %r340, %r344
+  %r359 = and i1 %r358, %r348
+  %r360 = and i1 %r359, %r351
+  %r361 = and i1 %r360, %r354
+  %r362 = and i1 %r361, %r357
+  %r363 = and i16 %r346, 2048
+  %r364 = icmp eq i16 %r363, 0
+  %r365 = and i1 %r362, %r364
+  %r366 = and i16 %r346, 4096
+  %r367 = icmp ne i16 %r366, 0
+  %r368 = and i1 %r365, %r367
+  br i1 %r368, label %class_field_get.fast.42, label %class_field_inline.guardcall.46
+
+class_field_inline.guardcall.46:
+  %r369 = call i32 @js_typed_feedback_class_field_get_guard(i64 8450987250308612131, double %r323, i32 1, i64 %r329, i64 %r328, i32 3, i32 1)
+  %r370 = icmp ne i32 %r369, 0
+  br i1 %r370, label %class_field_get.fast.42, label %class_field_get.fallback.43
+
+put.dynic.guard.47:
+  %r399 = sub i64 %r385, 8
+  %r400 = inttoptr i64 %r399 to ptr
+  %r401 = load i8, ptr %r400
+  %r402 = icmp eq i8 %r401, 2
+  %r403 = sub i64 %r385, 7
+  %r404 = inttoptr i64 %r403 to ptr
+  %r405 = load i8, ptr %r404
+  %r406 = and i8 %r405, 128
+  %r407 = icmp eq i8 %r406, 0
+  %r408 = sub i64 %r385, 6
+  %r409 = inttoptr i64 %r408 to ptr
+  %r410 = load i16, ptr %r409
+  %r411 = and i16 %r410, 6407
+  %r412 = icmp eq i16 %r411, 0
+  %r413 = inttoptr i64 %r385 to ptr
+  %r414 = load i32, ptr %r413
+  %r415 = icmp eq i32 %r414, 1
+  %r416 = add i64 %r385, 4
+  %r417 = inttoptr i64 %r416 to ptr
+  %r418 = load i32, ptr %r417
+  %r419 = icmp ne i32 %r418, 0
+  %r420 = icmp ne i32 %r418, -2
+  %r421 = add i64 %r385, 16
+  %r422 = inttoptr i64 %r421 to ptr
+  %r423 = load i64, ptr %r422
+  %r424 = add i64 %r385, 8
+  %r425 = inttoptr i64 %r424 to ptr
+  %r426 = load i32, ptr %r425
+  %r427 = add i32 %r426, -2147483648
+  %r428 = icmp ult i32 %r427, 1073741824
+  %r429 = zext i32 %r426 to i64
+  %r430 = or i64 %r429, 4611686018427387904
+  %r431 = select i1 %r428, i64 %r430, i64 %r423
+  %r432 = getelementptr i64, ptr @perry_ic_36, i64 0
+  %r433 = load i64, ptr %r432
+  %r434 = icmp eq i64 %r431, %r433
+  %r435 = icmp ne i64 %r431, 0
+  %r436 = and i1 %r402, %r407
+  %r437 = and i1 %r436, %r412
+  %r438 = and i1 %r437, %r415
+  %r439 = and i1 %r438, %r419
+  %r440 = and i1 %r439, %r420
+  %r441 = and i1 %r440, %r434
+  %r442 = and i1 %r441, %r435
+  br i1 %r442, label %put.dynic.ways.48, label %put.dynic.slow.53
+
+put.dynic.ways.48:
+  %r443 = getelementptr i64, ptr @perry_ic_36, i64 1
+  %r444 = load i64, ptr %r443
+  %r445 = getelementptr i64, ptr @perry_ic_36, i64 2
+  %r446 = load i64, ptr %r445
+  %r447 = icmp eq i64 %r382, %r444
+  br i1 %r447, label %put.dynic.bounds.51, label %put.dynic.way1.49
+
+put.dynic.way1.49:
+  %r448 = getelementptr i64, ptr @perry_ic_36, i64 3
+  %r449 = load i64, ptr %r448
+  %r450 = getelementptr i64, ptr @perry_ic_36, i64 4
+  %r451 = load i64, ptr %r450
+  %r452 = icmp eq i64 %r382, %r449
+  br i1 %r452, label %put.dynic.bounds.51, label %put.dynic.way2.50
+
+put.dynic.way2.50:
+  %r453 = getelementptr i64, ptr @perry_ic_36, i64 5
+  %r454 = load i64, ptr %r453
+  %r455 = getelementptr i64, ptr @perry_ic_36, i64 6
+  %r456 = load i64, ptr %r455
+  %r457 = icmp eq i64 %r382, %r454
+  br i1 %r457, label %put.dynic.bounds.51, label %put.dynic.slow.53
+
+put.dynic.bounds.51:
+  %r458 = phi i64 [ %r446, %put.dynic.ways.48 ], [ %r451, %put.dynic.way1.49 ], [ %r456, %put.dynic.way2.50 ]
+  %r459 = add i64 %r385, 12
+  %r460 = inttoptr i64 %r459 to ptr
+  %r461 = load i32, ptr %r460
+  %r462 = zext i32 %r461 to i64
+  %r463 = icmp ult i64 %r462, 4
+  %r464 = select i1 %r463, i64 4, i64 %r462
+  %r465 = icmp ult i64 %r458, %r464
+  br i1 %r465, label %put.dynic.store.52, label %put.dynic.slow.53
+
+put.dynic.store.52:
+  %r466 = add i64 %r458, 4
+  %r467 = inttoptr i64 %r385 to ptr
+  %r468 = getelementptr inbounds i64, ptr %r467, i64 %r466
+  store double %r379, ptr %r468
+  br label %put.dynic.merge.54
+
+put.dynic.slow.53:
+  %r469 = call double @js_put_value_set_dyn_ic(ptr @perry_ic_36, double %r381, double %r380, double %r379, i32 1)
+  br label %put.dynic.merge.54
+
+put.dynic.merge.54:
+  %r470 = phi double [ %r379, %put.dynic.store.52 ], [ %r469, %put.dynic.slow.53 ]
+  %r471 = load double, ptr %r8
+  %r472 = bitcast double %r471 to i64
+  %r473 = and i64 %r472, 281474976710655
+  %r474 = load double, ptr @batch_ts_.str.4.handle
+  %r475 = bitcast double %r474 to i64
+  %r476 = and i64 %r475, 281474976710655
+  %r477 = load i64, ptr @perry_class_keys_batch_ts__Row
+  %r478 = load volatile i8, ptr @PERRY_CLASS_FIELD_INLINE_GUARD_DISABLED
+  %r479 = icmp eq i8 %r478, 0
+  %r480 = lshr i64 %r472, 48
+  %r481 = icmp eq i64 %r480, 32765
+  %r482 = icmp ugt i64 %r473, 1048575
+  %r483 = and i1 %r481, %r482
+  %r484 = and i1 %r483, %r479
+  br i1 %r484, label %class_field_inline.deref.58, label %class_field_inline.guardcall.59
+
+class_field_get.fast.55:
+  %r519 = inttoptr i64 %r473 to ptr
+  %r520 = getelementptr i8, ptr %r519, i64 32
+  %r521 = getelementptr double, ptr %r520, i64 3
+  %r522 = load double, ptr %r521
+  br label %class_field_get.merge.57
+
+class_field_get.fallback.56:
+  call void @js_typed_feedback_record_fallback_call(i64 8450987250308612133)
+  %r523 = call double @js_object_get_field_by_name_f64(i64 %r472, i64 %r476)
+  br label %class_field_get.merge.57
+
+class_field_get.merge.57:
+  %r524 = phi double [ %r522, %class_field_get.fast.55 ], [ %r523, %class_field_get.fallback.56 ]
+  %r525 = load double, ptr %r66
+  %r526 = bitcast double %r525 to i64
+  %r527 = and i64 %r526, 281474976710655
+  %r528 = load double, ptr @batch_ts_.str.3.handle
+  %r529 = bitcast double %r528 to i64
+  %r530 = and i64 %r529, 281474976710655
+  %r531 = lshr i64 %r526, 48
+  %r532 = icmp eq i64 %r531, 32761
+  %r533 = icmp eq i64 %r531, 32766
+  %r534 = and i64 %r531, 65533
+  %r535 = icmp eq i64 %r534, 32765
+  br i1 %r532, label %pget.recv_sso.60, label %pget.check_class_ref.66
+
+class_field_inline.deref.58:
+  %r485 = inttoptr i64 %r473 to ptr
+  %r486 = getelementptr i8, ptr %r485, i64 -8
+  %r487 = load i8, ptr %r486
+  %r488 = icmp eq i8 %r487, 2
+  %r489 = getelementptr i8, ptr %r485, i64 -7
+  %r490 = load i8, ptr %r489
+  %r491 = and i8 %r490, -128
+  %r492 = icmp eq i8 %r491, 0
+  %r493 = getelementptr i8, ptr %r485, i64 -6
+  %r494 = load i16, ptr %r493
+  %r495 = load i32, ptr %r485
+  %r496 = icmp eq i32 %r495, 1
+  %r497 = getelementptr i8, ptr %r485, i64 4
+  %r498 = load i32, ptr %r497
+  %r499 = icmp eq i32 %r498, 1
+  %r500 = getelementptr i8, ptr %r485, i64 12
+  %r501 = load i32, ptr %r500
+  %r502 = icmp ugt i32 %r501, 3
+  %r503 = getelementptr i8, ptr %r485, i64 16
+  %r504 = load i64, ptr %r503
+  %r505 = icmp eq i64 %r504, %r477
+  %r506 = and i1 %r488, %r492
+  %r507 = and i1 %r506, %r496
+  %r508 = and i1 %r507, %r499
+  %r509 = and i1 %r508, %r502
+  %r510 = and i1 %r509, %r505
+  %r511 = and i16 %r494, 2048
+  %r512 = icmp eq i16 %r511, 0
+  %r513 = and i1 %r510, %r512
+  %r514 = and i16 %r494, 4096
+  %r515 = icmp ne i16 %r514, 0
+  %r516 = and i1 %r513, %r515
+  br i1 %r516, label %class_field_get.fast.55, label %class_field_inline.guardcall.59
+
+class_field_inline.guardcall.59:
+  %r517 = call i32 @js_typed_feedback_class_field_get_guard(i64 8450987250308612133, double %r471, i32 1, i64 %r477, i64 %r476, i32 3, i32 1)
+  %r518 = icmp ne i32 %r517, 0
+  br i1 %r518, label %class_field_get.fast.55, label %class_field_get.fallback.56
+
+pget.recv_sso.60:
+  %r599 = call double @js_object_get_field_by_name_f64(i64 %r526, i64 %r530)
+  br label %pget.recv_merge.64
+
+pget.recv_ok.61:
+  call void @js_typed_feedback_observe_property_get(i64 8450987250308612134, i64 %r527, i64 %r530)
+  %r537 = icmp ugt i64 %r527, 1048575
+  %r538 = ptrtoint ptr @perry_ic_39 to i64
+  %r539 = select i1 %r537, i64 %r527, i64 %r538
+  %r540 = sub i64 %r539, 8
+  %r541 = inttoptr i64 %r540 to ptr
+  %r542 = load i8, ptr %r541
+  %r543 = icmp eq i8 %r542, 2
+  %r544 = and i1 %r537, %r543
+  %r545 = add i64 %r539, 12
+  %r546 = inttoptr i64 %r545 to ptr
+  %r547 = load i32, ptr %r546
+  %r548 = icmp eq i32 %r547, 1129268819
+  %r549 = xor i1 %r548, true
+  %r550 = and i1 %r544, %r549
+  %r551 = inttoptr i64 %r539 to ptr
+  %r552 = load i32, ptr %r551
+  %r553 = icmp eq i32 %r552, 1
+  %r554 = and i1 %r550, %r553
+  %r555 = sub i64 %r539, 6
+  %r556 = inttoptr i64 %r555 to ptr
+  %r557 = load i16, ptr %r556
+  %r558 = and i16 %r557, 2048
+  %r559 = icmp eq i16 %r558, 0
+  %r560 = and i1 %r554, %r559
+  %r561 = add i64 %r539, 16
+  %r562 = inttoptr i64 %r561 to ptr
+  %r563 = load i64, ptr %r562
+  %r564 = add i64 %r539, 8
+  %r565 = inttoptr i64 %r564 to ptr
+  %r566 = load i32, ptr %r565
+  %r567 = add i32 %r566, -2147483648
+  %r568 = icmp ult i32 %r567, 1073741824
+  %r569 = zext i32 %r566 to i64
+  %r570 = or i64 %r569, 4611686018427387904
+  %r571 = select i1 %r568, i64 %r570, i64 %r563
+  %r572 = getelementptr i64, ptr @perry_ic_39, i64 0
+  %r573 = load i64, ptr %r572
+  %r574 = icmp eq i64 %r571, %r573
+  %r575 = icmp ne i64 %r571, 0
+  %r576 = and i1 %r560, %r574
+  %r577 = and i1 %r576, %r575
+  br i1 %r577, label %pic.hit.67, label %pic.miss.68
+
+pget.recv_bad.62:
+  %r594 = icmp eq i64 %r526, 9222246136947933185
+  %r595 = icmp eq i64 %r526, 9222246136947933186
+  %r596 = or i1 %r594, %r595
+  br i1 %r596, label %pget.throw_nullish.71, label %pget.recv_undef_return.72
+
+pget.recv_class_ref.63:
+  %r536 = call double @js_typed_feedback_object_get_field_by_name_f64(i64 8450987250308612134, i64 %r526, i64 %r530)
+  br label %pget.recv_merge.64
+
+pget.recv_merge.64:
+  %r600 = phi double [ %r593, %pic.merge.69 ], [ %r598, %pget.recv_undef_return.72 ], [ %r599, %pget.recv_sso.60 ], [ %r536, %pget.recv_class_ref.63 ]
+  %r601 = call double @js_rel_gt(double %r524, double %r600)
+  %r602 = bitcast double %r601 to i64
+  %r603 = icmp eq i64 %r602, 9222246136947933188
+  br i1 %r603, label %if.then.73, label %if.else.74
+
+pget.check_ptr.65:
+  br i1 %r535, label %pget.recv_ok.61, label %pget.recv_bad.62
+
+pget.check_class_ref.66:
+  br i1 %r533, label %pget.recv_class_ref.63, label %pget.check_ptr.65
+
+pic.hit.67:
+  %r578 = getelementptr i64, ptr @perry_ic_39, i64 1
+  %r579 = load i64, ptr %r578
+  %r580 = add i64 %r539, 12
+  %r581 = inttoptr i64 %r580 to ptr
+  %r582 = load i32, ptr %r581
+  %r583 = zext i32 %r582 to i64
+  %r584 = icmp ult i64 %r583, 4
+  %r585 = select i1 %r584, i64 4, i64 %r583
+  %r586 = icmp ult i64 %r579, %r585
+  br i1 %r586, label %pic.hit.load.70, label %pic.miss.68
+
+pic.miss.68:
+  call void @js_typed_feedback_record_guard_fail(i64 8450987250308612134)
+  call void @js_typed_feedback_record_fallback_call(i64 8450987250308612134)
+  %r592 = call double @js_object_get_field_ic_miss(i64 %r527, i64 %r530, ptr @perry_ic_39)
+  br label %pic.merge.69
+
+pic.merge.69:
+  %r593 = phi double [ %r591, %pic.hit.load.70 ], [ %r592, %pic.miss.68 ]
+  br label %pget.recv_merge.64
+
+pic.hit.load.70:
+  call void @js_typed_feedback_record_guard_pass(i64 8450987250308612134)
+  %r587 = shl i64 %r579, 3
+  %r588 = add i64 %r527, 32
+  %r589 = add i64 %r588, %r587
+  %r590 = inttoptr i64 %r589 to ptr
+  %r591 = load double, ptr %r590
+  br label %pic.merge.69
+
+pget.throw_nullish.71:
+  %r597 = zext i1 %r595 to i32
+  call void @js_throw_type_error_property_access(i32 %r597, ptr @batch_ts_.str.3.bytes, i64 4)
+  unreachable
+
+pget.recv_undef_return.72:
+  %r598 = call double @js_object_get_field_by_name_f64(i64 %r526, i64 %r530)
+  br label %pget.recv_merge.64
+
+if.then.73:
+  %r604 = load double, ptr @batch_ts_.str.3.handle
+  %r605 = load double, ptr %r8
+  %r606 = bitcast double %r605 to i64
+  %r607 = and i64 %r606, 281474976710655
+  %r608 = load double, ptr @batch_ts_.str.4.handle
+  %r609 = bitcast double %r608 to i64
+  %r610 = and i64 %r609, 281474976710655
+  %r611 = load i64, ptr @perry_class_keys_batch_ts__Row
+  %r612 = load volatile i8, ptr @PERRY_CLASS_FIELD_INLINE_GUARD_DISABLED
+  %r613 = icmp eq i8 %r612, 0
+  %r614 = lshr i64 %r606, 48
+  %r615 = icmp eq i64 %r614, 32765
+  %r616 = icmp ugt i64 %r607, 1048575
+  %r617 = and i1 %r615, %r616
+  %r618 = and i1 %r617, %r613
+  br i1 %r618, label %class_field_inline.deref.79, label %class_field_inline.guardcall.80
+
+if.else.74:
+  br label %if.merge.75
+
+if.merge.75:
+  %r750 = load double, ptr %r7
+  %shadow_pop_l_0 = load i64, ptr %r1
+  call void @js_shadow_frame_pop(i64 %shadow_pop_l_0)
+  ret double %r750
+
+class_field_get.fast.76:
+  %r653 = inttoptr i64 %r607 to ptr
+  %r654 = getelementptr i8, ptr %r653, i64 32
+  %r655 = getelementptr double, ptr %r654, i64 3
+  %r656 = load double, ptr %r655
+  br label %class_field_get.merge.78
+
+class_field_get.fallback.77:
+  call void @js_typed_feedback_record_fallback_call(i64 8450987250308612136)
+  %r657 = call double @js_object_get_field_by_name_f64(i64 %r606, i64 %r610)
+  br label %class_field_get.merge.78
+
+class_field_get.merge.78:
+  %r658 = phi double [ %r656, %class_field_get.fast.76 ], [ %r657, %class_field_get.fallback.77 ]
+  %r659 = load double, ptr @batch_ts_.str.3.handle
+  %r660 = load double, ptr %r66
+  %r661 = bitcast double %r659 to i64
+  %r662 = bitcast double %r658 to i64
+  %r663 = bitcast double %r660 to i64
+  %r664 = and i64 %r663, 281474976710655
+  %r665 = lshr i64 %r663, 48
+  %r666 = icmp eq i64 %r665, 32765
+  %r667 = icmp ugt i64 %r664, 1048575
+  %r668 = lshr i64 %r662, 48
+  %r669 = icmp ne i64 %r668, 32765
+  %r670 = icmp ne i64 %r668, 32767
+  %r671 = icmp ne i64 %r668, 32762
+  %r672 = icmp ne i64 %r661, 0
+  %r673 = and i1 %r666, %r667
+  %r674 = and i1 %r673, %r669
+  %r675 = and i1 %r674, %r670
+  %r676 = and i1 %r675, %r671
+  %r677 = and i1 %r676, %r672
+  br i1 %r677, label %put.dynic.guard.81, label %put.dynic.slow.87
+
+class_field_inline.deref.79:
+  %r619 = inttoptr i64 %r607 to ptr
+  %r620 = getelementptr i8, ptr %r619, i64 -8
+  %r621 = load i8, ptr %r620
+  %r622 = icmp eq i8 %r621, 2
+  %r623 = getelementptr i8, ptr %r619, i64 -7
+  %r624 = load i8, ptr %r623
+  %r625 = and i8 %r624, -128
+  %r626 = icmp eq i8 %r625, 0
+  %r627 = getelementptr i8, ptr %r619, i64 -6
+  %r628 = load i16, ptr %r627
+  %r629 = load i32, ptr %r619
+  %r630 = icmp eq i32 %r629, 1
+  %r631 = getelementptr i8, ptr %r619, i64 4
+  %r632 = load i32, ptr %r631
+  %r633 = icmp eq i32 %r632, 1
+  %r634 = getelementptr i8, ptr %r619, i64 12
+  %r635 = load i32, ptr %r634
+  %r636 = icmp ugt i32 %r635, 3
+  %r637 = getelementptr i8, ptr %r619, i64 16
+  %r638 = load i64, ptr %r637
+  %r639 = icmp eq i64 %r638, %r611
+  %r640 = and i1 %r622, %r626
+  %r641 = and i1 %r640, %r630
+  %r642 = and i1 %r641, %r633
+  %r643 = and i1 %r642, %r636
+  %r644 = and i1 %r643, %r639
+  %r645 = and i16 %r628, 2048
+  %r646 = icmp eq i16 %r645, 0
+  %r647 = and i1 %r644, %r646
+  %r648 = and i16 %r628, 4096
+  %r649 = icmp ne i16 %r648, 0
+  %r650 = and i1 %r647, %r649
+  br i1 %r650, label %class_field_get.fast.76, label %class_field_inline.guardcall.80
+
+class_field_inline.guardcall.80:
+  %r651 = call i32 @js_typed_feedback_class_field_get_guard(i64 8450987250308612136, double %r605, i32 1, i64 %r611, i64 %r610, i32 3, i32 1)
+  %r652 = icmp ne i32 %r651, 0
+  br i1 %r652, label %class_field_get.fast.76, label %class_field_get.fallback.77
+
+put.dynic.guard.81:
+  %r678 = sub i64 %r664, 8
+  %r679 = inttoptr i64 %r678 to ptr
+  %r680 = load i8, ptr %r679
+  %r681 = icmp eq i8 %r680, 2
+  %r682 = sub i64 %r664, 7
+  %r683 = inttoptr i64 %r682 to ptr
+  %r684 = load i8, ptr %r683
+  %r685 = and i8 %r684, 128
+  %r686 = icmp eq i8 %r685, 0
+  %r687 = sub i64 %r664, 6
+  %r688 = inttoptr i64 %r687 to ptr
+  %r689 = load i16, ptr %r688
+  %r690 = and i16 %r689, 6407
+  %r691 = icmp eq i16 %r690, 0
+  %r692 = inttoptr i64 %r664 to ptr
+  %r693 = load i32, ptr %r692
+  %r694 = icmp eq i32 %r693, 1
+  %r695 = add i64 %r664, 4
+  %r696 = inttoptr i64 %r695 to ptr
+  %r697 = load i32, ptr %r696
+  %r698 = icmp ne i32 %r697, 0
+  %r699 = icmp ne i32 %r697, -2
+  %r700 = add i64 %r664, 16
+  %r701 = inttoptr i64 %r700 to ptr
+  %r702 = load i64, ptr %r701
+  %r703 = add i64 %r664, 8
+  %r704 = inttoptr i64 %r703 to ptr
+  %r705 = load i32, ptr %r704
+  %r706 = add i32 %r705, -2147483648
+  %r707 = icmp ult i32 %r706, 1073741824
+  %r708 = zext i32 %r705 to i64
+  %r709 = or i64 %r708, 4611686018427387904
+  %r710 = select i1 %r707, i64 %r709, i64 %r702
+  %r711 = getelementptr i64, ptr @perry_ic_41, i64 0
+  %r712 = load i64, ptr %r711
+  %r713 = icmp eq i64 %r710, %r712
+  %r714 = icmp ne i64 %r710, 0
+  %r715 = and i1 %r681, %r686
+  %r716 = and i1 %r715, %r691
+  %r717 = and i1 %r716, %r694
+  %r718 = and i1 %r717, %r698
+  %r719 = and i1 %r718, %r699
+  %r720 = and i1 %r719, %r713
+  %r721 = and i1 %r720, %r714
+  br i1 %r721, label %put.dynic.ways.82, label %put.dynic.slow.87
+
+put.dynic.ways.82:
+  %r722 = getelementptr i64, ptr @perry_ic_41, i64 1
+  %r723 = load i64, ptr %r722
+  %r724 = getelementptr i64, ptr @perry_ic_41, i64 2
+  %r725 = load i64, ptr %r724
+  %r726 = icmp eq i64 %r661, %r723
+  br i1 %r726, label %put.dynic.bounds.85, label %put.dynic.way1.83
+
+put.dynic.way1.83:
+  %r727 = getelementptr i64, ptr @perry_ic_41, i64 3
+  %r728 = load i64, ptr %r727
+  %r729 = getelementptr i64, ptr @perry_ic_41, i64 4
+  %r730 = load i64, ptr %r729
+  %r731 = icmp eq i64 %r661, %r728
+  br i1 %r731, label %put.dynic.bounds.85, label %put.dynic.way2.84
+
+put.dynic.way2.84:
+  %r732 = getelementptr i64, ptr @perry_ic_41, i64 5
+  %r733 = load i64, ptr %r732
+  %r734 = getelementptr i64, ptr @perry_ic_41, i64 6
+  %r735 = load i64, ptr %r734
+  %r736 = icmp eq i64 %r661, %r733
+  br i1 %r736, label %put.dynic.bounds.85, label %put.dynic.slow.87
+
+put.dynic.bounds.85:
+  %r737 = phi i64 [ %r725, %put.dynic.ways.82 ], [ %r730, %put.dynic.way1.83 ], [ %r735, %put.dynic.way2.84 ]
+  %r738 = add i64 %r664, 12
+  %r739 = inttoptr i64 %r738 to ptr
+  %r740 = load i32, ptr %r739
+  %r741 = zext i32 %r740 to i64
+  %r742 = icmp ult i64 %r741, 4
+  %r743 = select i1 %r742, i64 4, i64 %r741
+  %r744 = icmp ult i64 %r737, %r743
+  br i1 %r744, label %put.dynic.store.86, label %put.dynic.slow.87
+
+put.dynic.store.86:
+  %r745 = add i64 %r737, 4
+  %r746 = inttoptr i64 %r664 to ptr
+  %r747 = getelementptr inbounds i64, ptr %r746, i64 %r745
+  store double %r658, ptr %r747
+  br label %put.dynic.merge.88
+
+put.dynic.slow.87:
+  %r748 = call double @js_put_value_set_dyn_ic(ptr @perry_ic_41, double %r660, double %r659, double %r658, i32 1)
+  br label %put.dynic.merge.88
+
+put.dynic.merge.88:
+  %r749 = phi double [ %r658, %put.dynic.store.86 ], [ %r748, %put.dynic.slow.87 ]
+  br label %if.merge.75
+}
+
+define double @perry_method_batch_ts__Row__rescore(double %this_arg, double %arg13) {
+entry.0:
+  %r1 = alloca i64
+  %r2 = alloca ptr
+  store ptr null, ptr %r2
+  %r3 = call ptr @js_shadow_frame_enter(i32 1)
+  store ptr %r3, ptr %r2
+  %r4 = getelementptr inbounds i8, ptr %r3, i64 24
+  %r5 = load i64, ptr %r4
+  %r6 = sub i64 %r5, 1
+  store i64 %r6, ptr %r1
+  %r7 = alloca double
+  store double %this_arg, ptr %r7
+  call void @js_shadow_slot_bind(i32 0, ptr %r7)
+  %r8 = alloca double
+  store double %arg13, ptr %r8
+  %r9 = load double, ptr %r7
+  %r10 = load double, ptr %r7
+  %r11 = bitcast double %r10 to i64
+  %r12 = and i64 %r11, 281474976710655
+  %r13 = load double, ptr @batch_ts_.str.2.handle
+  %r14 = bitcast double %r13 to i64
+  %r15 = and i64 %r14, 281474976710655
+  %r16 = load i64, ptr @perry_class_keys_batch_ts__Row
+  %r17 = load volatile i8, ptr @PERRY_CLASS_FIELD_INLINE_GUARD_DISABLED
+  %r18 = icmp eq i8 %r17, 0
+  %r19 = lshr i64 %r11, 48
+  %r20 = icmp eq i64 %r19, 32765
+  %r21 = icmp ugt i64 %r12, 1048575
+  %r22 = and i1 %r20, %r21
+  %r23 = and i1 %r22, %r18
+  br i1 %r23, label %class_field_inline.deref.4, label %class_field_inline.guardcall.5
+
+class_field_get_number.fast.1:
+  %r58 = inttoptr i64 %r12 to ptr
+  %r59 = getelementptr i8, ptr %r58, i64 32
+  %r60 = getelementptr double, ptr %r59, i64 2
+  %r61 = load double, ptr %r60
+  br label %class_field_get_number.merge.3
+
+class_field_get_number.fallback.2:
+  call void @js_typed_feedback_record_fallback_call(i64 8450987250308612138)
+  %r62 = call double @js_object_get_field_by_name_f64(i64 %r11, i64 %r15)
+  %r63 = call double @js_number_coerce(double %r62)
+  br label %class_field_get_number.merge.3
+
+class_field_get_number.merge.3:
+  %r64 = phi double [ %r61, %class_field_get_number.fast.1 ], [ %r63, %class_field_get_number.fallback.2 ]
+  %r65 = load double, ptr %r8
+  %r66 = fmul double %r64, %r65
+  %r67 = load double, ptr %r7
+  %r68 = bitcast double %r67 to i64
+  %r69 = and i64 %r68, 281474976710655
+  %r70 = load double, ptr @batch_ts_.str.7.handle
+  %r71 = bitcast double %r70 to i64
+  %r72 = and i64 %r71, 281474976710655
+  %r73 = load i64, ptr @perry_class_keys_batch_ts__Row
+  %r74 = load volatile i8, ptr @PERRY_CLASS_FIELD_INLINE_GUARD_DISABLED
+  %r75 = icmp eq i8 %r74, 0
+  %r76 = lshr i64 %r68, 48
+  %r77 = icmp eq i64 %r76, 32765
+  %r78 = icmp ugt i64 %r69, 1048575
+  %r79 = and i1 %r77, %r78
+  %r80 = and i1 %r79, %r75
+  br i1 %r80, label %class_field_inline.deref.9, label %class_field_inline.guardcall.10
+
+class_field_inline.deref.4:
+  %r24 = inttoptr i64 %r12 to ptr
+  %r25 = getelementptr i8, ptr %r24, i64 -8
+  %r26 = load i8, ptr %r25
+  %r27 = icmp eq i8 %r26, 2
+  %r28 = getelementptr i8, ptr %r24, i64 -7
+  %r29 = load i8, ptr %r28
+  %r30 = and i8 %r29, -128
+  %r31 = icmp eq i8 %r30, 0
+  %r32 = getelementptr i8, ptr %r24, i64 -6
+  %r33 = load i16, ptr %r32
+  %r34 = load i32, ptr %r24
+  %r35 = icmp eq i32 %r34, 1
+  %r36 = getelementptr i8, ptr %r24, i64 4
+  %r37 = load i32, ptr %r36
+  %r38 = icmp eq i32 %r37, 1
+  %r39 = getelementptr i8, ptr %r24, i64 12
+  %r40 = load i32, ptr %r39
+  %r41 = icmp ugt i32 %r40, 2
+  %r42 = getelementptr i8, ptr %r24, i64 16
+  %r43 = load i64, ptr %r42
+  %r44 = icmp eq i64 %r43, %r16
+  %r45 = and i1 %r27, %r31
+  %r46 = and i1 %r45, %r35
+  %r47 = and i1 %r46, %r38
+  %r48 = and i1 %r47, %r41
+  %r49 = and i1 %r48, %r44
+  %r50 = and i16 %r33, 2048
+  %r51 = icmp eq i16 %r50, 0
+  %r52 = and i1 %r49, %r51
+  %r53 = and i16 %r33, 4096
+  %r54 = icmp ne i16 %r53, 0
+  %r55 = and i1 %r52, %r54
+  br i1 %r55, label %class_field_get_number.fast.1, label %class_field_inline.guardcall.5
+
+class_field_inline.guardcall.5:
+  %r56 = call i32 @js_typed_feedback_class_field_get_guard(i64 8450987250308612138, double %r10, i32 1, i64 %r16, i64 %r15, i32 2, i32 1)
+  %r57 = icmp ne i32 %r56, 0
+  br i1 %r57, label %class_field_get_number.fast.1, label %class_field_get_number.fallback.2
+
+class_field_get_number.fast.6:
+  %r115 = inttoptr i64 %r69 to ptr
+  %r116 = getelementptr i8, ptr %r115, i64 32
+  %r117 = getelementptr double, ptr %r116, i64 0
+  %r118 = load double, ptr %r117
+  br label %class_field_get_number.merge.8
+
+class_field_get_number.fallback.7:
+  call void @js_typed_feedback_record_fallback_call(i64 8450987250308612139)
+  %r119 = call double @js_object_get_field_by_name_f64(i64 %r68, i64 %r72)
+  %r120 = call double @js_number_coerce(double %r119)
+  br label %class_field_get_number.merge.8
+
+class_field_get_number.merge.8:
+  %r121 = phi double [ %r118, %class_field_get_number.fast.6 ], [ %r120, %class_field_get_number.fallback.7 ]
+  %r122 = frem double %r121, 7.0
+  %r123 = fadd double %r66, %r122
+  %r124 = bitcast double %r9 to i64
+  %r125 = and i64 %r124, 281474976710655
+  %r126 = load double, ptr @batch_ts_.str.4.handle
+  %r127 = bitcast double %r126 to i64
+  %r128 = and i64 %r127, 281474976710655
+  %r129 = load i64, ptr @perry_class_keys_batch_ts__Row
+  %r130 = bitcast double %r123 to i64
+  %r131 = load volatile i8, ptr @PERRY_CLASS_FIELD_INLINE_GUARD_DISABLED
+  %r132 = icmp eq i8 %r131, 0
+  %r133 = lshr i64 %r124, 48
+  %r134 = icmp eq i64 %r133, 32765
+  %r135 = icmp ugt i64 %r125, 1048575
+  %r136 = and i1 %r134, %r135
+  %r137 = and i1 %r136, %r132
+  br i1 %r137, label %class_field_inline.deref.14, label %class_field_inline.guardcall.15
+
+class_field_inline.deref.9:
+  %r81 = inttoptr i64 %r69 to ptr
+  %r82 = getelementptr i8, ptr %r81, i64 -8
+  %r83 = load i8, ptr %r82
+  %r84 = icmp eq i8 %r83, 2
+  %r85 = getelementptr i8, ptr %r81, i64 -7
+  %r86 = load i8, ptr %r85
+  %r87 = and i8 %r86, -128
+  %r88 = icmp eq i8 %r87, 0
+  %r89 = getelementptr i8, ptr %r81, i64 -6
+  %r90 = load i16, ptr %r89
+  %r91 = load i32, ptr %r81
+  %r92 = icmp eq i32 %r91, 1
+  %r93 = getelementptr i8, ptr %r81, i64 4
+  %r94 = load i32, ptr %r93
+  %r95 = icmp eq i32 %r94, 1
+  %r96 = getelementptr i8, ptr %r81, i64 12
+  %r97 = load i32, ptr %r96
+  %r98 = icmp ugt i32 %r97, 0
+  %r99 = getelementptr i8, ptr %r81, i64 16
+  %r100 = load i64, ptr %r99
+  %r101 = icmp eq i64 %r100, %r73
+  %r102 = and i1 %r84, %r88
+  %r103 = and i1 %r102, %r92
+  %r104 = and i1 %r103, %r95
+  %r105 = and i1 %r104, %r98
+  %r106 = and i1 %r105, %r101
+  %r107 = and i16 %r90, 2048
+  %r108 = icmp eq i16 %r107, 0
+  %r109 = and i1 %r106, %r108
+  %r110 = and i16 %r90, 4096
+  %r111 = icmp ne i16 %r110, 0
+  %r112 = and i1 %r109, %r111
+  br i1 %r112, label %class_field_get_number.fast.6, label %class_field_inline.guardcall.10
+
+class_field_inline.guardcall.10:
+  %r113 = call i32 @js_typed_feedback_class_field_get_guard(i64 8450987250308612139, double %r67, i32 1, i64 %r73, i64 %r72, i32 0, i32 1)
+  %r114 = icmp ne i32 %r113, 0
+  br i1 %r114, label %class_field_get_number.fast.6, label %class_field_get_number.fallback.7
+
+class_field_set.fast.11:
+  %r178 = inttoptr i64 %r125 to ptr
+  %r179 = getelementptr i8, ptr %r178, i64 32
+  %r180 = getelementptr double, ptr %r179, i64 3
+  %r181 = call double @js_array_numeric_value_to_raw_f64(double %r123)
+  store double %r181, ptr %r180
+  br label %class_field_set.merge.13
+
+class_field_set.fallback.12:
+  call void @js_class_field_set_fallback(i64 8450987250308612140, i64 %r124, i64 %r128, double %r123)
+  br label %class_field_set.merge.13
+
+class_field_set.merge.13:
+  %r182 = load double, ptr %r7
+  %r183 = bitcast double %r182 to i64
+  %r184 = and i64 %r183, 281474976710655
+  %r185 = load double, ptr @batch_ts_.str.4.handle
+  %r186 = bitcast double %r185 to i64
+  %r187 = and i64 %r186, 281474976710655
+  %r188 = load i64, ptr @perry_class_keys_batch_ts__Row
+  %r189 = load volatile i8, ptr @PERRY_CLASS_FIELD_INLINE_GUARD_DISABLED
+  %r190 = icmp eq i8 %r189, 0
+  %r191 = lshr i64 %r183, 48
+  %r192 = icmp eq i64 %r191, 32765
+  %r193 = icmp ugt i64 %r184, 1048575
+  %r194 = and i1 %r192, %r193
+  %r195 = and i1 %r194, %r190
+  br i1 %r195, label %class_field_inline.deref.19, label %class_field_inline.guardcall.20
+
+class_field_inline.deref.14:
+  %r138 = inttoptr i64 %r125 to ptr
+  %r139 = getelementptr i8, ptr %r138, i64 -8
+  %r140 = load i8, ptr %r139
+  %r141 = icmp eq i8 %r140, 2
+  %r142 = getelementptr i8, ptr %r138, i64 -7
+  %r143 = load i8, ptr %r142
+  %r144 = and i8 %r143, -128
+  %r145 = icmp eq i8 %r144, 0
+  %r146 = getelementptr i8, ptr %r138, i64 -6
+  %r147 = load i16, ptr %r146
+  %r148 = load i32, ptr %r138
+  %r149 = icmp eq i32 %r148, 1
+  %r150 = getelementptr i8, ptr %r138, i64 4
+  %r151 = load i32, ptr %r150
+  %r152 = icmp eq i32 %r151, 1
+  %r153 = getelementptr i8, ptr %r138, i64 12
+  %r154 = load i32, ptr %r153
+  %r155 = icmp ugt i32 %r154, 3
+  %r156 = getelementptr i8, ptr %r138, i64 16
+  %r157 = load i64, ptr %r156
+  %r158 = icmp eq i64 %r157, %r129
+  %r159 = and i1 %r141, %r145
+  %r160 = and i1 %r159, %r149
+  %r161 = and i1 %r160, %r152
+  %r162 = and i1 %r161, %r155
+  %r163 = and i1 %r162, %r158
+  %r164 = and i16 %r147, 2048
+  %r165 = icmp eq i16 %r164, 0
+  %r166 = and i1 %r163, %r165
+  %r167 = and i16 %r147, 4096
+  %r168 = icmp ne i16 %r167, 0
+  %r169 = and i1 %r166, %r168
+  %r170 = and i16 %r147, 1
+  %r171 = icmp eq i16 %r170, 0
+  %r172 = and i1 %r169, %r171
+  %r173 = and i64 %r130, 9218868437227405312
+  %r174 = icmp ne i64 %r173, 9218868437227405312
+  %r175 = and i1 %r172, %r174
+  br i1 %r175, label %class_field_set.fast.11, label %class_field_inline.guardcall.15
+
+class_field_inline.guardcall.15:
+  %r176 = call i32 @js_typed_feedback_class_field_set_guard(i64 8450987250308612140, double %r9, i32 1, i64 %r129, i64 %r128, i32 3, double %r123, i32 1)
+  %r177 = icmp ne i32 %r176, 0
+  br i1 %r177, label %class_field_set.fast.11, label %class_field_set.fallback.12
+
+class_field_get.fast.16:
+  %r230 = inttoptr i64 %r184 to ptr
+  %r231 = getelementptr i8, ptr %r230, i64 32
+  %r232 = getelementptr double, ptr %r231, i64 3
+  %r233 = load double, ptr %r232
+  br label %class_field_get.merge.18
+
+class_field_get.fallback.17:
+  call void @js_typed_feedback_record_fallback_call(i64 8450987250308612141)
+  %r234 = call double @js_object_get_field_by_name_f64(i64 %r183, i64 %r187)
+  br label %class_field_get.merge.18
+
+class_field_get.merge.18:
+  %r235 = phi double [ %r233, %class_field_get.fast.16 ], [ %r234, %class_field_get.fallback.17 ]
+  %shadow_pop_l_0 = load i64, ptr %r1
+  call void @js_shadow_frame_pop(i64 %shadow_pop_l_0)
+  ret double %r235
+
+class_field_inline.deref.19:
+  %r196 = inttoptr i64 %r184 to ptr
+  %r197 = getelementptr i8, ptr %r196, i64 -8
+  %r198 = load i8, ptr %r197
+  %r199 = icmp eq i8 %r198, 2
+  %r200 = getelementptr i8, ptr %r196, i64 -7
+  %r201 = load i8, ptr %r200
+  %r202 = and i8 %r201, -128
+  %r203 = icmp eq i8 %r202, 0
+  %r204 = getelementptr i8, ptr %r196, i64 -6
+  %r205 = load i16, ptr %r204
+  %r206 = load i32, ptr %r196
+  %r207 = icmp eq i32 %r206, 1
+  %r208 = getelementptr i8, ptr %r196, i64 4
+  %r209 = load i32, ptr %r208
+  %r210 = icmp eq i32 %r209, 1
+  %r211 = getelementptr i8, ptr %r196, i64 12
+  %r212 = load i32, ptr %r211
+  %r213 = icmp ugt i32 %r212, 3
+  %r214 = getelementptr i8, ptr %r196, i64 16
+  %r215 = load i64, ptr %r214
+  %r216 = icmp eq i64 %r215, %r188
+  %r217 = and i1 %r199, %r203
+  %r218 = and i1 %r217, %r207
+  %r219 = and i1 %r218, %r210
+  %r220 = and i1 %r219, %r213
+  %r221 = and i1 %r220, %r216
+  %r222 = and i16 %r205, 2048
+  %r223 = icmp eq i16 %r222, 0
+  %r224 = and i1 %r221, %r223
+  %r225 = and i16 %r205, 4096
+  %r226 = icmp ne i16 %r225, 0
+  %r227 = and i1 %r224, %r226
+  br i1 %r227, label %class_field_get.fast.16, label %class_field_inline.guardcall.20
+
+class_field_inline.guardcall.20:
+  %r228 = call i32 @js_typed_feedback_class_field_get_guard(i64 8450987250308612141, double %r182, i32 1, i64 %r188, i64 %r187, i32 3, i32 1)
+  %r229 = icmp ne i32 %r228, 0
+  br i1 %r229, label %class_field_get.fast.16, label %class_field_get.fallback.17
+}
+
+define internal double @perry_method_batch_ts__Row__rescore__pshape(double %this_arg, double %arg13) {
+entry.0:
+  %r1 = alloca i64
+  %r2 = alloca ptr
+  store ptr null, ptr %r2
+  %r3 = call ptr @js_shadow_frame_enter(i32 1)
+  store ptr %r3, ptr %r2
+  %r4 = getelementptr inbounds i8, ptr %r3, i64 24
+  %r5 = load i64, ptr %r4
+  %r6 = sub i64 %r5, 1
+  store i64 %r6, ptr %r1
+  %r7 = alloca double
+  store double %this_arg, ptr %r7
+  call void @js_shadow_slot_bind(i32 0, ptr %r7)
+  %r8 = alloca double
+  store double %arg13, ptr %r8
+  %r9 = load double, ptr %r7
+  %r10 = load double, ptr %r7
+  %r11 = bitcast double %r10 to i64
+  %r12 = and i64 %r11, 281474976710655
+  %r13 = inttoptr i64 %r12 to ptr
+  %r14 = getelementptr i8, ptr %r13, i64 32
+  %r15 = getelementptr double, ptr %r14, i64 2
+  %r16 = load double, ptr %r15
+  %r17 = bitcast double %r16 to i64
+  %r18 = and i64 %r17, 9218868437227405312
+  %r19 = icmp ne i64 %r18, 9218868437227405312
+  br i1 %r19, label %ptr_shape_get_number.plain.1, label %ptr_shape_get_number.coerce.2
+
+ptr_shape_get_number.plain.1:
+  br label %ptr_shape_get_number.merge.3
+
+ptr_shape_get_number.coerce.2:
+  %r20 = call double @js_number_coerce(double %r16)
+  br label %ptr_shape_get_number.merge.3
+
+ptr_shape_get_number.merge.3:
+  %r21 = phi double [ %r16, %ptr_shape_get_number.plain.1 ], [ %r20, %ptr_shape_get_number.coerce.2 ]
+  %r22 = load double, ptr %r8
+  %r23 = fmul double %r21, %r22
+  %r24 = load double, ptr %r7
+  %r25 = bitcast double %r24 to i64
+  %r26 = and i64 %r25, 281474976710655
+  %r27 = inttoptr i64 %r26 to ptr
+  %r28 = getelementptr i8, ptr %r27, i64 32
+  %r29 = getelementptr double, ptr %r28, i64 0
+  %r30 = load double, ptr %r29
+  %r31 = bitcast double %r30 to i64
+  %r32 = and i64 %r31, 9218868437227405312
+  %r33 = icmp ne i64 %r32, 9218868437227405312
+  br i1 %r33, label %ptr_shape_get_number.plain.4, label %ptr_shape_get_number.coerce.5
+
+ptr_shape_get_number.plain.4:
+  br label %ptr_shape_get_number.merge.6
+
+ptr_shape_get_number.coerce.5:
+  %r34 = call double @js_number_coerce(double %r30)
+  br label %ptr_shape_get_number.merge.6
+
+ptr_shape_get_number.merge.6:
+  %r35 = phi double [ %r30, %ptr_shape_get_number.plain.4 ], [ %r34, %ptr_shape_get_number.coerce.5 ]
+  %r36 = frem double %r35, 7.0
+  %r37 = fadd double %r23, %r36
+  %r38 = bitcast double %r9 to i64
+  %r39 = and i64 %r38, 281474976710655
+  %r40 = inttoptr i64 %r39 to ptr
+  %r41 = getelementptr i8, ptr %r40, i64 32
+  %r42 = getelementptr double, ptr %r41, i64 3
+  %r43 = bitcast double %r37 to i64
+  %r44 = and i64 %r43, 9218868437227405312
+  %r45 = icmp ne i64 %r44, 9218868437227405312
+  br i1 %r45, label %ptr_shape_set.raw_store.7, label %ptr_shape_set.downgrade.8
+
+ptr_shape_set.raw_store.7:
+  store double %r37, ptr %r42
+  br label %ptr_shape_set.merge.9
+
+ptr_shape_set.downgrade.8:
+  %r46 = load double, ptr @batch_ts_.str.4.handle
+  %r47 = bitcast double %r46 to i64
+  %r48 = and i64 %r47, 281474976710655
+  call void @js_class_field_set_fallback(i64 8450987250308612142, i64 %r38, i64 %r48, double %r37)
+  br label %ptr_shape_set.merge.9
+
+ptr_shape_set.merge.9:
+  %r49 = load double, ptr %r7
+  %r50 = bitcast double %r49 to i64
+  %r51 = and i64 %r50, 281474976710655
+  %r52 = inttoptr i64 %r51 to ptr
+  %r53 = getelementptr i8, ptr %r52, i64 32
+  %r54 = getelementptr double, ptr %r53, i64 3
+  %r55 = load double, ptr %r54
+  %shadow_pop_l_0 = load i64, ptr %r1
+  call void @js_shadow_frame_pop(i64 %shadow_pop_l_0)
+  ret double %r55
+}
+
+define double @batch_ts__Row_constructor(double %this_arg, double %arg9, double %arg10, double %arg11) {
+entry.0:
+  %r1 = alloca i64
+  %r2 = alloca ptr
+  store ptr null, ptr %r2
+  %r3 = call ptr @js_shadow_frame_enter(i32 2)
+  store ptr %r3, ptr %r2
+  %r4 = getelementptr inbounds i8, ptr %r3, i64 24
+  %r5 = load i64, ptr %r4
+  %r6 = sub i64 %r5, 1
+  store i64 %r6, ptr %r1
+  %r7 = alloca double
+  store double %this_arg, ptr %r7
+  call void @js_shadow_slot_bind(i32 1, ptr %r7)
+  %r8 = alloca double
+  store double %arg9, ptr %r8
+  %r9 = alloca double
+  store double %arg10, ptr %r9
+  call void @js_shadow_slot_bind(i32 0, ptr %r9)
+  %r10 = alloca double
+  store double %arg11, ptr %r10
+  %r11 = load double, ptr %r7
+  %r12 = bitcast double %r11 to i64
+  %r13 = and i64 %r12, 281474976710655
+  %r14 = load double, ptr @batch_ts_.str.7.handle
+  %r15 = bitcast double %r14 to i64
+  %r16 = and i64 %r15, 281474976710655
+  %r17 = load i64, ptr @perry_class_keys_batch_ts__Row
+  %r18 = bitcast double 0x7FFC000000000001 to i64
+  %r19 = load volatile i8, ptr @PERRY_CLASS_FIELD_INLINE_GUARD_DISABLED
+  %r20 = icmp eq i8 %r19, 0
+  %r21 = lshr i64 %r12, 48
+  %r22 = icmp eq i64 %r21, 32765
+  %r23 = icmp ugt i64 %r13, 1048575
+  %r24 = and i1 %r22, %r23
+  %r25 = and i1 %r24, %r20
+  br i1 %r25, label %class_field_inline.deref.4, label %class_field_inline.guardcall.5
+
+class_field_set.fast.1:
+  %r66 = inttoptr i64 %r13 to ptr
+  %r67 = getelementptr i8, ptr %r66, i64 32
+  %r68 = getelementptr double, ptr %r67, i64 0
+  %r69 = call double @js_array_numeric_value_to_raw_f64(double 0x7FFC000000000001)
+  store double %r69, ptr %r68
+  br label %class_field_set.merge.3
+
+class_field_set.fallback.2:
+  call void @js_class_field_set_fallback(i64 8450987250308612143, i64 %r12, i64 %r16, double 0x7FFC000000000001)
+  br label %class_field_set.merge.3
+
+class_field_set.merge.3:
+  %r70 = load double, ptr %r7
+  %r71 = bitcast double %r70 to i64
+  %r72 = and i64 %r71, 281474976710655
+  %r73 = load double, ptr @batch_ts_.str.5.handle
+  %r74 = bitcast double %r73 to i64
+  %r75 = and i64 %r74, 281474976710655
+  %r76 = load i64, ptr @perry_class_keys_batch_ts__Row
+  %r77 = bitcast double 0x7FFC000000000001 to i64
+  %r78 = call i32 @js_typed_feedback_class_field_set_guard(i64 8450987250308612144, double %r70, i32 1, i64 %r76, i64 %r75, i32 1, double 0x7FFC000000000001, i32 0)
+  %r79 = icmp ne i32 %r78, 0
+  br i1 %r79, label %class_field_set.fast.6, label %class_field_set.fallback.7
+
+class_field_inline.deref.4:
+  %r26 = inttoptr i64 %r13 to ptr
+  %r27 = getelementptr i8, ptr %r26, i64 -8
+  %r28 = load i8, ptr %r27
+  %r29 = icmp eq i8 %r28, 2
+  %r30 = getelementptr i8, ptr %r26, i64 -7
+  %r31 = load i8, ptr %r30
+  %r32 = and i8 %r31, -128
+  %r33 = icmp eq i8 %r32, 0
+  %r34 = getelementptr i8, ptr %r26, i64 -6
+  %r35 = load i16, ptr %r34
+  %r36 = load i32, ptr %r26
+  %r37 = icmp eq i32 %r36, 1
+  %r38 = getelementptr i8, ptr %r26, i64 4
+  %r39 = load i32, ptr %r38
+  %r40 = icmp eq i32 %r39, 1
+  %r41 = getelementptr i8, ptr %r26, i64 12
+  %r42 = load i32, ptr %r41
+  %r43 = icmp ugt i32 %r42, 0
+  %r44 = getelementptr i8, ptr %r26, i64 16
+  %r45 = load i64, ptr %r44
+  %r46 = icmp eq i64 %r45, %r17
+  %r47 = and i1 %r29, %r33
+  %r48 = and i1 %r47, %r37
+  %r49 = and i1 %r48, %r40
+  %r50 = and i1 %r49, %r43
+  %r51 = and i1 %r50, %r46
+  %r52 = and i16 %r35, 2048
+  %r53 = icmp eq i16 %r52, 0
+  %r54 = and i1 %r51, %r53
+  %r55 = and i16 %r35, 4096
+  %r56 = icmp ne i16 %r55, 0
+  %r57 = and i1 %r54, %r56
+  %r58 = and i16 %r35, 1
+  %r59 = icmp eq i16 %r58, 0
+  %r60 = and i1 %r57, %r59
+  %r61 = and i64 %r18, 9218868437227405312
+  %r62 = icmp ne i64 %r61, 9218868437227405312
+  %r63 = and i1 %r60, %r62
+  br i1 %r63, label %class_field_set.fast.1, label %class_field_inline.guardcall.5
+
+class_field_inline.guardcall.5:
+  %r64 = call i32 @js_typed_feedback_class_field_set_guard(i64 8450987250308612143, double %r11, i32 1, i64 %r17, i64 %r16, i32 0, double 0x7FFC000000000001, i32 1)
+  %r65 = icmp ne i32 %r64, 0
+  br i1 %r65, label %class_field_set.fast.1, label %class_field_set.fallback.2
+
+class_field_set.fast.6:
+  %r80 = inttoptr i64 %r72 to ptr
+  %r81 = getelementptr i8, ptr %r80, i64 32
+  %r82 = getelementptr double, ptr %r81, i64 1
+  %r83 = ptrtoint ptr %r82 to i64
+  store double 0x7FFC000000000001, ptr %r82
+  call void @js_string_addref_if_heap_string(double 0x7FFC000000000001)
+  %r84 = bitcast double 0x7FFC000000000001 to i64
+  call void @js_gc_note_slot_layout(i64 %r72, i32 1, i64 %r84)
+  br label %class_field_set.merge.8
+
+class_field_set.fallback.7:
+  call void @js_class_field_set_fallback(i64 8450987250308612144, i64 %r71, i64 %r75, double 0x7FFC000000000001)
+  br label %class_field_set.merge.8
+
+class_field_set.merge.8:
+  %r85 = load double, ptr %r7
+  %r86 = bitcast double %r85 to i64
+  %r87 = and i64 %r86, 281474976710655
+  %r88 = load double, ptr @batch_ts_.str.2.handle
+  %r89 = bitcast double %r88 to i64
+  %r90 = and i64 %r89, 281474976710655
+  %r91 = load i64, ptr @perry_class_keys_batch_ts__Row
+  %r92 = bitcast double 0x7FFC000000000001 to i64
+  %r93 = load volatile i8, ptr @PERRY_CLASS_FIELD_INLINE_GUARD_DISABLED
+  %r94 = icmp eq i8 %r93, 0
+  %r95 = lshr i64 %r86, 48
+  %r96 = icmp eq i64 %r95, 32765
+  %r97 = icmp ugt i64 %r87, 1048575
+  %r98 = and i1 %r96, %r97
+  %r99 = and i1 %r98, %r94
+  br i1 %r99, label %class_field_inline.deref.12, label %class_field_inline.guardcall.13
+
+class_field_set.fast.9:
+  %r140 = inttoptr i64 %r87 to ptr
+  %r141 = getelementptr i8, ptr %r140, i64 32
+  %r142 = getelementptr double, ptr %r141, i64 2
+  %r143 = call double @js_array_numeric_value_to_raw_f64(double 0x7FFC000000000001)
+  store double %r143, ptr %r142
+  br label %class_field_set.merge.11
+
+class_field_set.fallback.10:
+  call void @js_class_field_set_fallback(i64 8450987250308612145, i64 %r86, i64 %r90, double 0x7FFC000000000001)
+  br label %class_field_set.merge.11
+
+class_field_set.merge.11:
+  %r144 = load double, ptr %r7
+  %r145 = bitcast double %r144 to i64
+  %r146 = and i64 %r145, 281474976710655
+  %r147 = load double, ptr @batch_ts_.str.4.handle
+  %r148 = bitcast double %r147 to i64
+  %r149 = and i64 %r148, 281474976710655
+  %r150 = load i64, ptr @perry_class_keys_batch_ts__Row
+  %r151 = bitcast double 0x7FFC000000000001 to i64
+  %r152 = load volatile i8, ptr @PERRY_CLASS_FIELD_INLINE_GUARD_DISABLED
+  %r153 = icmp eq i8 %r152, 0
+  %r154 = lshr i64 %r145, 48
+  %r155 = icmp eq i64 %r154, 32765
+  %r156 = icmp ugt i64 %r146, 1048575
+  %r157 = and i1 %r155, %r156
+  %r158 = and i1 %r157, %r153
+  br i1 %r158, label %class_field_inline.deref.17, label %class_field_inline.guardcall.18
+
+class_field_inline.deref.12:
+  %r100 = inttoptr i64 %r87 to ptr
+  %r101 = getelementptr i8, ptr %r100, i64 -8
+  %r102 = load i8, ptr %r101
+  %r103 = icmp eq i8 %r102, 2
+  %r104 = getelementptr i8, ptr %r100, i64 -7
+  %r105 = load i8, ptr %r104
+  %r106 = and i8 %r105, -128
+  %r107 = icmp eq i8 %r106, 0
+  %r108 = getelementptr i8, ptr %r100, i64 -6
+  %r109 = load i16, ptr %r108
+  %r110 = load i32, ptr %r100
+  %r111 = icmp eq i32 %r110, 1
+  %r112 = getelementptr i8, ptr %r100, i64 4
+  %r113 = load i32, ptr %r112
+  %r114 = icmp eq i32 %r113, 1
+  %r115 = getelementptr i8, ptr %r100, i64 12
+  %r116 = load i32, ptr %r115
+  %r117 = icmp ugt i32 %r116, 2
+  %r118 = getelementptr i8, ptr %r100, i64 16
+  %r119 = load i64, ptr %r118
+  %r120 = icmp eq i64 %r119, %r91
+  %r121 = and i1 %r103, %r107
+  %r122 = and i1 %r121, %r111
+  %r123 = and i1 %r122, %r114
+  %r124 = and i1 %r123, %r117
+  %r125 = and i1 %r124, %r120
+  %r126 = and i16 %r109, 2048
+  %r127 = icmp eq i16 %r126, 0
+  %r128 = and i1 %r125, %r127
+  %r129 = and i16 %r109, 4096
+  %r130 = icmp ne i16 %r129, 0
+  %r131 = and i1 %r128, %r130
+  %r132 = and i16 %r109, 1
+  %r133 = icmp eq i16 %r132, 0
+  %r134 = and i1 %r131, %r133
+  %r135 = and i64 %r92, 9218868437227405312
+  %r136 = icmp ne i64 %r135, 9218868437227405312
+  %r137 = and i1 %r134, %r136
+  br i1 %r137, label %class_field_set.fast.9, label %class_field_inline.guardcall.13
+
+class_field_inline.guardcall.13:
+  %r138 = call i32 @js_typed_feedback_class_field_set_guard(i64 8450987250308612145, double %r85, i32 1, i64 %r91, i64 %r90, i32 2, double 0x7FFC000000000001, i32 1)
+  %r139 = icmp ne i32 %r138, 0
+  br i1 %r139, label %class_field_set.fast.9, label %class_field_set.fallback.10
+
+class_field_set.fast.14:
+  %r199 = inttoptr i64 %r146 to ptr
+  %r200 = getelementptr i8, ptr %r199, i64 32
+  %r201 = getelementptr double, ptr %r200, i64 3
+  %r202 = call double @js_array_numeric_value_to_raw_f64(double 0x7FFC000000000001)
+  store double %r202, ptr %r201
+  br label %class_field_set.merge.16
+
+class_field_set.fallback.15:
+  call void @js_class_field_set_fallback(i64 8450987250308612146, i64 %r145, i64 %r149, double 0x7FFC000000000001)
+  br label %class_field_set.merge.16
+
+class_field_set.merge.16:
+  %r203 = load double, ptr %r7
+  %r204 = load double, ptr %r8
+  %r205 = bitcast double %r203 to i64
+  %r206 = and i64 %r205, 281474976710655
+  %r207 = load double, ptr @batch_ts_.str.7.handle
+  %r208 = bitcast double %r207 to i64
+  %r209 = and i64 %r208, 281474976710655
+  %r210 = load i64, ptr @perry_class_keys_batch_ts__Row
+  %r211 = bitcast double %r204 to i64
+  %r212 = load volatile i8, ptr @PERRY_CLASS_FIELD_INLINE_GUARD_DISABLED
+  %r213 = icmp eq i8 %r212, 0
+  %r214 = lshr i64 %r205, 48
+  %r215 = icmp eq i64 %r214, 32765
+  %r216 = icmp ugt i64 %r206, 1048575
+  %r217 = and i1 %r215, %r216
+  %r218 = and i1 %r217, %r213
+  br i1 %r218, label %class_field_inline.deref.22, label %class_field_inline.guardcall.23
+
+class_field_inline.deref.17:
+  %r159 = inttoptr i64 %r146 to ptr
+  %r160 = getelementptr i8, ptr %r159, i64 -8
+  %r161 = load i8, ptr %r160
+  %r162 = icmp eq i8 %r161, 2
+  %r163 = getelementptr i8, ptr %r159, i64 -7
+  %r164 = load i8, ptr %r163
+  %r165 = and i8 %r164, -128
+  %r166 = icmp eq i8 %r165, 0
+  %r167 = getelementptr i8, ptr %r159, i64 -6
+  %r168 = load i16, ptr %r167
+  %r169 = load i32, ptr %r159
+  %r170 = icmp eq i32 %r169, 1
+  %r171 = getelementptr i8, ptr %r159, i64 4
+  %r172 = load i32, ptr %r171
+  %r173 = icmp eq i32 %r172, 1
+  %r174 = getelementptr i8, ptr %r159, i64 12
+  %r175 = load i32, ptr %r174
+  %r176 = icmp ugt i32 %r175, 3
+  %r177 = getelementptr i8, ptr %r159, i64 16
+  %r178 = load i64, ptr %r177
+  %r179 = icmp eq i64 %r178, %r150
+  %r180 = and i1 %r162, %r166
+  %r181 = and i1 %r180, %r170
+  %r182 = and i1 %r181, %r173
+  %r183 = and i1 %r182, %r176
+  %r184 = and i1 %r183, %r179
+  %r185 = and i16 %r168, 2048
+  %r186 = icmp eq i16 %r185, 0
+  %r187 = and i1 %r184, %r186
+  %r188 = and i16 %r168, 4096
+  %r189 = icmp ne i16 %r188, 0
+  %r190 = and i1 %r187, %r189
+  %r191 = and i16 %r168, 1
+  %r192 = icmp eq i16 %r191, 0
+  %r193 = and i1 %r190, %r192
+  %r194 = and i64 %r151, 9218868437227405312
+  %r195 = icmp ne i64 %r194, 9218868437227405312
+  %r196 = and i1 %r193, %r195
+  br i1 %r196, label %class_field_set.fast.14, label %class_field_inline.guardcall.18
+
+class_field_inline.guardcall.18:
+  %r197 = call i32 @js_typed_feedback_class_field_set_guard(i64 8450987250308612146, double %r144, i32 1, i64 %r150, i64 %r149, i32 3, double 0x7FFC000000000001, i32 1)
+  %r198 = icmp ne i32 %r197, 0
+  br i1 %r198, label %class_field_set.fast.14, label %class_field_set.fallback.15
+
+class_field_set.fast.19:
+  %r259 = inttoptr i64 %r206 to ptr
+  %r260 = getelementptr i8, ptr %r259, i64 32
+  %r261 = getelementptr double, ptr %r260, i64 0
+  %r262 = call double @js_array_numeric_value_to_raw_f64(double %r204)
+  store double %r262, ptr %r261
+  br label %class_field_set.merge.21
+
+class_field_set.fallback.20:
+  call void @js_class_field_set_fallback(i64 8450987250308612147, i64 %r205, i64 %r209, double %r204)
+  br label %class_field_set.merge.21
+
+class_field_set.merge.21:
+  %r263 = load double, ptr %r7
+  %r264 = load double, ptr %r9
+  %r265 = bitcast double %r263 to i64
+  %r266 = and i64 %r265, 281474976710655
+  %r267 = load double, ptr @batch_ts_.str.5.handle
+  %r268 = bitcast double %r267 to i64
+  %r269 = and i64 %r268, 281474976710655
+  %r270 = load i64, ptr @perry_class_keys_batch_ts__Row
+  %r271 = bitcast double %r264 to i64
+  %r272 = call i32 @js_typed_feedback_class_field_set_guard(i64 8450987250308612148, double %r263, i32 1, i64 %r270, i64 %r269, i32 1, double %r264, i32 0)
+  %r273 = icmp ne i32 %r272, 0
+  br i1 %r273, label %class_field_set.fast.24, label %class_field_set.fallback.25
+
+class_field_inline.deref.22:
+  %r219 = inttoptr i64 %r206 to ptr
+  %r220 = getelementptr i8, ptr %r219, i64 -8
+  %r221 = load i8, ptr %r220
+  %r222 = icmp eq i8 %r221, 2
+  %r223 = getelementptr i8, ptr %r219, i64 -7
+  %r224 = load i8, ptr %r223
+  %r225 = and i8 %r224, -128
+  %r226 = icmp eq i8 %r225, 0
+  %r227 = getelementptr i8, ptr %r219, i64 -6
+  %r228 = load i16, ptr %r227
+  %r229 = load i32, ptr %r219
+  %r230 = icmp eq i32 %r229, 1
+  %r231 = getelementptr i8, ptr %r219, i64 4
+  %r232 = load i32, ptr %r231
+  %r233 = icmp eq i32 %r232, 1
+  %r234 = getelementptr i8, ptr %r219, i64 12
+  %r235 = load i32, ptr %r234
+  %r236 = icmp ugt i32 %r235, 0
+  %r237 = getelementptr i8, ptr %r219, i64 16
+  %r238 = load i64, ptr %r237
+  %r239 = icmp eq i64 %r238, %r210
+  %r240 = and i1 %r222, %r226
+  %r241 = and i1 %r240, %r230
+  %r242 = and i1 %r241, %r233
+  %r243 = and i1 %r242, %r236
+  %r244 = and i1 %r243, %r239
+  %r245 = and i16 %r228, 2048
+  %r246 = icmp eq i16 %r245, 0
+  %r247 = and i1 %r244, %r246
+  %r248 = and i16 %r228, 4096
+  %r249 = icmp ne i16 %r248, 0
+  %r250 = and i1 %r247, %r249
+  %r251 = and i16 %r228, 1
+  %r252 = icmp eq i16 %r251, 0
+  %r253 = and i1 %r250, %r252
+  %r254 = and i64 %r211, 9218868437227405312
+  %r255 = icmp ne i64 %r254, 9218868437227405312
+  %r256 = and i1 %r253, %r255
+  br i1 %r256, label %class_field_set.fast.19, label %class_field_inline.guardcall.23
+
+class_field_inline.guardcall.23:
+  %r257 = call i32 @js_typed_feedback_class_field_set_guard(i64 8450987250308612147, double %r203, i32 1, i64 %r210, i64 %r209, i32 0, double %r204, i32 1)
+  %r258 = icmp ne i32 %r257, 0
+  br i1 %r258, label %class_field_set.fast.19, label %class_field_set.fallback.20
+
+class_field_set.fast.24:
+  %r274 = inttoptr i64 %r266 to ptr
+  %r275 = getelementptr i8, ptr %r274, i64 32
+  %r276 = getelementptr double, ptr %r275, i64 1
+  %r277 = ptrtoint ptr %r276 to i64
+  store double %r264, ptr %r276
+  call void @js_string_addref_if_heap_string(double %r264)
+  %r278 = bitcast double %r264 to i64
+  call void @js_gc_note_slot_layout(i64 %r266, i32 1, i64 %r278)
+  call void @js_write_barrier_slot(i64 %r265, i64 %r277, i64 %r278)
+  br label %class_field_set.merge.26
+
+class_field_set.fallback.25:
+  call void @js_class_field_set_fallback(i64 8450987250308612148, i64 %r265, i64 %r269, double %r264)
+  br label %class_field_set.merge.26
+
+class_field_set.merge.26:
+  %r279 = load double, ptr %r7
+  %r280 = load double, ptr %r10
+  %r281 = bitcast double %r279 to i64
+  %r282 = and i64 %r281, 281474976710655
+  %r283 = load double, ptr @batch_ts_.str.2.handle
+  %r284 = bitcast double %r283 to i64
+  %r285 = and i64 %r284, 281474976710655
+  %r286 = load i64, ptr @perry_class_keys_batch_ts__Row
+  %r287 = bitcast double %r280 to i64
+  %r288 = load volatile i8, ptr @PERRY_CLASS_FIELD_INLINE_GUARD_DISABLED
+  %r289 = icmp eq i8 %r288, 0
+  %r290 = lshr i64 %r281, 48
+  %r291 = icmp eq i64 %r290, 32765
+  %r292 = icmp ugt i64 %r282, 1048575
+  %r293 = and i1 %r291, %r292
+  %r294 = and i1 %r293, %r289
+  br i1 %r294, label %class_field_inline.deref.30, label %class_field_inline.guardcall.31
+
+class_field_set.fast.27:
+  %r335 = inttoptr i64 %r282 to ptr
+  %r336 = getelementptr i8, ptr %r335, i64 32
+  %r337 = getelementptr double, ptr %r336, i64 2
+  %r338 = call double @js_array_numeric_value_to_raw_f64(double %r280)
+  store double %r338, ptr %r337
+  br label %class_field_set.merge.29
+
+class_field_set.fallback.28:
+  call void @js_class_field_set_fallback(i64 8450987250308612149, i64 %r281, i64 %r285, double %r280)
+  br label %class_field_set.merge.29
+
+class_field_set.merge.29:
+  %r339 = load double, ptr %r7
+  %r340 = bitcast double %r339 to i64
+  %r341 = and i64 %r340, 281474976710655
+  %r342 = load double, ptr @batch_ts_.str.4.handle
+  %r343 = bitcast double %r342 to i64
+  %r344 = and i64 %r343, 281474976710655
+  %r345 = load i64, ptr @perry_class_keys_batch_ts__Row
+  %r346 = bitcast double 0.0 to i64
+  %r347 = load volatile i8, ptr @PERRY_CLASS_FIELD_INLINE_GUARD_DISABLED
+  %r348 = icmp eq i8 %r347, 0
+  %r349 = lshr i64 %r340, 48
+  %r350 = icmp eq i64 %r349, 32765
+  %r351 = icmp ugt i64 %r341, 1048575
+  %r352 = and i1 %r350, %r351
+  %r353 = and i1 %r352, %r348
+  br i1 %r353, label %class_field_inline.deref.35, label %class_field_inline.guardcall.36
+
+class_field_inline.deref.30:
+  %r295 = inttoptr i64 %r282 to ptr
+  %r296 = getelementptr i8, ptr %r295, i64 -8
+  %r297 = load i8, ptr %r296
+  %r298 = icmp eq i8 %r297, 2
+  %r299 = getelementptr i8, ptr %r295, i64 -7
+  %r300 = load i8, ptr %r299
+  %r301 = and i8 %r300, -128
+  %r302 = icmp eq i8 %r301, 0
+  %r303 = getelementptr i8, ptr %r295, i64 -6
+  %r304 = load i16, ptr %r303
+  %r305 = load i32, ptr %r295
+  %r306 = icmp eq i32 %r305, 1
+  %r307 = getelementptr i8, ptr %r295, i64 4
+  %r308 = load i32, ptr %r307
+  %r309 = icmp eq i32 %r308, 1
+  %r310 = getelementptr i8, ptr %r295, i64 12
+  %r311 = load i32, ptr %r310
+  %r312 = icmp ugt i32 %r311, 2
+  %r313 = getelementptr i8, ptr %r295, i64 16
+  %r314 = load i64, ptr %r313
+  %r315 = icmp eq i64 %r314, %r286
+  %r316 = and i1 %r298, %r302
+  %r317 = and i1 %r316, %r306
+  %r318 = and i1 %r317, %r309
+  %r319 = and i1 %r318, %r312
+  %r320 = and i1 %r319, %r315
+  %r321 = and i16 %r304, 2048
+  %r322 = icmp eq i16 %r321, 0
+  %r323 = and i1 %r320, %r322
+  %r324 = and i16 %r304, 4096
+  %r325 = icmp ne i16 %r324, 0
+  %r326 = and i1 %r323, %r325
+  %r327 = and i16 %r304, 1
+  %r328 = icmp eq i16 %r327, 0
+  %r329 = and i1 %r326, %r328
+  %r330 = and i64 %r287, 9218868437227405312
+  %r331 = icmp ne i64 %r330, 9218868437227405312
+  %r332 = and i1 %r329, %r331
+  br i1 %r332, label %class_field_set.fast.27, label %class_field_inline.guardcall.31
+
+class_field_inline.guardcall.31:
+  %r333 = call i32 @js_typed_feedback_class_field_set_guard(i64 8450987250308612149, double %r279, i32 1, i64 %r286, i64 %r285, i32 2, double %r280, i32 1)
+  %r334 = icmp ne i32 %r333, 0
+  br i1 %r334, label %class_field_set.fast.27, label %class_field_set.fallback.28
+
+class_field_set.fast.32:
+  %r394 = inttoptr i64 %r341 to ptr
+  %r395 = getelementptr i8, ptr %r394, i64 32
+  %r396 = getelementptr double, ptr %r395, i64 3
+  %r397 = call double @js_array_numeric_value_to_raw_f64(double 0.0)
+  store double %r397, ptr %r396
+  br label %class_field_set.merge.34
+
+class_field_set.fallback.33:
+  call void @js_class_field_set_fallback(i64 8450987250308612150, i64 %r340, i64 %r344, double 0.0)
+  br label %class_field_set.merge.34
+
+class_field_set.merge.34:
+  %shadow_pop_l_0 = load i64, ptr %r1
+  call void @js_shadow_frame_pop(i64 %shadow_pop_l_0)
+  ret double 0x7FFC000000000001
+
+class_field_inline.deref.35:
+  %r354 = inttoptr i64 %r341 to ptr
+  %r355 = getelementptr i8, ptr %r354, i64 -8
+  %r356 = load i8, ptr %r355
+  %r357 = icmp eq i8 %r356, 2
+  %r358 = getelementptr i8, ptr %r354, i64 -7
+  %r359 = load i8, ptr %r358
+  %r360 = and i8 %r359, -128
+  %r361 = icmp eq i8 %r360, 0
+  %r362 = getelementptr i8, ptr %r354, i64 -6
+  %r363 = load i16, ptr %r362
+  %r364 = load i32, ptr %r354
+  %r365 = icmp eq i32 %r364, 1
+  %r366 = getelementptr i8, ptr %r354, i64 4
+  %r367 = load i32, ptr %r366
+  %r368 = icmp eq i32 %r367, 1
+  %r369 = getelementptr i8, ptr %r354, i64 12
+  %r370 = load i32, ptr %r369
+  %r371 = icmp ugt i32 %r370, 3
+  %r372 = getelementptr i8, ptr %r354, i64 16
+  %r373 = load i64, ptr %r372
+  %r374 = icmp eq i64 %r373, %r345
+  %r375 = and i1 %r357, %r361
+  %r376 = and i1 %r375, %r365
+  %r377 = and i1 %r376, %r368
+  %r378 = and i1 %r377, %r371
+  %r379 = and i1 %r378, %r374
+  %r380 = and i16 %r363, 2048
+  %r381 = icmp eq i16 %r380, 0
+  %r382 = and i1 %r379, %r381
+  %r383 = and i16 %r363, 4096
+  %r384 = icmp ne i16 %r383, 0
+  %r385 = and i1 %r382, %r384
+  %r386 = and i16 %r363, 1
+  %r387 = icmp eq i16 %r386, 0
+  %r388 = and i1 %r385, %r387
+  %r389 = and i64 %r346, 9218868437227405312
+  %r390 = icmp ne i64 %r389, 9218868437227405312
+  %r391 = and i1 %r388, %r390
+  br i1 %r391, label %class_field_set.fast.32, label %class_field_inline.guardcall.36
+
+class_field_inline.guardcall.36:
+  %r392 = call i32 @js_typed_feedback_class_field_set_guard(i64 8450987250308612150, double %r339, i32 1, i64 %r345, i64 %r344, i32 3, double 0.0, i32 1)
+  %r393 = icmp ne i32 %r392, 0
+  br i1 %r393, label %class_field_set.fast.32, label %class_field_set.fallback.33
+}
+
+define double @batch_ts____AnonShape_e75d7e32e87dc826_constructor(double %this_arg, double %arg20, double %arg21, double %arg22) {
+entry.0:
+  %r1 = alloca i64
+  %r2 = alloca ptr
+  store ptr null, ptr %r2
+  %r3 = call ptr @js_shadow_frame_enter(i32 4)
+  store ptr %r3, ptr %r2
+  %r4 = getelementptr inbounds i8, ptr %r3, i64 24
+  %r5 = load i64, ptr %r4
+  %r6 = sub i64 %r5, 1
+  store i64 %r6, ptr %r1
+  %r7 = alloca double
+  store double %this_arg, ptr %r7
+  call void @js_shadow_slot_bind(i32 3, ptr %r7)
+  %r8 = alloca double
+  store double %arg20, ptr %r8
+  call void @js_shadow_slot_bind(i32 0, ptr %r8)
+  %r9 = alloca double
+  store double %arg21, ptr %r9
+  call void @js_shadow_slot_bind(i32 1, ptr %r9)
+  %r10 = alloca double
+  store double %arg22, ptr %r10
+  call void @js_shadow_slot_bind(i32 2, ptr %r10)
+  %r11 = load double, ptr %r7
+  %r12 = bitcast double %r11 to i64
+  %r13 = and i64 %r12, 281474976710655
+  %r14 = load double, ptr @batch_ts_.str.12.handle
+  %r15 = bitcast double %r14 to i64
+  %r16 = and i64 %r15, 281474976710655
+  %r17 = load i64, ptr @perry_class_keys_batch_ts____AnonShape_e75d7e32e87dc826
+  %r18 = bitcast double 0x7FFC000000000001 to i64
+  %r19 = call i32 @js_typed_feedback_class_field_set_guard(i64 8450987250308612151, double %r11, i32 2, i64 %r17, i64 %r16, i32 0, double 0x7FFC000000000001, i32 0)
+  %r20 = icmp ne i32 %r19, 0
+  br i1 %r20, label %class_field_set.fast.1, label %class_field_set.fallback.2
+
+class_field_set.fast.1:
+  %r21 = inttoptr i64 %r13 to ptr
+  %r22 = getelementptr i8, ptr %r21, i64 32
+  %r23 = getelementptr double, ptr %r22, i64 0
+  %r24 = ptrtoint ptr %r23 to i64
+  store double 0x7FFC000000000001, ptr %r23
+  call void @js_string_addref_if_heap_string(double 0x7FFC000000000001)
+  %r25 = bitcast double 0x7FFC000000000001 to i64
+  call void @js_gc_note_slot_layout(i64 %r13, i32 0, i64 %r25)
+  br label %class_field_set.merge.3
+
+class_field_set.fallback.2:
+  call void @js_class_field_set_fallback(i64 8450987250308612151, i64 %r12, i64 %r16, double 0x7FFC000000000001)
+  br label %class_field_set.merge.3
+
+class_field_set.merge.3:
+  %r26 = load double, ptr %r7
+  %r27 = bitcast double %r26 to i64
+  %r28 = and i64 %r27, 281474976710655
+  %r29 = load double, ptr @batch_ts_.str.11.handle
+  %r30 = bitcast double %r29 to i64
+  %r31 = and i64 %r30, 281474976710655
+  %r32 = load i64, ptr @perry_class_keys_batch_ts____AnonShape_e75d7e32e87dc826
+  %r33 = bitcast double 0x7FFC000000000001 to i64
+  %r34 = call i32 @js_typed_feedback_class_field_set_guard(i64 8450987250308612152, double %r26, i32 2, i64 %r32, i64 %r31, i32 1, double 0x7FFC000000000001, i32 0)
+  %r35 = icmp ne i32 %r34, 0
+  br i1 %r35, label %class_field_set.fast.4, label %class_field_set.fallback.5
+
+class_field_set.fast.4:
+  %r36 = inttoptr i64 %r28 to ptr
+  %r37 = getelementptr i8, ptr %r36, i64 32
+  %r38 = getelementptr double, ptr %r37, i64 1
+  %r39 = ptrtoint ptr %r38 to i64
+  store double 0x7FFC000000000001, ptr %r38
+  call void @js_string_addref_if_heap_string(double 0x7FFC000000000001)
+  %r40 = bitcast double 0x7FFC000000000001 to i64
+  call void @js_gc_note_slot_layout(i64 %r28, i32 1, i64 %r40)
+  br label %class_field_set.merge.6
+
+class_field_set.fallback.5:
+  call void @js_class_field_set_fallback(i64 8450987250308612152, i64 %r27, i64 %r31, double 0x7FFC000000000001)
+  br label %class_field_set.merge.6
+
+class_field_set.merge.6:
+  %r41 = load double, ptr %r7
+  %r42 = bitcast double %r41 to i64
+  %r43 = and i64 %r42, 281474976710655
+  %r44 = load double, ptr @batch_ts_.str.14.handle
+  %r45 = bitcast double %r44 to i64
+  %r46 = and i64 %r45, 281474976710655
+  %r47 = load i64, ptr @perry_class_keys_batch_ts____AnonShape_e75d7e32e87dc826
+  %r48 = bitcast double 0x7FFC000000000001 to i64
+  %r49 = call i32 @js_typed_feedback_class_field_set_guard(i64 8450987250308612153, double %r41, i32 2, i64 %r47, i64 %r46, i32 2, double 0x7FFC000000000001, i32 0)
+  %r50 = icmp ne i32 %r49, 0
+  br i1 %r50, label %class_field_set.fast.7, label %class_field_set.fallback.8
+
+class_field_set.fast.7:
+  %r51 = inttoptr i64 %r43 to ptr
+  %r52 = getelementptr i8, ptr %r51, i64 32
+  %r53 = getelementptr double, ptr %r52, i64 2
+  %r54 = ptrtoint ptr %r53 to i64
+  store double 0x7FFC000000000001, ptr %r53
+  call void @js_string_addref_if_heap_string(double 0x7FFC000000000001)
+  %r55 = bitcast double 0x7FFC000000000001 to i64
+  call void @js_gc_note_slot_layout(i64 %r43, i32 2, i64 %r55)
+  br label %class_field_set.merge.9
+
+class_field_set.fallback.8:
+  call void @js_class_field_set_fallback(i64 8450987250308612153, i64 %r42, i64 %r46, double 0x7FFC000000000001)
+  br label %class_field_set.merge.9
+
+class_field_set.merge.9:
+  %r56 = load double, ptr %r7
+  %r57 = load double, ptr %r8
+  %r58 = bitcast double %r56 to i64
+  %r59 = and i64 %r58, 281474976710655
+  %r60 = load double, ptr @batch_ts_.str.12.handle
+  %r61 = bitcast double %r60 to i64
+  %r62 = and i64 %r61, 281474976710655
+  %r63 = load i64, ptr @perry_class_keys_batch_ts____AnonShape_e75d7e32e87dc826
+  %r64 = bitcast double %r57 to i64
+  %r65 = call i32 @js_typed_feedback_class_field_set_guard(i64 8450987250308612154, double %r56, i32 2, i64 %r63, i64 %r62, i32 0, double %r57, i32 0)
+  %r66 = icmp ne i32 %r65, 0
+  br i1 %r66, label %class_field_set.fast.10, label %class_field_set.fallback.11
+
+class_field_set.fast.10:
+  %r67 = inttoptr i64 %r59 to ptr
+  %r68 = getelementptr i8, ptr %r67, i64 32
+  %r69 = getelementptr double, ptr %r68, i64 0
+  %r70 = ptrtoint ptr %r69 to i64
+  store double %r57, ptr %r69
+  call void @js_string_addref_if_heap_string(double %r57)
+  %r71 = bitcast double %r57 to i64
+  call void @js_gc_note_slot_layout(i64 %r59, i32 0, i64 %r71)
+  call void @js_write_barrier_slot(i64 %r58, i64 %r70, i64 %r71)
+  br label %class_field_set.merge.12
+
+class_field_set.fallback.11:
+  call void @js_class_field_set_fallback(i64 8450987250308612154, i64 %r58, i64 %r62, double %r57)
+  br label %class_field_set.merge.12
+
+class_field_set.merge.12:
+  %r72 = load double, ptr %r7
+  %r73 = load double, ptr %r9
+  %r74 = bitcast double %r72 to i64
+  %r75 = and i64 %r74, 281474976710655
+  %r76 = load double, ptr @batch_ts_.str.11.handle
+  %r77 = bitcast double %r76 to i64
+  %r78 = and i64 %r77, 281474976710655
+  %r79 = load i64, ptr @perry_class_keys_batch_ts____AnonShape_e75d7e32e87dc826
+  %r80 = bitcast double %r73 to i64
+  %r81 = call i32 @js_typed_feedback_class_field_set_guard(i64 8450987250308612155, double %r72, i32 2, i64 %r79, i64 %r78, i32 1, double %r73, i32 0)
+  %r82 = icmp ne i32 %r81, 0
+  br i1 %r82, label %class_field_set.fast.13, label %class_field_set.fallback.14
+
+class_field_set.fast.13:
+  %r83 = inttoptr i64 %r75 to ptr
+  %r84 = getelementptr i8, ptr %r83, i64 32
+  %r85 = getelementptr double, ptr %r84, i64 1
+  %r86 = ptrtoint ptr %r85 to i64
+  store double %r73, ptr %r85
+  call void @js_string_addref_if_heap_string(double %r73)
+  %r87 = bitcast double %r73 to i64
+  call void @js_gc_note_slot_layout(i64 %r75, i32 1, i64 %r87)
+  call void @js_write_barrier_slot(i64 %r74, i64 %r86, i64 %r87)
+  br label %class_field_set.merge.15
+
+class_field_set.fallback.14:
+  call void @js_class_field_set_fallback(i64 8450987250308612155, i64 %r74, i64 %r78, double %r73)
+  br label %class_field_set.merge.15
+
+class_field_set.merge.15:
+  %r88 = load double, ptr %r7
+  %r89 = load double, ptr %r10
+  %r90 = bitcast double %r88 to i64
+  %r91 = and i64 %r90, 281474976710655
+  %r92 = load double, ptr @batch_ts_.str.14.handle
+  %r93 = bitcast double %r92 to i64
+  %r94 = and i64 %r93, 281474976710655
+  %r95 = load i64, ptr @perry_class_keys_batch_ts____AnonShape_e75d7e32e87dc826
+  %r96 = bitcast double %r89 to i64
+  %r97 = call i32 @js_typed_feedback_class_field_set_guard(i64 8450987250308612156, double %r88, i32 2, i64 %r95, i64 %r94, i32 2, double %r89, i32 0)
+  %r98 = icmp ne i32 %r97, 0
+  br i1 %r98, label %class_field_set.fast.16, label %class_field_set.fallback.17
+
+class_field_set.fast.16:
+  %r99 = inttoptr i64 %r91 to ptr
+  %r100 = getelementptr i8, ptr %r99, i64 32
+  %r101 = getelementptr double, ptr %r100, i64 2
+  %r102 = ptrtoint ptr %r101 to i64
+  store double %r89, ptr %r101
+  call void @js_string_addref_if_heap_string(double %r89)
+  %r103 = bitcast double %r89 to i64
+  call void @js_gc_note_slot_layout(i64 %r91, i32 2, i64 %r103)
+  call void @js_write_barrier_slot(i64 %r90, i64 %r102, i64 %r103)
+  br label %class_field_set.merge.18
+
+class_field_set.fallback.17:
+  call void @js_class_field_set_fallback(i64 8450987250308612156, i64 %r90, i64 %r94, double %r89)
+  br label %class_field_set.merge.18
+
+class_field_set.merge.18:
+  %shadow_pop_l_0 = load i64, ptr %r1
+  call void @js_shadow_frame_pop(i64 %shadow_pop_l_0)
+  ret double 0x7FFC000000000001
+}
+
+define double @batch_ts____AnonShape_c33c4204c28b9430_constructor(double %this_arg, double %arg30, double %arg31, double %arg32, double %arg33) {
+entry.0:
+  %r1 = alloca i64
+  %r2 = alloca ptr
+  store ptr null, ptr %r2
+  %r3 = call ptr @js_shadow_frame_enter(i32 2)
+  store ptr %r3, ptr %r2
+  %r4 = getelementptr inbounds i8, ptr %r3, i64 24
+  %r5 = load i64, ptr %r4
+  %r6 = sub i64 %r5, 1
+  store i64 %r6, ptr %r1
+  %r7 = alloca double
+  store double %this_arg, ptr %r7
+  call void @js_shadow_slot_bind(i32 1, ptr %r7)
+  %r8 = alloca double
+  store double %arg30, ptr %r8
+  call void @js_shadow_slot_bind(i32 0, ptr %r8)
+  %r9 = alloca double
+  store double %arg31, ptr %r9
+  %r10 = alloca double
+  store double %arg32, ptr %r10
+  %r11 = alloca double
+  store double %arg33, ptr %r11
+  %r12 = load double, ptr %r7
+  %r13 = bitcast double %r12 to i64
+  %r14 = and i64 %r13, 281474976710655
+  %r15 = load double, ptr @batch_ts_.str.5.handle
+  %r16 = bitcast double %r15 to i64
+  %r17 = and i64 %r16, 281474976710655
+  %r18 = load i64, ptr @perry_class_keys_batch_ts____AnonShape_c33c4204c28b9430
+  %r19 = bitcast double 0x7FFC000000000001 to i64
+  %r20 = call i32 @js_typed_feedback_class_field_set_guard(i64 8450987250308612157, double %r12, i32 3, i64 %r18, i64 %r17, i32 0, double 0x7FFC000000000001, i32 0)
+  %r21 = icmp ne i32 %r20, 0
+  br i1 %r21, label %class_field_set.fast.1, label %class_field_set.fallback.2
+
+class_field_set.fast.1:
+  %r22 = inttoptr i64 %r14 to ptr
+  %r23 = getelementptr i8, ptr %r22, i64 32
+  %r24 = getelementptr double, ptr %r23, i64 0
+  %r25 = ptrtoint ptr %r24 to i64
+  store double 0x7FFC000000000001, ptr %r24
+  call void @js_string_addref_if_heap_string(double 0x7FFC000000000001)
+  %r26 = bitcast double 0x7FFC000000000001 to i64
+  call void @js_gc_note_slot_layout(i64 %r14, i32 0, i64 %r26)
+  br label %class_field_set.merge.3
+
+class_field_set.fallback.2:
+  call void @js_class_field_set_fallback(i64 8450987250308612157, i64 %r13, i64 %r17, double 0x7FFC000000000001)
+  br label %class_field_set.merge.3
+
+class_field_set.merge.3:
+  %r27 = load double, ptr %r7
+  %r28 = bitcast double %r27 to i64
+  %r29 = and i64 %r28, 281474976710655
+  %r30 = load double, ptr @batch_ts_.str.13.handle
+  %r31 = bitcast double %r30 to i64
+  %r32 = and i64 %r31, 281474976710655
+  %r33 = load i64, ptr @perry_class_keys_batch_ts____AnonShape_c33c4204c28b9430
+  %r34 = bitcast double 0x7FFC000000000001 to i64
+  %r35 = load volatile i8, ptr @PERRY_CLASS_FIELD_INLINE_GUARD_DISABLED
+  %r36 = icmp eq i8 %r35, 0
+  %r37 = lshr i64 %r28, 48
+  %r38 = icmp eq i64 %r37, 32765
+  %r39 = icmp ugt i64 %r29, 1048575
+  %r40 = and i1 %r38, %r39
+  %r41 = and i1 %r40, %r36
+  br i1 %r41, label %class_field_inline.deref.7, label %class_field_inline.guardcall.8
+
+class_field_set.fast.4:
+  %r82 = inttoptr i64 %r29 to ptr
+  %r83 = getelementptr i8, ptr %r82, i64 32
+  %r84 = getelementptr double, ptr %r83, i64 1
+  %r85 = call double @js_array_numeric_value_to_raw_f64(double 0x7FFC000000000001)
+  store double %r85, ptr %r84
+  br label %class_field_set.merge.6
+
+class_field_set.fallback.5:
+  call void @js_class_field_set_fallback(i64 8450987250308612158, i64 %r28, i64 %r32, double 0x7FFC000000000001)
+  br label %class_field_set.merge.6
+
+class_field_set.merge.6:
+  %r86 = load double, ptr %r7
+  %r87 = bitcast double %r86 to i64
+  %r88 = and i64 %r87, 281474976710655
+  %r89 = load double, ptr @batch_ts_.str.1.handle
+  %r90 = bitcast double %r89 to i64
+  %r91 = and i64 %r90, 281474976710655
+  %r92 = load i64, ptr @perry_class_keys_batch_ts____AnonShape_c33c4204c28b9430
+  %r93 = bitcast double 0x7FFC000000000001 to i64
+  %r94 = load volatile i8, ptr @PERRY_CLASS_FIELD_INLINE_GUARD_DISABLED
+  %r95 = icmp eq i8 %r94, 0
+  %r96 = lshr i64 %r87, 48
+  %r97 = icmp eq i64 %r96, 32765
+  %r98 = icmp ugt i64 %r88, 1048575
+  %r99 = and i1 %r97, %r98
+  %r100 = and i1 %r99, %r95
+  br i1 %r100, label %class_field_inline.deref.12, label %class_field_inline.guardcall.13
+
+class_field_inline.deref.7:
+  %r42 = inttoptr i64 %r29 to ptr
+  %r43 = getelementptr i8, ptr %r42, i64 -8
+  %r44 = load i8, ptr %r43
+  %r45 = icmp eq i8 %r44, 2
+  %r46 = getelementptr i8, ptr %r42, i64 -7
+  %r47 = load i8, ptr %r46
+  %r48 = and i8 %r47, -128
+  %r49 = icmp eq i8 %r48, 0
+  %r50 = getelementptr i8, ptr %r42, i64 -6
+  %r51 = load i16, ptr %r50
+  %r52 = load i32, ptr %r42
+  %r53 = icmp eq i32 %r52, 1
+  %r54 = getelementptr i8, ptr %r42, i64 4
+  %r55 = load i32, ptr %r54
+  %r56 = icmp eq i32 %r55, 3
+  %r57 = getelementptr i8, ptr %r42, i64 12
+  %r58 = load i32, ptr %r57
+  %r59 = icmp ugt i32 %r58, 1
+  %r60 = getelementptr i8, ptr %r42, i64 16
+  %r61 = load i64, ptr %r60
+  %r62 = icmp eq i64 %r61, %r33
+  %r63 = and i1 %r45, %r49
+  %r64 = and i1 %r63, %r53
+  %r65 = and i1 %r64, %r56
+  %r66 = and i1 %r65, %r59
+  %r67 = and i1 %r66, %r62
+  %r68 = and i16 %r51, 2048
+  %r69 = icmp eq i16 %r68, 0
+  %r70 = and i1 %r67, %r69
+  %r71 = and i16 %r51, 4096
+  %r72 = icmp ne i16 %r71, 0
+  %r73 = and i1 %r70, %r72
+  %r74 = and i16 %r51, 1
+  %r75 = icmp eq i16 %r74, 0
+  %r76 = and i1 %r73, %r75
+  %r77 = and i64 %r34, 9218868437227405312
+  %r78 = icmp ne i64 %r77, 9218868437227405312
+  %r79 = and i1 %r76, %r78
+  br i1 %r79, label %class_field_set.fast.4, label %class_field_inline.guardcall.8
+
+class_field_inline.guardcall.8:
+  %r80 = call i32 @js_typed_feedback_class_field_set_guard(i64 8450987250308612158, double %r27, i32 3, i64 %r33, i64 %r32, i32 1, double 0x7FFC000000000001, i32 1)
+  %r81 = icmp ne i32 %r80, 0
+  br i1 %r81, label %class_field_set.fast.4, label %class_field_set.fallback.5
+
+class_field_set.fast.9:
+  %r141 = inttoptr i64 %r88 to ptr
+  %r142 = getelementptr i8, ptr %r141, i64 32
+  %r143 = getelementptr double, ptr %r142, i64 2
+  %r144 = call double @js_array_numeric_value_to_raw_f64(double 0x7FFC000000000001)
+  store double %r144, ptr %r143
+  br label %class_field_set.merge.11
+
+class_field_set.fallback.10:
+  call void @js_class_field_set_fallback(i64 8450987250308612159, i64 %r87, i64 %r91, double 0x7FFC000000000001)
+  br label %class_field_set.merge.11
+
+class_field_set.merge.11:
+  %r145 = load double, ptr %r7
+  %r146 = bitcast double %r145 to i64
+  %r147 = and i64 %r146, 281474976710655
+  %r148 = load double, ptr @batch_ts_.str.3.handle
+  %r149 = bitcast double %r148 to i64
+  %r150 = and i64 %r149, 281474976710655
+  %r151 = load i64, ptr @perry_class_keys_batch_ts____AnonShape_c33c4204c28b9430
+  %r152 = bitcast double 0x7FFC000000000001 to i64
+  %r153 = load volatile i8, ptr @PERRY_CLASS_FIELD_INLINE_GUARD_DISABLED
+  %r154 = icmp eq i8 %r153, 0
+  %r155 = lshr i64 %r146, 48
+  %r156 = icmp eq i64 %r155, 32765
+  %r157 = icmp ugt i64 %r147, 1048575
+  %r158 = and i1 %r156, %r157
+  %r159 = and i1 %r158, %r154
+  br i1 %r159, label %class_field_inline.deref.17, label %class_field_inline.guardcall.18
+
+class_field_inline.deref.12:
+  %r101 = inttoptr i64 %r88 to ptr
+  %r102 = getelementptr i8, ptr %r101, i64 -8
+  %r103 = load i8, ptr %r102
+  %r104 = icmp eq i8 %r103, 2
+  %r105 = getelementptr i8, ptr %r101, i64 -7
+  %r106 = load i8, ptr %r105
+  %r107 = and i8 %r106, -128
+  %r108 = icmp eq i8 %r107, 0
+  %r109 = getelementptr i8, ptr %r101, i64 -6
+  %r110 = load i16, ptr %r109
+  %r111 = load i32, ptr %r101
+  %r112 = icmp eq i32 %r111, 1
+  %r113 = getelementptr i8, ptr %r101, i64 4
+  %r114 = load i32, ptr %r113
+  %r115 = icmp eq i32 %r114, 3
+  %r116 = getelementptr i8, ptr %r101, i64 12
+  %r117 = load i32, ptr %r116
+  %r118 = icmp ugt i32 %r117, 2
+  %r119 = getelementptr i8, ptr %r101, i64 16
+  %r120 = load i64, ptr %r119
+  %r121 = icmp eq i64 %r120, %r92
+  %r122 = and i1 %r104, %r108
+  %r123 = and i1 %r122, %r112
+  %r124 = and i1 %r123, %r115
+  %r125 = and i1 %r124, %r118
+  %r126 = and i1 %r125, %r121
+  %r127 = and i16 %r110, 2048
+  %r128 = icmp eq i16 %r127, 0
+  %r129 = and i1 %r126, %r128
+  %r130 = and i16 %r110, 4096
+  %r131 = icmp ne i16 %r130, 0
+  %r132 = and i1 %r129, %r131
+  %r133 = and i16 %r110, 1
+  %r134 = icmp eq i16 %r133, 0
+  %r135 = and i1 %r132, %r134
+  %r136 = and i64 %r93, 9218868437227405312
+  %r137 = icmp ne i64 %r136, 9218868437227405312
+  %r138 = and i1 %r135, %r137
+  br i1 %r138, label %class_field_set.fast.9, label %class_field_inline.guardcall.13
+
+class_field_inline.guardcall.13:
+  %r139 = call i32 @js_typed_feedback_class_field_set_guard(i64 8450987250308612159, double %r86, i32 3, i64 %r92, i64 %r91, i32 2, double 0x7FFC000000000001, i32 1)
+  %r140 = icmp ne i32 %r139, 0
+  br i1 %r140, label %class_field_set.fast.9, label %class_field_set.fallback.10
+
+class_field_set.fast.14:
+  %r200 = inttoptr i64 %r147 to ptr
+  %r201 = getelementptr i8, ptr %r200, i64 32
+  %r202 = getelementptr double, ptr %r201, i64 3
+  %r203 = call double @js_array_numeric_value_to_raw_f64(double 0x7FFC000000000001)
+  store double %r203, ptr %r202
+  br label %class_field_set.merge.16
+
+class_field_set.fallback.15:
+  call void @js_class_field_set_fallback(i64 8450987250308612160, i64 %r146, i64 %r150, double 0x7FFC000000000001)
+  br label %class_field_set.merge.16
+
+class_field_set.merge.16:
+  %r204 = load double, ptr %r7
+  %r205 = load double, ptr %r8
+  %r206 = bitcast double %r204 to i64
+  %r207 = and i64 %r206, 281474976710655
+  %r208 = load double, ptr @batch_ts_.str.5.handle
+  %r209 = bitcast double %r208 to i64
+  %r210 = and i64 %r209, 281474976710655
+  %r211 = load i64, ptr @perry_class_keys_batch_ts____AnonShape_c33c4204c28b9430
+  %r212 = bitcast double %r205 to i64
+  %r213 = call i32 @js_typed_feedback_class_field_set_guard(i64 8450987250308612161, double %r204, i32 3, i64 %r211, i64 %r210, i32 0, double %r205, i32 0)
+  %r214 = icmp ne i32 %r213, 0
+  br i1 %r214, label %class_field_set.fast.19, label %class_field_set.fallback.20
+
+class_field_inline.deref.17:
+  %r160 = inttoptr i64 %r147 to ptr
+  %r161 = getelementptr i8, ptr %r160, i64 -8
+  %r162 = load i8, ptr %r161
+  %r163 = icmp eq i8 %r162, 2
+  %r164 = getelementptr i8, ptr %r160, i64 -7
+  %r165 = load i8, ptr %r164
+  %r166 = and i8 %r165, -128
+  %r167 = icmp eq i8 %r166, 0
+  %r168 = getelementptr i8, ptr %r160, i64 -6
+  %r169 = load i16, ptr %r168
+  %r170 = load i32, ptr %r160
+  %r171 = icmp eq i32 %r170, 1
+  %r172 = getelementptr i8, ptr %r160, i64 4
+  %r173 = load i32, ptr %r172
+  %r174 = icmp eq i32 %r173, 3
+  %r175 = getelementptr i8, ptr %r160, i64 12
+  %r176 = load i32, ptr %r175
+  %r177 = icmp ugt i32 %r176, 3
+  %r178 = getelementptr i8, ptr %r160, i64 16
+  %r179 = load i64, ptr %r178
+  %r180 = icmp eq i64 %r179, %r151
+  %r181 = and i1 %r163, %r167
+  %r182 = and i1 %r181, %r171
+  %r183 = and i1 %r182, %r174
+  %r184 = and i1 %r183, %r177
+  %r185 = and i1 %r184, %r180
+  %r186 = and i16 %r169, 2048
+  %r187 = icmp eq i16 %r186, 0
+  %r188 = and i1 %r185, %r187
+  %r189 = and i16 %r169, 4096
+  %r190 = icmp ne i16 %r189, 0
+  %r191 = and i1 %r188, %r190
+  %r192 = and i16 %r169, 1
+  %r193 = icmp eq i16 %r192, 0
+  %r194 = and i1 %r191, %r193
+  %r195 = and i64 %r152, 9218868437227405312
+  %r196 = icmp ne i64 %r195, 9218868437227405312
+  %r197 = and i1 %r194, %r196
+  br i1 %r197, label %class_field_set.fast.14, label %class_field_inline.guardcall.18
+
+class_field_inline.guardcall.18:
+  %r198 = call i32 @js_typed_feedback_class_field_set_guard(i64 8450987250308612160, double %r145, i32 3, i64 %r151, i64 %r150, i32 3, double 0x7FFC000000000001, i32 1)
+  %r199 = icmp ne i32 %r198, 0
+  br i1 %r199, label %class_field_set.fast.14, label %class_field_set.fallback.15
+
+class_field_set.fast.19:
+  %r215 = inttoptr i64 %r207 to ptr
+  %r216 = getelementptr i8, ptr %r215, i64 32
+  %r217 = getelementptr double, ptr %r216, i64 0
+  %r218 = ptrtoint ptr %r217 to i64
+  store double %r205, ptr %r217
+  call void @js_string_addref_if_heap_string(double %r205)
+  %r219 = bitcast double %r205 to i64
+  call void @js_gc_note_slot_layout(i64 %r207, i32 0, i64 %r219)
+  call void @js_write_barrier_slot(i64 %r206, i64 %r218, i64 %r219)
+  br label %class_field_set.merge.21
+
+class_field_set.fallback.20:
+  call void @js_class_field_set_fallback(i64 8450987250308612161, i64 %r206, i64 %r210, double %r205)
+  br label %class_field_set.merge.21
+
+class_field_set.merge.21:
+  %r220 = load double, ptr %r7
+  %r221 = load double, ptr %r9
+  %r222 = bitcast double %r220 to i64
+  %r223 = and i64 %r222, 281474976710655
+  %r224 = load double, ptr @batch_ts_.str.13.handle
+  %r225 = bitcast double %r224 to i64
+  %r226 = and i64 %r225, 281474976710655
+  %r227 = load i64, ptr @perry_class_keys_batch_ts____AnonShape_c33c4204c28b9430
+  %r228 = bitcast double %r221 to i64
+  %r229 = load volatile i8, ptr @PERRY_CLASS_FIELD_INLINE_GUARD_DISABLED
+  %r230 = icmp eq i8 %r229, 0
+  %r231 = lshr i64 %r222, 48
+  %r232 = icmp eq i64 %r231, 32765
+  %r233 = icmp ugt i64 %r223, 1048575
+  %r234 = and i1 %r232, %r233
+  %r235 = and i1 %r234, %r230
+  br i1 %r235, label %class_field_inline.deref.25, label %class_field_inline.guardcall.26
+
+class_field_set.fast.22:
+  %r276 = inttoptr i64 %r223 to ptr
+  %r277 = getelementptr i8, ptr %r276, i64 32
+  %r278 = getelementptr double, ptr %r277, i64 1
+  %r279 = call double @js_array_numeric_value_to_raw_f64(double %r221)
+  store double %r279, ptr %r278
+  br label %class_field_set.merge.24
+
+class_field_set.fallback.23:
+  call void @js_class_field_set_fallback(i64 8450987250308612162, i64 %r222, i64 %r226, double %r221)
+  br label %class_field_set.merge.24
+
+class_field_set.merge.24:
+  %r280 = load double, ptr %r7
+  %r281 = load double, ptr %r10
+  %r282 = bitcast double %r280 to i64
+  %r283 = and i64 %r282, 281474976710655
+  %r284 = load double, ptr @batch_ts_.str.1.handle
+  %r285 = bitcast double %r284 to i64
+  %r286 = and i64 %r285, 281474976710655
+  %r287 = load i64, ptr @perry_class_keys_batch_ts____AnonShape_c33c4204c28b9430
+  %r288 = bitcast double %r281 to i64
+  %r289 = load volatile i8, ptr @PERRY_CLASS_FIELD_INLINE_GUARD_DISABLED
+  %r290 = icmp eq i8 %r289, 0
+  %r291 = lshr i64 %r282, 48
+  %r292 = icmp eq i64 %r291, 32765
+  %r293 = icmp ugt i64 %r283, 1048575
+  %r294 = and i1 %r292, %r293
+  %r295 = and i1 %r294, %r290
+  br i1 %r295, label %class_field_inline.deref.30, label %class_field_inline.guardcall.31
+
+class_field_inline.deref.25:
+  %r236 = inttoptr i64 %r223 to ptr
+  %r237 = getelementptr i8, ptr %r236, i64 -8
+  %r238 = load i8, ptr %r237
+  %r239 = icmp eq i8 %r238, 2
+  %r240 = getelementptr i8, ptr %r236, i64 -7
+  %r241 = load i8, ptr %r240
+  %r242 = and i8 %r241, -128
+  %r243 = icmp eq i8 %r242, 0
+  %r244 = getelementptr i8, ptr %r236, i64 -6
+  %r245 = load i16, ptr %r244
+  %r246 = load i32, ptr %r236
+  %r247 = icmp eq i32 %r246, 1
+  %r248 = getelementptr i8, ptr %r236, i64 4
+  %r249 = load i32, ptr %r248
+  %r250 = icmp eq i32 %r249, 3
+  %r251 = getelementptr i8, ptr %r236, i64 12
+  %r252 = load i32, ptr %r251
+  %r253 = icmp ugt i32 %r252, 1
+  %r254 = getelementptr i8, ptr %r236, i64 16
+  %r255 = load i64, ptr %r254
+  %r256 = icmp eq i64 %r255, %r227
+  %r257 = and i1 %r239, %r243
+  %r258 = and i1 %r257, %r247
+  %r259 = and i1 %r258, %r250
+  %r260 = and i1 %r259, %r253
+  %r261 = and i1 %r260, %r256
+  %r262 = and i16 %r245, 2048
+  %r263 = icmp eq i16 %r262, 0
+  %r264 = and i1 %r261, %r263
+  %r265 = and i16 %r245, 4096
+  %r266 = icmp ne i16 %r265, 0
+  %r267 = and i1 %r264, %r266
+  %r268 = and i16 %r245, 1
+  %r269 = icmp eq i16 %r268, 0
+  %r270 = and i1 %r267, %r269
+  %r271 = and i64 %r228, 9218868437227405312
+  %r272 = icmp ne i64 %r271, 9218868437227405312
+  %r273 = and i1 %r270, %r272
+  br i1 %r273, label %class_field_set.fast.22, label %class_field_inline.guardcall.26
+
+class_field_inline.guardcall.26:
+  %r274 = call i32 @js_typed_feedback_class_field_set_guard(i64 8450987250308612162, double %r220, i32 3, i64 %r227, i64 %r226, i32 1, double %r221, i32 1)
+  %r275 = icmp ne i32 %r274, 0
+  br i1 %r275, label %class_field_set.fast.22, label %class_field_set.fallback.23
+
+class_field_set.fast.27:
+  %r336 = inttoptr i64 %r283 to ptr
+  %r337 = getelementptr i8, ptr %r336, i64 32
+  %r338 = getelementptr double, ptr %r337, i64 2
+  %r339 = call double @js_array_numeric_value_to_raw_f64(double %r281)
+  store double %r339, ptr %r338
+  br label %class_field_set.merge.29
+
+class_field_set.fallback.28:
+  call void @js_class_field_set_fallback(i64 8450987250308612163, i64 %r282, i64 %r286, double %r281)
+  br label %class_field_set.merge.29
+
+class_field_set.merge.29:
+  %r340 = load double, ptr %r7
+  %r341 = load double, ptr %r11
+  %r342 = bitcast double %r340 to i64
+  %r343 = and i64 %r342, 281474976710655
+  %r344 = load double, ptr @batch_ts_.str.3.handle
+  %r345 = bitcast double %r344 to i64
+  %r346 = and i64 %r345, 281474976710655
+  %r347 = load i64, ptr @perry_class_keys_batch_ts____AnonShape_c33c4204c28b9430
+  %r348 = bitcast double %r341 to i64
+  %r349 = load volatile i8, ptr @PERRY_CLASS_FIELD_INLINE_GUARD_DISABLED
+  %r350 = icmp eq i8 %r349, 0
+  %r351 = lshr i64 %r342, 48
+  %r352 = icmp eq i64 %r351, 32765
+  %r353 = icmp ugt i64 %r343, 1048575
+  %r354 = and i1 %r352, %r353
+  %r355 = and i1 %r354, %r350
+  br i1 %r355, label %class_field_inline.deref.35, label %class_field_inline.guardcall.36
+
+class_field_inline.deref.30:
+  %r296 = inttoptr i64 %r283 to ptr
+  %r297 = getelementptr i8, ptr %r296, i64 -8
+  %r298 = load i8, ptr %r297
+  %r299 = icmp eq i8 %r298, 2
+  %r300 = getelementptr i8, ptr %r296, i64 -7
+  %r301 = load i8, ptr %r300
+  %r302 = and i8 %r301, -128
+  %r303 = icmp eq i8 %r302, 0
+  %r304 = getelementptr i8, ptr %r296, i64 -6
+  %r305 = load i16, ptr %r304
+  %r306 = load i32, ptr %r296
+  %r307 = icmp eq i32 %r306, 1
+  %r308 = getelementptr i8, ptr %r296, i64 4
+  %r309 = load i32, ptr %r308
+  %r310 = icmp eq i32 %r309, 3
+  %r311 = getelementptr i8, ptr %r296, i64 12
+  %r312 = load i32, ptr %r311
+  %r313 = icmp ugt i32 %r312, 2
+  %r314 = getelementptr i8, ptr %r296, i64 16
+  %r315 = load i64, ptr %r314
+  %r316 = icmp eq i64 %r315, %r287
+  %r317 = and i1 %r299, %r303
+  %r318 = and i1 %r317, %r307
+  %r319 = and i1 %r318, %r310
+  %r320 = and i1 %r319, %r313
+  %r321 = and i1 %r320, %r316
+  %r322 = and i16 %r305, 2048
+  %r323 = icmp eq i16 %r322, 0
+  %r324 = and i1 %r321, %r323
+  %r325 = and i16 %r305, 4096
+  %r326 = icmp ne i16 %r325, 0
+  %r327 = and i1 %r324, %r326
+  %r328 = and i16 %r305, 1
+  %r329 = icmp eq i16 %r328, 0
+  %r330 = and i1 %r327, %r329
+  %r331 = and i64 %r288, 9218868437227405312
+  %r332 = icmp ne i64 %r331, 9218868437227405312
+  %r333 = and i1 %r330, %r332
+  br i1 %r333, label %class_field_set.fast.27, label %class_field_inline.guardcall.31
+
+class_field_inline.guardcall.31:
+  %r334 = call i32 @js_typed_feedback_class_field_set_guard(i64 8450987250308612163, double %r280, i32 3, i64 %r287, i64 %r286, i32 2, double %r281, i32 1)
+  %r335 = icmp ne i32 %r334, 0
+  br i1 %r335, label %class_field_set.fast.27, label %class_field_set.fallback.28
+
+class_field_set.fast.32:
+  %r396 = inttoptr i64 %r343 to ptr
+  %r397 = getelementptr i8, ptr %r396, i64 32
+  %r398 = getelementptr double, ptr %r397, i64 3
+  %r399 = call double @js_array_numeric_value_to_raw_f64(double %r341)
+  store double %r399, ptr %r398
+  br label %class_field_set.merge.34
+
+class_field_set.fallback.33:
+  call void @js_class_field_set_fallback(i64 8450987250308612164, i64 %r342, i64 %r346, double %r341)
+  br label %class_field_set.merge.34
+
+class_field_set.merge.34:
+  %shadow_pop_l_0 = load i64, ptr %r1
+  call void @js_shadow_frame_pop(i64 %shadow_pop_l_0)
+  ret double 0x7FFC000000000001
+
+class_field_inline.deref.35:
+  %r356 = inttoptr i64 %r343 to ptr
+  %r357 = getelementptr i8, ptr %r356, i64 -8
+  %r358 = load i8, ptr %r357
+  %r359 = icmp eq i8 %r358, 2
+  %r360 = getelementptr i8, ptr %r356, i64 -7
+  %r361 = load i8, ptr %r360
+  %r362 = and i8 %r361, -128
+  %r363 = icmp eq i8 %r362, 0
+  %r364 = getelementptr i8, ptr %r356, i64 -6
+  %r365 = load i16, ptr %r364
+  %r366 = load i32, ptr %r356
+  %r367 = icmp eq i32 %r366, 1
+  %r368 = getelementptr i8, ptr %r356, i64 4
+  %r369 = load i32, ptr %r368
+  %r370 = icmp eq i32 %r369, 3
+  %r371 = getelementptr i8, ptr %r356, i64 12
+  %r372 = load i32, ptr %r371
+  %r373 = icmp ugt i32 %r372, 3
+  %r374 = getelementptr i8, ptr %r356, i64 16
+  %r375 = load i64, ptr %r374
+  %r376 = icmp eq i64 %r375, %r347
+  %r377 = and i1 %r359, %r363
+  %r378 = and i1 %r377, %r367
+  %r379 = and i1 %r378, %r370
+  %r380 = and i1 %r379, %r373
+  %r381 = and i1 %r380, %r376
+  %r382 = and i16 %r365, 2048
+  %r383 = icmp eq i16 %r382, 0
+  %r384 = and i1 %r381, %r383
+  %r385 = and i16 %r365, 4096
+  %r386 = icmp ne i16 %r385, 0
+  %r387 = and i1 %r384, %r386
+  %r388 = and i16 %r365, 1
+  %r389 = icmp eq i16 %r388, 0
+  %r390 = and i1 %r387, %r389
+  %r391 = and i64 %r348, 9218868437227405312
+  %r392 = icmp ne i64 %r391, 9218868437227405312
+  %r393 = and i1 %r390, %r392
+  br i1 %r393, label %class_field_set.fast.32, label %class_field_inline.guardcall.36
+
+class_field_inline.guardcall.36:
+  %r394 = call i32 @js_typed_feedback_class_field_set_guard(i64 8450987250308612164, double %r340, i32 3, i64 %r347, i64 %r346, i32 3, double %r341, i32 1)
+  %r395 = icmp ne i32 %r394, 0
+  br i1 %r395, label %class_field_set.fast.32, label %class_field_set.fallback.33
+}
+
+define double @__perry_wrap_perry_fn_batch_ts__buildRows(i64 %this_closure, double %a0, double %a1) {
+entry.0:
+  %r1 = call double @perry_fn_batch_ts__buildRows(double %a0, double %a1)
+  ret double %r1
+}
+
+define double @__perry_wrap_perry_fn_batch_ts__shape(i64 %this_closure, double %a0) {
+entry.0:
+  %r1 = call double @perry_fn_batch_ts__shape(double %a0)
+  ret double %r1
+}
+
+define double @__perry_wrap_perry_fn_batch_ts__ranked(i64 %this_closure, double %a0) {
+entry.0:
+  %r1 = call double @perry_fn_batch_ts__ranked(double %a0)
+  ret double %r1
+}
+
+define double @__perry_wrap_perry_fn_batch_ts__summarize(i64 %this_closure, double %a0) {
+entry.0:
+  %r1 = call double @perry_fn_batch_ts__summarize(double %a0)
+  ret double %r1
+}
+
+define double @__perry_wrap_perry_fn_batch_ts__totalsRow(i64 %this_closure, double %a0) {
+entry.0:
+  %r1 = call double @perry_fn_batch_ts__totalsRow(double %a0)
+  ret double %r1
+}
+
+define double @__perry_wrap_perry_method_batch_ts__Row__rescore(i64 %this_closure, double %a0) {
+entry.0:
+  %r1 = call double @js_implicit_this_get()
+  %r2 = call double @perry_method_batch_ts__Row__rescore(double %r1, double %a0)
+  ret double %r2
+}
+
+define internal double @__perry_wrap_perry_unknown_func(i64 %this_closure, double %a0, double %a1, double %a2, double %a3, double %a4) {
+entry.0:
+  ret double 0x7FFC000000000001
+}
+
+define void @batch_ts__init() {
+entry.0:
+  ret void
+}
+
+define i32 @main() {
+entry.0:
+  %r1 = alloca i64
+  %r2 = alloca ptr
+  store ptr null, ptr %r2
+  %r8 = alloca i32
+  store i32 0, ptr %r8
+  %r13 = alloca ptr
+  %r14 = call ptr @js_inline_arena_state()
+  store ptr %r14, ptr %r13
+  %r54 = alloca double
+  store double 0x7FFC000000000001, ptr %r54
+  %r83 = alloca double
+  store double 0x7FFC000000000001, ptr %r83
+  %r115 = alloca double
+  store double 0x7FFC000000000001, ptr %r115
+  %r168 = alloca double
+  store double 0x7FFC000000000001, ptr %r168
+  %r206 = alloca double
+  store double 0x7FFC000000000001, ptr %r206
+  %r245 = alloca double
+  store double 0x7FFC000000000001, ptr %r245
+  %r246 = alloca i32
+  store i32 0, ptr %r246
+  %r408 = alloca i32
+  store i32 0, ptr %r408
+  %r721 = alloca double
+  store double 0x7FFC000000000001, ptr %r721
+  call void @js_gc_init()
+  call void @js_gc_write_barriers_emitted(i32 1)
+  call void @perry_macos_bundle_chdir()
+  call void @__perry_init_strings_batch_ts()
+  %r3 = call ptr @js_shadow_frame_enter(i32 7)
+  store ptr %r3, ptr %r2
+  %r4 = getelementptr inbounds i8, ptr %r3, i64 24
+  %r5 = load i64, ptr %r4
+  %r6 = sub i64 %r5, 1
+  store i64 %r6, ptr %r1
+  %r7 = ptrtoint ptr @perry_global_batch_ts__1 to i64
+  call void @js_gc_register_global_root(i64 %r7)
+  store i32 40000, ptr %r8
+  %r9 = load double, ptr @batch_ts_.str.15.handle
+  %r10 = load double, ptr @batch_ts_.str.16.handle
+  %r11 = load double, ptr @batch_ts_.str.17.handle
+  %r12 = load double, ptr @batch_ts_.str.18.handle
+  %r15 = load ptr, ptr %r13
+  %r16 = getelementptr i8, ptr %r15, i64 8
+  %r17 = load i64, ptr %r16
+  %r18 = add i64 %r17, 48
+  %r19 = getelementptr i8, ptr %r15, i64 16
+  %r20 = load i64, ptr %r19
+  %r21 = icmp ule i64 %r18, %r20
+  br i1 %r21, label %arrlit.fast.1, label %arrlit.slow.2
+
+arrlit.fast.1:
+  store i64 %r18, ptr %r16
+  %r22 = load ptr, ptr %r15
+  %r23 = getelementptr i8, ptr %r22, i64 %r17
+  br label %arrlit.merge.3
+
+arrlit.slow.2:
+  %r24 = call ptr @js_inline_arena_slow_alloc(ptr %r15, i64 48, i64 8)
+  br label %arrlit.merge.3
+
+arrlit.merge.3:
+  %r25 = phi ptr [ %r23, %arrlit.fast.1 ], [ %r24, %arrlit.slow.2 ]
+  store i64 207232172545, ptr %r25
+  %r26 = getelementptr i8, ptr %r25, i64 8
+  store i64 17179869188, ptr %r26
+  %r27 = getelementptr i8, ptr %r25, i64 8
+  %r28 = ptrtoint ptr %r27 to i64
+  %r29 = getelementptr inbounds i8, ptr %r25, i64 16
+  store double %r9, ptr %r29
+  call void @js_string_addref_if_heap_string(double %r9)
+  %r30 = bitcast double %r9 to i64
+  call void @js_gc_note_slot_layout(i64 %r28, i32 0, i64 %r30)
+  %r31 = getelementptr inbounds i8, ptr %r25, i64 24
+  store double %r10, ptr %r31
+  call void @js_string_addref_if_heap_string(double %r10)
+  %r32 = bitcast double %r10 to i64
+  call void @js_gc_note_slot_layout(i64 %r28, i32 1, i64 %r32)
+  %r33 = getelementptr inbounds i8, ptr %r25, i64 32
+  store double %r11, ptr %r33
+  call void @js_string_addref_if_heap_string(double %r11)
+  %r34 = bitcast double %r11 to i64
+  call void @js_gc_note_slot_layout(i64 %r28, i32 2, i64 %r34)
+  %r35 = getelementptr inbounds i8, ptr %r25, i64 40
+  store double %r12, ptr %r35
+  call void @js_string_addref_if_heap_string(double %r12)
+  %r36 = bitcast double %r12 to i64
+  call void @js_gc_note_slot_layout(i64 %r28, i32 3, i64 %r36)
+  %r37 = or i64 %r28, 9222527611924643840
+  %r38 = bitcast i64 %r37 to double
+  store double %r38, ptr @perry_global_batch_ts__1
+  call void @js_write_barrier_root_nanbox(i64 %r37)
+  %r39 = load ptr, ptr %r2
+  %r40 = icmp eq ptr %r39, null
+  br i1 %r40, label %ss.slow.4, label %ss.chk_top.5
+
+ss.slow.4:
+  call void @js_shadow_slot_set(i32 0, i64 0)
+  br label %ss.done.8
+
+ss.chk_top.5:
+  %r41 = getelementptr inbounds i8, ptr %r39, i64 24
+  %r42 = load i64, ptr %r41
+  %r43 = icmp eq i64 %r42, -1
+  br i1 %r43, label %ss.done.8, label %ss.chk_len.6
+
+ss.chk_len.6:
+  %r44 = add i64 %r42, 0
+  %r45 = getelementptr inbounds i8, ptr %r39, i64 8
+  %r46 = load i64, ptr %r45
+  %r47 = icmp ult i64 %r44, %r46
+  br i1 %r47, label %ss.store.7, label %ss.done.8
+
+ss.store.7:
+  %r48 = load ptr, ptr %r39
+  %r49 = shl i64 %r44, 4
+  %r50 = getelementptr inbounds i8, ptr %r48, i64 %r49
+  %r51 = getelementptr inbounds i8, ptr %r50, i64 8
+  %r52 = load i64, ptr %r51
+  %r53 = and i64 %r52, -2
+  store i64 0, ptr %r50
+  store i64 %r53, ptr %r51
+  br label %ss.done.8
+
+ss.done.8:
+  %r55 = call i64 @js_array_alloc(i32 0)
+  %r56 = or i64 %r55, 9222527611924643840
+  %r57 = bitcast i64 %r56 to double
+  store double %r57, ptr %r54
+  %r58 = load ptr, ptr %r2
+  %r59 = icmp eq ptr %r58, null
+  br i1 %r59, label %ss.slow.9, label %ss.chk_top.10
+
+ss.slow.9:
+  call void @js_shadow_slot_bind(i32 1, ptr %r54)
+  br label %ss.done.13
+
+ss.chk_top.10:
+  %r60 = getelementptr inbounds i8, ptr %r58, i64 24
+  %r61 = load i64, ptr %r60
+  %r62 = icmp eq i64 %r61, -1
+  br i1 %r62, label %ss.done.13, label %ss.chk_len.11
+
+ss.chk_len.11:
+  %r63 = add i64 %r61, 1
+  %r64 = getelementptr inbounds i8, ptr %r58, i64 8
+  %r65 = load i64, ptr %r64
+  %r66 = icmp ult i64 %r63, %r65
+  br i1 %r66, label %ss.store.12, label %ss.done.13
+
+ss.store.12:
+  %r67 = load ptr, ptr %r58
+  %r68 = shl i64 %r63, 4
+  %r69 = getelementptr inbounds i8, ptr %r67, i64 %r68
+  %r70 = getelementptr inbounds i8, ptr %r69, i64 8
+  %r71 = load i64, ptr %r54
+  %r72 = ptrtoint ptr %r54 to i64
+  %r73 = and i64 %r72, 1
+  %r74 = icmp eq i64 %r73, 0
+  %r75 = select i1 %r74, i64 %r72, i64 0
+  %r76 = or i64 %r75, 1
+  store i64 %r71, ptr %r69
+  store i64 %r76, ptr %r70
+  %r77 = load atomic i32, ptr @PERRY_INCREMENTAL_MARK_BARRIER_ACTIVE_COUNT seq_cst, align 4
+  %r78 = icmp ne i32 %r77, 0
+  br i1 %r78, label %ss.barrier.14, label %ss.done.13
+
+ss.done.13:
+  %r79 = load i32, ptr %r8
+  %r80 = sitofp i32 %r79 to double
+  %r81 = load double, ptr %r54
+  %r82 = call double @perry_fn_batch_ts__buildRows(double %r80, double %r81)
+  %r84 = load double, ptr %r54
+  %r85 = call i64 @js_closure_alloc_singleton(ptr @perry_closure_batch_ts__7)
+  %r86 = or i64 %r85, 9222527611924643840
+  %r87 = bitcast i64 %r86 to double
+  %r88 = bitcast double %r84 to i64
+  %r89 = and i64 %r88, 281474976710655
+  %r90 = call i64 @js_validate_array_map_callback(i64 %r89, double %r87)
+  %r91 = call i64 @js_array_map(i64 %r89, i64 %r90)
+  %r92 = or i64 %r91, 9222527611924643840
+  %r93 = bitcast i64 %r92 to double
+  store double %r93, ptr %r83
+  %r94 = load ptr, ptr %r2
+  %r95 = icmp eq ptr %r94, null
+  br i1 %r95, label %ss.slow.15, label %ss.chk_top.16
+
+ss.barrier.14:
+  call void @js_write_barrier_root_nanbox(i64 %r71)
+  br label %ss.done.13
+
+ss.slow.15:
+  call void @js_shadow_slot_bind(i32 2, ptr %r83)
+  br label %ss.done.19
+
+ss.chk_top.16:
+  %r96 = getelementptr inbounds i8, ptr %r94, i64 24
+  %r97 = load i64, ptr %r96
+  %r98 = icmp eq i64 %r97, -1
+  br i1 %r98, label %ss.done.19, label %ss.chk_len.17
+
+ss.chk_len.17:
+  %r99 = add i64 %r97, 2
+  %r100 = getelementptr inbounds i8, ptr %r94, i64 8
+  %r101 = load i64, ptr %r100
+  %r102 = icmp ult i64 %r99, %r101
+  br i1 %r102, label %ss.store.18, label %ss.done.19
+
+ss.store.18:
+  %r103 = load ptr, ptr %r94
+  %r104 = shl i64 %r99, 4
+  %r105 = getelementptr inbounds i8, ptr %r103, i64 %r104
+  %r106 = getelementptr inbounds i8, ptr %r105, i64 8
+  %r107 = load i64, ptr %r83
+  %r108 = ptrtoint ptr %r83 to i64
+  %r109 = and i64 %r108, 1
+  %r110 = icmp eq i64 %r109, 0
+  %r111 = select i1 %r110, i64 %r108, i64 0
+  %r112 = or i64 %r111, 1
+  store i64 %r107, ptr %r105
+  store i64 %r112, ptr %r106
+  %r113 = load atomic i32, ptr @PERRY_INCREMENTAL_MARK_BARRIER_ACTIVE_COUNT seq_cst, align 4
+  %r114 = icmp ne i32 %r113, 0
+  br i1 %r114, label %ss.barrier.20, label %ss.done.19
+
+ss.done.19:
+  %r116 = load double, ptr %r83
+  %r117 = bitcast double %r116 to i64
+  %r118 = and i64 %r117, 281474976710655
+  %r119 = call i64 @js_array_slice_values(i64 %r118, double 0.0, double 0x7FFC000000000001)
+  %r120 = or i64 %r119, 9222527611924643840
+  %r121 = bitcast i64 %r120 to double
+  store double %r121, ptr %r115
+  %r122 = load ptr, ptr %r2
+  %r123 = icmp eq ptr %r122, null
+  br i1 %r123, label %ss.slow.21, label %ss.chk_top.22
+
+ss.barrier.20:
+  call void @js_write_barrier_root_nanbox(i64 %r107)
+  br label %ss.done.19
+
+ss.slow.21:
+  call void @js_shadow_slot_bind(i32 3, ptr %r115)
+  br label %ss.done.25
+
+ss.chk_top.22:
+  %r124 = getelementptr inbounds i8, ptr %r122, i64 24
+  %r125 = load i64, ptr %r124
+  %r126 = icmp eq i64 %r125, -1
+  br i1 %r126, label %ss.done.25, label %ss.chk_len.23
+
+ss.chk_len.23:
+  %r127 = add i64 %r125, 3
+  %r128 = getelementptr inbounds i8, ptr %r122, i64 8
+  %r129 = load i64, ptr %r128
+  %r130 = icmp ult i64 %r127, %r129
+  br i1 %r130, label %ss.store.24, label %ss.done.25
+
+ss.store.24:
+  %r131 = load ptr, ptr %r122
+  %r132 = shl i64 %r127, 4
+  %r133 = getelementptr inbounds i8, ptr %r131, i64 %r132
+  %r134 = getelementptr inbounds i8, ptr %r133, i64 8
+  %r135 = load i64, ptr %r115
+  %r136 = ptrtoint ptr %r115 to i64
+  %r137 = and i64 %r136, 1
+  %r138 = icmp eq i64 %r137, 0
+  %r139 = select i1 %r138, i64 %r136, i64 0
+  %r140 = or i64 %r139, 1
+  store i64 %r135, ptr %r133
+  store i64 %r140, ptr %r134
+  %r141 = load atomic i32, ptr @PERRY_INCREMENTAL_MARK_BARRIER_ACTIVE_COUNT seq_cst, align 4
+  %r142 = icmp ne i32 %r141, 0
+  br i1 %r142, label %ss.barrier.26, label %ss.done.25
+
+ss.done.25:
+  %r143 = load ptr, ptr %r2
+  %r144 = icmp eq ptr %r143, null
+  br i1 %r144, label %ss.slow.27, label %ss.chk_top.28
+
+ss.barrier.26:
+  call void @js_write_barrier_root_nanbox(i64 %r135)
+  br label %ss.done.25
+
+ss.slow.27:
+  call void @js_shadow_slot_set(i32 2, i64 0)
+  br label %ss.done.31
+
+ss.chk_top.28:
+  %r145 = getelementptr inbounds i8, ptr %r143, i64 24
+  %r146 = load i64, ptr %r145
+  %r147 = icmp eq i64 %r146, -1
+  br i1 %r147, label %ss.done.31, label %ss.chk_len.29
+
+ss.chk_len.29:
+  %r148 = add i64 %r146, 2
+  %r149 = getelementptr inbounds i8, ptr %r143, i64 8
+  %r150 = load i64, ptr %r149
+  %r151 = icmp ult i64 %r148, %r150
+  br i1 %r151, label %ss.store.30, label %ss.done.31
+
+ss.store.30:
+  %r152 = load ptr, ptr %r143
+  %r153 = shl i64 %r148, 4
+  %r154 = getelementptr inbounds i8, ptr %r152, i64 %r153
+  %r155 = getelementptr inbounds i8, ptr %r154, i64 8
+  %r156 = load i64, ptr %r155
+  %r157 = and i64 %r156, -2
+  store i64 0, ptr %r154
+  store i64 %r157, ptr %r155
+  br label %ss.done.31
+
+ss.done.31:
+  %r158 = load double, ptr %r115
+  %r159 = call i64 @js_closure_alloc_singleton(ptr @perry_closure_batch_ts__9)
+  %r160 = or i64 %r159, 9222527611924643840
+  %r161 = bitcast i64 %r160 to double
+  %r162 = bitcast double %r158 to i64
+  %r163 = and i64 %r162, 281474976710655
+  %r164 = call i64 @js_validate_array_comparator(double %r161)
+  %r165 = call i64 @js_array_sort_with_comparator(i64 %r163, i64 %r164)
+  %r166 = or i64 %r165, 9222527611924643840
+  %r167 = bitcast i64 %r166 to double
+  %r169 = load double, ptr %r115
+  store double %r169, ptr %r168
+  %r170 = load ptr, ptr %r2
+  %r171 = icmp eq ptr %r170, null
+  br i1 %r171, label %ss.slow.32, label %ss.chk_top.33
+
+ss.slow.32:
+  call void @js_shadow_slot_bind(i32 4, ptr %r168)
+  br label %ss.done.36
+
+ss.chk_top.33:
+  %r172 = getelementptr inbounds i8, ptr %r170, i64 24
+  %r173 = load i64, ptr %r172
+  %r174 = icmp eq i64 %r173, -1
+  br i1 %r174, label %ss.done.36, label %ss.chk_len.34
+
+ss.chk_len.34:
+  %r175 = add i64 %r173, 4
+  %r176 = getelementptr inbounds i8, ptr %r170, i64 8
+  %r177 = load i64, ptr %r176
+  %r178 = icmp ult i64 %r175, %r177
+  br i1 %r178, label %ss.store.35, label %ss.done.36
+
+ss.store.35:
+  %r179 = load ptr, ptr %r170
+  %r180 = shl i64 %r175, 4
+  %r181 = getelementptr inbounds i8, ptr %r179, i64 %r180
+  %r182 = getelementptr inbounds i8, ptr %r181, i64 8
+  %r183 = load i64, ptr %r168
+  %r184 = ptrtoint ptr %r168 to i64
+  %r185 = and i64 %r184, 1
+  %r186 = icmp eq i64 %r185, 0
+  %r187 = select i1 %r186, i64 %r184, i64 0
+  %r188 = or i64 %r187, 1
+  store i64 %r183, ptr %r181
+  store i64 %r188, ptr %r182
+  %r189 = load atomic i32, ptr @PERRY_INCREMENTAL_MARK_BARRIER_ACTIVE_COUNT seq_cst, align 4
+  %r190 = icmp ne i32 %r189, 0
+  br i1 %r190, label %ss.barrier.37, label %ss.done.36
+
+ss.done.36:
+  %r191 = load ptr, ptr %r2
+  %r192 = icmp eq ptr %r191, null
+  br i1 %r192, label %ss.slow.38, label %ss.chk_top.39
+
+ss.barrier.37:
+  call void @js_write_barrier_root_nanbox(i64 %r183)
+  br label %ss.done.36
+
+ss.slow.38:
+  call void @js_shadow_slot_set(i32 3, i64 0)
+  br label %ss.done.42
+
+ss.chk_top.39:
+  %r193 = getelementptr inbounds i8, ptr %r191, i64 24
+  %r194 = load i64, ptr %r193
+  %r195 = icmp eq i64 %r194, -1
+  br i1 %r195, label %ss.done.42, label %ss.chk_len.40
+
+ss.chk_len.40:
+  %r196 = add i64 %r194, 3
+  %r197 = getelementptr inbounds i8, ptr %r191, i64 8
+  %r198 = load i64, ptr %r197
+  %r199 = icmp ult i64 %r196, %r198
+  br i1 %r199, label %ss.store.41, label %ss.done.42
+
+ss.store.41:
+  %r200 = load ptr, ptr %r191
+  %r201 = shl i64 %r196, 4
+  %r202 = getelementptr inbounds i8, ptr %r200, i64 %r201
+  %r203 = getelementptr inbounds i8, ptr %r202, i64 8
+  %r204 = load i64, ptr %r203
+  %r205 = and i64 %r204, -2
+  store i64 0, ptr %r202
+  store i64 %r205, ptr %r203
+  br label %ss.done.42
+
+ss.done.42:
+  %r207 = load double, ptr %r54
+  %r208 = call double @perry_fn_batch_ts__summarize(double %r207)
+  store double %r208, ptr %r206
+  %r209 = load ptr, ptr %r2
+  %r210 = icmp eq ptr %r209, null
+  br i1 %r210, label %ss.slow.43, label %ss.chk_top.44
+
+ss.slow.43:
+  call void @js_shadow_slot_bind(i32 5, ptr %r206)
+  br label %ss.done.47
+
+ss.chk_top.44:
+  %r211 = getelementptr inbounds i8, ptr %r209, i64 24
+  %r212 = load i64, ptr %r211
+  %r213 = icmp eq i64 %r212, -1
+  br i1 %r213, label %ss.done.47, label %ss.chk_len.45
+
+ss.chk_len.45:
+  %r214 = add i64 %r212, 5
+  %r215 = getelementptr inbounds i8, ptr %r209, i64 8
+  %r216 = load i64, ptr %r215
+  %r217 = icmp ult i64 %r214, %r216
+  br i1 %r217, label %ss.store.46, label %ss.done.47
+
+ss.store.46:
+  %r218 = load ptr, ptr %r209
+  %r219 = shl i64 %r214, 4
+  %r220 = getelementptr inbounds i8, ptr %r218, i64 %r219
+  %r221 = getelementptr inbounds i8, ptr %r220, i64 8
+  %r222 = load i64, ptr %r206
+  %r223 = ptrtoint ptr %r206 to i64
+  %r224 = and i64 %r223, 1
+  %r225 = icmp eq i64 %r224, 0
+  %r226 = select i1 %r225, i64 %r223, i64 0
+  %r227 = or i64 %r226, 1
+  store i64 %r222, ptr %r220
+  store i64 %r227, ptr %r221
+  %r228 = load atomic i32, ptr @PERRY_INCREMENTAL_MARK_BARRIER_ACTIVE_COUNT seq_cst, align 4
+  %r229 = icmp ne i32 %r228, 0
+  br i1 %r229, label %ss.barrier.48, label %ss.done.47
+
+ss.done.47:
+  %r230 = load ptr, ptr %r2
+  %r231 = icmp eq ptr %r230, null
+  br i1 %r231, label %ss.slow.49, label %ss.chk_top.50
+
+ss.barrier.48:
+  call void @js_write_barrier_root_nanbox(i64 %r222)
+  br label %ss.done.47
+
+ss.slow.49:
+  call void @js_shadow_slot_set(i32 1, i64 0)
+  br label %ss.done.53
+
+ss.chk_top.50:
+  %r232 = getelementptr inbounds i8, ptr %r230, i64 24
+  %r233 = load i64, ptr %r232
+  %r234 = icmp eq i64 %r233, -1
+  br i1 %r234, label %ss.done.53, label %ss.chk_len.51
+
+ss.chk_len.51:
+  %r235 = add i64 %r233, 1
+  %r236 = getelementptr inbounds i8, ptr %r230, i64 8
+  %r237 = load i64, ptr %r236
+  %r238 = icmp ult i64 %r235, %r237
+  br i1 %r238, label %ss.store.52, label %ss.done.53
+
+ss.store.52:
+  %r239 = load ptr, ptr %r230
+  %r240 = shl i64 %r235, 4
+  %r241 = getelementptr inbounds i8, ptr %r239, i64 %r240
+  %r242 = getelementptr inbounds i8, ptr %r241, i64 8
+  %r243 = load i64, ptr %r242
+  %r244 = and i64 %r243, -2
+  store i64 0, ptr %r241
+  store i64 %r244, ptr %r242
+  br label %ss.done.53
+
+ss.done.53:
+  store double 0.0, ptr %r245
+  store i32 0, ptr %r246
+  br label %for.cond.54
+
+for.cond.54:
+  %r247 = load i32, ptr %r246
+  %r248 = sitofp i32 %r247 to double
+  %r249 = fcmp olt double %r248, 16.0
+  %r250 = select i1 %r249, i64 9222246136947933188, i64 9222246136947933187
+  %r251 = bitcast i64 %r250 to double
+  %r252 = icmp eq i64 %r250, 9222246136947933188
+  br i1 %r252, label %for.body.55, label %for.exit.57
+
+for.body.55:
+  %r253 = load double, ptr %r245
+  %r254 = load double, ptr %r168
+  %r255 = load i32, ptr %r246
+  %r256 = bitcast double %r254 to i64
+  %r257 = and i64 %r256, 281474976710655
+  %r258 = lshr i64 %r256, 48
+  %r259 = icmp eq i64 %r258, 32765
+  %r260 = icmp ugt i64 %r257, 1048575
+  %r261 = and i1 %r259, %r260
+  br i1 %r261, label %arr.guard.deref.61, label %arr.fallback.59
+
+for.update.56:
+  %r389 = load i32, ptr %r246
+  %r390 = add i32 %r389, 1
+  store i32 %r390, ptr %r246
+  %r391 = sitofp i32 %r389 to double
+  %r392 = sitofp i32 %r390 to double
+  br label %for.cond.54
+
+for.exit.57:
+  %r393 = load ptr, ptr %r2
+  %r394 = icmp eq ptr %r393, null
+  br i1 %r394, label %ss.slow.75, label %ss.chk_top.76
+
+arr.fast.58:
+  %r300 = bitcast double %r254 to i64
+  %r301 = and i64 %r300, 281474976710655
+  %r302 = zext i32 %r255 to i64
+  %r303 = shl i64 %r302, 3
+  %r304 = add i64 %r303, 8
+  %r305 = add i64 %r301, %r304
+  %r306 = inttoptr i64 %r305 to ptr
+  %r307 = load double, ptr %r306
+  %r308 = bitcast double %r307 to i64
+  %r309 = icmp eq i64 %r308, 9222246136947933200
+  %r310 = bitcast i64 9222246136947933185 to double
+  %r311 = select i1 %r309, double %r310, double %r307
+  br label %arr.merge.60
+
+arr.fallback.59:
+  %r298 = sitofp i32 %r255 to double
+  %r299 = call double @js_typed_feedback_array_index_get_fallback_boxed(i64 8450987250308612165, double %r254, double %r298)
+  br label %arr.merge.60
+
+arr.merge.60:
+  %r312 = phi double [ %r311, %arr.fast.58 ], [ %r299, %arr.fallback.59 ]
+  %r313 = bitcast double %r312 to i64
+  %r314 = and i64 %r313, 281474976710655
+  %r315 = load double, ptr @batch_ts_.str.11.handle
+  %r316 = bitcast double %r315 to i64
+  %r317 = and i64 %r316, 281474976710655
+  %r318 = lshr i64 %r313, 48
+  %r319 = icmp eq i64 %r318, 32761
+  %r320 = icmp eq i64 %r318, 32766
+  %r321 = and i64 %r318, 65533
+  %r322 = icmp eq i64 %r321, 32765
+  br i1 %r319, label %pget.recv_sso.62, label %pget.check_class_ref.68
+
+arr.guard.deref.61:
+  %r262 = bitcast double %r254 to i64
+  %r263 = and i64 %r262, 281474976710655
+  %r264 = sub i64 %r263, 8
+  %r265 = inttoptr i64 %r264 to ptr
+  %r266 = load i8, ptr %r265
+  %r267 = icmp eq i8 %r266, 1
+  %r268 = sub i64 %r263, 7
+  %r269 = inttoptr i64 %r268 to ptr
+  %r270 = load i8, ptr %r269
+  %r271 = and i8 %r270, 128
+  %r272 = icmp eq i8 %r271, 0
+  %r273 = sub i64 %r263, 6
+  %r274 = inttoptr i64 %r273 to ptr
+  %r275 = load i16, ptr %r274
+  %r276 = and i16 %r275, 1024
+  %r277 = icmp eq i16 %r276, 0
+  %r278 = load volatile i8, ptr @PERRY_ARRAY_INDEX_FAST_PATH_INVALIDATED
+  %r279 = icmp eq i8 %r278, 0
+  %r280 = inttoptr i64 %r263 to ptr
+  %r281 = load i32, ptr %r280
+  %r282 = getelementptr i8, ptr %r280, i64 4
+  %r283 = load i32, ptr %r282
+  %r284 = icmp slt i32 %r255, 0
+  %r285 = icmp eq i1 %r284, false
+  %r286 = icmp ult i32 %r255, %r281
+  %r287 = icmp ule i32 %r281, 16000000
+  %r288 = icmp ule i32 %r283, 16000000
+  %r289 = icmp ule i32 %r281, %r283
+  %r290 = and i1 %r267, %r272
+  %r291 = and i1 %r290, %r277
+  %r292 = and i1 %r291, %r279
+  %r293 = and i1 %r292, %r285
+  %r294 = and i1 %r293, %r286
+  %r295 = and i1 %r294, %r287
+  %r296 = and i1 %r295, %r288
+  %r297 = and i1 %r296, %r289
+  br i1 %r297, label %arr.fast.58, label %arr.fallback.59
+
+pget.recv_sso.62:
+  %r386 = call double @js_object_get_field_by_name_f64(i64 %r313, i64 %r317)
+  br label %pget.recv_merge.66
+
+pget.recv_ok.63:
+  call void @js_typed_feedback_observe_property_get(i64 8450987250308612166, i64 %r314, i64 %r317)
+  %r324 = icmp ugt i64 %r314, 1048575
+  %r325 = ptrtoint ptr @perry_ic_71 to i64
+  %r326 = select i1 %r324, i64 %r314, i64 %r325
+  %r327 = sub i64 %r326, 8
+  %r328 = inttoptr i64 %r327 to ptr
+  %r329 = load i8, ptr %r328
+  %r330 = icmp eq i8 %r329, 2
+  %r331 = and i1 %r324, %r330
+  %r332 = add i64 %r326, 12
+  %r333 = inttoptr i64 %r332 to ptr
+  %r334 = load i32, ptr %r333
+  %r335 = icmp eq i32 %r334, 1129268819
+  %r336 = xor i1 %r335, true
+  %r337 = and i1 %r331, %r336
+  %r338 = inttoptr i64 %r326 to ptr
+  %r339 = load i32, ptr %r338
+  %r340 = icmp eq i32 %r339, 1
+  %r341 = and i1 %r337, %r340
+  %r342 = sub i64 %r326, 6
+  %r343 = inttoptr i64 %r342 to ptr
+  %r344 = load i16, ptr %r343
+  %r345 = and i16 %r344, 2048
+  %r346 = icmp eq i16 %r345, 0
+  %r347 = and i1 %r341, %r346
+  %r348 = add i64 %r326, 16
+  %r349 = inttoptr i64 %r348 to ptr
+  %r350 = load i64, ptr %r349
+  %r351 = add i64 %r326, 8
+  %r352 = inttoptr i64 %r351 to ptr
+  %r353 = load i32, ptr %r352
+  %r354 = add i32 %r353, -2147483648
+  %r355 = icmp ult i32 %r354, 1073741824
+  %r356 = zext i32 %r353 to i64
+  %r357 = or i64 %r356, 4611686018427387904
+  %r358 = select i1 %r355, i64 %r357, i64 %r350
+  %r359 = getelementptr i64, ptr @perry_ic_71, i64 0
+  %r360 = load i64, ptr %r359
+  %r361 = icmp eq i64 %r358, %r360
+  %r362 = icmp ne i64 %r358, 0
+  %r363 = and i1 %r347, %r361
+  %r364 = and i1 %r363, %r362
+  br i1 %r364, label %pic.hit.69, label %pic.miss.70
+
+pget.recv_bad.64:
+  %r381 = icmp eq i64 %r313, 9222246136947933185
+  %r382 = icmp eq i64 %r313, 9222246136947933186
+  %r383 = or i1 %r381, %r382
+  br i1 %r383, label %pget.throw_nullish.73, label %pget.recv_undef_return.74
+
+pget.recv_class_ref.65:
+  %r323 = call double @js_typed_feedback_object_get_field_by_name_f64(i64 8450987250308612166, i64 %r313, i64 %r317)
+  br label %pget.recv_merge.66
+
+pget.recv_merge.66:
+  %r387 = phi double [ %r380, %pic.merge.71 ], [ %r385, %pget.recv_undef_return.74 ], [ %r386, %pget.recv_sso.62 ], [ %r323, %pget.recv_class_ref.65 ]
+  %r388 = call double @js_dynamic_string_or_number_add(double %r253, double %r387)
+  store double %r388, ptr %r245
+  br label %for.update.56
+
+pget.check_ptr.67:
+  br i1 %r322, label %pget.recv_ok.63, label %pget.recv_bad.64
+
+pget.check_class_ref.68:
+  br i1 %r320, label %pget.recv_class_ref.65, label %pget.check_ptr.67
+
+pic.hit.69:
+  %r365 = getelementptr i64, ptr @perry_ic_71, i64 1
+  %r366 = load i64, ptr %r365
+  %r367 = add i64 %r326, 12
+  %r368 = inttoptr i64 %r367 to ptr
+  %r369 = load i32, ptr %r368
+  %r370 = zext i32 %r369 to i64
+  %r371 = icmp ult i64 %r370, 4
+  %r372 = select i1 %r371, i64 4, i64 %r370
+  %r373 = icmp ult i64 %r366, %r372
+  br i1 %r373, label %pic.hit.load.72, label %pic.miss.70
+
+pic.miss.70:
+  call void @js_typed_feedback_record_guard_fail(i64 8450987250308612166)
+  call void @js_typed_feedback_record_fallback_call(i64 8450987250308612166)
+  %r379 = call double @js_object_get_field_ic_miss(i64 %r314, i64 %r317, ptr @perry_ic_71)
+  br label %pic.merge.71
+
+pic.merge.71:
+  %r380 = phi double [ %r378, %pic.hit.load.72 ], [ %r379, %pic.miss.70 ]
+  br label %pget.recv_merge.66
+
+pic.hit.load.72:
+  call void @js_typed_feedback_record_guard_pass(i64 8450987250308612166)
+  %r374 = shl i64 %r366, 3
+  %r375 = add i64 %r314, 32
+  %r376 = add i64 %r375, %r374
+  %r377 = inttoptr i64 %r376 to ptr
+  %r378 = load double, ptr %r377
+  br label %pic.merge.71
+
+pget.throw_nullish.73:
+  %r384 = zext i1 %r382 to i32
+  call void @js_throw_type_error_property_access(i32 %r384, ptr @batch_ts_.str.11.bytes, i64 5)
+  unreachable
+
+pget.recv_undef_return.74:
+  %r385 = call double @js_object_get_field_by_name_f64(i64 %r313, i64 %r317)
+  br label %pget.recv_merge.66
+
+ss.slow.75:
+  call void @js_shadow_slot_set(i32 4, i64 0)
+  br label %ss.done.79
+
+ss.chk_top.76:
+  %r395 = getelementptr inbounds i8, ptr %r393, i64 24
+  %r396 = load i64, ptr %r395
+  %r397 = icmp eq i64 %r396, -1
+  br i1 %r397, label %ss.done.79, label %ss.chk_len.77
+
+ss.chk_len.77:
+  %r398 = add i64 %r396, 4
+  %r399 = getelementptr inbounds i8, ptr %r393, i64 8
+  %r400 = load i64, ptr %r399
+  %r401 = icmp ult i64 %r398, %r400
+  br i1 %r401, label %ss.store.78, label %ss.done.79
+
+ss.store.78:
+  %r402 = load ptr, ptr %r393
+  %r403 = shl i64 %r398, 4
+  %r404 = getelementptr inbounds i8, ptr %r402, i64 %r403
+  %r405 = getelementptr inbounds i8, ptr %r404, i64 8
+  %r406 = load i64, ptr %r405
+  %r407 = and i64 %r406, -2
+  store i64 0, ptr %r404
+  store i64 %r407, ptr %r405
+  br label %ss.done.79
+
+ss.done.79:
+  store i32 0, ptr %r408
+  br label %for.cond.80
+
+for.cond.80:
+  %r409 = load i32, ptr %r408
+  %r410 = sitofp i32 %r409 to double
+  %r411 = load double, ptr %r206
+  %r412 = bitcast double %r411 to i64
+  %r413 = and i64 %r412, 281474976710655
+  %r414 = lshr i64 %r412, 48
+  %r415 = and i64 %r414, 65533
+  %r416 = icmp eq i64 %r415, 32765
+  %r417 = icmp ugt i64 %r413, 1048575
+  %r418 = and i1 %r416, %r417
+  br i1 %r418, label %plen.check_gc.84, label %plen.slow.86
+
+for.body.81:
+  %r442 = load double, ptr %r245
+  %r443 = load double, ptr %r206
+  %r444 = load i32, ptr %r408
+  %r445 = bitcast double %r443 to i64
+  %r446 = and i64 %r445, 281474976710655
+  %r447 = lshr i64 %r445, 48
+  %r448 = icmp eq i64 %r447, 32765
+  %r449 = icmp ugt i64 %r446, 1048575
+  %r450 = and i1 %r448, %r449
+  br i1 %r450, label %arr.guard.deref.91, label %arr.fallback.89
+
+for.update.82:
+  %r717 = load i32, ptr %r408
+  %r718 = add i32 %r717, 1
+  store i32 %r718, ptr %r408
+  %r719 = sitofp i32 %r717 to double
+  %r720 = sitofp i32 %r718 to double
+  br label %for.cond.80
+
+for.exit.83:
+  %r722 = load double, ptr %r206
+  %r723 = call double @perry_fn_batch_ts__totalsRow(double %r722)
+  store double %r723, ptr %r721
+  %r724 = load ptr, ptr %r2
+  %r725 = icmp eq ptr %r724, null
+  br i1 %r725, label %ss.slow.122, label %ss.chk_top.123
+
+plen.check_gc.84:
+  %r419 = sub i64 %r413, 8
+  %r420 = inttoptr i64 %r419 to ptr
+  %r421 = load i8, ptr %r420
+  %r422 = icmp eq i8 %r421, 1
+  %r423 = icmp eq i8 %r421, 3
+  %r424 = or i1 %r422, %r423
+  %r425 = sub i64 %r413, 7
+  %r426 = inttoptr i64 %r425 to ptr
+  %r427 = load i8, ptr %r426
+  %r428 = and i8 %r427, 128
+  %r429 = icmp eq i8 %r428, 0
+  %r430 = and i1 %r424, %r429
+  br i1 %r430, label %plen.fast.85, label %plen.slow.86
+
+plen.fast.85:
+  %r431 = icmp ult i64 %r413, 4096
+  %r432 = inttoptr i64 %r413 to ptr
+  %r433 = select i1 %r431, ptr @perry_null_guard_zero, ptr %r432
+  %r434 = load i32, ptr %r433
+  %r435 = uitofp i32 %r434 to double
+  br label %plen.merge.87
+
+plen.slow.86:
+  %r436 = call double @js_value_length_f64(double %r411)
+  br label %plen.merge.87
+
+plen.merge.87:
+  %r437 = phi double [ %r435, %plen.fast.85 ], [ %r436, %plen.slow.86 ]
+  %r438 = fcmp olt double %r410, %r437
+  %r439 = select i1 %r438, i64 9222246136947933188, i64 9222246136947933187
+  %r440 = bitcast i64 %r439 to double
+  %r441 = icmp eq i64 %r439, 9222246136947933188
+  br i1 %r441, label %for.body.81, label %for.exit.83
+
+arr.fast.88:
+  %r489 = bitcast double %r443 to i64
+  %r490 = and i64 %r489, 281474976710655
+  %r491 = zext i32 %r444 to i64
+  %r492 = shl i64 %r491, 3
+  %r493 = add i64 %r492, 8
+  %r494 = add i64 %r490, %r493
+  %r495 = inttoptr i64 %r494 to ptr
+  %r496 = load double, ptr %r495
+  %r497 = bitcast double %r496 to i64
+  %r498 = icmp eq i64 %r497, 9222246136947933200
+  %r499 = bitcast i64 9222246136947933185 to double
+  %r500 = select i1 %r498, double %r499, double %r496
+  br label %arr.merge.90
+
+arr.fallback.89:
+  %r487 = sitofp i32 %r444 to double
+  %r488 = call double @js_typed_feedback_array_index_get_fallback_boxed(i64 8450987250308612168, double %r443, double %r487)
+  br label %arr.merge.90
+
+arr.merge.90:
+  %r501 = phi double [ %r500, %arr.fast.88 ], [ %r488, %arr.fallback.89 ]
+  %r502 = bitcast double %r501 to i64
+  %r503 = and i64 %r502, 281474976710655
+  %r504 = load double, ptr @batch_ts_.str.13.handle
+  %r505 = bitcast double %r504 to i64
+  %r506 = and i64 %r505, 281474976710655
+  %r507 = lshr i64 %r502, 48
+  %r508 = icmp eq i64 %r507, 32761
+  %r509 = icmp eq i64 %r507, 32766
+  %r510 = and i64 %r507, 65533
+  %r511 = icmp eq i64 %r510, 32765
+  br i1 %r508, label %pget.recv_sso.92, label %pget.check_class_ref.98
+
+arr.guard.deref.91:
+  %r451 = bitcast double %r443 to i64
+  %r452 = and i64 %r451, 281474976710655
+  %r453 = sub i64 %r452, 8
+  %r454 = inttoptr i64 %r453 to ptr
+  %r455 = load i8, ptr %r454
+  %r456 = icmp eq i8 %r455, 1
+  %r457 = sub i64 %r452, 7
+  %r458 = inttoptr i64 %r457 to ptr
+  %r459 = load i8, ptr %r458
+  %r460 = and i8 %r459, 128
+  %r461 = icmp eq i8 %r460, 0
+  %r462 = sub i64 %r452, 6
+  %r463 = inttoptr i64 %r462 to ptr
+  %r464 = load i16, ptr %r463
+  %r465 = and i16 %r464, 1024
+  %r466 = icmp eq i16 %r465, 0
+  %r467 = load volatile i8, ptr @PERRY_ARRAY_INDEX_FAST_PATH_INVALIDATED
+  %r468 = icmp eq i8 %r467, 0
+  %r469 = inttoptr i64 %r452 to ptr
+  %r470 = load i32, ptr %r469
+  %r471 = getelementptr i8, ptr %r469, i64 4
+  %r472 = load i32, ptr %r471
+  %r473 = icmp slt i32 %r444, 0
+  %r474 = icmp eq i1 %r473, false
+  %r475 = icmp ult i32 %r444, %r470
+  %r476 = icmp ule i32 %r470, 16000000
+  %r477 = icmp ule i32 %r472, 16000000
+  %r478 = icmp ule i32 %r470, %r472
+  %r479 = and i1 %r456, %r461
+  %r480 = and i1 %r479, %r466
+  %r481 = and i1 %r480, %r468
+  %r482 = and i1 %r481, %r474
+  %r483 = and i1 %r482, %r475
+  %r484 = and i1 %r483, %r476
+  %r485 = and i1 %r484, %r477
+  %r486 = and i1 %r485, %r478
+  br i1 %r486, label %arr.fast.88, label %arr.fallback.89
+
+pget.recv_sso.92:
+  %r575 = call double @js_object_get_field_by_name_f64(i64 %r502, i64 %r506)
+  br label %pget.recv_merge.96
+
+pget.recv_ok.93:
+  call void @js_typed_feedback_observe_property_get(i64 8450987250308612169, i64 %r503, i64 %r506)
+  %r513 = icmp ugt i64 %r503, 1048575
+  %r514 = ptrtoint ptr @perry_ic_74 to i64
+  %r515 = select i1 %r513, i64 %r503, i64 %r514
+  %r516 = sub i64 %r515, 8
+  %r517 = inttoptr i64 %r516 to ptr
+  %r518 = load i8, ptr %r517
+  %r519 = icmp eq i8 %r518, 2
+  %r520 = and i1 %r513, %r519
+  %r521 = add i64 %r515, 12
+  %r522 = inttoptr i64 %r521 to ptr
+  %r523 = load i32, ptr %r522
+  %r524 = icmp eq i32 %r523, 1129268819
+  %r525 = xor i1 %r524, true
+  %r526 = and i1 %r520, %r525
+  %r527 = inttoptr i64 %r515 to ptr
+  %r528 = load i32, ptr %r527
+  %r529 = icmp eq i32 %r528, 1
+  %r530 = and i1 %r526, %r529
+  %r531 = sub i64 %r515, 6
+  %r532 = inttoptr i64 %r531 to ptr
+  %r533 = load i16, ptr %r532
+  %r534 = and i16 %r533, 2048
+  %r535 = icmp eq i16 %r534, 0
+  %r536 = and i1 %r530, %r535
+  %r537 = add i64 %r515, 16
+  %r538 = inttoptr i64 %r537 to ptr
+  %r539 = load i64, ptr %r538
+  %r540 = add i64 %r515, 8
+  %r541 = inttoptr i64 %r540 to ptr
+  %r542 = load i32, ptr %r541
+  %r543 = add i32 %r542, -2147483648
+  %r544 = icmp ult i32 %r543, 1073741824
+  %r545 = zext i32 %r542 to i64
+  %r546 = or i64 %r545, 4611686018427387904
+  %r547 = select i1 %r544, i64 %r546, i64 %r539
+  %r548 = getelementptr i64, ptr @perry_ic_74, i64 0
+  %r549 = load i64, ptr %r548
+  %r550 = icmp eq i64 %r547, %r549
+  %r551 = icmp ne i64 %r547, 0
+  %r552 = and i1 %r536, %r550
+  %r553 = and i1 %r552, %r551
+  br i1 %r553, label %pic.hit.99, label %pic.miss.100
+
+pget.recv_bad.94:
+  %r570 = icmp eq i64 %r502, 9222246136947933185
+  %r571 = icmp eq i64 %r502, 9222246136947933186
+  %r572 = or i1 %r570, %r571
+  br i1 %r572, label %pget.throw_nullish.103, label %pget.recv_undef_return.104
+
+pget.recv_class_ref.95:
+  %r512 = call double @js_typed_feedback_object_get_field_by_name_f64(i64 8450987250308612169, i64 %r502, i64 %r506)
+  br label %pget.recv_merge.96
+
+pget.recv_merge.96:
+  %r576 = phi double [ %r569, %pic.merge.101 ], [ %r574, %pget.recv_undef_return.104 ], [ %r575, %pget.recv_sso.92 ], [ %r512, %pget.recv_class_ref.95 ]
+  %r577 = call double @js_dynamic_string_or_number_add(double %r442, double %r576)
+  %r578 = bitcast double %r577 to i64
+  %r579 = call i32 @js_gc_temp_root_push(i64 %r578)
+  %r580 = load double, ptr %r206
+  %r581 = load i32, ptr %r408
+  %r582 = bitcast double %r580 to i64
+  %r583 = and i64 %r582, 281474976710655
+  %r584 = lshr i64 %r582, 48
+  %r585 = icmp eq i64 %r584, 32765
+  %r586 = icmp ugt i64 %r583, 1048575
+  %r587 = and i1 %r585, %r586
+  br i1 %r587, label %arr.guard.deref.108, label %arr.fallback.106
+
+pget.check_ptr.97:
+  br i1 %r511, label %pget.recv_ok.93, label %pget.recv_bad.94
+
+pget.check_class_ref.98:
+  br i1 %r509, label %pget.recv_class_ref.95, label %pget.check_ptr.97
+
+pic.hit.99:
+  %r554 = getelementptr i64, ptr @perry_ic_74, i64 1
+  %r555 = load i64, ptr %r554
+  %r556 = add i64 %r515, 12
+  %r557 = inttoptr i64 %r556 to ptr
+  %r558 = load i32, ptr %r557
+  %r559 = zext i32 %r558 to i64
+  %r560 = icmp ult i64 %r559, 4
+  %r561 = select i1 %r560, i64 4, i64 %r559
+  %r562 = icmp ult i64 %r555, %r561
+  br i1 %r562, label %pic.hit.load.102, label %pic.miss.100
+
+pic.miss.100:
+  call void @js_typed_feedback_record_guard_fail(i64 8450987250308612169)
+  call void @js_typed_feedback_record_fallback_call(i64 8450987250308612169)
+  %r568 = call double @js_object_get_field_ic_miss(i64 %r503, i64 %r506, ptr @perry_ic_74)
+  br label %pic.merge.101
+
+pic.merge.101:
+  %r569 = phi double [ %r567, %pic.hit.load.102 ], [ %r568, %pic.miss.100 ]
+  br label %pget.recv_merge.96
+
+pic.hit.load.102:
+  call void @js_typed_feedback_record_guard_pass(i64 8450987250308612169)
+  %r563 = shl i64 %r555, 3
+  %r564 = add i64 %r503, 32
+  %r565 = add i64 %r564, %r563
+  %r566 = inttoptr i64 %r565 to ptr
+  %r567 = load double, ptr %r566
+  br label %pic.merge.101
+
+pget.throw_nullish.103:
+  %r573 = zext i1 %r571 to i32
+  call void @js_throw_type_error_property_access(i32 %r573, ptr @batch_ts_.str.13.bytes, i64 5)
+  unreachable
+
+pget.recv_undef_return.104:
+  %r574 = call double @js_object_get_field_by_name_f64(i64 %r502, i64 %r506)
+  br label %pget.recv_merge.96
+
+arr.fast.105:
+  %r626 = bitcast double %r580 to i64
+  %r627 = and i64 %r626, 281474976710655
+  %r628 = zext i32 %r581 to i64
+  %r629 = shl i64 %r628, 3
+  %r630 = add i64 %r629, 8
+  %r631 = add i64 %r627, %r630
+  %r632 = inttoptr i64 %r631 to ptr
+  %r633 = load double, ptr %r632
+  %r634 = bitcast double %r633 to i64
+  %r635 = icmp eq i64 %r634, 9222246136947933200
+  %r636 = bitcast i64 9222246136947933185 to double
+  %r637 = select i1 %r635, double %r636, double %r633
+  br label %arr.merge.107
+
+arr.fallback.106:
+  %r624 = sitofp i32 %r581 to double
+  %r625 = call double @js_typed_feedback_array_index_get_fallback_boxed(i64 8450987250308612171, double %r580, double %r624)
+  br label %arr.merge.107
+
+arr.merge.107:
+  %r638 = phi double [ %r637, %arr.fast.105 ], [ %r625, %arr.fallback.106 ]
+  %r639 = bitcast double %r638 to i64
+  %r640 = and i64 %r639, 281474976710655
+  %r641 = load double, ptr @batch_ts_.str.3.handle
+  %r642 = bitcast double %r641 to i64
+  %r643 = and i64 %r642, 281474976710655
+  %r644 = lshr i64 %r639, 48
+  %r645 = icmp eq i64 %r644, 32761
+  %r646 = icmp eq i64 %r644, 32766
+  %r647 = and i64 %r644, 65533
+  %r648 = icmp eq i64 %r647, 32765
+  br i1 %r645, label %pget.recv_sso.109, label %pget.check_class_ref.115
+
+arr.guard.deref.108:
+  %r588 = bitcast double %r580 to i64
+  %r589 = and i64 %r588, 281474976710655
+  %r590 = sub i64 %r589, 8
+  %r591 = inttoptr i64 %r590 to ptr
+  %r592 = load i8, ptr %r591
+  %r593 = icmp eq i8 %r592, 1
+  %r594 = sub i64 %r589, 7
+  %r595 = inttoptr i64 %r594 to ptr
+  %r596 = load i8, ptr %r595
+  %r597 = and i8 %r596, 128
+  %r598 = icmp eq i8 %r597, 0
+  %r599 = sub i64 %r589, 6
+  %r600 = inttoptr i64 %r599 to ptr
+  %r601 = load i16, ptr %r600
+  %r602 = and i16 %r601, 1024
+  %r603 = icmp eq i16 %r602, 0
+  %r604 = load volatile i8, ptr @PERRY_ARRAY_INDEX_FAST_PATH_INVALIDATED
+  %r605 = icmp eq i8 %r604, 0
+  %r606 = inttoptr i64 %r589 to ptr
+  %r607 = load i32, ptr %r606
+  %r608 = getelementptr i8, ptr %r606, i64 4
+  %r609 = load i32, ptr %r608
+  %r610 = icmp slt i32 %r581, 0
+  %r611 = icmp eq i1 %r610, false
+  %r612 = icmp ult i32 %r581, %r607
+  %r613 = icmp ule i32 %r607, 16000000
+  %r614 = icmp ule i32 %r609, 16000000
+  %r615 = icmp ule i32 %r607, %r609
+  %r616 = and i1 %r593, %r598
+  %r617 = and i1 %r616, %r603
+  %r618 = and i1 %r617, %r605
+  %r619 = and i1 %r618, %r611
+  %r620 = and i1 %r619, %r612
+  %r621 = and i1 %r620, %r613
+  %r622 = and i1 %r621, %r614
+  %r623 = and i1 %r622, %r615
+  br i1 %r623, label %arr.fast.105, label %arr.fallback.106
+
+pget.recv_sso.109:
+  %r712 = call double @js_object_get_field_by_name_f64(i64 %r639, i64 %r643)
+  br label %pget.recv_merge.113
+
+pget.recv_ok.110:
+  call void @js_typed_feedback_observe_property_get(i64 8450987250308612172, i64 %r640, i64 %r643)
+  %r650 = icmp ugt i64 %r640, 1048575
+  %r651 = ptrtoint ptr @perry_ic_77 to i64
+  %r652 = select i1 %r650, i64 %r640, i64 %r651
+  %r653 = sub i64 %r652, 8
+  %r654 = inttoptr i64 %r653 to ptr
+  %r655 = load i8, ptr %r654
+  %r656 = icmp eq i8 %r655, 2
+  %r657 = and i1 %r650, %r656
+  %r658 = add i64 %r652, 12
+  %r659 = inttoptr i64 %r658 to ptr
+  %r660 = load i32, ptr %r659
+  %r661 = icmp eq i32 %r660, 1129268819
+  %r662 = xor i1 %r661, true
+  %r663 = and i1 %r657, %r662
+  %r664 = inttoptr i64 %r652 to ptr
+  %r665 = load i32, ptr %r664
+  %r666 = icmp eq i32 %r665, 1
+  %r667 = and i1 %r663, %r666
+  %r668 = sub i64 %r652, 6
+  %r669 = inttoptr i64 %r668 to ptr
+  %r670 = load i16, ptr %r669
+  %r671 = and i16 %r670, 2048
+  %r672 = icmp eq i16 %r671, 0
+  %r673 = and i1 %r667, %r672
+  %r674 = add i64 %r652, 16
+  %r675 = inttoptr i64 %r674 to ptr
+  %r676 = load i64, ptr %r675
+  %r677 = add i64 %r652, 8
+  %r678 = inttoptr i64 %r677 to ptr
+  %r679 = load i32, ptr %r678
+  %r680 = add i32 %r679, -2147483648
+  %r681 = icmp ult i32 %r680, 1073741824
+  %r682 = zext i32 %r679 to i64
+  %r683 = or i64 %r682, 4611686018427387904
+  %r684 = select i1 %r681, i64 %r683, i64 %r676
+  %r685 = getelementptr i64, ptr @perry_ic_77, i64 0
+  %r686 = load i64, ptr %r685
+  %r687 = icmp eq i64 %r684, %r686
+  %r688 = icmp ne i64 %r684, 0
+  %r689 = and i1 %r673, %r687
+  %r690 = and i1 %r689, %r688
+  br i1 %r690, label %pic.hit.116, label %pic.miss.117
+
+pget.recv_bad.111:
+  %r707 = icmp eq i64 %r639, 9222246136947933185
+  %r708 = icmp eq i64 %r639, 9222246136947933186
+  %r709 = or i1 %r707, %r708
+  br i1 %r709, label %pget.throw_nullish.120, label %pget.recv_undef_return.121
+
+pget.recv_class_ref.112:
+  %r649 = call double @js_typed_feedback_object_get_field_by_name_f64(i64 8450987250308612172, i64 %r639, i64 %r643)
+  br label %pget.recv_merge.113
+
+pget.recv_merge.113:
+  %r713 = phi double [ %r706, %pic.merge.118 ], [ %r711, %pget.recv_undef_return.121 ], [ %r712, %pget.recv_sso.109 ], [ %r649, %pget.recv_class_ref.112 ]
+  %r714 = call i64 @js_gc_temp_root_get(i32 %r579)
+  %r715 = bitcast i64 %r714 to double
+  %r716 = call double @js_dynamic_string_or_number_add(double %r715, double %r713)
+  call void @js_gc_temp_root_truncate(i32 %r579)
+  store double %r716, ptr %r245
+  br label %for.update.82
+
+pget.check_ptr.114:
+  br i1 %r648, label %pget.recv_ok.110, label %pget.recv_bad.111
+
+pget.check_class_ref.115:
+  br i1 %r646, label %pget.recv_class_ref.112, label %pget.check_ptr.114
+
+pic.hit.116:
+  %r691 = getelementptr i64, ptr @perry_ic_77, i64 1
+  %r692 = load i64, ptr %r691
+  %r693 = add i64 %r652, 12
+  %r694 = inttoptr i64 %r693 to ptr
+  %r695 = load i32, ptr %r694
+  %r696 = zext i32 %r695 to i64
+  %r697 = icmp ult i64 %r696, 4
+  %r698 = select i1 %r697, i64 4, i64 %r696
+  %r699 = icmp ult i64 %r692, %r698
+  br i1 %r699, label %pic.hit.load.119, label %pic.miss.117
+
+pic.miss.117:
+  call void @js_typed_feedback_record_guard_fail(i64 8450987250308612172)
+  call void @js_typed_feedback_record_fallback_call(i64 8450987250308612172)
+  %r705 = call double @js_object_get_field_ic_miss(i64 %r640, i64 %r643, ptr @perry_ic_77)
+  br label %pic.merge.118
+
+pic.merge.118:
+  %r706 = phi double [ %r704, %pic.hit.load.119 ], [ %r705, %pic.miss.117 ]
+  br label %pget.recv_merge.113
+
+pic.hit.load.119:
+  call void @js_typed_feedback_record_guard_pass(i64 8450987250308612172)
+  %r700 = shl i64 %r692, 3
+  %r701 = add i64 %r640, 32
+  %r702 = add i64 %r701, %r700
+  %r703 = inttoptr i64 %r702 to ptr
+  %r704 = load double, ptr %r703
+  br label %pic.merge.118
+
+pget.throw_nullish.120:
+  %r710 = zext i1 %r708 to i32
+  call void @js_throw_type_error_property_access(i32 %r710, ptr @batch_ts_.str.3.bytes, i64 4)
+  unreachable
+
+pget.recv_undef_return.121:
+  %r711 = call double @js_object_get_field_by_name_f64(i64 %r639, i64 %r643)
+  br label %pget.recv_merge.113
+
+ss.slow.122:
+  call void @js_shadow_slot_bind(i32 6, ptr %r721)
+  br label %ss.done.126
+
+ss.chk_top.123:
+  %r726 = getelementptr inbounds i8, ptr %r724, i64 24
+  %r727 = load i64, ptr %r726
+  %r728 = icmp eq i64 %r727, -1
+  br i1 %r728, label %ss.done.126, label %ss.chk_len.124
+
+ss.chk_len.124:
+  %r729 = add i64 %r727, 6
+  %r730 = getelementptr inbounds i8, ptr %r724, i64 8
+  %r731 = load i64, ptr %r730
+  %r732 = icmp ult i64 %r729, %r731
+  br i1 %r732, label %ss.store.125, label %ss.done.126
+
+ss.store.125:
+  %r733 = load ptr, ptr %r724
+  %r734 = shl i64 %r729, 4
+  %r735 = getelementptr inbounds i8, ptr %r733, i64 %r734
+  %r736 = getelementptr inbounds i8, ptr %r735, i64 8
+  %r737 = load i64, ptr %r721
+  %r738 = ptrtoint ptr %r721 to i64
+  %r739 = and i64 %r738, 1
+  %r740 = icmp eq i64 %r739, 0
+  %r741 = select i1 %r740, i64 %r738, i64 0
+  %r742 = or i64 %r741, 1
+  store i64 %r737, ptr %r735
+  store i64 %r742, ptr %r736
+  %r743 = load atomic i32, ptr @PERRY_INCREMENTAL_MARK_BARRIER_ACTIVE_COUNT seq_cst, align 4
+  %r744 = icmp ne i32 %r743, 0
+  br i1 %r744, label %ss.barrier.127, label %ss.done.126
+
+ss.done.126:
+  %r745 = load ptr, ptr %r2
+  %r746 = icmp eq ptr %r745, null
+  br i1 %r746, label %ss.slow.128, label %ss.chk_top.129
+
+ss.barrier.127:
+  call void @js_write_barrier_root_nanbox(i64 %r737)
+  br label %ss.done.126
+
+ss.slow.128:
+  call void @js_shadow_slot_set(i32 5, i64 0)
+  br label %ss.done.132
+
+ss.chk_top.129:
+  %r747 = getelementptr inbounds i8, ptr %r745, i64 24
+  %r748 = load i64, ptr %r747
+  %r749 = icmp eq i64 %r748, -1
+  br i1 %r749, label %ss.done.132, label %ss.chk_len.130
+
+ss.chk_len.130:
+  %r750 = add i64 %r748, 5
+  %r751 = getelementptr inbounds i8, ptr %r745, i64 8
+  %r752 = load i64, ptr %r751
+  %r753 = icmp ult i64 %r750, %r752
+  br i1 %r753, label %ss.store.131, label %ss.done.132
+
+ss.store.131:
+  %r754 = load ptr, ptr %r745
+  %r755 = shl i64 %r750, 4
+  %r756 = getelementptr inbounds i8, ptr %r754, i64 %r755
+  %r757 = getelementptr inbounds i8, ptr %r756, i64 8
+  %r758 = load i64, ptr %r757
+  %r759 = and i64 %r758, -2
+  store i64 0, ptr %r756
+  store i64 %r759, ptr %r757
+  br label %ss.done.132
+
+ss.done.132:
+  %r760 = load double, ptr %r245
+  %r761 = load double, ptr %r245
+  %r762 = load double, ptr %r245
+  %r763 = load double, ptr %r245
+  %r764 = load double, ptr %r721
+  %r765 = bitcast double %r764 to i64
+  %r766 = and i64 %r765, 281474976710655
+  %r767 = load double, ptr @batch_ts_.str.2.handle
+  %r768 = bitcast double %r767 to i64
+  %r769 = and i64 %r768, 281474976710655
+  %r770 = load i64, ptr @perry_class_keys_batch_ts__Row
+  %r771 = load volatile i8, ptr @PERRY_CLASS_FIELD_INLINE_GUARD_DISABLED
+  %r772 = icmp eq i8 %r771, 0
+  %r773 = lshr i64 %r765, 48
+  %r774 = icmp eq i64 %r773, 32765
+  %r775 = icmp ugt i64 %r766, 1048575
+  %r776 = and i1 %r774, %r775
+  %r777 = and i1 %r776, %r772
+  br i1 %r777, label %class_field_inline.deref.136, label %class_field_inline.guardcall.137
+
+class_field_get_number.fast.133:
+  %r812 = inttoptr i64 %r766 to ptr
+  %r813 = getelementptr i8, ptr %r812, i64 32
+  %r814 = getelementptr double, ptr %r813, i64 2
+  %r815 = load double, ptr %r814
+  br label %class_field_get_number.merge.135
+
+class_field_get_number.fallback.134:
+  call void @js_typed_feedback_record_fallback_call(i64 8450987250308612174)
+  %r816 = call double @js_object_get_field_by_name_f64(i64 %r765, i64 %r769)
+  %r817 = call double @js_number_coerce(double %r816)
+  br label %class_field_get_number.merge.135
+
+class_field_get_number.merge.135:
+  %r818 = phi double [ %r815, %class_field_get_number.fast.133 ], [ %r817, %class_field_get_number.fallback.134 ]
+  %r819 = fadd double %r763, %r818
+  %r820 = load double, ptr %r721
+  %r821 = bitcast double %r820 to i64
+  %r822 = and i64 %r821, 281474976710655
+  %r823 = load double, ptr @batch_ts_.str.4.handle
+  %r824 = bitcast double %r823 to i64
+  %r825 = and i64 %r824, 281474976710655
+  %r826 = load i64, ptr @perry_class_keys_batch_ts__Row
+  %r827 = load volatile i8, ptr @PERRY_CLASS_FIELD_INLINE_GUARD_DISABLED
+  %r828 = icmp eq i8 %r827, 0
+  %r829 = lshr i64 %r821, 48
+  %r830 = icmp eq i64 %r829, 32765
+  %r831 = icmp ugt i64 %r822, 1048575
+  %r832 = and i1 %r830, %r831
+  %r833 = and i1 %r832, %r828
+  br i1 %r833, label %class_field_inline.deref.141, label %class_field_inline.guardcall.142
+
+class_field_inline.deref.136:
+  %r778 = inttoptr i64 %r766 to ptr
+  %r779 = getelementptr i8, ptr %r778, i64 -8
+  %r780 = load i8, ptr %r779
+  %r781 = icmp eq i8 %r780, 2
+  %r782 = getelementptr i8, ptr %r778, i64 -7
+  %r783 = load i8, ptr %r782
+  %r784 = and i8 %r783, -128
+  %r785 = icmp eq i8 %r784, 0
+  %r786 = getelementptr i8, ptr %r778, i64 -6
+  %r787 = load i16, ptr %r786
+  %r788 = load i32, ptr %r778
+  %r789 = icmp eq i32 %r788, 1
+  %r790 = getelementptr i8, ptr %r778, i64 4
+  %r791 = load i32, ptr %r790
+  %r792 = icmp eq i32 %r791, 1
+  %r793 = getelementptr i8, ptr %r778, i64 12
+  %r794 = load i32, ptr %r793
+  %r795 = icmp ugt i32 %r794, 2
+  %r796 = getelementptr i8, ptr %r778, i64 16
+  %r797 = load i64, ptr %r796
+  %r798 = icmp eq i64 %r797, %r770
+  %r799 = and i1 %r781, %r785
+  %r800 = and i1 %r799, %r789
+  %r801 = and i1 %r800, %r792
+  %r802 = and i1 %r801, %r795
+  %r803 = and i1 %r802, %r798
+  %r804 = and i16 %r787, 2048
+  %r805 = icmp eq i16 %r804, 0
+  %r806 = and i1 %r803, %r805
+  %r807 = and i16 %r787, 4096
+  %r808 = icmp ne i16 %r807, 0
+  %r809 = and i1 %r806, %r808
+  br i1 %r809, label %class_field_get_number.fast.133, label %class_field_inline.guardcall.137
+
+class_field_inline.guardcall.137:
+  %r810 = call i32 @js_typed_feedback_class_field_get_guard(i64 8450987250308612174, double %r764, i32 1, i64 %r770, i64 %r769, i32 2, i32 1)
+  %r811 = icmp ne i32 %r810, 0
+  br i1 %r811, label %class_field_get_number.fast.133, label %class_field_get_number.fallback.134
+
+class_field_get_number.fast.138:
+  %r868 = inttoptr i64 %r822 to ptr
+  %r869 = getelementptr i8, ptr %r868, i64 32
+  %r870 = getelementptr double, ptr %r869, i64 3
+  %r871 = load double, ptr %r870
+  br label %class_field_get_number.merge.140
+
+class_field_get_number.fallback.139:
+  call void @js_typed_feedback_record_fallback_call(i64 8450987250308612175)
+  %r872 = call double @js_object_get_field_by_name_f64(i64 %r821, i64 %r825)
+  %r873 = call double @js_number_coerce(double %r872)
+  br label %class_field_get_number.merge.140
+
+class_field_get_number.merge.140:
+  %r874 = phi double [ %r871, %class_field_get_number.fast.138 ], [ %r873, %class_field_get_number.fallback.139 ]
+  %r875 = fadd double %r819, %r874
+  store double %r875, ptr %r245
+  %r876 = load ptr, ptr %r2
+  %r877 = icmp eq ptr %r876, null
+  br i1 %r877, label %ss.slow.143, label %ss.chk_top.144
+
+class_field_inline.deref.141:
+  %r834 = inttoptr i64 %r822 to ptr
+  %r835 = getelementptr i8, ptr %r834, i64 -8
+  %r836 = load i8, ptr %r835
+  %r837 = icmp eq i8 %r836, 2
+  %r838 = getelementptr i8, ptr %r834, i64 -7
+  %r839 = load i8, ptr %r838
+  %r840 = and i8 %r839, -128
+  %r841 = icmp eq i8 %r840, 0
+  %r842 = getelementptr i8, ptr %r834, i64 -6
+  %r843 = load i16, ptr %r842
+  %r844 = load i32, ptr %r834
+  %r845 = icmp eq i32 %r844, 1
+  %r846 = getelementptr i8, ptr %r834, i64 4
+  %r847 = load i32, ptr %r846
+  %r848 = icmp eq i32 %r847, 1
+  %r849 = getelementptr i8, ptr %r834, i64 12
+  %r850 = load i32, ptr %r849
+  %r851 = icmp ugt i32 %r850, 3
+  %r852 = getelementptr i8, ptr %r834, i64 16
+  %r853 = load i64, ptr %r852
+  %r854 = icmp eq i64 %r853, %r826
+  %r855 = and i1 %r837, %r841
+  %r856 = and i1 %r855, %r845
+  %r857 = and i1 %r856, %r848
+  %r858 = and i1 %r857, %r851
+  %r859 = and i1 %r858, %r854
+  %r860 = and i16 %r843, 2048
+  %r861 = icmp eq i16 %r860, 0
+  %r862 = and i1 %r859, %r861
+  %r863 = and i16 %r843, 4096
+  %r864 = icmp ne i16 %r863, 0
+  %r865 = and i1 %r862, %r864
+  br i1 %r865, label %class_field_get_number.fast.138, label %class_field_inline.guardcall.142
+
+class_field_inline.guardcall.142:
+  %r866 = call i32 @js_typed_feedback_class_field_get_guard(i64 8450987250308612175, double %r820, i32 1, i64 %r826, i64 %r825, i32 3, i32 1)
+  %r867 = icmp ne i32 %r866, 0
+  br i1 %r867, label %class_field_get_number.fast.138, label %class_field_get_number.fallback.139
+
+ss.slow.143:
+  call void @js_shadow_slot_set(i32 6, i64 0)
+  br label %ss.done.147
+
+ss.chk_top.144:
+  %r878 = getelementptr inbounds i8, ptr %r876, i64 24
+  %r879 = load i64, ptr %r878
+  %r880 = icmp eq i64 %r879, -1
+  br i1 %r880, label %ss.done.147, label %ss.chk_len.145
+
+ss.chk_len.145:
+  %r881 = add i64 %r879, 6
+  %r882 = getelementptr inbounds i8, ptr %r876, i64 8
+  %r883 = load i64, ptr %r882
+  %r884 = icmp ult i64 %r881, %r883
+  br i1 %r884, label %ss.store.146, label %ss.done.147
+
+ss.store.146:
+  %r885 = load ptr, ptr %r876
+  %r886 = shl i64 %r881, 4
+  %r887 = getelementptr inbounds i8, ptr %r885, i64 %r886
+  %r888 = getelementptr inbounds i8, ptr %r887, i64 8
+  %r889 = load i64, ptr %r888
+  %r890 = and i64 %r889, -2
+  store i64 0, ptr %r887
+  store i64 %r890, ptr %r888
+  br label %ss.done.147
+
+ss.done.147:
+  %r891 = load double, ptr @batch_ts_.str.19.handle
+  %r892 = load double, ptr %r245
+  %r893 = call i64 @js_number_to_fixed(double %r892, double 4.0)
+  %r894 = or i64 %r893, 9223090561878065152
+  %r895 = bitcast i64 %r894 to double
+  %r896 = load double, ptr @batch_ts_.str.19.handle
+  %r897 = call double @js_string_concat_box(double %r896, double %r895)
+  %r898 = bitcast double %r897 to i64
+  %r899 = call i32 @js_gc_temp_root_push(i64 %r898)
+  %r900 = call i64 @js_array_alloc(i32 1)
+  %r901 = call i32 @js_gc_temp_root_push(i64 %r900)
+  %r902 = call i64 @js_gc_temp_root_get(i32 %r899)
+  %r903 = bitcast i64 %r902 to double
+  call void @js_array_push_f64_temp_rooted(i32 %r901, double %r903)
+  %r904 = call i64 @js_gc_temp_root_get(i32 %r901)
+  call void @js_console_log_spread(i64 %r904)
+  call void @js_gc_temp_root_truncate(i32 %r899)
+  %r905 = call i32 @js_promise_run_microtasks_event_loop()
+  %r906 = call i32 @js_timer_tick_if_refed()
+  %r907 = call i32 @js_callback_timer_tick()
+  %r908 = call i32 @js_interval_timer_tick()
+  %r909 = call i32 @js_promise_run_microtasks_event_loop()
+  %r910 = call i32 @js_timer_tick_if_refed()
+  %r911 = call i32 @js_callback_timer_tick()
+  %r912 = call i32 @js_interval_timer_tick()
+  %r913 = call i32 @js_promise_run_microtasks_event_loop()
+  %r914 = call i32 @js_timer_tick_if_refed()
+  %r915 = call i32 @js_callback_timer_tick()
+  %r916 = call i32 @js_interval_timer_tick()
+  %r917 = call i32 @js_promise_run_microtasks_event_loop()
+  %r918 = call i32 @js_timer_tick_if_refed()
+  %r919 = call i32 @js_callback_timer_tick()
+  %r920 = call i32 @js_interval_timer_tick()
+  call void @js_run_stdlib_pump()
+  br label %event_loop.header.148
+
+event_loop.header.148:
+  %r921 = call i32 @js_event_loop_host_driven()
+  %r922 = icmp ne i32 %r921, 0
+  br i1 %r922, label %event_loop.host_return.150, label %event_loop.check_pending.149
+
+event_loop.check_pending.149:
+  %r923 = call i32 @js_timer_has_pending()
+  %r924 = call i32 @js_callback_timer_has_pending()
+  %r925 = call i32 @js_interval_timer_has_pending()
+  %r926 = call i32 @js_stdlib_has_active_handles()
+  %r927 = call i32 @js_microtasks_pending()
+  %r928 = or i32 %r923, %r924
+  %r929 = or i32 %r925, %r926
+  %r930 = or i32 %r928, %r929
+  %r931 = or i32 %r930, 0
+  %r932 = or i32 %r931, %r927
+  %r933 = icmp ne i32 %r932, 0
+  br i1 %r933, label %event_loop.body.151, label %event_loop.exit.152
+
+event_loop.host_return.150:
+  call void @js_typed_feedback_maybe_dump_trace()
+  %shadow_pop_l_0 = load i64, ptr %r1
+  call void @js_shadow_frame_pop(i64 %shadow_pop_l_0)
+  ret i32 0
+
+event_loop.body.151:
+  %r934 = call i32 @js_promise_run_microtasks_event_loop()
+  %r935 = call i32 @js_timer_tick()
+  %r936 = call i32 @js_callback_timer_tick()
+  %r937 = call i32 @js_interval_timer_tick()
+  call void @js_run_stdlib_pump()
+  call void @js_wait_for_event()
+  br label %event_loop.header.148
+
+event_loop.exit.152:
+  call void @js_process_emit_before_exit(double 0x0)
+  %r938 = call i32 @js_promise_run_microtasks_event_loop()
+  %r939 = call i32 @js_timer_tick_if_refed()
+  %r940 = call i32 @js_callback_timer_tick()
+  %r941 = call i32 @js_interval_timer_tick()
+  call void @js_process_run_finalization_exit()
+  call void @js_trace_events_flush_output()
+  call void @js_promise_report_unhandled_rejections()
+  call void @js_gc_release_current_thread_collection_side_allocations()
+  %r942 = call i32 @js_process_pending_exit_code()
+  call void @js_typed_feedback_maybe_dump_trace()
+  %shadow_pop_l_1 = load i64, ptr %r1
+  call void @js_shadow_frame_pop(i64 %shadow_pop_l_1)
+  ret i32 %r942
+}
+
+define void @__perry_init_strings_batch_ts_chunk0() {
+entry.0:
+  %r1 = call i64 @js_string_from_bytes(ptr @batch_ts_.str.0.bytes, i32 3)
+  %r2 = call double @js_nanbox_string(i64 %r1)
+  store double %r2, ptr @batch_ts_.str.0.handle
+  %r3 = ptrtoint ptr @batch_ts_.str.0.handle to i64
+  call void @js_gc_register_global_root(i64 %r3)
+  %r4 = call i64 @js_string_from_bytes(ptr @batch_ts_.str.1.bytes, i32 5)
+  %r5 = call double @js_nanbox_string(i64 %r4)
+  store double %r5, ptr @batch_ts_.str.1.handle
+  %r6 = ptrtoint ptr @batch_ts_.str.1.handle to i64
+  call void @js_gc_register_global_root(i64 %r6)
+  %r7 = call i64 @js_string_from_bytes(ptr @batch_ts_.str.2.bytes, i32 6)
+  %r8 = call double @js_nanbox_string(i64 %r7)
+  store double %r8, ptr @batch_ts_.str.2.handle
+  %r9 = ptrtoint ptr @batch_ts_.str.2.handle to i64
+  call void @js_gc_register_global_root(i64 %r9)
+  %r10 = call i64 @js_string_from_bytes(ptr @batch_ts_.str.3.bytes, i32 4)
+  %r11 = call double @js_nanbox_string(i64 %r10)
+  store double %r11, ptr @batch_ts_.str.3.handle
+  %r12 = ptrtoint ptr @batch_ts_.str.3.handle to i64
+  call void @js_gc_register_global_root(i64 %r12)
+  %r13 = call i64 @js_string_from_bytes(ptr @batch_ts_.str.4.bytes, i32 5)
+  %r14 = call double @js_nanbox_string(i64 %r13)
+  store double %r14, ptr @batch_ts_.str.4.handle
+  %r15 = ptrtoint ptr @batch_ts_.str.4.handle to i64
+  call void @js_gc_register_global_root(i64 %r15)
+  %r16 = call i64 @js_string_from_bytes(ptr @batch_ts_.str.5.bytes, i32 6)
+  %r17 = call double @js_nanbox_string(i64 %r16)
+  store double %r17, ptr @batch_ts_.str.5.handle
+  %r18 = ptrtoint ptr @batch_ts_.str.5.handle to i64
+  call void @js_gc_register_global_root(i64 %r18)
+  %r19 = call i64 @js_string_from_bytes(ptr @batch_ts_.str.6.bytes, i32 1)
+  %r20 = call double @js_nanbox_string(i64 %r19)
+  store double %r20, ptr @batch_ts_.str.6.handle
+  %r21 = ptrtoint ptr @batch_ts_.str.6.handle to i64
+  call void @js_gc_register_global_root(i64 %r21)
+  %r22 = call i64 @js_string_from_bytes(ptr @batch_ts_.str.7.bytes, i32 2)
+  %r23 = call double @js_nanbox_string(i64 %r22)
+  store double %r23, ptr @batch_ts_.str.7.handle
+  %r24 = ptrtoint ptr @batch_ts_.str.7.handle to i64
+  call void @js_gc_register_global_root(i64 %r24)
+  %r25 = call i64 @js_string_from_bytes(ptr @batch_ts_.str.8.bytes, i32 7)
+  %r26 = call double @js_nanbox_string(i64 %r25)
+  store double %r26, ptr @batch_ts_.str.8.handle
+  %r27 = ptrtoint ptr @batch_ts_.str.8.handle to i64
+  call void @js_gc_register_global_root(i64 %r27)
+  %r28 = call i64 @js_string_from_bytes(ptr @batch_ts_.str.9.bytes, i32 4)
+  %r29 = call double @js_nanbox_string(i64 %r28)
+  store double %r29, ptr @batch_ts_.str.9.handle
+  %r30 = ptrtoint ptr @batch_ts_.str.9.handle to i64
+  call void @js_gc_register_global_root(i64 %r30)
+  %r31 = call i64 @js_string_from_bytes(ptr @batch_ts_.str.10.bytes, i32 3)
+  %r32 = call double @js_nanbox_string(i64 %r31)
+  store double %r32, ptr @batch_ts_.str.10.handle
+  %r33 = ptrtoint ptr @batch_ts_.str.10.handle to i64
+  call void @js_gc_register_global_root(i64 %r33)
+  %r34 = call i64 @js_string_from_bytes(ptr @batch_ts_.str.11.bytes, i32 5)
+  %r35 = call double @js_nanbox_string(i64 %r34)
+  store double %r35, ptr @batch_ts_.str.11.handle
+  %r36 = ptrtoint ptr @batch_ts_.str.11.handle to i64
+  call void @js_gc_register_global_root(i64 %r36)
+  %r37 = call i64 @js_string_from_bytes(ptr @batch_ts_.str.12.bytes, i32 3)
+  %r38 = call double @js_nanbox_string(i64 %r37)
+  store double %r38, ptr @batch_ts_.str.12.handle
+  %r39 = ptrtoint ptr @batch_ts_.str.12.handle to i64
+  call void @js_gc_register_global_root(i64 %r39)
+  %r40 = call i64 @js_string_from_bytes(ptr @batch_ts_.str.13.bytes, i32 5)
+  %r41 = call double @js_nanbox_string(i64 %r40)
+  store double %r41, ptr @batch_ts_.str.13.handle
+  %r42 = ptrtoint ptr @batch_ts_.str.13.handle to i64
+  call void @js_gc_register_global_root(i64 %r42)
+  %r43 = call i64 @js_string_from_bytes(ptr @batch_ts_.str.14.bytes, i32 3)
+  %r44 = call double @js_nanbox_string(i64 %r43)
+  store double %r44, ptr @batch_ts_.str.14.handle
+  %r45 = ptrtoint ptr @batch_ts_.str.14.handle to i64
+  call void @js_gc_register_global_root(i64 %r45)
+  %r46 = call i64 @js_string_from_bytes(ptr @batch_ts_.str.15.bytes, i32 5)
+  %r47 = call double @js_nanbox_string(i64 %r46)
+  store double %r47, ptr @batch_ts_.str.15.handle
+  %r48 = ptrtoint ptr @batch_ts_.str.15.handle to i64
+  call void @js_gc_register_global_root(i64 %r48)
+  %r49 = call i64 @js_string_from_bytes(ptr @batch_ts_.str.16.bytes, i32 4)
+  %r50 = call double @js_nanbox_string(i64 %r49)
+  store double %r50, ptr @batch_ts_.str.16.handle
+  %r51 = ptrtoint ptr @batch_ts_.str.16.handle to i64
+  call void @js_gc_register_global_root(i64 %r51)
+  %r52 = call i64 @js_string_from_bytes(ptr @batch_ts_.str.17.bytes, i32 5)
+  %r53 = call double @js_nanbox_string(i64 %r52)
+  store double %r53, ptr @batch_ts_.str.17.handle
+  %r54 = ptrtoint ptr @batch_ts_.str.17.handle to i64
+  call void @js_gc_register_global_root(i64 %r54)
+  %r55 = call i64 @js_string_from_bytes(ptr @batch_ts_.str.18.bytes, i32 5)
+  %r56 = call double @js_nanbox_string(i64 %r55)
+  store double %r56, ptr @batch_ts_.str.18.handle
+  %r57 = ptrtoint ptr @batch_ts_.str.18.handle to i64
+  call void @js_gc_register_global_root(i64 %r57)
+  %r58 = call i64 @js_string_from_bytes(ptr @batch_ts_.str.19.bytes, i32 10)
+  %r59 = call double @js_nanbox_string(i64 %r58)
+  store double %r59, ptr @batch_ts_.str.19.handle
+  %r60 = ptrtoint ptr @batch_ts_.str.19.handle to i64
+  call void @js_gc_register_global_root(i64 %r60)
+  call void @js_register_function_name(ptr @__perry_wrap_perry_fn_batch_ts__buildRows, ptr @.str.0, i32 9)
+  call void @js_register_function_name(ptr @__perry_wrap_perry_fn_batch_ts__shape, ptr @.str.1, i32 5)
+  call void @js_register_function_name(ptr @__perry_wrap_perry_fn_batch_ts__ranked, ptr @.str.2, i32 6)
+  call void @js_register_function_name(ptr @__perry_wrap_perry_fn_batch_ts__summarize, ptr @.str.3, i32 9)
+  call void @js_register_function_name(ptr @__perry_wrap_perry_fn_batch_ts__totalsRow, ptr @.str.4, i32 9)
+  call void @js_register_function_source(ptr @__perry_wrap_perry_fn_batch_ts__buildRows, ptr @.str.5, i32 213)
+  call void @js_register_function_source(ptr @__perry_wrap_perry_fn_batch_ts__shape, ptr @.str.6, i32 193)
+  call void @js_register_function_source(ptr @__perry_wrap_perry_fn_batch_ts__ranked, ptr @.str.7, i32 271)
+  call void @js_register_function_source(ptr @__perry_wrap_perry_fn_batch_ts__summarize, ptr @.str.8, i32 639)
+  call void @js_register_function_source(ptr @__perry_wrap_perry_fn_batch_ts__totalsRow, ptr @.str.9, i32 263)
+  call void @js_register_function_source(ptr @perry_closure_batch_ts__7, ptr @.str.10, i32 129)
+  call void @js_register_function_source(ptr @perry_closure_batch_ts__9, ptr @.str.11, i32 159)
+  call void @js_register_function_source(ptr @perry_closure_batch_ts__11, ptr @.str.12, i32 291)
+  %r61 = call i64 @js_build_class_keys_array(i32 1, i32 4, ptr @perry_class_keys_packed_batch_ts__0, i32 23)
+  store i64 %r61, ptr @perry_class_keys_batch_ts__Row
+  call void @js_write_barrier_root_heap_word(i64 %r61)
+  %r62 = ptrtoint ptr @perry_class_keys_batch_ts__Row to i64
+  call void @js_gc_register_global_root(i64 %r62)
+  %r63 = call i64 @js_build_class_keys_array(i32 2, i32 3, ptr @perry_class_keys_packed_batch_ts__1, i32 14)
+  store i64 %r63, ptr @perry_class_keys_batch_ts____AnonShape_e75d7e32e87dc826
+  call void @js_write_barrier_root_heap_word(i64 %r63)
+  %r64 = ptrtoint ptr @perry_class_keys_batch_ts____AnonShape_e75d7e32e87dc826 to i64
+  call void @js_gc_register_global_root(i64 %r64)
+  %r65 = call i64 @js_build_class_keys_array(i32 3, i32 4, ptr @perry_class_keys_packed_batch_ts__2, i32 24)
+  store i64 %r65, ptr @perry_class_keys_batch_ts____AnonShape_c33c4204c28b9430
+  call void @js_write_barrier_root_heap_word(i64 %r65)
+  %r66 = ptrtoint ptr @perry_class_keys_batch_ts____AnonShape_c33c4204c28b9430 to i64
+  call void @js_gc_register_global_root(i64 %r66)
+  %r67 = ptrtoint ptr @perry_method_batch_ts__Row__rescore to i64
+  %r68 = ptrtoint ptr @batch_ts_.str.8.bytes to i64
+  call void @js_register_class_method(i64 1, i64 %r68, i64 7, i64 %r67, i64 1, i64 0, i64 0)
+  call void @js_register_class_method_bind_length(i64 1, i64 %r68, i64 7, i64 1)
+  %r69 = ptrtoint ptr @batch_ts__Row_constructor to i64
+  call void @js_register_class_constructor(i64 1, i64 %r69, i64 3, i64 0)
+  %r70 = ptrtoint ptr @batch_ts____AnonShape_e75d7e32e87dc826_constructor to i64
+  call void @js_register_class_constructor(i64 2, i64 %r70, i64 3, i64 0)
+  %r71 = ptrtoint ptr @batch_ts____AnonShape_c33c4204c28b9430_constructor to i64
+  call void @js_register_class_constructor(i64 3, i64 %r71, i64 4, i64 0)
+  call void @js_register_class_id(i32 1)
+  call void @js_register_class_id(i32 2)
+  call void @js_register_class_id(i32 3)
+  call void @js_register_anon_shape_class_id(i32 2)
+  call void @js_register_anon_shape_class_id(i32 3)
+  call void @js_register_class_name(i32 1, ptr @.str.13, i32 3)
+  call void @js_register_closure_arity(ptr @perry_closure_batch_ts__7, i32 1)
+  call void @js_register_closure_arity(ptr @perry_closure_batch_ts__9, i32 2)
+  call void @js_register_closure_arity(ptr @perry_closure_batch_ts__11, i32 2)
+  call void @js_register_closure_length(ptr @perry_closure_batch_ts__7, i32 1)
+  call void @js_register_closure_length(ptr @perry_closure_batch_ts__9, i32 2)
+  call void @js_register_closure_length(ptr @perry_closure_batch_ts__11, i32 2)
+  call void @js_register_closure_arrow_function(ptr @perry_closure_batch_ts__7)
+  call void @js_register_closure_arrow_function(ptr @perry_closure_batch_ts__9)
+  call void @js_register_closure_arrow_function(ptr @perry_closure_batch_ts__11)
+  call void @js_register_closure_arity(ptr @__perry_wrap_perry_fn_batch_ts__buildRows, i32 2)
+  call void @js_register_closure_arity(ptr @__perry_wrap_perry_fn_batch_ts__ranked, i32 1)
+  call void @js_register_closure_arity(ptr @__perry_wrap_perry_fn_batch_ts__shape, i32 1)
+  call void @js_register_closure_arity(ptr @__perry_wrap_perry_fn_batch_ts__summarize, i32 1)
+  call void @js_register_closure_arity(ptr @__perry_wrap_perry_fn_batch_ts__totalsRow, i32 1)
+  call void @js_register_closure_length(ptr @__perry_wrap_perry_fn_batch_ts__buildRows, i32 2)
+  call void @js_register_closure_length(ptr @__perry_wrap_perry_fn_batch_ts__ranked, i32 1)
+  call void @js_register_closure_length(ptr @__perry_wrap_perry_fn_batch_ts__shape, i32 1)
+  call void @js_register_closure_length(ptr @__perry_wrap_perry_fn_batch_ts__summarize, i32 1)
+  call void @js_register_closure_length(ptr @__perry_wrap_perry_fn_batch_ts__totalsRow, i32 1)
+  call void @js_register_closure_strict_function(ptr @__perry_wrap_perry_fn_batch_ts__buildRows)
+  call void @js_register_closure_strict_function(ptr @__perry_wrap_perry_fn_batch_ts__ranked)
+  call void @js_register_closure_strict_function(ptr @__perry_wrap_perry_fn_batch_ts__shape)
+  call void @js_register_closure_strict_function(ptr @__perry_wrap_perry_fn_batch_ts__summarize)
+  call void @js_register_closure_strict_function(ptr @__perry_wrap_perry_fn_batch_ts__totalsRow)
+  call void @js_register_closure_strict_function(ptr @perry_closure_batch_ts__11)
+  call void @js_register_closure_strict_function(ptr @perry_closure_batch_ts__7)
+  call void @js_register_closure_strict_function(ptr @perry_closure_batch_ts__9)
+  ret void
+}
+
+define void @__perry_init_strings_batch_ts() {
+entry.0:
+  call void @__perry_init_strings_batch_ts_chunk0()
+  ret void
+}
+
+
+attributes #0 = { returns_twice }
+attributes #1 = { noinline }
+
+attributes #2 = { nounwind willreturn readnone }
+
+attributes #3 = { nounwind willreturn readonly }
+
+attributes #4 = { nounwind willreturn }
+
+!0 = !{}
diff --git a/experiments/llvm-inprocess-spike/mk_llvm_sys_shim.sh b/experiments/llvm-inprocess-spike/mk_llvm_sys_shim.sh
new file mode 100755
index 0000000000..12dc13f951
--- /dev/null
+++ b/experiments/llvm-inprocess-spike/mk_llvm_sys_shim.sh
@@ -0,0 +1,61 @@
+#!/bin/bash
+# Build an LLVM_SYS_221_PREFIX shim for a downloaded upstream LLVM release.
+#
+#   ./mk_llvm_sys_shim.sh ~/opt/LLVM-22.1.8-Linux-X64 ~/opt/llvm22-shim
+#   export LLVM_SYS_221_PREFIX=~/opt/llvm22-shim
+#
+# Why this exists: on a distro with no LLVM 22 package (Fedora 43 stops at
+# llvm20-devel; its system libs are 21), the upstream release tarball is the
+# only route. But those tarballs are built on Ubuntu, and `llvm-config
+# --system-libs` reports the BUILD HOST's static system libraries by absolute
+# path -- e.g. /usr/lib/x86_64-linux-gnu/libzstd.a, which exists on no other
+# distro. llvm-sys's build script panics on any --system-libs entry that is
+# neither `-lfoo` nor an existing file:
+#
+#   Unable to parse result of llvm-config --system-libs: /usr/.../libzstd.a
+#
+# so the build dies before compiling anything. This wrapper rewrites exactly
+# those dangling absolute paths to plain `-lname` flags, letting the linker
+# resolve them against the host's own shared libraries. Entries that DO exist
+# are left alone -- llvm-sys handles a real absolute path fine, and silently
+# converting a deliberate static link into a dynamic one would be a change we
+# were not asked to make.
+#
+# Everything else passes through untouched, including every path query: the
+# real llvm-config still answers those relative to its own prefix, so the shim
+# needs no lib/ or include/ of its own.
+set -euo pipefail
+
+REAL=${1:?usage: mk_llvm_sys_shim.sh  }
+SHIM=${2:?usage: mk_llvm_sys_shim.sh  }
+REAL=$(cd "$REAL" && pwd)
+
+[ -x "$REAL/bin/llvm-config" ] || { echo "no llvm-config under $REAL/bin" >&2; exit 1; }
+
+mkdir -p "$SHIM/bin"
+cat > "$SHIM/bin/llvm-config" < $REAL/bin/llvm-config"
+echo "  --version:     $("$SHIM/bin/llvm-config" --version)"
+echo "  --libdir:      $("$SHIM/bin/llvm-config" --libdir)"
+echo "  --system-libs: $("$SHIM/bin/llvm-config" --system-libs --link-static)"
+echo
+echo "export LLVM_SYS_221_PREFIX=$SHIM"
diff --git a/experiments/llvm-inprocess-spike/spike.ts b/experiments/llvm-inprocess-spike/spike.ts
new file mode 100644
index 0000000000..a9298842f5
--- /dev/null
+++ b/experiments/llvm-inprocess-spike/spike.ts
@@ -0,0 +1,36 @@
+// Phase 0 differential module: small but touches strings, arrays, closures,
+// classes, Map iteration, and async — the value shapes Perry's IR leans on.
+function fib(n: number): number {
+  return n < 2 ? n : fib(n - 1) + fib(n - 2);
+}
+
+const arr = [3, 1, 4, 1, 5, 9, 2, 6];
+arr.sort((a, b) => a - b);
+console.log("fib(20) =", fib(20));
+console.log("sorted:", arr.join(","));
+
+const m = new Map();
+m.set("alpha", 1);
+m.set("beta", 2);
+for (const [k, v] of m) console.log(k, "->", v);
+
+class Point {
+  x: number;
+  y: number;
+  constructor(x: number, y: number) {
+    this.x = x;
+    this.y = y;
+  }
+  norm(): number {
+    return Math.sqrt(this.x * this.x + this.y * this.y);
+  }
+}
+console.log("norm:", new Point(3, 4).norm());
+
+const greet = (name: string) => `hello, ${name}!`;
+console.log(greet("perry"));
+
+(async () => {
+  const v = await Promise.resolve(42);
+  console.log("async:", v);
+})();
diff --git a/experiments/llvm-inprocess-spike/spike_text.ll b/experiments/llvm-inprocess-spike/spike_text.ll
new file mode 100644
index 0000000000..759ce25fcf
--- /dev/null
+++ b/experiments/llvm-inprocess-spike/spike_text.ll
@@ -0,0 +1,5625 @@
+; Generated by perry-codegen
+target triple = "arm64-apple-macosx15.0.0"
+
+@spike_ts_.str.0.bytes = private unnamed_addr constant [8 x i8] c"hello, \00"
+@spike_ts_.str.1.bytes = private unnamed_addr constant [2 x i8] c"!\00"
+@spike_ts_.str.2.bytes = private unnamed_addr constant [7 x i8] c"async:\00"
+@spike_ts_.str.3.bytes = private unnamed_addr constant [2 x i8] c"x\00"
+@spike_ts_.str.4.bytes = private unnamed_addr constant [2 x i8] c"y\00"
+@spike_ts_.str.5.bytes = private unnamed_addr constant [10 x i8] c"fib(20) =\00"
+@spike_ts_.str.6.bytes = private unnamed_addr constant [8 x i8] c"sorted:\00"
+@spike_ts_.str.7.bytes = private unnamed_addr constant [2 x i8] c",\00"
+@spike_ts_.str.8.bytes = private unnamed_addr constant [6 x i8] c"alpha\00"
+@spike_ts_.str.9.bytes = private unnamed_addr constant [5 x i8] c"beta\00"
+@spike_ts_.str.10.bytes = private unnamed_addr constant [3 x i8] c"->\00"
+@spike_ts_.str.11.bytes = private unnamed_addr constant [6 x i8] c"norm:\00"
+@spike_ts_.str.12.bytes = private unnamed_addr constant [5 x i8] c"norm\00"
+@spike_ts_.str.13.bytes = private unnamed_addr constant [6 x i8] c"perry\00"
+@perry_class_keys_packed_spike_ts__0 = private unnamed_addr constant [5 x i8] c"x\00y\00\00"
+@.str.0 = private unnamed_addr constant [4 x i8] c"fib\00"
+@.str.1 = private unnamed_addr constant [6 x i8] c"greet\00"
+@.str.2 = private unnamed_addr constant [82 x i8] c"function fib(n: number): number {\0A  return n < 2 ? n : fib(n - 1) + fib(n - 2);\0A}\00"
+@.str.3 = private unnamed_addr constant [16 x i8] c"(a, b) => a - b\00"
+@.str.4 = private unnamed_addr constant [36 x i8] c"(name: string) => `hello, ${name}!`\00"
+@.str.5 = private unnamed_addr constant [83 x i8] c"async () => {\0A  const v = await Promise.resolve(42);\0A  console.log(\22async:\22, v);\0A}\00"
+@.str.6 = private unnamed_addr constant [6 x i8] c"Point\00"
+
+@perry_null_guard_zero = internal global i32 0
+@PERRY_CLASS_FIELD_INLINE_GUARD_DISABLED = external global i8
+@PERRY_ARRAY_INDEX_FAST_PATH_INVALIDATED = external global i8
+@PERRY_INCREMENTAL_MARK_BARRIER_ACTIVE_COUNT = external global i32
+@PERRY_TA_KIND_CACHE = external global [64 x i64]
+@PERRY_TA_VIEW_GUARD = external global i64
+@perry_class_keys_spike_ts__Point = internal global i64 0
+@spike_ts_.str.0.handle = internal global double 0.0
+@spike_ts_.str.1.handle = internal global double 0.0
+@spike_ts_.str.2.handle = internal global double 0.0
+@spike_ts_.str.3.handle = internal global double 0.0
+@spike_ts_.str.4.handle = internal global double 0.0
+@spike_ts_.str.5.handle = internal global double 0.0
+@spike_ts_.str.6.handle = internal global double 0.0
+@spike_ts_.str.7.handle = internal global double 0.0
+@spike_ts_.str.8.handle = internal global double 0.0
+@spike_ts_.str.9.handle = internal global double 0.0
+@spike_ts_.str.10.handle = internal global double 0.0
+@spike_ts_.str.11.handle = internal global double 0.0
+@spike_ts_.str.12.dispatch = private unnamed_addr constant { i32, i32, i64, ptr } { i32 4, i32 0, i64 4315873112953976271, ptr @spike_ts_.str.12.bytes }
+@spike_ts_.str.12.handle = internal global double 0.0
+@spike_ts_.str.13.handle = internal global double 0.0
+@perry_typed_shape_raw_f64_mask_spike_ts__Point = private unnamed_addr constant [1 x i64] [i64 3]
+
+declare void @js_gc_init()
+declare void @js_typed_feedback_maybe_dump_trace()
+declare void @js_stdlib_init_dispatch()
+declare void @perry_app_group_init(ptr, i32)
+declare void @perry_macos_bundle_chdir()
+declare i32 @perry_i18n_locale_index_for(i64, i32)
+declare void @perry_i18n_init(ptr, ptr, i32, i32)
+declare void @perry_i18n_set_currencies(ptr, i32)
+declare i32 @perry_i18n_plural_category(i32, double)
+declare void @js_register_function_name(ptr, ptr, i32)
+declare void @js_register_function_source(ptr, ptr, i32)
+declare void @js_console_log_dynamic(double)
+declare void @js_console_log_number(double)
+declare void @js_console_error_dynamic(double)
+declare void @js_console_error_number(double)
+declare void @js_console_warn_dynamic(double)
+declare void @js_console_warn_number(double)
+declare void @js_console_dir_with_options(double, double)
+declare double @js_console_method_by_value(double)
+declare double @js_nanbox_string(i64)
+declare double @js_nanbox_pointer(i64) #2
+declare i64 @js_nanbox_get_pointer(double) #2
+declare double @js_native_handle_new_owned(i64, i64, i32, i32, ptr, ptr, i64)
+declare double @js_native_handle_new_borrowed(i64, i64, i32, i32, ptr, i64)
+declare i64 @js_native_handle_unwrap(double, i64, i32, i32, i32)
+declare i64 @js_string_from_bytes(ptr, i32)
+declare i64 @js_string_from_wtf8_bytes(ptr, i32)
+declare i32 @js_is_truthy(double) #3
+declare double @js_native_abi_check_f64(double)
+declare i32 @js_typed_f64_arg_guard(double) #2
+declare double @js_typed_f64_arg_to_raw(double)
+declare i32 @js_typed_i32_arg_guard(double) #2
+declare i32 @js_typed_i32_arg_to_raw(double) #2
+declare i32 @js_typed_i1_arg_guard(double) #2
+declare i32 @js_typed_i1_arg_to_raw(double) #2
+declare i32 @js_typed_string_arg_guard(double) #2
+declare i64 @js_typed_string_arg_to_raw(double)
+declare float @js_native_abi_check_f32(double)
+declare i32 @js_native_abi_check_i32(double)
+declare i64 @js_native_abi_check_i64(double)
+declare i32 @js_native_abi_check_u32(double)
+declare i64 @js_native_abi_check_u64(double)
+declare i64 @js_native_abi_check_usize(double)
+declare i64 @js_native_abi_check_string_ptr(double)
+declare i64 @js_native_abi_check_ptr(double)
+declare ptr @js_native_abi_check_buffer_data_ptr(double)
+declare i64 @js_native_abi_check_buffer_byte_len(double)
+declare i64 @js_native_abi_check_promise(double)
+declare i64 @js_native_abi_check_pod_object(double)
+declare double @js_date_now()
+declare void @js_gc_register_global_root(i64)
+declare i64 @js_string_concat(i64, i64)
+declare double @js_string_concat_box(double, double)
+declare i64 @js_jsvalue_to_string(double)
+declare i64 @js_jsvalue_to_string_method(double)
+declare i64 @js_jsvalue_to_string_coerce(double)
+declare i64 @js_string_concat_value(i64, double)
+declare i64 @js_value_concat_string(double, i64)
+declare i64 @js_string_concat_chain(i64, i32)
+declare i64 @js_string_append(i64, i64)
+declare i32 @js_string_index_of(i64, i64)
+declare i32 @js_string_index_of_from(i64, i64, i32)
+declare i32 @js_string_position_to_index(double)
+declare i64 @js_string_slice(i64, i32, i32)
+declare i64 @js_string_substring(i64, i32, i32)
+declare i64 @js_string_substr(i64, double, double)
+declare i64 @js_string_split(i64, i64)
+declare i64 @js_string_split_n(i64, i64, i32)
+declare double @js_string_split_part_value(i64, i64, i32)
+declare double @js_string_split_part_utf16_length(i64, i64, i32)
+declare double @js_string_to_upper_case_split_part_utf16_length(i64, i64, i32)
+declare i32 @js_string_to_upper_case_index_of(i64, i64)
+declare i64 @js_string_split_value(i64, double, double)
+declare double @js_math_trunc(double)
+declare double @js_math_round(double)
+declare double @js_math_sign(double)
+declare double @js_math_imul(double, double)
+declare double @js_math_pow(double, double)
+declare double @llvm.sqrt.f64(double)
+declare double @llvm.floor.f64(double)
+declare double @llvm.ceil.f64(double)
+declare double @llvm.fabs.f64(double)
+declare double @llvm.copysign.f64(double, double)
+declare void @llvm.assume(i1)
+declare i16 @llvm.bswap.i16(i16)
+declare i32 @llvm.bswap.i32(i32)
+declare i64 @llvm.bswap.i64(i64)
+declare i32 @llvm.aarch64.fjcvtzs(double)
+declare void @llvm.memset.p0.i64(ptr, i8, i64, i1)
+declare void @llvm.memmove.p0.p0.i64(ptr, ptr, i64, i1)
+declare i64 @js_json_stringify(double, i32)
+declare i64 @js_map_alloc(i32)
+declare i64 @js_text_encoder_encode_into_llvm(double, double)
+declare i64 @js_value_typeof(double)
+declare i32 @js_string_starts_with(i64, i64)
+declare i32 @js_string_ends_with(i64, i64)
+declare i64 @js_string_search_value_to_string(double, i32)
+declare i32 @js_string_starts_with_at(i64, i64, i32)
+declare i32 @js_string_ends_with_at(i64, i64, i32)
+declare i64 @js_closure_alloc(ptr, i32)
+declare i64 @js_closure_alloc_singleton(ptr)
+declare i64 @js_closure_alloc_with_captures_singleton(ptr, i32, ptr)
+declare void @js_closure_set_capture_bits(i64, i32, i64)
+declare i64 @js_closure_get_capture_bits(i64, i32)
+declare void @js_closure_set_capture_f64(i64, i32, double)
+declare double @js_closure_get_capture_f64(i64, i32)
+declare void @js_register_closure_rest(ptr, i32)
+declare void @js_register_closure_synthetic_arguments(ptr, i32)
+declare void @js_register_closure_rest_and_arguments(ptr, i32)
+declare void @js_register_closure_arity(ptr, i32)
+declare void @js_register_closure_length(ptr, i32)
+declare void @js_register_closure_arrow_function(ptr)
+declare void @js_register_closure_strict_function(ptr)
+declare void @js_register_closure_async_function(ptr)
+declare void @js_register_closure_generator_function(ptr)
+declare void @js_register_closure_async_generator_function(ptr)
+declare i64 @js_closure_unbox_callee_checked(double)
+declare i64 @js_closure_unbox_callee_checked_rebind(double, double)
+declare double @js_closure_call0(i64)
+declare double @js_closure_call1(i64, double)
+declare double @js_closure_call2(i64, double, double)
+declare double @js_closure_call3(i64, double, double, double)
+declare double @js_closure_call4(i64, double, double, double, double)
+declare double @js_closure_call5(i64, double, double, double, double, double)
+declare double @js_closure_call6(i64, double, double, double, double, double, double)
+declare double @js_closure_call7(i64, double, double, double, double, double, double, double)
+declare double @js_closure_call8(i64, double, double, double, double, double, double, double, double)
+declare double @js_closure_call9(i64, double, double, double, double, double, double, double, double, double)
+declare double @js_closure_call10(i64, double, double, double, double, double, double, double, double, double, double)
+declare double @js_closure_call11(i64, double, double, double, double, double, double, double, double, double, double, double)
+declare double @js_closure_call12(i64, double, double, double, double, double, double, double, double, double, double, double, double)
+declare double @js_closure_call13(i64, double, double, double, double, double, double, double, double, double, double, double, double, double)
+declare double @js_closure_call14(i64, double, double, double, double, double, double, double, double, double, double, double, double, double, double)
+declare double @js_closure_call15(i64, double, double, double, double, double, double, double, double, double, double, double, double, double, double, double)
+declare double @js_closure_call16(i64, double, double, double, double, double, double, double, double, double, double, double, double, double, double, double, double)
+declare i64 @js_array_map(i64, i64)
+declare void @js_array_map_discard(i64, i64)
+declare i64 @js_array_filter(i64, i64)
+declare i64 @js_array_concat(i64, i64)
+declare i64 @js_array_concat_new(i64, i64)
+declare i64 @js_error_new()
+declare i64 @js_error_new_with_message(i64)
+declare i64 @js_error_new_from_value(double)
+declare i64 @js_error_new_kind_from_value(i32, double)
+declare i64 @js_error_new_with_cause_from_value(double, double)
+declare i64 @js_error_new_kind_with_options_from_value(i32, double, double)
+declare double @js_assert_assertion_error_ctor(double)
+declare double @js_assert_assert_ctor(double)
+declare void @js_throw_type_error_property_access(i32, ptr, i64)
+declare void @js_throw_type_error_not_a_function(ptr, i64, ptr, i64)
+declare void @js_throw_error_with_code(ptr, i64, ptr, i64, i32)
+declare i64 @js_map_set(i64, double, double)
+declare i64 @js_map_set_string_number(i64, i64, double)
+declare i64 @js_map_set_string_key(i64, i64, double)
+declare i64 @js_map_set_string_i32(i64, i64, i32)
+declare i64 @js_map_set_string_u32(i64, i64, i32)
+declare i64 @js_map_set_string_f32(i64, i64, float)
+declare i64 @js_map_set_string_bool(i64, i64, i32)
+declare i64 @js_map_set_string_string(i64, i64, i64)
+declare i64 @js_map_set_number_key(i64, double, double)
+declare double @js_map_get(i64, double)
+declare double @js_map_get_string_key(i64, i64)
+declare double @js_map_get_number_key(i64, double)
+declare i32 @js_map_has(i64, double)
+declare i32 @js_map_has_string_key(i64, i64)
+declare i32 @js_map_has_number_key(i64, double)
+declare i32 @js_map_delete(i64, double)
+declare i32 @js_map_delete_string_key(i64, i64)
+declare i32 @js_map_delete_number_key(i64, double)
+declare i64 @js_object_keys(i64)
+declare i64 @js_object_keys_value(double)
+declare i64 @js_for_in_keys_value(double)
+declare double @js_is_finite(double)
+declare i32 @js_is_undefined_or_bare_nan(double)
+declare double @js_math_min_array(i64)
+declare double @js_math_max_array(i64)
+declare double @js_math_min2(double, double)
+declare double @js_math_max2(double, double)
+declare i64 @js_string_coerce(double)
+declare i64 @js_string_coerce_method_this(double, ptr, i64)
+declare i64 @js_array_slice(i64, i32, i32)
+declare i64 @js_array_slice_values(i64, double, double)
+declare double @js_array_shift_f64(i64)
+declare i64 @js_set_alloc(i32)
+declare i64 @js_set_from_array(i64)
+declare i64 @js_set_from_iterable(double)
+declare i64 @js_map_from_array(i64)
+declare i64 @js_map_from_iterable(double)
+declare double @js_object_has_property(double, double)
+declare double @js_in_operator(double, double)
+declare double @js_private_brand_check(double, i32, ptr, i32)
+declare double @js_private_guard(double, i32, ptr, i32, i32, i32)
+declare double @js_fs_to_unix_timestamp(double)
+declare i32 @js_fs_write_file_sync(double, double)
+declare i32 @js_fs_write_file_sync_options(double, double, double)
+declare i32 @js_fs_append_file_sync(double, double)
+declare i32 @js_fs_append_file_sync_options(double, double, double)
+declare i32 @js_fs_exists_sync(double)
+declare i64 @js_fs_read_file_sync(double)
+declare double @js_fs_read_file_dispatch(double, double)
+declare double @js_fs_open_as_blob(double, double)
+declare double @js_fs_promises_read_file(double, double)
+declare double @js_fs_promises_write_file(double, double, double)
+declare double @js_fs_promises_append_file(double, double, double)
+declare double @js_fs_promises_mkdir(double, double)
+declare double @js_fs_promises_rmdir(double, double)
+declare i32 @js_fs_mkdir_sync(double)
+declare i32 @js_fs_mkdir_sync_options(double, double)
+declare i32 @js_fs_unlink_sync(double)
+declare double @js_fs_readdir_sync(double, double)
+declare double @js_fs_stat_sync(double)
+declare double @js_fs_stat_sync_options(double, double)
+declare double @js_fs_lstat_sync(double)
+declare double @js_fs_lstat_sync_options(double, double)
+declare i32 @js_fs_rename_sync(double, double)
+declare i32 @js_fs_copy_file_sync(double, double)
+declare i32 @js_fs_copy_file_sync_flags(double, double, double)
+declare i32 @js_fs_cp_sync(double, double)
+declare i32 @js_fs_cp_sync_options(double, double, double)
+declare i32 @js_fs_chmod_sync(double, double)
+declare i32 @js_fs_chown_sync(double, double, double)
+declare i32 @js_fs_lchown_sync(double, double, double)
+declare i32 @js_fs_lchmod_sync(double, double)
+declare i32 @js_fs_truncate_sync(double, double)
+declare i32 @js_fs_ftruncate_sync(double, double)
+declare i32 @js_fs_fsync_sync(double)
+declare i32 @js_fs_fdatasync_sync(double)
+declare i32 @js_fs_fchmod_sync(double, double)
+declare i32 @js_fs_fchown_sync(double, double, double)
+declare double @js_fs_fstat_sync(double)
+declare double @js_fs_fstat_sync_options(double, double)
+declare i32 @js_fs_utimes_sync(double, double, double)
+declare i32 @js_fs_lutimes_sync(double, double, double)
+declare i32 @js_fs_futimes_sync(double, double, double)
+declare double @js_fs_readv_sync(double, double, double)
+declare double @js_fs_writev_sync(double, double, double)
+declare double @js_fs_statfs_sync(double)
+declare double @js_fs_statfs_sync_options(double, double)
+declare double @js_fs_opendir_sync(double)
+declare double @js_fs_glob_sync(double)
+declare double @js_fs_glob_sync_options(double, double)
+declare i32 @js_fs_link_sync(double, double)
+declare i32 @js_fs_symlink_sync(double, double)
+declare double @js_fs_symlink_callback(double, double, double, double)
+declare i64 @js_fs_readlink_sync(double)
+declare i64 @js_fs_readlink_sync_options(double, double)
+declare double @js_fs_readlink_dispatch(double, double)
+declare double @js_fs_open_sync(double, double)
+declare i32 @js_fs_close_sync(double)
+declare double @js_fs_read_sync(double, double, double, double, double)
+declare double @js_fs_read_sync_options(double, double, double)
+declare double @js_fs_write_sync(double, double)
+declare double @js_fs_write_string_sync_options(double, double, double)
+declare double @js_fs_write_buffer_sync(double, double, double, double, double)
+declare double @js_fs_write_sync_options_dispatch(double, double, double)
+declare i32 @js_fs_access_sync(double)
+declare i32 @js_fs_access_sync_mode(double, double)
+declare double @js_fs_access_sync_throw(double)
+declare double @js_fs_access_sync_throw_mode(double, double)
+declare i64 @js_fs_realpath_sync(double)
+declare double @js_fs_realpath_dispatch(double, double)
+declare i64 @js_fs_mkdtemp_sync(double)
+declare i64 @js_fs_mkdtemp_sync_options(double, double)
+declare double @js_fs_mkdtemp_dispatch(double, double)
+declare double @js_fs_mkdtemp_disposable_sync(double, double)
+declare i32 @js_fs_rmdir_sync(double)
+declare i32 @js_fs_rmdir_sync_options(double, double)
+declare i32 @js_fs_rm_recursive(double)
+declare i32 @js_fs_rm_recursive_options(double, double)
+declare double @js_fs_create_write_stream(double, double)
+declare double @js_fs_create_read_stream(double, double)
+declare double @js_fs_utf8_stream_new(double)
+declare double @js_fs_utf8_stream_call_without_new(double)
+declare double @js_fs_utf8_stream_write(double, double)
+declare double @js_fs_utf8_stream_flush(double, double)
+declare double @js_fs_utf8_stream_flush_sync(double)
+declare double @js_fs_utf8_stream_end(double, double)
+declare double @js_fs_utf8_stream_destroy(double)
+declare double @js_fs_utf8_stream_reopen(double, double)
+declare double @js_fs_utf8_stream_on(double, double, double)
+declare double @js_fs_utf8_stream_once(double, double, double)
+declare double @js_fs_utf8_stream_off(double, double, double)
+declare double @js_fs_utf8_stream_remove_all(double, double)
+declare double @js_fs_utf8_stream_listener_count(double, double)
+declare double @js_fs_utf8_stream_emit(double, double, double)
+declare double @js_fs_read_file_callback(double, double, double)
+declare double @js_fs_stats_is_file(double)
+declare double @js_fs_stats_is_directory(double)
+declare i64 @js_fs_read_file_binary(double)
+declare double @js_number_coerce(double)
+declare double @js_math_to_number(double)
+declare i64 @js_set_add(i64, double)
+declare i64 @js_set_add_string(i64, i64)
+declare i64 @js_set_add_number(i64, double)
+declare i64 @js_set_add_i32(i64, i32)
+declare i64 @js_set_add_u32(i64, i32)
+declare i64 @js_set_add_f32(i64, float)
+declare i64 @js_set_add_bool(i64, i32)
+declare i32 @js_set_has(i64, double)
+declare i32 @js_set_has_string(i64, i64)
+declare i32 @js_set_has_number(i64, double)
+declare i32 @js_set_has_i32(i64, i32)
+declare i32 @js_set_has_u32(i64, i32)
+declare i32 @js_set_has_f32(i64, float)
+declare i32 @js_set_has_bool(i64, i32)
+declare i32 @js_set_delete(i64, double)
+declare i32 @js_set_delete_string(i64, i64)
+declare i32 @js_set_delete_number(i64, double)
+declare i32 @js_set_delete_i32(i64, i32)
+declare i32 @js_set_delete_u32(i64, i32)
+declare i32 @js_set_delete_f32(i64, float)
+declare i32 @js_set_delete_bool(i64, i32)
+declare i32 @js_set_size(i64)
+declare i64 @js_set_union(i64, double)
+declare i64 @js_set_intersection(i64, double)
+declare i64 @js_set_difference(i64, double)
+declare i64 @js_set_symmetric_difference(i64, double)
+declare i32 @js_set_is_subset_of(i64, double)
+declare i32 @js_set_is_superset_of(i64, double)
+declare i32 @js_set_is_disjoint_from(i64, double)
+declare i64 @js_string_to_lower_case(i64)
+declare i64 @js_string_to_upper_case(i64)
+declare i64 @js_string_to_locale_lower_case(i64, double)
+declare i64 @js_string_to_locale_upper_case(i64, double)
+declare void @js_string_validate_collator_args(double, double)
+declare i64 @js_string_trim(i64)
+declare i64 @js_string_trim_start(i64)
+declare i64 @js_string_trim_end(i64)
+declare i64 @js_string_big(i64)
+declare i64 @js_string_blink(i64)
+declare i64 @js_string_bold(i64)
+declare i64 @js_string_fixed(i64)
+declare i64 @js_string_italics(i64)
+declare i64 @js_string_small(i64)
+declare i64 @js_string_strike(i64)
+declare i64 @js_string_sub(i64)
+declare i64 @js_string_sup(i64)
+declare i64 @js_string_anchor(i64, i64)
+declare i64 @js_string_link(i64, i64)
+declare i64 @js_string_fontcolor(i64, i64)
+declare i64 @js_string_fontsize(i64, i64)
+declare i64 @js_string_char_at(i64, i32)
+declare double @js_string_index_get(i64, double)
+declare double @js_string_index_get_boxed(double, double)
+declare i32 @js_string_index_to_i32(double)
+declare i32 @js_string_end_index_to_i32(double, i32)
+declare double @js_dyn_index_get(double, double)
+declare double @js_dyn_index_set(double, double, double)
+declare i64 @js_string_to_char_array(i64)
+declare i64 @js_string_repeat(i64, double)
+declare i64 @js_string_replace_string(i64, i64, i64)
+declare i64 @js_string_replace_all_string(i64, i64, i64)
+declare i32 @js_string_equals(i64, i64)
+declare i32 @js_string_compare(i64, i64)
+declare i32 @js_jsvalue_equals(double, double)
+declare i32 @js_string_compare_value(double, double)
+declare i64 @js_jsvalue_to_string_radix(double, double)
+declare double @js_math_random()
+declare double @js_webassembly_validate(double)
+declare double @js_webassembly_compile(double)
+declare double @js_webassembly_module_new(double)
+declare double @js_webassembly_module_exports(double)
+declare double @js_webassembly_module_imports(double)
+declare double @js_webassembly_module_custom_sections(double, double)
+declare double @js_webassembly_instantiate(double, double)
+declare double @js_wasi_emit_warning()
+declare double @js_webassembly_call_export_0(double, double)
+declare double @js_webassembly_call_export_1(double, double, double)
+declare double @js_webassembly_call_export_2(double, double, double, double)
+declare double @js_webassembly_call_export_3(double, double, double, double, double)
+declare double @js_webassembly_call_export_4(double, double, double, double, double, double)
+declare void @js_console_log_spread(i64)
+declare void @js_console_info_spread(i64)
+declare void @js_console_debug_spread(i64)
+declare void @js_console_error_spread(i64)
+declare void @js_console_warn_spread(i64)
+declare double @js_util_format(i64)
+declare double @js_util_format_with_options(double, i64)
+declare double @js_util_inspect(double, double)
+declare double @js_util_debuglog(double, double)
+declare double @js_util_diff(double, double)
+declare double @js_util_inherits(double, double)
+declare double @js_util_is_deep_strict_equal(double, double)
+declare double @js_util_strip_vt_control_characters(double)
+declare double @js_util_style_text(double, double, double)
+declare double @js_util_get_call_sites(double, double)
+declare double @js_util_promisify(double)
+declare double @js_util_callbackify(double)
+declare double @js_util_deprecate(double, double, double)
+declare double @js_util_aborted(double, double)
+declare double @js_util_transferable_abort_controller()
+declare double @js_util_transferable_abort_signal(double)
+declare double @js_util_parse_args(double)
+declare double @js_boxed_number_new(double)
+declare double @js_boxed_string_new(double, i32)
+declare double @js_boxed_boolean_new(double)
+declare double @js_util_types_is_arguments_object(double)
+declare double @js_util_types_is_promise(double)
+declare double @js_util_types_is_big_int_object(double)
+declare double @js_util_types_is_symbol_object(double)
+declare double @js_util_types_is_array_buffer(double)
+declare double @js_util_types_is_shared_array_buffer(double)
+declare double @js_util_types_is_any_array_buffer(double)
+declare double @js_util_types_is_array_buffer_view(double)
+declare double @js_util_types_is_data_view(double)
+declare double @js_util_types_is_typed_array(double)
+declare double @js_util_types_is_uint8_array(double)
+declare double @js_util_types_is_int8_array(double)
+declare double @js_util_types_is_int16_array(double)
+declare double @js_util_types_is_uint16_array(double)
+declare double @js_util_types_is_int32_array(double)
+declare double @js_util_types_is_uint32_array(double)
+declare double @js_util_types_is_float16_array(double)
+declare double @js_util_types_is_float32_array(double)
+declare double @js_util_types_is_float64_array(double)
+declare double @js_util_types_is_uint8_clamped_array(double)
+declare double @js_util_types_is_big_int64_array(double)
+declare double @js_util_types_is_big_uint64_array(double)
+declare double @js_util_types_is_map(double)
+declare double @js_util_types_is_weak_map(double)
+declare double @js_util_types_is_set(double)
+declare double @js_util_types_is_weak_set(double)
+declare double @js_util_types_is_date(double)
+declare double @js_util_types_is_reg_exp(double)
+declare double @js_util_types_is_async_function(double)
+declare double @js_util_types_is_generator_function(double)
+declare double @js_util_types_is_generator_object(double)
+declare double @js_util_types_is_native_error(double)
+declare double @js_util_types_is_number_object(double)
+declare double @js_util_types_is_string_object(double)
+declare double @js_util_types_is_boolean_object(double)
+declare double @js_util_types_is_boxed_primitive(double)
+declare double @js_util_types_is_external(double)
+declare double @js_util_types_is_module_namespace_object(double)
+declare double @js_util_types_is_key_object(double)
+declare double @js_util_types_is_crypto_key(double)
+declare double @js_util_types_is_proxy(double)
+declare double @js_util_types_is_map_iterator(double)
+declare double @js_util_types_is_set_iterator(double)
+declare double @js_data_view_new(double, double, double)
+declare double @js_data_view_get_direct(double, double, double, i32, i32)
+declare double @js_data_view_set_direct(double, double, double, double, i32, i32)
+declare i64 @js_getenv(i64)
+declare double @js_getenv_value(i64)
+declare void @js_setenv(i64, double)
+declare void @js_removeenv(i64)
+declare double @js_process_exit_code_get()
+declare double @js_process_exit_code_set(double)
+declare void @js_console_table(double)
+declare void @js_console_table_with_properties(double, double)
+declare void @js_console_trace(double)
+declare void @js_console_trace_spread(i64)
+declare i64 @js_process_cwd()
+declare i64 @js_process_argv()
+declare double @js_process_pid()
+declare double @js_process_ppid()
+declare double @js_process_uptime()
+declare i64 @js_process_version()
+declare double @js_process_versions()
+declare double @js_process_memory_usage()
+declare double @js_bigint_as_int_n_call(double, double)
+declare double @js_bigint_as_uint_n_call(double, double)
+declare double @js_v8_serialize(double)
+declare double @js_v8_deserialize(double)
+declare double @js_v8_get_heap_statistics()
+declare double @js_v8_get_heap_code_statistics()
+declare double @js_v8_get_heap_space_statistics()
+declare double @js_v8_cached_data_version_tag()
+declare double @js_v8_get_heap_snapshot(double)
+declare double @js_v8_write_heap_snapshot(double, double)
+declare double @js_v8_gc_profiler_new()
+declare double @js_v8_gc_profiler_start(double)
+declare double @js_v8_gc_profiler_stop(double)
+declare double @js_v8_gc_profiler_report()
+declare double @js_v8_serializer_new(double)
+declare double @js_v8_deserializer_new(double)
+declare double @js_v8_noop_undefined()
+declare double @js_v8_is_building_snapshot()
+declare double @js_v8_namespace(ptr, i64)
+declare double @js_v8_throw_not_building_snapshot()
+declare double @js_v8_promise_hook_register()
+declare double @js_v8_promise_hooks_on_init(double)
+declare double @js_v8_promise_hooks_on_before(double)
+declare double @js_v8_promise_hooks_on_after(double)
+declare double @js_v8_promise_hooks_on_settled(double)
+declare double @js_v8_promise_hooks_create_hook(double)
+declare double @js_process_thread_cpu_usage(double)
+declare double @js_process_available_memory()
+declare double @js_process_constrained_memory()
+declare double @js_process_source_maps_enabled()
+declare double @js_process_set_source_maps_enabled(double)
+declare double @js_process_has_uncaught_exception_capture_callback()
+declare double @js_process_set_uncaught_exception_capture_callback(double)
+declare double @js_process_add_uncaught_exception_capture_callback(double)
+declare double @js_process_getuid()
+declare double @js_process_geteuid()
+declare double @js_process_getgid()
+declare double @js_process_getegid()
+declare void @js_process_emit_warning(double, double, double)
+declare double @js_process_cpu_usage(double)
+declare double @js_process_resource_usage()
+declare double @js_process_active_resources_info()
+declare double @js_process_env()
+declare double @js_process_hrtime_bigint()
+declare double @js_process_hrtime(double)
+declare double @js_process_title()
+declare void @js_process_set_title(double)
+declare void @js_process_chdir(i64)
+declare void @js_process_chdir_jsv(double)
+declare double @js_process_kill(double, double)
+declare void @js_process_exit(double)
+declare void @js_process_abort()
+declare double @js_process_umask()
+declare double @js_process_umask_set(double)
+declare double @js_process_on(i64, i64)
+declare double @js_process_add_listener(i64, i64)
+declare double @js_process_once(i64, i64)
+declare double @js_process_prepend_listener(i64, i64)
+declare double @js_process_prepend_once_listener(i64, i64)
+declare double @js_process_emit(i64, i64)
+declare void @js_process_emit_before_exit(double)
+declare void @js_process_run_finalization_exit()
+declare void @js_trace_events_flush_output()
+declare void @js_promise_report_unhandled_rejections()
+declare i32 @js_process_pending_exit_code()
+declare void @js_gc_release_current_thread_collection_side_allocations()
+declare double @js_process_remove_listener(i64, i64)
+declare double @js_process_off(i64, i64)
+declare double @js_process_remove_all_listeners(i64)
+declare double @js_process_listener_count(i64, i64)
+declare i64 @js_process_listeners(i64)
+declare i64 @js_process_raw_listeners(i64)
+declare i64 @js_process_event_names()
+declare double @js_process_set_max_listeners(double)
+declare double @js_process_get_max_listeners()
+declare double @js_process_get_builtin_module(double)
+declare double @js_process_get_builtin_module_devirt(double)
+declare double @js_process_execve(double, double, double)
+declare double @js_module_is_builtin(double)
+declare double @js_module_find_package_json(double, double)
+declare double @js_module_register(double, double, double)
+declare double @js_module_register_hooks(double)
+declare void @js_process_next_tick(i64, i64)
+declare double @js_process_stdin()
+declare double @js_process_stdout()
+declare double @js_process_stderr()
+declare double @js_readline_set_raw_mode(double)
+declare void @js_readline_stdin_on(i64, i64)
+declare double @js_readline_stdin_remove_listener(i64, i64)
+declare double @js_readline_stdin_pause()
+declare double @js_readline_stdin_resume()
+declare double @js_readline_stdin_unref()
+declare double @js_readline_stdin_ref()
+declare double @js_readline_stdin_destroy()
+declare double @js_tty_isatty(double)
+declare double @js_tty_read_stream_new(double)
+declare double @js_tty_write_stream_new(double)
+declare double @js_wasi_constructor_call(double)
+declare double @js_process_stdin_isatty()
+declare double @js_process_stdout_isatty()
+declare double @js_process_stderr_isatty()
+declare double @js_process_stdout_columns()
+declare double @js_process_stdout_rows()
+declare double @js_process_stdout_on(i64, i64)
+declare i64 @js_os_platform()
+declare i64 @js_os_arch()
+declare i64 @js_os_type()
+declare i64 @js_os_release()
+declare i64 @js_os_hostname()
+declare i64 @js_os_eol()
+declare double @js_os_available_parallelism()
+declare i64 @js_os_endianness()
+declare i64 @js_os_dev_null()
+declare i64 @js_os_machine()
+declare i64 @js_os_loadavg()
+declare i64 @js_os_version()
+declare i64 @js_box_alloc_bits(i64)
+declare i64 @js_box_get_bits(i64)
+declare void @js_box_set_bits(i64, i64)
+declare i64 @js_box_alloc(double)
+declare double @js_box_get(i64)
+declare void @js_box_set(i64, double)
+declare i64 @js_i32_box_alloc(i32)
+declare i32 @js_i32_box_get(i64)
+declare void @js_i32_box_set(i64, i32)
+declare i64 @js_bool_box_alloc(i32)
+declare i32 @js_bool_box_get(i64)
+declare void @js_bool_box_set(i64, i32)
+declare i64 @js_arguments_object_alloc(double, double, i32)
+declare void @js_arguments_object_map_index(i64, i32, i64)
+declare i64 @js_array_like_to_array(double)
+declare i32 @js_object_get_class_id(i64)
+declare i64 @js_object_alloc_with_parent(i32, i32, i32)
+declare i64 @js_object_alloc_class_with_keys(i32, i32, i32, ptr, i32)
+declare i64 @js_object_alloc_class_dynamic_parent(i32, i32, ptr, i32)
+declare i64 @js_object_alloc_class_inline_keys(i32, i32, i32, i64)
+declare i64 @js_build_class_keys_array(i32, i32, ptr, i32)
+declare ptr @js_inline_arena_state()
+declare ptr @js_inline_arena_slow_alloc(ptr, i64, i64)
+declare i32 @js_object_delete_field(i64, i64)
+declare i32 @js_object_delete_field_value(double, i64)
+declare i32 @js_object_delete_dynamic_value(double, double)
+declare double @js_delete_result(i32, i32)
+declare i64 @js_eq(i64, i64)
+declare i64 @js_loose_eq(i64, i64)
+declare i64 @js_number_to_fixed(double, double)
+declare i64 @js_string_replace_regex(i64, i64, i64)
+declare i64 @js_string_replace_all_regex(i64, i64, i64)
+declare double @js_array_at(i64, double)
+declare double @js_date_get_time(double)
+declare double @js_date_get_full_year(double)
+declare double @js_date_get_month(double)
+declare double @js_date_get_date(double)
+declare double @js_date_get_day(double)
+declare double @js_date_get_hours(double)
+declare double @js_date_get_minutes(double)
+declare double @js_date_get_seconds(double)
+declare double @js_date_get_milliseconds(double)
+declare double @js_date_get_utc_day(double)
+declare double @js_date_get_utc_full_year(double)
+declare double @js_date_get_utc_month(double)
+declare double @js_date_get_utc_date(double)
+declare double @js_date_get_utc_hours(double)
+declare double @js_date_get_utc_minutes(double)
+declare double @js_date_get_utc_seconds(double)
+declare double @js_date_get_utc_milliseconds(double)
+declare double @js_date_value_of(double)
+declare double @js_date_get_timezone_offset(double)
+declare double @js_date_coerce_number(double)
+declare double @js_rel_lt(double, double)
+declare double @js_rel_le(double, double)
+declare double @js_rel_gt(double, double)
+declare double @js_rel_ge(double, double)
+declare i64 @js_date_to_string(double)
+declare i64 @js_date_to_iso_string(double)
+declare i64 @js_date_to_iso_string_or_throw(double)
+declare double @js_date_new_from_timestamp(double)
+declare double @js_date_new_from_value(double)
+declare i32 @js_array_indexOf_f64(i64, double)
+declare i64 @js_array_indexOf_jsvalue(i64, double, double, i32)
+declare i64 @js_array_last_index_of_jsvalue(i64, double, double, i32)
+declare i32 @js_array_includes_f64(i64, double)
+declare i32 @js_array_includes_jsvalue(i64, double, double, i32)
+declare i32 @js_map_size(i64)
+declare void @js_map_clear(i64)
+declare void @js_set_clear(i64)
+declare i64 @js_map_entries(i64)
+declare i64 @js_map_keys(i64)
+declare i64 @js_map_values(i64)
+declare double @js_map_entry_key_at(i64, i32)
+declare double @js_map_entry_value_at(i64, i32)
+declare double @js_map_find_key_index(double, double)
+declare double @js_set_find_value_index(double, double)
+declare void @js_map_foreach(i64, double, double)
+declare void @js_set_foreach(i64, double, double)
+declare i64 @js_map_entries_iter_obj(i64)
+declare i64 @js_map_keys_iter_obj(i64)
+declare i64 @js_map_values_iter_obj(i64)
+declare i64 @js_set_values_iter_obj(i64)
+declare i64 @js_set_keys_iter_obj(i64)
+declare i64 @js_set_entries_iter_obj(i64)
+declare i64 @js_set_to_array(i64)
+declare double @js_set_value_at(i64, i32)
+declare i64 @js_array_splice(i64, i32, i32, ptr, i32, ptr)
+declare i32 @js_array_splice_delete_count(double)
+declare double @js_parse_int(i64, double)
+declare double @js_parse_float(i64)
+declare double @js_array_reduce(i64, i64, i32, double)
+declare double @js_array_reduce_right(i64, i64, i32, double)
+declare i64 @js_array_sort_default(i64)
+declare i64 @js_array_reverse(i64)
+declare double @js_array_reverse_value(double)
+declare i64 @js_array_flat(i64)
+declare i64 @js_array_flat_depth(i64, double)
+declare i64 @js_array_flatMap(i64, i64)
+declare i64 @js_array_sort_with_comparator(i64, i64)
+declare i64 @js_validate_array_comparator(double)
+declare i64 @js_validate_array_callback(double)
+declare i64 @js_validate_array_map_callback(i64, double)
+declare i64 @js_array_to_reversed(i64)
+declare i64 @js_array_to_sorted_default(i64)
+declare i64 @js_array_to_sorted_with_comparator(i64, i64)
+declare i64 @js_array_to_spliced(i64, double, double, ptr, i32)
+declare i64 @js_array_with(i64, double, double)
+declare i64 @js_array_copy_within(i64, double, double, i32, double)
+declare double @js_array_copy_within_value(double, double, double, i32, double)
+declare i64 @js_regexp_new(i64, i64)
+declare i64 @js_regexp_construct(double, double)
+declare i64 @js_regexp_construct_call(double, double)
+declare i32 @js_regexp_test(i64, i64)
+declare double @js_regexp_escape(double)
+declare i64 @js_get_string_pointer_unified(double)
+declare i32 @js_switch_strict_equals(double, double)
+declare i64 @js_value_to_str_ptr_for_ffi(double)
+declare void @js_string_addref(i64)
+declare void @js_string_addref_if_heap_string(double)
+declare i64 @js_bigint_from_string(ptr, i32)
+declare i64 @js_bigint_from_f64(double)
+declare i64 @js_bigint_from_i128_parts(i64, i64)
+declare i32 @js_bigint_cmp(i64, i64)
+declare double @js_dynamic_add(double, double)
+declare double @js_to_numeric(double)
+declare double @js_numeric_step(double, i32)
+declare double @js_dynamic_string_or_number_add(double, double)
+declare double @js_dynamic_sub(double, double)
+declare double @js_dynamic_mul(double, double)
+declare double @js_dynamic_div(double, double)
+declare double @js_dynamic_mod(double, double)
+declare double @js_dynamic_bitand(double, double)
+declare double @js_dynamic_bitor(double, double)
+declare double @js_dynamic_bitxor(double, double)
+declare double @js_dynamic_shl(double, double)
+declare double @js_dynamic_shr(double, double)
+declare double @js_dynamic_bitnot(double)
+declare double @js_dynamic_pow(double, double)
+declare double @js_dynamic_ushr(double, double)
+declare double @js_instanceof(double, i32)
+declare double @js_instanceof_dynamic(double, double)
+declare double @js_instanceof_noncallable_rhs()
+declare void @js_register_class_extends_error(i32)
+declare void @js_register_class_extends_data_view(i32)
+declare void @js_register_class_id(i32)
+declare void @js_register_class_name(i32, ptr, i32)
+declare void @js_register_anon_shape_class_id(i32)
+declare double @js_get_global_this_builtin_value(ptr, i64)
+declare double @js_promise_static_function_value(ptr, i64)
+declare double @js_builtin_prototype_method_value(ptr, i64, ptr, i64)
+declare void @js_register_class_parent(i32, i32)
+declare void @js_register_class_parent_dynamic(i32, double)
+declare double @js_get_dynamic_parent_value(i32)
+declare void @js_class_register_capture_values(i32, ptr, i64)
+declare void @js_class_object_refresh_capture_values(double, i64, double)
+declare void @js_tdz_suppress_begin()
+declare void @js_tdz_suppress_end()
+declare double @js_class_capture_value(i32, i32)
+declare double @js_class_capture_value_for_receiver(double, i32, i32)
+declare double @js_class_capture_value_or(i32, i32, double)
+declare double @js_param_or_class_capture_value(double, i32, i32)
+declare void @js_super_construct_apply(i32, double, double)
+declare double @js_super_method_call_dynamic(i32, ptr, i64, double, ptr, i64)
+declare double @js_super_method_call_dynamic_apply(i32, ptr, i64, double, double)
+declare i64 @js_array_push_spread_any(i64, double)
+declare i32 @js_set_function_prototype(double, double)
+declare void @js_register_prototype_method(i32, ptr, i64, double)
+declare i32 @js_register_function_prototype_method(double, ptr, i64, double)
+declare double @js_new_function_construct(double, ptr, i64)
+declare double @js_function_ctor_from_strings(ptr, i64)
+declare double @js_new_function_construct_apply(double, double)
+declare double @js_throw_not_a_constructor()
+declare double @js_new_target_value()
+declare double @js_get_function_prototype_method(double, ptr, i64)
+declare double @js_function_prototype_value_for_read(double)
+declare i64 @js_typeerror_new(i64)
+declare i64 @js_rangeerror_new(i64)
+declare i64 @js_syntaxerror_new(i64)
+declare i64 @js_referenceerror_new(i64)
+declare double @js_throw_symbol_constructor_type_error()
+declare double @js_throw_bigint_constructor_type_error()
+declare double @js_throw_strict_eval_arguments_syntax_error()
+declare double @js_throw_eval_syntax_error(double)
+declare double @js_throw_restricted_function_property_assignment()
+declare double @js_throw_math_constructor_type_error()
+declare double @js_throw_json_constructor_type_error()
+declare double @js_webcrypto_illegal_constructor()
+declare double @js_throw_type_error_const_assignment(double)
+declare double @js_throw_reference_error_unresolvable_assignment(double)
+declare double @js_throw_reference_error_unresolved_get()
+declare double @js_with_implicit_unset()
+declare double @js_with_implicit_read(double, double)
+declare double @js_iterator_result_validate(double)
+declare double @js_global_get_or_throw_unresolved(double)
+declare double @js_module_ambient_require()
+declare double @js_module_ambient_require_apply(double)
+declare double @js_module_dynamic_import_fallback(double)
+declare double @js_module_dynamic_import_deferred(double, double)
+declare double @js_module_create_require_devirt(double)
+declare double @js_global_get_optional(double)
+declare double @js_global_update(double, double, double)
+declare double @js_global_assign_existing_or_throw(double, double)
+declare double @js_throw_reference_error_this_before_super()
+declare double @js_throw_reference_error_super_delete()
+declare double @js_throw_reference_error_unresolved_assignment()
+declare i64 @js_evalerror_new(i64)
+declare i64 @js_urierror_new(i64)
+declare i64 @js_weakmap_new()
+declare i64 @js_weakset_new()
+declare double @js_weakmap_init_iterable(double, double)
+declare double @js_weakset_init_iterable(double, double)
+declare double @js_weakmap_set(double, double, double)
+declare double @js_weakmap_get(double, double)
+declare double @js_weakmap_has(double, double)
+declare double @js_weakmap_delete(double, double)
+declare double @js_weakset_add(double, double)
+declare double @js_weakset_has(double, double)
+declare double @js_weakset_delete(double, double)
+declare double @js_weak_throw_primitive()
+declare i64 @js_buffer_from_string(i64, i32)
+declare i32 @js_encoding_tag_from_value(double)
+declare i64 @js_value_to_string_with_encoding(double, i32)
+declare i64 @js_value_to_string_with_encoding_or_radix(double, i32, double)
+declare i64 @js_object_values(i64)
+declare i64 @js_object_values_value(double)
+declare i64 @js_object_entries(i64)
+declare i64 @js_object_entries_value(double)
+declare i64 @js_path_join(i64, i64)
+declare i64 @js_path_win32_join(i64, i64)
+declare i64 @js_path_win32_dirname(i64)
+declare i64 @js_path_win32_basename(i64)
+declare i64 @js_path_win32_basename_ext(i64, i64)
+declare i64 @js_path_win32_extname(i64)
+declare i32 @js_path_win32_is_absolute(i64)
+declare i64 @js_path_win32_normalize(i64)
+declare i64 @js_path_win32_parse(i64)
+declare i64 @js_path_win32_format(double)
+declare i64 @js_path_win32_relative(i64, i64)
+declare i64 @js_path_win32_relative_checked(double, double)
+declare i64 @js_path_win32_resolve(i64)
+declare i64 @js_path_win32_resolve_join(i64, i64)
+declare i64 @js_path_win32_to_namespaced_path(i64)
+declare double @js_path_win32_to_namespaced_path_value(double)
+declare i32 @js_path_win32_matches_glob(i64, i64)
+declare i64 @js_path_win32_sep_get()
+declare i64 @js_path_win32_delimiter_get()
+declare i64 @js_path_dirname(i64)
+declare i64 @js_path_resolve(i64)
+declare i64 @js_path_relative(i64, i64)
+declare i64 @js_path_relative_checked(double, double)
+declare i64 @js_path_to_namespaced_path(i64)
+declare double @js_path_to_namespaced_path_value(double)
+declare i32 @js_path_matches_glob(i64, i64)
+declare i64 @js_path_resolve_join(i64, i64)
+declare double @js_object_from_entries(double)
+declare i64 @js_string_match(i64, i64)
+declare i64 @js_string_match_all(i64, i64)
+declare i64 @js_string_match_all_value(i64, double)
+declare double @llvm.log.f64(double)
+declare double @llvm.log2.f64(double)
+declare double @llvm.log10.f64(double)
+declare double @llvm.exp.f64(double)
+declare double @llvm.sin.f64(double)
+declare double @llvm.cos.f64(double)
+declare i64 @js_path_basename(i64)
+declare i64 @js_path_basename_ext(i64, i64)
+declare i64 @js_path_extname(i64)
+declare i64 @js_path_sep_get()
+declare i64 @js_path_delimiter_get()
+declare i64 @js_path_parse(i64)
+declare i64 @js_json_parse(i64)
+declare i64 @js_json_text_to_string(double)
+declare double @js_json_raw_json(double)
+declare double @js_json_is_raw_json(double)
+declare i64 @js_json_parse_or_null(i64)
+declare i64 @js_json_parse_typed_array(i64, i64, i32, i32)
+declare i64 @js_date_to_date_string(double)
+declare i64 @js_date_to_time_string(double)
+declare i64 @js_date_to_utc_string(double)
+declare i64 @js_date_to_locale_date_string(double)
+declare i64 @js_date_to_locale_time_string(double)
+declare i64 @js_date_to_json(double)
+declare i64 @js_regexp_exec(i64, i64)
+declare i64 @js_number_to_precision(double, double)
+declare i64 @js_number_to_exponential(double, double)
+declare double @js_date_new()
+declare double @js_number_is_integer(double)
+declare double @js_number_is_nan(double)
+declare double @js_number_is_safe_integer(double)
+declare double @js_date_parse(i64)
+declare double @js_date_utc(ptr, i32)
+declare double @js_date_new_local_components(double, double, double, double, double, double, double)
+declare double @js_date_apply_setter(double, i32, i32, ptr, i32)
+declare double @js_math_clz32(double)
+declare double @js_math_cbrt(double)
+declare double @js_math_fround(double)
+declare double @js_math_f16round(double)
+declare double @js_math_sinh(double)
+declare double @js_math_cosh(double)
+declare double @js_math_tanh(double)
+declare double @js_math_asinh(double)
+declare double @js_math_acosh(double)
+declare double @js_math_atanh(double)
+declare double @js_math_hypot(double, double)
+declare double @js_object_is(double, double)
+declare i64 @js_path_normalize(i64)
+declare i64 @js_path_format(double)
+declare i32 @js_path_is_absolute(i64)
+declare i64 @js_encode_uri(double)
+declare i64 @js_decode_uri(double)
+declare i64 @js_encode_uri_component(double)
+declare i64 @js_decode_uri_component(double)
+declare i64 @js_text_encoder_new()
+declare i64 @js_text_decoder_new(double, double, double)
+declare i64 @js_text_encoder_encode_llvm(double)
+declare i64 @js_text_decoder_decode_llvm(double, double)
+declare i64 @js_text_decoder_encoding(double)
+declare double @js_text_decoder_fatal(double)
+declare double @js_text_decoder_ignore_bom(double)
+declare void @js_queue_microtask(i64)
+declare void @js_queue_next_tick(i64)
+declare void @js_queue_next_tick_args(i64, ptr, i32)
+declare void @js_drain_queued_microtasks()
+declare i64 @js_uint8array_from_array(i64)
+declare i64 @js_uint8array_alloc(i32)
+declare i64 @js_uint8array_new(double)
+declare i64 @js_uint8array_view(double, double, double)
+declare i64 @js_typed_array_new_empty(i32, i32)
+declare i64 @js_typed_array_new_from_array(i32, i64)
+declare i64 @js_typed_array_new(i32, double)
+declare i64 @js_typed_array_view(i32, double, double, double)
+declare i32 @js_typed_array_length(i64)
+declare double @js_typed_array_get(i64, i32)
+declare i32 @js_typed_array_read_int32(i64, i32)
+declare double @js_typed_array_read_f64(i64, i32)
+declare double @js_typed_array_index_get_dynamic(i64, double)
+declare double @js_typed_array_at(i64, double)
+declare void @js_typed_array_set(i64, i32, double)
+declare double @js_typed_array_index_set_dynamic(i64, double, double)
+declare i32 @js_uint8array_get(i64, i32)
+declare double @js_uint8array_index_get_value(i64, i32)
+declare void @js_uint8array_set(i64, i32, i32)
+declare i64 @js_native_arena_alloc(i64)
+declare i64 @js_native_arena_view(i64, i32, i64, i64)
+declare i64 @js_native_pod_view(i64, i64, i64, i64, i64, i64)
+declare ptr @js_native_abi_check_pod_view_data_ptr(double, i64)
+declare i64 @js_native_abi_check_pod_view_record_count(double, i64)
+declare void @js_native_arena_dispose(i64)
+declare void @js_native_memory_fill_u32(i64, double)
+declare void @js_native_memory_copy(i64, i64)
+declare i64 @js_typed_array_to_reversed(i64)
+declare i64 @js_typed_array_to_sorted_default(i64)
+declare i64 @js_typed_array_to_sorted_with_comparator(i64, i64)
+declare i64 @js_typed_array_with(i64, double, double)
+declare double @js_typed_array_find_last(i64, i64)
+declare double @js_typed_array_find_last_index(i64, i64)
+declare double @js_typed_array_set_from(i64, double, double)
+declare i64 @js_typed_array_subarray(i64, i32, double, i32, double)
+declare double @js_object_has_own(double, double)
+declare double @js_object_property_is_enumerable(double, double)
+declare double @js_object_define_getter(double, double, double)
+declare double @js_object_define_setter(double, double, double)
+declare double @js_object_lookup_getter(double, double)
+declare double @js_object_lookup_setter(double, double)
+declare double @js_object_get_own_field_or_undef(double, ptr, i64)
+declare double @js_unresolved_namespace_stub()
+declare double @js_node_submodule_export_as_function(ptr, i32, ptr, i32)
+declare double @js_node_submodule_namespace_member(ptr, i32, ptr, i32)
+declare double @js_node_submodule_namespace(ptr, i32)
+declare void @js_node_submod_install_vm()
+declare void @js_node_submod_install_timers()
+declare void @js_node_submod_install_timers_promises()
+declare void @js_node_submod_install_fs_promises()
+declare void @js_node_submod_install_readline_promises()
+declare void @js_node_submod_install_stream_promises()
+declare void @js_node_submod_install_stream_consumers()
+declare void @js_node_submod_install_stream_web()
+declare void @js_node_submod_install_hono_jsx_server()
+declare void @js_node_submod_install_hono_jsx_streaming()
+declare void @js_node_submod_install_sys()
+declare void @js_node_submod_install_diagnostics_channel()
+declare void @js_node_submod_install_trace_events()
+declare void @js_node_submod_install_test()
+declare void @js_node_submod_install_test_reporters()
+declare void @js_node_submod_install_all()
+declare void @js_node_submod_enable_install_all()
+declare double @js_unresolved_default_call()
+declare double @js_get_global_this()
+declare double @js_module_top_this()
+declare double @js_global_or_console_property_by_name(i64)
+declare void @js_class_register_static_symbol(i32, double, double)
+declare void @js_register_class_computed_method(i64, double, i64, i64, i64, i64)
+declare void @js_register_class_computed_accessor(i64, double, i64, i64, i64)
+declare void @js_class_register_static_field(i32, ptr, i64, double)
+declare double @js_object_define_property(double, double, double)
+declare double @js_object_get_own_property_descriptor(double, double)
+declare double @js_object_get_own_property_descriptors(double)
+declare double @js_object_get_own_property_names(double)
+declare double @js_symbol_new(double)
+declare double @js_symbol_new_empty()
+declare double @js_symbol_for(double)
+declare double @js_symbol_computed_member(double, double)
+declare double @js_symbol_key_for(double)
+declare double @js_symbol_description(double)
+declare i64 @js_symbol_to_string(double)
+declare i32 @js_symbol_equals(double, double)
+declare i32 @js_is_symbol(double)
+declare i64 @js_object_get_own_property_symbols(double)
+declare double @js_object_set_symbol_property(double, double, double)
+declare double @js_to_property_key(double)
+declare double @js_object_set_property_key(double, double, double)
+declare double @js_object_get_property_key(double, double)
+declare double @js_object_set_property_key_method(double, double, double)
+declare double @js_object_super_get(double, double, double)
+declare double @js_object_super_put_value_set(double, double, double, double, i32)
+declare double @js_object_super_call(double, double, double, ptr, i64)
+declare double @js_object_literal_infer_computed_function_name(double, double)
+declare double @js_object_get_symbol_property(double, double)
+declare double @js_object_create(double)
+declare double @js_object_create_with_props(double, double)
+declare double @js_object_freeze(double)
+declare double @js_object_seal(double)
+declare double @js_object_prevent_extensions(double)
+declare void @js_object_copy_own_fields(i64, double)
+declare double @js_object_assign_validate_target(double)
+declare double @js_object_assign_one(double, double)
+declare double @js_string_at(i64, i32)
+declare double @js_string_code_point_at(i64, i32)
+declare i64 @js_string_from_code_point(double)
+declare i64 @js_string_raw(double, double)
+declare i64 @js_string_from_char_code(double)
+declare i64 @js_string_from_char_code_array(double)
+declare double @js_string_char_code_at(i64, i32)
+declare i32 @js_string_last_index_of(i64, i64)
+declare i32 @js_string_last_index_of_from(i64, i64, double, i32)
+declare double @js_string_locale_compare(i64, i64)
+declare double @js_string_locale_compare_opts(i64, i64, double)
+declare i64 @js_string_normalize(i64, double)
+declare i64 @js_string_pad_start(i64, double, i64)
+declare i64 @js_string_pad_end(i64, double, i64)
+declare i64 @js_string_pad_fill(double)
+declare double @js_string_is_well_formed(i64)
+declare i64 @js_string_to_well_formed(i64)
+declare i32 @js_string_search_regex(i64, i64)
+declare i32 @js_string_search_value(i64, double)
+declare i64 @js_string_match_value(i64, double)
+declare double @js_regexp_exec_get_index()
+declare i64 @js_regexp_exec_get_groups()
+declare double @js_regexp_get_last_index(i64)
+declare void @js_regexp_set_last_index(i64, double)
+declare i64 @js_regexp_get_source(i64)
+declare i64 @js_regexp_get_flags(i64)
+declare i64 @js_string_replace_regex_named(i64, i64, i64)
+declare i64 @js_string_replace_all_regex_named(i64, i64, i64)
+declare i64 @js_string_replace_string_fn(i64, i64, double)
+declare i64 @js_string_replace_string_dyn(i64, i64, double)
+declare i64 @js_string_replace_all_string_dyn(i64, i64, double)
+declare i64 @js_string_replace_regex_dyn(i64, i64, double)
+declare i64 @js_string_replace_all_regex_dyn(i64, i64, double)
+declare i64 @js_string_replace_search_dyn(i64, double, double)
+declare i64 @js_string_replace_all_search_dyn(i64, double, double)
+declare i64 @js_string_replace_all_string_fn(i64, i64, double)
+declare i64 @js_string_replace_regex_fn(i64, i64, double)
+declare i64 @js_string_replace_all_regex_fn(i64, i64, double)
+declare double @js_structured_clone(double)
+declare double @js_structured_clone_with_options(double, double)
+declare double @js_generator_attach_prototype(double, i32)
+declare double @js_generator_attach_closure_prototype(double, i64)
+declare i64 @js_weakref_new(double)
+declare double @js_weakref_deref(double)
+declare i64 @js_finreg_new(double)
+declare double @js_finreg_register(double, double, double, double)
+declare double @js_finreg_unregister(double, double)
+declare i64 @js_atob(double)
+declare i64 @js_btoa(double)
+declare double @js_object_is_frozen(double)
+declare double @js_object_is_sealed(double)
+declare double @js_object_is_extensible(double)
+declare i64 @js_aggregateerror_new(i64, i64)
+declare i64 @js_error_new_with_cause(i64, double)
+declare i64 @js_aggregateerror_new_full(double, i64, double)
+declare i64 @js_error_new_kind_with_options(i32, i64, double)
+declare double @js_error_is_error(double)
+declare i64 @js_error_get_errors(i64)
+declare i64 @js_crypto_sha256(i64)
+declare i64 @js_crypto_sha256_bytes(i64)
+declare i64 @js_crypto_md5(i64)
+declare i64 @js_crypto_hmac_sha256(i64, i64)
+declare i64 @js_crypto_hmac_sha256_bytes(i64, i64)
+declare void @js_runtime_validate_string_arg(double, ptr, i32)
+declare void @js_set_call_location(ptr, i64, i32)
+declare void @js_runtime_validate_crypto_key_arg(double, ptr, i32)
+declare void @js_runtime_validate_integer_arg(double, ptr, i32, double, double)
+declare i64 @js_crypto_pbkdf2_bytes(i64, i64, double, double, i64)
+declare double @js_crypto_pbkdf2_async_alg(i64, i64, double, double, i64, double)
+declare i64 @js_crypto_argon2_sync(i64, double)
+declare double @js_crypto_argon2_async(i64, double, double)
+declare i64 @js_crypto_encapsulate(double)
+declare double @js_crypto_encapsulate_async(double, double)
+declare i64 @js_crypto_decapsulate(double, double)
+declare double @js_crypto_decapsulate_async(double, double, double)
+declare i64 @js_crypto_hkdf_bytes_alg(i64, i64, i64, i64, double)
+declare double @js_crypto_hkdf_async_alg(i64, i64, i64, i64, double, double)
+declare i64 @js_crypto_scrypt_bytes(i64, i64, double, i64)
+declare double @js_crypto_scrypt_async(i64, i64, double, double)
+declare i64 @js_crypto_sign_rsa_sha256(i64, i64, double)
+declare double @js_crypto_sign_async(i64, i64, double, double)
+declare double @js_crypto_verify_rsa_sha256(i64, i64, double, i64)
+declare double @js_crypto_verify_async(i64, i64, double, i64, double)
+declare i64 @js_crypto_public_encrypt(i64, i64)
+declare i64 @js_crypto_private_decrypt(i64, i64)
+declare i64 @js_crypto_private_encrypt(i64, i64)
+declare i64 @js_crypto_public_decrypt(i64, i64)
+declare i64 @js_crypto_create_public_key(i64)
+declare i64 @js_crypto_create_private_key_value(double)
+declare i64 @js_crypto_create_public_key_value(double)
+declare i64 @js_crypto_generate_key_pair_sync_rsa(double)
+declare i64 @js_crypto_generate_key_pair_sync_ec_p256(double)
+declare i64 @js_crypto_generate_key_pair_sync_ed25519(double)
+declare i64 @js_crypto_generate_key_pair_sync_x25519(double)
+declare double @js_crypto_generate_key_pair_async(i64, double, double)
+declare i64 @js_crypto_diffie_hellman(double)
+declare double @js_crypto_get_cipher_info(double, double)
+declare i64 @js_crypto_get_curves()
+declare i64 @js_crypto_secure_heap_used()
+declare i64 @js_crypto_random_bytes_buffer(double)
+declare double @js_crypto_random_bytes_async(double, double)
+declare i64 @js_crypto_random_uuid(double)
+declare i64 @js_crypto_random_uuidv7()
+declare double @js_crypto_random_int(double, double)
+declare double @js_crypto_random_int_async(double, double, double)
+declare double @js_crypto_timing_safe_equal(double, double)
+declare i64 @js_crypto_get_hashes()
+declare i64 @js_crypto_get_ciphers()
+declare double @js_crypto_generate_prime_sync(double, double)
+declare double @js_crypto_generate_prime_async(double, double, double)
+declare double @js_crypto_check_prime_sync(double, double)
+declare double @js_crypto_check_prime_async(double, double, double)
+declare i64 @js_crypto_create_secret_key(i64, i64)
+declare i64 @js_crypto_generate_key_sync(i64, double)
+declare double @js_crypto_generate_key_async(i64, double, double)
+declare i64 @js_webcrypto_digest(double, double)
+declare i64 @js_webcrypto_import_key(double, double, double, double, double)
+declare i64 @js_webcrypto_export_key(double, double)
+declare i64 @js_webcrypto_sign(double, double, double)
+declare i64 @js_webcrypto_verify(double, double, double, double)
+declare i64 @js_webcrypto_derive_bits(double, double, double)
+declare i64 @js_webcrypto_derive_key(double, double, double, double, double)
+declare i64 @js_webcrypto_encrypt(double, double, double)
+declare i64 @js_webcrypto_decrypt(double, double, double)
+declare i64 @js_webcrypto_generate_key(double, double, double)
+declare i64 @js_webcrypto_wrap_key(double, double, double, double)
+declare i64 @js_webcrypto_unwrap_key(double, double, double, double, double, double, double)
+declare i64 @js_zlib_create_brotli_decompress(double)
+declare double @js_crypto_random_fill_sync(double, double, double)
+declare double @js_crypto_random_fill_async(double, double, double, double)
+declare double @js_crypto_create_hash(i64)
+declare double @js_crypto_create_hash_options(i64, double)
+declare double @js_crypto_x509_new(i64)
+declare double @js_crypto_certificate_verify_spkac(double)
+declare double @js_crypto_certificate_export_public_key(double)
+declare double @js_crypto_certificate_export_challenge(double)
+declare double @js_crypto_create_sign(i64)
+declare double @js_crypto_create_verify(i64)
+declare double @js_crypto_create_ecdh(i64)
+declare double @js_crypto_create_diffie_hellman(double, double, double)
+declare double @js_crypto_get_diffie_hellman(double)
+declare double @js_crypto_ecdh_convert_key(double, double, double, double, double)
+declare double @js_crypto_create_hmac(i64, i64)
+declare i64 @js_buffer_alloc(i32, i32)
+declare i64 @js_buffer_alloc_fill_value(i32, double, i32)
+declare i64 @js_array_buffer_new(i32)
+declare i64 @js_shared_array_buffer_new(i32)
+declare i64 @js_array_buffer_new_value(double)
+declare i64 @js_shared_array_buffer_new_value(double)
+declare i64 @js_json_stringify_full(double, double, double)
+declare i64 @js_json_parse_with_reviver(i64, i64)
+declare double @js_array_find(i64, i64)
+declare i32 @js_array_findIndex(i64, i64)
+declare double @js_array_find_last(i64, i64)
+declare i32 @js_array_find_last_index(i64, i64)
+declare double @js_array_some(i64, i64)
+declare double @js_array_every(i64, i64)
+declare i32 @js_promise_state(i64)
+declare double @js_promise_value(i64)
+declare double @js_promise_reason(i64)
+declare i32 @js_value_is_promise(double)
+declare double @js_assimilate_thenable(double)
+declare i32 @js_promise_run_microtasks()
+declare i32 @js_promise_run_microtasks_event_loop()
+declare i32 @js_promise_run_microtasks_await_loop()
+declare i32 @js_await_loop_tick_timers()
+declare void @js_mark_entry_module_esm()
+declare i32 @js_promise_run_promise_jobs()
+declare void @js_run_stdlib_pump()
+declare void @js_sleep_ms(double)
+declare void @js_wait_for_event()
+declare i32 @js_event_loop_host_driven()
+declare void @js_unsettled_top_level_await_exit()
+declare void @js_throw(double)
+declare ptr @js_try_push()
+declare i32 @_setjmp(ptr) #0
+declare void @js_try_end()
+declare double @js_get_exception()
+declare void @js_clear_exception()
+declare i32 @js_has_exception()
+declare void @js_enter_finally()
+declare void @js_leave_finally()
+declare double @js_await_any_promise(double)
+declare i64 @js_promise_new()
+declare i64 @js_promise_new_with_executor(i64)
+declare i32 @js_timer_tick()
+declare i32 @js_timer_tick_if_refed()
+declare i32 @js_callback_timer_tick()
+declare i32 @js_interval_timer_tick()
+declare i32 @js_timer_has_pending()
+declare i32 @js_callback_timer_has_pending()
+declare i32 @js_interval_timer_has_pending()
+declare i32 @js_stdlib_has_active_handles()
+declare i32 @js_microtasks_pending()
+declare i64 @js_timer_validate_callback(double, i32)
+declare i64 @js_set_timeout_callback(i64, double)
+declare i64 @js_set_timeout_callback_args(i64, double, ptr, i32)
+declare i64 @js_set_immediate_callback(i64)
+declare i64 @js_set_immediate_callback_args(i64, ptr, i32)
+declare i64 @setInterval(i64, double)
+declare i64 @js_set_interval_callback_args(i64, double, ptr, i32)
+declare void @clearTimeout(i64)
+declare void @clearInterval(i64)
+declare void @clearImmediate(i64)
+declare void @js_clear_timeout_value(double)
+declare void @js_clear_interval_value(double)
+declare void @js_clear_immediate_value(double)
+declare i64 @js_buffer_from_array(i64)
+declare i64 @js_buffer_from_arraybuffer_slice(i64, i32, i32)
+declare i32 @js_buffer_length(i64)
+declare i32 @js_buffer_get(i64, i32)
+declare double @js_buffer_index_get_value(i64, i32)
+declare ptr @js_native_buffer_data_ptr(double)
+declare i64 @js_native_buffer_byte_len(double)
+declare void @js_console_time(i64)
+declare void @js_console_time_end(i64)
+declare void @js_console_time_log(i64)
+declare void @js_console_time_value(double)
+declare void @js_console_time_end_value(double)
+declare void @js_console_time_log_value(double)
+declare void @js_console_time_log_spread(double, i64)
+declare void @js_console_count(i64)
+declare void @js_console_count_reset(i64)
+declare void @js_console_count_value(double)
+declare void @js_console_count_reset_value(double)
+declare double @js_console_new(double)
+declare double @js_console_new2(double, double)
+declare void @js_console_group_begin()
+declare void @js_console_group_end()
+declare void @js_console_clear()
+declare void @js_console_noop()
+declare double @js_native_call_method(double, ptr, i64, ptr, i64)
+declare double @js_native_call_method_by_id(double, i64, ptr, i64)
+declare double @js_native_call_method_apply(double, ptr, i64, i64)
+declare double @js_native_call_method_apply_by_id(double, i64, i64)
+declare double @js_native_call_method_str_key(double, i64, ptr, i64)
+declare double @js_native_call_method_value(double, double, ptr, i64)
+declare double @js_native_call_method_value_apply(double, double, i64)
+declare void @js_promise_resolve(i64, double)
+declare void @js_promise_reject(i64, double)
+declare void @js_promise_mark_internally_handled(i64)
+declare i64 @js_promise_resolved(double)
+declare i64 @js_async_fn_result(double)
+declare i64 @js_promise_rejected(double)
+declare double @js_create_namespace(i32, ptr, ptr, ptr)
+declare i64 @js_promise_then(i64, i64, i64)
+declare i64 @js_promise_resolved_then(double, i64, i64)
+declare i64 @js_promise_finally(i64, i64)
+declare double @js_promise_then_checked(double, double, double)
+declare double @js_promise_catch_checked(double, double)
+declare double @js_promise_finally_checked(double, double)
+declare i64 @js_promise_closure_arg(double)
+declare i64 @js_promise_all(i64)
+declare i64 @js_promise_race(i64)
+declare i64 @js_promise_any(i64)
+declare i64 @js_promise_all_settled(i64)
+declare i64 @js_promise_all_iterable(double)
+declare i64 @js_promise_race_iterable(double)
+declare i64 @js_promise_any_iterable(double)
+declare i64 @js_promise_all_settled_iterable(double)
+declare i64 @js_promise_with_resolvers()
+declare i64 @js_promise_try(double, i64)
+declare i64 @js_array_unshift_f64(i64, double)
+declare i64 @js_array_unshift_variadic(i64, ptr, i32)
+declare i64 @js_array_entries(i64)
+declare i64 @js_array_keys(i64)
+declare i64 @js_array_values(i64)
+declare i64 @js_array_entries_iter_obj(i64)
+declare i64 @js_array_keys_iter_obj(i64)
+declare i64 @js_array_values_iter_obj(i64)
+declare double @js_response_new(i64, double, i64, double)
+declare i64 @js_response_body_init_ptr(double)
+declare double @js_headers_new()
+declare double @js_headers_set(double, i64, i64)
+declare double @js_headers_append(double, i64, i64)
+declare i64 @js_headers_get(double, i64)
+declare double @js_headers_get_set_cookie(double)
+declare double @js_headers_has(double, i64)
+declare double @js_headers_delete(double, i64)
+declare double @js_headers_for_each(double, double)
+declare double @js_headers_keys(double)
+declare double @js_headers_values(double)
+declare double @js_headers_entries(double)
+declare double @js_headers_init_from_value(double, double)
+declare double @js_headers_method_value(double, i64, i64)
+declare double @js_request_new(i64, i64, i64, double, i64, i64, i64, i64, i64, i64, i64, double, i64, double)
+declare double @js_request_new_from_init(i64, double)
+declare i64 @js_request_get_url(double)
+declare i64 @js_request_input_to_url(double)
+declare i64 @js_request_get_method(double)
+declare double @js_request_get_body(double)
+declare double @js_request_body_used(double)
+declare i64 @js_request_get_destination(double)
+declare i64 @js_request_get_referrer(double)
+declare i64 @js_request_get_referrer_policy(double)
+declare i64 @js_request_get_mode(double)
+declare i64 @js_request_get_credentials(double)
+declare i64 @js_request_get_cache(double)
+declare i64 @js_request_get_redirect(double)
+declare i64 @js_request_get_integrity(double)
+declare double @js_request_get_keepalive(double)
+declare i64 @js_request_get_duplex(double)
+declare double @js_request_get_signal(double)
+declare double @js_request_get_headers(double)
+declare i64 @js_request_text(double)
+declare i64 @js_request_json(double)
+declare i64 @js_request_array_buffer(double)
+declare i64 @js_request_blob(double)
+declare i64 @js_request_bytes(double)
+declare i64 @js_request_form_data(double)
+declare double @js_request_clone(double)
+declare double @js_fetch_response_status(double)
+declare i64 @js_fetch_response_status_text(double)
+declare double @js_fetch_response_ok(double)
+declare i64 @js_fetch_response_type(double)
+declare i64 @js_fetch_response_url(double)
+declare double @js_fetch_response_redirected(double)
+declare double @js_response_body_used(double)
+declare i64 @js_fetch_response_text(double)
+declare i64 @js_fetch_response_json(double)
+declare double @js_response_get_headers(double)
+declare double @js_response_clone(double)
+declare i64 @js_response_array_buffer(double)
+declare i64 @js_response_blob(double)
+declare i64 @js_response_bytes(double)
+declare i64 @js_response_form_data(double)
+declare double @js_form_data_new()
+declare double @js_form_data_append(double, double, double)
+declare double @js_form_data_set(double, double, double)
+declare double @js_form_data_delete(double, i64)
+declare double @js_form_data_get(double, i64)
+declare double @js_form_data_get_all(double, i64)
+declare double @js_form_data_has(double, i64)
+declare double @js_form_data_entries(double)
+declare double @js_form_data_keys(double)
+declare double @js_form_data_values(double)
+declare double @js_form_data_for_each(double, double)
+declare double @js_blob_size(double)
+declare i64 @js_blob_type(double)
+declare i64 @js_blob_array_buffer(double)
+declare i64 @js_blob_bytes(double)
+declare i64 @js_blob_text(double)
+declare double @js_blob_slice(double, double, double, i64)
+declare double @js_blob_new(double, double)
+declare double @js_file_new(double, double, double, double)
+declare i64 @js_file_name(double)
+declare double @js_file_last_modified(double)
+declare i64 @js_url_create_object_url(double)
+declare void @js_url_revoke_object_url(double)
+declare double @js_buffer_resolve_object_url(double)
+declare double @js_response_static_json(double, double, i64, double)
+declare double @js_response_static_redirect(i64, double)
+declare double @js_response_static_error()
+declare double @js_blob_stream(double)
+declare double @js_response_body(double)
+declare double @js_readable_stream_new(double, double, double, double)
+declare double @js_readable_stream_new_with_source_type(double, double, double, double, double)
+declare double @js_readable_stream_new_with_strategy_and_source_type(double, double, double, double, double)
+declare double @js_readable_stream_new_from_source_object(double, double)
+declare double @js_readable_stream_get_reader(double)
+declare double @js_readable_stream_get_reader_with_options(double, double)
+declare double @js_readable_stream_get_byob_reader(double)
+declare double @js_readable_stream_controller_byob_request(double)
+declare double @js_readable_stream_from_iterable(double)
+declare double @js_readable_stream_locked(double)
+declare i64 @js_readable_stream_cancel(double, double)
+declare double @js_readable_stream_tee(double)
+declare i64 @js_readable_stream_pipe_to(double, double, double)
+declare double @js_readable_stream_pipe_through(double, double, double)
+declare double @js_readable_stream_pipe_through_validate(double, double, double, double)
+declare double @js_readable_stream_controller_enqueue(double, double)
+declare double @js_readable_stream_controller_close(double)
+declare double @js_readable_stream_controller_error(double, double)
+declare double @js_readable_stream_controller_desired_size(double)
+declare i64 @js_reader_read(double)
+declare i64 @js_reader_read_with_view(double, double)
+declare double @js_reader_release_lock(double)
+declare i64 @js_reader_closed(double)
+declare i64 @js_reader_cancel(double, double)
+declare double @js_writable_stream_new(double, double, double, double, double)
+declare double @js_writable_stream_new_with_sink_type(double, double, double, double, double, double)
+declare double @js_writable_stream_new_from_sink_object(double, double)
+declare double @js_writable_stream_throw_invalid_sink()
+declare double @js_writable_stream_get_writer(double)
+declare double @js_writable_stream_locked(double)
+declare i64 @js_writable_stream_close(double)
+declare i64 @js_writable_stream_abort(double, double)
+declare i64 @js_writer_write(double, double)
+declare i64 @js_writer_close(double)
+declare i64 @js_writer_abort(double, double)
+declare double @js_writer_release_lock(double)
+declare i64 @js_writer_closed(double)
+declare i64 @js_writer_ready(double)
+declare double @js_writer_desired_size(double)
+declare double @js_transform_stream_new(double, double, double, double, double)
+declare double @js_transform_stream_new_from_transformer_object(double, double, double)
+declare double @js_transform_stream_readable(double)
+declare double @js_transform_stream_writable(double)
+declare double @js_text_encoding_stream_new()
+declare double @js_text_encoder_stream_new()
+declare double @js_text_decoder_stream_new()
+declare double @js_stream_web_text_encoder_stream_new()
+declare double @js_stream_web_text_decoder_stream_new(double, double)
+declare double @js_stream_web_compression_stream_new(double)
+declare double @js_stream_web_decompression_stream_new(double)
+declare double @js_streams_strategy_high_water_mark(double)
+declare double @js_count_queuing_strategy_new(double)
+declare double @js_byte_length_queuing_strategy_new(double)
+declare double @js_stream_unwrap_handle(double)
+declare double @js_readable_stream_subclass_init(double, double, double, double, double)
+declare double @js_writable_stream_subclass_init(double, double, double, double, double)
+declare double @js_transform_stream_subclass_init(double, double, double, double)
+declare double @js_request_subclass_init(double, double, double)
+declare double @js_response_subclass_init(double, double, double)
+declare double @js_fetch_or_value_super(double, double, ptr, i64)
+declare i64 @js_abort_controller_new()
+declare i64 @js_abort_controller_signal(i64)
+declare void @js_abort_controller_abort(i64)
+declare void @js_abort_controller_abort_reason(i64, double)
+declare void @js_abort_signal_add_listener(i64, double, double)
+declare i64 @js_abort_signal_timeout(double)
+declare i64 @js_abort_signal_abort(double)
+declare i64 @js_abort_signal_any(i64)
+declare double @js_abort_signal_throw_if_aborted(i64)
+declare i64 @js_event_target_new()
+declare i64 @js_event_new(double, double, i32)
+declare double @js_event_subclass_init(double, double, double, i32, i32)
+declare i64 @js_custom_event_new(double, double, i32)
+declare i64 @js_dom_exception_new(double, double)
+declare double @js_dom_exception_subclass_init(double, double, double)
+declare void @js_event_target_add_event_listener(i64, i64, i64)
+declare void @js_event_target_add_event_listener_with_options(i64, i64, i64, double)
+declare void @js_event_target_remove_event_listener(i64, i64, i64)
+declare void @js_event_target_remove_event_listener_with_options(i64, i64, i64, double)
+declare double @js_event_target_dispatch_event(i64, double)
+declare i32 @js_event_target_is_event_target(i64)
+declare i64 @js_event_target_get_event_listeners(i64, i64)
+declare double @js_event_target_get_max_listeners(i64)
+declare i32 @js_event_target_set_max_listeners(i64, double)
+declare double @js_message_channel_new()
+declare double @js_message_port_constructor_error()
+declare double @js_broadcast_channel_new(double)
+declare i64 @js_array_alloc(i32)
+declare i64 @js_tagged_template_register_raw(i64, i64)
+declare i64 @js_tagged_template_get_or_init(i64, i64, i64)
+declare i64 @js_template_raw(i64)
+declare i64 @js_array_create()
+declare i64 @js_array_constructor_single(double)
+declare i64 @js_array_alloc_literal(i32)
+declare i64 @js_array_from_values(ptr, i32)
+declare i64 @js_array_push_f64(i64, double)
+declare void @js_array_push_guard(i64)
+declare i64 @js_array_push_hole(i64)
+declare i64 @js_array_numeric_push_f64_unboxed(i64, double)
+declare i64 @js_array_push_spread_f64(i64, i64)
+declare double @js_array_get_f64(i64, i32)
+declare double @js_array_get_index_or_string(i64, double)
+declare double @js_array_numeric_get_f64_unboxed(i64, i32)
+declare void @js_array_set_f64(i64, i32, double)
+declare i32 @js_array_numeric_set_f64_unboxed(i64, i32, double)
+declare i64 @js_array_set_f64_extend(i64, i32, double)
+declare i64 @js_array_set_f64_extend_strict(i64, i32, double)
+declare i64 @js_array_fill_f64_const_extend(i64, i32, double)
+declare i64 @js_array_fill_f64_iota_extend(i64, i32)
+declare i64 @js_array_fill_f64_const_len_extend(i64, double)
+declare i64 @js_array_fill_f64_iota_len_extend(i64)
+declare i64 @js_array_numeric_range_add(double, double, double, double)
+declare i64 @js_array_numeric_range_add_len(double, double, double)
+declare i64 @js_array_set_string_key(i64, i64, double)
+declare i64 @js_array_set_index_or_string(i64, double, double)
+declare i64 @js_array_mark_arguments_object(i64)
+declare i32 @js_array_mark_numeric_f64_layout(i64)
+declare i32 @js_array_is_numeric_f64_layout(i64)
+declare void @js_array_clear_numeric_layout(i64)
+declare double @js_array_numeric_value_to_raw_f64(double) #4
+declare double @js_array_refresh_local_head(double)
+declare void @js_array_note_numeric_write(i64, i64)
+declare i32 @js_array_length(i64)
+declare double @js_array_is_array(double)
+declare double @js_value_length_f64(double)
+declare nonnull ptr @js_shadow_frame_enter(i32)
+declare i64 @js_shadow_frame_push(i32)
+declare void @js_shadow_frame_pop(i64)
+declare void @js_shadow_slot_set(i32, i64)
+declare void @js_shadow_slot_bind(i32, ptr)
+declare void @js_gc_write_barriers_emitted(i32)
+declare i32 @js_gc_temp_root_push(i64)
+declare i64 @js_gc_temp_root_get(i32)
+declare void @js_gc_temp_root_set(i32, i64)
+declare void @js_gc_temp_root_truncate(i32)
+declare void @js_array_push_f64_temp_rooted(i32, double)
+declare void @js_gc_loop_safepoint()
+declare void @js_write_barrier(i64, i64)
+declare void @js_write_barrier_slot(i64, i64, i64)
+declare void @js_write_barrier_root_nanbox(i64)
+declare void @js_write_barrier_root_heap_word(i64)
+declare void @js_gc_note_slot_layout(i64, i32, i64)
+declare void @js_gc_note_slot_layout_aware(i64, i32, i64, i64)
+declare void @js_gc_init_typed_shape_layout(i64, i32, ptr, i32, ptr, i32)
+declare void @js_gc_init_unboxed_object_layout(i64, i32, i64, i64)
+declare double @js_array_pop_f64(i64)
+declare i64 @js_array_join(i64, i64)
+declare i64 @js_array_join_value(i64, double)
+declare void @js_array_forEach(i64, i64)
+declare i64 @js_array_fill(i64, double)
+declare i64 @js_array_fill_range(i64, double, double, double)
+declare double @js_array_fill_generic(double, double, i32, double, i32, double)
+declare i32 @js_array_delete(i64, i32)
+declare void @js_array_set_length(i64, double)
+declare void @js_array_set_length_strict(i64, double)
+declare i64 @js_array_clone(i64)
+declare i64 @js_array_from_value(double)
+declare i64 @js_array_from_arraylike_holey_value(double)
+declare double @js_iterator_from(double)
+declare i64 @js_array_from_mapped(double, double, double)
+declare i64 @js_array_concat_variadic(i64, ptr, i32)
+declare double @js_arraylike_forEach(double, double, double)
+declare double @js_arraylike_map(double, double, double)
+declare double @js_arraylike_filter(double, double, double)
+declare double @js_arraylike_some(double, double, double)
+declare double @js_arraylike_every(double, double, double)
+declare double @js_arraylike_find(double, double, double)
+declare double @js_arraylike_findIndex(double, double, double)
+declare double @js_arraylike_findLast(double, double, double)
+declare double @js_arraylike_findLastIndex(double, double, double)
+declare double @js_arraylike_reduce(double, double, i32, double)
+declare double @js_arraylike_reduceRight(double, double, i32, double)
+declare double @js_arraylike_indexOf(double, double, double, i32)
+declare double @js_arraylike_lastIndexOf(double, double, double, i32)
+declare double @js_arraylike_includes(double, double, double, i32)
+declare double @js_arraylike_at(double, double)
+declare double @js_arraylike_join(double, double)
+declare double @js_arraylike_slice(double, double, i32, double, i32)
+declare double @js_arraylike_sort(double, double)
+declare double @js_arraylike_splice(double, ptr, i32)
+declare double @js_arraylike_concat(double, ptr, i32)
+declare double @js_arraylike_pop(double)
+declare double @js_arraylike_shift(double)
+declare double @js_arraylike_push(double, ptr, i32)
+declare double @js_arraylike_unshift(double, ptr, i32)
+declare i64 @js_array_clone_for_spread(double)
+declare i64 @js_array_spread_append(i64, double)
+declare i64 @js_iterator_to_array(double)
+declare double @js_iterator_next_result(double)
+declare double @js_iterator_close_if_not_done(double, double)
+declare double @js_iterator_rest_to_array(double, double)
+declare double @js_get_iterator(double)
+declare double @js_get_async_iterator(double)
+declare double @js_for_of_to_array(double)
+declare i64 @js_object_alloc(i32, i32)
+declare double @js_object_coerce(double)
+declare void @js_object_mark_class(i64)
+declare void @js_class_object_pin_parent(i64, i32)
+declare i64 @js_object_alloc_with_shape(i32, i32, ptr, i32)
+declare void @js_object_set_field(i64, i32, i64)
+declare void @js_object_set_unboxed_f64_field(i64, i32, double)
+declare double @js_object_get_unboxed_f64_field(i64, i32)
+declare void @js_object_set_field_by_name(i64, i64, double)
+declare void @js_object_set_field_by_property_id(i64, i64, double)
+declare void @js_object_set_field_by_name_nonenum(i64, i64, double)
+declare void @js_error_subclass_default_init(double, double, i64)
+declare void @js_object_set_field_by_name_nonconfigurable(i64, i64, double)
+declare void @js_error_apply_cause_to_object(i64, double)
+declare i32 @js_with_has_binding(double, i64)
+declare double @js_with_get_binding(double, i64)
+declare double @js_with_set_binding(double, i64, double, i32)
+declare i32 @js_with_delete_binding(double, i64)
+declare i32 @js_pod_scalar_write_compatible(double, i32)
+declare void @js_typed_feedback_register_site(i64, i32, ptr, i64, ptr, i64, ptr, i64, ptr, i64, ptr, i64, ptr, i64)
+declare void @js_typed_feedback_record_guard_pass(i64)
+declare void @js_typed_feedback_record_guard_fail(i64)
+declare void @js_typed_feedback_record_fallback_call(i64)
+declare void @js_typed_feedback_observe_property_get(i64, i64, i64)
+declare void @js_typed_feedback_observe_property_set(i64, i64, i64)
+declare double @js_typed_feedback_object_get_field_by_name_f64(i64, i64, i64)
+declare void @js_typed_feedback_object_set_field_by_name(i64, i64, i64, double)
+declare void @js_typed_feedback_object_set_field_by_name_fast(i64, i64, i64, double)
+declare i32 @js_typed_feedback_class_field_set_guard(i64, double, i32, i64, i64, i32, double, i32)
+declare void @js_class_field_set_fallback(i64, i64, i64, double)
+declare void @js_class_field_set_ic(i64, double, i32, i64, i64, i32, double, i32)
+declare i32 @js_typed_feedback_class_field_get_guard(i64, double, i32, i64, i64, i32, i32)
+declare double @js_class_field_get_ic(i64, double, i32, i64, i64, i32, i32)
+declare double @js_typed_feedback_native_call_method(i64, double, ptr, i64, ptr, i64)
+declare double @js_typed_feedback_native_call_method_by_id(i64, double, i64, ptr, i64)
+declare double @js_typed_feedback_native_call_method_apply(i64, double, ptr, i64, i64)
+declare double @js_typed_feedback_native_call_method_apply_by_id(i64, double, i64, i64)
+declare i32 @js_typed_feedback_method_direct_call_guard(i64, double, i32, i64, ptr, i64, ptr)
+declare i32 @js_method_direct_shape_guard(double, i32, i64)
+declare i32 @js_typed_feedback_closure_direct_call_guard(i64, double, ptr, i32, i32)
+declare void @js_typed_feedback_object_set_unboxed_f64_field(i64, i64, i32, i64, double)
+declare double @js_typed_feedback_observe_helper_return(i64, double)
+declare void @js_object_set_index_polymorphic(i64, double, double)
+declare double @js_object_get_index_polymorphic(i64, double)
+declare double @js_object_get_field_by_name_f64(i64, i64)
+declare double @js_object_get_field_by_name_boxed(double, i64)
+declare double @js_object_get_field_by_property_id_f64(i64, i64)
+declare double @js_native_module_property_by_name(ptr, i64, ptr, i64)
+declare double @js_create_native_module_namespace(ptr, i64)
+declare void @js_nm_install_assert()
+declare void @js_nm_install_async_hooks()
+declare void @js_nm_install_bigint()
+declare void @js_nm_install_buffer()
+declare void @js_nm_install_bun()
+declare void @js_nm_install_bun_ffi()
+declare void @js_nm_install_child_process()
+declare void @js_nm_install_cluster()
+declare void @js_nm_install_console()
+declare void @js_nm_install_crypto()
+declare void @js_nm_install_dgram()
+declare void @js_nm_install_dns()
+declare void @js_nm_install_domain()
+declare void @js_nm_install_events()
+declare void @js_nm_install_fs()
+declare void @js_nm_install_http()
+declare void @js_nm_install_inspector()
+declare void @js_nm_install_module()
+declare void @js_nm_install_net()
+declare void @js_nm_install_node_pty()
+declare void @js_nm_install_os()
+declare void @js_nm_install_path()
+declare void @js_nm_install_perf()
+declare void @js_nm_install_process()
+declare void @js_nm_install_punycode()
+declare void @js_nm_install_querystring()
+declare void @js_nm_install_readline()
+declare void @js_nm_install_repl()
+declare void @js_nm_install_sea()
+declare void @js_nm_install_sqlite()
+declare void @js_nm_install_stream()
+declare void @js_nm_install_timers()
+declare void @js_nm_install_tls()
+declare void @js_nm_install_tty()
+declare void @js_nm_install_url()
+declare void @js_nm_install_util()
+declare void @js_nm_install_v8()
+declare void @js_nm_install_vm()
+declare void @js_nm_install_wasi()
+declare void @js_nm_install_zlib()
+declare void @js_nm_install_all()
+declare double @js_object_get_field_ic_miss(i64, i64, ptr)
+declare double @js_object_get_field_ic(i64, i64, i64, ptr)
+declare i64 @js_object_rest(i64, i64)
+declare double @js_require_object_coercible(double)
+declare double @js_require_json_disk(double)
+declare double @js_require_resolve_node_modules(double, double)
+declare void @js_globalthis_seed_async_local_storage()
+declare void @js_register_path_module(double, double)
+declare double @js_require_path_module(double)
+declare void @js_register_path_init(ptr, i64, i64)
+declare i64 @js_array_alloc_with_length(i32)
+declare void @js_array_set_f64_unchecked(i64, i32, double)
+declare double @js_typed_feedback_array_get_f64(i64, i64, i32)
+declare i32 @js_typed_feedback_plain_array_index_get_guard(i64, double, i32, i32) #4
+declare i32 @js_typed_feedback_numeric_array_index_get_guard(i64, double, i32, i32) #4
+declare i32 @js_typed_feedback_packed_f64_array_loop_guard(i64, double)
+declare i32 @js_typed_feedback_packed_f64_range_loop_guard(i64, double, i32, i32)
+declare i32 @js_typed_feedback_packed_f64_range_loop_guard_dense(i64, double, i32, i32)
+declare i32 @js_typed_feedback_packed_f64_range_loop_guard_dense_i32(i64, double, i32, i32)
+declare i32 @js_typed_feedback_masked_window_ta_kind(i64, double, i32, i32)
+declare i64 @js_typed_array_masked_window_data_ptr(double)
+declare i32 @js_typed_feedback_packed_u32_array_loop_guard(i64, double)
+declare double @js_typed_feedback_array_index_get_fallback_boxed(i64, double, double)
+declare void @js_typed_feedback_array_set_f64(i64, i64, i32, double)
+declare i64 @js_typed_feedback_array_set_f64_extend(i64, i64, i32, double)
+declare i32 @js_typed_feedback_plain_array_index_set_guard(i64, double, i32, double, i32) #4
+declare i32 @js_typed_feedback_numeric_array_index_set_guard(i64, double, i32, double, i32) #4
+declare i32 @js_typed_feedback_numeric_array_push_guard(i64, double, double) #4
+declare double @js_typed_feedback_array_index_set_fallback_boxed(i64, double, double, double)
+declare void @js_typed_feedback_observe_array_element(i64, i64, i32)
+declare i64 @js_typed_feedback_array_set_string_key(i64, i64, i64, double)
+declare i64 @js_typed_feedback_array_set_index_or_string(i64, i64, double, double)
+declare void @js_typed_feedback_object_set_index_polymorphic(i64, i64, double, double)
+declare double @js_proxy_new(double, double)
+declare double @js_proxy_revocable(double, double)
+declare void @js_proxy_revoke(double)
+declare i32 @js_proxy_is_revoked(double)
+declare i32 @js_proxy_is_proxy(double)
+declare double @js_proxy_target(double)
+declare double @js_proxy_get(double, double)
+declare double @js_proxy_set(double, double, double)
+declare double @js_proxy_has(double, double)
+declare double @js_proxy_delete(double, double)
+declare double @js_proxy_apply(double, double, double)
+declare double @js_proxy_construct(double, double, double)
+declare double @js_reflect_construct(double, double, double)
+declare double @js_reflect_get(double, double, double)
+declare double @js_reflect_set(double, double, double, double)
+declare double @js_put_value_set(double, double, double, double, i32)
+declare double @js_put_value_set_dyn_ic(ptr, double, double, double, i32)
+declare double @js_put_value_set_ic_miss(double, i64, double, i32, ptr)
+declare i64 @js_object_array_numeric_write_guard(double, double, double, double, double, i32, i32)
+declare double @js_super_put_value_set(i32, double, double, double, i32)
+declare double @js_super_accessor_get(i32, double, double)
+declare double @js_reflect_has(double, double)
+declare double @js_reflect_delete(double, double)
+declare double @js_reflect_own_keys(double)
+declare double @js_reflect_apply(double, double, double)
+declare double @js_reflect_define_property(double, double, double)
+declare double @js_reflect_get_own_property_descriptor(double, double)
+declare double @js_reflect_get_prototype_of(double)
+declare double @js_reflect_set_prototype_of(double, double)
+declare double @js_reflect_is_extensible(double)
+declare double @js_reflect_prevent_extensions(double)
+declare double @js_reflect_define_metadata(double, double, double, double)
+declare double @js_reflect_get_metadata(double, double, double)
+declare double @js_reflect_get_own_metadata(double, double, double)
+declare double @js_reflect_has_metadata(double, double, double)
+declare double @js_reflect_has_own_metadata(double, double, double)
+declare double @js_reflect_get_metadata_keys(double, double)
+declare double @js_reflect_get_own_metadata_keys(double, double)
+declare double @js_reflect_delete_metadata(double, double, double)
+declare double @js_http_server_construct_with_this(double, double, double)
+declare double @js_https_server_construct_with_this(double, double, double)
+declare i64 @js_net_socket_set_encoding(i64, i64)
+declare double @js_vm_create_context(double)
+declare double @js_vm_module_call()
+declare double @js_vm_module_constructor_error()
+declare double @js_repl_start(double)
+declare double @js_repl_repl_server_new(double)
+declare double @js_repl_recoverable_new(double)
+declare double @js_worker_threads_worker_new(i64, double)
+declare double @js_worker_threads_worker_post_message(i64, double)
+declare double @js_worker_threads_worker_on(i64, double, i64)
+declare double @js_worker_threads_worker_once(i64, double, i64)
+declare double @js_worker_threads_worker_off(i64, double, i64)
+declare double @js_worker_threads_worker_add_event_listener(i64, double, i64)
+declare double @js_worker_threads_worker_remove_event_listener(i64, double, i64)
+declare double @js_worker_threads_worker_terminate(i64)
+declare double @js_worker_threads_worker_ref(i64)
+declare double @js_worker_threads_worker_unref(i64)
+declare double @js_worker_threads_worker_get_heap_statistics(i64)
+declare double @js_worker_threads_worker_cpu_usage(i64, double)
+declare double @js_worker_threads_worker_get_heap_snapshot(i64, double)
+declare double @js_worker_threads_worker_start_cpu_profile(i64)
+declare double @js_worker_threads_worker_start_heap_profile(i64)
+declare i64 @js_http_client_request_end(i64, double)
+declare i64 @js_http_client_request_write(i64, double)
+declare i64 @js_http_client_request_end_full(i64, double, i64, i64)
+declare double @js_http_client_request_write_full(i64, double, i64, i64)
+declare i64 @js_http_set_timeout_full(i64, double, i64)
+declare i64 @js_http_client_request_method(i64)
+declare i64 @js_http_client_request_protocol(i64)
+declare i64 @js_http_client_request_host(i64)
+declare i64 @js_http_client_request_path(i64)
+declare double @js_http_client_request_listener_count(i64, i64)
+declare double @js_http_client_request_get_header(i64, i64)
+declare double @js_http_client_request_has_header(i64, i64)
+declare double @js_http_client_request_remove_header(i64, i64)
+declare double @js_http_client_request_get_header_names(i64)
+declare double @js_http_client_request_get_headers(i64)
+declare double @js_http_client_request_get_raw_header_names(i64)
+declare double @js_http_client_request_abort(i64)
+declare i64 @js_http_client_request_destroy(i64, double)
+declare double @js_http_client_request_noop_undefined(i64, double, double)
+declare double @js_http_client_request_aborted(i64)
+declare double @js_http_client_request_destroyed(i64)
+declare double @js_http_client_request_finished(i64)
+declare double @js_http_client_request_reused_socket(i64)
+declare double @js_http_client_request_max_headers_count(i64)
+declare double @js_http_client_request_writable_ended(i64)
+declare double @js_http_client_request_writable_finished(i64)
+declare double @js_http_client_request_socket(i64)
+declare i64 @js_http_get(double, i64)
+declare i64 @js_http_get_overload(i64)
+declare i64 @js_http_request_overload(i64)
+declare i64 @js_https_get_overload(i64)
+declare i64 @js_https_request_overload(i64)
+declare i64 @js_http_on(i64, i64, i64)
+declare i64 @js_http_request(double, i64)
+declare i64 @js_http_request_body(i64)
+declare double @js_http_request_body_length(i64)
+declare i64 @js_http_request_content_type(i64)
+declare double @js_http_request_has_header(i64, i64)
+declare i64 @js_http_request_header(i64, i64)
+declare i64 @js_http_request_headers_all(i64)
+declare double @js_http_request_id(i64)
+declare double @js_http_request_is_method(i64, i64)
+declare i64 @js_http_request_method(i64)
+declare i64 @js_http_request_path(i64)
+declare i64 @js_http_request_query(i64)
+declare i64 @js_http_request_query_all(i64)
+declare i64 @js_http_request_query_param(i64, i64)
+declare double @js_http_respond_error(i64, double, i64)
+declare double @js_http_respond_html(i64, double, i64)
+declare double @js_http_respond_json(i64, double, i64)
+declare double @js_http_respond_not_found(i64)
+declare double @js_http_respond_redirect(i64, i64, double)
+declare i64 @js_http_respond_status_text(double)
+declare double @js_http_respond_text(i64, double, i64)
+declare double @js_http_respond_with_headers(i64, double, i64, i64)
+declare double @js_http_response_headers(i64)
+declare double @js_http_response_trailers(i64)
+declare i64 @js_http_incoming_message_set_encoding(i64, i64)
+declare i64 @js_http_server_accept_v2(i64)
+declare double @js_http_server_close(i64)
+declare i64 @js_http_server_create(double)
+declare i64 @js_http_set_header(i64, i64, i64)
+declare i64 @js_http_set_timeout(i64, double)
+declare double @js_http_status_code(i64)
+declare i64 @js_http_status_message(i64)
+declare i64 @js_http_agent_new(double)
+declare i64 @js_https_agent_new(double)
+declare i64 @js_http_agent_get_name(i64, double)
+declare i64 @js_http_agent_noop_self(i64)
+declare double @js_http_agent_max_sockets(i64)
+declare double @js_http_agent_max_free_sockets(i64)
+declare double @js_http_agent_max_total_sockets(i64)
+declare double @js_http_agent_keep_alive_msecs(i64)
+declare double @js_http_agent_keep_alive(i64)
+declare i64 @js_http_agent_protocol(i64)
+declare double @js_http_agent_default_port(i64)
+declare void @js_http_agent_set_protocol(i64, i64)
+declare i64 @js_http_agent_destroy(i64)
+declare double @js_http_agent_destroyed(i64)
+declare double @js_http_agent_sockets(i64)
+declare double @js_http_agent_free_sockets(i64)
+declare double @js_http_agent_requests(i64)
+declare void @js_http_agent_set_max_sockets(i64, double)
+declare void @js_http_agent_set_max_free_sockets(i64, double)
+declare void @js_http_agent_set_max_total_sockets(i64, double)
+declare void @js_http_agent_set_keep_alive(i64, double)
+declare void @js_http_agent_set_keep_alive_msecs(i64, double)
+declare void @js_http_agent_set_create_connection(i64, i64)
+declare void @js_http_agent_set_create_socket(i64, i64)
+declare i64 @js_http_agent_create_connection(i64)
+declare i64 @js_http_agent_create_socket(i64)
+declare i64 @js_https_get(double, i64)
+declare i64 @js_https_request(double, i64)
+declare i64 @js_node_http_create_server(i64)
+declare i64 @js_node_http_server_listen(i64, i64)
+declare void @js_node_http_server_close(i64, i64)
+declare void @js_node_http_server_close_all_connections(i64)
+declare void @js_node_http_server_close_idle_connections(i64)
+declare i64 @js_node_http_server_address_json(i64)
+declare i32 @js_node_http_server_listening(i64)
+declare double @js_node_http_server_listening_value(i64)
+declare double @js_node_http_server_on(i64, i64, i64)
+declare i64 @js_node_http_im_method(i64)
+declare i64 @js_node_http_im_url(i64)
+declare i64 @js_node_http_im_http_version(i64)
+declare i64 @js_node_http_im_headers_json(i64)
+declare i64 @js_node_http_im_raw_headers_json(i64)
+declare i64 @js_node_http_im_headers_distinct_json(i64)
+declare i64 @js_node_http_im_trailers_json(i64)
+declare i64 @js_node_http_im_raw_trailers_json(i64)
+declare i64 @js_node_http_im_trailers_distinct_json(i64)
+declare i32 @js_node_http_im_complete(i64)
+declare i32 @js_node_http_im_aborted(i64)
+declare i32 @js_node_http_im_destroyed(i64)
+declare i64 @js_node_http_im_remote_address(i64)
+declare double @js_node_http_im_remote_port(i64)
+declare void @js_node_http_im_pause(i64)
+declare void @js_node_http_im_resume(i64)
+declare void @js_node_http_im_destroy(i64)
+declare double @js_node_http_im_on(i64, i64, i64)
+declare double @js_node_http_im_read(i64)
+declare i64 @js_node_http_im_set_timeout(i64, double, i64)
+declare void @js_node_http_res_set_status(i64, double)
+declare double @js_node_http_res_get_status(i64)
+declare void @js_node_http_res_set_status_message(i64, i64)
+declare void @js_node_http_res_set_header(i64, i64, double)
+declare i64 @js_node_http_res_set_header_self(i64, i64, double)
+declare double @js_node_http_res_get_header(i64, i64)
+declare void @js_node_http_res_remove_header(i64, i64)
+declare i32 @js_node_http_res_has_header(i64, i64)
+declare double @js_node_http_res_has_header_value(i64, i64)
+declare i64 @js_node_http_res_get_headers_json(i64)
+declare i64 @js_node_http_res_get_header_names_json(i64)
+declare i64 @js_node_http_res_append_header(i64, i64, i64)
+declare i64 @js_node_http_res_set_headers(i64, double)
+declare double @js_node_http_res_get_status_message(i64)
+declare i32 @js_node_http_res_headers_sent(i64)
+declare i32 @js_node_http_res_writable_ended(i64)
+declare i32 @js_node_http_res_writable_finished(i64)
+declare i32 @js_node_http_res_finished(i64)
+declare i32 @js_node_http_res_send_date(i64)
+declare void @js_node_http_res_set_send_date(i64, double)
+declare i32 @js_node_http_res_strict_content_length(i64)
+declare void @js_node_http_res_set_strict_content_length(i64, double)
+declare i64 @js_node_http_res_req_handle(i64)
+declare void @js_node_http_res_write_head(i64, double, i64, i64)
+declare i32 @js_node_http_res_write(i64, double)
+declare double @js_node_http_res_write_full(i64, double, i64, i64)
+declare void @js_node_http_res_add_trailers(i64, double)
+declare void @js_node_http_res_end(i64, double)
+declare void @js_node_http_res_end_full(i64, double, i64, i64)
+declare void @js_node_http_res_flush_headers(i64)
+declare void @js_node_http_res_cork(i64)
+declare void @js_node_http_res_uncork(i64)
+declare i64 @js_node_http_res_set_timeout(i64, double, i64)
+declare void @js_node_http_res_write_early_hints(i64, double, i64)
+declare void @js_node_http_res_write_continue(i64)
+declare void @js_node_http_res_write_processing(i64)
+declare double @js_node_http_res_on(i64, i64, i64)
+declare i64 @js_node_https_create_server(double, i64)
+declare i64 @js_node_https_server_listen(i64, i64)
+declare void @js_node_https_server_close(i64, i64)
+declare void @js_node_https_server_close_all_connections(i64)
+declare void @js_node_https_server_close_idle_connections(i64)
+declare i64 @js_node_https_server_address_json(i64)
+declare double @js_node_https_server_on(i64, i64, i64)
+declare double @js_node_https_server_listening_value(i64)
+declare double @js_node_https_server_headers_timeout(i64)
+declare double @js_node_https_server_set_headers_timeout(i64, double)
+declare double @js_node_https_server_keep_alive_timeout(i64)
+declare double @js_node_https_server_set_keep_alive_timeout(i64, double)
+declare double @js_node_https_server_keep_alive_timeout_buffer(i64)
+declare double @js_node_https_server_set_keep_alive_timeout_buffer(i64, double)
+declare double @js_node_https_server_request_timeout(i64)
+declare double @js_node_https_server_set_request_timeout(i64, double)
+declare double @js_node_https_server_idle_timeout(i64)
+declare double @js_node_https_server_set_idle_timeout(i64, double)
+declare double @js_node_https_server_max_headers_count(i64)
+declare double @js_node_https_server_set_max_headers_count(i64, double)
+declare double @js_node_https_server_max_requests_per_socket(i64)
+declare double @js_node_https_server_set_max_requests_per_socket(i64, double)
+declare i64 @js_node_https_server_set_timeout_method(i64, double, i64)
+declare i64 @js_node_http2_create_server(double, double)
+declare i64 @js_node_http2_create_secure_server(double, i64)
+declare i64 @js_node_http2_connect(double, double, i64)
+declare i64 @js_node_http2_server_listen(i64, i64)
+declare void @js_node_http2_server_close(i64, i64)
+declare i64 @js_node_http2_server_address_json(i64)
+declare double @js_node_http2_server_on(i64, i64, i64)
+declare i64 @js_node_http2_get_default_settings()
+declare i64 @js_node_http2_get_packed_settings(i64)
+declare i64 @js_node_http2_get_unpacked_settings(i64)
+declare i64 @js_pg_client_connect(i64)
+declare i64 @js_pg_client_end(i64)
+declare i64 @js_pg_client_new(i64)
+declare i64 @js_pg_client_query(i64, i64)
+declare i64 @js_pg_client_query_params(i64, i64, i64)
+declare i64 @js_pg_connect(i64)
+declare i64 @js_pg_create_pool(i64)
+declare i64 @js_pg_pool_end(i64)
+declare i64 @js_pg_pool_new(i64)
+declare i64 @js_pg_pool_query(i64, i64)
+declare i64 @js_ioredis_connect(i64)
+declare i64 @js_ioredis_decr(i64, i64)
+declare i64 @js_ioredis_del(i64, i64)
+declare void @js_ioredis_disconnect(i64)
+declare i64 @js_ioredis_exists(i64, i64)
+declare i64 @js_ioredis_expire(i64, i64, double)
+declare i64 @js_ioredis_get(i64, i64)
+declare i64 @js_ioredis_hdel(i64, i64, i64)
+declare i64 @js_ioredis_hget(i64, i64, i64)
+declare i64 @js_ioredis_hgetall(i64, i64)
+declare i64 @js_ioredis_hlen(i64, i64)
+declare i64 @js_ioredis_hset(i64, i64, i64, i64)
+declare i64 @js_ioredis_incr(i64, i64)
+declare i64 @js_ioredis_new(i64)
+declare i64 @js_ioredis_ping(i64)
+declare i64 @js_ioredis_quit(i64)
+declare i64 @js_ioredis_set(i64, i64, i64)
+declare i64 @js_ioredis_setex(i64, i64, double, i64)
+declare i64 @js_mongodb_client_close(i64)
+declare i64 @js_mongodb_client_connect(i64)
+declare i64 @js_mongodb_client_db(i64, i64)
+declare i64 @js_mongodb_client_list_databases(i64)
+declare i64 @js_mongodb_client_new(i64)
+declare i64 @js_mongodb_collection_count_value(i64, double)
+declare i64 @js_mongodb_collection_delete_many_value(i64, double)
+declare i64 @js_mongodb_collection_delete_one_value(i64, double)
+declare i64 @js_mongodb_collection_find_one_value(i64, double)
+declare i64 @js_mongodb_collection_find_value(i64, double)
+declare i64 @js_mongodb_collection_insert_many_value(i64, double)
+declare i64 @js_mongodb_collection_insert_one_value(i64, double)
+declare i64 @js_mongodb_collection_update_many_value(i64, double, double)
+declare i64 @js_mongodb_collection_update_one_value(i64, double, double)
+declare i64 @js_mongodb_collection_count(i64, i64)
+declare i64 @js_mongodb_collection_delete_many(i64, i64)
+declare i64 @js_mongodb_collection_delete_one(i64, i64)
+declare i64 @js_mongodb_collection_find(i64, i64)
+declare i64 @js_mongodb_collection_find_one(i64, i64)
+declare i64 @js_mongodb_collection_insert_many(i64, i64)
+declare i64 @js_mongodb_collection_insert_one(i64, i64)
+declare i64 @js_mongodb_collection_update_many(i64, i64, i64)
+declare i64 @js_mongodb_collection_update_one(i64, i64, i64)
+declare i64 @js_mongodb_connect(i64)
+declare i64 @js_mongodb_db_collection(i64, i64)
+declare i64 @js_mongodb_db_list_collections(i64)
+declare void @js_sqlite_close(i64)
+declare void @js_sqlite_exec(i64, i64)
+declare i64 @js_sqlite_open(i64)
+declare i64 @js_sqlite_pragma(i64, i64, i64)
+declare i64 @js_sqlite_prepare(i64, i64)
+declare i64 @js_sqlite_stmt_all(i64, i64)
+declare i64 @js_sqlite_stmt_columns(i64)
+declare i64 @js_sqlite_stmt_get(i64, i64)
+declare i64 @js_sqlite_stmt_run(i64, i64)
+declare i64 @js_sqlite_transaction(i64, i64)
+declare void @js_sqlite_transaction_commit(i64)
+declare void @js_sqlite_transaction_rollback(i64)
+declare i64 @js_node_sqlite_backup(double, double, double)
+declare i64 @js_node_sqlite_database_sync_call(double, double)
+declare i64 @js_node_sqlite_database_sync_new(double, double)
+declare i32 @js_node_sqlite_database_sync_open(i64)
+declare i32 @js_node_sqlite_database_sync_close(i64)
+declare i32 @js_node_sqlite_database_sync_dispose(i64)
+declare i32 @js_node_sqlite_database_sync_exec(i64, double)
+declare i64 @js_node_sqlite_database_sync_prepare(i64, double, double)
+declare i32 @js_node_sqlite_database_sync_function(i64, double, double, double)
+declare i32 @js_node_sqlite_database_sync_aggregate(i64, double, double)
+declare i32 @js_node_sqlite_database_sync_enable_defensive(i64, double)
+declare i32 @js_node_sqlite_database_sync_set_authorizer(i64, double)
+declare i64 @js_node_sqlite_database_sync_create_tag_store(i64, double)
+declare i64 @js_node_sqlite_database_sync_create_session(i64, double)
+declare double @js_node_sqlite_database_sync_apply_changeset(i64, double, double)
+declare i32 @js_node_sqlite_database_sync_enable_load_extension(i64, double)
+declare i32 @js_node_sqlite_database_sync_load_extension(i64, double)
+declare double @js_node_sqlite_database_sync_location(i64, double)
+declare double @js_node_sqlite_database_sync_is_open(i64)
+declare double @js_node_sqlite_database_sync_is_transaction(i64)
+declare i64 @js_node_sqlite_database_sync_limits(i64)
+declare i64 @js_node_sqlite_statement_sync_call(double, double)
+declare i64 @js_node_sqlite_statement_sync_new(double, double)
+declare i64 @js_node_sqlite_statement_sync_run(i64, i64)
+declare double @js_node_sqlite_statement_sync_get(i64, i64)
+declare i64 @js_node_sqlite_statement_sync_all(i64, i64)
+declare double @js_node_sqlite_statement_sync_iterate(i64, i64)
+declare i64 @js_node_sqlite_statement_sync_columns(i64)
+declare i32 @js_node_sqlite_statement_sync_set_read_bigints(i64, double)
+declare i32 @js_node_sqlite_statement_sync_set_return_arrays(i64, double)
+declare i32 @js_node_sqlite_statement_sync_set_allow_bare_named_parameters(i64, double)
+declare i32 @js_node_sqlite_statement_sync_set_allow_unknown_named_parameters(i64, double)
+declare i64 @js_node_sqlite_statement_sync_source_sql(i64)
+declare i64 @js_node_sqlite_statement_sync_expanded_sql(i64)
+declare i64 @js_node_sqlite_sql_tag_store_run(i64, i64)
+declare double @js_node_sqlite_sql_tag_store_get(i64, i64)
+declare i64 @js_node_sqlite_sql_tag_store_all(i64, i64)
+declare double @js_node_sqlite_sql_tag_store_iterate(i64, i64)
+declare i32 @js_node_sqlite_sql_tag_store_clear(i64)
+declare double @js_node_sqlite_sql_tag_store_size(i64)
+declare double @js_node_sqlite_sql_tag_store_capacity(i64)
+declare i64 @js_node_sqlite_sql_tag_store_db(i64)
+declare i64 @js_node_sqlite_session_call(double, double)
+declare i64 @js_node_sqlite_session_new(double, double)
+declare i64 @js_node_sqlite_session_changeset(i64)
+declare i64 @js_node_sqlite_session_patchset(i64)
+declare i32 @js_node_sqlite_session_close(i64)
+declare i32 @js_node_sqlite_session_dispose(i64)
+declare i64 @js_os_cpus()
+declare double @js_os_freemem()
+declare i64 @js_os_homedir()
+declare i64 @js_os_network_interfaces()
+declare i64 @js_os_tmpdir()
+declare double @js_os_totalmem()
+declare double @js_os_uptime()
+declare i64 @js_os_user_info()
+declare i64 @js_os_user_info_buffer()
+declare i64 @js_os_user_info_options(i64)
+declare i64 @js_crypto_aes256_decrypt(i64, i64, i64)
+declare i64 @js_crypto_aes256_encrypt(i64, i64, i64)
+declare i64 @js_crypto_aes256_gcm_decrypt(i64, i64, i64)
+declare i64 @js_crypto_aes256_gcm_encrypt(i64, i64, i64)
+declare double @js_crypto_create_cipheriv(i64, i64, i64, double)
+declare double @js_crypto_create_decipheriv(i64, i64, i64, double)
+declare i64 @js_crypto_hkdf_sha256(i64, i64, i64, double)
+declare i64 @js_crypto_hkdf_sync(i64, i64, i64, i64, double)
+declare i64 @js_crypto_pbkdf2(i64, i64, double, double)
+declare i64 @js_crypto_random_bytes_hex(double)
+declare i64 @js_crypto_random_nonce()
+declare i64 @js_crypto_scrypt(i64, i64, double)
+declare double @js_crypto_generate_key_pair_sync(i64, i64)
+declare i64 @js_crypto_scrypt_custom(i64, i64, double, double, double, double)
+declare i64 @js_crypto_x25519_keypair()
+declare i64 @js_crypto_x25519_shared_secret(i64, i64)
+declare i64 @js_keccak256_native(i64)
+declare i64 @js_keccak256_native_bytes(i64)
+declare i64 @js_nanoid(double)
+declare i64 @js_nanoid_custom(i64, double)
+declare i64 @js_argon2_hash(i64)
+declare i64 @js_argon2_hash_options(i64, i64)
+declare i64 @js_argon2_verify(i64, i64)
+declare i64 @js_bcrypt_compare(i64, i64)
+declare double @js_bcrypt_compare_sync(i64, i64)
+declare i64 @js_bcrypt_gen_salt(double)
+declare i64 @js_bcrypt_hash(i64, double)
+declare i64 @js_bcrypt_hash_sync(i64, double)
+declare i64 @js_ads_interstitial_load(i64)
+declare i64 @js_ads_interstitial_show()
+declare i64 @js_ads_rewarded_load(i64)
+declare i64 @js_ads_rewarded_show()
+declare double @js_ads_banner_create(i64, i64)
+declare void @js_ads_banner_destroy(double)
+declare i64 @js_ads_request_consent()
+declare i64 @js_perry_read_embedded(double)
+declare i64 @js_perry_embedded_files()
+declare double @js_thread_parallel_map(double, double)
+declare double @js_thread_parallel_filter(double, double)
+declare double @js_thread_spawn(double)
+declare i64 @js_jwt_decode(i64)
+declare i64 @js_jwt_sign(i64, i64, double, i64)
+declare i64 @js_jwt_sign_es256(i64, i64, double, i64)
+declare i64 @js_jwt_sign_rs256(i64, i64, double, i64)
+declare i64 @js_jwt_verify(i64, i64)
+declare i64 @js_jwt_verify_es256(i64, i64)
+declare i64 @js_jwt_verify_rs256(i64, i64)
+declare i64 @js_jwt_sign_dyn(i64, i64, i64, double, i64)
+declare i64 @js_jwt_verify_dyn(i64, i64, i64)
+declare i64 @js_jwt_sign_dyn_opts(i64, i64, double)
+declare i64 @js_jwt_verify_dyn_opts(i64, i64, double)
+declare double @js_axios_create(i64)
+declare i64 @js_axios_delete(i64)
+declare i64 @js_axios_get(i64)
+declare i64 @js_axios_head(i64)
+declare i64 @js_axios_options(i64)
+declare i64 @js_axios_post(i64, double)
+declare i64 @js_axios_put(i64, double)
+declare i64 @js_axios_patch(i64, double)
+declare i64 @js_axios_request(i64)
+declare double @js_axios_response_status(i64)
+declare i64 @js_axios_response_status_text(i64)
+declare i64 @js_axios_response_data(i64)
+declare double @js_axios_response_data_parsed(i64)
+declare i64 @js_sharp_auto_orient(i64)
+declare i64 @js_sharp_avif(i64, double)
+declare i64 @js_sharp_blur(i64, double)
+declare i64 @js_sharp_composite(i64, double)
+declare i64 @js_sharp_extend(i64, double)
+declare i64 @js_sharp_extract(i64, double)
+declare i64 @js_sharp_flip(i64)
+declare i64 @js_sharp_flop(i64)
+declare i64 @js_sharp_from_buffer(i64, double)
+declare i64 @js_sharp_from_file(i64)
+declare i64 @js_sharp_from_input(i64)
+declare i64 @js_sharp_grayscale(i64)
+declare i64 @js_sharp_metadata(i64)
+declare i64 @js_sharp_sharpen(i64)
+declare i64 @js_sharp_trim(i64)
+declare i64 @js_sharp_negate(i64)
+declare i64 @js_sharp_quality(i64, double)
+declare i64 @js_sharp_resize(i64, double, double)
+declare i64 @js_sharp_rotate(i64, double)
+declare i64 @js_sharp_to_buffer(i64)
+declare i64 @js_sharp_to_file(i64, i64)
+declare i64 @js_sharp_to_format(i64, i64)
+declare void @js_cron_clear_interval(i64)
+declare void @js_cron_clear_timeout(i64)
+declare i64 @js_cron_describe(i64)
+declare double @js_cron_job_is_running(i64)
+declare i64 @js_cron_job_new(i64, i64, double)
+declare void @js_cron_job_start(i64)
+declare void @js_cron_job_stop(i64)
+declare i64 @js_cron_next_date(i64)
+declare i64 @js_cron_next_dates(i64, double)
+declare i64 @js_cron_schedule(i64, i64)
+declare i64 @js_cron_set_interval(double, double)
+declare i64 @js_cron_set_timeout(double, double)
+declare i32 @js_cron_timer_has_pending()
+declare i32 @js_cron_timer_tick()
+declare double @js_cron_validate(i64)
+declare i64 @js_async_hooks_create_hook(double)
+declare double @js_async_hooks_execution_async_id()
+declare double @js_async_hooks_trigger_async_id()
+declare double @js_async_hooks_execution_async_resource()
+declare i64 @js_async_hook_enable(i64)
+declare i64 @js_async_hook_disable(i64)
+declare i64 @js_async_resource_new(double, double)
+declare double @js_async_resource_async_id(i64)
+declare double @js_async_resource_trigger_async_id(i64)
+declare i64 @js_async_resource_emit_destroy(i64)
+declare double @js_async_resource_run_in_async_scope(i64, double, double, i64)
+declare i64 @js_async_resource_bind(i64, double, double)
+declare i64 @js_async_resource_static_bind(i64, double)
+declare void @js_async_local_storage_disable(i64)
+declare void @js_async_local_storage_enter_with(i64, double)
+declare double @js_async_local_storage_exit(i64, double, i64)
+declare double @js_async_local_storage_get_store(i64)
+declare i64 @js_async_local_storage_new()
+declare double @js_async_local_storage_run(i64, double, double, i64)
+declare i64 @js_disposable_stack_new()
+declare i64 @js_async_disposable_stack_new()
+declare double @js_suppressed_error_new(double, double, double)
+declare i64 @js_zlib_deflate_sync(i64, double)
+declare void @js_zlib_deflate(double, double)
+declare i64 @js_zlib_gunzip_sync(i64)
+declare void @js_zlib_gunzip(double, double)
+declare i64 @js_zlib_gzip_sync(i64, double)
+declare void @js_zlib_gzip(double, double)
+declare i64 @js_zlib_inflate_sync(i64)
+declare void @js_zlib_inflate(double, double)
+declare i64 @js_zlib_deflate_raw_sync(double, double)
+declare void @js_zlib_deflate_raw(double, double)
+declare i64 @js_zlib_inflate_raw_sync(double)
+declare void @js_zlib_inflate_raw(double, double)
+declare i64 @js_zlib_unzip_sync(double)
+declare void @js_zlib_unzip(double, double)
+declare double @js_zlib_crc32(double, double)
+declare i64 @js_zlib_brotli_compress_sync(i64)
+declare i64 @js_zlib_brotli_decompress_sync(i64)
+declare void @js_zlib_brotli_compress(double, double)
+declare void @js_zlib_brotli_decompress(double, double)
+declare i64 @js_zlib_zstd_compress_sync(double, double)
+declare i64 @js_zlib_zstd_decompress_sync(double, double)
+declare void @js_zlib_zstd_compress(double, double)
+declare void @js_zlib_zstd_decompress(double, double)
+declare i64 @js_zlib_create_gzip(double)
+declare i64 @js_zlib_create_gunzip(double)
+declare i64 @js_zlib_create_deflate(double)
+declare i64 @js_zlib_create_inflate(double)
+declare i64 @js_zlib_create_deflate_raw(double)
+declare i64 @js_zlib_create_inflate_raw(double)
+declare i64 @js_zlib_create_unzip(double)
+declare i64 @js_zlib_create_brotli_compress(double)
+declare i64 @js_zlib_create_zstd_compress(double)
+declare i64 @js_zlib_create_zstd_decompress(double)
+declare i64 @js_buffer_alloc_unsafe(i32)
+declare i32 @js_buffer_byte_length(i64)
+declare i32 @js_buffer_byte_length_value(double, double)
+declare i64 @js_buffer_concat(i64)
+declare i64 @js_buffer_concat_with_length(i64, double)
+declare i32 @js_buffer_validate_size(double)
+declare i64 @js_buffer_validate_concat_list(double)
+declare i32 @js_buffer_copy(i64, i64, i32, i32, i32)
+declare i32 @js_buffer_equals(i64, i64)
+declare i64 @js_buffer_fill(i64, i32)
+declare i64 @js_buffer_from_value(i64, i32)
+declare double @js_buffer_is_ascii(double)
+declare i32 @js_buffer_is_buffer(i64)
+declare i32 @js_buffer_is_encoding(double)
+declare double @js_buffer_is_utf8(double)
+declare void @js_buffer_print(i64)
+declare void @js_buffer_set(i64, i32, i32)
+declare void @js_buffer_set_from(i64, i64, i32)
+declare i64 @js_buffer_slice(i64, i32, i32)
+declare i64 @js_buffer_to_string(i64, i32)
+declare i64 @js_buffer_transcode(double, double, double)
+declare i32 @js_buffer_write(i64, i64, i32, i32)
+declare double @js_child_process_exec_sync(i64, i64)
+declare double @js_child_process_exec(i64, double, double)
+declare i64 @js_child_process_get_process_status(double)
+declare i32 @js_child_process_kill_process(double)
+declare i64 @js_child_process_spawn_background(double, i64, double, double)
+declare i64 @js_child_process_spawn_sync(i64, i64, i64)
+declare double @js_child_process_spawn_streams(i64, i64, i64)
+declare double @js_pty_spawn(i64, i64, i64)
+declare double @js_child_process_fork(i64, i64, i64)
+declare double @js_child_process_exec_file(i64, double, double, double)
+declare double @js_child_process_exec_file_sync(i64, double, double)
+declare double @js_child_process_validate_command(double, ptr, i32)
+declare double @js_child_process_validate_args(double)
+declare double @js_child_process_validate_options(double, i32, i32)
+declare double @js_child_process_validate_fork_module(double)
+declare double @js_child_process_validate_spawn_args(double, i32, i32)
+declare double @js_child_process_new()
+declare i64 @js_cheerio_load(i64)
+declare i64 @js_cheerio_load_fragment(i64)
+declare i64 @js_cheerio_select(i64, i64)
+declare i64 @js_cheerio_selection_attr(i64, i64)
+declare i64 @js_cheerio_selection_attrs(i64, i64)
+declare i64 @js_cheerio_selection_children(i64, i64)
+declare i64 @js_cheerio_selection_eq(i64, double)
+declare i64 @js_cheerio_selection_find(i64, i64)
+declare i64 @js_cheerio_selection_first(i64)
+declare double @js_cheerio_selection_has_class(i64, i64)
+declare i64 @js_cheerio_selection_html(i64)
+declare double @js_cheerio_selection_is(i64, i64)
+declare i64 @js_cheerio_selection_last(i64)
+declare double @js_cheerio_selection_length(i64)
+declare i64 @js_cheerio_selection_parent(i64)
+declare i64 @js_cheerio_selection_text(i64)
+declare i64 @js_cheerio_selection_texts(i64)
+declare i64 @js_cheerio_selection_to_array(i64)
+declare double @js_url_file_url_to_path(double, double)
+declare double @js_url_file_url_to_path_buffer(double, double)
+declare double @js_url_get_hash(i64)
+declare double @js_url_get_host(i64)
+declare double @js_url_get_hostname(i64)
+declare double @js_url_get_href(i64)
+declare double @js_url_get_origin(i64)
+declare double @js_url_get_pathname(i64)
+declare double @js_url_get_port(i64)
+declare double @js_url_get_protocol(i64)
+declare double @js_url_get_search(i64)
+declare double @js_url_get_search_params(i64)
+declare i64 @js_url_new(i64)
+declare i64 @js_url_new_with_base(i64, i64)
+declare i64 @js_url_pattern_new(double, double)
+declare double @js_url_pattern_constructor_call(double, double)
+declare i32 @js_url_can_parse(i64)
+declare i32 @js_url_can_parse_with_base(i64, i64)
+declare i64 @js_url_parse(i64)
+declare i64 @js_url_parse_with_base(i64, i64)
+declare void @js_url_set_pathname(i64, double)
+declare void @js_url_set_search(i64, double)
+declare void @js_url_set_hash(i64, double)
+declare void @js_url_set_protocol(i64, double)
+declare void @js_url_set_hostname(i64, double)
+declare void @js_url_set_port(i64, double)
+declare void @js_url_set_username(i64, double)
+declare void @js_url_set_password(i64, double)
+declare void @js_url_set_href(i64, double)
+declare double @js_url_search_params_has2(i64, double, double)
+declare void @js_url_search_params_delete2(i64, double, double)
+declare double @js_url_search_params_throw_missing_args(i32)
+declare void @js_url_search_params_append(i64, double, double)
+declare void @js_url_search_params_delete(i64, double)
+declare i64 @js_url_search_params_get(i64, double)
+declare double @js_url_search_params_get_all(i64, double)
+declare double @js_url_search_params_has(i64, double)
+declare i64 @js_url_search_params_new(i64)
+declare i64 @js_url_search_params_new_any(double)
+declare i64 @js_url_search_params_new_empty()
+declare double @js_url_search_params_subclass_init(double, double)
+declare void @js_url_search_params_set(i64, double, double)
+declare i64 @js_url_search_params_to_string(i64)
+declare i32 @js_url_search_params_size(i64)
+declare double @js_url_search_params_entries_arr(i64)
+declare double @js_url_search_params_keys_arr(i64)
+declare double @js_url_search_params_values_arr(i64)
+declare void @js_url_search_params_sort(i64)
+declare void @js_url_search_params_for_each(i64, double, double)
+declare i64 @js_url_coerce_string(double)
+declare double @js_url_path_to_file_url(double, double)
+declare double @js_url_domain_to_ascii(double)
+declare double @js_url_domain_to_unicode(double)
+declare double @js_url_to_http_options(double)
+declare double @js_url_legacy_url_new()
+declare double @js_url_format(double, double)
+declare double @js_url_legacy_parse(double, double, double)
+declare double @js_url_legacy_resolve(double, double)
+declare double @js_url_legacy_resolve_object(double, double)
+declare void @js_ws_close(i64)
+declare i64 @js_ws_connect(i64)
+declare double @js_ws_connect_start(double)
+declare i64 @js_ws_handle_to_i64(double)
+declare double @js_ws_is_open(i64)
+declare double @js_ws_message_count(i64)
+declare double @js_ws_ready_state(i64)
+declare i64 @js_ws_on(i64, i64, i64)
+declare i64 @js_ws_receive(i64)
+declare void @js_ws_send(i64, i64)
+declare void @js_ws_send_to_client(double, i64)
+declare void @js_ws_close_client(double)
+declare void @js_ws_send_client_i64(i64, i64)
+declare void @js_ws_close_client_i64(i64)
+declare i64 @js_ws_on_client_i64(i64, i64, i64)
+declare void @js_ws_server_close(i64)
+declare i64 @js_ws_server_new(double)
+declare i64 @js_ws_handle_upgrade(i64, double, double, double, i64)
+declare i64 @js_ws_wait_for_message(i64, double)
+declare i64 @js_pdf_create_pdf(double)
+declare void @js_pdf_add_text(i64, i64, double, double, double)
+declare void @js_pdf_add_line(i64, double, double, double, double)
+declare void @js_pdf_new_page(i64)
+declare void @js_pdf_save(i64)
+declare i64 @js_commander_action(i64, i64)
+declare i64 @js_commander_command(i64, i64)
+declare i64 @js_commander_description(i64, i64)
+declare i64 @js_commander_get_option(i64, i64)
+declare double @js_commander_get_option_bool(i64, i64)
+declare double @js_commander_get_option_number(i64, i64)
+declare i64 @js_commander_name(i64, i64)
+declare i64 @js_commander_new()
+declare i64 @js_commander_option(i64, i64, i64, i64)
+declare i64 @js_commander_opts(i64)
+declare i64 @js_commander_parse(i64, double)
+declare i64 @js_commander_required_option(i64, i64, i64, i64)
+declare i64 @js_commander_version(i64, i64)
+declare double @js_dotenv_config()
+declare double @js_dotenv_config_path(i64)
+declare i64 @js_dotenv_parse(i64)
+declare double @js_datefns_add_days(double, double)
+declare double @js_datefns_add_months(double, double)
+declare double @js_datefns_add_years(double, double)
+declare double @js_datefns_difference_in_days(double, double)
+declare double @js_datefns_difference_in_hours(double, double)
+declare double @js_datefns_difference_in_minutes(double, double)
+declare double @js_datefns_end_of_day(double)
+declare i64 @js_datefns_format(double, i64)
+declare double @js_datefns_is_after(double, double)
+declare double @js_datefns_is_before(double, double)
+declare double @js_datefns_parse_iso(i64)
+declare double @js_datefns_start_of_day(double)
+declare double @js_dayjs_add(i64, double, i64)
+declare double @js_dayjs_date(i64)
+declare double @js_dayjs_day(i64)
+declare double @js_dayjs_diff(i64, i64, i64)
+declare double @js_dayjs_end_of(i64, i64)
+declare double @js_dayjs_factory(i64)
+declare i64 @js_dayjs_format(i64, i64)
+declare double @js_dayjs_from_timestamp(double)
+declare double @js_dayjs_hour(i64)
+declare double @js_dayjs_is_after(i64, i64)
+declare double @js_dayjs_is_before(i64, i64)
+declare double @js_dayjs_is_same(i64, i64)
+declare double @js_dayjs_is_valid(i64)
+declare double @js_dayjs_millisecond(i64)
+declare double @js_dayjs_minute(i64)
+declare double @js_dayjs_month(i64)
+declare double @js_dayjs_now()
+declare double @js_dayjs_parse(i64)
+declare double @js_dayjs_second(i64)
+declare double @js_dayjs_start_of(i64, i64)
+declare double @js_dayjs_subtract(i64, double, i64)
+declare i64 @js_dayjs_to_iso_string(i64)
+declare double @js_dayjs_unix(i64)
+declare double @js_dayjs_value_of(i64)
+declare double @js_dayjs_year(i64)
+declare double @js_moment_add(i64, double, i64)
+declare double @js_moment_clone(i64)
+declare double @js_moment_date(i64)
+declare double @js_moment_day(i64)
+declare double @js_moment_diff(i64, i64, i64)
+declare double @js_moment_end_of(i64, i64)
+declare double @js_moment_factory(i64)
+declare i64 @js_moment_format(i64, i64)
+declare i64 @js_moment_from_now(i64)
+declare double @js_moment_from_timestamp(double)
+declare double @js_moment_hour(i64)
+declare double @js_moment_is_after(i64, i64)
+declare double @js_moment_is_before(i64, i64)
+declare double @js_moment_is_between(i64, i64, i64)
+declare double @js_moment_is_same(i64, i64, i64)
+declare double @js_moment_is_valid(i64)
+declare double @js_moment_millisecond(i64)
+declare double @js_moment_minute(i64)
+declare double @js_moment_month(i64)
+declare double @js_moment_now()
+declare double @js_moment_parse(i64)
+declare double @js_moment_second(i64)
+declare double @js_moment_start_of(i64, i64)
+declare double @js_moment_subtract(i64, double, i64)
+declare double @js_moment_to_date(i64)
+declare i64 @js_moment_to_iso_string(i64)
+declare double @js_moment_unix(i64)
+declare double @js_moment_value_of(i64)
+declare double @js_moment_year(i64)
+declare i64 @js_decimal_abs(i64)
+declare i64 @js_decimal_ceil(i64)
+declare double @js_decimal_cmp(i64, i64)
+declare double @js_decimal_cmp_value(i64, double)
+declare i64 @js_decimal_coerce_to_handle(double)
+declare i64 @js_decimal_div(i64, i64)
+declare i64 @js_decimal_div_number(i64, double)
+declare i64 @js_decimal_div_value(i64, double)
+declare double @js_decimal_eq(i64, i64)
+declare double @js_decimal_eq_value(i64, double)
+declare i64 @js_decimal_floor(i64)
+declare i64 @js_decimal_from_number(double)
+declare i64 @js_decimal_from_string(i64)
+declare double @js_decimal_gt(i64, i64)
+declare double @js_decimal_gt_value(i64, double)
+declare double @js_decimal_gte(i64, i64)
+declare double @js_decimal_gte_value(i64, double)
+declare double @js_decimal_is_negative(i64)
+declare double @js_decimal_is_positive(i64)
+declare double @js_decimal_is_zero(i64)
+declare double @js_decimal_lt(i64, i64)
+declare double @js_decimal_lt_value(i64, double)
+declare double @js_decimal_lte(i64, i64)
+declare double @js_decimal_lte_value(i64, double)
+declare i64 @js_decimal_minus(i64, i64)
+declare i64 @js_decimal_minus_number(i64, double)
+declare i64 @js_decimal_minus_value(i64, double)
+declare i64 @js_decimal_mod(i64, i64)
+declare i64 @js_decimal_mod_value(i64, double)
+declare i64 @js_decimal_neg(i64)
+declare i64 @js_decimal_plus(i64, i64)
+declare i64 @js_decimal_plus_number(i64, double)
+declare i64 @js_decimal_plus_value(i64, double)
+declare i64 @js_decimal_pow(i64, double)
+declare i64 @js_decimal_round(i64)
+declare i64 @js_decimal_sqrt(i64)
+declare i64 @js_decimal_times(i64, i64)
+declare i64 @js_decimal_times_number(i64, double)
+declare i64 @js_decimal_times_value(i64, double)
+declare i64 @js_decimal_to_fixed(i64, double)
+declare double @js_decimal_to_number(i64)
+declare i64 @js_decimal_to_string(i64)
+declare i64 @js_ethers_format_ether(i64)
+declare i64 @js_ethers_format_units(i64, double)
+declare i64 @js_ethers_get_address(i64)
+declare i64 @js_ethers_parse_ether(i64)
+declare i64 @js_ethers_parse_units(i64, double)
+declare i64 @js_lodash_camel_case(i64)
+declare i64 @js_lodash_capitalize(i64)
+declare i64 @js_lodash_chunk(i64, double)
+declare double @js_lodash_clamp(double, double, double)
+declare i64 @js_lodash_compact(i64)
+declare i64 @js_lodash_concat(i64, i64)
+declare i64 @js_lodash_difference(i64, i64)
+declare i64 @js_lodash_drop(i64, double)
+declare i64 @js_lodash_drop_right(i64, double)
+declare double @js_lodash_ends_with(i64, i64)
+declare i64 @js_lodash_escape(i64)
+declare double @js_lodash_first(i64)
+declare i64 @js_lodash_flatten(i64)
+declare double @js_lodash_in_range(double, double, double)
+declare double @js_lodash_includes(i64, i64)
+declare i64 @js_lodash_initial(i64)
+declare i64 @js_lodash_kebab_case(i64)
+declare double @js_lodash_last(i64)
+declare i64 @js_lodash_lower_case(i64)
+declare i64 @js_lodash_lower_first(i64)
+declare double @js_lodash_max(i64)
+declare double @js_lodash_max_by(i64, double)
+declare double @js_lodash_mean(i64)
+declare double @js_lodash_mean_by(i64, double)
+declare double @js_lodash_min(i64)
+declare double @js_lodash_min_by(i64, double)
+declare i64 @js_lodash_pad(i64, double)
+declare i64 @js_lodash_pad_end(i64, double)
+declare i64 @js_lodash_pad_start(i64, double)
+declare double @js_lodash_random(double, double)
+declare i64 @js_lodash_repeat(i64, double)
+declare i64 @js_lodash_replace(i64, i64, i64)
+declare i64 @js_lodash_reverse(i64)
+declare double @js_lodash_size(i64)
+declare i64 @js_lodash_snake_case(i64)
+declare i64 @js_lodash_split(i64, i64)
+declare i64 @js_lodash_start_case(i64)
+declare double @js_lodash_starts_with(i64, i64)
+declare double @js_lodash_sum(i64)
+declare double @js_lodash_sum_by(i64, double)
+declare i64 @js_lodash_tail(i64)
+declare i64 @js_lodash_take(i64, double)
+declare i64 @js_lodash_take_right(i64, double)
+declare i64 @js_lodash_trim(i64)
+declare i64 @js_lodash_trim_end(i64)
+declare i64 @js_lodash_trim_start(i64)
+declare i64 @js_lodash_truncate(i64, double)
+declare i64 @js_lodash_unescape(i64)
+declare i64 @js_lodash_uniq(i64)
+declare i64 @js_lodash_upper_case(i64)
+declare i64 @js_lodash_upper_first(i64)
+declare void @js_lru_cache_clear(i64)
+declare double @js_lru_cache_delete(i64, double)
+declare double @js_lru_cache_get(i64, double)
+declare double @js_lru_cache_has(i64, double)
+declare i64 @js_lru_cache_new(double)
+declare double @js_lru_cache_peek(i64, double)
+declare i64 @js_lru_cache_set(i64, double, double)
+declare double @js_lru_cache_size(i64)
+declare double @js_event_emitter_subclass_init(double)
+declare double @js_array_subclass_init(double, double)
+declare double @js_map_set_subclass_init(double, i32, double)
+declare double @js_promise_subclass_init(double, double)
+declare double @js_node_stream_readable_new(double)
+declare double @js_node_stream_readable_subclass_init(double, double)
+declare double @js_node_stream_writable_new(double)
+declare double @js_node_stream_writable_subclass_init(double, double)
+declare double @js_node_stream_duplex_new(double)
+declare double @js_node_stream_duplex_subclass_init(double, double)
+declare double @js_node_stream_transform_new(double)
+declare double @js_node_stream_transform_subclass_init(double, double)
+declare double @js_node_stream_passthrough_new(double)
+declare double @js_node_stream_readable_from(double)
+declare double @js_node_stream_readable_from_options(double, double)
+declare double @js_node_stream_duplex_from_options(double, double)
+declare double @js_node_stream_is_disturbed(double)
+declare double @js_node_stream_is_errored(double)
+declare double @js_node_stream_is_readable(double)
+declare double @js_node_stream_is_writable(double)
+declare double @js_node_stream_is_array_buffer_view(double)
+declare double @js_node_stream_is_uint8_array(double)
+declare double @js_node_stream_is_destroyed(double)
+declare double @js_node_stream_uint8_array_to_buffer(double)
+declare double @js_node_stream_get_default_hwm(double)
+declare double @js_node_stream_set_default_hwm(double, double)
+declare double @js_node_stream_add_abort_signal(double, double)
+declare double @js_node_stream_compose(i64)
+declare double @js_node_stream_pipeline(i64)
+declare double @js_node_stream_finished(i64)
+declare double @js_node_stream_duplex_pair(double)
+declare double @js_node_stream_readable_to_web(double)
+declare double @js_node_stream_writable_to_web(double)
+declare double @js_node_stream_duplex_to_web(double)
+declare double @js_node_stream_readable_from_web(double, double)
+declare double @js_node_stream_writable_from_web(double, double)
+declare double @js_node_stream_duplex_from_web(double, double)
+declare double @js_node_stream_to_web(double)
+declare double @js_node_stream_from_web(double)
+declare double @js_node_stream_method_readable_aborted(i64)
+declare double @js_node_stream_method_closed(i64)
+declare double @js_node_stream_method_errored(i64)
+declare double @js_node_stream_method_readable_did_read(i64)
+declare double @js_node_stream_method_destroyed(i64)
+declare double @js_node_stream_method_destroy(i64, double)
+declare double @js_node_stream_method_pause(i64)
+declare double @js_node_stream_method_readable(i64)
+declare double @js_node_stream_method_readable_length(i64)
+declare double @js_node_stream_method_readable_flowing(i64)
+declare double @js_node_stream_method_readable_ended(i64)
+declare double @js_node_stream_method_readable_object_mode(i64)
+declare double @js_node_stream_method_pipe(i64, double, double)
+declare double @js_node_stream_method_unpipe(i64, double)
+declare double @js_node_stream_method_is_paused(i64)
+declare double @js_node_stream_method_resume(i64)
+declare double @js_node_stream_method_readable_encoding(i64)
+declare double @js_node_stream_method_cork(i64)
+declare double @js_node_stream_method_uncork(i64)
+declare double @js_node_stream_method_writable_corked(i64)
+declare double @js_node_stream_method_writable_length(i64)
+declare double @js_node_stream_method_writable_need_drain(i64)
+declare double @js_node_stream_method_writable(i64)
+declare double @js_node_stream_method_writable_ended(i64)
+declare double @js_node_stream_method_writable_finished(i64)
+declare double @js_node_stream_method_allow_half_open(i64)
+declare double @js_node_stream_method_set_encoding(i64, double)
+declare double @js_node_stream_method_writable_object_mode(i64)
+declare double @js_event_emitter_emit(i64, i64, i64)
+declare double @js_event_emitter_emit0(i64, i64)
+declare double @js_event_emitter_listener_count(i64, i64, i64)
+declare i64 @js_event_emitter_new()
+declare i64 @js_event_emitter_new_with_options(double)
+declare i64 @js_event_emitter_on(i64, i64, i64)
+declare i64 @js_event_emitter_once(i64, i64, i64)
+declare i64 @js_event_emitter_prepend_listener(i64, i64, i64)
+declare i64 @js_event_emitter_prepend_once_listener(i64, i64, i64)
+declare i64 @js_event_emitter_remove_all_listeners(i64, i64)
+declare i64 @js_event_emitter_remove_listener(i64, i64, i64)
+declare i64 @js_event_emitter_set_max_listeners(i64, double)
+declare double @js_event_emitter_get_max_listeners(i64)
+declare i64 @js_event_emitter_event_names(i64)
+declare i64 @js_event_emitter_listeners(i64, i64)
+declare i64 @js_event_emitter_raw_listeners(i64, i64)
+declare double @js_event_emitter_domain_value(i64)
+declare i64 @js_event_emitter_async_resource_new(double)
+declare double @js_event_emitter_async_resource_call(double)
+declare double @js_event_emitter_async_resource_async_id(i64)
+declare double @js_event_emitter_async_resource_trigger_async_id(i64)
+declare double @js_event_emitter_async_resource_async_resource(i64)
+declare double @js_event_emitter_async_resource_emit_destroy(i64)
+declare i64 @js_events_once(double, i64, double)
+declare i64 @js_events_on(double, i64, double)
+declare i64 @js_events_add_abort_listener(double, double)
+declare i64 @js_events_get_event_listeners(double, i64)
+declare double @js_events_listener_count(double, i64)
+declare double @js_events_get_max_listeners(double)
+declare double @js_events_set_max_listeners(double, i64)
+declare double @js_events_init()
+declare i64 @js_domain_create()
+declare i64 @js_domain_on(i64, i64, i64)
+declare double @js_domain_emit(i64, i64, i64)
+declare double @js_domain_run(i64, double, i64)
+declare double @js_domain_bind(i64, double)
+declare double @js_domain_intercept(i64, double)
+declare i64 @js_domain_add(i64, double)
+declare i64 @js_domain_remove(i64, double)
+declare double @js_domain_enter(i64)
+declare double @js_domain_exit(i64)
+declare i64 @js_string_decoder_new(i64)
+declare double @js_string_decoder_write(i64, double)
+declare double @js_string_decoder_end(i64, double)
+declare double @js_querystring_escape(double)
+declare double @js_querystring_unescape(double)
+declare i64 @js_querystring_unescape_buffer(double, double)
+declare i64 @js_querystring_parse(double, double, double, double)
+declare double @js_querystring_stringify(double, double, double, double)
+declare i32 @js_fastify_add_hook(i64, i64, i64)
+declare i32 @js_fastify_all(i64, i64, i64)
+declare i64 @js_fastify_create()
+declare i64 @js_fastify_create_with_opts(double)
+declare double @js_fastify_ctx_html(i64, i64, double)
+declare double @js_fastify_ctx_json(i64, double, double)
+declare double @js_fastify_ctx_redirect(i64, i64, double)
+declare double @js_fastify_ctx_text(i64, i64, double)
+declare i32 @js_fastify_delete(i64, i64, i64)
+declare i32 @js_fastify_get(i64, i64, i64)
+declare i32 @js_fastify_head(i64, i64, i64)
+declare void @js_fastify_listen(i64, double, i64)
+declare void @js_fastify_app_close(i64)
+declare i64 @js_fastify_app_server(i64)
+declare void @js_fastify_app_on(i64, i64, i64)
+declare i32 @js_fastify_options(i64, i64, i64)
+declare i32 @js_fastify_patch(i64, i64, i64)
+declare i32 @js_fastify_post(i64, i64, i64)
+declare i32 @js_fastify_put(i64, i64, i64)
+declare i32 @js_fastify_register(i64, i64, double)
+declare i64 @js_fastify_reply_header(i64, i64, i64)
+declare i32 @js_fastify_reply_send(i64, double)
+declare i64 @js_fastify_reply_status(i64, double)
+declare i64 @js_fastify_reply_type(i64, i64)
+declare i64 @js_fastify_req_body(i64)
+declare double @js_fastify_req_get_user_data(i64)
+declare i64 @js_fastify_req_header(i64, i64)
+declare i64 @js_fastify_req_headers(i64)
+declare double @js_fastify_req_json(i64)
+declare i64 @js_fastify_req_method(i64)
+declare i64 @js_fastify_req_param(i64, i64)
+declare i64 @js_fastify_req_params(i64)
+declare i64 @js_fastify_req_query(i64)
+declare double @js_fastify_req_query_object(i64)
+declare void @js_fastify_req_set_user_data(i64, double)
+declare i64 @js_fastify_req_url(i64)
+declare i32 @js_fastify_route(i64, i64, i64, i64)
+declare i32 @js_fastify_set_error_handler(i64, i64)
+declare double @js_nodemailer_create_transport(i64)
+declare i64 @js_nodemailer_send_mail(i64, i64)
+declare i64 @js_nodemailer_verify(i64)
+declare i64 @js_ratelimit_block(i64, i64, double)
+declare i64 @js_ratelimit_consume(i64, i64, double)
+declare i64 @js_ratelimit_create(i64)
+declare i64 @js_ratelimit_delete(i64, i64)
+declare i64 @js_ratelimit_get(i64, i64)
+declare i64 @js_ratelimit_new_from_options(i64)
+declare i64 @js_ratelimit_penalty(i64, i64, double)
+declare i64 @js_ratelimit_reward(i64, i64, double)
+declare double @js_validator_contains(i64, i64)
+declare double @js_validator_equals(i64, i64)
+declare double @js_validator_is_alpha(i64)
+declare double @js_validator_is_alphanumeric(i64)
+declare double @js_validator_is_email(i64)
+declare double @js_validator_is_empty(i64)
+declare double @js_validator_is_float(i64)
+declare double @js_validator_is_hexadecimal(i64)
+declare double @js_validator_is_int(i64)
+declare double @js_validator_is_json(i64)
+declare double @js_validator_is_length(i64, double, double)
+declare double @js_validator_is_lowercase(i64)
+declare double @js_validator_is_numeric(i64)
+declare double @js_validator_is_uppercase(i64)
+declare double @js_validator_is_url(i64)
+declare double @js_validator_is_uuid(i64)
+declare i64 @js_date_to_locale_string(double)
+declare i64 @js_number_to_locale_string(double)
+declare double @js_value_to_locale_string(double)
+declare i64 @js_string_split_regex(i64, i64)
+declare i32 @js_object_delete_dynamic(i64, double)
+declare double @js_object_get_prototype_of(double)
+declare double @js_object_set_prototype_of(double, double)
+declare double @js_object_define_properties(double, double)
+declare double @js_math_acos(double)
+declare double @js_math_asin(double)
+declare double @js_math_atan(double)
+declare double @js_math_atan2(double, double)
+declare double @js_math_cos(double)
+declare double @js_math_expm1(double)
+declare double @js_math_log(double)
+declare double @js_math_log10(double)
+declare double @js_math_log1p(double)
+declare double @js_math_log2(double)
+declare double @js_math_sin(double)
+declare double @js_math_tan(double)
+declare double @js_atomics_load(ptr, double, double)
+declare double @js_atomics_is_lock_free(ptr, double)
+declare double @js_atomics_store(ptr, double, double, double)
+declare double @js_atomics_add(ptr, double, double, double)
+declare double @js_atomics_sub(ptr, double, double, double)
+declare double @js_atomics_and(ptr, double, double, double)
+declare double @js_atomics_or(ptr, double, double, double)
+declare double @js_atomics_xor(ptr, double, double, double)
+declare double @js_atomics_exchange(ptr, double, double, double)
+declare double @js_atomics_compare_exchange(ptr, double, double, double, double)
+declare double @js_atomics_notify(ptr, double, double, double)
+declare double @js_atomics_wait(ptr, double, double, double, double)
+declare double @js_atomics_wait_async(ptr, double, double, double, double)
+declare double @js_number_is_finite(double)
+declare double @js_json_get_bool(i64, i64)
+declare double @js_json_get_number(i64, i64)
+declare i64 @js_json_get_string(i64, i64)
+declare double @js_json_is_valid(i64)
+declare i64 @js_json_stringify_bool(double)
+declare i64 @js_json_stringify_null()
+declare i64 @js_json_stringify_number(double)
+declare i64 @js_json_stringify_string(i64)
+declare void @js_set_property(double, i64, i64, double)
+declare i64 @js_error_get_message(i64)
+declare double @js_await_js_promise(double)
+declare i64 @js_text_decoder_decode(i64)
+declare i64 @js_text_encoder_encode(double)
+declare double @js_call_function(i64, i64, i64, i64, i64)
+declare double @js_call_method(double, i64, i64, i64, i64)
+declare double @js_call_value(double, i64, i64)
+declare double @js_closure_call_array(i64, ptr, i64)
+declare double @js_closure_call_apply_with_spread(double, ptr, i64, i64)
+declare double @js_create_callback(i64, i64, i64)
+declare double @js_dynamic_neg(double)
+declare i32 @js_dynamic_string_equals(double, double)
+declare double @js_is_nan(double)
+declare i32 @js_jsvalue_compare(double, double)
+declare i32 @js_jsvalue_loose_equals(double, double)
+declare void @js_gc_collect()
+declare void @js_console_assert(double, i64)
+declare void @js_console_assert_spread(double, i64)
+declare void @js_console_group(i64)
+declare double @js_console_context(double)
+declare double @js_console_create_task(double)
+declare i64 @js_fetch_get(i64)
+declare i64 @js_fetch_get_with_auth(i64, i64)
+declare i64 @js_fetch_post(i64, i64, i64)
+declare i64 @js_fetch_post_with_auth(i64, i64, i64)
+declare double @js_fetch_stream_close(double)
+declare i64 @js_fetch_stream_poll(double)
+declare double @js_fetch_stream_start(i64, i64, i64, i64)
+declare double @js_fetch_stream_status(double)
+declare i64 @js_fetch_text(i64)
+declare i64 @js_fetch_with_options(i64, i64, i64, i64)
+declare void @js_fetch_set_pending_signal(double)
+declare i64 @js_fetch_headers_to_json(double)
+declare double @js_net_create_connection(i32, i64, i64)
+declare i64 @js_net_create_server(i64, i64)
+declare double @js_net_normalize_args(double)
+declare double @js_net_create_server_handle_stub(double, double, double, double, double)
+declare void @js_net_validate_create_server_options(double)
+declare i64 @js_net_socket_set_timeout(i64, double, i64)
+declare void @js_net_server_listen(i64, double, double, double)
+declare void @js_net_server_close(i64, i64)
+declare i64 @js_net_server_address(i64)
+declare void @js_net_server_on(i64, i64, i64)
+declare double @js_net_server_get_listening(i64)
+declare double @js_net_server_get_connections(i64)
+declare double @js_net_server_get_max_connections(i64)
+declare double @js_net_server_set_max_connections(i64, double)
+declare double @js_net_server_get_drop_max_connection(i64)
+declare double @js_net_server_set_drop_max_connection(i64, double)
+declare i64 @js_net_block_list_new()
+declare double @js_net_block_list_is_block_list(double)
+declare double @js_net_block_list_add_address(i64, i64, i64)
+declare double @js_net_block_list_add_range(i64, i64, i64, i64)
+declare double @js_net_block_list_add_subnet(i64, i64, double, i64)
+declare double @js_net_block_list_check(i64, i64, i64)
+declare double @js_net_block_list_to_json(i64)
+declare i64 @js_net_block_list_rules(i64)
+declare double @js_net_block_list_from_json(i64, double)
+declare i64 @js_net_socket_address_new(double)
+declare double @js_net_socket_address_parse(i64)
+declare i64 @js_net_socket_address_get_address(i64)
+declare i64 @js_net_socket_address_get_family(i64)
+declare double @js_net_socket_address_get_port(i64)
+declare double @js_net_socket_address_get_flowlabel(i64)
+declare double @js_net_socket_get_type_of_service(i64)
+declare i64 @js_net_socket_set_type_of_service(i64, double)
+declare i64 @js_net_socket_address(i64)
+declare i64 @js_net_socket_once(i64, i64, i64)
+declare i64 @js_net_socket_remove_listener(i64, i64, i64)
+declare i64 @js_net_socket_remove_all_listeners(i64, i64)
+declare double @js_net_socket_listener_count(i64, i64)
+declare i64 @js_net_socket_event_names(i64)
+declare i64 @js_net_socket_reset_and_destroy(i64)
+declare i64 @js_net_server_once(i64, i64, i64)
+declare i64 @js_net_server_remove_listener(i64, i64, i64)
+declare i64 @js_net_server_remove_all_listeners(i64, i64)
+declare double @js_net_server_listener_count(i64, i64)
+declare i64 @js_net_server_event_names(i64)
+declare double @js_performance_now()
+declare double @js_perf_mark(double, double)
+declare double @js_perf_measure(double, double, double)
+declare double @js_perf_get_entries()
+declare double @js_perf_get_entries_by_type(double)
+declare double @js_perf_get_entries_by_name(double, double)
+declare double @js_perf_clear_marks(double)
+declare double @js_perf_clear_measures(double)
+declare double @js_perf_event_loop_utilization(double, double)
+declare double @js_perf_to_json()
+declare double @js_perf_clear_resource_timings()
+declare double @js_perf_set_resource_timing_buffer_size(double)
+declare double @js_perf_mark_resource_timing(double, double, double, double, double, double, double, double)
+declare double @js_perf_timerify(double, double)
+declare double @js_perf_observer_new(double)
+declare double @js_perf_observer_observe(double, double)
+declare double @js_perf_observer_disconnect(double)
+declare double @js_perf_observer_take_records(double)
+declare double @js_perf_monitor_event_loop_delay(double)
+declare double @js_perf_create_histogram(double)
+declare double @js_perf_histogram_noop()
+declare double @js_perf_histogram_percentile(double)
+declare double @js_iter_result_set(double, i32)
+declare double @js_iter_result_set_f64(double, i32)
+declare double @js_iter_result_set_i32(i32, i32)
+declare double @js_iter_result_set_i1(i32, i32)
+declare double @js_iter_result_get_value()
+declare double @js_iter_result_get_value_f64()
+declare i32 @js_iter_result_get_value_i32()
+declare i32 @js_iter_result_get_value_i1()
+declare double @js_iter_result_get_done()
+declare i64 @js_async_step_chain(double, i64)
+declare i64 @js_async_step_done(double, i64)
+declare i64 @js_get_current_step_closure()
+declare double @js_async_first_call(double)
+declare double @js_async_generator_resume(double, double, double)
+declare i64 @js_slugify(i64)
+declare i64 @js_slugify_strict(i64)
+declare void @js_register_class_getter(i64, i64, i64, i64)
+declare void @js_register_class_setter(i64, i64, i64, i64)
+declare void @js_register_class_method_bind_length(i64, i64, i64, i64)
+declare void @js_register_class_static_method_bind_length(i64, i64, i64, i64)
+declare void @js_register_class_static_getter(i64, i64, i64, i64)
+declare void @js_register_class_static_setter(i64, i64, i64, i64)
+declare void @js_register_class_method(i64, i64, i64, i64, i64, i64, i64)
+declare void @js_register_class_constructor(i64, i64, i64, i64)
+declare void @js_register_class_constructor_flags(i64, i64, i64)
+declare void @js_register_class_static_method(i64, i64, i64, i64, i64, i64)
+declare double @js_class_static_method_call(double, i64, i64, ptr, i64)
+declare double @js_class_method_bind(double, i64, i64)
+declare double @js_class_method_bind_by_id(double, i64)
+declare double @js_class_prototype_method_value(double, double)
+declare double @js_implicit_this_get()
+declare double @js_implicit_this_get_sloppy()
+declare double @js_implicit_this_set(double)
+declare double @js_static_this_resolve(double)
+declare void @js_static_this_arm_classref(i32)
+declare void @js_static_this_arm_value(double)
+declare double @js_ctor_return_override(double, double, i32)
+declare double @js_new_target_get()
+declare double @js_new_target_set(double)
+declare double @js_get_export(i64, i64, i64)
+declare double @js_get_property(double, i64, i64)
+declare i64 @js_load_module(i64, i64)
+declare double @js_module_dynamic_import_apply_hooks(double)
+declare double @js_native_call_method_nullsafe(double, i64, i64, i64, i64)
+declare double @js_native_call_value(double, i64, i64)
+declare double @js_new_from_handle(double, i64, i64)
+declare double @js_new_instance(i64, i64, i64, i64, i64)
+declare void @js_runtime_init()
+declare double @js_object_set_symbol_method(double, double, double)
+declare double @js_object_set_method_by_name(double, double, double)
+declare double @js_object_define_accessor(double, double, double, double)
+declare double @js_object_literal_set_computed(double, double, double)
+declare double @js_object_literal_to_property_key(double)
+declare double @js_object_literal_set_prototype(double, double)
+declare double @js_to_primitive(double, i32)
+declare void @js_register_class_has_instance(i32, i64)
+declare void @js_register_class_to_string_tag(i32, i64)
+declare double @js_object_to_string(double)
+declare double @js_object_group_by(double, double)
+declare double @js_map_group_by(double, double)
+declare double @js_array_from_async(double, double, double)
+declare double @js_jsx(double, double)
+declare double @js_jsxs(double, double)
+declare i64 @js_node_http_server_ref(i64)
+declare i64 @js_node_http_server_unref(i64)
+declare i64 @js_node_https_server_ref(i64)
+declare i64 @js_node_https_server_unref(i64)
+declare double @js_http_client_request_flush_headers(i64, double, double)
+declare double @js_node_http_im_http_version_major(i64)
+declare double @js_node_http_im_http_version_minor(i64)
+declare i64 @js_node_http_im_pause_self(i64)
+declare i64 @js_node_http_im_resume_self(i64)
+declare i64 @js_commander_args_array(i64)
+declare i64 @js_commander_argument(i64, i64)
+
+define i64 @perry_fn_spike_ts__fib_i64(i64 %arg3) alwaysinline {
+entry.0:
+  %r1 = alloca i64
+  store i64 %arg3, ptr %r1
+  %r2 = alloca i64
+  %r3 = load i64, ptr %r1
+  %r4 = icmp slt i64 %r3, 2
+  br i1 %r4, label %i64.cond.then.1, label %i64.cond.else.2
+
+i64.cond.then.1:
+  %r5 = load i64, ptr %r1
+  store i64 %r5, ptr %r2
+  br label %i64.cond.merge.3
+
+i64.cond.else.2:
+  %r6 = load i64, ptr %r1
+  %r7 = sub i64 %r6, 1
+  %r8 = call i64 @perry_fn_spike_ts__fib_i64(i64 %r7)
+  %r9 = load i64, ptr %r1
+  %r10 = sub i64 %r9, 2
+  %r11 = call i64 @perry_fn_spike_ts__fib_i64(i64 %r10)
+  %r12 = add i64 %r8, %r11
+  store i64 %r12, ptr %r2
+  br label %i64.cond.merge.3
+
+i64.cond.merge.3:
+  %r13 = load i64, ptr %r2
+  ret i64 %r13
+}
+
+define double @perry_fn_spike_ts__fib(double %arg3) alwaysinline {
+entry.0:
+  %r1 = fptosi double %arg3 to i64
+  %r2 = call i64 @perry_fn_spike_ts__fib_i64(i64 %r1)
+  %r3 = sitofp i64 %r2 to double
+  ret double %r3
+}
+
+define double @perry_closure_spike_ts__1(i64 %this_closure, double %arg4, double %arg5) {
+entry.0:
+  %r1 = alloca i64
+  %r2 = alloca ptr
+  store ptr null, ptr %r2
+  %r3 = call ptr @js_shadow_frame_enter(i32 2)
+  store ptr %r3, ptr %r2
+  %r4 = getelementptr inbounds i8, ptr %r3, i64 24
+  %r5 = load i64, ptr %r4
+  %r6 = sub i64 %r5, 1
+  store i64 %r6, ptr %r1
+  %r7 = alloca double
+  store double %arg4, ptr %r7
+  call void @js_shadow_slot_bind(i32 0, ptr %r7)
+  %r8 = alloca double
+  store double %arg5, ptr %r8
+  call void @js_shadow_slot_bind(i32 1, ptr %r8)
+  %r9 = load double, ptr %r7
+  %r10 = load double, ptr %r8
+  %r11 = call double @js_dynamic_sub(double %r9, double %r10)
+  %shadow_pop_l_0 = load i64, ptr %r1
+  call void @js_shadow_frame_pop(i64 %shadow_pop_l_0)
+  ret double %r11
+}
+
+define double @perry_closure_spike_ts__4(i64 %this_closure, double %arg19) {
+entry.0:
+  %r1 = alloca i64
+  %r2 = alloca ptr
+  store ptr null, ptr %r2
+  %r3 = call ptr @js_shadow_frame_enter(i32 1)
+  store ptr %r3, ptr %r2
+  %r4 = getelementptr inbounds i8, ptr %r3, i64 24
+  %r5 = load i64, ptr %r4
+  %r6 = sub i64 %r5, 1
+  store i64 %r6, ptr %r1
+  %r15 = alloca [32 x double]
+  %r7 = alloca double
+  store double %arg19, ptr %r7
+  call void @js_shadow_slot_bind(i32 0, ptr %r7)
+  %r8 = load double, ptr @spike_ts_.str.0.handle
+  %r9 = load double, ptr %r7
+  %r10 = call i64 @js_string_coerce(double %r9)
+  %r11 = or i64 %r10, 9223090561878065152
+  %r12 = bitcast i64 %r11 to double
+  %r13 = load double, ptr @spike_ts_.str.1.handle
+  %r14 = load double, ptr @spike_ts_.str.0.handle
+  %r16 = getelementptr double, ptr %r15, i64 0
+  store double %r14, ptr %r16
+  %r17 = getelementptr double, ptr %r15, i64 1
+  store double %r12, ptr %r17
+  %r18 = getelementptr double, ptr %r15, i64 2
+  store double %r13, ptr %r18
+  %r19 = ptrtoint ptr %r15 to i64
+  %r20 = call i64 @js_string_concat_chain(i64 %r19, i32 3)
+  %r21 = or i64 %r20, 9223090561878065152
+  %r22 = bitcast i64 %r21 to double
+  %shadow_pop_l_0 = load i64, ptr %r1
+  call void @js_shadow_frame_pop(i64 %shadow_pop_l_0)
+  ret double %r22
+}
+
+define double @perry_closure_spike_ts__5(i64 %this_closure) {
+entry.0:
+  %r1 = alloca i64
+  %r2 = alloca ptr
+  store ptr null, ptr %r2
+  %r3 = call ptr @js_shadow_frame_enter(i32 5)
+  store ptr %r3, ptr %r2
+  %r4 = getelementptr inbounds i8, ptr %r3, i64 24
+  %r5 = load i64, ptr %r4
+  %r6 = sub i64 %r5, 1
+  store i64 %r6, ptr %r1
+  %r10 = alloca i64
+  store i64 9222246136947933185, ptr %r10
+  %r33 = alloca i64
+  store i64 9222246136947933185, ptr %r33
+  %r56 = alloca i64
+  store i64 9222246136947933185, ptr %r56
+  %r58 = alloca i64
+  store i64 9222246136947933185, ptr %r58
+  %r60 = alloca i64
+  store i64 9222246136947933185, ptr %r60
+  %r83 = alloca i64
+  store i64 9222246136947933185, ptr %r83
+  %r96 = alloca double
+  store double 0x7FFC000000000001, ptr %r96
+  %r103 = alloca [6 x i64]
+  %r7 = alloca i64
+  %r8 = or i64 %this_closure, 9222527611924643840
+  store i64 %r8, ptr %r7
+  call void @js_shadow_slot_bind(i32 4, ptr %r7)
+  %r9 = call i64 @js_box_alloc_bits(i64 9222246136947933185)
+  store i64 %r9, ptr %r10
+  %r11 = load ptr, ptr %r2
+  %r12 = icmp eq ptr %r11, null
+  br i1 %r12, label %ss.slow.1, label %ss.chk_top.2
+
+ss.slow.1:
+  call void @js_shadow_slot_bind(i32 1, ptr %r10)
+  br label %ss.done.5
+
+ss.chk_top.2:
+  %r13 = getelementptr inbounds i8, ptr %r11, i64 24
+  %r14 = load i64, ptr %r13
+  %r15 = icmp eq i64 %r14, -1
+  br i1 %r15, label %ss.done.5, label %ss.chk_len.3
+
+ss.chk_len.3:
+  %r16 = add i64 %r14, 1
+  %r17 = getelementptr inbounds i8, ptr %r11, i64 8
+  %r18 = load i64, ptr %r17
+  %r19 = icmp ult i64 %r16, %r18
+  br i1 %r19, label %ss.store.4, label %ss.done.5
+
+ss.store.4:
+  %r20 = load ptr, ptr %r11
+  %r21 = shl i64 %r16, 4
+  %r22 = getelementptr inbounds i8, ptr %r20, i64 %r21
+  %r23 = getelementptr inbounds i8, ptr %r22, i64 8
+  %r24 = load i64, ptr %r10
+  %r25 = ptrtoint ptr %r10 to i64
+  %r26 = and i64 %r25, 1
+  %r27 = icmp eq i64 %r26, 0
+  %r28 = select i1 %r27, i64 %r25, i64 0
+  %r29 = or i64 %r28, 1
+  store i64 %r24, ptr %r22
+  store i64 %r29, ptr %r23
+  %r30 = load atomic i32, ptr @PERRY_INCREMENTAL_MARK_BARRIER_ACTIVE_COUNT seq_cst, align 4
+  %r31 = icmp ne i32 %r30, 0
+  br i1 %r31, label %ss.barrier.6, label %ss.done.5
+
+ss.done.5:
+  %r32 = call i64 @js_box_alloc_bits(i64 9222246136947933185)
+  store i64 %r32, ptr %r33
+  %r34 = load ptr, ptr %r2
+  %r35 = icmp eq ptr %r34, null
+  br i1 %r35, label %ss.slow.7, label %ss.chk_top.8
+
+ss.barrier.6:
+  call void @js_write_barrier_root_nanbox(i64 %r24)
+  br label %ss.done.5
+
+ss.slow.7:
+  call void @js_shadow_slot_bind(i32 0, ptr %r33)
+  br label %ss.done.11
+
+ss.chk_top.8:
+  %r36 = getelementptr inbounds i8, ptr %r34, i64 24
+  %r37 = load i64, ptr %r36
+  %r38 = icmp eq i64 %r37, -1
+  br i1 %r38, label %ss.done.11, label %ss.chk_len.9
+
+ss.chk_len.9:
+  %r39 = add i64 %r37, 0
+  %r40 = getelementptr inbounds i8, ptr %r34, i64 8
+  %r41 = load i64, ptr %r40
+  %r42 = icmp ult i64 %r39, %r41
+  br i1 %r42, label %ss.store.10, label %ss.done.11
+
+ss.store.10:
+  %r43 = load ptr, ptr %r34
+  %r44 = shl i64 %r39, 4
+  %r45 = getelementptr inbounds i8, ptr %r43, i64 %r44
+  %r46 = getelementptr inbounds i8, ptr %r45, i64 8
+  %r47 = load i64, ptr %r33
+  %r48 = ptrtoint ptr %r33 to i64
+  %r49 = and i64 %r48, 1
+  %r50 = icmp eq i64 %r49, 0
+  %r51 = select i1 %r50, i64 %r48, i64 0
+  %r52 = or i64 %r51, 1
+  store i64 %r47, ptr %r45
+  store i64 %r52, ptr %r46
+  %r53 = load atomic i32, ptr @PERRY_INCREMENTAL_MARK_BARRIER_ACTIVE_COUNT seq_cst, align 4
+  %r54 = icmp ne i32 %r53, 0
+  br i1 %r54, label %ss.barrier.12, label %ss.done.11
+
+ss.done.11:
+  %r55 = call i64 @js_i32_box_alloc(i32 0)
+  store i64 %r55, ptr %r56
+  %r57 = call i64 @js_bool_box_alloc(i32 0)
+  store i64 %r57, ptr %r58
+  %r59 = call i64 @js_box_alloc_bits(i64 9222246136947933185)
+  store i64 %r59, ptr %r60
+  %r61 = load ptr, ptr %r2
+  %r62 = icmp eq ptr %r61, null
+  br i1 %r62, label %ss.slow.13, label %ss.chk_top.14
+
+ss.barrier.12:
+  call void @js_write_barrier_root_nanbox(i64 %r47)
+  br label %ss.done.11
+
+ss.slow.13:
+  call void @js_shadow_slot_bind(i32 2, ptr %r60)
+  br label %ss.done.17
+
+ss.chk_top.14:
+  %r63 = getelementptr inbounds i8, ptr %r61, i64 24
+  %r64 = load i64, ptr %r63
+  %r65 = icmp eq i64 %r64, -1
+  br i1 %r65, label %ss.done.17, label %ss.chk_len.15
+
+ss.chk_len.15:
+  %r66 = add i64 %r64, 2
+  %r67 = getelementptr inbounds i8, ptr %r61, i64 8
+  %r68 = load i64, ptr %r67
+  %r69 = icmp ult i64 %r66, %r68
+  br i1 %r69, label %ss.store.16, label %ss.done.17
+
+ss.store.16:
+  %r70 = load ptr, ptr %r61
+  %r71 = shl i64 %r66, 4
+  %r72 = getelementptr inbounds i8, ptr %r70, i64 %r71
+  %r73 = getelementptr inbounds i8, ptr %r72, i64 8
+  %r74 = load i64, ptr %r60
+  %r75 = ptrtoint ptr %r60 to i64
+  %r76 = and i64 %r75, 1
+  %r77 = icmp eq i64 %r76, 0
+  %r78 = select i1 %r77, i64 %r75, i64 0
+  %r79 = or i64 %r78, 1
+  store i64 %r74, ptr %r72
+  store i64 %r79, ptr %r73
+  %r80 = load atomic i32, ptr @PERRY_INCREMENTAL_MARK_BARRIER_ACTIVE_COUNT seq_cst, align 4
+  %r81 = icmp ne i32 %r80, 0
+  br i1 %r81, label %ss.barrier.18, label %ss.done.17
+
+ss.done.17:
+  %r82 = call i64 @js_bool_box_alloc(i32 0)
+  store i64 %r82, ptr %r83
+  %r84 = load i64, ptr %r56
+  call void @js_i32_box_set(i64 %r84, i32 0)
+  %r85 = sitofp i32 0 to double
+  %r86 = load i64, ptr %r58
+  %r87 = zext i1 false to i32
+  call void @js_bool_box_set(i64 %r86, i32 %r87)
+  %r88 = select i1 false, i64 9222246136947933188, i64 9222246136947933187
+  %r89 = bitcast i64 %r88 to double
+  %r90 = load i64, ptr %r83
+  %r91 = zext i1 false to i32
+  call void @js_bool_box_set(i64 %r90, i32 %r91)
+  %r92 = select i1 false, i64 9222246136947933188, i64 9222246136947933187
+  %r93 = bitcast i64 %r92 to double
+  %r94 = load i64, ptr %r60
+  %r95 = bitcast double 0x7FFC000000000001 to i64
+  call void @js_box_set_bits(i64 %r94, i64 %r95)
+  call void @js_write_barrier(i64 %r94, i64 %r95)
+  %r97 = load i64, ptr %r10
+  %r98 = load i64, ptr %r33
+  %r99 = load i64, ptr %r56
+  %r100 = load i64, ptr %r58
+  %r101 = load i64, ptr %r60
+  %r102 = load i64, ptr %r83
+  %r104 = getelementptr i64, ptr %r103, i64 0
+  store i64 %r97, ptr %r104
+  %r105 = getelementptr i64, ptr %r103, i64 1
+  store i64 %r98, ptr %r105
+  %r106 = getelementptr i64, ptr %r103, i64 2
+  store i64 %r99, ptr %r106
+  %r107 = getelementptr i64, ptr %r103, i64 3
+  store i64 %r100, ptr %r107
+  %r108 = getelementptr i64, ptr %r103, i64 4
+  store i64 %r101, ptr %r108
+  %r109 = getelementptr i64, ptr %r103, i64 5
+  store i64 %r102, ptr %r109
+  %r110 = call i64 @js_closure_alloc_with_captures_singleton(ptr @perry_closure_spike_ts__8, i32 6, ptr %r103)
+  %r111 = or i64 %r110, 9222527611924643840
+  %r112 = bitcast i64 %r111 to double
+  store double %r112, ptr %r96
+  %r113 = load ptr, ptr %r2
+  %r114 = icmp eq ptr %r113, null
+  br i1 %r114, label %ss.slow.19, label %ss.chk_top.20
+
+ss.barrier.18:
+  call void @js_write_barrier_root_nanbox(i64 %r74)
+  br label %ss.done.17
+
+ss.slow.19:
+  call void @js_shadow_slot_bind(i32 3, ptr %r96)
+  br label %ss.done.23
+
+ss.chk_top.20:
+  %r115 = getelementptr inbounds i8, ptr %r113, i64 24
+  %r116 = load i64, ptr %r115
+  %r117 = icmp eq i64 %r116, -1
+  br i1 %r117, label %ss.done.23, label %ss.chk_len.21
+
+ss.chk_len.21:
+  %r118 = add i64 %r116, 3
+  %r119 = getelementptr inbounds i8, ptr %r113, i64 8
+  %r120 = load i64, ptr %r119
+  %r121 = icmp ult i64 %r118, %r120
+  br i1 %r121, label %ss.store.22, label %ss.done.23
+
+ss.store.22:
+  %r122 = load ptr, ptr %r113
+  %r123 = shl i64 %r118, 4
+  %r124 = getelementptr inbounds i8, ptr %r122, i64 %r123
+  %r125 = getelementptr inbounds i8, ptr %r124, i64 8
+  %r126 = load i64, ptr %r96
+  %r127 = ptrtoint ptr %r96 to i64
+  %r128 = and i64 %r127, 1
+  %r129 = icmp eq i64 %r128, 0
+  %r130 = select i1 %r129, i64 %r127, i64 0
+  %r131 = or i64 %r130, 1
+  store i64 %r126, ptr %r124
+  store i64 %r131, ptr %r125
+  %r132 = load atomic i32, ptr @PERRY_INCREMENTAL_MARK_BARRIER_ACTIVE_COUNT seq_cst, align 4
+  %r133 = icmp ne i32 %r132, 0
+  br i1 %r133, label %ss.barrier.24, label %ss.done.23
+
+ss.done.23:
+  %r134 = load double, ptr %r96
+  %r135 = call double @js_async_first_call(double %r134)
+  %shadow_pop_l_0 = load i64, ptr %r1
+  call void @js_shadow_frame_pop(i64 %shadow_pop_l_0)
+  ret double %r135
+
+ss.barrier.24:
+  call void @js_write_barrier_root_nanbox(i64 %r126)
+  br label %ss.done.23
+}
+
+define double @perry_closure_spike_ts__8(i64 %this_closure, double %arg31, double %arg32) #1 {
+entry.0:
+  %r1 = alloca i64
+  %r2 = alloca ptr
+  store ptr null, ptr %r2
+  %r3 = call ptr @js_shadow_frame_enter(i32 5)
+  store ptr %r3, ptr %r2
+  %r4 = getelementptr inbounds i8, ptr %r3, i64 24
+  %r5 = load i64, ptr %r4
+  %r6 = sub i64 %r5, 1
+  store i64 %r6, ptr %r1
+  %r11 = alloca double
+  store double 0x7FFC000000000001, ptr %r11
+  %r43 = alloca double
+  store volatile double 0x7FFC000000000001, ptr %r43
+  %r156 = alloca double
+  %r7 = alloca double
+  store double %arg31, ptr %r7
+  call void @js_shadow_slot_bind(i32 0, ptr %r7)
+  %r8 = alloca double
+  store double %arg32, ptr %r8
+  %r9 = alloca i64
+  %r10 = or i64 %this_closure, 9222527611924643840
+  store i64 %r10, ptr %r9
+  call void @js_shadow_slot_bind(i32 4, ptr %r9)
+  %r12 = call i64 @js_get_current_step_closure()
+  %r13 = or i64 %r12, 9222527611924643840
+  %r14 = bitcast i64 %r13 to double
+  store double %r14, ptr %r11
+  %r15 = load ptr, ptr %r2
+  %r16 = icmp eq ptr %r15, null
+  br i1 %r16, label %ss.slow.1, label %ss.chk_top.2
+
+ss.slow.1:
+  call void @js_shadow_slot_bind(i32 1, ptr %r11)
+  br label %ss.done.5
+
+ss.chk_top.2:
+  %r17 = getelementptr inbounds i8, ptr %r15, i64 24
+  %r18 = load i64, ptr %r17
+  %r19 = icmp eq i64 %r18, -1
+  br i1 %r19, label %ss.done.5, label %ss.chk_len.3
+
+ss.chk_len.3:
+  %r20 = add i64 %r18, 1
+  %r21 = getelementptr inbounds i8, ptr %r15, i64 8
+  %r22 = load i64, ptr %r21
+  %r23 = icmp ult i64 %r20, %r22
+  br i1 %r23, label %ss.store.4, label %ss.done.5
+
+ss.store.4:
+  %r24 = load ptr, ptr %r15
+  %r25 = shl i64 %r20, 4
+  %r26 = getelementptr inbounds i8, ptr %r24, i64 %r25
+  %r27 = getelementptr inbounds i8, ptr %r26, i64 8
+  %r28 = load i64, ptr %r11
+  %r29 = ptrtoint ptr %r11 to i64
+  %r30 = and i64 %r29, 1
+  %r31 = icmp eq i64 %r30, 0
+  %r32 = select i1 %r31, i64 %r29, i64 0
+  %r33 = or i64 %r32, 1
+  store i64 %r28, ptr %r26
+  store i64 %r33, ptr %r27
+  %r34 = load atomic i32, ptr @PERRY_INCREMENTAL_MARK_BARRIER_ACTIVE_COUNT seq_cst, align 4
+  %r35 = icmp ne i32 %r34, 0
+  br i1 %r35, label %ss.barrier.6, label %ss.done.5
+
+ss.done.5:
+  %r36 = call ptr @js_try_push()
+  %r37 = call i32 @_setjmp(ptr %r36) #0
+  %r38 = icmp ne i32 %r37, 0
+  br i1 %r38, label %try.catch.8, label %try.body.7
+
+ss.barrier.6:
+  call void @js_write_barrier_root_nanbox(i64 %r28)
+  br label %ss.done.5
+
+try.body.7:
+  br label %dowhile.body.10
+
+try.catch.8:
+  call void @js_try_end()
+  %r155 = call double @js_get_exception()
+  call void @js_clear_exception()
+  store double %r155, ptr %r156
+  %r157 = load ptr, ptr %r2
+  %r158 = icmp eq ptr %r157, null
+  br i1 %r158, label %ss.slow.39, label %ss.chk_top.40
+
+try.finally.9:
+  %r197 = call double @js_iter_result_get_done()
+  %r198 = call i32 @js_is_truthy(double %r197)
+  %r199 = icmp ne i32 %r198, 0
+  br i1 %r199, label %if.then.48, label %if.else.49
+
+dowhile.body.10:
+  %r39 = load double, ptr %r8
+  %r40 = bitcast double %r39 to i64
+  %r41 = icmp eq i64 %r40, 9222246136947933188
+  br i1 %r41, label %if.then.13, label %if.else.14
+
+dowhile.cond.11:
+  %r152 = select i1 false, i64 9222246136947933188, i64 9222246136947933187
+  %r153 = bitcast i64 %r152 to double
+  %r154 = icmp eq i64 %r152, 9222246136947933188
+  br i1 %r154, label %dowhile.body.10, label %dowhile.exit.12
+
+dowhile.exit.12:
+  call void @js_try_end()
+  br label %try.finally.9
+
+if.then.13:
+  %r42 = load double, ptr %r7
+  call void @js_throw(double %r42)
+  unreachable
+
+if.else.14:
+  %r44 = load double, ptr %r7
+  store volatile double %r44, ptr %r43
+  %r45 = load ptr, ptr %r2
+  %r46 = icmp eq ptr %r45, null
+  br i1 %r46, label %ss.slow.16, label %ss.chk_top.17
+
+if.merge.15:
+  %r137 = load ptr, ptr %r2
+  %r138 = icmp eq ptr %r137, null
+  br i1 %r138, label %ss.slow.34, label %ss.chk_top.35
+
+ss.slow.16:
+  call void @js_shadow_slot_bind(i32 2, ptr %r43)
+  br label %ss.done.20
+
+ss.chk_top.17:
+  %r47 = getelementptr inbounds i8, ptr %r45, i64 24
+  %r48 = load i64, ptr %r47
+  %r49 = icmp eq i64 %r48, -1
+  br i1 %r49, label %ss.done.20, label %ss.chk_len.18
+
+ss.chk_len.18:
+  %r50 = add i64 %r48, 2
+  %r51 = getelementptr inbounds i8, ptr %r45, i64 8
+  %r52 = load i64, ptr %r51
+  %r53 = icmp ult i64 %r50, %r52
+  br i1 %r53, label %ss.store.19, label %ss.done.20
+
+ss.store.19:
+  %r54 = load ptr, ptr %r45
+  %r55 = shl i64 %r50, 4
+  %r56 = getelementptr inbounds i8, ptr %r54, i64 %r55
+  %r57 = getelementptr inbounds i8, ptr %r56, i64 8
+  %r58 = load volatile i64, ptr %r43
+  %r59 = ptrtoint ptr %r43 to i64
+  %r60 = and i64 %r59, 1
+  %r61 = icmp eq i64 %r60, 0
+  %r62 = select i1 %r61, i64 %r59, i64 0
+  %r63 = or i64 %r62, 1
+  store i64 %r58, ptr %r56
+  store i64 %r63, ptr %r57
+  %r64 = load atomic i32, ptr @PERRY_INCREMENTAL_MARK_BARRIER_ACTIVE_COUNT seq_cst, align 4
+  %r65 = icmp ne i32 %r64, 0
+  br i1 %r65, label %ss.barrier.21, label %ss.done.20
+
+ss.done.20:
+  %r66 = load volatile double, ptr %r43
+  %r67 = load i64, ptr %r9
+  %r68 = and i64 %r67, 281474976710655
+  %r69 = call i64 @js_closure_get_capture_bits(i64 %r68, i32 4)
+  %r70 = bitcast double %r66 to i64
+  call void @js_box_set_bits(i64 %r69, i64 %r70)
+  call void @js_write_barrier(i64 %r69, i64 %r70)
+  %r71 = load i64, ptr %r9
+  %r72 = and i64 %r71, 281474976710655
+  %r73 = call i64 @js_closure_get_capture_bits(i64 %r72, i32 3)
+  %r74 = call i32 @js_bool_box_get(i64 %r73)
+  %r75 = icmp ne i32 %r74, 0
+  br i1 %r75, label %if.then.22, label %if.else.23
+
+ss.barrier.21:
+  call void @js_write_barrier_root_nanbox(i64 %r58)
+  br label %ss.done.20
+
+if.then.22:
+  %r76 = call double @js_iter_result_set(double 0x7FFC000000000001, i32 1)
+  br label %dowhile.exit.12
+
+if.else.23:
+  br label %if.merge.24
+
+if.merge.24:
+  br label %while.cond.25
+
+while.cond.25:
+  %r77 = select i1 true, i64 9222246136947933188, i64 9222246136947933187
+  %r78 = bitcast i64 %r77 to double
+  %r79 = icmp eq i64 %r77, 9222246136947933188
+  br i1 %r79, label %while.body.26, label %while.exit.27
+
+while.body.26:
+  %r80 = load i64, ptr %r9
+  %r81 = and i64 %r80, 281474976710655
+  %r82 = call i64 @js_closure_get_capture_bits(i64 %r81, i32 2)
+  %r83 = call i32 @js_i32_box_get(i64 %r82)
+  %r84 = icmp eq i32 %r83, 0
+  br i1 %r84, label %if.then.28, label %if.else.29
+
+while.exit.27:
+  br label %if.merge.15
+
+if.then.28:
+  %r85 = call i64 @js_promise_resolved(double 42.0)
+  %r86 = or i64 %r85, 9222527611924643840
+  %r87 = bitcast i64 %r86 to double
+  %r88 = load i64, ptr %r9
+  %r89 = and i64 %r88, 281474976710655
+  %r90 = call i64 @js_closure_get_capture_bits(i64 %r89, i32 1)
+  call void @js_box_set_bits(i64 %r90, i64 %r86)
+  call void @js_write_barrier(i64 %r90, i64 %r86)
+  %r91 = load i64, ptr %r9
+  %r92 = and i64 %r91, 281474976710655
+  %r93 = call i64 @js_closure_get_capture_bits(i64 %r92, i32 2)
+  call void @js_i32_box_set(i64 %r93, i32 1)
+  %r94 = sitofp i32 1 to double
+  %r95 = load i64, ptr %r9
+  %r96 = and i64 %r95, 281474976710655
+  %r97 = call i64 @js_closure_get_capture_bits(i64 %r96, i32 1)
+  %r98 = call i64 @js_box_get_bits(i64 %r97)
+  %r99 = bitcast i64 %r98 to double
+  %r100 = call double @js_iter_result_set(double %r99, i32 0)
+  br label %dowhile.exit.12
+
+if.else.29:
+  br label %if.merge.30
+
+if.merge.30:
+  %r101 = load i64, ptr %r9
+  %r102 = and i64 %r101, 281474976710655
+  %r103 = call i64 @js_closure_get_capture_bits(i64 %r102, i32 2)
+  %r104 = call i32 @js_i32_box_get(i64 %r103)
+  %r105 = icmp eq i32 %r104, 1
+  br i1 %r105, label %if.then.31, label %if.else.32
+
+if.then.31:
+  %r106 = load i64, ptr %r9
+  %r107 = and i64 %r106, 281474976710655
+  %r108 = call i64 @js_closure_get_capture_bits(i64 %r107, i32 4)
+  %r109 = call i64 @js_box_get_bits(i64 %r108)
+  %r110 = bitcast i64 %r109 to double
+  %r111 = load i64, ptr %r9
+  %r112 = and i64 %r111, 281474976710655
+  %r113 = call i64 @js_closure_get_capture_bits(i64 %r112, i32 0)
+  call void @js_box_set_bits(i64 %r113, i64 %r109)
+  call void @js_write_barrier(i64 %r113, i64 %r109)
+  %r114 = call i64 @js_array_alloc(i32 2)
+  %r115 = call i32 @js_gc_temp_root_push(i64 %r114)
+  %r116 = load double, ptr @spike_ts_.str.2.handle
+  call void @js_array_push_f64_temp_rooted(i32 %r115, double %r116)
+  %r117 = load i64, ptr %r9
+  %r118 = and i64 %r117, 281474976710655
+  %r119 = call i64 @js_closure_get_capture_bits(i64 %r118, i32 0)
+  %r120 = call i64 @js_box_get_bits(i64 %r119)
+  %r121 = bitcast i64 %r120 to double
+  call void @js_array_push_f64_temp_rooted(i32 %r115, double %r121)
+  %r122 = call i64 @js_gc_temp_root_get(i32 %r115)
+  call void @js_console_log_spread(i64 %r122)
+  call void @js_gc_temp_root_truncate(i32 %r115)
+  %r123 = load i64, ptr %r9
+  %r124 = and i64 %r123, 281474976710655
+  %r125 = call i64 @js_closure_get_capture_bits(i64 %r124, i32 3)
+  %r126 = zext i1 true to i32
+  call void @js_bool_box_set(i64 %r125, i32 %r126)
+  %r127 = select i1 true, i64 9222246136947933188, i64 9222246136947933187
+  %r128 = bitcast i64 %r127 to double
+  %r129 = call double @js_iter_result_set(double 0x7FFC000000000001, i32 1)
+  br label %dowhile.exit.12
+
+if.else.32:
+  br label %if.merge.33
+
+if.merge.33:
+  %r130 = load i64, ptr %r9
+  %r131 = and i64 %r130, 281474976710655
+  %r132 = call i64 @js_closure_get_capture_bits(i64 %r131, i32 3)
+  %r133 = zext i1 true to i32
+  call void @js_bool_box_set(i64 %r132, i32 %r133)
+  %r134 = select i1 true, i64 9222246136947933188, i64 9222246136947933187
+  %r135 = bitcast i64 %r134 to double
+  %r136 = call double @js_iter_result_set(double 0x7FFC000000000001, i32 1)
+  br label %dowhile.exit.12
+
+ss.slow.34:
+  call void @js_shadow_slot_set(i32 2, i64 0)
+  br label %ss.done.38
+
+ss.chk_top.35:
+  %r139 = getelementptr inbounds i8, ptr %r137, i64 24
+  %r140 = load i64, ptr %r139
+  %r141 = icmp eq i64 %r140, -1
+  br i1 %r141, label %ss.done.38, label %ss.chk_len.36
+
+ss.chk_len.36:
+  %r142 = add i64 %r140, 2
+  %r143 = getelementptr inbounds i8, ptr %r137, i64 8
+  %r144 = load i64, ptr %r143
+  %r145 = icmp ult i64 %r142, %r144
+  br i1 %r145, label %ss.store.37, label %ss.done.38
+
+ss.store.37:
+  %r146 = load ptr, ptr %r137
+  %r147 = shl i64 %r142, 4
+  %r148 = getelementptr inbounds i8, ptr %r146, i64 %r147
+  %r149 = getelementptr inbounds i8, ptr %r148, i64 8
+  %r150 = load i64, ptr %r149
+  %r151 = and i64 %r150, -2
+  store i64 0, ptr %r148
+  store i64 %r151, ptr %r149
+  br label %ss.done.38
+
+ss.done.38:
+  br label %dowhile.cond.11
+
+ss.slow.39:
+  call void @js_shadow_slot_bind(i32 3, ptr %r156)
+  br label %ss.done.43
+
+ss.chk_top.40:
+  %r159 = getelementptr inbounds i8, ptr %r157, i64 24
+  %r160 = load i64, ptr %r159
+  %r161 = icmp eq i64 %r160, -1
+  br i1 %r161, label %ss.done.43, label %ss.chk_len.41
+
+ss.chk_len.41:
+  %r162 = add i64 %r160, 3
+  %r163 = getelementptr inbounds i8, ptr %r157, i64 8
+  %r164 = load i64, ptr %r163
+  %r165 = icmp ult i64 %r162, %r164
+  br i1 %r165, label %ss.store.42, label %ss.done.43
+
+ss.store.42:
+  %r166 = load ptr, ptr %r157
+  %r167 = shl i64 %r162, 4
+  %r168 = getelementptr inbounds i8, ptr %r166, i64 %r167
+  %r169 = getelementptr inbounds i8, ptr %r168, i64 8
+  %r170 = load i64, ptr %r156
+  %r171 = ptrtoint ptr %r156 to i64
+  %r172 = and i64 %r171, 1
+  %r173 = icmp eq i64 %r172, 0
+  %r174 = select i1 %r173, i64 %r171, i64 0
+  %r175 = or i64 %r174, 1
+  store i64 %r170, ptr %r168
+  store i64 %r175, ptr %r169
+  %r176 = load atomic i32, ptr @PERRY_INCREMENTAL_MARK_BARRIER_ACTIVE_COUNT seq_cst, align 4
+  %r177 = icmp ne i32 %r176, 0
+  br i1 %r177, label %ss.barrier.44, label %ss.done.43
+
+ss.done.43:
+  %r178 = load double, ptr %r8
+  %r179 = bitcast double %r178 to i64
+  %r180 = icmp eq i64 %r179, 9222246136947933188
+  br i1 %r180, label %if.then.45, label %if.else.46
+
+ss.barrier.44:
+  call void @js_write_barrier_root_nanbox(i64 %r170)
+  br label %ss.done.43
+
+if.then.45:
+  %r181 = load double, ptr %r156
+  %r182 = call i64 @js_promise_rejected(double %r181)
+  %r183 = or i64 %r182, 9222527611924643840
+  %r184 = bitcast i64 %r183 to double
+  %shadow_pop_l_0 = load i64, ptr %r1
+  call void @js_shadow_frame_pop(i64 %shadow_pop_l_0)
+  ret double %r184
+
+if.else.46:
+  br label %if.merge.47
+
+if.merge.47:
+  %r185 = load double, ptr %r11
+  %r186 = load double, ptr %r156
+  %r187 = select i1 true, i64 9222246136947933188, i64 9222246136947933187
+  %r188 = bitcast i64 %r187 to double
+  %r189 = call double @js_implicit_this_set(double 0x7FFC000000000001)
+  %r190 = bitcast double %r189 to i64
+  %r191 = call i32 @js_gc_temp_root_push(i64 %r190)
+  %r192 = call i64 @js_closure_unbox_callee_checked(double %r185)
+  %r193 = call double @js_closure_call2(i64 %r192, double %r186, double %r188)
+  %r194 = call i64 @js_gc_temp_root_get(i32 %r191)
+  %r195 = bitcast i64 %r194 to double
+  call void @js_gc_temp_root_truncate(i32 %r191)
+  %r196 = call double @js_implicit_this_set(double %r195)
+  %shadow_pop_l_1 = load i64, ptr %r1
+  call void @js_shadow_frame_pop(i64 %shadow_pop_l_1)
+  ret double %r193
+
+if.then.48:
+  %r200 = call double @js_iter_result_get_value()
+  %r201 = load double, ptr %r11
+  %r202 = bitcast double %r201 to i64
+  %r203 = and i64 %r202, 281474976710655
+  %r204 = call i64 @js_async_step_done(double %r200, i64 %r203)
+  %r205 = or i64 %r204, 9222527611924643840
+  %r206 = bitcast i64 %r205 to double
+  %shadow_pop_l_2 = load i64, ptr %r1
+  call void @js_shadow_frame_pop(i64 %shadow_pop_l_2)
+  ret double %r206
+
+if.else.49:
+  br label %if.merge.50
+
+if.merge.50:
+  %r207 = call double @js_iter_result_get_value()
+  %r208 = load double, ptr %r11
+  %r209 = bitcast double %r208 to i64
+  %r210 = and i64 %r209, 281474976710655
+  %r211 = call i64 @js_async_step_chain(double %r207, i64 %r210)
+  %r212 = or i64 %r211, 9222527611924643840
+  %r213 = bitcast i64 %r212 to double
+  %shadow_pop_l_3 = load i64, ptr %r1
+  call void @js_shadow_frame_pop(i64 %shadow_pop_l_3)
+  ret double %r213
+}
+
+define double @perry_method_spike_ts__Point__norm(double %this_arg) {
+entry.0:
+  %r1 = alloca i64
+  %r2 = alloca ptr
+  store ptr null, ptr %r2
+  %r3 = call ptr @js_shadow_frame_enter(i32 1)
+  store ptr %r3, ptr %r2
+  %r4 = getelementptr inbounds i8, ptr %r3, i64 24
+  %r5 = load i64, ptr %r4
+  %r6 = sub i64 %r5, 1
+  store i64 %r6, ptr %r1
+  %r7 = alloca double
+  store double %this_arg, ptr %r7
+  call void @js_shadow_slot_bind(i32 0, ptr %r7)
+  %r8 = load double, ptr %r7
+  %r9 = bitcast double %r8 to i64
+  %r10 = and i64 %r9, 281474976710655
+  %r11 = load double, ptr @spike_ts_.str.3.handle
+  %r12 = bitcast double %r11 to i64
+  %r13 = and i64 %r12, 281474976710655
+  %r14 = load i64, ptr @perry_class_keys_spike_ts__Point
+  %r15 = load volatile i8, ptr @PERRY_CLASS_FIELD_INLINE_GUARD_DISABLED
+  %r16 = icmp eq i8 %r15, 0
+  %r17 = lshr i64 %r9, 48
+  %r18 = icmp eq i64 %r17, 32765
+  %r19 = icmp ugt i64 %r10, 1048575
+  %r20 = and i1 %r18, %r19
+  %r21 = and i1 %r20, %r16
+  br i1 %r21, label %class_field_inline.deref.4, label %class_field_inline.guardcall.5
+
+class_field_get_number.fast.1:
+  %r56 = inttoptr i64 %r10 to ptr
+  %r57 = getelementptr i8, ptr %r56, i64 32
+  %r58 = getelementptr double, ptr %r57, i64 0
+  %r59 = load double, ptr %r58
+  br label %class_field_get_number.merge.3
+
+class_field_get_number.fallback.2:
+  call void @js_typed_feedback_record_fallback_call(i64 7695367220062322688)
+  %r60 = call double @js_object_get_field_by_name_f64(i64 %r9, i64 %r13)
+  %r61 = call double @js_number_coerce(double %r60)
+  br label %class_field_get_number.merge.3
+
+class_field_get_number.merge.3:
+  %r62 = phi double [ %r59, %class_field_get_number.fast.1 ], [ %r61, %class_field_get_number.fallback.2 ]
+  %r63 = load double, ptr %r7
+  %r64 = bitcast double %r63 to i64
+  %r65 = and i64 %r64, 281474976710655
+  %r66 = load double, ptr @spike_ts_.str.3.handle
+  %r67 = bitcast double %r66 to i64
+  %r68 = and i64 %r67, 281474976710655
+  %r69 = load i64, ptr @perry_class_keys_spike_ts__Point
+  %r70 = load volatile i8, ptr @PERRY_CLASS_FIELD_INLINE_GUARD_DISABLED
+  %r71 = icmp eq i8 %r70, 0
+  %r72 = lshr i64 %r64, 48
+  %r73 = icmp eq i64 %r72, 32765
+  %r74 = icmp ugt i64 %r65, 1048575
+  %r75 = and i1 %r73, %r74
+  %r76 = and i1 %r75, %r71
+  br i1 %r76, label %class_field_inline.deref.9, label %class_field_inline.guardcall.10
+
+class_field_inline.deref.4:
+  %r22 = inttoptr i64 %r10 to ptr
+  %r23 = getelementptr i8, ptr %r22, i64 -8
+  %r24 = load i8, ptr %r23
+  %r25 = icmp eq i8 %r24, 2
+  %r26 = getelementptr i8, ptr %r22, i64 -7
+  %r27 = load i8, ptr %r26
+  %r28 = and i8 %r27, -128
+  %r29 = icmp eq i8 %r28, 0
+  %r30 = getelementptr i8, ptr %r22, i64 -6
+  %r31 = load i16, ptr %r30
+  %r32 = load i32, ptr %r22
+  %r33 = icmp eq i32 %r32, 1
+  %r34 = getelementptr i8, ptr %r22, i64 4
+  %r35 = load i32, ptr %r34
+  %r36 = icmp eq i32 %r35, 1
+  %r37 = getelementptr i8, ptr %r22, i64 12
+  %r38 = load i32, ptr %r37
+  %r39 = icmp ugt i32 %r38, 0
+  %r40 = getelementptr i8, ptr %r22, i64 16
+  %r41 = load i64, ptr %r40
+  %r42 = icmp eq i64 %r41, %r14
+  %r43 = and i1 %r25, %r29
+  %r44 = and i1 %r43, %r33
+  %r45 = and i1 %r44, %r36
+  %r46 = and i1 %r45, %r39
+  %r47 = and i1 %r46, %r42
+  %r48 = and i16 %r31, 2048
+  %r49 = icmp eq i16 %r48, 0
+  %r50 = and i1 %r47, %r49
+  %r51 = and i16 %r31, 4096
+  %r52 = icmp ne i16 %r51, 0
+  %r53 = and i1 %r50, %r52
+  br i1 %r53, label %class_field_get_number.fast.1, label %class_field_inline.guardcall.5
+
+class_field_inline.guardcall.5:
+  %r54 = call i32 @js_typed_feedback_class_field_get_guard(i64 7695367220062322688, double %r8, i32 1, i64 %r14, i64 %r13, i32 0, i32 1)
+  %r55 = icmp ne i32 %r54, 0
+  br i1 %r55, label %class_field_get_number.fast.1, label %class_field_get_number.fallback.2
+
+class_field_get_number.fast.6:
+  %r111 = inttoptr i64 %r65 to ptr
+  %r112 = getelementptr i8, ptr %r111, i64 32
+  %r113 = getelementptr double, ptr %r112, i64 0
+  %r114 = load double, ptr %r113
+  br label %class_field_get_number.merge.8
+
+class_field_get_number.fallback.7:
+  call void @js_typed_feedback_record_fallback_call(i64 7695367220062322689)
+  %r115 = call double @js_object_get_field_by_name_f64(i64 %r64, i64 %r68)
+  %r116 = call double @js_number_coerce(double %r115)
+  br label %class_field_get_number.merge.8
+
+class_field_get_number.merge.8:
+  %r117 = phi double [ %r114, %class_field_get_number.fast.6 ], [ %r116, %class_field_get_number.fallback.7 ]
+  %r118 = fmul double %r62, %r117
+  %r119 = load double, ptr %r7
+  %r120 = bitcast double %r119 to i64
+  %r121 = and i64 %r120, 281474976710655
+  %r122 = load double, ptr @spike_ts_.str.4.handle
+  %r123 = bitcast double %r122 to i64
+  %r124 = and i64 %r123, 281474976710655
+  %r125 = load i64, ptr @perry_class_keys_spike_ts__Point
+  %r126 = load volatile i8, ptr @PERRY_CLASS_FIELD_INLINE_GUARD_DISABLED
+  %r127 = icmp eq i8 %r126, 0
+  %r128 = lshr i64 %r120, 48
+  %r129 = icmp eq i64 %r128, 32765
+  %r130 = icmp ugt i64 %r121, 1048575
+  %r131 = and i1 %r129, %r130
+  %r132 = and i1 %r131, %r127
+  br i1 %r132, label %class_field_inline.deref.14, label %class_field_inline.guardcall.15
+
+class_field_inline.deref.9:
+  %r77 = inttoptr i64 %r65 to ptr
+  %r78 = getelementptr i8, ptr %r77, i64 -8
+  %r79 = load i8, ptr %r78
+  %r80 = icmp eq i8 %r79, 2
+  %r81 = getelementptr i8, ptr %r77, i64 -7
+  %r82 = load i8, ptr %r81
+  %r83 = and i8 %r82, -128
+  %r84 = icmp eq i8 %r83, 0
+  %r85 = getelementptr i8, ptr %r77, i64 -6
+  %r86 = load i16, ptr %r85
+  %r87 = load i32, ptr %r77
+  %r88 = icmp eq i32 %r87, 1
+  %r89 = getelementptr i8, ptr %r77, i64 4
+  %r90 = load i32, ptr %r89
+  %r91 = icmp eq i32 %r90, 1
+  %r92 = getelementptr i8, ptr %r77, i64 12
+  %r93 = load i32, ptr %r92
+  %r94 = icmp ugt i32 %r93, 0
+  %r95 = getelementptr i8, ptr %r77, i64 16
+  %r96 = load i64, ptr %r95
+  %r97 = icmp eq i64 %r96, %r69
+  %r98 = and i1 %r80, %r84
+  %r99 = and i1 %r98, %r88
+  %r100 = and i1 %r99, %r91
+  %r101 = and i1 %r100, %r94
+  %r102 = and i1 %r101, %r97
+  %r103 = and i16 %r86, 2048
+  %r104 = icmp eq i16 %r103, 0
+  %r105 = and i1 %r102, %r104
+  %r106 = and i16 %r86, 4096
+  %r107 = icmp ne i16 %r106, 0
+  %r108 = and i1 %r105, %r107
+  br i1 %r108, label %class_field_get_number.fast.6, label %class_field_inline.guardcall.10
+
+class_field_inline.guardcall.10:
+  %r109 = call i32 @js_typed_feedback_class_field_get_guard(i64 7695367220062322689, double %r63, i32 1, i64 %r69, i64 %r68, i32 0, i32 1)
+  %r110 = icmp ne i32 %r109, 0
+  br i1 %r110, label %class_field_get_number.fast.6, label %class_field_get_number.fallback.7
+
+class_field_get_number.fast.11:
+  %r167 = inttoptr i64 %r121 to ptr
+  %r168 = getelementptr i8, ptr %r167, i64 32
+  %r169 = getelementptr double, ptr %r168, i64 1
+  %r170 = load double, ptr %r169
+  br label %class_field_get_number.merge.13
+
+class_field_get_number.fallback.12:
+  call void @js_typed_feedback_record_fallback_call(i64 7695367220062322690)
+  %r171 = call double @js_object_get_field_by_name_f64(i64 %r120, i64 %r124)
+  %r172 = call double @js_number_coerce(double %r171)
+  br label %class_field_get_number.merge.13
+
+class_field_get_number.merge.13:
+  %r173 = phi double [ %r170, %class_field_get_number.fast.11 ], [ %r172, %class_field_get_number.fallback.12 ]
+  %r174 = load double, ptr %r7
+  %r175 = bitcast double %r174 to i64
+  %r176 = and i64 %r175, 281474976710655
+  %r177 = load double, ptr @spike_ts_.str.4.handle
+  %r178 = bitcast double %r177 to i64
+  %r179 = and i64 %r178, 281474976710655
+  %r180 = load i64, ptr @perry_class_keys_spike_ts__Point
+  %r181 = load volatile i8, ptr @PERRY_CLASS_FIELD_INLINE_GUARD_DISABLED
+  %r182 = icmp eq i8 %r181, 0
+  %r183 = lshr i64 %r175, 48
+  %r184 = icmp eq i64 %r183, 32765
+  %r185 = icmp ugt i64 %r176, 1048575
+  %r186 = and i1 %r184, %r185
+  %r187 = and i1 %r186, %r182
+  br i1 %r187, label %class_field_inline.deref.19, label %class_field_inline.guardcall.20
+
+class_field_inline.deref.14:
+  %r133 = inttoptr i64 %r121 to ptr
+  %r134 = getelementptr i8, ptr %r133, i64 -8
+  %r135 = load i8, ptr %r134
+  %r136 = icmp eq i8 %r135, 2
+  %r137 = getelementptr i8, ptr %r133, i64 -7
+  %r138 = load i8, ptr %r137
+  %r139 = and i8 %r138, -128
+  %r140 = icmp eq i8 %r139, 0
+  %r141 = getelementptr i8, ptr %r133, i64 -6
+  %r142 = load i16, ptr %r141
+  %r143 = load i32, ptr %r133
+  %r144 = icmp eq i32 %r143, 1
+  %r145 = getelementptr i8, ptr %r133, i64 4
+  %r146 = load i32, ptr %r145
+  %r147 = icmp eq i32 %r146, 1
+  %r148 = getelementptr i8, ptr %r133, i64 12
+  %r149 = load i32, ptr %r148
+  %r150 = icmp ugt i32 %r149, 1
+  %r151 = getelementptr i8, ptr %r133, i64 16
+  %r152 = load i64, ptr %r151
+  %r153 = icmp eq i64 %r152, %r125
+  %r154 = and i1 %r136, %r140
+  %r155 = and i1 %r154, %r144
+  %r156 = and i1 %r155, %r147
+  %r157 = and i1 %r156, %r150
+  %r158 = and i1 %r157, %r153
+  %r159 = and i16 %r142, 2048
+  %r160 = icmp eq i16 %r159, 0
+  %r161 = and i1 %r158, %r160
+  %r162 = and i16 %r142, 4096
+  %r163 = icmp ne i16 %r162, 0
+  %r164 = and i1 %r161, %r163
+  br i1 %r164, label %class_field_get_number.fast.11, label %class_field_inline.guardcall.15
+
+class_field_inline.guardcall.15:
+  %r165 = call i32 @js_typed_feedback_class_field_get_guard(i64 7695367220062322690, double %r119, i32 1, i64 %r125, i64 %r124, i32 1, i32 1)
+  %r166 = icmp ne i32 %r165, 0
+  br i1 %r166, label %class_field_get_number.fast.11, label %class_field_get_number.fallback.12
+
+class_field_get_number.fast.16:
+  %r222 = inttoptr i64 %r176 to ptr
+  %r223 = getelementptr i8, ptr %r222, i64 32
+  %r224 = getelementptr double, ptr %r223, i64 1
+  %r225 = load double, ptr %r224
+  br label %class_field_get_number.merge.18
+
+class_field_get_number.fallback.17:
+  call void @js_typed_feedback_record_fallback_call(i64 7695367220062322691)
+  %r226 = call double @js_object_get_field_by_name_f64(i64 %r175, i64 %r179)
+  %r227 = call double @js_number_coerce(double %r226)
+  br label %class_field_get_number.merge.18
+
+class_field_get_number.merge.18:
+  %r228 = phi double [ %r225, %class_field_get_number.fast.16 ], [ %r227, %class_field_get_number.fallback.17 ]
+  %r229 = fmul double %r173, %r228
+  %r230 = fadd double %r118, %r229
+  %r231 = call double @llvm.sqrt.f64(double %r230)
+  %shadow_pop_l_0 = load i64, ptr %r1
+  call void @js_shadow_frame_pop(i64 %shadow_pop_l_0)
+  ret double %r231
+
+class_field_inline.deref.19:
+  %r188 = inttoptr i64 %r176 to ptr
+  %r189 = getelementptr i8, ptr %r188, i64 -8
+  %r190 = load i8, ptr %r189
+  %r191 = icmp eq i8 %r190, 2
+  %r192 = getelementptr i8, ptr %r188, i64 -7
+  %r193 = load i8, ptr %r192
+  %r194 = and i8 %r193, -128
+  %r195 = icmp eq i8 %r194, 0
+  %r196 = getelementptr i8, ptr %r188, i64 -6
+  %r197 = load i16, ptr %r196
+  %r198 = load i32, ptr %r188
+  %r199 = icmp eq i32 %r198, 1
+  %r200 = getelementptr i8, ptr %r188, i64 4
+  %r201 = load i32, ptr %r200
+  %r202 = icmp eq i32 %r201, 1
+  %r203 = getelementptr i8, ptr %r188, i64 12
+  %r204 = load i32, ptr %r203
+  %r205 = icmp ugt i32 %r204, 1
+  %r206 = getelementptr i8, ptr %r188, i64 16
+  %r207 = load i64, ptr %r206
+  %r208 = icmp eq i64 %r207, %r180
+  %r209 = and i1 %r191, %r195
+  %r210 = and i1 %r209, %r199
+  %r211 = and i1 %r210, %r202
+  %r212 = and i1 %r211, %r205
+  %r213 = and i1 %r212, %r208
+  %r214 = and i16 %r197, 2048
+  %r215 = icmp eq i16 %r214, 0
+  %r216 = and i1 %r213, %r215
+  %r217 = and i16 %r197, 4096
+  %r218 = icmp ne i16 %r217, 0
+  %r219 = and i1 %r216, %r218
+  br i1 %r219, label %class_field_get_number.fast.16, label %class_field_inline.guardcall.20
+
+class_field_inline.guardcall.20:
+  %r220 = call i32 @js_typed_feedback_class_field_get_guard(i64 7695367220062322691, double %r174, i32 1, i64 %r180, i64 %r179, i32 1, i32 1)
+  %r221 = icmp ne i32 %r220, 0
+  br i1 %r221, label %class_field_get_number.fast.16, label %class_field_get_number.fallback.17
+}
+
+define internal double @perry_method_spike_ts__Point__norm__pshape(double %this_arg) {
+entry.0:
+  %r1 = alloca i64
+  %r2 = alloca ptr
+  store ptr null, ptr %r2
+  %r3 = call ptr @js_shadow_frame_enter(i32 1)
+  store ptr %r3, ptr %r2
+  %r4 = getelementptr inbounds i8, ptr %r3, i64 24
+  %r5 = load i64, ptr %r4
+  %r6 = sub i64 %r5, 1
+  store i64 %r6, ptr %r1
+  %r7 = alloca double
+  store double %this_arg, ptr %r7
+  call void @js_shadow_slot_bind(i32 0, ptr %r7)
+  %r8 = load double, ptr %r7
+  %r9 = bitcast double %r8 to i64
+  %r10 = and i64 %r9, 281474976710655
+  %r11 = inttoptr i64 %r10 to ptr
+  %r12 = getelementptr i8, ptr %r11, i64 32
+  %r13 = getelementptr double, ptr %r12, i64 0
+  %r14 = load double, ptr %r13
+  %r15 = bitcast double %r14 to i64
+  %r16 = and i64 %r15, 9218868437227405312
+  %r17 = icmp ne i64 %r16, 9218868437227405312
+  br i1 %r17, label %ptr_shape_get_number.plain.1, label %ptr_shape_get_number.coerce.2
+
+ptr_shape_get_number.plain.1:
+  br label %ptr_shape_get_number.merge.3
+
+ptr_shape_get_number.coerce.2:
+  %r18 = call double @js_number_coerce(double %r14)
+  br label %ptr_shape_get_number.merge.3
+
+ptr_shape_get_number.merge.3:
+  %r19 = phi double [ %r14, %ptr_shape_get_number.plain.1 ], [ %r18, %ptr_shape_get_number.coerce.2 ]
+  %r20 = load double, ptr %r7
+  %r21 = bitcast double %r20 to i64
+  %r22 = and i64 %r21, 281474976710655
+  %r23 = inttoptr i64 %r22 to ptr
+  %r24 = getelementptr i8, ptr %r23, i64 32
+  %r25 = getelementptr double, ptr %r24, i64 0
+  %r26 = load double, ptr %r25
+  %r27 = bitcast double %r26 to i64
+  %r28 = and i64 %r27, 9218868437227405312
+  %r29 = icmp ne i64 %r28, 9218868437227405312
+  br i1 %r29, label %ptr_shape_get_number.plain.4, label %ptr_shape_get_number.coerce.5
+
+ptr_shape_get_number.plain.4:
+  br label %ptr_shape_get_number.merge.6
+
+ptr_shape_get_number.coerce.5:
+  %r30 = call double @js_number_coerce(double %r26)
+  br label %ptr_shape_get_number.merge.6
+
+ptr_shape_get_number.merge.6:
+  %r31 = phi double [ %r26, %ptr_shape_get_number.plain.4 ], [ %r30, %ptr_shape_get_number.coerce.5 ]
+  %r32 = fmul double %r19, %r31
+  %r33 = load double, ptr %r7
+  %r34 = bitcast double %r33 to i64
+  %r35 = and i64 %r34, 281474976710655
+  %r36 = inttoptr i64 %r35 to ptr
+  %r37 = getelementptr i8, ptr %r36, i64 32
+  %r38 = getelementptr double, ptr %r37, i64 1
+  %r39 = load double, ptr %r38
+  %r40 = bitcast double %r39 to i64
+  %r41 = and i64 %r40, 9218868437227405312
+  %r42 = icmp ne i64 %r41, 9218868437227405312
+  br i1 %r42, label %ptr_shape_get_number.plain.7, label %ptr_shape_get_number.coerce.8
+
+ptr_shape_get_number.plain.7:
+  br label %ptr_shape_get_number.merge.9
+
+ptr_shape_get_number.coerce.8:
+  %r43 = call double @js_number_coerce(double %r39)
+  br label %ptr_shape_get_number.merge.9
+
+ptr_shape_get_number.merge.9:
+  %r44 = phi double [ %r39, %ptr_shape_get_number.plain.7 ], [ %r43, %ptr_shape_get_number.coerce.8 ]
+  %r45 = load double, ptr %r7
+  %r46 = bitcast double %r45 to i64
+  %r47 = and i64 %r46, 281474976710655
+  %r48 = inttoptr i64 %r47 to ptr
+  %r49 = getelementptr i8, ptr %r48, i64 32
+  %r50 = getelementptr double, ptr %r49, i64 1
+  %r51 = load double, ptr %r50
+  %r52 = bitcast double %r51 to i64
+  %r53 = and i64 %r52, 9218868437227405312
+  %r54 = icmp ne i64 %r53, 9218868437227405312
+  br i1 %r54, label %ptr_shape_get_number.plain.10, label %ptr_shape_get_number.coerce.11
+
+ptr_shape_get_number.plain.10:
+  br label %ptr_shape_get_number.merge.12
+
+ptr_shape_get_number.coerce.11:
+  %r55 = call double @js_number_coerce(double %r51)
+  br label %ptr_shape_get_number.merge.12
+
+ptr_shape_get_number.merge.12:
+  %r56 = phi double [ %r51, %ptr_shape_get_number.plain.10 ], [ %r55, %ptr_shape_get_number.coerce.11 ]
+  %r57 = fmul double %r44, %r56
+  %r58 = fadd double %r32, %r57
+  %r59 = call double @llvm.sqrt.f64(double %r58)
+  %shadow_pop_l_0 = load i64, ptr %r1
+  call void @js_shadow_frame_pop(i64 %shadow_pop_l_0)
+  ret double %r59
+}
+
+define double @spike_ts__Point_constructor(double %this_arg, double %arg16, double %arg17) {
+entry.0:
+  %r1 = alloca i64
+  %r2 = alloca ptr
+  store ptr null, ptr %r2
+  %r3 = call ptr @js_shadow_frame_enter(i32 1)
+  store ptr %r3, ptr %r2
+  %r4 = getelementptr inbounds i8, ptr %r3, i64 24
+  %r5 = load i64, ptr %r4
+  %r6 = sub i64 %r5, 1
+  store i64 %r6, ptr %r1
+  %r7 = alloca double
+  store double %this_arg, ptr %r7
+  call void @js_shadow_slot_bind(i32 0, ptr %r7)
+  %r8 = alloca double
+  store double %arg16, ptr %r8
+  %r9 = alloca double
+  store double %arg17, ptr %r9
+  %r10 = load double, ptr %r7
+  %r11 = bitcast double %r10 to i64
+  %r12 = and i64 %r11, 281474976710655
+  %r13 = load double, ptr @spike_ts_.str.3.handle
+  %r14 = bitcast double %r13 to i64
+  %r15 = and i64 %r14, 281474976710655
+  %r16 = load i64, ptr @perry_class_keys_spike_ts__Point
+  %r17 = bitcast double 0x7FFC000000000001 to i64
+  %r18 = load volatile i8, ptr @PERRY_CLASS_FIELD_INLINE_GUARD_DISABLED
+  %r19 = icmp eq i8 %r18, 0
+  %r20 = lshr i64 %r11, 48
+  %r21 = icmp eq i64 %r20, 32765
+  %r22 = icmp ugt i64 %r12, 1048575
+  %r23 = and i1 %r21, %r22
+  %r24 = and i1 %r23, %r19
+  br i1 %r24, label %class_field_inline.deref.4, label %class_field_inline.guardcall.5
+
+class_field_set.fast.1:
+  %r65 = inttoptr i64 %r12 to ptr
+  %r66 = getelementptr i8, ptr %r65, i64 32
+  %r67 = getelementptr double, ptr %r66, i64 0
+  %r68 = call double @js_array_numeric_value_to_raw_f64(double 0x7FFC000000000001)
+  store double %r68, ptr %r67
+  br label %class_field_set.merge.3
+
+class_field_set.fallback.2:
+  call void @js_class_field_set_fallback(i64 7695367220062322692, i64 %r11, i64 %r15, double 0x7FFC000000000001)
+  br label %class_field_set.merge.3
+
+class_field_set.merge.3:
+  %r69 = load double, ptr %r7
+  %r70 = bitcast double %r69 to i64
+  %r71 = and i64 %r70, 281474976710655
+  %r72 = load double, ptr @spike_ts_.str.4.handle
+  %r73 = bitcast double %r72 to i64
+  %r74 = and i64 %r73, 281474976710655
+  %r75 = load i64, ptr @perry_class_keys_spike_ts__Point
+  %r76 = bitcast double 0x7FFC000000000001 to i64
+  %r77 = load volatile i8, ptr @PERRY_CLASS_FIELD_INLINE_GUARD_DISABLED
+  %r78 = icmp eq i8 %r77, 0
+  %r79 = lshr i64 %r70, 48
+  %r80 = icmp eq i64 %r79, 32765
+  %r81 = icmp ugt i64 %r71, 1048575
+  %r82 = and i1 %r80, %r81
+  %r83 = and i1 %r82, %r78
+  br i1 %r83, label %class_field_inline.deref.9, label %class_field_inline.guardcall.10
+
+class_field_inline.deref.4:
+  %r25 = inttoptr i64 %r12 to ptr
+  %r26 = getelementptr i8, ptr %r25, i64 -8
+  %r27 = load i8, ptr %r26
+  %r28 = icmp eq i8 %r27, 2
+  %r29 = getelementptr i8, ptr %r25, i64 -7
+  %r30 = load i8, ptr %r29
+  %r31 = and i8 %r30, -128
+  %r32 = icmp eq i8 %r31, 0
+  %r33 = getelementptr i8, ptr %r25, i64 -6
+  %r34 = load i16, ptr %r33
+  %r35 = load i32, ptr %r25
+  %r36 = icmp eq i32 %r35, 1
+  %r37 = getelementptr i8, ptr %r25, i64 4
+  %r38 = load i32, ptr %r37
+  %r39 = icmp eq i32 %r38, 1
+  %r40 = getelementptr i8, ptr %r25, i64 12
+  %r41 = load i32, ptr %r40
+  %r42 = icmp ugt i32 %r41, 0
+  %r43 = getelementptr i8, ptr %r25, i64 16
+  %r44 = load i64, ptr %r43
+  %r45 = icmp eq i64 %r44, %r16
+  %r46 = and i1 %r28, %r32
+  %r47 = and i1 %r46, %r36
+  %r48 = and i1 %r47, %r39
+  %r49 = and i1 %r48, %r42
+  %r50 = and i1 %r49, %r45
+  %r51 = and i16 %r34, 2048
+  %r52 = icmp eq i16 %r51, 0
+  %r53 = and i1 %r50, %r52
+  %r54 = and i16 %r34, 4096
+  %r55 = icmp ne i16 %r54, 0
+  %r56 = and i1 %r53, %r55
+  %r57 = and i16 %r34, 1
+  %r58 = icmp eq i16 %r57, 0
+  %r59 = and i1 %r56, %r58
+  %r60 = and i64 %r17, 9218868437227405312
+  %r61 = icmp ne i64 %r60, 9218868437227405312
+  %r62 = and i1 %r59, %r61
+  br i1 %r62, label %class_field_set.fast.1, label %class_field_inline.guardcall.5
+
+class_field_inline.guardcall.5:
+  %r63 = call i32 @js_typed_feedback_class_field_set_guard(i64 7695367220062322692, double %r10, i32 1, i64 %r16, i64 %r15, i32 0, double 0x7FFC000000000001, i32 1)
+  %r64 = icmp ne i32 %r63, 0
+  br i1 %r64, label %class_field_set.fast.1, label %class_field_set.fallback.2
+
+class_field_set.fast.6:
+  %r124 = inttoptr i64 %r71 to ptr
+  %r125 = getelementptr i8, ptr %r124, i64 32
+  %r126 = getelementptr double, ptr %r125, i64 1
+  %r127 = call double @js_array_numeric_value_to_raw_f64(double 0x7FFC000000000001)
+  store double %r127, ptr %r126
+  br label %class_field_set.merge.8
+
+class_field_set.fallback.7:
+  call void @js_class_field_set_fallback(i64 7695367220062322693, i64 %r70, i64 %r74, double 0x7FFC000000000001)
+  br label %class_field_set.merge.8
+
+class_field_set.merge.8:
+  %r128 = load double, ptr %r7
+  %r129 = load double, ptr %r8
+  %r130 = bitcast double %r128 to i64
+  %r131 = and i64 %r130, 281474976710655
+  %r132 = load double, ptr @spike_ts_.str.3.handle
+  %r133 = bitcast double %r132 to i64
+  %r134 = and i64 %r133, 281474976710655
+  %r135 = load i64, ptr @perry_class_keys_spike_ts__Point
+  %r136 = bitcast double %r129 to i64
+  %r137 = load volatile i8, ptr @PERRY_CLASS_FIELD_INLINE_GUARD_DISABLED
+  %r138 = icmp eq i8 %r137, 0
+  %r139 = lshr i64 %r130, 48
+  %r140 = icmp eq i64 %r139, 32765
+  %r141 = icmp ugt i64 %r131, 1048575
+  %r142 = and i1 %r140, %r141
+  %r143 = and i1 %r142, %r138
+  br i1 %r143, label %class_field_inline.deref.14, label %class_field_inline.guardcall.15
+
+class_field_inline.deref.9:
+  %r84 = inttoptr i64 %r71 to ptr
+  %r85 = getelementptr i8, ptr %r84, i64 -8
+  %r86 = load i8, ptr %r85
+  %r87 = icmp eq i8 %r86, 2
+  %r88 = getelementptr i8, ptr %r84, i64 -7
+  %r89 = load i8, ptr %r88
+  %r90 = and i8 %r89, -128
+  %r91 = icmp eq i8 %r90, 0
+  %r92 = getelementptr i8, ptr %r84, i64 -6
+  %r93 = load i16, ptr %r92
+  %r94 = load i32, ptr %r84
+  %r95 = icmp eq i32 %r94, 1
+  %r96 = getelementptr i8, ptr %r84, i64 4
+  %r97 = load i32, ptr %r96
+  %r98 = icmp eq i32 %r97, 1
+  %r99 = getelementptr i8, ptr %r84, i64 12
+  %r100 = load i32, ptr %r99
+  %r101 = icmp ugt i32 %r100, 1
+  %r102 = getelementptr i8, ptr %r84, i64 16
+  %r103 = load i64, ptr %r102
+  %r104 = icmp eq i64 %r103, %r75
+  %r105 = and i1 %r87, %r91
+  %r106 = and i1 %r105, %r95
+  %r107 = and i1 %r106, %r98
+  %r108 = and i1 %r107, %r101
+  %r109 = and i1 %r108, %r104
+  %r110 = and i16 %r93, 2048
+  %r111 = icmp eq i16 %r110, 0
+  %r112 = and i1 %r109, %r111
+  %r113 = and i16 %r93, 4096
+  %r114 = icmp ne i16 %r113, 0
+  %r115 = and i1 %r112, %r114
+  %r116 = and i16 %r93, 1
+  %r117 = icmp eq i16 %r116, 0
+  %r118 = and i1 %r115, %r117
+  %r119 = and i64 %r76, 9218868437227405312
+  %r120 = icmp ne i64 %r119, 9218868437227405312
+  %r121 = and i1 %r118, %r120
+  br i1 %r121, label %class_field_set.fast.6, label %class_field_inline.guardcall.10
+
+class_field_inline.guardcall.10:
+  %r122 = call i32 @js_typed_feedback_class_field_set_guard(i64 7695367220062322693, double %r69, i32 1, i64 %r75, i64 %r74, i32 1, double 0x7FFC000000000001, i32 1)
+  %r123 = icmp ne i32 %r122, 0
+  br i1 %r123, label %class_field_set.fast.6, label %class_field_set.fallback.7
+
+class_field_set.fast.11:
+  %r184 = inttoptr i64 %r131 to ptr
+  %r185 = getelementptr i8, ptr %r184, i64 32
+  %r186 = getelementptr double, ptr %r185, i64 0
+  %r187 = call double @js_array_numeric_value_to_raw_f64(double %r129)
+  store double %r187, ptr %r186
+  br label %class_field_set.merge.13
+
+class_field_set.fallback.12:
+  call void @js_class_field_set_fallback(i64 7695367220062322694, i64 %r130, i64 %r134, double %r129)
+  br label %class_field_set.merge.13
+
+class_field_set.merge.13:
+  %r188 = load double, ptr %r7
+  %r189 = load double, ptr %r9
+  %r190 = bitcast double %r188 to i64
+  %r191 = and i64 %r190, 281474976710655
+  %r192 = load double, ptr @spike_ts_.str.4.handle
+  %r193 = bitcast double %r192 to i64
+  %r194 = and i64 %r193, 281474976710655
+  %r195 = load i64, ptr @perry_class_keys_spike_ts__Point
+  %r196 = bitcast double %r189 to i64
+  %r197 = load volatile i8, ptr @PERRY_CLASS_FIELD_INLINE_GUARD_DISABLED
+  %r198 = icmp eq i8 %r197, 0
+  %r199 = lshr i64 %r190, 48
+  %r200 = icmp eq i64 %r199, 32765
+  %r201 = icmp ugt i64 %r191, 1048575
+  %r202 = and i1 %r200, %r201
+  %r203 = and i1 %r202, %r198
+  br i1 %r203, label %class_field_inline.deref.19, label %class_field_inline.guardcall.20
+
+class_field_inline.deref.14:
+  %r144 = inttoptr i64 %r131 to ptr
+  %r145 = getelementptr i8, ptr %r144, i64 -8
+  %r146 = load i8, ptr %r145
+  %r147 = icmp eq i8 %r146, 2
+  %r148 = getelementptr i8, ptr %r144, i64 -7
+  %r149 = load i8, ptr %r148
+  %r150 = and i8 %r149, -128
+  %r151 = icmp eq i8 %r150, 0
+  %r152 = getelementptr i8, ptr %r144, i64 -6
+  %r153 = load i16, ptr %r152
+  %r154 = load i32, ptr %r144
+  %r155 = icmp eq i32 %r154, 1
+  %r156 = getelementptr i8, ptr %r144, i64 4
+  %r157 = load i32, ptr %r156
+  %r158 = icmp eq i32 %r157, 1
+  %r159 = getelementptr i8, ptr %r144, i64 12
+  %r160 = load i32, ptr %r159
+  %r161 = icmp ugt i32 %r160, 0
+  %r162 = getelementptr i8, ptr %r144, i64 16
+  %r163 = load i64, ptr %r162
+  %r164 = icmp eq i64 %r163, %r135
+  %r165 = and i1 %r147, %r151
+  %r166 = and i1 %r165, %r155
+  %r167 = and i1 %r166, %r158
+  %r168 = and i1 %r167, %r161
+  %r169 = and i1 %r168, %r164
+  %r170 = and i16 %r153, 2048
+  %r171 = icmp eq i16 %r170, 0
+  %r172 = and i1 %r169, %r171
+  %r173 = and i16 %r153, 4096
+  %r174 = icmp ne i16 %r173, 0
+  %r175 = and i1 %r172, %r174
+  %r176 = and i16 %r153, 1
+  %r177 = icmp eq i16 %r176, 0
+  %r178 = and i1 %r175, %r177
+  %r179 = and i64 %r136, 9218868437227405312
+  %r180 = icmp ne i64 %r179, 9218868437227405312
+  %r181 = and i1 %r178, %r180
+  br i1 %r181, label %class_field_set.fast.11, label %class_field_inline.guardcall.15
+
+class_field_inline.guardcall.15:
+  %r182 = call i32 @js_typed_feedback_class_field_set_guard(i64 7695367220062322694, double %r128, i32 1, i64 %r135, i64 %r134, i32 0, double %r129, i32 1)
+  %r183 = icmp ne i32 %r182, 0
+  br i1 %r183, label %class_field_set.fast.11, label %class_field_set.fallback.12
+
+class_field_set.fast.16:
+  %r244 = inttoptr i64 %r191 to ptr
+  %r245 = getelementptr i8, ptr %r244, i64 32
+  %r246 = getelementptr double, ptr %r245, i64 1
+  %r247 = call double @js_array_numeric_value_to_raw_f64(double %r189)
+  store double %r247, ptr %r246
+  br label %class_field_set.merge.18
+
+class_field_set.fallback.17:
+  call void @js_class_field_set_fallback(i64 7695367220062322695, i64 %r190, i64 %r194, double %r189)
+  br label %class_field_set.merge.18
+
+class_field_set.merge.18:
+  %shadow_pop_l_0 = load i64, ptr %r1
+  call void @js_shadow_frame_pop(i64 %shadow_pop_l_0)
+  ret double 0x7FFC000000000001
+
+class_field_inline.deref.19:
+  %r204 = inttoptr i64 %r191 to ptr
+  %r205 = getelementptr i8, ptr %r204, i64 -8
+  %r206 = load i8, ptr %r205
+  %r207 = icmp eq i8 %r206, 2
+  %r208 = getelementptr i8, ptr %r204, i64 -7
+  %r209 = load i8, ptr %r208
+  %r210 = and i8 %r209, -128
+  %r211 = icmp eq i8 %r210, 0
+  %r212 = getelementptr i8, ptr %r204, i64 -6
+  %r213 = load i16, ptr %r212
+  %r214 = load i32, ptr %r204
+  %r215 = icmp eq i32 %r214, 1
+  %r216 = getelementptr i8, ptr %r204, i64 4
+  %r217 = load i32, ptr %r216
+  %r218 = icmp eq i32 %r217, 1
+  %r219 = getelementptr i8, ptr %r204, i64 12
+  %r220 = load i32, ptr %r219
+  %r221 = icmp ugt i32 %r220, 1
+  %r222 = getelementptr i8, ptr %r204, i64 16
+  %r223 = load i64, ptr %r222
+  %r224 = icmp eq i64 %r223, %r195
+  %r225 = and i1 %r207, %r211
+  %r226 = and i1 %r225, %r215
+  %r227 = and i1 %r226, %r218
+  %r228 = and i1 %r227, %r221
+  %r229 = and i1 %r228, %r224
+  %r230 = and i16 %r213, 2048
+  %r231 = icmp eq i16 %r230, 0
+  %r232 = and i1 %r229, %r231
+  %r233 = and i16 %r213, 4096
+  %r234 = icmp ne i16 %r233, 0
+  %r235 = and i1 %r232, %r234
+  %r236 = and i16 %r213, 1
+  %r237 = icmp eq i16 %r236, 0
+  %r238 = and i1 %r235, %r237
+  %r239 = and i64 %r196, 9218868437227405312
+  %r240 = icmp ne i64 %r239, 9218868437227405312
+  %r241 = and i1 %r238, %r240
+  br i1 %r241, label %class_field_set.fast.16, label %class_field_inline.guardcall.20
+
+class_field_inline.guardcall.20:
+  %r242 = call i32 @js_typed_feedback_class_field_set_guard(i64 7695367220062322695, double %r188, i32 1, i64 %r195, i64 %r194, i32 1, double %r189, i32 1)
+  %r243 = icmp ne i32 %r242, 0
+  br i1 %r243, label %class_field_set.fast.16, label %class_field_set.fallback.17
+}
+
+define double @__perry_wrap_perry_fn_spike_ts__fib(i64 %this_closure, double %a0) {
+entry.0:
+  %r1 = call double @perry_fn_spike_ts__fib(double %a0)
+  ret double %r1
+}
+
+define double @__perry_wrap_perry_method_spike_ts__Point__norm(i64 %this_closure) {
+entry.0:
+  %r1 = call double @js_implicit_this_get()
+  %r2 = call double @perry_method_spike_ts__Point__norm(double %r1)
+  ret double %r2
+}
+
+define internal double @__perry_wrap_perry_unknown_func(i64 %this_closure, double %a0, double %a1, double %a2, double %a3, double %a4) {
+entry.0:
+  ret double 0x7FFC000000000001
+}
+
+define void @spike_ts__init() {
+entry.0:
+  ret void
+}
+
+define i32 @main() {
+entry.0:
+  %r1 = alloca i64
+  %r2 = alloca ptr
+  store ptr null, ptr %r2
+  %r7 = alloca double
+  store double 0x7FFC000000000001, ptr %r7
+  %r8 = alloca ptr
+  %r9 = call ptr @js_inline_arena_state()
+  store ptr %r9, ptr %r8
+  %r97 = alloca double
+  store double 0x7FFC000000000001, ptr %r97
+  %r138 = alloca double
+  store double 0x7FFC000000000001, ptr %r138
+  %r176 = alloca double
+  store double 0x7FFC000000000001, ptr %r176
+  %r177 = alloca double
+  store double 0x7FFC000000000001, ptr %r177
+  %r178 = alloca double
+  store double 0x7FFC000000000001, ptr %r178
+  %r179 = alloca double
+  store double 0x7FFC000000000001, ptr %r179
+  %r263 = alloca double
+  store double 0x7FFC000000000001, ptr %r263
+  %r291 = alloca double
+  store double 0x7FFC000000000001, ptr %r291
+  %r371 = alloca i64
+  %r383 = alloca i64
+  %r394 = alloca double
+  store double 0x7FFC000000000001, ptr %r394
+  %r461 = alloca [5 x i64]
+  call void @js_gc_init()
+  call void @js_gc_write_barriers_emitted(i32 1)
+  call void @perry_macos_bundle_chdir()
+  call void @__perry_init_strings_spike_ts()
+  %r3 = call ptr @js_shadow_frame_enter(i32 6)
+  store ptr %r3, ptr %r2
+  %r4 = getelementptr inbounds i8, ptr %r3, i64 24
+  %r5 = load i64, ptr %r4
+  %r6 = sub i64 %r5, 1
+  store i64 %r6, ptr %r1
+  %r372 = load i64, ptr @perry_class_keys_spike_ts__Point
+  store i64 %r372, ptr %r371
+  %r384 = load i64, ptr @perry_class_keys_spike_ts__Point
+  store i64 %r384, ptr %r383
+  %r10 = load ptr, ptr %r8
+  %r11 = getelementptr i8, ptr %r10, i64 8
+  %r12 = load i64, ptr %r11
+  %r13 = add i64 %r12, 80
+  %r14 = getelementptr i8, ptr %r10, i64 16
+  %r15 = load i64, ptr %r14
+  %r16 = icmp ule i64 %r13, %r15
+  br i1 %r16, label %arrlit.fast.1, label %arrlit.slow.2
+
+arrlit.fast.1:
+  store i64 %r13, ptr %r11
+  %r17 = load ptr, ptr %r10
+  %r18 = getelementptr i8, ptr %r17, i64 %r12
+  br label %arrlit.merge.3
+
+arrlit.slow.2:
+  %r19 = call ptr @js_inline_arena_slow_alloc(ptr %r10, i64 80, i64 8)
+  br label %arrlit.merge.3
+
+arrlit.merge.3:
+  %r20 = phi ptr [ %r18, %arrlit.fast.1 ], [ %r19, %arrlit.slow.2 ]
+  store i64 344671126017, ptr %r20
+  %r21 = getelementptr i8, ptr %r20, i64 8
+  store i64 34359738376, ptr %r21
+  %r22 = getelementptr i8, ptr %r20, i64 8
+  %r23 = ptrtoint ptr %r22 to i64
+  %r24 = getelementptr inbounds i8, ptr %r20, i64 16
+  store double 3.0, ptr %r24
+  %r25 = getelementptr inbounds i8, ptr %r20, i64 24
+  store double 1.0, ptr %r25
+  %r26 = getelementptr inbounds i8, ptr %r20, i64 32
+  store double 4.0, ptr %r26
+  %r27 = getelementptr inbounds i8, ptr %r20, i64 40
+  store double 1.0, ptr %r27
+  %r28 = getelementptr inbounds i8, ptr %r20, i64 48
+  store double 5.0, ptr %r28
+  %r29 = getelementptr inbounds i8, ptr %r20, i64 56
+  store double 9.0, ptr %r29
+  %r30 = getelementptr inbounds i8, ptr %r20, i64 64
+  store double 2.0, ptr %r30
+  %r31 = getelementptr inbounds i8, ptr %r20, i64 72
+  store double 6.0, ptr %r31
+  %r32 = call i32 @js_array_mark_numeric_f64_layout(i64 %r23)
+  %r33 = or i64 %r23, 9222527611924643840
+  %r34 = bitcast i64 %r33 to double
+  store double %r34, ptr %r7
+  %r35 = load ptr, ptr %r2
+  %r36 = icmp eq ptr %r35, null
+  br i1 %r36, label %ss.slow.4, label %ss.chk_top.5
+
+ss.slow.4:
+  call void @js_shadow_slot_bind(i32 0, ptr %r7)
+  br label %ss.done.8
+
+ss.chk_top.5:
+  %r37 = getelementptr inbounds i8, ptr %r35, i64 24
+  %r38 = load i64, ptr %r37
+  %r39 = icmp eq i64 %r38, -1
+  br i1 %r39, label %ss.done.8, label %ss.chk_len.6
+
+ss.chk_len.6:
+  %r40 = add i64 %r38, 0
+  %r41 = getelementptr inbounds i8, ptr %r35, i64 8
+  %r42 = load i64, ptr %r41
+  %r43 = icmp ult i64 %r40, %r42
+  br i1 %r43, label %ss.store.7, label %ss.done.8
+
+ss.store.7:
+  %r44 = load ptr, ptr %r35
+  %r45 = shl i64 %r40, 4
+  %r46 = getelementptr inbounds i8, ptr %r44, i64 %r45
+  %r47 = getelementptr inbounds i8, ptr %r46, i64 8
+  %r48 = load i64, ptr %r7
+  %r49 = ptrtoint ptr %r7 to i64
+  %r50 = and i64 %r49, 1
+  %r51 = icmp eq i64 %r50, 0
+  %r52 = select i1 %r51, i64 %r49, i64 0
+  %r53 = or i64 %r52, 1
+  store i64 %r48, ptr %r46
+  store i64 %r53, ptr %r47
+  %r54 = load atomic i32, ptr @PERRY_INCREMENTAL_MARK_BARRIER_ACTIVE_COUNT seq_cst, align 4
+  %r55 = icmp ne i32 %r54, 0
+  br i1 %r55, label %ss.barrier.9, label %ss.done.8
+
+ss.done.8:
+  %r56 = load double, ptr %r7
+  %r57 = call i64 @js_closure_alloc_singleton(ptr @perry_closure_spike_ts__1)
+  %r58 = or i64 %r57, 9222527611924643840
+  %r59 = bitcast i64 %r58 to double
+  %r60 = bitcast double %r56 to i64
+  %r61 = and i64 %r60, 281474976710655
+  %r62 = call i64 @js_validate_array_comparator(double %r59)
+  %r63 = call i64 @js_array_sort_with_comparator(i64 %r61, i64 %r62)
+  %r64 = or i64 %r63, 9222527611924643840
+  %r65 = bitcast i64 %r64 to double
+  %r66 = call i64 @js_array_alloc(i32 2)
+  %r67 = call i32 @js_gc_temp_root_push(i64 %r66)
+  %r68 = load double, ptr @spike_ts_.str.5.handle
+  call void @js_array_push_f64_temp_rooted(i32 %r67, double %r68)
+  %r69 = call double @perry_fn_spike_ts__fib(double 20.0)
+  call void @js_array_push_f64_temp_rooted(i32 %r67, double %r69)
+  %r70 = call i64 @js_gc_temp_root_get(i32 %r67)
+  call void @js_console_log_spread(i64 %r70)
+  call void @js_gc_temp_root_truncate(i32 %r67)
+  %r71 = call i64 @js_array_alloc(i32 2)
+  %r72 = call i32 @js_gc_temp_root_push(i64 %r71)
+  %r73 = load double, ptr @spike_ts_.str.6.handle
+  call void @js_array_push_f64_temp_rooted(i32 %r72, double %r73)
+  %r74 = load double, ptr %r7
+  %r75 = load double, ptr @spike_ts_.str.7.handle
+  %r76 = bitcast double %r74 to i64
+  %r77 = and i64 %r76, 281474976710655
+  %r78 = call i64 @js_array_join_value(i64 %r77, double %r75)
+  %r79 = or i64 %r78, 9223090561878065152
+  %r80 = bitcast i64 %r79 to double
+  call void @js_array_push_f64_temp_rooted(i32 %r72, double %r80)
+  %r81 = call i64 @js_gc_temp_root_get(i32 %r72)
+  call void @js_console_log_spread(i64 %r81)
+  call void @js_gc_temp_root_truncate(i32 %r72)
+  %r82 = load ptr, ptr %r2
+  %r83 = icmp eq ptr %r82, null
+  br i1 %r83, label %ss.slow.10, label %ss.chk_top.11
+
+ss.barrier.9:
+  call void @js_write_barrier_root_nanbox(i64 %r48)
+  br label %ss.done.8
+
+ss.slow.10:
+  call void @js_shadow_slot_set(i32 0, i64 0)
+  br label %ss.done.14
+
+ss.chk_top.11:
+  %r84 = getelementptr inbounds i8, ptr %r82, i64 24
+  %r85 = load i64, ptr %r84
+  %r86 = icmp eq i64 %r85, -1
+  br i1 %r86, label %ss.done.14, label %ss.chk_len.12
+
+ss.chk_len.12:
+  %r87 = add i64 %r85, 0
+  %r88 = getelementptr inbounds i8, ptr %r82, i64 8
+  %r89 = load i64, ptr %r88
+  %r90 = icmp ult i64 %r87, %r89
+  br i1 %r90, label %ss.store.13, label %ss.done.14
+
+ss.store.13:
+  %r91 = load ptr, ptr %r82
+  %r92 = shl i64 %r87, 4
+  %r93 = getelementptr inbounds i8, ptr %r91, i64 %r92
+  %r94 = getelementptr inbounds i8, ptr %r93, i64 8
+  %r95 = load i64, ptr %r94
+  %r96 = and i64 %r95, -2
+  store i64 0, ptr %r93
+  store i64 %r96, ptr %r94
+  br label %ss.done.14
+
+ss.done.14:
+  %r98 = call i64 @js_map_alloc(i32 8)
+  %r99 = or i64 %r98, 9222527611924643840
+  %r100 = bitcast i64 %r99 to double
+  store double %r100, ptr %r97
+  %r101 = load ptr, ptr %r2
+  %r102 = icmp eq ptr %r101, null
+  br i1 %r102, label %ss.slow.15, label %ss.chk_top.16
+
+ss.slow.15:
+  call void @js_shadow_slot_bind(i32 1, ptr %r97)
+  br label %ss.done.19
+
+ss.chk_top.16:
+  %r103 = getelementptr inbounds i8, ptr %r101, i64 24
+  %r104 = load i64, ptr %r103
+  %r105 = icmp eq i64 %r104, -1
+  br i1 %r105, label %ss.done.19, label %ss.chk_len.17
+
+ss.chk_len.17:
+  %r106 = add i64 %r104, 1
+  %r107 = getelementptr inbounds i8, ptr %r101, i64 8
+  %r108 = load i64, ptr %r107
+  %r109 = icmp ult i64 %r106, %r108
+  br i1 %r109, label %ss.store.18, label %ss.done.19
+
+ss.store.18:
+  %r110 = load ptr, ptr %r101
+  %r111 = shl i64 %r106, 4
+  %r112 = getelementptr inbounds i8, ptr %r110, i64 %r111
+  %r113 = getelementptr inbounds i8, ptr %r112, i64 8
+  %r114 = load i64, ptr %r97
+  %r115 = ptrtoint ptr %r97 to i64
+  %r116 = and i64 %r115, 1
+  %r117 = icmp eq i64 %r116, 0
+  %r118 = select i1 %r117, i64 %r115, i64 0
+  %r119 = or i64 %r118, 1
+  store i64 %r114, ptr %r112
+  store i64 %r119, ptr %r113
+  %r120 = load atomic i32, ptr @PERRY_INCREMENTAL_MARK_BARRIER_ACTIVE_COUNT seq_cst, align 4
+  %r121 = icmp ne i32 %r120, 0
+  br i1 %r121, label %ss.barrier.20, label %ss.done.19
+
+ss.done.19:
+  %r122 = load double, ptr %r97
+  %r123 = load double, ptr @spike_ts_.str.8.handle
+  %r124 = bitcast double %r122 to i64
+  %r125 = and i64 %r124, 281474976710655
+  %r126 = call i64 @js_get_string_pointer_unified(double %r123)
+  %r127 = call i64 @js_map_set_string_number(i64 %r125, i64 %r126, double 1.0)
+  %r128 = or i64 %r127, 9222527611924643840
+  %r129 = bitcast i64 %r128 to double
+  %r130 = load double, ptr %r97
+  %r131 = load double, ptr @spike_ts_.str.9.handle
+  %r132 = bitcast double %r130 to i64
+  %r133 = and i64 %r132, 281474976710655
+  %r134 = call i64 @js_get_string_pointer_unified(double %r131)
+  %r135 = call i64 @js_map_set_string_number(i64 %r133, i64 %r134, double 2.0)
+  %r136 = or i64 %r135, 9222527611924643840
+  %r137 = bitcast i64 %r136 to double
+  %r139 = load double, ptr %r97
+  store double %r139, ptr %r138
+  %r140 = load ptr, ptr %r2
+  %r141 = icmp eq ptr %r140, null
+  br i1 %r141, label %ss.slow.21, label %ss.chk_top.22
+
+ss.barrier.20:
+  call void @js_write_barrier_root_nanbox(i64 %r114)
+  br label %ss.done.19
+
+ss.slow.21:
+  call void @js_shadow_slot_bind(i32 2, ptr %r138)
+  br label %ss.done.25
+
+ss.chk_top.22:
+  %r142 = getelementptr inbounds i8, ptr %r140, i64 24
+  %r143 = load i64, ptr %r142
+  %r144 = icmp eq i64 %r143, -1
+  br i1 %r144, label %ss.done.25, label %ss.chk_len.23
+
+ss.chk_len.23:
+  %r145 = add i64 %r143, 2
+  %r146 = getelementptr inbounds i8, ptr %r140, i64 8
+  %r147 = load i64, ptr %r146
+  %r148 = icmp ult i64 %r145, %r147
+  br i1 %r148, label %ss.store.24, label %ss.done.25
+
+ss.store.24:
+  %r149 = load ptr, ptr %r140
+  %r150 = shl i64 %r145, 4
+  %r151 = getelementptr inbounds i8, ptr %r149, i64 %r150
+  %r152 = getelementptr inbounds i8, ptr %r151, i64 8
+  %r153 = load i64, ptr %r138
+  %r154 = ptrtoint ptr %r138 to i64
+  %r155 = and i64 %r154, 1
+  %r156 = icmp eq i64 %r155, 0
+  %r157 = select i1 %r156, i64 %r154, i64 0
+  %r158 = or i64 %r157, 1
+  store i64 %r153, ptr %r151
+  store i64 %r158, ptr %r152
+  %r159 = load atomic i32, ptr @PERRY_INCREMENTAL_MARK_BARRIER_ACTIVE_COUNT seq_cst, align 4
+  %r160 = icmp ne i32 %r159, 0
+  br i1 %r160, label %ss.barrier.26, label %ss.done.25
+
+ss.done.25:
+  %r161 = load ptr, ptr %r2
+  %r162 = icmp eq ptr %r161, null
+  br i1 %r162, label %ss.slow.27, label %ss.chk_top.28
+
+ss.barrier.26:
+  call void @js_write_barrier_root_nanbox(i64 %r153)
+  br label %ss.done.25
+
+ss.slow.27:
+  call void @js_shadow_slot_set(i32 1, i64 0)
+  br label %ss.done.31
+
+ss.chk_top.28:
+  %r163 = getelementptr inbounds i8, ptr %r161, i64 24
+  %r164 = load i64, ptr %r163
+  %r165 = icmp eq i64 %r164, -1
+  br i1 %r165, label %ss.done.31, label %ss.chk_len.29
+
+ss.chk_len.29:
+  %r166 = add i64 %r164, 1
+  %r167 = getelementptr inbounds i8, ptr %r161, i64 8
+  %r168 = load i64, ptr %r167
+  %r169 = icmp ult i64 %r166, %r168
+  br i1 %r169, label %ss.store.30, label %ss.done.31
+
+ss.store.30:
+  %r170 = load ptr, ptr %r161
+  %r171 = shl i64 %r166, 4
+  %r172 = getelementptr inbounds i8, ptr %r170, i64 %r171
+  %r173 = getelementptr inbounds i8, ptr %r172, i64 8
+  %r174 = load i64, ptr %r173
+  %r175 = and i64 %r174, -2
+  store i64 0, ptr %r172
+  store i64 %r175, ptr %r173
+  br label %ss.done.31
+
+ss.done.31:
+  store double 0x7FFC000000000001, ptr %r176
+  store double 0.0, ptr %r177
+  store double 0.0, ptr %r178
+  store double 0.0, ptr %r179
+  br label %for.cond.32
+
+for.cond.32:
+  %r180 = load double, ptr %r138
+  %r181 = bitcast double %r180 to i64
+  %r182 = and i64 %r181, 281474976710655
+  %r183 = call i32 @js_map_size(i64 %r182)
+  %r184 = sitofp i32 %r183 to double
+  store double %r184, ptr %r177
+  %r185 = load double, ptr %r179
+  %r186 = fcmp oeq double %r185, 0.0
+  %r187 = select i1 %r186, i64 9222246136947933188, i64 9222246136947933187
+  %r188 = bitcast i64 %r187 to double
+  %r189 = icmp eq i64 %r187, 9222246136947933188
+  br i1 %r189, label %ternary.then.36, label %ternary.else.37
+
+for.body.33:
+  %r236 = load double, ptr %r138
+  %r237 = load double, ptr %r179
+  %r238 = bitcast double %r236 to i64
+  %r239 = and i64 %r238, 281474976710655
+  %r240 = fptosi double %r237 to i32
+  %r241 = call double @js_map_entry_key_at(i64 %r239, i32 %r240)
+  store double %r241, ptr %r176
+  %r242 = load ptr, ptr %r2
+  %r243 = icmp eq ptr %r242, null
+  br i1 %r243, label %ss.slow.48, label %ss.chk_top.49
+
+for.update.34:
+  %r319 = load double, ptr %r179
+  %r320 = call double @js_to_numeric(double %r319)
+  %r321 = call double @js_numeric_step(double %r320, i32 1)
+  store double %r321, ptr %r179
+  br label %for.cond.32
+
+for.exit.35:
+  %r322 = load ptr, ptr %r2
+  %r323 = icmp eq ptr %r322, null
+  br i1 %r323, label %ss.slow.65, label %ss.chk_top.66
+
+ternary.then.36:
+  %r190 = load double, ptr %r179
+  br label %ternary.merge.38
+
+ternary.else.37:
+  %r191 = load double, ptr %r138
+  %r192 = load double, ptr %r179
+  %r193 = fsub double %r192, 1.0
+  %r194 = bitcast double %r191 to i64
+  %r195 = and i64 %r194, 281474976710655
+  %r196 = fptosi double %r193 to i32
+  %r197 = call double @js_map_entry_key_at(i64 %r195, i32 %r196)
+  %r198 = load double, ptr %r176
+  %r199 = bitcast double %r197 to i64
+  %r200 = bitcast double %r198 to i64
+  %r201 = call i64 @js_eq(i64 %r199, i64 %r200)
+  %r202 = bitcast i64 %r201 to double
+  %r203 = icmp eq i64 %r201, 9222246136947933188
+  br i1 %r203, label %ternary.then.39, label %ternary.else.40
+
+ternary.merge.38:
+  %r228 = phi double [ %r190, %ternary.then.36 ], [ %r227, %ternary.merge.41 ]
+  store double %r228, ptr %r179
+  %r229 = load double, ptr %r179
+  %r230 = load double, ptr %r177
+  %r231 = fcmp olt double %r229, %r230
+  %r232 = select i1 %r231, i64 9222246136947933188, i64 9222246136947933187
+  %r233 = bitcast i64 %r232 to double
+  %r234 = call i32 @js_is_truthy(double %r233)
+  %r235 = icmp ne i32 %r234, 0
+  br i1 %r235, label %for.body.33, label %for.exit.35
+
+ternary.then.39:
+  %r204 = load double, ptr %r179
+  br label %ternary.merge.41
+
+ternary.else.40:
+  %r205 = load double, ptr %r138
+  %r206 = load double, ptr %r176
+  %r207 = call double @js_map_find_key_index(double %r205, double %r206)
+  store double %r207, ptr %r178
+  %r208 = load double, ptr %r178
+  %r209 = fcmp oge double %r208, 0.0
+  %r210 = select i1 %r209, i64 9222246136947933188, i64 9222246136947933187
+  %r211 = bitcast i64 %r210 to double
+  %r212 = icmp eq i64 %r210, 9222246136947933188
+  br i1 %r212, label %ternary.then.42, label %ternary.else.43
+
+ternary.merge.41:
+  %r227 = phi double [ %r204, %ternary.then.39 ], [ %r226, %ternary.merge.44 ]
+  br label %ternary.merge.38
+
+ternary.then.42:
+  %r213 = load double, ptr %r178
+  %r214 = load double, ptr %r179
+  %r215 = fcmp olt double %r213, %r214
+  %r216 = select i1 %r215, i64 9222246136947933188, i64 9222246136947933187
+  %r217 = bitcast i64 %r216 to double
+  %r218 = icmp eq i64 %r216, 9222246136947933188
+  br i1 %r218, label %ternary.then.45, label %ternary.else.46
+
+ternary.else.43:
+  %r224 = load double, ptr %r179
+  %r225 = fsub double %r224, 1.0
+  br label %ternary.merge.44
+
+ternary.merge.44:
+  %r226 = phi double [ %r223, %ternary.merge.47 ], [ %r225, %ternary.else.43 ]
+  br label %ternary.merge.41
+
+ternary.then.45:
+  %r219 = load double, ptr %r178
+  %r220 = fadd double %r219, 1.0
+  br label %ternary.merge.47
+
+ternary.else.46:
+  %r221 = load double, ptr %r179
+  %r222 = fsub double %r221, 1.0
+  br label %ternary.merge.47
+
+ternary.merge.47:
+  %r223 = phi double [ %r220, %ternary.then.45 ], [ %r222, %ternary.else.46 ]
+  br label %ternary.merge.44
+
+ss.slow.48:
+  call void @js_shadow_slot_bind(i32 3, ptr %r176)
+  br label %ss.done.52
+
+ss.chk_top.49:
+  %r244 = getelementptr inbounds i8, ptr %r242, i64 24
+  %r245 = load i64, ptr %r244
+  %r246 = icmp eq i64 %r245, -1
+  br i1 %r246, label %ss.done.52, label %ss.chk_len.50
+
+ss.chk_len.50:
+  %r247 = add i64 %r245, 3
+  %r248 = getelementptr inbounds i8, ptr %r242, i64 8
+  %r249 = load i64, ptr %r248
+  %r250 = icmp ult i64 %r247, %r249
+  br i1 %r250, label %ss.store.51, label %ss.done.52
+
+ss.store.51:
+  %r251 = load ptr, ptr %r242
+  %r252 = shl i64 %r247, 4
+  %r253 = getelementptr inbounds i8, ptr %r251, i64 %r252
+  %r254 = getelementptr inbounds i8, ptr %r253, i64 8
+  %r255 = load i64, ptr %r176
+  %r256 = ptrtoint ptr %r176 to i64
+  %r257 = and i64 %r256, 1
+  %r258 = icmp eq i64 %r257, 0
+  %r259 = select i1 %r258, i64 %r256, i64 0
+  %r260 = or i64 %r259, 1
+  store i64 %r255, ptr %r253
+  store i64 %r260, ptr %r254
+  %r261 = load atomic i32, ptr @PERRY_INCREMENTAL_MARK_BARRIER_ACTIVE_COUNT seq_cst, align 4
+  %r262 = icmp ne i32 %r261, 0
+  br i1 %r262, label %ss.barrier.53, label %ss.done.52
+
+ss.done.52:
+  %r264 = load double, ptr %r138
+  %r265 = load double, ptr %r179
+  %r266 = bitcast double %r264 to i64
+  %r267 = and i64 %r266, 281474976710655
+  %r268 = fptosi double %r265 to i32
+  %r269 = call double @js_map_entry_key_at(i64 %r267, i32 %r268)
+  store double %r269, ptr %r263
+  %r270 = load ptr, ptr %r2
+  %r271 = icmp eq ptr %r270, null
+  br i1 %r271, label %ss.slow.54, label %ss.chk_top.55
+
+ss.barrier.53:
+  call void @js_write_barrier_root_nanbox(i64 %r255)
+  br label %ss.done.52
+
+ss.slow.54:
+  call void @js_shadow_slot_bind(i32 4, ptr %r263)
+  br label %ss.done.58
+
+ss.chk_top.55:
+  %r272 = getelementptr inbounds i8, ptr %r270, i64 24
+  %r273 = load i64, ptr %r272
+  %r274 = icmp eq i64 %r273, -1
+  br i1 %r274, label %ss.done.58, label %ss.chk_len.56
+
+ss.chk_len.56:
+  %r275 = add i64 %r273, 4
+  %r276 = getelementptr inbounds i8, ptr %r270, i64 8
+  %r277 = load i64, ptr %r276
+  %r278 = icmp ult i64 %r275, %r277
+  br i1 %r278, label %ss.store.57, label %ss.done.58
+
+ss.store.57:
+  %r279 = load ptr, ptr %r270
+  %r280 = shl i64 %r275, 4
+  %r281 = getelementptr inbounds i8, ptr %r279, i64 %r280
+  %r282 = getelementptr inbounds i8, ptr %r281, i64 8
+  %r283 = load i64, ptr %r263
+  %r284 = ptrtoint ptr %r263 to i64
+  %r285 = and i64 %r284, 1
+  %r286 = icmp eq i64 %r285, 0
+  %r287 = select i1 %r286, i64 %r284, i64 0
+  %r288 = or i64 %r287, 1
+  store i64 %r283, ptr %r281
+  store i64 %r288, ptr %r282
+  %r289 = load atomic i32, ptr @PERRY_INCREMENTAL_MARK_BARRIER_ACTIVE_COUNT seq_cst, align 4
+  %r290 = icmp ne i32 %r289, 0
+  br i1 %r290, label %ss.barrier.59, label %ss.done.58
+
+ss.done.58:
+  %r292 = load double, ptr %r138
+  %r293 = load double, ptr %r179
+  %r294 = bitcast double %r292 to i64
+  %r295 = and i64 %r294, 281474976710655
+  %r296 = fptosi double %r293 to i32
+  %r297 = call double @js_map_entry_value_at(i64 %r295, i32 %r296)
+  store double %r297, ptr %r291
+  %r298 = call i64 @js_array_alloc(i32 3)
+  %r299 = call i32 @js_gc_temp_root_push(i64 %r298)
+  %r300 = load double, ptr %r263
+  call void @js_array_push_f64_temp_rooted(i32 %r299, double %r300)
+  %r301 = load double, ptr @spike_ts_.str.10.handle
+  call void @js_array_push_f64_temp_rooted(i32 %r299, double %r301)
+  %r302 = load double, ptr %r291
+  call void @js_array_push_f64_temp_rooted(i32 %r299, double %r302)
+  %r303 = call i64 @js_gc_temp_root_get(i32 %r299)
+  call void @js_console_log_spread(i64 %r303)
+  call void @js_gc_temp_root_truncate(i32 %r299)
+  %r304 = load ptr, ptr %r2
+  %r305 = icmp eq ptr %r304, null
+  br i1 %r305, label %ss.slow.60, label %ss.chk_top.61
+
+ss.barrier.59:
+  call void @js_write_barrier_root_nanbox(i64 %r283)
+  br label %ss.done.58
+
+ss.slow.60:
+  call void @js_shadow_slot_set(i32 4, i64 0)
+  br label %ss.done.64
+
+ss.chk_top.61:
+  %r306 = getelementptr inbounds i8, ptr %r304, i64 24
+  %r307 = load i64, ptr %r306
+  %r308 = icmp eq i64 %r307, -1
+  br i1 %r308, label %ss.done.64, label %ss.chk_len.62
+
+ss.chk_len.62:
+  %r309 = add i64 %r307, 4
+  %r310 = getelementptr inbounds i8, ptr %r304, i64 8
+  %r311 = load i64, ptr %r310
+  %r312 = icmp ult i64 %r309, %r311
+  br i1 %r312, label %ss.store.63, label %ss.done.64
+
+ss.store.63:
+  %r313 = load ptr, ptr %r304
+  %r314 = shl i64 %r309, 4
+  %r315 = getelementptr inbounds i8, ptr %r313, i64 %r314
+  %r316 = getelementptr inbounds i8, ptr %r315, i64 8
+  %r317 = load i64, ptr %r316
+  %r318 = and i64 %r317, -2
+  store i64 0, ptr %r315
+  store i64 %r318, ptr %r316
+  br label %ss.done.64
+
+ss.done.64:
+  br label %for.update.34
+
+ss.slow.65:
+  call void @js_shadow_slot_set(i32 2, i64 0)
+  br label %ss.done.69
+
+ss.chk_top.66:
+  %r324 = getelementptr inbounds i8, ptr %r322, i64 24
+  %r325 = load i64, ptr %r324
+  %r326 = icmp eq i64 %r325, -1
+  br i1 %r326, label %ss.done.69, label %ss.chk_len.67
+
+ss.chk_len.67:
+  %r327 = add i64 %r325, 2
+  %r328 = getelementptr inbounds i8, ptr %r322, i64 8
+  %r329 = load i64, ptr %r328
+  %r330 = icmp ult i64 %r327, %r329
+  br i1 %r330, label %ss.store.68, label %ss.done.69
+
+ss.store.68:
+  %r331 = load ptr, ptr %r322
+  %r332 = shl i64 %r327, 4
+  %r333 = getelementptr inbounds i8, ptr %r331, i64 %r332
+  %r334 = getelementptr inbounds i8, ptr %r333, i64 8
+  %r335 = load i64, ptr %r334
+  %r336 = and i64 %r335, -2
+  store i64 0, ptr %r333
+  store i64 %r336, ptr %r334
+  br label %ss.done.69
+
+ss.done.69:
+  %r337 = load ptr, ptr %r2
+  %r338 = icmp eq ptr %r337, null
+  br i1 %r338, label %ss.slow.70, label %ss.chk_top.71
+
+ss.slow.70:
+  call void @js_shadow_slot_set(i32 3, i64 0)
+  br label %ss.done.74
+
+ss.chk_top.71:
+  %r339 = getelementptr inbounds i8, ptr %r337, i64 24
+  %r340 = load i64, ptr %r339
+  %r341 = icmp eq i64 %r340, -1
+  br i1 %r341, label %ss.done.74, label %ss.chk_len.72
+
+ss.chk_len.72:
+  %r342 = add i64 %r340, 3
+  %r343 = getelementptr inbounds i8, ptr %r337, i64 8
+  %r344 = load i64, ptr %r343
+  %r345 = icmp ult i64 %r342, %r344
+  br i1 %r345, label %ss.store.73, label %ss.done.74
+
+ss.store.73:
+  %r346 = load ptr, ptr %r337
+  %r347 = shl i64 %r342, 4
+  %r348 = getelementptr inbounds i8, ptr %r346, i64 %r347
+  %r349 = getelementptr inbounds i8, ptr %r348, i64 8
+  %r350 = load i64, ptr %r349
+  %r351 = and i64 %r350, -2
+  store i64 0, ptr %r348
+  store i64 %r351, ptr %r349
+  br label %ss.done.74
+
+ss.done.74:
+  %r352 = load ptr, ptr %r2
+  %r353 = icmp eq ptr %r352, null
+  br i1 %r353, label %ss.slow.75, label %ss.chk_top.76
+
+ss.slow.75:
+  call void @js_shadow_slot_set(i32 4, i64 0)
+  br label %ss.done.79
+
+ss.chk_top.76:
+  %r354 = getelementptr inbounds i8, ptr %r352, i64 24
+  %r355 = load i64, ptr %r354
+  %r356 = icmp eq i64 %r355, -1
+  br i1 %r356, label %ss.done.79, label %ss.chk_len.77
+
+ss.chk_len.77:
+  %r357 = add i64 %r355, 4
+  %r358 = getelementptr inbounds i8, ptr %r352, i64 8
+  %r359 = load i64, ptr %r358
+  %r360 = icmp ult i64 %r357, %r359
+  br i1 %r360, label %ss.store.78, label %ss.done.79
+
+ss.store.78:
+  %r361 = load ptr, ptr %r352
+  %r362 = shl i64 %r357, 4
+  %r363 = getelementptr inbounds i8, ptr %r361, i64 %r362
+  %r364 = getelementptr inbounds i8, ptr %r363, i64 8
+  %r365 = load i64, ptr %r364
+  %r366 = and i64 %r365, -2
+  store i64 0, ptr %r363
+  store i64 %r366, ptr %r364
+  br label %ss.done.79
+
+ss.done.79:
+  %r367 = call i64 @js_array_alloc(i32 2)
+  %r368 = call i32 @js_gc_temp_root_push(i64 %r367)
+  %r369 = load double, ptr @spike_ts_.str.11.handle
+  call void @js_array_push_f64_temp_rooted(i32 %r368, double %r369)
+  %r370 = call i32 @js_gc_temp_root_push(i64 0)
+  %r373 = load i64, ptr %r371
+  %r374 = call i64 @js_object_alloc_class_inline_keys(i32 1, i32 0, i32 2, i64 %r373)
+  %r375 = call i32 @js_gc_temp_root_push(i64 %r374)
+  %r376 = or i64 %r374, 9222527611924643840
+  %r377 = bitcast i64 %r376 to double
+  %r378 = call double @spike_ts__Point_constructor(double %r377, double 3.0, double 4.0)
+  %r379 = call i64 @js_gc_temp_root_get(i32 %r375)
+  %r380 = or i64 %r379, 9222527611924643840
+  %r381 = bitcast i64 %r380 to double
+  call void @js_gc_init_typed_shape_layout(i64 %r379, i32 2, ptr @perry_typed_shape_raw_f64_mask_spike_ts__Point, i32 1, ptr null, i32 0)
+  %r382 = call double @js_ctor_return_override(double %r381, double %r378, i32 0)
+  call void @js_gc_temp_root_truncate(i32 %r370)
+  %r385 = load i64, ptr %r383
+  br label %method_direct.guard.80
+
+method_direct.guard.80:
+  %r386 = call i32 @js_method_direct_shape_guard(double %r382, i32 1, i64 %r385)
+  %r387 = icmp ne i32 %r386, 0
+  br i1 %r387, label %method_direct.fast.81, label %method_direct.fallback.82
+
+method_direct.fast.81:
+  %r388 = call double @perry_method_spike_ts__Point__norm__pshape(double %r382)
+  br label %method_direct.merge.83
+
+method_direct.fallback.82:
+  %r389 = ptrtoint ptr @spike_ts_.str.12.dispatch to i64
+  %r390 = or i64 %r389, 9221120237041090560
+  %r391 = call double @js_native_call_method_by_id(double %r382, i64 %r390, ptr null, i64 0)
+  br label %method_direct.merge.83
+
+method_direct.merge.83:
+  %r392 = phi double [ %r388, %method_direct.fast.81 ], [ %r391, %method_direct.fallback.82 ]
+  call void @js_array_push_f64_temp_rooted(i32 %r368, double %r392)
+  %r393 = call i64 @js_gc_temp_root_get(i32 %r368)
+  call void @js_console_log_spread(i64 %r393)
+  call void @js_gc_temp_root_truncate(i32 %r368)
+  %r395 = call i64 @js_closure_alloc_singleton(ptr @perry_closure_spike_ts__4)
+  %r396 = or i64 %r395, 9222527611924643840
+  %r397 = bitcast i64 %r396 to double
+  store double %r397, ptr %r394
+  %r398 = load ptr, ptr %r2
+  %r399 = icmp eq ptr %r398, null
+  br i1 %r399, label %ss.slow.84, label %ss.chk_top.85
+
+ss.slow.84:
+  call void @js_shadow_slot_bind(i32 5, ptr %r394)
+  br label %ss.done.88
+
+ss.chk_top.85:
+  %r400 = getelementptr inbounds i8, ptr %r398, i64 24
+  %r401 = load i64, ptr %r400
+  %r402 = icmp eq i64 %r401, -1
+  br i1 %r402, label %ss.done.88, label %ss.chk_len.86
+
+ss.chk_len.86:
+  %r403 = add i64 %r401, 5
+  %r404 = getelementptr inbounds i8, ptr %r398, i64 8
+  %r405 = load i64, ptr %r404
+  %r406 = icmp ult i64 %r403, %r405
+  br i1 %r406, label %ss.store.87, label %ss.done.88
+
+ss.store.87:
+  %r407 = load ptr, ptr %r398
+  %r408 = shl i64 %r403, 4
+  %r409 = getelementptr inbounds i8, ptr %r407, i64 %r408
+  %r410 = getelementptr inbounds i8, ptr %r409, i64 8
+  %r411 = load i64, ptr %r394
+  %r412 = ptrtoint ptr %r394 to i64
+  %r413 = and i64 %r412, 1
+  %r414 = icmp eq i64 %r413, 0
+  %r415 = select i1 %r414, i64 %r412, i64 0
+  %r416 = or i64 %r415, 1
+  store i64 %r411, ptr %r409
+  store i64 %r416, ptr %r410
+  %r417 = load atomic i32, ptr @PERRY_INCREMENTAL_MARK_BARRIER_ACTIVE_COUNT seq_cst, align 4
+  %r418 = icmp ne i32 %r417, 0
+  br i1 %r418, label %ss.barrier.89, label %ss.done.88
+
+ss.done.88:
+  %r419 = load double, ptr %r394
+  %r420 = load double, ptr @spike_ts_.str.13.handle
+  %r421 = bitcast double %r419 to i64
+  %r422 = and i64 %r421, 281474976710655
+  %r423 = call i32 @js_typed_feedback_closure_direct_call_guard(i64 7695367220062322696, double %r419, ptr @perry_closure_spike_ts__4, i32 1, i32 1)
+  %r424 = icmp ne i32 %r423, 0
+  br i1 %r424, label %closure_direct.fast.90, label %closure_direct.fallback.91
+
+ss.barrier.89:
+  call void @js_write_barrier_root_nanbox(i64 %r411)
+  br label %ss.done.88
+
+closure_direct.fast.90:
+  %r425 = call double @perry_closure_spike_ts__4(i64 %r422, double %r420)
+  br label %closure_direct.merge.92
+
+closure_direct.fallback.91:
+  call void @js_typed_feedback_record_fallback_call(i64 7695367220062322696)
+  %r426 = call double @js_implicit_this_set(double 0x7FFC000000000001)
+  %r427 = bitcast double %r426 to i64
+  %r428 = call i32 @js_gc_temp_root_push(i64 %r427)
+  %r429 = call double @js_closure_call1(i64 %r422, double %r420)
+  %r430 = call i64 @js_gc_temp_root_get(i32 %r428)
+  %r431 = bitcast i64 %r430 to double
+  call void @js_gc_temp_root_truncate(i32 %r428)
+  %r432 = call double @js_implicit_this_set(double %r431)
+  br label %closure_direct.merge.92
+
+closure_direct.merge.92:
+  %r433 = phi double [ %r425, %closure_direct.fast.90 ], [ %r429, %closure_direct.fallback.91 ]
+  %r434 = bitcast double %r433 to i64
+  %r435 = call i32 @js_gc_temp_root_push(i64 %r434)
+  %r436 = call i64 @js_array_alloc(i32 1)
+  %r437 = call i32 @js_gc_temp_root_push(i64 %r436)
+  %r438 = call i64 @js_gc_temp_root_get(i32 %r435)
+  %r439 = bitcast i64 %r438 to double
+  call void @js_array_push_f64_temp_rooted(i32 %r437, double %r439)
+  %r440 = call i64 @js_gc_temp_root_get(i32 %r437)
+  call void @js_console_log_spread(i64 %r440)
+  call void @js_gc_temp_root_truncate(i32 %r435)
+  %r441 = load ptr, ptr %r2
+  %r442 = icmp eq ptr %r441, null
+  br i1 %r442, label %ss.slow.93, label %ss.chk_top.94
+
+ss.slow.93:
+  call void @js_shadow_slot_set(i32 5, i64 0)
+  br label %ss.done.97
+
+ss.chk_top.94:
+  %r443 = getelementptr inbounds i8, ptr %r441, i64 24
+  %r444 = load i64, ptr %r443
+  %r445 = icmp eq i64 %r444, -1
+  br i1 %r445, label %ss.done.97, label %ss.chk_len.95
+
+ss.chk_len.95:
+  %r446 = add i64 %r444, 5
+  %r447 = getelementptr inbounds i8, ptr %r441, i64 8
+  %r448 = load i64, ptr %r447
+  %r449 = icmp ult i64 %r446, %r448
+  br i1 %r449, label %ss.store.96, label %ss.done.97
+
+ss.store.96:
+  %r450 = load ptr, ptr %r441
+  %r451 = shl i64 %r446, 4
+  %r452 = getelementptr inbounds i8, ptr %r450, i64 %r451
+  %r453 = getelementptr inbounds i8, ptr %r452, i64 8
+  %r454 = load i64, ptr %r453
+  %r455 = and i64 %r454, -2
+  store i64 0, ptr %r452
+  store i64 %r455, ptr %r453
+  br label %ss.done.97
+
+ss.done.97:
+  %r456 = bitcast double 0x7FFC000000000001 to i64
+  %r457 = bitcast double 0x7FFC000000000001 to i64
+  %r458 = bitcast double 0x7FFC000000000001 to i64
+  %r459 = bitcast double 0x7FFC000000000001 to i64
+  %r460 = bitcast double 0x7FFC000000000001 to i64
+  %r462 = getelementptr i64, ptr %r461, i64 0
+  store i64 %r456, ptr %r462
+  %r463 = getelementptr i64, ptr %r461, i64 1
+  store i64 %r457, ptr %r463
+  %r464 = getelementptr i64, ptr %r461, i64 2
+  store i64 %r458, ptr %r464
+  %r465 = getelementptr i64, ptr %r461, i64 3
+  store i64 %r459, ptr %r465
+  %r466 = getelementptr i64, ptr %r461, i64 4
+  store i64 %r460, ptr %r466
+  %r467 = call i64 @js_closure_alloc_with_captures_singleton(ptr @perry_closure_spike_ts__5, i32 5, ptr %r461)
+  %r468 = or i64 %r467, 9222527611924643840
+  %r469 = bitcast i64 %r468 to double
+  %r470 = call double @js_implicit_this_set(double 0x7FFC000000000001)
+  %r471 = bitcast double %r470 to i64
+  %r472 = call i32 @js_gc_temp_root_push(i64 %r471)
+  %r473 = call i64 @js_closure_unbox_callee_checked(double %r469)
+  %r474 = call double @js_closure_call0(i64 %r473)
+  %r475 = call i64 @js_gc_temp_root_get(i32 %r472)
+  %r476 = bitcast i64 %r475 to double
+  call void @js_gc_temp_root_truncate(i32 %r472)
+  %r477 = call double @js_implicit_this_set(double %r476)
+  %r478 = call i32 @js_promise_run_microtasks_event_loop()
+  %r479 = call i32 @js_timer_tick_if_refed()
+  %r480 = call i32 @js_callback_timer_tick()
+  %r481 = call i32 @js_interval_timer_tick()
+  %r482 = call i32 @js_promise_run_microtasks_event_loop()
+  %r483 = call i32 @js_timer_tick_if_refed()
+  %r484 = call i32 @js_callback_timer_tick()
+  %r485 = call i32 @js_interval_timer_tick()
+  %r486 = call i32 @js_promise_run_microtasks_event_loop()
+  %r487 = call i32 @js_timer_tick_if_refed()
+  %r488 = call i32 @js_callback_timer_tick()
+  %r489 = call i32 @js_interval_timer_tick()
+  %r490 = call i32 @js_promise_run_microtasks_event_loop()
+  %r491 = call i32 @js_timer_tick_if_refed()
+  %r492 = call i32 @js_callback_timer_tick()
+  %r493 = call i32 @js_interval_timer_tick()
+  call void @js_run_stdlib_pump()
+  br label %event_loop.header.98
+
+event_loop.header.98:
+  %r494 = call i32 @js_event_loop_host_driven()
+  %r495 = icmp ne i32 %r494, 0
+  br i1 %r495, label %event_loop.host_return.100, label %event_loop.check_pending.99
+
+event_loop.check_pending.99:
+  %r496 = call i32 @js_timer_has_pending()
+  %r497 = call i32 @js_callback_timer_has_pending()
+  %r498 = call i32 @js_interval_timer_has_pending()
+  %r499 = call i32 @js_stdlib_has_active_handles()
+  %r500 = call i32 @js_microtasks_pending()
+  %r501 = or i32 %r496, %r497
+  %r502 = or i32 %r498, %r499
+  %r503 = or i32 %r501, %r502
+  %r504 = or i32 %r503, 0
+  %r505 = or i32 %r504, %r500
+  %r506 = icmp ne i32 %r505, 0
+  br i1 %r506, label %event_loop.body.101, label %event_loop.exit.102
+
+event_loop.host_return.100:
+  call void @js_typed_feedback_maybe_dump_trace()
+  %shadow_pop_l_0 = load i64, ptr %r1
+  call void @js_shadow_frame_pop(i64 %shadow_pop_l_0)
+  ret i32 0
+
+event_loop.body.101:
+  %r507 = call i32 @js_promise_run_microtasks_event_loop()
+  %r508 = call i32 @js_timer_tick()
+  %r509 = call i32 @js_callback_timer_tick()
+  %r510 = call i32 @js_interval_timer_tick()
+  call void @js_run_stdlib_pump()
+  call void @js_wait_for_event()
+  br label %event_loop.header.98
+
+event_loop.exit.102:
+  call void @js_process_emit_before_exit(double 0x0)
+  %r511 = call i32 @js_promise_run_microtasks_event_loop()
+  %r512 = call i32 @js_timer_tick_if_refed()
+  %r513 = call i32 @js_callback_timer_tick()
+  %r514 = call i32 @js_interval_timer_tick()
+  call void @js_process_run_finalization_exit()
+  call void @js_trace_events_flush_output()
+  call void @js_promise_report_unhandled_rejections()
+  call void @js_gc_release_current_thread_collection_side_allocations()
+  %r515 = call i32 @js_process_pending_exit_code()
+  call void @js_typed_feedback_maybe_dump_trace()
+  %shadow_pop_l_1 = load i64, ptr %r1
+  call void @js_shadow_frame_pop(i64 %shadow_pop_l_1)
+  ret i32 %r515
+}
+
+define void @__perry_init_strings_spike_ts_chunk0() {
+entry.0:
+  %r1 = call i64 @js_string_from_bytes(ptr @spike_ts_.str.0.bytes, i32 7)
+  %r2 = call double @js_nanbox_string(i64 %r1)
+  store double %r2, ptr @spike_ts_.str.0.handle
+  %r3 = ptrtoint ptr @spike_ts_.str.0.handle to i64
+  call void @js_gc_register_global_root(i64 %r3)
+  %r4 = call i64 @js_string_from_bytes(ptr @spike_ts_.str.1.bytes, i32 1)
+  %r5 = call double @js_nanbox_string(i64 %r4)
+  store double %r5, ptr @spike_ts_.str.1.handle
+  %r6 = ptrtoint ptr @spike_ts_.str.1.handle to i64
+  call void @js_gc_register_global_root(i64 %r6)
+  %r7 = call i64 @js_string_from_bytes(ptr @spike_ts_.str.2.bytes, i32 6)
+  %r8 = call double @js_nanbox_string(i64 %r7)
+  store double %r8, ptr @spike_ts_.str.2.handle
+  %r9 = ptrtoint ptr @spike_ts_.str.2.handle to i64
+  call void @js_gc_register_global_root(i64 %r9)
+  %r10 = call i64 @js_string_from_bytes(ptr @spike_ts_.str.3.bytes, i32 1)
+  %r11 = call double @js_nanbox_string(i64 %r10)
+  store double %r11, ptr @spike_ts_.str.3.handle
+  %r12 = ptrtoint ptr @spike_ts_.str.3.handle to i64
+  call void @js_gc_register_global_root(i64 %r12)
+  %r13 = call i64 @js_string_from_bytes(ptr @spike_ts_.str.4.bytes, i32 1)
+  %r14 = call double @js_nanbox_string(i64 %r13)
+  store double %r14, ptr @spike_ts_.str.4.handle
+  %r15 = ptrtoint ptr @spike_ts_.str.4.handle to i64
+  call void @js_gc_register_global_root(i64 %r15)
+  %r16 = call i64 @js_string_from_bytes(ptr @spike_ts_.str.5.bytes, i32 9)
+  %r17 = call double @js_nanbox_string(i64 %r16)
+  store double %r17, ptr @spike_ts_.str.5.handle
+  %r18 = ptrtoint ptr @spike_ts_.str.5.handle to i64
+  call void @js_gc_register_global_root(i64 %r18)
+  %r19 = call i64 @js_string_from_bytes(ptr @spike_ts_.str.6.bytes, i32 7)
+  %r20 = call double @js_nanbox_string(i64 %r19)
+  store double %r20, ptr @spike_ts_.str.6.handle
+  %r21 = ptrtoint ptr @spike_ts_.str.6.handle to i64
+  call void @js_gc_register_global_root(i64 %r21)
+  %r22 = call i64 @js_string_from_bytes(ptr @spike_ts_.str.7.bytes, i32 1)
+  %r23 = call double @js_nanbox_string(i64 %r22)
+  store double %r23, ptr @spike_ts_.str.7.handle
+  %r24 = ptrtoint ptr @spike_ts_.str.7.handle to i64
+  call void @js_gc_register_global_root(i64 %r24)
+  %r25 = call i64 @js_string_from_bytes(ptr @spike_ts_.str.8.bytes, i32 5)
+  %r26 = call double @js_nanbox_string(i64 %r25)
+  store double %r26, ptr @spike_ts_.str.8.handle
+  %r27 = ptrtoint ptr @spike_ts_.str.8.handle to i64
+  call void @js_gc_register_global_root(i64 %r27)
+  %r28 = call i64 @js_string_from_bytes(ptr @spike_ts_.str.9.bytes, i32 4)
+  %r29 = call double @js_nanbox_string(i64 %r28)
+  store double %r29, ptr @spike_ts_.str.9.handle
+  %r30 = ptrtoint ptr @spike_ts_.str.9.handle to i64
+  call void @js_gc_register_global_root(i64 %r30)
+  %r31 = call i64 @js_string_from_bytes(ptr @spike_ts_.str.10.bytes, i32 2)
+  %r32 = call double @js_nanbox_string(i64 %r31)
+  store double %r32, ptr @spike_ts_.str.10.handle
+  %r33 = ptrtoint ptr @spike_ts_.str.10.handle to i64
+  call void @js_gc_register_global_root(i64 %r33)
+  %r34 = call i64 @js_string_from_bytes(ptr @spike_ts_.str.11.bytes, i32 5)
+  %r35 = call double @js_nanbox_string(i64 %r34)
+  store double %r35, ptr @spike_ts_.str.11.handle
+  %r36 = ptrtoint ptr @spike_ts_.str.11.handle to i64
+  call void @js_gc_register_global_root(i64 %r36)
+  %r37 = call i64 @js_string_from_bytes(ptr @spike_ts_.str.12.bytes, i32 4)
+  %r38 = call double @js_nanbox_string(i64 %r37)
+  store double %r38, ptr @spike_ts_.str.12.handle
+  %r39 = ptrtoint ptr @spike_ts_.str.12.handle to i64
+  call void @js_gc_register_global_root(i64 %r39)
+  %r40 = call i64 @js_string_from_bytes(ptr @spike_ts_.str.13.bytes, i32 5)
+  %r41 = call double @js_nanbox_string(i64 %r40)
+  store double %r41, ptr @spike_ts_.str.13.handle
+  %r42 = ptrtoint ptr @spike_ts_.str.13.handle to i64
+  call void @js_gc_register_global_root(i64 %r42)
+  call void @js_register_function_name(ptr @__perry_wrap_perry_fn_spike_ts__fib, ptr @.str.0, i32 3)
+  call void @js_register_function_name(ptr @perry_closure_spike_ts__4, ptr @.str.1, i32 5)
+  call void @js_register_function_source(ptr @__perry_wrap_perry_fn_spike_ts__fib, ptr @.str.2, i32 81)
+  call void @js_register_function_source(ptr @perry_closure_spike_ts__1, ptr @.str.3, i32 15)
+  call void @js_register_function_source(ptr @perry_closure_spike_ts__4, ptr @.str.4, i32 35)
+  call void @js_register_function_source(ptr @perry_closure_spike_ts__5, ptr @.str.5, i32 82)
+  %r43 = call i64 @js_build_class_keys_array(i32 1, i32 2, ptr @perry_class_keys_packed_spike_ts__0, i32 4)
+  store i64 %r43, ptr @perry_class_keys_spike_ts__Point
+  call void @js_write_barrier_root_heap_word(i64 %r43)
+  %r44 = ptrtoint ptr @perry_class_keys_spike_ts__Point to i64
+  call void @js_gc_register_global_root(i64 %r44)
+  %r45 = ptrtoint ptr @perry_method_spike_ts__Point__norm to i64
+  %r46 = ptrtoint ptr @spike_ts_.str.12.bytes to i64
+  call void @js_register_class_method(i64 1, i64 %r46, i64 4, i64 %r45, i64 0, i64 0, i64 0)
+  call void @js_register_class_method_bind_length(i64 1, i64 %r46, i64 4, i64 0)
+  %r47 = ptrtoint ptr @spike_ts__Point_constructor to i64
+  call void @js_register_class_constructor(i64 1, i64 %r47, i64 2, i64 0)
+  call void @js_register_class_id(i32 1)
+  call void @js_register_class_name(i32 1, ptr @.str.6, i32 5)
+  call void @js_register_closure_arity(ptr @perry_closure_spike_ts__1, i32 2)
+  call void @js_register_closure_arity(ptr @perry_closure_spike_ts__4, i32 1)
+  call void @js_register_closure_arity(ptr @perry_closure_spike_ts__5, i32 0)
+  call void @js_register_closure_arity(ptr @perry_closure_spike_ts__8, i32 2)
+  call void @js_register_closure_length(ptr @perry_closure_spike_ts__1, i32 2)
+  call void @js_register_closure_length(ptr @perry_closure_spike_ts__4, i32 1)
+  call void @js_register_closure_length(ptr @perry_closure_spike_ts__5, i32 0)
+  call void @js_register_closure_length(ptr @perry_closure_spike_ts__8, i32 2)
+  call void @js_register_closure_arrow_function(ptr @perry_closure_spike_ts__1)
+  call void @js_register_closure_arrow_function(ptr @perry_closure_spike_ts__4)
+  call void @js_register_closure_arrow_function(ptr @perry_closure_spike_ts__5)
+  call void @js_register_closure_arity(ptr @__perry_wrap_perry_fn_spike_ts__fib, i32 1)
+  call void @js_register_closure_length(ptr @__perry_wrap_perry_fn_spike_ts__fib, i32 1)
+  call void @js_register_closure_strict_function(ptr @__perry_wrap_perry_fn_spike_ts__fib)
+  call void @js_register_closure_strict_function(ptr @perry_closure_spike_ts__1)
+  call void @js_register_closure_strict_function(ptr @perry_closure_spike_ts__4)
+  call void @js_register_closure_strict_function(ptr @perry_closure_spike_ts__5)
+  call void @js_register_closure_strict_function(ptr @perry_closure_spike_ts__8)
+  ret void
+}
+
+define void @__perry_init_strings_spike_ts() {
+entry.0:
+  call void @__perry_init_strings_spike_ts_chunk0()
+  ret void
+}
+
+
+attributes #0 = { returns_twice }
+attributes #1 = { noinline }
+
+attributes #2 = { nounwind willreturn readnone }
+
+attributes #3 = { nounwind willreturn readonly }
+
+attributes #4 = { nounwind willreturn }
+
+!0 = !{}
diff --git a/experiments/llvm-inprocess-spike/src/main.rs b/experiments/llvm-inprocess-spike/src/main.rs
new file mode 100644
index 0000000000..f848524699
--- /dev/null
+++ b/experiments/llvm-inprocess-spike/src/main.rs
@@ -0,0 +1,470 @@
+//! Phase 0 feasibility spike for the in-process LLVM backend (exp/llvm-inprocess).
+//!
+//! Three modes:
+//!
+//! * `--version`            — prints a clang-compatible banner, so Perry's
+//!                            `find_clang`/`ensure_supported_clang` accept this
+//!                            binary via `PERRY_LLVM_CLANG`.
+//! * `demo `        — builds a module through the inkwell builder API
+//!                            exercising every construct the experiment brief
+//!                            flags as a potential blocker (NaN-box constants,
+//!                            f64<->i64 bitcasts, inline asm with exact
+//!                            constraint strings, module-level asm, appending
+//!                            `@llvm.used`, `gc "statepoint-example"`), then
+//!                            verifies, emits a .o, links it with `cc`, runs
+//!                            it, and checks the output.
+//! * ``   — the shim: accepts exactly the argv Perry's
+//!                            `build_clang_compile_plan` produces
+//!                            (`-c -O3 -fno-math-errno [...] x.ll -o x.o
+//!                            -target `), but compiles **in-process**:
+//!                            parse IR -> verify -> `default` pass
+//!                            pipeline -> TargetMachine object emission.
+//!                            Setting `PERRY_LLVM_CLANG` to this binary swaps
+//!                            the whole Perry compile onto the in-process
+//!                            backend with zero Perry changes — the Phase 0
+//!                            A/B harness.
+//!
+//! Liveness proof (the "gate must assert its subject was live" rule): every
+//! shim compile appends a line to `$PERRY_LLVMC_SPIKE_LOG` when set. An A/B
+//! arm that claims to be in-process must show a non-empty log.
+
+use std::ffi::CString;
+use std::path::{Path, PathBuf};
+use std::process::{Command, ExitCode};
+use std::time::Instant;
+
+use inkwell::context::Context;
+use inkwell::memory_buffer::MemoryBuffer;
+use inkwell::module::{Linkage, Module};
+use inkwell::passes::PassBuilderOptions;
+use inkwell::targets::{
+    CodeModel, FileType, InitializationConfig, RelocMode, Target, TargetMachine, TargetTriple,
+};
+use inkwell::values::{AsValueRef, CallSiteValue, IntValue};
+use inkwell::{AddressSpace, IntPredicate, OptimizationLevel};
+
+/// inkwell 0.9 returns a `ValueKind` from `try_as_basic_value`; all demo
+/// callees return i64, so collapse to the IntValue or panic loudly.
+fn call_ret_i64(cs: CallSiteValue<'_>) -> IntValue<'_> {
+    match cs.try_as_basic_value() {
+        inkwell::values::ValueKind::Basic(v) => v.into_int_value(),
+        other => panic!("call did not produce a basic value: {other:?}"),
+    }
+}
+
+// NaN-box tags, mirrored from perry-runtime/src/value.rs.
+const TAG_UNDEFINED: u64 = 0x7FFC_0000_0000_0001;
+const INT32_TAG_SHIFTED: u64 = 0x7FFE_0000_0000_002A; // INT32_TAG with payload 42
+
+fn main() -> ExitCode {
+    let args: Vec = std::env::args().skip(1).collect();
+    if args.iter().any(|a| a == "--version" || a == "-v") {
+        print_version_banner();
+        return ExitCode::SUCCESS;
+    }
+    match args.first().map(String::as_str) {
+        Some("demo") => {
+            let outdir = args
+                .get(1)
+                .map(PathBuf::from)
+                .unwrap_or_else(|| PathBuf::from("."));
+            match run_demo(&outdir) {
+                Ok(()) => ExitCode::SUCCESS,
+                Err(e) => {
+                    eprintln!("demo failed: {e}");
+                    ExitCode::FAILURE
+                }
+            }
+        }
+        Some(_) => match run_shim(&args) {
+            Ok(()) => ExitCode::SUCCESS,
+            Err(e) => {
+                eprintln!("perry-llvmc-spike: {e}");
+                ExitCode::FAILURE
+            }
+        },
+        None => {
+            eprintln!("usage: perry-llvmc-spike [--version | demo  | ]");
+            ExitCode::FAILURE
+        }
+    }
+}
+
+fn print_version_banner() {
+    // `parse_clang_major_version` looks for "clang version "; report
+    // the LLVM major we actually embed so `ensure_supported_clang` sees a
+    // supported opaque-pointer toolchain.
+    let triple = TargetMachine::get_default_triple();
+    println!(
+        "clang version 22.1.4 (perry-llvmc-spike in-process LLVM backend)\n\
+         Target: {}\n\
+         Thread model: posix\n\
+         InstalledDir: (in-process)",
+        triple.as_str().to_string_lossy()
+    );
+}
+
+// ---------------------------------------------------------------------------
+// Shim mode: clang-compatible argv, in-process compile
+// ---------------------------------------------------------------------------
+
+struct ShimArgs {
+    input: PathBuf,
+    output: PathBuf,
+    opt: char, // '0', 's', '3', ...
+    target: Option,
+    mcpu_native: bool,
+    explicit_cpu: Option,
+    mllvm: Vec,
+}
+
+fn parse_shim_args(args: &[String]) -> Result {
+    let mut input = None;
+    let mut output = None;
+    let mut opt = '0';
+    let mut target = None;
+    let mut mcpu_native = false;
+    let mut explicit_cpu = None;
+    let mut mllvm = Vec::new();
+    let mut it = args.iter().peekable();
+    while let Some(a) = it.next() {
+        match a.as_str() {
+            "-c" | "-fno-math-errno" | "-g" => {} // -g: parity with clang — no DI metadata in Perry IR, so it adds nothing (#7144)
+            "-o" => output = it.next().cloned().map(PathBuf::from),
+            "-target" => target = it.next().cloned(),
+            "-mllvm" => {
+                if let Some(f) = it.next() {
+                    mllvm.push(f.clone());
+                }
+            }
+            s if s.starts_with("-O") => opt = s.chars().nth(2).unwrap_or('0'),
+            "-mcpu=native" | "-march=native" => mcpu_native = true,
+            s if s.starts_with("-mcpu=") => explicit_cpu = Some(s["-mcpu=".len()..].to_string()),
+            s if s.starts_with("-march=") => explicit_cpu = Some(s["-march=".len()..].to_string()),
+            s if !s.starts_with('-') => input = Some(PathBuf::from(s)),
+            other => return Err(format!("unrecognized clang arg: {other}")),
+        }
+    }
+    Ok(ShimArgs {
+        input: input.ok_or("missing input .ll")?,
+        output: output.ok_or("missing -o output")?,
+        opt,
+        target,
+        mcpu_native,
+        explicit_cpu,
+        mllvm,
+    })
+}
+
+fn run_shim(args: &[String]) -> Result<(), String> {
+    let t0 = Instant::now();
+    let sa = parse_shim_args(args)?;
+
+    // -mllvm flags (e.g. -inlinehint-threshold=N) go through the cl::opt
+    // parser, same effect as clang's -mllvm passthrough. Process-global, which
+    // is fine here (one compile per process) but is a real constraint for the
+    // integrated backend — noted in the write-up.
+    if !sa.mllvm.is_empty() {
+        let mut argv: Vec = vec![CString::new("perry-llvmc-spike").unwrap()];
+        for f in &sa.mllvm {
+            argv.push(CString::new(f.as_str()).map_err(|e| e.to_string())?);
+        }
+        let ptrs: Vec<*const std::os::raw::c_char> = argv.iter().map(|c| c.as_ptr()).collect();
+        unsafe {
+            llvm_sys::support::LLVMParseCommandLineOptions(
+                ptrs.len() as i32,
+                ptrs.as_ptr(),
+                std::ptr::null(),
+            );
+        }
+    }
+
+    Target::initialize_all(&InitializationConfig::default());
+    let context = Context::create();
+    let buf = MemoryBuffer::create_from_file(&sa.input)
+        .map_err(|e| format!("read {}: {}", sa.input.display(), e))?;
+    let ir_bytes = buf.get_size();
+    let module = context
+        .create_module_from_ir(buf)
+        .map_err(|e| format!("LLVM IR parse error in {}:\n{}", sa.input.display(), e))?;
+
+    module
+        .verify()
+        .map_err(|e| format!("verifier rejected {}:\n{}", sa.input.display(), e))?;
+
+    let triple_str = sa
+        .target
+        .clone()
+        .unwrap_or_else(|| TargetMachine::get_default_triple().as_str().to_string_lossy().into_owned());
+    let triple = TargetTriple::create(&triple_str);
+    let target =
+        Target::from_triple(&triple).map_err(|e| format!("no target for {triple_str}: {e}"))?;
+
+    let (cpu, features) = if sa.mcpu_native {
+        (
+            TargetMachine::get_host_cpu_name().to_string_lossy().into_owned(),
+            TargetMachine::get_host_cpu_features().to_string_lossy().into_owned(),
+        )
+    } else if let Some(cpu) = &sa.explicit_cpu {
+        (cpu.clone(), String::new())
+    } else {
+        (String::new(), String::new())
+    };
+
+    let opt_level = match sa.opt {
+        '0' => OptimizationLevel::None,
+        '1' => OptimizationLevel::Less,
+        '2' | 's' | 'z' => OptimizationLevel::Default,
+        _ => OptimizationLevel::Aggressive,
+    };
+    let tm = target
+        .create_target_machine(&triple, &cpu, &features, opt_level, RelocMode::PIC, CodeModel::Default)
+        .ok_or("failed to create TargetMachine")?;
+
+    // Match clang's behavior of trusting -target over the module's own triple,
+    // and give the module the machine's real datalayout before optimizing.
+    module.set_triple(&triple);
+    module.set_data_layout(&tm.get_target_data().get_data_layout());
+
+    let pipeline = match sa.opt {
+        '0' => "default",
+        '1' => "default",
+        '2' => "default",
+        's' => "default",
+        'z' => "default",
+        _ => "default",
+    };
+    module
+        .run_passes(pipeline, &tm, PassBuilderOptions::create())
+        .map_err(|e| format!("pass pipeline {pipeline} failed: {e}"))?;
+
+    tm.write_to_file(&module, FileType::Object, &sa.output)
+        .map_err(|e| format!("object emission to {} failed: {}", sa.output.display(), e))?;
+
+    if let Ok(log) = std::env::var("PERRY_LLVMC_SPIKE_LOG") {
+        use std::io::Write;
+        if let Ok(mut f) = std::fs::OpenOptions::new().create(true).append(true).open(&log) {
+            let _ = writeln!(
+                f,
+                "inprocess-compile input={} ir_bytes={} opt=-O{} cpu={} target={} ms={}",
+                sa.input.display(),
+                ir_bytes,
+                sa.opt,
+                if cpu.is_empty() { "(default)" } else { &cpu },
+                triple_str,
+                t0.elapsed().as_millis()
+            );
+        }
+    }
+    Ok(())
+}
+
+// ---------------------------------------------------------------------------
+// Demo mode: builder-API construction of the brief's "can it express X" list
+// ---------------------------------------------------------------------------
+
+fn run_demo(outdir: &Path) -> Result<(), String> {
+    std::fs::create_dir_all(outdir).map_err(|e| e.to_string())?;
+    Target::initialize_all(&InitializationConfig::default());
+
+    let context = Context::create();
+    let module = context.create_module("spike_demo");
+    let builder = context.create_builder();
+    let i64t = context.i64_type();
+    let f64t = context.f64_type();
+    let i32t = context.i32_type();
+    let ptrt = context.ptr_type(AddressSpace::default());
+
+    // (1) NaN-box constant fidelity: TAG_UNDEFINED as a double constant built
+    // from raw bits. If f64::from_bits -> const_float loses NaN payload bits,
+    // the whole constant-emission strategy must change; the compiled program
+    // prints the bits so we can check end to end.
+    let undef_const = f64t.const_float(f64::from_bits(TAG_UNDEFINED));
+    let int42_const = f64t.const_float(f64::from_bits(INT32_TAG_SHIFTED));
+
+    // (2) f64 -> i64 bitcast in a function: `nanbox_bits(double) -> i64`.
+    let bits_fn_ty = i64t.fn_type(&[f64t.into()], false);
+    let bits_fn = module.add_function("nanbox_bits", bits_fn_ty, None);
+    {
+        let entry = context.append_basic_block(bits_fn, "entry");
+        builder.position_at_end(entry);
+        let v = bits_fn.get_nth_param(0).unwrap().into_float_value();
+        let as_bits = builder
+            .build_bit_cast(v, i64t, "bits")
+            .map_err(|e| e.to_string())?
+            .into_int_value();
+        builder.build_return(Some(&as_bits)).map_err(|e| e.to_string())?;
+    }
+
+    // (6) gc attribute — inkwell has no wrapper; llvm-sys expresses it.
+    let gc_fn = module.add_function("gc_marked", i64t.fn_type(&[i64t.into()], false), None);
+    unsafe {
+        let name = CString::new("statepoint-example").unwrap();
+        llvm_sys::core::LLVMSetGC(gc_fn.as_value_ref(), name.as_ptr());
+    }
+    {
+        let entry = context.append_basic_block(gc_fn, "entry");
+        builder.position_at_end(entry);
+        let p = gc_fn.get_nth_param(0).unwrap().into_int_value();
+        let one = i64t.const_int(1, false);
+        let r = builder.build_int_add(p, one, "r").map_err(|e| e.to_string())?;
+        builder.build_return(Some(&r)).map_err(|e| e.to_string())?;
+    }
+
+    // (7) extern varargs declaration, same shape as Perry's runtime calls.
+    let printf_ty = i32t.fn_type(&[ptrt.into()], true);
+    let printf = module.add_function("printf", printf_ty, Some(Linkage::External));
+
+    // main
+    let main_fn = module.add_function("main", i32t.fn_type(&[], false), None);
+    let entry = context.append_basic_block(main_fn, "entry");
+    builder.position_at_end(entry);
+
+    // (3) the exact inline-asm barrier Perry emits: `call void asm sideeffect "", ""()`.
+    let void_fn_ty = context.void_type().fn_type(&[], false);
+    let asm = context.create_inline_asm(
+        void_fn_ty,
+        String::new(),
+        String::new(),
+        true,  // sideeffect
+        false, // alignstack
+        None,  // dialect
+        false, // can_throw
+    );
+    builder
+        .build_indirect_call(void_fn_ty, asm, &[], "barrier")
+        .map_err(|e| e.to_string())?;
+
+    // Format string global.
+    let fmt = builder
+        .build_global_string_ptr("tag_undefined=%llx int42=%llx gc=%lld cmp=%d\n", "fmt")
+        .map_err(|e| e.to_string())?;
+
+    // Push the NaN-box constants through the bitcast fn and print their bits.
+    let undef_bits = call_ret_i64(
+        builder
+            .build_call(bits_fn, &[undef_const.into()], "u")
+            .map_err(|e| e.to_string())?,
+    );
+    let int42_bits = call_ret_i64(
+        builder
+            .build_call(bits_fn, &[int42_const.into()], "i")
+            .map_err(|e| e.to_string())?,
+    );
+    let gc_out = call_ret_i64(
+        builder
+            .build_call(gc_fn, &[i64t.const_int(41, false).into()], "g")
+            .map_err(|e| e.to_string())?,
+    );
+    // Tag-check pattern from generated code: (bits >> 32) == 0x7FFE ?
+    let hi = builder
+        .build_right_shift(int42_bits, i64t.const_int(32, false), false, "hi")
+        .map_err(|e| e.to_string())?;
+    let is_i32 = builder
+        .build_int_compare(IntPredicate::EQ, hi, i64t.const_int(0x7FFE_0000, false), "isi32")
+        .map_err(|e| e.to_string())?;
+    let is_i32_ext = builder
+        .build_int_z_extend(is_i32, i32t, "isi32e")
+        .map_err(|e| e.to_string())?;
+
+    builder
+        .build_call(
+            printf,
+            &[
+                fmt.as_pointer_value().into(),
+                undef_bits.into(),
+                int42_bits.into(),
+                gc_out.into(),
+                is_i32_ext.into(),
+            ],
+            "p",
+        )
+        .map_err(|e| e.to_string())?;
+    builder
+        .build_return(Some(&i32t.const_zero()))
+        .map_err(|e| e.to_string())?;
+
+    // (5) appending @llvm.used keeping gc_marked alive (the Mach-O
+    // no-dead-strip mechanism Perry's runtime relies on for anchors).
+    let used_ty = ptrt.array_type(1);
+    let used = module.add_global(used_ty, None, "llvm.used");
+    used.set_linkage(Linkage::Appending);
+    used.set_section(Some("llvm.metadata"));
+    used.set_initializer(&ptrt.const_array(&[gc_fn.as_global_value().as_pointer_value()]));
+
+    // (4) module-level asm defining a real symbol.
+    module.set_inline_assembly(
+        ".globl _perry_spike_asm_marker\n_perry_spike_asm_marker:\n.quad 0xC0FFEE\n",
+    );
+
+    module.verify().map_err(|e| format!("verifier: {e}"))?;
+
+    // Debug view — printed from the real module, exactly the thesis.
+    let ll_path = outdir.join("spike_demo.ll");
+    std::fs::write(&ll_path, module.print_to_string().to_string()).map_err(|e| e.to_string())?;
+
+    // Optimize + emit through the same path the shim uses.
+    let triple = TargetMachine::get_default_triple();
+    let target = Target::from_triple(&triple).map_err(|e| e.to_string())?;
+    let tm = target
+        .create_target_machine(
+            &triple,
+            &TargetMachine::get_host_cpu_name().to_string_lossy(),
+            &TargetMachine::get_host_cpu_features().to_string_lossy(),
+            OptimizationLevel::Aggressive,
+            RelocMode::PIC,
+            CodeModel::Default,
+        )
+        .ok_or("failed to create TargetMachine")?;
+    module.set_data_layout(&tm.get_target_data().get_data_layout());
+    module
+        .run_passes("default", &tm, PassBuilderOptions::create())
+        .map_err(|e| format!("passes: {e}"))?;
+
+    let obj_path = outdir.join("spike_demo.o");
+    tm.write_to_file(&module, FileType::Object, &obj_path)
+        .map_err(|e| e.to_string())?;
+
+    // Link + run + check.
+    let bin_path = outdir.join("spike_demo");
+    let link = Command::new("cc")
+        .arg(&obj_path)
+        .arg("-o")
+        .arg(&bin_path)
+        .output()
+        .map_err(|e| e.to_string())?;
+    if !link.status.success() {
+        return Err(format!(
+            "link failed:\n{}",
+            String::from_utf8_lossy(&link.stderr)
+        ));
+    }
+    let run = Command::new(&bin_path).output().map_err(|e| e.to_string())?;
+    let stdout = String::from_utf8_lossy(&run.stdout);
+    println!("--- compiled program output ---\n{stdout}-------------------------------");
+
+    let expect_undef = format!("{:x}", TAG_UNDEFINED);
+    let expect_i42 = format!("{:x}", INT32_TAG_SHIFTED);
+    if !stdout.contains(&expect_undef) || !stdout.contains(&expect_i42) {
+        return Err(format!(
+            "NaN-box constant bits were NOT preserved: expected {expect_undef} and {expect_i42} in output"
+        ));
+    }
+    if !stdout.contains("gc=42") || !stdout.contains("cmp=1") {
+        return Err("gc-marked function or tag-check produced wrong values".into());
+    }
+
+    // The module-asm symbol must exist in the object.
+    let nm = Command::new("nm").arg(&obj_path).output().map_err(|e| e.to_string())?;
+    let nm_out = String::from_utf8_lossy(&nm.stdout);
+    if !nm_out.contains("_perry_spike_asm_marker") {
+        return Err("module-level asm symbol missing from object".into());
+    }
+
+    println!(
+        "demo OK: NaN-box constants preserved, inline asm + module asm + llvm.used + gc attr \
+         all expressed; artifacts in {}",
+        outdir.display()
+    );
+    Ok(())
+}