wasmerio/wasmer · critical

not yet implemented

Error message

not yet implemented

What it means

emit_relaxed_cmp for the RISC-V singlepass backend is a stub: it is declared to emit a relaxed-width comparison but the body is `todo!()`, so any code path that lowers a comparison through it panics with 'not yet implemented'. The RISC-V port has not implemented this instruction-lowering hook.

Source

Thrown at lib/compiler-singlepass/src/machine_riscv.rs:2853

        self.assembler.emit_pop(size, loc)
    }

    fn emit_relaxed_mov(
        &mut self,
        sz: Size,
        src: Location,
        dst: Location,
    ) -> Result<(), CompileError> {
        self.emit_relaxed_binop(Assembler::emit_mov, sz, src, dst)
    }

    fn emit_relaxed_cmp(
        &mut self,
        _sz: Size,
        _src: Location,
        _dst: Location,
    ) -> Result<(), CompileError> {
        todo!();
    }

    fn emit_memory_fence(&mut self) -> Result<(), CompileError> {
        self.assembler.emit_rwfence()
    }

    fn emit_relaxed_sign_extension(
        &mut self,
        sz_src: Size,
        src: Location,
        sz_dst: Size,
        dst: Location,
    ) -> Result<(), CompileError> {
        let mut temps = vec![];

        match (src, dst) {
            (Location::Memory(reg, offset), Location::GPR(_)) => {
                let src = if ImmType::Bits12.compatible_imm(offset as _) {

View on GitHub (pinned to 8c4b9ee9d3)

Solutions

  1. Select the cranelift compiler for riscv64 targets instead of singlepass
  2. Upgrade wasmer to a release where emit_relaxed_cmp is implemented for RISC-V
  3. Backend contributors: implement the hook by emitting a slt/xor-based comparison of the requested Size
  4. Avoid singlepass on RISC-V until the port is marked complete upstream

Example fix

// before (machine_riscv.rs)
fn emit_relaxed_cmp(&mut self, _sz: Size, _src: Location, _dst: Location) -> Result<(), CompileError> {
    todo!();
}
// after
fn emit_relaxed_cmp(&mut self, sz: Size, src: Location, dst: Location) -> Result<(), CompileError> {
    self.emit_cmp(sz, src, dst) // or a proper sltu/xori sequence
}
Defensive patterns

Strategy: fallback

Validate before calling

// refuse singlepass on riscv until emit_relaxed_cmp exists
if is_riscv_target() && uses_singlepass() { return Err("singlepass unsupported on riscv; use cranelift"); }

Type guard

fn compiler_supports_target(cfg: &dyn CompilerConfig, triple: &Triple) -> bool {
    !(triple.architecture == Architecture::Riscv64 && cfg.name() == "singlepass")
}

Prevention

When it happens

Trigger: Any singlepass-on-riscv64 compilation whose instruction selection reaches emit_relaxed_cmp (integer comparisons emitted in relaxed form), e.g. wasm i32/i64 comparison ops (eq/ne/lt/gt/le/ge) routed to this backend.

Common situations: Using wasmer's experimental RISC-V singlepass backend on any nontrivial wasm module — nearly every module contains comparisons — so this fires almost immediately on riscv hosts with singlepass selected.

Related errors


AI-assisted analysis of wasmerio/wasmer@8c4b9ee9d3 (2026-09-01). Data as JSON: /api/errors/20a873b7dc594027. Report an issue: GitHub.