Skip to content
← Back

src/ir/values/load/function_pointer.ghul

1
namespace IR.Values.Load is
2
use IO.Std;
3
4
use System.NotImplementedException;
5
use System.Text.StringBuilder;
6
7
use TypeTyped = Semantic.Types.Typed;
8
use Semantic.Types.Type;
9
use SymbolBase = Semantic.Symbols.Symbol;
10
11
class FUNCTION_POINTER: SYMBOL, TypeTyped is
12
has_address: bool => false;
13
is_consumable: bool => true;
14
15
// True when this pointer must dispatch virtually - a real
16
// override could sit behind the statically-known symbol at
17
// the receiver's runtime type, and a plain `ldftn` always
18
// captures the statically-resolved implementation. Only ever
19
// true for a function reference bound to a live receiver
20
// (FUNCTION_REFERENCE_RESOLVER); a closure's own synthesized
21
// method is never virtual, so every other caller passes false.
22
is_virtual: bool;
23
is_virtual_dispatch: bool => is_virtual;
24
25
init(symbol: Semantic.Symbols.Symbol) is
26
init(symbol, false);
27
si
28
29
init(symbol: Semantic.Symbols.Symbol, is_virtual: bool) is
30
super.init(null, symbol);
31
32
self.is_virtual = is_virtual;
33
si
34
35
referenced_function: Semantic.Symbols.Function? =>
36
cast Semantic.Symbols.Function?(symbol);
37
38
gen(context: IR.CONTEXT) is
39
let opcode = if is_virtual then "ldvirtftn" else "ldftn" fi;
40
41
context.write_line("{opcode} {symbol.get_il_reference()} /* function: {symbol} */");
42
si
43
44
to_string() -> string =>
45
"function:[{type}](\"{symbol.name}\")";
46
si
47
si