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//! invoking a user-defined function, and what its definition gives an invocation (§9.15). CANCEL
3//! is `Op::Cancel`.
4
5use super::{BlockId, Chars, Comparand, DebugId, Operand, ParaId, PlaceId, RefMod, SymId};
6use crate::{codec_enum, codec_struct};
7
8/// The op returns Arm(0) after a normal return, Arm(1) when no program has the name and ON
9/// EXCEPTION is written, or End(StopRun); Next rather than Arm(0) when neither phrase is written.
10/// `returning` is moved by the callee's RETURNING kind.
11#[derive(Clone, Debug, PartialEq, Eq)]
12pub struct CallPlan<P = PlaceId, O = Operand> {
13    pub target: CallTarget<P, O>,
14    pub args: Vec<CallArg<P, O>>,
15    pub returning: Option<P>,
16    pub on_exception: bool,
17    pub not_on_exception: bool,
18}
19
20#[derive(Clone, Copy, Debug, PartialEq, Eq)]
21pub enum CallTarget<P = PlaceId, O = Operand> {
22    /// A literal: the program is found when the CALL runs, and `le` runs when none has the name.
23    Named { name: SymId, le: Option<LeService> },
24    /// An identifier, its value decoded, trimmed and upper-cased when the CALL runs.
25    Dynamic(O),
26    /// A FUNCTION-POINTER or PROCEDURE-POINTER, which holds a JNI service. Its arguments are all
27    /// `Value` or `Omitted`: the service takes each operand's value as it reads, OMITTED as NULL.
28    Pointer(P),
29    /// Any other FUNCTION-POINTER or PROCEDURE-POINTER: the program of the entry SET TO ENTRY gave
30    /// it, called by its name and as it was loaded; a value naming no entry is `Pointer`'s service.
31    Entry(P),
32}
33
34#[derive(Clone, Debug, PartialEq, Eq)]
35pub enum CallArg<P = PlaceId, O = Operand> {
36    Reference(P),
37    /// Copied to a temporary; BY REFERENCE of anything but a data item passes as this. A literal's
38    /// bytes are those its own data item would hold; LENGTH OF is a binary fullword.
39    Content(Chars<P, O>),
40    /// A fullword, an address or bytes, from the value.
41    Value(O),
42    Omitted,
43}
44
45/// An ENTRY statement: a CALL of `name` starts at `block`, the statement after the ENTRY in
46/// paragraph `paragraph`, in the Main frame, with `using` in place of `Storage.using`.
47#[derive(Clone, Debug, PartialEq, Eq)]
48pub struct EntryPoint {
49    pub name: SymId,
50    pub paragraph: ParaId,
51    pub block: BlockId,
52    pub using: Vec<u16>,
53}
54
55/// The LE callable services the runtime provides.
56#[derive(Clone, Copy, Debug, PartialEq, Eq)]
57pub enum LeService {
58    Cee3abd,
59    Cee3dmp,
60    Ceedate,
61    Ceedatm,
62    Ceedays,
63    Ceedywk,
64    Ceefrst,
65    Ceegmt,
66    Ceegmto,
67    Ceegtst,
68    Ceeloct,
69    Ceemout,
70    Ceesecs,
71    Ceeutc,
72}
73
74/// An invocation of a user-defined function, `Operand::UserFunction`: its definition is loaded by
75/// `external`, `name` as written naming it in messages; each argument is evaluated in turn; the
76/// function runs as a callee (`rt::callee::By::Function`); its value is its RETURNING item's,
77/// reference-modified last by `refmod`, which is checked whatever SSRANGE says.
78#[derive(Clone, Debug, PartialEq, Eq)]
79pub struct UserFunctionPlan {
80    pub name: SymId,
81    pub external: SymId,
82    pub args: Vec<UserArgument>,
83    pub refmod: Option<RefMod>,
84    pub at: DebugId,
85}
86
87/// A data item passed BY REFERENCE passes its address. Any other argument passes its value, which
88/// the function's activation moves into a temporary its formal parameter describes (C272).
89#[derive(Clone, Debug, PartialEq, Eq)]
90pub enum UserArgument {
91    Reference(PlaceId),
92    Value(Comparand),
93}
94
95/// A user-defined function's definition: a place naming each formal parameter's whole LINKAGE
96/// record, in order, and one naming the RETURNING record.
97#[derive(Clone, Debug, PartialEq, Eq)]
98pub struct FunctionDefinition {
99    pub params: Vec<PlaceId>,
100    pub returning: PlaceId,
101}
102
103codec_struct!(CallPlan { target, args, returning, on_exception, not_on_exception });
104codec_struct!(UserFunctionPlan { name, external, args, refmod, at });
105codec_enum!(UserArgument { Reference(place) = 0, Value(value) = 1 });
106codec_struct!(FunctionDefinition { params, returning });
107codec_enum!(CallTarget { Named { name, le } = 0, Dynamic(name) = 1, Pointer(place) = 2, Entry(place) = 3 });
108codec_enum!(CallArg { Reference(place) = 0, Content(chars) = 1, Value(value) = 2, Omitted = 3 });
109codec_struct!(EntryPoint { name, paragraph, block, using });
110codec_enum!(LeService {
111    Cee3abd = 0,
112    Cee3dmp = 1,
113    Ceedate = 2,
114    Ceedatm = 3,
115    Ceedays = 4,
116    Ceedywk = 5,
117    Ceefrst = 6,
118    Ceegmt = 7,
119    Ceegmto = 8,
120    Ceegtst = 9,
121    Ceeloct = 10,
122    Ceemout = 11,
123    Ceesecs = 12,
124    Ceeutc = 13,
125});