Skip to content
← Back

src/ir/values/instruction.ghul

1
namespace IR.Values is
2
use System.Reflection.Metadata.ILOpCode
3
4
// A single operand-less IL instruction.
5
class INSTRUCTION: Value is
6
op_code: ILOpCode
7
8
init(op_code: ILOpCode) is
9
super.init()
10
11
self.op_code = op_code
12
si
13
14
gen(context: IR.CONTEXT) is
15
context.current_srm_body_emitter!.op(op_code)
16
si
17
18
to_string() -> string => "{op_code}"
19
si
20
21
// Constructs one of the built-in integer range structs from the
22
// two bounds already on the stack. Its constructor is not reachable
23
// from a Function symbol, so the reference is built from the range
24
// type and the known (int, int) signature.
25
class NEW_RANGE: Value is
26
type: Semantic.Types.Type
27
28
init(type: Semantic.Types.Type) is
29
super.init()
30
31
self.type = type
32
si
33
34
gen(context: IR.CONTEXT) is
35
let body = context.current_srm_body_emitter!
36
body.new_object(context.resolve_range_constructor(type))
37
si
38
39
to_string() -> string => "new-range:[{type}]()"
40
si
41
42
// The stack-depth bound a method body reserves.
43
//
44
// Metadata carries the bound in the body header rather than as an
45
// instruction, and the emitter reserves the same depth for every
46
// body it writes, so nothing is encoded where this value sits. It
47
// stays a value rather than being dropped from the block because
48
// the walk that builds the block does not know that.
49
class MAX_STACK: Value is
50
depth: int
51
52
init(depth: int) is
53
super.init()
54
55
self.depth = depth
56
si
57
58
gen(context: IR.CONTEXT) is
59
si
60
61
to_string() -> string => ".maxstack {depth}"
62
si
63
64
// Marks the position a branch names.
65
class MARK_LABEL: Value is
66
label: IR.LABEL
67
68
init(label: IR.LABEL) is
69
super.init()
70
71
self.label = label
72
si
73
74
gen(context: IR.CONTEXT) is
75
let body = context.current_srm_body_emitter!
76
body.mark_label(label)
77
si
78
79
to_string() -> string => "{label}:"
80
si
81
82
// A branch to a label.
83
//
84
// The long-form opcode is not the final encoding: the encoder
85
// narrows it to the short form once the eventual offset is known.
86
class BRANCH_TO: Value is
87
op_code: ILOpCode
88
label: IR.LABEL
89
90
init(op_code: ILOpCode, label: IR.LABEL) is
91
super.init()
92
93
self.op_code = op_code
94
self.label = label
95
si
96
97
gen(context: IR.CONTEXT) is
98
context.current_srm_body_emitter!.branch(op_code, label)
99
si
100
101
to_string() -> string => "{op_code} {label}"
102
si
103
si