mt-lang 0.3.24 → 0.3.26

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (97) hide show
  1. checksums.yaml +4 -4
  2. data/lib/milk_tea/base.rb +1 -1
  3. data/lib/milk_tea/core/bindings/attribute_binding.rb +51 -49
  4. data/lib/milk_tea/core/bindings/function_binding.rb +3 -1
  5. data/lib/milk_tea/core/bindings/module_binding.rb +42 -40
  6. data/lib/milk_tea/core/bindings/value_binding.rb +16 -14
  7. data/lib/milk_tea/core/bindings.rb +4 -9
  8. data/lib/milk_tea/core/c_backend/control_flow_emission.rb +11 -11
  9. data/lib/milk_tea/core/c_backend/expressions.rb +11 -11
  10. data/lib/milk_tea/core/c_backend/feature_detection.rb +15 -19
  11. data/lib/milk_tea/core/c_backend/format_helpers.rb +1 -1
  12. data/lib/milk_tea/core/c_backend/reinterpret.rb +10 -10
  13. data/lib/milk_tea/core/c_backend/runtime_helpers.rb +1 -1
  14. data/lib/milk_tea/core/c_backend/statements.rb +20 -20
  15. data/lib/milk_tea/core/c_backend/type_declaration.rb +4 -4
  16. data/lib/milk_tea/core/c_backend/type_system.rb +1 -1
  17. data/lib/milk_tea/core/c_backend.rb +3 -3
  18. data/lib/milk_tea/core/compile_time.rb +41 -70
  19. data/lib/milk_tea/core/control_flow/builder.rb +3 -3
  20. data/lib/milk_tea/core/control_flow/constant_propagation.rb +1 -1
  21. data/lib/milk_tea/core/control_flow/graph.rb +1 -1
  22. data/lib/milk_tea/core/control_flow/termination.rb +1 -1
  23. data/lib/milk_tea/core/cst.rb +16 -0
  24. data/lib/milk_tea/core/flow_scope.rb +13 -0
  25. data/lib/milk_tea/core/lexer/character_classes.rb +2 -2
  26. data/lib/milk_tea/core/lexer/format_strings.rb +5 -5
  27. data/lib/milk_tea/core/lexer/heredocs.rb +6 -6
  28. data/lib/milk_tea/core/lexer/indentation.rb +4 -4
  29. data/lib/milk_tea/core/lexer/numbers.rb +1 -1
  30. data/lib/milk_tea/core/lexer/strings.rb +4 -4
  31. data/lib/milk_tea/core/lexer/symbols.rb +3 -3
  32. data/lib/milk_tea/core/lexer/trivia.rb +4 -4
  33. data/lib/milk_tea/core/lexer.rb +17 -17
  34. data/lib/milk_tea/core/lowering/async/analysis.rb +210 -208
  35. data/lib/milk_tea/core/lowering/async/async_lowering.rb +1406 -0
  36. data/lib/milk_tea/core/lowering/async/frame_builder.rb +615 -613
  37. data/lib/milk_tea/core/lowering/async/normalization.rb +410 -408
  38. data/lib/milk_tea/core/lowering/block.rb +982 -980
  39. data/lib/milk_tea/core/lowering/calls.rb +1360 -1358
  40. data/lib/milk_tea/core/lowering/declarations.rb +175 -173
  41. data/lib/milk_tea/core/lowering/dyn.rb +171 -169
  42. data/lib/milk_tea/core/lowering/events.rb +946 -944
  43. data/lib/milk_tea/core/lowering/expressions.rb +1514 -1512
  44. data/lib/milk_tea/core/lowering/foreign_cstr.rb +180 -178
  45. data/lib/milk_tea/core/lowering/functions.rb +186 -184
  46. data/lib/milk_tea/core/lowering/loops.rb +1004 -1002
  47. data/lib/milk_tea/core/lowering/lowering_context.rb +1 -1
  48. data/lib/milk_tea/core/lowering/proc.rb +355 -353
  49. data/lib/milk_tea/core/lowering/resolve.rb +2127 -2125
  50. data/lib/milk_tea/core/lowering/scans.rb +162 -168
  51. data/lib/milk_tea/core/lowering/str_buffer.rb +104 -102
  52. data/lib/milk_tea/core/lowering/utils.rb +964 -963
  53. data/lib/milk_tea/core/lowering.rb +22 -22
  54. data/lib/milk_tea/core/module_binder.rb +1 -1
  55. data/lib/milk_tea/core/module_loader.rb +2 -2
  56. data/lib/milk_tea/core/parser/attributes.rb +1 -1
  57. data/lib/milk_tea/core/parser/blocks.rb +2 -2
  58. data/lib/milk_tea/core/parser/declarations.rb +15 -15
  59. data/lib/milk_tea/core/parser/expressions.rb +20 -20
  60. data/lib/milk_tea/core/parser/recovery.rb +1 -1
  61. data/lib/milk_tea/core/parser/statements.rb +3 -3
  62. data/lib/milk_tea/core/parser/types.rb +4 -4
  63. data/lib/milk_tea/core/parser.rb +39 -21
  64. data/lib/milk_tea/core/pretty_printer/ast_formatter.rb +6 -6
  65. data/lib/milk_tea/core/pretty_printer/ir_formatter.rb +5 -5
  66. data/lib/milk_tea/core/semantic_analyzer/analysis_context.rb +2 -2
  67. data/lib/milk_tea/core/semantic_analyzer/calls.rb +1 -1
  68. data/lib/milk_tea/core/semantic_analyzer/expressions.rb +4 -4
  69. data/lib/milk_tea/core/semantic_analyzer/flow_refinement.rb +37 -37
  70. data/lib/milk_tea/core/semantic_analyzer/foreign_functions.rb +4 -4
  71. data/lib/milk_tea/core/semantic_analyzer/function_binding.rb +4 -4
  72. data/lib/milk_tea/core/semantic_analyzer/generics.rb +4 -4
  73. data/lib/milk_tea/core/semantic_analyzer/name_resolution.rb +7 -7
  74. data/lib/milk_tea/core/semantic_analyzer/nullability.rb +59 -59
  75. data/lib/milk_tea/core/semantic_analyzer/statements.rb +3 -3
  76. data/lib/milk_tea/core/semantic_analyzer/top_level.rb +1 -1
  77. data/lib/milk_tea/core/semantic_analyzer/type_declaration.rb +12 -12
  78. data/lib/milk_tea/core/types/layout.rb +3 -1
  79. data/lib/milk_tea/core/types/visitor.rb +351 -349
  80. data/lib/milk_tea/core.rb +0 -2
  81. data/lib/milk_tea/tooling/cli/commands/bindgen.rb +1 -1
  82. data/lib/milk_tea/tooling/cli/commands/check.rb +5 -5
  83. data/lib/milk_tea/tooling/cli/commands/debug.rb +3 -3
  84. data/lib/milk_tea/tooling/cli/commands/deps.rb +1 -1
  85. data/lib/milk_tea/tooling/cli/commands/emit_c.rb +2 -2
  86. data/lib/milk_tea/tooling/cli/commands/format.rb +6 -6
  87. data/lib/milk_tea/tooling/cli/commands/lint.rb +3 -3
  88. data/lib/milk_tea/tooling/cli/commands/lower.rb +3 -3
  89. data/lib/milk_tea/tooling/cli/commands/parse.rb +3 -3
  90. data/lib/milk_tea/tooling/cli/commands/test.rb +3 -3
  91. data/lib/milk_tea/tooling/cli/commands/toolchain.rb +1 -1
  92. data/lib/milk_tea/tooling/cli.rb +22 -34
  93. data/lib/milk_tea/tooling/linter/flow_rules.rb +3 -3
  94. metadata +4 -5
  95. data/lib/milk_tea/core/cst_builder.rb +0 -19
  96. data/lib/milk_tea/core/lowering/async/lowering.rb +0 -1404
  97. data/lib/milk_tea/core/token_stream.rb +0 -30
