implement primop (filter)
This commit is contained in:
+36
-10
@@ -1,5 +1,6 @@
|
||||
#![allow(dead_code)]
|
||||
|
||||
use std::cell::RefCell;
|
||||
use std::fmt;
|
||||
use std::marker::PhantomData;
|
||||
use std::mem::size_of;
|
||||
@@ -7,6 +8,7 @@ use std::ops::Deref;
|
||||
|
||||
use fix_builtins::BuiltinId;
|
||||
use fix_common::*;
|
||||
use gc_arena::barrier::Unlock;
|
||||
use gc_arena::collect::Trace;
|
||||
use gc_arena::{Collect, Gc, GcRefLock, Mutation, RefLock};
|
||||
use num_enum::TryFromPrimitive;
|
||||
@@ -345,8 +347,12 @@ impl StaticValue {
|
||||
Self(Value::new_inline(val))
|
||||
}
|
||||
#[inline]
|
||||
pub fn new_primop(id: BuiltinId, arity: u8) -> Self {
|
||||
Self(Value::new_inline(PrimOp { id, arity }))
|
||||
pub fn new_primop(id: BuiltinId, arity: u8, dispatch_ip: u32) -> Self {
|
||||
Self(Value::new_inline(PrimOp {
|
||||
id,
|
||||
arity,
|
||||
dispatch_ip,
|
||||
}))
|
||||
}
|
||||
#[inline]
|
||||
pub fn is_float(self) -> bool {
|
||||
@@ -487,14 +493,22 @@ impl<'gc> AttrSet<'gc> {
|
||||
}
|
||||
|
||||
#[derive(Collect, Debug, Default)]
|
||||
#[repr(transparent)]
|
||||
#[collect(no_drop)]
|
||||
pub(crate) struct List<'gc> {
|
||||
pub(crate) inner: SmallVec<[Value<'gc>; 4]>,
|
||||
pub(crate) inner: RefLock<SmallVec<[Value<'gc>; 4]>>,
|
||||
}
|
||||
impl<'gc> Deref for List<'gc> {
|
||||
type Target = SmallVec<[Value<'gc>; 4]>;
|
||||
fn deref(&self) -> &Self::Target {
|
||||
&self.inner
|
||||
|
||||
impl<'gc> List<'gc> {
|
||||
pub(crate) fn new_gc(mc: &Mutation<'gc>) -> Gc<'gc, Self> {
|
||||
Gc::new(mc, Self::default())
|
||||
}
|
||||
}
|
||||
|
||||
impl<'gc> Unlock for List<'gc> {
|
||||
type Unlocked = RefCell<SmallVec<[Value<'gc>; 4]>>;
|
||||
unsafe fn unlock_unchecked(&self) -> &Self::Unlocked {
|
||||
unsafe { self.inner.unlock_unchecked() }
|
||||
}
|
||||
}
|
||||
|
||||
@@ -572,22 +586,33 @@ pub(crate) struct PatternInfo {
|
||||
pub(crate) param_spans: Box<[(StringId, u32)]>,
|
||||
}
|
||||
|
||||
#[repr(packed, Rust)]
|
||||
#[derive(Clone, Copy, Debug, Collect)]
|
||||
#[collect(require_static)]
|
||||
pub(crate) struct PrimOp {
|
||||
pub(crate) id: BuiltinId,
|
||||
pub(crate) arity: u8,
|
||||
pub(crate) dispatch_ip: u32,
|
||||
}
|
||||
|
||||
impl RawStore for PrimOp {
|
||||
fn to_val(self, value: &mut RawValue) {
|
||||
value.set_data([0, 0, 0, 0, self.id as u8, self.arity]);
|
||||
let bytes = self.dispatch_ip.to_le_bytes();
|
||||
value.set_data([
|
||||
self.id as u8,
|
||||
self.arity,
|
||||
bytes[0],
|
||||
bytes[1],
|
||||
bytes[2],
|
||||
bytes[3],
|
||||
]);
|
||||
}
|
||||
fn from_val(value: &RawValue) -> Self {
|
||||
let [.., id, arity] = *value.data();
|
||||
let [id, arity, bytes @ ..] = *value.data();
|
||||
Self {
|
||||
id: BuiltinId::try_from_primitive(id).expect("invalid BuiltinId"),
|
||||
arity,
|
||||
dispatch_ip: u32::from_le_bytes(bytes),
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -596,7 +621,8 @@ impl RawStore for PrimOp {
|
||||
#[collect(no_drop)]
|
||||
pub(crate) struct PrimOpApp<'gc> {
|
||||
pub(crate) primop: PrimOp,
|
||||
pub(crate) args: SmallVec<[Value<'gc>; 2]>,
|
||||
pub(crate) arity: u8,
|
||||
pub(crate) args: [Value<'gc>; 3],
|
||||
}
|
||||
|
||||
#[derive(Copy, Clone, Default, Collect)]
|
||||
|
||||
Reference in New Issue
Block a user