implement primop (filter)

This commit is contained in:
2026-04-25 21:08:54 +08:00
parent 4f3cd0ef4c
commit d77dcc8929
18 changed files with 558 additions and 129 deletions
+29 -14
View File
@@ -16,6 +16,7 @@ pub(crate) trait Forced<'gc>: Sized {
reader: &mut BytecodeReader<'_>,
mc: &Mutation<'gc>,
base_depth: usize,
resume_pc: usize,
) -> Step;
/// After `force_and_check` returned `Continue`, pop `WIDTH` slots
@@ -33,8 +34,9 @@ impl<'gc> Forced<'gc> for StrictValue<'gc> {
reader: &mut BytecodeReader<'_>,
mc: &Mutation<'gc>,
base_depth: usize,
resume_pc: usize,
) -> Step {
vm.force_slot(base_depth, reader, mc)
vm.force_slot_to_pc(base_depth, reader, mc, resume_pc)
}
#[inline(always)]
@@ -55,8 +57,9 @@ macro_rules! impl_forced_inline {
reader: &mut BytecodeReader<'_>,
mc: &Mutation<'gc>,
base_depth: usize,
resume_pc: usize,
) -> Step {
vm.force_slot(base_depth, reader, mc)?;
vm.force_slot_to_pc(base_depth, reader, mc, resume_pc)?;
let v = vm.peek_forced(base_depth);
if v.as_inline::<$ty>().is_none() {
let _: Step = vm.finish_type_err($nix_ty, v.ty());
@@ -88,8 +91,9 @@ macro_rules! impl_forced_gc {
reader: &mut BytecodeReader<'_>,
mc: &Mutation<'gc>,
base_depth: usize,
resume_pc: usize,
) -> Step {
vm.force_slot(base_depth, reader, mc)?;
vm.force_slot_to_pc(base_depth, reader, mc, resume_pc)?;
let v = vm.peek_forced(base_depth);
if v.as_gc::<$ty>().is_none() {
let _: Step = vm.finish_type_err($nix_ty, v.ty());
@@ -135,8 +139,9 @@ impl<'gc> Forced<'gc> for NixNum {
reader: &mut BytecodeReader<'_>,
mc: &Mutation<'gc>,
base_depth: usize,
resume_pc: usize,
) -> Step {
vm.force_slot(base_depth, reader, mc)?;
vm.force_slot_to_pc(base_depth, reader, mc, resume_pc)?;
let v = vm.peek_forced(base_depth);
if v.as_num().is_none() {
let _: Step = vm.finish_type_err(NixType::Int, v.ty());
@@ -162,8 +167,9 @@ impl<'gc> Forced<'gc> for f64 {
reader: &mut BytecodeReader<'_>,
mc: &Mutation<'gc>,
base_depth: usize,
resume_pc: usize,
) -> Step {
vm.force_slot(base_depth, reader, mc)?;
vm.force_slot_to_pc(base_depth, reader, mc, resume_pc)?;
let v = vm.peek_forced(base_depth);
if v.as_float().is_none() {
let _: Step = vm.finish_type_err(NixType::Float, v.ty());
@@ -189,9 +195,10 @@ impl<'gc, A: Forced<'gc>, B: Forced<'gc>> Forced<'gc> for (A, B) {
reader: &mut BytecodeReader<'_>,
mc: &Mutation<'gc>,
base: usize,
resume_pc: usize,
) -> Step {
A::force_and_check(vm, reader, mc, base + B::WIDTH)?;
B::force_and_check(vm, reader, mc, base)
A::force_and_check(vm, reader, mc, base + B::WIDTH, resume_pc)?;
B::force_and_check(vm, reader, mc, base, resume_pc)
}
#[inline(always)]
@@ -211,10 +218,11 @@ impl<'gc, A: Forced<'gc>, B: Forced<'gc>, C: Forced<'gc>> Forced<'gc> for (A, B,
reader: &mut BytecodeReader<'_>,
mc: &Mutation<'gc>,
base: usize,
resume_pc: usize,
) -> Step {
A::force_and_check(vm, reader, mc, base + B::WIDTH + C::WIDTH)?;
B::force_and_check(vm, reader, mc, base + C::WIDTH)?;
C::force_and_check(vm, reader, mc, base)
A::force_and_check(vm, reader, mc, base + B::WIDTH + C::WIDTH, resume_pc)?;
B::force_and_check(vm, reader, mc, base + C::WIDTH, resume_pc)?;
C::force_and_check(vm, reader, mc, base, resume_pc)
}
#[inline(always)]
@@ -237,11 +245,18 @@ impl<'gc, A: Forced<'gc>, B: Forced<'gc>, C: Forced<'gc>, D: Forced<'gc>> Forced
reader: &mut BytecodeReader<'_>,
mc: &Mutation<'gc>,
base: usize,
resume_pc: usize,
) -> Step {
A::force_and_check(vm, reader, mc, base + B::WIDTH + C::WIDTH + D::WIDTH)?;
B::force_and_check(vm, reader, mc, base + C::WIDTH + D::WIDTH)?;
C::force_and_check(vm, reader, mc, base + D::WIDTH)?;
D::force_and_check(vm, reader, mc, base)
A::force_and_check(
vm,
reader,
mc,
base + B::WIDTH + C::WIDTH + D::WIDTH,
resume_pc,
)?;
B::force_and_check(vm, reader, mc, base + C::WIDTH + D::WIDTH, resume_pc)?;
C::force_and_check(vm, reader, mc, base + D::WIDTH, resume_pc)?;
D::force_and_check(vm, reader, mc, base, resume_pc)
}
#[inline(always)]