@@ -1,149 +1,130 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module MilkTea
4
- module LowererDyn
5
- def lower_adapt_call(expression, env:, type:, interface:)
6
- argument = expression.arguments.fetch(0)
7
- arg_value = lower_expression(argument.value, env:)
8
- arg_type = infer_expression_type(argument.value, env:)
9
- concrete_type = ref_type?(arg_type) ? referenced_type(arg_type) : arg_type
10
-
11
- @dyn_vtables ||= {}
12
- key = [concrete_type, interface.name]
13
- return @dyn_vtables[key] unless @dyn_vtables[key].nil?
14
-
15
- vtable_struct_full = dyn_vtable_struct_type(interface)
16
- vtable_c_name = ensure_dyn_vtable(interface, concrete_type)
17
-
18
- void_ptr = Types::Registry.generic_instance("ptr", [@ctx.types.fetch("void")])
19
- vtable_field = IR::Cast.new(
20
- target_type: void_ptr,
21
- expression: IR::AddressOf.new(
22
- expression: IR::Name.new(name: vtable_c_name, type: vtable_struct_full, pointer: false),
23
- type: Types::Registry.generic_instance("ptr", [vtable_struct_full]),
24
- ),
25
- type: void_ptr,
26
- )
27
-
28
- result = IR::AggregateLiteral.new(
29
- type:,
30
- fields: [
31
- IR::AggregateField.new(name: "data", value: IR::Cast.new(target_type: void_ptr, expression: arg_value, type: void_ptr)),
32
- IR::AggregateField.new(name: "vtable", value: vtable_field),
33
- ],
34
- )
35
- @dyn_vtables[key] = result
36
- result
37
- end
4
+ module Lowering
5
+ module Dyn
6
+ def lower_adapt_call(expression, env:, type:, interface:)
7
+ argument = expression.arguments.fetch(0)
8
+ arg_value = lower_expression(argument.value, env:)
9
+ arg_type = infer_expression_type(argument.value, env:)
10
+ concrete_type = ref_type?(arg_type) ? referenced_type(arg_type) : arg_type
11
+
12
+ @dyn_vtables ||= {}
13
+ key = [concrete_type, interface.name]
14
+ return @dyn_vtables[key] unless @dyn_vtables[key].nil?
15
+
16
+ vtable_struct_full = dyn_vtable_struct_type(interface)
17
+ vtable_c_name = ensure_dyn_vtable(interface, concrete_type)
18
+
19
+ void_ptr = Types::Registry.generic_instance("ptr", [@ctx.types.fetch("void")])
20
+ vtable_field = IR::Cast.new(
21
+ target_type: void_ptr,
22
+ expression: IR::AddressOf.new(
23
+ expression: IR::Name.new(name: vtable_c_name, type: vtable_struct_full, pointer: false),
24
+ type: Types::Registry.generic_instance("ptr", [vtable_struct_full]),
25
+ ),
26
+ type: void_ptr,
27
+ )
38
28
 
