diff --git a/Cargo.toml b/Cargo.toml index 88879d660..859573ee9 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -46,6 +46,7 @@ adler = { version = "1" } toml = { version = "1", default-features = false, features = ["parse", "display", "serde"] } libc = { version = "0.2" } + [profile.dev.package.wado-compiler] opt-level = 1 diff --git a/wado-compiler/src/cm_abi.rs b/wado-compiler/src/cm_abi.rs index 1f2b21384..fe9a87862 100644 --- a/wado-compiler/src/cm_abi.rs +++ b/wado-compiler/src/cm_abi.rs @@ -230,8 +230,19 @@ pub fn layout_option_with_registry( inner: &Type, registry: &crate::component_model::WasiRegistry, ) -> CmLayout { - let payload_align = crate::component_model::cm_align_with_registry(inner, registry); - let payload_size = crate::component_model::cm_size_with_registry(inner, registry); + layout_option_with_registry_scoped(inner, registry, None) +} + +/// Package-scoped registry-aware layout for option. +pub fn layout_option_with_registry_scoped( + inner: &Type, + registry: &crate::component_model::WasiRegistry, + wasi_package: Option<&str>, +) -> CmLayout { + let payload_align = + crate::component_model::cm_align_with_registry_scoped(inner, registry, wasi_package); + let payload_size = + crate::component_model::cm_size_with_registry_scoped(inner, registry, wasi_package); let overall_align = 1u32.max(payload_align); let payload_offset = align_to(1, payload_align); let size = align_to(payload_offset + payload_size, overall_align); @@ -248,11 +259,24 @@ pub fn layout_result_with_registry( err: &Type, registry: &crate::component_model::WasiRegistry, ) -> CmLayout { - let payload_align = crate::component_model::cm_align_with_registry(ok, registry).max( - crate::component_model::cm_align_with_registry(err, registry), - ); - let payload_size = crate::component_model::cm_size_with_registry(ok, registry) - .max(crate::component_model::cm_size_with_registry(err, registry)); + layout_result_with_registry_scoped(ok, err, registry, None) +} + +/// Package-scoped registry-aware layout for result. +pub fn layout_result_with_registry_scoped( + ok: &Type, + err: &Type, + registry: &crate::component_model::WasiRegistry, + wasi_package: Option<&str>, +) -> CmLayout { + let payload_align = + crate::component_model::cm_align_with_registry_scoped(ok, registry, wasi_package).max( + crate::component_model::cm_align_with_registry_scoped(err, registry, wasi_package), + ); + let payload_size = + crate::component_model::cm_size_with_registry_scoped(ok, registry, wasi_package).max( + crate::component_model::cm_size_with_registry_scoped(err, registry, wasi_package), + ); let overall_align = 1u32.max(payload_align); let disc_size = 1u32; let payload_offset = align_to(disc_size, payload_align); diff --git a/wado-compiler/src/codegen/component.rs b/wado-compiler/src/codegen/component.rs index 5b39c1b4e..e8c56981c 100644 --- a/wado-compiler/src/codegen/component.rs +++ b/wado-compiler/src/codegen/component.rs @@ -1437,7 +1437,7 @@ fn generate_wasi_imports( .iter() .filter(|name| { project.wasi_registry.is_variant(name) - && !(name.as_str() == "ErrorCode" && !has_local_error_code) + && (name.as_str() != "ErrorCode" || has_local_error_code) }) .cloned() .collect(); @@ -1448,7 +1448,7 @@ fn generate_wasi_imports( .filter(|name| { project.wasi_registry.is_enum(name) && !needed_variants.contains(name) - && !(name.as_str() == "ErrorCode" && !has_local_error_code) + && (name.as_str() != "ErrorCode" || has_local_error_code) }) .cloned() .collect(); diff --git a/wado-compiler/src/component_model.rs b/wado-compiler/src/component_model.rs index bd357da0c..c0eb5ecdc 100644 --- a/wado-compiler/src/component_model.rs +++ b/wado-compiler/src/component_model.rs @@ -2286,7 +2286,26 @@ pub fn cm_align_with_registry(ty: &Type, registry: &WasiRegistry) -> u32 { /// - payload: at `align_to(1, max_payload_align)` /// - total: `align_to(payload_offset + max_payload_size, max_payload_align)` pub fn wasi_variant_cm_size_align(name: &str, registry: &WasiRegistry) -> Option<(u32, u32)> { - let cases = registry.get_variant_cases(name)?; + wasi_variant_cm_size_align_scoped(name, registry, None) +} + +/// Package-scoped variant of `wasi_variant_cm_size_align`. +/// +/// When `wasi_package` is provided (e.g., `"http"`), uses package-scoped lookup +/// to disambiguate variant types that share the same Wado name across different +/// WASI packages (e.g., `ErrorCode` exists in http, filesystem, and sockets). +pub fn wasi_variant_cm_size_align_scoped( + name: &str, + registry: &WasiRegistry, + wasi_package: Option<&str>, +) -> Option<(u32, u32)> { + let cases = if let Some(pkg) = wasi_package { + registry + .get_variant_cases_by_package(pkg, name) + .or_else(|| registry.get_variant_cases(name)) + } else { + registry.get_variant_cases(name) + }?; if !cases.iter().any(|case| case.payload.is_some()) { return None; // no payload cases — not outptr } @@ -2294,8 +2313,10 @@ pub fn wasi_variant_cm_size_align(name: &str, registry: &WasiRegistry) -> Option let mut max_payload_align = 1u32; for case in cases { if let Some(ty) = &case.payload { - max_payload_size = max_payload_size.max(cm_size_with_registry(ty, registry)); - max_payload_align = max_payload_align.max(cm_align_with_registry(ty, registry)); + max_payload_size = + max_payload_size.max(cm_size_with_registry_scoped(ty, registry, wasi_package)); + max_payload_align = + max_payload_align.max(cm_align_with_registry_scoped(ty, registry, wasi_package)); } } let disc_size = 1u32; // u8 for n ≤ 256 cases @@ -2305,6 +2326,133 @@ pub fn wasi_variant_cm_size_align(name: &str, registry: &WasiRegistry) -> Option Some((size, overall_align)) } +/// Package-scoped CM canonical ABI size for a type. +/// +/// Like `cm_size_with_registry`, but uses `wasi_package` to disambiguate types +/// with the same name across different WASI packages. +pub fn cm_size_with_registry_scoped( + ty: &Type, + registry: &WasiRegistry, + wasi_package: Option<&str>, +) -> u32 { + match ty { + Type::Named(named) => { + if let Some(resolved) = registry.get_newtype(&named.name) { + return cm_size_with_registry_scoped(resolved, registry, wasi_package); + } + if let Some(fields) = registry.get_struct_fields(&named.name) { + let resolved_fields: Vec = fields + .iter() + .map(|(_, ty)| registry.resolve_type(ty)) + .collect(); + let mut offset = 0u32; + let mut max_align = 1u32; + for field_ty in &resolved_fields { + let fa = cm_align_with_registry_scoped(field_ty, registry, wasi_package); + let fs = cm_size_with_registry_scoped(field_ty, registry, wasi_package); + offset = crate::cm_abi::align_to(offset, fa); + offset += fs; + max_align = max_align.max(fa); + } + return crate::cm_abi::align_to(offset, max_align); + } + if let Some(sa) = wasi_variant_cm_size_align_scoped(&named.name, registry, wasi_package) + { + return sa.0; + } + if let Some(variants) = registry.get_enum_variants(&named.name) { + return crate::synthesis::cm_binding::cm_enum_byte_size(variants.len()); + } + if let Some(members) = registry.get_flags_members(&named.name) { + return crate::synthesis::cm_binding::cm_flags_byte_size(members.len()); + } + crate::cm_abi::cm_size(ty) + } + Type::Generic(g) => match g.name.as_str() { + "Option" if g.args.len() == 1 => { + let inner = &g.args[0]; + let payload_align = cm_align_with_registry_scoped(inner, registry, wasi_package); + let payload_size = cm_size_with_registry_scoped(inner, registry, wasi_package); + let payload_offset = crate::cm_abi::align_to(1, payload_align); + let overall_align = 1u32.max(payload_align); + crate::cm_abi::align_to(payload_offset + payload_size, overall_align) + } + "Result" if g.args.len() == 2 => { + let ok_size = cm_size_with_registry_scoped(&g.args[0], registry, wasi_package); + let err_size = cm_size_with_registry_scoped(&g.args[1], registry, wasi_package); + let payload_size = ok_size.max(err_size); + let payload_align = + cm_align_with_registry_scoped(&g.args[0], registry, wasi_package).max( + cm_align_with_registry_scoped(&g.args[1], registry, wasi_package), + ); + let payload_offset = crate::cm_abi::align_to(1, payload_align); + let overall_align = 1u32.max(payload_align); + crate::cm_abi::align_to(payload_offset + payload_size, overall_align) + } + _ => crate::cm_abi::cm_size(ty), + }, + _ => crate::cm_abi::cm_size(ty), + } +} + +/// Package-scoped CM canonical ABI alignment for a type. +pub fn cm_align_with_registry_scoped( + ty: &Type, + registry: &WasiRegistry, + wasi_package: Option<&str>, +) -> u32 { + match ty { + Type::Named(named) => { + if let Some(resolved) = registry.get_newtype(&named.name) { + return cm_align_with_registry_scoped(resolved, registry, wasi_package); + } + if let Some(fields) = registry.get_struct_fields(&named.name) { + let mut max_align = 1u32; + for (_, field_ty) in fields { + let resolved = registry.resolve_type(field_ty); + max_align = max_align.max(cm_align_with_registry_scoped( + &resolved, + registry, + wasi_package, + )); + } + return max_align; + } + if let Some(sa) = wasi_variant_cm_size_align_scoped(&named.name, registry, wasi_package) + { + return sa.1; + } + if let Some(variants) = registry.get_enum_variants(&named.name) { + return crate::synthesis::cm_binding::cm_enum_byte_size(variants.len()); + } + if let Some(members) = registry.get_flags_members(&named.name) { + return crate::synthesis::cm_binding::cm_flags_byte_align(members.len()); + } + crate::cm_abi::cm_align(ty) + } + Type::Generic(g) => match g.name.as_str() { + "Option" if g.args.len() == 1 => 1u32.max(cm_align_with_registry_scoped( + &g.args[0], + registry, + wasi_package, + )), + "Result" if g.args.len() == 2 => 1u32 + .max(cm_align_with_registry_scoped( + &g.args[0], + registry, + wasi_package, + )) + .max(cm_align_with_registry_scoped( + &g.args[1], + registry, + wasi_package, + )), + _ => crate::cm_abi::cm_align(ty), + }, + _ => crate::cm_abi::cm_align(ty), + } +} + /// Primitive type for CM tuple return handling #[derive(Debug, Clone, Copy, PartialEq, Eq)] pub enum CmPrimitiveType { diff --git a/wado-compiler/src/lib.rs b/wado-compiler/src/lib.rs index 70ba9b463..8d9baaddd 100644 --- a/wado-compiler/src/lib.rs +++ b/wado-compiler/src/lib.rs @@ -230,7 +230,7 @@ pub async fn compile_with_options( let is_todo_module = load_result.entry_ast.has_todo(); // Wrap all subsequent Bail errors with is_todo_module - let result = compile_after_load(load_result, options, &logger, filename).await; + let result = compile_after_load(load_result, options, &logger, filename); match result { Ok((wasm, module, wir_module)) => Ok(CompileResult { wasm, @@ -243,7 +243,7 @@ pub async fn compile_with_options( } /// Internal: run compilation phases after module loading. -async fn compile_after_load( +fn compile_after_load( load_result: loader::LoadResult, options: CompilerOptions, logger: &Logger<'_, H>, diff --git a/wado-compiler/src/monomorphize/func_inst.rs b/wado-compiler/src/monomorphize/func_inst.rs index 1d5696480..f7426257c 100644 --- a/wado-compiler/src/monomorphize/func_inst.rs +++ b/wado-compiler/src/monomorphize/func_inst.rs @@ -1974,7 +1974,7 @@ impl Monomorphizer { // selects the correct generic function template // ("&^IntoIterator::into_iter" instead of "Array^IntoIterator::into_iter"). if info.is_ref_impl { - new_info.base_struct_name = info.base_struct_name.clone(); + new_info.base_struct_name.clone_from(&info.base_struct_name); } new_info } else { diff --git a/wado-compiler/src/synthesis/cm_binding.rs b/wado-compiler/src/synthesis/cm_binding.rs index 037325c29..d8236fdaa 100644 --- a/wado-compiler/src/synthesis/cm_binding.rs +++ b/wado-compiler/src/synthesis/cm_binding.rs @@ -593,10 +593,21 @@ fn synthesize_lift_wasi_variant( )); // Compute max payload alignment for payload offset calculation + let wasi_package = ctx.and_then(|c| c.wasi_package); let max_payload_align = cases .iter() .filter_map(|case| case.payload.as_ref()) - .map(cm_abi::cm_align) + .map(|ty| { + if let Some(c) = ctx { + crate::component_model::cm_align_with_registry_scoped( + ty, + c.wasi_registry, + wasi_package, + ) + } else { + cm_abi::cm_align(ty) + } + }) .max() .unwrap_or(1); let payload_offset = cm_abi::align_to(1, max_payload_align); // after 1-byte disc @@ -935,7 +946,7 @@ fn synthesize_lift_option_inner( ctx: Option<&LiftContext<'_>>, ) -> TirExpr { let layout = if let Some(c) = ctx { - cm_abi::layout_option_with_registry(inner_ty, c.wasi_registry) + cm_abi::layout_option_with_registry_scoped(inner_ty, c.wasi_registry, c.wasi_package) } else { cm_abi::layout_option(inner_ty) }; @@ -1012,7 +1023,7 @@ fn synthesize_lift_result_inner( ctx: Option<&LiftContext<'_>>, ) -> TirExpr { let layout = if let Some(c) = ctx { - cm_abi::layout_result_with_registry(ok_ty, err_ty, c.wasi_registry) + cm_abi::layout_result_with_registry_scoped(ok_ty, err_ty, c.wasi_registry, c.wasi_package) } else { cm_abi::layout_result(ok_ty, err_ty) }; @@ -1461,9 +1472,17 @@ fn synthesize_lower_tuple( stmts } -fn is_gc_passthrough_param(ty: &Type) -> bool { - matches!(ty, Type::Named(n) if n.name == "String") - || matches!(ty, Type::Generic(g) if g.name == "Array" && g.args.len() == 1) +/// Check if a type is a "GC passthrough" parameter — one that the binding +/// accepts as a GC reference and lowers internally, rather than requiring +/// the call site to flatten into CM ABI i32 args. +fn is_gc_passthrough_param(ty: &Type, wasi_registry: &WasiRegistry) -> bool { + match ty { + Type::Named(n) if n.name == "String" => true, + Type::Named(n) if wasi_registry.is_variant(&n.name) => true, + Type::Generic(g) if g.name == "Array" && g.args.len() == 1 => true, + Type::Generic(g) if g.name == "Option" && g.args.len() == 1 => true, + _ => false, + } } fn is_wasm_flat_type(type_id: TypeId) -> bool { @@ -1478,6 +1497,15 @@ pub fn flatten_param_type( ty: &Type, wasi_registry: &crate::component_model::WasiRegistry, ) -> Vec { + fn cm_val_to_type_id(v: &cm_abi::CmValType) -> TypeId { + match v { + cm_abi::CmValType::I32 => TypeTable::I32, + cm_abi::CmValType::I64 => TypeTable::I64, + cm_abi::CmValType::F32 => TypeTable::F32, + cm_abi::CmValType::F64 => TypeTable::F64, + } + } + let resolved = wasi_registry.resolve_type(ty); match &resolved { Type::Named(named) => match named.name.as_str() { @@ -1488,21 +1516,49 @@ pub fn flatten_param_type( "f32" => vec![TypeTable::F32], "f64" => vec![TypeTable::F64], "String" => vec![TypeTable::I32, TypeTable::I32], - _ => vec![TypeTable::I32], + name => { + // WASI variant: discriminant + join of all case payload flat types + if let Some(cases) = wasi_registry.get_variant_cases(name) { + let mut result = vec![TypeTable::I32]; // discriminant + let case_flats: Vec> = cases + .iter() + .map(|c| { + c.payload + .as_ref() + .map(|t| flatten_param_type(t, wasi_registry)) + .unwrap_or_default() + }) + .collect(); + let max_len = case_flats.iter().map(Vec::len).max().unwrap_or(0); + for i in 0..max_len { + // Join: if all non-empty cases at position i agree on a type, + // use that type; otherwise use i32 (per CM spec join). + let joined = case_flats + .iter() + .filter_map(|f| f.get(i).copied()) + .reduce(|a, b| if a == b { a } else { TypeTable::I32 }) + .unwrap_or(TypeTable::I32); + result.push(joined); + } + return result; + } + // WASI struct (record): concatenation of all field flat types + if let Some(fields) = wasi_registry.get_struct_fields_with_wado_names(name) { + return fields + .iter() + .flat_map(|(_, _, ft)| flatten_param_type(ft, wasi_registry)) + .collect(); + } + // Resource handles, enums, flags, etc.: single i32 + vec![TypeTable::I32] + } }, Type::Generic(g) if g.name == "Stream" => vec![TypeTable::I32], Type::Reference(_) | Type::MutReference(_) => vec![TypeTable::I32], Type::Tuple(elems) if elems.is_empty() => vec![], _ => { let flat = cm_abi::cm_flat_types(&resolved); - flat.iter() - .map(|t| match t { - cm_abi::CmValType::I32 => TypeTable::I32, - cm_abi::CmValType::I64 => TypeTable::I64, - cm_abi::CmValType::F32 => TypeTable::F32, - cm_abi::CmValType::F64 => TypeTable::F64, - }) - .collect() + flat.iter().map(cm_val_to_type_id).collect() } } } @@ -1655,6 +1711,345 @@ fn synthesize_lower_wasi_variant_to_memory( } } +/// Lower an `Option` value to linear memory at the given address. +/// +/// Memory layout (Canonical ABI for `option`): +/// - discriminant byte at offset 0 (0=None, 1=Some) +/// - payload at `align_to(1, payload_align)`, lowered using `synthesize_lower_wasi_type_to_memory` +fn synthesize_lower_option_to_memory( + inner_type: &Type, + value: TirExpr, + addr: TirExpr, + next_local: &mut u32, + stmts: &mut Vec, + local_types: &mut Vec, + wasi_registry: &crate::component_model::WasiRegistry, + type_table: &RefCell, +) { + let value_type_id = value.type_id; + + // Materialize value into a local so we can reference it multiple times + let value_local = alloc_local(next_local, local_types, value_type_id); + stmts.push(let_stmt("__opt_val", value_local, value_type_id, value)); + + // Store discriminant byte: variant_test(Some) → 1 = Some, 0 = None. + // Use variant_test (ref.test) rather than variant_tag (struct.get) + // because variant_tag traps on null refs. + stmts.push(expr_stmt(builtin_call( + "i32_store8", + vec![ + addr.clone(), + variant_test( + local_ref(value_local, "__opt_val", value_type_id), + 0, + "Some", + ), + ], + TypeTable::UNIT, + ))); + + // Compute payload offset (aligned to payload alignment) + let payload_align = crate::component_model::cm_align_with_registry(inner_type, wasi_registry); + let payload_offset = crate::cm_abi::align_to(1, payload_align); + + let payload_addr = if payload_offset == 0 { + addr + } else { + binary_add(addr, i32_const(payload_offset as i32)) + }; + + // If Some: lower payload to memory + let inner_type_id = { + let mut tt = type_table.borrow_mut(); + wasi_type_to_type_id_with_registry(inner_type, &mut tt, Some(wasi_registry)) + }; + let payload_expr = variant_payload( + local_ref(value_local, "__opt_val", value_type_id), + 0, + inner_type_id, + ); + + let case_stmts = synthesize_lower_wasi_type_to_memory( + inner_type, + payload_expr, + payload_addr, + next_local, + local_types, + wasi_registry, + type_table, + ); + + stmts.push(if_stmt( + variant_test( + local_ref(value_local, "__opt_val", value_type_id), + 0, + "Some", + ), + block(case_stmts), + None, + )); +} + +/// Flatten a WASI type value (GC ref) to flat CM ABI args (i32/i64/f32/f64). +/// +/// Used for sync function params where the binding receives a GC value +/// but needs to pass flat values to the WASI import. +/// Appends lowering statements to `stmts` and flat value expressions to `flat_args`. +fn synthesize_flatten_value_to_flat_args( + ty: &Type, + value: TirExpr, + prefix: &str, + next_local: &mut u32, + stmts: &mut Vec, + local_types: &mut Vec, + flat_args: &mut Vec, + wasi_registry: &crate::component_model::WasiRegistry, + type_table: &RefCell, +) { + let resolved = wasi_registry.resolve_type(ty); + match &resolved { + // String → cm_lower_string → packed i64 → (ptr, len) + Type::Named(n) if n.name == "String" => { + let packed_local = alloc_local(next_local, local_types, TypeTable::I64); + stmts.push(let_stmt( + &format!("{prefix}_packed"), + packed_local, + TypeTable::I64, + internal_call("cm_lower_string", vec![value], TypeTable::I64), + )); + // ptr = packed as i32 (low 32 bits) + flat_args.push(cast( + local_ref(packed_local, &format!("{prefix}_packed"), TypeTable::I64), + TypeTable::I32, + )); + // len = (packed >> 32) as i32 (high 32 bits) + flat_args.push(cast( + binary( + crate::tir::TirBinaryOp::Shr, + local_ref(packed_local, &format!("{prefix}_packed"), TypeTable::I64), + i64_const(32), + TypeTable::I64, + ), + TypeTable::I32, + )); + } + // Enum → variant_tag (single i32) + Type::Named(n) if wasi_registry.is_enum(&n.name) => { + flat_args.push(variant_tag(value)); + } + // Variant → disc + join of all case payload flats + Type::Named(n) if wasi_registry.is_variant(&n.name) => { + let vt = value.type_id; + let val_local = alloc_local(next_local, local_types, vt); + stmts.push(let_stmt(&format!("{prefix}_val"), val_local, vt, value)); + + // Push discriminant + flat_args.push(variant_tag(local_ref( + val_local, + &format!("{prefix}_val"), + vt, + ))); + + // Compute max flat payload count across all cases (the "join") + let cases = wasi_registry.get_variant_cases(&n.name).unwrap_or(&[]); + let max_flat_count: usize = cases + .iter() + .map(|c| { + c.payload + .as_ref() + .map(|t| flatten_param_type(t, wasi_registry).len()) + .unwrap_or(0) + }) + .max() + .unwrap_or(0); + + if max_flat_count > 0 { + // Allocate mutable locals for each payload flat slot, initialized to 0 + let mut payload_locals: Vec<(u32, TypeId)> = Vec::new(); + for i in 0..max_flat_count { + let local = alloc_local(next_local, local_types, TypeTable::I32); + stmts.push(let_mut_stmt( + &format!("{prefix}_p{i}"), + local, + TypeTable::I32, + i32_const(0), + )); + payload_locals.push((local, TypeTable::I32)); + } + + // For each case with a payload, generate conditional flattening + for (case_idx, case) in cases.iter().enumerate() { + if let Some(payload_ty) = &case.payload { + let payload_type_id = { + let mut tt = type_table.borrow_mut(); + wasi_type_to_type_id_with_registry( + payload_ty, + &mut tt, + Some(wasi_registry), + ) + }; + let payload_expr = variant_payload( + local_ref(val_local, &format!("{prefix}_val"), vt), + case_idx as u32, + payload_type_id, + ); + + let mut case_stmts = Vec::new(); + let mut case_flat = Vec::new(); + synthesize_flatten_value_to_flat_args( + payload_ty, + payload_expr, + &format!("{prefix}_c{case_idx}"), + next_local, + &mut case_stmts, + local_types, + &mut case_flat, + wasi_registry, + type_table, + ); + // Assign case flat values to shared payload locals + for (i, flat_val) in case_flat.into_iter().enumerate() { + if i < payload_locals.len() { + let (pl, pt) = payload_locals[i]; + case_stmts.push(expr_stmt(assign( + local_ref(pl, &format!("{prefix}_p{i}"), pt), + flat_val, + ))); + } + } + stmts.push(if_stmt( + variant_test( + local_ref(val_local, &format!("{prefix}_val"), vt), + case_idx as u32, + &case.wado_name, + ), + block(case_stmts), + None, + )); + } + } + + // Push all payload locals as flat args + for (i, (pl, pt)) in payload_locals.iter().enumerate() { + flat_args.push(local_ref(*pl, &format!("{prefix}_p{i}"), *pt)); + } + } + } + // Simple primitives / handles → pass through directly + _ => { + flat_args.push(value); + } + } +} + +/// Flatten an `Option` GC value to flat CM ABI args for sync function calls. +/// +/// Produces: [discriminant (0=None, 1=Some), ...flatten(T)] +/// The discriminant and payload locals are mutable, initialized to 0, +/// and populated conditionally when the option is `Some`. +fn synthesize_flatten_option_to_flat_args( + inner_type: &Type, + value: TirExpr, + prefix: &str, + next_local: &mut u32, + stmts: &mut Vec, + local_types: &mut Vec, + flat_args: &mut Vec, + wasi_registry: &crate::component_model::WasiRegistry, + type_table: &RefCell, +) { + let vt = value.type_id; + let val_local = alloc_local(next_local, local_types, vt); + stmts.push(let_stmt(&format!("{prefix}_optval"), val_local, vt, value)); + + // CM ABI option discriminant: 0 = None, 1 = Some. + // Use variant_test (ref.test) instead of variant_tag (struct.get) + // because variant_tag traps on null refs. + let disc_local = alloc_local(next_local, local_types, TypeTable::I32); + stmts.push(let_stmt( + &format!("{prefix}_disc"), + disc_local, + TypeTable::I32, + variant_test( + local_ref(val_local, &format!("{prefix}_optval"), vt), + 0, + "Some", + ), + )); + flat_args.push(local_ref( + disc_local, + &format!("{prefix}_disc"), + TypeTable::I32, + )); + + // Compute inner flat types + let inner_flat_types = flatten_param_type(inner_type, wasi_registry); + if inner_flat_types.is_empty() { + return; + } + + // Allocate mutable locals for inner flats, initialized to 0 + let mut inner_locals: Vec<(u32, TypeId)> = Vec::new(); + for (i, &ft) in inner_flat_types.iter().enumerate() { + let local = alloc_local(next_local, local_types, ft); + let zero = match ft { + TypeTable::I64 => i64_const(0), + _ => i32_const(0), + }; + stmts.push(let_mut_stmt(&format!("{prefix}_inner{i}"), local, ft, zero)); + inner_locals.push((local, ft)); + } + + // If Some: extract payload and flatten it + let inner_type_id = { + let mut tt = type_table.borrow_mut(); + wasi_type_to_type_id_with_registry(inner_type, &mut tt, Some(wasi_registry)) + }; + let payload_expr = variant_payload( + local_ref(val_local, &format!("{prefix}_optval"), vt), + 0, // case_index 0 = Some + inner_type_id, + ); + + let mut some_stmts = Vec::new(); + let mut some_flat = Vec::new(); + synthesize_flatten_value_to_flat_args( + inner_type, + payload_expr, + &format!("{prefix}_s"), + next_local, + &mut some_stmts, + local_types, + &mut some_flat, + wasi_registry, + type_table, + ); + // Assign flattened values to the mutable locals + for (i, flat_val) in some_flat.into_iter().enumerate() { + if i < inner_locals.len() { + let (il, it) = inner_locals[i]; + some_stmts.push(expr_stmt(assign( + local_ref(il, &format!("{prefix}_inner{i}"), it), + flat_val, + ))); + } + } + stmts.push(if_stmt( + variant_test( + local_ref(val_local, &format!("{prefix}_optval"), vt), + 0, + "Some", + ), + block(some_stmts), + None, + )); + + // Push inner locals as flat args + for (i, (il, it)) in inner_locals.iter().enumerate() { + flat_args.push(local_ref(*il, &format!("{prefix}_inner{i}"), *it)); + } +} + /// Lower a WASI type value to linear memory at the given address. fn synthesize_lower_wasi_type_to_memory( ty: &Type, @@ -2036,19 +2431,23 @@ fn synthesize_adapter( crate::cm_abi::cm_flat_types(rt).len() > MAX_FLAT_RESULTS || crate::component_model::wasi_named_type_return_needs_outptr(rt, wasi_registry) }); + let pkg = Some(func_info.package.as_str()); let outptr_alloc = if needs_outptr { func_info.return_type.as_ref().map(|rt| { // WASI variants need their registry-computed size/align, not the generic cm_size if let crate::ast::Type::Named(named) = rt - && let Some(sa) = - crate::component_model::wasi_variant_cm_size_align(&named.name, wasi_registry) + && let Some(sa) = crate::component_model::wasi_variant_cm_size_align_scoped( + &named.name, + wasi_registry, + pkg, + ) { return sa; } // Use registry-aware size/align for WASI structs and other complex types ( - crate::component_model::cm_size_with_registry(rt, wasi_registry), - crate::component_model::cm_align_with_registry(rt, wasi_registry), + crate::component_model::cm_size_with_registry_scoped(rt, wasi_registry, pkg), + crate::component_model::cm_align_with_registry_scoped(rt, wasi_registry, pkg), ) }) } else { @@ -2156,6 +2555,23 @@ fn synthesize_adapter( next_local += 1; param_mapping.push((start, 1)); } + // Option: single GC ref param (binding body lowers to discriminant + payload) + Type::Generic(g) if g.name == "Option" && g.args.len() == 1 => { + let option_type_id = { + let mut tt = type_table.borrow_mut(); + wasi_type_to_type_id_with_registry(param_type, &mut tt, Some(wasi_registry)) + }; + params.push(TirParam { + name: param_name.clone(), + type_id: option_type_id, + local_index: next_local, + is_mut: false, + span: synth_span(), + }); + local_types.push(option_type_id); + next_local += 1; + param_mapping.push((start, 1)); + } // All other types: create flat params matching CM ABI _ => { for (j, flat_ty) in flat_tys.iter().enumerate() { @@ -2479,12 +2895,47 @@ fn synthesize_adapter( }); } } - // Variant param: pass GC ref, lowered in Step 3 (indirect params) + // Variant param: for async, pass GC ref (lowered in Step 3 indirect params); + // for sync, flatten directly to flat i32 args. Type::Named(n) if wasi_registry.is_variant(&n.name) => { - let variant_type_id = params[start_idx].type_id; - flat_args.push(local_ref(param_local, param_name, variant_type_id)); + if func_info.is_async { + let variant_type_id = params[start_idx].type_id; + flat_args.push(local_ref(param_local, param_name, variant_type_id)); + } else { + synthesize_flatten_value_to_flat_args( + param_type, + local_ref(param_local, param_name, params[start_idx].type_id), + &format!("__{param_name}"), + &mut next_local, + &mut body_stmts, + &mut local_types, + &mut flat_args, + wasi_registry, + type_table, + ); + } } - // All other types (including Option): flat params passed through directly + // Option: for async, pass GC ref (lowered in Step 3 indirect params); + // for sync, flatten directly to flat args. + Type::Generic(g) if g.name == "Option" && g.args.len() == 1 => { + if func_info.is_async { + let option_type_id = params[start_idx].type_id; + flat_args.push(local_ref(param_local, param_name, option_type_id)); + } else { + synthesize_flatten_option_to_flat_args( + &g.args[0], + local_ref(param_local, param_name, params[start_idx].type_id), + &format!("__{param_name}"), + &mut next_local, + &mut body_stmts, + &mut local_types, + &mut flat_args, + wasi_registry, + type_table, + ); + } + } + // All other types: flat params passed through directly _ => { for j in 0..count { let p = ¶ms[start_idx + j]; @@ -2514,25 +2965,34 @@ fn synthesize_adapter( // Allocate the async results buffer via realloc (only when there are results). if has_results { - let (async_result_size, async_result_align) = if let Some(return_type) = - &func_info.return_type - { - if let crate::ast::Type::Named(named) = return_type - && let Some(sa) = crate::component_model::wasi_variant_cm_size_align( - &named.name, - wasi_registry, - ) - { - sa + let pkg = Some(func_info.package.as_str()); + let (async_result_size, async_result_align) = + if let Some(return_type) = &func_info.return_type { + if let crate::ast::Type::Named(named) = return_type + && let Some(sa) = crate::component_model::wasi_variant_cm_size_align_scoped( + &named.name, + wasi_registry, + pkg, + ) + { + sa + } else { + ( + crate::component_model::cm_size_with_registry_scoped( + return_type, + wasi_registry, + pkg, + ), + crate::component_model::cm_align_with_registry_scoped( + return_type, + wasi_registry, + pkg, + ), + ) + } } else { - ( - crate::component_model::cm_size_with_registry(return_type, wasi_registry), - crate::component_model::cm_align_with_registry(return_type, wasi_registry), - ) - } - } else { - unreachable!() - }; + unreachable!() + }; let async_outptr_local = next_local; body_stmts.push(let_stmt( "__async_outptr", @@ -2554,12 +3014,12 @@ fn synthesize_adapter( async_outptr_info = Some((async_outptr_local, async_result_size, async_result_align)); } - // Force indirect path when variant params are present (they need - // memory lowering, not direct flat passing). - let has_variant_params = func_info - .params - .iter() - .any(|(_, _, ty)| matches!(ty, Type::Named(n) if wasi_registry.is_variant(&n.name))); + // Force indirect path when variant or Option params are present + // (they need memory lowering, not direct flat passing). + let has_variant_params = func_info.params.iter().any(|(_, _, ty)| { + matches!(ty, Type::Named(n) if wasi_registry.is_variant(&n.name)) + || matches!(ty, Type::Generic(g) if g.name == "Option" && g.args.len() == 1) + }); if flat_args.len() > MAX_FLAT_ASYNC_PARAMS || has_variant_params { // Indirect calling: write all params to a memory buffer using CM layout. @@ -2632,6 +3092,33 @@ fn synthesize_adapter( ); continue; } + // Option: lower directly to the buffer + if let Type::Generic(g) = ty + && g.name == "Option" + && g.args.len() == 1 + { + let buf_addr = if base_offset == 0 { + local_ref(params_buf_local, "__params_buf", TypeTable::I32) + } else { + binary_add( + local_ref(params_buf_local, "__params_buf", TypeTable::I32), + i32_const(base_offset as i32), + ) + }; + let option_value = flat_args[flat_idx].clone(); + flat_idx += 1; + synthesize_lower_option_to_memory( + &g.args[0], + option_value, + buf_addr, + &mut next_local, + &mut body_stmts, + &mut local_types, + wasi_registry, + type_table, + ); + continue; + } let stores = cm_param_store_plan(ty, wasi_registry); for (sub_offset, store_name) in &stores { let offset = base_offset + sub_offset; @@ -6264,13 +6751,8 @@ fn parameterize_stream_cm_name(cm_name: &str, expr: &TirExpr, tt: &TypeTable) -> // Resolve through references: &Stream → Stream use crate::tir::ResolvedType; let mut type_id = receiver_type_id; - loop { - match tt.get(type_id) { - ResolvedType::Ref(inner) | ResolvedType::MutRef(inner) => { - type_id = *inner; - } - _ => break, - } + while let ResolvedType::Ref(inner) | ResolvedType::MutRef(inner) = tt.get(type_id) { + type_id = *inner; } // Extract element type from Stream if let Some(type_args) = tt.generic_type_args(type_id) @@ -6905,7 +7387,12 @@ fn fixup_expr_type(expr: &mut TirExpr, old_type: TypeId, new_type: TypeId) { /// For multi-flat types like `Option`, the Wado-level arg (e.g., `null`) /// is expanded into multiple i32 args (discriminant + payload). fn flatten_arg_for_call_site(arg: &TirExpr, flat_tys: &[TypeId], flat_args: &mut Vec) { - match &arg.kind { + // Unwrap Cast nodes transparently + let inner = match &arg.kind { + TirExprKind::Cast { expr, .. } => expr.as_ref(), + _ => arg, + }; + match &inner.kind { // null literal → discriminant=0, payload=0 for each flat type TirExprKind::Null => { for _ in flat_tys { @@ -6929,12 +7416,15 @@ fn flatten_arg_for_call_site(arg: &TirExpr, flat_tys: &[TypeId], flat_args: &mut .. } if case_name == "Some" => { flat_args.push(i32_const(1)); - // Multi-value inner: would need further flattening - // For now, handle the common single-value case - for j in 1..flat_tys.len() { - if j == 1 { - flat_args.push((**value).clone()); - } else { + let remaining = &flat_tys[1..]; + if remaining.len() == 1 { + // Single-value payload: pass through (e.g., enum discriminant) + flatten_arg_for_call_site(value, remaining, flat_args); + } else { + // Multi-value payload (e.g., String → ptr+len): pass through as-is + // The binding will lower it internally + flat_args.push((**value).clone()); + for _ in 2..flat_tys.len() { flat_args.push(i32_const(0)); } } @@ -6945,7 +7435,7 @@ fn flatten_arg_for_call_site(arg: &TirExpr, flat_tys: &[TypeId], flat_args: &mut panic!( "StaticCall adapter: cannot flatten arg of kind {:?} into {} flat types at call site; \ only null and VariantConstruct literals are supported", - arg.kind, + inner.kind, flat_tys.len() ); } @@ -7131,7 +7621,8 @@ fn rewrite_calls_in_expr( for (i, arg) in args.iter().enumerate() { if i < adapter.params.len() && adapter.params[i].type_id != arg.expr.type_id { let is_gc_passthrough = wasi_func.is_some_and(|f| { - i < f.params.len() && is_gc_passthrough_param(&f.params[i].2) + i < f.params.len() + && is_gc_passthrough_param(&f.params[i].2, wasi_registry) }); if is_streaming && adapter.params[i].type_id == TypeTable::I32 { // Streaming: keep adapter param as i32, cast the arg instead @@ -7272,7 +7763,10 @@ fn rewrite_calls_in_expr( let wasi_param_idx = i + 1; let is_gc_passthrough = method_func.is_some_and(|f| { wasi_param_idx < f.params.len() - && is_gc_passthrough_param(&f.params[wasi_param_idx].2) + && is_gc_passthrough_param( + &f.params[wasi_param_idx].2, + wasi_registry, + ) }); if is_streaming && adapter.params[param_idx].type_id == TypeTable::I32 { // Streaming: keep adapter param as i32, cast the arg instead @@ -7329,10 +7823,52 @@ fn rewrite_calls_in_expr( } } + // Flatten call site args to match the binding's flat CM params. + // For method calls, self is the first param; remaining args may need flattening. + let method_func = wasi_registry.get_function(&qualified); + let flat_taken_args = if let Some(func_info) = method_func { + let mut flat = Vec::new(); + for (i, arg) in taken_args.iter().enumerate() { + // WASI param index: i+1 to skip self + let wasi_param_idx = i + 1; + if wasi_param_idx >= func_info.params.len() { + flat.push(arg.expr.clone()); + continue; + } + let param_type = &func_info.params[wasi_param_idx].2; + let flat_tys = flatten_param_type(param_type, wasi_registry); + if flat_tys.is_empty() { + continue; + } + if is_gc_passthrough_param(param_type, wasi_registry) { + if matches!(arg.expr.kind, TirExprKind::Null) { + let option_type_id = { + let mut tt = type_table.borrow_mut(); + wasi_type_to_type_id_with_registry( + param_type, + &mut tt, + Some(wasi_registry), + ) + }; + flat.push(option_none(option_type_id)); + } else { + flat.push(arg.expr.clone()); + } + } else if flat_tys.len() == 1 { + flat.push(arg.expr.clone()); + } else { + flatten_arg_for_call_site(&arg.expr, &flat_tys, &mut flat); + } + } + flat + } else { + taken_args.into_iter().map(|a| a.expr).collect() + }; + // Replace MethodCall with Call targeting the binding // Prepend receiver to args let mut all_args = vec![taken_receiver]; - all_args.extend(taken_args.into_iter().map(|a| a.expr)); + all_args.extend(flat_taken_args); expr.kind = TirExprKind::Call { func: FunctionRef::from_resolved(&adapter_rc.borrow(), entry_source.clone()), @@ -7436,9 +7972,9 @@ fn rewrite_calls_in_expr( } // Flatten call site args to match the binding's flat CM params. - // Types that the binding lowers internally (String, Array) are - // passed through. Option and other multi-flat types are flattened - // here into individual i32 args. + // GC passthrough types (String, Array, Option) are passed + // through as GC refs — the binding body handles lowering. + // Other multi-flat types are flattened here into individual i32 args. let flat_call_args = if let Some(func_info) = &wasi_func_info { let mut flat = Vec::new(); for (i, (_param_name, _, param_type)) in func_info.params.iter().enumerate() { @@ -7446,23 +7982,29 @@ fn rewrite_calls_in_expr( if flat_tys.is_empty() || i >= taken_args.len() { continue; } - match param_type { - // String/Array: pass through (binding body lowers) - Type::Named(n) if n.name == "String" => { - flat.push(taken_args[i].clone()); - } - Type::Generic(g) if g.name == "Array" && g.args.len() == 1 => { - flat.push(taken_args[i].clone()); - } - _ => { - if flat_tys.len() == 1 { - // Single flat type: pass through - flat.push(taken_args[i].clone()); - } else { - // Multi-flat type: flatten at call site - flatten_arg_for_call_site(&taken_args[i], &flat_tys, &mut flat); - } + if is_gc_passthrough_param(param_type, wasi_registry) { + let arg = &taken_args[i]; + // Convert bare Null to VariantConstruct None. + // Use the binding's param type (from the WASI registry) + // to get a properly-resolved type_id, since the + // source null's type_id may have unknown inner type. + if matches!(arg.kind, TirExprKind::Null) { + let option_type_id = { + let mut tt = type_table.borrow_mut(); + wasi_type_to_type_id_with_registry( + param_type, + &mut tt, + Some(wasi_registry), + ) + }; + flat.push(option_none(option_type_id)); + } else { + flat.push(arg.clone()); } + } else if flat_tys.len() == 1 { + flat.push(taken_args[i].clone()); + } else { + flatten_arg_for_call_site(&taken_args[i], &flat_tys, &mut flat); } } flat diff --git a/wado-compiler/src/wir_build/translate.rs b/wado-compiler/src/wir_build/translate.rs index a4312cde1..09deca601 100644 --- a/wado-compiler/src/wir_build/translate.rs +++ b/wado-compiler/src/wir_build/translate.rs @@ -4642,7 +4642,7 @@ impl FunctionTranslator<'_, '_> { instrs.push(WirInstr::LocalSet { name: result_name.clone(), value: Box::new(WirInstr::Call { - func_id: future_read_id.clone(), + func_id: future_read_id, args: vec![ WirInstr::LocalGet { name: handle_name.clone(), @@ -4656,20 +4656,19 @@ impl FunctionTranslator<'_, '_> { }), }); - // canon future.read async returns: - // -1 (BLOCKED): future not ready, wait using the FUTURE handle - // (subtask_handle << 4) | status: - // status 0/1 = Starting/Started: async subtask in flight, wait using SUBTASK handle - // status 2 = Returned: sync completion, payload in buffer + // canon future.read returns pack_copy_result: + // 0xFFFF_FFFF (BLOCKED): future not ready, wait using the FUTURE handle + // (count << 4) | status: + // status 0 = COMPLETED: payload written to buffer → Some(lifted_value) + // status 1 = DROPPED: writer dropped → None + // status 2 = CANCELLED + // For futures, count is always 0, so COMPLETED = 0, DROPPED = 1. let ws_drop_id = self.ctx.ensure_canonical( CanonicalIntrinsic::WaitableSetDrop, vec![WirType::I32], vec![], ); - let subtask_drop_id = - self.ctx - .ensure_canonical(CanonicalIntrinsic::SubtaskDrop, vec![WirType::I32], vec![]); - // Case 1: BLOCKED (-1) → wait on future handle, then retry future-read + // Case 1: BLOCKED (0xFFFF_FFFF) → wait on future handle instrs.push(WirInstr::If { condition: Box::new(WirInstr::I32Eq( Box::new(WirInstr::LocalGet { @@ -4695,7 +4694,7 @@ impl FunctionTranslator<'_, '_> { WirInstr::LocalSet { name: ws_name.clone(), value: Box::new(WirInstr::Call { - func_id: ws_new_id.clone(), + func_id: ws_new_id, args: vec![], }), }, @@ -4728,7 +4727,7 @@ impl FunctionTranslator<'_, '_> { }, // waitable_set_wait(ws, evt_ptr) WirInstr::Drop(Box::new(WirInstr::Call { - func_id: ws_wait_id.clone(), + func_id: ws_wait_id, args: vec![ WirInstr::LocalGet { name: ws_name.clone(), @@ -4753,161 +4752,43 @@ impl FunctionTranslator<'_, '_> { WirInstr::I32Const(0), ], })), - // Drop waitable set - WirInstr::Call { - func_id: ws_drop_id.clone(), - args: vec![WirInstr::LocalGet { - name: ws_name, - result_ty: WirType::I32, - }], - }, - // Retry future-read now that future is ready - WirInstr::LocalSet { - name: result_name.clone(), - value: Box::new(WirInstr::Call { - func_id: future_read_id, - args: vec![ - WirInstr::LocalGet { - name: handle_name, - result_ty: WirType::I32, - }, - WirInstr::LocalGet { - name: ptr_name.clone(), - result_ty: WirType::I32, - }, - ], - }), - }, - ] - }, - else_body: None, - }); - - // Case 2: subtask in-flight (status 0 or 1) → wait on subtask, drop it, set result=2 - { - let subtask_name = format!("__fr_subtask_{suffix}"); - let ws_name2 = format!("__fr_ws2_{suffix}"); - let evt2 = format!("__fr_evtptr2_{suffix}"); - instrs.push(WirInstr::If { - condition: Box::new(WirInstr::I32Ne( - Box::new(WirInstr::I32And( - Box::new(WirInstr::LocalGet { - name: result_name.clone(), - result_ty: WirType::I32, - }), - Box::new(WirInstr::I32Const(0xF)), - )), - Box::new(WirInstr::I32Const(2)), - )), - result: None, - then_body: vec![ - WirInstr::DeclareLocal { - name: subtask_name.clone(), - ty: WirType::I32, - }, - WirInstr::DeclareLocal { - name: ws_name2.clone(), - ty: WirType::I32, - }, - WirInstr::DeclareLocal { - name: evt2.clone(), - ty: WirType::I32, - }, - WirInstr::LocalSet { - name: subtask_name.clone(), - value: Box::new(WirInstr::I32ShrU( - Box::new(WirInstr::LocalGet { - name: result_name.clone(), - result_ty: WirType::I32, - }), - Box::new(WirInstr::I32Const(4)), - )), - }, - WirInstr::LocalSet { - name: ws_name2.clone(), - value: Box::new(WirInstr::Call { - func_id: ws_new_id, - args: vec![], - }), - }, + // Unjoin future handle from waitable set before dropping it. + // waitable.join(handle, 0) removes the child relationship. WirInstr::Call { func_id: w_join_id, args: vec![ WirInstr::LocalGet { - name: subtask_name.clone(), - result_ty: WirType::I32, - }, - WirInstr::LocalGet { - name: ws_name2.clone(), - result_ty: WirType::I32, - }, - ], - }, - WirInstr::LocalSet { - name: evt2.clone(), - value: Box::new(WirInstr::Call { - func_id: realloc_id.clone(), - args: vec![ - WirInstr::I32Const(0), - WirInstr::I32Const(0), - WirInstr::I32Const(4), - WirInstr::I32Const(8), - ], - }), - }, - WirInstr::Drop(Box::new(WirInstr::Call { - func_id: ws_wait_id, - args: vec![ - WirInstr::LocalGet { - name: ws_name2.clone(), - result_ty: WirType::I32, - }, - WirInstr::LocalGet { - name: evt2.clone(), + name: handle_name, result_ty: WirType::I32, }, - ], - })), - WirInstr::Drop(Box::new(WirInstr::Call { - func_id: realloc_id.clone(), - args: vec![ - WirInstr::LocalGet { - name: evt2, - result_ty: WirType::I32, - }, - WirInstr::I32Const(8), - WirInstr::I32Const(4), WirInstr::I32Const(0), ], - })), - WirInstr::Call { - func_id: ws_drop_id, - args: vec![WirInstr::LocalGet { - name: ws_name2, - result_ty: WirType::I32, - }], }, + // Drop waitable set WirInstr::Call { - func_id: subtask_drop_id, + func_id: ws_drop_id, args: vec![WirInstr::LocalGet { - name: subtask_name, + name: ws_name, result_ty: WirType::I32, }], }, - // After subtask completes, payload is in buffer + // After wait completes, the data transfer is done and the + // future handle is consumed. Do NOT retry future-read; + // just mark the result as COMPLETED (0) so the payload + // lifter reads from the buffer. WirInstr::LocalSet { name: result_name.clone(), - value: Box::new(WirInstr::I32Const(2)), + value: Box::new(WirInstr::I32Const(0)), }, - ], - else_body: None, - }); - } + ] + }, + else_body: None, + }); - // canon future.read async returns (subtask_handle << 4) | status: - // status 2 = Returned → payload written to buffer → Some(lifted_value) - // After wait+retry, status should also be 2. - // Any other status → None (writer dropped without fulfilling) + // pack_copy_result status: + // status 0 = COMPLETED → payload written to buffer → Some(lifted_value) + // status 1 = DROPPED → writer dropped → None + // After BLOCKED wait, result is set to 0 (COMPLETED). let option_wir_type = self .ctx .type_id_to_wir_type(self.type_table, result_type_id); @@ -4925,7 +4806,7 @@ impl FunctionTranslator<'_, '_> { ty: option_wir_type.clone(), }); - // option_result = if (result & 0xF) == 2 { Some(lifted_value) } else { None } + // option_result = if (result & 0xF) == 0 { Some(lifted_value) } else { None } instrs.push(WirInstr::LocalSet { name: option_result_name.clone(), value: Box::new(WirInstr::If { @@ -4937,7 +4818,7 @@ impl FunctionTranslator<'_, '_> { }), Box::new(WirInstr::I32Const(0xF)), )), - Box::new(WirInstr::I32Const(2)), + Box::new(WirInstr::I32Const(0)), )), result: Some(option_wir_type.clone()), then_body: vec![some_variant], diff --git a/wado-compiler/tests/e2e.rs b/wado-compiler/tests/e2e.rs index d0770d1d9..7bd0026cf 100644 --- a/wado-compiler/tests/e2e.rs +++ b/wado-compiler/tests/e2e.rs @@ -425,9 +425,11 @@ async fn run_http_request_async( fn verify_http_result(result: &HttpTestResult, spec: &HttpServiceSpec, fixture_name: &str) { if let Some(expected_status) = spec.status { assert_eq!( - result.status, expected_status, - "[{fixture_name}] HTTP status mismatch: expected {expected_status}, got {}", - result.status + result.status, + expected_status, + "[{fixture_name}] HTTP status mismatch: expected {expected_status}, got {}; body: {}", + result.status, + String::from_utf8_lossy(&result.body), ); } diff --git a/wado-compiler/tests/fixtures.golden/cm-error-context.wir.wado b/wado-compiler/tests/fixtures.golden/cm-error-context.wir.wado index 07c576e38..e302530fa 100644 --- a/wado-compiler/tests/fixtures.golden/cm-error-context.wir.wado +++ b/wado-compiler/tests/fixtures.golden/cm-error-context.wir.wado @@ -206,6 +206,16 @@ struct Result::Err { payload_0: ref "wasi:http/types.wado/ErrorCode", } +variant Option> { + Some(i32), + None, +} + +struct Option>::Some { + discriminant: i32, + payload_0: i32, +} + type "functype/wasi/error-context-new" = fn(i32, i32) -> i32; type "functype/mem/realloc" = fn(i32, i32, i32, i32) -> i32; @@ -240,7 +250,7 @@ type "functype/wasi/waitable-join" = fn(i32, i32); type "functype/wasi/waitable-set-wait" = fn(i32, i32) -> i32; -type "functype/__cm_binding__Response_new" = fn(i32, i32, i32, i32) -> [i32, i32]; +type "functype/__cm_binding__Response_new" = fn(i32, ref Option>, i32) -> [i32, i32]; import fn error-context-new from "wasi/error-context-new"; import fn realloc from "mem/realloc"; @@ -404,7 +414,7 @@ fn handle(request) { headers = __cm_binding__Fields_new(); let __sroa___pattern_temp_1_0: i32; let __sroa___pattern_temp_1_1: i32; - multivalue_bind [__sroa___pattern_temp_1_0, __sroa___pattern_temp_1_1] = __cm_binding__Response_new(headers, 0, 0, trailers_future); + multivalue_bind [__sroa___pattern_temp_1_0, __sroa___pattern_temp_1_1] = __cm_binding__Response_new(headers, Option> { 1 }, trailers_future); response = __sroa___pattern_temp_1_0; __task_ret = Result::Ok { discriminant: 0, payload_0: response }; __tv_1 = 0; @@ -734,16 +744,23 @@ fn __cm_binding__Fields_new() { return "wasi/wasi:http/Fields::new"(); } -fn __cm_binding__Response_new(headers, contents_flat0, contents_flat1, trailers) { +fn __cm_binding__Response_new(headers, contents, trailers) { + let __contents_disc: i32; + let __contents_inner0: i32; let __outptr: i32; - let __lifted_result_5: i32; - let __lifted_result_6: i32; + let __lifted_result_7: i32; + let __lifted_result_8: i32; + __contents_disc = ref.test Option>::Some(contents); + __contents_inner0 = 0; + if ref.test Option>::Some(contents) { + __contents_inner0 = ref.cast Option>::Some(contents).payload_0; + }; __outptr = "mem/realloc"(0, 0, 4, 8); - "wasi/wasi:http/Response::new"(headers, contents_flat0, contents_flat1, trailers, __outptr); - __lifted_result_5 = builtin::load_i32(__outptr + 0); - __lifted_result_6 = builtin::load_i32(__outptr + 4); + "wasi/wasi:http/Response::new"(headers, __contents_disc, __contents_inner0, trailers, __outptr); + __lifted_result_7 = builtin::load_i32(__outptr + 0); + __lifted_result_8 = builtin::load_i32(__outptr + 4); drop("mem/realloc"(__outptr, 8, 4, 0)); - return __lifted_result_5; __lifted_result_6; + return __lifted_result_7; __lifted_result_8; } fn __cm_export__handle(request) { @@ -755,13 +772,13 @@ fn "core:internal/gc_array_to_memory"(arr, ptr, len) { // from core:internal __for_1: block { i = 0; block { - l40: loop { + l41: loop { if (i < len) == 0 { break __for_1; }; builtin::store_u8(ptr + i, builtin::array_get_u8(arr, i)); i = i + 1; - continue l40; + continue l41; }; }; }; diff --git a/wado-compiler/tests/fixtures.golden/cm-future-read-cli.wir.wado b/wado-compiler/tests/fixtures.golden/cm-future-read-cli.wir.wado new file mode 100644 index 000000000..c06fd04f5 --- /dev/null +++ b/wado-compiler/tests/fixtures.golden/cm-future-read-cli.wir.wado @@ -0,0 +1,507 @@ +// Golden file: WIR with -O2 optimization +// Source: wado-compiler/tests/fixtures/cm-future-read-cli.wado +// Generated by: mise run update-golden-fixtures + +array array (mut u8); + +struct String { + mut repr: ref array, + mut used: i32, +} + +struct Formatter { + mut fill: char, + mut align: i32, + mut sign_plus: bool, + mut zero_pad: bool, + mut width: i32, + mut precision: i32, + mut indent: i32, + mut buf: ref String, +} + +variant Option { + Some(i32), + None, +} + +struct Option::Some { + discriminant: i32, + payload_0: i32, +} + +enum Alignment { Left = 0, Center = 1, Right = 2 }; + +type "functype/mem/realloc" = fn(i32, i32, i32, i32) -> i32; + +type "functype/wasi/stream-write" = fn(i32, i32, i32) -> i32; + +type "functype/wasi/task-return" = fn(i32); + +type "functype/wasi/waitable-join" = fn(i32, i32); + +type "functype/wasi/waitable-set-drop" = fn(i32); + +type "functype/wasi/waitable-set-new" = fn() -> i32; + +type "functype/wasi/waitable-set-wait" = fn(i32, i32) -> i32; + +type "functype/wasi/wasi:cli/Stdout::write_via_stream" = fn(i32) -> i32; + +type "functype/run" = fn(); + +type "functype/__cm_binding__Stdout_write_via_stream" = fn(i32) -> i32; + +type "functype/__cm_export__run" = fn(); + +type "functype/core:cli/write_to_stream" = fn(i32, ref String, bool); + +type "functype/core:cli/println" = fn(ref String); + +type "functype/core:internal/gc_array_to_memory" = fn(ref array, i32, i32); + +type "functype/core:internal/cm_lower_list_u8" = fn(ref array, i32) -> i64; + +type "functype/core:internal/wait_for_blocked" = fn(i32) -> i32; + +type "functype/core:internal/cm_stream_write_raw_u8" = fn(i32, ref array, i32); + +type "functype/count_digits_i64" = fn(i64) -> i32; + +type "functype/write_decimal_digits" = fn(ref array, i32, i64, i32); + +type "functype/String::grow" = fn(ref String, i32); + +type "functype/String::internal_reserve_uninit" = fn(ref String, i32) -> i32; + +type "functype/String::push_str" = fn(ref String, ref String); + +type "functype/String::push" = fn(ref String, char); + +type "functype/Formatter::write_char_n" = fn(ref Formatter, char, i32); + +type "functype/Formatter::prepare_int_write" = fn(ref Formatter, bool, ref String, i32) -> i32; + +type "functype/wasi/future-new:s32" = fn() -> i64; + +type "functype/wasi/future-write:s32" = fn(i32, i32) -> i32; + +type "functype/wasi/future-read:s32" = fn(i32, i32) -> i32; + +type "functype/wasi/stream-drop-writable" = fn(i32); + +type "functype/wasi/stream-new" = fn() -> i64; + +type "functype/wasi/future-drop-readable:transmission-cli" = fn(i32); + +type "functype/i32::fmt_decimal" = fn(i32, ref Formatter); + +import fn realloc from "mem/realloc"; +import fn stream-write from "wasi/stream-write"; +import fn task-return from "wasi/task-return"; +import fn waitable-join from "wasi/waitable-join"; +import fn waitable-set-drop from "wasi/waitable-set-drop"; +import fn waitable-set-new from "wasi/waitable-set-new"; +import fn waitable-set-wait from "wasi/waitable-set-wait"; +import fn wasi:cli/Stdout::write_via_stream from "wasi/wasi:cli/Stdout::write_via_stream"; +import memory (1) from "mem/memory"; +import fn future-new:s32 from "wasi/future-new:s32"; +import fn future-write:s32 from "wasi/future-write:s32"; +import fn future-read:s32 from "wasi/future-read:s32"; +import fn stream-drop-writable from "wasi/stream-drop-writable"; +import fn stream-new from "wasi/stream-new"; +import fn future-drop-readable:transmission-cli from "wasi/future-drop-readable:transmission-cli"; + +fn run() with Stdout { + let future_rx: i32; + let future_tx: i32; + let result: ref Option; + let value: i32; + let __local_4: ref String; + let __local_5: ref Formatter; + let __pair_temp_1: i64; + __pair_temp_1 = "wasi/future-new:s32"(); + future_rx = builtin::i32_wrap_i64(__pair_temp_1); + future_tx = builtin::i32_wrap_i64(__pair_temp_1 >>u 32_i64); + let __fw_write_ptr_2: i32; + __fw_write_ptr_2 = "mem/realloc"(0, 0, 4, 4); + builtin::store_i32(__fw_write_ptr_2, 42); + drop("wasi/future-write:s32"(future_tx, __fw_write_ptr_2)); + let __fr_handle_3: i32; + let __fr_ptr_3: i32; + let __fr_result_3: i32; + __fr_handle_3 = future_rx; + __fr_ptr_3 = "mem/realloc"(0, 0, 8, 40); + __fr_result_3 = "wasi/future-read:s32"(__fr_handle_3, __fr_ptr_3); + if __fr_result_3 == -1 { + let __fr_ws_3: i32; + let __fr_evtptr_3: i32; + __fr_ws_3 = "wasi/waitable-set-new"(); + "wasi/waitable-join"(__fr_handle_3, __fr_ws_3); + __fr_evtptr_3 = "mem/realloc"(0, 0, 4, 8); + drop("wasi/waitable-set-wait"(__fr_ws_3, __fr_evtptr_3)); + drop("mem/realloc"(__fr_evtptr_3, 8, 4, 0)); + "wasi/waitable-join"(__fr_handle_3, 0); + "wasi/waitable-set-drop"(__fr_ws_3); + __fr_result_3 = 0; + }; + let __fr_opt_4: ref Option; + __fr_opt_4 = if (__fr_result_3 & 15) == 0 -> ref Option { + Option::Some { discriminant: 0, payload_0: builtin::load_i32(__fr_ptr_3) }; + } else { + Option { 1 }; + }; + drop("mem/realloc"(__fr_ptr_3, 40, 8, 0)); + result = __fr_opt_4; + if ref.test Option::Some(result) { + value = ref.cast Option::Some(result).payload_0; + "core:cli/println"(__tmpl: block -> ref String { + __local_4 = String { repr: builtin::array_new(16), used: 0 }; + __local_5 = Formatter { fill: 32, align: 2, sign_plus: 0, zero_pad: 0, width: -1, precision: -1, indent: 0, buf: __local_4 }; + i32::fmt_decimal(value, __local_5); + break __tmpl: __local_4; + }); + } else { + "core:cli/println"(String { repr: array.new_data("none"), used: 4 }); + }; +} + +fn __cm_binding__Stdout_write_via_stream(data) { + return "wasi/wasi:cli/Stdout::write_via_stream"(data); +} + +fn __cm_export__run() { + run(); + "wasi/task-return"(0); +} + +fn "core:cli/write_to_stream"(tx, message, add_newline) { // from core:cli + let bytes: ref array; + let len: i32; + let new_repr: ref array; + bytes = message.repr; + len = message.used; + if add_newline { + new_repr = builtin::array_new(len + 1); + builtin::array_copy(new_repr, 0, bytes, 0, len); + builtin::array_set_u8(new_repr, len, 10); + "core:internal/cm_stream_write_raw_u8"(tx, new_repr, len + 1); + } else { + "core:internal/cm_stream_write_raw_u8"(tx, bytes, len); + }; + "wasi/stream-drop-writable"(tx); +} + +fn "core:cli/println"(message) with Stdout { // from core:cli + let rx: i32; + let tx: i32; + let handle: i32; + let future: i32; + let __pair_temp_1: i64; + __pair_temp_1 = "wasi/stream-new"(); + rx = builtin::i32_wrap_i64(__pair_temp_1); + tx = builtin::i32_wrap_i64(__pair_temp_1 >>u 32_i64); + handle = __cm_binding__Stdout_write_via_stream(rx); + "core:cli/write_to_stream"(tx, message, 1); + future = handle; + "wasi/future-drop-readable:transmission-cli"(future); +} + +fn "core:internal/gc_array_to_memory"(arr, ptr, len) { // from core:internal + let i: i32; + __for_1: block { + i = 0; + block { + l5: loop { + if (i < len) == 0 { + break __for_1; + }; + builtin::store_u8(ptr + i, builtin::array_get_u8(arr, i)); + i = i + 1; + continue l5; + }; + }; + }; +} + +fn "core:internal/cm_lower_list_u8"(data, len) { // from core:internal + let ptr: i32; + ptr = "mem/realloc"(0, 0, 1, len); + "core:internal/gc_array_to_memory"(data, ptr, len); + return builtin::i64_extend_i32_s(ptr) | (builtin::i64_extend_i32_s(len) << 32_i64); +} + +fn "core:internal/wait_for_blocked"(handle) { // from core:internal + let ws: i32; + let evt_ptr: i32; + let payload: i32; + ws = "wasi/waitable-set-new"(); + "wasi/waitable-join"(handle, ws); + evt_ptr = "mem/realloc"(0, 0, 4, 8); + drop("wasi/waitable-set-wait"(ws, evt_ptr)); + payload = builtin::load_i32(evt_ptr + 4); + drop("mem/realloc"(evt_ptr, 8, 4, 0)); + "wasi/waitable-set-drop"(ws); + return payload; +} + +fn "core:internal/cm_stream_write_raw_u8"(handle, data, len) { // from core:internal + let packed: i64; + let ptr: i32; + let raw_len: i32; + let result: i32; + packed = "core:internal/cm_lower_list_u8"(data, len); + ptr = builtin::i32_wrap_i64(packed); + raw_len = builtin::i32_wrap_i64(packed >> 32_i64); + result = "wasi/stream-write"(handle, ptr, raw_len); + if result == -1 { + drop("core:internal/wait_for_blocked"(handle)); + }; + drop("mem/realloc"(ptr, raw_len, 1, 0)); +} + +fn count_digits_i64(val) { + let n: i32; + let t: i64; + if val == 0_i64 { + return 1; + }; + n = 0; + __for_1: block { + t = val; + block { + l10: loop { + if (t > 0_i64) == 0 { + break __for_1; + }; + n = n + 1; + t = t / 10_i64; + continue l10; + }; + }; + }; + return n; +} + +fn write_decimal_digits(arr, offset, abs_val, digit_count) { + let pos: i32; + let temp: i64; + pos = offset + digit_count; + if abs_val == 0_i64 { + builtin::array_set_u8(arr, offset, 48); + } else { + __for_2: block { + temp = abs_val; + block { + l14: loop { + if (temp > 0_i64) == 0 { + break __for_2; + }; + pos = pos - 1; + builtin::array_set_u8(arr, pos, (48 + builtin::i32_wrap_i64(temp % 10_i64)) & 255); + temp = temp / 10_i64; + continue l14; + }; + }; + }; + }; +} + +fn i32::fmt_decimal(self, f) { + let is_negative: bool; + let abs_val: i64; + let digit_count: i32; + let offset: i32; + let __local_6: ref String; + is_negative = self < 0; + abs_val = if is_negative -> i64 { + 0_i64 - builtin::i64_extend_i32_s(self); + } else { + builtin::i64_extend_i32_s(self); + }; + digit_count = count_digits_i64(abs_val); + offset = Formatter::prepare_int_write(f, is_negative, String { repr: builtin::array_new(0), used: 0 }, digit_count); + write_decimal_digits(__inline_String__internal_raw_bytes_0: block -> ref array { + __local_6 = f.buf; + break __inline_String__internal_raw_bytes_0: __local_6.repr; + }, offset, abs_val, digit_count); +} + +fn String::grow(self, min_capacity) { + let capacity: i32; + let new_capacity: i32; + let new_repr: ref array; + let __local_5: i32; + let __local_7: i32; + capacity = builtin::array_len(self.repr); + if min_capacity <= capacity { + return; + }; + new_capacity = __inline_i32_max_0: block -> i32 { + __local_5 = __inline_i32_max_1: block -> i32 { + __local_7 = capacity * 2; + break __inline_i32_max_1: select i32(__local_7 > min_capacity, __local_7, min_capacity); + }; + break __inline_i32_max_0: select i32(__local_5 > 8, __local_5, 8); + }; + new_repr = builtin::array_new(new_capacity); + builtin::array_copy(new_repr, 0, self.repr, 0, self.used); + self.repr = new_repr; +} + +fn String::internal_reserve_uninit(self, n) { + let new_used: i32; + let start: i32; + new_used = self.used + n; + if builtin::unlikely(new_used > builtin::array_len(self.repr)) { + String::grow(self, new_used); + }; + start = self.used; + self.used = new_used; + return start; +} + +fn String::push_str(self, other) { + let other_len: i32; + let new_used: i32; + other_len = other.used; + if other_len == 0 { + return; + }; + new_used = self.used + other_len; + if builtin::unlikely(new_used > builtin::array_len(self.repr)) { + String::grow(self, new_used); + }; + builtin::array_copy(self.repr, self.used, other.repr, 0, other_len); + self.used = new_used; +} + +fn String::push(self, c) { + let code: u32; + code = c; + if builtin::unlikely((self.used + 4) > builtin::array_len(self.repr)) { + String::grow(self, self.used + 4); + }; + if code >u 6)) & 255); + builtin::array_set_u8(self.repr, self.used + 1, (128 | (code & 63)) & 255); + self.used = self.used + 2; + } else if code >u 12)) & 255); + builtin::array_set_u8(self.repr, self.used + 1, (128 | ((code >>u 6) & 63)) & 255); + builtin::array_set_u8(self.repr, self.used + 2, (128 | (code & 63)) & 255); + self.used = self.used + 3; + } else { + builtin::array_set_u8(self.repr, self.used, (240 | (code >>u 18)) & 255); + builtin::array_set_u8(self.repr, self.used + 1, (128 | ((code >>u 12) & 63)) & 255); + builtin::array_set_u8(self.repr, self.used + 2, (128 | ((code >>u 6) & 63)) & 255); + builtin::array_set_u8(self.repr, self.used + 3, (128 | (code & 63)) & 255); + self.used = self.used + 4; + }; +} + +fn Formatter::write_char_n(self, c, n) { + let i: i32; + let _licm_buf_4: ref String; + __for_0: block { + i = 0; + _licm_buf_4 = self.buf; + block { + l26: loop { + if (i < n) == 0 { + break __for_0; + }; + String::push(_licm_buf_4, c); + i = i + 1; + continue l26; + }; + }; + }; +} + +fn Formatter::prepare_int_write(self, is_negative, prefix, digit_count) { + let sign: ref String; + let sign_len: i32; + let prefix_len: i32; + let content_len: i32; + let padding: i32; + let align: enum:Alignment; + let offset_10: i32; + let left_pad: i32; + let right_pad: i32; + let offset_13: i32; + sign = String { repr: builtin::array_new(0), used: 0 }; + if is_negative { + sign = String { repr: array.new_data("-"), used: 1 }; + } else if self.sign_plus { + sign = String { repr: array.new_data("+"), used: 1 }; + }; + sign_len = sign.used; + prefix_len = prefix.used; + content_len = (sign_len + prefix_len) + digit_count; + if if self.width <= 0 -> i32 { + 1; + } else { + content_len >= self.width; + } { + if sign_len > 0 { + String::push_str(self.buf, sign); + }; + if prefix_len > 0 { + String::push_str(self.buf, prefix); + }; + return String::internal_reserve_uninit(self.buf, digit_count); + }; + padding = self.width - content_len; + if self.zero_pad { + if sign_len > 0 { + String::push_str(self.buf, sign); + }; + if prefix_len > 0 { + String::push_str(self.buf, prefix); + }; + Formatter::write_char_n(self, 48, padding); + return String::internal_reserve_uninit(self.buf, digit_count); + }; + align = self.align; + let __match_scrut_0: enum:Alignment; + __match_scrut_0 = align; + if __match_scrut_0 == 0 { + if sign_len > 0 { + String::push_str(self.buf, sign); + }; + if prefix_len > 0 { + String::push_str(self.buf, prefix); + }; + offset_10 = String::internal_reserve_uninit(self.buf, digit_count); + Formatter::write_char_n(self, self.fill, padding); + return offset_10; + } else if align == 1 { + left_pad = padding / 2; + right_pad = padding - left_pad; + Formatter::write_char_n(self, self.fill, left_pad); + if sign_len > 0 { + String::push_str(self.buf, sign); + }; + if prefix_len > 0 { + String::push_str(self.buf, prefix); + }; + offset_13 = String::internal_reserve_uninit(self.buf, digit_count); + Formatter::write_char_n(self, self.fill, right_pad); + return offset_13; + } else { + Formatter::write_char_n(self, self.fill, padding); + if sign_len > 0 { + String::push_str(self.buf, sign); + }; + if prefix_len > 0 { + String::push_str(self.buf, prefix); + }; + return String::internal_reserve_uninit(self.buf, digit_count); + }; +} + +export fn __cm_export__run as "run" diff --git a/wado-compiler/tests/fixtures.golden/cm-future-read.wir.wado b/wado-compiler/tests/fixtures.golden/cm-future-read.wir.wado new file mode 100644 index 000000000..ebf6695bd --- /dev/null +++ b/wado-compiler/tests/fixtures.golden/cm-future-read.wir.wado @@ -0,0 +1,828 @@ +// Golden file: WIR with -O2 optimization +// Source: wado-compiler/tests/fixtures/cm-future-read.wado +// Generated by: mise run update-golden-fixtures + +array array (mut u8); + +struct String { + mut repr: ref array, + mut used: i32, +} + +struct FieldSizePayload { // from wasi:http/types.wado + mut field_name: ref null String, + mut field_size: ref Option, +} + +struct TlsAlertReceivedPayload { // from wasi:http/types.wado + mut alert_id: ref Option, + mut alert_message: ref null String, +} + +struct DnsErrorPayload { // from wasi:http/types.wado + mut rcode: ref null String, + mut info_code: ref Option, +} + +variant ErrorCode { // from wasi:http/types.wado + DnsTimeout, + DnsError(ref "wasi:http/types.wado/DnsErrorPayload"), + DestinationNotFound, + DestinationUnavailable, + DestinationIpProhibited, + DestinationIpUnroutable, + ConnectionRefused, + ConnectionTerminated, + ConnectionTimeout, + ConnectionReadTimeout, + ConnectionWriteTimeout, + ConnectionLimitReached, + TlsProtocolError, + TlsCertificateError, + TlsAlertReceived(ref "wasi:http/types.wado/TlsAlertReceivedPayload"), + HttpRequestDenied, + HttpRequestLengthRequired, + HttpRequestBodySize(ref Option), + HttpRequestMethodInvalid, + HttpRequestUriInvalid, + HttpRequestUriTooLong, + HttpRequestHeaderSectionSize(ref Option), + HttpRequestHeaderSize(ref null "wasi:http/types.wado/FieldSizePayload"), + HttpRequestTrailerSectionSize(ref Option), + HttpRequestTrailerSize(ref "wasi:http/types.wado/FieldSizePayload"), + HttpResponseIncomplete, + HttpResponseHeaderSectionSize(ref Option), + HttpResponseHeaderSize(ref "wasi:http/types.wado/FieldSizePayload"), + HttpResponseBodySize(ref Option), + HttpResponseTrailerSectionSize(ref Option), + HttpResponseTrailerSize(ref "wasi:http/types.wado/FieldSizePayload"), + HttpResponseTransferCoding(ref null String), + HttpResponseContentCoding(ref null String), + HttpResponseTimeout, + HttpUpgradeFailed, + HttpProtocolError, + LoopDetected, + ConfigurationError, + InternalError(ref null String), +} + +struct ErrorCode::DnsError { + discriminant: i32, + payload_0: ref "wasi:http/types.wado/DnsErrorPayload", +} + +struct ErrorCode::TlsAlertReceived { + discriminant: i32, + payload_0: ref "wasi:http/types.wado/TlsAlertReceivedPayload", +} + +struct ErrorCode::HttpRequestBodySize { + discriminant: i32, + payload_0: ref Option, +} + +struct ErrorCode::HttpRequestHeaderSectionSize { + discriminant: i32, + payload_0: ref Option, +} + +struct ErrorCode::HttpRequestHeaderSize { + discriminant: i32, + payload_0: ref null "wasi:http/types.wado/FieldSizePayload", +} + +struct ErrorCode::HttpRequestTrailerSectionSize { + discriminant: i32, + payload_0: ref Option, +} + +struct ErrorCode::HttpRequestTrailerSize { + discriminant: i32, + payload_0: ref "wasi:http/types.wado/FieldSizePayload", +} + +struct ErrorCode::HttpResponseHeaderSectionSize { + discriminant: i32, + payload_0: ref Option, +} + +struct ErrorCode::HttpResponseHeaderSize { + discriminant: i32, + payload_0: ref "wasi:http/types.wado/FieldSizePayload", +} + +struct ErrorCode::HttpResponseBodySize { + discriminant: i32, + payload_0: ref Option, +} + +struct ErrorCode::HttpResponseTrailerSectionSize { + discriminant: i32, + payload_0: ref Option, +} + +struct ErrorCode::HttpResponseTrailerSize { + discriminant: i32, + payload_0: ref "wasi:http/types.wado/FieldSizePayload", +} + +struct ErrorCode::HttpResponseTransferCoding { + discriminant: i32, + payload_0: ref null String, +} + +struct ErrorCode::HttpResponseContentCoding { + discriminant: i32, + payload_0: ref null String, +} + +struct ErrorCode::InternalError { + discriminant: i32, + payload_0: ref null String, +} + +variant Option { + Some(ref String), + None, +} + +variant Option { + Some(u16), + None, +} + +struct Option::Some { + discriminant: i32, + payload_0: u16, +} + +variant Option { + Some(u8), + None, +} + +struct Option::Some { + discriminant: i32, + payload_0: u8, +} + +variant Option { + Some(u32), + None, +} + +struct Option::Some { + discriminant: i32, + payload_0: u32, +} + +variant Option { + Some(u64), + None, +} + +struct Option::Some { + discriminant: i32, + payload_0: u64, +} + +variant Option { + Some(ref "wasi:http/types.wado/FieldSizePayload"), + None, +} + +variant Result { + Ok(i32), + Err(ref "wasi:http/types.wado/ErrorCode"), +} + +struct Result::Ok { + discriminant: i32, + payload_0: i32, +} + +struct Result::Err { + discriminant: i32, + payload_0: ref "wasi:http/types.wado/ErrorCode", +} + +variant Option> { + Some(i32), + None, +} + +struct Option>::Some { + discriminant: i32, + payload_0: i32, +} + +type "functype/mem/realloc" = fn(i32, i32, i32, i32) -> i32; + +type "functype/wasi/task-return" = fn(i32, i32, i32, i64, i32, i32, i32, i32); + +type "functype/wasi/wasi:http/Fields::new" = fn() -> i32; + +type "functype/wasi/wasi:http/Response::new" = fn(i32, i32, i32, i32, i32); + +type "functype/handle" = fn(i32); + +type "functype/__cm_binding__Fields_new" = fn() -> i32; + +type "functype/__cm_export__handle" = fn(i32); + +type "functype/core:internal/gc_array_to_memory" = fn(ref array, i32, i32); + +type "functype/core:internal/cm_lower_string" = fn(ref String) -> i64; + +type "functype/wasi/future-new:s32" = fn() -> i64; + +type "functype/wasi/future-write:s32" = fn(i32, i32) -> i32; + +type "functype/wasi/future-read:s32" = fn(i32, i32) -> i32; + +type "functype/wasi/waitable-set-new" = fn() -> i32; + +type "functype/wasi/waitable-join" = fn(i32, i32); + +type "functype/wasi/waitable-set-wait" = fn(i32, i32) -> i32; + +type "functype/wasi/waitable-set-drop" = fn(i32); + +type "functype/wasi/future-new" = fn() -> i64; + +type "functype/wasi/future-write" = fn(i32, i32) -> i32; + +type "functype/__cm_binding__Response_new" = fn(i32, ref Option>, i32) -> [i32, i32]; + +import fn realloc from "mem/realloc"; +import fn task-return from "wasi/task-return"; +import fn wasi:http/Fields::new from "wasi/wasi:http/Fields::new"; +import fn wasi:http/Response::new from "wasi/wasi:http/Response::new"; +import memory (1) from "mem/memory"; +import fn future-new:s32 from "wasi/future-new:s32"; +import fn future-write:s32 from "wasi/future-write:s32"; +import fn future-read:s32 from "wasi/future-read:s32"; +import fn waitable-set-new from "wasi/waitable-set-new"; +import fn waitable-join from "wasi/waitable-join"; +import fn waitable-set-wait from "wasi/waitable-set-wait"; +import fn waitable-set-drop from "wasi/waitable-set-drop"; +import fn future-new from "wasi/future-new"; +import fn future-write from "wasi/future-write"; + +fn handle(request) { + let future_rx: i32; + let future_tx: i32; + let trailers_future: i32; + let trailers_tx: i32; + let headers: i32; + let response: i32; + let __task_ret: ref Result; + let __tv_1: i32; + let __tv_2: i32; + let __tv_3: i64; + let __tv_4: i32; + let __tv_5: i32; + let __tv_6: i32; + let __tv_7: i32; + let __ok_val: i32; + let __err_val: ref "wasi:http/types.wado/ErrorCode"; + let __case_payload_21: ref "wasi:http/types.wado/DnsErrorPayload"; + let __opt_val_23: ref null String; + let __opt_disc_24: i32; + let __opt_inner_0_25: i32; + let __opt_inner_1_26: i32; + let __packed_27: i64; + let __ptr_28: i32; + let __len_29: i32; + let __opt_val_30: ref Option; + let __opt_disc_31: i32; + let __opt_inner_0_32: i32; + let __flat_33: i32; + let __case_payload_34: ref "wasi:http/types.wado/TlsAlertReceivedPayload"; + let __opt_val_36: ref Option; + let __opt_disc_37: i32; + let __opt_inner_0_38: i32; + let __flat_39: i32; + let __opt_val_40: ref null String; + let __opt_disc_41: i32; + let __opt_inner_0_42: i32; + let __opt_inner_1_43: i32; + let __packed_44: i64; + let __ptr_45: i32; + let __len_46: i32; + let __case_payload_47: ref Option; + let __opt_disc_49: i32; + let __opt_inner_0_50: i64; + let __flat_51: i64; + let __case_payload_52: ref Option; + let __opt_disc_54: i32; + let __opt_inner_0_55: i32; + let __flat_56: i32; + let __case_payload_57: ref null "wasi:http/types.wado/FieldSizePayload"; + let __opt_disc_59: i32; + let __opt_inner_0_60: i32; + let __opt_inner_1_61: i32; + let __opt_inner_2: i32; + let __opt_inner_3: i32; + let __opt_inner_4: i32; + let __struct_val: ref "wasi:http/types.wado/FieldSizePayload"; + let __opt_val_66: ref null String; + let __opt_disc_67: i32; + let __opt_inner_0_68: i32; + let __opt_inner_1_69: i32; + let __packed_70: i64; + let __ptr_71: i32; + let __len_72: i32; + let __opt_val_73: ref Option; + let __opt_disc_74: i32; + let __opt_inner_0_75: i32; + let __flat_76: i32; + let __case_payload_77: ref Option; + let __opt_disc_79: i32; + let __opt_inner_0_80: i32; + let __flat_81: i32; + let __case_payload_82: ref "wasi:http/types.wado/FieldSizePayload"; + let __opt_val_84: ref null String; + let __opt_disc_85: i32; + let __opt_inner_0_86: i32; + let __opt_inner_1_87: i32; + let __packed_88: i64; + let __ptr_89: i32; + let __len_90: i32; + let __opt_val_91: ref Option; + let __opt_disc_92: i32; + let __opt_inner_0_93: i32; + let __flat_94: i32; + let __case_payload_95: ref Option; + let __opt_disc_97: i32; + let __opt_inner_0_98: i32; + let __flat_99: i32; + let __case_payload_100: ref "wasi:http/types.wado/FieldSizePayload"; + let __opt_val_102: ref null String; + let __opt_disc_103: i32; + let __opt_inner_0_104: i32; + let __opt_inner_1_105: i32; + let __packed_106: i64; + let __ptr_107: i32; + let __len_108: i32; + let __opt_val_109: ref Option; + let __opt_disc_110: i32; + let __opt_inner_0_111: i32; + let __flat_112: i32; + let __case_payload_113: ref Option; + let __opt_disc_115: i32; + let __opt_inner_0_116: i64; + let __flat_117: i64; + let __case_payload_118: ref Option; + let __opt_disc_120: i32; + let __opt_inner_0_121: i32; + let __flat_122: i32; + let __case_payload_123: ref "wasi:http/types.wado/FieldSizePayload"; + let __opt_val_125: ref null String; + let __opt_disc_126: i32; + let __opt_inner_0_127: i32; + let __opt_inner_1_128: i32; + let __packed_129: i64; + let __ptr_130: i32; + let __len_131: i32; + let __opt_val_132: ref Option; + let __opt_disc_133: i32; + let __opt_inner_0_134: i32; + let __flat_135: i32; + let __case_payload_136: ref null String; + let __opt_disc_138: i32; + let __opt_inner_0_139: i32; + let __opt_inner_1_140: i32; + let __packed_141: i64; + let __ptr_142: i32; + let __len_143: i32; + let __case_payload_144: ref null String; + let __opt_disc_146: i32; + let __opt_inner_0_147: i32; + let __opt_inner_1_148: i32; + let __packed_149: i64; + let __ptr_150: i32; + let __len_151: i32; + let __case_payload_152: ref null String; + let __opt_disc_154: i32; + let __opt_inner_0_155: i32; + let __opt_inner_1_156: i32; + let __packed_157: i64; + let __ptr_158: i32; + let __len_159: i32; + let __pair_temp_1: i64; + __pair_temp_1 = "wasi/future-new:s32"(); + future_rx = builtin::i32_wrap_i64(__pair_temp_1); + future_tx = builtin::i32_wrap_i64(__pair_temp_1 >>u 32_i64); + let __fw_write_ptr_2: i32; + __fw_write_ptr_2 = "mem/realloc"(0, 0, 4, 4); + builtin::store_i32(__fw_write_ptr_2, 42); + drop("wasi/future-write:s32"(future_tx, __fw_write_ptr_2)); + let __fr_handle_3: i32; + let __fr_ptr_3: i32; + let __fr_result_3: i32; + __fr_handle_3 = future_rx; + __fr_ptr_3 = "mem/realloc"(0, 0, 8, 40); + __fr_result_3 = "wasi/future-read:s32"(__fr_handle_3, __fr_ptr_3); + if __fr_result_3 == -1 { + let __fr_ws_3: i32; + let __fr_evtptr_3: i32; + __fr_ws_3 = "wasi/waitable-set-new"(); + "wasi/waitable-join"(__fr_handle_3, __fr_ws_3); + __fr_evtptr_3 = "mem/realloc"(0, 0, 4, 8); + drop("wasi/waitable-set-wait"(__fr_ws_3, __fr_evtptr_3)); + drop("mem/realloc"(__fr_evtptr_3, 8, 4, 0)); + "wasi/waitable-join"(__fr_handle_3, 0); + "wasi/waitable-set-drop"(__fr_ws_3); + __fr_result_3 = 0; + }; + drop("mem/realloc"(__fr_ptr_3, 40, 8, 0)); + let __pair_temp_5: i64; + __pair_temp_5 = "wasi/future-new"(); + trailers_future = builtin::i32_wrap_i64(__pair_temp_5); + trailers_tx = builtin::i32_wrap_i64(__pair_temp_5 >>u 32_i64); + headers = __cm_binding__Fields_new(); + let __sroa___pattern_temp_2_0: i32; + let __sroa___pattern_temp_2_1: i32; + multivalue_bind [__sroa___pattern_temp_2_0, __sroa___pattern_temp_2_1] = __cm_binding__Response_new(headers, Option> { 1 }, trailers_future); + response = __sroa___pattern_temp_2_0; + __task_ret = Result::Ok { discriminant: 0, payload_0: response }; + __tv_1 = 0; + __tv_2 = 0; + __tv_3 = 0_i64; + __tv_4 = 0; + __tv_5 = 0; + __tv_6 = 0; + __tv_7 = 0; + if ref.test Result::Ok(__task_ret) { + __ok_val = ref.cast Result::Ok(__task_ret).payload_0; + __tv_1 = __ok_val; + "wasi/task-return"(0, __tv_1, 0, 0_i64, 0, 0, 0, 0); + } else { + __err_val = ref.cast Result::Err(__task_ret).payload_0; + __tv_1 = __err_val.discriminant; + if ref.test "wasi:http/types.wado/ErrorCode::DnsError"(__err_val) { + __case_payload_21 = ref.cast "wasi:http/types.wado/ErrorCode::DnsError"(__err_val).payload_0; + __opt_val_23 = __case_payload_21.rcode; + __opt_disc_24 = ref.is_null(__opt_val_23) == 0; + __opt_inner_0_25 = 0; + __opt_inner_1_26 = 0; + if __opt_disc_24 != 0 { + __packed_27 = "core:internal/cm_lower_string"(ref.as_non_null(__opt_val_23)); + __ptr_28 = builtin::i32_wrap_i64(__packed_27); + __len_29 = builtin::i32_wrap_i64(__packed_27 >> 32_i64); + __opt_inner_0_25 = __ptr_28; + __opt_inner_1_26 = __len_29; + }; + __opt_val_30 = __case_payload_21.info_code; + __opt_disc_31 = ref.test Option::Some(__opt_val_30); + __opt_inner_0_32 = 0; + if __opt_disc_31 != 0 { + __flat_33 = ref.cast Option::Some(__opt_val_30).payload_0; + __opt_inner_0_32 = __flat_33; + }; + __tv_2 = __opt_disc_24; + __tv_3 = builtin::i64_extend_i32_s(__opt_inner_0_25); + __tv_4 = __opt_inner_1_26; + __tv_5 = __opt_disc_31; + __tv_6 = __opt_inner_0_32; + }; + if ref.test "wasi:http/types.wado/ErrorCode::TlsAlertReceived"(__err_val) { + __case_payload_34 = ref.cast "wasi:http/types.wado/ErrorCode::TlsAlertReceived"(__err_val).payload_0; + __opt_val_36 = __case_payload_34.alert_id; + __opt_disc_37 = ref.test Option::Some(__opt_val_36); + __opt_inner_0_38 = 0; + if __opt_disc_37 != 0 { + __flat_39 = ref.cast Option::Some(__opt_val_36).payload_0; + __opt_inner_0_38 = __flat_39; + }; + __opt_val_40 = __case_payload_34.alert_message; + __opt_disc_41 = ref.is_null(__opt_val_40) == 0; + __opt_inner_0_42 = 0; + __opt_inner_1_43 = 0; + if __opt_disc_41 != 0 { + __packed_44 = "core:internal/cm_lower_string"(ref.as_non_null(__opt_val_40)); + __ptr_45 = builtin::i32_wrap_i64(__packed_44); + __len_46 = builtin::i32_wrap_i64(__packed_44 >> 32_i64); + __opt_inner_0_42 = __ptr_45; + __opt_inner_1_43 = __len_46; + }; + __tv_2 = __opt_disc_37; + __tv_3 = builtin::i64_extend_i32_s(__opt_inner_0_38); + __tv_4 = __opt_disc_41; + __tv_5 = __opt_inner_0_42; + __tv_6 = __opt_inner_1_43; + }; + if ref.test "wasi:http/types.wado/ErrorCode::HttpRequestBodySize"(__err_val) { + __case_payload_47 = value_copy Option(ref.cast "wasi:http/types.wado/ErrorCode::HttpRequestBodySize"(__err_val).payload_0); + __opt_disc_49 = ref.test Option::Some(__case_payload_47); + __opt_inner_0_50 = 0_i64; + if __opt_disc_49 != 0 { + __flat_51 = ref.cast Option::Some(__case_payload_47).payload_0; + __opt_inner_0_50 = __flat_51; + }; + __tv_2 = __opt_disc_49; + __tv_3 = __opt_inner_0_50; + }; + if ref.test "wasi:http/types.wado/ErrorCode::HttpRequestHeaderSectionSize"(__err_val) { + __case_payload_52 = value_copy Option(ref.cast "wasi:http/types.wado/ErrorCode::HttpRequestHeaderSectionSize"(__err_val).payload_0); + __opt_disc_54 = ref.test Option::Some(__case_payload_52); + __opt_inner_0_55 = 0; + if __opt_disc_54 != 0 { + __flat_56 = ref.cast Option::Some(__case_payload_52).payload_0; + __opt_inner_0_55 = __flat_56; + }; + __tv_2 = __opt_disc_54; + __tv_3 = builtin::i64_extend_i32_s(__opt_inner_0_55); + }; + if ref.test "wasi:http/types.wado/ErrorCode::HttpRequestHeaderSize"(__err_val) { + __case_payload_57 = value_copy Option(ref.cast "wasi:http/types.wado/ErrorCode::HttpRequestHeaderSize"(__err_val).payload_0); + __opt_disc_59 = ref.is_null(__case_payload_57) == 0; + __opt_inner_0_60 = 0; + __opt_inner_1_61 = 0; + __opt_inner_2 = 0; + __opt_inner_3 = 0; + __opt_inner_4 = 0; + if __opt_disc_59 != 0 { + __struct_val = ref.as_non_null(__case_payload_57); + __opt_val_66 = __struct_val.field_name; + __opt_disc_67 = ref.is_null(__opt_val_66) == 0; + __opt_inner_0_68 = 0; + __opt_inner_1_69 = 0; + if __opt_disc_67 != 0 { + __packed_70 = "core:internal/cm_lower_string"(ref.as_non_null(__opt_val_66)); + __ptr_71 = builtin::i32_wrap_i64(__packed_70); + __len_72 = builtin::i32_wrap_i64(__packed_70 >> 32_i64); + __opt_inner_0_68 = __ptr_71; + __opt_inner_1_69 = __len_72; + }; + __opt_val_73 = __struct_val.field_size; + __opt_disc_74 = ref.test Option::Some(__opt_val_73); + __opt_inner_0_75 = 0; + if __opt_disc_74 != 0 { + __flat_76 = ref.cast Option::Some(__opt_val_73).payload_0; + __opt_inner_0_75 = __flat_76; + }; + __opt_inner_0_60 = __opt_disc_67; + __opt_inner_1_61 = __opt_inner_0_68; + __opt_inner_2 = __opt_inner_1_69; + __opt_inner_3 = __opt_disc_74; + __opt_inner_4 = __opt_inner_0_75; + }; + __tv_2 = __opt_disc_59; + __tv_3 = builtin::i64_extend_i32_s(__opt_inner_0_60); + __tv_4 = __opt_inner_1_61; + __tv_5 = __opt_inner_2; + __tv_6 = __opt_inner_3; + __tv_7 = __opt_inner_4; + }; + if ref.test "wasi:http/types.wado/ErrorCode::HttpRequestTrailerSectionSize"(__err_val) { + __case_payload_77 = value_copy Option(ref.cast "wasi:http/types.wado/ErrorCode::HttpRequestTrailerSectionSize"(__err_val).payload_0); + __opt_disc_79 = ref.test Option::Some(__case_payload_77); + __opt_inner_0_80 = 0; + if __opt_disc_79 != 0 { + __flat_81 = ref.cast Option::Some(__case_payload_77).payload_0; + __opt_inner_0_80 = __flat_81; + }; + __tv_2 = __opt_disc_79; + __tv_3 = builtin::i64_extend_i32_s(__opt_inner_0_80); + }; + if ref.test "wasi:http/types.wado/ErrorCode::HttpRequestTrailerSize"(__err_val) { + __case_payload_82 = ref.cast "wasi:http/types.wado/ErrorCode::HttpRequestTrailerSize"(__err_val).payload_0; + __opt_val_84 = __case_payload_82.field_name; + __opt_disc_85 = ref.is_null(__opt_val_84) == 0; + __opt_inner_0_86 = 0; + __opt_inner_1_87 = 0; + if __opt_disc_85 != 0 { + __packed_88 = "core:internal/cm_lower_string"(ref.as_non_null(__opt_val_84)); + __ptr_89 = builtin::i32_wrap_i64(__packed_88); + __len_90 = builtin::i32_wrap_i64(__packed_88 >> 32_i64); + __opt_inner_0_86 = __ptr_89; + __opt_inner_1_87 = __len_90; + }; + __opt_val_91 = __case_payload_82.field_size; + __opt_disc_92 = ref.test Option::Some(__opt_val_91); + __opt_inner_0_93 = 0; + if __opt_disc_92 != 0 { + __flat_94 = ref.cast Option::Some(__opt_val_91).payload_0; + __opt_inner_0_93 = __flat_94; + }; + __tv_2 = __opt_disc_85; + __tv_3 = builtin::i64_extend_i32_s(__opt_inner_0_86); + __tv_4 = __opt_inner_1_87; + __tv_5 = __opt_disc_92; + __tv_6 = __opt_inner_0_93; + }; + if ref.test "wasi:http/types.wado/ErrorCode::HttpResponseHeaderSectionSize"(__err_val) { + __case_payload_95 = value_copy Option(ref.cast "wasi:http/types.wado/ErrorCode::HttpResponseHeaderSectionSize"(__err_val).payload_0); + __opt_disc_97 = ref.test Option::Some(__case_payload_95); + __opt_inner_0_98 = 0; + if __opt_disc_97 != 0 { + __flat_99 = ref.cast Option::Some(__case_payload_95).payload_0; + __opt_inner_0_98 = __flat_99; + }; + __tv_2 = __opt_disc_97; + __tv_3 = builtin::i64_extend_i32_s(__opt_inner_0_98); + }; + if ref.test "wasi:http/types.wado/ErrorCode::HttpResponseHeaderSize"(__err_val) { + __case_payload_100 = ref.cast "wasi:http/types.wado/ErrorCode::HttpResponseHeaderSize"(__err_val).payload_0; + __opt_val_102 = __case_payload_100.field_name; + __opt_disc_103 = ref.is_null(__opt_val_102) == 0; + __opt_inner_0_104 = 0; + __opt_inner_1_105 = 0; + if __opt_disc_103 != 0 { + __packed_106 = "core:internal/cm_lower_string"(ref.as_non_null(__opt_val_102)); + __ptr_107 = builtin::i32_wrap_i64(__packed_106); + __len_108 = builtin::i32_wrap_i64(__packed_106 >> 32_i64); + __opt_inner_0_104 = __ptr_107; + __opt_inner_1_105 = __len_108; + }; + __opt_val_109 = __case_payload_100.field_size; + __opt_disc_110 = ref.test Option::Some(__opt_val_109); + __opt_inner_0_111 = 0; + if __opt_disc_110 != 0 { + __flat_112 = ref.cast Option::Some(__opt_val_109).payload_0; + __opt_inner_0_111 = __flat_112; + }; + __tv_2 = __opt_disc_103; + __tv_3 = builtin::i64_extend_i32_s(__opt_inner_0_104); + __tv_4 = __opt_inner_1_105; + __tv_5 = __opt_disc_110; + __tv_6 = __opt_inner_0_111; + }; + if ref.test "wasi:http/types.wado/ErrorCode::HttpResponseBodySize"(__err_val) { + __case_payload_113 = value_copy Option(ref.cast "wasi:http/types.wado/ErrorCode::HttpResponseBodySize"(__err_val).payload_0); + __opt_disc_115 = ref.test Option::Some(__case_payload_113); + __opt_inner_0_116 = 0_i64; + if __opt_disc_115 != 0 { + __flat_117 = ref.cast Option::Some(__case_payload_113).payload_0; + __opt_inner_0_116 = __flat_117; + }; + __tv_2 = __opt_disc_115; + __tv_3 = __opt_inner_0_116; + }; + if ref.test "wasi:http/types.wado/ErrorCode::HttpResponseTrailerSectionSize"(__err_val) { + __case_payload_118 = value_copy Option(ref.cast "wasi:http/types.wado/ErrorCode::HttpResponseTrailerSectionSize"(__err_val).payload_0); + __opt_disc_120 = ref.test Option::Some(__case_payload_118); + __opt_inner_0_121 = 0; + if __opt_disc_120 != 0 { + __flat_122 = ref.cast Option::Some(__case_payload_118).payload_0; + __opt_inner_0_121 = __flat_122; + }; + __tv_2 = __opt_disc_120; + __tv_3 = builtin::i64_extend_i32_s(__opt_inner_0_121); + }; + if ref.test "wasi:http/types.wado/ErrorCode::HttpResponseTrailerSize"(__err_val) { + __case_payload_123 = ref.cast "wasi:http/types.wado/ErrorCode::HttpResponseTrailerSize"(__err_val).payload_0; + __opt_val_125 = __case_payload_123.field_name; + __opt_disc_126 = ref.is_null(__opt_val_125) == 0; + __opt_inner_0_127 = 0; + __opt_inner_1_128 = 0; + if __opt_disc_126 != 0 { + __packed_129 = "core:internal/cm_lower_string"(ref.as_non_null(__opt_val_125)); + __ptr_130 = builtin::i32_wrap_i64(__packed_129); + __len_131 = builtin::i32_wrap_i64(__packed_129 >> 32_i64); + __opt_inner_0_127 = __ptr_130; + __opt_inner_1_128 = __len_131; + }; + __opt_val_132 = __case_payload_123.field_size; + __opt_disc_133 = ref.test Option::Some(__opt_val_132); + __opt_inner_0_134 = 0; + if __opt_disc_133 != 0 { + __flat_135 = ref.cast Option::Some(__opt_val_132).payload_0; + __opt_inner_0_134 = __flat_135; + }; + __tv_2 = __opt_disc_126; + __tv_3 = builtin::i64_extend_i32_s(__opt_inner_0_127); + __tv_4 = __opt_inner_1_128; + __tv_5 = __opt_disc_133; + __tv_6 = __opt_inner_0_134; + }; + if ref.test "wasi:http/types.wado/ErrorCode::HttpResponseTransferCoding"(__err_val) { + __case_payload_136 = value_copy Option(ref.cast "wasi:http/types.wado/ErrorCode::HttpResponseTransferCoding"(__err_val).payload_0); + __opt_disc_138 = ref.is_null(__case_payload_136) == 0; + __opt_inner_0_139 = 0; + __opt_inner_1_140 = 0; + if __opt_disc_138 != 0 { + __packed_141 = "core:internal/cm_lower_string"(ref.as_non_null(__case_payload_136)); + __ptr_142 = builtin::i32_wrap_i64(__packed_141); + __len_143 = builtin::i32_wrap_i64(__packed_141 >> 32_i64); + __opt_inner_0_139 = __ptr_142; + __opt_inner_1_140 = __len_143; + }; + __tv_2 = __opt_disc_138; + __tv_3 = builtin::i64_extend_i32_s(__opt_inner_0_139); + __tv_4 = __opt_inner_1_140; + }; + if ref.test "wasi:http/types.wado/ErrorCode::HttpResponseContentCoding"(__err_val) { + __case_payload_144 = value_copy Option(ref.cast "wasi:http/types.wado/ErrorCode::HttpResponseContentCoding"(__err_val).payload_0); + __opt_disc_146 = ref.is_null(__case_payload_144) == 0; + __opt_inner_0_147 = 0; + __opt_inner_1_148 = 0; + if __opt_disc_146 != 0 { + __packed_149 = "core:internal/cm_lower_string"(ref.as_non_null(__case_payload_144)); + __ptr_150 = builtin::i32_wrap_i64(__packed_149); + __len_151 = builtin::i32_wrap_i64(__packed_149 >> 32_i64); + __opt_inner_0_147 = __ptr_150; + __opt_inner_1_148 = __len_151; + }; + __tv_2 = __opt_disc_146; + __tv_3 = builtin::i64_extend_i32_s(__opt_inner_0_147); + __tv_4 = __opt_inner_1_148; + }; + if ref.test "wasi:http/types.wado/ErrorCode::InternalError"(__err_val) { + __case_payload_152 = value_copy Option(ref.cast "wasi:http/types.wado/ErrorCode::InternalError"(__err_val).payload_0); + __opt_disc_154 = ref.is_null(__case_payload_152) == 0; + __opt_inner_0_155 = 0; + __opt_inner_1_156 = 0; + if __opt_disc_154 != 0 { + __packed_157 = "core:internal/cm_lower_string"(ref.as_non_null(__case_payload_152)); + __ptr_158 = builtin::i32_wrap_i64(__packed_157); + __len_159 = builtin::i32_wrap_i64(__packed_157 >> 32_i64); + __opt_inner_0_155 = __ptr_158; + __opt_inner_1_156 = __len_159; + }; + __tv_2 = __opt_disc_154; + __tv_3 = builtin::i64_extend_i32_s(__opt_inner_0_155); + __tv_4 = __opt_inner_1_156; + }; + "wasi/task-return"(1, __tv_1, __tv_2, __tv_3, __tv_4, __tv_5, __tv_6, __tv_7); + }; + let __fw_write_ptr_6: i32; + let __fw_handle_6: i32; + let __fw_result_6: i32; + __fw_handle_6 = trailers_tx; + __fw_write_ptr_6 = "mem/realloc"(0, 0, 8, 40); + builtin::store_i64(__fw_write_ptr_6, 0_i64); + builtin::store_i64[8](__fw_write_ptr_6, 0_i64); + builtin::store_i64[16](__fw_write_ptr_6, 0_i64); + builtin::store_i64[24](__fw_write_ptr_6, 0_i64); + builtin::store_i64[32](__fw_write_ptr_6, 0_i64); + __fw_result_6 = "wasi/future-write"(__fw_handle_6, __fw_write_ptr_6); + if __fw_result_6 == -1 { + let __fw_evt_6: i32; + __fw_result_6 = "wasi/waitable-set-new"(); + "wasi/waitable-join"(__fw_handle_6, __fw_result_6); + __fw_evt_6 = "mem/realloc"(0, 0, 4, 8); + drop("wasi/waitable-set-wait"(__fw_result_6, __fw_evt_6)); + drop("mem/realloc"(__fw_evt_6, 8, 4, 0)); + }; + drop("mem/realloc"(__fw_write_ptr_6, 40, 8, 0)); +} + +fn __cm_binding__Fields_new() { + return "wasi/wasi:http/Fields::new"(); +} + +fn __cm_binding__Response_new(headers, contents, trailers) { + let __contents_disc: i32; + let __contents_inner0: i32; + let __outptr: i32; + let __lifted_result_7: i32; + let __lifted_result_8: i32; + __contents_disc = ref.test Option>::Some(contents); + __contents_inner0 = 0; + if ref.test Option>::Some(contents) { + __contents_inner0 = ref.cast Option>::Some(contents).payload_0; + }; + __outptr = "mem/realloc"(0, 0, 4, 8); + "wasi/wasi:http/Response::new"(headers, __contents_disc, __contents_inner0, trailers, __outptr); + __lifted_result_7 = builtin::load_i32(__outptr + 0); + __lifted_result_8 = builtin::load_i32(__outptr + 4); + drop("mem/realloc"(__outptr, 8, 4, 0)); + return __lifted_result_7; __lifted_result_8; +} + +fn __cm_export__handle(request) { + handle(request); +} + +fn "core:internal/gc_array_to_memory"(arr, ptr, len) { // from core:internal + let i: i32; + __for_1: block { + i = 0; + block { + l42: loop { + if (i < len) == 0 { + break __for_1; + }; + builtin::store_u8(ptr + i, builtin::array_get_u8(arr, i)); + i = i + 1; + continue l42; + }; + }; + }; +} + +fn "core:internal/cm_lower_string"(s) { // from core:internal + let len: i32; + let bytes: ref array; + let ptr: i32; + len = s.used; + bytes = s.repr; + ptr = "mem/realloc"(0, 0, 1, len); + "core:internal/gc_array_to_memory"(bytes, ptr, len); + return builtin::i64_extend_i32_s(ptr) | (builtin::i64_extend_i32_s(len) << 32_i64); +} + +export fn __cm_export__handle as "handle" diff --git a/wado-compiler/tests/fixtures.golden/cm-subtask-join.wir.wado b/wado-compiler/tests/fixtures.golden/cm-subtask-join.wir.wado index 1b3f6a75c..b7d7da2a1 100644 --- a/wado-compiler/tests/fixtures.golden/cm-subtask-join.wir.wado +++ b/wado-compiler/tests/fixtures.golden/cm-subtask-join.wir.wado @@ -206,6 +206,16 @@ struct Result::Err { payload_0: ref "wasi:http/types.wado/ErrorCode", } +variant Option> { + Some(i32), + None, +} + +struct Option>::Some { + discriminant: i32, + payload_0: i32, +} + type "functype/mem/realloc" = fn(i32, i32, i32, i32) -> i32; type "functype/wasi/task-return" = fn(i32, i32, i32, i64, i32, i32, i32, i32); @@ -234,7 +244,7 @@ type "functype/wasi/waitable-join" = fn(i32, i32); type "functype/wasi/waitable-set-wait" = fn(i32, i32) -> i32; -type "functype/__cm_binding__Response_new" = fn(i32, i32, i32, i32) -> [i32, i32]; +type "functype/__cm_binding__Response_new" = fn(i32, ref Option>, i32) -> [i32, i32]; import fn realloc from "mem/realloc"; import fn task-return from "wasi/task-return"; @@ -393,7 +403,7 @@ fn handle(request) { headers = __cm_binding__Fields_new(); let __sroa___pattern_temp_1_0: i32; let __sroa___pattern_temp_1_1: i32; - multivalue_bind [__sroa___pattern_temp_1_0, __sroa___pattern_temp_1_1] = __cm_binding__Response_new(headers, 0, 0, trailers_future); + multivalue_bind [__sroa___pattern_temp_1_0, __sroa___pattern_temp_1_1] = __cm_binding__Response_new(headers, Option> { 1 }, trailers_future); response = __sroa___pattern_temp_1_0; __task_ret = Result::Ok { discriminant: 0, payload_0: response }; __tv_1 = 0; @@ -723,16 +733,23 @@ fn __cm_binding__Fields_new() { return "wasi/wasi:http/Fields::new"(); } -fn __cm_binding__Response_new(headers, contents_flat0, contents_flat1, trailers) { +fn __cm_binding__Response_new(headers, contents, trailers) { + let __contents_disc: i32; + let __contents_inner0: i32; let __outptr: i32; - let __lifted_result_5: i32; - let __lifted_result_6: i32; + let __lifted_result_7: i32; + let __lifted_result_8: i32; + __contents_disc = ref.test Option>::Some(contents); + __contents_inner0 = 0; + if ref.test Option>::Some(contents) { + __contents_inner0 = ref.cast Option>::Some(contents).payload_0; + }; __outptr = "mem/realloc"(0, 0, 4, 8); - "wasi/wasi:http/Response::new"(headers, contents_flat0, contents_flat1, trailers, __outptr); - __lifted_result_5 = builtin::load_i32(__outptr + 0); - __lifted_result_6 = builtin::load_i32(__outptr + 4); + "wasi/wasi:http/Response::new"(headers, __contents_disc, __contents_inner0, trailers, __outptr); + __lifted_result_7 = builtin::load_i32(__outptr + 0); + __lifted_result_8 = builtin::load_i32(__outptr + 4); drop("mem/realloc"(__outptr, 8, 4, 0)); - return __lifted_result_5; __lifted_result_6; + return __lifted_result_7; __lifted_result_8; } fn __cm_export__handle(request) { @@ -744,13 +761,13 @@ fn "core:internal/gc_array_to_memory"(arr, ptr, len) { // from core:internal __for_1: block { i = 0; block { - l40: loop { + l41: loop { if (i < len) == 0 { break __for_1; }; builtin::store_u8(ptr + i, builtin::array_get_u8(arr, i)); i = i + 1; - continue l40; + continue l41; }; }; }; diff --git a/wado-compiler/tests/fixtures.golden/cm-waitable-set-new.wir.wado b/wado-compiler/tests/fixtures.golden/cm-waitable-set-new.wir.wado index 0db32c31b..7435359bb 100644 --- a/wado-compiler/tests/fixtures.golden/cm-waitable-set-new.wir.wado +++ b/wado-compiler/tests/fixtures.golden/cm-waitable-set-new.wir.wado @@ -206,6 +206,16 @@ struct Result::Err { payload_0: ref "wasi:http/types.wado/ErrorCode", } +variant Option> { + Some(i32), + None, +} + +struct Option>::Some { + discriminant: i32, + payload_0: i32, +} + type "functype/mem/realloc" = fn(i32, i32, i32, i32) -> i32; type "functype/wasi/task-return" = fn(i32, i32, i32, i64, i32, i32, i32, i32); @@ -236,7 +246,7 @@ type "functype/wasi/waitable-join" = fn(i32, i32); type "functype/wasi/waitable-set-wait" = fn(i32, i32) -> i32; -type "functype/__cm_binding__Response_new" = fn(i32, i32, i32, i32) -> [i32, i32]; +type "functype/__cm_binding__Response_new" = fn(i32, ref Option>, i32) -> [i32, i32]; import fn realloc from "mem/realloc"; import fn task-return from "wasi/task-return"; @@ -399,7 +409,7 @@ fn handle(request) { headers = __cm_binding__Fields_new(); let __sroa___pattern_temp_1_0: i32; let __sroa___pattern_temp_1_1: i32; - multivalue_bind [__sroa___pattern_temp_1_0, __sroa___pattern_temp_1_1] = __cm_binding__Response_new(headers, 0, 0, trailers_future); + multivalue_bind [__sroa___pattern_temp_1_0, __sroa___pattern_temp_1_1] = __cm_binding__Response_new(headers, Option> { 1 }, trailers_future); response = __sroa___pattern_temp_1_0; __task_ret = Result::Ok { discriminant: 0, payload_0: response }; __tv_1 = 0; @@ -729,16 +739,23 @@ fn __cm_binding__Fields_new() { return "wasi/wasi:http/Fields::new"(); } -fn __cm_binding__Response_new(headers, contents_flat0, contents_flat1, trailers) { +fn __cm_binding__Response_new(headers, contents, trailers) { + let __contents_disc: i32; + let __contents_inner0: i32; let __outptr: i32; - let __lifted_result_5: i32; - let __lifted_result_6: i32; + let __lifted_result_7: i32; + let __lifted_result_8: i32; + __contents_disc = ref.test Option>::Some(contents); + __contents_inner0 = 0; + if ref.test Option>::Some(contents) { + __contents_inner0 = ref.cast Option>::Some(contents).payload_0; + }; __outptr = "mem/realloc"(0, 0, 4, 8); - "wasi/wasi:http/Response::new"(headers, contents_flat0, contents_flat1, trailers, __outptr); - __lifted_result_5 = builtin::load_i32(__outptr + 0); - __lifted_result_6 = builtin::load_i32(__outptr + 4); + "wasi/wasi:http/Response::new"(headers, __contents_disc, __contents_inner0, trailers, __outptr); + __lifted_result_7 = builtin::load_i32(__outptr + 0); + __lifted_result_8 = builtin::load_i32(__outptr + 4); drop("mem/realloc"(__outptr, 8, 4, 0)); - return __lifted_result_5; __lifted_result_6; + return __lifted_result_7; __lifted_result_8; } fn __cm_export__handle(request) { @@ -750,13 +767,13 @@ fn "core:internal/gc_array_to_memory"(arr, ptr, len) { // from core:internal __for_1: block { i = 0; block { - l40: loop { + l41: loop { if (i < len) == 0 { break __for_1; }; builtin::store_u8(ptr + i, builtin::array_get_u8(arr, i)); i = i + 1; - continue l40; + continue l41; }; }; }; diff --git a/wado-compiler/tests/fixtures.golden/cm-waitable-set-poll.wir.wado b/wado-compiler/tests/fixtures.golden/cm-waitable-set-poll.wir.wado index f73626d9f..4a07bf7b2 100644 --- a/wado-compiler/tests/fixtures.golden/cm-waitable-set-poll.wir.wado +++ b/wado-compiler/tests/fixtures.golden/cm-waitable-set-poll.wir.wado @@ -212,6 +212,16 @@ struct Result::Err { payload_0: ref "wasi:http/types.wado/ErrorCode", } +variant Option> { + Some(i32), + None, +} + +struct Option>::Some { + discriminant: i32, + payload_0: i32, +} + type "functype/mem/realloc" = fn(i32, i32, i32, i32) -> i32; type "functype/wasi/task-return" = fn(i32, i32, i32, i64, i32, i32, i32, i32); @@ -246,7 +256,7 @@ type "functype/wasi/waitable-join" = fn(i32, i32); type "functype/wasi/waitable-set-wait" = fn(i32, i32) -> i32; -type "functype/__cm_binding__Response_new" = fn(i32, i32, i32, i32) -> [i32, i32]; +type "functype/__cm_binding__Response_new" = fn(i32, ref Option>, i32) -> [i32, i32]; import fn realloc from "mem/realloc"; import fn task-return from "wasi/task-return"; @@ -551,7 +561,7 @@ fn handle(request) { headers_5 = __cm_binding__Fields_new(); let __sroa___pattern_temp_2_0: i32; let __sroa___pattern_temp_2_1: i32; - multivalue_bind [__sroa___pattern_temp_2_0, __sroa___pattern_temp_2_1] = __cm_binding__Response_new(headers_5, 0, 0, trailers_future_3); + multivalue_bind [__sroa___pattern_temp_2_0, __sroa___pattern_temp_2_1] = __cm_binding__Response_new(headers_5, Option> { 1 }, trailers_future_3); response_6 = __sroa___pattern_temp_2_0; __task_ret_13 = Result::Ok { discriminant: 0, payload_0: response_6 }; __tv_1_15 = 0; @@ -884,7 +894,7 @@ fn handle(request) { headers_10 = __cm_binding__Fields_new(); let __sroa___pattern_temp_4_0: i32; let __sroa___pattern_temp_4_1: i32; - multivalue_bind [__sroa___pattern_temp_4_0, __sroa___pattern_temp_4_1] = __cm_binding__Response_new(headers_10, 0, 0, trailers_future_8); + multivalue_bind [__sroa___pattern_temp_4_0, __sroa___pattern_temp_4_1] = __cm_binding__Response_new(headers_10, Option> { 1 }, trailers_future_8); response_11 = __sroa___pattern_temp_4_0; __task_ret_164 = Result::Ok { discriminant: 0, payload_0: response_11 }; __tv_1_166 = 0; @@ -1214,16 +1224,23 @@ fn __cm_binding__Fields_new() { return "wasi/wasi:http/Fields::new"(); } -fn __cm_binding__Response_new(headers, contents_flat0, contents_flat1, trailers) { +fn __cm_binding__Response_new(headers, contents, trailers) { + let __contents_disc: i32; + let __contents_inner0: i32; let __outptr: i32; - let __lifted_result_5: i32; - let __lifted_result_6: i32; + let __lifted_result_7: i32; + let __lifted_result_8: i32; + __contents_disc = ref.test Option>::Some(contents); + __contents_inner0 = 0; + if ref.test Option>::Some(contents) { + __contents_inner0 = ref.cast Option>::Some(contents).payload_0; + }; __outptr = "mem/realloc"(0, 0, 4, 8); - "wasi/wasi:http/Response::new"(headers, contents_flat0, contents_flat1, trailers, __outptr); - __lifted_result_5 = builtin::load_i32(__outptr + 0); - __lifted_result_6 = builtin::load_i32(__outptr + 4); + "wasi/wasi:http/Response::new"(headers, __contents_disc, __contents_inner0, trailers, __outptr); + __lifted_result_7 = builtin::load_i32(__outptr + 0); + __lifted_result_8 = builtin::load_i32(__outptr + 4); drop("mem/realloc"(__outptr, 8, 4, 0)); - return __lifted_result_5; __lifted_result_6; + return __lifted_result_7; __lifted_result_8; } fn __cm_export__handle(request) { @@ -1235,13 +1252,13 @@ fn "core:internal/gc_array_to_memory"(arr, ptr, len) { // from core:internal __for_1: block { i = 0; block { - l80: loop { + l81: loop { if (i < len) == 0 { break __for_1; }; builtin::store_u8(ptr + i, builtin::array_get_u8(arr, i)); i = i + 1; - continue l80; + continue l81; }; }; }; diff --git a/wado-compiler/tests/fixtures.golden/http-200.wir.wado b/wado-compiler/tests/fixtures.golden/http-200.wir.wado index c20340698..7ecf24644 100644 --- a/wado-compiler/tests/fixtures.golden/http-200.wir.wado +++ b/wado-compiler/tests/fixtures.golden/http-200.wir.wado @@ -206,6 +206,16 @@ struct Result::Err { payload_0: ref "wasi:http/types.wado/ErrorCode", } +variant Option> { + Some(i32), + None, +} + +struct Option>::Some { + discriminant: i32, + payload_0: i32, +} + type "functype/mem/realloc" = fn(i32, i32, i32, i32) -> i32; type "functype/wasi/task-return" = fn(i32, i32, i32, i64, i32, i32, i32, i32); @@ -234,7 +244,7 @@ type "functype/wasi/waitable-join" = fn(i32, i32); type "functype/wasi/waitable-set-wait" = fn(i32, i32) -> i32; -type "functype/__cm_binding__Response_new" = fn(i32, i32, i32, i32) -> [i32, i32]; +type "functype/__cm_binding__Response_new" = fn(i32, ref Option>, i32) -> [i32, i32]; import fn realloc from "mem/realloc"; import fn task-return from "wasi/task-return"; @@ -393,7 +403,7 @@ fn handle(request) { headers = __cm_binding__Fields_new(); let __sroa___pattern_temp_1_0: i32; let __sroa___pattern_temp_1_1: i32; - multivalue_bind [__sroa___pattern_temp_1_0, __sroa___pattern_temp_1_1] = __cm_binding__Response_new(headers, 0, 0, trailers_future); + multivalue_bind [__sroa___pattern_temp_1_0, __sroa___pattern_temp_1_1] = __cm_binding__Response_new(headers, Option> { 1 }, trailers_future); response = __sroa___pattern_temp_1_0; __task_ret = Result::Ok { discriminant: 0, payload_0: response }; __tv_1 = 0; @@ -723,16 +733,23 @@ fn __cm_binding__Fields_new() { return "wasi/wasi:http/Fields::new"(); } -fn __cm_binding__Response_new(headers, contents_flat0, contents_flat1, trailers) { +fn __cm_binding__Response_new(headers, contents, trailers) { + let __contents_disc: i32; + let __contents_inner0: i32; let __outptr: i32; - let __lifted_result_5: i32; - let __lifted_result_6: i32; + let __lifted_result_7: i32; + let __lifted_result_8: i32; + __contents_disc = ref.test Option>::Some(contents); + __contents_inner0 = 0; + if ref.test Option>::Some(contents) { + __contents_inner0 = ref.cast Option>::Some(contents).payload_0; + }; __outptr = "mem/realloc"(0, 0, 4, 8); - "wasi/wasi:http/Response::new"(headers, contents_flat0, contents_flat1, trailers, __outptr); - __lifted_result_5 = builtin::load_i32(__outptr + 0); - __lifted_result_6 = builtin::load_i32(__outptr + 4); + "wasi/wasi:http/Response::new"(headers, __contents_disc, __contents_inner0, trailers, __outptr); + __lifted_result_7 = builtin::load_i32(__outptr + 0); + __lifted_result_8 = builtin::load_i32(__outptr + 4); drop("mem/realloc"(__outptr, 8, 4, 0)); - return __lifted_result_5; __lifted_result_6; + return __lifted_result_7; __lifted_result_8; } fn __cm_export__handle(request) { @@ -744,13 +761,13 @@ fn "core:internal/gc_array_to_memory"(arr, ptr, len) { // from core:internal __for_1: block { i = 0; block { - l40: loop { + l41: loop { if (i < len) == 0 { break __for_1; }; builtin::store_u8(ptr + i, builtin::array_get_u8(arr, i)); i = i + 1; - continue l40; + continue l41; }; }; }; diff --git a/wado-compiler/tests/fixtures.golden/http-400.wir.wado b/wado-compiler/tests/fixtures.golden/http-400.wir.wado index 1989ef239..4890b3a5c 100644 --- a/wado-compiler/tests/fixtures.golden/http-400.wir.wado +++ b/wado-compiler/tests/fixtures.golden/http-400.wir.wado @@ -211,6 +211,16 @@ variant Result { Err, } +variant Option> { + Some(i32), + None, +} + +struct Option>::Some { + discriminant: i32, + payload_0: i32, +} + type "functype/mem/realloc" = fn(i32, i32, i32, i32) -> i32; type "functype/wasi/task-return" = fn(i32, i32, i32, i64, i32, i32, i32, i32); @@ -243,7 +253,7 @@ type "functype/wasi/waitable-join" = fn(i32, i32); type "functype/wasi/waitable-set-wait" = fn(i32, i32) -> i32; -type "functype/__cm_binding__Response_new" = fn(i32, i32, i32, i32) -> [i32, i32]; +type "functype/__cm_binding__Response_new" = fn(i32, ref Option>, i32) -> [i32, i32]; import fn realloc from "mem/realloc"; import fn task-return from "wasi/task-return"; @@ -403,7 +413,7 @@ fn handle(request) { headers = __cm_binding__Fields_new(); let __sroa___pattern_temp_1_0: i32; let __sroa___pattern_temp_1_1: i32; - multivalue_bind [__sroa___pattern_temp_1_0, __sroa___pattern_temp_1_1] = __cm_binding__Response_new(headers, 0, 0, trailers_future); + multivalue_bind [__sroa___pattern_temp_1_0, __sroa___pattern_temp_1_1] = __cm_binding__Response_new(headers, Option> { 1 }, trailers_future); response = __sroa___pattern_temp_1_0; drop(__cm_binding__Response_set_status_code(response, 400)); __task_ret = Result::Ok { discriminant: 0, payload_0: response }; @@ -734,16 +744,23 @@ fn __cm_binding__Fields_new() { return "wasi/wasi:http/Fields::new"(); } -fn __cm_binding__Response_new(headers, contents_flat0, contents_flat1, trailers) { +fn __cm_binding__Response_new(headers, contents, trailers) { + let __contents_disc: i32; + let __contents_inner0: i32; let __outptr: i32; - let __lifted_result_5: i32; - let __lifted_result_6: i32; + let __lifted_result_7: i32; + let __lifted_result_8: i32; + __contents_disc = ref.test Option>::Some(contents); + __contents_inner0 = 0; + if ref.test Option>::Some(contents) { + __contents_inner0 = ref.cast Option>::Some(contents).payload_0; + }; __outptr = "mem/realloc"(0, 0, 4, 8); - "wasi/wasi:http/Response::new"(headers, contents_flat0, contents_flat1, trailers, __outptr); - __lifted_result_5 = builtin::load_i32(__outptr + 0); - __lifted_result_6 = builtin::load_i32(__outptr + 4); + "wasi/wasi:http/Response::new"(headers, __contents_disc, __contents_inner0, trailers, __outptr); + __lifted_result_7 = builtin::load_i32(__outptr + 0); + __lifted_result_8 = builtin::load_i32(__outptr + 4); drop("mem/realloc"(__outptr, 8, 4, 0)); - return __lifted_result_5; __lifted_result_6; + return __lifted_result_7; __lifted_result_8; } fn __cm_binding__Response_set_status_code(self, status_code) { @@ -768,13 +785,13 @@ fn "core:internal/gc_array_to_memory"(arr, ptr, len) { // from core:internal __for_1: block { i = 0; block { - l41: loop { + l42: loop { if (i < len) == 0 { break __for_1; }; builtin::store_u8(ptr + i, builtin::array_get_u8(arr, i)); i = i + 1; - continue l41; + continue l42; }; }; }; diff --git a/wado-compiler/tests/fixtures.golden/http-500.wir.wado b/wado-compiler/tests/fixtures.golden/http-500.wir.wado index 3d5a56617..b3e697520 100644 --- a/wado-compiler/tests/fixtures.golden/http-500.wir.wado +++ b/wado-compiler/tests/fixtures.golden/http-500.wir.wado @@ -211,6 +211,16 @@ variant Result { Err, } +variant Option> { + Some(i32), + None, +} + +struct Option>::Some { + discriminant: i32, + payload_0: i32, +} + type "functype/mem/realloc" = fn(i32, i32, i32, i32) -> i32; type "functype/wasi/task-return" = fn(i32, i32, i32, i64, i32, i32, i32, i32); @@ -243,7 +253,7 @@ type "functype/wasi/waitable-join" = fn(i32, i32); type "functype/wasi/waitable-set-wait" = fn(i32, i32) -> i32; -type "functype/__cm_binding__Response_new" = fn(i32, i32, i32, i32) -> [i32, i32]; +type "functype/__cm_binding__Response_new" = fn(i32, ref Option>, i32) -> [i32, i32]; import fn realloc from "mem/realloc"; import fn task-return from "wasi/task-return"; @@ -403,7 +413,7 @@ fn handle(request) { headers = __cm_binding__Fields_new(); let __sroa___pattern_temp_1_0: i32; let __sroa___pattern_temp_1_1: i32; - multivalue_bind [__sroa___pattern_temp_1_0, __sroa___pattern_temp_1_1] = __cm_binding__Response_new(headers, 0, 0, trailers_future); + multivalue_bind [__sroa___pattern_temp_1_0, __sroa___pattern_temp_1_1] = __cm_binding__Response_new(headers, Option> { 1 }, trailers_future); response = __sroa___pattern_temp_1_0; drop(__cm_binding__Response_set_status_code(response, 500)); __task_ret = Result::Ok { discriminant: 0, payload_0: response }; @@ -734,16 +744,23 @@ fn __cm_binding__Fields_new() { return "wasi/wasi:http/Fields::new"(); } -fn __cm_binding__Response_new(headers, contents_flat0, contents_flat1, trailers) { +fn __cm_binding__Response_new(headers, contents, trailers) { + let __contents_disc: i32; + let __contents_inner0: i32; let __outptr: i32; - let __lifted_result_5: i32; - let __lifted_result_6: i32; + let __lifted_result_7: i32; + let __lifted_result_8: i32; + __contents_disc = ref.test Option>::Some(contents); + __contents_inner0 = 0; + if ref.test Option>::Some(contents) { + __contents_inner0 = ref.cast Option>::Some(contents).payload_0; + }; __outptr = "mem/realloc"(0, 0, 4, 8); - "wasi/wasi:http/Response::new"(headers, contents_flat0, contents_flat1, trailers, __outptr); - __lifted_result_5 = builtin::load_i32(__outptr + 0); - __lifted_result_6 = builtin::load_i32(__outptr + 4); + "wasi/wasi:http/Response::new"(headers, __contents_disc, __contents_inner0, trailers, __outptr); + __lifted_result_7 = builtin::load_i32(__outptr + 0); + __lifted_result_8 = builtin::load_i32(__outptr + 4); drop("mem/realloc"(__outptr, 8, 4, 0)); - return __lifted_result_5; __lifted_result_6; + return __lifted_result_7; __lifted_result_8; } fn __cm_binding__Response_set_status_code(self, status_code) { @@ -768,13 +785,13 @@ fn "core:internal/gc_array_to_memory"(arr, ptr, len) { // from core:internal __for_1: block { i = 0; block { - l41: loop { + l42: loop { if (i < len) == 0 { break __for_1; }; builtin::store_u8(ptr + i, builtin::array_get_u8(arr, i)); i = i + 1; - continue l41; + continue l42; }; }; }; diff --git a/wado-compiler/tests/fixtures.golden/http-body-contains.wir.wado b/wado-compiler/tests/fixtures.golden/http-body-contains.wir.wado index d203d51b0..8398d6c5a 100644 --- a/wado-compiler/tests/fixtures.golden/http-body-contains.wir.wado +++ b/wado-compiler/tests/fixtures.golden/http-body-contains.wir.wado @@ -206,6 +206,16 @@ struct Result::Err { payload_0: ref "wasi:http/types.wado/ErrorCode", } +variant Option> { + Some(i32), + None, +} + +struct Option>::Some { + discriminant: i32, + payload_0: i32, +} + struct Array { // Array with T=u8 mut repr: ref array, mut used: i32, @@ -257,7 +267,7 @@ type "functype/wasi/stream-drop-writable" = fn(i32); type "functype/wasi/future-write" = fn(i32, i32) -> i32; -type "functype/__cm_binding__Response_new" = fn(i32, i32, i32, i32) -> [i32, i32]; +type "functype/__cm_binding__Response_new" = fn(i32, ref Option>, i32) -> [i32, i32]; import fn realloc from "mem/realloc"; import fn stream-write from "wasi/stream-write"; @@ -428,7 +438,7 @@ fn handle(request) { headers = __cm_binding__Fields_new(); let __sroa___pattern_temp_2_0: i32; let __sroa___pattern_temp_2_1: i32; - multivalue_bind [__sroa___pattern_temp_2_0, __sroa___pattern_temp_2_1] = __cm_binding__Response_new(headers, 1, body_rx, trailers_future); + multivalue_bind [__sroa___pattern_temp_2_0, __sroa___pattern_temp_2_1] = __cm_binding__Response_new(headers, Option>::Some { discriminant: 0, payload_0: body_rx }, trailers_future); response = __sroa___pattern_temp_2_0; __task_ret = Result::Ok { discriminant: 0, payload_0: response }; __tv_1 = 0; @@ -764,16 +774,23 @@ fn __cm_binding__Fields_new() { return "wasi/wasi:http/Fields::new"(); } -fn __cm_binding__Response_new(headers, contents_flat0, contents_flat1, trailers) { +fn __cm_binding__Response_new(headers, contents, trailers) { + let __contents_disc: i32; + let __contents_inner0: i32; let __outptr: i32; - let __lifted_result_5: i32; - let __lifted_result_6: i32; + let __lifted_result_7: i32; + let __lifted_result_8: i32; + __contents_disc = ref.test Option>::Some(contents); + __contents_inner0 = 0; + if ref.test Option>::Some(contents) { + __contents_inner0 = ref.cast Option>::Some(contents).payload_0; + }; __outptr = "mem/realloc"(0, 0, 4, 8); - "wasi/wasi:http/Response::new"(headers, contents_flat0, contents_flat1, trailers, __outptr); - __lifted_result_5 = builtin::load_i32(__outptr + 0); - __lifted_result_6 = builtin::load_i32(__outptr + 4); + "wasi/wasi:http/Response::new"(headers, __contents_disc, __contents_inner0, trailers, __outptr); + __lifted_result_7 = builtin::load_i32(__outptr + 0); + __lifted_result_8 = builtin::load_i32(__outptr + 4); drop("mem/realloc"(__outptr, 8, 4, 0)); - return __lifted_result_5; __lifted_result_6; + return __lifted_result_7; __lifted_result_8; } fn __cm_export__handle(request) { @@ -785,13 +802,13 @@ fn "core:internal/gc_array_to_memory"(arr, ptr, len) { // from core:internal __for_1: block { i = 0; block { - l40: loop { + l41: loop { if (i < len) == 0 { break __for_1; }; builtin::store_u8(ptr + i, builtin::array_get_u8(arr, i)); i = i + 1; - continue l40; + continue l41; }; }; }; @@ -879,13 +896,13 @@ fn Array::grow(self) { __for_0: block { i = 0; block { - l45: loop { + l46: loop { if (i < used) == 0 { break __for_0; }; builtin::array_set_u8(new_repr, i, builtin::array_get(old_repr, i)); i = i + 1; - continue l45; + continue l46; }; }; }; diff --git a/wado-compiler/tests/fixtures.golden/http-client-send-simple.wir.wado b/wado-compiler/tests/fixtures.golden/http-client-send-simple.wir.wado new file mode 100644 index 000000000..7393cca6b --- /dev/null +++ b/wado-compiler/tests/fixtures.golden/http-client-send-simple.wir.wado @@ -0,0 +1,1356 @@ +// Golden file: WIR with -O2 optimization +// Source: wado-compiler/tests/fixtures/http-client-send-simple.wado +// Generated by: mise run update-golden-fixtures + +array array (mut u8); + +struct String { + mut repr: ref array, + mut used: i32, +} + +variant Scheme { // from wasi:http/types.wado + Http, + Https, + Other(ref String), +} + +struct Scheme::Other { + discriminant: i32, + payload_0: ref String, +} + +struct FieldSizePayload { // from wasi:http/types.wado + mut field_name: ref null String, + mut field_size: ref Option, +} + +struct TlsAlertReceivedPayload { // from wasi:http/types.wado + mut alert_id: ref Option, + mut alert_message: ref null String, +} + +struct DnsErrorPayload { // from wasi:http/types.wado + mut rcode: ref null String, + mut info_code: ref Option, +} + +variant ErrorCode { // from wasi:http/types.wado + DnsTimeout, + DnsError(ref "wasi:http/types.wado/DnsErrorPayload"), + DestinationNotFound, + DestinationUnavailable, + DestinationIpProhibited, + DestinationIpUnroutable, + ConnectionRefused, + ConnectionTerminated, + ConnectionTimeout, + ConnectionReadTimeout, + ConnectionWriteTimeout, + ConnectionLimitReached, + TlsProtocolError, + TlsCertificateError, + TlsAlertReceived(ref "wasi:http/types.wado/TlsAlertReceivedPayload"), + HttpRequestDenied, + HttpRequestLengthRequired, + HttpRequestBodySize(ref Option), + HttpRequestMethodInvalid, + HttpRequestUriInvalid, + HttpRequestUriTooLong, + HttpRequestHeaderSectionSize(ref Option), + HttpRequestHeaderSize(ref null "wasi:http/types.wado/FieldSizePayload"), + HttpRequestTrailerSectionSize(ref Option), + HttpRequestTrailerSize(ref "wasi:http/types.wado/FieldSizePayload"), + HttpResponseIncomplete, + HttpResponseHeaderSectionSize(ref Option), + HttpResponseHeaderSize(ref "wasi:http/types.wado/FieldSizePayload"), + HttpResponseBodySize(ref Option), + HttpResponseTrailerSectionSize(ref Option), + HttpResponseTrailerSize(ref "wasi:http/types.wado/FieldSizePayload"), + HttpResponseTransferCoding(ref null String), + HttpResponseContentCoding(ref null String), + HttpResponseTimeout, + HttpUpgradeFailed, + HttpProtocolError, + LoopDetected, + ConfigurationError, + InternalError(ref null String), +} + +struct ErrorCode::DnsError { + discriminant: i32, + payload_0: ref "wasi:http/types.wado/DnsErrorPayload", +} + +struct ErrorCode::TlsAlertReceived { + discriminant: i32, + payload_0: ref "wasi:http/types.wado/TlsAlertReceivedPayload", +} + +struct ErrorCode::HttpRequestBodySize { + discriminant: i32, + payload_0: ref Option, +} + +struct ErrorCode::HttpRequestHeaderSectionSize { + discriminant: i32, + payload_0: ref Option, +} + +struct ErrorCode::HttpRequestHeaderSize { + discriminant: i32, + payload_0: ref null "wasi:http/types.wado/FieldSizePayload", +} + +struct ErrorCode::HttpRequestTrailerSectionSize { + discriminant: i32, + payload_0: ref Option, +} + +struct ErrorCode::HttpRequestTrailerSize { + discriminant: i32, + payload_0: ref "wasi:http/types.wado/FieldSizePayload", +} + +struct ErrorCode::HttpResponseHeaderSectionSize { + discriminant: i32, + payload_0: ref Option, +} + +struct ErrorCode::HttpResponseHeaderSize { + discriminant: i32, + payload_0: ref "wasi:http/types.wado/FieldSizePayload", +} + +struct ErrorCode::HttpResponseBodySize { + discriminant: i32, + payload_0: ref Option, +} + +struct ErrorCode::HttpResponseTrailerSectionSize { + discriminant: i32, + payload_0: ref Option, +} + +struct ErrorCode::HttpResponseTrailerSize { + discriminant: i32, + payload_0: ref "wasi:http/types.wado/FieldSizePayload", +} + +struct ErrorCode::HttpResponseTransferCoding { + discriminant: i32, + payload_0: ref null String, +} + +struct ErrorCode::HttpResponseContentCoding { + discriminant: i32, + payload_0: ref null String, +} + +struct ErrorCode::InternalError { + discriminant: i32, + payload_0: ref null String, +} + +variant Option { + Some(ref String), + None, +} + +variant Option { + Some(u16), + None, +} + +struct Option::Some { + discriminant: i32, + payload_0: u16, +} + +variant Option { + Some(u8), + None, +} + +struct Option::Some { + discriminant: i32, + payload_0: u8, +} + +variant Option { + Some(u32), + None, +} + +struct Option::Some { + discriminant: i32, + payload_0: u32, +} + +variant Option { + Some(u64), + None, +} + +struct Option::Some { + discriminant: i32, + payload_0: u64, +} + +variant Option { + Some(ref "wasi:http/types.wado/FieldSizePayload"), + None, +} + +variant Option { + Some(i32), + None, +} + +struct Option::Some { + discriminant: i32, + payload_0: i32, +} + +variant Result { + Ok(i32), + Err(ref "wasi:http/types.wado/ErrorCode"), +} + +struct Result::Ok { + discriminant: i32, + payload_0: i32, +} + +struct Result::Err { + discriminant: i32, + payload_0: ref "wasi:http/types.wado/ErrorCode", +} + +variant Result { + Ok, + Err, +} + +variant Option> { + Some(i32), + None, +} + +struct Option>::Some { + discriminant: i32, + payload_0: i32, +} + +type "functype/mem/realloc" = fn(i32, i32, i32, i32) -> i32; + +type "functype/wasi/task-return" = fn(i32, i32, i32, i64, i32, i32, i32, i32); + +type "functype/wasi/waitable-join" = fn(i32, i32); + +type "functype/wasi/waitable-set-wait" = fn(i32, i32) -> i32; + +type "functype/wasi/wasi:http/Client::send" = fn(i32, i32) -> i32; + +type "functype/wasi/wasi:http/Fields::new" = fn() -> i32; + +type "functype/wasi/wasi:http/Request::new" = fn(i32, i32, i32, i32, i32, i32, i32); + +type "functype/wasi/wasi:http/Request::set_path_with_query" = fn(i32, i32, i32, i32) -> i32; + +type "functype/wasi/wasi:http/Request::set_scheme" = fn(i32, i32, i32, i32, i32) -> i32; + +type "functype/wasi/wasi:http/Request::set_authority" = fn(i32, i32, i32, i32) -> i32; + +type "functype/handle" = fn(i32); + +type "functype/__cm_binding__Fields_new" = fn() -> i32; + +type "functype/__cm_binding__Request_set_scheme" = fn(i32, ref null "wasi:http/types.wado/Scheme") -> ref Result; + +type "functype/__cm_binding__Request_set_authority" = fn(i32, ref null String) -> ref Result; + +type "functype/__cm_binding__Request_set_path_with_query" = fn(i32, ref null String) -> ref Result; + +type "functype/__cm_binding__Client_send" = fn(i32) -> ref Result; + +type "functype/__cm_export__handle" = fn(i32); + +type "functype/core:internal/memory_to_gc_array" = fn(i32, i32) -> ref array; + +type "functype/core:internal/gc_array_to_memory" = fn(ref array, i32, i32); + +type "functype/core:internal/wait_for_subtask" = fn(i32); + +type "functype/core:internal/cm_lower_string" = fn(ref String) -> i64; + +type "functype/wasi/future-new" = fn() -> i64; + +type "functype/wasi/future-write" = fn(i32, i32) -> i32; + +type "functype/wasi/waitable-set-new" = fn() -> i32; + +type "functype/wasi/subtask-drop" = fn(i32); + +type "functype/wasi/waitable-set-drop" = fn(i32); + +type "functype/__cm_binding__Request_new" = fn(i32, ref Option>, i32, ref Option) -> [i32, i32]; + +type "functype/core:internal/cm_waitable_set_wait" = fn(i32) -> [i32, i32, u32]; + +import fn realloc from "mem/realloc"; +import fn task-return from "wasi/task-return"; +import fn waitable-join from "wasi/waitable-join"; +import fn waitable-set-wait from "wasi/waitable-set-wait"; +import fn wasi:http/Client::send from "wasi/wasi:http/Client::send"; +import fn wasi:http/Fields::new from "wasi/wasi:http/Fields::new"; +import fn wasi:http/Request::new from "wasi/wasi:http/Request::new"; +import fn wasi:http/Request::set_path_with_query from "wasi/wasi:http/Request::set_path_with_query"; +import fn wasi:http/Request::set_scheme from "wasi/wasi:http/Request::set_scheme"; +import fn wasi:http/Request::set_authority from "wasi/wasi:http/Request::set_authority"; +import memory (1) from "mem/memory"; +import fn future-new from "wasi/future-new"; +import fn future-write from "wasi/future-write"; +import fn waitable-set-new from "wasi/waitable-set-new"; +import fn subtask-drop from "wasi/subtask-drop"; +import fn waitable-set-drop from "wasi/waitable-set-drop"; + +fn handle(request) { + let headers: i32; + let trailers_future: i32; + let trailers_tx: i32; + let out_req: i32; + let upstream: ref Result; + let __tv_1: i32; + let __tv_2: i32; + let __tv_3: i64; + let __tv_4: i32; + let __tv_5: i32; + let __tv_6: i32; + let __tv_7: i32; + let __ok_val: i32; + let __err_val: ref "wasi:http/types.wado/ErrorCode"; + let __case_payload_19: ref "wasi:http/types.wado/DnsErrorPayload"; + let __opt_val_21: ref null String; + let __opt_disc_22: i32; + let __opt_inner_0_23: i32; + let __opt_inner_1_24: i32; + let __packed_25: i64; + let __ptr_26: i32; + let __len_27: i32; + let __opt_val_28: ref Option; + let __opt_disc_29: i32; + let __opt_inner_0_30: i32; + let __flat_31: i32; + let __case_payload_32: ref "wasi:http/types.wado/TlsAlertReceivedPayload"; + let __opt_val_34: ref Option; + let __opt_disc_35: i32; + let __opt_inner_0_36: i32; + let __flat_37: i32; + let __opt_val_38: ref null String; + let __opt_disc_39: i32; + let __opt_inner_0_40: i32; + let __opt_inner_1_41: i32; + let __packed_42: i64; + let __ptr_43: i32; + let __len_44: i32; + let __case_payload_45: ref Option; + let __opt_disc_47: i32; + let __opt_inner_0_48: i64; + let __flat_49: i64; + let __case_payload_50: ref Option; + let __opt_disc_52: i32; + let __opt_inner_0_53: i32; + let __flat_54: i32; + let __case_payload_55: ref null "wasi:http/types.wado/FieldSizePayload"; + let __opt_disc_57: i32; + let __opt_inner_0_58: i32; + let __opt_inner_1_59: i32; + let __opt_inner_2: i32; + let __opt_inner_3: i32; + let __opt_inner_4: i32; + let __struct_val: ref "wasi:http/types.wado/FieldSizePayload"; + let __opt_val_64: ref null String; + let __opt_disc_65: i32; + let __opt_inner_0_66: i32; + let __opt_inner_1_67: i32; + let __packed_68: i64; + let __ptr_69: i32; + let __len_70: i32; + let __opt_val_71: ref Option; + let __opt_disc_72: i32; + let __opt_inner_0_73: i32; + let __flat_74: i32; + let __case_payload_75: ref Option; + let __opt_disc_77: i32; + let __opt_inner_0_78: i32; + let __flat_79: i32; + let __case_payload_80: ref "wasi:http/types.wado/FieldSizePayload"; + let __opt_val_82: ref null String; + let __opt_disc_83: i32; + let __opt_inner_0_84: i32; + let __opt_inner_1_85: i32; + let __packed_86: i64; + let __ptr_87: i32; + let __len_88: i32; + let __opt_val_89: ref Option; + let __opt_disc_90: i32; + let __opt_inner_0_91: i32; + let __flat_92: i32; + let __case_payload_93: ref Option; + let __opt_disc_95: i32; + let __opt_inner_0_96: i32; + let __flat_97: i32; + let __case_payload_98: ref "wasi:http/types.wado/FieldSizePayload"; + let __opt_val_100: ref null String; + let __opt_disc_101: i32; + let __opt_inner_0_102: i32; + let __opt_inner_1_103: i32; + let __packed_104: i64; + let __ptr_105: i32; + let __len_106: i32; + let __opt_val_107: ref Option; + let __opt_disc_108: i32; + let __opt_inner_0_109: i32; + let __flat_110: i32; + let __case_payload_111: ref Option; + let __opt_disc_113: i32; + let __opt_inner_0_114: i64; + let __flat_115: i64; + let __case_payload_116: ref Option; + let __opt_disc_118: i32; + let __opt_inner_0_119: i32; + let __flat_120: i32; + let __case_payload_121: ref "wasi:http/types.wado/FieldSizePayload"; + let __opt_val_123: ref null String; + let __opt_disc_124: i32; + let __opt_inner_0_125: i32; + let __opt_inner_1_126: i32; + let __packed_127: i64; + let __ptr_128: i32; + let __len_129: i32; + let __opt_val_130: ref Option; + let __opt_disc_131: i32; + let __opt_inner_0_132: i32; + let __flat_133: i32; + let __case_payload_134: ref null String; + let __opt_disc_136: i32; + let __opt_inner_0_137: i32; + let __opt_inner_1_138: i32; + let __packed_139: i64; + let __ptr_140: i32; + let __len_141: i32; + let __case_payload_142: ref null String; + let __opt_disc_144: i32; + let __opt_inner_0_145: i32; + let __opt_inner_1_146: i32; + let __packed_147: i64; + let __ptr_148: i32; + let __len_149: i32; + let __case_payload_150: ref null String; + let __opt_disc_152: i32; + let __opt_inner_0_153: i32; + let __opt_inner_1_154: i32; + let __packed_155: i64; + let __ptr_156: i32; + let __len_157: i32; + headers = __cm_binding__Fields_new(); + let __pair_temp_1: i64; + __pair_temp_1 = "wasi/future-new"(); + trailers_future = builtin::i32_wrap_i64(__pair_temp_1); + trailers_tx = builtin::i32_wrap_i64(__pair_temp_1 >>u 32_i64); + let __sroa___pattern_temp_1_0: i32; + let __sroa___pattern_temp_1_1: i32; + multivalue_bind [__sroa___pattern_temp_1_0, __sroa___pattern_temp_1_1] = __cm_binding__Request_new(headers, Option> { 1 }, trailers_future, Option { 1 }); + out_req = __sroa___pattern_temp_1_0; + drop(__cm_binding__Request_set_scheme(out_req, "wasi:http/types.wado/Scheme" { 0 })); + drop(__cm_binding__Request_set_authority(out_req, String { repr: array.new_data("localhost"), used: 9 })); + drop(__cm_binding__Request_set_path_with_query(out_req, String { repr: array.new_data("/"), used: 1 })); + upstream = __cm_binding__Client_send(out_req); + __tv_1 = 0; + __tv_2 = 0; + __tv_3 = 0_i64; + __tv_4 = 0; + __tv_5 = 0; + __tv_6 = 0; + __tv_7 = 0; + if ref.test Result::Ok(upstream) { + __ok_val = ref.cast Result::Ok(upstream).payload_0; + __tv_1 = __ok_val; + "wasi/task-return"(0, __tv_1, 0, 0_i64, 0, 0, 0, 0); + } else { + __err_val = ref.cast Result::Err(upstream).payload_0; + __tv_1 = __err_val.discriminant; + if ref.test "wasi:http/types.wado/ErrorCode::DnsError"(__err_val) { + __case_payload_19 = ref.cast "wasi:http/types.wado/ErrorCode::DnsError"(__err_val).payload_0; + __opt_val_21 = __case_payload_19.rcode; + __opt_disc_22 = ref.is_null(__opt_val_21) == 0; + __opt_inner_0_23 = 0; + __opt_inner_1_24 = 0; + if __opt_disc_22 != 0 { + __packed_25 = "core:internal/cm_lower_string"(ref.as_non_null(__opt_val_21)); + __ptr_26 = builtin::i32_wrap_i64(__packed_25); + __len_27 = builtin::i32_wrap_i64(__packed_25 >> 32_i64); + __opt_inner_0_23 = __ptr_26; + __opt_inner_1_24 = __len_27; + }; + __opt_val_28 = __case_payload_19.info_code; + __opt_disc_29 = ref.test Option::Some(__opt_val_28); + __opt_inner_0_30 = 0; + if __opt_disc_29 != 0 { + __flat_31 = ref.cast Option::Some(__opt_val_28).payload_0; + __opt_inner_0_30 = __flat_31; + }; + __tv_2 = __opt_disc_22; + __tv_3 = builtin::i64_extend_i32_s(__opt_inner_0_23); + __tv_4 = __opt_inner_1_24; + __tv_5 = __opt_disc_29; + __tv_6 = __opt_inner_0_30; + }; + if ref.test "wasi:http/types.wado/ErrorCode::TlsAlertReceived"(__err_val) { + __case_payload_32 = ref.cast "wasi:http/types.wado/ErrorCode::TlsAlertReceived"(__err_val).payload_0; + __opt_val_34 = __case_payload_32.alert_id; + __opt_disc_35 = ref.test Option::Some(__opt_val_34); + __opt_inner_0_36 = 0; + if __opt_disc_35 != 0 { + __flat_37 = ref.cast Option::Some(__opt_val_34).payload_0; + __opt_inner_0_36 = __flat_37; + }; + __opt_val_38 = __case_payload_32.alert_message; + __opt_disc_39 = ref.is_null(__opt_val_38) == 0; + __opt_inner_0_40 = 0; + __opt_inner_1_41 = 0; + if __opt_disc_39 != 0 { + __packed_42 = "core:internal/cm_lower_string"(ref.as_non_null(__opt_val_38)); + __ptr_43 = builtin::i32_wrap_i64(__packed_42); + __len_44 = builtin::i32_wrap_i64(__packed_42 >> 32_i64); + __opt_inner_0_40 = __ptr_43; + __opt_inner_1_41 = __len_44; + }; + __tv_2 = __opt_disc_35; + __tv_3 = builtin::i64_extend_i32_s(__opt_inner_0_36); + __tv_4 = __opt_disc_39; + __tv_5 = __opt_inner_0_40; + __tv_6 = __opt_inner_1_41; + }; + if ref.test "wasi:http/types.wado/ErrorCode::HttpRequestBodySize"(__err_val) { + __case_payload_45 = value_copy Option(ref.cast "wasi:http/types.wado/ErrorCode::HttpRequestBodySize"(__err_val).payload_0); + __opt_disc_47 = ref.test Option::Some(__case_payload_45); + __opt_inner_0_48 = 0_i64; + if __opt_disc_47 != 0 { + __flat_49 = ref.cast Option::Some(__case_payload_45).payload_0; + __opt_inner_0_48 = __flat_49; + }; + __tv_2 = __opt_disc_47; + __tv_3 = __opt_inner_0_48; + }; + if ref.test "wasi:http/types.wado/ErrorCode::HttpRequestHeaderSectionSize"(__err_val) { + __case_payload_50 = value_copy Option(ref.cast "wasi:http/types.wado/ErrorCode::HttpRequestHeaderSectionSize"(__err_val).payload_0); + __opt_disc_52 = ref.test Option::Some(__case_payload_50); + __opt_inner_0_53 = 0; + if __opt_disc_52 != 0 { + __flat_54 = ref.cast Option::Some(__case_payload_50).payload_0; + __opt_inner_0_53 = __flat_54; + }; + __tv_2 = __opt_disc_52; + __tv_3 = builtin::i64_extend_i32_s(__opt_inner_0_53); + }; + if ref.test "wasi:http/types.wado/ErrorCode::HttpRequestHeaderSize"(__err_val) { + __case_payload_55 = value_copy Option(ref.cast "wasi:http/types.wado/ErrorCode::HttpRequestHeaderSize"(__err_val).payload_0); + __opt_disc_57 = ref.is_null(__case_payload_55) == 0; + __opt_inner_0_58 = 0; + __opt_inner_1_59 = 0; + __opt_inner_2 = 0; + __opt_inner_3 = 0; + __opt_inner_4 = 0; + if __opt_disc_57 != 0 { + __struct_val = ref.as_non_null(__case_payload_55); + __opt_val_64 = __struct_val.field_name; + __opt_disc_65 = ref.is_null(__opt_val_64) == 0; + __opt_inner_0_66 = 0; + __opt_inner_1_67 = 0; + if __opt_disc_65 != 0 { + __packed_68 = "core:internal/cm_lower_string"(ref.as_non_null(__opt_val_64)); + __ptr_69 = builtin::i32_wrap_i64(__packed_68); + __len_70 = builtin::i32_wrap_i64(__packed_68 >> 32_i64); + __opt_inner_0_66 = __ptr_69; + __opt_inner_1_67 = __len_70; + }; + __opt_val_71 = __struct_val.field_size; + __opt_disc_72 = ref.test Option::Some(__opt_val_71); + __opt_inner_0_73 = 0; + if __opt_disc_72 != 0 { + __flat_74 = ref.cast Option::Some(__opt_val_71).payload_0; + __opt_inner_0_73 = __flat_74; + }; + __opt_inner_0_58 = __opt_disc_65; + __opt_inner_1_59 = __opt_inner_0_66; + __opt_inner_2 = __opt_inner_1_67; + __opt_inner_3 = __opt_disc_72; + __opt_inner_4 = __opt_inner_0_73; + }; + __tv_2 = __opt_disc_57; + __tv_3 = builtin::i64_extend_i32_s(__opt_inner_0_58); + __tv_4 = __opt_inner_1_59; + __tv_5 = __opt_inner_2; + __tv_6 = __opt_inner_3; + __tv_7 = __opt_inner_4; + }; + if ref.test "wasi:http/types.wado/ErrorCode::HttpRequestTrailerSectionSize"(__err_val) { + __case_payload_75 = value_copy Option(ref.cast "wasi:http/types.wado/ErrorCode::HttpRequestTrailerSectionSize"(__err_val).payload_0); + __opt_disc_77 = ref.test Option::Some(__case_payload_75); + __opt_inner_0_78 = 0; + if __opt_disc_77 != 0 { + __flat_79 = ref.cast Option::Some(__case_payload_75).payload_0; + __opt_inner_0_78 = __flat_79; + }; + __tv_2 = __opt_disc_77; + __tv_3 = builtin::i64_extend_i32_s(__opt_inner_0_78); + }; + if ref.test "wasi:http/types.wado/ErrorCode::HttpRequestTrailerSize"(__err_val) { + __case_payload_80 = ref.cast "wasi:http/types.wado/ErrorCode::HttpRequestTrailerSize"(__err_val).payload_0; + __opt_val_82 = __case_payload_80.field_name; + __opt_disc_83 = ref.is_null(__opt_val_82) == 0; + __opt_inner_0_84 = 0; + __opt_inner_1_85 = 0; + if __opt_disc_83 != 0 { + __packed_86 = "core:internal/cm_lower_string"(ref.as_non_null(__opt_val_82)); + __ptr_87 = builtin::i32_wrap_i64(__packed_86); + __len_88 = builtin::i32_wrap_i64(__packed_86 >> 32_i64); + __opt_inner_0_84 = __ptr_87; + __opt_inner_1_85 = __len_88; + }; + __opt_val_89 = __case_payload_80.field_size; + __opt_disc_90 = ref.test Option::Some(__opt_val_89); + __opt_inner_0_91 = 0; + if __opt_disc_90 != 0 { + __flat_92 = ref.cast Option::Some(__opt_val_89).payload_0; + __opt_inner_0_91 = __flat_92; + }; + __tv_2 = __opt_disc_83; + __tv_3 = builtin::i64_extend_i32_s(__opt_inner_0_84); + __tv_4 = __opt_inner_1_85; + __tv_5 = __opt_disc_90; + __tv_6 = __opt_inner_0_91; + }; + if ref.test "wasi:http/types.wado/ErrorCode::HttpResponseHeaderSectionSize"(__err_val) { + __case_payload_93 = value_copy Option(ref.cast "wasi:http/types.wado/ErrorCode::HttpResponseHeaderSectionSize"(__err_val).payload_0); + __opt_disc_95 = ref.test Option::Some(__case_payload_93); + __opt_inner_0_96 = 0; + if __opt_disc_95 != 0 { + __flat_97 = ref.cast Option::Some(__case_payload_93).payload_0; + __opt_inner_0_96 = __flat_97; + }; + __tv_2 = __opt_disc_95; + __tv_3 = builtin::i64_extend_i32_s(__opt_inner_0_96); + }; + if ref.test "wasi:http/types.wado/ErrorCode::HttpResponseHeaderSize"(__err_val) { + __case_payload_98 = ref.cast "wasi:http/types.wado/ErrorCode::HttpResponseHeaderSize"(__err_val).payload_0; + __opt_val_100 = __case_payload_98.field_name; + __opt_disc_101 = ref.is_null(__opt_val_100) == 0; + __opt_inner_0_102 = 0; + __opt_inner_1_103 = 0; + if __opt_disc_101 != 0 { + __packed_104 = "core:internal/cm_lower_string"(ref.as_non_null(__opt_val_100)); + __ptr_105 = builtin::i32_wrap_i64(__packed_104); + __len_106 = builtin::i32_wrap_i64(__packed_104 >> 32_i64); + __opt_inner_0_102 = __ptr_105; + __opt_inner_1_103 = __len_106; + }; + __opt_val_107 = __case_payload_98.field_size; + __opt_disc_108 = ref.test Option::Some(__opt_val_107); + __opt_inner_0_109 = 0; + if __opt_disc_108 != 0 { + __flat_110 = ref.cast Option::Some(__opt_val_107).payload_0; + __opt_inner_0_109 = __flat_110; + }; + __tv_2 = __opt_disc_101; + __tv_3 = builtin::i64_extend_i32_s(__opt_inner_0_102); + __tv_4 = __opt_inner_1_103; + __tv_5 = __opt_disc_108; + __tv_6 = __opt_inner_0_109; + }; + if ref.test "wasi:http/types.wado/ErrorCode::HttpResponseBodySize"(__err_val) { + __case_payload_111 = value_copy Option(ref.cast "wasi:http/types.wado/ErrorCode::HttpResponseBodySize"(__err_val).payload_0); + __opt_disc_113 = ref.test Option::Some(__case_payload_111); + __opt_inner_0_114 = 0_i64; + if __opt_disc_113 != 0 { + __flat_115 = ref.cast Option::Some(__case_payload_111).payload_0; + __opt_inner_0_114 = __flat_115; + }; + __tv_2 = __opt_disc_113; + __tv_3 = __opt_inner_0_114; + }; + if ref.test "wasi:http/types.wado/ErrorCode::HttpResponseTrailerSectionSize"(__err_val) { + __case_payload_116 = value_copy Option(ref.cast "wasi:http/types.wado/ErrorCode::HttpResponseTrailerSectionSize"(__err_val).payload_0); + __opt_disc_118 = ref.test Option::Some(__case_payload_116); + __opt_inner_0_119 = 0; + if __opt_disc_118 != 0 { + __flat_120 = ref.cast Option::Some(__case_payload_116).payload_0; + __opt_inner_0_119 = __flat_120; + }; + __tv_2 = __opt_disc_118; + __tv_3 = builtin::i64_extend_i32_s(__opt_inner_0_119); + }; + if ref.test "wasi:http/types.wado/ErrorCode::HttpResponseTrailerSize"(__err_val) { + __case_payload_121 = ref.cast "wasi:http/types.wado/ErrorCode::HttpResponseTrailerSize"(__err_val).payload_0; + __opt_val_123 = __case_payload_121.field_name; + __opt_disc_124 = ref.is_null(__opt_val_123) == 0; + __opt_inner_0_125 = 0; + __opt_inner_1_126 = 0; + if __opt_disc_124 != 0 { + __packed_127 = "core:internal/cm_lower_string"(ref.as_non_null(__opt_val_123)); + __ptr_128 = builtin::i32_wrap_i64(__packed_127); + __len_129 = builtin::i32_wrap_i64(__packed_127 >> 32_i64); + __opt_inner_0_125 = __ptr_128; + __opt_inner_1_126 = __len_129; + }; + __opt_val_130 = __case_payload_121.field_size; + __opt_disc_131 = ref.test Option::Some(__opt_val_130); + __opt_inner_0_132 = 0; + if __opt_disc_131 != 0 { + __flat_133 = ref.cast Option::Some(__opt_val_130).payload_0; + __opt_inner_0_132 = __flat_133; + }; + __tv_2 = __opt_disc_124; + __tv_3 = builtin::i64_extend_i32_s(__opt_inner_0_125); + __tv_4 = __opt_inner_1_126; + __tv_5 = __opt_disc_131; + __tv_6 = __opt_inner_0_132; + }; + if ref.test "wasi:http/types.wado/ErrorCode::HttpResponseTransferCoding"(__err_val) { + __case_payload_134 = value_copy Option(ref.cast "wasi:http/types.wado/ErrorCode::HttpResponseTransferCoding"(__err_val).payload_0); + __opt_disc_136 = ref.is_null(__case_payload_134) == 0; + __opt_inner_0_137 = 0; + __opt_inner_1_138 = 0; + if __opt_disc_136 != 0 { + __packed_139 = "core:internal/cm_lower_string"(ref.as_non_null(__case_payload_134)); + __ptr_140 = builtin::i32_wrap_i64(__packed_139); + __len_141 = builtin::i32_wrap_i64(__packed_139 >> 32_i64); + __opt_inner_0_137 = __ptr_140; + __opt_inner_1_138 = __len_141; + }; + __tv_2 = __opt_disc_136; + __tv_3 = builtin::i64_extend_i32_s(__opt_inner_0_137); + __tv_4 = __opt_inner_1_138; + }; + if ref.test "wasi:http/types.wado/ErrorCode::HttpResponseContentCoding"(__err_val) { + __case_payload_142 = value_copy Option(ref.cast "wasi:http/types.wado/ErrorCode::HttpResponseContentCoding"(__err_val).payload_0); + __opt_disc_144 = ref.is_null(__case_payload_142) == 0; + __opt_inner_0_145 = 0; + __opt_inner_1_146 = 0; + if __opt_disc_144 != 0 { + __packed_147 = "core:internal/cm_lower_string"(ref.as_non_null(__case_payload_142)); + __ptr_148 = builtin::i32_wrap_i64(__packed_147); + __len_149 = builtin::i32_wrap_i64(__packed_147 >> 32_i64); + __opt_inner_0_145 = __ptr_148; + __opt_inner_1_146 = __len_149; + }; + __tv_2 = __opt_disc_144; + __tv_3 = builtin::i64_extend_i32_s(__opt_inner_0_145); + __tv_4 = __opt_inner_1_146; + }; + if ref.test "wasi:http/types.wado/ErrorCode::InternalError"(__err_val) { + __case_payload_150 = value_copy Option(ref.cast "wasi:http/types.wado/ErrorCode::InternalError"(__err_val).payload_0); + __opt_disc_152 = ref.is_null(__case_payload_150) == 0; + __opt_inner_0_153 = 0; + __opt_inner_1_154 = 0; + if __opt_disc_152 != 0 { + __packed_155 = "core:internal/cm_lower_string"(ref.as_non_null(__case_payload_150)); + __ptr_156 = builtin::i32_wrap_i64(__packed_155); + __len_157 = builtin::i32_wrap_i64(__packed_155 >> 32_i64); + __opt_inner_0_153 = __ptr_156; + __opt_inner_1_154 = __len_157; + }; + __tv_2 = __opt_disc_152; + __tv_3 = builtin::i64_extend_i32_s(__opt_inner_0_153); + __tv_4 = __opt_inner_1_154; + }; + "wasi/task-return"(1, __tv_1, __tv_2, __tv_3, __tv_4, __tv_5, __tv_6, __tv_7); + }; + let __fw_write_ptr_2: i32; + let __fw_handle_2: i32; + let __fw_result_2: i32; + __fw_handle_2 = trailers_tx; + __fw_write_ptr_2 = "mem/realloc"(0, 0, 8, 40); + builtin::store_i64(__fw_write_ptr_2, 0_i64); + builtin::store_i64[8](__fw_write_ptr_2, 0_i64); + builtin::store_i64[16](__fw_write_ptr_2, 0_i64); + builtin::store_i64[24](__fw_write_ptr_2, 0_i64); + builtin::store_i64[32](__fw_write_ptr_2, 0_i64); + __fw_result_2 = "wasi/future-write"(__fw_handle_2, __fw_write_ptr_2); + if __fw_result_2 == -1 { + let __fw_evt_2: i32; + __fw_result_2 = "wasi/waitable-set-new"(); + "wasi/waitable-join"(__fw_handle_2, __fw_result_2); + __fw_evt_2 = "mem/realloc"(0, 0, 4, 8); + drop("wasi/waitable-set-wait"(__fw_result_2, __fw_evt_2)); + drop("mem/realloc"(__fw_evt_2, 8, 4, 0)); + }; + drop("mem/realloc"(__fw_write_ptr_2, 40, 8, 0)); +} + +fn __cm_binding__Fields_new() { + return "wasi/wasi:http/Fields::new"(); +} + +fn __cm_binding__Request_new(headers, contents, trailers, options) { + let __contents_disc: i32; + let __contents_inner0: i32; + let __options_disc: i32; + let __options_inner0: i32; + let __outptr: i32; + let __lifted_result_11: i32; + let __lifted_result_12: i32; + __contents_disc = ref.test Option>::Some(contents); + __contents_inner0 = 0; + if ref.test Option>::Some(contents) { + __contents_inner0 = ref.cast Option>::Some(contents).payload_0; + }; + __options_disc = ref.test Option::Some(options); + __options_inner0 = 0; + if ref.test Option::Some(options) { + __options_inner0 = ref.cast Option::Some(options).payload_0; + }; + __outptr = "mem/realloc"(0, 0, 4, 8); + "wasi/wasi:http/Request::new"(headers, __contents_disc, __contents_inner0, trailers, __options_disc, __options_inner0, __outptr); + __lifted_result_11 = builtin::load_i32(__outptr + 0); + __lifted_result_12 = builtin::load_i32(__outptr + 4); + drop("mem/realloc"(__outptr, 8, 4, 0)); + return __lifted_result_11; __lifted_result_12; +} + +fn __cm_binding__Request_set_scheme(self, scheme) { + let __scheme_disc: i32; + let __scheme_inner0: i32; + let __scheme_inner1: i32; + let __scheme_inner2: i32; + let __scheme_s_val: ref "wasi:http/types.wado/Scheme"; + let __scheme_s_p0: i32; + let __scheme_s_p1: i32; + let __scheme_s_c2_packed: i64; + let __disc: i32; + let __result_val: ref Result; + __scheme_disc = ref.is_null(scheme) == 0; + __scheme_inner0 = 0; + __scheme_inner1 = 0; + __scheme_inner2 = 0; + if ref.is_null(scheme) == 0 { + __scheme_s_val = value_copy "wasi:http/types.wado/Scheme"(ref.as_non_null(scheme)); + __scheme_s_p0 = 0; + __scheme_s_p1 = 0; + if ref.test "wasi:http/types.wado/Scheme::Other"(__scheme_s_val) { + __scheme_s_c2_packed = "core:internal/cm_lower_string"(ref.cast "wasi:http/types.wado/Scheme::Other"(__scheme_s_val).payload_0); + __scheme_s_p0 = builtin::i32_wrap_i64(__scheme_s_c2_packed); + __scheme_s_p1 = builtin::i32_wrap_i64(__scheme_s_c2_packed >> 32_i64); + }; + __scheme_inner0 = __scheme_s_val.discriminant; + __scheme_inner1 = __scheme_s_p0; + __scheme_inner2 = __scheme_s_p1; + }; + __disc = "wasi/wasi:http/Request::set_scheme"(self, __scheme_disc, __scheme_inner0, __scheme_inner1, __scheme_inner2); + __result_val = ref.null none; + if __disc == 0 { + __result_val = Result { 0 }; + } else { + __result_val = Result { 1 }; + }; + return __result_val; +} + +fn __cm_binding__Request_set_authority(self, authority) { + let __authority_disc: i32; + let __authority_inner0: i32; + let __authority_inner1: i32; + let __authority_s_packed: i64; + let __disc: i32; + let __result_val: ref Result; + __authority_disc = ref.is_null(authority) == 0; + __authority_inner0 = 0; + __authority_inner1 = 0; + if ref.is_null(authority) == 0 { + __authority_s_packed = "core:internal/cm_lower_string"(ref.as_non_null(authority)); + __authority_inner0 = builtin::i32_wrap_i64(__authority_s_packed); + __authority_inner1 = builtin::i32_wrap_i64(__authority_s_packed >> 32_i64); + }; + __disc = "wasi/wasi:http/Request::set_authority"(self, __authority_disc, __authority_inner0, __authority_inner1); + __result_val = ref.null none; + if __disc == 0 { + __result_val = Result { 0 }; + } else { + __result_val = Result { 1 }; + }; + return __result_val; +} + +fn __cm_binding__Request_set_path_with_query(self, path_with_query) { + let __path_with_query_disc: i32; + let __path_with_query_inner0: i32; + let __path_with_query_inner1: i32; + let __path_with_query_s_packed: i64; + let __disc: i32; + let __result_val: ref Result; + __path_with_query_disc = ref.is_null(path_with_query) == 0; + __path_with_query_inner0 = 0; + __path_with_query_inner1 = 0; + if ref.is_null(path_with_query) == 0 { + __path_with_query_s_packed = "core:internal/cm_lower_string"(ref.as_non_null(path_with_query)); + __path_with_query_inner0 = builtin::i32_wrap_i64(__path_with_query_s_packed); + __path_with_query_inner1 = builtin::i32_wrap_i64(__path_with_query_s_packed >> 32_i64); + }; + __disc = "wasi/wasi:http/Request::set_path_with_query"(self, __path_with_query_disc, __path_with_query_inner0, __path_with_query_inner1); + __result_val = ref.null none; + if __disc == 0 { + __result_val = Result { 0 }; + } else { + __result_val = Result { 1 }; + }; + return __result_val; +} + +fn __cm_binding__Client_send(request) { + let __async_outptr: i32; + let __subtask: i32; + let __disc_3: i32; + let __result_val: ref Result; + let __vdisc: i32; + let __vresult: ref "wasi:http/types.wado/ErrorCode"; + let __disc_7: i32; + let __option_result_8: ref null String; + let __disc_9: i32; + let __option_result_10: ref null String; + let __disc_11: i32; + let __option_result_12: ref null String; + let __disc_13: i32; + let __option_result_14: ref null String; + let __disc_15: i32; + let __option_result_16: ref Option; + let __struct_result_17: ref "wasi:http/types.wado/FieldSizePayload"; + let __disc_18: i32; + let __option_result_19: ref Option; + let __disc_20: i32; + let __option_result_21: ref Option; + let __disc_22: i32; + let __option_result_23: ref null String; + let __disc_24: i32; + let __option_result_25: ref Option; + let __struct_result_26: ref "wasi:http/types.wado/FieldSizePayload"; + let __disc_27: i32; + let __option_result_28: ref Option; + let __disc_29: i32; + let __option_result_30: ref null String; + let __disc_31: i32; + let __option_result_32: ref Option; + let __struct_result_33: ref "wasi:http/types.wado/FieldSizePayload"; + let __disc_34: i32; + let __option_result_35: ref Option; + let __disc_36: i32; + let __option_result_37: ref null "wasi:http/types.wado/FieldSizePayload"; + let __disc_38: i32; + let __option_result_39: ref null String; + let __disc_40: i32; + let __option_result_41: ref Option; + let __struct_result_42: ref "wasi:http/types.wado/FieldSizePayload"; + let __disc_43: i32; + let __option_result_44: ref Option; + let __disc_45: i32; + let __option_result_46: ref Option; + let __disc_47: i32; + let __option_result_48: ref Option; + let __disc_49: i32; + let __option_result_50: ref null String; + let __struct_result_51: ref "wasi:http/types.wado/TlsAlertReceivedPayload"; + let __disc_52: i32; + let __option_result_53: ref null String; + let __disc_54: i32; + let __option_result_55: ref Option; + let __struct_result_56: ref "wasi:http/types.wado/DnsErrorPayload"; + let __local_57: i32; + let __local_58: i32; + let __local_59: ref array; + let __local_60: i32; + let __local_61: i32; + let __local_62: ref array; + let __local_63: i32; + let __local_64: i32; + let __local_65: ref array; + let __local_66: i32; + let __local_67: i32; + let __local_68: ref array; + let __local_69: i32; + let __local_70: i32; + let __local_71: ref array; + let __local_72: i32; + let __local_73: i32; + let __local_74: ref array; + let __local_75: i32; + let __local_76: i32; + let __local_77: ref array; + let __local_78: i32; + let __local_79: i32; + let __local_80: ref array; + let __local_81: i32; + let __local_82: i32; + let __local_83: ref array; + __async_outptr = "mem/realloc"(0, 0, 8, 40); + __subtask = "wasi/wasi:http/Client::send"(request, __async_outptr); + "core:internal/wait_for_subtask"(__subtask); + __disc_3 = builtin::load_u8(__async_outptr); + __result_val = ref.null none; + if __disc_3 == 0 { + __result_val = Result::Ok { discriminant: 0, payload_0: builtin::load_i32(__async_outptr + 8) }; + } else { + __vdisc = builtin::load_u8(__async_outptr + 8); + __vresult = ref.null none; + if __vdisc == 0 { + __vresult = "wasi:http/types.wado/ErrorCode" { 0 }; + } else if __vdisc == 1 { + __disc_52 = builtin::load_u8((__async_outptr + 8) + 8); + __option_result_53 = ref.null none; + if __disc_52 != 0 { + __option_result_53 = ref.as_non_null(__inline_memory_to_gc_string_0: block -> ref String { + __local_57 = builtin::load_i32(((__async_outptr + 8) + 8) + 4); + __local_58 = builtin::load_i32((((__async_outptr + 8) + 8) + 4) + 4); + __local_59 = "core:internal/memory_to_gc_array"(__local_57, __local_58); + break __inline_memory_to_gc_string_0: String { repr: __local_59, used: __local_58 }; + }); + drop("mem/realloc"(builtin::load_i32(((__async_outptr + 8) + 8) + 4), builtin::load_i32((((__async_outptr + 8) + 8) + 4) + 4), 1, 0)); + }; + __disc_54 = builtin::load_u8(((__async_outptr + 8) + 8) + 12); + __option_result_55 = Option { 1 }; + if __disc_54 != 0 { + __option_result_55 = Option::Some { discriminant: 0, payload_0: builtin::load_u16((((__async_outptr + 8) + 8) + 12) + 2) }; + }; + __struct_result_56 = "wasi:http/types.wado/DnsErrorPayload" { rcode: __option_result_53, info_code: __option_result_55 }; + __vresult = "wasi:http/types.wado/ErrorCode::DnsError" { discriminant: 1, payload_0: __struct_result_56 }; + } else if __vdisc == 2 { + __vresult = "wasi:http/types.wado/ErrorCode" { 2 }; + } else if __vdisc == 3 { + __vresult = "wasi:http/types.wado/ErrorCode" { 3 }; + } else if __vdisc == 4 { + __vresult = "wasi:http/types.wado/ErrorCode" { 4 }; + } else if __vdisc == 5 { + __vresult = "wasi:http/types.wado/ErrorCode" { 5 }; + } else if __vdisc == 6 { + __vresult = "wasi:http/types.wado/ErrorCode" { 6 }; + } else if __vdisc == 7 { + __vresult = "wasi:http/types.wado/ErrorCode" { 7 }; + } else if __vdisc == 8 { + __vresult = "wasi:http/types.wado/ErrorCode" { 8 }; + } else if __vdisc == 9 { + __vresult = "wasi:http/types.wado/ErrorCode" { 9 }; + } else if __vdisc == 10 { + __vresult = "wasi:http/types.wado/ErrorCode" { 10 }; + } else if __vdisc == 11 { + __vresult = "wasi:http/types.wado/ErrorCode" { 11 }; + } else if __vdisc == 12 { + __vresult = "wasi:http/types.wado/ErrorCode" { 12 }; + } else if __vdisc == 13 { + __vresult = "wasi:http/types.wado/ErrorCode" { 13 }; + } else if __vdisc == 14 { + __disc_47 = builtin::load_u8((__async_outptr + 8) + 8); + __option_result_48 = Option { 1 }; + if __disc_47 != 0 { + __option_result_48 = Option::Some { discriminant: 0, payload_0: builtin::load_u8(((__async_outptr + 8) + 8) + 1) }; + }; + __disc_49 = builtin::load_u8(((__async_outptr + 8) + 8) + 4); + __option_result_50 = ref.null none; + if __disc_49 != 0 { + __option_result_50 = ref.as_non_null(__inline_memory_to_gc_string_1: block -> ref String { + __local_60 = builtin::load_i32((((__async_outptr + 8) + 8) + 4) + 4); + __local_61 = builtin::load_i32(((((__async_outptr + 8) + 8) + 4) + 4) + 4); + __local_62 = "core:internal/memory_to_gc_array"(__local_60, __local_61); + break __inline_memory_to_gc_string_1: String { repr: __local_62, used: __local_61 }; + }); + drop("mem/realloc"(builtin::load_i32((((__async_outptr + 8) + 8) + 4) + 4), builtin::load_i32(((((__async_outptr + 8) + 8) + 4) + 4) + 4), 1, 0)); + }; + __struct_result_51 = "wasi:http/types.wado/TlsAlertReceivedPayload" { alert_id: __option_result_48, alert_message: __option_result_50 }; + __vresult = "wasi:http/types.wado/ErrorCode::TlsAlertReceived" { discriminant: 14, payload_0: __struct_result_51 }; + } else if __vdisc == 15 { + __vresult = "wasi:http/types.wado/ErrorCode" { 15 }; + } else if __vdisc == 16 { + __vresult = "wasi:http/types.wado/ErrorCode" { 16 }; + } else if __vdisc == 17 { + __disc_45 = builtin::load_u8((__async_outptr + 8) + 8); + __option_result_46 = Option { 1 }; + if __disc_45 != 0 { + __option_result_46 = Option::Some { discriminant: 0, payload_0: builtin::load_i64(((__async_outptr + 8) + 8) + 8) }; + }; + __vresult = "wasi:http/types.wado/ErrorCode::HttpRequestBodySize" { discriminant: 17, payload_0: __option_result_46 }; + } else if __vdisc == 18 { + __vresult = "wasi:http/types.wado/ErrorCode" { 18 }; + } else if __vdisc == 19 { + __vresult = "wasi:http/types.wado/ErrorCode" { 19 }; + } else if __vdisc == 20 { + __vresult = "wasi:http/types.wado/ErrorCode" { 20 }; + } else if __vdisc == 21 { + __disc_43 = builtin::load_u8((__async_outptr + 8) + 8); + __option_result_44 = Option { 1 }; + if __disc_43 != 0 { + __option_result_44 = Option::Some { discriminant: 0, payload_0: builtin::load_i32(((__async_outptr + 8) + 8) + 4) }; + }; + __vresult = "wasi:http/types.wado/ErrorCode::HttpRequestHeaderSectionSize" { discriminant: 21, payload_0: __option_result_44 }; + } else if __vdisc == 22 { + __disc_36 = builtin::load_u8((__async_outptr + 8) + 8); + __option_result_37 = ref.null none; + if __disc_36 != 0 { + __disc_38 = builtin::load_u8(((__async_outptr + 8) + 8) + 4); + __option_result_39 = ref.null none; + if __disc_38 != 0 { + __option_result_39 = ref.as_non_null(__inline_memory_to_gc_string_2: block -> ref String { + __local_63 = builtin::load_i32((((__async_outptr + 8) + 8) + 4) + 4); + __local_64 = builtin::load_i32(((((__async_outptr + 8) + 8) + 4) + 4) + 4); + __local_65 = "core:internal/memory_to_gc_array"(__local_63, __local_64); + break __inline_memory_to_gc_string_2: String { repr: __local_65, used: __local_64 }; + }); + drop("mem/realloc"(builtin::load_i32((((__async_outptr + 8) + 8) + 4) + 4), builtin::load_i32(((((__async_outptr + 8) + 8) + 4) + 4) + 4), 1, 0)); + }; + __disc_40 = builtin::load_u8((((__async_outptr + 8) + 8) + 4) + 12); + __option_result_41 = Option { 1 }; + if __disc_40 != 0 { + __option_result_41 = Option::Some { discriminant: 0, payload_0: builtin::load_i32(((((__async_outptr + 8) + 8) + 4) + 12) + 4) }; + }; + __struct_result_42 = "wasi:http/types.wado/FieldSizePayload" { field_name: __option_result_39, field_size: __option_result_41 }; + __option_result_37 = __struct_result_42; + }; + __vresult = "wasi:http/types.wado/ErrorCode::HttpRequestHeaderSize" { discriminant: 22, payload_0: __option_result_37 }; + } else if __vdisc == 23 { + __disc_34 = builtin::load_u8((__async_outptr + 8) + 8); + __option_result_35 = Option { 1 }; + if __disc_34 != 0 { + __option_result_35 = Option::Some { discriminant: 0, payload_0: builtin::load_i32(((__async_outptr + 8) + 8) + 4) }; + }; + __vresult = "wasi:http/types.wado/ErrorCode::HttpRequestTrailerSectionSize" { discriminant: 23, payload_0: __option_result_35 }; + } else if __vdisc == 24 { + __disc_29 = builtin::load_u8((__async_outptr + 8) + 8); + __option_result_30 = ref.null none; + if __disc_29 != 0 { + __option_result_30 = ref.as_non_null(__inline_memory_to_gc_string_3: block -> ref String { + __local_66 = builtin::load_i32(((__async_outptr + 8) + 8) + 4); + __local_67 = builtin::load_i32((((__async_outptr + 8) + 8) + 4) + 4); + __local_68 = "core:internal/memory_to_gc_array"(__local_66, __local_67); + break __inline_memory_to_gc_string_3: String { repr: __local_68, used: __local_67 }; + }); + drop("mem/realloc"(builtin::load_i32(((__async_outptr + 8) + 8) + 4), builtin::load_i32((((__async_outptr + 8) + 8) + 4) + 4), 1, 0)); + }; + __disc_31 = builtin::load_u8(((__async_outptr + 8) + 8) + 12); + __option_result_32 = Option { 1 }; + if __disc_31 != 0 { + __option_result_32 = Option::Some { discriminant: 0, payload_0: builtin::load_i32((((__async_outptr + 8) + 8) + 12) + 4) }; + }; + __struct_result_33 = "wasi:http/types.wado/FieldSizePayload" { field_name: __option_result_30, field_size: __option_result_32 }; + __vresult = "wasi:http/types.wado/ErrorCode::HttpRequestTrailerSize" { discriminant: 24, payload_0: __struct_result_33 }; + } else if __vdisc == 25 { + __vresult = "wasi:http/types.wado/ErrorCode" { 25 }; + } else if __vdisc == 26 { + __disc_27 = builtin::load_u8((__async_outptr + 8) + 8); + __option_result_28 = Option { 1 }; + if __disc_27 != 0 { + __option_result_28 = Option::Some { discriminant: 0, payload_0: builtin::load_i32(((__async_outptr + 8) + 8) + 4) }; + }; + __vresult = "wasi:http/types.wado/ErrorCode::HttpResponseHeaderSectionSize" { discriminant: 26, payload_0: __option_result_28 }; + } else if __vdisc == 27 { + __disc_22 = builtin::load_u8((__async_outptr + 8) + 8); + __option_result_23 = ref.null none; + if __disc_22 != 0 { + __option_result_23 = ref.as_non_null(__inline_memory_to_gc_string_4: block -> ref String { + __local_69 = builtin::load_i32(((__async_outptr + 8) + 8) + 4); + __local_70 = builtin::load_i32((((__async_outptr + 8) + 8) + 4) + 4); + __local_71 = "core:internal/memory_to_gc_array"(__local_69, __local_70); + break __inline_memory_to_gc_string_4: String { repr: __local_71, used: __local_70 }; + }); + drop("mem/realloc"(builtin::load_i32(((__async_outptr + 8) + 8) + 4), builtin::load_i32((((__async_outptr + 8) + 8) + 4) + 4), 1, 0)); + }; + __disc_24 = builtin::load_u8(((__async_outptr + 8) + 8) + 12); + __option_result_25 = Option { 1 }; + if __disc_24 != 0 { + __option_result_25 = Option::Some { discriminant: 0, payload_0: builtin::load_i32((((__async_outptr + 8) + 8) + 12) + 4) }; + }; + __struct_result_26 = "wasi:http/types.wado/FieldSizePayload" { field_name: __option_result_23, field_size: __option_result_25 }; + __vresult = "wasi:http/types.wado/ErrorCode::HttpResponseHeaderSize" { discriminant: 27, payload_0: __struct_result_26 }; + } else if __vdisc == 28 { + __disc_20 = builtin::load_u8((__async_outptr + 8) + 8); + __option_result_21 = Option { 1 }; + if __disc_20 != 0 { + __option_result_21 = Option::Some { discriminant: 0, payload_0: builtin::load_i64(((__async_outptr + 8) + 8) + 8) }; + }; + __vresult = "wasi:http/types.wado/ErrorCode::HttpResponseBodySize" { discriminant: 28, payload_0: __option_result_21 }; + } else if __vdisc == 29 { + __disc_18 = builtin::load_u8((__async_outptr + 8) + 8); + __option_result_19 = Option { 1 }; + if __disc_18 != 0 { + __option_result_19 = Option::Some { discriminant: 0, payload_0: builtin::load_i32(((__async_outptr + 8) + 8) + 4) }; + }; + __vresult = "wasi:http/types.wado/ErrorCode::HttpResponseTrailerSectionSize" { discriminant: 29, payload_0: __option_result_19 }; + } else if __vdisc == 30 { + __disc_13 = builtin::load_u8((__async_outptr + 8) + 8); + __option_result_14 = ref.null none; + if __disc_13 != 0 { + __option_result_14 = ref.as_non_null(__inline_memory_to_gc_string_5: block -> ref String { + __local_72 = builtin::load_i32(((__async_outptr + 8) + 8) + 4); + __local_73 = builtin::load_i32((((__async_outptr + 8) + 8) + 4) + 4); + __local_74 = "core:internal/memory_to_gc_array"(__local_72, __local_73); + break __inline_memory_to_gc_string_5: String { repr: __local_74, used: __local_73 }; + }); + drop("mem/realloc"(builtin::load_i32(((__async_outptr + 8) + 8) + 4), builtin::load_i32((((__async_outptr + 8) + 8) + 4) + 4), 1, 0)); + }; + __disc_15 = builtin::load_u8(((__async_outptr + 8) + 8) + 12); + __option_result_16 = Option { 1 }; + if __disc_15 != 0 { + __option_result_16 = Option::Some { discriminant: 0, payload_0: builtin::load_i32((((__async_outptr + 8) + 8) + 12) + 4) }; + }; + __struct_result_17 = "wasi:http/types.wado/FieldSizePayload" { field_name: __option_result_14, field_size: __option_result_16 }; + __vresult = "wasi:http/types.wado/ErrorCode::HttpResponseTrailerSize" { discriminant: 30, payload_0: __struct_result_17 }; + } else if __vdisc == 31 { + __disc_11 = builtin::load_u8((__async_outptr + 8) + 8); + __option_result_12 = ref.null none; + if __disc_11 != 0 { + __option_result_12 = ref.as_non_null(__inline_memory_to_gc_string_6: block -> ref String { + __local_75 = builtin::load_i32(((__async_outptr + 8) + 8) + 4); + __local_76 = builtin::load_i32((((__async_outptr + 8) + 8) + 4) + 4); + __local_77 = "core:internal/memory_to_gc_array"(__local_75, __local_76); + break __inline_memory_to_gc_string_6: String { repr: __local_77, used: __local_76 }; + }); + drop("mem/realloc"(builtin::load_i32(((__async_outptr + 8) + 8) + 4), builtin::load_i32((((__async_outptr + 8) + 8) + 4) + 4), 1, 0)); + }; + __vresult = "wasi:http/types.wado/ErrorCode::HttpResponseTransferCoding" { discriminant: 31, payload_0: __option_result_12 }; + } else if __vdisc == 32 { + __disc_9 = builtin::load_u8((__async_outptr + 8) + 8); + __option_result_10 = ref.null none; + if __disc_9 != 0 { + __option_result_10 = ref.as_non_null(__inline_memory_to_gc_string_7: block -> ref String { + __local_78 = builtin::load_i32(((__async_outptr + 8) + 8) + 4); + __local_79 = builtin::load_i32((((__async_outptr + 8) + 8) + 4) + 4); + __local_80 = "core:internal/memory_to_gc_array"(__local_78, __local_79); + break __inline_memory_to_gc_string_7: String { repr: __local_80, used: __local_79 }; + }); + drop("mem/realloc"(builtin::load_i32(((__async_outptr + 8) + 8) + 4), builtin::load_i32((((__async_outptr + 8) + 8) + 4) + 4), 1, 0)); + }; + __vresult = "wasi:http/types.wado/ErrorCode::HttpResponseContentCoding" { discriminant: 32, payload_0: __option_result_10 }; + } else if __vdisc == 33 { + __vresult = "wasi:http/types.wado/ErrorCode" { 33 }; + } else if __vdisc == 34 { + __vresult = "wasi:http/types.wado/ErrorCode" { 34 }; + } else if __vdisc == 35 { + __vresult = "wasi:http/types.wado/ErrorCode" { 35 }; + } else if __vdisc == 36 { + __vresult = "wasi:http/types.wado/ErrorCode" { 36 }; + } else if __vdisc == 37 { + __vresult = "wasi:http/types.wado/ErrorCode" { 37 }; + } else { + __disc_7 = builtin::load_u8((__async_outptr + 8) + 8); + __option_result_8 = ref.null none; + if __disc_7 != 0 { + __option_result_8 = ref.as_non_null(__inline_memory_to_gc_string_8: block -> ref String { + __local_81 = builtin::load_i32(((__async_outptr + 8) + 8) + 4); + __local_82 = builtin::load_i32((((__async_outptr + 8) + 8) + 4) + 4); + __local_83 = "core:internal/memory_to_gc_array"(__local_81, __local_82); + break __inline_memory_to_gc_string_8: String { repr: __local_83, used: __local_82 }; + }); + drop("mem/realloc"(builtin::load_i32(((__async_outptr + 8) + 8) + 4), builtin::load_i32((((__async_outptr + 8) + 8) + 4) + 4), 1, 0)); + }; + __vresult = "wasi:http/types.wado/ErrorCode::InternalError" { discriminant: 38, payload_0: __option_result_8 }; + }; + __result_val = Result::Err { discriminant: 1, payload_0: __vresult }; + }; + drop("mem/realloc"(__async_outptr, 40, 8, 0)); + return __result_val; +} + +fn __cm_export__handle(request) { + handle(request); +} + +fn "core:internal/memory_to_gc_array"(ptr, len) { // from core:internal + let arr: ref array; + let i: i32; + arr = builtin::array_new(len); + __for_0: block { + i = 0; + block { + l110: loop { + if (i < len) == 0 { + break __for_0; + }; + builtin::array_set_u8(arr, i, builtin::load_u8(ptr + i) & 255); + i = i + 1; + continue l110; + }; + }; + }; + return arr; +} + +fn "core:internal/gc_array_to_memory"(arr, ptr, len) { // from core:internal + let i: i32; + __for_1: block { + i = 0; + block { + l113: loop { + if (i < len) == 0 { + break __for_1; + }; + builtin::store_u8(ptr + i, builtin::array_get_u8(arr, i)); + i = i + 1; + continue l113; + }; + }; + }; +} + +fn "core:internal/wait_for_subtask"(packed) { // from core:internal + let handle: i32; + let subtask: i32; + let ws: i32; + let __local_5: i32; + handle = packed >> 4; + if handle != 0 { + subtask = handle; + ws = "wasi/waitable-set-new"(); + drop(__inline_cm_waitable_join_0: block -> i32 { + __local_5 = subtask; + "wasi/waitable-join"(__local_5, ws); + break __inline_cm_waitable_join_0: __local_5; + }); + b116: block { + l117: loop { + let __sroa_event_code: i32; + let __sroa_event_handle: i32; + let __sroa_event_payload: u32; + multivalue_bind [__sroa_event_code, __sroa_event_handle, __sroa_event_payload] = "core:internal/cm_waitable_set_wait"(ws); + if __sroa_event_payload == 2 { + break b116; + }; + continue l117; + }; + }; + "wasi/subtask-drop"(subtask); + "wasi/waitable-set-drop"(ws); + }; +} + +fn "core:internal/cm_lower_string"(s) { // from core:internal + let len: i32; + let bytes: ref array; + let ptr: i32; + len = s.used; + bytes = s.repr; + ptr = "mem/realloc"(0, 0, 1, len); + "core:internal/gc_array_to_memory"(bytes, ptr, len); + return builtin::i64_extend_i32_s(ptr) | (builtin::i64_extend_i32_s(len) << 32_i64); +} + +fn "core:internal/cm_waitable_set_wait"(ws) { // from core:internal + let out_ptr: i32; + let code: i32; + let evt_handle: i32; + let payload: i32; + out_ptr = "mem/realloc"(0, 0, 4, 8); + code = "wasi/waitable-set-wait"(ws, out_ptr); + evt_handle = builtin::load_i32(out_ptr); + payload = builtin::load_i32(out_ptr + 4); + drop("mem/realloc"(out_ptr, 8, 4, 0)); + return code; evt_handle; payload; +} + +export fn __cm_export__handle as "handle" diff --git a/wado-compiler/tests/fixtures.golden/http-echo-headers.wir.wado b/wado-compiler/tests/fixtures.golden/http-echo-headers.wir.wado index 149a97674..6d4672bb3 100644 --- a/wado-compiler/tests/fixtures.golden/http-echo-headers.wir.wado +++ b/wado-compiler/tests/fixtures.golden/http-echo-headers.wir.wado @@ -221,6 +221,16 @@ struct Result::Err { payload_0: ref "wasi:http/types.wado/ErrorCode", } +variant Option> { + Some(i32), + None, +} + +struct Option>::Some { + discriminant: i32, + payload_0: i32, +} + struct Array { // Array with T=u8 mut repr: ref array, mut used: i32, @@ -309,7 +319,7 @@ type "functype/wasi/stream-new" = fn() -> i64; type "functype/wasi/future-drop-readable:transmission-cli" = fn(i32); -type "functype/__cm_binding__Response_new" = fn(i32, i32, i32, i32) -> [i32, i32]; +type "functype/__cm_binding__Response_new" = fn(i32, ref Option>, i32) -> [i32, i32]; import fn realloc from "mem/realloc"; import fn stream-write from "wasi/stream-write"; @@ -493,7 +503,7 @@ fn handle(request) { }; let __sroa___pattern_temp_1_0: i32; let __sroa___pattern_temp_1_1: i32; - multivalue_bind [__sroa___pattern_temp_1_0, __sroa___pattern_temp_1_1] = __cm_binding__Response_new(resp_headers, 0, 0, trailers_future); + multivalue_bind [__sroa___pattern_temp_1_0, __sroa___pattern_temp_1_1] = __cm_binding__Response_new(resp_headers, Option> { 1 }, trailers_future); response = __sroa___pattern_temp_1_0; __task_ret = Result::Ok { discriminant: 0, payload_0: response }; __tv_1 = 0; @@ -947,16 +957,23 @@ fn __cm_binding__Fields_append(self, name, value) { return __result_val; } -fn __cm_binding__Response_new(headers, contents_flat0, contents_flat1, trailers) { +fn __cm_binding__Response_new(headers, contents, trailers) { + let __contents_disc: i32; + let __contents_inner0: i32; let __outptr: i32; - let __lifted_result_5: i32; - let __lifted_result_6: i32; + let __lifted_result_7: i32; + let __lifted_result_8: i32; + __contents_disc = ref.test Option>::Some(contents); + __contents_inner0 = 0; + if ref.test Option>::Some(contents) { + __contents_inner0 = ref.cast Option>::Some(contents).payload_0; + }; __outptr = "mem/realloc"(0, 0, 4, 8); - "wasi/wasi:http/Response::new"(headers, contents_flat0, contents_flat1, trailers, __outptr); - __lifted_result_5 = builtin::load_i32(__outptr + 0); - __lifted_result_6 = builtin::load_i32(__outptr + 4); + "wasi/wasi:http/Response::new"(headers, __contents_disc, __contents_inner0, trailers, __outptr); + __lifted_result_7 = builtin::load_i32(__outptr + 0); + __lifted_result_8 = builtin::load_i32(__outptr + 4); drop("mem/realloc"(__outptr, 8, 4, 0)); - return __lifted_result_5; __lifted_result_6; + return __lifted_result_7; __lifted_result_8; } fn __cm_export__handle(request) { @@ -970,13 +987,13 @@ fn "core:internal/memory_to_gc_array"(ptr, len) { // from core:internal __for_0: block { i = 0; block { - l57: loop { + l58: loop { if (i < len) == 0 { break __for_0; }; builtin::array_set_u8(arr, i, builtin::load_u8(ptr + i) & 255); i = i + 1; - continue l57; + continue l58; }; }; }; @@ -988,13 +1005,13 @@ fn "core:internal/gc_array_to_memory"(arr, ptr, len) { // from core:internal __for_1: block { i = 0; block { - l60: loop { + l61: loop { if (i < len) == 0 { break __for_1; }; builtin::store_u8(ptr + i, builtin::array_get_u8(arr, i)); i = i + 1; - continue l60; + continue l61; }; }; }; @@ -1113,13 +1130,13 @@ fn Array>::grow(self) { __for_0: block { i = 0; block { - l66: loop { + l67: loop { if (i < used) == 0 { break __for_0; }; builtin::array_set>(new_repr, i, builtin::array_get>(old_repr, i)); i = i + 1; - continue l66; + continue l67; }; }; }; @@ -1155,13 +1172,13 @@ fn Array::grow(self) { __for_0: block { i = 0; block { - l70: loop { + l71: loop { if (i < used) == 0 { break __for_0; }; builtin::array_set_u8(new_repr, i, builtin::array_get(old_repr, i)); i = i + 1; - continue l70; + continue l71; }; }; }; diff --git a/wado-compiler/tests/fixtures.golden/http-fields-copy-all.wir.wado b/wado-compiler/tests/fixtures.golden/http-fields-copy-all.wir.wado index b2a5fe0b6..a7caec4c9 100644 --- a/wado-compiler/tests/fixtures.golden/http-fields-copy-all.wir.wado +++ b/wado-compiler/tests/fixtures.golden/http-fields-copy-all.wir.wado @@ -237,6 +237,16 @@ struct Result::Err { payload_0: ref "wasi:http/types.wado/ErrorCode", } +variant Option> { + Some(i32), + None, +} + +struct Option>::Some { + discriminant: i32, + payload_0: i32, +} + struct Array { // Array with T=u8 mut repr: ref array, mut used: i32, @@ -335,7 +345,7 @@ type "functype/wasi/stream-new" = fn() -> i64; type "functype/wasi/future-drop-readable:transmission-cli" = fn(i32); -type "functype/__cm_binding__Response_new" = fn(i32, i32, i32, i32) -> [i32, i32]; +type "functype/__cm_binding__Response_new" = fn(i32, ref Option>, i32) -> [i32, i32]; type "functype/i32::fmt_decimal" = fn(i32, ref Formatter); @@ -559,7 +569,7 @@ condition: all.len() == 2 trailers_tx = builtin::i32_wrap_i64(__pair_temp_1 >>u 32_i64); let __sroa___pattern_temp_1_0: i32; let __sroa___pattern_temp_1_1: i32; - multivalue_bind [__sroa___pattern_temp_1_0, __sroa___pattern_temp_1_1] = __cm_binding__Response_new(fields, 0, 0, trailers_future); + multivalue_bind [__sroa___pattern_temp_1_0, __sroa___pattern_temp_1_1] = __cm_binding__Response_new(fields, Option> { 1 }, trailers_future); response = __sroa___pattern_temp_1_0; __task_ret = Result::Ok { discriminant: 0, payload_0: response }; __tv_1 = 0; @@ -1012,16 +1022,23 @@ fn __cm_binding__Fields_copy_all(self) { return __result_4; } -fn __cm_binding__Response_new(headers, contents_flat0, contents_flat1, trailers) { +fn __cm_binding__Response_new(headers, contents, trailers) { + let __contents_disc: i32; + let __contents_inner0: i32; let __outptr: i32; - let __lifted_result_5: i32; - let __lifted_result_6: i32; + let __lifted_result_7: i32; + let __lifted_result_8: i32; + __contents_disc = ref.test Option>::Some(contents); + __contents_inner0 = 0; + if ref.test Option>::Some(contents) { + __contents_inner0 = ref.cast Option>::Some(contents).payload_0; + }; __outptr = "mem/realloc"(0, 0, 4, 8); - "wasi/wasi:http/Response::new"(headers, contents_flat0, contents_flat1, trailers, __outptr); - __lifted_result_5 = builtin::load_i32(__outptr + 0); - __lifted_result_6 = builtin::load_i32(__outptr + 4); + "wasi/wasi:http/Response::new"(headers, __contents_disc, __contents_inner0, trailers, __outptr); + __lifted_result_7 = builtin::load_i32(__outptr + 0); + __lifted_result_8 = builtin::load_i32(__outptr + 4); drop("mem/realloc"(__outptr, 8, 4, 0)); - return __lifted_result_5; __lifted_result_6; + return __lifted_result_7; __lifted_result_8; } fn __cm_export__handle(request) { @@ -1035,13 +1052,13 @@ fn "core:internal/memory_to_gc_array"(ptr, len) { // from core:internal __for_0: block { i = 0; block { - l55: loop { + l56: loop { if (i < len) == 0 { break __for_0; }; builtin::array_set_u8(arr, i, builtin::load_u8(ptr + i) & 255); i = i + 1; - continue l55; + continue l56; }; }; }; @@ -1053,13 +1070,13 @@ fn "core:internal/gc_array_to_memory"(arr, ptr, len) { // from core:internal __for_1: block { i = 0; block { - l58: loop { + l59: loop { if (i < len) == 0 { break __for_1; }; builtin::store_u8(ptr + i, builtin::array_get_u8(arr, i)); i = i + 1; - continue l58; + continue l59; }; }; }; @@ -1159,13 +1176,13 @@ fn count_digits_i64(val) { __for_1: block { t = val; block { - l64: loop { + l65: loop { if (t > 0_i64) == 0 { break __for_1; }; n = n + 1; t = t / 10_i64; - continue l64; + continue l65; }; }; }; @@ -1182,14 +1199,14 @@ fn write_decimal_digits(arr, offset, abs_val, digit_count) { __for_2: block { temp = abs_val; block { - l68: loop { + l69: loop { if (temp > 0_i64) == 0 { break __for_2; }; pos = pos - 1; builtin::array_set_u8(arr, pos, (48 + builtin::i32_wrap_i64(temp % 10_i64)) & 255); temp = temp / 10_i64; - continue l68; + continue l69; }; }; }; @@ -1321,13 +1338,13 @@ fn Array>>::grow(self) { __for_0: block { i = 0; block { - l81: loop { + l82: loop { if (i < used) == 0 { break __for_0; }; builtin::array_set]">(new_repr, i, builtin::array_get]">(old_repr, i)); i = i + 1; - continue l81; + continue l82; }; }; }; @@ -1363,13 +1380,13 @@ fn Array::grow(self) { __for_0: block { i = 0; block { - l85: loop { + l86: loop { if (i < used) == 0 { break __for_0; }; builtin::array_set_u8(new_repr, i, builtin::array_get(old_repr, i)); i = i + 1; - continue l85; + continue l86; }; }; }; @@ -1383,13 +1400,13 @@ fn Formatter::write_char_n(self, c, n) { i = 0; _licm_buf_4 = self.buf; block { - l88: loop { + l89: loop { if (i < n) == 0 { break __for_0; }; String::push(_licm_buf_4, c); i = i + 1; - continue l88; + continue l89; }; }; }; diff --git a/wado-compiler/tests/fixtures.golden/http-fields-from-list.wir.wado b/wado-compiler/tests/fixtures.golden/http-fields-from-list.wir.wado index 4faa797a6..94051f6b7 100644 --- a/wado-compiler/tests/fixtures.golden/http-fields-from-list.wir.wado +++ b/wado-compiler/tests/fixtures.golden/http-fields-from-list.wir.wado @@ -252,6 +252,16 @@ struct Result::Err { payload_0: ref "wasi:http/types.wado/HeaderError", } +variant Option> { + Some(i32), + None, +} + +struct Option>::Some { + discriminant: i32, + payload_0: i32, +} + struct Array { // Array with T=u8 mut repr: ref array, mut used: i32, @@ -352,7 +362,7 @@ type "functype/wasi/stream-new" = fn() -> i64; type "functype/wasi/future-drop-readable:transmission-cli" = fn(i32); -type "functype/__cm_binding__Response_new" = fn(i32, i32, i32, i32) -> [i32, i32]; +type "functype/__cm_binding__Response_new" = fn(i32, ref Option>, i32) -> [i32, i32]; type "functype/i32::fmt_decimal" = fn(i32, ref Formatter); @@ -583,7 +593,7 @@ condition: fields.has(\"x-one\" as FieldName) headers = __cm_binding__Fields_new(); let __sroa___pattern_temp_2_0: i32; let __sroa___pattern_temp_2_1: i32; - multivalue_bind [__sroa___pattern_temp_2_0, __sroa___pattern_temp_2_1] = __cm_binding__Response_new(headers, 0, 0, trailers_future); + multivalue_bind [__sroa___pattern_temp_2_0, __sroa___pattern_temp_2_1] = __cm_binding__Response_new(headers, Option> { 1 }, trailers_future); response = __sroa___pattern_temp_2_0; __task_ret = Result::Ok { discriminant: 0, payload_0: response }; __tv_1 = 0; @@ -1012,16 +1022,23 @@ fn __cm_binding__Fields_new() { return "wasi/wasi:http/Fields::new"(); } -fn __cm_binding__Response_new(headers, contents_flat0, contents_flat1, trailers) { +fn __cm_binding__Response_new(headers, contents, trailers) { + let __contents_disc: i32; + let __contents_inner0: i32; let __outptr: i32; - let __lifted_result_5: i32; - let __lifted_result_6: i32; + let __lifted_result_7: i32; + let __lifted_result_8: i32; + __contents_disc = ref.test Option>::Some(contents); + __contents_inner0 = 0; + if ref.test Option>::Some(contents) { + __contents_inner0 = ref.cast Option>::Some(contents).payload_0; + }; __outptr = "mem/realloc"(0, 0, 4, 8); - "wasi/wasi:http/Response::new"(headers, contents_flat0, contents_flat1, trailers, __outptr); - __lifted_result_5 = builtin::load_i32(__outptr + 0); - __lifted_result_6 = builtin::load_i32(__outptr + 4); + "wasi/wasi:http/Response::new"(headers, __contents_disc, __contents_inner0, trailers, __outptr); + __lifted_result_7 = builtin::load_i32(__outptr + 0); + __lifted_result_8 = builtin::load_i32(__outptr + 4); drop("mem/realloc"(__outptr, 8, 4, 0)); - return __lifted_result_5; __lifted_result_6; + return __lifted_result_7; __lifted_result_8; } fn __cm_export__handle(request) { @@ -1035,13 +1052,13 @@ fn "core:internal/memory_to_gc_array"(ptr, len) { // from core:internal __for_0: block { i = 0; block { - l53: loop { + l54: loop { if (i < len) == 0 { break __for_0; }; builtin::array_set_u8(arr, i, builtin::load_u8(ptr + i) & 255); i = i + 1; - continue l53; + continue l54; }; }; }; @@ -1053,13 +1070,13 @@ fn "core:internal/gc_array_to_memory"(arr, ptr, len) { // from core:internal __for_1: block { i = 0; block { - l56: loop { + l57: loop { if (i < len) == 0 { break __for_1; }; builtin::store_u8(ptr + i, builtin::array_get_u8(arr, i)); i = i + 1; - continue l56; + continue l57; }; }; }; @@ -1159,13 +1176,13 @@ fn count_digits_i64(val) { __for_1: block { t = val; block { - l62: loop { + l63: loop { if (t > 0_i64) == 0 { break __for_1; }; n = n + 1; t = t / 10_i64; - continue l62; + continue l63; }; }; }; @@ -1182,14 +1199,14 @@ fn write_decimal_digits(arr, offset, abs_val, digit_count) { __for_2: block { temp = abs_val; block { - l66: loop { + l67: loop { if (temp > 0_i64) == 0 { break __for_2; }; pos = pos - 1; builtin::array_set_u8(arr, pos, (48 + builtin::i32_wrap_i64(temp % 10_i64)) & 255); temp = temp / 10_i64; - continue l66; + continue l67; }; }; }; @@ -1321,13 +1338,13 @@ fn Array>>::grow(self) { __for_0: block { i = 0; block { - l79: loop { + l80: loop { if (i < used) == 0 { break __for_0; }; builtin::array_set]">(new_repr, i, builtin::array_get]">(old_repr, i)); i = i + 1; - continue l79; + continue l80; }; }; }; @@ -1363,13 +1380,13 @@ fn Array::grow(self) { __for_0: block { i = 0; block { - l83: loop { + l84: loop { if (i < used) == 0 { break __for_0; }; builtin::array_set_u8(new_repr, i, builtin::array_get(old_repr, i)); i = i + 1; - continue l83; + continue l84; }; }; }; @@ -1383,13 +1400,13 @@ fn Formatter::write_char_n(self, c, n) { i = 0; _licm_buf_4 = self.buf; block { - l86: loop { + l87: loop { if (i < n) == 0 { break __for_0; }; String::push(_licm_buf_4, c); i = i + 1; - continue l86; + continue l87; }; }; }; diff --git a/wado-compiler/tests/fixtures.golden/http-fields-get-and-delete.wir.wado b/wado-compiler/tests/fixtures.golden/http-fields-get-and-delete.wir.wado index 03a15743a..6523d4588 100644 --- a/wado-compiler/tests/fixtures.golden/http-fields-get-and-delete.wir.wado +++ b/wado-compiler/tests/fixtures.golden/http-fields-get-and-delete.wir.wado @@ -232,6 +232,16 @@ struct Result::Err { payload_0: ref "wasi:http/types.wado/ErrorCode", } +variant Option> { + Some(i32), + None, +} + +struct Option>::Some { + discriminant: i32, + payload_0: i32, +} + struct Array { // Array with T=u8 mut repr: ref array, mut used: i32, @@ -351,7 +361,7 @@ type "functype/wasi/stream-new" = fn() -> i64; type "functype/wasi/future-drop-readable:transmission-cli" = fn(i32); -type "functype/__cm_binding__Response_new" = fn(i32, i32, i32, i32) -> [i32, i32]; +type "functype/__cm_binding__Response_new" = fn(i32, ref Option>, i32) -> [i32, i32]; type "functype/i32::fmt_decimal" = fn(i32, ref Formatter); @@ -662,7 +672,7 @@ condition: !fields.has(\"x-temp\" as FieldName) resp_headers = __cm_binding__Fields_new(); let __sroa___pattern_temp_2_0: i32; let __sroa___pattern_temp_2_1: i32; - multivalue_bind [__sroa___pattern_temp_2_0, __sroa___pattern_temp_2_1] = __cm_binding__Response_new(resp_headers, 0, 0, trailers_future); + multivalue_bind [__sroa___pattern_temp_2_0, __sroa___pattern_temp_2_1] = __cm_binding__Response_new(resp_headers, Option> { 1 }, trailers_future); response = __sroa___pattern_temp_2_0; __task_ret = Result::Ok { discriminant: 0, payload_0: response }; __tv_1 = 0; @@ -1152,16 +1162,23 @@ fn __cm_binding__Fields_get_and_delete(self, name) { return __result_val; } -fn __cm_binding__Response_new(headers, contents_flat0, contents_flat1, trailers) { +fn __cm_binding__Response_new(headers, contents, trailers) { + let __contents_disc: i32; + let __contents_inner0: i32; let __outptr: i32; - let __lifted_result_5: i32; - let __lifted_result_6: i32; + let __lifted_result_7: i32; + let __lifted_result_8: i32; + __contents_disc = ref.test Option>::Some(contents); + __contents_inner0 = 0; + if ref.test Option>::Some(contents) { + __contents_inner0 = ref.cast Option>::Some(contents).payload_0; + }; __outptr = "mem/realloc"(0, 0, 4, 8); - "wasi/wasi:http/Response::new"(headers, contents_flat0, contents_flat1, trailers, __outptr); - __lifted_result_5 = builtin::load_i32(__outptr + 0); - __lifted_result_6 = builtin::load_i32(__outptr + 4); + "wasi/wasi:http/Response::new"(headers, __contents_disc, __contents_inner0, trailers, __outptr); + __lifted_result_7 = builtin::load_i32(__outptr + 0); + __lifted_result_8 = builtin::load_i32(__outptr + 4); drop("mem/realloc"(__outptr, 8, 4, 0)); - return __lifted_result_5; __lifted_result_6; + return __lifted_result_7; __lifted_result_8; } fn __cm_export__handle(request) { @@ -1175,13 +1192,13 @@ fn "core:internal/memory_to_gc_array"(ptr, len) { // from core:internal __for_0: block { i = 0; block { - l66: loop { + l67: loop { if (i < len) == 0 { break __for_0; }; builtin::array_set_u8(arr, i, builtin::load_u8(ptr + i) & 255); i = i + 1; - continue l66; + continue l67; }; }; }; @@ -1193,13 +1210,13 @@ fn "core:internal/gc_array_to_memory"(arr, ptr, len) { // from core:internal __for_1: block { i = 0; block { - l69: loop { + l70: loop { if (i < len) == 0 { break __for_1; }; builtin::store_u8(ptr + i, builtin::array_get_u8(arr, i)); i = i + 1; - continue l69; + continue l70; }; }; }; @@ -1299,13 +1316,13 @@ fn count_digits_i64(val) { __for_1: block { t = val; block { - l75: loop { + l76: loop { if (t > 0_i64) == 0 { break __for_1; }; n = n + 1; t = t / 10_i64; - continue l75; + continue l76; }; }; }; @@ -1322,14 +1339,14 @@ fn write_decimal_digits(arr, offset, abs_val, digit_count) { __for_2: block { temp = abs_val; block { - l79: loop { + l80: loop { if (temp > 0_i64) == 0 { break __for_2; }; pos = pos - 1; builtin::array_set_u8(arr, pos, (48 + builtin::i32_wrap_i64(temp % 10_i64)) & 255); temp = temp / 10_i64; - continue l79; + continue l80; }; }; }; @@ -1461,13 +1478,13 @@ fn Array>::grow(self) { __for_0: block { i = 0; block { - l92: loop { + l93: loop { if (i < used) == 0 { break __for_0; }; builtin::array_set>(new_repr, i, builtin::array_get>(old_repr, i)); i = i + 1; - continue l92; + continue l93; }; }; }; @@ -1503,13 +1520,13 @@ fn Array::grow(self) { __for_0: block { i = 0; block { - l96: loop { + l97: loop { if (i < used) == 0 { break __for_0; }; builtin::array_set_u8(new_repr, i, builtin::array_get(old_repr, i)); i = i + 1; - continue l96; + continue l97; }; }; }; @@ -1523,13 +1540,13 @@ fn Formatter::write_char_n(self, c, n) { i = 0; _licm_buf_4 = self.buf; block { - l99: loop { + l100: loop { if (i < n) == 0 { break __for_0; }; String::push(_licm_buf_4, c); i = i + 1; - continue l99; + continue l100; }; }; }; diff --git a/wado-compiler/tests/fixtures.golden/http-fields-set.wir.wado b/wado-compiler/tests/fixtures.golden/http-fields-set.wir.wado index eae690354..1b86e2a95 100644 --- a/wado-compiler/tests/fixtures.golden/http-fields-set.wir.wado +++ b/wado-compiler/tests/fixtures.golden/http-fields-set.wir.wado @@ -232,6 +232,16 @@ struct Result::Err { payload_0: ref "wasi:http/types.wado/ErrorCode", } +variant Option> { + Some(i32), + None, +} + +struct Option>::Some { + discriminant: i32, + payload_0: i32, +} + struct Array { // Array with T=u8 mut repr: ref array, mut used: i32, @@ -340,7 +350,7 @@ type "functype/wasi/stream-new" = fn() -> i64; type "functype/wasi/future-drop-readable:transmission-cli" = fn(i32); -type "functype/__cm_binding__Response_new" = fn(i32, i32, i32, i32) -> [i32, i32]; +type "functype/__cm_binding__Response_new" = fn(i32, ref Option>, i32) -> [i32, i32]; type "functype/i32::fmt_decimal" = fn(i32, ref Formatter); @@ -618,7 +628,7 @@ condition: got.len() == 1 trailers_tx = builtin::i32_wrap_i64(__pair_temp_1 >>u 32_i64); let __sroa___pattern_temp_2_0: i32; let __sroa___pattern_temp_2_1: i32; - multivalue_bind [__sroa___pattern_temp_2_0, __sroa___pattern_temp_2_1] = __cm_binding__Response_new(fields, 0, 0, trailers_future); + multivalue_bind [__sroa___pattern_temp_2_0, __sroa___pattern_temp_2_1] = __cm_binding__Response_new(fields, Option> { 1 }, trailers_future); response = __sroa___pattern_temp_2_0; __task_ret = Result::Ok { discriminant: 0, payload_0: response }; __tv_1 = 0; @@ -1157,16 +1167,23 @@ fn __cm_binding__Fields_get(self, name) { return __result_6; } -fn __cm_binding__Response_new(headers, contents_flat0, contents_flat1, trailers) { +fn __cm_binding__Response_new(headers, contents, trailers) { + let __contents_disc: i32; + let __contents_inner0: i32; let __outptr: i32; - let __lifted_result_5: i32; - let __lifted_result_6: i32; + let __lifted_result_7: i32; + let __lifted_result_8: i32; + __contents_disc = ref.test Option>::Some(contents); + __contents_inner0 = 0; + if ref.test Option>::Some(contents) { + __contents_inner0 = ref.cast Option>::Some(contents).payload_0; + }; __outptr = "mem/realloc"(0, 0, 4, 8); - "wasi/wasi:http/Response::new"(headers, contents_flat0, contents_flat1, trailers, __outptr); - __lifted_result_5 = builtin::load_i32(__outptr + 0); - __lifted_result_6 = builtin::load_i32(__outptr + 4); + "wasi/wasi:http/Response::new"(headers, __contents_disc, __contents_inner0, trailers, __outptr); + __lifted_result_7 = builtin::load_i32(__outptr + 0); + __lifted_result_8 = builtin::load_i32(__outptr + 4); drop("mem/realloc"(__outptr, 8, 4, 0)); - return __lifted_result_5; __lifted_result_6; + return __lifted_result_7; __lifted_result_8; } fn __cm_export__handle(request) { @@ -1180,13 +1197,13 @@ fn "core:internal/memory_to_gc_array"(ptr, len) { // from core:internal __for_0: block { i = 0; block { - l68: loop { + l69: loop { if (i < len) == 0 { break __for_0; }; builtin::array_set_u8(arr, i, builtin::load_u8(ptr + i) & 255); i = i + 1; - continue l68; + continue l69; }; }; }; @@ -1198,13 +1215,13 @@ fn "core:internal/gc_array_to_memory"(arr, ptr, len) { // from core:internal __for_1: block { i = 0; block { - l71: loop { + l72: loop { if (i < len) == 0 { break __for_1; }; builtin::store_u8(ptr + i, builtin::array_get_u8(arr, i)); i = i + 1; - continue l71; + continue l72; }; }; }; @@ -1304,13 +1321,13 @@ fn count_digits_i64(val) { __for_1: block { t = val; block { - l77: loop { + l78: loop { if (t > 0_i64) == 0 { break __for_1; }; n = n + 1; t = t / 10_i64; - continue l77; + continue l78; }; }; }; @@ -1327,14 +1344,14 @@ fn write_decimal_digits(arr, offset, abs_val, digit_count) { __for_2: block { temp = abs_val; block { - l81: loop { + l82: loop { if (temp > 0_i64) == 0 { break __for_2; }; pos = pos - 1; builtin::array_set_u8(arr, pos, (48 + builtin::i32_wrap_i64(temp % 10_i64)) & 255); temp = temp / 10_i64; - continue l81; + continue l82; }; }; }; @@ -1466,13 +1483,13 @@ fn Array>::grow(self) { __for_0: block { i = 0; block { - l94: loop { + l95: loop { if (i < used) == 0 { break __for_0; }; builtin::array_set>(new_repr, i, builtin::array_get>(old_repr, i)); i = i + 1; - continue l94; + continue l95; }; }; }; @@ -1508,13 +1525,13 @@ fn Array::grow(self) { __for_0: block { i = 0; block { - l98: loop { + l99: loop { if (i < used) == 0 { break __for_0; }; builtin::array_set_u8(new_repr, i, builtin::array_get(old_repr, i)); i = i + 1; - continue l98; + continue l99; }; }; }; @@ -1528,13 +1545,13 @@ fn Formatter::write_char_n(self, c, n) { i = 0; _licm_buf_4 = self.buf; block { - l101: loop { + l102: loop { if (i < n) == 0 { break __for_0; }; String::push(_licm_buf_4, c); i = i + 1; - continue l101; + continue l102; }; }; }; diff --git a/wado-compiler/tests/fixtures.golden/http-fields.wir.wado b/wado-compiler/tests/fixtures.golden/http-fields.wir.wado index afef4441d..bd2c5b7ca 100644 --- a/wado-compiler/tests/fixtures.golden/http-fields.wir.wado +++ b/wado-compiler/tests/fixtures.golden/http-fields.wir.wado @@ -230,6 +230,16 @@ struct Result::Err { payload_0: ref "wasi:http/types.wado/ErrorCode", } +variant Option> { + Some(i32), + None, +} + +struct Option>::Some { + discriminant: i32, + payload_0: i32, +} + struct Array { // Array with T=u8 mut repr: ref array, mut used: i32, @@ -329,7 +339,7 @@ type "functype/wasi/stream-new" = fn() -> i64; type "functype/wasi/future-drop-readable:transmission-cli" = fn(i32); -type "functype/__cm_binding__Response_new" = fn(i32, i32, i32, i32) -> [i32, i32]; +type "functype/__cm_binding__Response_new" = fn(i32, ref Option>, i32) -> [i32, i32]; type "functype/i32::fmt_decimal" = fn(i32, ref Formatter); @@ -733,7 +743,7 @@ condition: cloned_still_has response_headers = __cm_binding__Fields_new(); let __sroa___pattern_temp_3_0: i32; let __sroa___pattern_temp_3_1: i32; - multivalue_bind [__sroa___pattern_temp_3_0, __sroa___pattern_temp_3_1] = __cm_binding__Response_new(response_headers, 0, 0, trailers_future); + multivalue_bind [__sroa___pattern_temp_3_0, __sroa___pattern_temp_3_1] = __cm_binding__Response_new(response_headers, Option> { 1 }, trailers_future); response = __sroa___pattern_temp_3_0; __task_ret = Result::Ok { discriminant: 0, payload_0: response }; __tv_1 = 0; @@ -1181,16 +1191,23 @@ fn __cm_binding__Fields_delete(self, name) { return __result_val; } -fn __cm_binding__Response_new(headers, contents_flat0, contents_flat1, trailers) { +fn __cm_binding__Response_new(headers, contents, trailers) { + let __contents_disc: i32; + let __contents_inner0: i32; let __outptr: i32; - let __lifted_result_5: i32; - let __lifted_result_6: i32; + let __lifted_result_7: i32; + let __lifted_result_8: i32; + __contents_disc = ref.test Option>::Some(contents); + __contents_inner0 = 0; + if ref.test Option>::Some(contents) { + __contents_inner0 = ref.cast Option>::Some(contents).payload_0; + }; __outptr = "mem/realloc"(0, 0, 4, 8); - "wasi/wasi:http/Response::new"(headers, contents_flat0, contents_flat1, trailers, __outptr); - __lifted_result_5 = builtin::load_i32(__outptr + 0); - __lifted_result_6 = builtin::load_i32(__outptr + 4); + "wasi/wasi:http/Response::new"(headers, __contents_disc, __contents_inner0, trailers, __outptr); + __lifted_result_7 = builtin::load_i32(__outptr + 0); + __lifted_result_8 = builtin::load_i32(__outptr + 4); drop("mem/realloc"(__outptr, 8, 4, 0)); - return __lifted_result_5; __lifted_result_6; + return __lifted_result_7; __lifted_result_8; } fn __cm_export__handle(request) { @@ -1204,13 +1221,13 @@ fn "core:internal/memory_to_gc_array"(ptr, len) { // from core:internal __for_0: block { i = 0; block { - l64: loop { + l65: loop { if (i < len) == 0 { break __for_0; }; builtin::array_set_u8(arr, i, builtin::load_u8(ptr + i) & 255); i = i + 1; - continue l64; + continue l65; }; }; }; @@ -1222,13 +1239,13 @@ fn "core:internal/gc_array_to_memory"(arr, ptr, len) { // from core:internal __for_1: block { i = 0; block { - l67: loop { + l68: loop { if (i < len) == 0 { break __for_1; }; builtin::store_u8(ptr + i, builtin::array_get_u8(arr, i)); i = i + 1; - continue l67; + continue l68; }; }; }; @@ -1328,13 +1345,13 @@ fn count_digits_i64(val) { __for_1: block { t = val; block { - l73: loop { + l74: loop { if (t > 0_i64) == 0 { break __for_1; }; n = n + 1; t = t / 10_i64; - continue l73; + continue l74; }; }; }; @@ -1351,14 +1368,14 @@ fn write_decimal_digits(arr, offset, abs_val, digit_count) { __for_2: block { temp = abs_val; block { - l77: loop { + l78: loop { if (temp > 0_i64) == 0 { break __for_2; }; pos = pos - 1; builtin::array_set_u8(arr, pos, (48 + builtin::i32_wrap_i64(temp % 10_i64)) & 255); temp = temp / 10_i64; - continue l77; + continue l78; }; }; }; @@ -1490,13 +1507,13 @@ fn Array::grow(self) { __for_0: block { i = 0; block { - l90: loop { + l91: loop { if (i < used) == 0 { break __for_0; }; builtin::array_set_u8(new_repr, i, builtin::array_get(old_repr, i)); i = i + 1; - continue l90; + continue l91; }; }; }; @@ -1510,13 +1527,13 @@ fn Formatter::write_char_n(self, c, n) { i = 0; _licm_buf_4 = self.buf; block { - l93: loop { + l94: loop { if (i < n) == 0 { break __for_0; }; String::push(_licm_buf_4, c); i = i + 1; - continue l93; + continue l94; }; }; }; diff --git a/wado-compiler/tests/fixtures.golden/http-future-new.wir.wado b/wado-compiler/tests/fixtures.golden/http-future-new.wir.wado index aef72e515..19f26b37e 100644 --- a/wado-compiler/tests/fixtures.golden/http-future-new.wir.wado +++ b/wado-compiler/tests/fixtures.golden/http-future-new.wir.wado @@ -206,6 +206,16 @@ struct Result::Err { payload_0: ref "wasi:http/types.wado/ErrorCode", } +variant Option> { + Some(i32), + None, +} + +struct Option>::Some { + discriminant: i32, + payload_0: i32, +} + type "functype/mem/realloc" = fn(i32, i32, i32, i32) -> i32; type "functype/wasi/task-return" = fn(i32, i32, i32, i64, i32, i32, i32, i32); @@ -234,7 +244,7 @@ type "functype/wasi/waitable-join" = fn(i32, i32); type "functype/wasi/waitable-set-wait" = fn(i32, i32) -> i32; -type "functype/__cm_binding__Response_new" = fn(i32, i32, i32, i32) -> [i32, i32]; +type "functype/__cm_binding__Response_new" = fn(i32, ref Option>, i32) -> [i32, i32]; import fn realloc from "mem/realloc"; import fn task-return from "wasi/task-return"; @@ -394,7 +404,7 @@ fn handle(request) { headers = __cm_binding__Fields_new(); let __sroa___pattern_temp_2_0: i32; let __sroa___pattern_temp_2_1: i32; - multivalue_bind [__sroa___pattern_temp_2_0, __sroa___pattern_temp_2_1] = __cm_binding__Response_new(headers, 0, 0, trailers_future); + multivalue_bind [__sroa___pattern_temp_2_0, __sroa___pattern_temp_2_1] = __cm_binding__Response_new(headers, Option> { 1 }, trailers_future); response = __sroa___pattern_temp_2_0; __task_ret = Result::Ok { discriminant: 0, payload_0: response }; __tv_1 = 0; @@ -724,16 +734,23 @@ fn __cm_binding__Fields_new() { return "wasi/wasi:http/Fields::new"(); } -fn __cm_binding__Response_new(headers, contents_flat0, contents_flat1, trailers) { +fn __cm_binding__Response_new(headers, contents, trailers) { + let __contents_disc: i32; + let __contents_inner0: i32; let __outptr: i32; - let __lifted_result_5: i32; - let __lifted_result_6: i32; + let __lifted_result_7: i32; + let __lifted_result_8: i32; + __contents_disc = ref.test Option>::Some(contents); + __contents_inner0 = 0; + if ref.test Option>::Some(contents) { + __contents_inner0 = ref.cast Option>::Some(contents).payload_0; + }; __outptr = "mem/realloc"(0, 0, 4, 8); - "wasi/wasi:http/Response::new"(headers, contents_flat0, contents_flat1, trailers, __outptr); - __lifted_result_5 = builtin::load_i32(__outptr + 0); - __lifted_result_6 = builtin::load_i32(__outptr + 4); + "wasi/wasi:http/Response::new"(headers, __contents_disc, __contents_inner0, trailers, __outptr); + __lifted_result_7 = builtin::load_i32(__outptr + 0); + __lifted_result_8 = builtin::load_i32(__outptr + 4); drop("mem/realloc"(__outptr, 8, 4, 0)); - return __lifted_result_5; __lifted_result_6; + return __lifted_result_7; __lifted_result_8; } fn __cm_export__handle(request) { @@ -745,13 +762,13 @@ fn "core:internal/gc_array_to_memory"(arr, ptr, len) { // from core:internal __for_1: block { i = 0; block { - l40: loop { + l41: loop { if (i < len) == 0 { break __for_1; }; builtin::store_u8(ptr + i, builtin::array_get_u8(arr, i)); i = i + 1; - continue l40; + continue l41; }; }; }; diff --git a/wado-compiler/tests/fixtures.golden/http-method-routing.wir.wado b/wado-compiler/tests/fixtures.golden/http-method-routing.wir.wado index 951599fb1..dc3cc271c 100644 --- a/wado-compiler/tests/fixtures.golden/http-method-routing.wir.wado +++ b/wado-compiler/tests/fixtures.golden/http-method-routing.wir.wado @@ -229,6 +229,16 @@ variant Result { Err, } +variant Option> { + Some(i32), + None, +} + +struct Option>::Some { + discriminant: i32, + payload_0: i32, +} + type "functype/mem/realloc" = fn(i32, i32, i32, i32) -> i32; type "functype/wasi/task-return" = fn(i32, i32, i32, i64, i32, i32, i32, i32); @@ -267,7 +277,7 @@ type "functype/wasi/waitable-join" = fn(i32, i32); type "functype/wasi/waitable-set-wait" = fn(i32, i32) -> i32; -type "functype/__cm_binding__Response_new" = fn(i32, i32, i32, i32) -> [i32, i32]; +type "functype/__cm_binding__Response_new" = fn(i32, ref Option>, i32) -> [i32, i32]; import fn realloc from "mem/realloc"; import fn task-return from "wasi/task-return"; @@ -446,7 +456,7 @@ fn handle(request) { headers = __cm_binding__Fields_new(); let __sroa___pattern_temp_1_0: i32; let __sroa___pattern_temp_1_1: i32; - multivalue_bind [__sroa___pattern_temp_1_0, __sroa___pattern_temp_1_1] = __cm_binding__Response_new(headers, 0, 0, trailers_future); + multivalue_bind [__sroa___pattern_temp_1_0, __sroa___pattern_temp_1_1] = __cm_binding__Response_new(headers, Option> { 1 }, trailers_future); response = __sroa___pattern_temp_1_0; drop(__cm_binding__Response_set_status_code(response, status & 65535)); __task_ret = Result::Ok { discriminant: 0, payload_0: response }; @@ -818,16 +828,23 @@ fn __cm_binding__Fields_new() { return "wasi/wasi:http/Fields::new"(); } -fn __cm_binding__Response_new(headers, contents_flat0, contents_flat1, trailers) { +fn __cm_binding__Response_new(headers, contents, trailers) { + let __contents_disc: i32; + let __contents_inner0: i32; let __outptr: i32; - let __lifted_result_5: i32; - let __lifted_result_6: i32; + let __lifted_result_7: i32; + let __lifted_result_8: i32; + __contents_disc = ref.test Option>::Some(contents); + __contents_inner0 = 0; + if ref.test Option>::Some(contents) { + __contents_inner0 = ref.cast Option>::Some(contents).payload_0; + }; __outptr = "mem/realloc"(0, 0, 4, 8); - "wasi/wasi:http/Response::new"(headers, contents_flat0, contents_flat1, trailers, __outptr); - __lifted_result_5 = builtin::load_i32(__outptr + 0); - __lifted_result_6 = builtin::load_i32(__outptr + 4); + "wasi/wasi:http/Response::new"(headers, __contents_disc, __contents_inner0, trailers, __outptr); + __lifted_result_7 = builtin::load_i32(__outptr + 0); + __lifted_result_8 = builtin::load_i32(__outptr + 4); drop("mem/realloc"(__outptr, 8, 4, 0)); - return __lifted_result_5; __lifted_result_6; + return __lifted_result_7; __lifted_result_8; } fn __cm_binding__Response_set_status_code(self, status_code) { @@ -854,13 +871,13 @@ fn "core:internal/memory_to_gc_array"(ptr, len) { // from core:internal __for_0: block { i = 0; block { - l55: loop { + l56: loop { if (i < len) == 0 { break __for_0; }; builtin::array_set_u8(arr, i, builtin::load_u8(ptr + i) & 255); i = i + 1; - continue l55; + continue l56; }; }; }; @@ -872,13 +889,13 @@ fn "core:internal/gc_array_to_memory"(arr, ptr, len) { // from core:internal __for_1: block { i = 0; block { - l58: loop { + l59: loop { if (i < len) == 0 { break __for_1; }; builtin::store_u8(ptr + i, builtin::array_get_u8(arr, i)); i = i + 1; - continue l58; + continue l59; }; }; }; diff --git a/wado-compiler/tests/fixtures.golden/http-request-authority.wir.wado b/wado-compiler/tests/fixtures.golden/http-request-authority.wir.wado index e21556629..83dca8ac1 100644 --- a/wado-compiler/tests/fixtures.golden/http-request-authority.wir.wado +++ b/wado-compiler/tests/fixtures.golden/http-request-authority.wir.wado @@ -206,6 +206,16 @@ struct Result::Err { payload_0: ref "wasi:http/types.wado/ErrorCode", } +variant Option> { + Some(i32), + None, +} + +struct Option>::Some { + discriminant: i32, + payload_0: i32, +} + type "functype/mem/realloc" = fn(i32, i32, i32, i32) -> i32; type "functype/wasi/task-return" = fn(i32, i32, i32, i64, i32, i32, i32, i32); @@ -240,7 +250,7 @@ type "functype/wasi/waitable-join" = fn(i32, i32); type "functype/wasi/waitable-set-wait" = fn(i32, i32) -> i32; -type "functype/__cm_binding__Response_new" = fn(i32, i32, i32, i32) -> [i32, i32]; +type "functype/__cm_binding__Response_new" = fn(i32, ref Option>, i32) -> [i32, i32]; import fn realloc from "mem/realloc"; import fn task-return from "wasi/task-return"; @@ -401,7 +411,7 @@ fn handle(request) { headers = __cm_binding__Fields_new(); let __sroa___pattern_temp_1_0: i32; let __sroa___pattern_temp_1_1: i32; - multivalue_bind [__sroa___pattern_temp_1_0, __sroa___pattern_temp_1_1] = __cm_binding__Response_new(headers, 0, 0, trailers_future); + multivalue_bind [__sroa___pattern_temp_1_0, __sroa___pattern_temp_1_1] = __cm_binding__Response_new(headers, Option> { 1 }, trailers_future); response = __sroa___pattern_temp_1_0; __task_ret = Result::Ok { discriminant: 0, payload_0: response }; __tv_1 = 0; @@ -755,16 +765,23 @@ fn __cm_binding__Fields_new() { return "wasi/wasi:http/Fields::new"(); } -fn __cm_binding__Response_new(headers, contents_flat0, contents_flat1, trailers) { +fn __cm_binding__Response_new(headers, contents, trailers) { + let __contents_disc: i32; + let __contents_inner0: i32; let __outptr: i32; - let __lifted_result_5: i32; - let __lifted_result_6: i32; + let __lifted_result_7: i32; + let __lifted_result_8: i32; + __contents_disc = ref.test Option>::Some(contents); + __contents_inner0 = 0; + if ref.test Option>::Some(contents) { + __contents_inner0 = ref.cast Option>::Some(contents).payload_0; + }; __outptr = "mem/realloc"(0, 0, 4, 8); - "wasi/wasi:http/Response::new"(headers, contents_flat0, contents_flat1, trailers, __outptr); - __lifted_result_5 = builtin::load_i32(__outptr + 0); - __lifted_result_6 = builtin::load_i32(__outptr + 4); + "wasi/wasi:http/Response::new"(headers, __contents_disc, __contents_inner0, trailers, __outptr); + __lifted_result_7 = builtin::load_i32(__outptr + 0); + __lifted_result_8 = builtin::load_i32(__outptr + 4); drop("mem/realloc"(__outptr, 8, 4, 0)); - return __lifted_result_5; __lifted_result_6; + return __lifted_result_7; __lifted_result_8; } fn __cm_export__handle(request) { @@ -778,13 +795,13 @@ fn "core:internal/memory_to_gc_array"(ptr, len) { // from core:internal __for_0: block { i = 0; block { - l41: loop { + l42: loop { if (i < len) == 0 { break __for_0; }; builtin::array_set_u8(arr, i, builtin::load_u8(ptr + i) & 255); i = i + 1; - continue l41; + continue l42; }; }; }; @@ -796,13 +813,13 @@ fn "core:internal/gc_array_to_memory"(arr, ptr, len) { // from core:internal __for_1: block { i = 0; block { - l44: loop { + l45: loop { if (i < len) == 0 { break __for_1; }; builtin::store_u8(ptr + i, builtin::array_get_u8(arr, i)); i = i + 1; - continue l44; + continue l45; }; }; }; diff --git a/wado-compiler/tests/fixtures.golden/http-request-headers.wir.wado b/wado-compiler/tests/fixtures.golden/http-request-headers.wir.wado index 25f8700b3..e966504ad 100644 --- a/wado-compiler/tests/fixtures.golden/http-request-headers.wir.wado +++ b/wado-compiler/tests/fixtures.golden/http-request-headers.wir.wado @@ -219,6 +219,16 @@ struct Result::Err { payload_0: ref "wasi:http/types.wado/ErrorCode", } +variant Option> { + Some(i32), + None, +} + +struct Option>::Some { + discriminant: i32, + payload_0: i32, +} + struct Array { // Array with T=u8 mut repr: ref array, mut used: i32, @@ -321,7 +331,7 @@ type "functype/wasi/stream-new" = fn() -> i64; type "functype/wasi/future-drop-readable:transmission-cli" = fn(i32); -type "functype/__cm_binding__Response_new" = fn(i32, i32, i32, i32) -> [i32, i32]; +type "functype/__cm_binding__Response_new" = fn(i32, ref Option>, i32) -> [i32, i32]; type "functype/i32::fmt_decimal" = fn(i32, ref Formatter); @@ -575,7 +585,7 @@ condition: values.len() == 1 headers = __cm_binding__Fields_new(); let __sroa___pattern_temp_1_0: i32; let __sroa___pattern_temp_1_1: i32; - multivalue_bind [__sroa___pattern_temp_1_0, __sroa___pattern_temp_1_1] = __cm_binding__Response_new(headers, 0, 0, trailers_future); + multivalue_bind [__sroa___pattern_temp_1_0, __sroa___pattern_temp_1_1] = __cm_binding__Response_new(headers, Option> { 1 }, trailers_future); response = __sroa___pattern_temp_1_0; __task_ret = Result::Ok { discriminant: 0, payload_0: response }; __tv_1 = 0; @@ -971,16 +981,23 @@ fn __cm_binding__Fields_new() { return "wasi/wasi:http/Fields::new"(); } -fn __cm_binding__Response_new(headers, contents_flat0, contents_flat1, trailers) { +fn __cm_binding__Response_new(headers, contents, trailers) { + let __contents_disc: i32; + let __contents_inner0: i32; let __outptr: i32; - let __lifted_result_5: i32; - let __lifted_result_6: i32; + let __lifted_result_7: i32; + let __lifted_result_8: i32; + __contents_disc = ref.test Option>::Some(contents); + __contents_inner0 = 0; + if ref.test Option>::Some(contents) { + __contents_inner0 = ref.cast Option>::Some(contents).payload_0; + }; __outptr = "mem/realloc"(0, 0, 4, 8); - "wasi/wasi:http/Response::new"(headers, contents_flat0, contents_flat1, trailers, __outptr); - __lifted_result_5 = builtin::load_i32(__outptr + 0); - __lifted_result_6 = builtin::load_i32(__outptr + 4); + "wasi/wasi:http/Response::new"(headers, __contents_disc, __contents_inner0, trailers, __outptr); + __lifted_result_7 = builtin::load_i32(__outptr + 0); + __lifted_result_8 = builtin::load_i32(__outptr + 4); drop("mem/realloc"(__outptr, 8, 4, 0)); - return __lifted_result_5; __lifted_result_6; + return __lifted_result_7; __lifted_result_8; } fn __cm_export__handle(request) { @@ -992,13 +1009,13 @@ fn "core:internal/gc_array_to_memory"(arr, ptr, len) { // from core:internal __for_1: block { i = 0; block { - l51: loop { + l52: loop { if (i < len) == 0 { break __for_1; }; builtin::store_u8(ptr + i, builtin::array_get_u8(arr, i)); i = i + 1; - continue l51; + continue l52; }; }; }; @@ -1098,13 +1115,13 @@ fn count_digits_i64(val) { __for_1: block { t = val; block { - l57: loop { + l58: loop { if (t > 0_i64) == 0 { break __for_1; }; n = n + 1; t = t / 10_i64; - continue l57; + continue l58; }; }; }; @@ -1121,14 +1138,14 @@ fn write_decimal_digits(arr, offset, abs_val, digit_count) { __for_2: block { temp = abs_val; block { - l61: loop { + l62: loop { if (temp > 0_i64) == 0 { break __for_2; }; pos = pos - 1; builtin::array_set_u8(arr, pos, (48 + builtin::i32_wrap_i64(temp % 10_i64)) & 255); temp = temp / 10_i64; - continue l61; + continue l62; }; }; }; @@ -1260,13 +1277,13 @@ fn Array>::grow(self) { __for_0: block { i = 0; block { - l74: loop { + l75: loop { if (i < used) == 0 { break __for_0; }; builtin::array_set>(new_repr, i, builtin::array_get>(old_repr, i)); i = i + 1; - continue l74; + continue l75; }; }; }; @@ -1302,13 +1319,13 @@ fn Array::grow(self) { __for_0: block { i = 0; block { - l78: loop { + l79: loop { if (i < used) == 0 { break __for_0; }; builtin::array_set_u8(new_repr, i, builtin::array_get(old_repr, i)); i = i + 1; - continue l78; + continue l79; }; }; }; @@ -1322,13 +1339,13 @@ fn Formatter::write_char_n(self, c, n) { i = 0; _licm_buf_4 = self.buf; block { - l81: loop { + l82: loop { if (i < n) == 0 { break __for_0; }; String::push(_licm_buf_4, c); i = i + 1; - continue l81; + continue l82; }; }; }; diff --git a/wado-compiler/tests/fixtures.golden/http-request-method-delete.wir.wado b/wado-compiler/tests/fixtures.golden/http-request-method-delete.wir.wado index 213ff8bad..cd3ff6478 100644 --- a/wado-compiler/tests/fixtures.golden/http-request-method-delete.wir.wado +++ b/wado-compiler/tests/fixtures.golden/http-request-method-delete.wir.wado @@ -235,6 +235,16 @@ struct Result::Err { payload_0: ref "wasi:http/types.wado/ErrorCode", } +variant Option> { + Some(i32), + None, +} + +struct Option>::Some { + discriminant: i32, + payload_0: i32, +} + enum Alignment { Left = 0, Center = 1, Right = 2 }; type "functype/mem/realloc" = fn(i32, i32, i32, i32) -> i32; @@ -311,7 +321,7 @@ type "functype/wasi/stream-new" = fn() -> i64; type "functype/wasi/future-drop-readable:transmission-cli" = fn(i32); -type "functype/__cm_binding__Response_new" = fn(i32, i32, i32, i32) -> [i32, i32]; +type "functype/__cm_binding__Response_new" = fn(i32, ref Option>, i32) -> [i32, i32]; type "functype/i32::fmt_decimal" = fn(i32, ref Formatter); @@ -516,7 +526,7 @@ condition: method matches { Delete } headers = __cm_binding__Fields_new(); let __sroa___pattern_temp_1_0: i32; let __sroa___pattern_temp_1_1: i32; - multivalue_bind [__sroa___pattern_temp_1_0, __sroa___pattern_temp_1_1] = __cm_binding__Response_new(headers, 0, 0, trailers_future); + multivalue_bind [__sroa___pattern_temp_1_0, __sroa___pattern_temp_1_1] = __cm_binding__Response_new(headers, Option> { 1 }, trailers_future); response = __sroa___pattern_temp_1_0; __task_ret = Result::Ok { discriminant: 0, payload_0: response }; __tv_1 = 0; @@ -887,16 +897,23 @@ fn __cm_binding__Fields_new() { return "wasi/wasi:http/Fields::new"(); } -fn __cm_binding__Response_new(headers, contents_flat0, contents_flat1, trailers) { +fn __cm_binding__Response_new(headers, contents, trailers) { + let __contents_disc: i32; + let __contents_inner0: i32; let __outptr: i32; - let __lifted_result_5: i32; - let __lifted_result_6: i32; + let __lifted_result_7: i32; + let __lifted_result_8: i32; + __contents_disc = ref.test Option>::Some(contents); + __contents_inner0 = 0; + if ref.test Option>::Some(contents) { + __contents_inner0 = ref.cast Option>::Some(contents).payload_0; + }; __outptr = "mem/realloc"(0, 0, 4, 8); - "wasi/wasi:http/Response::new"(headers, contents_flat0, contents_flat1, trailers, __outptr); - __lifted_result_5 = builtin::load_i32(__outptr + 0); - __lifted_result_6 = builtin::load_i32(__outptr + 4); + "wasi/wasi:http/Response::new"(headers, __contents_disc, __contents_inner0, trailers, __outptr); + __lifted_result_7 = builtin::load_i32(__outptr + 0); + __lifted_result_8 = builtin::load_i32(__outptr + 4); drop("mem/realloc"(__outptr, 8, 4, 0)); - return __lifted_result_5; __lifted_result_6; + return __lifted_result_7; __lifted_result_8; } fn __cm_export__handle(request) { @@ -910,13 +927,13 @@ fn "core:internal/memory_to_gc_array"(ptr, len) { // from core:internal __for_0: block { i = 0; block { - l51: loop { + l52: loop { if (i < len) == 0 { break __for_0; }; builtin::array_set_u8(arr, i, builtin::load_u8(ptr + i) & 255); i = i + 1; - continue l51; + continue l52; }; }; }; @@ -928,13 +945,13 @@ fn "core:internal/gc_array_to_memory"(arr, ptr, len) { // from core:internal __for_1: block { i = 0; block { - l54: loop { + l55: loop { if (i < len) == 0 { break __for_1; }; builtin::store_u8(ptr + i, builtin::array_get_u8(arr, i)); i = i + 1; - continue l54; + continue l55; }; }; }; @@ -1034,13 +1051,13 @@ fn count_digits_i64(val) { __for_1: block { t = val; block { - l60: loop { + l61: loop { if (t > 0_i64) == 0 { break __for_1; }; n = n + 1; t = t / 10_i64; - continue l60; + continue l61; }; }; }; @@ -1057,14 +1074,14 @@ fn write_decimal_digits(arr, offset, abs_val, digit_count) { __for_2: block { temp = abs_val; block { - l64: loop { + l65: loop { if (temp > 0_i64) == 0 { break __for_2; }; pos = pos - 1; builtin::array_set_u8(arr, pos, (48 + builtin::i32_wrap_i64(temp % 10_i64)) & 255); temp = temp / 10_i64; - continue l64; + continue l65; }; }; }; @@ -1174,13 +1191,13 @@ fn Formatter::write_char_n(self, c, n) { i = 0; _licm_buf_4 = self.buf; block { - l76: loop { + l77: loop { if (i < n) == 0 { break __for_0; }; String::push(_licm_buf_4, c); i = i + 1; - continue l76; + continue l77; }; }; }; diff --git a/wado-compiler/tests/fixtures.golden/http-request-method-get.wir.wado b/wado-compiler/tests/fixtures.golden/http-request-method-get.wir.wado index 15698bbc1..80118bda6 100644 --- a/wado-compiler/tests/fixtures.golden/http-request-method-get.wir.wado +++ b/wado-compiler/tests/fixtures.golden/http-request-method-get.wir.wado @@ -235,6 +235,16 @@ struct Result::Err { payload_0: ref "wasi:http/types.wado/ErrorCode", } +variant Option> { + Some(i32), + None, +} + +struct Option>::Some { + discriminant: i32, + payload_0: i32, +} + enum Alignment { Left = 0, Center = 1, Right = 2 }; type "functype/mem/realloc" = fn(i32, i32, i32, i32) -> i32; @@ -311,7 +321,7 @@ type "functype/wasi/stream-new" = fn() -> i64; type "functype/wasi/future-drop-readable:transmission-cli" = fn(i32); -type "functype/__cm_binding__Response_new" = fn(i32, i32, i32, i32) -> [i32, i32]; +type "functype/__cm_binding__Response_new" = fn(i32, ref Option>, i32) -> [i32, i32]; type "functype/i32::fmt_decimal" = fn(i32, ref Formatter); @@ -516,7 +526,7 @@ condition: method matches { Get } headers = __cm_binding__Fields_new(); let __sroa___pattern_temp_1_0: i32; let __sroa___pattern_temp_1_1: i32; - multivalue_bind [__sroa___pattern_temp_1_0, __sroa___pattern_temp_1_1] = __cm_binding__Response_new(headers, 0, 0, trailers_future); + multivalue_bind [__sroa___pattern_temp_1_0, __sroa___pattern_temp_1_1] = __cm_binding__Response_new(headers, Option> { 1 }, trailers_future); response = __sroa___pattern_temp_1_0; __task_ret = Result::Ok { discriminant: 0, payload_0: response }; __tv_1 = 0; @@ -887,16 +897,23 @@ fn __cm_binding__Fields_new() { return "wasi/wasi:http/Fields::new"(); } -fn __cm_binding__Response_new(headers, contents_flat0, contents_flat1, trailers) { +fn __cm_binding__Response_new(headers, contents, trailers) { + let __contents_disc: i32; + let __contents_inner0: i32; let __outptr: i32; - let __lifted_result_5: i32; - let __lifted_result_6: i32; + let __lifted_result_7: i32; + let __lifted_result_8: i32; + __contents_disc = ref.test Option>::Some(contents); + __contents_inner0 = 0; + if ref.test Option>::Some(contents) { + __contents_inner0 = ref.cast Option>::Some(contents).payload_0; + }; __outptr = "mem/realloc"(0, 0, 4, 8); - "wasi/wasi:http/Response::new"(headers, contents_flat0, contents_flat1, trailers, __outptr); - __lifted_result_5 = builtin::load_i32(__outptr + 0); - __lifted_result_6 = builtin::load_i32(__outptr + 4); + "wasi/wasi:http/Response::new"(headers, __contents_disc, __contents_inner0, trailers, __outptr); + __lifted_result_7 = builtin::load_i32(__outptr + 0); + __lifted_result_8 = builtin::load_i32(__outptr + 4); drop("mem/realloc"(__outptr, 8, 4, 0)); - return __lifted_result_5; __lifted_result_6; + return __lifted_result_7; __lifted_result_8; } fn __cm_export__handle(request) { @@ -910,13 +927,13 @@ fn "core:internal/memory_to_gc_array"(ptr, len) { // from core:internal __for_0: block { i = 0; block { - l51: loop { + l52: loop { if (i < len) == 0 { break __for_0; }; builtin::array_set_u8(arr, i, builtin::load_u8(ptr + i) & 255); i = i + 1; - continue l51; + continue l52; }; }; }; @@ -928,13 +945,13 @@ fn "core:internal/gc_array_to_memory"(arr, ptr, len) { // from core:internal __for_1: block { i = 0; block { - l54: loop { + l55: loop { if (i < len) == 0 { break __for_1; }; builtin::store_u8(ptr + i, builtin::array_get_u8(arr, i)); i = i + 1; - continue l54; + continue l55; }; }; }; @@ -1034,13 +1051,13 @@ fn count_digits_i64(val) { __for_1: block { t = val; block { - l60: loop { + l61: loop { if (t > 0_i64) == 0 { break __for_1; }; n = n + 1; t = t / 10_i64; - continue l60; + continue l61; }; }; }; @@ -1057,14 +1074,14 @@ fn write_decimal_digits(arr, offset, abs_val, digit_count) { __for_2: block { temp = abs_val; block { - l64: loop { + l65: loop { if (temp > 0_i64) == 0 { break __for_2; }; pos = pos - 1; builtin::array_set_u8(arr, pos, (48 + builtin::i32_wrap_i64(temp % 10_i64)) & 255); temp = temp / 10_i64; - continue l64; + continue l65; }; }; }; @@ -1174,13 +1191,13 @@ fn Formatter::write_char_n(self, c, n) { i = 0; _licm_buf_4 = self.buf; block { - l76: loop { + l77: loop { if (i < n) == 0 { break __for_0; }; String::push(_licm_buf_4, c); i = i + 1; - continue l76; + continue l77; }; }; }; diff --git a/wado-compiler/tests/fixtures.golden/http-request-method-patch.wir.wado b/wado-compiler/tests/fixtures.golden/http-request-method-patch.wir.wado index a649a2a93..17980eba2 100644 --- a/wado-compiler/tests/fixtures.golden/http-request-method-patch.wir.wado +++ b/wado-compiler/tests/fixtures.golden/http-request-method-patch.wir.wado @@ -235,6 +235,16 @@ struct Result::Err { payload_0: ref "wasi:http/types.wado/ErrorCode", } +variant Option> { + Some(i32), + None, +} + +struct Option>::Some { + discriminant: i32, + payload_0: i32, +} + enum Alignment { Left = 0, Center = 1, Right = 2 }; type "functype/mem/realloc" = fn(i32, i32, i32, i32) -> i32; @@ -311,7 +321,7 @@ type "functype/wasi/stream-new" = fn() -> i64; type "functype/wasi/future-drop-readable:transmission-cli" = fn(i32); -type "functype/__cm_binding__Response_new" = fn(i32, i32, i32, i32) -> [i32, i32]; +type "functype/__cm_binding__Response_new" = fn(i32, ref Option>, i32) -> [i32, i32]; type "functype/i32::fmt_decimal" = fn(i32, ref Formatter); @@ -516,7 +526,7 @@ condition: method matches { Patch } headers = __cm_binding__Fields_new(); let __sroa___pattern_temp_1_0: i32; let __sroa___pattern_temp_1_1: i32; - multivalue_bind [__sroa___pattern_temp_1_0, __sroa___pattern_temp_1_1] = __cm_binding__Response_new(headers, 0, 0, trailers_future); + multivalue_bind [__sroa___pattern_temp_1_0, __sroa___pattern_temp_1_1] = __cm_binding__Response_new(headers, Option> { 1 }, trailers_future); response = __sroa___pattern_temp_1_0; __task_ret = Result::Ok { discriminant: 0, payload_0: response }; __tv_1 = 0; @@ -887,16 +897,23 @@ fn __cm_binding__Fields_new() { return "wasi/wasi:http/Fields::new"(); } -fn __cm_binding__Response_new(headers, contents_flat0, contents_flat1, trailers) { +fn __cm_binding__Response_new(headers, contents, trailers) { + let __contents_disc: i32; + let __contents_inner0: i32; let __outptr: i32; - let __lifted_result_5: i32; - let __lifted_result_6: i32; + let __lifted_result_7: i32; + let __lifted_result_8: i32; + __contents_disc = ref.test Option>::Some(contents); + __contents_inner0 = 0; + if ref.test Option>::Some(contents) { + __contents_inner0 = ref.cast Option>::Some(contents).payload_0; + }; __outptr = "mem/realloc"(0, 0, 4, 8); - "wasi/wasi:http/Response::new"(headers, contents_flat0, contents_flat1, trailers, __outptr); - __lifted_result_5 = builtin::load_i32(__outptr + 0); - __lifted_result_6 = builtin::load_i32(__outptr + 4); + "wasi/wasi:http/Response::new"(headers, __contents_disc, __contents_inner0, trailers, __outptr); + __lifted_result_7 = builtin::load_i32(__outptr + 0); + __lifted_result_8 = builtin::load_i32(__outptr + 4); drop("mem/realloc"(__outptr, 8, 4, 0)); - return __lifted_result_5; __lifted_result_6; + return __lifted_result_7; __lifted_result_8; } fn __cm_export__handle(request) { @@ -910,13 +927,13 @@ fn "core:internal/memory_to_gc_array"(ptr, len) { // from core:internal __for_0: block { i = 0; block { - l51: loop { + l52: loop { if (i < len) == 0 { break __for_0; }; builtin::array_set_u8(arr, i, builtin::load_u8(ptr + i) & 255); i = i + 1; - continue l51; + continue l52; }; }; }; @@ -928,13 +945,13 @@ fn "core:internal/gc_array_to_memory"(arr, ptr, len) { // from core:internal __for_1: block { i = 0; block { - l54: loop { + l55: loop { if (i < len) == 0 { break __for_1; }; builtin::store_u8(ptr + i, builtin::array_get_u8(arr, i)); i = i + 1; - continue l54; + continue l55; }; }; }; @@ -1034,13 +1051,13 @@ fn count_digits_i64(val) { __for_1: block { t = val; block { - l60: loop { + l61: loop { if (t > 0_i64) == 0 { break __for_1; }; n = n + 1; t = t / 10_i64; - continue l60; + continue l61; }; }; }; @@ -1057,14 +1074,14 @@ fn write_decimal_digits(arr, offset, abs_val, digit_count) { __for_2: block { temp = abs_val; block { - l64: loop { + l65: loop { if (temp > 0_i64) == 0 { break __for_2; }; pos = pos - 1; builtin::array_set_u8(arr, pos, (48 + builtin::i32_wrap_i64(temp % 10_i64)) & 255); temp = temp / 10_i64; - continue l64; + continue l65; }; }; }; @@ -1174,13 +1191,13 @@ fn Formatter::write_char_n(self, c, n) { i = 0; _licm_buf_4 = self.buf; block { - l76: loop { + l77: loop { if (i < n) == 0 { break __for_0; }; String::push(_licm_buf_4, c); i = i + 1; - continue l76; + continue l77; }; }; }; diff --git a/wado-compiler/tests/fixtures.golden/http-request-method-put.wir.wado b/wado-compiler/tests/fixtures.golden/http-request-method-put.wir.wado index d444cd099..21ca38f8a 100644 --- a/wado-compiler/tests/fixtures.golden/http-request-method-put.wir.wado +++ b/wado-compiler/tests/fixtures.golden/http-request-method-put.wir.wado @@ -235,6 +235,16 @@ struct Result::Err { payload_0: ref "wasi:http/types.wado/ErrorCode", } +variant Option> { + Some(i32), + None, +} + +struct Option>::Some { + discriminant: i32, + payload_0: i32, +} + enum Alignment { Left = 0, Center = 1, Right = 2 }; type "functype/mem/realloc" = fn(i32, i32, i32, i32) -> i32; @@ -311,7 +321,7 @@ type "functype/wasi/stream-new" = fn() -> i64; type "functype/wasi/future-drop-readable:transmission-cli" = fn(i32); -type "functype/__cm_binding__Response_new" = fn(i32, i32, i32, i32) -> [i32, i32]; +type "functype/__cm_binding__Response_new" = fn(i32, ref Option>, i32) -> [i32, i32]; type "functype/i32::fmt_decimal" = fn(i32, ref Formatter); @@ -516,7 +526,7 @@ condition: method matches { Put } headers = __cm_binding__Fields_new(); let __sroa___pattern_temp_1_0: i32; let __sroa___pattern_temp_1_1: i32; - multivalue_bind [__sroa___pattern_temp_1_0, __sroa___pattern_temp_1_1] = __cm_binding__Response_new(headers, 0, 0, trailers_future); + multivalue_bind [__sroa___pattern_temp_1_0, __sroa___pattern_temp_1_1] = __cm_binding__Response_new(headers, Option> { 1 }, trailers_future); response = __sroa___pattern_temp_1_0; __task_ret = Result::Ok { discriminant: 0, payload_0: response }; __tv_1 = 0; @@ -887,16 +897,23 @@ fn __cm_binding__Fields_new() { return "wasi/wasi:http/Fields::new"(); } -fn __cm_binding__Response_new(headers, contents_flat0, contents_flat1, trailers) { +fn __cm_binding__Response_new(headers, contents, trailers) { + let __contents_disc: i32; + let __contents_inner0: i32; let __outptr: i32; - let __lifted_result_5: i32; - let __lifted_result_6: i32; + let __lifted_result_7: i32; + let __lifted_result_8: i32; + __contents_disc = ref.test Option>::Some(contents); + __contents_inner0 = 0; + if ref.test Option>::Some(contents) { + __contents_inner0 = ref.cast Option>::Some(contents).payload_0; + }; __outptr = "mem/realloc"(0, 0, 4, 8); - "wasi/wasi:http/Response::new"(headers, contents_flat0, contents_flat1, trailers, __outptr); - __lifted_result_5 = builtin::load_i32(__outptr + 0); - __lifted_result_6 = builtin::load_i32(__outptr + 4); + "wasi/wasi:http/Response::new"(headers, __contents_disc, __contents_inner0, trailers, __outptr); + __lifted_result_7 = builtin::load_i32(__outptr + 0); + __lifted_result_8 = builtin::load_i32(__outptr + 4); drop("mem/realloc"(__outptr, 8, 4, 0)); - return __lifted_result_5; __lifted_result_6; + return __lifted_result_7; __lifted_result_8; } fn __cm_export__handle(request) { @@ -910,13 +927,13 @@ fn "core:internal/memory_to_gc_array"(ptr, len) { // from core:internal __for_0: block { i = 0; block { - l51: loop { + l52: loop { if (i < len) == 0 { break __for_0; }; builtin::array_set_u8(arr, i, builtin::load_u8(ptr + i) & 255); i = i + 1; - continue l51; + continue l52; }; }; }; @@ -928,13 +945,13 @@ fn "core:internal/gc_array_to_memory"(arr, ptr, len) { // from core:internal __for_1: block { i = 0; block { - l54: loop { + l55: loop { if (i < len) == 0 { break __for_1; }; builtin::store_u8(ptr + i, builtin::array_get_u8(arr, i)); i = i + 1; - continue l54; + continue l55; }; }; }; @@ -1034,13 +1051,13 @@ fn count_digits_i64(val) { __for_1: block { t = val; block { - l60: loop { + l61: loop { if (t > 0_i64) == 0 { break __for_1; }; n = n + 1; t = t / 10_i64; - continue l60; + continue l61; }; }; }; @@ -1057,14 +1074,14 @@ fn write_decimal_digits(arr, offset, abs_val, digit_count) { __for_2: block { temp = abs_val; block { - l64: loop { + l65: loop { if (temp > 0_i64) == 0 { break __for_2; }; pos = pos - 1; builtin::array_set_u8(arr, pos, (48 + builtin::i32_wrap_i64(temp % 10_i64)) & 255); temp = temp / 10_i64; - continue l64; + continue l65; }; }; }; @@ -1174,13 +1191,13 @@ fn Formatter::write_char_n(self, c, n) { i = 0; _licm_buf_4 = self.buf; block { - l76: loop { + l77: loop { if (i < n) == 0 { break __for_0; }; String::push(_licm_buf_4, c); i = i + 1; - continue l76; + continue l77; }; }; }; diff --git a/wado-compiler/tests/fixtures.golden/http-request-method.wir.wado b/wado-compiler/tests/fixtures.golden/http-request-method.wir.wado index 8808810d2..06c00ae5d 100644 --- a/wado-compiler/tests/fixtures.golden/http-request-method.wir.wado +++ b/wado-compiler/tests/fixtures.golden/http-request-method.wir.wado @@ -235,6 +235,16 @@ struct Result::Err { payload_0: ref "wasi:http/types.wado/ErrorCode", } +variant Option> { + Some(i32), + None, +} + +struct Option>::Some { + discriminant: i32, + payload_0: i32, +} + enum Alignment { Left = 0, Center = 1, Right = 2 }; type "functype/mem/realloc" = fn(i32, i32, i32, i32) -> i32; @@ -311,7 +321,7 @@ type "functype/wasi/stream-new" = fn() -> i64; type "functype/wasi/future-drop-readable:transmission-cli" = fn(i32); -type "functype/__cm_binding__Response_new" = fn(i32, i32, i32, i32) -> [i32, i32]; +type "functype/__cm_binding__Response_new" = fn(i32, ref Option>, i32) -> [i32, i32]; type "functype/i32::fmt_decimal" = fn(i32, ref Formatter); @@ -516,7 +526,7 @@ condition: method matches { Post } headers = __cm_binding__Fields_new(); let __sroa___pattern_temp_1_0: i32; let __sroa___pattern_temp_1_1: i32; - multivalue_bind [__sroa___pattern_temp_1_0, __sroa___pattern_temp_1_1] = __cm_binding__Response_new(headers, 0, 0, trailers_future); + multivalue_bind [__sroa___pattern_temp_1_0, __sroa___pattern_temp_1_1] = __cm_binding__Response_new(headers, Option> { 1 }, trailers_future); response = __sroa___pattern_temp_1_0; __task_ret = Result::Ok { discriminant: 0, payload_0: response }; __tv_1 = 0; @@ -887,16 +897,23 @@ fn __cm_binding__Fields_new() { return "wasi/wasi:http/Fields::new"(); } -fn __cm_binding__Response_new(headers, contents_flat0, contents_flat1, trailers) { +fn __cm_binding__Response_new(headers, contents, trailers) { + let __contents_disc: i32; + let __contents_inner0: i32; let __outptr: i32; - let __lifted_result_5: i32; - let __lifted_result_6: i32; + let __lifted_result_7: i32; + let __lifted_result_8: i32; + __contents_disc = ref.test Option>::Some(contents); + __contents_inner0 = 0; + if ref.test Option>::Some(contents) { + __contents_inner0 = ref.cast Option>::Some(contents).payload_0; + }; __outptr = "mem/realloc"(0, 0, 4, 8); - "wasi/wasi:http/Response::new"(headers, contents_flat0, contents_flat1, trailers, __outptr); - __lifted_result_5 = builtin::load_i32(__outptr + 0); - __lifted_result_6 = builtin::load_i32(__outptr + 4); + "wasi/wasi:http/Response::new"(headers, __contents_disc, __contents_inner0, trailers, __outptr); + __lifted_result_7 = builtin::load_i32(__outptr + 0); + __lifted_result_8 = builtin::load_i32(__outptr + 4); drop("mem/realloc"(__outptr, 8, 4, 0)); - return __lifted_result_5; __lifted_result_6; + return __lifted_result_7; __lifted_result_8; } fn __cm_export__handle(request) { @@ -910,13 +927,13 @@ fn "core:internal/memory_to_gc_array"(ptr, len) { // from core:internal __for_0: block { i = 0; block { - l51: loop { + l52: loop { if (i < len) == 0 { break __for_0; }; builtin::array_set_u8(arr, i, builtin::load_u8(ptr + i) & 255); i = i + 1; - continue l51; + continue l52; }; }; }; @@ -928,13 +945,13 @@ fn "core:internal/gc_array_to_memory"(arr, ptr, len) { // from core:internal __for_1: block { i = 0; block { - l54: loop { + l55: loop { if (i < len) == 0 { break __for_1; }; builtin::store_u8(ptr + i, builtin::array_get_u8(arr, i)); i = i + 1; - continue l54; + continue l55; }; }; }; @@ -1034,13 +1051,13 @@ fn count_digits_i64(val) { __for_1: block { t = val; block { - l60: loop { + l61: loop { if (t > 0_i64) == 0 { break __for_1; }; n = n + 1; t = t / 10_i64; - continue l60; + continue l61; }; }; }; @@ -1057,14 +1074,14 @@ fn write_decimal_digits(arr, offset, abs_val, digit_count) { __for_2: block { temp = abs_val; block { - l64: loop { + l65: loop { if (temp > 0_i64) == 0 { break __for_2; }; pos = pos - 1; builtin::array_set_u8(arr, pos, (48 + builtin::i32_wrap_i64(temp % 10_i64)) & 255); temp = temp / 10_i64; - continue l64; + continue l65; }; }; }; @@ -1174,13 +1191,13 @@ fn Formatter::write_char_n(self, c, n) { i = 0; _licm_buf_4 = self.buf; block { - l76: loop { + l77: loop { if (i < n) == 0 { break __for_0; }; String::push(_licm_buf_4, c); i = i + 1; - continue l76; + continue l77; }; }; }; diff --git a/wado-compiler/tests/fixtures.golden/http-request-path.wir.wado b/wado-compiler/tests/fixtures.golden/http-request-path.wir.wado index 262d7a297..54a611c84 100644 --- a/wado-compiler/tests/fixtures.golden/http-request-path.wir.wado +++ b/wado-compiler/tests/fixtures.golden/http-request-path.wir.wado @@ -223,6 +223,16 @@ struct Result::Err { payload_0: ref "wasi:http/types.wado/ErrorCode", } +variant Option> { + Some(i32), + None, +} + +struct Option>::Some { + discriminant: i32, + payload_0: i32, +} + enum Alignment { Left = 0, Center = 1, Right = 2 }; type "functype/mem/realloc" = fn(i32, i32, i32, i32) -> i32; @@ -305,7 +315,7 @@ type "functype/wasi/stream-new" = fn() -> i64; type "functype/wasi/future-drop-readable:transmission-cli" = fn(i32); -type "functype/__cm_binding__Response_new" = fn(i32, i32, i32, i32) -> [i32, i32]; +type "functype/__cm_binding__Response_new" = fn(i32, ref Option>, i32) -> [i32, i32]; type "functype/StrCharIter^Iterator::next" = fn(ref StrCharIter) -> [i32, char]; @@ -523,7 +533,7 @@ condition: p == \"/hello\" headers = __cm_binding__Fields_new(); let __sroa___pattern_temp_2_0: i32; let __sroa___pattern_temp_2_1: i32; - multivalue_bind [__sroa___pattern_temp_2_0, __sroa___pattern_temp_2_1] = __cm_binding__Response_new(headers, 0, 0, trailers_future); + multivalue_bind [__sroa___pattern_temp_2_0, __sroa___pattern_temp_2_1] = __cm_binding__Response_new(headers, Option> { 1 }, trailers_future); response = __sroa___pattern_temp_2_0; __task_ret = Result::Ok { discriminant: 0, payload_0: response }; __tv_1 = 0; @@ -877,16 +887,23 @@ fn __cm_binding__Fields_new() { return "wasi/wasi:http/Fields::new"(); } -fn __cm_binding__Response_new(headers, contents_flat0, contents_flat1, trailers) { +fn __cm_binding__Response_new(headers, contents, trailers) { + let __contents_disc: i32; + let __contents_inner0: i32; let __outptr: i32; - let __lifted_result_5: i32; - let __lifted_result_6: i32; + let __lifted_result_7: i32; + let __lifted_result_8: i32; + __contents_disc = ref.test Option>::Some(contents); + __contents_inner0 = 0; + if ref.test Option>::Some(contents) { + __contents_inner0 = ref.cast Option>::Some(contents).payload_0; + }; __outptr = "mem/realloc"(0, 0, 4, 8); - "wasi/wasi:http/Response::new"(headers, contents_flat0, contents_flat1, trailers, __outptr); - __lifted_result_5 = builtin::load_i32(__outptr + 0); - __lifted_result_6 = builtin::load_i32(__outptr + 4); + "wasi/wasi:http/Response::new"(headers, __contents_disc, __contents_inner0, trailers, __outptr); + __lifted_result_7 = builtin::load_i32(__outptr + 0); + __lifted_result_8 = builtin::load_i32(__outptr + 4); drop("mem/realloc"(__outptr, 8, 4, 0)); - return __lifted_result_5; __lifted_result_6; + return __lifted_result_7; __lifted_result_8; } fn __cm_export__handle(request) { @@ -900,13 +917,13 @@ fn "core:internal/memory_to_gc_array"(ptr, len) { // from core:internal __for_0: block { i = 0; block { - l43: loop { + l44: loop { if (i < len) == 0 { break __for_0; }; builtin::array_set_u8(arr, i, builtin::load_u8(ptr + i) & 255); i = i + 1; - continue l43; + continue l44; }; }; }; @@ -918,13 +935,13 @@ fn "core:internal/gc_array_to_memory"(arr, ptr, len) { // from core:internal __for_1: block { i = 0; block { - l46: loop { + l47: loop { if (i < len) == 0 { break __for_1; }; builtin::store_u8(ptr + i, builtin::array_get_u8(arr, i)); i = i + 1; - continue l46; + continue l47; }; }; }; @@ -1024,13 +1041,13 @@ fn count_digits_i64(val) { __for_1: block { t = val; block { - l52: loop { + l53: loop { if (t > 0_i64) == 0 { break __for_1; }; n = n + 1; t = t / 10_i64; - continue l52; + continue l53; }; }; }; @@ -1047,14 +1064,14 @@ fn write_decimal_digits(arr, offset, abs_val, digit_count) { __for_2: block { temp = abs_val; block { - l56: loop { + l57: loop { if (temp > 0_i64) == 0 { break __for_2; }; pos = pos - 1; builtin::array_set_u8(arr, pos, (48 + builtin::i32_wrap_i64(temp % 10_i64)) & 255); temp = temp / 10_i64; - continue l56; + continue l57; }; }; }; @@ -1144,7 +1161,7 @@ fn String^Eq::eq_bytes(a, b, len) { __for_1: block { i = 0; block { - l65: loop { + l66: loop { if (i < len) == 0 { break __for_1; }; @@ -1152,7 +1169,7 @@ fn String^Eq::eq_bytes(a, b, len) { return 0; }; i = i + 1; - continue l65; + continue l66; }; }; }; @@ -1237,13 +1254,13 @@ fn Formatter::write_char_n(self, c, n) { i = 0; _licm_buf_4 = self.buf; block { - l77: loop { + l78: loop { if (i < n) == 0 { break __for_0; }; String::push(_licm_buf_4, c); i = i + 1; - continue l77; + continue l78; }; }; }; @@ -1346,8 +1363,8 @@ fn String^Inspect::inspect(self, f) { break __inline_StrCharIter_IntoIterator__into_iter_1: __local_7; }; _licm_buf_33 = f.buf; - b96: block { - l97: loop { + b97: block { + l98: loop { let __sroa___pattern_temp_0_discriminant: i32; let __sroa___pattern_temp_0_payload_0: char; multivalue_bind [__sroa___pattern_temp_0_discriminant, __sroa___pattern_temp_0_payload_0] = StrCharIter^Iterator::next(__iter_2); @@ -1372,9 +1389,9 @@ fn String^Inspect::inspect(self, f) { String::push(_licm_buf_33, c); }; } else { - break b96; + break b97; }; - continue l97; + continue l98; }; }; String::push(f.buf, 34); diff --git a/wado-compiler/tests/fixtures.golden/http-request-scheme.wir.wado b/wado-compiler/tests/fixtures.golden/http-request-scheme.wir.wado index f5d96b968..d8d993ff5 100644 --- a/wado-compiler/tests/fixtures.golden/http-request-scheme.wir.wado +++ b/wado-compiler/tests/fixtures.golden/http-request-scheme.wir.wado @@ -228,6 +228,16 @@ struct Result::Err { payload_0: ref "wasi:http/types.wado/ErrorCode", } +variant Option> { + Some(i32), + None, +} + +struct Option>::Some { + discriminant: i32, + payload_0: i32, +} + enum Alignment { Left = 0, Center = 1, Right = 2 }; type "functype/mem/realloc" = fn(i32, i32, i32, i32) -> i32; @@ -304,7 +314,7 @@ type "functype/wasi/stream-new" = fn() -> i64; type "functype/wasi/future-drop-readable:transmission-cli" = fn(i32); -type "functype/__cm_binding__Response_new" = fn(i32, i32, i32, i32) -> [i32, i32]; +type "functype/__cm_binding__Response_new" = fn(i32, ref Option>, i32) -> [i32, i32]; type "functype/i32::fmt_decimal" = fn(i32, ref Formatter); @@ -513,7 +523,7 @@ condition: s matches { Http } headers = __cm_binding__Fields_new(); let __sroa___pattern_temp_2_0: i32; let __sroa___pattern_temp_2_1: i32; - multivalue_bind [__sroa___pattern_temp_2_0, __sroa___pattern_temp_2_1] = __cm_binding__Response_new(headers, 0, 0, trailers_future); + multivalue_bind [__sroa___pattern_temp_2_0, __sroa___pattern_temp_2_1] = __cm_binding__Response_new(headers, Option> { 1 }, trailers_future); response = __sroa___pattern_temp_2_0; __task_ret = Result::Ok { discriminant: 0, payload_0: response }; __tv_1 = 0; @@ -877,16 +887,23 @@ fn __cm_binding__Fields_new() { return "wasi/wasi:http/Fields::new"(); } -fn __cm_binding__Response_new(headers, contents_flat0, contents_flat1, trailers) { +fn __cm_binding__Response_new(headers, contents, trailers) { + let __contents_disc: i32; + let __contents_inner0: i32; let __outptr: i32; - let __lifted_result_5: i32; - let __lifted_result_6: i32; + let __lifted_result_7: i32; + let __lifted_result_8: i32; + __contents_disc = ref.test Option>::Some(contents); + __contents_inner0 = 0; + if ref.test Option>::Some(contents) { + __contents_inner0 = ref.cast Option>::Some(contents).payload_0; + }; __outptr = "mem/realloc"(0, 0, 4, 8); - "wasi/wasi:http/Response::new"(headers, contents_flat0, contents_flat1, trailers, __outptr); - __lifted_result_5 = builtin::load_i32(__outptr + 0); - __lifted_result_6 = builtin::load_i32(__outptr + 4); + "wasi/wasi:http/Response::new"(headers, __contents_disc, __contents_inner0, trailers, __outptr); + __lifted_result_7 = builtin::load_i32(__outptr + 0); + __lifted_result_8 = builtin::load_i32(__outptr + 4); drop("mem/realloc"(__outptr, 8, 4, 0)); - return __lifted_result_5; __lifted_result_6; + return __lifted_result_7; __lifted_result_8; } fn __cm_export__handle(request) { @@ -900,13 +917,13 @@ fn "core:internal/memory_to_gc_array"(ptr, len) { // from core:internal __for_0: block { i = 0; block { - l46: loop { + l47: loop { if (i < len) == 0 { break __for_0; }; builtin::array_set_u8(arr, i, builtin::load_u8(ptr + i) & 255); i = i + 1; - continue l46; + continue l47; }; }; }; @@ -918,13 +935,13 @@ fn "core:internal/gc_array_to_memory"(arr, ptr, len) { // from core:internal __for_1: block { i = 0; block { - l49: loop { + l50: loop { if (i < len) == 0 { break __for_1; }; builtin::store_u8(ptr + i, builtin::array_get_u8(arr, i)); i = i + 1; - continue l49; + continue l50; }; }; }; @@ -1024,13 +1041,13 @@ fn count_digits_i64(val) { __for_1: block { t = val; block { - l55: loop { + l56: loop { if (t > 0_i64) == 0 { break __for_1; }; n = n + 1; t = t / 10_i64; - continue l55; + continue l56; }; }; }; @@ -1047,14 +1064,14 @@ fn write_decimal_digits(arr, offset, abs_val, digit_count) { __for_2: block { temp = abs_val; block { - l59: loop { + l60: loop { if (temp > 0_i64) == 0 { break __for_2; }; pos = pos - 1; builtin::array_set_u8(arr, pos, (48 + builtin::i32_wrap_i64(temp % 10_i64)) & 255); temp = temp / 10_i64; - continue l59; + continue l60; }; }; }; @@ -1164,13 +1181,13 @@ fn Formatter::write_char_n(self, c, n) { i = 0; _licm_buf_4 = self.buf; block { - l71: loop { + l72: loop { if (i < n) == 0 { break __for_0; }; String::push(_licm_buf_4, c); i = i + 1; - continue l71; + continue l72; }; }; }; diff --git a/wado-compiler/tests/fixtures.golden/http-response-get-headers.wir.wado b/wado-compiler/tests/fixtures.golden/http-response-get-headers.wir.wado index df05f4a47..11362eed5 100644 --- a/wado-compiler/tests/fixtures.golden/http-response-get-headers.wir.wado +++ b/wado-compiler/tests/fixtures.golden/http-response-get-headers.wir.wado @@ -230,6 +230,16 @@ struct Result::Err { payload_0: ref "wasi:http/types.wado/ErrorCode", } +variant Option> { + Some(i32), + None, +} + +struct Option>::Some { + discriminant: i32, + payload_0: i32, +} + struct Array { // Array with T=u8 mut repr: ref array, mut used: i32, @@ -325,7 +335,7 @@ type "functype/wasi/stream-new" = fn() -> i64; type "functype/wasi/future-drop-readable:transmission-cli" = fn(i32); -type "functype/__cm_binding__Response_new" = fn(i32, i32, i32, i32) -> [i32, i32]; +type "functype/__cm_binding__Response_new" = fn(i32, ref Option>, i32) -> [i32, i32]; type "functype/i32::fmt_decimal" = fn(i32, ref Formatter); @@ -508,7 +518,7 @@ fn handle(request) { drop(__cm_binding__Fields_append(headers, String { repr: array.new_data("x-check"), used: 7 }, v)); let __sroa___pattern_temp_1_0: i32; let __sroa___pattern_temp_1_1: i32; - multivalue_bind [__sroa___pattern_temp_1_0, __sroa___pattern_temp_1_1] = __cm_binding__Response_new(headers, 0, 0, trailers_future); + multivalue_bind [__sroa___pattern_temp_1_0, __sroa___pattern_temp_1_1] = __cm_binding__Response_new(headers, Option> { 1 }, trailers_future); response = __sroa___pattern_temp_1_0; resp_headers = __cm_binding__Response_get_headers(response); __v0 = __cm_binding__Fields_has(resp_headers, String { repr: array.new_data("x-check"), used: 7 }); @@ -933,16 +943,23 @@ fn __cm_binding__Fields_append(self, name, value) { return __result_val; } -fn __cm_binding__Response_new(headers, contents_flat0, contents_flat1, trailers) { +fn __cm_binding__Response_new(headers, contents, trailers) { + let __contents_disc: i32; + let __contents_inner0: i32; let __outptr: i32; - let __lifted_result_5: i32; - let __lifted_result_6: i32; + let __lifted_result_7: i32; + let __lifted_result_8: i32; + __contents_disc = ref.test Option>::Some(contents); + __contents_inner0 = 0; + if ref.test Option>::Some(contents) { + __contents_inner0 = ref.cast Option>::Some(contents).payload_0; + }; __outptr = "mem/realloc"(0, 0, 4, 8); - "wasi/wasi:http/Response::new"(headers, contents_flat0, contents_flat1, trailers, __outptr); - __lifted_result_5 = builtin::load_i32(__outptr + 0); - __lifted_result_6 = builtin::load_i32(__outptr + 4); + "wasi/wasi:http/Response::new"(headers, __contents_disc, __contents_inner0, trailers, __outptr); + __lifted_result_7 = builtin::load_i32(__outptr + 0); + __lifted_result_8 = builtin::load_i32(__outptr + 4); drop("mem/realloc"(__outptr, 8, 4, 0)); - return __lifted_result_5; __lifted_result_6; + return __lifted_result_7; __lifted_result_8; } fn __cm_binding__Response_get_headers(self) { @@ -966,13 +983,13 @@ fn "core:internal/memory_to_gc_array"(ptr, len) { // from core:internal __for_0: block { i = 0; block { - l48: loop { + l49: loop { if (i < len) == 0 { break __for_0; }; builtin::array_set_u8(arr, i, builtin::load_u8(ptr + i) & 255); i = i + 1; - continue l48; + continue l49; }; }; }; @@ -984,13 +1001,13 @@ fn "core:internal/gc_array_to_memory"(arr, ptr, len) { // from core:internal __for_1: block { i = 0; block { - l51: loop { + l52: loop { if (i < len) == 0 { break __for_1; }; builtin::store_u8(ptr + i, builtin::array_get_u8(arr, i)); i = i + 1; - continue l51; + continue l52; }; }; }; @@ -1090,13 +1107,13 @@ fn count_digits_i64(val) { __for_1: block { t = val; block { - l57: loop { + l58: loop { if (t > 0_i64) == 0 { break __for_1; }; n = n + 1; t = t / 10_i64; - continue l57; + continue l58; }; }; }; @@ -1113,14 +1130,14 @@ fn write_decimal_digits(arr, offset, abs_val, digit_count) { __for_2: block { temp = abs_val; block { - l61: loop { + l62: loop { if (temp > 0_i64) == 0 { break __for_2; }; pos = pos - 1; builtin::array_set_u8(arr, pos, (48 + builtin::i32_wrap_i64(temp % 10_i64)) & 255); temp = temp / 10_i64; - continue l61; + continue l62; }; }; }; @@ -1252,13 +1269,13 @@ fn Array::grow(self) { __for_0: block { i = 0; block { - l74: loop { + l75: loop { if (i < used) == 0 { break __for_0; }; builtin::array_set_u8(new_repr, i, builtin::array_get(old_repr, i)); i = i + 1; - continue l74; + continue l75; }; }; }; @@ -1272,13 +1289,13 @@ fn Formatter::write_char_n(self, c, n) { i = 0; _licm_buf_4 = self.buf; block { - l77: loop { + l78: loop { if (i < n) == 0 { break __for_0; }; String::push(_licm_buf_4, c); i = i + 1; - continue l77; + continue l78; }; }; }; diff --git a/wado-compiler/tests/fixtures.golden/http-response-headers-multi.wir.wado b/wado-compiler/tests/fixtures.golden/http-response-headers-multi.wir.wado index 2d68f6243..cc5edde75 100644 --- a/wado-compiler/tests/fixtures.golden/http-response-headers-multi.wir.wado +++ b/wado-compiler/tests/fixtures.golden/http-response-headers-multi.wir.wado @@ -219,6 +219,16 @@ struct Result::Err { payload_0: ref "wasi:http/types.wado/ErrorCode", } +variant Option> { + Some(i32), + None, +} + +struct Option>::Some { + discriminant: i32, + payload_0: i32, +} + struct Array { // Array with T=u8 mut repr: ref array, mut used: i32, @@ -264,7 +274,7 @@ type "functype/wasi/waitable-join" = fn(i32, i32); type "functype/wasi/waitable-set-wait" = fn(i32, i32) -> i32; -type "functype/__cm_binding__Response_new" = fn(i32, i32, i32, i32) -> [i32, i32]; +type "functype/__cm_binding__Response_new" = fn(i32, ref Option>, i32) -> [i32, i32]; import fn realloc from "mem/realloc"; import fn task-return from "wasi/task-return"; @@ -438,7 +448,7 @@ fn handle(request) { drop(__cm_binding__Fields_append(headers, String { repr: array.new_data("x-second"), used: 8 }, v2)); let __sroa___pattern_temp_1_0: i32; let __sroa___pattern_temp_1_1: i32; - multivalue_bind [__sroa___pattern_temp_1_0, __sroa___pattern_temp_1_1] = __cm_binding__Response_new(headers, 0, 0, trailers_future); + multivalue_bind [__sroa___pattern_temp_1_0, __sroa___pattern_temp_1_1] = __cm_binding__Response_new(headers, Option> { 1 }, trailers_future); response = __sroa___pattern_temp_1_0; __task_ret = Result::Ok { discriminant: 0, payload_0: response }; __tv_1 = 0; @@ -826,16 +836,23 @@ fn __cm_binding__Fields_append(self, name, value) { return __result_val; } -fn __cm_binding__Response_new(headers, contents_flat0, contents_flat1, trailers) { +fn __cm_binding__Response_new(headers, contents, trailers) { + let __contents_disc: i32; + let __contents_inner0: i32; let __outptr: i32; - let __lifted_result_5: i32; - let __lifted_result_6: i32; + let __lifted_result_7: i32; + let __lifted_result_8: i32; + __contents_disc = ref.test Option>::Some(contents); + __contents_inner0 = 0; + if ref.test Option>::Some(contents) { + __contents_inner0 = ref.cast Option>::Some(contents).payload_0; + }; __outptr = "mem/realloc"(0, 0, 4, 8); - "wasi/wasi:http/Response::new"(headers, contents_flat0, contents_flat1, trailers, __outptr); - __lifted_result_5 = builtin::load_i32(__outptr + 0); - __lifted_result_6 = builtin::load_i32(__outptr + 4); + "wasi/wasi:http/Response::new"(headers, __contents_disc, __contents_inner0, trailers, __outptr); + __lifted_result_7 = builtin::load_i32(__outptr + 0); + __lifted_result_8 = builtin::load_i32(__outptr + 4); drop("mem/realloc"(__outptr, 8, 4, 0)); - return __lifted_result_5; __lifted_result_6; + return __lifted_result_7; __lifted_result_8; } fn __cm_export__handle(request) { @@ -849,13 +866,13 @@ fn "core:internal/memory_to_gc_array"(ptr, len) { // from core:internal __for_0: block { i = 0; block { - l46: loop { + l47: loop { if (i < len) == 0 { break __for_0; }; builtin::array_set_u8(arr, i, builtin::load_u8(ptr + i) & 255); i = i + 1; - continue l46; + continue l47; }; }; }; @@ -867,13 +884,13 @@ fn "core:internal/gc_array_to_memory"(arr, ptr, len) { // from core:internal __for_1: block { i = 0; block { - l49: loop { + l50: loop { if (i < len) == 0 { break __for_1; }; builtin::store_u8(ptr + i, builtin::array_get_u8(arr, i)); i = i + 1; - continue l49; + continue l50; }; }; }; @@ -926,13 +943,13 @@ fn Array::grow(self) { __for_0: block { i = 0; block { - l53: loop { + l54: loop { if (i < used) == 0 { break __for_0; }; builtin::array_set_u8(new_repr, i, builtin::array_get(old_repr, i)); i = i + 1; - continue l53; + continue l54; }; }; }; diff --git a/wado-compiler/tests/fixtures.golden/http-response-headers.wir.wado b/wado-compiler/tests/fixtures.golden/http-response-headers.wir.wado index 5105199bf..1d5fb6e0f 100644 --- a/wado-compiler/tests/fixtures.golden/http-response-headers.wir.wado +++ b/wado-compiler/tests/fixtures.golden/http-response-headers.wir.wado @@ -219,6 +219,16 @@ struct Result::Err { payload_0: ref "wasi:http/types.wado/ErrorCode", } +variant Option> { + Some(i32), + None, +} + +struct Option>::Some { + discriminant: i32, + payload_0: i32, +} + struct Array { // Array with T=u8 mut repr: ref array, mut used: i32, @@ -264,7 +274,7 @@ type "functype/wasi/waitable-join" = fn(i32, i32); type "functype/wasi/waitable-set-wait" = fn(i32, i32) -> i32; -type "functype/__cm_binding__Response_new" = fn(i32, i32, i32, i32) -> [i32, i32]; +type "functype/__cm_binding__Response_new" = fn(i32, ref Option>, i32) -> [i32, i32]; import fn realloc from "mem/realloc"; import fn task-return from "wasi/task-return"; @@ -431,7 +441,7 @@ fn handle(request) { drop(__cm_binding__Fields_append(headers, String { repr: array.new_data("x-wado"), used: 6 }, value)); let __sroa___pattern_temp_1_0: i32; let __sroa___pattern_temp_1_1: i32; - multivalue_bind [__sroa___pattern_temp_1_0, __sroa___pattern_temp_1_1] = __cm_binding__Response_new(headers, 0, 0, trailers_future); + multivalue_bind [__sroa___pattern_temp_1_0, __sroa___pattern_temp_1_1] = __cm_binding__Response_new(headers, Option> { 1 }, trailers_future); response = __sroa___pattern_temp_1_0; __task_ret = Result::Ok { discriminant: 0, payload_0: response }; __tv_1 = 0; @@ -819,16 +829,23 @@ fn __cm_binding__Fields_append(self, name, value) { return __result_val; } -fn __cm_binding__Response_new(headers, contents_flat0, contents_flat1, trailers) { +fn __cm_binding__Response_new(headers, contents, trailers) { + let __contents_disc: i32; + let __contents_inner0: i32; let __outptr: i32; - let __lifted_result_5: i32; - let __lifted_result_6: i32; + let __lifted_result_7: i32; + let __lifted_result_8: i32; + __contents_disc = ref.test Option>::Some(contents); + __contents_inner0 = 0; + if ref.test Option>::Some(contents) { + __contents_inner0 = ref.cast Option>::Some(contents).payload_0; + }; __outptr = "mem/realloc"(0, 0, 4, 8); - "wasi/wasi:http/Response::new"(headers, contents_flat0, contents_flat1, trailers, __outptr); - __lifted_result_5 = builtin::load_i32(__outptr + 0); - __lifted_result_6 = builtin::load_i32(__outptr + 4); + "wasi/wasi:http/Response::new"(headers, __contents_disc, __contents_inner0, trailers, __outptr); + __lifted_result_7 = builtin::load_i32(__outptr + 0); + __lifted_result_8 = builtin::load_i32(__outptr + 4); drop("mem/realloc"(__outptr, 8, 4, 0)); - return __lifted_result_5; __lifted_result_6; + return __lifted_result_7; __lifted_result_8; } fn __cm_export__handle(request) { @@ -842,13 +859,13 @@ fn "core:internal/memory_to_gc_array"(ptr, len) { // from core:internal __for_0: block { i = 0; block { - l46: loop { + l47: loop { if (i < len) == 0 { break __for_0; }; builtin::array_set_u8(arr, i, builtin::load_u8(ptr + i) & 255); i = i + 1; - continue l46; + continue l47; }; }; }; @@ -860,13 +877,13 @@ fn "core:internal/gc_array_to_memory"(arr, ptr, len) { // from core:internal __for_1: block { i = 0; block { - l49: loop { + l50: loop { if (i < len) == 0 { break __for_1; }; builtin::store_u8(ptr + i, builtin::array_get_u8(arr, i)); i = i + 1; - continue l49; + continue l50; }; }; }; @@ -919,13 +936,13 @@ fn Array::grow(self) { __for_0: block { i = 0; block { - l53: loop { + l54: loop { if (i < used) == 0 { break __for_0; }; builtin::array_set_u8(new_repr, i, builtin::array_get(old_repr, i)); i = i + 1; - continue l53; + continue l54; }; }; }; diff --git a/wado-compiler/tests/fixtures.golden/http-response-ops.wir.wado b/wado-compiler/tests/fixtures.golden/http-response-ops.wir.wado index 528cb1866..c38547f3e 100644 --- a/wado-compiler/tests/fixtures.golden/http-response-ops.wir.wado +++ b/wado-compiler/tests/fixtures.golden/http-response-ops.wir.wado @@ -222,6 +222,16 @@ variant Result { Err, } +variant Option> { + Some(i32), + None, +} + +struct Option>::Some { + discriminant: i32, + payload_0: i32, +} + enum Alignment { Left = 0, Center = 1, Right = 2 }; type "functype/mem/realloc" = fn(i32, i32, i32, i32) -> i32; @@ -300,7 +310,7 @@ type "functype/wasi/stream-new" = fn() -> i64; type "functype/wasi/future-drop-readable:transmission-cli" = fn(i32); -type "functype/__cm_binding__Response_new" = fn(i32, i32, i32, i32) -> [i32, i32]; +type "functype/__cm_binding__Response_new" = fn(i32, ref Option>, i32) -> [i32, i32]; type "functype/i32::fmt_decimal" = fn(i32, ref Formatter); @@ -483,7 +493,7 @@ fn handle(request) { headers = __cm_binding__Fields_new(); let __sroa___pattern_temp_1_0: i32; let __sroa___pattern_temp_1_1: i32; - multivalue_bind [__sroa___pattern_temp_1_0, __sroa___pattern_temp_1_1] = __cm_binding__Response_new(headers, 0, 0, trailers_future); + multivalue_bind [__sroa___pattern_temp_1_0, __sroa___pattern_temp_1_1] = __cm_binding__Response_new(headers, Option> { 1 }, trailers_future); response = __sroa___pattern_temp_1_0; default_status = __cm_binding__Response_get_status_code(response); __cond_8 = default_status == 200; @@ -884,16 +894,23 @@ fn __cm_binding__Fields_new() { return "wasi/wasi:http/Fields::new"(); } -fn __cm_binding__Response_new(headers, contents_flat0, contents_flat1, trailers) { +fn __cm_binding__Response_new(headers, contents, trailers) { + let __contents_disc: i32; + let __contents_inner0: i32; let __outptr: i32; - let __lifted_result_5: i32; - let __lifted_result_6: i32; + let __lifted_result_7: i32; + let __lifted_result_8: i32; + __contents_disc = ref.test Option>::Some(contents); + __contents_inner0 = 0; + if ref.test Option>::Some(contents) { + __contents_inner0 = ref.cast Option>::Some(contents).payload_0; + }; __outptr = "mem/realloc"(0, 0, 4, 8); - "wasi/wasi:http/Response::new"(headers, contents_flat0, contents_flat1, trailers, __outptr); - __lifted_result_5 = builtin::load_i32(__outptr + 0); - __lifted_result_6 = builtin::load_i32(__outptr + 4); + "wasi/wasi:http/Response::new"(headers, __contents_disc, __contents_inner0, trailers, __outptr); + __lifted_result_7 = builtin::load_i32(__outptr + 0); + __lifted_result_8 = builtin::load_i32(__outptr + 4); drop("mem/realloc"(__outptr, 8, 4, 0)); - return __lifted_result_5; __lifted_result_6; + return __lifted_result_7; __lifted_result_8; } fn __cm_binding__Response_get_status_code(self) { @@ -922,13 +939,13 @@ fn "core:internal/gc_array_to_memory"(arr, ptr, len) { // from core:internal __for_1: block { i = 0; block { - l43: loop { + l44: loop { if (i < len) == 0 { break __for_1; }; builtin::store_u8(ptr + i, builtin::array_get_u8(arr, i)); i = i + 1; - continue l43; + continue l44; }; }; }; @@ -1028,13 +1045,13 @@ fn count_digits_i64(val) { __for_1: block { t = val; block { - l49: loop { + l50: loop { if (t > 0_i64) == 0 { break __for_1; }; n = n + 1; t = t / 10_i64; - continue l49; + continue l50; }; }; }; @@ -1051,14 +1068,14 @@ fn write_decimal_digits(arr, offset, abs_val, digit_count) { __for_2: block { temp = abs_val; block { - l53: loop { + l54: loop { if (temp > 0_i64) == 0 { break __for_2; }; pos = pos - 1; builtin::array_set_u8(arr, pos, (48 + builtin::i32_wrap_i64(temp % 10_i64)) & 255); temp = temp / 10_i64; - continue l53; + continue l54; }; }; }; @@ -1168,13 +1185,13 @@ fn Formatter::write_char_n(self, c, n) { i = 0; _licm_buf_4 = self.buf; block { - l65: loop { + l66: loop { if (i < n) == 0 { break __for_0; }; String::push(_licm_buf_4, c); i = i + 1; - continue l65; + continue l66; }; }; }; diff --git a/wado-compiler/tests/fixtures.golden/http-routing-created.wir.wado b/wado-compiler/tests/fixtures.golden/http-routing-created.wir.wado index a374a4562..2e71e588b 100644 --- a/wado-compiler/tests/fixtures.golden/http-routing-created.wir.wado +++ b/wado-compiler/tests/fixtures.golden/http-routing-created.wir.wado @@ -211,6 +211,16 @@ variant Result { Err, } +variant Option> { + Some(i32), + None, +} + +struct Option>::Some { + discriminant: i32, + payload_0: i32, +} + type "functype/mem/realloc" = fn(i32, i32, i32, i32) -> i32; type "functype/wasi/task-return" = fn(i32, i32, i32, i64, i32, i32, i32, i32); @@ -253,7 +263,7 @@ type "functype/wasi/waitable-join" = fn(i32, i32); type "functype/wasi/waitable-set-wait" = fn(i32, i32) -> i32; -type "functype/__cm_binding__Response_new" = fn(i32, i32, i32, i32) -> [i32, i32]; +type "functype/__cm_binding__Response_new" = fn(i32, ref Option>, i32) -> [i32, i32]; import fn realloc from "mem/realloc"; import fn task-return from "wasi/task-return"; @@ -417,7 +427,7 @@ fn handle(request) { headers = __cm_binding__Fields_new(); let __sroa___pattern_temp_1_0: i32; let __sroa___pattern_temp_1_1: i32; - multivalue_bind [__sroa___pattern_temp_1_0, __sroa___pattern_temp_1_1] = __cm_binding__Response_new(headers, 0, 0, trailers_future); + multivalue_bind [__sroa___pattern_temp_1_0, __sroa___pattern_temp_1_1] = __cm_binding__Response_new(headers, Option> { 1 }, trailers_future); response = __sroa___pattern_temp_1_0; if ref.is_null(path) == 0 { p = value_copy String(ref.as_non_null(path)); @@ -777,16 +787,23 @@ fn __cm_binding__Fields_new() { return "wasi/wasi:http/Fields::new"(); } -fn __cm_binding__Response_new(headers, contents_flat0, contents_flat1, trailers) { +fn __cm_binding__Response_new(headers, contents, trailers) { + let __contents_disc: i32; + let __contents_inner0: i32; let __outptr: i32; - let __lifted_result_5: i32; - let __lifted_result_6: i32; + let __lifted_result_7: i32; + let __lifted_result_8: i32; + __contents_disc = ref.test Option>::Some(contents); + __contents_inner0 = 0; + if ref.test Option>::Some(contents) { + __contents_inner0 = ref.cast Option>::Some(contents).payload_0; + }; __outptr = "mem/realloc"(0, 0, 4, 8); - "wasi/wasi:http/Response::new"(headers, contents_flat0, contents_flat1, trailers, __outptr); - __lifted_result_5 = builtin::load_i32(__outptr + 0); - __lifted_result_6 = builtin::load_i32(__outptr + 4); + "wasi/wasi:http/Response::new"(headers, __contents_disc, __contents_inner0, trailers, __outptr); + __lifted_result_7 = builtin::load_i32(__outptr + 0); + __lifted_result_8 = builtin::load_i32(__outptr + 4); drop("mem/realloc"(__outptr, 8, 4, 0)); - return __lifted_result_5; __lifted_result_6; + return __lifted_result_7; __lifted_result_8; } fn __cm_binding__Response_set_status_code(self, status_code) { @@ -813,13 +830,13 @@ fn "core:internal/memory_to_gc_array"(ptr, len) { // from core:internal __for_0: block { i = 0; block { - l44: loop { + l45: loop { if (i < len) == 0 { break __for_0; }; builtin::array_set_u8(arr, i, builtin::load_u8(ptr + i) & 255); i = i + 1; - continue l44; + continue l45; }; }; }; @@ -831,13 +848,13 @@ fn "core:internal/gc_array_to_memory"(arr, ptr, len) { // from core:internal __for_1: block { i = 0; block { - l47: loop { + l48: loop { if (i < len) == 0 { break __for_1; }; builtin::store_u8(ptr + i, builtin::array_get_u8(arr, i)); i = i + 1; - continue l47; + continue l48; }; }; }; @@ -868,7 +885,7 @@ fn String^Eq::eq_bytes(a, b, len) { __for_1: block { i = 0; block { - l51: loop { + l52: loop { if (i < len) == 0 { break __for_1; }; @@ -876,7 +893,7 @@ fn String^Eq::eq_bytes(a, b, len) { return 0; }; i = i + 1; - continue l51; + continue l52; }; }; }; diff --git a/wado-compiler/tests/fixtures.golden/http-routing.wir.wado b/wado-compiler/tests/fixtures.golden/http-routing.wir.wado index 7316d3ddd..c0fc1fab2 100644 --- a/wado-compiler/tests/fixtures.golden/http-routing.wir.wado +++ b/wado-compiler/tests/fixtures.golden/http-routing.wir.wado @@ -211,6 +211,16 @@ variant Result { Err, } +variant Option> { + Some(i32), + None, +} + +struct Option>::Some { + discriminant: i32, + payload_0: i32, +} + type "functype/mem/realloc" = fn(i32, i32, i32, i32) -> i32; type "functype/wasi/task-return" = fn(i32, i32, i32, i64, i32, i32, i32, i32); @@ -253,7 +263,7 @@ type "functype/wasi/waitable-join" = fn(i32, i32); type "functype/wasi/waitable-set-wait" = fn(i32, i32) -> i32; -type "functype/__cm_binding__Response_new" = fn(i32, i32, i32, i32) -> [i32, i32]; +type "functype/__cm_binding__Response_new" = fn(i32, ref Option>, i32) -> [i32, i32]; import fn realloc from "mem/realloc"; import fn task-return from "wasi/task-return"; @@ -417,7 +427,7 @@ fn handle(request) { headers = __cm_binding__Fields_new(); let __sroa___pattern_temp_1_0: i32; let __sroa___pattern_temp_1_1: i32; - multivalue_bind [__sroa___pattern_temp_1_0, __sroa___pattern_temp_1_1] = __cm_binding__Response_new(headers, 0, 0, trailers_future); + multivalue_bind [__sroa___pattern_temp_1_0, __sroa___pattern_temp_1_1] = __cm_binding__Response_new(headers, Option> { 1 }, trailers_future); response = __sroa___pattern_temp_1_0; if ref.is_null(path) == 0 { p = value_copy String(ref.as_non_null(path)); @@ -779,16 +789,23 @@ fn __cm_binding__Fields_new() { return "wasi/wasi:http/Fields::new"(); } -fn __cm_binding__Response_new(headers, contents_flat0, contents_flat1, trailers) { +fn __cm_binding__Response_new(headers, contents, trailers) { + let __contents_disc: i32; + let __contents_inner0: i32; let __outptr: i32; - let __lifted_result_5: i32; - let __lifted_result_6: i32; + let __lifted_result_7: i32; + let __lifted_result_8: i32; + __contents_disc = ref.test Option>::Some(contents); + __contents_inner0 = 0; + if ref.test Option>::Some(contents) { + __contents_inner0 = ref.cast Option>::Some(contents).payload_0; + }; __outptr = "mem/realloc"(0, 0, 4, 8); - "wasi/wasi:http/Response::new"(headers, contents_flat0, contents_flat1, trailers, __outptr); - __lifted_result_5 = builtin::load_i32(__outptr + 0); - __lifted_result_6 = builtin::load_i32(__outptr + 4); + "wasi/wasi:http/Response::new"(headers, __contents_disc, __contents_inner0, trailers, __outptr); + __lifted_result_7 = builtin::load_i32(__outptr + 0); + __lifted_result_8 = builtin::load_i32(__outptr + 4); drop("mem/realloc"(__outptr, 8, 4, 0)); - return __lifted_result_5; __lifted_result_6; + return __lifted_result_7; __lifted_result_8; } fn __cm_binding__Response_set_status_code(self, status_code) { @@ -815,13 +832,13 @@ fn "core:internal/memory_to_gc_array"(ptr, len) { // from core:internal __for_0: block { i = 0; block { - l45: loop { + l46: loop { if (i < len) == 0 { break __for_0; }; builtin::array_set_u8(arr, i, builtin::load_u8(ptr + i) & 255); i = i + 1; - continue l45; + continue l46; }; }; }; @@ -833,13 +850,13 @@ fn "core:internal/gc_array_to_memory"(arr, ptr, len) { // from core:internal __for_1: block { i = 0; block { - l48: loop { + l49: loop { if (i < len) == 0 { break __for_1; }; builtin::store_u8(ptr + i, builtin::array_get_u8(arr, i)); i = i + 1; - continue l48; + continue l49; }; }; }; @@ -870,7 +887,7 @@ fn String^Eq::eq_bytes(a, b, len) { __for_1: block { i = 0; block { - l52: loop { + l53: loop { if (i < len) == 0 { break __for_1; }; @@ -878,7 +895,7 @@ fn String^Eq::eq_bytes(a, b, len) { return 0; }; i = i + 1; - continue l52; + continue l53; }; }; }; diff --git a/wado-compiler/tests/fixtures.golden/http-unmatched-async-export.wir.wado b/wado-compiler/tests/fixtures.golden/http-unmatched-async-export.wir.wado index dcbac6b57..82d38ec98 100644 --- a/wado-compiler/tests/fixtures.golden/http-unmatched-async-export.wir.wado +++ b/wado-compiler/tests/fixtures.golden/http-unmatched-async-export.wir.wado @@ -206,6 +206,16 @@ struct Result::Err { payload_0: ref "wasi:http/types.wado/ErrorCode", } +variant Option> { + Some(i32), + None, +} + +struct Option>::Some { + discriminant: i32, + payload_0: i32, +} + type "functype/mem/realloc" = fn(i32, i32, i32, i32) -> i32; type "functype/wasi/task-return" = fn(i32, i32, i32, i64, i32, i32, i32, i32); @@ -234,7 +244,7 @@ type "functype/wasi/waitable-join" = fn(i32, i32); type "functype/wasi/waitable-set-wait" = fn(i32, i32) -> i32; -type "functype/__cm_binding__Response_new" = fn(i32, i32, i32, i32) -> [i32, i32]; +type "functype/__cm_binding__Response_new" = fn(i32, ref Option>, i32) -> [i32, i32]; import fn realloc from "mem/realloc"; import fn task-return from "wasi/task-return"; @@ -393,7 +403,7 @@ fn handle(request) { headers = __cm_binding__Fields_new(); let __sroa___pattern_temp_1_0: i32; let __sroa___pattern_temp_1_1: i32; - multivalue_bind [__sroa___pattern_temp_1_0, __sroa___pattern_temp_1_1] = __cm_binding__Response_new(headers, 0, 0, trailers_future); + multivalue_bind [__sroa___pattern_temp_1_0, __sroa___pattern_temp_1_1] = __cm_binding__Response_new(headers, Option> { 1 }, trailers_future); response = __sroa___pattern_temp_1_0; __task_ret = Result::Ok { discriminant: 0, payload_0: response }; __tv_1 = 0; @@ -723,16 +733,23 @@ fn __cm_binding__Fields_new() { return "wasi/wasi:http/Fields::new"(); } -fn __cm_binding__Response_new(headers, contents_flat0, contents_flat1, trailers) { +fn __cm_binding__Response_new(headers, contents, trailers) { + let __contents_disc: i32; + let __contents_inner0: i32; let __outptr: i32; - let __lifted_result_5: i32; - let __lifted_result_6: i32; + let __lifted_result_7: i32; + let __lifted_result_8: i32; + __contents_disc = ref.test Option>::Some(contents); + __contents_inner0 = 0; + if ref.test Option>::Some(contents) { + __contents_inner0 = ref.cast Option>::Some(contents).payload_0; + }; __outptr = "mem/realloc"(0, 0, 4, 8); - "wasi/wasi:http/Response::new"(headers, contents_flat0, contents_flat1, trailers, __outptr); - __lifted_result_5 = builtin::load_i32(__outptr + 0); - __lifted_result_6 = builtin::load_i32(__outptr + 4); + "wasi/wasi:http/Response::new"(headers, __contents_disc, __contents_inner0, trailers, __outptr); + __lifted_result_7 = builtin::load_i32(__outptr + 0); + __lifted_result_8 = builtin::load_i32(__outptr + 4); drop("mem/realloc"(__outptr, 8, 4, 0)); - return __lifted_result_5; __lifted_result_6; + return __lifted_result_7; __lifted_result_8; } fn __cm_export__handle(request) { @@ -744,13 +761,13 @@ fn "core:internal/gc_array_to_memory"(arr, ptr, len) { // from core:internal __for_1: block { i = 0; block { - l40: loop { + l41: loop { if (i < len) == 0 { break __for_1; }; builtin::store_u8(ptr + i, builtin::array_get_u8(arr, i)); i = i + 1; - continue l40; + continue l41; }; }; }; diff --git a/wado-compiler/tests/fixtures.golden/stream-cm-future-drop.wir.wado b/wado-compiler/tests/fixtures.golden/stream-cm-future-drop.wir.wado index 303fccf52..1c8176906 100644 --- a/wado-compiler/tests/fixtures.golden/stream-cm-future-drop.wir.wado +++ b/wado-compiler/tests/fixtures.golden/stream-cm-future-drop.wir.wado @@ -206,6 +206,16 @@ struct Result::Err { payload_0: ref "wasi:http/types.wado/ErrorCode", } +variant Option> { + Some(i32), + None, +} + +struct Option>::Some { + discriminant: i32, + payload_0: i32, +} + type "functype/mem/realloc" = fn(i32, i32, i32, i32) -> i32; type "functype/wasi/task-return" = fn(i32, i32, i32, i64, i32, i32, i32, i32); @@ -228,7 +238,7 @@ type "functype/wasi/future-new" = fn() -> i64; type "functype/wasi/future-drop-writable" = fn(i32); -type "functype/__cm_binding__Response_new" = fn(i32, i32, i32, i32) -> [i32, i32]; +type "functype/__cm_binding__Response_new" = fn(i32, ref Option>, i32) -> [i32, i32]; import fn realloc from "mem/realloc"; import fn task-return from "wasi/task-return"; @@ -384,7 +394,7 @@ fn handle(request) { headers = __cm_binding__Fields_new(); let __sroa___pattern_temp_1_0: i32; let __sroa___pattern_temp_1_1: i32; - multivalue_bind [__sroa___pattern_temp_1_0, __sroa___pattern_temp_1_1] = __cm_binding__Response_new(headers, 0, 0, trailers_future); + multivalue_bind [__sroa___pattern_temp_1_0, __sroa___pattern_temp_1_1] = __cm_binding__Response_new(headers, Option> { 1 }, trailers_future); response = __sroa___pattern_temp_1_0; __task_ret = Result::Ok { discriminant: 0, payload_0: response }; __tv_1 = 0; @@ -695,16 +705,23 @@ fn __cm_binding__Fields_new() { return "wasi/wasi:http/Fields::new"(); } -fn __cm_binding__Response_new(headers, contents_flat0, contents_flat1, trailers) { +fn __cm_binding__Response_new(headers, contents, trailers) { + let __contents_disc: i32; + let __contents_inner0: i32; let __outptr: i32; - let __lifted_result_5: i32; - let __lifted_result_6: i32; + let __lifted_result_7: i32; + let __lifted_result_8: i32; + __contents_disc = ref.test Option>::Some(contents); + __contents_inner0 = 0; + if ref.test Option>::Some(contents) { + __contents_inner0 = ref.cast Option>::Some(contents).payload_0; + }; __outptr = "mem/realloc"(0, 0, 4, 8); - "wasi/wasi:http/Response::new"(headers, contents_flat0, contents_flat1, trailers, __outptr); - __lifted_result_5 = builtin::load_i32(__outptr + 0); - __lifted_result_6 = builtin::load_i32(__outptr + 4); + "wasi/wasi:http/Response::new"(headers, __contents_disc, __contents_inner0, trailers, __outptr); + __lifted_result_7 = builtin::load_i32(__outptr + 0); + __lifted_result_8 = builtin::load_i32(__outptr + 4); drop("mem/realloc"(__outptr, 8, 4, 0)); - return __lifted_result_5; __lifted_result_6; + return __lifted_result_7; __lifted_result_8; } fn __cm_export__handle(request) { @@ -716,13 +733,13 @@ fn "core:internal/gc_array_to_memory"(arr, ptr, len) { // from core:internal __for_1: block { i = 0; block { - l39: loop { + l40: loop { if (i < len) == 0 { break __for_1; }; builtin::store_u8(ptr + i, builtin::array_get_u8(arr, i)); i = i + 1; - continue l39; + continue l40; }; }; }; diff --git a/wado-compiler/tests/fixtures.golden/stream-cm-stderr-write.wir.wado b/wado-compiler/tests/fixtures.golden/stream-cm-stderr-write.wir.wado new file mode 100644 index 000000000..8ac7b6c3f --- /dev/null +++ b/wado-compiler/tests/fixtures.golden/stream-cm-stderr-write.wir.wado @@ -0,0 +1,224 @@ +// Golden file: WIR with -O2 optimization +// Source: wado-compiler/tests/fixtures/stream-cm-stderr-write.wado +// Generated by: mise run update-golden-fixtures + +array array (mut u8); + +variant Result { + Ok, + Err(i32), +} + +struct Result::Err { + discriminant: i32, + payload_0: i32, +} + +struct Array { // Array with T=u8 + mut repr: ref array, + mut used: i32, +} + +type "functype/mem/realloc" = fn(i32, i32, i32, i32) -> i32; + +type "functype/wasi/stream-write" = fn(i32, i32, i32) -> i32; + +type "functype/wasi/task-return" = fn(i32); + +type "functype/wasi/waitable-join" = fn(i32, i32); + +type "functype/wasi/waitable-set-drop" = fn(i32); + +type "functype/wasi/waitable-set-new" = fn() -> i32; + +type "functype/wasi/waitable-set-wait" = fn(i32, i32) -> i32; + +type "functype/wasi/wasi:cli/Stderr::write_via_stream" = fn(i32) -> i32; + +type "functype/run" = fn(); + +type "functype/__cm_binding__Stderr_write_via_stream" = fn(i32) -> i32; + +type "functype/__cm_export__run" = fn(); + +type "functype/core:internal/gc_array_to_memory" = fn(ref array, i32, i32); + +type "functype/core:internal/cm_lower_list_u8" = fn(ref array, i32) -> i64; + +type "functype/core:internal/wait_for_blocked" = fn(i32) -> i32; + +type "functype/core:internal/cm_stream_write_u8" = fn(i32, ref Array); + +type "functype/Array::push" = fn(ref Array, u8); + +type "functype/Array::grow" = fn(ref Array); + +type "functype/wasi/stream-new" = fn() -> i64; + +type "functype/wasi/stream-drop-writable" = fn(i32); + +type "functype/wasi/future-read:transmission-cli" = fn(i32, i32) -> i32; + +import fn realloc from "mem/realloc"; +import fn stream-write from "wasi/stream-write"; +import fn task-return from "wasi/task-return"; +import fn waitable-join from "wasi/waitable-join"; +import fn waitable-set-drop from "wasi/waitable-set-drop"; +import fn waitable-set-new from "wasi/waitable-set-new"; +import fn waitable-set-wait from "wasi/waitable-set-wait"; +import fn wasi:cli/Stderr::write_via_stream from "wasi/wasi:cli/Stderr::write_via_stream"; +import memory (1) from "mem/memory"; +import fn stream-new from "wasi/stream-new"; +import fn stream-drop-writable from "wasi/stream-drop-writable"; +import fn future-read:transmission-cli from "wasi/future-read:transmission-cli"; + +fn run() with Stderr { + let rx: i32; + let tx: i32; + let subtask: i32; + let __local_3: ref Array; + let data: ref Array; + let __pair_temp_1: i64; + __pair_temp_1 = "wasi/stream-new"(); + rx = builtin::i32_wrap_i64(__pair_temp_1); + tx = builtin::i32_wrap_i64(__pair_temp_1 >>u 32_i64); + subtask = __cm_binding__Stderr_write_via_stream(rx); + data = __seq_lit: block -> ref Array { + __local_3 = Array { repr: array.new_fixed(101, 114, 114, 32, 109, 115, 103, 10), used: 8 }; + break __seq_lit: __local_3; + }; + "core:internal/cm_stream_write_u8"(tx, data); + "wasi/stream-drop-writable"(tx); + drop(let __fr_handle_2: i32; let __fr_ptr_2: i32; let __fr_result_2: i32; __fr_handle_2 = subtask; __fr_ptr_2 = "mem/realloc"(0, 0, 8, 40); __fr_result_2 = "wasi/future-read:transmission-cli"(__fr_handle_2, __fr_ptr_2); if __fr_result_2 == -1 { + let __fr_ws_2: i32; + let __fr_evtptr_2: i32; + __fr_ws_2 = "wasi/waitable-set-new"(); + "wasi/waitable-join"(__fr_handle_2, __fr_ws_2); + __fr_evtptr_2 = "mem/realloc"(0, 0, 4, 8); + drop("wasi/waitable-set-wait"(__fr_ws_2, __fr_evtptr_2)); + drop("mem/realloc"(__fr_evtptr_2, 8, 4, 0)); + "wasi/waitable-join"(__fr_handle_2, 0); + "wasi/waitable-set-drop"(__fr_ws_2); + __fr_result_2 = 0; + }; let __fr_opt_3: ref null Result; __fr_opt_3 = if (__fr_result_2 & 15) == 0 -> ref null Result { + ref.as_non_null(if builtin::load_i32(__fr_ptr_2) == 0 -> ref Result { + Result { 0 }; + } else { + unreachable; + }); + } else { + ref.null none; + }; drop("mem/realloc"(__fr_ptr_2, 40, 8, 0)); __fr_opt_3); +} + +fn __cm_binding__Stderr_write_via_stream(data) { + return "wasi/wasi:cli/Stderr::write_via_stream"(data); +} + +fn __cm_export__run() { + run(); + "wasi/task-return"(0); +} + +fn "core:internal/gc_array_to_memory"(arr, ptr, len) { // from core:internal + let i: i32; + __for_1: block { + i = 0; + block { + l4: loop { + if (i < len) == 0 { + break __for_1; + }; + builtin::store_u8(ptr + i, builtin::array_get_u8(arr, i)); + i = i + 1; + continue l4; + }; + }; + }; +} + +fn "core:internal/cm_lower_list_u8"(data, len) { // from core:internal + let ptr: i32; + ptr = "mem/realloc"(0, 0, 1, len); + "core:internal/gc_array_to_memory"(data, ptr, len); + return builtin::i64_extend_i32_s(ptr) | (builtin::i64_extend_i32_s(len) << 32_i64); +} + +fn "core:internal/wait_for_blocked"(handle) { // from core:internal + let ws: i32; + let evt_ptr: i32; + let payload: i32; + ws = "wasi/waitable-set-new"(); + "wasi/waitable-join"(handle, ws); + evt_ptr = "mem/realloc"(0, 0, 4, 8); + drop("wasi/waitable-set-wait"(ws, evt_ptr)); + payload = builtin::load_i32(evt_ptr + 4); + drop("mem/realloc"(evt_ptr, 8, 4, 0)); + "wasi/waitable-set-drop"(ws); + return payload; +} + +fn "core:internal/cm_stream_write_u8"(handle, data) { // from core:internal + let packed: i64; + let ptr: i32; + let len: i32; + let result: i32; + let __local_9: ref array; + let __local_10: i32; + packed = __inline_cm_lower_array_u8_0: block -> i64 { + __local_9 = data.repr; + __local_10 = data.used; + break __inline_cm_lower_array_u8_0: "core:internal/cm_lower_list_u8"(__local_9, __local_10); + }; + ptr = builtin::i32_wrap_i64(packed); + len = builtin::i32_wrap_i64(packed >> 32_i64); + result = "wasi/stream-write"(handle, ptr, len); + if result == -1 { + drop("core:internal/wait_for_blocked"(handle)); + }; + drop("mem/realloc"(ptr, len, 1, 0)); +} + +fn Array::push(self, value) { + let used: i32; + used = self.used; + if builtin::unlikely(used >= builtin::array_len(self.repr)) { + Array::grow(self); + }; + builtin::array_set_u8(self.repr, used, value); + self.used = used + 1; +} + +fn Array::grow(self) { + let capacity: i32; + let new_capacity: i32; + let new_repr: ref array; + let old_repr: ref array; + let used: i32; + let i: i32; + let __local_7: i32; + capacity = builtin::array_len(self.repr); + new_capacity = __inline_i32_max_0: block -> i32 { + __local_7 = capacity * 2; + break __inline_i32_max_0: select i32(__local_7 > 4, __local_7, 4); + }; + new_repr = builtin::array_new(new_capacity); + old_repr = self.repr; + used = self.used; + __for_0: block { + i = 0; + block { + l9: loop { + if (i < used) == 0 { + break __for_0; + }; + builtin::array_set_u8(new_repr, i, builtin::array_get(old_repr, i)); + i = i + 1; + continue l9; + }; + }; + }; + self.repr = new_repr; +} + +export fn __cm_export__run as "run" diff --git a/wado-compiler/tests/fixtures.golden/stream-cm-stdin-pipe.wir.wado b/wado-compiler/tests/fixtures.golden/stream-cm-stdin-pipe.wir.wado new file mode 100644 index 000000000..20dbbe718 --- /dev/null +++ b/wado-compiler/tests/fixtures.golden/stream-cm-stdin-pipe.wir.wado @@ -0,0 +1,129 @@ +// Golden file: WIR with -O2 optimization +// Source: wado-compiler/tests/fixtures/stream-cm-stdin-pipe.wado +// Generated by: mise run update-golden-fixtures + +variant Result { + Ok, + Err(i32), +} + +struct Result::Err { + discriminant: i32, + payload_0: i32, +} + +type "functype/mem/realloc" = fn(i32, i32, i32, i32) -> i32; + +type "functype/wasi/task-return" = fn(i32); + +type "functype/wasi/wasi:cli/Stdin::read_via_stream" = fn(i32); + +type "functype/wasi/wasi:cli/Stdout::write_via_stream" = fn(i32) -> i32; + +type "functype/run" = fn(); + +type "functype/__cm_binding__Stdout_write_via_stream" = fn(i32) -> i32; + +type "functype/__cm_export__run" = fn(); + +type "functype/wasi/future-read:transmission-cli" = fn(i32, i32) -> i32; + +type "functype/wasi/waitable-set-new" = fn() -> i32; + +type "functype/wasi/waitable-join" = fn(i32, i32); + +type "functype/wasi/waitable-set-wait" = fn(i32, i32) -> i32; + +type "functype/wasi/waitable-set-drop" = fn(i32); + +type "functype/__cm_binding__Stdin_read_via_stream" = fn() -> [i32, i32]; + +import fn realloc from "mem/realloc"; +import fn task-return from "wasi/task-return"; +import fn wasi:cli/Stdin::read_via_stream from "wasi/wasi:cli/Stdin::read_via_stream"; +import fn wasi:cli/Stdout::write_via_stream from "wasi/wasi:cli/Stdout::write_via_stream"; +import memory (1) from "mem/memory"; +import fn future-read:transmission-cli from "wasi/future-read:transmission-cli"; +import fn waitable-set-new from "wasi/waitable-set-new"; +import fn waitable-join from "wasi/waitable-join"; +import fn waitable-set-wait from "wasi/waitable-set-wait"; +import fn waitable-set-drop from "wasi/waitable-set-drop"; + +fn run() with Stdout, Stdin { + let stdin_stream: i32; + let subtask: i32; + let __sroa___pattern_temp_0_0: i32; + let __sroa___pattern_temp_0_1: i32; + multivalue_bind [__sroa___pattern_temp_0_0, __sroa___pattern_temp_0_1] = __cm_binding__Stdin_read_via_stream(); + stdin_stream = __sroa___pattern_temp_0_0; + subtask = __cm_binding__Stdout_write_via_stream(stdin_stream); + drop(let __fr_handle_1: i32; let __fr_ptr_1: i32; let __fr_result_1: i32; __fr_handle_1 = subtask; __fr_ptr_1 = "mem/realloc"(0, 0, 8, 40); __fr_result_1 = "wasi/future-read:transmission-cli"(__fr_handle_1, __fr_ptr_1); if __fr_result_1 == -1 { + let __fr_ws_1: i32; + let __fr_evtptr_1: i32; + __fr_ws_1 = "wasi/waitable-set-new"(); + "wasi/waitable-join"(__fr_handle_1, __fr_ws_1); + __fr_evtptr_1 = "mem/realloc"(0, 0, 4, 8); + drop("wasi/waitable-set-wait"(__fr_ws_1, __fr_evtptr_1)); + drop("mem/realloc"(__fr_evtptr_1, 8, 4, 0)); + "wasi/waitable-join"(__fr_handle_1, 0); + "wasi/waitable-set-drop"(__fr_ws_1); + __fr_result_1 = 0; + }; let __fr_opt_2: ref null Result; __fr_opt_2 = if (__fr_result_1 & 15) == 0 -> ref null Result { + ref.as_non_null(if builtin::load_i32(__fr_ptr_1) == 0 -> ref Result { + Result { 0 }; + } else { + unreachable; + }); + } else { + ref.null none; + }; drop("mem/realloc"(__fr_ptr_1, 40, 8, 0)); __fr_opt_2); +} + +fn __cm_binding__Stdout_write_via_stream(data) { + return "wasi/wasi:cli/Stdout::write_via_stream"(data); +} + +fn __cm_binding__Stdin_read_via_stream() { + let __outptr: i32; + let __lifted_result_1: i32; + let __lifted_result_2: i32; + __outptr = "mem/realloc"(0, 0, 4, 8); + "wasi/wasi:cli/Stdin::read_via_stream"(__outptr); + __lifted_result_1 = builtin::load_i32(__outptr + 0); + __lifted_result_2 = builtin::load_i32(__outptr + 4); + drop("mem/realloc"(__outptr, 8, 4, 0)); + return __lifted_result_1; __lifted_result_2; +} + +fn __cm_export__run() { + let stdin_stream: i32; + let subtask: i32; + let __sroa___pattern_temp_0_0: i32; + let __sroa___pattern_temp_0_1: i32; + multivalue_bind [__sroa___pattern_temp_0_0, __sroa___pattern_temp_0_1] = __cm_binding__Stdin_read_via_stream(); + stdin_stream = __sroa___pattern_temp_0_0; + subtask = __cm_binding__Stdout_write_via_stream(stdin_stream); + drop(let __fr_handle_1: i32; let __fr_ptr_1: i32; let __fr_result_1: i32; __fr_handle_1 = subtask; __fr_ptr_1 = "mem/realloc"(0, 0, 8, 40); __fr_result_1 = "wasi/future-read:transmission-cli"(__fr_handle_1, __fr_ptr_1); if __fr_result_1 == -1 { + let __fr_ws_1: i32; + let __fr_evtptr_1: i32; + __fr_ws_1 = "wasi/waitable-set-new"(); + "wasi/waitable-join"(__fr_handle_1, __fr_ws_1); + __fr_evtptr_1 = "mem/realloc"(0, 0, 4, 8); + drop("wasi/waitable-set-wait"(__fr_ws_1, __fr_evtptr_1)); + drop("mem/realloc"(__fr_evtptr_1, 8, 4, 0)); + "wasi/waitable-join"(__fr_handle_1, 0); + "wasi/waitable-set-drop"(__fr_ws_1); + __fr_result_1 = 0; + }; let __fr_opt_2: ref null Result; __fr_opt_2 = if (__fr_result_1 & 15) == 0 -> ref null Result { + ref.as_non_null(if builtin::load_i32(__fr_ptr_1) == 0 -> ref Result { + Result { 0 }; + } else { + unreachable; + }); + } else { + ref.null none; + }; drop("mem/realloc"(__fr_ptr_1, 40, 8, 0)); __fr_opt_2); + "wasi/task-return"(0); +} + +export fn __cm_export__run as "run" diff --git a/wado-compiler/tests/fixtures.golden/stream-http-echo.wir.wado b/wado-compiler/tests/fixtures.golden/stream-http-echo.wir.wado index b7cb7803b..682bc8e1c 100644 --- a/wado-compiler/tests/fixtures.golden/stream-http-echo.wir.wado +++ b/wado-compiler/tests/fixtures.golden/stream-http-echo.wir.wado @@ -214,6 +214,16 @@ struct Result::Err { payload_0: ref "wasi:http/types.wado/ErrorCode", } +variant Option> { + Some(i32), + None, +} + +struct Option>::Some { + discriminant: i32, + payload_0: i32, +} + struct Array { // Array with T=u8 mut repr: ref array, mut used: i32, @@ -286,7 +296,7 @@ type "functype/wasi/future-write" = fn(i32, i32) -> i32; type "functype/__cm_binding__Request_consume_body" = fn(i32, i32) -> [i32, i32]; -type "functype/__cm_binding__Response_new" = fn(i32, i32, i32, i32) -> [i32, i32]; +type "functype/__cm_binding__Response_new" = fn(i32, ref Option>, i32) -> [i32, i32]; import fn realloc from "mem/realloc"; import fn stream-read from "wasi/stream-read"; @@ -489,7 +499,7 @@ fn handle(request) { headers = __cm_binding__Fields_new(); let __sroa___pattern_temp_4_0: i32; let __sroa___pattern_temp_4_1: i32; - multivalue_bind [__sroa___pattern_temp_4_0, __sroa___pattern_temp_4_1] = __cm_binding__Response_new(headers, 1, resp_rx, trailers_future); + multivalue_bind [__sroa___pattern_temp_4_0, __sroa___pattern_temp_4_1] = __cm_binding__Response_new(headers, Option>::Some { discriminant: 0, payload_0: resp_rx }, trailers_future); response = __sroa___pattern_temp_4_0; __task_ret = Result::Ok { discriminant: 0, payload_0: response }; __tv_1 = 0; @@ -845,16 +855,23 @@ fn __cm_binding__Fields_new() { return "wasi/wasi:http/Fields::new"(); } -fn __cm_binding__Response_new(headers, contents_flat0, contents_flat1, trailers) { +fn __cm_binding__Response_new(headers, contents, trailers) { + let __contents_disc: i32; + let __contents_inner0: i32; let __outptr: i32; - let __lifted_result_5: i32; - let __lifted_result_6: i32; + let __lifted_result_7: i32; + let __lifted_result_8: i32; + __contents_disc = ref.test Option>::Some(contents); + __contents_inner0 = 0; + if ref.test Option>::Some(contents) { + __contents_inner0 = ref.cast Option>::Some(contents).payload_0; + }; __outptr = "mem/realloc"(0, 0, 4, 8); - "wasi/wasi:http/Response::new"(headers, contents_flat0, contents_flat1, trailers, __outptr); - __lifted_result_5 = builtin::load_i32(__outptr + 0); - __lifted_result_6 = builtin::load_i32(__outptr + 4); + "wasi/wasi:http/Response::new"(headers, __contents_disc, __contents_inner0, trailers, __outptr); + __lifted_result_7 = builtin::load_i32(__outptr + 0); + __lifted_result_8 = builtin::load_i32(__outptr + 4); drop("mem/realloc"(__outptr, 8, 4, 0)); - return __lifted_result_5; __lifted_result_6; + return __lifted_result_7; __lifted_result_8; } fn __cm_export__handle(request) { @@ -868,13 +885,13 @@ fn "core:internal/memory_to_gc_array"(ptr, len) { // from core:internal __for_0: block { i = 0; block { - l46: loop { + l47: loop { if (i < len) == 0 { break __for_0; }; builtin::array_set_u8(arr, i, builtin::load_u8(ptr + i) & 255); i = i + 1; - continue l46; + continue l47; }; }; }; @@ -886,13 +903,13 @@ fn "core:internal/gc_array_to_memory"(arr, ptr, len) { // from core:internal __for_1: block { i = 0; block { - l49: loop { + l50: loop { if (i < len) == 0 { break __for_1; }; builtin::store_u8(ptr + i, builtin::array_get_u8(arr, i)); i = i + 1; - continue l49; + continue l50; }; }; }; @@ -1006,13 +1023,13 @@ fn Array>::grow(self) { __for_0: block { i = 0; block { - l56: loop { + l57: loop { if (i < used) == 0 { break __for_0; }; builtin::array_set>(new_repr, i, builtin::array_get>(old_repr, i)); i = i + 1; - continue l56; + continue l57; }; }; }; diff --git a/wado-compiler/tests/fixtures.golden/stream-http-read-request-body.wir.wado b/wado-compiler/tests/fixtures.golden/stream-http-read-request-body.wir.wado index e5c045d03..ad2393806 100644 --- a/wado-compiler/tests/fixtures.golden/stream-http-read-request-body.wir.wado +++ b/wado-compiler/tests/fixtures.golden/stream-http-read-request-body.wir.wado @@ -206,6 +206,16 @@ struct Result::Err { payload_0: ref "wasi:http/types.wado/ErrorCode", } +variant Option> { + Some(i32), + None, +} + +struct Option>::Some { + discriminant: i32, + payload_0: i32, +} + struct Array { // Array with T=u8 mut repr: ref array, mut used: i32, @@ -269,7 +279,7 @@ type "functype/wasi/future-write" = fn(i32, i32) -> i32; type "functype/__cm_binding__Request_consume_body" = fn(i32, i32) -> [i32, i32]; -type "functype/__cm_binding__Response_new" = fn(i32, i32, i32, i32) -> [i32, i32]; +type "functype/__cm_binding__Response_new" = fn(i32, ref Option>, i32) -> [i32, i32]; type "functype/core:internal/cm_stream_read_u8" = fn(i32, i32) -> [ref array, i32]; @@ -471,7 +481,7 @@ fn handle(request) { headers = __cm_binding__Fields_new(); let __sroa___pattern_temp_4_0: i32; let __sroa___pattern_temp_4_1: i32; - multivalue_bind [__sroa___pattern_temp_4_0, __sroa___pattern_temp_4_1] = __cm_binding__Response_new(headers, 1, resp_body_rx, trailers_future); + multivalue_bind [__sroa___pattern_temp_4_0, __sroa___pattern_temp_4_1] = __cm_binding__Response_new(headers, Option>::Some { discriminant: 0, payload_0: resp_body_rx }, trailers_future); response = __sroa___pattern_temp_4_0; __task_ret = Result::Ok { discriminant: 0, payload_0: response }; __tv_1 = 0; @@ -820,16 +830,23 @@ fn __cm_binding__Fields_new() { return "wasi/wasi:http/Fields::new"(); } -fn __cm_binding__Response_new(headers, contents_flat0, contents_flat1, trailers) { +fn __cm_binding__Response_new(headers, contents, trailers) { + let __contents_disc: i32; + let __contents_inner0: i32; let __outptr: i32; - let __lifted_result_5: i32; - let __lifted_result_6: i32; + let __lifted_result_7: i32; + let __lifted_result_8: i32; + __contents_disc = ref.test Option>::Some(contents); + __contents_inner0 = 0; + if ref.test Option>::Some(contents) { + __contents_inner0 = ref.cast Option>::Some(contents).payload_0; + }; __outptr = "mem/realloc"(0, 0, 4, 8); - "wasi/wasi:http/Response::new"(headers, contents_flat0, contents_flat1, trailers, __outptr); - __lifted_result_5 = builtin::load_i32(__outptr + 0); - __lifted_result_6 = builtin::load_i32(__outptr + 4); + "wasi/wasi:http/Response::new"(headers, __contents_disc, __contents_inner0, trailers, __outptr); + __lifted_result_7 = builtin::load_i32(__outptr + 0); + __lifted_result_8 = builtin::load_i32(__outptr + 4); drop("mem/realloc"(__outptr, 8, 4, 0)); - return __lifted_result_5; __lifted_result_6; + return __lifted_result_7; __lifted_result_8; } fn __cm_export__handle(request) { @@ -843,13 +860,13 @@ fn "core:internal/memory_to_gc_array"(ptr, len) { // from core:internal __for_0: block { i = 0; block { - l43: loop { + l44: loop { if (i < len) == 0 { break __for_0; }; builtin::array_set_u8(arr, i, builtin::load_u8(ptr + i) & 255); i = i + 1; - continue l43; + continue l44; }; }; }; @@ -861,13 +878,13 @@ fn "core:internal/gc_array_to_memory"(arr, ptr, len) { // from core:internal __for_1: block { i = 0; block { - l46: loop { + l47: loop { if (i < len) == 0 { break __for_1; }; builtin::store_u8(ptr + i, builtin::array_get_u8(arr, i)); i = i + 1; - continue l46; + continue l47; }; }; }; @@ -971,13 +988,13 @@ fn Array::grow(self) { __for_0: block { i = 0; block { - l52: loop { + l53: loop { if (i < used) == 0 { break __for_0; }; builtin::array_set_u8(new_repr, i, builtin::array_get(old_repr, i)); i = i + 1; - continue l52; + continue l53; }; }; }; diff --git a/wado-compiler/tests/fixtures.golden/stream-http-response-body-multi.wir.wado b/wado-compiler/tests/fixtures.golden/stream-http-response-body-multi.wir.wado index 3bb3e97e8..d22723e95 100644 --- a/wado-compiler/tests/fixtures.golden/stream-http-response-body-multi.wir.wado +++ b/wado-compiler/tests/fixtures.golden/stream-http-response-body-multi.wir.wado @@ -206,6 +206,16 @@ struct Result::Err { payload_0: ref "wasi:http/types.wado/ErrorCode", } +variant Option> { + Some(i32), + None, +} + +struct Option>::Some { + discriminant: i32, + payload_0: i32, +} + struct Array { // Array with T=u8 mut repr: ref array, mut used: i32, @@ -257,7 +267,7 @@ type "functype/wasi/stream-drop-writable" = fn(i32); type "functype/wasi/future-write" = fn(i32, i32) -> i32; -type "functype/__cm_binding__Response_new" = fn(i32, i32, i32, i32) -> [i32, i32]; +type "functype/__cm_binding__Response_new" = fn(i32, ref Option>, i32) -> [i32, i32]; import fn realloc from "mem/realloc"; import fn stream-write from "wasi/stream-write"; @@ -430,7 +440,7 @@ fn handle(request) { headers = __cm_binding__Fields_new(); let __sroa___pattern_temp_2_0: i32; let __sroa___pattern_temp_2_1: i32; - multivalue_bind [__sroa___pattern_temp_2_0, __sroa___pattern_temp_2_1] = __cm_binding__Response_new(headers, 1, body_rx, trailers_future); + multivalue_bind [__sroa___pattern_temp_2_0, __sroa___pattern_temp_2_1] = __cm_binding__Response_new(headers, Option>::Some { discriminant: 0, payload_0: body_rx }, trailers_future); response = __sroa___pattern_temp_2_0; __task_ret = Result::Ok { discriminant: 0, payload_0: response }; __tv_1 = 0; @@ -771,16 +781,23 @@ fn __cm_binding__Fields_new() { return "wasi/wasi:http/Fields::new"(); } -fn __cm_binding__Response_new(headers, contents_flat0, contents_flat1, trailers) { +fn __cm_binding__Response_new(headers, contents, trailers) { + let __contents_disc: i32; + let __contents_inner0: i32; let __outptr: i32; - let __lifted_result_5: i32; - let __lifted_result_6: i32; + let __lifted_result_7: i32; + let __lifted_result_8: i32; + __contents_disc = ref.test Option>::Some(contents); + __contents_inner0 = 0; + if ref.test Option>::Some(contents) { + __contents_inner0 = ref.cast Option>::Some(contents).payload_0; + }; __outptr = "mem/realloc"(0, 0, 4, 8); - "wasi/wasi:http/Response::new"(headers, contents_flat0, contents_flat1, trailers, __outptr); - __lifted_result_5 = builtin::load_i32(__outptr + 0); - __lifted_result_6 = builtin::load_i32(__outptr + 4); + "wasi/wasi:http/Response::new"(headers, __contents_disc, __contents_inner0, trailers, __outptr); + __lifted_result_7 = builtin::load_i32(__outptr + 0); + __lifted_result_8 = builtin::load_i32(__outptr + 4); drop("mem/realloc"(__outptr, 8, 4, 0)); - return __lifted_result_5; __lifted_result_6; + return __lifted_result_7; __lifted_result_8; } fn __cm_export__handle(request) { @@ -792,13 +809,13 @@ fn "core:internal/gc_array_to_memory"(arr, ptr, len) { // from core:internal __for_1: block { i = 0; block { - l40: loop { + l41: loop { if (i < len) == 0 { break __for_1; }; builtin::store_u8(ptr + i, builtin::array_get_u8(arr, i)); i = i + 1; - continue l40; + continue l41; }; }; }; @@ -886,13 +903,13 @@ fn Array::grow(self) { __for_0: block { i = 0; block { - l45: loop { + l46: loop { if (i < used) == 0 { break __for_0; }; builtin::array_set_u8(new_repr, i, builtin::array_get(old_repr, i)); i = i + 1; - continue l45; + continue l46; }; }; }; diff --git a/wado-compiler/tests/fixtures.golden/stream-http-response-body-string.wir.wado b/wado-compiler/tests/fixtures.golden/stream-http-response-body-string.wir.wado index 52171a753..86a5f5098 100644 --- a/wado-compiler/tests/fixtures.golden/stream-http-response-body-string.wir.wado +++ b/wado-compiler/tests/fixtures.golden/stream-http-response-body-string.wir.wado @@ -212,6 +212,16 @@ struct Result::Err { payload_0: ref "wasi:http/types.wado/ErrorCode", } +variant Option> { + Some(i32), + None, +} + +struct Option>::Some { + discriminant: i32, + payload_0: i32, +} + struct Array { // Array with T=u8 mut repr: ref array, mut used: i32, @@ -265,7 +275,7 @@ type "functype/wasi/stream-drop-writable" = fn(i32); type "functype/wasi/future-write" = fn(i32, i32) -> i32; -type "functype/__cm_binding__Response_new" = fn(i32, i32, i32, i32) -> [i32, i32]; +type "functype/__cm_binding__Response_new" = fn(i32, ref Option>, i32) -> [i32, i32]; type "functype/StrCharIter^Iterator::next" = fn(ref StrCharIter) -> [i32, char]; @@ -464,7 +474,7 @@ fn handle(request) { headers = __cm_binding__Fields_new(); let __sroa___pattern_temp_2_0: i32; let __sroa___pattern_temp_2_1: i32; - multivalue_bind [__sroa___pattern_temp_2_0, __sroa___pattern_temp_2_1] = __cm_binding__Response_new(headers, 1, body_rx, trailers_future); + multivalue_bind [__sroa___pattern_temp_2_0, __sroa___pattern_temp_2_1] = __cm_binding__Response_new(headers, Option>::Some { discriminant: 0, payload_0: body_rx }, trailers_future); response = __sroa___pattern_temp_2_0; __task_ret = Result::Ok { discriminant: 0, payload_0: response }; __tv_1 = 0; @@ -797,16 +807,23 @@ fn __cm_binding__Fields_new() { return "wasi/wasi:http/Fields::new"(); } -fn __cm_binding__Response_new(headers, contents_flat0, contents_flat1, trailers) { +fn __cm_binding__Response_new(headers, contents, trailers) { + let __contents_disc: i32; + let __contents_inner0: i32; let __outptr: i32; - let __lifted_result_5: i32; - let __lifted_result_6: i32; + let __lifted_result_7: i32; + let __lifted_result_8: i32; + __contents_disc = ref.test Option>::Some(contents); + __contents_inner0 = 0; + if ref.test Option>::Some(contents) { + __contents_inner0 = ref.cast Option>::Some(contents).payload_0; + }; __outptr = "mem/realloc"(0, 0, 4, 8); - "wasi/wasi:http/Response::new"(headers, contents_flat0, contents_flat1, trailers, __outptr); - __lifted_result_5 = builtin::load_i32(__outptr + 0); - __lifted_result_6 = builtin::load_i32(__outptr + 4); + "wasi/wasi:http/Response::new"(headers, __contents_disc, __contents_inner0, trailers, __outptr); + __lifted_result_7 = builtin::load_i32(__outptr + 0); + __lifted_result_8 = builtin::load_i32(__outptr + 4); drop("mem/realloc"(__outptr, 8, 4, 0)); - return __lifted_result_5; __lifted_result_6; + return __lifted_result_7; __lifted_result_8; } fn __cm_export__handle(request) { @@ -818,13 +835,13 @@ fn "core:internal/gc_array_to_memory"(arr, ptr, len) { // from core:internal __for_1: block { i = 0; block { - l43: loop { + l44: loop { if (i < len) == 0 { break __for_1; }; builtin::store_u8(ptr + i, builtin::array_get_u8(arr, i)); i = i + 1; - continue l43; + continue l44; }; }; }; @@ -956,13 +973,13 @@ fn Array::grow(self) { __for_0: block { i = 0; block { - l52: loop { + l53: loop { if (i < used) == 0 { break __for_0; }; builtin::array_set_u8(new_repr, i, builtin::array_get(old_repr, i)); i = i + 1; - continue l52; + continue l53; }; }; }; diff --git a/wado-compiler/tests/fixtures.golden/stream-http-response-body.wir.wado b/wado-compiler/tests/fixtures.golden/stream-http-response-body.wir.wado index bcb7784fd..0d098101f 100644 --- a/wado-compiler/tests/fixtures.golden/stream-http-response-body.wir.wado +++ b/wado-compiler/tests/fixtures.golden/stream-http-response-body.wir.wado @@ -206,6 +206,16 @@ struct Result::Err { payload_0: ref "wasi:http/types.wado/ErrorCode", } +variant Option> { + Some(i32), + None, +} + +struct Option>::Some { + discriminant: i32, + payload_0: i32, +} + struct Array { // Array with T=u8 mut repr: ref array, mut used: i32, @@ -257,7 +267,7 @@ type "functype/wasi/stream-drop-writable" = fn(i32); type "functype/wasi/future-write" = fn(i32, i32) -> i32; -type "functype/__cm_binding__Response_new" = fn(i32, i32, i32, i32) -> [i32, i32]; +type "functype/__cm_binding__Response_new" = fn(i32, ref Option>, i32) -> [i32, i32]; import fn realloc from "mem/realloc"; import fn stream-write from "wasi/stream-write"; @@ -428,7 +438,7 @@ fn handle(request) { headers = __cm_binding__Fields_new(); let __sroa___pattern_temp_2_0: i32; let __sroa___pattern_temp_2_1: i32; - multivalue_bind [__sroa___pattern_temp_2_0, __sroa___pattern_temp_2_1] = __cm_binding__Response_new(headers, 1, body_rx, trailers_future); + multivalue_bind [__sroa___pattern_temp_2_0, __sroa___pattern_temp_2_1] = __cm_binding__Response_new(headers, Option>::Some { discriminant: 0, payload_0: body_rx }, trailers_future); response = __sroa___pattern_temp_2_0; __task_ret = Result::Ok { discriminant: 0, payload_0: response }; __tv_1 = 0; @@ -764,16 +774,23 @@ fn __cm_binding__Fields_new() { return "wasi/wasi:http/Fields::new"(); } -fn __cm_binding__Response_new(headers, contents_flat0, contents_flat1, trailers) { +fn __cm_binding__Response_new(headers, contents, trailers) { + let __contents_disc: i32; + let __contents_inner0: i32; let __outptr: i32; - let __lifted_result_5: i32; - let __lifted_result_6: i32; + let __lifted_result_7: i32; + let __lifted_result_8: i32; + __contents_disc = ref.test Option>::Some(contents); + __contents_inner0 = 0; + if ref.test Option>::Some(contents) { + __contents_inner0 = ref.cast Option>::Some(contents).payload_0; + }; __outptr = "mem/realloc"(0, 0, 4, 8); - "wasi/wasi:http/Response::new"(headers, contents_flat0, contents_flat1, trailers, __outptr); - __lifted_result_5 = builtin::load_i32(__outptr + 0); - __lifted_result_6 = builtin::load_i32(__outptr + 4); + "wasi/wasi:http/Response::new"(headers, __contents_disc, __contents_inner0, trailers, __outptr); + __lifted_result_7 = builtin::load_i32(__outptr + 0); + __lifted_result_8 = builtin::load_i32(__outptr + 4); drop("mem/realloc"(__outptr, 8, 4, 0)); - return __lifted_result_5; __lifted_result_6; + return __lifted_result_7; __lifted_result_8; } fn __cm_export__handle(request) { @@ -785,13 +802,13 @@ fn "core:internal/gc_array_to_memory"(arr, ptr, len) { // from core:internal __for_1: block { i = 0; block { - l40: loop { + l41: loop { if (i < len) == 0 { break __for_1; }; builtin::store_u8(ptr + i, builtin::array_get_u8(arr, i)); i = i + 1; - continue l40; + continue l41; }; }; }; @@ -879,13 +896,13 @@ fn Array::grow(self) { __for_0: block { i = 0; block { - l45: loop { + l46: loop { if (i < used) == 0 { break __for_0; }; builtin::array_set_u8(new_repr, i, builtin::array_get(old_repr, i)); i = i + 1; - continue l45; + continue l46; }; }; }; diff --git a/wado-compiler/tests/fixtures/cm-future-read-cli.wado b/wado-compiler/tests/fixtures/cm-future-read-cli.wado index e87ddfbee..4f41abde1 100644 --- a/wado-compiler/tests/fixtures/cm-future-read-cli.wado +++ b/wado-compiler/tests/fixtures/cm-future-read-cli.wado @@ -1,4 +1,3 @@ -#![TODO] // Future::read E2E test (CLI world) // Tests Future::read() and FutureWritable::write() with scalar i32 in CLI world. @@ -19,9 +18,6 @@ export fn run() with Stdout { } else { println("none"); } - - // Drop the future handle - future_rx.drop(); } __DATA__ diff --git a/wado-compiler/tests/fixtures/cm-future-read.wado b/wado-compiler/tests/fixtures/cm-future-read.wado index 0bc6cbb0d..3baee5faa 100644 --- a/wado-compiler/tests/fixtures/cm-future-read.wado +++ b/wado-compiler/tests/fixtures/cm-future-read.wado @@ -1,4 +1,3 @@ -#![TODO] // Future::read E2E test // Tests Future::read() and FutureWritable::write() with scalar numeric types. // The CM spec allows same-instance read/write for number types via the @@ -16,9 +15,6 @@ export async fn handle(request: Request) -> Result { // Read from the future — should get Some(42) let result = future_rx.read(); - // Drop the future handle - future_rx.drop(); - // Return 200 OK let [trailers_future, trailers_tx] = Future::, ErrorCode>>::new(); let headers = Fields::new(); diff --git a/wado-compiler/tests/fixtures/http-client-send-simple.wado b/wado-compiler/tests/fixtures/http-client-send-simple.wado index 7ef50a431..030cd59d9 100644 --- a/wado-compiler/tests/fixtures/http-client-send-simple.wado +++ b/wado-compiler/tests/fixtures/http-client-send-simple.wado @@ -1,25 +1,29 @@ -#![TODO] // Minimal test: Client::send returns Result and // task return forwards it directly. This exercises the variant lowering // in the task return expansion for ErrorCode (a variant with mixed // payload/no-payload cases). -use { Request, Response, ErrorCode, Fields, Trailers } from "wasi:http"; +use { Request, Response, ErrorCode, Fields, Trailers, Scheme } from "wasi:http"; use { Client } from "wasi:http/client.wado"; export async fn handle(request: Request) -> Result { let headers = Fields::new(); let [trailers_future, trailers_tx] = Future::, ErrorCode>>::new(); let [out_req, _req_future] = Request::new(headers, null, trailers_future, null); - trailers_tx.write(Result::, ErrorCode>::Ok(null)); + + out_req.set_scheme(Option::::Some(Scheme::Http)); + out_req.set_authority(Option::::Some("localhost")); + out_req.set_path_with_query(Option::::Some("/")); let upstream = Client::send(out_req); task return upstream; + + // Write trailers after task return + trailers_tx.write(Result::, ErrorCode>::Ok(null)); } __DATA__ { - "wasi:http/service": { "status": 200, "body": "mocked" diff --git a/wado-compiler/tests/fixtures/stream-cm-stderr-write.wado b/wado-compiler/tests/fixtures/stream-cm-stderr-write.wado index 4ece44dda..66ad518de 100644 --- a/wado-compiler/tests/fixtures/stream-cm-stderr-write.wado +++ b/wado-compiler/tests/fixtures/stream-cm-stderr-write.wado @@ -1,4 +1,3 @@ -#![TODO] // Test: Write raw bytes to stderr via CM stream resource API // Verifies that Stream data correctly reaches stderr through the CM adapter. // @@ -6,7 +5,6 @@ // CM streams are zero-buffered rendezvous channels, so the consumer must be // started before stream.write() to avoid BLOCKED. use { Stderr } from "core:cli"; -use { ErrorCode } from "wasi:cli/types.wado"; export fn run() with Stderr { let [rx, tx] = Stream::::new(); @@ -23,7 +21,6 @@ export fn run() with Stderr { // 4. Wait for consumer to finish subtask.read(); - let __f = subtask as Future>; __f.drop(); } __DATA__ diff --git a/wado-compiler/tests/fixtures/stream-cm-stdin-pipe.wado b/wado-compiler/tests/fixtures/stream-cm-stdin-pipe.wado index ce81a3500..5a3fd997d 100644 --- a/wado-compiler/tests/fixtures/stream-cm-stdin-pipe.wado +++ b/wado-compiler/tests/fixtures/stream-cm-stdin-pipe.wado @@ -1,4 +1,3 @@ -#![TODO] // Test: Stdin::read_via_stream() piped to Stdout::write_via_stream() // This is the cat(1) pattern that exposed the CM adapter return type bug. // @@ -13,7 +12,6 @@ export fn run() with Stdout, Stdin { let [stdin_stream, _done] = Stdin::read_via_stream(); let subtask = Stdout::write_via_stream(stdin_stream); subtask.read(); - let __f = subtask as Future>; __f.drop(); } __DATA__