Skip to content

Commit

Permalink
feat(compiler): Enable single-file compilation
Browse files Browse the repository at this point in the history
  • Loading branch information
ospencer committed May 10, 2024
1 parent 193e5ec commit 6e314ce
Show file tree
Hide file tree
Showing 26 changed files with 367 additions and 357 deletions.
4 changes: 4 additions & 0 deletions cli/bin/grain.js
Original file line number Diff line number Diff line change
Expand Up @@ -188,6 +188,10 @@ program
.command("compile <file>")
.description("compile a grain program into wasm")
.forwardOption("-o <filename>", "output filename")
.forwardOption(
"--single-file",
"compile a single file without compiling dependencies"
)
.forwardOption(
"--use-start-section",
"replaces the _start export with a start section during linking"
Expand Down
82 changes: 63 additions & 19 deletions compiler/grainc/grainc.re
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
open Grain;
open Grain_typed;
open Compile;
open Printf;
open Lexing;
Expand Down Expand Up @@ -26,24 +27,8 @@ let () =
}
);

let compile_file = (name, outfile_arg) => {
if (!Printexc.backtrace_status() && Grain_utils.Config.verbose^) {
Printexc.record_backtrace(true);
};
try({
let outfile =
Option.value(
~default=Compile.default_wasm_filename(name),
outfile_arg,
);
let hook =
if (Grain_utils.Config.statically_link^) {
Compile.stop_after_assembled;
} else {
Compile.stop_after_object_emitted;
};
ignore(Compile.compile_file(~is_root_file=true, ~hook, ~outfile, name));
}) {
let error_wrapped = f =>
try(f()) {
| exn =>
let bt =
if (Printexc.backtrace_status()) {
Expand All @@ -63,6 +48,59 @@ let compile_file = (name, outfile_arg) => {
);
exit(2);
};

let compile_file = (~outfile=?, filename) => {
let outfile =
Option.value(
~default=Compile.default_object_filename(filename),
outfile,
);
ignore(Compile.compile_file(~outfile, filename));
};
let compile_file = (~outfile=?, filename) =>
error_wrapped(() => compile_file(~outfile?, filename));

let grainc = (single_file_mode, name, outfile) => {
Grain_utils.Config.set_root_config();

if (!Printexc.backtrace_status() && Grain_utils.Config.verbose^) {
Printexc.record_backtrace(true);
};

if (single_file_mode) {
compile_file(~outfile?, name);
} else {
switch (Grain_utils.Config.wasi_polyfill^) {
| Some(name) =>
Grain_utils.Config.preserve_config(() => {
Grain_utils.Config.compilation_mode := Grain_utils.Config.Runtime;
Module_resolution.load_dependency_graph(name);
let to_compile = Module_resolution.get_out_of_date_dependencies();
List.iter(compile_file, to_compile);
compile_file(name);
})
| None => ()
};

Module_resolution.load_dependency_graph(name);
let to_compile = Module_resolution.get_out_of_date_dependencies();
List.iter(compile_file, to_compile);
compile_file(name);

if (Grain_utils.Config.statically_link^) {
let main_object =
Option.value(
~default=Compile.default_object_filename(name),
outfile,
);
let outfile =
Option.value(~default=Compile.default_wasm_filename(name), outfile);
let dependencies = Module_resolution.get_dependencies();

Link.link(~main_object, ~outfile, dependencies);
};
};

`Ok();
};

Expand Down Expand Up @@ -107,6 +145,11 @@ let output_filename = {
);
};

let single_file_mode = {
let doc = sprintf("Compile a single file without compiling dependencies");
Arg.(value & vflag(false, [(true, info(["single-file"], ~doc))]));
};

let cmd = {
let doc = sprintf("Compile Grain programs");
let version =
Expand All @@ -118,7 +161,8 @@ let cmd = {
Cmd.info(Sys.argv[0], ~version, ~doc),
Term.(
ret(
Grain_utils.Config.with_cli_options(compile_file)
Grain_utils.Config.with_cli_options(grainc)
$ single_file_mode
$ input_filename
$ output_filename,
)
Expand Down
2 changes: 1 addition & 1 deletion compiler/graindoc/docblock.re
Original file line number Diff line number Diff line change
Expand Up @@ -330,7 +330,7 @@ let get_comments_from_loc = (loc: Grain_parsing.Location.t) => {
| Some(comments) => comments
| None =>
let comments =
switch (compile_file(~is_root_file=true, ~hook=stop_after_parse, file)) {
switch (compile_file(~hook=stop_after_parse, file)) {
| exception exn => []
| {cstate_desc: Parsed(parsed_program)} => parsed_program.comments
| _ => failwith("Invalid compilation state")
Expand Down
32 changes: 23 additions & 9 deletions compiler/graindoc/graindoc.re
Original file line number Diff line number Diff line change
Expand Up @@ -47,14 +47,26 @@ type params = {
current_version: option(string),
};

let compile_typed = (input: Fp.t(Fp.absolute)) => {
switch (
Compile.compile_file(
~is_root_file=true,
~hook=stop_after_typed,
Filepath.to_string(input),
)
) {
let compile_typed = file => {
Module_resolution.load_dependency_graph(file);
let to_compile = Module_resolution.get_out_of_date_dependencies();
List.iter(
file =>
ignore(
compile_file(
~hook=stop_after_object_emitted,
~outfile=Compile.default_wasm_filename(file),
file,
),
),
to_compile,
);
compile_file(~hook=stop_after_typed, file);
};

let compile = (input: Fp.t(Fp.absolute)) => {
reset_compiler_state();
switch (compile_typed(Filepath.to_string(input))) {
| exception exn =>
let bt =
if (Printexc.backtrace_status()) {
Expand Down Expand Up @@ -180,9 +192,11 @@ let enumerate_runs = opts =>
};

let graindoc = (opts, runs) => {
Config.set_root_config();

List.iter(
({input_path, output_path}) => {
let program = compile_typed(input_path);
let program = compile(input_path);
try(
generate_docs(
~current_version=opts.current_version,
Expand Down
8 changes: 3 additions & 5 deletions compiler/src/codegen/linkedtree.re
Original file line number Diff line number Diff line change
Expand Up @@ -29,9 +29,7 @@ let max_stack_size = (s1, s2) => {

let wasi_module = "wasi_snapshot_preview1";

let link = main_mashtree => {
let main_module = Module_resolution.current_filename^();

let link = (~main_object, dependencies) => {
let new_base_dir = Filepath.String.dirname;

let resolve = (~base_dir=?, mod_name) =>
Expand All @@ -43,7 +41,6 @@ let link = main_mashtree => {
Config.wasi_polyfill_path(),
);

let dependencies = Module_resolution.get_dependencies();
let dependencies =
switch (wasi_polyfill) {
| Some(polyfill) => [polyfill, ...dependencies]
Expand Down Expand Up @@ -199,7 +196,8 @@ let link = main_mashtree => {
dependencies,
);

let main_program = process_mashtree(~main=true, main_module, main_mashtree);
let main_mashtree = Emitmod.load_object(main_object);
let main_program = process_mashtree(~main=true, main_object, main_mashtree);
let programs = List.rev([main_program, ...programs]);
let num_function_table_elements = num_function_table_elements^;
let signature = main_mashtree.signature;
Expand Down
Loading

0 comments on commit 6e314ce

Please sign in to comment.