39
- def lower_dyn_method_call(expression, receiver, method_binding, env:, type:)
40
- ir_expr = lower_expression(receiver, env:)
41
- void_ptr = Types::Registry.generic_instance("ptr", [@ctx.types.fetch("void")])
42
- dyn_type = infer_expression_type(receiver, env:)
43
- interface = dyn_type.interface_binding
29
+ result = IR::AggregateLiteral.new(
30
+ type:,
31
+ fields: [
32
+ IR::AggregateField.new(name: "data", value: IR::Cast.new(target_type: void_ptr, expression: arg_value, type: void_ptr)),
33
+ IR::AggregateField.new(name: "vtable", value: vtable_field),
34
+ ],
35
+ )
36
+ @dyn_vtables[key] = result
37
+ result
38
+ end
44
39
 
45
- data_ptr = IR::Member.new(receiver: ir_expr, member: "data", type: void_ptr)
46
- vtable_field = IR::Member.new(receiver: ir_expr, member: "vtable", type: void_ptr)
40
+ def lower_dyn_method_call(expression, receiver, method_binding, env:, type:)
41
+ ir_expr = lower_expression(receiver, env:)
42
+ void_ptr = Types::Registry.generic_instance("ptr", [@ctx.types.fetch("void")])
43
+ dyn_type = infer_expression_type(receiver, env:)
44
+ interface = dyn_type.interface_binding
47
45
 
