From fca00b04ba518688dbe22e4f2efb4bf3f9b23974 Mon Sep 17 00:00:00 2001 From: imxyy_soope_ Date: Sun, 3 May 2026 22:20:00 +0800 Subject: [PATCH] implement Assert --- fix-codegen/src/lib.rs | 2 +- fix-vm/src/dispatch_tailcall.rs | 2 +- fix-vm/src/instructions/control.rs | 24 +++++++++++++++++++----- fix-vm/src/lib.rs | 2 +- 4 files changed, 22 insertions(+), 8 deletions(-) diff --git a/fix-codegen/src/lib.rs b/fix-codegen/src/lib.rs index 4e64238..bdb72ed 100644 --- a/fix-codegen/src/lib.rs +++ b/fix-codegen/src/lib.rs @@ -645,10 +645,10 @@ impl<'a, Ctx: BytecodeContext> BytecodeEmitter<'a, Ctx> { let raw_idx = self.ctx.intern_string(assertion_raw); let span_id = self.ctx.register_span(*span); self.emit_expr(*assertion); - self.emit_expr(*expr); self.emit_op(Op::Assert); self.emit_str_id(raw_idx); self.emit_u32(span_id); + self.emit_expr(*expr); } &Ir::ReplBinding(name) => { self.emit_op(Op::LoadReplBinding); diff --git a/fix-vm/src/dispatch_tailcall.rs b/fix-vm/src/dispatch_tailcall.rs index 5fb45b8..7c78b15 100644 --- a/fix-vm/src/dispatch_tailcall.rs +++ b/fix-vm/src/dispatch_tailcall.rs @@ -185,7 +185,7 @@ tail_fn!(op_coerce_to_string, (reader, mc)); tail_fn!(op_concat_strings, (ctx, reader, mc)); tail_fn!(op_resolve_path, (ctx)); -tail_fn!(op_assert, (reader)); +tail_fn!(op_assert, (ctx, reader, mc)); tail_fn!(op_push_with, (ctx, reader, mc)); tail_fn!(op_pop_with, ()); diff --git a/fix-vm/src/instructions/control.rs b/fix-vm/src/instructions/control.rs index 9dd02d4..e30509f 100644 --- a/fix-vm/src/instructions/control.rs +++ b/fix-vm/src/instructions/control.rs @@ -1,5 +1,8 @@ +use fix_error::Error; +use gc_arena::Mutation; + use crate::value::*; -use crate::{BytecodeReader, Step}; +use crate::{BytecodeReader, Step, VmRuntimeCtx}; impl<'gc> crate::Vm<'gc> { #[inline(always)] @@ -20,7 +23,7 @@ impl<'gc> crate::Vm<'gc> { pub(crate) fn op_jump_if_true( &mut self, reader: &mut BytecodeReader<'_>, - mc: &gc_arena::Mutation<'gc>, + mc: &Mutation<'gc>, ) -> Step { let offset = reader.read_i32(); let cond = self.force_and_retry::(reader, mc)?; @@ -38,9 +41,20 @@ impl<'gc> crate::Vm<'gc> { } #[inline(always)] - pub(crate) fn op_assert(&mut self, reader: &mut BytecodeReader<'_>) -> Step { - let _raw_idx = reader.read_u32(); + pub(crate) fn op_assert( + &mut self, + ctx: &mut impl VmRuntimeCtx, + reader: &mut BytecodeReader<'_>, + mc: &Mutation<'gc>, + ) -> Step { + let raw_id = reader.read_string_id(); + let raw = ctx.resolve_string(raw_id); let _span_id = reader.read_u32(); - todo!("implement Assert (force TOS)"); + let assertion = self.force_and_retry::(reader, mc)?; + if !assertion { + // FIXME: use catchable error + return self.finish_err(Error::eval_error(format!("assertion '{raw}' failed"))); + } + Step::Continue(()) } } diff --git a/fix-vm/src/lib.rs b/fix-vm/src/lib.rs index cdd3827..e11d40b 100644 --- a/fix-vm/src/lib.rs +++ b/fix-vm/src/lib.rs @@ -697,7 +697,7 @@ impl<'gc> Vm<'gc> { CoerceToString => self.op_coerce_to_string(&mut reader, mc), ResolvePath => self.op_resolve_path(ctx), - Assert => self.op_assert(&mut reader), + Assert => self.op_assert(ctx, &mut reader, mc), PushWith => self.op_push_with(ctx, &mut reader, mc), PopWith => self.op_pop_with(),