use wasm_encoder::{Function, Instruction, ValType};
use super::restore_bump;
pub(in crate::codegen::wasm_gc) struct TcpConnectIndices {
pub fn_type: u32,
pub fn_idx: u32,
pub string_type_idx: u32,
pub stub_err_segment_idx: u32,
pub stub_err_len: u32,
pub dns_err_segment_idx: u32,
pub dns_err_len: u32,
pub no_addr_segment_idx: u32,
pub no_addr_len: u32,
pub sock_err_segment_idx: u32,
pub sock_err_len: u32,
pub conn_err_segment_idx: u32,
pub conn_err_len: u32,
pub port_err_segment_idx: u32,
pub port_err_len: u32,
pub limit_err_segment_idx: u32,
pub limit_err_len: u32,
}
pub(in crate::codegen::wasm_gc) struct TcpConnectPool {
pub tcp_next_id_global: u32,
pub tcp_pool_global: u32,
pub tcp_slot_type_idx: u32,
pub tcp_pool_type_idx: u32,
pub bump_alloc_ptr_global: u32,
}
pub(in crate::codegen::wasm_gc) struct TcpConnectDns {
pub instance_network_fn: u32,
pub network_handle_global: u32,
pub resolve_addresses_fn: u32,
pub resolve_next_address_fn: u32,
pub drop_resolve_stream_fn: u32,
pub stream_subscribe_fn: u32,
pub poll_fn: u32,
pub drop_pollable_fn: u32,
}
pub(in crate::codegen::wasm_gc) struct TcpConnectSocket {
pub create_tcp_socket_fn: u32,
pub start_connect_fn: u32,
pub finish_connect_fn: u32,
pub socket_subscribe_fn: u32,
pub drop_tcp_socket_fn: u32,
}
pub(in crate::codegen::wasm_gc) struct TcpConnectMaterialize {
pub cabi_realloc_fn: u32,
pub str_to_lm_fn: u32,
pub format_id_fn: u32,
pub record_make_fn: u32,
pub result_ok_fn: u32,
pub result_err_fn: u32,
}
pub(in crate::codegen::wasm_gc) struct TcpConnectHelperFns {
pub pool: TcpConnectPool,
pub dns: TcpConnectDns,
pub socket: TcpConnectSocket,
pub materialize: TcpConnectMaterialize,
}
const SCRATCH_BLOCK_SIZE: i32 = 64;
const SCRATCH_OFFSET_RESOLVE: u32 = 0;
const SCRATCH_OFFSET_NEXT: u32 = 16;
const SCRATCH_OFFSET_POLL: u32 = 48;
const SCRATCH_OFFSET_POLLABLE_IN: u32 = 56;
pub(in crate::codegen::wasm_gc) fn emit_tcp_connect_stub(
indices: &TcpConnectIndices,
helpers: &TcpConnectHelperFns,
) -> Function {
use wasm_encoder::{BlockType, MemArg};
let stale_slot_ref = ValType::Ref(wasm_encoder::RefType {
nullable: true,
heap_type: wasm_encoder::HeapType::Concrete(helpers.pool.tcp_slot_type_idx),
});
let mut f = Function::new(vec![
(12u32, ValType::I32),
(1u32, stale_slot_ref),
(1u32, ValType::I32),
]);
let l_host_len: u32 = 2;
let l_scratch: u32 = 3;
let l_resolve_stream: u32 = 4;
let l_pollable: u32 = 5;
let l_ipv4_a: u32 = 6;
let l_ipv4_b: u32 = 7;
let l_ipv4_c: u32 = 8;
let l_ipv4_d: u32 = 9;
let l_socket: u32 = 10;
let l_in_stream: u32 = 11;
let l_out_stream: u32 = 12;
let l_saved_alloc: u32 = 13;
let l_stale_slot: u32 = 14;
let l_scan_idx: u32 = 15;
let mem4_resolve = MemArg {
offset: u64::from(SCRATCH_OFFSET_RESOLVE),
align: 2,
memory_index: 0,
};
let mem4_resolve_off4 = MemArg {
offset: u64::from(SCRATCH_OFFSET_RESOLVE + 4),
align: 2,
memory_index: 0,
};
let mem1_resolve = MemArg {
offset: u64::from(SCRATCH_OFFSET_RESOLVE),
align: 0,
memory_index: 0,
};
let mem1_next_outer = MemArg {
offset: u64::from(SCRATCH_OFFSET_NEXT),
align: 0,
memory_index: 0,
};
let mem1_next_option = MemArg {
offset: u64::from(SCRATCH_OFFSET_NEXT + 2),
align: 0,
memory_index: 0,
};
let mem1_next_variant = MemArg {
offset: u64::from(SCRATCH_OFFSET_NEXT + 4),
align: 0,
memory_index: 0,
};
let mem1_next_octet_a = MemArg {
offset: u64::from(SCRATCH_OFFSET_NEXT + 6),
align: 0,
memory_index: 0,
};
let mem1_next_octet_b = MemArg {
offset: u64::from(SCRATCH_OFFSET_NEXT + 7),
align: 0,
memory_index: 0,
};
let mem1_next_octet_c = MemArg {
offset: u64::from(SCRATCH_OFFSET_NEXT + 8),
align: 0,
memory_index: 0,
};
let mem1_next_octet_d = MemArg {
offset: u64::from(SCRATCH_OFFSET_NEXT + 9),
align: 0,
memory_index: 0,
};
let mem4_pollable_in = MemArg {
offset: u64::from(SCRATCH_OFFSET_POLLABLE_IN),
align: 2,
memory_index: 0,
};
f.instruction(&Instruction::GlobalGet(helpers.pool.bump_alloc_ptr_global));
f.instruction(&Instruction::LocalSet(l_saved_alloc));
f.instruction(&Instruction::LocalGet(1)); f.instruction(&Instruction::I64Const(0));
f.instruction(&Instruction::I64LtS);
f.instruction(&Instruction::LocalGet(1));
f.instruction(&Instruction::I64Const(65535));
f.instruction(&Instruction::I64GtS);
f.instruction(&Instruction::I32Or);
f.instruction(&Instruction::If(BlockType::Empty));
f.instruction(&Instruction::I32Const(0));
f.instruction(&Instruction::I32Const(indices.port_err_len as i32));
f.instruction(&Instruction::ArrayNewData {
array_type_index: indices.string_type_idx,
array_data_index: indices.port_err_segment_idx,
});
f.instruction(&Instruction::Call(helpers.materialize.result_err_fn));
restore_bump(&mut f, l_saved_alloc, helpers.pool.bump_alloc_ptr_global);
f.instruction(&Instruction::Return);
f.instruction(&Instruction::End);
f.instruction(&Instruction::GlobalGet(helpers.dns.network_handle_global));
f.instruction(&Instruction::I32Const(-1));
f.instruction(&Instruction::I32Eq);
f.instruction(&Instruction::If(BlockType::Empty));
f.instruction(&Instruction::Call(helpers.dns.instance_network_fn));
f.instruction(&Instruction::GlobalSet(helpers.dns.network_handle_global));
f.instruction(&Instruction::End);
f.instruction(&Instruction::LocalGet(0));
f.instruction(&Instruction::Call(helpers.materialize.str_to_lm_fn));
f.instruction(&Instruction::LocalSet(l_host_len));
f.instruction(&Instruction::I32Const(0));
f.instruction(&Instruction::I32Const(0));
f.instruction(&Instruction::I32Const(4));
f.instruction(&Instruction::I32Const(SCRATCH_BLOCK_SIZE));
f.instruction(&Instruction::Call(helpers.materialize.cabi_realloc_fn));
f.instruction(&Instruction::LocalSet(l_scratch));
f.instruction(&Instruction::GlobalGet(helpers.dns.network_handle_global));
f.instruction(&Instruction::I32Const(0)); f.instruction(&Instruction::LocalGet(l_host_len));
f.instruction(&Instruction::LocalGet(l_scratch));
f.instruction(&Instruction::Call(helpers.dns.resolve_addresses_fn));
f.instruction(&Instruction::LocalGet(l_scratch));
f.instruction(&Instruction::I32Load8U(mem1_resolve));
f.instruction(&Instruction::If(BlockType::Empty));
f.instruction(&Instruction::I32Const(0));
f.instruction(&Instruction::I32Const(indices.dns_err_len as i32));
f.instruction(&Instruction::ArrayNewData {
array_type_index: indices.string_type_idx,
array_data_index: indices.dns_err_segment_idx,
});
f.instruction(&Instruction::Call(helpers.materialize.result_err_fn));
restore_bump(&mut f, l_saved_alloc, helpers.pool.bump_alloc_ptr_global);
f.instruction(&Instruction::Return);
f.instruction(&Instruction::End);
f.instruction(&Instruction::LocalGet(l_scratch));
f.instruction(&Instruction::I32Load(mem4_resolve_off4));
f.instruction(&Instruction::LocalSet(l_resolve_stream));
let _ = mem4_resolve;
f.instruction(&Instruction::Block(BlockType::Empty));
f.instruction(&Instruction::Loop(BlockType::Empty));
f.instruction(&Instruction::LocalGet(l_resolve_stream));
f.instruction(&Instruction::Call(helpers.dns.stream_subscribe_fn));
f.instruction(&Instruction::LocalSet(l_pollable));
f.instruction(&Instruction::LocalGet(l_scratch));
f.instruction(&Instruction::LocalGet(l_pollable));
f.instruction(&Instruction::I32Store(mem4_pollable_in));
f.instruction(&Instruction::LocalGet(l_scratch));
f.instruction(&Instruction::I32Const(SCRATCH_OFFSET_POLLABLE_IN as i32));
f.instruction(&Instruction::I32Add);
f.instruction(&Instruction::I32Const(1));
f.instruction(&Instruction::LocalGet(l_scratch));
f.instruction(&Instruction::I32Const(SCRATCH_OFFSET_POLL as i32));
f.instruction(&Instruction::I32Add);
f.instruction(&Instruction::Call(helpers.dns.poll_fn));
f.instruction(&Instruction::LocalGet(l_pollable));
f.instruction(&Instruction::Call(helpers.dns.drop_pollable_fn));
f.instruction(&Instruction::LocalGet(l_resolve_stream));
f.instruction(&Instruction::LocalGet(l_scratch));
f.instruction(&Instruction::I32Const(SCRATCH_OFFSET_NEXT as i32));
f.instruction(&Instruction::I32Add);
f.instruction(&Instruction::Call(helpers.dns.resolve_next_address_fn));
f.instruction(&Instruction::LocalGet(l_scratch));
f.instruction(&Instruction::I32Load8U(mem1_next_outer));
f.instruction(&Instruction::If(BlockType::Empty));
f.instruction(&Instruction::LocalGet(l_resolve_stream));
f.instruction(&Instruction::Call(helpers.dns.drop_resolve_stream_fn));
f.instruction(&Instruction::I32Const(0));
f.instruction(&Instruction::I32Const(indices.no_addr_len as i32));
f.instruction(&Instruction::ArrayNewData {
array_type_index: indices.string_type_idx,
array_data_index: indices.no_addr_segment_idx,
});
f.instruction(&Instruction::Call(helpers.materialize.result_err_fn));
restore_bump(&mut f, l_saved_alloc, helpers.pool.bump_alloc_ptr_global);
f.instruction(&Instruction::Return);
f.instruction(&Instruction::End);
f.instruction(&Instruction::LocalGet(l_scratch));
f.instruction(&Instruction::I32Load8U(mem1_next_option));
f.instruction(&Instruction::I32Eqz);
f.instruction(&Instruction::If(BlockType::Empty));
f.instruction(&Instruction::LocalGet(l_resolve_stream));
f.instruction(&Instruction::Call(helpers.dns.drop_resolve_stream_fn));
f.instruction(&Instruction::I32Const(0));
f.instruction(&Instruction::I32Const(indices.no_addr_len as i32));
f.instruction(&Instruction::ArrayNewData {
array_type_index: indices.string_type_idx,
array_data_index: indices.no_addr_segment_idx,
});
f.instruction(&Instruction::Call(helpers.materialize.result_err_fn));
restore_bump(&mut f, l_saved_alloc, helpers.pool.bump_alloc_ptr_global);
f.instruction(&Instruction::Return);
f.instruction(&Instruction::End);
f.instruction(&Instruction::LocalGet(l_scratch));
f.instruction(&Instruction::I32Load8U(mem1_next_variant));
f.instruction(&Instruction::BrIf(0));
f.instruction(&Instruction::LocalGet(l_scratch));
f.instruction(&Instruction::I32Load8U(mem1_next_octet_a));
f.instruction(&Instruction::LocalSet(l_ipv4_a));
f.instruction(&Instruction::LocalGet(l_scratch));
f.instruction(&Instruction::I32Load8U(mem1_next_octet_b));
f.instruction(&Instruction::LocalSet(l_ipv4_b));
f.instruction(&Instruction::LocalGet(l_scratch));
f.instruction(&Instruction::I32Load8U(mem1_next_octet_c));
f.instruction(&Instruction::LocalSet(l_ipv4_c));
f.instruction(&Instruction::LocalGet(l_scratch));
f.instruction(&Instruction::I32Load8U(mem1_next_octet_d));
f.instruction(&Instruction::LocalSet(l_ipv4_d));
f.instruction(&Instruction::Br(1));
f.instruction(&Instruction::End); f.instruction(&Instruction::End);
f.instruction(&Instruction::LocalGet(l_resolve_stream));
f.instruction(&Instruction::Call(helpers.dns.drop_resolve_stream_fn));
f.instruction(&Instruction::GlobalGet(helpers.pool.tcp_pool_global));
f.instruction(&Instruction::RefIsNull);
f.instruction(&Instruction::If(BlockType::Empty));
f.instruction(&Instruction::I32Const(256));
f.instruction(&Instruction::ArrayNewDefault(
helpers.pool.tcp_pool_type_idx,
));
f.instruction(&Instruction::GlobalSet(helpers.pool.tcp_pool_global));
f.instruction(&Instruction::End);
f.instruction(&Instruction::I32Const(0));
f.instruction(&Instruction::LocalSet(l_scan_idx));
f.instruction(&Instruction::Block(BlockType::Empty)); f.instruction(&Instruction::Loop(BlockType::Empty));
f.instruction(&Instruction::LocalGet(l_scan_idx));
f.instruction(&Instruction::I32Const(256));
f.instruction(&Instruction::I32GeU);
f.instruction(&Instruction::If(BlockType::Empty));
f.instruction(&Instruction::I32Const(0));
f.instruction(&Instruction::I32Const(indices.limit_err_len as i32));
f.instruction(&Instruction::ArrayNewData {
array_type_index: indices.string_type_idx,
array_data_index: indices.limit_err_segment_idx,
});
f.instruction(&Instruction::Call(helpers.materialize.result_err_fn));
restore_bump(&mut f, l_saved_alloc, helpers.pool.bump_alloc_ptr_global);
f.instruction(&Instruction::Return);
f.instruction(&Instruction::End); f.instruction(&Instruction::GlobalGet(helpers.pool.tcp_pool_global));
f.instruction(&Instruction::LocalGet(l_scan_idx));
f.instruction(&Instruction::ArrayGet(helpers.pool.tcp_pool_type_idx));
f.instruction(&Instruction::LocalTee(l_stale_slot));
f.instruction(&Instruction::RefIsNull);
f.instruction(&Instruction::BrIf(1)); f.instruction(&Instruction::LocalGet(l_stale_slot));
f.instruction(&Instruction::StructGet {
struct_type_index: helpers.pool.tcp_slot_type_idx,
field_index: 3, });
f.instruction(&Instruction::I32Eqz);
f.instruction(&Instruction::BrIf(1)); f.instruction(&Instruction::LocalGet(l_scan_idx));
f.instruction(&Instruction::I32Const(1));
f.instruction(&Instruction::I32Add);
f.instruction(&Instruction::LocalSet(l_scan_idx));
f.instruction(&Instruction::Br(0)); f.instruction(&Instruction::End); f.instruction(&Instruction::End);
f.instruction(&Instruction::I32Const(0)); f.instruction(&Instruction::LocalGet(l_scratch));
f.instruction(&Instruction::Call(helpers.socket.create_tcp_socket_fn));
f.instruction(&Instruction::LocalGet(l_scratch));
f.instruction(&Instruction::I32Load8U(mem1_resolve));
f.instruction(&Instruction::If(BlockType::Empty));
f.instruction(&Instruction::I32Const(0));
f.instruction(&Instruction::I32Const(indices.sock_err_len as i32));
f.instruction(&Instruction::ArrayNewData {
array_type_index: indices.string_type_idx,
array_data_index: indices.sock_err_segment_idx,
});
f.instruction(&Instruction::Call(helpers.materialize.result_err_fn));
restore_bump(&mut f, l_saved_alloc, helpers.pool.bump_alloc_ptr_global);
f.instruction(&Instruction::Return);
f.instruction(&Instruction::End);
f.instruction(&Instruction::LocalGet(l_scratch));
f.instruction(&Instruction::I32Load(mem4_resolve_off4));
f.instruction(&Instruction::LocalSet(l_socket));
f.instruction(&Instruction::LocalGet(l_socket));
f.instruction(&Instruction::GlobalGet(helpers.dns.network_handle_global));
f.instruction(&Instruction::I32Const(0)); f.instruction(&Instruction::LocalGet(1)); f.instruction(&Instruction::I32WrapI64);
f.instruction(&Instruction::LocalGet(l_ipv4_a));
f.instruction(&Instruction::LocalGet(l_ipv4_b));
f.instruction(&Instruction::LocalGet(l_ipv4_c));
f.instruction(&Instruction::LocalGet(l_ipv4_d));
for _ in 0..6 {
f.instruction(&Instruction::I32Const(0));
}
f.instruction(&Instruction::LocalGet(l_scratch));
f.instruction(&Instruction::Call(helpers.socket.start_connect_fn));
f.instruction(&Instruction::LocalGet(l_scratch));
f.instruction(&Instruction::I32Load8U(mem1_resolve));
f.instruction(&Instruction::If(BlockType::Empty));
f.instruction(&Instruction::LocalGet(l_socket));
f.instruction(&Instruction::Call(helpers.socket.drop_tcp_socket_fn));
f.instruction(&Instruction::I32Const(0));
f.instruction(&Instruction::I32Const(indices.conn_err_len as i32));
f.instruction(&Instruction::ArrayNewData {
array_type_index: indices.string_type_idx,
array_data_index: indices.conn_err_segment_idx,
});
f.instruction(&Instruction::Call(helpers.materialize.result_err_fn));
restore_bump(&mut f, l_saved_alloc, helpers.pool.bump_alloc_ptr_global);
f.instruction(&Instruction::Return);
f.instruction(&Instruction::End);
f.instruction(&Instruction::LocalGet(l_socket));
f.instruction(&Instruction::Call(helpers.socket.socket_subscribe_fn));
f.instruction(&Instruction::LocalSet(l_pollable));
f.instruction(&Instruction::LocalGet(l_scratch));
f.instruction(&Instruction::LocalGet(l_pollable));
f.instruction(&Instruction::I32Store(mem4_pollable_in));
f.instruction(&Instruction::LocalGet(l_scratch));
f.instruction(&Instruction::I32Const(SCRATCH_OFFSET_POLLABLE_IN as i32));
f.instruction(&Instruction::I32Add);
f.instruction(&Instruction::I32Const(1));
f.instruction(&Instruction::LocalGet(l_scratch));
f.instruction(&Instruction::I32Const(SCRATCH_OFFSET_POLL as i32));
f.instruction(&Instruction::I32Add);
f.instruction(&Instruction::Call(helpers.dns.poll_fn));
f.instruction(&Instruction::LocalGet(l_pollable));
f.instruction(&Instruction::Call(helpers.dns.drop_pollable_fn));
f.instruction(&Instruction::LocalGet(l_socket));
f.instruction(&Instruction::LocalGet(l_scratch));
f.instruction(&Instruction::Call(helpers.socket.finish_connect_fn));
f.instruction(&Instruction::LocalGet(l_scratch));
f.instruction(&Instruction::I32Load8U(mem1_resolve));
f.instruction(&Instruction::If(BlockType::Empty));
f.instruction(&Instruction::LocalGet(l_socket));
f.instruction(&Instruction::Call(helpers.socket.drop_tcp_socket_fn));
f.instruction(&Instruction::I32Const(0));
f.instruction(&Instruction::I32Const(indices.conn_err_len as i32));
f.instruction(&Instruction::ArrayNewData {
array_type_index: indices.string_type_idx,
array_data_index: indices.conn_err_segment_idx,
});
f.instruction(&Instruction::Call(helpers.materialize.result_err_fn));
restore_bump(&mut f, l_saved_alloc, helpers.pool.bump_alloc_ptr_global);
f.instruction(&Instruction::Return);
f.instruction(&Instruction::End);
f.instruction(&Instruction::LocalGet(l_scratch));
f.instruction(&Instruction::I32Load(mem4_resolve_off4));
f.instruction(&Instruction::LocalSet(l_in_stream));
{
let mem4_resolve_off8 = MemArg {
offset: u64::from(SCRATCH_OFFSET_RESOLVE + 8),
align: 2,
memory_index: 0,
};
f.instruction(&Instruction::LocalGet(l_scratch));
f.instruction(&Instruction::I32Load(mem4_resolve_off8));
f.instruction(&Instruction::LocalSet(l_out_stream));
}
let _ = (l_ipv4_a, l_ipv4_b, l_ipv4_c, l_ipv4_d);
let _ = l_stale_slot;
f.instruction(&Instruction::GlobalGet(helpers.pool.tcp_pool_global));
f.instruction(&Instruction::LocalGet(l_scan_idx));
f.instruction(&Instruction::LocalGet(l_socket));
f.instruction(&Instruction::LocalGet(l_in_stream));
f.instruction(&Instruction::LocalGet(l_out_stream));
f.instruction(&Instruction::I32Const(1)); f.instruction(&Instruction::GlobalGet(helpers.pool.tcp_next_id_global));
f.instruction(&Instruction::StructNew(helpers.pool.tcp_slot_type_idx));
f.instruction(&Instruction::ArraySet(helpers.pool.tcp_pool_type_idx));
f.instruction(&Instruction::GlobalGet(helpers.pool.tcp_next_id_global));
f.instruction(&Instruction::Call(helpers.materialize.format_id_fn));
f.instruction(&Instruction::GlobalGet(helpers.pool.tcp_next_id_global));
f.instruction(&Instruction::I32Const(1));
f.instruction(&Instruction::I32Add);
f.instruction(&Instruction::GlobalSet(helpers.pool.tcp_next_id_global));
f.instruction(&Instruction::LocalGet(0)); f.instruction(&Instruction::LocalGet(1)); f.instruction(&Instruction::Call(helpers.materialize.record_make_fn));
f.instruction(&Instruction::Call(helpers.materialize.result_ok_fn));
restore_bump(&mut f, l_saved_alloc, helpers.pool.bump_alloc_ptr_global);
let _ = indices.stub_err_segment_idx;
let _ = indices.stub_err_len;
f.instruction(&Instruction::End);
f
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn stub_emit_compiles() {
let indices = TcpConnectIndices {
fn_type: 0,
fn_idx: 0,
string_type_idx: 1,
stub_err_segment_idx: 0,
stub_err_len: b"tcp: connect not yet implemented".len() as u32,
dns_err_segment_idx: 1,
dns_err_len: b"tcp: dns resolve failed".len() as u32,
no_addr_segment_idx: 2,
no_addr_len: b"tcp: dns no addresses".len() as u32,
sock_err_segment_idx: 3,
sock_err_len: b"tcp: socket create failed".len() as u32,
conn_err_segment_idx: 4,
conn_err_len: b"tcp: connect failed".len() as u32,
port_err_segment_idx: 5,
port_err_len: b"tcp: port out of range".len() as u32,
limit_err_segment_idx: 6,
limit_err_len: b"tcp: connection limit reached (256 max)".len() as u32,
};
let helpers = TcpConnectHelperFns {
pool: TcpConnectPool {
tcp_next_id_global: 1,
tcp_pool_global: 2,
tcp_slot_type_idx: 3,
tcp_pool_type_idx: 4,
bump_alloc_ptr_global: 5,
},
dns: TcpConnectDns {
instance_network_fn: 3,
network_handle_global: 0,
resolve_addresses_fn: 6,
resolve_next_address_fn: 11,
drop_resolve_stream_fn: 7,
stream_subscribe_fn: 8,
poll_fn: 9,
drop_pollable_fn: 10,
},
socket: TcpConnectSocket {
create_tcp_socket_fn: 12,
start_connect_fn: 13,
finish_connect_fn: 15,
socket_subscribe_fn: 14,
drop_tcp_socket_fn: 16,
},
materialize: TcpConnectMaterialize {
cabi_realloc_fn: 4,
str_to_lm_fn: 5,
format_id_fn: 17,
record_make_fn: 18,
result_ok_fn: 19,
result_err_fn: 2,
},
};
let _f = emit_tcp_connect_stub(&indices, &helpers);
}
}