1use super::{Program, SymId};
5use crate::codec_struct;
6use crate::module::ModuleError;
7use crate::module::codec::{Decode, Encode, Reader, Writer};
8use std::cell::Cell;
9
10#[derive(Clone, Debug, PartialEq, Eq)]
13pub struct Class {
14 pub external: SymId,
15 pub parent: SymId,
16 pub factory: Option<ClassPart>,
17 pub object: Option<ClassPart>,
18 pub methods: Vec<Method>,
19}
20
21#[derive(Clone, Debug, PartialEq, Eq)]
24pub struct ClassPart {
25 pub data: Program,
26 pub records: Vec<u32>,
27}
28
29#[derive(Clone, Debug, PartialEq, Eq)]
33pub struct Method {
34 pub name: SymId,
35 pub factory: bool,
36 pub params: Vec<SymId>,
37 pub returns: Option<SymId>,
38 pub own_records: u16,
39 pub code: Program,
40}
41
42codec_struct!(ClassPart { data, records });
43codec_struct!(Method { name, factory, params, returns, own_records, code });
44
45thread_local! {
46 static IN_CLASS: Cell<bool> = const { Cell::new(false) };
47}
48
49impl Encode for Class {
50 fn encode(&self, w: &mut Writer) {
51 let Class { external, parent, factory, object, methods } = self;
52 external.encode(w);
53 parent.encode(w);
54 factory.encode(w);
55 object.encode(w);
56 methods.encode(w);
57 }
58}
59
60impl Decode for Class {
63 fn decode(r: &mut Reader<'_>) -> Result<Self, ModuleError> {
64 if IN_CLASS.get() {
65 return Err(r.malformed(r.position(), "a class definition inside a class definition"));
66 }
67 IN_CLASS.set(true);
68 let class = (|| {
69 Ok(Class {
70 external: Decode::decode(r)?,
71 parent: Decode::decode(r)?,
72 factory: Decode::decode(r)?,
73 object: Decode::decode(r)?,
74 methods: Decode::decode(r)?,
75 })
76 })();
77 IN_CLASS.set(false);
78 class
79 }
80}