Skip to content
← Back

src/ir/values/declare_local.ghul

1
namespace IR.Values is
2
use Semantic.Types.Type
3
4
// Declares one CLR local.
5
//
6
// A body header points at a StandAloneSig listing the local types
7
// in slot order, and every load and store addresses a slot by
8
// index, so a declaration has to reach the emitter as data rather
9
// than as anything textual.
10
//
11
// Being in the block gets the ordering right for free: a
12
// declaration is emitted before the loads that follow it, so the
13
// slot exists by the time one is encoded.
14
class DECLARE_LOCAL: Value is
15
name: string
16
type: Type
17
18
init(name: string, type: Type) is
19
super.init()
20
21
self.name = name
22
self.type = type
23
si
24
25
gen(context: IR.CONTEXT) is
26
let body = context.current_srm_body_emitter!
27
body.declare_local(name, type)
28
si
29
30
to_string() -> string => "declare-local:[{type}]({name})"
31
si
32
33
// Stores the top of the stack into a named local. The counterpart
34
// of DECLARE_LOCAL, and raw text for the same reason.
35
class STORE_TEMP: Value is
36
name: string
37
type: Type
38
39
init(name: string, type: Type) is
40
super.init()
41
42
self.name = name
43
self.type = type
44
si
45
46
gen(context: IR.CONTEXT) is
47
let body = context.current_srm_body_emitter!
48
body.stloc(name)
49
si
50
51
to_string() -> string => "store-temp:[{type}]({name})"
52
si
53
54
// Returns from the enclosing method. A value for the same reason
55
// as DECLARE_LOCAL: silently dropping an instruction produces a
56
// body that fails verification with nothing to point at.
57
class RET: Value is
58
init() is
59
super.init()
60
si
61
62
gen(context: IR.CONTEXT) is
63
let body = context.current_srm_body_emitter!
64
body.ret()
65
si
66
67
to_string() -> string => "ret"
68
si
69
70
// The value a non-void function falls out of the bottom with: a
71
// fresh local of the return type, never assigned, loaded so the
72
// trailing `ret` has something to return. The local is anonymous
73
// and used once, so it is declared and loaded together rather than
74
// through the usual declare-then-load pair.
75
class DEFAULT_RETURN: Value is
76
type: Type
77
78
init(type: Type) is
79
super.init()
80
81
self.type = type
82
si
83
84
gen(context: IR.CONTEXT) is
85
let body = context.current_srm_body_emitter!
86
body.declare_local(".default", type)
87
body.ldloc(".default")
88
si
89
90
to_string() -> string => "default-return:[{type}]()"
91
si
92
si