48
- vtable_full = dyn_vtable_struct_type(interface)
49
- vtable_ptr_type = Types::Registry.generic_instance("ptr", [vtable_full])
50
- vtable_cast = IR::Cast.new(target_type: vtable_ptr_type, expression: vtable_field, type: vtable_ptr_type)
46
+ data_ptr = IR::Member.new(receiver: ir_expr, member: "data", type: void_ptr)
47
+ vtable_field = IR::Member.new(receiver: ir_expr, member: "vtable", type: void_ptr)
51
48
 
52
- fn_type = vtable_full.field(method_binding.name)
53
- vtable_method = IR::Member.new(receiver: vtable_cast, member: method_binding.name, type: fn_type)
49
+ vtable_full = dyn_vtable_struct_type(interface)
50
+ vtable_ptr_type = Types::Registry.generic_instance("ptr", [vtable_full])
51
+ vtable_cast = IR::Cast.new(target_type: vtable_ptr_type, expression: vtable_field, type: vtable_ptr_type)
54
52
 
55
- arguments = [data_ptr, *lower_call_arguments(expression.arguments, method_binding, env:)]
56
- IR::Call.new(callee: vtable_method, arguments:, type:)
57
- end
53
+ fn_type = vtable_full.field(method_binding.name)
54
+ vtable_method = IR::Member.new(receiver: vtable_cast, member: method_binding.name, type: fn_type)
58
55
 
59
- def dyn_vtable_struct_type(interface)
60
- void_ptr = Types::Registry.generic_instance("ptr", [@ctx.types.fetch("void")])
61
- fields = {}
62
- interface.methods.each do |method_name, method_binding|
63
- fn_params = [Types::Registry.parameter("data", void_ptr), *method_binding.params]
64
- fn_type = Types::Registry.function(nil, params: fn_params, return_type: method_binding.return_type)
65
- fields[method_name] = fn_type
56
+ arguments = [data_ptr, *lower_call_arguments(expression.arguments, method_binding, env:)]
57
+ IR::Call.new(callee: vtable_method, arguments:, type:)
66
58
  end
67
- Types::DynVtable.new(interface.name, fields)
68
- end
69
-
70
- def ensure_dyn_vtable(interface, concrete_type)
71
- concrete_type_name = sanitize_identifier(concrete_type.to_s)
72
- vtable_c_name = "mt_vtable_#{concrete_type_name}_#{interface.name}"
73
- return vtable_c_name if @dyn_generated_vtables&.key?(vtable_c_name)
74
- @dyn_generated_vtables ||= {}
75
-
76
- ensure_dyn_vtable_struct(interface)
77
- wrappers = gen_dyn_vtable_wrappers(concrete_type, interface)
78
- gen_dyn_vtable_constant(concrete_type, interface, vtable_c_name, wrappers)
79
- @dyn_generated_vtables[vtable_c_name] = true
80
- vtable_c_name
81
- end
82
59
 
83
- def ensure_dyn_vtable_struct(interface)
84
- vtable_c_name = "mt_vtable_#{interface.name}"
85
- return if @artifacts.synthetic_structs.any? { |s| s.linkage_name == vtable_c_name }
60
+ def dyn_vtable_struct_type(interface)
61
+ void_ptr = Types::Registry.generic_instance("ptr", [@ctx.types.fetch("void")])
62
+ fields = {}
63
+ interface.methods.each do |method_name, method_binding|
64
+ fn_params = [Types::Registry.parameter("data", void_ptr), *method_binding.params]
65
+ fn_type = Types::Registry.function(nil, params: fn_params, return_type: method_binding.return_type)
66
+ fields[method_name] = fn_type
67
+ end
68
+ Types::DynVtable.new(interface.name, fields)
69
+ end
86
70
 
