Skip to main content

ironwork_rt/lir/
call.rs

1//! CALL and the LE callable services behind it, and the ENTRY points a CALL enters (lir.md ยง9.3).
2//! CANCEL is `Op::Cancel`.
3
4use super::{BlockId, Chars, Operand, ParaId, PlaceId, SymId};
5use crate::{codec_enum, codec_struct};
6
7/// The op returns Arm(0) after a normal return, Arm(1) when no program has the name and ON
8/// EXCEPTION is written, or End(StopRun); Next rather than Arm(0) when neither phrase is written.
9/// `returning` is moved by the callee's RETURNING kind.
10#[derive(Clone, Debug, PartialEq, Eq)]
11pub struct CallPlan<P = PlaceId, O = Operand> {
12    pub target: CallTarget<P, O>,
13    pub args: Vec<CallArg<P, O>>,
14    pub returning: Option<P>,
15    pub on_exception: bool,
16    pub not_on_exception: bool,
17}
18
19#[derive(Clone, Copy, Debug, PartialEq, Eq)]
20pub enum CallTarget<P = PlaceId, O = Operand> {
21    /// A literal: the program is found when the CALL runs, and `le` runs when none has the name.
22    Named { name: SymId, le: Option<LeService> },
23    /// An identifier, its value decoded, trimmed and upper-cased when the CALL runs.
24    Dynamic(O),
25    /// A FUNCTION-POINTER or PROCEDURE-POINTER, which holds a JNI service. Its arguments are all
26    /// `Value` or `Omitted`: the service takes each operand's value as it reads, OMITTED as NULL.
27    Pointer(P),
28}
29
30#[derive(Clone, Debug, PartialEq, Eq)]
31pub enum CallArg<P = PlaceId, O = Operand> {
32    Reference(P),
33    /// Copied to a temporary; BY REFERENCE of anything but a data item passes as this. A literal's
34    /// bytes are those its own data item would hold; LENGTH OF is a binary fullword.
35    Content(Chars<P, O>),
36    /// A fullword, an address or bytes, from the value.
37    Value(O),
38    Omitted,
39}
40
41/// An ENTRY statement: a CALL of `name` starts at `block`, the statement after the ENTRY in
42/// paragraph `paragraph`, in the Main frame, with `using` in place of `Storage.using`.
43#[derive(Clone, Debug, PartialEq, Eq)]
44pub struct EntryPoint {
45    pub name: SymId,
46    pub paragraph: ParaId,
47    pub block: BlockId,
48    pub using: Vec<u16>,
49}
50
51/// The LE callable services the runtime provides.
52#[derive(Clone, Copy, Debug, PartialEq, Eq)]
53pub enum LeService {
54    Cee3abd,
55    Cee3dmp,
56    Ceedate,
57    Ceedatm,
58    Ceedays,
59    Ceedywk,
60    Ceefrst,
61    Ceegmt,
62    Ceegmto,
63    Ceegtst,
64    Ceeloct,
65    Ceemout,
66    Ceesecs,
67    Ceeutc,
68}
69
70codec_struct!(CallPlan { target, args, returning, on_exception, not_on_exception });
71codec_enum!(CallTarget { Named { name, le } = 0, Dynamic(name) = 1, Pointer(place) = 2 });
72codec_enum!(CallArg { Reference(place) = 0, Content(chars) = 1, Value(value) = 2, Omitted = 3 });
73codec_struct!(EntryPoint { name, paragraph, block, using });
74codec_enum!(LeService {
75    Cee3abd = 0,
76    Cee3dmp = 1,
77    Ceedate = 2,
78    Ceedatm = 3,
79    Ceedays = 4,
80    Ceedywk = 5,
81    Ceefrst = 6,
82    Ceegmt = 7,
83    Ceegmto = 8,
84    Ceegtst = 9,
85    Ceeloct = 10,
86    Ceemout = 11,
87    Ceesecs = 12,
88    Ceeutc = 13,
89});