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});