Skip to content
← Back

src/syntax/process/generate-il/generate_il_pack_thunk.ghul

1
namespace Syntax.Process is
2
use IR
3
use IR.Values
4
5
// An argument pack thunk has no literal behind it, so its body is
6
// generated from the description on its closure rather than walked:
7
// read the thunk's own parameters, turn the pack from the shape the
8
// thunk takes into the shape the wrapped function takes, call that
9
// function and return what it returns.
10
partial GENERATE_IL is
11
_gen_pack_thunk(closure: Semantic.Symbols.Closure) is
12
let thunk = closure.pack_thunk
13
14
if !thunk? then
15
return
16
fi
17
18
closure.map_type_arguments()
19
20
let assembly_emitter = _context.srm_assembly_emitter
21
let enclosing = _context.current_srm_body_emitter
22
let enclosing_member = assembly_emitter.current_emission_member
23
let body_emitter = IR.Emitter.SRM_METHOD_BODY_EMITTER()
24
25
_context.current_srm_body_emitter = body_emitter
26
assembly_emitter.current_emission_member = closure
27
28
enter_block()
29
30
let arguments = Collections.LIST[Value]()
31
32
for i in 0..thunk.fixed_count do
33
arguments.add(_pack_thunk_parameter(closure, i))
34
od
35
36
if thunk.is_unpack then
37
let tuple = IR.TEMP(current_block, "pack_thunk_tuple", _pack_thunk_parameter(closure, thunk.fixed_count))
38
39
let strategy = DESTRUCTURE_RESOLVER.resolve_strategy(tuple.type, thunk.element_types.count)
40
41
for i in 0..thunk.element_types.count do
42
arguments.add(strategy.members[i]!.load(closure.location, tuple.load(), _symbol_loader))
43
od
44
else
45
let elements = Collections.LIST[Value]()
46
47
for i in 0..thunk.element_types.count do
48
elements.add(_pack_thunk_parameter(closure, thunk.fixed_count + i))
49
od
50
51
arguments.add(
52
Values.TUPLE(
53
_innate_symbol_lookup.get_tuple_type(thunk.element_types, null),
54
elements
55
)
56
)
57
fi
58
59
let return_type = closure.return_type!
60
61
if let target = thunk.target then
62
add(target.call(closure.location, null, arguments, null, _function_caller))
63
elif let callee = thunk.callee then
64
add(
65
Values.Call.CLOSURE(
66
callee,
67
return_type,
68
return_type.compare(_innate_symbol_lookup.get_void_type()) == Semantic.Types.MATCH.SAME,
69
thunk.callee_type,
70
arguments
71
)
72
)
73
fi
74
75
add(Values.RET())
76
77
current_block.gen(_context)
78
79
leave_block()
80
81
assembly_emitter.handles.set_body_offset(closure, body_emitter.flush(assembly_emitter))
82
assembly_emitter.handles.set_il_outputs(closure, body_emitter.il_outputs)
83
84
_context.current_srm_body_emitter = enclosing
85
assembly_emitter.current_emission_member = enclosing_member
86
87
closure.unmap_type_arguments()
88
si
89
90
_pack_thunk_parameter(closure: Semantic.Symbols.Closure, index: int) -> Value =>
91
closure.find_direct("$pack_{index}")!.load(closure.location, null, _symbol_loader)
92
si
93
si