87
- void_ptr = Types::Registry.generic_instance("ptr", [Types::Registry.primitive("void")])
88
- fields = interface.methods.map do |method_name, method_binding|
89
- fn_params = [Types::Registry.parameter("data", void_ptr), *method_binding.params]
90
- fn_type = Types::Registry.function(nil, params: fn_params, return_type: method_binding.return_type)
91
- IR::Field.new(name: method_name, type: fn_type)
71
+ def ensure_dyn_vtable(interface, concrete_type)
72
+ concrete_type_name = sanitize_identifier(concrete_type.to_s)
73
+ vtable_c_name = "mt_vtable_#{concrete_type_name}_#{interface.name}"
74
+ return vtable_c_name if @dyn_generated_vtables&.key?(vtable_c_name)
75
+ @dyn_generated_vtables ||= {}
76
+
77
+ ensure_dyn_vtable_struct(interface)
78
+ wrappers = generate_dyn_vtable_wrappers(concrete_type, interface)
79
+ generate_dyn_vtable_constant(concrete_type, interface, vtable_c_name, wrappers)
80
+ @dyn_generated_vtables[vtable_c_name] = true
81
+ vtable_c_name
92
82
  end
93
83
 
94
- @artifacts.synthetic_structs << IR::StructDecl.new(
95
- name: "vtable_#{interface.name}",
96
- linkage_name: vtable_c_name,
97
- fields:,
98
- packed: false,
99
- alignment: nil,
100
- )
101
- end
84
+ def ensure_dyn_vtable_struct(interface)
85
+ vtable_c_name = "mt_vtable_#{interface.name}"
86
+ return if @artifacts.synthetic_structs.any? { |s| s.linkage_name == vtable_c_name }
87
+
88
+ void_ptr = Types::Registry.generic_instance("ptr", [Types::Registry.primitive("void")])
89
+ fields = interface.methods.map do |method_name, method_binding|
90
+ fn_params = [Types::Registry.parameter("data", void_ptr), *method_binding.params]
91
+ fn_type = Types::Registry.function(nil, params: fn_params, return_type: method_binding.return_type)
92
+ IR::Field.new(name: method_name, type: fn_type)
93
+ end
102
94
 
