xee_interpreter/function/
function_core.rs1use std::rc::Rc;
2
3use crate::{context, stack};
4
5use super::array::Array;
6use super::map::Map;
7
8#[derive(Debug, Clone, Copy, Eq, PartialEq, Hash)]
9pub struct InlineFunctionId(pub(crate) usize);
10
11impl InlineFunctionId {
12 pub fn new(id: usize) -> Self {
13 InlineFunctionId(id)
14 }
15
16 pub fn get(&self) -> usize {
17 self.0
18 }
19
20 pub fn as_u16(&self) -> u16 {
21 self.0 as u16
22 }
23}
24
25#[derive(Debug, Clone, Copy, Eq, PartialEq, Hash)]
26pub struct StaticFunctionId(pub(crate) usize);
27
28impl StaticFunctionId {
29 pub fn as_u16(&self) -> u16 {
30 self.0 as u16
31 }
32}
33
34#[derive(Debug, Clone, PartialEq)]
35pub enum Function {
36 Static(Rc<StaticFunctionData>),
37 Inline(Rc<InlineFunctionData>),
38 Map(Map),
39 Array(Array),
40}
41
42#[cfg(target_arch = "x86_64")]
43static_assertions::assert_eq_size!(Function, [u8; 16]);
44
45#[derive(Debug, PartialEq)]
46pub struct StaticFunctionData {
47 pub(crate) id: StaticFunctionId,
48 pub(crate) closure_vars: Box<[stack::Value]>,
49}
50
51impl From<StaticFunctionData> for Function {
52 fn from(data: StaticFunctionData) -> Self {
53 Self::Static(Rc::new(data))
54 }
55}
56
57impl StaticFunctionData {
58 pub(crate) fn new(id: StaticFunctionId, closure_vars: Vec<stack::Value>) -> Self {
59 StaticFunctionData {
60 id,
61 closure_vars: closure_vars.into(),
62 }
63 }
64}
65
66#[derive(Debug, PartialEq)]
67pub struct InlineFunctionData {
68 pub(crate) id: InlineFunctionId,
69 pub(crate) closure_vars: Box<[stack::Value]>,
70}
71
72impl From<InlineFunctionData> for Function {
73 fn from(data: InlineFunctionData) -> Self {
74 Self::Inline(Rc::new(data))
75 }
76}
77
78impl InlineFunctionData {
79 pub(crate) fn new(id: InlineFunctionId, closure_vars: Vec<stack::Value>) -> Self {
80 InlineFunctionData {
81 id,
82 closure_vars: closure_vars.into(),
83 }
84 }
85}
86
87impl Function {
88 pub(crate) fn closure_vars(&self) -> &[stack::Value] {
89 match self {
90 Self::Static(data) => &data.closure_vars,
91 Self::Inline(data) => &data.closure_vars,
92 _ => unreachable!(),
93 }
94 }
95
96 pub fn display_representation(
97 &self,
98 xot: &xot::Xot,
99 context: &context::DynamicContext,
100 ) -> String {
101 match self {
102 Self::Static(data) => {
103 let function = context.static_function_by_id(data.id);
104 function.display_representation()
105 }
106 Self::Inline(data) => {
107 let function = context.inline_function_by_id(data.id);
108 function.display_representation()
109 }
110 Self::Map(map) => map.display_representation(xot, context),
111 Self::Array(array) => array.display_representation(xot, context),
112 }
113 }
114}