@@ -23,36 +23,55 @@ let tool_name = "ocamlopt"
23
23
let with_info = Compile_common. with_info ~native: true ~tool_name
24
24
25
25
let interface ~source_file ~output_prefix =
26
- with_info ~source_file ~output_prefix ~dump_ext: " cmi" @@ fun info ->
26
+ with_info ~source_file ~output_prefix ~dump_ext: " cmi"
27
+ ~compilation_unit: Inferred_from_output_prefix
28
+ @@ fun info ->
27
29
Compile_common. interface
28
30
~hook_parse_tree: (Compiler_hooks. execute Compiler_hooks. Parse_tree_intf )
29
31
~hook_typed_tree: (Compiler_hooks. execute Compiler_hooks. Typed_tree_intf )
30
32
info
31
33
32
34
(* * Native compilation backend for .ml files. *)
33
35
34
- let compile i typed ~transl_style ~unix ~pipeline =
35
- typed
36
- |> Profile. (record transl)
37
- (Translmod. transl_implementation i.module_name ~style: transl_style)
36
+ let make_arg_descr ~param ~arg_block_field : Lambda. arg_descr option =
37
+ match param, arg_block_field with
38
+ | Some arg_param , Some arg_block_field -> Some { arg_param; arg_block_field }
39
+ | None , None -> None
40
+ | Some _ , None -> Misc. fatal_error " No argument field"
41
+ | None , Some _ -> Misc. fatal_error " Unexpected argument field"
42
+
43
+ let compile_from_raw_lambda i raw_lambda ~unix ~pipeline ~as_arg_for =
44
+ raw_lambda
38
45
|> print_if i.ppf_dump Clflags. dump_rawlambda Printlambda. program
39
46
|> Compiler_hooks. execute_and_pipe Compiler_hooks. Raw_lambda
40
47
|> Profile. (record generate)
41
- (fun program ->
48
+ (fun ( program : Lambda.program ) ->
42
49
Builtin_attributes. warn_unused () ;
43
50
let code = Simplif. simplify_lambda program.Lambda. code in
44
51
{ program with Lambda. code }
45
52
|> print_if i.ppf_dump Clflags. dump_lambda Printlambda. program
46
53
|> Compiler_hooks. execute_and_pipe Compiler_hooks. Lambda
47
- |> (fun program ->
54
+ |> (fun ( program : Lambda.program ) ->
48
55
Asmgen. compile_implementation
49
56
unix
50
57
~pipeline
51
58
~filename: i.source_file
52
59
~prefixname: i.output_prefix
53
60
~ppf_dump: i.ppf_dump
54
61
program);
55
- Compilenv. save_unit_info (cmx i))
62
+ let arg_descr =
63
+ make_arg_descr ~param: as_arg_for
64
+ ~arg_block_field: program.arg_block_field
65
+ in
66
+ Compilenv. save_unit_info (cmx i)
67
+ ~module_block_format: program.module_block_format
68
+ ~arg_descr )
69
+
70
+ let compile_from_typed i typed ~transl_style ~unix ~pipeline ~as_arg_for =
71
+ typed
72
+ |> Profile. (record transl)
73
+ (Translmod. transl_implementation i.module_name ~style: transl_style)
74
+ |> compile_from_raw_lambda i ~unix ~pipeline ~as_arg_for
56
75
57
76
type flambda2 =
58
77
ppf_dump :Format .formatter ->
@@ -68,31 +87,106 @@ let emit unix i =
68
87
Asmgen. compile_implementation_linear unix
69
88
i.output_prefix ~progname: i.source_file
70
89
71
- let implementation unix ~(flambda2 : flambda2 ) ~start_from ~source_file
72
- ~output_prefix ~keep_symbol_tables =
73
- let backend info ({ structure; coercion; _ } : Typedtree.implementation ) =
90
+ type starting_point =
91
+ | Parsing
92
+ | Emit
93
+ | Instantiation of {
94
+ runtime_args : Translmod .runtime_arg list ;
95
+ main_module_block_size : int ;
96
+ arg_descr : Lambda .arg_descr option ;
97
+ }
98
+
99
+ let starting_point_of_compiler_pass start_from =
100
+ match (start_from:Clflags.Compiler_pass.t ) with
101
+ | Parsing -> Parsing
102
+ | Emit -> Emit
103
+ | _ -> Misc. fatal_errorf " Cannot start from %s"
104
+ (Clflags.Compiler_pass. to_string start_from)
105
+
106
+ let implementation0 unix ~(flambda2 : flambda2 ) ~start_from
107
+ ~source_file ~output_prefix ~keep_symbol_tables
108
+ ~(compilation_unit : Compile_common.compilation_unit_or_inferred ) =
109
+ let transl_style : Translmod.compilation_unit_style =
110
+ if Config. flambda || Config. flambda2 then Plain_block
111
+ else Set_individual_fields
112
+ in
113
+ let pipeline : Asmgen.pipeline =
114
+ Direct_to_cmm (flambda2 ~keep_symbol_tables )
115
+ in
116
+ let backend info ({ structure; coercion; argument_interface; _ }
117
+ : Typedtree. implementation ) =
74
118
Compilenv. reset info.module_name;
75
- let typed = structure, coercion in
76
- let transl_style : Translmod.compilation_unit_style =
77
- if Config. flambda || Config. flambda2 then Plain_block
78
- else Set_individual_fields
119
+ let argument_coercion =
120
+ match argument_interface with
121
+ | Some { ai_coercion_from_primary; ai_signature = _ } ->
122
+ Some ai_coercion_from_primary
123
+ | None -> None
79
124
in
80
- let pipeline : Asmgen.pipeline =
81
- Direct_to_cmm (flambda2 ~keep_symbol_tables )
125
+ let typed = structure, coercion, argument_coercion in
126
+ let as_arg_for =
127
+ ! Clflags. as_argument_for
128
+ |> Option. map (fun param ->
129
+ (* Currently, parameters don't have parameters, so we assume the argument
130
+ list is empty *)
131
+ Global_module.Name. create_exn param [] )
82
132
in
83
133
if not (Config. flambda || Config. flambda2) then Clflags. set_oclassic () ;
84
- compile info typed ~unix ~transl_style ~pipeline
134
+ compile_from_typed info typed ~unix ~transl_style ~pipeline ~as_arg_for
85
135
in
86
- with_info ~source_file ~output_prefix ~dump_ext: " cmx" @@ fun info ->
136
+ with_info ~source_file ~output_prefix ~dump_ext: " cmx" ~compilation_unit
137
+ @@ fun info ->
87
138
if ! Flambda_backend_flags. internal_assembler then
88
139
Emitaux. binary_backend_available := true ;
89
- match ( start_from: Clflags.Compiler_pass.t ) with
140
+ match start_from with
90
141
| Parsing ->
91
142
Compile_common. implementation
92
143
~hook_parse_tree: (Compiler_hooks. execute Compiler_hooks. Parse_tree_impl )
93
144
~hook_typed_tree: (fun (impl : Typedtree.implementation ) ->
94
145
Compiler_hooks. execute Compiler_hooks. Typed_tree_impl impl)
95
146
info ~backend
96
147
| Emit -> emit unix info ~ppf_dump: info.ppf_dump
97
- | _ -> Misc. fatal_errorf " Cannot start from %s"
98
- (Clflags.Compiler_pass. to_string start_from)
148
+ | Instantiation { runtime_args; main_module_block_size; arg_descr } ->
149
+ Compilenv. reset info.module_name;
150
+ (* FIXME delete {[
151
+ let global_name =
152
+ Compilation_unit.to_global_name_exn info.module_name
153
+ in
154
+ (* Consider the names of arguments to be parameters for the purposes of the
155
+ subset rule - that is, a module we import can refer to our arguments as
156
+ parameters. *)
157
+ List.iter
158
+ (fun (param, _value) ->
159
+ let import = Compilation_unit.Name.of_head_of_global_name param in
160
+ Env.register_parameter_import import)
161
+ global_name.args;
162
+ ]} *)
163
+ let as_arg_for, arg_block_field =
164
+ match (arg_descr : Lambda.arg_descr option ) with
165
+ | Some { arg_param; arg_block_field } ->
166
+ Some arg_param, Some arg_block_field
167
+ | None -> None , None
168
+ in
169
+ let impl =
170
+ Translmod. transl_instance info.module_name ~runtime_args
171
+ ~main_module_block_size ~arg_block_field
172
+ ~style: transl_style
173
+ in
174
+ if not (Config. flambda || Config. flambda2) then Clflags. set_oclassic () ;
175
+ compile_from_raw_lambda info impl ~unix ~pipeline ~as_arg_for
176
+
177
+ let implementation unix ~flambda2 ~start_from ~source_file
178
+ ~output_prefix ~keep_symbol_tables =
179
+ let start_from = start_from |> starting_point_of_compiler_pass in
180
+ implementation0 unix ~flambda2 ~start_from ~source_file
181
+ ~output_prefix ~keep_symbol_tables
182
+ ~compilation_unit: Inferred_from_output_prefix
183
+
184
+ let instance unix ~flambda2 ~source_file
185
+ ~output_prefix ~compilation_unit ~runtime_args ~main_module_block_size
186
+ ~arg_descr ~keep_symbol_tables =
187
+ let start_from =
188
+ Instantiation { runtime_args; main_module_block_size; arg_descr }
189
+ in
190
+ implementation0 unix ~flambda2 ~start_from ~source_file
191
+ ~output_prefix ~keep_symbol_tables
192
+ ~compilation_unit: (Exactly compilation_unit)
0 commit comments