103
- def gen_dyn_vtable_wrappers(concrete_type, interface)
104
- void_ptr = Types::Registry.generic_instance("ptr", [Types::Registry.primitive("void")])
105
- wrappers = {}
106
- concrete_type_name = sanitize_identifier(concrete_type.to_s)
107
- ptr_to_concrete = Types::Registry.generic_instance("ptr", [concrete_type])
108
-
109
- interface.methods.each do |method_name, method_binding|
110
- method_info = @method_definitions[[concrete_type, method_name]]
111
- raise LoweringError.new("no method #{method_name} for #{concrete_type}",
112
- line: 0, column: 0, path: @ctx.current_analysis_path) unless method_info
113
-
114
- method_analysis, method_ast = method_info
115
- method_key = method_ast.kind == :static ? "static:#{method_ast.name}" : method_ast.name
116
- real_binding = method_analysis.methods.fetch(concrete_type).fetch(method_key)
117
- real_c_name = function_binding_c_name(real_binding, module_name: method_analysis.module_name, receiver_type: concrete_type)
118
- wrapper_c_name = "__dyn_#{concrete_type_name}_#{method_name}"
119
- is_editable = method_ast.kind == :editable
120
-
121
- params = [
122
- IR::Param.new(name: "data", linkage_name: "data", type: void_ptr, pointer: false),
123
- *method_binding.params.map.with_index { |p, i| IR::Param.new(name: p.name, linkage_name: p.name || "arg#{i}", type: p.type, pointer: false) },
124
- ]
125
-
126
- body = if is_editable
127
- [
128
- IR::ReturnStmt.new(value: IR::Call.new(
129
- callee: real_c_name,
130
- arguments: [
131
- IR::Cast.new(target_type: ptr_to_concrete, expression: IR::Name.new(name: "data", type: void_ptr, pointer: false), type: ptr_to_concrete),
132
- *method_binding.params.map.with_index { |p, i| IR::Name.new(name: p.name || "arg#{i}", type: p.type, pointer: false) },
133
- ],
134
- type: method_binding.return_type,
135
- )),
95
+ @artifacts.synthetic_structs << IR::StructDecl.new(
96
+ name: "vtable_#{interface.name}",
97
+ linkage_name: vtable_c_name,
98
+ fields:,
99
+ packed: false,
100
+ alignment: nil,
101
+ )
102
+ end
103
+
104
+ def generate_dyn_vtable_wrappers(concrete_type, interface)
105
+ void_ptr = Types::Registry.generic_instance("ptr", [Types::Registry.primitive("void")])
106
+ wrappers = {}
107
+ concrete_type_name = sanitize_identifier(concrete_type.to_s)
108
+ ptr_to_concrete = Types::Registry.generic_instance("ptr", [concrete_type])
109
+
110
+ interface.methods.each do |method_name, method_binding|
111
+ method_info = @method_definitions[[concrete_type, method_name]]
112
+ raise LoweringError.new("no method #{method_name} for #{concrete_type}",
113
+ line: 0, column: 0, path: @ctx.current_analysis_path) unless method_info
114
+
115
+ method_analysis, method_ast = method_info
116
+ method_key = method_ast.kind == :static ? "static:#{method_ast.name}" : method_ast.name
117
+ real_binding = method_analysis.methods.fetch(concrete_type).fetch(method_key)
118
+ real_c_name = function_binding_c_name(real_binding, module_name: method_analysis.module_name, receiver_type: concrete_type)
119
+ wrapper_c_name = "__dyn_#{concrete_type_name}_#{method_name}"
120
+ is_editable = method_ast.kind == :editable
121
+
122
+ params = [
123
+ IR::Param.new(name: "data", linkage_name: "data", type: void_ptr, pointer: false),
124
+ *method_binding.params.map.with_index { |p, i| IR::Param.new(name: p.name, linkage_name: p.name || "arg#{i}", type: p.type, pointer: false) },
136
125
  ]
137
- else
138
- if method_ast.kind == :static
139
- [
140
- IR::ReturnStmt.new(value: IR::Call.new(
141
- callee: real_c_name,
142
- arguments: method_binding.params.map.with_index { |p, i| IR::Name.new(name: p.name || "arg#{i}", type: p.type, pointer: false) },
143
- type: method_binding.return_type,
144
- )),
145
- ]
146
- elsif receiver_type_uses_pointer_lowering?(concrete_type)
126
+
127
+ body = if is_editable
147
128
  [
148
129
  IR::ReturnStmt.new(value: IR::Call.new(
149
130
  callee: real_c_name,
@@ -155,51 +136,72 @@ module MilkTea
155
136
  )),
156
137
  ]
157
138
  else
158
- # The receiver is always passed here; the C backend's
159
- # omitted-receiver call logic drops it when the target
160
- # method's unused receiver parameter was omitted (the same
161
- # single source of truth every ordinary method call uses,
162
- # which requires a String callee).
163
- [
164
- IR::ReturnStmt.new(value: IR::Call.new(
165
- callee: real_c_name,
166
- arguments: [
167
- IR::Unary.new(operator: "*", operand: IR::Cast.new(target_type: ptr_to_concrete, expression: IR::Name.new(name: "data", type: void_ptr, pointer: false), type: ptr_to_concrete), type: concrete_type),
168
- *method_binding.params.map.with_index { |p, i| IR::Name.new(name: p.name || "arg#{i}", type: p.type, pointer: false) },
169
- ],
170
- type: method_binding.return_type,
171
- )),
172
- ]
139
+ if method_ast.kind == :static
140
+ [
141
+ IR::ReturnStmt.new(value: IR::Call.new(
142
+ callee: real_c_name,
143
+ arguments: method_binding.params.map.with_index { |p, i| IR::Name.new(name: p.name || "arg#{i}", type: p.type, pointer: false) },
144
+ type: method_binding.return_type,
145
+ )),
146
+ ]
147
+ elsif receiver_type_uses_pointer_lowering?(concrete_type)
148
+ [
149
+ IR::ReturnStmt.new(value: IR::Call.new(
150
+ callee: real_c_name,
151
+ arguments: [
152
+ IR::Cast.new(target_type: ptr_to_concrete, expression: IR::Name.new(name: "data", type: void_ptr, pointer: false), type: ptr_to_concrete),
153
+ *method_binding.params.map.with_index { |p, i| IR::Name.new(name: p.name || "arg#{i}", type: p.type, pointer: false) },
154
+ ],
155
+ type: method_binding.return_type,
156
+ )),
157
+ ]
158
+ else
159
+ # The receiver is always passed here; the C backend's
160
+ # omitted-receiver call logic drops it when the target
161
+ # method's unused receiver parameter was omitted (the same
162
+ # single source of truth every ordinary method call uses,
163
+ # which requires a String callee).
164
+ [
165
+ IR::ReturnStmt.new(value: IR::Call.new(
166
+ callee: real_c_name,
167
+ arguments: [
168
+ IR::Unary.new(operator: "*", operand: IR::Cast.new(target_type: ptr_to_concrete, expression: IR::Name.new(name: "data", type: void_ptr, pointer: false), type: ptr_to_concrete), type: concrete_type),
169
+ *method_binding.params.map.with_index { |p, i| IR::Name.new(name: p.name || "arg#{i}", type: p.type, pointer: false) },
170
+ ],
171
+ type: method_binding.return_type,
172
+ )),
173
+ ]
174
+ end
173
175
  end
176
+
177
+ @artifacts.synthetic_functions << IR::Function.new(
178
+ name: "__dyn_#{concrete_type_name}_#{method_name}",
179
+ linkage_name: wrapper_c_name,
180
+ params:,
181
+ return_type: method_binding.return_type,
182
+ body:,
183
+ entry_point: false,
184
+ )
185
+ wrappers[method_name] = wrapper_c_name
174
186
  end
175
187
 
176
- @artifacts.synthetic_functions << IR::Function.new(
177
- name: "__dyn_#{concrete_type_name}_#{method_name}",
178
- linkage_name: wrapper_c_name,
179
- params:,
180
- return_type: method_binding.return_type,
181
- body:,
182
- entry_point: false,
183
- )
184
- wrappers[method_name] = wrapper_c_name
188
+ wrappers
185
189
  end
186
190
 
187
- wrappers
188
- end
189
-
190
- def gen_dyn_vtable_constant(concrete_type, interface, vtable_c_name, wrappers)
191
- vtable_full = dyn_vtable_struct_type(interface)
192
- fields = interface.methods.map do |method_name, _|
193
- wrapper_c_name = wrappers[method_name]
194
- field_type = vtable_full.field(method_name)
195
- IR::AggregateField.new(name: method_name, value: IR::Name.new(name: wrapper_c_name, type: field_type || @error_type, pointer: false))
191
+ def generate_dyn_vtable_constant(concrete_type, interface, vtable_c_name, wrappers)
192
+ vtable_full = dyn_vtable_struct_type(interface)
193
+ fields = interface.methods.map do |method_name, _|
194
+ wrapper_c_name = wrappers[method_name]
195
+ field_type = vtable_full.field(method_name)
196
+ IR::AggregateField.new(name: method_name, value: IR::Name.new(name: wrapper_c_name, type: field_type || @error_type, pointer: false))
197
+ end
198
+ @artifacts.synthetic_constants << IR::Constant.new(
199
+ name: vtable_c_name,
200
+ linkage_name: vtable_c_name,
201
+ type: vtable_full,
202
+ value: IR::AggregateLiteral.new(type: vtable_full, fields:),
203
+ )
196
204
  end
197
- @artifacts.synthetic_constants << IR::Constant.new(
198
- name: vtable_c_name,
199
- linkage_name: vtable_c_name,
200
- type: vtable_full,
201
- value: IR::AggregateLiteral.new(type: vtable_full, fields:),
202
- )
203
205
  end
204
206
  end
205
207
  end