Skip to content
← Back

src/ir/values/load/self.ghul

1
namespace IR.Values.Load is
2
use TypeTyped = Semantic.Types.Typed
3
use Semantic.Types.Type
4
use SymbolBase = Semantic.Symbols.Symbol
5
6
class REFERENCE_SELF: Value, TypeTyped is
7
`self: SymbolBase
8
type: Type?
9
10
is_self: bool => true
11
has_address: bool => true
12
is_lightweight_pure: bool => true
13
14
init(`self: SymbolBase) is
15
init(`self, null)
16
si
17
18
init(`self: SymbolBase, type: Type?) is
19
super.init()
20
21
self.`self = `self
22
23
if type? then
24
self.type = type
25
elif isa TypeTyped(`self) then
26
self.type = cast TypeTyped(`self).type!
27
fi
28
si
29
30
gen(context: IR.CONTEXT) is
31
let body = context.current_srm_body_emitter!
32
body.ldarg(0)
33
si
34
35
gen_address(context: IR.CONTEXT) is
36
let body = context.current_srm_body_emitter!
37
body.ldarg(0)
38
si
39
40
to_string() -> string =>
41
"self:[{type}]"
42
si
43
44
// Self-load inside a generator's MoveNext: ldarg.0 is the
45
// state-machine frame, not the user's instance, so the body's
46
// `self` accesses go through the synthesised _outer_self
47
// frame field. INSTANCE_GENERATOR_METHOD.load_self constructs
48
// this variant; ordinary instance methods keep the plain
49
// REFERENCE_SELF (ldarg.0).
50
class OUTER_SELF: Value, TypeTyped is
51
`self: SymbolBase
52
outer_self_field: Semantic.Symbols.Field
53
type: Type?
54
55
is_self: bool => true
56
has_address: bool => true
57
is_lightweight_pure: bool => true
58
59
init(`self: SymbolBase, type: Type?, outer_self_field: Semantic.Symbols.Field) is
60
super.init()
61
62
self.`self = `self
63
self.outer_self_field = outer_self_field
64
65
if type? then
66
self.type = type
67
elif isa TypeTyped(`self) then
68
self.type = cast TypeTyped(`self).type!
69
fi
70
si
71
72
gen(context: IR.CONTEXT) is
73
_load(context)
74
si
75
76
gen_address(context: IR.CONTEXT) is
77
_load(context)
78
si
79
80
_load(context: IR.CONTEXT) is
81
let body = context.current_srm_body_emitter!
82
body.ldarg(0)
83
body.ldfld(context.resolve_field_target(outer_self_field))
84
si
85
86
to_string() -> string =>
87
"outer_self:[{type}]"
88
si
89
90
// pretty much all the time we reference a struct's self
91
// we actually want the address, but for an explicit `self`
92
// we need the value:
93
class VALUE_SELF: Value, TypeTyped is
94
`self: SymbolBase
95
type: Type?
96
97
is_self: bool => true
98
has_address: bool => true
99
is_lightweight_pure: bool => true
100
101
init(`self: SymbolBase) is
102
init(`self, null)
103
si
104
105
init(`self: SymbolBase, type: Type?) is
106
super.init()
107
108
self.`self = `self
109
110
if type? then
111
self.type = type
112
elif isa TypeTyped(`self) then
113
self.type = cast TypeTyped(`self).type!
114
fi
115
si
116
117
gen(context: IR.CONTEXT) is
118
let body = context.current_srm_body_emitter!
119
body.ldarg(0)
120
body.load_object(context.resolve_type_token(type!))
121
si
122
123
// we do actually have an address, just default to the value
124
gen_address(context: IR.CONTEXT) is
125
let body = context.current_srm_body_emitter!
126
body.ldarg(0)
127
si
128
129
to_string() -> string =>
130
"self:[{type}]"
131
si
132
133
si