diff --git a/crates/cranelift/src/compiler/component.rs b/crates/cranelift/src/compiler/component.rs index 3d49e8daac86..a4c98bebaba9 100644 --- a/crates/cranelift/src/compiler/component.rs +++ b/crates/cranelift/src/compiler/component.rs @@ -689,13 +689,10 @@ impl<'a> TrampolineCompiler<'a> { |_, _| {}, ); } - Trampoline::Trap => { - self.translate_libcall( - host::trap, - TrapSentinel::Falsy, - WasmArgs::InRegisters, - |_, _| {}, - ); + Trampoline::Trap(code) => { + let code = crate::env_trap_to_clif_trap(*code); + let (mut traps, builder) = self.traps(); + traps.trap(builder, code); } Trampoline::EnterSyncCall => { self.translate_libcall( @@ -1491,7 +1488,7 @@ impl<'a> TrampolineCompiler<'a> { | Trampoline::FutureTransfer | Trampoline::StreamTransfer | Trampoline::ErrorContextTransfer - | Trampoline::Trap + | Trampoline::Trap(_) | Trampoline::EnterSyncCall | Trampoline::ExitSyncCall | Trampoline::Transcoder { .. } => return, diff --git a/crates/cranelift/src/func_environ.rs b/crates/cranelift/src/func_environ.rs index 64311df3e192..6a58b20fe9ef 100644 --- a/crates/cranelift/src/func_environ.rs +++ b/crates/cranelift/src/func_environ.rs @@ -9,7 +9,7 @@ use crate::translate::{ }; use crate::trap::TranslateTrap; use crate::{ - BuiltinFunctionSignatures, TRAP_ARRAY_OUT_OF_BOUNDS, TRAP_GC_HEAP_CORRUPT, + BuiltinFunctionSignatures, Reachability, TRAP_ARRAY_OUT_OF_BOUNDS, TRAP_GC_HEAP_CORRUPT, TRAP_TABLE_OUT_OF_BOUNDS, }; use cranelift_codegen::cursor::FuncCursor; @@ -1807,7 +1807,7 @@ impl<'a, 'func, 'module_env> Call<'a, 'func, 'module_env> { callee_index: FuncIndex, sig_ref: ir::SigRef, wasm_call_args: &[ir::Value], - ) -> WasmResult { + ) -> WasmResult> { let mut real_call_args = Vec::with_capacity(wasm_call_args.len() + 2); let caller_vmctx = self .builder @@ -1831,7 +1831,9 @@ impl<'a, 'func, 'module_env> Call<'a, 'func, 'module_env> { let callee = self .env .get_or_create_defined_func_ref(self.builder.func, def_func_index); - return Ok(self.direct_call_inst(callee, &real_call_args)); + return Ok(Reachability::Reachable( + self.direct_call_inst(callee, &real_call_args), + )); } // Handle direct calls to imported functions. We use an indirect call @@ -1873,9 +1875,11 @@ impl<'a, 'func, 'module_env> Call<'a, 'func, 'module_env> { let result = intrinsic_compiler .translate(*intrinsic, &real_call_args) .unwrap(); - Ok(result.into_iter().collect()) + Ok(Reachability::Reachable(result.into_iter().collect())) } else { - Ok(self.direct_call_inst(callee, &real_call_args)) + Ok(Reachability::Reachable( + self.direct_call_inst(callee, &real_call_args), + )) } } @@ -1887,37 +1891,54 @@ impl<'a, 'func, 'module_env> Call<'a, 'func, 'module_env> { let callee = self .env .get_or_create_imported_func_ref(self.builder.func, callee_index); - Ok(self.direct_call_inst(callee, &real_call_args)) + Ok(Reachability::Reachable( + self.direct_call_inst(callee, &real_call_args), + )) } - // The guest-to-guest sync fast path: these adapter intrinsics are - // lowered inline rather than called, but only when concurrency - // support is enabled (the deferred thread state only exists then) - // and this isn't a tail call (the deferred frame must outlive the - // call). Otherwise fall back to the indirect call, which is also - // the out-of-line slow path the inline `exit` branches to. + // Fused adapter intrinsics that are lowered inline rather than + // called. Some(KnownFunc::FactIntrinsic(intrinsic)) => { - if self.env.tunables.concurrency_support { - debug_assert!(!self.tail); - match intrinsic { - FactInlineIntrinsic::EnterSyncCall => { - return Ok(self.lower_fact_enter_sync_call(&real_call_args)); - } - FactInlineIntrinsic::ExitSyncCall => { - return Ok(self.lower_fact_exit_sync_call( - callee_index, - sig_ref, - &real_call_args, - )); - } + match intrinsic { + FactInlineIntrinsic::Trap(trap) => { + self.env + .trap(self.builder, crate::env_trap_to_clif_trap(*trap)); + return Ok(Reachability::Unreachable); } + + // The guest-to-guest sync fast path: these adapter + // intrinsics are lowered inline rather than called, but + // only when concurrency support is enabled (the deferred + // thread state only exists then) and this isn't a tail call + // (the deferred frame must outlive the call). Otherwise + // fall back to the indirect call, which is also the + // out-of-line slow path the inline `exit` branches to. + FactInlineIntrinsic::EnterSyncCall if self.env.tunables.concurrency_support => { + debug_assert!(!self.tail); + return Ok(Reachability::Reachable( + self.lower_fact_enter_sync_call(&real_call_args), + )); + } + FactInlineIntrinsic::ExitSyncCall if self.env.tunables.concurrency_support => { + debug_assert!(!self.tail); + return Ok(Reachability::Reachable(self.lower_fact_exit_sync_call( + callee_index, + sig_ref, + &real_call_args, + ))); + } + FactInlineIntrinsic::EnterSyncCall | FactInlineIntrinsic::ExitSyncCall => {} } let func_addr = self.env.alias_regions.vmctx_vmfunction_import_wasm_call( &mut self.builder.cursor(), vmctx, callee_index, ); - Ok(self.indirect_call_inst(sig_ref, func_addr, &real_call_args)) + Ok(Reachability::Reachable(self.indirect_call_inst( + sig_ref, + func_addr, + &real_call_args, + ))) } Some(key) => panic!("unexpected kind of known-import function: {key:?}"), @@ -1931,7 +1952,11 @@ impl<'a, 'func, 'module_env> Call<'a, 'func, 'module_env> { vmctx, callee_index, ); - Ok(self.indirect_call_inst(sig_ref, func_addr, &real_call_args)) + Ok(Reachability::Reachable(self.indirect_call_inst( + sig_ref, + func_addr, + &real_call_args, + ))) } } } @@ -3406,6 +3431,8 @@ impl FuncEnvironment<'_> { ) } + /// Returns `None` when the call was lowered to an unconditional trap and so + /// everything after it is unreachable. See `Call::direct_call`. pub fn translate_call<'a>( &mut self, builder: &'a mut FunctionBuilder, @@ -3413,7 +3440,7 @@ impl FuncEnvironment<'_> { callee_index: FuncIndex, sig_ref: ir::SigRef, call_args: &[ir::Value], - ) -> WasmResult { + ) -> WasmResult> { Call::new(builder, self, srcloc).direct_call(callee_index, sig_ref, call_args) } @@ -3436,7 +3463,8 @@ impl FuncEnvironment<'_> { sig_ref: ir::SigRef, call_args: &[ir::Value], ) -> WasmResult<()> { - Call::new_tail(builder, self, srcloc).direct_call(callee_index, sig_ref, call_args)?; + let _ = + Call::new_tail(builder, self, srcloc).direct_call(callee_index, sig_ref, call_args)?; Ok(()) } @@ -6088,7 +6116,10 @@ impl FuncEnvironment<'_> { .signature .unwrap_module_type_index(); let sig_ref = self.get_or_create_interned_sig_ref(builder.func, ty); - self.translate_call(builder, Default::default(), func, sig_ref, &[])?; + match self.translate_call(builder, Default::default(), func, sig_ref, &[])? { + Reachability::Reachable(_) => {} + Reachability::Unreachable => return Ok(()), + } if self.tunables.consume_fuel { self.fuel_load_into_var(builder); } diff --git a/crates/cranelift/src/lib.rs b/crates/cranelift/src/lib.rs index 150726f70c8b..aa9e448e9c79 100644 --- a/crates/cranelift/src/lib.rs +++ b/crates/cranelift/src/lib.rs @@ -78,6 +78,16 @@ pub const TRAP_CAST_FAILURE: TrapCode = pub const TRAP_UNCAUGHT_EXCEPTION: TrapCode = TrapCode::unwrap_user(Trap::UncaughtException as u8 + TRAP_OFFSET); +/// The CLIF trap code for a Wasmtime trap code. +/// +/// This is the inverse of `clif_trap_to_env_trap`'s fallback arm, and is what +/// all of the `TRAP_*` constants above compute for their particular trap. Use +/// it for traps that don't have a constant above, e.g. the trap named by a +/// fused adapter's `trap` intrinsic. +const fn env_trap_to_clif_trap(trap: Trap) -> TrapCode { + TrapCode::unwrap_user(trap as u8 + TRAP_OFFSET) +} + /// Creates a new cranelift `Signature` with no wasm params/results for the /// given calling convention. /// diff --git a/crates/cranelift/src/translate/code_translator.rs b/crates/cranelift/src/translate/code_translator.rs index 6e1b49cb7070..088e0f2bd488 100644 --- a/crates/cranelift/src/translate/code_translator.rs +++ b/crates/cranelift/src/translate/code_translator.rs @@ -715,13 +715,16 @@ pub fn translate_operator( let mut args = environ.stacks.peekn(num_args).to_vec(); bitcast_wasm_params(environ, sig_ref, &mut args, builder); - let inst_results = environ.translate_call( - builder, - environ.next_srcloc, - function_index, - sig_ref, - &args, - )?; + let inst_results = unwrap_or_return_unreachable_state!( + environ, + environ.translate_call( + builder, + environ.next_srcloc, + function_index, + sig_ref, + &args, + )? + ); debug_assert_eq!( inst_results.len(), diff --git a/crates/environ/src/compile/module_environ.rs b/crates/environ/src/compile/module_environ.rs index 1c7961323aed..22d0f842b7ac 100644 --- a/crates/environ/src/compile/module_environ.rs +++ b/crates/environ/src/compile/module_environ.rs @@ -8,7 +8,7 @@ use crate::{ EngineOrModuleTypeIndex, EntityIndex, EntityType, FuncIndex, FuncKey, GlobalIndex, IndexType, MemoryIndex, MemoryInitializer, ModuleInternedTypeIndex, ModuleStartup, ModuleTypesBuilder, PanicOnOom as _, PassiveElemIndex, PrimaryMap, RuntimeDataIndex, StaticModuleIndex, TableIndex, - TableInitialValue, TableInitialization, Tag, TagIndex, Tunables, TypeConvert, TypeIndex, + TableInitialValue, TableInitialization, Tag, TagIndex, Trap, Tunables, TypeConvert, TypeIndex, WasmHeapTopType, WasmHeapType, WasmResult, WasmValType, WasmparserTypeConverter, }; use alloc::borrow::Cow; @@ -47,6 +47,8 @@ pub enum FactInlineIntrinsic { /// fall back to the out-of-line `exit-sync-call` libcall when the thread /// was promoted. ExitSyncCall, + /// `trap`: raise the given trap. + Trap(Trap), } /// A statically-known function import. diff --git a/crates/environ/src/component.rs b/crates/environ/src/component.rs index 3f7886778137..9e3233209d66 100644 --- a/crates/environ/src/component.rs +++ b/crates/environ/src/component.rs @@ -202,8 +202,6 @@ macro_rules! foreach_builtin_component_function { #[cfg(feature = "component-model-async")] thread_yield_then_promote(vmctx: vmctx, caller_instance: u32, cancellable: u8, thread_idx: u32) -> u32; - trap(vmctx: vmctx, code: u32) -> bool; - utf8_to_utf8(vmctx: vmctx, src: ptr_u8, len: size, dst: ptr_u8) -> bool; utf16_to_utf16(vmctx: vmctx, src: ptr_u16, len: size, dst: ptr_u16) -> bool; latin1_to_latin1(vmctx: vmctx, src: ptr_u8, len: size, dst: ptr_u8) -> bool; diff --git a/crates/environ/src/component/dfg.rs b/crates/environ/src/component/dfg.rs index e89fccf18e55..fad632be02ef 100644 --- a/crates/environ/src/component/dfg.rs +++ b/crates/environ/src/component/dfg.rs @@ -30,7 +30,7 @@ use crate::component::*; use crate::error::Result; use crate::prelude::*; -use crate::{EntityIndex, EntityRef, ModuleInternedTypeIndex, PrimaryMap, WasmValType}; +use crate::{EntityIndex, EntityRef, ModuleInternedTypeIndex, PrimaryMap, Trap, WasmValType}; use cranelift_entity::packed_option::PackedOption; use indexmap::IndexMap; use info::LinearMemoryOptions; @@ -469,7 +469,7 @@ pub enum Trampoline { FutureTransfer, StreamTransfer, ErrorContextTransfer, - Trap, + Trap(Trap), EnterSyncCall, ExitSyncCall, ThreadIndex { @@ -1155,7 +1155,7 @@ impl LinearizeDfg<'_> { Trampoline::FutureTransfer => info::Trampoline::FutureTransfer, Trampoline::StreamTransfer => info::Trampoline::StreamTransfer, Trampoline::ErrorContextTransfer => info::Trampoline::ErrorContextTransfer, - Trampoline::Trap => info::Trampoline::Trap, + Trampoline::Trap(trap) => info::Trampoline::Trap(*trap), Trampoline::EnterSyncCall => info::Trampoline::EnterSyncCall, Trampoline::ExitSyncCall => info::Trampoline::ExitSyncCall, Trampoline::ThreadIndex { instance } => info::Trampoline::ThreadIndex { diff --git a/crates/environ/src/component/info.rs b/crates/environ/src/component/info.rs index 6f9386cc0a13..679564a33a6c 100644 --- a/crates/environ/src/component/info.rs +++ b/crates/environ/src/component/info.rs @@ -48,7 +48,7 @@ use crate::component::*; use crate::prelude::*; -use crate::{EntityIndex, ModuleInternedTypeIndex, PrimaryMap, WasmValType}; +use crate::{EntityIndex, ModuleInternedTypeIndex, PrimaryMap, Trap, WasmValType}; use cranelift_entity::packed_option::PackedOption; use serde_derive::{Deserialize, Serialize}; @@ -1097,9 +1097,9 @@ pub enum Trampoline { /// component does not invalidate the handle in the original component. ErrorContextTransfer, - /// An intrinsic used by FACT-generated modules to trap with a specified + /// An intrinsic used by FACT-generated modules to trap with the specified /// code. - Trap, + Trap(Trap), /// An intrinsic used by FACT-generated modules to push a task onto the /// stack for a sync-to-sync, guest-to-guest call. @@ -1247,7 +1247,7 @@ impl Trampoline { FutureTransfer => format!("future-transfer"), StreamTransfer => format!("stream-transfer"), ErrorContextTransfer => format!("error-context-transfer"), - Trap => format!("trap"), + Trap(trap) => format!("trap-{}", *trap as u8), EnterSyncCall => format!("enter-sync-call"), ExitSyncCall => format!("exit-sync-call"), ThreadIndex { .. } => format!("thread-index"), diff --git a/crates/environ/src/component/translate.rs b/crates/environ/src/component/translate.rs index c4d7ed007edf..4a80c5f927b2 100644 --- a/crates/environ/src/component/translate.rs +++ b/crates/environ/src/component/translate.rs @@ -635,6 +635,7 @@ impl<'a, 'data> Translator<'a, 'data> { CoreDef::Trampoline(index) => match translation.trampolines[*index] { Trampoline::EnterSyncCall => FactInlineIntrinsic::EnterSyncCall.into(), Trampoline::ExitSyncCall => FactInlineIntrinsic::ExitSyncCall.into(), + Trampoline::Trap(trap) => FactInlineIntrinsic::Trap(trap).into(), _ => continue, }, diff --git a/crates/environ/src/component/translate/adapt.rs b/crates/environ/src/component/translate/adapt.rs index 69d310a507c9..dacc586a026d 100644 --- a/crates/environ/src/component/translate/adapt.rs +++ b/crates/environ/src/component/translate/adapt.rs @@ -348,7 +348,7 @@ fn fact_import_to_core_def( fact::Import::ErrorContextTransfer => { simple_intrinsic(dfg::Trampoline::ErrorContextTransfer) } - fact::Import::Trap => simple_intrinsic(dfg::Trampoline::Trap), + fact::Import::Trap(trap) => simple_intrinsic(dfg::Trampoline::Trap(*trap)), fact::Import::EnterSyncCall => simple_intrinsic(dfg::Trampoline::EnterSyncCall), fact::Import::ExitSyncCall => simple_intrinsic(dfg::Trampoline::ExitSyncCall), } diff --git a/crates/environ/src/fact.rs b/crates/environ/src/fact.rs index 302bc00162dd..8eeca27db35f 100644 --- a/crates/environ/src/fact.rs +++ b/crates/environ/src/fact.rs @@ -28,7 +28,7 @@ use crate::fact::transcode::Transcoder; use crate::prelude::*; use crate::{ EntityRef, FuncIndex, GlobalIndex, IndexType, Memory, MemoryIndex, ModuleInternedTypeIndex, - PrimaryMap, Tunables, + PrimaryMap, Trap, Tunables, }; use std::collections::HashMap; use wasm_encoder::*; @@ -97,7 +97,8 @@ pub struct Module<'a> { imported_enter_sync_call: Option, imported_exit_sync_call: Option, - imported_trap: Option, + /// Cached versions of the imported `trap` intrinsic, one per trap code. + imported_traps: HashMap, // Current status of index spaces from the imports generated so far. imported_funcs: PrimaryMap>, @@ -291,7 +292,7 @@ impl<'a> Module<'a> { imported_error_context_transfer: None, imported_enter_sync_call: None, imported_exit_sync_call: None, - imported_trap: None, + imported_traps: HashMap::new(), exports: Vec::new(), task_may_block: None, } @@ -762,14 +763,18 @@ impl<'a> Module<'a> { ) } - fn import_trap(&mut self) -> FuncIndex { - self.import_simple( + fn import_trap(&mut self, trap: Trap) -> FuncIndex { + let name = format!("trap{}", trap as u8); + self.import_simple_get_and_set( "runtime", - "trap", - &[ValType::I32], + &name, &[], - Import::Trap, - |me| &mut me.imported_trap, + &[], + Import::Trap(trap), + |me| me.imported_traps.get(&trap).copied(), + |me, idx| { + me.imported_traps.insert(trap, idx); + }, ) } @@ -912,7 +917,7 @@ pub enum Import { /// ownership of an `error-context`. ErrorContextTransfer, /// An intrinsic for trapping the instance with a specific trap code. - Trap, + Trap(Trap), /// An intrinsic used by FACT-generated modules to check whether an instance /// may be entered for a sync-to-sync call and push a task onto the stack if /// so. diff --git a/crates/environ/src/fact/trampoline.rs b/crates/environ/src/fact/trampoline.rs index bf1236dd903c..2b2afec8f2ba 100644 --- a/crates/environ/src/fact/trampoline.rs +++ b/crates/environ/src/fact/trampoline.rs @@ -3930,8 +3930,7 @@ impl<'a, 'b> Compiler<'a, 'b> { } fn trap(&mut self, trap: Trap) { - let trap_func = self.module.import_trap(); - self.instruction(I32Const(trap as i32)); + let trap_func = self.module.import_trap(trap); self.instruction(Call(trap_func.as_u32())); self.instruction(Unreachable); } diff --git a/crates/wasmtime/src/runtime/vm/component/libcalls.rs b/crates/wasmtime/src/runtime/vm/component/libcalls.rs index f62ea58d9ccd..11ec01108492 100644 --- a/crates/wasmtime/src/runtime/vm/component/libcalls.rs +++ b/crates/wasmtime/src/runtime/vm/component/libcalls.rs @@ -666,12 +666,6 @@ fn resource_transfer_borrow( instance.resource_transfer_borrow(store, src_idx, src_table, dst_table) } -fn trap(_store: &mut dyn VMStore, _instance: Instance, code: u32) -> Result<()> { - Err(wasmtime_environ::Trap::from_u8(u8::try_from(code).unwrap()) - .unwrap() - .into()) -} - fn enter_sync_call( store: &mut dyn VMStore, instance: Instance, diff --git a/tests/disas/component-model/direct-adapter-calls-inlining.wat b/tests/disas/component-model/direct-adapter-calls-inlining.wat index d7900b80b5ba..f266e9f9a4fb 100644 --- a/tests/disas/component-model/direct-adapter-calls-inlining.wat +++ b/tests/disas/component-model/direct-adapter-calls-inlining.wat @@ -60,7 +60,6 @@ ;; region2 = 1207959576 "VMFunctionImport+0x18" ;; region3 = 1476395008 "VMGlobalImport+0x0" ;; region4 = 402653184 "PublicGlobal" -;; region5 = 1207959560 "VMFunctionImport+0x8" ;; gv0 = vmctx ;; gv1 = load.i64 notrap aligned readonly can_move region0 gv0+8 ;; gv2 = load.i64 notrap aligned region1 gv1+24 @@ -71,7 +70,7 @@ ;; gv7 = load.i64 notrap aligned readonly can_move region0 gv6+8 ;; gv8 = load.i64 notrap aligned region1 gv7+24 ;; sig0 = (i64 vmctx, i64, i32) -> i32 tail -;; sig1 = (i64 vmctx, i64, i32) tail +;; sig1 = (i64 vmctx, i64) tail ;; sig2 = (i64 vmctx, i64, i32) -> i32 tail ;; fn0 = colocated u2:0 sig0 ;; fn1 = colocated u0:0 sig2 @@ -83,57 +82,41 @@ ;; block2: ;; jump block6 ;; -;; block8(v5: i64): -;; jump block5 -;; ;; block6: ;; @00ee v3 = load.i64 notrap aligned readonly can_move region2 v0+72 -;; v9 = load.i64 notrap aligned readonly can_move region3 v3+136 +;; v9 = load.i64 notrap aligned readonly can_move region3 v3+168 ;; v10 = load.i32 notrap aligned region4 v9 -;; brif v10, block9, block10 -;; -;; block10: -;; v24 = load.i64 notrap aligned readonly can_move region5 v3+88 -;; v23 = load.i64 notrap aligned readonly can_move region2 v3+104 -;; v22 = iconst.i32 23 -;; try_call_indirect v24(v23, v3, v22), sig1, block11, [ context v3, default: block8(exn0) ] ; v22 = 23 -;; -;; block11: -;; trap user12 +;; trapz v10, user26 +;; jump block9 ;; ;; block9: -;; v11 = load.i64 notrap aligned readonly can_move region3 v3+112 +;; v11 = load.i64 notrap aligned readonly can_move region3 v3+144 ;; v12 = load.i32 notrap aligned region4 v11 +;; jump block12 +;; +;; block12: ;; jump block13 ;; ;; block13: -;; jump block14 +;; jump block11 ;; -;; block14: -;; jump block12 -;; -;; block12: +;; block11: ;; store.i32 notrap aligned region4 v10, v9 ;; jump block7 ;; ;; block7: ;; jump block4 ;; -;; block5: -;; v26 = iconst.i32 49 -;; call_indirect.i64 sig1, v24(v23, v3, v26) ; v26 = 49 -;; trap user12 -;; ;; block4: ;; jump block3 ;; ;; block3: -;; jump block15 +;; jump block14 ;; -;; block15: +;; block14: ;; @00f0 jump block1 ;; ;; block1: -;; v29 = iconst.i32 1276 -;; @00f0 return v29 ; v29 = 1276 +;; v23 = iconst.i32 1276 +;; @00f0 return v23 ; v23 = 1276 ;; } diff --git a/tests/disas/component-model/direct-adapter-calls-x64.wat b/tests/disas/component-model/direct-adapter-calls-x64.wat index 8831a79b6fc8..1af859b389f4 100644 --- a/tests/disas/component-model/direct-adapter-calls-x64.wat +++ b/tests/disas/component-model/direct-adapter-calls-x64.wat @@ -80,14 +80,14 @@ ;; retq ;; 4f: ud2 ;; -;; wasm[2]::function[2]: +;; wasm[2]::function[3]: ;; pushq %rbp ;; movq %rsp, %rbp ;; movq 8(%rdi), %r10 ;; movq 0x18(%r10), %r10 ;; addq $0x60, %r10 ;; cmpq %rsp, %r10 -;; ja 0x13e +;; ja 0x103 ;; 79: subq $0x50, %rsp ;; movq %rbx, 0x20(%rsp) ;; movq %r12, 0x28(%rsp) @@ -96,29 +96,20 @@ ;; movq %r15, 0x40(%rsp) ;; movq %rdi, (%rsp) ;; movq (%rsp), %rdi -;; movq 0x88(%rdi), %rcx +;; movq 0xa8(%rdi), %rcx ;; movl (%rcx), %esi ;; movq %rcx, 0x10(%rsp) ;; testl %esi, %esi ;; movq %rsi, 8(%rsp) -;; jne 0xd5 +;; je 0x105 ;; b9: movq (%rsp), %rdi -;; movq 0x58(%rdi), %rax -;; movq 0x68(%rdi), %rdi -;; movl $0x17, %edx -;; movq (%rsp), %rsi -;; callq *%rax -;; ├─╼ exception frame offset: SP = FP - 0x50 -;; ╰─╼ exception handler: default handler, context at [SP+0x0], handler=0x121 -;; jmp 0x11f -;; d5: movq (%rsp), %rcx -;; movq 0x70(%rcx), %rax +;; movq 0x90(%rdi), %rax ;; movl (%rax), %eax -;; movq 0x48(%rcx), %rdi +;; movq 0x48(%rdi), %rdi ;; movq (%rsp), %rsi ;; callq 0 ;; ├─╼ exception frame offset: SP = FP - 0x50 -;; ╰─╼ exception handler: default handler, context at [SP+0x0], handler=0x121 +;; ╰─╼ exception handler: default handler, context at [SP+0x0], handler=0x101 ;; movq 0x10(%rsp), %rcx ;; movq 8(%rsp), %rsi ;; movl %esi, (%rcx) @@ -131,14 +122,6 @@ ;; movq %rbp, %rsp ;; popq %rbp ;; retq -;; 11a: jmp 0x121 -;; 11f: ud2 -;; 121: movq (%rsp), %rcx -;; 125: movq 0x58(%rcx), %rcx -;; 129: movq (%rsp), %rax -;; 12d: movq 0x68(%rax), %rdi -;; 131: movl $0x31, %edx -;; 136: movq (%rsp), %rsi -;; 13a: callq *%rcx -;; 13c: ud2 -;; 13e: ud2 +;; 101: ud2 +;; 103: ud2 +;; 105: ud2 diff --git a/tests/disas/component-model/direct-adapter-calls.wat b/tests/disas/component-model/direct-adapter-calls.wat index 870554c73541..32963874224f 100644 --- a/tests/disas/component-model/direct-adapter-calls.wat +++ b/tests/disas/component-model/direct-adapter-calls.wat @@ -101,58 +101,45 @@ ;; region2 = 1476395008 "VMGlobalImport+0x0" ;; region3 = 402653184 "PublicGlobal" ;; region4 = 1207959576 "VMFunctionImport+0x18" -;; region5 = 1207959560 "VMFunctionImport+0x8" ;; gv0 = vmctx ;; gv1 = load.i64 notrap aligned readonly can_move region0 gv0+8 ;; gv2 = load.i64 notrap aligned region1 gv1+24 -;; sig0 = (i64 vmctx, i64, i32) tail +;; sig0 = (i64 vmctx, i64) tail ;; sig1 = (i64 vmctx, i64, i32) -> i32 tail ;; fn0 = colocated u0:0 sig1 ;; stack_limit = gv2 ;; ;; block0(v0: i64, v1: i64, v2: i32): -;; @007b jump block4 +;; @008d jump block4 ;; ;; block6(v4: i64): -;; @007b jump block3 +;; @008d jump block3 ;; ;; block4: -;; @0082 v6 = load.i64 notrap aligned readonly can_move region2 v0+136 -;; @0082 v7 = load.i32 notrap aligned region3 v6 -;; @0086 brif v7, block7, block8 -;; -;; block8: -;; @008a v10 = load.i64 notrap aligned readonly can_move region5 v0+88 -;; @008a v9 = load.i64 notrap aligned readonly can_move region4 v0+104 -;; @0088 v8 = iconst.i32 23 -;; @008a try_call_indirect v10(v9, v0, v8), sig0, block9, [ context v0, default: block6(exn0) ] ; v8 = 23 -;; -;; block9: -;; @008c trap user12 +;; @0094 v6 = load.i64 notrap aligned readonly can_move region2 v0+168 +;; @0094 v7 = load.i32 notrap aligned region3 v6 +;; @0098 trapz v7, user26 +;; @0098 jump block7 ;; ;; block7: -;; @008e v11 = load.i64 notrap aligned readonly can_move region2 v0+112 -;; @008e v12 = load.i32 notrap aligned region3 v11 -;; @009c v16 = load.i64 notrap aligned readonly can_move region4 v0+72 -;; @009c try_call fn0(v16, v0, v2), sig1, block10(ret0), [ context v0, default: block6(exn0) ] +;; @009e v9 = load.i64 notrap aligned readonly can_move region2 v0+144 +;; @009e v10 = load.i32 notrap aligned region3 v9 +;; @00ac v14 = load.i64 notrap aligned readonly can_move region4 v0+72 +;; @00ac try_call fn0(v14, v0, v2), sig1, block9(ret0), [ context v0, default: block6(exn0) ] ;; -;; block10(v17: i32): -;; @00a8 store.i32 notrap aligned region3 v7, v6 -;; @00aa jump block5 +;; block9(v15: i32): +;; @00b8 store.i32 notrap aligned region3 v7, v6 +;; @00ba jump block5 ;; ;; block5: -;; @00ab jump block2 +;; @00bb jump block2 ;; ;; block3: -;; v24 = load.i64 notrap aligned readonly can_move region5 v0+88 -;; v25 = load.i64 notrap aligned readonly can_move region4 v0+104 -;; @00ae v21 = iconst.i32 49 -;; @00b0 call_indirect sig0, v24(v25, v0, v21) ; v21 = 49 -;; @00b2 trap user12 +;; @00be trap user52 ;; ;; block2: -;; @00b4 jump block1 +;; @00c2 jump block1 ;; ;; block1: -;; @00b4 return v17 +;; @00c2 return v15 ;; } diff --git a/tests/disas/component-model/sync-adapter-calls-x64.wat b/tests/disas/component-model/sync-adapter-calls-x64.wat index a67c0ce87aff..27be6c1b5ddd 100644 --- a/tests/disas/component-model/sync-adapter-calls-x64.wat +++ b/tests/disas/component-model/sync-adapter-calls-x64.wat @@ -56,67 +56,45 @@ ;; movq %rsp, %rbp ;; movq 8(%rdi), %r10 ;; movq 0x18(%r10), %r10 -;; addq $0x70, %r10 +;; addq $0x30, %r10 ;; cmpq %rsp, %r10 -;; ja 0x154 -;; 39: subq $0x60, %rsp -;; movq %rbx, 0x30(%rsp) -;; movq %r12, 0x38(%rsp) -;; movq %r13, 0x40(%rsp) -;; movq %r14, 0x48(%rsp) -;; movq %r15, 0x50(%rsp) -;; movq 0x48(%rdi), %rsi -;; movq 0xc8(%rsi), %rax +;; ja 0xfb +;; 39: subq $0x30, %rsp +;; movq %rbx, 0x20(%rsp) +;; movq 0x48(%rdi), %rdi +;; movq 0xe8(%rdi), %rax ;; movl (%rax), %ecx ;; testl %ecx, %ecx -;; jne 0x84 -;; 6b: movq 0x58(%rsi), %rax -;; movq 0x68(%rsi), %rdi -;; movq %rsi, 0x20(%rsp) -;; movl $0x17, %edx -;; callq *%rax -;; ├─╼ exception frame offset: SP = FP - 0x60 -;; ╰─╼ exception handler: default handler, context at [SP+0x20], handler=0x13e -;; jmp 0x13c -;; 84: movq 0xe0(%rsi), %rdx -;; movl (%rdx), %r8d +;; je 0xfd +;; 57: movq 0x100(%rdi), %rdx +;; movl (%rdx), %esi ;; movl $0, (%rdx) -;; movq 8(%rsi), %rdi -;; movq 0x88(%rdi), %r9 +;; movq 8(%rdi), %r8 +;; movq 0x88(%r8), %r9 ;; leaq (%rsp), %rbx ;; movq %r9, (%rsp) ;; movl $2, 8(%rsp) ;; movl $0, 0xc(%rsp) ;; movl $1, 0x10(%rsp) -;; movl 0x80(%rdi), %r10d +;; movl 0x80(%r8), %r10d ;; movl %r10d, 0x14(%rsp) -;; movl $0, 0x80(%rdi) -;; movl 0x84(%rdi), %r11d +;; movl $0, 0x80(%r8) +;; movl 0x84(%r8), %r11d ;; movl %r11d, 0x18(%rsp) -;; movl $0, 0x84(%rdi) -;; movq %rbx, 0x88(%rdi) -;; movq 0xb0(%rsi), %rsi -;; movl (%rsi), %esi -;; movq %r9, 0x88(%rdi) -;; movl %r10d, 0x80(%rdi) -;; movl %r11d, 0x84(%rdi) +;; movl $0, 0x84(%r8) +;; movq %rbx, 0x88(%r8) +;; movq 0xd0(%rdi), %rdi +;; movl (%rdi), %edi +;; movq %r9, 0x88(%r8) +;; movl %r10d, 0x80(%r8) +;; movl %r11d, 0x84(%r8) ;; movl %ecx, (%rax) -;; movl %r8d, (%rdx) +;; movl %esi, (%rdx) ;; movl $0x4fc, %eax -;; movq 0x30(%rsp), %rbx -;; movq 0x38(%rsp), %r12 -;; movq 0x40(%rsp), %r13 -;; movq 0x48(%rsp), %r14 -;; movq 0x50(%rsp), %r15 -;; addq $0x60, %rsp +;; movq 0x20(%rsp), %rbx +;; addq $0x30, %rsp ;; movq %rbp, %rsp ;; popq %rbp ;; retq -;; 13c: ud2 -;; 13e: movq 0x20(%rsp), %rsi -;; 143: movq 0x58(%rsi), %rax -;; 147: movq 0x68(%rsi), %rdi -;; 14b: movl $0x31, %edx -;; 150: callq *%rax -;; 152: ud2 -;; 154: ud2 +;; fb: ud2 +;; fd: ud2 diff --git a/tests/disas/component-model/sync-adapter-calls.wat b/tests/disas/component-model/sync-adapter-calls.wat index 73df6c06ee47..b89550743fdf 100644 --- a/tests/disas/component-model/sync-adapter-calls.wat +++ b/tests/disas/component-model/sync-adapter-calls.wat @@ -78,10 +78,9 @@ ;; gv7 = load.i64 notrap aligned readonly can_move region0 gv6+8 ;; gv8 = load.i64 notrap aligned region1 gv7+24 ;; sig0 = (i64 vmctx, i64, i32) -> i32 tail -;; sig1 = (i64 vmctx, i64, i32) tail +;; sig1 = (i64 vmctx, i64) tail ;; sig2 = (i64 vmctx, i64, i32, i32, i32) tail ;; sig3 = (i64 vmctx, i64, i32) -> i32 tail -;; sig4 = (i64 vmctx, i64) tail ;; fn0 = colocated u2:0 sig0 ;; fn1 = colocated u0:0 sig3 ;; stack_limit = gv2 @@ -92,26 +91,15 @@ ;; block2: ;; jump block6 ;; -;; block8(v5: i64): -;; jump block5 -;; ;; block6: ;; @00ee v3 = load.i64 notrap aligned readonly can_move region2 v0+72 -;; v9 = load.i64 notrap aligned readonly can_move region3 v3+200 +;; v9 = load.i64 notrap aligned readonly can_move region3 v3+232 ;; v10 = load.i32 notrap aligned region4 v9 -;; brif v10, block9, block10 -;; -;; block10: -;; v53 = load.i64 notrap aligned readonly can_move region14 v3+88 -;; v52 = load.i64 notrap aligned readonly can_move region2 v3+104 -;; v51 = iconst.i32 23 -;; try_call_indirect v53(v52, v3, v51), sig1, block11, [ context v3, default: block8(exn0) ] ; v51 = 23 -;; -;; block11: -;; trap user12 +;; trapz v10, user26 +;; jump block9 ;; ;; block9: -;; v11 = load.i64 notrap aligned readonly can_move region3 v3+224 +;; v11 = load.i64 notrap aligned readonly can_move region3 v3+256 ;; v12 = load.i32 notrap aligned region4 v11 ;; v8 = iconst.i32 0 ;; store notrap aligned region4 v8, v11 ; v8 = 0 @@ -131,26 +119,26 @@ ;; store notrap aligned region13 v24, v19+24 ;; store notrap aligned region12 v8, v20+132 ; v8 = 0 ;; store notrap aligned region5 v19, v20+136 -;; v26 = load.i64 notrap aligned readonly can_move region3 v3+176 +;; v26 = load.i64 notrap aligned readonly can_move region3 v3+208 ;; v27 = load.i32 notrap aligned region4 v26 +;; jump block16 +;; +;; block16: ;; jump block17 ;; ;; block17: -;; jump block18 +;; jump block11 ;; -;; block18: +;; block11: ;; jump block12 ;; ;; block12: -;; jump block13 -;; -;; block13: ;; store.i64 notrap aligned region5 v21, v20+136 ;; store.i32 notrap aligned region10 v22, v20+128 ;; store.i32 notrap aligned region12 v24, v20+132 -;; jump block15 +;; jump block14 ;; -;; block15: +;; block14: ;; store.i32 notrap aligned region4 v10, v9 ;; store.i32 notrap aligned region4 v12, v11 ;; jump block7 @@ -158,23 +146,16 @@ ;; block7: ;; jump block4 ;; -;; block5: -;; v61 = load.i64 notrap aligned readonly can_move region14 v3+88 -;; v62 = load.i64 notrap aligned readonly can_move region2 v3+104 -;; v48 = iconst.i32 49 -;; call_indirect sig1, v61(v62, v3, v48) ; v48 = 49 -;; trap user12 -;; ;; block4: ;; jump block3 ;; ;; block3: -;; jump block19 +;; jump block18 ;; -;; block19: +;; block18: ;; @00f0 jump block1 ;; ;; block1: -;; v54 = iconst.i32 1276 -;; @00f0 return v54 ; v54 = 1276 +;; v50 = iconst.i32 1276 +;; @00f0 return v50 ; v50 = 1276 ;; }