Skip to content
← Back

src/ir/values/load/instance_field.ghul

1
namespace IR.Values.Load is
2
use TypeTyped = Semantic.Types.Typed
3
use SymbolBase = Semantic.Symbols.Symbol
4
5
// The cast to the symbol's expected kind is a checked construction
6
// invariant: the caller only ever builds this value with a symbol of
7
// that kind, so a throw here means the invariant broke elsewhere.
8
@suppress("cast-may-throw")
9
class INSTANCE_FIELD: SYMBOL, TypeTyped is
10
is_consumable: bool => true
11
is_lightweight_pure: bool => from!.is_lightweight_pure
12
13
// A field is addressable in place when its containing instance
14
// is: a reference receiver holds the object, so ldflda always
15
// works; a struct receiver must itself be addressable or the
16
// field lives in a temporary copy.
17
has_address: bool =>
18
if from!.is_value_type then
19
from!.has_address
20
else
21
true
22
fi
23
24
init(from: Value, symbol: SymbolBase) is
25
super.init(from, symbol)
26
si
27
28
gen(context: IR.CONTEXT) is
29
gen(from, context)
30
31
let body = context.current_srm_body_emitter!
32
body.ldfld(context.resolve_field_target(cast Semantic.Symbols.Field(symbol)))
33
si
34
35
gen_address(context: IR.CONTEXT) is
36
// `ldflda` takes the containing instance: the reference value
37
// for a reference-type receiver, a managed pointer for a
38
// value-type (struct) receiver. Taking the receiver's address
39
// unconditionally would compute the field offset from the local
40
// slot holding the reference, not from the object.
41
if from!.is_value_type then
42
from!.gen_address(context)
43
else
44
gen(from, context)
45
fi
46
let body = context.current_srm_body_emitter!
47
body.ldflda(
48
context.resolve_field_target(
49
cast Semantic.Symbols.Field(symbol)))
50
si
51
52
to_string() -> string =>
53
"load:[{type}]({from},\"{symbol.name}\")"
54
si
55
si